Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bundle_submission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ body:
Thanks for contributing a bundle! This template captures metadata for maintainers to validate formatting, links, component resolution, and installation evidence. Maintainers do not audit, endorse, or support bundle code or installed components.

**Before submitting:**
- Review the [Bundles reference](https://github.com/github/spec-kit/blob/main/docs/reference/bundles.md)
- Review the [Bundle publishing guide](https://github.github.io/spec-kit/bundles/publishing.html)
- Ensure your bundle has a valid `bundle.yml` manifest
- Create a GitHub release with a versioned bundle artifact
- Test installation from a downloaded artifact: `specify bundle install ./your-bundle-1.0.0.zip`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Spec Kit combines ready-to-use processes with composable mechanisms:
| Automate prompts, commands, gates, and shell tasks | [Workflow](https://github.github.io/spec-kit/workflows/overview.html) |
| Modify an installed workflow without forking it | [Workflow overlay](https://github.github.io/spec-kit/workflows/overlays.html) |
| Add reusable executable behavior to workflows | [Workflow step](https://github.github.io/spec-kit/workflows/developing.html#custom-step-packages) |
| Install a curated setup for a role or team | [Bundle](https://github.github.io/spec-kit/reference/bundles.html) |
| Install a curated setup for a role or team | [Bundle](https://github.github.io/spec-kit/bundles/overview.html) |
| Discover community components | [Catalog](https://github.github.io/spec-kit/reference/catalogs.html) |
| Host a private catalog of approved components | [Catalog](https://github.github.io/spec-kit/reference/catalogs.html) |
| Access private catalogs and component downloads | [Authentication](https://github.github.io/spec-kit/reference/authentication.html) |
Expand Down
5 changes: 5 additions & 0 deletions bundles/assess/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ specify bundle remove assess
```

Removing the bundle uninstalls the workflow and the extension it contributed, unless they are still depended on by another installed bundle (FR-022). Components you installed independently are not attributed to this bundle and survive removal.

## See also

- [Bundle overview](https://github.github.io/spec-kit/bundles/overview.html)
- [Bundle CLI reference](https://github.github.io/spec-kit/bundles/cli.html)
5 changes: 5 additions & 0 deletions bundles/bugfix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ specify bundle remove bugfix
```

Removing the bundle uninstalls the workflow and the extension it contributed, unless they are still depended on by another installed bundle (FR-022). Components you installed independently are not attributed to this bundle and survive removal.

## See also

- [Bundle overview](https://github.github.io/spec-kit/bundles/overview.html)
- [Bundle CLI reference](https://github.github.io/spec-kit/bundles/cli.html)
6 changes: 6 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ To build the documentation locally:
- `workflows/overlays.md` - Workflow composition through overlays and slots
- `workflows/catalogs.md` - Workflow and step catalogs, releases, and trust
- `workflows/publishing.md` - Workflow publishing and catalog submission guide
- `bundles/overview.md` - Bundle user guide and first-party setups
- `bundles/cli.md` - Bundle management CLI reference
- `bundles/developing.md` - Bundle authoring and installation testing guide
- `bundles/api.md` - Manifest, reference expansion, and installed-record contracts
- `bundles/catalogs.md` - Bundle catalogs, policies, and release history
- `bundles/publishing.md` - Bundle publishing and catalog submission guide
- `community/extensions.md` - Community extension listing
- `integrations/index.md` - Integration directory and shared setup guidance
- `integrations/cli.md` - Shared integration management CLI reference
Expand Down
236 changes: 236 additions & 0 deletions docs/bundles/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# Bundle API reference

This page defines the declarative bundle manifest, reference expansion, and
installed-record contracts. Bundles compose existing components; they do not
provide a separate execution API.

## Manifest

The UTF-8 `bundle.yml` file is a YAML mapping. Bundle ZIPs must contain it at
the archive root. The developing guide provides complete examples.

| Field | Requirement |
| --- | --- |
| `schema_version` | Required; `"1.0"` or `"1.1"` |
| `bundle` | Required metadata mapping |
| `requires.speckit_version` | Required nonempty Spec Kit version constraint |
| `requires.tools` | Optional list of tool names; defaults to empty |
| `requires.mcp` | Optional list of MCP server names; defaults to empty |
| `integration` | Optional mapping with a nonempty `id` |
| `provides` | Optional component/reference mapping |
| `tags` | Optional list of strings |

An absent or null `requires`/`provides` mapping is treated as empty, although
the required Spec Kit constraint must still be supplied. A present non-mapping
value is invalid. String-list fields cannot be bare strings or contain
non-string members.

### Metadata

All fields in `bundle` are required and nonempty:

| Field | Meaning |
| --- | --- |
| `id` | Filesystem-safe bundle identifier |
| `name` | Human-readable name |
| `version` | Exact semantic version |
| `role` | Role, team, or persona served |
| `description` | Description of the setup |
| `author` | Author or organization |
| `license` | License identifier |

IDs match `^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$`: start and end with a
lowercase letter or digit, with lowercase letters, digits, dots, underscores,
and hyphens between. Path separators and traversal IDs are invalid.

Bundle and component versions use full `MAJOR.MINOR.PATCH` SemVer, optionally
with prerelease/build metadata and a leading `v` or `V`. Component ranges and
`latest` are not accepted. The Spec Kit requirement is instead a constraint,
such as `">=0.9.0,<2.0.0"`; it is evaluated during installation/update, not
against the running version by `bundle validate`.

`requires.tools` and `requires.mcp` generate requirement warnings. They do not
install tools, provision MCP servers, or verify those dependencies are present.

### Integration

```yaml
integration:
id: copilot
```

Omitting `integration` or setting it to null makes a bundle
integration-agnostic. A mapping without a nonempty ID is invalid.

The root bundle must agree with the project's active integration. It does not
switch integrations. Referenced bundle integration differences or an
indeterminate effective integration are warnings rather than additional
integration gates.

### Component references

`provides.extensions`, `provides.presets`, `provides.steps`, and
`provides.workflows` are lists of mappings. Omitted or null lists are empty.
Each `(kind, id)` may appear only once in a manifest, even with identical pins.
The same ID in different component kinds is distinct.

| Field | Extensions | Presets | Steps | Workflows |
| --- | --- | --- | --- | --- |
| `id` | Required | Required | Required | Required |
| `version` | Required | Required | Optional | Required |
| `source` | Optional catalog name | Optional catalog name | Optional catalog name | Optional catalog name |
| `priority` | Optional; default `10` | Required integer, at least `1` | Not used | Not used |
| `strategy` | Not used | Required | Not used | Not used |

Explicit extension priority must also be at least `1`. Preset strategies are
`replace`, `prepend`, `append`, and `wrap`; their effects are defined by the
[preset composition contract](../presets/api.md).

`source` asserts the expected winning component catalog. It does not select a
lower-priority catalog, bypass a discovery-only policy, accept a direct
artifact URL, or refer to bundle-local payloads. Explicit sources are checked
even for already installed components, require network access, and reject
ambiguous catalog names.

Without `source`, packaged extensions and presets take precedence over their
catalogs. Packaged workflows may also be used. The CLI reference explains
stable packaged patch compatibility and catalog pin enforcement.

### Bundle references

A nonempty `provides.bundles` list requires schema `"1.1"`. An empty or null
list has no references and is also accepted under schema `"1.0"`.

```yaml
provides:
bundles:
- id: qa-pack
version: 2.0.0
source: team-catalog
```

| Field | Requirement |
| --- | --- |
| `id` | Required safe slug; unique in this manifest and different from the parent ID |
| `version` | Required exact SemVer |
| `source` | Optional expected winning bundle catalog ID, not a URL |

References are resolved at command time through the same effective bundle
catalog stack as the parent. An explicit source is an assertion, not a
precedence override. A mismatch fails without falling through to another
catalog.

## Reference expansion

The result is a single flat component plan, not nested installations.

### Ordering and conflict rules

References are walked depth-first in declaration order, followed by the
declaring bundle's own components. The final plan preserves component grouping:
extensions, presets, steps, then workflows.

Each component is installed at most once per `(kind, id)`. Repeated declarations
agree when versions and sources match; omitted and explicit sources differ.
Extensions and presets must also agree on priority, and presets on strategy.
An omitted extension priority equals its default of `10`.

Conflicting sibling references fail unless the declaring bundle resolves them
with its own component declaration. At every level, a bundle's own declaration
wins over its references, takes its own declaration position, and emits an
override warning with the replaced declarations' origin chains.

One bundle ID can have only one version in an expansion. A second version is
an error, not another installation. Choose compatible referencing releases to
resolve that conflict.

### Limits and gates

- Cycles are rejected with their reference chain.
- At most `10` levels of reference nesting are allowed.
- At most `50` distinct referenced bundle IDs are allowed, excluding the root.
- Install and update enforce the Spec Kit version requirement for every bundle
in the graph.
- The root is the only integration gate. Referenced integration differences
generate warnings.
- Tools and MCP requirements are unioned across the graph for warnings.

`info` can expand discovery-only references for inspection. Install, update,
and online validate reject them as non-installable. `validate --offline` does
not expand references and warns once per declared reference. `build` performs
structural checks only; it neither resolves nor embeds referenced bundles.

Referenced manifests require network-backed catalog downloads. Local/offline
reference resolution and local `bundle info` previews are not supported.
First-party bundle catalogs keep no release history, so a first-party reference
can become unavailable when the catalog advances. Broader schema compatibility
negotiation is not implemented.

## Installed records and ownership

The project stores provenance in `.specify/bundle-records.json`:

```json
{
"schema_version": "1.0",
"updated_at": "2026-01-01T00:00:00Z",
"bundles": [
{
"bundle_id": "team-setup",
"version": "1.0.0",
"installed_at": "2026-01-01T00:00:00Z",
"required_components": [
{"kind": "extensions", "id": "bug", "version": "1.0.0"}
],
"contributed_components": [
{"kind": "extensions", "id": "bug", "version": "1.0.0"}
],
"installed_versions": {
"extensions:bug": "1.0.1"
}
}
]
}
```

| Record field | Meaning |
| --- | --- |
| `bundle_id`, `version` | Installed root bundle identity |
| `installed_at` | Original installation time, preserved across refresh/update |
| `required_components` | Every required component in the expanded plan, including independently supplied components |
| `contributed_components` | Components attributed to the bundle; always a subset of its requirements |
| `installed_versions` | Optional known actual versions keyed by plural `kind:id`, distinct from requested pins |
| `bundle_references` | Optional list of direct/transitive bundle references, each with `id`, `version`, and resolved catalog `source` |

Record component entries use plural `kind` names and contain `id`, `version`,
and any declared `source`, `priority`, and `strategy`. For a reference-bearing
bundle, only the parent has an installed record; child references are recorded
once, not installed as separate bundle records.

Required pins participate in cross-bundle conflict checks even when the
component was independently installed. Compatible independently installed
components are not adopted, refreshed, or uninstalled by the bundle. Components
already owned by other bundles can be shared.

Shared requirements must agree on version and source, extension/preset
priority, and preset strategy. A bundle update cannot replace a pin another
bundle requires. When removing a bundle or dropping a component during refresh,
components another bundle still needs are retained; ownership transfers to a
remaining requiring bundle if necessary.

Older records without `required_components` retain their known contributed
pins. A successful reinstall/refresh records the full requirements. Missing
records are treated as no bundles, but malformed records and incompatible
schema major versions are errors, not an empty installation.

Record writes happen after successful component operations. They do not make
installation, update, refresh, or removal globally transactional; see the CLI
reference for failure and rollback boundaries.

## See also

- [Developing bundles](developing.md)
- [CLI output and lifecycle behavior](cli.md)
- [Catalog entry and release contracts](catalogs.md)
- [Publishing bundles](publishing.md)
- [Bundle overview](overview.md)
Loading
Loading