skilldrop-cli 0.11.8 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -202
- package/contracts/agent.schema.json +28 -0
- package/contracts/guide.schema.json +18 -0
- package/contracts/pack.schema.json +42 -0
- package/contracts/skill.schema.json +95 -0
- package/loops/build/evals/eval_queries.json +30 -0
- package/loops/build/evals/evals.json +27 -0
- package/loops/design/evals/eval_queries.json +30 -0
- package/loops/design/evals/evals.json +26 -0
- package/loops/discover/evals/eval_queries.json +30 -0
- package/loops/discover/evals/evals.json +26 -0
- package/loops/operate/evals/eval_queries.json +30 -0
- package/loops/operate/evals/evals.json +25 -0
- package/loops/ship-a-draft/evals/eval_queries.json +30 -0
- package/loops/ship-a-draft/evals/evals.json +25 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -463,16 +463,20 @@ The six **pack plugins** work differently, because a plugin's skills have to sit
|
|
|
463
463
|
|
|
464
464
|
`.claude-plugin/{marketplace,plugin}.json` are generated from `package.json` + `packs.json` by [`build_marketplace.py`](build_marketplace.py) (`--check` guards drift in CI; `--dist` renders the branch). Use the CLI above when you want per-skill granularity, another IDE, or hooks; use the marketplace when you're in Claude Code. Rationale: [RFC-0027](docs/rfcs/0027-retire-agentbundle-export.md).
|
|
465
465
|
|
|
466
|
-
###
|
|
466
|
+
### Everything else about installing
|
|
467
467
|
|
|
468
|
-
|
|
468
|
+
The long-form install material moved to [`guides/`](guides/) so this page stays scannable:
|
|
469
469
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
470
|
+
| If you want to | Read |
|
|
471
|
+
|---|---|
|
|
472
|
+
| Install by hand into a specific IDE | [Install a skill into your IDE](guides/how-to/install-per-ide.md) |
|
|
473
|
+
| Wire a skill to an event (opt-in hooks) | [Wire a skill to an event](guides/how-to/wire-a-hook.md) |
|
|
474
|
+
| Publish your own catalogue for `--from` | [Publish your own catalogue](guides/how-to/publish-a-catalogue.md) |
|
|
475
|
+
| Use the two skills that ship scripts | [Skills that ship scripts](guides/reference/skills-with-scripts.md) |
|
|
476
|
+
| Add a skill or a loop to this repo | [Author a skill](guides/how-to/author-a-skill.md) · [Author a loop](guides/how-to/author-a-loop.md) |
|
|
477
|
+
| Understand why it is built this way | [Why loops](guides/explanation/loops.md) · [ARCHITECTURE.md](ARCHITECTURE.md) |
|
|
478
|
+
| See one change go through all four loops | [Follow one change through the loops](guides/tutorial/follow-a-change-through-the-loops.md) |
|
|
479
|
+
| Point a model at this repo | [`llms.txt`](llms.txt) — a generated index so a tool reads the few relevant pages instead of the tree |
|
|
476
480
|
|
|
477
481
|
### Reviewer subagents
|
|
478
482
|
|
|
@@ -503,145 +507,6 @@ Each generated target omits the permission field it cannot map safely rather tha
|
|
|
503
507
|
|
|
504
508
|
**Every surveyed tool now installs.** Only Cursor is absent, because it has no agent file format at all — use a custom mode ([`agents/README.md`](agents/README.md) has the steps).
|
|
505
509
|
|
|
506
|
-
### Third-party catalogs — publish your own skills through the same CLI
|
|
507
|
-
|
|
508
|
-
Any git repo or directory shaped like this one is a **catalog**: `skills/<name>/` folders each holding `SKILL.md` + `manifest.json`, optionally a root `packs.json`. That's the whole contract ([RFC-0003](docs/rfcs/0003-third-party-catalogs.md)):
|
|
509
|
-
|
|
510
|
-
```bash
|
|
511
|
-
npx skilldrop-cli list --from https://github.com/you/your-skills
|
|
512
|
-
npx skilldrop-cli install my-skill --from https://github.com/you/your-skills#v1.2 # #ref pins a branch/tag
|
|
513
|
-
npx skilldrop-cli install --pack starter --from ../local-catalog
|
|
514
|
-
npx skilldrop-cli update # updates bundled and third-party skills side by side — the ledger remembers each skill's source
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
The CLI also reads **agentbundle-shaped catalogs** ([agent-ready-repo](https://github.com/eugenelim/agent-ready-repo)) — `packs/<pack>/.apm/skills/<name>/SKILL.md` with a `pack.toml` per pack — so you can install *its* packs through the same command ([RFC-0014](docs/rfcs/0014-agentbundle-interop.md)). This is one-directional by design: skilldrop reads his shape, and no longer publishes a generated catalogue back into it ([RFC-0027](docs/rfcs/0027-retire-agentbundle-export.md)). Both shapes share the agentskills.io `SKILL.md`, so the reader just maps his packs onto the accessors above:
|
|
518
|
-
|
|
519
|
-
```bash
|
|
520
|
-
npx skilldrop-cli packs --from https://github.com/eugenelim/agent-ready-repo
|
|
521
|
-
npx skilldrop-cli install --pack contracts --from https://github.com/eugenelim/agent-ready-repo --dest .agents/skills
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
Safety model: installs **copy files only — nothing from a catalog is ever executed**; every skill passes a structural check before copying (broken folders are refused with reasons); and third-party installs print a review-before-use warning, because skills are instructions your AI agent will follow — read a stranger's `SKILL.md` before letting your agent obey it.
|
|
525
|
-
|
|
526
|
-
**Authoring a catalog:** mirror the layout above, then check it with `npx skilldrop-cli validate --from <your-repo-or-path>` before publishing. `related`, `packs.json`, and `requirements.txt` all work in third-party catalogs exactly as they do here.
|
|
527
|
-
|
|
528
|
-
### Manual install
|
|
529
|
-
|
|
530
|
-
Each skill is a plain directory. Installation is always the same two steps: (1) copy the skill folder into your IDE's skills/rules location, then (2) install the skill's dependencies (the commands are in `manifest.json` under `deps`, or run the install line from the skill's SKILL.md). Optionally, also copy the companions listed under `related` in the skill's `manifest.json` — skills reference each other, and while a hand-off to an uninstalled sibling degrades gracefully to inline guidance, the pipelines work best complete.
|
|
531
|
-
|
|
532
|
-
### Claude Code
|
|
533
|
-
|
|
534
|
-
Claude Code reads skills from two locations:
|
|
535
|
-
|
|
536
|
-
- **User-scope** (available in every project): `~/.claude/skills/<skill-name>/`
|
|
537
|
-
- **Project-scope** (tracked with the repo): `<project>/.claude/skills/<skill-name>/`
|
|
538
|
-
|
|
539
|
-
Install a skill by copying its folder — drop the directory directly into the skills location, **not** its parent category folder:
|
|
540
|
-
|
|
541
|
-
```bash
|
|
542
|
-
# user-scope (recommended for personal use)
|
|
543
|
-
mkdir -p ~/.claude/skills
|
|
544
|
-
cp -R skills/architecture-diagrams ~/.claude/skills/
|
|
545
|
-
cp -R skills/figma-diagrams ~/.claude/skills/
|
|
546
|
-
|
|
547
|
-
# project-scope (recommended when sharing with a team)
|
|
548
|
-
mkdir -p .claude/skills
|
|
549
|
-
cp -R skills/architecture-diagrams .claude/skills/
|
|
550
|
-
cp -R skills/figma-diagrams .claude/skills/
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
Claude Code discovers the skill via its `SKILL.md` frontmatter `name` field. Invoke it in chat with `/<skill-name>` or by describing the task — Claude will route to the matching skill automatically.
|
|
554
|
-
|
|
555
|
-
### Cursor
|
|
556
|
-
|
|
557
|
-
Cursor does not have a native "skills" concept, but you can install a skill as a **project rule**:
|
|
558
|
-
|
|
559
|
-
1. Copy the skill folder somewhere in the repo (e.g. `.cursor/skills/<skill-name>/`):
|
|
560
|
-
```bash
|
|
561
|
-
mkdir -p .cursor/skills
|
|
562
|
-
cp -R skills/architecture-diagrams .cursor/skills/
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
2. Create `.cursor/rules/<skill-name>.mdc` that points Cursor at it:
|
|
566
|
-
```markdown
|
|
567
|
-
---
|
|
568
|
-
description: <paste the skill's description from manifest.json>
|
|
569
|
-
globs:
|
|
570
|
-
alwaysApply: false
|
|
571
|
-
---
|
|
572
|
-
Follow the instructions in .cursor/skills/<skill-name>/SKILL.md when the user requests this task.
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
3. In chat, attach `SKILL.md` with `@` or simply describe the task — the rule will fire when the description matches.
|
|
576
|
-
|
|
577
|
-
### Kiro (IDE and CLI)
|
|
578
|
-
|
|
579
|
-
Kiro has native **Agent Skills**, and Kiro IDE and Kiro CLI read the same directories. Copy the folder in — that's the whole install:
|
|
580
|
-
|
|
581
|
-
```bash
|
|
582
|
-
mkdir -p .kiro/skills # workspace scope
|
|
583
|
-
cp -R skills/figma-diagrams .kiro/skills/
|
|
584
|
-
|
|
585
|
-
mkdir -p ~/.kiro/skills # global scope, every project
|
|
586
|
-
cp -R skills/figma-diagrams ~/.kiro/skills/
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
Kiro matches the skill by its `SKILL.md` frontmatter `name` (which must equal the folder name) and `description` — the same contract every other tool uses.
|
|
590
|
-
|
|
591
|
-
**No steering file needed.** Earlier versions of the CLI also wrote `.kiro/steering/<skill-name>.md` pointing back at the skill. That predates native Agent Skills, and because a steering file without frontmatter is *always* loaded, it pinned one description per installed skill into every session's context — to point at a folder Kiro already reads. The CLI no longer writes them, and `install`/`uninstall` remove any it wrote before. A steering file it didn't author is left alone, with a note.
|
|
592
|
-
|
|
593
|
-
### Codex and GitHub Copilot
|
|
594
|
-
|
|
595
|
-
Both read `SKILL.md` folders, and both deliberately read *other* tools' directories — so a skilldrop install often already works with no extra step:
|
|
596
|
-
|
|
597
|
-
| Path | Read by |
|
|
598
|
-
|---|---|
|
|
599
|
-
| `.claude/skills/` | Claude Code, **Copilot CLI** |
|
|
600
|
-
| `.agents/skills/` | **Codex** (project), **Copilot CLI** |
|
|
601
|
-
| `.github/skills/` | **Copilot** |
|
|
602
|
-
| `~/.codex/skills/` | Codex (personal) |
|
|
603
|
-
| `~/.copilot/skills/` | Copilot (personal) |
|
|
604
|
-
|
|
605
|
-
**If you already ran `skilldrop install --project`, Copilot CLI can use every skill you installed** — `.claude/skills/` is one of its discovery paths. Otherwise pick the path your tool reads:
|
|
606
|
-
|
|
607
|
-
```bash
|
|
608
|
-
npx skilldrop-cli install --pack dev-team --dest .agents/skills # Codex + Copilot CLI
|
|
609
|
-
npx skilldrop-cli install --pack dev-team --dest .github/skills # Copilot
|
|
610
|
-
npx skilldrop-cli install --pack dev-team --dest ~/.codex/skills # Codex, all projects
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
There is no `--ide codex` or `--ide copilot` flag yet, and `--dest` is not a workaround here — it writes the identical folder the native flags would. Both tools also read a repo-root `AGENTS.md`, which this repo has.
|
|
614
|
-
|
|
615
|
-
### Continue, Cline, Aider, and other agents
|
|
616
|
-
|
|
617
|
-
These tools don't have a standard skills directory yet. Two patterns work:
|
|
618
|
-
|
|
619
|
-
- **Context attachment.** Copy the skill folder anywhere in the repo, then attach `SKILL.md` to your prompt (Continue: `@file`, Cline: `@file`, Aider: `/add <path>`) and tell the agent to follow it.
|
|
620
|
-
- **Custom prompt / agent.** Paste `SKILL.md` into the IDE's custom-agent or system-prompt configuration. The skill's `manifest.json` `description` field is a good seed for the agent's name/summary.
|
|
621
|
-
|
|
622
|
-
In all cases, the scripts are invoked from the **copied** folder, so keep the directory structure intact — don't flatten `scripts/` or `templates/` out of the skill folder.
|
|
623
|
-
|
|
624
|
-
### VS Code (Continue / Cline extensions)
|
|
625
|
-
|
|
626
|
-
These behave like the "Other agents" path above. For Continue, you can also add the skill folder to `.continue/config.json` under `contextProviders` so `SKILL.md` shows up in `@` suggestions.
|
|
627
|
-
|
|
628
|
-
## Installing dependencies
|
|
629
|
-
|
|
630
|
-
Each skill declares its deps in `manifest.json`:
|
|
631
|
-
|
|
632
|
-
- **`deps.npm`** → run `npm install <packages>` before using the skill (or let `SKILL.md` step 1 install them on demand).
|
|
633
|
-
- **`deps.pip`** → run `python3 -m pip install -r <skill>/requirements.txt`.
|
|
634
|
-
|
|
635
|
-
Per-skill quick reference:
|
|
636
|
-
|
|
637
|
-
| Skill | Install command (run from inside the copied skill folder) |
|
|
638
|
-
|---|---|
|
|
639
|
-
| `figma-diagrams` | `python3 -m pip install -r requirements.txt` + `export FIGMA_TOKEN=figd_...` |
|
|
640
|
-
| `deck-builder` | `python3 -m pip install -r requirements.txt` (installs `python-pptx`) |
|
|
641
|
-
| _all other skills_ | _no runtime deps — pure markdown skills_ |
|
|
642
|
-
|
|
643
|
-
For `figma-diagrams`, you also need a [Figma Personal Access Token](https://www.figma.com/developers/api#access-tokens) exported as the `FIGMA_TOKEN` env var.
|
|
644
|
-
|
|
645
510
|
## Reviewer agents
|
|
646
511
|
|
|
647
512
|
The [`agents/`](agents/) folder ships **portable reviewer personas** — single-file agents you delegate code and test review to, packaged in Claude Code subagent format (frontmatter + system prompt) but written so the body pastes into Cursor, Codex, Kiro, Continue, Cline, or Aider just as cleanly.
|
|
@@ -650,65 +515,10 @@ The [`agents/`](agents/) folder ships **portable reviewer personas** — single-
|
|
|
650
515
|
|---|---|---|
|
|
651
516
|
| [`devils-advocate`](agents/devils-advocate.md) | Correctness — edge cases, broken assumptions, staff-engineer pushback, test gaps | "Will this break?" |
|
|
652
517
|
| [`code-quality`](agents/code-quality.md) | Craft — naming, structure, duplication, complexity, readability | "Will the next engineer hate this?" |
|
|
653
|
-
|
|
654
518
|
| [`security-reviewer`](agents/security-reviewer.md) | Exploitability — injection, authz gaps, secret handling, unsafe deserialisation | "How would someone abuse this?" |
|
|
655
519
|
|
|
656
520
|
No tool auto-discovers a folder named `agents/`; it's the canonical source of truth. See [`agents/README.md`](agents/README.md) for where to copy each file in your tool — `.claude/agents/` for Claude Code, a custom mode for Cursor, an `AGENTS.md` section for Codex, a steering file or custom agent for Kiro.
|
|
657
521
|
|
|
658
|
-
## Skill Usage
|
|
659
|
-
|
|
660
|
-
All skills are invoked in chat. Arguments are passed as plain text after the skill's trigger phrase (or via `$ARGUMENTS` when invoked as a slash command in Claude Code).
|
|
661
|
-
|
|
662
|
-
### `architecture-diagrams`
|
|
663
|
-
|
|
664
|
-
Natural-language trigger (works in any IDE that has the skill installed):
|
|
665
|
-
|
|
666
|
-
> Draw me a Mermaid diagram of a three-tier web app on AWS with an ALB, two ECS services, and an RDS Postgres backend.
|
|
667
|
-
|
|
668
|
-
Slash-command form (Claude Code):
|
|
669
|
-
|
|
670
|
-
```
|
|
671
|
-
/architecture-diagrams three-tier web app on AWS with ALB, two ECS services, RDS Postgres
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
Everything after the slash command becomes `$ARGUMENTS` inside the skill.
|
|
675
|
-
|
|
676
|
-
### `figma-diagrams`
|
|
677
|
-
|
|
678
|
-
Natural-language trigger:
|
|
679
|
-
|
|
680
|
-
> Inspect the structure of this Figma file: https://figma.com/file/abc123/MyArchitecture
|
|
681
|
-
|
|
682
|
-
Slash-command form (Claude Code):
|
|
683
|
-
|
|
684
|
-
```
|
|
685
|
-
/figma-diagrams inspect https://figma.com/file/abc123/MyArchitecture
|
|
686
|
-
/figma-diagrams post-comment https://figma.com/file/abc123/MyArchitecture "Looks good — ship it."
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
The skill parses `$ARGUMENTS` to figure out which Figma URL you mean and which action to take.
|
|
690
|
-
|
|
691
|
-
## Adding a new skill
|
|
692
|
-
|
|
693
|
-
Full contributor guide — the three lanes, the PR gates, and the release flow — is in [CONTRIBUTING.md](CONTRIBUTING.md). The short version:
|
|
694
|
-
|
|
695
|
-
0. Write a one-page RFC first — copy [`docs/rfcs/0000-template.md`](docs/rfcs/0000-template.md) to `docs/rfcs/NNNN-<slug>.md` and record the problem, the fit check, and the alternatives. New skills and structural changes need one; fixes to existing skills don't.
|
|
696
|
-
1. Create `skills/<your-skill>/SKILL.md` with this frontmatter:
|
|
697
|
-
```yaml
|
|
698
|
-
---
|
|
699
|
-
name: your-skill
|
|
700
|
-
description: One sentence, use-case-first. AI agents match this against user prompts to decide when to invoke.
|
|
701
|
-
---
|
|
702
|
-
```
|
|
703
|
-
2. Add `skills/<your-skill>/manifest.json` with the same `name` + `description` plus declared `deps` and required env vars — this is what makes the skill portable across IDEs.
|
|
704
|
-
3. Keep `SKILL.md` short (under ~500 lines). Move long reference material into sibling files like `reference.md`, `examples.md`, or `templates/`.
|
|
705
|
-
4. If your skill needs scripts, drop them in `scripts/` and reference them with a path relative to the skill folder — **avoid hard-coding `${CLAUDE_SKILL_DIR}` only**; show both paths so non–Claude-Code users aren't stuck.
|
|
706
|
-
5. Add an `evals/` folder: `evals.json` (at least one realistic prompt with a list of assertions the output must satisfy) and `eval_queries.json` (phrases that should and should **not** trigger the skill). These double as the checklist for the manual test pass and keep the `description` honest about when the skill fires.
|
|
707
|
-
6. Add an entry to the **Skills in this repo** table above and to the **Installing dependencies** table.
|
|
708
|
-
7. Add the skill to at least one pack **and** at least one outcome in `packs.json`.
|
|
709
|
-
8. If the change is going out in a release, add a bullet to [`CHANGELOG.md`](CHANGELOG.md) under the new version — the site build fails without one.
|
|
710
|
-
9. Run `python3 validate.py` from the repo root — it checks name consistency, the tier sync with `model-routing.json`, the `related`↔SKILL.md reference sync, description sync, pack and outcome membership, and eval file shape.
|
|
711
|
-
|
|
712
522
|
## License
|
|
713
523
|
|
|
714
524
|
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/sananthanarayan/skilldrop/contracts/agent.schema.json",
|
|
4
|
+
"title": "skilldrop reviewer subagent frontmatter",
|
|
5
|
+
"$comment": "RFC-0012 / RFC-0029. agents/<name>.md is a single markdown file whose YAML frontmatter is already Claude Code's format; the body is the system prompt. The CLI projects this into each target's own shape (Kiro JSON, Codex TOML, Copilot .agent.md), so these four fields are the portable core.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["name", "description"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"name": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
13
|
+
"description": "Must equal the filename stem. A rename that misses one silently breaks every delegation pointing here."
|
|
14
|
+
},
|
|
15
|
+
"description": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "What routes a delegation to this agent. Required — without it the agent is unreachable."
|
|
18
|
+
},
|
|
19
|
+
"tools": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Comma-separated tool names. Recommended; the CLI maps these per target and warns where a tool has no equivalent."
|
|
22
|
+
},
|
|
23
|
+
"model": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Recommended. A hint the target may honour or ignore."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/sananthanarayan/skilldrop/contracts/guide.schema.json",
|
|
4
|
+
"title": "skilldrop guide frontmatter",
|
|
5
|
+
"$comment": "RFC-0029. Diátaxis `kind` is a PAGE CONTRACT, not a directory requirement — the directory is a convenience, the frontmatter is the truth. That keeps the tree shallow while still forcing each page to declare what kind of document it is, which is the discipline Diátaxis actually provides.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["title", "summary", "kind"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"title": { "type": "string", "description": "Sentence case. Becomes the page's single h1." },
|
|
11
|
+
"summary": { "type": "string", "description": "One line, shown in the guides index." },
|
|
12
|
+
"kind": {
|
|
13
|
+
"enum": ["tutorial", "how-to", "reference", "explanation"],
|
|
14
|
+
"description": "tutorial = learning by doing. how-to = a task with a goal. reference = look it up. explanation = why it is this way. A page that cannot pick one is doing two jobs and should be split."
|
|
15
|
+
},
|
|
16
|
+
"status": { "enum": ["draft", "review", "stable", "deprecated"], "default": "stable" }
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/sananthanarayan/skilldrop/contracts/pack.schema.json",
|
|
4
|
+
"title": "skilldrop packs.json",
|
|
5
|
+
"$comment": "RFC-0001 / RFC-0026 / RFC-0029. Packs and outcomes are METADATA ONLY — skills never move out of flat skills/<name> folders. Packs answer WHO needs a skill; outcomes answer WHY someone opened the catalogue. Both get the same two-way membership check in validate.py.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["version", "packs", "outcomes"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"$comment": { "type": "string" },
|
|
11
|
+
"version": { "type": "string" },
|
|
12
|
+
"packs": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"description": "Role-based bundles. Keys are pack names.",
|
|
15
|
+
"additionalProperties": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"required": ["description", "skills"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"description": { "type": "string", "description": "One line — who this pack is for." },
|
|
21
|
+
"skills": { "type": "array", "items": { "type": "string" }, "minItems": 1,
|
|
22
|
+
"description": "Real skill folders. Every skill must appear in at least one pack." },
|
|
23
|
+
"loops": { "type": "array", "items": { "type": "string" },
|
|
24
|
+
"description": "RFC-0028. Real loops/ folders. Every loop must appear in at least one pack." }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"outcomes": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"description": "The catalogue's second browse axis. A browse aid only — never an install unit; the CLI takes no --outcome.",
|
|
31
|
+
"additionalProperties": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"required": ["description", "skills"],
|
|
35
|
+
"properties": {
|
|
36
|
+
"description": { "type": "string", "description": "The chip's tooltip on the catalogue site." },
|
|
37
|
+
"skills": { "type": "array", "items": { "type": "string" }, "minItems": 1 }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/sananthanarayan/skilldrop/contracts/skill.schema.json",
|
|
4
|
+
"title": "skilldrop skill manifest",
|
|
5
|
+
"$comment": "RFC-0029. This shape lived only as prose in AGENTS.md, so the one authoritative statement of what a manifest is was a paragraph a contributor had to read and obey. It is now data. Checked by hand-rolled stdlib code in validate.py — skilldrop ships zero runtime dependencies and this file must not become a reason to add `jsonschema`.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["name", "version", "description", "entrypoint", "deps", "env", "related", "tags", "model"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"name": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
13
|
+
"description": "Kebab-case. Must equal the folder name AND the SKILL.md frontmatter name — the triple-match in golden rule 1."
|
|
14
|
+
},
|
|
15
|
+
"version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
|
|
16
|
+
"description": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "The most-read string in the skill. Use-case-first: what it does, then the trigger phrases an agent matches on. Must match the SKILL.md frontmatter description."
|
|
19
|
+
},
|
|
20
|
+
"entrypoint": { "const": "SKILL.md" },
|
|
21
|
+
"deps": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"additionalProperties": false,
|
|
24
|
+
"required": ["npm", "pip"],
|
|
25
|
+
"properties": {
|
|
26
|
+
"npm": { "type": "array", "items": { "type": "string" } },
|
|
27
|
+
"pip": { "type": "array", "items": { "type": "string" } }
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"env": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"additionalProperties": false,
|
|
33
|
+
"required": ["required", "optional"],
|
|
34
|
+
"properties": {
|
|
35
|
+
"required": { "type": "array", "items": { "type": "string" },
|
|
36
|
+
"description": "Vars the skill cannot work without, e.g. FIGMA_TOKEN." },
|
|
37
|
+
"optional": { "type": "array", "items": { "type": "string" },
|
|
38
|
+
"description": "Vars that change behaviour but do not block." }
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"related": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": { "type": "string" },
|
|
44
|
+
"description": "Undirected: every sibling this SKILL.md references, in either direction. validate.py enforces the sync both ways."
|
|
45
|
+
},
|
|
46
|
+
"handoff": {
|
|
47
|
+
"type": "array",
|
|
48
|
+
"description": "RFC-0028. The directed companion to `related`. Every `to` must also appear in `related`.",
|
|
49
|
+
"items": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"additionalProperties": false,
|
|
52
|
+
"required": ["to", "when", "purpose", "fallback"],
|
|
53
|
+
"properties": {
|
|
54
|
+
"to": { "type": "string", "description": "A skill folder name. Never this skill." },
|
|
55
|
+
"when": { "type": "string", "description": "The condition under which the hand-off fires." },
|
|
56
|
+
"purpose": { "type": "string", "description": "What the target does with what it receives." },
|
|
57
|
+
"fallback": { "type": "string", "description": "What to do when the target is not installed. Required — this is what makes an advisory hand-off degrade in a stated way instead of dead-ending." }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"tags": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
|
|
62
|
+
"model": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"additionalProperties": false,
|
|
65
|
+
"required": ["tier", "rationale"],
|
|
66
|
+
"properties": {
|
|
67
|
+
"tier": {
|
|
68
|
+
"enum": ["light", "standard", "heavy"],
|
|
69
|
+
"description": "Abstract and provider-neutral. Never a vendor model name — the provider map in model-routing.json is the only place concrete models live. Must agree with this skill's entry there."
|
|
70
|
+
},
|
|
71
|
+
"rationale": { "type": "string", "description": "One sentence: why this tier fits what the skill does." }
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"install": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"additionalProperties": false,
|
|
77
|
+
"description": "Human-readable install lines for a skill with runtime deps.",
|
|
78
|
+
"properties": { "npm": { "type": "string" }, "pip": { "type": "string" } }
|
|
79
|
+
},
|
|
80
|
+
"hooks": {
|
|
81
|
+
"type": "array",
|
|
82
|
+
"description": "RFC-0006. Only for loop-shaped skills that benefit from event automation; artifact generators carry none.",
|
|
83
|
+
"items": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"additionalProperties": false,
|
|
86
|
+
"required": ["event", "action", "description"],
|
|
87
|
+
"properties": {
|
|
88
|
+
"event": { "enum": ["session-start", "pre-commit-review", "on-demand"] },
|
|
89
|
+
"action": { "type": "string", "description": "A real skill folder this hook points at." },
|
|
90
|
+
"description": { "type": "string" }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "take this story to merged code",
|
|
4
|
+
"should_trigger": true
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"query": "run the build loop on this ticket",
|
|
8
|
+
"should_trigger": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "implement this and gate it before I merge",
|
|
12
|
+
"should_trigger": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"query": "is this branch safe to merge yet?",
|
|
16
|
+
"should_trigger": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "write me an ADR for this decision",
|
|
20
|
+
"should_trigger": false
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "design the system for this requirement",
|
|
24
|
+
"should_trigger": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "what should we build next quarter?",
|
|
28
|
+
"should_trigger": false
|
|
29
|
+
}
|
|
30
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"loop_name": "build",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": "red-gate-blocks-the-merge",
|
|
6
|
+
"prompt": "Run the build loop on this story: add a /export endpoint. `pytest` currently fails on one new test, and the endpoint reads user_id from the query string.",
|
|
7
|
+
"assertions": [
|
|
8
|
+
"Runs the stages in order — shape, implement, verify — and never starts implement without acceptance criteria a test can assert",
|
|
9
|
+
"Treats the failing pytest as a RED G2 gate that forces NOT READY on its own, independent of any review finding",
|
|
10
|
+
"Returns to the `implement` stage on NOT READY, not to `shape`, because G2's revise_to names implement",
|
|
11
|
+
"Never edits the gate script, its config, or the failing test to turn G2 green",
|
|
12
|
+
"Names the gate id (G2) and the verdict verbatim from contracts/terminals.json",
|
|
13
|
+
"Stops after 3 returns and emits BLOCKED naming what did not converge, rather than starting a 4th round"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "escalates-a-design-dispute-not-a-defect",
|
|
18
|
+
"prompt": "Build-loop this change. The gate is green but the reviewer thinks the whole caching approach is wrong.",
|
|
19
|
+
"assertions": [
|
|
20
|
+
"Records G2 as green and does not conflate a design disagreement with a gate failure",
|
|
21
|
+
"Escalates the disagreement to the `decide` stage / council-review rather than arguing it inside the diff",
|
|
22
|
+
"Treats RECONSIDER or SPLIT as leaving the loop, not as a revise",
|
|
23
|
+
"Leaves the merge decision itself to a human at G2.1"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "design the system for this requirement",
|
|
4
|
+
"should_trigger": true
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"query": "run the design loop on this PRD",
|
|
8
|
+
"should_trigger": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "how should we architect this?",
|
|
12
|
+
"should_trigger": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"query": "get this to a recorded architecture decision",
|
|
16
|
+
"should_trigger": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "implement this story",
|
|
20
|
+
"should_trigger": false
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "write the runbook for this alert",
|
|
24
|
+
"should_trigger": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "summarise this for the board",
|
|
28
|
+
"should_trigger": false
|
|
29
|
+
}
|
|
30
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"loop_name": "design",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": "constrains-then-attacks-before-ratifying",
|
|
6
|
+
"prompt": "Run the design loop for per-plan API rate limiting, from this ratified PRD.",
|
|
7
|
+
"assertions": [
|
|
8
|
+
"Runs nfr-spec first and expresses targets as numbers, not adjectives",
|
|
9
|
+
"Produces the design doc and the diagram as one artifact, and checks they agree",
|
|
10
|
+
"Runs threat-model BEFORE the G1 panel, not after",
|
|
11
|
+
"Seats council-review at G1 and records dissent plus what would change each seat's mind",
|
|
12
|
+
"Writes the ADR only after G1 returns, and carries any PROCEED WITH CONDITIONS conditions into it",
|
|
13
|
+
"Names the rejected options and why each lost"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "conditions-must-reach-the-adr",
|
|
18
|
+
"prompt": "The design-loop panel returned PROCEED WITH CONDITIONS — the operator seat wants the failure mode documented. Finish the loop.",
|
|
19
|
+
"assertions": [
|
|
20
|
+
"Does not treat PROCEED WITH CONDITIONS as PROCEED",
|
|
21
|
+
"Carries the named condition into the ADR as part of the decision",
|
|
22
|
+
"Proceeds to `record` rather than looping back to `shape`"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "turn these stakeholder notes into requirements",
|
|
4
|
+
"should_trigger": true
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"query": "run the discover loop on this complaint",
|
|
8
|
+
"should_trigger": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "what problem are we actually solving here?",
|
|
12
|
+
"should_trigger": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"query": "get this idea to a ratified brief",
|
|
16
|
+
"should_trigger": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "split this epic into stories",
|
|
20
|
+
"should_trigger": false
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "write the design doc for this",
|
|
24
|
+
"should_trigger": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "review my pull request",
|
|
28
|
+
"should_trigger": false
|
|
29
|
+
}
|
|
30
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"loop_name": "discover",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": "refuses-to-specify-on-a-thin-brief",
|
|
6
|
+
"prompt": "Run the discover loop. An account manager says enterprise customers keep hitting our API limits and are complaining.",
|
|
7
|
+
"assertions": [
|
|
8
|
+
"Starts at `gather` with requirements-interview, because the signal arrived as a conversation rather than a journey or a strategy question",
|
|
9
|
+
"Does not run all three gather skills on the same input",
|
|
10
|
+
"Tags every brief field [explicit] / [implied] / [inferred] / [missing] with its source",
|
|
11
|
+
"Marks the threshold and the affected-customer count as [missing] rather than inventing plausible numbers",
|
|
12
|
+
"Refuses to complete `specify` until the [missing] anchors are resolved, and says which ones block it",
|
|
13
|
+
"Does not self-ratify G0 — it names ratification as a human decision"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "reconsider-leaves-the-loop",
|
|
18
|
+
"prompt": "We ran discover and the stakeholder now says they actually want burst capacity, not a higher ceiling.",
|
|
19
|
+
"assertions": [
|
|
20
|
+
"Classifies this as RECONSIDER, a redirect-class verdict",
|
|
21
|
+
"States that a redirect leaves the loop rather than revising within it",
|
|
22
|
+
"Does not route back to `structure` for another brief on the original problem"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "write the postmortem for last night's incident",
|
|
4
|
+
"should_trigger": true
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"query": "run the operate loop on this service",
|
|
8
|
+
"should_trigger": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "what should we alert on and what's the runbook?",
|
|
12
|
+
"should_trigger": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"query": "we're in an incident — what do I tell customers?",
|
|
16
|
+
"should_trigger": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "implement the fix for this bug",
|
|
20
|
+
"should_trigger": false
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "design the retry architecture",
|
|
24
|
+
"should_trigger": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "draft the PRD for this feature",
|
|
28
|
+
"should_trigger": false
|
|
29
|
+
}
|
|
30
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"loop_name": "operate",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": "postmortem-must-produce-runbook-deltas",
|
|
6
|
+
"prompt": "Run the operate loop. Our rate limiter alert fired last night — a customer's retry loop hammered the API for 40 minutes.",
|
|
7
|
+
"assertions": [
|
|
8
|
+
"Enters at `respond`, not at `instrument` — an incident does not replay earlier stages",
|
|
9
|
+
"Stages the communication (detect / mitigate / resolve) and matches the message to the stage the incident is in",
|
|
10
|
+
"Produces a blameless postmortem that names missing guardrails, never people",
|
|
11
|
+
"Ends in concrete runbook deltas phrased as before/after edits",
|
|
12
|
+
"Routes those deltas back to `document` via G3's revise edge rather than treating the postmortem as terminal"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": "refuses-to-guess-incident-facts",
|
|
17
|
+
"prompt": "Write the postmortem for last night's outage. I don't have the exact timeline or customer impact numbers yet.",
|
|
18
|
+
"assertions": [
|
|
19
|
+
"Emits BLOCKED naming the missing facts rather than producing a confident postmortem",
|
|
20
|
+
"Does not fabricate timings, customer counts, or a root cause",
|
|
21
|
+
"States exactly what to re-run with once the facts exist"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "turn these notes into something I can send",
|
|
4
|
+
"should_trigger": true
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"query": "run ship-a-draft on this transcript",
|
|
8
|
+
"should_trigger": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "take this ticket to a finished document",
|
|
12
|
+
"should_trigger": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"query": "polish this draft and check the argument",
|
|
16
|
+
"should_trigger": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "implement this feature",
|
|
20
|
+
"should_trigger": false
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "gate my pull request",
|
|
24
|
+
"should_trigger": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "what should our OKRs be?",
|
|
28
|
+
"should_trigger": false
|
|
29
|
+
}
|
|
30
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"loop_name": "ship-a-draft",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": "picks-the-generator-before-collecting",
|
|
6
|
+
"prompt": "Run ship-a-draft on this Slack thread — I need something the exec team can read.",
|
|
7
|
+
"assertions": [
|
|
8
|
+
"Chooses the target generator (exec-summary) BEFORE running intake, because the brief is shaped for a target",
|
|
9
|
+
"Runs brief-intake and tags every field explicit / implied / inferred / missing",
|
|
10
|
+
"Runs doc-critique at G4 against the same rubric the generator was held to",
|
|
11
|
+
"Runs output-hygiene last, only once the argument is settled",
|
|
12
|
+
"Reports what output-hygiene did not touch"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": "major-rewrite-returns-to-intake",
|
|
17
|
+
"prompt": "The critique on my draft came back MAJOR REWRITE. Continue the ship-a-draft wrapper.",
|
|
18
|
+
"assertions": [
|
|
19
|
+
"Routes back to `intake`, not to `draft`, because G4's revise_to names intake",
|
|
20
|
+
"Explains that re-drafting from the same incomplete brief reproduces the same gaps",
|
|
21
|
+
"Does not run output-hygiene on a draft that is about to be rewritten"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skilldrop-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Portable AI-agent skills for the deliverables knowledge workers ship \u2014 diagrams, ADRs, PRDs, runbooks, decks, reviews \u2014 installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Sanjay Ananthanarayan",
|