feat(scripts): harvest spec-kit upstream — argument-hints, --paths-only, --dry-run, gitflow detection (#75 #76 #77)#89
Conversation
…#75) The five iikit skills that accept arguments — iikit-core, iikit-01-specify, iikit-bugfix, iikit-08-taskstoissues, iikit-clarify — now carry an argument-hint: field. Claude Code's slash-command UI surfaces the hint inline so users see the expected input shape without reading the SKILL body. Other agents ignore the unknown field per rule-frontmatter passthrough. Harvested from upstream spec-kit commit 10be4848 (PRs #2059, #1951). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
check-prerequisites.sh --paths-only (and --phase core) now skips the feature-branch gate, mirroring status_mode. Returns paths informationally on a non-feature branch with empty feature dirs, instead of exiting 1. Use cases: CI dry-runs, worktree-isolated read-only inspection, and feeding a planned /iikit-core doctor (#74) with structured paths. create-new-feature.sh --dry-run (and -DryRun in PowerShell) previews BRANCH_NAME / FEATURE_NUM / SPEC_FILE without writing — no branch checkout, no specs/NNN-*/ directory, no spec.md copy, no active-feature write. JSON output carries "dry_run": true. Harvested from upstream spec-kit commits 3227b966 (#2672) and b44ffc01 (#1998). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…#77) The active-feature cascade now recognizes both `NNN-name` (standard) and `<prefix>/NNN-name` (gitflow — feat/001-user-auth, fix/042-null-deref, chore/007-foo). New extract_feature_id / Get-FeatureIdFromBranch helper strips the prefix; get_current_branch, check_feature_branch, find_feature_dir_by_prefix, and create-new-feature's highest-number scan all route through it. Teams on gitflow conventions no longer fall through to "single feature auto-select" or hit a "not on a feature branch" error. Cascade semantics unchanged. Also rolls the three CHANGELOG entries for this harvest set (#75 #76 #77) into Unreleased. Harvested from upstream spec-kit commit 4687c33b (PR #2202). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Skipping: self-review-bias — author-family anthropic; see jbaruch/coding-policy: author-model-declaration.
Generated by PR Policy Review (Anthropic) for issue #89 · ● 235.7K
There was a problem hiding this comment.
Policy loaded: 20 rule files from /tmp/gh-aw/coding-policy/.tessl/plugins/jbaruch/coding-policy/rules/ (installed tile).
Changes requested: --paths-only / core soft branch mode still fails with needs_selection in multi-feature workspaces, which violates the error-handling fallback requirement in both Bash and PowerShell. The PowerShell mirror also needs Pester coverage for the newly added dry-run/gitflow behavior under the repo’s existing PowerShell test convention.
Generated by PR Policy Review (OpenAI) for issue #89
| if [[ "$P_EXTRAS" == *"status_mode"* ]] || [[ "$P_EXTRAS" == *"paths_only"* ]]; then | ||
| SOFT_BRANCH_MODE=true | ||
| fi | ||
| if $SOFT_BRANCH_MODE; then |
There was a problem hiding this comment.
jbaruch/coding-policy: error-handling says: "When multiple approaches exist, try alternatives before failing." In --phase core / --paths-only, SOFT_BRANCH_MODE is meant to make non-feature branches informational, but a multi-feature workspace still returns BRANCH_EXIT=2 and exits through the unchanged needs_selection block before the soft fallback runs. That means --paths-only --json still gates on feature selection as soon as two specs/NNN-* dirs exist. Handle BRANCH_EXIT=2 inside soft mode the same way as the no-feature fallback, or otherwise emit path JSON without exiting 2, and add a regression test with multiple feature dirs.
| $statusNoFeature = $false | ||
| $noFeatureBranch = $false | ||
| # paths_only and status_mode tolerate non-feature branches. | ||
| $softBranchMode = ($cfg.Extras -match 'status_mode') -or ($cfg.Extras -match 'paths_only') |
There was a problem hiding this comment.
jbaruch/coding-policy: error-handling says: "When multiple approaches exist, try alternatives before failing." The PowerShell mirror sets $softBranchMode for paths_only, but NEEDS_SELECTION is still handled before the soft fallback, so -Phase core -Json exits 2 on a non-feature branch with multiple features instead of returning informational paths. Mirror the Bash fix here as well, and cover it in tests/powershell/check-prerequisites.Tests.ps1 so the two implementations stay aligned.
| @@ -257,6 +261,29 @@ if ($branchName.Length -gt $maxBranchLength) { | |||
| Write-Warning "[specify] Truncated to: $branchName ($($branchName.Length) bytes)" | |||
There was a problem hiding this comment.
jbaruch/coding-policy: testing-standards says: "Every module gets tests — no untested code ships." This adds the PowerShell -DryRun behavior, but the PR only adds Bats coverage; tests/powershell/create-new-feature.Tests.ps1 has no matching -DryRun or gitflow-numbering cases. Add Pester coverage for the PowerShell mirror so the changed module is tested under the repo’s existing PowerShell test convention.
There was a problem hiding this comment.
Pull request overview
This PR harvests three upstream spec-kit improvements into IIKit: (1) Claude slash-command UX via argument-hint frontmatter, (2) safer/non-destructive “inspection” modes with check-prerequisites --paths-only / --phase core and create-new-feature --dry-run, and (3) gitflow-prefixed branch support (feat/NNN-name, fix/NNN-name) in feature detection. It also updates the BATS test suite and the CHANGELOG to reflect the new behavior.
Changes:
- Add
argument-hint:YAML frontmatter to the argument-taking skills to improve Claude Code slash-command UX. - Extend bash + PowerShell core scripts with
--paths-only/--phase core,--dry-run, and gitflow-prefixed branch parsing via new helper(s). - Add BATS coverage for
--dry-run,--paths-only/--phase core, and gitflow branch prefix behavior; document the release notes inCHANGELOG.md.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
tests/bash/create-new-feature.bats |
Adds BATS coverage for create-new-feature --dry-run and gitflow branch-prefix numbering. |
tests/bash/common.bats |
Adds BATS coverage for extract_feature_id, gitflow branch acceptance, and gitflow dir resolution. |
tests/bash/check-prerequisites.bats |
Adds BATS coverage ensuring --paths-only and --phase core succeed on non-feature branches. |
CHANGELOG.md |
Documents the three harvested upstream features in Unreleased. |
.claude/skills/iikit-core/SKILL.md |
Adds argument-hint for /iikit-core actions/feature selector. |
.claude/skills/iikit-clarify/SKILL.md |
Adds argument-hint for clarify target selection. |
.claude/skills/iikit-bugfix/SKILL.md |
Adds argument-hint for bug description / issue URL input. |
.claude/skills/iikit-08-taskstoissues/SKILL.md |
Adds argument-hint for optional flags. |
.claude/skills/iikit-01-specify/SKILL.md |
Adds argument-hint for feature description input. |
.claude/skills/iikit-core/scripts/powershell/create-new-feature.ps1 |
Implements -DryRun output path + gitflow branch scanning for next-number selection. |
.claude/skills/iikit-core/scripts/powershell/common.ps1 |
Adds Get-FeatureIdFromBranch and uses it in branch/feature detection (see review comment). |
.claude/skills/iikit-core/scripts/powershell/check-prerequisites.ps1 |
Softens branch validation for paths_only/status_mode and renames state flag. |
.claude/skills/iikit-core/scripts/bash/create-new-feature.sh |
Implements --dry-run and gitflow-aware next-number scanning. |
.claude/skills/iikit-core/scripts/bash/common.sh |
Adds extract_feature_id and routes feature detection through it (gitflow support). |
.claude/skills/iikit-core/scripts/bash/check-prerequisites.sh |
Softens branch validation for paths_only/status_mode and renames state flag. |
| # 3. Check git branch if available. If it's NNN-* or prefix/NNN-* (gitflow), | ||
| # return the extracted feature id; otherwise return the raw branch. | ||
| try { | ||
| $result = git rev-parse --abbrev-ref HEAD 2>$null | ||
| if ($LASTEXITCODE -eq 0) { |
… Pester coverage Three review-driven fixes to PR #89: 1. Soft branch mode (paths_only, status_mode) was still exiting 2 with needs_selection when multiple feature dirs existed. The caller wants informational paths, not a selection prompt. Both bash and PowerShell now fall through to empty-paths in soft mode regardless of which non-zero branch-validation status the caller hit. 2. PowerShell Get-CurrentBranch read .specify/active-feature before consulting the git branch, so a gitflow branch (feat/001-foo) could be masked by a stale sticky file — diverging from bash and undermining the gitflow support added in this PR. Cascade reordered to match bash: SPECIFY_FEATURE → git branch (with extract) → active-feature → raw branch → non-git fallbacks. 3. PowerShell mirrors of the new behavior had no Pester coverage. Added tests for: Get-FeatureIdFromBranch (standard, feat/, fix/, rejection); Test-FeatureBranch accepting gitflow shapes; Find-FeatureDirByPrefix resolving gitflow branches; -DryRun (no writes, dry_run=true JSON, respects -ShortName/-Number); gitflow numbering in get-highest-from- branches; -PathsOnly / -Phase core / -Phase status not exiting 2 under multi-feature non-feature-branch workspaces. Bats also gets the corresponding soft-mode regression cases. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Skipping: self-review-bias — author-family anthropic; see jbaruch/coding-policy: author-model-declaration.
Generated by PR Policy Review (Anthropic) for issue #89 · ● 237.6K
There was a problem hiding this comment.
Policy loaded: 20 rule files from /tmp/gh-aw/coding-policy/.tessl/plugins/jbaruch/coding-policy/rules/ (installed tile).
Requesting changes for jbaruch/coding-policy: commit-conventions: the policy requires PR titles to follow <type>(<scope>): <imperative summary>, but this PR is titled feat: harvest spec-kit upstream — argument-hints, --paths-only, --dry-run, gitflow detection (#75 #76 #77), which omits the required scope. Please retitle it with an explicit scope, for example feat(scripts): harvest spec-kit upstream updates, or another accurate scoped title.
Generated by PR Policy Review (OpenAI) for issue #89
The prior fixup let status_mode also bypass the needs_selection picker, but BUG-19's regression test (check-prerequisites: --phase status still exits 2 for needs_selection) correctly asserts the opposite: /iikit-core status SHOULD surface the picker so the user gets guidance on selecting a feature. Narrow scope: only paths_only swallows needs_selection. status_mode keeps the picker. Bash and PowerShell mirror, with the over-broad bats test from the prior fixup removed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Skipping: self-review-bias — author-family anthropic; see jbaruch/coding-policy: author-model-declaration.
Generated by PR Policy Review (Anthropic) for issue #89 · ● 233.5K
There was a problem hiding this comment.
Policy loaded: 20 rule files from /tmp/gh-aw/coding-policy/.tessl/plugins/jbaruch/coding-policy/rules/ (installed tile).
Requesting changes for one jbaruch/coding-policy: script-delegation violation: the new PowerShell soft branch mode can contaminate -Json output with branch-validation prose before the structured payload. The bash implementation suppresses that diagnostic path; the PowerShell mirror should capture or suppress Test-FeatureBranch output in soft modes so JSON-producing invocations emit only JSON on stdout.
Generated by PR Policy Review (OpenAI) for issue #89
| $statusNoFeature = $false | ||
| $noFeatureBranch = $false | ||
| # paths_only and status_mode tolerate non-feature branches. | ||
| $softBranchMode = ($cfg.Extras -match 'status_mode') -or ($cfg.Extras -match 'paths_only') |
There was a problem hiding this comment.
jbaruch/coding-policy: script-delegation says JSON-producing scripts must output structured data, not prose. This new soft branch mode still calls Test-FeatureBranch normally on line 126; in the PowerShell helper, the ERROR and NEEDS_SELECTION paths use Write-Output, so -Phase core -Json / -PathsOnly -Json can emit warning/error prose before the JSON object when no feature branch exists or multiple features exist. The bash mirror suppresses branch-validation diagnostics in soft mode. Capture or suppress this call in soft mode, then emit only the final JSON payload on stdout.
There was a problem hiding this comment.
Skipping: self-review-bias — author-family anthropic; see jbaruch/coding-policy: author-model-declaration.
Generated by PR Policy Review (Anthropic) for issue #89 · ● 371.8K
The PowerShell mirror let Test-FeatureBranch's warning (stream 3) and error (stream 2) streams reach the caller in soft modes, where the script's contract is to emit only JSON or status text. Bash uses `2>/dev/null` for parity; PS now mirrors that with `2>$null 3>$null` on the Test-FeatureBranch call inside soft branch mode. Hard modes still surface those streams so users on a wrong branch see the diagnostic. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Skipping: self-review-bias — author-family anthropic; see jbaruch/coding-policy: author-model-declaration.
Generated by PR Policy Review (Anthropic) for issue #89 · ● 234.8K
There was a problem hiding this comment.
Policy loaded: 20 rule files from /tmp/gh-aw/coding-policy/.tessl/plugins/jbaruch/coding-policy/rules/ (installed tile).
Requesting changes for a jbaruch/coding-policy: skill-authoring frontmatter violation: the PR adds argument-hint to five changed SKILL.md files, but the loaded policy only permits allowed-tools, disable-model-invocation, and user-invocable as optional skill frontmatter fields. The script and test changes otherwise looked consistent with the loaded rules.
Generated by PR Policy Review (OpenAI) for issue #89
| description: >- | ||
| Initialize an IIKit (Intent Integrity Kit) project, uninit (remove IIKit scaffolding before `tessl uninstall`), check IIKit feature progress, select the active IIKit feature, and display the IIKit workflow command reference. | ||
| Use when starting a new IIKit project, running IIKit init or setup, uninstalling/removing/uninit-ing IIKit before running `tessl uninstall`, checking IIKit status, switching between IIKit features, looking up IIKit available commands and phases, or asking for help with the IIKit workflow. | ||
| argument-hint: "[init|status|use|uninit|help] [feature]" |
There was a problem hiding this comment.
jbaruch/coding-policy: skill-authoring says: "Optional fields: allowed-tools, disable-model-invocation, user-invocable". This PR adds argument-hint frontmatter to this skill (and the same pattern appears in the other changed SKILL.md files), but that field is not permitted by the loaded skill frontmatter contract. Remove these argument-hint entries, or update the policy first so argument-hint is an allowed skill frontmatter field before introducing it here.
Summary
Three small upstream harvests bundled per the harvest-tier sequencing in #75/#76/#77.
argument-hint:frontmatter on the five iikit skills that take args (iikit-core,iikit-01-specify,iikit-bugfix,iikit-08-taskstoissues,iikit-clarify). Claude Code's slash-command UI surfaces the hint inline. Upstream:10be4848(#2059, #1951).check-prerequisites.sh --paths-only(and--phase core) no longer requires a feature branch — emits paths informationally instead of exiting 1.create-new-feature.sh --dry-runpreviewsBRANCH_NAME/FEATURE_NUM/SPEC_FILEwithout writing. PowerShell mirrors updated. Upstream:3227b966(#2672),b44ffc01(#1998).NNN-nameand<prefix>/NNN-name(e.g.feat/001-user-auth,fix/042-null-deref). Newextract_feature_id/Get-FeatureIdFromBranchhelper strips the prefix; all five callers route through it. Upstream:4687c33b(#2202).Each issue is its own commit. CHANGELOG entries rolled into Unreleased on the #77 commit.
Author-Model: claude-opus-4-7
Test plan
check-prerequisites.bats—--paths-onlyand--phase coresucceed on non-feature branch with no features (Harvest: --paths-only and --dry-run flags on iikit-core scripts #76)create-new-feature.bats—--dry-rundoes not create branch/dir/spec.md, emitsdry_run:true, respects--short-name/--number(Harvest: --paths-only and --dry-run flags on iikit-core scripts #76); countsfeat/NNN-*andfix/NNN-*for next-number computation (Harvest: support gitflow branch prefixes (feat/001-name) in feature detection #77)common.bats—extract_feature_idfor standard,feat/,fix/shapes and rejection cases;check_feature_branchaccepts gitflow shapes;find_feature_dir_by_prefixresolves gitflow branches (Harvest: support gitflow branch prefixes (feat/001-name) in feature detection #77)Notes
main(manifest paths excluded by.gitignore) is independent of this PR's changes.feat/iikit-harvest-75-76-77does not match the new gitflow<prefix>/NNN-nameshape — so this PR's branch does not trigger the new detection path itself.