Add a read-only Files tab browsing a task's worktree

This commit is contained in:
Ian Gulliver
2026-10-15 07:31:53 -07:00
parent 4ca6f88861
commit de5b944a0c
16 changed files with 1460 additions and 123 deletions
+75
View File
@@ -372,6 +372,47 @@ paths:
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/dir:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
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.
parameters:
- { name: path, in: query, required: false, schema: { type: string }, description: "Slash-separated, relative to the worktree root; empty or absent for the root." }
responses:
"200":
description: The directory's entries.
content:
application/json:
schema: { $ref: "#/components/schemas/DirListing" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/file:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
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.
parameters:
- { name: path, in: query, required: true, schema: { type: string }, description: "Slash-separated, relative to the worktree root." }
responses:
"200":
description: The file.
content:
application/json:
schema: { $ref: "#/components/schemas/FileContent" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/snapshots:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
@@ -783,6 +824,40 @@ components:
path: { type: string }
patch: { type: string }
DirListing:
type: object
required: [path, entries, truncated]
properties:
path: { type: string, description: "The directory, relative to the worktree root; empty for the root." }
entries:
type: array
items: { $ref: "#/components/schemas/DirEntry" }
truncated: { type: boolean, description: The directory has more entries than were returned. }
DirEntry:
type: object
required: [name, type, symlink, size, ignored]
properties:
name: { type: string }
ignored: { type: boolean, description: "git ignores the entry: .gitignore and the other exclude files match it or a directory above it." }
type:
type: string
enum: [dir, file, other]
x-enum-varnames: [DirEntryTypeDir, DirEntryTypeFile, DirEntryTypeOther]
description: "What the entry is, following a symlink that stays in the worktree. other: a symlink that leaves the worktree or points nowhere, or a device, socket or pipe."
symlink: { type: boolean }
size: { type: integer, format: int64, description: "file: its size in bytes." }
FileContent:
type: object
required: [path, size, binary, truncated, text]
properties:
path: { type: string }
size: { type: integer, format: int64 }
binary: { type: boolean, description: The file isn't UTF-8 text; text is empty. }
truncated: { type: boolean, description: "text holds only the start of the file." }
text: { type: string }
Snapshot:
type: object
required: [id, task_id, agent_session_id, n, commit_sha, tree_sha, event_seq, trigger, created_at]