@wrongstack/tools 0.305.1 → 0.306.2
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/_shell-pick.d.ts +4 -5
- package/dist/_util.d.ts +22 -5
- package/dist/audit.d.ts +0 -1
- package/dist/audit.js +135 -46
- package/dist/bash.js +61 -37
- package/dist/browser/index.js +29 -9
- package/dist/browser/types.d.ts +7 -1
- package/dist/builtin.js +1294 -726
- package/dist/codebase-index/codebase-search-tool.d.ts +5 -0
- package/dist/codebase-index/index.js +223 -152
- package/dist/codebase-index/project-server.js +10 -11
- package/dist/diff.d.ts +5 -0
- package/dist/diff.js +78 -12
- package/dist/document.js +18 -6
- package/dist/edit.js +69 -16
- package/dist/exec.js +44 -22
- package/dist/fetch.js +13 -1
- package/dist/format.d.ts +4 -2
- package/dist/format.js +81 -31
- package/dist/glob.js +12 -4
- package/dist/grep.d.ts +2 -0
- package/dist/grep.js +15 -4
- package/dist/index.js +1359 -762
- package/dist/install.js +96 -37
- package/dist/kanban-tool-types.d.ts +6 -1
- package/dist/kanban.js +60 -0
- package/dist/languages/index.js +28 -13
- package/dist/lint.js +28 -13
- package/dist/logs.d.ts +0 -1
- package/dist/logs.js +44 -13
- package/dist/memory.d.ts +8 -0
- package/dist/memory.js +23 -3
- package/dist/mode.d.ts +1 -1
- package/dist/mode.js +3 -0
- package/dist/next-steps.d.ts +2 -3
- package/dist/next-steps.js +3 -3
- package/dist/outdated.d.ts +0 -3
- package/dist/outdated.js +89 -48
- package/dist/pack.js +1294 -726
- package/dist/plan.js +91 -3
- package/dist/process-registry.d.ts +8 -2
- package/dist/process-registry.js +28 -13
- package/dist/ps-slash.js +22 -12
- package/dist/read.js +10 -3
- package/dist/replace.d.ts +4 -0
- package/dist/replace.js +104 -7
- package/dist/search.d.ts +6 -0
- package/dist/search.js +47 -26
- package/dist/session-kanban.js +3 -1
- package/dist/skill.d.ts +6 -0
- package/dist/skill.js +9 -10
- package/dist/task.js +81 -2
- package/dist/test.js +28 -13
- package/dist/todo.js +79 -2
- package/dist/tool-icons.js +4 -2
- package/dist/tool-summary.d.ts +1 -1
- package/dist/tool-summary.js +76 -1
- package/dist/tool-tier.js +1294 -726
- package/dist/tree.js +9 -10
- package/dist/typecheck.d.ts +0 -2
- package/dist/typecheck.js +98 -31
- package/dist/write.js +58 -10
- package/package.json +4 -4
package/dist/format.js
CHANGED
|
@@ -364,8 +364,11 @@ var SENSITIVE_FLAG_PATTERNS = [
|
|
|
364
364
|
/--(?: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,
|
|
365
365
|
// -t short flag (token): attached (-tVALUE), separated (-t VALUE), or -t=VALUE.
|
|
366
366
|
// (?<![-\w]) anchors to a token start so we don't match the `-t` inside `--token`.
|
|
367
|
+
// The value must be token-like (>= 8 chars) so ordinary combined flags such
|
|
368
|
+
// as `tar -tf` / `ssh -tt` are not eaten. Global flag: EVERY occurrence is
|
|
369
|
+
// redacted, not just the first.
|
|
367
370
|
// NOTE: synced with @wrongstack/core observability/redact-command.ts.
|
|
368
|
-
/(?<![-\w])-t(?:[=\s]+)?[^\s,-]
|
|
371
|
+
/(?<![-\w])-t(?:[=\s]+)?[^\s,-]{8,}/g,
|
|
369
372
|
// -p|-password|-a (redis auth) short flags: attached + separated + =value.
|
|
370
373
|
// Same token-start anchor; over-redaction is an accepted tradeoff for a
|
|
371
374
|
// redaction function. Synced with core copy.
|
|
@@ -373,8 +376,9 @@ var SENSITIVE_FLAG_PATTERNS = [
|
|
|
373
376
|
// env var–style secrets: TOKEN=x, API_KEY=y, etc.
|
|
374
377
|
/(?:TOKEN|API_KEY|API_SECRET|AUTH_TOKEN|GITHUB_TOKEN|GH_TOKEN|BEARER|JWT|OAUTH|CREDENTIAL|SECRET|PRIVATE_KEY|PASSWORD|PASSWD)\s*[=:]\s*[^\s,]+/gi,
|
|
375
378
|
// Generic high-entropy look: base64 strings >32 chars or hex strings >32 digits — but only
|
|
376
|
-
// when preceded by a flag name (e.g. --github-token=EyJ...).
|
|
377
|
-
|
|
379
|
+
// when preceded by a flag name (e.g. --github-token=EyJ...). Global flag so
|
|
380
|
+
// every such flag in the command line is redacted, not just the first.
|
|
381
|
+
/--\w*(?:token|key|secret|password|passwd|auth|credential)\w*[=\s,][A-Za-z0-9+/=]{32,}/g
|
|
378
382
|
];
|
|
379
383
|
function redactCommand(cmd) {
|
|
380
384
|
let result = cmd;
|
|
@@ -463,11 +467,15 @@ var ProcessRegistryImpl = class {
|
|
|
463
467
|
return Number.isInteger(pid) && pid > 1 && pid !== process.pid && pid !== process.ppid;
|
|
464
468
|
}
|
|
465
469
|
_canSignalProcessGroup(p) {
|
|
466
|
-
return os.platform() !== "win32" && p.processGroupLeader === true && this._isSafeSignalPid(p.pid) && typeof p.child.pid === "number" && p.child.pid === p.pid;
|
|
470
|
+
return os.platform() !== "win32" && p.processGroupLeader === true && this._isSafeSignalPid(p.pid) && p.child !== null && typeof p.child.pid === "number" && p.child.pid === p.pid;
|
|
467
471
|
}
|
|
468
472
|
_killChildDirect(p, signal) {
|
|
469
473
|
try {
|
|
470
|
-
p.child
|
|
474
|
+
if (p.child) {
|
|
475
|
+
p.child.kill(signal);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (this._isSafeSignalPid(p.pid)) process.kill(p.pid, signal);
|
|
471
479
|
} catch {
|
|
472
480
|
}
|
|
473
481
|
}
|
|
@@ -665,15 +673,15 @@ var ProcessRegistryImpl = class {
|
|
|
665
673
|
this._pruneStale(pid);
|
|
666
674
|
const p = this.processes.get(pid);
|
|
667
675
|
if (!p) return false;
|
|
668
|
-
if (p.killed) return true;
|
|
676
|
+
if (p.killed && opts.force !== true) return true;
|
|
669
677
|
if (p.protected && opts.includeProtected !== true) return false;
|
|
670
678
|
if (opts.preserveBackground && p.background) return false;
|
|
671
679
|
const { force = false, graceMs = DEFAULT_GRACE_MS } = opts;
|
|
672
680
|
const isWin2 = os.platform() === "win32";
|
|
673
681
|
if (isWin2) {
|
|
674
|
-
const liveRealChild = p.child.exitCode === null && typeof p.child.pid === "number";
|
|
682
|
+
const liveRealChild = p.child === null || p.child.exitCode === null && typeof p.child.pid === "number";
|
|
675
683
|
const directFallback = () => {
|
|
676
|
-
if (p.child.exitCode === null) {
|
|
684
|
+
if (p.child && p.child.exitCode === null) {
|
|
677
685
|
try {
|
|
678
686
|
p.child.kill("SIGKILL");
|
|
679
687
|
} catch {
|
|
@@ -685,10 +693,7 @@ var ProcessRegistryImpl = class {
|
|
|
685
693
|
onSettled: directFallback
|
|
686
694
|
})) {
|
|
687
695
|
} else {
|
|
688
|
-
|
|
689
|
-
p.child.kill(force ? "SIGKILL" : "SIGTERM");
|
|
690
|
-
} catch {
|
|
691
|
-
}
|
|
696
|
+
this._killChildDirect(p, force ? "SIGKILL" : "SIGTERM");
|
|
692
697
|
}
|
|
693
698
|
p.killed = true;
|
|
694
699
|
return true;
|
|
@@ -699,7 +704,7 @@ var ProcessRegistryImpl = class {
|
|
|
699
704
|
} else {
|
|
700
705
|
this._killPosix(p, "SIGTERM");
|
|
701
706
|
const timer = setTimeout(() => {
|
|
702
|
-
if (this.processes.has(pid) && !p.child
|
|
707
|
+
if (this.processes.has(pid) && !p.child?.killed) {
|
|
703
708
|
this._killPosix(p, "SIGKILL");
|
|
704
709
|
}
|
|
705
710
|
}, graceMs);
|
|
@@ -754,6 +759,16 @@ var ProcessRegistryImpl = class {
|
|
|
754
759
|
* before reusing a PID, but we want to clean up before that becomes a risk.
|
|
755
760
|
*/
|
|
756
761
|
_isStaleEntry(entry) {
|
|
762
|
+
if (entry.child === null) {
|
|
763
|
+
if (Date.now() - entry.startedAt <= 6e4) return false;
|
|
764
|
+
if (os.platform() === "win32") return false;
|
|
765
|
+
try {
|
|
766
|
+
process.kill(entry.pid, 0);
|
|
767
|
+
return false;
|
|
768
|
+
} catch (err) {
|
|
769
|
+
return err.code !== "EPERM";
|
|
770
|
+
}
|
|
771
|
+
}
|
|
757
772
|
return entry.child.exitCode !== null && Date.now() - entry.startedAt > 6e4;
|
|
758
773
|
}
|
|
759
774
|
/**
|
|
@@ -3590,8 +3605,9 @@ var formatTool = {
|
|
|
3590
3605
|
type: "final",
|
|
3591
3606
|
output: {
|
|
3592
3607
|
fixer: bridge.language,
|
|
3593
|
-
|
|
3594
|
-
|
|
3608
|
+
// Language-bridge runs don't report per-file counts.
|
|
3609
|
+
files_checked: void 0,
|
|
3610
|
+
files_changed: void 0,
|
|
3595
3611
|
output: normalizeCommandOutput(run.output || run.error || ""),
|
|
3596
3612
|
truncated: run.truncated
|
|
3597
3613
|
}
|
|
@@ -3618,11 +3634,14 @@ var formatTool = {
|
|
|
3618
3634
|
text: `Running ${detected}\u2026`,
|
|
3619
3635
|
data: { fixer: detected, check: !!input.check }
|
|
3620
3636
|
};
|
|
3621
|
-
const
|
|
3622
|
-
|
|
3623
|
-
if (
|
|
3624
|
-
|
|
3625
|
-
args.push(
|
|
3637
|
+
const fileList = input.files ? (Array.isArray(input.files) ? input.files : input.files.split(",")).map((f) => f.trim()) : [];
|
|
3638
|
+
let args;
|
|
3639
|
+
if (detected === "prettier") {
|
|
3640
|
+
args = [input.check ? "--check" : "--write"];
|
|
3641
|
+
args.push(...fileList.length > 0 ? fileList : ["."]);
|
|
3642
|
+
} else {
|
|
3643
|
+
args = ["format", input.check ? "--check" : "--write"];
|
|
3644
|
+
if (fileList.length > 0) args.push("--", ...fileList);
|
|
3626
3645
|
}
|
|
3627
3646
|
const result = yield* spawnStream({
|
|
3628
3647
|
cmd: detected,
|
|
@@ -3631,32 +3650,63 @@ var formatTool = {
|
|
|
3631
3650
|
signal: opts.signal,
|
|
3632
3651
|
maxBytes: 1e5
|
|
3633
3652
|
});
|
|
3634
|
-
const
|
|
3653
|
+
const combinedOut = `${result.stdout}
|
|
3654
|
+
${result.stderr}`;
|
|
3655
|
+
const counts = parseFormatterCounts(detected, combinedOut);
|
|
3635
3656
|
yield {
|
|
3636
3657
|
type: "final",
|
|
3637
3658
|
output: {
|
|
3638
3659
|
fixer: detected,
|
|
3639
|
-
files_checked:
|
|
3640
|
-
files_changed: changed,
|
|
3660
|
+
files_checked: counts.checked,
|
|
3661
|
+
files_changed: counts.changed,
|
|
3641
3662
|
output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ""),
|
|
3642
3663
|
truncated: result.truncated
|
|
3643
3664
|
}
|
|
3644
3665
|
};
|
|
3645
3666
|
}
|
|
3646
3667
|
};
|
|
3668
|
+
function parseFormatterCounts(fixer, output) {
|
|
3669
|
+
if (fixer !== "biome") return { checked: void 0, changed: void 0 };
|
|
3670
|
+
const checkedMatch = /\b(?:Checked|Formatted)\s+(\d+)\s+files?\b/i.exec(output);
|
|
3671
|
+
const changedMatch = /\bFixed\s+(\d+)\s+files?\b/i.exec(output);
|
|
3672
|
+
return {
|
|
3673
|
+
checked: checkedMatch?.[1] !== void 0 ? Number(checkedMatch[1]) : void 0,
|
|
3674
|
+
changed: changedMatch?.[1] !== void 0 ? Number(changedMatch[1]) : void 0
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
3647
3677
|
async function detectFixer(cwd) {
|
|
3648
|
-
const
|
|
3649
|
-
|
|
3650
|
-
await stat5(`${cwd}/biome.json`);
|
|
3651
|
-
return "biome";
|
|
3652
|
-
} catch {
|
|
3678
|
+
const fs6 = await import("node:fs/promises");
|
|
3679
|
+
const exists = async (file) => {
|
|
3653
3680
|
try {
|
|
3654
|
-
await
|
|
3655
|
-
return
|
|
3681
|
+
await fs6.stat(`${cwd}/${file}`);
|
|
3682
|
+
return true;
|
|
3656
3683
|
} catch {
|
|
3657
|
-
return
|
|
3684
|
+
return false;
|
|
3658
3685
|
}
|
|
3686
|
+
};
|
|
3687
|
+
if (await exists("biome.json") || await exists("biome.jsonc")) return "biome";
|
|
3688
|
+
const PRETTIER_CONFIGS = [
|
|
3689
|
+
".prettierrc",
|
|
3690
|
+
".prettierrc.json",
|
|
3691
|
+
".prettierrc.yml",
|
|
3692
|
+
".prettierrc.yaml",
|
|
3693
|
+
".prettierrc.js",
|
|
3694
|
+
".prettierrc.cjs",
|
|
3695
|
+
".prettierrc.mjs",
|
|
3696
|
+
"prettier.config.js",
|
|
3697
|
+
"prettier.config.cjs",
|
|
3698
|
+
"prettier.config.mjs"
|
|
3699
|
+
];
|
|
3700
|
+
for (const cfg of PRETTIER_CONFIGS) {
|
|
3701
|
+
if (await exists(cfg)) return "prettier";
|
|
3702
|
+
}
|
|
3703
|
+
try {
|
|
3704
|
+
const raw = await fs6.readFile(`${cwd}/package.json`, "utf8");
|
|
3705
|
+
const pkg = JSON.parse(raw);
|
|
3706
|
+
if (pkg["prettier"] !== void 0) return "prettier";
|
|
3707
|
+
} catch {
|
|
3659
3708
|
}
|
|
3709
|
+
return "biome";
|
|
3660
3710
|
}
|
|
3661
3711
|
export {
|
|
3662
3712
|
formatTool
|
package/dist/glob.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import * as fs2 from "node:fs/promises";
|
|
3
3
|
import * as path3 from "node:path";
|
|
4
4
|
import { compileGlob as compileGlob2, DEFAULT_WALK_IGNORE_DIRS } from "@wrongstack/core/utils";
|
|
5
|
+
import { ToolValidationError } from "@wrongstack/core/types";
|
|
5
6
|
|
|
6
7
|
// src/_concurrency.ts
|
|
7
8
|
async function mapWithConcurrency(items, limit, fn) {
|
|
@@ -143,7 +144,7 @@ var WALK_CONCURRENCY = 16;
|
|
|
143
144
|
var globTool = {
|
|
144
145
|
name: "glob",
|
|
145
146
|
category: "Filesystem",
|
|
146
|
-
description: "Find files by path pattern. Use index-backed `codebase-search` first for code symbols or concepts when it is live.",
|
|
147
|
+
description: "Find files by path pattern. Results are sorted by modification time, newest first, so when the list is truncated at `limit` it is the oldest files that are dropped (recency-biased). Use index-backed `codebase-search` first for code symbols or concepts when it is live.",
|
|
147
148
|
usageHint: "PATH DISCOVERY AND SEARCH SCOPING:\n\n- When `codebase-search` is live, use it first for code concepts; use `glob` for filenames, path patterns, and non-indexed files.\n- Combine with `path` and `limit`.\n- Default ignores common build/dependency directories.\nMuch more efficient than shell `find` for most use cases inside the agent.",
|
|
148
149
|
selection: {
|
|
149
150
|
doNotUseWhen: "you need to search inside file contents.",
|
|
@@ -154,7 +155,7 @@ var globTool = {
|
|
|
154
155
|
capabilities: ["fs.read"],
|
|
155
156
|
icon: "folder",
|
|
156
157
|
maxOutputBytes: 65536,
|
|
157
|
-
timeoutMs:
|
|
158
|
+
timeoutMs: 15e3,
|
|
158
159
|
inputSchema: {
|
|
159
160
|
type: "object",
|
|
160
161
|
properties: {
|
|
@@ -168,13 +169,20 @@ var globTool = {
|
|
|
168
169
|
},
|
|
169
170
|
limit: {
|
|
170
171
|
type: "integer",
|
|
171
|
-
|
|
172
|
+
minimum: 1,
|
|
173
|
+
maximum: 5e3,
|
|
174
|
+
description: "Maximum number of results to return (default 1000, max 5000). Results are sorted by mtime descending, so truncation keeps the most recently modified files."
|
|
172
175
|
}
|
|
173
176
|
},
|
|
174
177
|
required: ["pattern"]
|
|
175
178
|
},
|
|
176
179
|
async execute(input, ctx, opts) {
|
|
177
|
-
if (!input?.pattern)
|
|
180
|
+
if (!input?.pattern) {
|
|
181
|
+
throw new ToolValidationError({
|
|
182
|
+
message: "glob: pattern is required",
|
|
183
|
+
field: "pattern"
|
|
184
|
+
});
|
|
185
|
+
}
|
|
178
186
|
const signal = opts?.signal;
|
|
179
187
|
const base = input.path ? await safeResolveReal(input.path, ctx) : ctx.cwd;
|
|
180
188
|
const limit = Math.max(1, Math.min(input.limit ?? 1e3, 5e3));
|
package/dist/grep.d.ts
CHANGED
|
@@ -15,5 +15,7 @@ interface GrepOutput {
|
|
|
15
15
|
used: 'rg' | 'native';
|
|
16
16
|
}
|
|
17
17
|
export declare const grepTool: Tool<GrepInput, GrepOutput>;
|
|
18
|
+
/** Test-only: forget the cached rg availability so mocks can vary per test. */
|
|
19
|
+
export declare function __resetRgDetectionForTests(): void;
|
|
18
20
|
export {};
|
|
19
21
|
//# sourceMappingURL=grep.d.ts.map
|
package/dist/grep.js
CHANGED
|
@@ -358,7 +358,7 @@ var grepTool = {
|
|
|
358
358
|
field: "pattern"
|
|
359
359
|
});
|
|
360
360
|
}
|
|
361
|
-
const rgAvailable = await detectRg(
|
|
361
|
+
const rgAvailable = await detectRg();
|
|
362
362
|
if (rgAvailable) {
|
|
363
363
|
try {
|
|
364
364
|
yield* runRgStream(input, base, mode, limit, opts.signal);
|
|
@@ -371,16 +371,26 @@ var grepTool = {
|
|
|
371
371
|
yield { type: "final", output: out };
|
|
372
372
|
}
|
|
373
373
|
};
|
|
374
|
-
|
|
375
|
-
|
|
374
|
+
var rgAvailabilityCache;
|
|
375
|
+
function __resetRgDetectionForTests() {
|
|
376
|
+
rgAvailabilityCache = void 0;
|
|
377
|
+
}
|
|
378
|
+
function detectRg() {
|
|
379
|
+
rgAvailabilityCache ??= new Promise((resolve2) => {
|
|
376
380
|
try {
|
|
377
|
-
const p = spawn("rg", ["--version"], {
|
|
381
|
+
const p = spawn("rg", ["--version"], {
|
|
382
|
+
env: buildChildEnv(),
|
|
383
|
+
stdio: "ignore",
|
|
384
|
+
signal: AbortSignal.timeout(1e4),
|
|
385
|
+
windowsHide: true
|
|
386
|
+
});
|
|
378
387
|
p.on("error", () => resolve2(false));
|
|
379
388
|
p.on("close", (code) => resolve2(code === 0));
|
|
380
389
|
} catch {
|
|
381
390
|
resolve2(false);
|
|
382
391
|
}
|
|
383
392
|
});
|
|
393
|
+
return rgAvailabilityCache;
|
|
384
394
|
}
|
|
385
395
|
async function* runRgStream(input, base, mode, limit, signal) {
|
|
386
396
|
const args = ["--no-heading"];
|
|
@@ -701,6 +711,7 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
701
711
|
};
|
|
702
712
|
}
|
|
703
713
|
export {
|
|
714
|
+
__resetRgDetectionForTests,
|
|
704
715
|
grepTool
|
|
705
716
|
};
|
|
706
717
|
//# sourceMappingURL=grep.js.map
|