For AI agents: the complete documentation index is available at https://scriptedalchemy.github.io/agent-bundle/llms.txt, the full documentation bundle is available at https://scriptedalchemy.github.io/agent-bundle/llms-full.txt, and this page is available as Markdown at https://scriptedalchemy.github.io/agent-bundle/guide/authoring/skills.md.
  • English
  • Skills

    A Skill is a Markdown document plus the files it references. agent-bundle discovers Skills from the src/ convention, lowers each one into the spelling every selected host expects, and ships the directory's other files as that Skill's resources.

    The convention

    One directory per Skill, with SKILL.md inside:

    src/skills/release-review/
    ├── SKILL.md
    ├── assets/report-template.md
    └── references/checklist.md

    That ships with no declaration at all. Everything in the directory other than SKILL.md — and other than the rendered-skill source files, which are build inputs — becomes a resource of that Skill, copied into the artifact with its relative path preserved.

    The document

    SKILL.md starts with YAML frontmatter and continues as ordinary Markdown:

    ---
    name: release-review
    description: Reviews release evidence and issues an auditable readiness verdict.
    ---
    # Release review
    
    ## When to use
    
    Use this Skill when a release candidate needs a go/no-go verdict supported by
    checked, reproducible evidence.
    
    ## Required resources
    
    - Read [the release checklist](references/checklist.md) to inspect the artifact.
    - Deliver the result with [the report template](assets/report-template.md).

    Frontmatter is required. A document with none reports AB3001; invalid YAML reports AB3002. name and description are what every host reads — the description is the activation surface, so write it as the condition under which the Skill should be used, not as a title.

    Links to sibling files are how a Skill points at its own resources. They stay relative in the emitted document, so they resolve inside whichever artifact the host installed.

    Selecting Skills explicitly

    Conventional discovery covers src/skills/*/SKILL.{md,ts,tsx}. Declare skills when you need a different location, a subset, or a literal list:

    import { 
    const defineConfig: (config: AgentBundleConfig | ConfigFactory) => AgentBundleConfig | ConfigFactory
    defineConfig
    } from 'agent-bundle/config';
    export default
    function defineConfig(config: AgentBundleConfig | ConfigFactory): AgentBundleConfig | ConfigFactory
    defineConfig
    ({
    AgentBundleConfig.plugin: AgentBundlePluginConfig
    plugin
    : {
    AgentBundlePluginConfig.description?: string | undefined
    description
    : 'Engineering operations.',
    AgentBundlePluginConfig.name: string
    name
    : 'ops-bundle' },
    AgentBundleConfig.skills?: string[] | undefined
    skills
    : ['src/skills/*'],
    AgentBundleConfig.targets?: string[] | undefined
    targets
    : ['portable', 'codex', 'claude'],
    });

    Literal paths stay literal; globs match Skill directories or SKILL.md files. Config always wins over the convention.

    Host extensions

    Portable Skill metadata — name, description, license, compatibility, allowed-tools (the Agent Skills spelling; camelCase allowedTools is accepted only under targets.claude), and a free-form metadata record — is understood by every target. Host-specific keys live under their host so they reach only that adapter:

    HostExamples
    claudeallowedTools, disallowedTools, argumentHint, model, effort, context: 'fork', background, userInvocable, disableModelInvocation, whenToUse, shell, paths, hooks
    codexdependencies.tools, interface (display name, icons, brand color, default prompt), policy.allowImplicitInvocation
    cursorglobs, icon, color, paths, disableModelInvocation

    targets in Skill frontmatter is that per-host object and nothing else; a list such as targets: ['claude'] is AB3006. A Skill is emitted to every target the project selects — there is no per-Skill artifact restriction.

    Path tokens

    Host placeholder syntax differs — ${CLAUDE_PLUGIN_ROOT} is not what Cursor or the portable standard write. Author the canonical token instead and let build-time lowering substitute the host spelling:

    TokenMeans
    agent-bundle:path:plugin-rootThe plugin install root.
    agent-bundle:path:plugin-dataThe host-provided plugin data directory.
    agent-bundle:path:workspace-rootThe user's workspace or project root.
    agent-bundle:token:argumentsThe invocation arguments.
    agent-bundle:token:session-identityThe current session identity.
    agent-bundle:token:skill-rootThe installed Skill's own directory.

    Lowering substitutes syntax only; no runtime value is resolved at build time. A token a host cannot express is reported rather than silently emitted as literal text.

    Rendered Skills

    When a Skill document is generated rather than typed — the same checklist repeated per environment, a table derived from a contract — put a component at src/skills/<name>/SKILL.tsx (or .ts). It default-exports a component and exports a frontmatter record; the build compiles the rendered tree into the SKILL.md document hosts consume:

    // src/skills/release-review/SKILL.tsx
    import { Skill } from 'agent-bundle';
    
    export const frontmatter = {
      name: 'release-review',
      description: 'Reviews release evidence and issues an auditable readiness verdict.',
    };
    
    export default () => (
      <>
        <h1>Release review</h1>
        <p>Evidence lives under {Skill.PluginRoot()}/assets.</p>
      </>
    );

    Six Skill.* members emit canonical tokens: Skill.Arguments, Skill.PluginData, Skill.PluginRoot, Skill.ProjectRoot, Skill.SessionIdentity, and Skill.SkillRoot. Skill.Resource renders a Markdown link ([path](path)), not a token. Host syntax is applied during lowering, never in the component.

    A hand-authored SKILL.md in the same directory always wins — an authored file beats a generated one — and the shadowed component reports the informational AB4735 nudge. A rendered module that fails to load reports AB3003; one that does not default-export a component function, or does not export a frontmatter record, reports AB3004.

    defineSkill types a Skill definition next to a rendered source:

    import { 
    const defineSkill: <Skill extends DefinedSkill>(skill: Skill) => Skill

    Identity helper so authors can type a Skill definition next to a rendered source.

    defineSkill
    } from 'agent-bundle';
    export const
    const skill: {
        description: string;
        name: string;
    }
    skill
    =
    defineSkill<{
        description: string;
        name: string;
    }>(skill: {
        description: string;
        name: string;
    }): {
        description: string;
        name: string;
    }

    Identity helper so authors can type a Skill definition next to a rendered source.

    defineSkill
    ({
    description: string
    description
    : 'Reviews release evidence and issues an auditable readiness verdict.',
    name: string
    name
    : 'release-review',
    });

    Inspecting what shipped

    npx agent-bundle inspect --root . --skills

    The skill focus shows each discovered Skill, its provenance (conventional or config), its resources, and the per-target lowering decisions. In the developer Workbench, the Skills page renders the emitted document for each host.

    Raw HTML, JSX/MDX, and Mermaid inside Skill Markdown are inert in the Workbench renderer. That is a deliberate containment boundary, not a rendering gap.

    Next