Commit graph

13 commits

Author SHA1 Message Date
8a7af06983 container: Fail early on missing subuid/subgid ranges
Rootless Podman falls back to a single-UID user namespace when the
invoking user has no /etc/subuid and /etc/subgid entry, and then any
chown to an unmapped UID fails with EINVAL. Newer pacman versions hit
this during builds and updates: their download sandbox chowns its
temporary download directory to the 'alpm' user, which made image
builds fail with a cryptic traceback after several minutes of output.

Accounts created manually or before shadow 4.11.1-3 (October 2022) get
no subordinate ID ranges automatically, while freshly created ones do.
Rather than working around this in the image (disabling pacman's
sandbox would silently drop a security feature), detect the missing
ranges before building and stop with the exact fix, using the first
unclaimed 65536-ID block so the printed command never collides with
other users' ranges. Link the Arch Wiki section and Podman's rootless
tutorial for background.
2026-10-29 08:33:23 +09:00
fa32cc4218 readme: Document the in-container marker & link release notes
Agents and skills gate on AGENT_CONTAINER=1 to know they are inside the
container rather than on the host, but nothing told a reader that the
variable exists, or that containers predating it get recreated.

The release notes only help someone who finds them, so the upgrade
section now points at CHANGELOG.md.
2026-10-29 02:15:25 +09:00
ed1c9a7b92 container: Use rootless Podman instead of Docker
Access to the Docker socket is equivalent to host root: whoever can talk
to /var/run/docker.sock can start a privileged container with the host
filesystem mounted and edit any file on it. Membership of the docker
group defeats the containment this tool exists to provide, because an
agent escapes the project directory by asking the daemon, not by
exploiting a bug. Rootless Podman keeps the workflow and drops the
escape: containers run in a user namespace owned by the invoking user,
and container root maps to a subuid from /etc/subuid instead of to host
root.

Rootless containers are created with --userns=keep-id so that the host
UID/GID map to the same values inside the container and bind-mounted
files keep their ownership in both directions; without it the container
UID 1000 would own nothing in the project. Sudo inside the container
keeps working, but only reaches container root.

Docker stays available through AGENT_CONTAINER_RUNTIME=docker for hosts
that cannot run rootless Podman. Existing Docker containers and images
are deliberately left alone: they are not reused, and the first Podman
run builds its own image.
2026-10-29 02:14:12 +09:00
e91b74ea38 tools: Install on first use instead of baking them into the image
Baked installs had two failure modes: anything installed into $HOME
at build time is shadowed by the container-home bind mount at runtime,
and system-wide installs are root-owned, so the tools' own update
commands (pi update, claude update, opencode upgrade) failed with an
unwritable install path. With pi releasing new versions almost daily,
the only remedy, a full image rebuild that also deleted every
container, was too heavy for that cadence.

Now each tool is installed at runtime into the persistent container
home by its official installer (no sudo), the same way the Docker
image itself is built on first use. Self-updates work inside the
container and survive image rebuilds and container recreation. The
image shrinks to a plain Arch base, and agent-container update no
longer removes containers, so sudo-installed project dependencies
survive it too.

docker exec now attaches a TTY only when stdin is one, so scripted
runs like 'pi -p' work without a terminal.
2026-09-18 08:38:23 +09:00
70699026c3 setup: Show a plan and ask for confirmation before changing anything 2026-09-12 21:40:17 +09:00
d110942710 setup: Add script to share agent state via container home symlinks 2026-09-12 21:38:39 +09:00
a3aa03e14d readme: Document sharing agent state via symlinks in container home 2026-09-12 21:36:03 +09:00
336ec1d97d readme: Document local aliases and bundled OpenCode plugin 2026-09-09 09:42:20 +09:00
6c859eb427 readme: Remove broken Claude Pro/Max bridge docs and mention local aliases 2026-09-09 09:39:47 +09:00
5c2f3ae83c container: Add Pi coding agent (pi.dev) as a third harness
- Install @earendil-works/pi-coding-agent globally via npm in the
  image so it survives the home directory bind mount
- Add pi subcommand forwarding PI_* and provider key prefixes
- Add pi shell wrapper alias
- Build with --network host so image builds work on hosts where the
  Docker bridge network cannot create veth pairs
2026-08-30 11:50:56 +09:00
a3db357b6f container: Forward env vars by prefix and source shell config from container-home
Replace hardcoded env var lists with prefix-based forwarding (OPENCODE_*,
ANTHROPIC_*, CLAUDE_*) so new env vars are picked up automatically.

Run tools through bash -l inside the container so that .bashrc, .bash_profile,
and .profile from container-home are sourced. Seed container-home with default
shell config from /etc/skel on first run if the files don't already exist.
2026-03-31 04:26:20 +00:00
2d3d5caacb container: Improve usability of web mode, error handling, and CLI commands
Use --network host so that web interfaces (e.g. opencode web) are
accessible from the host. Suppress Python tracebacks when the tool
exits with a non-zero code. Ignore SIGTSTP to prevent Ctrl+Z from
leaving orphaned containers. Rename force-cleanup to purge.
2026-03-28 22:07:58 +00:00
61017da6ba Combine opencode-container and claude-container into a unified agent-container
Merge the two separate container projects into a single image and
management script. Both OpenCode and Claude Code are installed in the
same Arch Linux image and share one persistent $HOME directory, which
enables the opencode-claude-bridge plugin to read Claude CLI credentials
from within OpenCode.

Subcommands: opencode, claude, update, force-cleanup.
2026-03-24 09:39:25 +09:00