@ralph-orchestrator/ralph-cli 2.2.2 → 2.2.3

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 CHANGED
@@ -29,6 +29,7 @@ v1.0.0 was ralphed into existence with little oversight and guidance. v2.0.0 is
29
29
  - [Presets](#presets)
30
30
  - [Key Concepts](#key-concepts)
31
31
  - [Orchestration and Coordination Patterns](#orchestration-and-coordination-patterns)
32
+ - [Multi-Loop Concurrency](#multi-loop-concurrency)
32
33
  - [CLI Reference](#cli-reference)
33
34
  - [Architecture](#architecture)
34
35
  - [Building & Testing](#building--testing)
@@ -76,6 +77,7 @@ See [AGENTS.md](AGENTS.md) for the full philosophy.
76
77
  - **Interactive TUI** — Real-time terminal UI for monitoring Ralph's activity (enabled by default)
77
78
  - **Memories** — Persistent learning across sessions stored in `.agent/memories.md`
78
79
  - **Tasks** — Runtime work tracking stored in `.agent/tasks.jsonl`
80
+ - **Multi-Loop Concurrency** — Run parallel loops in git worktrees with automatic merge workflow
79
81
  - **Session Recording** — Record and replay sessions for debugging and testing (experimental)
80
82
 
81
83
  ## Installation
@@ -924,6 +926,259 @@ Ralph enforces quality gates through backpressure. When a builder publishes `bui
924
926
  tests: pass, lint: pass, typecheck: pass
925
927
  ```
926
928
 
929
+ ## Multi-Loop Concurrency
930
+
931
+ Ralph supports running multiple orchestration loops in parallel using git worktrees for filesystem isolation. This enables working on multiple tasks simultaneously without conflicts.
932
+
933
+ ### How It Works
934
+
935
+ When you start a Ralph loop:
936
+
937
+ 1. **First loop** acquires `.ralph/loop.lock` and runs in-place (the primary loop)
938
+ 2. **Additional loops** automatically spawn into `.worktrees/<loop-id>/`
939
+ 3. **Each loop** has isolated events, tasks, and scratchpad
940
+ 4. **Memories are shared** — symlinked back to the main repo's `.agent/memories.md`
941
+ 5. **On completion**, worktree loops automatically spawn a merge-ralph to integrate changes
942
+
943
+ ```
944
+ ┌─────────────────────────────────────────────────────────────────────┐
945
+ │ Terminal 1 │ Terminal 2 │
946
+ │ ralph run -p "Add auth" │ ralph run -p "Add logging" │
947
+ │ [acquires lock, runs in-place]│ [spawns to worktree] │
948
+ │ ↓ │ ↓ │
949
+ │ Primary loop │ .worktrees/ralph-20250124-a3f2/ │
950
+ │ ↓ │ ↓ │
951
+ │ LOOP_COMPLETE │ LOOP_COMPLETE → auto-merge │
952
+ └─────────────────────────────────────────────────────────────────────┘
953
+ ```
954
+
955
+ ### Usage
956
+
957
+ ```bash
958
+ # First loop acquires lock, runs in-place
959
+ ralph run -p "Add authentication"
960
+
961
+ # In another terminal — automatically spawns to worktree
962
+ ralph run -p "Add logging"
963
+
964
+ # Check running loops
965
+ ralph loops
966
+
967
+ # View logs from a specific loop
968
+ ralph loops logs <loop-id>
969
+ ralph loops logs <loop-id> --follow # Real-time streaming
970
+
971
+ # Force sequential execution (wait for lock)
972
+ ralph run --exclusive -p "Task that needs main workspace"
973
+
974
+ # Skip auto-merge (keep worktree for manual handling)
975
+ ralph run --no-auto-merge -p "Experimental feature"
976
+ ```
977
+
978
+ ### Loop States
979
+
980
+ | State | Description |
981
+ |-------|-------------|
982
+ | `running` | Loop is actively executing |
983
+ | `queued` | Completed, waiting for merge |
984
+ | `merging` | Merge operation in progress |
985
+ | `merged` | Successfully merged to main |
986
+ | `needs-review` | Merge failed, requires manual resolution |
987
+ | `crashed` | Process died unexpectedly |
988
+ | `orphan` | Worktree exists but not tracked |
989
+ | `discarded` | Explicitly abandoned by user |
990
+
991
+ ### File Structure
992
+
993
+ ```
994
+ project/
995
+ ├── .ralph/
996
+ │ ├── loop.lock # Primary loop indicator
997
+ │ ├── loops.json # Loop registry
998
+ │ ├── merge-queue.jsonl # Merge event log
999
+ │ └── events.jsonl # Primary loop events
1000
+ ├── .agent/
1001
+ │ └── memories.md # Shared across all loops
1002
+ └── .worktrees/
1003
+ └── ralph-20250124-a3f2/
1004
+ ├── .ralph/events.jsonl # Loop-isolated
1005
+ ├── .agent/
1006
+ │ ├── memories.md → ../../.agent/memories.md # Symlink
1007
+ │ └── scratchpad.md # Loop-isolated
1008
+ └── [project files]
1009
+ ```
1010
+
1011
+ ### Managing Loops
1012
+
1013
+ ```bash
1014
+ # List all loops with status
1015
+ ralph loops list
1016
+
1017
+ # View loop output
1018
+ ralph loops logs <id> # Full output
1019
+ ralph loops logs <id> --follow # Stream real-time
1020
+
1021
+ # View event history
1022
+ ralph loops history <id> # Formatted table
1023
+ ralph loops history <id> --json # Raw JSONL
1024
+
1025
+ # Show changes from merge-base
1026
+ ralph loops diff <id> # Full diff
1027
+ ralph loops diff <id> --stat # Summary only
1028
+
1029
+ # Open shell in worktree
1030
+ ralph loops attach <id>
1031
+
1032
+ # Re-run merge for failed loop
1033
+ ralph loops retry <id>
1034
+
1035
+ # Stop a running loop
1036
+ ralph loops stop <id> # SIGTERM
1037
+ ralph loops stop <id> --force # SIGKILL
1038
+
1039
+ # Abandon loop and cleanup
1040
+ ralph loops discard <id> # With confirmation
1041
+ ralph loops discard <id> -y # Skip confirmation
1042
+
1043
+ # Clean up stale loops (crashed processes)
1044
+ ralph loops prune
1045
+ ```
1046
+
1047
+ ### Auto-Merge Workflow
1048
+
1049
+ When a worktree loop completes, it queues itself for merge. The primary loop processes this queue when it finishes:
1050
+
1051
+ ```
1052
+ ┌──────────────────────────────────────────────────────────────────────┐
1053
+ │ Worktree Loop Primary Loop │
1054
+ │ ───────────── ───────────── │
1055
+ │ LOOP_COMPLETE │
1056
+ │ ↓ │
1057
+ │ Queue for merge ─────────────────────→ [continues working] │
1058
+ │ ↓ ↓ │
1059
+ │ Exit cleanly LOOP_COMPLETE │
1060
+ │ ↓ │
1061
+ │ Process merge queue │
1062
+ │ ↓ │
1063
+ │ Spawn merge-ralph │
1064
+ └──────────────────────────────────────────────────────────────────────┘
1065
+ ```
1066
+
1067
+ The merge-ralph process uses a **hat collection** with specialized roles:
1068
+
1069
+ | Hat | Trigger | Purpose |
1070
+ |-----|---------|---------|
1071
+ | `merger` | `merge.start` | Performs `git merge`, runs tests |
1072
+ | `resolver` | `conflict.detected` | Resolves merge conflicts by understanding intent |
1073
+ | `tester` | `conflict.resolved` | Verifies tests pass after conflict resolution |
1074
+ | `cleaner` | `merge.done` | Removes worktree and branch |
1075
+ | `failure_handler` | `*failed`, `unresolvable` | Marks loop for manual review |
1076
+
1077
+ The workflow handles conflicts intelligently:
1078
+ 1. **No conflicts**: Merge → Run tests → Clean up → Done
1079
+ 2. **With conflicts**: Detect → AI resolves → Run tests → Clean up → Done
1080
+ 3. **Unresolvable**: Abort → Mark for review → Keep worktree for manual fix
1081
+
1082
+ ### Conflict Resolution
1083
+
1084
+ When merge conflicts occur, the AI resolver:
1085
+
1086
+ 1. Examines conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`)
1087
+ 2. Understands the **intent** of both sides (not just the code)
1088
+ 3. Resolves by preserving both intents when possible
1089
+ 4. Prefers the loop's changes when directly contradictory (newer work)
1090
+
1091
+ **Conflicts marked `needs-review`:**
1092
+ - Major architectural changes on both sides
1093
+ - Complex refactoring that can't be automatically reconciled
1094
+ - Business logic contradictions requiring human judgment
1095
+
1096
+ To manually resolve:
1097
+ ```bash
1098
+ # Enter the worktree
1099
+ ralph loops attach <loop-id>
1100
+
1101
+ # Fix the issue, commit
1102
+ git add . && git commit -m "Manual conflict resolution"
1103
+
1104
+ # Retry the merge
1105
+ ralph loops retry <loop-id>
1106
+
1107
+ # Or discard if unneeded
1108
+ ralph loops discard <loop-id>
1109
+ ```
1110
+
1111
+ ### Best Practices
1112
+
1113
+ **When to use parallel loops:**
1114
+ - ✅ Independent features with minimal file overlap
1115
+ - ✅ Bug fixes while feature work continues
1116
+ - ✅ Documentation updates parallel to code changes
1117
+ - ✅ Test additions that don't conflict with active development
1118
+
1119
+ **When to use `--exclusive` (sequential):**
1120
+ - ⚠️ Large refactoring touching many files
1121
+ - ⚠️ Database migrations or schema changes
1122
+ - ⚠️ Tasks that modify shared configuration files
1123
+ - ⚠️ Work that depends on changes from another in-progress loop
1124
+
1125
+ **Tips for reducing conflicts:**
1126
+ - Keep loops focused on distinct areas of the codebase
1127
+ - Use separate files when adding new features
1128
+ - Avoid modifying the same functions in parallel loops
1129
+ - Let one loop complete before starting conflicting work
1130
+
1131
+ ### Troubleshooting
1132
+
1133
+ **Loop stuck in `queued` state:**
1134
+ ```bash
1135
+ # Check if primary loop is still running
1136
+ ralph loops
1137
+
1138
+ # If primary finished but merge didn't start, manually trigger
1139
+ ralph loops retry <loop-id>
1140
+ ```
1141
+
1142
+ **Merge keeps failing:**
1143
+ ```bash
1144
+ # View merge-ralph logs
1145
+ ralph loops logs <loop-id>
1146
+
1147
+ # Check what changes conflict
1148
+ ralph loops diff <loop-id>
1149
+
1150
+ # Manually resolve in worktree
1151
+ ralph loops attach <loop-id>
1152
+ ```
1153
+
1154
+ **Orphaned worktrees:**
1155
+ ```bash
1156
+ # List and clean up orphans
1157
+ ralph loops prune
1158
+
1159
+ # Force cleanup of specific worktree
1160
+ git worktree remove .worktrees/<loop-id> --force
1161
+ git branch -D ralph/<loop-id>
1162
+ ```
1163
+
1164
+ **Lock file issues:**
1165
+ ```bash
1166
+ # Check who holds the lock
1167
+ cat .ralph/loop.lock
1168
+
1169
+ # If process is dead, remove stale lock
1170
+ rm .ralph/loop.lock
1171
+ ```
1172
+
1173
+ ### Environment Variables
1174
+
1175
+ | Variable | Description |
1176
+ |----------|-------------|
1177
+ | `RALPH_MERGE_LOOP_ID` | Set by auto-merge to identify which loop to merge |
1178
+ | `RALPH_DIAGNOSTICS=1` | Enable detailed diagnostic logging |
1179
+ | `RALPH_VERBOSE=1` | Verbose output mode |
1180
+ | `RALPH_DEBUG_LOG=1` | Write debug logs to `.agent/ralph.log` |
1181
+
927
1182
  ## CLI Reference
928
1183
 
929
1184
  ### Commands
@@ -939,6 +1194,7 @@ tests: pass, lint: pass, typecheck: pass
939
1194
  | `ralph clean` | Clean up `.agent/` directory |
940
1195
  | `ralph emit` | Emit an event to the event log |
941
1196
  | `ralph tools` | Runtime tools for memories and tasks (agent-facing) |
1197
+ | `ralph loops` | Manage parallel loops (list, logs, stop, merge) |
942
1198
 
943
1199
  ### Global Options
944
1200
 
@@ -963,6 +1219,8 @@ tests: pass, lint: pass, typecheck: pass
963
1219
  | `--record-session <FILE>` | Record session to JSONL |
964
1220
  | `-q, --quiet` | Suppress output (for CI) |
965
1221
  | `--continue` | Resume from existing scratchpad |
1222
+ | `--exclusive` | Wait for primary loop slot instead of spawning worktree |
1223
+ | `--no-auto-merge` | Skip automatic merge after worktree loop completes |
966
1224
 
967
1225
  ### `ralph init` Options
968
1226
 
@@ -1007,6 +1265,22 @@ ralph tools task ready # Unblocked tasks only
1007
1265
  ralph tools task close <id> # Mark complete
1008
1266
  ```
1009
1267
 
1268
+ ### `ralph loops` Subcommands
1269
+
1270
+ Manage parallel loops running in git worktrees:
1271
+
1272
+ | Subcommand | Description |
1273
+ |------------|-------------|
1274
+ | `list` | Show all loops with status (default) |
1275
+ | `logs <ID>` | View loop output (`--follow` for real-time) |
1276
+ | `history <ID>` | Show event history (`--json` for raw JSONL) |
1277
+ | `retry <ID>` | Re-run merge for `needs-review` loop |
1278
+ | `discard <ID>` | Abandon loop and cleanup worktree (`-y` to skip confirm) |
1279
+ | `stop <ID>` | Terminate running loop (`--force` for SIGKILL) |
1280
+ | `prune` | Clean up stale loops (crashed processes) |
1281
+ | `attach <ID>` | Open shell in loop's worktree |
1282
+ | `diff <ID>` | Show changes from merge-base (`--stat` for summary) |
1283
+
1010
1284
  ## Architecture
1011
1285
 
1012
1286
  Ralph is organized as a Cargo workspace with seven crates:
@@ -23,7 +23,7 @@
23
23
  "hasInstallScript": true,
24
24
  "license": "MIT",
25
25
  "name": "@ralph-orchestrator/ralph-cli",
26
- "version": "2.2.2"
26
+ "version": "2.2.3"
27
27
  },
28
28
  "node_modules/@isaacs/balanced-match": {
29
29
  "engines": {
@@ -515,5 +515,5 @@
515
515
  }
516
516
  },
517
517
  "requires": true,
518
- "version": "2.2.2"
518
+ "version": "2.2.3"
519
519
  }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "artifactDownloadUrl": "https://github.com/mikeyobrien/ralph-orchestrator/releases/download/v2.2.2",
2
+ "artifactDownloadUrl": "https://github.com/mikeyobrien/ralph-orchestrator/releases/download/v2.2.3",
3
3
  "bin": {
4
4
  "ralph": "run-ralph.js"
5
5
  },
@@ -62,7 +62,7 @@
62
62
  "zipExt": ".tar.xz"
63
63
  }
64
64
  },
65
- "version": "2.2.2",
65
+ "version": "2.2.3",
66
66
  "volta": {
67
67
  "node": "18.14.1",
68
68
  "npm": "9.5.0"