bmalph 2.7.2 โ†’ 2.7.4

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 (46) hide show
  1. package/README.md +14 -4
  2. package/dist/commands/doctor-checks.js +17 -10
  3. package/dist/commands/doctor-checks.js.map +1 -1
  4. package/dist/run/ralph-process.js +101 -7
  5. package/dist/run/ralph-process.js.map +1 -1
  6. package/dist/transition/artifact-collection.js +74 -0
  7. package/dist/transition/artifact-collection.js.map +1 -0
  8. package/dist/transition/artifacts.js +12 -1
  9. package/dist/transition/artifacts.js.map +1 -1
  10. package/dist/transition/context.js +17 -25
  11. package/dist/transition/context.js.map +1 -1
  12. package/dist/transition/fix-plan.js +12 -7
  13. package/dist/transition/fix-plan.js.map +1 -1
  14. package/dist/transition/orchestration.js +213 -116
  15. package/dist/transition/orchestration.js.map +1 -1
  16. package/dist/transition/preflight.js +30 -17
  17. package/dist/transition/preflight.js.map +1 -1
  18. package/dist/transition/section-patterns.js +56 -4
  19. package/dist/transition/section-patterns.js.map +1 -1
  20. package/dist/transition/specs-index.js +5 -2
  21. package/dist/transition/specs-index.js.map +1 -1
  22. package/dist/transition/specs-sync.js +23 -0
  23. package/dist/transition/specs-sync.js.map +1 -0
  24. package/dist/transition/sprint-status.js +91 -0
  25. package/dist/transition/sprint-status.js.map +1 -0
  26. package/dist/transition/story-id.js +46 -0
  27. package/dist/transition/story-id.js.map +1 -0
  28. package/dist/transition/story-parsing.js +7 -7
  29. package/dist/transition/story-parsing.js.map +1 -1
  30. package/dist/transition/tech-stack.js +1 -7
  31. package/dist/transition/tech-stack.js.map +1 -1
  32. package/package.json +1 -1
  33. package/ralph/RALPH-REFERENCE.md +50 -46
  34. package/ralph/drivers/claude-code.sh +44 -2
  35. package/ralph/drivers/codex.sh +10 -1
  36. package/ralph/drivers/copilot.sh +5 -0
  37. package/ralph/drivers/cursor-agent-wrapper.sh +13 -0
  38. package/ralph/drivers/cursor.sh +178 -14
  39. package/ralph/lib/circuit_breaker.sh +5 -5
  40. package/ralph/lib/enable_core.sh +10 -10
  41. package/ralph/lib/response_analyzer.sh +357 -111
  42. package/ralph/ralph_import.sh +14 -10
  43. package/ralph/ralph_loop.sh +168 -119
  44. package/ralph/ralph_monitor.sh +4 -4
  45. package/ralph/templates/AGENT.md +7 -7
  46. package/ralph/templates/PROMPT.md +13 -13
@@ -272,11 +272,14 @@ Supported formats:
272
272
  - PDFs (.pdf)
273
273
  - Any text-based format
274
274
 
275
+ This legacy helper is kept for standalone Ralph compatibility.
276
+ If you are using bmalph, use `bmalph implement` instead.
277
+
275
278
  The command will:
276
279
  1. Create a new Ralph project
277
280
  2. Use Claude Code to intelligently convert your PRD into:
278
281
  - .ralph/PROMPT.md (Ralph instructions)
279
- - .ralph/fix_plan.md (prioritized tasks)
282
+ - .ralph/@fix_plan.md (prioritized tasks)
280
283
  - .ralph/specs/ (technical specifications)
281
284
 
282
285
  HELPEOF
@@ -320,7 +323,7 @@ convert_prd() {
320
323
  cat > "$CONVERSION_PROMPT_FILE" << 'PROMPTEOF'
321
324
  # PRD to Ralph Conversion Task
322
325
 
323
- You are tasked with converting a Product Requirements Document (PRD) or specification into Ralph for Claude Code format.
326
+ You are tasked with converting a Product Requirements Document (PRD) or specification into Ralph's autonomous implementation format.
324
327
 
325
328
  ## Input Analysis
326
329
  Analyze the provided specification file and extract:
@@ -350,7 +353,7 @@ You are Ralph, an autonomous AI development agent working on a [PROJECT NAME] pr
350
353
  - Search the codebase before assuming something isn't implemented
351
354
  - Use subagents for expensive operations (file searching, analysis)
352
355
  - Write comprehensive tests with clear documentation
353
- - Update fix_plan.md with your learnings
356
+ - Update @fix_plan.md with your learnings
354
357
  - Commit working changes with descriptive messages
355
358
 
356
359
  ## ๐Ÿงช Testing Guidelines (CRITICAL)
@@ -370,10 +373,10 @@ You are Ralph, an autonomous AI development agent working on a [PROJECT NAME] pr
370
373
  [Define what "done" looks like based on the PRD]
371
374
 
372
375
  ## Current Task
373
- Follow fix_plan.md and choose the most important item to implement next.
376
+ Follow @fix_plan.md and choose the most important item to implement next.
374
377
  ```
375
378
 
376
- ### 2. .ralph/fix_plan.md
379
+ ### 2. .ralph/@fix_plan.md
377
380
  Convert requirements into a prioritized task list:
378
381
  ```markdown
379
382
  # Ralph Fix Plan
@@ -416,7 +419,7 @@ Create detailed technical specifications:
416
419
  2. Create the three files above with content derived from the PRD
417
420
  3. Ensure all requirements are captured and properly prioritized
418
421
  4. Make the PROMPT.md actionable for autonomous development
419
- 5. Structure fix_plan.md with clear, implementable tasks
422
+ 5. Structure @fix_plan.md with clear, implementable tasks
420
423
 
421
424
  PROMPTEOF
422
425
 
@@ -527,7 +530,7 @@ PROMPTEOF
527
530
  # Use PARSED_FILES_CREATED from JSON if available, otherwise check filesystem
528
531
  local missing_files=()
529
532
  local created_files=()
530
- local expected_files=(".ralph/PROMPT.md" ".ralph/fix_plan.md" ".ralph/specs/requirements.md")
533
+ local expected_files=(".ralph/PROMPT.md" ".ralph/@fix_plan.md" ".ralph/specs/requirements.md")
531
534
 
532
535
  # If JSON provided files_created, use that to inform verification
533
536
  if [[ "$json_parsed" == "true" && -n "$PARSED_FILES_CREATED" && "$PARSED_FILES_CREATED" != "[]" ]]; then
@@ -632,10 +635,11 @@ main() {
632
635
  echo "Next steps:"
633
636
  echo " 1. Review and edit the generated files:"
634
637
  echo " - .ralph/PROMPT.md (Ralph instructions)"
635
- echo " - .ralph/fix_plan.md (task priorities)"
638
+ echo " - .ralph/@fix_plan.md (task priorities)"
636
639
  echo " - .ralph/specs/requirements.md (technical specs)"
637
640
  echo " 2. Start autonomous development:"
638
- echo " ralph --monitor"
641
+ echo " ralph --monitor # standalone Ralph"
642
+ echo " bmalph run # bmalph-managed projects"
639
643
  echo ""
640
644
  echo "Project created in: $(pwd)"
641
645
  }
@@ -649,4 +653,4 @@ case "${1:-}" in
649
653
  *)
650
654
  main "$@"
651
655
  ;;
652
- esac
656
+ esac
@@ -26,6 +26,7 @@ DOCS_DIR="$RALPH_DIR/docs/generated"
26
26
  STATUS_FILE="$RALPH_DIR/status.json"
27
27
  PROGRESS_FILE="$RALPH_DIR/progress.json"
28
28
  CLAUDE_CODE_CMD="claude"
29
+ DRIVER_DISPLAY_NAME="Claude Code"
29
30
  SLEEP_DURATION=3600 # 1 hour in seconds
30
31
  LIVE_OUTPUT=false # Show Claude Code output in real-time (streaming)
31
32
  LIVE_LOG_FILE="$RALPH_DIR/live.log" # Fixed file for live output monitoring
@@ -95,17 +96,36 @@ MAX_CONSECUTIVE_TEST_LOOPS=3
95
96
  MAX_CONSECUTIVE_DONE_SIGNALS=2
96
97
  TEST_PERCENTAGE_THRESHOLD=30 # If more than 30% of recent loops are test-only, flag it
97
98
 
98
- # .ralphrc configuration file
99
- RALPHRC_FILE=".ralphrc"
99
+ # Ralph configuration file
100
+ # bmalph installs .ralph/.ralphrc. Fall back to a project-root .ralphrc for
101
+ # older standalone Ralph layouts.
102
+ RALPHRC_FILE="${RALPHRC_FILE:-$RALPH_DIR/.ralphrc}"
100
103
  RALPHRC_LOADED=false
101
104
 
102
105
  # Platform driver (set from .ralphrc or environment)
103
106
  PLATFORM_DRIVER="${PLATFORM_DRIVER:-claude-code}"
107
+ RUNTIME_CONTEXT_LOADED=false
104
108
 
105
- # load_ralphrc - Load project-specific configuration from .ralphrc
109
+ # resolve_ralphrc_file - Resolve the Ralph config path
110
+ resolve_ralphrc_file() {
111
+ if [[ -f "$RALPHRC_FILE" ]]; then
112
+ echo "$RALPHRC_FILE"
113
+ return 0
114
+ fi
115
+
116
+ if [[ "$RALPHRC_FILE" != ".ralphrc" && -f ".ralphrc" ]]; then
117
+ echo ".ralphrc"
118
+ return 0
119
+ fi
120
+
121
+ echo "$RALPHRC_FILE"
122
+ }
123
+
124
+ # load_ralphrc - Load project-specific configuration from .ralph/.ralphrc
106
125
  #
107
- # This function sources .ralphrc if it exists, applying project-specific
108
- # settings. Environment variables take precedence over .ralphrc values.
126
+ # This function sources the bundled .ralph/.ralphrc file when present, falling
127
+ # back to a project-root .ralphrc for older standalone Ralph layouts.
128
+ # Environment variables take precedence over config values.
109
129
  #
110
130
  # Configuration values that can be overridden:
111
131
  # - MAX_CALLS_PER_HOUR
@@ -120,15 +140,18 @@ PLATFORM_DRIVER="${PLATFORM_DRIVER:-claude-code}"
120
140
  # - RALPH_VERBOSE
121
141
  #
122
142
  load_ralphrc() {
123
- if [[ ! -f "$RALPHRC_FILE" ]]; then
143
+ local config_file
144
+ config_file="$(resolve_ralphrc_file)"
145
+
146
+ if [[ ! -f "$config_file" ]]; then
124
147
  return 0
125
148
  fi
126
149
 
127
- # Source .ralphrc (this may override default values)
150
+ # Source config (this may override default values)
128
151
  # shellcheck source=/dev/null
129
- source "$RALPHRC_FILE"
152
+ source "$config_file"
130
153
 
131
- # Map .ralphrc variable names to internal names
154
+ # Map config variable names to internal names
132
155
  if [[ -n "${ALLOWED_TOOLS:-}" ]]; then
133
156
  CLAUDE_ALLOWED_TOOLS="$ALLOWED_TOOLS"
134
157
  fi
@@ -155,6 +178,7 @@ load_ralphrc() {
155
178
  [[ -n "$_env_CB_COOLDOWN_MINUTES" ]] && CB_COOLDOWN_MINUTES="$_env_CB_COOLDOWN_MINUTES"
156
179
  [[ -n "$_env_CB_AUTO_RESET" ]] && CB_AUTO_RESET="$_env_CB_AUTO_RESET"
157
180
 
181
+ RALPHRC_FILE="$config_file"
158
182
  RALPHRC_LOADED=true
159
183
  return 0
160
184
  }
@@ -175,8 +199,25 @@ load_platform_driver() {
175
199
 
176
200
  # Set CLI binary from driver
177
201
  CLAUDE_CODE_CMD="$(driver_cli_binary)"
202
+ DRIVER_DISPLAY_NAME="$(driver_display_name)"
178
203
 
179
- log_status "INFO" "Platform driver: $(driver_display_name) ($(driver_cli_binary))"
204
+ log_status "INFO" "Platform driver: $DRIVER_DISPLAY_NAME ($CLAUDE_CODE_CMD)"
205
+ }
206
+
207
+ initialize_runtime_context() {
208
+ if [[ "$RUNTIME_CONTEXT_LOADED" == "true" ]]; then
209
+ return 0
210
+ fi
211
+
212
+ if load_ralphrc; then
213
+ if [[ "$RALPHRC_LOADED" == "true" ]]; then
214
+ log_status "INFO" "Loaded configuration from $RALPHRC_FILE"
215
+ fi
216
+ fi
217
+
218
+ # Load platform driver after config so PLATFORM_DRIVER can be overridden.
219
+ load_platform_driver
220
+ RUNTIME_CONTEXT_LOADED=true
180
221
  }
181
222
 
182
223
  # Colors for terminal output
@@ -217,6 +258,8 @@ setup_tmux_session() {
217
258
  local ralph_home="${RALPH_HOME:-$HOME/.ralph}"
218
259
  local project_dir="$(pwd)"
219
260
 
261
+ initialize_runtime_context
262
+
220
263
  # Get the tmux base-index to handle custom configurations (e.g., base-index 1)
221
264
  local base_win
222
265
  base_win=$(get_tmux_base_index)
@@ -235,7 +278,7 @@ setup_tmux_session() {
235
278
  # Split right pane horizontally (top: Claude output, bottom: status)
236
279
  tmux split-window -v -t "$session_name:${base_win}.1" -c "$project_dir"
237
280
 
238
- # Right-top pane (pane 1): Live Claude Code output
281
+ # Right-top pane (pane 1): Live driver output
239
282
  tmux send-keys -t "$session_name:${base_win}.1" "tail -f '$project_dir/$LIVE_LOG_FILE'" Enter
240
283
 
241
284
  # Right-bottom pane (pane 2): Ralph status monitor
@@ -304,7 +347,7 @@ setup_tmux_session() {
304
347
 
305
348
  # Set pane titles (requires tmux 2.6+)
306
349
  tmux select-pane -t "$session_name:${base_win}.0" -T "Ralph Loop"
307
- tmux select-pane -t "$session_name:${base_win}.1" -T "Claude Output"
350
+ tmux select-pane -t "$session_name:${base_win}.1" -T "$DRIVER_DISPLAY_NAME Output"
308
351
  tmux select-pane -t "$session_name:${base_win}.2" -T "Status"
309
352
 
310
353
  # Set window title
@@ -312,7 +355,7 @@ setup_tmux_session() {
312
355
 
313
356
  log_status "SUCCESS" "Tmux session created with 3 panes:"
314
357
  log_status "INFO" " Left: Ralph loop"
315
- log_status "INFO" " Right-top: Claude Code live output"
358
+ log_status "INFO" " Right-top: $DRIVER_DISPLAY_NAME live output"
316
359
  log_status "INFO" " Right-bottom: Status monitor"
317
360
  log_status "INFO" ""
318
361
  log_status "INFO" "Use Ctrl+B then D to detach from session"
@@ -701,7 +744,7 @@ get_session_file_age_seconds() {
701
744
  echo "$age_seconds"
702
745
  }
703
746
 
704
- # Initialize or resume Claude session (with expiration check)
747
+ # Initialize or resume persisted driver session (with expiration check)
705
748
  #
706
749
  # Session Expiration Strategy:
707
750
  # - Default expiration: 24 hours (configurable via CLAUDE_SESSION_EXPIRY_HOURS)
@@ -743,16 +786,17 @@ init_claude_session() {
743
786
  fi
744
787
 
745
788
  # Session is valid, try to read it
746
- local session_id=$(cat "$CLAUDE_SESSION_FILE" 2>/dev/null)
789
+ local session_id
790
+ session_id=$(get_last_session_id)
747
791
  if [[ -n "$session_id" ]]; then
748
792
  local age_hours=$((age_seconds / 3600))
749
- log_status "INFO" "Resuming Claude session: ${session_id:0:20}... (${age_hours}h old)"
793
+ log_status "INFO" "Resuming session: ${session_id:0:20}... (${age_hours}h old)"
750
794
  echo "$session_id"
751
795
  return 0
752
796
  fi
753
797
  fi
754
798
 
755
- log_status "INFO" "Starting new Claude session"
799
+ log_status "INFO" "Starting new session"
756
800
  echo ""
757
801
  }
758
802
 
@@ -760,12 +804,13 @@ init_claude_session() {
760
804
  save_claude_session() {
761
805
  local output_file=$1
762
806
 
763
- # Try to extract session ID from JSON output
807
+ # Try to extract session ID from structured output
764
808
  if [[ -f "$output_file" ]]; then
765
- local session_id=$(jq -r '.metadata.session_id // .session_id // empty' "$output_file" 2>/dev/null)
809
+ local session_id
810
+ session_id=$(extract_session_id_from_output "$output_file" 2>/dev/null || echo "")
766
811
  if [[ -n "$session_id" && "$session_id" != "null" ]]; then
767
812
  echo "$session_id" > "$CLAUDE_SESSION_FILE"
768
- log_status "INFO" "Saved Claude session: ${session_id:0:20}..."
813
+ log_status "INFO" "Saved session: ${session_id:0:20}..."
769
814
  fi
770
815
  fi
771
816
  }
@@ -972,6 +1017,7 @@ update_session_last_used() {
972
1017
 
973
1018
  # Global array for Claude command arguments (avoids shell injection)
974
1019
  declare -a CLAUDE_CMD_ARGS=()
1020
+ declare -a LIVE_CMD_ARGS=()
975
1021
 
976
1022
  # Build CLI command with platform driver (shell-injection safe)
977
1023
  # Delegates to the active platform driver's driver_build_command()
@@ -980,6 +1026,45 @@ build_claude_command() {
980
1026
  driver_build_command "$@"
981
1027
  }
982
1028
 
1029
+ supports_driver_sessions() {
1030
+ if declare -F driver_supports_sessions >/dev/null; then
1031
+ driver_supports_sessions
1032
+ return $?
1033
+ fi
1034
+
1035
+ return 0
1036
+ }
1037
+
1038
+ supports_live_output() {
1039
+ if declare -F driver_supports_live_output >/dev/null; then
1040
+ driver_supports_live_output
1041
+ return $?
1042
+ fi
1043
+
1044
+ return 0
1045
+ }
1046
+
1047
+ prepare_live_command_args() {
1048
+ LIVE_CMD_ARGS=("${CLAUDE_CMD_ARGS[@]}")
1049
+
1050
+ if declare -F driver_prepare_live_command >/dev/null; then
1051
+ driver_prepare_live_command
1052
+ return $?
1053
+ fi
1054
+
1055
+ return 0
1056
+ }
1057
+
1058
+ get_live_stream_filter() {
1059
+ if declare -F driver_stream_filter >/dev/null; then
1060
+ driver_stream_filter
1061
+ return 0
1062
+ fi
1063
+
1064
+ echo "empty"
1065
+ return 1
1066
+ }
1067
+
983
1068
  # Main execution function
984
1069
  execute_claude_code() {
985
1070
  local timestamp=$(date '+%Y-%m-%d_%H-%M-%S')
@@ -996,9 +1081,9 @@ execute_claude_code() {
996
1081
  fi
997
1082
  echo "$loop_start_sha" > "$RALPH_DIR/.loop_start_sha"
998
1083
 
999
- log_status "LOOP" "Executing Claude Code (Call $calls_made/$MAX_CALLS_PER_HOUR)"
1084
+ log_status "LOOP" "Executing $DRIVER_DISPLAY_NAME (Call $calls_made/$MAX_CALLS_PER_HOUR)"
1000
1085
  local timeout_seconds=$((CLAUDE_TIMEOUT_MINUTES * 60))
1001
- log_status "INFO" "โณ Starting Claude Code execution... (timeout: ${CLAUDE_TIMEOUT_MINUTES}m)"
1086
+ log_status "INFO" "โณ Starting $DRIVER_DISPLAY_NAME execution... (timeout: ${CLAUDE_TIMEOUT_MINUTES}m)"
1002
1087
 
1003
1088
  # Build loop context for session continuity
1004
1089
  local loop_context=""
@@ -1011,7 +1096,7 @@ execute_claude_code() {
1011
1096
 
1012
1097
  # Initialize or resume session
1013
1098
  local session_id=""
1014
- if [[ "$CLAUDE_USE_CONTINUE" == "true" ]]; then
1099
+ if [[ "$CLAUDE_USE_CONTINUE" == "true" ]] && supports_driver_sessions; then
1015
1100
  session_id=$(init_claude_session)
1016
1101
  fi
1017
1102
 
@@ -1051,11 +1136,16 @@ execute_claude_code() {
1051
1136
  # - --continue (session continuity)
1052
1137
  # - -p (prompt content)
1053
1138
 
1139
+ if ! supports_live_output; then
1140
+ log_status "WARN" "$DRIVER_DISPLAY_NAME does not support structured live streaming. Falling back to background mode."
1141
+ LIVE_OUTPUT=false
1142
+ fi
1143
+
1054
1144
  # Check dependencies for live mode
1055
- if ! command -v jq &> /dev/null; then
1145
+ if [[ "$LIVE_OUTPUT" == "true" ]] && ! command -v jq &> /dev/null; then
1056
1146
  log_status "ERROR" "Live mode requires 'jq' but it's not installed. Falling back to background mode."
1057
1147
  LIVE_OUTPUT=false
1058
- elif ! command -v stdbuf &> /dev/null; then
1148
+ elif [[ "$LIVE_OUTPUT" == "true" ]] && ! command -v stdbuf &> /dev/null; then
1059
1149
  log_status "ERROR" "Live mode requires 'stdbuf' (from coreutils) but it's not installed. Falling back to background mode."
1060
1150
  LIVE_OUTPUT=false
1061
1151
  fi
@@ -1070,45 +1160,18 @@ execute_claude_code() {
1070
1160
  fi
1071
1161
 
1072
1162
  if [[ "$LIVE_OUTPUT" == "true" ]]; then
1073
- log_status "INFO" "๐Ÿ“บ Live output mode enabled - showing Claude Code streaming..."
1074
- echo -e "${PURPLE}โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” Claude Code Output โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”${NC}"
1075
-
1076
- # Modify CLAUDE_CMD_ARGS: replace --output-format value with stream-json
1077
- # and add streaming-specific flags
1078
- local -a LIVE_CMD_ARGS=()
1079
- local skip_next=false
1080
- for arg in "${CLAUDE_CMD_ARGS[@]}"; do
1081
- if [[ "$skip_next" == "true" ]]; then
1082
- # Replace "json" with "stream-json" for output format
1083
- LIVE_CMD_ARGS+=("stream-json")
1084
- skip_next=false
1085
- elif [[ "$arg" == "--output-format" ]]; then
1086
- LIVE_CMD_ARGS+=("$arg")
1087
- skip_next=true
1088
- else
1089
- LIVE_CMD_ARGS+=("$arg")
1090
- fi
1091
- done
1163
+ log_status "INFO" "๐Ÿ“บ Live output mode enabled - showing $DRIVER_DISPLAY_NAME streaming..."
1164
+ echo -e "${PURPLE}โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” ${DRIVER_DISPLAY_NAME} Output โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”${NC}"
1092
1165
 
1093
- # Add streaming-specific flags (--verbose and --include-partial-messages)
1094
- # These are required for stream-json to work properly
1095
- LIVE_CMD_ARGS+=("--verbose" "--include-partial-messages")
1096
-
1097
- # jq filter: show text + tool names + newlines for readability
1098
- local jq_filter='
1099
- if .type == "stream_event" then
1100
- if .event.type == "content_block_delta" and .event.delta.type == "text_delta" then
1101
- .event.delta.text
1102
- elif .event.type == "content_block_start" and .event.content_block.type == "tool_use" then
1103
- "\n\nโšก [" + .event.content_block.name + "]\n"
1104
- elif .event.type == "content_block_stop" then
1105
- "\n"
1106
- else
1107
- empty
1108
- end
1109
- else
1110
- empty
1111
- end'
1166
+ if ! prepare_live_command_args; then
1167
+ log_status "ERROR" "Failed to prepare live streaming command. Falling back to background mode."
1168
+ LIVE_OUTPUT=false
1169
+ fi
1170
+ fi
1171
+
1172
+ if [[ "$LIVE_OUTPUT" == "true" ]]; then
1173
+ local jq_filter
1174
+ jq_filter=$(get_live_stream_filter)
1112
1175
 
1113
1176
  # Execute with streaming, preserving all flags from build_claude_command()
1114
1177
  # Use stdbuf to disable buffering for real-time output
@@ -1140,34 +1203,26 @@ execute_claude_code() {
1140
1203
  echo ""
1141
1204
  echo -e "${PURPLE}โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” End of Output โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”${NC}"
1142
1205
 
1143
- # Extract session ID from stream-json output for session continuity
1144
- # Stream-json format has session_id in the final "result" type message
1145
- # Keep full stream output in _stream.log, extract session data separately
1206
+ # Preserve full stream output for downstream analysis and session extraction.
1207
+ # Claude-style stream_json can be collapsed to the final result record,
1208
+ # while Codex JSONL should remain as event output for the shared parser.
1146
1209
  if [[ "$CLAUDE_USE_CONTINUE" == "true" && -f "$output_file" ]]; then
1147
- # Preserve full stream output for analysis (don't overwrite output_file)
1148
1210
  local stream_output_file="${output_file%.log}_stream.log"
1149
1211
  cp "$output_file" "$stream_output_file"
1150
1212
 
1151
- # Extract the result message and convert to standard JSON format
1152
- # Use flexible regex to match various JSON formatting styles
1153
- # Matches: "type":"result", "type": "result", "type" : "result"
1213
+ # Collapse Claude-style stream_json to the final result object when present.
1154
1214
  local result_line=$(grep -E '"type"[[:space:]]*:[[:space:]]*"result"' "$output_file" 2>/dev/null | tail -1)
1155
1215
 
1156
1216
  if [[ -n "$result_line" ]]; then
1157
- # Validate that extracted line is valid JSON before using it
1158
1217
  if echo "$result_line" | jq -e . >/dev/null 2>&1; then
1159
- # Write validated result as the output_file for downstream processing
1160
- # (save_claude_session and analyze_response expect JSON format)
1161
1218
  echo "$result_line" > "$output_file"
1162
- log_status "INFO" "Extracted and validated session data from stream output"
1219
+ log_status "INFO" "Collapsed streamed response to the final result record"
1163
1220
  else
1164
- log_status "WARN" "Extracted result line is not valid JSON, keeping stream output"
1165
- # Restore original stream output
1166
1221
  cp "$stream_output_file" "$output_file"
1222
+ log_status "WARN" "Final result record was invalid JSON, keeping full stream output"
1167
1223
  fi
1168
1224
  else
1169
- log_status "WARN" "Could not find result message in stream output"
1170
- # Keep stream output as-is for debugging
1225
+ log_status "INFO" "Keeping full stream output for shared response analysis"
1171
1226
  fi
1172
1227
  fi
1173
1228
  else
@@ -1182,7 +1237,7 @@ execute_claude_code() {
1182
1237
  then
1183
1238
  : # Continue to wait loop
1184
1239
  else
1185
- log_status "ERROR" "โŒ Failed to start Claude Code process (modern mode)"
1240
+ log_status "ERROR" "โŒ Failed to start $DRIVER_DISPLAY_NAME process (modern mode)"
1186
1241
  # Fall back to legacy mode
1187
1242
  log_status "INFO" "Falling back to legacy mode..."
1188
1243
  use_modern_cli=false
@@ -1197,7 +1252,7 @@ execute_claude_code() {
1197
1252
  then
1198
1253
  : # Continue to wait loop
1199
1254
  else
1200
- log_status "ERROR" "โŒ Failed to start Claude Code process"
1255
+ log_status "ERROR" "โŒ Failed to start $DRIVER_DISPLAY_NAME process"
1201
1256
  return 1
1202
1257
  fi
1203
1258
  fi
@@ -1238,9 +1293,9 @@ EOF
1238
1293
  # Only log if verbose mode is enabled
1239
1294
  if [[ "$VERBOSE_PROGRESS" == "true" ]]; then
1240
1295
  if [[ -n "$last_line" ]]; then
1241
- log_status "INFO" "$progress_indicator Claude Code: $last_line... (${progress_counter}0s)"
1296
+ log_status "INFO" "$progress_indicator $DRIVER_DISPLAY_NAME: $last_line... (${progress_counter}0s)"
1242
1297
  else
1243
- log_status "INFO" "$progress_indicator Claude Code working... (${progress_counter}0s elapsed)"
1298
+ log_status "INFO" "$progress_indicator $DRIVER_DISPLAY_NAME working... (${progress_counter}0s elapsed)"
1244
1299
  fi
1245
1300
  fi
1246
1301
 
@@ -1259,15 +1314,15 @@ EOF
1259
1314
  # Clear progress file
1260
1315
  echo '{"status": "completed", "timestamp": "'$(date '+%Y-%m-%d %H:%M:%S')'"}' > "$PROGRESS_FILE"
1261
1316
 
1262
- log_status "SUCCESS" "โœ… Claude Code execution completed successfully"
1317
+ log_status "SUCCESS" "โœ… $DRIVER_DISPLAY_NAME execution completed successfully"
1263
1318
 
1264
1319
  # Save session ID from JSON output (Phase 1.1)
1265
- if [[ "$CLAUDE_USE_CONTINUE" == "true" ]]; then
1320
+ if [[ "$CLAUDE_USE_CONTINUE" == "true" ]] && supports_driver_sessions; then
1266
1321
  save_claude_session "$output_file"
1267
1322
  fi
1268
1323
 
1269
1324
  # Analyze the response
1270
- log_status "INFO" "๐Ÿ” Analyzing Claude Code response..."
1325
+ log_status "INFO" "๐Ÿ” Analyzing $DRIVER_DISPLAY_NAME response..."
1271
1326
  analyze_response "$output_file" "$loop_count"
1272
1327
  local analysis_exit_code=$?
1273
1328
 
@@ -1356,7 +1411,7 @@ EOF
1356
1411
  log_status "ERROR" "๐Ÿšซ Claude API 5-hour usage limit reached"
1357
1412
  return 2 # Special return code for API limit
1358
1413
  else
1359
- log_status "ERROR" "โŒ Claude Code execution failed, check: $output_file"
1414
+ log_status "ERROR" "โŒ $DRIVER_DISPLAY_NAME execution failed, check: $output_file"
1360
1415
  return 1
1361
1416
  fi
1362
1417
  fi
@@ -1378,22 +1433,14 @@ loop_count=0
1378
1433
 
1379
1434
  # Main loop
1380
1435
  main() {
1381
- # Load project-specific configuration from .ralphrc
1382
- if load_ralphrc; then
1383
- if [[ "$RALPHRC_LOADED" == "true" ]]; then
1384
- log_status "INFO" "Loaded configuration from .ralphrc"
1385
- fi
1386
- fi
1387
-
1388
- # Load platform driver (after .ralphrc so PLATFORM_DRIVER can be overridden)
1389
- load_platform_driver
1436
+ initialize_runtime_context
1390
1437
 
1391
1438
  # Validate --allowed-tools now that platform-specific VALID_TOOL_PATTERNS are loaded
1392
1439
  if [[ "${_CLI_ALLOWED_TOOLS:-}" == "true" ]] && ! validate_allowed_tools "$CLAUDE_ALLOWED_TOOLS"; then
1393
1440
  exit 1
1394
1441
  fi
1395
1442
 
1396
- log_status "SUCCESS" "๐Ÿš€ Ralph loop starting with Claude Code"
1443
+ log_status "SUCCESS" "๐Ÿš€ Ralph loop starting with $DRIVER_DISPLAY_NAME"
1397
1444
  log_status "INFO" "Max calls per hour: $MAX_CALLS_PER_HOUR"
1398
1445
  log_status "INFO" "Logs: $LOG_DIR/ | Docs: $DOCS_DIR/ | Status: $STATUS_FILE"
1399
1446
 
@@ -1417,19 +1464,19 @@ main() {
1417
1464
  echo ""
1418
1465
 
1419
1466
  # Check if this looks like a partial Ralph project
1420
- if [[ -f "$RALPH_DIR/@fix_plan.md" ]] || [[ -d "$RALPH_DIR/specs" ]] || [[ -f "$RALPH_DIR/AGENT.md" ]]; then
1421
- echo "This appears to be a Ralph project but is missing .ralph/PROMPT.md."
1467
+ if [[ -f "$RALPH_DIR/@fix_plan.md" ]] || [[ -d "$RALPH_DIR/specs" ]] || [[ -f "$RALPH_DIR/@AGENT.md" ]]; then
1468
+ echo "This appears to be a bmalph/Ralph project but is missing .ralph/PROMPT.md."
1422
1469
  echo "You may need to create or restore the PROMPT.md file."
1423
1470
  else
1424
- echo "This directory is not a Ralph project."
1471
+ echo "This directory is not a bmalph/Ralph project."
1425
1472
  fi
1426
1473
 
1427
1474
  echo ""
1428
1475
  echo "To fix this:"
1429
- echo " 1. Enable Ralph in existing project: ralph-enable"
1430
- echo " 2. Create a new project: ralph-setup my-project"
1431
- echo " 3. Import existing requirements: ralph-import requirements.md"
1432
- echo " 4. Navigate to an existing Ralph project directory"
1476
+ echo " 1. Initialize bmalph in this project: bmalph init"
1477
+ echo " 2. Restore bundled Ralph files in an existing project: bmalph upgrade"
1478
+ echo " 3. Generate Ralph task files after planning: bmalph implement"
1479
+ echo " 4. Navigate to an existing bmalph/Ralph project directory"
1433
1480
  echo " 5. Or create .ralph/PROMPT.md manually in this directory"
1434
1481
  echo ""
1435
1482
  echo "Ralph projects should contain: .ralph/PROMPT.md, .ralph/@fix_plan.md, .ralph/specs/, src/, etc."
@@ -1496,7 +1543,7 @@ main() {
1496
1543
  echo -e "${RED}โ•‘ PERMISSION DENIED - Loop Halted โ•‘${NC}"
1497
1544
  echo -e "${RED}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}"
1498
1545
  echo ""
1499
- echo -e "${YELLOW}Claude Code was denied permission to execute commands.${NC}"
1546
+ echo -e "${YELLOW}$DRIVER_DISPLAY_NAME was denied permission to execute commands.${NC}"
1500
1547
  echo ""
1501
1548
  echo -e "${YELLOW}To fix this:${NC}"
1502
1549
  echo " 1. Edit .ralphrc and update ALLOWED_TOOLS to include the required tools"
@@ -1507,8 +1554,8 @@ main() {
1507
1554
  echo " - Bash(yarn *) - All yarn commands"
1508
1555
  echo ""
1509
1556
  echo -e "${YELLOW}After updating .ralphrc:${NC}"
1510
- echo " ralph --reset-session # Clear stale session state"
1511
- echo " ralph --monitor # Restart the loop"
1557
+ echo " bash .ralph/ralph_loop.sh --reset-session # Clear stale session state"
1558
+ echo " bmalph run # Restart the loop"
1512
1559
  echo ""
1513
1560
 
1514
1561
  # Show current ALLOWED_TOOLS if .ralphrc exists
@@ -1553,7 +1600,7 @@ main() {
1553
1600
  reset_session "circuit_breaker_trip"
1554
1601
  update_status "$loop_count" "$(cat "$CALL_COUNT_FILE")" "circuit_breaker_open" "halted" "stagnation_detected"
1555
1602
  log_status "ERROR" "๐Ÿ›‘ Circuit breaker has opened - halting loop"
1556
- log_status "INFO" "Run 'ralph --reset-circuit' to reset the circuit breaker after addressing issues"
1603
+ log_status "INFO" "Run 'bash .ralph/ralph_loop.sh --reset-circuit' to reset the circuit breaker after addressing issues"
1557
1604
  break
1558
1605
  elif [ $exec_result -eq 2 ]; then
1559
1606
  # API 5-hour limit reached - handle specially
@@ -1605,12 +1652,12 @@ main() {
1605
1652
  # Help function
1606
1653
  show_help() {
1607
1654
  cat << HELPEOF
1608
- Ralph Loop for Claude Code
1655
+ Ralph Loop
1609
1656
 
1610
1657
  Usage: $0 [OPTIONS]
1611
1658
 
1612
- IMPORTANT: This command must be run from a Ralph project directory.
1613
- Use 'ralph-setup project-name' to create a new project first.
1659
+ IMPORTANT: This command must be run from a bmalph/Ralph project directory.
1660
+ Use 'bmalph init' in your project first.
1614
1661
 
1615
1662
  Options:
1616
1663
  -h, --help Show this help message
@@ -1619,15 +1666,15 @@ Options:
1619
1666
  -s, --status Show current status and exit
1620
1667
  -m, --monitor Start with tmux session and live monitor (requires tmux)
1621
1668
  -v, --verbose Show detailed progress updates during execution
1622
- -l, --live Show Claude Code output in real-time (auto-switches to JSON output)
1623
- -t, --timeout MIN Set Claude Code execution timeout in minutes (default: $CLAUDE_TIMEOUT_MINUTES)
1669
+ -l, --live Show live driver output in real-time (auto-switches to JSON output)
1670
+ -t, --timeout MIN Set driver execution timeout in minutes (default: $CLAUDE_TIMEOUT_MINUTES)
1624
1671
  --reset-circuit Reset circuit breaker to CLOSED state
1625
1672
  --circuit-status Show circuit breaker status and exit
1626
1673
  --auto-reset-circuit Auto-reset circuit breaker on startup (bypasses cooldown)
1627
1674
  --reset-session Reset session state and exit (clears session continuity)
1628
1675
 
1629
1676
  Modern CLI Options (Phase 1.1):
1630
- --output-format FORMAT Set Claude output format: json or text (default: $CLAUDE_OUTPUT_FORMAT)
1677
+ --output-format FORMAT Set driver output format: json or text (default: $CLAUDE_OUTPUT_FORMAT)
1631
1678
  Note: --live mode requires JSON and will auto-switch
1632
1679
  --allowed-tools TOOLS Comma-separated list of allowed tools (default: $CLAUDE_ALLOWED_TOOLS)
1633
1680
  --no-continue Disable session continuity across loops
@@ -1643,15 +1690,17 @@ Files created:
1643
1690
  - .ralph/.last_reset: Timestamp of last rate limit reset
1644
1691
 
1645
1692
  Example workflow:
1646
- ralph-setup my-project # Create project
1647
- cd my-project # Enter project directory
1648
- $0 --monitor # Start Ralph with monitoring
1693
+ cd my-project # Enter project directory
1694
+ bmalph init # Install bmalph + Ralph files
1695
+ bmalph implement # Generate Ralph task files
1696
+ $0 --monitor # Start Ralph with monitoring
1649
1697
 
1650
1698
  Examples:
1699
+ bmalph run # Start Ralph via the bmalph CLI
1651
1700
  $0 --calls 50 --prompt my_prompt.md
1652
- $0 --monitor # Start with integrated tmux monitoring
1653
- $0 --live # Show Claude Code output in real-time (streaming)
1654
- $0 --live --verbose # Live streaming + verbose logging
1701
+ $0 --monitor # Start with integrated tmux monitoring
1702
+ $0 --live # Show live driver output in real-time (streaming)
1703
+ $0 --live --verbose # Live streaming + verbose logging
1655
1704
  $0 --monitor --timeout 30 # 30-minute timeout for complex tasks
1656
1705
  $0 --verbose --timeout 5 # 5-minute timeout with detailed progress
1657
1706
  $0 --output-format text # Use legacy text output format