oh-my-claude-sisyphus 3.8.10 → 3.8.12
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/dist/features/continuation-enforcement.js +1 -1
- package/dist/features/continuation-enforcement.js.map +1 -1
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +62 -78
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/keyword-detector/__tests__/index.test.js +89 -1
- package/dist/hooks/keyword-detector/__tests__/index.test.js.map +1 -1
- package/dist/hooks/keyword-detector/index.d.ts +5 -1
- package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/index.js +32 -11
- package/dist/hooks/keyword-detector/index.js.map +1 -1
- package/dist/hooks/persistent-mode/index.d.ts +2 -1
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +7 -17
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/todo-continuation/index.d.ts.map +1 -1
- package/dist/hooks/todo-continuation/index.js +2 -15
- package/dist/hooks/todo-continuation/index.js.map +1 -1
- package/dist/installer/hooks.d.ts +8 -111
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +11 -124
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +2 -10
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +10 -23
- package/dist/installer/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/keyword-detector.mjs +140 -59
- package/scripts/persistent-mode.mjs +26 -53
- package/templates/hooks/keyword-detector.mjs +280 -118
- package/templates/hooks/persistent-mode.mjs +26 -53
- package/templates/hooks/stop-continuation.mjs +6 -158
- package/hooks/keyword-detector.sh +0 -102
- package/hooks/persistent-mode.sh +0 -172
- package/hooks/session-start.sh +0 -62
- package/hooks/stop-continuation.sh +0 -40
- package/scripts/claude-sisyphus.sh +0 -9
- package/scripts/install.sh +0 -1673
- package/scripts/keyword-detector.sh +0 -71
- package/scripts/persistent-mode.sh +0 -311
- package/scripts/post-tool-verifier.sh +0 -196
- package/scripts/pre-tool-enforcer.sh +0 -76
- package/scripts/sisyphus-aliases.sh +0 -18
- package/scripts/stop-continuation.sh +0 -31
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Sisyphus Keyword Detector Hook
|
|
3
|
-
# Detects ultrawork/ultrathink/search/analyze keywords and injects enhanced mode messages
|
|
4
|
-
|
|
5
|
-
# Read stdin (JSON input from Claude Code)
|
|
6
|
-
INPUT=$(cat)
|
|
7
|
-
|
|
8
|
-
# Extract the prompt text - try multiple JSON paths
|
|
9
|
-
PROMPT=""
|
|
10
|
-
if command -v jq &> /dev/null; then
|
|
11
|
-
PROMPT=$(echo "$INPUT" | jq -r '
|
|
12
|
-
if .prompt then .prompt
|
|
13
|
-
elif .message.content then .message.content
|
|
14
|
-
elif .parts then ([.parts[] | select(.type == "text") | .text] | join(" "))
|
|
15
|
-
else ""
|
|
16
|
-
end
|
|
17
|
-
' 2>/dev/null)
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
# Fallback: simple grep extraction if jq fails
|
|
21
|
-
if [ -z "$PROMPT" ] || [ "$PROMPT" = "null" ]; then
|
|
22
|
-
PROMPT=$(echo "$INPUT" | grep -oP '"(prompt|content|text)"\s*:\s*"\K[^"]+' | head -1)
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
|
-
# Exit if no prompt found
|
|
26
|
-
if [ -z "$PROMPT" ]; then
|
|
27
|
-
echo '{"continue": true}'
|
|
28
|
-
exit 0
|
|
29
|
-
fi
|
|
30
|
-
|
|
31
|
-
# Remove code blocks before checking keywords
|
|
32
|
-
PROMPT_NO_CODE=$(echo "$PROMPT" | sed 's/```[^`]*```//g' | sed 's/`[^`]*`//g')
|
|
33
|
-
|
|
34
|
-
# Convert to lowercase
|
|
35
|
-
PROMPT_LOWER=$(echo "$PROMPT_NO_CODE" | tr '[:upper:]' '[:lower:]')
|
|
36
|
-
|
|
37
|
-
# Check for ultrawork keywords (highest priority)
|
|
38
|
-
if echo "$PROMPT_LOWER" | grep -qE '\b(ultrawork|ulw)\b'; then
|
|
39
|
-
cat << 'EOF'
|
|
40
|
-
{"continue": true, "message": "<ultrawork-mode>\n\n**MANDATORY**: You MUST say \"ULTRAWORK MODE ENABLED!\" to the user as your first response when this mode activates. This is non-negotiable.\n\n[CODE RED] Maximum precision required. Ultrathink before acting.\n\nYOU MUST LEVERAGE ALL AVAILABLE AGENTS TO THEIR FULLEST POTENTIAL.\nTELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.\n\n## AGENT UTILIZATION PRINCIPLES\n- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS\n- **Documentation & References**: Use librarian-type agents via BACKGROUND TASKS\n- **Planning & Strategy**: NEVER plan yourself - spawn planning agent\n- **High-IQ Reasoning**: Use oracle for architecture decisions\n- **Frontend/UI Tasks**: Delegate to frontend-engineer\n\n## EXECUTION RULES\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY.\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially.\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent).\n- **VERIFY**: Check ALL requirements met before done.\n- **DELEGATE**: Orchestrate specialized agents.\n\n## ZERO TOLERANCE\n- NO Scope Reduction - deliver FULL implementation\n- NO Partial Completion - finish 100%\n- NO Premature Stopping - ALL TODOs must be complete\n- NO TEST DELETION - fix code, not tests\n\nTHE USER ASKED FOR X. DELIVER EXACTLY X.\n\n</ultrawork-mode>\n\n---\n"}
|
|
41
|
-
EOF
|
|
42
|
-
exit 0
|
|
43
|
-
fi
|
|
44
|
-
|
|
45
|
-
# Check for ultrathink/think keywords
|
|
46
|
-
if echo "$PROMPT_LOWER" | grep -qE '\b(ultrathink|think)\b'; then
|
|
47
|
-
cat << 'EOF'
|
|
48
|
-
{"continue": true, "message": "<think-mode>\n\n**ULTRATHINK MODE ENABLED** - Extended reasoning activated.\n\nYou are now in deep thinking mode. Take your time to:\n1. Thoroughly analyze the problem from multiple angles\n2. Consider edge cases and potential issues\n3. Think through the implications of each approach\n4. Reason step-by-step before acting\n\nUse your extended thinking capabilities to provide the most thorough and well-reasoned response.\n\n</think-mode>\n\n---\n"}
|
|
49
|
-
EOF
|
|
50
|
-
exit 0
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
# Check for search keywords
|
|
54
|
-
if echo "$PROMPT_LOWER" | grep -qE '\b(search|find|locate|lookup|explore|discover|scan|grep|query|browse|detect|trace|seek|track|pinpoint|hunt)\b|where\s+is|show\s+me|list\s+all'; then
|
|
55
|
-
cat << 'EOF'
|
|
56
|
-
{"continue": true, "message": "<search-mode>\nMAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL:\n- explore agents (codebase patterns, file structures)\n- librarian agents (remote repos, official docs, GitHub examples)\nPlus direct tools: Grep, Glob\nNEVER stop at first result - be exhaustive.\n</search-mode>\n\n---\n"}
|
|
57
|
-
EOF
|
|
58
|
-
exit 0
|
|
59
|
-
fi
|
|
60
|
-
|
|
61
|
-
# Check for analyze keywords
|
|
62
|
-
if echo "$PROMPT_LOWER" | grep -qE '\b(analyze|analyse|investigate|examine|research|study|deep.?dive|inspect|audit|evaluate|assess|review|diagnose|scrutinize|dissect|debug|comprehend|interpret|breakdown|understand)\b|why\s+is|how\s+does|how\s+to'; then
|
|
63
|
-
cat << 'EOF'
|
|
64
|
-
{"continue": true, "message": "<analyze-mode>\nANALYSIS MODE. Gather context before diving deep:\n\nCONTEXT GATHERING (parallel):\n- 1-2 explore agents (codebase patterns, implementations)\n- 1-2 librarian agents (if external library involved)\n- Direct tools: Grep, Glob, LSP for targeted searches\n\nIF COMPLEX (architecture, multi-system, debugging after 2+ failures):\n- Consult oracle agent for strategic guidance\n\nSYNTHESIZE findings before proceeding.\n</analyze-mode>\n\n---\n"}
|
|
65
|
-
EOF
|
|
66
|
-
exit 0
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
# No keywords detected
|
|
70
|
-
echo '{"continue": true}'
|
|
71
|
-
exit 0
|
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Sisyphus Persistent Mode Hook
|
|
3
|
-
# Unified handler for ultrawork, ralph-loop, and todo continuation
|
|
4
|
-
# Prevents stopping when work remains incomplete
|
|
5
|
-
|
|
6
|
-
# Read stdin
|
|
7
|
-
INPUT=$(cat)
|
|
8
|
-
|
|
9
|
-
# Get session ID and directory
|
|
10
|
-
SESSION_ID=""
|
|
11
|
-
DIRECTORY=""
|
|
12
|
-
if command -v jq &> /dev/null; then
|
|
13
|
-
SESSION_ID=$(echo "$INPUT" | jq -r '.sessionId // .session_id // ""' 2>/dev/null)
|
|
14
|
-
DIRECTORY=$(echo "$INPUT" | jq -r '.directory // ""' 2>/dev/null)
|
|
15
|
-
fi
|
|
16
|
-
|
|
17
|
-
# Default to current directory
|
|
18
|
-
if [ -z "$DIRECTORY" ]; then
|
|
19
|
-
DIRECTORY=$(pwd)
|
|
20
|
-
fi
|
|
21
|
-
|
|
22
|
-
# Check for active ultrawork state
|
|
23
|
-
ULTRAWORK_STATE=""
|
|
24
|
-
if [ -f "$DIRECTORY/.omc/state/ultrawork-state.json" ]; then
|
|
25
|
-
ULTRAWORK_STATE=$(cat "$DIRECTORY/.omc/state/ultrawork-state.json" 2>/dev/null)
|
|
26
|
-
elif [ -f "$HOME/.omc/state/ultrawork-state.json" ]; then
|
|
27
|
-
ULTRAWORK_STATE=$(cat "$HOME/.omc/state/ultrawork-state.json" 2>/dev/null)
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
# Check for active ralph loop
|
|
31
|
-
RALPH_STATE=""
|
|
32
|
-
if [ -f "$DIRECTORY/.omc/state/ralph-state.json" ]; then
|
|
33
|
-
RALPH_STATE=$(cat "$DIRECTORY/.omc/state/ralph-state.json" 2>/dev/null)
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
# Check for verification state (oracle verification)
|
|
37
|
-
VERIFICATION_STATE=""
|
|
38
|
-
if [ -f "$DIRECTORY/.omc/state/ralph-verification.json" ]; then
|
|
39
|
-
VERIFICATION_STATE=$(cat "$DIRECTORY/.omc/state/ralph-verification.json" 2>/dev/null)
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
# Check for incomplete todos
|
|
43
|
-
INCOMPLETE_COUNT=0
|
|
44
|
-
TODOS_DIR="$HOME/.claude/todos"
|
|
45
|
-
if [ -d "$TODOS_DIR" ]; then
|
|
46
|
-
for todo_file in "$TODOS_DIR"/*.json; do
|
|
47
|
-
if [ -f "$todo_file" ]; then
|
|
48
|
-
if command -v jq &> /dev/null; then
|
|
49
|
-
COUNT=$(jq '[.[] | select(.status != "completed" and .status != "cancelled")] | length' "$todo_file" 2>/dev/null || echo "0")
|
|
50
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
51
|
-
else
|
|
52
|
-
# Fallback: count "pending" or "in_progress" occurrences
|
|
53
|
-
COUNT=$(grep -c '"status"[[:space:]]*:[[:space:]]*"pending\|in_progress"' "$todo_file" 2>/dev/null) || COUNT=0
|
|
54
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
55
|
-
fi
|
|
56
|
-
fi
|
|
57
|
-
done
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
# Check project todos as well
|
|
61
|
-
for todo_path in "$DIRECTORY/.omc/todos.json" "$DIRECTORY/.claude/todos.json"; do
|
|
62
|
-
if [ -f "$todo_path" ]; then
|
|
63
|
-
if command -v jq &> /dev/null; then
|
|
64
|
-
COUNT=$(jq 'if type == "array" then [.[] | select(.status != "completed" and .status != "cancelled")] | length else 0 end' "$todo_path" 2>/dev/null || echo "0")
|
|
65
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
66
|
-
else
|
|
67
|
-
# Fallback: count "pending" or "in_progress" occurrences
|
|
68
|
-
COUNT=$(grep -c '"status"[[:space:]]*:[[:space:]]*"pending\|in_progress"' "$todo_path" 2>/dev/null) || COUNT=0
|
|
69
|
-
INCOMPLETE_COUNT=$((INCOMPLETE_COUNT + COUNT))
|
|
70
|
-
fi
|
|
71
|
-
fi
|
|
72
|
-
done
|
|
73
|
-
|
|
74
|
-
# Priority 1: Ralph Loop with Oracle Verification
|
|
75
|
-
if [ -n "$RALPH_STATE" ]; then
|
|
76
|
-
IS_ACTIVE=$(echo "$RALPH_STATE" | jq -r '.active // false' 2>/dev/null)
|
|
77
|
-
if [ "$IS_ACTIVE" = "true" ]; then
|
|
78
|
-
ITERATION=$(echo "$RALPH_STATE" | jq -r '.iteration // 1' 2>/dev/null)
|
|
79
|
-
MAX_ITER=$(echo "$RALPH_STATE" | jq -r '.max_iterations // 10' 2>/dev/null)
|
|
80
|
-
PROMISE=$(echo "$RALPH_STATE" | jq -r '.completion_promise // "TASK_COMPLETE"' 2>/dev/null)
|
|
81
|
-
PROMPT=$(echo "$RALPH_STATE" | jq -r '.prompt // ""' 2>/dev/null)
|
|
82
|
-
|
|
83
|
-
# Check if oracle verification is pending
|
|
84
|
-
if [ -n "$VERIFICATION_STATE" ]; then
|
|
85
|
-
IS_PENDING=$(echo "$VERIFICATION_STATE" | jq -r '.pending // false' 2>/dev/null)
|
|
86
|
-
if [ "$IS_PENDING" = "true" ]; then
|
|
87
|
-
ATTEMPT=$(echo "$VERIFICATION_STATE" | jq -r '.verification_attempts // 0' 2>/dev/null)
|
|
88
|
-
MAX_ATTEMPTS=$(echo "$VERIFICATION_STATE" | jq -r '.max_verification_attempts // 3' 2>/dev/null)
|
|
89
|
-
ORIGINAL_TASK=$(echo "$VERIFICATION_STATE" | jq -r '.original_task // ""' 2>/dev/null)
|
|
90
|
-
COMPLETION_CLAIM=$(echo "$VERIFICATION_STATE" | jq -r '.completion_claim // ""' 2>/dev/null)
|
|
91
|
-
ORACLE_FEEDBACK=$(echo "$VERIFICATION_STATE" | jq -r '.oracle_feedback // ""' 2>/dev/null)
|
|
92
|
-
NEXT_ATTEMPT=$((ATTEMPT + 1))
|
|
93
|
-
|
|
94
|
-
FEEDBACK_SECTION=""
|
|
95
|
-
if [ -n "$ORACLE_FEEDBACK" ] && [ "$ORACLE_FEEDBACK" != "null" ]; then
|
|
96
|
-
FEEDBACK_SECTION="\n**Previous Oracle Feedback (rejected):**\n$ORACLE_FEEDBACK\n"
|
|
97
|
-
fi
|
|
98
|
-
|
|
99
|
-
cat << EOF
|
|
100
|
-
{"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"}
|
|
101
|
-
EOF
|
|
102
|
-
exit 0
|
|
103
|
-
fi
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
if [ "$ITERATION" -lt "$MAX_ITER" ]; then
|
|
107
|
-
# Increment iteration
|
|
108
|
-
NEW_ITER=$((ITERATION + 1))
|
|
109
|
-
echo "$RALPH_STATE" | jq ".iteration = $NEW_ITER" > "$DIRECTORY/.omc/state/ralph-state.json" 2>/dev/null
|
|
110
|
-
|
|
111
|
-
# Check if ultrawork is linked (auto-activated with ralph)
|
|
112
|
-
LINKED_ULTRAWORK=$(echo "$RALPH_STATE" | jq -r '.linked_ultrawork // false' 2>/dev/null)
|
|
113
|
-
|
|
114
|
-
if [ "$LINKED_ULTRAWORK" = "true" ]; then
|
|
115
|
-
# Combined ralph+ultrawork message with parallel execution rules
|
|
116
|
-
cat << EOF
|
|
117
|
-
{"continue": false, "reason": "<ralph-ultrawork-continuation>\n\n[RALPH + ULTRAWORK - ITERATION $NEW_ITER/$MAX_ITER]\n\nYour previous attempt did not output the completion promise. The work is NOT done yet.\n\n## ULTRAWORK RULES (ACTIVE)\n- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially\n- **BACKGROUND FIRST**: Use Task(run_in_background=true) for long operations\n- **DELEGATE**: Route tasks to specialist agents immediately\n- **SMART ROUTING**: Use haiku for lookups, sonnet for standard work, opus for complex analysis\n- **TODO**: Track EVERY step. Mark complete IMMEDIATELY.\n\n## COMPLETION REQUIREMENTS\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 using PARALLEL execution\n4. Get Architect verification when ready\n5. When FULLY complete AND verified, output: <promise>$PROMISE</promise>\n6. Do NOT stop until the task is truly done\n\nOriginal task: $PROMPT\n\n</ralph-ultrawork-continuation>\n\n---\n"}
|
|
118
|
-
EOF
|
|
119
|
-
else
|
|
120
|
-
# Standard ralph-only message
|
|
121
|
-
cat << EOF
|
|
122
|
-
{"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"}
|
|
123
|
-
EOF
|
|
124
|
-
fi
|
|
125
|
-
exit 0
|
|
126
|
-
fi
|
|
127
|
-
fi
|
|
128
|
-
fi
|
|
129
|
-
|
|
130
|
-
# Priority 1.5: Verification Requirements (build/test/git/background)
|
|
131
|
-
VERIFICATION_FAILURES=()
|
|
132
|
-
|
|
133
|
-
# Check 1: Build verification
|
|
134
|
-
BUILD_ISSUES=""
|
|
135
|
-
if [ -f "$DIRECTORY/package.json" ]; then
|
|
136
|
-
if command -v jq &> /dev/null; then
|
|
137
|
-
BUILD_SCRIPT=$(jq -r '.scripts.build // empty' "$DIRECTORY/package.json" 2>/dev/null)
|
|
138
|
-
if [ -n "$BUILD_SCRIPT" ]; then
|
|
139
|
-
# Check if build directory exists or recent build artifacts
|
|
140
|
-
if [ ! -d "$DIRECTORY/dist" ] && [ ! -d "$DIRECTORY/build" ] && [ ! -d "$DIRECTORY/out" ]; then
|
|
141
|
-
BUILD_ISSUES="Build script exists but no build artifacts found (dist/build/out). Run 'npm run build' to verify."
|
|
142
|
-
fi
|
|
143
|
-
fi
|
|
144
|
-
fi
|
|
145
|
-
elif [ -f "$DIRECTORY/Makefile" ]; then
|
|
146
|
-
# Check for common make targets
|
|
147
|
-
if grep -q "^build:" "$DIRECTORY/Makefile" 2>/dev/null; then
|
|
148
|
-
BUILD_ISSUES="Makefile with build target detected. Run 'make build' to verify before stopping."
|
|
149
|
-
fi
|
|
150
|
-
elif [ -f "$DIRECTORY/Cargo.toml" ]; then
|
|
151
|
-
# Check for Rust build artifacts
|
|
152
|
-
if [ ! -d "$DIRECTORY/target/release" ] && [ ! -d "$DIRECTORY/target/debug" ]; then
|
|
153
|
-
BUILD_ISSUES="Rust project detected but no build artifacts found. Run 'cargo build' to verify."
|
|
154
|
-
fi
|
|
155
|
-
fi
|
|
156
|
-
|
|
157
|
-
if [ -n "$BUILD_ISSUES" ]; then
|
|
158
|
-
VERIFICATION_FAILURES+=("BUILD: $BUILD_ISSUES")
|
|
159
|
-
fi
|
|
160
|
-
|
|
161
|
-
# Check 2: Test failures in recent output
|
|
162
|
-
TEST_ISSUES=""
|
|
163
|
-
if [ -f "$DIRECTORY/package.json" ]; then
|
|
164
|
-
if command -v jq &> /dev/null; then
|
|
165
|
-
TEST_SCRIPT=$(jq -r '.scripts.test // empty' "$DIRECTORY/package.json" 2>/dev/null)
|
|
166
|
-
if [ -n "$TEST_SCRIPT" ]; then
|
|
167
|
-
# Check for test artifacts or recent test run indicators
|
|
168
|
-
TEST_ISSUES="Test script exists. Run 'npm test' to verify all tests pass before stopping."
|
|
169
|
-
fi
|
|
170
|
-
fi
|
|
171
|
-
elif [ -f "$DIRECTORY/pytest.ini" ] || [ -f "$DIRECTORY/setup.py" ] || [ -d "$DIRECTORY/tests" ]; then
|
|
172
|
-
TEST_ISSUES="Python test directory/config detected. Run tests to verify before stopping."
|
|
173
|
-
elif [ -f "$DIRECTORY/Cargo.toml" ]; then
|
|
174
|
-
TEST_ISSUES="Rust project detected. Run 'cargo test' to verify before stopping."
|
|
175
|
-
fi
|
|
176
|
-
|
|
177
|
-
# Check for recent test failure indicators in common log locations
|
|
178
|
-
for log_file in "$DIRECTORY/test-results.log" "$DIRECTORY/.test-output" "$HOME/.claude/last-test-run.log"; do
|
|
179
|
-
if [ -f "$log_file" ]; then
|
|
180
|
-
if grep -qi "FAIL\|ERROR\|failed" "$log_file" 2>/dev/null; then
|
|
181
|
-
TEST_ISSUES="Recent test failures detected in $log_file. Fix failures before stopping."
|
|
182
|
-
break
|
|
183
|
-
fi
|
|
184
|
-
fi
|
|
185
|
-
done
|
|
186
|
-
|
|
187
|
-
if [ -n "$TEST_ISSUES" ]; then
|
|
188
|
-
VERIFICATION_FAILURES+=("TEST: $TEST_ISSUES")
|
|
189
|
-
fi
|
|
190
|
-
|
|
191
|
-
# Check 3: Git status - uncommitted changes
|
|
192
|
-
GIT_ISSUES=""
|
|
193
|
-
if [ -d "$DIRECTORY/.git" ]; then
|
|
194
|
-
# Check for uncommitted changes
|
|
195
|
-
cd "$DIRECTORY" 2>/dev/null
|
|
196
|
-
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
|
197
|
-
CHANGED_FILES=$(git status --porcelain 2>/dev/null | wc -l)
|
|
198
|
-
GIT_ISSUES="$CHANGED_FILES uncommitted file(s). Consider committing changes or verify they should be discarded."
|
|
199
|
-
fi
|
|
200
|
-
# Check for unpushed commits
|
|
201
|
-
UNPUSHED=$(git log @{u}.. --oneline 2>/dev/null | wc -l)
|
|
202
|
-
if [ "$UNPUSHED" -gt 0 ]; then
|
|
203
|
-
if [ -n "$GIT_ISSUES" ]; then
|
|
204
|
-
GIT_ISSUES="$GIT_ISSUES Also, $UNPUSHED unpushed commit(s) exist."
|
|
205
|
-
else
|
|
206
|
-
GIT_ISSUES="$UNPUSHED unpushed commit(s). Consider pushing to remote or verify local-only is intended."
|
|
207
|
-
fi
|
|
208
|
-
fi
|
|
209
|
-
fi
|
|
210
|
-
|
|
211
|
-
if [ -n "$GIT_ISSUES" ]; then
|
|
212
|
-
VERIFICATION_FAILURES+=("GIT: $GIT_ISSUES")
|
|
213
|
-
fi
|
|
214
|
-
|
|
215
|
-
# Check 4: Background tasks still running
|
|
216
|
-
BACKGROUND_ISSUES=""
|
|
217
|
-
BACKGROUND_DIR="$HOME/.claude/background-tasks"
|
|
218
|
-
if [ -d "$BACKGROUND_DIR" ]; then
|
|
219
|
-
RUNNING_TASKS=0
|
|
220
|
-
for task_file in "$BACKGROUND_DIR"/*.json; do
|
|
221
|
-
if [ -f "$task_file" ]; then
|
|
222
|
-
if command -v jq &> /dev/null; then
|
|
223
|
-
STATUS=$(jq -r '.status // ""' "$task_file" 2>/dev/null)
|
|
224
|
-
if [ "$STATUS" = "running" ] || [ "$STATUS" = "pending" ]; then
|
|
225
|
-
RUNNING_TASKS=$((RUNNING_TASKS + 1))
|
|
226
|
-
fi
|
|
227
|
-
else
|
|
228
|
-
# Fallback: check for running/pending status
|
|
229
|
-
if grep -q '"status"[[:space:]]*:[[:space:]]*"running\|pending"' "$task_file" 2>/dev/null; then
|
|
230
|
-
RUNNING_TASKS=$((RUNNING_TASKS + 1))
|
|
231
|
-
fi
|
|
232
|
-
fi
|
|
233
|
-
fi
|
|
234
|
-
done
|
|
235
|
-
|
|
236
|
-
if [ "$RUNNING_TASKS" -gt 0 ]; then
|
|
237
|
-
BACKGROUND_ISSUES="$RUNNING_TASKS background task(s) still running. Wait for completion or verify results."
|
|
238
|
-
fi
|
|
239
|
-
fi
|
|
240
|
-
|
|
241
|
-
if [ -n "$BACKGROUND_ISSUES" ]; then
|
|
242
|
-
VERIFICATION_FAILURES+=("BACKGROUND: $BACKGROUND_ISSUES")
|
|
243
|
-
fi
|
|
244
|
-
|
|
245
|
-
# If any verification failures exist, block stopping
|
|
246
|
-
if [ ${#VERIFICATION_FAILURES[@]} -gt 0 ]; then
|
|
247
|
-
FAILURE_LIST=""
|
|
248
|
-
for failure in "${VERIFICATION_FAILURES[@]}"; do
|
|
249
|
-
FAILURE_LIST="$FAILURE_LIST\n- $failure"
|
|
250
|
-
done
|
|
251
|
-
|
|
252
|
-
cat << EOF
|
|
253
|
-
{"continue": false, "reason": "<verification-requirements>\n\n[VERIFICATION REQUIREMENTS NOT MET]\n\nBefore stopping, you must address the following verification requirements:\n$FAILURE_LIST\n\n## REQUIRED ACTIONS:\n\n1. **Build Verification**: If build scripts exist, run them and verify success\n2. **Test Verification**: Run all tests and ensure they pass\n3. **Git Status**: Review uncommitted/unpushed changes - commit or verify intentional\n4. **Background Tasks**: Wait for or check results of running background tasks\n\n**You cannot stop until these verifications are complete.**\n\nAddress each issue above, then you may conclude.\n\n</verification-requirements>\n\n---\n"}
|
|
254
|
-
EOF
|
|
255
|
-
exit 0
|
|
256
|
-
fi
|
|
257
|
-
|
|
258
|
-
# Priority 2: Ultrawork Mode with incomplete todos
|
|
259
|
-
if [ -n "$ULTRAWORK_STATE" ] && [ "$INCOMPLETE_COUNT" -gt 0 ]; then
|
|
260
|
-
# Check if active (with jq fallback)
|
|
261
|
-
IS_ACTIVE=""
|
|
262
|
-
if command -v jq &> /dev/null; then
|
|
263
|
-
IS_ACTIVE=$(echo "$ULTRAWORK_STATE" | jq -r '.active // false' 2>/dev/null)
|
|
264
|
-
else
|
|
265
|
-
# Fallback: grep for "active": true
|
|
266
|
-
if echo "$ULTRAWORK_STATE" | grep -q '"active"[[:space:]]*:[[:space:]]*true'; then
|
|
267
|
-
IS_ACTIVE="true"
|
|
268
|
-
fi
|
|
269
|
-
fi
|
|
270
|
-
|
|
271
|
-
if [ "$IS_ACTIVE" = "true" ]; then
|
|
272
|
-
# Get reinforcement count (with fallback)
|
|
273
|
-
REINFORCE_COUNT=0
|
|
274
|
-
if command -v jq &> /dev/null; then
|
|
275
|
-
REINFORCE_COUNT=$(echo "$ULTRAWORK_STATE" | jq -r '.reinforcement_count // 0' 2>/dev/null)
|
|
276
|
-
else
|
|
277
|
-
REINFORCE_COUNT=$(echo "$ULTRAWORK_STATE" | grep -oP '"reinforcement_count"[[:space:]]*:[[:space:]]*\K[0-9]+' 2>/dev/null) || REINFORCE_COUNT=0
|
|
278
|
-
fi
|
|
279
|
-
NEW_COUNT=$((REINFORCE_COUNT + 1))
|
|
280
|
-
|
|
281
|
-
# Get original prompt (with fallback)
|
|
282
|
-
ORIGINAL_PROMPT=""
|
|
283
|
-
if command -v jq &> /dev/null; then
|
|
284
|
-
ORIGINAL_PROMPT=$(echo "$ULTRAWORK_STATE" | jq -r '.original_prompt // ""' 2>/dev/null)
|
|
285
|
-
else
|
|
286
|
-
ORIGINAL_PROMPT=$(echo "$ULTRAWORK_STATE" | grep -oP '"original_prompt"[[:space:]]*:[[:space:]]*"\K[^"]+' 2>/dev/null) || ORIGINAL_PROMPT=""
|
|
287
|
-
fi
|
|
288
|
-
|
|
289
|
-
# Update state file (best effort)
|
|
290
|
-
if command -v jq &> /dev/null; then
|
|
291
|
-
echo "$ULTRAWORK_STATE" | jq ".reinforcement_count = $NEW_COUNT | .last_checked_at = \"$(date -Iseconds)\"" > "$DIRECTORY/.omc/state/ultrawork-state.json" 2>/dev/null
|
|
292
|
-
fi
|
|
293
|
-
|
|
294
|
-
cat << EOF
|
|
295
|
-
{"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"}
|
|
296
|
-
EOF
|
|
297
|
-
exit 0
|
|
298
|
-
fi
|
|
299
|
-
fi
|
|
300
|
-
|
|
301
|
-
# Priority 3: Todo Continuation (baseline)
|
|
302
|
-
if [ "$INCOMPLETE_COUNT" -gt 0 ]; then
|
|
303
|
-
cat << EOF
|
|
304
|
-
{"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"}
|
|
305
|
-
EOF
|
|
306
|
-
exit 0
|
|
307
|
-
fi
|
|
308
|
-
|
|
309
|
-
# No blocking needed
|
|
310
|
-
echo '{"continue": true}'
|
|
311
|
-
exit 0
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
"""
|
|
4
|
-
PostToolUse Hook: Verification Reminder System
|
|
5
|
-
Monitors tool execution and provides contextual guidance
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import sys
|
|
9
|
-
import json
|
|
10
|
-
import re
|
|
11
|
-
import os
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
from datetime import datetime
|
|
14
|
-
|
|
15
|
-
# State file for session tracking
|
|
16
|
-
STATE_FILE = Path.home() / ".claude" / ".session-stats.json"
|
|
17
|
-
STATE_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
18
|
-
|
|
19
|
-
def load_stats():
|
|
20
|
-
"""Load session statistics from state file."""
|
|
21
|
-
if STATE_FILE.exists():
|
|
22
|
-
try:
|
|
23
|
-
with open(STATE_FILE, 'r') as f:
|
|
24
|
-
return json.load(f)
|
|
25
|
-
except (json.JSONDecodeError, IOError):
|
|
26
|
-
pass
|
|
27
|
-
return {"sessions": {}}
|
|
28
|
-
|
|
29
|
-
def save_stats(stats):
|
|
30
|
-
"""Save session statistics to state file."""
|
|
31
|
-
try:
|
|
32
|
-
with open(STATE_FILE, 'w') as f:
|
|
33
|
-
json.dump(stats, f, indent=2)
|
|
34
|
-
except IOError:
|
|
35
|
-
pass # Fail silently
|
|
36
|
-
|
|
37
|
-
def update_stats(tool_name, session_id):
|
|
38
|
-
"""Update execution count for this session and tool."""
|
|
39
|
-
stats = load_stats()
|
|
40
|
-
|
|
41
|
-
if session_id not in stats["sessions"]:
|
|
42
|
-
stats["sessions"][session_id] = {
|
|
43
|
-
"tool_counts": {},
|
|
44
|
-
"last_tool": "",
|
|
45
|
-
"total_calls": 0,
|
|
46
|
-
"started_at": int(datetime.now().timestamp())
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
session = stats["sessions"][session_id]
|
|
50
|
-
session["tool_counts"][tool_name] = session["tool_counts"].get(tool_name, 0) + 1
|
|
51
|
-
session["last_tool"] = tool_name
|
|
52
|
-
session["total_calls"] = session.get("total_calls", 0) + 1
|
|
53
|
-
session["updated_at"] = int(datetime.now().timestamp())
|
|
54
|
-
|
|
55
|
-
save_stats(stats)
|
|
56
|
-
return session["tool_counts"][tool_name]
|
|
57
|
-
|
|
58
|
-
def detect_bash_failure(output):
|
|
59
|
-
"""Detect failures in Bash tool output."""
|
|
60
|
-
error_patterns = [
|
|
61
|
-
r"error:",
|
|
62
|
-
r"failed",
|
|
63
|
-
r"cannot",
|
|
64
|
-
r"permission denied",
|
|
65
|
-
r"command not found",
|
|
66
|
-
r"no such file",
|
|
67
|
-
r"exit code: [1-9]",
|
|
68
|
-
r"exit status [1-9]",
|
|
69
|
-
r"fatal:",
|
|
70
|
-
r"abort",
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
output_lower = output.lower()
|
|
74
|
-
for pattern in error_patterns:
|
|
75
|
-
if re.search(pattern, output_lower, re.IGNORECASE):
|
|
76
|
-
return True
|
|
77
|
-
return False
|
|
78
|
-
|
|
79
|
-
def detect_background_operation(output):
|
|
80
|
-
"""Detect if output suggests a background operation."""
|
|
81
|
-
bg_patterns = [
|
|
82
|
-
r"started",
|
|
83
|
-
r"running",
|
|
84
|
-
r"background",
|
|
85
|
-
r"async",
|
|
86
|
-
r"task_id",
|
|
87
|
-
r"spawned",
|
|
88
|
-
]
|
|
89
|
-
|
|
90
|
-
output_lower = output.lower()
|
|
91
|
-
for pattern in bg_patterns:
|
|
92
|
-
if re.search(pattern, output_lower, re.IGNORECASE):
|
|
93
|
-
return True
|
|
94
|
-
return False
|
|
95
|
-
|
|
96
|
-
def detect_write_failure(output):
|
|
97
|
-
"""Detect failures in Write/Edit operations."""
|
|
98
|
-
error_patterns = [
|
|
99
|
-
r"error",
|
|
100
|
-
r"failed",
|
|
101
|
-
r"permission denied",
|
|
102
|
-
r"read-only",
|
|
103
|
-
r"not found",
|
|
104
|
-
]
|
|
105
|
-
|
|
106
|
-
output_lower = output.lower()
|
|
107
|
-
for pattern in error_patterns:
|
|
108
|
-
if re.search(pattern, output_lower, re.IGNORECASE):
|
|
109
|
-
return True
|
|
110
|
-
return False
|
|
111
|
-
|
|
112
|
-
def generate_message(tool_name, tool_output, session_id, tool_count):
|
|
113
|
-
"""Generate contextual message based on tool usage."""
|
|
114
|
-
message = ""
|
|
115
|
-
|
|
116
|
-
if tool_name == "Bash":
|
|
117
|
-
if detect_bash_failure(tool_output):
|
|
118
|
-
message = "Command failed. Please investigate the error and fix before continuing."
|
|
119
|
-
elif detect_background_operation(tool_output):
|
|
120
|
-
message = "Background operation detected. Remember to verify results before proceeding."
|
|
121
|
-
|
|
122
|
-
elif tool_name == "Task":
|
|
123
|
-
if detect_write_failure(tool_output):
|
|
124
|
-
message = "Task delegation failed. Verify agent name and parameters."
|
|
125
|
-
elif detect_background_operation(tool_output):
|
|
126
|
-
message = "Background task launched. Use TaskOutput to check results when needed."
|
|
127
|
-
elif tool_count > 5:
|
|
128
|
-
message = f"Multiple tasks delegated ({tool_count} total). Track their completion status."
|
|
129
|
-
|
|
130
|
-
elif tool_name == "Edit":
|
|
131
|
-
if detect_write_failure(tool_output):
|
|
132
|
-
message = "Edit operation failed. Verify file exists and content matches exactly."
|
|
133
|
-
else:
|
|
134
|
-
message = "Code modified. Verify changes work as expected before marking complete."
|
|
135
|
-
|
|
136
|
-
elif tool_name == "Write":
|
|
137
|
-
if detect_write_failure(tool_output):
|
|
138
|
-
message = "Write operation failed. Check file permissions and directory existence."
|
|
139
|
-
else:
|
|
140
|
-
message = "File written. Test the changes to ensure they work correctly."
|
|
141
|
-
|
|
142
|
-
elif tool_name == "TodoWrite":
|
|
143
|
-
output_lower = tool_output.lower()
|
|
144
|
-
if re.search(r"created|added", output_lower):
|
|
145
|
-
message = "Todo list updated. Proceed with next task on the list."
|
|
146
|
-
elif re.search(r"completed|done", output_lower):
|
|
147
|
-
message = "Task marked complete. Continue with remaining todos."
|
|
148
|
-
elif re.search(r"in_progress", output_lower):
|
|
149
|
-
message = "Task marked in progress. Focus on completing this task."
|
|
150
|
-
|
|
151
|
-
elif tool_name == "Read":
|
|
152
|
-
if tool_count > 10:
|
|
153
|
-
message = f"Extensive reading ({tool_count} files). Consider using Grep for pattern searches."
|
|
154
|
-
|
|
155
|
-
elif tool_name == "Grep":
|
|
156
|
-
if re.search(r"^0$|no matches", tool_output):
|
|
157
|
-
message = "No matches found. Verify pattern syntax or try broader search."
|
|
158
|
-
|
|
159
|
-
elif tool_name == "Glob":
|
|
160
|
-
if not tool_output.strip() or re.search(r"no files", tool_output.lower()):
|
|
161
|
-
message = "No files matched pattern. Verify glob syntax and directory."
|
|
162
|
-
|
|
163
|
-
return message
|
|
164
|
-
|
|
165
|
-
def main():
|
|
166
|
-
"""Main hook execution."""
|
|
167
|
-
try:
|
|
168
|
-
# Read JSON input from stdin
|
|
169
|
-
input_data = json.load(sys.stdin)
|
|
170
|
-
|
|
171
|
-
tool_name = input_data.get("toolName", "")
|
|
172
|
-
tool_output = input_data.get("toolOutput", "")
|
|
173
|
-
session_id = input_data.get("sessionId", "unknown")
|
|
174
|
-
directory = input_data.get("directory", "")
|
|
175
|
-
|
|
176
|
-
# Update session statistics
|
|
177
|
-
tool_count = update_stats(tool_name, session_id)
|
|
178
|
-
|
|
179
|
-
# Generate contextual message
|
|
180
|
-
message = generate_message(tool_name, tool_output, session_id, tool_count)
|
|
181
|
-
|
|
182
|
-
# Build response JSON (always continue for post-tool hooks)
|
|
183
|
-
response = {"continue": True}
|
|
184
|
-
if message:
|
|
185
|
-
response["message"] = message
|
|
186
|
-
|
|
187
|
-
# Output response
|
|
188
|
-
print(json.dumps(response, indent=2))
|
|
189
|
-
|
|
190
|
-
except Exception as e:
|
|
191
|
-
# On error, always continue with no message
|
|
192
|
-
print(json.dumps({"continue": True}))
|
|
193
|
-
sys.exit(0)
|
|
194
|
-
|
|
195
|
-
if __name__ == "__main__":
|
|
196
|
-
main()
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# PreToolUse Hook: Sisyphus Reminder Enforcer
|
|
4
|
-
# Injects contextual reminders before every tool execution
|
|
5
|
-
|
|
6
|
-
set -euo pipefail
|
|
7
|
-
|
|
8
|
-
# Read JSON input from stdin
|
|
9
|
-
input=$(cat)
|
|
10
|
-
|
|
11
|
-
# Simple JSON extraction using grep/sed (avoids jq dependency)
|
|
12
|
-
extract_json_field() {
|
|
13
|
-
local field=$1
|
|
14
|
-
local default=${2:-""}
|
|
15
|
-
echo "$input" | grep -o "\"$field\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" | sed 's/.*"\([^"]*\)".*/\1/' || echo "$default"
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
toolName=$(extract_json_field "toolName" "unknown")
|
|
19
|
-
directory=$(extract_json_field "directory" "")
|
|
20
|
-
|
|
21
|
-
# Try to get todo count from todo list file (if exists)
|
|
22
|
-
todo_file="${directory}/.omc/todos.json"
|
|
23
|
-
todo_status=""
|
|
24
|
-
if [[ -f "$todo_file" ]] && command -v jq &> /dev/null; then
|
|
25
|
-
pending=$(jq -r '[.todos[] | select(.status == "pending")] | length' "$todo_file" 2>/dev/null || echo "0")
|
|
26
|
-
in_progress=$(jq -r '[.todos[] | select(.status == "in_progress")] | length' "$todo_file" 2>/dev/null || echo "0")
|
|
27
|
-
if [[ $((pending + in_progress)) -gt 0 ]]; then
|
|
28
|
-
todo_status="[${in_progress} active, ${pending} pending] "
|
|
29
|
-
fi
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
# Generate contextual reminder based on tool type
|
|
33
|
-
message=""
|
|
34
|
-
|
|
35
|
-
case "$toolName" in
|
|
36
|
-
TodoWrite)
|
|
37
|
-
message="${todo_status}Mark todos in_progress BEFORE starting, completed IMMEDIATELY after finishing."
|
|
38
|
-
;;
|
|
39
|
-
|
|
40
|
-
Bash)
|
|
41
|
-
message="${todo_status}Use parallel execution for independent tasks. Use run_in_background for long operations (npm install, builds, tests)."
|
|
42
|
-
;;
|
|
43
|
-
|
|
44
|
-
Task)
|
|
45
|
-
message="${todo_status}Launch multiple agents in parallel when tasks are independent. Use run_in_background for long operations."
|
|
46
|
-
;;
|
|
47
|
-
|
|
48
|
-
Edit|Write)
|
|
49
|
-
message="${todo_status}Verify changes work after editing. Test functionality before marking complete."
|
|
50
|
-
;;
|
|
51
|
-
|
|
52
|
-
Read)
|
|
53
|
-
message="${todo_status}Read multiple files in parallel when possible for faster analysis."
|
|
54
|
-
;;
|
|
55
|
-
|
|
56
|
-
Grep|Glob)
|
|
57
|
-
message="${todo_status}Combine searches in parallel when investigating multiple patterns."
|
|
58
|
-
;;
|
|
59
|
-
|
|
60
|
-
*)
|
|
61
|
-
message="${todo_status}The boulder never stops. Continue until all tasks complete."
|
|
62
|
-
;;
|
|
63
|
-
esac
|
|
64
|
-
|
|
65
|
-
# Return JSON response (always continue, just remind)
|
|
66
|
-
# Escape message for JSON (replace " with \", newlines with \n)
|
|
67
|
-
escaped_message=$(echo "$message" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
68
|
-
|
|
69
|
-
cat <<EOF
|
|
70
|
-
{
|
|
71
|
-
"continue": true,
|
|
72
|
-
"message": "$escaped_message"
|
|
73
|
-
}
|
|
74
|
-
EOF
|
|
75
|
-
|
|
76
|
-
exit 0
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Sisyphus Mode Aliases for Claude CLI
|
|
2
|
-
# Add these to your ~/.bashrc or ~/.zshrc
|
|
3
|
-
|
|
4
|
-
# Primary Sisyphus alias - enforces task completion discipline
|
|
5
|
-
alias claude-s='/home/bellman/.claude/claude-sisyphus.sh'
|
|
6
|
-
|
|
7
|
-
# Work mode alias - shorter alternative
|
|
8
|
-
alias claudew='/home/bellman/.claude/claude-sisyphus.sh'
|
|
9
|
-
|
|
10
|
-
# Usage examples:
|
|
11
|
-
# claude-s "Refactor the API layer"
|
|
12
|
-
# claudew "Fix all failing tests"
|
|
13
|
-
# claude-s --model opus "Debug this complex issue"
|
|
14
|
-
|
|
15
|
-
# Installation:
|
|
16
|
-
# 1. Add the aliases above to your shell config (~/.bashrc or ~/.zshrc)
|
|
17
|
-
# 2. Reload: source ~/.bashrc (or source ~/.zshrc)
|
|
18
|
-
# 3. Use: claude-s "your task here"
|