@wrongstack/tools 0.89.1 → 0.89.3
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.js +1 -7
- package/dist/audit.js.map +1 -1
- package/dist/{background-indexer-DYm1FUxK.d.ts → background-indexer-C2014mH0.d.ts} +1 -1
- package/dist/bash.js +6 -18
- package/dist/bash.js.map +1 -1
- package/dist/builtin.js +45 -133
- package/dist/builtin.js.map +1 -1
- package/dist/circuit-breaker.js +1 -1
- package/dist/circuit-breaker.js.map +1 -1
- package/dist/codebase-index/index.d.ts +2 -21
- package/dist/codebase-index/index.js +25 -69
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/diff.js.map +1 -1
- package/dist/document.js +1 -1
- package/dist/document.js.map +1 -1
- package/dist/edit.js.map +1 -1
- package/dist/exec.js +3 -15
- package/dist/exec.js.map +1 -1
- package/dist/fetch.js.map +1 -1
- package/dist/format.js +4 -16
- package/dist/format.js.map +1 -1
- package/dist/git.js +1 -7
- package/dist/git.js.map +1 -1
- package/dist/glob.js.map +1 -1
- package/dist/grep.js +1 -7
- package/dist/grep.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +159 -136
- package/dist/index.js.map +1 -1
- package/dist/install.js +4 -16
- package/dist/install.js.map +1 -1
- package/dist/lint.js +4 -16
- package/dist/lint.js.map +1 -1
- package/dist/logs.js.map +1 -1
- package/dist/memory.d.ts +29 -1
- package/dist/memory.js +115 -4
- package/dist/memory.js.map +1 -1
- package/dist/outdated.js.map +1 -1
- package/dist/pack.js +45 -133
- package/dist/pack.js.map +1 -1
- package/dist/patch.js.map +1 -1
- package/dist/process-registry.js +2 -7
- package/dist/process-registry.js.map +1 -1
- package/dist/read.js +1 -1
- package/dist/read.js.map +1 -1
- package/dist/replace.js +1 -7
- package/dist/replace.js.map +1 -1
- package/dist/scaffold.js.map +1 -1
- package/dist/search.js +2 -7
- package/dist/search.js.map +1 -1
- package/dist/test.js +4 -16
- package/dist/test.js.map +1 -1
- package/dist/tree.js +1 -7
- package/dist/tree.js.map +1 -1
- package/dist/typecheck.js +4 -16
- package/dist/typecheck.js.map +1 -1
- package/dist/write.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
import * as fs4 from 'node:fs/promises';
|
|
2
|
+
import * as Core from '@wrongstack/core';
|
|
3
|
+
import { atomicWrite, unifiedDiff, detectNewlineStyle, normalizeToLf, toStyle, compileGlob, expectDefined, buildChildEnv, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, resolveWstackPaths } from '@wrongstack/core';
|
|
2
4
|
import * as path from 'node:path';
|
|
3
5
|
import { resolve, sep, dirname } from 'node:path';
|
|
4
|
-
import * as Core from '@wrongstack/core';
|
|
5
|
-
import { atomicWrite, unifiedDiff, detectNewlineStyle, normalizeToLf, toStyle, compileGlob, buildChildEnv, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, resolveWstackPaths } from '@wrongstack/core';
|
|
6
6
|
import { spawn, execFileSync, spawnSync } from 'node:child_process';
|
|
7
7
|
import * as os from 'node:os';
|
|
8
8
|
import * as dns from 'node:dns/promises';
|
|
9
9
|
import * as net from 'node:net';
|
|
10
10
|
import { Agent } from 'undici';
|
|
11
11
|
import * as fs13 from 'node:fs';
|
|
12
|
-
import { statSync,
|
|
12
|
+
import { statSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
14
14
|
import * as ts from 'typescript';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
18
|
-
}) : x)(function(x) {
|
|
19
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
20
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
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
|
-
}
|
|
16
|
+
// src/read.ts
|
|
28
17
|
async function detectPackageManager(cwd) {
|
|
29
18
|
const { stat: stat10 } = await import('node:fs/promises');
|
|
30
19
|
try {
|
|
@@ -472,12 +461,6 @@ function capSubject(line) {
|
|
|
472
461
|
}
|
|
473
462
|
|
|
474
463
|
// 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
|
-
}
|
|
481
464
|
var DEFAULT_IGNORE = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
482
465
|
var replaceTool = {
|
|
483
466
|
name: "replace",
|
|
@@ -557,8 +540,8 @@ var replaceTool = {
|
|
|
557
540
|
const count = matches.length;
|
|
558
541
|
let newContentLf = contentLf;
|
|
559
542
|
for (let i = matches.length - 1; i >= 0; i--) {
|
|
560
|
-
const m =
|
|
561
|
-
newContentLf = newContentLf.slice(0, m.index) + input.replacement + newContentLf.slice(
|
|
543
|
+
const m = expectDefined(matches[i]);
|
|
544
|
+
newContentLf = newContentLf.slice(0, m.index) + input.replacement + newContentLf.slice(expectDefined(m.index) + m[0].length);
|
|
562
545
|
}
|
|
563
546
|
re.lastIndex = 0;
|
|
564
547
|
totalReplacements += count;
|
|
@@ -759,12 +742,6 @@ async function readGitignore(dir) {
|
|
|
759
742
|
return [];
|
|
760
743
|
}
|
|
761
744
|
}
|
|
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
|
-
}
|
|
768
745
|
var DEFAULT_IGNORE3 = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
769
746
|
var grepTool = {
|
|
770
747
|
name: "grep",
|
|
@@ -906,7 +883,7 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
906
883
|
waiter = r;
|
|
907
884
|
});
|
|
908
885
|
}
|
|
909
|
-
const c =
|
|
886
|
+
const c = expectDefined(queue.shift());
|
|
910
887
|
if (c.kind === "error") {
|
|
911
888
|
errored = true;
|
|
912
889
|
continue;
|
|
@@ -1055,7 +1032,7 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
1055
1032
|
|
|
1056
1033
|
// src/circuit-breaker.ts
|
|
1057
1034
|
var DEFAULT_MAX_CONSECUTIVE_FAILURES = 5;
|
|
1058
|
-
var DEFAULT_SLOW_CALL_THRESHOLD_MS =
|
|
1035
|
+
var DEFAULT_SLOW_CALL_THRESHOLD_MS = 18e4;
|
|
1059
1036
|
var DEFAULT_MAX_SLOW_CALLS = 3;
|
|
1060
1037
|
var DEFAULT_WINDOW_MS = 6e4;
|
|
1061
1038
|
var DEFAULT_MAX_CALLS_PER_WINDOW = 30;
|
|
@@ -1198,12 +1175,6 @@ var CircuitBreaker = class {
|
|
|
1198
1175
|
};
|
|
1199
1176
|
|
|
1200
1177
|
// 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
|
-
}
|
|
1207
1178
|
var SENSITIVE_FLAG_PATTERNS = [
|
|
1208
1179
|
// --flag=value or --flag "value" (value captured up to next space or comma)
|
|
1209
1180
|
/--(?: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,
|
|
@@ -1224,7 +1195,7 @@ function redactCommand(cmd) {
|
|
|
1224
1195
|
const sp = match.search(/\s/);
|
|
1225
1196
|
const delim = eq !== -1 ? "=" : sp !== -1 ? match[sp] : null;
|
|
1226
1197
|
if (delim !== null) {
|
|
1227
|
-
const flag = match.slice(0, match.indexOf(
|
|
1198
|
+
const flag = match.slice(0, match.indexOf(expectDefined(delim)) + 1);
|
|
1228
1199
|
return `${flag}[REDACTED]`;
|
|
1229
1200
|
}
|
|
1230
1201
|
const flagEnd = match.match(/^--?[a-zA-Z][a-zA-Z0-9_-]*/)?.[0] ?? match;
|
|
@@ -1407,7 +1378,7 @@ function _resetProcessRegistry() {
|
|
|
1407
1378
|
|
|
1408
1379
|
// src/bash.ts
|
|
1409
1380
|
var MAX_OUTPUT = 32768;
|
|
1410
|
-
var DEFAULT_TIMEOUT_MS =
|
|
1381
|
+
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
1411
1382
|
var STREAM_FLUSH_INTERVAL_MS = 200;
|
|
1412
1383
|
var STREAM_FLUSH_BYTES = 4 * 1024;
|
|
1413
1384
|
var bashTool = {
|
|
@@ -1423,9 +1394,9 @@ var bashTool = {
|
|
|
1423
1394
|
// explicitly removes the implicit cross-tool aliasing.
|
|
1424
1395
|
subjectKey: "command",
|
|
1425
1396
|
capabilities: ["shell.arbitrary"],
|
|
1426
|
-
timeoutMs:
|
|
1397
|
+
timeoutMs: 3e5,
|
|
1427
1398
|
maxOutputBytes: MAX_OUTPUT,
|
|
1428
|
-
estimatedDurationMs:
|
|
1399
|
+
estimatedDurationMs: 3e4,
|
|
1429
1400
|
inputSchema: {
|
|
1430
1401
|
type: "object",
|
|
1431
1402
|
properties: {
|
|
@@ -2275,14 +2246,6 @@ function htmlToMarkdown(html) {
|
|
|
2275
2246
|
function stripTags(s) {
|
|
2276
2247
|
return s.replace(/<[^>]+>/g, "");
|
|
2277
2248
|
}
|
|
2278
|
-
|
|
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
|
-
}
|
|
2286
2249
|
var DEFAULT_NUM = 10;
|
|
2287
2250
|
var MAX_RESULTS = 50;
|
|
2288
2251
|
var TIMEOUT_MS2 = 15e3;
|
|
@@ -2378,11 +2341,11 @@ function parseDuckDuckGo(html, num) {
|
|
|
2378
2341
|
const snippetRegex = /<a class="result-link"[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>/gi;
|
|
2379
2342
|
const snippet2Regex = /<a class="result-snippet"[^>]*>([^<]+)<\/a>/gi;
|
|
2380
2343
|
const linkMatches = takeFrom(
|
|
2381
|
-
[...html.matchAll(snippetRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url:
|
|
2344
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined(m[1]), title: stripTags2(expectDefined(m[2])) })),
|
|
2382
2345
|
num
|
|
2383
2346
|
);
|
|
2384
2347
|
const snippetMatches = takeFrom(
|
|
2385
|
-
[...html.matchAll(snippet2Regex)].filter((m) => m[1]).map((m) => stripTags2(
|
|
2348
|
+
[...html.matchAll(snippet2Regex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
|
|
2386
2349
|
num
|
|
2387
2350
|
);
|
|
2388
2351
|
for (let i = 0; i < linkMatches.length && i < num; i++) {
|
|
@@ -2413,15 +2376,15 @@ function parseGoogleResults(html, num) {
|
|
|
2413
2376
|
const urlRegex = /<cite[^>]*>([^<]+)<\/cite>/gi;
|
|
2414
2377
|
const snippetRegex = /<span[^>]*class="[^"]*aXCZ0b[^>]*>([^<]+)<\/span>/gi;
|
|
2415
2378
|
const titles = takeFrom(
|
|
2416
|
-
[...html.matchAll(titleRegex)].filter((m) => m[1]).map((m) => stripTags2(
|
|
2379
|
+
[...html.matchAll(titleRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
|
|
2417
2380
|
num
|
|
2418
2381
|
);
|
|
2419
2382
|
const urls = takeFrom(
|
|
2420
|
-
[...html.matchAll(urlRegex)].filter((m) => m[1]).map((m) => stripTags2(
|
|
2383
|
+
[...html.matchAll(urlRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1])).replace(/^\*(https?:\/\/[^\s]+).*$/, "$1")).filter((u) => u.startsWith("http")),
|
|
2421
2384
|
num
|
|
2422
2385
|
);
|
|
2423
2386
|
const snippets = takeFrom(
|
|
2424
|
-
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(
|
|
2387
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
|
|
2425
2388
|
num
|
|
2426
2389
|
);
|
|
2427
2390
|
for (let i = 0; i < Math.min(titles.length, num); i++) {
|
|
@@ -2450,11 +2413,11 @@ function parseBingResults(html, num) {
|
|
|
2450
2413
|
const titleRegex = /<h2[^>]*>\s*<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>\s*<\/h2>/gi;
|
|
2451
2414
|
const snippetRegex = /<p[^>]*class="[^"]*b_paractl[^"]*"[^>]*>([^<]+)<\/p>/gi;
|
|
2452
2415
|
const entries = takeFrom(
|
|
2453
|
-
[...html.matchAll(titleRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url:
|
|
2416
|
+
[...html.matchAll(titleRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined(m[1]), title: stripTags2(expectDefined(m[2])) })),
|
|
2454
2417
|
num
|
|
2455
2418
|
);
|
|
2456
2419
|
const snippets = takeFrom(
|
|
2457
|
-
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(
|
|
2420
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
|
|
2458
2421
|
num
|
|
2459
2422
|
);
|
|
2460
2423
|
for (let i = 0; i < entries.length; i++) {
|
|
@@ -3358,12 +3321,6 @@ function formatWithLineNumbers(file, lines) {
|
|
|
3358
3321
|
return `--- ${file} (line-numbered dump, not a unified diff) ---
|
|
3359
3322
|
${numbered}`;
|
|
3360
3323
|
}
|
|
3361
|
-
function expectDefined6(value) {
|
|
3362
|
-
if (value === null || value === void 0) {
|
|
3363
|
-
throw new Error("Expected value to be defined");
|
|
3364
|
-
}
|
|
3365
|
-
return value;
|
|
3366
|
-
}
|
|
3367
3324
|
var DEFAULT_IGNORE4 = [
|
|
3368
3325
|
"node_modules",
|
|
3369
3326
|
".git",
|
|
@@ -3476,7 +3433,7 @@ var treeTool = {
|
|
|
3476
3433
|
});
|
|
3477
3434
|
while (!walkDone || queue.length > 0) {
|
|
3478
3435
|
if (queue.length > 0) {
|
|
3479
|
-
yield
|
|
3436
|
+
yield expectDefined(queue.shift());
|
|
3480
3437
|
} else {
|
|
3481
3438
|
let pollTimer;
|
|
3482
3439
|
const poll = new Promise((r) => {
|
|
@@ -3541,12 +3498,6 @@ async function walkDir(dir, depth, opts) {
|
|
|
3541
3498
|
}
|
|
3542
3499
|
}
|
|
3543
3500
|
}
|
|
3544
|
-
function expectDefined7(value) {
|
|
3545
|
-
if (value === null || value === void 0) {
|
|
3546
|
-
throw new Error("Expected value to be defined");
|
|
3547
|
-
}
|
|
3548
|
-
return value;
|
|
3549
|
-
}
|
|
3550
3501
|
async function* spawnStream(opts) {
|
|
3551
3502
|
const max = opts.maxBytes ?? 2e5;
|
|
3552
3503
|
const flushAt = opts.flushBytes ?? 4 * 1024;
|
|
@@ -3598,7 +3549,7 @@ async function* spawnStream(opts) {
|
|
|
3598
3549
|
waiter = resolve7;
|
|
3599
3550
|
});
|
|
3600
3551
|
}
|
|
3601
|
-
const chunk =
|
|
3552
|
+
const chunk = expectDefined(queue.shift());
|
|
3602
3553
|
if (chunk.kind === "close") {
|
|
3603
3554
|
if (!spawnFailed) exitCode = chunk.code ?? 0;
|
|
3604
3555
|
break;
|
|
@@ -5265,8 +5216,8 @@ function rememberTool(memory) {
|
|
|
5265
5216
|
return {
|
|
5266
5217
|
name: "remember",
|
|
5267
5218
|
category: "Session",
|
|
5268
|
-
description: "Persist
|
|
5269
|
-
usageHint:
|
|
5219
|
+
description: "Persist facts, conventions, decisions, and preferences into long-term memory. Memories survive restarts and are scored for relevance in future sessions.",
|
|
5220
|
+
usageHint: "Persist facts, conventions, decisions, and preferences into long-term memory.\n\nWHEN TO USE:\n- Project conventions discovered during a task (build tool, lint rules, code style)\n- Architecture decisions made (chose X over Y, decided to use pattern Z)\n- User preferences expressed (prefers short names, always uses pnpm)\n- Anti-patterns identified (never do X, avoid pattern Y)\n- File/location references useful across sessions\n\nWHEN NOT TO USE:\n- Temporary task state or progress \u2192 use `todo`\n- One-off debugging notes\n- Information already obvious from the codebase\n\nAlways include `type` and `priority`. Use 1-3 `tags` for grouping.\nBetter to remember a fact now than rediscover it next session.",
|
|
5270
5221
|
permission: "auto",
|
|
5271
5222
|
mutating: true,
|
|
5272
5223
|
timeoutMs: 2e3,
|
|
@@ -5281,6 +5232,21 @@ function rememberTool(memory) {
|
|
|
5281
5232
|
type: "string",
|
|
5282
5233
|
enum: ["project-agents", "project-memory", "user-memory"],
|
|
5283
5234
|
description: "Where to store it: project-memory (shared), user-memory (personal), or project-agents."
|
|
5235
|
+
},
|
|
5236
|
+
type: {
|
|
5237
|
+
type: "string",
|
|
5238
|
+
enum: ["fact", "decision", "convention", "preference", "reference", "anti_pattern"],
|
|
5239
|
+
description: "Category for filtering and relevance scoring."
|
|
5240
|
+
},
|
|
5241
|
+
tags: {
|
|
5242
|
+
type: "array",
|
|
5243
|
+
items: { type: "string" },
|
|
5244
|
+
description: "Hashtag-style tags for grouping and search."
|
|
5245
|
+
},
|
|
5246
|
+
priority: {
|
|
5247
|
+
type: "string",
|
|
5248
|
+
enum: ["critical", "high", "medium", "low"],
|
|
5249
|
+
description: "Priority level. Critical = always injected into context."
|
|
5284
5250
|
}
|
|
5285
5251
|
},
|
|
5286
5252
|
required: ["text"]
|
|
@@ -5288,7 +5254,11 @@ function rememberTool(memory) {
|
|
|
5288
5254
|
async execute(input) {
|
|
5289
5255
|
if (!input?.text) throw new Error("remember: text is required");
|
|
5290
5256
|
const scope = input.scope ?? "project-memory";
|
|
5291
|
-
await memory.remember(input.text, scope
|
|
5257
|
+
await memory.remember(input.text, scope, {
|
|
5258
|
+
type: input.type,
|
|
5259
|
+
tags: input.tags,
|
|
5260
|
+
priority: input.priority
|
|
5261
|
+
});
|
|
5292
5262
|
return { ok: true, scope };
|
|
5293
5263
|
}
|
|
5294
5264
|
};
|
|
@@ -5318,6 +5288,98 @@ function forgetTool(memory) {
|
|
|
5318
5288
|
}
|
|
5319
5289
|
};
|
|
5320
5290
|
}
|
|
5291
|
+
function searchMemoryTool(memory) {
|
|
5292
|
+
return {
|
|
5293
|
+
name: "search_memory",
|
|
5294
|
+
category: "Session",
|
|
5295
|
+
description: "Search memory entries by content. With the default backend this does substring matching; semantic/graph backends use embedding similarity or graph traversal.",
|
|
5296
|
+
usageHint: "Search long-term memory for relevant facts, conventions, or decisions.\n- Returns results ordered by relevance (newest-first for default, similarity for semantic).\n- Use before starting a task to recall project conventions and past decisions.\n- `limit` caps results (default 5, max 20).",
|
|
5297
|
+
permission: "auto",
|
|
5298
|
+
mutating: false,
|
|
5299
|
+
timeoutMs: 2e3,
|
|
5300
|
+
inputSchema: {
|
|
5301
|
+
type: "object",
|
|
5302
|
+
properties: {
|
|
5303
|
+
query: {
|
|
5304
|
+
type: "string",
|
|
5305
|
+
description: "Search query \u2014 words or phrase to find in memory."
|
|
5306
|
+
},
|
|
5307
|
+
scope: {
|
|
5308
|
+
type: "string",
|
|
5309
|
+
enum: ["project-agents", "project-memory", "user-memory"],
|
|
5310
|
+
description: "Which scope to search. Defaults to project-memory."
|
|
5311
|
+
},
|
|
5312
|
+
limit: {
|
|
5313
|
+
type: "number",
|
|
5314
|
+
description: "Maximum results to return (default 5, max 20)."
|
|
5315
|
+
}
|
|
5316
|
+
},
|
|
5317
|
+
required: ["query"]
|
|
5318
|
+
},
|
|
5319
|
+
async execute(input) {
|
|
5320
|
+
if (!input?.query) throw new Error("search_memory: query is required");
|
|
5321
|
+
const scope = input.scope ?? "project-memory";
|
|
5322
|
+
const limit = Math.min(input.limit ?? 5, 20);
|
|
5323
|
+
const entries = await memory.search(input.query, scope, limit);
|
|
5324
|
+
return {
|
|
5325
|
+
results: entries.map((e) => ({
|
|
5326
|
+
text: e.text,
|
|
5327
|
+
ts: e.ts,
|
|
5328
|
+
scope: e.scope,
|
|
5329
|
+
type: e.type,
|
|
5330
|
+
tags: e.tags,
|
|
5331
|
+
priority: e.priority
|
|
5332
|
+
}))
|
|
5333
|
+
};
|
|
5334
|
+
}
|
|
5335
|
+
};
|
|
5336
|
+
}
|
|
5337
|
+
function relatedMemoryTool(memory) {
|
|
5338
|
+
return {
|
|
5339
|
+
name: "find_related_memories",
|
|
5340
|
+
category: "Session",
|
|
5341
|
+
description: "Find memories related to the given text via graph traversal. Only available with graph backends; falls back to content search with file backends.",
|
|
5342
|
+
usageHint: "Discover memories connected to a topic through co-occurrence or similarity edges.\n- Useful for exploring what else the project knows about a given concept.\n- Falls back to content search when no graph backend is configured.\n- `limit` caps results (default 5, max 20).",
|
|
5343
|
+
permission: "auto",
|
|
5344
|
+
mutating: false,
|
|
5345
|
+
timeoutMs: 2e3,
|
|
5346
|
+
inputSchema: {
|
|
5347
|
+
type: "object",
|
|
5348
|
+
properties: {
|
|
5349
|
+
text: {
|
|
5350
|
+
type: "string",
|
|
5351
|
+
description: "Text to find related memories for."
|
|
5352
|
+
},
|
|
5353
|
+
scope: {
|
|
5354
|
+
type: "string",
|
|
5355
|
+
enum: ["project-agents", "project-memory", "user-memory"],
|
|
5356
|
+
description: "Which scope to search. Defaults to project-memory."
|
|
5357
|
+
},
|
|
5358
|
+
limit: {
|
|
5359
|
+
type: "number",
|
|
5360
|
+
description: "Maximum results to return (default 5, max 20)."
|
|
5361
|
+
}
|
|
5362
|
+
},
|
|
5363
|
+
required: ["text"]
|
|
5364
|
+
},
|
|
5365
|
+
async execute(input) {
|
|
5366
|
+
if (!input?.text) throw new Error("find_related_memories: text is required");
|
|
5367
|
+
const scope = input.scope ?? "project-memory";
|
|
5368
|
+
const limit = Math.min(input.limit ?? 5, 20);
|
|
5369
|
+
const entries = memory.findRelated ? await memory.findRelated(input.text, scope, limit) : await memory.search(input.text, scope, limit);
|
|
5370
|
+
return {
|
|
5371
|
+
results: entries.map((e) => ({
|
|
5372
|
+
text: e.text,
|
|
5373
|
+
ts: e.ts,
|
|
5374
|
+
scope: e.scope,
|
|
5375
|
+
type: e.type,
|
|
5376
|
+
tags: e.tags,
|
|
5377
|
+
priority: e.priority
|
|
5378
|
+
}))
|
|
5379
|
+
};
|
|
5380
|
+
}
|
|
5381
|
+
};
|
|
5382
|
+
}
|
|
5321
5383
|
|
|
5322
5384
|
// src/mode.ts
|
|
5323
5385
|
function createModeTool(modeStore) {
|
|
@@ -5439,12 +5501,6 @@ function lspKindToInternalKind(k) {
|
|
|
5439
5501
|
}
|
|
5440
5502
|
|
|
5441
5503
|
// src/codebase-index/writer.ts
|
|
5442
|
-
function expectDefined8(value) {
|
|
5443
|
-
if (value === null || value === void 0) {
|
|
5444
|
-
throw new Error("Expected value to be defined");
|
|
5445
|
-
}
|
|
5446
|
-
return value;
|
|
5447
|
-
}
|
|
5448
5504
|
var DB_FILE = "index.db";
|
|
5449
5505
|
function resolveIndexDir(projectRoot, override) {
|
|
5450
5506
|
return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
|
|
@@ -5589,7 +5645,7 @@ var IndexStore = class {
|
|
|
5589
5645
|
"SELECT file, lang, mtime_ms, symbol_count, last_indexed FROM files WHERE file = ?"
|
|
5590
5646
|
).all(file);
|
|
5591
5647
|
if (!rows.length) return null;
|
|
5592
|
-
const r =
|
|
5648
|
+
const r = expectDefined(rows[0]);
|
|
5593
5649
|
return { file: r.file, lang: r.lang, mtimeMs: r.mtime_ms, symbolCount: r.symbol_count, lastIndexed: r.last_indexed };
|
|
5594
5650
|
}
|
|
5595
5651
|
getAllFileMetas() {
|
|
@@ -6502,12 +6558,6 @@ function syncPyParse(filePath, lang) {
|
|
|
6502
6558
|
return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
|
|
6503
6559
|
}
|
|
6504
6560
|
}
|
|
6505
|
-
function expectDefined9(value) {
|
|
6506
|
-
if (value === null || value === void 0) {
|
|
6507
|
-
throw new Error("Expected value to be defined");
|
|
6508
|
-
}
|
|
6509
|
-
return value;
|
|
6510
|
-
}
|
|
6511
6561
|
function parseSymbols4(opts) {
|
|
6512
6562
|
const { file, content, lang } = opts;
|
|
6513
6563
|
const nativeAvailable = checkNativeParser();
|
|
@@ -6547,8 +6597,7 @@ function tryNativeParse(file, content) {
|
|
|
6547
6597
|
const toolsDir = path.join(process.cwd(), "tools");
|
|
6548
6598
|
const crateDir = path.join(toolsDir, "syn-parser");
|
|
6549
6599
|
const tmpFile = path.join(crateDir, "src", "input.rs");
|
|
6550
|
-
|
|
6551
|
-
writeFileSync3(tmpFile, content, "utf8");
|
|
6600
|
+
writeFileSync(tmpFile, content, "utf8");
|
|
6552
6601
|
const result = spawnSync(
|
|
6553
6602
|
"cargo",
|
|
6554
6603
|
["run", "--manifest-path", path.join(toolsDir, "Cargo.toml")],
|
|
@@ -6596,7 +6645,7 @@ function regexParse(opts) {
|
|
|
6596
6645
|
let hi = lineOffsets.length - 1;
|
|
6597
6646
|
while (lo < hi) {
|
|
6598
6647
|
const mid = lo + hi + 1 >>> 1;
|
|
6599
|
-
if (
|
|
6648
|
+
if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;
|
|
6600
6649
|
else hi = mid - 1;
|
|
6601
6650
|
}
|
|
6602
6651
|
return lo + 1;
|
|
@@ -6608,7 +6657,7 @@ function regexParse(opts) {
|
|
|
6608
6657
|
for (const pattern of RS_PATTERNS) {
|
|
6609
6658
|
pattern.regex.lastIndex = 0;
|
|
6610
6659
|
for (let match = pattern.regex.exec(content); match !== null; match = pattern.regex.exec(content)) {
|
|
6611
|
-
const name =
|
|
6660
|
+
const name = expectDefined(match[1]);
|
|
6612
6661
|
const offset = match.index ?? 0;
|
|
6613
6662
|
const line = lineFromOffset(offset);
|
|
6614
6663
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
@@ -6638,12 +6687,6 @@ function regexParse(opts) {
|
|
|
6638
6687
|
});
|
|
6639
6688
|
return { file, lang, symbols: deduped, mtimeMs: Date.now() };
|
|
6640
6689
|
}
|
|
6641
|
-
function expectDefined10(value) {
|
|
6642
|
-
if (value === null || value === void 0) {
|
|
6643
|
-
throw new Error("Expected value to be defined");
|
|
6644
|
-
}
|
|
6645
|
-
return value;
|
|
6646
|
-
}
|
|
6647
6690
|
function parseSymbols5(opts) {
|
|
6648
6691
|
const { file, content, lang } = opts;
|
|
6649
6692
|
try {
|
|
@@ -6670,14 +6713,14 @@ function regexParse2(opts) {
|
|
|
6670
6713
|
let hi = lineOffsets.length - 1;
|
|
6671
6714
|
while (lo < hi) {
|
|
6672
6715
|
const mid = lo + hi + 1 >>> 1;
|
|
6673
|
-
if (
|
|
6716
|
+
if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;
|
|
6674
6717
|
else hi = mid - 1;
|
|
6675
6718
|
}
|
|
6676
6719
|
return lo + 1;
|
|
6677
6720
|
}
|
|
6678
6721
|
const rootMatch = content.match(/^\s*\{/m);
|
|
6679
6722
|
if (rootMatch) {
|
|
6680
|
-
const offset =
|
|
6723
|
+
const offset = expectDefined(rootMatch.index);
|
|
6681
6724
|
const line = lineFromOffset(offset);
|
|
6682
6725
|
symbols.push(
|
|
6683
6726
|
makeSymbol({
|
|
@@ -6693,7 +6736,7 @@ function regexParse2(opts) {
|
|
|
6693
6736
|
}
|
|
6694
6737
|
const topLevelKeyRegex = /^\s*"([^"]+)"\s*:/gm;
|
|
6695
6738
|
for (let match = topLevelKeyRegex.exec(content); match !== null; match = topLevelKeyRegex.exec(content)) {
|
|
6696
|
-
const key =
|
|
6739
|
+
const key = expectDefined(match[1]);
|
|
6697
6740
|
const offset = match.index ?? 0;
|
|
6698
6741
|
const line = lineFromOffset(offset);
|
|
6699
6742
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
@@ -6740,7 +6783,7 @@ function regexParse2(opts) {
|
|
|
6740
6783
|
const defsRegex = /"\$defs"\s*:|"\$defs"\s*:/g;
|
|
6741
6784
|
const defsMatch = defsRegex.exec(content);
|
|
6742
6785
|
if (defsMatch !== null) {
|
|
6743
|
-
const offset =
|
|
6786
|
+
const offset = expectDefined(defsMatch.index);
|
|
6744
6787
|
const line = lineFromOffset(offset);
|
|
6745
6788
|
symbols.push(
|
|
6746
6789
|
makeSymbol({
|
|
@@ -6765,7 +6808,7 @@ function regexParse2(opts) {
|
|
|
6765
6808
|
for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {
|
|
6766
6809
|
const offset = match.index ?? 0;
|
|
6767
6810
|
const line = lineFromOffset(offset);
|
|
6768
|
-
const key = match[0]?.match(/"([^"]+)"/)?.[1] ??
|
|
6811
|
+
const key = match[0]?.match(/"([^"]+)"/)?.[1] ?? expectDefined(match[0]);
|
|
6769
6812
|
symbols.push(
|
|
6770
6813
|
makeSymbol({
|
|
6771
6814
|
name: key,
|
|
@@ -6784,12 +6827,12 @@ function regexParse2(opts) {
|
|
|
6784
6827
|
function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset) {
|
|
6785
6828
|
const scriptsBlockRegex = /"scripts"\s*:\s*\{([^}]+)\}/g;
|
|
6786
6829
|
for (let match = scriptsBlockRegex.exec(content); match !== null; match = scriptsBlockRegex.exec(content)) {
|
|
6787
|
-
const blockContent =
|
|
6830
|
+
const blockContent = expectDefined(match[0]);
|
|
6788
6831
|
const blockOffset = match.index ?? 0;
|
|
6789
6832
|
const scriptKeyRegex = /"(\w[\w-]*)"\s*:/g;
|
|
6790
6833
|
for (let scriptMatch = scriptKeyRegex.exec(blockContent); scriptMatch !== null; scriptMatch = scriptKeyRegex.exec(blockContent)) {
|
|
6791
|
-
const key =
|
|
6792
|
-
const keyOffset = blockOffset +
|
|
6834
|
+
const key = expectDefined(scriptMatch[1]);
|
|
6835
|
+
const keyOffset = blockOffset + expectDefined(scriptMatch.index);
|
|
6793
6836
|
const line = lineFromOffset(keyOffset);
|
|
6794
6837
|
symbols.push(
|
|
6795
6838
|
makeSymbol({
|
|
@@ -6808,12 +6851,12 @@ function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFr
|
|
|
6808
6851
|
function extractCompilerOptions(content, symbols, file, lang, lineOffsets, parentLine, lineFromOffset) {
|
|
6809
6852
|
const optsBlockRegex = /"compilerOptions"\s*:\s*\{([^}]+)\}/g;
|
|
6810
6853
|
for (let match = optsBlockRegex.exec(content); match !== null; match = optsBlockRegex.exec(content)) {
|
|
6811
|
-
const blockContent =
|
|
6854
|
+
const blockContent = expectDefined(match[0]);
|
|
6812
6855
|
const blockOffset = match.index ?? 0;
|
|
6813
6856
|
const optKeyRegex = /"(\w[\w]*)"\s*:/g;
|
|
6814
6857
|
for (let optMatch = optKeyRegex.exec(blockContent); optMatch !== null; optMatch = optKeyRegex.exec(blockContent)) {
|
|
6815
|
-
const key =
|
|
6816
|
-
const keyOffset = blockOffset +
|
|
6858
|
+
const key = expectDefined(optMatch[1]);
|
|
6859
|
+
const keyOffset = blockOffset + expectDefined(optMatch.index);
|
|
6817
6860
|
const line = lineFromOffset(keyOffset);
|
|
6818
6861
|
if (line <= parentLine) continue;
|
|
6819
6862
|
symbols.push(
|
|
@@ -6845,14 +6888,6 @@ function makeSymbol(opts) {
|
|
|
6845
6888
|
text: `${opts.name} ${opts.signature}`.trim()
|
|
6846
6889
|
};
|
|
6847
6890
|
}
|
|
6848
|
-
|
|
6849
|
-
// src/codebase-index/yaml-parser.ts
|
|
6850
|
-
function expectDefined11(value) {
|
|
6851
|
-
if (value === null || value === void 0) {
|
|
6852
|
-
throw new Error("Expected value to be defined");
|
|
6853
|
-
}
|
|
6854
|
-
return value;
|
|
6855
|
-
}
|
|
6856
6891
|
function parseSymbols6(opts) {
|
|
6857
6892
|
const { file, content, lang } = opts;
|
|
6858
6893
|
try {
|
|
@@ -6874,14 +6909,14 @@ function regexParse3(opts) {
|
|
|
6874
6909
|
let hi = lineOffsets.length - 1;
|
|
6875
6910
|
while (lo < hi) {
|
|
6876
6911
|
const mid = lo + hi + 1 >>> 1;
|
|
6877
|
-
if (
|
|
6912
|
+
if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;
|
|
6878
6913
|
else hi = mid - 1;
|
|
6879
6914
|
}
|
|
6880
6915
|
return lo + 1;
|
|
6881
6916
|
}
|
|
6882
6917
|
const anchorRegex = /&(\w[\w-]*)/g;
|
|
6883
6918
|
for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {
|
|
6884
|
-
const name =
|
|
6919
|
+
const name = expectDefined(match[1]);
|
|
6885
6920
|
const offset = match.index ?? 0;
|
|
6886
6921
|
const line = lineFromOffset(offset);
|
|
6887
6922
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
@@ -6899,7 +6934,7 @@ function regexParse3(opts) {
|
|
|
6899
6934
|
}
|
|
6900
6935
|
const aliasRegex = /\*(\w[\w-]*)/g;
|
|
6901
6936
|
for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {
|
|
6902
|
-
const name =
|
|
6937
|
+
const name = expectDefined(match[1]);
|
|
6903
6938
|
const offset = match.index ?? 0;
|
|
6904
6939
|
const line = lineFromOffset(offset);
|
|
6905
6940
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
@@ -6934,7 +6969,7 @@ function regexParse3(opts) {
|
|
|
6934
6969
|
}
|
|
6935
6970
|
const listItemRegex = /^-(\s+)([^:#\s][^:#\s]*)\s*:/gm;
|
|
6936
6971
|
for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {
|
|
6937
|
-
const key =
|
|
6972
|
+
const key = expectDefined(match[2]);
|
|
6938
6973
|
const offset = match.index ?? 0;
|
|
6939
6974
|
const line = lineFromOffset(offset);
|
|
6940
6975
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
@@ -6954,7 +6989,7 @@ function regexParse3(opts) {
|
|
|
6954
6989
|
}
|
|
6955
6990
|
const blockScalarRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:\s*[|>](\s|$)/gm;
|
|
6956
6991
|
for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {
|
|
6957
|
-
const key =
|
|
6992
|
+
const key = expectDefined(match[2]);
|
|
6958
6993
|
const offset = match.index ?? 0;
|
|
6959
6994
|
const line = lineFromOffset(offset);
|
|
6960
6995
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
@@ -7174,12 +7209,6 @@ function cancelPendingReindexes() {
|
|
|
7174
7209
|
}
|
|
7175
7210
|
|
|
7176
7211
|
// src/codebase-index/indexer.ts
|
|
7177
|
-
function expectDefined12(value) {
|
|
7178
|
-
if (value === null || value === void 0) {
|
|
7179
|
-
throw new Error("Expected value to be defined");
|
|
7180
|
-
}
|
|
7181
|
-
return value;
|
|
7182
|
-
}
|
|
7183
7212
|
var YIELD_EVERY_N = 50;
|
|
7184
7213
|
function yieldEventLoop() {
|
|
7185
7214
|
return new Promise((resolve7) => setImmediate(resolve7));
|
|
@@ -7288,7 +7317,7 @@ async function runIndexer(_ctx, opts) {
|
|
|
7288
7317
|
for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);
|
|
7289
7318
|
}
|
|
7290
7319
|
for (let fi = 0; fi < files.length; fi++) {
|
|
7291
|
-
const file =
|
|
7320
|
+
const file = expectDefined(files[fi]);
|
|
7292
7321
|
_setIndexProgress(fi + 1, files.length);
|
|
7293
7322
|
if (fi > 0 && fi % YIELD_EVERY_N === 0) {
|
|
7294
7323
|
await yieldEventLoop();
|
|
@@ -7345,7 +7374,7 @@ async function runIndexer(_ctx, opts) {
|
|
|
7345
7374
|
langStats[lang] = (langStats[lang] ?? 0) + count;
|
|
7346
7375
|
if (parsed.refs && parsed.refs.length > 0) {
|
|
7347
7376
|
for (let i = 0; i < symbolsWithIds.length; i++) {
|
|
7348
|
-
const sym =
|
|
7377
|
+
const sym = expectDefined(symbolsWithIds[i]);
|
|
7349
7378
|
const symRefs = parsed.refs.filter((r) => r.line === sym.line);
|
|
7350
7379
|
if (symRefs.length > 0) {
|
|
7351
7380
|
const refsWithFromId = symRefs.map((r) => ({ ...r, fromId: sym.id }));
|
|
@@ -7516,12 +7545,6 @@ var Bm25Index = class {
|
|
|
7516
7545
|
};
|
|
7517
7546
|
|
|
7518
7547
|
// src/codebase-index/codebase-search-tool.ts
|
|
7519
|
-
function expectDefined13(value) {
|
|
7520
|
-
if (value === null || value === void 0) {
|
|
7521
|
-
throw new Error("Expected value to be defined");
|
|
7522
|
-
}
|
|
7523
|
-
return value;
|
|
7524
|
-
}
|
|
7525
7548
|
var codebaseSearchTool = {
|
|
7526
7549
|
name: "codebase-search",
|
|
7527
7550
|
category: "Project",
|
|
@@ -7611,7 +7634,7 @@ var codebaseSearchTool = {
|
|
|
7611
7634
|
const top = scored.slice(0, limit);
|
|
7612
7635
|
const qTokens = tokenise(input.query);
|
|
7613
7636
|
const results = top.map(({ id, score }) => {
|
|
7614
|
-
const c =
|
|
7637
|
+
const c = expectDefined(candidates.find((c2) => c2.id === id));
|
|
7615
7638
|
const snippet = bm25.extractSnippet(id, qTokens);
|
|
7616
7639
|
return {
|
|
7617
7640
|
...c,
|
|
@@ -7736,6 +7759,6 @@ var builtinToolsPack = {
|
|
|
7736
7759
|
tools: builtinTools
|
|
7737
7760
|
};
|
|
7738
7761
|
|
|
7739
|
-
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 };
|
|
7762
|
+
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, relatedMemoryTool, rememberTool, replaceTool, runStartupIndex, scaffoldTool, searchMemoryTool, searchTool, testTool, todoTool, toolHelpTool, toolSearchTool, toolUseTool, treeTool, typecheckTool, writeTool };
|
|
7740
7763
|
//# sourceMappingURL=index.js.map
|
|
7741
7764
|
//# sourceMappingURL=index.js.map
|