Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
431 changes: 431 additions & 0 deletions .agents/skills/magpie-setup/SKILL.md

Large diffs are not rendered by default.

1,470 changes: 1,470 additions & 0 deletions .agents/skills/magpie-setup/adopt.md

Large diffs are not rendered by default.

199 changes: 199 additions & 0 deletions .agents/skills/magpie-setup/agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/legal/release-policy.html -->

# agents — the agent-target registry (where framework-skill symlinks land)

Framework skills are **vendor-neutral content**: every supported
agent reads the *same* `SKILL.md` (the open Agent Skills format —
plain Markdown + a small YAML frontmatter). The skill body is
byte-identical no matter which agent loads it; there is **no
per-agent compile, adapter, or content transform**. The only thing
that genuinely differs between agents is **where on disk each one
looks for skills**. This file is the registry of those locations —
the single source of truth `adopt`, `upgrade`, `verify`,
`unadopt`, and `worktree-init` consult to decide *which directories*
to wire, refresh, health-check, and tear down.

It is the magpie analogue of a package manager's per-agent path
table: keep all vendor-specific knowledge here as *"where files
go"*, never as *"what files contain"*.

## The registry

| Target id | Project skills dir | Kind | Reads it |
|---|---|---|---|
| `universal` | `.agents/skills/` | universal **(canonical)** | Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode, Cline, Zed, Warp, Amp, and the rest of the cluster that converged on the shared path |
| `claude-code` | `.claude/skills/` | native (relay) | Claude Code |
| `github` | `.github/skills/` | native (relay) | GitHub's skill loader |
| `windsurf` | `.windsurf/skills/` | native (relay) | Windsurf |
| `goose` | `.goose/skills/` | native (relay) | Goose |
| `kiro` | `.kiro/skills/` | native (relay) | Kiro CLI |

The table is **extensible**: a new agent that wants framework
skills is one new row (`id`, project dir, kind), nothing else —
the same way a path-registry-driven installer adds an agent. Do
not invent per-agent *content*; if an agent needs a different
directory, add a row, never a forked skill.

## The canonical directory — `.agents/skills/`

`.agents/skills/` is the **one canonical home** for every framework
skill. Its `magpie-<skill>` entries are the links that resolve to
the actual skill source — the gitignored snapshot
(`.apache-magpie/skills/<skill>/`) for a normal adopter, or the
in-repo `../../skills/<skill>/` source for the framework's own
[local self-adoption](adopt.md#local-self-adoption-methodlocal).

This is the load-bearing move for neutrality on two fronts:

1. **One placement covers the whole shared-path cluster.** A large
set of agents (Codex, Cursor, Gemini CLI, GitHub Copilot,
OpenCode, Cline, Zed, Warp, …) all read `.agents/skills/` as
their project-scope skills path, so a single
`.agents/skills/magpie-<skill>` link is seen by all of them:

```text
.agents/skills/magpie-pr-management-triage → the canonical link
├─ Codex picks it up
├─ Cursor picks it up
├─ Gemini CLI picks it up
└─ Copilot … picks it up
```

2. **Every other target is a thin relay into it.** Agents with a
bespoke folder (`claude-code` → `.claude/skills/`, `github` →
`.github/skills/`, `windsurf`, `goose`, …) do **not** link into
the snapshot independently. Each one gets a per-skill relay
symlink that points back at the canonical entry:

```text
.claude/skills/magpie-<skill> → ../../.agents/skills/magpie-<skill>
.github/skills/magpie-<skill> → ../../.agents/skills/magpie-<skill>
```

The snapshot path appears exactly **once** — in
`.agents/skills/`. Re-pointing the framework at a new snapshot,
or repairing a broken link, is a single-source operation; the
relays follow automatically. Adopters keep their own native
(non-`magpie-`) skills in `.claude/skills/` / `.github/skills/`
untouched — only the `magpie-*` entries are relayed.

(Global / per-user skill paths diverge across agents — e.g.
`~/.cursor/skills/`, `~/.codex/skills/`, `~/.gemini/skills/`. The
framework's adoption is **project-scope** — it writes inside the
adopter repo — so it only ever cares about the project columns
above. Global installs are the operator's concern, out of scope
for `setup`.)

## Active-target selection — which dirs `adopt` wires

On every `adopt` / `upgrade` / `worktree-init`, the **active
target set** is computed as the union of:

1. **The always-on neutral targets** — `universal`
(`.agents/skills/`, canonical) **plus** the `claude-code` +
`github` relay pair. These three are wired unconditionally; the
relays are cheap relative symlinks, harmless to an agent that
never reads them, and dropping them is not a supported
configuration.
2. **Any other registry target already present in the repo** —
if `.windsurf/skills/` or `.goose/skills/` (etc.) already
exists as a real directory, it is added to the active set so
that agent sees the framework skills too (as a relay).
3. **Explicit opt-in** via the `agents:<list>` flag (see
[`SKILL.md` Inputs](SKILL.md#inputs)) — a comma-separated list
of registry ids. When passed it **replaces** the auto-detected
set (1)+(2) for that run; `universal` is always retained even
if omitted, because it is the canonical home every relay points
at — dropping it would leave the relays dangling.

The flow **never** removes or rewrites an adopter's own
non-`magpie-` skill content in any target dir. It only adds /
repairs `magpie-*` symlinks. Whatever layout an adopter's
`.claude/` / `.github/` directories were in before, the framework
always wires the `magpie-*` set the same way: canonical in
`.agents/skills/`, relayed everywhere else.

## How the framework's rules generalise across targets

Every adoption rule is "canonical link, then relays", not
"per-target independent link":

- **`magpie-` prefix** ([`SKILL.md` Golden rule 6](SKILL.md#golden-rules))
— unchanged. Every framework skill is `magpie-<skill>` in
*every* active target dir, so it never collides with an
adopter's own skills regardless of agent.
- **`.gitignore`** — one **uniform** block per active target dir,
with no per-layout variation: `/<dir>/magpie-*` ignored plus
`!/<dir>/magpie-setup` un-ignored. The negation keeps the one
committed bootstrap (`magpie-setup`) tracked; the glob ignores
the rest (the canonical links target the gitignored snapshot, so
the relays that follow them dangle on a fresh clone). See
[`adopt.md` Step 7](adopt.md#step-7--gitignore-entries-fresh-only).
- **Symlink wiring** — the canonical `magpie-<n>` →
snapshot/source link is created once in `.agents/skills/`; every
other active target (`claude-code`, `github`, `windsurf`,
`goose`, …) gets a per-skill relay `magpie-<n>` →
`../../.agents/skills/magpie-<n>`. See
[`adopt.md` Step 8](adopt.md#step-8--wire-up-the-framework-skill-symlinks).
- **Committed bootstrap** ([`SKILL.md` Golden rule 6](SKILL.md#golden-rules))
— the one committed framework artefact, `magpie-setup`, lives at
the **canonical** `.agents/skills/magpie-setup/` (a committed
copy for adopters; a committed symlink under self-adoption).
`.claude`/`.github` carry a committed relay symlink to it.
- **Local self-adoption** (framework checkout) — canonical
committed symlinks into `../../skills/<skill>/` in
`.agents/skills/`, plus committed relays into
`../../.agents/skills/magpie-<skill>` in every other active
target. See
[`adopt.md` → Local self-adoption](adopt.md#local-self-adoption-methodlocal).
- **`unadopt` / `worktree-init`** — every active target dir is
torn down / propagated uniformly. Removing only `.claude` +
`.github` would orphan the canonical `.agents/skills/magpie-*`
links; removing only `.agents` would leave every relay dangling.

## SKILL.md format portability

The same `SKILL.md` is valid in every target with no
per-agent edit:

| Frontmatter field | Cross-agent behaviour |
|---|---|
| `name`, `description` | Universal — discovery works everywhere. |
| `when_to_use` | Claude-family routing hint; other agents may ignore it → discovery still works off `description`, only routing precision degrades. |
| `argument-hint`, `capability` | magpie / Claude extensions; non-supporting agents silently ignore them. |
| `license` | Inert metadata. |

Unknown frontmatter is ignored by each agent (graceful
degradation), so there is **no compile step and no per-agent
file**. The gitignored snapshot stays the single source of truth;
`.agents/skills/` links into it, and every other target dir
resolves into it through the `.agents/skills/` relay.

## The Claude-Code-only layer (not wired for other targets)

Some of what `adopt` installs is **genuinely Claude-Code-specific
and is wired only when the `claude-code` target is active**:

- `.claude/settings.json` — the sandbox (`network.allowedDomains`
allowlist, `filesystem.denyRead`), the MCP-tool permission
allowlist, and the hooks. Schema:
`claude-code-settings.json`.
- `.claude/settings.local.json` — per-machine sandbox-allowlist
entries.
- The `setup-isolated-setup-*` skill family — sandbox / pinned-
tools / hooks installer.

Other agents adopt the **skills** (the neutral content) **without**
this layer.

> **Security caveat — this layer is a control, not cosmetics.**
> For a security framework the sandbox is a *confidentiality
> control* (it blocks exfiltration of non-public vulnerability
> data and reading `~/`). Running a security-class skill on an
> agent that lacks an equivalent control is a **policy decision**,
> not graceful degradation. Adopting the skills onto a non-Claude
> agent is supported; *executing confidential workflows there*
> requires the project to either declare that agent unsupported
> for those workflows or provide an equivalent control. `adopt`
> itself only places files — it does not grant that approval.
136 changes: 136 additions & 0 deletions .agents/skills/magpie-setup/overrides.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/legal/release-policy.html -->

# overrides — manage agentic overrides for framework skills

The agentic-overrides mechanism is the framework's answer to
"how does an adopter modify a framework skill's behaviour
without forking the framework". An override file lives at
`.apache-magpie-overrides/<framework-skill>.md` in the
adopter repo (committed). The framework skill consults the
file at run-time **before** executing default behaviour and
applies the agent-readable instructions in it.

This sub-action helps the user manage those override files —
list them, scaffold a new one, or open an existing one.

The full *contract* (what an override file may contain, how
the framework skill applies it, the hard rules that bound the
mechanism) lives in
[`docs/setup/agentic-overrides.md`](../../docs/setup/agentic-overrides.md)
in the framework. This file is the operational helper.

## Inputs

- `<framework-skill>` — required. The skill name to scaffold
/ open the override for (e.g. `pr-management-triage`).

## Step 0 — Pre-flight

1. The repo must be adopted (see [`verify.md`](verify.md)
check 1 + check 5). If not, redirect to `/magpie-setup
adopt`.
2. The named `<framework-skill>` must exist in the snapshot at
`<repo-root>/.apache-magpie/skills/<framework-skill>/`.
If not, name the typo and list the available framework
skills.

## Step 1 — Resolve the override path

`<override-path>` =
`<repo-root>/.apache-magpie-overrides/<framework-skill>.md`.

If `<override-path>` already exists, this is an *open*
operation: surface the file's current content, ask the user
what they want to change, walk through the edit. Same as if
they had opened the file in their editor — the agent is just
doing it agentically.

If `<override-path>` doesn't exist, this is a *scaffold*
operation: continue to Step 2.

## Step 2 — Scaffold a new override

Read the framework skill's structure to know what the
override might target — the skill's section headings, golden
rules, decision-table rows, etc. Surface these as candidate
override anchors.

Ask the user what they want to override:

- *"Skip Step N"* → invalidate a specific step.
- *"Replace Step N with: ..."* → replace a step's behaviour.
- *"Add a new step before/after Step N: ..."* → insert.
- *"Always do X regardless of the framework's classification"*
→ pre-empt the framework's decision logic.
- Free-form — the agent interprets at run-time.

Generate the override file with the user's instructions.
Use the canonical scaffold below.

## Override file scaffold

```markdown
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/legal/release-policy.html -->

<!-- apache-magpie agentic override
Framework skill: <framework-skill>
Pinned to snapshot: see ../.apache-magpie.lock for the SHA
this override was authored against.
Applied by: the framework skill at run-time, before
executing default behaviour. -->

# Overrides for `<framework-skill>`

## Why these overrides exist

(One paragraph explaining the local context. Why does this
adopter need to deviate from the framework's default? Future
maintainers — including the agent on a later run — read this
to know whether the override is still relevant.)

## Overrides

### Override 1 — <one-line headline>

(Free-form agent-readable instructions. The framework skill
applies these before running its default behaviour. Be
specific about which step / golden rule / decision-table row
the override targets.)

### Override 2 — <one-line headline>

(...)
```

## Step 3 — Surface the contract reminders

Whenever the skill scaffolds or opens an override file,
remind the user:

1. **Never modify the snapshot** at
`<repo-root>/.apache-magpie/`. Local mods go in this
override file.
2. **If the override is widely useful, upstream it.** Open a
PR against `apache/magpie` implementing the change
in the framework skill itself. The framework will then
apply the change on every adopter's next
`/magpie-setup upgrade`, and this adopter's override
becomes redundant — at which point the user deletes it.
3. **Re-anchor on framework upgrades.** The skill's
[`upgrade.md`](upgrade.md) sub-action surfaces conflicts
when a framework upgrade restructures a skill the user has
an override for. Re-anchor when prompted.

## Failure modes

- **Snapshot missing** → redirect to `/magpie-setup upgrade`.
- **Skill name typo** → list available skills, ask again.
- **The override target is on a framework skill that does
not consult overrides** → the framework treats overrides
as opt-in per skill (each skill that supports overrides
documents this in its own `SKILL.md`). If the named
skill doesn't yet support overrides, surface that and
suggest opening a framework-side issue requesting the
hook.
Loading