skills

Build & Distribution

Every product skill is authored once under src/skills/. The distribution catalog renders complete committed installation units under skills/ and plugins/, including target-specific names, references/assets, and bundled dependency-free .mjs runtime where needed. Edit the canonical owner or shared source, never a generated payload.

The build contract

  • pnpm run build runs tsx scripts/build-generated.ts and writes all declared installation units through staged validation and replacement.
  • pnpm run build:check runs the same owner with --check, comparing complete file inventories, content, and executable modes without mutating tracked files.
  • tests/tooling/generated-output-sync.test.ts runs the drift guard as part of pnpm test.

TypeScript, Vitest, and esbuild are developer tooling only. Installed skills with bundled runtime still run committed Node ESM with no dependency installation step. The instruction-only seshtk-cli skill instead uses the external @tkstang/session-toolkit CLI (verified baseline 0.1.0); that execution prerequisite is installed separately and is not part of its generated payload.

Build and shipping topology

The build owns declared skill payloads and generated plugin runtime. Provider manifests and shared marketplace catalogs remain independently maintained release surfaces; a generated plugin target does not register or release a plugin by itself.

Canonical owner to generated forms

Canonical ownerGenerated forms
src/skills/consensus-create, consensus-decide, consensus-plan, consensus-refine, consensus-evaluate, consensus-panelMatching plugin-only plugins/consensus/skills/<short-name>/ payloads
src/skills/phone-a-friendskills/phone-a-friend/ and plugins/consensus/skills/phone-a-friend/
src/skills/consensus-reviewskills/consensus-review/ and plugins/consensus/skills/review/
src/skills/consensus-delegateskills/delegate/ and plugins/consensus/skills/delegate/
src/skills/session-observerskills/session-observer/ and plugins/consensus/skills/observer/
src/skills/session-observer-collabskills/session-observer-collab/ and plugins/consensus/skills/observer-collab/
src/skills/session-handoffskills/session-handoff/ and plugins/session/skills/handoff/
src/skills/session-retroskills/session-retro/ and plugins/session/skills/retro/
src/skills/session-export-transcriptskills/session-export-transcript/ and plugins/session/skills/export-transcript/
src/skills/session-fork-to-destinationskills/session-fork-to-destination/ and plugins/session/skills/fork-to-destination/
src/skills/seshtk-cliskills/seshtk-cli/ and plugins/session/skills/seshtk-cli/
src/skills/session-searchskills/session-search/ and plugins/session/skills/search/
src/skills/reorientskills/reorient/ and plugins/session/skills/reorient/
src/skills/complexity-reviewskills/complexity-review/ only
src/skills/author-skillskills/author-skill/ only
src/skills/babysit-prskills/babysit-pr/ only
src/skills/land-prskills/land-pr/ only; requires the babysit-pr workflow
src/skills/alignskills/align/ and plugins/session/skills/align/
src/skills/debriefskills/debrief/ and plugins/session/skills/debrief/
src/skills/sitrepskills/sitrep/ and plugins/session/skills/sitrep/
src/skills/next-stepsskills/next-steps/ and plugins/session/skills/next-steps/
src/skills/explain-optionsskills/explain-options/ and plugins/session/skills/explain-options/
src/skills/must-weskills/must-we/ and plugins/session/skills/must-we/

Executable owners declare entrypoints in build.json; prompt-only skills do not need one. The build follows actual imports into permitted shared roots, bundles that closure into each installation unit, and rejects undeclared source escapes, duplicate targets, or runtime package dependencies.

The authored collaboration .mjs and .d.mts modules live under src/skills/session-observer-collab/src/. Their runtime is bundled into each generated form by the same build rather than maintained as a second authored tree. An authored .mjs entrypoint must have an adjacent .d.mts declaration, but the builder bundles the .mjs dependency closure and does not ship declarations.

For the concrete authoring sequence, see Adding a skill or distribution.

Code and workflow relationships

Bundled code and workflow prerequisites solve different problems. A runtime import enters the generated installation unit. A required workflow must already be installed, while an optional integration may be absent without blocking the core skill.

The distribution declaration carries required and optional workflow references so generated instructions can use the right standalone or plugin-local name. It does not install those workflows automatically.

Target-specific names and versions

Canonical identity is independent from plugin-local identity. For example, session-export-transcript becomes export-transcript inside the session plugin. The generated frontmatter uses the target name, while every form inherits the canonical owner's single quoted stable metadata.version.

Plugin releases are separate: plugins/consensus/ and plugins/session/ each have their own provider and marketplace manifest version. Bumping a plugin does not rewrite its member skill versions; bumping a skill does not rewrite either plugin release version.

Consensus plugin-local runtime layout

Consensus wrappers live under plugins/consensus/skills/<name>/scripts/, while the shared loop and provider CLI live once under plugins/consensus/scripts/. Generated wrappers keep plugin-root-relative imports, so a provider install or local load must preserve scripts/ beside skills/.

The plugin also contains skills/observer/ and skills/observer-collab/. Their shared transcript and observer runtime closure is materialized into the plugin unit; they do not import the standalone skills/ tree at runtime.

The standalone phone-a-friend unit bundles its provider helper and advisory schema. It does not require the Consensus plugin or a helper under the user's home directory. Standalone delegate bundles the same provider helper for text-mode task runs. The plugin's six converging and panel workflows remain plugin-only; Review carries its own bundled review runtime in both declared forms.

Session plugin-local runtime layout

The session plugin is a separate complete package. export-transcript, fork-to-destination, and search each carry their own bundled runtime closure inside their skill directory; handoff, retro, and reorient are instruction-only with bundled templates or references. Their canonical standalone names stay session-export-transcript, session-fork-to-destination, session-search, session-handoff, session-retro, and reorient. The instruction-only seshtk-cli member keeps that same name in standalone and plugin forms and requires the external toolkit CLI only when executing a session operation. align, debrief, sitrep, next-steps, explain-options, and must-we are instruction-only members with the same standalone and plugin-local names. Debrief and Sitrep declare Next Steps as an optional workflow reference: standalone payloads name next-steps, while Session payloads resolve the plugin-local next-steps member. Neither workflow invokes it automatically. Must We retains complexity-review as optional analysis; Complexity Review remains standalone and is not included in Session.

Import rewriting

Canonical TypeScript uses normal .js specifiers. The build derives import rewrites from actual source imports and resolves them against declared outputs. An unresolvable or ambiguous specifier fails loudly. This keeps generated local .mjs paths correct without a hand-maintained second consumer graph.

Never hand-edit generated output

Files under declared skills/ and plugins/*/skills/ installation units are produced by the build, including rendered SKILL.md, references/assets, schemas, and executable runtime. Change the canonical owner under src/skills/, shared code under src/shared/, or plugin source under src/plugins/, then run pnpm run build. pnpm run build:check and the generated-output-sync test flag inventory, content, or executable-mode drift.

When build or check fails

FailureWhat it meansSafe response
Missing, stale, or orphan generated fileThe committed unit differs from the complete staged inventory.Inspect the canonical source and declaration first. If the change is intentional, run pnpm run build, inspect the generated diff, then rerun pnpm run build:check.
Source escapes its allowed roots or a runtime imports a packageThe declared ownership boundary or dependency-free runtime contract was crossed.Fix the declaration or import. Do not repair the failure by installing a runtime dependency.
Replacement failed; prior outputs restoredPublication failed after staging, but the reported rollback restored the prior outputs.Fix the reported cause and rebuild.
Replacement failed and rollback was incompleteSome replacement or restoration operation failed.Treat the paths in the error's recovery details as authoritative and inspect them individually. Do not guess at cleanup targets.
Distribution installed but backup cleanup failedNew outputs were installed, but one or more reported recovery backups remain.Verify the installed output and inspect only the exact backup paths named by the error before cleanup.

The builder stages and validates complete units before replacing outputs. Its errors distinguish restoration from incomplete recovery; they are not a promise that every failed filesystem operation is losslessly reversible.

The build as a staged transaction

The failure table above describes one transaction. The builder stages and validates the complete unit before touching anything, moves prior outputs aside, then installs; validation failure aborts before any mutation, and the three replacement outcomes need three different responses.

Mermaid updated 2026-09-20

On this page