@wrongstack/tools 0.299.0 → 0.301.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.
- package/dist/audit.js +6 -2
- package/dist/bash.js +6 -2
- package/dist/batch-tool-use.js +3 -1
- package/dist/browser/index.js +1 -1
- package/dist/builtin.d.ts +3 -2
- package/dist/builtin.js +1781 -376
- package/dist/codebase-index/bm25.d.ts +7 -1
- package/dist/codebase-index/import-extractor.d.ts +39 -0
- package/dist/codebase-index/index.js +1418 -267
- package/dist/codebase-index/languages.d.ts +24 -0
- package/dist/codebase-index/module-resolver.d.ts +78 -0
- package/dist/codebase-index/module-roots.d.ts +81 -0
- package/dist/codebase-index/parser-output.d.ts +29 -0
- package/dist/codebase-index/project-server.js +1402 -249
- package/dist/codebase-index/rs-parser.d.ts +22 -0
- package/dist/codebase-index/schema.d.ts +24 -1
- package/dist/codebase-index/worker.js +1401 -250
- package/dist/codebase-index/writer-graph-helpers.d.ts +17 -5
- package/dist/codebase-index/writer-ref-mapper.d.ts +3 -0
- package/dist/codebase-index/writer-schema.d.ts +15 -3
- package/dist/codebase-index/writer.d.ts +76 -3
- package/dist/exec.js +35 -2
- package/dist/format.js +6 -2
- package/dist/git.js +2 -5
- package/dist/glob.js +2 -2
- package/dist/grep.js +118 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1925 -415
- package/dist/install.js +6 -2
- package/dist/json.js +132 -2
- package/dist/languages/index.js +6 -2
- package/dist/lint.js +6 -2
- package/dist/logs.js +81 -0
- package/dist/next-steps-tool.d.ts +26 -0
- package/dist/outdated.js +6 -2
- package/dist/pack.js +1781 -376
- package/dist/patch.js +206 -45
- package/dist/process-registry.d.ts +6 -0
- package/dist/process-registry.js +6 -2
- package/dist/ps-slash.js +6 -2
- package/dist/read.js +1410 -257
- package/dist/replace.js +81 -0
- package/dist/skill.js +51 -2
- package/dist/test.js +6 -2
- package/dist/tool-help.js +2 -2
- package/dist/tool-search.js +1 -1
- package/dist/tool-tier.d.ts +1 -1
- package/dist/tool-tier.js +1786 -397
- package/dist/tool-use.js +1 -1
- package/dist/tree.js +13 -3
- package/dist/typecheck.js +6 -2
- package/package.json +3 -3
- package/dist/codebase-index/refs-extractor.d.ts +0 -11
package/dist/install.js
CHANGED
|
@@ -673,7 +673,7 @@ var ProcessRegistryImpl = class {
|
|
|
673
673
|
const p = this.processes.get(pid);
|
|
674
674
|
if (!p) return false;
|
|
675
675
|
if (p.killed) return true;
|
|
676
|
-
if (p.protected) return false;
|
|
676
|
+
if (p.protected && opts.includeProtected !== true) return false;
|
|
677
677
|
if (opts.preserveBackground && p.background) return false;
|
|
678
678
|
const { force = false, graceMs = DEFAULT_GRACE_MS } = opts;
|
|
679
679
|
const isWin2 = os.platform() === "win32";
|
|
@@ -724,9 +724,13 @@ var ProcessRegistryImpl = class {
|
|
|
724
724
|
killAll(opts = {}) {
|
|
725
725
|
const pids = Array.from(this.processes.keys());
|
|
726
726
|
const killed = [];
|
|
727
|
+
const includeProtected = opts.includeProtected === true;
|
|
727
728
|
for (const pid of pids) {
|
|
728
729
|
const p = this.processes.get(pid);
|
|
729
|
-
if (
|
|
730
|
+
if (!p) continue;
|
|
731
|
+
if (p.protected && !includeProtected) continue;
|
|
732
|
+
if (opts.preserveBackground && p.background) continue;
|
|
733
|
+
if (this.kill(pid, opts)) killed.push(pid);
|
|
730
734
|
}
|
|
731
735
|
return killed;
|
|
732
736
|
}
|
package/dist/json.js
CHANGED
|
@@ -2,6 +2,132 @@
|
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import { deepMerge as deepMergeCore } from "@wrongstack/core/utils";
|
|
4
4
|
|
|
5
|
+
// src/_regex.ts
|
|
6
|
+
var MAX_PATTERN_LEN = 256;
|
|
7
|
+
var DANGEROUS_PATTERNS = [
|
|
8
|
+
// (a+)+, (.*)+, etc — nested quantifier on a group with internal quantifier
|
|
9
|
+
/(\([^)]*[+*][^)]*\))[+*]/,
|
|
10
|
+
/(\(\?:[^)]*[+*][^)]*\))[+*]/,
|
|
11
|
+
// Adjacent quantifiers: a++ a*+
|
|
12
|
+
/[+*]{2,}/,
|
|
13
|
+
// Quantifier on alternation with length 2+
|
|
14
|
+
/\([^|)]+\|[^)]+\)[+*][+*]/,
|
|
15
|
+
// Greedy quantifier inside lookahead/lookbehind — (?!.*a+)
|
|
16
|
+
/[([][^)\]]*[+*][^)\]]*[)\]][^)]*\?\??/
|
|
17
|
+
];
|
|
18
|
+
function hasAmbiguousQuantifiedAlternation(pattern) {
|
|
19
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
20
|
+
if (pattern[i] !== "(") continue;
|
|
21
|
+
if (i > 0 && pattern[i - 1] === "\\") continue;
|
|
22
|
+
let depth = 0;
|
|
23
|
+
let inClass = false;
|
|
24
|
+
let j = i;
|
|
25
|
+
for (; j < pattern.length; j++) {
|
|
26
|
+
const ch = pattern[j];
|
|
27
|
+
if (ch === "\\") {
|
|
28
|
+
j++;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (inClass) {
|
|
32
|
+
if (ch === "]") inClass = false;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (ch === "[") {
|
|
36
|
+
inClass = true;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (ch === "(") depth++;
|
|
40
|
+
else if (ch === ")") {
|
|
41
|
+
depth--;
|
|
42
|
+
if (depth === 0) break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (j >= pattern.length) return false;
|
|
46
|
+
const next = pattern[j + 1];
|
|
47
|
+
if (next !== "+" && next !== "*" && next !== "{") continue;
|
|
48
|
+
let inner = pattern.slice(i + 1, j);
|
|
49
|
+
inner = inner.replace(/^\?(?::|<?[=!])/u, "");
|
|
50
|
+
const branches = [];
|
|
51
|
+
let current = "";
|
|
52
|
+
let d = 0;
|
|
53
|
+
let cls = false;
|
|
54
|
+
for (let k = 0; k < inner.length; k++) {
|
|
55
|
+
const ch = inner[k];
|
|
56
|
+
if (ch === "\\") {
|
|
57
|
+
current += ch + (inner[k + 1] ?? "");
|
|
58
|
+
k++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (cls) {
|
|
62
|
+
if (ch === "]") cls = false;
|
|
63
|
+
current += ch;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (ch === "[") {
|
|
67
|
+
cls = true;
|
|
68
|
+
current += ch;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (ch === "(") d++;
|
|
72
|
+
if (ch === ")") d--;
|
|
73
|
+
if (ch === "|" && d === 0) {
|
|
74
|
+
branches.push(current);
|
|
75
|
+
current = "";
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
current += ch;
|
|
79
|
+
}
|
|
80
|
+
branches.push(current);
|
|
81
|
+
if (branches.length < 2) continue;
|
|
82
|
+
for (let a = 0; a < branches.length; a++) {
|
|
83
|
+
for (let b = a + 1; b < branches.length; b++) {
|
|
84
|
+
const x = branches[a];
|
|
85
|
+
const y = branches[b];
|
|
86
|
+
if (x === "" || y === "") return true;
|
|
87
|
+
if (x === y || x.startsWith(y) || y.startsWith(x)) return true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
function compileUserRegex(pattern, flags) {
|
|
94
|
+
if (typeof pattern !== "string") {
|
|
95
|
+
return { ok: false, reason: "pattern must be a string" };
|
|
96
|
+
}
|
|
97
|
+
if (pattern.length === 0) {
|
|
98
|
+
return { ok: false, reason: "pattern is empty" };
|
|
99
|
+
}
|
|
100
|
+
if (pattern.length > MAX_PATTERN_LEN) {
|
|
101
|
+
return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };
|
|
102
|
+
}
|
|
103
|
+
for (const rx of DANGEROUS_PATTERNS) {
|
|
104
|
+
if (rx.test(pattern)) {
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
reason: "pattern looks vulnerable to catastrophic backtracking \u2014 rewrite without nested quantifiers"
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (hasAmbiguousQuantifiedAlternation(pattern)) {
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
reason: "pattern quantifies an alternation with overlapping branches \u2014 rewrite so no two branches can match the same text"
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
return { ok: true, regex: new RegExp(pattern, flags) };
|
|
119
|
+
} catch (err) {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
reason: err instanceof Error ? err.message : "invalid regex"
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
var MAX_SUBJECT_LEN = 64 * 1024;
|
|
127
|
+
function capSubject(line) {
|
|
128
|
+
return line.length > MAX_SUBJECT_LEN ? line.slice(0, MAX_SUBJECT_LEN) : line;
|
|
129
|
+
}
|
|
130
|
+
|
|
5
131
|
// src/_util.ts
|
|
6
132
|
import * as fsp from "node:fs/promises";
|
|
7
133
|
import * as path from "node:path";
|
|
@@ -500,8 +626,12 @@ function validateJsonSchema(data, schema) {
|
|
|
500
626
|
}
|
|
501
627
|
}
|
|
502
628
|
if (typeof value === "string" && s["pattern"]) {
|
|
503
|
-
const
|
|
504
|
-
if (!
|
|
629
|
+
const compiled = compileUserRegex(s["pattern"], "");
|
|
630
|
+
if (!compiled.ok) {
|
|
631
|
+
errors.push(`${path2}: invalid schema pattern \u2014 ${compiled.reason}`);
|
|
632
|
+
} else if (!compiled.regex.test(capSubject(value))) {
|
|
633
|
+
errors.push(`${path2}: does not match pattern ${s["pattern"]}`);
|
|
634
|
+
}
|
|
505
635
|
}
|
|
506
636
|
if (typeof value === "string" && s["minLength"] !== void 0 && value.length < s["minLength"]) {
|
|
507
637
|
errors.push(`${path2}: string too short (min ${s["minLength"]})`);
|
package/dist/languages/index.js
CHANGED
|
@@ -2794,7 +2794,7 @@ var ProcessRegistryImpl = class {
|
|
|
2794
2794
|
const p = this.processes.get(pid);
|
|
2795
2795
|
if (!p) return false;
|
|
2796
2796
|
if (p.killed) return true;
|
|
2797
|
-
if (p.protected) return false;
|
|
2797
|
+
if (p.protected && opts.includeProtected !== true) return false;
|
|
2798
2798
|
if (opts.preserveBackground && p.background) return false;
|
|
2799
2799
|
const { force = false, graceMs = DEFAULT_GRACE_MS } = opts;
|
|
2800
2800
|
const isWin2 = os.platform() === "win32";
|
|
@@ -2845,9 +2845,13 @@ var ProcessRegistryImpl = class {
|
|
|
2845
2845
|
killAll(opts = {}) {
|
|
2846
2846
|
const pids = Array.from(this.processes.keys());
|
|
2847
2847
|
const killed = [];
|
|
2848
|
+
const includeProtected = opts.includeProtected === true;
|
|
2848
2849
|
for (const pid of pids) {
|
|
2849
2850
|
const p = this.processes.get(pid);
|
|
2850
|
-
if (
|
|
2851
|
+
if (!p) continue;
|
|
2852
|
+
if (p.protected && !includeProtected) continue;
|
|
2853
|
+
if (opts.preserveBackground && p.background) continue;
|
|
2854
|
+
if (this.kill(pid, opts)) killed.push(pid);
|
|
2851
2855
|
}
|
|
2852
2856
|
return killed;
|
|
2853
2857
|
}
|
package/dist/lint.js
CHANGED
|
@@ -666,7 +666,7 @@ var ProcessRegistryImpl = class {
|
|
|
666
666
|
const p = this.processes.get(pid);
|
|
667
667
|
if (!p) return false;
|
|
668
668
|
if (p.killed) return true;
|
|
669
|
-
if (p.protected) return false;
|
|
669
|
+
if (p.protected && opts.includeProtected !== true) return false;
|
|
670
670
|
if (opts.preserveBackground && p.background) return false;
|
|
671
671
|
const { force = false, graceMs = DEFAULT_GRACE_MS } = opts;
|
|
672
672
|
const isWin2 = os.platform() === "win32";
|
|
@@ -717,9 +717,13 @@ var ProcessRegistryImpl = class {
|
|
|
717
717
|
killAll(opts = {}) {
|
|
718
718
|
const pids = Array.from(this.processes.keys());
|
|
719
719
|
const killed = [];
|
|
720
|
+
const includeProtected = opts.includeProtected === true;
|
|
720
721
|
for (const pid of pids) {
|
|
721
722
|
const p = this.processes.get(pid);
|
|
722
|
-
if (
|
|
723
|
+
if (!p) continue;
|
|
724
|
+
if (p.protected && !includeProtected) continue;
|
|
725
|
+
if (opts.preserveBackground && p.background) continue;
|
|
726
|
+
if (this.kill(pid, opts)) killed.push(pid);
|
|
723
727
|
}
|
|
724
728
|
return killed;
|
|
725
729
|
}
|
package/dist/logs.js
CHANGED
|
@@ -15,6 +15,81 @@ var DANGEROUS_PATTERNS = [
|
|
|
15
15
|
// Greedy quantifier inside lookahead/lookbehind — (?!.*a+)
|
|
16
16
|
/[([][^)\]]*[+*][^)\]]*[)\]][^)]*\?\??/
|
|
17
17
|
];
|
|
18
|
+
function hasAmbiguousQuantifiedAlternation(pattern) {
|
|
19
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
20
|
+
if (pattern[i] !== "(") continue;
|
|
21
|
+
if (i > 0 && pattern[i - 1] === "\\") continue;
|
|
22
|
+
let depth = 0;
|
|
23
|
+
let inClass = false;
|
|
24
|
+
let j = i;
|
|
25
|
+
for (; j < pattern.length; j++) {
|
|
26
|
+
const ch = pattern[j];
|
|
27
|
+
if (ch === "\\") {
|
|
28
|
+
j++;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (inClass) {
|
|
32
|
+
if (ch === "]") inClass = false;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (ch === "[") {
|
|
36
|
+
inClass = true;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (ch === "(") depth++;
|
|
40
|
+
else if (ch === ")") {
|
|
41
|
+
depth--;
|
|
42
|
+
if (depth === 0) break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (j >= pattern.length) return false;
|
|
46
|
+
const next = pattern[j + 1];
|
|
47
|
+
if (next !== "+" && next !== "*" && next !== "{") continue;
|
|
48
|
+
let inner = pattern.slice(i + 1, j);
|
|
49
|
+
inner = inner.replace(/^\?(?::|<?[=!])/u, "");
|
|
50
|
+
const branches = [];
|
|
51
|
+
let current = "";
|
|
52
|
+
let d = 0;
|
|
53
|
+
let cls = false;
|
|
54
|
+
for (let k = 0; k < inner.length; k++) {
|
|
55
|
+
const ch = inner[k];
|
|
56
|
+
if (ch === "\\") {
|
|
57
|
+
current += ch + (inner[k + 1] ?? "");
|
|
58
|
+
k++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (cls) {
|
|
62
|
+
if (ch === "]") cls = false;
|
|
63
|
+
current += ch;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (ch === "[") {
|
|
67
|
+
cls = true;
|
|
68
|
+
current += ch;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (ch === "(") d++;
|
|
72
|
+
if (ch === ")") d--;
|
|
73
|
+
if (ch === "|" && d === 0) {
|
|
74
|
+
branches.push(current);
|
|
75
|
+
current = "";
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
current += ch;
|
|
79
|
+
}
|
|
80
|
+
branches.push(current);
|
|
81
|
+
if (branches.length < 2) continue;
|
|
82
|
+
for (let a = 0; a < branches.length; a++) {
|
|
83
|
+
for (let b = a + 1; b < branches.length; b++) {
|
|
84
|
+
const x = branches[a];
|
|
85
|
+
const y = branches[b];
|
|
86
|
+
if (x === "" || y === "") return true;
|
|
87
|
+
if (x === y || x.startsWith(y) || y.startsWith(x)) return true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
18
93
|
function compileUserRegex(pattern, flags) {
|
|
19
94
|
if (typeof pattern !== "string") {
|
|
20
95
|
return { ok: false, reason: "pattern must be a string" };
|
|
@@ -33,6 +108,12 @@ function compileUserRegex(pattern, flags) {
|
|
|
33
108
|
};
|
|
34
109
|
}
|
|
35
110
|
}
|
|
111
|
+
if (hasAmbiguousQuantifiedAlternation(pattern)) {
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
reason: "pattern quantifies an alternation with overlapping branches \u2014 rewrite so no two branches can match the same text"
|
|
115
|
+
};
|
|
116
|
+
}
|
|
36
117
|
try {
|
|
37
118
|
return { ok: true, regex: new RegExp(pattern, flags) };
|
|
38
119
|
} catch (err) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Tool } from '@wrongstack/core/types';
|
|
2
|
+
/**
|
|
3
|
+
* Structured alternative to typing a `<nextsteps>` block into the final message.
|
|
4
|
+
*
|
|
5
|
+
* Both routes are equally valid and produce the same result — the runtime folds
|
|
6
|
+
* whatever this tool parks into the turn-ending response (see
|
|
7
|
+
* `next-steps-slot.ts` in core), so every surface reads it through the same
|
|
8
|
+
* parser it already uses. What the tool buys is that the schema enforces the
|
|
9
|
+
* shape: a block cannot arrive unbalanced, `auto` cannot land on the wrong
|
|
10
|
+
* item, and item count cannot drift past the contract.
|
|
11
|
+
*
|
|
12
|
+
* Opt-in via `tools.nextsteps.enabled`; registered for the leader only.
|
|
13
|
+
*/
|
|
14
|
+
interface NextStepsInput {
|
|
15
|
+
steps: Array<{
|
|
16
|
+
text: string;
|
|
17
|
+
auto?: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
interface NextStepsOutput {
|
|
21
|
+
accepted: number;
|
|
22
|
+
auto: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare const nextStepsTool: Tool<NextStepsInput, NextStepsOutput>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=next-steps-tool.d.ts.map
|
package/dist/outdated.js
CHANGED
|
@@ -3018,7 +3018,7 @@ var init_process_registry = __esm({
|
|
|
3018
3018
|
const p = this.processes.get(pid);
|
|
3019
3019
|
if (!p) return false;
|
|
3020
3020
|
if (p.killed) return true;
|
|
3021
|
-
if (p.protected) return false;
|
|
3021
|
+
if (p.protected && opts.includeProtected !== true) return false;
|
|
3022
3022
|
if (opts.preserveBackground && p.background) return false;
|
|
3023
3023
|
const { force = false, graceMs = DEFAULT_GRACE_MS } = opts;
|
|
3024
3024
|
const isWin2 = os.platform() === "win32";
|
|
@@ -3069,9 +3069,13 @@ var init_process_registry = __esm({
|
|
|
3069
3069
|
killAll(opts = {}) {
|
|
3070
3070
|
const pids = Array.from(this.processes.keys());
|
|
3071
3071
|
const killed = [];
|
|
3072
|
+
const includeProtected = opts.includeProtected === true;
|
|
3072
3073
|
for (const pid of pids) {
|
|
3073
3074
|
const p = this.processes.get(pid);
|
|
3074
|
-
if (
|
|
3075
|
+
if (!p) continue;
|
|
3076
|
+
if (p.protected && !includeProtected) continue;
|
|
3077
|
+
if (opts.preserveBackground && p.background) continue;
|
|
3078
|
+
if (this.kill(pid, opts)) killed.push(pid);
|
|
3075
3079
|
}
|
|
3076
3080
|
return killed;
|
|
3077
3081
|
}
|