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
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.
This commit is contained in:
@@ -66,3 +66,27 @@ jobs:
|
||||
# ("no project was found"). Globbing the workflow files is the
|
||||
# supported way to lint a non-GitHub layout.
|
||||
run: actionlint -color .gitea/workflows/*.yml
|
||||
|
||||
hadolint:
|
||||
# Lint the two Dockerfiles that ARE the project (the shell/actions linting
|
||||
# above never looked at them). Config — ignored rules + failure threshold
|
||||
# — lives in .hadolint.yaml, which hadolint reads automatically, so a local
|
||||
# `hadolint Dockerfile.base` reproduces CI exactly.
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install hadolint (pinned)
|
||||
env:
|
||||
HADOLINT_VERSION: 2.14.0
|
||||
run: |
|
||||
curl -fsSL \
|
||||
"https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-Linux-x86_64" \
|
||||
-o /usr/local/bin/hadolint
|
||||
chmod +x /usr/local/bin/hadolint
|
||||
hadolint --version
|
||||
|
||||
- name: Run hadolint
|
||||
run: hadolint Dockerfile.base Dockerfile.variant
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# hadolint configuration for opencode-devbox.
|
||||
#
|
||||
# Both Dockerfiles are linted in CI (.gitea/workflows/lint.yml → `hadolint`
|
||||
# job). hadolint reads this file automatically, so a local
|
||||
# `hadolint Dockerfile.base` reproduces CI exactly.
|
||||
#
|
||||
# The ignores below are DELIBERATE project choices — they mirror the
|
||||
# philosophy of the shellcheck excludes already applied to `run:` steps
|
||||
# (SHELLCHECK_OPTS in lint.yml). Anything NOT listed here still fails the
|
||||
# build at `warning` and above, so new Dockerfile smells are caught going
|
||||
# forward.
|
||||
ignored:
|
||||
- DL3008 # "pin apt versions" — intentionally unpinned: the base tracks
|
||||
# Debian stable and runs `apt-get upgrade`, so pinning point
|
||||
# versions would rot and fight security updates.
|
||||
- DL3016 # "pin npm versions" — opencode / oh-my-opencode-slim ARE pinned,
|
||||
# but via build-args (CI-resolved from npm), not the npm CLI.
|
||||
- DL4006 # "set -o pipefail before a pipe" — the piped RUNs are
|
||||
# download|extract steps with their own retries / `set -e`.
|
||||
# Switching the global SHELL to bash is a larger, base-affecting
|
||||
# change — tracked in IDEAS.md.
|
||||
- DL3003 # "use WORKDIR, not cd" — cosmetic in the few `cd` RUNs here.
|
||||
- SC2086 # "double-quote to prevent word-splitting" — the same code is
|
||||
# excluded for shell `run:` steps in lint.yml; splitting is
|
||||
# intentional in these contexts.
|
||||
|
||||
failure-threshold: warning
|
||||
@@ -6,6 +6,82 @@ Tags follow **independent semver** (since `v2.0.0`) — they version *this image
|
||||
|
||||
---
|
||||
|
||||
## v2.7.0 — 2026-07-13
|
||||
|
||||
Minor release. Headline: **further parity with the sibling `pi-devbox` image** —
|
||||
ports the base additions from pi-devbox v1.4.0 + v1.5.0 that opencode-devbox
|
||||
lacked. **PDF export now works out of the box** (`typst` as the pandoc PDF
|
||||
engine — pandoc shipped since v2.6.0 as a front-end only), modern terminal
|
||||
emulators resolve their `TERM` over SSH (ncurses-term + kitty-terminfo + a
|
||||
compiled `xterm-ghostty` alias), Neovim renders in readable 24-bit colour by
|
||||
default, and a first-shell **host SSH reachability check** warns when the Mac
|
||||
host isn't reachable. Also adds repository hygiene (LICENSE, THIRD_PARTY.md,
|
||||
hadolint CI, IDEAS backlog) and a `.claude` gitignore-seed pattern. All the
|
||||
tooling/rootfs changes are base-affecting, so `base-<hash>` advances and the
|
||||
base rebuilds.
|
||||
|
||||
### Added
|
||||
|
||||
- **`typst` — PDF engine for pandoc (Markdown→PDF).** `pandoc` shipped in the
|
||||
base since v2.6.0 but as a front-end only — with no PDF back-end,
|
||||
`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`; a fuller TeX Live remains the higher-fidelity
|
||||
fallback (install on demand). Also patches pandoc's bundled typst template
|
||||
(`/usr/share/pandoc/data/templates/template.typst`), whose empty `font: ()`
|
||||
default otherwise made a naked `--pdf-engine=typst` fail with "font fallback
|
||||
list must not be empty" — defaulted to `Libertinus Serif` so PDF export works
|
||||
without `-V mainfont`. Adds `xz-utils` to the apt layer (typst ships a
|
||||
`.tar.xz`). Tracks `latest`; pin with `--build-arg TYPST_VERSION=vX.Y.Z`.
|
||||
Ported from pi-devbox v1.4.0 (+ its v1.5.0 font-default fix). Base-affecting.
|
||||
|
||||
- **Terminal support beyond the default: `ncurses-term` + `kitty-terminfo` + a
|
||||
compiled `xterm-ghostty` alias.** The base previously shipped only
|
||||
`ncurses-base`, so SSHing in from a modern emulator degraded to a dumb
|
||||
fallback. Now installs `ncurses-term` (terminfo for WezTerm, Alacritty, foot,
|
||||
st, the base `ghostty` entry, and many more) and `kitty-terminfo`
|
||||
(`xterm-kitty`), and compiles an `xterm-ghostty` alias with `tic -x`
|
||||
(`use=ghostty`) — Ghostty connects as `TERM=xterm-ghostty` and no distro
|
||||
packages that name. iTerm2's `xterm-256color` is already in ncurses-base. New
|
||||
`rootfs/usr/local/share/terminfo-src/ghostty.terminfo`; the build asserts the
|
||||
entry landed via `infocmp`. Ported from pi-devbox v1.5.0. Base-affecting.
|
||||
|
||||
- **Readable Neovim colours out of the box.** New system-wide Neovim config
|
||||
(`rootfs/etc/xdg/nvim/sysinit.vim`) enables `termguicolors`. Vanilla Neovim
|
||||
otherwise fell back to a muddy, low-contrast 256-colour palette over ssh.
|
||||
`sysinit.vim` is Neovim's system vimrc — it loads for every user before any
|
||||
personal `~/.config/nvim` and can still be overridden per-user
|
||||
(`:set notermguicolors`). Pairs with `kitty-terminfo` above. Ported from
|
||||
pi-devbox v1.5.0. Base-affecting.
|
||||
|
||||
- **Host SSH reachability check at shell startup.** `~/.bash_aliases` (baked
|
||||
into the base) 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 skip the check (a `/tmp` flag cleared on recreate); silent when SSH
|
||||
works. Complements the existing `setup-lan-access.sh` key-generation message.
|
||||
Ported from pi-devbox v1.4.0. Base-affecting.
|
||||
|
||||
- **Seeded global gitignore now ignores `**/.claude/settings.local.json`.**
|
||||
Claude Code's per-machine local settings file holds machine-specific
|
||||
permissions and can carry credentials, so it should never be committed. The
|
||||
seed (`rootfs/home/developer/.gitignore_global`, baked to `/etc/skel-devbox/`)
|
||||
gains the pattern. Existing containers are unaffected (the seed is copied only
|
||||
when `~/.gitignore_global` is absent). Base-affecting (rootfs COPY).
|
||||
|
||||
- **Repository hygiene: `LICENSE`, `THIRD_PARTY.md`, `hadolint` CI, `IDEAS.md`.**
|
||||
The repo declared MIT only in prose; it now ships an actual `LICENSE` file
|
||||
(MIT, © Joakim Persson) plus `THIRD_PARTY.md` recording that the published
|
||||
images bundle third-party software under its own terms (opencode, OMOS,
|
||||
mempalace — MIT; gosu/uv/typst Apache-2.0; Debian packages under their own
|
||||
licenses). A new `hadolint` job (pinned v2.14.0) in the lint workflow lints
|
||||
`Dockerfile.base` and `Dockerfile.variant`; `.hadolint.yaml` grandfathers the
|
||||
deliberate choices (unpinned apt/npm, `cd`-in-`RUN`, `SC2086` — mirroring the
|
||||
existing shellcheck excludes) and fails on anything new at `warning`+.
|
||||
`IDEAS.md` parks vetted-but-unscheduled follow-ups. Repo/CI only — not baked
|
||||
into the image.
|
||||
|
||||
## v2.6.0 — 2026-07-08
|
||||
|
||||
Minor release. Headline: **CLI-toolset parity with the sibling `pi-devbox`
|
||||
|
||||
+55
-1
@@ -15,7 +15,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-05-14 (v1.14.50b — fresh apt + first promote-base-latest)
|
||||
# BASE_REBUILD_DATE: 2026-07-13 (v2.7.0 — typst PDF engine + terminal terminfo (ncurses-term/kitty/xterm-ghostty) + nvim true-colour; pi-devbox parity)
|
||||
#
|
||||
# See the project README's "Build pipeline" section for the rationale.
|
||||
|
||||
@@ -74,7 +74,10 @@ RUN apt-get update && \
|
||||
python3-venv \
|
||||
nano \
|
||||
pandoc \
|
||||
xz-utils \
|
||||
graphviz \
|
||||
kitty-terminfo \
|
||||
ncurses-term \
|
||||
&& ln -s /usr/bin/fdfind /usr/local/bin/fd \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -314,6 +317,40 @@ 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, used via
|
||||
# `pandoc --pdf-engine=typst`. A fuller TeX Live remains the higher-fidelity
|
||||
# fallback for anyone who needs LaTeX-exact output (install on demand).
|
||||
# Ported from pi-devbox (its v1.4.0 + v1.5.0 font-default fix).
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# We also patch pandoc's bundled typst template
|
||||
# (/usr/share/pandoc/data/templates/template.typst): its conf() 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"
|
||||
# unless the caller passes `-V mainfont=...`. We default it to Libertinus Serif
|
||||
# (typst's own bundled default font) so PDF export works out-of-the-box.
|
||||
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 && \
|
||||
sed -i 's/^ font: (),$/ font: ("Libertinus Serif",),/' /usr/share/pandoc/data/templates/template.typst && \
|
||||
grep -q 'font: ("Libertinus Serif",),' /usr/share/pandoc/data/templates/template.typst
|
||||
|
||||
# ── MemPalace — local-first AI memory system ─────────────────────────
|
||||
# Provides semantic search over conversation history via 29 MCP tools.
|
||||
# Always installed in the base (variant-independent). Set
|
||||
@@ -494,6 +531,23 @@ COPY rootfs/home/developer/.bash_aliases /etc/skel-devbox/.bash_aliases
|
||||
COPY rootfs/home/developer/.inputrc /etc/skel-devbox/.inputrc
|
||||
COPY rootfs/home/developer/.gitignore_global /etc/skel-devbox/.gitignore_global
|
||||
|
||||
# ── Editor defaults: system-wide Neovim true-colour ──────────────────
|
||||
# /etc/xdg/nvim/sysinit.vim is Neovim's system vimrc: it loads for every user
|
||||
# (before any personal ~/.config/nvim) and can still be overridden per-user.
|
||||
# Enables termguicolors so the default theme renders in 24-bit colour instead
|
||||
# of a muddy 256-colour fallback. Pairs with kitty-terminfo (installed above).
|
||||
COPY rootfs/etc/xdg/nvim/sysinit.vim /etc/xdg/nvim/sysinit.vim
|
||||
|
||||
# ── Terminal support: xterm-ghostty terminfo alias ──────────────────
|
||||
# ncurses-term (installed above) covers wezterm/alacritty/foot/st and the base
|
||||
# `ghostty` entry, but Ghostty connects with TERM=xterm-ghostty, for which no
|
||||
# distro packages an entry. Ship a thin alias (use=ghostty) and compile it into
|
||||
# the system terminfo db with `tic -x`, so it inherits the maintained ghostty
|
||||
# capability set. The `infocmp` check fails the build if the entry didn't land.
|
||||
COPY rootfs/usr/local/share/terminfo-src/ghostty.terminfo /usr/local/share/terminfo-src/ghostty.terminfo
|
||||
RUN tic -x -o /usr/share/terminfo /usr/local/share/terminfo-src/ghostty.terminfo && \
|
||||
infocmp -x xterm-ghostty >/dev/null
|
||||
|
||||
# ── Entrypoint ────────────────────────────────────────────────────────
|
||||
COPY rootfs/usr/local/lib/opencode-devbox/ /usr/local/lib/opencode-devbox/
|
||||
COPY rootfs/usr/local/bin/dot-watch /usr/local/bin/dot-watch
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Ideas & backlog
|
||||
|
||||
A living list of potential improvements for opencode-devbox that are **not yet
|
||||
scheduled**. This is intentionally lightweight — a place to park ideas so they
|
||||
aren't lost between sessions. When an item ships, describe it in
|
||||
[`CHANGELOG.md`](CHANGELOG.md) and remove it from here.
|
||||
|
||||
Rough effort tags: 🟢 small · 🟡 medium · 🔴 large. Status: `idea` (unvetted) ·
|
||||
`planned` (agreed, not started).
|
||||
|
||||
---
|
||||
|
||||
## Supply-chain hardening
|
||||
|
||||
- 🟡 `planned` — **Pin CI actions to commit SHAs.** The workflows use floating
|
||||
major tags (`actions/checkout@v4`, `docker/build-push-action@v7`,
|
||||
`docker/setup-buildx-action@v4`, `docker/login-action@v3`,
|
||||
`docker/setup-qemu-action@v3`). This is inconsistent with the project's own
|
||||
philosophy of SHA-pinning *content* refs to defeat floating refs. Pin each
|
||||
action to a SHA with a trailing `# vX.Y.Z` comment. Pairs naturally with the
|
||||
renovate item below to keep the pins fresh.
|
||||
|
||||
- 🟡 `planned` — **Vulnerability scanning in CI.** No CVE scan runs on the
|
||||
published images today. Add a `trivy image` (or grype) job to
|
||||
`docker-publish-split.yml` after `smoke`. Start non-blocking (report only),
|
||||
then tighten to fail on `HIGH`/`CRITICAL` with an available fix.
|
||||
|
||||
- 🟢🟡 `planned` — **Standardize build provenance → buildx SBOM + attestations.**
|
||||
The image already carries hand-rolled provenance (OCI labels +
|
||||
`build-manifest`). `docker/build-push-action` can emit a standard SBOM and
|
||||
SLSA provenance attestation nearly for free (`provenance: mode=max`,
|
||||
`sbom: true`). Makes provenance machine-consumable and pairs well with the
|
||||
trivy item (scan the SBOM).
|
||||
|
||||
## Dockerfile hardening
|
||||
|
||||
- 🟡 `idea` — **Address hadolint DL4006 properly.** Currently ignored in
|
||||
`.hadolint.yaml`. The clean fix is `SHELL ["/bin/bash", "-o", "pipefail",
|
||||
"-c"]` so piped `RUN`s fail on the first non-zero stage. This changes the
|
||||
default `RUN` shell from `sh` to `bash` for all subsequent layers, so it is
|
||||
base-affecting and needs a careful pass over existing `RUN`s before removing
|
||||
the ignore.
|
||||
|
||||
## Developer experience
|
||||
|
||||
- 🟢 `idea` — **`Makefile`/`justfile` for local iteration.** Reproducing a CI
|
||||
build locally means hand-assembling many `--build-arg`s. Thin targets
|
||||
(`make build-base`, `make build-variant`, `make smoke`, `make lint`) would
|
||||
make local testing painless and document the canonical invocations.
|
||||
|
||||
- 🟡 `idea` — **Dependency-update automation (renovate).** With CI actions
|
||||
SHA-pinned (above), a `renovate.json` keeps those pins — plus the pinned tool
|
||||
versions (`ACTIONLINT_VERSION`, `HADOLINT_VERSION`, gosu, etc.) — current via
|
||||
automated PRs. Requires a renovate runner against the Gitea instance.
|
||||
|
||||
## Housekeeping
|
||||
|
||||
- 🟢 `idea` — **Registry retention for `base-<hash>` tags.** The base-hash
|
||||
caching scheme accumulates `base-<hash>` tags over time. Confirm whether the
|
||||
registry prunes old ones, and add a retention/cleanup step if not.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Joakim Persson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Third-party notices
|
||||
|
||||
opencode-devbox is distributed under the MIT License (see [`LICENSE`](LICENSE)),
|
||||
which covers **this repository's own contents** — the Dockerfiles, entrypoint
|
||||
scripts, `rootfs/` seeds, CI workflows, and docs.
|
||||
|
||||
The **published container images** (`joakimp/opencode-devbox:*`) additionally
|
||||
*bundle* third-party software, each of which remains under its own license. This
|
||||
file is a good-faith summary; the authoritative sources are the upstream
|
||||
projects and, for OS packages, the per-package copyright files inside the image
|
||||
at `/usr/share/doc/<package>/copyright`.
|
||||
|
||||
## opencode and agent components (installed in the variant layer)
|
||||
|
||||
| Component | Upstream | License |
|
||||
| --- | --- | --- |
|
||||
| opencode | github.com/sst/opencode | MIT |
|
||||
| oh-my-opencode-slim (OMOS) *(`-omos` variant only)* | npm | MIT |
|
||||
| mempalace / mempalace-toolkit | authored by the maintainer (Joakim Persson) | MIT |
|
||||
| gitea-mcp | gitea.com/gitea/gitea-mcp | MIT |
|
||||
|
||||
## Tooling baked into the base image
|
||||
|
||||
| Component | Upstream | License (best effort) |
|
||||
| --- | --- | --- |
|
||||
| gosu | github.com/tianon/gosu | Apache-2.0 |
|
||||
| Node.js | nodejs.org | MIT (bundles components under their own licenses) |
|
||||
| uv | github.com/astral-sh/uv | Apache-2.0 OR MIT |
|
||||
| Neovim | neovim.io | Apache-2.0 + Vim license |
|
||||
| micro | github.com/zyedidia/micro | MIT |
|
||||
| Pandoc | pandoc.org | GPL-2.0-or-later |
|
||||
| Typst | github.com/typst/typst | Apache-2.0 |
|
||||
| Graphviz | graphviz.org | CPL-1.0 |
|
||||
| ripgrep / fd / bat / eza / zoxide / tealdeer / yq (mikefarah) | respective repos | MIT / Apache-2.0 / Unlicense (varies) |
|
||||
| bun *(`-omos` variant only)* | github.com/oven-sh/bun | MIT |
|
||||
|
||||
## Base OS
|
||||
|
||||
The image is built `FROM` a Debian base and installs packages via `apt`. Debian
|
||||
and its packages are distributed under their respective licenses (GPL, LGPL,
|
||||
MIT, BSD, and others). See each package's copyright file in the image under
|
||||
`/usr/share/doc/<package>/copyright`.
|
||||
|
||||
---
|
||||
|
||||
*Licenses marked "best effort" are widely known but were not each verified at
|
||||
the exact bundled version; consult the upstream project for authoritative
|
||||
terms. Corrections welcome.*
|
||||
@@ -0,0 +1,18 @@
|
||||
" opencode-devbox — system-wide Neovim defaults.
|
||||
"
|
||||
" This is Neovim's *system vimrc*: it loads for every user before any personal
|
||||
" ~/.config/nvim, and personal configs can still override it.
|
||||
"
|
||||
" Enable 24-bit ("true") colour. Without it, Neovim's default theme is squeezed
|
||||
" into a 256-colour palette where strings/comments become a muddy, low-contrast
|
||||
" dark colour — a common complaint over ssh/kitty where COLORTERM often isn't
|
||||
" propagated into the container. Modern terminals (kitty, WezTerm, iTerm2,
|
||||
" Alacritty, ...) all support true colour; the bundled kitty-terminfo also lets
|
||||
" Neovim auto-detect it, but forcing it here guarantees readable colour
|
||||
" regardless of how the terminal type / COLORTERM reach the container.
|
||||
"
|
||||
" Opt out for a session: :set notermguicolors
|
||||
" Override permanently: set your own value in ~/.config/nvim/init.lua
|
||||
if has('termguicolors')
|
||||
set termguicolors
|
||||
endif
|
||||
@@ -54,6 +54,38 @@ alias gs='git status'
|
||||
alias gd='git diff'
|
||||
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) ───────────────────────────────────
|
||||
# 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
|
||||
|
||||
@@ -9,3 +9,7 @@
|
||||
*.orig
|
||||
*.swp
|
||||
*.tmp
|
||||
|
||||
# Claude Code per-machine local settings: holds machine-specific permissions
|
||||
# and can carry credentials — must never be committed.
|
||||
**/.claude/settings.local.json
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# xterm-ghostty — alias of the maintained ncurses `ghostty` terminfo entry.
|
||||
#
|
||||
# Ghostty sets TERM=xterm-ghostty by default, but the ncurses terminfo
|
||||
# database (Debian: ncurses-term) ships the entry under the name `ghostty`
|
||||
# only — there is no `xterm-ghostty` alias, and no distro packages one. This
|
||||
# thin alias makes xterm-ghostty resolve to the same upstream-maintained
|
||||
# capability set, so SSH sessions from a Ghostty terminal work without
|
||||
# vendoring Ghostty's full (Zig-generated) terminfo here.
|
||||
#
|
||||
# `use=ghostty` is resolved by `tic` at compile time against the base
|
||||
# `ghostty` entry from ncurses-term (installed in Dockerfile.base before the
|
||||
# compile step). Compiled with `tic -x`.
|
||||
xterm-ghostty|Ghostty terminal emulator (xterm-ghostty alias),
|
||||
use=ghostty,
|
||||
@@ -8,6 +8,10 @@
|
||||
# - Entrypoint runs cleanly as non-root after UID adjustment
|
||||
# - Generated opencode.json has the expected shape
|
||||
# - MCP wrapper works (when mempalace is installed)
|
||||
# - typst PDF engine for pandoc — `pandoc --pdf-engine=typst`
|
||||
# - terminfo for modern emulators: xterm-kitty, xterm-ghostty, wezterm,
|
||||
# alacritty, foot (kitty-terminfo + ncurses-term + compiled ghostty alias)
|
||||
# - Neovim true-colour default (sysinit.vim termguicolors)
|
||||
#
|
||||
# Usage: ./scripts/smoke-test.sh <image> [--variant base|omos]
|
||||
#
|
||||
@@ -119,6 +123,10 @@ run "node" "node --version"
|
||||
run "npm" "npm --version"
|
||||
run "git" "git --version"
|
||||
run "nvim" "nvim --version | head -1"
|
||||
run "nvim true-colour default (sysinit.vim)" "nvim --headless -c 'lua os.exit(vim.o.termguicolors and 0 or 1)'"
|
||||
run "kitty-terminfo" "infocmp -x xterm-kitty >/dev/null 2>&1"
|
||||
run "terminfo: modern emulators (ncurses-term)" 'for t in wezterm alacritty foot ghostty st-256color; do infocmp -x "$t" >/dev/null 2>&1 || exit 1; done'
|
||||
run "terminfo: xterm-ghostty alias (tic)" "infocmp -x xterm-ghostty >/dev/null 2>&1"
|
||||
run "nano" "nano --version | head -1"
|
||||
run "micro" "micro --version"
|
||||
run "bat" "bat --version"
|
||||
@@ -139,6 +147,8 @@ run "gitea-mcp" "gitea-mcp --version"
|
||||
run "gosu" "gosu --version"
|
||||
run "tmux" "tmux -V"
|
||||
run "pandoc" "pandoc --version | head -1"
|
||||
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 "tldr (tealdeer)" "tldr --version"
|
||||
run "dot-watch" "test -x /usr/local/bin/dot-watch && bash -n /usr/local/bin/dot-watch && echo ok"
|
||||
|
||||
Reference in New Issue
Block a user