spec-and-loop 1.0.8 → 1.2.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/QUICKSTART.md +265 -53
- package/README.md +210 -175
- package/lib/mini-ralph/context.js +99 -0
- package/lib/mini-ralph/errors.js +112 -0
- package/lib/mini-ralph/history.js +99 -0
- package/lib/mini-ralph/index.js +93 -0
- package/lib/mini-ralph/invoker.js +243 -0
- package/lib/mini-ralph/prompt.js +116 -0
- package/lib/mini-ralph/runner.js +495 -0
- package/lib/mini-ralph/state.js +93 -0
- package/lib/mini-ralph/status.js +238 -0
- package/lib/mini-ralph/tasks.js +209 -0
- package/package.json +3 -3
- package/scripts/mini-ralph-cli.js +226 -0
- package/scripts/ralph-run.sh +182 -72
- package/scripts/setup.js +39 -31
package/scripts/ralph-run.sh
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
set -e
|
|
4
|
-
|
|
5
3
|
VERSION="1.0.0"
|
|
6
4
|
|
|
7
|
-
# Add Bun to PATH if installed
|
|
8
|
-
if [[ -d "$HOME/.bun/bin" ]]; then
|
|
9
|
-
export PATH="$HOME/.bun/bin:$PATH"
|
|
10
|
-
fi
|
|
11
|
-
|
|
12
5
|
# Detect OS for cross-platform compatibility
|
|
13
6
|
detect_os() {
|
|
14
7
|
case "$(uname -s)" in
|
|
@@ -63,8 +56,8 @@ get_realpath() {
|
|
|
63
56
|
|
|
64
57
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
65
58
|
LOCAL_NODE_BIN="$SCRIPT_DIR/../node_modules/.bin"
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
# Allow tests to inject a mock by setting MINI_RALPH_CLI_OVERRIDE in the environment
|
|
60
|
+
MINI_RALPH_CLI="${MINI_RALPH_CLI_OVERRIDE:-$SCRIPT_DIR/mini-ralph-cli.js}"
|
|
68
61
|
|
|
69
62
|
if [[ -d "$LOCAL_NODE_BIN" ]]; then
|
|
70
63
|
case ":$PATH:" in
|
|
@@ -105,22 +98,18 @@ make_temp_dir() {
|
|
|
105
98
|
}
|
|
106
99
|
|
|
107
100
|
resolve_ralph_command() {
|
|
108
|
-
if command -v
|
|
109
|
-
RALPH_CMD=("ralph")
|
|
101
|
+
if [[ -f "$MINI_RALPH_CLI" ]] && command -v node >/dev/null 2>&1; then
|
|
110
102
|
return 0
|
|
111
103
|
fi
|
|
112
|
-
|
|
113
|
-
if [[ -f "$BUNDLED_RALPH_JS" ]] && command -v node >/dev/null 2>&1; then
|
|
114
|
-
RALPH_CMD=("node" "$BUNDLED_RALPH_JS")
|
|
115
|
-
return 0
|
|
116
|
-
fi
|
|
117
|
-
|
|
118
|
-
RALPH_CMD=()
|
|
119
104
|
return 1
|
|
120
105
|
}
|
|
121
106
|
|
|
122
107
|
CHANGE_NAME=""
|
|
123
108
|
MAX_ITERATIONS=""
|
|
109
|
+
NO_COMMIT=false
|
|
110
|
+
SHOW_STATUS=false
|
|
111
|
+
ADD_CONTEXT=""
|
|
112
|
+
CLEAR_CONTEXT=false
|
|
124
113
|
ERROR_OCCURRED=false
|
|
125
114
|
CLEANUP_IN_PROGRESS=false
|
|
126
115
|
|
|
@@ -135,12 +124,10 @@ cleanup() {
|
|
|
135
124
|
local exit_code=$1
|
|
136
125
|
log_info "Cleaning up..."
|
|
137
126
|
|
|
138
|
-
# NOTE: We do NOT kill
|
|
139
|
-
# 1. Ralph runs synchronously in the foreground
|
|
127
|
+
# NOTE: We do NOT kill node processes here because:
|
|
128
|
+
# 1. The mini Ralph runtime runs synchronously in the foreground
|
|
140
129
|
# 2. Ctrl+C (SIGINT) naturally propagates to child processes
|
|
141
|
-
# 3.
|
|
142
|
-
# 4. Using pkill -f "ralph" could kill other user processes
|
|
143
|
-
# The shell's process group handling ensures clean termination.
|
|
130
|
+
# 3. The shell's process group handling ensures clean termination.
|
|
144
131
|
|
|
145
132
|
if [[ $exit_code -ne 0 ]]; then
|
|
146
133
|
log_error "Script terminated with exit code: $exit_code"
|
|
@@ -148,7 +135,9 @@ cleanup() {
|
|
|
148
135
|
exit $exit_code
|
|
149
136
|
}
|
|
150
137
|
|
|
151
|
-
|
|
138
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
139
|
+
trap 'cleanup $?' EXIT INT TERM QUIT
|
|
140
|
+
fi
|
|
152
141
|
|
|
153
142
|
handle_error() {
|
|
154
143
|
local exit_code=$1
|
|
@@ -171,19 +160,28 @@ USAGE:
|
|
|
171
160
|
OPTIONS:
|
|
172
161
|
--change <name> Specify the OpenSpec change to execute (default: auto-detect)
|
|
173
162
|
--max-iterations <n> Maximum iterations for Ralph loop (default: 50)
|
|
163
|
+
--no-commit Suppress automatic git commits during the loop
|
|
174
164
|
--verbose, -v Enable verbose mode for debugging
|
|
175
165
|
--help, -h Show this help message
|
|
176
166
|
|
|
167
|
+
OBSERVABILITY AND CONTROL:
|
|
168
|
+
--status Print the current loop status dashboard and exit
|
|
169
|
+
--add-context <text> Add pending context to inject into the next iteration and exit
|
|
170
|
+
--clear-context Clear any pending context and exit
|
|
171
|
+
|
|
177
172
|
EXAMPLES:
|
|
178
173
|
ralph-run # Auto-detect most recent change
|
|
179
174
|
ralph-run --change my-feature # Execute specific change
|
|
180
|
-
ralph-run --max-iterations 100
|
|
175
|
+
ralph-run --change my-feature --max-iterations 100
|
|
176
|
+
ralph-run --change my-feature --no-commit # Run without auto-committing
|
|
181
177
|
ralph-run --verbose # Run with debug output
|
|
178
|
+
ralph-run --status # Check status of the active loop
|
|
179
|
+
ralph-run --add-context "Focus on error handling in module X"
|
|
180
|
+
ralph-run --clear-context # Remove pending context
|
|
182
181
|
|
|
183
182
|
PREREQUISITES:
|
|
184
183
|
- Git repository (git init)
|
|
185
|
-
- OpenSpec artifacts created (openspec init,
|
|
186
|
-
- ralph CLI installed (npm install -g @th0rgal/ralph-wiggum)
|
|
184
|
+
- OpenSpec artifacts created (openspec init, openspec new, openspec ff)
|
|
187
185
|
- opencode CLI installed (npm install -g opencode-ai)
|
|
188
186
|
|
|
189
187
|
EOF
|
|
@@ -200,10 +198,26 @@ parse_arguments() {
|
|
|
200
198
|
MAX_ITERATIONS="$2"
|
|
201
199
|
shift 2
|
|
202
200
|
;;
|
|
201
|
+
--no-commit)
|
|
202
|
+
NO_COMMIT=true
|
|
203
|
+
shift
|
|
204
|
+
;;
|
|
203
205
|
--verbose|-v)
|
|
204
206
|
VERBOSE=true
|
|
205
207
|
shift
|
|
206
208
|
;;
|
|
209
|
+
--status)
|
|
210
|
+
SHOW_STATUS=true
|
|
211
|
+
shift
|
|
212
|
+
;;
|
|
213
|
+
--add-context)
|
|
214
|
+
ADD_CONTEXT="$2"
|
|
215
|
+
shift 2
|
|
216
|
+
;;
|
|
217
|
+
--clear-context)
|
|
218
|
+
CLEAR_CONTEXT=true
|
|
219
|
+
shift
|
|
220
|
+
;;
|
|
207
221
|
--help|-h)
|
|
208
222
|
SHOW_HELP=true
|
|
209
223
|
shift
|
|
@@ -252,12 +266,11 @@ validate_dependencies() {
|
|
|
252
266
|
log_verbose "Validating dependencies..."
|
|
253
267
|
|
|
254
268
|
if ! resolve_ralph_command; then
|
|
255
|
-
log_error "
|
|
256
|
-
log_error "
|
|
257
|
-
log_error "If spec-and-loop is globally installed, reinstalling it should also restore the bundled Ralph dependency."
|
|
269
|
+
log_error "Internal mini Ralph runtime not found: $MINI_RALPH_CLI"
|
|
270
|
+
log_error "Ensure node is installed and spec-and-loop dependencies are up to date (npm install)."
|
|
258
271
|
exit 1
|
|
259
272
|
fi
|
|
260
|
-
log_verbose "Found Ralph
|
|
273
|
+
log_verbose "Found internal mini Ralph runtime: $MINI_RALPH_CLI"
|
|
261
274
|
|
|
262
275
|
# Check for opencode
|
|
263
276
|
if ! command -v opencode &> /dev/null; then
|
|
@@ -454,7 +467,7 @@ parse_tasks() {
|
|
|
454
467
|
((line_number++)) || true
|
|
455
468
|
|
|
456
469
|
if [[ "$line" == "- [ ]"* ]]; then
|
|
457
|
-
local task_desc="${line#- [ ] }"
|
|
470
|
+
local task_desc="${line#- \[ \] }"
|
|
458
471
|
TASKS+=("$task_desc")
|
|
459
472
|
TASK_IDS+=("$line_number")
|
|
460
473
|
log_verbose "Found incomplete task (line $line_number): $task_desc"
|
|
@@ -483,6 +496,10 @@ check_tasks_modified() {
|
|
|
483
496
|
return 1
|
|
484
497
|
}
|
|
485
498
|
|
|
499
|
+
# DEPRECATED: The following functions are superseded by lib/mini-ralph/errors.js.
|
|
500
|
+
# Do not add new callers. These will be removed in a future cleanup.
|
|
501
|
+
# See: lib/mini-ralph/errors.js for the current implementation.
|
|
502
|
+
|
|
486
503
|
format_error_entry() {
|
|
487
504
|
local task_id="$1"
|
|
488
505
|
local task_description="$2"
|
|
@@ -692,7 +709,7 @@ sync_tasks_to_ralph() {
|
|
|
692
709
|
rm "$old_ralph_tasks_file"
|
|
693
710
|
fi
|
|
694
711
|
|
|
695
|
-
# Use symlink so
|
|
712
|
+
# Use a symlink so the loop runtime always works against the OpenSpec tasks file
|
|
696
713
|
# Ensure parent directory for ralph_tasks_file exists
|
|
697
714
|
mkdir -p "$(dirname "$ralph_tasks_file")"
|
|
698
715
|
|
|
@@ -744,6 +761,10 @@ Include full context from openspec artifacts in {{change_dir}}:
|
|
|
744
761
|
|
|
745
762
|
{{tasks}}
|
|
746
763
|
|
|
764
|
+
## Fresh Task Context
|
|
765
|
+
|
|
766
|
+
{{task_context}}
|
|
767
|
+
|
|
747
768
|
## Instructions
|
|
748
769
|
|
|
749
770
|
1. **Identify** current task:
|
|
@@ -751,15 +772,15 @@ Include full context from openspec artifacts in {{change_dir}}:
|
|
|
751
772
|
- If no task is in progress, pick the first task marked as [ ] (incomplete)
|
|
752
773
|
- Mark the task as [/] in the tasks file before starting work
|
|
753
774
|
|
|
754
|
-
2. **Implement** task
|
|
755
|
-
-
|
|
756
|
-
-
|
|
757
|
-
-
|
|
758
|
-
- The openspec-apply-change skill will implement changes and update task status automatically
|
|
775
|
+
2. **Implement** the current task directly:
|
|
776
|
+
- Read the relevant OpenSpec artifacts for context (proposal.md, design.md, specs)
|
|
777
|
+
- Make the smallest maintainable change that fully satisfies the current task
|
|
778
|
+
- Run the most relevant validation or tests for the task before claiming completion
|
|
759
779
|
|
|
760
780
|
3. **Complete** task:
|
|
761
781
|
- Verify that the implementation meets the requirements
|
|
762
782
|
- When the task is successfully completed, mark it as [x] in the tasks file
|
|
783
|
+
- Create a git commit using the required format below
|
|
763
784
|
- Output: `<promise>{{task_promise}}</promise>`
|
|
764
785
|
|
|
765
786
|
4. **Continue** to the next task:
|
|
@@ -769,7 +790,9 @@ Include full context from openspec artifacts in {{change_dir}}:
|
|
|
769
790
|
## Critical Rules
|
|
770
791
|
|
|
771
792
|
- Work on ONE task at a time from the task list
|
|
772
|
-
-
|
|
793
|
+
- Read the full tasks file every iteration; do not rely on memory from prior iterations
|
|
794
|
+
- Do not rely on editor-specific slash commands or local-only skills; follow this prompt directly
|
|
795
|
+
- Treat tasks.md as the only source of truth for task state
|
|
773
796
|
- ONLY output `<promise>{{task_promise}}</promise>` when the current task is complete and marked as [x]
|
|
774
797
|
- ONLY output `<promise>{{completion_promise}}</promise>` when ALL tasks are [x]
|
|
775
798
|
- Output promise tags DIRECTLY - do not quote them, explain them, or say you "will" output them
|
|
@@ -881,12 +904,12 @@ get_current_task_context() {
|
|
|
881
904
|
while IFS= read -r line; do
|
|
882
905
|
if [[ "$line" =~ ^-\ \[/\] ]]; then
|
|
883
906
|
# Found in-progress task - extract description
|
|
884
|
-
current_task_desc="${line#- [
|
|
907
|
+
current_task_desc="${line#- \[/\] }"
|
|
885
908
|
found_task=true
|
|
886
909
|
break
|
|
887
910
|
elif [[ "$line" =~ ^-\ \[\ \] ]] && [[ "$found_task" == "false" ]]; then
|
|
888
911
|
# Found incomplete task - extract description
|
|
889
|
-
current_task_desc="${line#- [ ] }"
|
|
912
|
+
current_task_desc="${line#- \[ \] }"
|
|
890
913
|
found_task=true
|
|
891
914
|
break
|
|
892
915
|
fi
|
|
@@ -948,14 +971,18 @@ execute_ralph_loop() {
|
|
|
948
971
|
local change_dir="$1"
|
|
949
972
|
local ralph_dir="$2"
|
|
950
973
|
local max_iterations="${3:-50}"
|
|
974
|
+
local no_commit="${4:-false}"
|
|
951
975
|
|
|
952
|
-
log_info "Starting Ralph
|
|
976
|
+
log_info "Starting internal mini Ralph loop..."
|
|
953
977
|
log_info "Max iterations: $max_iterations"
|
|
954
978
|
log_info "Change directory: $change_dir"
|
|
979
|
+
if [[ "$no_commit" == true ]]; then
|
|
980
|
+
log_info "Auto-commit disabled (--no-commit)"
|
|
981
|
+
fi
|
|
955
982
|
|
|
956
983
|
if ! resolve_ralph_command; then
|
|
957
|
-
log_error "
|
|
958
|
-
log_error "
|
|
984
|
+
log_error "Internal mini Ralph runtime not found: $MINI_RALPH_CLI"
|
|
985
|
+
log_error "Ensure node is installed and spec-and-loop dependencies are up to date (npm install)."
|
|
959
986
|
return 1
|
|
960
987
|
fi
|
|
961
988
|
|
|
@@ -973,51 +1000,132 @@ execute_ralph_loop() {
|
|
|
973
1000
|
prd_content=$(generate_prd "$change_dir")
|
|
974
1001
|
echo "$prd_content" > "$ralph_dir/PRD.md"
|
|
975
1002
|
|
|
976
|
-
# Get current task context for Ralph to use in commits
|
|
977
|
-
local task_context
|
|
978
|
-
task_context=$(get_current_task_context "$change_dir")
|
|
979
|
-
|
|
980
|
-
# Create context injection file for Ralph
|
|
981
|
-
local context_file="$ralph_dir/.context_injection"
|
|
982
|
-
if [[ -n "$task_context" ]]; then
|
|
983
|
-
log_verbose "Writing task context injection..."
|
|
984
|
-
echo "$task_context" > "$context_file"
|
|
985
|
-
fi
|
|
986
|
-
|
|
987
|
-
# Restore Ralph state from tasks.md before running
|
|
988
|
-
restore_ralph_state_from_tasks "$change_dir/tasks.md"
|
|
989
|
-
|
|
990
|
-
# Initialize context injections file for Ralph to read context
|
|
991
|
-
initialize_context_injections "$ralph_dir"
|
|
992
|
-
|
|
993
1003
|
# Output files
|
|
994
1004
|
local stdout_log="$output_dir/ralph-stdout.log"
|
|
995
1005
|
local stderr_log="$output_dir/ralph-stderr.log"
|
|
996
1006
|
|
|
997
|
-
log_info "
|
|
1007
|
+
log_info "Invoking internal mini Ralph runtime..."
|
|
998
1008
|
log_info "Capturing output to: $output_dir"
|
|
999
1009
|
|
|
1000
|
-
#
|
|
1010
|
+
# Build the mini-ralph-cli arguments
|
|
1011
|
+
local mini_ralph_args=(
|
|
1012
|
+
"--prompt-file" "$ralph_dir/PRD.md"
|
|
1013
|
+
"--prompt-template" "$template_file"
|
|
1014
|
+
"--ralph-dir" "$ralph_dir"
|
|
1015
|
+
"--tasks-file" "$change_dir/tasks.md"
|
|
1016
|
+
"--tasks"
|
|
1017
|
+
"--max-iterations" "$max_iterations"
|
|
1018
|
+
)
|
|
1019
|
+
|
|
1020
|
+
if [[ "$no_commit" == true ]]; then
|
|
1021
|
+
mini_ralph_args+=("--no-commit")
|
|
1022
|
+
fi
|
|
1023
|
+
|
|
1024
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
1025
|
+
mini_ralph_args+=("--verbose")
|
|
1026
|
+
fi
|
|
1027
|
+
|
|
1028
|
+
# Run the internal mini Ralph CLI and capture output
|
|
1001
1029
|
{
|
|
1002
|
-
"${
|
|
1003
|
-
--agent opencode \
|
|
1004
|
-
--tasks \
|
|
1005
|
-
--max-iterations "$max_iterations" \
|
|
1006
|
-
--prompt-template "$template_file" \
|
|
1007
|
-
--verbose-tools
|
|
1030
|
+
node "$MINI_RALPH_CLI" "${mini_ralph_args[@]}"
|
|
1008
1031
|
} > >(tee "$stdout_log") 2> >(tee "$stderr_log")
|
|
1009
1032
|
|
|
1010
1033
|
return $?
|
|
1011
1034
|
}
|
|
1012
1035
|
|
|
1013
1036
|
|
|
1037
|
+
# ---------------------------------------------------------------------------
|
|
1038
|
+
# Observability and control commands
|
|
1039
|
+
#
|
|
1040
|
+
# These commands delegate to the internal mini-ralph-cli.js for status,
|
|
1041
|
+
# context management, and other loop controls without running the full loop.
|
|
1042
|
+
# ---------------------------------------------------------------------------
|
|
1043
|
+
|
|
1044
|
+
run_observability_command() {
|
|
1045
|
+
local change_name="$1"
|
|
1046
|
+
local command="$2"
|
|
1047
|
+
local arg="$3"
|
|
1048
|
+
|
|
1049
|
+
if [[ ! -f "$MINI_RALPH_CLI" ]]; then
|
|
1050
|
+
log_error "Internal mini-ralph-cli.js not found: $MINI_RALPH_CLI"
|
|
1051
|
+
exit 1
|
|
1052
|
+
fi
|
|
1053
|
+
|
|
1054
|
+
if [[ ! -x "$(command -v node)" ]]; then
|
|
1055
|
+
log_error "node is required but not found in PATH."
|
|
1056
|
+
exit 1
|
|
1057
|
+
fi
|
|
1058
|
+
|
|
1059
|
+
local change_dir="openspec/changes/$change_name"
|
|
1060
|
+
local ralph_dir="$change_dir/.ralph"
|
|
1061
|
+
|
|
1062
|
+
case "$command" in
|
|
1063
|
+
status)
|
|
1064
|
+
local tasks_file="$change_dir/tasks.md"
|
|
1065
|
+
local tasks_arg=""
|
|
1066
|
+
if [[ -f "$tasks_file" ]]; then
|
|
1067
|
+
tasks_arg="--tasks-file $tasks_file"
|
|
1068
|
+
fi
|
|
1069
|
+
# shellcheck disable=SC2086
|
|
1070
|
+
node "$MINI_RALPH_CLI" --ralph-dir "$ralph_dir" --status $tasks_arg
|
|
1071
|
+
;;
|
|
1072
|
+
add-context)
|
|
1073
|
+
node "$MINI_RALPH_CLI" --ralph-dir "$ralph_dir" --add-context "$arg"
|
|
1074
|
+
;;
|
|
1075
|
+
clear-context)
|
|
1076
|
+
node "$MINI_RALPH_CLI" --ralph-dir "$ralph_dir" --clear-context
|
|
1077
|
+
;;
|
|
1078
|
+
*)
|
|
1079
|
+
log_error "Unknown observability command: $command"
|
|
1080
|
+
exit 1
|
|
1081
|
+
;;
|
|
1082
|
+
esac
|
|
1083
|
+
}
|
|
1014
1084
|
|
|
1015
1085
|
main() {
|
|
1086
|
+
set -e
|
|
1016
1087
|
parse_arguments "$@"
|
|
1017
1088
|
|
|
1018
1089
|
log_verbose "Starting ralph-run v$VERSION"
|
|
1019
1090
|
log_verbose "Change name: ${CHANGE_NAME:-<auto-detect>}"
|
|
1020
|
-
|
|
1091
|
+
|
|
1092
|
+
# Resolve change name first for observability commands that need it
|
|
1093
|
+
if [[ -z "$CHANGE_NAME" ]] && ( [[ "$SHOW_STATUS" == true ]] || [[ -n "$ADD_CONTEXT" ]] || [[ "$CLEAR_CONTEXT" == true ]] ); then
|
|
1094
|
+
validate_git_repository
|
|
1095
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1096
|
+
log_verbose "Auto-detected change for observability: $CHANGE_NAME"
|
|
1097
|
+
fi
|
|
1098
|
+
|
|
1099
|
+
# Handle observability commands (status, add-context, clear-context)
|
|
1100
|
+
# These exit early without running the full loop.
|
|
1101
|
+
if [[ "$SHOW_STATUS" == true ]]; then
|
|
1102
|
+
if [[ -z "$CHANGE_NAME" ]]; then
|
|
1103
|
+
validate_git_repository
|
|
1104
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1105
|
+
fi
|
|
1106
|
+
run_observability_command "$CHANGE_NAME" "status"
|
|
1107
|
+
exit $?
|
|
1108
|
+
fi
|
|
1109
|
+
|
|
1110
|
+
if [[ -n "$ADD_CONTEXT" ]]; then
|
|
1111
|
+
if [[ -z "$CHANGE_NAME" ]]; then
|
|
1112
|
+
validate_git_repository
|
|
1113
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1114
|
+
fi
|
|
1115
|
+
run_observability_command "$CHANGE_NAME" "add-context" "$ADD_CONTEXT"
|
|
1116
|
+
exit $?
|
|
1117
|
+
fi
|
|
1118
|
+
|
|
1119
|
+
if [[ "$CLEAR_CONTEXT" == true ]]; then
|
|
1120
|
+
if [[ -z "$CHANGE_NAME" ]]; then
|
|
1121
|
+
validate_git_repository
|
|
1122
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1123
|
+
fi
|
|
1124
|
+
run_observability_command "$CHANGE_NAME" "clear-context"
|
|
1125
|
+
exit $?
|
|
1126
|
+
fi
|
|
1127
|
+
|
|
1128
|
+
# Normal loop execution path
|
|
1021
1129
|
validate_git_repository
|
|
1022
1130
|
validate_dependencies
|
|
1023
1131
|
|
|
@@ -1045,9 +1153,11 @@ main() {
|
|
|
1045
1153
|
|
|
1046
1154
|
local max_iterations="${MAX_ITERATIONS:-50}"
|
|
1047
1155
|
|
|
1048
|
-
execute_ralph_loop "$change_dir" "$ralph_dir" "$max_iterations"
|
|
1156
|
+
execute_ralph_loop "$change_dir" "$ralph_dir" "$max_iterations" "$NO_COMMIT"
|
|
1049
1157
|
|
|
1050
1158
|
log_info "ralph-run.sh initialized successfully"
|
|
1051
1159
|
}
|
|
1052
1160
|
|
|
1053
|
-
|
|
1161
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
1162
|
+
main "$@"
|
|
1163
|
+
fi
|
package/scripts/setup.js
CHANGED
|
@@ -4,40 +4,48 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { execSync } = require('child_process');
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
function runSetup() {
|
|
8
|
+
console.log('Setting up spec-and-loop...');
|
|
8
9
|
|
|
9
|
-
// Get the installation directory
|
|
10
|
-
const installDir = __dirname;
|
|
11
|
-
const ralphRunScript = path.join(installDir, 'ralph-run.sh');
|
|
10
|
+
// Get the installation directory
|
|
11
|
+
const installDir = __dirname;
|
|
12
|
+
const ralphRunScript = path.join(installDir, 'ralph-run.sh');
|
|
12
13
|
|
|
13
|
-
console.log(`Installation directory: ${installDir}`);
|
|
14
|
+
console.log(`Installation directory: ${installDir}`);
|
|
14
15
|
|
|
15
|
-
// Make ralph-run.sh executable
|
|
16
|
-
if (fs.existsSync(ralphRunScript)) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
// Make ralph-run.sh executable
|
|
17
|
+
if (fs.existsSync(ralphRunScript)) {
|
|
18
|
+
try {
|
|
19
|
+
execSync(`chmod +x "${ralphRunScript}"`, { stdio: 'inherit' });
|
|
20
|
+
console.log('✓ Made ralph-run.sh executable');
|
|
21
|
+
} catch (err) {
|
|
22
|
+
console.warn(`Could not make ralph-run.sh executable: ${err.message}`);
|
|
23
|
+
}
|
|
24
|
+
} else {
|
|
25
|
+
console.error(`Error: ralph-run.sh not found at ${ralphRunScript}`);
|
|
26
|
+
process.exit(1);
|
|
22
27
|
}
|
|
23
|
-
|
|
24
|
-
console.
|
|
25
|
-
|
|
28
|
+
|
|
29
|
+
console.log('');
|
|
30
|
+
console.log('spec-and-loop setup complete!');
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log('Usage:');
|
|
33
|
+
console.log(' cd /path/to/your/project');
|
|
34
|
+
console.log(' openspec init # Initialize OpenSpec');
|
|
35
|
+
console.log(' openspec new <name> # Create a new change');
|
|
36
|
+
console.log(' openspec ff <name> # Fast-forward artifacts');
|
|
37
|
+
console.log(' ralph-run --change <name> # Run ralph loop');
|
|
38
|
+
console.log(' ralph-run # Auto-detect change');
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log('Prerequisites:');
|
|
41
|
+
console.log(' - openspec CLI: npm install -g openspec');
|
|
42
|
+
console.log(' - opencode CLI: npm install -g opencode-ai');
|
|
43
|
+
console.log(' - jq CLI: apt install jq / brew install jq');
|
|
44
|
+
console.log(' - git: git init');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (require.main === module) {
|
|
48
|
+
runSetup();
|
|
26
49
|
}
|
|
27
50
|
|
|
28
|
-
|
|
29
|
-
console.log('spec-and-loop setup complete!');
|
|
30
|
-
console.log('');
|
|
31
|
-
console.log('Usage:');
|
|
32
|
-
console.log(' cd /path/to/your/project');
|
|
33
|
-
console.log(' openspec init # Initialize OpenSpec');
|
|
34
|
-
console.log(' openspec new <name> # Create a new change');
|
|
35
|
-
console.log(' openspec ff <name> # Fast-forward artifacts');
|
|
36
|
-
console.log(' ralph-run --change <name> # Run ralph loop');
|
|
37
|
-
console.log(' ralph-run # Auto-detect change');
|
|
38
|
-
console.log('');
|
|
39
|
-
console.log('Prerequisites:');
|
|
40
|
-
console.log(' - openspec CLI: npm install -g openspec');
|
|
41
|
-
console.log(' - opencode CLI: npm install -g opencode-ai');
|
|
42
|
-
console.log(' - jq CLI: apt install jq / brew install jq');
|
|
43
|
-
console.log(' - git: git init');
|
|
51
|
+
module.exports = { runSetup };
|