@veewo/gitnexus 1.5.8 → 1.5.9

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.
@@ -4,6 +4,7 @@ export interface StoredAnalyzeOptions {
4
4
  repoAlias?: string;
5
5
  embeddings?: boolean;
6
6
  csharpDefineCsproj?: string;
7
+ aiContext?: boolean;
7
8
  }
8
9
  export interface ResolveAnalyzeOptionsInput {
9
10
  extensions?: string;
@@ -12,6 +13,7 @@ export interface ResolveAnalyzeOptionsInput {
12
13
  embeddings?: boolean;
13
14
  reuseOptions?: boolean;
14
15
  csharpDefineCsproj?: string;
16
+ aiContext?: boolean;
15
17
  }
16
18
  export interface EffectiveAnalyzeOptions {
17
19
  includeExtensions: string[];
@@ -19,6 +21,7 @@ export interface EffectiveAnalyzeOptions {
19
21
  repoAlias?: string;
20
22
  embeddings: boolean;
21
23
  csharpDefineCsproj?: string;
24
+ aiContext: boolean;
22
25
  }
23
26
  export declare function parseExtensionList(rawExtensions?: string): string[];
24
27
  /** Parse comma-separated scope rules (e.g. "Assets/,Packages/com.veewo.*"). */
@@ -30,6 +33,7 @@ export interface ValidatedStoredOptions {
30
33
  repoAlias?: string;
31
34
  embeddings: boolean;
32
35
  csharpDefineCsproj?: string;
36
+ aiContext: boolean;
33
37
  }
34
38
  /**
35
39
  * Validate stored options from meta.json.analyzeOptions before reusing them.
@@ -35,7 +35,14 @@ export function normalizeRepoAlias(repoAlias) {
35
35
  */
36
36
  export async function validateStoredOptions(stored, repoPath) {
37
37
  if (!stored) {
38
- return { includeExtensions: [], scopeRules: [], repoAlias: undefined, embeddings: false, csharpDefineCsproj: undefined };
38
+ return {
39
+ includeExtensions: [],
40
+ scopeRules: [],
41
+ repoAlias: undefined,
42
+ embeddings: false,
43
+ csharpDefineCsproj: undefined,
44
+ aiContext: true,
45
+ };
39
46
  }
40
47
  // Validate repoAlias
41
48
  let repoAlias;
@@ -84,6 +91,7 @@ export async function validateStoredOptions(stored, repoPath) {
84
91
  repoAlias,
85
92
  embeddings: Boolean(stored.embeddings),
86
93
  csharpDefineCsproj,
94
+ aiContext: stored.aiContext !== false,
87
95
  };
88
96
  }
89
97
  export async function resolveEffectiveAnalyzeOptions(options, stored) {
@@ -94,6 +102,7 @@ export async function resolveEffectiveAnalyzeOptions(options, stored) {
94
102
  const hasCliScope = options?.scope !== undefined;
95
103
  const hasCliRepoAlias = options?.repoAlias !== undefined;
96
104
  const hasCliCsproj = options?.csharpDefineCsproj !== undefined;
105
+ const hasCliAiContext = options?.aiContext !== undefined;
97
106
  const canReuse = options?.reuseOptions !== false;
98
107
  const includeExtensions = hasCliExtensions
99
108
  ? includeExtensionsFromCli
@@ -110,11 +119,15 @@ export async function resolveEffectiveAnalyzeOptions(options, stored) {
110
119
  const csharpDefineCsproj = hasCliCsproj
111
120
  ? options.csharpDefineCsproj
112
121
  : (canReuse ? stored?.csharpDefineCsproj : undefined);
122
+ const aiContext = hasCliAiContext
123
+ ? options.aiContext !== false
124
+ : (canReuse ? stored?.aiContext !== false : true);
113
125
  return {
114
126
  includeExtensions: [...includeExtensions],
115
127
  scopeRules: [...scopeRules],
116
128
  repoAlias,
117
129
  embeddings,
118
130
  csharpDefineCsproj,
131
+ aiContext,
119
132
  };
120
133
  }
@@ -20,11 +20,13 @@ test('resolveEffectiveAnalyzeOptions reuses stored settings when CLI omits them'
20
20
  scopeRules: ['Assets/NEON/Code'],
21
21
  repoAlias: 'neonspark-v1-subset',
22
22
  embeddings: true,
23
+ aiContext: false,
23
24
  });
24
25
  assert.deepEqual(resolved.includeExtensions, ['.cs']);
25
26
  assert.deepEqual(resolved.scopeRules, ['Assets/NEON/Code']);
26
27
  assert.equal(resolved.repoAlias, 'neonspark-v1-subset');
27
28
  assert.equal(resolved.embeddings, true);
29
+ assert.equal(resolved.aiContext, false);
28
30
  });
29
31
  test('resolveEffectiveAnalyzeOptions disables reuse via reuseOptions=false', async () => {
30
32
  const resolved = await resolveEffectiveAnalyzeOptions({ reuseOptions: false }, {
@@ -33,12 +35,14 @@ test('resolveEffectiveAnalyzeOptions disables reuse via reuseOptions=false', asy
33
35
  repoAlias: 'neonspark-v1-subset',
34
36
  embeddings: true,
35
37
  csharpDefineCsproj: '/tmp/Assembly-CSharp.csproj',
38
+ aiContext: false,
36
39
  });
37
40
  assert.deepEqual(resolved.includeExtensions, []);
38
41
  assert.deepEqual(resolved.scopeRules, []);
39
42
  assert.equal(resolved.repoAlias, undefined);
40
43
  assert.equal(resolved.embeddings, false);
41
44
  assert.equal(resolved.csharpDefineCsproj, undefined);
45
+ assert.equal(resolved.aiContext, true);
42
46
  });
43
47
  test('resolveEffectiveAnalyzeOptions prefers explicit CLI values over stored settings', async () => {
44
48
  const resolved = await resolveEffectiveAnalyzeOptions({
@@ -46,16 +50,19 @@ test('resolveEffectiveAnalyzeOptions prefers explicit CLI values over stored set
46
50
  scope: 'src/',
47
51
  repoAlias: 'new-alias',
48
52
  embeddings: false,
53
+ aiContext: true,
49
54
  }, {
50
55
  includeExtensions: ['.cs'],
51
56
  scopeRules: ['Assets/NEON/Code'],
52
57
  repoAlias: 'old-alias',
53
58
  embeddings: true,
59
+ aiContext: false,
54
60
  });
55
61
  assert.deepEqual(resolved.includeExtensions, ['.ts']);
56
62
  assert.deepEqual(resolved.scopeRules, ['src']);
57
63
  assert.equal(resolved.repoAlias, 'new-alias');
58
64
  assert.equal(resolved.embeddings, false);
65
+ assert.equal(resolved.aiContext, true);
59
66
  });
60
67
  test('resolveEffectiveAnalyzeOptions no stored uses defaults', async () => {
61
68
  const resolved = await resolveEffectiveAnalyzeOptions({}, undefined);
@@ -64,6 +71,7 @@ test('resolveEffectiveAnalyzeOptions no stored uses defaults', async () => {
64
71
  assert.equal(resolved.repoAlias, undefined);
65
72
  assert.equal(resolved.embeddings, false);
66
73
  assert.equal(resolved.csharpDefineCsproj, undefined);
74
+ assert.equal(resolved.aiContext, true);
67
75
  });
68
76
  test('resolveEffectiveAnalyzeOptions reuses stored scopeRules when CLI scope is omitted', async () => {
69
77
  const resolved = await resolveEffectiveAnalyzeOptions({ extensions: '.ts' }, {
@@ -87,6 +95,18 @@ test('resolveEffectiveAnalyzeOptions CLI csharpDefineCsproj overrides stored', a
87
95
  });
88
96
  assert.equal(resolved.csharpDefineCsproj, '/new/path.csproj');
89
97
  });
98
+ test('resolveEffectiveAnalyzeOptions reuses stored aiContext=false', async () => {
99
+ const resolved = await resolveEffectiveAnalyzeOptions({}, {
100
+ aiContext: false,
101
+ });
102
+ assert.equal(resolved.aiContext, false);
103
+ });
104
+ test('resolveEffectiveAnalyzeOptions CLI aiContext=true overrides stored false', async () => {
105
+ const resolved = await resolveEffectiveAnalyzeOptions({ aiContext: true }, {
106
+ aiContext: false,
107
+ });
108
+ assert.equal(resolved.aiContext, true);
109
+ });
90
110
  // ─── validateStoredOptions tests ────────────────────────────────────
91
111
  test('validateStoredOptions returns defaults when stored is undefined', async () => {
92
112
  const result = await validateStoredOptions(undefined, '/tmp');
@@ -95,6 +115,7 @@ test('validateStoredOptions returns defaults when stored is undefined', async ()
95
115
  assert.equal(result.repoAlias, undefined);
96
116
  assert.equal(result.embeddings, false);
97
117
  assert.equal(result.csharpDefineCsproj, undefined);
118
+ assert.equal(result.aiContext, true);
98
119
  });
99
120
  test('validateStoredOptions passes valid options unchanged', async () => {
100
121
  const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-validate-'));
@@ -106,12 +127,14 @@ test('validateStoredOptions passes valid options unchanged', async () => {
106
127
  repoAlias: 'my-repo',
107
128
  csharpDefineCsproj: csprojPath,
108
129
  embeddings: true,
130
+ aiContext: false,
109
131
  }, tmpDir);
110
132
  assert.deepEqual(result.includeExtensions, ['.cs', '.ts']);
111
133
  assert.deepEqual(result.scopeRules, ['Assets/']);
112
134
  assert.equal(result.repoAlias, 'my-repo');
113
135
  assert.equal(result.csharpDefineCsproj, csprojPath);
114
136
  assert.equal(result.embeddings, true);
137
+ assert.equal(result.aiContext, false);
115
138
  });
116
139
  test('validateStoredOptions warns on invalid repoAlias and falls back', async () => {
117
140
  const result = await validateStoredOptions({
@@ -5,6 +5,7 @@
5
5
  */
6
6
  export interface AnalyzeOptions {
7
7
  force?: boolean;
8
+ aiContext?: boolean;
8
9
  embeddings?: boolean;
9
10
  extensions?: string;
10
11
  scope?: string;
@@ -111,6 +111,7 @@ export const analyzeCommand = async (inputPath, options) => {
111
111
  let repoAlias;
112
112
  let embeddingsEnabled = false;
113
113
  let csharpDefineCsproj;
114
+ let aiContextEnabled = true;
114
115
  try {
115
116
  const validatedStored = await validateStoredOptions(options?.reuseOptions !== false ? existingMeta?.analyzeOptions : undefined, repoPath);
116
117
  const effectiveOptions = await resolveEffectiveAnalyzeOptions({
@@ -120,12 +121,14 @@ export const analyzeCommand = async (inputPath, options) => {
120
121
  embeddings: options?.embeddings,
121
122
  reuseOptions: options?.reuseOptions,
122
123
  csharpDefineCsproj: options?.csharpDefineCsproj,
124
+ aiContext: options?.aiContext,
123
125
  }, validatedStored);
124
126
  includeExtensions = effectiveOptions.includeExtensions;
125
127
  scopeRules = effectiveOptions.scopeRules;
126
128
  repoAlias = effectiveOptions.repoAlias;
127
129
  embeddingsEnabled = effectiveOptions.embeddings;
128
130
  csharpDefineCsproj = effectiveOptions.csharpDefineCsproj;
131
+ aiContextEnabled = effectiveOptions.aiContext;
129
132
  }
130
133
  catch (error) {
131
134
  console.log(` ${error?.message || String(error)}\n`);
@@ -141,6 +144,7 @@ export const analyzeCommand = async (inputPath, options) => {
141
144
  options?.repoAlias !== undefined ||
142
145
  options?.csharpDefineCsproj !== undefined ||
143
146
  options?.embeddings !== undefined ||
147
+ options?.aiContext !== undefined ||
144
148
  options?.reuseOptions === false;
145
149
  if (!hasCliOverrides) {
146
150
  console.log(' Already up to date\n');
@@ -150,7 +154,8 @@ export const analyzeCommand = async (inputPath, options) => {
150
154
  includeExtensions.length === 0 &&
151
155
  scopeRules.length === 0 &&
152
156
  !repoAlias &&
153
- !embeddingsEnabled) {
157
+ !embeddingsEnabled &&
158
+ aiContextEnabled) {
154
159
  console.log(' Already up to date\n');
155
160
  return;
156
161
  }
@@ -350,6 +355,7 @@ export const analyzeCommand = async (inputPath, options) => {
350
355
  scopeRules,
351
356
  repoAlias,
352
357
  embeddings: embeddingsEnabled,
358
+ aiContext: aiContextEnabled,
353
359
  ...(csharpDefineCsproj ? { csharpDefineCsproj } : {}),
354
360
  },
355
361
  stats: {
@@ -382,17 +388,20 @@ export const analyzeCommand = async (inputPath, options) => {
382
388
  const skillResult = await generateSkillFiles(repoPath, projectName, pipelineForSkills);
383
389
  generatedSkills = skillResult.skills;
384
390
  }
385
- const cliConfig = await loadCLIConfig();
386
- const aiContext = await generateAIContextFiles(repoPath, storagePath, projectName, {
387
- files: pipelineRuntime.totalFileCount,
388
- nodes: stats.nodes,
389
- edges: stats.edges,
390
- communities: pipelineRuntime.communityResult?.stats.totalCommunities,
391
- clusters: aggregatedClusterCount,
392
- processes: pipelineRuntime.processResult?.stats.totalProcesses,
393
- }, {
394
- skillScope: (cliConfig.setupScope === 'global') ? 'global' : 'project',
395
- }, generatedSkills);
391
+ let aiContext = { files: [] };
392
+ if (aiContextEnabled) {
393
+ const cliConfig = await loadCLIConfig();
394
+ aiContext = await generateAIContextFiles(repoPath, storagePath, projectName, {
395
+ files: pipelineRuntime.totalFileCount,
396
+ nodes: stats.nodes,
397
+ edges: stats.edges,
398
+ communities: pipelineRuntime.communityResult?.stats.totalCommunities,
399
+ clusters: aggregatedClusterCount,
400
+ processes: pipelineRuntime.processResult?.stats.totalProcesses,
401
+ }, {
402
+ skillScope: (cliConfig.setupScope === 'global') ? 'global' : 'project',
403
+ }, generatedSkills);
404
+ }
396
405
  await closeLbug();
397
406
  // Note: we intentionally do NOT call disposeEmbedder() here.
398
407
  // ONNX Runtime's native cleanup segfaults on macOS and some Linux configs.
@@ -442,7 +451,10 @@ export const analyzeCommand = async (inputPath, options) => {
442
451
  console.log(` File filter: ${includeExtensions.join(', ')}`);
443
452
  }
444
453
  console.log(` ${repoPath}`);
445
- if (aiContext.files.length > 0) {
454
+ if (!aiContextEnabled) {
455
+ console.log(' Context: skipped (--no-ai-context)');
456
+ }
457
+ else if (aiContext.files.length > 0) {
446
458
  console.log(` Context: ${aiContext.files.join(', ')}`);
447
459
  }
448
460
  if (lbugWarnings.length > 0) {
package/dist/cli/clean.js CHANGED
@@ -5,7 +5,28 @@
5
5
  * Also unregisters the repo from the global registry.
6
6
  */
7
7
  import fs from 'fs/promises';
8
+ import path from 'path';
8
9
  import { findRepo, unregisterRepo, listRegisteredRepos } from '../storage/repo-manager.js';
10
+ /**
11
+ * Selectively delete contents of a .gitnexus directory, preserving config files.
12
+ * Preserves: meta.json, config.json, .gitnexusignore
13
+ */
14
+ const selectiveClean = async (storagePath) => {
15
+ const PRESERVE = new Set(['meta.json', 'config.json', '.gitnexusignore']);
16
+ let entries;
17
+ try {
18
+ entries = await fs.readdir(storagePath);
19
+ }
20
+ catch {
21
+ // Directory doesn't exist, nothing to clean
22
+ return;
23
+ }
24
+ for (const entry of entries) {
25
+ if (PRESERVE.has(entry))
26
+ continue;
27
+ await fs.rm(path.join(storagePath, entry), { recursive: true, force: true });
28
+ }
29
+ };
9
30
  export const cleanCommand = async (options) => {
10
31
  // --all flag: clean all indexed repos
11
32
  if (options?.all) {
@@ -25,7 +46,7 @@ export const cleanCommand = async (options) => {
25
46
  const entries = await listRegisteredRepos();
26
47
  for (const entry of entries) {
27
48
  try {
28
- await fs.rm(entry.storagePath, { recursive: true, force: true });
49
+ await selectiveClean(entry.storagePath);
29
50
  await unregisterRepo(entry.path);
30
51
  console.log(`Cleaned: ${entry.name} (${entry.storagePath})`);
31
52
  }
@@ -50,7 +71,7 @@ export const cleanCommand = async (options) => {
50
71
  return;
51
72
  }
52
73
  try {
53
- await fs.rm(repo.storagePath, { recursive: true, force: true });
74
+ await selectiveClean(repo.storagePath);
54
75
  await unregisterRepo(repo.repoPath);
55
76
  console.log(`Cleaned: ${repo.storagePath}`);
56
77
  }
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // Heap re-spawn removed — only analyze.ts needs the 8GB heap (via its own ensureHeap()).
3
3
  // Removing it from here improves MCP server startup time significantly.
4
- import { Command } from 'commander';
4
+ import { Command, Option } from 'commander';
5
5
  import { createRequire } from 'node:module';
6
6
  import { createLazyAction } from './lazy-action.js';
7
7
  const _require = createRequire(import.meta.url);
@@ -24,6 +24,8 @@ program
24
24
  .description('Index a repository (full analysis)')
25
25
  .option('-f, --force', 'Force full re-index even if up to date')
26
26
  .option('--no-reuse-options', 'Do not reuse stored analyze options from previous index')
27
+ .addOption(new Option('--ai-context', 'Write AGENTS.md/CLAUDE.md and install repo-local GitNexus skills').hideHelp())
28
+ .option('--no-ai-context', 'Skip writing AGENTS.md/CLAUDE.md and installing repo-local GitNexus skills')
27
29
  .option('--embeddings', 'Enable embedding generation for semantic search (off by default)')
28
30
  .option('--extensions <list>', 'Comma-separated file extensions to include (e.g. .cs,.ts)')
29
31
  .option('--repo-alias <name>', 'Override indexed repository name with a stable alias')
@@ -51,6 +51,7 @@ test('saveMeta/loadMeta persists analyzeOptions for future re-index reuse', asyn
51
51
  scopeRules: ['Assets/NEON/Code'],
52
52
  repoAlias: 'neonspark-v1-subset',
53
53
  embeddings: true,
54
+ aiContext: false,
54
55
  },
55
56
  stats: { files: 1, nodes: 2, edges: 3 },
56
57
  });
@@ -60,6 +61,7 @@ test('saveMeta/loadMeta persists analyzeOptions for future re-index reuse', asyn
60
61
  scopeRules: ['Assets/NEON/Code'],
61
62
  repoAlias: 'neonspark-v1-subset',
62
63
  embeddings: true,
64
+ aiContext: false,
63
65
  });
64
66
  assert.equal(meta?.repoId, 'neonspark-v1-subset');
65
67
  });
@@ -11,6 +11,6 @@ export declare const RUST_QUERIES = "\n; Functions & Items\n(function_item name:
11
11
  export declare const PHP_QUERIES = "\n; \u2500\u2500 Namespace \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(namespace_definition\n name: (namespace_name) @name) @definition.namespace\n\n; \u2500\u2500 Classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_declaration\n name: (name) @name) @definition.class\n\n; \u2500\u2500 Interfaces \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(interface_declaration\n name: (name) @name) @definition.interface\n\n; \u2500\u2500 Traits \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(trait_declaration\n name: (name) @name) @definition.trait\n\n; \u2500\u2500 Enums (PHP 8.1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(enum_declaration\n name: (name) @name) @definition.enum\n\n; \u2500\u2500 Top-level functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(function_definition\n name: (name) @name) @definition.function\n\n; \u2500\u2500 Methods (including constructors) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(method_declaration\n name: (name) @name) @definition.method\n\n; \u2500\u2500 Class properties (including Eloquent $fillable, $casts, etc.) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(property_declaration\n (property_element\n (variable_name\n (name) @name))) @definition.property\n\n; \u2500\u2500 Imports: use statements \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n; Simple: use App\\Models\\User;\n(namespace_use_declaration\n (namespace_use_clause\n (qualified_name) @import.source)) @import\n\n; \u2500\u2500 Function/method calls \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n; Regular function call: foo()\n(function_call_expression\n function: (name) @call.name) @call\n\n; Method call: $obj->method()\n(member_call_expression\n name: (name) @call.name) @call\n\n; Nullsafe method call: $obj?->method()\n(nullsafe_member_call_expression\n name: (name) @call.name) @call\n\n; Static call: Foo::bar() (php_only uses scoped_call_expression)\n(scoped_call_expression\n name: (name) @call.name) @call\n\n; Constructor call: new User()\n(object_creation_expression (name) @call.name) @call\n\n; \u2500\u2500 Heritage: extends \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_declaration\n name: (name) @heritage.class\n (base_clause\n [(name) (qualified_name)] @heritage.extends)) @heritage\n\n; \u2500\u2500 Heritage: implements \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_declaration\n name: (name) @heritage.class\n (class_interface_clause\n [(name) (qualified_name)] @heritage.implements)) @heritage.impl\n\n; \u2500\u2500 Heritage: use trait (must capture enclosing class name) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_declaration\n name: (name) @heritage.class\n body: (declaration_list\n (use_declaration\n [(name) (qualified_name)] @heritage.trait))) @heritage\n";
12
12
  export declare const RUBY_QUERIES = "\n; \u2500\u2500 Modules \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(module\n name: (constant) @name) @definition.module\n\n; \u2500\u2500 Classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class\n name: (constant) @name) @definition.class\n\n; \u2500\u2500 Instance methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(method\n name: (identifier) @name) @definition.method\n\n; \u2500\u2500 Singleton (class-level) methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(singleton_method\n name: (identifier) @name) @definition.method\n\n; \u2500\u2500 All calls (require, include, attr_*, and regular calls routed in JS) \u2500\u2500\u2500\u2500\u2500\n(call\n method: (identifier) @call.name) @call\n\n; \u2500\u2500 Bare calls without parens (identifiers at statement level are method calls) \u2500\n; NOTE: This may over-capture variable reads as calls (e.g. 'result' at\n; statement level). Ruby's grammar makes bare identifiers ambiguous \u2014 they\n; could be local variables or zero-arity method calls. Post-processing via\n; isBuiltInOrNoise and symbol resolution filtering suppresses most false\n; positives, but a variable name that coincidentally matches a method name\n; elsewhere may produce a false CALLS edge.\n(body_statement\n (identifier) @call.name @call)\n\n; \u2500\u2500 Heritage: class < SuperClass \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class\n name: (constant) @heritage.class\n superclass: (superclass\n (constant) @heritage.extends)) @heritage\n";
13
13
  export declare const KOTLIN_QUERIES = "\n; \u2500\u2500 Interfaces \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n; tree-sitter-kotlin (fwcd) has no interface_declaration node type.\n; Interfaces are class_declaration nodes with an anonymous \"interface\" keyword child.\n(class_declaration\n \"interface\"\n (type_identifier) @name) @definition.interface\n\n; \u2500\u2500 Classes (regular, data, sealed, enum) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n; All have the anonymous \"class\" keyword child. enum class has both\n; \"enum\" and \"class\" children \u2014 the \"class\" child still matches.\n(class_declaration\n \"class\"\n (type_identifier) @name) @definition.class\n\n; \u2500\u2500 Object declarations (Kotlin singletons) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(object_declaration\n (type_identifier) @name) @definition.class\n\n; \u2500\u2500 Companion objects (named only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(companion_object\n (type_identifier) @name) @definition.class\n\n; \u2500\u2500 Functions (top-level, member, extension) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(function_declaration\n (simple_identifier) @name) @definition.function\n\n; \u2500\u2500 Properties \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(property_declaration\n (variable_declaration\n (simple_identifier) @name)) @definition.property\n\n; \u2500\u2500 Enum entries \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(enum_entry\n (simple_identifier) @name) @definition.enum\n\n; \u2500\u2500 Type aliases \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(type_alias\n (type_identifier) @name) @definition.type\n\n; \u2500\u2500 Imports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(import_header\n (identifier) @import.source) @import\n\n; \u2500\u2500 Function calls (direct) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(call_expression\n (simple_identifier) @call.name) @call\n\n; \u2500\u2500 Method calls (via navigation: obj.method()) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(call_expression\n (navigation_expression\n (navigation_suffix\n (simple_identifier) @call.name))) @call\n\n; \u2500\u2500 Constructor invocations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(constructor_invocation\n (user_type\n (type_identifier) @call.name)) @call\n\n; \u2500\u2500 Infix function calls (e.g., a to b, x until y) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(infix_expression\n (simple_identifier) @call.name) @call\n\n; \u2500\u2500 Heritage: extends / implements via delegation_specifier \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n; Interface implementation (bare user_type): class Foo : Bar\n(class_declaration\n (type_identifier) @heritage.class\n (delegation_specifier\n (user_type (type_identifier) @heritage.extends))) @heritage\n\n; Class extension (constructor_invocation): class Foo : Bar()\n(class_declaration\n (type_identifier) @heritage.class\n (delegation_specifier\n (constructor_invocation\n (user_type (type_identifier) @heritage.extends)))) @heritage\n";
14
- export declare const GDSCRIPT_QUERIES = "\n; \u2500\u2500 Class Name (file-level class) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_name_statement\n (name) @name) @definition.class\n\n; \u2500\u2500 Inner Class Definition \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_definition\n name: (name) @name) @definition.class\n\n; \u2500\u2500 Functions & Methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(function_definition\n name: (name) @name) @definition.function\n\n; \u2500\u2500 Constructor (_init) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(constructor_definition) @definition.constructor\n\n; \u2500\u2500 Constructor with name capture for symbol extraction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(constructor_definition\n parameters: (parameters)) @definition.constructor\n\n; \u2500\u2500 Signals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(signal_statement\n name: (name) @name) @definition.signal\n\n; \u2500\u2500 Enums \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(enum_definition\n name: (name) @name) @definition.enum\n\n; \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(const_statement\n (name) @name) @definition.const\n\n; \u2500\u2500 Extends (inheritance) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(extends_statement\n (type (identifier) @heritage.extends)) @heritage\n\n; \u2500\u2500 Class with extends \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_definition\n name: (name) @heritage.class\n extends: (extends_statement\n (type (identifier) @heritage.extends))) @heritage\n\n; \u2500\u2500 Preload/Load (imports) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n; Only preload(\"res://...\") and load(\"res://...\") are real imports.\n; Generic call expressions must NOT be tagged @import to avoid double-classifying\n; call sites as imports (which corrupts import resolution and call routing).\n(call\n function: (identifier) @_preload\n arguments: (arguments (string) @import.source)) @import\n(#eq? @_preload \"preload\")\n\n(call\n function: (identifier) @_load\n arguments: (arguments (string) @import.source)) @import\n(#eq? @_load \"load\")\n\n; \u2500\u2500 Function Calls \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(call\n function: (identifier) @call.name) @call\n\n";
14
+ export declare const GDSCRIPT_QUERIES = "\n; \u2500\u2500 Class Name (file-level class) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_name_statement\n (name) @name) @definition.class\n\n; \u2500\u2500 Inner Class Definition \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_definition\n name: (name) @name) @definition.class\n\n; \u2500\u2500 Functions & Methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(function_definition\n name: (name) @name) @definition.function\n\n; \u2500\u2500 Constructor (_init) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(constructor_definition) @definition.constructor\n\n; \u2500\u2500 Constructor with name capture for symbol extraction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(constructor_definition\n parameters: (parameters)) @definition.constructor\n\n; \u2500\u2500 Signals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(signal_statement\n name: (name) @name) @definition.signal\n\n; \u2500\u2500 Enums \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(enum_definition\n name: (name) @name) @definition.enum\n\n; \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(const_statement\n (name) @name) @definition.const\n\n; \u2500\u2500 Extends (inheritance) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(extends_statement\n (type (identifier) @heritage.extends)) @heritage\n\n; \u2500\u2500 Class with extends \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(class_definition\n name: (name) @heritage.class\n extends: (extends_statement\n (type (identifier) @heritage.extends))) @heritage\n\n; \u2500\u2500 Preload/Load (imports) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n; Only preload(\"res://...\") and load(\"res://...\") are real imports.\n; Generic call expressions must NOT be tagged @import to avoid double-classifying\n; call sites as imports (which corrupts import resolution and call routing).\n(call\n (identifier) @_preload\n arguments: (arguments (string) @import.source)) @import\n(#eq? @_preload \"preload\")\n\n(call\n (identifier) @_load\n arguments: (arguments (string) @import.source)) @import\n(#eq? @_load \"load\")\n\n; \u2500\u2500 Function Calls \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n(call\n (identifier) @call.name) @call\n\n";
15
15
  export declare const SWIFT_QUERIES = "\n; Classes\n(class_declaration \"class\" name: (type_identifier) @name) @definition.class\n\n; Structs\n(class_declaration \"struct\" name: (type_identifier) @name) @definition.struct\n\n; Enums\n(class_declaration \"enum\" name: (type_identifier) @name) @definition.enum\n\n; Extensions (mapped to class \u2014 no dedicated label in schema)\n(class_declaration \"extension\" name: (user_type (type_identifier) @name)) @definition.class\n\n; Actors\n(class_declaration \"actor\" name: (type_identifier) @name) @definition.class\n\n; Protocols (mapped to interface)\n(protocol_declaration name: (type_identifier) @name) @definition.interface\n\n; Type aliases\n(typealias_declaration name: (type_identifier) @name) @definition.type\n\n; Functions (top-level and methods)\n(function_declaration name: (simple_identifier) @name) @definition.function\n\n; Protocol method declarations\n(protocol_function_declaration name: (simple_identifier) @name) @definition.method\n\n; Initializers\n(init_declaration) @definition.constructor\n\n; Properties (stored and computed)\n(property_declaration (pattern (simple_identifier) @name)) @definition.property\n\n; Imports\n(import_declaration (identifier (simple_identifier) @import.source)) @import\n\n; Calls - direct function calls\n(call_expression (simple_identifier) @call.name) @call\n\n; Calls - member/navigation calls (obj.method())\n(call_expression (navigation_expression (navigation_suffix (simple_identifier) @call.name))) @call\n\n; Heritage - class/struct/enum inheritance and protocol conformance\n(class_declaration name: (type_identifier) @heritage.class\n (inheritance_specifier inherits_from: (user_type (type_identifier) @heritage.extends))) @heritage\n\n; Heritage - protocol inheritance\n(protocol_declaration name: (type_identifier) @heritage.class\n (inheritance_specifier inherits_from: (user_type (type_identifier) @heritage.extends))) @heritage\n\n; Heritage - extension protocol conformance (e.g. extension Foo: SomeProtocol)\n; Extensions wrap the name in user_type unlike class/struct/enum declarations\n(class_declaration \"extension\" name: (user_type (type_identifier) @heritage.class)\n (inheritance_specifier inherits_from: (user_type (type_identifier) @heritage.extends))) @heritage\n";
16
16
  export declare const LANGUAGE_QUERIES: Record<SupportedLanguages, string>;
@@ -662,18 +662,18 @@ export const GDSCRIPT_QUERIES = `
662
662
  ; Generic call expressions must NOT be tagged @import to avoid double-classifying
663
663
  ; call sites as imports (which corrupts import resolution and call routing).
664
664
  (call
665
- function: (identifier) @_preload
665
+ (identifier) @_preload
666
666
  arguments: (arguments (string) @import.source)) @import
667
667
  (#eq? @_preload "preload")
668
668
 
669
669
  (call
670
- function: (identifier) @_load
670
+ (identifier) @_load
671
671
  arguments: (arguments (string) @import.source)) @import
672
672
  (#eq? @_load "load")
673
673
 
674
674
  ; ── Function Calls ──────────────────────────────────────────────────────────
675
675
  (call
676
- function: (identifier) @call.name) @call
676
+ (identifier) @call.name) @call
677
677
 
678
678
  `;
679
679
  export const SWIFT_QUERIES = `
@@ -16,6 +16,7 @@ export interface RepoMeta {
16
16
  repoAlias?: string;
17
17
  embeddings?: boolean;
18
18
  csharpDefineCsproj?: string;
19
+ aiContext?: boolean;
19
20
  };
20
21
  stats?: {
21
22
  files?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veewo/gitnexus",
3
- "version": "1.5.8",
3
+ "version": "1.5.9",
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",
@@ -71,6 +71,7 @@
71
71
  },
72
72
  "dependencies": {
73
73
  "@huggingface/transformers": "^3.0.0",
74
+ "@ladybugdb/core": "0.15.1",
74
75
  "@modelcontextprotocol/sdk": "^1.0.0",
75
76
  "cli-progress": "^3.12.0",
76
77
  "commander": "^12.0.0",
@@ -80,7 +81,6 @@
80
81
  "graphology": "^0.25.4",
81
82
  "graphology-indices": "^0.17.0",
82
83
  "graphology-utils": "^2.3.0",
83
- "@ladybugdb/core": "0.15.1",
84
84
  "ignore": "^7.0.5",
85
85
  "lru-cache": "^11.0.0",
86
86
  "mnemonist": "^0.39.0",
@@ -100,9 +100,9 @@
100
100
  "uuid": "^13.0.0"
101
101
  },
102
102
  "optionalDependencies": {
103
+ "tree-sitter-gdscript": "^6.1.0",
103
104
  "tree-sitter-kotlin": "^0.3.8",
104
- "tree-sitter-swift": "^0.6.0",
105
- "tree-sitter-gdscript": "^6.1.0"
105
+ "tree-sitter-swift": "^0.6.0"
106
106
  },
107
107
  "devDependencies": {
108
108
  "@types/cli-progress": "^3.11.6",
@@ -58,7 +58,7 @@ fi
58
58
  $GN analyze
59
59
  ```
60
60
 
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.
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 unless `--no-ai-context` is set.
62
62
 
63
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
64
 
@@ -66,6 +66,7 @@ Analyze options are resolved with two-layer priority: **CLI arguments** > **stor
66
66
  |------|--------|
67
67
  | `--force` | Force full re-index even if up to date |
68
68
  | `--no-reuse-options` | Do not reuse stored analyze options from previous index |
69
+ | `--no-ai-context` | Skip writing `AGENTS.md` / `CLAUDE.md` and installing repo-local GitNexus skills |
69
70
  | `--embeddings` | Enable embedding generation (off by default) |
70
71
  | `--extensions <list>` | Comma-separated file extensions (e.g. `.cs,.ts`) |
71
72
  | `--scope <rules>` | Comma-separated scope path-prefix rules (e.g. `Assets/,Packages/com.veewo.*`) |
@@ -74,7 +75,9 @@ Analyze options are resolved with two-layer priority: **CLI arguments** > **stor
74
75
  | `--skills` | Generate repo-specific skill files from detected communities |
75
76
  | `-v, --verbose` | Enable verbose ingestion warnings |
76
77
 
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`.
78
+ **Option persistence:** `--extensions`, `--scope`, `--repo-alias`, `--embeddings`, `--csharp-define-csproj`, and the effective AI-context setting 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`.
79
+
80
+ When `--no-ai-context` is saved, later `analyze` runs continue skipping AGENTS/CLAUDE generation until you explicitly re-enable AI context (for example by passing `--ai-context` through a direct CLI invocation or clearing the stored setting with `--no-reuse-options`).
78
81
 
79
82
  #### Scope rules
80
83