bmalph 2.8.0 → 2.10.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.
- package/README.md +51 -28
- package/dist/cli.js +4 -2
- package/dist/commands/doctor-checks.js +1 -1
- package/dist/commands/doctor-health-checks.js +2 -1
- package/dist/commands/init.js +3 -1
- package/dist/commands/reset.js +1 -1
- package/dist/commands/run.js +49 -1
- package/dist/commands/status.js +0 -9
- package/dist/commands/upgrade.js +1 -1
- package/dist/installer/metadata.js +1 -1
- package/dist/installer/project-files.js +2 -3
- package/dist/installer/ralph-assets.js +8 -0
- package/dist/installer/template-files.js +54 -0
- package/dist/reset.js +2 -3
- package/dist/run/ralph-process.js +13 -3
- package/dist/run/run-dashboard.js +6 -4
- package/dist/transition/artifact-scan.js +3 -6
- package/dist/transition/context.js +1 -1
- package/dist/utils/constants.js +22 -0
- package/dist/utils/github.js +4 -3
- package/dist/utils/ralph-runtime-state.js +3 -13
- package/dist/utils/validate.js +4 -10
- package/dist/watch/dashboard.js +1 -0
- package/dist/watch/renderer.js +23 -0
- package/dist/watch/state-reader.js +20 -1
- package/package.json +8 -2
- package/ralph/drivers/DRIVER_INTERFACE.md +422 -0
- package/ralph/drivers/codex.sh +2 -2
- package/ralph/lib/response_analyzer.sh +87 -87
- package/ralph/ralph_loop.sh +220 -1
- package/ralph/templates/PROMPT.md +12 -0
- package/ralph/templates/REVIEW_PROMPT.md +60 -0
- package/ralph/templates/ralphrc.template +18 -0
- package/dist/cli.js.map +0 -1
- package/dist/commands/check-updates.js.map +0 -1
- package/dist/commands/doctor-checks.js.map +0 -1
- package/dist/commands/doctor-health-checks.js.map +0 -1
- package/dist/commands/doctor-runtime-checks.js.map +0 -1
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/implement.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/reset.js.map +0 -1
- package/dist/commands/run.js.map +0 -1
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/upgrade.js.map +0 -1
- package/dist/commands/watch.js.map +0 -1
- package/dist/installer/bmad-assets.js.map +0 -1
- package/dist/installer/commands.js.map +0 -1
- package/dist/installer/install.js.map +0 -1
- package/dist/installer/metadata.js.map +0 -1
- package/dist/installer/project-files.js.map +0 -1
- package/dist/installer/ralph-assets.js.map +0 -1
- package/dist/installer/template-files.js.map +0 -1
- package/dist/installer/types.js.map +0 -1
- package/dist/installer.js.map +0 -1
- package/dist/platform/aider.js.map +0 -1
- package/dist/platform/claude-code.js.map +0 -1
- package/dist/platform/codex.js.map +0 -1
- package/dist/platform/copilot.js.map +0 -1
- package/dist/platform/cursor-runtime-checks.js.map +0 -1
- package/dist/platform/cursor.js.map +0 -1
- package/dist/platform/detect.js.map +0 -1
- package/dist/platform/doctor-checks.js.map +0 -1
- package/dist/platform/guidance.js.map +0 -1
- package/dist/platform/instructions-snippet.js.map +0 -1
- package/dist/platform/opencode.js.map +0 -1
- package/dist/platform/registry.js.map +0 -1
- package/dist/platform/resolve.js.map +0 -1
- package/dist/platform/types.js.map +0 -1
- package/dist/platform/windsurf.js.map +0 -1
- package/dist/reset.js.map +0 -1
- package/dist/run/ralph-process.js.map +0 -1
- package/dist/run/run-dashboard.js.map +0 -1
- package/dist/run/types.js.map +0 -1
- package/dist/transition/artifact-collection.js.map +0 -1
- package/dist/transition/artifact-loading.js.map +0 -1
- package/dist/transition/artifact-scan.js.map +0 -1
- package/dist/transition/artifacts.js.map +0 -1
- package/dist/transition/context-output.js.map +0 -1
- package/dist/transition/context.js.map +0 -1
- package/dist/transition/fix-plan-sync.js.map +0 -1
- package/dist/transition/fix-plan.js.map +0 -1
- package/dist/transition/index.js.map +0 -1
- package/dist/transition/orchestration.js.map +0 -1
- package/dist/transition/preflight.js.map +0 -1
- package/dist/transition/section-patterns.js.map +0 -1
- package/dist/transition/specs-changelog.js.map +0 -1
- package/dist/transition/specs-index.js.map +0 -1
- package/dist/transition/specs-sync.js.map +0 -1
- package/dist/transition/sprint-status.js.map +0 -1
- package/dist/transition/story-id.js.map +0 -1
- package/dist/transition/story-parsing.js.map +0 -1
- package/dist/transition/tech-stack.js.map +0 -1
- package/dist/transition/types.js.map +0 -1
- package/dist/utils/artifact-definitions.js.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/constants.js.map +0 -1
- package/dist/utils/dryrun.js.map +0 -1
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/file-system.js.map +0 -1
- package/dist/utils/format-status.js.map +0 -1
- package/dist/utils/github.js.map +0 -1
- package/dist/utils/json.js.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/ralph-runtime-state.js.map +0 -1
- package/dist/utils/state.js.map +0 -1
- package/dist/utils/validate.js.map +0 -1
- package/dist/watch/dashboard.js.map +0 -1
- package/dist/watch/file-watcher.js.map +0 -1
- package/dist/watch/frame-writer.js.map +0 -1
- package/dist/watch/renderer.js.map +0 -1
- package/dist/watch/state-reader.js.map +0 -1
- package/dist/watch/types.js.map +0 -1
package/ralph/drivers/codex.sh
CHANGED
|
@@ -46,7 +46,7 @@ driver_permission_denial_help() {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
# Build Codex CLI command
|
|
49
|
-
# Codex uses: codex exec [
|
|
49
|
+
# Codex uses: codex exec [resume <id>] --json "prompt"
|
|
50
50
|
driver_build_command() {
|
|
51
51
|
local prompt_file=$1
|
|
52
52
|
local loop_context=$2
|
|
@@ -67,7 +67,7 @@ driver_build_command() {
|
|
|
67
67
|
|
|
68
68
|
# Session resume — gated on CLAUDE_USE_CONTINUE to respect --no-continue flag
|
|
69
69
|
if [[ "$CLAUDE_USE_CONTINUE" == "true" && -n "$session_id" ]]; then
|
|
70
|
-
CLAUDE_CMD_ARGS+=("
|
|
70
|
+
CLAUDE_CMD_ARGS+=("resume" "$session_id")
|
|
71
71
|
fi
|
|
72
72
|
|
|
73
73
|
# Build prompt with context
|
|
@@ -762,14 +762,14 @@ parse_json_response() {
|
|
|
762
762
|
local summary_has_no_work_pattern="false"
|
|
763
763
|
if [[ "$response_shape" == "codex_jsonl" || "$response_shape" == "opencode_jsonl" || "$response_shape" == "cursor_stream_jsonl" ]] && [[ "$explicit_exit_signal_found" != "true" && -n "$summary" ]]; then
|
|
764
764
|
for keyword in "${COMPLETION_KEYWORDS[@]}"; do
|
|
765
|
-
if echo "$summary" | grep -
|
|
765
|
+
if echo "$summary" | grep -qiw "$keyword"; then
|
|
766
766
|
summary_has_completion_keyword="true"
|
|
767
767
|
break
|
|
768
768
|
fi
|
|
769
769
|
done
|
|
770
770
|
|
|
771
771
|
for pattern in "${NO_WORK_PATTERNS[@]}"; do
|
|
772
|
-
if echo "$summary" | grep -
|
|
772
|
+
if echo "$summary" | grep -qiw "$pattern"; then
|
|
773
773
|
summary_has_no_work_pattern="true"
|
|
774
774
|
break
|
|
775
775
|
fi
|
|
@@ -1035,13 +1035,15 @@ analyze_response() {
|
|
|
1035
1035
|
|
|
1036
1036
|
# Text parsing fallback (original logic)
|
|
1037
1037
|
|
|
1038
|
-
#
|
|
1039
|
-
#
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1038
|
+
# 1. Check for explicit structured output (RALPH_STATUS block)
|
|
1039
|
+
# When a status block is present, it is authoritative — skip all heuristics.
|
|
1040
|
+
# A structurally valid but field-empty block results in exit_signal=false,
|
|
1041
|
+
# confidence=0 by design (AI produced a block but provided no signal).
|
|
1042
|
+
local ralph_status_block_found=false
|
|
1043
1043
|
local ralph_status_json=""
|
|
1044
1044
|
if ralph_status_json=$(extract_ralph_status_block_json "$output_content" 2>/dev/null); then
|
|
1045
|
+
ralph_status_block_found=true
|
|
1046
|
+
|
|
1045
1047
|
local status
|
|
1046
1048
|
status=$(printf '%s' "$ralph_status_json" | jq -r -j '.status' 2>/dev/null)
|
|
1047
1049
|
local exit_sig_found
|
|
@@ -1062,14 +1064,14 @@ analyze_response() {
|
|
|
1062
1064
|
|
|
1063
1065
|
# If EXIT_SIGNAL is explicitly provided, respect it
|
|
1064
1066
|
if [[ "$exit_sig_found" == "true" ]]; then
|
|
1065
|
-
explicit_exit_signal_found=true
|
|
1066
1067
|
if [[ "$exit_sig" == "true" ]]; then
|
|
1067
1068
|
has_completion_signal=true
|
|
1068
1069
|
exit_signal=true
|
|
1069
1070
|
confidence_score=100
|
|
1070
1071
|
else
|
|
1071
|
-
# Explicit EXIT_SIGNAL: false
|
|
1072
|
+
# Explicit EXIT_SIGNAL: false — Claude says to continue
|
|
1072
1073
|
exit_signal=false
|
|
1074
|
+
confidence_score=80
|
|
1073
1075
|
fi
|
|
1074
1076
|
elif [[ "$status" == "COMPLETE" ]]; then
|
|
1075
1077
|
# No explicit EXIT_SIGNAL but STATUS is COMPLETE
|
|
@@ -1077,68 +1079,93 @@ analyze_response() {
|
|
|
1077
1079
|
exit_signal=true
|
|
1078
1080
|
confidence_score=100
|
|
1079
1081
|
fi
|
|
1082
|
+
# is_test_only and is_stuck stay false (defaults) — status block is authoritative
|
|
1080
1083
|
fi
|
|
1081
1084
|
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
if grep -qi "$keyword" "$output_file"; then
|
|
1085
|
-
has_completion_signal=true
|
|
1086
|
-
((confidence_score+=10))
|
|
1087
|
-
break
|
|
1088
|
-
fi
|
|
1089
|
-
done
|
|
1085
|
+
if [[ "$ralph_status_block_found" != "true" ]]; then
|
|
1086
|
+
# No status block found — fall back to heuristic analysis
|
|
1090
1087
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1088
|
+
# 2. Detect completion keywords in natural language output
|
|
1089
|
+
for keyword in "${COMPLETION_KEYWORDS[@]}"; do
|
|
1090
|
+
if grep -qiw "$keyword" "$output_file"; then
|
|
1091
|
+
has_completion_signal=true
|
|
1092
|
+
((confidence_score+=10))
|
|
1093
|
+
break
|
|
1094
|
+
fi
|
|
1095
|
+
done
|
|
1095
1096
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1097
|
+
# 3. Detect test-only loops
|
|
1098
|
+
local test_command_count=0
|
|
1099
|
+
local implementation_count=0
|
|
1100
|
+
local error_count=0
|
|
1098
1101
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
implementation_count=$(echo "$implementation_count" | tr -d '[:space:]')
|
|
1102
|
+
test_command_count=$(grep -c -i "running tests\|npm test\|bats\|pytest\|jest" "$output_file" 2>/dev/null | head -1 || echo "0")
|
|
1103
|
+
implementation_count=$(grep -c -i "implementing\|creating\|writing\|adding\|function\|class" "$output_file" 2>/dev/null | head -1 || echo "0")
|
|
1102
1104
|
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
test_command_count=$((test_command_count + 0))
|
|
1107
|
-
implementation_count=$((implementation_count + 0))
|
|
1105
|
+
# Strip whitespace and ensure it's a number
|
|
1106
|
+
test_command_count=$(echo "$test_command_count" | tr -d '[:space:]')
|
|
1107
|
+
implementation_count=$(echo "$implementation_count" | tr -d '[:space:]')
|
|
1108
1108
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1109
|
+
# Convert to integers with default fallback
|
|
1110
|
+
test_command_count=${test_command_count:-0}
|
|
1111
|
+
implementation_count=${implementation_count:-0}
|
|
1112
|
+
test_command_count=$((test_command_count + 0))
|
|
1113
|
+
implementation_count=$((implementation_count + 0))
|
|
1113
1114
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
# Pattern aligned with ralph_loop.sh to ensure consistent behavior
|
|
1119
|
-
error_count=$(grep -v '"[^"]*error[^"]*":' "$output_file" 2>/dev/null | \
|
|
1120
|
-
grep -cE '(^Error:|^ERROR:|^error:|\]: error|Link: error|Error occurred|failed with error|[Ee]xception|Fatal|FATAL)' \
|
|
1121
|
-
2>/dev/null || echo "0")
|
|
1122
|
-
error_count=$(echo "$error_count" | tr -d '[:space:]')
|
|
1123
|
-
error_count=${error_count:-0}
|
|
1124
|
-
error_count=$((error_count + 0))
|
|
1115
|
+
if [[ $test_command_count -gt 0 ]] && [[ $implementation_count -eq 0 ]]; then
|
|
1116
|
+
is_test_only=true
|
|
1117
|
+
work_summary="Test execution only, no implementation"
|
|
1118
|
+
fi
|
|
1125
1119
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1120
|
+
# 4. Detect stuck/error loops
|
|
1121
|
+
# Use two-stage filtering to avoid counting JSON field names as errors
|
|
1122
|
+
# Stage 1: Filter out JSON field patterns like "is_error": false
|
|
1123
|
+
# Stage 2: Count actual error messages in specific contexts
|
|
1124
|
+
# Pattern aligned with ralph_loop.sh to ensure consistent behavior
|
|
1125
|
+
error_count=$(grep -v '"[^"]*error[^"]*":' "$output_file" 2>/dev/null | \
|
|
1126
|
+
grep -cE '(^Error:|^ERROR:|^error:|\]: error|Link: error|Error occurred|failed with error|[Ee]xception|Fatal|FATAL)' \
|
|
1127
|
+
2>/dev/null || echo "0")
|
|
1128
|
+
error_count=$(echo "$error_count" | tr -d '[:space:]')
|
|
1129
|
+
error_count=${error_count:-0}
|
|
1130
|
+
error_count=$((error_count + 0))
|
|
1131
|
+
|
|
1132
|
+
if [[ $error_count -gt 5 ]]; then
|
|
1133
|
+
is_stuck=true
|
|
1134
|
+
fi
|
|
1129
1135
|
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1136
|
+
# 5. Detect "nothing to do" patterns
|
|
1137
|
+
for pattern in "${NO_WORK_PATTERNS[@]}"; do
|
|
1138
|
+
if grep -qiw "$pattern" "$output_file"; then
|
|
1139
|
+
has_completion_signal=true
|
|
1140
|
+
((confidence_score+=15))
|
|
1141
|
+
work_summary="No work remaining"
|
|
1142
|
+
break
|
|
1143
|
+
fi
|
|
1144
|
+
done
|
|
1145
|
+
|
|
1146
|
+
# 7. Analyze output length trends (detect declining engagement)
|
|
1147
|
+
if [[ -f "$RALPH_DIR/.last_output_length" ]]; then
|
|
1148
|
+
local last_length
|
|
1149
|
+
last_length=$(cat "$RALPH_DIR/.last_output_length")
|
|
1150
|
+
if [[ "$last_length" -gt 0 ]]; then
|
|
1151
|
+
local length_ratio=$((output_length * 100 / last_length))
|
|
1152
|
+
if [[ $length_ratio -lt 50 ]]; then
|
|
1153
|
+
# Output is less than 50% of previous - possible completion
|
|
1154
|
+
((confidence_score+=10))
|
|
1155
|
+
fi
|
|
1156
|
+
fi
|
|
1137
1157
|
fi
|
|
1138
|
-
done
|
|
1139
1158
|
|
|
1140
|
-
|
|
1141
|
-
|
|
1159
|
+
# 9. Determine exit signal based on confidence (heuristic)
|
|
1160
|
+
if [[ $confidence_score -ge 40 || "$has_completion_signal" == "true" ]]; then
|
|
1161
|
+
exit_signal=true
|
|
1162
|
+
fi
|
|
1163
|
+
fi
|
|
1164
|
+
|
|
1165
|
+
# Always persist output length for next iteration (both paths)
|
|
1166
|
+
echo "$output_length" > "$RALPH_DIR/.last_output_length"
|
|
1167
|
+
|
|
1168
|
+
# 6. Check for file changes (git integration) — always runs
|
|
1142
1169
|
if command -v git &>/dev/null && git rev-parse --git-dir >/dev/null 2>&1; then
|
|
1143
1170
|
local loop_start_sha=""
|
|
1144
1171
|
local current_sha=""
|
|
@@ -1174,19 +1201,7 @@ analyze_response() {
|
|
|
1174
1201
|
fi
|
|
1175
1202
|
fi
|
|
1176
1203
|
|
|
1177
|
-
#
|
|
1178
|
-
if [[ -f "$RALPH_DIR/.last_output_length" ]]; then
|
|
1179
|
-
local last_length=$(cat "$RALPH_DIR/.last_output_length")
|
|
1180
|
-
local length_ratio=$((output_length * 100 / last_length))
|
|
1181
|
-
|
|
1182
|
-
if [[ $length_ratio -lt 50 ]]; then
|
|
1183
|
-
# Output is less than 50% of previous - possible completion
|
|
1184
|
-
((confidence_score+=10))
|
|
1185
|
-
fi
|
|
1186
|
-
fi
|
|
1187
|
-
echo "$output_length" > "$RALPH_DIR/.last_output_length"
|
|
1188
|
-
|
|
1189
|
-
# 8. Extract work summary from output
|
|
1204
|
+
# 8. Extract work summary from output — always runs
|
|
1190
1205
|
if [[ -z "$work_summary" ]]; then
|
|
1191
1206
|
# Try to find summary in output
|
|
1192
1207
|
work_summary=$(grep -i "summary\|completed\|implemented" "$output_file" | head -1 | cut -c 1-100)
|
|
@@ -1195,21 +1210,6 @@ analyze_response() {
|
|
|
1195
1210
|
fi
|
|
1196
1211
|
fi
|
|
1197
1212
|
|
|
1198
|
-
# Explicit EXIT_SIGNAL=false means "continue working", so completion
|
|
1199
|
-
# heuristics must not register a done signal.
|
|
1200
|
-
if [[ "$explicit_exit_signal_found" == "true" && "$exit_signal" == "false" ]]; then
|
|
1201
|
-
has_completion_signal=false
|
|
1202
|
-
fi
|
|
1203
|
-
|
|
1204
|
-
# 9. Determine exit signal based on confidence (heuristic)
|
|
1205
|
-
# IMPORTANT: Only apply heuristics if no explicit EXIT_SIGNAL was found in RALPH_STATUS
|
|
1206
|
-
# Claude's explicit intent takes precedence over natural language pattern matching
|
|
1207
|
-
if [[ "$explicit_exit_signal_found" != "true" ]]; then
|
|
1208
|
-
if [[ $confidence_score -ge 40 || "$has_completion_signal" == "true" ]]; then
|
|
1209
|
-
exit_signal=true
|
|
1210
|
-
fi
|
|
1211
|
-
fi
|
|
1212
|
-
|
|
1213
1213
|
local has_permission_denials=false
|
|
1214
1214
|
local permission_denial_count=0
|
|
1215
1215
|
local denied_commands_json='[]'
|
package/ralph/ralph_loop.sh
CHANGED
|
@@ -74,6 +74,9 @@ _env_QUALITY_GATES="${QUALITY_GATES:-}"
|
|
|
74
74
|
_env_QUALITY_GATE_MODE="${QUALITY_GATE_MODE:-}"
|
|
75
75
|
_env_QUALITY_GATE_TIMEOUT="${QUALITY_GATE_TIMEOUT:-}"
|
|
76
76
|
_env_QUALITY_GATE_ON_COMPLETION_ONLY="${QUALITY_GATE_ON_COMPLETION_ONLY:-}"
|
|
77
|
+
_env_REVIEW_ENABLED="${REVIEW_ENABLED:-}"
|
|
78
|
+
_env_REVIEW_INTERVAL="${REVIEW_INTERVAL:-}"
|
|
79
|
+
_env_REVIEW_MODE="${REVIEW_MODE:-}"
|
|
77
80
|
|
|
78
81
|
# Now set defaults (only if not already set by environment)
|
|
79
82
|
MAX_CALLS_PER_HOUR="${MAX_CALLS_PER_HOUR:-100}"
|
|
@@ -107,6 +110,18 @@ QUALITY_GATE_TIMEOUT="${QUALITY_GATE_TIMEOUT:-120}"
|
|
|
107
110
|
QUALITY_GATE_ON_COMPLETION_ONLY="${QUALITY_GATE_ON_COMPLETION_ONLY:-false}"
|
|
108
111
|
QUALITY_GATE_RESULTS_FILE="$RALPH_DIR/.quality_gate_results"
|
|
109
112
|
|
|
113
|
+
# Periodic code review configuration
|
|
114
|
+
REVIEW_ENABLED="${REVIEW_ENABLED:-false}"
|
|
115
|
+
REVIEW_INTERVAL="${REVIEW_INTERVAL:-5}"
|
|
116
|
+
REVIEW_FINDINGS_FILE="$RALPH_DIR/.review_findings.json"
|
|
117
|
+
REVIEW_PROMPT_FILE="$RALPH_DIR/REVIEW_PROMPT.md"
|
|
118
|
+
REVIEW_LAST_SHA_FILE="$RALPH_DIR/.review_last_sha"
|
|
119
|
+
|
|
120
|
+
# REVIEW_MODE is derived in initialize_runtime_context() after .ralphrc is loaded.
|
|
121
|
+
# This ensures backwards compat: old .ralphrc files with only REVIEW_ENABLED=true
|
|
122
|
+
# still map to enhanced mode. Env vars always win via the snapshot/restore mechanism.
|
|
123
|
+
REVIEW_MODE="${REVIEW_MODE:-off}"
|
|
124
|
+
|
|
110
125
|
# Valid tool patterns for --allowed-tools validation
|
|
111
126
|
# Default: Claude Code tools. Platform driver overwrites via driver_valid_tools() in main().
|
|
112
127
|
# Validation runs in main() after load_platform_driver so the correct patterns are in effect.
|
|
@@ -256,6 +271,9 @@ load_ralphrc() {
|
|
|
256
271
|
[[ -n "$_env_QUALITY_GATE_MODE" ]] && QUALITY_GATE_MODE="$_env_QUALITY_GATE_MODE"
|
|
257
272
|
[[ -n "$_env_QUALITY_GATE_TIMEOUT" ]] && QUALITY_GATE_TIMEOUT="$_env_QUALITY_GATE_TIMEOUT"
|
|
258
273
|
[[ -n "$_env_QUALITY_GATE_ON_COMPLETION_ONLY" ]] && QUALITY_GATE_ON_COMPLETION_ONLY="$_env_QUALITY_GATE_ON_COMPLETION_ONLY"
|
|
274
|
+
[[ -n "$_env_REVIEW_ENABLED" ]] && REVIEW_ENABLED="$_env_REVIEW_ENABLED"
|
|
275
|
+
[[ -n "$_env_REVIEW_INTERVAL" ]] && REVIEW_INTERVAL="$_env_REVIEW_INTERVAL"
|
|
276
|
+
[[ -n "$_env_REVIEW_MODE" ]] && REVIEW_MODE="$_env_REVIEW_MODE"
|
|
259
277
|
|
|
260
278
|
normalize_claude_permission_mode
|
|
261
279
|
RALPHRC_FILE="$config_file"
|
|
@@ -306,6 +324,14 @@ initialize_runtime_context() {
|
|
|
306
324
|
fi
|
|
307
325
|
fi
|
|
308
326
|
|
|
327
|
+
# Derive REVIEW_MODE after .ralphrc load so backwards-compat works:
|
|
328
|
+
# old .ralphrc files with only REVIEW_ENABLED=true map to enhanced mode.
|
|
329
|
+
if [[ "$REVIEW_MODE" == "off" && "$REVIEW_ENABLED" == "true" ]]; then
|
|
330
|
+
REVIEW_MODE="enhanced"
|
|
331
|
+
fi
|
|
332
|
+
# Keep REVIEW_ENABLED in sync for any code that checks it
|
|
333
|
+
[[ "$REVIEW_MODE" != "off" ]] && REVIEW_ENABLED="true" || REVIEW_ENABLED="false"
|
|
334
|
+
|
|
309
335
|
# Load platform driver after config so PLATFORM_DRIVER can be overridden.
|
|
310
336
|
load_platform_driver
|
|
311
337
|
RUNTIME_CONTEXT_LOADED=true
|
|
@@ -346,7 +372,7 @@ get_tmux_base_index() {
|
|
|
346
372
|
# Setup tmux session with monitor
|
|
347
373
|
setup_tmux_session() {
|
|
348
374
|
local session_name="ralph-$(date +%s)"
|
|
349
|
-
local ralph_home="${RALPH_HOME:-$
|
|
375
|
+
local ralph_home="${RALPH_HOME:-$SCRIPT_DIR}"
|
|
350
376
|
local project_dir="$(pwd)"
|
|
351
377
|
|
|
352
378
|
initialize_runtime_context
|
|
@@ -1271,6 +1297,177 @@ build_loop_context() {
|
|
|
1271
1297
|
echo "${context:0:500}"
|
|
1272
1298
|
}
|
|
1273
1299
|
|
|
1300
|
+
# Check if a code review should run this iteration
|
|
1301
|
+
# Returns 0 (true) when review is due, 1 (false) otherwise
|
|
1302
|
+
# Args: $1 = loop_count, $2 = fix_plan_completed_delta (optional, for ultimate mode)
|
|
1303
|
+
should_run_review() {
|
|
1304
|
+
[[ "$REVIEW_MODE" == "off" ]] && return 1
|
|
1305
|
+
local loop_count=$1
|
|
1306
|
+
local fix_plan_delta=${2:-0}
|
|
1307
|
+
|
|
1308
|
+
# Never review on first loop (no implementation yet)
|
|
1309
|
+
(( loop_count < 1 )) && return 1
|
|
1310
|
+
|
|
1311
|
+
# Skip if circuit breaker is not CLOSED
|
|
1312
|
+
if [[ -f "$RALPH_DIR/.circuit_breaker_state" ]]; then
|
|
1313
|
+
local cb_state
|
|
1314
|
+
cb_state=$(jq -r '.state // "CLOSED"' "$RALPH_DIR/.circuit_breaker_state" 2>/dev/null)
|
|
1315
|
+
[[ "$cb_state" != "CLOSED" ]] && return 1
|
|
1316
|
+
fi
|
|
1317
|
+
|
|
1318
|
+
# Mode-specific trigger
|
|
1319
|
+
case "$REVIEW_MODE" in
|
|
1320
|
+
enhanced)
|
|
1321
|
+
(( loop_count % REVIEW_INTERVAL != 0 )) && return 1
|
|
1322
|
+
;;
|
|
1323
|
+
ultimate)
|
|
1324
|
+
(( fix_plan_delta < 1 )) && return 1
|
|
1325
|
+
;;
|
|
1326
|
+
*)
|
|
1327
|
+
# Unknown mode — treat as off
|
|
1328
|
+
return 1
|
|
1329
|
+
;;
|
|
1330
|
+
esac
|
|
1331
|
+
|
|
1332
|
+
# Skip if no changes since last review (committed or uncommitted)
|
|
1333
|
+
if command -v git &>/dev/null && git rev-parse --git-dir &>/dev/null 2>&1; then
|
|
1334
|
+
local current_sha last_sha
|
|
1335
|
+
current_sha=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
|
|
1336
|
+
last_sha=""
|
|
1337
|
+
[[ -f "$REVIEW_LAST_SHA_FILE" ]] && last_sha=$(cat "$REVIEW_LAST_SHA_FILE" 2>/dev/null)
|
|
1338
|
+
local has_uncommitted
|
|
1339
|
+
has_uncommitted=$(git status --porcelain 2>/dev/null | head -1)
|
|
1340
|
+
if [[ "$current_sha" == "$last_sha" && -z "$has_uncommitted" ]]; then
|
|
1341
|
+
return 1
|
|
1342
|
+
fi
|
|
1343
|
+
fi
|
|
1344
|
+
return 0
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
# Build review findings context for injection into the next implementation loop
|
|
1348
|
+
# Returns a compact string (max 500-700 chars) with unresolved findings
|
|
1349
|
+
# HIGH/CRITICAL findings get a PRIORITY prefix and a higher char cap (700)
|
|
1350
|
+
build_review_context() {
|
|
1351
|
+
if [[ ! -f "$REVIEW_FINDINGS_FILE" ]]; then
|
|
1352
|
+
echo ""
|
|
1353
|
+
return
|
|
1354
|
+
fi
|
|
1355
|
+
|
|
1356
|
+
local severity issues_found summary
|
|
1357
|
+
severity=$(jq -r '.severity // ""' "$REVIEW_FINDINGS_FILE" 2>/dev/null)
|
|
1358
|
+
issues_found=$(jq -r '.issues_found // 0' "$REVIEW_FINDINGS_FILE" 2>/dev/null)
|
|
1359
|
+
summary=$(jq -r '.summary // ""' "$REVIEW_FINDINGS_FILE" 2>/dev/null | head -c 300)
|
|
1360
|
+
|
|
1361
|
+
if [[ "$issues_found" == "0" || -z "$severity" || "$severity" == "null" ]]; then
|
|
1362
|
+
echo ""
|
|
1363
|
+
return
|
|
1364
|
+
fi
|
|
1365
|
+
|
|
1366
|
+
# HIGH/CRITICAL findings: instruct the AI to fix them before picking a new story
|
|
1367
|
+
local context=""
|
|
1368
|
+
local max_len=500
|
|
1369
|
+
if [[ "$severity" == "HIGH" || "$severity" == "CRITICAL" ]]; then
|
|
1370
|
+
context="PRIORITY: Fix these code review findings BEFORE picking a new story. "
|
|
1371
|
+
max_len=700
|
|
1372
|
+
fi
|
|
1373
|
+
context+="REVIEW FINDINGS ($severity, $issues_found issues): $summary"
|
|
1374
|
+
|
|
1375
|
+
# Include top details if space allows
|
|
1376
|
+
local top_details
|
|
1377
|
+
top_details=$(jq -r '(.details[:2] // []) | map("- [\(.severity)] \(.file): \(.issue)") | join("; ")' "$REVIEW_FINDINGS_FILE" 2>/dev/null | head -c 150)
|
|
1378
|
+
if [[ -n "$top_details" && "$top_details" != "null" ]]; then
|
|
1379
|
+
context+=" Details: $top_details"
|
|
1380
|
+
fi
|
|
1381
|
+
|
|
1382
|
+
echo "${context:0:$max_len}"
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
# Execute a periodic code review loop (read-only, no file modifications)
|
|
1386
|
+
# Uses a fresh ephemeral session with restricted tool permissions
|
|
1387
|
+
run_review_loop() {
|
|
1388
|
+
local loop_count=$1
|
|
1389
|
+
|
|
1390
|
+
log_status "INFO" "Starting periodic code review (loop #$loop_count)"
|
|
1391
|
+
|
|
1392
|
+
# Get diff context (committed + uncommitted changes)
|
|
1393
|
+
local last_sha=""
|
|
1394
|
+
[[ -f "$REVIEW_LAST_SHA_FILE" ]] && last_sha=$(cat "$REVIEW_LAST_SHA_FILE" 2>/dev/null)
|
|
1395
|
+
local diff_context=""
|
|
1396
|
+
if command -v git &>/dev/null && git rev-parse --git-dir &>/dev/null 2>&1; then
|
|
1397
|
+
local committed_diff="" uncommitted_diff=""
|
|
1398
|
+
if [[ -n "$last_sha" ]]; then
|
|
1399
|
+
committed_diff=$(git diff "$last_sha"..HEAD --stat 2>/dev/null | head -20 || true)
|
|
1400
|
+
else
|
|
1401
|
+
committed_diff=$(git diff HEAD~5..HEAD --stat 2>/dev/null | head -20 || true)
|
|
1402
|
+
fi
|
|
1403
|
+
uncommitted_diff=$(git diff --stat 2>/dev/null | head -10 || true)
|
|
1404
|
+
diff_context="${committed_diff}"
|
|
1405
|
+
if [[ -n "$uncommitted_diff" ]]; then
|
|
1406
|
+
diff_context+=$'\nUncommitted:\n'"${uncommitted_diff}"
|
|
1407
|
+
fi
|
|
1408
|
+
[[ -z "$diff_context" ]] && diff_context="No recent changes"
|
|
1409
|
+
fi
|
|
1410
|
+
|
|
1411
|
+
# Check review prompt exists
|
|
1412
|
+
if [[ ! -f "$REVIEW_PROMPT_FILE" ]]; then
|
|
1413
|
+
log_status "WARN" "Review prompt file not found: $REVIEW_PROMPT_FILE — skipping review"
|
|
1414
|
+
return 0
|
|
1415
|
+
fi
|
|
1416
|
+
|
|
1417
|
+
# Build review-specific context
|
|
1418
|
+
local review_context="CODE REVIEW LOOP (read-only). Analyze changes since last review. Recent changes: $diff_context"
|
|
1419
|
+
|
|
1420
|
+
# Save and override CLAUDE_ALLOWED_TOOLS for read-only mode
|
|
1421
|
+
local saved_tools="$CLAUDE_ALLOWED_TOOLS"
|
|
1422
|
+
CLAUDE_ALLOWED_TOOLS="Read,Glob,Grep"
|
|
1423
|
+
|
|
1424
|
+
local timeout_seconds=$((CLAUDE_TIMEOUT_MINUTES * 60))
|
|
1425
|
+
local review_output_file="$LOG_DIR/review_loop_${loop_count}.log"
|
|
1426
|
+
|
|
1427
|
+
# Build command with review prompt and NO session resume (ephemeral)
|
|
1428
|
+
if driver_build_command "$REVIEW_PROMPT_FILE" "$review_context" ""; then
|
|
1429
|
+
# Execute review (capture output)
|
|
1430
|
+
portable_timeout "${timeout_seconds}s" "${CLAUDE_CMD_ARGS[@]}" \
|
|
1431
|
+
< /dev/null > "$review_output_file" 2>&1 || true
|
|
1432
|
+
fi
|
|
1433
|
+
|
|
1434
|
+
# Restore CLAUDE_ALLOWED_TOOLS
|
|
1435
|
+
CLAUDE_ALLOWED_TOOLS="$saved_tools"
|
|
1436
|
+
|
|
1437
|
+
# Parse review findings from output
|
|
1438
|
+
if [[ -f "$review_output_file" ]]; then
|
|
1439
|
+
# Review ran successfully — save SHA so we don't re-review the same state
|
|
1440
|
+
git rev-parse HEAD > "$REVIEW_LAST_SHA_FILE" 2>/dev/null || true
|
|
1441
|
+
|
|
1442
|
+
local findings_json=""
|
|
1443
|
+
# Extract JSON between ---REVIEW_FINDINGS--- and ---END_REVIEW_FINDINGS--- markers
|
|
1444
|
+
findings_json=$(sed -n '/---REVIEW_FINDINGS---/,/---END_REVIEW_FINDINGS---/{//!p;}' "$review_output_file" 2>/dev/null | tr -d '\n' | head -c 5000)
|
|
1445
|
+
|
|
1446
|
+
# If output is JSON format, try extracting from result field first
|
|
1447
|
+
if [[ -z "$findings_json" ]]; then
|
|
1448
|
+
local raw_text
|
|
1449
|
+
raw_text=$(jq -r '.result // .content // ""' "$review_output_file" 2>/dev/null || cat "$review_output_file" 2>/dev/null)
|
|
1450
|
+
findings_json=$(echo "$raw_text" | sed -n '/---REVIEW_FINDINGS---/,/---END_REVIEW_FINDINGS---/{//!p;}' 2>/dev/null | tr -d '\n' | head -c 5000)
|
|
1451
|
+
fi
|
|
1452
|
+
|
|
1453
|
+
if [[ -n "$findings_json" ]]; then
|
|
1454
|
+
# Validate it's valid JSON before writing
|
|
1455
|
+
if echo "$findings_json" | jq . > /dev/null 2>&1; then
|
|
1456
|
+
local tmp_findings="$REVIEW_FINDINGS_FILE.tmp"
|
|
1457
|
+
echo "$findings_json" > "$tmp_findings"
|
|
1458
|
+
mv "$tmp_findings" "$REVIEW_FINDINGS_FILE"
|
|
1459
|
+
local issue_count
|
|
1460
|
+
issue_count=$(echo "$findings_json" | jq -r '.issues_found // 0' 2>/dev/null)
|
|
1461
|
+
log_status "INFO" "Code review complete. $issue_count issue(s) found."
|
|
1462
|
+
else
|
|
1463
|
+
log_status "WARN" "Review findings JSON is malformed — skipping"
|
|
1464
|
+
fi
|
|
1465
|
+
else
|
|
1466
|
+
log_status "INFO" "Code review complete. No structured findings extracted."
|
|
1467
|
+
fi
|
|
1468
|
+
fi
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1274
1471
|
# Get session file age in seconds (cross-platform)
|
|
1275
1472
|
# Returns: age in seconds on stdout, or -1 if stat fails
|
|
1276
1473
|
get_session_file_age_seconds() {
|
|
@@ -1805,6 +2002,13 @@ execute_claude_code() {
|
|
|
1805
2002
|
if build_claude_command "$PROMPT_FILE" "$loop_context" "$session_id"; then
|
|
1806
2003
|
use_modern_cli=true
|
|
1807
2004
|
log_status "INFO" "Using modern CLI mode (${CLAUDE_OUTPUT_FORMAT} output)"
|
|
2005
|
+
|
|
2006
|
+
# Build review findings context (separate from loop context)
|
|
2007
|
+
local review_context=""
|
|
2008
|
+
review_context=$(build_review_context)
|
|
2009
|
+
if [[ -n "$review_context" ]]; then
|
|
2010
|
+
CLAUDE_CMD_ARGS+=("--append-system-prompt" "$review_context")
|
|
2011
|
+
fi
|
|
1808
2012
|
else
|
|
1809
2013
|
log_status "WARN" "Failed to build modern CLI command, falling back to legacy mode"
|
|
1810
2014
|
if [[ "$LIVE_OUTPUT" == "true" ]]; then
|
|
@@ -2336,6 +2540,21 @@ main() {
|
|
|
2336
2540
|
|
|
2337
2541
|
update_status "$loop_count" "$(cat "$CALL_COUNT_FILE")" "completed" "success"
|
|
2338
2542
|
|
|
2543
|
+
# Consume review findings after successful execution — the AI has received
|
|
2544
|
+
# the context via --append-system-prompt. Deleting here (not in
|
|
2545
|
+
# build_review_context) ensures findings survive transient loop failures.
|
|
2546
|
+
rm -f "$REVIEW_FINDINGS_FILE"
|
|
2547
|
+
|
|
2548
|
+
# Code review check
|
|
2549
|
+
local fix_plan_delta=0
|
|
2550
|
+
if [[ -f "$RESPONSE_ANALYSIS_FILE" ]]; then
|
|
2551
|
+
fix_plan_delta=$(jq -r '.analysis.fix_plan_completed_delta // 0' "$RESPONSE_ANALYSIS_FILE" 2>/dev/null || echo "0")
|
|
2552
|
+
[[ ! "$fix_plan_delta" =~ ^-?[0-9]+$ ]] && fix_plan_delta=0
|
|
2553
|
+
fi
|
|
2554
|
+
if should_run_review "$loop_count" "$fix_plan_delta"; then
|
|
2555
|
+
run_review_loop "$loop_count"
|
|
2556
|
+
fi
|
|
2557
|
+
|
|
2339
2558
|
# Brief pause between successful executions
|
|
2340
2559
|
sleep 5
|
|
2341
2560
|
elif [ $exec_result -eq 3 ]; then
|
|
@@ -50,6 +50,18 @@ You are Ralph, an autonomous AI development agent working on a [YOUR PROJECT NAM
|
|
|
50
50
|
- prefer small, reversible changes when requirements are ambiguous
|
|
51
51
|
- surface blockers in the Ralph status block instead of starting a conversation
|
|
52
52
|
|
|
53
|
+
## Self-Review Checklist (Before Reporting Status)
|
|
54
|
+
|
|
55
|
+
Before writing your RALPH_STATUS block, review your own work:
|
|
56
|
+
|
|
57
|
+
1. Re-read the diff of files you modified this loop — check for obvious bugs, typos, missing error handling
|
|
58
|
+
2. Verify you did not introduce regressions in existing functionality
|
|
59
|
+
3. Confirm your changes match the spec in .ralph/specs/ for the story you worked on
|
|
60
|
+
4. Check that new functions have proper error handling and edge case coverage
|
|
61
|
+
5. Ensure you did not leave TODO/FIXME/HACK comments without justification
|
|
62
|
+
|
|
63
|
+
If you find issues, fix them before reporting status. This self-check costs nothing extra.
|
|
64
|
+
|
|
53
65
|
## 🎯 Status Reporting (CRITICAL - Ralph needs this!)
|
|
54
66
|
|
|
55
67
|
**IMPORTANT**: At the end of your response, ALWAYS include this status block:
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Code Review Instructions
|
|
2
|
+
|
|
3
|
+
You are a code reviewer for [YOUR PROJECT NAME].
|
|
4
|
+
Your role is to analyze recent code changes and provide structured quality feedback.
|
|
5
|
+
|
|
6
|
+
## CRITICAL RULES
|
|
7
|
+
|
|
8
|
+
- Do NOT modify any files
|
|
9
|
+
- Do NOT create any files
|
|
10
|
+
- Do NOT run any commands that change state
|
|
11
|
+
- ONLY read, analyze, and report
|
|
12
|
+
|
|
13
|
+
## Review Checklist
|
|
14
|
+
|
|
15
|
+
1. **Correctness**: Logic errors, off-by-one errors, missing edge cases
|
|
16
|
+
2. **Error handling**: Errors properly caught and handled, no swallowed exceptions
|
|
17
|
+
3. **Security**: Hardcoded secrets, injection vectors, unsafe patterns
|
|
18
|
+
4. **Performance**: N+1 queries, unnecessary iterations, memory leaks
|
|
19
|
+
5. **Code quality**: Dead code, duplicated logic, overly complex functions
|
|
20
|
+
6. **Test coverage**: New features tested, tests meaningful (not testing implementation)
|
|
21
|
+
7. **API contracts**: Public interfaces match their documentation and types
|
|
22
|
+
|
|
23
|
+
## What to Analyze
|
|
24
|
+
|
|
25
|
+
- Read the git log and diff summary provided below
|
|
26
|
+
- Check .ralph/specs/ for specification compliance
|
|
27
|
+
- Review modified files for broader context
|
|
28
|
+
- Focus on substantive issues, not style nitpicks
|
|
29
|
+
|
|
30
|
+
## Output Format
|
|
31
|
+
|
|
32
|
+
At the end of your analysis, include this block with a JSON payload:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
---REVIEW_FINDINGS---
|
|
36
|
+
{"severity":"HIGH","issues_found":0,"summary":"No issues found.","details":[]}
|
|
37
|
+
---END_REVIEW_FINDINGS---
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### JSON Schema
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"severity": "LOW | MEDIUM | HIGH | CRITICAL",
|
|
45
|
+
"issues_found": 0,
|
|
46
|
+
"summary": "One paragraph summary of findings",
|
|
47
|
+
"details": [
|
|
48
|
+
{
|
|
49
|
+
"severity": "HIGH",
|
|
50
|
+
"file": "src/example.ts",
|
|
51
|
+
"line": 42,
|
|
52
|
+
"issue": "Description of the issue",
|
|
53
|
+
"suggestion": "How to fix it"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The `severity` field at the top level reflects the highest severity among all issues found.
|
|
60
|
+
If no issues are found, set `severity` to `"LOW"`, `issues_found` to `0`, and `details` to `[]`.
|
|
@@ -125,6 +125,24 @@ QUALITY_GATE_TIMEOUT="${QUALITY_GATE_TIMEOUT:-120}"
|
|
|
125
125
|
# Only run gates when the agent signals completion (EXIT_SIGNAL=true)
|
|
126
126
|
QUALITY_GATE_ON_COMPLETION_ONLY="${QUALITY_GATE_ON_COMPLETION_ONLY:-false}"
|
|
127
127
|
|
|
128
|
+
# =============================================================================
|
|
129
|
+
# PERIODIC CODE REVIEW
|
|
130
|
+
# =============================================================================
|
|
131
|
+
|
|
132
|
+
# Review mode: off, enhanced, or ultimate (set via 'bmalph run --review [mode]')
|
|
133
|
+
# - off: no code review (default)
|
|
134
|
+
# - enhanced: periodic review every REVIEW_INTERVAL loops (~10-14% more tokens)
|
|
135
|
+
# - ultimate: review after every completed story (~20-30% more tokens)
|
|
136
|
+
# The review agent analyzes git diffs and outputs findings for the next implementation loop.
|
|
137
|
+
# Currently supported on Claude Code only.
|
|
138
|
+
REVIEW_MODE="${REVIEW_MODE:-off}"
|
|
139
|
+
|
|
140
|
+
# (Legacy) Enables review — prefer REVIEW_MODE instead
|
|
141
|
+
REVIEW_ENABLED="${REVIEW_ENABLED:-false}"
|
|
142
|
+
|
|
143
|
+
# Number of implementation loops between review sessions (enhanced mode only)
|
|
144
|
+
REVIEW_INTERVAL="${REVIEW_INTERVAL:-5}"
|
|
145
|
+
|
|
128
146
|
# =============================================================================
|
|
129
147
|
# ADVANCED SETTINGS
|
|
130
148
|
# =============================================================================
|
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"check-updates.js","sourceRoot":"","sources":["../../src/commands/check-updates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EACL,aAAa,EACb,cAAc,GAGf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAYvD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAA+B,EAAE;IACzE,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,OAA4B;IACzD,MAAM,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAE3C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAE5C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QAEnE,MAAM,MAAM,GAAe;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU;SACX,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,wBAAwB;IACxB,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QACtF,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CACV,uCAAuC,MAAM,CAAC,IAAI,CAAC,UAAU,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,CAC5F,CACF,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,qCAAqC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,UAAU;IACV,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAClD,CAAC;AACH,CAAC"}
|