Skip to content

Extending FeatherSpec

Gregor Biswanger edited this page Aug 3, 2026 · 1 revision

Extending FeatherSpec

Adding to FeatherSpec means adding Markdown files. There is no registry, no manifest and no build step.

Add a command

A command needs two files that share the same stem:

1 · The body.claude/commands/sdd-mytask.md

---
description: One-line summary shown in the / menu.
argument-hint: "[thing]"
disable-model-invocation: true
---

<!-- Single source for the /sdd-mytask workflow. Claude Code runs this file directly;
     GitHub Copilot reaches it through the one-line loader in
     .github/prompts/sdd-mytask.prompt.md. Deliberately no shell injection and no
     argument-variable substitution: Copilot supports neither. -->

# /sdd-mytask

Do something. The user may name a thing after the command; if none is given, list the
candidates and ask.

2 · The Copilot loader.github/prompts/sdd-mytask.prompt.md

---
name: sdd-mytask
description: One-line summary shown in the / menu.
argument-hint: "[thing]"
---

# /sdd-mytask

Follow [`.claude/commands/sdd-mytask.md`](../../.claude/commands/sdd-mytask.md) exactly — read
that file first and treat it as your instructions for this turn. It is the single source for
this workflow; this file only points at it and holds no rules of its own.

Anything the user typed after the command is the argument the workflow refers to.

The loader is the same three fields plus name:, and a single line pointing at the body. It never holds a rule of its own.

Invoked as /sdd-mytask in both tools. Claude Code picks up new command files without a restart; VS Code may need a full restart, not just a window reload.

Rules for writing a body

Because both tools execute the same text, the body is written to the lowest common denominator:

Don't Do instead
!`git status` "Run git status --short and use the result."
$ARGUMENTS, $0, $1 "The user may name X after the command; if none is given, ask."
Naming a tool (WebFetch, #fetch) Name the capability: "your web search or fetch capability" — and say what to do when it is missing
Assuming a terminal tool name State the command to run

Keep the HTML comment at the top. It is what stops the next person reintroducing Claude-only syntax. See Design Decisions.

Should it write to AGENTS.md?

If your command changes DocLanguage, the architecture: snapshot or a style preference, it must write to AGENTS.md — that is the only place those live. Never introduce a second store.

Add a rule

One file, no loader needed — both tools read .claude/rules/.

.claude/rules/mytopic.md:

---
paths:
  - src/**/*.ts
---

# My topic rules

- Keep it concise.

paths: is a YAML list, even for a single entry. The rule loads when a matching file is read — which also means it may not be loaded when a file is being created. If your rule must apply at creation time, state the essentials inline in the command that creates the file, the way /sdd-specify and /sdd-plan do, and note why.

Omitting paths: makes VS Code default to ** (always on). Prefer a scope: an always-on rule belongs in AGENTS.md instead.

Rule or constitution?

It is… Put it in
policy — a lifecycle, a file set, a non-negotiable AGENTS.md
craft — how to write files of a particular kind .claude/rules/<topic>.md
mutable state — language, architecture, style preferences AGENTS.md, and nowhere else

Add a skill (rarely)

FeatherSpec ships no skills on purpose: both tools read every skill's name and description up front, so each skill costs context on every request.

Add one only when a workflow genuinely needs the model to trigger it on its own, without you typing anything. Both tools read .claude/skills/<name>/SKILL.md, so a skill is shared without a loader.

Add a Copilot persona

.github/agents/<Name>.agent.md is a Copilot-only persona you pick from the agent dropdown. Claude Code has no persona picker — its equivalent is AGENTS.md plus /sdd-overview.

Do not move a persona file into .claude/agents/ expecting the same behaviour: in Claude Code that folder defines an isolated subagent with its own context window, not a persona for your conversation.

Add MCP servers or hooks

See Configuration — including the VS Code caveat that hook matchers are ignored, so a shared hook must filter on tool_name inside the script.

Clone this wiki locally