@veewo/gitnexus 1.3.10 → 1.3.11

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.
Files changed (109) hide show
  1. package/README.md +3 -3
  2. package/dist/benchmark/analyze-memory-sampler.d.ts +10 -0
  3. package/dist/benchmark/analyze-memory-sampler.js +12 -0
  4. package/dist/benchmark/analyze-memory-sampler.test.d.ts +1 -0
  5. package/dist/benchmark/analyze-memory-sampler.test.js +12 -0
  6. package/dist/benchmark/io.test.js +48 -5
  7. package/dist/benchmark/u2-e2e/config.d.ts +1 -0
  8. package/dist/benchmark/u2-e2e/retrieval-runner.js +25 -3
  9. package/dist/benchmark/u2-e2e/retrieval-runner.test.js +44 -1
  10. package/dist/benchmark/unity-lazy-context-sampler.d.ts +58 -0
  11. package/dist/benchmark/unity-lazy-context-sampler.js +217 -0
  12. package/dist/benchmark/unity-lazy-context-sampler.test.d.ts +1 -0
  13. package/dist/benchmark/unity-lazy-context-sampler.test.js +32 -0
  14. package/dist/cli/analyze-close-policy.d.ts +5 -0
  15. package/dist/cli/analyze-close-policy.js +9 -0
  16. package/dist/cli/analyze-close-policy.test.d.ts +1 -0
  17. package/dist/cli/analyze-close-policy.test.js +12 -0
  18. package/dist/cli/analyze-runtime-summary.d.ts +2 -0
  19. package/dist/cli/analyze-runtime-summary.js +9 -0
  20. package/dist/cli/analyze-runtime-summary.test.d.ts +1 -0
  21. package/dist/cli/analyze-runtime-summary.test.js +14 -0
  22. package/dist/cli/analyze.js +42 -15
  23. package/dist/cli/eval-server.js +3 -0
  24. package/dist/cli/exit-code.d.ts +13 -0
  25. package/dist/cli/exit-code.js +25 -0
  26. package/dist/cli/exit-code.test.d.ts +1 -0
  27. package/dist/cli/exit-code.test.js +28 -0
  28. package/dist/cli/index.js +8 -2
  29. package/dist/cli/mcp.js +3 -0
  30. package/dist/cli/setup.js +3 -2
  31. package/dist/cli/setup.test.js +67 -0
  32. package/dist/cli/tool.d.ts +3 -1
  33. package/dist/cli/tool.js +2 -0
  34. package/dist/core/graph/types.d.ts +1 -1
  35. package/dist/core/ingestion/filesystem-walker.d.ts +6 -0
  36. package/dist/core/ingestion/filesystem-walker.js +17 -0
  37. package/dist/core/ingestion/filesystem-walker.test.d.ts +1 -0
  38. package/dist/core/ingestion/filesystem-walker.test.js +51 -0
  39. package/dist/core/ingestion/pipeline.js +4 -3
  40. package/dist/core/ingestion/unity-parity-seed.d.ts +9 -0
  41. package/dist/core/ingestion/unity-parity-seed.js +69 -0
  42. package/dist/core/ingestion/unity-parity-seed.test.d.ts +1 -0
  43. package/dist/core/ingestion/unity-parity-seed.test.js +35 -0
  44. package/dist/core/ingestion/unity-resource-processor.d.ts +2 -0
  45. package/dist/core/ingestion/unity-resource-processor.js +87 -53
  46. package/dist/core/ingestion/unity-resource-processor.test.js +37 -39
  47. package/dist/core/kuzu/csv-generator.d.ts +20 -1
  48. package/dist/core/kuzu/csv-generator.js +92 -25
  49. package/dist/core/kuzu/csv-generator.test.d.ts +1 -0
  50. package/dist/core/kuzu/csv-generator.test.js +28 -0
  51. package/dist/core/kuzu/kuzu-adapter.js +35 -54
  52. package/dist/core/kuzu/relationship-pair-buckets.d.ts +17 -0
  53. package/dist/core/kuzu/relationship-pair-buckets.js +79 -0
  54. package/dist/core/kuzu/relationship-pair-buckets.test.d.ts +1 -0
  55. package/dist/core/kuzu/relationship-pair-buckets.test.js +10 -0
  56. package/dist/core/kuzu/schema.d.ts +1 -1
  57. package/dist/core/kuzu/schema.js +1 -0
  58. package/dist/core/unity/options.d.ts +2 -0
  59. package/dist/core/unity/options.js +9 -0
  60. package/dist/core/unity/options.test.js +8 -1
  61. package/dist/core/unity/resolver.d.ts +3 -0
  62. package/dist/core/unity/resolver.js +56 -2
  63. package/dist/core/unity/resolver.test.js +46 -0
  64. package/dist/core/unity/scan-context.d.ts +5 -0
  65. package/dist/core/unity/scan-context.js +133 -44
  66. package/dist/core/unity/scan-context.test.js +41 -2
  67. package/dist/core/unity/serialized-type-index.d.ts +5 -0
  68. package/dist/core/unity/serialized-type-index.js +44 -13
  69. package/dist/core/unity/serialized-type-index.test.js +9 -1
  70. package/dist/mcp/local/local-backend.d.ts +16 -0
  71. package/dist/mcp/local/local-backend.js +320 -4
  72. package/dist/mcp/local/local-backend.unity-merge.test.d.ts +1 -0
  73. package/dist/mcp/local/local-backend.unity-merge.test.js +261 -0
  74. package/dist/mcp/local/unity-enrichment.d.ts +15 -0
  75. package/dist/mcp/local/unity-enrichment.js +69 -5
  76. package/dist/mcp/local/unity-enrichment.test.js +69 -1
  77. package/dist/mcp/local/unity-lazy-config.d.ts +6 -0
  78. package/dist/mcp/local/unity-lazy-config.js +7 -0
  79. package/dist/mcp/local/unity-lazy-config.test.d.ts +1 -0
  80. package/dist/mcp/local/unity-lazy-config.test.js +9 -0
  81. package/dist/mcp/local/unity-lazy-hydrator.d.ts +15 -0
  82. package/dist/mcp/local/unity-lazy-hydrator.js +43 -0
  83. package/dist/mcp/local/unity-lazy-hydrator.test.d.ts +1 -0
  84. package/dist/mcp/local/unity-lazy-hydrator.test.js +66 -0
  85. package/dist/mcp/local/unity-lazy-overlay.d.ts +3 -0
  86. package/dist/mcp/local/unity-lazy-overlay.js +89 -0
  87. package/dist/mcp/local/unity-lazy-overlay.test.d.ts +1 -0
  88. package/dist/mcp/local/unity-lazy-overlay.test.js +83 -0
  89. package/dist/mcp/local/unity-parity-cache.d.ts +7 -0
  90. package/dist/mcp/local/unity-parity-cache.js +88 -0
  91. package/dist/mcp/local/unity-parity-cache.test.d.ts +1 -0
  92. package/dist/mcp/local/unity-parity-cache.test.js +143 -0
  93. package/dist/mcp/local/unity-parity-seed-loader.d.ts +2 -0
  94. package/dist/mcp/local/unity-parity-seed-loader.js +30 -0
  95. package/dist/mcp/local/unity-parity-seed-loader.test.d.ts +1 -0
  96. package/dist/mcp/local/unity-parity-seed-loader.test.js +25 -0
  97. package/dist/mcp/local/unity-parity-warmup-queue.d.ts +6 -0
  98. package/dist/mcp/local/unity-parity-warmup-queue.js +28 -0
  99. package/dist/mcp/local/unity-parity-warmup-queue.test.d.ts +1 -0
  100. package/dist/mcp/local/unity-parity-warmup-queue.test.js +15 -0
  101. package/dist/mcp/tools.js +24 -2
  102. package/dist/types/pipeline.d.ts +7 -0
  103. package/package.json +4 -1
  104. package/skills/gitnexus-cli.md +18 -0
  105. package/skills/gitnexus-debugging.md +16 -2
  106. package/skills/gitnexus-exploring.md +15 -1
  107. package/skills/gitnexus-guide.md +15 -0
  108. package/skills/gitnexus-impact-analysis.md +2 -0
  109. package/skills/gitnexus-refactoring.md +5 -1
@@ -0,0 +1,143 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import path from 'node:path';
4
+ import os from 'node:os';
5
+ import fs from 'node:fs/promises';
6
+ import { createHash } from 'node:crypto';
7
+ import { readUnityParityCache, upsertUnityParityCache } from './unity-parity-cache.js';
8
+ test('unity parity cache reads and writes by symbol key', async () => {
9
+ const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-unity-parity-'));
10
+ try {
11
+ const before = await readUnityParityCache(storagePath, 'abc123', 'Class:Foo');
12
+ assert.equal(before, null);
13
+ await upsertUnityParityCache(storagePath, 'abc123', 'Class:Foo', {
14
+ resourceBindings: [{
15
+ resourcePath: 'Assets/A.prefab',
16
+ resourceType: 'prefab',
17
+ bindingKind: 'direct',
18
+ componentObjectId: '100',
19
+ serializedFields: { scalarFields: [], referenceFields: [] },
20
+ resolvedReferences: [],
21
+ evidence: { line: 1, lineText: 'm_Script: ...' },
22
+ }],
23
+ serializedFields: { scalarFields: [], referenceFields: [] },
24
+ unityDiagnostics: [],
25
+ });
26
+ const after = await readUnityParityCache(storagePath, 'abc123', 'Class:Foo');
27
+ assert.equal(after?.resourceBindings.length, 1);
28
+ assert.equal(after?.resourceBindings[0]?.componentObjectId, '100');
29
+ }
30
+ finally {
31
+ await fs.rm(storagePath, { recursive: true, force: true });
32
+ }
33
+ });
34
+ test('unity parity cache invalidates entries on indexed commit change', async () => {
35
+ const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-unity-parity-'));
36
+ try {
37
+ await upsertUnityParityCache(storagePath, 'old-commit', 'Class:Foo', {
38
+ resourceBindings: [{
39
+ resourcePath: 'Assets/A.prefab',
40
+ resourceType: 'prefab',
41
+ bindingKind: 'direct',
42
+ componentObjectId: '100',
43
+ serializedFields: { scalarFields: [], referenceFields: [] },
44
+ resolvedReferences: [],
45
+ evidence: { line: 1, lineText: 'm_Script: ...' },
46
+ }],
47
+ serializedFields: { scalarFields: [], referenceFields: [] },
48
+ unityDiagnostics: [],
49
+ });
50
+ const stale = await readUnityParityCache(storagePath, 'new-commit', 'Class:Foo');
51
+ assert.equal(stale, null);
52
+ }
53
+ finally {
54
+ await fs.rm(storagePath, { recursive: true, force: true });
55
+ }
56
+ });
57
+ test('unity parity cache persists entries in shard files and supports atomic replace', async () => {
58
+ const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-unity-parity-'));
59
+ try {
60
+ await upsertUnityParityCache(storagePath, 'abc123', 'Class:Foo', {
61
+ resourceBindings: [{
62
+ resourcePath: 'Assets/A.prefab',
63
+ resourceType: 'prefab',
64
+ bindingKind: 'direct',
65
+ componentObjectId: '101',
66
+ serializedFields: { scalarFields: [], referenceFields: [] },
67
+ resolvedReferences: [],
68
+ evidence: { line: 1, lineText: 'm_Script: ...' },
69
+ }],
70
+ serializedFields: { scalarFields: [], referenceFields: [] },
71
+ unityDiagnostics: [],
72
+ });
73
+ await upsertUnityParityCache(storagePath, 'abc123', 'Class:Bar', {
74
+ resourceBindings: [{
75
+ resourcePath: 'Assets/B.prefab',
76
+ resourceType: 'prefab',
77
+ bindingKind: 'direct',
78
+ componentObjectId: '102',
79
+ serializedFields: { scalarFields: [], referenceFields: [] },
80
+ resolvedReferences: [],
81
+ evidence: { line: 1, lineText: 'm_Script: ...' },
82
+ }],
83
+ serializedFields: { scalarFields: [], referenceFields: [] },
84
+ unityDiagnostics: [],
85
+ });
86
+ const shardsDir = path.join(storagePath, 'unity-parity-cache');
87
+ const shards = await fs.readdir(shardsDir);
88
+ assert.ok(shards.length > 0);
89
+ assert.ok(shards.every((name) => name.endsWith('.json')));
90
+ }
91
+ finally {
92
+ await fs.rm(storagePath, { recursive: true, force: true });
93
+ }
94
+ });
95
+ test('unity parity cache evicts oldest entries when max entries exceeded', async () => {
96
+ const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-unity-parity-'));
97
+ try {
98
+ const shard = (key) => createHash('sha1').update(key).digest('hex').slice(0, 2);
99
+ const firstKey = 'Class:A';
100
+ let secondKey = '';
101
+ for (let i = 0; i < 4096; i += 1) {
102
+ const candidate = `Class:B:${i}`;
103
+ if (shard(candidate) === shard(firstKey)) {
104
+ secondKey = candidate;
105
+ break;
106
+ }
107
+ }
108
+ assert.notEqual(secondKey, '');
109
+ await upsertUnityParityCache(storagePath, 'abc123', firstKey, {
110
+ resourceBindings: [{
111
+ resourcePath: 'Assets/A.prefab',
112
+ resourceType: 'prefab',
113
+ bindingKind: 'direct',
114
+ componentObjectId: '201',
115
+ serializedFields: { scalarFields: [], referenceFields: [] },
116
+ resolvedReferences: [],
117
+ evidence: { line: 1, lineText: 'm_Script: ...' },
118
+ }],
119
+ serializedFields: { scalarFields: [], referenceFields: [] },
120
+ unityDiagnostics: [],
121
+ }, { maxEntries: 1 });
122
+ await upsertUnityParityCache(storagePath, 'abc123', secondKey, {
123
+ resourceBindings: [{
124
+ resourcePath: 'Assets/B.prefab',
125
+ resourceType: 'prefab',
126
+ bindingKind: 'direct',
127
+ componentObjectId: '202',
128
+ serializedFields: { scalarFields: [], referenceFields: [] },
129
+ resolvedReferences: [],
130
+ evidence: { line: 1, lineText: 'm_Script: ...' },
131
+ }],
132
+ serializedFields: { scalarFields: [], referenceFields: [] },
133
+ unityDiagnostics: [],
134
+ }, { maxEntries: 1 });
135
+ const evicted = await readUnityParityCache(storagePath, 'abc123', firstKey);
136
+ const retained = await readUnityParityCache(storagePath, 'abc123', secondKey);
137
+ assert.equal(evicted, null);
138
+ assert.ok(retained);
139
+ }
140
+ finally {
141
+ await fs.rm(storagePath, { recursive: true, force: true });
142
+ }
143
+ });
@@ -0,0 +1,2 @@
1
+ import type { UnityParitySeed } from '../../core/ingestion/unity-parity-seed.js';
2
+ export declare function loadUnityParitySeed(storagePath: string): Promise<UnityParitySeed | null>;
@@ -0,0 +1,30 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ const SEED_FILENAME = 'unity-parity-seed.json';
4
+ export async function loadUnityParitySeed(storagePath) {
5
+ const seedPath = path.join(storagePath, SEED_FILENAME);
6
+ let raw = '';
7
+ try {
8
+ raw = await fs.readFile(seedPath, 'utf-8');
9
+ }
10
+ catch (error) {
11
+ if (error.code === 'ENOENT') {
12
+ return null;
13
+ }
14
+ throw error;
15
+ }
16
+ try {
17
+ const parsed = JSON.parse(raw);
18
+ if (!parsed
19
+ || parsed.version !== 1
20
+ || typeof parsed.symbolToScriptPath !== 'object'
21
+ || typeof parsed.scriptPathToGuid !== 'object'
22
+ || typeof parsed.guidToResourcePaths !== 'object') {
23
+ return null;
24
+ }
25
+ return parsed;
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import fs from 'node:fs/promises';
6
+ import { loadUnityParitySeed } from './unity-parity-seed-loader.js';
7
+ test('loadUnityParitySeed returns null on missing file and parsed object on valid file', async () => {
8
+ const storagePath = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-seed-loader-'));
9
+ try {
10
+ const missing = await loadUnityParitySeed(storagePath);
11
+ assert.equal(missing, null);
12
+ await fs.writeFile(path.join(storagePath, 'unity-parity-seed.json'), JSON.stringify({
13
+ version: 1,
14
+ symbolToScriptPath: { DoorObj: 'Assets/Code/DoorObj.cs' },
15
+ scriptPathToGuid: { 'Assets/Code/DoorObj.cs': 'abc123abc123abc123abc123abc123ab' },
16
+ guidToResourcePaths: { abc123abc123abc123abc123abc123ab: ['Assets/Prefabs/Door.prefab'] },
17
+ }), 'utf-8');
18
+ const loaded = await loadUnityParitySeed(storagePath);
19
+ assert.equal(loaded?.version, 1);
20
+ assert.equal(loaded?.symbolToScriptPath.DoorObj, 'Assets/Code/DoorObj.cs');
21
+ }
22
+ finally {
23
+ await fs.rm(storagePath, { recursive: true, force: true });
24
+ }
25
+ });
@@ -0,0 +1,6 @@
1
+ export interface ParityWarmupQueue {
2
+ run<T>(task: () => Promise<T>): Promise<T>;
3
+ }
4
+ export declare function createParityWarmupQueue(input: {
5
+ maxParallel: number;
6
+ }): ParityWarmupQueue;
@@ -0,0 +1,28 @@
1
+ export function createParityWarmupQueue(input) {
2
+ const maxParallel = Math.max(1, Math.floor(input.maxParallel || 1));
3
+ let running = 0;
4
+ const pending = [];
5
+ const drain = () => {
6
+ while (running < maxParallel && pending.length > 0) {
7
+ const job = pending.shift();
8
+ if (!job)
9
+ return;
10
+ running += 1;
11
+ job();
12
+ }
13
+ };
14
+ const run = (task) => (new Promise((resolve, reject) => {
15
+ const exec = () => {
16
+ Promise.resolve()
17
+ .then(task)
18
+ .then(resolve, reject)
19
+ .finally(() => {
20
+ running = Math.max(0, running - 1);
21
+ drain();
22
+ });
23
+ };
24
+ pending.push(exec);
25
+ drain();
26
+ }));
27
+ return { run };
28
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { createParityWarmupQueue } from './unity-parity-warmup-queue.js';
4
+ test('runWarmupTask respects max parallel limit', async () => {
5
+ let running = 0;
6
+ let maxSeen = 0;
7
+ const queue = createParityWarmupQueue({ maxParallel: 2 });
8
+ await Promise.all(Array.from({ length: 6 }).map(() => queue.run(async () => {
9
+ running += 1;
10
+ maxSeen = Math.max(maxSeen, running);
11
+ await new Promise((resolve) => setTimeout(resolve, 20));
12
+ running -= 1;
13
+ })));
14
+ assert.equal(maxSeen <= 2, true);
15
+ });
package/dist/mcp/tools.js CHANGED
@@ -35,7 +35,12 @@ Returns results grouped by process (execution flow):
35
35
  - process_symbols: all symbols in those flows with file locations and module (functional area)
36
36
  - definitions: standalone types/interfaces not in any process
37
37
 
38
- Hybrid ranking: BM25 keyword + semantic vector search, ranked by Reciprocal Rank Fusion.`,
38
+ Hybrid ranking: BM25 keyword + semantic vector search, ranked by Reciprocal Rank Fusion.
39
+
40
+ Includes optional Unity retrieval contract:
41
+ - Set unity_resources=on|auto to include Unity resource evidence.
42
+ - Default unity_hydration_mode=compact (fast path).
43
+ - Check response hydrationMeta: when needsParityRetry=true, rerun with unity_hydration_mode=parity for completeness.`,
39
44
  inputSchema: {
40
45
  type: 'object',
41
46
  properties: {
@@ -51,6 +56,12 @@ Hybrid ranking: BM25 keyword + semantic vector search, ranked by Reciprocal Rank
51
56
  description: 'Unity resource retrieval mode (default: off)',
52
57
  default: 'off',
53
58
  },
59
+ unity_hydration_mode: {
60
+ type: 'string',
61
+ enum: ['parity', 'compact'],
62
+ description: 'Unity hydration mode when unity_resources is enabled (default: compact)',
63
+ default: 'compact',
64
+ },
54
65
  repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
55
66
  },
56
67
  required: ['query'],
@@ -104,7 +115,12 @@ Shows categorized incoming/outgoing references (calls, imports, extends, impleme
104
115
  WHEN TO USE: After query() to understand a specific symbol in depth. When you need to know all callers, callees, and what execution flows a symbol participates in.
105
116
  AFTER THIS: Use impact() if planning changes, or READ gitnexus://repo/{name}/process/{processName} for full execution trace.
106
117
 
107
- Handles disambiguation: if multiple symbols share the same name, returns candidates for you to pick from. Use uid param for zero-ambiguity lookup from prior results.`,
118
+ Handles disambiguation: if multiple symbols share the same name, returns candidates for you to pick from. Use uid param for zero-ambiguity lookup from prior results.
119
+
120
+ Unity retrieval contract:
121
+ - Set unity_resources=on|auto to include Unity resource evidence.
122
+ - Default unity_hydration_mode=compact (fast path).
123
+ - Check response hydrationMeta: when needsParityRetry=true, rerun with unity_hydration_mode=parity for completeness.`,
108
124
  inputSchema: {
109
125
  type: 'object',
110
126
  properties: {
@@ -118,6 +134,12 @@ Handles disambiguation: if multiple symbols share the same name, returns candida
118
134
  description: 'Unity resource retrieval mode (default: off)',
119
135
  default: 'off',
120
136
  },
137
+ unity_hydration_mode: {
138
+ type: 'string',
139
+ enum: ['parity', 'compact'],
140
+ description: 'Unity hydration mode when unity_resources is enabled (default: compact)',
141
+ default: 'compact',
142
+ },
121
143
  repo: { type: 'string', description: 'Repository name or path. Omit if only one repo is indexed.' },
122
144
  },
123
145
  required: [],
@@ -30,6 +30,13 @@ export interface PipelineResult {
30
30
  unityResult?: UnityResourceProcessingResult;
31
31
  scopeDiagnostics?: ScopeSelectionDiagnostics;
32
32
  }
33
+ export interface PipelineRuntimeSummary {
34
+ totalFileCount: number;
35
+ communityResult?: CommunityDetectionResult;
36
+ processResult?: ProcessDetectionResult;
37
+ unityResult?: UnityResourceProcessingResult;
38
+ scopeDiagnostics?: ScopeSelectionDiagnostics;
39
+ }
33
40
  export interface SerializablePipelineResult {
34
41
  nodes: GraphNode[];
35
42
  relationships: GraphRelationship[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veewo/gitnexus",
3
- "version": "1.3.10",
3
+ "version": "1.3.11",
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",
@@ -54,6 +54,9 @@
54
54
  "benchmark:agent-context:quick": "npm run check:neonspark-target && npm run build && node dist/cli/index.js benchmark-agent-context ../benchmarks/agent-context/neonspark-refactor-v1 --profile quick --target-path \"$GITNEXUS_NEONSPARK_TARGET_PATH\" --repo-alias neonspark-v1-subset --scope-manifest ../benchmarks/unity-baseline/neonspark-v2/sync-manifest.txt",
55
55
  "benchmark:agent-context:full": "npm run check:neonspark-target && npm run build && node dist/cli/index.js benchmark-agent-context ../benchmarks/agent-context/neonspark-refactor-v1 --profile full --target-path \"$GITNEXUS_NEONSPARK_TARGET_PATH\" --repo-alias neonspark-v1-subset --scope-manifest ../benchmarks/unity-baseline/neonspark-v2/sync-manifest.txt",
56
56
  "benchmark:u2:sample": "npm run build && node dist/benchmark/u2-performance-sampler.js",
57
+ "benchmark:analyze-memory:sample": "npm run build && node --test dist/benchmark/analyze-memory-sampler.test.js",
58
+ "benchmark:unity:lazy-context": "npm run build && node dist/benchmark/unity-lazy-context-sampler.js",
59
+ "benchmark:unity:hydration-gates": "npm run build && node dist/benchmark/unity-lazy-context-sampler.js",
57
60
  "benchmark:u2:e2e": "npm run check:u2-e2e-target && npm run build && node dist/cli/index.js benchmark-u2-e2e --config ../benchmarks/u2-e2e/neonspark-full-u2-e2e.config.json"
58
61
  },
59
62
  "dependencies": {
@@ -70,6 +70,24 @@ npx gitnexus list
70
70
 
71
71
  Lists all repositories registered in `~/.gitnexus/registry.json`. The MCP `list_repos` tool provides the same information.
72
72
 
73
+ ### query/context — Unity hydration mode
74
+
75
+ For Unity resource retrieval:
76
+
77
+ ```bash
78
+ npx gitnexus context DoorObj --repo neonnew-core --file Assets/NEON/Code/Game/Doors/DoorObj.cs --unity-resources on --unity-hydration compact
79
+ ```
80
+
81
+ ```bash
82
+ npx gitnexus query "DoorObj binding" --repo neonnew-core --unity-resources on --unity-hydration compact
83
+ ```
84
+
85
+ Rules:
86
+
87
+ - `--unity-hydration compact` is the default (fast path).
88
+ - If response `hydrationMeta.needsParityRetry=true`, rerun with `--unity-hydration parity`.
89
+ - `--unity-hydration parity` is completeness-first mode for advanced verification.
90
+
73
91
  ## After Indexing
74
92
 
75
93
  1. **Read `gitnexus://repo/{name}/context`** to verify the index loaded
@@ -18,8 +18,9 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
18
18
  ```
19
19
  1. gitnexus_query({query: "<error or symptom>"}) → Find related execution flows
20
20
  2. gitnexus_context({name: "<suspect>"}) → See callers/callees/processes
21
- 3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
22
- 4. gitnexus_cypher({query: "MATCH path..."}) Custom traces if needed
21
+ 3. (Unity symbols) use unity_resources + hydration contract
22
+ 4. READ gitnexus://repo/{name}/process/{name} Trace execution flow
23
+ 5. gitnexus_cypher({query: "MATCH path..."}) → Custom traces if needed
23
24
  ```
24
25
 
25
26
  > If "Index is stale" → run `npx gitnexus analyze` in terminal.
@@ -31,6 +32,8 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
31
32
  - [ ] gitnexus_query for error text or related code
32
33
  - [ ] Identify the suspect function from returned processes
33
34
  - [ ] gitnexus_context to see callers and callees
35
+ - [ ] For Unity retrieval, start with `unity_hydration_mode: "compact"` and inspect `hydrationMeta`
36
+ - [ ] If `hydrationMeta.needsParityRetry === true`, rerun with `unity_hydration_mode: "parity"` before concluding root cause
34
37
  - [ ] Trace execution flow via process resource if applicable
35
38
  - [ ] gitnexus_cypher for custom call chain traces if needed
36
39
  - [ ] Read source files to confirm root cause
@@ -65,6 +68,17 @@ gitnexus_context({name: "validatePayment"})
65
68
  → Processes: CheckoutFlow (step 3/7)
66
69
  ```
67
70
 
71
+ **Unity debug retrieval** — explicit completeness control:
72
+
73
+ ```
74
+ gitnexus_context({
75
+ name: "DoorObj",
76
+ unity_resources: "on",
77
+ unity_hydration_mode: "compact"
78
+ })
79
+ → if hydrationMeta.needsParityRetry then rerun with unity_hydration_mode: "parity"
80
+ ```
81
+
68
82
  **gitnexus_cypher** — custom call chain traces:
69
83
 
70
84
  ```cypher
@@ -20,7 +20,8 @@ description: "Use when the user asks how code works, wants to understand archite
20
20
  2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness
21
21
  3. gitnexus_query({query: "<what you want to understand>"}) → Find related execution flows
22
22
  4. gitnexus_context({name: "<symbol>"}) → Deep dive on specific symbol
23
- 5. READ gitnexus://repo/{name}/process/{name} → Trace full execution flow
23
+ 5. (Unity symbols) rerun context/query with unity params when needed
24
+ 6. READ gitnexus://repo/{name}/process/{name} → Trace full execution flow
24
25
  ```
25
26
 
26
27
  > If step 2 says "Index is stale" → run `npx gitnexus analyze` in terminal.
@@ -32,6 +33,8 @@ description: "Use when the user asks how code works, wants to understand archite
32
33
  - [ ] gitnexus_query for the concept you want to understand
33
34
  - [ ] Review returned processes (execution flows)
34
35
  - [ ] gitnexus_context on key symbols for callers/callees
36
+ - [ ] For Unity evidence, call context/query with `unity_resources: "on"` and `unity_hydration_mode: "compact"`
37
+ - [ ] If `hydrationMeta.needsParityRetry === true`, rerun with `unity_hydration_mode: "parity"`
35
38
  - [ ] READ process resource for full execution traces
36
39
  - [ ] Read source files for implementation details
37
40
  ```
@@ -64,6 +67,17 @@ gitnexus_context({name: "validateUser"})
64
67
  → Processes: LoginFlow (step 2/5), TokenRefresh (step 1/3)
65
68
  ```
66
69
 
70
+ **Unity-focused context/query** — use compact first, parity only when needed:
71
+
72
+ ```
73
+ gitnexus_context({
74
+ name: "DoorObj",
75
+ unity_resources: "on",
76
+ unity_hydration_mode: "compact"
77
+ })
78
+ → hydrationMeta.needsParityRetry ? rerun with unity_hydration_mode: "parity" : continue
79
+ ```
80
+
67
81
  ## Example: "How does payment processing work?"
68
82
 
69
83
  ```
@@ -40,6 +40,21 @@ For any task involving code understanding, debugging, impact analysis, or refact
40
40
  | `cypher` | Raw graph queries (read `gitnexus://repo/{name}/schema` first) |
41
41
  | `list_repos` | Discover indexed repos |
42
42
 
43
+ ### Unity Retrieval Contract (query/context)
44
+
45
+ When you need Unity resource evidence, pass:
46
+
47
+ - `unity_resources: "on"` (or `"auto"` when you want adaptive behavior)
48
+ - `unity_hydration_mode: "compact" | "parity"` (default: `"compact"`)
49
+
50
+ Recommended default workflow:
51
+
52
+ 1. Call `context/query` with `unity_hydration_mode: "compact"` for speed.
53
+ 2. Inspect `hydrationMeta` in the response:
54
+ - `needsParityRetry: true` → rerun same call with `unity_hydration_mode: "parity"`
55
+ - `isComplete: true` → keep compact result
56
+ 3. Treat parity as the completeness path for advanced verification.
57
+
43
58
  ## Resources Reference
44
59
 
45
60
  Lightweight reads (~100-500 tokens) for navigation:
@@ -31,6 +31,8 @@ description: "Use when the user wants to know what will break if they change som
31
31
  - [ ] gitnexus_impact({target, direction: "upstream"}) to find dependents
32
32
  - [ ] Review d=1 items first (these WILL BREAK)
33
33
  - [ ] Check high-confidence (>0.8) dependencies
34
+ - [ ] For Unity symbols, verify `context(..., unity_resources: "on")` hydration completeness
35
+ - [ ] If compact response has `hydrationMeta.needsParityRetry === true`, rerun in parity before final risk call
34
36
  - [ ] READ processes to check affected execution flows
35
37
  - [ ] gitnexus_detect_changes() for pre-commit check
36
38
  - [ ] Assess risk level and report to user
@@ -19,7 +19,8 @@ description: "Use when the user wants to rename, extract, split, move, or restru
19
19
  1. gitnexus_impact({target: "X", direction: "upstream"}) → Map all dependents
20
20
  2. gitnexus_query({query: "X"}) → Find execution flows involving X
21
21
  3. gitnexus_context({name: "X"}) → See all incoming/outgoing refs
22
- 4. Plan update order: interfaces implementations → callers → tests
22
+ 4. (Unity symbols) validate compact/parity retrieval completeness
23
+ 5. Plan update order: interfaces → implementations → callers → tests
23
24
  ```
24
25
 
25
26
  > If "Index is stale" → run `npx gitnexus analyze` in terminal.
@@ -40,6 +41,8 @@ description: "Use when the user wants to rename, extract, split, move, or restru
40
41
 
41
42
  ```
42
43
  - [ ] gitnexus_context({name: target}) — see all incoming/outgoing refs
44
+ - [ ] For Unity targets: `unity_resources: "on"`, `unity_hydration_mode: "compact"` first
45
+ - [ ] If `hydrationMeta.needsParityRetry === true`, rerun with `unity_hydration_mode: "parity"` before extraction
43
46
  - [ ] gitnexus_impact({target, direction: "upstream"}) — find all external callers
44
47
  - [ ] Define new module interface
45
48
  - [ ] Extract code, update imports
@@ -51,6 +54,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
51
54
 
52
55
  ```
53
56
  - [ ] gitnexus_context({name: target}) — understand all callees
57
+ - [ ] For Unity targets: ensure final verification run uses parity when compact requests retry
54
58
  - [ ] Group callees by responsibility
55
59
  - [ ] gitnexus_impact({target, direction: "upstream"}) — map callers to update
56
60
  - [ ] Create new functions/services