bmalph 2.7.2 → 2.7.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.
Files changed (40) 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 +8 -3
  13. package/dist/transition/fix-plan.js.map +1 -1
  14. package/dist/transition/orchestration.js +176 -111
  15. package/dist/transition/orchestration.js.map +1 -1
  16. package/dist/transition/preflight.js +21 -16
  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-parsing.js +4 -3
  27. package/dist/transition/story-parsing.js.map +1 -1
  28. package/dist/transition/tech-stack.js +1 -7
  29. package/dist/transition/tech-stack.js.map +1 -1
  30. package/package.json +1 -1
  31. package/ralph/RALPH-REFERENCE.md +50 -46
  32. package/ralph/drivers/cursor-agent-wrapper.sh +13 -0
  33. package/ralph/drivers/cursor.sh +168 -7
  34. package/ralph/lib/circuit_breaker.sh +5 -5
  35. package/ralph/lib/enable_core.sh +10 -10
  36. package/ralph/ralph_import.sh +14 -10
  37. package/ralph/ralph_loop.sh +94 -57
  38. package/ralph/ralph_monitor.sh +4 -4
  39. package/ralph/templates/AGENT.md +7 -7
  40. package/ralph/templates/PROMPT.md +13 -13
@@ -16,7 +16,15 @@ driver_display_name() {
16
16
  }
17
17
 
18
18
  driver_cli_binary() {
19
- echo "agent"
19
+ local binary
20
+ binary=$(driver_resolve_cli_binary)
21
+
22
+ if [[ -n "$binary" ]]; then
23
+ echo "$binary"
24
+ return 0
25
+ fi
26
+
27
+ echo "cursor-agent"
20
28
  }
21
29
 
22
30
  driver_min_version() {
@@ -24,7 +32,14 @@ driver_min_version() {
24
32
  }
25
33
 
26
34
  driver_check_available() {
27
- command -v "$(driver_cli_binary)" &>/dev/null
35
+ local cli_binary
36
+ cli_binary=$(driver_cli_binary)
37
+
38
+ if [[ -f "$cli_binary" ]]; then
39
+ return 0
40
+ fi
41
+
42
+ command -v "$cli_binary" &>/dev/null
28
43
  }
29
44
 
30
45
  # Cursor CLI tool names
@@ -46,14 +61,21 @@ driver_build_command() {
46
61
  local prompt_file=$1
47
62
  local loop_context=$2
48
63
  local session_id=$3
49
-
50
- CLAUDE_CMD_ARGS=("$(driver_cli_binary)")
64
+ local cli_binary
65
+ cli_binary=$(driver_cli_binary)
51
66
 
52
67
  if [[ ! -f "$prompt_file" ]]; then
53
68
  echo "ERROR: Prompt file not found: $prompt_file" >&2
54
69
  return 1
55
70
  fi
56
71
 
72
+ CLAUDE_CMD_ARGS=()
73
+ if [[ "$cli_binary" == *.cmd ]]; then
74
+ CLAUDE_CMD_ARGS+=("$(driver_wrapper_path)" "$cli_binary")
75
+ else
76
+ CLAUDE_CMD_ARGS+=("$cli_binary")
77
+ fi
78
+
57
79
  # Headless mode
58
80
  CLAUDE_CMD_ARGS+=("--print")
59
81
 
@@ -70,11 +92,15 @@ driver_build_command() {
70
92
 
71
93
  # Build prompt with context prepended
72
94
  local prompt_content
73
- prompt_content=$(cat "$prompt_file")
74
- if [[ -n "$loop_context" ]]; then
75
- prompt_content="$loop_context
95
+ if driver_running_on_windows; then
96
+ prompt_content=$(driver_build_windows_bootstrap_prompt "$loop_context" "$prompt_file")
97
+ else
98
+ prompt_content=$(cat "$prompt_file")
99
+ if [[ -n "$loop_context" ]]; then
100
+ prompt_content="$loop_context
76
101
 
77
102
  $prompt_content"
103
+ fi
78
104
  fi
79
105
 
80
106
  CLAUDE_CMD_ARGS+=("$prompt_content")
@@ -88,3 +114,138 @@ driver_supports_sessions() {
88
114
  driver_stream_filter() {
89
115
  echo 'select(.type == "text") | .content // empty'
90
116
  }
117
+
118
+ driver_running_on_windows() {
119
+ [[ "${OS:-}" == "Windows_NT" || "${OSTYPE:-}" == msys* || "${OSTYPE:-}" == cygwin* || "${OSTYPE:-}" == win32* ]]
120
+ }
121
+
122
+ driver_resolve_cli_binary() {
123
+ local candidate
124
+ local resolved
125
+ local fallback
126
+ local candidates=(
127
+ "cursor-agent"
128
+ "cursor-agent.cmd"
129
+ "agent"
130
+ "agent.cmd"
131
+ )
132
+
133
+ for candidate in "${candidates[@]}"; do
134
+ resolved=$(driver_lookup_cli_candidate "$candidate")
135
+ if [[ -n "$resolved" ]]; then
136
+ echo "$resolved"
137
+ return 0
138
+ fi
139
+ done
140
+
141
+ fallback=$(driver_localappdata_cli_binary)
142
+ if [[ -n "$fallback" ]]; then
143
+ echo "$fallback"
144
+ return 0
145
+ fi
146
+
147
+ echo ""
148
+ }
149
+
150
+ driver_lookup_cli_candidate() {
151
+ local candidate=$1
152
+ local resolved
153
+
154
+ resolved=$(command -v "$candidate" 2>/dev/null || true)
155
+ if [[ -n "$resolved" ]]; then
156
+ echo "$resolved"
157
+ return 0
158
+ fi
159
+
160
+ if ! driver_running_on_windows; then
161
+ return 0
162
+ fi
163
+
164
+ driver_find_windows_path_candidate "$candidate"
165
+ }
166
+
167
+ driver_find_windows_path_candidate() {
168
+ local candidate=$1
169
+ local path_entry
170
+ local normalized_entry
171
+ local resolved_candidate
172
+ local path_entries="${PATH:-}"
173
+ local -a path_parts=()
174
+
175
+ if [[ "$path_entries" == *";"* ]]; then
176
+ IFS=';' read -r -a path_parts <<< "$path_entries"
177
+ else
178
+ IFS=':' read -r -a path_parts <<< "$path_entries"
179
+ fi
180
+
181
+ for path_entry in "${path_parts[@]}"; do
182
+ [[ -z "$path_entry" ]] && continue
183
+
184
+ normalized_entry=$path_entry
185
+ if command -v cygpath &>/dev/null && [[ "$normalized_entry" =~ ^[A-Za-z]:\\ ]]; then
186
+ normalized_entry=$(cygpath -u "$normalized_entry")
187
+ fi
188
+
189
+ resolved_candidate="$normalized_entry/$candidate"
190
+ if [[ -f "$resolved_candidate" ]]; then
191
+ echo "$resolved_candidate"
192
+ return 0
193
+ fi
194
+ done
195
+ }
196
+
197
+ driver_localappdata_cli_binary() {
198
+ local local_app_data="${LOCALAPPDATA:-}"
199
+
200
+ if [[ -z "$local_app_data" ]] || ! driver_running_on_windows; then
201
+ return 0
202
+ fi
203
+
204
+ if command -v cygpath &>/dev/null && [[ "$local_app_data" =~ ^[A-Za-z]:\\ ]]; then
205
+ local_app_data=$(cygpath -u "$local_app_data")
206
+ fi
207
+
208
+ local candidate="$local_app_data/cursor-agent/agent.cmd"
209
+ if [[ -f "$candidate" ]]; then
210
+ echo "$candidate"
211
+ fi
212
+ }
213
+
214
+ driver_wrapper_path() {
215
+ local driver_dir
216
+ driver_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
217
+ echo "$driver_dir/cursor-agent-wrapper.sh"
218
+ }
219
+
220
+ driver_build_windows_bootstrap_prompt() {
221
+ local loop_context=$1
222
+ local prompt_file=$2
223
+
224
+ cat <<EOF
225
+ Read these Ralph workspace files before taking action:
226
+ - .ralph/PROMPT.md
227
+ - .ralph/PROJECT_CONTEXT.md
228
+ - .ralph/SPECS_INDEX.md
229
+ - .ralph/@fix_plan.md
230
+ - .ralph/@AGENT.md
231
+ - relevant files under .ralph/specs/
232
+
233
+ Then follow the Ralph instructions from those files and continue the next task.
234
+ EOF
235
+
236
+ if [[ -n "$loop_context" ]]; then
237
+ cat <<EOF
238
+
239
+ Current loop context:
240
+ $loop_context
241
+ EOF
242
+ fi
243
+
244
+ if [[ "$prompt_file" != ".ralph/PROMPT.md" ]]; then
245
+ cat <<EOF
246
+
247
+ Also read the active prompt file if it differs:
248
+ - $prompt_file
249
+ EOF
250
+ fi
251
+ }
@@ -463,16 +463,16 @@ should_halt_execution() {
463
463
  echo -e "${YELLOW}Ralph has detected that no progress is being made.${NC}"
464
464
  echo ""
465
465
  echo -e "${YELLOW}Possible reasons:${NC}"
466
- echo " • Project may be complete (check .ralph/fix_plan.md)"
467
- echo " • Claude may be stuck on an error"
466
+ echo " • Project may be complete (check .ralph/@fix_plan.md)"
467
+ echo " • The active driver may be stuck on an error"
468
468
  echo " • .ralph/PROMPT.md may need clarification"
469
469
  echo " • Manual intervention may be required"
470
470
  echo ""
471
471
  echo -e "${YELLOW}To continue:${NC}"
472
472
  echo " 1. Review recent logs: tail -20 .ralph/logs/ralph.log"
473
- echo " 2. Check Claude output: ls -lt .ralph/logs/claude_output_*.log | head -1"
474
- echo " 3. Update .ralph/fix_plan.md if needed"
475
- echo " 4. Reset circuit breaker: ralph --reset-circuit"
473
+ echo " 2. Check recent driver output: ls -lt .ralph/logs/claude_output_*.log | head -1"
474
+ echo " 3. Update .ralph/@fix_plan.md if needed"
475
+ echo " 4. Reset circuit breaker: bash .ralph/ralph_loop.sh --reset-circuit"
476
476
  echo ""
477
477
  return 0 # Signal to halt
478
478
  else
@@ -83,8 +83,8 @@ check_existing_ralph() {
83
83
  # Check for required files
84
84
  local required_files=(
85
85
  ".ralph/PROMPT.md"
86
- ".ralph/fix_plan.md"
87
- ".ralph/AGENT.md"
86
+ ".ralph/@fix_plan.md"
87
+ ".ralph/@AGENT.md"
88
88
  )
89
89
 
90
90
  local missing=()
@@ -505,7 +505,7 @@ generate_prompt_md() {
505
505
  objectives_section="$objectives"
506
506
  else
507
507
  objectives_section="- Review the codebase and understand the current state
508
- - Follow tasks in fix_plan.md
508
+ - Follow tasks in @fix_plan.md
509
509
  - Implement one task per loop
510
510
  - Write tests for new functionality
511
511
  - Update documentation as needed"
@@ -527,7 +527,7 @@ ${objectives_section}
527
527
  - ONE task per loop - focus on the most important thing
528
528
  - Search the codebase before assuming something isn't implemented
529
529
  - Write comprehensive tests with clear documentation
530
- - Update fix_plan.md with your learnings
530
+ - Update @fix_plan.md with your learnings
531
531
  - Commit working changes with descriptive messages
532
532
 
533
533
  ## Testing Guidelines
@@ -536,7 +536,7 @@ ${objectives_section}
536
536
  - Only write tests for NEW functionality you implement
537
537
 
538
538
  ## Build & Run
539
- See AGENT.md for build and run instructions.
539
+ See @AGENT.md for build and run instructions.
540
540
 
541
541
  ## Status Reporting (CRITICAL)
542
542
 
@@ -555,11 +555,11 @@ RECOMMENDATION: <one line summary of what to do next>
555
555
  \`\`\`
556
556
 
557
557
  ## Current Task
558
- Follow fix_plan.md and choose the most important item to implement next.
558
+ Follow @fix_plan.md and choose the most important item to implement next.
559
559
  PROMPTEOF
560
560
  }
561
561
 
562
- # generate_agent_md - Generate AGENT.md with detected build commands
562
+ # generate_agent_md - Generate @AGENT.md with detected build commands
563
563
  #
564
564
  # Parameters:
565
565
  # $1 (build_cmd) - Build command
@@ -604,7 +604,7 @@ ${run_cmd}
604
604
  AGENTEOF
605
605
  }
606
606
 
607
- # generate_fix_plan_md - Generate fix_plan.md with imported tasks
607
+ # generate_fix_plan_md - Generate @fix_plan.md with imported tasks
608
608
  #
609
609
  # Parameters:
610
610
  # $1 (tasks) - Tasks to include (newline-separated, markdown checkbox format)
@@ -768,11 +768,11 @@ enable_ralph_in_directory() {
768
768
 
769
769
  local agent_content
770
770
  agent_content=$(generate_agent_md "$DETECTED_BUILD_CMD" "$DETECTED_TEST_CMD" "$DETECTED_RUN_CMD")
771
- safe_create_file ".ralph/AGENT.md" "$agent_content"
771
+ safe_create_file ".ralph/@AGENT.md" "$agent_content"
772
772
 
773
773
  local fix_plan_content
774
774
  fix_plan_content=$(generate_fix_plan_md "$task_content")
775
- safe_create_file ".ralph/fix_plan.md" "$fix_plan_content"
775
+ safe_create_file ".ralph/@fix_plan.md" "$fix_plan_content"
776
776
 
777
777
  # Detect task sources for .ralphrc
778
778
  detect_task_sources
@@ -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