@veewo/gitnexus 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +234 -0
- package/dist/benchmark/agent-context/evaluators.d.ts +9 -0
- package/dist/benchmark/agent-context/evaluators.js +196 -0
- package/dist/benchmark/agent-context/evaluators.test.d.ts +1 -0
- package/dist/benchmark/agent-context/evaluators.test.js +39 -0
- package/dist/benchmark/agent-context/io.d.ts +2 -0
- package/dist/benchmark/agent-context/io.js +23 -0
- package/dist/benchmark/agent-context/io.test.d.ts +1 -0
- package/dist/benchmark/agent-context/io.test.js +19 -0
- package/dist/benchmark/agent-context/report.d.ts +2 -0
- package/dist/benchmark/agent-context/report.js +59 -0
- package/dist/benchmark/agent-context/report.test.d.ts +1 -0
- package/dist/benchmark/agent-context/report.test.js +85 -0
- package/dist/benchmark/agent-context/runner.d.ts +46 -0
- package/dist/benchmark/agent-context/runner.js +111 -0
- package/dist/benchmark/agent-context/runner.test.d.ts +1 -0
- package/dist/benchmark/agent-context/runner.test.js +79 -0
- package/dist/benchmark/agent-context/tool-runner.d.ts +7 -0
- package/dist/benchmark/agent-context/tool-runner.js +18 -0
- package/dist/benchmark/agent-context/tool-runner.test.d.ts +1 -0
- package/dist/benchmark/agent-context/tool-runner.test.js +11 -0
- package/dist/benchmark/agent-context/types.d.ts +40 -0
- package/dist/benchmark/agent-context/types.js +1 -0
- package/dist/benchmark/analyze-runner.d.ts +16 -0
- package/dist/benchmark/analyze-runner.js +51 -0
- package/dist/benchmark/analyze-runner.test.d.ts +1 -0
- package/dist/benchmark/analyze-runner.test.js +37 -0
- package/dist/benchmark/evaluators.d.ts +6 -0
- package/dist/benchmark/evaluators.js +10 -0
- package/dist/benchmark/evaluators.test.d.ts +1 -0
- package/dist/benchmark/evaluators.test.js +12 -0
- package/dist/benchmark/io.d.ts +7 -0
- package/dist/benchmark/io.js +25 -0
- package/dist/benchmark/io.test.d.ts +1 -0
- package/dist/benchmark/io.test.js +35 -0
- package/dist/benchmark/neonspark-candidates.d.ts +19 -0
- package/dist/benchmark/neonspark-candidates.js +94 -0
- package/dist/benchmark/neonspark-candidates.test.d.ts +1 -0
- package/dist/benchmark/neonspark-candidates.test.js +43 -0
- package/dist/benchmark/neonspark-materialize.d.ts +19 -0
- package/dist/benchmark/neonspark-materialize.js +111 -0
- package/dist/benchmark/neonspark-materialize.test.d.ts +1 -0
- package/dist/benchmark/neonspark-materialize.test.js +124 -0
- package/dist/benchmark/neonspark-sync.d.ts +3 -0
- package/dist/benchmark/neonspark-sync.js +53 -0
- package/dist/benchmark/neonspark-sync.test.d.ts +1 -0
- package/dist/benchmark/neonspark-sync.test.js +20 -0
- package/dist/benchmark/report.d.ts +1 -0
- package/dist/benchmark/report.js +7 -0
- package/dist/benchmark/runner.d.ts +48 -0
- package/dist/benchmark/runner.js +302 -0
- package/dist/benchmark/runner.test.d.ts +1 -0
- package/dist/benchmark/runner.test.js +50 -0
- package/dist/benchmark/scoring.d.ts +16 -0
- package/dist/benchmark/scoring.js +27 -0
- package/dist/benchmark/scoring.test.d.ts +1 -0
- package/dist/benchmark/scoring.test.js +24 -0
- package/dist/benchmark/tool-runner.d.ts +6 -0
- package/dist/benchmark/tool-runner.js +17 -0
- package/dist/benchmark/types.d.ts +36 -0
- package/dist/benchmark/types.js +1 -0
- package/dist/cli/ai-context.d.ts +22 -0
- package/dist/cli/ai-context.js +184 -0
- package/dist/cli/ai-context.test.d.ts +1 -0
- package/dist/cli/ai-context.test.js +30 -0
- package/dist/cli/analyze-multi-scope-regression.test.d.ts +1 -0
- package/dist/cli/analyze-multi-scope-regression.test.js +22 -0
- package/dist/cli/analyze-options.d.ts +7 -0
- package/dist/cli/analyze-options.js +56 -0
- package/dist/cli/analyze-options.test.d.ts +1 -0
- package/dist/cli/analyze-options.test.js +36 -0
- package/dist/cli/analyze.d.ts +14 -0
- package/dist/cli/analyze.js +384 -0
- package/dist/cli/augment.d.ts +13 -0
- package/dist/cli/augment.js +33 -0
- package/dist/cli/benchmark-agent-context.d.ts +29 -0
- package/dist/cli/benchmark-agent-context.js +61 -0
- package/dist/cli/benchmark-agent-context.test.d.ts +1 -0
- package/dist/cli/benchmark-agent-context.test.js +80 -0
- package/dist/cli/benchmark-unity.d.ts +15 -0
- package/dist/cli/benchmark-unity.js +31 -0
- package/dist/cli/benchmark-unity.test.d.ts +1 -0
- package/dist/cli/benchmark-unity.test.js +18 -0
- package/dist/cli/claude-hooks.d.ts +22 -0
- package/dist/cli/claude-hooks.js +97 -0
- package/dist/cli/clean.d.ts +10 -0
- package/dist/cli/clean.js +60 -0
- package/dist/cli/eval-server.d.ts +30 -0
- package/dist/cli/eval-server.js +372 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +182 -0
- package/dist/cli/list.d.ts +6 -0
- package/dist/cli/list.js +33 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +34 -0
- package/dist/cli/repo-manager-alias.test.d.ts +1 -0
- package/dist/cli/repo-manager-alias.test.js +40 -0
- package/dist/cli/scope-filter.test.d.ts +1 -0
- package/dist/cli/scope-filter.test.js +49 -0
- package/dist/cli/serve.d.ts +4 -0
- package/dist/cli/serve.js +6 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +311 -0
- package/dist/cli/setup.test.d.ts +1 -0
- package/dist/cli/setup.test.js +31 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.js +27 -0
- package/dist/cli/tool.d.ts +40 -0
- package/dist/cli/tool.js +94 -0
- package/dist/cli/version.test.d.ts +1 -0
- package/dist/cli/version.test.js +19 -0
- package/dist/cli/wiki.d.ts +15 -0
- package/dist/cli/wiki.js +361 -0
- package/dist/config/ignore-service.d.ts +1 -0
- package/dist/config/ignore-service.js +210 -0
- package/dist/config/supported-languages.d.ts +12 -0
- package/dist/config/supported-languages.js +15 -0
- package/dist/core/augmentation/engine.d.ts +26 -0
- package/dist/core/augmentation/engine.js +213 -0
- package/dist/core/embeddings/embedder.d.ts +60 -0
- package/dist/core/embeddings/embedder.js +251 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +51 -0
- package/dist/core/embeddings/embedding-pipeline.js +329 -0
- package/dist/core/embeddings/index.d.ts +9 -0
- package/dist/core/embeddings/index.js +9 -0
- package/dist/core/embeddings/text-generator.d.ts +24 -0
- package/dist/core/embeddings/text-generator.js +182 -0
- package/dist/core/embeddings/types.d.ts +87 -0
- package/dist/core/embeddings/types.js +32 -0
- package/dist/core/graph/graph.d.ts +2 -0
- package/dist/core/graph/graph.js +66 -0
- package/dist/core/graph/types.d.ts +61 -0
- package/dist/core/graph/types.js +1 -0
- package/dist/core/ingestion/ast-cache.d.ts +11 -0
- package/dist/core/ingestion/ast-cache.js +34 -0
- package/dist/core/ingestion/call-processor.d.ts +15 -0
- package/dist/core/ingestion/call-processor.js +327 -0
- package/dist/core/ingestion/cluster-enricher.d.ts +38 -0
- package/dist/core/ingestion/cluster-enricher.js +170 -0
- package/dist/core/ingestion/community-processor.d.ts +39 -0
- package/dist/core/ingestion/community-processor.js +312 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +39 -0
- package/dist/core/ingestion/entry-point-scoring.js +260 -0
- package/dist/core/ingestion/filesystem-walker.d.ts +28 -0
- package/dist/core/ingestion/filesystem-walker.js +80 -0
- package/dist/core/ingestion/framework-detection.d.ts +39 -0
- package/dist/core/ingestion/framework-detection.js +235 -0
- package/dist/core/ingestion/heritage-processor.d.ts +20 -0
- package/dist/core/ingestion/heritage-processor.js +197 -0
- package/dist/core/ingestion/import-processor.d.ts +38 -0
- package/dist/core/ingestion/import-processor.js +778 -0
- package/dist/core/ingestion/parsing-processor.d.ts +15 -0
- package/dist/core/ingestion/parsing-processor.js +291 -0
- package/dist/core/ingestion/pipeline.d.ts +5 -0
- package/dist/core/ingestion/pipeline.js +323 -0
- package/dist/core/ingestion/process-processor.d.ts +51 -0
- package/dist/core/ingestion/process-processor.js +309 -0
- package/dist/core/ingestion/scope-filter.d.ts +25 -0
- package/dist/core/ingestion/scope-filter.js +100 -0
- package/dist/core/ingestion/structure-processor.d.ts +2 -0
- package/dist/core/ingestion/structure-processor.js +36 -0
- package/dist/core/ingestion/symbol-table.d.ts +33 -0
- package/dist/core/ingestion/symbol-table.js +38 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +12 -0
- package/dist/core/ingestion/tree-sitter-queries.js +398 -0
- package/dist/core/ingestion/utils.d.ts +10 -0
- package/dist/core/ingestion/utils.js +50 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +59 -0
- package/dist/core/ingestion/workers/parse-worker.js +672 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +16 -0
- package/dist/core/ingestion/workers/worker-pool.js +120 -0
- package/dist/core/kuzu/csv-generator.d.ts +29 -0
- package/dist/core/kuzu/csv-generator.js +336 -0
- package/dist/core/kuzu/kuzu-adapter.d.ts +101 -0
- package/dist/core/kuzu/kuzu-adapter.js +753 -0
- package/dist/core/kuzu/schema.d.ts +53 -0
- package/dist/core/kuzu/schema.js +407 -0
- package/dist/core/search/bm25-index.d.ts +23 -0
- package/dist/core/search/bm25-index.js +95 -0
- package/dist/core/search/hybrid-search.d.ts +49 -0
- package/dist/core/search/hybrid-search.js +118 -0
- package/dist/core/tree-sitter/parser-loader.d.ts +4 -0
- package/dist/core/tree-sitter/parser-loader.js +44 -0
- package/dist/core/wiki/generator.d.ts +110 -0
- package/dist/core/wiki/generator.js +786 -0
- package/dist/core/wiki/graph-queries.d.ts +80 -0
- package/dist/core/wiki/graph-queries.js +238 -0
- package/dist/core/wiki/html-viewer.d.ts +10 -0
- package/dist/core/wiki/html-viewer.js +297 -0
- package/dist/core/wiki/llm-client.d.ts +40 -0
- package/dist/core/wiki/llm-client.js +162 -0
- package/dist/core/wiki/prompts.d.ts +53 -0
- package/dist/core/wiki/prompts.js +174 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +3 -0
- package/dist/mcp/core/embedder.d.ts +27 -0
- package/dist/mcp/core/embedder.js +108 -0
- package/dist/mcp/core/kuzu-adapter.d.ts +34 -0
- package/dist/mcp/core/kuzu-adapter.js +231 -0
- package/dist/mcp/local/local-backend.d.ts +160 -0
- package/dist/mcp/local/local-backend.js +1646 -0
- package/dist/mcp/resources.d.ts +31 -0
- package/dist/mcp/resources.js +407 -0
- package/dist/mcp/server.d.ts +23 -0
- package/dist/mcp/server.js +251 -0
- package/dist/mcp/staleness.d.ts +15 -0
- package/dist/mcp/staleness.js +29 -0
- package/dist/mcp/tools.d.ts +24 -0
- package/dist/mcp/tools.js +195 -0
- package/dist/server/api.d.ts +10 -0
- package/dist/server/api.js +344 -0
- package/dist/server/mcp-http.d.ts +13 -0
- package/dist/server/mcp-http.js +100 -0
- package/dist/storage/git.d.ts +6 -0
- package/dist/storage/git.js +32 -0
- package/dist/storage/repo-manager.d.ts +125 -0
- package/dist/storage/repo-manager.js +257 -0
- package/dist/types/pipeline.d.ts +34 -0
- package/dist/types/pipeline.js +18 -0
- package/hooks/claude/gitnexus-hook.cjs +135 -0
- package/hooks/claude/pre-tool-use.sh +78 -0
- package/hooks/claude/session-start.sh +42 -0
- package/package.json +92 -0
- package/skills/gitnexus-cli.md +82 -0
- package/skills/gitnexus-debugging.md +89 -0
- package/skills/gitnexus-exploring.md +78 -0
- package/skills/gitnexus-guide.md +64 -0
- package/skills/gitnexus-impact-analysis.md +97 -0
- package/skills/gitnexus-refactoring.md +121 -0
- package/vendor/leiden/index.cjs +355 -0
- package/vendor/leiden/utils.cjs +392 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Raise Node heap limit for large repos (e.g. Linux kernel).
|
|
3
|
+
// Must run before any heavy allocation. If already set by the user, respect it.
|
|
4
|
+
if (!process.env.NODE_OPTIONS?.includes('--max-old-space-size')) {
|
|
5
|
+
const execArgv = process.execArgv.join(' ');
|
|
6
|
+
if (!execArgv.includes('--max-old-space-size')) {
|
|
7
|
+
// Re-spawn with a larger heap (8 GB)
|
|
8
|
+
const { execFileSync } = await import('node:child_process');
|
|
9
|
+
try {
|
|
10
|
+
execFileSync(process.execPath, ['--max-old-space-size=8192', ...process.argv.slice(1)], {
|
|
11
|
+
stdio: 'inherit',
|
|
12
|
+
env: { ...process.env, NODE_OPTIONS: `${process.env.NODE_OPTIONS || ''} --max-old-space-size=8192`.trim() },
|
|
13
|
+
});
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
// If the child exited with an error code, propagate it
|
|
18
|
+
process.exit(e.status ?? 1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
import { Command } from 'commander';
|
|
23
|
+
import fs from 'fs';
|
|
24
|
+
import path from 'path';
|
|
25
|
+
import { fileURLToPath } from 'url';
|
|
26
|
+
import { analyzeCommand } from './analyze.js';
|
|
27
|
+
import { serveCommand } from './serve.js';
|
|
28
|
+
import { listCommand } from './list.js';
|
|
29
|
+
import { statusCommand } from './status.js';
|
|
30
|
+
import { mcpCommand } from './mcp.js';
|
|
31
|
+
import { cleanCommand } from './clean.js';
|
|
32
|
+
import { setupCommand } from './setup.js';
|
|
33
|
+
import { augmentCommand } from './augment.js';
|
|
34
|
+
import { wikiCommand } from './wiki.js';
|
|
35
|
+
import { queryCommand, contextCommand, impactCommand, cypherCommand } from './tool.js';
|
|
36
|
+
import { evalServerCommand } from './eval-server.js';
|
|
37
|
+
import { benchmarkUnityCommand } from './benchmark-unity.js';
|
|
38
|
+
import { benchmarkAgentContextCommand } from './benchmark-agent-context.js';
|
|
39
|
+
function resolveCliVersion() {
|
|
40
|
+
try {
|
|
41
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
42
|
+
const packageJsonPath = path.resolve(path.dirname(currentFile), '..', '..', 'package.json');
|
|
43
|
+
const raw = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
44
|
+
const parsed = JSON.parse(raw);
|
|
45
|
+
if (typeof parsed.version === 'string' && parsed.version.length > 0) {
|
|
46
|
+
return parsed.version;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// fall through to default
|
|
51
|
+
}
|
|
52
|
+
return '0.0.0';
|
|
53
|
+
}
|
|
54
|
+
const program = new Command();
|
|
55
|
+
const collectValues = (value, previous) => [...previous, value];
|
|
56
|
+
program
|
|
57
|
+
.name('gitnexus')
|
|
58
|
+
.description('GitNexus local CLI and MCP server')
|
|
59
|
+
.version(resolveCliVersion());
|
|
60
|
+
program
|
|
61
|
+
.command('setup')
|
|
62
|
+
.description('One-time setup: configure MCP for Cursor, Claude Code, OpenCode')
|
|
63
|
+
.action(setupCommand);
|
|
64
|
+
program
|
|
65
|
+
.command('analyze [path]')
|
|
66
|
+
.description('Index a repository (full analysis)')
|
|
67
|
+
.option('-f, --force', 'Force full re-index even if up to date')
|
|
68
|
+
.option('--embeddings', 'Enable embedding generation for semantic search (off by default)')
|
|
69
|
+
.option('--extensions <list>', 'Comma-separated file extensions to include (e.g. .cs,.ts)')
|
|
70
|
+
.option('--repo-alias <name>', 'Override indexed repository name with a stable alias')
|
|
71
|
+
.option('--scope-manifest <path>', 'Manifest file with scope rules (supports comments and * wildcard)')
|
|
72
|
+
.option('--scope-prefix <pathPrefix>', 'Add a scope path prefix rule (repeatable)', collectValues, [])
|
|
73
|
+
.action(analyzeCommand);
|
|
74
|
+
program
|
|
75
|
+
.command('serve')
|
|
76
|
+
.description('Start local HTTP server for web UI connection')
|
|
77
|
+
.option('-p, --port <port>', 'Port number', '4747')
|
|
78
|
+
.option('--host <host>', 'Bind address (default: 127.0.0.1, use 0.0.0.0 for remote access)')
|
|
79
|
+
.action(serveCommand);
|
|
80
|
+
program
|
|
81
|
+
.command('mcp')
|
|
82
|
+
.description('Start MCP server (stdio) — serves all indexed repos')
|
|
83
|
+
.action(mcpCommand);
|
|
84
|
+
program
|
|
85
|
+
.command('list')
|
|
86
|
+
.description('List all indexed repositories')
|
|
87
|
+
.action(listCommand);
|
|
88
|
+
program
|
|
89
|
+
.command('status')
|
|
90
|
+
.description('Show index status for current repo')
|
|
91
|
+
.action(statusCommand);
|
|
92
|
+
program
|
|
93
|
+
.command('clean')
|
|
94
|
+
.description('Delete GitNexus index for current repo')
|
|
95
|
+
.option('-f, --force', 'Skip confirmation prompt')
|
|
96
|
+
.option('--all', 'Clean all indexed repos')
|
|
97
|
+
.action(cleanCommand);
|
|
98
|
+
program
|
|
99
|
+
.command('wiki [path]')
|
|
100
|
+
.description('Generate repository wiki from knowledge graph')
|
|
101
|
+
.option('-f, --force', 'Force full regeneration even if up to date')
|
|
102
|
+
.option('--model <model>', 'LLM model name (default: minimax/minimax-m2.5)')
|
|
103
|
+
.option('--base-url <url>', 'LLM API base URL (default: OpenAI)')
|
|
104
|
+
.option('--api-key <key>', 'LLM API key (saved to ~/.gitnexus/config.json)')
|
|
105
|
+
.option('--concurrency <n>', 'Parallel LLM calls (default: 3)', '3')
|
|
106
|
+
.option('--gist', 'Publish wiki as a public GitHub Gist after generation')
|
|
107
|
+
.action(wikiCommand);
|
|
108
|
+
program
|
|
109
|
+
.command('augment <pattern>')
|
|
110
|
+
.description('Augment a search pattern with knowledge graph context (used by hooks)')
|
|
111
|
+
.action(augmentCommand);
|
|
112
|
+
// ─── Direct Tool Commands (no MCP overhead) ────────────────────────
|
|
113
|
+
// These invoke LocalBackend directly for use in eval, scripts, and CI.
|
|
114
|
+
program
|
|
115
|
+
.command('query <search_query>')
|
|
116
|
+
.description('Search the knowledge graph for execution flows related to a concept')
|
|
117
|
+
.option('-r, --repo <name>', 'Target repository (omit if only one indexed)')
|
|
118
|
+
.option('-c, --context <text>', 'Task context to improve ranking')
|
|
119
|
+
.option('-g, --goal <text>', 'What you want to find')
|
|
120
|
+
.option('-l, --limit <n>', 'Max processes to return (default: 5)')
|
|
121
|
+
.option('--content', 'Include full symbol source code')
|
|
122
|
+
.action(queryCommand);
|
|
123
|
+
program
|
|
124
|
+
.command('context [name]')
|
|
125
|
+
.description('360-degree view of a code symbol: callers, callees, processes')
|
|
126
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
127
|
+
.option('-u, --uid <uid>', 'Direct symbol UID (zero-ambiguity lookup)')
|
|
128
|
+
.option('-f, --file <path>', 'File path to disambiguate common names')
|
|
129
|
+
.option('--content', 'Include full symbol source code')
|
|
130
|
+
.action(contextCommand);
|
|
131
|
+
program
|
|
132
|
+
.command('impact <target>')
|
|
133
|
+
.description('Blast radius analysis: what breaks if you change a symbol')
|
|
134
|
+
.option('-d, --direction <dir>', 'upstream (dependants) or downstream (dependencies)', 'upstream')
|
|
135
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
136
|
+
.option('-u, --uid <uid>', 'Exact target UID (disambiguates same-name symbols)')
|
|
137
|
+
.option('-f, --file <path>', 'File path filter to disambiguate target name')
|
|
138
|
+
.option('--depth <n>', 'Max relationship depth (default: 3)')
|
|
139
|
+
.option('--min-confidence <n>', 'Minimum edge confidence 0-1 (default: 0.3)')
|
|
140
|
+
.option('--include-tests', 'Include test files in results')
|
|
141
|
+
.action(impactCommand);
|
|
142
|
+
program
|
|
143
|
+
.command('cypher <query>')
|
|
144
|
+
.description('Execute raw Cypher query against the knowledge graph')
|
|
145
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
146
|
+
.action(cypherCommand);
|
|
147
|
+
// ─── Eval Server (persistent daemon for SWE-bench) ─────────────────
|
|
148
|
+
program
|
|
149
|
+
.command('eval-server')
|
|
150
|
+
.description('Start lightweight HTTP server for fast tool calls during evaluation')
|
|
151
|
+
.option('-p, --port <port>', 'Port number', '4848')
|
|
152
|
+
.option('--idle-timeout <seconds>', 'Auto-shutdown after N seconds idle (0 = disabled)', '0')
|
|
153
|
+
.action(evalServerCommand);
|
|
154
|
+
program
|
|
155
|
+
.command('benchmark-unity <dataset>')
|
|
156
|
+
.description('Run Unity accuracy baseline and hard-gated regression checks')
|
|
157
|
+
.option('-p, --profile <profile>', 'quick or full', 'quick')
|
|
158
|
+
.option('-r, --repo <name>', 'Target indexed repo')
|
|
159
|
+
.option('--repo-alias <name>', 'Analyze-time repo alias and default evaluation repo when --repo is omitted')
|
|
160
|
+
.option('--target-path <path>', 'Path to analyze before evaluation (required unless --skip-analyze)')
|
|
161
|
+
.option('--report-dir <path>', 'Output directory for benchmark-report.json and benchmark-summary.md', '.gitnexus/benchmark')
|
|
162
|
+
.option('--extensions <list>', 'Analyze extension filter (default: .cs)', '.cs')
|
|
163
|
+
.option('--scope-manifest <path>', 'Analyze scope manifest file')
|
|
164
|
+
.option('--scope-prefix <pathPrefix>', 'Analyze scope path prefix (repeatable)', collectValues, [])
|
|
165
|
+
.option('--skip-analyze', 'Skip analyze stage and evaluate current index only')
|
|
166
|
+
.action(benchmarkUnityCommand);
|
|
167
|
+
program
|
|
168
|
+
.command('benchmark-agent-context <dataset>')
|
|
169
|
+
.description('Run scenario-based agent refactor context benchmark')
|
|
170
|
+
.option('-p, --profile <profile>', 'quick or full', 'quick')
|
|
171
|
+
.option('-r, --repo <name>', 'Target indexed repo')
|
|
172
|
+
.option('--repo-alias <name>', 'Analyze-time repo alias and default evaluation repo when --repo is omitted')
|
|
173
|
+
.option('--target-path <path>', 'Path to analyze before evaluation (required unless --skip-analyze)')
|
|
174
|
+
.option('--report-dir <path>', 'Output directory for benchmark-report.json and benchmark-summary.md', '.gitnexus/benchmark-agent-context')
|
|
175
|
+
.option('--extensions <list>', 'Analyze extension filter (default: .cs)', '.cs')
|
|
176
|
+
.option('--scope-manifest <path>', 'Analyze scope manifest file')
|
|
177
|
+
.option('--scope-prefix <pathPrefix>', 'Analyze scope path prefix (repeatable)', collectValues, [])
|
|
178
|
+
.option('--skip-analyze', 'Skip analyze stage and evaluate current index only')
|
|
179
|
+
.action(async (dataset, options) => {
|
|
180
|
+
await benchmarkAgentContextCommand(dataset, options);
|
|
181
|
+
});
|
|
182
|
+
program.parse(process.argv);
|
package/dist/cli/list.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List Command
|
|
3
|
+
*
|
|
4
|
+
* Shows all indexed repositories from the global registry.
|
|
5
|
+
*/
|
|
6
|
+
import { listRegisteredRepos } from '../storage/repo-manager.js';
|
|
7
|
+
export const listCommand = async () => {
|
|
8
|
+
const entries = await listRegisteredRepos({ validate: true });
|
|
9
|
+
if (entries.length === 0) {
|
|
10
|
+
console.log('No indexed repositories found.');
|
|
11
|
+
console.log('Run `gitnexus analyze` in a git repo to index it.');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
console.log(`\n Indexed Repositories (${entries.length})\n`);
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const indexedDate = new Date(entry.indexedAt).toLocaleString();
|
|
17
|
+
const stats = entry.stats || {};
|
|
18
|
+
const commitShort = entry.lastCommit?.slice(0, 7) || 'unknown';
|
|
19
|
+
console.log(` ${entry.name}`);
|
|
20
|
+
console.log(` Path: ${entry.path}`);
|
|
21
|
+
if (entry.alias) {
|
|
22
|
+
console.log(` Alias: ${entry.alias} (source: ${entry.sourceName || 'unknown'})`);
|
|
23
|
+
}
|
|
24
|
+
console.log(` Indexed: ${indexedDate}`);
|
|
25
|
+
console.log(` Commit: ${commitShort}`);
|
|
26
|
+
console.log(` Stats: ${stats.files ?? 0} files, ${stats.nodes ?? 0} symbols, ${stats.edges ?? 0} edges`);
|
|
27
|
+
if (stats.communities)
|
|
28
|
+
console.log(` Clusters: ${stats.communities}`);
|
|
29
|
+
if (stats.processes)
|
|
30
|
+
console.log(` Processes: ${stats.processes}`);
|
|
31
|
+
console.log('');
|
|
32
|
+
}
|
|
33
|
+
};
|
package/dist/cli/mcp.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Command
|
|
3
|
+
*
|
|
4
|
+
* Starts the MCP server in standalone mode.
|
|
5
|
+
* Loads all indexed repos from the global registry.
|
|
6
|
+
* No longer depends on cwd — works from any directory.
|
|
7
|
+
*/
|
|
8
|
+
import { startMCPServer } from '../mcp/server.js';
|
|
9
|
+
import { LocalBackend } from '../mcp/local/local-backend.js';
|
|
10
|
+
export const mcpCommand = async () => {
|
|
11
|
+
// Prevent unhandled errors from crashing the MCP server process.
|
|
12
|
+
// KuzuDB lock conflicts and transient errors should degrade gracefully.
|
|
13
|
+
process.on('uncaughtException', (err) => {
|
|
14
|
+
console.error(`GitNexus MCP: uncaught exception — ${err.message}`);
|
|
15
|
+
});
|
|
16
|
+
process.on('unhandledRejection', (reason) => {
|
|
17
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
18
|
+
console.error(`GitNexus MCP: unhandled rejection — ${msg}`);
|
|
19
|
+
});
|
|
20
|
+
// Initialize multi-repo backend from registry.
|
|
21
|
+
// The server starts even with 0 repos — tools call refreshRepos() lazily,
|
|
22
|
+
// so repos indexed after the server starts are discovered automatically.
|
|
23
|
+
const backend = new LocalBackend();
|
|
24
|
+
await backend.init();
|
|
25
|
+
const repos = await backend.listRepos();
|
|
26
|
+
if (repos.length === 0) {
|
|
27
|
+
console.error('GitNexus: No indexed repos yet. Run `gitnexus analyze` in a git repo — the server will pick it up automatically.');
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.error(`GitNexus: MCP server starting with ${repos.length} repo(s): ${repos.map(r => r.name).join(', ')}`);
|
|
31
|
+
}
|
|
32
|
+
// Start MCP server (serves all repos, discovers new ones lazily)
|
|
33
|
+
await startMCPServer(backend);
|
|
34
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { readRegistry, registerRepo } from '../storage/repo-manager.js';
|
|
7
|
+
function makeMeta(repoPath, lastCommit) {
|
|
8
|
+
return {
|
|
9
|
+
repoPath,
|
|
10
|
+
lastCommit,
|
|
11
|
+
indexedAt: '2026-03-02T00:00:00.000Z',
|
|
12
|
+
stats: { files: 10, nodes: 20, edges: 30 },
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
test('registerRepo stores alias and rejects collisions on different paths', async () => {
|
|
16
|
+
const tmpHome = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-home-'));
|
|
17
|
+
const originalHome = process.env.GITNEXUS_HOME;
|
|
18
|
+
process.env.GITNEXUS_HOME = tmpHome;
|
|
19
|
+
try {
|
|
20
|
+
const repoA = path.join(tmpHome, 'repo-a');
|
|
21
|
+
const repoB = path.join(tmpHome, 'repo-b');
|
|
22
|
+
await fs.mkdir(repoA, { recursive: true });
|
|
23
|
+
await fs.mkdir(repoB, { recursive: true });
|
|
24
|
+
await registerRepo(repoA, makeMeta(repoA, 'abc1234'), { repoAlias: 'neonspark-v1-subset' });
|
|
25
|
+
const entries = await readRegistry();
|
|
26
|
+
assert.equal(entries.length, 1);
|
|
27
|
+
assert.equal(entries[0].name, 'neonspark-v1-subset');
|
|
28
|
+
assert.equal(entries[0].alias, 'neonspark-v1-subset');
|
|
29
|
+
assert.equal(entries[0].sourceName, 'repo-a');
|
|
30
|
+
await assert.rejects(registerRepo(repoB, makeMeta(repoB, 'def5678'), { repoAlias: 'neonspark-v1-subset' }), /already registered/i);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
if (originalHome === undefined) {
|
|
34
|
+
delete process.env.GITNEXUS_HOME;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
process.env.GITNEXUS_HOME = originalHome;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { parseScopeRules, pathMatchesScopeRules, selectEntriesByScopeRules } from '../core/ingestion/scope-filter.js';
|
|
4
|
+
test('parseScopeRules ignores comments and blank lines', () => {
|
|
5
|
+
const rules = parseScopeRules(`
|
|
6
|
+
# comment
|
|
7
|
+
Assets/NEON/Code
|
|
8
|
+
|
|
9
|
+
Packages/com.veewo.*
|
|
10
|
+
Packages/com.neonspark.*
|
|
11
|
+
`);
|
|
12
|
+
assert.deepEqual(rules, [
|
|
13
|
+
'Assets/NEON/Code',
|
|
14
|
+
'Packages/com.veewo.*',
|
|
15
|
+
'Packages/com.neonspark.*',
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
test('pathMatchesScopeRules supports wildcard and descendant semantics', () => {
|
|
19
|
+
const rules = ['Assets/NEON/Code', 'Packages/com.veewo.*'];
|
|
20
|
+
assert.equal(pathMatchesScopeRules('Assets/NEON/Code/Game/A.cs', rules), true);
|
|
21
|
+
assert.equal(pathMatchesScopeRules('Assets/NEON/Code', rules), true);
|
|
22
|
+
assert.equal(pathMatchesScopeRules('Packages/com.veewo.stat/Runtime/Stat.cs', rules), true);
|
|
23
|
+
assert.equal(pathMatchesScopeRules('Packages/com.unity.inputsystem/Runtime/X.cs', rules), false);
|
|
24
|
+
});
|
|
25
|
+
test('selectEntriesByScopeRules reports overlap dedupe and normalized path collisions', () => {
|
|
26
|
+
const entries = [
|
|
27
|
+
{ path: 'Assets/NEON/Code/Game/A.cs' },
|
|
28
|
+
{ path: 'Packages/com.veewo.stat/Runtime/Stat.cs' },
|
|
29
|
+
{ path: 'Packages\\com.veewo.stat\\Runtime\\Stat.cs' },
|
|
30
|
+
{ path: 'Packages/com.unity.inputsystem/Runtime/X.cs' },
|
|
31
|
+
];
|
|
32
|
+
const result = selectEntriesByScopeRules(entries, [
|
|
33
|
+
'Assets/NEON/Code',
|
|
34
|
+
'Assets/NEON/*',
|
|
35
|
+
'Packages/com.veewo.*',
|
|
36
|
+
]);
|
|
37
|
+
assert.equal(result.selected.length, 3);
|
|
38
|
+
assert.equal(result.diagnostics.appliedRuleCount, 3);
|
|
39
|
+
assert.equal(result.diagnostics.overlapFiles, 1);
|
|
40
|
+
assert.equal(result.diagnostics.dedupedMatchCount, 1);
|
|
41
|
+
assert.equal(result.diagnostics.normalizedCollisions.length, 1);
|
|
42
|
+
assert.deepEqual(result.diagnostics.normalizedCollisions[0], {
|
|
43
|
+
normalizedPath: 'Packages/com.veewo.stat/Runtime/Stat.cs',
|
|
44
|
+
paths: [
|
|
45
|
+
'Packages/com.veewo.stat/Runtime/Stat.cs',
|
|
46
|
+
'Packages\\com.veewo.stat\\Runtime\\Stat.cs',
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup Command
|
|
3
|
+
*
|
|
4
|
+
* One-time global MCP configuration writer.
|
|
5
|
+
* Detects installed AI editors and writes the appropriate MCP config
|
|
6
|
+
* so the GitNexus MCP server is available in all projects.
|
|
7
|
+
*/
|
|
8
|
+
export declare const setupCommand: () => Promise<void>;
|