From 05931d19bc0c161d0177c3f983d0cd903d5e8ae3 Mon Sep 17 00:00:00 2001 From: soryu Date: Fri, 16 Jan 2026 01:39:16 +0000 Subject: Fixup: add task contract type to frontend --- makima/docs/PLAN-resume-history-system.md | 4 +- makima/frontend/src/lib/api.ts | 50 +++++++++++++++++++- makima/frontend/src/routes/contracts.tsx | 22 ++++++++- .../migrations/20250117000000_history_tables.sql | 55 ---------------------- .../migrations/20250118000000_history_tables.sql | 55 ++++++++++++++++++++++ 5 files changed, 125 insertions(+), 61 deletions(-) delete mode 100644 makima/migrations/20250117000000_history_tables.sql create mode 100644 makima/migrations/20250118000000_history_tables.sql diff --git a/makima/docs/PLAN-resume-history-system.md b/makima/docs/PLAN-resume-history-system.md index 9e81c93..19d02f3 100644 --- a/makima/docs/PLAN-resume-history-system.md +++ b/makima/docs/PLAN-resume-history-system.md @@ -18,7 +18,7 @@ This document provides a detailed, actionable implementation plan for the Resume ### Task 1.1: Create Database Migrations **Files to Create:** -- `makima/migrations/20250117000000_history_tables.sql` +- `makima/migrations/20250118000000_history_tables.sql` **Schema Changes:** @@ -1243,7 +1243,7 @@ Phase 5 (Daemon) can be done in parallel with Phases 3-4 ### Files to Create -1. `makima/migrations/20250117000000_history_tables.sql` +1. `makima/migrations/20250118000000_history_tables.sql` 2. `makima/src/server/handlers/history.rs` ### Files to Modify diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts index 100a85a..1e62732 100644 --- a/makima/frontend/src/lib/api.ts +++ b/makima/frontend/src/lib/api.ts @@ -1415,7 +1415,7 @@ export async function deleteAccount( // ============================================================================= /** Contract type determines the workflow and required documents */ -export type ContractType = "simple" | "specification"; +export type ContractType = "simple" | "specification" | "task"; export type ContractPhase = "research" | "specify" | "plan" | "execute" | "review"; export type ContractStatus = "active" | "completed" | "archived"; export type RepositorySourceType = "remote" | "local" | "managed"; @@ -1426,12 +1426,17 @@ export function getValidPhases(contractType: ContractType): ContractPhase[] { if (contractType === "simple") { return ["plan", "execute"]; } + if (contractType === "task") { + return ["execute"]; + } return ["research", "specify", "plan", "execute", "review"]; } /** Get default initial phase for a contract type */ export function getDefaultPhase(contractType: ContractType): ContractPhase { - return contractType === "simple" ? "plan" : "research"; + if (contractType === "simple") return "plan"; + if (contractType === "task") return "execute"; + return "research"; } export interface ContractRepository { @@ -2047,3 +2052,44 @@ export async function deleteRepositoryHistory(id: string): Promise { throw new Error(`Failed to delete repository history: ${res.statusText}`); } } + +// ============================================================================= +// Adhoc Task Types (for one-off tasks without supervisor overhead) +// ============================================================================= + +/** Request payload for creating an adhoc (one-off) task */ +export interface AdhocTaskRequest { + /** Name/description of the task */ + name: string; + /** The plan/instructions for the task */ + plan: string; + /** Repository URL (optional) */ + repositoryUrl?: string; + /** Base branch to work from */ + baseBranch?: string; +} + +/** Response for adhoc task creation */ +export interface AdhocTaskResponse { + contract: ContractSummary; + task: Task; +} + +/** + * Create an adhoc (one-off) task without supervisor overhead. + * This creates a minimal "task" type contract with a single task. + * The contract auto-archives when the task completes. + */ +export async function createAdhocTask( + data: AdhocTaskRequest +): Promise { + const res = await authFetch(`${API_BASE}/api/v1/tasks/adhoc`, { + method: "POST", + body: JSON.stringify(data), + }); + if (!res.ok) { + const errorText = await res.text(); + throw new Error(`Failed to create adhoc task: ${errorText || res.statusText}`); + } + return res.json(); +} diff --git a/makima/frontend/src/routes/contracts.tsx b/makima/frontend/src/routes/contracts.tsx index 5e9bf60..8ed4ab5 100644 --- a/makima/frontend/src/routes/contracts.tsx +++ b/makima/frontend/src/routes/contracts.tsx @@ -471,6 +471,20 @@ function ContractsPageContent() { Contract Type
+

- {contractType === "simple" + {contractType === "task" + ? "Execute: One-off adhoc task with no supervisor (auto-archives on completion)" + : contractType === "simple" ? "Plan → Execute: Simple workflow with a plan document" : "Research → Specify → Plan → Execute → Review: Full specification-driven development with TDD"}

@@ -524,7 +540,9 @@ function ContractsPageContent() { ))}

- {contractType === "simple" + {contractType === "task" + ? "Task contracts always start in Execute phase" + : contractType === "simple" ? "Start in Plan to define what to build, or Execute if already planned" : "Skip earlier phases if you already have requirements defined"}

diff --git a/makima/migrations/20250117000000_history_tables.sql b/makima/migrations/20250117000000_history_tables.sql deleted file mode 100644 index 60e371c..0000000 --- a/makima/migrations/20250117000000_history_tables.sql +++ /dev/null @@ -1,55 +0,0 @@ --- History tables for Resume and History System --- Enables conversation rewind, snapshots, and unified event timeline - --- 1. Conversation Snapshots table --- Stores conversation state at specific points for rewind capability -CREATE TABLE IF NOT EXISTS conversation_snapshots ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, - checkpoint_id UUID REFERENCES task_checkpoints(id) ON DELETE SET NULL, - snapshot_type VARCHAR(50) NOT NULL, -- 'auto', 'manual', 'checkpoint' - message_count INTEGER NOT NULL, - conversation_state JSONB NOT NULL, -- Full conversation at this point - metadata JSONB, -- Additional context (token count, cost, etc.) - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX idx_conversation_snapshots_task ON conversation_snapshots(task_id); -CREATE INDEX idx_conversation_snapshots_checkpoint ON conversation_snapshots(checkpoint_id); -CREATE INDEX idx_conversation_snapshots_created ON conversation_snapshots(created_at DESC); - --- 2. History Events table --- Unified event stream for timeline views -CREATE TABLE IF NOT EXISTS history_events ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, - contract_id UUID REFERENCES contracts(id) ON DELETE CASCADE, - task_id UUID REFERENCES tasks(id) ON DELETE CASCADE, - event_type VARCHAR(50) NOT NULL, -- 'task', 'chat', 'checkpoint', 'phase', 'file' - event_subtype VARCHAR(50), -- Specific event: 'created', 'completed', 'message', etc. - phase VARCHAR(50), -- Contract phase when event occurred - event_data JSONB NOT NULL, -- Event-specific data - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - -CREATE INDEX idx_history_events_contract ON history_events(contract_id, created_at DESC); -CREATE INDEX idx_history_events_task ON history_events(task_id, created_at DESC); -CREATE INDEX idx_history_events_owner ON history_events(owner_id, created_at DESC); -CREATE INDEX idx_history_events_type ON history_events(event_type, created_at DESC); - --- 3. Alter task_checkpoints - add conversation snapshot reference -ALTER TABLE task_checkpoints - ADD COLUMN IF NOT EXISTS conversation_snapshot_id UUID REFERENCES conversation_snapshots(id) ON DELETE SET NULL; - --- 4. Alter tasks - add forking fields -ALTER TABLE tasks - ADD COLUMN IF NOT EXISTS forked_from_task_id UUID REFERENCES tasks(id) ON DELETE SET NULL, - ADD COLUMN IF NOT EXISTS forked_at_checkpoint_id UUID REFERENCES task_checkpoints(id) ON DELETE SET NULL; - -CREATE INDEX IF NOT EXISTS idx_tasks_forked_from ON tasks(forked_from_task_id) WHERE forked_from_task_id IS NOT NULL; - --- Comments for documentation -COMMENT ON TABLE conversation_snapshots IS 'Stores conversation state at specific points for rewind/resume capability'; -COMMENT ON TABLE history_events IS 'Unified event stream for timeline views across contracts and tasks'; -COMMENT ON COLUMN conversation_snapshots.snapshot_type IS 'Type: auto (periodic), manual (user-triggered), checkpoint (at git checkpoint)'; -COMMENT ON COLUMN history_events.event_type IS 'Category: task, chat, checkpoint, phase, file'; diff --git a/makima/migrations/20250118000000_history_tables.sql b/makima/migrations/20250118000000_history_tables.sql new file mode 100644 index 0000000..60e371c --- /dev/null +++ b/makima/migrations/20250118000000_history_tables.sql @@ -0,0 +1,55 @@ +-- History tables for Resume and History System +-- Enables conversation rewind, snapshots, and unified event timeline + +-- 1. Conversation Snapshots table +-- Stores conversation state at specific points for rewind capability +CREATE TABLE IF NOT EXISTS conversation_snapshots ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, + checkpoint_id UUID REFERENCES task_checkpoints(id) ON DELETE SET NULL, + snapshot_type VARCHAR(50) NOT NULL, -- 'auto', 'manual', 'checkpoint' + message_count INTEGER NOT NULL, + conversation_state JSONB NOT NULL, -- Full conversation at this point + metadata JSONB, -- Additional context (token count, cost, etc.) + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX idx_conversation_snapshots_task ON conversation_snapshots(task_id); +CREATE INDEX idx_conversation_snapshots_checkpoint ON conversation_snapshots(checkpoint_id); +CREATE INDEX idx_conversation_snapshots_created ON conversation_snapshots(created_at DESC); + +-- 2. History Events table +-- Unified event stream for timeline views +CREATE TABLE IF NOT EXISTS history_events ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + contract_id UUID REFERENCES contracts(id) ON DELETE CASCADE, + task_id UUID REFERENCES tasks(id) ON DELETE CASCADE, + event_type VARCHAR(50) NOT NULL, -- 'task', 'chat', 'checkpoint', 'phase', 'file' + event_subtype VARCHAR(50), -- Specific event: 'created', 'completed', 'message', etc. + phase VARCHAR(50), -- Contract phase when event occurred + event_data JSONB NOT NULL, -- Event-specific data + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX idx_history_events_contract ON history_events(contract_id, created_at DESC); +CREATE INDEX idx_history_events_task ON history_events(task_id, created_at DESC); +CREATE INDEX idx_history_events_owner ON history_events(owner_id, created_at DESC); +CREATE INDEX idx_history_events_type ON history_events(event_type, created_at DESC); + +-- 3. Alter task_checkpoints - add conversation snapshot reference +ALTER TABLE task_checkpoints + ADD COLUMN IF NOT EXISTS conversation_snapshot_id UUID REFERENCES conversation_snapshots(id) ON DELETE SET NULL; + +-- 4. Alter tasks - add forking fields +ALTER TABLE tasks + ADD COLUMN IF NOT EXISTS forked_from_task_id UUID REFERENCES tasks(id) ON DELETE SET NULL, + ADD COLUMN IF NOT EXISTS forked_at_checkpoint_id UUID REFERENCES task_checkpoints(id) ON DELETE SET NULL; + +CREATE INDEX IF NOT EXISTS idx_tasks_forked_from ON tasks(forked_from_task_id) WHERE forked_from_task_id IS NOT NULL; + +-- Comments for documentation +COMMENT ON TABLE conversation_snapshots IS 'Stores conversation state at specific points for rewind/resume capability'; +COMMENT ON TABLE history_events IS 'Unified event stream for timeline views across contracts and tasks'; +COMMENT ON COLUMN conversation_snapshots.snapshot_type IS 'Type: auto (periodic), manual (user-triggered), checkpoint (at git checkpoint)'; +COMMENT ON COLUMN history_events.event_type IS 'Category: task, chat, checkpoint, phase, file'; -- cgit v1.2.3