@veewo/gitnexus 1.5.6 → 1.5.7

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 (41) hide show
  1. package/dist/benchmark/analyze-runner.d.ts +0 -2
  2. package/dist/benchmark/analyze-runner.js +0 -6
  3. package/dist/benchmark/analyze-runner.test.js +1 -10
  4. package/dist/benchmark/runner.d.ts +0 -2
  5. package/dist/benchmark/runner.js +0 -2
  6. package/dist/benchmark/u2-e2e/neonspark-full-e2e.js +0 -11
  7. package/dist/benchmark/u2-performance-sampler.js +3 -16
  8. package/dist/cli/analyze-options.d.ts +19 -6
  9. package/dist/cli/analyze-options.js +76 -71
  10. package/dist/cli/analyze-options.test.js +78 -73
  11. package/dist/cli/analyze.d.ts +2 -4
  12. package/dist/cli/analyze.js +13 -25
  13. package/dist/cli/analyze.test.js +9 -15
  14. package/dist/cli/benchmark-agent-context.d.ts +0 -2
  15. package/dist/cli/benchmark-agent-context.js +0 -2
  16. package/dist/cli/benchmark-agent-safe-query-context.d.ts +0 -2
  17. package/dist/cli/benchmark-agent-safe-query-context.js +0 -2
  18. package/dist/cli/benchmark-unity.d.ts +0 -2
  19. package/dist/cli/benchmark-unity.js +0 -2
  20. package/dist/cli/clean.d.ts +2 -3
  21. package/dist/cli/clean.js +4 -25
  22. package/dist/cli/index.js +1 -10
  23. package/dist/core/ingestion/pipeline.js +1 -1
  24. package/dist/storage/repo-manager.d.ts +1 -0
  25. package/package.json +1 -1
  26. package/skills/gitnexus-cli.md +62 -38
  27. package/vendor/node_modules/node-addon-api/node_addon_api.Makefile +6 -0
  28. package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +122 -0
  29. package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +126 -0
  30. package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +122 -0
  31. package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +122 -0
  32. package/vendor/tree-sitter-dart/build/Release/.deps/node_modules/node-addon-api/node_addon_api_except.stamp.d +1 -0
  33. package/vendor/tree-sitter-dart/build/node_modules/node-addon-api/node_addon_api_except.stamp +0 -0
  34. package/vendor/tree-sitter-proto/build/Release/.deps/node_modules/node-addon-api/node_addon_api_except.stamp.d +1 -0
  35. package/vendor/tree-sitter-proto/build/node_modules/node-addon-api/node_addon_api_except.stamp +0 -0
  36. package/dist/cli/scope-manifest-config.d.ts +0 -9
  37. package/dist/cli/scope-manifest-config.js +0 -37
  38. package/dist/cli/sync-manifest.d.ts +0 -27
  39. package/dist/cli/sync-manifest.js +0 -200
  40. package/dist/cli/sync-manifest.test.d.ts +0 -1
  41. package/dist/cli/sync-manifest.test.js +0 -88
@@ -18,11 +18,10 @@ import { getCurrentCommit, isGitRepo, getGitRoot } from '../storage/git.js';
18
18
  import { generateAIContextFiles } from './ai-context.js';
19
19
  import { generateSkillFiles } from './skill-gen.js';
20
20
  import fs from 'fs/promises';
21
- import { resolveEffectiveAnalyzeOptions } from './analyze-options.js';
21
+ import { resolveEffectiveAnalyzeOptions, validateStoredOptions } from './analyze-options.js';
22
22
  import { formatCSharpPreprocDiagnosticsSummary, formatFallbackSummary, formatUnityDiagnosticsSummary, formatUnityRuleBindingSummary, resolveFallbackStats, } from './analyze-summary.js';
23
23
  import { resolveChildProcessExit } from './exit-code.js';
24
24
  import { toPipelineRuntimeSummary } from './analyze-runtime-summary.js';
25
- import { enforceSyncManifestConsistency, resolveScopeManifestForAnalyze } from './sync-manifest.js';
26
25
  const HEAP_MB = 8192;
27
26
  const HEAP_FLAG = `--max-old-space-size=${HEAP_MB}`;
28
27
  /** Re-exec the process with an 8GB heap if we're currently below that. */
@@ -111,31 +110,22 @@ export const analyzeCommand = async (inputPath, options) => {
111
110
  let scopeRules = [];
112
111
  let repoAlias;
113
112
  let embeddingsEnabled = false;
113
+ let csharpDefineCsproj;
114
114
  try {
115
- const scopeManifest = await resolveScopeManifestForAnalyze(repoPath, {
116
- scopeManifest: options?.scopeManifest,
117
- scopePrefix: options?.scopePrefix,
118
- });
119
- await enforceSyncManifestConsistency({
120
- manifestPath: scopeManifest,
121
- extensions: options?.extensions,
122
- repoAlias: options?.repoAlias,
123
- embeddings: options?.embeddings,
124
- policy: options?.syncManifestPolicy,
125
- stdinIsTTY: Boolean(process.stdin.isTTY),
126
- });
115
+ const validatedStored = await validateStoredOptions(options?.reuseOptions !== false ? existingMeta?.analyzeOptions : undefined, repoPath);
127
116
  const effectiveOptions = await resolveEffectiveAnalyzeOptions({
128
117
  extensions: options?.extensions,
129
- scopeManifest,
130
- scopePrefix: options?.scopePrefix,
118
+ scope: options?.scope,
131
119
  repoAlias: options?.repoAlias,
132
120
  embeddings: options?.embeddings,
133
121
  reuseOptions: options?.reuseOptions,
134
- }, existingMeta?.analyzeOptions);
122
+ csharpDefineCsproj: options?.csharpDefineCsproj,
123
+ }, validatedStored);
135
124
  includeExtensions = effectiveOptions.includeExtensions;
136
125
  scopeRules = effectiveOptions.scopeRules;
137
126
  repoAlias = effectiveOptions.repoAlias;
138
127
  embeddingsEnabled = effectiveOptions.embeddings;
128
+ csharpDefineCsproj = effectiveOptions.csharpDefineCsproj;
139
129
  }
140
130
  catch (error) {
141
131
  console.log(` ${error?.message || String(error)}\n`);
@@ -146,13 +136,10 @@ export const analyzeCommand = async (inputPath, options) => {
146
136
  console.log(' Existing metadata found, but LadybugDB index file is missing — rebuilding index...\n');
147
137
  }
148
138
  if (existingMeta && hasLbugIndex && !options?.force && existingMeta.lastCommit === currentCommit && !options?.skills) {
149
- const hasScopePrefixInput = Array.isArray(options?.scopePrefix)
150
- ? options.scopePrefix.length > 0
151
- : Boolean(options?.scopePrefix);
152
139
  const hasCliOverrides = options?.extensions !== undefined ||
153
- Boolean(options?.scopeManifest) ||
154
- hasScopePrefixInput ||
140
+ options?.scope !== undefined ||
155
141
  options?.repoAlias !== undefined ||
142
+ options?.csharpDefineCsproj !== undefined ||
156
143
  options?.embeddings !== undefined ||
157
144
  options?.reuseOptions === false;
158
145
  if (!hasCliOverrides) {
@@ -253,7 +240,7 @@ export const analyzeCommand = async (inputPath, options) => {
253
240
  // ── Phase 1: Full Pipeline (0–60%) ─────────────────────────────────
254
241
  let pipelineResult;
255
242
  try {
256
- const pipelineRunOptions = buildPipelineRunOptionsForAnalyze({ includeExtensions, scopeRules }, options);
243
+ const pipelineRunOptions = buildPipelineRunOptionsForAnalyze({ includeExtensions, scopeRules, csharpDefineCsproj });
257
244
  pipelineResult = await runPipelineFromRepo(repoPath, (progress) => {
258
245
  const phaseLabel = PHASE_LABELS[progress.phase] || progress.phase;
259
246
  const scaled = Math.round(progress.percent * 0.6);
@@ -363,6 +350,7 @@ export const analyzeCommand = async (inputPath, options) => {
363
350
  scopeRules,
364
351
  repoAlias,
365
352
  embeddings: embeddingsEnabled,
353
+ ...(csharpDefineCsproj ? { csharpDefineCsproj } : {}),
366
354
  },
367
355
  stats: {
368
356
  files: pipelineRuntime.totalFileCount,
@@ -484,8 +472,8 @@ export function buildPipelineRunOptionsForAnalyze(resolvedOptions, options) {
484
472
  return {
485
473
  includeExtensions: resolvedOptions.includeExtensions,
486
474
  scopeRules: resolvedOptions.scopeRules,
487
- ...(options?.csharpDefineCsproj
488
- ? { csharpDefineCsproj: options.csharpDefineCsproj }
475
+ ...(resolvedOptions.csharpDefineCsproj
476
+ ? { csharpDefineCsproj: resolvedOptions.csharpDefineCsproj }
489
477
  : {}),
490
478
  };
491
479
  }
@@ -1,25 +1,19 @@
1
1
  import test from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
- import path from 'node:path';
4
3
  import { buildPipelineRunOptionsForAnalyze } from './analyze.js';
5
- import { resolveScopeManifestForAnalyze } from './sync-manifest.js';
6
- test('analyze auto-loads .gitnexus/sync-manifest.txt when CLI scope options are omitted', async () => {
7
- const repoPath = path.join('/tmp', 'demo-repo');
8
- const expectedManifest = path.join(repoPath, '.gitnexus', 'sync-manifest.txt');
9
- const resolved = await resolveScopeManifestForAnalyze(repoPath, {}, async (candidate) => candidate === expectedManifest);
10
- assert.equal(resolved, expectedManifest);
11
- });
12
- test('explicit --scope-manifest still wins over auto-detected default file', async () => {
13
- const repoPath = path.join('/tmp', 'demo-repo');
14
- const explicitManifest = path.join(repoPath, 'custom-manifest.txt');
15
- const resolved = await resolveScopeManifestForAnalyze(repoPath, { scopeManifest: explicitManifest }, async () => true);
16
- assert.equal(resolved, explicitManifest);
17
- });
18
4
  test('buildPipelineRunOptionsForAnalyze passes csharp define csproj option through to pipeline', () => {
19
- const out = buildPipelineRunOptionsForAnalyze({ includeExtensions: ['.cs'], scopeRules: ['Assets/**'] }, { csharpDefineCsproj: '/tmp/Assembly-CSharp.csproj' });
5
+ const out = buildPipelineRunOptionsForAnalyze({ includeExtensions: ['.cs'], scopeRules: ['Assets/**'], csharpDefineCsproj: '/tmp/Assembly-CSharp.csproj' });
20
6
  assert.deepEqual(out, {
21
7
  includeExtensions: ['.cs'],
22
8
  scopeRules: ['Assets/**'],
23
9
  csharpDefineCsproj: '/tmp/Assembly-CSharp.csproj',
24
10
  });
25
11
  });
12
+ test('buildPipelineRunOptionsForAnalyze omits csharpDefineCsproj when not provided', () => {
13
+ const out = buildPipelineRunOptionsForAnalyze({ includeExtensions: ['.cs'], scopeRules: ['Assets/**'] });
14
+ assert.deepEqual(out, {
15
+ includeExtensions: ['.cs'],
16
+ scopeRules: ['Assets/**'],
17
+ });
18
+ assert.equal(Object.keys(out).includes('csharpDefineCsproj'), false);
19
+ });
@@ -17,8 +17,6 @@ export declare function benchmarkAgentContextCommand(dataset: string, options: {
17
17
  targetPath?: string;
18
18
  reportDir?: string;
19
19
  extensions?: string;
20
- scopeManifest?: string;
21
- scopePrefix?: string[];
22
20
  skipAnalyze?: boolean;
23
21
  }, deps?: {
24
22
  loadDataset?: (root: string) => Promise<AgentContextDataset>;
@@ -29,8 +29,6 @@ export async function benchmarkAgentContextCommand(dataset, options, deps) {
29
29
  const analyzeOptions = {
30
30
  extensions: options.extensions,
31
31
  repoAlias: options.repoAlias,
32
- scopeManifest: options.scopeManifest,
33
- scopePrefix: options.scopePrefix,
34
32
  };
35
33
  try {
36
34
  await analyze(analyzePath, analyzeOptions);
@@ -8,8 +8,6 @@ export declare function benchmarkAgentSafeQueryContextCommand(dataset: string, o
8
8
  reportDir?: string;
9
9
  subagentRunsDir?: string;
10
10
  extensions?: string;
11
- scopeManifest?: string;
12
- scopePrefix?: string[];
13
11
  skipAnalyze?: boolean;
14
12
  }, deps?: {
15
13
  loadSuite?: (root: string) => Promise<AgentSafeBenchmarkSuite>;
@@ -16,8 +16,6 @@ export async function benchmarkAgentSafeQueryContextCommand(dataset, options, de
16
16
  await analyze(path.resolve(options.targetPath), {
17
17
  extensions: options.extensions,
18
18
  repoAlias: options.repoAlias,
19
- scopeManifest: options.scopeManifest,
20
- scopePrefix: options.scopePrefix,
21
19
  });
22
20
  }
23
21
  const suite = await loadSuite(path.resolve(dataset));
@@ -9,7 +9,5 @@ export declare function benchmarkUnityCommand(dataset: string, options: {
9
9
  targetPath?: string;
10
10
  reportDir?: string;
11
11
  extensions?: string;
12
- scopeManifest?: string;
13
- scopePrefix?: string[];
14
12
  skipAnalyze?: boolean;
15
13
  }): Promise<void>;
@@ -19,8 +19,6 @@ export async function benchmarkUnityCommand(dataset, options) {
19
19
  profile: profileConfig,
20
20
  reportDir: options.reportDir,
21
21
  extensions: options.extensions,
22
- scopeManifest: options.scopeManifest,
23
- scopePrefix: options.scopePrefix,
24
22
  skipAnalyze: options.skipAnalyze ?? false,
25
23
  });
26
24
  process.stderr.write(`${result.pass ? 'PASS' : 'FAIL'}\n`);
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * Clean Command
3
3
  *
4
- * Removes the GitNexus index from the current repository while preserving
5
- * configuration files (e.g. sync-manifest.txt). Also unregisters the repo
6
- * from the global registry.
4
+ * Removes the GitNexus index from the current repository.
5
+ * Also unregisters the repo from the global registry.
7
6
  */
8
7
  export declare const cleanCommand: (options?: {
9
8
  force?: boolean;
package/dist/cli/clean.js CHANGED
@@ -1,32 +1,11 @@
1
1
  /**
2
2
  * Clean Command
3
3
  *
4
- * Removes the GitNexus index from the current repository while preserving
5
- * configuration files (e.g. sync-manifest.txt). Also unregisters the repo
6
- * from the global registry.
4
+ * Removes the GitNexus index from the current repository.
5
+ * Also unregisters the repo from the global registry.
7
6
  */
8
7
  import fs from 'fs/promises';
9
- import path from 'path';
10
8
  import { findRepo, unregisterRepo, listRegisteredRepos } from '../storage/repo-manager.js';
11
- /** Files under .gitnexus/ that are configuration, not index data. */
12
- const PRESERVE_FILES = new Set(['sync-manifest.txt']);
13
- async function cleanStoragePath(storagePath) {
14
- let entries;
15
- try {
16
- entries = await fs.readdir(storagePath);
17
- }
18
- catch (err) {
19
- if (err.code === 'ENOENT')
20
- return;
21
- throw err;
22
- }
23
- for (const entry of entries) {
24
- if (PRESERVE_FILES.has(entry))
25
- continue;
26
- const fullPath = path.join(storagePath, entry);
27
- await fs.rm(fullPath, { recursive: true, force: true });
28
- }
29
- }
30
9
  export const cleanCommand = async (options) => {
31
10
  // --all flag: clean all indexed repos
32
11
  if (options?.all) {
@@ -46,7 +25,7 @@ export const cleanCommand = async (options) => {
46
25
  const entries = await listRegisteredRepos();
47
26
  for (const entry of entries) {
48
27
  try {
49
- await cleanStoragePath(entry.storagePath);
28
+ await fs.rm(entry.storagePath, { recursive: true, force: true });
50
29
  await unregisterRepo(entry.path);
51
30
  console.log(`Cleaned: ${entry.name} (${entry.storagePath})`);
52
31
  }
@@ -71,7 +50,7 @@ export const cleanCommand = async (options) => {
71
50
  return;
72
51
  }
73
52
  try {
74
- await cleanStoragePath(repo.storagePath);
53
+ await fs.rm(repo.storagePath, { recursive: true, force: true });
75
54
  await unregisterRepo(repo.repoPath);
76
55
  console.log(`Cleaned: ${repo.storagePath}`);
77
56
  }
package/dist/cli/index.js CHANGED
@@ -8,7 +8,6 @@ import { attachRuleLabCommands } from './rule-lab.js';
8
8
  const _require = createRequire(import.meta.url);
9
9
  const pkg = _require('../../package.json');
10
10
  const program = new Command();
11
- const collectValues = (value, previous) => [...previous, value];
12
11
  program
13
12
  .name('gitnexus')
14
13
  .description('GitNexus local CLI and MCP server')
@@ -29,12 +28,10 @@ program
29
28
  .option('--embeddings', 'Enable embedding generation for semantic search (off by default)')
30
29
  .option('--extensions <list>', 'Comma-separated file extensions to include (e.g. .cs,.ts)')
31
30
  .option('--repo-alias <name>', 'Override indexed repository name with a stable alias')
31
+ .option('--scope <rules>', 'Comma-separated scope path-prefix rules (e.g. Assets/,Packages/com.veewo.*)')
32
32
  .option('--csharp-define-csproj <path>', 'Load C# DefineConstants from the specified .csproj and normalize conditional-compilation blocks before parsing')
33
- .option('--sync-manifest-policy <policy>', 'When CLI options differ from sync manifest directives: ask|update|keep|error (default: ask)')
34
33
  .option('--skills', 'Generate repo-specific skill files from detected communities')
35
34
  .option('-v, --verbose', 'Enable verbose ingestion warnings (default: false)')
36
- .option('--scope-manifest <path>', 'Manifest file with scope rules (supports comments and * wildcard; recommended: .gitnexus/sync-manifest.txt)')
37
- .option('--scope-prefix <pathPrefix>', 'Add a scope path prefix rule (repeatable)', collectValues, [])
38
35
  .addHelpText('after', '\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)')
39
36
  .action(createLazyAction(() => import('./analyze.js'), 'analyzeCommand'));
40
37
  program
@@ -155,8 +152,6 @@ program
155
152
  .option('--target-path <path>', 'Path to analyze before evaluation (required unless --skip-analyze)')
156
153
  .option('--report-dir <path>', 'Output directory for benchmark-report.json and benchmark-summary.md', '.gitnexus/benchmark')
157
154
  .option('--extensions <list>', 'Analyze extension filter (comma-separated, optional)')
158
- .option('--scope-manifest <path>', 'Analyze scope manifest file')
159
- .option('--scope-prefix <pathPrefix>', 'Analyze scope path prefix (repeatable)', collectValues, [])
160
155
  .option('--skip-analyze', 'Skip analyze stage and evaluate current index only')
161
156
  .action(createLazyAction(() => import('./benchmark-unity.js'), 'benchmarkUnityCommand'));
162
157
  program
@@ -168,8 +163,6 @@ program
168
163
  .option('--target-path <path>', 'Path to analyze before evaluation (required unless --skip-analyze)')
169
164
  .option('--report-dir <path>', 'Output directory for benchmark-report.json and benchmark-summary.md', '.gitnexus/benchmark-agent-context')
170
165
  .option('--extensions <list>', 'Analyze extension filter (comma-separated, optional)')
171
- .option('--scope-manifest <path>', 'Analyze scope manifest file')
172
- .option('--scope-prefix <pathPrefix>', 'Analyze scope path prefix (repeatable)', collectValues, [])
173
166
  .option('--skip-analyze', 'Skip analyze stage and evaluate current index only')
174
167
  .action(createLazyAction(() => import('./benchmark-agent-context.js'), 'benchmarkAgentContextCommand'));
175
168
  program
@@ -181,8 +174,6 @@ program
181
174
  .option('--subagent-runs-dir <path>', 'Directory containing session-generated subagent run artifacts')
182
175
  .option('--report-dir <path>', 'Output directory for benchmark-report.json and benchmark-summary.md', '.gitnexus/benchmark-agent-safe-query-context')
183
176
  .option('--extensions <list>', 'Analyze extension filter (comma-separated, optional)')
184
- .option('--scope-manifest <path>', 'Analyze scope manifest file')
185
- .option('--scope-prefix <pathPrefix>', 'Analyze scope path prefix (repeatable)', collectValues, [])
186
177
  .option('--skip-analyze', 'Skip analyze stage and evaluate current index only')
187
178
  .action(createLazyAction(() => import('./benchmark-agent-safe-query-context.js'), 'benchmarkAgentSafeQueryContextCommand'));
188
179
  program
@@ -79,7 +79,7 @@ export const runPipelineFromRepo = async (repoPath, onProgress, options) => {
79
79
  const scopeSelection = selectEntriesByScopeRules(scannedFiles, options?.scopeRules || []);
80
80
  const scopedFiles = scopeSelection.selected;
81
81
  if (scopeSelection.diagnostics.appliedRuleCount > 0 && scopedFiles.length === 0) {
82
- throw new Error('Scope filters matched zero files. Check --scope-manifest/--scope-prefix.');
82
+ throw new Error('Scope filters matched zero files. Check your scope rules and extensions.');
83
83
  }
84
84
  const includeExtensions = new Set((options?.includeExtensions || [])
85
85
  .map(ext => ext.trim().toLowerCase())
@@ -15,6 +15,7 @@ export interface RepoMeta {
15
15
  scopeRules?: string[];
16
16
  repoAlias?: string;
17
17
  embeddings?: boolean;
18
+ csharpDefineCsproj?: string;
18
19
  };
19
20
  stats?: {
20
21
  files?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veewo/gitnexus",
3
- "version": "1.5.6",
3
+ "version": "1.5.7",
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",
@@ -60,73 +60,97 @@ $GN analyze
60
60
 
61
61
  Run from the project root. This parses all source files, builds the knowledge graph, writes it to `.gitnexus/`, and generates CLAUDE.md / AGENTS.md context files.
62
62
 
63
+ Analyze options are resolved with two-layer priority: **CLI arguments** > **stored options** in `meta.json.analyzeOptions`. On first run, pass CLI flags; they are persisted automatically for subsequent runs.
64
+
63
65
  | Flag | Effect |
64
66
  |------|--------|
65
67
  | `--force` | Force full re-index even if up to date |
68
+ | `--no-reuse-options` | Do not reuse stored analyze options from previous index |
66
69
  | `--embeddings` | Enable embedding generation (off by default) |
70
+ | `--extensions <list>` | Comma-separated file extensions (e.g. `.cs,.ts`) |
71
+ | `--scope <rules>` | Comma-separated scope path-prefix rules (e.g. `Assets/,Packages/com.veewo.*`) |
72
+ | `--repo-alias <name>` | Override indexed repository name with a stable alias |
73
+ | `--csharp-define-csproj <path>` | Load C# `DefineConstants` from `.csproj` for `#if` normalization |
67
74
  | `--skills` | Generate repo-specific skill files from detected communities |
75
+ | `-v, --verbose` | Enable verbose ingestion warnings |
68
76
 
69
- **Two mutually exclusive paths. Choose one per rebuild.**
77
+ **Option persistence:** `--extensions`, `--scope`, `--repo-alias`, `--embeddings`, and `--csharp-define-csproj` are automatically saved to `meta.json.analyzeOptions` after a successful run. On subsequent runs, these stored values are reused unless you pass new CLI flags or use `--no-reuse-options`.
70
78
 
71
- #### Path A: sync-manifest managed (recommended for Unity / monorepo)
79
+ #### Scope rules
72
80
 
73
- If `.gitnexus/sync-manifest.txt` exists, `analyze` **auto-uses** it when you do **not** pass `--scope-prefix` or `--scope-manifest`.
81
+ Scope rules control which files are included in the index. When no scope rules are stored, **all files** in the repo are indexed. Use `--scope` on first run to set scope rules; they are persisted automatically.
82
+
83
+ **Scope rule semantics:**
84
+ - Each rule is a **path prefix** — `Assets/` matches all files under `Assets/`
85
+ - Trailing `*` is a **wildcard prefix** — `Packages/com.veewo.*` matches `Packages/com.veewo.stat/...`
86
+ - No glob support: `Assets/**/*.cs` will not work
87
+ - Empty scope = full repo scan (all files)
74
88
 
75
89
  ```bash
76
- # Unity project with an existing manifest — this is the normal rebuild command
90
+ # Scope to specific directories
91
+ $GN analyze --force --scope "Assets/,Packages/"
92
+
93
+ # Wildcard scope
94
+ $GN analyze --force --scope "Assets/NEON/Code,Packages/com.veewo.*"
95
+
96
+ # No --scope = full repo (or reuse stored scope rules)
77
97
  $GN analyze --force
78
98
  ```
79
99
 
80
- The manifest controls scope rules, extensions, and repo alias. Example:
100
+ #### Unity project recommended parameters
81
101
 
82
- ```
83
- Assets/
84
- Packages/
85
- @extensions=.cs,.meta
86
- @repoAlias=neonspark-core
102
+ Unity projects benefit from a specific combination of parameters to ensure correct C# parsing and optimal scope:
103
+
104
+ ```bash
105
+ # Unity project — first-time index (recommended)
106
+ $GN analyze --force \
107
+ --extensions ".cs,.meta" \
108
+ --scope "Assets/,Packages/" \
109
+ --repo-alias <repo-alias> \
110
+ --csharp-define-csproj <path-to-Assembly-CSharp.csproj>
111
+
112
+ # Subsequent rebuilds (all options are reused automatically)
113
+ $GN analyze --force
87
114
  ```
88
115
 
89
- - Non-`@` lines = path-prefix scope rules
90
- - `@extensions=<csv>` = file extension filter
91
- - `@repoAlias=<name>` = stable repo alias
92
- - `@embeddings=<true|false>` = embedding toggle
116
+ | Parameter | Recommended value | Why |
117
+ |-----------|------------------|-----|
118
+ | `--extensions` | `.cs,.meta` | C# scripts + Unity `.meta` asset files for resource binding |
119
+ | `--scope` | `Assets/,Packages/` | Limit to Unity project directories; skip `Library/`, `Temp/`, `obj/` |
120
+ | `--csharp-define-csproj` | `path/to/Assembly-CSharp.csproj` | Normalize `#if` / `#elif` conditional compilation using project's `DefineConstants` |
121
+ | `--repo-alias` | e.g. `neonspark-core` | Stable alias for MCP repo lookup regardless of directory name |
93
122
 
94
- **Drift guard:** If you pass `--extensions` / `--repo-alias` / `--embeddings` while a manifest exists, CLI compares them. Use `--sync-manifest-policy` to control: `ask|update|keep|error` (default `ask`; non-TTY requires explicit policy).
123
+ **C# preprocessing detail:** Unity projects commonly use conditional compilation (`#if UNITY_EDITOR`, `#if NEON_DEBUG`, etc.). Without `--csharp-define-csproj`, tree-sitter parses each `#if` branch as-is, often producing incorrect AST for the active branch. The csproj path is persisted and reused automatically after first specification.
95
124
 
96
- **Do not mix Path A and Path B.** Passing `--scope-prefix` or `--extensions` when a manifest exists triggers the drift guard and may error out in non-TTY environments.
125
+ **Scope for large Unity repos:** For repos where only specific packages matter, narrow scope instead of indexing all of `Assets/`:
97
126
 
98
- #### Path B: manual CLI flags (first-time or simple projects)
127
+ ```bash
128
+ $GN analyze --force \
129
+ --scope "Assets/NEON/Code,Packages/com.veewo.*" \
130
+ --extensions ".cs,.meta" \
131
+ --repo-alias neonspark-core
132
+ ```
99
133
 
100
- Use when no sync-manifest exists:
134
+ #### Other project examples
101
135
 
102
136
  ```bash
103
- # Unity project, first-time index
104
- $GN analyze --force --extensions ".cs,.meta" --scope-prefix Assets/ --repo-alias neonspark-core
137
+ # Generic TypeScript project
138
+ $GN analyze --force --extensions ".ts,.tsx" --repo-alias my-project
105
139
 
106
- # Generic project
107
- $GN analyze --force --extensions ".ts,.tsx" --scope-prefix src/
140
+ # Subsequent rebuilds (stored options are reused automatically)
141
+ $GN analyze --force
108
142
  ```
109
143
 
110
- | Manual flag | Effect |
111
- |-------------|--------|
112
- | `--extensions <ext>` | Comma-separated file extensions |
113
- | `--scope-prefix <prefix>` | Add a path prefix rule (repeatable) |
114
- | `--scope-manifest <file>` | Read scope rules from a manifest file |
115
- | `--repo-alias <name>` | Override indexed repository name |
116
- | `--csharp-define-csproj <path>` | Load C# `DefineConstants` from `.csproj` for `#if` normalization |
117
-
118
- **C# preprocessing (Unity):** For projects with heavy conditional compilation, add `--csharp-define-csproj /path/to/Assembly-CSharp.csproj` (neonspark: `/Volumes/Shuttle/projects/neonspark/Assembly-CSharp.csproj`). Without it, C# files are parsed raw and tree-sitter may mishandle `#if` branches.
119
-
120
144
  #### Rebuild recovery — when analyze hangs or crashes
121
145
 
122
146
  If `analyze --force` hangs (no progress after 5+ minutes) or crashes leaving a corrupted index:
123
147
 
124
148
  ```bash
125
- # 1. Clean the corrupted index (preserves sync-manifest.txt)
149
+ # 1. Clean the corrupted index
126
150
  $GN clean --force
127
151
 
128
- # 2. Rebuild
129
- $GN analyze --force
152
+ # 2. Rebuild (re-specify CLI options since meta.json was deleted)
153
+ $GN analyze --force --extensions ".cs,.meta" --repo-alias neonspark-core
130
154
  ```
131
155
 
132
156
  **When to clean before rebuild:**
@@ -145,13 +169,13 @@ $GN status
145
169
 
146
170
  Shows whether the current repo has a GitNexus index, when it was last updated, and symbol/relationship counts. Use this to check if re-indexing is needed.
147
171
 
148
- ### clean — Delete the index (preserves config)
172
+ ### clean — Delete the index
149
173
 
150
174
  ```bash
151
175
  $GN clean --force
152
176
  ```
153
177
 
154
- Removes the GitNexus index (graph, CSVs, LadybugDB) from `.gitnexus/` while **preserving `sync-manifest.txt`** and other configuration files. Use this to recover from a corrupted index before re-indexing.
178
+ Removes the entire `.gitnexus/` directory (including `meta.json` and all index data). After cleaning, you must re-specify analyze options on the next `analyze` run since stored options are deleted.
155
179
 
156
180
  | Flag | Effect |
157
181
  | --------- | ------------------------------------------------- |
@@ -237,7 +261,7 @@ $GN unity-ui-trace "Assets/NEON/VeewoUI/Uxml/BarScreen/Patch/PatchItemPreview.ux
237
261
  - **"Not inside a git repository"**: Run from a directory inside a git repo
238
262
  - **Index is stale after re-analyzing**: Restart Claude Code to reload the MCP server
239
263
  - **Embeddings slow**: Omit `--embeddings` (it's off by default) or set `OPENAI_API_KEY` for faster API-based embedding
240
- - **`analyze --force` hangs or crashes**: Run `$GN clean --force` to remove the corrupted index (sync-manifest is preserved), then `$GN analyze --force` to rebuild. Common corruption signatures: `.gitnexus/csv/` exists but `relations.csv` is missing; `.gitnexus/lbug.wal` exists while `lbug` is only a few KB.
264
+ - **`analyze --force` hangs or crashes**: Run `$GN clean --force` to remove the corrupted index, then `$GN analyze --force` (with your CLI options) to rebuild. Common corruption signatures: `.gitnexus/csv/` exists but `relations.csv` is missing; `.gitnexus/lbug.wal` exists while `lbug` is only a few KB.
241
265
 
242
266
  ## Runtime-Chain Closure Guard
243
267
 
@@ -0,0 +1,6 @@
1
+ # This file is generated by gyp; do not edit.
2
+
3
+ export builddir_name ?= ./build/../../node_modules/node-addon-api/.
4
+ .PHONY: all
5
+ all:
6
+ $(MAKE) -C ../../tree-sitter-dart/build node_addon_api_except
@@ -0,0 +1,122 @@
1
+ # This file is generated by gyp; do not edit.
2
+
3
+ TOOLSET := target
4
+ TARGET := node_addon_api
5
+ DEFS_Debug := \
6
+ '-DNODE_GYP_MODULE_NAME=node_addon_api' \
7
+ '-DUSING_UV_SHARED=1' \
8
+ '-DUSING_V8_SHARED=1' \
9
+ '-DV8_DEPRECATION_WARNINGS=1' \
10
+ '-D_GLIBCXX_USE_CXX11_ABI=1' \
11
+ '-D_FILE_OFFSET_BITS=64' \
12
+ '-D_DARWIN_USE_64_BIT_INODE=1' \
13
+ '-D_LARGEFILE_SOURCE' \
14
+ '-DOPENSSL_NO_PINSHARED' \
15
+ '-DOPENSSL_THREADS' \
16
+ '-DDEBUG' \
17
+ '-D_DEBUG'
18
+
19
+ # Flags passed to all source files.
20
+ CFLAGS_Debug := \
21
+ -O0 \
22
+ -gdwarf-2 \
23
+ -fno-strict-aliasing \
24
+ -mmacosx-version-min=13.5 \
25
+ -arch \
26
+ arm64 \
27
+ -Wall \
28
+ -Wendif-labels \
29
+ -W \
30
+ -Wno-unused-parameter
31
+
32
+ # Flags passed to only C files.
33
+ CFLAGS_C_Debug :=
34
+
35
+ # Flags passed to only C++ files.
36
+ CFLAGS_CC_Debug := \
37
+ -std=gnu++20 \
38
+ -stdlib=libc++ \
39
+ -fno-rtti \
40
+ -fno-exceptions
41
+
42
+ # Flags passed to only ObjC files.
43
+ CFLAGS_OBJC_Debug :=
44
+
45
+ # Flags passed to only ObjC++ files.
46
+ CFLAGS_OBJCC_Debug :=
47
+
48
+ INCS_Debug := \
49
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/include/node \
50
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/src \
51
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/openssl/config \
52
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/openssl/openssl/include \
53
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/uv/include \
54
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/zlib \
55
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/v8/include
56
+
57
+ DEFS_Release := \
58
+ '-DNODE_GYP_MODULE_NAME=node_addon_api' \
59
+ '-DUSING_UV_SHARED=1' \
60
+ '-DUSING_V8_SHARED=1' \
61
+ '-DV8_DEPRECATION_WARNINGS=1' \
62
+ '-D_GLIBCXX_USE_CXX11_ABI=1' \
63
+ '-D_FILE_OFFSET_BITS=64' \
64
+ '-D_DARWIN_USE_64_BIT_INODE=1' \
65
+ '-D_LARGEFILE_SOURCE' \
66
+ '-DOPENSSL_NO_PINSHARED' \
67
+ '-DOPENSSL_THREADS'
68
+
69
+ # Flags passed to all source files.
70
+ CFLAGS_Release := \
71
+ -O3 \
72
+ -gdwarf-2 \
73
+ -fno-strict-aliasing \
74
+ -mmacosx-version-min=13.5 \
75
+ -arch \
76
+ arm64 \
77
+ -Wall \
78
+ -Wendif-labels \
79
+ -W \
80
+ -Wno-unused-parameter
81
+
82
+ # Flags passed to only C files.
83
+ CFLAGS_C_Release :=
84
+
85
+ # Flags passed to only C++ files.
86
+ CFLAGS_CC_Release := \
87
+ -std=gnu++20 \
88
+ -stdlib=libc++ \
89
+ -fno-rtti \
90
+ -fno-exceptions
91
+
92
+ # Flags passed to only ObjC files.
93
+ CFLAGS_OBJC_Release :=
94
+
95
+ # Flags passed to only ObjC++ files.
96
+ CFLAGS_OBJCC_Release :=
97
+
98
+ INCS_Release := \
99
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/include/node \
100
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/src \
101
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/openssl/config \
102
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/openssl/openssl/include \
103
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/uv/include \
104
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/zlib \
105
+ -I/Users/nantasmac/Library/Caches/node-gyp/24.15.0/deps/v8/include
106
+
107
+ OBJS :=
108
+
109
+ # Add to the list of files we specially track dependencies for.
110
+ all_deps += $(OBJS)
111
+
112
+
113
+ ### Rules for final target.
114
+ $(obj).target/../../node_modules/node-addon-api/node_addon_api.stamp: TOOLSET := $(TOOLSET)
115
+ $(obj).target/../../node_modules/node-addon-api/node_addon_api.stamp: FORCE_DO_CMD
116
+ $(call do_cmd,touch)
117
+
118
+ all_deps += $(obj).target/../../node_modules/node-addon-api/node_addon_api.stamp
119
+ # Add target alias
120
+ .PHONY: node_addon_api
121
+ node_addon_api: $(obj).target/../../node_modules/node-addon-api/node_addon_api.stamp
122
+