v2.9.0
22 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
37960186c6 |
release: v2.9.0 — agent-browser, manifest reader, opencode 1.18.13
Not tagged yet; this is the v2.9.0 changeset landing on main. Added - agent-browser + a Playwright-managed headless Chromium in the base (~625 MB after deleting the redundant chromium_headless_shell build), so an agent can drive a real browser and VERIFY front-end work instead of assuming it renders. Ported from pi-devbox. AGENT_BROWSER_EXECUTABLE_PATH points at the stable symlink /usr/local/bin/agent-chrome, which the Dockerfile resolves with `find` rather than hardcoding: Playwright's browser dir is per-version AND per-arch (chrome-linux on arm64, chrome-linux64 on amd64), and the headless shell binary is named chrome-headless-shell so `-name chrome` skips it. - opencode-devbox-version: a reader for the build manifest. The image has baked ground truth to /etc/opencode-devbox/build-manifest.json for several releases, but nothing read it and nothing printed it — so "which image am I running?" meant knowing the path by heart. Three modes (--json/--quiet/human), plus a live-vs-baked drift check, because NPM_CONFIG_PREFIX points at the persistent config volume and a user `npm install -g opencode` can shadow the baked binary. entrypoint-user.sh prints it as its first output. - ENV COLORTERM=truecolor, completing a true-colour story the image already half-shipped (terminfo entries + Neovim termguicolors, but no capability advertisement, so bat/delta fell back to 256 colours). - Smoke assertions for agent-browser, that agent-chrome resolves to an executable (catches a Playwright layout change, not just a dangling symlink), COLORTERM, the manifest's release_tag, and all three version-command modes. Changed - opencode 1.17.20 -> 1.18.13. Verified by diffing upstream source, not release notes: core config.ts, config/provider.ts and schema.json are byte-identical, so generate-config.py needs no change. 1.18.13 (published mid-audit) was re-verified separately — 249 files in the compare payload, under GitHub's 300-file cap, so the list is complete rather than truncated; content is the Electron app plus localisation; the five contract-surface files hash identical at both tags. The bg-subagents removal trigger has NOT fired: runtime-flags.ts still gates the flag behind OPENCODE_EXPERIMENTAL at all three tags. - yq: dropped Debian's apt package (the unrelated Python kislyuk/yq — jq syntax, 3.x line) for mikefarah's Go yq v4 from GitHub. The cloud-init repo's provision.sh/deploy.sh need v4 syntax, and THIRD_PARTY.md already credited "yq (mikefarah)" while the image shipped the Python one, so this also closes a documented-vs-shipped mismatch. Smoke pins the contract to mikefarah v4. BEHAVIOUR CHANGE for any in-image script calling yq with jq-style syntax. - mempalace pin 3.5.0 -> 3.6.0, in lockstep with pi-devbox (5724302). Reviewed for MCP tool-schema changes before bumping — none, and nothing touches diary_write. - Default models -> claude-opus-5 (anthropic, and bedrock's global.anthropic.claude-opus-5) and openai/gpt-5.6. gpt-5.4 had gone stale: gpt-5.6 shipped four days before the v2.8.0 cut. Affects only new containers with no OPENCODE_MODEL and no existing config. - Smoke size thresholds +650 MB (base 2950->3600, omos 3650->4300), sized to keep the same ~250 MB headroom so the guardrail still catches runaway growth rather than routine apt drift. Do NOT copy pi-devbox's number: it sums `docker history`, this repo uses `docker image inspect .Size`. Documentation - New README section "Choosing a provider and model", making explicit that the baked defaults are only defaults and nobody is locked to Anthropic/Bedrock, including the three real gotchas: defaults seed only a NEW config, an existing opencode.jsonc on the persistent volume is never rewritten, and switching model needs no rebuild. - New README section "Browser automation (agent-browser)"; opencode-devbox-version documented under Build provenance; COLORTERM under Terminal compatibility. - README Build Args table drift fixed — FOUR missing args added (AGENT_BROWSER_VERSION, PLAYWRIGHT_VERSION, YQ_VERSION and GITLEAKS_VERSION, the last of which had existed as an ARG but was never listed), plus rows for the two pinned args absent entirely (MEMPALACE_VERSION, DEBIAN_VERSION), plus a refreshed stale OPENCODE_VERSION example. Third consecutive release to find drift in this table. - AGENTS.md: the stale MemPalace anyOf convention rewritten. It described a perl RUN block already DELETED at the 3.5.0 bump and asserted "PyPI latest is 3.4.0 (== our pin), no release contains the fix yet, the workaround must stay" — all three false. Replaced with a pin-review rule. Two new conventions added: the agent-browser/Chromium size coupling, and the yq identity trap. - THIRD_PARTY.md: agent-browser, Playwright, Chromium. Verified locally with the CI-pinned hadolint 2.14.0 and actionlint 1.7.7, the shell guard, DOCKER_HUB.md sync, bash -n, py_compile, and by generating the config for all three providers. |
||
|
|
d2f2396c4a |
docs(rootfs): re-sync mempalace snapshot from skillset 63f3bf5
Lint workflows / hadolint (push) Successful in 8s
Validate / docs-check (push) Successful in 8s
Lint workflows / actionlint (push) Successful in 23s
Validate / base-change-warning (push) Successful in 9s
Validate / validate-omos (push) Has been skipped
Validate / validate-base (push) Has been skipped
This snapshot was byte-identical to skillset and therefore MISSING the
Temporal grounding guidance, which had been authored only into pi-devbox's
vendored copy (pi-devbox 904fe85) and never back-ported to the owner repo. So
opencode-devbox containers — and any host consumer reading skillset directly —
never saw it, while pi-devbox containers did.
skillset 63f3bf5 is now canonical again and carries the section with wording
generalized to cover both devboxes ("a devbox container (pi-devbox or
opencode-devbox)"). Snapshot + VENDORED.md provenance updated to match.
Substance for the agent: establish "now" and compute now - entry.timestamp
before saying "yesterday"/"last week" — a container recreate or fresh session
is not a day boundary, and two diary entries 90 minutes apart can straddle one.
|
||
|
|
bade89ff35 |
docs(skill): note macOS NFD-filename gotcha for dscp/scp
Lint workflows / hadolint (push) Failing after 12s
Lint workflows / actionlint (push) Successful in 27s
Validate / docs-check (push) Failing after 20s
Validate / base-change-warning (push) Successful in 16s
Validate / validate-base (push) Has been skipped
Validate / validate-omos (push) Has been skipped
Mirror of the pi-devbox note: accented filenames on a macOS host are stored decomposed (NFD), so a precomposed (NFC) remote path in scp/dscp silently fails with 'No such file or directory'. Document the wildcard / list-first workaround next to the dssh/dscp alias table in opencode-devbox-environment. |
||
|
|
0cbcea83dc |
chore(config): bump default amazon-bedrock model to claude-sonnet-5
Lint workflows / hadolint (push) Successful in 8s
Validate / docs-check (push) Successful in 9s
Lint workflows / actionlint (push) Successful in 15s
Validate / base-change-warning (push) Successful in 8s
Validate / validate-base (push) Has been skipped
Validate / validate-omos (push) Has been skipped
DEFAULT_MODELS[amazon-bedrock] -> amazon-bedrock/global.anthropic.claude-sonnet-5 (was global.anthropic.claude-sonnet-4-5-20250929-v1:0). Verified invokable via pi --list-models. Folded into the existing Unreleased changelog entry; openai (gpt-5.4) default unchanged. |
||
|
|
4024c4d87b |
chore(config): bump default anthropic model to claude-sonnet-5
Validate / docs-check (push) Successful in 7s
Lint workflows / hadolint (push) Successful in 13s
Lint workflows / actionlint (push) Successful in 18s
Validate / base-change-warning (push) Successful in 6s
Validate / validate-base (push) Has been skipped
Validate / validate-omos (push) Has been skipped
DEFAULT_MODELS[anthropic] (and thus FALLBACK_MODEL) -> anthropic/claude-sonnet-5, matching the .env.example bump. openai/amazon-bedrock defaults unchanged. Documented under CHANGELOG Unreleased (no release cut yet). |
||
|
|
281ccbaa70 |
feat: pi-devbox parity — typst PDF, terminal terminfo, nvim colour, host-ssh check, hygiene
Validate / docs-check (push) Successful in 14s
Validate / base-change-warning (push) Successful in 9s
Publish Docker Image / resolve-versions (push) Successful in 14s
Lint workflows / actionlint (push) Successful in 21s
Validate / validate-base (push) Has been skipped
Validate / validate-omos (push) Has been skipped
Lint workflows / hadolint (push) Successful in 16s
Publish Docker Image / base-decide (push) Successful in 12s
Publish Docker Image / build-base (push) Successful in 42m20s
Publish Docker Image / smoke-base (push) Successful in 4m25s
Publish Docker Image / smoke-omos (push) Successful in 5m33s
Publish Docker Image / build-variant-base (push) Successful in 14m26s
Publish Docker Image / build-variant-omos (push) Successful in 19m41s
Publish Docker Image / promote-base-latest (push) Successful in 9s
Publish Docker Image / update-description (push) Successful in 14s
Ports the base additions from pi-devbox v1.4.0 + v1.5.0 that opencode-devbox lacked (opencode-devbox already tracks pi-devbox for CLI-toolset parity, v2.6.0): - typst PDF engine for pandoc (v1.4.0) + the pandoc typst-template default-font patch (v1.5.0) so 'pandoc --pdf-engine=typst' works without -V mainfont. pandoc shipped since v2.6.0 as a front-end only (no PDF back-end). +xz-utils. Tracks latest; --build-arg TYPST_VERSION escape hatch. - Terminal support (v1.5.0): ncurses-term + kitty-terminfo + a compiled xterm-ghostty alias (tic -x, use=ghostty), so wezterm/alacritty/foot/ghostty/ kitty resolve TERM over SSH instead of degrading to a dumb fallback. - Readable Neovim colours (v1.5.0): system-wide /etc/xdg/nvim/sysinit.vim with termguicolors. - Host SSH reachability check at shell startup (v1.4.0): one-time probe in .bash_aliases warning (with fix steps + inline pubkey) when the Mac host is unreachable. The rest of the LAN stack was already present. - .claude/settings.local.json added to the gitignore_global seed (v1.5.0). - Repo hygiene (v1.5.0): LICENSE (MIT), THIRD_PARTY.md, hadolint CI job (pinned v2.14.0) + .hadolint.yaml, IDEAS.md backlog. Base-affecting (Dockerfile.base + rootfs) → base-<hash> advances, base rebuilds. smoke-test gains typst/PDF, terminfo, and nvim-tgc assertions. Validated: hadolint clean on both Dockerfiles, bash -n OK, base-hash guard OK, workflow guard OK. CHANGELOG v2.7.0. |
||
|
|
61ec340e40 |
feat: add yq, pandoc, graphviz, tldr (tealdeer) + dot-watch — CLI parity with pi-devbox
- apt: yq (YAML query), pandoc (doc converter), graphviz (dot rendering) - tealdeer: tldr command as ~5MB static musl binary (TEALDEER_VERSION arg) - dot-watch: auto-render .dot to PNG on save (graphviz-only, no imagemagick) - README: document new tools - smoke-test: presence assertions for yq, pandoc, dot, tldr, dot-watch Excludes socat, imagemagick, studio-expose (pi-studio-specific). |
||
|
|
703edbe4a1 |
feat: optional shared/external MemPalace + fix validate.yml false-red on base changes
Added: - generate-config.py registers mempalace as a remote MCP endpoint when MEMPALACE_REMOTE_URL is set (MEMPALACE_REMOTE_TOKEN -> Bearer), else the local stdio command as before. Same env contract as pi-devbox's bridge. - docker-compose.mempalace.yml: optional shared server (mempalace-mcp --transport http), loopback-bound by default. - compose (both) + .env.example(.shared): MEMPALACE_REMOTE_URL/TOKEN + local-vs-external docs. Fixed: - validate.yml: skip validate-base/validate-omos on base-changing commits (base-change-warning now exports base_changed). Previously a commit that changed the base AND tightened smoke-test.sh in lockstep (v2.4.0 nano/micro) hard-failed against the stale base-latest until the release rebuilt it. actionlint clean. README + CHANGELOG (Unreleased). |
||
|
|
6639ba5820 |
feat: bake global gitignore (core.excludesFile) into image
Seed ~/.gitignore_global from /etc/skel-devbox (seed-if-absent, like .bash_aliases/.inputrc, so user edits survive recreate) and wire it via git config --global core.excludesFile, guarded so a user-set excludesFile is never overridden. Ignores *.bak, *.bak.*, *~, *.orig, *.swp, *.tmp across all repos without per-repo .gitignore entries. |
||
|
|
b9039f577e |
release: v2.3.0 — image-baked fallback skills + opencode 1.17.10 + mempalace 3.5.0
Validate / base-change-warning (push) Successful in 14s
Publish Docker Image / resolve-versions (push) Successful in 9s
Publish Docker Image / base-decide (push) Successful in 13s
Validate / validate-base (push) Failing after 3m26s
Validate / validate-omos (push) Failing after 4m28s
Publish Docker Image / build-base (push) Successful in 37m26s
Publish Docker Image / smoke-omos (push) Successful in 4m36s
Publish Docker Image / smoke-base (push) Successful in 7m41s
Publish Docker Image / build-variant-base (push) Successful in 13m47s
Publish Docker Image / build-variant-omos (push) Successful in 19m24s
Publish Docker Image / promote-base-latest (push) Successful in 8s
Validate / docs-check (push) Successful in 6s
Publish Docker Image / update-description (push) Successful in 9s
- Add image-baked fallback skills (opencode-devbox-environment, mempalace) + harness instruction (instructions/opencode-devbox.md) under /usr/local/share/opencode-devbox/, symlinked in by entrypoint-user.sh (skills only-when-absent; instruction symlink to image, never copied into the devbox-opencode-config volume). Ported from pi-devbox v1.2.0/v1.2.1, adapted to opencode's ~/.config/opencode/instructions/ auto-load model. No pi-extensions skill (opencode has no fork/recall). - Bump opencode 1.17.8 -> 1.17.10. - Bump mempalace 3.4.0 -> 3.5.0 (lockstep with pi-devbox v1.2.2); remove the obsolete diary_write anyOf perl workaround (fixed upstream, issue #1728). - Fix stale ssh-lan.conf ProxyJump guidance comment in setup-lan-access.sh (mirrors pi-devbox 8de0fad); comment-only. - smoke-test.sh + recreate-sanity-check.sh assert baked source + resolved links. - Docs: README Custom skills, AGENTS.md duties + MINOR example, CHANGELOG. |
||
|
|
af11c32f4f |
feat(config): non-destructive opencode.jsonc.proposed sidecar (closes #8 batch item)
Completes the pi-devbox v1.1.4 "merge new defaults into preserved config" idea, adapted to opencode-devbox's env-generated, JSONC-with-comments config where an in-place merge would be destructive. generate-config.py keeps its "never touch an existing config" guarantee and adds a side-channel: when a live config exists, render the config it WOULD generate for the current env + image defaults and write it to a NON-loaded opencode.jsonc.proposed — but only when it differs from the live config; remove it once they match. opencode never loads .proposed files, so it is a pure manual-merge reference (e.g. surfacing a default MCP server added in a newer image). An unparseable live config surfaces the proposal rather than guessing equivalence. A one-line hint is logged on write. - render_config(): shared renderer so first-gen and proposed paths can't drift - _loads_jsonc(): string-aware //-comment strip (same approach as smoke-test; preserves https:// inside strings), raises on invalid JSON - write_proposed(): write-on-diff + stale removal + live untouched - smoke-test.sh: asserts write-on-diff, removal-on-match, live not clobbered - entrypoint-user.sh + module docstring: document the sidecar - CHANGELOG: moved from "Deferred" to "Added" Caveat (documented in the file header): the proposal reflects env + image defaults, so a diff may include the user's own past edits, not only new image defaults. |
||
|
|
1c4239e9b0 |
port pi-devbox v1.1.4–v1.1.6 hardening; bump opencode 1.17.7→1.17.8
Functional (not verbatim) port of the build-provenance, CI-hardening, SSH and shell fixes from the sibling pi-devbox repo, adapted to opencode-devbox's companions and two-variant (base/omos) shape. Defaults unchanged → canonical CI build stays byte-identical apart from the opencode bump and the (cache-free) provenance layer. Fixed: - SSH read-only ~/.ssh ControlPath: setup-lan-access.sh now renders the writable ~/.ssh-local/config sidecar (ControlPath redirect + Include) on EVERY host OS instead of exit 0-ing on native Linux; jump-specific blocks gated behind new NEED_JUMP flag. dssh/dscp + ControlMaster now survive a read-only ~/.ssh on native-Linux hosts. (pi-devbox v1.1.5) - bash history loss in nested/tmux shells: DEVBOX_HIST_SET no longer exported so each shell re-installs its own history -a flush. (pi-devbox v1.1.4) Added: - build provenance: OCI labels + /etc/opencode-devbox/build-manifest.json written from ground truth (opencode --version, installed omos version, /opt/mempalace-toolkit HEAD); wired into build-variant-* and smoke-* jobs; smoke-test.sh asserts manifest + label. (pi-devbox v1.1.6) - scripts/check-base-hash.sh CI guard: fails if a Dockerfile.base ARG *_REF is not folded into the base_tag hash. (pi-devbox v1.1.6) - overridable MEMPALACE_TOOLKIT_REPO build-arg in Dockerfile.base. (v1.1.6) Changed: - resolve-versions: fail-loud validation (SHA / semver) that aborts the release instead of silently falling back to floating main; adds shell: bash (set -o pipefail is illegal under the runner default dash). (pi-devbox v1.1.6) Bumped: - opencode-ai 1.17.7 → 1.17.8 (current npm latest stable). Deferred (needs a decision): opencode.json merge-on-recreate — see CHANGELOG. |
||
|
|
0b78ab4a94 |
LAN jump key: persist via named volume + one-line authorize hint
Validate / docs-check (push) Successful in 7s
Validate / base-change-warning (push) Successful in 9s
Validate / validate-omos (push) Successful in 4m26s
Validate / validate-with-pi (push) Successful in 4m30s
Validate / validate-pi-only (push) Successful in 3m33s
Validate / validate-omos-with-pi (push) Successful in 8m44s
Validate / validate-base (push) Successful in 9m8s
Persist ~/.ssh-local (devbox-ssh-local named volume) so the generated LAN-jump key survives 'docker compose up --force-recreate'. Authorize it on the host once per machine instead of after every container update. setup-lan-access.sh now prints a copy-paste 'echo <pubkey> >> ~/.ssh/authorized_keys' line whenever it generates a new key (not only when HOST_SSH_USER is unset), and stays silent once the key is persisted. README + CHANGELOG updated. |
||
|
|
a56a5846a5 |
LAN-access: fix Include scope + read-only ControlPath, add ssh-lan.conf & RFC1918 autojump
Validate / docs-check (push) Successful in 6s
Validate / base-change-warning (push) Successful in 11s
Validate / validate-omos (push) Successful in 4m25s
Validate / validate-base (push) Successful in 5m21s
Validate / validate-omos-with-pi (push) Successful in 5m24s
Publish Docker Image / base-decide (push) Successful in 9s
Publish Docker Image / resolve-versions (push) Successful in 4s
Validate / validate-with-pi (push) Successful in 10m42s
Validate / validate-pi-only (push) Successful in 5m51s
Publish Docker Image / build-base (push) Successful in 30m30s
Publish Docker Image / smoke-base (push) Successful in 3m31s
Publish Docker Image / smoke-with-pi (push) Successful in 7m7s
Publish Docker Image / smoke-pi-only (push) Successful in 3m50s
Publish Docker Image / smoke-omos-with-pi (push) Successful in 5m20s
Publish Docker Image / smoke-omos (push) Successful in 12m4s
Publish Docker Image / build-variant-base (push) Successful in 15m56s
Publish Docker Image / build-variant-pi-only (push) Successful in 16m6s
Publish Docker Image / build-variant-with-pi (push) Successful in 17m56s
Publish Docker Image / build-variant-omos (push) Successful in 22m32s
Publish Docker Image / build-variant-omos-with-pi (push) Successful in 33m41s
Publish Docker Image / update-description (push) Successful in 9s
Publish Docker Image / promote-base-latest (push) Successful in 13s
- Fix: Include ~/.ssh/config was scoped to the Host host/mac block, so dssh <peer> by name fell back to SSH defaults. Emit Host * scope reset before every Include. - Fix: redirect ControlPath to writable ~/.ssh-local sidecar (Mac config's ~/.ssh/cm path is read-only in the container, broke multiplexed hosts). - Add: Include host-owned ~/.config/devbox-shell/ssh-lan.conf for named-peer ProxyJump overrides (keeps image generic; peer names stay host-side). - Add: opt-in DEVBOX_LAN_AUTOJUMP_PRIVATE=1 RFC1918 catch-all for roaming. - Docs: README/.env.example/AGENTS/CHANGELOG + new ssh-lan.conf.example. |
||
|
|
f09a4f382a |
feat: host-agnostic LAN access (base) + fork/recall in pi variants
Validate / base-change-warning (push) Successful in 22s
Validate / docs-check (push) Successful in 44s
Validate / validate-base (push) Successful in 3m27s
Validate / validate-omos (push) Successful in 7m3s
Validate / validate-with-pi (push) Failing after 4m33s
Validate / validate-omos-with-pi (push) Failing after 8m29s
Item A — LAN access (base image): - New rootfs/usr/local/lib/opencode-devbox/setup-lan-access.sh, invoked non-fatally from entrypoint-user.sh. On VM-backed hosts (macOS OrbStack / Docker Desktop, detected via host.docker.internal) it generates a writable ~/.ssh-local/config that uses the host as an SSH jump to reach LAN peers; no-op on native Linux. Ships the mechanism (generic 'host' jump alias), not policy (targets stay in the user's bind-mounted ~/.ssh/config). - New env knobs: DEVBOX_LAN_ACCESS (auto|jump|off), HOST_SSH_USER, DEVBOX_HOST_ALIAS. dssh/dscp aliases in .bash_aliases (guarded). Item B — pi-fork (fork) + pi-observational-memory (recall) in pi variants: - Dockerfile.variant clones both elpapi42 repos to /opt and runs npm install there at build time (local-path 'pi install' does not npm-install, so deps must be present to load). New args PI_FORK_REPO/REF, PI_OBSMEM_REPO/REF. - entrypoint-user.sh registers them at runtime via 'pi install /opt/<pkg>' (instant, in-place, idempotent; tools bind on next pi start). - CI resolve-versions resolves each repo's master HEAD to a commit SHA and passes PI_FORK_REF/PI_OBSMEM_REF — same cache-hit guard as PI_VERSION. - smoke-test asserts /opt clones + node_modules + settings.json registration; size thresholds bumped (with-pi 2700->2900, omos-with-pi 3700->3900). Versions unchanged (opencode 1.15.13, pi 0.78.0 — both still latest). Docs: README LAN section + env table, .env.example, AGENTS.md, CHANGELOG. Plan recorded in docs/plan-lan-access-and-pi-extensions.md. |
||
|
|
3d4e739529 |
Add Context7 remote MCP server to auto-generated config
Context7 provides up-to-date library documentation for LLMs via a remote endpoint — no local binary needed. Always registered since it has no PATH dependency. Also switches generated config from .json to .jsonc so we can include a comment about the optional API key for higher rate limits. The existing-config check now detects both file extensions. |
||
|
|
23bae2ab7d |
Use mempalace-mcp entry point directly, drop redundant wrapper
Validate / docs-check (push) Successful in 20s
Validate / validate-base (push) Successful in 11m32s
Validate / validate-omos (push) Successful in 15m18s
Publish Docker Image / build-base (push) Successful in 53m5s
Publish Docker Image / build-omos (push) Successful in 1h11m3s
Publish Docker Image / update-description (push) Successful in 15s
The mempalace Python package ships a 'mempalace-mcp' console entry
point; 'uv tool install' places it on PATH as a shim whose shebang
points at the isolated venv's Python. Our hand-rolled wrapper at
/usr/local/bin/mempalace-mcp-server was duplicating what uv installs
for free — one less file to maintain.
Fixes the MCP error users saw after the v1.14.28b → v1.14.29 upgrade
path: custom opencode.json files typically had the pre-v1.14.29
command ['python3', '-m', 'mempalace.mcp_server'] which worked with
the old pip install but fails silently after the uv-tool migration
because system python3 cannot import from the venv. Opencode surfaced
this as 'MCP error -32000: connection closed'.
- generate-config.py now emits ['mempalace-mcp'] and keys its detect
on shutil.which('mempalace-mcp').
- Dockerfile drops 'COPY rootfs/usr/local/bin/' and the chmod of the
wrapper. Build shrinks from 30 to 29 stages.
- rootfs/usr/local/bin/ removed entirely.
- Smoke test asserts /usr/local/bin/mempalace-mcp is executable and
prints its symlink target.
- README's MemPalace section shows ['mempalace-mcp'] and explicitly
warns against the old pattern with the observed failure mode.
- CHANGELOG adds a v1.14.29c entry.
|
||
|
|
113c9f0bb0 |
Infrastructure pass: CI smoke tests, floating versions, chown sentinel, generate-config script
Main changes: - Extract opencode.json generation from entrypoint-user.sh into a standalone Python script (rootfs/usr/local/lib/opencode-devbox/ generate-config.py). Preserves the never-overwrite-existing-config guarantee. Cuts entrypoint-user.sh from 176 to 97 lines. - Install MemPalace via 'uv tool install' into an isolated venv at /opt/uv-tools/mempalace/ with a /usr/local/bin/mempalace-mcp-server wrapper, replacing the 'pip install --break-system-packages' escape hatch. The wrapper is what generate-config.py references in the auto-generated opencode.json. Also fix 'mempalace init' in entrypoint-user.sh to use --yes so first-start initialization isn't interactive (this used to hang or print prompts into the user's terminal). Gated by INSTALL_MEMPALACE build arg (default true) so users who don't need AI memory can shave ~300 MB. - Sentinel-file pattern in entrypoint.sh volume-ownership loop: write .devbox-owner after a successful chown -R, skip the recursive walk on subsequent starts when the sentinel matches FINAL_UID:FINAL_GID. Cuts multi-second startup costs to milliseconds on large volumes (nvim plugins, palace data). UID changes still trigger a full chown. - Float all GitHub/Gitea-hosted binary versions: gosu, fzf, git-lfs, neovim, bat, eza, zoxide, uv, gitea-mcp now default to 'latest' and resolve the newest upstream release at build time via the /releases/ latest redirect. Go (go.dev JSON feed) and oh-my-opencode-slim (npm @latest) likewise. Intentional pins still in place: OPENCODE_VERSION, NODE_VERSION=22, DEBIAN_VERSION=trixie-slim. Each *_VERSION ARG accepts an explicit value to lock a specific version when needed. - New scripts/smoke-test.sh verifies binary presence, opencode startup, entrypoint user drop, generate-config idempotency, bun's presence- per-variant, and image size against thresholds (2500 MB base, 3000 MB OMOS). Prints resolved component versions as its first step so CI logs always record what got baked into a given image. - New .gitea/workflows/validate.yml runs on push to main and PRs: single-arch amd64 build, smoke test, DOCKER_HUB.md sync check. Tag- triggered docker-publish.yml now smoke-tests each variant on amd64 before the full multi-arch push. - scripts/generate-dockerhub-md.py auto-generates DOCKER_HUB.md from README.md using explicit SECTION_RULES. --check mode fails CI when the committed file is out of sync. Enforces the 25 kB Docker Hub limit. Adding a new README section forces an explicit keep/drop/ replace decision. - Remove dead INSTALL_PYTHON build arg (was a no-op since mempalace added python3 unconditionally). |
||
|
|
c34cf3641b |
Add devbox-shell bridge line to baked .bash_aliases
If the host bind-mounts ~/.config/devbox-shell/ into the container (the directory-mount pattern that avoids single-file inode breakage), the container needs a bridge line in .bashrc or .bash_aliases to source the mounted file. Previously this bridge had to be re-added manually after every --force-recreate because it lived in the container's writable layer. Baking it into the skel .bash_aliases makes it automatic: every fresh container sources ~/.config/devbox-shell/bash_aliases if it exists, with zero manual steps. Hosts that don't use the devbox-shell pattern are unaffected — the [ -r ... ] test silently skips. |
||
|
|
9bb93025f0 |
Fix [devbox] prompt marker disappearing after 'exec bash'
The previous guard used an exported DEVBOX_PS1_SET env var to avoid double-prefixing on re-source. But env vars survive 'exec bash' while PS1 does not — a new bash rebuilds PS1 from .bashrc. Result: the guard saw DEVBOX_PS1_SET=1, skipped the prefix, and the new shell ran with bare PS1 (no [devbox] marker). Replace the env-var guard with a substring check on PS1 itself. If PS1 already contains '[devbox]' we skip, otherwise we prepend. Correct in all three cases: first shell (PS1 has no marker → add), exec bash (fresh PS1 has no marker → add), re-source within same shell (PS1 still has marker → skip, no doubling). |
||
|
|
84b5ed4412 |
Fix PROMPT_COMMAND collision with zoxide causing ';;' parse error
v1.14.19c installed 'history -a; ' at the start of PROMPT_COMMAND
before zoxide's init ran. Zoxide's init uses ';' as its separator
when prepending __zoxide_hook, producing 'history -a;;__zoxide_hook'.
Every interactive prompt then emitted:
bash: PROMPT_COMMAND: syntax error near unexpected token ';;'
History flushing still worked (the 'history -a' half parsed fine),
but the error spam made the shell feel broken.
Fix by moving the history-flush PROMPT_COMMAND assignment AFTER
zoxide's init, and using a newline separator (via ${PROMPT_COMMAND:+...}
parameter expansion) so there's no semicolon involved at all. Each
PROMPT_COMMAND line runs as its own statement, no parsing contention.
Known upstream issue: https://github.com/ajeetdsouza/zoxide/issues/722
|
||
|
|
e4063b5559 |
Persist bash history and bake shell quality-of-life defaults
Two changes that address a longstanding frustration: bash history is lost on every container recreate, and the container's ~/.bashrc and ~/.inputrc are stock Debian (no history tuning, no prefix search on arrow keys, no integrations). Added a named volume 'devbox-shell-history' mounted at ~/.cache/bash with HISTFILE pointing there; history now survives 'docker compose up --force-recreate'. The volume is added to both docker-compose.yml and docker-compose.shared.yml, and ~/.cache/bash is registered in the entrypoint ownership-fix loop per the AGENTS.md convention. Baked rootfs/home/developer/.bash_aliases (sourced automatically by Debian's default ~/.bashrc) and rootfs/home/developer/.inputrc into the image. They give new containers: 100k-entry timestamped dedup history with per-prompt flush, Up/Down arrow prefix history search, case-insensitive coloured completion, aliases that prefer eza and bat when present, git shortcuts, interactive rm/mv/cp, zoxide and fzf (via 'fzf --bash') integration, and a [devbox] prompt marker. The fzf integration uses 'fzf --bash' because we install fzf from GitHub releases, not apt — the apt-path key-bindings aren't present. Users who prefer their host's own shell config can uncomment two commented bind-mount lines in docker-compose.yml to shadow the baked defaults. |