@the-bearded-bear/claude-craft 8.26.0 → 8.27.0

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 (187) hide show
  1. package/Dev/i18n/base/Common/commands/aliases.md +48 -48
  2. package/Dev/i18n/base/Common/skills/sub-agents-patterns/SKILL.md +1 -0
  3. package/Dev/i18n/de/Common/agents/devops-engineer.md +19 -14
  4. package/Dev/i18n/de/Common/agents/migration-specialist.md +10 -15
  5. package/Dev/i18n/de/Common/agents/mlops-engineer.md +19 -15
  6. package/Dev/i18n/de/Common/agents/ralph-conductor.md +4 -15
  7. package/Dev/i18n/de/Common/agents/refactoring-specialist.md +0 -9
  8. package/Dev/i18n/de/Common/agents/tdd-coach.md +0 -9
  9. package/Dev/i18n/de/Common/agents/uiux-orchestrator.md +0 -9
  10. package/Dev/i18n/de/Common/commands/ralph-run.md +52 -0
  11. package/Dev/i18n/de/Common/commands/research-context7.md +5 -253
  12. package/Dev/i18n/de/Common/rules/12-context-management.md +10 -8
  13. package/Dev/i18n/de/Common/templates/settings.json.template +4 -0
  14. package/Dev/i18n/de/Python/skills/coding-standards/SKILL.md +1 -1
  15. package/Dev/i18n/de/Python/skills/testing-python/SKILL.md +1 -1
  16. package/Dev/i18n/de/Python/skills/tooling/SKILL.md +1 -1
  17. package/Dev/i18n/de/Symfony/commands/check-security.md +20 -20
  18. package/Dev/i18n/de/Symfony/skills/aggregates/SKILL.md +1 -1
  19. package/Dev/i18n/de/Symfony/skills/async/SKILL.md +1 -1
  20. package/Dev/i18n/de/Symfony/skills/cqrs/SKILL.md +1 -1
  21. package/Dev/i18n/de/Symfony/skills/domain-events/SKILL.md +1 -1
  22. package/Dev/i18n/de/Symfony/skills/i18n/SKILL.md +1 -1
  23. package/Dev/i18n/de/Symfony/skills/multitenant/SKILL.md +1 -1
  24. package/Dev/i18n/de/Symfony/skills/value-objects/SKILL.md +1 -1
  25. package/Dev/i18n/de/Team/commands/audit.md +29 -4
  26. package/Dev/i18n/de/Team/commands/delivery.md +29 -4
  27. package/Dev/i18n/de/Team/commands/security.md +31 -4
  28. package/Dev/i18n/de/Team/commands/sprint.md +30 -5
  29. package/Dev/i18n/de/UIUX/commands/audit.md +1 -30
  30. package/Dev/i18n/de/UIUX/commands/component-spec.md +1 -5
  31. package/Dev/i18n/de/UIUX/commands/orchestrator.md +5 -98
  32. package/Dev/i18n/de/Workflow/commands/auto-sprint.md +7 -4
  33. package/Dev/i18n/de/Workflow/commands/plan.md +1 -2
  34. package/Dev/i18n/en/Common/agents/devops-engineer.md +19 -14
  35. package/Dev/i18n/en/Common/agents/migration-specialist.md +10 -15
  36. package/Dev/i18n/en/Common/agents/mlops-engineer.md +19 -15
  37. package/Dev/i18n/en/Common/agents/ralph-conductor.md +4 -15
  38. package/Dev/i18n/en/Common/agents/refactoring-specialist.md +0 -9
  39. package/Dev/i18n/en/Common/agents/tdd-coach.md +0 -9
  40. package/Dev/i18n/en/Common/agents/uiux-orchestrator.md +0 -9
  41. package/Dev/i18n/en/Common/commands/ralph-run.md +52 -0
  42. package/Dev/i18n/en/Common/commands/research-context7.md +5 -253
  43. package/Dev/i18n/en/Common/rules/12-context-management.md +12 -10
  44. package/Dev/i18n/en/Common/templates/settings.json.template +4 -0
  45. package/Dev/i18n/en/Python/skills/coding-standards/SKILL.md +1 -1
  46. package/Dev/i18n/en/Python/skills/testing-python/SKILL.md +1 -1
  47. package/Dev/i18n/en/Python/skills/tooling/SKILL.md +1 -1
  48. package/Dev/i18n/en/Symfony/commands/check-security.md +20 -20
  49. package/Dev/i18n/en/Symfony/skills/aggregates/SKILL.md +1 -1
  50. package/Dev/i18n/en/Symfony/skills/async/SKILL.md +1 -1
  51. package/Dev/i18n/en/Symfony/skills/cqrs/SKILL.md +1 -1
  52. package/Dev/i18n/en/Symfony/skills/domain-events/SKILL.md +1 -1
  53. package/Dev/i18n/en/Symfony/skills/i18n/SKILL.md +1 -1
  54. package/Dev/i18n/en/Symfony/skills/multitenant/SKILL.md +1 -1
  55. package/Dev/i18n/en/Symfony/skills/value-objects/SKILL.md +1 -1
  56. package/Dev/i18n/en/Team/commands/audit.md +29 -4
  57. package/Dev/i18n/en/Team/commands/delivery.md +29 -4
  58. package/Dev/i18n/en/Team/commands/security.md +31 -4
  59. package/Dev/i18n/en/Team/commands/sprint.md +30 -5
  60. package/Dev/i18n/en/UIUX/commands/audit.md +1 -30
  61. package/Dev/i18n/en/UIUX/commands/component-spec.md +1 -5
  62. package/Dev/i18n/en/UIUX/commands/orchestrator.md +5 -98
  63. package/Dev/i18n/en/Workflow/commands/auto-sprint.md +7 -4
  64. package/Dev/i18n/en/Workflow/commands/plan.md +1 -2
  65. package/Dev/i18n/es/Common/agents/devops-engineer.md +19 -14
  66. package/Dev/i18n/es/Common/agents/migration-specialist.md +10 -15
  67. package/Dev/i18n/es/Common/agents/mlops-engineer.md +19 -15
  68. package/Dev/i18n/es/Common/agents/ralph-conductor.md +4 -15
  69. package/Dev/i18n/es/Common/agents/refactoring-specialist.md +0 -9
  70. package/Dev/i18n/es/Common/agents/tdd-coach.md +0 -9
  71. package/Dev/i18n/es/Common/agents/uiux-orchestrator.md +0 -9
  72. package/Dev/i18n/es/Common/commands/ralph-run.md +52 -0
  73. package/Dev/i18n/es/Common/commands/research-context7.md +5 -253
  74. package/Dev/i18n/es/Common/rules/12-context-management.md +9 -7
  75. package/Dev/i18n/es/Common/templates/settings.json.template +4 -0
  76. package/Dev/i18n/es/Python/skills/coding-standards/SKILL.md +1 -1
  77. package/Dev/i18n/es/Python/skills/testing-python/SKILL.md +1 -1
  78. package/Dev/i18n/es/Python/skills/tooling/SKILL.md +1 -1
  79. package/Dev/i18n/es/Symfony/commands/check-security.md +20 -20
  80. package/Dev/i18n/es/Symfony/skills/aggregates/SKILL.md +1 -1
  81. package/Dev/i18n/es/Symfony/skills/async/SKILL.md +1 -1
  82. package/Dev/i18n/es/Symfony/skills/cqrs/SKILL.md +1 -1
  83. package/Dev/i18n/es/Symfony/skills/domain-events/SKILL.md +1 -1
  84. package/Dev/i18n/es/Symfony/skills/i18n/SKILL.md +1 -1
  85. package/Dev/i18n/es/Symfony/skills/multitenant/SKILL.md +1 -1
  86. package/Dev/i18n/es/Symfony/skills/value-objects/SKILL.md +1 -1
  87. package/Dev/i18n/es/Team/commands/audit.md +29 -4
  88. package/Dev/i18n/es/Team/commands/delivery.md +29 -4
  89. package/Dev/i18n/es/Team/commands/security.md +31 -4
  90. package/Dev/i18n/es/Team/commands/sprint.md +30 -5
  91. package/Dev/i18n/es/UIUX/commands/audit.md +1 -30
  92. package/Dev/i18n/es/UIUX/commands/component-spec.md +1 -5
  93. package/Dev/i18n/es/UIUX/commands/orchestrator.md +5 -98
  94. package/Dev/i18n/es/Workflow/commands/auto-sprint.md +7 -4
  95. package/Dev/i18n/es/Workflow/commands/plan.md +1 -2
  96. package/Dev/i18n/fr/Common/agents/devops-engineer.md +19 -14
  97. package/Dev/i18n/fr/Common/agents/migration-specialist.md +10 -15
  98. package/Dev/i18n/fr/Common/agents/mlops-engineer.md +19 -15
  99. package/Dev/i18n/fr/Common/agents/ralph-conductor.md +4 -15
  100. package/Dev/i18n/fr/Common/agents/refactoring-specialist.md +0 -9
  101. package/Dev/i18n/fr/Common/agents/tdd-coach.md +0 -9
  102. package/Dev/i18n/fr/Common/agents/uiux-orchestrator.md +0 -9
  103. package/Dev/i18n/fr/Common/commands/ralph-run.md +52 -0
  104. package/Dev/i18n/fr/Common/commands/research-context7.md +5 -253
  105. package/Dev/i18n/fr/Common/rules/12-context-management.md +10 -8
  106. package/Dev/i18n/fr/Common/templates/settings.json.template +4 -0
  107. package/Dev/i18n/fr/React/commands/check-compliance.md +1 -1
  108. package/Dev/i18n/fr/React/commands/check-security.md +2 -2
  109. package/Dev/i18n/fr/Symfony/commands/check-security.md +20 -20
  110. package/Dev/i18n/fr/Symfony/skills/aggregates/SKILL.md +1 -1
  111. package/Dev/i18n/fr/Symfony/skills/async/SKILL.md +1 -1
  112. package/Dev/i18n/fr/Symfony/skills/cqrs/SKILL.md +1 -1
  113. package/Dev/i18n/fr/Symfony/skills/domain-events/SKILL.md +1 -1
  114. package/Dev/i18n/fr/Symfony/skills/i18n/SKILL.md +1 -1
  115. package/Dev/i18n/fr/Symfony/skills/multitenant/SKILL.md +1 -1
  116. package/Dev/i18n/fr/Symfony/skills/value-objects/SKILL.md +1 -1
  117. package/Dev/i18n/fr/Team/commands/audit.md +29 -4
  118. package/Dev/i18n/fr/Team/commands/delivery.md +29 -4
  119. package/Dev/i18n/fr/Team/commands/security.md +31 -4
  120. package/Dev/i18n/fr/Team/commands/sprint.md +30 -5
  121. package/Dev/i18n/fr/UIUX/commands/audit.md +1 -30
  122. package/Dev/i18n/fr/UIUX/commands/component-spec.md +1 -5
  123. package/Dev/i18n/fr/UIUX/commands/orchestrator.md +5 -98
  124. package/Dev/i18n/fr/Workflow/commands/auto-sprint.md +7 -4
  125. package/Dev/i18n/fr/Workflow/commands/plan.md +1 -2
  126. package/Dev/i18n/pt/Common/agents/devops-engineer.md +19 -14
  127. package/Dev/i18n/pt/Common/agents/migration-specialist.md +10 -15
  128. package/Dev/i18n/pt/Common/agents/mlops-engineer.md +19 -15
  129. package/Dev/i18n/pt/Common/agents/ralph-conductor.md +4 -15
  130. package/Dev/i18n/pt/Common/agents/refactoring-specialist.md +0 -9
  131. package/Dev/i18n/pt/Common/agents/tdd-coach.md +0 -9
  132. package/Dev/i18n/pt/Common/agents/uiux-orchestrator.md +0 -9
  133. package/Dev/i18n/pt/Common/commands/ralph-run.md +52 -0
  134. package/Dev/i18n/pt/Common/commands/research-context7.md +5 -253
  135. package/Dev/i18n/pt/Common/rules/12-context-management.md +9 -7
  136. package/Dev/i18n/pt/Common/templates/settings.json.template +4 -0
  137. package/Dev/i18n/pt/Python/skills/coding-standards/SKILL.md +1 -1
  138. package/Dev/i18n/pt/Python/skills/testing-python/SKILL.md +1 -1
  139. package/Dev/i18n/pt/Python/skills/tooling/SKILL.md +1 -1
  140. package/Dev/i18n/pt/Symfony/commands/check-security.md +20 -20
  141. package/Dev/i18n/pt/Symfony/skills/aggregates/SKILL.md +1 -1
  142. package/Dev/i18n/pt/Symfony/skills/async/SKILL.md +1 -1
  143. package/Dev/i18n/pt/Symfony/skills/cqrs/SKILL.md +1 -1
  144. package/Dev/i18n/pt/Symfony/skills/domain-events/SKILL.md +1 -1
  145. package/Dev/i18n/pt/Symfony/skills/i18n/SKILL.md +1 -1
  146. package/Dev/i18n/pt/Symfony/skills/multitenant/SKILL.md +1 -1
  147. package/Dev/i18n/pt/Symfony/skills/value-objects/SKILL.md +1 -1
  148. package/Dev/i18n/pt/Team/commands/audit.md +29 -4
  149. package/Dev/i18n/pt/Team/commands/delivery.md +29 -4
  150. package/Dev/i18n/pt/Team/commands/security.md +31 -4
  151. package/Dev/i18n/pt/Team/commands/sprint.md +30 -5
  152. package/Dev/i18n/pt/UIUX/commands/audit.md +1 -30
  153. package/Dev/i18n/pt/UIUX/commands/component-spec.md +1 -5
  154. package/Dev/i18n/pt/UIUX/commands/orchestrator.md +5 -98
  155. package/Dev/i18n/pt/Workflow/commands/auto-sprint.md +7 -4
  156. package/Dev/i18n/pt/Workflow/commands/plan.md +1 -2
  157. package/Dev/scripts/install-common-rules.sh +8 -0
  158. package/README.md +12 -8
  159. package/Tools/Ralph/lib/checkpoint.sh +3 -3
  160. package/Tools/Ralph/lib/circuit-breaker.sh +10 -10
  161. package/Tools/Ralph/lib/context-manager.sh +56 -65
  162. package/Tools/Ralph/lib/context-reconstruction.sh +46 -79
  163. package/Tools/Ralph/lib/dod-templates.sh +2 -2
  164. package/Tools/Ralph/lib/dod-validator.sh +18 -18
  165. package/Tools/Ralph/lib/escalation-service.sh +9 -7
  166. package/Tools/Ralph/lib/hooks-generator.sh +2 -1
  167. package/Tools/Ralph/lib/loop-finalizer.sh +1 -1
  168. package/Tools/Ralph/lib/loop.sh +44 -10
  169. package/Tools/Ralph/lib/metrics-exporter.sh +1 -1
  170. package/Tools/Ralph/lib/parallel-manager.sh +173 -88
  171. package/Tools/Ralph/lib/project-detector.sh +3 -3
  172. package/Tools/Ralph/lib/recovery-engine.sh +8 -8
  173. package/Tools/Ralph/lib/session.sh +2 -2
  174. package/Tools/Ralph/lib/sprint-conductor.sh +167 -124
  175. package/Tools/Ralph/lib/sprint-progress.sh +9 -9
  176. package/Tools/Ralph/ralph.sh +66 -38
  177. package/Tools/StatusLine/statusline.sh +0 -0
  178. package/Tools/i18n/ralph/de.sh +165 -33
  179. package/Tools/i18n/ralph/en.sh +132 -0
  180. package/Tools/i18n/ralph/es.sh +209 -77
  181. package/Tools/i18n/ralph/fr.sh +234 -102
  182. package/Tools/i18n/ralph/pt.sh +227 -95
  183. package/bundles/cursor/.cursorrules +3 -3
  184. package/bundles/windsurf/.windsurfrules +3 -3
  185. package/cli/lib/doctor.js +1 -1
  186. package/config/removed-commands.yaml +61 -1
  187. package/package.json +1 -1
@@ -9,7 +9,7 @@ set -euo pipefail
9
9
  DOD_COMPLETION_MARKER="${DOD_COMPLETION_MARKER:-<promise>COMPLETE</promise>}"
10
10
 
11
11
  # DoD validator types
12
- declare -A DOD_VALIDATORS=(
12
+ declare -gA DOD_VALIDATORS=(
13
13
  ["command"]="validate_command"
14
14
  ["output_contains"]="validate_output_contains"
15
15
  ["file_changed"]="validate_file_changed"
@@ -27,12 +27,12 @@ validate_dod() {
27
27
 
28
28
  # If no config, use simple completion marker check
29
29
  if [[ -z "$config_file" || ! -f "$config_file" ]]; then
30
- return $(validate_simple_completion "$output")
30
+ validate_simple_completion "$output"; return
31
31
  fi
32
32
 
33
33
  # Check if yq is available for YAML parsing
34
34
  if ! command -v yq &> /dev/null; then
35
- return $(validate_simple_completion "$output")
35
+ validate_simple_completion "$output"; return
36
36
  fi
37
37
 
38
38
  # Get DoD checklist from config
@@ -44,7 +44,7 @@ validate_dod() {
44
44
  if [[ -n "$marker" ]]; then
45
45
  DOD_COMPLETION_MARKER="$marker"
46
46
  fi
47
- return $(validate_simple_completion "$output")
47
+ validate_simple_completion "$output"; return
48
48
  fi
49
49
 
50
50
  # Process checklist items
@@ -52,14 +52,14 @@ validate_dod() {
52
52
  local results=()
53
53
 
54
54
  # Get count of checklist items
55
- local count=$(echo "$checklist" | yq e 'length' -)
55
+ local count=$(echo "$checklist" | yq e 'length' -) || true
56
56
 
57
57
  for ((i=0; i<count; i++)); do
58
58
  local item=$(yq e ".definition_of_done.checklist[$i]" "$config_file")
59
- local id=$(echo "$item" | yq e '.id' -)
60
- local name=$(echo "$item" | yq e '.name' -)
61
- local type=$(echo "$item" | yq e '.type' -)
62
- local required=$(echo "$item" | yq e '.required // true' -)
59
+ local id=$(echo "$item" | yq e '.id' -) || true
60
+ local name=$(echo "$item" | yq e '.name' -) || true
61
+ local type=$(echo "$item" | yq e '.type' -) || true
62
+ local required=$(echo "$item" | yq e '.required // true' -) || true
63
63
 
64
64
  # Validate based on type
65
65
  local passed=false
@@ -67,7 +67,7 @@ validate_dod() {
67
67
 
68
68
  case "$type" in
69
69
  command)
70
- local cmd=$(echo "$item" | yq e '.command' -)
70
+ local cmd=$(echo "$item" | yq e '.command' -) || true
71
71
  if validate_command "$cmd"; then
72
72
  passed=true
73
73
  message="Command passed"
@@ -76,7 +76,7 @@ validate_dod() {
76
76
  fi
77
77
  ;;
78
78
  output_contains)
79
- local pattern=$(echo "$item" | yq e '.pattern' -)
79
+ local pattern=$(echo "$item" | yq e '.pattern' -) || true
80
80
  if validate_output_contains "$output" "$pattern"; then
81
81
  passed=true
82
82
  message="Pattern found"
@@ -85,7 +85,7 @@ validate_dod() {
85
85
  fi
86
86
  ;;
87
87
  file_changed)
88
- local pattern=$(echo "$item" | yq e '.pattern' -)
88
+ local pattern=$(echo "$item" | yq e '.pattern' -) || true
89
89
  if validate_file_changed "$pattern"; then
90
90
  passed=true
91
91
  message="Files changed"
@@ -94,7 +94,7 @@ validate_dod() {
94
94
  fi
95
95
  ;;
96
96
  hook)
97
- local script=$(echo "$item" | yq e '.script' -)
97
+ local script=$(echo "$item" | yq e '.script' -) || true
98
98
  if validate_hook "$script" "$output"; then
99
99
  passed=true
100
100
  message="Hook passed"
@@ -103,7 +103,7 @@ validate_dod() {
103
103
  fi
104
104
  ;;
105
105
  human)
106
- local prompt=$(echo "$item" | yq e '.prompt // ""' -)
106
+ local prompt=$(echo "$item" | yq e '.prompt // ""' -) || true
107
107
  if validate_human "$name" "$prompt"; then
108
108
  passed=true
109
109
  message="Human approved"
@@ -209,13 +209,13 @@ validate_file_changed() {
209
209
 
210
210
  # Use git to check for changes matching pattern
211
211
  if command -v git &> /dev/null && git rev-parse --git-dir &> /dev/null; then
212
- local changes=$(git status --porcelain 2>/dev/null | grep -E "$pattern" | wc -l)
212
+ local changes=$(git status --porcelain 2>/dev/null | grep -E "$pattern" | wc -l) || true
213
213
  if [[ $changes -gt 0 ]]; then
214
214
  return 0
215
215
  fi
216
216
  else
217
217
  # Fallback: check for recently modified files
218
- local changes=$(find . -name "$pattern" -mmin -5 2>/dev/null | wc -l)
218
+ local changes=$(find . -name "$pattern" -mmin -5 2>/dev/null | wc -l) || true
219
219
  if [[ $changes -gt 0 ]]; then
220
220
  return 0
221
221
  fi
@@ -381,7 +381,7 @@ export_dod_status() {
381
381
 
382
382
  # Count checks
383
383
  local total
384
- total=$(echo "$checklist" | yq e 'length' -)
384
+ total=$(echo "$checklist" | yq e 'length' -) || total=0
385
385
 
386
386
  local required=0
387
387
  for ((i=0; i<total; i++)); do
@@ -424,7 +424,7 @@ get_dod_summary() {
424
424
 
425
425
  # Build summary
426
426
  local count
427
- count=$(echo "$checklist" | yq e 'length' -)
427
+ count=$(echo "$checklist" | yq e 'length' -) || count=0
428
428
 
429
429
  local checks="["
430
430
  for ((i=0; i<count; i++)); do
@@ -21,7 +21,7 @@ ESCALATION_RESOLVED_DIR=""
21
21
  ESCALATION_AUDIT_FILE=""
22
22
 
23
23
  # Escalation priorities
24
- declare -A ESCALATION_PRIORITIES=(
24
+ declare -gA ESCALATION_PRIORITIES=(
25
25
  ["critical"]=1
26
26
  ["high"]=2
27
27
  ["medium"]=3
@@ -188,7 +188,7 @@ list_escalations() {
188
188
  priority=$(yq e '.priority' "$file")
189
189
 
190
190
  printf "[%s] %s: %s - %s (%s)\n" "$priority" "$id" "$level" "$error_type" "$created"
191
- ((count++))
191
+ count=$((count + 1))
192
192
  fi
193
193
  done
194
194
 
@@ -295,7 +295,9 @@ check_escalation_timeouts() {
295
295
  get_pending_count() {
296
296
  local count=0
297
297
  for file in "$ESCALATION_QUEUE_DIR"/*.yaml; do
298
- [[ -f "$file" ]] && ((count++))
298
+ if [[ -f "$file" ]]; then
299
+ count=$((count + 1))
300
+ fi
299
301
  done
300
302
  echo "$count"
301
303
  }
@@ -421,7 +423,7 @@ build_slack_payload() {
421
423
 
422
424
  local title="Ralph Escalation: $event"
423
425
  local truncated_details
424
- truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ')
426
+ truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ') || true
425
427
 
426
428
  jq -n \
427
429
  --arg color "$color" \
@@ -441,7 +443,7 @@ build_teams_payload() {
441
443
  [[ "$event" == "resolved" ]] && color="good"
442
444
 
443
445
  local truncated_details
444
- truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ')
446
+ truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ') || true
445
447
 
446
448
  jq -n \
447
449
  --arg type "MessageCard" \
@@ -462,7 +464,7 @@ build_discord_payload() {
462
464
  [[ "$event" == "resolved" ]] && color=65280 # Green
463
465
 
464
466
  local truncated_details
465
- truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ')
467
+ truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ') || true
466
468
 
467
469
  jq -n \
468
470
  --arg title "Ralph Escalation: $event" \
@@ -479,7 +481,7 @@ build_generic_payload() {
479
481
  local id="$1" event="$2" level="$3" error="$4" details="$5" session="$6"
480
482
 
481
483
  local truncated_details
482
- truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ')
484
+ truncated_details=$(echo "$details" | head -c 500 | tr '\n' ' ') || true
483
485
 
484
486
  jq -n \
485
487
  --arg event "$event" \
@@ -95,7 +95,8 @@ generate_hooks_config() {
95
95
  # Merge with existing settings
96
96
  local merged
97
97
  if command -v jq &>/dev/null; then
98
- merged=$(echo "$existing_settings" | jq --argjson hooks "$hooks_config" '. + {hooks: $hooks}')
98
+ merged=$(echo "$existing_settings" | jq --argjson hooks "$hooks_config" '. + {hooks: $hooks}') \
99
+ || merged="{\"hooks\": $hooks_config}"
99
100
  else
100
101
  # Fallback: just write hooks config
101
102
  merged="{\"hooks\": $hooks_config}"
@@ -56,7 +56,7 @@ ralph_finalize_loop() {
56
56
 
57
57
  # Save sprint progress before summary
58
58
  if type save_sprint_progress &>/dev/null; then
59
- save_sprint_progress "$session_id"
59
+ save_sprint_progress "$session_id" || print_verbose "No sprint progress file to save"
60
60
  fi
61
61
 
62
62
  # Save metrics export
@@ -13,6 +13,30 @@ CLAUDE_ARGS="${CLAUDE_ARGS:-}"
13
13
  # Claude Invocation
14
14
  # =============================================================================
15
15
 
16
+ # Print a random RFC 4122 v4 UUID (`claude --session-id` requires a valid UUID).
17
+ generate_uuid() {
18
+ if [[ -r /proc/sys/kernel/random/uuid ]]; then
19
+ cat /proc/sys/kernel/random/uuid
20
+ elif command -v uuidgen &> /dev/null; then
21
+ uuidgen | tr '[:upper:]' '[:lower:]'
22
+ else
23
+ local hex
24
+ hex=$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n') || true
25
+ printf '%s-%s-4%s-%x%s-%s\n' "${hex:0:8}" "${hex:8:4}" "${hex:13:3}" \
26
+ $(( (0x${hex:16:1} & 0x3) | 0x8 )) "${hex:17:3}" "${hex:20:12}"
27
+ fi
28
+ }
29
+
30
+ # Print the Claude session UUID pinned to a Ralph session, or nothing if
31
+ # Claude has not been invoked yet for it. Always succeeds (set -e safe).
32
+ get_claude_session_uuid() {
33
+ local id_file="$RALPH_SESSION_BASE/sessions/$1/claude_session_id"
34
+ if [[ -n "$1" && -s "$id_file" ]]; then
35
+ cat "$id_file"
36
+ fi
37
+ return 0
38
+ }
39
+
16
40
  invoke_claude() {
17
41
  local session_id="$1"
18
42
  local prompt="$2"
@@ -25,9 +49,21 @@ invoke_claude() {
25
49
  local -a cmd
26
50
  IFS=' ' read -r -a cmd <<< "${CLAUDE_COMMAND:-claude}"
27
51
 
28
- # Add continue flag if we have a session
52
+ # Pin an explicit Claude session per Ralph session. `--continue` resumes
53
+ # "the most recent conversation in this directory", which parallel workers
54
+ # (and unrelated user sessions) would share.
29
55
  if [[ -n "$session_id" ]]; then
30
- cmd+=(--continue)
56
+ local claude_session_uuid
57
+ claude_session_uuid=$(get_claude_session_uuid "$session_id")
58
+ if [[ -n "$claude_session_uuid" ]]; then
59
+ cmd+=(--resume "$claude_session_uuid")
60
+ else
61
+ local id_file="$RALPH_SESSION_BASE/sessions/$session_id/claude_session_id"
62
+ claude_session_uuid=$(generate_uuid)
63
+ mkdir -p "$(dirname "$id_file")"
64
+ echo "$claude_session_uuid" > "$id_file"
65
+ cmd+=(--session-id "$claude_session_uuid")
66
+ fi
31
67
  fi
32
68
 
33
69
  # Add prompt
@@ -39,12 +75,11 @@ invoke_claude() {
39
75
  # Execute with timeout
40
76
  local timeout_sec=$((timeout / 1000))
41
77
  local output
42
- local exit_code
78
+ local exit_code=0
43
79
 
44
80
  # Use timeout command if available
45
81
  if command -v timeout &> /dev/null; then
46
- output=$(timeout "${timeout_sec}s" "${cmd[@]}" "$prompt" 2>&1)
47
- exit_code=$?
82
+ output=$(timeout "${timeout_sec}s" "${cmd[@]}" "$prompt" 2>&1) || exit_code=$?
48
83
 
49
84
  # Check for timeout (exit code 124)
50
85
  if [[ $exit_code -eq 124 ]]; then
@@ -53,8 +88,7 @@ invoke_claude() {
53
88
  fi
54
89
  else
55
90
  # Fallback without timeout
56
- output=$("${cmd[@]}" "$prompt" 2>&1)
57
- exit_code=$?
91
+ output=$("${cmd[@]}" "$prompt" 2>&1) || exit_code=$?
58
92
  fi
59
93
 
60
94
  # Log result
@@ -104,7 +138,7 @@ detect_file_changes() {
104
138
 
105
139
  # Use git to detect changes if available
106
140
  if command -v git &> /dev/null && git rev-parse --git-dir &> /dev/null; then
107
- local changes=$(git status --porcelain 2>/dev/null | wc -l)
141
+ local changes=$(git status --porcelain 2>/dev/null | wc -l) || true
108
142
  log_session "$session_id" "DEBUG" "Detected $changes file changes"
109
143
  echo "$changes"
110
144
  else
@@ -112,7 +146,7 @@ detect_file_changes() {
112
146
  local changes=0
113
147
  for dir in src lib app tests; do
114
148
  if [[ -d "$dir" ]]; then
115
- local recent=$(find "$dir" -type f -mmin -1 2>/dev/null | wc -l)
149
+ local recent=$(find "$dir" -type f -mmin -1 2>/dev/null | wc -l) || true
116
150
  changes=$((changes + recent))
117
151
  fi
118
152
  done
@@ -219,7 +253,7 @@ get_loop_state() {
219
253
  status: (.status // "unknown"),
220
254
  circuit_breaker: (.circuit_breaker // {}),
221
255
  dod_results: (.dod_results // [])
222
- }' 2>/dev/null)
256
+ }' 2>/dev/null) || result=""
223
257
 
224
258
  if [[ -n "$result" ]]; then
225
259
  echo "$result"
@@ -12,7 +12,7 @@ METRICS_REALTIME_ENABLED="${METRICS_REALTIME_ENABLED:-true}"
12
12
  METRICS_REALTIME_INTERVAL="${METRICS_REALTIME_INTERVAL:-1000}"
13
13
 
14
14
  # Metrics data
15
- declare -A METRICS_DATA
15
+ declare -gA METRICS_DATA
16
16
  METRICS_START_TIME=0
17
17
  METRICS_ITERATION_TIMES=()
18
18
  METRICS_CONTEXT_SAMPLES=()