From 5d1fbed2733e93cc2be2e1a89ca022d88bef613f Mon Sep 17 00:00:00 2001 From: soryu Date: Tue, 24 Feb 2026 23:37:44 +0000 Subject: feat: non-blocking reconcile polling, directive CLI orders & cleanup (#82) * feat: soryu-co/soryu - makima: Remove aarch64-unknown-linux-gnu from release workflow * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Implement non-blocking ask with client-side polling for reconcile mode --- makima/src/daemon/api/supervisor.rs | 31 +++++++++++++++++++++++++++++++ makima/src/daemon/cli/directive.rs | 27 +++++++++++++++++++++++++++ makima/src/daemon/cli/mod.rs | 3 +++ makima/src/daemon/skills/directive.md | 27 ++++++++++++++++++++++++++- 4 files changed, 87 insertions(+), 1 deletion(-) (limited to 'makima/src/daemon') diff --git a/makima/src/daemon/api/supervisor.rs b/makima/src/daemon/api/supervisor.rs index c67c9ca..675b0bb 100644 --- a/makima/src/daemon/api/supervisor.rs +++ b/makima/src/daemon/api/supervisor.rs @@ -83,6 +83,20 @@ pub struct AskQuestionRequest { pub question_type: String, } +/// Request to create an order for future work. +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CreateOrderRequest { + pub title: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, + pub priority: String, + pub order_type: String, + pub labels: serde_json::Value, + #[serde(skip_serializing_if = "Option::is_none")] + pub repository_url: Option, +} + // Generic response type for JSON output #[derive(Deserialize, Serialize)] pub struct JsonValue(pub serde_json::Value); @@ -228,6 +242,18 @@ impl ApiClient { self.post("/api/v1/mesh/supervisor/questions", &req).await } + /// Poll for a question response by question_id. + /// + /// Used after a still_pending response from supervisor_ask. Blocks for up to + /// 5 minutes on the server side. Returns still_pending if no response yet. + pub async fn supervisor_poll_question( + &self, + question_id: Uuid, + ) -> Result { + self.get(&format!("/api/v1/mesh/supervisor/questions/{}/poll", question_id)) + .await + } + /// Advance contract to a new phase. /// /// When `confirmed` is false and phase_guard is enabled, returns a response with @@ -312,6 +338,11 @@ impl ApiClient { .await } + /// Create an order for future work from a directive task. + pub async fn create_order(&self, req: &CreateOrderRequest) -> Result { + self.post("/api/v1/mesh/supervisor/orders", req).await + } + /// Delete a task. pub async fn delete_task(&self, task_id: Uuid) -> Result<(), ApiError> { self.delete(&format!("/api/v1/mesh/tasks/{}", task_id)).await diff --git a/makima/src/daemon/cli/directive.rs b/makima/src/daemon/cli/directive.rs index 7c8451f..cc7b224 100644 --- a/makima/src/daemon/cli/directive.rs +++ b/makima/src/daemon/cli/directive.rs @@ -150,6 +150,33 @@ pub struct AskArgs { pub question_type: String, } +/// Arguments for create-order command. +#[derive(Args, Debug)] +pub struct CreateOrderArgs { + #[command(flatten)] + pub common: DirectiveArgs, + + /// Order title + #[arg(long)] + pub title: String, + + /// Order description + #[arg(long)] + pub description: Option, + + /// Priority: critical, high, medium, low, none + #[arg(long, default_value = "medium")] + pub priority: String, + + /// Order type: spike or chore only + #[arg(long, default_value = "spike")] + pub order_type: String, + + /// Comma-separated labels + #[arg(long)] + pub labels: Option, +} + /// Arguments for update command. #[derive(Args, Debug)] pub struct UpdateArgs { diff --git a/makima/src/daemon/cli/mod.rs b/makima/src/daemon/cli/mod.rs index 8063541..af6f885 100644 --- a/makima/src/daemon/cli/mod.rs +++ b/makima/src/daemon/cli/mod.rs @@ -252,6 +252,9 @@ pub enum DirectiveCommand { /// Ask a question and wait for user feedback Ask(directive::AskArgs), + + /// Create an order for future work (spike or chore only) + CreateOrder(directive::CreateOrderArgs), } impl Cli { diff --git a/makima/src/daemon/skills/directive.md b/makima/src/daemon/skills/directive.md index 02de836..dc1bce2 100644 --- a/makima/src/daemon/skills/directive.md +++ b/makima/src/daemon/skills/directive.md @@ -92,7 +92,7 @@ Options: - `--choices "opt1,opt2,opt3"` - Provide choices for the user to select from - `--context ""` - Additional context to help the user understand the question - `--timeout ` - Wait timeout (default: 3600 = 1 hour) -- `--phaseguard` - Block indefinitely until the user responds (no timeout). Recommended for critical decisions during planning. +- `--phaseguard` - Wait indefinitely until the user responds (no timeout). The CLI automatically reconnects via polling every ~5 minutes to avoid HTTP timeout limits. Recommended for critical decisions during planning. - `--multi-select` - Allow the user to select multiple choices - `--non-blocking` - Return immediately without waiting for a response - `--question-type ` - Question type @@ -108,6 +108,31 @@ Options: makima directive ask "Should we use REST or GraphQL for the new API?" --choices "REST,GraphQL" --context "The existing codebase uses REST but the frontend team prefers GraphQL" --phaseguard ``` +### Create an Order (Future Work) +```bash +makima directive create-order --title "Order title" --order-type spike +``` +Creates an order for future work that is automatically linked to the current directive. Only `spike` and `chore` order types are allowed. + +Options: +- `--title ""` - (Required) Title of the order +- `--description "<description>"` - Optional description of the work +- `--priority <critical|high|medium|low|none>` - Priority level (default: medium) +- `--order-type <spike|chore>` - Type of work (default: spike). Only spike and chore are allowed. +- `--labels "label1,label2"` - Optional comma-separated labels + +**When to use:** +- When you discover work that is out of scope for the current directive step but should be tracked +- When a spike reveals follow-up tasks that need to be done later +- When you identify technical debt or maintenance work during implementation +- When a chore (e.g., dependency update, config change) is needed but not part of the current goal + +**Example:** +```bash +makima directive create-order --title "Investigate flaky test in auth module" --order-type spike --priority high --description "The auth module tests intermittently fail on CI. Needs investigation." --labels "testing,auth" +makima directive create-order --title "Update deprecated serde API usage" --order-type chore --priority low --labels "tech-debt" +``` + ## Memory Commands Directives have an optional key-value memory system that persists across steps and planning cycles. Use memory to share context, decisions, and learned information between steps — so downstream tasks don't need to re-discover what earlier steps already figured out. -- cgit v1.2.3