diff --git a/AGENTS.md b/AGENTS.md index 763d120..1b32338 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -153,14 +153,14 @@ deprecated artifacts (to be removed in opencode-devbox v2.0.0). ## What we DON'T install (and why) -- **No texlive** (~600 MB–1 GB). Users who need PDF export from pandoc - or pi-studio can install on demand: `sudo apt-get install texlive-xetex - texlive-latex-recommended`. PDF export is planned for a future release — but - note pandoc alone can't render PDF (it needs a back-end engine), and a full TeX - install is heavy. A lightweight engine like **`typst`** (~30 MB static - binary, `pandoc --pdf-engine=typst`) is the preferred candidate and, being - small, could land in base rather than a dedicated `:latest-studio-tex` - variant. `texlive-xetex` stays the higher-fidelity fallback. +- **No texlive** (~600 MB–1 GB). PDF export from pandoc / pi-studio works + out of the box via **`typst`** (~30 MB static binary), which the base ships + as the pandoc PDF engine (`pandoc --pdf-engine=typst`) — small enough to live + 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), vendored to `/opt/pi-studio` and registered at container start via `pi install /opt/pi-studio` (see Dockerfile.variant `INSTALL_STUDIO`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d4a46c..0269a2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,26 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`). --- +## Unreleased + +### Added + +- **`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-` + (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 Minor release. Headline: **shared/external MemPalace** — the `mempalace.ts` diff --git a/Dockerfile.base b/Dockerfile.base index 95afbc2..ebc67f1 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -14,7 +14,7 @@ # content-addressed over this file, so any byte change invalidates the # 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 ───────────────────────────────────────────────────── # 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): # pandoc — Markdown↔HTML/PDF/etc. conversion. Required by pi-studio # 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. # See the bundled `dot-watch` helper for live .dot -> PNG # re-render (handy with pi-studio's image preview). @@ -95,6 +102,7 @@ RUN apt-get update && \ python3-pip \ python3-venv \ pandoc \ + xz-utils \ graphviz \ imagemagick \ socat \ @@ -444,6 +452,32 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64" chmod +x /usr/local/bin/tldr && \ 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--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 ───────── # 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 diff --git a/README.md b/README.md index 353a4ae..655e9b8 100644 --- a/README.md +++ b/README.md @@ -149,12 +149,10 @@ Currently published: Planned for an upcoming minor release: -- **PDF export from Studio/pandoc** (a future minor release). Engine still to be decided. - A lightweight engine is preferred over a full TeX install: - - `typst` — single static binary (~30 MB), `pandoc --pdf-engine=typst`; light - enough it could ship in the base image (no separate `-tex` variant needed). - - `joakimp/pi-devbox:latest-studio-tex` — `-studio` plus `texlive-xetex` - (~600 MB on top of `-studio`); highest fidelity, kept as the fallback. +- *(shipped in Unreleased/base)* **PDF export from Studio/pandoc** now works: + 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) @@ -289,11 +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 > (`/studio --status`) and the bridge is running (`ps aux | grep socat`). -> PDF export (`/studio-pdf`, `studio_export_pdf`) needs a PDF engine, which is -> **not** in `-studio` (pandoc is present but has no engine, so export fails -> with `xelatex not found`). Planned for a future release — likely a lightweight -> engine such as `typst`, with `texlive-xetex` as the heavier fallback. HTML export, -> KaTeX, Mermaid, and all REPL features work without it. +> PDF export (`/studio-pdf`, `studio_export_pdf`) uses **`typst`**, shipped in +> the base image as the pandoc PDF engine (`pandoc --pdf-engine=typst`). For +> 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` diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh index 528c791..174b2bd 100755 --- a/scripts/smoke-test.sh +++ b/scripts/smoke-test.sh @@ -6,6 +6,7 @@ # Verifies: # - 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) +# - typst PDF engine for pandoc (Unreleased) — `pandoc --pdf-engine=typst` # - non-modal editors nano + micro (alongside nvim) # - tmux 0-indexing baked in /etc/tmux.conf (required for pi-studio variants) # - pi-toolkit cloned at /opt/pi-toolkit @@ -78,6 +79,8 @@ run "micro" "micro --version" run "mempalace-mcp" "mempalace-mcp --help" # v1.0.0 base additions — verify presence and basic functionality. 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 "imagemagick" "magick --version" run "yq (mikefarah v4)" "yq --version | grep -qE 'mikefarah.*version v4'"