43cd6e22f2
Publish Docker Image / resolve-versions (push) Successful in 9s
Lint / actionlint (push) Successful in 15s
Lint / hadolint (push) Successful in 13s
Publish Docker Image / base-decide (push) Successful in 8s
Publish Docker Image / build-base (push) Successful in 41m22s
Publish Docker Image / smoke-studio (push) Successful in 5m16s
Publish Docker Image / smoke (push) Successful in 7m31s
Publish Docker Image / build-variant-studio (push) Successful in 18m31s
Publish Docker Image / build-variant (push) Successful in 27m18s
Publish Docker Image / promote-base-latest (push) Successful in 11s
Publish Docker Image / update-description (push) Successful in 12s
Two changes that belong together, because the first is what makes the second dangerous to get wrong. pi-atelier (TUI sidebar + status rail) is now vendored to /opt/pi-atelier at PI_ATELIER_REF=v0.8.0 and registered by entrypoint-user.sh — the pi-fork / pi-observational-memory / pi-studio pattern, deliberately NOT `pi install npm:pi-atelier`, which writes into ~/.pi/npm-global on the config volume where it shadows the image and pins nothing. Unlike its siblings it gets no `npm install`: atelier declares zero runtime deps (peerDeps only, satisfied by the baked pi) and has no build step, so pi loads its TypeScript straight from the checkout via package.json `pi.extensions`. pi is no longer resolved to npm `latest` at build time. The pin lives in Dockerfile.variant and CI reads it from there, so a local `docker build` and a CI release ship the same versions by construction. The pin is a CHECKPOINT, NOT A FREEZE: bumping stays a one-line change; what stops is *unreviewed* adoption of whatever shipped that morning, in the same build that then gets tagged and published. CI fails when a pin is not concrete or not actually published on npm, and warns — never adopts — when npm latest moves ahead, naming what to re-check. Why this pairing needed care: pi-atelier 0.6.0/0.7.0 wrap pi's PRIVATE TUI renderer, and under pi 0.84 that wrapper recurses — pi hangs at startup burning CPU with no error. Upstream fixed the recursion in 0.7.1 and restored the non-overlapping split in 0.7.2; 0.8.0 is additive on top. atelier's own peerDependencies still say >=0.80.7, which does not express that floor, so nothing in npm metadata could have warned us. The floor is therefore encoded as an executable rule — pi >= 0.84 => pi-atelier >= 0.7.1 — asserted in both smoke-test.sh (build time) and recreate-sanity-check.sh (after a real recreate), verified against a 4x4 version matrix. Existing volumes needed migration, not just vendoring: a hand-installed `npm:pi-atelier` entry is counted as already-registered by the entrypoint guard, so every existing volume would have kept its unpinned npm copy — and a 0.6.x copy next to pi 0.84 is exactly the startup hang. The entrypoint now drops that one exact string (settings.json.bak.atelier.<ts> backup, distinct prefix so it cannot clobber the template merge's backup in the same second) and lets the pinned /opt copy register. Tested against a real settings.json: only that entry removed, other packages and all keys intact, idempotent, and unparseable JSON leaves the file untouched. DEVBOX_ATELIER=0 opts out entirely — in the entrypoint rather than via `pi uninstall`, because this component's failure mode is "pi will not start", which cannot be repaired from inside pi. 0.84.1 was audited for this release, not merely adopted: theme/TUI changes are additive, the session format is unchanged (CURRENT_SESSION_VERSION = 3 in both 0.83.0 and 0.84.1 with an identical migrateV1ToV2/migrateV2ToV3 ladder, so existing transcripts are neither migrated nor at risk and pi-session-repair stays valid), and the Node engine floor is unmoved at >=22.19.0. CI resolves the atelier tag to its PEELED commit SHA — atelier uses annotated tags, so the unpeeled ref is a tag object, not a commit; pi-studio's lightweight tags never exposed that distinction. Also: docs for overriding the read-only ~/.ssh/config from the container — container-only keys in ~/.ssh-local, hardened authorized_keys, the fact that `from=` must allow the HOST's addresses because container egress is NAT'd through it, and the macOS-only-keyword trap (`UseKeychain` is fatal to Linux OpenSSH and takes out dssh/pi --ssh while the host keeps working). Corrects two claims in "Naming LAN peers": ssh-lan.conf is not ProxyJump-only, and first-time creation does need one restart because the Include is emitted only when the file already exists at start.
81 lines
4.2 KiB
Bash
81 lines
4.2 KiB
Bash
# pi-devbox environment configuration
|
|
# Copy this file to .env and fill in your values:
|
|
# cp .env.example .env
|
|
|
|
# ── Workspace ────────────────────────────────────────────────────────
|
|
# Path on host to mount as /workspace in the container
|
|
WORKSPACE_PATH=~/projects
|
|
|
|
# Path to SSH keys on host
|
|
SSH_KEY_PATH=~/.ssh
|
|
|
|
# ── MemPalace memory (local by default) ───────────────────────────
|
|
# By default the mempalace.ts extension spawns a LOCAL mempalace-mcp stdio
|
|
# server (palace at ~/.mempalace). Uncomment the devbox-palace volume in
|
|
# docker-compose.yml to persist it across container recreation.
|
|
#
|
|
# To instead share ONE MemPalace across containers/harnesses (pi + opencode
|
|
# + native), set the URL below. When set, the extension connects over HTTP
|
|
# and NO local mempalace-mcp is spawned; the devbox-palace volume is then
|
|
# irrelevant. MEMPALACE_REMOTE_TOKEN, if set, is sent as a bearer token.
|
|
# Serve it with: mempalace-mcp --transport http --host 0.0.0.0 --port 8765
|
|
# MEMPALACE_REMOTE_URL=http://mempalace.lan:8765/mcp
|
|
# MEMPALACE_REMOTE_TOKEN=
|
|
|
|
# ── LAN access from the container (host-OS-agnostic) ─────────────────
|
|
# On VM-backed hosts (macOS OrbStack / Docker Desktop) the container can't
|
|
# reach the host's directly-attached LAN peers by default. The entrypoint
|
|
# then sets up the host as an SSH jump (use the `dssh` alias). Reach the host
|
|
# with `dssh host`; for named LAN peers put `ProxyJump host` overrides in a
|
|
# host-owned ~/.config/devbox-shell/ssh-lan.conf (bind-mounted in) rather than
|
|
# editing ~/.ssh/config. On native Linux Docker the LAN is reachable directly
|
|
# and this is a no-op.
|
|
# See the opencode-devbox README for the full walkthrough.
|
|
#
|
|
# DEVBOX_LAN_ACCESS: auto (default) | jump | off
|
|
# DEVBOX_LAN_ACCESS=auto
|
|
# HOST_SSH_USER: your username on the host (required for the jump). On first
|
|
# start the entrypoint prints the public key to authorize on the host.
|
|
# HOST_SSH_USER=
|
|
# DEVBOX_HOST_ALIAS: host hostname to reach (default host.docker.internal).
|
|
# DEVBOX_HOST_ALIAS=host.docker.internal
|
|
# DEVBOX_LAN_AUTOJUMP_PRIVATE: 1 = ProxyJump any private (RFC1918) IP through
|
|
# the host, so bare `dssh user@<ip>` works on whatever LAN you're roaming on.
|
|
# DEVBOX_LAN_AUTOJUMP_PRIVATE=0
|
|
|
|
# ── pi-atelier (TUI sidebar) ─────────────────────────────────────────
|
|
# The image vendors pi-atelier at a pinned, audited tag and registers it on
|
|
# container start. Set to 0 to opt out: the entrypoint then removes it from
|
|
# pi's `packages[]` instead of registering it. This lives here rather than
|
|
# being a `pi uninstall` because a broken TUI extension's failure mode is
|
|
# "pi will not start", which you cannot fix from inside pi.
|
|
# DEVBOX_ATELIER=1
|
|
|
|
# ── Git Configuration ────────────────────────────────────────────────
|
|
GIT_USER_NAME=
|
|
GIT_USER_EMAIL=
|
|
|
|
# ── Gitea (for gitea-mcp MCP server) ────────────────────────────────
|
|
# GITEA_ACCESS_TOKEN=
|
|
# GITEA_HOST=https://gitea.example.com
|
|
|
|
# ── GitHub (optional, for GitHub MCP / git operations) ───────────────
|
|
# GITHUB_PERSONAL_ACCESS_TOKEN=
|
|
|
|
# ── AWS (optional, for AWS CLI / Bedrock) ────────────────────────────
|
|
# AWS_REGION=eu-west-1
|
|
# AWS_PROFILE=default
|
|
# AWS_ACCESS_KEY_ID=
|
|
# AWS_SECRET_ACCESS_KEY=
|
|
|
|
# ── Skillset (agent skills and instructions) ─────────────────────────
|
|
# If you have a skillset repo, the entrypoint auto-deploys skills and
|
|
# instructions on container start using relative symlinks.
|
|
# Detection is automatic if the skillset lives at WORKSPACE_PATH/skillset.
|
|
# SKILLSET_CONTAINER_PATH=
|
|
|
|
# ── Locale ───────────────────────────────────────────────────────────
|
|
# LANG=sv_SE.UTF-8
|
|
# LANGUAGE=sv_SE:sv
|
|
# LC_ALL=sv_SE.UTF-8
|