Skip to content

Compile target-aware Skills with host frontmatter and interpolation #108

Description

@ScriptedAlchemy

Summary

Provide one expressive Skill authoring surface that Agent Bundle can compile into
the exact skill and plugin artifacts supported by each selected agent host.

Authors should be able to use portable Agent Skills content, host-specific
frontmatter and sidecar metadata, runtime placeholders, plugin-path variables,
arguments, resources, and generated Markdown without manually maintaining one
SKILL.md tree per host.

This is an outcome requirement, not a commitment to one implementation. MDX,
TSX, a custom Rslib/MDX loader, an Agent Document renderer, or a simpler
compiler-owned transform are all valid avenues to evaluate.

Problem

Agent Bundle currently normalizes one skill directory and copies or generates
the same skills/<name>/SKILL.md tree for every selected target. This works for
the portable Agent Skills core, but the hosts have materially different native
surfaces:

  • Claude Code extends Skill frontmatter with arguments, invocation policy,
    model/effort selection, forked context, agents, background execution,
    tool restrictions, path filters, shell injection, and skill-scoped hooks.
  • Codex keeps SKILL.md deliberately small and expresses UI, invocation policy,
    and dependencies in agents/openai.yaml; it has no documented Skill Markdown
    interpolation engine. Codex plugin hooks expose PLUGIN_ROOT/PLUGIN_DATA
    variables, while deprecated custom prompts have a separate argument syntax.
  • Cursor extends Skill discovery and frontmatter with path filters and explicit-
    only invocation, but its documented ${VAR} interpolation belongs to plugin
    configuration rather than Skill Markdown. It also has separate native rules,
    commands, hooks, agents, and a workspaceOpen plugin-loading surface.

A single superset YAML document is not a safe solution. Several portable,
upload, plugin, and generated-artifact schemas reject unknown fields rather than
promising to ignore them. Conversely, reducing every Skill to the portable
intersection prevents authors from using important native capabilities.

Required authoring outcome

Support one canonical Skill source with:

  • the portable Agent Skills fields and Markdown body;
  • optional typed target-specific fields and sidecar documents;
  • canonical references to arguments, skill root, plugin root, plugin data,
    project/workspace root, session identity, and other host runtime values;
  • referenced scripts/, references/, assets/, and arbitrary additional
    Skill resources;
  • static Markdown authoring and a rendered authoring form suitable for dynamic
    composition (for example MDX or TSX);
  • target selection and capability requirements;
  • deterministic diagnostics when a requested behavior cannot be expressed on a
    selected host.

Illustrative only:

export const skill = defineSkill({
  name: 'review',
  description: 'Review a change and report actionable findings.',
  targets: {
    claude: { model: 'sonnet', context: 'fork' },
    cursor: { paths: ['src/**'] },
    codex: {
      interface: { displayName: 'Review change' },
      policy: { allowImplicitInvocation: true },
    },
  },
});

export default function ReviewSkill() {
  return (
    <>
      <h1>Review the change</h1>
      <p>Review <Skill.Arguments /> in <Skill.ProjectRoot />.</p>
      <p>Use <Skill.Resource path="references/checklist.md" />.</p>
    </>
  );
}

The source syntax above is not prescribed. It demonstrates the information the
compiler must be able to represent.

Compiler and projection requirements

  1. Parse the source into a canonical Skill IR that retains portable metadata,
    host extensions, the rendered document, resource references, runtime
    placeholders, provenance, and capability requirements.
  2. Lower the IR through the existing target adapter/capability system. Emit only
    fields and auxiliary documents legal for that host; never depend on unknown
    fields being ignored.
  3. Preserve runtime values as runtime placeholders. For example, a canonical
    argument or plugin-root reference may lower to Claude's $ARGUMENTS or
    ${CLAUDE_PLUGIN_ROOT}, a legal Codex hook/plugin variable in the correct
    document, or an explicit unsupported diagnostic. Do not resolve these values
    at build time and do not leak one host's syntax into another host's output.
  4. Cover interpolation across the whole plugin surface, not only the Skill body:
    Skill arguments, plugin configuration, MCP arguments/environment/working
    directory, hooks, commands, prompts, resources, and host sidecar documents
    must share one typed capability and token model where their semantics align.
  5. Compile a rendered source into ordinary static SKILL.md plus resources.
    Evaluate MDX/TSX compiled to a server component, rendered into an Agent
    Document and projected to Markdown, against a smaller Markdown-AST transform.
  6. The build may share identical bytes across hosts, but differing native
    metadata or placeholder syntax requires target-specific documents or an
    equivalent install-time projection. Do not claim one shared file is valid
    without proving semantic identity.
  7. The Agent Bundle artifact planner owns final destinations such as
    skills/<name>/SKILL.md, atomic staging, manifests, validation, and output
    provenance. A loader may compile source modules or assets, but must not bypass
    target planning or create untracked files.
  8. Skill sources, imports, resources, and capability schemas participate in
    watch invalidation and content/effective-behavior digests.
  9. inspect and Workbench show the authored source, each generated host
    document, placeholder lowering, omitted/degraded features, and the evidence
    behind every capability decision.
  10. Existing hand-authored portable SKILL.md directories remain a supported
    pass-through source and do not require React, MDX, or JavaScript.

Static build versus Flight

Skills are static install artifacts. A rendered Skill source may reuse the same
React-owned Agent Document renderer and Markdown projector introduced by #96,
but it does not need to ship JavaScript or send a Flight stream to a client.
The build can execute the compiled server component, await its final document,
project Markdown, and emit the result.

Current hooks likewise do not use Flight: they are generated Node wrappers plus
host-native manifests and codecs. Semantic event routes may later use #96 to
render hook/event results, but this issue must not describe that future
composition as current integrated behavior.

Acceptance criteria

  • One source produces schema-valid Codex, Claude Code, and Cursor Skill/plugin
    artifacts that exercise at least one genuinely different native capability
    per host.
  • Portable-only Skills remain byte-stable when no host extension or canonical
    placeholder requires target-specific output.
  • Claude arguments and skill/plugin-root variables lower and execute in a real
    Claude plugin installation.
  • Codex agents/openai.yaml metadata/policy/dependencies lower separately from
    SKILL.md and are verified in a real Codex installation.
  • Cursor path/invocation fields and plugin configuration variables lower to
    their documented native locations and are verified in a real Cursor plugin
    installation.
  • Selecting a host without an equivalent for a required field or placeholder
    fails before publication with a precise diagnostic and recovery options.
  • Unknown host fields are never silently copied into another host's closed
    frontmatter or manifest schema.
  • Static Markdown, rendered Skill source, resources, watch rebuilds, packed
    publication, install, discovery, explicit invocation, and implicit activation
    have end-to-end fixtures.
  • Generated artifacts contain no authoring-only MDX/TSX modules and include
    exact source/capability provenance.

Implementation questions to resolve

  • Should the rendered source convention be SKILL.mdx, SKILL.tsx, or both?
  • Is the best implementation an Rslib/MDX loader feeding a canonical IR, a
    dedicated Skill build profile, or the existing compiler-owned generated-write
    path with a renderer? Compare watch behavior, source maps, output control,
    dependency tracking, and multi-target lowering.
  • Can the combined multi-host plugin retain one shared skills/ tree when
    outputs differ, or must lifecycle installation select/copy a host-specific
    tree? Prove actual host discovery and precedence before choosing.
  • Which placeholders are semantically portable, which require target-specific
    namespaces, and which have no honest cross-host equivalent?
  • How should native fields that affect one invocation/turn be distinguished from
    persistent session or plugin behavior?

Design references

Stack position

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthost-integrationAgent host capabilities, projection, discovery, and lifecyclemeta-frameworkAgent Bundle compiler-coupled meta-framework

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions