feat(foundry): checkpoint actor and workspace refactor

This commit is contained in:
Nathan Flurry 2026-03-15 10:20:27 -07:00
parent 32f3c6c3bc
commit dbe57d45b9
81 changed files with 3441 additions and 2332 deletions

View file

@ -3,7 +3,7 @@ CREATE TABLE `task` (
`branch_name` text,
`title` text,
`task` text NOT NULL,
`provider_id` text NOT NULL,
`sandbox_provider_id` text NOT NULL,
`status` text NOT NULL,
`agent_type` text DEFAULT 'claude',
`pr_submitted` integer DEFAULT 0,
@ -19,13 +19,17 @@ CREATE TABLE `task_runtime` (
`active_switch_target` text,
`active_cwd` text,
`status_message` text,
`git_state_json` text,
`git_state_updated_at` integer,
`provision_stage` text,
`provision_stage_updated_at` integer,
`updated_at` integer NOT NULL,
CONSTRAINT "task_runtime_singleton_id_check" CHECK("task_runtime"."id" = 1)
);
--> statement-breakpoint
CREATE TABLE `task_sandboxes` (
`sandbox_id` text PRIMARY KEY NOT NULL,
`provider_id` text NOT NULL,
`sandbox_provider_id` text NOT NULL,
`sandbox_actor_id` text,
`switch_target` text NOT NULL,
`cwd` text,
@ -34,10 +38,15 @@ CREATE TABLE `task_sandboxes` (
`updated_at` integer NOT NULL
);
--> statement-breakpoint
CREATE TABLE `task_workbench_sessions` (
CREATE TABLE `task_workspace_sessions` (
`session_id` text PRIMARY KEY NOT NULL,
`sandbox_session_id` text,
`session_name` text NOT NULL,
`model` text NOT NULL,
`status` text DEFAULT 'ready' NOT NULL,
`error_message` text,
`transcript_json` text DEFAULT '[]' NOT NULL,
`transcript_updated_at` integer,
`unread` integer DEFAULT 0 NOT NULL,
`draft_text` text DEFAULT '' NOT NULL,
`draft_attachments_json` text DEFAULT '[]' NOT NULL,

View file

@ -221,8 +221,8 @@
"uniqueConstraints": {},
"checkConstraints": {}
},
"task_workbench_sessions": {
"name": "task_workbench_sessions",
"task_workspace_sessions": {
"name": "task_workspace_sessions",
"columns": {
"session_id": {
"name": "session_id",

View file

@ -10,12 +10,6 @@ const journal = {
tag: "0000_charming_maestro",
breakpoints: true,
},
{
idx: 1,
when: 1773810000000,
tag: "0001_sandbox_provider_columns",
breakpoints: true,
},
],
} as const;
@ -27,10 +21,8 @@ export default {
\`branch_name\` text,
\`title\` text,
\`task\` text NOT NULL,
\`provider_id\` text NOT NULL,
\`sandbox_provider_id\` text NOT NULL,
\`status\` text NOT NULL,
\`agent_type\` text DEFAULT 'claude',
\`pr_submitted\` integer DEFAULT 0,
\`created_at\` integer NOT NULL,
\`updated_at\` integer NOT NULL,
CONSTRAINT "task_singleton_id_check" CHECK("task"."id" = 1)
@ -39,17 +31,17 @@ export default {
CREATE TABLE \`task_runtime\` (
\`id\` integer PRIMARY KEY NOT NULL,
\`active_sandbox_id\` text,
\`active_session_id\` text,
\`active_switch_target\` text,
\`active_cwd\` text,
\`status_message\` text,
\`git_state_json\` text,
\`git_state_updated_at\` integer,
\`updated_at\` integer NOT NULL,
CONSTRAINT "task_runtime_singleton_id_check" CHECK("task_runtime"."id" = 1)
);
--> statement-breakpoint
CREATE TABLE \`task_sandboxes\` (
\`sandbox_id\` text PRIMARY KEY NOT NULL,
\`provider_id\` text NOT NULL,
\`sandbox_provider_id\` text NOT NULL,
\`sandbox_actor_id\` text,
\`switch_target\` text NOT NULL,
\`cwd\` text,
@ -58,24 +50,21 @@ CREATE TABLE \`task_sandboxes\` (
\`updated_at\` integer NOT NULL
);
--> statement-breakpoint
CREATE TABLE \`task_workbench_sessions\` (
CREATE TABLE \`task_workspace_sessions\` (
\`session_id\` text PRIMARY KEY NOT NULL,
\`sandbox_session_id\` text,
\`session_name\` text NOT NULL,
\`model\` text NOT NULL,
\`unread\` integer DEFAULT 0 NOT NULL,
\`draft_text\` text DEFAULT '' NOT NULL,
\`draft_attachments_json\` text DEFAULT '[]' NOT NULL,
\`draft_updated_at\` integer,
\`status\` text DEFAULT 'ready' NOT NULL,
\`error_message\` text,
\`transcript_json\` text DEFAULT '[]' NOT NULL,
\`transcript_updated_at\` integer,
\`created\` integer DEFAULT 1 NOT NULL,
\`closed\` integer DEFAULT 0 NOT NULL,
\`thinking_since_ms\` integer,
\`created_at\` integer NOT NULL,
\`created_at\` integer NOT NULL,
\`updated_at\` integer NOT NULL
);
`,
m0001: `ALTER TABLE \`task\` RENAME COLUMN \`provider_id\` TO \`sandbox_provider_id\`;
--> statement-breakpoint
ALTER TABLE \`task_sandboxes\` RENAME COLUMN \`provider_id\` TO \`sandbox_provider_id\`;
`,
} as const,
};

View file

@ -11,8 +11,6 @@ export const task = sqliteTable(
task: text("task").notNull(),
sandboxProviderId: text("sandbox_provider_id").notNull(),
status: text("status").notNull(),
agentType: text("agent_type").default("claude"),
prSubmitted: integer("pr_submitted").default(0),
createdAt: integer("created_at").notNull(),
updatedAt: integer("updated_at").notNull(),
},
@ -24,14 +22,10 @@ export const taskRuntime = sqliteTable(
{
id: integer("id").primaryKey(),
activeSandboxId: text("active_sandbox_id"),
activeSessionId: text("active_session_id"),
activeSwitchTarget: text("active_switch_target"),
activeCwd: text("active_cwd"),
statusMessage: text("status_message"),
gitStateJson: text("git_state_json"),
gitStateUpdatedAt: integer("git_state_updated_at"),
provisionStage: text("provision_stage"),
provisionStageUpdatedAt: integer("provision_stage_updated_at"),
updatedAt: integer("updated_at").notNull(),
},
(table) => [check("task_runtime_singleton_id_check", sql`${table.id} = 1`)],
@ -54,12 +48,12 @@ export const taskSandboxes = sqliteTable("task_sandboxes", {
});
/**
* Coordinator index of workbench sessions within this task.
* Coordinator index of workspace sessions within this task.
* The task actor is the coordinator for sessions. Each row holds session
* metadata, model, status, transcript, and draft state. Sessions are
* sub-entities of the task no separate session actor in the DB.
*/
export const taskWorkbenchSessions = sqliteTable("task_workbench_sessions", {
export const taskWorkspaceSessions = sqliteTable("task_workspace_sessions", {
sessionId: text("session_id").notNull().primaryKey(),
sandboxSessionId: text("sandbox_session_id"),
sessionName: text("session_name").notNull(),
@ -68,11 +62,6 @@ export const taskWorkbenchSessions = sqliteTable("task_workbench_sessions", {
errorMessage: text("error_message"),
transcriptJson: text("transcript_json").notNull().default("[]"),
transcriptUpdatedAt: integer("transcript_updated_at"),
unread: integer("unread").notNull().default(0),
draftText: text("draft_text").notNull().default(""),
// Structured by the workbench composer attachment payload format.
draftAttachmentsJson: text("draft_attachments_json").notNull().default("[]"),
draftUpdatedAt: integer("draft_updated_at"),
created: integer("created").notNull().default(1),
closed: integer("closed").notNull().default(0),
thinkingSinceMs: integer("thinking_since_ms"),