Skip to content

feat(setup): implement antigravity integration setup and hook adapter…#1730

Merged
magyargergo merged 25 commits into
abhigyanpatwari:mainfrom
NilotpalK:feat/antigravity-support
May 25, 2026
Merged

feat(setup): implement antigravity integration setup and hook adapter…#1730
magyargergo merged 25 commits into
abhigyanpatwari:mainfrom
NilotpalK:feat/antigravity-support

Conversation

@NilotpalK

Copy link
Copy Markdown
Contributor

Summary

Adds Antigravity (Google) to the list of editors gitnexus setup configures automatically. Closes the gap
raised in #79.

When ~/.gemini/antigravity exists, setup now writes:

  • MCP server~/.gemini/antigravity/mcp_config.json (stdio entry, same shape as the Cursor/Claude Code
    configs).
  • JSON Hooks~/.gemini/config/hooks.json under a top-level gitnexus group, with PreToolUse
    (grep_search|run_command) and PostToolUse (run_command) entries per the Antigravity JSON Hooks
    docs
    .
  • Hook adapter + lock helpers~/.gemini/config/hooks/gitnexus/gitnexus-antigravity-hook.cjs (plus
    hook-lock.cjs and hook-db-lock-probe.cjs reused from the Claude adapter).
  • Skills~/.gemini/antigravity/skills/<name>/SKILL.md per the Antigravity skills
    codelab
    .

The adapter mirrors the Claude Code hook but respects Antigravity's contract differences:

  • Tool names are snake_case (grep_search, run_command) instead of Pascal-case (Grep, Glob, Bash).
  • PostToolUse stdout must be {} — stale-index hints go to stderr rather than via
    hookSpecificOutput.additionalContext.
  • PreToolUse surfaces graph context to the agent via { decision: "allow", reason: "..." } so the tool
    still runs.

Setup is idempotent: re-running detects existing gitnexus hook entries and skips duplicates. Corrupt config
files are left untouched (same safety policy as the other editor adapters).

Files changed

  • gitnexus/hooks/antigravity/gitnexus-antigravity-hook.cjs — new adapter.
  • gitnexus/src/cli/setup.tssetupAntigravity(), installAntigravityHooks(),
    installAntigravitySkills(), mergeAntigravityHooksJsonc(), wired into setupCommand.
  • gitnexus/src/cli/index.ts — updated setup command description.
  • gitnexus/test/unit/setup-antigravity.test.ts — 14 new tests.
  • README.md, gitnexus/README.md — Antigravity row in editor support table + manual MCP snippet.

Test plan

  • cd gitnexus && npx vitest run test/unit/setup-antigravity.test.ts — 14 passing locally.
  • cd gitnexus && npx vitest run test/unit/setup.test.ts test/unit/setup-codex.test.ts test/unit/setup-jsonc.test.ts test/unit/hooks.test.ts test/unit/cursor-hook.test.ts test/unit/setup-antigravity.test.ts — 238 passing locally (no regressions).
  • cd gitnexus && npx tsc --noEmit — clean.
  • Manual: with Antigravity installed, run gitnexus setup and verify mcp_config.json, hooks.json,
    hook adapter files, and skills/ directory are all written.
  • Manual: re-run gitnexus setup and confirm hook entries are not duplicated.
  • Manual: in an indexed repo, run a grep_search from Antigravity and confirm graph context surfaces; run
    git commit and confirm a stale-index hint appears on stderr after the index drifts.

Refs #79

@vercel

vercel Bot commented May 20, 2026

Copy link
Copy Markdown

@NilotpalK is attempting to deploy a commit to the NexusCore Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

CI Report

All checks passed

Pipeline Status

Stage Status Details
✅ Typecheck success tsc --noEmit
✅ Tests success unit tests, 3 platforms
✅ E2E success gitnexus-web changes only

Test Results

Tests Passed Failed Skipped Duration
9850 9847 0 3 604s

✅ All 9847 tests passed

3 test(s) skipped — expand for details
  • PHP pipeline benchmark > scales with file count (workers enabled)
  • Rust pipeline benchmark > scales with file count (workers enabled)
  • buildTypeEnv > known limitations (documented skip tests) > Ruby block parameter: users.each { |user| } — closure param inference, different feature

Code Coverage

Tests

Metric Coverage Covered Base Delta Status
Statements 80.01% 33988/42478 N/A% 🟢 ████████████████░░░░
Branches 68.54% 21722/31689 N/A% 🟢 █████████████░░░░░░░
Functions 84.99% 3522/4144 N/A% 🟢 ████████████████░░░░
Lines 83.51% 30613/36656 N/A% 🟢 ████████████████░░░░

📋 View full run · Generated by CI

The MCP entry assertion expected `npx` directly, but on Windows
`getMcpEntry()` wraps it as `cmd /c npx ...`, which broke the Windows
runner. Pin platform to darwin in beforeEach so the existing assertion
is deterministic, restore the descriptor in afterEach, and add a
parity test for the win32 cmd-wrapper shape.
@github-actions

github-actions Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @magyargergo's task in 5m 28s —— View job


PR #1730 Production-Readiness Review

Reviewer persona: Senior GitNexus maintainer + Expert Antigravity setup engineer + LLM/tooling engineer

Todo List

  • Post initial comment
  • Read repo docs (AGENTS.md, GUARDRAILS.md, CONTRIBUTING.md — DoD.md not present, using CONTRIBUTING.md + GUARDRAILS.md as the bar)
  • Read changed files: hook adapter, setup.ts, tests, README, index.ts
  • Read reference files: Claude hook, hook helpers, skills
  • Run branch hygiene checks
  • Check CI status and job details
  • Analyze Lane A: MCP setup
  • Analyze Lane B: JSON Hooks setup
  • Analyze Lane C: Hook adapter correctness
  • Analyze Lane D: LLM context quality
  • Analyze Lane E: Skills
  • Analyze Lane F: Docs accuracy
  • Analyze Lane G: Cross-platform and packaging
  • Analyze Lane H: Existing integrations regression
  • Compile all findings and write final verdict

1. Review bar for this PR

DoD.md is absent from the repo. The bar used is GUARDRAILS.md + CONTRIBUTING.md:

  • All changed files are required for the fix/feature, no unrelated formatting (GUARDRAILS.md § Scope)
  • Tests pass on Linux, macOS, and Windows (CONTRIBUTING.md § Before you open a PR)
  • No secrets, no machine-specific paths committed
  • Documentation updated for user-visible CLI behavior
  • npx tsc --noEmit clean (CONTRIBUTING.md § Typecheck)

2. Problem being solved

Issue #79 requests Google Antigravity support in gitnexus setup. The PR implements automatic detection of ~/.gemini/antigravity, writes MCP config to mcp_config.json, JSON Hooks to ~/.gemini/config/hooks.json, a hook adapter to ~/.gemini/config/hooks/gitnexus/, and skills to ~/.gemini/antigravity/skills/. Per the PR body, Antigravity differs from Claude Code in tool naming (snake_case), PostToolUse stdout contract ({}), and PreToolUse context delivery ({ decision: "allow", reason } instead of hookSpecificOutput).


3. Current PR state

  • 3 topical commits: feat/setup, docs/readme, test/pin-platform
  • 6 files changed: +978/-11
  • Changed files are strictly Antigravity-scoped (no unrelated churn)
  • Typecheck: ✅ passes (verified via CI job quality / typecheck)
  • Lint/format: ✅ passes (CI jobs quality / format, quality / lint)

4. Merge status and mergeability

CI is failing. The PR is NOT mergeable in its current state.

From get_workflow_run_details on run 26207219127 (latest, on head commit 83d2f3c):

Job Status
tests / ubuntu / coverage ✅ success
tests / macos-latest ✅ success
tests / windows-latest failure — step 4 "Run npx vitest run"
quality / typecheck ✅ success
quality / format ✅ success
quality / lint ✅ success
CI Gate ❌ failure (depends on windows job)

Commit 83d2f3c was pushed as "fix Windows CI failure" but the Windows job is still failing on the current head. The test plan claims 238 passing locally — local claims do not substitute for green CI on all three platforms.


5. Repository history considered


6. Branch hygiene assessment

Clean. Three topical commits, all files relate to Antigravity setup. No merge-from-main commit. No formatting sweeps or unrelated changes. git log confirms feat(setup), docs(readme), test(setup-antigravity) are the only additions on this branch.


7. Understanding of the change

gitnexus/hooks/antigravity/gitnexus-antigravity-hook.cjs — New adapter (325 lines). Mirrors the Claude hook with snake_case tool names (grep_search/run_command), {} PostToolUse stdout, and { decision: "allow", reason } PreToolUse output. Shares isGlobalRegistryDir/walkForGitNexusDir/findCanonicalRepoRoot logic with Claude hook.

gitnexus/src/cli/setup.ts — Adds setupAntigravity, installAntigravitySkills, installAntigravityHooks, mergeAntigravityHooksJsonc, antigravityHasGitnexusHook. Antigravity is detected by ~/.gemini/antigravity existence. MCP config goes to mcp_config.json, hooks to ~/.gemini/config/hooks.json under a gitnexus top-level group.

gitnexus/src/cli/index.ts — Setup command description updated to include Antigravity.

gitnexus/test/unit/setup-antigravity.test.ts — 14 tests: MCP write, win32 shape, skip behavior, key preservation, corrupt file, hooks.json write, idempotency, helper copy, skill layout, adapter stdout/stderr contract, non-git command, stale index, no-.gitnexus no-op, unknown tool no-op.


8. Findings


Finding 1: Windows CI still failing after 83d2f3c platform-pin fix
Risk: The PR cannot merge with a failing Windows CI job. Commit 83d2f3c was pushed to fix the Windows failure but run 26207219127 on head shows tests / windows-latest failing at "Run npx vitest run" (job 77109582068). The platform-pin in setup-antigravity.test.ts:80 (setPlatform('darwin') by default) and the win32 shape test were added as fixes, but the Windows runner is still failing. The actual failure reason in the Windows logs has not been downloaded, but it is confirmed broken.
Evidence: mcp__github_ci__get_workflow_run_details run 26207219127, job tests / windows-latest, step 4 failed.
Recommended fix: Download the Windows job log to identify the actual test failure, then fix. The platform-pin approach only fixes the MCP shape assertion — if the adapter itself has Windows-specific execution issues, those need separate fixes.
Blocks merge: YES


Finding 2: win-rm-list-json.ps1 not copied to Antigravity hook directory
Risk: hook-db-lock-probe.cjs loads win-rm-list-json.ps1 via path.join(__dirname, 'win-rm-list-json.ps1') (hook-db-lock-probe.cjs:73). The Claude hook setup copies this file (setup.ts:387–394):

await fs.copyFile(
  path.join(pluginHooksPath, 'win-rm-list-json.ps1'),
  path.join(destHooksDir, 'win-rm-list-json.ps1'),
);

The Antigravity setup (installAntigravityHooks, setup.ts:641–648) only copies hook-lock.cjs and hook-db-lock-probe.cjs — not the PowerShell script. On Windows, getWindowsRmListEncodedCommand() will catch the missing file, cache null, and hasGitNexusServerOwnerWindows returns false (fail-open). The MCP server ownership check silently stops working on Windows, potentially allowing the hook and MCP server to contend on the LadybugDB simultaneously — the exact failure mode the probe exists to prevent.
Evidence: setup.ts:641–648 (Antigravity copies) vs setup.ts:387–394 (Claude copies). hook-db-lock-probe.cjs:73 (__dirname reference). The hooks/antigravity/ dir has no .ps1.
Recommended fix: Add a copy for win-rm-list-json.ps1 in installAntigravityHooks analogous to the Claude Code hook setup.
Blocks merge: YES (broken Windows behavior)


Finding 3: timeout: 10000 unit is unverified — potential 10,000-second hang
Risk: Claude Code hooks use timeout: 10 (seconds, per Claude Code's settings.json schema). Antigravity hooks are configured with timeout: 10000 (setup.ts:670, 679). If Antigravity's hook timeout unit is also seconds, each hook invocation would be allowed up to 2.7 hours before timing out. If it's milliseconds, 10000 ms = 10 s matches Claude's intention. The discrepancy is unexplained in the PR and unverified against Antigravity documentation.
Evidence: setup.ts:670: timeout: 10000 vs setup.ts:428: timeout: 10. No comment explaining the unit change.
Recommended fix: Verify unit from Antigravity docs and add a comment. If milliseconds, note explicitly: timeout: 10000 // ms (Antigravity uses ms, unlike Claude Code's seconds). If seconds, change to 10.
Blocks merge: YES (if seconds: catastrophic; unit must be confirmed before merge)


Finding 4: PreToolUse { decision: "allow", reason } output contract is unverified
Risk: The adapter writes JSON.stringify({ decision: 'allow', reason: context }) to stdout for PreToolUse enrichment (hook adapter:227). The code comment claims this is "the documented way to surface extra context to Antigravity without blocking the tool call." If reason is an internal permission-decision annotation not shown to the agent (e.g., audit logging), the entire graph context enrichment feature silently provides zero value to the agent with no error. The PR body asserts this is correct behavior but cannot be verified without Antigravity's actual hook protocol documentation.
Evidence: gitnexus-antigravity-hook.cjs:224–228. Contrast with Claude hook which uses hookSpecificOutput.additionalContext (gitnexus-hook.cjs:279–283).
Recommended fix: Verify against Antigravity JSON Hooks documentation that { decision: "allow", reason: <string> } in PreToolUse stdout causes the reason text to be surfaced to the agent as context. If a different field (e.g., context, message, additionalContext) is the documented channel, use that instead. Add a docs link in the comment.
Blocks merge: YES (if reason is not surfaced to agent, the core enrichment feature is silently broken)


Finding 5: hooks.json top-level gitnexus group schema is unverified
Risk: The generated hooks.json has the shape { "gitnexus": { "PreToolUse": [...], "PostToolUse": [...] } } (setup.ts:527–530). The comment says "Antigravity's hooks.json layout is a flat object keyed by integration name." If Antigravity actually expects { "hooks": { "PreToolUse": [...] } } (like Claude) or any other shape, the entire hooks configuration would be silently ignored at runtime with no error. The test (setup-antigravity.test.ts:183) verifies config.gitnexus.PreToolUse exists in the written file — it tests the write, not Antigravity's consumption.
Evidence: setup.ts:527–530. mergeAntigravityHooksJsonc uses [group, eventName, ...] path (setup.ts:581). The PR body links to https://antigravity.google/docs/features but this is not independently verifiable in this review.
Recommended fix: Cite the specific Antigravity docs section that confirms top-level integration grouping. If unsupported, change mergeAntigravityHooksJsonc to write the documented flat { "hooks": { ... } } shape using a per-integration matcher prefix (gitnexus-*) for scoping.
Blocks merge: YES (if schema is wrong, hooks do nothing)


Finding 6: Summary output includes hooks entries in "MCP configured for:"
Risk: The summary filter at setup.ts:978 is result.configured.filter((c) => !c.includes('skills')). This filters skills but includes hook entries, so output reads:

MCP configured for: Cursor, Claude Code, Antigravity, Claude Code hooks (PreToolUse, PostToolUse), Antigravity hooks (PreToolUse, PostToolUse), OpenCode, Codex

This conflates "MCP servers configured" with "hooks configured" and is confusing for users. Note: this is a pre-existing issue for Claude Code hooks, not introduced by this PR. Antigravity simply joins the same pool.
Evidence: setup.ts:977–979. Pre-existing for "Claude Code hooks" entry.
Recommended fix: Add a second filter or dedicated category for hooks in the summary. Or filter !c.includes('hooks') from the MCP line and add a separate "Hooks installed for:" line.
Blocks merge: NO (pre-existing issue, UX quality only)


Finding 7: run_command pattern extraction silently misses quoted patterns starting with short tokens
Risk: In extractPattern (hook adapter:112–153), whitespace-splitting rg "my pattern" ./src gives tokens ['rg', '"my', 'pattern"', './src']. The first non-flag positional after rg is "my → stripped to my (2 chars < 3 minimum) → returns null. No augmentation for patterns whose quoted first word is ≤ 2 characters. For -e "pattern": -e sets skipNext, "pattern" is skipped, next token is the path — also missed. These are realistic rg/grep invocations.
Evidence: hook adapter:115–148. The Claude hook's Bash handler has identical whitespace-split logic (gitnexus-hook.cjs:147) — this is a pre-existing limitation inherited in the Antigravity adapter.
Recommended fix: The short-token case is a graceful no-augmentation degradation, not a broken tool run. Still worth a test case documenting the known limitation. Adding handling for -e <pattern> (return the skipped token after -e) would improve coverage.
Blocks merge: NO (graceful degradation, pre-existing pattern)


Finding 8: Installed skills contain Claude-specific guidance
Risk: gitnexus/skills/gitnexus-cli.md:83 reads "Restart Claude Code to reload the MCP server." When this skill is installed for Antigravity agents, the instruction routes them to restart the wrong editor. Pre-existing design: all editors share the same skill pool.
Evidence: gitnexus/skills/gitnexus-cli.md:83. installAntigravitySkills uses the shared installSkillsTo (setup.ts:509–523).
Recommended fix: Make the restart guidance editor-agnostic ("Restart your AI editor to reload the MCP server"). This is a pre-existing issue across Cursor/OpenCode/Codex skills too.
Blocks merge: NO (pre-existing, minor UX)


Finding 9: README manual Antigravity section does not include hooks.json snippet
Risk: README.md:172–185 shows the manual mcp_config.json snippet with a note that gitnexus setup also writes hooks.json and installs skills, but provides no manual hooks.json example. Users who prefer manual setup (as suggested by the "If you prefer to configure manually" framing) have no reference for hook configuration.
Evidence: README.md:172–185.
Recommended fix: Add an Antigravity manual hooks.json snippet analogous to the Claude Code section. Alternatively, explicitly state "hooks require gitnexus setup (no manual snippet provided)."
Blocks merge: NO (doc gap, minor)


9. PR-specific assessment sections

Lane A — MCP setup
Path detection (~/.gemini/antigravity), mcp_config.json merge via shared mergeJsoncFile, key preservation, corrupt-file safety, and Windows cmd /c npx shape are all correctly implemented and tested (tests 1–4, win32 test). Package.json "files" includes "hooks" so the adapter ships in the tarball. ✅ The NPX_REF pinning rationale is documented at setup.ts:24–36. ✅

Lane B — JSON Hooks setup
mergeAntigravityHooksJsonc correctly writes a top-level group key instead of the Claude-style { hooks: { … } }. Idempotency guard antigravityHasGitnexusHook (setup.ts:589–600) checks parsed?.gitnexus?.[eventName] for existing command strings. Tests cover idempotency and group structure. However: both the group schema and the timeout unit are unverified (Findings 3 and 5). This lane cannot be confirmed green.

Lane C — Hook adapter correctness
readInput, isGlobalRegistryDir, walkForGitNexusDir, findCanonicalRepoRoot, findGitNexusDir, resolveCliPath, runGitNexusCli are all faithfully ported from the Claude hook. handlePreToolUse returns without output when no context is found (no stdout pollution). handlePostToolUse always calls writeEmpty() before returning via every exit path — verified: lines 237–238, 243–244, 250–252, 255–257, 261–263, 280–282, 295–298, 305. The stale-index hint goes to stderr only (line 301). ✅ The GITNEXUS_DEBUG conditional present in Claude's extractAugmentContext is absent in the Antigravity adapter (minor observability gap). Finding 4 (PreToolUse output contract) is unresolved in this lane.

Lane D — LLM context quality
When graph context is found, it is delivered as the full [GitNexus]-tagged output from gitnexus augment. The minimum 3-char pattern gate prevents augmenting single-letter queries. No evidence of context-length capping — if augment returns a very large response, the entire body goes into reason. For large codebases with many matching symbols this could be verbose, but it's bounded by the augment command's own output limits, consistent with the Claude hook. Stale-index hints emit only after git commit/merge/rebase/cherry-pick/pull with exit_code 0 — not on every run_command. ✅

Lane E — Skills
Skills are installed under ~/.gemini/antigravity/skills/<name>/SKILL.md per the codelab path. All skills are plain .md files with YAML frontmatter (name, description). The shared installSkillsTo function is used — same as Claude Code, Cursor, OpenCode. Skill content works for any MCP-capable editor (tool names in skills are MCP tool names, not editor-specific). Exception: Claude-specific text in gitnexus-cli.md:83 (Finding 8). Overwrite is silent: re-running setup silently overwrites user-modified skills — pre-existing behavior.

Lane F — Docs
README.md lists Antigravity as "Full" support (MCP + Skills + Hooks). This is a strong claim. With Findings 3, 4, and 5 unresolved, "Full" support is not yet substantiated. The manual MCP snippet uses gitnexus@latest (quickstart doc, intentional per setup.ts:29). The gitnexus setup note mentions hooks.json and skills. No docs claim behavior that depends on manual setup except the hooks/skills note. Line 185 could be expanded for manual hooks (Finding 9).

Lane G — Cross-platform and packaging
Package files includes "hooks" → adapter ships in tarball (verified in package.json). Setup rewrites the baked-in CLI path at install time for both adapters. win-rm-list-json.ps1 is not copied (Finding 2). No new dependencies. .cjs files use only Node builtins — no cross-platform concerns beyond the .ps1 gap.

Lane H — Existing integrations regression
setupAntigravity, installAntigravitySkills, installAntigravityHooks are new functions that only run when ~/.gemini/antigravity exists. Existing setupCursor, setupClaudeCode, setupOpenCode, setupCodex are unchanged. Setup result categories are the same (configured, skipped, errors). Pre-existing summary UX bug is not worsened beyond adding one more hooks entry (Finding 6). No evidence of regression to existing setup/hook tests.


10. Back-and-forth avoided by verifying


11. Open questions (unavoidable — require Antigravity documentation)

  1. timeout unit: Does Antigravity's hooks.json schema interpret the timeout field as seconds or milliseconds? If seconds, 10000 must be changed to 10.
  2. PreToolUse stdout contract: Does { decision: "allow", reason: "<text>" } in PreToolUse stdout cause <text> to be shown to the agent as context? Or is reason an internal field?
  3. hooks.json grouping schema: Does Antigravity support a top-level integration-keyed grouping { "gitnexus": { "PreToolUse": [...] } }, or does it require a different schema?

These three questions correspond to Findings 3, 4, and 5 respectively and must be answered with evidence from Antigravity documentation before this PR can merge.


12. Final verdict

not production-ready

The PR has correct structural foundations — the adapter logic, index discovery, idempotency guards, worktree support, and corrupt-file safety are all well-implemented. However, five blocking issues prevent merge:

  1. Windows CI is still failing on head commit 83d2f3c (tests / windows-latest, step "Run npx vitest run"). The platform-pin fix was insufficient.
  2. win-rm-list-json.ps1 is not copied into the Antigravity hook directory, causing the Windows MCP server lock probe to silently fail open — the exact production bug it was designed to prevent.
  3. Hook timeout unit (10000) is unverified. If Antigravity expects seconds (like Claude Code's 10), this value causes hooks to hang for 10,000 seconds.
  4. PreToolUse output contract ({ decision: "allow", reason }) is unverified. If reason is not surfaced to the agent, the enrichment feature silently provides nothing.
  5. hooks.json top-level gitnexus group schema is unverified. If Antigravity does not support this grouping, all hooks are silently ignored.

Items 3–5 require Antigravity documentation verification. Item 2 is a concrete code fix. Item 1 requires diagnosing and fixing the Windows test failure.

View CI run ·

magyargergo and others added 10 commits May 21, 2026 08:53
…ws CI

Rebase the Antigravity integration on the canonical Gemini CLI hooks
contract (https://geminicli.com/docs/hooks/reference/), which is the
documented schema Antigravity 2.0 inherits:

- Hook adapter: replace PreToolUse/PostToolUse with the single AfterTool
  event. BeforeTool has no documented context-injection channel in the
  Gemini contract, so augmentation runs in AfterTool where
  hookSpecificOutput.additionalContext is the documented way to append
  text to the tool result the agent reads. Stale-index hints land in the
  same channel (so the agent sees them) and are mirrored to stderr for
  terminal users. Tool-name matcher updated to Gemini CLI snake_case
  (search_file_content|glob|run_shell_command).
- Setup: write hooks to ~/.gemini/settings.json under canonical
  hooks.AfterTool[] (replaces the ad-hoc hooks.json top-level group).
  Polite-neighbor merge preserves existing user hooks. Also copy
  win-rm-list-json.ps1 alongside hook-db-lock-probe.cjs so the Windows
  MCP server ownership probe doesn't silently fail open.
- Tests: 17 regression tests covering MCP write, win32 shape, hook
  schema, polite-neighbor merge, idempotency, adapter context emission,
  stale-index hint, and skill layout.
- README: footnote documenting the AfterTool design choice and a link
  to the Gemini CLI hooks reference.

Windows CI fix: installSkillsTo previously used glob('*.md') +
glob('*/SKILL.md'), which returned zero matches under the Windows
runner's temp paths (8.3 short-name like RUNNER~1). Replace with
fs.readdir + dirent type checks — same behavior, no path quirks. This
fixes the only failing Windows job on the PR.
@magyargergo magyargergo linked an issue May 24, 2026 that may be closed by this pull request
@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Claude finished @magyargergo's task in 7m 22s —— View job


PR #1730 Production-Readiness Review (Three-Lens)

Reviewer persona: Senior GitNexus CLI/MCP reviewer · Senior Gemini CLI hooks reviewer · Senior Antigravity integration reviewer

Todo List

  • Post initial comment
  • Read repo docs (AGENTS.md, GUARDRAILS.md, CONTRIBUTING.md, ARCHITECTURE.md)
  • Read changed files: hook adapter, setup.ts, index.ts, tests, READMEs
  • Read reference files: Claude hook, hook helpers, existing setup tests
  • Check package.json for hook file inclusion
  • Run diff analysis and branch hygiene checks
  • Check CI status
  • Run Unicode/bidi scan on changed files
  • Run targeted search terms (stale schema refs, augment --, windowsHide, etc.)
  • Analyze Lane A: Antigravity setup paths and config schema
  • Analyze Lane B: Gemini/Antigravity hook contract
  • Analyze Lane C: Hook adapter runtime behavior
  • Analyze Lane D: Setup JSON/JSONC merging and idempotency
  • Analyze Lane E: Existing editor regression risk
  • Analyze Lane F: Tests and CI
  • Analyze Lane G: Docs/user-facing claims
  • Analyze Lane H: Branch hygiene
  • Compile all findings and write final verdict

Review bar for this PR

DoD.md is absent. Bar applied: GUARDRAILS.md + CONTRIBUTING.md.

  • All changed files required for the fix/feature, no unrelated churn
  • Tests pass on Linux, macOS, Windows
  • No secrets, no machine-specific paths committed
  • Documentation updated for user-visible CLI behavior
  • npx tsc --noEmit clean

Problem being solved

Issue #79 requests Google Antigravity editor support in gitnexus setup. This PR implements: detection of ~/.gemini/antigravity, MCP config at mcp_config.json, skills at ~/.gemini/antigravity/skills/, and a hook adapter under ~/.gemini/config/hooks/gitnexus/ registered in ~/.gemini/settings.json under hooks.AfterTool using the Gemini CLI contract.


Current PR state

  • Functional commits: ceca820 (feat), b6f9668 (docs), 83d2f3c (test platform pin), c1872b4 (schema realignment to Gemini CLI)
  • 10+ Merge branch 'main' into feat/antigravity-support merge commits
  • 6 changed files: README.md, gitnexus/README.md, gitnexus/hooks/antigravity/gitnexus-antigravity-hook.cjs, gitnexus/src/cli/index.ts, gitnexus/src/cli/setup.ts, gitnexus/test/unit/setup-antigravity.test.ts

Merge status and mergeability

CI Gate: failing. However, the root cause is a transient infrastructure failure.

From run 26386362130 (latest, head commit 3f110b4):

Job Status
tests / ubuntu / coverage ✅ success
tests / windows-latest (platform-sensitive) ✅ success
tests / macos-latest (platform-sensitive) ✅ success
tests / packaged install smoke (ubuntu) ✅ success
tests / packaged install smoke (windows) ✅ success
quality / typecheck ✅ success
quality / format ✅ success
quality / lint ✅ success
e2e / Check web module changes ✅ success
scope-parity / scope-resolution parity failure — step 3 "Run ./.github/actions/setup-gitnexus"
CI Gate ❌ failure (depends on above)

The failure log shows npm error code: 'ENETUNREACH' — the npm registry was unreachable during the setup-gitnexus action, a transient network error. All actual test and quality jobs pass. The scope-parity failure is unrelated to this PR's changes. The CI gate failure is therefore not a blocker from a code-quality perspective.


Repository history considered


Branch hygiene assessment

Messy, but functionally clean. The branch has 10+ merge-from-main commits. The final diff is exactly 6 expected files — no unrelated churn. CONTRIBUTING.md doesn't mandate a clean linear history, so this is a style issue, not a blocker. A squash before merge is recommended to reduce noise.


Understanding of the change

gitnexus/hooks/antigravity/gitnexus-antigravity-hook.cjs — 327-line adapter. Reads Gemini CLI AfterTool events (hook_event_name: 'AfterTool'), extracts search patterns from search_file_content, glob, grep_search, run_shell_command tool calls, augments with gitnexus augment -- <pattern>, and emits hookSpecificOutput.additionalContext via stdout. Stale-index hints after git commit/merge/rebase go to both additionalContext and stderr. Shares isGlobalRegistryDir / walkForGitNexusDir / findCanonicalRepoRoot with Claude hook.

gitnexus/src/cli/setup.ts — Adds setupAntigravity, installAntigravitySkills, installAntigravityHooks, mergeGeminiSettingsHooks, geminiHasGitnexusHook. The hooks section writes ~/.gemini/settings.json under hooks.AfterTool using jsonc-parser, with idempotency guard and JSONC-preserving merge. win-rm-list-json.ps1 is now correctly copied (lines 659-664) — this was the fix in c1872b4.

gitnexus/test/unit/setup-antigravity.test.ts — 17 tests covering: MCP write, win32 shape, skip, key preservation, corrupt file, settings.json AfterTool write, idempotency, polite-neighbor merge, helper copy (including .ps1), skill layout, and adapter child-process smoke tests.


Findings


Finding 1: windowsHide: true missing from all spawnSync calls in the Antigravity hook

  • Severity: blocker
  • Risk: PR fix(windows): pass windowsHide:true to every child_process spawn-family call #1794 (fix(windows): pass windowsHide:true to every child_process spawn-family call) landed on main and added windowsHide: true to every spawnSync call in the Claude hook. The Antigravity adapter was written before this fix and the merge-from-main commits did not propagate the change into the new file. On Windows, every spawnSync call without windowsHide: true opens a visible console window for the duration of the call. The adapter has three affected sites:
    • findCanonicalRepoRoot (line 62): spawnSync('git', ['rev-parse', ...])
    • runGitNexusCli (lines 175, 182): both the process.execPath and npx.cmd branches
    • buildStaleIndexHint (line 274): spawnSync('git', ['rev-parse', 'HEAD'])
  • Evidence: grep windowsHide gitnexus/hooks/antigravity/gitnexus-antigravity-hook.cjs returns no matches. grep windowsHide gitnexus/hooks/claude/gitnexus-hook.cjs returns lines 80, 222, 231, 321.
  • Recommended fix: Add windowsHide: true to all four spawnSync call sites in the Antigravity adapter, matching the Claude hook.
  • Blocks merge: yes — Windows-specific regression relative to code already on main. Fix this →

Finding 2: gitnexus/README.md:37 documents the OLD schema

  • Severity: blocker
  • Risk: After commit c1872b4 realigned the implementation to the Gemini CLI contract, the gitnexus/README.md editor table was not updated. Line 37 currently reads:
    | Antigravity (Google) | Yes | Yes | Yes (PreToolUse + PostToolUse, JSON Hooks) | Full |
    
    The link points to https://antigravity.google/docs/features. The actual final implementation uses AfterTool in ~/.gemini/settings.json under the Gemini CLI hooks schema (https://geminicli.com/docs/hooks/reference/). The root README.md:121 was correctly updated (says "AfterTool"), but gitnexus/README.md was not. This tells future maintainers and users the wrong hook event name and links to the wrong docs page.
  • Evidence: gitnexus/README.md:37 — "PreToolUse + PostToolUse, JSON Hooks". Root README.md:121 — "AfterTool, Gemini CLI hooks schema". Final installAntigravityHooks registers AfterTool only.
  • Recommended fix: Update gitnexus/README.md:37 to say "AfterTool" and link to https://geminicli.com/docs/hooks/reference/, matching README.md:121.
  • Blocks merge: yes — Published README contradicts the implementation. Fix this →

Finding 3: Stale block comment at setup.ts:470-480 documents the old design

  • Severity: major
  • Risk: The block comment immediately preceding setupAntigravity was written for the original hooks.json design and was not updated after c1872b4. It states:
    // Antigravity stores its MCP config under ~/.gemini/antigravity/ and its
    // JSON Hooks config under ~/.gemini/config/hooks.json. The hooks schema is
    // the same {matcher, hooks:[{type:"command",command}]} shape Antigravity
    // inherited from Gemini CLI, but grouped under a top-level `gitnexus` key
    // so multiple integrations can coexist without colliding on event arrays.
    //
    // Tool names differ from Claude Code: `grep_search` and `run_command`
    // (snake_case) replace `Grep`/`Glob`/`Bash`. PostToolUse stdout must be `{}`
    // — see the antigravity hook adapter for the contract.
    
    Everything after the first sentence is wrong: (a) the config file is ~/.gemini/settings.json, not ~/.gemini/config/hooks.json; (b) there is no top-level gitnexus group; (c) the tool names are search_file_content|glob|run_shell_command, not grep_search/run_command; (d) there is no PostToolUse — everything is AfterTool.
  • Evidence: setup.ts:472-480 vs final installAntigravityHooks (setup.ts:620-719) which writes settings.json under hooks.AfterTool with search_file_content|glob|run_shell_command.
  • Recommended fix: Rewrite the block comment to describe the actual implementation.
  • Blocks merge: no — Runtime behavior is correct; comment is the only wrong artifact. But it will confuse the next maintainer. Fix this →

Finding 4: grep_search in extractPattern is dead code

  • Severity: major
  • Risk: extractPattern at adapter line 107 handles toolName === 'grep_search' alongside search_file_content and glob. The registered matcher in installAntigravityHooks is search_file_content|glob|run_shell_command. Gemini/Antigravity will only invoke the hook for tools matching that pattern — grep_search is not in the matcher, so if the hook fires it will never see tool_name: 'grep_search'. The doc comment at adapter line 211 also still lists grep_search. This is a relic from the first design where grep_search was the Antigravity search tool name.
  • Evidence: gitnexus-antigravity-hook.cjs:107toolName === 'grep_search'. setup.ts:689 — matcher is 'search_file_content|glob|run_shell_command'.
  • Recommended fix: Remove || toolName === 'grep_search' from extractPattern line 107 and remove the mention of grep_search from the comment at line 211. If grep_search is an additional real Antigravity tool name that should be handled, add it to the installAntigravityHooks matcher instead.
  • Blocks merge: no — Dead code, not a runtime failure. Fix this →

Finding 5: timeout: 10000 lacks a unit comment

  • Severity: minor
  • Risk: The Claude Code hook registration uses timeout: 10 (seconds, per Claude Code's settings.json schema). The Antigravity/Gemini hook registration uses timeout: 10000 (setup.ts:695). If reviewers or future maintainers assume the same unit, they would read this as 10,000 seconds. Based on the Gemini CLI hooks reference and the adapter's internal 7000ms timeout to runGitNexusCli, this is almost certainly milliseconds (= 10 s), which is the correct value. But no comment says so.
  • Evidence: setup.ts:695: timeout: 10000 (Antigravity). setup.ts:444: timeout: 10 (Claude Code). adapter:259: runGitNexusCli(cliPath, [...], cwd, 7000) (ms).
  • Recommended fix: Add // ms (Gemini CLI uses ms; Claude Code uses seconds) next to the timeout: 10000 line.
  • Blocks merge: no — Clarification only.

Finding 6: GITNEXUS_DEBUG observability gap in adapter

  • Severity: minor
  • Risk: The Claude hook's extractAugmentContext logs discarded augment stderr prefixes when GITNEXUS_DEBUG=1, enabling operators to see filtered diagnostics. The Antigravity adapter's extractAugmentContext (line 92-96) omits this debug path entirely.
  • Evidence: gitnexus-antigravity-hook.cjs:92-96 vs gitnexus-hook.cjs:112-128.
  • Recommended fix: Add the GITNEXUS_DEBUG branch to extractAugmentContext for consistency.
  • Blocks merge: no

Finding 7: stageAdapter in tests does not copy win-rm-list-json.ps1

  • Severity: minor
  • Risk: The stageAdapter helper (test lines 297-303) copies the adapter and lock helpers to a temp dir for child-process smoke tests but does not copy win-rm-list-json.ps1. On Windows CI, hook-db-lock-probe.cjs will fail to load the .ps1, cache null, and the Windows lock-probe path will be skipped (fail-open) during the smoke tests. The copies adapter + lock helpers test (line 236) correctly asserts the .ps1 is installed by setupCommand, but the adapter's Windows DB-lock behavior is untested in child-process scenarios.
  • Evidence: test:297-303 — copies adapter, hook-lock.cjs, hook-db-lock-probe.cjs. No .ps1. The packaged Windows smoke test passed CI, so install works, but the hook's Windows lock-probe is not exercised.
  • Recommended fix: Add win-rm-list-json.ps1 to stageAdapter. At minimum, add a test-only assertion that the adapter doesn't crash when the .ps1 is absent.
  • Blocks merge: no

Finding 8: win-rm-list-json.ps1 IS correctly copied — previous review finding resolved

  • Severity: N/A (informational)
  • The prior automated review (Finding 2) flagged win-rm-list-json.ps1 as missing. The final code at setup.ts:659-664 does include it in the copy loop with a comment explaining its purpose. The test at setup-antigravity.test.ts:248 also asserts its presence. This was fixed in c1872b4. ✅

Finding 9: No bidi/hidden Unicode in changed files

  • Severity: N/A (pass)
  • Grep for Unicode bidi controls (U+202A–U+202E, U+2066–U+2069) found no matches in any of the 6 changed files. ✅

PR-specific assessment sections

Antigravity setup paths and config schema
Detection path (~/.gemini/antigravity) is unverifiable against a live Antigravity docs page from within this review, but it is the path all comments, tests, and README snippets consistently use, and it matches the ~/.gemini/ root that Gemini CLI is documented to own. MCP config at ~/.gemini/antigravity/mcp_config.json and skills at ~/.gemini/antigravity/skills/<name>/SKILL.md are internally consistent across code, tests, and README. Hook files at ~/.gemini/config/hooks/gitnexus/ and settings at ~/.gemini/settings.json match the Gemini CLI hooks reference URL cited in the code. The mcp_config.json schema ({ mcpServers: { gitnexus: { command, args } } }) matches all other editors. ✅ (modulo Finding 2 — gitnexus/README.md still says hooks.json)

Gemini/Antigravity hook contract
AfterTool is the correct event for post-execution context injection. Stdout is JSON-only (writeAdditionalContext writes JSON.stringify({ hookSpecificOutput: { hookEventName: 'AfterTool', additionalContext } })). No plain text reaches stdout outside this path. Stderr carries only debug/stale-index messages. toolSucceeded checks toolResponse.error and toolResponse.exit_code which matches the tool_response schema documented at line 19-20 of the adapter. hookSpecificOutput.hookEventName is 'AfterTool' ✅. Matcher search_file_content|glob|run_shell_command covers the documented Gemini built-in search/shell tools. timeout: 10000 — unit is unconfirmed in this review but contextually milliseconds (Finding 5). Missing windowsHide is Finding 1.

Hook adapter runtime behavior
.gitnexus discovery (worktrees, nested cwd, global registry exclusion) is faithfully ported from Claude hook ✅. DB lock probing via acquireHookSlot + hasGitNexusDbLockedByGitNexusServer prevents MCP server contention ✅. augment -- <pattern> guards against --prefixed injection (PR #200) ✅. run_shell_command pattern extraction uses the same whitespace-split heuristic as the Claude hook — known limitation for quoted patterns (graceful no-augmentation, not a crash) ✅. Stale-index detection fires only after successful git commit/merge/rebase/cherry-pick/pull ✅. Stack traces suppressed behind GITNEXUS_DEBUG ✅. Missing windowsHide (Finding 1) is the only runtime concern.

Cross-platform/package install behavior
package.json "files" includes "hooks"hooks/antigravity/gitnexus-antigravity-hook.cjs ships in the npm tarball ✅. CLI path rewrite at install time prevents MODULE_NOT_FOUND regression (#108/#132) ✅. Windows cmd /c npx wrapper in MCP entry ✅. win-rm-list-json.ps1 copied ✅. windowsHide: true missing from all spawnSync calls — Finding 1, blocker.

Existing editor regression risk
setupAntigravity, installAntigravitySkills, installAntigravityHooks, mergeGeminiSettingsHooks, geminiHasGitnexusHook are all new functions that run only when ~/.gemini/antigravity exists. No changes to setupCursor, setupClaudeCode, setupOpenCode, setupCodex, installClaudeCodeHooks, installSkillsTo, getMcpEntry, mergeJsoncFile. No regression risk to existing editors. ✅

Tests and CI
17 tests covering all DoD items except: (a) stageAdapter missing .ps1 (Finding 7), (b) no test for Windows lock-probe path in child-process context, (c) no negative test for patterns whose first token is ≤2 chars (known limitation). All CI test jobs pass on all 3 platforms. CI Gate failure is a transient ENETUNREACH in the scope-parity infrastructure step, unrelated to this PR.

Docs/user-facing claims
Root README.md:121 correctly says "AfterTool" — ✅. gitnexus/README.md:37 says "PreToolUse + PostToolUse" — ❌ Finding 2 (blocker). index.ts:22 description says "Antigravity" — ✅. "Full" support claim in both READMEs: hooks and skills are implemented, but the gitnexus/README.md claim is backed by wrong documentation, so it's misleading until Fixed 2 is applied.

Branch hygiene
10+ merge-from-main commits. Final diff is clean (6 expected files only, no unrelated churn). Recommend squash before merge for cleaner history, but not a hard blocker per CONTRIBUTING.md.


Back-and-forth avoided by verifying

  • "Is win-rm-list-json.ps1 copied?" → Yes (setup.ts:659). Was missing in original commit, fixed in c1872b4. ✅
  • "Did the platform-pin fix Windows CI?" → Yes, all three platform test jobs pass on head 3f110b4. ✅
  • "Is the scope-parity CI failure related to Antigravity?" → No. Log shows ENETUNREACH during npm install — transient infrastructure. ✅
  • "Does the adapter use augment -- <pattern>?" → Yes (adapter:259). ✅
  • "Are existing editors regressed?" → No. All new functions are gated on ~/.gemini/antigravity. ✅
  • "Is hooks/antigravity in the npm package?" → Yes (package.json "files": ["dist","hooks",...]). ✅
  • "Is windowsHide in the Antigravity hook?" → No — not a single occurrence. Claude hook has it at 4 sites. ❌
  • "Does gitnexus/README.md match the final schema?" → No — still says old schema. ❌

Open questions (genuinely unavoidable)

  1. timeout: 10000 unit: The Gemini CLI hooks reference (https://geminicli.com/docs/hooks/reference/) should confirm whether timeout is seconds or milliseconds. The contextual evidence (internal 7000ms runGitNexusCli timeout, adapter comment header) strongly suggests milliseconds, but a docs citation in a code comment would remove all ambiguity.

  2. grep_search as a live Gemini/Antigravity tool: If grep_search is a documented Antigravity tool name (distinct from search_file_content), it should be added to the registered matcher. If it's not a real tool, the dead code should be removed. The Gemini CLI tools reference page should clarify this.


Final verdict

not production-ready

Two blockers prevent merge. Finding 1 (windowsHide: true missing from all spawnSync calls in the Antigravity adapter) is a direct Windows regression relative to PR #1794 already on main — every matched tool call on Windows will flash a console window. Finding 2 (gitnexus/README.md:37 still documents PreToolUse + PostToolUse and the old hooks.json schema) means the published package README tells users the wrong hook event name and links to the wrong documentation. Both are small, targeted fixes. The core implementation is sound: the schema realignment in c1872b4 is correct, CI passes on all three platforms, the win-rm-list-json.ps1 copy is present, the augment -- separator guards against injection, idempotency works, and the test coverage is substantial. Fix Findings 1 and 2, address the stale comment and dead code in Findings 3–4 as cleanup, then this is merge-ready.

@magyargergo

Copy link
Copy Markdown
Collaborator

@NilotpalK Can you please address claude's findings?

Addresses the production-readiness review findings on PR abhigyanpatwari#1730:

- F1 (blocker): add windowsHide:true to all four spawnSync sites in the
  Antigravity hook adapter (findCanonicalRepoRoot, runGitNexusCli's two
  branches, buildStaleIndexHint) so they don't flash console windows on
  Windows. Matches the fix abhigyanpatwari#1794 already on main for the Claude hook.
- F2 (blocker): update gitnexus/README.md editor table to say AfterTool
  and link the Gemini CLI hooks reference. The published README had
  drifted to the pre-c1872b4 PreToolUse + PostToolUse schema.
- F3: rewrite the stale ~/.gemini block comment in setup.ts. It still
  described the old hooks.json + gitnexus group + grep_search design.
- F4: remove grep_search dead code from extractPattern and its doc
  comment. The registered matcher is search_file_content|glob|run_shell_command,
  so grep_search would never be invoked.
- F5: annotate timeout:10000 with a ms-unit comment noting Gemini CLI
  uses milliseconds (Claude Code uses seconds).
- F6: add the GITNEXUS_DEBUG branch to extractAugmentContext for parity
  with the Claude adapter, so suppressed augment stderr is recoverable.
- F7: stageAdapter test helper now copies win-rm-list-json.ps1 alongside
  the .cjs helpers, so the adapter's Windows lock-probe path isn't a
  silent fail-open in child-process smoke tests.
@magyargergo

Copy link
Copy Markdown
Collaborator

btw, could you please add some integration tests to this setup and also update the gitnexus\scripts\cross-platform-tests.ts file please 🙏

NilotpalK and others added 6 commits May 25, 2026 15:12
…rm matrix

Adds end-to-end coverage on top of the unit-level tests, per maintainer
request:

- test/integration/setup-antigravity.test.ts (10 tests): exercises the
  real setupCommand() against a temp HOME with ~/.gemini/antigravity/
  present. Verifies mcp_config.json shape, ~/.gemini/settings.json
  AfterTool entry, adapter + helpers + win-rm-list-json.ps1 copy,
  baked-in cliPath rewrite (issue abhigyanpatwari#108 regression class), skill layout,
  polite-neighbor merge against existing user hooks, idempotency,
  skip-when-absent, corrupt-file safety, and key preservation.
- test/integration/antigravity-hook-e2e.test.ts (19 tests): runs the
  full install-then-execute flow — invokes setupCommand to lay down
  the adapter + helpers, then spawns the INSTALLED adapter as a real
  child process against a temp git repo + .gitnexus/. The source
  adapter cannot be spawned directly (it requires sibling .cjs helpers
  that only live in hooks/claude/); install-then-spawn mirrors the
  production codepath. Covers staleness detection across all five git
  mutation types, --embeddings propagation, polite skip on
  toolResponse.error / exit_code !== 0, augment crash-free behavior,
  cwd validation, corrupted/missing meta.json, unknown event names,
  empty stdin, and the no-.gitnexus deep-nested case.
- scripts/cross-platform-tests.ts: registers all three antigravity
  test files (unit in PLATFORM_LOGIC, two integration files in
  SPAWN_CLI) so Windows and macOS CI exercise them on every run.
…ercion, glob filter

- Delete mergeGeminiSettingsHooks (verbatim copy of mergeHooksJsonc),
  replace call site with the original
- Unify geminiHasGitnexusHook into hasGitnexusHook with commandFragment
  parameter; delete the duplicate
- Guard against silent adapter-copy failure: verify the adapter file
  exists before registering the AfterTool hook entry in settings.json;
  surface helper copy errors instead of swallowing
- Fix toolSucceeded type coercion: use Number() so string exit_code
  values from Gemini CLI are handled correctly
- Align glob tool extractPattern with Claude adapter's restrictive
  regex filter (/[*\/]([a-zA-Z][a-zA-Z0-9_-]{2,})/)
- Remove bounds-only toBeGreaterThan(0) assertion (DoD §2.7)
- Add antigravity adapter to HOOK_FILES windowsHide regression list
# Conflicts:
#	gitnexus/scripts/cross-platform-tests.ts
@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

✨ PR Autofix

Found fixable formatting / unused-import issues across 26 changed lines. Comment /autofix on this PR to apply them, or run npm run lint:fix && npm run format locally.

{"schema":"gitnexus.pr-autofix/v2","state":"fixes-available","pr_number":1730,"changed_lines":26,"head_sha":"230b705d81adf2ddbcd82b078ef2d3371636eda8","run_id":"26400274031","apply_command":"/autofix"}

@magyargergo

Copy link
Copy Markdown
Collaborator

/autofix

@github-actions

Copy link
Copy Markdown
Contributor

✅ Applied autofix and pushed a commit. (apply run)

@magyargergo magyargergo merged commit 50c6acb into abhigyanpatwari:main May 25, 2026
25 of 26 checks passed
@magyargergo

Copy link
Copy Markdown
Collaborator

Thanks @NilotpalK !

magyargergo added a commit to magyargergo/GitNexus that referenced this pull request Jun 10, 2026
…DEBUG

The antigravity AfterTool handler mirrored the stale-index hint to stderr
unconditionally on a normal (non-error) success path — the last ungated
stderr write of the class issue abhigyanpatwari#1913 targets, and a divergence from the
claude hook, which never mirrors this hint to stderr.

Gate the stderr mirror behind isDebugEnabled(). The hint still reaches the
agent via additionalContext (stdout JSON) — parts.push(hint) stays
unconditional — so there is no functional loss; only the by-default
terminal mirror moves behind GITNEXUS_DEBUG=1. This knowingly changes the
abhigyanpatwari#1730 terminal-mirror behavior in favor of strict-runner cleanliness and
parity with the claude adapter.

Split the e2e assertion into a default-silent test (hint in
additionalContext, absent from stderr) and a GITNEXUS_DEBUG=1 test (hint
mirrored to stderr).

Refs abhigyanpatwari#1913

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
magyargergo added a commit that referenced this pull request Jun 10, 2026
…#1913) (#2134)

* fix(hooks): silence MCP-owned-DB augment skip for strict hook runners

The PreToolUse augment-skip path wrote `[GitNexus] augment skipped: MCP
server owns DB` to stderr unconditionally on a normal (non-error) skip.
Strict hook runners that validate hook output (e.g. Codex `PreToolUse`)
treat that as noisy / "invalid pre-tool-use JSON output".

Gate the diagnostic behind GITNEXUS_DEBUG via a shared `isDebugEnabled()`
helper, so normal skips are silent by default (empty stdout AND stderr,
exit 0) and the reason stays recoverable with `GITNEXUS_DEBUG=1`. Applied
consistently to all three hand-maintained hook copies (claude,
antigravity, claude-plugin).

Tests:
- Unit (claude CJS + plugin): assert default-silent and debug-on behavior
  for the MCP-owned-DB skip and for the fail-closed (lsof ETIMEDOUT) skip
  that routes through the same gated line; the owner-detection tests run
  with GITNEXUS_DEBUG=1 so the skip discriminator stays observable.
- e2e (antigravity): the antigravity adapter shares the identical gated
  skip but only runs from its install dir, so cover it through the install
  pipeline with a faked DB-owner probe (strict empty-stdout/stderr +
  debug-on). Promote the fake-probe helpers (createHookToolDir / hookEnv,
  plus a module-private writeExecutable) into shared hook-test-helpers so
  unit + e2e reuse them.

Fixes #1913

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

* fix(hooks): unify GITNEXUS_DEBUG gating in main() catch handlers

The main() catch-handler in all three hook copies still gated its crash
log on truthy `if (process.env.GITNEXUS_DEBUG)`, while the skip diagnostic
the #1913 fix added is gated on the strict `isDebugEnabled()` helper
(=== '1' || === 'true'). That split meant GITNEXUS_DEBUG=0 or =false
suppressed the skip line yet still enabled crash logging — two conflicting
contract signals in the same file.

Switch the three catch handlers to isDebugEnabled() so GITNEXUS_DEBUG has
one strict meaning everywhere: exactly '1' or 'true' enables all
diagnostics; everything else (incl. '0', 'false', empty, unset) is silent.

Add boundary tests asserting the MCP-owner skip stays silent with
GITNEXUS_DEBUG='0' and 'false' (CJS + Plugin), pinning the strict contract.

Refs #1913

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

* fix(hooks): gate antigravity stale-index hint stderr behind GITNEXUS_DEBUG

The antigravity AfterTool handler mirrored the stale-index hint to stderr
unconditionally on a normal (non-error) success path — the last ungated
stderr write of the class issue #1913 targets, and a divergence from the
claude hook, which never mirrors this hint to stderr.

Gate the stderr mirror behind isDebugEnabled(). The hint still reaches the
agent via additionalContext (stdout JSON) — parts.push(hint) stays
unconditional — so there is no functional loss; only the by-default
terminal mirror moves behind GITNEXUS_DEBUG=1. This knowingly changes the
#1730 terminal-mirror behavior in favor of strict-runner cleanliness and
parity with the claude adapter.

Split the e2e assertion into a default-silent test (hint in
additionalContext, absent from stderr) and a GITNEXUS_DEBUG=1 test (hint
mirrored to stderr).

Refs #1913

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

* docs(hooks): document GITNEXUS_DEBUG=1 for hook diagnostics

GITNEXUS_DEBUG was documented only in the cursor integration README, so
the diagnostic escape hatch for the Claude Code / Antigravity hooks was
undiscoverable. Operators hitting a silent hook skip (MCP server owns the
DB, fail-closed probe timeout, or an already-current index) had no
documented way to surface the reason.

Add a Troubleshooting subsection explaining that the hooks stay silent on
normal skip paths for strict runners, that GITNEXUS_DEBUG=1 surfaces the
reason on stderr, and that only '1'/'true' enable diagnostics (stdout JSON
the agent consumes is unaffected).

Refs #1913

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

* test(hooks): update setup-antigravity unit test for gated stale-index hint

U2 (7995e92) gated the antigravity stale-index hint stderr mirror behind
GITNEXUS_DEBUG, but a second test — setup-antigravity.test.ts's "AfterTool
emits stale-index hint" — also asserted the hint on stderr by default and
was missed (it lives outside the two files validated locally; the full CI
matrix caught it).

Update it to the U2 contract: assert the hint via additionalContext with
stderr silent by default, plus a GITNEXUS_DEBUG=1 run asserting the
terminal mirror reappears.

Refs #1913

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

Feature Request Add support for Google Antigravity as Editor

2 participants