feat(cli): add read-only agent-init status subcommand#74
Conversation
`status [target]` reports the scaffold's current visibility (shared / local / hidden / shadowed-by-global), the absolute path of the file carrying the agent-init ignore block, and the exact sed undo command. When the scaffold is committed locally but a global-default ignore exists, the report includes the force-add hint explaining why files may still be tracked. Detection follows git's ignore precedence (.gitignore > .git/info/exclude > core.excludesfile) and reports the most-local carrier. The subcommand is strictly read-only — no files and no git config are mutated. `gitignore` gains `HasBlock` and exports `MarkerStart` / `MarkerEnd` so the detector and the undo hint reuse the same markers the writers do. Closes #60 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Reject unknown flags loudly: `status --no-such-flag` now errors instead of silently resolving the flag string to an absolute target path. - Documented that detection is marker-based (not effective-behavior), and that `git config --global --get core.excludesfile` is invoked to locate the machine-wide excludes file. - Print a note that `sed -i.bak` leaves a one-shot backup file. - Rephrase the shadowed-by-global note so "git ignores rules" no longer garden-paths as "git ignores-the-rules". - Switch the default-target test to `t.Chdir` (Go 1.24+); it auto-restores and refuses `t.Parallel`, removing a latent race. - Justify detectStatus's slight overrun of the ~40-line guideline inline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the hand-rolled strings.HasPrefix check with a.newFlagSet, matching how init and add-tracker handle unknown flags. Drops the dedicated TestStatusRejectsUnknownFlag test — unknown-flag rejection is a property of the shared FlagSet, not of status specifically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
LOW — Fix: render the path with |
Summary
agent-init status [target]— read-only reporter that prints the scaffold's current visibility mode (shared,local,hidden, orshadowed-by-global), the absolute path of the file carrying the agent-init ignore block, and the exact sed undo command. Forshadowed-by-globalit also prints the force-add hint explaining why files may still be tracked..gitignore>.git/info/exclude>core.excludesfile) and reports the most-local carrier. Writes nothing; touches no git config.internal/gitignorerather than duplicating them.gitignoregainsHasBlockand exportsMarkerStart/MarkerEndso the detector and the undo hint stay byte-for-byte in sync with the writers.internal/cli/cli.go;TestHelpFlagsMatchDocs, the top-level help test, and the flagless-subcommand help test are updated to includestatus. Docs added underdocs/cli.md; README subcommand list updated.Closes #60.
Acceptance criterion calls
shared,local,hidden,shadowed-by-globalverbatim from the issue..gitignore>.git/info/exclude> global).shadowed-by-globalonly fires when neither repo-local file carries the block but the global one does — the state where the scaffold is committed openly here yet ignored everywhere else.sed -i.bakinvocation that works on both GNU and BSD sed, plus a note about the.bakleftover and a manual-edit fallback. Markers come fromgitignore.MarkerStart/MarkerEnd.docs/cli.md"Behavior". A user who manually negates a rule below the block still seeslocal/hidden/shadowed-by-global.status --no-such-flagerrors instead of silently treating the flag as a target path).Test plan
./.agent/scripts/check.shpasses (codemap, fmt, lint, lint-shell, mod-tidy, typecheck, test, cross-build, smoke-test).just smoke-testpasses (no template changes, but verified — no-op).internal/cli/status_test.gocover: shared, local, hidden, shadowed-by-global, multi-carrier precedence, default target (cwd), explicit target canonicalization, extra-positional rejection, unknown-flag rejection, three help triggers, and graceful degradation when HOME is unreadable. Read-only is asserted via on-disk snapshots taken before and after the run.HasBlock(six edge cases) and a drift guard linkingMarkerStart/MarkerEndto the internal constants.localand ahiddenproject and ranstatusagainst both; output matches the documented format.🤖 Generated with Claude Code