@wrongstack/tools 0.73.1 → 0.82.6
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/audit.d.ts +4 -4
- package/dist/audit.js +10 -2
- package/dist/audit.js.map +1 -1
- package/dist/{background-indexer-sbsseCCC.d.ts → background-indexer-DYm1FUxK.d.ts} +49 -17
- package/dist/bash.d.ts +4 -4
- package/dist/bash.js +18 -4
- package/dist/bash.js.map +1 -1
- package/dist/batch-tool-use.d.ts +4 -4
- package/dist/batch-tool-use.js.map +1 -1
- package/dist/builtin.js +266 -71
- package/dist/builtin.js.map +1 -1
- package/dist/circuit-breaker.d.ts +6 -6
- package/dist/circuit-breaker.js.map +1 -1
- package/dist/codebase-index/index.d.ts +12 -12
- package/dist/codebase-index/index.js +270 -106
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/diff.d.ts +7 -7
- package/dist/diff.js.map +1 -1
- package/dist/document.d.ts +6 -6
- package/dist/document.js.map +1 -1
- package/dist/edit.d.ts +1 -1
- package/dist/edit.js.map +1 -1
- package/dist/exec.d.ts +3 -3
- package/dist/exec.js +15 -3
- package/dist/exec.js.map +1 -1
- package/dist/fetch.d.ts +1 -1
- package/dist/fetch.js +3 -1
- package/dist/fetch.js.map +1 -1
- package/dist/format.d.ts +4 -4
- package/dist/format.js +18 -4
- package/dist/format.js.map +1 -1
- package/dist/git.d.ts +10 -10
- package/dist/git.js +8 -2
- package/dist/git.js.map +1 -1
- package/dist/glob.d.ts +2 -2
- package/dist/glob.js.map +1 -1
- package/dist/grep.d.ts +6 -6
- package/dist/grep.js +10 -2
- package/dist/grep.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +366 -136
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +5 -5
- package/dist/install.js +18 -4
- package/dist/install.js.map +1 -1
- package/dist/json.d.ts +8 -8
- package/dist/json.js.map +1 -1
- package/dist/lint.d.ts +4 -4
- package/dist/lint.js +18 -4
- package/dist/lint.js.map +1 -1
- package/dist/logs.d.ts +8 -8
- package/dist/logs.js.map +1 -1
- package/dist/memory.d.ts +2 -2
- package/dist/memory.js.map +1 -1
- package/dist/mode.d.ts +3 -3
- package/dist/mode.js.map +1 -1
- package/dist/outdated.d.ts +4 -4
- package/dist/outdated.js.map +1 -1
- package/dist/pack.js +266 -71
- package/dist/pack.js.map +1 -1
- package/dist/patch.d.ts +3 -3
- package/dist/patch.js.map +1 -1
- package/dist/process-registry.d.ts +3 -3
- package/dist/process-registry.js +7 -1
- package/dist/process-registry.js.map +1 -1
- package/dist/read.d.ts +2 -2
- package/dist/read.js.map +1 -1
- package/dist/replace.d.ts +4 -4
- package/dist/replace.js +8 -2
- package/dist/replace.js.map +1 -1
- package/dist/scaffold.d.ts +2 -2
- package/dist/scaffold.js.map +1 -1
- package/dist/search.d.ts +2 -2
- package/dist/search.js +16 -8
- package/dist/search.js.map +1 -1
- package/dist/test.d.ts +7 -7
- package/dist/test.js +18 -4
- package/dist/test.js.map +1 -1
- package/dist/todo.js +2 -1
- package/dist/todo.js.map +1 -1
- package/dist/tool-help.d.ts +4 -4
- package/dist/tool-help.js.map +1 -1
- package/dist/tool-search.d.ts +5 -5
- package/dist/tool-search.js.map +1 -1
- package/dist/tool-use.d.ts +2 -2
- package/dist/tool-use.js.map +1 -1
- package/dist/tree.d.ts +7 -7
- package/dist/tree.js +10 -2
- package/dist/tree.js.map +1 -1
- package/dist/typecheck.d.ts +4 -4
- package/dist/typecheck.js +18 -4
- package/dist/typecheck.js.map +1 -1
- package/dist/write.d.ts +1 -1
- package/dist/write.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -19,6 +19,12 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
19
19
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
20
20
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
21
21
|
});
|
|
22
|
+
function expectDefined(value) {
|
|
23
|
+
if (value === null || value === void 0) {
|
|
24
|
+
throw new Error("Expected value to be defined");
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
22
28
|
async function detectPackageManager(cwd) {
|
|
23
29
|
const { stat: stat10 } = await import('node:fs/promises');
|
|
24
30
|
try {
|
|
@@ -108,9 +114,9 @@ function collapseConsecutiveDuplicates(text, minRun = REPEAT_RUN_THRESHOLD) {
|
|
|
108
114
|
while (j < lines.length && lines[j] === lines[i]) j++;
|
|
109
115
|
const run = j - i;
|
|
110
116
|
if (run >= minRun) {
|
|
111
|
-
out.push(lines[i], `\u2026 \u27E8repeated ${run}\xD7\u27E9`);
|
|
117
|
+
out.push(expectDefined(lines[i]), `\u2026 \u27E8repeated ${run}\xD7\u27E9`);
|
|
112
118
|
} else {
|
|
113
|
-
for (let k = i; k < j; k++) out.push(lines[k]);
|
|
119
|
+
for (let k = i; k < j; k++) out.push(expectDefined(lines[k]));
|
|
114
120
|
}
|
|
115
121
|
i = j;
|
|
116
122
|
}
|
|
@@ -466,6 +472,12 @@ function capSubject(line) {
|
|
|
466
472
|
}
|
|
467
473
|
|
|
468
474
|
// src/replace.ts
|
|
475
|
+
function expectDefined2(value) {
|
|
476
|
+
if (value === null || value === void 0) {
|
|
477
|
+
throw new Error("Expected value to be defined");
|
|
478
|
+
}
|
|
479
|
+
return value;
|
|
480
|
+
}
|
|
469
481
|
var DEFAULT_IGNORE = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
470
482
|
var replaceTool = {
|
|
471
483
|
name: "replace",
|
|
@@ -545,8 +557,8 @@ var replaceTool = {
|
|
|
545
557
|
const count = matches.length;
|
|
546
558
|
let newContentLf = contentLf;
|
|
547
559
|
for (let i = matches.length - 1; i >= 0; i--) {
|
|
548
|
-
const m = matches[i];
|
|
549
|
-
newContentLf = newContentLf.slice(0, m.index) + input.replacement + newContentLf.slice(m.index + m[0].length);
|
|
560
|
+
const m = expectDefined2(matches[i]);
|
|
561
|
+
newContentLf = newContentLf.slice(0, m.index) + input.replacement + newContentLf.slice(expectDefined2(m.index) + m[0].length);
|
|
550
562
|
}
|
|
551
563
|
re.lastIndex = 0;
|
|
552
564
|
totalReplacements += count;
|
|
@@ -747,6 +759,12 @@ async function readGitignore(dir) {
|
|
|
747
759
|
return [];
|
|
748
760
|
}
|
|
749
761
|
}
|
|
762
|
+
function expectDefined3(value) {
|
|
763
|
+
if (value === null || value === void 0) {
|
|
764
|
+
throw new Error("Expected value to be defined");
|
|
765
|
+
}
|
|
766
|
+
return value;
|
|
767
|
+
}
|
|
750
768
|
var DEFAULT_IGNORE3 = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
751
769
|
var grepTool = {
|
|
752
770
|
name: "grep",
|
|
@@ -795,7 +813,9 @@ var grepTool = {
|
|
|
795
813
|
},
|
|
796
814
|
async execute(input, ctx, opts) {
|
|
797
815
|
let final;
|
|
798
|
-
|
|
816
|
+
const executeStream = grepTool.executeStream;
|
|
817
|
+
if (!executeStream) throw new Error("grepTool: stream execution unavailable");
|
|
818
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
799
819
|
if (ev.type === "final") final = ev.output;
|
|
800
820
|
}
|
|
801
821
|
if (!final) throw new Error("grep: stream ended without final event");
|
|
@@ -886,7 +906,7 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
886
906
|
waiter = r;
|
|
887
907
|
});
|
|
888
908
|
}
|
|
889
|
-
const c = queue.shift();
|
|
909
|
+
const c = expectDefined3(queue.shift());
|
|
890
910
|
if (c.kind === "error") {
|
|
891
911
|
errored = true;
|
|
892
912
|
continue;
|
|
@@ -1178,6 +1198,12 @@ var CircuitBreaker = class {
|
|
|
1178
1198
|
};
|
|
1179
1199
|
|
|
1180
1200
|
// src/process-registry.ts
|
|
1201
|
+
function expectDefined4(value) {
|
|
1202
|
+
if (value === null || value === void 0) {
|
|
1203
|
+
throw new Error("Expected value to be defined");
|
|
1204
|
+
}
|
|
1205
|
+
return value;
|
|
1206
|
+
}
|
|
1181
1207
|
var SENSITIVE_FLAG_PATTERNS = [
|
|
1182
1208
|
// --flag=value or --flag "value" (value captured up to next space or comma)
|
|
1183
1209
|
/--(?:token|password|passwd|pwd|secret|api[-_]?key|api[-_]?secret|auth|credential|private[-_]?key|access[-_]?key|github[-_]?token|gh[-_]?token|bearer|jwt|oauth|pin|pincode|passphrase|access[-_]?token)(?:[=\s,][^\s]*)?/gi,
|
|
@@ -1198,7 +1224,7 @@ function redactCommand(cmd) {
|
|
|
1198
1224
|
const sp = match.search(/\s/);
|
|
1199
1225
|
const delim = eq !== -1 ? "=" : sp !== -1 ? match[sp] : null;
|
|
1200
1226
|
if (delim !== null) {
|
|
1201
|
-
const flag = match.slice(0, match.indexOf(delim) + 1);
|
|
1227
|
+
const flag = match.slice(0, match.indexOf(expectDefined4(delim)) + 1);
|
|
1202
1228
|
return `${flag}[REDACTED]`;
|
|
1203
1229
|
}
|
|
1204
1230
|
const flagEnd = match.match(/^--?[a-zA-Z][a-zA-Z0-9_-]*/)?.[0] ?? match;
|
|
@@ -1420,7 +1446,9 @@ var bashTool = {
|
|
|
1420
1446
|
},
|
|
1421
1447
|
async execute(input, ctx, opts) {
|
|
1422
1448
|
let final;
|
|
1423
|
-
|
|
1449
|
+
const executeStream = bashTool.executeStream;
|
|
1450
|
+
if (!executeStream) throw new Error("bashTool: stream execution unavailable");
|
|
1451
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
1424
1452
|
if (ev.type === "final") final = ev.output;
|
|
1425
1453
|
}
|
|
1426
1454
|
if (!final) throw new Error("bash: stream ended without final event");
|
|
@@ -2018,7 +2046,9 @@ var fetchTool = {
|
|
|
2018
2046
|
},
|
|
2019
2047
|
async execute(input, ctx, opts) {
|
|
2020
2048
|
let final;
|
|
2021
|
-
|
|
2049
|
+
const executeStream = fetchTool.executeStream;
|
|
2050
|
+
if (!executeStream) throw new Error("fetchTool: stream execution unavailable");
|
|
2051
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
2022
2052
|
if (ev.type === "final") final = ev.output;
|
|
2023
2053
|
}
|
|
2024
2054
|
if (!final) throw new Error("fetch: stream ended without final event");
|
|
@@ -2247,6 +2277,12 @@ function stripTags(s) {
|
|
|
2247
2277
|
}
|
|
2248
2278
|
|
|
2249
2279
|
// src/search.ts
|
|
2280
|
+
function expectDefined5(value) {
|
|
2281
|
+
if (value === null || value === void 0) {
|
|
2282
|
+
throw new Error("Expected value to be defined");
|
|
2283
|
+
}
|
|
2284
|
+
return value;
|
|
2285
|
+
}
|
|
2250
2286
|
var DEFAULT_NUM = 10;
|
|
2251
2287
|
var MAX_RESULTS = 50;
|
|
2252
2288
|
var TIMEOUT_MS3 = 15e3;
|
|
@@ -2279,7 +2315,9 @@ var searchTool = {
|
|
|
2279
2315
|
},
|
|
2280
2316
|
async execute(input, ctx, opts) {
|
|
2281
2317
|
let final;
|
|
2282
|
-
|
|
2318
|
+
const executeStream = searchTool.executeStream;
|
|
2319
|
+
if (!executeStream) throw new Error("searchTool: stream execution unavailable");
|
|
2320
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
2283
2321
|
if (ev.type === "final") final = ev.output;
|
|
2284
2322
|
}
|
|
2285
2323
|
if (!final) throw new Error("search: stream ended without final event");
|
|
@@ -2340,11 +2378,11 @@ function parseDuckDuckGo(html, num) {
|
|
|
2340
2378
|
const snippetRegex = /<a class="result-link"[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>/gi;
|
|
2341
2379
|
const snippet2Regex = /<a class="result-snippet"[^>]*>([^<]+)<\/a>/gi;
|
|
2342
2380
|
const linkMatches = takeFrom(
|
|
2343
|
-
[...html.matchAll(snippetRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: m[1], title: stripTags2(m[2]) })),
|
|
2381
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined5(m[1]), title: stripTags2(expectDefined5(m[2])) })),
|
|
2344
2382
|
num
|
|
2345
2383
|
);
|
|
2346
2384
|
const snippetMatches = takeFrom(
|
|
2347
|
-
[...html.matchAll(snippet2Regex)].filter((m) => m[1]).map((m) => stripTags2(m[1])),
|
|
2385
|
+
[...html.matchAll(snippet2Regex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined5(m[1]))),
|
|
2348
2386
|
num
|
|
2349
2387
|
);
|
|
2350
2388
|
for (let i = 0; i < linkMatches.length && i < num; i++) {
|
|
@@ -2375,15 +2413,15 @@ function parseGoogleResults(html, num) {
|
|
|
2375
2413
|
const urlRegex = /<cite[^>]*>([^<]+)<\/cite>/gi;
|
|
2376
2414
|
const snippetRegex = /<span[^>]*class="[^"]*aXCZ0b[^>]*>([^<]+)<\/span>/gi;
|
|
2377
2415
|
const titles = takeFrom(
|
|
2378
|
-
[...html.matchAll(titleRegex)].filter((m) => m[1]).map((m) => stripTags2(m[1])),
|
|
2416
|
+
[...html.matchAll(titleRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined5(m[1]))),
|
|
2379
2417
|
num
|
|
2380
2418
|
);
|
|
2381
2419
|
const urls = takeFrom(
|
|
2382
|
-
[...html.matchAll(urlRegex)].filter((m) => m[1]).map((m) => stripTags2(m[1]).replace(/^\*(https?:\/\/[^\s]+).*$/, "$1")).filter((u) => u.startsWith("http")),
|
|
2420
|
+
[...html.matchAll(urlRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined5(m[1])).replace(/^\*(https?:\/\/[^\s]+).*$/, "$1")).filter((u) => u.startsWith("http")),
|
|
2383
2421
|
num
|
|
2384
2422
|
);
|
|
2385
2423
|
const snippets = takeFrom(
|
|
2386
|
-
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(m[1])),
|
|
2424
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined5(m[1]))),
|
|
2387
2425
|
num
|
|
2388
2426
|
);
|
|
2389
2427
|
for (let i = 0; i < Math.min(titles.length, num); i++) {
|
|
@@ -2412,11 +2450,11 @@ function parseBingResults(html, num) {
|
|
|
2412
2450
|
const titleRegex = /<h2[^>]*>\s*<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>\s*<\/h2>/gi;
|
|
2413
2451
|
const snippetRegex = /<p[^>]*class="[^"]*b_paractl[^"]*"[^>]*>([^<]+)<\/p>/gi;
|
|
2414
2452
|
const entries = takeFrom(
|
|
2415
|
-
[...html.matchAll(titleRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: m[1], title: stripTags2(m[2]) })),
|
|
2453
|
+
[...html.matchAll(titleRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined5(m[1]), title: stripTags2(expectDefined5(m[2])) })),
|
|
2416
2454
|
num
|
|
2417
2455
|
);
|
|
2418
2456
|
const snippets = takeFrom(
|
|
2419
|
-
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(m[1])),
|
|
2457
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined5(m[1]))),
|
|
2420
2458
|
num
|
|
2421
2459
|
);
|
|
2422
2460
|
for (let i = 0; i < entries.length; i++) {
|
|
@@ -2463,9 +2501,10 @@ var todoTool = {
|
|
|
2463
2501
|
name: "todo",
|
|
2464
2502
|
category: "Session",
|
|
2465
2503
|
description: "Manage the session-level todo list. This is the primary mechanism for tracking multi-step work. The list is fully replaced on every call (not appended).",
|
|
2466
|
-
usageHint: "BEST PRACTICE for complex tasks:\n- At the beginning of a non-trivial task, create a clear todo list with specific, actionable items.\n- Only **one** item should be `in_progress` at any time.\n- Update the list frequently as work progresses (mark items done, add new ones, change status).\n- The system and user can see this list, so keep it honest and up-to-date.\nThis tool is extremely valuable for maintaining focus and giving the user visibility into your plan.",
|
|
2504
|
+
usageHint: "BEST PRACTICE for complex tasks:\n- At the beginning of a non-trivial task, create a clear todo list with specific, actionable items.\n- Only **one** item should be `in_progress` at any time.\n- Update the list frequently as work progresses (mark items done, add new ones, change status).\n- **Re-order items** to reflect current priorities \u2014 the full list is replaced each call, so item order is entirely under your control.\n- When all items are completed the board auto-clears \u2014 you do NOT need to send an empty list.\n- The system and user can see this list, so keep it honest and up-to-date.\nThis tool is extremely valuable for maintaining focus and giving the user visibility into your plan.",
|
|
2467
2505
|
permission: "auto",
|
|
2468
2506
|
mutating: false,
|
|
2507
|
+
// mutates only conversation state (ctx.todos), not external state — no confirmation needed
|
|
2469
2508
|
timeoutMs: 1e3,
|
|
2470
2509
|
inputSchema: {
|
|
2471
2510
|
type: "object",
|
|
@@ -2677,14 +2716,15 @@ var planTool = {
|
|
|
2677
2716
|
};
|
|
2678
2717
|
function mkResult(plan, ok, message, todos) {
|
|
2679
2718
|
const open = plan.items.filter((i) => i.status !== "done").length;
|
|
2680
|
-
|
|
2719
|
+
const result = {
|
|
2681
2720
|
ok,
|
|
2682
2721
|
message,
|
|
2683
2722
|
plan: formatPlan(plan),
|
|
2684
2723
|
count: plan.items.length,
|
|
2685
|
-
open
|
|
2686
|
-
todos
|
|
2724
|
+
open
|
|
2687
2725
|
};
|
|
2726
|
+
if (todos !== void 0) result.todos = todos;
|
|
2727
|
+
return result;
|
|
2688
2728
|
}
|
|
2689
2729
|
var TIMEOUT_MS4 = 3e4;
|
|
2690
2730
|
var MAX_OUTPUT3 = 1e5;
|
|
@@ -3305,6 +3345,12 @@ function formatWithLineNumbers(file, lines) {
|
|
|
3305
3345
|
return `--- ${file} (line-numbered dump, not a unified diff) ---
|
|
3306
3346
|
${numbered}`;
|
|
3307
3347
|
}
|
|
3348
|
+
function expectDefined6(value) {
|
|
3349
|
+
if (value === null || value === void 0) {
|
|
3350
|
+
throw new Error("Expected value to be defined");
|
|
3351
|
+
}
|
|
3352
|
+
return value;
|
|
3353
|
+
}
|
|
3308
3354
|
var DEFAULT_IGNORE4 = [
|
|
3309
3355
|
"node_modules",
|
|
3310
3356
|
".git",
|
|
@@ -3365,7 +3411,9 @@ var treeTool = {
|
|
|
3365
3411
|
},
|
|
3366
3412
|
async execute(input, ctx, opts) {
|
|
3367
3413
|
let final;
|
|
3368
|
-
|
|
3414
|
+
const executeStream = treeTool.executeStream;
|
|
3415
|
+
if (!executeStream) throw new Error("treeTool: stream execution unavailable");
|
|
3416
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
3369
3417
|
if (ev.type === "final") final = ev.output;
|
|
3370
3418
|
}
|
|
3371
3419
|
if (!final) throw new Error("tree: stream ended without final event");
|
|
@@ -3415,7 +3463,7 @@ var treeTool = {
|
|
|
3415
3463
|
});
|
|
3416
3464
|
while (!walkDone || queue.length > 0) {
|
|
3417
3465
|
if (queue.length > 0) {
|
|
3418
|
-
yield queue.shift();
|
|
3466
|
+
yield expectDefined6(queue.shift());
|
|
3419
3467
|
} else {
|
|
3420
3468
|
let pollTimer;
|
|
3421
3469
|
const poll = new Promise((r) => {
|
|
@@ -3480,6 +3528,12 @@ async function walkDir(dir, depth, opts) {
|
|
|
3480
3528
|
}
|
|
3481
3529
|
}
|
|
3482
3530
|
}
|
|
3531
|
+
function expectDefined7(value) {
|
|
3532
|
+
if (value === null || value === void 0) {
|
|
3533
|
+
throw new Error("Expected value to be defined");
|
|
3534
|
+
}
|
|
3535
|
+
return value;
|
|
3536
|
+
}
|
|
3483
3537
|
async function* spawnStream(opts) {
|
|
3484
3538
|
const max = opts.maxBytes ?? 2e5;
|
|
3485
3539
|
const flushAt = opts.flushBytes ?? 4 * 1024;
|
|
@@ -3531,7 +3585,7 @@ async function* spawnStream(opts) {
|
|
|
3531
3585
|
waiter = resolve7;
|
|
3532
3586
|
});
|
|
3533
3587
|
}
|
|
3534
|
-
const chunk = queue.shift();
|
|
3588
|
+
const chunk = expectDefined7(queue.shift());
|
|
3535
3589
|
if (chunk.kind === "close") {
|
|
3536
3590
|
if (!spawnFailed) exitCode = chunk.code ?? 0;
|
|
3537
3591
|
break;
|
|
@@ -3586,7 +3640,9 @@ var lintTool = {
|
|
|
3586
3640
|
},
|
|
3587
3641
|
async execute(input, ctx, opts) {
|
|
3588
3642
|
let final;
|
|
3589
|
-
|
|
3643
|
+
const executeStream = lintTool.executeStream;
|
|
3644
|
+
if (!executeStream) throw new Error("lintTool: stream execution unavailable");
|
|
3645
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
3590
3646
|
if (ev.type === "final") final = ev.output;
|
|
3591
3647
|
}
|
|
3592
3648
|
if (!final) throw new Error("lint: stream ended without final event");
|
|
@@ -3682,7 +3738,9 @@ var formatTool = {
|
|
|
3682
3738
|
},
|
|
3683
3739
|
async execute(input, ctx, opts) {
|
|
3684
3740
|
let final;
|
|
3685
|
-
|
|
3741
|
+
const executeStream = formatTool.executeStream;
|
|
3742
|
+
if (!executeStream) throw new Error("formatTool: stream execution unavailable");
|
|
3743
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
3686
3744
|
if (ev.type === "final") final = ev.output;
|
|
3687
3745
|
}
|
|
3688
3746
|
if (!final) throw new Error("format: stream ended without final event");
|
|
@@ -3775,7 +3833,9 @@ var typecheckTool = {
|
|
|
3775
3833
|
},
|
|
3776
3834
|
async execute(input, ctx, opts) {
|
|
3777
3835
|
let final;
|
|
3778
|
-
|
|
3836
|
+
const executeStream = typecheckTool.executeStream;
|
|
3837
|
+
if (!executeStream) throw new Error("typecheckTool: stream execution unavailable");
|
|
3838
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
3779
3839
|
if (ev.type === "final") final = ev.output;
|
|
3780
3840
|
}
|
|
3781
3841
|
if (!final) throw new Error("typecheck: stream ended without final event");
|
|
@@ -3859,7 +3919,9 @@ var testTool = {
|
|
|
3859
3919
|
},
|
|
3860
3920
|
async execute(input, ctx, opts) {
|
|
3861
3921
|
let final;
|
|
3862
|
-
|
|
3922
|
+
const executeStream = testTool.executeStream;
|
|
3923
|
+
if (!executeStream) throw new Error("testTool: stream execution unavailable");
|
|
3924
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
3863
3925
|
if (ev.type === "final") final = ev.output;
|
|
3864
3926
|
}
|
|
3865
3927
|
if (!final) throw new Error("test: stream ended without final event");
|
|
@@ -4016,7 +4078,9 @@ var installTool = {
|
|
|
4016
4078
|
},
|
|
4017
4079
|
async execute(input, ctx, opts) {
|
|
4018
4080
|
let final;
|
|
4019
|
-
|
|
4081
|
+
const executeStream = installTool.executeStream;
|
|
4082
|
+
if (!executeStream) throw new Error("installTool: stream execution unavailable");
|
|
4083
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
4020
4084
|
if (ev.type === "final") final = ev.output;
|
|
4021
4085
|
}
|
|
4022
4086
|
if (!final) throw new Error("install: stream ended without final event");
|
|
@@ -4107,7 +4171,9 @@ var auditTool = {
|
|
|
4107
4171
|
},
|
|
4108
4172
|
async execute(input, ctx, opts) {
|
|
4109
4173
|
let final;
|
|
4110
|
-
|
|
4174
|
+
const executeStream = auditTool.executeStream;
|
|
4175
|
+
if (!executeStream) throw new Error("auditTool: stream execution unavailable");
|
|
4176
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
4111
4177
|
if (ev.type === "final") final = ev.output;
|
|
4112
4178
|
}
|
|
4113
4179
|
if (!final) throw new Error("audit: stream ended without final event");
|
|
@@ -5360,6 +5426,12 @@ function lspKindToInternalKind(k) {
|
|
|
5360
5426
|
}
|
|
5361
5427
|
|
|
5362
5428
|
// src/codebase-index/writer.ts
|
|
5429
|
+
function expectDefined8(value) {
|
|
5430
|
+
if (value === null || value === void 0) {
|
|
5431
|
+
throw new Error("Expected value to be defined");
|
|
5432
|
+
}
|
|
5433
|
+
return value;
|
|
5434
|
+
}
|
|
5363
5435
|
var DB_FILE = "index.db";
|
|
5364
5436
|
function resolveIndexDir(projectRoot, override) {
|
|
5365
5437
|
return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
|
|
@@ -5504,7 +5576,7 @@ var IndexStore = class {
|
|
|
5504
5576
|
"SELECT file, lang, mtime_ms, symbol_count, last_indexed FROM files WHERE file = ?"
|
|
5505
5577
|
).all(file);
|
|
5506
5578
|
if (!rows.length) return null;
|
|
5507
|
-
const r = rows[0];
|
|
5579
|
+
const r = expectDefined8(rows[0]);
|
|
5508
5580
|
return { file: r.file, lang: r.lang, mtimeMs: r.mtime_ms, symbolCount: r.symbol_count, lastIndexed: r.last_indexed };
|
|
5509
5581
|
}
|
|
5510
5582
|
getAllFileMetas() {
|
|
@@ -5586,7 +5658,7 @@ var IndexStore = class {
|
|
|
5586
5658
|
const lastRows = this.db.prepare(
|
|
5587
5659
|
"SELECT value FROM metadata WHERE key = 'last_indexed'"
|
|
5588
5660
|
).all();
|
|
5589
|
-
const lastIndexed = lastRows.length ? Number(lastRows[0]
|
|
5661
|
+
const lastIndexed = lastRows.length ? Number(lastRows[0]?.value) : null;
|
|
5590
5662
|
const totalRows = this.db.prepare("SELECT COUNT(*) FROM symbols").all();
|
|
5591
5663
|
const totalSymbols = totalRows[0] ? Number(totalRows[0]["COUNT(*)"]) : 0;
|
|
5592
5664
|
const fileRows = this.db.prepare("SELECT COUNT(*) FROM files").all();
|
|
@@ -5661,8 +5733,9 @@ var IndexStore = class {
|
|
|
5661
5733
|
let resolved = 0;
|
|
5662
5734
|
for (const row of unresolved) {
|
|
5663
5735
|
const target = this.db.prepare("SELECT id FROM symbols WHERE name = ? LIMIT 1").all(row.to_name);
|
|
5664
|
-
|
|
5665
|
-
|
|
5736
|
+
const first = target[0];
|
|
5737
|
+
if (first) {
|
|
5738
|
+
this.db.prepare("UPDATE refs SET to_id = ? WHERE id = ?").run(first.id, row.id);
|
|
5666
5739
|
resolved++;
|
|
5667
5740
|
}
|
|
5668
5741
|
}
|
|
@@ -6416,6 +6489,12 @@ function syncPyParse(filePath, lang) {
|
|
|
6416
6489
|
return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
|
|
6417
6490
|
}
|
|
6418
6491
|
}
|
|
6492
|
+
function expectDefined9(value) {
|
|
6493
|
+
if (value === null || value === void 0) {
|
|
6494
|
+
throw new Error("Expected value to be defined");
|
|
6495
|
+
}
|
|
6496
|
+
return value;
|
|
6497
|
+
}
|
|
6419
6498
|
function parseSymbols4(opts) {
|
|
6420
6499
|
const { file, content, lang } = opts;
|
|
6421
6500
|
const nativeAvailable = checkNativeParser();
|
|
@@ -6497,14 +6576,14 @@ function regexParse(opts) {
|
|
|
6497
6576
|
const lines = content.split("\n");
|
|
6498
6577
|
const lineOffsets = [0];
|
|
6499
6578
|
for (let i = 0; i < lines.length; i++) {
|
|
6500
|
-
lineOffsets.push(lineOffsets[i] + lines[i]
|
|
6579
|
+
lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);
|
|
6501
6580
|
}
|
|
6502
6581
|
function lineFromOffset(offset) {
|
|
6503
6582
|
let lo = 0;
|
|
6504
6583
|
let hi = lineOffsets.length - 1;
|
|
6505
6584
|
while (lo < hi) {
|
|
6506
6585
|
const mid = lo + hi + 1 >>> 1;
|
|
6507
|
-
if (lineOffsets[mid] <= offset) lo = mid;
|
|
6586
|
+
if (expectDefined9(lineOffsets[mid]) <= offset) lo = mid;
|
|
6508
6587
|
else hi = mid - 1;
|
|
6509
6588
|
}
|
|
6510
6589
|
return lo + 1;
|
|
@@ -6516,8 +6595,8 @@ function regexParse(opts) {
|
|
|
6516
6595
|
for (const pattern of RS_PATTERNS) {
|
|
6517
6596
|
pattern.regex.lastIndex = 0;
|
|
6518
6597
|
for (let match = pattern.regex.exec(content); match !== null; match = pattern.regex.exec(content)) {
|
|
6519
|
-
const name = match[1];
|
|
6520
|
-
const offset = match.index;
|
|
6598
|
+
const name = expectDefined9(match[1]);
|
|
6599
|
+
const offset = match.index ?? 0;
|
|
6521
6600
|
const line = lineFromOffset(offset);
|
|
6522
6601
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
6523
6602
|
const lineIdx = line - 1;
|
|
@@ -6546,6 +6625,12 @@ function regexParse(opts) {
|
|
|
6546
6625
|
});
|
|
6547
6626
|
return { file, lang, symbols: deduped, mtimeMs: Date.now() };
|
|
6548
6627
|
}
|
|
6628
|
+
function expectDefined10(value) {
|
|
6629
|
+
if (value === null || value === void 0) {
|
|
6630
|
+
throw new Error("Expected value to be defined");
|
|
6631
|
+
}
|
|
6632
|
+
return value;
|
|
6633
|
+
}
|
|
6549
6634
|
function parseSymbols5(opts) {
|
|
6550
6635
|
const { file, content, lang } = opts;
|
|
6551
6636
|
try {
|
|
@@ -6565,21 +6650,21 @@ function regexParse2(opts) {
|
|
|
6565
6650
|
const lines = content.split("\n");
|
|
6566
6651
|
const lineOffsets = [0];
|
|
6567
6652
|
for (let i = 0; i < lines.length; i++) {
|
|
6568
|
-
lineOffsets.push(lineOffsets[i] + lines[i]
|
|
6653
|
+
lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);
|
|
6569
6654
|
}
|
|
6570
6655
|
function lineFromOffset(offset) {
|
|
6571
6656
|
let lo = 0;
|
|
6572
6657
|
let hi = lineOffsets.length - 1;
|
|
6573
6658
|
while (lo < hi) {
|
|
6574
6659
|
const mid = lo + hi + 1 >>> 1;
|
|
6575
|
-
if (lineOffsets[mid] <= offset) lo = mid;
|
|
6660
|
+
if (expectDefined10(lineOffsets[mid]) <= offset) lo = mid;
|
|
6576
6661
|
else hi = mid - 1;
|
|
6577
6662
|
}
|
|
6578
6663
|
return lo + 1;
|
|
6579
6664
|
}
|
|
6580
6665
|
const rootMatch = content.match(/^\s*\{/m);
|
|
6581
6666
|
if (rootMatch) {
|
|
6582
|
-
const offset = rootMatch.index;
|
|
6667
|
+
const offset = expectDefined10(rootMatch.index);
|
|
6583
6668
|
const line = lineFromOffset(offset);
|
|
6584
6669
|
symbols.push(
|
|
6585
6670
|
makeSymbol({
|
|
@@ -6595,8 +6680,8 @@ function regexParse2(opts) {
|
|
|
6595
6680
|
}
|
|
6596
6681
|
const topLevelKeyRegex = /^\s*"([^"]+)"\s*:/gm;
|
|
6597
6682
|
for (let match = topLevelKeyRegex.exec(content); match !== null; match = topLevelKeyRegex.exec(content)) {
|
|
6598
|
-
const key = match[1];
|
|
6599
|
-
const offset = match.index;
|
|
6683
|
+
const key = expectDefined10(match[1]);
|
|
6684
|
+
const offset = match.index ?? 0;
|
|
6600
6685
|
const line = lineFromOffset(offset);
|
|
6601
6686
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
6602
6687
|
let kind = "property";
|
|
@@ -6642,7 +6727,7 @@ function regexParse2(opts) {
|
|
|
6642
6727
|
const defsRegex = /"\$defs"\s*:|"\$defs"\s*:/g;
|
|
6643
6728
|
const defsMatch = defsRegex.exec(content);
|
|
6644
6729
|
if (defsMatch !== null) {
|
|
6645
|
-
const offset = defsMatch.index;
|
|
6730
|
+
const offset = expectDefined10(defsMatch.index);
|
|
6646
6731
|
const line = lineFromOffset(offset);
|
|
6647
6732
|
symbols.push(
|
|
6648
6733
|
makeSymbol({
|
|
@@ -6665,9 +6750,9 @@ function regexParse2(opts) {
|
|
|
6665
6750
|
for (const pat of defsPatterns) {
|
|
6666
6751
|
pat.lastIndex = 0;
|
|
6667
6752
|
for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {
|
|
6668
|
-
const offset = match.index;
|
|
6753
|
+
const offset = match.index ?? 0;
|
|
6669
6754
|
const line = lineFromOffset(offset);
|
|
6670
|
-
const key = match[0]
|
|
6755
|
+
const key = match[0]?.match(/"([^"]+)"/)?.[1] ?? expectDefined10(match[0]);
|
|
6671
6756
|
symbols.push(
|
|
6672
6757
|
makeSymbol({
|
|
6673
6758
|
name: key,
|
|
@@ -6686,12 +6771,12 @@ function regexParse2(opts) {
|
|
|
6686
6771
|
function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset) {
|
|
6687
6772
|
const scriptsBlockRegex = /"scripts"\s*:\s*\{([^}]+)\}/g;
|
|
6688
6773
|
for (let match = scriptsBlockRegex.exec(content); match !== null; match = scriptsBlockRegex.exec(content)) {
|
|
6689
|
-
const blockContent = match[0];
|
|
6690
|
-
const blockOffset = match.index;
|
|
6774
|
+
const blockContent = expectDefined10(match[0]);
|
|
6775
|
+
const blockOffset = match.index ?? 0;
|
|
6691
6776
|
const scriptKeyRegex = /"(\w[\w-]*)"\s*:/g;
|
|
6692
6777
|
for (let scriptMatch = scriptKeyRegex.exec(blockContent); scriptMatch !== null; scriptMatch = scriptKeyRegex.exec(blockContent)) {
|
|
6693
|
-
const key = scriptMatch[1];
|
|
6694
|
-
const keyOffset = blockOffset + scriptMatch.index;
|
|
6778
|
+
const key = expectDefined10(scriptMatch[1]);
|
|
6779
|
+
const keyOffset = blockOffset + expectDefined10(scriptMatch.index);
|
|
6695
6780
|
const line = lineFromOffset(keyOffset);
|
|
6696
6781
|
symbols.push(
|
|
6697
6782
|
makeSymbol({
|
|
@@ -6710,12 +6795,12 @@ function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFr
|
|
|
6710
6795
|
function extractCompilerOptions(content, symbols, file, lang, lineOffsets, parentLine, lineFromOffset) {
|
|
6711
6796
|
const optsBlockRegex = /"compilerOptions"\s*:\s*\{([^}]+)\}/g;
|
|
6712
6797
|
for (let match = optsBlockRegex.exec(content); match !== null; match = optsBlockRegex.exec(content)) {
|
|
6713
|
-
const blockContent = match[0];
|
|
6714
|
-
const blockOffset = match.index;
|
|
6798
|
+
const blockContent = expectDefined10(match[0]);
|
|
6799
|
+
const blockOffset = match.index ?? 0;
|
|
6715
6800
|
const optKeyRegex = /"(\w[\w]*)"\s*:/g;
|
|
6716
6801
|
for (let optMatch = optKeyRegex.exec(blockContent); optMatch !== null; optMatch = optKeyRegex.exec(blockContent)) {
|
|
6717
|
-
const key = optMatch[1];
|
|
6718
|
-
const keyOffset = blockOffset + optMatch.index;
|
|
6802
|
+
const key = expectDefined10(optMatch[1]);
|
|
6803
|
+
const keyOffset = blockOffset + expectDefined10(optMatch.index);
|
|
6719
6804
|
const line = lineFromOffset(keyOffset);
|
|
6720
6805
|
if (line <= parentLine) continue;
|
|
6721
6806
|
symbols.push(
|
|
@@ -6749,6 +6834,12 @@ function makeSymbol(opts) {
|
|
|
6749
6834
|
}
|
|
6750
6835
|
|
|
6751
6836
|
// src/codebase-index/yaml-parser.ts
|
|
6837
|
+
function expectDefined11(value) {
|
|
6838
|
+
if (value === null || value === void 0) {
|
|
6839
|
+
throw new Error("Expected value to be defined");
|
|
6840
|
+
}
|
|
6841
|
+
return value;
|
|
6842
|
+
}
|
|
6752
6843
|
function parseSymbols6(opts) {
|
|
6753
6844
|
const { file, content, lang } = opts;
|
|
6754
6845
|
try {
|
|
@@ -6763,22 +6854,22 @@ function regexParse3(opts) {
|
|
|
6763
6854
|
const lines = content.split("\n");
|
|
6764
6855
|
const lineOffsets = [0];
|
|
6765
6856
|
for (let i = 0; i < lines.length; i++) {
|
|
6766
|
-
lineOffsets.push(lineOffsets[i] + lines[i]
|
|
6857
|
+
lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);
|
|
6767
6858
|
}
|
|
6768
6859
|
function lineFromOffset(offset) {
|
|
6769
6860
|
let lo = 0;
|
|
6770
6861
|
let hi = lineOffsets.length - 1;
|
|
6771
6862
|
while (lo < hi) {
|
|
6772
6863
|
const mid = lo + hi + 1 >>> 1;
|
|
6773
|
-
if (lineOffsets[mid] <= offset) lo = mid;
|
|
6864
|
+
if (expectDefined11(lineOffsets[mid]) <= offset) lo = mid;
|
|
6774
6865
|
else hi = mid - 1;
|
|
6775
6866
|
}
|
|
6776
6867
|
return lo + 1;
|
|
6777
6868
|
}
|
|
6778
6869
|
const anchorRegex = /&(\w[\w-]*)/g;
|
|
6779
6870
|
for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {
|
|
6780
|
-
const name = match[1];
|
|
6781
|
-
const offset = match.index;
|
|
6871
|
+
const name = expectDefined11(match[1]);
|
|
6872
|
+
const offset = match.index ?? 0;
|
|
6782
6873
|
const line = lineFromOffset(offset);
|
|
6783
6874
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
6784
6875
|
symbols.push(
|
|
@@ -6795,8 +6886,8 @@ function regexParse3(opts) {
|
|
|
6795
6886
|
}
|
|
6796
6887
|
const aliasRegex = /\*(\w[\w-]*)/g;
|
|
6797
6888
|
for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {
|
|
6798
|
-
const name = match[1];
|
|
6799
|
-
const offset = match.index;
|
|
6889
|
+
const name = expectDefined11(match[1]);
|
|
6890
|
+
const offset = match.index ?? 0;
|
|
6800
6891
|
const line = lineFromOffset(offset);
|
|
6801
6892
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
6802
6893
|
symbols.push(
|
|
@@ -6813,27 +6904,28 @@ function regexParse3(opts) {
|
|
|
6813
6904
|
}
|
|
6814
6905
|
const kvRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:/gm;
|
|
6815
6906
|
for (let match = kvRegex.exec(content); match !== null; match = kvRegex.exec(content)) {
|
|
6816
|
-
const indent = match[1]
|
|
6907
|
+
const indent = match[1]?.length ?? 0;
|
|
6817
6908
|
const key = match[2];
|
|
6818
|
-
|
|
6909
|
+
if (!key) continue;
|
|
6910
|
+
const offset = match.index ?? 0;
|
|
6819
6911
|
const line = lineFromOffset(offset);
|
|
6820
6912
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
6821
6913
|
const lineContent = lines[line - 1] ?? "";
|
|
6822
6914
|
if (/^[|&>]/.test(lineContent.trim())) continue;
|
|
6823
6915
|
if (key === "---" || key === "...") continue;
|
|
6824
6916
|
if (indent > 12) continue;
|
|
6825
|
-
const value = extractValue(content, match.index);
|
|
6917
|
+
const value = extractValue(content, match.index ?? 0);
|
|
6826
6918
|
const kind = isScalar(value) ? "literal" : "property";
|
|
6827
6919
|
const signature = `${key}: ${truncate(value, 60)}`;
|
|
6828
6920
|
symbols.push(makeSymbol2({ name: key, kind, line, col, signature, file, lang }));
|
|
6829
6921
|
}
|
|
6830
6922
|
const listItemRegex = /^-(\s+)([^:#\s][^:#\s]*)\s*:/gm;
|
|
6831
6923
|
for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {
|
|
6832
|
-
const key = match[2];
|
|
6833
|
-
const offset = match.index;
|
|
6924
|
+
const key = expectDefined11(match[2]);
|
|
6925
|
+
const offset = match.index ?? 0;
|
|
6834
6926
|
const line = lineFromOffset(offset);
|
|
6835
6927
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
6836
|
-
const value = extractValue(content, offset + match[0]
|
|
6928
|
+
const value = extractValue(content, offset + match[0]?.length);
|
|
6837
6929
|
const kind = isScalar(value) ? "literal" : "property";
|
|
6838
6930
|
symbols.push(
|
|
6839
6931
|
makeSymbol2({
|
|
@@ -6849,8 +6941,8 @@ function regexParse3(opts) {
|
|
|
6849
6941
|
}
|
|
6850
6942
|
const blockScalarRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:\s*[|>](\s|$)/gm;
|
|
6851
6943
|
for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {
|
|
6852
|
-
const key = match[2];
|
|
6853
|
-
const offset = match.index;
|
|
6944
|
+
const key = expectDefined11(match[2]);
|
|
6945
|
+
const offset = match.index ?? 0;
|
|
6854
6946
|
const line = lineFromOffset(offset);
|
|
6855
6947
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
6856
6948
|
symbols.push(
|
|
@@ -6949,7 +7041,136 @@ async function loadGitignoreMatcher(projectRoot) {
|
|
|
6949
7041
|
return compileGitignore(lines);
|
|
6950
7042
|
}
|
|
6951
7043
|
|
|
7044
|
+
// src/codebase-index/background-indexer.ts
|
|
7045
|
+
var _ready = false;
|
|
7046
|
+
var _indexing = false;
|
|
7047
|
+
var _currentFile = 0;
|
|
7048
|
+
var _totalFiles = 0;
|
|
7049
|
+
var _lastError = null;
|
|
7050
|
+
function isIndexReady() {
|
|
7051
|
+
return _ready;
|
|
7052
|
+
}
|
|
7053
|
+
function setIndexReady() {
|
|
7054
|
+
_ready = true;
|
|
7055
|
+
}
|
|
7056
|
+
function isIndexing() {
|
|
7057
|
+
return _indexing;
|
|
7058
|
+
}
|
|
7059
|
+
function getIndexState() {
|
|
7060
|
+
return {
|
|
7061
|
+
ready: _ready,
|
|
7062
|
+
indexing: _indexing,
|
|
7063
|
+
currentFile: _currentFile,
|
|
7064
|
+
totalFiles: _totalFiles,
|
|
7065
|
+
lastError: _lastError
|
|
7066
|
+
};
|
|
7067
|
+
}
|
|
7068
|
+
var _listeners = [];
|
|
7069
|
+
function onIndexStateChange(listener) {
|
|
7070
|
+
_listeners.push(listener);
|
|
7071
|
+
return () => {
|
|
7072
|
+
_listeners = _listeners.filter((l) => l !== listener);
|
|
7073
|
+
};
|
|
7074
|
+
}
|
|
7075
|
+
function emitState() {
|
|
7076
|
+
const state = getIndexState();
|
|
7077
|
+
for (const l of _listeners) l(state);
|
|
7078
|
+
}
|
|
7079
|
+
function _setIndexProgress(current, total) {
|
|
7080
|
+
_currentFile = current;
|
|
7081
|
+
_totalFiles = total;
|
|
7082
|
+
emitState();
|
|
7083
|
+
}
|
|
7084
|
+
function stubCtx(projectRoot) {
|
|
7085
|
+
return {
|
|
7086
|
+
projectRoot,
|
|
7087
|
+
cwd: projectRoot,
|
|
7088
|
+
messages: [],
|
|
7089
|
+
todos: [],
|
|
7090
|
+
readFiles: /* @__PURE__ */ new Set(),
|
|
7091
|
+
fileMtimes: /* @__PURE__ */ new Map()
|
|
7092
|
+
};
|
|
7093
|
+
}
|
|
7094
|
+
var chain = Promise.resolve();
|
|
7095
|
+
function withMutex(job) {
|
|
7096
|
+
const run = chain.then(job, job);
|
|
7097
|
+
chain = run.then(
|
|
7098
|
+
() => void 0,
|
|
7099
|
+
() => void 0
|
|
7100
|
+
);
|
|
7101
|
+
return run;
|
|
7102
|
+
}
|
|
7103
|
+
var DEFAULT_DEBOUNCE_MS = 400;
|
|
7104
|
+
var debounceTimers = /* @__PURE__ */ new Map();
|
|
7105
|
+
function debounceKey(indexDir, file) {
|
|
7106
|
+
return `${indexDir ?? ""}|${file}`;
|
|
7107
|
+
}
|
|
7108
|
+
function isIndexableFile(filePath) {
|
|
7109
|
+
return detectLang(filePath) !== null;
|
|
7110
|
+
}
|
|
7111
|
+
async function runStartupIndex(opts) {
|
|
7112
|
+
_indexing = true;
|
|
7113
|
+
_currentFile = 0;
|
|
7114
|
+
_totalFiles = 0;
|
|
7115
|
+
_lastError = null;
|
|
7116
|
+
emitState();
|
|
7117
|
+
try {
|
|
7118
|
+
const result = await withMutex(
|
|
7119
|
+
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7120
|
+
projectRoot: opts.projectRoot,
|
|
7121
|
+
indexDir: opts.indexDir,
|
|
7122
|
+
force: opts.force
|
|
7123
|
+
})
|
|
7124
|
+
);
|
|
7125
|
+
_ready = true;
|
|
7126
|
+
return result;
|
|
7127
|
+
} catch (err) {
|
|
7128
|
+
_lastError = err instanceof Error ? err.message : String(err);
|
|
7129
|
+
_ready = true;
|
|
7130
|
+
throw err;
|
|
7131
|
+
} finally {
|
|
7132
|
+
_indexing = false;
|
|
7133
|
+
emitState();
|
|
7134
|
+
}
|
|
7135
|
+
}
|
|
7136
|
+
function enqueueReindex(opts) {
|
|
7137
|
+
const files = opts.files.filter(isIndexableFile);
|
|
7138
|
+
if (files.length === 0) return;
|
|
7139
|
+
const ms = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
7140
|
+
for (const file of files) {
|
|
7141
|
+
const key = debounceKey(opts.indexDir, file);
|
|
7142
|
+
const existing = debounceTimers.get(key);
|
|
7143
|
+
if (existing) clearTimeout(existing);
|
|
7144
|
+
const timer = setTimeout(() => {
|
|
7145
|
+
debounceTimers.delete(key);
|
|
7146
|
+
void withMutex(
|
|
7147
|
+
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7148
|
+
projectRoot: opts.projectRoot,
|
|
7149
|
+
files: [file],
|
|
7150
|
+
indexDir: opts.indexDir
|
|
7151
|
+
})
|
|
7152
|
+
).catch((err) => opts.onError?.(err));
|
|
7153
|
+
}, ms);
|
|
7154
|
+
timer.unref?.();
|
|
7155
|
+
debounceTimers.set(key, timer);
|
|
7156
|
+
}
|
|
7157
|
+
}
|
|
7158
|
+
function cancelPendingReindexes() {
|
|
7159
|
+
for (const t of debounceTimers.values()) clearTimeout(t);
|
|
7160
|
+
debounceTimers.clear();
|
|
7161
|
+
}
|
|
7162
|
+
|
|
6952
7163
|
// src/codebase-index/indexer.ts
|
|
7164
|
+
function expectDefined12(value) {
|
|
7165
|
+
if (value === null || value === void 0) {
|
|
7166
|
+
throw new Error("Expected value to be defined");
|
|
7167
|
+
}
|
|
7168
|
+
return value;
|
|
7169
|
+
}
|
|
7170
|
+
var YIELD_EVERY_N = 50;
|
|
7171
|
+
function yieldEventLoop() {
|
|
7172
|
+
return new Promise((resolve7) => setImmediate(resolve7));
|
|
7173
|
+
}
|
|
6953
7174
|
var DEFAULT_IGNORE5 = [
|
|
6954
7175
|
"node_modules",
|
|
6955
7176
|
".git",
|
|
@@ -7053,7 +7274,12 @@ async function runIndexer(_ctx, opts) {
|
|
|
7053
7274
|
if (!force) {
|
|
7054
7275
|
for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);
|
|
7055
7276
|
}
|
|
7056
|
-
for (
|
|
7277
|
+
for (let fi = 0; fi < files.length; fi++) {
|
|
7278
|
+
const file = expectDefined12(files[fi]);
|
|
7279
|
+
_setIndexProgress(fi + 1, files.length);
|
|
7280
|
+
if (fi > 0 && fi % YIELD_EVERY_N === 0) {
|
|
7281
|
+
await yieldEventLoop();
|
|
7282
|
+
}
|
|
7057
7283
|
let stat10;
|
|
7058
7284
|
try {
|
|
7059
7285
|
stat10 = await fs4.stat(file);
|
|
@@ -7106,7 +7332,7 @@ async function runIndexer(_ctx, opts) {
|
|
|
7106
7332
|
langStats[lang] = (langStats[lang] ?? 0) + count;
|
|
7107
7333
|
if (parsed.refs && parsed.refs.length > 0) {
|
|
7108
7334
|
for (let i = 0; i < symbolsWithIds.length; i++) {
|
|
7109
|
-
const sym = symbolsWithIds[i];
|
|
7335
|
+
const sym = expectDefined12(symbolsWithIds[i]);
|
|
7110
7336
|
const symRefs = parsed.refs.filter((r) => r.line === sym.line);
|
|
7111
7337
|
if (symRefs.length > 0) {
|
|
7112
7338
|
const refsWithFromId = symRefs.map((r) => ({ ...r, fromId: sym.id }));
|
|
@@ -7167,12 +7393,23 @@ var codebaseIndexTool = {
|
|
|
7167
7393
|
}
|
|
7168
7394
|
},
|
|
7169
7395
|
async execute(input, ctx) {
|
|
7396
|
+
if (isIndexing()) {
|
|
7397
|
+
return {
|
|
7398
|
+
filesIndexed: 0,
|
|
7399
|
+
symbolsIndexed: 0,
|
|
7400
|
+
langStats: {},
|
|
7401
|
+
durationMs: 0,
|
|
7402
|
+
errors: [],
|
|
7403
|
+
note: "A full index is already in progress. Retry codebase-index after it completes (check codebase-stats)."
|
|
7404
|
+
};
|
|
7405
|
+
}
|
|
7170
7406
|
const result = await runIndexer(ctx, {
|
|
7171
7407
|
projectRoot: ctx.projectRoot,
|
|
7172
7408
|
force: input.force ?? false,
|
|
7173
7409
|
langs: input.langs,
|
|
7174
7410
|
indexDir: codebaseIndexDirOverride(ctx)
|
|
7175
7411
|
});
|
|
7412
|
+
setIndexReady();
|
|
7176
7413
|
return result;
|
|
7177
7414
|
}
|
|
7178
7415
|
};
|
|
@@ -7266,6 +7503,12 @@ var Bm25Index = class {
|
|
|
7266
7503
|
};
|
|
7267
7504
|
|
|
7268
7505
|
// src/codebase-index/codebase-search-tool.ts
|
|
7506
|
+
function expectDefined13(value) {
|
|
7507
|
+
if (value === null || value === void 0) {
|
|
7508
|
+
throw new Error("Expected value to be defined");
|
|
7509
|
+
}
|
|
7510
|
+
return value;
|
|
7511
|
+
}
|
|
7269
7512
|
var codebaseSearchTool = {
|
|
7270
7513
|
name: "codebase-search",
|
|
7271
7514
|
category: "Project",
|
|
@@ -7308,6 +7551,31 @@ var codebaseSearchTool = {
|
|
|
7308
7551
|
required: ["query"]
|
|
7309
7552
|
},
|
|
7310
7553
|
async execute(input, ctx) {
|
|
7554
|
+
const state = getIndexState();
|
|
7555
|
+
if (!state.ready) {
|
|
7556
|
+
return {
|
|
7557
|
+
results: [],
|
|
7558
|
+
total: 0,
|
|
7559
|
+
query: input.query,
|
|
7560
|
+
indexStatus: state.indexing ? `Indexing in progress (${state.currentFile}/${state.totalFiles} files) \u2014 retry in a moment.` : "Index not yet built. The codebase is being indexed at startup \u2014 search will be available shortly."
|
|
7561
|
+
};
|
|
7562
|
+
}
|
|
7563
|
+
if (state.indexing) {
|
|
7564
|
+
return {
|
|
7565
|
+
results: [],
|
|
7566
|
+
total: 0,
|
|
7567
|
+
query: input.query,
|
|
7568
|
+
indexStatus: `Index refresh in progress (${state.currentFile}/${state.totalFiles} files). Results may be incomplete.`
|
|
7569
|
+
};
|
|
7570
|
+
}
|
|
7571
|
+
if (state.lastError) {
|
|
7572
|
+
return {
|
|
7573
|
+
results: [],
|
|
7574
|
+
total: 0,
|
|
7575
|
+
query: input.query,
|
|
7576
|
+
indexStatus: `Index build failed: ${state.lastError}. Try /codebase-reindex.`
|
|
7577
|
+
};
|
|
7578
|
+
}
|
|
7311
7579
|
const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
7312
7580
|
try {
|
|
7313
7581
|
const limit = Math.min(input.limit ?? 20, 100);
|
|
@@ -7330,7 +7598,7 @@ var codebaseSearchTool = {
|
|
|
7330
7598
|
const top = scored.slice(0, limit);
|
|
7331
7599
|
const qTokens = tokenise(input.query);
|
|
7332
7600
|
const results = top.map(({ id, score }) => {
|
|
7333
|
-
const c = candidates.find((c2) => c2.id === id);
|
|
7601
|
+
const c = expectDefined13(candidates.find((c2) => c2.id === id));
|
|
7334
7602
|
const snippet = bm25.extractSnippet(id, qTokens);
|
|
7335
7603
|
return {
|
|
7336
7604
|
...c,
|
|
@@ -7365,6 +7633,32 @@ var codebaseStatsTool = {
|
|
|
7365
7633
|
additionalProperties: false
|
|
7366
7634
|
},
|
|
7367
7635
|
async execute(_input, ctx) {
|
|
7636
|
+
const idxState = getIndexState();
|
|
7637
|
+
if (!idxState.ready) {
|
|
7638
|
+
return {
|
|
7639
|
+
totalSymbols: 0,
|
|
7640
|
+
totalFiles: 0,
|
|
7641
|
+
byLang: {},
|
|
7642
|
+
byKind: {},
|
|
7643
|
+
lastIndexed: null,
|
|
7644
|
+
sizeBytes: 0,
|
|
7645
|
+
indexPath: "",
|
|
7646
|
+
version: SCHEMA_VERSION,
|
|
7647
|
+
indexStatus: idxState.indexing ? `Indexing in progress (${idxState.currentFile}/${idxState.totalFiles} files).` : "Index not yet built."
|
|
7648
|
+
};
|
|
7649
|
+
}
|
|
7650
|
+
if (idxState.indexing) {
|
|
7651
|
+
const store2 = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
7652
|
+
try {
|
|
7653
|
+
const stats = store2.getStats();
|
|
7654
|
+
return {
|
|
7655
|
+
...stats,
|
|
7656
|
+
indexStatus: `Index refresh in progress (${idxState.currentFile}/${idxState.totalFiles} files). Stats may be incomplete.`
|
|
7657
|
+
};
|
|
7658
|
+
} finally {
|
|
7659
|
+
store2.close();
|
|
7660
|
+
}
|
|
7661
|
+
}
|
|
7368
7662
|
const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
7369
7663
|
try {
|
|
7370
7664
|
const stats = store.getStats();
|
|
@@ -7384,70 +7678,6 @@ var codebaseStatsTool = {
|
|
|
7384
7678
|
}
|
|
7385
7679
|
};
|
|
7386
7680
|
|
|
7387
|
-
// src/codebase-index/background-indexer.ts
|
|
7388
|
-
function stubCtx(projectRoot) {
|
|
7389
|
-
return {
|
|
7390
|
-
projectRoot,
|
|
7391
|
-
cwd: projectRoot,
|
|
7392
|
-
messages: [],
|
|
7393
|
-
todos: [],
|
|
7394
|
-
readFiles: /* @__PURE__ */ new Set(),
|
|
7395
|
-
fileMtimes: /* @__PURE__ */ new Map()
|
|
7396
|
-
};
|
|
7397
|
-
}
|
|
7398
|
-
var chain = Promise.resolve();
|
|
7399
|
-
function withMutex(job) {
|
|
7400
|
-
const run = chain.then(job, job);
|
|
7401
|
-
chain = run.then(
|
|
7402
|
-
() => void 0,
|
|
7403
|
-
() => void 0
|
|
7404
|
-
);
|
|
7405
|
-
return run;
|
|
7406
|
-
}
|
|
7407
|
-
var DEFAULT_DEBOUNCE_MS = 400;
|
|
7408
|
-
var debounceTimers = /* @__PURE__ */ new Map();
|
|
7409
|
-
function debounceKey(indexDir, file) {
|
|
7410
|
-
return `${indexDir ?? ""}|${file}`;
|
|
7411
|
-
}
|
|
7412
|
-
function isIndexableFile(filePath) {
|
|
7413
|
-
return detectLang(filePath) !== null;
|
|
7414
|
-
}
|
|
7415
|
-
function runStartupIndex(opts) {
|
|
7416
|
-
return withMutex(
|
|
7417
|
-
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7418
|
-
projectRoot: opts.projectRoot,
|
|
7419
|
-
indexDir: opts.indexDir,
|
|
7420
|
-
force: opts.force
|
|
7421
|
-
})
|
|
7422
|
-
);
|
|
7423
|
-
}
|
|
7424
|
-
function enqueueReindex(opts) {
|
|
7425
|
-
const files = opts.files.filter(isIndexableFile);
|
|
7426
|
-
if (files.length === 0) return;
|
|
7427
|
-
const ms = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
7428
|
-
for (const file of files) {
|
|
7429
|
-
const key = debounceKey(opts.indexDir, file);
|
|
7430
|
-
const existing = debounceTimers.get(key);
|
|
7431
|
-
if (existing) clearTimeout(existing);
|
|
7432
|
-
const timer = setTimeout(() => {
|
|
7433
|
-
debounceTimers.delete(key);
|
|
7434
|
-
void withMutex(
|
|
7435
|
-
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7436
|
-
projectRoot: opts.projectRoot,
|
|
7437
|
-
files: [file],
|
|
7438
|
-
indexDir: opts.indexDir
|
|
7439
|
-
})
|
|
7440
|
-
).catch((err) => opts.onError?.(err));
|
|
7441
|
-
}, ms);
|
|
7442
|
-
timer.unref?.();
|
|
7443
|
-
debounceTimers.set(key, timer);
|
|
7444
|
-
}
|
|
7445
|
-
}
|
|
7446
|
-
function cancelPendingReindexes() {
|
|
7447
|
-
for (const t of debounceTimers.values()) clearTimeout(t);
|
|
7448
|
-
debounceTimers.clear();
|
|
7449
|
-
}
|
|
7450
|
-
|
|
7451
7681
|
// src/builtin.ts
|
|
7452
7682
|
var builtinTools = [
|
|
7453
7683
|
readTool,
|
|
@@ -7493,6 +7723,6 @@ var builtinToolsPack = {
|
|
|
7493
7723
|
tools: builtinTools
|
|
7494
7724
|
};
|
|
7495
7725
|
|
|
7496
|
-
export { CircuitBreaker, _resetProcessRegistry, auditTool, bashTool, batchToolUseTool, builtinTools, builtinToolsPack, cancelPendingReindexes, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, createModeTool, diffTool, documentTool, editTool, enqueueReindex, execTool, fetchTool, forgetTool, formatTool, getProcessRegistry, gitTool, globTool, grepTool, installTool, isIndexableFile, jsonTool, lintTool, logsTool, outdatedTool, patchTool, planTool, readTool, rememberTool, replaceTool, runStartupIndex, scaffoldTool, searchTool, testTool, todoTool, toolHelpTool, toolSearchTool, toolUseTool, treeTool, typecheckTool, writeTool };
|
|
7726
|
+
export { CircuitBreaker, _resetProcessRegistry, auditTool, bashTool, batchToolUseTool, builtinTools, builtinToolsPack, cancelPendingReindexes, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, createModeTool, diffTool, documentTool, editTool, enqueueReindex, execTool, fetchTool, forgetTool, formatTool, getIndexState, getProcessRegistry, gitTool, globTool, grepTool, installTool, isIndexReady, isIndexableFile, isIndexing, jsonTool, lintTool, logsTool, onIndexStateChange, outdatedTool, patchTool, planTool, readTool, rememberTool, replaceTool, runStartupIndex, scaffoldTool, searchTool, testTool, todoTool, toolHelpTool, toolSearchTool, toolUseTool, treeTool, typecheckTool, writeTool };
|
|
7497
7727
|
//# sourceMappingURL=index.js.map
|
|
7498
7728
|
//# sourceMappingURL=index.js.map
|