@wrongstack/tools 0.286.0 → 0.289.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 (120) hide show
  1. package/README.md +2 -2
  2. package/dist/_edit-match.d.ts.map +1 -1
  3. package/dist/_fetch-guard.d.ts.map +1 -1
  4. package/dist/_redact-command.d.ts.map +1 -1
  5. package/dist/_spawn-stream.d.ts.map +1 -1
  6. package/dist/audit.js +61 -14
  7. package/dist/audit.js.map +3 -3
  8. package/dist/bash.d.ts +1 -1
  9. package/dist/bash.d.ts.map +1 -1
  10. package/dist/bash.js +97 -19
  11. package/dist/bash.js.map +3 -3
  12. package/dist/batch-tool-use.d.ts +1 -1
  13. package/dist/batch-tool-use.d.ts.map +1 -1
  14. package/dist/batch-tool-use.js +26 -8
  15. package/dist/batch-tool-use.js.map +2 -2
  16. package/dist/browser/index.js +1 -1
  17. package/dist/browser/index.js.map +1 -1
  18. package/dist/browser/types.d.ts +1 -1
  19. package/dist/browser/types.d.ts.map +1 -1
  20. package/dist/builtin.d.ts +12 -10
  21. package/dist/builtin.d.ts.map +1 -1
  22. package/dist/builtin.js +2107 -864
  23. package/dist/builtin.js.map +4 -4
  24. package/dist/codebase-index/background-indexer.d.ts.map +1 -1
  25. package/dist/codebase-index/bm25.d.ts +1 -2
  26. package/dist/codebase-index/bm25.d.ts.map +1 -1
  27. package/dist/codebase-index/codebase-index-tool.d.ts.map +1 -1
  28. package/dist/codebase-index/codebase-search-tool.d.ts.map +1 -1
  29. package/dist/codebase-index/codebase-stats-tool.d.ts +7 -0
  30. package/dist/codebase-index/codebase-stats-tool.d.ts.map +1 -1
  31. package/dist/codebase-index/go-parser.d.ts.map +1 -1
  32. package/dist/codebase-index/index-service.d.ts +11 -1
  33. package/dist/codebase-index/index-service.d.ts.map +1 -1
  34. package/dist/codebase-index/index.d.ts +2 -1
  35. package/dist/codebase-index/index.d.ts.map +1 -1
  36. package/dist/codebase-index/index.js +934 -283
  37. package/dist/codebase-index/index.js.map +4 -4
  38. package/dist/codebase-index/indexer.d.ts.map +1 -1
  39. package/dist/codebase-index/py-parser.d.ts.map +1 -1
  40. package/dist/codebase-index/rs-parser.d.ts.map +1 -1
  41. package/dist/codebase-index/schema.d.ts +43 -1
  42. package/dist/codebase-index/schema.d.ts.map +1 -1
  43. package/dist/codebase-index/ts-parser.d.ts.map +1 -1
  44. package/dist/codebase-index/worker-protocol.d.ts +1 -0
  45. package/dist/codebase-index/worker-protocol.d.ts.map +1 -1
  46. package/dist/codebase-index/worker.js +793 -241
  47. package/dist/codebase-index/worker.js.map +4 -4
  48. package/dist/codebase-index/writer.d.ts +27 -1
  49. package/dist/codebase-index/writer.d.ts.map +1 -1
  50. package/dist/e2e.js +477 -0
  51. package/dist/e2e.js.map +7 -0
  52. package/dist/edit.d.ts.map +1 -1
  53. package/dist/edit.js +36 -12
  54. package/dist/edit.js.map +3 -3
  55. package/dist/exec.d.ts +1 -1
  56. package/dist/exec.d.ts.map +1 -1
  57. package/dist/exec.js +60 -5
  58. package/dist/exec.js.map +3 -3
  59. package/dist/fetch.js +2 -2
  60. package/dist/fetch.js.map +2 -2
  61. package/dist/format.js +61 -14
  62. package/dist/format.js.map +3 -3
  63. package/dist/glob.js +2 -2
  64. package/dist/glob.js.map +1 -1
  65. package/dist/grep.d.ts.map +1 -1
  66. package/dist/grep.js +2 -2
  67. package/dist/grep.js.map +2 -2
  68. package/dist/index.d.ts +3 -1
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +2535 -865
  71. package/dist/index.js.map +4 -4
  72. package/dist/install.js +61 -14
  73. package/dist/install.js.map +3 -3
  74. package/dist/kanban.d.ts +16 -2
  75. package/dist/kanban.d.ts.map +1 -1
  76. package/dist/kanban.js +795 -532
  77. package/dist/kanban.js.map +4 -4
  78. package/dist/languages/detect.d.ts.map +1 -1
  79. package/dist/languages/index.js +61 -14
  80. package/dist/languages/index.js.map +3 -3
  81. package/dist/languages/types.d.ts +7 -0
  82. package/dist/languages/types.d.ts.map +1 -1
  83. package/dist/lint.js +61 -14
  84. package/dist/lint.js.map +3 -3
  85. package/dist/next-steps.d.ts +6 -2
  86. package/dist/next-steps.d.ts.map +1 -1
  87. package/dist/next-steps.js +3 -3
  88. package/dist/next-steps.js.map +2 -2
  89. package/dist/outdated.js +61 -14
  90. package/dist/outdated.js.map +3 -3
  91. package/dist/pack.js +2104 -861
  92. package/dist/pack.js.map +4 -4
  93. package/dist/plan.d.ts.map +1 -1
  94. package/dist/plan.js +158 -4
  95. package/dist/plan.js.map +4 -4
  96. package/dist/process-registry.js +12 -5
  97. package/dist/process-registry.js.map +2 -2
  98. package/dist/search.js +2 -2
  99. package/dist/search.js.map +2 -2
  100. package/dist/session-kanban.d.ts +47 -0
  101. package/dist/session-kanban.d.ts.map +1 -0
  102. package/dist/session-kanban.js +626 -0
  103. package/dist/session-kanban.js.map +7 -0
  104. package/dist/task.d.ts.map +1 -1
  105. package/dist/task.js +167 -4
  106. package/dist/task.js.map +4 -4
  107. package/dist/test.js +61 -14
  108. package/dist/test.js.map +3 -3
  109. package/dist/todo.d.ts.map +1 -1
  110. package/dist/todo.js +159 -7
  111. package/dist/todo.js.map +4 -4
  112. package/dist/tool-icon-map.d.ts.map +1 -1
  113. package/dist/tool-icons.d.ts.map +1 -1
  114. package/dist/tool-icons.js +7 -1
  115. package/dist/tool-icons.js.map +2 -2
  116. package/dist/tree.js +2 -2
  117. package/dist/tree.js.map +1 -1
  118. package/dist/typecheck.js +61 -14
  119. package/dist/typecheck.js.map +3 -3
  120. package/package.json +11 -3
package/dist/typecheck.js CHANGED
@@ -3,7 +3,12 @@ import * as path9 from "node:path";
3
3
 
4
4
  // src/_spawn-stream.ts
5
5
  import { spawn as spawn2 } from "node:child_process";
6
- import { buildChildEnv } from "@wrongstack/core";
6
+ import {
7
+ buildChildEnv,
8
+ emitProcessCompleted,
9
+ emitProcessOutput,
10
+ emitProcessStarted
11
+ } from "@wrongstack/core";
7
12
 
8
13
  // src/_output-spool.ts
9
14
  import { createWriteStream, mkdirSync } from "node:fs";
@@ -313,9 +318,14 @@ import { expectDefined } from "@wrongstack/core";
313
318
  var SENSITIVE_FLAG_PATTERNS = [
314
319
  // --flag=value or --flag "value" (value captured up to next space or comma)
315
320
  /--(?: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,
316
- // -f "value" style short flags
317
- /(?<!\w)-t(?:\s+|\s*=\s*)[^\s,]+/,
318
- /(?<!\w)-(?:p|password)(?:\s+|\s*=\s*)[^\s,]+/gi,
321
+ // -t short flag (token): attached (-tVALUE), separated (-t VALUE), or -t=VALUE.
322
+ // (?<![-\w]) anchors to a token start so we don't match the `-t` inside `--token`.
323
+ // NOTE: synced with @wrongstack/core observability/redact-command.ts.
324
+ /(?<![-\w])-t(?:[=\s]+)?[^\s,-]+/,
325
+ // -p|-password|-a (redis auth) short flags: attached + separated + =value.
326
+ // Same token-start anchor; over-redaction is an accepted tradeoff for a
327
+ // redaction function. Synced with core copy.
328
+ /(?<![-\w])-(?:password|p|a)(?:[=\s]+)?[^\s,-]+/gi,
319
329
  // env var–style secrets: TOKEN=x, API_KEY=y, etc.
320
330
  /(?:TOKEN|API_KEY|API_SECRET|AUTH_TOKEN|GITHUB_TOKEN|GH_TOKEN|BEARER|JWT|OAUTH|CREDENTIAL|SECRET|PRIVATE_KEY|PASSWORD|PASSWD)\s*[=:]\s*[^\s,]+/gi,
321
331
  // Generic high-entropy look: base64 strings >32 chars or hex strings >32 digits — but only
@@ -333,8 +343,10 @@ function redactCommand(cmd) {
333
343
  const flag = match.slice(0, match.indexOf(expectDefined(delim)) + 1);
334
344
  return `${flag}[REDACTED]`;
335
345
  }
336
- const flagEnd = match.match(/^--?[a-zA-Z][a-zA-Z0-9_-]*/)?.[0] ?? match;
337
- return `${flagEnd}=**redacted**`;
346
+ if (match.startsWith("--")) {
347
+ return match;
348
+ }
349
+ return `${match.slice(0, 2)}[REDACTED]`;
338
350
  });
339
351
  }
340
352
  return result;
@@ -771,6 +783,19 @@ async function* spawnStream(opts) {
771
783
  });
772
784
  const registry = getProcessRegistry();
773
785
  const pid = child.pid;
786
+ const processStartedAt = Date.now();
787
+ let stdoutBytes = 0;
788
+ let stderrBytes = 0;
789
+ let telemetryCompleted = false;
790
+ emitProcessStarted({
791
+ ...pid !== void 0 ? { pid } : {},
792
+ parentPid: process.pid,
793
+ command: redactCommand(`${opts.cmd} ${opts.args.join(" ")}`),
794
+ args: redactCommand(opts.args.join(" ")).split(" ").filter(Boolean),
795
+ cwd: opts.cwd,
796
+ background: false,
797
+ startedAt: new Date(processStartedAt).toISOString()
798
+ });
774
799
  if (typeof pid === "number") {
775
800
  registry.register({
776
801
  pid,
@@ -799,6 +824,8 @@ async function* spawnStream(opts) {
799
824
  };
800
825
  const onOut = (c) => {
801
826
  const s = c.toString();
827
+ stdoutBytes += c.byteLength;
828
+ emitProcessOutput({ pid, stream: "stdout", chunk: c });
802
829
  if (stdout.length < max) stdout += s;
803
830
  spool.write(s);
804
831
  queue.push({ kind: "out", data: s });
@@ -811,6 +838,8 @@ async function* spawnStream(opts) {
811
838
  };
812
839
  const onErr = (c) => {
813
840
  const s = c.toString();
841
+ stderrBytes += c.byteLength;
842
+ emitProcessOutput({ pid, stream: "stderr", chunk: c });
814
843
  if (stderr.length < max) stderr += s;
815
844
  spool.write(s);
816
845
  queue.push({ kind: "err", data: s });
@@ -828,9 +857,25 @@ async function* spawnStream(opts) {
828
857
  queue.push({ kind: "error", data: e.message });
829
858
  wake();
830
859
  });
831
- child.on("close", (code) => {
860
+ const completeTelemetry = (code, signal, timedOut = false) => {
861
+ if (telemetryCompleted) return;
862
+ telemetryCompleted = true;
863
+ emitProcessCompleted({
864
+ ...pid !== void 0 ? { pid } : {},
865
+ exitCode: code,
866
+ ...signal ? { signal } : {},
867
+ durationMs: Date.now() - processStartedAt,
868
+ stdoutBytes,
869
+ stderrBytes,
870
+ timedOut,
871
+ endedAt: (/* @__PURE__ */ new Date()).toISOString()
872
+ });
873
+ };
874
+ child.on("close", (code, signal) => {
832
875
  if (typeof pid === "number") registry.unregister(pid);
833
- queue.push({ kind: "close", data: "", code: code ?? 0 });
876
+ const exitCode2 = code ?? (signal ? 1 : 0);
877
+ completeTelemetry(exitCode2, signal ?? void 0);
878
+ queue.push({ kind: "close", data: "", code: exitCode2, ...signal ? { signal } : {} });
834
879
  wake();
835
880
  });
836
881
  const onAbort = () => {
@@ -843,6 +888,7 @@ async function* spawnStream(opts) {
843
888
  }
844
889
  }
845
890
  queue.push({ kind: "close", data: "", code: 124 });
891
+ completeTelemetry(124, "SIGKILL", true);
846
892
  wake();
847
893
  };
848
894
  if (isWin) {
@@ -2371,13 +2417,14 @@ async function detectLanguageWorkspaces(options) {
2371
2417
  const target = options.target ? await canonicalInside(resolveFrom(cwd, options.target), projectRoot, "target") : void 0;
2372
2418
  const profiles = (options.profiles ?? languageProfileRegistry.list()).filter((profile) => !options.language || profile.id === options.language).slice().sort((a, b) => a.id.localeCompare(b.id));
2373
2419
  const limits = normalizeLimits(options.limits);
2420
+ const extraIgnores = new Set(options.ignoredDirectories ?? []);
2374
2421
  const state = {
2375
2422
  entries: 0,
2376
2423
  truncated: false,
2377
2424
  sourcePaths: /* @__PURE__ */ new Map(),
2378
2425
  candidates: /* @__PURE__ */ new Map()
2379
2426
  };
2380
- await scanDirectory(projectRoot, 0, profiles, limits, state, options.signal);
2427
+ await scanDirectory(projectRoot, 0, profiles, limits, state, extraIgnores, options.signal);
2381
2428
  addSourceFallbacks(projectRoot, profiles, state);
2382
2429
  if (target) addTargetEvidence(target, projectRoot, profiles, state);
2383
2430
  const workspaces = await Promise.all(
@@ -2391,7 +2438,7 @@ async function detectLanguageWorkspaces(options) {
2391
2438
  workspaces
2392
2439
  };
2393
2440
  }
2394
- async function scanDirectory(directory, depth, profiles, limits, state, signal) {
2441
+ async function scanDirectory(directory, depth, profiles, limits, state, extraIgnores, signal) {
2395
2442
  signal?.throwIfAborted();
2396
2443
  if (depth > limits.maxDepth || state.entries >= limits.maxEntries) {
2397
2444
  state.truncated = true;
@@ -2414,12 +2461,12 @@ async function scanDirectory(directory, depth, profiles, limits, state, signal)
2414
2461
  const fullPath = path4.join(directory, entry.name);
2415
2462
  if (entry.isSymbolicLink()) continue;
2416
2463
  if (entry.isDirectory()) {
2417
- if (shouldIgnoreDirectory(entry.name, profiles)) continue;
2464
+ if (shouldIgnoreDirectory(entry.name, profiles, extraIgnores)) continue;
2418
2465
  if (depth >= limits.maxDepth) {
2419
2466
  state.truncated = true;
2420
2467
  continue;
2421
2468
  }
2422
- await scanDirectory(fullPath, depth + 1, profiles, limits, state, signal);
2469
+ await scanDirectory(fullPath, depth + 1, profiles, limits, state, extraIgnores, signal);
2423
2470
  continue;
2424
2471
  }
2425
2472
  if (!entry.isFile()) continue;
@@ -2548,8 +2595,8 @@ function getCandidate(state, profile, root) {
2548
2595
  }
2549
2596
  return candidate;
2550
2597
  }
2551
- function shouldIgnoreDirectory(name, profiles) {
2552
- if (GLOBAL_IGNORES.has(name) || name.startsWith(".")) return true;
2598
+ function shouldIgnoreDirectory(name, profiles, extraIgnores) {
2599
+ if (GLOBAL_IGNORES.has(name) || extraIgnores.has(name) || name.startsWith(".")) return true;
2553
2600
  return profiles.some((profile) => profile.ignoredDirectories.includes(name));
2554
2601
  }
2555
2602
  function normalizeLimits(input) {