summaryrefslogtreecommitdiff
path: root/makima/src/server/handlers/directives.rs
Commit message (Collapse)AuthorAgeFilesLines
* feat(doc-mode): unified surface — ephemeral tasks, tmp/, /exec redirect, ↵soryu2026-05-011-0/+161
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | palette, SWR (#117) Phases 1-3 of the unified-surface plan, bundled per the user's request. The directive document/folder UI is now the canonical place to interact with makima; legacy /exec is subsumed by routing redirects, /contracts is already hidden in nav, and orphan tasks surface under a top-level tmp/ pseudo-folder. Phase 4 (porting contract-only features) was confirmed out of scope; Phase 5 (deleting the contracts code) is a follow-up. ## Backend - New migration `20260501000000_archive_existing_contracts.sql` flips every legacy contract to `archived` so /contracts is read-only history. - New endpoint `POST /api/v1/directives/{id}/tasks` creates an ephemeral task — `directive_id` set, `directive_step_id` NULL, repo/branch inherited from the directive. Reuses `create_task_for_owner`. - New endpoint `GET /api/v1/directives/{id}/tasks` lists ephemeral tasks attached to a directive (drives the per-folder ephemeral group). - `GET /api/v1/mesh/tasks?orphan=true` returns top-level tasks with no `directive_id` AND no `parent_task_id` — backs the sidebar's tmp/. - New repo helpers `list_ephemeral_directive_tasks_for_owner` and `list_orphan_tasks_for_owner`. - The existing `mesh_merge` endpoints are reused as-is for ephemeral task merge (no new merge logic needed). ## Frontend ### Sticky composer + auto-scroll fix (`DocumentTaskStream.tsx`) - Sticky comment composer pinned to viewport bottom; padding compensates so the last entry isn't hidden behind it. - `autoScroll` now resumes when the user scrolls back within 80px of the bottom (previously stuck off forever after a single scroll-up). - Floating "↓ Jump to latest" chip when the user has scrolled away. - Action header strip: explicit Stop / Send / Open-in-task-page + conditional "Merge to base ↗" button on ephemeral terminal tasks. - Module-level cache of historical entries by taskId so re-selecting a task you've viewed renders instantly while a fresh fetch runs. ### Sidebar (`document-directives.tsx`) - Top-level `tmp/` folder: orphan tasks, polled every 5s. - Per-directive `tasks/` subfolder now also surfaces ephemeral tasks (lazily fetched on folder open) with a distinct asterisk-on-terminal icon (`EphemeralTaskIcon`). - Inline hover-action chips on each directive folder header: Start / Pause / PR / +New task. Right-click menu still works as a power-user fallback. - "Now executing" amber strip in the editor pane: surfaces the live orchestrator/completion/running-step task with a one-click jump. - Inline `+ New task` modal (name + plan); on submit calls `createDirectiveTask` and navigates into the freshly-spawned task. - New `EphemeralAwareTaskStream` wrapper passes `ephemeral` and `status` to `DocumentTaskStream` so the merge button only shows when the selected task is genuinely an ephemeral spinoff in a terminal state. Step-spawned tasks merge via the directive's PR completion. ### SWR cache (`useDirectives.ts`) - Module-level `listCache` and per-id `detailCache` (mirrors the pattern in `useUserSettings.ts`). Mounting the hook renders the cache value immediately if present and kicks a background refresh; subscribers see the new value when it lands. Cuts perceived navigation latency to near-zero on warm cache hits. ### QuickSwitcher (`QuickSwitcher.tsx`, new) - IntelliJ-style double-Shift command palette mounted at app root. - Listens at the document level for two `Shift` keydowns within 300ms with no other key in between; ignores while focus is in an input/textarea so capitalising letters doesn't pop the palette. - Searches across directives + their tasks (orchestrator/completion/ steps/ephemerals) + orphan tmp tasks. Fuzzy matches on title. - Eagerly loads task details for the first 20 directives on open so searches don't block on per-directive fetches. ### Routing (`main.tsx` + `exec-redirect.tsx` + `tmp.tsx`) - New `ExecRedirect` wrapper at `/exec/:id`: when documentMode is on AND the task has a `directiveId`, replaces the URL with `/directives/<directiveId>?task=<taskId>`. Otherwise renders the legacy `MeshPage` as before. - New `/tmp/:taskId` route renders `DocumentTaskStream` standalone for orphan tasks, with the masthead and a `tmp / <slug>` breadcrumb. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(directives): amendment lifecycle — inactive status, new draft, ↵soryu2026-04-301-0/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | before/after diff (#113) Stage 4 of the doc-mode revamp. Closes the loop on living-spec contracts: once a contract ships (PR raised) it becomes 'inactive', editing it kicks off an amendment cycle, the planner sees the previously-merged content as context, and "New draft" lets users abandon amendment and start the next contract on a clean slate. ## inactive lifecycle - New status `'inactive'`. Set automatically when `update_directive` detects a `pr_url` transition None → Some, alongside the revision snapshot (set_directive_inactive: idempotent, only flips active/idle/paused). - `update_directive_goal` extends its CASE flip to include 'inactive', so editing a shipped contract's goal reactivates it for the planner. - Frontend: `DirectiveStatus` gains 'inactive'; STATUS_DOT and the legacy STATUS_BADGEs (DirectiveDetail, DirectiveList) get color/label entries. Sidebar sort puts inactive after draft / before archived. ## Amendment diff to the orchestrator `build_planning_prompt` takes a new `previous_merged_revision` parameter. When set, it prepends an "AMENDMENT TO A PREVIOUSLY-MERGED CONTRACT" header that shows the merged content and the amended content explicitly, with guidance to plan a delta rather than a from-scratch rebuild. Both the planning and replanning phases call `get_latest_merged_revision` and pass it through. ## "New draft" affordance - New `repository::reset_directive_for_new_draft`: clears goal to '', status → 'draft', detaches pr_url / pr_branch / orchestrator linkage. Past revisions stay in directive_revisions as history. - New `POST /api/v1/directives/{id}/new-draft` handler. - DirectiveContextMenu surfaces "New draft" only when status === 'inactive', via an optional onNewDraft callback (legacy tabular UI doesn't have to wire it up). After reset, the page navigates to the contract so the user starts typing the next iteration immediately. ## PR-state-aware updates The user's spec — "open ⇒ update, merged ⇒ new PR, closed ⇒ new PR" — is already implemented in `build_completion_prompt`'s `gh pr view` runtime check, so no code change was needed here. The amendment cycle naturally flows through it: inactive → goal save → status flips to active → phase_replanning spawns a planner → completion task picks up the existing pr_url, sees the GitHub state, and decides update vs new PR accordingly. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(directives): per-PR revision snapshots + sidebar history (#112)soryu2026-04-301-2/+98
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Stage 3 of the doc-mode revamp. Builds the foundation for treating contracts as living specifications by freezing their content into a revision every time a PR is raised. ## directive_revisions table (new migration) (id, directive_id, content, pr_url, pr_branch, pr_state, version, frozen_at) with UNIQUE(directive_id, version) and a partial index on pr_state='open' so the next reconciler iteration can poll only what's still in flight. pr_state is constrained to 'open' | 'merged' | 'closed' to mirror GitHub's PR lifecycle. For Stage 3 we only freeze on PR creation; pr_state poll is deferred to a follow-up. ## Repository helpers - create_directive_revision: idempotent on (directive_id, pr_url) so a re-run of the orchestrator's completion task can't double-snapshot. Auto-assigns version = MAX(existing) + 1 per directive. - list_directive_revisions_for_owner: scoped through the directive join so users can only read their own contract history. - update_directive_revision_pr_state: stub for the upcoming poller. - get_latest_merged_revision: returns the most recent merged revision — this is what Stage 4 will diff against on amendments. ## Snapshot trigger update_directive handler now reads the BEFORE pr_url before the update. If pr_url transitions None → Some, it snapshots the directive's current goal as a revision tied to the new pr_url. Failures log and continue — the directive update itself is unaffected. ## API + OpenAPI GET /api/v1/directives/{id}/revisions returns DirectiveRevisionListResponse (revisions newest-first). Schemas registered in OpenAPI. ## Frontend: revisions/ subfolder + read-only viewer Each contract folder now has a third subfolder ("revisions/") that lazily fetches and lists past revisions when the parent directive folder is open. Empty contracts skip the subfolder entirely so brand-new ones aren't cluttered. Each row shows v<N>.md plus a small pill ('open'/'merged'/ 'closed'). Selecting a revision encodes itself into the existing ?task= param as "revision:<id>", so EditorShell can route between the live task stream (realTaskId), the read-only RevisionViewer (revisionId), or the editor itself (neither). The viewer renders the frozen markdown verbatim with a deep-link to the PR — these are immutable historical records, not edit surfaces. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(directive): cancel orphaned planner and kick reconciler on goal update ↵soryu2026-04-301-10/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (#104) Resolves the user-visible bug where editing a directive's goal mid-flight shows "saved" but does not actually replan: the running planner kept emitting add-step calls based on the OLD goal while a fresh planner was supposed to take over, and the user had to wait up to 15s for the next reconciler tick before any replanning even started. ## What was happening PUT /api/v1/directives/{id}/goal already had two paths: - Small change + planner running → SendMessage interrupt + KEEP orchestrator. - Everything else → clear orchestrator_task_id and let phase_replanning spawn a new planner on the next 15s tick. The "everything else" path cleared the directive's pointer to the planner task but never cancelled the task itself. The task kept executing and could race the new planner by adding more steps from the stale plan. Worse, those new steps could push MAX(steps.created_at) past the just-bumped goal_updated_at, suppressing phase_replanning entirely. ## Fix 1. New helper `try_cancel_running_planner()` (orchestration/directive.rs): sends `InterruptTask { graceful: true }` to the daemon owning the orchestrator task and marks the task `interrupted` in the DB. All errors are logged and swallowed so the goal update still completes. 2. update_goal handler calls the helper whenever it is about to take the "clear orchestrator_task_id" branch, so the orphaned planner stops producing stale-plan steps before its DB linkage is cut. 3. New `AppState::directive_kick` (tokio::sync::Notify) lets the handler signal the reconciler to run a tick immediately. The reconciler loop in server/mod.rs now selects between its 15s interval and the notify, so the user no longer waits up to 15s after editing a goal before replanning actually starts. update_goal calls `kick_directive_reconciler()` after the goal is persisted (both paths). ## Why not also loosen `get_directives_needing_replanning` The query already covers the common cases once the orphan-cancel lands — without a still-running orphan adding fresh steps, goal_updated_at reliably exceeds MAX(steps.created_at) after a goal edit. Loosening the predicate risked spurious replans for directives that legitimately have no steps yet (those are handled by `phase_planning`). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: document-mode directive UI proof of concept (Lexical) (#101)soryu2026-04-291-17/+68
| | | | | | | | | | | * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Backend: feature flag + goal-edit interrupt messaging * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Frontend: Lexical document editor with step blocks, context menu, countdown
* feat: soryu-co/soryu - makima: Add DOG database schema and backend CRUDsoryu2026-03-071-2/+581
|
* WIP: heartbeat checkpointsoryu2026-03-071-0/+3
|
* feat: auto-remove merged steps, fix UI overflow, and improve worktree ↵soryu2026-02-201-1/+38
| | | | | | | | | | | | | | | handling (#74) * feat: soryu-co/soryu - makima: Fix contracts page overflow - constrain layout to viewport height * feat: soryu-co/soryu - makima: Add git fetch to create_worktree and improve completion prompt merge conflict handling * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Add pending question notification badge to directive sidebar and nav * feat: soryu-co/soryu - makima: Fix reconcile:on blocking - make phaseguard poll indefinitely instead of returning immediately * feat: soryu-co/soryu - makima: Auto-remove merged steps before planning runs
* feat: smart cleanup, order linking, and improved PR titles (#69)soryu2026-02-171-22/+134
| | | | | | | | | | | | | * feat: soryu-co/soryu: Reorder navigation: move Orders before Contracts * feat: soryu-co/soryu: Generate PR titles from step content instead of directive title * feat: soryu-co/soryu: Add orderId field to step creation and link orders to steps * feat: soryu-co/soryu: Handle completed orders during plan-orders flow * WIP: heartbeat checkpoint * Merge origin/makima/soryu-co-soryu--handle-completed-orders-during-pla-5aa9a15b (resolved conflicts)
* feat: reorder nav, link orders to steps, improve PR titles (#68)soryu2026-02-171-0/+1
| | | | | | | | | * feat: soryu-co/soryu: Reorder navigation: move Orders before Contracts * feat: soryu-co/soryu: Generate PR titles from step content instead of directive title * feat: soryu-co/soryu: Add orderId field to step creation and link orders to steps * feat: soryu-co/soryu: Handle completed orders during plan-orders flow
* soryu-co/soryu - makima (#67)soryu2026-02-171-0/+13
| | | | | | | | | | | | | | | | | | | | | | | * feat: soryu-co/soryu - makima: Fix contracts page scrolling overflow * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Remove contract association from orders and make directive mandatory in UI * feat: soryu-co/soryu - makima: Add directive name to order metadata for searchability * feat: soryu-co/soryu - makima: Change directive link in orders to use search interface * feat: soryu-co/soryu - makima: Name directive PRs based on content not directive title * feat: soryu-co/soryu - makima: Add orderId to step creation and auto-link orders to steps * feat: soryu-co/soryu - makima: Add under_review status and auto-complete orders in plan flow
* soryu-co/soryu - makima (#66)soryu2026-02-161-3/+10
| | | | | | | | | | | * feat: soryu-co/soryu - makima: Fix contracts page scrolling overflow * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint
* Add PR button to directivessoryu2026-02-161-0/+82
|
* Add pick-up-orders feature for directives (#64)soryu2026-02-161-2/+198
| | | | | | | | | * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Add frontend pick-up-orders button and API integration * feat: soryu-co/soryu - makima: Add pick-up-orders backend endpoint and repository functions
* feat: track directive goal history for intelligent re-planning (#63)soryu2026-02-161-21/+24
| | | | | * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Save previous goal on update and include history in re-planning prompt
* Rerun plan when directive goal is edited (#61)soryu2026-02-131-1/+22
| | | | | | | | | | | | | | | When a directive's goal is updated, pending/ready/failed/skipped steps are now automatically cleared so that replanning generates fresh steps aligned with the new goal. The planning prompt is also improved to clearly categorize existing steps by status and provide explicit instructions for re-evaluation. Changes: - Add clear_pending_directive_steps() repository function to remove non-started steps when the goal changes - Call step cleanup in the update_goal HTTP handler - Restructure the planning prompt to categorize steps (completed, running, pending, failed, skipped) with clear instructions for each category Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix worktree branching for directive tasks and remove memoriessoryu2026-02-131-390/+4
|
* Add task cleanup and directive PR updatingsoryu2026-02-121-0/+1
|
* Add depends_on for directive taskssoryu2026-02-121-5/+67
| | | | | # Conflicts: # makima/src/orchestration/directive.rs
* makima: Add an optional memory system for directives (#59)soryu2026-02-121-4/+391
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: makima: Add an optional memory system for directives: Add directive_memories database table and migration * feat: makima: Add an optional memory system for directives: Update directive skill documentation with memory commands * feat: makima: Add an optional memory system for directives: Add repository functions for directive memory CRUD * feat: makima: Add an optional memory system for directives: Add frontend API functions and types for directive memory * feat: makima: Add an optional memory system for directives: Add Rust models for directive memory * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * feat: makima: Add an optional memory system for directives: Add memory panel to frontend DirectiveDetail component * Merge remote-tracking branch 'origin/makima/makima--add-an-optional-memory-system-for-directiv-5de1e06d' into combined branch * Merge remote-tracking branch 'origin/makima/makima--add-an-optional-memory-system-for-directiv-c8298c6c' into combined branch * feat: makima: Add an optional memory system for directives: Create useMultiTaskSubscription hook for multi-output WebSocket streaming * feat: makima: Add an optional memory system for directives: Create DirectiveLogStream component for stern-like multi-task output viewing * feat: makima: Add an optional memory system for directives: Integrate log stream panel into directive detail page
* Add new directive mechanism v3soryu2026-02-091-0/+841
|
* Remove directive mechanismsoryu2026-02-081-785/+0
|
* Fixes for directive chain initsoryu2026-02-081-1/+60
|
* Add directive monitor contractssoryu2026-02-071-6/+217
|
* Show directive init on frontendsoryu2026-02-071-2/+19
|
* Add directive init mechanismsoryu2026-02-071-0/+58
|
* Add new directive initial implementationsoryu2026-02-071-0/+440
|
* Remove directives for reimplementationsoryu2026-02-071-2116/+0
|
* Fix: Link directives and contractssoryu2026-02-061-1/+67
|
* Fix: Cleanup old chain codesoryu2026-02-061-2/+483
|
* Fix: Directives APIsoryu2026-02-061-2/+83
|
* Add directive-first chain system redesignsoryu2026-02-051-0/+1488
Redesigns the chain system with a directive-first architecture where Directive is the top-level entity (the "why/what") and Chains are generated execution plans (the "how") that can be dynamically modified. Backend: - Add database migration for directive system tables - Add Directive, DirectiveChain, ChainStep, DirectiveEvent models - Add DirectiveVerifier and DirectiveApproval models - Add orchestration module with engine, planner, and verifier - Add comprehensive API handlers for directives - Add daemon CLI commands for directive management - Add directive skill documentation - Integrate contract completion with directive engine - Add SSE endpoint for real-time directive events Frontend: - Add directives route with split-view layout - Add 6-tab detail view (Overview, Chain, Events, Evaluations, Approvals, Verifiers) - Add React Flow DAG visualization for chain steps - Add SSE subscription hook for real-time event updates - Add useDirectives and useDirectiveEventSubscription hooks - Add directive types and API functions Fixes: - Fix test failures in ws/protocol, task_output, completion_gate, patch - Fix word boundary matching in looks_like_task() - Fix parse_last() to find actual last completion gate - Fix create_export_patch when merge-base equals HEAD - Clean up clippy warnings in new code Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>