Manifest reference
Every field a package manifest can carry, per kind.
Generated from the code that implements this. If the schemas, the platform table or the routes change, this page changes with them — and the tests fail if it does not.
A manifest describes one version of one package. It is validated on upload by the same schema this page is generated from, so anything not listed here is rejected — every manifest type is strict, and an unknown key is an error rather than a silently ignored field.
Common fields
Carried by every kind.
| Field | Type | Required | Rules | Notes |
|---|---|---|---|---|
name | string | yes | matches ^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$ | Package name without the scope. The scope is your username; SenClaw sets it, the manifest does not. |
version | string | yes | — | Semver. Required, unlike upstream plugin manifests — without an ordered immutable version you cannot pin, yank or diff. |
description | string | yes | 1–1024 chars | One line, shown in the store listing and search results. |
author | object | no | — | Who wrote it. Distinct from the publisher, which is the signed-in account that ran publish. |
author.name | string | yes | 1–128 chars | Display name. |
author.email | string | no | email format | Optional contact address. Published as-is, so use one you are happy to make public. |
author.url | string | no | uri format | Homepage for the author. |
license | string | no | ≤ 64 chars | SPDX identifier, e.g. MIT. Not validated against the SPDX list — a non-standard string is accepted and shown verbatim. |
homepage | string | no | uri format | Project homepage. |
repository | string | no | uri format | Source repository. Shown on the package page so a reader can compare published bytes against source. |
keywords | string[] | no | ≤ 16 items; each: ≤ 32 chars | Search terms. |
category | string | no | ≤ 32 chars | Free-text grouping, e.g. testing. |
permissions | object | no | — | What the package expects to touch. Optional, but omitting it is itself a signal — see the permissions reference. |
The permissions object has its own reference: Permissions.
Kind-specific fields
Each kind adds one block, named after the kind.
skill
| Field | Type | Required | Rules | Notes |
|---|---|---|---|---|
kind | "skill" | yes | — | Discriminator. Fixed per manifest type and chosen by which upload form or CLI subcommand you use. |
skill | object | no | — | Skill frontmatter, carried through verbatim. The registry does not interpret these; the agent does. |
skill.whenToUse | string | no | ≤ 1024 chars | When the agent should reach for this skill. This is what drives skill selection, so it is the most load-bearing field here. |
skill.allowedTools | string | no | ≤ 256 chars | Comma-separated tool allowlist. |
skill.disallowedTools | string | no | ≤ 256 chars | Comma-separated tool denylist. |
skill.model | string | no | ≤ 64 chars | Model the skill expects, e.g. claude-opus-5. |
skill.argumentHint | string | no | ≤ 128 chars | Hint shown when the skill is invoked with arguments. |
skill.userInvocable | boolean | no | — | Whether the skill can be invoked directly as /name. |
skill.disableModelInvocation | boolean | no | — | Whether the model is prevented from invoking it on its own. |
app
| Field | Type | Required | Rules | Notes |
|---|---|---|---|---|
kind | "app" | yes | — | Discriminator. Fixed per manifest type and chosen by which upload form or CLI subcommand you use. |
app | object | yes | — | App metadata. Required — an app is defined by its artifact matrix. |
app.updater | "none" | "tauri" | "electron" | no | default "none" | Which auto-update protocol the artifacts feed, and therefore what /updates serves for this package. |
app.artifacts | object[] | yes | 1–64 items | The platform matrix. One row per downloadable build. |
app.artifacts[].platform | "any" | "darwin-arm64" | "darwin-x64" | "win32-x64" | "win32-arm64" | "linux-x64" | "linux-arm64" | yes | — | Normalised as ${process.platform}-${process.arch}, so the CLI resolves a build with no guessing. Rust and Go triples are translated at publish time, never at install time. |
app.artifacts[].libc | "na" | "glibc" | "musl" | no | default "na" | glibc or musl for Linux builds; na everywhere else. Never null — a nullable libc would let two otherwise-identical rows both exist. |
app.artifacts[].format | "tgz" | "zip" | "dmg" | "exe" | "msi" | "nsis" | "appimage" | "deb" | "rpm" | yes | — | Installer or archive format. |
app.artifacts[].channel | "stable" | "beta" | "alpha" | no | default "stable" | Release lane. latest is a dist-tag; this is separate from it. |
app.artifacts[].filename | string | yes | ≤ 256 chars | Filename as downloaded. |
app.artifacts[].buildTriple | string | no | ≤ 64 chars | Exact build triple (aarch64-apple-darwin), kept for provenance. Resolution uses platform, not this. |
plugin
| Field | Type | Required | Rules | Notes |
|---|---|---|---|---|
kind | "plugin" | yes | — | Discriminator. Fixed per manifest type and chosen by which upload form or CLI subcommand you use. |
plugin | object | no | — | Plugin metadata. |
plugin.displayName | string | no | ≤ 128 chars | Human-readable name shown in the plugin list. |
plugin.defaultEnabled | boolean | no | — | Whether the plugin is active as soon as it is installed. |
plugin.components | object | no | — | What the plugin ships. Declared rather than counted so the package page can say "adds 3 agents and 6 workflows" before anything is downloaded. |
plugin.components.skills | integer | no | ≥ 0 | Number of skills bundled. |
plugin.components.commands | integer | no | ≥ 0 | Number of slash commands bundled. |
plugin.components.agents | integer | no | ≥ 0 | Number of subagents bundled. |
plugin.components.workflows | integer | no | ≥ 0 | Number of workflow scripts bundled. |
plugin.components.hooks | boolean | no | — | Whether it installs hooks. Hooks run commands on your machine, so this is the row to read first. |
plugin.components.mcpServers | boolean | no | — | Whether it configures MCP servers. |
plugin.components.lspServers | boolean | no | — | Whether it configures LSP servers. |
plugin.dependencies | (string | object)[] | no | ≤ 32 items | Other packages it needs: either a bare name, or { name, version }. |
workflow
| Field | Type | Required | Rules | Notes |
|---|---|---|---|---|
kind | "workflow" | yes | — | Discriminator. Fixed per manifest type and chosen by which upload form or CLI subcommand you use. |
workflow | object | yes | — | Workflow metadata. Required — a workflow with no entry point is not installable. |
workflow.entry | string | no | default "workflow.js"; ≤ 256 chars; matches \.js$ | Script inside the tarball. Must end in .js and must not traverse upward out of the workflows directory. |
workflow.whenToUse | string | no | ≤ 1024 chars | Mirrors the script's own meta.whenToUse, so SenClaw can show it without executing the script. |
workflow.phases | object[] | no | ≤ 32 items | Mirrors meta.phases — the stages the workflow runs, for display only. |
workflow.phases[].title | string | yes | ≤ 64 chars | Phase name. |
workflow.phases[].detail | string | no | ≤ 256 chars | One line on what the phase does. |
What the schema cannot express
Two rules are enforced on upload but cannot be represented as JSON Schema, so they do not appear as "Rules" above:
versionmust parse as semver. A version that does not is refused outright.workflow.entrymust not contain a..segment. The consumer extracts this
path, and upward traversal would write outside the workflows directory.