@semalt-ai/code 1.8.5 → 1.20.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/.claude/settings.local.json +7 -1
- package/.github/workflows/ci.yml +69 -0
- package/ARCHITECTURE.md +6 -95
- package/CLAUDE.md +196 -316
- package/README.md +148 -4
- package/docs/ARCHITECTURE.md +1321 -0
- package/docs/CONFIG.md +340 -0
- package/docs/HISTORY.md +245 -0
- package/examples/embed.js +74 -0
- package/index.js +251 -10
- package/lib/agent.js +856 -120
- package/lib/api.js +239 -50
- package/lib/args.js +74 -2
- package/lib/audit.js +23 -1
- package/lib/background.js +584 -0
- package/lib/checkpoints.js +757 -0
- package/lib/commands/auth.js +94 -0
- package/lib/commands/chat-session.js +489 -0
- package/lib/commands/chat-slash.js +415 -0
- package/lib/commands/chat-turn.js +669 -0
- package/lib/commands/chat.js +407 -0
- package/lib/commands/custom.js +157 -0
- package/lib/commands/history-utils.js +66 -0
- package/lib/commands/index.js +268 -0
- package/lib/commands/mcp.js +113 -0
- package/lib/commands/oneshot.js +193 -0
- package/lib/commands/registry.js +269 -0
- package/lib/commands/tasks.js +89 -0
- package/lib/compact.js +87 -0
- package/lib/config.js +360 -11
- package/lib/constants.js +401 -3
- package/lib/deny.js +199 -0
- package/lib/doctor.js +160 -0
- package/lib/headless.js +202 -0
- package/lib/hooks.js +286 -0
- package/lib/images.js +270 -0
- package/lib/internals.js +49 -0
- package/lib/mcp/boundary.js +131 -0
- package/lib/mcp/client.js +270 -0
- package/lib/mcp/oauth.js +134 -0
- package/lib/memory.js +209 -0
- package/lib/metrics.js +37 -2
- package/lib/payload.js +54 -0
- package/lib/permission-rules.js +401 -0
- package/lib/permissions.js +123 -26
- package/lib/pricing.js +67 -0
- package/lib/proc.js +62 -0
- package/lib/prompts.js +99 -8
- package/lib/sandbox.js +568 -0
- package/lib/sdk.js +328 -0
- package/lib/secrets.js +211 -0
- package/lib/skills.js +223 -0
- package/lib/subagents.js +516 -0
- package/lib/tool_registry.js +2862 -0
- package/lib/tool_specs.js +263 -9
- package/lib/tools.js +352 -1039
- package/lib/ui/anim.js +86 -0
- package/lib/ui/ansi.js +17 -27
- package/lib/ui/chat-history.js +253 -71
- package/lib/ui/create-ui.js +67 -24
- package/lib/ui/diff.js +90 -25
- package/lib/ui/file-activity.js +236 -0
- package/lib/ui/format.js +195 -29
- package/lib/ui/input-field.js +21 -11
- package/lib/ui/md-stream.js +234 -0
- package/lib/ui/render-operation.js +113 -0
- package/lib/ui/select.js +1 -4
- package/lib/ui/status-bar.js +146 -36
- package/lib/ui/stream.js +20 -13
- package/lib/ui/theme.js +190 -44
- package/lib/ui/tool-operation.js +190 -0
- package/lib/ui/utils.js +9 -5
- package/lib/ui/web-activity.js +270 -0
- package/lib/ui/writer.js +159 -45
- package/lib/ui.js +1 -1
- package/lib/verify.js +229 -0
- package/lib/web-extract.js +213 -0
- package/lib/web-summarize.js +68 -0
- package/package.json +19 -4
- package/scripts/lint.js +57 -0
- package/test/agent-loop.test.js +389 -0
- package/test/anim-driver.test.js +153 -0
- package/test/ask-user-display.test.js +226 -0
- package/test/ask-user-gate.test.js +231 -0
- package/test/background.test.js +414 -0
- package/test/chat-history-nocolor.test.js +155 -0
- package/test/chat-relogin.test.js +207 -0
- package/test/chat.test.js +114 -0
- package/test/checkpoints-agent.test.js +181 -0
- package/test/checkpoints.test.js +650 -0
- package/test/command-registry.test.js +160 -0
- package/test/compact.test.js +116 -0
- package/test/completion-lazy.test.js +52 -0
- package/test/config-merge.test.js +324 -0
- package/test/config-quarantine.test.js +128 -0
- package/test/config-write-guard-allow-anywhere.test.js +56 -0
- package/test/config-write-guard-skip.test.js +46 -0
- package/test/config-write-guard.test.js +153 -0
- package/test/context-split.test.js +215 -0
- package/test/cost-doctor.test.js +142 -0
- package/test/custom-commands-chat.test.js +106 -0
- package/test/custom-commands.test.js +230 -0
- package/test/defer-detail-band.test.js +403 -0
- package/test/deny-windows.test.js +120 -0
- package/test/deny.test.js +83 -0
- package/test/detail-band-tab-flatten.test.js +242 -0
- package/test/download-allow-anywhere.test.js +66 -0
- package/test/download-confine.test.js +153 -0
- package/test/exec-diff.test.js +268 -0
- package/test/executors.test.js +599 -0
- package/test/extract-tool-calls.test.js +349 -0
- package/test/fetch-url-validation.test.js +219 -0
- package/test/file-activity.test.js +522 -0
- package/test/fixtures/tool-calls.js +57 -0
- package/test/fixtures/web-page.js +91 -0
- package/test/git-tools.test.js +384 -0
- package/test/grep-glob-serialize.test.js +242 -0
- package/test/grep-glob.test.js +268 -0
- package/test/grep-path-target.test.js +227 -0
- package/test/harness/README.md +57 -0
- package/test/harness/chat-harness.js +143 -0
- package/test/harness/memwarn-headless-child.js +65 -0
- package/test/harness/mock-llm.js +120 -0
- package/test/harness/mock-mcp-server.js +142 -0
- package/test/harness/sse-server.js +69 -0
- package/test/headless.test.js +348 -0
- package/test/history-utils.test.js +88 -0
- package/test/hooks-agent.test.js +238 -0
- package/test/hooks-verify-sandbox.test.js +232 -0
- package/test/hooks.test.js +216 -0
- package/test/http-get-user-agent.test.js +142 -0
- package/test/images-api.test.js +208 -0
- package/test/images.test.js +238 -0
- package/test/input-field-ctrl-o.test.js +37 -0
- package/test/live-height-physical.test.js +281 -0
- package/test/max-iterations.test.js +218 -0
- package/test/mcp-boundary.test.js +57 -0
- package/test/mcp-client.test.js +267 -0
- package/test/mcp-oauth.test.js +86 -0
- package/test/md-stream.test.js +183 -0
- package/test/memory-truncation-warning.test.js +222 -0
- package/test/memory.test.js +198 -0
- package/test/native-dispatch.test.js +409 -0
- package/test/native-live-narration.test.js +254 -0
- package/test/output-chokepoint.test.js +188 -0
- package/test/output-heredoc-leak.test.js +195 -0
- package/test/output-preview.test.js +245 -0
- package/test/path-guards.test.js +134 -0
- package/test/payload.test.js +99 -0
- package/test/permission-rules-agent.test.js +210 -0
- package/test/permission-rules.test.js +297 -0
- package/test/permissions.test.js +362 -0
- package/test/plan-mode.test.js +167 -0
- package/test/read-paginate.test.js +275 -0
- package/test/readonly-tools.test.js +177 -0
- package/test/render-operation.test.js +317 -0
- package/test/replay-descriptor-xml.test.js +216 -0
- package/test/replay-descriptor.test.js +189 -0
- package/test/replay-web-aggregate.test.js +291 -0
- package/test/replay-web-persist.test.js +241 -0
- package/test/result-cap.test.js +233 -0
- package/test/running-glyph-anim.test.js +111 -0
- package/test/sandbox-agent.test.js +147 -0
- package/test/sandbox-integration.test.js +216 -0
- package/test/sandbox.test.js +408 -0
- package/test/sdk.test.js +234 -0
- package/test/shell-output-cap.test.js +181 -0
- package/test/skills-chat.test.js +110 -0
- package/test/skills.test.js +295 -0
- package/test/smoke.test.js +68 -0
- package/test/status-bar-driver.test.js +93 -0
- package/test/status-bar-pause.test.js +164 -0
- package/test/status-bar-resync.test.js +188 -0
- package/test/stream-parser.test.js +171 -0
- package/test/subagents-agent.test.js +178 -0
- package/test/subagents.test.js +222 -0
- package/test/theme-palette.test.js +166 -0
- package/test/tool-registry.test.js +85 -0
- package/test/trim-budget.test.js +101 -0
- package/test/truncate-visible.test.js +78 -0
- package/test/verify-agent.test.js +317 -0
- package/test/verify.test.js +141 -0
- package/test/view-image.test.js +199 -0
- package/test/web-activity-ordering.test.js +203 -0
- package/test/web-activity.test.js +207 -0
- package/test/web-data-extraction-guidance.test.js +71 -0
- package/test/web-extract.test.js +185 -0
- package/test/web-fetch-agent.test.js +291 -0
- package/test/web-fetch-mode.test.js +193 -0
- package/test/web-search.test.js +380 -0
- package/lib/commands.js +0 -1438
- package/path +0 -1
package/lib/tool_specs.js
CHANGED
|
@@ -50,7 +50,11 @@ const TOOL_SPECS = {
|
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
read_file: {
|
|
53
|
-
description: 'Read a UTF-8 text file
|
|
53
|
+
description: 'Read a UTF-8 text file. Paginated: by default returns the first ~2000 lines; '
|
|
54
|
+
+ 'if the file is longer the result ends with a [PARTIAL] notice giving the total line count '
|
|
55
|
+
+ 'and the start_line for the next page. Use start_line/end_line to read a specific slice '
|
|
56
|
+
+ '(also capped to ~2000 lines). Set show_line_numbers=true when you need line numbers to '
|
|
57
|
+
+ 'target an edit_file call (off by default — keeps content copyable for replace_in_file and cheaper).',
|
|
54
58
|
parameters: {
|
|
55
59
|
type: 'object',
|
|
56
60
|
properties: {
|
|
@@ -58,6 +62,39 @@ const TOOL_SPECS = {
|
|
|
58
62
|
type: 'string',
|
|
59
63
|
description: 'Absolute or relative path to the file to read',
|
|
60
64
|
},
|
|
65
|
+
start_line: {
|
|
66
|
+
type: 'integer',
|
|
67
|
+
description: 'First line to read (1-based, inclusive). Omit to start at line 1.',
|
|
68
|
+
},
|
|
69
|
+
end_line: {
|
|
70
|
+
type: 'integer',
|
|
71
|
+
description: 'Last line to read (1-based, inclusive). Omit to read to the line cap. '
|
|
72
|
+
+ 'A range wider than the line cap is still capped — page with start_line.',
|
|
73
|
+
},
|
|
74
|
+
show_line_numbers: {
|
|
75
|
+
type: 'boolean',
|
|
76
|
+
description: 'Prefix each line with its 1-based line number (aligned with edit_file). '
|
|
77
|
+
+ 'Default false. Turn on when you intend to edit by line number.',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
required: ['path'],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
view_image: {
|
|
85
|
+
description: 'Load a LOCAL image file (PNG, JPEG, GIF, or WebP) into YOUR OWN vision context so you can '
|
|
86
|
+
+ 'analyze it — read text/diagrams in it, inspect a screenshot, compare a mockup, etc. The image is made '
|
|
87
|
+
+ 'visible to YOU (the model) for the next turn; it is NOT displayed to the user, so never say "take a look" '
|
|
88
|
+
+ 'or otherwise refer to the image as something the user can see. To analyze an image that lives at a URL, '
|
|
89
|
+
+ 'first use `download <url>` to save it to the working directory, then call view_image on the saved path. '
|
|
90
|
+
+ 'Unsupported formats, oversized files (image_max_bytes), or missing paths return a clear error, not a crash.',
|
|
91
|
+
parameters: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {
|
|
94
|
+
path: {
|
|
95
|
+
type: 'string',
|
|
96
|
+
description: 'Absolute or relative path to a local image file (PNG/JPEG/GIF/WebP) to load into vision context',
|
|
97
|
+
},
|
|
61
98
|
},
|
|
62
99
|
required: ['path'],
|
|
63
100
|
},
|
|
@@ -228,7 +265,7 @@ const TOOL_SPECS = {
|
|
|
228
265
|
},
|
|
229
266
|
|
|
230
267
|
edit_file: {
|
|
231
|
-
description: 'Replace
|
|
268
|
+
description: 'Replace a single line, or a contiguous range of lines, in a file by 1-based line number. With end_line set, lines line..end_line are replaced wholesale by content (which may itself span multiple lines) — a regex-free way to swap a block: read the slice with read_file (start_line/end_line + show_line_numbers), then replace that exact range. For large block edits this and a literal replace_in_file are the two supported paths.',
|
|
232
269
|
parameters: {
|
|
233
270
|
type: 'object',
|
|
234
271
|
properties: {
|
|
@@ -238,12 +275,17 @@ const TOOL_SPECS = {
|
|
|
238
275
|
},
|
|
239
276
|
line: {
|
|
240
277
|
type: 'integer',
|
|
241
|
-
description: '1-based line number of the line to replace',
|
|
278
|
+
description: '1-based line number of the (first) line to replace',
|
|
279
|
+
minimum: 1,
|
|
280
|
+
},
|
|
281
|
+
end_line: {
|
|
282
|
+
type: 'integer',
|
|
283
|
+
description: 'Optional 1-based last line of the range to replace (inclusive). Omit for a single-line edit. Must be >= line and within the file.',
|
|
242
284
|
minimum: 1,
|
|
243
285
|
},
|
|
244
286
|
content: {
|
|
245
287
|
type: 'string',
|
|
246
|
-
description: 'New text for the target line;
|
|
288
|
+
description: 'New text for the target line or range; may contain newlines to expand a range into several lines. Trailing newline is added automatically when the file is rejoined.',
|
|
247
289
|
default: '',
|
|
248
290
|
},
|
|
249
291
|
},
|
|
@@ -289,8 +331,72 @@ const TOOL_SPECS = {
|
|
|
289
331
|
},
|
|
290
332
|
},
|
|
291
333
|
|
|
334
|
+
grep: {
|
|
335
|
+
description: 'Search file contents by regular expression across the working tree and return the actual matches (file:line:text), so you can navigate to the relevant lines and read only a slice instead of whole files. Honors .gitignore, skips binary files and node_modules/.git. Prefers ripgrep when available with an identical pure-Node fallback. output_mode selects what is returned: "content" (default) gives file:line:text per match ("show me the lines"); "files_with_matches" gives just the unique file paths ("which files contain this"); "count" gives per-file and total match counts ("how many") — count/files_with_matches return almost nothing, so prefer them when you do not need the line text. Results are bounded by head_limit (default 100); when more matches exist than are shown, a truncation notice tells you how many were omitted — narrow the pattern, switch to count/files_with_matches, or raise head_limit.',
|
|
336
|
+
parameters: {
|
|
337
|
+
type: 'object',
|
|
338
|
+
properties: {
|
|
339
|
+
pattern: {
|
|
340
|
+
type: 'string',
|
|
341
|
+
description: 'Regular expression to search for (matched per line)',
|
|
342
|
+
},
|
|
343
|
+
path: {
|
|
344
|
+
type: 'string',
|
|
345
|
+
description: 'Optional search target: a FILE path (search just that file — absolute or relative, like search_in_file), a DIRECTORY path (search recursively under it), or a GLOB filter limiting which files in the working tree are searched, e.g. "*.js" or "src/**/*.ts". A path that is neither an existing file nor directory is treated as a glob. If a supplied path/glob matches nothing to search, grep returns a diagnostic error rather than a silent zero-match result.',
|
|
346
|
+
},
|
|
347
|
+
ignore_case: {
|
|
348
|
+
type: 'boolean',
|
|
349
|
+
description: 'Case-insensitive match when true',
|
|
350
|
+
default: false,
|
|
351
|
+
},
|
|
352
|
+
output_mode: {
|
|
353
|
+
type: 'string',
|
|
354
|
+
enum: ['content', 'files_with_matches', 'count'],
|
|
355
|
+
description: 'What to return: "content" = file:line:text per match (default); "files_with_matches" = unique file paths only; "count" = match counts per file and total. Use count/files_with_matches when you only need how many / which files.',
|
|
356
|
+
default: 'content',
|
|
357
|
+
},
|
|
358
|
+
head_limit: {
|
|
359
|
+
type: 'integer',
|
|
360
|
+
description: 'Maximum number of results to serialize into context (default 100): match lines in content mode, files in files_with_matches/count mode. Excess is omitted with a truncation notice.',
|
|
361
|
+
},
|
|
362
|
+
offset: {
|
|
363
|
+
type: 'integer',
|
|
364
|
+
description: 'Number of results to skip before serializing (for paging through a large match set). Default 0.',
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
required: ['pattern'],
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
|
|
371
|
+
glob: {
|
|
372
|
+
description: 'List files matching a glob pattern (relative paths). Skips node_modules/.git and hidden entries. The file list is bounded by head_limit (default 100); when more files match than are shown, a truncation notice reports how many were omitted — narrow the glob or raise head_limit.',
|
|
373
|
+
parameters: {
|
|
374
|
+
type: 'object',
|
|
375
|
+
properties: {
|
|
376
|
+
pattern: {
|
|
377
|
+
type: 'string',
|
|
378
|
+
description: 'Glob pattern such as "*.ts" or "src/**/*.js"; matches the basename when it has no slash, otherwise the relative path',
|
|
379
|
+
},
|
|
380
|
+
path: {
|
|
381
|
+
type: 'string',
|
|
382
|
+
description: 'Base directory to search from; defaults to the current working directory',
|
|
383
|
+
default: '.',
|
|
384
|
+
},
|
|
385
|
+
head_limit: {
|
|
386
|
+
type: 'integer',
|
|
387
|
+
description: 'Maximum number of file paths to serialize into context (default 100). Excess is omitted with a truncation notice.',
|
|
388
|
+
},
|
|
389
|
+
offset: {
|
|
390
|
+
type: 'integer',
|
|
391
|
+
description: 'Number of file paths to skip before serializing (for paging). Default 0.',
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
required: ['pattern'],
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
|
|
292
398
|
replace_in_file: {
|
|
293
|
-
description: '
|
|
399
|
+
description: 'Exact string replacement in a file (Claude Code Edit model). The search text is matched LITERALLY by default — byte-for-byte, NO regex — so paste the exact verbatim code, including all whitespace and indentation, even if it contains ( ) { } . [ ] $ etc. The match must be UNIQUE: if the search string is not found the call ERRORS and the file is unchanged; if it appears more than once the call ERRORS (asking you to add surrounding context) unless you set replace_all:true. Returns the honest number of replacements made. Set regex:true to interpret the search as a JavaScript regular expression instead (bounded: long or backtracking-prone regexes are rejected). For block edits by line number, see line-range edit_file.',
|
|
294
400
|
parameters: {
|
|
295
401
|
type: 'object',
|
|
296
402
|
properties: {
|
|
@@ -300,16 +406,26 @@ const TOOL_SPECS = {
|
|
|
300
406
|
},
|
|
301
407
|
search: {
|
|
302
408
|
type: 'string',
|
|
303
|
-
description: '
|
|
409
|
+
description: 'Exact text to find. Matched literally (verbatim, no regex) unless regex:true is set. Include enough surrounding context that it appears EXACTLY ONCE in the file, or set replace_all:true.',
|
|
304
410
|
},
|
|
305
411
|
replace: {
|
|
306
412
|
type: 'string',
|
|
307
|
-
description: 'Replacement string
|
|
413
|
+
description: 'Replacement string. In literal mode (default) it is inserted as raw text. In regex mode it supports the standard $1, $2, $& back-references.',
|
|
308
414
|
default: '',
|
|
309
415
|
},
|
|
416
|
+
replace_all: {
|
|
417
|
+
type: 'boolean',
|
|
418
|
+
description: 'Replace ALL occurrences instead of requiring a unique match. Without this, matching more than one occurrence is an error. The result reports the actual number replaced.',
|
|
419
|
+
default: false,
|
|
420
|
+
},
|
|
421
|
+
regex: {
|
|
422
|
+
type: 'boolean',
|
|
423
|
+
description: 'Opt into regex mode: interpret search as a JavaScript regular expression (bounded by a length cap + nested-quantifier guard). Default false = literal exact match. The uniqueness guard still applies in regex mode (use the g flag or replace_all to replace multiple).',
|
|
424
|
+
default: false,
|
|
425
|
+
},
|
|
310
426
|
flags: {
|
|
311
427
|
type: 'string',
|
|
312
|
-
description: 'Regex flags, any combination of g/i/m/s/u/y
|
|
428
|
+
description: 'Regex flags (only meaningful with regex:true), any combination of g/i/m/s/u/y. Without "g" (and without replace_all) the match must be unique.',
|
|
313
429
|
default: '',
|
|
314
430
|
},
|
|
315
431
|
},
|
|
@@ -384,7 +500,7 @@ const TOOL_SPECS = {
|
|
|
384
500
|
},
|
|
385
501
|
|
|
386
502
|
http_get: {
|
|
387
|
-
description: '
|
|
503
|
+
description: 'Fetch a web page. The `mode` parameter selects how much processing to apply: "summarized" (default) runs the page through Readability + Markdown conversion and a secondary-model summary so only a compact result enters context — use it for find/answer tasks; "extracted" returns the extracted main-content Markdown without the summary — use it to read an article/doc verbatim or grab an exact snippet/quote; "raw" bypasses extraction entirely and returns the ORIGINAL fetched HTML/content (token-capped) — use it to analyze a page\'s HTML/CSS/JavaScript/markup/structure, which extraction destroys. Plain-text/JSON responses pass through unchanged in summarized/extracted modes. Optionally pass intent to focus the summary. The deprecated booleans summarize=false and raw=true are aliases for mode="extracted". DATA EXTRACTION: to pull SPECIFIC VALUES out of a page (hex colors, version strings, URLs, IDs, counts), do NOT use http_get — use `download` (or sandboxed `curl`) to save the page to the working directory, then `grep` it (e.g. `grep -oiE \'#[0-9a-f]{6}\'` for hex colors) so only the matching lines enter context, not the whole page. Reserve mode="raw" for when you actually need to read the markup structure; it loads the entire (token-capped) page and is expensive for simple value extraction. For SPA / asset-heavy sites the values often live in linked assets (e.g. /_nuxt/*.css or *.js, bundled stylesheets) rather than the top-level HTML — download+grep those asset URLs.',
|
|
388
504
|
parameters: {
|
|
389
505
|
type: 'object',
|
|
390
506
|
properties: {
|
|
@@ -392,11 +508,46 @@ const TOOL_SPECS = {
|
|
|
392
508
|
type: 'string',
|
|
393
509
|
description: 'HTTP or HTTPS URL to fetch',
|
|
394
510
|
},
|
|
511
|
+
mode: {
|
|
512
|
+
type: 'string',
|
|
513
|
+
enum: ['summarized', 'extracted', 'raw'],
|
|
514
|
+
description: 'How to process the page. "summarized" (default): extract main content, convert to Markdown, then summarize with a secondary model — for find/answer tasks. "extracted": extracted Markdown of the main content, no summary — for reading a doc/article verbatim or an exact snippet. "raw": the original fetched HTML/content, token-capped, NO extraction — for analyzing the page\'s HTML/CSS/JS/structure.',
|
|
515
|
+
},
|
|
516
|
+
summarize: {
|
|
517
|
+
type: 'boolean',
|
|
518
|
+
description: 'DEPRECATED alias (prefer mode). false ≡ mode="extracted" (extracted Markdown, no summary). An explicit mode wins over this.',
|
|
519
|
+
},
|
|
520
|
+
raw: {
|
|
521
|
+
type: 'boolean',
|
|
522
|
+
description: 'DEPRECATED alias (prefer mode). true ≡ mode="extracted". NOTE: this does NOT return raw HTML — use mode="raw" for the original markup. An explicit mode wins over this.',
|
|
523
|
+
},
|
|
524
|
+
intent: {
|
|
525
|
+
type: 'string',
|
|
526
|
+
description: 'Why you are fetching this page; focuses the summary on answering it.',
|
|
527
|
+
},
|
|
395
528
|
},
|
|
396
529
|
required: ['url'],
|
|
397
530
|
},
|
|
398
531
|
},
|
|
399
532
|
|
|
533
|
+
web_search: {
|
|
534
|
+
description: 'Search the web and return a compact list of candidate results — each with a title, url, and snippet. Use this to FIND relevant pages when you do not already know the URL, instead of guessing URLs. IMPORTANT: this returns only short snippets, NOT page content. Read the snippets, pick the single most relevant result (or the few that matter), and then fetch ONLY those with http_get to read them — use http_get mode="summarized" for reading/answering and mode="raw" only for analyzing markup. Do NOT fetch every result; that wastes context. Optional count caps how many results to return (the backend clamps it).',
|
|
535
|
+
parameters: {
|
|
536
|
+
type: 'object',
|
|
537
|
+
properties: {
|
|
538
|
+
query: {
|
|
539
|
+
type: 'string',
|
|
540
|
+
description: 'The search query.',
|
|
541
|
+
},
|
|
542
|
+
count: {
|
|
543
|
+
type: 'integer',
|
|
544
|
+
description: 'Optional maximum number of results to return (clamped by the backend; defaults to the backend default).',
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
required: ['query'],
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
|
|
400
551
|
ask_user: {
|
|
401
552
|
description: 'Prompt the interactive user for input and return their answer; auto-answers "y" in non-TTY mode.',
|
|
402
553
|
parameters: {
|
|
@@ -462,6 +613,109 @@ const TOOL_SPECS = {
|
|
|
462
613
|
},
|
|
463
614
|
},
|
|
464
615
|
|
|
616
|
+
// ──────────────────────────────────────────────────────────────────
|
|
617
|
+
// Native git tools (Task 5.1). Implemented by shelling out to `git`
|
|
618
|
+
// through the same sandbox + deny-list chokepoint as <shell>, but they
|
|
619
|
+
// parse output into structured results. Read-only: git_status, git_diff,
|
|
620
|
+
// git_log (and the LIST ops of git_branch / git_worktree). Mutating:
|
|
621
|
+
// git_add, git_commit, git_branch (create/delete), git_checkout,
|
|
622
|
+
// git_worktree (add/remove). NOTE: git operations are NOT reversible via
|
|
623
|
+
// /rewind — checkpoints (Task 4.3) snapshot file-tool mutations only.
|
|
624
|
+
// ──────────────────────────────────────────────────────────────────
|
|
625
|
+
|
|
626
|
+
git_status: {
|
|
627
|
+
description: 'Show the working-tree status as structured lists of staged, unstaged, and untracked files plus the current branch. Read-only.',
|
|
628
|
+
parameters: { type: 'object', properties: {}, required: [] },
|
|
629
|
+
},
|
|
630
|
+
|
|
631
|
+
git_diff: {
|
|
632
|
+
description: 'Show changes as a structured diff (files, hunks, +/- counts). Defaults to unstaged changes; set staged=true for the staged (index) diff. Read-only.',
|
|
633
|
+
parameters: {
|
|
634
|
+
type: 'object',
|
|
635
|
+
properties: {
|
|
636
|
+
staged: { type: 'boolean', description: 'Diff the staged (index) changes instead of the working tree', default: false },
|
|
637
|
+
path: { type: 'string', description: 'Optional path to limit the diff to' },
|
|
638
|
+
},
|
|
639
|
+
required: [],
|
|
640
|
+
},
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
git_log: {
|
|
644
|
+
description: 'List recent commits as structured records (hash, author, email, date, subject). Read-only.',
|
|
645
|
+
parameters: {
|
|
646
|
+
type: 'object',
|
|
647
|
+
properties: {
|
|
648
|
+
count: { type: 'integer', description: 'Maximum number of commits to return (default 20)', minimum: 1, default: 20 },
|
|
649
|
+
path: { type: 'string', description: 'Optional path to limit history to' },
|
|
650
|
+
},
|
|
651
|
+
required: [],
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
|
|
655
|
+
git_add: {
|
|
656
|
+
description: 'Stage changes for commit. Provide `paths` (one or more files) or set all=true to stage everything. Mutating — requires approval.',
|
|
657
|
+
parameters: {
|
|
658
|
+
type: 'object',
|
|
659
|
+
properties: {
|
|
660
|
+
paths: { type: 'string', description: 'File path(s) to stage; space-separated for multiple' },
|
|
661
|
+
all: { type: 'boolean', description: 'Stage all changes (git add -A)', default: false },
|
|
662
|
+
},
|
|
663
|
+
required: [],
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
|
|
667
|
+
git_commit: {
|
|
668
|
+
description: 'Create a commit with the given message and return the new commit hash and branch. The message is required and must be non-empty (the tool never invents one). Mutating — requires approval. NOTE: a commit is not reversible via /rewind.',
|
|
669
|
+
parameters: {
|
|
670
|
+
type: 'object',
|
|
671
|
+
properties: {
|
|
672
|
+
message: { type: 'string', description: 'Commit message (required, non-empty)' },
|
|
673
|
+
all: { type: 'boolean', description: 'Automatically stage modified/deleted tracked files before committing (git commit -a)', default: false },
|
|
674
|
+
},
|
|
675
|
+
required: ['message'],
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
|
|
679
|
+
git_branch: {
|
|
680
|
+
description: 'List branches (no name — read-only) or create/delete a branch (name given — mutating). Set delete=true to delete (force=true for -D). Branch creation/deletion is not reversible via /rewind.',
|
|
681
|
+
parameters: {
|
|
682
|
+
type: 'object',
|
|
683
|
+
properties: {
|
|
684
|
+
name: { type: 'string', description: 'Branch name to create or delete; omit to list branches' },
|
|
685
|
+
delete: { type: 'boolean', description: 'Delete the named branch instead of creating it', default: false },
|
|
686
|
+
force: { type: 'boolean', description: 'Force the operation (e.g. delete an unmerged branch with -D)', default: false },
|
|
687
|
+
},
|
|
688
|
+
required: [],
|
|
689
|
+
},
|
|
690
|
+
},
|
|
691
|
+
|
|
692
|
+
git_checkout: {
|
|
693
|
+
description: 'Switch to a branch or ref (set create=true to create and switch with -b). Mutating — requires approval. WARNING: checkout can overwrite or discard uncommitted changes in the working tree, and those changes are NOT recoverable via /rewind (checkpoints snapshot file-tool mutations only, not git operations).',
|
|
694
|
+
parameters: {
|
|
695
|
+
type: 'object',
|
|
696
|
+
properties: {
|
|
697
|
+
name: { type: 'string', description: 'Branch or ref to switch to' },
|
|
698
|
+
create: { type: 'boolean', description: 'Create the branch and switch to it (git checkout -b)', default: false },
|
|
699
|
+
force: { type: 'boolean', description: 'Force checkout, discarding local changes (git checkout -f)', default: false },
|
|
700
|
+
},
|
|
701
|
+
required: ['name'],
|
|
702
|
+
},
|
|
703
|
+
},
|
|
704
|
+
|
|
705
|
+
git_worktree: {
|
|
706
|
+
description: 'Manage linked worktrees for running parallel agents in isolated working trees. op=list (read-only) lists worktrees; op=add creates one (optionally on a new `branch`); op=remove deletes one (force=true to override). add/remove are mutating and not reversible via /rewind.',
|
|
707
|
+
parameters: {
|
|
708
|
+
type: 'object',
|
|
709
|
+
properties: {
|
|
710
|
+
op: { type: 'string', description: 'Operation: list | add | remove', enum: ['list', 'add', 'remove'], default: 'list' },
|
|
711
|
+
path: { type: 'string', description: 'Worktree directory path (required for add/remove)' },
|
|
712
|
+
branch: { type: 'string', description: 'For add: create and check out this new branch in the worktree' },
|
|
713
|
+
force: { type: 'boolean', description: 'For remove: remove even with local changes', default: false },
|
|
714
|
+
},
|
|
715
|
+
required: [],
|
|
716
|
+
},
|
|
717
|
+
},
|
|
718
|
+
|
|
465
719
|
// ──────────────────────────────────────────────────────────────────
|
|
466
720
|
// Parser-wrapper tags. These are XML envelopes that carry other tool
|
|
467
721
|
// calls; they are not invocable tools themselves. Entries exist only
|