@wrongstack/tools 0.1.10 → 0.3.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/README.md +1 -1
- package/dist/audit.js +1 -0
- package/dist/audit.js.map +1 -1
- package/dist/bash.js +1 -0
- package/dist/bash.js.map +1 -1
- package/dist/batch-tool-use.js +2 -1
- package/dist/batch-tool-use.js.map +1 -1
- package/dist/builtin.js +161 -10
- package/dist/builtin.js.map +1 -1
- package/dist/diff.js +1 -0
- package/dist/diff.js.map +1 -1
- package/dist/document.js +1 -0
- package/dist/document.js.map +1 -1
- package/dist/edit.js +1 -0
- package/dist/edit.js.map +1 -1
- package/dist/exec.js +2 -1
- package/dist/exec.js.map +1 -1
- package/dist/fetch.js +1 -0
- package/dist/fetch.js.map +1 -1
- package/dist/format.js +1 -0
- package/dist/format.js.map +1 -1
- package/dist/git.js +1 -0
- package/dist/git.js.map +1 -1
- package/dist/glob.js +1 -0
- package/dist/glob.js.map +1 -1
- package/dist/grep.js +18 -1
- package/dist/grep.js.map +1 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +172 -11
- package/dist/index.js.map +1 -1
- package/dist/install.js +1 -0
- package/dist/install.js.map +1 -1
- package/dist/json.js +1 -0
- package/dist/json.js.map +1 -1
- package/dist/lint.js +1 -0
- package/dist/lint.js.map +1 -1
- package/dist/logs.js +1 -0
- package/dist/logs.js.map +1 -1
- package/dist/memory.js +2 -0
- package/dist/memory.js.map +1 -1
- package/dist/mode.js +1 -0
- package/dist/mode.js.map +1 -1
- package/dist/outdated.js +1 -0
- package/dist/outdated.js.map +1 -1
- package/dist/pack.d.ts +9 -0
- package/dist/pack.js +4216 -0
- package/dist/pack.js.map +1 -0
- package/dist/patch.js +1 -0
- package/dist/patch.js.map +1 -1
- package/dist/read.js +1 -0
- package/dist/read.js.map +1 -1
- package/dist/replace.js +12 -5
- package/dist/replace.js.map +1 -1
- package/dist/scaffold.js +1 -0
- package/dist/scaffold.js.map +1 -1
- package/dist/search.js +1 -0
- package/dist/search.js.map +1 -1
- package/dist/test.js +1 -0
- package/dist/test.js.map +1 -1
- package/dist/todo.js +1 -0
- package/dist/todo.js.map +1 -1
- package/dist/tool-help.js +1 -0
- package/dist/tool-help.js.map +1 -1
- package/dist/tool-search.js +1 -0
- package/dist/tool-search.js.map +1 -1
- package/dist/tool-use.js +2 -1
- package/dist/tool-use.js.map +1 -1
- package/dist/tree.js +1 -0
- package/dist/tree.js.map +1 -1
- package/dist/typecheck.js +1 -0
- package/dist/typecheck.js.map +1 -1
- package/dist/write.js +1 -0
- package/dist/write.js.map +1 -1
- package/package.json +6 -2
package/dist/builtin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
|
-
import { buildChildEnv, stripAnsi, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, compileGlob } from '@wrongstack/core';
|
|
2
|
+
import { buildChildEnv, stripAnsi, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, compileGlob, loadPlan, emptyPlan, clearPlan, savePlan, removePlanItem, setPlanItemStatus, addPlanItem, formatPlan } from '@wrongstack/core';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { dirname } from 'path';
|
|
5
5
|
import * as os from 'os';
|
|
@@ -125,6 +125,7 @@ function isBinaryBuffer(buf) {
|
|
|
125
125
|
// src/audit.ts
|
|
126
126
|
var auditTool = {
|
|
127
127
|
name: "audit",
|
|
128
|
+
category: "Package Management",
|
|
128
129
|
description: "Run npm/pnpm security audit. Returns vulnerabilities sorted by severity.",
|
|
129
130
|
usageHint: "Set `level` to filter minimum severity. `fix` attempts auto-fix. `packages` checks specific packages.",
|
|
130
131
|
permission: "confirm",
|
|
@@ -238,6 +239,7 @@ var STREAM_FLUSH_INTERVAL_MS = 200;
|
|
|
238
239
|
var STREAM_FLUSH_BYTES = 4 * 1024;
|
|
239
240
|
var bashTool = {
|
|
240
241
|
name: "bash",
|
|
242
|
+
category: "Shell",
|
|
241
243
|
description: "Run a shell command. stdout and stderr are merged.",
|
|
242
244
|
usageHint: "Runs via `bash -c` (or `cmd /c` on Windows). Cwd is the project root. Default timeout 30s. Output truncated from the middle if oversized. Use for git, npm, builds, tests.",
|
|
243
245
|
permission: "confirm",
|
|
@@ -417,10 +419,11 @@ var bashTool = {
|
|
|
417
419
|
// src/batch-tool-use.ts
|
|
418
420
|
var batchToolUseTool = {
|
|
419
421
|
name: "batch_tool_use",
|
|
422
|
+
category: "Meta",
|
|
420
423
|
description: "Execute multiple tool calls in sequence or parallel. Returns all results.",
|
|
421
424
|
usageHint: "Set `calls` array with tool names and inputs. `stop_on_error` halts on first failure. `parallel` runs concurrently (default: true).",
|
|
422
425
|
permission: "confirm",
|
|
423
|
-
mutating:
|
|
426
|
+
mutating: true,
|
|
424
427
|
timeoutMs: 12e4,
|
|
425
428
|
inputSchema: {
|
|
426
429
|
type: "object",
|
|
@@ -518,6 +521,7 @@ async function executeSingle(call, ctx, opts) {
|
|
|
518
521
|
}
|
|
519
522
|
var diffTool = {
|
|
520
523
|
name: "diff",
|
|
524
|
+
category: "Filesystem",
|
|
521
525
|
description: "Show differences between files, commits, or branches. Supports staged vs working tree.",
|
|
522
526
|
usageHint: "Use `files` for file paths, `a`/`b` for commit refs, `staged` for git index. `mode`: unified (default), stat, side-by-side.",
|
|
523
527
|
permission: "auto",
|
|
@@ -634,6 +638,7 @@ function formatUnified(lines, context) {
|
|
|
634
638
|
}
|
|
635
639
|
var documentTool = {
|
|
636
640
|
name: "document",
|
|
641
|
+
category: "Project",
|
|
637
642
|
description: "Generate or update documentation comments for functions, classes, and types. Supports JSDoc, TSDoc, and block comments.",
|
|
638
643
|
usageHint: "Set `target` for what to document. `files` for paths. `style` for comment format. `overwrite` replaces existing docs.",
|
|
639
644
|
permission: "confirm",
|
|
@@ -782,6 +787,7 @@ function processFile(content, absPath, style, overwrite, target) {
|
|
|
782
787
|
}
|
|
783
788
|
var editTool = {
|
|
784
789
|
name: "edit",
|
|
790
|
+
category: "Filesystem",
|
|
785
791
|
description: "Make a surgical edit by replacing exact text. Fails if `old_string` is not unique unless `replace_all` is true.",
|
|
786
792
|
usageHint: "Always `read` the file first. `old_string` must be an EXACT match (whitespace included). If multiple matches exist, either narrow `old_string` with more context or set `replace_all: true`.",
|
|
787
793
|
permission: "confirm",
|
|
@@ -938,10 +944,11 @@ var MAX_OUTPUT2 = 2e5;
|
|
|
938
944
|
var TIMEOUT_MS = 3e4;
|
|
939
945
|
var execTool = {
|
|
940
946
|
name: "exec",
|
|
947
|
+
category: "Shell",
|
|
941
948
|
description: "Restricted shell that only runs pre-approved commands with constrained arguments. Safer alternative to `bash`.",
|
|
942
949
|
usageHint: "Set `command` (must be in allowlist). `args` passed through. For arbitrary shell access use the `bash` tool instead.",
|
|
943
950
|
permission: "confirm",
|
|
944
|
-
mutating:
|
|
951
|
+
mutating: true,
|
|
945
952
|
timeoutMs: TIMEOUT_MS,
|
|
946
953
|
inputSchema: {
|
|
947
954
|
type: "object",
|
|
@@ -1083,6 +1090,7 @@ async function fetchWithRedirectLimit(url, maxRedirects, signal) {
|
|
|
1083
1090
|
}
|
|
1084
1091
|
var fetchTool = {
|
|
1085
1092
|
name: "fetch",
|
|
1093
|
+
category: "Network",
|
|
1086
1094
|
description: "Fetch the contents of a URL. HTML is converted to markdown by default.",
|
|
1087
1095
|
usageHint: "HTTPS only by default. Localhost and RFC1918 ranges blocked unless WRONGSTACK_FETCH_ALLOW_PRIVATE=1. Max 5 redirects, 20s timeout, 128KB cap.",
|
|
1088
1096
|
permission: "confirm",
|
|
@@ -1331,6 +1339,7 @@ function stripTags(s) {
|
|
|
1331
1339
|
// src/format.ts
|
|
1332
1340
|
var formatTool = {
|
|
1333
1341
|
name: "format",
|
|
1342
|
+
category: "Code Quality",
|
|
1334
1343
|
description: "Format files with biome or prettier. Use `check` to verify without modifying.",
|
|
1335
1344
|
usageHint: "Set `files` (glob or comma-separated). `check` only validates. `fixer` forces tool.",
|
|
1336
1345
|
permission: "confirm",
|
|
@@ -1429,6 +1438,7 @@ var TIMEOUT_MS3 = 3e4;
|
|
|
1429
1438
|
var MAX_OUTPUT3 = 1e5;
|
|
1430
1439
|
var gitTool = {
|
|
1431
1440
|
name: "git",
|
|
1441
|
+
category: "Git",
|
|
1432
1442
|
description: "Run git commands. Wraps common operations: status, log, diff, commit, branch, checkout, stash, push, pull, fetch, reset.",
|
|
1433
1443
|
usageHint: "Prefer built-in subcommands over raw args. `command` is required. `message` for commits. `branch` for checkout/branch. `files` for status/diff. `format` for log.",
|
|
1434
1444
|
permission: "confirm",
|
|
@@ -1593,6 +1603,7 @@ function runGit2(args, cwd, signal) {
|
|
|
1593
1603
|
var DEFAULT_IGNORE = ["node_modules", ".git", "dist", "build", ".next", "coverage", ".turbo"];
|
|
1594
1604
|
var globTool = {
|
|
1595
1605
|
name: "glob",
|
|
1606
|
+
category: "Filesystem",
|
|
1596
1607
|
description: "Find files matching a glob pattern. Returns paths sorted by mtime (newest first).",
|
|
1597
1608
|
usageHint: "Examples: `**/*.ts`, `src/**/*.test.ts`, `*.json`. Common dirs (node_modules, .git, dist) are ignored by default. Returns up to 1000 paths.",
|
|
1598
1609
|
permission: "auto",
|
|
@@ -1709,6 +1720,7 @@ function capSubject(line) {
|
|
|
1709
1720
|
var DEFAULT_IGNORE2 = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
1710
1721
|
var grepTool = {
|
|
1711
1722
|
name: "grep",
|
|
1723
|
+
category: "Search",
|
|
1712
1724
|
description: "Search file contents with a regex. Uses ripgrep when available.",
|
|
1713
1725
|
usageHint: 'Pattern is regex. Use `output_mode: "content"` for matched lines, `"files_with_matches"` for paths, `"count"` for tallies. `glob` filters files (e.g. `*.ts`).',
|
|
1714
1726
|
permission: "auto",
|
|
@@ -1741,6 +1753,10 @@ var grepTool = {
|
|
|
1741
1753
|
const base = input.path ? safeResolve(input.path, ctx) : ctx.cwd;
|
|
1742
1754
|
const mode = input.output_mode ?? "content";
|
|
1743
1755
|
const limit = Math.max(1, Math.min(input.limit ?? 200, 2e3));
|
|
1756
|
+
const validation = compileUserRegex(input.pattern, input.case_insensitive ? "i" : "");
|
|
1757
|
+
if (!validation.ok) {
|
|
1758
|
+
throw new Error(`grep: ${validation.reason}`);
|
|
1759
|
+
}
|
|
1744
1760
|
const rgAvailable = await detectRg(opts.signal);
|
|
1745
1761
|
if (rgAvailable) {
|
|
1746
1762
|
try {
|
|
@@ -1774,11 +1790,15 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
1774
1790
|
args.push("-n");
|
|
1775
1791
|
if (input.context_lines) args.push("-C", String(input.context_lines));
|
|
1776
1792
|
}
|
|
1793
|
+
for (const ignored of DEFAULT_IGNORE2) {
|
|
1794
|
+
args.push("--glob", `!${ignored}/**`, "--glob", `!**/${ignored}/**`);
|
|
1795
|
+
}
|
|
1777
1796
|
if (input.glob) args.push("--glob", input.glob);
|
|
1778
1797
|
args.push("--", input.pattern, base);
|
|
1779
1798
|
const matches = [];
|
|
1780
1799
|
let buf = "";
|
|
1781
1800
|
let totalLines = 0;
|
|
1801
|
+
let totalCount = 0;
|
|
1782
1802
|
let batchSinceFlush = 0;
|
|
1783
1803
|
const FLUSH_AT = 16;
|
|
1784
1804
|
const MAX_BUF_BYTES = 1e6;
|
|
@@ -1835,6 +1855,7 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
1835
1855
|
for (const line of ready.split("\n")) {
|
|
1836
1856
|
if (!line) continue;
|
|
1837
1857
|
totalLines++;
|
|
1858
|
+
if (mode === "count") totalCount += parseRgCountLine(line);
|
|
1838
1859
|
if (matches.length < limit) {
|
|
1839
1860
|
matches.push(line);
|
|
1840
1861
|
pendingBatch.push(line);
|
|
@@ -1855,6 +1876,7 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
1855
1876
|
for (const line of buf.split("\n")) {
|
|
1856
1877
|
if (!line) continue;
|
|
1857
1878
|
totalLines++;
|
|
1879
|
+
if (mode === "count") totalCount += parseRgCountLine(line);
|
|
1858
1880
|
if (matches.length < limit) {
|
|
1859
1881
|
matches.push(line);
|
|
1860
1882
|
pendingBatch.push(line);
|
|
@@ -1873,12 +1895,18 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
1873
1895
|
type: "final",
|
|
1874
1896
|
output: {
|
|
1875
1897
|
matches,
|
|
1876
|
-
count: totalLines,
|
|
1898
|
+
count: mode === "count" ? totalCount : totalLines,
|
|
1877
1899
|
truncated: totalLines > limit || bufOverflow,
|
|
1878
1900
|
used: "rg"
|
|
1879
1901
|
}
|
|
1880
1902
|
};
|
|
1881
1903
|
}
|
|
1904
|
+
function parseRgCountLine(line) {
|
|
1905
|
+
const idx = line.lastIndexOf(":");
|
|
1906
|
+
if (idx === -1) return 0;
|
|
1907
|
+
const n = Number.parseInt(line.slice(idx + 1), 10);
|
|
1908
|
+
return Number.isFinite(n) ? n : 0;
|
|
1909
|
+
}
|
|
1882
1910
|
async function runNative(input, base, mode, limit, signal) {
|
|
1883
1911
|
const flags = input.case_insensitive ? "i" : "";
|
|
1884
1912
|
const compiled = compileUserRegex(input.pattern, flags);
|
|
@@ -1955,6 +1983,7 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
1955
1983
|
// src/install.ts
|
|
1956
1984
|
var installTool = {
|
|
1957
1985
|
name: "install",
|
|
1986
|
+
category: "Package Management",
|
|
1958
1987
|
description: "Install npm packages. Detects pnpm/npm/yarn and uses the right package manager.",
|
|
1959
1988
|
usageHint: "Set `packages` to install. `save` as dependency type. `global` for global install. `dry_run` to preview.",
|
|
1960
1989
|
permission: "confirm",
|
|
@@ -2048,6 +2077,7 @@ async function detectPackageManager(cwd) {
|
|
|
2048
2077
|
}
|
|
2049
2078
|
var jsonTool = {
|
|
2050
2079
|
name: "json",
|
|
2080
|
+
category: "Data",
|
|
2051
2081
|
description: "Parse, query, and validate JSON/JSON5/YAML. Use `query` with JMESPath-like paths to extract values.",
|
|
2052
2082
|
usageHint: 'Provide `file` path or `data` string. `query` supports dot notation (e.g. "results[0].name"). `format` outputs in specified format.',
|
|
2053
2083
|
permission: "auto",
|
|
@@ -2170,6 +2200,7 @@ function toYaml(data, indent = 0) {
|
|
|
2170
2200
|
// src/lint.ts
|
|
2171
2201
|
var lintTool = {
|
|
2172
2202
|
name: "lint",
|
|
2203
|
+
category: "Code Quality",
|
|
2173
2204
|
description: "Run a linter on files. Auto-detects biome, eslint, or tslint. Use `fix` to auto-fix issues.",
|
|
2174
2205
|
usageHint: "Set `files` (glob or comma-separated). `fix` applies corrections. `linter` forces specific tool.",
|
|
2175
2206
|
permission: "confirm",
|
|
@@ -2259,6 +2290,7 @@ async function detectLinter(cwd) {
|
|
|
2259
2290
|
}
|
|
2260
2291
|
var logsTool = {
|
|
2261
2292
|
name: "logs",
|
|
2293
|
+
category: "Logs",
|
|
2262
2294
|
description: "Stream or fetch logs from a service or file. Supports Docker, systemd, or plain log files.",
|
|
2263
2295
|
usageHint: "Set `service` for Docker/systemd, `path` for file. `lines` limits output. `stream` for tail -f behavior. `filter` regex filters lines.",
|
|
2264
2296
|
permission: "confirm",
|
|
@@ -2436,6 +2468,7 @@ function parseLine(line) {
|
|
|
2436
2468
|
}
|
|
2437
2469
|
var outdatedTool = {
|
|
2438
2470
|
name: "outdated",
|
|
2471
|
+
category: "Package Management",
|
|
2439
2472
|
description: "Check for outdated npm packages. Shows current, wanted, and latest versions.",
|
|
2440
2473
|
usageHint: "Set `check` to filter specific packages. `format` as list or table. `include_deprecated` shows deprecated packages.",
|
|
2441
2474
|
permission: "auto",
|
|
@@ -2547,6 +2580,7 @@ function parseOutdatedOutput(json, exitCode) {
|
|
|
2547
2580
|
}
|
|
2548
2581
|
var patchTool = {
|
|
2549
2582
|
name: "patch",
|
|
2583
|
+
category: "Filesystem",
|
|
2550
2584
|
description: "Apply a unified diff patch to files. Writes .orig and .rej files on failure.",
|
|
2551
2585
|
usageHint: "Set `patch` (the diff text). `directory` defaults to cwd. `strip` removes leading path components. `dry_run` previews.",
|
|
2552
2586
|
permission: "confirm",
|
|
@@ -2653,9 +2687,108 @@ function extractPatchedFiles(output) {
|
|
|
2653
2687
|
}
|
|
2654
2688
|
return files;
|
|
2655
2689
|
}
|
|
2690
|
+
var planTool = {
|
|
2691
|
+
name: "plan",
|
|
2692
|
+
category: "Session",
|
|
2693
|
+
description: "Inspect or edit the strategic plan board for this session. Plans persist across resume (unlike todos). Use this to lay out the multi-step approach before diving in, then mark steps in_progress/done as the work proceeds.",
|
|
2694
|
+
usageHint: "Set action to one of: show | add | start | done | remove | clear. Pass `title` for add. Pass `target` (item id, 1-based index, or title substring) for start/done/remove. Always returns the formatted plan plus open/total counts.",
|
|
2695
|
+
permission: "auto",
|
|
2696
|
+
mutating: false,
|
|
2697
|
+
timeoutMs: 2e3,
|
|
2698
|
+
inputSchema: {
|
|
2699
|
+
type: "object",
|
|
2700
|
+
properties: {
|
|
2701
|
+
action: {
|
|
2702
|
+
type: "string",
|
|
2703
|
+
enum: ["show", "add", "start", "done", "remove", "clear"]
|
|
2704
|
+
},
|
|
2705
|
+
title: { type: "string", description: "Required when action = add." },
|
|
2706
|
+
details: { type: "string", description: "Optional extra context for add." },
|
|
2707
|
+
target: {
|
|
2708
|
+
type: "string",
|
|
2709
|
+
description: "Plan item id, 1-based index, or title substring. Required for start/done/remove."
|
|
2710
|
+
}
|
|
2711
|
+
},
|
|
2712
|
+
required: ["action"]
|
|
2713
|
+
},
|
|
2714
|
+
async execute(input, ctx) {
|
|
2715
|
+
const planPath = ctx.meta["plan.path"];
|
|
2716
|
+
if (typeof planPath !== "string" || !planPath) {
|
|
2717
|
+
return {
|
|
2718
|
+
ok: false,
|
|
2719
|
+
message: "Plan storage path is not configured for this session.",
|
|
2720
|
+
plan: "",
|
|
2721
|
+
count: 0,
|
|
2722
|
+
open: 0
|
|
2723
|
+
};
|
|
2724
|
+
}
|
|
2725
|
+
const sessionId = ctx.session?.id ?? "unknown";
|
|
2726
|
+
let plan = await loadPlan(planPath) ?? emptyPlan(sessionId);
|
|
2727
|
+
switch (input.action) {
|
|
2728
|
+
case "show":
|
|
2729
|
+
break;
|
|
2730
|
+
case "add": {
|
|
2731
|
+
const title = input.title?.trim();
|
|
2732
|
+
if (!title) {
|
|
2733
|
+
return mkResult(plan, false, "add requires `title`.");
|
|
2734
|
+
}
|
|
2735
|
+
({ plan } = addPlanItem(plan, title, input.details?.trim() || void 0));
|
|
2736
|
+
await savePlan(planPath, plan);
|
|
2737
|
+
break;
|
|
2738
|
+
}
|
|
2739
|
+
case "start":
|
|
2740
|
+
case "done": {
|
|
2741
|
+
if (!input.target) {
|
|
2742
|
+
return mkResult(plan, false, `${input.action} requires \`target\` (id|index|substring).`);
|
|
2743
|
+
}
|
|
2744
|
+
const next = setPlanItemStatus(
|
|
2745
|
+
plan,
|
|
2746
|
+
input.target,
|
|
2747
|
+
input.action === "start" ? "in_progress" : "done"
|
|
2748
|
+
);
|
|
2749
|
+
if (next === plan) {
|
|
2750
|
+
return mkResult(plan, false, `No plan item matched "${input.target}".`);
|
|
2751
|
+
}
|
|
2752
|
+
plan = next;
|
|
2753
|
+
await savePlan(planPath, plan);
|
|
2754
|
+
break;
|
|
2755
|
+
}
|
|
2756
|
+
case "remove": {
|
|
2757
|
+
if (!input.target) {
|
|
2758
|
+
return mkResult(plan, false, "remove requires `target` (id|index|substring).");
|
|
2759
|
+
}
|
|
2760
|
+
const next = removePlanItem(plan, input.target);
|
|
2761
|
+
if (next === plan) {
|
|
2762
|
+
return mkResult(plan, false, `No plan item matched "${input.target}".`);
|
|
2763
|
+
}
|
|
2764
|
+
plan = next;
|
|
2765
|
+
await savePlan(planPath, plan);
|
|
2766
|
+
break;
|
|
2767
|
+
}
|
|
2768
|
+
case "clear":
|
|
2769
|
+
plan = clearPlan(plan);
|
|
2770
|
+
await savePlan(planPath, plan);
|
|
2771
|
+
break;
|
|
2772
|
+
default:
|
|
2773
|
+
return mkResult(plan, false, `Unknown action "${input.action}".`);
|
|
2774
|
+
}
|
|
2775
|
+
return mkResult(plan, true, `Plan ${input.action} ok.`);
|
|
2776
|
+
}
|
|
2777
|
+
};
|
|
2778
|
+
function mkResult(plan, ok, message) {
|
|
2779
|
+
const open = plan.items.filter((i) => i.status !== "done").length;
|
|
2780
|
+
return {
|
|
2781
|
+
ok,
|
|
2782
|
+
message,
|
|
2783
|
+
plan: formatPlan(plan),
|
|
2784
|
+
count: plan.items.length,
|
|
2785
|
+
open
|
|
2786
|
+
};
|
|
2787
|
+
}
|
|
2656
2788
|
var MAX_BYTES2 = 5 * 1024 * 1024;
|
|
2657
2789
|
var readTool = {
|
|
2658
2790
|
name: "read",
|
|
2791
|
+
category: "Filesystem",
|
|
2659
2792
|
description: "Read the contents of a file. Lines are 1-indexed and prefixed with line numbers.",
|
|
2660
2793
|
usageHint: "Read a file before editing it. Returns lines numbered like ` 1\u2192content`. Use `offset` and `limit` for large files (default reads up to 2000 lines).",
|
|
2661
2794
|
permission: "auto",
|
|
@@ -2708,6 +2841,7 @@ var readTool = {
|
|
|
2708
2841
|
var DEFAULT_IGNORE3 = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
2709
2842
|
var replaceTool = {
|
|
2710
2843
|
name: "replace",
|
|
2844
|
+
category: "Transform",
|
|
2711
2845
|
description: "Batch replace a pattern across multiple files matched by glob. Returns diff for each modified file.",
|
|
2712
2846
|
usageHint: 'Use `glob` for broad patterns (e.g. "**/*.ts"). Set `dry_run: true` to preview without modifying. `files` can be a single path, comma-separated list, or glob pattern.',
|
|
2713
2847
|
permission: "confirm",
|
|
@@ -2736,7 +2870,7 @@ var replaceTool = {
|
|
|
2736
2870
|
if (input.replacement === void 0) throw new Error("replace: replacement is required");
|
|
2737
2871
|
if (!input?.files) throw new Error("replace: files is required");
|
|
2738
2872
|
const replaceAll = input.replace_all ?? true;
|
|
2739
|
-
const compiled = compileUserRegex(input.pattern,
|
|
2873
|
+
const compiled = compileUserRegex(input.pattern, "g");
|
|
2740
2874
|
if (!compiled.ok) {
|
|
2741
2875
|
throw new Error(`replace: ${compiled.reason}`);
|
|
2742
2876
|
}
|
|
@@ -2775,11 +2909,17 @@ var replaceTool = {
|
|
|
2775
2909
|
const style = detectNewlineStyle(content);
|
|
2776
2910
|
const contentLf = normalizeToLf(content);
|
|
2777
2911
|
re.lastIndex = 0;
|
|
2778
|
-
const
|
|
2779
|
-
if (
|
|
2780
|
-
const
|
|
2912
|
+
const allMatches = [...contentLf.matchAll(re)];
|
|
2913
|
+
if (allMatches.length === 0) continue;
|
|
2914
|
+
const matches = replaceAll ? allMatches : allMatches.slice(0, 1);
|
|
2915
|
+
const count = matches.length;
|
|
2916
|
+
let newContentLf = contentLf;
|
|
2917
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
2918
|
+
const m = matches[i];
|
|
2919
|
+
newContentLf = newContentLf.slice(0, m.index) + input.replacement + newContentLf.slice(m.index + m[0].length);
|
|
2920
|
+
}
|
|
2781
2921
|
re.lastIndex = 0;
|
|
2782
|
-
totalReplacements +=
|
|
2922
|
+
totalReplacements += count;
|
|
2783
2923
|
if (!dryRun) {
|
|
2784
2924
|
const newContent = toStyle(newContentLf, style);
|
|
2785
2925
|
await atomicWrite(realPath, newContent, { mode: stat9.mode & 511 });
|
|
@@ -2981,6 +3121,7 @@ describe('{{Name}}', () => {
|
|
|
2981
3121
|
};
|
|
2982
3122
|
var scaffoldTool = {
|
|
2983
3123
|
name: "scaffold",
|
|
3124
|
+
category: "Project",
|
|
2984
3125
|
description: "Generate boilerplate code from built-in templates or paths. Creates package.json, source files, tests.",
|
|
2985
3126
|
usageHint: "Set `template` (npm-package, cli-tool, react-component) and `name`. `vars` for template variables. `dry_run` preview.",
|
|
2986
3127
|
permission: "confirm",
|
|
@@ -3069,6 +3210,7 @@ var MAX_RESULTS = 50;
|
|
|
3069
3210
|
var TIMEOUT_MS4 = 15e3;
|
|
3070
3211
|
var searchTool = {
|
|
3071
3212
|
name: "search",
|
|
3213
|
+
category: "Search",
|
|
3072
3214
|
description: "Search the web for information. Returns title, URL, and snippet for each result.",
|
|
3073
3215
|
usageHint: "Set `num_results` (1-50, default 10). Use `source` to pick engine: duckduckgo (default), google, bing.",
|
|
3074
3216
|
permission: "confirm",
|
|
@@ -3277,6 +3419,7 @@ function stripTags2(html) {
|
|
|
3277
3419
|
}
|
|
3278
3420
|
var testTool = {
|
|
3279
3421
|
name: "test",
|
|
3422
|
+
category: "Code Quality",
|
|
3280
3423
|
description: "Run tests with vitest, jest, or mocha. Returns pass/fail counts and output.",
|
|
3281
3424
|
usageHint: "Set `files` for specific tests. `watch` enables watch mode. `coverage` generates coverage report. `grep` filters by name.",
|
|
3282
3425
|
permission: "confirm",
|
|
@@ -3424,6 +3567,7 @@ function parseResult(runner, result, duration) {
|
|
|
3424
3567
|
// src/todo.ts
|
|
3425
3568
|
var todoTool = {
|
|
3426
3569
|
name: "todo",
|
|
3570
|
+
category: "Session",
|
|
3427
3571
|
description: "Replace the current todo list with a new set of items.",
|
|
3428
3572
|
usageHint: "Use for multi-step tasks. Replace the full list on each call. At most ONE task may be in_progress at a time. Items have id, content, status (pending|in_progress|completed), and optional activeForm.",
|
|
3429
3573
|
permission: "auto",
|
|
@@ -3474,6 +3618,7 @@ var todoTool = {
|
|
|
3474
3618
|
// src/tool-help.ts
|
|
3475
3619
|
var toolHelpTool = {
|
|
3476
3620
|
name: "tool_help",
|
|
3621
|
+
category: "Meta",
|
|
3477
3622
|
description: "Get help and usage information for a specific tool or list all available tools.",
|
|
3478
3623
|
usageHint: "Set `tool` for specific help. Omit to list all tools. `format`: short (one-liner), full (schema), markdown (formatted).",
|
|
3479
3624
|
permission: "auto",
|
|
@@ -3595,6 +3740,7 @@ function formatAllToolsMarkdown(tools) {
|
|
|
3595
3740
|
// src/tool-search.ts
|
|
3596
3741
|
var toolSearchTool = {
|
|
3597
3742
|
name: "tool_search",
|
|
3743
|
+
category: "Meta",
|
|
3598
3744
|
description: "Search available tools by name, description, tags, permission level, or mutating flag.",
|
|
3599
3745
|
usageHint: "Set `query` for keyword search. `tags` to filter by category. `permission` to filter by required permission. `mutating` to filter by mutating flag.",
|
|
3600
3746
|
permission: "auto",
|
|
@@ -3662,10 +3808,11 @@ var toolSearchTool = {
|
|
|
3662
3808
|
// src/tool-use.ts
|
|
3663
3809
|
var toolUseTool = {
|
|
3664
3810
|
name: "tool_use",
|
|
3811
|
+
category: "Meta",
|
|
3665
3812
|
description: "Execute a specific tool by name with given input. Useful when the agent knows exactly which tool to call.",
|
|
3666
3813
|
usageHint: "Set `tool` with exact tool name and `input` with the tool parameters. Returns result or error.",
|
|
3667
3814
|
permission: "confirm",
|
|
3668
|
-
mutating:
|
|
3815
|
+
mutating: true,
|
|
3669
3816
|
timeoutMs: 6e4,
|
|
3670
3817
|
inputSchema: {
|
|
3671
3818
|
type: "object",
|
|
@@ -3737,6 +3884,7 @@ var DEFAULT_IGNORE4 = [
|
|
|
3737
3884
|
];
|
|
3738
3885
|
var treeTool = {
|
|
3739
3886
|
name: "tree",
|
|
3887
|
+
category: "Filesystem",
|
|
3740
3888
|
description: "Display directory structure as an ASCII tree. Shows files and folders with indentation.",
|
|
3741
3889
|
usageHint: "Set `path` (default: cwd). `depth` limits nesting (default: 3). `glob` filters files. `exclude` ignores dirs. `show_files` toggles file listing (default: true).",
|
|
3742
3890
|
permission: "auto",
|
|
@@ -3891,6 +4039,7 @@ async function walkDir(dir, depth, opts) {
|
|
|
3891
4039
|
}
|
|
3892
4040
|
var typecheckTool = {
|
|
3893
4041
|
name: "typecheck",
|
|
4042
|
+
category: "Code Quality",
|
|
3894
4043
|
description: "Run TypeScript type checking with `tsc --noEmit`. Checks for type errors without compiling.",
|
|
3895
4044
|
usageHint: "Set `project` for tsconfig path (default: nearest). `strict` enables strictest flags. `all` checks all projects in workspace.",
|
|
3896
4045
|
permission: "confirm",
|
|
@@ -3970,6 +4119,7 @@ async function findTsConfig(cwd) {
|
|
|
3970
4119
|
}
|
|
3971
4120
|
var writeTool = {
|
|
3972
4121
|
name: "write",
|
|
4122
|
+
category: "Filesystem",
|
|
3973
4123
|
description: "Write or overwrite a file. For existing files, prefer `edit` over `write`.",
|
|
3974
4124
|
usageHint: "Use `write` for new files or full replacements. For partial edits use `edit`. Existing files must have been `read` first in this session.",
|
|
3975
4125
|
permission: "confirm",
|
|
@@ -4032,6 +4182,7 @@ var builtinTools = [
|
|
|
4032
4182
|
fetchTool,
|
|
4033
4183
|
searchTool,
|
|
4034
4184
|
todoTool,
|
|
4185
|
+
planTool,
|
|
4035
4186
|
gitTool,
|
|
4036
4187
|
patchTool,
|
|
4037
4188
|
jsonTool,
|