Collapse

Open source, public repo. Clone, pnpm dev, and collapse a lesson into a skill. Part of the akaOSS studio.
Open source · Developer tool · Claude Code
Collapse
A Claude Code skill-building framework — a pattern → SKILL.md compiler. github.com/akaieuan/collapse
What this is
Collapse exists because Claude’s default knowledge is stack-agnostic, but most developers live inside one stack at a time. The same idea — reactive state, lifecycle, error boundaries, circuit composition — lands differently in React, Vue, Nuxt, and Qiskit, and a “generic” answer costs round-trips. Collapsed skills carry your cross-stack vocabulary so Claude reaches for the right idiom on the first try, with trigger phrases derived from your annotations. The repo ships with 21 cross-stack reference lessons and a sample notebook that exercises the import flow end to end.
How it works
A three-layer pipeline — each boundary is a TypeScript interface, and no layer reaches into another. Type-safe by construction (ingestors produce a typed input the engine consumes without knowing the source format), stateless (the skills directory is the state, read on every request), and atomic (writes go to .tmp then rename(), so an interrupted write never leaves a partial SKILL.md).
ingestor ───▶ template engine ───▶ persistence
(on-ramps) lib/skill-template /api/skills
MDX · .ipynb generateSkillDraft() ~/.claude/skills/{name}/SKILL.md
MyST · custom renderSkillFile() (v0.2: MCP server scaffold)Ingestors
- MDX lessons. Annotated code fences with
{lines#id}metadata linked to sibling<Note>blocks, scoped per-stack via<LangTab>, frontmatter-validated. - Jupyter + MyST import. Paste
.ipynbJSON, upload a file, or drop MyST.md; it infers kernel language and auto-prefills annotations from MyST admonitions (note / warning / tip). - Pluggable model. Any source format ships in ~4 files following the
lib/notebook/template — there’s a worked example in the docs.
Engine & persistence
- Template engine. One annotation → one skill, or a whole lesson → one skill; auto-derives up to five Claude trigger phrases from your annotation tips and titles.
- Cross-language equivalents. Pulled automatically from sibling
<LangTab>blocks, so the generated SKILL.md carries the translation inline. - Quality linter. clean / info / warn verdicts on description length, trigger-phrase ambiguity, kebab-case naming, and body size — shown as colored dots in the skills viewer.
- Local atomic writes. Zod-validated POST,
.tmp+ rename, path-traversal rejected, 409 on collision. No telemetry, no cloud, no database — the filesystem is the storage layer.
Why collapse across stacks
The leverage isn’t “I have skills” — it’s skills that move with you when you switch stacks. Writing the Vue version after the React version forces you to see exactly where they diverge, and the lesson captures it. The generated SKILL.md carries that translation, so asking “how do I do reactive state in Nuxt” in a Vue project answers correctly first try. The library compounds — skills cite each other and inherit trigger phrases — and a SKILL.md is just a kebab-case markdown file, so polyglot teams ship them via dotfiles or a gist. Switching cost approaches zero: you’re learning where stacks diverge, not relearning from scratch.
Status & roadmap
Active development. Shipped: the MDX ingestor (<LangTab> / <Note> model, 21 reference lessons), the notebook ingestor (.ipynb + MyST with admonition prefill), the template engine with cross-language equivalents, the atomic persistence layer with 409 handling, the three-tier quality linter, the lesson + import + skills-directory UIs, the MCP server scaffold output (v0.2) as a second output target sharing the template engine, and a green Vitest suite (99 tests). On the roadmap: multi-cell notebook composition and a MyST chapter URL fetcher.
TypeScript 5 · Next.js 16 (App Router, RSC, Turbopack) · Tailwind v4 · shadcn/ui · Shiki · Zod 4 · Vitest · Node 20+ · local filesystem
More views
Why it's different
Most skill tooling leaves you with a pile of files. Collapse makes the skills directory a vocabulary: one pattern lives across React / Vue / Nuxt / Qiskit tabs, the generated SKILL.md carries the translation inline, and switching stacks becomes learning where they diverge — not relearning from scratch.




