repo-dependency-graph · git:20260916.f5399c9 · 2026-09-16 · sha256 cb35c2669e5a32eb

repo-dependency-graph git:20260916.f5399c9A

Immutable. This exact content is served forever at /api/v1/blob/cb35c2669e5a32eb.

---
name: repo-dependency-graph
description: >-
  Reconstruct a DARE skill repo's true use-dependency relations and render them
  as a self-contained, offline, Obsidian-style interactive HTML graph (pyvis /
  vis-network). Use this whenever the user wants to graph / map / visualize the
  skill dependencies of a repo or package, "画依赖图 / graph 化这个 repo / 把 skill
  连边画出来 / 用 pyvis 出个图 / skill 关系图", or to audit how campaign→strategy→
  tactic→sop skills connect. Trigger even if the user just says "给这个 package
  做个图" without naming pyvis or HTML. Goes straight to HTML — never write an
  intermediate mermaid markdown first.
metadata:
  internal: true
---

# repo-dependency-graph

Turn a skill repo (or a whole campaign package) into a clean, interactive
**use-dependency graph**: read the original `SKILL.md` + design docs, reconstruct
the real `use` edges, and render one offline HTML per repo that looks and behaves
like an Obsidian graph (force-directed, draggable, neighbourhood-highlight, HTML
hover tooltips).

This skill exists because a repo's frontmatter alone gives a broken graph — real
routing lives in prose, in `references/*-index.md`, and in same-layer escalation
handoffs. Reconstructing the true graph takes a careful read of each repo, then a
deterministic render. This skill captures both halves so the result is consistent
every time and reusable across all repos.

## The model (read `references/layer-rules.md` for the full rules)

- **5 vertex types**: `campaign` (red) · `strategy` (cyan) · `tactic` (yellow) ·
  `sop` (purple) · `references` (gray dashed, = a `.py`/`.md` helper file).
- **One edge type `use`**: `A -->|use| B` = A invokes/orchestrates B (caller → callee).
- **Layer comes from frontmatter `type:` / `layer:`** (NOT `execution:`). Infer
  from body+README only if absent, and record the reasoning.
- **Escalation = same-layer `sop → sop` use edge** (locked decision): "escalate to
  X" / "for deeper analysis use X" / "import X" are all drawn as `use` edges. Do
  NOT promote a skill's layer just to make the edge look legal — same-layer
  handoff is a first-class edge here.

## Workflow

### 1. Read the repo and reconstruct the dependencies

For each `skills/*/SKILL.md`: read the **full body + frontmatter** (layer field,
and any prose that invokes/escalates to another skill or points at a
`references/` helper). Also read `README.md`, `docs/`, `assets/`, and any
`*-index.md` — real routing often lives there, not in frontmatter.

Only draw an edge the design files actually justify. If two skills are
independent siblings, leave them unconnected — do not invent edges. A pointer to
an external MCP tool (`alphaxiv`, `brave`) is a tool, not a vertex. A broken /
never-used file pointer does not justify a `references` vertex — verify the live
reference.

**For a large package (50+ skills), dispatch one subagent per package** to read
its `skills/` + `docs/` and return the reconstructed nodes/edges — they are
independent and parallelize cleanly. Give each subagent `references/layer-rules.md`
and `references/graph-schema.md` so its output is consistent and directly usable.

### 2. Write the graph JSON

Emit one JSON file per repo following `references/graph-schema.md`:

```json
{
  "name": "<repo-name>",
  "nodes": [ {"id": "<full-skill-name>", "layer": "sop", "desc": "<bilingual hover>"} ],
  "edges": [ {"from": "...", "to": "...", "tip": "<trigger scenario hover>"} ]
}
```

- **Node IDs are full skill names — never abbreviate.**
- `desc` (中英混合) = what the SKILL does + its depth / HARD-GATE. HTML allowed.
- `tip` = the condition under which the caller hands off to the callee; quote the
  source skill's own escalation language where possible. HTML allowed.
- Both `desc` and `tip` are optional — omit and the tooltip falls back to
  `name [layer]` / `use`.

### 3. Render the HTML

```
python scripts/render_graph.py --data <repo>.json --out <repo>.html
# or batch a whole directory of graph JSONs:
python scripts/render_graph.py --data-dir ./data --out-dir ./graphs
```

The script prints a `[warn]` for any edge that breaks layer legality
(`sop → sop` escalation never warns). It produces a fully offline HTML
(vis-network inlined, external CDN stripped) with:

- 5 vertex-type colors, dashed border for `references`.
- Force-directed, draggable, scroll-zoom, click-to-highlight neighbourhood.
- A self-managed `#dare-tip` hover layer that renders the HTML in `desc`/`tip`
  (vis's native tooltip shows a string title as plain text, leaking `<b>` tags —
  the script bypasses it with an event-driven layer; this is why HTML renders).
- No navigation buttons, no bootstrap card frame — just the graph on a dark canvas.

### 4. Verify

Open the HTML in a browser and confirm: nodes colored by layer, edges arrow
caller→callee, hovering a node/edge shows the bilingual tooltip with HTML
rendered (bold + `<hr>` divider, not raw tags). Requires `pyvis` (>=0.3.2).

## Key constraints

- **HTML directly, no intermediate mermaid `.md`.** The HTML is the deliverable.
- **Full skill names** as node IDs and labels — no abbreviations.
- Privacy: the HTML embeds only node names + layer + the desc/tip you write. Never
  emit filesystem paths, log paths, or session IDs into the graph data or output.
- Read-only on the source repo — reconstructing a graph never edits skills.

See `examples/literature-engine.json` for a complete, working graph JSON.