Skip to content

feat: opt-in workspace dev mounts (edit Pi extensions without an image rebuild)#786

Draft
runyaga wants to merge 1 commit into
mainfrom
feat/workspace-dev-mounts
Draft

feat: opt-in workspace dev mounts (edit Pi extensions without an image rebuild)#786
runyaga wants to merge 1 commit into
mainfrom
feat/workspace-dev-mounts

Conversation

@runyaga

@runyaga runyaga commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Opt-in (off by default) fast-iteration path for the container side: edit Pi extensions in a running workspace without the klangk:build-workspace-image (podman build) round-trip. Companion to the web-frontend dev mode in #785 — same "layered, opt-in, default-unchanged" philosophy.

How

The workspace container is long-lived (sleep infinity; sessions via podman exec) and Pi auto-discovers ~/.pi/agent/extensions/ in addition to the baked image dir (klangk-setup-clankers.py:64). So a host dir mounted there is additive — it doesn't hide the baked builtin/plugin extensions — and host edits show up on the next workspace open with no rebuild.

export KLANGK_WORKSPACE_DEV=1
export KLANGK_WORKSPACE_DEV_EXTENSIONS_DIR=$PWD/src/containers/workspace/builtin-extensions
# start the stack normally; edit a .ts file; reopen the workspace -> live, no podman build

container.py::workspace_dev_mounts() returns the extra read-only bind specs appended to the container binds; returns [] (default/prod unchanged) when the flag is off, the dir is unset, or the dir is missing (missing logs a warning).

Validation

  • Live on the real klangk-arm64 image: mounted a host dir of extensions into a running workspace container; a host edit reflected live with no rebuild and no restart, including the nested case under the /home mount.
  • Unit tests: full branch coverage of workspace_dev_mounts() (flag off / off-with-dir / on-no-dir / on-missing-dir-warns / on-valid-dir / disabled-value). 6 tests, all green.
  • Note: 3 unrelated TestAllowedMountRoots/TestProtectedPaths tests fail locally on macOS only (/tmp/private/tmp realpath); they fail identically on main and pass on Linux CI.

Scope / follow-ups

Covers extensions (the common case). Tools (/opt/klangk/bin) and the frequently-edited klangk-* scripts live outside /home and would need per-file mounts or a merged dir — left as a follow-up to keep this additive and small.

See docs/dev/workspace-dev-mounts.md. Strategy rationale in #785's docs/dev/web-fast-iteration.md.

…eration

KLANGK_WORKSPACE_DEV=1 + KLANGK_WORKSPACE_DEV_EXTENSIONS_DIR mounts a host
directory of Pi extensions read-only into ~/.pi/agent/extensions, which Pi
auto-discovers in addition to the image's baked extensions. So an extension
edit takes effect on the next workspace open with no podman image rebuild, and
the baked builtin/plugin extensions are not hidden (additive mount).

- container.py: workspace_dev_mounts() helper, appended to container binds.
  Returns [] (default/prod unchanged) when off / dir unset / dir missing.
- tests: full branch coverage of the helper.
- docs/dev/workspace-dev-mounts.md: usage + scope.

Validated on the real klangk-arm64 image: host edit reflects live in the
running container with no rebuild/restart, including nested under the /home
mount.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant