For AI agents: the complete documentation index is available at https://scriptedalchemy.github.io/agent-bundle/llms.txt, the full documentation bundle is available at https://scriptedalchemy.github.io/agent-bundle/llms-full.txt, and this page is available as Markdown at https://scriptedalchemy.github.io/agent-bundle/guide/distribution/index.md.
Skip to main content
  • English
  • Shipping a bundle

    There are two delivery forms, with the same compiled plugin inside them:

    DeliverableUse it for
    Composite artifact, artifact/ by defaultCopying a built plugin or following its generated native installation instructions.
    Generated npm root, dist/ when package output is enabledPacking an npm tarball with the artifact, package metadata, and any package-only entries.

    Neither form needs a handwritten host repackager. npm still needs its normal packaging step; that step must use the generated package root, not the source project or a second implementation of the application.

    The following npx --no-install commands run the compiler already installed in the developer project. They deliberately do not fetch a package by the unqualified agent-bundle name. See framework installation for the supported preview/release selector.

    The pipeline

    For installation from a source repository, configure the compiler to emit its root marketplace:

    export default defineConfig({
      plugin: { name: 'my-plugin' },
      targets: ['cursor', 'portable'],
      marketplace: true,
      output: { distPath: 'artifact', repositoryMarketplace: true },
    });

    After building, commit artifact/ and .cursor-plugin/marketplace.json (use git add -f for ignored generated output). The root marketplace points to ./artifact; every plugin manifest, script, skill, and installer is emitted by Agent Bundle. Consumers do not build. The same option emits .claude-plugin/marketplace.json and .agents/plugins/marketplace.json when Claude and Codex are selected. CI only needs to build, validate, and commit the output.

    npx --no-install agent-bundle build --output artifact
    npx --no-install agent-bundle validate --artifact artifact --strict
    StepWhat it establishes
    Source validation / buildThe authored declarations can be compiled into the selected projections. A successful build is not native-host execution evidence.
    Artifact validationThe bare composite artifact's files and digests agree with its manifest and the applicable validation rules. Host-tool checks depend on the selected validation options and available tools.
    Application and integration testsThe operations behave as expected; stronger packed-process/native-host claims need their own tests.
    Explicit installationThe chosen host receives the intended projection under its supported scope and ownership rules.

    A source validate run is useful before a typecheck or while editing, but it is not a substitute for validating the deliverable. validate --artifact does not require the source project. Installation is a separate operator action; building a plugin must not register it globally.

    How the root compiles

    The compiler discovers the application, resolves selected host projections, compiles the required browser/server entries, and assembles one validated tree. Shared paths must have compatible bytes, and a host must not accidentally discover another host's components.

    The generated manifest, not a consumer's filename probe, identifies the executable, its launch arguments, and its owning server or App. Do not reconstruct a server command from the first argument in a native mcp.json, guess an artifact/<host>/ directory, or rename generated executables after compilation. Advanced compiler details belong in architecture and artifact validation.

    What ships inside the root

    The composite includes the selected native manifests, shared component files, compiled entries, agent-bundle.manifest.json, persisted compile evidence, and generated INSTALL.md where applicable. It contains the plugin's actual names, not a template name consumers must replace. The project-structure guide shows the output layout.

    The composite root and a host's native install root are not always identical. Amp's directory plugin is nested at .amp/plugins/<name>/; the other built-in native projections read their manifests from the composite root. The framework's manifest-aware install --from command accepts the composite root and resolves the selected host's layout. Use its generated instructions rather than requiring end users to learn the nesting.

    Selecting cursor or portable includes the standalone install.mjs path described in host installation. That is a documented installation mechanism, not a universal claim that every portable client supports every native hook or App capability.

    Treat delivered code as immutable. Writable framework state is resolved independently of the installed code directory. Domain data, including refreshed sessions and application databases, needs a deliberate application-owned location and migration policy. Do not package live credentials, mutable caches, or operator data as assets.

    The npm-facing half

    For a project with package output enabled, such as the MCP starter, dist/ contains the complete npm root: the validated artifact copied unchanged, generated package.json, standard package documentation, and declared package-only bins/library output. There is no nested artifact/ inside the tarball.

    For a generated routed CLI, package.json.bin points directly at bin/<name>.mjs from the artifact. It has the same operation surface as the artifact CLI, including web when declared. An explicit authored package bin instead compiles to bin/<name>.js; these are different entry kinds, not two versions of the same routed CLI.

    Run the framework gate, then pack the generated directory:

    npx --no-install agent-bundle prepack --json
    npm pack ./dist --ignore-scripts

    prepack performs the release build and validates the dry-run package inventory, entry paths, artifact hashes, versions, and declared runtime dependencies. The second command creates the actual tarball. --ignore-scripts here prevents pack-time scripts from rebuilding a different product; it is not a promise that consumer install scripts are ignored during installation.

    Check the generated dist/package.json, its bin/exports, and the tarball file list. Do not patch the generated manifest by hand. Update authored package/configuration inputs and rebuild. The minimal and mcp-server starters are private development packages; an intentional public release also needs suitable authored package metadata and removal of their private: true. The cli-tool starter is publishable as scaffolded. This guide does not publish anything automatically.

    A static plugin distributed as a built directory does not need to invent a library or executable just to use native installation. See package entries when choosing npm delivery and its optional entry points.

    Consumer install scripts and dependencies

    Build tools are not automatically runtime dependencies. Self-contained generated JavaScript must not depend on the source checkout, workspace aliases, or the consumer installing the compiler. A prebuilt payload or an explicitly retained consumer install script may have real runtime dependencies; declare those accurately instead of externalizing ordinary generated entries to make the package smaller.

    Do not carry source-relative shell scripts into the installed package by accident. The package builder supports a bounded relocation of documented script forms and diagnoses unsupported ones. A package that passes only with --ignore-scripts during consumer installation has not proved its promised install lifecycle. Use isolated fixtures when testing scripts with side effects; never use real credentials or global host configuration for that test.

    An optional package-bound installer

    For a consumer-friendly my-plugin-install install <host> command, declare a package-only bin and delegate its implementation to the public framework entry. Merge this entry into the existing config rather than replacing unrelated entries:

    import { 
    const defineConfig: (config: AgentBundleConfig | ConfigFactory) => AgentBundleConfig | ConfigFactory
    defineConfig
    } from 'agent-bundle/config';
    export default
    function defineConfig(config: AgentBundleConfig | ConfigFactory): AgentBundleConfig | ConfigFactory
    defineConfig
    ({
    AgentBundleConfig.plugin: AgentBundlePluginConfig
    plugin
    : {
    AgentBundlePluginConfig.name: string
    name
    : 'my-plugin',
    AgentBundlePluginConfig.description?: string | undefined
    description
    : 'Project tools for an agent.' },
    AgentBundleConfig.targets?: string[] | undefined
    targets
    : ['claude', 'codex', 'cursor'],
    AgentBundleConfig.bin?: AgentBundleBinConfig | undefined
    bin
    : { 'my-plugin-install': './src/install-bin.ts' },
    });
    // src/install-bin.ts
    import { fileURLToPath } from 'node:url';
    import { runInstallCli } from 'agent-bundle/install';
    
    export const main = (argv: readonly string[]): Promise<number> =>
      runInstallCli(argv, {
        from: fileURLToPath(new URL('..', import.meta.url)),
        name: 'my-plugin-install',
      });

    The parent-directory binding refers to the emitted bin/ entry in the npm root. Run its built/installed form, not the source file as a substitute for an installation proof. The package build bundles the lifecycle implementation, so the consumer does not install the compiler just to use this bin.

    This is an opt-in entry, not an installer automatically added to every plugin. It reuses install, uninstall, and doctor with the package root bound once. There is no consumer-owned argv parser, native config merger, root-search loop, or private framework import. Supported flags and scopes are in host installation.

    Prove the installed package

    Install the actual tarball in a fresh temporary consumer and test its declared bin or named MCP server. Move or remove the source fixture, use a different working directory, and give it a separate writable state root. Confirm the expected tools and representative results. A test that launches the source tree's artifact/ is useful, but it is not an npm-install test.

    Artifact-only commands such as validate --artifact take the bare composite artifact. The manifest-aware install --from path accepts an npm root as well and excludes npm-only metadata from host ownership comparisons. Do not interchange those roots merely because both contain agent-bundle.manifest.json.

    Use public packed test helpers and the canonical manifest rather than copying a private installer or native-document parser into the plugin's test harness. Native account authorization and host execution remain separately qualified evidence.

    Install explicitly

    Consumers follow the delivered INSTALL.md, or invoke the package-bound installer when the plugin provides one. Developers who already have the compiler can use:

    npx --no-install agent-bundle install claude --from artifact --scope user

    Use only the intended host and scope. npm package installation is not host registration; framework build/prepack does not imply consent to modify a host. Read-only doctor and planned uninstall behavior are documented in host installation.

    In this section