purecontext-mcp 1.2.0 → 1.5.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/AGENT_INSTRUCTIONS.md +110 -784
- package/AGENT_REFERENCE.md +561 -0
- package/CHANGELOG.md +177 -6
- package/FRAMEWORK-ADAPTERS.md +351 -0
- package/LANGUAGE-SUPPORT.md +144 -0
- package/README.md +92 -12
- package/USER-GUIDE.md +8 -0
- package/dist/cli/hooks.d.ts +28 -0
- package/dist/cli/hooks.d.ts.map +1 -0
- package/dist/cli/hooks.js +570 -0
- package/dist/cli/hooks.js.map +1 -0
- package/dist/cli/install-detect.d.ts +16 -0
- package/dist/cli/install-detect.d.ts.map +1 -0
- package/dist/cli/install-detect.js +70 -0
- package/dist/cli/install-detect.js.map +1 -0
- package/dist/cli/install-writers.d.ts +59 -0
- package/dist/cli/install-writers.d.ts.map +1 -0
- package/dist/cli/install-writers.js +292 -0
- package/dist/cli/install-writers.js.map +1 -0
- package/dist/cli/install.d.ts +14 -0
- package/dist/cli/install.d.ts.map +1 -0
- package/dist/cli/install.js +150 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/config/config-loader.js +3 -0
- package/dist/config/config-loader.js.map +1 -1
- package/dist/config/config-schema.d.ts +11 -0
- package/dist/config/config-schema.d.ts.map +1 -1
- package/dist/config/config-schema.js +15 -0
- package/dist/config/config-schema.js.map +1 -1
- package/dist/core/db/symbol-store.d.ts +1 -0
- package/dist/core/db/symbol-store.d.ts.map +1 -1
- package/dist/core/db/symbol-store.js +120 -6
- package/dist/core/db/symbol-store.js.map +1 -1
- package/dist/core/file-discovery.d.ts +6 -0
- package/dist/core/file-discovery.d.ts.map +1 -1
- package/dist/core/file-discovery.js +20 -13
- package/dist/core/file-discovery.js.map +1 -1
- package/dist/core/file-processor.d.ts.map +1 -1
- package/dist/core/file-processor.js +26 -1
- package/dist/core/file-processor.js.map +1 -1
- package/dist/core/git-log-reader.d.ts.map +1 -1
- package/dist/core/git-log-reader.js +21 -0
- package/dist/core/git-log-reader.js.map +1 -1
- package/dist/core/index-manager.d.ts.map +1 -1
- package/dist/core/index-manager.js +21 -7
- package/dist/core/index-manager.js.map +1 -1
- package/dist/core/indexing-worker.d.ts.map +1 -1
- package/dist/core/indexing-worker.js +14 -0
- package/dist/core/indexing-worker.js.map +1 -1
- package/dist/core/parse-dispatcher.d.ts.map +1 -1
- package/dist/core/parse-dispatcher.js +20 -5
- package/dist/core/parse-dispatcher.js.map +1 -1
- package/dist/core/search/query-preprocessor.d.ts +69 -3
- package/dist/core/search/query-preprocessor.d.ts.map +1 -1
- package/dist/core/search/query-preprocessor.js +450 -17
- package/dist/core/search/query-preprocessor.js.map +1 -1
- package/dist/core/search/relevance-ranker.d.ts +60 -5
- package/dist/core/search/relevance-ranker.d.ts.map +1 -1
- package/dist/core/search/relevance-ranker.js +931 -33
- package/dist/core/search/relevance-ranker.js.map +1 -1
- package/dist/core/test-mapper.d.ts.map +1 -1
- package/dist/core/test-mapper.js +7 -1
- package/dist/core/test-mapper.js.map +1 -1
- package/dist/core/types.d.ts +28 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/handlers/angular-html.d.ts +3 -0
- package/dist/handlers/angular-html.d.ts.map +1 -0
- package/dist/handlers/angular-html.js +215 -0
- package/dist/handlers/angular-html.js.map +1 -0
- package/dist/handlers/c.d.ts.map +1 -1
- package/dist/handlers/c.js +19 -0
- package/dist/handlers/c.js.map +1 -1
- package/dist/handlers/cpp-macro-registry.d.ts +21 -0
- package/dist/handlers/cpp-macro-registry.d.ts.map +1 -0
- package/dist/handlers/cpp-macro-registry.js +44 -0
- package/dist/handlers/cpp-macro-registry.js.map +1 -0
- package/dist/handlers/cpp.d.ts.map +1 -1
- package/dist/handlers/cpp.js +579 -10
- package/dist/handlers/cpp.js.map +1 -1
- package/dist/handlers/csharp.d.ts.map +1 -1
- package/dist/handlers/csharp.js +39 -2
- package/dist/handlers/csharp.js.map +1 -1
- package/dist/handlers/css.d.ts +3 -0
- package/dist/handlers/css.d.ts.map +1 -0
- package/dist/handlers/css.js +154 -0
- package/dist/handlers/css.js.map +1 -0
- package/dist/handlers/erlang.d.ts.map +1 -1
- package/dist/handlers/erlang.js +8 -1
- package/dist/handlers/erlang.js.map +1 -1
- package/dist/handlers/fortran.js +1 -1
- package/dist/handlers/fortran.js.map +1 -1
- package/dist/handlers/go.d.ts.map +1 -1
- package/dist/handlers/go.js +87 -2
- package/dist/handlers/go.js.map +1 -1
- package/dist/handlers/handler-registry.d.ts.map +1 -1
- package/dist/handlers/handler-registry.js +4 -0
- package/dist/handlers/handler-registry.js.map +1 -1
- package/dist/handlers/hcl.d.ts +3 -0
- package/dist/handlers/hcl.d.ts.map +1 -0
- package/dist/handlers/hcl.js +193 -0
- package/dist/handlers/hcl.js.map +1 -0
- package/dist/handlers/java.d.ts.map +1 -1
- package/dist/handlers/java.js +33 -16
- package/dist/handlers/java.js.map +1 -1
- package/dist/handlers/kotlin.d.ts.map +1 -1
- package/dist/handlers/kotlin.js +48 -3
- package/dist/handlers/kotlin.js.map +1 -1
- package/dist/handlers/less.d.ts +3 -0
- package/dist/handlers/less.d.ts.map +1 -0
- package/dist/handlers/less.js +255 -0
- package/dist/handlers/less.js.map +1 -0
- package/dist/handlers/objective-c.d.ts.map +1 -1
- package/dist/handlers/objective-c.js +122 -64
- package/dist/handlers/objective-c.js.map +1 -1
- package/dist/handlers/openapi.d.ts.map +1 -1
- package/dist/handlers/openapi.js +30 -5
- package/dist/handlers/openapi.js.map +1 -1
- package/dist/handlers/php.d.ts.map +1 -1
- package/dist/handlers/php.js +287 -41
- package/dist/handlers/php.js.map +1 -1
- package/dist/handlers/protobuf.d.ts.map +1 -1
- package/dist/handlers/protobuf.js +1 -0
- package/dist/handlers/protobuf.js.map +1 -1
- package/dist/handlers/python.d.ts.map +1 -1
- package/dist/handlers/python.js +1 -3
- package/dist/handlers/python.js.map +1 -1
- package/dist/handlers/ruby-dsl.d.ts +23 -0
- package/dist/handlers/ruby-dsl.d.ts.map +1 -0
- package/dist/handlers/ruby-dsl.js +251 -0
- package/dist/handlers/ruby-dsl.js.map +1 -0
- package/dist/handlers/ruby.d.ts.map +1 -1
- package/dist/handlers/ruby.js +29 -4
- package/dist/handlers/ruby.js.map +1 -1
- package/dist/handlers/rust.d.ts.map +1 -1
- package/dist/handlers/rust.js +98 -2
- package/dist/handlers/rust.js.map +1 -1
- package/dist/handlers/scss.d.ts +3 -0
- package/dist/handlers/scss.d.ts.map +1 -0
- package/dist/handlers/scss.js +290 -0
- package/dist/handlers/scss.js.map +1 -0
- package/dist/handlers/sql.d.ts.map +1 -1
- package/dist/handlers/sql.js +37 -18
- package/dist/handlers/sql.js.map +1 -1
- package/dist/handlers/typescript.d.ts.map +1 -1
- package/dist/handlers/typescript.js +65 -17
- package/dist/handlers/typescript.js.map +1 -1
- package/dist/handlers/xml.d.ts.map +1 -1
- package/dist/handlers/xml.js +35 -2
- package/dist/handlers/xml.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -1
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +10 -0
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/tools/detect-antipatterns.d.ts +1 -1
- package/dist/server/tools/get-architecture-snapshot.d.ts +1 -1
- package/dist/server/tools/get-entry-points.d.ts +1 -1
- package/dist/server/tools/get-lexical-scope-matches.d.ts +54 -0
- package/dist/server/tools/get-lexical-scope-matches.d.ts.map +1 -0
- package/dist/server/tools/get-lexical-scope-matches.js +470 -0
- package/dist/server/tools/get-lexical-scope-matches.js.map +1 -0
- package/dist/server/tools/search-symbols.d.ts +10 -0
- package/dist/server/tools/search-symbols.d.ts.map +1 -1
- package/dist/server/tools/search-symbols.js +353 -8
- package/dist/server/tools/search-symbols.js.map +1 -1
- package/dist/server/tools/trace-invocation-chain.d.ts +53 -0
- package/dist/server/tools/trace-invocation-chain.d.ts.map +1 -0
- package/dist/server/tools/trace-invocation-chain.js +280 -0
- package/dist/server/tools/trace-invocation-chain.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/02-installation.md +89 -17
- package/docs/05-cli-reference.md +89 -0
- package/docs/dev/benchmark-findings-eu-za-tebe.md +210 -0
- package/docs/dev/phase-35-coverage-audit.md +469 -0
- package/package.json +4 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* trace-invocation-chain.ts
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: trace_invocation_chain
|
|
5
|
+
*
|
|
6
|
+
* Trace multi-hop call chains from a start symbol forward through callees,
|
|
7
|
+
* returning all discovered paths as ordered symbol lists. Useful for questions
|
|
8
|
+
* like "what execution path leads from this API endpoint to a background worker?"
|
|
9
|
+
*
|
|
10
|
+
* Strategy: query-time text scan (same as get_call_hierarchy) — no pre-built
|
|
11
|
+
* call edges required. Scans symbol source text for `identifier(` patterns and
|
|
12
|
+
* matches them against all indexed symbols in the repo.
|
|
13
|
+
*
|
|
14
|
+
* Cycle detection: back-edges are included as leaf nodes with `cyclic: true`
|
|
15
|
+
* so the traversal terminates and the caller can see the cycle.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import { openDatabase, getRepo } from '../../core/db/schema.js';
|
|
19
|
+
import { getSymbolsByRepo } from '../../core/db/symbol-store.js';
|
|
20
|
+
import { getFileContent } from '../../core/db/file-store.js';
|
|
21
|
+
import { buildMeta } from './_meta.js';
|
|
22
|
+
export const name = 'trace_invocation_chain';
|
|
23
|
+
export const description = 'Trace all call chains from a start symbol forward through its callees, ' +
|
|
24
|
+
'returning each discovered path as an ordered list of symbols. ' +
|
|
25
|
+
'Use endHint to truncate chains at a symbol matching a glob pattern ' +
|
|
26
|
+
'(e.g. "*Worker", "*Service"). ' +
|
|
27
|
+
'Cycles are detected and annotated with cyclic=true rather than looping. ' +
|
|
28
|
+
'Useful for multi-hop traces like "route handler → service → background worker". ' +
|
|
29
|
+
'Use search_symbols to find the symbolId or name of the start symbol first.';
|
|
30
|
+
export const inputSchema = {
|
|
31
|
+
repoId: z.string().describe('Repository ID returned by index_folder or list_repos'),
|
|
32
|
+
startSymbol: z
|
|
33
|
+
.string()
|
|
34
|
+
.min(1)
|
|
35
|
+
.describe('Name (or symbolId) of the entry point symbol to start tracing from. ' +
|
|
36
|
+
'If multiple symbols share the name, all are used as starting points.'),
|
|
37
|
+
endHint: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Glob-style pattern for terminal symbols (e.g. "*Worker", "*Job", "Background*"). ' +
|
|
41
|
+
'Chains stop when a symbol matching this pattern is found, even before maxDepth. ' +
|
|
42
|
+
'Supports * as wildcard. When omitted, chains end at leaves (no further callees).'),
|
|
43
|
+
maxDepth: z
|
|
44
|
+
.number()
|
|
45
|
+
.int()
|
|
46
|
+
.min(1)
|
|
47
|
+
.max(10)
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Maximum chain depth (default 6)'),
|
|
50
|
+
maxChains: z
|
|
51
|
+
.number()
|
|
52
|
+
.int()
|
|
53
|
+
.min(1)
|
|
54
|
+
.max(200)
|
|
55
|
+
.optional()
|
|
56
|
+
.describe('Maximum number of chains to return (default 50)'),
|
|
57
|
+
includeDynamicCalls: z
|
|
58
|
+
.boolean()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('When true, include symbols tagged with frameworkMeta.dynamicDispatch=true ' +
|
|
61
|
+
'(e.g. method_missing handlers) as potential callees. Default false.'),
|
|
62
|
+
};
|
|
63
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
64
|
+
// Keywords that match `\bword(` but are not function calls.
|
|
65
|
+
const CALL_SKIP = new Set([
|
|
66
|
+
'if', 'else', 'for', 'while', 'do', 'switch', 'case', 'catch',
|
|
67
|
+
'finally', 'try', 'new', 'return', 'throw', 'typeof', 'instanceof',
|
|
68
|
+
'function', 'class', 'import', 'export', 'const', 'let', 'var',
|
|
69
|
+
'async', 'await', 'yield', 'delete', 'void', 'in', 'of', 'super',
|
|
70
|
+
'this', 'true', 'false', 'null', 'undefined',
|
|
71
|
+
]);
|
|
72
|
+
/** Callable symbol kinds — only these are expanded as callee targets. */
|
|
73
|
+
const CALLABLE_KINDS = new Set([
|
|
74
|
+
'function', 'method', 'hook', 'composable', 'route', 'middleware',
|
|
75
|
+
]);
|
|
76
|
+
function extractCallNames(text) {
|
|
77
|
+
const names = new Set();
|
|
78
|
+
const re = /\b([A-Za-z_$][\w$]*)\s*\(/g;
|
|
79
|
+
let m;
|
|
80
|
+
while ((m = re.exec(text)) !== null) {
|
|
81
|
+
const n = m[1];
|
|
82
|
+
if (!CALL_SKIP.has(n))
|
|
83
|
+
names.add(n);
|
|
84
|
+
}
|
|
85
|
+
return names;
|
|
86
|
+
}
|
|
87
|
+
/** Glob-style match: only * as wildcard, anchored to full string. */
|
|
88
|
+
function globMatch(pattern, value) {
|
|
89
|
+
const escaped = pattern.replace(/[$()+.?[\\\]^{|}]/g, '\\$&').replace(/\*/g, '.*');
|
|
90
|
+
return new RegExp(`^${escaped}$`).test(value);
|
|
91
|
+
}
|
|
92
|
+
// ─── Handler ──────────────────────────────────────────────────────────────────
|
|
93
|
+
export async function handler(args) {
|
|
94
|
+
const t0 = Date.now();
|
|
95
|
+
const { repoId, startSymbol, endHint, maxDepth = 6, maxChains = 50, includeDynamicCalls = false, } = args;
|
|
96
|
+
const db = openDatabase(repoId);
|
|
97
|
+
try {
|
|
98
|
+
const repo = getRepo(db, repoId);
|
|
99
|
+
if (!repo) {
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: 'text',
|
|
104
|
+
text: JSON.stringify({ error: `Repository not found: ${repoId}` }),
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
isError: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// ── Load all symbols ─────────────────────────────────────────────────────
|
|
111
|
+
const allSymbols = getSymbolsByRepo(db, repoId, 1_000_000);
|
|
112
|
+
// Build name → SymbolRecord[] index (both full name and short name for methods)
|
|
113
|
+
const byName = new Map();
|
|
114
|
+
const byId = new Map();
|
|
115
|
+
for (const sym of allSymbols) {
|
|
116
|
+
byId.set(sym.id, sym);
|
|
117
|
+
const names = [sym.name];
|
|
118
|
+
if (sym.name.includes('.'))
|
|
119
|
+
names.push(sym.name.split('.').pop());
|
|
120
|
+
for (const n of names) {
|
|
121
|
+
const list = byName.get(n) ?? [];
|
|
122
|
+
list.push(sym);
|
|
123
|
+
byName.set(n, list);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// ── Resolve start symbol(s) ──────────────────────────────────────────────
|
|
127
|
+
// Support both name lookup and direct symbolId
|
|
128
|
+
let startSymbols;
|
|
129
|
+
if (byId.has(startSymbol)) {
|
|
130
|
+
startSymbols = [byId.get(startSymbol)];
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
startSymbols = byName.get(startSymbol) ?? [];
|
|
134
|
+
}
|
|
135
|
+
if (startSymbols.length === 0) {
|
|
136
|
+
return {
|
|
137
|
+
content: [
|
|
138
|
+
{
|
|
139
|
+
type: 'text',
|
|
140
|
+
text: JSON.stringify({
|
|
141
|
+
chains: [],
|
|
142
|
+
truncated: false,
|
|
143
|
+
error: `Symbol not found: ${startSymbol}`,
|
|
144
|
+
_meta: buildMeta({ timingMs: Date.now() - t0 }),
|
|
145
|
+
}),
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// ── File content cache ───────────────────────────────────────────────────
|
|
151
|
+
const fileCache = new Map();
|
|
152
|
+
function getContent(filePath) {
|
|
153
|
+
if (!fileCache.has(filePath)) {
|
|
154
|
+
fileCache.set(filePath, getFileContent(db, repoId, filePath));
|
|
155
|
+
}
|
|
156
|
+
return fileCache.get(filePath) ?? null;
|
|
157
|
+
}
|
|
158
|
+
function symbolText(sym) {
|
|
159
|
+
const buf = getContent(sym.filePath);
|
|
160
|
+
if (!buf)
|
|
161
|
+
return '';
|
|
162
|
+
return buf.slice(sym.startByte, Math.min(sym.endByte, buf.length)).toString('utf8');
|
|
163
|
+
}
|
|
164
|
+
/** Direct callees of a symbol (by text scan). */
|
|
165
|
+
function calleesOf(sym) {
|
|
166
|
+
const text = symbolText(sym);
|
|
167
|
+
const callNames = extractCallNames(text);
|
|
168
|
+
const seen = new Set();
|
|
169
|
+
const result = [];
|
|
170
|
+
for (const cname of callNames) {
|
|
171
|
+
const candidates = byName.get(cname) ?? [];
|
|
172
|
+
for (const cand of candidates) {
|
|
173
|
+
if (cand.id === sym.id)
|
|
174
|
+
continue;
|
|
175
|
+
if (!CALLABLE_KINDS.has(cand.kind))
|
|
176
|
+
continue;
|
|
177
|
+
if (!includeDynamicCalls) {
|
|
178
|
+
// Skip dynamic dispatch symbols unless explicitly included
|
|
179
|
+
const meta = cand.frameworkMeta;
|
|
180
|
+
if (meta?.['dynamicDispatch'] === true)
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (!seen.has(cand.id)) {
|
|
184
|
+
seen.add(cand.id);
|
|
185
|
+
result.push(cand);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
// ── DFS to collect chains ────────────────────────────────────────────────
|
|
192
|
+
const chains = [];
|
|
193
|
+
let overallTruncated = false;
|
|
194
|
+
function toChainNode(sym, cyclic = false) {
|
|
195
|
+
return {
|
|
196
|
+
symbolId: sym.id,
|
|
197
|
+
name: sym.name,
|
|
198
|
+
kind: sym.kind,
|
|
199
|
+
filePath: sym.filePath,
|
|
200
|
+
signature: sym.signature,
|
|
201
|
+
...(cyclic ? { cyclic: true } : {}),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function dfs(sym, currentPath, visitedInPath, depth) {
|
|
205
|
+
if (chains.length >= maxChains) {
|
|
206
|
+
overallTruncated = true;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
// Check if this symbol matches endHint
|
|
210
|
+
const matchesEnd = endHint ? globMatch(endHint, sym.name) : false;
|
|
211
|
+
if (matchesEnd) {
|
|
212
|
+
// Terminal: endHint matched
|
|
213
|
+
const nodes = [...currentPath.map((s) => toChainNode(s)), toChainNode(sym)];
|
|
214
|
+
chains.push({ nodes, truncatedByDepth: false, endedAtHint: true });
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (depth >= maxDepth) {
|
|
218
|
+
// Truncated by depth
|
|
219
|
+
const nodes = [...currentPath, sym].map((s) => toChainNode(s));
|
|
220
|
+
chains.push({ nodes, truncatedByDepth: true, endedAtHint: false });
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const callees = calleesOf(sym);
|
|
224
|
+
if (callees.length === 0) {
|
|
225
|
+
// Leaf node — emit chain
|
|
226
|
+
const nodes = [...currentPath, sym].map((s) => toChainNode(s));
|
|
227
|
+
chains.push({ nodes, truncatedByDepth: false, endedAtHint: false });
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// Expand callees
|
|
231
|
+
for (const callee of callees) {
|
|
232
|
+
if (chains.length >= maxChains) {
|
|
233
|
+
overallTruncated = true;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
if (visitedInPath.has(callee.id)) {
|
|
237
|
+
// Cycle detected — emit current path with cyclic leaf
|
|
238
|
+
const nodes = [
|
|
239
|
+
...currentPath.map((s) => toChainNode(s)),
|
|
240
|
+
toChainNode(sym),
|
|
241
|
+
toChainNode(callee, true),
|
|
242
|
+
];
|
|
243
|
+
chains.push({ nodes, truncatedByDepth: false, endedAtHint: false });
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
const nextPath = [...currentPath, sym];
|
|
247
|
+
const nextVisited = new Set(visitedInPath);
|
|
248
|
+
nextVisited.add(sym.id);
|
|
249
|
+
dfs(callee, nextPath, nextVisited, depth + 1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
for (const start of startSymbols) {
|
|
253
|
+
if (chains.length >= maxChains) {
|
|
254
|
+
overallTruncated = true;
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
dfs(start, [], new Set([start.id]), 0);
|
|
258
|
+
}
|
|
259
|
+
const tokenEstimate = Math.ceil(chains.reduce((sum, c) => sum + c.nodes.reduce((s, n) => s + n.name.length + n.filePath.length + 40, 0), 0) / 4);
|
|
260
|
+
return {
|
|
261
|
+
content: [
|
|
262
|
+
{
|
|
263
|
+
type: 'text',
|
|
264
|
+
text: JSON.stringify({
|
|
265
|
+
chains,
|
|
266
|
+
totalChains: chains.length,
|
|
267
|
+
truncated: overallTruncated,
|
|
268
|
+
startSymbol,
|
|
269
|
+
_tokenEstimate: tokenEstimate,
|
|
270
|
+
_meta: buildMeta({ timingMs: Date.now() - t0 }),
|
|
271
|
+
}, null, 2),
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
db.close();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=trace-invocation-chain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-invocation-chain.js","sourceRoot":"","sources":["../../../src/server/tools/trace-invocation-chain.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
1
|
+
export declare const VERSION = "1.5.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '1.
|
|
1
|
+
export const VERSION = '1.5.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/docs/02-installation.md
CHANGED
|
@@ -177,43 +177,115 @@ Your API key is issued by your team's PureContext administrator. See [Team Setup
|
|
|
177
177
|
|
|
178
178
|
Installing PureContext gives your AI agent access to the tools. Adding the agent instructions tells it *how* to use them efficiently — which tool to pick for each situation, in what order to call them, and what patterns to avoid.
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
Without them, an AI agent given access to PureContext may default to reading entire files (wasting tokens) rather than using `search_symbols`, or may not know to call `list_repos` first to get the `repoId` required by every tool. The instructions encode the correct workflow: check if indexed → search by name or meaning → retrieve source only for what you'll use.
|
|
181
|
+
|
|
182
|
+
### Recommended: `purecontext-mcp install`
|
|
183
|
+
|
|
184
|
+
PureContext ships with a multi-IDE installer that writes the workflow rules into the conventions file each tool expects. Run it once inside your project root:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
npx purecontext-mcp install all
|
|
188
|
+
```
|
|
181
189
|
|
|
182
|
-
|
|
190
|
+
This auto-detects which AI tools are configured in the project (by looking for marker files such as `.cursor/`, `.windsurfrules`, `CLAUDE.md`, `.continue/`, etc.) and installs the rules for each.
|
|
183
191
|
|
|
184
|
-
|
|
192
|
+
When no `--scope` flag is given, the CLI prompts you to choose where to install:
|
|
185
193
|
|
|
186
|
-
|
|
194
|
+
```
|
|
195
|
+
Where should PureContext be installed?
|
|
196
|
+
1) Local — this project only
|
|
197
|
+
2) Global — all projects (user-level config)
|
|
198
|
+
3) Both
|
|
199
|
+
```
|
|
187
200
|
|
|
188
|
-
|
|
201
|
+
Pass `--scope` to skip the prompt:
|
|
189
202
|
|
|
190
203
|
```bash
|
|
191
|
-
|
|
204
|
+
npx purecontext-mcp install all --scope=local # this project only
|
|
205
|
+
npx purecontext-mcp install all --scope=global # user-level, all projects
|
|
206
|
+
npx purecontext-mcp install all --scope=both # both places at once
|
|
192
207
|
```
|
|
193
208
|
|
|
194
|
-
|
|
209
|
+
For a single tool:
|
|
195
210
|
|
|
196
211
|
```bash
|
|
197
|
-
|
|
212
|
+
npx purecontext-mcp install cursor --scope=global
|
|
213
|
+
npx purecontext-mcp install windsurf
|
|
214
|
+
npx purecontext-mcp install continue
|
|
215
|
+
# ...etc.
|
|
198
216
|
```
|
|
199
217
|
|
|
200
|
-
|
|
218
|
+
Useful flags:
|
|
201
219
|
|
|
202
|
-
|
|
220
|
+
```bash
|
|
221
|
+
npx purecontext-mcp install --list # show detection state, write nothing
|
|
222
|
+
npx purecontext-mcp install all --dry-run # preview which writers would run
|
|
223
|
+
```
|
|
203
224
|
|
|
204
|
-
|
|
225
|
+
### Supported tools
|
|
205
226
|
|
|
206
|
-
|
|
227
|
+
| Tool | Local | Global | Notes |
|
|
228
|
+
|------|-------|--------|-------|
|
|
229
|
+
| `claude` | `CLAUDE.md` in project | `~/.claude/CLAUDE.md` + hooks | Global registers seven hook events — see [Claude Code hooks](#claude-code-hooks) below. |
|
|
230
|
+
| `cursor` | `.cursor/rules/purecontext.mdc` | `~/.cursor/rules/purecontext.mdc` | MDC frontmatter with `alwaysApply: true`. |
|
|
231
|
+
| `windsurf` | `.windsurfrules` | `~/.windsurfrules` | Marked block appended or replaced in place. |
|
|
232
|
+
| `continue` | `.continue/config.json` | `~/.continue/config.json` | JSON-aware merge; other fields are preserved. |
|
|
233
|
+
| `cline` | `.clinerules` | local only | No known global config path. |
|
|
234
|
+
| `roo-code` | `.roo/rules-code.md` | local only | No known global config path. |
|
|
235
|
+
| `vscode` | `.github/copilot-instructions.md` | local only | Picked up by GitHub Copilot in VS Code. |
|
|
236
|
+
| `claude-desktop` | always global | always global | Merges MCP server entry; leaves other servers untouched. |
|
|
207
237
|
|
|
208
|
-
|
|
238
|
+
### Claude Code hooks
|
|
209
239
|
|
|
210
|
-
|
|
240
|
+
When you run `npx purecontext-mcp install claude` (or the standalone `npx purecontext-mcp hooks --install`), PureContext registers seven hook events in `~/.claude/settings.json`. Each hook is a CLI-style command — no scripts are copied to `~/.claude/hooks/`; the hook logic lives inside the installed package and updates automatically when you upgrade.
|
|
211
241
|
|
|
212
|
-
|
|
242
|
+
| Hook event | Command | What it does |
|
|
243
|
+
|------------|---------|--------------|
|
|
244
|
+
| `PostToolUse` | `hook-posttooluse` | Re-indexes files modified by Edit/Write/MultiEdit |
|
|
245
|
+
| `PreToolUse` | `hook-pretooluse` | Soft edit guard — suggests read tools before editing unread files |
|
|
246
|
+
| `PreCompact` | `hook-precompact` | Injects the list of indexed repos before context is compacted |
|
|
247
|
+
| `WorktreeCreate` | `hook-worktree-create` | Auto-indexes a newly created agent worktree |
|
|
248
|
+
| `WorktreeRemove` | `hook-worktree-remove` | Fires when an agent worktree is removed (reserved for cleanup) |
|
|
249
|
+
| `TaskCompleted` | `hook-taskcompleted` | Post-task diagnostics: complexity hotspots, TODO count, suggested tools |
|
|
250
|
+
| `SubagentStart` | `hook-subagentstart` | Injects a condensed repo orientation for newly spawned subagents |
|
|
213
251
|
|
|
214
|
-
|
|
252
|
+
Running `hooks --install` more than once is safe. It replaces existing PureContext entries (including old `.mjs`-path style entries from versions prior to 1.8.0) while leaving other tools' hooks untouched.
|
|
215
253
|
|
|
216
|
-
|
|
254
|
+
To see the current registration status without making changes:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
npx purecontext-mcp hooks --list
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Idempotency
|
|
261
|
+
|
|
262
|
+
Every writer is safe to re-run. The Markdown writers wrap their content in HTML comment markers:
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<!-- purecontext-mcp-start -->
|
|
266
|
+
... PureContext workflow rules ...
|
|
267
|
+
<!-- purecontext-mcp-end -->
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
On re-run, the marked block is replaced in place. Anything outside the markers (your own rules, other tools' rules) is preserved. The JSON writers (`continue`, `claude-desktop`) parse and merge structurally rather than re-emitting the whole file.
|
|
271
|
+
|
|
272
|
+
### Manual install (if you'd rather paste)
|
|
273
|
+
|
|
274
|
+
The two source-of-truth files are at the repository root:
|
|
275
|
+
|
|
276
|
+
- **`AGENT_INSTRUCTIONS_SHORT.md`** — Compact (~2 KB). Mandatory first step, tool selection table, core rules, common usage patterns. Use for agents with limited system prompt space.
|
|
277
|
+
- **`AGENT_INSTRUCTIONS.md`** — Full (~15 KB). Adds parameter notes, every usage pattern, known limitations, decision trees, anti-patterns. Use for complex multi-step workflows.
|
|
278
|
+
|
|
279
|
+
To use these manually:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Claude Code
|
|
283
|
+
cat AGENT_INSTRUCTIONS_SHORT.md >> CLAUDE.md
|
|
284
|
+
|
|
285
|
+
# Cursor — paste into .cursorrules or via Cursor Settings → Rules
|
|
286
|
+
# Windsurf — paste into .windsurfrules or workspace memory
|
|
287
|
+
# Anything else — paste into whatever rule/memory config it supports
|
|
288
|
+
```
|
|
217
289
|
|
|
218
290
|
---
|
|
219
291
|
|
package/docs/05-cli-reference.md
CHANGED
|
@@ -37,6 +37,95 @@ purecontext-mcp config --check
|
|
|
37
37
|
purecontext-mcp config
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
### `install`
|
|
41
|
+
|
|
42
|
+
Write PureContext workflow rules into the conventions file each AI tool expects.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Auto-detect installed tools and install rules for all of them
|
|
46
|
+
npx purecontext-mcp install all
|
|
47
|
+
|
|
48
|
+
# Install for a specific tool
|
|
49
|
+
npx purecontext-mcp install cursor
|
|
50
|
+
npx purecontext-mcp install windsurf
|
|
51
|
+
npx purecontext-mcp install continue
|
|
52
|
+
npx purecontext-mcp install cline
|
|
53
|
+
npx purecontext-mcp install roo-code
|
|
54
|
+
npx purecontext-mcp install vscode
|
|
55
|
+
npx purecontext-mcp install claude
|
|
56
|
+
npx purecontext-mcp install claude-desktop
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When no `--scope` flag is given, the CLI prompts interactively:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
Where should PureContext be installed?
|
|
63
|
+
1) Local — this project only
|
|
64
|
+
2) Global — all projects (user-level config)
|
|
65
|
+
3) Both
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Pass `--scope` to skip the prompt:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx purecontext-mcp install all --scope=global # user-level for all IDEs
|
|
72
|
+
npx purecontext-mcp install cursor --scope=both # project + home dir
|
|
73
|
+
npx purecontext-mcp install all --scope=local # this project only
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Useful flags:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx purecontext-mcp install --list # show detection state, write nothing
|
|
80
|
+
npx purecontext-mcp install all --dry-run # preview which writers would run
|
|
81
|
+
npx purecontext-mcp install all --scope=global # install globally without prompt
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Scope behaviour per tool:**
|
|
85
|
+
|
|
86
|
+
| Tool | Local | Global |
|
|
87
|
+
|------|-------|--------|
|
|
88
|
+
| `claude` | `CLAUDE.md` in project | `~/.claude/CLAUDE.md` + hooks |
|
|
89
|
+
| `cursor` | `.cursor/rules/purecontext.mdc` | `~/.cursor/rules/purecontext.mdc` |
|
|
90
|
+
| `windsurf` | `.windsurfrules` | `~/.windsurfrules` |
|
|
91
|
+
| `continue` | `.continue/config.json` | `~/.continue/config.json` |
|
|
92
|
+
| `cline` | `.clinerules` | local only (no global path) |
|
|
93
|
+
| `roo-code` | `.roo/rules-code.md` | local only (no global path) |
|
|
94
|
+
| `vscode` | `.github/copilot-instructions.md` | local only (no global path) |
|
|
95
|
+
| `claude-desktop` | always global | always global |
|
|
96
|
+
|
|
97
|
+
All writers are idempotent: re-running updates the marked block in place without touching anything outside it.
|
|
98
|
+
|
|
99
|
+
### `hooks`
|
|
100
|
+
|
|
101
|
+
Install or inspect Claude Code hook registrations.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Register all PureContext hooks in ~/.claude/settings.json
|
|
105
|
+
npx purecontext-mcp hooks --install
|
|
106
|
+
|
|
107
|
+
# List current hook registration status
|
|
108
|
+
npx purecontext-mcp hooks --list
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Hooks are registered as CLI commands in `~/.claude/settings.json`. Re-running `--install` is safe — it replaces existing PureContext entries (including any old `.mjs`-path style entries from earlier versions) while leaving other tools' hooks untouched.
|
|
112
|
+
|
|
113
|
+
### `hook-*` (Claude Code hook handlers)
|
|
114
|
+
|
|
115
|
+
These are the hook handlers invoked by Claude Code. They are not meant to be called directly; they are registered by `hooks --install` and executed automatically by Claude Code as events fire.
|
|
116
|
+
|
|
117
|
+
| Command | Hook event | What it does |
|
|
118
|
+
|---------|-----------|--------------|
|
|
119
|
+
| `hook-posttooluse` | `PostToolUse` | Re-indexes files modified by Edit/Write/MultiEdit |
|
|
120
|
+
| `hook-pretooluse` | `PreToolUse` | Soft edit guard — suggests read tools before editing |
|
|
121
|
+
| `hook-precompact` | `PreCompact` | Injects the list of indexed repos before context compaction |
|
|
122
|
+
| `hook-worktree-create` | `WorktreeCreate` | Auto-indexes a newly created agent worktree |
|
|
123
|
+
| `hook-worktree-remove` | `WorktreeRemove` | Fires when an agent worktree is removed (no-op, reserved) |
|
|
124
|
+
| `hook-taskcompleted` | `TaskCompleted` | Post-task diagnostics: complexity hotspots, TODO count, tool suggestions |
|
|
125
|
+
| `hook-subagentstart` | `SubagentStart` | Injects condensed repo orientation for newly spawned subagents |
|
|
126
|
+
|
|
127
|
+
All handlers read from stdin (the JSON payload Claude Code sends) and write a `systemMessage` JSON object to stdout when they have context to inject. They always exit 0 and never block tool execution.
|
|
128
|
+
|
|
40
129
|
### `keys`
|
|
41
130
|
|
|
42
131
|
Manage API keys for hosted deployments.
|