gitnexus 1.6.10-rc.1 → 1.6.10-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,13 +43,13 @@ To configure MCP for your editor, run `npx gitnexus setup` once — or set it up
43
43
  | **Claude Code** | Yes | Yes | Yes (PreToolUse + PostToolUse) | **Full** |
44
44
  | **Cursor** | Yes | Yes | Yes (postToolUse, [manual install](../gitnexus-cursor-integration/README.md#hook-install)) | **Full** |
45
45
  | **Antigravity** (Google) | Yes | Yes | Yes (AfterTool, [Gemini CLI hooks schema](https://geminicli.com/docs/hooks/reference/)) | **Full** |
46
- | **Codex** | Yes | Yes | — | MCP + Skills |
46
+ | **Codex** | Yes | Yes | Yes (PreToolUse + PostToolUse, [Codex hooks](https://developers.openai.com/codex/hooks)) | **Full** |
47
47
  | **OpenCode** | Yes | Yes | — | MCP + Skills |
48
48
  | **CodeBuddy** (Tencent) | Yes | Yes | — | MCP + Skills |
49
49
  | **Qoder** (Alibaba) | Yes | Yes | — | MCP + Skills |
50
50
  | **Windsurf** | Yes | — | — | MCP |
51
51
 
52
- > **Claude Code** gets the deepest integration: MCP tools + agent skills + PreToolUse hooks that automatically enrich grep/glob/bash calls with knowledge graph context + PostToolUse hooks that detect a stale index after commits and prompt the agent to reindex.
52
+ > **Claude Code** and **Codex** get the deepest integration: MCP tools + agent skills + PreToolUse hooks that automatically enrich grep/glob/bash calls with knowledge graph context + PostToolUse hooks that detect a stale index after commits and prompt the agent to reindex.
53
53
 
54
54
  ### Community Integrations
55
55
 
@@ -71,12 +71,23 @@ claude mcp add gitnexus -- npx -y gitnexus@latest mcp
71
71
  claude mcp add gitnexus -- cmd /c npx -y gitnexus@latest mcp
72
72
  ```
73
73
 
74
- ### Codex (full support — MCP + skills)
74
+ ### Codex (full support — MCP + skills + hooks)
75
75
 
76
76
  ```bash
77
77
  codex mcp add gitnexus -- npx -y gitnexus@latest mcp
78
78
  ```
79
79
 
80
+ Codex hooks (PreToolUse graph enrichment + PostToolUse stale-index detection in `~/.codex/hooks.json`, [same schema as Claude Code](https://developers.openai.com/codex/hooks)) need the bundled adapter script, so they are installed by `gitnexus setup -c codex` rather than manually.
81
+
82
+ Alternatively, install everything as a [Codex plugin](https://developers.openai.com/codex/plugins/build) (MCP + skills + hooks in one step):
83
+
84
+ ```bash
85
+ codex plugin marketplace add abhigyanpatwari/GitNexus
86
+ # then inside Codex: /plugins → install "GitNexus"
87
+ ```
88
+
89
+ > **Codex notes:** SessionStart is intentionally not registered — Codex reads [AGENTS.md natively](https://developers.openai.com/codex/guides/agents-md), which already carries the GitNexus context block. Newly installed hooks need a one-time approval in Codex via `/hooks` before they run. Pick **one** install route (`gitnexus setup -c codex` **or** the plugin): plugin hooks load alongside `~/.codex/hooks.json`, so installing both can fire duplicate hooks per tool call.
90
+
80
91
  ### Cursor / Windsurf
81
92
 
82
93
  Add to `~/.cursor/mcp.json` (global — works for all projects):
@@ -102,6 +102,17 @@ export function getEditorTargets(home = os.homedir()) {
102
102
  needle: 'gitnexus-hook',
103
103
  scriptDir: path.join(home, '.claude', 'hooks', 'gitnexus'),
104
104
  },
105
+ {
106
+ id: 'codex',
107
+ label: 'Codex',
108
+ // Codex hooks use Claude Code's exact {hooks: {Event: [...]}} JSON shape
109
+ // and hookSpecificOutput response contract, in a dedicated hooks.json
110
+ // (https://developers.openai.com/codex/hooks).
111
+ settingsFile: path.join(home, '.codex', 'hooks.json'),
112
+ events: ['PreToolUse', 'PostToolUse'],
113
+ needle: 'gitnexus-hook',
114
+ scriptDir: path.join(home, '.codex', 'hooks', 'gitnexus'),
115
+ },
105
116
  {
106
117
  id: 'antigravity',
107
118
  label: 'Antigravity',
package/dist/cli/setup.js CHANGED
@@ -407,20 +407,26 @@ export async function copyHookHelpers(srcDir, destDir, label, result) {
407
407
  return failedRequired;
408
408
  }
409
409
  /**
410
- * Install GitNexus hooks to ~/.claude/settings.json for Claude Code.
411
- * Merges hook config without overwriting existing hooks, preserving
412
- * comments and formatting in the JSONC file.
410
+ * Install GitNexus hooks for editors that use Claude Code's hooks schema.
411
+ *
412
+ * Claude Code registers hooks in ~/.claude/settings.json; Codex uses a
413
+ * dedicated ~/.codex/hooks.json with the identical {hooks: {Event: [...]}}
414
+ * JSON shape, stdin payload, and hookSpecificOutput response contract
415
+ * (https://developers.openai.com/codex/hooks), so both runtimes share this
416
+ * installer and the same bundled adapter script. Merges hook config without
417
+ * overwriting existing hooks, preserving comments and formatting.
413
418
  */
414
- async function installClaudeCodeHooks(result) {
415
- const claudeDir = path.join(os.homedir(), '.claude');
416
- if (!(await dirExists(claudeDir)))
419
+ async function installClaudeSchemaHooks(result, id) {
420
+ const hookCfg = hookTarget(id);
421
+ const settingsPath = hookCfg.settingsFile;
422
+ const label = `${hookCfg.label} hooks`;
423
+ // Gate on the editor's own config dir (~/.claude, ~/.codex) existing.
424
+ if (!(await dirExists(path.dirname(settingsPath))))
417
425
  return;
418
- const claudeHook = hookTarget('claude');
419
- const settingsPath = claudeHook.settingsFile;
420
426
  // Source hooks bundled within the gitnexus package (hooks/claude/)
421
427
  const pluginHooksPath = path.join(__dirname, '..', '..', 'hooks', 'claude');
422
- // Copy unified hook script to ~/.claude/hooks/gitnexus/
423
- const destHooksDir = claudeHook.scriptDir;
428
+ // Copy unified hook script to the editor's hooks/gitnexus/ dir
429
+ const destHooksDir = hookCfg.scriptDir;
424
430
  try {
425
431
  await fs.mkdir(destHooksDir, { recursive: true });
426
432
  const src = path.join(pluginHooksPath, 'gitnexus-hook.cjs');
@@ -431,7 +437,7 @@ async function installClaudeCodeHooks(result) {
431
437
  const normalizedCli = path.resolve(resolvedCli).replace(/\\/g, '/');
432
438
  const jsonCli = JSON.stringify(normalizedCli);
433
439
  if (!content.includes(CLI_PATH_SOURCE_LITERAL)) {
434
- result.errors.push('Claude Code hooks: gitnexus-hook.cjs no longer contains the cliPath literal to patch — the installed hook may fail to resolve the CLI. Update CLI_PATH_SOURCE_LITERAL in setup.ts.');
440
+ result.errors.push(`${label}: gitnexus-hook.cjs no longer contains the cliPath literal to patch — the installed hook may fail to resolve the CLI. Update CLI_PATH_SOURCE_LITERAL in setup.ts.`);
435
441
  }
436
442
  content = content.replace(CLI_PATH_SOURCE_LITERAL, `let cliPath = ${jsonCli};`);
437
443
  await fs.writeFile(dest, content, 'utf-8');
@@ -446,12 +452,12 @@ async function installClaudeCodeHooks(result) {
446
452
  await fs.access(dest);
447
453
  }
448
454
  catch {
449
- result.errors.push('Claude Code hooks: adapter script was not installed — skipping hook registration');
455
+ result.errors.push(`${label}: adapter script was not installed — skipping hook registration`);
450
456
  return;
451
457
  }
452
- const failedRequired = await copyHookHelpers(pluginHooksPath, destHooksDir, 'Claude Code hooks', result);
458
+ const failedRequired = await copyHookHelpers(pluginHooksPath, destHooksDir, label, result);
453
459
  if (failedRequired.length > 0) {
454
- result.errors.push(`Claude Code hooks: required helper(s) ${failedRequired.join(', ')} failed to copy — skipping hook registration`);
460
+ result.errors.push(`${label}: required helper(s) ${failedRequired.join(', ')} failed to copy — skipping hook registration`);
455
461
  return;
456
462
  }
457
463
  const hookPath = path.join(destHooksDir, 'gitnexus-hook.cjs').replace(/\\/g, '/');
@@ -467,9 +473,10 @@ async function installClaudeCodeHooks(result) {
467
473
  }
468
474
  })();
469
475
  const hookEntries = [];
470
- // NOTE: SessionStart hooks are broken on Windows (Claude Code bug #23576).
471
- // Session context is delivered via CLAUDE.md / skills instead.
472
- if (!hasGitnexusHook(parsed?.hooks, 'PreToolUse', claudeHook.needle)) {
476
+ // NOTE: SessionStart hooks are broken on Windows (Claude Code bug #23576),
477
+ // and Codex reads AGENTS.md natively. Session context is delivered via
478
+ // CLAUDE.md / AGENTS.md / skills instead.
479
+ if (!hasGitnexusHook(parsed?.hooks, 'PreToolUse', hookCfg.needle)) {
473
480
  hookEntries.push({
474
481
  eventName: 'PreToolUse',
475
482
  value: {
@@ -485,7 +492,7 @@ async function installClaudeCodeHooks(result) {
485
492
  },
486
493
  });
487
494
  }
488
- if (!hasGitnexusHook(parsed?.hooks, 'PostToolUse', claudeHook.needle)) {
495
+ if (!hasGitnexusHook(parsed?.hooks, 'PostToolUse', hookCfg.needle)) {
489
496
  hookEntries.push({
490
497
  eventName: 'PostToolUse',
491
498
  value: {
@@ -502,19 +509,19 @@ async function installClaudeCodeHooks(result) {
502
509
  });
503
510
  }
504
511
  if (hookEntries.length === 0) {
505
- result.configured.push('Claude Code hooks (already configured)');
512
+ result.configured.push(`${label} (already configured)`);
506
513
  return;
507
514
  }
508
515
  const ok = await mergeHooksJsonc(settingsPath, hookEntries);
509
516
  if (ok) {
510
- result.configured.push('Claude Code hooks (PreToolUse, PostToolUse)');
517
+ result.configured.push(`${label} (PreToolUse, PostToolUse)`);
511
518
  }
512
519
  else {
513
- result.errors.push('Claude Code hooks: settings.json is corrupt — skipping to preserve existing content');
520
+ result.errors.push(`${label}: ${path.basename(settingsPath)} is corrupt — skipping to preserve existing content`);
514
521
  }
515
522
  }
516
523
  catch (err) {
517
- result.errors.push(`Claude Code hooks: ${err.message}`);
524
+ result.errors.push(`${label}: ${err.message}`);
518
525
  }
519
526
  }
520
527
  // ─── Antigravity (Google) ──────────────────────────────────────────
@@ -1053,7 +1060,7 @@ export const setupCommand = async (options) => {
1053
1060
  // Install global skills for platforms that support them
1054
1061
  if (selected.has('claude')) {
1055
1062
  await installClaudeCodeSkills(result);
1056
- await installClaudeCodeHooks(result);
1063
+ await installClaudeSchemaHooks(result, 'claude');
1057
1064
  }
1058
1065
  if (selected.has('antigravity')) {
1059
1066
  await installAntigravitySkills(result);
@@ -1067,8 +1074,10 @@ export const setupCommand = async (options) => {
1067
1074
  await installCodeBuddySkills(result);
1068
1075
  if (selected.has('qoder'))
1069
1076
  await installQoderSkills(result);
1070
- if (selected.has('codex'))
1077
+ if (selected.has('codex')) {
1071
1078
  await installCodexSkills(result);
1079
+ await installClaudeSchemaHooks(result, 'codex');
1080
+ }
1072
1081
  // Print results
1073
1082
  if (result.configured.length > 0) {
1074
1083
  console.log(' Configured:');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.10-rc.1",
3
+ "version": "1.6.10-rc.2",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",