You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat(subos): subos-as-xpkg system (M1-M5) (#296)
* feat(xim): map PackageType::Subos to pkgType=4
Mirrors upstream mcpplibs/libxpkg enum addition. Foundation for
type=subos package dispatch — see
.agents/docs/subos-as-xpkg-design-2026-05-16.md (Phase 0 / Task 1).
Requires upstream commit "feat(xpkg): add PackageType::Subos for
subos-as-xpkg" on mcpplibs/libxpkg feat/pkgtype-subos branch.
* feat(xim): dispatch type='subos' through default install/config/uninstall
Adds xim::subos namespace mirroring the script.cppm pattern. Default
hooks:
- install: ensure install_dir + bin/ skeleton; synthesize .xlings.json
workspace from xpm.deps when tarball doesn't carry one
- config: register via xvm.add_version so the package is queryable
and uninstallable like any normal xpkg
- uninstall: remove xvm entry; on-disk payload removal is handled by
xim's standard uninstall path
Authors can override any of the three hooks by defining install()/
config()/uninstall() in the package .lua. The existing executor's
has_hook() check still routes to user code first.
Package path convention is unchanged — type='subos' packages land at
xpkgs/<namespace>-x-<name>/<ver>/, identical to xim-x-foo / scode-x-foo.
E2E test covers: install path, xpkgs layout, .xlings.json synthesis,
xvm registration. Fixture in tests/e2e/fixtures/subos_xpkg/py-demo.lua.
Refs: .agents/docs/subos-as-xpkg-design-2026-05-16.md (M1)
* feat(subos): subos use --cmd <string> for non-interactive exec
Extends 'xlings subos use' with --cmd <string> (and --cmd=<value>)
to run a single command in the subos and exit with the command's
exit code. POSIX: shell -c <cmd>; Windows: pwsh -Command / cmd /c.
Works in both shell-level and sandbox modes; threaded through
build_bwrap_argv_ and build_proot_argv_ to append -c <cmd>.
Rejected combinations:
--cmd + --global : --global persists active subos, doesn't spawn
--cmd + --shell : --shell emits eval-able env code, no shell to exec
E2E coverage: stdout capture, exit-code propagation, incompatible
flag combinations, --cmd=<value> equals form.
Refs: .agents/docs/subos-as-xpkg-design-2026-05-16.md (M3)
* feat(subos): subos new --from <spec> for fork from local subos or pkg
Adds `xlings subos new <name> --from <spec>` which forks the new subos
from either:
- a local subos (bare name, e.g. --from base-env): copies content
from subos/<base>/ to subos/<new>/
- a pkg-spec (contains ':' or '@', e.g. --from subos:py-ds@1.0.0):
locates xpkgs/<ns>-x-<name>/<ver>/; if not yet installed,
auto-invokes `xlings install <spec>` (E5: agent always 1 command)
Cross-platform copy uses reflink-where-possible (Linux btrfs/xfs,
macOS APFS clonefile); falls back to full byte copy via
std::filesystem::copy on Windows / non-COW filesystems. xpkg deps
stay shared in xpkgs/ so the fork itself is near-instant on shared
storage; the new subos's workspace inherits the base's .xlings.json.
Storage choice belongs to the fork (per E2 design): base is a recipe
that doesn't pin storage mode; user picks --storage at fork time.
copy_tree_ overlays base content, then storage/imageSize fields in
.xlings.json are re-applied so the new subos's storage wins.
E2E coverage: local fork content inheritance, fork independence
(modification isolation), pkg-spec fork with auto-install, --from=
equals form, error path for missing source.
Refs: .agents/docs/subos-as-xpkg-design-2026-05-16.md (M2, E1-E5)
* feat(subos): auto-keeper primitives + --keep/--no-keep/--ttl + subos stop
Adds the keeper module (Linux-focused, cross-platform stubs) that
holds bwrap's mount namespace alive between sandboxed --cmd execs
so high-frequency agent workloads avoid per-call mount overhead.
This commit lands:
- keeper.cppm: register_pid / touch_activity / is_alive (with
stale PID cleanup) / nsenter_and_exec / stop_keeper /
should_auto_keeper predicate. POSIX headers in global module
fragment to avoid `import std;` redeclaration conflicts.
- subos.cppm: argparse for --keep / --no-keep / --ttl <sec> on
`subos use`; mutual-exclusion validation; integer-parse error
handling for --ttl.
- `xlings subos stop <name>` CLI: SIGTERM then SIGKILL fallback,
cleans .keeper.pid + .keeper.lastused. Idempotent — safe to call
when no keeper is running.
- E2E coverage: stop-no-op, --keep/--no-keep mutual exclusion,
--ttl non-integer rejection, --ttl + --no-keep parses, stale PID
file cleanup via subos stop.
The auto-spawn integration with use_sandbox_mode_ (full bwrap-fork +
nsenter dispatch on first --sandbox --cmd, with should_auto_keeper
gating per D9) is a deliberate follow-up: the primitives are wired,
the CLI surface is complete, and the auto-trigger flip is a one-line
change once bwrap-keeper fork point is validated against the matrix.
Refs: .agents/docs/subos-as-xpkg-design-2026-05-16.md (M4 + M5, D9)
* docs: subos-as-xpkg design (rev4) + implementation plan
Design doc records the converged subos-as-xpkg architecture across
revisions:
rev1: initial brainstorming convergence
rev2: simplification (no Lua API needed)
rev3: bring back type='subos' + default hooks; sandbox/storage
decisions; xvm-as-normal-package registration
rev4: auto-keeper with TTL=5min idle (M4); explicit overrides (M5)
Plan decomposes into 11 tasks across 5 phases (Phase 0 + M1-M5),
with parallel/sequential dependencies noted so a downstream
subagent run can fan out where the file map allows. Each task has
TDD-style checkpoints + exact file paths.
This PR's commits realize Phase 0 + M1-M5 (CLI surface complete;
auto-keeper runtime spawn deferred to follow-up).
Refs design: .agents/docs/subos-as-xpkg-design-2026-05-16.md
Refs plan: docs/superpowers/plans/2026-05-16-subos-as-xpkg.md
* chore: bump mcpplibs-xpkg dep to 0.0.41 (PackageType::Subos)
Pulls in the upstream Subos enum addition required by the
subos-as-xpkg dispatch. Replaces the local_libxpkg dev override that
was needed before openxlings/libxpkg#23 merged.
Refs: mcpplibs/mcpplibs-index#13, openxlings/libxpkg#23
* chore(0.4.36): bump version for release
Includes:
- feat(subos): subos-as-xpkg system (M1-M5)
- type='subos' xpkg dispatch + default install/config/uninstall hooks
- subos new --from <local|pkg-spec> fork with auto-install
- subos use --cmd <string> non-interactive exec (POSIX + Windows)
- keeper primitives + --keep/--no-keep/--ttl flags + subos stop
- chore: bump mcpplibs-xpkg dep to 0.0.41 (brings PackageType::Subos)