docker: two ways to talk to the loose agent
Remote Control, so a detached run is not a one-way trip: ./sylph-agent remote -> https://claude.ai/code/session_... ./sylph-agent attach -> the container's own terminal `loose` now starts Claude Code with `--remote-control <name>`, registering the session with your account so you can chat with it from claude.ai or a phone. The name is passed EXPLICITLY because the flag's value is optional — a bare `--remote-control` swallows the /loop prompt that follows as the session name. Off with SYLPH_REMOTE=0, renamed with SYLPH_REMOTE_NAME. The pty is forced to 200x50. A detached `docker run -t` gives 80x24, and Claude Code hard-wraps to the terminal width — which truncated the Remote Control URL to ".../session_01..." in the one place you actually need to read it, and made `docker logs` nearly unusable besides. `remote` waits up to six minutes and reports progress: registration lands a minute or two after launch, so answering "not found" immediately would be answering a different question than the one being asked. Verified: a loose run registers and `./sylph-agent remote` prints the full URL. `attach` is NOT verified end to end from here — `docker attach` refuses a piped stdin ("cannot attach stdin to a TTY-enabled container"), which is a property of this harness rather than of the container, so it needs a real terminal to try. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,8 @@ the emulator, reads its guest memory and photographs its screen.
|
||||
./sylph-agent shell # poke around
|
||||
./sylph-agent agent # Claude Code, --dangerously-skip-permissions
|
||||
./sylph-agent loose # turn it loose: detached, /loop, self-paced
|
||||
./sylph-agent remote # link to chat with it from anywhere
|
||||
./sylph-agent attach # chat with it locally
|
||||
./sylph-agent logs -f # watch it
|
||||
./sylph-agent stop # stop it
|
||||
```
|
||||
@@ -26,8 +28,28 @@ fixed cadence instead of letting it self-pace.
|
||||
|
||||
It runs `-d` **without** `--rm`, so the transcript survives the container
|
||||
exiting — for an unattended run that is the only record of what happened.
|
||||
`./sylph-agent attach` joins the live session (Ctrl-P Ctrl-Q to leave it
|
||||
running).
|
||||
|
||||
### Talking to it
|
||||
|
||||
Two channels, both live while it works:
|
||||
|
||||
* **`./sylph-agent remote`** prints a `https://claude.ai/code/session_…` link.
|
||||
`loose` starts Claude Code with `--remote-control`, so the session registers
|
||||
with your account and you can chat with it from claude.ai or your phone —
|
||||
which is the point of a detached run. Disable with `SYLPH_REMOTE=0`, rename
|
||||
with `SYLPH_REMOTE_NAME`.
|
||||
|
||||
Registration takes a minute or two after launch, so `remote` waits for it
|
||||
rather than reporting "not found" to what is really "not yet".
|
||||
|
||||
* **`./sylph-agent attach`** joins the container's own terminal. Type to talk to
|
||||
it; **Ctrl-P Ctrl-Q** detaches and leaves it running. Do not press Ctrl-C —
|
||||
that goes to the agent.
|
||||
|
||||
The pty is forced to 200×50 (`stty_init` in `bin/claude-autonomous`). A detached
|
||||
`docker run -t` is 80×24, and Claude Code hard-wraps to the terminal width,
|
||||
which truncated the Remote Control URL to `…/session_01…` in the one place you
|
||||
need to read it — and made `docker logs` almost unreadable besides.
|
||||
|
||||
**It cannot push.** No git credentials are mounted, deliberately: a human
|
||||
reviews before anything leaves the box. Review with
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
set timeout 90
|
||||
log_user 1
|
||||
|
||||
# Give the pty a wide, tall geometry. A detached `docker run -t` defaults to
|
||||
# 80x24, and Claude Code hard-wraps to the terminal width — which truncates the
|
||||
# Remote Control URL to "https://claude.ai/code/session_01…" in the one place
|
||||
# you need to read it, and makes `docker logs` nearly unusable generally.
|
||||
set stty_init "rows 50 cols 200"
|
||||
|
||||
set answered_theme 0
|
||||
set answered_trust 0
|
||||
set answered_bypass 0
|
||||
|
||||
@@ -115,6 +115,15 @@ if [ "${SYLPH_AUTONOMOUS:-0}" = "1" ]; then
|
||||
fi
|
||||
# The flag the user asked for. It is refused under root, which is why this
|
||||
# image runs as `agent`.
|
||||
# Remote Control registers the session with your account so you can chat with
|
||||
# the agent from claude.ai or your phone — the point of a detached run being
|
||||
# that you are not sitting in front of it. The name is passed EXPLICITLY: the
|
||||
# flag's value is optional, so a bare `--remote-control` would swallow the
|
||||
# /loop prompt that follows as the session name.
|
||||
if [ "${SYLPH_REMOTE:-1}" != "0" ]; then
|
||||
set -- --remote-control "${SYLPH_REMOTE_NAME:-sylpheed-agent}" "$@"
|
||||
log "Remote Control enabled as '${SYLPH_REMOTE_NAME:-sylpheed-agent}'"
|
||||
fi
|
||||
# claude-autonomous wraps `claude --dangerously-skip-permissions` in a pty and
|
||||
# answers the one-time first-run gates. The Bypass Permissions disclaimer in
|
||||
# particular has no config key that skips it, so unattended it hangs forever.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
# ./sylph-agent agent [prompt] Claude Code, --dangerously-skip-permissions
|
||||
# ./sylph-agent loose [task] turn it loose: detached, /loop, self-paced
|
||||
# ./sylph-agent logs [-f] what the loose agent is doing
|
||||
# ./sylph-agent remote print the Remote Control link (chat from anywhere)
|
||||
# ./sylph-agent attach attach to the loose agent's session
|
||||
# ./sylph-agent run <cmd...> one-shot command
|
||||
# ./sylph-agent stop stop it
|
||||
@@ -18,6 +19,8 @@
|
||||
# SYLPH_CLAUDE_HOME host dir mounted as the agent's ~/.claude
|
||||
# (default: $HOME/.claude — shares auth AND memory with you)
|
||||
# SYLPH_VULKAN=sw force software Vulkan (lavapipe) even if /dev/dri exists
|
||||
# SYLPH_REMOTE=0 do NOT enable Remote Control (default: enabled for `loose`)
|
||||
# SYLPH_REMOTE_NAME Remote Control session name (default: sylpheed-agent)
|
||||
# SYLPH_CPUS / SYLPH_MEM_GB override the computed half
|
||||
set -euo pipefail
|
||||
|
||||
@@ -124,6 +127,8 @@ docker_args() {
|
||||
|
||||
[ -n "${ANTHROPIC_API_KEY:-}" ] && _out+=(-e "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY")
|
||||
[ -n "${SYLPH_VULKAN:-}" ] && _out+=(-e "SYLPH_VULKAN=$SYLPH_VULKAN")
|
||||
[ -n "${SYLPH_REMOTE:-}" ] && _out+=(-e "SYLPH_REMOTE=$SYLPH_REMOTE")
|
||||
[ -n "${SYLPH_REMOTE_NAME:-}" ] && _out+=(-e "SYLPH_REMOTE_NAME=$SYLPH_REMOTE_NAME")
|
||||
[ -n "${SYLPH_ISO:-}" ] && _out+=(-e "SYLPH_ISO=$SYLPH_ISO")
|
||||
|
||||
# ── GPU ──
|
||||
@@ -196,8 +201,9 @@ case "${1:-}" in
|
||||
docker run -d -i -t "${ARGS[@]}" "$IMAGE" "/loop ${INTERVAL:+$INTERVAL }$TASK" >/dev/null
|
||||
echo
|
||||
echo " running detached as '$NAME'."
|
||||
echo " ./sylph-agent remote link to chat with it from anywhere"
|
||||
echo " ./sylph-agent logs -f follow it"
|
||||
echo " ./sylph-agent attach attach to the session (Ctrl-P Ctrl-Q to detach)"
|
||||
echo " ./sylph-agent attach chat with it locally (Ctrl-P Ctrl-Q to leave it running)"
|
||||
echo " ./sylph-agent stop stop it"
|
||||
echo
|
||||
echo " It commits to auto/* branches and cannot push — no git credentials"
|
||||
@@ -205,7 +211,35 @@ case "${1:-}" in
|
||||
;;
|
||||
|
||||
logs) shift; exec docker logs "$@" "$NAME" ;;
|
||||
attach) exec docker attach "$NAME" ;;
|
||||
|
||||
remote)
|
||||
# Fish the Remote Control link out of the session's own output. Claude Code
|
||||
# prints it once, when the session registers with your account — which takes
|
||||
# a minute or two after launch, so this waits rather than answering "not
|
||||
# found" to a question that is really "not yet".
|
||||
printf 'waiting for the session to register' >&2
|
||||
for i in $(seq 1 90); do
|
||||
url=$(docker logs "$NAME" 2>&1 \
|
||||
| sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\r//g' \
|
||||
| grep -oE 'https://claude\.ai/code/[A-Za-z0-9_-]+' | tail -1)
|
||||
if [ -n "${url:-}" ]; then
|
||||
printf '\n' >&2
|
||||
echo "$url"
|
||||
exit 0
|
||||
fi
|
||||
docker ps -q -f "name=$NAME" | grep -q . || {
|
||||
printf '\n' >&2
|
||||
echo "container is not running — start it with: ./sylph-agent loose" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '.' >&2
|
||||
sleep 4
|
||||
done
|
||||
printf '\n' >&2
|
||||
echo "no Remote Control URL after 6 minutes." >&2
|
||||
echo " Launched with SYLPH_REMOTE=0? Or check: ./sylph-agent logs | tail" >&2
|
||||
exit 1
|
||||
;;
|
||||
|
||||
shell|agent|run)
|
||||
mode=$1; shift
|
||||
|
||||
Reference in New Issue
Block a user