@wrongstack/tools 0.287.0 → 0.291.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 (102) hide show
  1. package/dist/_fetch-guard.d.ts.map +1 -1
  2. package/dist/_redact-command.d.ts.map +1 -1
  3. package/dist/_spawn-stream.d.ts.map +1 -1
  4. package/dist/audit.js +61 -14
  5. package/dist/audit.js.map +3 -3
  6. package/dist/auto-proceed-loop-guard.d.ts +128 -0
  7. package/dist/auto-proceed-loop-guard.d.ts.map +1 -0
  8. package/dist/auto-proceed-loop-guard.js +46 -0
  9. package/dist/auto-proceed-loop-guard.js.map +7 -0
  10. package/dist/bash.d.ts +1 -1
  11. package/dist/bash.d.ts.map +1 -1
  12. package/dist/bash.js +97 -19
  13. package/dist/bash.js.map +3 -3
  14. package/dist/builtin.d.ts +12 -10
  15. package/dist/builtin.d.ts.map +1 -1
  16. package/dist/builtin.js +1766 -864
  17. package/dist/builtin.js.map +3 -3
  18. package/dist/codebase-index/background-indexer.d.ts +1 -1
  19. package/dist/codebase-index/background-indexer.d.ts.map +1 -1
  20. package/dist/codebase-index/bm25.d.ts +1 -2
  21. package/dist/codebase-index/bm25.d.ts.map +1 -1
  22. package/dist/codebase-index/codebase-index-tool.d.ts.map +1 -1
  23. package/dist/codebase-index/codebase-search-tool.d.ts.map +1 -1
  24. package/dist/codebase-index/codebase-stats-tool.d.ts +7 -0
  25. package/dist/codebase-index/codebase-stats-tool.d.ts.map +1 -1
  26. package/dist/codebase-index/index-service.d.ts +11 -1
  27. package/dist/codebase-index/index-service.d.ts.map +1 -1
  28. package/dist/codebase-index/index.d.ts +2 -1
  29. package/dist/codebase-index/index.d.ts.map +1 -1
  30. package/dist/codebase-index/index.js +888 -254
  31. package/dist/codebase-index/index.js.map +3 -3
  32. package/dist/codebase-index/indexer.d.ts.map +1 -1
  33. package/dist/codebase-index/refs-extractor.d.ts +2 -17
  34. package/dist/codebase-index/refs-extractor.d.ts.map +1 -1
  35. package/dist/codebase-index/schema.d.ts +43 -1
  36. package/dist/codebase-index/schema.d.ts.map +1 -1
  37. package/dist/codebase-index/ts-parser.d.ts.map +1 -1
  38. package/dist/codebase-index/worker-protocol.d.ts +1 -0
  39. package/dist/codebase-index/worker-protocol.d.ts.map +1 -1
  40. package/dist/codebase-index/worker.js +738 -212
  41. package/dist/codebase-index/worker.js.map +3 -3
  42. package/dist/codebase-index/writer.d.ts +60 -1
  43. package/dist/codebase-index/writer.d.ts.map +1 -1
  44. package/dist/e2e.js +477 -0
  45. package/dist/e2e.js.map +7 -0
  46. package/dist/exec.d.ts +1 -1
  47. package/dist/exec.d.ts.map +1 -1
  48. package/dist/exec.js +60 -5
  49. package/dist/exec.js.map +3 -3
  50. package/dist/fetch.js +2 -2
  51. package/dist/fetch.js.map +2 -2
  52. package/dist/format.js +61 -14
  53. package/dist/format.js.map +3 -3
  54. package/dist/glob.js +2 -2
  55. package/dist/glob.js.map +1 -1
  56. package/dist/grep.d.ts.map +1 -1
  57. package/dist/grep.js +2 -2
  58. package/dist/grep.js.map +2 -2
  59. package/dist/index.d.ts +3 -2
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +2001 -873
  62. package/dist/index.js.map +3 -3
  63. package/dist/install.js +61 -14
  64. package/dist/install.js.map +3 -3
  65. package/dist/kanban.d.ts +21 -2
  66. package/dist/kanban.d.ts.map +1 -1
  67. package/dist/kanban.js +713 -572
  68. package/dist/kanban.js.map +3 -3
  69. package/dist/languages/detect.d.ts.map +1 -1
  70. package/dist/languages/index.js +61 -14
  71. package/dist/languages/index.js.map +3 -3
  72. package/dist/languages/types.d.ts +7 -0
  73. package/dist/languages/types.d.ts.map +1 -1
  74. package/dist/lint.js +61 -14
  75. package/dist/lint.js.map +3 -3
  76. package/dist/outdated.js +61 -14
  77. package/dist/outdated.js.map +3 -3
  78. package/dist/pack.js +1763 -861
  79. package/dist/pack.js.map +3 -3
  80. package/dist/plan.js +4 -0
  81. package/dist/plan.js.map +2 -2
  82. package/dist/process-registry.js +12 -5
  83. package/dist/process-registry.js.map +2 -2
  84. package/dist/read.d.ts.map +1 -1
  85. package/dist/read.js.map +2 -2
  86. package/dist/search.js +2 -2
  87. package/dist/search.js.map +2 -2
  88. package/dist/session-kanban.d.ts +9 -0
  89. package/dist/session-kanban.d.ts.map +1 -1
  90. package/dist/session-kanban.js +197 -3
  91. package/dist/session-kanban.js.map +2 -2
  92. package/dist/task.js +4 -0
  93. package/dist/task.js.map +2 -2
  94. package/dist/test.js +61 -14
  95. package/dist/test.js.map +3 -3
  96. package/dist/todo.js +4 -0
  97. package/dist/todo.js.map +2 -2
  98. package/dist/tree.js +2 -2
  99. package/dist/tree.js.map +1 -1
  100. package/dist/typecheck.js +61 -14
  101. package/dist/typecheck.js.map +3 -3
  102. package/package.json +13 -5
package/dist/install.js CHANGED
@@ -4,7 +4,12 @@ import { detectPackageEcosystem, recordPackageAction } from "@wrongstack/core";
4
4
 
5
5
  // src/_spawn-stream.ts
6
6
  import { spawn as spawn2 } from "node:child_process";
7
- import { buildChildEnv } from "@wrongstack/core";
7
+ import {
8
+ buildChildEnv,
9
+ emitProcessCompleted,
10
+ emitProcessOutput,
11
+ emitProcessStarted
12
+ } from "@wrongstack/core";
8
13
 
9
14
  // src/_output-spool.ts
10
15
  import { createWriteStream, mkdirSync } from "node:fs";
@@ -314,9 +319,14 @@ import { expectDefined } from "@wrongstack/core";
314
319
  var SENSITIVE_FLAG_PATTERNS = [
315
320
  // --flag=value or --flag "value" (value captured up to next space or comma)
316
321
  /--(?: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,
317
- // -f "value" style short flags
318
- /(?<!\w)-t(?:\s+|\s*=\s*)[^\s,]+/,
319
- /(?<!\w)-(?:p|password)(?:\s+|\s*=\s*)[^\s,]+/gi,
322
+ // -t short flag (token): attached (-tVALUE), separated (-t VALUE), or -t=VALUE.
323
+ // (?<![-\w]) anchors to a token start so we don't match the `-t` inside `--token`.
324
+ // NOTE: synced with @wrongstack/core observability/redact-command.ts.
325
+ /(?<![-\w])-t(?:[=\s]+)?[^\s,-]+/,
326
+ // -p|-password|-a (redis auth) short flags: attached + separated + =value.
327
+ // Same token-start anchor; over-redaction is an accepted tradeoff for a
328
+ // redaction function. Synced with core copy.
329
+ /(?<![-\w])-(?:password|p|a)(?:[=\s]+)?[^\s,-]+/gi,
320
330
  // env var–style secrets: TOKEN=x, API_KEY=y, etc.
321
331
  /(?:TOKEN|API_KEY|API_SECRET|AUTH_TOKEN|GITHUB_TOKEN|GH_TOKEN|BEARER|JWT|OAUTH|CREDENTIAL|SECRET|PRIVATE_KEY|PASSWORD|PASSWD)\s*[=:]\s*[^\s,]+/gi,
322
332
  // Generic high-entropy look: base64 strings >32 chars or hex strings >32 digits — but only
@@ -334,8 +344,10 @@ function redactCommand(cmd) {
334
344
  const flag = match.slice(0, match.indexOf(expectDefined(delim)) + 1);
335
345
  return `${flag}[REDACTED]`;
336
346
  }
337
- const flagEnd = match.match(/^--?[a-zA-Z][a-zA-Z0-9_-]*/)?.[0] ?? match;
338
- return `${flagEnd}=**redacted**`;
347
+ if (match.startsWith("--")) {
348
+ return match;
349
+ }
350
+ return `${match.slice(0, 2)}[REDACTED]`;
339
351
  });
340
352
  }
341
353
  return result;
@@ -772,6 +784,19 @@ async function* spawnStream(opts) {
772
784
  });
773
785
  const registry = getProcessRegistry();
774
786
  const pid = child.pid;
787
+ const processStartedAt = Date.now();
788
+ let stdoutBytes = 0;
789
+ let stderrBytes = 0;
790
+ let telemetryCompleted = false;
791
+ emitProcessStarted({
792
+ ...pid !== void 0 ? { pid } : {},
793
+ parentPid: process.pid,
794
+ command: redactCommand(`${opts.cmd} ${opts.args.join(" ")}`),
795
+ args: redactCommand(opts.args.join(" ")).split(" ").filter(Boolean),
796
+ cwd: opts.cwd,
797
+ background: false,
798
+ startedAt: new Date(processStartedAt).toISOString()
799
+ });
775
800
  if (typeof pid === "number") {
776
801
  registry.register({
777
802
  pid,
@@ -800,6 +825,8 @@ async function* spawnStream(opts) {
800
825
  };
801
826
  const onOut = (c) => {
802
827
  const s = c.toString();
828
+ stdoutBytes += c.byteLength;
829
+ emitProcessOutput({ pid, stream: "stdout", chunk: c });
803
830
  if (stdout.length < max) stdout += s;
804
831
  spool.write(s);
805
832
  queue.push({ kind: "out", data: s });
@@ -812,6 +839,8 @@ async function* spawnStream(opts) {
812
839
  };
813
840
  const onErr = (c) => {
814
841
  const s = c.toString();
842
+ stderrBytes += c.byteLength;
843
+ emitProcessOutput({ pid, stream: "stderr", chunk: c });
815
844
  if (stderr.length < max) stderr += s;
816
845
  spool.write(s);
817
846
  queue.push({ kind: "err", data: s });
@@ -829,9 +858,25 @@ async function* spawnStream(opts) {
829
858
  queue.push({ kind: "error", data: e.message });
830
859
  wake();
831
860
  });
832
- child.on("close", (code) => {
861
+ const completeTelemetry = (code, signal, timedOut = false) => {
862
+ if (telemetryCompleted) return;
863
+ telemetryCompleted = true;
864
+ emitProcessCompleted({
865
+ ...pid !== void 0 ? { pid } : {},
866
+ exitCode: code,
867
+ ...signal ? { signal } : {},
868
+ durationMs: Date.now() - processStartedAt,
869
+ stdoutBytes,
870
+ stderrBytes,
871
+ timedOut,
872
+ endedAt: (/* @__PURE__ */ new Date()).toISOString()
873
+ });
874
+ };
875
+ child.on("close", (code, signal) => {
833
876
  if (typeof pid === "number") registry.unregister(pid);
834
- queue.push({ kind: "close", data: "", code: code ?? 0 });
877
+ const exitCode2 = code ?? (signal ? 1 : 0);
878
+ completeTelemetry(exitCode2, signal ?? void 0);
879
+ queue.push({ kind: "close", data: "", code: exitCode2, ...signal ? { signal } : {} });
835
880
  wake();
836
881
  });
837
882
  const onAbort = () => {
@@ -844,6 +889,7 @@ async function* spawnStream(opts) {
844
889
  }
845
890
  }
846
891
  queue.push({ kind: "close", data: "", code: 124 });
892
+ completeTelemetry(124, "SIGKILL", true);
847
893
  wake();
848
894
  };
849
895
  if (isWin) {
@@ -2386,13 +2432,14 @@ async function detectLanguageWorkspaces(options) {
2386
2432
  const target = options.target ? await canonicalInside(resolveFrom(cwd, options.target), projectRoot, "target") : void 0;
2387
2433
  const profiles = (options.profiles ?? languageProfileRegistry.list()).filter((profile) => !options.language || profile.id === options.language).slice().sort((a, b) => a.id.localeCompare(b.id));
2388
2434
  const limits = normalizeLimits(options.limits);
2435
+ const extraIgnores = new Set(options.ignoredDirectories ?? []);
2389
2436
  const state = {
2390
2437
  entries: 0,
2391
2438
  truncated: false,
2392
2439
  sourcePaths: /* @__PURE__ */ new Map(),
2393
2440
  candidates: /* @__PURE__ */ new Map()
2394
2441
  };
2395
- await scanDirectory(projectRoot, 0, profiles, limits, state, options.signal);
2442
+ await scanDirectory(projectRoot, 0, profiles, limits, state, extraIgnores, options.signal);
2396
2443
  addSourceFallbacks(projectRoot, profiles, state);
2397
2444
  if (target) addTargetEvidence(target, projectRoot, profiles, state);
2398
2445
  const workspaces = await Promise.all(
@@ -2406,7 +2453,7 @@ async function detectLanguageWorkspaces(options) {
2406
2453
  workspaces
2407
2454
  };
2408
2455
  }
2409
- async function scanDirectory(directory, depth, profiles, limits, state, signal) {
2456
+ async function scanDirectory(directory, depth, profiles, limits, state, extraIgnores, signal) {
2410
2457
  signal?.throwIfAborted();
2411
2458
  if (depth > limits.maxDepth || state.entries >= limits.maxEntries) {
2412
2459
  state.truncated = true;
@@ -2429,12 +2476,12 @@ async function scanDirectory(directory, depth, profiles, limits, state, signal)
2429
2476
  const fullPath = path4.join(directory, entry.name);
2430
2477
  if (entry.isSymbolicLink()) continue;
2431
2478
  if (entry.isDirectory()) {
2432
- if (shouldIgnoreDirectory(entry.name, profiles)) continue;
2479
+ if (shouldIgnoreDirectory(entry.name, profiles, extraIgnores)) continue;
2433
2480
  if (depth >= limits.maxDepth) {
2434
2481
  state.truncated = true;
2435
2482
  continue;
2436
2483
  }
2437
- await scanDirectory(fullPath, depth + 1, profiles, limits, state, signal);
2484
+ await scanDirectory(fullPath, depth + 1, profiles, limits, state, extraIgnores, signal);
2438
2485
  continue;
2439
2486
  }
2440
2487
  if (!entry.isFile()) continue;
@@ -2563,8 +2610,8 @@ function getCandidate(state, profile, root) {
2563
2610
  }
2564
2611
  return candidate;
2565
2612
  }
2566
- function shouldIgnoreDirectory(name, profiles) {
2567
- if (GLOBAL_IGNORES.has(name) || name.startsWith(".")) return true;
2613
+ function shouldIgnoreDirectory(name, profiles, extraIgnores) {
2614
+ if (GLOBAL_IGNORES.has(name) || extraIgnores.has(name) || name.startsWith(".")) return true;
2568
2615
  return profiles.some((profile) => profile.ignoredDirectories.includes(name));
2569
2616
  }
2570
2617
  function normalizeLimits(input) {