mobius-loop 1.0.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/.claude/commands/linear/define.md +22 -0
- package/.claude/commands/linear/execute.md +22 -0
- package/.claude/commands/linear/refine.md +22 -0
- package/.claude/commands/linear/verify.md +22 -0
- package/.claude/skills/define-linear-issue/SKILL.md +386 -0
- package/.claude/skills/execute-linear-issue/SKILL.md +629 -0
- package/.claude/skills/refine-linear-issue/SKILL.md +379 -0
- package/.claude/skills/verify-linear-issue/SKILL.md +663 -0
- package/AGENTS.md +70 -0
- package/LICENSE +21 -0
- package/README.md +457 -0
- package/dist/bin/mobius.d.ts +3 -0
- package/dist/bin/mobius.d.ts.map +1 -0
- package/dist/bin/mobius.js +75 -0
- package/dist/bin/mobius.js.map +1 -0
- package/dist/commands/config.d.ts +6 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +88 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +86 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/run.d.ts +10 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +62 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/setup.d.ts +2 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +131 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/lib/checks/cclean.d.ts +3 -0
- package/dist/lib/checks/cclean.d.ts.map +1 -0
- package/dist/lib/checks/cclean.js +23 -0
- package/dist/lib/checks/cclean.js.map +1 -0
- package/dist/lib/checks/claude.d.ts +3 -0
- package/dist/lib/checks/claude.d.ts.map +1 -0
- package/dist/lib/checks/claude.js +38 -0
- package/dist/lib/checks/claude.js.map +1 -0
- package/dist/lib/checks/config.d.ts +4 -0
- package/dist/lib/checks/config.d.ts.map +1 -0
- package/dist/lib/checks/config.js +45 -0
- package/dist/lib/checks/config.js.map +1 -0
- package/dist/lib/checks/docker.d.ts +3 -0
- package/dist/lib/checks/docker.d.ts.map +1 -0
- package/dist/lib/checks/docker.js +46 -0
- package/dist/lib/checks/docker.js.map +1 -0
- package/dist/lib/checks/linear-mcp.d.ts +3 -0
- package/dist/lib/checks/linear-mcp.d.ts.map +1 -0
- package/dist/lib/checks/linear-mcp.js +46 -0
- package/dist/lib/checks/linear-mcp.js.map +1 -0
- package/dist/lib/checks/path.d.ts +5 -0
- package/dist/lib/checks/path.d.ts.map +1 -0
- package/dist/lib/checks/path.js +49 -0
- package/dist/lib/checks/path.js.map +1 -0
- package/dist/lib/config.d.ts +37 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +145 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/paths.d.ts +39 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +117 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/mobius.config.yaml +38 -0
- package/package.json +56 -0
- package/scripts/mobius.sh +394 -0
- package/scripts/render-diagrams.sh +38 -0
- package/scripts/render-terminal.sh +49 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Mobius - AI-Powered Development Workflow Tool
|
|
3
|
+
#
|
|
4
|
+
# Executes sub-tasks of an issue in a loop using Claude skills.
|
|
5
|
+
# Supports multiple planning backends (Linear, Jira, etc.)
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# mobius VER-159 # Execute sub-tasks (uses default backend)
|
|
9
|
+
# mobius VER-159 10 # Max 10 iterations
|
|
10
|
+
# mobius VER-159 --local # Run locally (bypass sandbox)
|
|
11
|
+
# mobius VER-159 --backend=jira # Use Jira backend
|
|
12
|
+
#
|
|
13
|
+
# Configuration:
|
|
14
|
+
# ~/.config/mobius/config.yaml # User config (takes precedence)
|
|
15
|
+
# Environment variables # Override config file settings
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
21
|
+
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/mobius"
|
|
22
|
+
# Support config path from npm wrapper (MOBIUS_CONFIG_FILE env var)
|
|
23
|
+
CONFIG_FILE="${MOBIUS_CONFIG_FILE:-$CONFIG_DIR/config.yaml}"
|
|
24
|
+
DEFAULT_CONFIG="$PROJECT_ROOT/mobius.config.yaml"
|
|
25
|
+
|
|
26
|
+
# Default configuration (can be overridden by config file or environment)
|
|
27
|
+
DELAY_SECONDS="${MOBIUS_DELAY_SECONDS:-3}"
|
|
28
|
+
DEFAULT_BACKEND="${MOBIUS_BACKEND:-linear}"
|
|
29
|
+
MAX_ITERATIONS_DEFAULT="${MOBIUS_MAX_ITERATIONS:-50}"
|
|
30
|
+
CONTAINER_NAME="${MOBIUS_CONTAINER:-mobius-sandbox}"
|
|
31
|
+
MODEL="${MOBIUS_MODEL:-opus}"
|
|
32
|
+
USE_SANDBOX="${MOBIUS_SANDBOX_ENABLED:-true}"
|
|
33
|
+
|
|
34
|
+
# Backend skill mappings
|
|
35
|
+
declare -A BACKEND_SKILLS=(
|
|
36
|
+
[linear]="/execute-linear-issue"
|
|
37
|
+
[jira]="/execute-jira-issue" # Future: implement Jira skill
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
declare -A BACKEND_ID_PATTERNS=(
|
|
41
|
+
[linear]='^[A-Z]+-[0-9]+$'
|
|
42
|
+
[jira]='^[A-Z]+-[0-9]+$'
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Parse YAML config file (basic parser for simple key: value pairs)
|
|
46
|
+
# Supports nested keys like "execution.delay_seconds"
|
|
47
|
+
parse_yaml_config() {
|
|
48
|
+
local config_file="$1"
|
|
49
|
+
|
|
50
|
+
if [ ! -f "$config_file" ]; then
|
|
51
|
+
return 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
local current_section=""
|
|
55
|
+
|
|
56
|
+
while IFS= read -r line || [ -n "$line" ]; do
|
|
57
|
+
# Skip comments and empty lines
|
|
58
|
+
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
|
59
|
+
[[ -z "${line// }" ]] && continue
|
|
60
|
+
|
|
61
|
+
# Detect section headers (no leading whitespace, ends with colon, no value)
|
|
62
|
+
if [[ "$line" =~ ^([a-zA-Z_][a-zA-Z0-9_]*):$ ]] || [[ "$line" =~ ^([a-zA-Z_][a-zA-Z0-9_]*):[[:space:]]*$ ]]; then
|
|
63
|
+
current_section="${BASH_REMATCH[1]}"
|
|
64
|
+
continue
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Parse key: value pairs
|
|
68
|
+
if [[ "$line" =~ ^[[:space:]]*([a-zA-Z_][a-zA-Z0-9_]*):[[:space:]]*(.+)$ ]]; then
|
|
69
|
+
local key="${BASH_REMATCH[1]}"
|
|
70
|
+
local value="${BASH_REMATCH[2]}"
|
|
71
|
+
|
|
72
|
+
# Remove comments from value
|
|
73
|
+
value="${value%%#*}"
|
|
74
|
+
# Trim whitespace
|
|
75
|
+
value="${value%"${value##*[![:space:]]}"}"
|
|
76
|
+
|
|
77
|
+
# Skip empty values
|
|
78
|
+
[ -z "$value" ] && continue
|
|
79
|
+
|
|
80
|
+
# Build full key name
|
|
81
|
+
local full_key="$key"
|
|
82
|
+
if [ -n "$current_section" ]; then
|
|
83
|
+
full_key="${current_section}.${key}"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Map config keys to variables (only if not already set by env)
|
|
87
|
+
case "$full_key" in
|
|
88
|
+
backend)
|
|
89
|
+
[ -z "${MOBIUS_BACKEND:-}" ] && DEFAULT_BACKEND="$value"
|
|
90
|
+
;;
|
|
91
|
+
execution.delay_seconds)
|
|
92
|
+
[ -z "${MOBIUS_DELAY_SECONDS:-}" ] && DELAY_SECONDS="$value"
|
|
93
|
+
;;
|
|
94
|
+
execution.max_iterations)
|
|
95
|
+
[ -z "${MOBIUS_MAX_ITERATIONS:-}" ] && MAX_ITERATIONS_DEFAULT="$value"
|
|
96
|
+
;;
|
|
97
|
+
execution.model)
|
|
98
|
+
[ -z "${MOBIUS_MODEL:-}" ] && MODEL="$value"
|
|
99
|
+
;;
|
|
100
|
+
execution.sandbox)
|
|
101
|
+
[ -z "${MOBIUS_SANDBOX_ENABLED:-}" ] && USE_SANDBOX="$value"
|
|
102
|
+
;;
|
|
103
|
+
execution.container_name)
|
|
104
|
+
[ -z "${MOBIUS_CONTAINER:-}" ] && CONTAINER_NAME="$value"
|
|
105
|
+
;;
|
|
106
|
+
esac
|
|
107
|
+
fi
|
|
108
|
+
done < "$config_file"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Load configuration (user config takes precedence over defaults)
|
|
112
|
+
load_config() {
|
|
113
|
+
# Load default config if it exists
|
|
114
|
+
if [ -f "$DEFAULT_CONFIG" ]; then
|
|
115
|
+
parse_yaml_config "$DEFAULT_CONFIG"
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Load user config (overrides defaults)
|
|
119
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
120
|
+
parse_yaml_config "$CONFIG_FILE"
|
|
121
|
+
fi
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Parse arguments
|
|
125
|
+
TASK_ID=""
|
|
126
|
+
MAX_ITERATIONS=0
|
|
127
|
+
RUN_LOCAL=false
|
|
128
|
+
BACKEND=""
|
|
129
|
+
SHOW_CONFIG=false
|
|
130
|
+
|
|
131
|
+
parse_args() {
|
|
132
|
+
local args=()
|
|
133
|
+
for arg in "$@"; do
|
|
134
|
+
case "$arg" in
|
|
135
|
+
--local|-l)
|
|
136
|
+
RUN_LOCAL=true
|
|
137
|
+
;;
|
|
138
|
+
--help|-h)
|
|
139
|
+
show_help
|
|
140
|
+
exit 0
|
|
141
|
+
;;
|
|
142
|
+
--version|-v)
|
|
143
|
+
echo "mobius v1.0.0"
|
|
144
|
+
exit 0
|
|
145
|
+
;;
|
|
146
|
+
--config)
|
|
147
|
+
SHOW_CONFIG=true
|
|
148
|
+
;;
|
|
149
|
+
--backend=*)
|
|
150
|
+
BACKEND="${arg#*=}"
|
|
151
|
+
;;
|
|
152
|
+
--model=*)
|
|
153
|
+
MODEL="${arg#*=}"
|
|
154
|
+
;;
|
|
155
|
+
--delay=*)
|
|
156
|
+
DELAY_SECONDS="${arg#*=}"
|
|
157
|
+
;;
|
|
158
|
+
*)
|
|
159
|
+
args+=("$arg")
|
|
160
|
+
;;
|
|
161
|
+
esac
|
|
162
|
+
done
|
|
163
|
+
|
|
164
|
+
# Show config and exit if requested
|
|
165
|
+
if [ "$SHOW_CONFIG" = "true" ]; then
|
|
166
|
+
show_config
|
|
167
|
+
exit 0
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
if [ ${#args[@]} -eq 0 ]; then
|
|
171
|
+
echo "Error: Task ID required"
|
|
172
|
+
echo "Usage: mobius <TASK-ID> [max-iterations] [options]"
|
|
173
|
+
echo "Run 'mobius --help' for more information."
|
|
174
|
+
exit 1
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
TASK_ID="${args[0]}"
|
|
178
|
+
|
|
179
|
+
# Use default backend if not specified via flag
|
|
180
|
+
[ -z "$BACKEND" ] && BACKEND="$DEFAULT_BACKEND"
|
|
181
|
+
|
|
182
|
+
# Validate backend
|
|
183
|
+
if [ -z "${BACKEND_SKILLS[$BACKEND]:-}" ]; then
|
|
184
|
+
echo "Error: Unknown backend: $BACKEND"
|
|
185
|
+
echo "Available backends: ${!BACKEND_SKILLS[*]}"
|
|
186
|
+
exit 1
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# Validate task ID format
|
|
190
|
+
local pattern="${BACKEND_ID_PATTERNS[$BACKEND]}"
|
|
191
|
+
if ! [[ "$TASK_ID" =~ $pattern ]]; then
|
|
192
|
+
echo "Error: Invalid task ID format for $BACKEND: $TASK_ID"
|
|
193
|
+
echo "Expected format: PREFIX-NUMBER (e.g., VER-159)"
|
|
194
|
+
exit 1
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# Optional max iterations from args (overrides config)
|
|
198
|
+
if [ ${#args[@]} -ge 2 ] && [[ "${args[1]}" =~ ^[0-9]+$ ]]; then
|
|
199
|
+
MAX_ITERATIONS="${args[1]}"
|
|
200
|
+
else
|
|
201
|
+
MAX_ITERATIONS="$MAX_ITERATIONS_DEFAULT"
|
|
202
|
+
fi
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
show_help() {
|
|
206
|
+
cat << EOF
|
|
207
|
+
mobius - AI-Powered Development Workflow Tool
|
|
208
|
+
|
|
209
|
+
Execute sub-tasks of an issue using Claude skills in an autonomous loop.
|
|
210
|
+
|
|
211
|
+
USAGE:
|
|
212
|
+
mobius <TASK-ID> [max-iterations] [options]
|
|
213
|
+
|
|
214
|
+
ARGUMENTS:
|
|
215
|
+
TASK-ID Issue ID (e.g., VER-159 for Linear, PROJ-123 for Jira)
|
|
216
|
+
max-iterations Maximum iterations (default: from config or 50)
|
|
217
|
+
|
|
218
|
+
OPTIONS:
|
|
219
|
+
--backend=NAME Planning backend to use (default: $DEFAULT_BACKEND)
|
|
220
|
+
--model=MODEL Claude model: opus, sonnet, haiku (default: $MODEL)
|
|
221
|
+
--delay=SECONDS Delay between iterations (default: $DELAY_SECONDS)
|
|
222
|
+
--local, -l Run locally (bypass container sandbox)
|
|
223
|
+
--config Show current configuration and exit
|
|
224
|
+
--version, -v Show version
|
|
225
|
+
--help, -h Show this help message
|
|
226
|
+
|
|
227
|
+
AVAILABLE BACKENDS:
|
|
228
|
+
${!BACKEND_SKILLS[*]}
|
|
229
|
+
|
|
230
|
+
CONFIGURATION:
|
|
231
|
+
User config: $CONFIG_FILE
|
|
232
|
+
Default config: $DEFAULT_CONFIG
|
|
233
|
+
|
|
234
|
+
Environment variables override config file settings:
|
|
235
|
+
MOBIUS_BACKEND Default backend
|
|
236
|
+
MOBIUS_DELAY_SECONDS Delay between iterations
|
|
237
|
+
MOBIUS_MAX_ITERATIONS Maximum iterations
|
|
238
|
+
MOBIUS_MODEL Claude model
|
|
239
|
+
MOBIUS_CONTAINER Docker container name
|
|
240
|
+
MOBIUS_SANDBOX_ENABLED Enable sandbox mode (true/false)
|
|
241
|
+
|
|
242
|
+
EXAMPLES:
|
|
243
|
+
mobius VER-159 Execute sub-tasks of VER-159 (Linear)
|
|
244
|
+
mobius VER-159 10 Max 10 iterations
|
|
245
|
+
mobius VER-159 --local Run locally with browser access
|
|
246
|
+
mobius VER-159 --model=sonnet Use Sonnet model
|
|
247
|
+
mobius PROJ-123 --backend=jira Use Jira backend
|
|
248
|
+
|
|
249
|
+
WORKFLOW:
|
|
250
|
+
Each iteration:
|
|
251
|
+
1. Claude runs the backend's execute skill
|
|
252
|
+
2. The skill finds the next ready sub-task and executes it
|
|
253
|
+
3. Sub-task is marked complete in the planning tool
|
|
254
|
+
4. Loop continues until all sub-tasks are done
|
|
255
|
+
|
|
256
|
+
The loop reads AGENTS.md from your project root for context.
|
|
257
|
+
EOF
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
show_config() {
|
|
261
|
+
echo "Mobius Configuration"
|
|
262
|
+
echo "===================="
|
|
263
|
+
echo ""
|
|
264
|
+
echo "Config files:"
|
|
265
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
266
|
+
echo " User: $CONFIG_FILE (active)"
|
|
267
|
+
else
|
|
268
|
+
echo " User: $CONFIG_FILE (not found)"
|
|
269
|
+
fi
|
|
270
|
+
if [ -f "$DEFAULT_CONFIG" ]; then
|
|
271
|
+
echo " Default: $DEFAULT_CONFIG (active)"
|
|
272
|
+
else
|
|
273
|
+
echo " Default: $DEFAULT_CONFIG (not found)"
|
|
274
|
+
fi
|
|
275
|
+
echo ""
|
|
276
|
+
echo "Current settings:"
|
|
277
|
+
echo " backend: $DEFAULT_BACKEND"
|
|
278
|
+
echo " model: $MODEL"
|
|
279
|
+
echo " delay_seconds: $DELAY_SECONDS"
|
|
280
|
+
echo " max_iterations: $MAX_ITERATIONS_DEFAULT"
|
|
281
|
+
echo " sandbox: $USE_SANDBOX"
|
|
282
|
+
echo " container: $CONTAINER_NAME"
|
|
283
|
+
echo ""
|
|
284
|
+
echo "Available backends: ${!BACKEND_SKILLS[*]}"
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
log() { echo "[mobius] $1"; }
|
|
288
|
+
|
|
289
|
+
# Sandbox delegation (optional - requires container setup)
|
|
290
|
+
delegate_to_sandbox() {
|
|
291
|
+
local args="$TASK_ID"
|
|
292
|
+
if [ "$MAX_ITERATIONS" -gt 0 ]; then
|
|
293
|
+
args="$TASK_ID $MAX_ITERATIONS"
|
|
294
|
+
fi
|
|
295
|
+
args="$args --backend=$BACKEND"
|
|
296
|
+
|
|
297
|
+
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
|
|
298
|
+
log "Delegating to sandbox..."
|
|
299
|
+
exec docker exec -it "$CONTAINER_NAME" bash -c "cd /workspace && MOBIUS_SANDBOX=1 ./scripts/mobius.sh $args"
|
|
300
|
+
else
|
|
301
|
+
# Check if sandbox script exists
|
|
302
|
+
if [ -f "$PROJECT_ROOT/scripts/sandbox.sh" ]; then
|
|
303
|
+
log "Starting sandbox..."
|
|
304
|
+
"$PROJECT_ROOT/scripts/sandbox.sh"
|
|
305
|
+
exec docker exec -it "$CONTAINER_NAME" bash -c "cd /workspace && MOBIUS_SANDBOX=1 ./scripts/mobius.sh $args"
|
|
306
|
+
else
|
|
307
|
+
log "No sandbox configured, running locally"
|
|
308
|
+
RUN_LOCAL=true
|
|
309
|
+
fi
|
|
310
|
+
fi
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
# The main loop
|
|
314
|
+
run_loop() {
|
|
315
|
+
trap 'echo ""; log "Stopped"; exit 0' INT TERM
|
|
316
|
+
|
|
317
|
+
local skill="${BACKEND_SKILLS[$BACKEND]}"
|
|
318
|
+
|
|
319
|
+
echo ""
|
|
320
|
+
echo "================================"
|
|
321
|
+
echo " Mobius - AI Development Workflow"
|
|
322
|
+
echo "================================"
|
|
323
|
+
echo ""
|
|
324
|
+
log "Task: $TASK_ID"
|
|
325
|
+
log "Backend: $BACKEND"
|
|
326
|
+
log "Skill: $skill"
|
|
327
|
+
log "Model: $MODEL"
|
|
328
|
+
if [ "$MAX_ITERATIONS" -gt 0 ]; then
|
|
329
|
+
log "Max iterations: $MAX_ITERATIONS"
|
|
330
|
+
else
|
|
331
|
+
log "Max iterations: unlimited"
|
|
332
|
+
fi
|
|
333
|
+
log "Delay: ${DELAY_SECONDS}s between iterations"
|
|
334
|
+
log "Press Ctrl+C to stop"
|
|
335
|
+
echo ""
|
|
336
|
+
|
|
337
|
+
local iteration=0
|
|
338
|
+
|
|
339
|
+
while true; do
|
|
340
|
+
# Check max iterations
|
|
341
|
+
if [ "$MAX_ITERATIONS" -gt 0 ] && [ "$iteration" -ge "$MAX_ITERATIONS" ]; then
|
|
342
|
+
echo ""
|
|
343
|
+
log "Reached max iterations: $MAX_ITERATIONS"
|
|
344
|
+
break
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
iteration=$((iteration + 1))
|
|
348
|
+
echo ""
|
|
349
|
+
echo "--- Iteration $iteration$([ "$MAX_ITERATIONS" -gt 0 ] && echo "/$MAX_ITERATIONS") ($(date +%H:%M:%S)) ---"
|
|
350
|
+
echo ""
|
|
351
|
+
|
|
352
|
+
# Run Claude with the backend-specific skill
|
|
353
|
+
local chrome_flag=""
|
|
354
|
+
if [ "$RUN_LOCAL" = "true" ]; then
|
|
355
|
+
chrome_flag="--chrome"
|
|
356
|
+
fi
|
|
357
|
+
|
|
358
|
+
# The skill will find the next ready sub-task and execute it
|
|
359
|
+
# If no sub-tasks remain, Claude will indicate completion
|
|
360
|
+
echo "$skill $TASK_ID" | claude -p \
|
|
361
|
+
--dangerously-skip-permissions \
|
|
362
|
+
--verbose \
|
|
363
|
+
--output-format=stream-json \
|
|
364
|
+
--model "$MODEL" \
|
|
365
|
+
$chrome_flag | cclean
|
|
366
|
+
|
|
367
|
+
echo ""
|
|
368
|
+
log "Waiting ${DELAY_SECONDS}s..."
|
|
369
|
+
sleep "$DELAY_SECONDS"
|
|
370
|
+
done
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
# Main
|
|
374
|
+
main() {
|
|
375
|
+
cd "$PROJECT_ROOT"
|
|
376
|
+
|
|
377
|
+
# Load configuration before parsing args
|
|
378
|
+
load_config
|
|
379
|
+
|
|
380
|
+
parse_args "$@"
|
|
381
|
+
|
|
382
|
+
# Delegate to sandbox unless already inside, --local flag, or sandbox disabled
|
|
383
|
+
if [ -z "${MOBIUS_SANDBOX:-}" ] && [ "$RUN_LOCAL" = "false" ] && [ "$USE_SANDBOX" = "true" ]; then
|
|
384
|
+
delegate_to_sandbox
|
|
385
|
+
fi
|
|
386
|
+
|
|
387
|
+
if [ "$RUN_LOCAL" = "true" ]; then
|
|
388
|
+
log "Running locally (sandbox bypassed)"
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
run_loop
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
main "$@"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Render Mermaid diagrams to SVG using mermaid-cli
|
|
3
|
+
# Usage: ./scripts/render-diagrams.sh
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
9
|
+
SRC_DIR="$PROJECT_DIR/assets/diagrams/src"
|
|
10
|
+
OUT_DIR="$PROJECT_DIR/assets/diagrams"
|
|
11
|
+
|
|
12
|
+
# Check if mermaid-cli is available
|
|
13
|
+
if ! command -v mmdc &> /dev/null && ! npx mmdc --version &> /dev/null 2>&1; then
|
|
14
|
+
echo "Installing @mermaid-js/mermaid-cli..."
|
|
15
|
+
npm install -g @mermaid-js/mermaid-cli
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
echo "Rendering Mermaid diagrams..."
|
|
19
|
+
|
|
20
|
+
for file in "$SRC_DIR"/*.mmd; do
|
|
21
|
+
if [ -f "$file" ]; then
|
|
22
|
+
name=$(basename "$file" .mmd)
|
|
23
|
+
echo " Rendering $name.svg..."
|
|
24
|
+
npx -p @mermaid-js/mermaid-cli mmdc \
|
|
25
|
+
-i "$file" \
|
|
26
|
+
-o "$OUT_DIR/$name.svg" \
|
|
27
|
+
-t dark \
|
|
28
|
+
-b transparent \
|
|
29
|
+
--configFile "$PROJECT_DIR/assets/diagrams/mermaid.config.json" 2>/dev/null || \
|
|
30
|
+
npx -p @mermaid-js/mermaid-cli mmdc \
|
|
31
|
+
-i "$file" \
|
|
32
|
+
-o "$OUT_DIR/$name.svg" \
|
|
33
|
+
-t dark \
|
|
34
|
+
-b transparent
|
|
35
|
+
fi
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
echo "Done! Diagrams rendered to $OUT_DIR/"
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Render VHS tape files to SVG terminal recordings
|
|
3
|
+
# Usage: ./scripts/render-terminal.sh
|
|
4
|
+
#
|
|
5
|
+
# Requirements:
|
|
6
|
+
# - VHS: brew install charmbracelet/tap/vhs (macOS) or go install github.com/charmbracelet/vhs@latest
|
|
7
|
+
# - svg-term-cli: npm install -g svg-term-cli
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
13
|
+
TAPES_DIR="$PROJECT_DIR/assets/terminal/tapes"
|
|
14
|
+
OUT_DIR="$PROJECT_DIR/assets/terminal"
|
|
15
|
+
|
|
16
|
+
# Check for VHS
|
|
17
|
+
if ! command -v vhs &> /dev/null; then
|
|
18
|
+
echo "Error: VHS is not installed."
|
|
19
|
+
echo "Install with: brew install charmbracelet/tap/vhs (macOS)"
|
|
20
|
+
echo " or: go install github.com/charmbracelet/vhs@latest"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Check for svg-term-cli
|
|
25
|
+
if ! command -v svg-term &> /dev/null && ! npx svg-term --version &> /dev/null 2>&1; then
|
|
26
|
+
echo "Installing svg-term-cli..."
|
|
27
|
+
npm install -g svg-term-cli
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
echo "Rendering terminal recordings..."
|
|
31
|
+
|
|
32
|
+
for tape in "$TAPES_DIR"/*.tape; do
|
|
33
|
+
if [ -f "$tape" ]; then
|
|
34
|
+
name=$(basename "$tape" .tape)
|
|
35
|
+
cast_file="$OUT_DIR/$name.cast"
|
|
36
|
+
svg_file="$OUT_DIR/$name.svg"
|
|
37
|
+
|
|
38
|
+
echo " Recording $name..."
|
|
39
|
+
vhs "$tape" -o "$cast_file"
|
|
40
|
+
|
|
41
|
+
echo " Converting to SVG..."
|
|
42
|
+
npx svg-term --in "$cast_file" --out "$svg_file" --window --no-cursor
|
|
43
|
+
|
|
44
|
+
# Clean up cast file (optional, comment out to keep)
|
|
45
|
+
rm -f "$cast_file"
|
|
46
|
+
fi
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
echo "Done! Terminal recordings rendered to $OUT_DIR/"
|