Project Capsule
Universal agent plugin for Claude Code, Grok Build, Codex, and Cursor.
Say import the login module to a single markdown file. The agent finds that slice — not the repo — and writes one file. Paste it into a chat window. Drop it into a Claude Project, an OpenAI Project, a Grok Project, a Gemini Gem, or a NotebookLM notebook. Apply the YAML twin into a real directory on the other side.
Wraps two Spillwave tools:
- create_project_markdown — directory → one markdown file
- yaml_project — directory ⇄ YAML (generate, apply, patch)
Spillwave Solutions · MIT License
Why this exists
Whole-repo dumps fail in the places people actually work:
| Place | What goes wrong without a capsule | What you ship instead |
|---|---|---|
| Chat windows (Claude, ChatGPT, Grok, Gemini) | Token budget dies on node_modules, tests you did not ask for, and five unrelated packages | One 12–40 KB markdown of the login module |
| Claude Projects | Project knowledge wants a handful of sources, not a monorepo zip | login.md as a project file. Ask “how does session expiry work?” against the real code |
| OpenAI Projects | Same shape: project files are the working set | The capsule is the working set |
| Grok Projects | Long threads rot; a pinned source file does not | Pin auth.yaml or login.md on the project |
| Gemini Gems / NotebookLM | They index documents. Forty scattered .ts files are a worse corpus than one structured markdown with paths as headings | Upload login.md. Cite-backed answers over the slice you named |
| Moving between repos | Copy-paste misses siblings (session.ts next to login.ts) | YAML round-trip: pack here, yaml-project apply create there |
| A tutorial / book / article | Listings are trapped in a blog post | Harvest fences → YAML → a directory you can run |
Natural language is the point. You do not hand-write include regexes. You say what to ship. The agent resolves the smallest slice that matches.
Natural language → what gets shipped
The skill treats your words as a slice selector. “The login module”
is not “the repo.” It searches for login paths, takes the containing
directory, and pulls siblings (session.ts, password.ts, types.ts).
| You say | What ships | Format |
|---|---|---|
| import the login module to a single markdown file | src/auth/login.ts + siblings in that folder | login.md |
| pack src/auth as yaml | that directory, round-trip | auth.yaml |
| capture just the password hasher | basename match on password | markdown unless you named yaml |
| dump the webhook worker for the LLM | worker / webhook module | markdown (read-only context) |
| extract the listings from this tutorial | fenced blocks in the doc, any doc type | listings.yaml |
| generate a chapter example as yaml | a complete runnable companion (README, Taskfile, tests) | FullContentYAML |
| export this yaml into a directory of code | apply the capsule onto disk | a tree |
Book, article, tutorial, workshop notes — the source shape does not matter.
The agent then runs something like:
# markdown --include matches the **filename basename**, so slice by directory
create-project-markdown src/auth -o login.md
# yaml-project --include is a glob; --project-dir is the slice
yaml-project generate full --project-dir src/auth --outfile auth.yaml
If the list would be huge, it confirms before writing. It never dumps
node_modules, .git, dist, or venvs unless you insist.
Example output: markdown capsule
examples/login.md is what import the login module
to a single markdown file writes. Headings are paths. A chat model, a
Claude Project, or NotebookLM can cite src/auth/session.ts without you
attaching four files.
# login
Packed from src/auth (login module) · 4 files
## src/auth/types.ts
## src/auth/password.ts
## src/auth/session.ts
## src/auth/login.ts
Drop login.md into:
- A chat window — paste or attach. The model sees types, session TTL, and login together.
- Claude / OpenAI / Grok Project knowledge — add it as a project file. Every new thread in that project already has the module.
- NotebookLM or a Gemini Gem — upload as a source. Ask “when does a Harbor session expire?” and get a grounded answer (12 hours, from
TTL_MS).
Example output: YAML capsule (round-trip)
Markdown is for reading. YAML is for moving. Pack in repo A, apply in
repo B, or harvest a post into a tree. Full file: examples/auth.yaml.
metadata:
version: "1.0.0"
description: "Example: login module slice"
generator: "yaml-project"
author: "Project Capsule"
tags:
- "example"
- "auth"
content:
files:
src/auth/types.ts:
content: |
export type Session = {
token: string
userId: string
expiresAt: number
}
metadata:
extension: ".ts"
language: "typescript"
src/auth/session.ts:
content: |
export function createSession(userId: string): Session {
...
}
metadata:
extension: ".ts"
language: "typescript"
Apply it:
yaml-project apply create auth.yaml --output-dir ./harbor-auth
That is how a tutorial becomes a repo, and how a module leaves one project and lands in another without a brittle copy.
The three directions
repo slice ──pack──► login.md ──paste──► chat / Claude Project / NotebookLM
──pack──► auth.yaml ──apply──► another repo / machine
article.md ──harvest─► listings.yaml ──apply──► ./from-document/
chapter ──generate► example.yaml ──apply──► runnable companion (Poetry, Task, tests)
Harvest vs generate is in skills/project-capsule/from-document.md.
Harvest pulls fences that already exist. Generate writes the missing glue
(README, Taskfile, pyproject, tests that do not need an API key).
Quick install
skilz install SpillwaveSolutions/project-capsule --agent claude
Claude Code
mkdir -p .claude/skills/project-capsule
cp skills/project-capsule/* /path/to/project/.claude/skills/project-capsule/
Grok Build
mkdir -p /path/to/workspace/.grok/skills/project-capsule
cp plugins/grok-build/* /path/to/workspace/.grok/skills/project-capsule/
cp skills/project-capsule/commands.md skills/project-capsule/formats.md \
skills/project-capsule/install.md skills/project-capsule/from-document.md \
/path/to/workspace/.grok/skills/project-capsule/
Codex
cat plugins/codex/AGENTS.project-capsule.md >> /path/to/project/AGENTS.md
Cursor
mkdir -p /path/to/project/.cursor/rules /path/to/project/.cursor/skills/project-capsule
cp plugins/cursor/project-capsule.mdc /path/to/project/.cursor/rules/
cp -R skills/project-capsule/* /path/to/project/.cursor/skills/project-capsule/
create_project_markdown is a script (no setup.py). yaml_project installs
as yaml-project / create-project-yaml. See skills/project-capsule/install.md.
Copy templates/pmarkdownc.config.yml to
.pmarkdownc/config.yml before packing a TypeScript UI tree — stock
create_project_markdown skips .tsx, .jsx, .md, and .json.
Layout
skills/project-capsule/ shared skill + commands / formats / install / from-document
plugins/claude-code/ Claude pack
plugins/grok-build/ Grok Build pack
plugins/codex/ AGENTS merge
plugins/cursor/ Cursor rule
templates/ .pmarkdownc/config.yml with TS/React extensions
engine/ TypeScript reference (pack / unpack / extract / intent)
examples/ sample login.md and auth.yaml capsules