You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a self-hosted Mac target to the remote workbench: run the CodeWhale runtime + Telegram bridge inside an isolated Linux container on Apple silicon via apple/container, instead of renting a VPS. Zero cloud cost, phone-controlled, and the agent is sandboxed away from the host Mac.
Motivating setup: an always-on Apple-silicon desktop (e.g. a Mac Studio with 36 GB RAM) dedicating ~16 GB and a few cores to a containerized workbench.
Why this works
No inbound ports needed. The bridge is outbound long polling and the runtime binds 127.0.0.1 — a Mac behind home NAT is exactly as reachable as a cloud VM. Nothing about the v0.8.56: Ship DigitalOcean + Telegram remote-workbench setup #2964 lane assumes a public IP.
arm64 Linux binaries already ship with every release (codewhale-linux-arm64, codewhale-tui-linux-arm64 + sha256 manifest) — native speed in an Apple-silicon Linux VM, no Rust build.
The existing multi-arch Docker image is OCI-compliant, and apple/container runs OCI images — the distribution artifact already exists (docs/DOCKER.md).
Isolation is better than running natively on the Mac: a phone-controlled agent with allow_shell=true lives inside a lightweight VM with hard CPU/memory caps (--cpus, --memory 16g), with only explicitly mounted volumes visible. The runtime API on container-localhost is unreachable even from the host LAN. Teardown = delete container + volumes.
With ≥8 GB the container can run cargo builds and subagents comfortably — more headroom than the entry VPS tiers.
Reuse the existing image or a thin variant; reuse the env-file layout (runtime.env, telegram-bridge.env) mounted read-only from a host directory (chmod 600).
Supervision without systemd (these containers do not run systemd as init): a small entrypoint that starts codewhale serve --http --host 127.0.0.1 and the bridge, restarts on failure, and exits nonzero when both are down — mirroring the .service units' Restart=on-failure semantics.
Boot/restart persistence on the host: a launchd plist that runs container run ... at load and keeps it alive (the macOS equivalent of systemctl enable).
Volumes: /opt/whalebro (workspace + checkout), /var/lib/codewhale-telegram-bridge (thread map), env dir.
Doctor: adapt scripts/tencent-lighthouse/doctor.sh checks that assume systemd into a container-aware variant (process supervision + health checks still apply; systemctl sections skipped).
Host notes: prevent sleep (pmset/caffeinate), Apple silicon required, macOS 26 recommended (macOS 15 has container networking limitations; single-container layout avoids most of them).
Container-aware doctor variant (or doctor flags to skip systemd sections).
Docs: section in the remote-workbench docs presenting the three lanes side by side (DO VPS / Tencent HK / self-hosted Mac) with cost + isolation tradeoffs.
Fresh Apple-silicon Mac → working phone control using only the README: container starts with capped resources, runtime healthy on container-localhost, bridge polls, allowlist enforced.
Goal
Add a self-hosted Mac target to the remote workbench: run the CodeWhale runtime + Telegram bridge inside an isolated Linux container on Apple silicon via
apple/container, instead of renting a VPS. Zero cloud cost, phone-controlled, and the agent is sandboxed away from the host Mac.Motivating setup: an always-on Apple-silicon desktop (e.g. a Mac Studio with 36 GB RAM) dedicating ~16 GB and a few cores to a containerized workbench.
Why this works
127.0.0.1— a Mac behind home NAT is exactly as reachable as a cloud VM. Nothing about the v0.8.56: Ship DigitalOcean + Telegram remote-workbench setup #2964 lane assumes a public IP.codewhale-linux-arm64,codewhale-tui-linux-arm64+ sha256 manifest) — native speed in an Apple-silicon Linux VM, no Rust build.apple/containerruns OCI images — the distribution artifact already exists (docs/DOCKER.md).allow_shell=truelives inside a lightweight VM with hard CPU/memory caps (--cpus,--memory 16g), with only explicitly mounted volumes visible. The runtime API on container-localhost is unreachable even from the host LAN. Teardown = delete container + volumes.cargobuilds and subagents comfortably — more headroom than the entry VPS tiers.Design sketch
CloudTargetrow candidate for the codewhale remote-setup wizard: guided cloud + chat-bridge + provider setup (/remote) #2965remote-setupwizard, slug e.g.mac-container):runtime.env,telegram-bridge.env) mounted read-only from a host directory (chmod 600).codewhale serve --http --host 127.0.0.1and the bridge, restarts on failure, and exits nonzero when both are down — mirroring the.serviceunits' Restart=on-failure semantics.launchdplist that runscontainer run ...at load and keeps it alive (the macOS equivalent ofsystemctl enable)./opt/whalebro(workspace + checkout),/var/lib/codewhale-telegram-bridge(thread map), env dir.scripts/tencent-lighthouse/doctor.shchecks that assume systemd into a container-aware variant (process supervision + health checks still apply;systemctlsections skipped).pmset/caffeinate), Apple silicon required, macOS 26 recommended (macOS 15 has container networking limitations; single-container layout avoids most of them).Scope
scripts/remote-smoke/mac-container/: entrypoint,launchdplist template, setup + teardown scripts, README (mirroringdigitalocean/).mac-containeras a row in codewhale remote-setup wizard: guided cloud + chat-bridge + provider setup (/remote) #2965.Non-goals
Acceptance criteria
/status, prompt → turn, approval allow/deny,/interrupt(requires telegram-bridge: serial update dispatch deadlocks approvals — poll loop must never await a turn #2966), restart behavior.launchdbrings the container back; both processes resume (reattach behavior intact).Related
remote-setupwizard — this becomes a cloud/target row)docs/DOCKER.md,docs/REMOTE_VM_US.md