This document specifies the single-source format for community components
in community-config/. Components written in this format are compiled by
scripts/build-components.sh into tool-specific outputs for Gemini CLI
and Claude Code.
name, description, type.| Type | Source location | Gemini CLI output | Claude Code output |
|---|---|---|---|
skill |
skills/<name>/SKILL.md |
.gemini/skills/<name>/SKILL.md |
.claude/skills/<name>/SKILL.md |
command |
commands/<name>.md |
.gemini/commands/<name>.toml |
.claude/skills/<name>/SKILL.md |
agent |
agents/<name>/AGENT.md |
.gemini/agents/<name>.md |
.claude/agents/<name>/AGENT.md |
Hooks, policies, and MCP servers use JSON formats and are handled separately by the build script (merged into tool-specific config files).
Every source file uses Markdown with YAML frontmatter:
---
# === Universal metadata (required) ===
name: my-component
description: "Brief description used for discovery and activation"
type: skill # skill | command | agent
# === Gemini CLI overrides (optional) ===
# Only include if Gemini needs different metadata than the universal fields.
# Omit entirely to use universal defaults.
gemini:
# No extra fields needed for most skills.
# For commands: no overrides needed (description + body used as-is).
# === Claude Code overrides (optional) ===
# Only include if Claude Code needs extra metadata.
# Omit entirely to use universal defaults.
claude:
allowed-tools:
- Read
- Write
- Edit
- Bash
- Grep
- Glob
user-invocable: true
# disable-model-invocation: false # default
---
# Component Title
Prompt content here — shared across ALL tools, written once.
## Sections
Detailed instructions, workflows, constraints...
| Field | Type | Description |
|---|---|---|
name |
string | Component identifier (kebab-case) |
description |
string | Brief description for discovery. Used by both tools. |
type |
string | skill, command, or agent |
metadata |
mapping | Optional container recognised by the agentskills.io spec for non-standard keys. crewrig curates metadata.provenance here (see Provenance & Forks). |
The gemini: section is rarely needed. The build script uses universal
fields by default:
skill: generates a SKILL.md with name and description in
the frontmatter, body as-is.command: generates a .toml file with description and the
body wrapped in prompt = """...""".agent: generates a flat .gemini/agents/<name>.md file with YAML
frontmatter (name, description) — required by Gemini CLI’s
sub-agent discovery — followed by the body as the system prompt.The claude: section adds Claude Code-specific frontmatter fields:
| Field | Type | Default | Description |
|---|---|---|---|
allowed-tools |
string[] | (none) | Tools the skill can use |
user-invocable |
boolean | true |
Can the user invoke with /name? |
disable-model-invocation |
boolean | false |
Prevent auto-invocation? |
context |
string | (none) | Run context (fork for isolated subagent) |
agent |
string | (none) | Agent type (Explore, Plan, etc.) |
model |
string | (none) | Model override |
effort |
string | (none) | Effort level override |
community-config/skills/<name>/SKILL.mdGemini CLI → .gemini/skills/<name>/SKILL.md
---
name: <name>
description: <description>
---
<body>
Claude Code → .claude/skills/<name>/SKILL.md
---
name: <name>
description: <description>
allowed-tools: # from claude.allowed-tools (if present)
- Read
- Bash
user-invocable: true # from claude.user-invocable (if present)
---
<body>
scripts/, references/, assets/)Per the Agent Skills spec, a
skill may ship three optional resource subfolders alongside its
SKILL.md:
| Subfolder | Purpose |
|---|---|
scripts/ |
Executable code the skill invokes (Python, Bash, JavaScript). |
references/ |
Additional documentation loaded on demand. |
assets/ |
Templates, fixtures, static resources. |
When present in a source under community-config/skills/<name>/,
these subfolders are propagated verbatim to both build outputs
(.gemini/skills/<name>/<subfolder>/... and
.claude/skills/<name>/<subfolder>/...). Executable bits are
preserved. Skill bodies should reference resources by path relative
to the skill root (e.g. scripts/curate.sh), so the same invocation
works regardless of whether the skill lives at project level
(.gemini/.claude/) or user level (~/.gemini/, ~/.claude/).
community-config/commands/<name>.mdGemini CLI → .gemini/commands/<name>.toml
description = "<description>"
prompt = """
<body>
"""
Claude Code → .claude/skills/<name>/SKILL.md
---
name: <name>
description: <description>
user-invocable: true
---
<body>
community-config/agents/<name>/AGENT.mdGemini CLI → .gemini/agents/<name>.md
---
name: <name>
description: <description>
metadata: # propagated when source declares metadata.provenance
provenance:
canonical: ...
feedback: ...
version: ...
---
<body — becomes the agent's system prompt>
Claude Code → .claude/agents/<name>/AGENT.md
---
name: <name>
description: <description>
---
<body>
Components carry a metadata.provenance: block in their frontmatter that
survives forks and lets feedback flow back to the right repo. The block
is optional but recommended for any component intended to be re-shared.
provenance lives under metadata: to keep the root frontmatter
restricted to fields recognised by the
agentskills.io specification
(name, description, license, compatibility, metadata,
allowed-tools). The spec reserves metadata: for non-standard keys —
crewrig curates provenance there.
---
name: my-component
description: "..."
type: skill
metadata:
provenance:
canonical: "${CANONICAL_REPO}" # origin (audit + license trace)
feedback: "${FEEDBACK_REPO}" # MR target (defaults to canonical)
version: "1.0.0" # version at build/import
---
${SHELL_LIKE} placeholders are resolved at build time by
scripts/build-components.sh from crewrig.config.toml at the repo
root. Each line in the config file maps an uppercased key to a value:
canonical_repo = "https://github.com/hcross/crewrig"
feedback_repo = "https://github.com/hcross/crewrig"
The build substitutes every ${KEY} placeholder it encounters in the
generated outputs (.gemini/, .claude/) — frontmatter and body —
not only inside the metadata.provenance: block. This is intentional:
components may reference ${CANONICAL_REPO} or other config keys in
their prompt body too. Source files keep the placeholders untouched.
When you fork crewrig (or a fork of it):
crewrig.config.toml to point at your URLs. Typically:
canonical_repo pointing at the upstream you forked from
(audit trail).feedback_repo to your own repo so harness feedback lands
internally.task build-components to regenerate the outputs with your
values.crewrig.config.toml and the regenerated outputs.The version: field in metadata.provenance: is a literal
per-component string, not a placeholder. It tracks the component’s own
evolution independently from the host repo.
The metadata.provenance.version field follows
Semantic Versioning
(MAJOR.MINOR.PATCH):
| Bump | When |
|---|---|
PATCH (1.0.0 → 1.0.1) |
Friction-driven fix or wording change. The skill’s contract is unchanged; an agent following 1.0.0 and an agent following 1.0.1 produce equivalent output. Most curator-driven fixes are PATCH. |
MINOR (1.0.1 → 1.1.0) |
Additive change. New section, new recognition signal, new payload field, new optional behaviour. Backward-compatible — agents following 1.0.x keep working unchanged. |
MAJOR (1.1.0 → 2.0.0) |
Breaking contract change. Removed payload fields, renamed required fields, semantics flip. Forks pinning 1.x need to migrate consciously. |
Bump rule. Every PR that touches a SKILL.md or AGENT.md
source under community-config/ MUST bump metadata.provenance.version
in the same diff. CI enforces this via scripts/check-skill-versions.sh
(see task check-skill-versions for the local invocation). The
rationale:
evidence: <path>:<line> against an
unspecified version drifts silently once the source changes. The
version pins the contract observed at tag time.~/.gemini/, ~/.claude/) need
a signal to re-pull. A version field with no bump = no signal.harness-feedback issues can compare the
friction’s observed version against the current canonical version
and immediately see whether the friction has already been fixed.The bump goes in the same PR as the change. A “version-only bump” PR is not a thing — it always accompanies a content edit.
metadata.provenance: blockComponents shipped before the provenance contract existed (or intentionally unscoped) build unchanged — the resolver only acts on content that actually contains placeholders. There is no automatic backfill.
The build script (scripts/build-components.sh) requires:
yq (preferred) for YAML frontmatter parsing, or a lightweight
Python helper as fallback.jq for JSON merging (hooks, policies, MCP servers).name, description, and type in
the frontmatter.type field MUST be one of: skill, command, agent.---) MUST NOT be empty.gemini:, claude:) are optional.