From c62fa8d6a03377370c3a08ac49320cbba1c44227 Mon Sep 17 00:00:00 2001 From: Dotta <34892728+cryppadotta@users.noreply.github.com> Date: Thu, 30 Jul 2026 07:40:33 -0700 Subject: [PATCH] docs(agents): add create-paperclip-bundled-skill agent skill (#10477) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents learn repeatable procedures through skills, and Paperclip ships a curated skills catalog in `packages/skills-catalog` > - People frequently send agents an idea, a tweet, or a task and ask for it to become a catalog skill > - Until now no written procedure existed for that flow, so each attempt rediscovered the catalog rules (frontmatter fields, `catalog-ref.json`, manifest regeneration, test expectations) > - This pull request adds a repo agent skill that documents the full find-or-make-and-publish procedure > - The benefit is that any agent can turn source material into a correct catalog pull request on the first pass ## Linked Issues or Issue Description No public issue exists. Feature description: agents that maintain this repository need a documented procedure to (a) research whether a requested skill already exists, (b) add it to the skills catalog as a local skill or a pinned external reference, (c) include worked examples, and (d) regenerate the manifest and open a pull request. This change adds that procedure as an agent skill. Related PR: #10410 (a catalog skill addition that this skill uses as its worked example). ## What Changed - Added `.agents/skills/create-paperclip-bundled-skill/SKILL.md`. It documents: source capture (tweet fetch via the `xc` CLI or delegation), a FIND-before-MAKE search order, kind/category/slug placement rules, the `catalog-ref.json` external-reference format, local `SKILL.md` authoring rules, `examples/` requirements, manifest regeneration, `shipped-catalog.test.ts` expectation updates, and the PR procedure. - Added `.agents/skills/create-paperclip-bundled-skill/examples/new-local-skill.md`. It is a worked example of the MAKE path, based on the simplified-english catalog skill (#10410). - Added `.agents/skills/create-paperclip-bundled-skill/examples/external-reference.md`. It is a worked example of the FIND path, based on the last30days external reference that ships in the catalog today. ## Verification - `pnpm --filter @paperclipai/skills-catalog test` — 20/20 tests pass. This suite scans `.agents/**/SKILL.md` frontmatter, so it validates the new skill's description budget. - All statements about the catalog builder were checked against `packages/skills-catalog/src/catalog-builder.ts` and the live artifacts (`catalog/optional/research/last30days/catalog-ref.json`, PR #10410). ## Risks - Low risk. The change adds three markdown files under `.agents/skills/`. No runtime code changes. ## Model Used - Claude Fable 5 (Anthropic, model ID `claude-fable-5`), agentic coding session with tool use (file edits, shell, test runs). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (branch name comes from the managed execution workspace and cannot be renamed) - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable (no code paths changed; existing frontmatter tests cover the new files) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip Co-authored-by: Claude Fable 5 --- .../create-paperclip-bundled-skill/SKILL.md | 265 ++++++++++++++++++ .../examples/external-reference.md | 84 ++++++ .../examples/new-local-skill.md | 90 ++++++ 3 files changed, 439 insertions(+) create mode 100644 .agents/skills/create-paperclip-bundled-skill/SKILL.md create mode 100644 .agents/skills/create-paperclip-bundled-skill/examples/external-reference.md create mode 100644 .agents/skills/create-paperclip-bundled-skill/examples/new-local-skill.md diff --git a/.agents/skills/create-paperclip-bundled-skill/SKILL.md b/.agents/skills/create-paperclip-bundled-skill/SKILL.md new file mode 100644 index 0000000000..50b4dd57ab --- /dev/null +++ b/.agents/skills/create-paperclip-bundled-skill/SKILL.md @@ -0,0 +1,265 @@ +--- +name: create-paperclip-bundled-skill +description: > + Turn an idea, tweet, or task into a skill in the Paperclip skills catalog + (packages/skills-catalog). Use when asked to FIND or MAKE a skill and publish + it as a bundled/optional catalog skill: research prior art, reference or + author it, add examples, regenerate the manifest, open a PR. +--- + +# Create a Paperclip Bundled Skill + +Take source material — a tweet, a task description, a blog post, "make a skill +that does X" — and land it as a skill in the Paperclip skills catalog +(`packages/skills-catalog/`), delivered as a reviewed PR. The catalog is the +shelf every Paperclip company browses and installs from, so the bar is: correct +metadata, useful instructions, worked examples, and a clean validation run. + +The core rule is **FIND before MAKE**: if a good skill already exists (in the +catalog, in this repo, or published on GitHub), reference or adapt it instead +of writing a duplicate from scratch. + +## When to use + +- A human sends a tweet/link/idea and asks for it to become a Paperclip skill. +- A task asks to bundle an existing repo skill into the catalog. +- A task asks to add an external published skill to the catalog. + +## When not to use + +- The skill is company-private (belongs in that company's library via the + Skills UI/API, not the shipped catalog). +- You only need a repo-internal agent skill for working on Paperclip itself — + that goes in `.agents/skills/` or `skills/`, with no catalog machinery. + +## Step 0 — Capture the source material + +Understand exactly what the skill should teach before writing anything. + +**Tweets / X links.** Use the `xc` CLI (X API client). Paperclip engineering +agent environments ship it preinstalled and pre-authenticated; it is not a +tool you install or mint credentials for yourself. Check availability before +relying on it: + +```sh +command -v xc && xc whoami # on PATH and authenticated? if not, use the fallback below +``` + +```sh +xc get --json # the post itself (conversation_id, author) +xc search 'conversation_id:' --archive --json # rest of the thread (>7 days old needs --archive) +xc user # author context +xc search '' -n 30 # related discussion +``` + +If `xc` is not on PATH, is unauthenticated, or the account lacks read access +(the check above fails for any reason), delegate the +fetch to a teammate with X/Twitter access (e.g. the Content Strategist agent) +via a child issue: give them the URL and ask for full text of the post + thread ++ any linked content. + +**Other sources.** Fetch linked articles/READMEs directly. Record the source +URL — it goes in the skill body or PR description as attribution. + +Distill: what is the repeatable procedure? What inputs does it take? What does +"done" look like? If the source is just an aspiration ("agents should write +better commit messages"), you are authoring the procedure yourself — say so in +the PR. + +## Step 1 — FIND: search for an existing skill + +Search in this order; stop when you have a clear winner. + +1. **Already in the catalog?** Avoid duplicates (duplicate slugs fail the + build): + ```sh + grep -i '' packages/skills-catalog/generated/catalog.json + ls packages/skills-catalog/catalog/{bundled,optional}/*/ + ``` +2. **Already in this repo?** Check `.agents/skills/`, `skills/`, and issue + history (`gh search issues` / Paperclip board) for prior work on the topic. +3. **Published on GitHub?** Skills are conventionally a directory with a + `SKILL.md`: + ```sh + gh search code --filename SKILL.md "" --limit 20 + gh search repos " skill" --limit 20 + ``` + Also check known collections (e.g. `anthropics/skills`) and do a web search + for ` agent skill SKILL.md`. + +Judge candidates by: does the SKILL.md actually contain the procedure (not a +stub)? Is it maintained? What does it bundle (scripts raise the trust level)? +Is the license compatible with redistribution? Then pick a path: + +- **Good external skill exists** → add it as an **external reference** + (Step 2A). It stays attributed to and pinned at the upstream repo. +- **Partial match** → author a local skill (Step 2B) that adapts the idea; + credit the source with a link in the SKILL.md body. +- **Nothing usable** → author a new local skill (Step 2B). + +## Step 2 — Choose kind, category, and slug + +- **kind**: default to `optional`. Use `bundled` only when the skill should + ship to every Paperclip company by default — that needs explicit human/board + direction, not your judgment call. +- **category**: reuse an existing directory when one fits (`browser`, + `content`, `docs`, `finance`, `paperclip-operations`, `product`, `quality`, + `research`, `software-development`). New categories are allowed but must be + lowercase kebab-case slugs. +- **slug**: lowercase kebab-case (`^[a-z0-9]+(-[a-z0-9]+)*$`), unique across + the whole catalog (both kinds). + +The skill lives at +`packages/skills-catalog/catalog////` and its canonical +key is `paperclipai///`. + +## Step 2A — External reference path (`catalog-ref.json`) + +The directory contains **only** `catalog-ref.json` (a directory with both +`catalog-ref.json` and `SKILL.md` fails the build). The manifest builder +fetches the pinned files from GitHub at build time and inventories them. + +```sh +# Pin the exact commit for the chosen ref (tag or branch) +gh api repos///commits/ --jq .sha +``` + +```json +{ + "source": { + "type": "github", + "hostname": "github.com", + "owner": "", + "repo": "", + "ref": "", + "commit": "<40-char sha from above>", + "path": "" + }, + "files": ["SKILL.md", "references/**", "scripts/run.py"], + "defaultInstall": false, + "recommendedForRoles": ["researcher"], + "requires": ["python3"], + "tags": ["topic", "keywords"] +} +``` + +Rules the builder enforces: + +- `files` entries are exact relative paths or `dir/**` globs; `SKILL.md` must + be included and must have frontmatter with `name` and `description`. +- If the upstream frontmatter declares `key`/`slug`, they must match the + catalog placement — otherwise pick a matching slug or use the local path. +- `commit` must be a full 40-hex SHA; every listed file must be ≤ 1 MiB. +- `recommendedForRoles`, `requires`, `tags` live in the JSON (there is no + local SKILL.md to carry them). + +See `catalog/optional/research/last30days/catalog-ref.json` for the live +example, and `examples/external-reference.md` next to this skill. + +## Step 2B — Author a local catalog skill + +Layout: + +``` +catalog//// +├── SKILL.md # required entrypoint +├── examples/ # 1–2 worked examples (Step 3) +├── references/ # optional deep-dive docs +├── scripts/ # optional — raises trust level, avoid unless needed +└── assets/ # optional templates/images +``` + +`SKILL.md` frontmatter (all validated by the builder): + +```markdown +--- +name: +description: > + 40–300 chars. Routing logic, not marketing: what it does, when to use it, + when not to. +key: paperclipai/// +recommendedForRoles: + - engineer # non-empty; used for staffing suggestions +tags: + - topic # non-empty; used for browse/search +--- +``` + +Optional frontmatter: `defaultInstall: true` (only for skills every new +company should get), `requires: [node, python3, ...]` for runtime deps. + +Body: follow `docs/guides/agent-developer/writing-a-skill.md` — "When to use" +/ "When not to use" sections, concrete commands over prose, supporting detail +in `references/`. If the skill came from a tweet or external source, link it +in the body for attribution. + +Trust level is derived from files, not declared: any `scripts/` file makes the +skill `scripts_executables` (install becomes audit-gated and you must extend +the `scriptBearing` expectation in `src/shipped-catalog.test.ts`); `assets/` +or non-markdown files make it `assets`; markdown-only skills stay +`markdown_only`. Prefer markdown-only. + +## Step 3 — Write 1–2 worked examples + +Create `examples/` inside the skill directory with one or two markdown files, +each a complete input → application → output walkthrough (realistic input, the +skill's steps applied, the finished artifact). These ship with the skill so +installers can judge it before running it, and they keep the trust level at +`markdown_only` because they are `.md` files. + +Name them by scenario, e.g. `examples/rewrite-release-note.md`. + +## Step 4 — Regenerate the manifest and update tests + +Never hand-edit `generated/catalog.json`; it is deterministic build output. + +```sh +pnpm --filter @paperclipai/skills-catalog build:manifest # regenerates generated/catalog.json +pnpm --filter @paperclipai/skills-catalog validate # must report no errors +``` + +(External references need network access to GitHub during these steps.) + +Then update `packages/skills-catalog/src/shipped-catalog.test.ts`: + +- add the new key to `EXPECTED_BUNDLED_KEYS` or `EXPECTED_OPTIONAL_KEYS` + (alphabetical order); +- if the skill bears scripts, add it to the `scriptBearing` expectation. + +```sh +pnpm --filter @paperclipai/skills-catalog test +``` + +The test suite also enforces the ≤300-char frontmatter description budget +across the repo and the ≥40-char description / non-empty roles+tags rules for +every catalog skill. + +## Step 5 — Open the PR + +Follow the `prepare-paperclip-pr` skill (`.agents/skills/prepare-paperclip-pr/`) +against `paperclipai/paperclip` master. The diff should contain exactly: + +1. the new skill directory (SKILL.md + examples/ + supporting files, **or** + catalog-ref.json), +2. the regenerated `generated/catalog.json`, +3. the `shipped-catalog.test.ts` expectation update. + +In the PR body: link the source material (tweet URL, upstream repo), state +whether this is a new skill / adaptation / external reference, and note the +trust level. Reference PR #10410 (simplified-english) as the shape of a +minimal optional-skill PR. + +## Gotchas + +- `generated/catalog.json` staleness is a validation error — always rerun + `build:manifest` after any file change inside the skill directory (the + inventory carries per-file sha256 hashes). +- Duplicate `slug` across bundled *and* optional fails the build, not just + duplicate keys. +- Symlinks inside a skill directory must resolve within it; directory + symlinks are rejected — copy files in. +- The `bundled` kind and `defaultInstall` are independent axes; don't set + `defaultInstall: true` casually on optional skills. +- For external references the builder fetches from GitHub on every manifest + build; a moved/deleted upstream breaks the build, which is why `commit` is + pinned — prefer upstream tags for `ref`. diff --git a/.agents/skills/create-paperclip-bundled-skill/examples/external-reference.md b/.agents/skills/create-paperclip-bundled-skill/examples/external-reference.md new file mode 100644 index 0000000000..6c2084794d --- /dev/null +++ b/.agents/skills/create-paperclip-bundled-skill/examples/external-reference.md @@ -0,0 +1,84 @@ +# Example — FIND path: tweet → existing skill → external reference + +Real artifact: `packages/skills-catalog/catalog/optional/research/last30days/`. + +## Input + +Dotta sends a tweet praising a "last 30 days" research workflow that sweeps +Reddit/X/YouTube for what changed recently on a topic. + +## Step 0 — Capture + +```sh +xc get https://x.com//status/ --json # post text + conversation_id +xc search 'conversation_id:' --archive --json # the rest of the thread +``` + +The thread links a GitHub repo: `mvanhorn/last30days-skill`, which already +contains a proper skill (`skills/last30days/SKILL.md` plus scripts and +references). + +## Step 1 — FIND + +- Not in the catalog, not in this repo. +- The upstream repo IS the skill — maintained, tagged releases, real SKILL.md. +- Verdict: **FIND** — add it as an external reference, keep attribution and + updates upstream. + +## Step 2A — catalog-ref.json + +Placement: `optional` / `research` / `last30days`. Pin the release tag to an +exact commit: + +```sh +gh api repos/mvanhorn/last30days-skill/commits/v3.3.0 --jq .sha +# → daca71f89eb71d0d56d01a43ed7627aa919dba4f +``` + +`catalog/optional/research/last30days/catalog-ref.json` (the only file in the +directory): + +```json +{ + "source": { + "type": "github", + "hostname": "github.com", + "owner": "mvanhorn", + "repo": "last30days-skill", + "ref": "v3.3.0", + "commit": "daca71f89eb71d0d56d01a43ed7627aa919dba4f", + "path": "skills/last30days" + }, + "files": [ + "SKILL.md", + "agents/openai.yaml", + "references/**", + "scripts/briefing.py", + "scripts/compare.sh", + "scripts/last30days.py", + "scripts/lib/**", + "scripts/setup-keychain.sh", + "scripts/store.py", + "scripts/watchlist.py" + ], + "defaultInstall": false, + "recommendedForRoles": ["researcher", "marketer", "product-manager", "analyst"], + "requires": ["node", "python3"], + "tags": ["research", "last-30-days", "social-media", "trends", "citations", "reddit", "x", "youtube"] +} +``` + +Metadata (`recommendedForRoles`, `requires`, `tags`) lives in the JSON because +there is no local SKILL.md to carry it. + +## Steps 4–5 — Manifest, tests, PR + +- `pnpm --filter @paperclipai/skills-catalog build:manifest` fetches the + pinned files from GitHub and inventories them (network required). +- The skill bundles `scripts/`, so trust level derives to + `scripts_executables` → it must also be added to the `scriptBearing` + expectation in `src/shipped-catalog.test.ts`, alongside + `EXPECTED_OPTIONAL_KEYS`. +- PR diff: `catalog-ref.json`, regenerated `generated/catalog.json`, test + expectations. PR body links both the tweet and the upstream repo, and calls + out the elevated trust level so review is deliberate. diff --git a/.agents/skills/create-paperclip-bundled-skill/examples/new-local-skill.md b/.agents/skills/create-paperclip-bundled-skill/examples/new-local-skill.md new file mode 100644 index 0000000000..7a0d1c4aa8 --- /dev/null +++ b/.agents/skills/create-paperclip-bundled-skill/examples/new-local-skill.md @@ -0,0 +1,90 @@ +# Example — MAKE path: idea → new optional catalog skill + +Real run: PAP-15684 → PR #10410 (`feat(skills-catalog): add optional +/simplified-english skill`). + +## Input + +Task from Dotta: "make a skill that has agents write user-facing text in +Simplified English." No tweet this time — the source is a known public +specification (ASD-STE100 Simplified Technical English). + +## Step 1 — FIND + +- `grep -i 'simplified\|plain.english' packages/skills-catalog/generated/catalog.json` + → no hits; nothing in `.agents/skills/` or `skills/` either. +- `gh search code --filename SKILL.md "simplified technical english"` → no + usable published skill (only STE checker tools, no SKILL.md procedure). +- Verdict: **MAKE** a new local skill. + +## Step 2 — Placement + +- kind: `optional` (useful, but not something every company must ship with). +- category: `content` (existing category, fits writing/communication). +- slug: `simplified-english`. +- Path: `packages/skills-catalog/catalog/optional/content/simplified-english/`. + +## Step 2B — Authoring + +One markdown-only `SKILL.md` (trust level stays `markdown_only`): + +```markdown +--- +name: simplified-english +description: Write user-facing comments, plans, and documents in ASD-STE100 Simplified Technical English — short, unambiguous sentences with approved words and one meaning each — so readers understand them the first time. +key: paperclipai/optional/content/simplified-english +recommendedForRoles: + - engineer + - product + - writer + - devrel +tags: + - writing + - communication + - clarity + - style +--- + +# Simplified English + +For user-facing comments, plans, and documents, write using only ASD-STE100 +Simplified Technical English. + +## Core rules + +- Use short sentences (procedures ≤ 20 words, descriptions ≤ 25 words). +- Give one instruction per sentence. +- Use approved words with one meaning each; avoid synonyms and jargon. +... +``` + +Note the frontmatter hits every builder rule: description is 40–300 chars, +`key` matches the placement, roles and tags are non-empty. + +## Steps 3–4 — Examples, manifest, tests + +- Add `examples/rewrite-status-comment.md` showing a jargon-heavy status + comment rewritten under the rules (before/after). +- `pnpm --filter @paperclipai/skills-catalog build:manifest` → regenerates + `generated/catalog.json` with the new entry. +- Add `"paperclipai/optional/content/simplified-english"` to + `EXPECTED_OPTIONAL_KEYS` in `src/shipped-catalog.test.ts` (alphabetical). +- `pnpm --filter @paperclipai/skills-catalog test` → green. + +## Step 5 — PR + +Four-part diff: + +``` +packages/skills-catalog/catalog/optional/content/simplified-english/SKILL.md +packages/skills-catalog/catalog/optional/content/simplified-english/examples/rewrite-status-comment.md +packages/skills-catalog/generated/catalog.json +packages/skills-catalog/src/shipped-catalog.test.ts +``` + +(The historical PR #10410 predates this skill and shipped as a three-part +diff without the `examples/` file; a run that follows this skill includes the +worked example from Step 3 in the same PR.) + +PR body links the ASD-STE100 spec as the source and states trust level +`markdown_only`.