spec-and-loop 1.0.8 → 2.0.0-rc.1
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 +38 -27
- package/README.md +99 -152
- package/lib/mini-ralph/context.js +99 -0
- package/lib/mini-ralph/history.js +99 -0
- package/lib/mini-ralph/index.js +91 -0
- package/lib/mini-ralph/invoker.js +205 -0
- package/lib/mini-ralph/prompt.js +116 -0
- package/lib/mini-ralph/runner.js +415 -0
- package/lib/mini-ralph/state.js +93 -0
- package/lib/mini-ralph/status.js +211 -0
- package/lib/mini-ralph/tasks.js +209 -0
- package/package.json +3 -4
- package/scripts/mini-ralph-cli.js +226 -0
- package/scripts/ralph-run.sh +178 -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"
|
|
@@ -692,7 +705,7 @@ sync_tasks_to_ralph() {
|
|
|
692
705
|
rm "$old_ralph_tasks_file"
|
|
693
706
|
fi
|
|
694
707
|
|
|
695
|
-
# Use symlink so
|
|
708
|
+
# Use a symlink so the loop runtime always works against the OpenSpec tasks file
|
|
696
709
|
# Ensure parent directory for ralph_tasks_file exists
|
|
697
710
|
mkdir -p "$(dirname "$ralph_tasks_file")"
|
|
698
711
|
|
|
@@ -744,6 +757,10 @@ Include full context from openspec artifacts in {{change_dir}}:
|
|
|
744
757
|
|
|
745
758
|
{{tasks}}
|
|
746
759
|
|
|
760
|
+
## Fresh Task Context
|
|
761
|
+
|
|
762
|
+
{{task_context}}
|
|
763
|
+
|
|
747
764
|
## Instructions
|
|
748
765
|
|
|
749
766
|
1. **Identify** current task:
|
|
@@ -751,15 +768,15 @@ Include full context from openspec artifacts in {{change_dir}}:
|
|
|
751
768
|
- If no task is in progress, pick the first task marked as [ ] (incomplete)
|
|
752
769
|
- Mark the task as [/] in the tasks file before starting work
|
|
753
770
|
|
|
754
|
-
2. **Implement** task
|
|
755
|
-
-
|
|
756
|
-
-
|
|
757
|
-
-
|
|
758
|
-
- The openspec-apply-change skill will implement changes and update task status automatically
|
|
771
|
+
2. **Implement** the current task directly:
|
|
772
|
+
- Read the relevant OpenSpec artifacts for context (proposal.md, design.md, specs)
|
|
773
|
+
- Make the smallest maintainable change that fully satisfies the current task
|
|
774
|
+
- Run the most relevant validation or tests for the task before claiming completion
|
|
759
775
|
|
|
760
776
|
3. **Complete** task:
|
|
761
777
|
- Verify that the implementation meets the requirements
|
|
762
778
|
- When the task is successfully completed, mark it as [x] in the tasks file
|
|
779
|
+
- Create a git commit using the required format below
|
|
763
780
|
- Output: `<promise>{{task_promise}}</promise>`
|
|
764
781
|
|
|
765
782
|
4. **Continue** to the next task:
|
|
@@ -769,7 +786,9 @@ Include full context from openspec artifacts in {{change_dir}}:
|
|
|
769
786
|
## Critical Rules
|
|
770
787
|
|
|
771
788
|
- Work on ONE task at a time from the task list
|
|
772
|
-
-
|
|
789
|
+
- Read the full tasks file every iteration; do not rely on memory from prior iterations
|
|
790
|
+
- Do not rely on editor-specific slash commands or local-only skills; follow this prompt directly
|
|
791
|
+
- Treat tasks.md as the only source of truth for task state
|
|
773
792
|
- ONLY output `<promise>{{task_promise}}</promise>` when the current task is complete and marked as [x]
|
|
774
793
|
- ONLY output `<promise>{{completion_promise}}</promise>` when ALL tasks are [x]
|
|
775
794
|
- Output promise tags DIRECTLY - do not quote them, explain them, or say you "will" output them
|
|
@@ -881,12 +900,12 @@ get_current_task_context() {
|
|
|
881
900
|
while IFS= read -r line; do
|
|
882
901
|
if [[ "$line" =~ ^-\ \[/\] ]]; then
|
|
883
902
|
# Found in-progress task - extract description
|
|
884
|
-
current_task_desc="${line#- [
|
|
903
|
+
current_task_desc="${line#- \[/\] }"
|
|
885
904
|
found_task=true
|
|
886
905
|
break
|
|
887
906
|
elif [[ "$line" =~ ^-\ \[\ \] ]] && [[ "$found_task" == "false" ]]; then
|
|
888
907
|
# Found incomplete task - extract description
|
|
889
|
-
current_task_desc="${line#- [ ] }"
|
|
908
|
+
current_task_desc="${line#- \[ \] }"
|
|
890
909
|
found_task=true
|
|
891
910
|
break
|
|
892
911
|
fi
|
|
@@ -948,14 +967,18 @@ execute_ralph_loop() {
|
|
|
948
967
|
local change_dir="$1"
|
|
949
968
|
local ralph_dir="$2"
|
|
950
969
|
local max_iterations="${3:-50}"
|
|
970
|
+
local no_commit="${4:-false}"
|
|
951
971
|
|
|
952
|
-
log_info "Starting Ralph
|
|
972
|
+
log_info "Starting internal mini Ralph loop..."
|
|
953
973
|
log_info "Max iterations: $max_iterations"
|
|
954
974
|
log_info "Change directory: $change_dir"
|
|
975
|
+
if [[ "$no_commit" == true ]]; then
|
|
976
|
+
log_info "Auto-commit disabled (--no-commit)"
|
|
977
|
+
fi
|
|
955
978
|
|
|
956
979
|
if ! resolve_ralph_command; then
|
|
957
|
-
log_error "
|
|
958
|
-
log_error "
|
|
980
|
+
log_error "Internal mini Ralph runtime not found: $MINI_RALPH_CLI"
|
|
981
|
+
log_error "Ensure node is installed and spec-and-loop dependencies are up to date (npm install)."
|
|
959
982
|
return 1
|
|
960
983
|
fi
|
|
961
984
|
|
|
@@ -973,51 +996,132 @@ execute_ralph_loop() {
|
|
|
973
996
|
prd_content=$(generate_prd "$change_dir")
|
|
974
997
|
echo "$prd_content" > "$ralph_dir/PRD.md"
|
|
975
998
|
|
|
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
999
|
# Output files
|
|
994
1000
|
local stdout_log="$output_dir/ralph-stdout.log"
|
|
995
1001
|
local stderr_log="$output_dir/ralph-stderr.log"
|
|
996
1002
|
|
|
997
|
-
log_info "
|
|
1003
|
+
log_info "Invoking internal mini Ralph runtime..."
|
|
998
1004
|
log_info "Capturing output to: $output_dir"
|
|
999
1005
|
|
|
1000
|
-
#
|
|
1006
|
+
# Build the mini-ralph-cli arguments
|
|
1007
|
+
local mini_ralph_args=(
|
|
1008
|
+
"--prompt-file" "$ralph_dir/PRD.md"
|
|
1009
|
+
"--prompt-template" "$template_file"
|
|
1010
|
+
"--ralph-dir" "$ralph_dir"
|
|
1011
|
+
"--tasks-file" "$change_dir/tasks.md"
|
|
1012
|
+
"--tasks"
|
|
1013
|
+
"--max-iterations" "$max_iterations"
|
|
1014
|
+
)
|
|
1015
|
+
|
|
1016
|
+
if [[ "$no_commit" == true ]]; then
|
|
1017
|
+
mini_ralph_args+=("--no-commit")
|
|
1018
|
+
fi
|
|
1019
|
+
|
|
1020
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
1021
|
+
mini_ralph_args+=("--verbose")
|
|
1022
|
+
fi
|
|
1023
|
+
|
|
1024
|
+
# Run the internal mini Ralph CLI and capture output
|
|
1001
1025
|
{
|
|
1002
|
-
"${
|
|
1003
|
-
--agent opencode \
|
|
1004
|
-
--tasks \
|
|
1005
|
-
--max-iterations "$max_iterations" \
|
|
1006
|
-
--prompt-template "$template_file" \
|
|
1007
|
-
--verbose-tools
|
|
1026
|
+
node "$MINI_RALPH_CLI" "${mini_ralph_args[@]}"
|
|
1008
1027
|
} > >(tee "$stdout_log") 2> >(tee "$stderr_log")
|
|
1009
1028
|
|
|
1010
1029
|
return $?
|
|
1011
1030
|
}
|
|
1012
1031
|
|
|
1013
1032
|
|
|
1033
|
+
# ---------------------------------------------------------------------------
|
|
1034
|
+
# Observability and control commands
|
|
1035
|
+
#
|
|
1036
|
+
# These commands delegate to the internal mini-ralph-cli.js for status,
|
|
1037
|
+
# context management, and other loop controls without running the full loop.
|
|
1038
|
+
# ---------------------------------------------------------------------------
|
|
1039
|
+
|
|
1040
|
+
run_observability_command() {
|
|
1041
|
+
local change_name="$1"
|
|
1042
|
+
local command="$2"
|
|
1043
|
+
local arg="$3"
|
|
1044
|
+
|
|
1045
|
+
if [[ ! -f "$MINI_RALPH_CLI" ]]; then
|
|
1046
|
+
log_error "Internal mini-ralph-cli.js not found: $MINI_RALPH_CLI"
|
|
1047
|
+
exit 1
|
|
1048
|
+
fi
|
|
1049
|
+
|
|
1050
|
+
if [[ ! -x "$(command -v node)" ]]; then
|
|
1051
|
+
log_error "node is required but not found in PATH."
|
|
1052
|
+
exit 1
|
|
1053
|
+
fi
|
|
1054
|
+
|
|
1055
|
+
local change_dir="openspec/changes/$change_name"
|
|
1056
|
+
local ralph_dir="$change_dir/.ralph"
|
|
1057
|
+
|
|
1058
|
+
case "$command" in
|
|
1059
|
+
status)
|
|
1060
|
+
local tasks_file="$change_dir/tasks.md"
|
|
1061
|
+
local tasks_arg=""
|
|
1062
|
+
if [[ -f "$tasks_file" ]]; then
|
|
1063
|
+
tasks_arg="--tasks-file $tasks_file"
|
|
1064
|
+
fi
|
|
1065
|
+
# shellcheck disable=SC2086
|
|
1066
|
+
node "$MINI_RALPH_CLI" --ralph-dir "$ralph_dir" --status $tasks_arg
|
|
1067
|
+
;;
|
|
1068
|
+
add-context)
|
|
1069
|
+
node "$MINI_RALPH_CLI" --ralph-dir "$ralph_dir" --add-context "$arg"
|
|
1070
|
+
;;
|
|
1071
|
+
clear-context)
|
|
1072
|
+
node "$MINI_RALPH_CLI" --ralph-dir "$ralph_dir" --clear-context
|
|
1073
|
+
;;
|
|
1074
|
+
*)
|
|
1075
|
+
log_error "Unknown observability command: $command"
|
|
1076
|
+
exit 1
|
|
1077
|
+
;;
|
|
1078
|
+
esac
|
|
1079
|
+
}
|
|
1014
1080
|
|
|
1015
1081
|
main() {
|
|
1082
|
+
set -e
|
|
1016
1083
|
parse_arguments "$@"
|
|
1017
1084
|
|
|
1018
1085
|
log_verbose "Starting ralph-run v$VERSION"
|
|
1019
1086
|
log_verbose "Change name: ${CHANGE_NAME:-<auto-detect>}"
|
|
1020
|
-
|
|
1087
|
+
|
|
1088
|
+
# Resolve change name first for observability commands that need it
|
|
1089
|
+
if [[ -z "$CHANGE_NAME" ]] && ( [[ "$SHOW_STATUS" == true ]] || [[ -n "$ADD_CONTEXT" ]] || [[ "$CLEAR_CONTEXT" == true ]] ); then
|
|
1090
|
+
validate_git_repository
|
|
1091
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1092
|
+
log_verbose "Auto-detected change for observability: $CHANGE_NAME"
|
|
1093
|
+
fi
|
|
1094
|
+
|
|
1095
|
+
# Handle observability commands (status, add-context, clear-context)
|
|
1096
|
+
# These exit early without running the full loop.
|
|
1097
|
+
if [[ "$SHOW_STATUS" == true ]]; then
|
|
1098
|
+
if [[ -z "$CHANGE_NAME" ]]; then
|
|
1099
|
+
validate_git_repository
|
|
1100
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1101
|
+
fi
|
|
1102
|
+
run_observability_command "$CHANGE_NAME" "status"
|
|
1103
|
+
exit $?
|
|
1104
|
+
fi
|
|
1105
|
+
|
|
1106
|
+
if [[ -n "$ADD_CONTEXT" ]]; then
|
|
1107
|
+
if [[ -z "$CHANGE_NAME" ]]; then
|
|
1108
|
+
validate_git_repository
|
|
1109
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1110
|
+
fi
|
|
1111
|
+
run_observability_command "$CHANGE_NAME" "add-context" "$ADD_CONTEXT"
|
|
1112
|
+
exit $?
|
|
1113
|
+
fi
|
|
1114
|
+
|
|
1115
|
+
if [[ "$CLEAR_CONTEXT" == true ]]; then
|
|
1116
|
+
if [[ -z "$CHANGE_NAME" ]]; then
|
|
1117
|
+
validate_git_repository
|
|
1118
|
+
CHANGE_NAME=$(auto_detect_change)
|
|
1119
|
+
fi
|
|
1120
|
+
run_observability_command "$CHANGE_NAME" "clear-context"
|
|
1121
|
+
exit $?
|
|
1122
|
+
fi
|
|
1123
|
+
|
|
1124
|
+
# Normal loop execution path
|
|
1021
1125
|
validate_git_repository
|
|
1022
1126
|
validate_dependencies
|
|
1023
1127
|
|
|
@@ -1045,9 +1149,11 @@ main() {
|
|
|
1045
1149
|
|
|
1046
1150
|
local max_iterations="${MAX_ITERATIONS:-50}"
|
|
1047
1151
|
|
|
1048
|
-
execute_ralph_loop "$change_dir" "$ralph_dir" "$max_iterations"
|
|
1152
|
+
execute_ralph_loop "$change_dir" "$ralph_dir" "$max_iterations" "$NO_COMMIT"
|
|
1049
1153
|
|
|
1050
1154
|
log_info "ralph-run.sh initialized successfully"
|
|
1051
1155
|
}
|
|
1052
1156
|
|
|
1053
|
-
|
|
1157
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
1158
|
+
main "$@"
|
|
1159
|
+
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 };
|