coder-config 0.40.16 → 0.41.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.
- package/README.md +42 -0
- package/config-loader.js +32 -0
- package/hooks/ralph-loop-preprompt.sh +96 -0
- package/hooks/ralph-loop-stop.sh +101 -0
- package/lib/cli.js +81 -0
- package/lib/constants.js +1 -1
- package/lib/loops.js +849 -0
- package/package.json +2 -5
- package/scripts/sync-version.js +0 -12
- package/ui/dist/assets/index-BX3EJoIY.css +32 -0
- package/ui/dist/assets/index-CGdqBV9k.js +3839 -0
- package/ui/dist/index.html +2 -2
- package/ui/routes/index.js +2 -0
- package/ui/routes/loops.js +427 -0
- package/ui/routes/projects.js +27 -0
- package/ui/server.cjs +56 -0
- package/scripts/tauri-prepare.js +0 -328
- package/ui/dist/assets/index-DZrd_FEC.js +0 -3204
- package/ui/dist/assets/index-DjLdm3Mr.css +0 -32
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ One tool to configure all your AI coding assistants:
|
|
|
16
16
|
| **Rules & Commands** | Manage project-specific guidelines |
|
|
17
17
|
| **Memory** | Persistent context across sessions |
|
|
18
18
|
| **Workstreams** | Group projects with shared context |
|
|
19
|
+
| **Ralph Loops** | Autonomous development until task completion |
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
21
22
|
|
|
@@ -157,6 +158,47 @@ coder-config workstream install-hook --codex
|
|
|
157
158
|
coder-config workstream install-hook --all
|
|
158
159
|
```
|
|
159
160
|
|
|
161
|
+
### Loop Commands (Ralph Loop)
|
|
162
|
+
|
|
163
|
+
Ralph Loops enable autonomous development - Claude Code runs continuously until a task is completed.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
coder-config loop # List all loops
|
|
167
|
+
coder-config loop create "Task description" # Create new loop
|
|
168
|
+
coder-config loop create "Task" --workstream <name> # Create loop in workstream context
|
|
169
|
+
coder-config loop start <id> # Start/resume a loop
|
|
170
|
+
coder-config loop pause <id> # Pause loop at next safe point
|
|
171
|
+
coder-config loop resume <id> # Resume paused loop
|
|
172
|
+
coder-config loop cancel <id> # Cancel loop
|
|
173
|
+
coder-config loop delete <id> # Delete loop and its data
|
|
174
|
+
coder-config loop approve <id> # Approve plan (when in plan phase)
|
|
175
|
+
coder-config loop complete <id> # Mark loop as complete
|
|
176
|
+
coder-config loop status [id] # Show status (active loop if no id)
|
|
177
|
+
coder-config loop active # Show current active loop
|
|
178
|
+
coder-config loop history # Show completed loops
|
|
179
|
+
coder-config loop config # Show loop configuration
|
|
180
|
+
coder-config loop config --max-iterations 50 # Set max iterations
|
|
181
|
+
coder-config loop config --max-cost 10.00 # Set max cost budget
|
|
182
|
+
coder-config loop config --auto-approve-plan # Skip manual plan approval
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Three-Phase Workflow**:
|
|
186
|
+
1. **Clarify** - Claude asks questions to understand requirements
|
|
187
|
+
2. **Plan** - Claude creates an implementation plan (requires approval)
|
|
188
|
+
3. **Execute** - Claude implements the plan until complete
|
|
189
|
+
|
|
190
|
+
**Running a loop**:
|
|
191
|
+
```bash
|
|
192
|
+
export CODER_LOOP_ID=<id>
|
|
193
|
+
claude --continue "Your task description"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Safety mechanisms**:
|
|
197
|
+
- Iteration limits (default: 50)
|
|
198
|
+
- Cost budget caps (default: $10)
|
|
199
|
+
- Phase gates (manual plan approval)
|
|
200
|
+
- Graceful pause on budget exceeded
|
|
201
|
+
|
|
160
202
|
### Registry Commands
|
|
161
203
|
|
|
162
204
|
```bash
|
package/config-loader.js
CHANGED
|
@@ -30,6 +30,7 @@ const { envList, envSet, envUnset } = require('./lib/env');
|
|
|
30
30
|
const { getProjectsRegistryPath, loadProjectsRegistry, saveProjectsRegistry, projectList, projectAdd, projectRemove } = require('./lib/projects');
|
|
31
31
|
const { getWorkstreamsPath, loadWorkstreams, saveWorkstreams, workstreamList, workstreamCreate, workstreamUpdate, workstreamDelete, workstreamUse, workstreamActive, workstreamAddProject, workstreamRemoveProject, workstreamInject, workstreamDetect, workstreamGet, getActiveWorkstream, countWorkstreamsForProject, workstreamInstallHook, workstreamInstallHookGemini, workstreamInstallHookCodex, workstreamDeactivate, workstreamCheckPath } = require('./lib/workstreams');
|
|
32
32
|
const { getActivityPath, getDefaultActivity, loadActivity, saveActivity, detectProjectRoot, activityLog, activitySummary, generateWorkstreamName, activitySuggestWorkstreams, activityClear } = require('./lib/activity');
|
|
33
|
+
const { getLoopsPath, loadLoops, saveLoops, loadLoopState, saveLoopState, loadHistory, saveHistory, loopList, loopCreate, loopGet, loopUpdate, loopDelete, loopStart, loopPause, loopResume, loopCancel, loopApprove, loopComplete, loopStatus, loopHistory, loopConfig, getActiveLoop, recordIteration, saveClarifications, savePlan, loadClarifications, loadPlan, loopInject, archiveLoop } = require('./lib/loops');
|
|
33
34
|
const { runCli } = require('./lib/cli');
|
|
34
35
|
|
|
35
36
|
class ClaudeConfigManager {
|
|
@@ -148,6 +149,37 @@ class ClaudeConfigManager {
|
|
|
148
149
|
workstreamDeactivate() { return workstreamDeactivate(); }
|
|
149
150
|
workstreamCheckPath(targetPath, silent) { return workstreamCheckPath(this.installDir, targetPath, silent); }
|
|
150
151
|
|
|
152
|
+
// Loops (Ralph Loop)
|
|
153
|
+
getLoopsPath() { return getLoopsPath(this.installDir); }
|
|
154
|
+
loadLoops() { return loadLoops(this.installDir); }
|
|
155
|
+
saveLoops(data) { return saveLoops(this.installDir, data); }
|
|
156
|
+
loadLoopState(loopId) { return loadLoopState(this.installDir, loopId); }
|
|
157
|
+
saveLoopState(loopId, state) { return saveLoopState(this.installDir, loopId, state); }
|
|
158
|
+
loadHistory() { return loadHistory(this.installDir); }
|
|
159
|
+
saveHistory(data) { return saveHistory(this.installDir, data); }
|
|
160
|
+
loopList() { return loopList(this.installDir); }
|
|
161
|
+
loopCreate(task, options) { return loopCreate(this.installDir, task, options); }
|
|
162
|
+
loopGet(idOrName) { return loopGet(this.installDir, idOrName); }
|
|
163
|
+
loopUpdate(idOrName, updates) { return loopUpdate(this.installDir, idOrName, updates); }
|
|
164
|
+
loopDelete(idOrName) { return loopDelete(this.installDir, idOrName); }
|
|
165
|
+
loopStart(idOrName) { return loopStart(this.installDir, idOrName); }
|
|
166
|
+
loopPause(idOrName) { return loopPause(this.installDir, idOrName); }
|
|
167
|
+
loopResume(idOrName) { return loopResume(this.installDir, idOrName); }
|
|
168
|
+
loopCancel(idOrName) { return loopCancel(this.installDir, idOrName); }
|
|
169
|
+
loopApprove(idOrName) { return loopApprove(this.installDir, idOrName); }
|
|
170
|
+
loopComplete(idOrName) { return loopComplete(this.installDir, idOrName); }
|
|
171
|
+
loopStatus(idOrName) { return loopStatus(this.installDir, idOrName); }
|
|
172
|
+
loopHistory() { return loopHistory(this.installDir); }
|
|
173
|
+
loopConfig(updates) { return loopConfig(this.installDir, updates); }
|
|
174
|
+
getActiveLoop() { return getActiveLoop(this.installDir); }
|
|
175
|
+
recordIteration(loopId, iteration) { return recordIteration(this.installDir, loopId, iteration); }
|
|
176
|
+
saveClarifications(loopId, content) { return saveClarifications(this.installDir, loopId, content); }
|
|
177
|
+
savePlan(loopId, content) { return savePlan(this.installDir, loopId, content); }
|
|
178
|
+
loadClarifications(loopId) { return loadClarifications(this.installDir, loopId); }
|
|
179
|
+
loadPlan(loopId) { return loadPlan(this.installDir, loopId); }
|
|
180
|
+
loopInject(silent) { return loopInject(this.installDir, silent); }
|
|
181
|
+
archiveLoop(loopId) { return archiveLoop(this.installDir, loopId); }
|
|
182
|
+
|
|
151
183
|
// Activity
|
|
152
184
|
getActivityPath() { return getActivityPath(this.installDir); }
|
|
153
185
|
loadActivity() { return loadActivity(this.installDir); }
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Ralph Loop context injection hook
|
|
3
|
+
# Called at the start of each Claude session to inject loop context
|
|
4
|
+
#
|
|
5
|
+
# This hook:
|
|
6
|
+
# 1. Checks if we're in an active loop (via CODER_LOOP_ID env var)
|
|
7
|
+
# 2. Reads the current loop state
|
|
8
|
+
# 3. Outputs loop context including task, phase, clarifications, and plan
|
|
9
|
+
|
|
10
|
+
LOOP_ID="$CODER_LOOP_ID"
|
|
11
|
+
if [[ -z "$LOOP_ID" ]]; then
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
STATE_FILE="$HOME/.coder-config/loops/$LOOP_ID/state.json"
|
|
16
|
+
PLAN_FILE="$HOME/.coder-config/loops/$LOOP_ID/plan.md"
|
|
17
|
+
CLARIFY_FILE="$HOME/.coder-config/loops/$LOOP_ID/clarifications.md"
|
|
18
|
+
|
|
19
|
+
if [[ ! -f "$STATE_FILE" ]]; then
|
|
20
|
+
echo "Warning: Loop state file not found: $STATE_FILE"
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Read loop state
|
|
25
|
+
NAME=$(jq -r '.name' "$STATE_FILE")
|
|
26
|
+
PHASE=$(jq -r '.phase' "$STATE_FILE")
|
|
27
|
+
STATUS=$(jq -r '.status' "$STATE_FILE")
|
|
28
|
+
CURRENT_ITER=$(jq -r '.iterations.current // 0' "$STATE_FILE")
|
|
29
|
+
MAX_ITER=$(jq -r '.iterations.max // 50' "$STATE_FILE")
|
|
30
|
+
TASK=$(jq -r '.task.original' "$STATE_FILE")
|
|
31
|
+
CLARIFIED_TASK=$(jq -r '.task.clarified // empty' "$STATE_FILE")
|
|
32
|
+
|
|
33
|
+
echo "<ralph-loop-context>"
|
|
34
|
+
echo "# Ralph Loop: $NAME"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "**Phase:** $PHASE"
|
|
37
|
+
echo "**Status:** $STATUS"
|
|
38
|
+
echo "**Iteration:** $CURRENT_ITER / $MAX_ITER"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "## Original Task"
|
|
41
|
+
echo "$TASK"
|
|
42
|
+
echo ""
|
|
43
|
+
|
|
44
|
+
if [[ -n "$CLARIFIED_TASK" && "$CLARIFIED_TASK" != "null" ]]; then
|
|
45
|
+
echo "## Clarified Task"
|
|
46
|
+
echo "$CLARIFIED_TASK"
|
|
47
|
+
echo ""
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
if [[ -f "$CLARIFY_FILE" ]]; then
|
|
51
|
+
echo "## Clarifications"
|
|
52
|
+
cat "$CLARIFY_FILE"
|
|
53
|
+
echo ""
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
if [[ -f "$PLAN_FILE" ]]; then
|
|
57
|
+
echo "## Implementation Plan"
|
|
58
|
+
cat "$PLAN_FILE"
|
|
59
|
+
echo ""
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
echo "## Loop Instructions"
|
|
63
|
+
echo ""
|
|
64
|
+
echo "You are operating within a Ralph Loop - an autonomous development workflow."
|
|
65
|
+
echo "Your current phase is: **$PHASE**"
|
|
66
|
+
echo ""
|
|
67
|
+
|
|
68
|
+
case "$PHASE" in
|
|
69
|
+
"clarify")
|
|
70
|
+
echo "### Clarify Phase"
|
|
71
|
+
echo "- Ask questions to fully understand the requirements"
|
|
72
|
+
echo "- Gather any missing information needed for implementation"
|
|
73
|
+
echo "- Document Q&A in clarifications.md"
|
|
74
|
+
echo "- When requirements are clear, advance to 'plan' phase"
|
|
75
|
+
;;
|
|
76
|
+
"plan")
|
|
77
|
+
echo "### Plan Phase"
|
|
78
|
+
echo "- Review the clarified requirements"
|
|
79
|
+
echo "- Create a detailed implementation plan"
|
|
80
|
+
echo "- Break down work into clear steps"
|
|
81
|
+
echo "- Save the plan to plan.md"
|
|
82
|
+
echo "- Wait for approval before advancing to 'execute' phase"
|
|
83
|
+
;;
|
|
84
|
+
"execute")
|
|
85
|
+
echo "### Execute Phase"
|
|
86
|
+
echo "- Follow the implementation plan step by step"
|
|
87
|
+
echo "- Implement the required changes"
|
|
88
|
+
echo "- Test your work"
|
|
89
|
+
echo "- When complete, set taskComplete=true in state.json"
|
|
90
|
+
;;
|
|
91
|
+
esac
|
|
92
|
+
|
|
93
|
+
echo ""
|
|
94
|
+
echo "## State File Location"
|
|
95
|
+
echo "$STATE_FILE"
|
|
96
|
+
echo "</ralph-loop-context>"
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Ralph Loop continuation hook
|
|
3
|
+
# Called after each Claude response to manage loop continuation
|
|
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
|
|
11
|
+
|
|
12
|
+
LOOP_ID="$CODER_LOOP_ID"
|
|
13
|
+
if [[ -z "$LOOP_ID" ]]; then
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
STATE_FILE="$HOME/.coder-config/loops/$LOOP_ID/state.json"
|
|
18
|
+
if [[ ! -f "$STATE_FILE" ]]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Check if loop is still active
|
|
23
|
+
STATUS=$(jq -r '.status' "$STATE_FILE")
|
|
24
|
+
if [[ "$STATUS" != "running" ]]; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
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
|
+
|
|
34
|
+
# Check iteration limit
|
|
35
|
+
if (( CURRENT_ITER >= MAX_ITER )); then
|
|
36
|
+
echo "Loop paused: max iterations reached ($MAX_ITER)"
|
|
37
|
+
jq '.status = "paused" | .pauseReason = "max_iterations" | .updatedAt = (now | todate)' "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
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"
|
|
53
|
+
|
|
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")
|
|
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
|
|
66
|
+
fi
|
|
67
|
+
|
|
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.
|
|
73
|
+
|
|
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.
|
|
88
|
+
|
|
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
|
|
95
|
+
|
|
96
|
+
echo ""
|
|
97
|
+
echo "---"
|
|
98
|
+
echo "[Ralph Loop iteration $NEW_ITER/$MAX_ITER - Phase: $PHASE]"
|
|
99
|
+
echo ""
|
|
100
|
+
echo "$PHASE_PROMPT"
|
|
101
|
+
echo "---"
|
package/lib/cli.js
CHANGED
|
@@ -149,6 +149,63 @@ function runCli(manager) {
|
|
|
149
149
|
}
|
|
150
150
|
break;
|
|
151
151
|
|
|
152
|
+
// Loops (Ralph Loop)
|
|
153
|
+
case 'loop':
|
|
154
|
+
case 'loops':
|
|
155
|
+
if (args[1] === 'create' || args[1] === 'new') {
|
|
156
|
+
const task = args.slice(2).join(' ');
|
|
157
|
+
const wsIdx = args.indexOf('--workstream');
|
|
158
|
+
const workstreamId = wsIdx !== -1 ? args[wsIdx + 1] : null;
|
|
159
|
+
manager.loopCreate(task, { workstreamId });
|
|
160
|
+
} else if (args[1] === 'start') {
|
|
161
|
+
manager.loopStart(args[2]);
|
|
162
|
+
} else if (args[1] === 'pause') {
|
|
163
|
+
manager.loopPause(args[2]);
|
|
164
|
+
} else if (args[1] === 'resume') {
|
|
165
|
+
manager.loopResume(args[2]);
|
|
166
|
+
} else if (args[1] === 'cancel') {
|
|
167
|
+
manager.loopCancel(args[2]);
|
|
168
|
+
} else if (args[1] === 'approve') {
|
|
169
|
+
manager.loopApprove(args[2]);
|
|
170
|
+
} else if (args[1] === 'complete') {
|
|
171
|
+
manager.loopComplete(args[2]);
|
|
172
|
+
} else if (args[1] === 'delete' || args[1] === 'rm') {
|
|
173
|
+
manager.loopDelete(args[2]);
|
|
174
|
+
} else if (args[1] === 'status') {
|
|
175
|
+
manager.loopStatus(args[2]);
|
|
176
|
+
} else if (args[1] === 'history') {
|
|
177
|
+
manager.loopHistory();
|
|
178
|
+
} else if (args[1] === 'config') {
|
|
179
|
+
const updates = {};
|
|
180
|
+
const maxIterIdx = args.indexOf('--max-iterations');
|
|
181
|
+
if (maxIterIdx !== -1) updates.maxIterations = args[maxIterIdx + 1];
|
|
182
|
+
const maxCostIdx = args.indexOf('--max-cost');
|
|
183
|
+
if (maxCostIdx !== -1) updates.maxCost = args[maxCostIdx + 1];
|
|
184
|
+
if (args.includes('--auto-approve-plan')) updates.autoApprovePlan = true;
|
|
185
|
+
if (args.includes('--no-auto-approve-plan')) updates.autoApprovePlan = false;
|
|
186
|
+
if (Object.keys(updates).length > 0) {
|
|
187
|
+
manager.loopConfig(updates);
|
|
188
|
+
} else {
|
|
189
|
+
manager.loopConfig();
|
|
190
|
+
}
|
|
191
|
+
} else if (args[1] === 'inject') {
|
|
192
|
+
const silent = args.includes('--silent') || args.includes('-s');
|
|
193
|
+
manager.loopInject(silent);
|
|
194
|
+
} else if (args[1] === 'active') {
|
|
195
|
+
const loop = manager.getActiveLoop();
|
|
196
|
+
if (loop) {
|
|
197
|
+
console.log(`Active: ${loop.name}`);
|
|
198
|
+
console.log(` Phase: ${loop.phase}`);
|
|
199
|
+
console.log(` Status: ${loop.status}`);
|
|
200
|
+
console.log(` Iteration: ${loop.iterations.current}/${loop.iterations.max}`);
|
|
201
|
+
} else {
|
|
202
|
+
console.log('No active loop');
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
manager.loopList();
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
|
|
152
209
|
// Maintenance
|
|
153
210
|
case 'update':
|
|
154
211
|
manager.update(args.slice(1)).catch(err => {
|
|
@@ -232,6 +289,30 @@ Workstream Commands:
|
|
|
232
289
|
Per-session activation (enables parallel work):
|
|
233
290
|
export CODER_WORKSTREAM=<name-or-id>
|
|
234
291
|
|
|
292
|
+
Loop Commands (Ralph Loop - autonomous development):
|
|
293
|
+
loop List all loops
|
|
294
|
+
loop create "Task" Create new loop with task description
|
|
295
|
+
loop create "Task" --workstream <name> Create loop in workstream context
|
|
296
|
+
loop start <id> Start/resume a loop
|
|
297
|
+
loop pause <id> Pause loop at next safe point
|
|
298
|
+
loop resume <id> Resume paused loop
|
|
299
|
+
loop cancel <id> Cancel loop
|
|
300
|
+
loop delete <id> Delete loop and its data
|
|
301
|
+
loop approve <id> Approve plan (when in plan phase)
|
|
302
|
+
loop complete <id> Mark loop as complete
|
|
303
|
+
loop status [id] Show status (active loop if no id)
|
|
304
|
+
loop active Show current active loop
|
|
305
|
+
loop history Show completed loops
|
|
306
|
+
loop config Show loop configuration
|
|
307
|
+
loop config --max-iterations 50 Set max iterations
|
|
308
|
+
loop config --max-cost 10.00 Set max cost budget
|
|
309
|
+
loop config --auto-approve-plan Skip manual plan approval
|
|
310
|
+
loop inject [--silent] Output loop context (for hooks)
|
|
311
|
+
|
|
312
|
+
Running a loop with Claude Code:
|
|
313
|
+
export CODER_LOOP_ID=<id>
|
|
314
|
+
claude --continue "Your task"
|
|
315
|
+
|
|
235
316
|
Registry Commands:
|
|
236
317
|
registry List MCPs in global registry
|
|
237
318
|
registry add <name> '<json>' Add MCP to global registry
|