Repository navigation
Package generated host packs into publishable npm plugins with a package-relative installer #252
Copy link
Copy link
Closed
Description
Summary
Make a plugin produced by Agent Bundle publishable as a self-contained npm package. Installing the tarball must provide the exact generated Claude, Codex, and Cursor host packs plus a package-relative install command, without requiring the source repository, a checkout path, or a project-maintained install script.
This is the missing distribution boundary between the host packs tracked by #181 and ordinary npm publishing. It does not require a reusable GitHub Action: once the package is self-contained, the repository's existing Changesets/npm/provenance flow is sufficient.
Verified gap
- Agent Bundle currently writes generated host artifacts to the configured artifact directory while npm package outputs are built separately into dist.
- The publishable scaffolder allowlists dist and README, so npm pack excludes the generated host packs, INSTALL.md, install.mjs, marketplace manifests, skills, hooks, MCP entries, and artifact provenance.
- The framework install command defaults its source bundle to the current working directory; a published plugin has no package-local entrypoint that resolves its bundled host packs from import.meta.url.
- Cargo Hauler therefore still maintains host-install documentation and a Cursor installer even though that logic is framework-generic. Its current npm manifest is private and its allowlist would not publish artifact/plugin.
- The framework release checks prove compiler-package tarballs and local built-directory installs, but not installing a plugin from the exact tarball intended for publication after deleting its source tree.
Relationship to existing issues
- Feature: emit ready-to-install host packs (and/or an 'agent-bundle install <host>' command) so projects don't hand-maintain install scripts #181 owns host-pack layouts and framework install mechanics from a built bundle directory.
- Add safe managed lifecycle for generated host bundles #101 owns managed lifecycle semantics such as update, repair, rollback, receipts, and uninstall.
- Track Claude Code plugin contract parity beyond the current adapter #187 and Track Codex plugin manifest, hooks, marketplace, and policy parity #188 own Claude and Codex marketplace/npm-source parity.
- Generated plugin contract matrix: catch source→artifact→dev→installed-host drift before release #218 owns the generated source-to-artifact-to-installed-host contract matrix.
This issue owns packaging those outputs into a consumer plugin's npm tarball and locating them at runtime from the installed package.
Acceptance criteria
- A publishable plugin tarball contains every selected host pack, required executable payload, marketplace manifest, skills/hooks/MCP resources, INSTALL.md, and artifact manifest/provenance.
- A generated package-local bin resolves the bundled artifact from import.meta.url rather than process.cwd(), then delegates to the existing Agent Bundle installer for Claude, Codex, and Cursor.
- npm install itself performs no host mutation; installation is an explicit documented command such as npx install .
- From an empty directory, after deleting the repository and source tree, a test installs the exact packed tarball and registers each supported host from package-local assets.
- Generated scaffolds provide correct files, bin, and prepack/build behavior with no project-maintained host installer.
- npm pack --json validates the full expected host-pack inventory and fails for missing, stale, or source-relative entries.
- Package version, host-manifest version, artifact provenance, and installed version are checked for agreement.
- The release workflow publishes the same verified tarball; no separate host-specific publishing service or reusable GitHub Action is introduced unless later evidence requires one.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
ScriptedAlchemy commentedon Sep 2, 2026
Decision (2026-09-01): prioritized next — lane in flight; cargo-conductor #25/#26 are the first consumers.
test(install): empty-dir packed-tarball host-install proofs for the p…
fix(package): keep the generated installer's artifact URL statically …
feat(scaffold): publishable host-pack templates with generated instal…
ScriptedAlchemy commentedon Sep 2, 2026
Landed across four PRs, all gated locally (scoped tests + typecheck + lint, plus the real-host proofs):
#281 — framework contract (
2655ca58d)dist/bin/<name>-install.js, or<name>.jswhen the package has no other bin claim on the plugin name). It resolves the bundledartifact/root fromimport.meta.url— neverprocess.cwd()or repo layout — and delegates to the existingagent-bundle installengine (installBundle).npm installitself never mutates a host; installation is the explicitnpx <bin> install <host> [--scope user|project] [--json].agent-bundle prepackcommand: runs the release build, thennpm pack --dry-run --json --ignore-scripts, and fail-closes the tarball inventory via the sharedpackOutputFromJson— AB7010 missing allowlisted artifacts, AB7011 stale artifact hashes vs the artifact manifest, AB7012 bin targets not shipped, AB7013 package/host-manifest/artifact version disagreement.#283 — empty-dir install-from-tarball proof (
09ac90b0f)packed-host-install-proof.test.tsat thehost-installproof level: oneagent-bundle prepackfixture build, one realnpm pack,npm installof the exact tarball into a verified-empty consumer, source tree deleted and asserted absent, then per host the installednode_modules/.bin/<bin> install <host> --jsonruns. Claude Code 2.1.257 and codex-cli 0.147.0 registrations observed through the hosts' own CLIs (binary-gated with honest skips), Cursor placement schema-validated and idempotent; installed/registered versions asserted equal to the fixture package version. Wired astest:host-install:packedand intonative-host-smoke.yml.#288 — packed-consumer regression fix (
abf73be61)new URL(<non-literal>, import.meta.url)inside the shared installer runtime made Rspack synthesize a directory ContextModule in consumers that build through a tarball-installedagent-bundle, and the provenance collector correctly fail-closed (AB5000). The baked-literal URL resolution moved into the generated wrapper; regression coverage rides the packed-consumer deleted-source journey.#289 — scaffold adoption + release wiring (
0b46b0278)cli-toolandmcp-servertemplates shipartifactinfiles, the generated installer bin, andagent-bundle prepackas npmprepack; the skills-onlyminimaltemplate intentionally stays unpackaged. The release matrix asserts the packed inventory (artifact manifest, all three host manifests, installer bin) from a realnpm pack.pnpm release=pnpm check:release && changeset publish(pack dry-run, release audit, packed release pool — including the scaffolder matrix — before any publish), and the changesets publish step setsNPM_CONFIG_PROVENANCE: true.One deliberate remainder, owned by the release owner rather than this issue:
.changeset/config.jsonkeeps"access": "restricted"until the final package name/scope + license decision documented indocs/preview-packages.md; the provenance publish path is wired and gated behind it.Downstream: cargo-conductor #25/#26 can adopt this directly — notes posted there. Closing.