@orquentra/codebuddy 2.6.2 → 2.7.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/dist/{chunk-IBLJOHJL.js → chunk-3QGW53GD.js} +2 -2
- package/dist/{chunk-NERKZSSE.js → chunk-5EDGAZQN.js} +438 -68
- package/dist/chunk-5EDGAZQN.js.map +1 -0
- package/dist/{chunk-JFDRBPYF.js → chunk-6JCKMIQY.js} +2 -2
- package/dist/{chunk-2XDPKFUW.js → chunk-AK2UAE32.js} +46 -20
- package/dist/chunk-AK2UAE32.js.map +1 -0
- package/dist/{chunk-GDJH7XJC.js → chunk-AL6VBTNA.js} +77 -3
- package/dist/chunk-AL6VBTNA.js.map +1 -0
- package/dist/{chunk-QBDJXGG5.js → chunk-AQHPEJR6.js} +93 -22
- package/dist/chunk-AQHPEJR6.js.map +1 -0
- package/dist/{chunk-OWWCDRXW.js → chunk-BQM7FJ7D.js} +6 -6
- package/dist/chunk-BQM7FJ7D.js.map +1 -0
- package/dist/{chunk-XBJQKCLU.js → chunk-CAEPHLHC.js} +13 -9
- package/dist/chunk-CAEPHLHC.js.map +1 -0
- package/dist/chunk-CG5B3LYG.js +66 -0
- package/dist/chunk-CG5B3LYG.js.map +1 -0
- package/dist/{chunk-IHQM2ZDV.js → chunk-DFV2SK6C.js} +1 -1
- package/dist/{chunk-IHQM2ZDV.js.map → chunk-DFV2SK6C.js.map} +1 -1
- package/dist/{chunk-IMFUYEZA.js → chunk-EEUFU7KV.js} +81 -54
- package/dist/chunk-EEUFU7KV.js.map +1 -0
- package/dist/{chunk-5MQOE4J6.js → chunk-ESZXCZIN.js} +3 -3
- package/dist/{chunk-J2EAZ4MA.js → chunk-GKNYMNFM.js} +22 -25
- package/dist/chunk-GKNYMNFM.js.map +1 -0
- package/dist/{chunk-JPHJBCZB.js → chunk-HPOR6YXA.js} +3 -2
- package/dist/chunk-HPOR6YXA.js.map +1 -0
- package/dist/{chunk-S6VEG4S2.js → chunk-JUAFCLRB.js} +28 -5
- package/dist/chunk-JUAFCLRB.js.map +1 -0
- package/dist/{chunk-5KZY6OTG.js → chunk-KNR2P2UY.js} +33 -83
- package/dist/chunk-KNR2P2UY.js.map +1 -0
- package/dist/{chunk-B6CO63SQ.js → chunk-LCSBL5TT.js} +21 -9
- package/dist/chunk-LCSBL5TT.js.map +1 -0
- package/dist/{chunk-5FW3PMNP.js → chunk-MSUAVR3R.js} +76 -11
- package/dist/chunk-MSUAVR3R.js.map +1 -0
- package/dist/{chunk-RAJJSCIP.js → chunk-SFMIMLXR.js} +2 -2
- package/dist/chunk-TGFTKWOR.js +16 -0
- package/dist/chunk-TGFTKWOR.js.map +1 -0
- package/dist/chunk-TUR6YKEE.js +55 -0
- package/dist/chunk-TUR6YKEE.js.map +1 -0
- package/dist/chunk-Y7D7PUBE.js +321 -0
- package/dist/chunk-Y7D7PUBE.js.map +1 -0
- package/dist/{chunk-R7CD6EXS.js → chunk-YJIA2MFL.js} +572 -377
- package/dist/chunk-YJIA2MFL.js.map +1 -0
- package/dist/cli/index.js +5 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/{cloud-7WM3YLI4.js → cloud-LXZUR3U2.js} +3 -3
- package/dist/{codebuddy-B_pCaQrV.d.ts → codebuddy-DO7ZhoWn.d.ts} +15 -1
- package/dist/config-GEZFLXK6.js +12 -0
- package/dist/index.d.ts +46 -3
- package/dist/index.js +22 -19
- package/dist/langgraph/index.d.ts +1 -1
- package/dist/lean-command-CWJAVQ5G.js +18 -0
- package/dist/{local-5MZURLCZ.js → local-ST4WMRCG.js} +3 -3
- package/dist/{main-MTBQZGJV.js → main-AHNGHC4L.js} +213 -183
- package/dist/main-AHNGHC4L.js.map +1 -0
- package/dist/{memory-KIC5FJVW.js → memory-TGHVTBME.js} +9 -8
- package/dist/memory-TGHVTBME.js.map +1 -0
- package/dist/operations-7BTAAUHF.js +26 -0
- package/dist/pretool-command-3SXQSMAO.js +13 -0
- package/dist/{rerank-5QZ3PNUW.js → rerank-IQAEWLQR.js} +6 -5
- package/dist/rerank-IQAEWLQR.js.map +1 -0
- package/dist/{runtime-CUBOOPZO.js → runtime-E7JQZ2BZ.js} +14 -11
- package/dist/summaries-XV3JGGCC.js +20 -0
- package/dist/{zvec-MSRKT7IV.js → zvec-KP4KNB7Y.js} +10 -3
- package/package.json +1 -1
- package/src/db/migrations/0006_fact_idempotency_key.sql +2 -0
- package/src/db/migrations/meta/0006_snapshot.json +1258 -0
- package/src/db/migrations/meta/_journal.json +7 -0
- package/dist/chunk-2XDPKFUW.js.map +0 -1
- package/dist/chunk-5FW3PMNP.js.map +0 -1
- package/dist/chunk-5KZY6OTG.js.map +0 -1
- package/dist/chunk-B6CO63SQ.js.map +0 -1
- package/dist/chunk-GDJH7XJC.js.map +0 -1
- package/dist/chunk-IMFUYEZA.js.map +0 -1
- package/dist/chunk-J2EAZ4MA.js.map +0 -1
- package/dist/chunk-JPHJBCZB.js.map +0 -1
- package/dist/chunk-NERKZSSE.js.map +0 -1
- package/dist/chunk-OWWCDRXW.js.map +0 -1
- package/dist/chunk-PQK3GKZH.js +0 -98
- package/dist/chunk-PQK3GKZH.js.map +0 -1
- package/dist/chunk-QBDJXGG5.js.map +0 -1
- package/dist/chunk-R7CD6EXS.js.map +0 -1
- package/dist/chunk-S6VEG4S2.js.map +0 -1
- package/dist/chunk-XBJQKCLU.js.map +0 -1
- package/dist/config-DEVHUDIU.js +0 -11
- package/dist/lean-command-HTQCPH76.js +0 -15
- package/dist/main-MTBQZGJV.js.map +0 -1
- package/dist/memory-KIC5FJVW.js.map +0 -1
- package/dist/operations-POCHY3WR.js +0 -25
- package/dist/pretool-command-AX6JXP25.js +0 -10
- package/dist/rerank-5QZ3PNUW.js.map +0 -1
- package/dist/summaries-SB5L2TSW.js +0 -18
- /package/dist/{chunk-IBLJOHJL.js.map → chunk-3QGW53GD.js.map} +0 -0
- /package/dist/{chunk-JFDRBPYF.js.map → chunk-6JCKMIQY.js.map} +0 -0
- /package/dist/{chunk-5MQOE4J6.js.map → chunk-ESZXCZIN.js.map} +0 -0
- /package/dist/{chunk-RAJJSCIP.js.map → chunk-SFMIMLXR.js.map} +0 -0
- /package/dist/{cloud-7WM3YLI4.js.map → cloud-LXZUR3U2.js.map} +0 -0
- /package/dist/{config-DEVHUDIU.js.map → config-GEZFLXK6.js.map} +0 -0
- /package/dist/{lean-command-HTQCPH76.js.map → lean-command-CWJAVQ5G.js.map} +0 -0
- /package/dist/{local-5MZURLCZ.js.map → local-ST4WMRCG.js.map} +0 -0
- /package/dist/{operations-POCHY3WR.js.map → operations-7BTAAUHF.js.map} +0 -0
- /package/dist/{pretool-command-AX6JXP25.js.map → pretool-command-3SXQSMAO.js.map} +0 -0
- /package/dist/{runtime-CUBOOPZO.js.map → runtime-E7JQZ2BZ.js.map} +0 -0
- /package/dist/{summaries-SB5L2TSW.js.map → summaries-XV3JGGCC.js.map} +0 -0
- /package/dist/{zvec-MSRKT7IV.js.map → zvec-KP4KNB7Y.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readConfigFile
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KNR2P2UY.js";
|
|
4
4
|
|
|
5
5
|
// src/llm/config.ts
|
|
6
6
|
var BASE_URL = {
|
|
@@ -60,4 +60,4 @@ export {
|
|
|
60
60
|
resolveLlmConfig,
|
|
61
61
|
redactLlmKeys
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-SFMIMLXR.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/hooks/root.ts
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { dirname, join, resolve } from "path";
|
|
4
|
+
function hookRoot(cwd, env = process.env) {
|
|
5
|
+
if (env.CLAUDE_PROJECT_DIR) return resolve(env.CLAUDE_PROJECT_DIR);
|
|
6
|
+
const start = resolve(cwd ?? process.cwd());
|
|
7
|
+
for (let dir = start; ; dir = dirname(dir)) {
|
|
8
|
+
if (existsSync(join(dir, ".codebuddy", "config.json"))) return dir;
|
|
9
|
+
if (dirname(dir) === dir) return start;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
hookRoot
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=chunk-TGFTKWOR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/root.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\n/**\n * The project a hook acts on. Claude Code reports the session's *current*\n * directory as `cwd`, which follows `cd` in Bash, so it may be a subfolder;\n * memory written there would split off into a stray `.codebuddy/`. Use, in\n * order: CLAUDE_PROJECT_DIR (set by Claude Code for hooks), the nearest folder\n * at or above `cwd` holding `.codebuddy/config.json`, then `cwd` itself.\n */\nexport function hookRoot(cwd: string | undefined, env: NodeJS.ProcessEnv = process.env): string {\n if (env.CLAUDE_PROJECT_DIR) return resolve(env.CLAUDE_PROJECT_DIR);\n const start = resolve(cwd ?? process.cwd());\n for (let dir = start; ; dir = dirname(dir)) {\n if (existsSync(join(dir, \".codebuddy\", \"config.json\"))) return dir;\n if (dirname(dir) === dir) return start;\n }\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,SAAS,SAAS,MAAM,eAAe;AAShC,SAAS,SAAS,KAAyB,MAAyB,QAAQ,KAAa;AAC9F,MAAI,IAAI,mBAAoB,QAAO,QAAQ,IAAI,kBAAkB;AACjE,QAAM,QAAQ,QAAQ,OAAO,QAAQ,IAAI,CAAC;AAC1C,WAAS,MAAM,SAAS,MAAM,QAAQ,GAAG,GAAG;AAC1C,QAAI,WAAW,KAAK,KAAK,cAAc,aAAa,CAAC,EAAG,QAAO;AAC/D,QAAI,QAAQ,GAAG,MAAM,IAAK,QAAO;AAAA,EACnC;AACF;","names":[]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
writeAtomic
|
|
3
|
+
} from "./chunk-CG5B3LYG.js";
|
|
4
|
+
|
|
5
|
+
// src/tracing/log.ts
|
|
6
|
+
import { appendFile, mkdir, readFile, stat } from "fs/promises";
|
|
7
|
+
import { dirname, join } from "path";
|
|
8
|
+
var MAX_BYTES = 4 * 1024 * 1024;
|
|
9
|
+
function tracePath(repositoryRoot) {
|
|
10
|
+
return join(repositoryRoot, ".codebuddy", "cache", "traces.jsonl");
|
|
11
|
+
}
|
|
12
|
+
async function recordTrace(repositoryRoot, event) {
|
|
13
|
+
if (process.env.CODEBUDDY_TRACE === "0") return;
|
|
14
|
+
const path = tracePath(repositoryRoot);
|
|
15
|
+
try {
|
|
16
|
+
await mkdir(dirname(path), { recursive: true });
|
|
17
|
+
await appendFile(path, `${JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...event })}
|
|
18
|
+
`);
|
|
19
|
+
if ((await stat(path)).size > MAX_BYTES) {
|
|
20
|
+
const lines = (await readFile(path, "utf8")).split("\n").filter(Boolean);
|
|
21
|
+
await writeAtomic(path, `${lines.slice(Math.floor(lines.length / 2)).join("\n")}
|
|
22
|
+
`);
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function readTraces(repositoryRoot, limit = 2e3) {
|
|
28
|
+
let raw;
|
|
29
|
+
try {
|
|
30
|
+
raw = await readFile(tracePath(repositoryRoot), "utf8");
|
|
31
|
+
} catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
return parseTraceLines(raw).slice(-limit);
|
|
35
|
+
}
|
|
36
|
+
function parseTraceLines(raw) {
|
|
37
|
+
const events = [];
|
|
38
|
+
for (const line of raw.split("\n")) {
|
|
39
|
+
if (!line.trim()) continue;
|
|
40
|
+
try {
|
|
41
|
+
const event = JSON.parse(line);
|
|
42
|
+
if (typeof event.ts === "string" && typeof event.name === "string") events.push(event);
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return events;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
tracePath,
|
|
51
|
+
recordTrace,
|
|
52
|
+
readTraces,
|
|
53
|
+
parseTraceLines
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=chunk-TUR6YKEE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tracing/log.ts"],"sourcesContent":["import { appendFile, mkdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\n\n/**\n * Local usage traces for `codebuddy dashboard`: one JSON line per MCP tool\n * call, prompt recall, capture and sync, in `.codebuddy/cache/traces.jsonl`\n * (gitignored, never leaves the machine). Recording is best-effort: it never\n * throws and never blocks a tool or hook on failure. `CODEBUDDY_TRACE=0`\n * turns it off. Token counts are cl100k estimates of the payload text.\n */\n\nexport type TraceKind = \"tool\" | \"recall\" | \"capture\" | \"sync\" | \"guard\";\n\nexport type TraceEvent = {\n ts: string;\n kind: TraceKind;\n /** Tool name, or the hook step (`context`, `capture`, `sync`). */\n name: string;\n ms: number;\n ok: boolean;\n /** Estimated tokens the agent sent (tool arguments, prompt). */\n tokensIn?: number;\n /** Estimated tokens CodeBuddy returned or injected. */\n tokensOut?: number;\n session?: string;\n detail?: Record<string, string | number | boolean | string[]>;\n};\n\n/** Past this size the oldest half is dropped (~10k events). */\nconst MAX_BYTES = 4 * 1024 * 1024;\n\nexport function tracePath(repositoryRoot: string): string {\n return join(repositoryRoot, \".codebuddy\", \"cache\", \"traces.jsonl\");\n}\n\nexport async function recordTrace(\n repositoryRoot: string,\n event: Omit<TraceEvent, \"ts\"> & { ts?: string },\n): Promise<void> {\n if (process.env.CODEBUDDY_TRACE === \"0\") return;\n const path = tracePath(repositoryRoot);\n try {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, `${JSON.stringify({ ts: new Date().toISOString(), ...event })}\\n`);\n if ((await stat(path)).size > MAX_BYTES) {\n const lines = (await readFile(path, \"utf8\")).split(\"\\n\").filter(Boolean);\n // Atomic: a reader (the dashboard) never sees a half-written file.\n await writeAtomic(path, `${lines.slice(Math.floor(lines.length / 2)).join(\"\\n\")}\\n`);\n }\n } catch {\n // Tracing must never break a tool call or a hook.\n }\n}\n\n/** The newest `limit` events, oldest first. Malformed lines are skipped. */\nexport async function readTraces(repositoryRoot: string, limit = 2_000): Promise<TraceEvent[]> {\n let raw: string;\n try {\n raw = await readFile(tracePath(repositoryRoot), \"utf8\");\n } catch {\n return [];\n }\n return parseTraceLines(raw).slice(-limit);\n}\n\nexport function parseTraceLines(raw: string): TraceEvent[] {\n const events: TraceEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line) as TraceEvent;\n if (typeof event.ts === \"string\" && typeof event.name === \"string\") events.push(event);\n } catch {\n // A torn write from a concurrent hook process; skip it.\n }\n }\n return events;\n}\n"],"mappings":";;;;;AAAA,SAAS,YAAY,OAAO,UAAU,YAAY;AAClD,SAAS,SAAS,YAAY;AA6B9B,IAAM,YAAY,IAAI,OAAO;AAEtB,SAAS,UAAU,gBAAgC;AACxD,SAAO,KAAK,gBAAgB,cAAc,SAAS,cAAc;AACnE;AAEA,eAAsB,YACpB,gBACA,OACe;AACf,MAAI,QAAQ,IAAI,oBAAoB,IAAK;AACzC,QAAM,OAAO,UAAU,cAAc;AACrC,MAAI;AACF,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,WAAW,MAAM,GAAG,KAAK,UAAU,EAAE,KAAI,oBAAI,KAAK,GAAE,YAAY,GAAG,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AACxF,SAAK,MAAM,KAAK,IAAI,GAAG,OAAO,WAAW;AACvC,YAAM,SAAS,MAAM,SAAS,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,OAAO,OAAO;AAEvE,YAAM,YAAY,MAAM,GAAG,MAAM,MAAM,KAAK,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,IACrF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAGA,eAAsB,WAAW,gBAAwB,QAAQ,KAA8B;AAC7F,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,SAAS,UAAU,cAAc,GAAG,MAAM;AAAA,EACxD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,SAAO,gBAAgB,GAAG,EAAE,MAAM,CAAC,KAAK;AAC1C;AAEO,SAAS,gBAAgB,KAA2B;AACzD,QAAM,SAAuB,CAAC;AAC9B,aAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,UAAI,OAAO,MAAM,OAAO,YAAY,OAAO,MAAM,SAAS,SAAU,QAAO,KAAK,KAAK;AAAA,IACvF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
// src/indexer/python.ts
|
|
2
|
+
function pythonLogicalLines(content) {
|
|
3
|
+
const lines = content.split(/\r?\n/);
|
|
4
|
+
const result = [];
|
|
5
|
+
let current = null;
|
|
6
|
+
let parts = [];
|
|
7
|
+
const emit = (line) => {
|
|
8
|
+
line.text = parts.join(" ").trimStart();
|
|
9
|
+
parts = [];
|
|
10
|
+
result.push(line);
|
|
11
|
+
};
|
|
12
|
+
let quote = null;
|
|
13
|
+
let depth = 0;
|
|
14
|
+
let backslash = false;
|
|
15
|
+
for (let index = 0; index < lines.length; index++) {
|
|
16
|
+
const line = lines[index] ?? "";
|
|
17
|
+
if (!current) {
|
|
18
|
+
const trimmed = line.trim();
|
|
19
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
20
|
+
current = {
|
|
21
|
+
start: index,
|
|
22
|
+
end: index,
|
|
23
|
+
indent: line.length - line.trimStart().length,
|
|
24
|
+
text: ""
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
let code = "";
|
|
28
|
+
for (let at = 0; at < line.length; at++) {
|
|
29
|
+
const char = line[at] ?? "";
|
|
30
|
+
if (quote) {
|
|
31
|
+
code += char;
|
|
32
|
+
if (char === "\\") {
|
|
33
|
+
code += line[at + 1] ?? "";
|
|
34
|
+
at++;
|
|
35
|
+
} else if (line.startsWith(quote, at)) {
|
|
36
|
+
code += quote.slice(1);
|
|
37
|
+
at += quote.length - 1;
|
|
38
|
+
quote = null;
|
|
39
|
+
}
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (char === "#") break;
|
|
43
|
+
if (char === '"' || char === "'") {
|
|
44
|
+
quote = line.startsWith(char.repeat(3), at) ? char.repeat(3) : char;
|
|
45
|
+
code += quote;
|
|
46
|
+
at += quote.length - 1;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if ("([{".includes(char)) depth++;
|
|
50
|
+
else if (")]}".includes(char)) depth = Math.max(0, depth - 1);
|
|
51
|
+
code += char;
|
|
52
|
+
}
|
|
53
|
+
backslash = !quote && code.endsWith("\\");
|
|
54
|
+
if (quote && quote.length === 1 && !code.endsWith("\\")) quote = null;
|
|
55
|
+
const piece = (backslash ? code.slice(0, -1) : code).trimEnd();
|
|
56
|
+
if (piece.trim() !== "") parts.push(piece);
|
|
57
|
+
current.end = index;
|
|
58
|
+
if (!quote && depth === 0 && !backslash) {
|
|
59
|
+
emit(current);
|
|
60
|
+
current = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (current) emit(current);
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
var DEF = /^(?:async\s+)?def\s+([A-Za-z_]\w*)/;
|
|
67
|
+
var CLASS = /^class\s+([A-Za-z_]\w*)/;
|
|
68
|
+
var CONSTANT = /^([A-Z][A-Z0-9_]*)\s*(?::[^=]*)?=(?!=)/;
|
|
69
|
+
var SIGNATURE_MAX = 120;
|
|
70
|
+
function extractPythonSymbols(content, limit) {
|
|
71
|
+
const logical = pythonLogicalLines(content);
|
|
72
|
+
const symbols = [];
|
|
73
|
+
collect(logical, 0, logical.length, 0, null, symbols, limit);
|
|
74
|
+
return symbols.slice(0, limit);
|
|
75
|
+
}
|
|
76
|
+
function collect(logical, from, to, indent, className, symbols, limit) {
|
|
77
|
+
let decorator = null;
|
|
78
|
+
for (let index = from; index < to && symbols.length < limit; index++) {
|
|
79
|
+
const line = logical[index];
|
|
80
|
+
if (!line || line.indent !== indent) continue;
|
|
81
|
+
if (line.text.startsWith("@")) {
|
|
82
|
+
decorator ??= line.start;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const start = decorator ?? line.start;
|
|
86
|
+
decorator = null;
|
|
87
|
+
const def = DEF.exec(line.text);
|
|
88
|
+
const cls = def || className ? null : CLASS.exec(line.text);
|
|
89
|
+
const constant = def || cls || className ? null : CONSTANT.exec(line.text);
|
|
90
|
+
const name = def?.[1] ?? cls?.[1] ?? constant?.[1];
|
|
91
|
+
if (!name) continue;
|
|
92
|
+
const blockEnd = constant ? index + 1 : endOfBlock(logical, index);
|
|
93
|
+
const endLine = (logical[blockEnd - 1]?.end ?? line.end) + 1;
|
|
94
|
+
const head = constant ? line.text : header(line.text);
|
|
95
|
+
const exported = !(className ?? name).startsWith("_");
|
|
96
|
+
symbols.push({
|
|
97
|
+
name: className ? `${className}.${name}` : name,
|
|
98
|
+
kind: className ? "method" : def ? "function" : cls ? "class" : "const",
|
|
99
|
+
startLine: start + 1,
|
|
100
|
+
endLine,
|
|
101
|
+
signature: truncate(className ? `${className}: ${head}` : head),
|
|
102
|
+
exported
|
|
103
|
+
});
|
|
104
|
+
if (cls && className === null && blockEnd > index + 1) {
|
|
105
|
+
const bodyIndent = logical[index + 1]?.indent ?? 0;
|
|
106
|
+
if (bodyIndent > indent)
|
|
107
|
+
collect(logical, index + 1, blockEnd, bodyIndent, name, symbols, limit);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function endOfBlock(logical, index) {
|
|
112
|
+
const indent = logical[index]?.indent ?? 0;
|
|
113
|
+
for (let next = index + 1; next < logical.length; next++) {
|
|
114
|
+
if ((logical[next]?.indent ?? 0) <= indent) return next;
|
|
115
|
+
}
|
|
116
|
+
return logical.length;
|
|
117
|
+
}
|
|
118
|
+
function header(text) {
|
|
119
|
+
let depth = 0;
|
|
120
|
+
let quote = null;
|
|
121
|
+
for (let at = 0; at < text.length; at++) {
|
|
122
|
+
const char = text[at] ?? "";
|
|
123
|
+
if (quote) {
|
|
124
|
+
if (char === "\\") at++;
|
|
125
|
+
else if (char === quote) quote = null;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (char === '"' || char === "'") quote = char;
|
|
129
|
+
else if ("([{".includes(char)) depth++;
|
|
130
|
+
else if (")]}".includes(char)) depth--;
|
|
131
|
+
else if (char === ":" && depth === 0) return tidy(text.slice(0, at));
|
|
132
|
+
}
|
|
133
|
+
return tidy(text);
|
|
134
|
+
}
|
|
135
|
+
function tidy(text) {
|
|
136
|
+
return text.replace(/\s+/g, " ").replace(/([([{])\s+/g, "$1").replace(/,?\s*([)\]}])/g, "$1").trim();
|
|
137
|
+
}
|
|
138
|
+
function truncate(value) {
|
|
139
|
+
return value.length <= SIGNATURE_MAX ? value : `${value.slice(0, SIGNATURE_MAX - 1)}\u2026`;
|
|
140
|
+
}
|
|
141
|
+
function extractPythonImports(content) {
|
|
142
|
+
const imports = [];
|
|
143
|
+
for (const { text } of pythonLogicalLines(content)) {
|
|
144
|
+
for (const statement of text.split(";").map((part) => part.trim())) {
|
|
145
|
+
const plain = /^import\s+(.+)$/.exec(statement);
|
|
146
|
+
if (plain?.[1]) {
|
|
147
|
+
for (const part of plain[1].split(",")) {
|
|
148
|
+
const module = part.trim().split(/\s+as\s+/)[0]?.trim() ?? "";
|
|
149
|
+
if (/^[A-Za-z_][\w.]*$/.test(module)) imports.push({ level: 0, module, names: [] });
|
|
150
|
+
}
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const from = /^from\s+(\.*)\s*([A-Za-z_][\w.]*)?\s+import\s+(.+)$/.exec(statement);
|
|
154
|
+
if (!from) continue;
|
|
155
|
+
const names = (from[3] ?? "").replace(/[()]/g, " ").split(",").map(
|
|
156
|
+
(part) => part.trim().split(/\s+as\s+/)[0]?.trim() ?? ""
|
|
157
|
+
).filter((name) => /^[A-Za-z_]\w*$/.test(name));
|
|
158
|
+
imports.push({ level: from[1]?.length ?? 0, module: from[2] ?? "", names });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return imports;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/indexer/symbols.ts
|
|
165
|
+
import { extname } from "path";
|
|
166
|
+
var SYMBOL_CODE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py"]);
|
|
167
|
+
var HEADING_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx", ".rst"]);
|
|
168
|
+
var SIGNATURE_MAX2 = 120;
|
|
169
|
+
var SYMBOL_LIMIT = 100;
|
|
170
|
+
function supportsSymbols(path) {
|
|
171
|
+
const extension = extname(path).toLowerCase();
|
|
172
|
+
return SYMBOL_CODE_EXTENSIONS.has(extension) || HEADING_EXTENSIONS.has(extension);
|
|
173
|
+
}
|
|
174
|
+
var DECLARATION = /^(?<export>export\s+)?(?<default>default\s+)?(?<mods>(?:declare\s+|abstract\s+|async\s+)*)(?<kind>function\*?|class|interface|type|enum|const|let|var)\s+(?<name>[A-Za-z_$][\w$]*)/;
|
|
175
|
+
function extractSymbolTable(content, path = "") {
|
|
176
|
+
const extension = extname(path).toLowerCase();
|
|
177
|
+
if (extension === ".py") return extractPythonSymbols(content, SYMBOL_LIMIT);
|
|
178
|
+
if (HEADING_EXTENSIONS.has(extension)) return extractHeadings(content, extension === ".rst");
|
|
179
|
+
const lines = content.split(/\r?\n/);
|
|
180
|
+
const symbols = [];
|
|
181
|
+
for (let index = 0; index < lines.length; index++) {
|
|
182
|
+
const line = lines[index] ?? "";
|
|
183
|
+
if (/^\s/.test(line)) continue;
|
|
184
|
+
const match = DECLARATION.exec(line);
|
|
185
|
+
if (!match?.groups) continue;
|
|
186
|
+
const rawKind = match.groups.kind ?? "";
|
|
187
|
+
const kind = normalizeKind(rawKind);
|
|
188
|
+
const name = match.groups.name ?? "";
|
|
189
|
+
if (!name) continue;
|
|
190
|
+
const startLine = index + 1;
|
|
191
|
+
const endLine = findEndLine(lines, index) + 1;
|
|
192
|
+
const exported = Boolean(match.groups.export);
|
|
193
|
+
symbols.push({ name, kind, startLine, endLine, signature: buildSignature(line), exported });
|
|
194
|
+
if (kind === "class") symbols.push(...classMethods(lines, index, endLine - 1, name, exported));
|
|
195
|
+
if (symbols.length >= SYMBOL_LIMIT) break;
|
|
196
|
+
}
|
|
197
|
+
return symbols.slice(0, SYMBOL_LIMIT);
|
|
198
|
+
}
|
|
199
|
+
var METHOD = /^\s+(?:(?:public|private|protected|static|abstract|override|async|get|set|readonly)\s+)*(#?[A-Za-z_$][\w$]*)\??(?:<[^>]*>)?\s*\(/;
|
|
200
|
+
function classMethods(lines, classIndex, classEnd, className, exported) {
|
|
201
|
+
const methods = [];
|
|
202
|
+
let depth = 0;
|
|
203
|
+
let parens = 0;
|
|
204
|
+
let open = null;
|
|
205
|
+
for (let index = classIndex; index <= classEnd; index++) {
|
|
206
|
+
const line = lines[index] ?? "";
|
|
207
|
+
const method = depth === 1 && !open ? METHOD.exec(line) : null;
|
|
208
|
+
if (method?.[1]) {
|
|
209
|
+
open = {
|
|
210
|
+
name: `${className}.${method[1]}`,
|
|
211
|
+
startLine: index + 1,
|
|
212
|
+
signature: `${className}: ${buildSignature(line.trim())}`
|
|
213
|
+
};
|
|
214
|
+
parens = 0;
|
|
215
|
+
}
|
|
216
|
+
const code = codeOnly(line);
|
|
217
|
+
depth += braceDelta(code);
|
|
218
|
+
parens += delta(code, "(", ")");
|
|
219
|
+
if (open && depth === 1 && parens <= 0 && (code.includes("}") || code.trimEnd().endsWith(";"))) {
|
|
220
|
+
methods.push({ ...open, kind: "method", endLine: index + 1, exported });
|
|
221
|
+
open = null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return methods;
|
|
225
|
+
}
|
|
226
|
+
function normalizeKind(raw) {
|
|
227
|
+
if (raw.startsWith("function")) return "function";
|
|
228
|
+
if (raw === "let" || raw === "var" || raw === "const") return "const";
|
|
229
|
+
return raw;
|
|
230
|
+
}
|
|
231
|
+
function buildSignature(line) {
|
|
232
|
+
const head = line.split("{")[0]?.split("=>")[0]?.trimEnd() ?? line.trim();
|
|
233
|
+
const cleaned = head.replace(/[=;{]\s*$/, "").trim();
|
|
234
|
+
return cleaned.length <= SIGNATURE_MAX2 ? cleaned : `${cleaned.slice(0, SIGNATURE_MAX2 - 1)}\u2026`;
|
|
235
|
+
}
|
|
236
|
+
function findEndLine(lines, startIndex) {
|
|
237
|
+
let braces = 0;
|
|
238
|
+
let parens = 0;
|
|
239
|
+
for (let index = startIndex; index < lines.length; index++) {
|
|
240
|
+
const code = codeOnly(lines[index] ?? "");
|
|
241
|
+
braces += braceDelta(code);
|
|
242
|
+
parens += delta(code, "(", ")");
|
|
243
|
+
if (braces <= 0 && parens <= 0) return index;
|
|
244
|
+
}
|
|
245
|
+
return lines.length - 1;
|
|
246
|
+
}
|
|
247
|
+
function codeOnly(line) {
|
|
248
|
+
return line.replace(/(["'`])(?:\\.|(?!\1).)*\1/g, '""').replace(/\/\/.*$/, "");
|
|
249
|
+
}
|
|
250
|
+
function braceDelta(code) {
|
|
251
|
+
return delta(code, "{", "}");
|
|
252
|
+
}
|
|
253
|
+
function delta(code, open, close) {
|
|
254
|
+
let total = 0;
|
|
255
|
+
for (const char of code) {
|
|
256
|
+
if (char === open) total++;
|
|
257
|
+
else if (char === close) total--;
|
|
258
|
+
}
|
|
259
|
+
return total;
|
|
260
|
+
}
|
|
261
|
+
var RST_ADORNMENT = /^([=\-~^"'`#*+.:_<>!$%&,;/?@\\|])\1+\s*$/;
|
|
262
|
+
function atxTitle(text) {
|
|
263
|
+
const trimmed = text.trimEnd();
|
|
264
|
+
let end = trimmed.length;
|
|
265
|
+
while (end > 0 && trimmed[end - 1] === "#") end--;
|
|
266
|
+
const closed = end < trimmed.length && (end === 0 || /[ \t]/.test(trimmed[end - 1] ?? ""));
|
|
267
|
+
return (closed ? trimmed.slice(0, end) : trimmed).trim();
|
|
268
|
+
}
|
|
269
|
+
function extractHeadings(content, rst) {
|
|
270
|
+
const lines = content.split(/\r?\n/);
|
|
271
|
+
const found = [];
|
|
272
|
+
const styles = [];
|
|
273
|
+
let fence = null;
|
|
274
|
+
for (let index = 0; index < lines.length && found.length <= SYMBOL_LIMIT; index++) {
|
|
275
|
+
const line = lines[index] ?? "";
|
|
276
|
+
if (!rst) {
|
|
277
|
+
const marker = /^\s{0,3}(`{3,}|~{3,})/.exec(line)?.[1];
|
|
278
|
+
if (marker && (!fence || marker.startsWith(fence))) fence = fence ? null : marker;
|
|
279
|
+
const atx = fence || marker ? null : /^(#{1,6})[ \t]+(.*)$/.exec(line);
|
|
280
|
+
const name = atx?.[2] === void 0 ? void 0 : atxTitle(atx[2]);
|
|
281
|
+
if (atx?.[1] && name) {
|
|
282
|
+
found.push({ name, signature: line.trim(), start: index, level: atx[1].length });
|
|
283
|
+
}
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const title = line.trim();
|
|
287
|
+
const under = (lines[index + 1] ?? "").trimEnd();
|
|
288
|
+
if (!title || RST_ADORNMENT.test(title)) continue;
|
|
289
|
+
const adornment = RST_ADORNMENT.exec(under)?.[1];
|
|
290
|
+
if (!adornment || under.length < Math.max(2, title.length)) continue;
|
|
291
|
+
const overlined = index > 0 && (lines[index - 1] ?? "").trimEnd() === under;
|
|
292
|
+
if (!overlined && /^\s/.test(line)) continue;
|
|
293
|
+
const style = `${overlined ? "o" : ""}${adornment}`;
|
|
294
|
+
if (!styles.includes(style)) styles.push(style);
|
|
295
|
+
const start = overlined ? index - 1 : index;
|
|
296
|
+
found.push({ name: title, signature: title, start, level: styles.indexOf(style) });
|
|
297
|
+
index++;
|
|
298
|
+
}
|
|
299
|
+
let last = lines.length - 1;
|
|
300
|
+
while (last > 0 && (lines[last] ?? "").trim() === "") last--;
|
|
301
|
+
return found.slice(0, SYMBOL_LIMIT).map((heading, position) => {
|
|
302
|
+
const next = found.slice(position + 1).find((other) => other.level <= heading.level);
|
|
303
|
+
let end = next ? next.start - 1 : last;
|
|
304
|
+
while (end > heading.start && (lines[end] ?? "").trim() === "") end--;
|
|
305
|
+
return {
|
|
306
|
+
name: heading.name.slice(0, SIGNATURE_MAX2),
|
|
307
|
+
kind: "heading",
|
|
308
|
+
startLine: heading.start + 1,
|
|
309
|
+
endLine: end + 1,
|
|
310
|
+
signature: heading.signature.slice(0, SIGNATURE_MAX2),
|
|
311
|
+
exported: true
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export {
|
|
317
|
+
extractPythonImports,
|
|
318
|
+
supportsSymbols,
|
|
319
|
+
extractSymbolTable
|
|
320
|
+
};
|
|
321
|
+
//# sourceMappingURL=chunk-Y7D7PUBE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/indexer/python.ts","../src/indexer/symbols.ts"],"sourcesContent":["import type { SymbolSpan } from \"./symbols.js\";\n\n/**\n * Python without a parser: one pass splits the file into logical lines\n * (bracket, backslash and triple-quoted string continuations joined, comments\n * dropped), then indentation gives block ends. Enough for an outline and an\n * import map; anything it can't classify is skipped.\n */\n\nexport type LogicalLine = {\n /** 0-based first and last physical line. */\n start: number;\n end: number;\n indent: number;\n /** Code of all physical lines joined by spaces, comments removed. */\n text: string;\n};\n\nexport function pythonLogicalLines(content: string): LogicalLine[] {\n const lines = content.split(/\\r?\\n/);\n const result: LogicalLine[] = [];\n let current: LogicalLine | null = null;\n // Joined once per logical line: re-concatenating per physical line was\n // quadratic on a long unclosed string or bracket.\n let parts: string[] = [];\n const emit = (line: LogicalLine) => {\n line.text = parts.join(\" \").trimStart();\n parts = [];\n result.push(line);\n };\n let quote: string | null = null;\n let depth = 0;\n let backslash = false;\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index] ?? \"\";\n if (!current) {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"#\")) continue;\n current = {\n start: index,\n end: index,\n indent: line.length - line.trimStart().length,\n text: \"\",\n };\n }\n let code = \"\";\n for (let at = 0; at < line.length; at++) {\n const char = line[at] ?? \"\";\n if (quote) {\n code += char;\n if (char === \"\\\\\") {\n code += line[at + 1] ?? \"\";\n at++;\n } else if (line.startsWith(quote, at)) {\n code += quote.slice(1);\n at += quote.length - 1;\n quote = null;\n }\n continue;\n }\n if (char === \"#\") break;\n if (char === '\"' || char === \"'\") {\n quote = line.startsWith(char.repeat(3), at) ? char.repeat(3) : char;\n code += quote;\n at += quote.length - 1;\n continue;\n }\n if (\"([{\".includes(char)) depth++;\n else if (\")]}\".includes(char)) depth = Math.max(0, depth - 1);\n code += char;\n }\n backslash = !quote && code.endsWith(\"\\\\\");\n // An unterminated single-quoted string ends at the line break.\n if (quote && quote.length === 1 && !code.endsWith(\"\\\\\")) quote = null;\n const piece = (backslash ? code.slice(0, -1) : code).trimEnd();\n if (piece.trim() !== \"\") parts.push(piece);\n current.end = index;\n if (!quote && depth === 0 && !backslash) {\n emit(current);\n current = null;\n }\n }\n if (current) emit(current);\n return result;\n}\n\nconst DEF = /^(?:async\\s+)?def\\s+([A-Za-z_]\\w*)/;\nconst CLASS = /^class\\s+([A-Za-z_]\\w*)/;\nconst CONSTANT = /^([A-Z][A-Z0-9_]*)\\s*(?::[^=]*)?=(?!=)/;\nconst SIGNATURE_MAX = 120;\n\nexport function extractPythonSymbols(content: string, limit: number): SymbolSpan[] {\n const logical = pythonLogicalLines(content);\n const symbols: SymbolSpan[] = [];\n collect(logical, 0, logical.length, 0, null, symbols, limit);\n return symbols.slice(0, limit);\n}\n\n/** Declarations at exactly `indent` in logical lines [from, to); methods for classes at 0. */\nfunction collect(\n logical: LogicalLine[],\n from: number,\n to: number,\n indent: number,\n className: string | null,\n symbols: SymbolSpan[],\n limit: number,\n): void {\n let decorator: number | null = null;\n for (let index = from; index < to && symbols.length < limit; index++) {\n const line = logical[index];\n if (!line || line.indent !== indent) continue;\n if (line.text.startsWith(\"@\")) {\n decorator ??= line.start;\n continue;\n }\n const start = decorator ?? line.start;\n decorator = null;\n const def = DEF.exec(line.text);\n const cls = def || className ? null : CLASS.exec(line.text);\n const constant = def || cls || className ? null : CONSTANT.exec(line.text);\n const name = def?.[1] ?? cls?.[1] ?? constant?.[1];\n if (!name) continue;\n const blockEnd = constant ? index + 1 : endOfBlock(logical, index);\n const endLine = (logical[blockEnd - 1]?.end ?? line.end) + 1;\n const head = constant ? line.text : header(line.text);\n const exported = !(className ?? name).startsWith(\"_\");\n symbols.push({\n name: className ? `${className}.${name}` : name,\n kind: className ? \"method\" : def ? \"function\" : cls ? \"class\" : \"const\",\n startLine: start + 1,\n endLine,\n signature: truncate(className ? `${className}: ${head}` : head),\n exported,\n });\n if (cls && className === null && blockEnd > index + 1) {\n const bodyIndent = logical[index + 1]?.indent ?? 0;\n if (bodyIndent > indent)\n collect(logical, index + 1, blockEnd, bodyIndent, name, symbols, limit);\n }\n }\n}\n\n/** Index of the first logical line after the block opened at `index`. */\nfunction endOfBlock(logical: LogicalLine[], index: number): number {\n const indent = logical[index]?.indent ?? 0;\n for (let next = index + 1; next < logical.length; next++) {\n if ((logical[next]?.indent ?? 0) <= indent) return next;\n }\n return logical.length;\n}\n\n/** The declaration head: text before the first colon outside brackets and strings. */\nfunction header(text: string): string {\n let depth = 0;\n let quote: string | null = null;\n for (let at = 0; at < text.length; at++) {\n const char = text[at] ?? \"\";\n if (quote) {\n if (char === \"\\\\\") at++;\n else if (char === quote) quote = null;\n continue;\n }\n if (char === '\"' || char === \"'\") quote = char;\n else if (\"([{\".includes(char)) depth++;\n else if (\")]}\".includes(char)) depth--;\n else if (char === \":\" && depth === 0) return tidy(text.slice(0, at));\n }\n return tidy(text);\n}\n\nfunction tidy(text: string): string {\n return text\n .replace(/\\s+/g, \" \")\n .replace(/([([{])\\s+/g, \"$1\")\n .replace(/,?\\s*([)\\]}])/g, \"$1\")\n .trim();\n}\n\nfunction truncate(value: string): string {\n return value.length <= SIGNATURE_MAX ? value : `${value.slice(0, SIGNATURE_MAX - 1)}…`;\n}\n\nexport type PythonImport = {\n /** Leading dots of a relative import (0 = absolute). */\n level: number;\n /** Dotted module, \"\" for `from . import x`. */\n module: string;\n /** Names after `from … import`; empty for `import a.b`. */\n names: string[];\n};\n\n/** `import` / `from … import` statements anywhere in the file (not in strings or comments). */\nexport function extractPythonImports(content: string): PythonImport[] {\n const imports: PythonImport[] = [];\n for (const { text } of pythonLogicalLines(content)) {\n for (const statement of text.split(\";\").map((part) => part.trim())) {\n const plain = /^import\\s+(.+)$/.exec(statement);\n if (plain?.[1]) {\n for (const part of plain[1].split(\",\")) {\n const module =\n part\n .trim()\n .split(/\\s+as\\s+/)[0]\n ?.trim() ?? \"\";\n if (/^[A-Za-z_][\\w.]*$/.test(module)) imports.push({ level: 0, module, names: [] });\n }\n continue;\n }\n const from = /^from\\s+(\\.*)\\s*([A-Za-z_][\\w.]*)?\\s+import\\s+(.+)$/.exec(statement);\n if (!from) continue;\n const names = (from[3] ?? \"\")\n .replace(/[()]/g, \" \")\n .split(\",\")\n .map(\n (part) =>\n part\n .trim()\n .split(/\\s+as\\s+/)[0]\n ?.trim() ?? \"\",\n )\n .filter((name) => /^[A-Za-z_]\\w*$/.test(name));\n imports.push({ level: from[1]?.length ?? 0, module: from[2] ?? \"\", names });\n }\n }\n return imports;\n}\n","import { extname } from \"node:path\";\nimport { extractPythonSymbols } from \"./python.js\";\n\n/**\n * Lightweight symbol extraction (Roadmap N.3). Records the top-level symbols of\n * a TS/JS file, plus class methods as `Class.method` — name, kind, line range,\n * and a one-line signature — using regex\n * + brace matching, deliberately *not* a full parser (consistent with the\n * indexer's \"no fragile parser platform\" stance). This lets context represent a\n * file by its public API (a handful of signatures) instead of its whole body,\n * so an agent can see what a file offers without reading it.\n *\n * It is a heuristic: it targets the common top-level declaration forms and skips\n * anything it can't classify. Deterministic — the same file always yields the\n * same table.\n */\n\nexport type SymbolKind =\n | \"function\"\n | \"method\"\n | \"class\"\n | \"interface\"\n | \"type\"\n | \"enum\"\n | \"const\"\n | \"heading\";\n\nexport type SymbolSpan = {\n name: string;\n kind: SymbolKind;\n /** 1-based inclusive line range. */\n startLine: number;\n endLine: number;\n /** One-line signature (declaration head), truncated. */\n signature: string;\n exported: boolean;\n};\n\nconst SYMBOL_CODE_EXTENSIONS = new Set([\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\", \".py\"]);\nconst HEADING_EXTENSIONS = new Set([\".md\", \".mdx\", \".rst\"]);\nconst SIGNATURE_MAX = 120;\nconst SYMBOL_LIMIT = 100;\n\n/** True when a symbol table (code declarations or doc headings) exists for this path. */\nexport function supportsSymbols(path: string): boolean {\n const extension = extname(path).toLowerCase();\n return SYMBOL_CODE_EXTENSIONS.has(extension) || HEADING_EXTENSIONS.has(extension);\n}\n\n/** True when this path's language declares code symbols (not doc headings). */\nexport function supportsCodeSymbols(path: string): boolean {\n return SYMBOL_CODE_EXTENSIONS.has(extname(path).toLowerCase());\n}\n\nconst DECLARATION =\n /^(?<export>export\\s+)?(?<default>default\\s+)?(?<mods>(?:declare\\s+|abstract\\s+|async\\s+)*)(?<kind>function\\*?|class|interface|type|enum|const|let|var)\\s+(?<name>[A-Za-z_$][\\w$]*)/;\n\n/** Symbols of `content`; `path` picks the language (TS/JS when omitted). */\nexport function extractSymbolTable(content: string, path = \"\"): SymbolSpan[] {\n const extension = extname(path).toLowerCase();\n if (extension === \".py\") return extractPythonSymbols(content, SYMBOL_LIMIT);\n if (HEADING_EXTENSIONS.has(extension)) return extractHeadings(content, extension === \".rst\");\n const lines = content.split(/\\r?\\n/);\n const symbols: SymbolSpan[] = [];\n\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index] ?? \"\";\n // Top-level only: a declaration that starts at column 0 (optionally exported).\n if (/^\\s/.test(line)) continue;\n const match = DECLARATION.exec(line);\n if (!match?.groups) continue;\n\n const rawKind = match.groups.kind ?? \"\";\n const kind = normalizeKind(rawKind);\n const name = match.groups.name ?? \"\";\n if (!name) continue;\n\n const startLine = index + 1;\n const endLine = findEndLine(lines, index) + 1;\n const exported = Boolean(match.groups.export);\n symbols.push({ name, kind, startLine, endLine, signature: buildSignature(line), exported });\n if (kind === \"class\") symbols.push(...classMethods(lines, index, endLine - 1, name, exported));\n if (symbols.length >= SYMBOL_LIMIT) break;\n }\n\n return symbols.slice(0, SYMBOL_LIMIT);\n}\n\nconst METHOD =\n /^\\s+(?:(?:public|private|protected|static|abstract|override|async|get|set|readonly)\\s+)*(#?[A-Za-z_$][\\w$]*)\\??(?:<[^>]*>)?\\s*\\(/;\n\n/**\n * Methods directly in a class body (brace depth 1), named `Class.method`, so a\n * task can name a method and get its own span instead of the whole class.\n */\nfunction classMethods(\n lines: string[],\n classIndex: number,\n classEnd: number,\n className: string,\n exported: boolean,\n): SymbolSpan[] {\n const methods: SymbolSpan[] = [];\n let depth = 0;\n let parens = 0;\n let open: { name: string; startLine: number; signature: string } | null = null;\n for (let index = classIndex; index <= classEnd; index++) {\n const line = lines[index] ?? \"\";\n const method: RegExpExecArray | null = depth === 1 && !open ? METHOD.exec(line) : null;\n if (method?.[1]) {\n open = {\n name: `${className}.${method[1]}`,\n startLine: index + 1,\n signature: `${className}: ${buildSignature(line.trim())}`,\n };\n parens = 0;\n }\n const code = codeOnly(line);\n depth += braceDelta(code);\n parens += delta(code, \"(\", \")\");\n // Back at class-body depth after a body, or a bodiless (abstract/overload)\n // member; an object type in a multi-line parameter list is not the body.\n if (\n open &&\n depth === 1 &&\n parens <= 0 &&\n (code.includes(\"}\") || code.trimEnd().endsWith(\";\"))\n ) {\n methods.push({ ...open, kind: \"method\", endLine: index + 1, exported });\n open = null;\n }\n }\n return methods;\n}\n\n/**\n * Render a file's symbols as compact signature lines (the \"symbol capsule\").\n * The signature already preserves a leading `export`, so it is used verbatim.\n */\nexport function symbolSignatures(symbols: SymbolSpan[], limit = 12): string[] {\n return symbols.slice(0, limit).map((symbol) => symbol.signature);\n}\n\nfunction normalizeKind(raw: string): SymbolKind {\n if (raw.startsWith(\"function\")) return \"function\";\n if (raw === \"let\" || raw === \"var\" || raw === \"const\") return \"const\";\n return raw as SymbolKind;\n}\n\nfunction buildSignature(line: string): string {\n const head = line.split(\"{\")[0]?.split(\"=>\")[0]?.trimEnd() ?? line.trim();\n const cleaned = head.replace(/[=;{]\\s*$/, \"\").trim();\n return cleaned.length <= SIGNATURE_MAX ? cleaned : `${cleaned.slice(0, SIGNATURE_MAX - 1)}…`;\n}\n\n/**\n * Find the last line of a declaration: the first line where both braces and\n * parentheses are balanced, so a multi-line parameter list carries on to its\n * body. A one-line const/type is a single line. Braces in single-line strings\n * and `//` comments are ignored; multi-line template literals, block comments\n * and regex literals can still skew it.\n */\nfunction findEndLine(lines: string[], startIndex: number): number {\n let braces = 0;\n let parens = 0;\n for (let index = startIndex; index < lines.length; index++) {\n const code = codeOnly(lines[index] ?? \"\");\n braces += braceDelta(code);\n parens += delta(code, \"(\", \")\");\n if (braces <= 0 && parens <= 0) return index;\n }\n return lines.length - 1;\n}\n\n/** The line without single-line string literals and a trailing `//` comment. */\nfunction codeOnly(line: string): string {\n return line.replace(/([\"'`])(?:\\\\.|(?!\\1).)*\\1/g, '\"\"').replace(/\\/\\/.*$/, \"\");\n}\n\nfunction braceDelta(code: string): number {\n return delta(code, \"{\", \"}\");\n}\n\nfunction delta(code: string, open: string, close: string): number {\n let total = 0;\n for (const char of code) {\n if (char === open) total++;\n else if (char === close) total--;\n }\n return total;\n}\n\nconst RST_ADORNMENT = /^([=\\-~^\"'`#*+.:_<>!$%&,;/?@\\\\|])\\1+\\s*$/;\n\n/**\n * Doc headings as symbols: Markdown ATX (`## Title`, outside code fences) or\n * reStructuredText (a title underlined, optionally also overlined, by one\n * repeated punctuation character at least as long as the title). A heading's\n * span runs to the next heading of the same or a higher level.\n */\n/**\n * A Markdown heading's text without its closing `#`s, which count only after\n * whitespace. Scanned by hand: every regex for this backtracked at least\n * quadratically on a heading with a long run of spaces.\n */\nfunction atxTitle(text: string): string {\n const trimmed = text.trimEnd();\n let end = trimmed.length;\n while (end > 0 && trimmed[end - 1] === \"#\") end--;\n const closed = end < trimmed.length && (end === 0 || /[ \\t]/.test(trimmed[end - 1] ?? \"\"));\n return (closed ? trimmed.slice(0, end) : trimmed).trim();\n}\n\nfunction extractHeadings(content: string, rst: boolean): SymbolSpan[] {\n const lines = content.split(/\\r?\\n/);\n const found: Array<{ name: string; signature: string; start: number; level: number }> = [];\n const styles: string[] = [];\n let fence: string | null = null;\n // Past the cap headings are still found (as section ends) but not returned.\n for (let index = 0; index < lines.length && found.length <= SYMBOL_LIMIT; index++) {\n const line = lines[index] ?? \"\";\n if (!rst) {\n const marker = /^\\s{0,3}(`{3,}|~{3,})/.exec(line)?.[1];\n if (marker && (!fence || marker.startsWith(fence))) fence = fence ? null : marker;\n const atx = fence || marker ? null : /^(#{1,6})[ \\t]+(.*)$/.exec(line);\n const name = atx?.[2] === undefined ? undefined : atxTitle(atx[2]);\n if (atx?.[1] && name) {\n found.push({ name, signature: line.trim(), start: index, level: atx[1].length });\n }\n continue;\n }\n const title = line.trim();\n const under = (lines[index + 1] ?? \"\").trimEnd();\n if (!title || RST_ADORNMENT.test(title)) continue;\n const adornment = RST_ADORNMENT.exec(under)?.[1];\n if (!adornment || under.length < Math.max(2, title.length)) continue;\n const overlined = index > 0 && (lines[index - 1] ?? \"\").trimEnd() === under;\n // Only an overlined title may be inset; an indented line is body text.\n if (!overlined && /^\\s/.test(line)) continue;\n const style = `${overlined ? \"o\" : \"\"}${adornment}`;\n if (!styles.includes(style)) styles.push(style);\n const start = overlined ? index - 1 : index;\n found.push({ name: title, signature: title, start, level: styles.indexOf(style) });\n index++;\n }\n let last = lines.length - 1;\n while (last > 0 && (lines[last] ?? \"\").trim() === \"\") last--;\n return found.slice(0, SYMBOL_LIMIT).map((heading, position) => {\n const next = found.slice(position + 1).find((other) => other.level <= heading.level);\n let end = next ? next.start - 1 : last;\n while (end > heading.start && (lines[end] ?? \"\").trim() === \"\") end--;\n return {\n name: heading.name.slice(0, SIGNATURE_MAX),\n kind: \"heading\" as const,\n startLine: heading.start + 1,\n endLine: end + 1,\n signature: heading.signature.slice(0, SIGNATURE_MAX),\n exported: true,\n };\n });\n}\n"],"mappings":"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","names":["SIGNATURE_MAX","SIGNATURE_MAX"]}
|