Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7b55905
feat(build): package the canonical npm root
ScriptedAlchemy Sep 5, 2026
0d24755
docs(changeset): reference PR 639
ScriptedAlchemy Sep 5, 2026
e61aadd
fix(package): close npm-root review gaps
ScriptedAlchemy Sep 5, 2026
c209793
fix(install): compare manifest-owned package bytes
ScriptedAlchemy Sep 5, 2026
d06670c
fix(build): preserve host install comparisons
ScriptedAlchemy Sep 5, 2026
bd3de9b
fix(build): align canonical root consumers
ScriptedAlchemy Sep 5, 2026
a25aea3
fix(build): reconcile latest artifact metadata
ScriptedAlchemy Sep 5, 2026
7519c39
fix(build): validate package lifecycle assets
ScriptedAlchemy Sep 5, 2026
faae260
fix(build): reconcile canonical npm root with manifest v2
ScriptedAlchemy Sep 5, 2026
92c7abf
fix(build): align npm root with compiler evidence policy
ScriptedAlchemy Sep 5, 2026
42e482e
fix(install): resolve package-root symlinks
ScriptedAlchemy Sep 5, 2026
6effcf8
docs(distribution): clarify canonical publish boundaries
ScriptedAlchemy Sep 5, 2026
78907be
test(manifest): canonicalize symlink expectations
ScriptedAlchemy Sep 5, 2026
b37a5b4
test(pack): isolate doctor host commands
ScriptedAlchemy Sep 5, 2026
02370d4
feat: complete manifest-driven npm distribution
ScriptedAlchemy Sep 6, 2026
f72cbaa
docs: bind npm root changeset to PR
ScriptedAlchemy Sep 6, 2026
bfa41d9
fix: close npm distribution review gaps
ScriptedAlchemy Sep 6, 2026
e78331d
Merge remote-tracking branch 'origin/main' into feat/555-npm-root
ScriptedAlchemy Sep 6, 2026
43da98f
test: restore manifest-declared executable modes
ScriptedAlchemy Sep 6, 2026
aec7f71
Merge remote-tracking branch 'origin/main' into feat/555-npm-root
ScriptedAlchemy Sep 6, 2026
d57ead8
fix: align standalone manifest inventory
ScriptedAlchemy Sep 6, 2026
6d0fecb
Merge remote-tracking branch 'origin/main' into feat/555-npm-root
ScriptedAlchemy Sep 6, 2026
4b1fc8e
Merge remote-tracking branch 'origin/main' into feat/555-npm-root
ScriptedAlchemy Sep 6, 2026
543928c
Merge remote-tracking branch 'origin/main' into feat/555-npm-root
ScriptedAlchemy Sep 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/canonical-npm-root.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"agent-bundle": minor
"create-agent-bundle": minor
---

Package the validated composite root as the npm root, point generated CLI bins at its manifest-declared executable, advance `agent-bundle.manifest.json` to version 3, preserve supported lifecycle assets and authored `AGENTS.md`, persist package-only compile evidence, reject unpublishable dependency protocols with `AB7015`, and report missing generated executables or lifecycle assets with `AB4767` and `AB4768`; rebuild and replace version 2 installs before managing them with this release (#656).
37 changes: 20 additions & 17 deletions docs/diagnostics.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/effect-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -645,8 +645,8 @@ Wiring rules:
- **Protocol stdout stays raw.** MCP stdio JSON-RPC (`mcp-entry.ts`,
`mcp run`), hook result JSON (`adapters/hook-contract.ts`), the emitted
routed-CLI shell (`cli-entry.ts`'s `writeOut`/`writeErr` ports and the
`entry-shell.ts` bin template), generated installers (`install-entry.ts`,
`install/surface.ts`), and child/worker stderr forwarding keep their direct
`entry-shell.ts` bin template), installers (`install/surface.ts`), and
child/worker stderr forwarding keep their direct
`process.stdout`/`process.stderr` adapters: emitted artifacts must not carry
a platform runtime, and byte-exact protocol frames are not terminal text.
- **The route-facing terminal capability is plain Node, not `Terminal`.**
Expand Down
189 changes: 75 additions & 114 deletions docs/entry-conventions.md

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions docs/framework-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,11 @@ the handwritten `runRscCli` compatibility path still serializes validated
results and never renders JSX. Routed `src/cli/**` commands and
`src/scripts/**` scripts follow one sentence: `.tsx` renders through the
Agent renderer (TTY progress, piped Markdown, `--json`, `--ndjson`); `.ts`
is plain. The routed CLI ships twice from one build: as the npm package bin
(`dist/bin/<name>.js`) for users who install the package, and as
`bin/<name>.mjs` inside the plugin root so the plugin's own skills,
hooks, and scripts can run it with `node` from the installed plugin root
(see [Entry conventions](entry-conventions.md#the-routed-cli-inside-the-plugin-root)).
is plain. The routed CLI compiles once as `bin/<name>.mjs` in the plugin root;
the npm root copies that proven executable unchanged and points its
`package.json` `bin` at it, so npm users and the plugin's own skills, hooks,
and scripts run the same command surface (see
[Entry conventions](entry-conventions.md#the-routed-cli-inside-every-distribution)).

## Release identity in source: `agent-bundle/meta`

Expand Down
4 changes: 2 additions & 2 deletions examples/audiobook-curator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Build and globally link the workspace package without a tarball:
```sh
pnpm --filter @agent-bundle-example/audiobook-curator build
cd examples/audiobook-curator
ln -s "$(pwd)/dist/bin/audiobook-curator.js" ~/.local/bin/audiobook-curator
ln -s "$(pwd)/dist/bin/audiobook-curator.mjs" ~/.local/bin/audiobook-curator
audiobook-curator --help
```

Expand All @@ -44,7 +44,7 @@ One `agent-bundle build` produces everything: one plugin root at `artifact/`
that both Claude Code and Codex install (each host's manifest directory,
`.claude-plugin/` and `.codex-plugin/`, over the shared Skill, bundled CLI
script, and lifecycle-wrapped MCP server) plus the npm package beneath `dist/`
(`dist/bin/audiobook-curator.js` for `package.json` `bin`, and `dist/index.js`
(`dist/bin/audiobook-curator.mjs` for `package.json` `bin`, and `dist/index.js`
plus declarations for `exports`). The example uses only public `agent-bundle`
and `@agent-bundle/runtime` exports with `workspace:*` dependencies.

Expand Down
2 changes: 1 addition & 1 deletion examples/audiobook-curator/agent-bundle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default defineConfig({
// #102 stage 4 adopts the in-house G7 projection for every curator tool.
routes: { mcpCommands: true },
// No `scripts` or `bin` fields needed: the routed `src/cli/` commands
// compile into the package executable (dist/bin/audiobook-curator.js) by
// compile into the shared artifact/package executable (bin/audiobook-curator.mjs) by
// convention (#102 stages 2-3).
// No `skills` field needed: `src/skills/curate-audiobooks/SKILL.md` is
// discovered by convention.
Expand Down
7 changes: 0 additions & 7 deletions examples/audiobook-curator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@
"engines": {
"node": ">=22.19.0"
},
"files": [
"dist",
"README.md"
],
"bin": {
"audiobook-curator": "./dist/bin/audiobook-curator.js"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion examples/host-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Two MCP servers ship in the plugin:
judged against the wire.

The rendered CLI `host-test dump [--conversation <id>] [--full] [--log <file>]`
(`dist/bin/host-test.js`) reads the same log outside any host.
(`dist/bin/host-test.mjs`) reads the same log outside any host.

The log lives at `$HOST_TEST_LOG_DIR/captures.ndjson` when that variable is
set, otherwise `$AGENT_BUNDLE_PLUGIN_ROOT/state/host-test/captures.ndjson`
Expand Down
2 changes: 1 addition & 1 deletion examples/host-test/agent-bundle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ export default defineConfig({
// The generated `host-test` MCP server (src/mcp/host-test/tools) hosts the
// shared event runtime; `src/mcp/host-test-raw.ts` is a hand-rolled stdio
// server that records the raw MCP request envelope for correlation.
// The rendered `src/cli/dump.tsx` command compiles into dist/bin/host-test.js.
// The rendered `src/cli/dump.tsx` command compiles into dist/bin/host-test.mjs.
targets: ['claude', 'codex', 'cursor', 'portable'],
});
7 changes: 0 additions & 7 deletions examples/host-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@
"engines": {
"node": ">=22.19.0"
},
"files": [
"artifact",
"README.md"
],
"bin": {
"host-test": "./dist/bin/host-test.js"
},
"scripts": {
"build": "agent-bundle build --output artifact",
"check": "pnpm validate && pnpm build && pnpm typecheck && pnpm test",
Expand Down
21 changes: 10 additions & 11 deletions packages/agent-bundle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,15 +291,13 @@ content)` (`AB7308`), `version mismatch` (`AB7309`), `foreign install`
(`AB7321`), `not installed` (`AB7307`), or `unknown` when the host inventory
could not be read.

When package outputs ship one of those host packs, the build also emits a
package-relative installer bin. It uses the plugin name when no configured bin
claims it and `<plugin-name>-install` otherwise. Map that name to the generated
`dist/bin/*.js` file in `package.json`; consumers run
`<bin> install <host> [--scope <scope>] [--replace|--force] [--json]` and
`<bin> uninstall <host> [--scope <scope>] [--mode local|marketplace] [--keep-data | --purge-data --confirm-purge] [--force] [--plan] [--json]`.
The executable locates the artifact directory beside the installed package, so
it works from `node_modules` regardless of the current directory. No npm
lifecycle performs an installation.
When package outputs ship one of those host packs, `dist/` becomes the npm
root containing that complete composite artifact. A generated routed CLI is
not compiled again: `package.json` points its `bin` at the manifest-declared
`bin/<name>.mjs` copied unchanged from the validated artifact. Consumers
therefore get the same complete command surface, including `web`, whether they
run the artifact or the npm-installed bin. No npm lifecycle performs a host
installation.

### Uninstall by receipt

Expand Down Expand Up @@ -1051,8 +1049,9 @@ self-contained module run as `node <plugin-root>/bin/<plugin-name>.mjs <command>
route can spawn its `../bin/<plugin-name>.mjs` sibling and a Claude skill can point at
`${CLAUDE_PLUGIN_ROOT}/bin/<plugin-name>.mjs` without a separate npm install. Every built-in host
publishes the `cli` capability that admits it; `inspect` accounts for it as a `cli` component, and
the manifest records both files with bundle provenance. The npm package bin under `dist/bin/` is
unchanged. See `docs/entry-conventions.md` for the layout and diagnostics (`AB4765`, `AB4766`).
the manifest records both files with bundle provenance. The generated npm root copies this
executable unchanged and points `package.json` `bin` at it. See `docs/entry-conventions.md` for the
layout and diagnostics (`AB4765`–`AB4767`).

### What gets hashed

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Plain object export keeps this packed fixture independent of the package build (#564).
export default {
bin: { 'web-surface-lifecycle': './src/lifecycle-proof.ts' },
mcp: {
servers: {
status: {
Expand Down
10 changes: 10 additions & 0 deletions packages/agent-bundle/fixtures/web-surface/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
"name": "web-surface-fixture",
"private": true,
"type": "module",
"version": "1.0.0",
"bin": {
"web-surface-lifecycle": "./dist/bin/web-surface-lifecycle.js"
},
"scripts": {
"postinstall": "node ./dist/bin/web-surface-lifecycle.js"
},
"dependencies": {
"typescript": "7.0.2"
},
"devDependencies": {
"@modelcontextprotocol/server": "2.0.0"
}
Expand Down
12 changes: 12 additions & 0 deletions packages/agent-bundle/fixtures/web-surface/src/lifecycle-proof.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { writeFile } from 'node:fs/promises';
import { createRequire } from 'node:module';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const require = createRequire(import.meta.url);

export const main = async (): Promise<number> => {
const typescript = require('typescript') as { readonly version: string };
await writeFile(join(dirname(fileURLToPath(import.meta.url)), '..', 'lifecycle-ran.txt'), `${typescript.version}\n`);
return 0;
};
1 change: 0 additions & 1 deletion packages/agent-bundle/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ const runtimeEntries = {
'cli-entry': './src/cli-entry.ts',
'event-ipc': './src/events/ipc.ts',
'event-project': './src/events/project.ts',
'install-entry': './src/install-entry.ts',
'launch-env': './src/launch-env.ts',
'mcp-entry': './src/mcp-entry.ts',
'mcp-server-runtime': process.env['AGENT_BUNDLE_RUNTIME_REBUNDLE_FIXTURE'] === '1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://scriptedalchemy.github.io/agent-bundle/schemas/agent-bundle.manifest.schema.json",
"title": "agent-bundle artifact manifest",
"description": "The authoritative `agent-bundle.manifest.json` written at the root of every compiled artifact (manifestVersion 2). The public contract and the operational `compiler` record are versioned independently (`compiler.recordVersion`). Keys are closed at every level. This schema mirrors the structural rules of `parseArtifactManifest`; the parser additionally enforces what JSON Schema cannot express: canonical `stableJson` bytes, sorted arrays with unique sort keys, cross-references between sections (hosts name declared projections, referenced paths name manifest files, `compiler.provenance` paths equal `files` paths, `compiler.adapters` hosts equal `projections` hosts, `compiler.project.revision` and `compiler.project.configDigest` match `compiler.project.sourceInputs`, each provenance `sourceInput` names a `compiler.project.sourceInputs` path, `compiler.validation.projections` mirror `projections`, server routes carry their server's id, rendered scripts name a script route, `inputSchema.required` names declared properties), the generated runtime floor for `runtime.node`, and npm package-name and semantic-version validity for `compiler.project.packageName` and `compiler.project.packageVersion`.",
"description": "The authoritative `agent-bundle.manifest.json` written at the root of every compiled artifact (manifestVersion 3). The public contract and the operational `compiler` record are versioned independently (`compiler.recordVersion`). Keys are closed at every level. This schema mirrors the structural rules of `parseArtifactManifest`; the parser additionally enforces what JSON Schema cannot express: canonical `stableJson` bytes, sorted arrays with unique sort keys, cross-references between sections (hosts name declared projections, referenced paths name manifest files, `compiler.provenance` paths equal `files` paths, `compiler.adapters` hosts equal `projections` hosts, `compiler.project.revision` and `compiler.project.configDigest` match `compiler.project.sourceInputs`, each provenance `sourceInput` names a `compiler.project.sourceInputs` path, `compiler.validation.projections` mirror `projections`, server routes carry their server's id, rendered scripts name a script route, `inputSchema.required` names declared properties), the generated runtime floor for `runtime.node`, and npm package-name and semantic-version validity for `compiler.project.packageName` and `compiler.project.packageVersion`.",
"type": "object",
"additionalProperties": false,
"properties": {
Expand All @@ -27,7 +27,7 @@
"uniqueItems": true
},
"manifestVersion": {
"const": 2
"const": 3
},
"projections": {
"type": "array",
Expand Down
8 changes: 3 additions & 5 deletions packages/agent-bundle/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { build as buildArtifact, type BuildResult } from './build/build.ts';
import { routedCliBins } from './build/cli-bins.ts';
import { planComposite } from './build/compose.ts';
import { buildPackageOutputs, type PackageBuildResult } from './build/package-build.ts';
import { rewritesWorkspaceProtocols } from './build/pack-dependencies.ts';
import {
packInventoryDiagnostics,
packOutputFromJson,
Expand Down Expand Up @@ -1299,7 +1298,7 @@ export const build = async (options: BuildOptions): Promise<BuildProjectResult>
let packageBuild: PackageBuildResult | undefined;
if (packageOutputRoot !== undefined) {
packageBuild = await buildPackageOutputs({
...(isInsideOrEqual(prepared.root, output) ? { artifactRoot: output } : {}),
artifactRoot: output,
model,
projectRoot: prepared.root,
...(prepared.tools === undefined ? {} : { tools: prepared.tools }),
Expand Down Expand Up @@ -1373,15 +1372,14 @@ export const prepack = async (options: BuildOptions): Promise<PrepackResult> =>
}]);
}
const { stdout } = await execFile('npm', ['pack', '--dry-run', '--json', '--ignore-scripts'], {
cwd: resolve(options.root),
cwd: result.packageBuild.outputRoot,
});
const pack = packOutputFromJson(stdout);
const diagnostics = await packInventoryDiagnostics({
artifactRoot: result.build.outputRoot,
model: result.model,
packageBuild: result.packageBuild,
packOutput: pack,
packerRewritesWorkspaceProtocols: rewritesWorkspaceProtocols(process.env.npm_config_user_agent),
packerRewritesWorkspaceProtocols: false,
projectRoot: options.root,
});
if (hasErrors(diagnostics)) throw new DiagnosticError(diagnostics);
Expand Down
10 changes: 8 additions & 2 deletions packages/agent-bundle/src/build/build.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mkdir, mkdtemp, rm } from 'node:fs/promises';
import { chmod, mkdir, mkdtemp, rm } from 'node:fs/promises';
import { basename, dirname, join, relative, resolve } from 'node:path';

import { rspack } from '@rslib/core';
Expand All @@ -22,7 +22,12 @@ import {
type CompiledHookEntry,
type CompiledMcpEntry,
} from './entries.ts';
import { planCliBinsSurface, planCompiledCliBins, type CompiledCliBin } from './cli-bins.ts';
import {
cliBinExecutableMode,
planCliBinsSurface,
planCompiledCliBins,
type CompiledCliBin,
} from './cli-bins.ts';
import { composeProjections, type CompositePlan } from './compose.ts';
import { projectMeta } from './meta.ts';
import {
Expand Down Expand Up @@ -810,6 +815,7 @@ export const build = async (options: BuildOptions): Promise<BuildResult> => {
}
}
}
await Promise.all(compiledCliBins.map((entry) => chmod(entry.output, cliBinExecutableMode)));
const publishedCompiledEntries = deepFreeze(compiledEntries.map((entry) =>
({
...entry,
Expand Down
11 changes: 6 additions & 5 deletions packages/agent-bundle/src/build/cli-bins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ const webHostPageScript = await readWebHostPageScript();

/**
* The artifact-hosted routed CLI (#387). A generated-mode `src/cli/**`
* surface already compiles into the npm package bin (`dist/bin/<name>.js`);
* this module emits the same compiled command graph into every host artifact
* surface compiles here into every host artifact
* whose adapter publishes the `cli` capability, as `bin/<name>.mjs` beside
* an optional `bin/<name>-flight.mjs` react-server worker. The bin is a
* plain self-contained ESM module invoked as `node <root>/bin/<name>.mjs`,
* exactly like the artifact's `scripts/*.mjs`, so hooks, skills, and script
* self-contained executable ESM module, so hooks, skills, scripts, and the npm
* package bin
* routes installed with the plugin can reach the routed CLI without a
* separate npm install. The package build's own bin emission is untouched.
* share one proven command surface without a second compilation.
*/

/** The one directory the compiler emits the routed CLI into; the registry pins every `cliBin` layout to it. */
export const cliBinDirectory: string = routedCliBinLayout.directory;
export const cliBinExecutableMode = 0o755;

/** The artifact-relative executable path for one routed-CLI bin. */
export const cliBinArtifactPath = (name: string): string => `${cliBinDirectory}/${name}.mjs`;
Expand Down Expand Up @@ -156,6 +156,7 @@ export const cliBinRslibEntries = (
[launchEnvRuntimeSpecifier]: launchEnvRuntimePath(),
...(entry.bin.web === true ? { [webHostRuntimeSpecifier]: webHostRuntimePath() } : {}),
},
banner: '#!/usr/bin/env node',
name: `bin-${entry.name}`,
virtualModules: [
operatorEnvLayerVirtualModule(),
Expand Down
4 changes: 3 additions & 1 deletion packages/agent-bundle/src/build/compile-evidence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { classifyExternal } from './external-policy.ts';
* states plainly what the compiler could not see.
*/
export const compileEvidenceFileName = 'agent-bundle.compile-evidence.json';
/** Package-only compiler evidence beside the canonical npm root's artifact evidence. */
export const packageCompileEvidenceFileName = 'agent-bundle.package-compile-evidence.json';

/** The self-containment policy the record was judged under; bump `revision` when `external-policy.ts` changes what it permits. */
export const externalPolicy = Object.freeze({ name: 'closed-world-externals', revision: 1 });
Expand Down Expand Up @@ -339,7 +341,7 @@ export const compileEvidenceDiagnostics = (
const nodeBundles = new Set([...compiled].filter((path) => !isViewAsset(path)));
for (const asset of record.assets) {
if (!compiled.has(asset.path)) {
diagnostics.push(evidenceDiagnostic(`names ${JSON.stringify(asset.path)}, which the manifest does not list as a compiled file.`));
diagnostics.push(evidenceDiagnostic(`names ${JSON.stringify(asset.path)}, which the file table does not list as a compiled file.`));
}
for (const external of asset.externals) {
if (isViewAsset(asset.path)) {
Expand Down
19 changes: 0 additions & 19 deletions packages/agent-bundle/src/build/entry-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,25 +169,6 @@ export const webHostRuntimeSpecifier = 'agent-bundle/web-host';

export const webHostRuntimePath = (): string => runtimeModulePath('web-host');

export const installEntryRuntimeSpecifier = 'agent-bundle/install-entry';

export const installEntryRuntimePath = (): string => runtimeModulePath('install-entry');

export const generatedInstallBinEntrySource = (options: {
readonly artifactRelativeUrl: string;
readonly hosts: readonly ('claude' | 'codex' | 'cursor')[];
readonly name: string;
}): string => [
`import { runGeneratedInstallProcess } from ${JSON.stringify(installEntryRuntimeSpecifier)};`,
'',
'process.exitCode = await runGeneratedInstallProcess(process.argv.slice(2), Object.freeze({',
` artifactRoot: new URL(${JSON.stringify(options.artifactRelativeUrl)}, import.meta.url),`,
` hosts: Object.freeze(${stableJson(options.hosts)}),`,
` name: ${JSON.stringify(options.name)},`,
'}));',
'',
].join('\n');

/**
* The code root a generated module falls back to when the host supplies no
* `AGENT_BUNDLE_PLUGIN_ROOT`, and with it where its state root derives absent
Expand Down
8 changes: 4 additions & 4 deletions packages/agent-bundle/src/build/launch-env-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
*/
export const launchEnvRuntimeSpecifier = 'agent-bundle/launch-env';

// This module is imported by the hook contract, which the installer bundle
// (`install-entry`) also carries and a consumer's own Rspack run re-bundles,
// so it must stay free of filesystem probing and `new URL(…, import.meta.url)`:
// `launchEnvRuntimePath` lives in `entry-shell.ts` beside the other paths.
// This module is imported by the hook contract and may be re-bundled by a
// consumer, so it stays free of filesystem probing and
// `new URL(…, import.meta.url)`: `launchEnvRuntimePath` lives in
// `entry-shell.ts` beside the other paths.

/**
* The generated module that applies the layer, served virtually to each
Expand Down
Loading
Loading