Files
rose-ash/scripts/sx-loops-up.sh
giles 985671cd76 hs: query targets, prolog hook, loop scripts, new plans, WASM regen
Hyperscript compiler/runtime:
- query target support in set/fire/put commands
- hs-set-prolog-hook! / hs-prolog-hook / hs-prolog in runtime
- runtime log-capture cleanup

Scripts: sx-loops-up/down, sx-hs-e-up/down, sx-primitives-down
Plans: datalog, elixir, elm, go, koka, minikanren, ocaml, hs-bucket-f,
       designs (breakpoint, null-safety, step-limit, tell, cookies, eval,
       plugin-system)
lib/prolog/hs-bridge.sx: initial hook-based bridge draft
lib/common-lisp/tests/runtime.sx: CL runtime tests

WASM: regenerate sx_browser.bc.js from updated hs sources

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 09:19:56 +00:00

175 lines
5.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Spawn 12 claude sessions in tmux, one per language loop.
# Each runs in its own git worktree rooted at /root/rose-ash-loops/<lang>,
# on branch loops/<lang>. No two loops share a working tree, so there's
# zero risk of file collisions between languages.
#
# Usage: ./scripts/sx-loops-up.sh [interval]
# interval defaults to self-paced (omit to let model decide)
#
# After the script prints done:
# tmux a -t sx-loops
# Ctrl-B + <window-number> to switch (0=lua ... 11=tcl)
# Ctrl-B + d to detach (loops keep running, SSH-safe)
#
# Stop: ./scripts/sx-loops-down.sh
# Wipe worktrees too: ./scripts/sx-loops-down.sh --clean
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
SESSION="sx-loops"
WORKTREE_BASE="/root/rose-ash-loops"
INTERVAL="${1:-}" # e.g. "15m", or empty for self-paced
BOOT_WAIT=20
if tmux has-session -t "$SESSION" 2>/dev/null; then
echo "Session '$SESSION' already exists."
echo " Attach: tmux a -t $SESSION"
echo " Kill: ./scripts/sx-loops-down.sh"
exit 1
fi
declare -A BRIEFING=(
[lua]=lua-loop.md
[prolog]=prolog-loop.md
[forth]=forth-loop.md
[erlang]=erlang-loop.md
[haskell]=haskell-loop.md
[js]=loop.md
[hs]=hs-loop.md
[smalltalk]=smalltalk-loop.md
[common-lisp]=common-lisp-loop.md
[apl]=apl-loop.md
[ruby]=ruby-loop.md
[tcl]=tcl-loop.md
)
ORDER=(lua prolog forth erlang haskell js hs smalltalk common-lisp apl ruby tcl)
mkdir -p "$WORKTREE_BASE"
# Settings written into every worktree so loops never stall on sx-tree permission prompts
write_worktree_settings() {
local wt="$1"
local settings_dir="$wt/.claude"
mkdir -p "$settings_dir"
cat > "$settings_dir/settings.local.json" <<'SETTINGS'
{
"permissions": {
"allow": [
"mcp__sx-tree__sx_summarise",
"mcp__sx-tree__sx_read_tree",
"mcp__sx-tree__sx_read_subtree",
"mcp__sx-tree__sx_get_context",
"mcp__sx-tree__sx_find_all",
"mcp__sx-tree__sx_find_across",
"mcp__sx-tree__sx_get_siblings",
"mcp__sx-tree__sx_validate",
"mcp__sx-tree__sx_replace_node",
"mcp__sx-tree__sx_insert_child",
"mcp__sx-tree__sx_insert_near",
"mcp__sx-tree__sx_delete_node",
"mcp__sx-tree__sx_wrap_node",
"mcp__sx-tree__sx_rename_symbol",
"mcp__sx-tree__sx_replace_by_pattern",
"mcp__sx-tree__sx_rename_across",
"mcp__sx-tree__sx_write_file",
"mcp__sx-tree__sx_pretty_print",
"mcp__sx-tree__sx_eval",
"mcp__sx-tree__sx_harness_eval",
"mcp__sx-tree__sx_macroexpand",
"mcp__sx-tree__sx_trace",
"mcp__sx-tree__sx_deps",
"mcp__sx-tree__sx_diff",
"mcp__sx-tree__sx_diff_branch",
"mcp__sx-tree__sx_changed",
"mcp__sx-tree__sx_blame",
"mcp__sx-tree__sx_build",
"mcp__sx-tree__sx_build_manifest",
"mcp__sx-tree__sx_build_bytecode",
"mcp__sx-tree__sx_test",
"mcp__sx-tree__sx_format_check",
"mcp__sx-tree__sx_comp_list",
"mcp__sx-tree__sx_comp_usage",
"mcp__sx-tree__sx_nav",
"mcp__sx-tree__sx_env",
"mcp__sx-tree__sx_playwright",
"mcp__hs-test__hs_test_run",
"mcp__hs-test__hs_test_regen",
"mcp__hs-test__hs_test_kill",
"mcp__hs-test__hs_test_status",
"Bash(node *)",
"Bash(python3 *)",
"Bash(bash *)",
"Bash(cp *)",
"Bash(git *)"
]
},
"enabledMcpjsonServers": [
"sx-tree",
"rose-ash-services",
"hs-test"
]
}
SETTINGS
}
echo "Preparing per-language worktrees under $WORKTREE_BASE ..."
for lang in "${ORDER[@]}"; do
wt="$WORKTREE_BASE/$lang"
branch="loops/$lang"
if [ -d "$wt/.git" ] || [ -f "$wt/.git" ]; then
echo " $lang: worktree exists at $wt"
else
# Create or reset the branch at current architecture HEAD, then add worktree
if git show-ref --verify --quiet "refs/heads/$branch"; then
git worktree add "$wt" "$branch" >/dev/null
else
git worktree add -b "$branch" "$wt" architecture >/dev/null
fi
echo " $lang: worktree created at $wt on $branch"
fi
write_worktree_settings "$wt"
done
# Create tmux session with one window per language, each cwd in its worktree
tmux new-session -d -s "$SESSION" -n "${ORDER[0]}" -c "$WORKTREE_BASE/${ORDER[0]}"
for lang in "${ORDER[@]:1}"; do
tmux new-window -t "$SESSION" -n "$lang" -c "$WORKTREE_BASE/$lang"
done
echo "Starting ${#ORDER[@]} claude sessions..."
for lang in "${ORDER[@]}"; do
tmux send-keys -t "$SESSION:$lang" "claude" C-m
done
echo "Waiting ${BOOT_WAIT}s for claude to boot..."
sleep "$BOOT_WAIT"
for lang in "${ORDER[@]}"; do
briefing="${BRIEFING[$lang]}"
if [ -n "$INTERVAL" ]; then
preamble="/loop $INTERVAL "
else
preamble="/loop "
fi
cmd="${preamble}Read plans/agent-briefings/$briefing and do ONE iteration per fire: pick the first unchecked [ ] from the plan, implement, test, commit with a short factual message, tick the box, append one dated line to the Progress log (newest first), then stop. You are on branch loops/$lang in worktree /root/rose-ash-loops/$lang; push commits to origin/loops/$lang (never main). Stay strictly in the briefing's scope."
tmux send-keys -t "$SESSION:$lang" "$cmd"
# tiny pause, then a second Enter — Claude's input box sometimes eats the first newline as a soft break
sleep 0.5
tmux send-keys -t "$SESSION:$lang" Enter
done
echo ""
echo "Done. ${#ORDER[@]} loops started in tmux session '$SESSION', each in its own worktree."
echo ""
echo " Attach: tmux a -t $SESSION"
echo " Switch: Ctrl-B <0..11> (0=lua 1=prolog 2=forth 3=erlang 4=haskell 5=js 6=hs 7=smalltalk 8=common-lisp 9=apl 10=ruby 11=tcl)"
echo " List: Ctrl-B w"
echo " Detach: Ctrl-B d"
echo " Stop: ./scripts/sx-loops-down.sh"
echo " Capture: tmux capture-pane -t $SESSION:<lang> -p | tail -40"
echo ""
echo "Worktrees:"
git worktree list | grep -E "rose-ash-loops/" || true