Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fa6e9dc9d6 | |||
| bd0627a557 | |||
| 67da05b99b | |||
| 4563b4d76d | |||
| f19c35da32 |
@@ -153,10 +153,14 @@ deprecated artifacts (to be removed in opencode-devbox v2.0.0).
|
|||||||
|
|
||||||
## What we DON'T install (and why)
|
## What we DON'T install (and why)
|
||||||
|
|
||||||
- **No texlive** (~600 MB–1 GB). Users who need PDF export from pandoc
|
- **No texlive** (~600 MB–1 GB). PDF export from pandoc / pi-studio works
|
||||||
or pi-studio can install on demand: `sudo apt-get install texlive-xetex
|
out of the box via **`typst`** (~30 MB static binary), which the base ships
|
||||||
texlive-latex-recommended`. The planned `:latest-studio-tex` variant
|
as the pandoc PDF engine (`pandoc --pdf-engine=typst`) — small enough to live
|
||||||
will bake this in.
|
in base rather than a dedicated `:latest-studio-tex` variant. We don't bake in
|
||||||
|
a full TeX Live: it's heavy and typst covers the common Markdown→PDF case.
|
||||||
|
Users needing LaTeX-exact output can install the higher-fidelity fallback on
|
||||||
|
demand: `sudo apt-get install texlive-xetex texlive-latex-recommended` (then
|
||||||
|
`pandoc --pdf-engine=xelatex`).
|
||||||
- **pi-studio** ships in the `:latest-studio` variant (since v1.1.0),
|
- **pi-studio** ships in the `:latest-studio` variant (since v1.1.0),
|
||||||
vendored to `/opt/pi-studio` and registered at container start via
|
vendored to `/opt/pi-studio` and registered at container start via
|
||||||
`pi install /opt/pi-studio` (see Dockerfile.variant `INSTALL_STUDIO`).
|
`pi install /opt/pi-studio` (see Dockerfile.variant `INSTALL_STUDIO`).
|
||||||
|
|||||||
@@ -11,6 +11,45 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## v1.4.0 — 2026-07-11
|
||||||
|
|
||||||
|
Minor release. Headline: **PDF export works out of the box** — the base now
|
||||||
|
ships **`typst`** as the pandoc PDF engine (`pandoc --pdf-engine=typst`), so
|
||||||
|
`studio_export_pdf` / `pandoc -o out.pdf` no longer fail with "xelatex not
|
||||||
|
found". Also adds a **host SSH reachability check at shell startup**. Both are
|
||||||
|
base-affecting (`Dockerfile.base` apt+RUN for typst/xz-utils; `.bash_aliases`
|
||||||
|
for the SSH check is COPYd into the base), so the base rebuilds and both land in
|
||||||
|
`base-<hash>`. pi auto-resolves `latest` at build time (0.80.3 → 0.80.6);
|
||||||
|
mempalace stays pinned at 3.5.0 (current PyPI latest).
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Host SSH reachability check at shell startup.** `~/.bash_aliases` (baked
|
||||||
|
into the image) now runs a one-time SSH probe on the first bash session of
|
||||||
|
each container. If the Mac host is not reachable (Remote Login disabled or
|
||||||
|
the `devbox_jump` key not yet authorized) it prints a clear warning with the
|
||||||
|
exact two steps to fix it, including the container's public key inline.
|
||||||
|
Subsequent shells in the same container skip the check (flag in `/tmp`,
|
||||||
|
cleared on recreate). Silent when SSH is working. Complements the existing
|
||||||
|
key-generation message in `setup-lan-access.sh` which only fires once at key
|
||||||
|
creation time and can easily be missed. Commit `4563b4d`.
|
||||||
|
|
||||||
|
- **`typst` — lightweight PDF engine for pandoc (Markdown→PDF).** `pandoc` has
|
||||||
|
shipped in the base since v1.0.0 but as a front-end only — with no PDF
|
||||||
|
back-end installed, `studio_export_pdf` / `pandoc -o out.pdf` failed with
|
||||||
|
"xelatex not found". The base now installs `typst`, a single ~30 MB static
|
||||||
|
Rust binary (no LaTeX), used via `pandoc --pdf-engine=typst`. Chosen over a
|
||||||
|
~600 MB TeX Live install; a fuller TeX Live remains the higher-fidelity
|
||||||
|
fallback for anyone needing LaTeX-exact output (install on demand). Also adds
|
||||||
|
`xz-utils` to the apt layer (typst ships a `.tar.xz` asset that `tar` needs
|
||||||
|
`xz` to extract). Installed with the standard `latest` GitHub-release idiom;
|
||||||
|
pin with `--build-arg TYPST_VERSION=vX.Y.Z`. This lands in `base-<hash>`
|
||||||
|
(Dockerfile.base changed). Supersedes the previously-planned
|
||||||
|
`:latest-studio-tex` variant — typst is small enough to ship in BASE, so no
|
||||||
|
separate TeX variant is needed. See `pi-devbox-roadmap`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v1.3.0 — 2026-07-02
|
## v1.3.0 — 2026-07-02
|
||||||
|
|
||||||
Minor release. Headline: **shared/external MemPalace** — the `mempalace.ts`
|
Minor release. Headline: **shared/external MemPalace** — the `mempalace.ts`
|
||||||
|
|||||||
+36
-2
@@ -14,7 +14,7 @@
|
|||||||
# content-addressed over this file, so any byte change invalidates the
|
# content-addressed over this file, so any byte change invalidates the
|
||||||
# cache. Recommended cadence: once per release for security updates.
|
# cache. Recommended cadence: once per release for security updates.
|
||||||
#
|
#
|
||||||
# BASE_REBUILD_DATE: 2026-06-09 (v1.0.0 — decoupled from opencode-devbox)
|
# BASE_REBUILD_DATE: 2026-07-11 (Unreleased — typst PDF engine + xz-utils)
|
||||||
#
|
#
|
||||||
# ── Lineage note ─────────────────────────────────────────────────────
|
# ── Lineage note ─────────────────────────────────────────────────────
|
||||||
# Adapted from opencode-devbox/Dockerfile.base (commit before v1.16.2).
|
# Adapted from opencode-devbox/Dockerfile.base (commit before v1.16.2).
|
||||||
@@ -46,7 +46,14 @@ ENV DEBIAN_FRONTEND=noninteractive
|
|||||||
# Additions vs the upstream opencode-devbox base (2026-06-09):
|
# Additions vs the upstream opencode-devbox base (2026-06-09):
|
||||||
# pandoc — Markdown↔HTML/PDF/etc. conversion. Required by pi-studio
|
# pandoc — Markdown↔HTML/PDF/etc. conversion. Required by pi-studio
|
||||||
# preview/export pipelines and broadly useful for any
|
# preview/export pipelines and broadly useful for any
|
||||||
# agent-driven document workflow. ~200 MB.
|
# agent-driven document workflow. ~200 MB. NOTE: pandoc is
|
||||||
|
# only the front-end — PDF output needs a back-end engine.
|
||||||
|
# We ship `typst` (installed further down) as the
|
||||||
|
# lightweight default engine (`pandoc --pdf-engine=typst`)
|
||||||
|
# instead of a ~600 MB TeX Live install.
|
||||||
|
# xz-utils — `xz` decompressor. tar shells out to it for `.tar.xz`
|
||||||
|
# assets (typst ships .tar.xz). ~0.5 MB. Also generally
|
||||||
|
# useful for extracting xz-compressed archives.
|
||||||
# graphviz — `dot` rendering for many diagram tools. ~10 MB.
|
# graphviz — `dot` rendering for many diagram tools. ~10 MB.
|
||||||
# See the bundled `dot-watch` helper for live .dot -> PNG
|
# See the bundled `dot-watch` helper for live .dot -> PNG
|
||||||
# re-render (handy with pi-studio's image preview).
|
# re-render (handy with pi-studio's image preview).
|
||||||
@@ -95,6 +102,7 @@ RUN apt-get update && \
|
|||||||
python3-pip \
|
python3-pip \
|
||||||
python3-venv \
|
python3-venv \
|
||||||
pandoc \
|
pandoc \
|
||||||
|
xz-utils \
|
||||||
graphviz \
|
graphviz \
|
||||||
imagemagick \
|
imagemagick \
|
||||||
socat \
|
socat \
|
||||||
@@ -444,6 +452,32 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64"
|
|||||||
chmod +x /usr/local/bin/tldr && \
|
chmod +x /usr/local/bin/tldr && \
|
||||||
tldr --version
|
tldr --version
|
||||||
|
|
||||||
|
# ── typst — lightweight PDF engine for pandoc (Markdown→PDF) ─────────
|
||||||
|
# pandoc (apt-installed above) is only a front-end; rendering PDF needs a
|
||||||
|
# back-end engine. Rather than a ~600 MB TeX Live install, we ship typst:
|
||||||
|
# a single ~30 MB static Rust binary with no LaTeX dependency. pi-studio's
|
||||||
|
# PDF export (studio_export_pdf) and pandoc invocations use it via
|
||||||
|
# `pandoc --pdf-engine=typst`. A fuller TeX Live remains the higher-
|
||||||
|
# fidelity fallback for anyone who needs LaTeX-exact output (not shipped
|
||||||
|
# here — install on demand or in a future variant).
|
||||||
|
#
|
||||||
|
# Follows the `latest` GitHub-release convention (like tealdeer/uv/bat).
|
||||||
|
# typst ships a `.tar.xz` asset (hence xz-utils in the apt layer above)
|
||||||
|
# that extracts to typst-<arch>-unknown-linux-musl/typst. Pin a specific
|
||||||
|
# tag with --build-arg TYPST_VERSION=vX.Y.Z.
|
||||||
|
ARG TYPST_VERSION=latest
|
||||||
|
RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64" ;; *) echo "x86_64" ;; esac) && \
|
||||||
|
V="${TYPST_VERSION}" && \
|
||||||
|
if [ "$V" = "latest" ]; then \
|
||||||
|
V=$(curl -sI --retry 5 --retry-delay 5 --retry-all-errors "https://github.com/typst/typst/releases/latest" | awk 'tolower($1)=="location:" { sub(/\r$/,"",$2); n=split($2,a,"/"); print a[n] }'); \
|
||||||
|
fi && \
|
||||||
|
V="${V#v}" && [ -n "$V" ] && \
|
||||||
|
echo "Installing typst ${V}" && \
|
||||||
|
curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors "https://github.com/typst/typst/releases/download/v${V}/typst-${ARCH}-unknown-linux-musl.tar.xz" | tar -xJ -C /tmp && \
|
||||||
|
install /tmp/typst-${ARCH}-unknown-linux-musl/typst /usr/local/bin/typst && \
|
||||||
|
rm -rf /tmp/typst-${ARCH}-unknown-linux-musl && \
|
||||||
|
typst --version
|
||||||
|
|
||||||
# ── yq (mikefarah) — YAML processor, jq's companion for YAML ─────────
|
# ── yq (mikefarah) — YAML processor, jq's companion for YAML ─────────
|
||||||
# Installed as the mikefarah Go binary — NOT Debian's `yq` apt package, which
|
# Installed as the mikefarah Go binary — NOT Debian's `yq` apt package, which
|
||||||
# is the unrelated Python kislyuk/yq (a jq wrapper with different syntax and
|
# is the unrelated Python kislyuk/yq (a jq wrapper with different syntax and
|
||||||
|
|||||||
@@ -149,8 +149,10 @@ Currently published:
|
|||||||
|
|
||||||
Planned for an upcoming minor release:
|
Planned for an upcoming minor release:
|
||||||
|
|
||||||
- `joakimp/pi-devbox:latest-studio-tex` — `-studio` plus `texlive-xetex`
|
- *(shipped in Unreleased/base)* **PDF export from Studio/pandoc** now works:
|
||||||
for PDF export from Studio. Adds ~600 MB on top of `-studio`.
|
the base image ships **`typst`** as the PDF engine (`pandoc --pdf-engine=typst`),
|
||||||
|
a single ~30 MB static binary — no separate `-tex` variant needed.
|
||||||
|
`texlive-xetex` stays the higher-fidelity fallback (install on demand).
|
||||||
|
|
||||||
## Using pi-studio (`-studio` variant)
|
## Using pi-studio (`-studio` variant)
|
||||||
|
|
||||||
@@ -285,9 +287,10 @@ Assuming the compose file publishes `127.0.0.1:8765:8765` (see method B):
|
|||||||
> until step 2 runs. If the browser can't connect, verify Studio is up
|
> until step 2 runs. If the browser can't connect, verify Studio is up
|
||||||
> (`/studio --status`) and the bridge is running (`ps aux | grep socat`).
|
> (`/studio --status`) and the bridge is running (`ps aux | grep socat`).
|
||||||
|
|
||||||
> PDF export (`/studio-pdf`, `studio_export_pdf`) needs a LaTeX engine,
|
> PDF export (`/studio-pdf`, `studio_export_pdf`) uses **`typst`**, shipped in
|
||||||
> which is **not** in `-studio` (only the planned `-studio-tex`). HTML
|
> the base image as the pandoc PDF engine (`pandoc --pdf-engine=typst`). For
|
||||||
> export, KaTeX, Mermaid, and all REPL features work without it.
|
> LaTeX-exact output you can install `texlive-xetex` on demand as a heavier
|
||||||
|
> fallback. HTML export, KaTeX, Mermaid, and all REPL features work regardless.
|
||||||
|
|
||||||
### Graphviz diagrams in Studio: `dot-watch`
|
### Graphviz diagrams in Studio: `dot-watch`
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,38 @@ alias gs='git status'
|
|||||||
alias gd='git diff'
|
alias gd='git diff'
|
||||||
alias gl='git log --oneline --graph --decorate -20'
|
alias gl='git log --oneline --graph --decorate -20'
|
||||||
|
|
||||||
|
# ── Host SSH reachability check (once per container lifetime) ───────────────
|
||||||
|
# Warns at first shell startup if the Mac host is not reachable via SSH.
|
||||||
|
# Only runs inside a container, only if the jump key exists, and only once
|
||||||
|
# per container lifetime (/tmp flag is cleared on recreate).
|
||||||
|
_devbox_check_host_ssh() {
|
||||||
|
[ -f "/.dockerenv" ] || return 0
|
||||||
|
local ssh_cfg="$HOME/.ssh-local/config"
|
||||||
|
[ -f "$ssh_cfg" ] || return 0
|
||||||
|
local key_pub="$HOME/.ssh-local/devbox_jump_ed25519.pub"
|
||||||
|
[ -f "$key_pub" ] || return 0
|
||||||
|
local flag="/tmp/.devbox_host_ssh_ok"
|
||||||
|
[ -f "$flag" ] && return 0
|
||||||
|
if ssh -F "$ssh_cfg" \
|
||||||
|
-o BatchMode=yes \
|
||||||
|
-o ConnectTimeout=2 \
|
||||||
|
-o StrictHostKeyChecking=accept-new \
|
||||||
|
mac true 2>/dev/null; then
|
||||||
|
touch "$flag"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local pub_key
|
||||||
|
pub_key=$(cat "$key_pub")
|
||||||
|
printf '\n\033[1;33m⚠ devbox: Mac host not reachable via SSH\033[0m\n'
|
||||||
|
printf ' Some tools use SSH to run commands on the Mac host.\n'
|
||||||
|
printf ' Fix (run both on the Mac):\n\n'
|
||||||
|
printf ' \033[1mStep 1\033[0m System Settings → General → Sharing → Remote Login → ON\n\n'
|
||||||
|
printf ' \033[1mStep 2\033[0m echo '"'"'%s'"'"' >> ~/.ssh/authorized_keys\n' "$pub_key"
|
||||||
|
printf '\n Then open a new shell in the container to verify.\n\n'
|
||||||
|
}
|
||||||
|
_devbox_check_host_ssh
|
||||||
|
unset -f _devbox_check_host_ssh
|
||||||
|
|
||||||
# ── LAN access via the host (dssh) ───────────────────────────────────
|
# ── LAN access via the host (dssh) ───────────────────────────────────
|
||||||
# When running on a VM-backed host (macOS OrbStack / Docker Desktop), the
|
# When running on a VM-backed host (macOS OrbStack / Docker Desktop), the
|
||||||
# entrypoint's setup-lan-access.sh generates ~/.ssh-local/config so the host
|
# entrypoint's setup-lan-access.sh generates ~/.ssh-local/config so the host
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
# Verifies:
|
# Verifies:
|
||||||
# - pi binary present and (if EXPECTED_PI_VERSION set) matches CI's resolved version
|
# - pi binary present and (if EXPECTED_PI_VERSION set) matches CI's resolved version
|
||||||
# - new v1.0.0 base additions (pandoc, graphviz, imagemagick, yq, tealdeer)
|
# - new v1.0.0 base additions (pandoc, graphviz, imagemagick, yq, tealdeer)
|
||||||
|
# - typst PDF engine for pandoc (Unreleased) — `pandoc --pdf-engine=typst`
|
||||||
# - non-modal editors nano + micro (alongside nvim)
|
# - non-modal editors nano + micro (alongside nvim)
|
||||||
# - tmux 0-indexing baked in /etc/tmux.conf (required for pi-studio variants)
|
# - tmux 0-indexing baked in /etc/tmux.conf (required for pi-studio variants)
|
||||||
# - pi-toolkit cloned at /opt/pi-toolkit
|
# - pi-toolkit cloned at /opt/pi-toolkit
|
||||||
@@ -78,6 +79,8 @@ run "micro" "micro --version"
|
|||||||
run "mempalace-mcp" "mempalace-mcp --help"
|
run "mempalace-mcp" "mempalace-mcp --help"
|
||||||
# v1.0.0 base additions — verify presence and basic functionality.
|
# v1.0.0 base additions — verify presence and basic functionality.
|
||||||
run "pandoc" "pandoc --version"
|
run "pandoc" "pandoc --version"
|
||||||
|
run "typst" "typst --version"
|
||||||
|
run "pandoc+typst PDF engine" "printf '# hi\n' | pandoc --pdf-engine=typst -o /tmp/_smoke.pdf - && test -s /tmp/_smoke.pdf; rm -f /tmp/_smoke.pdf"
|
||||||
run "graphviz (dot)" "dot -V"
|
run "graphviz (dot)" "dot -V"
|
||||||
run "imagemagick" "magick --version"
|
run "imagemagick" "magick --version"
|
||||||
run "yq (mikefarah v4)" "yq --version | grep -qE 'mikefarah.*version v4'"
|
run "yq (mikefarah v4)" "yq --version | grep -qE 'mikefarah.*version v4'"
|
||||||
|
|||||||
Reference in New Issue
Block a user