summaryrefslogtreecommitdiff
path: root/makima/src/daemon/task/manager.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/daemon/task/manager.rs')
-rw-r--r--makima/src/daemon/task/manager.rs80
1 files changed, 75 insertions, 5 deletions
diff --git a/makima/src/daemon/task/manager.rs b/makima/src/daemon/task/manager.rs
index 8269083..3b4ffdd 100644
--- a/makima/src/daemon/task/manager.rs
+++ b/makima/src/daemon/task/manager.rs
@@ -27,12 +27,27 @@ fn generate_tool_key() -> String {
}
/// Check if output contains an OAuth authentication error.
-fn is_oauth_auth_error(output: &str) -> bool {
+/// Only checks system/error messages, not assistant responses (which could mention auth errors conversationally).
+fn is_oauth_auth_error(output: &str, json_type: Option<&str>, is_stdout: bool) -> bool {
+ // Only check system messages or stderr output - not assistant messages
+ // which could mention auth errors in conversation
+ match json_type {
+ Some("assistant") | Some("user") | Some("result") => return false,
+ _ => {}
+ }
+
+ // For stdout JSON messages, only check system/error types
+ if is_stdout && json_type.is_none() {
+ // Non-JSON stdout output - could be startup messages, check carefully
+ // Only match very specific patterns that wouldn't appear in conversation
+ }
+
// Match various authentication error patterns from Claude Code
- if output.contains("Please run /login") {
+ // These patterns are specific enough that they shouldn't appear in normal conversation
+ if output.contains("Please run /login") && output.contains("authenticate") {
return true;
}
- if output.contains("Invalid API key") {
+ if output.contains("Invalid API key") && output.contains("ANTHROPIC_API_KEY") {
return true;
}
if output.contains("authentication_error")
@@ -41,6 +56,10 @@ fn is_oauth_auth_error(output: &str) -> bool {
{
return true;
}
+ // Check for Claude Code's specific error format
+ if output.contains("\"type\":\"error\"") && output.contains("authentication") {
+ return true;
+ }
false
}
@@ -695,6 +714,51 @@ makima supervisor checkpoints [task_id]
makima supervisor status
```
+### User Feedback
+```bash
+# Ask a free-form question
+makima supervisor ask "Your question here"
+
+# Ask with choices (comma-separated)
+makima supervisor ask "Choose an option" --choices "Option A,Option B,Option C"
+
+# Ask with context
+makima supervisor ask "Ready to proceed?" --context "After completing task X"
+
+# Ask with custom timeout (default 1 hour)
+makima supervisor ask "Question" --timeout 3600
+```
+
+## User Feedback (Ask Command)
+
+You can ask the user questions when you need clarification or approval:
+
+```bash
+# Ask a free-form question (waits for user to respond)
+makima supervisor ask "What authentication method should I use?"
+
+# Ask with predefined choices
+makima supervisor ask "Ready to create PR?" --choices "Yes,No,Need more changes"
+
+# Ask with context
+makima supervisor ask "Should I proceed?" --context "Plan phase complete"
+```
+
+The ask command will block until the user responds (or timeout). Use this to:
+- Clarify requirements before starting work
+- Get approval before creating PRs
+- Ask for guidance when tasks fail
+
+## Contract Phase Progression
+
+### For "Simple" contracts (Plan → Execute):
+1. **Plan Phase**: Review the plan document and understand the goal
+2. **Execute Phase**: Spawn tasks to implement the plan, then create PR
+3. Mark contract as complete when PR is created
+
+### For "Specification" contracts (Research → Specify → Plan → Execute → Review):
+Progress through each phase, spawning tasks as needed and asking for user feedback.
+
## Key Points
1. **Create a makima branch first** - use `branch "makima/{name}"` for the contract's work
@@ -703,6 +767,7 @@ makima supervisor status
4. **Never fire-and-forget** - always wait for each task before moving on
5. **Merge to your makima branch** - use `merge <task_id> --to "makima/{name}"` to collect completed work
6. **Create PR when done** - use `pr "makima/{name}" --title "..." --base main`
+7. **Ask when unsure** - use `ask` to get user feedback on decisions
## Standard Workflow
@@ -711,16 +776,19 @@ makima supervisor status
- `spawn` - Create task
- `wait` - Block until complete
- `merge --to "makima/{name}"` - Merge to branch
-3. `pr "makima/{name}" --title "..." --base main` - Create PR
+3. `ask "Ready to create PR?"` - Get user approval
+4. `pr "makima/{name}" --title "..." --base main` - Create PR
## Important Reminders
- **ONLY YOU can spawn tasks** - regular tasks cannot create children
- **NEVER implement anything yourself** - always spawn tasks
- **ALWAYS create a makima branch** - use `makima/{name}` naming convention
+- **ASK for feedback** when you need clarification or approval
- Tasks run independently - you just coordinate
- You will be resumed if interrupted - your conversation is preserved
- Create checkpoints before major transitions
+- **Mark contract complete** when PR is created by updating status
---
@@ -2834,6 +2902,8 @@ impl TaskManagerInner {
// Check for OAuth auth error before sending output
let content_for_auth_check = line.content.clone();
+ let json_type_for_auth_check = line.json_type.clone();
+ let is_stdout_for_auth_check = line.is_stdout;
let msg = DaemonMessage::task_output(task_id, line.content, false);
if ws_tx.send(msg).await.is_err() {
@@ -2842,7 +2912,7 @@ impl TaskManagerInner {
}
// Detect OAuth token expiration and trigger remote login flow
- if !auth_error_handled && is_oauth_auth_error(&content_for_auth_check) {
+ if !auth_error_handled && is_oauth_auth_error(&content_for_auth_check, json_type_for_auth_check.as_deref(), is_stdout_for_auth_check) {
auth_error_handled = true;
tracing::warn!(task_id = %task_id, "OAuth authentication error detected, initiating remote login flow");