Skills & SKILL.md
Feature Definition
Section titled “Feature Definition”Skills are portable instruction bundles rooted in a SKILL.md file. A skill is not just “extra prompt text” - it is a packaging format for:
- Trigger metadata (
name,description) - Executable workflow guidance (the skill body)
- Optional bundled resources (
scripts/,references/,assets/) - Optional dependency and UI metadata (
agents/openai.yamlin Codex, or equivalent metadata in other systems)
In practice, skills are a context-budget and execution-control system as much as a prompting system. The hard engineering problems are:
- Discovery scope and precedence: local project skills vs user/global skills vs system-provided skills
- Trigger correctness: avoiding false positives/negatives and ambiguous name collisions
- Token discipline: loading only metadata by default and deferring heavy content
- Dependency bootstrapping: env vars and MCP prerequisites without silently failing
- Permission boundaries: allowing useful automation without granting blanket access
- Supply-chain trust: remote skill download and update behavior
For this page, “reference implementations” include:
- Aider (no first-class skill system)
- Codex (Rust, first-class
SKILL.mdruntime) - OpenCode (TypeScript/Bun, first-class
skilltool + directory scanner) - OpenTUI (no runtime skill engine, but ecosystem-level skill packaging mention)
- Claude Agent Skills docs (public product specification and operational best practices)
Claude docs used for the SKILL.md spec and best-practice guidance:
Aider Implementation
Section titled “Aider Implementation”Reference: references/aider/ at commit b9050e1d
Aider does not implement a first-class skill runtime:
- No
SKILL.mdparser - No skill directory discovery layer (
.claude/skills,.agents/skills, etc.) - No skill metadata registry
- No skill injection envelope into conversation history
- No skill dependency model (env vars/MCP dependencies declared by skill)
What Aider Uses Instead
Section titled “What Aider Uses Instead”Aider’s extensibility remains:
- command-line configuration
- coder modes (
--edit-format,--architect, etc.) - project docs and read-only context inclusion
- custom shell commands (
--lint-cmd,--test-cmd,/run)
This gives flexibility, but no portable “skill package” abstraction. Team-specific procedures can be documented in project files, but there is no reusable/triggerable skill lifecycle equivalent to Codex/OpenCode/Claude.
Practical Consequence
Section titled “Practical Consequence”If OpenOxide wants Claude/Codex-style skills, Aider is primarily a negative reference here: useful for understanding what breaks when skills are absent (repeat prompt boilerplate, no structured discovery, no dependency prompting), but not for implementation patterns.
Codex Implementation
Section titled “Codex Implementation”Reference: references/codex/ at commit 4ab44e2c
Codex has a complete, multi-layer skill subsystem in Rust:
codex-rs/core/src/skills/loader.rscodex-rs/core/src/skills/manager.rscodex-rs/core/src/skills/injection.rscodex-rs/core/src/skills/env_var_dependencies.rscodex-rs/core/src/mcp/skill_dependencies.rscodex-rs/core/src/skills/permissions.rscodex-rs/core/src/skills/system.rscodex-rs/core/src/project_doc.rscodex-rs/core/src/instructions/user_instructions.rs
End-to-End Flow
Section titled “End-to-End Flow”At a high level:
- Session start loads skills through
SkillsManagerand composes a “skills index section” into user instructions. - Turn start re-resolves skills for current cwd and selects explicit mentions from structured inputs and text tokens.
- Dependency prompts/installers run for selected skills (env vars + MCP).
- Selected
SKILL.mdfiles are read and injected as user-role<skill>...</skill>messages. - Sampling continues with those injected instructions.
1) Discovery, Scope, and Caching
Section titled “1) Discovery, Scope, and Caching”Discovery Roots
Section titled “Discovery Roots”skills/loader.rs defines roots from config layers and cwd/project topology:
- repo scope roots
- user scope roots
- system scope roots
- admin scope roots
- intermediate
.agents/skillsdirectories from project root to cwd
Important behavior:
- Root scopes are ranked (
Repo>User>System>Admin) for dedupe precedence. - Canonicalized paths are used where possible.
- Duplicate skill paths are removed.
- Scans are breadth-first with explicit limits (
MAX_SCAN_DEPTH,MAX_SKILLS_DIRS_PER_ROOT).
Symlink Behavior
Section titled “Symlink Behavior”Codex follows symlinked directories for repo/user/admin scopes, but not for system scope, since system skills are generated by Codex itself (skills/loader.rs:343+).
Manager Cache
Section titled “Manager Cache”SkillsManager caches outcomes per cwd:
skills_for_config(&Config)seeds cache during spawnskills_for_cwd(cwd, force_reload)andskills_for_cwd_with_extra_user_roots(...)serve API/runtime pathsclear_cache()invalidates the map
This cache is also visible in app-server behavior (skills/list with forceReload).
2) SKILL.md Parsing and Optional Metadata
Section titled “2) SKILL.md Parsing and Optional Metadata”Required File + Frontmatter
Section titled “Required File + Frontmatter”parse_skill_file() reads SKILL.md, extracts YAML frontmatter, and requires:
namedescription
Both fields are:
- normalized to single-line whitespace
- length-validated
- rejected when missing/empty
Optional Metadata: agents/openai.yaml
Section titled “Optional Metadata: agents/openai.yaml”Codex loads additional metadata from agents/openai.yaml adjacent to SKILL.md:
interface(display name, short description, icons, brand color, default prompt)dependencies.tools[](e.g.,env_var,mcp)policy.allow_implicit_invocationpermissions(compiled into runtime permission profile)
Loader behavior is intentionally fail-open for optional metadata: invalid optional metadata logs warnings and does not block base skill loading.
3) System Skills Installation
Section titled “3) System Skills Installation”skills/system.rs embeds sample skills at compile time using include_dir, then installs them into:
CODEX_HOME/skills/.system
Install is marker/fingerprint guarded:
- compares an embedded-directory fingerprint against
.codex-system-skills.marker - skips reinstall when unchanged
- rewrites system cache when fingerprint differs
Embedded examples include:
skill-creatorskill-installer
with supporting agents/, scripts/, references/, and assets/ folders under:
codex-rs/core/src/skills/assets/samples/
4) Skills as Session-Level Instruction Inventory
Section titled “4) Skills as Session-Level Instruction Inventory”At spawn time (codex.rs), Codex computes:
loaded_skills.allowed_skills_for_implicit_invocation()
Then get_user_instructions() (project_doc.rs) appends a rendered “Skills” section (skills/render.rs) after AGENTS/user instructions, including:
- available skill names/descriptions/paths
- explicit trigger/use rules
- progressive-disclosure guidance
This is key: metadata is always available to the model, but full skill bodies are deferred.
5) Explicit Mention Selection
Section titled “5) Explicit Mention Selection”Per turn, run_turn() calls:
collect_explicit_skill_mentions(...)inskills/injection.rs
Selection algorithm:
- Structured
UserInput::Skillresolved by path first - Text mentions parsed (
$skill-nameand[$name](path)forms) - Path-linked mentions preferred over plain-name fallback
- Plain-name fallback requires unambiguous name and no connector-slug conflict
- Disabled skill paths are excluded
- Deduping by path and name is enforced
This prevents accidental selection for ambiguous skill names and connector collisions.
6) Skill Injection Format
Section titled “6) Skill Injection Format”build_skill_injections() reads selected SKILL.md files and emits user-role messages via SkillInstructions:
<skill><name>...</name><path>...</path>... SKILL.md content ...</skill>Implementation path:
skills/injection.rsbuildsResponseItemsinstructions/user_instructions.rsdefinesFrom<SkillInstructions> for ResponseItemrun_turn()records injected items before sampling
Failures to read files are emitted as warning events and metrics; other skills continue.
7) Dependency Handling
Section titled “7) Dependency Handling”Env Var Dependencies
Section titled “Env Var Dependencies”skills/env_var_dependencies.rs:
- collects dependencies where
dependencies.tools[].type == "env_var" - checks session-scoped dependency env cache, then process env
- prompts user via
request_user_inputfor missing variables (is_secret = true) - stores values in-memory for current session only
MCP Dependencies
Section titled “MCP Dependencies”mcp/skill_dependencies.rs:
- extracts missing MCP dependencies from selected skills
- prompts for installation unless in full-access mode
- can persist MCP config edits to global config
- supports OAuth login flow for installed MCP servers where required
- tracks prompted dependencies to avoid repetitive prompts in one session
8) Skill-Specific Permission Profiles
Section titled “8) Skill-Specific Permission Profiles”skills/permissions.rs compiles optional manifest permissions into a constrained runtime permissions profile:
- filesystem read/write path normalization
- optional network access
- macOS-specific seatbelt extension fields
- default approval policy set to
Neverwithin that compiled profile
This enables skill-authored permission narrowing/expansion patterns, but introduces trust/safety concerns discussed below.
9) App-Server Surface
Section titled “9) App-Server Surface”Codex app-server v2 exposes skill operations in codex_message_processor.rs and documented in app-server/README.md:
skills/listskills/remote/read(under development)skills/remote/write(under development)skills/config/write
skills/list supports:
- multiple cwd queries
- per-cwd extra user roots (absolute paths only)
- force-reload cache bypass
10) Remote Skill Download
Section titled “10) Remote Skill Download”skills/remote.rs supports:
- listing remote public skills
- downloading zip payloads
- path-safe extraction (
safe_join, component validation) - whitelist extraction via server-provided file map
Current app-server docs explicitly mark remote read/write endpoints as under development.
OpenCode Implementation
Section titled “OpenCode Implementation”Reference: references/opencode/ at commit 7ed44997
OpenCode implements skills with both:
- a discovery registry (
src/skill/skill.ts) - a model-callable tool (
src/tool/skill.ts)
Plus API/CLI/TUI surfaces.
End-to-End Flow
Section titled “End-to-End Flow”Skill.state()scans configured roots and builds{ name -> skill info }.- Skill names are exposed as slash-command-like commands via
Command.state(). - The
skilltool can be called by the model to load full skill content. - Loaded content is returned inside
<skill_content ...>output and becomes part of conversation context through normal tool-result flow.
1) Discovery Pipeline
Section titled “1) Discovery Pipeline”Skill Info Schema
Section titled “Skill Info Schema”Skill.Info in skill.ts:
namedescriptionlocationcontent
Parsed from SKILL.md frontmatter/body using ConfigMarkdown.parse.
Scan Sources and Precedence
Section titled “Scan Sources and Precedence”Skill.state() builds registry by scanning in this order:
- global external dirs (
~/.claude/skills/**/SKILL.md,~/.agents/skills/**/SKILL.md) - project-level external dirs found by upward search from instance directory
.opencode/{skill,skills}/**/SKILL.mdacross config directories- extra
skills.paths[]from config - remote discovery sources from
skills.urls[]
On duplicate name:
- logs warning
- later scan overrides earlier entry
This “last write wins” behavior is practical but can silently shadow skills.
Remote Discovery
Section titled “Remote Discovery”skill/discovery.ts fetches a skill index:
<base>/index.json
Expected shape:
skills: [{ name, description, files[] }]
It downloads listed files into cache (Global.Path.cache/skills/<name>/...) and only returns directories containing SKILL.md.
Caching behavior:
- file fetch skips already-existing destination files
- repeat pulls typically become no-op for unchanged files
2) Skill Tool Contract
Section titled “2) Skill Tool Contract”SkillTool in tool/skill.ts:
- dynamically describes available skills in tool description XML block
- validates params with
zod({ name: string }) - asks permission (
permission: "skill", pattern = selected name) - returns structured output:
<skill_content name="...">- raw skill content
- base directory URI
- sampled file listing (
<skill_files>)
This is a direct, explicit load model: full body comes through a tool call instead of hidden prompt mutation.
3) Permission Integration
Section titled “3) Permission Integration”OpenCode integrates skills into permission and agent systems:
- config schema includes
permission.skillrules (config.ts) SkillToolevaluates agent permission withPermissionNext.evaluate("skill", skill.name, ...)- default agent permissions include allow-rules for skill directories in
external_directory
This avoids a common failure mode where skill instructions reference bundled files that the active agent cannot read.
4) Command, API, and TUI Surfaces
Section titled “4) Command, API, and TUI Surfaces”Skills as Commands
Section titled “Skills as Commands”command/index.ts adds each skill as a command when no command name collision exists:
- command
source: "skill" - template returns skill content
HTTP API
Section titled “HTTP API”server/server.ts exposes:
GET /skill
returning Skill.Info[].
CLI Debug
Section titled “CLI Debug”cli/cmd/debug/skill.ts:
opencode debug skill
prints all discovered skills as JSON.
TUI Skill Picker
Section titled “TUI Skill Picker”TUI dialog components (dialog-skill.tsx) fetch from /skill and support searchable selection.
5) Test Coverage
Section titled “5) Test Coverage”OpenCode has extensive tests in:
test/skill/skill.test.tstest/skill/discovery.test.ts- agent permission test coverage in
test/agent/agent.test.ts
Covered scenarios include:
- discovery from
.opencode/skill,.opencode/skills - discovery from
.claude/skillsand.agents/skills(project + global) - missing frontmatter skip behavior
- remote discovery from Cloudflare
.well-known/skills - reference-file download alongside
SKILL.md - cache behavior on repeated pulls
OpenTUI Implementation
Section titled “OpenTUI Implementation”Reference: references/opentui/ at commit f4712b9a
OpenTUI does not implement a runtime skill system in framework code (no SKILL.md parser/runtime in packages/ source tree). Skills appear only as ecosystem distribution guidance in README:
- install an “OpenTUI skill” for AI assistants
- no in-framework skill discovery/injection/dependency lifecycle
So OpenTUI is not a direct architectural reference for implementing skills in OpenOxide core; it is only a packaging ecosystem signal.
Claude Agent Skills (Spec)
Section titled “Claude Agent Skills (Spec)”Claude’s public docs are the strongest public spec for SKILL.md authoring conventions and progressive disclosure behavior:
Key Design Patterns from Claude Docs
Section titled “Key Design Patterns from Claude Docs”- Three-level loading model:
- lightweight metadata always visible
- skill body loaded when invoked
- bundled resources loaded on demand
- Strict skill folder contract:
SKILL.mdrequired- predictable adjacent resources
- Progressive disclosure as a token strategy:
- keep core body concise
- push heavy details into referenced files
- Trigger hygiene:
- descriptions should clearly encode when to use the skill
- avoid vague metadata that overfires
- Operational best practices:
- use scripts for deterministic repetitive tasks
- avoid oversized monolithic instructions
- include clear “when to read which file” guidance
OpenCode and Codex independently converge on many of these same patterns (directory-based discovery, metadata-first, delayed full-body loading, optional bundled references/scripts).
Claude Code Implementation
Section titled “Claude Code Implementation”Reference: Claude Code Skills docs (fetched 2026-02-21)
Claude Code has the most mature skill system of the four references, built on the Agent Skills open standard. Custom slash commands (.claude/commands/) have been merged into skills — both paths create the same /name shortcut, but skills/ take precedence when both exist.
End-to-End Flow
Section titled “End-to-End Flow”- At session start, skill descriptions are loaded from all discovery roots and injected as lightweight metadata.
- Skills consume up to 2% of the context window for descriptions (configurable via
SLASH_COMMAND_TOOL_CHAR_BUDGET). Skills that exceed the budget are excluded (visible via/context). - When invoked (user
/slash-commandor Claude auto-invocation), the fullSKILL.mdbody is loaded and injected. - Skills with
context: forkexecute in an isolated subagent context — the skill body becomes the subagent’s task. - Skills passed to subagents via the
skills:frontmatter field are fully preloaded into the subagent’s context at launch (not on-demand).
Discovery and Precedence
Section titled “Discovery and Precedence”Four scope levels, highest priority wins on name collision:
| Level | Location | Priority |
|---|---|---|
| Enterprise | Managed settings | Highest |
| Personal | ~/.claude/skills/<name>/SKILL.md | |
| Project | .claude/skills/<name>/SKILL.md | |
| Plugin | <plugin>/skills/<name>/SKILL.md | Lowest (namespaced as plugin-name:skill-name) |
Automatic discovery from nested .claude/skills/ directories supports monorepo setups. Skills from --add-dir directories support live change detection (no restart needed).
SKILL.md Frontmatter
Section titled “SKILL.md Frontmatter”| Field | Type | Purpose |
|---|---|---|
name | string | Display name and /slash-command. Lowercase, hyphens, max 64 chars |
description | string | When to use. Claude uses this for auto-invocation decisions |
argument-hint | string | Autocomplete hint shown in UI, e.g., [issue-number] |
disable-model-invocation | bool | true = only the user can invoke (hides from Claude’s auto-invoke) |
user-invocable | bool | false = hidden from / menu, Claude-only background knowledge |
allowed-tools | list | Tools permitted without approval when skill is active |
model | string | Model override while skill is active |
context | string | fork = run in isolated subagent context |
agent | string | Subagent type for context: fork (default: general-purpose) |
hooks | object | Lifecycle hooks scoped to skill’s lifetime (cleaned up when skill finishes) |
Invocation Control Matrix
Section titled “Invocation Control Matrix”The combination of disable-model-invocation and user-invocable creates three distinct behavioral modes:
| Config | User invoke | Claude invoke | Context load |
|---|---|---|---|
| (defaults) | Yes | Yes | Description every request, full on invoke |
disable-model-invocation: true | Yes | No | Nothing until user invokes |
user-invocable: false | No | Yes | Description every request, full on invoke |
String Substitutions
Section titled “String Substitutions”Skill bodies support several substitution patterns:
$ARGUMENTS— all args passed after the slash command$ARGUMENTS[N]or$N— positional args (0-indexed)${CLAUDE_SESSION_ID}— current session ID!`command`— shell preprocessing: the command runs before the skill body is sent to Claude, and its stdout replaces the backtick expression
Shell preprocessing is unique to Claude Code among all references — it enables dynamic context injection (e.g., !`git log --oneline -5` to inject recent commits).
Hook Scoping in Skills
Section titled “Hook Scoping in Skills”Skills can declare hooks in frontmatter that are scoped to the skill’s lifetime:
---name: deployhooks: Stop: - hooks: - type: command command: "echo 'Deploy skill finishing'" once: true---The once: true field causes the hook to fire exactly once per session then be removed. This is only supported in skill frontmatter, not in agent frontmatter or settings files.
Key Design Differences from Codex and OpenCode
Section titled “Key Design Differences from Codex and OpenCode”| Aspect | Codex | OpenCode | Claude Code |
|---|---|---|---|
| Discovery roots | 4 scopes (Repo > User > System > Admin) | Config + upward search | 4 scopes (Enterprise > Personal > Project > Plugin) |
| Name collision | Scope rank precedence | Last-write-wins | Higher-priority wins + plugin namespace |
| Loading model | Metadata-first, body on mention | Metadata-first, body via tool call | Descriptions at start, full on invoke |
| Invocation | $skill-name, [$name](path) | /skill-name via tool | /skill-name or Claude auto-invocation |
| Invocation control | allow_implicit_invocation | N/A | disable-model-invocation + user-invocable |
| Shell preprocessing | No | No | Yes (!`command` syntax) |
| Fork execution | No | No | context: fork runs in subagent |
| Hook scoping | No | No | Hooks in skill frontmatter, scoped to lifetime |
| Context budget | N/A | N/A | 2% of window, configurable |
| Dependencies | env_var + MCP (explicit) | env_var + MCP (explicit) | None (self-contained) |
Pitfalls & Hard Lessons
Section titled “Pitfalls & Hard Lessons”1) Name Collisions and Ambiguity
Section titled “1) Name Collisions and Ambiguity”Codex and OpenCode both expose potential collision scenarios:
- two skills with same name in different roots
- connector/app slug matching skill name
- command namespace collisions with skill names
Hard requirement: disambiguation by explicit path and predictable precedence rules.
2) Silent Shadowing Is Dangerous
Section titled “2) Silent Shadowing Is Dangerous”OpenCode’s last-write-wins duplicate behavior is convenient but can hide unexpected overrides. Codex’s scope ranking mitigates some ambiguity but still needs user visibility in UI/API.
3) Token Blowups from Monolithic SKILL.md
Section titled “3) Token Blowups from Monolithic SKILL.md”If entire skills auto-load, context cost explodes quickly. Both Codex and Claude guidance reinforce metadata-first loading. Skills must be structured for deferred reads.
4) Dependency Drift
Section titled “4) Dependency Drift”A skill that assumes env vars or MCP servers without prompting creates brittle failures. Codex’s env-var + MCP dependency prompts are a strong reference and should be treated as baseline behavior.
5) Remote Registry Trust
Section titled “5) Remote Registry Trust”Remote downloads add integrity and provenance risk:
- tampered index payloads
- skill updates changing behavior unexpectedly
- unreviewed dependency instructions
At minimum: path-safe extraction, deterministic caching, origin transparency, and explicit user approval for install/enable.
6) Permission Mismatch with Bundled Files
Section titled “6) Permission Mismatch with Bundled Files”A skill may instruct the model to run scripts or read references that current policy blocks. OpenCode’s default permission tweaks for skill directories and Codex’s optional skill permission profiles both address this from different angles.
7) Cache Invalidation Bugs
Section titled “7) Cache Invalidation Bugs”Per-cwd caches speed lookup, but stale registry state causes confusing “skill not found” or old-content injection. Force-reload pathways and filesystem-triggered invalidation are important.
OpenOxide Blueprint
Section titled “OpenOxide Blueprint”OpenOxide should implement skills as a first-class subsystem, not a prompt hack.
Architecture
Section titled “Architecture”Proposed crate split:
openoxide-skills:- discovery
- parsing and validation
- metadata model
- mention matching
- injection rendering
- dependency resolvers
openoxide-skill-registry(optional if split desired):- remote index handling
- cache and install manager
- integrate with:
openoxide-agent(turn loop)openoxide-config(roots, enable/disable, trusted sources)openoxide-permissions(skill-scoped permission profile support)
Data Model
Section titled “Data Model”pub struct SkillMetadata { pub name: String, pub description: String, pub short_description: Option<String>, pub path: PathBuf, pub scope: SkillScope, // Repo | User | System | Admin pub policy: SkillPolicy, pub interface: Option<SkillInterface>, pub dependencies: Option<SkillDependencies>, pub permissions: Option<PermissionsProfile>,}Discovery and Scope Order
Section titled “Discovery and Scope Order”Adopt Codex-like precedence with explicit policy:
- repo roots (
.openoxide/skills,.agents/skillsalong project-root->cwd chain) - user roots (
$OPENOXIDE_HOME/skills,$HOME/.agents/skills, optionally$HOME/.claude/skillsfor compatibility) - system roots (embedded defaults cache)
- admin roots (system config location)
Rules:
- canonicalize paths
- dedupe by path
- deterministic sorting (scope rank -> name -> path)
- bounded traversal depth and dir count
- controlled symlink policy by scope
SKILL.md Contract
Section titled “SKILL.md Contract”Required:
- YAML frontmatter with
name,description - markdown body
Optional adjacent metadata:
agents/openoxide.yaml(primary)agents/openai.yamlcompatibility reader for portability
Field parity target (v1):
interface.*dependencies.tools[](env_var,mcp; leave room for future kinds)policy.allow_implicit_invocation- optional permissions profile
Selection and Invocation
Section titled “Selection and Invocation”Implement two-stage flow:
- Always-visible metadata section in initial instructions (names + descriptions + paths + usage rules)
- Explicit skill load/injection on mention or structured input
Mention resolver requirements:
- structured selection by path first
- text mentions (
$nameand[$name](path)) - plain-name fallback only when unambiguous
- connector/app slug conflict suppression
- disabled-path filtering
- stable ordering
Injection Format
Section titled “Injection Format”Use a clear XML-like envelope for loaded skills:
<skill> <name>...</name> <path>...</path> ...body...</skill>Keep this as user-role content items so history filtering can identify and compact skill instructions cleanly.
Dependency Resolution
Section titled “Dependency Resolution”Env Vars
Section titled “Env Vars”- collect all
env_vardependencies for selected skills - resolve from session cache -> process env
- prompt for missing values (secret input mode)
- session-memory storage by default; optional encrypted persistence later
MCP Dependencies
Section titled “MCP Dependencies”- detect missing servers
- prompt install/skip with remember-for-session state
- install through config edit pipeline
- optional OAuth flow handoff where transport requires auth
Permission Strategy
Section titled “Permission Strategy”Baseline recommendation:
- do not auto-expand permissions blindly from skill metadata
- require explicit user opt-in for manifest-derived permission profile
- always show effective delta before applying
Optional modes:
- strict mode: ignore skill permission manifests entirely
- trusted-source mode: allow manifests from system/admin scopes only
Remote Skill Registry (Future)
Section titled “Remote Skill Registry (Future)”If implemented:
- index schema with explicit file lists
- path-safe extraction only
- source pinning and lock metadata
- optional signature verification
- install requires approval
- clear status UI: source URL, version/hash, install path, enabled state
API/CLI/TUI Surface
Section titled “API/CLI/TUI Surface”Minimum user-facing surface:
skills/listskills/reloadskills/enable/skills/disableskills/install(future, remote/local)- debug view for:
- resolved roots
- effective precedence
- parse errors
- disabled paths
TUI:
- searchable skill picker
- show scope badges (
repo,user,system,admin) - show dependency warnings before invocation
Testing Plan
Section titled “Testing Plan”Must-have tests:
- discovery precedence and dedupe across scopes
- duplicate-name ambiguity behavior
- mention parser edge cases (
$, links, env-var lookalikes) - skill injection serialization
- env-var prompt flow
- mcp dependency detection/install prompt flow
- cache behavior + force reload
- path traversal/symlink safety checks in loader and installer
- compatibility parsing for Claude/Codex-style skill folder layouts
Crates
Section titled “Crates”Likely Rust dependencies:
serde,serde_yamlwalkdirorignorepath_clean/dunceaho-corasickor custom parser for mention extractionschemars(if skill metadata schema export is desired)tokiofor async reads/prompts/install orchestration
Invocation Control (from Claude Code)
Section titled “Invocation Control (from Claude Code)”Implement two frontmatter fields for invocation control:
disable_model_invocation: bool— when true, only user can invoke (e.g.,/deploy). Skill metadata is not sent to the model at all.user_invocable: bool— when false, skill is hidden from the/menu but Claude can auto-invoke based on description match.
These two fields create a three-way matrix (both-true, user-only, model-only) that covers all real-world use cases.
Context Fork (from Claude Code)
Section titled “Context Fork (from Claude Code)”Support a context: fork field that executes the skill body in an isolated subagent context:
pub enum SkillContext { /// Default: inject skill body into current conversation. Inline, /// Run skill body as a subagent task, return summary to parent. Fork { agent_type: Option<String>, },}This enables long-running or tool-heavy skills (e.g., “review all files in src/”) without polluting the main conversation context.
Shell Preprocessing (from Claude Code)
Section titled “Shell Preprocessing (from Claude Code)”Support !`command` syntax in skill bodies. Before the skill content is sent to the model, shell expressions are evaluated and replaced with their stdout. This enables dynamic context like recent git history, environment info, or project-specific metadata without requiring the model to make tool calls.
Context Budget (from Claude Code)
Section titled “Context Budget (from Claude Code)”Cap skill descriptions at a configurable percentage of the context window (default 2%):
pub struct SkillBudget { /// Maximum percentage of context window for skill descriptions. pub max_pct: f32, // default: 0.02 /// Absolute fallback if context size is unknown. pub fallback_chars: usize, // default: 16_000}Skills that exceed the budget are excluded with a warning visible via a /context or similar debug command. This prevents skill metadata from crowding out actual conversation content.
Plugin Namespacing (from Claude Code)
Section titled “Plugin Namespacing (from Claude Code)”When the plugin system lands, plugin skills must be namespaced as plugin-name:skill-name to prevent cross-plugin name collisions. Non-plugin skills keep their bare names.
Hook Scoping (from Claude Code)
Section titled “Hook Scoping (from Claude Code)”Skills can declare hooks in frontmatter that are scoped to the skill’s lifetime:
pub struct SkillHooks { /// Hooks that are registered when skill activates and removed when it deactivates. pub hooks: HashMap<HookEvent, Vec<HookHandler>>,}
pub struct HookHandler { pub hook_type: HookType, pub command: String, /// If true, hook fires once per session then is removed. pub once: bool,}Key Design Decisions
Section titled “Key Design Decisions”- Skills are a runtime subsystem, not a markdown convention.
- Metadata-first, content-later loading is mandatory for token discipline.
- Explicit path-based selection must outrank name heuristics.
- Dependency resolution is first-class, not ad-hoc.
- Permission expansion from skill manifests must be explicit and inspectable.
- Registry/install features must be designed with supply-chain safety from day one.
- Invocation control (
disable_model_invocation+user_invocable) is first-class — skills are not all-or-nothing. - Context fork enables heavy skills to run in isolated subagent context without polluting the main conversation.
- Shell preprocessing enables dynamic context injection before model sees the skill body.
- Context budget prevents skill metadata from crowding out conversation content.
- Plugin namespacing prevents cross-plugin name collisions from day one.