@wrongstack/tools 0.306.4 → 0.307.1

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 (73) hide show
  1. package/dist/audit.js +14 -8
  2. package/dist/auto-proceed-loop-guard.js +8 -2
  3. package/dist/bash.js +57 -22
  4. package/dist/builtin.d.ts +6 -6
  5. package/dist/builtin.js +11469 -9304
  6. package/dist/clarify.d.ts +32 -0
  7. package/dist/codebase-index/ast-invariant-engine.d.ts +102 -0
  8. package/dist/codebase-index/ast-symbol-mutator.d.ts +28 -0
  9. package/dist/codebase-index/background-indexer.d.ts +9 -0
  10. package/dist/codebase-index/codebase-ast-replace-tool.d.ts +31 -0
  11. package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +42 -0
  12. package/dist/codebase-index/codebase-invariant-check-tool.d.ts +23 -0
  13. package/dist/codebase-index/codebase-repo-map-tool.d.ts +22 -0
  14. package/dist/codebase-index/codebase-skeleton-tool.d.ts +36 -0
  15. package/dist/codebase-index/codebase-targeted-test-tool.d.ts +30 -0
  16. package/dist/codebase-index/index.d.ts +11 -1
  17. package/dist/codebase-index/index.js +4239 -1492
  18. package/dist/codebase-index/project-server-client-state.d.ts +79 -0
  19. package/dist/codebase-index/project-server-client.d.ts +3 -71
  20. package/dist/codebase-index/project-server-protocol.d.ts +1 -0
  21. package/dist/codebase-index/project-server.js +819 -933
  22. package/dist/codebase-index/repo-map.d.ts +20 -0
  23. package/dist/codebase-index/skeleton-extractor.d.ts +64 -0
  24. package/dist/codebase-index/tree-sitter-parser.d.ts +11 -0
  25. package/dist/codebase-index/worker.js +790 -914
  26. package/dist/codebase-index/writer-graph-helpers.d.ts +1 -1
  27. package/dist/codebase-index/writer-helpers.d.ts +12 -0
  28. package/dist/codebase-index/writer-mutations.d.ts +26 -0
  29. package/dist/codebase-index/writer-refs.d.ts +50 -0
  30. package/dist/codebase-index/writer-search.d.ts +30 -0
  31. package/dist/codebase-index/writer.d.ts +2 -320
  32. package/dist/edit.js +8602 -349
  33. package/dist/exec.js +73 -20
  34. package/dist/fetch.js +11 -9
  35. package/dist/format.js +14 -8
  36. package/dist/glob.js +5 -1
  37. package/dist/grep.js +19 -8
  38. package/dist/index.d.ts +3 -1
  39. package/dist/index.js +6178 -4037
  40. package/dist/install.js +14 -8
  41. package/dist/json.js +88 -15
  42. package/dist/kanban-board-actions.d.ts +4 -0
  43. package/dist/kanban-lifecycle-actions.d.ts +4 -0
  44. package/dist/kanban-serializer.d.ts +21 -0
  45. package/dist/kanban.js +985 -1034
  46. package/dist/languages/index.js +14 -8
  47. package/dist/lint.js +14 -8
  48. package/dist/logs.js +13 -3
  49. package/dist/next-steps.d.ts +8 -0
  50. package/dist/next-steps.js +18 -0
  51. package/dist/outdated.js +14 -8
  52. package/dist/pack.js +11461 -9304
  53. package/dist/patch.js +8345 -78
  54. package/dist/plan.js +1231 -1281
  55. package/dist/process-registry.js +14 -8
  56. package/dist/ps-slash.js +65 -30
  57. package/dist/read.js +822 -937
  58. package/dist/replace.js +8494 -224
  59. package/dist/search.js +21 -15
  60. package/dist/security-ast-scan-tool.d.ts +43 -0
  61. package/dist/session-kanban-graph.d.ts +9 -0
  62. package/dist/session-kanban-sync.d.ts +31 -0
  63. package/dist/session-kanban.d.ts +5 -141
  64. package/dist/session-kanban.js +367 -360
  65. package/dist/task.js +1157 -1207
  66. package/dist/test.js +14 -8
  67. package/dist/todo.js +2187 -2237
  68. package/dist/tool-diff.js +6 -1
  69. package/dist/tool-summary.js +4 -2
  70. package/dist/tool-tier.js +11469 -9304
  71. package/dist/typecheck.js +14 -8
  72. package/dist/write.js +8425 -160
  73. package/package.json +7 -7
package/dist/exec.js CHANGED
@@ -289,9 +289,33 @@ var RULES = [
289
289
  id: "shell-launcher",
290
290
  level: "caution",
291
291
  test: (cmd, args) => {
292
- const launchers = ["env", "timeout", "nohup", "nice", "script", "expect", "tmux", "screen", "byobu", "dtach"];
292
+ const launchers = [
293
+ "env",
294
+ "timeout",
295
+ "nohup",
296
+ "nice",
297
+ "script",
298
+ "expect",
299
+ "tmux",
300
+ "screen",
301
+ "byobu",
302
+ "dtach"
303
+ ];
293
304
  if (!launchers.includes(cmd)) return false;
294
- const shells = ["sh", "bash", "zsh", "fish", "python", "python3", "perl", "ruby", "node", "pwsh", "powershell", "cmd"];
305
+ const shells = [
306
+ "sh",
307
+ "bash",
308
+ "zsh",
309
+ "fish",
310
+ "python",
311
+ "python3",
312
+ "perl",
313
+ "ruby",
314
+ "node",
315
+ "pwsh",
316
+ "powershell",
317
+ "cmd"
318
+ ];
295
319
  if (cmd === "env") {
296
320
  const prog = args.find((a) => !a.includes("=") && !a.startsWith("-"));
297
321
  return prog !== void 0 && shells.includes(prog);
@@ -888,13 +912,16 @@ function killWin32Tree(pid, opts = {}) {
888
912
  };
889
913
  child.on("error", settle);
890
914
  child.on("close", settle);
891
- timeout = setTimeout(() => {
892
- try {
893
- child.kill();
894
- } catch {
895
- }
896
- settle();
897
- }, Math.max(1, opts.timeoutMs ?? WIN32_TASKKILL_TIMEOUT_MS));
915
+ timeout = setTimeout(
916
+ () => {
917
+ try {
918
+ child.kill();
919
+ } catch {
920
+ }
921
+ settle();
922
+ },
923
+ Math.max(1, opts.timeoutMs ?? WIN32_TASKKILL_TIMEOUT_MS)
924
+ );
898
925
  timeout.unref?.();
899
926
  child.unref();
900
927
  return true;
@@ -1068,7 +1095,10 @@ var ProcessRegistryImpl = class {
1068
1095
  getBreakerCountdown() {
1069
1096
  if (this.autoKillArmedAt === null || this.autoKillResetMs <= 0) return null;
1070
1097
  const elapsed = Date.now() - this.autoKillArmedAt;
1071
- return { remainingMs: Math.max(0, this.autoKillResetMs - elapsed), totalMs: this.autoKillResetMs };
1098
+ return {
1099
+ remainingMs: Math.max(0, this.autoKillResetMs - elapsed),
1100
+ totalMs: this.autoKillResetMs
1101
+ };
1072
1102
  }
1073
1103
  /**
1074
1104
  * Subscribe to countdown arm/cancel events. Returns an unsubscribe function.
@@ -1383,12 +1413,16 @@ async function readRegistryFile(filePath) {
1383
1413
  }
1384
1414
  async function writeRegistryFile(filePath, data) {
1385
1415
  const tmpPath = `${filePath}.tmp.${process.pid}`;
1386
- const content = JSON.stringify(data, (_k, v) => {
1387
- if (v instanceof Map) {
1388
- return Array.from(v.entries());
1389
- }
1390
- return v;
1391
- }, 2);
1416
+ const content = JSON.stringify(
1417
+ data,
1418
+ (_k, v) => {
1419
+ if (v instanceof Map) {
1420
+ return Array.from(v.entries());
1421
+ }
1422
+ return v;
1423
+ },
1424
+ 2
1425
+ );
1392
1426
  await fs2.writeFile(tmpPath, content, "utf-8");
1393
1427
  await fs2.rename(tmpPath, filePath);
1394
1428
  }
@@ -1416,7 +1450,12 @@ var PersistentProcessRegistry = class {
1416
1450
  this.lockPath = path4.join(globalRoot, LOCKFILE);
1417
1451
  this.baseRegistry = baseRegistry ?? getProcessRegistry();
1418
1452
  this.ensureDirectory().catch((err) => {
1419
- emitStructuredLog("warn", "process_registry.dir_create_failed", "PersistentProcessRegistry: failed to create .wrongstack directory", err);
1453
+ emitStructuredLog(
1454
+ "warn",
1455
+ "process_registry.dir_create_failed",
1456
+ "PersistentProcessRegistry: failed to create .wrongstack directory",
1457
+ err
1458
+ );
1420
1459
  });
1421
1460
  }
1422
1461
  async ensureDirectory() {
@@ -1607,7 +1646,12 @@ var PersistentProcessRegistry = class {
1607
1646
  data.lastCleanup = now;
1608
1647
  await writeRegistryFile(this.registryPath, data);
1609
1648
  } catch (err) {
1610
- emitStructuredLog("warn", "process_registry.sync_failed", "PersistentProcessRegistry: sync failed", err);
1649
+ emitStructuredLog(
1650
+ "warn",
1651
+ "process_registry.sync_failed",
1652
+ "PersistentProcessRegistry: sync failed",
1653
+ err
1654
+ );
1611
1655
  } finally {
1612
1656
  await release();
1613
1657
  }
@@ -1646,7 +1690,12 @@ var PersistentProcessRegistry = class {
1646
1690
  await writeRegistryFile(this.registryPath, data);
1647
1691
  }
1648
1692
  } catch (err) {
1649
- emitStructuredLog("warn", "process_registry.cleanup_failed", "PersistentProcessRegistry: cleanup failed", err);
1693
+ emitStructuredLog(
1694
+ "warn",
1695
+ "process_registry.cleanup_failed",
1696
+ "PersistentProcessRegistry: cleanup failed",
1697
+ err
1698
+ );
1650
1699
  } finally {
1651
1700
  await release();
1652
1701
  }
@@ -1795,7 +1844,11 @@ async function checkExecKillCommand(cmd, args) {
1795
1844
  if (filterArg) {
1796
1845
  const nameMatch = filterArg.match(/IMAGENAME\s+eq\s+"?([^"\s]+)/i);
1797
1846
  if (nameMatch?.[1]) {
1798
- const result = await checkKillTarget({ name: nameMatch[1], signal, cmd: fullCommand });
1847
+ const result = await checkKillTarget({
1848
+ name: nameMatch[1],
1849
+ signal,
1850
+ cmd: fullCommand
1851
+ });
1799
1852
  if (result.blocked) return result;
1800
1853
  }
1801
1854
  }
package/dist/fetch.js CHANGED
@@ -5,10 +5,7 @@ import TurndownService from "turndown";
5
5
  // src/_fetch-guard.ts
6
6
  import * as dns from "node:dns/promises";
7
7
  import * as net from "node:net";
8
- import {
9
- isPrivateIPv4,
10
- isPrivateIPv6
11
- } from "@wrongstack/core/utils";
8
+ import { isPrivateIPv4, isPrivateIPv6 } from "@wrongstack/core/utils";
12
9
  import { FetchError, ToolValidationError } from "@wrongstack/core/types";
13
10
  import { Agent, fetch as undiciFetch } from "undici";
14
11
  var nativeGlobalFetch = globalThis.fetch;
@@ -275,11 +272,16 @@ var fetchTool = {
275
272
  await assertNotPrivate(u.hostname);
276
273
  yield { type: "log", text: `GET ${input.url}` };
277
274
  const ctrl = new AbortController();
278
- const timer = setTimeout(() => ctrl.abort(new ToolError({
279
- message: "fetch timeout",
280
- code: "TOOL_TIMEOUT",
281
- toolName: "fetch"
282
- })), TIMEOUT_MS);
275
+ const timer = setTimeout(
276
+ () => ctrl.abort(
277
+ new ToolError({
278
+ message: "fetch timeout",
279
+ code: "TOOL_TIMEOUT",
280
+ toolName: "fetch"
281
+ })
282
+ ),
283
+ TIMEOUT_MS
284
+ );
283
285
  const combined = combineSignals([opts.signal, ctrl.signal]);
284
286
  try {
285
287
  let res;
package/dist/format.js CHANGED
@@ -422,13 +422,16 @@ function killWin32Tree(pid, opts = {}) {
422
422
  };
423
423
  child.on("error", settle);
424
424
  child.on("close", settle);
425
- timeout = setTimeout(() => {
426
- try {
427
- child.kill();
428
- } catch {
429
- }
430
- settle();
431
- }, Math.max(1, opts.timeoutMs ?? WIN32_TASKKILL_TIMEOUT_MS));
425
+ timeout = setTimeout(
426
+ () => {
427
+ try {
428
+ child.kill();
429
+ } catch {
430
+ }
431
+ settle();
432
+ },
433
+ Math.max(1, opts.timeoutMs ?? WIN32_TASKKILL_TIMEOUT_MS)
434
+ );
432
435
  timeout.unref?.();
433
436
  child.unref();
434
437
  return true;
@@ -602,7 +605,10 @@ var ProcessRegistryImpl = class {
602
605
  getBreakerCountdown() {
603
606
  if (this.autoKillArmedAt === null || this.autoKillResetMs <= 0) return null;
604
607
  const elapsed = Date.now() - this.autoKillArmedAt;
605
- return { remainingMs: Math.max(0, this.autoKillResetMs - elapsed), totalMs: this.autoKillResetMs };
608
+ return {
609
+ remainingMs: Math.max(0, this.autoKillResetMs - elapsed),
610
+ totalMs: this.autoKillResetMs
611
+ };
606
612
  }
607
613
  /**
608
614
  * Subscribe to countdown arm/cancel events. Returns an unsubscribe function.
package/dist/glob.js CHANGED
@@ -267,7 +267,11 @@ var globTool = {
267
267
  await mapWithConcurrency(matchedFiles, WALK_CONCURRENCY, pushResult);
268
268
  if (truncated) return;
269
269
  const remainingSubdirs = truncated ? [] : subdirs;
270
- await mapWithConcurrency(remainingSubdirs, WALK_CONCURRENCY, ({ full, rel }) => walk(full, rel));
270
+ await mapWithConcurrency(
271
+ remainingSubdirs,
272
+ WALK_CONCURRENCY,
273
+ ({ full, rel }) => walk(full, rel)
274
+ );
271
275
  };
272
276
  await walk(base, "");
273
277
  results.sort((a, b) => b.mtime - a.mtime);
package/dist/grep.js CHANGED
@@ -406,7 +406,10 @@ async function* runRgStream(input, base, mode, limit, signal) {
406
406
  args.push("--glob", `!${ignored}/**`, "--glob", `!**/${ignored}/**`);
407
407
  }
408
408
  const gitignorePath = path3.join(base, ".gitignore");
409
- if (await fs2.access(gitignorePath).then(() => true, () => false)) {
409
+ if (await fs2.access(gitignorePath).then(
410
+ () => true,
411
+ () => false
412
+ )) {
410
413
  args.push("--ignore-file", gitignorePath);
411
414
  }
412
415
  if (input.glob) args.push("--glob", input.glob);
@@ -440,14 +443,12 @@ async function* runRgStream(input, base, mode, limit, signal) {
440
443
  }
441
444
  };
442
445
  const pauseIfFlooded = () => {
443
- if (paused || queue.length < RG_MAX_QUEUE_CHUNKS && queuedChars < RG_MAX_QUEUE_CHARS)
444
- return;
446
+ if (paused || queue.length < RG_MAX_QUEUE_CHUNKS && queuedChars < RG_MAX_QUEUE_CHARS) return;
445
447
  paused = true;
446
448
  child.stdout?.pause();
447
449
  };
448
450
  const resumeIfDrained = () => {
449
- if (!paused || queue.length >= RG_MAX_QUEUE_CHUNKS || queuedChars >= RG_MAX_QUEUE_CHARS)
450
- return;
451
+ if (!paused || queue.length >= RG_MAX_QUEUE_CHUNKS || queuedChars >= RG_MAX_QUEUE_CHARS) return;
451
452
  paused = false;
452
453
  child.stdout?.resume();
453
454
  };
@@ -607,7 +608,12 @@ async function runNative(input, base, mode, limit, signal) {
607
608
  const buffer = Buffer.allocUnsafe(Math.min(NATIVE_READ_CHUNK_BYTES, maxBytes));
608
609
  while (!stopped && !signal.aborted && bytesReadTotal < maxBytes) {
609
610
  const remaining = maxBytes - bytesReadTotal;
610
- const { bytesRead } = await file.read(buffer, 0, Math.min(buffer.length, remaining), null);
611
+ const { bytesRead } = await file.read(
612
+ buffer,
613
+ 0,
614
+ Math.min(buffer.length, remaining),
615
+ null
616
+ );
611
617
  if (bytesRead === 0) break;
612
618
  const chunk = buffer.subarray(0, bytesRead);
613
619
  if (!binaryChecked) {
@@ -665,7 +671,8 @@ async function runNative(input, base, mode, limit, signal) {
665
671
  if (mode === "files_with_matches" && matches.length >= limit) stopped = true;
666
672
  }
667
673
  if (mode === "content" && matches.length >= limit) stopped = true;
668
- if (mode === "count" && matches.length >= limit && (countOnlyFirstHit || mode !== "count")) stopped = true;
674
+ if (mode === "count" && matches.length >= limit && (countOnlyFirstHit || mode !== "count"))
675
+ stopped = true;
669
676
  } finally {
670
677
  await file.close();
671
678
  }
@@ -696,7 +703,11 @@ async function runNative(input, base, mode, limit, signal) {
696
703
  files.push({ full, name: e.name });
697
704
  }
698
705
  }
699
- await mapWithConcurrency(files, NATIVE_SCAN_CONCURRENCY, ({ full, name }) => scanFile(full, name));
706
+ await mapWithConcurrency(
707
+ files,
708
+ NATIVE_SCAN_CONCURRENCY,
709
+ ({ full, name }) => scanFile(full, name)
710
+ );
700
711
  await mapWithConcurrency(
701
712
  subdirs,
702
713
  Math.min(16, NATIVE_SCAN_CONCURRENCY),
package/dist/index.d.ts CHANGED
@@ -8,7 +8,8 @@ export * from './browser/index.js';
8
8
  export { builtinTools, OFF_ONLY_TOOLS, OPTIONAL_TOOLS, TIER1_TOOLS, TIER2_TOOLS, TIER3_TOOLS, } from './builtin.js';
9
9
  export { CircuitBreaker, type CircuitBreakerConfig, type CircuitBreakerSnapshot, } from './circuit-breaker.js';
10
10
  export type { CircuitSnapshot, CircuitState, CodeMapGraph, DeadCodeScanInput, DeadCodeScanOutput, DeadFile, DeadPackage, DeadSymbol, GraphEdge, GraphNode, ProjectIndexDaemonAvailability, ProjectIndexServerActivity, ProjectIndexServerClientHealth, ProjectIndexServerConnectionState, ProjectIndexServerConnectionStatus, ProjectIndexServerHealth, } from './codebase-index/index.js';
11
- export { CircuitOpenError, cancelPendingReindexes, checkCodebaseIndexServerHealth, codebaseIndexStats, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, deadCodeScanTool, enqueueReindex, ensureCodebaseIndexServer, fileGraphService, getIndexState, IndexCircuitBreaker, IndexTimeoutError, indexCircuitBreaker, isIndexableFile, isIndexing, isIndexReady, onIndexStateChange, packageGraphService, resetIndexCircuitBreaker, resolveProjectIndexDaemonAvailability, runDeadCodeScan, runStartupIndex, searchCodebaseIndex, shutdownCodebaseIndexHost, shutdownCodebaseIndexServer, symbolGraphService, } from './codebase-index/index.js';
11
+ export { clarifyTool, type ClarifyQuestionInput, type ClarifyOutput, } from './clarify.js';
12
+ export { CircuitOpenError, cancelPendingReindexes, checkCodebaseIndexServerHealth, codebaseAstReplaceTool, codebaseImpactAnalysisTool, codebaseIndexStats, codebaseIndexTool, codebaseInvariantCheckTool, codebaseRepoMapTool, codebaseSearchTool, codebaseSkeletonTool, codebaseStatsTool, codebaseTargetedTestTool, deadCodeScanTool, enqueueReindex, ensureCodebaseIndexServer, extractDirectorySkeleton, extractFileSkeleton, generateRepoMap, replaceSymbolInFile, type FileSkeletonResult, type MutateSymbolOptions, type MutateSymbolResult, type RepoMapOptions, type RepoMapResult, type SkeletonOptions, type SkeletonSymbolRange, fileGraphService, getIndexState, IndexCircuitBreaker, IndexTimeoutError, indexCircuitBreaker, isIndexableFile, isIndexing, isIndexReady, onIndexStateChange, packageGraphService, resetIndexCircuitBreaker, resolveProjectIndexDaemonAvailability, runDeadCodeScan, runStartupIndex, searchCodebaseIndex, shutdownCodebaseIndexHost, shutdownCodebaseIndexServer, symbolGraphService, } from './codebase-index/index.js';
12
13
  export { designTool } from './design.js';
13
14
  export { diffTool } from './diff.js';
14
15
  export { documentTool } from './document.js';
@@ -43,6 +44,7 @@ export { readTool } from './read.js';
43
44
  export { replaceTool } from './replace.js';
44
45
  export { scaffoldTool } from './scaffold.js';
45
46
  export { searchTool } from './search.js';
47
+ export { analyzeSecurityAndPerformance, securityAstScanTool, type SecurityFinding, type SecurityScanInput, type SecurityScanOutput, } from './security-ast-scan-tool.js';
46
48
  export { applySessionKanbanBoardToTodos, applySessionKanbanTaskToSource, attachSessionKanbanMirror, ensureSessionKanbanBoard, hydrateSessionKanban, mirrorSessionPlanToKanban, mirrorSessionTasksToKanban, mirrorSessionTodosToKanban, projectSessionPlanToKanban, projectSessionTasksToKanban, projectSessionTodosToKanban, rebindSessionKanbanTask, SESSION_KANBAN_COLUMNS, } from './session-kanban.js';
47
49
  export { makeSkillTool } from './skill.js';
48
50
  export { taskTool } from './task.js';