Bold questions

This commit is contained in:
Ian Gulliver
2026-10-14 19:35:34 -07:00
parent ab4c3d2c6f
commit 1ea055682b
54 changed files with 3696 additions and 762 deletions
+146 -7
View File
@@ -110,15 +110,49 @@ paths:
schema: { $ref: "#/components/schemas/Task" }
"404": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/complete:
/api/tasks/{taskId}/unmerged:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
get:
operationId: getUnmerged
description: What the task's worktree holds that its project's default branch doesn't.
responses:
"200":
description: The unmerged changes.
content:
application/json:
schema: { $ref: "#/components/schemas/Unmerged" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/merge:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
post:
operationId: completeTask
description: Removes the task's worktree and branch. The task's record and events remain.
operationId: mergeTask
description: >
Squashes the task's worktree, uncommitted changes included, into one commit on the project's
default branch, fast-forwards the project's checkout to it, then removes the worktree and branch.
Nothing is pushed. Refused while a turn is running or queued, and on merge conflicts.
responses:
"200":
description: The completed task.
description: The merged task.
content:
application/json:
schema: { $ref: "#/components/schemas/Task" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/discard:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
post:
operationId: discardTask
description: Removes the task's worktree and branch without merging. The task's record and events remain.
responses:
"200":
description: The discarded task.
content:
application/json:
schema: { $ref: "#/components/schemas/Task" }
@@ -144,6 +178,48 @@ paths:
items: { $ref: "#/components/schemas/Event" }
"404": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/changes:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
get:
operationId: getTaskChanges
description: >
Everything in the task's worktree (committed, staged, unstaged and untracked, respecting .gitignore) as a tree,
compared with the merge-base of the task branch and the project's default branch, or with since when given.
The worktree's own index is not touched.
parameters:
- { name: since, in: query, required: false, schema: { type: string }, description: "A commit to compare with instead of the merge-base, such as a user.message event's head." }
responses:
"200":
description: Per-file stats.
content:
application/json:
schema: { $ref: "#/components/schemas/TaskChanges" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/diff:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
get:
operationId: getTaskDiff
description: The unified diff of one file between a base and tree from getTaskChanges.
parameters:
- { name: base, in: query, required: true, schema: { type: string } }
- { name: tree, in: query, required: true, schema: { type: string } }
- { name: path, in: query, required: true, schema: { type: string } }
- { name: old_path, in: query, required: false, schema: { type: string } }
responses:
"200":
description: The patch.
content:
application/json:
schema: { $ref: "#/components/schemas/FileDiff" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/sessions:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
@@ -210,6 +286,23 @@ paths:
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/sessions/{sessionId}/compact:
parameters:
- { name: sessionId, in: path, required: true, schema: { type: string } }
post:
operationId: compactSession
description: >
Asks the idle session's agent for a handoff (goal, decisions, state, dead ends, open questions, files). When that turn ends,
the session is completed and a new session on the same task and model starts with the handoff as its first message.
responses:
"202":
description: The handoff turn was started or queued.
content:
application/json:
schema: { $ref: "#/components/schemas/AgentSession" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/sessions/{sessionId}/interrupt:
parameters:
- { name: sessionId, in: path, required: true, schema: { type: string } }
@@ -367,10 +460,24 @@ components:
branch: { type: string }
worktree_path: { type: string }
base_ref: { type: string }
status: { type: string, enum: [active, completed] }
status:
type: string
enum: [active, merged, discarded]
x-enum-varnames: [TaskStatusActive, TaskStatusMerged, TaskStatusDiscarded]
created_by: { type: string }
created_at: { type: string, format: date-time }
completed_at: { type: string, format: date-time }
closed_at: { type: string, format: date-time, description: When the task was merged or discarded. }
merge_commit: { type: string, description: "merged: the squash commit on the default branch; empty when there was nothing to merge." }
Unmerged:
type: object
required: [commits, files, insertions, deletions, uncommitted]
properties:
commits: { type: integer, description: Commits on the task branch that aren't on the default branch. }
files: { type: integer, description: Files that differ from the merge base, uncommitted changes included. }
insertions: { type: integer }
deletions: { type: integer }
uncommitted: { type: integer, description: Paths with uncommitted changes in the worktree. }
TaskCreate:
type: object
@@ -378,6 +485,34 @@ components:
properties:
title: { type: string }
TaskChanges:
type: object
required: [base, tree, files]
properties:
base: { type: string, description: Merge-base commit of the task branch and the default branch. }
tree: { type: string, description: Tree of the worktree as if everything were staged. }
files:
type: array
items: { $ref: "#/components/schemas/FileChange" }
FileChange:
type: object
required: [path, status, additions, deletions, binary]
properties:
path: { type: string }
old_path: { type: string, description: "renamed: the path before the rename." }
status: { type: string, enum: [added, modified, deleted, renamed, type_changed] }
additions: { type: integer }
deletions: { type: integer }
binary: { type: boolean }
FileDiff:
type: object
required: [path, patch]
properties:
path: { type: string }
patch: { type: string }
AgentSession:
type: object
required: [id, task_id, vendor, model, vendor_session_id, state, role, created_by, created_at]
@@ -390,6 +525,7 @@ components:
state:
type: string
enum: [idle, queued, running, completed]
x-enum-varnames: [AgentSessionStateIdle, AgentSessionStateQueued, AgentSessionStateRunning, AgentSessionStateCompleted]
description: queued means a turn is waiting for a free slot under the concurrency caps.
role: { type: string, enum: [implementer] }
created_by: { type: string }
@@ -407,6 +543,9 @@ components:
required: [text]
properties:
text: { type: string }
model:
type: string
description: Model for this turn and later ones. When it differs from the session's model, the session switches before the message is sent.
Attachment:
type: object
@@ -444,7 +583,7 @@ components:
type: object
description: >
question: context, question, why_blocked, options, recommended_option, attachments.
report: done, next_steps, risks, deviations.
report: text (the final message of a turn that ended normally).
session_error: error.
rate_limited: vendor, rate_limit (the vendor's rate-limit status), error.
state: { $ref: "#/components/schemas/InboxState" }