@oh-my-pi/pi-coding-agent 15.4.3 → 15.5.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/CHANGELOG.md +81 -5
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/cli/auth-broker-cli.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +8 -0
- package/dist/types/config/settings-schema.d.ts +42 -1
- package/dist/types/edit/index.d.ts +2 -0
- package/dist/types/extensibility/custom-tools/types.d.ts +8 -2
- package/dist/types/extensibility/hooks/types.d.ts +4 -0
- package/dist/types/hashline/executor.d.ts +6 -3
- package/dist/types/lsp/index.d.ts +9 -1
- package/dist/types/mcp/client.d.ts +2 -1
- package/dist/types/mcp/oauth-discovery.d.ts +4 -3
- package/dist/types/mcp/timeout.d.ts +9 -0
- package/dist/types/mcp/types.d.ts +1 -1
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/streaming-output.d.ts +1 -1
- package/dist/types/task/index.d.ts +2 -0
- package/dist/types/task/types.d.ts +4 -0
- package/dist/types/tools/approval.d.ts +46 -0
- package/dist/types/tools/ask.d.ts +1 -0
- package/dist/types/tools/ast-edit.d.ts +2 -0
- package/dist/types/tools/ast-grep.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +11 -1
- package/dist/types/tools/browser.d.ts +2 -0
- package/dist/types/tools/calculator.d.ts +1 -0
- package/dist/types/tools/checkpoint.d.ts +2 -0
- package/dist/types/tools/debug.d.ts +9 -1
- package/dist/types/tools/eval.d.ts +2 -0
- package/dist/types/tools/find.d.ts +10 -0
- package/dist/types/tools/gh.d.ts +2 -1
- package/dist/types/tools/hindsight-recall.d.ts +1 -0
- package/dist/types/tools/hindsight-reflect.d.ts +1 -0
- package/dist/types/tools/hindsight-retain.d.ts +1 -0
- package/dist/types/tools/inspect-image.d.ts +1 -0
- package/dist/types/tools/irc.d.ts +1 -0
- package/dist/types/tools/job.d.ts +1 -0
- package/dist/types/tools/read.d.ts +1 -0
- package/dist/types/tools/recipe/index.d.ts +1 -0
- package/dist/types/tools/render-mermaid.d.ts +1 -0
- package/dist/types/tools/resolve.d.ts +1 -0
- package/dist/types/tools/search-tool-bm25.d.ts +1 -0
- package/dist/types/tools/search.d.ts +1 -0
- package/dist/types/tools/ssh.d.ts +2 -0
- package/dist/types/tools/todo-write.d.ts +1 -0
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/tools/yield.d.ts +1 -0
- package/dist/types/web/search/index.d.ts +1 -0
- package/package.json +7 -7
- package/src/cli/args.ts +14 -0
- package/src/cli/auth-broker-cli.ts +171 -22
- package/src/commands/auth-broker.ts +3 -0
- package/src/commands/launch.ts +16 -0
- package/src/config/mcp-schema.json +2 -2
- package/src/config/model-registry.ts +19 -4
- package/src/config/prompt-templates.ts +0 -125
- package/src/config/settings-schema.ts +59 -1
- package/src/config/settings.ts +2 -1
- package/src/dap/session.ts +35 -2
- package/src/discovery/builtin.ts +2 -2
- package/src/discovery/mcp-json.ts +1 -1
- package/src/edit/index.ts +26 -0
- package/src/edit/modes/patch.ts +1 -1
- package/src/edit/streaming.ts +12 -2
- package/src/exec/bash-executor.ts +6 -2
- package/src/extensibility/custom-commands/bundled/review/index.ts +18 -14
- package/src/extensibility/custom-tools/types.ts +16 -2
- package/src/extensibility/extensions/wrapper.ts +36 -1
- package/src/extensibility/hooks/types.ts +8 -1
- package/src/hashline/apply.ts +47 -2
- package/src/hashline/executor.ts +46 -24
- package/src/internal-urls/docs-index.generated.ts +8 -7
- package/src/lsp/edits.ts +82 -29
- package/src/lsp/index.ts +38 -1
- package/src/lsp/utils.ts +1 -1
- package/src/main.ts +6 -0
- package/src/mcp/client.ts +8 -6
- package/src/mcp/oauth-discovery.ts +120 -32
- package/src/mcp/oauth-flow.ts +34 -6
- package/src/mcp/timeout.ts +59 -0
- package/src/mcp/transports/http.ts +42 -44
- package/src/mcp/transports/stdio.ts +8 -5
- package/src/mcp/types.ts +1 -1
- package/src/modes/components/hook-editor.ts +11 -3
- package/src/modes/components/mcp-add-wizard.ts +6 -2
- package/src/modes/components/model-selector.ts +33 -11
- package/src/modes/controllers/command-controller.ts +6 -4
- package/src/modes/controllers/mcp-command-controller.ts +8 -4
- package/src/prompts/review-custom-request.md +22 -0
- package/src/prompts/review-headless-request.md +16 -0
- package/src/prompts/review-request.md +2 -3
- package/src/prompts/system/project-prompt.md +4 -0
- package/src/prompts/tools/debug.md +1 -0
- package/src/prompts/tools/find.md +4 -2
- package/src/prompts/tools/hashline.md +43 -93
- package/src/sdk.ts +47 -73
- package/src/session/agent-session.ts +93 -27
- package/src/session/streaming-output.ts +1 -1
- package/src/slash-commands/helpers/usage-report.ts +3 -1
- package/src/task/executor.ts +11 -0
- package/src/task/index.ts +19 -0
- package/src/task/render.ts +12 -2
- package/src/task/types.ts +4 -0
- package/src/tools/approval.ts +185 -0
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit.ts +25 -1
- package/src/tools/ast-grep.ts +1 -0
- package/src/tools/bash.ts +69 -1
- package/src/tools/browser/tab-supervisor.ts +1 -1
- package/src/tools/browser.ts +15 -0
- package/src/tools/calculator.ts +1 -0
- package/src/tools/checkpoint.ts +2 -0
- package/src/tools/debug.ts +38 -0
- package/src/tools/eval.ts +15 -0
- package/src/tools/find.ts +17 -8
- package/src/tools/gh.ts +21 -1
- package/src/tools/hindsight-recall.ts +1 -0
- package/src/tools/hindsight-reflect.ts +1 -0
- package/src/tools/hindsight-retain.ts +1 -0
- package/src/tools/image-gen.ts +1 -0
- package/src/tools/inspect-image.ts +1 -0
- package/src/tools/irc.ts +1 -0
- package/src/tools/job.ts +1 -0
- package/src/tools/path-utils.ts +14 -1
- package/src/tools/read.ts +1 -0
- package/src/tools/recipe/index.ts +1 -0
- package/src/tools/render-mermaid.ts +1 -0
- package/src/tools/report-tool-issue.ts +1 -0
- package/src/tools/resolve.ts +1 -0
- package/src/tools/review.ts +1 -0
- package/src/tools/search-tool-bm25.ts +1 -0
- package/src/tools/search.ts +1 -0
- package/src/tools/ssh.ts +8 -0
- package/src/tools/todo-write.ts +1 -0
- package/src/tools/write.ts +12 -1
- package/src/tools/yield.ts +1 -0
- package/src/web/search/index.ts +2 -0
package/src/tools/find.ts
CHANGED
|
@@ -59,11 +59,15 @@ const MAX_GLOB_TIMEOUT_MS = 60_000;
|
|
|
59
59
|
* Commas inside brace expansion (`{a,b}`) are legitimate glob syntax and
|
|
60
60
|
* must pass through.
|
|
61
61
|
*/
|
|
62
|
-
function validateFindPathInputs(paths: readonly string[]): void {
|
|
62
|
+
export function validateFindPathInputs(paths: readonly string[]): void {
|
|
63
63
|
for (const entry of paths) {
|
|
64
64
|
let braceDepth = 0;
|
|
65
65
|
for (let i = 0; i < entry.length; i++) {
|
|
66
66
|
const ch = entry.charCodeAt(i);
|
|
67
|
+
if (ch === 0x5c /* \ */ && i + 1 < entry.length) {
|
|
68
|
+
i++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
67
71
|
if (ch === 0x7b /* { */) braceDepth++;
|
|
68
72
|
else if (ch === 0x7d /* } */) {
|
|
69
73
|
if (braceDepth > 0) braceDepth--;
|
|
@@ -115,6 +119,7 @@ export interface FindToolOptions {
|
|
|
115
119
|
|
|
116
120
|
export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
|
|
117
121
|
readonly name = "find";
|
|
122
|
+
readonly approval = "read" as const;
|
|
118
123
|
readonly summary = "Find files and directories matching a glob pattern";
|
|
119
124
|
readonly loadMode = "discoverable";
|
|
120
125
|
readonly label = "Find";
|
|
@@ -304,6 +309,7 @@ export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
|
|
|
304
309
|
|
|
305
310
|
let matches: natives.GlobMatch[];
|
|
306
311
|
const onUpdateMatches: string[] = [];
|
|
312
|
+
const onUpdateMtimes: number[] = [];
|
|
307
313
|
const updateIntervalMs = 200;
|
|
308
314
|
let lastUpdate = 0;
|
|
309
315
|
const emitUpdate = () => {
|
|
@@ -323,9 +329,10 @@ export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
|
|
|
323
329
|
});
|
|
324
330
|
};
|
|
325
331
|
const onMatch = (err: Error | null, match: natives.GlobMatch | null) => {
|
|
326
|
-
if (err ||
|
|
332
|
+
if (err || combinedSignal.aborted || !match?.path) return;
|
|
327
333
|
const relativePath = formatMatchPath(match.path, match.fileType);
|
|
328
334
|
onUpdateMatches.push(relativePath);
|
|
335
|
+
onUpdateMtimes.push(match.mtime ?? 0);
|
|
329
336
|
emitUpdate();
|
|
330
337
|
};
|
|
331
338
|
|
|
@@ -335,7 +342,6 @@ export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
|
|
|
335
342
|
{
|
|
336
343
|
pattern: globPattern,
|
|
337
344
|
path: searchPath,
|
|
338
|
-
fileType: natives.FileType.File,
|
|
339
345
|
hidden: includeHidden,
|
|
340
346
|
maxResults: effectiveLimit,
|
|
341
347
|
sortByMtime: true,
|
|
@@ -371,15 +377,18 @@ export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
|
|
|
371
377
|
// instead of throwing — empty results after a multi-second wait force the
|
|
372
378
|
// caller to retry blind, which is the worst possible outcome.
|
|
373
379
|
const seen = new Set<string>();
|
|
374
|
-
const partial: string
|
|
375
|
-
for (
|
|
380
|
+
const partial: Array<{ p: string; m: number }> = [];
|
|
381
|
+
for (let i = 0; i < onUpdateMatches.length; i++) {
|
|
382
|
+
const entry = onUpdateMatches[i];
|
|
376
383
|
if (seen.has(entry)) continue;
|
|
377
384
|
seen.add(entry);
|
|
378
|
-
partial.push(entry);
|
|
385
|
+
partial.push({ p: entry, m: onUpdateMtimes[i] ?? 0 });
|
|
379
386
|
}
|
|
387
|
+
partial.sort((a, b) => b.m - a.m);
|
|
388
|
+
const sortedPaths = partial.map(e => e.p);
|
|
380
389
|
const seconds = timeoutMs % 1000 === 0 ? `${timeoutMs / 1000}` : (timeoutMs / 1000).toFixed(1);
|
|
381
|
-
const notice = `find timed out after ${seconds}s; returning ${
|
|
382
|
-
return buildResult(
|
|
390
|
+
const notice = `find timed out after ${seconds}s; returning ${sortedPaths.length} partial matches — increase timeout or narrow pattern`;
|
|
391
|
+
return buildResult(sortedPaths, { notice, forceTruncated: true });
|
|
383
392
|
}
|
|
384
393
|
|
|
385
394
|
const relativized: string[] = [];
|
package/src/tools/gh.ts
CHANGED
|
@@ -2,7 +2,13 @@ import * as fs from "node:fs/promises";
|
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { scheduler } from "node:timers/promises";
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
AgentTool,
|
|
7
|
+
AgentToolContext,
|
|
8
|
+
AgentToolResult,
|
|
9
|
+
AgentToolUpdateCallback,
|
|
10
|
+
ToolApprovalDecision,
|
|
11
|
+
} from "@oh-my-pi/pi-agent-core";
|
|
6
12
|
|
|
7
13
|
import { getWorktreeDir, hashPath, isEnoent, prompt, untilAborted } from "@oh-my-pi/pi-utils";
|
|
8
14
|
import * as z from "zod/v4";
|
|
@@ -196,6 +202,15 @@ const RUN_URL_PATTERN = /^https:\/\/github\.com\/([^/]+\/[^/]+)\/actions\/runs\/
|
|
|
196
202
|
const RUN_SUCCESS_CONCLUSIONS = new Set(["success", "neutral", "skipped"]);
|
|
197
203
|
const RUN_FAILURE_CONCLUSIONS = new Set(["failure", "timed_out", "cancelled", "action_required", "startup_failure"]);
|
|
198
204
|
const JOB_FAILURE_CONCLUSIONS = new Set(["failure", "timed_out", "cancelled", "action_required"]);
|
|
205
|
+
const GITHUB_READONLY_OPS: ReadonlySet<string> = new Set([
|
|
206
|
+
"repo_view",
|
|
207
|
+
"search_issues",
|
|
208
|
+
"search_prs",
|
|
209
|
+
"search_code",
|
|
210
|
+
"search_commits",
|
|
211
|
+
"search_repos",
|
|
212
|
+
"run_watch",
|
|
213
|
+
]);
|
|
199
214
|
|
|
200
215
|
const githubSchema = z
|
|
201
216
|
.object({
|
|
@@ -2344,6 +2359,11 @@ function buildTextResult(
|
|
|
2344
2359
|
|
|
2345
2360
|
export class GithubTool implements AgentTool<typeof githubSchema, GhToolDetails> {
|
|
2346
2361
|
readonly name = "github";
|
|
2362
|
+
readonly approval = (args: unknown): ToolApprovalDecision => {
|
|
2363
|
+
const rawOp = (args as Partial<GithubInput>).op;
|
|
2364
|
+
const op = typeof rawOp === "string" ? rawOp : "";
|
|
2365
|
+
return GITHUB_READONLY_OPS.has(op) ? "read" : "exec";
|
|
2366
|
+
};
|
|
2347
2367
|
readonly summary = "Interact with GitHub issues, pull requests, and repositories";
|
|
2348
2368
|
readonly loadMode = "discoverable";
|
|
2349
2369
|
readonly label = "GitHub";
|
|
@@ -13,6 +13,7 @@ export type HindsightRecallParams = z.infer<typeof hindsightRecallSchema>;
|
|
|
13
13
|
|
|
14
14
|
export class HindsightRecallTool implements AgentTool<typeof hindsightRecallSchema> {
|
|
15
15
|
readonly name = "recall";
|
|
16
|
+
readonly approval = "read" as const;
|
|
16
17
|
readonly label = "Recall";
|
|
17
18
|
readonly description = recallDescription;
|
|
18
19
|
readonly parameters = hindsightRecallSchema;
|
|
@@ -14,6 +14,7 @@ export type HindsightReflectParams = z.infer<typeof hindsightReflectSchema>;
|
|
|
14
14
|
|
|
15
15
|
export class HindsightReflectTool implements AgentTool<typeof hindsightReflectSchema> {
|
|
16
16
|
readonly name = "reflect";
|
|
17
|
+
readonly approval = "read" as const;
|
|
17
18
|
readonly label = "Reflect";
|
|
18
19
|
readonly description = reflectDescription;
|
|
19
20
|
readonly parameters = hindsightReflectSchema;
|
|
@@ -18,6 +18,7 @@ const hindsightRetainSchema = z.object({
|
|
|
18
18
|
export type HindsightRetainParams = z.infer<typeof hindsightRetainSchema>;
|
|
19
19
|
export class HindsightRetainTool implements AgentTool<typeof hindsightRetainSchema> {
|
|
20
20
|
readonly name = "retain";
|
|
21
|
+
readonly approval = "read" as const;
|
|
21
22
|
readonly label = "Retain";
|
|
22
23
|
readonly description = retainDescription;
|
|
23
24
|
readonly parameters = hindsightRetainSchema;
|
package/src/tools/image-gen.ts
CHANGED
|
@@ -901,6 +901,7 @@ export const imageGenTool: CustomTool<typeof imageGenSchema, ImageGenToolDetails
|
|
|
901
901
|
name: "generate_image",
|
|
902
902
|
label: "GenerateImage",
|
|
903
903
|
strict: false,
|
|
904
|
+
approval: "write",
|
|
904
905
|
description: prompt.render(imageGenDescription),
|
|
905
906
|
parameters: imageGenSchema,
|
|
906
907
|
async execute(_toolCallId, params, _onUpdate, ctx, signal) {
|
|
@@ -33,6 +33,7 @@ export interface InspectImageToolDetails {
|
|
|
33
33
|
|
|
34
34
|
export class InspectImageTool implements AgentTool<typeof inspectImageSchema, InspectImageToolDetails> {
|
|
35
35
|
readonly name = "inspect_image";
|
|
36
|
+
readonly approval = "read" as const;
|
|
36
37
|
readonly label = "InspectImage";
|
|
37
38
|
readonly loadMode = "discoverable";
|
|
38
39
|
readonly summary = "Describe or analyze an image file";
|
package/src/tools/irc.ts
CHANGED
|
@@ -54,6 +54,7 @@ export interface IrcDetails {
|
|
|
54
54
|
|
|
55
55
|
export class IrcTool implements AgentTool<typeof ircSchema, IrcDetails> {
|
|
56
56
|
readonly name = "irc";
|
|
57
|
+
readonly approval = "read" as const;
|
|
57
58
|
readonly label = "IRC";
|
|
58
59
|
readonly summary = "Send and receive messages between agents over IRC-like channels";
|
|
59
60
|
readonly description: string;
|
package/src/tools/job.ts
CHANGED
|
@@ -67,6 +67,7 @@ export interface JobToolDetails {
|
|
|
67
67
|
|
|
68
68
|
export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
|
|
69
69
|
readonly name = "job";
|
|
70
|
+
readonly approval = "read" as const;
|
|
70
71
|
readonly label = "Job";
|
|
71
72
|
readonly summary = "Manage long-running background jobs (async bash/python)";
|
|
72
73
|
readonly description: string;
|
package/src/tools/path-utils.ts
CHANGED
|
@@ -29,6 +29,13 @@ const INTERNAL_SCHEMES_WITH_SELECTORS: Record<string, true> = {
|
|
|
29
29
|
rule: true,
|
|
30
30
|
skill: true,
|
|
31
31
|
};
|
|
32
|
+
// Schemes whose resource URIs are server-defined and may legitimately end
|
|
33
|
+
// with selector-shaped tails (e.g. `:raw`, `:conflicts`, `:1-50`, `/:raw`).
|
|
34
|
+
// `McpProtocolHandler` resolves by exact URI match (`r.uri === uri`), so
|
|
35
|
+
// peeling syntactically can make valid resources unreachable. Keep these
|
|
36
|
+
// schemes opaque; selector support for them needs a resolver-aware path that
|
|
37
|
+
// tries the exact URI before interpreting any suffix as a read selector.
|
|
38
|
+
const OPAQUE_RESOURCE_SCHEMES: ReadonlySet<string> = new Set(["mcp"]);
|
|
32
39
|
const INTERNAL_URL_SCHEME_RE = /^([a-z][a-z0-9+.-]*):\/\//i;
|
|
33
40
|
const NARROW_NO_BREAK_SPACE = "\u202F";
|
|
34
41
|
const TOP_LEVEL_INTERNAL_URL_PREFIXES = [
|
|
@@ -173,10 +180,16 @@ export function splitPathAndSel(rawPath: string): { path: string; sel?: string }
|
|
|
173
180
|
*
|
|
174
181
|
* Falls back to the input unchanged when nothing matches.
|
|
175
182
|
*/
|
|
183
|
+
|
|
176
184
|
export function splitInternalUrlSel(rawPath: string): { path: string; sel?: string } {
|
|
177
185
|
const schemeMatch = rawPath.match(INTERNAL_URL_SCHEME_RE);
|
|
178
186
|
if (!schemeMatch) return { path: rawPath };
|
|
179
|
-
|
|
187
|
+
const scheme = schemeMatch[1].toLowerCase();
|
|
188
|
+
// Opaque schemes (mcp://, etc.) carry server-defined resource URIs that may
|
|
189
|
+
// legitimately end in selector-shaped tails. Forward verbatim — see
|
|
190
|
+
// OPAQUE_RESOURCE_SCHEMES.
|
|
191
|
+
if (OPAQUE_RESOURCE_SCHEMES.has(scheme)) return { path: rawPath };
|
|
192
|
+
if (!INTERNAL_SCHEMES_WITH_SELECTORS[scheme]) return { path: rawPath };
|
|
180
193
|
|
|
181
194
|
const schemeEnd = schemeMatch[0].length;
|
|
182
195
|
let path = rawPath;
|
package/src/tools/read.ts
CHANGED
|
@@ -718,6 +718,7 @@ interface ResolvedSqliteReadPath {
|
|
|
718
718
|
*/
|
|
719
719
|
export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
720
720
|
readonly name = "read";
|
|
721
|
+
readonly approval = "read" as const;
|
|
721
722
|
readonly label = "Read";
|
|
722
723
|
readonly loadMode = "essential";
|
|
723
724
|
readonly description: string;
|
|
@@ -27,6 +27,7 @@ type RecipeRenderResult = {
|
|
|
27
27
|
export class RecipeTool implements AgentTool<typeof recipeSchema, BashToolDetails, Theme> {
|
|
28
28
|
readonly name = "recipe";
|
|
29
29
|
readonly label = "Run";
|
|
30
|
+
readonly approval = "exec" as const;
|
|
30
31
|
readonly description: string;
|
|
31
32
|
readonly parameters = recipeSchema;
|
|
32
33
|
readonly strict = true;
|
|
@@ -34,6 +34,7 @@ export interface RenderMermaidToolDetails {
|
|
|
34
34
|
|
|
35
35
|
export class RenderMermaidTool implements AgentTool<typeof renderMermaidSchema, RenderMermaidToolDetails> {
|
|
36
36
|
readonly name = "render_mermaid";
|
|
37
|
+
readonly approval = "read" as const;
|
|
37
38
|
readonly label = "RenderMermaid";
|
|
38
39
|
readonly summary = "Render a Mermaid diagram to an image";
|
|
39
40
|
readonly description: string;
|
|
@@ -466,6 +466,7 @@ export function createReportToolIssueTool(session: ToolSession, activeBuiltinNam
|
|
|
466
466
|
name: "report_tool_issue",
|
|
467
467
|
label: "Report Tool Issue",
|
|
468
468
|
strict: false,
|
|
469
|
+
approval: "write",
|
|
469
470
|
description: "Report unexpected tool behavior for automated QA tracking.",
|
|
470
471
|
parameters: buildReportToolIssueParams(activeBuiltinNames),
|
|
471
472
|
intent: "omit",
|
package/src/tools/resolve.ts
CHANGED
|
@@ -160,6 +160,7 @@ export async function runResolveInvocation(
|
|
|
160
160
|
|
|
161
161
|
export class ResolveTool implements AgentTool<typeof resolveSchema, ResolveToolDetails> {
|
|
162
162
|
readonly name = "resolve";
|
|
163
|
+
readonly approval = "read" as const;
|
|
163
164
|
readonly label = "Resolve";
|
|
164
165
|
readonly hidden = true;
|
|
165
166
|
readonly description: string;
|
package/src/tools/review.ts
CHANGED
|
@@ -122,6 +122,7 @@ export function parseReportFindingDetails(value: unknown): ReportFindingDetails
|
|
|
122
122
|
export const reportFindingTool: AgentTool<typeof ReportFindingParams, ReportFindingDetails, Theme> = {
|
|
123
123
|
name: "report_finding",
|
|
124
124
|
label: "Report Finding",
|
|
125
|
+
approval: "read",
|
|
125
126
|
description: "Report a code review finding. Use this for each issue found. Call yield when done.",
|
|
126
127
|
parameters: ReportFindingParams,
|
|
127
128
|
intent: "omit",
|
|
@@ -180,6 +180,7 @@ function renderFallbackResult(text: string, theme: Theme): Component {
|
|
|
180
180
|
*/
|
|
181
181
|
export class SearchToolBm25Tool implements AgentTool<typeof searchToolBm25Schema, SearchToolBm25Details> {
|
|
182
182
|
readonly name = "search_tool_bm25";
|
|
183
|
+
readonly approval = "read" as const;
|
|
183
184
|
readonly label = "SearchTools";
|
|
184
185
|
readonly loadMode = "essential";
|
|
185
186
|
get description(): string {
|
package/src/tools/search.ts
CHANGED
|
@@ -218,6 +218,7 @@ type SearchParams = z.infer<typeof searchSchema>;
|
|
|
218
218
|
|
|
219
219
|
export class SearchTool implements AgentTool<typeof searchSchema, SearchToolDetails> {
|
|
220
220
|
readonly name = "search";
|
|
221
|
+
readonly approval = "read" as const;
|
|
221
222
|
readonly label = "Search";
|
|
222
223
|
readonly loadMode = "discoverable";
|
|
223
224
|
readonly summary = "Search file contents using ripgrep (fast text search)";
|
package/src/tools/ssh.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { executeSSH } from "../ssh/ssh-executor";
|
|
|
16
16
|
import { renderStatusLine } from "../tui";
|
|
17
17
|
import { CachedOutputBlock } from "../tui/output-block";
|
|
18
18
|
import type { ToolSession } from ".";
|
|
19
|
+
import { truncateForPrompt } from "./approval";
|
|
19
20
|
import { formatStyledTruncationWarning, type OutputMeta, stripOutputNotice } from "./output-meta";
|
|
20
21
|
import { ToolError } from "./tool-errors";
|
|
21
22
|
import { toolResult } from "./tool-result";
|
|
@@ -120,6 +121,13 @@ type SshToolParams = z.infer<typeof sshSchema>;
|
|
|
120
121
|
|
|
121
122
|
export class SshTool implements AgentTool<typeof sshSchema, SSHToolDetails> {
|
|
122
123
|
readonly name = "ssh";
|
|
124
|
+
readonly approval = "exec" as const;
|
|
125
|
+
readonly formatApprovalDetails = (args: unknown): string[] => {
|
|
126
|
+
const params = args as Partial<SshToolParams>;
|
|
127
|
+
const host = typeof params.host === "string" ? params.host : "(missing)";
|
|
128
|
+
const command = typeof params.command === "string" ? params.command : "(missing)";
|
|
129
|
+
return [`Host: ${truncateForPrompt(host)}`, `Command: ${truncateForPrompt(command)}`];
|
|
130
|
+
};
|
|
123
131
|
readonly summary = "Execute a command on a remote host over SSH";
|
|
124
132
|
readonly loadMode = "discoverable";
|
|
125
133
|
readonly label = "SSH";
|
package/src/tools/todo-write.ts
CHANGED
|
@@ -493,6 +493,7 @@ function formatSummary(phases: TodoPhase[], errors: string[]): string {
|
|
|
493
493
|
|
|
494
494
|
export class TodoWriteTool implements AgentTool<typeof todoWriteSchema, TodoWriteToolDetails> {
|
|
495
495
|
readonly name = "todo_write";
|
|
496
|
+
readonly approval = "read" as const;
|
|
496
497
|
readonly label = "Todo Write";
|
|
497
498
|
readonly summary = "Write a structured todo list to track progress within a session";
|
|
498
499
|
readonly description: string;
|
package/src/tools/write.ts
CHANGED
|
@@ -16,6 +16,7 @@ import writeDescription from "../prompts/tools/write.md" with { type: "text" };
|
|
|
16
16
|
import type { ToolSession } from "../sdk";
|
|
17
17
|
import { Ellipsis, Hasher, type RenderCache, renderStatusLine, truncateToWidth } from "../tui";
|
|
18
18
|
import { resolveFileDisplayMode } from "../utils/file-display-mode";
|
|
19
|
+
import { truncateForPrompt } from "./approval";
|
|
19
20
|
import { parseArchivePathCandidates } from "./archive-reader";
|
|
20
21
|
import { assertEditableFile } from "./auto-generated-guard";
|
|
21
22
|
import {
|
|
@@ -27,7 +28,7 @@ import {
|
|
|
27
28
|
} from "./conflict-detect";
|
|
28
29
|
import { invalidateFsScanAfterWrite } from "./fs-cache-invalidation";
|
|
29
30
|
import { type OutputMeta, outputMeta } from "./output-meta";
|
|
30
|
-
import { formatPathRelativeToCwd } from "./path-utils";
|
|
31
|
+
import { formatPathRelativeToCwd, isInternalUrlPath } from "./path-utils";
|
|
31
32
|
import { enforcePlanModeWrite, resolvePlanPath } from "./plan-mode-guard";
|
|
32
33
|
import {
|
|
33
34
|
formatDiagnostics,
|
|
@@ -184,6 +185,16 @@ function parseSqliteWriteTarget(subPath: string, queryString: string): { table:
|
|
|
184
185
|
*/
|
|
185
186
|
export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails> {
|
|
186
187
|
readonly name = "write";
|
|
188
|
+
readonly approval = (args: unknown) => {
|
|
189
|
+
const rawPath = (args as Partial<WriteParams>).path;
|
|
190
|
+
return typeof rawPath === "string" && isInternalUrlPath(rawPath) ? "read" : "write";
|
|
191
|
+
};
|
|
192
|
+
readonly formatApprovalDetails = (args: unknown): string[] => {
|
|
193
|
+
const params = args as Partial<WriteParams>;
|
|
194
|
+
const targetPath = typeof params.path === "string" ? params.path : "(missing)";
|
|
195
|
+
const content = typeof params.content === "string" ? params.content : "";
|
|
196
|
+
return [`Path: ${truncateForPrompt(targetPath)}`, `Content:\n${truncateForPrompt(content)}`];
|
|
197
|
+
};
|
|
187
198
|
readonly label = "Write";
|
|
188
199
|
readonly description: string;
|
|
189
200
|
readonly parameters = writeSchema;
|
package/src/tools/yield.ts
CHANGED
|
@@ -99,6 +99,7 @@ const MAX_SCHEMA_RETRIES = 3;
|
|
|
99
99
|
|
|
100
100
|
export class YieldTool implements AgentTool<TSchema, YieldDetails> {
|
|
101
101
|
readonly name = "yield";
|
|
102
|
+
readonly approval = "read" as const;
|
|
102
103
|
readonly label = "Submit Result";
|
|
103
104
|
readonly description =
|
|
104
105
|
"Finish the task with structured JSON output. Call exactly once at the end of the task.\n\n" +
|
package/src/web/search/index.ts
CHANGED
|
@@ -224,6 +224,7 @@ export async function runSearchQuery(
|
|
|
224
224
|
*/
|
|
225
225
|
export class WebSearchTool implements AgentTool<typeof webSearchSchema, SearchRenderDetails> {
|
|
226
226
|
readonly name = "web_search";
|
|
227
|
+
readonly approval = "read" as const;
|
|
227
228
|
readonly label = "Web Search";
|
|
228
229
|
readonly description: string;
|
|
229
230
|
readonly parameters = webSearchSchema;
|
|
@@ -258,6 +259,7 @@ export const webSearchCustomTool: CustomTool<typeof webSearchSchema, SearchRende
|
|
|
258
259
|
description: prompt.render(webSearchDescription),
|
|
259
260
|
parameters: webSearchSchema,
|
|
260
261
|
|
|
262
|
+
approval: "read",
|
|
261
263
|
async execute(
|
|
262
264
|
toolCallId: string,
|
|
263
265
|
params: SearchToolParams,
|