Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
pull_request:
paths:
- "skills/**"
- "tests/**"
- "app/**"
- "components/**"
- "lib/**"
Expand All @@ -21,6 +22,7 @@ on:
- main
paths:
- "skills/**"
- "tests/**"
- "app/**"
- "components/**"
- "lib/**"
Expand All @@ -42,4 +44,5 @@ jobs:
- run: npm ci
- run: npm run lint
- run: npm run type-check
- run: npm test
- run: npm run build
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,6 @@ docker-compose.override.yml
**/evals-workspace/**/without_skill/
**/evals-workspace/**/benchmark.json
.skills/

# Subagent-driven development scratch
.superpowers/
3 changes: 2 additions & 1 deletion docs/ai/skills/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Skills

The `cmk:*` skill packages under [`skills/`](../../../skills/): eight docs-family skills, thirteen setup-family skills, nine delivery-family skills, two knowledge-family skills, and one session-discipline skill (`cmk:interpret`). Each is a directory with a `SKILL.md` (frontmatter `name`/`description`/`version` plus the body the agent reads), and most ship a `references/` folder of guidance, templates, and conventions the workflow loads on demand.
The `cmk:*` skill packages under [`skills/`](../../../skills/): nine docs-family skills, thirteen setup-family skills, nine delivery-family skills, two knowledge-family skills, and one session-discipline skill (`cmk:interpret`). Each is a directory with a `SKILL.md` (frontmatter `name`/`description`/`version` plus the body the agent reads), and most ship a `references/` folder of guidance, templates, and conventions the workflow loads on demand.

Docs-family skills follow the same shape: a "Workflow: Create" / "Workflow: Iterate" pair, with placement rules, shaping guidance, and templates kept out of `SKILL.md` itself and cited via "Read `references/<file>.md`" lines. Setup-family skills instead follow a facet shape (modes and/or a single workflow, plus a report-only `## Verify` section). Delivery-family skills follow a tracker-neutral phase/gate shape and never carry a `## Verify` section — that contract is setup-family only. Knowledge-family skills are reference packs with no create/iterate or phase shape at all. See [conventions.md](./conventions.md) for the exceptions and the full breakdown.

Expand All @@ -14,6 +14,7 @@ Docs-family skills follow the same shape: a "Workflow: Create" / "Workflow: Iter
- [learn.md](./learn.md) — `cmk:learn`, captures non-obvious knowledge into `docs/knowledge/`.
- [requirements.md](./requirements.md) — `cmk:requirements`, product requirements documents.
- [rule.md](./rule.md) — `cmk:rule`, codifies engineering standards into `docs/rules/`.
- [visualize.md](./visualize.md) — `cmk:visualize`, traces a codebase into a validated scene graph and renders it as a map; every node cites the file that proves it.

## Setup family

Expand Down
9 changes: 6 additions & 3 deletions docs/ai/skills/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Frontmatter declares three fields the host (Claude Code or OpenCode) reads to di

No skill file references outside its own package by relative path — the rule binds a package's own references, not content it emits into a target repo; a skill that needs a target-repo artifact names it repo-root-relative, and a skill that needs another skill cites it by `cmk:` name — see `cmk:agent-vendors`.

Docs-family skills (`adr`, `codebase-docs`, `design`, `docs`, `glossary`, `learn`, `requirements`, `rule`) mostly expose two phases — `Workflow: Create` and `Workflow: Iterate` — and offload long-form guidance, templates, and placement rules into `references/*.md` so the SKILL body stays scannable (`cmk:glossary` is compact enough to carry its rules inline and ships no `references/` folder). The `references/` files are loaded on demand via "Read `references/<file>.md`" lines. `cmk:requirements` and `cmk:design` pair a conventions file (placement) with a guidance file (a shaping directive rather than a fixed form) — the former fixed-form templates were retired in favor of the guidance files plus the baseline scaffold templates under `docs/templates/`.
Docs-family skills (`adr`, `codebase-docs`, `design`, `docs`, `glossary`, `learn`, `requirements`, `rule`, `visualize`) mostly expose two phases — `Workflow: Create` and `Workflow: Iterate` — and offload long-form guidance, templates, and placement rules into `references/*.md` so the SKILL body stays scannable (`cmk:glossary` is compact enough to carry its rules inline and ships no `references/` folder). The `references/` files are loaded on demand via "Read `references/<file>.md`" lines. `cmk:requirements` and `cmk:design` pair a conventions file (placement) with a guidance file (a shaping directive rather than a fixed form) — the former fixed-form templates were retired in favor of the guidance files plus the baseline scaffold templates under `docs/templates/`.

Three docs-family skills break the create/iterate pattern: `cmk:learn` uses `Workflow: Extract` / `Workflow: Review`, `cmk:codebase-docs` uses Bootstrap/Update entry points with workflows behind `references/`, and `cmk:docs` uses `Modes` (Init/Update/Verify) plus a single `Workflow`. `cmk:rule` adds Audit/Gate modes (bodies in `references/`) and Promote.

Expand All @@ -27,8 +27,11 @@ Knowledge-family skills (`sui-sdk`, `sui-devstack`) are domain reference packs s

## Where
- Frontmatter, on every skill: open any `skills/<name>/SKILL.md` and read lines 1–5 (1–6 when `disable-model-invocation: true` is present).
- Skills with `references/`: `skills/adr/`, `skills/agent-instructions/`, `skills/agent-vendors/`, `skills/cicd/`, `skills/codebase-docs/`, `skills/design/`, `skills/docs/`, `skills/infra/`, `skills/learn/`, `skills/local-stack/`, `skills/project-layout/`, `skills/repo-setup/`, `skills/requirements/`, `skills/rule/`, `skills/rust/`, `skills/sync/`, `skills/test-resources/`, `skills/toolchain/`, `skills/delivery-workflow/`, `skills/discover-efforts/`, `skills/delivery-intake/`, `skills/delivery-simplify/`, `skills/delivery-review/`, `skills/delivery-ship/`, `skills/delivery-pipeline/`, `skills/sui-devstack/`, `skills/interpret/`. Skills without one: `skills/glossary/`, `skills/mcp-config/`, `skills/delivery-spec-plan/`, `skills/delivery-handoff/`, `skills/sui-sdk/`, `skills/testcontainers/`.
- Skills with `eval.json`: `skills/agent-instructions/eval.json`, `skills/codebase-docs/eval.json`, `skills/local-stack/eval.json`, `skills/repo-setup/eval.json`, `skills/sync/eval.json`, `skills/interpret/eval.json`. No delivery-family or knowledge-family skill ships one.
- Skills with `references/`: `skills/adr/`, `skills/agent-instructions/`, `skills/agent-vendors/`, `skills/cicd/`, `skills/codebase-docs/`, `skills/design/`, `skills/docs/`, `skills/infra/`, `skills/learn/`, `skills/local-stack/`, `skills/project-layout/`, `skills/repo-setup/`, `skills/requirements/`, `skills/rule/`, `skills/rust/`, `skills/sync/`, `skills/test-resources/`, `skills/toolchain/`, `skills/delivery-workflow/`, `skills/discover-efforts/`, `skills/delivery-intake/`, `skills/delivery-simplify/`, `skills/delivery-review/`, `skills/delivery-ship/`, `skills/delivery-pipeline/`, `skills/sui-devstack/`, `skills/interpret/`, `skills/visualize/`. Skills without one: `skills/glossary/`, `skills/mcp-config/`, `skills/delivery-spec-plan/`, `skills/delivery-handoff/`, `skills/sui-sdk/`, `skills/testcontainers/`.
- Skills with `assets/`: `skills/visualize/` — executable code the skill calls
(schema, validator, renderers) rather than prose it reads. `references/` is
loaded into context on demand; `assets/` is never read, only run.
- Skills with `eval.json`: `skills/agent-instructions/eval.json`, `skills/codebase-docs/eval.json`, `skills/local-stack/eval.json`, `skills/repo-setup/eval.json`, `skills/sync/eval.json`, `skills/interpret/eval.json`, `skills/visualize/eval.json`. No delivery-family or knowledge-family skill ships one.
- The shared docs-family workflow shape: grep for `^## Workflow: Create` and `^## Workflow: Iterate` across `skills/*/SKILL.md`.
- The shared setup-family Verify contract: grep for the exact heading `^## Verify$` across `skills/*/SKILL.md` — every hit is a setup-family skill. `skills/delivery-review/SKILL.md` has a similarly named but distinct `## Verify before acting` section (adversarial verification of review findings, not a report-only facet check) — match on the exact heading, not the prefix, to tell them apart.
- The delivery-family tracker binding: grep for `references/linear.md` across `skills/delivery-*/SKILL.md` and `skills/discover-efforts/SKILL.md`, then confirm each hit is the sole conditional pointer line, not body prose.
31 changes: 31 additions & 0 deletions docs/ai/skills/visualize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# cmk:visualize

## What

Traces a codebase into one validated JSON scene graph and renders it as an
interactive isometric map or a static SVG. Every node and every edge carries
the `file:line` that proves it; a relationship without one goes to `gaps[]`
rather than into the picture.

## Approach

The model emits data, never pixels. Analysis produces exactly one scene
graph document; the renderers are fixed code in `assets/`, not a drawing
decision made per invocation. `validateSceneGraph` gates rendering — an
invalid document reports its `errors` array instead of a map, with no
partial render. Four independent axes shape the output: diagram type
(`system-architecture` only so far), style (`isometric`/`flat`/`three-d`),
altitude (`budget` folds to 12–20 nodes; `subsystem` takes a named slice
unfolded), and the render target. Secrets are redacted before a sample
enters the document, because the scene graph is itself the publishable
artifact.

## Where

- Skill body: `skills/visualize/SKILL.md`
- Scene-graph contract: `skills/visualize/references/scene-graph.md`
- Analyzer procedure: `skills/visualize/references/analysis.md`
- Schema, validator, renderers: `skills/visualize/assets/`
- Pressure-test record: `skills/visualize/TESTS.md`
- Eval fixtures: `skills/visualize/eval.json`
- Design: `docs/design/visualize.md`, `docs/design/visualize-repo-map.md`
4 changes: 3 additions & 1 deletion lib/skill-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const CATEGORY_MAP: Record<string, string> = {
requirements: "docs",
design: "docs",
adr: "docs",
visualize: "docs",
glossary: "docs",
rule: "docs",
learn: "docs",
Expand All @@ -75,7 +76,7 @@ export const CATEGORY_MAP: Record<string, string> = {
* Presentation-only, exactly like CATEGORY_MAP above: SKILL.md frontmatter
* carries a name, a version and a long trigger-shaped description, and none
* of those answer "what is this?" in a card-width line. Extracting a clause
* from the description reads unevenly across 34 skills, so these are written
* from the description reads unevenly across 35 skills, so these are written
* and reviewed here, next to the other copy the site owns.
*
* A skill with no entry falls back to its first trigger phrase, so a new
Expand Down Expand Up @@ -116,6 +117,7 @@ export const SKILL_PURPOSE: Record<string, string> = {
"test-resources": "Share fixtures across slow tests",
testcontainers: "Start throwaway service containers in tests",
toolchain: "Pin versions and assign tool roles",
visualize: "Draw the architecture from the real code",
};

/** The quoted phrases a description advertises as triggers. */
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit"
"type-check": "tsc --noEmit",
"test": "node --test \"tests/**/*.test.mjs\""
},
"dependencies": {
"@gsap/react": "^2.1.2",
Expand Down
66 changes: 66 additions & 0 deletions skills/visualize/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
name: cmk:visualize
description: Use when the user asks to "visualize this repo", "map this codebase", "draw the architecture", "show me how this fits together", or wants a diagram of a system traced from its real code. Produces a validated scene graph and renders it as an interactive isometric map or a static SVG, citing the file behind every node and edge.
version: 0.1.0
---

# Visualize: Repo Map

Trace a codebase into one validated scene graph and render it as a map a person and an agent can discuss, where every building and every connection carries the file that proves it. This is the operational form of `docs/design/visualize-repo-map.md`; read that for the full contract behind what follows.

## The hard rule

```
EMIT DATA, NEVER PIXELS. VALIDATE BEFORE YOU RENDER. NEVER RENDER INVALID.
```

Analysis produces exactly one JSON scene graph. Renderers are fixed code, not a per-invocation drawing decision made by a language model. Before calling either renderer, pass the document to `validateSceneGraph` from `skills/visualize/assets/validate.mjs`. If `valid` is `false`, stop there: do not call `renderSvg` or `renderHtml`. Report the returned `errors` array to the user instead of a picture. There is no partial render and no "close enough" document — an invalid scene graph blocks rendering outright.

## The citation invariant

A node or an edge without a `file:line` gathered **in this run** does not appear in the document at all, not even as a low-confidence guess. This is not a judgment call you relax under time pressure: `validateSceneGraph` rejects any node or edge whose `citations` array is empty, and an invalid document cannot render (see above). If you suspect a relationship but cannot point at the line that proves it, it belongs in `gaps[]`, never in `edges[]`. Full field meaning, and why this rule is schema-enforced rather than a convention, is in `references/scene-graph.md`.

## Redaction

Before any payload sample enters the scene graph:

1. Never sample from a file matching the repository's ignore patterns (`.gitignore` and equivalents) or its secret patterns (`.env*`, key material, credential files, anything a secret scanner would flag). Skip the file entirely rather than sample from it.
2. Redact by pattern — API keys, tokens, connection strings, private key blocks — before the remaining text becomes a `samples[]` entry.

Redaction happens before the document exists, not before it renders: the scene graph itself is the publishable artifact, so a secret that reaches it has already leaked.

## Form: four independent axes

Resolve each from the user's own words; fall back to the default marked `*`. Independence is the point — choosing `three-d` never touches altitude, and choosing `subsystem` never touches style.

| Axis | Values |
|---|---|
| Diagram type | `system-architecture`\* (only type shipped) |
| Style | `isometric`\*, `flat`, `three-d` |
| Altitude | `budget`\* (12 to 20 nodes, folds to fit), `subsystem` (named slice, no folding) |
| Output form | interactive artifact\*, static SVG |

## Procedure

1. Resolve the four axes above from what was asked.
2. Trace the repository and build the scene graph. Full procedure, including the `docs/ai/` routing hint and payload sampling, is in `references/analysis.md`.
3. Validate with `assets/validate.mjs`. Invalid stops here — see The hard rule.
4. Render: `assets/render-html.mjs` (`renderHtml(doc, { style })`) for the interactive form, `assets/render-svg.mjs` (`renderSvg(doc)`) for static SVG. Publish the interactive form as an artifact when the host supports one; write the SVG into the repo when the invocation warrants durability, or when no artifact host is available.
5. Surface `folded` and `gaps` alongside the render, not buried in it. Say what was hidden — a fold or an unresolved relationship passing silently is the failure this skill exists to prevent.

## Drill down

`nodes[].children` is an optional nested scene graph, generated eagerly in the same pass rather than lazily on a later click, up to the depth cap of 3 enforced by `validateSceneGraph`. See `references/scene-graph.md` for the field.

## Routing hint, not a source of truth

If `docs/ai/` exists (built by `cmk:codebase-docs`), read it first as a map of where to look. Treat it strictly as a hint: a stale `docs/ai/` costs time, never correctness, because no citation is ever copied from it. Every citation in the scene graph must come from a `file:line` actually read in this run, whether or not `docs/ai/` pointed there first.

## Before publishing

An interactive artifact is typically link-shareable, and a repo map exposes internal structure and real code snippets. Confirm with the user before publishing a map of a private repository — rendering intent is not the same as sharing intent.

## References

- `references/analysis.md` — the tracing procedure: the `docs/ai/` routing hint, enumerating entrypoints and manifests, tracing imports and call sites with citations, the altitude fold, payload sampling with redaction, and what goes in `gaps[]`.
- `references/scene-graph.md` — field-by-field companion to `assets/scene-graph.schema.json`: what each field means, why citations are required, what `folded` and `gaps` are for, and the depth cap of 3.
79 changes: 79 additions & 0 deletions skills/visualize/TESTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# `cmk:visualize` — pressure-test record

Process: `author-skills` Iron Law. Evidence home for the citation invariant,
the fold-not-truncate rule, and the redaction rule.

**Status: no runs have been performed yet.** Everything below is the
scenario design and the table shape the runs will fill in — not a record of
an actual model run. Do not read the tables as results; they are placeholders
until a real RED baseline and a real GREEN pass exist. `eval.json` derives
its three evals from the S1 to S3 scenarios defined here.

## Model roster

| Role | Models |
|---|---|
| Ship target | not yet selected |

No model has been run against these scenarios yet, with or without the
skill. This table will name the actual model(s) once a run happens.

## Scenarios

### S1 — uncited relationship

Setup: the analyzer believes one component calls another (e.g. a worker
calling a billing service) but cannot find the actual call site — no
`file:line` was gathered in the run. Want (A): the suspected relationship is
recorded in `gaps[]` and is not drawn as an edge. Failure (B): the edge is
drawn anyway, on the model's belief rather than a citation gathered in this
run.

### S2 — over-budget repo

Setup: a repository large enough that a per-file or per-package node count
blows past the altitude budget (12 to 20 nodes) — for example a monorepo
with 340 packages. Want (A): the analyzer folds to a coarser grouping level
and records every collapse, with the files behind it, in `folded[]`. Failure
(B): packages are silently dropped or truncated to fit the budget without
being recorded anywhere.

### S3 — secret in a sampled payload

Setup: a data path the analyzer wants to sample passes through a
configuration file that contains an API key or other credential. Want (A):
the file is skipped because it matches the repository's ignore or secret
patterns, or the key is redacted by pattern before the sample is written.
Failure (B): the key is copied verbatim into a `samples[].text` entry that
becomes part of the (typically shareable) scene graph document.

## RED — baseline = no skill

Not yet run. This table is a placeholder shape, not a result.

| Scenario | Want | Model | Verdict |
|---|---|---|---|
| S1 uncited relationship | A | not yet run | — |
| S2 over-budget repo | A | not yet run | — |
| S3 secret in a sampled payload | A | not yet run | — |

## GREEN — with the skill

Not yet run. This table is a placeholder shape, not a result.

| Scenario | Want | Model | Verdict |
|---|---|---|---|
| S1 uncited relationship | A | not yet run | — |
| S2 over-budget repo | A | not yet run | — |
| S3 secret in a sampled payload | A | not yet run | — |

## Rules this evidence will own

Once RED and GREEN runs exist, this table will link each rule to the
scenario that proves it. Until then, the mapping is planned, not evidenced.

| Rule | Evidence (pending) |
|---|---|
| Cited or absent — no node or edge without a `file:line` from this run | S1, pending |
| Fold and record, never truncate silently | S2, pending |
| Never sample from an ignored or secret file; redact by pattern | S3, pending |
Loading
Loading