Skip to content

Commit c36c437

Browse files
Merge remote-tracking branch 'origin/main' into chore/tsgo-0.45
# Conflicts: # docs/effect-conventions.md
2 parents 5ad838d + f1db114 commit c36c437

92 files changed

Lines changed: 2079 additions & 1807 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎README.md‎

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# agent-bundle
22

3-
agent-bundle compiles an agent plugin — skills, hooks, MCP servers, and scripts, described by one typed config — into installable output for Claude Code, Codex, Cursor, portable Agent Plugins clients, and experimental Amp. You write the plugin once; the compiler emits each selected host's entry, manifests, and wrappers into one composite root. Amp is contract-verified against the pinned PluginAPI and install layout; live activation, tools, and events are runtime-unverified (no Amp account in CI).
3+
agent-bundle compiles an agent plugin (skills, hooks, MCP servers, and scripts, described by one typed config) into installable output for Claude Code, Codex, Cursor, portable Agent Plugins clients, and experimental Amp. You write the plugin once; the compiler emits each selected host's entry, manifests, and wrappers into one composite root. Amp is contract-verified against the pinned PluginAPI and install layout; live activation, tools, and events are runtime-unverified (no Amp account in CI).
44

55
Documentation: [scriptedalchemy.github.io/agent-bundle](https://scriptedalchemy.github.io/agent-bundle/) (English and 简体中文; guide, reference, generated type API, host capability matrices).
66

@@ -19,7 +19,7 @@ Use a PR number or the SHA of a commit whose package-preview run succeeded (ever
1919

2020
## Quick start
2121

22-
The fastest start is the scaffolder — it prompts for a name, a template
22+
The fastest start is the scaffolder. It prompts for a name, a template
2323
(`minimal`, `mcp-server`, or `cli-tool`), and the host targets, then emits a
2424
project that already passes its own `check`:
2525

@@ -53,25 +53,25 @@ npx agent-bundle dev --root . # local workbench with live rebu
5353

5454
`agent-bundle build` writes one composite root (`artifact/` by default; `--output` or `output.distPath` relocates it), and `targets` selects which host projections it carries: Amp's `.amp/plugins/<name>/index.js`, the `.claude-plugin/`, `.codex-plugin/`, and `.cursor-plugin/` manifests, and the portable `plugin.json`. Amp installs its nested directory; the other hosts install the composite root, and the generated `INSTALL.md` explains how. Omitting `targets` emits only the `portable` projection. The `amp` target is experimental: contract-verified, runtime-unverified.
5555

56-
The `portable` target is the [Agent Plugins open standard](https://agent-plugins.org/specification) (specification 1.0.0) adapter — the default projection, and the layout Cursor loads natively (Claude Code consumes it only through CLI translation). Every other client that reads this artifact is recorded with its tier, install command, and dated evidence in the `clients` section of that same capability table, rendered as the [hosts reference](https://scriptedalchemy.github.io/agent-bundle/reference/hosts). It emits the closed root `plugin.json` (canonical `$schema`, `name`, `version`, `description`, plus `author`, `homepage`, `repository`, `license`, `keywords`, and reverse-domain `extensions` authored under the `portable` config key), `skills/<name>/SKILL.md`, and `mcp.json` with stdio and Streamable HTTP servers whose `args`, `env` values, and `cwd` use the standard's `${PLUGIN_ROOT}`/`${PLUGIN_DATA}` placeholders. Rules, commands, hooks, marketplaces, and client extension directories are honestly unavailable there because the v1 standard packages only skills and MCP servers. Both documents are validated against the vendored, hash-pinned 1.0.0 schemas and the normative text at plan time (`portable.mcp.*.standard`), after every ordinary build and `validate --artifact` (`AB6011`/`AB6012` plus the Agent Plugins byte lane `AB6035`–`AB6037`), under `validate --artifact --host-validation` (same lane with the `AB6038` provenance note), and by `agent-bundle doctor` for installed Cursor local plugins that declare the standard's `$schema` (`AB7320`); see [Diagnostics](docs/diagnostics.md#agent-plugins-portable-validation-ab6035ab6038). Pins live in `packages/agent-bundle/src/adapters/schemas/portable/PROVENANCE.json`; the capability table `packages/agent-bundle/src/adapters/capabilities/portable-1.0.0.json` carries a dated row for every standard feature.
56+
The `portable` target is the [Agent Plugins open standard](https://agent-plugins.org/specification) (specification 1.0.0) adapter, the default projection, and the layout Cursor loads natively (Claude Code consumes it only through CLI translation). Every other client that reads this artifact is recorded with its tier, install command, and dated evidence in the `clients` section of that same capability table, rendered as the [hosts reference](https://scriptedalchemy.github.io/agent-bundle/reference/hosts). It emits the closed root `plugin.json` (canonical `$schema`, `name`, `version`, `description`, plus `author`, `homepage`, `repository`, `license`, `keywords`, and reverse-domain `extensions` authored under the `portable` config key), `skills/<name>/SKILL.md`, and `mcp.json` with stdio and Streamable HTTP servers whose `args`, `env` values, and `cwd` use the standard's `${PLUGIN_ROOT}`/`${PLUGIN_DATA}` placeholders. Rules, commands, hooks, marketplaces, and client extension directories are honestly unavailable there because the v1 standard packages only skills and MCP servers. Both documents are validated against the vendored, hash-pinned 1.0.0 schemas and the normative text at plan time (`portable.mcp.*.standard`), after every ordinary build and `validate --artifact` (`AB6011`/`AB6012` plus the Agent Plugins byte lane `AB6035`–`AB6037`), under `validate --artifact --host-validation` (same lane with the `AB6038` provenance note), and by `agent-bundle doctor` for installed Cursor local plugins that declare the standard's `$schema` (`AB7320`); see [Diagnostics](docs/diagnostics.md#agent-plugins-portable-validation-ab6035ab6038). Pins live in `packages/agent-bundle/src/adapters/schemas/portable/PROVENANCE.json`; the capability table `packages/agent-bundle/src/adapters/capabilities/portable-1.0.0.json` carries a dated row for every standard feature.
5757

58-
Claude Code language servers are declared under `claude.lspServers`; the `claude` projection emits the record as plugin-root `.lsp.json`. Agent Bundle expands path tokens only in `command`, `args`, `env`, and `workspaceFolder`, and it does not include the language-server binary — install that separately so the declared command is available on `PATH`. Codex, Cursor, and the portable format do not currently receive this host-scoped configuration.
58+
Claude Code language servers are declared under `claude.lspServers`; the `claude` projection emits the record as plugin-root `.lsp.json`. Agent Bundle expands path tokens only in `command`, `args`, `env`, and `workspaceFolder`, and it does not include the language-server binary, install that separately so the declared command is available on `PATH`. Codex, Cursor, and the portable format do not currently receive this host-scoped configuration.
5959

6060
Claude Code plugin defaults are declared under `claude.settings` and emitted as plugin-root `settings.json`, which Claude Code applies when the plugin is enabled. The pinned contract supports only `agent` and `subagentStatusLine`; Agent Bundle rejects any other key rather than shipping a default Claude Code would silently ignore, and it expands no path tokens here because `settings.json` is absent from the host's placeholder-substitution table. Because the plugin `agents/` component is still deferred, declaring `agent` also raises a warning: the referenced agent has to reach the plugin root some other way, such as a prebuilt payload.
6161

62-
Cursor Plugin manifest metadata is declared under `cursor.*` and emitted verbatim into `.cursor-plugin/plugin.json` by the `cursor` projection: `author` (`name`, optional `email`), `homepage`, `repository`, `license`, `keywords`, plus the schema-admitted `publisher`, `category`, `tags`, and `minClientVersions` (for example `{ cursor: '3.13.0' }`). Every field is validated against the pinned `cursor/plugins` manifest schema before emission — `author.url`, non-HTTP URLs, empty strings, and loose semver are rejected with `cursor.manifest.*` errors, and an invalid block emits no partial metadata. The Cursor Plugin documents never mix Agent Plugin (`plugin.json`, `${PLUGIN_ROOT}`) paths or tokens into the Cursor Plugin format; the portable projection owns that format, even when both share one root. The full documented-surface contract matrix (every Cursor hook event, cloud availability, hook options, marketplace and team-distribution surfaces, canvases, agents) lives as dated `supported` / `unavailable` rows in `packages/agent-bundle/src/adapters/capabilities/cursor-2026-08-28.json`.
62+
Cursor Plugin manifest metadata is declared under `cursor.*` and emitted verbatim into `.cursor-plugin/plugin.json` by the `cursor` projection: `author` (`name`, optional `email`), `homepage`, `repository`, `license`, `keywords`, plus the schema-admitted `publisher`, `category`, `tags`, and `minClientVersions` (for example `{ cursor: '3.13.0' }`). Every field is validated against the pinned `cursor/plugins` manifest schema before emission, `author.url`, non-HTTP URLs, empty strings, and loose semver are rejected with `cursor.manifest.*` errors, and an invalid block emits no partial metadata. The Cursor Plugin documents never mix Agent Plugin (`plugin.json`, `${PLUGIN_ROOT}`) paths or tokens into the Cursor Plugin format; the portable projection owns that format, even when both share one root. The full documented-surface contract matrix (every Cursor hook event, cloud availability, hook options, marketplace and team-distribution surfaces, canvases, agents) lives as dated `supported` / `unavailable` rows in `packages/agent-bundle/src/adapters/capabilities/cursor-2026-08-28.json`.
6363

64-
The same config also owns the npm package build — no second bundler config, bin shims, or hand-rolled stdio lifecycles. `bin` and `lib` entries (or the conventions `src/cli.ts`, `src/index.ts`, and `src/mcp/<server-id>.ts`) emit executable `dist/bin/<name>.js` bundles and a library output alongside the plugin root; an MCP entry that default-exports a server factory runs under a framework-owned stdio lifecycle; `tools.rsbuild` / `tools.rspack` is the one bundler escape hatch. [Entry conventions](docs/entry-conventions.md) is the full contract, and [Framework mode](docs/framework-mode.md) is the whole authoring model on one screen: structure in config and conventions (`src/skills/<name>/SKILL.md` ships with no declaration at all), JSX only where something is rendered.
64+
The same config also owns the npm package build, no second bundler config, bin shims, or hand-rolled stdio lifecycles. `bin` and `lib` entries (or the conventions `src/cli.ts`, `src/index.ts`, and `src/mcp/<server-id>.ts`) emit executable `dist/bin/<name>.js` bundles and a library output alongside the plugin root; an MCP entry that default-exports a server factory runs under a framework-owned stdio lifecycle; `tools.rsbuild` / `tools.rspack` is the one bundler escape hatch. [Entry conventions](docs/entry-conventions.md) is the full contract, and [Framework mode](docs/framework-mode.md) is the whole authoring model on one screen: structure in config and conventions (`src/skills/<name>/SKILL.md` ships with no declaration at all), JSX only where something is rendered.
6565

6666
## Commands
6767

68-
- `build` — validate the project and write the plugin root (plus the `bin`/`lib` package build when declared)
69-
- `validate` — check project source, or a built artifact with `--artifact <dir>`
70-
- `inspect` — show the normalized configuration and each selected host's projection plan; `--bundler` dumps the lowered Rspack config of every compiled output (post-`tools`-hatch merge, as Rslib/Rsbuild hand it to the compiler)
71-
- `dev` — serve the local development workbench and rebuild the `dist/` package build when its inputs change; `--install-host <claude|codex|cursor>` installs a development variant whose stable `dev proxy` MCP command hot-swaps epochs behind the host's open connection and re-syncs hooks and Skills on every adopted rebuild (see [Framework mode › Live development into hosts](docs/framework-mode.md#live-development-into-hosts))
72-
- `mcp list` / `mcp invoke` / `mcp run` — list, invoke, or run an artifact's MCP servers locally
73-
- `hooks list` / `hooks simulate` — inspect and simulate generated hooks
74-
- `eval` — run eval suites against a built artifact
68+
- `build`: validate the project and write the plugin root (plus the `bin`/`lib` package build when declared)
69+
- `validate`: check project source, or a built artifact with `--artifact <dir>`
70+
- `inspect`: show the normalized configuration and each selected host's projection plan; `--bundler` dumps the lowered Rspack config of every compiled output (post-`tools`-hatch merge, as Rslib/Rsbuild hand it to the compiler)
71+
- `dev`: serve the local development workbench and rebuild the `dist/` package build when its inputs change; `--install-host <claude|codex|cursor>` installs a development variant whose stable `dev proxy` MCP command hot-swaps epochs behind the host's open connection and re-syncs hooks and Skills on every adopted rebuild (see [Framework mode › Live development into hosts](docs/framework-mode.md#live-development-into-hosts))
72+
- `mcp list` / `mcp invoke` / `mcp run`: list, invoke, or run an artifact's MCP servers locally
73+
- `hooks list` / `hooks simulate`: inspect and simulate generated hooks
74+
- `eval`: run eval suites against a built artifact
7575

7676
When the `claude` projection is selected, validating the built root also runs the installed
7777
Claude Code developer toolchain in addition to the pinned schemas. Use
@@ -96,7 +96,7 @@ Run these from the repository root. `pnpm examples:check` validates and builds e
9696

9797
## Development
9898

99-
`pnpm check` runs the local delivery gate (build, unit and integration tests, lint, typecheck); `pnpm check:release` adds the packaging gates. `pnpm check:local-ci` mirrors the full hosted CI gate — the three-Node verify matrix plus the examples, release, and micro-eval jobs — in parallel local worktrees, and is the merge gate for the local-merge workflow described in [docs/local-ci.md](docs/local-ci.md). Versioning goes through Changesets. Native Claude/Codex host smokes are opt-in and intentionally skipped in CI. The Workbench architecture and the optional RSC runtime are documented in [docs/architecture/rsc-runtime-workbench.md](docs/architecture/rsc-runtime-workbench.md).
99+
`pnpm check` runs the local delivery gate (build, unit and integration tests, lint, typecheck); `pnpm check:release` adds the packaging gates. `pnpm check:local-ci` mirrors the full hosted CI gate, the three-Node verify matrix plus the examples, release, and micro-eval jobs, in parallel local worktrees, and is the merge gate for the local-merge workflow described in [docs/local-ci.md](docs/local-ci.md). Versioning goes through Changesets. Native Claude/Codex host smokes are opt-in and intentionally skipped in CI. The Workbench architecture and the optional RSC runtime are documented in [docs/architecture/rsc-runtime-workbench.md](docs/architecture/rsc-runtime-workbench.md).
100100

101101
## Status
102102

‎agent-patterns/effect-concurrency.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ lifecycle). Build those Effect-native from day one behind Promise edges.
1010

1111
## Fibers
1212

13-
- `yield* Effect.forkChild(effect)` — structured child of the current fiber.
14-
- `Fiber.await` / `Fiber.join` / `Fiber.interrupt` — observe or cancel.
13+
- `yield* Effect.forkChild(effect)`: structured child of the current fiber.
14+
- `Fiber.await` / `Fiber.join` / `Fiber.interrupt`: observe or cancel.
1515
- Prefer exported Fiber functions over `interruptUnsafe` / `pollUnsafe`.
1616
- Forked work that owns a resource must be forked *into a scope*
1717
(`forkScoped` / `Layer.scoped`) so interruption closes the resource.
@@ -20,7 +20,7 @@ Host `AbortSignal` still exists at the edges (`dispatch()` / `stream()`).
2020
Do not thread extra internal signals once the program is an Effect; interrupt
2121
the fiber (`Stream.interruptWhen` + `abortToInterrupt`). `Latch.makeUnsafe`
2222
is the legal sync bridge when a web `ReadableStream.pull` must open demand
23-
for an Effect stream — do not invent a second AbortSignal for that.
23+
for an Effect stream, do not invent a second AbortSignal for that.
2424

2525
## Bounded work
2626

@@ -37,8 +37,8 @@ for an Effect stream — do not invent a second AbortSignal for that.
3737

3838
## Racing and cancellation
3939

40-
- `Effect.raceFirst(a, b)` — first to complete wins; the loser is interrupted.
41-
- `interruptWhenAborted(effect, signal)` — host deadline into a race with
40+
- `Effect.raceFirst(a, b)`: first to complete wins; the loser is interrupted.
41+
- `interruptWhenAborted(effect, signal)`: host deadline into a race with
4242
`Effect.interrupt`.
4343
- Do not `Promise.race` around Effects. Race inside Effect, `runPromise` once.
4444

@@ -50,5 +50,5 @@ for an Effect stream — do not invent a second AbortSignal for that.
5050
`Fiber` you join/interrupt.
5151
- Using `PubSub` when consumers should compete (that's a `Queue`).
5252
- Using `Queue` when every subscriber needs every event (that's `PubSub`).
53-
- Coalescing rebuilds with debounce timers (`setTimeout`) — `Latch` +
53+
- Coalescing rebuilds with debounce timers (`setTimeout`): `Latch` +
5454
fiber, not host timers (`globalTimersInEffect`).

0 commit comments

Comments
 (0)