v1.8.1
88 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
53b41cd76b |
smoke: assert the pi stage $HOME-relative, and add a smoke_only dispatch
Lint / actionlint (push) Successful in 16s
Lint / hadolint (push) Successful in 13s
Publish Docker Image / resolve-versions (push) Successful in 10s
Publish Docker Image / base-decide (push) Successful in 16s
Publish Docker Image / build-base (push) Has been skipped
Publish Docker Image / smoke-studio (push) Successful in 5m20s
Publish Docker Image / smoke (push) Successful in 14m40s
Publish Docker Image / build-variant-studio (push) Successful in 21m51s
Publish Docker Image / build-variant (push) Successful in 15m59s
Publish Docker Image / update-description (push) Successful in 6s
Publish Docker Image / promote-base-latest (push) Successful in 17s
v1.8.0 never shipped: smoke (67/68) and smoke-studio (70/71) each failed the
same single assertion, so build-variant and everything downstream skipped and
latest stayed on v1.7.0.
The assertion was wrong, not the product. It grepped for a literal
stage=/home/developer/.mempalace/pi-stage/, but run() invokes
docker run --rm --entrypoint="" "$IMAGE" sh -c "$cmd"
and neither Dockerfile sets USER or ENV HOME — the published base image config
has no HOME at all; it is normally set by entrypoint-user.sh, which
--entrypoint="" skips on purpose. So the assertion executed as root with
HOME=/root, mempalace-pi-session correctly resolved
stage=/root/.mempalace/pi-stage/... (the stage is $HOME-relative by design), and
the literal grep could never match under any circumstances.
The tell was one line below in the log: the sibling assertion "pi stage follows
MEMPALACE_PALACE_PATH" PASSED, because it sets the variable explicitly and never
consults HOME. Default fails + explicit passes = wrong HOME, not broken staging.
Now asserts the invariant actually intended — the stage sits beside the resolved
palace, sharing its lifetime — which is user-independent:
case "$stage" in "stage=$HOME/.mempalace/pi-stage/"*) exit 0 ;; *) exit 1 ;; esac
$HOME is expanded by the container's own shell, so it holds as root, as
developer, or under any future user. Verified all four cases against the real
bin/mempalace-pi-session by extracting the committed assertion bodies and
running them under sh -c: virgin HOME -> exit 0; HOME=/home/developer -> exit 0;
MEMPALACE_PI_STAGE pinned to a .cache path -> exit 1 (the regression this
assertion exists to catch still fails it); developer-identity companion -> 0.
Added that companion assertion, "pi stage is palace-adjacent for the developer
user", which covers the deployment-specific path properly by SUPPLYING
HOME=/home/developer rather than assuming it.
Why this took a release to surface: docker-publish.yml triggers on push tags v*
only. The assertion was added on a push to main (
|
||
|
|
29b62093f0 |
v1.8.0: bump pi 0.84.1 → 0.84.2 and pi-atelier v0.8.0 → v0.8.1, audited
Publish Docker Image / resolve-versions (push) Successful in 12s
Lint / actionlint (push) Successful in 23s
Publish Docker Image / base-decide (push) Successful in 8s
Lint / hadolint (push) Successful in 1m20s
Publish Docker Image / build-base (push) Successful in 41m34s
Publish Docker Image / smoke (push) Failing after 4m41s
Publish Docker Image / build-variant (push) Has been skipped
Publish Docker Image / promote-base-latest (push) Has been skipped
Publish Docker Image / update-description (push) Has been skipped
Publish Docker Image / smoke-studio (push) Failing after 8m22s
Publish Docker Image / build-variant-studio (push) Has been skipped
pi 0.84.2 closes the Amazon Bedrock tool-argument poison pill that v1.6.4 recorded as "Not fixed upstream". pi-ai 0.84.2 adds a recursive sanitizeBedrockDocument() and applies it at exactly the site that entry named (dist/api/bedrock-converse-stream.js, line 692 -> 704; upstream PR #7882): - toolUse: { ..., input: c.arguments }, + toolUse: { ..., input: sanitizeBedrockDocument(c.arguments) }, It strips object members whose key is the empty string, recursing through arrays and nested objects. It runs at request-build time, so it covers the live turn and a resume alike: a session already bricked by an empty-key tool argument now replays instead of dying on a Bedrock ValidationException. pi-session-repair is therefore no longer the recovery path on this image -- it stays useful for older images and for inspection, since the fix sanitises what is sent, not what was recorded. Bumping PI_VERSION is the ONLY way to get that fix: pi publishes an npm-shrinkwrap.json, so pi 0.84.1 pins pi-ai to exactly 0.84.1 even though its package.json range (^0.84.1) would admit 0.84.2. Transitive upstream fixes never leak into this image. pi-atelier v0.8.1 is the matching companion -- both sides changed fullscreen input handling within three days. Its only code change (src/split-pane.ts) stops atelier writing its own 1002h/1006h pair around a sidebar resize under pi's fullscreen renderer, which had been tearing down the mouse reporting pi itself enabled and leaving the wheel dead. Audited against the surfaces the pin policies name: - session .jsonl: identical migrateV1ToV2/migrateV2ToV3 ladder - node engine floor: unchanged >=22.19.0 (image ships 22.23.2) - atelier's three private couplings all intact in pi-tui 0.84.2 -- class TuiAltScreen extends TuiBase (detected by constructor NAME, so a rename would fail silently), inputListeners still `new Set()` at the same line 103, own render(width) descriptor still present - pi's mouse sequences byte-identical between 0.84.1 and 0.84.2 - atelier metadata unchanged: engines >=22.19.0, peerDeps >=0.80.7, zero runtime deps, so the "no npm install step" note holds Not proven by execution: CI smoke does not drive the TUI, and 0.84.2 adds a focused fullscreen search overlay that also participates in input handling. The pairing is reasoned from the diffs. Worth an alt+a plus a sidebar resize and wheel scroll in fullscreen on first use. |
||
|
|
cbd7cf5c67 |
entrypoint: announce the "remote palace, no inbox" skip instead of vanishing
When MEMPALACE_REMOTE_URL is set but MEMPALACE_PI_SSH_TARGET is not, the feeder has nowhere to ship staged transcripts, so skipping is correct. The problem was that the branch was a bare `:` AND the skip happens before the subshell that writes ~/.pi/agent/mempalace-catchup.log -- so a container in that state contributed nothing to the palace and left no artifact at all, not even an empty log, to explain why. It is indistinguishable from a healthy run that had nothing to file, which is the worst property a memory system can have: the failure looks exactly like success. Surfaced while flipping the first client onto the shared palace, where this is the single most likely way to end up quietly memory-less -- the palace is the only thing that survives a container recreate. The notice goes to both the container start output (docker logs) and the log path anyone debugging looks at first. It names both variables, says what still works (MCP tools read/write the shared palace; only this container's own conversations go nowhere), and points at MEMPALACE_FEED=0 for anyone who meant it -- "HTTPS first, mining later" is a documented interim state, so the notice has to be silenceable without being ignorable. Guarded against becoming a startup failure. mkdir -p in a branch that previously touched no filesystem is a new risk: an unwritable ~/.pi (root-owned volume, a classic Docker accident) fails under set -e and would abort the entire entrypoint. It now degrades to stdout-only. Verified all five paths by executing the extracted block under `set -euo pipefail`: the trap prints and writes the log; unwritable ~/.pi still exits 0 and still prints; MEMPALACE_FEED=0 stays completely silent (no message, no file); and both normal-remote and local mode still background the feeder with no notice. Two smoke assertions guard against a regression to the silent no-op. They test the entrypoint as shipped in the image rather than behaviour, because this branch only runs at container start and a `docker run` one-shot cannot reach it. entrypoint-user.sh is COPY'd in Dockerfile.base, so this rides the base rebuild the Unreleased feeder work already needs. |
||
|
|
7c00dd6001 |
mempalace: drop the stage ENV pin, fix the shared-server compose
The feeder now defaults to <palace-root>/pi-stage upstream, so pinning
MEMPALACE_PI_STAGE into ~/.pi here is unnecessary -- and was actively wrong. It
created a second convention that could still diverge from the palace: keep the
devbox-palace volume, drop devbox-pi-config, and a scoped `mempalace sync`
prunes every conversation drawer, because dedup keys on the staged path. Both
the ENV and the entrypoint export are gone; a comment explains why adding one
back re-introduces the split it was meant to fix.
docker-compose.mempalace.yml was broken on mempalace 3.6.0 in both directions:
- `--host 0.0.0.0` with no token in the environment makes the server refuse
to start, crash-looping under `restart: unless-stopped`.
- Supply a token and the healthcheck's unauthenticated `tools/list` POST 401s,
marking a perfectly healthy server unhealthy forever.
Now the token is required via ${MEMPALACE_REMOTE_TOKEN:?...} so it fails fast at
`docker compose up` with a readable message, and the healthcheck probes the
deliberately token-free /healthz. The "no authentication of its own" security
note has been stale since 3.6.0 and is replaced with the actual posture
(bearer token + Host pin + Origin allowlist), including why browser-shaped auth
must not be put in front of it.
Dockerfile.base: mempalace-pi-session symlinked onto PATH, with a build-time
`--help` check so a broken feeder fails the image build rather than the first
session.
smoke-test: assert the stage resolves beside the palace (default, and following
$MEMPALACE_PALACE_PATH) instead of asserting the removed ENV pin. The two
behavioural guards -- a synthetic session that must be captured, an abandoned
one that must not be -- are unchanged.
.env.example: recommend `mempalace serve` on the docker0 gateway rather than
`mempalace-mcp --transport http --host 0.0.0.0`, with the two binds to avoid.
|
||
|
|
43cd6e22f2 |
v1.7.0: bundle pi-atelier at a pinned tag; pin pi to an audited 0.84.1
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. |
||
|
|
572430237f |
Bump mempalace pin 3.5.0 → 3.6.0 (lockstep with opencode-devbox v2.9.0)
3.6.0 (2026-07-17, PyPI latest) is additive/reliability only: secure
`mempalace serve` remote mode, optional Milvus backend, atomic KG
supersede(), conversation chronology, mining exclusions, plus recovery and
locking fixes.
Reviewed for MCP tool-schema changes before bumping — that being the exact
regression class this pin exists to catch, after an unpinned install once
swept in the broken 3.3.x/3.4.0 diary_write schema. There are none, and
nothing touches diary_write, so the perl workaround removed in v1.2.2 stays
removed.
Two fixes matter for how this image uses mempalace: read-only mode now covers
checkpoint + delete_by_source in _MUTATING_TOOLS (#1930), and agent
attribution is preserved in mempalace_checkpoint (#2023/#2034) — the latter
because the diary protocol relies on per-agent attribution.
Also adds a CHANGELOG Unreleased block that backfills the per-variant image
description labels (
|
||
|
|
e86e5df327 |
release: v1.6.4 — fork tool actually loads, pi 0.83.0 audited clean
Publish Docker Image / resolve-versions (push) Successful in 5s
Lint / hadolint (push) Successful in 13s
Lint / actionlint (push) Successful in 15s
Publish Docker Image / base-decide (push) Successful in 7s
Publish Docker Image / build-base (push) Successful in 41m24s
Publish Docker Image / smoke-studio (push) Successful in 5m11s
Publish Docker Image / smoke (push) Successful in 12m23s
Publish Docker Image / build-variant-studio (push) Successful in 22m46s
Publish Docker Image / build-variant (push) Successful in 22m58s
Publish Docker Image / update-description (push) Successful in 6s
Publish Docker Image / promote-base-latest (push) Successful in 13s
Headline is the fork-guard fix (the `fork` tool had never loaded since v1.0.0 because the registration guard grepped the whole settings.json and matched the pi-fork *config block* the template merge itself plants). pi 0.82.1 -> 0.83.0 is a clean hop with no intermediates. 0.83.0 carries an upstream Breaking Change (bundled TypeBox 1.1.38 -> 1.3.7, deprecated APIs removed) that cannot reach us: pi-fork vendors @sinclair/typebox (a different package name), obsmem's use is type-only, studio and atelier don't use TypeBox. Verified from source rather than from the audit narrative: extension-facing dist/core/extensions/*.d.ts declarations diff clean between the two versions, all six CLI flags pi-fork passes to child processes are present, and SESSION_VERSION is 3 in both so transcript tooling is unaffected. No PI_VERSION pin needed. Recorded for the release notes: the Bedrock poison pill is NOT fixed in pi-ai 0.83.0 (unsanitised input: c.arguments moved 634 -> 644), so pi-session-repair stays the recovery path. |
||
|
|
fa04d2083d |
docs(rootfs): re-sync pi-extensions skill snapshot (fork boundary mechanism)
Vendored floor snapshot re-synced from pi-extensions 98eb07b, which documents the mechanism behind fork boundary violations (full parent-transcript inheritance via index.ts:47) plus the corrected claims about tool restriction and narrative invention. CI resolves PI_EXTENSIONS_REF from main HEAD, so a normal build ships the package-owned copy; this keeps the committed floor identical so scripts/smoke-test.sh's cmp assertion holds either way. |
||
|
|
8248688d58 |
fix(entrypoint,tests): register pi-fork — guard matched its own config block
The `pi install /opt/<pkg>` loop in entrypoint-user.sh guarded on a whole-file substring grep of ~/.pi/agent/settings.json. settings.example.json ships a top-level "pi-fork" CONFIG block (fork effort profiles, pi-toolkit adb6907, 2026-06-17), so `grep -q pi-fork settings.json` matched the config key itself and `pi install /opt/pi-fork` never ran — on fresh or preserved volumes. The `fork` tool has therefore been absent since v1.0.0. The non-destructive template merge runs earlier in the same startup than the install loop, so the mechanism that delivers new template keys to an old volume is what plants the string that defeats the guard. pi-observational- memory and pi-studio escaped only by luck: the template key is "observational-memory" (no pi- prefix) and there is no studio block. Guard now inspects the `packages` array via jq, with a grep fallback on the stored `.../opt/<name>"` path form, which a config key can never produce. Existing volumes self-heal on the next container start. Both test suites asserted the bug as green — smoke-test.sh:244 and recreate-sanity-check.sh:204 used the same whole-file grep, so "pi-fork registered (fork tool)" passed on every build and recreate while the tool was missing. Both now assert against packages[] with the entrypoint's predicate, labels say packages[], and the smoke readiness wait loop uses the array check plus `docker exec -u developer` + $HOME instead of a hard-coded /home/developer path. Evidence: zero `fork` tool calls across all 19 sessions on this volume; the v1.6.3 session that tuned pi-fork.deep to opus-5 was configuring a tool that never loaded. |
||
|
|
e274510fd1 |
docs(changelog): unreleased — settings template defaults to Opus 5
Records the pi-toolkit 926f738 template change (defaultModel + pi-fork deep tier -> eu.anthropic.claude-opus-5). No tag, no build: CI resolves the pi-toolkit SHA from main at build time, so whichever release builds next picks it up. |
||
|
|
9ef7a92dce |
docs(changelog): v1.6.3 — pi 0.81.1→0.82.1
Publish Docker Image / resolve-versions (push) Successful in 7s
Publish Docker Image / base-decide (push) Successful in 15s
Publish Docker Image / build-base (push) Has been skipped
Lint / hadolint (push) Successful in 45s
Lint / actionlint (push) Successful in 15s
Publish Docker Image / smoke (push) Successful in 4m23s
Publish Docker Image / smoke-studio (push) Successful in 7m52s
Publish Docker Image / build-variant (push) Successful in 16m27s
Publish Docker Image / promote-base-latest (push) Successful in 5s
Publish Docker Image / update-description (push) Successful in 7s
Publish Docker Image / build-variant-studio (push) Successful in 21m48s
Pure pi version bump (variant-only rebuild). CI resolves pi@latest=0.82.1 at build. 0.82.0/0.82.1 audited: additive, no breaking changes to the extension execution API (pi-observational-memory) or pi-agent-core types (pi-fork). |
||
|
|
6dfbded9c8 |
release: v1.6.2 — lift smoke size threshold (3500→3800)
Publish Docker Image / resolve-versions (push) Successful in 12s
Lint / hadolint (push) Successful in 7s
Lint / actionlint (push) Successful in 20s
Publish Docker Image / base-decide (push) Successful in 11s
Publish Docker Image / build-base (push) Has been skipped
Publish Docker Image / smoke (push) Successful in 4m42s
Publish Docker Image / smoke-studio (push) Successful in 8m24s
Publish Docker Image / build-variant-studio (push) Successful in 18m8s
Publish Docker Image / build-variant (push) Successful in 25m53s
Publish Docker Image / promote-base-latest (push) Successful in 6s
Publish Docker Image / update-description (push) Successful in 12s
Completes v1.6.1's studio publish. Run 512 shipped v1.6.1 non-studio (3411 MB) cleanly, but smoke-studio failed the size gate at 3574 MB vs the 3500 MB threshold. Threshold was set in v1.0.0 pre-agent-browser (baseline was 3.20 GB local arm64 + 300 MB margin); v1.6.0 baked in agent-browser + Chromium (+~291 MB net) but the threshold was never lifted. v1.6.0 never got to smoke because of the network fault, so nothing surfaced this until v1.6.1's smoke-studio. Bump SIZE_THRESHOLD_MB to 3800 (~225 MB margin above observed studio number, tight enough to still catch a genuine +GB regression). Refresh the comment above the constant with the current baseline + run 512 actuals so future readers know where the number came from. CI-only change; image bytes identical to v1.6.1 except for the manifest's release_tag/source_revision. Not base-affecting. |
||
|
|
d00eef2acb |
docs(changelog): v1.6.1 — pi 0.80.6→0.81.1 (skips 0.81.0)
Publish Docker Image / resolve-versions (push) Successful in 7s
Lint / actionlint (push) Successful in 55s
Lint / hadolint (push) Successful in 9s
Publish Docker Image / base-decide (push) Successful in 55s
Publish Docker Image / build-base (push) Successful in 58m42s
Publish Docker Image / smoke (push) Failing after 4m50s
Publish Docker Image / build-variant (push) Has been skipped
Publish Docker Image / promote-base-latest (push) Has been skipped
Publish Docker Image / update-description (push) Has been skipped
Publish Docker Image / smoke-studio (push) Failing after 13m22s
Publish Docker Image / build-variant-studio (push) Has been skipped
v1.6.0 was tagged 2026-07-17 but never reached Docker Hub (variant publish blocked by a site-network SYN-drop fault, since fixed). Cut v1.6.1 to land v1.6.0's content (agent-browser + pi-devbox-version) alongside a first pi bump since v1.5.0. 0.81.0 is skipped deliberately: it removed the default stream fallback for extensions using the pre-0.81 pi-agent-core API, which pi-observational-memory relies on via agentLoop + stream.result(). 0.81.1 restored the fallback (earendil-works/pi#6915), so 0.81.1 — but not 0.81.0 — is a safe drop-in. pi-fork only imports types; unaffected. Audit of 0.80.7–0.81.1 vs the two baked extensions and the base image: no breaking changes affect pi-devbox. Node engine bumped to >=22.19.0 in 0.81.0 (nodesource 22.x currently 22.23.1, so no engine bump needed). Base-affecting via the npm install line, so base-<hash> rebuilds. |
||
|
|
649fc44c5b |
chore(release): v1.6.0
Lint / hadolint (push) Failing after 22s
Lint / actionlint (push) Successful in 26s
Publish Docker Image / resolve-versions (push) Successful in 9s
Publish Docker Image / base-decide (push) Successful in 16s
Publish Docker Image / build-base (push) Failing after 25m26s
Publish Docker Image / smoke (push) Has been skipped
Publish Docker Image / smoke-studio (push) Has been skipped
Publish Docker Image / build-variant-studio (push) Has been skipped
Publish Docker Image / build-variant (push) Has been skipped
Publish Docker Image / promote-base-latest (push) Has been skipped
Publish Docker Image / update-description (push) Has been skipped
Roll the unreleased changes into v1.6.0 (minor — significant base addition: agent-browser + headless Chromium baked into every variant for browser automation/front-end verification). Also includes the pi-devbox-version command and the bundled pi-toolkit sonnet-5 template bump. No pi bump — CI resolves latest pi from npm at build time (verified: 0.80.6→0.80.10 has no breaking changes affecting pi-devbox). |
||
|
|
89a8dc7fab |
perf(base): trim agent-browser footprint ~960MB→~625MB before release
Size concern ahead of the v1.6.0 base rebuild. agent-browser drives the full chrome (verified headless: open/title/eval with the headless_shell removed), so Playwright's chromium_headless_shell-* build is dead weight — drop it (~334MB), and clean apt/npm caches in-layer. Net browser footprint ~625MB/arch. CI disk is otherwise fine: build-base's 'Reclaim runner disk' step frees ~20-30GB (hostedtoolcache/dotnet/android/jvm) + docker prune before buildx. hadolint clean. |
||
|
|
6625d66f3a |
docs(agents): point the global AGENTS.md managed block at agent-browser
Discoverability follow-up to baking agent-browser into the base: agents won't reach for a browser they don't know they have (the exact gap that made this capability easy to miss). Add a short pointer section to the pi-devbox managed block — capability, the preset AGENT_BROWSER_EXECUTABLE_PATH, and `agent-browser skills get core --full` for the command set. Pointer only; depth stays in the skill. rootfs change → folds into the same base-<hash> rebuild. CHANGELOG note updated. |
||
|
|
8caafc3f49 |
base: bake agent-browser + Playwright Chromium (headless browsing, all variants)
Gives the agent a real browser it can drive so front-end work involving live DOM/WebGL can be VERIFIED, not guessed. The agent-browser skill (from the skillset repo) was a no-op without the binary; it now works out of the box. - agent-browser CLI (standalone Rust, ships no browser) via npm, prefixed NPM_CONFIG_PREFIX=/usr so it survives the ~/.pi/npm-global volume. - Chromium fetched with 'playwright install --with-deps chromium' into PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/ms-playwright — a system path that the /home/developer volume can't shadow (unlike agent-browser's own ~/.agent-browser/browsers default, which WOULD vanish on recreate). - Stable /usr/local/bin/agent-chrome symlink, exported as AGENT_BROWSER_EXECUTABLE_PATH, insulates the ENV from Playwright's per-version chromium-<rev> dir name. Verified end-to-end (this session): agent-browser drives the baked Chromium headless (open + title + screenshot + eval into a WebGL SPA); doctor launch test passes in ~0.5s. Debian trixie --with-deps resolution verified (exit 0; t64 lib renames handled). hadolint clean; check-base-hash OK (only *_VERSION args added). Cost ~960 MB (Chromium + headless shell). Base-affecting → rebuilds base-<hash> on next release. |
||
|
|
fb49828826 |
base: add pi-devbox-version command + startup banner
Wraps /etc/pi-devbox/build-manifest.json (already written at docker-build time in Dockerfile.variant) into a human-readable summary instead of requiring users to know the manifest path and pipe it through jq themselves. - rootfs/usr/local/bin/pi-devbox-version: human (default) / --json / --quiet output modes. Also flags live drift — compares the baked pi_version against the actually-running `pi --version` and warns on mismatch rather than trusting the manifest blindly (same ground-truth philosophy as the manifest generation itself). Exits 1 with a short stderr notice on images built before the manifest existed, instead of failing silently. - entrypoint-user.sh: calls it as the very first line. CMD is `bash -l` with tty:true in compose, so this banner lands directly above the first prompt on container start — no separate motd/bashrc hook needed (deliberately not wired into .bash_aliases, which would reprint on every docker exec -it). - Dockerfile.base: COPY + chmod, same pattern as dot-watch/studio-expose. - scripts/smoke-test.sh: 4 new checks (binary present+executable, human output has release tag, --json round-trips the manifest, --quiet is a single line). - README.md / AGENTS.md / CHANGELOG.md updated. |
||
|
|
02be95ac1f | docs(changelog): note bundled pi-toolkit sonnet-5 template bump (Unreleased) | ||
|
|
d68674d11e |
chore(release): v1.5.0
Publish Docker Image / resolve-versions (push) Successful in 12s
Publish Docker Image / base-decide (push) Successful in 9s
Lint / hadolint (push) Successful in 12s
Lint / actionlint (push) Successful in 13s
Publish Docker Image / build-base (push) Successful in 43m20s
Publish Docker Image / smoke (push) Successful in 4m20s
Publish Docker Image / smoke-studio (push) Successful in 7m2s
Publish Docker Image / build-variant (push) Successful in 16m18s
Publish Docker Image / update-description (push) Successful in 6s
Publish Docker Image / promote-base-latest (push) Successful in 14s
Publish Docker Image / build-variant-studio (push) Successful in 17m47s
Roll the 7 unreleased commits since v1.4.0 into v1.5.0 (minor — significant base additions: readable Neovim true-colour, broad terminal terminfo support). Also includes: typst PDF template font fix, .claude gitignore seed, pi-studio semver-tag pin + version label, and repo hygiene (LICENSE, THIRD_PARTY.md, .dockerignore, hadolint lint, IDEAS backlog). No pi bump — CI resolves latest pi from npm at build time as usual. |
||
|
|
8c27894cf2 |
base: support modern terminals (ncurses-term + xterm-ghostty alias)
The base only shipped ncurses-base (xterm-256color, tmux), so SSHing in from WezTerm/Alacritty/foot/Ghostty degraded to a dumb TERM fallback. Following the maintainer's ansible common role: - Dockerfile.base: install ncurses-term (terminfo for wezterm, alacritty, foot, st, base ghostty entry, and many more). - rootfs/.../terminfo-src/ghostty.terminfo: thin xterm-ghostty alias (use=ghostty) — Ghostty connects as TERM=xterm-ghostty, which no distro packages. Compiled into the system db with 'tic -x'; build asserts it resolved via infocmp. - kitty (xterm-kitty) already covered by kitty-terminfo; iTerm2 uses xterm-256color (ncurses-base). - smoke-test: assert ncurses-term emulators + xterm-ghostty alias resolve. Validated end-to-end in a throwaway container: ncurses-term brings the entries, the alias compiles and equals the ghostty capability set. hadolint clean, bash -n OK. Base-affecting, rebuilds base-<hash>. No tag. |
||
|
|
291ae5345e |
repo: add LICENSE, THIRD_PARTY.md, .dockerignore, hadolint lint, IDEAS backlog
Repo/CI hygiene batch (none base-affecting; image contents unchanged): - LICENSE: actual MIT file (repo previously declared MIT only in prose). - THIRD_PARTY.md: notes bundled software + licenses (pi/pi-fork/pi-obsmem/ pi-studio MIT, gosu Apache-2.0, Debian packages under their own terms). - .dockerignore: trims build context to what the Dockerfiles COPY (rootfs/ + entrypoint*.sh); keeps .git/docs/scripts/compose out. Verified it excludes none of the required COPY sources. - lint.yml: new hadolint job (pinned v2.14.0) lints both Dockerfiles; .hadolint.yaml grandfathers deliberate choices (DL3008/DL3016/DL4006/DL3003/ SC2086, mirroring the shellcheck excludes), fails on anything new at warning+. Verified hadolint exit 0 and the repo shell-guard passes with the new job. - IDEAS.md: parks deferred follow-ups (SHA-pin actions, trivy, buildx SBOM/ provenance, Makefile, renovate). - README/DOCKER_HUB License sections now link LICENSE + THIRD_PARTY.md. No tag. |
||
|
|
38d8832d34 |
ci: record pi-studio version as image label
Lint workflows / actionlint (push) Successful in 1m16s
Adds se.jordbo.pi-devbox.pi-studio-version (e.g. v0.9.36) alongside the existing SHA label, so 'docker inspect' shows the human-readable version. Plumbing: resolve-versions exposes studio_tag output -> both studio build steps pass --build-arg PI_STUDIO_VERSION -> Dockerfile.variant declares ARG PI_STUDIO_VERSION=none and emits the LABEL. Studio-variant only. Validated: yq parse OK, resolve run-script bash -n OK. No tag. |
||
|
|
32586f19e7 |
ci: pin pi-studio to newest semver tag, not main HEAD
Lint workflows / actionlint (push) Successful in 23s
Upstream omaclaren/pi-studio stopped publishing GitHub Releases at v0.5.55 but keeps tagging every version (v0.9.36 now) and pushing to main. Tracking main HEAD risked baking half-finished commits that land after a tag. resolve-versions now lists all tags via a single git ls-remote (the REST tags API paginates at 100 and the repo has >140 tags, so a single page can miss the newest), picks the highest X.Y.Z with sort -V (pre-releases excluded), and peels it to a commit SHA for PI_STUDIO_REF. SHA (not moving tag) keeps cache-busting + reproducibility; require_sha still enforced. Studio-variant only, not base-affecting. No change to the resolved commit today (v0.9.36 == current main HEAD). Validated: yq parse OK, bash -n OK, live git ls-remote -> v0.9.36 -> 2ef38ef. No tag. |
||
|
|
aaf1be0bcb |
base: readable Neovim colours out of the box (termguicolors + kitty-terminfo)
Lint workflows / actionlint (push) Successful in 22s
Vanilla Neovim fell back to a 256-colour palette over ssh/kitty and rendered strings/comments in a muddy, low-contrast colour. Fix, all base-affecting: - rootfs/etc/xdg/nvim/sysinit.vim: system vimrc enabling termguicolors. Loads for every user before any personal ~/.config/nvim; overridable per-user. - Dockerfile.base: install kitty-terminfo (TERM=xterm-kitty understood; lets Neovim auto-detect true colour) and set ENV COLORTERM=truecolor. - smoke-test.sh: assert xterm-kitty terminfo present and nvim tgc default on. - CHANGELOG (Unreleased/Added) + README editor note. No tag — lands on the next base-<hash> rebuild. |
||
|
|
92212fa447 |
base: seed global gitignore with .claude/settings.local.json
Lint workflows / actionlint (push) Successful in 23s
Claude Code's per-machine local settings can carry credentials and should never be committed. Add the pattern to the seeded ~/.gitignore_global so fresh containers match a host global that already ignores it. Existing containers are unaffected (seed copied only when absent). Base-affecting; rebuilds base-<hash>. |
||
|
|
3d46c6615e |
fix(base): default pandoc typst template font so PDF export works without -V mainfont
Lint workflows / actionlint (push) Successful in 21s
pandoc's bundled typst template defaults the document font to an empty tuple (font: ()), so a naked `pandoc --pdf-engine=typst` fails with "font fallback list must not be empty". Patch the template default to Libertinus Serif (typst's own bundled default) at build time so PDF export works out of the box. Document usage in README and note the fix in CHANGELOG (Unreleased). Base-affecting. |
||
|
|
fa6e9dc9d6 |
release: v1.4.0 — typst PDF engine + host SSH startup check
Publish Docker Image / resolve-versions (push) Successful in 6s
Publish Docker Image / base-decide (push) Successful in 9s
Lint workflows / actionlint (push) Successful in 1m9s
Publish Docker Image / build-base (push) Successful in 34m32s
Publish Docker Image / smoke-studio (push) Successful in 4m16s
Publish Docker Image / smoke (push) Successful in 10m52s
Publish Docker Image / build-variant-studio (push) Successful in 18m1s
Publish Docker Image / build-variant (push) Successful in 18m51s
Publish Docker Image / promote-base-latest (push) Successful in 11s
Publish Docker Image / update-description (push) Successful in 18s
Finalize the Unreleased batch as v1.4.0 (minor — significant base additions). Base rebuilds (Dockerfile.base for typst/xz-utils; .bash_aliases for the SSH check). pi auto-resolves latest (0.80.3 -> 0.80.6); mempalace stays 3.5.0 (current). |
||
|
|
bd0627a557 |
docs: note host SSH startup check in CHANGELOG Unreleased
Lint workflows / actionlint (push) Successful in 1m18s
|
||
|
|
67da05b99b |
feat(base): ship typst as lightweight pandoc PDF engine
Lint workflows / actionlint (push) Successful in 15s
pandoc has been in the base since v1.0.0 but only as a front-end; PDF export (studio_export_pdf / pandoc -o out.pdf) failed with 'xelatex not found' because no back-end engine was installed. Ship typst (~30 MB static Rust binary, no LaTeX) as the default engine via `pandoc --pdf-engine=typst`, chosen over a ~600 MB TeX Live install. texlive-xetex remains the higher-fidelity install-on-demand fallback. - Dockerfile.base: install typst (latest GitHub-release idiom, pin via TYPST_VERSION); add xz-utils (typst ships .tar.xz); bump BASE_REBUILD_DATE. Lands in base-<hash>. - smoke-test.sh: verify typst + a real pandoc --pdf-engine=typst render. - README/AGENTS/CHANGELOG: typst now shipped (supersedes the planned :latest-studio-tex variant). No tag pushed — CI build intentionally deferred. |
||
|
|
6002c6299d |
release: v1.3.0 — shared/external MemPalace + nano/micro editors + CI lint
Publish Docker Image / resolve-versions (push) Successful in 5s
Publish Docker Image / base-decide (push) Successful in 8s
Lint workflows / actionlint (push) Successful in 19s
Publish Docker Image / build-base (push) Successful in 33m17s
Publish Docker Image / smoke (push) Successful in 3m55s
Publish Docker Image / smoke-studio (push) Successful in 6m50s
Publish Docker Image / build-variant (push) Successful in 16m12s
Publish Docker Image / promote-base-latest (push) Successful in 9s
Publish Docker Image / update-description (push) Successful in 6s
Publish Docker Image / build-variant-studio (push) Successful in 20m50s
Promotes the Unreleased block to v1.3.0. Bundled contents: - feat: shared/external MemPalace — mempalace.ts bridge honours MEMPALACE_REMOTE_URL; adds docker-compose.mempalace.yml. - feat: nano + micro non-modal editors (Dockerfile.base → base rebuild). - ci: lint.yml (sh-vs-bash guard + actionlint/shellcheck), docker-publish.yml bash defaults, promote-base-latest shell fix. pi stays 0.80.3 (== npm latest). Base rebuilds (mempalace-toolkit ref advanced + Dockerfile.base nano/micro), so the new bridge + editors land in base-<hash>. |
||
|
|
d73bf2e9d3 |
feat: optional shared/external MemPalace via MEMPALACE_REMOTE_URL
Lint workflows / actionlint (push) Successful in 21s
Wire the shared-palace option (implemented in mempalace-toolkit's mempalace.ts) into the container: - .env.example: document MEMPALACE_REMOTE_URL / MEMPALACE_REMOTE_TOKEN (env_file-only, per this repo's convention). - docker-compose.mempalace.yml: optional shared server (mempalace-mcp --transport http), loopback-bound by default. - docker-compose.yml: local-vs-external note on the palace-volume comment. - README + CHANGELOG (Unreleased). |
||
|
|
3a59e15563 |
feat: ship nano + micro (non-modal editors) alongside nvim
Lint workflows / actionlint (push) Successful in 13s
The image shipped only nvim (EDITOR=nvim), a modal vi-style editor. Not everyone is comfortable with vi keybindings, so add both a classic and a modern non-modal option: - nano (apt): ~2.8 MB installed; deps (libc6, libncursesw6, libtinfo6) already present via nvim/less/htop/tmux, so no extra packages pulled in. - micro: ~12 MB single static Go binary from GitHub releases (same pattern as bat/eza/zoxide). Desktop-style keys (Ctrl+S/Ctrl+Q), mouse, syntax highlighting. ARG MICRO_VERSION pins; defaults to latest. Combined ~15 MB (<0.5% of the ~3.2 GB image). EDITOR stays nvim; both new editors are opt-in (export EDITOR=micro | nano). Uses the canonical micro-editor/micro URL because the old zyedidia/micro org rename makes /releases/latest redirect to another /latest, defeating the tag-parsing latest-resolution idiom. Base-image change, so it lands on the next base-<hash> rebuild. Updates README tool table + EDITOR note, CHANGELOG (Unreleased/Added), and smoke-test.sh (nano + micro presence checks). |
||
|
|
26384fe9f1 |
ci: eliminate the sh-vs-bash footgun class (defaults + lint guard)
Lint workflows / actionlint (push) Failing after 34s
Root cause of the recurring 'Illegal option -o pipefail' failures ( |
||
|
|
b33e9dc592 |
fix(ci): promote-base-latest re-tag step needs shell: bash (set -o pipefail)
|
||
|
|
3cdc2069db |
release: v1.2.4 — pi 0.80.2 → 0.80.3; global gitignore, env_file-only secrets, promote-base-latest CI fix
Publish Docker Image / build-variant (push) Successful in 16m16s
Publish Docker Image / promote-base-latest (push) Failing after 4s
Publish Docker Image / build-variant-studio (push) Successful in 17m52s
Publish Docker Image / update-description (push) Successful in 12s
Publish Docker Image / resolve-versions (push) Successful in 1m2s
Publish Docker Image / base-decide (push) Successful in 43s
Publish Docker Image / build-base (push) Successful in 41m46s
Publish Docker Image / smoke (push) Successful in 4m10s
Publish Docker Image / smoke-studio (push) Successful in 6m42s
|
||
|
|
cc53877328 |
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. |
||
|
|
c42b237d30 |
compose: deliver secrets via env_file only (drop environment: passthrough)
Removes GITEA_ACCESS_TOKEN / GITEA_HOST / GITHUB_PERSONAL_ACCESS_TOKEN from the compose environment: block. An environment: entry both overrides env_file AND is interpolated from the host shell, so a stale shell export (e.g. one auto-loaded by an opencode/dotenv hook) silently shadowed the users .env — an updated token never reached the container. Secrets now flow solely via env_file: .env; .env.example already documents every variable. - docker-compose.yml: drop the 3 passthrough lines + explanatory comment - README.md: sync the "basic shape" snippet - CHANGELOG.md: note under Unreleased (no tag bump / unpublished) |
||
|
|
b7197e88b0 |
ci(promote-base-latest): re-point base-latest by digest, not need_build
The gate keyed off need_build=='true', assuming need_build==false meant base-latest was already current. A dry-run dispatch (promote_latest=false) that pre-builds base-<hash> falsifies that: the later tag run sees need_build==false and skipped promotion, leaving base-latest one base behind (observed 2026-06-27, v1.2.3 dry-run-first release). Gate now runs on every tag release / promote dispatch; the no-op optimization moved into the step as a crane digest compare so it re-tags only when base-latest actually differs from the released base-<hash>. Workflow-only change; base hash unaffected (no base rebuild). |
||
|
|
2985d9ade8 |
release: v1.2.3 — mempalace-mcp self-heal (toolkit e12b624)
Publish Docker Image / resolve-versions (push) Successful in 7s
Publish Docker Image / base-decide (push) Successful in 14s
Publish Docker Image / build-base (push) Has been skipped
Publish Docker Image / smoke (push) Successful in 3m30s
Publish Docker Image / smoke-studio (push) Successful in 11m47s
Publish Docker Image / build-variant (push) Successful in 15m48s
Publish Docker Image / promote-base-latest (push) Has been skipped
Publish Docker Image / update-description (push) Successful in 7s
Publish Docker Image / build-variant-studio (push) Successful in 17m28s
Patch release. Headline: mempalace-mcp self-heals instead of latching available=false permanently after a slow virtiofs cold-open. Base image rebuilds via the mempalace-toolkit ref advancing to e12b624 (folded into the base-decide hash). No pi/mempalace version change — pi npm latest is still 0.80.2 (= v1.2.2). Also releases the queued yq (mikefarah Go yq) and mempalace-skill temporal-grounding changes. |
||
|
|
904fe85249 |
skill(mempalace): teach temporal grounding (recreate != new day)
Baked mempalace SKILL.md now instructs agents to establish current date/time and compute the delta against the actual diary/drawer timestamp before using relative terms (yesterday/last week), and explicitly that a container recreate or fresh session is NOT a day boundary (pi-devbox restarts several times a day). Phase 1 wake-up section + anti-pattern bullet. CHANGELOG Unreleased. |
||
|
|
cda488c565 |
base: yq follows latest (was pinned v4.53.3), gate on major v4
Match the repo's latest-following convention (tealdeer/uv/etc.) and keep the container in sync with the Mac's brew yq. smoke-test now asserts mikefarah AND major v4, so a surprise yq v5 fails CI instead of silently breaking provision.sh. Pin still available via --build-arg YQ_VERSION=vX.Y.Z. |
||
|
|
9ab9a28458 |
base: install mikefarah yq (pinned v4.53.3), drop Debian python yq
Debian/Ubuntu `apt install yq` is kislyuk/yq (Python, v3.x), incompatible with the mikefarah v4 syntax the cloud-init repo's provision.sh/deploy.sh require. Replace the apt package with a pinned mikefarah Go binary, mirroring the existing tealdeer ARG (latest-or-pin) pattern, multi-arch amd64/arm64. smoke-test.sh now asserts `yq --version` reports mikefarah so CI catches a regression. CHANGELOG: Unreleased entry. |
||
|
|
d175b31207 |
release: v1.2.2 — pi 0.80.2 + mempalace 3.5.0, drop anyOf workaround
Publish Docker Image / resolve-versions (push) Successful in 8s
Publish Docker Image / base-decide (push) Successful in 11s
Publish Docker Image / build-base (push) Successful in 33m19s
Publish Docker Image / smoke-studio (push) Successful in 4m3s
Publish Docker Image / smoke (push) Successful in 9m51s
Publish Docker Image / build-variant-studio (push) Successful in 17m29s
Publish Docker Image / build-variant (push) Successful in 24m10s
Publish Docker Image / update-description (push) Successful in 10s
Publish Docker Image / promote-base-latest (push) Successful in 14s
- Bump mempalace pin 3.4.0 -> 3.5.0: 3.5.0 carries the upstream fix for the top-level-anyOf diary_write schema (issue #1728 / PR #1717, merged 2026-06-14). Verified against the published 3.5.0 wheel that mcp_server.py now advertises 'required: [agent_name]' with no root-level anyOf. - Remove the Dockerfile.base perl workaround that stripped the anyOf from the installed mcp_server.py — obsolete now the fix is upstream. - pi auto-resolves to npm latest (0.79.10 -> 0.80.2) at build. - CHANGELOG v1.2.2. |
||
|
|
13e67599c4 |
release: v1.2.1 — fallback skills + mempalace directive
Publish Docker Image / smoke-studio (push) Successful in 6m27s
Publish Docker Image / build-variant (push) Successful in 16m16s
Publish Docker Image / update-description (push) Successful in 6s
Publish Docker Image / promote-base-latest (push) Successful in 8s
Publish Docker Image / build-variant-studio (push) Successful in 21m13s
Publish Docker Image / resolve-versions (push) Successful in 6s
Publish Docker Image / base-decide (push) Successful in 7s
Publish Docker Image / build-base (push) Successful in 46m21s
Publish Docker Image / smoke (push) Successful in 3m43s
Bake pi-extensions + mempalace skills into the image (available without a mounted skillset) and add the mempalace session-start proactive-load directive so frequently-recreated containers actually pick the skill up. Closes the fork/recall + mempalace under-utilisation gap. CHANGELOG: [Unreleased] -> v1.2.1. |
||
|
|
7551947466 |
feat(skills): add mempalace proactive-load directive for containers
Baking the mempalace fallback skill fixed *availability*, but mempalace had no proactive-load directive anywhere (pi-toolkit's global AGENTS.md only points to pi-extensions), so a new container would still surface it only via description-matching — the same under-utilisation the pi-extensions directive was created to fix. Add a session-start pointer to the pi-devbox managed AGENTS.md block (pi-global-AGENTS.append.md): gated to pi-devbox containers and conditional on the MemPalace MCP tools being present. Memory continuity matters most in a frequently-recreated container — the palace is its only cross-recreate memory. - pi-global-AGENTS.append.md: '## Session start: load the mempalace skill'. - smoke-test: assert the pointer merges into the global AGENTS.md at build. - docs: VENDORED.md, README, CHANGELOG [Unreleased]. Now both skills are complete in pi-devbox: directive + skill file. pi-extensions = directive (pi-toolkit) + baked skill; mempalace = directive (this block) + baked skill. |
||
|
|
a7d6a7d235 |
feat(skills): bake pi-extensions + mempalace fallback skills
The pi-toolkit global AGENTS.md tells every pi session to read
~/.agents/skills/pi-extensions/SKILL.md at start (the fork/recall
under-utilisation fix), but that skill lived only in the private skillset
repo — so the pointer dangled in any container started without skillset
mounted. Bake fallbacks so the pointer always resolves.
- pi-extensions (Option 1 + Option 2, layered):
* Canonical skill promoted to the public pi-extensions package repo under
skill/ (separate commit there); co-located with the code it documents.
* rootfs/ carries a committed snapshot (the floor).
* Dockerfile.variant copies /opt/pi-extensions/skill/ over the snapshot
after the pinned clone, so a normal build ships the fresh package copy
(recorded via PI_EXTENSIONS_REF) and an old-ref/mirror build still ships
the snapshot. Helper evaluate-extension-usage.py travels with it.
- mempalace (Option 2 only): snapshot in rootfs/. Its consumer skill has no
public package home (mempalace-toolkit ships a different skill,
opencode-mempalace-bridge), so no build-time refresh.
- entrypoint links both (only-when-absent; mounted skillset still wins).
- smoke-test: build-time presence + package-match check + runtime symlink
assertions; readiness gate now waits on the last-linked skill.
- docs: skills/VENDORED.md (provenance + refresh), README, AGENTS.md,
CHANGELOG [Unreleased].
Note: shipped in the NEXT release; v1.2.0 (run 409) predates this.
|
||
|
|
2abfee141b |
feat: image-baked agent skills + pi-devbox-environment skill (v1.2.0)
Publish Docker Image / smoke-studio (push) Failing after 4m5s
Publish Docker Image / build-variant-studio (push) Has been skipped
Publish Docker Image / smoke (push) Failing after 5m46s
Publish Docker Image / build-variant (push) Has been skipped
Publish Docker Image / update-description (push) Has been skipped
Publish Docker Image / promote-base-latest (push) Has been skipped
Publish Docker Image / resolve-versions (push) Successful in 35s
Publish Docker Image / base-decide (push) Successful in 23s
Publish Docker Image / build-base (push) Successful in 41m32s
Ship skills inside the image (independent of any mounted skillset repo): - rootfs/usr/local/share/pi-devbox/skills/<name>/ symlinked into ~/.agents/skills/ by entrypoint-user.sh (foreign-link, survives volume recreate, never clobbers a skillset/user skill of the same name). - New pi-devbox-environment skill: persistence model, host/LAN SSH reachability, split-DNS mechanisms, interactive-vs-tool-shell alias gotcha, tmux 0-index, uv-first Python, pi-studio reachability. Agnostic to host OS / hostnames / domains / nameservers (discovered at runtime). - Dockerfile.variant appends pi-global-AGENTS.append.md onto pi-toolkit's pi-global-AGENTS.md (single global slot) so the skill is loaded proactively; gated on /usr/local/lib/pi-devbox/. Idempotent. - smoke-test: baked-skill + append-snippet + merged-marker presence and a runtime symlink assertion. - docs: README 'Agent skills' section, AGENTS.md layout, DOCKER_HUB.md; moved studio-tex roadmap to v1.3.0. pi 0.79.7 -> 0.79.10 (auto-resolved from npm latest at build). |
||
|
|
c346a106a3 |
release: v1.1.7 — pi 0.79.8 → 0.79.9; ssh-lan.conf LAN-peer docs
Publish Docker Image / base-decide (push) Successful in 1m0s
Publish Docker Image / resolve-versions (push) Successful in 6s
Publish Docker Image / build-base (push) Successful in 33m15s
Publish Docker Image / smoke (push) Successful in 3m32s
Publish Docker Image / smoke-studio (push) Successful in 3m47s
Publish Docker Image / build-variant-studio (push) Successful in 17m39s
Publish Docker Image / build-variant (push) Successful in 19m13s
Publish Docker Image / promote-base-latest (push) Successful in 9s
Publish Docker Image / update-description (push) Successful in 13s
|
||
|
|
8de0fad776 |
docs(lan): document ssh-lan.conf for naming LAN peers
The host-owned, bind-mounted ~/.config/devbox-shell/ssh-lan.conf is the intended place to add `ProxyJump host` overrides for named LAN peers (so `pi --ssh <peer>` / `dssh <peer>` route through the host), but it was only documented in .env.example and the setup-lan-access.sh header — never in the README, where someone hitting "can't reach LAN peers" actually looks. - README: add a "Naming LAN peers" subsection under the macOS LAN-peers troubleshooting block, with a ProxyJump example and the read-only ~/.ssh caveat; add a pointer to it from the SSH and ControlMaster section. - setup-lan-access.sh: correct the INCLUDE_BLOCK comment that suggested adding ProxyJump to the read-only ~/.ssh/config; point at ssh-lan.conf instead. - CHANGELOG: note under Unreleased. Docs/comment only — no behavior change. |