@wrongstack/tools 0.319.0 → 0.319.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.
- package/dist/_edit-match.d.ts +1 -3
- package/dist/_util.d.ts +7 -0
- package/dist/audit.js +4 -4
- package/dist/bash.js +2 -2
- package/dist/builtin.d.ts +10 -0
- package/dist/builtin.js +44 -42
- package/dist/{chunk-2472NT76.js → chunk-2OXHS3KZ.js} +17 -5
- package/dist/{chunk-X5K3U6GI.js → chunk-3M7LLN7W.js} +71 -7
- package/dist/{chunk-VFF3Q5Z3.js → chunk-5EUJF3WC.js} +36 -8
- package/dist/{chunk-QZDOQRF7.js → chunk-64VIJPFV.js} +34 -13
- package/dist/{chunk-UMXVT7ST.js → chunk-6AAOT4PW.js} +58 -10
- package/dist/{chunk-WNUJR3H4.js → chunk-AKHYMB4V.js} +36 -12
- package/dist/{chunk-ZDUGI5BC.js → chunk-ATSKPZUK.js} +2 -2
- package/dist/{chunk-H6AWAZ2Y.js → chunk-B4HTSV6Z.js} +57 -6
- package/dist/{chunk-5ZYEGP2P.js → chunk-BK732J7I.js} +72 -27
- package/dist/{chunk-PMHVSHMU.js → chunk-BSJSNVGA.js} +73 -14
- package/dist/{chunk-KD5EHYA2.js → chunk-C2DQKVLO.js} +61 -28
- package/dist/{chunk-PRXZOIEW.js → chunk-CFLJFDYV.js} +100 -58
- package/dist/{chunk-TX3R5NVV.js → chunk-CMOUCKGC.js} +2 -2
- package/dist/{chunk-SYXW3Y5Z.js → chunk-DC4KMPJO.js} +2 -2
- package/dist/{chunk-MRKWZCHZ.js → chunk-DP6CXMJZ.js} +3 -3
- package/dist/{chunk-ODFVG54U.js → chunk-EADULOZV.js} +36 -12
- package/dist/{chunk-6RNIFLG4.js → chunk-ELRRTWNP.js} +38 -6
- package/dist/{chunk-YZHK4TLF.js → chunk-FQNXYA6W.js} +45 -6
- package/dist/{chunk-65EMYN5G.js → chunk-GMZYW52L.js} +3 -3
- package/dist/{chunk-HBM4QNXU.js → chunk-IU4DV2PA.js} +18 -8
- package/dist/{chunk-COUNXG4X.js → chunk-IWS56OY7.js} +30 -7
- package/dist/{chunk-Z4VBTVUM.js → chunk-IYKXK356.js} +98 -11
- package/dist/{chunk-OJ4FIBAN.js → chunk-JDPQOR7C.js} +14 -7
- package/dist/{chunk-TFMVHYJI.js → chunk-KY4PXYSO.js} +9 -15
- package/dist/{chunk-ZKSBHXVB.js → chunk-LOBRWKCR.js} +63 -14
- package/dist/{chunk-HWDB2G7J.js → chunk-MNP3GE7H.js} +38 -27
- package/dist/{chunk-MYRMD6PZ.js → chunk-O44IMQCN.js} +31 -7
- package/dist/{chunk-7WV3D4S3.js → chunk-OG2BEUBY.js} +69 -34
- package/dist/{chunk-VALQFAY2.js → chunk-OTINMOKK.js} +153 -40
- package/dist/{chunk-PQTONQ4P.js → chunk-QPNYDH5B.js} +19 -5
- package/dist/{chunk-4Q7LFU4T.js → chunk-RLMX75EM.js} +19 -8
- package/dist/{chunk-C3W3V54D.js → chunk-RNWUCZ2U.js} +53 -25
- package/dist/{chunk-RK47IWO3.js → chunk-RTZWBNTY.js} +59 -28
- package/dist/{chunk-UC3RKRIV.js → chunk-TTZOK6IY.js} +2 -2
- package/dist/{chunk-W4GAAI3M.js → chunk-UDVKRX5R.js} +2 -2
- package/dist/{chunk-Y7QXSE7N.js → chunk-UQQS3VNT.js} +43 -9
- package/dist/{chunk-D4CXUZIF.js → chunk-VD2LV5WO.js} +82 -13
- package/dist/{chunk-DPKTXJQS.js → chunk-VPALDFYM.js} +2 -2
- package/dist/{chunk-FJEQZHZN.js → chunk-W2CECGTG.js} +24 -14
- package/dist/{chunk-OYVPBPCL.js → chunk-X5FOFGXX.js} +72 -33
- package/dist/{chunk-CWALNI6K.js → chunk-X6KXNHUO.js} +1 -1
- package/dist/{chunk-OCUXN6Y3.js → chunk-XRNN44QY.js} +1 -1
- package/dist/{chunk-N5O3FK5Q.js → chunk-YOKD4GWJ.js} +67 -27
- package/dist/{chunk-QLF74MSV.js → chunk-ZUFHAHTE.js} +12 -6
- package/dist/codebase-index/index.js +7 -7
- package/dist/codebase-index/parser-worker-script.js +1 -1
- package/dist/codebase-index/project-server.js +3 -3
- package/dist/codebase-index/worker.js +2 -2
- package/dist/design.d.ts +1 -1
- package/dist/design.js +1 -1
- package/dist/diff.js +3 -2
- package/dist/document.js +2 -2
- package/dist/e2e.js +2 -2
- package/dist/edit.js +6 -6
- package/dist/exec.js +2 -2
- package/dist/fetch.js +2 -2
- package/dist/format.js +4 -4
- package/dist/git.js +2 -2
- package/dist/glob.js +2 -2
- package/dist/grep.d.ts +2 -0
- package/dist/grep.js +4 -2
- package/dist/index.js +44 -44
- package/dist/install.js +4 -4
- package/dist/json.js +2 -2
- package/dist/kanban-tool-types.d.ts +2 -0
- package/dist/kanban.js +2 -2
- package/dist/languages/index.js +2 -2
- package/dist/{legacy-bridge-EC7GM2IW.js → legacy-bridge-3T7SR4SK.js} +4 -4
- package/dist/lint.js +4 -4
- package/dist/logs.js +2 -2
- package/dist/outdated.js +4 -2
- package/dist/pack.js +43 -43
- package/dist/{parser-dispatch-3PDBKIQ7.js → parser-dispatch-QGC4HSP5.js} +2 -2
- package/dist/patch.js +6 -6
- package/dist/plan.js +4 -4
- package/dist/read.js +6 -6
- package/dist/replace.js +7 -6
- package/dist/scaffold.js +2 -2
- package/dist/search.js +1 -1
- package/dist/session-kanban.js +1 -1
- package/dist/task.js +4 -4
- package/dist/test.js +4 -4
- package/dist/todo.js +3 -3
- package/dist/tool-tier.js +44 -44
- package/dist/{tree-sitter-parser-FGKHJGSX.js → tree-sitter-parser-GILYQLS4.js} +2 -2
- package/dist/tree.js +2 -2
- package/dist/typecheck.js +4 -4
- package/dist/write.js +6 -6
- package/package.json +5 -5
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mapWithConcurrency
|
|
3
|
+
} from "./chunk-NWZ6XGBJ.js";
|
|
1
4
|
import {
|
|
2
5
|
safeResolveReal
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
4
7
|
|
|
5
8
|
// src/diff.ts
|
|
6
9
|
import { spawn } from "node:child_process";
|
|
@@ -59,6 +62,7 @@ var diffTool = {
|
|
|
59
62
|
},
|
|
60
63
|
async execute(input, ctx, opts) {
|
|
61
64
|
const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
|
|
65
|
+
signal.throwIfAborted();
|
|
62
66
|
if (input.a !== void 0 || input.b !== void 0) {
|
|
63
67
|
return await gitDiff(input, ctx, signal);
|
|
64
68
|
}
|
|
@@ -66,13 +70,25 @@ var diffTool = {
|
|
|
66
70
|
}
|
|
67
71
|
};
|
|
68
72
|
async function gitDiff(input, ctx, signal) {
|
|
69
|
-
if (input.a
|
|
73
|
+
if (input.a !== void 0 && (!input.a || !input.a.trim())) {
|
|
74
|
+
throw new ToolValidationError({
|
|
75
|
+
message: "diff: ref 'a' cannot be empty or whitespace-only",
|
|
76
|
+
field: "a"
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (input.b !== void 0 && (!input.b || !input.b.trim())) {
|
|
80
|
+
throw new ToolValidationError({
|
|
81
|
+
message: "diff: ref 'b' cannot be empty or whitespace-only",
|
|
82
|
+
field: "b"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (input.a?.trim().startsWith("-")) {
|
|
70
86
|
throw new ToolValidationError({
|
|
71
87
|
message: `diff: unsafe ref "${input.a}" \u2014 refs may not begin with '-' (flag injection)`,
|
|
72
88
|
field: "a"
|
|
73
89
|
});
|
|
74
90
|
}
|
|
75
|
-
if (input.b?.startsWith("-")) {
|
|
91
|
+
if (input.b?.trim().startsWith("-")) {
|
|
76
92
|
throw new ToolValidationError({
|
|
77
93
|
message: `diff: unsafe ref "${input.b}" \u2014 refs may not begin with '-' (flag injection)`,
|
|
78
94
|
field: "b"
|
|
@@ -82,9 +98,16 @@ async function gitDiff(input, ctx, signal) {
|
|
|
82
98
|
const statMode = requestedMode === "stat";
|
|
83
99
|
const effectiveMode = statMode ? "stat" : "unified";
|
|
84
100
|
const sideBySideNote = requestedMode === "side-by-side" ? "side-by-side output is not supported; a unified diff was produced instead." : void 0;
|
|
85
|
-
const
|
|
101
|
+
const basePath = input.path ? await safeResolveReal(input.path, ctx) : ctx.cwd;
|
|
102
|
+
const gitDir = findGitDir(basePath);
|
|
86
103
|
if (!gitDir) {
|
|
87
|
-
return {
|
|
104
|
+
return {
|
|
105
|
+
diff: "",
|
|
106
|
+
files: [],
|
|
107
|
+
truncated: false,
|
|
108
|
+
mode: effectiveMode,
|
|
109
|
+
note: "Not a git repository (or any parent up to root)."
|
|
110
|
+
};
|
|
88
111
|
}
|
|
89
112
|
const args = ["diff", "--no-color"];
|
|
90
113
|
if (statMode) args.push("--stat");
|
|
@@ -93,11 +116,11 @@ async function gitDiff(input, ctx, signal) {
|
|
|
93
116
|
if (Number.isFinite(contextLines)) args.push(`-U${contextLines}`);
|
|
94
117
|
}
|
|
95
118
|
if (input.staged) args.push("--staged");
|
|
96
|
-
if (input.a) args.push(input.a);
|
|
97
|
-
if (input.b) args.push(input.b);
|
|
119
|
+
if (input.a) args.push(input.a.trim());
|
|
120
|
+
if (input.b) args.push(input.b.trim());
|
|
98
121
|
if (input.files) {
|
|
99
122
|
const files = Array.isArray(input.files) ? input.files : input.files.split(",");
|
|
100
|
-
args.push("--", ...files.map((f) => f.trim()));
|
|
123
|
+
args.push("--", ...files.map((f) => f.trim().replace(/\\/g, "/")));
|
|
101
124
|
}
|
|
102
125
|
const result = await runGit(args, gitDir, signal);
|
|
103
126
|
let diff = result.stdout;
|
|
@@ -110,12 +133,14 @@ async function gitDiff(input, ctx, signal) {
|
|
|
110
133
|
\u2026[git diff truncated: ${result.stdout.length - clipped.length} of ${result.stdout.length} characters omitted]`;
|
|
111
134
|
truncated = true;
|
|
112
135
|
}
|
|
136
|
+
const exitNote = result.exitCode !== 0 ? `git diff exited with code ${result.exitCode}: ${result.stderr.trim() || "command failed"}` : void 0;
|
|
137
|
+
const combinedNote = [sideBySideNote, exitNote].filter(Boolean).join("\n") || void 0;
|
|
113
138
|
return {
|
|
114
139
|
diff,
|
|
115
140
|
files: [],
|
|
116
141
|
truncated,
|
|
117
142
|
mode: effectiveMode,
|
|
118
|
-
note:
|
|
143
|
+
note: combinedNote
|
|
119
144
|
};
|
|
120
145
|
}
|
|
121
146
|
function findGitDir(cwd) {
|
|
@@ -133,7 +158,10 @@ function findGitDir(cwd) {
|
|
|
133
158
|
return null;
|
|
134
159
|
}
|
|
135
160
|
function runGit(args, cwd, signal) {
|
|
136
|
-
|
|
161
|
+
if (signal.aborted) {
|
|
162
|
+
return Promise.resolve({ stdout: "", stderr: "Aborted", exitCode: 124 });
|
|
163
|
+
}
|
|
164
|
+
return new Promise((resolve2) => {
|
|
137
165
|
let stdout = "";
|
|
138
166
|
let stderr = "";
|
|
139
167
|
const child = spawn("git", args, {
|
|
@@ -149,11 +177,12 @@ function runGit(args, cwd, signal) {
|
|
|
149
177
|
child.stderr?.on("data", (c) => {
|
|
150
178
|
stderr += c.toString();
|
|
151
179
|
});
|
|
152
|
-
child.on("close", (code) =>
|
|
153
|
-
child.on("error", (e) =>
|
|
180
|
+
child.on("close", (code) => resolve2({ stdout, stderr, exitCode: code ?? 0 }));
|
|
181
|
+
child.on("error", (e) => resolve2({ stdout: "", stderr: e.message, exitCode: 1 }));
|
|
154
182
|
});
|
|
155
183
|
}
|
|
156
|
-
async function fileDiff(input, ctx,
|
|
184
|
+
async function fileDiff(input, ctx, signal) {
|
|
185
|
+
signal.throwIfAborted();
|
|
157
186
|
void input.context;
|
|
158
187
|
const files = input.files ? (Array.isArray(input.files) ? input.files : input.files.split(",")).map((f) => f.trim()).filter(Boolean) : [];
|
|
159
188
|
if (files.length === 0) {
|
|
@@ -164,25 +193,26 @@ async function fileDiff(input, ctx, _signal) {
|
|
|
164
193
|
mode: "dump"
|
|
165
194
|
};
|
|
166
195
|
}
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
output: `--- ${file} (skipped: ${stat2.size} bytes exceeds the ${MAX_FILE_DUMP_BYTES} limit; use the read tool with offset/limit) ---`
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
const content = await fs.readFile(absPath, "utf8");
|
|
179
|
-
const lines = content.split(/\r?\n/);
|
|
196
|
+
const basePath = input.path ? await safeResolveReal(input.path, ctx) : ctx.cwd;
|
|
197
|
+
const fileEntries = await mapWithConcurrency(files, 16, async (file) => {
|
|
198
|
+
signal.throwIfAborted();
|
|
199
|
+
const fileToResolve = path.isAbsolute(file) ? file : path.resolve(basePath, file);
|
|
200
|
+
const absPath = await safeResolveReal(fileToResolve, ctx);
|
|
201
|
+
const stat2 = await fs.stat(absPath).catch(() => null);
|
|
202
|
+
if (!stat2?.isFile()) return null;
|
|
203
|
+
if (stat2.size > MAX_FILE_DUMP_BYTES) {
|
|
180
204
|
return {
|
|
181
|
-
truncated:
|
|
182
|
-
output:
|
|
205
|
+
truncated: true,
|
|
206
|
+
output: `--- ${file} (skipped: ${stat2.size} bytes exceeds the ${MAX_FILE_DUMP_BYTES} limit; use the read tool with offset/limit) ---`
|
|
183
207
|
};
|
|
184
|
-
}
|
|
185
|
-
|
|
208
|
+
}
|
|
209
|
+
const content = await fs.readFile(absPath, "utf8");
|
|
210
|
+
const lines = content.split(/\r?\n/);
|
|
211
|
+
return {
|
|
212
|
+
truncated: false,
|
|
213
|
+
output: formatWithLineNumbers(file, lines)
|
|
214
|
+
};
|
|
215
|
+
});
|
|
186
216
|
const results = [];
|
|
187
217
|
let truncated = false;
|
|
188
218
|
for (const entry of fileEntries) {
|
|
@@ -201,13 +231,18 @@ async function fileDiff(input, ctx, _signal) {
|
|
|
201
231
|
};
|
|
202
232
|
}
|
|
203
233
|
function formatWithLineNumbers(file, lines) {
|
|
204
|
-
const
|
|
205
|
-
const
|
|
234
|
+
const count = lines.length;
|
|
235
|
+
const width = String(count).length;
|
|
236
|
+
const parts = new Array(count);
|
|
237
|
+
for (let i = 0; i < count; i++) {
|
|
238
|
+
const numStr = String(i + 1).padStart(width, " ");
|
|
239
|
+
parts[i] = `${numStr} | ${lines[i]}`;
|
|
240
|
+
}
|
|
206
241
|
return `--- ${file} (line-numbered dump, not a unified diff) ---
|
|
207
|
-
${
|
|
242
|
+
${parts.join("\n")}`;
|
|
208
243
|
}
|
|
209
244
|
|
|
210
245
|
export {
|
|
211
246
|
diffTool
|
|
212
247
|
};
|
|
213
|
-
//# sourceMappingURL=chunk-
|
|
248
|
+
//# sourceMappingURL=chunk-OG2BEUBY.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
e2ePlanTool
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VPALDFYM.js";
|
|
4
4
|
import {
|
|
5
5
|
codebaseAstReplaceTool,
|
|
6
6
|
codebaseImpactAnalysisTool,
|
|
@@ -14,13 +14,13 @@ import {
|
|
|
14
14
|
codebaseStatsTool,
|
|
15
15
|
codebaseTargetedTestTool,
|
|
16
16
|
deadCodeScanTool
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-RTZWBNTY.js";
|
|
18
18
|
import {
|
|
19
19
|
planTool
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-B4HTSV6Z.js";
|
|
21
21
|
import {
|
|
22
22
|
taskTool
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-3M7LLN7W.js";
|
|
24
24
|
import {
|
|
25
25
|
toolSearchTool
|
|
26
26
|
} from "./chunk-RJZQWEMS.js";
|
|
@@ -35,76 +35,76 @@ import {
|
|
|
35
35
|
} from "./chunk-QBV725YG.js";
|
|
36
36
|
import {
|
|
37
37
|
designTool
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-ELRRTWNP.js";
|
|
39
39
|
import {
|
|
40
40
|
testTool
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-UQQS3VNT.js";
|
|
42
42
|
import {
|
|
43
43
|
installTool
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-RLMX75EM.js";
|
|
45
45
|
import {
|
|
46
46
|
auditTool
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-64VIJPFV.js";
|
|
48
48
|
import {
|
|
49
49
|
outdatedTool
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-IYKXK356.js";
|
|
51
51
|
import {
|
|
52
52
|
logsTool
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-FQNXYA6W.js";
|
|
54
54
|
import {
|
|
55
55
|
documentTool
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-IU4DV2PA.js";
|
|
57
57
|
import {
|
|
58
58
|
scaffoldTool
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-2OXHS3KZ.js";
|
|
60
60
|
import {
|
|
61
61
|
gitTool
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-6AAOT4PW.js";
|
|
63
63
|
import {
|
|
64
64
|
patchTool
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-IWS56OY7.js";
|
|
66
66
|
import {
|
|
67
67
|
jsonTool
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-VD2LV5WO.js";
|
|
69
69
|
import {
|
|
70
70
|
diffTool
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-OG2BEUBY.js";
|
|
72
72
|
import {
|
|
73
73
|
treeTool
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-MNP3GE7H.js";
|
|
75
75
|
import {
|
|
76
76
|
lintTool
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-LOBRWKCR.js";
|
|
78
78
|
import {
|
|
79
79
|
formatTool
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-EADULOZV.js";
|
|
81
81
|
import {
|
|
82
82
|
typecheckTool
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-5EUJF3WC.js";
|
|
84
84
|
import {
|
|
85
85
|
languageInfoTool,
|
|
86
86
|
languagePackageTool,
|
|
87
87
|
languageTool
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-TTZOK6IY.js";
|
|
89
89
|
import {
|
|
90
90
|
replaceTool
|
|
91
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-X5FOFGXX.js";
|
|
92
92
|
import {
|
|
93
93
|
globTool
|
|
94
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-JDPQOR7C.js";
|
|
95
95
|
import {
|
|
96
96
|
grepTool
|
|
97
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-YOKD4GWJ.js";
|
|
98
98
|
import {
|
|
99
99
|
bashTool,
|
|
100
100
|
checkAndBlockKillCommand,
|
|
101
101
|
diagnoseBashism,
|
|
102
102
|
shellArgs
|
|
103
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-AKHYMB4V.js";
|
|
104
104
|
import {
|
|
105
105
|
detectDanger,
|
|
106
106
|
execTool
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-BSJSNVGA.js";
|
|
108
108
|
import {
|
|
109
109
|
buildChildEnv
|
|
110
110
|
} from "./chunk-BTSFTGIL.js";
|
|
@@ -118,28 +118,28 @@ import {
|
|
|
118
118
|
} from "./chunk-3PVYQFRQ.js";
|
|
119
119
|
import {
|
|
120
120
|
fetchTool
|
|
121
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-C2DQKVLO.js";
|
|
122
122
|
import {
|
|
123
123
|
searchTool
|
|
124
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-QPNYDH5B.js";
|
|
125
125
|
import {
|
|
126
126
|
todoTool
|
|
127
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-BK732J7I.js";
|
|
128
128
|
import {
|
|
129
129
|
kanbanTool
|
|
130
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-W2CECGTG.js";
|
|
131
131
|
import {
|
|
132
132
|
browserTools
|
|
133
133
|
} from "./chunk-45JPRMC2.js";
|
|
134
134
|
import {
|
|
135
135
|
readTool
|
|
136
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-RNWUCZ2U.js";
|
|
137
137
|
import {
|
|
138
138
|
writeTool
|
|
139
|
-
} from "./chunk-
|
|
139
|
+
} from "./chunk-O44IMQCN.js";
|
|
140
140
|
import {
|
|
141
141
|
editTool
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-CFLJFDYV.js";
|
|
143
143
|
import {
|
|
144
144
|
resolvePowerShell
|
|
145
145
|
} from "./chunk-V43EQ6VR.js";
|
|
@@ -147,7 +147,7 @@ import {
|
|
|
147
147
|
normalizeCommandOutput,
|
|
148
148
|
safeResolveProjectPath,
|
|
149
149
|
safeResolveReal
|
|
150
|
-
} from "./chunk-
|
|
150
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
151
151
|
|
|
152
152
|
// src/clarify.ts
|
|
153
153
|
import { toErrorMessage } from "@wrongstack/core/utils";
|
|
@@ -193,8 +193,10 @@ var clarifyTool = {
|
|
|
193
193
|
required: ["question", "options"],
|
|
194
194
|
additionalProperties: false
|
|
195
195
|
},
|
|
196
|
-
async execute(input, ctx) {
|
|
196
|
+
async execute(input, ctx, opts) {
|
|
197
197
|
try {
|
|
198
|
+
const signal = opts?.signal ?? ctx?.signal;
|
|
199
|
+
signal?.throwIfAborted();
|
|
198
200
|
const options = input.options;
|
|
199
201
|
if (!options || options.length < 2) {
|
|
200
202
|
throw new Error("clarify requires at least 2 distinct options.");
|
|
@@ -238,6 +240,7 @@ import {
|
|
|
238
240
|
emitProcessOutput,
|
|
239
241
|
emitProcessStarted
|
|
240
242
|
} from "@wrongstack/core/observability";
|
|
243
|
+
import { ToolValidationError } from "@wrongstack/core/types";
|
|
241
244
|
var MAX_OUTPUT = 32768;
|
|
242
245
|
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
243
246
|
var STREAM_FLUSH_INTERVAL_MS = 200;
|
|
@@ -383,8 +386,38 @@ var pwshTool = {
|
|
|
383
386
|
if (!final) throw new Error("pwsh: stream ended without final event");
|
|
384
387
|
return final;
|
|
385
388
|
},
|
|
389
|
+
async cleanup(_input, ctx) {
|
|
390
|
+
const registry = getProcessRegistry();
|
|
391
|
+
const sessionId = ctx.session?.id;
|
|
392
|
+
if (!sessionId) return;
|
|
393
|
+
for (const entry of registry.bySession(sessionId)) {
|
|
394
|
+
if (entry.name !== "pwsh") continue;
|
|
395
|
+
if (entry.child && entry.child.exitCode !== null) continue;
|
|
396
|
+
if (entry.protected) continue;
|
|
397
|
+
registry.kill(entry.pid, { force: true });
|
|
398
|
+
}
|
|
399
|
+
},
|
|
386
400
|
async *executeStream(input, ctx, opts) {
|
|
387
|
-
if (!input?.command
|
|
401
|
+
if (!input?.command || typeof input.command !== "string" || !input.command.trim()) {
|
|
402
|
+
throw new ToolValidationError({
|
|
403
|
+
message: "pwsh: command is required and cannot be empty",
|
|
404
|
+
field: "command"
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
const callerSignal = opts?.signal ?? ctx?.signal ?? new AbortController().signal;
|
|
408
|
+
if (callerSignal.aborted) {
|
|
409
|
+
yield {
|
|
410
|
+
type: "final",
|
|
411
|
+
output: {
|
|
412
|
+
output: "",
|
|
413
|
+
exit_code: 124,
|
|
414
|
+
timed_out: false,
|
|
415
|
+
pid: null,
|
|
416
|
+
error: "Aborted"
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
388
421
|
const isBackground = !!(input.run_in_background || input.background);
|
|
389
422
|
const registry = getProcessRegistry();
|
|
390
423
|
if (!registry.beforeCall(isBackground)) {
|
|
@@ -438,7 +471,6 @@ var pwshTool = {
|
|
|
438
471
|
return;
|
|
439
472
|
}
|
|
440
473
|
const startedAt = Date.now();
|
|
441
|
-
const callerSignal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
|
|
442
474
|
const detached = !isWin;
|
|
443
475
|
if (isBackground) {
|
|
444
476
|
const child2 = spawn(bin, args, {
|
|
@@ -546,7 +578,8 @@ Working directory: ${targetCwd}`,
|
|
|
546
578
|
processGroupLeader: detached && child.pid === pid
|
|
547
579
|
});
|
|
548
580
|
}
|
|
549
|
-
const
|
|
581
|
+
const rawTimeout = typeof input.timeout_ms === "number" && !Number.isNaN(input.timeout_ms) ? input.timeout_ms : DEFAULT_TIMEOUT_MS;
|
|
582
|
+
const timeoutMs = Math.min(Math.max(1e3, rawTimeout), 6e5);
|
|
550
583
|
let timedOut = false;
|
|
551
584
|
const timers = [];
|
|
552
585
|
const killWithTimeout = (timeout) => {
|
|
@@ -1018,6 +1051,78 @@ var setWorkingDirTool = {
|
|
|
1018
1051
|
};
|
|
1019
1052
|
|
|
1020
1053
|
// src/builtin.ts
|
|
1054
|
+
var BUILTIN_TOOL_DESCRIPTIONS = {
|
|
1055
|
+
browser_open: "Create an isolated, agent-owned Playwright browser session, optionally opening an approved HTTP(S) URL. Use it to begin browser QA; private and localhost origins require an explicit allowlist.",
|
|
1056
|
+
browser_list: "List browser sessions owned by this agent, including their state and current page, without exposing sessions owned by other agents.",
|
|
1057
|
+
browser_status: "Check whether the managed Playwright Chromium installation is available before attempting browser automation.",
|
|
1058
|
+
browser_navigate: "Navigate one of this agent\u2019s browser sessions to an approved HTTP(S) URL. Use browser_open first; private and localhost origins require an explicit allowlist.",
|
|
1059
|
+
browser_snapshot: "Inspect the current page through a bounded accessibility snapshot, with redacted console and network summaries. Prefer this before interacting with page elements.",
|
|
1060
|
+
browser_screenshot: "Capture a PNG of the current page or a selected element for visual QA. The result is a sensitive artifact with integrity metadata.",
|
|
1061
|
+
browser_type: "Fill a form control in an owned browser session. Use secretEnv for credentials so secret values never enter tool arguments or the audit trail.",
|
|
1062
|
+
browser_click: "Click a verified page element in an owned browser session. Snapshot first and use the most specific stable selector available.",
|
|
1063
|
+
browser_hover: "Hover over a verified page element in an owned browser session to reveal menus, tooltips, or other hover-driven UI state.",
|
|
1064
|
+
browser_select: "Choose an option in a select control in an owned browser session after confirming the target selector and intended value.",
|
|
1065
|
+
browser_press: "Send a keyboard key or shortcut to an owned browser session, such as Enter after verifying a form is ready to submit.",
|
|
1066
|
+
browser_drag: "Drag one page element onto another in an owned browser session. Use only when the page\u2019s drag-and-drop interaction is the intended action.",
|
|
1067
|
+
browser_wait: "Wait for a selector, navigation condition, or bounded duration in an owned browser session before taking the next browser action.",
|
|
1068
|
+
browser_evaluate: "Run a bounded JavaScript expression in an owned page when browser APIs cannot inspect the needed state. Treat page code as arbitrary and use sparingly.",
|
|
1069
|
+
browser_upload: "Upload project-local files through a page file input in an owned browser session. Verify both the file path and target control before uploading.",
|
|
1070
|
+
browser_close: "Close an owned browser session and reclaim its resources, returning trace-artifact metadata when tracing was enabled.",
|
|
1071
|
+
e2e_plan: "Create an end-to-end test plan from a feature or user flow. Use it to identify scenarios and acceptance coverage; it plans tests rather than executing them.",
|
|
1072
|
+
read: "Read a project file safely, with optional line ranges and binary-aware output. Use it to inspect source before editing; paths must stay within the project.",
|
|
1073
|
+
write: "Create or replace one project file with the complete supplied content. Use for new files or intentional full rewrites, after reading existing content when applicable.",
|
|
1074
|
+
edit: "Make a precise, guarded text edit by replacing an expected block in a project file. Prefer it for small source changes so mismatches prevent accidental overwrites.",
|
|
1075
|
+
clarify: "Record or ask a focused clarification when a missing decision would materially change the implementation. Do not use it for questions that can be answered from the repository.",
|
|
1076
|
+
"codebase-ast-replace": "Replace a named declaration using source-aware structure instead of fragile text matching. Use it for a function, method, class, interface, or variable when the target is unambiguous.",
|
|
1077
|
+
"codebase-invariant-check": "Compare candidate code with its original source and report structural invariants that may have changed. Use before writing a risky refactor; it validates but does not modify files.",
|
|
1078
|
+
"codebase-stats": "Report codebase-index health, indexed file and symbol counts, languages, and freshness. Use it before relying on indexed discovery results.",
|
|
1079
|
+
"codebase-search": "Search indexed symbols, signatures, and documentation with optional language, kind, path, or LSP-kind filters. Use it for semantic discovery before broad text search.",
|
|
1080
|
+
"codebase-skeleton": "Extract a compact structural skeleton from a source file or directory, preserving declarations while omitting implementation detail. Use it to understand unfamiliar code quickly.",
|
|
1081
|
+
"codebase-repo-map": "Generate a concise map of important files, symbols, and relationships in a project area. Use it for orientation before a cross-file change.",
|
|
1082
|
+
"codebase-impact-analysis": "Find likely callers, dependents, related tests, and change risk for a named symbol. Use it before changing a public or widely used declaration.",
|
|
1083
|
+
"codebase-targeted-test": "Discover and run tests that cover a specified symbol, source file, or explicit test files. Use it for focused regression validation after a change.",
|
|
1084
|
+
"security-ast-scan": "Statically scan source code for supported security patterns and return findings with locations. Use it as a focused code check, not as a substitute for a full security assessment.",
|
|
1085
|
+
"codebase-incoming-calls": "Find indexed call sites that invoke a named function, method, or type, optionally scoped to a file. Use it to estimate breakage before changing an API.",
|
|
1086
|
+
"codebase-outgoing-calls": "Find indexed symbols called by a named function, method, or type, optionally scoped to a file. Use it to understand dependencies before refactoring behavior.",
|
|
1087
|
+
"codebase-index": "Build or refresh the local semantic codebase index, optionally for selected languages. Use it when index results are absent or stale; force performs a full reindex.",
|
|
1088
|
+
"dead-code-scan": "Analyze the indexed project for declarations that appear unreachable from configured entry points. Treat results as candidates for review, not automatic deletion instructions.",
|
|
1089
|
+
replace: "Preview or apply a regular-expression replacement across selected project files. Start with dry_run, constrain files and globs carefully, then apply only reviewed changes.",
|
|
1090
|
+
glob: "Find project files by glob pattern, respecting repository boundaries and ignore rules. Use it to locate candidate paths before reading or editing them.",
|
|
1091
|
+
grep: "Search project text with a bounded regular expression and contextual matches. Use it for exact literals or patterns when semantic codebase search is not appropriate.",
|
|
1092
|
+
bash: "Run a shell command in the project with bounded output and timeout controls. Use it for development commands after checking side effects; background mode returns a process handle.",
|
|
1093
|
+
exec: "Execute a command directly without shell interpretation, using explicit program arguments. Prefer it when argument safety and predictable process invocation matter.",
|
|
1094
|
+
pwsh: "Execute a PowerShell command in the project with timeout, output, and background controls. Use it for Windows-native project operations and verify commands that can modify state.",
|
|
1095
|
+
fetch: "Fetch and extract content from an approved HTTP(S) URL for research or integration work. Use it for a known page or endpoint, not for general web discovery.",
|
|
1096
|
+
search: "Search the public web for current external information, then inspect selected results with fetch. Use it when repository evidence is insufficient or the fact may have changed.",
|
|
1097
|
+
todo: "Create, update, or list the session\u2019s concrete work items and their progress. Use it to keep multi-step work visible; it does not implement the tasks itself.",
|
|
1098
|
+
plan: "Create and manage higher-level plan-board items, priorities, and status. Use it for strategic work tracking rather than small immediate edits.",
|
|
1099
|
+
kanban: "Manage project Kanban boards, cards, assignments, and acceptance evidence. Use it for persistent team workflow; changing board state is intentional and reviewable.",
|
|
1100
|
+
task: "Manage structured task records, dependencies, ownership, and promotion into actionable session work. Use it to organize bounded work before delegation or execution.",
|
|
1101
|
+
git: "Inspect or run scoped Git operations in the project, including status, diff, history, branches, and commits. Review the target and working tree before mutating operations.",
|
|
1102
|
+
patch: "Apply a unified diff to project files with patch-style context checking. Use it for a reviewed multi-file change when exact patch content is available.",
|
|
1103
|
+
json: "Read, query, validate, or update JSON files while preserving valid structure. Use it instead of raw text edits when changing structured JSON data.",
|
|
1104
|
+
diff: "Compare two files, revisions, or text inputs and return a readable unified diff. Use it to review intended changes before applying or committing them.",
|
|
1105
|
+
tree: "Render a bounded directory tree with depth, file, hidden-file, and ignore controls. Use it for repository orientation without reading every file.",
|
|
1106
|
+
lint: "Run the project\u2019s configured linter for a target path or working directory and return diagnostics. Use it after code edits to catch style and static-analysis issues.",
|
|
1107
|
+
format: "Run the project\u2019s configured formatter on selected files or directories. Use it after editing code, while reviewing the resulting diff for unintended formatting scope.",
|
|
1108
|
+
typecheck: "Run TypeScript type checking for an auto-detected or specified tsconfig. Use it after type-affecting changes; it reports diagnostics without writing source files.",
|
|
1109
|
+
test: "Run the detected test runner for selected tests, with optional name filtering, coverage, watch, and timeout controls. Prefer focused tests first, then broader validation as needed.",
|
|
1110
|
+
language_info: "Inspect detected language tooling, workspaces, and supported operations for the project or target path. Use it before invoking language-specific tooling.",
|
|
1111
|
+
language: "Run a supported language-tooling operation in a detected workspace. Use it when the language profile provides a safer, structured alternative to an arbitrary shell command.",
|
|
1112
|
+
language_package: "Plan or perform a dependency operation through the detected package ecosystem. Use dry-run first when possible and specify the workspace or dependency scope deliberately.",
|
|
1113
|
+
install: "Install project dependencies with the detected package manager. Use only when dependency changes are required, and inspect lockfile and manifest changes afterward.",
|
|
1114
|
+
audit: "Run the package manager\u2019s dependency vulnerability audit and summarize actionable findings. Use it to assess known dependency advisories, not source-code vulnerabilities.",
|
|
1115
|
+
outdated: "List outdated project dependencies and available versions without changing manifests or lockfiles. Use it to plan dependency maintenance.",
|
|
1116
|
+
logs: "Read or tail configured local, container, or process logs with bounded output. Use it to investigate a known runtime failure or service behavior.",
|
|
1117
|
+
document: "Generate or update project documentation from supplied scope and source context. Use it to record verified behavior; review generated text before treating it as authoritative.",
|
|
1118
|
+
scaffold: "Preview or generate files from a built-in or custom scaffold template. Use dry_run first to inspect paths and content before creating project files.",
|
|
1119
|
+
design: "Create a structured implementation design with goals, constraints, approach, and risks. Use it before a substantial change that needs an explicit technical decision.",
|
|
1120
|
+
tool_search: "Discover registered tools by name, description, tag, permission, or mutating status. Use it to find a lazy capability before calling it through tool-use.",
|
|
1121
|
+
tool_use: "Invoke a registered tool by name with its input object, including a tool discovered lazily. Use it only after confirming the target tool\u2019s schema and side effects.",
|
|
1122
|
+
batch_tool_use: "Invoke several independent registered tools as a batch and return each result. Use it for parallel read-only discovery; avoid batching dependent or destructive operations.",
|
|
1123
|
+
tool_help: "Show a tool\u2019s purpose, input schema, permission, and examples, or summarize the catalog. Use it before invoking an unfamiliar or lazily discovered tool.",
|
|
1124
|
+
set_working_dir: "Show or change the session working directory within the permitted project scope. Use it when subsequent commands must target another project subdirectory."
|
|
1125
|
+
};
|
|
1021
1126
|
var OPTIONAL_TOOLS = [
|
|
1022
1127
|
...browserTools,
|
|
1023
1128
|
e2ePlanTool,
|
|
@@ -1093,7 +1198,7 @@ var TIER3_TOOLS = [
|
|
|
1093
1198
|
toolHelpTool,
|
|
1094
1199
|
setWorkingDirTool
|
|
1095
1200
|
];
|
|
1096
|
-
var
|
|
1201
|
+
var rawBuiltinTools = [
|
|
1097
1202
|
...browserTools,
|
|
1098
1203
|
e2ePlanTool,
|
|
1099
1204
|
readTool,
|
|
@@ -1150,6 +1255,13 @@ var builtinTools = [
|
|
|
1150
1255
|
toolHelpTool,
|
|
1151
1256
|
setWorkingDirTool
|
|
1152
1257
|
];
|
|
1258
|
+
var builtinTools = rawBuiltinTools.map((tool) => {
|
|
1259
|
+
const description = BUILTIN_TOOL_DESCRIPTIONS[tool.name];
|
|
1260
|
+
if (!description) {
|
|
1261
|
+
throw new Error(`Missing provider-facing description for built-in tool: ${tool.name}`);
|
|
1262
|
+
}
|
|
1263
|
+
return { ...tool, description };
|
|
1264
|
+
});
|
|
1153
1265
|
|
|
1154
1266
|
export {
|
|
1155
1267
|
clarifyTool,
|
|
@@ -1157,6 +1269,7 @@ export {
|
|
|
1157
1269
|
pwshTool,
|
|
1158
1270
|
analyzeSecurityAndPerformance,
|
|
1159
1271
|
securityAstScanTool,
|
|
1272
|
+
BUILTIN_TOOL_DESCRIPTIONS,
|
|
1160
1273
|
OPTIONAL_TOOLS,
|
|
1161
1274
|
OFF_ONLY_TOOLS,
|
|
1162
1275
|
TIER1_TOOLS,
|
|
@@ -1164,4 +1277,4 @@ export {
|
|
|
1164
1277
|
TIER3_TOOLS,
|
|
1165
1278
|
builtinTools
|
|
1166
1279
|
};
|
|
1167
|
-
//# sourceMappingURL=chunk-
|
|
1280
|
+
//# sourceMappingURL=chunk-OTINMOKK.js.map
|
|
@@ -56,17 +56,19 @@ var searchTool = {
|
|
|
56
56
|
return final;
|
|
57
57
|
},
|
|
58
58
|
async *executeStream(input, ctx, opts) {
|
|
59
|
-
if (!input?.query || input.query.trim() === "") {
|
|
59
|
+
if (!input?.query || typeof input.query !== "string" || input.query.trim() === "") {
|
|
60
60
|
throw new ToolValidationError({
|
|
61
61
|
message: "search: query is required and must be a non-empty string",
|
|
62
62
|
field: "query"
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
65
|
const signal = opts?.signal ?? ctx?.signal ?? new AbortController().signal;
|
|
66
|
-
const
|
|
66
|
+
const rawNum = typeof input.num_results === "number" && !Number.isNaN(input.num_results) ? input.num_results : DEFAULT_NUM;
|
|
67
|
+
const num = Math.max(1, Math.min(Math.floor(rawNum), MAX_RESULTS));
|
|
67
68
|
const source = input.source ?? "duckduckgo";
|
|
68
69
|
const skipCache = input.skip_cache ?? false;
|
|
69
|
-
const
|
|
70
|
+
const normalizedQuery = input.query.trim().toLowerCase().replace(/\s+/g, " ");
|
|
71
|
+
const cacheKey = `${source}:${normalizedQuery}`;
|
|
70
72
|
if (!skipCache) {
|
|
71
73
|
const entry = cache.get(cacheKey);
|
|
72
74
|
if (entry && Date.now() - entry.timestamp < CACHE_TTL_MS) {
|
|
@@ -426,11 +428,23 @@ function capSnippet(snippet) {
|
|
|
426
428
|
return snippet.length > MAX_SNIPPET_CHARS ? `${snippet.slice(0, MAX_SNIPPET_CHARS - 1)}\u2026` : snippet;
|
|
427
429
|
}
|
|
428
430
|
function decodeHtmlEntities(text) {
|
|
429
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'")
|
|
431
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/'/gi, "'").replace(/'/g, "'").replace(/ /g, " ").replace(/–/g, "\u2013").replace(/—/g, "\u2014").replace(/“|”/g, '"').replace(/‘|’/g, "'").replace(/&#(\d+);/g, (_, code) => {
|
|
432
|
+
try {
|
|
433
|
+
return String.fromCodePoint(Number(code));
|
|
434
|
+
} catch {
|
|
435
|
+
return _;
|
|
436
|
+
}
|
|
437
|
+
}).replace(/&#x([0-9a-f]+);/gi, (_, hex) => {
|
|
438
|
+
try {
|
|
439
|
+
return String.fromCodePoint(parseInt(hex, 16));
|
|
440
|
+
} catch {
|
|
441
|
+
return _;
|
|
442
|
+
}
|
|
443
|
+
});
|
|
430
444
|
}
|
|
431
445
|
|
|
432
446
|
export {
|
|
433
447
|
searchTool,
|
|
434
448
|
__clearSearchCache
|
|
435
449
|
};
|
|
436
|
-
//# sourceMappingURL=chunk-
|
|
450
|
+
//# sourceMappingURL=chunk-QPNYDH5B.js.map
|