codex-ralph 0.3.1 → 0.4.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 +22 -2
- package/agent/ralph-loop.sh +46 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Minimal Ralph Wiggum Loop runner that feeds a sprint requirement into Codex, one
|
|
|
5
5
|
## Quick start
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx codex-ralph
|
|
8
|
+
npx codex-ralph path/to/Sprint_0001.md --max-iterations=1
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Telegram progress notifications
|
|
@@ -17,7 +17,27 @@ CODEX_RALPH_TG_KEY=123456:bot-token
|
|
|
17
17
|
CODEX_RALPH_TG_CHAT=123456789
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Provide these as environment variables (e.g., when invoking `npx`). Each session generates a UUID and includes it in
|
|
20
|
+
Provide these as environment variables (e.g., when invoking `npx`). Each session generates a UUID and includes it in progress messages.
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
npx codex-ralph path/to/Sprint_0001.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Optional flags:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
--max-iterations=10
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Message format:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
🧭 ~<session-uuid>~
|
|
38
|
+
📌 <current requirement title>
|
|
39
|
+
🎯 <current index> of <total requirements>
|
|
40
|
+
```
|
|
21
41
|
|
|
22
42
|
## Sprint format (Markdown)
|
|
23
43
|
|
package/agent/ralph-loop.sh
CHANGED
|
@@ -9,7 +9,7 @@ PY
|
|
|
9
9
|
)"
|
|
10
10
|
ROOT_DIR="$(cd "$(dirname "$SCRIPT_PATH")/.." && pwd)"
|
|
11
11
|
SPRINT_FILE=""
|
|
12
|
-
MAX_ITERATIONS=
|
|
12
|
+
MAX_ITERATIONS=10
|
|
13
13
|
NOTES_FILE=""
|
|
14
14
|
SESSION_UUID=""
|
|
15
15
|
|
|
@@ -40,11 +40,11 @@ send_telegram() {
|
|
|
40
40
|
|
|
41
41
|
usage() {
|
|
42
42
|
cat <<USAGE
|
|
43
|
-
Usage: ralph-loop
|
|
43
|
+
Usage: ralph-loop SPRINT_PATH [--max-iterations=N]
|
|
44
44
|
|
|
45
45
|
Options:
|
|
46
|
-
|
|
47
|
-
--max-iterations=N Stop after N iterations (0 = no limit).
|
|
46
|
+
SPRINT_PATH Path to the sprint markdown file (required).
|
|
47
|
+
--max-iterations=N Stop after N iterations (0 = no limit, default 10).
|
|
48
48
|
-h, --help Show this help.
|
|
49
49
|
USAGE
|
|
50
50
|
}
|
|
@@ -53,9 +53,6 @@ session_uuid >/dev/null
|
|
|
53
53
|
|
|
54
54
|
for arg in "$@"; do
|
|
55
55
|
case "$arg" in
|
|
56
|
-
--sprint=*)
|
|
57
|
-
SPRINT_FILE="${arg#*=}"
|
|
58
|
-
;;
|
|
59
56
|
--max-iterations=*)
|
|
60
57
|
MAX_ITERATIONS="${arg#*=}"
|
|
61
58
|
;;
|
|
@@ -63,11 +60,20 @@ for arg in "$@"; do
|
|
|
63
60
|
usage
|
|
64
61
|
exit 0
|
|
65
62
|
;;
|
|
66
|
-
|
|
63
|
+
-*)
|
|
67
64
|
echo "Unknown argument: $arg" >&2
|
|
68
65
|
usage >&2
|
|
69
66
|
exit 1
|
|
70
67
|
;;
|
|
68
|
+
*)
|
|
69
|
+
if [[ -z "$SPRINT_FILE" ]]; then
|
|
70
|
+
SPRINT_FILE="$arg"
|
|
71
|
+
else
|
|
72
|
+
echo "Unexpected argument: $arg" >&2
|
|
73
|
+
usage >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
;;
|
|
71
77
|
esac
|
|
72
78
|
done
|
|
73
79
|
|
|
@@ -115,6 +121,33 @@ print(sum(1 for m in items if m.strip() != "x"))
|
|
|
115
121
|
PY
|
|
116
122
|
}
|
|
117
123
|
|
|
124
|
+
total_count() {
|
|
125
|
+
python3 - <<PY
|
|
126
|
+
from pathlib import Path
|
|
127
|
+
import re
|
|
128
|
+
|
|
129
|
+
path = Path("$SPRINT_FILE")
|
|
130
|
+
text = path.read_text(encoding="utf-8")
|
|
131
|
+
items = re.findall(r"^## \[( |x|X)\] ", text, flags=re.M)
|
|
132
|
+
print(len(items))
|
|
133
|
+
PY
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
current_index() {
|
|
137
|
+
python3 - <<PY
|
|
138
|
+
from pathlib import Path
|
|
139
|
+
import re
|
|
140
|
+
|
|
141
|
+
path = Path("$SPRINT_FILE")
|
|
142
|
+
text = path.read_text(encoding="utf-8")
|
|
143
|
+
items = re.findall(r"^## \[( |x|X)\] ", text, flags=re.M)
|
|
144
|
+
remaining = sum(1 for m in items if m.strip() != "x")
|
|
145
|
+
total = len(items)
|
|
146
|
+
current = total - remaining + 1 if remaining > 0 else total
|
|
147
|
+
print(current)
|
|
148
|
+
PY
|
|
149
|
+
}
|
|
150
|
+
|
|
118
151
|
next_description() {
|
|
119
152
|
python3 - <<PY
|
|
120
153
|
from pathlib import Path
|
|
@@ -161,7 +194,8 @@ iteration=1
|
|
|
161
194
|
while true; do
|
|
162
195
|
remaining="$(remaining_count)"
|
|
163
196
|
if [[ "$remaining" == "0" ]]; then
|
|
164
|
-
|
|
197
|
+
total="$(total_count)"
|
|
198
|
+
send_telegram "🧭 ~${SESSION_UUID}~"$'\n'"✅ All requirements completed"$'\n'"🎯 ${total} of ${total}"
|
|
165
199
|
echo "All sprint requirements complete."
|
|
166
200
|
echo "<promise>DONE</promise>"
|
|
167
201
|
exit 0
|
|
@@ -173,7 +207,9 @@ while true; do
|
|
|
173
207
|
fi
|
|
174
208
|
|
|
175
209
|
desc="$(next_description)"
|
|
176
|
-
|
|
210
|
+
total="$(total_count)"
|
|
211
|
+
current="$(current_index)"
|
|
212
|
+
send_telegram "🧭 ~${SESSION_UUID}~"$'\n'"📌 ${desc}"$'\n'"🎯 ${current} of ${total}"
|
|
177
213
|
echo "Iteration $iteration - next requirement: $desc"
|
|
178
214
|
|
|
179
215
|
prompt_tmp="$(mktemp)"
|