This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
A monorepo that publishes @stuffbucket/skills — an MCP server (stuffbucket) plus a collection of
agent skills. The stuffbucket MCP server exposes only two MCP tools (list_skills, get_skill) so agents
can search by intent and load skill content on demand instead of registering every skill as its own
tool. This keeps context-window cost constant as the skill catalog grows.
Each skill is a self-contained directory under plugins/stuffbucket/skills/<skill-name>/ containing
a SKILL.md (required, with YAML frontmatter name + description) and optional scripts/,
references/, assets/.
npm run setup # install deps + create MCP symlinks + build index (run once after clone)
npm run build:index # rebuild plugins/stuffbucket/skills/skill-router/{index,semantic-index}.json
npm test # build:index + MCP server smoke tests + plugin structure tests
npm run test:structure # just the plugin-structure tests (tests/test-plugin-structure.js)
npm run test:repl # interactive REPL against the MCP server
npm run lint # markdown + JS (eslint) + JSON schema validation
npm run validate # validate all skills (frontmatter + content) via Python
npm run validate:one -- plugins/stuffbucket/skills/<name>
npm run new -- <skill-name> # scaffold a new skill from template/SKILL.md
npm run package -- plugins/stuffbucket/skills/<name> # produce a .skill bundle
npm run ci # full CI: lint + validate + check:versions + test + check:llms + check:readme
npm run build:llms # regenerate llms.txt from llms.tmpl.txt
npm run build:readme # regenerate auto-managed sections in README.md
npm run check:readme # CI guard — fails if README's auto-sections are stale
npm run bump # bump version across all manifestsRun a single skill validation: npm run validate:one -- plugins/stuffbucket/skills/<name>. The
validator is plugins/stuffbucket/skills/skill-creator/scripts/quick_validate.py — invoke it
directly for tighter feedback loops.
The MCP server entry is plugins/stuffbucket/skills/skill-router/scripts/mcp-server.js (also exposed
as the stuffbucket-skills bin). The skl bin is cli.js in the same directory.
Index build is required before tests/REPL. build-index.js walks every skill directory, reads
SKILL.md frontmatter, and emits index.json + semantic-index.json in
plugins/stuffbucket/skills/skill-router/. These files are committed and shipped in the npm package
— regenerate them whenever a skill's frontmatter or description changes. prepublishOnly runs this
automatically.
Two parallel plugin manifests. .claude-plugin/marketplace.json (Claude Code) and
.github/plugin/marketplace.json (Copilot) describe the same plugin to different hosts. The
canonical MCP config lives at plugins/stuffbucket/.mcp.json; root .mcp.json and
.vscode/mcp.json are symlinks created by scripts/setup-links.js.
Skill authoring contract (enforced by quick_validate.py and validate_schemas.py):
name(kebab-case, ≤64 chars) must equal the directory name.description≤1024 chars and should state both what the skill does and when to trigger it — the router matches on this text.- SKILL.md body under ~500 lines / ~5000 tokens. Split overflow into
references/files. - Optional frontmatter:
license,metadata(flat string map),compatibility,allowed-tools(space-delimited). - See
spec/agent-skills-spec.mdanddocs/best-practices.mdfor the full contract.
Distribution. package.json#files is the source of truth for what ships to npm — note that
node_modules, site/, tests/, and dev-only files are deliberately excluded. EHU consumers pull
from x3-design/skills via GitHub Packages (see auto-memory); the public stuffbucket/skills
package goes to npmjs.
site/ is a standalone Astro project (own package.json, own node_modules) — it's the
docs/marketing site and is not part of the npm bundle. Treat it as a sub-project. Its
src/content/skills/ and src/content/docs/ are gitignored and regenerated by
site/scripts/sync-skills.js from canonical plugins/stuffbucket/skills/*/SKILL.md and root docs/
— never hand-edit those files; edit the canonical source and run cd site && npm run sync.
Auto-managed README + llms.txt. README.md has <!-- BEGIN:SKILLS -->/<!-- BEGIN:SCRIPTS -->
marker pairs whose contents are regenerated by scripts/build-readme.js; llms.txt is generated
from llms.tmpl.txt + the skill index. CI runs check:readme and check:llms to fail on stale
output. After adding/renaming a skill or script, run npm run build:index && npm run build:readme && npm run build:llms. The skill-pr-autogen and skill-submission workflows also regenerate these
on PRs, but local checks are faster.
Validate runs markdownlint. quick_validate.py invokes markdownlint-cli2 on each skill's
.md files in addition to frontmatter/content checks, using the rules in .markdownlint-cli2.jsonc
(MD013 capped at 200 chars). A new skill that lints clean in isolation but fails MD040/MD013/MD032
will block npm run validate — fix the markdown, don't suppress.
Trigger phrase + priming. The catalog supports an explicit-routing memetic phrase — use stuffbucket — that signals downstream agents to call list_skills
before answering. The README's "Trigger your agent to use skills" section is the canonical home for this, including a copy-pastable priming snippet for
CLAUDE.md / AGENTS.md / .clinerules. When updating user-facing routing guidance, edit that README section rather than duplicating it here.
Tauri skill family (61 skills). A large hierarchical cluster covers Tauri v2:
tauri-architecture, tauri-bundling, tauri-commands, tauri-debug-test, tauri-events,
tauri-plugin-dev, tauri-plugins, tauri-security, tauri-setup, tauri-sidecar,
tauri-tray-menu, tauri-updater, tauri-windows. Each "parent" skill is a high-level orientation
that triggers on broad reasoning ("how does Tauri's IPC work?"); each child (<parent>-<topic>) is a
narrow deep-dive that triggers on specific implementation questions (e.g. tauri-windows-splashscreen,
tauri-bundling-macos-signing). When adding a new Tauri topic, follow this two-level pattern — keep
the parent ≤500 lines and push detail into siblings rather than expanding the parent. Some Tauri
skills also ship hand-written browser-context code under templates/ (e.g. the isolation hook); the
root eslint.config.mjs ignores **/templates/** for that reason.
npm run new -- my-skillscaffolds fromtemplate/SKILL.md.- Edit
SKILL.mdfrontmatter and body. Thedescriptionis what the router uses to decide relevance — write it as a trigger sentence. npm run validate:one -- plugins/stuffbucket/skills/my-skillthennpm run build:indexso the router picks it up.- Regenerate derived files:
npm run build:readme && npm run build:llms. The README's "Available Skills" / "Scripts" tables are auto-managed between<!-- BEGIN: -->/<!-- END: -->markers — do not hand-edit those sections (they'll be overwritten andcheck:readmewill fail). - If the skill should appear on the docs site,
cd site && npm run syncto refresh the synced content (the site reads from canonical SKILL.md).