Skip to content

feat: state-aware CodeGraph integration for init flows + PreToolUse nudge hook#36

Merged
bdfinst merged 16 commits into
mainfrom
feat/codegraph-integration
Jun 1, 2026
Merged

feat: state-aware CodeGraph integration for init flows + PreToolUse nudge hook#36
bdfinst merged 16 commits into
mainfrom
feat/codegraph-integration

Conversation

@bdfinst
Copy link
Copy Markdown
Owner

@bdfinst bdfinst commented Jun 1, 2026

Summary

  • State-aware CodeGraph step in /init-dev-team. Classifies (installed × initialized) once at entry (command -v codegraph and [ -d .codegraph ]), then branches: install prompt → README link; init prompt → run codegraph init -i with surfaced output; silent confirmation when .codegraph/ is already present. Decisions persist under .claude/init-state.json with a top-level codegraph key. Stale-state override: live filesystem/PATH supersedes recorded preferences.
  • /init-dev-team JS bootstrap. When user selects JS/TS in a directory without package.json, the flow invokes /agentic-dev-team:js-project-init first, then proceeds to Stryker. Distinct messages for user-abort vs skill-failure; package-json-present path is byte-for-byte unchanged.
  • New codegraph-nudge.sh PreToolUse hook on Read|Grep|Glob. When a project has .codegraph/, warns once-per-turn when the tool call looks like multi-file exploration (Grep with non-file path, Glob with wildcard pattern) and no codegraph_* MCP tool has been used yet in this turn. Sentinel mechanism (codegraph-turn-mark.sh PostToolUse on mcp__codegraph__.*) avoids walking the full transcript on every Read/Grep/Glob. Blocks (exit 2) under /careful. Fail-open posture throughout — a broken hook never blocks legitimate calls.
  • Companion writing-team PR deferred to bdfinst/agentic-writing-team#36 — same state-aware CodeGraph step needs to land in /init-writing-team. Plan's DoD: dev-team merges first, writing-team mirror follows.

Quality Gate

  • Tests: 126/126 bats pass (75 pre-existing + 51 new: 23 hook tests, 6 settings tests, 22 command doc-inspection tests). Includes a perf benchmark — 20 invocations of the hot path, asserts median wall-clock < 50ms (current run: ~36–49ms median, dominated by python3/bash startup).
  • JSON valid: jq . plugins/agentic-dev-team/settings.json exits 0.
  • Shellcheck: clean on both new scripts.
  • Inline review: 4 reviewers (spec-compliance, security, concurrency, test-quality) ran during build; 5 findings applied in one pass (test isolation, vacuous assertion, settings regex, transcript scan cap, performance benchmark coverage).

Test Plan

  • Manual smoke 1 (warn path): drop .codegraph/ in a scratch dir, run a multi-file Grep, observe the warning to stderr. Activate /careful, repeat, observe exit 2.
  • Manual smoke 2 (sentinel suppression): run codegraph_context once, then run a multi-file Grep in the same turn → observe silence. Send a new user message, repeat → observe the warning returns.
  • Manual smoke 3 (JS bootstrap): run /init-dev-team in an empty directory, select JS/TS → js-project-init invoked, then Stryker installs without npm errors.
  • Manual smoke 4 (state matrix): run /init-dev-team in:
    • (a) a dir without codegraph on PATH → install prompt
    • (b) a dir with binary but no .codegraph/ → init prompt → accept → observe codegraph init -i runs
    • (c) a dir with .codegraph/ → silent confirmation only
    • (d) re-run case (a) after declining → state-aware skip note
    • (e) re-run case (a) after installing CodeGraph → recorded install_declined is overridden, init prompt fires

References

  • Spec: docs/specs/codegraph-integration.md
  • Plan: plans/codegraph-integration.md (status: implemented)
  • Hook docs: plugins/agentic-dev-team/docs/codegraph-nudge.md

🤖 Generated with Claude Code

bdfinst and others added 16 commits June 1, 2026 09:55
Spec covers state-aware init prompts (install/init/silent based on
'command -v codegraph' and '.codegraph/' presence), PreToolUse nudge
hook with sentinel-based turn detection, careful-mode block, JS
project bootstrap when no package.json. Plan decomposes into 11 TDD
steps; reviewed by four plan personas across two rounds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…heck

Plan step 1. New PreToolUse hook script that fails open and exits silently
when the project has no .codegraph/ index in cwd. Subsequent steps extend
this with tool-shape heuristics, sentinel-based turn detection, careful-mode
block, and registration in settings.json.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plan steps 2-3. Adds argument-shape heuristic for tool breadth — no
filesystem walk, no globstar, no glob expansion. Read always treated as
single-file. Grep is multi unless tool_input.path is a regular file. Glob
is multi when tool_input.pattern contains *, ?, or [. WARN_MSG kept as a
single-line tagged constant in the script and mirrored by EXPECTED_WARN_MSG
in the bats file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plan step 4. Adds hooks/codegraph-turn-mark.sh (PostToolUse on
mcp__codegraph__.*) which writes {transcript_id, turn_counter} to
${CLAUDE_PROJECT_DIR}/.claude/codegraph-turn-state.json after each
codegraph_* call. Extends codegraph-nudge.sh with a codegraph_used_this_turn
helper that reads that sentinel and suppresses the warning when both
fields match the current transcript and turn count.

The transcript_id is the basename-without-extension of transcript_path; the
turn_counter is grep -c '"type":"user"' on the transcript file. Both
sides compute identically so they agree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plan step 5. Reads plugins/agentic-dev-team/hooks/careful-state.json
(matching destructive-guard.sh's adjacent-file pattern). When
.active == true, the multi-file warning becomes a block: WARN_MSG plus
[blocked by /careful] suffix to stderr, exit 2. Missing/false careful-state
leaves the warn-then-exit-0 path unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plan step 6. Adds tests pinning the fail-open contract that was baked in
during steps 1–5 (per destructive-guard precedent: no global ERR trap,
per-call || true, every early-exit is exit 0). Covers malformed JSON,
empty stdin, missing jq on PATH, missing transcript file, and the same
patterns against codegraph-turn-mark.sh.

These tests pass against the existing implementation — they exist to lock
in the behavior so a future refactor cannot silently regress to a hook
that blocks tool calls on internal errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ings.json

Plan step 7. Three per-tool PreToolUse entries (Read, Grep, Glob) for
codegraph-nudge.sh, mirroring the unambiguous form rather than a regex
matcher (no Read|Grep|Glob precedent exists in this file). One PostToolUse
entry with regex matcher mcp__codegraph__.* for codegraph-turn-mark.sh.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plan step 8. Inserts Step 2.5 between hard-deps install and language
selection in /init-dev-team. The step:

- Classifies state via 'command -v codegraph' and '[ -d .codegraph ]'.
- Branches on the (installed, initialized) tuple — silent confirm when
  initialized; init prompt + execute 'codegraph init -i' when installed
  but not initialized; install prompt + README link otherwise.
- Records outcomes under top-level 'codegraph' key in
  .claude/init-state.json (state keys: install_accepted/install_declined/
  init_accepted/init_declined).
- Implements stale-state override: live filesystem/PATH supersedes
  recorded preferences (install_declined ignored when installed=true,
  init_declined ignored when initialized=true).

Doc-inspection tests in tests/commands/init_dev_team_codegraph_test.bats
pin each spec-mandated string. No runtime test surface (commands are
LLM-interpreted markdown); manual smoke 4 covers end-to-end behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…json

Plan step 9. Inserts a 'Bootstrap project if package.json is missing'
block before the existing 'Check if already installed (project-local)'
in the JS/TS Stryker section of /init-dev-team. When package.json is
absent, dispatches /agentic-dev-team:js-project-init to scaffold the
project, then proceeds. Distinct messages for user-abort vs skill-failure;
package.json-present path is byte-for-byte unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plan step 11. Adds /init-dev-team to the Slash Commands Registry in
CLAUDE.md (was missing) noting the state-aware CodeGraph offer and JS
bootstrap. Adds docs/codegraph-nudge.md describing the hook, fail-open
posture, sentinel mechanism, and how to silence / escalate it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- test-isolation: careful-state.json now cleaned by BATS setup/teardown
  (was inline-only, leaked on assertion failure).
- test-quality: mark_hook fail-open test pre-creates .claude/ so the
  absence assertion is non-vacuous.
- test-quality: settings.json anti-regression regex now catches any
  pipe-delimited matcher starting with Read/Grep/Glob, regardless of
  ordering.
- perf: cap transcript scan at last 1MB (tail -c 1048576) in both
  codegraph-nudge.sh and codegraph-turn-mark.sh. Transcripts grow
  unbounded across long sessions; without the cap the grep -c scaled
  linearly with session length and added latency to every Read/Grep/Glob.
- spec-coverage: add a performance benchmark bats test that runs 20
  invocations on the silent Read hot path and asserts median wall-clock
  under 50ms. Uses python3 for timing (a hard plugin dep; system bash on
  macOS is 3.2 and lacks EPOCHREALTIME).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Step 10 (writing-team mirror) deferred to bdfinst/agentic-writing-team#36.
Dev-team scope complete: 126 bats tests pass, perf benchmark under 50ms
median, four-reviewer inline checkpoint passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two doc surfaces missed during step 11:
- agent-architecture.md lists existing PreToolUse hooks; adds a parallel
  entry for codegraph-nudge alongside destructive-guard and pre-tool-guard.
- agentic-dev-team-reference.md's Slash Commands table is missing
  /init-dev-team; adds it under Workflow Commands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…raph-nudge

Records the two non-obvious design decisions plan-review flagged as
blockers in round 1: (1) write a sentinel from a PostToolUse mark hook
instead of parsing the transcript on every PreToolUse, and (2) classify
tool-call breadth from argument shape instead of walking the filesystem.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Companion to the existing adr-author agent. adr-author owns the decision
framework (when an ADR is warranted) and prose authoring; this skill owns
the CLI mechanics — adr new / new -s / new -l / link / list /
generate toc, and the editor caveat (EDITOR=true VISUAL=true) needed to
run 'adr new' from a non-interactive Claude shell without vim hanging.

Recorded as ADR-0003. Updated knowledge/agent-registry.md and the skill
count in CLAUDE.md (31 -> 32).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The adr-author agent already documented docs/adr/ as the canonical
location. adr-tools defaults to doc/adr/ and that's where ADRs 1-3
landed when we ran 'adr init' initially. Now aligned: ADRs moved
via git mv (history preserved), .adr-dir written so 'adr list' /
'adr generate toc' resolve to the new path, and the skill + ADR-3
updated to reference docs/adr/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bdfinst bdfinst merged commit 117a78e into main Jun 1, 2026
1 check passed
@bdfinst bdfinst deleted the feat/codegraph-integration branch June 1, 2026 16:04
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