@wrongstack/tools 0.9.19 → 0.10.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 +2 -2
- package/dist/audit.js.map +1 -1
- package/dist/bash.js +86 -19
- package/dist/bash.js.map +1 -1
- package/dist/batch-tool-use.js +2 -2
- package/dist/batch-tool-use.js.map +1 -1
- package/dist/builtin.js +386 -171
- package/dist/builtin.js.map +1 -1
- package/dist/circuit-breaker.d.ts +0 -2
- package/dist/circuit-breaker.js +0 -3
- package/dist/circuit-breaker.js.map +1 -1
- package/dist/codebase-index/index.d.ts +26 -6
- package/dist/codebase-index/index.js +34 -25
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/{codebase-stats-tool-BLhQmPNc.d.ts → codebase-stats-tool-C8ApERbn.d.ts} +0 -11
- package/dist/diff.js +28 -13
- package/dist/diff.js.map +1 -1
- package/dist/document.js +4 -4
- package/dist/document.js.map +1 -1
- package/dist/edit.js +3 -2
- package/dist/edit.js.map +1 -1
- package/dist/exec.js +96 -15
- package/dist/exec.js.map +1 -1
- package/dist/fetch.js +13 -6
- package/dist/fetch.js.map +1 -1
- package/dist/format.js +74 -4
- package/dist/format.js.map +1 -1
- package/dist/git.js +81 -8
- package/dist/git.js.map +1 -1
- package/dist/glob.js +15 -5
- package/dist/glob.js.map +1 -1
- package/dist/grep.js +32 -9
- package/dist/grep.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +404 -182
- package/dist/index.js.map +1 -1
- package/dist/install.js +85 -8
- package/dist/install.js.map +1 -1
- package/dist/json.js +2 -2
- package/dist/json.js.map +1 -1
- package/dist/lint.js +74 -4
- package/dist/lint.js.map +1 -1
- package/dist/logs.js +6 -2
- package/dist/logs.js.map +1 -1
- package/dist/memory.js +13 -6
- package/dist/memory.js.map +1 -1
- package/dist/mode.js +4 -4
- package/dist/mode.js.map +1 -1
- package/dist/outdated.js +2 -2
- package/dist/outdated.js.map +1 -1
- package/dist/pack.js +387 -172
- package/dist/pack.js.map +1 -1
- package/dist/patch.js +3 -2
- package/dist/patch.js.map +1 -1
- package/dist/process-registry.js +0 -3
- package/dist/process-registry.js.map +1 -1
- package/dist/read.js +16 -5
- package/dist/read.js.map +1 -1
- package/dist/replace.js +3 -3
- package/dist/replace.js.map +1 -1
- package/dist/scaffold.js +3 -2
- package/dist/scaffold.js.map +1 -1
- package/dist/search.js +3 -2
- package/dist/search.js.map +1 -1
- package/dist/test.js +74 -4
- package/dist/test.js.map +1 -1
- package/dist/todo.js +21 -7
- package/dist/todo.js.map +1 -1
- package/dist/tool-help.js +5 -5
- package/dist/tool-help.js.map +1 -1
- package/dist/tool-search.js +2 -2
- package/dist/tool-search.js.map +1 -1
- package/dist/tool-use.js +4 -4
- package/dist/tool-use.js.map +1 -1
- package/dist/tree.js +16 -8
- package/dist/tree.js.map +1 -1
- package/dist/typecheck.js +74 -4
- package/dist/typecheck.js.map +1 -1
- package/dist/write.js +11 -4
- package/dist/write.js.map +1 -1
- package/package.json +2 -2
package/dist/pack.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn, execFileSync, spawnSync } from 'node:child_process';
|
|
2
|
-
import { buildChildEnv,
|
|
2
|
+
import { buildChildEnv, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, compileGlob, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, stripAnsi, resolveWstackPaths } from '@wrongstack/core';
|
|
3
3
|
import * as fs11 from 'node:fs/promises';
|
|
4
4
|
import { stat } from 'node:fs/promises';
|
|
5
5
|
import * as path from 'node:path';
|
|
@@ -156,13 +156,83 @@ function isBinaryBuffer(buf) {
|
|
|
156
156
|
}
|
|
157
157
|
return false;
|
|
158
158
|
}
|
|
159
|
+
var COMMAND_OUTPUT_MAX_BYTES = 32768;
|
|
160
|
+
var REPEAT_RUN_THRESHOLD = 3;
|
|
161
|
+
function collapseCarriageReturns(text) {
|
|
162
|
+
const lf = text.replace(/\r\n/g, "\n");
|
|
163
|
+
if (!lf.includes("\r")) return lf;
|
|
164
|
+
return lf.split("\n").map((line) => line.includes("\r") ? line.slice(line.lastIndexOf("\r") + 1) : line).join("\n");
|
|
165
|
+
}
|
|
166
|
+
function collapseConsecutiveDuplicates(text, minRun = REPEAT_RUN_THRESHOLD) {
|
|
167
|
+
const lines = text.split("\n");
|
|
168
|
+
const out = [];
|
|
169
|
+
let i = 0;
|
|
170
|
+
while (i < lines.length) {
|
|
171
|
+
let j = i + 1;
|
|
172
|
+
while (j < lines.length && lines[j] === lines[i]) j++;
|
|
173
|
+
const run = j - i;
|
|
174
|
+
if (run >= minRun) {
|
|
175
|
+
out.push(lines[i], `\u2026 \u27E8repeated ${run}\xD7\u27E9`);
|
|
176
|
+
} else {
|
|
177
|
+
for (let k = i; k < j; k++) out.push(lines[k]);
|
|
178
|
+
}
|
|
179
|
+
i = j;
|
|
180
|
+
}
|
|
181
|
+
return out.join("\n");
|
|
182
|
+
}
|
|
183
|
+
function takeHeadBytes(s, maxBytes) {
|
|
184
|
+
if (maxBytes <= 0) return "";
|
|
185
|
+
if (Buffer.byteLength(s, "utf8") <= maxBytes) return s;
|
|
186
|
+
let lo = 0;
|
|
187
|
+
let hi = s.length;
|
|
188
|
+
while (lo < hi) {
|
|
189
|
+
const mid = Math.ceil((lo + hi) / 2);
|
|
190
|
+
if (Buffer.byteLength(s.slice(0, mid), "utf8") <= maxBytes) lo = mid;
|
|
191
|
+
else hi = mid - 1;
|
|
192
|
+
}
|
|
193
|
+
return s.slice(0, lo);
|
|
194
|
+
}
|
|
195
|
+
function takeTailBytes(s, maxBytes) {
|
|
196
|
+
if (maxBytes <= 0) return "";
|
|
197
|
+
if (Buffer.byteLength(s, "utf8") <= maxBytes) return s;
|
|
198
|
+
let lo = 0;
|
|
199
|
+
let hi = s.length;
|
|
200
|
+
while (lo < hi) {
|
|
201
|
+
const mid = Math.ceil((lo + hi) / 2);
|
|
202
|
+
if (Buffer.byteLength(s.slice(s.length - mid), "utf8") <= maxBytes) lo = mid;
|
|
203
|
+
else hi = mid - 1;
|
|
204
|
+
}
|
|
205
|
+
return s.slice(s.length - lo);
|
|
206
|
+
}
|
|
207
|
+
function truncateHeadTail(s, maxBytes) {
|
|
208
|
+
const total = Buffer.byteLength(s, "utf8");
|
|
209
|
+
if (total <= maxBytes) return s;
|
|
210
|
+
const MARKER_RESERVE = 64;
|
|
211
|
+
const avail = Math.max(0, maxBytes - MARKER_RESERVE);
|
|
212
|
+
const headBudget = Math.floor(avail * 0.45);
|
|
213
|
+
const head = takeHeadBytes(s, headBudget);
|
|
214
|
+
const tail = takeTailBytes(s, avail - Buffer.byteLength(head, "utf8"));
|
|
215
|
+
const kept = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
|
|
216
|
+
return `${head}
|
|
217
|
+
\u2026[truncated ${total - kept} bytes]\u2026
|
|
218
|
+
${tail}`;
|
|
219
|
+
}
|
|
220
|
+
function normalizeCommandOutput(raw, opts = {}) {
|
|
221
|
+
if (!raw) return raw;
|
|
222
|
+
let text = stripAnsi(raw);
|
|
223
|
+
text = collapseCarriageReturns(text);
|
|
224
|
+
text = text.replace(/[ \t]+$/gm, "");
|
|
225
|
+
text = collapseConsecutiveDuplicates(text);
|
|
226
|
+
text = text.replace(/\n{3,}/g, "\n\n");
|
|
227
|
+
return truncateHeadTail(text, opts.maxBytes ?? COMMAND_OUTPUT_MAX_BYTES);
|
|
228
|
+
}
|
|
159
229
|
|
|
160
230
|
// src/audit.ts
|
|
161
231
|
var auditTool = {
|
|
162
232
|
name: "audit",
|
|
163
233
|
category: "Package Management",
|
|
164
|
-
description: "Run
|
|
165
|
-
usageHint: "
|
|
234
|
+
description: "Run a security audit against project dependencies (using pnpm/npm audit). Reports known vulnerabilities with severity.",
|
|
235
|
+
usageHint: "CRITICAL SECURITY TOOL:\n\n- Run regularly and especially before any release.\n- Use `level` to focus on high/critical issues.\n- `fix` can attempt automatic remediation for some vulnerabilities.\nThis is one of the most important tools for supply chain security.",
|
|
166
236
|
permission: "confirm",
|
|
167
237
|
mutating: false,
|
|
168
238
|
timeoutMs: 6e4,
|
|
@@ -288,8 +358,6 @@ var CircuitBreaker = class {
|
|
|
288
358
|
lastSlowAt = null;
|
|
289
359
|
/** Timestamp when the breaker was opened (for cooldown calculation). */
|
|
290
360
|
openedAt = null;
|
|
291
|
-
/** Timestamp when the last call ran (for half-open gate). */
|
|
292
|
-
lastCallAt = null;
|
|
293
361
|
constructor(config = {}) {
|
|
294
362
|
this.maxConsecutiveFailures = config.maxConsecutiveFailures ?? DEFAULT_MAX_CONSECUTIVE_FAILURES;
|
|
295
363
|
this.slowCallThresholdMs = config.slowCallThresholdMs ?? DEFAULT_SLOW_CALL_THRESHOLD_MS;
|
|
@@ -347,7 +415,6 @@ var CircuitBreaker = class {
|
|
|
347
415
|
*/
|
|
348
416
|
afterCall(durationMs, failed) {
|
|
349
417
|
const now = Date.now();
|
|
350
|
-
this.lastCallAt = now;
|
|
351
418
|
if (this.state === "half-open") {
|
|
352
419
|
if (failed) {
|
|
353
420
|
this._trip();
|
|
@@ -621,23 +688,33 @@ var STREAM_FLUSH_BYTES = 4 * 1024;
|
|
|
621
688
|
var bashTool = {
|
|
622
689
|
name: "bash",
|
|
623
690
|
category: "Shell",
|
|
624
|
-
description: "
|
|
625
|
-
usageHint: "
|
|
691
|
+
description: "Execute an arbitrary command in the user's default shell (bash/zsh/pwsh/cmd). stdout and stderr are merged into one stream. This is the most powerful and dangerous tool \u2014 it gives the model full access to the developer's machine. Prefer specialized tools whenever possible.",
|
|
692
|
+
usageHint: "SECURITY WARNING: This tool runs with the full privileges of the current user.\n\nBest practices for the model:\n- Strongly prefer `exec` for known safe commands (node, npm, pnpm, tsc, git, etc.).\n- Use bash only when you genuinely need shell features (pipes, redirection, complex one-liners).\n- Prefer single focused commands over huge `&&` chains.\n- Use `background: true` only for long-running processes (dev servers, watchers).\n- The working directory is the project root.\n- Output may be truncated in the middle for very large results.",
|
|
626
693
|
permission: "confirm",
|
|
627
694
|
mutating: true,
|
|
628
695
|
// Trust rules match on the literal `command` string. Without subjectKey
|
|
629
696
|
// the policy heuristic would have done the same here, but declaring it
|
|
630
697
|
// explicitly removes the implicit cross-tool aliasing.
|
|
631
698
|
subjectKey: "command",
|
|
699
|
+
capabilities: ["shell.arbitrary"],
|
|
632
700
|
timeoutMs: 3e4,
|
|
633
701
|
maxOutputBytes: MAX_OUTPUT,
|
|
634
702
|
estimatedDurationMs: 3e3,
|
|
635
703
|
inputSchema: {
|
|
636
704
|
type: "object",
|
|
637
705
|
properties: {
|
|
638
|
-
command: {
|
|
639
|
-
|
|
640
|
-
|
|
706
|
+
command: {
|
|
707
|
+
type: "string",
|
|
708
|
+
description: "The exact shell command to run. Prefer simple, focused commands."
|
|
709
|
+
},
|
|
710
|
+
timeout_ms: {
|
|
711
|
+
type: "integer",
|
|
712
|
+
description: "Optional timeout for this specific command in milliseconds."
|
|
713
|
+
},
|
|
714
|
+
background: {
|
|
715
|
+
type: "boolean",
|
|
716
|
+
description: "If true, launch the process in the background and return the PID immediately."
|
|
717
|
+
}
|
|
641
718
|
},
|
|
642
719
|
required: ["command"]
|
|
643
720
|
},
|
|
@@ -719,7 +796,7 @@ var bashTool = {
|
|
|
719
796
|
yield {
|
|
720
797
|
type: "final",
|
|
721
798
|
output: {
|
|
722
|
-
output:
|
|
799
|
+
output: normalizeCommandOutput(buf2),
|
|
723
800
|
exit_code: null,
|
|
724
801
|
timed_out: false,
|
|
725
802
|
pid: pid2
|
|
@@ -846,11 +923,10 @@ var bashTool = {
|
|
|
846
923
|
if (remainder !== null) {
|
|
847
924
|
yield { type: "partial_output", text: remainder };
|
|
848
925
|
}
|
|
849
|
-
const cleaned = stripAnsi(buf).replace(/\r\n?/g, "\n");
|
|
850
926
|
yield {
|
|
851
927
|
type: "final",
|
|
852
928
|
output: {
|
|
853
|
-
output:
|
|
929
|
+
output: normalizeCommandOutput(buf),
|
|
854
930
|
exit_code: c.code,
|
|
855
931
|
timed_out: timedOut
|
|
856
932
|
}
|
|
@@ -873,8 +949,8 @@ var bashTool = {
|
|
|
873
949
|
var batchToolUseTool = {
|
|
874
950
|
name: "batch_tool_use",
|
|
875
951
|
category: "Meta",
|
|
876
|
-
description: "Execute
|
|
877
|
-
usageHint: "
|
|
952
|
+
description: "Execute a batch of tool calls either sequentially or in parallel. Returns structured results for every call.",
|
|
953
|
+
usageHint: "ADVANCED / POWER USER TOOL:\n\n- Useful when you have a clear list of independent operations to perform.\n- `parallel: true` (default) runs them concurrently for speed.\n- `stop_on_error: true` makes it fail fast on the first error.\nUse with care \u2014 batching many mutating operations can be risky. Prefer explicit sequential steps for important work.",
|
|
878
954
|
permission: "confirm",
|
|
879
955
|
mutating: true,
|
|
880
956
|
timeoutMs: 12e4,
|
|
@@ -1010,8 +1086,14 @@ function lspKindToInternalKind(k) {
|
|
|
1010
1086
|
}
|
|
1011
1087
|
|
|
1012
1088
|
// src/codebase-index/writer.ts
|
|
1013
|
-
var INDEX_DIR = ".codebase-index";
|
|
1014
1089
|
var DB_FILE = "index.db";
|
|
1090
|
+
function resolveIndexDir(projectRoot, override) {
|
|
1091
|
+
return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
|
|
1092
|
+
}
|
|
1093
|
+
function codebaseIndexDirOverride(ctx) {
|
|
1094
|
+
const v = ctx.meta?.["codebaseIndexDir"];
|
|
1095
|
+
return typeof v === "string" ? v : void 0;
|
|
1096
|
+
}
|
|
1015
1097
|
var warningSilenced = false;
|
|
1016
1098
|
function silenceSqliteExperimentalWarning() {
|
|
1017
1099
|
if (warningSilenced) return;
|
|
@@ -1039,16 +1121,16 @@ function loadDatabaseSync() {
|
|
|
1039
1121
|
return DatabaseSyncCtor;
|
|
1040
1122
|
}
|
|
1041
1123
|
var IndexStore = class {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1124
|
+
db;
|
|
1125
|
+
/** Absolute path to this project's index directory. */
|
|
1126
|
+
indexDir;
|
|
1127
|
+
constructor(projectRoot, opts = {}) {
|
|
1128
|
+
this.indexDir = resolveIndexDir(projectRoot, opts.indexDir);
|
|
1129
|
+
fs.mkdirSync(this.indexDir, { recursive: true });
|
|
1046
1130
|
const Database = loadDatabaseSync();
|
|
1047
|
-
this.db = new Database(path.join(
|
|
1131
|
+
this.db = new Database(path.join(this.indexDir, DB_FILE));
|
|
1048
1132
|
this.initSchema();
|
|
1049
1133
|
}
|
|
1050
|
-
projectRoot;
|
|
1051
|
-
db;
|
|
1052
1134
|
initSchema() {
|
|
1053
1135
|
this.db.exec(`
|
|
1054
1136
|
CREATE TABLE IF NOT EXISTS metadata (
|
|
@@ -1239,7 +1321,7 @@ var IndexStore = class {
|
|
|
1239
1321
|
totalFiles,
|
|
1240
1322
|
byLang,
|
|
1241
1323
|
byKind,
|
|
1242
|
-
indexPath:
|
|
1324
|
+
indexPath: this.indexDir,
|
|
1243
1325
|
lastIndexed,
|
|
1244
1326
|
sizeBytes,
|
|
1245
1327
|
version: SCHEMA_VERSION
|
|
@@ -1332,7 +1414,7 @@ var IndexStore = class {
|
|
|
1332
1414
|
}));
|
|
1333
1415
|
}
|
|
1334
1416
|
sizeBytes() {
|
|
1335
|
-
const dbPath = path.join(this.
|
|
1417
|
+
const dbPath = path.join(this.indexDir, DB_FILE);
|
|
1336
1418
|
try {
|
|
1337
1419
|
return fs.statSync(dbPath).size;
|
|
1338
1420
|
} catch {
|
|
@@ -2142,7 +2224,7 @@ function regexParse(opts) {
|
|
|
2142
2224
|
}
|
|
2143
2225
|
return lo + 1;
|
|
2144
2226
|
}
|
|
2145
|
-
function extractDeclaration(lineIdx,
|
|
2227
|
+
function extractDeclaration(lineIdx, _match) {
|
|
2146
2228
|
const line = lines[lineIdx] ?? "";
|
|
2147
2229
|
return line.trim().slice(0, 500);
|
|
2148
2230
|
}
|
|
@@ -2607,9 +2689,9 @@ async function parseFile(file, content, lang) {
|
|
|
2607
2689
|
return { file, lang, symbols: [], mtimeMs: Date.now() };
|
|
2608
2690
|
}
|
|
2609
2691
|
}
|
|
2610
|
-
async function runIndexer(
|
|
2611
|
-
const { projectRoot, force = false, langs, ignore = [] } = opts;
|
|
2612
|
-
const store = new IndexStore(projectRoot);
|
|
2692
|
+
async function runIndexer(_ctx, opts) {
|
|
2693
|
+
const { projectRoot, force = false, langs, ignore = [], indexDir } = opts;
|
|
2694
|
+
const store = new IndexStore(projectRoot, { indexDir });
|
|
2613
2695
|
const startMs = Date.now();
|
|
2614
2696
|
const errors = [];
|
|
2615
2697
|
const langStats = {};
|
|
@@ -2726,8 +2808,8 @@ async function runIndexer(ctx, opts) {
|
|
|
2726
2808
|
var codebaseIndexTool = {
|
|
2727
2809
|
name: "codebase-index",
|
|
2728
2810
|
category: "Project",
|
|
2729
|
-
description: "Build or update the symbol index
|
|
2730
|
-
usageHint: "
|
|
2811
|
+
description: "Build or incrementally update the project-wide symbol index. This powers fast codebase search and understanding. By default it only processes files that have changed since the last indexing run.",
|
|
2812
|
+
usageHint: "IMPORTANT FOR LARGE CODEBASES:\n\n- First run (or after major changes): consider `force: true` for a clean rebuild.\n- Normal usage: call without arguments for fast incremental updates.\n- Use `langs` to restrict to specific languages if you only care about certain parts of the project.\nThis tool is relatively expensive \u2014 do not call it on every turn. Use it when the index is stale or before heavy codebase-search sessions.",
|
|
2731
2813
|
permission: "auto",
|
|
2732
2814
|
mutating: true,
|
|
2733
2815
|
timeoutMs: 12e4,
|
|
@@ -2749,7 +2831,8 @@ var codebaseIndexTool = {
|
|
|
2749
2831
|
const result = await runIndexer(ctx, {
|
|
2750
2832
|
projectRoot: ctx.projectRoot,
|
|
2751
2833
|
force: input.force ?? false,
|
|
2752
|
-
langs: input.langs
|
|
2834
|
+
langs: input.langs,
|
|
2835
|
+
indexDir: codebaseIndexDirOverride(ctx)
|
|
2753
2836
|
});
|
|
2754
2837
|
return result;
|
|
2755
2838
|
}
|
|
@@ -2847,10 +2930,11 @@ var Bm25Index = class {
|
|
|
2847
2930
|
var codebaseSearchTool = {
|
|
2848
2931
|
name: "codebase-search",
|
|
2849
2932
|
category: "Project",
|
|
2850
|
-
description: "
|
|
2851
|
-
usageHint: "
|
|
2933
|
+
description: "Semantic/keyword search over the indexed codebase symbols (functions, classes, interfaces, etc.). Uses BM25 ranking. Much more powerful and structured than raw `grep` for finding code by name or concept.",
|
|
2934
|
+
usageHint: "PREFERRED FOR CODE UNDERSTANDING:\n\n- Use when you need to find where something is defined or used by name.\n- `kind` filter is very useful (e.g. only functions or only interfaces).\n- Combine with `file` filter to scope to a specific directory or module.\nThis is generally better than `grep` when you are looking for symbols rather than arbitrary text patterns.",
|
|
2852
2935
|
permission: "auto",
|
|
2853
2936
|
mutating: false,
|
|
2937
|
+
capabilities: ["fs.read"],
|
|
2854
2938
|
timeoutMs: 1e4,
|
|
2855
2939
|
inputSchema: {
|
|
2856
2940
|
type: "object",
|
|
@@ -2885,7 +2969,7 @@ var codebaseSearchTool = {
|
|
|
2885
2969
|
required: ["query"]
|
|
2886
2970
|
},
|
|
2887
2971
|
async execute(input, ctx) {
|
|
2888
|
-
const store = new IndexStore(ctx.projectRoot);
|
|
2972
|
+
const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
2889
2973
|
try {
|
|
2890
2974
|
const limit = Math.min(input.limit ?? 20, 100);
|
|
2891
2975
|
const candidates = store.search(input.query, {
|
|
@@ -2930,10 +3014,11 @@ var codebaseSearchTool = {
|
|
|
2930
3014
|
var codebaseStatsTool = {
|
|
2931
3015
|
name: "codebase-stats",
|
|
2932
3016
|
category: "Project",
|
|
2933
|
-
description: "Return statistics about the symbol index
|
|
2934
|
-
usageHint: "
|
|
3017
|
+
description: "Return health and statistics about the current symbol index (total symbols, files, language/kind breakdown, size, last update). Useful to decide whether to re-index.",
|
|
3018
|
+
usageHint: "CALL BEFORE HEAVY CODEBASE-SEARCH WORK:\n\n- Use to see if the index is up-to-date or needs a refresh.\n- No arguments required.\n- Helps avoid wasting tokens on searches against a stale index.\nLightweight and safe to call frequently.",
|
|
2935
3019
|
permission: "auto",
|
|
2936
3020
|
mutating: false,
|
|
3021
|
+
capabilities: ["fs.read"],
|
|
2937
3022
|
timeoutMs: 5e3,
|
|
2938
3023
|
inputSchema: {
|
|
2939
3024
|
type: "object",
|
|
@@ -2941,7 +3026,7 @@ var codebaseStatsTool = {
|
|
|
2941
3026
|
additionalProperties: false
|
|
2942
3027
|
},
|
|
2943
3028
|
async execute(_input, ctx) {
|
|
2944
|
-
const store = new IndexStore(ctx.projectRoot);
|
|
3029
|
+
const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
2945
3030
|
try {
|
|
2946
3031
|
const stats = store.getStats();
|
|
2947
3032
|
return {
|
|
@@ -2962,28 +3047,44 @@ var codebaseStatsTool = {
|
|
|
2962
3047
|
var diffTool = {
|
|
2963
3048
|
name: "diff",
|
|
2964
3049
|
category: "Filesystem",
|
|
2965
|
-
description: "Show differences between files, commits, or
|
|
2966
|
-
usageHint:
|
|
3050
|
+
description: "Show code differences between files, commits, branches, or staged changes. A safer and more structured alternative to raw `git diff` via shell.",
|
|
3051
|
+
usageHint: 'USE FOR CODE REVIEW AND CHANGE INSPECTION:\n\n- `files` + no `a`/`b` \u2192 diff working tree vs HEAD for those files.\n- `a` and/or `b` \u2192 git-style commit/branch diff.\n- `staged: true` \u2192 only show staged changes.\n- `mode` can be "unified", "stat", or "side-by-side".\nThis tool has important safety guards against flag injection (see previous security findings).',
|
|
2967
3052
|
permission: "auto",
|
|
2968
3053
|
mutating: false,
|
|
3054
|
+
capabilities: ["fs.read"],
|
|
2969
3055
|
timeoutMs: 1e4,
|
|
2970
3056
|
inputSchema: {
|
|
2971
3057
|
type: "object",
|
|
2972
3058
|
properties: {
|
|
2973
|
-
path: {
|
|
3059
|
+
path: {
|
|
3060
|
+
type: "string",
|
|
3061
|
+
description: "Working directory for the diff operation (defaults to project root)."
|
|
3062
|
+
},
|
|
2974
3063
|
files: {
|
|
2975
3064
|
type: "string",
|
|
2976
|
-
description: '
|
|
3065
|
+
description: 'Files or globs to diff (e.g. "src/**/*.ts" or comma-separated list).'
|
|
3066
|
+
},
|
|
3067
|
+
a: {
|
|
3068
|
+
type: "string",
|
|
3069
|
+
description: "First ref/commit/branch for git diff (e.g. HEAD, main, a commit hash)."
|
|
3070
|
+
},
|
|
3071
|
+
b: {
|
|
3072
|
+
type: "string",
|
|
3073
|
+
description: "Second ref/commit/branch for git diff."
|
|
3074
|
+
},
|
|
3075
|
+
staged: {
|
|
3076
|
+
type: "boolean",
|
|
3077
|
+
description: "If true, only show changes that are staged in git."
|
|
2977
3078
|
},
|
|
2978
|
-
a: { type: "string", description: "First commit/branch/ref (for git diff)" },
|
|
2979
|
-
b: { type: "string", description: "Second commit/branch/ref (for git diff)" },
|
|
2980
|
-
staged: { type: "boolean", description: "Diff staged changes only" },
|
|
2981
3079
|
mode: {
|
|
2982
3080
|
type: "string",
|
|
2983
3081
|
enum: ["unified", "side-by-side", "stat"],
|
|
2984
|
-
description:
|
|
3082
|
+
description: 'Output format. "unified" is default, "stat" shows summary only.'
|
|
2985
3083
|
},
|
|
2986
|
-
context: {
|
|
3084
|
+
context: {
|
|
3085
|
+
type: "integer",
|
|
3086
|
+
description: "Number of context lines for unified diffs (default: 3)."
|
|
3087
|
+
}
|
|
2987
3088
|
}
|
|
2988
3089
|
},
|
|
2989
3090
|
async execute(input, ctx, opts) {
|
|
@@ -3054,8 +3155,7 @@ function runGit(args, cwd, signal) {
|
|
|
3054
3155
|
child.on("error", (e) => resolve7({ stdout: "", stderr: e.message, exitCode: 1 }));
|
|
3055
3156
|
});
|
|
3056
3157
|
}
|
|
3057
|
-
async function fileDiff(input, ctx,
|
|
3058
|
-
input.path ? safeResolve(input.path, ctx) : ctx.cwd;
|
|
3158
|
+
async function fileDiff(input, ctx, _signal) {
|
|
3059
3159
|
input.context ?? 3;
|
|
3060
3160
|
const files = input.files ? (Array.isArray(input.files) ? input.files : input.files.split(",")).map((f) => f.trim()).filter(Boolean) : [];
|
|
3061
3161
|
if (files.length === 0) {
|
|
@@ -3084,14 +3184,14 @@ ${formatUnified(lines)}`);
|
|
|
3084
3184
|
mode: input.mode ?? "unified"
|
|
3085
3185
|
};
|
|
3086
3186
|
}
|
|
3087
|
-
function formatUnified(lines,
|
|
3088
|
-
return lines.map((line,
|
|
3187
|
+
function formatUnified(lines, _context) {
|
|
3188
|
+
return lines.map((line, _i) => ` ${line}`).join("\n");
|
|
3089
3189
|
}
|
|
3090
3190
|
var documentTool = {
|
|
3091
3191
|
name: "document",
|
|
3092
3192
|
category: "Project",
|
|
3093
|
-
description: "
|
|
3094
|
-
usageHint: "
|
|
3193
|
+
description: "Automatically generate or update documentation comments (JSDoc/TSDoc style) for code. Can target specific symbols or entire files/directories.",
|
|
3194
|
+
usageHint: "USE FOR IMPROVING CODE DOCUMENTATION:\n\n- Good for adding missing docs to public APIs or complex functions.\n- `overwrite: true` will replace existing documentation (use carefully).\n- You can target specific symbols via `target` or whole files/directories via `files`.\nAlways review the generated documentation before committing \u2014 the model can hallucinate details.",
|
|
3095
3195
|
permission: "confirm",
|
|
3096
3196
|
mutating: true,
|
|
3097
3197
|
timeoutMs: 3e4,
|
|
@@ -3175,9 +3275,8 @@ async function resolveFiles(filesInput, cwd) {
|
|
|
3175
3275
|
}
|
|
3176
3276
|
return resolved;
|
|
3177
3277
|
}
|
|
3178
|
-
function processFile(content, absPath,
|
|
3278
|
+
function processFile(content, absPath, _style, _overwrite, target) {
|
|
3179
3279
|
const results = [];
|
|
3180
|
-
content.split("\n");
|
|
3181
3280
|
const functionRegex = /(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)/g;
|
|
3182
3281
|
const arrowRegex = /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>/g;
|
|
3183
3282
|
const classRegex = /class\s+(\w+)/g;
|
|
@@ -3239,10 +3338,11 @@ function processFile(content, absPath, style, overwrite, target) {
|
|
|
3239
3338
|
var editTool = {
|
|
3240
3339
|
name: "edit",
|
|
3241
3340
|
category: "Filesystem",
|
|
3242
|
-
description: "
|
|
3243
|
-
usageHint: "
|
|
3341
|
+
description: "Perform a precise, surgical text replacement in a file. This is the preferred tool for modifying existing code. It requires that you have previously called `read` on the file in the current session. Fails safely if the `old_string` appears more than once unless `replace_all` is set.",
|
|
3342
|
+
usageHint: "MANDATORY WORKFLOW:\n1. Call `read` on the target file first (in the same conversation).\n2. Use a sufficiently unique `old_string` (include surrounding lines/context if needed).\n3. If the string appears multiple times and you want to change all of them, set `replace_all: true`.\n4. `new_string` must be the exact replacement text.\n\nThis tool is much safer than `write` for existing files because it works against the last-read version.",
|
|
3244
3343
|
permission: "confirm",
|
|
3245
3344
|
mutating: true,
|
|
3345
|
+
capabilities: ["fs.write"],
|
|
3246
3346
|
timeoutMs: 5e3,
|
|
3247
3347
|
inputSchema: {
|
|
3248
3348
|
type: "object",
|
|
@@ -3456,18 +3556,32 @@ function validateArgs(cmd, args) {
|
|
|
3456
3556
|
var execTool = {
|
|
3457
3557
|
name: "exec",
|
|
3458
3558
|
category: "Shell",
|
|
3459
|
-
description: "
|
|
3460
|
-
usageHint: "
|
|
3559
|
+
description: "Execute a **whitelisted, restricted set of commands** with strict argument validation. This is the **preferred and safer** alternative to the `bash` tool for running development tools (node, npm, pnpm, tsc, git, tests, linters, etc.). It prevents arbitrary command injection and limits what the model can do.",
|
|
3560
|
+
usageHint: "PREFERRED SHELL TOOL for most cases.\n\nUse this instead of `bash` whenever possible.\n- `command` must be one of the allowed commands (node, npm, pnpm, git, tsc, eslint, vitest, etc.).\n- Arguments are passed as a clean array (no shell interpretation).\n- `cwd` is validated to stay inside the project.\n- For anything that requires real shell features (pipes, complex redirection, arbitrary commands), fall back to `bash` (with strong justification).\nThis tool significantly reduces the risk compared to full shell access.",
|
|
3461
3561
|
permission: "confirm",
|
|
3462
3562
|
mutating: true,
|
|
3463
3563
|
timeoutMs: TIMEOUT_MS,
|
|
3564
|
+
capabilities: ["shell.restricted"],
|
|
3464
3565
|
inputSchema: {
|
|
3465
3566
|
type: "object",
|
|
3466
3567
|
properties: {
|
|
3467
|
-
command: {
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3568
|
+
command: {
|
|
3569
|
+
type: "string",
|
|
3570
|
+
description: 'The base command to run. Must be in the internal allowlist (e.g. "node", "pnpm", "git", "tsc").'
|
|
3571
|
+
},
|
|
3572
|
+
args: {
|
|
3573
|
+
type: "array",
|
|
3574
|
+
items: { type: "string" },
|
|
3575
|
+
description: "Arguments passed to the command. Passed as an array (no shell parsing)."
|
|
3576
|
+
},
|
|
3577
|
+
cwd: {
|
|
3578
|
+
type: "string",
|
|
3579
|
+
description: "Optional working directory. Must resolve inside the project root."
|
|
3580
|
+
},
|
|
3581
|
+
timeout: {
|
|
3582
|
+
type: "integer",
|
|
3583
|
+
description: "Per-command timeout in milliseconds."
|
|
3584
|
+
}
|
|
3471
3585
|
},
|
|
3472
3586
|
required: ["command"]
|
|
3473
3587
|
},
|
|
@@ -3576,10 +3690,10 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
|
3576
3690
|
resolve7({
|
|
3577
3691
|
command: cmd,
|
|
3578
3692
|
args,
|
|
3579
|
-
stdout: stdout
|
|
3580
|
-
stderr: stderr
|
|
3693
|
+
stdout: normalizeCommandOutput(stdout),
|
|
3694
|
+
stderr: normalizeCommandOutput(stderr),
|
|
3581
3695
|
exitCode,
|
|
3582
|
-
truncated: stdout
|
|
3696
|
+
truncated: Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES || Buffer.byteLength(stderr, "utf8") > COMMAND_OUTPUT_MAX_BYTES,
|
|
3583
3697
|
allowed: true
|
|
3584
3698
|
});
|
|
3585
3699
|
});
|
|
@@ -3590,10 +3704,10 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
|
3590
3704
|
resolve7({
|
|
3591
3705
|
command: cmd,
|
|
3592
3706
|
args,
|
|
3593
|
-
stdout: stdout
|
|
3707
|
+
stdout: normalizeCommandOutput(stdout),
|
|
3594
3708
|
stderr: err.message,
|
|
3595
3709
|
exitCode: 1,
|
|
3596
|
-
truncated:
|
|
3710
|
+
truncated: Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES,
|
|
3597
3711
|
allowed: true
|
|
3598
3712
|
});
|
|
3599
3713
|
});
|
|
@@ -3683,10 +3797,11 @@ async function guardedFetch(url, maxRedirects, signal, headers = {
|
|
|
3683
3797
|
var fetchTool = {
|
|
3684
3798
|
name: "fetch",
|
|
3685
3799
|
category: "Network",
|
|
3686
|
-
description: "Fetch
|
|
3687
|
-
usageHint: "HTTPS
|
|
3800
|
+
description: "Fetch a URL and return its content. HTML pages are automatically converted to clean markdown. This tool has strong SSRF protections (private IPs, localhost, and cloud metadata endpoints are blocked by default).",
|
|
3801
|
+
usageHint: "Use this when you need external information (documentation, API responses, web pages, etc.).\n\nSecurity notes:\n- Only HTTPS is allowed by default.\n- Internal/private networks are blocked unless explicitly enabled via environment variable.\n- Redirects are followed but re-validated at each hop.\n- Output is capped (128KB by default) to avoid flooding context.\nPrefer this over raw `bash curl` or `bash wget`.",
|
|
3688
3802
|
permission: "confirm",
|
|
3689
3803
|
mutating: false,
|
|
3804
|
+
capabilities: ["net.outbound"],
|
|
3690
3805
|
// Trust rules for fetch match on the literal URL — declare it explicitly
|
|
3691
3806
|
// so a user can trust `https://api.example.com/*` without accidentally
|
|
3692
3807
|
// matching that pattern on any other tool that happens to have a `url`
|
|
@@ -3697,8 +3812,15 @@ var fetchTool = {
|
|
|
3697
3812
|
inputSchema: {
|
|
3698
3813
|
type: "object",
|
|
3699
3814
|
properties: {
|
|
3700
|
-
url: {
|
|
3701
|
-
|
|
3815
|
+
url: {
|
|
3816
|
+
type: "string",
|
|
3817
|
+
description: "The target URL (must use https://)."
|
|
3818
|
+
},
|
|
3819
|
+
format: {
|
|
3820
|
+
type: "string",
|
|
3821
|
+
enum: ["markdown", "text", "raw"],
|
|
3822
|
+
description: 'Output format. "markdown" is recommended for HTML pages.'
|
|
3823
|
+
}
|
|
3702
3824
|
},
|
|
3703
3825
|
required: ["url"]
|
|
3704
3826
|
},
|
|
@@ -3935,8 +4057,8 @@ function stripTags(s) {
|
|
|
3935
4057
|
var formatTool = {
|
|
3936
4058
|
name: "format",
|
|
3937
4059
|
category: "Code Quality",
|
|
3938
|
-
description: "Format files
|
|
3939
|
-
usageHint: "
|
|
4060
|
+
description: "Format source files according to project style (Biome). Can also run in check-only mode.",
|
|
4061
|
+
usageHint: "RUN REGULARLY:\n\n- Use on changed files before committing.\n- `check: true` verifies formatting without making changes (useful in CI-like flows).\nThis project has very consistent formatting expectations. Always ensure your changes are formatted.",
|
|
3940
4062
|
permission: "confirm",
|
|
3941
4063
|
mutating: true,
|
|
3942
4064
|
timeoutMs: 6e4,
|
|
@@ -4009,7 +4131,7 @@ var formatTool = {
|
|
|
4009
4131
|
fixer: detected,
|
|
4010
4132
|
files_checked: 0,
|
|
4011
4133
|
files_changed: changed,
|
|
4012
|
-
output: result.stdout || result.stderr || result.error || "",
|
|
4134
|
+
output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ""),
|
|
4013
4135
|
truncated: result.truncated
|
|
4014
4136
|
}
|
|
4015
4137
|
};
|
|
@@ -4034,13 +4156,14 @@ var MAX_OUTPUT3 = 1e5;
|
|
|
4034
4156
|
var gitTool = {
|
|
4035
4157
|
name: "git",
|
|
4036
4158
|
category: "Git",
|
|
4037
|
-
description: "
|
|
4038
|
-
usageHint: "
|
|
4159
|
+
description: "Safe wrapper around common git operations. Supports status, log, diff, commit, branch, checkout, stash, push, pull, fetch, reset, worktree, etc. This is the preferred way to interact with git instead of using the raw `bash` or `exec` tools.",
|
|
4160
|
+
usageHint: "ALWAYS prefer this tool over raw shell git commands.\n\nKey fields:\n- `command`: one of the supported subcommands (status, log, diff, commit, etc.)\n- Use `message` only for commit operations.\n- Use `files` array for operations that take paths (status, diff, add, etc.).\n- Non-mutating commands (status, log, diff, branch, fetch) are still permission:confirm for safety.\nNever pass raw git flags through `args` for dangerous operations \u2014 use the structured fields.",
|
|
4039
4161
|
permission: "confirm",
|
|
4040
4162
|
// Conservative: any of these may mutate. The non-mutating commands
|
|
4041
4163
|
// (status/log/diff/branch/fetch) are still gated on `permission: 'confirm'`
|
|
4042
4164
|
// and `MUTATING_SUBCOMMANDS` is consulted at runtime for per-call checks.
|
|
4043
4165
|
mutating: true,
|
|
4166
|
+
capabilities: ["fs.write", "shell.restricted"],
|
|
4044
4167
|
timeoutMs: TIMEOUT_MS3,
|
|
4045
4168
|
inputSchema: {
|
|
4046
4169
|
type: "object",
|
|
@@ -4255,19 +4378,19 @@ function runGit2(args, cwd, signal) {
|
|
|
4255
4378
|
child.on("error", (err) => {
|
|
4256
4379
|
resolve7({
|
|
4257
4380
|
command: args[0],
|
|
4258
|
-
stdout,
|
|
4381
|
+
stdout: normalizeCommandOutput(stdout),
|
|
4259
4382
|
stderr: err.message,
|
|
4260
4383
|
exitCode: 1,
|
|
4261
|
-
truncated: stdout
|
|
4384
|
+
truncated: Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES
|
|
4262
4385
|
});
|
|
4263
4386
|
});
|
|
4264
4387
|
child.on("close", (code) => {
|
|
4265
4388
|
resolve7({
|
|
4266
4389
|
command: args[0],
|
|
4267
|
-
stdout: stdout
|
|
4268
|
-
stderr: stderr
|
|
4390
|
+
stdout: normalizeCommandOutput(stdout),
|
|
4391
|
+
stderr: normalizeCommandOutput(stderr),
|
|
4269
4392
|
exitCode: code ?? 1,
|
|
4270
|
-
truncated: stdout
|
|
4393
|
+
truncated: Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES || Buffer.byteLength(stderr, "utf8") > COMMAND_OUTPUT_MAX_BYTES
|
|
4271
4394
|
});
|
|
4272
4395
|
});
|
|
4273
4396
|
});
|
|
@@ -4276,18 +4399,28 @@ var DEFAULT_IGNORE2 = ["node_modules", ".git", "dist", "build", ".next", "covera
|
|
|
4276
4399
|
var globTool = {
|
|
4277
4400
|
name: "glob",
|
|
4278
4401
|
category: "Filesystem",
|
|
4279
|
-
description: "Find files matching a glob pattern.
|
|
4280
|
-
usageHint: "
|
|
4402
|
+
description: "Find files matching a glob pattern. Fast way to discover relevant files before reading, grepping, or editing them.",
|
|
4403
|
+
usageHint: "RECOMMENDED FOR SCOPING SEARCHES:\n\n- Use early to get a list of files you actually care about.\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.",
|
|
4281
4404
|
permission: "auto",
|
|
4282
4405
|
mutating: false,
|
|
4406
|
+
capabilities: ["fs.read"],
|
|
4283
4407
|
maxOutputBytes: 65536,
|
|
4284
4408
|
timeoutMs: 5e3,
|
|
4285
4409
|
inputSchema: {
|
|
4286
4410
|
type: "object",
|
|
4287
4411
|
properties: {
|
|
4288
|
-
pattern: {
|
|
4289
|
-
|
|
4290
|
-
|
|
4412
|
+
pattern: {
|
|
4413
|
+
type: "string",
|
|
4414
|
+
description: 'Glob pattern to match (e.g. "**/*.ts", "src/**").'
|
|
4415
|
+
},
|
|
4416
|
+
path: {
|
|
4417
|
+
type: "string",
|
|
4418
|
+
description: "Base directory to search from (defaults to project root)."
|
|
4419
|
+
},
|
|
4420
|
+
limit: {
|
|
4421
|
+
type: "integer",
|
|
4422
|
+
description: "Maximum number of results to return (default 1000, max 5000)."
|
|
4423
|
+
}
|
|
4291
4424
|
},
|
|
4292
4425
|
required: ["pattern"]
|
|
4293
4426
|
},
|
|
@@ -4398,22 +4531,45 @@ var DEFAULT_IGNORE3 = ["node_modules", ".git", "dist", "build", ".next", "covera
|
|
|
4398
4531
|
var grepTool = {
|
|
4399
4532
|
name: "grep",
|
|
4400
4533
|
category: "Search",
|
|
4401
|
-
description: "Search
|
|
4402
|
-
usageHint: '
|
|
4534
|
+
description: "Search across files using a regular expression. This is one of the primary code search tools. Prefers ripgrep for speed and features when available.",
|
|
4535
|
+
usageHint: 'POWERFUL CODE SEARCH TOOL:\n\n- `pattern` is a regular expression.\n- Use `output_mode: "content"` (default) to get matching lines with context.\n- Use `"files_with_matches"` when you only need the list of files.\n- Use `"count"` for quick statistics.\n- `glob` and `path` let you narrow the search scope significantly.\n- Always prefer this over `bash grep` when searching code.',
|
|
4403
4536
|
permission: "auto",
|
|
4404
4537
|
mutating: false,
|
|
4538
|
+
capabilities: ["fs.read"],
|
|
4405
4539
|
maxOutputBytes: 131072,
|
|
4406
4540
|
timeoutMs: 1e4,
|
|
4407
4541
|
inputSchema: {
|
|
4408
4542
|
type: "object",
|
|
4409
4543
|
properties: {
|
|
4410
|
-
pattern: {
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4544
|
+
pattern: {
|
|
4545
|
+
type: "string",
|
|
4546
|
+
description: "Regular expression pattern to search for in file contents."
|
|
4547
|
+
},
|
|
4548
|
+
path: {
|
|
4549
|
+
type: "string",
|
|
4550
|
+
description: "Limit search to this directory or file (relative to project root)."
|
|
4551
|
+
},
|
|
4552
|
+
glob: {
|
|
4553
|
+
type: "string",
|
|
4554
|
+
description: 'Glob filter for which files to include (e.g. "**/*.ts", "src/**").'
|
|
4555
|
+
},
|
|
4556
|
+
output_mode: {
|
|
4557
|
+
type: "string",
|
|
4558
|
+
enum: ["content", "files_with_matches", "count"],
|
|
4559
|
+
description: "Return style: detailed matches, just file list, or count only."
|
|
4560
|
+
},
|
|
4561
|
+
context_lines: {
|
|
4562
|
+
type: "integer",
|
|
4563
|
+
description: "How many lines of surrounding context to include with each match."
|
|
4564
|
+
},
|
|
4565
|
+
case_insensitive: {
|
|
4566
|
+
type: "boolean",
|
|
4567
|
+
description: "Ignore case when matching."
|
|
4568
|
+
},
|
|
4569
|
+
limit: {
|
|
4570
|
+
type: "integer",
|
|
4571
|
+
description: "Maximum number of matches to return."
|
|
4572
|
+
}
|
|
4417
4573
|
},
|
|
4418
4574
|
required: ["pattern"]
|
|
4419
4575
|
},
|
|
@@ -4661,11 +4817,12 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
4661
4817
|
var installTool = {
|
|
4662
4818
|
name: "install",
|
|
4663
4819
|
category: "Package Management",
|
|
4664
|
-
description: "Install
|
|
4665
|
-
usageHint: "
|
|
4820
|
+
description: "Install, update or manage packages using the detected package manager (pnpm/npm/yarn). Strongly preferred over raw shell commands for dependency management because it is structured and safer.",
|
|
4821
|
+
usageHint: "ALWAYS USE THIS INSTEAD OF BASH FOR PACKAGE WORK:\n\n- Empty `packages` \u2192 normal `install` (respects lockfile).\n- Provide names \u2192 adds/updates specific packages.\n- `dry_run: true` for safe preview.\n- Set `save` appropriately.\nThis tool has proper capability declaration and is heavily recommended in the security posture of the project.",
|
|
4666
4822
|
permission: "confirm",
|
|
4667
4823
|
mutating: true,
|
|
4668
4824
|
timeoutMs: 12e4,
|
|
4825
|
+
capabilities: ["package.install", "shell.restricted"],
|
|
4669
4826
|
inputSchema: {
|
|
4670
4827
|
type: "object",
|
|
4671
4828
|
properties: {
|
|
@@ -4676,14 +4833,20 @@ var installTool = {
|
|
|
4676
4833
|
save: {
|
|
4677
4834
|
type: "string",
|
|
4678
4835
|
enum: ["dependency", "dev", "optional"],
|
|
4679
|
-
description:
|
|
4836
|
+
description: 'Where to save the package(s): "dependency", "devDependencies", or "optionalDependencies".'
|
|
4837
|
+
},
|
|
4838
|
+
cwd: {
|
|
4839
|
+
type: "string",
|
|
4840
|
+
description: "Working directory for the install command (must stay inside project)."
|
|
4680
4841
|
},
|
|
4681
|
-
cwd: { type: "string", description: "Working directory (default: cwd)" },
|
|
4682
4842
|
dry_run: {
|
|
4683
4843
|
type: "boolean",
|
|
4684
|
-
description: "
|
|
4844
|
+
description: "If true, show what would be installed without actually modifying package.json or node_modules."
|
|
4685
4845
|
},
|
|
4686
|
-
global: {
|
|
4846
|
+
global: {
|
|
4847
|
+
type: "boolean",
|
|
4848
|
+
description: "Whether to perform a global install (use with caution)."
|
|
4849
|
+
}
|
|
4687
4850
|
}
|
|
4688
4851
|
},
|
|
4689
4852
|
async execute(input, ctx, opts) {
|
|
@@ -4747,7 +4910,7 @@ var installTool = {
|
|
|
4747
4910
|
output: {
|
|
4748
4911
|
packages: pkgList,
|
|
4749
4912
|
exit_code: result.exitCode,
|
|
4750
|
-
output: result.stdout || result.stderr || result.error || "",
|
|
4913
|
+
output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ""),
|
|
4751
4914
|
dry_run: args.includes("--dry-run"),
|
|
4752
4915
|
truncated: result.truncated
|
|
4753
4916
|
}
|
|
@@ -4771,8 +4934,8 @@ async function detectPackageManager(cwd) {
|
|
|
4771
4934
|
var jsonTool = {
|
|
4772
4935
|
name: "json",
|
|
4773
4936
|
category: "Data",
|
|
4774
|
-
description: "Parse, query, and
|
|
4775
|
-
usageHint:
|
|
4937
|
+
description: "Parse, pretty-print, query, and convert between JSON, JSON5, and YAML. Supports simple path-based queries.",
|
|
4938
|
+
usageHint: "VERY USEFUL FOR DATA INSPECTION:\n\n- Use on package.json, tsconfig, config files, or any structured data.\n- `query` lets you extract specific values without reading the whole file.\n- Great for validating that a file has the expected structure.\nPrefer this over raw `read` + manual parsing when dealing with configuration or data files.",
|
|
4776
4939
|
permission: "auto",
|
|
4777
4940
|
mutating: false,
|
|
4778
4941
|
timeoutMs: 5e3,
|
|
@@ -4894,8 +5057,8 @@ function toYaml(data, indent = 0) {
|
|
|
4894
5057
|
var lintTool = {
|
|
4895
5058
|
name: "lint",
|
|
4896
5059
|
category: "Code Quality",
|
|
4897
|
-
description: "Run
|
|
4898
|
-
usageHint: "
|
|
5060
|
+
description: "Run the project linter (primarily Biome in this repo). Detects style violations, potential bugs, and formatting issues.",
|
|
5061
|
+
usageHint: "RUN OFTEN DURING DEVELOPMENT:\n\n- `fix: true` will automatically correct what it can.\n- Target specific files or globs when you only want to check part of the project.\nThis is a fast and important quality gate. Use it before typecheck in most workflows.",
|
|
4899
5062
|
permission: "confirm",
|
|
4900
5063
|
mutating: false,
|
|
4901
5064
|
timeoutMs: 6e4,
|
|
@@ -4960,7 +5123,7 @@ var lintTool = {
|
|
|
4960
5123
|
files_checked: input.files ? Array.isArray(input.files) ? input.files.length : input.files.split(",").length : 0,
|
|
4961
5124
|
errors,
|
|
4962
5125
|
warnings,
|
|
4963
|
-
output: result.stdout,
|
|
5126
|
+
output: normalizeCommandOutput(result.stdout),
|
|
4964
5127
|
fix_applied: input.fix ?? false,
|
|
4965
5128
|
truncated: result.truncated
|
|
4966
5129
|
}
|
|
@@ -4984,8 +5147,8 @@ async function detectLinter(cwd) {
|
|
|
4984
5147
|
var logsTool = {
|
|
4985
5148
|
name: "logs",
|
|
4986
5149
|
category: "Logs",
|
|
4987
|
-
description: "
|
|
4988
|
-
usageHint: "
|
|
5150
|
+
description: "Read or stream logs from files, Docker containers, or systemd services. Useful for debugging running applications.",
|
|
5151
|
+
usageHint: "DEBUGGING TOOL \u2014 USE CAREFULLY IN AUTONOMOUS MODE:\n\n- Prefer `path` for local files or `service` for containers/systemd.\n- `stream: true` = live tail (can be expensive).\n- Always use `filter` (regex) when possible to reduce noise and token usage.\n- Long-running streams should be avoided unless the user explicitly wants live logs.",
|
|
4989
5152
|
permission: "confirm",
|
|
4990
5153
|
mutating: false,
|
|
4991
5154
|
timeoutMs: 3e4,
|
|
@@ -5090,6 +5253,10 @@ async function dockerLogs(service, lines, filterRe, cwd, signal, since) {
|
|
|
5090
5253
|
child.stderr?.on("data", (c) => {
|
|
5091
5254
|
if (stderr.length < MAX) stderr += c.toString();
|
|
5092
5255
|
});
|
|
5256
|
+
child.stdout?.on("error", () => {
|
|
5257
|
+
});
|
|
5258
|
+
child.stderr?.on("error", () => {
|
|
5259
|
+
});
|
|
5093
5260
|
child.on("close", () => {
|
|
5094
5261
|
const output = stdout + stderr;
|
|
5095
5262
|
const entries = parseLogLines(output, filterRe);
|
|
@@ -5181,8 +5348,8 @@ function parseLine(line) {
|
|
|
5181
5348
|
var outdatedTool = {
|
|
5182
5349
|
name: "outdated",
|
|
5183
5350
|
category: "Package Management",
|
|
5184
|
-
description: "Check for outdated
|
|
5185
|
-
usageHint: "
|
|
5351
|
+
description: "Check for outdated dependencies in the project. Reports current, wanted (semver range), and latest versions available.",
|
|
5352
|
+
usageHint: "MAINTENANCE & SECURITY TOOL:\n\n- Run periodically or before dependency-related work.\n- Helps surface packages that may need updates for security or features.\n- Safe, read-only operation.\nUse the output to decide on upgrades. Prefer this over manual shell commands for dependency hygiene.",
|
|
5186
5353
|
permission: "auto",
|
|
5187
5354
|
mutating: true,
|
|
5188
5355
|
timeoutMs: 6e4,
|
|
@@ -5291,10 +5458,11 @@ function parseOutdatedOutput(json, exitCode) {
|
|
|
5291
5458
|
var patchTool = {
|
|
5292
5459
|
name: "patch",
|
|
5293
5460
|
category: "Filesystem",
|
|
5294
|
-
description: "Apply a unified diff patch to
|
|
5295
|
-
usageHint: "
|
|
5461
|
+
description: "Apply a unified diff (patch) to the project. This is the correct tool when you have a diff that needs to be applied precisely, including handling of rejects.",
|
|
5462
|
+
usageHint: "Best used when you already have a diff (from generation, external source, or previous step).\n- Use `dry_run: true` to see what would happen without modifying files.\n- On failure it creates .rej and .orig files for manual review.\nOften cleaner than many small `edit` operations for larger changes.",
|
|
5296
5463
|
permission: "confirm",
|
|
5297
5464
|
mutating: true,
|
|
5465
|
+
capabilities: ["fs.write"],
|
|
5298
5466
|
timeoutMs: 3e4,
|
|
5299
5467
|
inputSchema: {
|
|
5300
5468
|
type: "object",
|
|
@@ -5400,8 +5568,8 @@ function extractPatchedFiles(output) {
|
|
|
5400
5568
|
var planTool = {
|
|
5401
5569
|
name: "plan",
|
|
5402
5570
|
category: "Session",
|
|
5403
|
-
description: "
|
|
5404
|
-
usageHint: '
|
|
5571
|
+
description: "Manage a persistent strategic plan for the current session. Unlike todos, plans are meant for higher-level, multi-phase approaches and survive across conversation resumptions. Use this to outline big-picture work, then promote concrete items into the todo list when ready to execute.",
|
|
5572
|
+
usageHint: 'RECOMMENDED FOR COMPLEX, MULTI-PHASE WORK:\n\n- Start by creating a high-level plan with `action: "add"` or using templates (`template_use`).\n- Use `promote` to turn a plan item into actionable todos.\n- Keep plans at the "why and what" level, and todos at the "how and next step" level.\n- Common templates: "new-feature", "bug-fix", "refactor", "release", "security-audit".\n\nThis tool is excellent for maintaining long-term direction across many turns or even multiple sessions.',
|
|
5405
5573
|
permission: "auto",
|
|
5406
5574
|
mutating: false,
|
|
5407
5575
|
timeoutMs: 2e3,
|
|
@@ -5410,22 +5578,29 @@ var planTool = {
|
|
|
5410
5578
|
properties: {
|
|
5411
5579
|
action: {
|
|
5412
5580
|
type: "string",
|
|
5413
|
-
enum: ["show", "add", "start", "done", "remove", "promote", "derive", "template_use", "clear"]
|
|
5581
|
+
enum: ["show", "add", "start", "done", "remove", "promote", "derive", "template_use", "clear"],
|
|
5582
|
+
description: "The operation to perform on the plan board."
|
|
5583
|
+
},
|
|
5584
|
+
title: {
|
|
5585
|
+
type: "string",
|
|
5586
|
+
description: "Title of the plan item. Required for action=add."
|
|
5587
|
+
},
|
|
5588
|
+
details: {
|
|
5589
|
+
type: "string",
|
|
5590
|
+
description: "Additional details or description for a new plan item (action=add)."
|
|
5414
5591
|
},
|
|
5415
|
-
title: { type: "string", description: "Required when action = add." },
|
|
5416
|
-
details: { type: "string", description: "Optional extra context for add." },
|
|
5417
5592
|
target: {
|
|
5418
5593
|
type: "string",
|
|
5419
|
-
description: "
|
|
5594
|
+
description: "Identifier for the target plan item (id, 1-based index, or partial title). Required for most actions except add/show/clear."
|
|
5420
5595
|
},
|
|
5421
5596
|
subtasks: {
|
|
5422
5597
|
type: "array",
|
|
5423
5598
|
items: { type: "string" },
|
|
5424
|
-
description: "
|
|
5599
|
+
description: "List of subtask titles. Used with promote or derive to break a plan item into multiple todos."
|
|
5425
5600
|
},
|
|
5426
5601
|
template: {
|
|
5427
5602
|
type: "string",
|
|
5428
|
-
description: "Template
|
|
5603
|
+
description: "Template identifier when using action=template_use. Common values: new-feature, bug-fix, refactor, release, security-audit."
|
|
5429
5604
|
}
|
|
5430
5605
|
},
|
|
5431
5606
|
required: ["action"]
|
|
@@ -5538,18 +5713,28 @@ var MAX_BYTES2 = 5 * 1024 * 1024;
|
|
|
5538
5713
|
var readTool = {
|
|
5539
5714
|
name: "read",
|
|
5540
5715
|
category: "Filesystem",
|
|
5541
|
-
description: "Read the contents of a file. Lines are 1-indexed
|
|
5542
|
-
usageHint: "
|
|
5716
|
+
description: "Read the contents of a file with line numbers. This is the primary way to inspect source code, configuration, or any text file before making changes. Lines are returned 1-indexed with a ` N| ` prefix for easy reference in edits.",
|
|
5717
|
+
usageHint: "FOUNDATIONAL TOOL \u2014 call this before almost any edit operation.\n\nBest practices:\n- Always read a file before using `edit`, `replace`, or `write` on it (the system often requires it for safety).\n- Use `offset` + `limit` for very large files instead of reading everything at once.\n- Default limit is generous (2000 lines) but can be increased.\n- The output format is designed to be directly usable as context for `edit` operations.",
|
|
5543
5718
|
permission: "auto",
|
|
5544
5719
|
mutating: false,
|
|
5720
|
+
capabilities: ["fs.read"],
|
|
5545
5721
|
maxOutputBytes: 262144,
|
|
5546
5722
|
timeoutMs: 5e3,
|
|
5547
5723
|
inputSchema: {
|
|
5548
5724
|
type: "object",
|
|
5549
5725
|
properties: {
|
|
5550
|
-
path: {
|
|
5551
|
-
|
|
5552
|
-
|
|
5726
|
+
path: {
|
|
5727
|
+
type: "string",
|
|
5728
|
+
description: "Path to the file (relative to project root or absolute within project)."
|
|
5729
|
+
},
|
|
5730
|
+
offset: {
|
|
5731
|
+
type: "integer",
|
|
5732
|
+
description: "1-based starting line number. Use together with `limit` for large files."
|
|
5733
|
+
},
|
|
5734
|
+
limit: {
|
|
5735
|
+
type: "integer",
|
|
5736
|
+
description: "Maximum number of lines to return (default is 2000)."
|
|
5737
|
+
}
|
|
5553
5738
|
},
|
|
5554
5739
|
required: ["path"]
|
|
5555
5740
|
},
|
|
@@ -5600,10 +5785,11 @@ var DEFAULT_IGNORE4 = ["node_modules", ".git", "dist", "build", ".next", "covera
|
|
|
5600
5785
|
var replaceTool = {
|
|
5601
5786
|
name: "replace",
|
|
5602
5787
|
category: "Transform",
|
|
5603
|
-
description: "
|
|
5604
|
-
usageHint:
|
|
5788
|
+
description: "Perform a search-and-replace across multiple files using a regex pattern. This is a powerful bulk transformation tool. Always use `dry_run: true` first on anything non-trivial.",
|
|
5789
|
+
usageHint: "DANGEROUS IF USED CARELESSLY \u2014 review the diff output carefully.\n\nRecommended workflow:\n1. Start with `dry_run: true` to see exactly what would change.\n2. Use a specific enough `pattern` (and `glob` / `files`) to avoid accidental broad changes.\n3. `replace_all` controls whether only the first match per file or all matches are replaced.\nThis tool is excellent for large-scale refactors (renaming, import updates, etc.) but must be used with caution.",
|
|
5605
5790
|
permission: "confirm",
|
|
5606
5791
|
mutating: true,
|
|
5792
|
+
capabilities: ["fs.write"],
|
|
5607
5793
|
timeoutMs: 3e4,
|
|
5608
5794
|
inputSchema: {
|
|
5609
5795
|
type: "object",
|
|
@@ -5719,7 +5905,6 @@ async function resolveFiles2(filesInput, ctx, extraGlob) {
|
|
|
5719
5905
|
return resolved;
|
|
5720
5906
|
}
|
|
5721
5907
|
async function globFiles(pattern, base, extraGlob) {
|
|
5722
|
-
const { spawn: spawn11 } = await import('node:child_process');
|
|
5723
5908
|
const rgAvailable = await checkRg();
|
|
5724
5909
|
if (rgAvailable) {
|
|
5725
5910
|
try {
|
|
@@ -5886,10 +6071,11 @@ describe('{{Name}}', () => {
|
|
|
5886
6071
|
var scaffoldTool = {
|
|
5887
6072
|
name: "scaffold",
|
|
5888
6073
|
category: "Project",
|
|
5889
|
-
description: "Generate
|
|
5890
|
-
usageHint: "
|
|
6074
|
+
description: "Generate new files and folder structures from built-in templates or custom definitions. This is the recommended way to bootstrap new packages, components, or modules instead of creating files one by one with `write`.",
|
|
6075
|
+
usageHint: "PREFERRED FOR SCAFFOLDING:\n\n- Use built-in templates when they match your needs (e.g. react-component, npm-package).\n- Supports `dry_run` so you can preview exactly what will be created.\n- Has the powerful `fs.write.outside-project` capability \u2014 review paths carefully.\nMuch cleaner and safer than manually writing multiple files.",
|
|
5891
6076
|
permission: "confirm",
|
|
5892
6077
|
mutating: true,
|
|
6078
|
+
capabilities: ["fs.write.outside-project", "fs.write"],
|
|
5893
6079
|
timeoutMs: 3e4,
|
|
5894
6080
|
inputSchema: {
|
|
5895
6081
|
type: "object",
|
|
@@ -5982,10 +6168,11 @@ var TIMEOUT_MS4 = 15e3;
|
|
|
5982
6168
|
var searchTool = {
|
|
5983
6169
|
name: "search",
|
|
5984
6170
|
category: "Search",
|
|
5985
|
-
description: "
|
|
5986
|
-
usageHint: "
|
|
6171
|
+
description: "Perform a web search and return results with title, URL, and snippet. Use this when you need up-to-date external information that is not in the local codebase.",
|
|
6172
|
+
usageHint: "Good for: API documentation, error messages, library usage examples, current best practices.\n\n- Prefer specific queries over very broad ones.\n- Results go through the guarded fetch system (same protections as the `fetch` tool).\n- This is often better than the model trying to recall outdated knowledge.",
|
|
5987
6173
|
permission: "confirm",
|
|
5988
6174
|
mutating: false,
|
|
6175
|
+
capabilities: ["net.outbound"],
|
|
5989
6176
|
timeoutMs: TIMEOUT_MS4,
|
|
5990
6177
|
inputSchema: {
|
|
5991
6178
|
type: "object",
|
|
@@ -6188,8 +6375,8 @@ function stripTags2(html) {
|
|
|
6188
6375
|
var testTool = {
|
|
6189
6376
|
name: "test",
|
|
6190
6377
|
category: "Code Quality",
|
|
6191
|
-
description: "
|
|
6192
|
-
usageHint: "
|
|
6378
|
+
description: "Execute the project's test suite. This is one of the most critical tools for validating that your changes are correct.",
|
|
6379
|
+
usageHint: "ESSENTIAL BEFORE CONSIDERING WORK DONE:\n\n- Use `files` or `grep` to run only relevant tests during development.\n- `coverage: true` is useful when working on critical paths.\nRun tests frequently. A clean test run is usually required before the task can be considered complete.",
|
|
6193
6380
|
permission: "confirm",
|
|
6194
6381
|
mutating: false,
|
|
6195
6382
|
timeoutMs: 12e4,
|
|
@@ -6327,7 +6514,7 @@ function parseResult(runner, result, duration) {
|
|
|
6327
6514
|
passed,
|
|
6328
6515
|
failed,
|
|
6329
6516
|
duration_ms: duration,
|
|
6330
|
-
output: result.stdout || result.error || "",
|
|
6517
|
+
output: normalizeCommandOutput(result.stdout || result.error || ""),
|
|
6331
6518
|
truncated: result.truncated
|
|
6332
6519
|
};
|
|
6333
6520
|
}
|
|
@@ -6336,8 +6523,8 @@ function parseResult(runner, result, duration) {
|
|
|
6336
6523
|
var todoTool = {
|
|
6337
6524
|
name: "todo",
|
|
6338
6525
|
category: "Session",
|
|
6339
|
-
description: "
|
|
6340
|
-
usageHint: "
|
|
6526
|
+
description: "Manage the session-level todo list. This is the primary mechanism for tracking multi-step work. The list is fully replaced on every call (not appended).",
|
|
6527
|
+
usageHint: "BEST PRACTICE for complex tasks:\n- At the beginning of a non-trivial task, create a clear todo list with specific, actionable items.\n- Only **one** item should be `in_progress` at any time.\n- Update the list frequently as work progresses (mark items done, add new ones, change status).\n- The system and user can see this list, so keep it honest and up-to-date.\nThis tool is extremely valuable for maintaining focus and giving the user visibility into your plan.",
|
|
6341
6528
|
permission: "auto",
|
|
6342
6529
|
mutating: false,
|
|
6343
6530
|
timeoutMs: 1e3,
|
|
@@ -6349,13 +6536,27 @@ var todoTool = {
|
|
|
6349
6536
|
items: {
|
|
6350
6537
|
type: "object",
|
|
6351
6538
|
properties: {
|
|
6352
|
-
id: {
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6539
|
+
id: {
|
|
6540
|
+
type: "string",
|
|
6541
|
+
description: 'Unique identifier for the todo item (e.g. "1", "auth-flow").'
|
|
6542
|
+
},
|
|
6543
|
+
content: {
|
|
6544
|
+
type: "string",
|
|
6545
|
+
description: "Clear, actionable description of the task."
|
|
6546
|
+
},
|
|
6547
|
+
status: {
|
|
6548
|
+
type: "string",
|
|
6549
|
+
enum: ["pending", "in_progress", "completed"],
|
|
6550
|
+
description: 'Current status. Only one item should be "in_progress" at a time.'
|
|
6551
|
+
},
|
|
6552
|
+
activeForm: {
|
|
6553
|
+
type: "string",
|
|
6554
|
+
description: 'Optional present-tense form shown while the task is active (e.g. "Fixing auth bug").'
|
|
6555
|
+
}
|
|
6356
6556
|
},
|
|
6357
6557
|
required: ["id", "content", "status"]
|
|
6358
|
-
}
|
|
6558
|
+
},
|
|
6559
|
+
description: "The complete new list of todos. This replaces the previous list entirely."
|
|
6359
6560
|
}
|
|
6360
6561
|
},
|
|
6361
6562
|
required: ["todos"]
|
|
@@ -6387,8 +6588,8 @@ var todoTool = {
|
|
|
6387
6588
|
var toolHelpTool = {
|
|
6388
6589
|
name: "tool_help",
|
|
6389
6590
|
category: "Meta",
|
|
6390
|
-
description: "Get help and usage
|
|
6391
|
-
usageHint: "
|
|
6591
|
+
description: "Get detailed help for one or more tools, including their full schema and usage guidance. This is the best way to understand exactly how to call a specific tool.",
|
|
6592
|
+
usageHint: "USE WHEN YOU NEED PRECISE TOOL INFORMATION:\n\n- Call with a specific `tool` name when you want the full schema and current usageHint.\n- Omit `tool` (or use a broad query) to get an overview of available tools.\n- Different `format` options give you different levels of detail.\nThis tool is extremely valuable for self-correction when you are unsure about a tool's interface.",
|
|
6392
6593
|
permission: "auto",
|
|
6393
6594
|
mutating: false,
|
|
6394
6595
|
timeoutMs: 5e3,
|
|
@@ -6397,16 +6598,16 @@ var toolHelpTool = {
|
|
|
6397
6598
|
properties: {
|
|
6398
6599
|
tool: {
|
|
6399
6600
|
type: "string",
|
|
6400
|
-
description: "
|
|
6601
|
+
description: "Specific tool name to get detailed help for. Omit to get a list of all tools."
|
|
6401
6602
|
},
|
|
6402
6603
|
format: {
|
|
6403
6604
|
type: "string",
|
|
6404
6605
|
enum: ["short", "full", "markdown"],
|
|
6405
|
-
description:
|
|
6606
|
+
description: 'Level of detail: "short" (summary), "full" (with full schema), "markdown" (human readable).'
|
|
6406
6607
|
},
|
|
6407
6608
|
include_examples: {
|
|
6408
6609
|
type: "boolean",
|
|
6409
|
-
description: "
|
|
6610
|
+
description: "Whether to include example usage in the response."
|
|
6410
6611
|
}
|
|
6411
6612
|
}
|
|
6412
6613
|
},
|
|
@@ -6509,8 +6710,8 @@ function formatAllToolsMarkdown(tools) {
|
|
|
6509
6710
|
var toolSearchTool = {
|
|
6510
6711
|
name: "tool_search",
|
|
6511
6712
|
category: "Meta",
|
|
6512
|
-
description: "Search available tools
|
|
6513
|
-
usageHint: "
|
|
6713
|
+
description: "Search the catalog of available tools. Very useful when you are unsure which tool to use for a task.",
|
|
6714
|
+
usageHint: "SELF-DISCOVERY TOOL:\n\n- Use when you need to find the right tool for a job.\n- `query` searches names and descriptions.\n- You can filter by `tags` (category), `permission`, or `mutating`.\nCall this before guessing tool names. It helps you discover the best tool for the current situation.",
|
|
6514
6715
|
permission: "auto",
|
|
6515
6716
|
mutating: false,
|
|
6516
6717
|
timeoutMs: 1e3,
|
|
@@ -6583,8 +6784,8 @@ var toolSearchTool = {
|
|
|
6583
6784
|
var toolUseTool = {
|
|
6584
6785
|
name: "tool_use",
|
|
6585
6786
|
category: "Meta",
|
|
6586
|
-
description: "
|
|
6587
|
-
usageHint: "
|
|
6787
|
+
description: "Directly execute any registered tool by its exact name, bypassing normal discovery. This is a powerful meta-tool intended for cases where the agent has a clear plan and knows precisely which tool to invoke.",
|
|
6788
|
+
usageHint: "ADVANCED META TOOL \u2014 USE WITH CARE:\n\n- Only use when you are certain of the exact tool name and its expected input shape.\n- Prefer using the normal tool calling mechanism when possible.\n- Very useful in batch-tool-use or when orchestrating complex workflows programmatically.\n- The call still goes through full permission checks and capability validation.",
|
|
6588
6789
|
permission: "confirm",
|
|
6589
6790
|
mutating: true,
|
|
6590
6791
|
timeoutMs: 6e4,
|
|
@@ -6593,11 +6794,11 @@ var toolUseTool = {
|
|
|
6593
6794
|
properties: {
|
|
6594
6795
|
tool: {
|
|
6595
6796
|
type: "string",
|
|
6596
|
-
description:
|
|
6797
|
+
description: 'The exact registered name of the tool to invoke (e.g. "bash", "read", "codebase-search").'
|
|
6597
6798
|
},
|
|
6598
6799
|
input: {
|
|
6599
6800
|
type: "object",
|
|
6600
|
-
description: "
|
|
6801
|
+
description: "The input object matching the target tool's inputSchema."
|
|
6601
6802
|
}
|
|
6602
6803
|
},
|
|
6603
6804
|
required: ["tool"]
|
|
@@ -6663,34 +6864,41 @@ var DEFAULT_IGNORE5 = [
|
|
|
6663
6864
|
var treeTool = {
|
|
6664
6865
|
name: "tree",
|
|
6665
6866
|
category: "Filesystem",
|
|
6666
|
-
description: "Display directory
|
|
6667
|
-
usageHint: "
|
|
6867
|
+
description: "Display a directory tree of the project (or a subpath). This is the recommended way to explore the high-level structure of a codebase before reading specific files.",
|
|
6868
|
+
usageHint: "BEST PRACTICE FOR INITIAL EXPLORATION:\n\n- Call early when working with an unfamiliar project or module.\n- Tune `depth` (default 3) and use `glob`/`exclude` to focus the view.\n- Prefer this over raw `bash find` or `glob` + manual reading when you need a quick structural overview.\nOutput is truncated for very large trees.",
|
|
6668
6869
|
permission: "auto",
|
|
6669
6870
|
mutating: false,
|
|
6871
|
+
capabilities: ["fs.read"],
|
|
6670
6872
|
timeoutMs: 15e3,
|
|
6671
6873
|
inputSchema: {
|
|
6672
6874
|
type: "object",
|
|
6673
6875
|
properties: {
|
|
6674
|
-
path: {
|
|
6876
|
+
path: {
|
|
6877
|
+
type: "string",
|
|
6878
|
+
description: "Root directory to display the tree from (defaults to project root)."
|
|
6879
|
+
},
|
|
6675
6880
|
depth: {
|
|
6676
6881
|
type: "integer",
|
|
6677
|
-
description: "
|
|
6882
|
+
description: "Maximum directory depth to traverse (default 3, use 0 for unlimited).",
|
|
6678
6883
|
minimum: 0,
|
|
6679
6884
|
maximum: 20
|
|
6680
6885
|
},
|
|
6681
|
-
glob: {
|
|
6886
|
+
glob: {
|
|
6887
|
+
type: "string",
|
|
6888
|
+
description: "Only include files matching this glob pattern."
|
|
6889
|
+
},
|
|
6682
6890
|
exclude: {
|
|
6683
6891
|
type: "array",
|
|
6684
6892
|
items: { type: "string" },
|
|
6685
|
-
description: "
|
|
6893
|
+
description: "List of directory names to completely ignore."
|
|
6686
6894
|
},
|
|
6687
6895
|
show_files: {
|
|
6688
6896
|
type: "boolean",
|
|
6689
|
-
description: "
|
|
6897
|
+
description: "Whether to show individual files (default true)."
|
|
6690
6898
|
},
|
|
6691
6899
|
show_dirs: {
|
|
6692
6900
|
type: "boolean",
|
|
6693
|
-
description: "
|
|
6901
|
+
description: "Whether to show directories (default true)."
|
|
6694
6902
|
},
|
|
6695
6903
|
show_hidden: {
|
|
6696
6904
|
type: "boolean",
|
|
@@ -6818,8 +7026,8 @@ async function walkDir(dir, depth, opts) {
|
|
|
6818
7026
|
var typecheckTool = {
|
|
6819
7027
|
name: "typecheck",
|
|
6820
7028
|
category: "Code Quality",
|
|
6821
|
-
description: "Run TypeScript type
|
|
6822
|
-
usageHint: "
|
|
7029
|
+
description: "Run the project's TypeScript type checker (`tsc --noEmit` or equivalent). Essential for verifying type safety before making changes or committing.",
|
|
7030
|
+
usageHint: "ALWAYS RUN BEFORE CONSIDERING WORK COMPLETE:\n\n- Use this to catch type errors early.\n- In monorepos, `all: true` will check every package.\n- This is one of the most important quality gates in this project.\nNever claim a task is done without a clean typecheck (unless the user explicitly says otherwise).",
|
|
6823
7031
|
permission: "confirm",
|
|
6824
7032
|
mutating: false,
|
|
6825
7033
|
timeoutMs: 12e4,
|
|
@@ -6877,7 +7085,7 @@ var typecheckTool = {
|
|
|
6877
7085
|
exit_code: result.exitCode,
|
|
6878
7086
|
errors,
|
|
6879
7087
|
warnings,
|
|
6880
|
-
output: result.stdout || result.stderr || result.error || "",
|
|
7088
|
+
output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ""),
|
|
6881
7089
|
truncated: result.truncated
|
|
6882
7090
|
}
|
|
6883
7091
|
};
|
|
@@ -6898,16 +7106,23 @@ async function findTsConfig(cwd) {
|
|
|
6898
7106
|
var writeTool = {
|
|
6899
7107
|
name: "write",
|
|
6900
7108
|
category: "Filesystem",
|
|
6901
|
-
description: "Write or overwrite a file. For existing files, prefer `edit`
|
|
6902
|
-
usageHint: "Use `write` for new files or
|
|
7109
|
+
description: "Write or completely overwrite a file on disk. This is a high-privilege operation. For modifying existing files, you should almost always prefer the `edit` tool instead, because `edit` is safer and works on the last-read version of the file.",
|
|
7110
|
+
usageHint: "RULES FOR CORRECT USAGE:\n- Use `write` primarily for **new files** or when you want to replace the entire content.\n- For any existing file, strongly prefer `edit` (it requires a prior `read` in the same session and is more precise).\n- You MUST have called `read` on the file earlier in the conversation before using `write` on an existing path (the system enforces this for safety).\n- The path is resolved relative to the project root and protected against escaping the workspace.",
|
|
6903
7111
|
permission: "confirm",
|
|
6904
7112
|
mutating: true,
|
|
6905
7113
|
timeoutMs: 5e3,
|
|
7114
|
+
capabilities: ["fs.write"],
|
|
6906
7115
|
inputSchema: {
|
|
6907
7116
|
type: "object",
|
|
6908
7117
|
properties: {
|
|
6909
|
-
path: {
|
|
6910
|
-
|
|
7118
|
+
path: {
|
|
7119
|
+
type: "string",
|
|
7120
|
+
description: "Relative path from project root. Must not escape the project."
|
|
7121
|
+
},
|
|
7122
|
+
content: {
|
|
7123
|
+
type: "string",
|
|
7124
|
+
description: "The complete new content of the file."
|
|
7125
|
+
}
|
|
6911
7126
|
},
|
|
6912
7127
|
required: ["path", "content"]
|
|
6913
7128
|
},
|
|
@@ -6994,7 +7209,7 @@ var builtinTools = [
|
|
|
6994
7209
|
// src/pack.ts
|
|
6995
7210
|
var builtinToolsPack = {
|
|
6996
7211
|
name: "builtin-tools",
|
|
6997
|
-
description: "
|
|
7212
|
+
description: "The complete set of built-in tools that ship with WrongStack. Covers filesystem (read/write/edit/replace/glob/grep/tree), execution (bash/exec/git/install), networking (fetch/search), code quality (lint/test/typecheck/format), planning (todo/plan/memory), and meta tools (tool-search/tool-help/batch-tool-use/codebase-*).",
|
|
6998
7213
|
tools: builtinTools
|
|
6999
7214
|
};
|
|
7000
7215
|
|