Commit graph

5 commits

Author SHA1 Message Date
abhigyantrumio
c0baba86ce fix(hooks): make augment concurrency cap a hard cap via atomic slot files
Address Claude's review of #1510. The original count-then-claim guard had
a TOCTOU window: N hooks could each read `active < MAX_INFLIGHT` between
readdirSync and the per-pid `wx` write and all proceed, briefly exceeding
the cap. The PR title's "cap" language overstated this.

Replace with fixed-name `slot-0.lock` ... `slot-N.lock` under `.hook-locks/`.
`O_CREAT|O_EXCL` on a fixed path is OS-atomic — exactly one process wins
each slot, so the cap is hard regardless of burst arrival timing. Each
slot file contains the owning PID so stale-takeover still works when a
hook crashes without releasing.

PID liveness is checked before age (Claude's Finding 3): a slow-but-alive
hook is never wrongly evicted. The 30s age window only kicks in to defend
against PID reuse on a long-abandoned slot, well above the 7s augment
timeout so a healthy run never hits it.

Also adds the missing concurrency-guard tests to cursor-hook.test.ts
(Claude's Finding 2): source-level wiring + dead-PID reclaim + 3-slots-full
bail. Previously only the CJS and Plugin variants had test coverage for
the guard; the Cursor variant was validated only by code inspection.

Tests: 5726 passing, +9 from baseline (1 hard-cap burst test + 4 source
regressions in hooks.test.ts; 3 source + 2 integration in cursor-hook.test.ts).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 19:12:56 +05:30
abhigyanpatwari
ee72183326 fix(hooks): cap concurrent augment subprocesses to prevent runaway process spawn (#1486)
When Claude Code fires PreToolUse hooks for parallel Grep/Glob/Bash tool
calls, each invocation spawned its own `gitnexus augment` subprocess —
a Node + LadybugDB cold start that holds resources for several seconds.
Under heavy parallel search load (issue #1486: 180+ piled-up processes,
load avg > 100), these accumulated faster than they completed because
nothing capped concurrent in-flight augments.

Add a lockfile-based concurrency guard under `<.gitnexus>/.hook-locks/`:
each running hook claims a `<pid>.lock`, the guard counts live PIDs and
prunes stale entries (>30s mtime or pid no longer alive), and bails
silently when MAX_INFLIGHT (3) is reached. Augment is best-effort
enrichment — missing a few fires under burst load is preferable to
melting the system.

Applied to all three hook variants that spawn augment:
- gitnexus/hooks/claude/gitnexus-hook.cjs (npm-installed Claude hook)
- gitnexus-claude-plugin/hooks/gitnexus-hook.js (plugin Claude hook)
- gitnexus-cursor-integration/hooks/gitnexus-hook.cjs (Cursor hook)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 23:18:32 +05:30
Abhigyan Patwari
2620b704e0
feat(cursor): upgrade hooks to Cursor 2.4 postToolUse for Read/Grep/Shell coverage (#1467)
* feat(cursor): upgrade hooks to Cursor 2.4 postToolUse for Read/Grep/Shell coverage

Cursor 2.4 (released 2026-01-22) shipped generic preToolUse/postToolUse hooks
matching `Shell|Read|Write|Grep|Delete|Task|MCP:<tool>`, replacing the
2.3-era beforeShellExecution hook that only fired on shell commands. The
existing integration only intercepted the shell path, so Cursor users got
graph augmentation roughly 10% as often as Claude Code users — only when
the agent dropped to rg/grep instead of using its native Read/Grep tools.

This swaps the integration over to postToolUse and ports the bash+jq
hook script to cross-platform Node:

- gitnexus-cursor-integration/hooks/hooks.json: registers a single
  postToolUse hook matching Shell|Read|Grep that invokes the new
  gitnexus-hook.cjs.
- gitnexus-cursor-integration/hooks/gitnexus-hook.cjs: new Node hook
  mirroring the safety patterns from the Claude hook (absolute-cwd
  validation, .gitnexus discovery with linked-worktree fallback,
  npx.cmd on Windows, end-of-options `--` marker, debug truncation,
  graceful failure). Extracts the search pattern per tool kind:
  Grep -> toolInput.query; Read -> file basename stripped to identifier
  chars; Shell -> existing rg/grep arg parser. Emits Cursor-shape
  `{ "additional_context": "..." }` on stdout — no shell, no jq.
- gitnexus-cursor-integration/hooks/augment-shell.sh: removed (Windows
  incompatible, narrower coverage).
- gitnexus/test/unit/cursor-hook.test.ts: 33 regression tests covering
  manifest wiring, source-level invariants (no shell:true, npx.cmd,
  isAbsolute, additional_context output shape, end-of-options marker),
  extractPattern coverage per tool, and behavioral early-exit paths
  (empty/invalid stdin, relative cwd, no .gitnexus, unknown tool name,
  short patterns, non-search shell commands, case-insensitive matching).
- README.md / gitnexus/README.md: editor-support table now lists Cursor
  as Full / hooks=Yes (postToolUse), matching reality.
- gitnexus/src/cli/augment.ts and gitnexus/src/core/augmentation/engine.ts:
  doc-strings updated from `Cursor beforeShellExecution` to
  `Cursor postToolUse`.

Closes #1466.

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

* fix(cursor): hook timeout is in seconds, not milliseconds

Cursor's `timeout` field in hooks.json is in seconds (per
https://cursor.com/docs/agent/hooks and the original integration's
`"timeout": 5`). I'd written `10000` after blindly copying the issue
body's example — that resolves to ~2.8 hours, not 10 seconds. If the
script ever hangs before reaching its inner spawnSync timeouts (e.g.
during stdin read), Cursor would have waited that long before killing
it.

Drop to `10` (seconds), matching the Claude plugin's hooks.json and
giving plenty of headroom over the inner 7s augment-CLI timeout.

Add a regression-guard assertion in cursor-hook.test.ts so a future
ms/s mixup fails fast.

Reported by Cursor Bugbot on PR #1467.

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

* fix(cursor): address Claude review findings — payload aliases, debug, install docs

Resolves three findings from Claude reviewer on PR #1467:

1. Cursor payload field-name uncertainty (SIGNIFICANT)
   Claude flagged that the Grep `query` field is an unverified assumption
   per Cursor 2.4 docs (https://cursor.com/docs/agent/hooks). Mitigated:
   - Expanded Grep aliases: query | pattern | regex | q | search | searchQuery
   - Added pickLongestStringValue() last-resort fallback so the hook
     extracts *something* even if Cursor renames every documented field
   - Added GITNEXUS_DEBUG=1 stderr logging of the raw stdin payload so
     users can capture Cursor's actual contract when diagnosing silent
     no-ops, and report it back if aliases drift
   - Added Read alias `filePath` (camelCase variant alongside `file_path`)
   - Inline comment block citing the docs URL and the uncertainty

2. Hook command path resolution + install docs (SIGNIFICANT)
   Claude flagged `node ./hooks/gitnexus-hook.cjs` as relative without
   documented install path. Added gitnexus-cursor-integration/README.md
   with explicit install steps:
   - .cursor/hooks.json + hooks/gitnexus-hook.cjs at project root
   - Confirms Cursor's project-root CWD convention with doc link
   - Verify steps including GITNEXUS_DEBUG capture
   - Pattern-extraction contract table per tool
   - Troubleshooting: not-firing, npx fallback, wrong-pattern diagnosis

3. README "Full" overclaim for Cursor (MODERATE)
   Both README rows now read `Yes (postToolUse, manual install)` linking
   to the new install README, accurately signaling that hooks aren't
   automated by `gitnexus setup` like they are for Claude Code.

4. Shell quoted-pattern parser limitation (MINOR, documented)
   Added inline comment in gitnexus-hook.cjs documenting the known
   `rg "User Service"` -> `User` truncation, plus regression tests in
   cursor-hook.test.ts pinning the behavior so a future change is
   visible.

Test additions (33 -> 41):
- Wide-alias source coverage for Grep (query / pattern / regex / q /
  search / searchQuery) plus pickLongestStringValue fallback
- Read alias coverage including camelCase filePath
- GITNEXUS_DEBUG behavioral test: stderr quiet by default, payload
  echoed when env var set, stdout output contract preserved either way
- Shell quoted-pattern documented behavior tests
- Install README presence + content (.cursor/hooks.json, hooks/, debug
  diagnostics)

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-05-10 13:29:06 +01:00
abhigyanpatwari
20ebd6b781 feat: security hardening, MCP improvements, skills, hooks, and CLI updates
- Export security primitives (CYPHER_WRITE_RE, isWriteQuery, isTestFilePath,
  VALID_NODE_LABELS, VALID_RELATION_TYPES) from local-backend
- Improve MCP kuzu-adapter with better query handling
- Add PR review skill for Claude, Cursor, and npm package
- Add CLI guide and CLI skills
- Update hooks for Claude plugin and Cursor integration
- Remove deprecated claude-hooks.ts CLI module
- Update eval-server, setup, and analyze CLI commands
- Improve CSV generator and ingestion processors
- Update CLAUDE.md and AGENTS.md configs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 20:13:42 +05:30
abhigyanpatwari
eca55aacd7 fixed resource count multiplying issue ( using resource templates now ) 2026-02-13 21:28:36 +05:30