Add server-side workflows with YAML files, task freeze and lead tools

This commit is contained in:
Ian Gulliver
2026-10-15 21:17:58 -07:00
parent 2f02f5ac3c
commit 2ce10a6c65
19 changed files with 1293 additions and 199 deletions
+199
View File
@@ -214,6 +214,25 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/tasks/{taskId}/workflow": {
parameters: {
query?: never;
header?: never;
path: {
taskId: string;
};
cookie?: never;
};
/** @description The workflow the task froze when it was created, as it was then. Later edits and deletes of the workflow don't change it. */
get: operations["getTaskWorkflow"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/tasks/{taskId}/unmerged": {
parameters: {
query?: never;
@@ -733,6 +752,41 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/workflows": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get: operations["listWorkflows"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/workflows/{name}": {
parameters: {
query?: never;
header?: never;
path: {
name: string;
};
cookie?: never;
};
get: operations["getWorkflow"];
/** @description Creates or replaces the workflow from its file, a WorkflowDefinition as YAML (or JSON). The name is one line of 1 to 100 characters. Tasks that already froze the workflow keep their copy. */
put: operations["putWorkflow"];
post?: never;
delete: operations["deleteWorkflow"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
}
export type webhooks = Record<string, never>;
export interface components {
@@ -814,6 +868,8 @@ export interface components {
* @description When Merge was requested while another task in the project was merging; absent once the merge starts or when none is held.
*/
merge_queued_at?: string;
/** @description The name of the workflow the task froze at creation (getTaskWorkflow has its copy); absent for a task without one. */
workflow?: string;
};
Todo: {
/** @description Whether the default branch has a TODO.md at its root. */
@@ -852,6 +908,35 @@ export interface components {
};
TaskCreate: {
title: string;
/** @description The name of a workflow for the task to freeze: it keeps a copy of the workflow's definition as it is now. */
workflow?: string;
};
WorkflowSummary: {
name: string;
description: string;
};
/** @description A workflow's file, which holds everything but its name: a sequence of stages run in order. Sent and returned as YAML. */
WorkflowDefinition: {
description?: string;
stages: components["schemas"]["Stage"][];
};
Stage: {
/** @description One line of 1 to 100 characters, unique within the workflow. */
name: string;
/**
* @description Must be the vendor that runs model (gpt-* models run on Codex, every other model on Claude Code).
* @enum {string}
*/
vendor: "claude" | "codex";
model: string;
/** @description The stage agent's instructions. */
prompt: string;
};
/** @description The workflow a task froze when it was created, as it was then. */
TaskWorkflow: {
name: string;
/** @description The WorkflowDefinition as YAML. */
definition: string;
};
TaskChanges: {
/** @description The commit or tree compared with: the merge-base of the task branch and the default branch, since, or the previous snapshot's tree. */
@@ -1589,6 +1674,29 @@ export interface operations {
404: components["responses"]["Error"];
};
};
getTaskWorkflow: {
parameters: {
query?: never;
header?: never;
path: {
taskId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The frozen workflow. */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["TaskWorkflow"];
};
};
404: components["responses"]["Error"];
};
};
getUnmerged: {
parameters: {
query?: never;
@@ -2342,4 +2450,95 @@ export interface operations {
};
};
};
listWorkflows: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Every workflow's name and description, by name. */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WorkflowSummary"][];
};
};
};
};
getWorkflow: {
parameters: {
query?: never;
header?: never;
path: {
name: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The workflow's file: its WorkflowDefinition as YAML, as an attachment named after it. */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/yaml": string;
};
};
404: components["responses"]["Error"];
};
};
putWorkflow: {
parameters: {
query?: never;
header?: never;
path: {
name: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/yaml": string;
};
};
responses: {
/** @description The stored workflow. */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WorkflowSummary"];
};
};
400: components["responses"]["Error"];
};
};
deleteWorkflow: {
parameters: {
query?: never;
header?: never;
path: {
name: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Deleted. Tasks that froze it keep their copy. */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
404: components["responses"]["Error"];
};
};
}