Add show_page and show_file, and let file tools reach any path

This commit is contained in:
Ian Gulliver
2026-10-21 18:29:01 -07:00
parent 585c8ba5f8
commit 524bc0252e
11 changed files with 540 additions and 496 deletions
+12 -15
View File
@@ -718,8 +718,8 @@ paths:
get:
operationId: getTaskImage
description: >
An image file from the task's worktree, for Markdown images and image attachments. path is absolute or relative
to the worktree; after resolving symlinks it must be inside the worktree. PNG, JPEG, GIF, WebP and SVG, chosen by extension.
An image file on the server, for Markdown images and image attachments. path is absolute or relative
to the task's worktree. PNG, JPEG, GIF, WebP and SVG, chosen by extension.
parameters:
- { name: path, in: query, required: true, schema: { type: string } }
responses:
@@ -732,7 +732,6 @@ paths:
image/webp: { schema: { type: string, format: binary } }
image/svg+xml: { schema: { type: string, format: binary } }
"400": { $ref: "#/components/responses/Error" }
"403": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
@@ -763,11 +762,10 @@ paths:
get:
operationId: getTaskDir
description: >
One directory of the task's worktree, directories first, then by name. Entries named .git are left out;
gitignored entries are included and marked.
A path that leaves the worktree, through .. or a symlink, is refused.
One directory on the server, directories first, then by name. Entries named .git are left out;
gitignored entries inside the task's worktree are included and marked.
parameters:
- { name: path, in: query, required: false, schema: { type: string }, description: "Slash-separated, relative to the worktree root; empty or absent for the root." }
- { name: path, in: query, required: false, schema: { type: string }, description: "Slash-separated, absolute or relative to the task's worktree root; empty or absent for the root." }
responses:
"200":
description: The directory's entries.
@@ -784,10 +782,9 @@ paths:
get:
operationId: getTaskFile
description: >
A regular file in the task's worktree. Text is returned up to a size limit; binary files return no content.
A path that leaves the worktree, through .. or a symlink, is refused.
A regular file on the server. Text is returned up to a size limit; binary files return no content.
parameters:
- { name: path, in: query, required: true, schema: { type: string }, description: "Slash-separated, relative to the worktree root." }
- { name: path, in: query, required: true, schema: { type: string }, description: "Slash-separated, absolute or relative to the task's worktree root." }
responses:
"200":
description: The file.
@@ -804,12 +801,11 @@ paths:
get:
operationId: getTaskRaw
description: >
A regular file in the task's worktree, whole, with a content type chosen by its extension: an HTML page in the
A regular file on the server, whole, with a content type chosen by its extension: an HTML page in the
app's Page view and the stylesheets, scripts and images it loads. The response carries a sandbox
Content-Security-Policy, so a page opened from this address directly can't act on the API as its viewer.
A path that leaves the worktree, through .. or a symlink, is refused.
parameters:
- { name: path, in: query, required: true, schema: { type: string }, description: "Slash-separated, relative to the worktree root." }
- { name: path, in: query, required: true, schema: { type: string }, description: "Slash-separated, absolute or relative to the task's worktree root." }
responses:
"200":
description: The file's bytes.
@@ -2342,13 +2338,14 @@ components:
description: Work a task agent, or a merge, asks a connected Mac to do, sent over /api/clients/connect.
properties:
id: { type: string }
op: { type: string, enum: [bash, exec, upload, download, read_file, write_file, hands, sign] }
op: { type: string, enum: [bash, exec, upload, download, read_file, write_file, hands, sign, open_page, open_file] }
command: { type: string, description: "bash, exec: run with zsh as a login shell in the home directory, in its own process group." }
timeout_ms: { type: integer, description: "bash, exec, sign: kill the process group after this long." }
ident: { type: string, description: "sign: the committer, as \"Name <email>\", to sign as when the Mac's git config has no user.signingkey." }
transfer: { type: string, description: "upload: the transfer id to get from /api/clients/transfers/{transferId}. download: the transfer id to put the archive to." }
dest: { type: string, description: "upload: where the archive's one entry ends up, absolute or starting with ~/; whatever is there is replaced." }
path: { type: string, description: "download, read_file, write_file: the file (or, for download, file or directory) on the client, absolute or starting with ~/." }
path: { type: string, description: "download, read_file, write_file: the file (or, for download, file or directory) on the client, absolute or starting with ~/. open_page, open_file: the file (or, for open_file, file or directory, a directory ending in /) on the server, absolute or relative to the task's worktree." }
task: { type: string, description: "open_page, open_file: the task beside whose transcript the app shows the file: open_page in its page view, open_file in its Files tab." }
data: { type: string, format: byte, description: "write_file: the file's new contents; parent directories are created. sign: the unsigned commit object, which the Mac signs with the program its git config names for its gpg.format (openpgp or x509), called as git calls it." }
tool: { type: string, description: "hands: the byre-hands tool to call." }
arguments: