Skip to content

Make graft init --dry-run honor --no-global, --no-mcp and --no-hooks - #333

Open
L4XB wants to merge 1 commit into
trailhq:mainfrom
L4XB:fix/init-dry-run-honors-suppression-flags
Open

Make graft init --dry-run honor --no-global, --no-mcp and --no-hooks#333
L4XB wants to merge 1 commit into
trailhq:mainfrom
L4XB:fix/init-dry-run-honors-suppression-flags

Conversation

@L4XB

@L4XB L4XB commented Sep 9, 2026

Copy link
Copy Markdown

Refs #329 — this covers the first half of that report (the suppression flags); the second half (retraction, wiring stamp and graph-build side effects in the plan) is not addressed here.

Problem

src/cli.ts built the dry-run plan with planInit(repo, { home }), so graft init --dry-run --no-global --no-mcp --no-hooks printed exactly the same planned writes as a plain --dry-run, including ~/.codex/config.toml, the Codex hook shim/hooks.json and opencode.json, all of which runHostsInit() skips for those flags. The help text says --dry-run prints every file init would touch, so the plan was wrong as a preflight for the flags.

Change

  • planInit() takes mcp, hooks and global and applies the same predicates as runHostsInit():
    • --no-mcp: no MCP registrations for the non-Claude hosts;
    • --no-hooks: no Codex hooks and no Cursor hooks;
    • --no-global: nothing outside the repo — the ~/.claude copy, the global MCP configs (Codex, Antigravity), the Codex hooks and the Antigravity skill are dropped; Cursor's hooks are repo-local and stay, as in the writer.
  • The CLI passes the flags to planInit for the parent repo and for every workspace child.
  • The · skipped out-of-repo writes (--no-global) notice still fires: it now asks the unsuppressed plan whether there was anything out-of-repo to skip (the existing CLI: --no-global writes AGENTS.md but leaves ~/.codex alone test covers that).

Tests

test/hosts-plan.test.ts: new case checking each flag against the plan (default plan lists the ~/.codex writes and Cursor hooks; --no-mcp drops MCP configs; --no-hooks drops Codex and Cursor hooks; --no-global leaves no scope: 'global' write and nothing under ~ while keeping Cursor's repo-local hooks; all three together leave the agents host with only AGENTS.md). Fails on main, passes with the change.

node --import tsx --test test/hosts-plan.test.ts test/hosts-init.test.ts test/claude-init.test.ts test/claude-init-workspace.test.ts: 54 pass. tsc --noEmit clean.

The dry-run plan was built without the suppression flags, so
`graft init --dry-run --no-global --no-mcp --no-hooks` printed the same
planned writes as a plain dry-run, including the ~/.codex config and
hooks that the real writer skips. That made --dry-run unusable as a
preflight for those flags although its help text promises to print
every file init would touch.

planInit() now applies the same predicates runHostsInit() uses:
--no-mcp drops the MCP registrations, --no-hooks the Codex and Cursor
hooks, --no-global everything outside the repo (the ~/.claude copy,
global MCP configs, Codex hooks, Antigravity skill; Cursor's repo-local
hooks stay). The CLI passes the flags through for the parent and every
workspace child. The "skipped out-of-repo writes" notice still fires by
checking the unsuppressed plan.

Refs trailhq#329 (the retraction / wiring-stamp / graph-build side effects are
still not part of the plan)
@trailhq-graft

trailhq-graft Bot commented Sep 9, 2026

Copy link
Copy Markdown

🌱 graft blast radius

Nothing outside this diff depends on it. 2 areas changed; no indexed dependents at depth 2.
Tests: no test reaches CLI Target Wiring; 1 area updated its tests.
Tag: @anirudhkumar-nanonets — Plan Initialization, CLI Target Wiring · @shhdwi — CLI Target Wiring · @afeddersen — Plan Initialization

Who knows this code — 3 people across 2 areas
Area Who knows it
Plan Initialization · changed @anirudhkumar-nanonets — 2 commits, last 8d ago · @afeddersen — 1 commit, last 9d ago
CLI Target Wiring · changed @anirudhkumar-nanonets — 36 commits, last 7d ago · @shhdwi — 23 commits, last 27d ago

Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no @ has no GitHub handle in its commit email — tag them by hand, or add a .mailmap entry. A suggestion from history, not a CODEOWNERS rule.

Test signal per changed area — 1 ✓ · 1 ✗

Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.

  • Plan Initialization — 1 of 2 reached · 1 test file changed here: test/hosts-plan.test.ts
    • not reached: inScope
  • CLI Target Wiring — 0 of 1 reached · no test file reaches it
    • not reached: wireTarget
2 test suites also reference this code

4 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.

  • test/cli-picker.test.ts
  • test/hosts-claude-global.test.ts

graft blast · origin/main...HEAD · depth 2 · 3 changed files

Open the interactive graph → — click an area to see its dependent symbols at file:line.

github-actions Bot added a commit that referenced this pull request Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant