| name | intent-layer |
| description | Build an "Intent Layer" for a codebase — walk the repo, chunk at semantic boundaries, and produce hierarchical, token-efficient context bundles ("Intent Nodes") written into CLAUDE.md / AGENTS.md files so any AI agent gets deep codebase understanding without parsing raw source. Use on large/multi-service codebases (>~1M tokens / 50k–100k LOC) or when agents keep re-reading the same files to rebuild context. Reimplements the method behind Intent Systems' Intent Layer (intent-systems.com/intent-layer) — it is not the commercial product. |
| argument-hint | [path (default: cwd)] [--update[=<since>]] [--dry-run] [--yes] |
/intent-layer
Generate a hierarchical context layer over a codebase. Each directory of significance gets an Intent Node — a dense, agent-consumable summary embedded in that directory's CLAUDE.md (and AGENTS.md if the repo uses one). Agents then read the root node for architecture, drill into subtree nodes only when a task touches that area, and stop re-deriving the same understanding from raw code.
This is a context-engineering task: the only deliverable is markdown context inside owned regions of CLAUDE.md/AGENTS.md. No source code changes.
The four principles (properties the finished layer must satisfy — not a per-node checklist)
- Fractal compression — Leaf nodes summarize code. Parent nodes summarize their children's nodes, not the raw code beneath them. Compression compounds upward, so the root stays small no matter how big the repo is.
- Hierarchical layout — The layer reads top-down: an agent gets broad architecture at the root, then specific detail where it's working. (Note: you author leaf-first — see Step 4 — but lay the content out so it's consumed root-first.)
- LCA deduplication — A shared fact lives once, at the shallowest node (lowest common ancestor) that covers every path it applies to. No duplication, no drift.
- Progressive disclosure — Each node states only what an agent needs to route (which child to open next) plus the non-obvious invariants. Detail lives deeper, fetched only when a task requires it.
Owned regions & the sentinel (read before any write)
Every generated node is wrapped in a sentinel-delimited region so the skill can always tell its own output from hand-written prose:
<!-- INTENT-LAYER:BEGIN (generated by /intent-layer — edit outside this block; this block is regenerated) -->
... generated node ...
<!-- INTENT-LAYER:END -->
Rules, applied to both CLAUDE.md and AGENTS.md:
- File has the sentinel block → replace only the content between
BEGIN/END; preserve everything outside it verbatim. Idempotent.
- File exists but has no sentinel (hand-written) → never silently touch it. Show a diff of the block you'd prepend and require explicit confirmation. Default placement is the top of the file, above the hand-written content.
- File does not exist → create it containing just the sentinel block.
Procedure
- Parse args & scope. From
$ARGUMENTS: target path (default cwd), --update[=<since>], --dry-run, --yes. Confirm the repo earns a layer — the method pays off above ~1M tokens / 50k–100k LOC (tokei or cloc; or LOC proxy ≈ git ls-files | xargs wc -l, tokens ≈ chars/4) or on multi-service architectures. For smaller repos, say so and offer a single root node instead of a full tree.
- Map the structure (cartography). Enumerate tracked files only —
git ls-files (respects .gitignore; skips vendored deps/build output/generated code for free). Identify semantic boundaries: a directory whose files share a deploy unit, build target, or import root — services, packages, apps, bounded modules — not merely top-level folders. Note the build system, entry points, and how components talk (HTTP, queues, shared DB, imports).
- Pick node sites. Choose directories that deserve a node: the repo root (always); each service/package root; any module dense or subtle enough that an agent would otherwise read several files to understand it. Don't node every folder — most leaves are covered by their parent. One exception: if a shared fact's LCA directory isn't already a node site, promote it to one (or, if that's awkward, host the fact at the nearest enclosing node) so every shared fact has a single canonical home.
- Author leaf-first. Summarize the deepest chosen nodes from their code: responsibility, key files/symbols, public surface, invariants, edge cases, gotchas. Be specific (
file_path:symbol), dense, token-frugal. Carry structure and behavior, not edit-sensitive numbers. Line counts ("the 514-line module"), exact file/function/test tallies, and other precise figures are the first facts to drift — often invalidated by the very next commit (even one made minutes later) — and --update only re-reads a leaf when its code changes, so a stale number elsewhere can sit wrong indefinitely. Prefer durable descriptors ("the large single-file generator", "covers all three generators") over counts; cite a number only when it's the actual point (a hard limit, a protocol version) and the node explains why it matters.
- Roll up. For each parent, summarize its children's nodes (fractal compression) — what the subtree is, how children relate, cross-cutting patterns. Apply LCA dedup as you go: when two siblings share a fact, lift it to their common-ancestor node (per Step 3's promotion rule) and delete it from the children.
- Capture what code can't say. Code shows what, rarely why. Record invariants, production lessons, deliberate trade-offs, "don't do X because Y" landmines. If the user is present, ask 2–4 targeted questions (the "expert interview"). Mark anything inferred-but-unverified as such.
- Preview, then write. Assemble each node into its sentinel block. Always present the full list of target paths plus per-file diffs first. Then:
--dry-run: print the planned node tree and diffs, write nothing, stop here (takes precedence over everything below — even hand-written files are only previewed).
- Hand-written files (no sentinel): require per-file confirmation regardless of
--yes.
- Otherwise: with
--yes proceed; without it, ask once to write the whole batch. Honor the owned-region rules above — merge, never clobber.
- Report. List nodes written, the tree shape, and the root node's token footprint (chars/4). Show one sample task an agent can now answer from the layer alone.
Node template (this structure is ours, not from the vendor)
<!-- INTENT-LAYER:BEGIN (generated by /intent-layer — edit outside this block; this block is regenerated) -->
# <component name> — Intent Node
**Role:** one line — what this subtree is and why it exists.
**Connects to:** parents/siblings/services it talks to, and how (HTTP/queue/import/DB).
## Map
- `child-or-file/` — one-line role. → see its CLAUDE.md ← link down, don't inline
- `key_file.py:EntryPoint` — what to start from.
## Invariants & gotchas
- Non-obvious rules, ordering constraints, "must X before Y", known footguns.
- Production lessons / deliberate trade-offs (the why).
## When working here
- Where common changes go; what tends to break; how to verify.
<!-- INTENT-LAYER:END -->
(Leaf nodes lean on Map/Invariants; parent nodes lean on Role/Connects to and route down. Keep the root node small — architecture and entry points only.)
--update mode (VCS-hook style refresh)
Refresh an existing layer instead of regenerating it. Baseline <since> defaults to HEAD~1; if the repo records a last-run marker, use that instead. Steps:
git diff --name-only <since> HEAD → changed files.
- Re-author only the leaf nodes whose code changed (Step 4).
- Propagate upward leaf-first: re-roll each affected parent. Stop propagating along a branch as soon as that parent's rolled-up summary is unchanged (an unchanged rollup means nothing above it on that branch needs updating). Untouched subtrees are never read.
This is the form to wire into a post-commit / pre-push hook. Because every write is sentinel-scoped, hook runs are idempotent and never disturb hand-written prose.
Notes
- Delivery format is the point. Embedding nodes in
CLAUDE.md means Claude Code auto-loads them; AGENTS.md is the emerging cross-tool standard (read by Codex and others). Don't assume every tool reads both — write AGENTS.md only when the repo already uses one, and if you write both, make one a pointer to the other to avoid drift.
- Token-frugal or it's pointless. If the layer costs an agent more tokens than reading the code, it failed. Compress hard; link instead of inline.
- Measure if asked. To prove value, run a representative task before and after the layer exists and compare tokens used, wall-clock, success rate, and output quality.
- Provenance. Reimplements the method behind Intent Systems' Intent Layer (https://intent-systems.com/intent-layer): fractal compression · hierarchical summarization · LCA dedup · progressive disclosure, delivered as AGENTS.md/CLAUDE.md, updated leaf-first via VCS hooks. This skill is an independent reconstruction of that method, not the commercial product, and makes no claim to its published results.