SDK — Contributions

A contribution is anything a biome adds to Xema: an agent definition, a workflow, a skill bundle, a mount source, a connector binding, a UI route, a document template. The unified surface for every contribution is the contributions/ directory at the biome root, with one *.contribution.json file per contribution.

This page is the authoring guide for those files.


The directory shape

A typical biome's contributions/ directory looks like:

text
1contributions/
2├── agent.greeter.contribution.json
3├── workflow.escalation.contribution.json
4├── skill.documentation.contribution.json
5├── connector.github.contribution.json
6└── document-template.invoice.contribution.json

One file = one contribution. Filenames are kebab-case; the prefix before the first dot conventionally matches the contribution kind, but that is a convention, not a requirement — the file's kind field is authoritative.

Inline contributions are also possible — declare them directly in xema-biome.json under contributions.inline[]. Use inline only for one-or-two-shot trivia; the directory form scales better, is easier to diff, and matches the format the publish pipeline expects.


The contribution envelope

Every *.contribution.json shares the same shape:

ts
1interface Contribution<TKind extends ContributionKind, TManifest> {
2  kind:    TKind;             // closed enum value
3  slug:    string;            // kebab-case; biome-unique within this kind
4  version: string;            // semver; pinned by the lockfile
5
6  // Exactly one of the next two is required:
7  directory?: string;         // path to a folder of free-form assets
8  inline?:    TManifest;      // the kind-specific manifest, inline
9
10  metadata?: {
11    title?:    string;
12    summary?:  string;
13    tags?:     string[];
14  };
15}

Hard rules:

  • kind MUST be a value of the closed ContributionKind enum. Unknown values fail validation at xema biome lint time.
  • Exactly one of directory or inline MUST be present.
  • slug is unique within (biome, kind). The full registered slug is <biomeId>.<kind>.<slug>@<version>.

When to use directory

Use directory when the contribution is a folder bundle — multiple files, a README.md, scripts, reference material, or other free-form assets the runtime needs to mount.

The contribution kinds that benefit from a directory:

  • agent-skill — the canonical example. Skills are folder bundles with SKILL.md, reference/, scripts/, assets/, and recursive sub-skills.
  • agent-definition — when the agent ships templated prompts, intrinsic-tool fixtures, or per-language variants.
  • workflow-definition — when the workflow ships YAML plus support scripts or test fixtures.
  • document-template — when the template ships theme assets and snippets.
jsonc
1{
2  "kind":    "agent-skill",
3  "slug":    "documentation",
4  "version": "1.0.0",
5  "directory": "./skills/documentation",
6  "metadata": {
7    "title":   "Documentation Skill",
8    "summary": "Authors public Xema docs for the public documentation.",
9    "tags":    ["skill", "docs"]
10  }
11}

The runtime mounts the entire directory contents at the appropriate location — for agent-skill, that is the agent runtime's skills location inside the workspace, under a directory named after the contribution's slug. The platform reads only the contract files in the bundle (SKILL.md for skills); everything else is mounted as-is for the agent to discover.


When to use inline

Use inline when the contribution is a typed manifest — a small JSON object the runtime parses and acts on without needing to mount files.

The kinds that benefit from inline:

  • capability — a typed capability registration (ref, input/output schemas, side-effect labels).
  • role-capability — a role → capability mapping.
  • artifact-type — an artifact-type definition.
  • icon — a small icon descriptor.
  • connector-adapter — a connector provider registration.
jsonc
1{
2  "kind":    "artifact-type",
3  "slug":    "design-review-notes",
4  "version": "1.0.0",
5  "inline": {
6    "displayName": "Design Review Notes",
7    "category":    "documentation",
8    "validations": [
9      { "kind": "min-words", "min": 200 }
10    ]
11  }
12}

inline is a typed object whose shape is set by the kind's Zod schema (in @xemahq/<kind>-contracts). Unknown fields fail validation; required fields are non-negotiable.


The closed ContributionKind enum

A short, illustrative slice. The authoritative list is the ContributionKind enum in @xemahq/contracts/contribution.

KindBody shapeTypical layout
agent-definitioninline or directory./agents/<slug>.agent.yaml
agent-skilldirectory./skills/<slug>/SKILL.md + bundle
workflow-definitioninline or directory./workflows/<slug>.workflow.yaml
deliverable-specinlinetyped manifest
document-templatedirectorytemplate assets
document-themedirectorytheme assets
artifact-typeinlinetyped manifest
connector-bindinginlineprovider + auth ref
capabilityinlineref + schemas
role-capabilityinlinerole → capabilities
connector-adapterinlineprovider registration
project-kitdirectoryscaffold + bootstrap
frontend-routedirectoryroute module
host-extension-slotinlineslot id + module ref
widget-kindinlinewidget descriptor
iconinlineicon descriptor

Adding a new kind is a kernel PR — one enum entry plus the Zod schema for its inline shape. No new top-level directory, no new seeder, no scattered registry updates.


Validation, lint, install

Three checks fire on the contributions:

bash
1xema biome lint            # static: schema validation + boundary CI
2xema biome install ./       # runtime: register contributions with the local Xema
3xema biome publish ./       # push + cosign-sign the OCI artifact

Lint failures are typed and structural — the failure message names the file, the field, and the closed-set value that was expected.


Migration from legacy layouts

Older biomes used per-kind top-level directories (agents/, workflows/, skills/, …) and the xema.content.* / xema.modules.* manifest blocks. Both shapes lift cleanly into contributions/:

  • Every former xema.content.agents entry becomes one agent-definition contribution.
  • The top-level directories may stay where they are — the contribution files just point at them via directory.

The migration is mechanical and idempotent. The codemod tooling/codegen/biome-content-to-contributions.mjs (shipped with the AWP collapse phase) walks every biome and produces the contributions/ directory in place.


  • Manifest — the contributions block in xema-biome.json.
  • Biomes — the bigger picture of what a biome is.
  • Capabilities — capability contributions become invocation surfaces.
  • Skills — agent-skill contributions are the canonical folder bundles.

Previous: ← Manifest Next: Lifecycle Hooks →