@wrongstack/tools 0.89.1 → 0.104.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.
Files changed (58) hide show
  1. package/dist/audit.js +1 -7
  2. package/dist/audit.js.map +1 -1
  3. package/dist/{background-indexer-DYm1FUxK.d.ts → background-indexer-C2014mH0.d.ts} +1 -1
  4. package/dist/bash.js +6 -18
  5. package/dist/bash.js.map +1 -1
  6. package/dist/builtin.js +187 -133
  7. package/dist/builtin.js.map +1 -1
  8. package/dist/circuit-breaker.js +1 -1
  9. package/dist/circuit-breaker.js.map +1 -1
  10. package/dist/codebase-index/index.d.ts +2 -21
  11. package/dist/codebase-index/index.js +25 -69
  12. package/dist/codebase-index/index.js.map +1 -1
  13. package/dist/diff.js.map +1 -1
  14. package/dist/document.js +1 -1
  15. package/dist/document.js.map +1 -1
  16. package/dist/edit.js.map +1 -1
  17. package/dist/exec.js +3 -15
  18. package/dist/exec.js.map +1 -1
  19. package/dist/fetch.js.map +1 -1
  20. package/dist/format.js +4 -16
  21. package/dist/format.js.map +1 -1
  22. package/dist/git.js +1 -7
  23. package/dist/git.js.map +1 -1
  24. package/dist/glob.js.map +1 -1
  25. package/dist/grep.js +1 -7
  26. package/dist/grep.js.map +1 -1
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.js +301 -136
  29. package/dist/index.js.map +1 -1
  30. package/dist/install.js +4 -16
  31. package/dist/install.js.map +1 -1
  32. package/dist/lint.js +4 -16
  33. package/dist/lint.js.map +1 -1
  34. package/dist/logs.js.map +1 -1
  35. package/dist/memory.d.ts +29 -1
  36. package/dist/memory.js +115 -4
  37. package/dist/memory.js.map +1 -1
  38. package/dist/outdated.js.map +1 -1
  39. package/dist/pack.js +187 -133
  40. package/dist/pack.js.map +1 -1
  41. package/dist/patch.js.map +1 -1
  42. package/dist/process-registry.js +2 -7
  43. package/dist/process-registry.js.map +1 -1
  44. package/dist/read.js +1 -1
  45. package/dist/read.js.map +1 -1
  46. package/dist/replace.js +1 -7
  47. package/dist/replace.js.map +1 -1
  48. package/dist/scaffold.js.map +1 -1
  49. package/dist/search.js +2 -7
  50. package/dist/search.js.map +1 -1
  51. package/dist/test.js +4 -16
  52. package/dist/test.js.map +1 -1
  53. package/dist/tree.js +1 -7
  54. package/dist/tree.js.map +1 -1
  55. package/dist/typecheck.js +4 -16
  56. package/dist/typecheck.js.map +1 -1
  57. package/dist/write.js.map +1 -1
  58. package/package.json +2 -2
package/dist/builtin.js CHANGED
@@ -1,30 +1,19 @@
1
- import { spawn, execFileSync, spawnSync } from 'node:child_process';
2
1
  import * as Core from '@wrongstack/core';
3
- import { buildChildEnv, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, compileGlob, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, resolveWstackPaths } from '@wrongstack/core';
2
+ import { buildChildEnv, expectDefined, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, compileGlob, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, loadTasks, emptyTaskFile, saveTasks, computeTaskItemProgress, formatTaskList, resolveWstackPaths } from '@wrongstack/core';
3
+ import { spawn, execFileSync, spawnSync } from 'node:child_process';
4
4
  import * as fs12 from 'node:fs/promises';
5
5
  import * as path from 'node:path';
6
6
  import { resolve, sep, dirname } from 'node:path';
7
7
  import * as os from 'node:os';
8
8
  import { createRequire } from 'node:module';
9
9
  import * as fs from 'node:fs';
10
- import { statSync, mkdirSync, writeFileSync } from 'node:fs';
10
+ import { statSync, writeFileSync, mkdirSync } from 'node:fs';
11
11
  import * as ts from 'typescript';
12
12
  import * as dns from 'node:dns/promises';
13
13
  import * as net from 'node:net';
14
14
  import { Agent } from 'undici';
15
15
 
16
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
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/_spawn-stream.ts
28
17
  async function* spawnStream(opts) {
29
18
  const max = opts.maxBytes ?? 2e5;
30
19
  const flushAt = opts.flushBytes ?? 4 * 1024;
@@ -103,12 +92,6 @@ async function* spawnStream(opts) {
103
92
  error
104
93
  };
105
94
  }
106
- function expectDefined2(value) {
107
- if (value === null || value === void 0) {
108
- throw new Error("Expected value to be defined");
109
- }
110
- return value;
111
- }
112
95
  async function detectPackageManager(cwd) {
113
96
  const { stat: stat10 } = await import('node:fs/promises');
114
97
  try {
@@ -198,9 +181,9 @@ function collapseConsecutiveDuplicates(text, minRun = REPEAT_RUN_THRESHOLD) {
198
181
  while (j < lines.length && lines[j] === lines[i]) j++;
199
182
  const run = j - i;
200
183
  if (run >= minRun) {
201
- out.push(expectDefined2(lines[i]), `\u2026 \u27E8repeated ${run}\xD7\u27E9`);
184
+ out.push(expectDefined(lines[i]), `\u2026 \u27E8repeated ${run}\xD7\u27E9`);
202
185
  } else {
203
- for (let k = i; k < j; k++) out.push(expectDefined2(lines[k]));
186
+ for (let k = i; k < j; k++) out.push(expectDefined(lines[k]));
204
187
  }
205
188
  i = j;
206
189
  }
@@ -353,7 +336,7 @@ function parseAuditOutput(json, exitCode) {
353
336
 
354
337
  // src/circuit-breaker.ts
355
338
  var DEFAULT_MAX_CONSECUTIVE_FAILURES = 5;
356
- var DEFAULT_SLOW_CALL_THRESHOLD_MS = 6e4;
339
+ var DEFAULT_SLOW_CALL_THRESHOLD_MS = 18e4;
357
340
  var DEFAULT_MAX_SLOW_CALLS = 3;
358
341
  var DEFAULT_WINDOW_MS = 6e4;
359
342
  var DEFAULT_MAX_CALLS_PER_WINDOW = 30;
@@ -496,12 +479,6 @@ var CircuitBreaker = class {
496
479
  };
497
480
 
498
481
  // src/process-registry.ts
499
- function expectDefined3(value) {
500
- if (value === null || value === void 0) {
501
- throw new Error("Expected value to be defined");
502
- }
503
- return value;
504
- }
505
482
  var SENSITIVE_FLAG_PATTERNS = [
506
483
  // --flag=value or --flag "value" (value captured up to next space or comma)
507
484
  /--(?: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,
@@ -522,7 +499,7 @@ function redactCommand(cmd) {
522
499
  const sp = match.search(/\s/);
523
500
  const delim = eq !== -1 ? "=" : sp !== -1 ? match[sp] : null;
524
501
  if (delim !== null) {
525
- const flag = match.slice(0, match.indexOf(expectDefined3(delim)) + 1);
502
+ const flag = match.slice(0, match.indexOf(expectDefined(delim)) + 1);
526
503
  return `${flag}[REDACTED]`;
527
504
  }
528
505
  const flagEnd = match.match(/^--?[a-zA-Z][a-zA-Z0-9_-]*/)?.[0] ?? match;
@@ -702,7 +679,7 @@ function getProcessRegistry() {
702
679
 
703
680
  // src/bash.ts
704
681
  var MAX_OUTPUT = 32768;
705
- var DEFAULT_TIMEOUT_MS = 3e4;
682
+ var DEFAULT_TIMEOUT_MS = 3e5;
706
683
  var STREAM_FLUSH_INTERVAL_MS = 200;
707
684
  var STREAM_FLUSH_BYTES = 4 * 1024;
708
685
  var bashTool = {
@@ -718,9 +695,9 @@ var bashTool = {
718
695
  // explicitly removes the implicit cross-tool aliasing.
719
696
  subjectKey: "command",
720
697
  capabilities: ["shell.arbitrary"],
721
- timeoutMs: 3e4,
698
+ timeoutMs: 3e5,
722
699
  maxOutputBytes: MAX_OUTPUT,
723
- estimatedDurationMs: 3e3,
700
+ estimatedDurationMs: 3e4,
724
701
  inputSchema: {
725
702
  type: "object",
726
703
  properties: {
@@ -1119,12 +1096,6 @@ function lspKindToInternalKind(k) {
1119
1096
  }
1120
1097
 
1121
1098
  // src/codebase-index/writer.ts
1122
- function expectDefined4(value) {
1123
- if (value === null || value === void 0) {
1124
- throw new Error("Expected value to be defined");
1125
- }
1126
- return value;
1127
- }
1128
1099
  var DB_FILE = "index.db";
1129
1100
  function resolveIndexDir(projectRoot, override) {
1130
1101
  return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
@@ -1269,7 +1240,7 @@ var IndexStore = class {
1269
1240
  "SELECT file, lang, mtime_ms, symbol_count, last_indexed FROM files WHERE file = ?"
1270
1241
  ).all(file);
1271
1242
  if (!rows.length) return null;
1272
- const r = expectDefined4(rows[0]);
1243
+ const r = expectDefined(rows[0]);
1273
1244
  return { file: r.file, lang: r.lang, mtimeMs: r.mtime_ms, symbolCount: r.symbol_count, lastIndexed: r.last_indexed };
1274
1245
  }
1275
1246
  getAllFileMetas() {
@@ -2182,12 +2153,6 @@ function syncPyParse(filePath, lang) {
2182
2153
  return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
2183
2154
  }
2184
2155
  }
2185
- function expectDefined5(value) {
2186
- if (value === null || value === void 0) {
2187
- throw new Error("Expected value to be defined");
2188
- }
2189
- return value;
2190
- }
2191
2156
  function parseSymbols4(opts) {
2192
2157
  const { file, content, lang } = opts;
2193
2158
  const nativeAvailable = checkNativeParser();
@@ -2227,8 +2192,7 @@ function tryNativeParse(file, content) {
2227
2192
  const toolsDir = path.join(process.cwd(), "tools");
2228
2193
  const crateDir = path.join(toolsDir, "syn-parser");
2229
2194
  const tmpFile = path.join(crateDir, "src", "input.rs");
2230
- const { writeFileSync: writeFileSync3 } = __require("node:fs");
2231
- writeFileSync3(tmpFile, content, "utf8");
2195
+ writeFileSync(tmpFile, content, "utf8");
2232
2196
  const result = spawnSync(
2233
2197
  "cargo",
2234
2198
  ["run", "--manifest-path", path.join(toolsDir, "Cargo.toml")],
@@ -2276,7 +2240,7 @@ function regexParse(opts) {
2276
2240
  let hi = lineOffsets.length - 1;
2277
2241
  while (lo < hi) {
2278
2242
  const mid = lo + hi + 1 >>> 1;
2279
- if (expectDefined5(lineOffsets[mid]) <= offset) lo = mid;
2243
+ if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;
2280
2244
  else hi = mid - 1;
2281
2245
  }
2282
2246
  return lo + 1;
@@ -2288,7 +2252,7 @@ function regexParse(opts) {
2288
2252
  for (const pattern of RS_PATTERNS) {
2289
2253
  pattern.regex.lastIndex = 0;
2290
2254
  for (let match = pattern.regex.exec(content); match !== null; match = pattern.regex.exec(content)) {
2291
- const name = expectDefined5(match[1]);
2255
+ const name = expectDefined(match[1]);
2292
2256
  const offset = match.index ?? 0;
2293
2257
  const line = lineFromOffset(offset);
2294
2258
  const col = offset - (lineOffsets[line - 1] ?? 0);
@@ -2318,12 +2282,6 @@ function regexParse(opts) {
2318
2282
  });
2319
2283
  return { file, lang, symbols: deduped, mtimeMs: Date.now() };
2320
2284
  }
2321
- function expectDefined6(value) {
2322
- if (value === null || value === void 0) {
2323
- throw new Error("Expected value to be defined");
2324
- }
2325
- return value;
2326
- }
2327
2285
  function parseSymbols5(opts) {
2328
2286
  const { file, content, lang } = opts;
2329
2287
  try {
@@ -2350,14 +2308,14 @@ function regexParse2(opts) {
2350
2308
  let hi = lineOffsets.length - 1;
2351
2309
  while (lo < hi) {
2352
2310
  const mid = lo + hi + 1 >>> 1;
2353
- if (expectDefined6(lineOffsets[mid]) <= offset) lo = mid;
2311
+ if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;
2354
2312
  else hi = mid - 1;
2355
2313
  }
2356
2314
  return lo + 1;
2357
2315
  }
2358
2316
  const rootMatch = content.match(/^\s*\{/m);
2359
2317
  if (rootMatch) {
2360
- const offset = expectDefined6(rootMatch.index);
2318
+ const offset = expectDefined(rootMatch.index);
2361
2319
  const line = lineFromOffset(offset);
2362
2320
  symbols.push(
2363
2321
  makeSymbol({
@@ -2373,7 +2331,7 @@ function regexParse2(opts) {
2373
2331
  }
2374
2332
  const topLevelKeyRegex = /^\s*"([^"]+)"\s*:/gm;
2375
2333
  for (let match = topLevelKeyRegex.exec(content); match !== null; match = topLevelKeyRegex.exec(content)) {
2376
- const key = expectDefined6(match[1]);
2334
+ const key = expectDefined(match[1]);
2377
2335
  const offset = match.index ?? 0;
2378
2336
  const line = lineFromOffset(offset);
2379
2337
  const col = offset - (lineOffsets[line - 1] ?? 0);
@@ -2420,7 +2378,7 @@ function regexParse2(opts) {
2420
2378
  const defsRegex = /"\$defs"\s*:|"\$defs"\s*:/g;
2421
2379
  const defsMatch = defsRegex.exec(content);
2422
2380
  if (defsMatch !== null) {
2423
- const offset = expectDefined6(defsMatch.index);
2381
+ const offset = expectDefined(defsMatch.index);
2424
2382
  const line = lineFromOffset(offset);
2425
2383
  symbols.push(
2426
2384
  makeSymbol({
@@ -2445,7 +2403,7 @@ function regexParse2(opts) {
2445
2403
  for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {
2446
2404
  const offset = match.index ?? 0;
2447
2405
  const line = lineFromOffset(offset);
2448
- const key = match[0]?.match(/"([^"]+)"/)?.[1] ?? expectDefined6(match[0]);
2406
+ const key = match[0]?.match(/"([^"]+)"/)?.[1] ?? expectDefined(match[0]);
2449
2407
  symbols.push(
2450
2408
  makeSymbol({
2451
2409
  name: key,
@@ -2464,12 +2422,12 @@ function regexParse2(opts) {
2464
2422
  function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset) {
2465
2423
  const scriptsBlockRegex = /"scripts"\s*:\s*\{([^}]+)\}/g;
2466
2424
  for (let match = scriptsBlockRegex.exec(content); match !== null; match = scriptsBlockRegex.exec(content)) {
2467
- const blockContent = expectDefined6(match[0]);
2425
+ const blockContent = expectDefined(match[0]);
2468
2426
  const blockOffset = match.index ?? 0;
2469
2427
  const scriptKeyRegex = /"(\w[\w-]*)"\s*:/g;
2470
2428
  for (let scriptMatch = scriptKeyRegex.exec(blockContent); scriptMatch !== null; scriptMatch = scriptKeyRegex.exec(blockContent)) {
2471
- const key = expectDefined6(scriptMatch[1]);
2472
- const keyOffset = blockOffset + expectDefined6(scriptMatch.index);
2429
+ const key = expectDefined(scriptMatch[1]);
2430
+ const keyOffset = blockOffset + expectDefined(scriptMatch.index);
2473
2431
  const line = lineFromOffset(keyOffset);
2474
2432
  symbols.push(
2475
2433
  makeSymbol({
@@ -2488,12 +2446,12 @@ function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFr
2488
2446
  function extractCompilerOptions(content, symbols, file, lang, lineOffsets, parentLine, lineFromOffset) {
2489
2447
  const optsBlockRegex = /"compilerOptions"\s*:\s*\{([^}]+)\}/g;
2490
2448
  for (let match = optsBlockRegex.exec(content); match !== null; match = optsBlockRegex.exec(content)) {
2491
- const blockContent = expectDefined6(match[0]);
2449
+ const blockContent = expectDefined(match[0]);
2492
2450
  const blockOffset = match.index ?? 0;
2493
2451
  const optKeyRegex = /"(\w[\w]*)"\s*:/g;
2494
2452
  for (let optMatch = optKeyRegex.exec(blockContent); optMatch !== null; optMatch = optKeyRegex.exec(blockContent)) {
2495
- const key = expectDefined6(optMatch[1]);
2496
- const keyOffset = blockOffset + expectDefined6(optMatch.index);
2453
+ const key = expectDefined(optMatch[1]);
2454
+ const keyOffset = blockOffset + expectDefined(optMatch.index);
2497
2455
  const line = lineFromOffset(keyOffset);
2498
2456
  if (line <= parentLine) continue;
2499
2457
  symbols.push(
@@ -2525,14 +2483,6 @@ function makeSymbol(opts) {
2525
2483
  text: `${opts.name} ${opts.signature}`.trim()
2526
2484
  };
2527
2485
  }
2528
-
2529
- // src/codebase-index/yaml-parser.ts
2530
- function expectDefined7(value) {
2531
- if (value === null || value === void 0) {
2532
- throw new Error("Expected value to be defined");
2533
- }
2534
- return value;
2535
- }
2536
2486
  function parseSymbols6(opts) {
2537
2487
  const { file, content, lang } = opts;
2538
2488
  try {
@@ -2554,14 +2504,14 @@ function regexParse3(opts) {
2554
2504
  let hi = lineOffsets.length - 1;
2555
2505
  while (lo < hi) {
2556
2506
  const mid = lo + hi + 1 >>> 1;
2557
- if (expectDefined7(lineOffsets[mid]) <= offset) lo = mid;
2507
+ if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;
2558
2508
  else hi = mid - 1;
2559
2509
  }
2560
2510
  return lo + 1;
2561
2511
  }
2562
2512
  const anchorRegex = /&(\w[\w-]*)/g;
2563
2513
  for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {
2564
- const name = expectDefined7(match[1]);
2514
+ const name = expectDefined(match[1]);
2565
2515
  const offset = match.index ?? 0;
2566
2516
  const line = lineFromOffset(offset);
2567
2517
  const col = offset - (lineOffsets[line - 1] ?? 0);
@@ -2579,7 +2529,7 @@ function regexParse3(opts) {
2579
2529
  }
2580
2530
  const aliasRegex = /\*(\w[\w-]*)/g;
2581
2531
  for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {
2582
- const name = expectDefined7(match[1]);
2532
+ const name = expectDefined(match[1]);
2583
2533
  const offset = match.index ?? 0;
2584
2534
  const line = lineFromOffset(offset);
2585
2535
  const col = offset - (lineOffsets[line - 1] ?? 0);
@@ -2614,7 +2564,7 @@ function regexParse3(opts) {
2614
2564
  }
2615
2565
  const listItemRegex = /^-(\s+)([^:#\s][^:#\s]*)\s*:/gm;
2616
2566
  for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {
2617
- const key = expectDefined7(match[2]);
2567
+ const key = expectDefined(match[2]);
2618
2568
  const offset = match.index ?? 0;
2619
2569
  const line = lineFromOffset(offset);
2620
2570
  const col = offset - (lineOffsets[line - 1] ?? 0);
@@ -2634,7 +2584,7 @@ function regexParse3(opts) {
2634
2584
  }
2635
2585
  const blockScalarRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:\s*[|>](\s|$)/gm;
2636
2586
  for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {
2637
- const key = expectDefined7(match[2]);
2587
+ const key = expectDefined(match[2]);
2638
2588
  const offset = match.index ?? 0;
2639
2589
  const line = lineFromOffset(offset);
2640
2590
  const col = offset - (lineOffsets[line - 1] ?? 0);
@@ -2765,12 +2715,6 @@ function _setIndexProgress(current, total) {
2765
2715
  Promise.resolve();
2766
2716
 
2767
2717
  // src/codebase-index/indexer.ts
2768
- function expectDefined8(value) {
2769
- if (value === null || value === void 0) {
2770
- throw new Error("Expected value to be defined");
2771
- }
2772
- return value;
2773
- }
2774
2718
  var YIELD_EVERY_N = 50;
2775
2719
  function yieldEventLoop() {
2776
2720
  return new Promise((resolve7) => setImmediate(resolve7));
@@ -2879,7 +2823,7 @@ async function runIndexer(_ctx, opts) {
2879
2823
  for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);
2880
2824
  }
2881
2825
  for (let fi = 0; fi < files.length; fi++) {
2882
- const file = expectDefined8(files[fi]);
2826
+ const file = expectDefined(files[fi]);
2883
2827
  _setIndexProgress(fi + 1, files.length);
2884
2828
  if (fi > 0 && fi % YIELD_EVERY_N === 0) {
2885
2829
  await yieldEventLoop();
@@ -2936,7 +2880,7 @@ async function runIndexer(_ctx, opts) {
2936
2880
  langStats[lang] = (langStats[lang] ?? 0) + count;
2937
2881
  if (parsed.refs && parsed.refs.length > 0) {
2938
2882
  for (let i = 0; i < symbolsWithIds.length; i++) {
2939
- const sym = expectDefined8(symbolsWithIds[i]);
2883
+ const sym = expectDefined(symbolsWithIds[i]);
2940
2884
  const symRefs = parsed.refs.filter((r) => r.line === sym.line);
2941
2885
  if (symRefs.length > 0) {
2942
2886
  const refsWithFromId = symRefs.map((r) => ({ ...r, fromId: sym.id }));
@@ -3097,12 +3041,6 @@ var Bm25Index = class {
3097
3041
  };
3098
3042
 
3099
3043
  // src/codebase-index/codebase-search-tool.ts
3100
- function expectDefined9(value) {
3101
- if (value === null || value === void 0) {
3102
- throw new Error("Expected value to be defined");
3103
- }
3104
- return value;
3105
- }
3106
3044
  var codebaseSearchTool = {
3107
3045
  name: "codebase-search",
3108
3046
  category: "Project",
@@ -3192,7 +3130,7 @@ var codebaseSearchTool = {
3192
3130
  const top = scored.slice(0, limit);
3193
3131
  const qTokens = tokenise(input.query);
3194
3132
  const results = top.map(({ id, score }) => {
3195
- const c = expectDefined9(candidates.find((c2) => c2.id === id));
3133
+ const c = expectDefined(candidates.find((c2) => c2.id === id));
3196
3134
  const snippet = bm25.extractSnippet(id, qTokens);
3197
3135
  return {
3198
3136
  ...c,
@@ -4766,12 +4704,6 @@ function capSubject(line) {
4766
4704
  }
4767
4705
 
4768
4706
  // src/grep.ts
4769
- function expectDefined10(value) {
4770
- if (value === null || value === void 0) {
4771
- throw new Error("Expected value to be defined");
4772
- }
4773
- return value;
4774
- }
4775
4707
  var DEFAULT_IGNORE3 = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
4776
4708
  var grepTool = {
4777
4709
  name: "grep",
@@ -4913,7 +4845,7 @@ async function* runRgStream(input, base, mode, limit, signal) {
4913
4845
  waiter = r;
4914
4846
  });
4915
4847
  }
4916
- const c = expectDefined10(queue.shift());
4848
+ const c = expectDefined(queue.shift());
4917
4849
  if (c.kind === "error") {
4918
4850
  errored = true;
4919
4851
  continue;
@@ -6027,12 +5959,6 @@ var readTool = {
6027
5959
  };
6028
5960
  }
6029
5961
  };
6030
- function expectDefined11(value) {
6031
- if (value === null || value === void 0) {
6032
- throw new Error("Expected value to be defined");
6033
- }
6034
- return value;
6035
- }
6036
5962
  var DEFAULT_IGNORE4 = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
6037
5963
  var replaceTool = {
6038
5964
  name: "replace",
@@ -6112,8 +6038,8 @@ var replaceTool = {
6112
6038
  const count = matches.length;
6113
6039
  let newContentLf = contentLf;
6114
6040
  for (let i = matches.length - 1; i >= 0; i--) {
6115
- const m = expectDefined11(matches[i]);
6116
- newContentLf = newContentLf.slice(0, m.index) + input.replacement + newContentLf.slice(expectDefined11(m.index) + m[0].length);
6041
+ const m = expectDefined(matches[i]);
6042
+ newContentLf = newContentLf.slice(0, m.index) + input.replacement + newContentLf.slice(expectDefined(m.index) + m[0].length);
6117
6043
  }
6118
6044
  re.lastIndex = 0;
6119
6045
  totalReplacements += count;
@@ -6412,14 +6338,6 @@ function substituteVars(content, name, vars) {
6412
6338
  }
6413
6339
  return result;
6414
6340
  }
6415
-
6416
- // src/search.ts
6417
- function expectDefined12(value) {
6418
- if (value === null || value === void 0) {
6419
- throw new Error("Expected value to be defined");
6420
- }
6421
- return value;
6422
- }
6423
6341
  var DEFAULT_NUM = 10;
6424
6342
  var MAX_RESULTS = 50;
6425
6343
  var TIMEOUT_MS3 = 15e3;
@@ -6515,11 +6433,11 @@ function parseDuckDuckGo(html, num) {
6515
6433
  const snippetRegex = /<a class="result-link"[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>/gi;
6516
6434
  const snippet2Regex = /<a class="result-snippet"[^>]*>([^<]+)<\/a>/gi;
6517
6435
  const linkMatches = takeFrom(
6518
- [...html.matchAll(snippetRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined12(m[1]), title: stripTags2(expectDefined12(m[2])) })),
6436
+ [...html.matchAll(snippetRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined(m[1]), title: stripTags2(expectDefined(m[2])) })),
6519
6437
  num
6520
6438
  );
6521
6439
  const snippetMatches = takeFrom(
6522
- [...html.matchAll(snippet2Regex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined12(m[1]))),
6440
+ [...html.matchAll(snippet2Regex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
6523
6441
  num
6524
6442
  );
6525
6443
  for (let i = 0; i < linkMatches.length && i < num; i++) {
@@ -6550,15 +6468,15 @@ function parseGoogleResults(html, num) {
6550
6468
  const urlRegex = /<cite[^>]*>([^<]+)<\/cite>/gi;
6551
6469
  const snippetRegex = /<span[^>]*class="[^"]*aXCZ0b[^>]*>([^<]+)<\/span>/gi;
6552
6470
  const titles = takeFrom(
6553
- [...html.matchAll(titleRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined12(m[1]))),
6471
+ [...html.matchAll(titleRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
6554
6472
  num
6555
6473
  );
6556
6474
  const urls = takeFrom(
6557
- [...html.matchAll(urlRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined12(m[1])).replace(/^\*(https?:\/\/[^\s]+).*$/, "$1")).filter((u) => u.startsWith("http")),
6475
+ [...html.matchAll(urlRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1])).replace(/^\*(https?:\/\/[^\s]+).*$/, "$1")).filter((u) => u.startsWith("http")),
6558
6476
  num
6559
6477
  );
6560
6478
  const snippets = takeFrom(
6561
- [...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined12(m[1]))),
6479
+ [...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
6562
6480
  num
6563
6481
  );
6564
6482
  for (let i = 0; i < Math.min(titles.length, num); i++) {
@@ -6587,11 +6505,11 @@ function parseBingResults(html, num) {
6587
6505
  const titleRegex = /<h2[^>]*>\s*<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>\s*<\/h2>/gi;
6588
6506
  const snippetRegex = /<p[^>]*class="[^"]*b_paractl[^"]*"[^>]*>([^<]+)<\/p>/gi;
6589
6507
  const entries = takeFrom(
6590
- [...html.matchAll(titleRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined12(m[1]), title: stripTags2(expectDefined12(m[2])) })),
6508
+ [...html.matchAll(titleRegex)].filter((m) => m[1] && m[2]).map((m) => ({ url: expectDefined(m[1]), title: stripTags2(expectDefined(m[2])) })),
6591
6509
  num
6592
6510
  );
6593
6511
  const snippets = takeFrom(
6594
- [...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined12(m[1]))),
6512
+ [...html.matchAll(snippetRegex)].filter((m) => m[1]).map((m) => stripTags2(expectDefined(m[1]))),
6595
6513
  num
6596
6514
  );
6597
6515
  for (let i = 0; i < entries.length; i++) {
@@ -6632,6 +6550,147 @@ function anySignal(...signals) {
6632
6550
  function stripTags2(html) {
6633
6551
  return html.replace(/<[^>]+>/g, "").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").trim();
6634
6552
  }
6553
+ var taskTool = {
6554
+ name: "task",
6555
+ category: "Session",
6556
+ description: "Manage structured work items with dependencies, types, and priorities. Use this for complex, multi-step work where tasks have ordering constraints. Unlike `todo` (flat, tactical), `task` supports typed work (feature/bugfix/refactor/etc.), dependencies between items, priority ranking, and agent assignment. The task list persists across session resumes.",
6557
+ usageHint: 'USE FOR STRUCTURED WORK:\n- `action: "replace"` \u2014 set the complete task list (tasks ordered by priority)\n- `action: "add"` \u2014 append a single task\n- `action: "status"` \u2014 update a task\'s status (e.g. pending\u2192in_progress, in_progress\u2192completed)\n- `action: "show"` \u2014 view current tasks without changing them\n\nTask fields:\n- `dependsOn`: list of task IDs this one waits for\n- `type`: "feature" | "bugfix" | "refactor" | "docs" | "test" | "chore"\n- `priority`: "critical" | "high" | "medium" | "low"\n- `assignee`: agent/subagent name (e.g. "bug-hunter", "refactor-planner")\n- `estimateHours`: rough time estimate',
6558
+ permission: "auto",
6559
+ mutating: false,
6560
+ timeoutMs: 2e3,
6561
+ inputSchema: {
6562
+ type: "object",
6563
+ properties: {
6564
+ action: {
6565
+ type: "string",
6566
+ enum: ["replace", "add", "status", "show"],
6567
+ description: "replace = set full list, add = append, status = update task status, show = view only."
6568
+ },
6569
+ tasks: {
6570
+ type: "array",
6571
+ items: {
6572
+ type: "object",
6573
+ properties: {
6574
+ id: { type: "string", description: 'Unique id (e.g. "t1", "auth-flow").' },
6575
+ title: { type: "string", description: "Short title." },
6576
+ description: { type: "string", description: "Optional details." },
6577
+ type: { type: "string", enum: ["feature", "bugfix", "refactor", "docs", "test", "chore"] },
6578
+ priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
6579
+ status: { type: "string", enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"] },
6580
+ dependsOn: {
6581
+ type: "array",
6582
+ items: { type: "string" },
6583
+ description: "IDs of tasks this one depends on."
6584
+ },
6585
+ assignee: { type: "string", description: "Agent/subagent assigned." },
6586
+ estimateHours: { type: "number", description: "Estimated hours." },
6587
+ tags: { type: "array", items: { type: "string" }, description: "Optional tags." },
6588
+ createdAt: { type: "string" },
6589
+ updatedAt: { type: "string" }
6590
+ },
6591
+ required: ["id", "title", "type", "priority", "status"]
6592
+ },
6593
+ description: "Complete task list. Replaces previous list entirely."
6594
+ },
6595
+ task: {
6596
+ type: "object",
6597
+ properties: {
6598
+ title: { type: "string" },
6599
+ description: { type: "string" },
6600
+ type: { type: "string", enum: ["feature", "bugfix", "refactor", "docs", "test", "chore"] },
6601
+ priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
6602
+ status: { type: "string", enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"] },
6603
+ dependsOn: { type: "array", items: { type: "string" } },
6604
+ assignee: { type: "string" },
6605
+ estimateHours: { type: "number" },
6606
+ tags: { type: "array", items: { type: "string" } }
6607
+ },
6608
+ required: ["title", "type", "priority"],
6609
+ description: "Single task to append (id/createdAt/updatedAt auto-generated)."
6610
+ },
6611
+ id: { type: "string", description: "Task id for action=status." },
6612
+ status: {
6613
+ type: "string",
6614
+ enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"],
6615
+ description: "New status for action=status."
6616
+ }
6617
+ },
6618
+ required: ["action"]
6619
+ },
6620
+ async execute(input, ctx) {
6621
+ const taskPath = ctx.meta["task.path"];
6622
+ if (typeof taskPath !== "string" || !taskPath) {
6623
+ return { ok: false, message: "Task storage path not configured.", count: 0, completed: 0, inProgress: 0 };
6624
+ }
6625
+ const sessionId = ctx.session?.id ?? "unknown";
6626
+ let file = await loadTasks(taskPath) ?? emptyTaskFile(sessionId);
6627
+ switch (input.action) {
6628
+ case "show":
6629
+ break;
6630
+ case "replace": {
6631
+ if (!Array.isArray(input.tasks)) {
6632
+ return { ok: false, message: "action=replace requires `tasks` array.", count: 0, completed: 0, inProgress: 0 };
6633
+ }
6634
+ const now = (/* @__PURE__ */ new Date()).toISOString();
6635
+ file.tasks = input.tasks.map((t) => ({
6636
+ ...t,
6637
+ createdAt: t.createdAt || now,
6638
+ updatedAt: now
6639
+ }));
6640
+ await saveTasks(taskPath, file);
6641
+ break;
6642
+ }
6643
+ case "add": {
6644
+ const t = input.task;
6645
+ if (!t || !t.title) {
6646
+ return { ok: false, message: "action=add requires `task` with at least `title`.", count: 0, completed: 0, inProgress: 0 };
6647
+ }
6648
+ const now = (/* @__PURE__ */ new Date()).toISOString();
6649
+ const newTask = {
6650
+ id: `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
6651
+ title: t.title,
6652
+ description: t.description,
6653
+ type: t.type || "feature",
6654
+ priority: t.priority || "medium",
6655
+ status: t.status || "pending",
6656
+ dependsOn: t.dependsOn,
6657
+ assignee: t.assignee,
6658
+ estimateHours: t.estimateHours,
6659
+ tags: t.tags,
6660
+ createdAt: now,
6661
+ updatedAt: now
6662
+ };
6663
+ file.tasks.push(newTask);
6664
+ await saveTasks(taskPath, file);
6665
+ break;
6666
+ }
6667
+ case "status": {
6668
+ if (!input.id || !input.status) {
6669
+ return { ok: false, message: "action=status requires `id` and `status`.", count: 0, completed: 0, inProgress: 0 };
6670
+ }
6671
+ const task = file.tasks.find((t) => t.id === input.id);
6672
+ if (!task) {
6673
+ return { ok: false, message: `Task "${input.id}" not found.`, count: 0, completed: 0, inProgress: 0 };
6674
+ }
6675
+ task.status = input.status;
6676
+ task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
6677
+ await saveTasks(taskPath, file);
6678
+ break;
6679
+ }
6680
+ default:
6681
+ return { ok: false, message: `Unknown action "${input.action}". Use replace | add | status | show.`, count: 0, completed: 0, inProgress: 0 };
6682
+ }
6683
+ const p = computeTaskItemProgress(file.tasks);
6684
+ const summary = file.tasks.length > 0 ? formatTaskList(file.tasks) : "No tasks.";
6685
+ return {
6686
+ ok: true,
6687
+ message: summary,
6688
+ count: file.tasks.length,
6689
+ completed: p.completed,
6690
+ inProgress: p.inProgress
6691
+ };
6692
+ }
6693
+ };
6635
6694
  var testTool = {
6636
6695
  name: "test",
6637
6696
  category: "Code Quality",
@@ -7115,12 +7174,6 @@ var toolUseTool = {
7115
7174
  }
7116
7175
  }
7117
7176
  };
7118
- function expectDefined13(value) {
7119
- if (value === null || value === void 0) {
7120
- throw new Error("Expected value to be defined");
7121
- }
7122
- return value;
7123
- }
7124
7177
  var DEFAULT_IGNORE5 = [
7125
7178
  "node_modules",
7126
7179
  ".git",
@@ -7233,7 +7286,7 @@ var treeTool = {
7233
7286
  });
7234
7287
  while (!walkDone || queue.length > 0) {
7235
7288
  if (queue.length > 0) {
7236
- yield expectDefined13(queue.shift());
7289
+ yield expectDefined(queue.shift());
7237
7290
  } else {
7238
7291
  let pollTimer;
7239
7292
  const poll = new Promise((r) => {
@@ -7459,6 +7512,7 @@ var builtinTools = [
7459
7512
  searchTool,
7460
7513
  todoTool,
7461
7514
  planTool,
7515
+ taskTool,
7462
7516
  gitTool,
7463
7517
  patchTool,
7464
7518
  jsonTool,