oh-my-claude-sisyphus 1.10.0 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/agents/definitions.js +1 -1
  2. package/dist/agents/model-lists.d.ts +26 -0
  3. package/dist/agents/model-lists.d.ts.map +1 -0
  4. package/dist/agents/model-lists.js +62 -0
  5. package/dist/agents/model-lists.js.map +1 -0
  6. package/dist/agents/orchestrator-sisyphus.js +1 -1
  7. package/dist/auth/index.d.ts +10 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/index.js +13 -0
  10. package/dist/auth/index.js.map +1 -0
  11. package/dist/auth/manager.d.ts +54 -0
  12. package/dist/auth/manager.d.ts.map +1 -0
  13. package/dist/auth/manager.js +248 -0
  14. package/dist/auth/manager.js.map +1 -0
  15. package/dist/auth/oauth-google.d.ts +47 -0
  16. package/dist/auth/oauth-google.d.ts.map +1 -0
  17. package/dist/auth/oauth-google.js +280 -0
  18. package/dist/auth/oauth-google.js.map +1 -0
  19. package/dist/auth/oauth-openai.d.ts +46 -0
  20. package/dist/auth/oauth-openai.d.ts.map +1 -0
  21. package/dist/auth/oauth-openai.js +264 -0
  22. package/dist/auth/oauth-openai.js.map +1 -0
  23. package/dist/auth/pkce.d.ts +14 -0
  24. package/dist/auth/pkce.d.ts.map +1 -0
  25. package/dist/auth/pkce.js +35 -0
  26. package/dist/auth/pkce.js.map +1 -0
  27. package/dist/auth/storage.d.ts +52 -0
  28. package/dist/auth/storage.d.ts.map +1 -0
  29. package/dist/auth/storage.js +230 -0
  30. package/dist/auth/storage.js.map +1 -0
  31. package/dist/auth/types.d.ts +76 -0
  32. package/dist/auth/types.d.ts.map +1 -0
  33. package/dist/auth/types.js +5 -0
  34. package/dist/auth/types.js.map +1 -0
  35. package/dist/cli/index.js +0 -0
  36. package/dist/features/auto-update.d.ts +20 -0
  37. package/dist/features/auto-update.d.ts.map +1 -1
  38. package/dist/features/auto-update.js +35 -0
  39. package/dist/features/auto-update.js.map +1 -1
  40. package/dist/features/builtin-skills/skills.js +2 -2
  41. package/dist/hooks/bridge.d.ts.map +1 -1
  42. package/dist/hooks/bridge.js +26 -1
  43. package/dist/hooks/bridge.js.map +1 -1
  44. package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
  45. package/dist/hooks/persistent-mode/index.js +126 -4
  46. package/dist/hooks/persistent-mode/index.js.map +1 -1
  47. package/dist/hooks/preemptive-compaction/index.js +2 -2
  48. package/dist/hooks/preemptive-compaction/index.js.map +1 -1
  49. package/dist/hooks/thinking-block-validator/index.d.ts +3 -34
  50. package/dist/hooks/thinking-block-validator/index.d.ts.map +1 -1
  51. package/dist/hooks/thinking-block-validator/index.js +21 -70
  52. package/dist/hooks/thinking-block-validator/index.js.map +1 -1
  53. package/dist/installer/hooks.d.ts +2 -2
  54. package/dist/installer/hooks.d.ts.map +1 -1
  55. package/dist/installer/hooks.js +85 -2
  56. package/dist/installer/hooks.js.map +1 -1
  57. package/dist/installer/index.js +3 -3
  58. package/dist/providers/index.d.ts +8 -0
  59. package/dist/providers/index.d.ts.map +1 -0
  60. package/dist/providers/index.js +10 -0
  61. package/dist/providers/index.js.map +1 -0
  62. package/dist/providers/registry.d.ts +29 -0
  63. package/dist/providers/registry.d.ts.map +1 -0
  64. package/dist/providers/registry.js +162 -0
  65. package/dist/providers/registry.js.map +1 -0
  66. package/dist/providers/router.d.ts +40 -0
  67. package/dist/providers/router.d.ts.map +1 -0
  68. package/dist/providers/router.js +88 -0
  69. package/dist/providers/router.js.map +1 -0
  70. package/dist/providers/types.d.ts +92 -0
  71. package/dist/providers/types.d.ts.map +1 -0
  72. package/dist/providers/types.js +27 -0
  73. package/dist/providers/types.js.map +1 -0
  74. package/dist/tools/ast-tools.d.ts +3 -3
  75. package/dist/tools/ast-tools.d.ts.map +1 -1
  76. package/dist/tools/ast-tools.js +205 -104
  77. package/dist/tools/ast-tools.js.map +1 -1
  78. package/package.json +1 -1
  79. package/scripts/install.sh +70 -3
  80. package/scripts/uninstall.sh +116 -3
@@ -80,7 +80,7 @@ export declare const STOP_CONTINUATION_SCRIPT_NODE = "#!/usr/bin/env node\n// Si
80
80
  * Persistent Mode Bash script
81
81
  * Enhanced stop hook that handles ultrawork, ralph-loop, and todo continuation
82
82
  */
83
- export declare const PERSISTENT_MODE_SCRIPT = "#!/bin/bash\n# Sisyphus Persistent Mode Hook\n# Unified handler for ultrawork, ralph-loop, and todo continuation\n# Prevents stopping when work remains incomplete\n\n# Read stdin\nINPUT=$(cat)\n\n# Get session ID and directory\nSESSION_ID=\"\"\nDIRECTORY=\"\"\nif command -v jq &> /dev/null; then\n SESSION_ID=$(echo \"$INPUT\" | jq -r '.sessionId // .session_id // \"\"' 2>/dev/null)\n DIRECTORY=$(echo \"$INPUT\" | jq -r '.directory // \"\"' 2>/dev/null)\nfi\n\n# Default to current directory\nif [ -z \"$DIRECTORY\" ]; then\n DIRECTORY=$(pwd)\nfi\n\n# Check for active ultrawork state\nULTRAWORK_STATE=\"\"\nif [ -f \"$DIRECTORY/.sisyphus/ultrawork-state.json\" ]; then\n ULTRAWORK_STATE=$(cat \"$DIRECTORY/.sisyphus/ultrawork-state.json\" 2>/dev/null)\nelif [ -f \"$HOME/.claude/ultrawork-state.json\" ]; then\n ULTRAWORK_STATE=$(cat \"$HOME/.claude/ultrawork-state.json\" 2>/dev/null)\nfi\n\n# Check for active ralph loop\nRALPH_STATE=\"\"\nif [ -f \"$DIRECTORY/.sisyphus/ralph-state.json\" ]; then\n RALPH_STATE=$(cat \"$DIRECTORY/.sisyphus/ralph-state.json\" 2>/dev/null)\nfi\n\n# Check for incomplete todos\nINCOMPLETE_COUNT=0\nTODOS_DIR=\"$HOME/.claude/todos\"\nif [ -d \"$TODOS_DIR\" ]; then\n for todo_file in \"$TODOS_DIR\"/*.json; do\n if [ -f \"$todo_file\" ]; then\n if command -v jq &> /dev/null; then\n COUNT=$(jq '[.[] | select(.status != \"completed\" and .status != \"cancelled\")] | length' \"$todo_file\" 2>/dev/null || echo \"0\")\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n else\n # Fallback: count \"pending\" or \"in_progress\" occurrences\n COUNT=$(grep -c '\"status\"[[:space:]]*:[[:space:]]*\"pending\\|in_progress\"' \"$todo_file\" 2>/dev/null) || COUNT=0\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n fi\n fi\n done\nfi\n\n# Check project todos as well\nfor todo_path in \"$DIRECTORY/.sisyphus/todos.json\" \"$DIRECTORY/.claude/todos.json\"; do\n if [ -f \"$todo_path\" ]; then\n if command -v jq &> /dev/null; then\n COUNT=$(jq 'if type == \"array\" then [.[] | select(.status != \"completed\" and .status != \"cancelled\")] | length else 0 end' \"$todo_path\" 2>/dev/null || echo \"0\")\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n else\n # Fallback: count \"pending\" or \"in_progress\" occurrences\n COUNT=$(grep -c '\"status\"[[:space:]]*:[[:space:]]*\"pending\\|in_progress\"' \"$todo_path\" 2>/dev/null) || COUNT=0\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n fi\n fi\ndone\n\n# Priority 1: Ralph Loop\nif [ -n \"$RALPH_STATE\" ]; then\n IS_ACTIVE=$(echo \"$RALPH_STATE\" | jq -r '.active // false' 2>/dev/null)\n if [ \"$IS_ACTIVE\" = \"true\" ]; then\n ITERATION=$(echo \"$RALPH_STATE\" | jq -r '.iteration // 1' 2>/dev/null)\n MAX_ITER=$(echo \"$RALPH_STATE\" | jq -r '.max_iterations // 10' 2>/dev/null)\n PROMISE=$(echo \"$RALPH_STATE\" | jq -r '.completion_promise // \"TASK_COMPLETE\"' 2>/dev/null)\n PROMPT=$(echo \"$RALPH_STATE\" | jq -r '.prompt // \"\"' 2>/dev/null)\n\n if [ \"$ITERATION\" -lt \"$MAX_ITER\" ]; then\n # Increment iteration\n NEW_ITER=$((ITERATION + 1))\n echo \"$RALPH_STATE\" | jq \".iteration = $NEW_ITER\" > \"$DIRECTORY/.sisyphus/ralph-state.json\" 2>/dev/null\n\n cat << EOF\n{\"continue\": false, \"reason\": \"<ralph-loop-continuation>\\n\\n[RALPH LOOP - ITERATION $NEW_ITER/$MAX_ITER]\\n\\nYour previous attempt did not output the completion promise. The work is NOT done yet.\\n\\nCRITICAL INSTRUCTIONS:\\n1. Review your progress and the original task\\n2. Check your todo list - are ALL items marked complete?\\n3. Continue from where you left off\\n4. When FULLY complete, output: <promise>$PROMISE</promise>\\n5. Do NOT stop until the task is truly done\\n\\nOriginal task: $PROMPT\\n\\n</ralph-loop-continuation>\\n\\n---\\n\"}\nEOF\n exit 0\n fi\n fi\nfi\n\n# Priority 2: Ultrawork Mode with incomplete todos\nif [ -n \"$ULTRAWORK_STATE\" ] && [ \"$INCOMPLETE_COUNT\" -gt 0 ]; then\n # Check if active (with jq fallback)\n IS_ACTIVE=\"\"\n if command -v jq &> /dev/null; then\n IS_ACTIVE=$(echo \"$ULTRAWORK_STATE\" | jq -r '.active // false' 2>/dev/null)\n else\n # Fallback: grep for \"active\": true\n if echo \"$ULTRAWORK_STATE\" | grep -q '\"active\"[[:space:]]*:[[:space:]]*true'; then\n IS_ACTIVE=\"true\"\n fi\n fi\n\n if [ \"$IS_ACTIVE\" = \"true\" ]; then\n # Get reinforcement count (with fallback)\n REINFORCE_COUNT=0\n if command -v jq &> /dev/null; then\n REINFORCE_COUNT=$(echo \"$ULTRAWORK_STATE\" | jq -r '.reinforcement_count // 0' 2>/dev/null)\n else\n REINFORCE_COUNT=$(echo \"$ULTRAWORK_STATE\" | grep -oP '\"reinforcement_count\"[[:space:]]*:[[:space:]]*\\K[0-9]+' 2>/dev/null) || REINFORCE_COUNT=0\n fi\n NEW_COUNT=$((REINFORCE_COUNT + 1))\n\n # Get original prompt (with fallback)\n ORIGINAL_PROMPT=\"\"\n if command -v jq &> /dev/null; then\n ORIGINAL_PROMPT=$(echo \"$ULTRAWORK_STATE\" | jq -r '.original_prompt // \"\"' 2>/dev/null)\n else\n ORIGINAL_PROMPT=$(echo \"$ULTRAWORK_STATE\" | grep -oP '\"original_prompt\"[[:space:]]*:[[:space:]]*\"\\K[^\"]+' 2>/dev/null) || ORIGINAL_PROMPT=\"\"\n fi\n\n # Update state file (best effort)\n if command -v jq &> /dev/null; then\n echo \"$ULTRAWORK_STATE\" | jq \".reinforcement_count = $NEW_COUNT | .last_checked_at = \\\"$(date -Iseconds)\\\"\" > \"$DIRECTORY/.sisyphus/ultrawork-state.json\" 2>/dev/null\n fi\n\n cat << EOF\n{\"continue\": false, \"reason\": \"<ultrawork-persistence>\\n\\n[ULTRAWORK MODE STILL ACTIVE - Reinforcement #$NEW_COUNT]\\n\\nYour ultrawork session is NOT complete. $INCOMPLETE_COUNT incomplete todos remain.\\n\\nREMEMBER THE ULTRAWORK RULES:\\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially\\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent)\\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each\\n- **VERIFY**: Check ALL requirements met before done\\n- **NO Premature Stopping**: ALL TODOs must be complete\\n\\nContinue working on the next pending task. DO NOT STOP until all tasks are marked complete.\\n\\nOriginal task: $ORIGINAL_PROMPT\\n\\n</ultrawork-persistence>\\n\\n---\\n\"}\nEOF\n exit 0\n fi\nfi\n\n# Priority 3: Todo Continuation (baseline)\nif [ \"$INCOMPLETE_COUNT\" -gt 0 ]; then\n cat << EOF\n{\"continue\": false, \"reason\": \"<todo-continuation>\\n\\n[SYSTEM REMINDER - TODO CONTINUATION]\\n\\nIncomplete tasks remain in your todo list ($INCOMPLETE_COUNT remaining). Continue working on the next pending task.\\n\\n- Proceed without asking for permission\\n- Mark each task complete when finished\\n- Do not stop until all tasks are done\\n\\n</todo-continuation>\\n\\n---\\n\"}\nEOF\n exit 0\nfi\n\n# No blocking needed\necho '{\"continue\": true}'\nexit 0\n";
83
+ export declare const PERSISTENT_MODE_SCRIPT = "#!/bin/bash\n# Sisyphus Persistent Mode Hook\n# Unified handler for ultrawork, ralph-loop, and todo continuation\n# Prevents stopping when work remains incomplete\n\n# Read stdin\nINPUT=$(cat)\n\n# Get session ID and directory\nSESSION_ID=\"\"\nDIRECTORY=\"\"\nif command -v jq &> /dev/null; then\n SESSION_ID=$(echo \"$INPUT\" | jq -r '.sessionId // .session_id // \"\"' 2>/dev/null)\n DIRECTORY=$(echo \"$INPUT\" | jq -r '.directory // \"\"' 2>/dev/null)\nfi\n\n# Default to current directory\nif [ -z \"$DIRECTORY\" ]; then\n DIRECTORY=$(pwd)\nfi\n\n# Check for active ultrawork state\nULTRAWORK_STATE=\"\"\nif [ -f \"$DIRECTORY/.sisyphus/ultrawork-state.json\" ]; then\n ULTRAWORK_STATE=$(cat \"$DIRECTORY/.sisyphus/ultrawork-state.json\" 2>/dev/null)\nelif [ -f \"$HOME/.claude/ultrawork-state.json\" ]; then\n ULTRAWORK_STATE=$(cat \"$HOME/.claude/ultrawork-state.json\" 2>/dev/null)\nfi\n\n# Check for active ralph loop\nRALPH_STATE=\"\"\nif [ -f \"$DIRECTORY/.sisyphus/ralph-state.json\" ]; then\n RALPH_STATE=$(cat \"$DIRECTORY/.sisyphus/ralph-state.json\" 2>/dev/null)\nfi\n\n# Check for verification state (oracle verification)\nVERIFICATION_STATE=\"\"\nif [ -f \"$DIRECTORY/.sisyphus/ralph-verification.json\" ]; then\n VERIFICATION_STATE=$(cat \"$DIRECTORY/.sisyphus/ralph-verification.json\" 2>/dev/null)\nfi\n\n# Check for incomplete todos\nINCOMPLETE_COUNT=0\nTODOS_DIR=\"$HOME/.claude/todos\"\nif [ -d \"$TODOS_DIR\" ]; then\n for todo_file in \"$TODOS_DIR\"/*.json; do\n if [ -f \"$todo_file\" ]; then\n if command -v jq &> /dev/null; then\n COUNT=$(jq '[.[] | select(.status != \"completed\" and .status != \"cancelled\")] | length' \"$todo_file\" 2>/dev/null || echo \"0\")\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n else\n # Fallback: count \"pending\" or \"in_progress\" occurrences\n COUNT=$(grep -c '\"status\"[[:space:]]*:[[:space:]]*\"pending\\|in_progress\"' \"$todo_file\" 2>/dev/null) || COUNT=0\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n fi\n fi\n done\nfi\n\n# Check project todos as well\nfor todo_path in \"$DIRECTORY/.sisyphus/todos.json\" \"$DIRECTORY/.claude/todos.json\"; do\n if [ -f \"$todo_path\" ]; then\n if command -v jq &> /dev/null; then\n COUNT=$(jq 'if type == \"array\" then [.[] | select(.status != \"completed\" and .status != \"cancelled\")] | length else 0 end' \"$todo_path\" 2>/dev/null || echo \"0\")\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n else\n # Fallback: count \"pending\" or \"in_progress\" occurrences\n COUNT=$(grep -c '\"status\"[[:space:]]*:[[:space:]]*\"pending\\|in_progress\"' \"$todo_path\" 2>/dev/null) || COUNT=0\n INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))\n fi\n fi\ndone\n\n# Priority 1: Ralph Loop with Oracle Verification\nif [ -n \"$RALPH_STATE\" ]; then\n IS_ACTIVE=$(echo \"$RALPH_STATE\" | jq -r '.active // false' 2>/dev/null)\n if [ \"$IS_ACTIVE\" = \"true\" ]; then\n ITERATION=$(echo \"$RALPH_STATE\" | jq -r '.iteration // 1' 2>/dev/null)\n MAX_ITER=$(echo \"$RALPH_STATE\" | jq -r '.max_iterations // 10' 2>/dev/null)\n PROMISE=$(echo \"$RALPH_STATE\" | jq -r '.completion_promise // \"TASK_COMPLETE\"' 2>/dev/null)\n PROMPT=$(echo \"$RALPH_STATE\" | jq -r '.prompt // \"\"' 2>/dev/null)\n\n # Check if oracle verification is pending\n if [ -n \"$VERIFICATION_STATE\" ]; then\n IS_PENDING=$(echo \"$VERIFICATION_STATE\" | jq -r '.pending // false' 2>/dev/null)\n if [ \"$IS_PENDING\" = \"true\" ]; then\n ATTEMPT=$(echo \"$VERIFICATION_STATE\" | jq -r '.verification_attempts // 0' 2>/dev/null)\n MAX_ATTEMPTS=$(echo \"$VERIFICATION_STATE\" | jq -r '.max_verification_attempts // 3' 2>/dev/null)\n ORIGINAL_TASK=$(echo \"$VERIFICATION_STATE\" | jq -r '.original_task // \"\"' 2>/dev/null)\n COMPLETION_CLAIM=$(echo \"$VERIFICATION_STATE\" | jq -r '.completion_claim // \"\"' 2>/dev/null)\n ORACLE_FEEDBACK=$(echo \"$VERIFICATION_STATE\" | jq -r '.oracle_feedback // \"\"' 2>/dev/null)\n NEXT_ATTEMPT=$((ATTEMPT + 1))\n\n FEEDBACK_SECTION=\"\"\n if [ -n \"$ORACLE_FEEDBACK\" ] && [ \"$ORACLE_FEEDBACK\" != \"null\" ]; then\n FEEDBACK_SECTION=\"\\n**Previous Oracle Feedback (rejected):**\\n$ORACLE_FEEDBACK\\n\"\n fi\n\n cat << EOF\n{\"continue\": false, \"reason\": \"<ralph-verification>\\n\\n[ORACLE VERIFICATION REQUIRED - Attempt $NEXT_ATTEMPT/$MAX_ATTEMPTS]\\n\\nThe agent claims the task is complete. Before accepting, YOU MUST verify with Oracle.\\n\\n**Original Task:**\\n$ORIGINAL_TASK\\n\\n**Completion Claim:**\\n$COMPLETION_CLAIM\\n$FEEDBACK_SECTION\\n## MANDATORY VERIFICATION STEPS\\n\\n1. **Spawn Oracle Agent** for verification:\\n \\`\\`\\`\\n Task(subagent_type=\\\"oracle\\\", prompt=\\\"Verify this task completion claim...\\\")\\n \\`\\`\\`\\n\\n2. **Oracle must check:**\\n - Are ALL requirements from the original task met?\\n - Is the implementation complete, not partial?\\n - Are there any obvious bugs or issues?\\n - Does the code compile/run without errors?\\n - Are tests passing (if applicable)?\\n\\n3. **Based on Oracle's response:**\\n - If APPROVED: Output \\`<oracle-approved>VERIFIED_COMPLETE</oracle-approved>\\`\\n - If REJECTED: Continue working on the identified issues\\n\\nDO NOT output the completion promise again until Oracle approves.\\n\\n</ralph-verification>\\n\\n---\\n\"}\nEOF\n exit 0\n fi\n fi\n\n if [ \"$ITERATION\" -lt \"$MAX_ITER\" ]; then\n # Increment iteration\n NEW_ITER=$((ITERATION + 1))\n echo \"$RALPH_STATE\" | jq \".iteration = $NEW_ITER\" > \"$DIRECTORY/.sisyphus/ralph-state.json\" 2>/dev/null\n\n cat << EOF\n{\"continue\": false, \"reason\": \"<ralph-loop-continuation>\\n\\n[RALPH LOOP - ITERATION $NEW_ITER/$MAX_ITER]\\n\\nYour previous attempt did not output the completion promise. The work is NOT done yet.\\n\\nCRITICAL INSTRUCTIONS:\\n1. Review your progress and the original task\\n2. Check your todo list - are ALL items marked complete?\\n3. Continue from where you left off\\n4. When FULLY complete, output: <promise>$PROMISE</promise>\\n5. Do NOT stop until the task is truly done\\n\\nOriginal task: $PROMPT\\n\\n</ralph-loop-continuation>\\n\\n---\\n\"}\nEOF\n exit 0\n fi\n fi\nfi\n\n# Priority 2: Ultrawork Mode with incomplete todos\nif [ -n \"$ULTRAWORK_STATE\" ] && [ \"$INCOMPLETE_COUNT\" -gt 0 ]; then\n # Check if active (with jq fallback)\n IS_ACTIVE=\"\"\n if command -v jq &> /dev/null; then\n IS_ACTIVE=$(echo \"$ULTRAWORK_STATE\" | jq -r '.active // false' 2>/dev/null)\n else\n # Fallback: grep for \"active\": true\n if echo \"$ULTRAWORK_STATE\" | grep -q '\"active\"[[:space:]]*:[[:space:]]*true'; then\n IS_ACTIVE=\"true\"\n fi\n fi\n\n if [ \"$IS_ACTIVE\" = \"true\" ]; then\n # Get reinforcement count (with fallback)\n REINFORCE_COUNT=0\n if command -v jq &> /dev/null; then\n REINFORCE_COUNT=$(echo \"$ULTRAWORK_STATE\" | jq -r '.reinforcement_count // 0' 2>/dev/null)\n else\n REINFORCE_COUNT=$(echo \"$ULTRAWORK_STATE\" | grep -oP '\"reinforcement_count\"[[:space:]]*:[[:space:]]*\\K[0-9]+' 2>/dev/null) || REINFORCE_COUNT=0\n fi\n NEW_COUNT=$((REINFORCE_COUNT + 1))\n\n # Get original prompt (with fallback)\n ORIGINAL_PROMPT=\"\"\n if command -v jq &> /dev/null; then\n ORIGINAL_PROMPT=$(echo \"$ULTRAWORK_STATE\" | jq -r '.original_prompt // \"\"' 2>/dev/null)\n else\n ORIGINAL_PROMPT=$(echo \"$ULTRAWORK_STATE\" | grep -oP '\"original_prompt\"[[:space:]]*:[[:space:]]*\"\\K[^\"]+' 2>/dev/null) || ORIGINAL_PROMPT=\"\"\n fi\n\n # Update state file (best effort)\n if command -v jq &> /dev/null; then\n echo \"$ULTRAWORK_STATE\" | jq \".reinforcement_count = $NEW_COUNT | .last_checked_at = \\\"$(date -Iseconds)\\\"\" > \"$DIRECTORY/.sisyphus/ultrawork-state.json\" 2>/dev/null\n fi\n\n cat << EOF\n{\"continue\": false, \"reason\": \"<ultrawork-persistence>\\n\\n[ULTRAWORK MODE STILL ACTIVE - Reinforcement #$NEW_COUNT]\\n\\nYour ultrawork session is NOT complete. $INCOMPLETE_COUNT incomplete todos remain.\\n\\nREMEMBER THE ULTRAWORK RULES:\\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially\\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent)\\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each\\n- **VERIFY**: Check ALL requirements met before done\\n- **NO Premature Stopping**: ALL TODOs must be complete\\n\\nContinue working on the next pending task. DO NOT STOP until all tasks are marked complete.\\n\\nOriginal task: $ORIGINAL_PROMPT\\n\\n</ultrawork-persistence>\\n\\n---\\n\"}\nEOF\n exit 0\n fi\nfi\n\n# Priority 3: Todo Continuation (baseline)\nif [ \"$INCOMPLETE_COUNT\" -gt 0 ]; then\n cat << EOF\n{\"continue\": false, \"reason\": \"<todo-continuation>\\n\\n[SYSTEM REMINDER - TODO CONTINUATION]\\n\\nIncomplete tasks remain in your todo list ($INCOMPLETE_COUNT remaining). Continue working on the next pending task.\\n\\n- Proceed without asking for permission\\n- Mark each task complete when finished\\n- Do not stop until all tasks are done\\n\\n</todo-continuation>\\n\\n---\\n\"}\nEOF\n exit 0\nfi\n\n# No blocking needed\necho '{\"continue\": true}'\nexit 0\n";
84
84
  /**
85
85
  * Session Start Bash script
86
86
  * Restores persistent mode states when a new session starts
@@ -89,7 +89,7 @@ export declare const SESSION_START_SCRIPT = "#!/bin/bash\n# Sisyphus Session Sta
89
89
  /**
90
90
  * Node.js Persistent Mode Hook Script
91
91
  */
92
- export declare const PERSISTENT_MODE_SCRIPT_NODE = "#!/usr/bin/env node\n// Sisyphus Persistent Mode Hook (Node.js)\n// Unified handler for ultrawork, ralph-loop, and todo continuation\n// Cross-platform: Windows, macOS, Linux\n\nimport { existsSync, readFileSync, writeFileSync, readdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nasync function readStdin() {\n const chunks = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nfunction readJsonFile(path) {\n try {\n if (!existsSync(path)) return null;\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction writeJsonFile(path, data) {\n try {\n writeFileSync(path, JSON.stringify(data, null, 2));\n return true;\n } catch {\n return false;\n }\n}\n\nfunction countIncompleteTodos(todosDir, projectDir) {\n let count = 0;\n\n // Check global todos\n if (existsSync(todosDir)) {\n try {\n const files = readdirSync(todosDir).filter(f => f.endsWith('.json'));\n for (const file of files) {\n const todos = readJsonFile(join(todosDir, file));\n if (Array.isArray(todos)) {\n count += todos.filter(t => t.status !== 'completed' && t.status !== 'cancelled').length;\n }\n }\n } catch {}\n }\n\n // Check project todos\n for (const path of [\n join(projectDir, '.sisyphus', 'todos.json'),\n join(projectDir, '.claude', 'todos.json')\n ]) {\n const todos = readJsonFile(path);\n if (Array.isArray(todos)) {\n count += todos.filter(t => t.status !== 'completed' && t.status !== 'cancelled').length;\n }\n }\n\n return count;\n}\n\nasync function main() {\n try {\n const input = await readStdin();\n let data = {};\n try { data = JSON.parse(input); } catch {}\n\n const directory = data.directory || process.cwd();\n const todosDir = join(homedir(), '.claude', 'todos');\n\n // Check for ultrawork state\n let ultraworkState = readJsonFile(join(directory, '.sisyphus', 'ultrawork-state.json'))\n || readJsonFile(join(homedir(), '.claude', 'ultrawork-state.json'));\n\n // Check for ralph loop state\n const ralphState = readJsonFile(join(directory, '.sisyphus', 'ralph-state.json'));\n\n // Count incomplete todos\n const incompleteCount = countIncompleteTodos(todosDir, directory);\n\n // Priority 1: Ralph Loop\n if (ralphState?.active) {\n const iteration = ralphState.iteration || 1;\n const maxIter = ralphState.max_iterations || 10;\n\n if (iteration < maxIter) {\n const newIter = iteration + 1;\n ralphState.iteration = newIter;\n writeJsonFile(join(directory, '.sisyphus', 'ralph-state.json'), ralphState);\n\n console.log(JSON.stringify({\n continue: false,\n reason: `<ralph-loop-continuation>\n\n[RALPH LOOP - ITERATION ${newIter}/${maxIter}]\n\nYour previous attempt did not output the completion promise. The work is NOT done yet.\n\nCRITICAL INSTRUCTIONS:\n1. Review your progress and the original task\n2. Check your todo list - are ALL items marked complete?\n3. Continue from where you left off\n4. When FULLY complete, output: <promise>${ralphState.completion_promise || 'TASK_COMPLETE'}</promise>\n5. Do NOT stop until the task is truly done\n\n${ralphState.prompt ? `Original task: ${ralphState.prompt}` : ''}\n\n</ralph-loop-continuation>\n\n---\n`\n }));\n return;\n }\n }\n\n // Priority 2: Ultrawork with incomplete todos\n if (ultraworkState?.active && incompleteCount > 0) {\n const newCount = (ultraworkState.reinforcement_count || 0) + 1;\n ultraworkState.reinforcement_count = newCount;\n ultraworkState.last_checked_at = new Date().toISOString();\n\n writeJsonFile(join(directory, '.sisyphus', 'ultrawork-state.json'), ultraworkState);\n\n console.log(JSON.stringify({\n continue: false,\n reason: `<ultrawork-persistence>\n\n[ULTRAWORK MODE STILL ACTIVE - Reinforcement #${newCount}]\n\nYour ultrawork session is NOT complete. ${incompleteCount} incomplete todos remain.\n\nREMEMBER THE ULTRAWORK RULES:\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent)\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each\n- **VERIFY**: Check ALL requirements met before done\n- **NO Premature Stopping**: ALL TODOs must be complete\n\nContinue working on the next pending task. DO NOT STOP until all tasks are marked complete.\n\n${ultraworkState.original_prompt ? `Original task: ${ultraworkState.original_prompt}` : ''}\n\n</ultrawork-persistence>\n\n---\n`\n }));\n return;\n }\n\n // Priority 3: Todo Continuation\n if (incompleteCount > 0) {\n console.log(JSON.stringify({\n continue: false,\n reason: `<todo-continuation>\n\n[SYSTEM REMINDER - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list (${incompleteCount} remaining). Continue working on the next pending task.\n\n- Proceed without asking for permission\n- Mark each task complete when finished\n- Do not stop until all tasks are done\n\n</todo-continuation>\n\n---\n`\n }));\n return;\n }\n\n // No blocking needed\n console.log(JSON.stringify({ continue: true }));\n } catch (error) {\n console.log(JSON.stringify({ continue: true }));\n }\n}\n\nmain();\n";
92
+ export declare const PERSISTENT_MODE_SCRIPT_NODE = "#!/usr/bin/env node\n// Sisyphus Persistent Mode Hook (Node.js)\n// Unified handler for ultrawork, ralph-loop, and todo continuation\n// Cross-platform: Windows, macOS, Linux\n\nimport { existsSync, readFileSync, writeFileSync, readdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nasync function readStdin() {\n const chunks = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nfunction readJsonFile(path) {\n try {\n if (!existsSync(path)) return null;\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction writeJsonFile(path, data) {\n try {\n writeFileSync(path, JSON.stringify(data, null, 2));\n return true;\n } catch {\n return false;\n }\n}\n\nfunction countIncompleteTodos(todosDir, projectDir) {\n let count = 0;\n\n // Check global todos\n if (existsSync(todosDir)) {\n try {\n const files = readdirSync(todosDir).filter(f => f.endsWith('.json'));\n for (const file of files) {\n const todos = readJsonFile(join(todosDir, file));\n if (Array.isArray(todos)) {\n count += todos.filter(t => t.status !== 'completed' && t.status !== 'cancelled').length;\n }\n }\n } catch {}\n }\n\n // Check project todos\n for (const path of [\n join(projectDir, '.sisyphus', 'todos.json'),\n join(projectDir, '.claude', 'todos.json')\n ]) {\n const todos = readJsonFile(path);\n if (Array.isArray(todos)) {\n count += todos.filter(t => t.status !== 'completed' && t.status !== 'cancelled').length;\n }\n }\n\n return count;\n}\n\nasync function main() {\n try {\n const input = await readStdin();\n let data = {};\n try { data = JSON.parse(input); } catch {}\n\n const directory = data.directory || process.cwd();\n const todosDir = join(homedir(), '.claude', 'todos');\n\n // Check for ultrawork state\n let ultraworkState = readJsonFile(join(directory, '.sisyphus', 'ultrawork-state.json'))\n || readJsonFile(join(homedir(), '.claude', 'ultrawork-state.json'));\n\n // Check for ralph loop state\n const ralphState = readJsonFile(join(directory, '.sisyphus', 'ralph-state.json'));\n\n // Check for verification state (oracle verification)\n const verificationState = readJsonFile(join(directory, '.sisyphus', 'ralph-verification.json'));\n\n // Count incomplete todos\n const incompleteCount = countIncompleteTodos(todosDir, directory);\n\n // Priority 1: Ralph Loop with Oracle Verification\n if (ralphState?.active) {\n const iteration = ralphState.iteration || 1;\n const maxIter = ralphState.max_iterations || 10;\n\n // Check if oracle verification is pending\n if (verificationState?.pending) {\n const attempt = (verificationState.verification_attempts || 0) + 1;\n const maxAttempts = verificationState.max_verification_attempts || 3;\n\n console.log(JSON.stringify({\n continue: false,\n reason: `<ralph-verification>\n\n[ORACLE VERIFICATION REQUIRED - Attempt ${attempt}/${maxAttempts}]\n\nThe agent claims the task is complete. Before accepting, YOU MUST verify with Oracle.\n\n**Original Task:**\n${verificationState.original_task || ralphState.prompt || 'No task specified'}\n\n**Completion Claim:**\n${verificationState.completion_claim || 'Task marked complete'}\n\n${verificationState.oracle_feedback ? `**Previous Oracle Feedback (rejected):**\n${verificationState.oracle_feedback}\n` : ''}\n\n## MANDATORY VERIFICATION STEPS\n\n1. **Spawn Oracle Agent** for verification:\n \\`\\`\\`\n Task(subagent_type=\"oracle\", prompt=\"Verify this task completion claim...\")\n \\`\\`\\`\n\n2. **Oracle must check:**\n - Are ALL requirements from the original task met?\n - Is the implementation complete, not partial?\n - Are there any obvious bugs or issues?\n - Does the code compile/run without errors?\n - Are tests passing (if applicable)?\n\n3. **Based on Oracle's response:**\n - If APPROVED: Output \\`<oracle-approved>VERIFIED_COMPLETE</oracle-approved>\\`\n - If REJECTED: Continue working on the identified issues\n\nDO NOT output the completion promise again until Oracle approves.\n\n</ralph-verification>\n\n---\n`\n }));\n return;\n }\n\n if (iteration < maxIter) {\n const newIter = iteration + 1;\n ralphState.iteration = newIter;\n writeJsonFile(join(directory, '.sisyphus', 'ralph-state.json'), ralphState);\n\n console.log(JSON.stringify({\n continue: false,\n reason: `<ralph-loop-continuation>\n\n[RALPH LOOP - ITERATION ${newIter}/${maxIter}]\n\nYour previous attempt did not output the completion promise. The work is NOT done yet.\n\nCRITICAL INSTRUCTIONS:\n1. Review your progress and the original task\n2. Check your todo list - are ALL items marked complete?\n3. Continue from where you left off\n4. When FULLY complete, output: <promise>${ralphState.completion_promise || 'TASK_COMPLETE'}</promise>\n5. Do NOT stop until the task is truly done\n\n${ralphState.prompt ? `Original task: ${ralphState.prompt}` : ''}\n\n</ralph-loop-continuation>\n\n---\n`\n }));\n return;\n }\n }\n\n // Priority 2: Ultrawork with incomplete todos\n if (ultraworkState?.active && incompleteCount > 0) {\n const newCount = (ultraworkState.reinforcement_count || 0) + 1;\n ultraworkState.reinforcement_count = newCount;\n ultraworkState.last_checked_at = new Date().toISOString();\n\n writeJsonFile(join(directory, '.sisyphus', 'ultrawork-state.json'), ultraworkState);\n\n console.log(JSON.stringify({\n continue: false,\n reason: `<ultrawork-persistence>\n\n[ULTRAWORK MODE STILL ACTIVE - Reinforcement #${newCount}]\n\nYour ultrawork session is NOT complete. ${incompleteCount} incomplete todos remain.\n\nREMEMBER THE ULTRAWORK RULES:\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent)\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each\n- **VERIFY**: Check ALL requirements met before done\n- **NO Premature Stopping**: ALL TODOs must be complete\n\nContinue working on the next pending task. DO NOT STOP until all tasks are marked complete.\n\n${ultraworkState.original_prompt ? `Original task: ${ultraworkState.original_prompt}` : ''}\n\n</ultrawork-persistence>\n\n---\n`\n }));\n return;\n }\n\n // Priority 3: Todo Continuation\n if (incompleteCount > 0) {\n console.log(JSON.stringify({\n continue: false,\n reason: `<todo-continuation>\n\n[SYSTEM REMINDER - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list (${incompleteCount} remaining). Continue working on the next pending task.\n\n- Proceed without asking for permission\n- Mark each task complete when finished\n- Do not stop until all tasks are done\n\n</todo-continuation>\n\n---\n`\n }));\n return;\n }\n\n // No blocking needed\n console.log(JSON.stringify({ continue: true }));\n } catch (error) {\n console.log(JSON.stringify({ continue: true }));\n }\n}\n\nmain();\n";
93
93
  /**
94
94
  * Node.js Session Start Hook Script
95
95
  */
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/installer/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,kCAAkC;AAClC,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,IAAI,OAAO,CAU5C;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,mCAAmC;AACnC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,woJA2F7B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,wcAgB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,2TAU1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,8cAgB3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,+PAME,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,uBAAuB,khMAsGnC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,u7CAwCpC,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,+lNAsMxC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,svEAgFzC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,ixNA+IlC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,g0EA8DhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,m3KAyLvC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,0iFAoGrC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;CAiCtC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;CAyCtC,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,0BAA0B,CAE1E;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;CAA6B,CAAC;AAMhE;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKpD,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEvD;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAqB,CAAC"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/installer/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,kCAAkC;AAClC,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,IAAI,OAAO,CAU5C;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,mCAAmC;AACnC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,woJA2F7B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,wcAgB9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,2TAU1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,8cAgB3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,+PAME,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,uBAAuB,khMAsGnC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,u7CAwCpC,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,+lNAsMxC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,svEAgFzC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,yqSA4KlC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,g0EA8DhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,4oOA+OvC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,0iFAoGrC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;CAiCtC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;CAyCtC,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,0BAA0B,CAE1E;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;CAA6B,CAAC;AAMhE;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKpD,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEvD;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAqB,CAAC"}
@@ -700,6 +700,12 @@ if [ -f "$DIRECTORY/.sisyphus/ralph-state.json" ]; then
700
700
  RALPH_STATE=$(cat "$DIRECTORY/.sisyphus/ralph-state.json" 2>/dev/null)
701
701
  fi
702
702
 
703
+ # Check for verification state (oracle verification)
704
+ VERIFICATION_STATE=""
705
+ if [ -f "$DIRECTORY/.sisyphus/ralph-verification.json" ]; then
706
+ VERIFICATION_STATE=$(cat "$DIRECTORY/.sisyphus/ralph-verification.json" 2>/dev/null)
707
+ fi
708
+
703
709
  # Check for incomplete todos
704
710
  INCOMPLETE_COUNT=0
705
711
  TODOS_DIR="$HOME/.claude/todos"
@@ -732,7 +738,7 @@ for todo_path in "$DIRECTORY/.sisyphus/todos.json" "$DIRECTORY/.claude/todos.jso
732
738
  fi
733
739
  done
734
740
 
735
- # Priority 1: Ralph Loop
741
+ # Priority 1: Ralph Loop with Oracle Verification
736
742
  if [ -n "$RALPH_STATE" ]; then
737
743
  IS_ACTIVE=$(echo "$RALPH_STATE" | jq -r '.active // false' 2>/dev/null)
738
744
  if [ "$IS_ACTIVE" = "true" ]; then
@@ -741,6 +747,29 @@ if [ -n "$RALPH_STATE" ]; then
741
747
  PROMISE=$(echo "$RALPH_STATE" | jq -r '.completion_promise // "TASK_COMPLETE"' 2>/dev/null)
742
748
  PROMPT=$(echo "$RALPH_STATE" | jq -r '.prompt // ""' 2>/dev/null)
743
749
 
750
+ # Check if oracle verification is pending
751
+ if [ -n "$VERIFICATION_STATE" ]; then
752
+ IS_PENDING=$(echo "$VERIFICATION_STATE" | jq -r '.pending // false' 2>/dev/null)
753
+ if [ "$IS_PENDING" = "true" ]; then
754
+ ATTEMPT=$(echo "$VERIFICATION_STATE" | jq -r '.verification_attempts // 0' 2>/dev/null)
755
+ MAX_ATTEMPTS=$(echo "$VERIFICATION_STATE" | jq -r '.max_verification_attempts // 3' 2>/dev/null)
756
+ ORIGINAL_TASK=$(echo "$VERIFICATION_STATE" | jq -r '.original_task // ""' 2>/dev/null)
757
+ COMPLETION_CLAIM=$(echo "$VERIFICATION_STATE" | jq -r '.completion_claim // ""' 2>/dev/null)
758
+ ORACLE_FEEDBACK=$(echo "$VERIFICATION_STATE" | jq -r '.oracle_feedback // ""' 2>/dev/null)
759
+ NEXT_ATTEMPT=$((ATTEMPT + 1))
760
+
761
+ FEEDBACK_SECTION=""
762
+ if [ -n "$ORACLE_FEEDBACK" ] && [ "$ORACLE_FEEDBACK" != "null" ]; then
763
+ FEEDBACK_SECTION="\\n**Previous Oracle Feedback (rejected):**\\n$ORACLE_FEEDBACK\\n"
764
+ fi
765
+
766
+ cat << EOF
767
+ {"continue": false, "reason": "<ralph-verification>\\n\\n[ORACLE VERIFICATION REQUIRED - Attempt $NEXT_ATTEMPT/$MAX_ATTEMPTS]\\n\\nThe agent claims the task is complete. Before accepting, YOU MUST verify with Oracle.\\n\\n**Original Task:**\\n$ORIGINAL_TASK\\n\\n**Completion Claim:**\\n$COMPLETION_CLAIM\\n$FEEDBACK_SECTION\\n## MANDATORY VERIFICATION STEPS\\n\\n1. **Spawn Oracle Agent** for verification:\\n \\\`\\\`\\\`\\n Task(subagent_type=\\"oracle\\", prompt=\\"Verify this task completion claim...\\")\\n \\\`\\\`\\\`\\n\\n2. **Oracle must check:**\\n - Are ALL requirements from the original task met?\\n - Is the implementation complete, not partial?\\n - Are there any obvious bugs or issues?\\n - Does the code compile/run without errors?\\n - Are tests passing (if applicable)?\\n\\n3. **Based on Oracle's response:**\\n - If APPROVED: Output \\\`<oracle-approved>VERIFIED_COMPLETE</oracle-approved>\\\`\\n - If REJECTED: Continue working on the identified issues\\n\\nDO NOT output the completion promise again until Oracle approves.\\n\\n</ralph-verification>\\n\\n---\\n"}
768
+ EOF
769
+ exit 0
770
+ fi
771
+ fi
772
+
744
773
  if [ "$ITERATION" -lt "$MAX_ITER" ]; then
745
774
  # Increment iteration
746
775
  NEW_ITER=$((ITERATION + 1))
@@ -960,14 +989,68 @@ async function main() {
960
989
  // Check for ralph loop state
961
990
  const ralphState = readJsonFile(join(directory, '.sisyphus', 'ralph-state.json'));
962
991
 
992
+ // Check for verification state (oracle verification)
993
+ const verificationState = readJsonFile(join(directory, '.sisyphus', 'ralph-verification.json'));
994
+
963
995
  // Count incomplete todos
964
996
  const incompleteCount = countIncompleteTodos(todosDir, directory);
965
997
 
966
- // Priority 1: Ralph Loop
998
+ // Priority 1: Ralph Loop with Oracle Verification
967
999
  if (ralphState?.active) {
968
1000
  const iteration = ralphState.iteration || 1;
969
1001
  const maxIter = ralphState.max_iterations || 10;
970
1002
 
1003
+ // Check if oracle verification is pending
1004
+ if (verificationState?.pending) {
1005
+ const attempt = (verificationState.verification_attempts || 0) + 1;
1006
+ const maxAttempts = verificationState.max_verification_attempts || 3;
1007
+
1008
+ console.log(JSON.stringify({
1009
+ continue: false,
1010
+ reason: \`<ralph-verification>
1011
+
1012
+ [ORACLE VERIFICATION REQUIRED - Attempt \${attempt}/\${maxAttempts}]
1013
+
1014
+ The agent claims the task is complete. Before accepting, YOU MUST verify with Oracle.
1015
+
1016
+ **Original Task:**
1017
+ \${verificationState.original_task || ralphState.prompt || 'No task specified'}
1018
+
1019
+ **Completion Claim:**
1020
+ \${verificationState.completion_claim || 'Task marked complete'}
1021
+
1022
+ \${verificationState.oracle_feedback ? \`**Previous Oracle Feedback (rejected):**
1023
+ \${verificationState.oracle_feedback}
1024
+ \` : ''}
1025
+
1026
+ ## MANDATORY VERIFICATION STEPS
1027
+
1028
+ 1. **Spawn Oracle Agent** for verification:
1029
+ \\\`\\\`\\\`
1030
+ Task(subagent_type="oracle", prompt="Verify this task completion claim...")
1031
+ \\\`\\\`\\\`
1032
+
1033
+ 2. **Oracle must check:**
1034
+ - Are ALL requirements from the original task met?
1035
+ - Is the implementation complete, not partial?
1036
+ - Are there any obvious bugs or issues?
1037
+ - Does the code compile/run without errors?
1038
+ - Are tests passing (if applicable)?
1039
+
1040
+ 3. **Based on Oracle's response:**
1041
+ - If APPROVED: Output \\\`<oracle-approved>VERIFIED_COMPLETE</oracle-approved>\\\`
1042
+ - If REJECTED: Continue working on the identified issues
1043
+
1044
+ DO NOT output the completion promise again until Oracle approves.
1045
+
1046
+ </ralph-verification>
1047
+
1048
+ ---
1049
+ \`
1050
+ }));
1051
+ return;
1052
+ }
1053
+
971
1054
  if (iteration < maxIter) {
972
1055
  const newIter = iteration + 1;
973
1056
  ralphState.iteration = newIter;
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/installer/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/installer/hooks.ts"],"names":[],"mappings":"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"}
@@ -736,7 +736,7 @@ You are "Sisyphus" - Powerful AI Agent with orchestration capabilities from OhMy
736
736
  - Adapting to codebase maturity (disciplined vs chaotic)
737
737
  - Delegating specialized work to the right subagents
738
738
  - Parallel execution for maximum throughput
739
- - Follows user instructions. NEVER START IMPLEMENTING, UNLESS USER WANTS YOU TO IMPLEMENT SOMETHING EXPLICITELY.
739
+ - Follows user instructions. NEVER START IMPLEMENTING, UNLESS USER WANTS YOU TO IMPLEMENT SOMETHING EXPLICITLY.
740
740
 
741
741
  **Operating Mode**: You NEVER work alone when specialists are available. Frontend work → delegate. Deep research → parallel background agents. Complex architecture → consult Oracle.
742
742
 
@@ -1540,7 +1540,7 @@ Named by [YeonGyu Kim](https://github.com/code-yeongyu).
1540
1540
  - Adapting to codebase maturity (disciplined vs chaotic)
1541
1541
  - Delegating specialized work to the right subagents
1542
1542
  - Parallel execution for maximum throughput
1543
- - Follows user instructions. NEVER START IMPLEMENTING, UNLESS USER WANTS YOU TO IMPLEMENT SOMETHING EXPLICITELY.
1543
+ - Follows user instructions. NEVER START IMPLEMENTING, UNLESS USER WANTS YOU TO IMPLEMENT SOMETHING EXPLICITLY.
1544
1544
  - KEEP IN MIND: YOUR TODO CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TODO CONTINUATION]), BUT IF NOT USER REQUESTED YOU TO WORK, NEVER START WORK.
1545
1545
 
1546
1546
  **Operating Mode**: You NEVER work alone when specialists are available. Frontend work → delegate. Deep research → parallel background agents (async subagents). Complex architecture → consult Oracle.
@@ -2866,7 +2866,7 @@ Named by [YeonGyu Kim](https://github.com/code-yeongyu).
2866
2866
  - Adapting to codebase maturity (disciplined vs chaotic)
2867
2867
  - Delegating specialized work to the right subagents
2868
2868
  - Parallel execution for maximum throughput
2869
- - Follows user instructions. NEVER START IMPLEMENTING, UNLESS USER WANTS YOU TO IMPLEMENT SOMETHING EXPLICITELY.
2869
+ - Follows user instructions. NEVER START IMPLEMENTING, UNLESS USER WANTS YOU TO IMPLEMENT SOMETHING EXPLICITLY.
2870
2870
  - KEEP IN MIND: YOUR TODO CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TODO CONTINUATION]), BUT IF NOT USER REQUESTED YOU TO WORK, NEVER START WORK.
2871
2871
 
2872
2872
  **Operating Mode**: You NEVER work alone when specialists are available. Frontend work → delegate. Deep research → parallel background agents (async subagents). Complex architecture → consult Oracle.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Provider module exports
3
+ */
4
+ export type { ProviderType, ModelId, AuthType, ProviderConfig, ResolvedModel, ModelInfo, OAuthTokens, OAuthConfig, } from './types.js';
5
+ export { getProviderFromModelId, getModelNameFromId, createModelId, } from './types.js';
6
+ export { MODEL_REGISTRY, getModelInfo, getModelsForProvider, isKnownModel, getAllModelIds, DEFAULT_MODELS, } from './registry.js';
7
+ export { ModelRouter, createModelRouter } from './router.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,aAAa,EACb,SAAS,EACT,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,cAAc,GACf,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Provider module exports
3
+ */
4
+ // Type utilities
5
+ export { getProviderFromModelId, getModelNameFromId, createModelId, } from './types.js';
6
+ // Registry
7
+ export { MODEL_REGISTRY, getModelInfo, getModelsForProvider, isKnownModel, getAllModelIds, DEFAULT_MODELS, } from './registry.js';
8
+ // Router
9
+ export { ModelRouter, createModelRouter } from './router.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,iBAAiB;AACjB,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,WAAW;AACX,OAAO,EACL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Model registry with known models and their capabilities
3
+ */
4
+ import type { ModelId, ModelInfo, ProviderType } from './types.js';
5
+ /**
6
+ * Registry of known models with their capabilities
7
+ */
8
+ export declare const MODEL_REGISTRY: Record<string, ModelInfo>;
9
+ /**
10
+ * Get model info from the registry
11
+ */
12
+ export declare function getModelInfo(modelId: ModelId): ModelInfo | undefined;
13
+ /**
14
+ * Get all models for a specific provider
15
+ */
16
+ export declare function getModelsForProvider(provider: ProviderType): ModelInfo[];
17
+ /**
18
+ * Check if a model is known in the registry
19
+ */
20
+ export declare function isKnownModel(modelId: ModelId): boolean;
21
+ /**
22
+ * Get all known model IDs
23
+ */
24
+ export declare function getAllModelIds(): ModelId[];
25
+ /**
26
+ * Get default models for each provider
27
+ */
28
+ export declare const DEFAULT_MODELS: Record<ProviderType, ModelId>;
29
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnE;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CA2HpD,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,CAExE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,EAAE,CAE1C;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,YAAY,EAAE,OAAO,CAKxD,CAAC"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Model registry with known models and their capabilities
3
+ */
4
+ /**
5
+ * Registry of known models with their capabilities
6
+ */
7
+ export const MODEL_REGISTRY = {
8
+ // OpenAI Models (OAuth - ChatGPT Plus/Pro)
9
+ 'openai/gpt-4o': {
10
+ id: 'openai/gpt-4o',
11
+ provider: 'openai',
12
+ displayName: 'GPT-4o',
13
+ contextWindow: 128000,
14
+ supportsVision: true,
15
+ supportsTools: true,
16
+ supportsStreaming: true,
17
+ },
18
+ 'openai/gpt-4o-mini': {
19
+ id: 'openai/gpt-4o-mini',
20
+ provider: 'openai',
21
+ displayName: 'GPT-4o Mini',
22
+ contextWindow: 128000,
23
+ supportsVision: true,
24
+ supportsTools: true,
25
+ supportsStreaming: true,
26
+ },
27
+ 'openai/o1': {
28
+ id: 'openai/o1',
29
+ provider: 'openai',
30
+ displayName: 'o1',
31
+ contextWindow: 200000,
32
+ supportsVision: true,
33
+ supportsTools: false,
34
+ supportsStreaming: false,
35
+ },
36
+ 'openai/o1-mini': {
37
+ id: 'openai/o1-mini',
38
+ provider: 'openai',
39
+ displayName: 'o1-mini',
40
+ contextWindow: 128000,
41
+ supportsVision: false,
42
+ supportsTools: false,
43
+ supportsStreaming: false,
44
+ },
45
+ 'openai/o1-pro': {
46
+ id: 'openai/o1-pro',
47
+ provider: 'openai',
48
+ displayName: 'o1-pro',
49
+ contextWindow: 200000,
50
+ supportsVision: true,
51
+ supportsTools: false,
52
+ supportsStreaming: false,
53
+ },
54
+ 'openai/o3-mini': {
55
+ id: 'openai/o3-mini',
56
+ provider: 'openai',
57
+ displayName: 'o3-mini',
58
+ contextWindow: 200000,
59
+ supportsVision: true,
60
+ supportsTools: true,
61
+ supportsStreaming: true,
62
+ },
63
+ // Google Models (OAuth - Consumer Account)
64
+ 'google/gemini-2.0-flash': {
65
+ id: 'google/gemini-2.0-flash',
66
+ provider: 'google',
67
+ displayName: 'Gemini 2.0 Flash',
68
+ contextWindow: 1000000,
69
+ supportsVision: true,
70
+ supportsTools: true,
71
+ supportsStreaming: true,
72
+ },
73
+ 'google/gemini-2.0-flash-lite': {
74
+ id: 'google/gemini-2.0-flash-lite',
75
+ provider: 'google',
76
+ displayName: 'Gemini 2.0 Flash Lite',
77
+ contextWindow: 1000000,
78
+ supportsVision: true,
79
+ supportsTools: true,
80
+ supportsStreaming: true,
81
+ },
82
+ 'google/gemini-1.5-pro': {
83
+ id: 'google/gemini-1.5-pro',
84
+ provider: 'google',
85
+ displayName: 'Gemini 1.5 Pro',
86
+ contextWindow: 2000000,
87
+ supportsVision: true,
88
+ supportsTools: true,
89
+ supportsStreaming: true,
90
+ },
91
+ 'google/gemini-1.5-flash': {
92
+ id: 'google/gemini-1.5-flash',
93
+ provider: 'google',
94
+ displayName: 'Gemini 1.5 Flash',
95
+ contextWindow: 1000000,
96
+ supportsVision: true,
97
+ supportsTools: true,
98
+ supportsStreaming: true,
99
+ },
100
+ // Anthropic Models (API Key)
101
+ 'anthropic/claude-opus-4-5': {
102
+ id: 'anthropic/claude-opus-4-5',
103
+ provider: 'anthropic',
104
+ displayName: 'Claude Opus 4.5',
105
+ contextWindow: 200000,
106
+ supportsVision: true,
107
+ supportsTools: true,
108
+ supportsStreaming: true,
109
+ },
110
+ 'anthropic/claude-sonnet-4-5': {
111
+ id: 'anthropic/claude-sonnet-4-5',
112
+ provider: 'anthropic',
113
+ displayName: 'Claude Sonnet 4.5',
114
+ contextWindow: 200000,
115
+ supportsVision: true,
116
+ supportsTools: true,
117
+ supportsStreaming: true,
118
+ },
119
+ 'anthropic/claude-haiku-4-5': {
120
+ id: 'anthropic/claude-haiku-4-5',
121
+ provider: 'anthropic',
122
+ displayName: 'Claude Haiku 4.5',
123
+ contextWindow: 200000,
124
+ supportsVision: true,
125
+ supportsTools: true,
126
+ supportsStreaming: true,
127
+ },
128
+ };
129
+ /**
130
+ * Get model info from the registry
131
+ */
132
+ export function getModelInfo(modelId) {
133
+ return MODEL_REGISTRY[modelId];
134
+ }
135
+ /**
136
+ * Get all models for a specific provider
137
+ */
138
+ export function getModelsForProvider(provider) {
139
+ return Object.values(MODEL_REGISTRY).filter(m => m.provider === provider);
140
+ }
141
+ /**
142
+ * Check if a model is known in the registry
143
+ */
144
+ export function isKnownModel(modelId) {
145
+ return modelId in MODEL_REGISTRY;
146
+ }
147
+ /**
148
+ * Get all known model IDs
149
+ */
150
+ export function getAllModelIds() {
151
+ return Object.keys(MODEL_REGISTRY);
152
+ }
153
+ /**
154
+ * Get default models for each provider
155
+ */
156
+ export const DEFAULT_MODELS = {
157
+ anthropic: 'anthropic/claude-sonnet-4-5',
158
+ openai: 'openai/gpt-4o',
159
+ google: 'google/gemini-2.0-flash',
160
+ openrouter: 'openrouter/anthropic/claude-3.5-sonnet', // OpenRouter uses passthrough
161
+ };
162
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Model router - resolves agent model preferences to actual models
3
+ * based on provider authentication status
4
+ */
5
+ import type { ModelId, ResolvedModel } from './types.js';
6
+ import type { AuthManager } from '../auth/manager.js';
7
+ /**
8
+ * Model router that resolves agent model lists to available models
9
+ */
10
+ export declare class ModelRouter {
11
+ private authManager;
12
+ constructor(authManager: AuthManager);
13
+ /**
14
+ * Resolve a model list to the first available authenticated model
15
+ *
16
+ * @param modelList - Ordered list of preferred models
17
+ * @returns The resolved model with provider info
18
+ * @throws Error if no authenticated provider is available for any model
19
+ */
20
+ resolveModel(modelList: ModelId[]): Promise<ResolvedModel>;
21
+ /**
22
+ * Check if any model in the list can be used
23
+ *
24
+ * @param modelList - List of models to check
25
+ * @returns true if at least one model has an authenticated provider
26
+ */
27
+ canResolve(modelList: ModelId[]): Promise<boolean>;
28
+ /**
29
+ * Get the first available model from the list without throwing
30
+ *
31
+ * @param modelList - List of models to check
32
+ * @returns The resolved model or null if none available
33
+ */
34
+ tryResolveModel(modelList: ModelId[]): Promise<ResolvedModel | null>;
35
+ }
36
+ /**
37
+ * Create a model router instance
38
+ */
39
+ export declare function createModelRouter(authManager: AuthManager): ModelRouter;
40
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/providers/router.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAC;AAEvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,WAAW;IAE5C;;;;;;OAMG;IACG,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAqChE;;;;;OAKG;IACG,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAexD;;;;;OAKG;IACG,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;CAO3E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW,CAEvE"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Model router - resolves agent model preferences to actual models
3
+ * based on provider authentication status
4
+ */
5
+ import { getProviderFromModelId, getModelNameFromId } from './types.js';
6
+ /**
7
+ * Model router that resolves agent model lists to available models
8
+ */
9
+ export class ModelRouter {
10
+ authManager;
11
+ constructor(authManager) {
12
+ this.authManager = authManager;
13
+ }
14
+ /**
15
+ * Resolve a model list to the first available authenticated model
16
+ *
17
+ * @param modelList - Ordered list of preferred models
18
+ * @returns The resolved model with provider info
19
+ * @throws Error if no authenticated provider is available for any model
20
+ */
21
+ async resolveModel(modelList) {
22
+ if (!modelList || modelList.length === 0) {
23
+ throw new Error('Model list cannot be empty');
24
+ }
25
+ const triedProviders = [];
26
+ for (let i = 0; i < modelList.length; i++) {
27
+ const modelId = modelList[i];
28
+ const provider = getProviderFromModelId(modelId);
29
+ // Skip if we've already tried this provider
30
+ if (triedProviders.includes(provider)) {
31
+ continue;
32
+ }
33
+ triedProviders.push(provider);
34
+ const isAuthenticated = await this.authManager.isAuthenticated(provider);
35
+ if (isAuthenticated) {
36
+ return {
37
+ provider,
38
+ modelId,
39
+ modelName: getModelNameFromId(modelId),
40
+ isFallback: i > 0,
41
+ fallbackReason: i > 0 ? `Primary model "${modelList[0]}" unavailable (provider not authenticated)` : undefined,
42
+ };
43
+ }
44
+ }
45
+ // All models exhausted - throw error with details
46
+ throw new Error(`No authenticated provider available. Tried models: ${modelList.join(', ')}. ` +
47
+ `Run /connect <provider> to authenticate.`);
48
+ }
49
+ /**
50
+ * Check if any model in the list can be used
51
+ *
52
+ * @param modelList - List of models to check
53
+ * @returns true if at least one model has an authenticated provider
54
+ */
55
+ async canResolve(modelList) {
56
+ if (!modelList || modelList.length === 0) {
57
+ return false;
58
+ }
59
+ for (const modelId of modelList) {
60
+ const provider = getProviderFromModelId(modelId);
61
+ if (await this.authManager.isAuthenticated(provider)) {
62
+ return true;
63
+ }
64
+ }
65
+ return false;
66
+ }
67
+ /**
68
+ * Get the first available model from the list without throwing
69
+ *
70
+ * @param modelList - List of models to check
71
+ * @returns The resolved model or null if none available
72
+ */
73
+ async tryResolveModel(modelList) {
74
+ try {
75
+ return await this.resolveModel(modelList);
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ }
82
+ /**
83
+ * Create a model router instance
84
+ */
85
+ export function createModelRouter(authManager) {
86
+ return new ModelRouter(authManager);
87
+ }
88
+ //# sourceMappingURL=router.js.map