coder-config 0.44.47 → 0.44.49

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.
@@ -1,21 +1,26 @@
1
1
  #!/bin/bash
2
- # Ralph Loop continuation hook
3
- # Called after each Claude response to manage loop continuation
2
+ # Ralph Loop continuation hook (coder-config)
3
+ # Called when Claude tries to stop - blocks exit and feeds prompt back
4
4
  #
5
- # This hook:
6
- # 1. Checks if we're in an active loop (via CODER_LOOP_ID env var)
7
- # 2. Verifies the loop is still running
8
- # 3. Checks budget limits (iterations and cost)
9
- # 4. Updates iteration count
10
- # 5. Outputs continuation prompt based on current phase
5
+ # Uses CODER_LOOP_ID env var to identify active loop
6
+ # State stored in ~/.coder-config/loops/<id>/state.json
11
7
 
12
- LOOP_ID="$CODER_LOOP_ID"
8
+ set -euo pipefail
9
+
10
+ LOOP_ID="${CODER_LOOP_ID:-}"
13
11
  if [[ -z "$LOOP_ID" ]]; then
14
12
  exit 0
15
13
  fi
16
14
 
17
- STATE_FILE="$HOME/.coder-config/loops/$LOOP_ID/state.json"
18
- if [[ ! -f "$STATE_FILE" ]]; then
15
+ # Check both new and legacy paths (manager uses legacy if it has projects.json)
16
+ NEW_STATE_FILE="$HOME/.coder-config/loops/$LOOP_ID/state.json"
17
+ LEGACY_STATE_FILE="$HOME/.claude-config/loops/$LOOP_ID/state.json"
18
+
19
+ if [[ -f "$NEW_STATE_FILE" ]]; then
20
+ STATE_FILE="$NEW_STATE_FILE"
21
+ elif [[ -f "$LEGACY_STATE_FILE" ]]; then
22
+ STATE_FILE="$LEGACY_STATE_FILE"
23
+ else
19
24
  exit 0
20
25
  fi
21
26
 
@@ -25,77 +30,59 @@ if [[ "$STATUS" != "running" ]]; then
25
30
  exit 0
26
31
  fi
27
32
 
28
- # Check budget limits
29
- CURRENT_ITER=$(jq -r '.iterations.current' "$STATE_FILE")
30
- MAX_ITER=$(jq -r '.iterations.max' "$STATE_FILE")
31
- CURRENT_COST=$(jq -r '.budget.currentCost // 0' "$STATE_FILE")
32
- MAX_COST=$(jq -r '.budget.maxCost // 10' "$STATE_FILE")
33
+ # Get loop config
34
+ CURRENT_ITER=$(jq -r '.iterations.current // 0' "$STATE_FILE")
35
+ MAX_ITER=$(jq -r '.iterations.max // 50' "$STATE_FILE")
36
+ COMPLETION_PROMISE=$(jq -r '.completionPromise // "DONE"' "$STATE_FILE")
37
+ TASK=$(jq -r '.task.original // ""' "$STATE_FILE")
33
38
 
34
39
  # Check iteration limit
35
- if (( CURRENT_ITER >= MAX_ITER )); then
36
- echo "Loop paused: max iterations reached ($MAX_ITER)"
40
+ if [[ $MAX_ITER -gt 0 ]] && [[ $CURRENT_ITER -ge $MAX_ITER ]]; then
37
41
  jq '.status = "paused" | .pauseReason = "max_iterations" | .updatedAt = (now | todate)' "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
38
42
  exit 0
39
43
  fi
40
44
 
41
- # Check cost limit (using bc for floating point comparison)
42
- if command -v bc &> /dev/null; then
43
- if (( $(echo "$CURRENT_COST >= $MAX_COST" | bc -l) )); then
44
- echo "Loop paused: budget exceeded (\$$MAX_COST)"
45
- jq '.status = "paused" | .pauseReason = "budget" | .updatedAt = (now | todate)' "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
46
- exit 0
47
- fi
48
- fi
49
-
50
- # Update iteration count
51
- NEW_ITER=$((CURRENT_ITER + 1))
52
- jq ".iterations.current = $NEW_ITER | .updatedAt = (now | todate)" "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
45
+ # Read hook input to check for completion
46
+ HOOK_INPUT=$(cat)
47
+ TRANSCRIPT_PATH=$(echo "$HOOK_INPUT" | jq -r '.transcript_path // ""')
53
48
 
54
- # Check if task is complete (Claude sets this flag)
55
- PHASE=$(jq -r '.phase' "$STATE_FILE")
56
- TASK_COMPLETE=$(jq -r '.taskComplete // false' "$STATE_FILE")
49
+ if [[ -n "$TRANSCRIPT_PATH" ]] && [[ -f "$TRANSCRIPT_PATH" ]]; then
50
+ # Get last assistant message
51
+ LAST_OUTPUT=$(grep '"role":"assistant"' "$TRANSCRIPT_PATH" | tail -1 | jq -r '
52
+ .message.content |
53
+ map(select(.type == "text")) |
54
+ map(.text) |
55
+ join("\n")
56
+ ' 2>/dev/null || echo "")
57
57
 
58
- if [[ "$TASK_COMPLETE" == "true" ]]; then
59
- jq '.status = "completed" | .completedAt = (now | todate) | .updatedAt = (now | todate)' "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
60
- echo ""
61
- echo "---"
62
- echo "[Ralph Loop COMPLETED]"
63
- echo "Task has been marked as complete."
64
- echo "---"
65
- exit 0
58
+ # Check for completion promise
59
+ if [[ -n "$COMPLETION_PROMISE" ]] && [[ "$COMPLETION_PROMISE" != "null" ]]; then
60
+ if echo "$LAST_OUTPUT" | grep -qF "$COMPLETION_PROMISE"; then
61
+ jq '.status = "completed" | .taskComplete = true | .completedAt = (now | todate) | .updatedAt = (now | todate)' "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
62
+ exit 0
63
+ fi
64
+ fi
66
65
  fi
67
66
 
68
- # Continue loop - output continuation prompt based on phase
69
- PHASE_PROMPT=""
70
- case "$PHASE" in
71
- "clarify")
72
- PHASE_PROMPT="Continue clarifying requirements. Ask any remaining questions needed to fully understand the task.
67
+ # Not complete - continue loop
68
+ NEXT_ITER=$((CURRENT_ITER + 1))
69
+ jq ".iterations.current = $NEXT_ITER | .updatedAt = (now | todate)" "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
73
70
 
74
- If requirements are now clear:
75
- 1. Save clarifications to ~/.coder-config/loops/$LOOP_ID/clarifications.md
76
- 2. Update state: jq '.phase = \"plan\"' to advance to planning phase"
77
- ;;
78
- "plan")
79
- PHASE_PROMPT="Continue developing the implementation plan based on clarified requirements.
80
-
81
- When the plan is complete:
82
- 1. Save the plan to ~/.coder-config/loops/$LOOP_ID/plan.md
83
- 2. Wait for user approval before advancing to execute phase
84
- 3. If auto-approve is enabled, update state: jq '.phase = \"execute\"'"
85
- ;;
86
- "execute")
87
- PHASE_PROMPT="Continue executing the implementation plan.
71
+ # Build system message
72
+ if [[ -n "$COMPLETION_PROMISE" ]] && [[ "$COMPLETION_PROMISE" != "null" ]]; then
73
+ SYSTEM_MSG="🔄 Ralph iteration $NEXT_ITER/$MAX_ITER | Output '$COMPLETION_PROMISE' when task is complete"
74
+ else
75
+ SYSTEM_MSG="🔄 Ralph iteration $NEXT_ITER/$MAX_ITER | No completion promise set"
76
+ fi
88
77
 
89
- When the task is complete:
90
- 1. Verify all requirements have been met
91
- 2. Run any relevant tests
92
- 3. Update state: jq '.taskComplete = true' to mark as complete"
93
- ;;
94
- esac
78
+ # Output JSON to block stop and feed prompt back
79
+ jq -n \
80
+ --arg prompt "$TASK" \
81
+ --arg msg "$SYSTEM_MSG" \
82
+ '{
83
+ "decision": "block",
84
+ "reason": $prompt,
85
+ "systemMessage": $msg
86
+ }'
95
87
 
96
- echo ""
97
- echo "---"
98
- echo "[Ralph Loop iteration $NEW_ITER/$MAX_ITER - Phase: $PHASE]"
99
- echo ""
100
- echo "$PHASE_PROMPT"
101
- echo "---"
88
+ exit 0
package/lib/constants.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Constants and tool path configurations
3
3
  */
4
4
 
5
- const VERSION = '0.44.47';
5
+ const VERSION = '0.44.49';
6
6
 
7
7
  // Tool-specific path configurations
8
8
  const TOOL_PATHS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-config",
3
- "version": "0.44.47",
3
+ "version": "0.44.49",
4
4
  "description": "Configuration manager for AI coding tools - Claude Code, Gemini CLI, Codex CLI, Antigravity. Manage MCPs, rules, permissions, memory, and workstreams.",
5
5
  "author": "regression.io",
6
6
  "main": "config-loader.js",