Files
stack/agents/rocko/launch.sh
T
jason.woltjeandClaude Opus 5.5 d41f81aafe feat(agents): Sage launch files, lead text across seat personas, lead decision record
- agents/sage/ launch files committed after Dewey's review (R1 revise, R2
  approve). The launcher test now covers sage with its zai/glm-5.3 high pin.
  The README states the lead role and its limits, and the seat reads but
  never writes the old DYOR records under ~/.mosaic.
- N6 (Dewey authored, Sage reviewed against pins): seat personas and the
  Rocko launcher name Sage as project lead and Darkwing as a collaborating
  engineering seat, per Jason's 2026-09-26 ruling.
- docs/plans/2026-09-26_lead-decisions.md: the push, no merge into next and
  its conditions, the board restart, queue-as-data rulings, Gate F waiting
  on a T3 source, and what stays with Jason.

Launcher tests 6/6 and 1/1, eight suites green. Not pushed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-26 15:11:10 -05:00

88 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Rocko's native Claude Code development session.
set -euo pipefail
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# Register this seat with the control board (packages/seat) unless already
# registered by `mosaic launch` or only running the checks.
if [ -z "${MOSAIC_LAUNCH_REGISTERED:-}" ] && ! printf '%s\n' "$@" | grep -qx -- '--check'; then
exec "$REPO/scripts/mosaic" launch --repo "$REPO" --harness claude-code rocko -- "$@"
fi
cd "$REPO"
fail() { echo "rocko: $*" >&2; exit 1; }
usage() {
echo 'Usage: agents/rocko/launch.sh [--fresh] [--check] [--soul FILE] [--constitution FILE] [--user FILE]'
}
FRESH=false
CHECK=false
SOUL="$REPO/agents/rocko/SOUL.md"
CONSTITUTION="$REPO/contracts/CONSTITUTION.md"
USER_FILE=""
while [ "$#" -gt 0 ]; do
case "$1" in
--fresh) FRESH=true; shift ;;
--check) CHECK=true; shift ;;
--soul|--constitution|--user)
[ "$#" -ge 2 ] && [ -n "$2" ] || fail "$1 needs a file"
case "$1" in
--soul) SOUL="$2" ;;
--constitution) CONSTITUTION="$2" ;;
--user) USER_FILE="$2" ;;
esac
shift 2 ;;
--help|-h) usage; exit 0 ;;
*) usage >&2; fail "unknown argument: $1" ;;
esac
done
source "$REPO/scripts/common.sh"
load_config
USER_FILE="${USER_FILE:-$MOSAIC_DATA_ROOT/user/USER.md}"
command -v claude >/dev/null || fail 'Claude Code is required on PATH'
command -v node >/dev/null || fail 'Node.js is required'
command -v flock >/dev/null || fail 'flock is required'
VERSION="$(claude --version)"
CONTEXT_FILES=("$CONSTITUTION" "$REPO/contracts/STANDARDS.md" "$SOUL" "$USER_FILE" "$REPO/AGENTS.md" "$REPO/agents/rocko/CONTEXT.md")
for file in "${CONTEXT_FILES[@]}"; do
[ -f "$file" ] && [ -r "$file" ] && [ -s "$file" ] || fail "missing, unreadable or empty context: $file"
done
STATE="$REPO/.pi/state/rocko"
echo "rocko: native host TUI | $VERSION | model sonnet"
echo "rocko: workspace $REPO | project lead Sage"
if "$CHECK"; then
echo 'rocko: configuration checks passed (no TUI, authentication request or model call)'
exit 0
fi
[ -t 0 ] && [ -t 1 ] || fail 'launch from an interactive terminal (or use --check)'
umask 077
mkdir -p "$STATE/launches"
exec 8>"$STATE/launch.lock"
flock -n 8 || fail 'another rocko TUI from this launcher is active'
SESSION_FILE="$STATE/session-id"
if ! "$FRESH" && [ -e "$SESSION_FILE" ]; then
[ -f "$SESSION_FILE" ] && [ -r "$SESSION_FILE" ] || fail 'invalid session-id file; inspect it or use --fresh'
SESSION_ID="$(cat "$SESSION_FILE")"
[[ "$SESSION_ID" =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ ]] || fail 'invalid session-id; inspect it or use --fresh'
SESSION_ARGS=(--resume "$SESSION_ID")
echo "rocko: resuming conversation $SESSION_ID"
else
SESSION_ID="$(node -e 'console.log(require("node:crypto").randomUUID())')"
SESSION_ARGS=(--session-id "$SESSION_ID")
echo "rocko: starting conversation $SESSION_ID; earlier conversations are preserved"
fi
LAUNCH="$(mktemp -d "$STATE/launches/launch.XXXXXXXX")"
PROMPT="$LAUNCH/context.md"
for file in "${CONTEXT_FILES[@]}"; do
printf '\n===== %s (%s) =====\n' "$(basename "$file")" "$file" >> "$PROMPT"
cat "$file" >> "$PROMPT"
printf '\n' >> "$PROMPT"
done
sha256sum "$PROMPT" > "$LAUNCH/context.sha256"
printf '%s\n' "$SESSION_ID" > "$LAUNCH/session-id"
# Retain each prior ID in its launch receipt; replace only the current pointer.
printf '%s\n' "$SESSION_ID" > "$STATE/session-id.tmp"
mv "$STATE/session-id.tmp" "$SESSION_FILE"
echo "rocko: context snapshot $PROMPT"
unset MOSAIC_LAUNCH_INCARNATION
export MOSAIC_AGENT_NAME=rocko
exec claude --model sonnet --name Rocko \
--append-system-prompt "$(cat "$PROMPT")" "${SESSION_ARGS[@]}"