@zuvia-software-solutions/code-mapper 1.4.0
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 +215 -0
- package/dist/cli/ai-context.d.ts +19 -0
- package/dist/cli/ai-context.js +168 -0
- package/dist/cli/analyze.d.ts +7 -0
- package/dist/cli/analyze.js +325 -0
- package/dist/cli/augment.d.ts +7 -0
- package/dist/cli/augment.js +27 -0
- package/dist/cli/clean.d.ts +5 -0
- package/dist/cli/clean.js +56 -0
- package/dist/cli/eval-server.d.ts +25 -0
- package/dist/cli/eval-server.js +365 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +102 -0
- package/dist/cli/lazy-action.d.ts +6 -0
- package/dist/cli/lazy-action.js +19 -0
- package/dist/cli/list.d.ts +2 -0
- package/dist/cli/list.js +27 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +35 -0
- package/dist/cli/refresh.d.ts +12 -0
- package/dist/cli/refresh.js +165 -0
- package/dist/cli/serve.d.ts +5 -0
- package/dist/cli/serve.js +8 -0
- package/dist/cli/setup.d.ts +6 -0
- package/dist/cli/setup.js +218 -0
- package/dist/cli/status.d.ts +2 -0
- package/dist/cli/status.js +33 -0
- package/dist/cli/tool.d.ts +28 -0
- package/dist/cli/tool.js +87 -0
- package/dist/config/ignore-service.d.ts +32 -0
- package/dist/config/ignore-service.js +282 -0
- package/dist/config/supported-languages.d.ts +23 -0
- package/dist/config/supported-languages.js +52 -0
- package/dist/core/augmentation/engine.d.ts +22 -0
- package/dist/core/augmentation/engine.js +232 -0
- package/dist/core/embeddings/embedder.d.ts +35 -0
- package/dist/core/embeddings/embedder.js +171 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +41 -0
- package/dist/core/embeddings/embedding-pipeline.js +402 -0
- package/dist/core/embeddings/index.d.ts +5 -0
- package/dist/core/embeddings/index.js +6 -0
- package/dist/core/embeddings/text-generator.d.ts +20 -0
- package/dist/core/embeddings/text-generator.js +159 -0
- package/dist/core/embeddings/types.d.ts +60 -0
- package/dist/core/embeddings/types.js +23 -0
- package/dist/core/graph/graph.d.ts +4 -0
- package/dist/core/graph/graph.js +65 -0
- package/dist/core/graph/types.d.ts +69 -0
- package/dist/core/graph/types.js +3 -0
- package/dist/core/incremental/child-process.d.ts +8 -0
- package/dist/core/incremental/child-process.js +649 -0
- package/dist/core/incremental/refresh-coordinator.d.ts +32 -0
- package/dist/core/incremental/refresh-coordinator.js +147 -0
- package/dist/core/incremental/types.d.ts +78 -0
- package/dist/core/incremental/types.js +153 -0
- package/dist/core/incremental/watcher.d.ts +63 -0
- package/dist/core/incremental/watcher.js +338 -0
- package/dist/core/ingestion/ast-cache.d.ts +12 -0
- package/dist/core/ingestion/ast-cache.js +34 -0
- package/dist/core/ingestion/call-processor.d.ts +34 -0
- package/dist/core/ingestion/call-processor.js +937 -0
- package/dist/core/ingestion/call-routing.d.ts +40 -0
- package/dist/core/ingestion/call-routing.js +97 -0
- package/dist/core/ingestion/cluster-enricher.d.ts +30 -0
- package/dist/core/ingestion/cluster-enricher.js +151 -0
- package/dist/core/ingestion/community-processor.d.ts +26 -0
- package/dist/core/ingestion/community-processor.js +272 -0
- package/dist/core/ingestion/constants.d.ts +5 -0
- package/dist/core/ingestion/constants.js +8 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +23 -0
- package/dist/core/ingestion/entry-point-scoring.js +317 -0
- package/dist/core/ingestion/export-detection.d.ts +11 -0
- package/dist/core/ingestion/export-detection.js +203 -0
- package/dist/core/ingestion/filesystem-walker.d.ts +18 -0
- package/dist/core/ingestion/filesystem-walker.js +64 -0
- package/dist/core/ingestion/framework-detection.d.ts +42 -0
- package/dist/core/ingestion/framework-detection.js +405 -0
- package/dist/core/ingestion/heritage-processor.d.ts +15 -0
- package/dist/core/ingestion/heritage-processor.js +237 -0
- package/dist/core/ingestion/import-processor.d.ts +31 -0
- package/dist/core/ingestion/import-processor.js +416 -0
- package/dist/core/ingestion/language-config.d.ts +32 -0
- package/dist/core/ingestion/language-config.js +161 -0
- package/dist/core/ingestion/mro-processor.d.ts +32 -0
- package/dist/core/ingestion/mro-processor.js +343 -0
- package/dist/core/ingestion/named-binding-extraction.d.ts +51 -0
- package/dist/core/ingestion/named-binding-extraction.js +343 -0
- package/dist/core/ingestion/parsing-processor.d.ts +20 -0
- package/dist/core/ingestion/parsing-processor.js +282 -0
- package/dist/core/ingestion/pipeline.d.ts +3 -0
- package/dist/core/ingestion/pipeline.js +416 -0
- package/dist/core/ingestion/process-processor.d.ts +42 -0
- package/dist/core/ingestion/process-processor.js +357 -0
- package/dist/core/ingestion/resolution-context.d.ts +40 -0
- package/dist/core/ingestion/resolution-context.js +171 -0
- package/dist/core/ingestion/resolvers/csharp.d.ts +10 -0
- package/dist/core/ingestion/resolvers/csharp.js +101 -0
- package/dist/core/ingestion/resolvers/go.d.ts +8 -0
- package/dist/core/ingestion/resolvers/go.js +33 -0
- package/dist/core/ingestion/resolvers/index.d.ts +14 -0
- package/dist/core/ingestion/resolvers/index.js +10 -0
- package/dist/core/ingestion/resolvers/jvm.d.ts +9 -0
- package/dist/core/ingestion/resolvers/jvm.js +74 -0
- package/dist/core/ingestion/resolvers/php.d.ts +7 -0
- package/dist/core/ingestion/resolvers/php.js +30 -0
- package/dist/core/ingestion/resolvers/ruby.d.ts +9 -0
- package/dist/core/ingestion/resolvers/ruby.js +13 -0
- package/dist/core/ingestion/resolvers/rust.d.ts +5 -0
- package/dist/core/ingestion/resolvers/rust.js +62 -0
- package/dist/core/ingestion/resolvers/standard.d.ts +16 -0
- package/dist/core/ingestion/resolvers/standard.js +144 -0
- package/dist/core/ingestion/resolvers/utils.d.ts +18 -0
- package/dist/core/ingestion/resolvers/utils.js +113 -0
- package/dist/core/ingestion/structure-processor.d.ts +4 -0
- package/dist/core/ingestion/structure-processor.js +39 -0
- package/dist/core/ingestion/symbol-table.d.ts +34 -0
- package/dist/core/ingestion/symbol-table.js +48 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +20 -0
- package/dist/core/ingestion/tree-sitter-queries.js +691 -0
- package/dist/core/ingestion/type-env.d.ts +52 -0
- package/dist/core/ingestion/type-env.js +349 -0
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +214 -0
- package/dist/core/ingestion/type-extractors/csharp.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/csharp.js +224 -0
- package/dist/core/ingestion/type-extractors/go.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/go.js +261 -0
- package/dist/core/ingestion/type-extractors/index.d.ts +20 -0
- package/dist/core/ingestion/type-extractors/index.js +30 -0
- package/dist/core/ingestion/type-extractors/jvm.d.ts +5 -0
- package/dist/core/ingestion/type-extractors/jvm.js +386 -0
- package/dist/core/ingestion/type-extractors/php.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/php.js +280 -0
- package/dist/core/ingestion/type-extractors/python.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/python.js +175 -0
- package/dist/core/ingestion/type-extractors/ruby.d.ts +12 -0
- package/dist/core/ingestion/type-extractors/ruby.js +218 -0
- package/dist/core/ingestion/type-extractors/rust.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/rust.js +290 -0
- package/dist/core/ingestion/type-extractors/shared.d.ts +81 -0
- package/dist/core/ingestion/type-extractors/shared.js +322 -0
- package/dist/core/ingestion/type-extractors/swift.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/swift.js +140 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +111 -0
- package/dist/core/ingestion/type-extractors/types.js +4 -0
- package/dist/core/ingestion/type-extractors/typescript.d.ts +4 -0
- package/dist/core/ingestion/type-extractors/typescript.js +227 -0
- package/dist/core/ingestion/utils.d.ts +73 -0
- package/dist/core/ingestion/utils.js +992 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +99 -0
- package/dist/core/ingestion/workers/parse-worker.js +1055 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +15 -0
- package/dist/core/ingestion/workers/worker-pool.js +123 -0
- package/dist/core/lbug/csv-generator.d.ts +28 -0
- package/dist/core/lbug/csv-generator.js +355 -0
- package/dist/core/lbug/lbug-adapter.d.ts +96 -0
- package/dist/core/lbug/lbug-adapter.js +753 -0
- package/dist/core/lbug/schema.d.ts +46 -0
- package/dist/core/lbug/schema.js +402 -0
- package/dist/core/search/bm25-index.d.ts +20 -0
- package/dist/core/search/bm25-index.js +123 -0
- package/dist/core/search/hybrid-search.d.ts +32 -0
- package/dist/core/search/hybrid-search.js +131 -0
- package/dist/core/search/query-cache.d.ts +18 -0
- package/dist/core/search/query-cache.js +47 -0
- package/dist/core/search/query-expansion.d.ts +19 -0
- package/dist/core/search/query-expansion.js +75 -0
- package/dist/core/search/reranker.d.ts +29 -0
- package/dist/core/search/reranker.js +122 -0
- package/dist/core/search/types.d.ts +154 -0
- package/dist/core/search/types.js +51 -0
- package/dist/core/semantic/tsgo-service.d.ts +67 -0
- package/dist/core/semantic/tsgo-service.js +355 -0
- package/dist/core/tree-sitter/parser-loader.d.ts +12 -0
- package/dist/core/tree-sitter/parser-loader.js +71 -0
- package/dist/lib/memory-guard.d.ts +35 -0
- package/dist/lib/memory-guard.js +70 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.js +6 -0
- package/dist/mcp/compatible-stdio-transport.d.ts +32 -0
- package/dist/mcp/compatible-stdio-transport.js +209 -0
- package/dist/mcp/core/embedder.d.ts +24 -0
- package/dist/mcp/core/embedder.js +168 -0
- package/dist/mcp/core/lbug-adapter.d.ts +29 -0
- package/dist/mcp/core/lbug-adapter.js +330 -0
- package/dist/mcp/local/local-backend.d.ts +188 -0
- package/dist/mcp/local/local-backend.js +2759 -0
- package/dist/mcp/resources.d.ts +22 -0
- package/dist/mcp/resources.js +379 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +217 -0
- package/dist/mcp/staleness.d.ts +10 -0
- package/dist/mcp/staleness.js +25 -0
- package/dist/mcp/tools.d.ts +21 -0
- package/dist/mcp/tools.js +202 -0
- package/dist/server/api.d.ts +5 -0
- package/dist/server/api.js +340 -0
- package/dist/server/mcp-http.d.ts +7 -0
- package/dist/server/mcp-http.js +95 -0
- package/dist/storage/git.d.ts +6 -0
- package/dist/storage/git.js +35 -0
- package/dist/storage/repo-manager.d.ts +87 -0
- package/dist/storage/repo-manager.js +249 -0
- package/dist/types/pipeline.d.ts +35 -0
- package/dist/types/pipeline.js +20 -0
- package/hooks/claude/code-mapper-hook.cjs +238 -0
- package/hooks/claude/pre-tool-use.sh +79 -0
- package/hooks/claude/session-start.sh +42 -0
- package/models/mlx-embedder.py +185 -0
- package/package.json +100 -0
- package/scripts/patch-tree-sitter-swift.cjs +74 -0
- package/vendor/leiden/index.cjs +355 -0
- package/vendor/leiden/utils.cjs +392 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
// code-mapper/src/cli/eval-server.ts
|
|
2
|
+
/**
|
|
3
|
+
* @file eval-server.ts
|
|
4
|
+
* @description Lightweight HTTP server for SWE-bench evaluation. Keeps LadybugDB warm in
|
|
5
|
+
* memory so tool calls from the agent are near-instant. Returns LLM-friendly text (not raw
|
|
6
|
+
* JSON) and appends next-step hints for productive tool chaining (query -> context -> impact)
|
|
7
|
+
*
|
|
8
|
+
* Architecture: Agent bash cmd -> curl localhost:PORT/tool/query -> eval-server -> LocalBackend -> format -> text
|
|
9
|
+
*
|
|
10
|
+
* API:
|
|
11
|
+
* POST /tool/:name - Call a tool; body is JSON arguments, returns formatted text
|
|
12
|
+
* GET /health - Health check; returns {"status":"ok","repos":[...]}
|
|
13
|
+
* POST /shutdown - Graceful shutdown
|
|
14
|
+
*/
|
|
15
|
+
import http from 'http';
|
|
16
|
+
import { LocalBackend } from '../mcp/local/local-backend.js';
|
|
17
|
+
// Text Formatters — convert structured JSON results into compact, LLM-friendly text
|
|
18
|
+
export function formatQueryResult(result) {
|
|
19
|
+
if (result.error)
|
|
20
|
+
return `Error: ${result.error}`;
|
|
21
|
+
const lines = [];
|
|
22
|
+
const processes = result.processes || [];
|
|
23
|
+
const symbols = result.process_symbols || [];
|
|
24
|
+
const defs = result.definitions || [];
|
|
25
|
+
if (processes.length === 0 && defs.length === 0) {
|
|
26
|
+
return 'No matching execution flows found. Try a different search term or use grep.';
|
|
27
|
+
}
|
|
28
|
+
lines.push(`Found ${processes.length} execution flow(s):\n`);
|
|
29
|
+
for (let i = 0; i < processes.length; i++) {
|
|
30
|
+
const p = processes[i];
|
|
31
|
+
lines.push(`${i + 1}. ${p.summary} (${p.step_count} steps, ${p.symbol_count} symbols)`);
|
|
32
|
+
// Show symbols belonging to this process
|
|
33
|
+
const procSymbols = symbols.filter((s) => s.process_id === p.id);
|
|
34
|
+
for (const s of procSymbols.slice(0, 6)) {
|
|
35
|
+
const loc = s.startLine ? `:${s.startLine}` : '';
|
|
36
|
+
lines.push(` ${s.type} ${s.name} → ${s.filePath}${loc}`);
|
|
37
|
+
}
|
|
38
|
+
if (procSymbols.length > 6) {
|
|
39
|
+
lines.push(` ... and ${procSymbols.length - 6} more`);
|
|
40
|
+
}
|
|
41
|
+
lines.push('');
|
|
42
|
+
}
|
|
43
|
+
if (defs.length > 0) {
|
|
44
|
+
lines.push(`Standalone definitions:`);
|
|
45
|
+
for (const d of defs.slice(0, 8)) {
|
|
46
|
+
lines.push(` ${d.type || 'Symbol'} ${d.name} → ${d.filePath || '?'}`);
|
|
47
|
+
}
|
|
48
|
+
if (defs.length > 8)
|
|
49
|
+
lines.push(` ... and ${defs.length - 8} more`);
|
|
50
|
+
}
|
|
51
|
+
return lines.join('\n').trim();
|
|
52
|
+
}
|
|
53
|
+
export function formatContextResult(result) {
|
|
54
|
+
if (result.error)
|
|
55
|
+
return `Error: ${result.error}`;
|
|
56
|
+
if (result.status === 'ambiguous') {
|
|
57
|
+
const lines = [`Multiple symbols named '${result.candidates?.[0]?.name || '?'}'. Disambiguate with file path:\n`];
|
|
58
|
+
for (const c of result.candidates || []) {
|
|
59
|
+
lines.push(` ${c.kind} ${c.name} → ${c.filePath}:${c.line || '?'} (uid: ${c.uid})`);
|
|
60
|
+
}
|
|
61
|
+
lines.push(`\nRe-run: code-mapper-context "${result.candidates?.[0]?.name}" "<file_path>"`);
|
|
62
|
+
return lines.join('\n');
|
|
63
|
+
}
|
|
64
|
+
const sym = result.symbol;
|
|
65
|
+
if (!sym)
|
|
66
|
+
return 'Symbol not found.';
|
|
67
|
+
const lines = [];
|
|
68
|
+
const loc = sym.startLine ? `:${sym.startLine}-${sym.endLine}` : '';
|
|
69
|
+
lines.push(`${sym.kind} ${sym.name} → ${sym.filePath}${loc}`);
|
|
70
|
+
lines.push('');
|
|
71
|
+
// Incoming refs (who calls/imports/extends this symbol)
|
|
72
|
+
const incoming = result.incoming || {};
|
|
73
|
+
const incomingCount = Object.values(incoming).reduce((sum, arr) => sum + arr.length, 0);
|
|
74
|
+
if (incomingCount > 0) {
|
|
75
|
+
lines.push(`Called/imported by (${incomingCount}):`);
|
|
76
|
+
for (const [relType, refs] of Object.entries(incoming)) {
|
|
77
|
+
for (const ref of refs.slice(0, 10)) {
|
|
78
|
+
lines.push(` ← [${relType}] ${ref.kind} ${ref.name} → ${ref.filePath}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
lines.push('');
|
|
82
|
+
}
|
|
83
|
+
// Outgoing refs (what this symbol calls/imports)
|
|
84
|
+
const outgoing = result.outgoing || {};
|
|
85
|
+
const outgoingCount = Object.values(outgoing).reduce((sum, arr) => sum + arr.length, 0);
|
|
86
|
+
if (outgoingCount > 0) {
|
|
87
|
+
lines.push(`Calls/imports (${outgoingCount}):`);
|
|
88
|
+
for (const [relType, refs] of Object.entries(outgoing)) {
|
|
89
|
+
for (const ref of refs.slice(0, 10)) {
|
|
90
|
+
lines.push(` → [${relType}] ${ref.kind} ${ref.name} → ${ref.filePath}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
lines.push('');
|
|
94
|
+
}
|
|
95
|
+
// Processes
|
|
96
|
+
const procs = result.processes || [];
|
|
97
|
+
if (procs.length > 0) {
|
|
98
|
+
lines.push(`Participates in ${procs.length} execution flow(s):`);
|
|
99
|
+
for (const p of procs) {
|
|
100
|
+
lines.push(` • ${p.name} (step ${p.step_index}/${p.step_count})`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (sym.content) {
|
|
104
|
+
lines.push('');
|
|
105
|
+
lines.push(`Source:`);
|
|
106
|
+
lines.push(sym.content);
|
|
107
|
+
}
|
|
108
|
+
return lines.join('\n').trim();
|
|
109
|
+
}
|
|
110
|
+
export function formatImpactResult(result) {
|
|
111
|
+
if (result.error)
|
|
112
|
+
return `Error: ${result.error}`;
|
|
113
|
+
const target = result.target;
|
|
114
|
+
const direction = result.direction;
|
|
115
|
+
const byDepth = result.byDepth || {};
|
|
116
|
+
const total = result.impactedCount || 0;
|
|
117
|
+
if (total === 0) {
|
|
118
|
+
return `${target?.name || '?'}: No ${direction} dependencies found. This symbol appears isolated.`;
|
|
119
|
+
}
|
|
120
|
+
const lines = [];
|
|
121
|
+
const dirLabel = direction === 'upstream' ? 'depends on this (will break if changed)' : 'this depends on';
|
|
122
|
+
lines.push(`Blast radius for ${target?.kind || ''} ${target?.name} (${direction}): ${total} symbol(s) ${dirLabel}\n`);
|
|
123
|
+
const depthLabels = {
|
|
124
|
+
1: 'WILL BREAK (direct)',
|
|
125
|
+
2: 'LIKELY AFFECTED (indirect)',
|
|
126
|
+
3: 'MAY NEED TESTING (transitive)',
|
|
127
|
+
};
|
|
128
|
+
for (const depth of [1, 2, 3]) {
|
|
129
|
+
const items = byDepth[depth];
|
|
130
|
+
if (!items || items.length === 0)
|
|
131
|
+
continue;
|
|
132
|
+
lines.push(`d=${depth}: ${depthLabels[depth] || ''} (${items.length})`);
|
|
133
|
+
for (const item of items.slice(0, 12)) {
|
|
134
|
+
const conf = item.confidence < 1 ? ` (conf: ${item.confidence})` : '';
|
|
135
|
+
lines.push(` ${item.type} ${item.name} → ${item.filePath} [${item.relationType}]${conf}`);
|
|
136
|
+
}
|
|
137
|
+
if (items.length > 12) {
|
|
138
|
+
lines.push(` ... and ${items.length - 12} more`);
|
|
139
|
+
}
|
|
140
|
+
lines.push('');
|
|
141
|
+
}
|
|
142
|
+
return lines.join('\n').trim();
|
|
143
|
+
}
|
|
144
|
+
export function formatCypherResult(result) {
|
|
145
|
+
if (result.error)
|
|
146
|
+
return `Error: ${result.error}`;
|
|
147
|
+
if (Array.isArray(result)) {
|
|
148
|
+
if (result.length === 0)
|
|
149
|
+
return 'Query returned 0 rows.';
|
|
150
|
+
// Format as a simple table
|
|
151
|
+
const keys = Object.keys(result[0]);
|
|
152
|
+
const lines = [`${result.length} row(s):\n`];
|
|
153
|
+
for (const row of result.slice(0, 30)) {
|
|
154
|
+
const parts = keys.map(k => `${k}: ${row[k]}`);
|
|
155
|
+
lines.push(` ${parts.join(' | ')}`);
|
|
156
|
+
}
|
|
157
|
+
if (result.length > 30) {
|
|
158
|
+
lines.push(` ... ${result.length - 30} more rows`);
|
|
159
|
+
}
|
|
160
|
+
return lines.join('\n');
|
|
161
|
+
}
|
|
162
|
+
return typeof result === 'string' ? result : JSON.stringify(result, null, 2);
|
|
163
|
+
}
|
|
164
|
+
export function formatDetectChangesResult(result) {
|
|
165
|
+
if (result.error)
|
|
166
|
+
return `Error: ${result.error}`;
|
|
167
|
+
const summary = result.summary || {};
|
|
168
|
+
const lines = [];
|
|
169
|
+
if (summary.changed_count === 0) {
|
|
170
|
+
return 'No changes detected.';
|
|
171
|
+
}
|
|
172
|
+
lines.push(`Changes: ${summary.changed_files || 0} files, ${summary.changed_count || 0} symbols`);
|
|
173
|
+
lines.push(`Affected processes: ${summary.affected_count || 0}`);
|
|
174
|
+
lines.push(`Risk level: ${summary.risk_level || 'unknown'}\n`);
|
|
175
|
+
const changed = result.changed_symbols || [];
|
|
176
|
+
if (changed.length > 0) {
|
|
177
|
+
lines.push(`Changed symbols:`);
|
|
178
|
+
for (const s of changed.slice(0, 15)) {
|
|
179
|
+
lines.push(` ${s.type} ${s.name} → ${s.filePath}`);
|
|
180
|
+
}
|
|
181
|
+
if (changed.length > 15)
|
|
182
|
+
lines.push(` ... and ${changed.length - 15} more`);
|
|
183
|
+
lines.push('');
|
|
184
|
+
}
|
|
185
|
+
const affected = result.affected_processes || [];
|
|
186
|
+
if (affected.length > 0) {
|
|
187
|
+
lines.push(`Affected execution flows:`);
|
|
188
|
+
for (const p of affected.slice(0, 10)) {
|
|
189
|
+
const steps = (p.changed_steps || []).map((s) => s.symbol).join(', ');
|
|
190
|
+
lines.push(` • ${p.name} (${p.step_count} steps) — changed: ${steps}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return lines.join('\n').trim();
|
|
194
|
+
}
|
|
195
|
+
export function formatListReposResult(result) {
|
|
196
|
+
if (!Array.isArray(result) || result.length === 0) {
|
|
197
|
+
return 'No indexed repositories.';
|
|
198
|
+
}
|
|
199
|
+
const lines = ['Indexed repositories:\n'];
|
|
200
|
+
for (const r of result) {
|
|
201
|
+
const stats = r.stats || {};
|
|
202
|
+
lines.push(` ${r.name} — ${stats.nodes || '?'} symbols, ${stats.edges || '?'} relationships, ${stats.processes || '?'} flows`);
|
|
203
|
+
lines.push(` Path: ${r.path}`);
|
|
204
|
+
lines.push(` Indexed: ${r.indexedAt}`);
|
|
205
|
+
}
|
|
206
|
+
return lines.join('\n');
|
|
207
|
+
}
|
|
208
|
+
/** Format a tool result as compact, LLM-friendly text */
|
|
209
|
+
function formatToolResult(toolName, result) {
|
|
210
|
+
switch (toolName) {
|
|
211
|
+
case 'query': return formatQueryResult(result);
|
|
212
|
+
case 'context': return formatContextResult(result);
|
|
213
|
+
case 'impact': return formatImpactResult(result);
|
|
214
|
+
case 'cypher': return formatCypherResult(result);
|
|
215
|
+
case 'detect_changes': return formatDetectChangesResult(result);
|
|
216
|
+
case 'list_repos': return formatListReposResult(result);
|
|
217
|
+
default: return typeof result === 'string' ? result : JSON.stringify(result, null, 2);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Next-step hints — guide the agent to the logical next tool call
|
|
221
|
+
// Critical for tool chaining: query -> context -> impact -> fix
|
|
222
|
+
function getNextStepHint(toolName) {
|
|
223
|
+
switch (toolName) {
|
|
224
|
+
case 'query':
|
|
225
|
+
return '\n---\nNext: Pick a symbol above and run code-mapper-context "<name>" to see all its callers, callees, and execution flows.';
|
|
226
|
+
case 'context':
|
|
227
|
+
return '\n---\nNext: To check what breaks if you change this, run code-mapper-impact "<name>" upstream';
|
|
228
|
+
case 'impact':
|
|
229
|
+
return '\n---\nNext: Review d=1 items first (WILL BREAK). Read the source with cat to understand the code, then make your fix.';
|
|
230
|
+
case 'cypher':
|
|
231
|
+
return '\n---\nNext: To explore a result symbol in depth, run code-mapper-context "<name>"';
|
|
232
|
+
case 'detect_changes':
|
|
233
|
+
return '\n---\nNext: Run code-mapper-context "<symbol>" on high-risk changed symbols to check their callers.';
|
|
234
|
+
default:
|
|
235
|
+
return '';
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Server
|
|
239
|
+
export async function evalServerCommand(options) {
|
|
240
|
+
const port = parseInt(options?.port || '4848');
|
|
241
|
+
const idleTimeoutSec = parseInt(options?.idleTimeout || '0');
|
|
242
|
+
const backend = new LocalBackend();
|
|
243
|
+
const ok = await backend.init();
|
|
244
|
+
if (!ok) {
|
|
245
|
+
console.error('Code Mapper eval-server: No indexed repositories found. Run: code-mapper analyze');
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
const repos = await backend.listRepos();
|
|
249
|
+
console.error(`Code Mapper eval-server: ${repos.length} repo(s) loaded: ${repos.map(r => r.name).join(', ')}`);
|
|
250
|
+
let idleTimer = null;
|
|
251
|
+
function resetIdleTimer() {
|
|
252
|
+
if (idleTimeoutSec <= 0)
|
|
253
|
+
return;
|
|
254
|
+
if (idleTimer)
|
|
255
|
+
clearTimeout(idleTimer);
|
|
256
|
+
idleTimer = setTimeout(async () => {
|
|
257
|
+
console.error('Code Mapper eval-server: Idle timeout reached, shutting down');
|
|
258
|
+
await backend.disconnect();
|
|
259
|
+
process.exit(0);
|
|
260
|
+
}, idleTimeoutSec * 1000);
|
|
261
|
+
}
|
|
262
|
+
const server = http.createServer(async (req, res) => {
|
|
263
|
+
resetIdleTimer();
|
|
264
|
+
try {
|
|
265
|
+
// GET /health
|
|
266
|
+
if (req.method === 'GET' && req.url === '/health') {
|
|
267
|
+
res.setHeader('Content-Type', 'application/json');
|
|
268
|
+
res.writeHead(200);
|
|
269
|
+
res.end(JSON.stringify({ status: 'ok', repos: repos.map(r => r.name) }));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
// POST /shutdown
|
|
273
|
+
if (req.method === 'POST' && req.url === '/shutdown') {
|
|
274
|
+
res.setHeader('Content-Type', 'application/json');
|
|
275
|
+
res.writeHead(200);
|
|
276
|
+
res.end(JSON.stringify({ status: 'shutting_down' }));
|
|
277
|
+
setTimeout(async () => {
|
|
278
|
+
await backend.disconnect();
|
|
279
|
+
server.close();
|
|
280
|
+
process.exit(0);
|
|
281
|
+
}, 100);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
// POST /tool/:name
|
|
285
|
+
const toolMatch = req.url?.match(/^\/tool\/(\w+)$/);
|
|
286
|
+
if (req.method === 'POST' && toolMatch) {
|
|
287
|
+
const toolName = toolMatch[1];
|
|
288
|
+
const body = await readBody(req);
|
|
289
|
+
let args = {};
|
|
290
|
+
if (body.trim()) {
|
|
291
|
+
try {
|
|
292
|
+
args = JSON.parse(body);
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
296
|
+
res.writeHead(400);
|
|
297
|
+
res.end('Error: Invalid JSON body');
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// Call tool, format result as text, append next-step hint for chaining
|
|
302
|
+
const result = await backend.callTool(toolName, args);
|
|
303
|
+
const formatted = formatToolResult(toolName, result);
|
|
304
|
+
const hint = getNextStepHint(toolName);
|
|
305
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
306
|
+
res.writeHead(200);
|
|
307
|
+
res.end(formatted + hint);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
// Not found
|
|
311
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
312
|
+
res.writeHead(404);
|
|
313
|
+
res.end('Not found. Use POST /tool/:name or GET /health');
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
317
|
+
res.writeHead(500);
|
|
318
|
+
res.end(`Error: ${err.message || 'Internal error'}`);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
server.listen(port, '127.0.0.1', () => {
|
|
322
|
+
console.error(`Code Mapper eval-server: listening on http://127.0.0.1:${port}`);
|
|
323
|
+
console.error(` POST /tool/query — search execution flows`);
|
|
324
|
+
console.error(` POST /tool/context — 360-degree symbol view`);
|
|
325
|
+
console.error(` POST /tool/impact — blast radius analysis`);
|
|
326
|
+
console.error(` POST /tool/cypher — raw Cypher query`);
|
|
327
|
+
console.error(` GET /health — health check`);
|
|
328
|
+
console.error(` POST /shutdown — graceful shutdown`);
|
|
329
|
+
if (idleTimeoutSec > 0) {
|
|
330
|
+
console.error(` Auto-shutdown after ${idleTimeoutSec}s idle`);
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
process.stdout.write(`CODE_MAPPER_EVAL_SERVER_READY:${port}\n`);
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
// stdout may be unavailable in some environments
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
resetIdleTimer();
|
|
340
|
+
const shutdown = async () => {
|
|
341
|
+
console.error('Code Mapper eval-server: shutting down...');
|
|
342
|
+
await backend.disconnect();
|
|
343
|
+
server.close();
|
|
344
|
+
process.exit(0);
|
|
345
|
+
};
|
|
346
|
+
process.on('SIGINT', shutdown);
|
|
347
|
+
process.on('SIGTERM', shutdown);
|
|
348
|
+
}
|
|
349
|
+
export const MAX_BODY_SIZE = 1024 * 1024; // 1 MB
|
|
350
|
+
function readBody(req) {
|
|
351
|
+
return new Promise((resolve, reject) => {
|
|
352
|
+
const chunks = [];
|
|
353
|
+
let totalSize = 0;
|
|
354
|
+
req.on('data', (chunk) => {
|
|
355
|
+
totalSize += chunk.length;
|
|
356
|
+
if (totalSize > MAX_BODY_SIZE) {
|
|
357
|
+
req.destroy(new Error('Request body too large (max 1MB)'));
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
chunks.push(chunk);
|
|
361
|
+
});
|
|
362
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
363
|
+
req.on('error', reject);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// code-mapper/src/cli/index.ts
|
|
3
|
+
/**
|
|
4
|
+
* @file CLI entry point — registers all commands via Commander
|
|
5
|
+
* @description Heap re-spawn removed; only analyze.ts needs the 8GB heap via ensureHeap()
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { createLazyAction } from './lazy-action.js';
|
|
10
|
+
const _require = createRequire(import.meta.url);
|
|
11
|
+
const pkg = _require('../../package.json');
|
|
12
|
+
const program = new Command();
|
|
13
|
+
program
|
|
14
|
+
.name('code-mapper')
|
|
15
|
+
.description('Code Mapper local CLI and MCP server')
|
|
16
|
+
.version(pkg.version);
|
|
17
|
+
program
|
|
18
|
+
.command('setup')
|
|
19
|
+
.description('One-time setup: configure MCP for Cursor, Claude Code, OpenCode')
|
|
20
|
+
.action(createLazyAction(() => import('./setup.js'), 'setupCommand'));
|
|
21
|
+
program
|
|
22
|
+
.command('analyze [path]')
|
|
23
|
+
.description('Index a repository (full analysis)')
|
|
24
|
+
.option('-f, --force', 'Force full re-index even if up to date')
|
|
25
|
+
.option('--embeddings', 'Enable embedding generation for semantic search (on by default)', true)
|
|
26
|
+
.option('--no-embeddings', 'Skip embedding generation')
|
|
27
|
+
.option('-v, --verbose', 'Enable verbose ingestion warnings (default: false)')
|
|
28
|
+
.addHelpText('after', '\nEnvironment variables:\n CODE_MAPPER_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .code-mapperignore)')
|
|
29
|
+
.action(createLazyAction(() => import('./analyze.js'), 'analyzeCommand'));
|
|
30
|
+
program
|
|
31
|
+
.command('serve')
|
|
32
|
+
.description('Start local HTTP server for web UI connection')
|
|
33
|
+
.option('-p, --port <port>', 'Port number', '4747')
|
|
34
|
+
.option('--host <host>', 'Bind address (default: 127.0.0.1, use 0.0.0.0 for remote access)')
|
|
35
|
+
.action(createLazyAction(() => import('./serve.js'), 'serveCommand'));
|
|
36
|
+
program
|
|
37
|
+
.command('mcp')
|
|
38
|
+
.description('Start MCP server (stdio) — serves all indexed repos')
|
|
39
|
+
.option('--tsgo', 'Enable tsgo semantic resolution for confidence-1.0 call edges')
|
|
40
|
+
.action(createLazyAction(() => import('./mcp.js'), 'mcpCommand'));
|
|
41
|
+
program
|
|
42
|
+
.command('list')
|
|
43
|
+
.description('List all indexed repositories')
|
|
44
|
+
.action(createLazyAction(() => import('./list.js'), 'listCommand'));
|
|
45
|
+
program
|
|
46
|
+
.command('status')
|
|
47
|
+
.description('Show index status for current repo')
|
|
48
|
+
.action(createLazyAction(() => import('./status.js'), 'statusCommand'));
|
|
49
|
+
program
|
|
50
|
+
.command('clean')
|
|
51
|
+
.description('Delete Code Mapper index for current repo')
|
|
52
|
+
.option('-f, --force', 'Skip confirmation prompt')
|
|
53
|
+
.option('--all', 'Clean all indexed repos')
|
|
54
|
+
.action(createLazyAction(() => import('./clean.js'), 'cleanCommand'));
|
|
55
|
+
program
|
|
56
|
+
.command('refresh')
|
|
57
|
+
.description('Incremental re-index: only update files changed since last commit')
|
|
58
|
+
.option('-s, --scope <scope>', 'What to refresh: committed (default), staged, unstaged', 'committed')
|
|
59
|
+
.action(createLazyAction(() => import('./refresh.js'), 'refreshCommand'));
|
|
60
|
+
program
|
|
61
|
+
.command('augment <pattern>')
|
|
62
|
+
.description('Augment a search pattern with knowledge graph context (used by hooks)')
|
|
63
|
+
.action(createLazyAction(() => import('./augment.js'), 'augmentCommand'));
|
|
64
|
+
// Direct tool commands — invoke LocalBackend directly (no MCP overhead)
|
|
65
|
+
program
|
|
66
|
+
.command('query <search_query>')
|
|
67
|
+
.description('Search the knowledge graph for execution flows related to a concept')
|
|
68
|
+
.option('-r, --repo <name>', 'Target repository (omit if only one indexed)')
|
|
69
|
+
.option('-c, --context <text>', 'Task context to improve ranking')
|
|
70
|
+
.option('-g, --goal <text>', 'What you want to find')
|
|
71
|
+
.option('-l, --limit <n>', 'Max processes to return (default: 5)')
|
|
72
|
+
.option('--content', 'Include full symbol source code')
|
|
73
|
+
.action(createLazyAction(() => import('./tool.js'), 'queryCommand'));
|
|
74
|
+
program
|
|
75
|
+
.command('context [name]')
|
|
76
|
+
.description('360-degree view of a code symbol: callers, callees, processes')
|
|
77
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
78
|
+
.option('-u, --uid <uid>', 'Direct symbol UID (zero-ambiguity lookup)')
|
|
79
|
+
.option('-f, --file <path>', 'File path to disambiguate common names')
|
|
80
|
+
.option('--content', 'Include full symbol source code')
|
|
81
|
+
.action(createLazyAction(() => import('./tool.js'), 'contextCommand'));
|
|
82
|
+
program
|
|
83
|
+
.command('impact <target>')
|
|
84
|
+
.description('Blast radius analysis: what breaks if you change a symbol')
|
|
85
|
+
.option('-d, --direction <dir>', 'upstream (dependants) or downstream (dependencies)', 'upstream')
|
|
86
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
87
|
+
.option('--depth <n>', 'Max relationship depth (default: 3)')
|
|
88
|
+
.option('--include-tests', 'Include test files in results')
|
|
89
|
+
.action(createLazyAction(() => import('./tool.js'), 'impactCommand'));
|
|
90
|
+
program
|
|
91
|
+
.command('cypher <query>')
|
|
92
|
+
.description('Execute raw Cypher query against the knowledge graph')
|
|
93
|
+
.option('-r, --repo <name>', 'Target repository')
|
|
94
|
+
.action(createLazyAction(() => import('./tool.js'), 'cypherCommand'));
|
|
95
|
+
// Eval server — persistent daemon for SWE-bench evaluation
|
|
96
|
+
program
|
|
97
|
+
.command('eval-server')
|
|
98
|
+
.description('Start lightweight HTTP server for fast tool calls during evaluation')
|
|
99
|
+
.option('-p, --port <port>', 'Port number', '4848')
|
|
100
|
+
.option('--idle-timeout <seconds>', 'Auto-shutdown after N seconds idle (0 = disabled)', '0')
|
|
101
|
+
.action(createLazyAction(() => import('./eval-server.js'), 'evalServerCommand'));
|
|
102
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file lazy-action.ts
|
|
3
|
+
* @description Creates a lazy-loaded CLI action that defers module import until invocation
|
|
4
|
+
* Generic constraints ensure the export name is a valid key of the module at compile time
|
|
5
|
+
*/
|
|
6
|
+
export declare function createLazyAction<TModule extends Record<string, unknown>, TKey extends string & keyof TModule>(loader: () => Promise<TModule>, exportName: TKey): (...args: unknown[]) => Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// code-mapper/src/cli/lazy-action.ts
|
|
2
|
+
/**
|
|
3
|
+
* @file lazy-action.ts
|
|
4
|
+
* @description Creates a lazy-loaded CLI action that defers module import until invocation
|
|
5
|
+
* Generic constraints ensure the export name is a valid key of the module at compile time
|
|
6
|
+
*/
|
|
7
|
+
function isCallable(value) {
|
|
8
|
+
return typeof value === 'function';
|
|
9
|
+
}
|
|
10
|
+
export function createLazyAction(loader, exportName) {
|
|
11
|
+
return async (...args) => {
|
|
12
|
+
const module = await loader();
|
|
13
|
+
const action = module[exportName];
|
|
14
|
+
if (!isCallable(action)) {
|
|
15
|
+
throw new Error(`Lazy action export not found: ${exportName}`);
|
|
16
|
+
}
|
|
17
|
+
await action(...args);
|
|
18
|
+
};
|
|
19
|
+
}
|
package/dist/cli/list.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// code-mapper/src/cli/list.ts
|
|
2
|
+
/** @file list.ts @description Shows all indexed repositories from the global registry */
|
|
3
|
+
import { listRegisteredRepos } from '../storage/repo-manager.js';
|
|
4
|
+
export const listCommand = async () => {
|
|
5
|
+
const entries = await listRegisteredRepos({ validate: true });
|
|
6
|
+
if (entries.length === 0) {
|
|
7
|
+
console.log('No indexed repositories found.');
|
|
8
|
+
console.log('Run `code-mapper analyze` in a git repo to index it.');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
console.log(`\n Indexed Repositories (${entries.length})\n`);
|
|
12
|
+
for (const entry of entries) {
|
|
13
|
+
const indexedDate = new Date(entry.indexedAt).toLocaleString();
|
|
14
|
+
const stats = entry.stats || {};
|
|
15
|
+
const commitShort = entry.lastCommit?.slice(0, 7) || 'unknown';
|
|
16
|
+
console.log(` ${entry.name}`);
|
|
17
|
+
console.log(` Path: ${entry.path}`);
|
|
18
|
+
console.log(` Indexed: ${indexedDate}`);
|
|
19
|
+
console.log(` Commit: ${commitShort}`);
|
|
20
|
+
console.log(` Stats: ${stats.files ?? 0} files, ${stats.nodes ?? 0} symbols, ${stats.edges ?? 0} edges`);
|
|
21
|
+
if (stats.communities)
|
|
22
|
+
console.log(` Clusters: ${stats.communities}`);
|
|
23
|
+
if (stats.processes)
|
|
24
|
+
console.log(` Processes: ${stats.processes}`);
|
|
25
|
+
console.log('');
|
|
26
|
+
}
|
|
27
|
+
};
|
package/dist/cli/mcp.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// code-mapper/src/cli/mcp.ts
|
|
2
|
+
/**
|
|
3
|
+
* @file mcp.ts
|
|
4
|
+
* @description Starts the MCP server in standalone mode. Loads all indexed repos from the
|
|
5
|
+
* global registry — works from any directory
|
|
6
|
+
*/
|
|
7
|
+
import { startMCPServer } from '../mcp/server.js';
|
|
8
|
+
import { LocalBackend } from '../mcp/local/local-backend.js';
|
|
9
|
+
export const mcpCommand = async (opts) => {
|
|
10
|
+
// Prevent unhandled errors from crashing the MCP server process
|
|
11
|
+
// LadybugDB lock conflicts and transient errors should degrade gracefully
|
|
12
|
+
process.on('uncaughtException', (err) => {
|
|
13
|
+
console.error(`Code Mapper MCP: uncaught exception — ${err.message}`);
|
|
14
|
+
// Process is in undefined state after uncaughtException — exit after flushing
|
|
15
|
+
setTimeout(() => process.exit(1), 100);
|
|
16
|
+
});
|
|
17
|
+
process.on('unhandledRejection', (reason) => {
|
|
18
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
19
|
+
console.error(`Code Mapper MCP: unhandled rejection — ${msg}`);
|
|
20
|
+
});
|
|
21
|
+
// Initialize multi-repo backend from registry
|
|
22
|
+
// Starts even with 0 repos — tools call refreshRepos() lazily,
|
|
23
|
+
// so repos indexed after server start are discovered automatically
|
|
24
|
+
const backend = new LocalBackend();
|
|
25
|
+
await backend.init({ tsgo: opts?.tsgo });
|
|
26
|
+
const repos = await backend.listRepos();
|
|
27
|
+
if (repos.length === 0) {
|
|
28
|
+
console.error('Code Mapper: No indexed repos yet. Run `code-mapper analyze` in a git repo — the server will pick it up automatically.');
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.error(`Code Mapper: MCP server starting with ${repos.length} repo(s): ${repos.map(r => r.name).join(', ')}`);
|
|
32
|
+
}
|
|
33
|
+
// Start MCP server (serves all repos, discovers new ones lazily)
|
|
34
|
+
await startMCPServer(backend);
|
|
35
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file refresh.ts
|
|
3
|
+
* @description CLI command for incremental refresh — re-indexes only files
|
|
4
|
+
* changed since the last commit. Reuses the same RefreshCoordinator + child
|
|
5
|
+
* process architecture as the MCP server's auto-refresh.
|
|
6
|
+
*
|
|
7
|
+
* Usage: code-mapper refresh [--scope unstaged|staged|committed]
|
|
8
|
+
*/
|
|
9
|
+
export interface RefreshOptions {
|
|
10
|
+
scope?: 'unstaged' | 'staged' | 'committed';
|
|
11
|
+
}
|
|
12
|
+
export declare const refreshCommand: (options?: RefreshOptions) => Promise<void>;
|