t1k:cocos:base:script-graph
| Field | Value |
|---|---|
| Module | base |
| Version | 3.3.2 |
| Effort | medium |
| Tools | — |
Keywords: class-diagram, code-index, dependency-cruiser, doc-comments, doc-xml, docs, documentation, prefab, scene, script-graph, tsdoc
How to invoke
Section titled “How to invoke”/t1k:cocos:base:script-grapht1k-cocos-base-script-graph
Section titled “t1k-cocos-base-script-graph”Cocos Creator 3.x diagram adapter and TypeScript documentation generator for the T1K toolchain.
Scope — generation and reporting, not authoring. This skill extracts documentation from source and reports on its coverage. Deciding what to annotate and writing it is a refactor-phase obligation, owned by the auto-loaded rule
rules/code-quality-cocos.mdand executed per-unit byt1k-cocos-playable-modularize-refactor(Tier 2.5). The quality bar for that prose and its RAG-discoverability verification are owned byt1k-cocos-base-doc-flywheel. Theannotatecommand still ships here — it is the tool those phases call — but this skill does not own the when or what. Do not run a bulkannotatesweep as a standalone docs task; annotate alongside the code change that needs it.
Produces five outputs from Cocos project sources:
- classes —
@ccclass-decorated class diagram viats-morph(inheritance +@propertycross-refs) - modules — TypeScript module import graph via
dependency-cruiser - scenes — Scene node hierarchy from
assets/**/*.sceneJSON via a custom JSON walker - prefabs — Prefab component tree from
assets/**/*.prefabJSON via the same walker - docs — TSDoc doc-comment extraction into per-module doc-XML via
ts-morph— the TypeScript analog of C#‘s<GenerateDocumentationFile>output (see Documentation extraction)
Prerequisites
Section titled “Prerequisites”Install the full Cocos toolchain:
t1k diagram install --preset cocosPer-project tools (ts-morph, dependency-cruiser) are recorded as npm i --save-dev hints — version locks stay aligned with the project’s TypeScript version.
Global tools (mermaid-cli, graphviz) render Mermaid diagrams into images.
Invoked with no arguments, generate the docs. Run the canonical docs command below from
the Cocos project dir, then report the coverage audit. Do NOT reach for generate.cjs --type docs for that — see the entry-point table.
Canonical docs command
Section titled “Canonical docs command”This is the one that produces the docs-ts-out/{xml,json} tree:
node scripts/docs-ts.cjs export assets/scripts --format both --layout splitOmit the out-dir so output lands at the OUTERMOST repo root. Then audit coverage:
node scripts/docs-ts.cjs audit assets/scriptsTwo entry points reach the same extractor but default differently (docs-ts.cjs export vs
generate.cjs --type docs) — full comparison table, every diagram-type invocation, and the
diagnostic commands (detect.cjs, list-capabilities.cjs, requirements.cjs):
references/usage-examples.md.
Output Files
Section titled “Output Files”| Capability | Output |
|---|---|
classes | classes.md — Mermaid classDiagram of @ccclass components |
modules | modules.md — Mermaid graph from dependency-cruiser --output-type mermaid |
scenes | scenes.md — Mermaid flowchart TD of scene node hierarchy (one section per .scene file) |
prefabs | prefabs.md — Mermaid flowchart TD of prefab component tree (one section per .prefab file) |
docs | <module>.xml (one per top-level assets/scripts/ dir) in the C#-compiler doc-XML envelope, plus docs.md index |
Annotation-coverage audit (audit)
Section titled “Annotation-coverage audit (audit)”The read-only counterpart to annotate. buildModel already flags every undocumented member
needs-summary="true", so the audit just aggregates that in memory — it writes nothing to the
project and never needs a refactor to run.
node scripts/docs-ts.cjs audit assets/scripts # per-module coverage tablenode scripts/docs-ts.cjs audit assets/scripts --by file --top 20 # worst files + 20 worst symbolsnode scripts/docs-ts.cjs audit assets/scripts --json cov.json # machine-readable reportnode scripts/docs-ts.cjs audit assets/scripts --min-coverage 80 # soft gate: exit 1 if underRows sort worst coverage first. --json emits {total, documented, missing, coverage, pass, groups[], worstUndocumented[]} — worstUndocumented carries {cref, file, line, module} so it doubles
as a worklist for an annotate overrides map.
Exit codes: 0 normally; 1 only when --min-coverage is set and unmet. Absent that flag the
audit never fails, so it is safe in any pipeline. When piping to head/tail, read PIPESTATUS[0] —
the pipe’s exit status is the tail command’s, not the audit’s.
Stereotypes and Edge Semantics
Section titled “Stereotypes and Edge Semantics”<<ccclass>>stereotype on every detected@ccclassclass.- Inheritance edge:
class X extends Ywhere Y is another@ccclass. - Composition edge:
@property(...)field labeled with the field name, pointing at the referenced class when resolvable. - Scene/prefab nodes: hierarchy follows
_children; component attachments come from_components[]. - UUID cross-references in components: resolved to a readable path via a prebuilt UUID → file map when possible; otherwise the first 8 chars of the UUID are kept for traceability.
Documentation extraction (docs)
Section titled “Documentation extraction (docs)”The docs capability is the TypeScript analog of C#‘s per-assembly doc-XML (what the
C# compiler emits with <GenerateDocumentationFile>true). It walks every .ts under the
project via ts-morph and emits one <module>.xml per top-level assets/scripts/ dir, in
the identical envelope:
<?xml version="1.0"?><doc> <assembly><name>gameplay</name></assembly> <members> <member name="M:BlockageDetector.scan(number,TileModel[])" file="assets/scripts/gameplay/BlockageDetector.ts" line="88"> <summary>Scan forward from the tip…</summary> <param name="arrowIndex">Index of the arrow being checked</param> <returns>ScanResult with the blocked flag and blocker index</returns> </member> <member name="M:BlockageDetector.buildOccupancy(number[])" file="assets/scripts/gameplay/BlockageDetector.ts" line="61" needs-summary="true"> <summary></summary> </member> </members></doc>EVERY symbol is emitted (not just documented ones) — undocumented members get an empty
<summary> and a needs-summary="true" flag instead of being dropped, so the tier-1 hybrid
code-index keeps the full surface (30–60% of engine code is typically undocumented). Each
<member> also carries file="…" + line="…" attributes (provenance + the tier-2
file:line link). Members sorted, 4-space indent; the “assembly” is the top-level script-folder
name (Cocos has no .asmdef). Pass --documented-only for the legacy docs-xml.py parity
(drop undocumented).
Summary source — --summaries:
comment(default) — copy the author’s TSDoc verbatim (preserves the author’s language).derive— ignore the author comment and synthesize each summary from the CURRENT ts-morph signature (name, kind, params+types, return,extends/implements,@ccclass/@property, enum members, alias type). Deterministic, English, never stale — the fix when comments are outdated, wrong, or non-English.
Human-friendly summaries — apply: for out/out-style intent prose, an AI reads the
source and writes concise summaries into an overrides map { "<cref>": { summary, params, returns } }; docs-ts.cjs apply <module.json> <overrides.json> merges them onto the structural
model and re-renders (code merges, AI reasons — rules/ai-driven-design.md).
Self-document the source — annotate: the same override map, but written BACK INTO the
.ts source as real /** */ TSDoc (above @ccclass/@property decorators), so a re-extract
yields zero needs-summary. Skips already-documented symbols unless --force; --dry-run
reports diffs without writing. This is the fill-the-gaps loop: export to find needs-summary
crefs → AI authors the map → annotate writes them → export --layout split to regenerate.
See Documentation extraction / references/docs-extraction.md.
The full docs-ts.cjs / generate.cjs command surface (export/convert/apply/annotate flags) is
in the Usage block above — not repeated here to avoid drift.
For docs as a deliverable use docs-ts.cjs export (see Which entry point?);
generate.cjs --type docs serves the adapter contract. Both are supported entry points; the
wider t1k diagram toolchain only invokes docs once it recognizes the 5th capability, so run
it directly until then.
Full spec — cref-ID grammar (T:/M:/P:/F:), TSDoc→XML element mapping, the JSON↔XML model,
grouping rules, and the docs-xml.py comparison: references/docs-extraction.md.
MVP Scope & Known Limitations
Section titled “MVP Scope & Known Limitations”classes/modules still stub out until the Mermaid Layer A/C extractors land — the scene
walker and docs extractor are the fully-implemented capabilities today. This adapter targets
Cocos 3.x scene JSON only (2.x differs; detect.cjs gates on it). Full scope breakdown,
JSON-size ceiling, and the other known limitations: references/scope-notes.md.
Gotchas
Section titled “Gotchas”- Cocos Creator class graphs depend on
@ccclassdecorator — utility scripts without@ccclassare skipped silently. - Component dependency graph != class graph — components reference each other through
@property(Type), which is editor-only metadata. Use a separate parser pass for runtime deps. - Scene graph diagrams from
.sceneJSON are large — flat-collapse leaf transforms (Sprite,Labelinside layout containers) before rendering. - Cocos 2.x is unsupported —
detect.cjsonly matches 3.x scene JSON; running against a 2.x project no-ops with a warning. docsemits EVERY symbol, flagging undocumented ones — members with no TSDoc/** */block are emitted with an empty<summary>+needs-summary="true"(the tier-1 hybrid index keeps the full surface). Pass--documented-onlyto drop them (legacy docs-xml.py parity). Two summary modes:--summaries comment(verbatim author text, default) and--summaries derive(AST-synthesized English, ignores stale/non-English comments). For human-readable intent prose, AI-author an overrides map and rundocs-ts.cjs apply.exportwithout an out-dir writes to the OUTERMOST repo root — the default is<repo-root>/docs-ts-out, resolved viagit rev-parse --show-toplevelthen the--show-superproject-working-treechain, so a Cocos project vendored as a submodule does NOT get generated docs dumped inside it. Falls back to an upward.gitscan, then the source dir, when git is unavailable. Passing an explicit out-dir opts out — it resolves against the process cwd as before, soexport . docs-ts-outrun from inside a submodule still writes inside that submodule. Omit the argument unless you specifically want another location.- Neither docs entry point defaults to the split layout.
docs-ts.cjs exportandgenerate.cjs --type docsboth default to--format xml --layout flat. Thedocs-ts-out/{xml,json}tree people expect requires--format both --layout splitexplicitly, on either one. Omitting it succeeds and writes a flat XML-only tree — a wrong-shape result, not an error, which is exactly how this gets missed. file=is relative to the SCRIPTS ROOT, not to the src-dir you passed (since v1.22.0).file="UI/GameView.ts"regardless of whether you invoked withassets/scriptsor the project root — so the two entry points now agree byte-for-byte, andfile:linelinks survive a regeneration invoked from somewhere else. Behaviour change: before v1.22.0relFile()anchored on the rawsrcDir, soexport <project-root>emittedassets/scripts/UI/GameView.ts. Anything that stored those paths needs a one-time regenerate.docsneeds per-projectts-morph— without it,generate.cjs --type docsemits a graceful stub withcapabilities_skipped: ["docs"](it does NOT hard-fail). Install withnpm i --save-dev ts-morph. ts-morph is resolved from the target repo (and cwd), NOT from the skill’s own location — so you run the scripts in-place against any repo that has ts-morph installed; you do NOT install ts-morph next to the skill.docsscans only under the scripts root —<src>/assets/scripts(or<src>when it has no such subtree). The repo’snode_modules/and*.d.tsare auto-excluded, so a repo with hundreds of installed packages still yields only project members. Pointing--srcat a single module dir scopes the scan to that dir.docscref uses written type nodes, not the type checker — param types are the annotated text (Vec3,TileModel[]), so inferred-only params fall back toany. Annotate public APIs (Cocos convention anyway).docsgrouping ≠ asset bundles — modules are top-levelassets/scripts/dirs, not Cocos asset-bundle roots. Bundle-aware grouping is a future enhancement.auditis read-only;annotateis not. Reach forauditfor any “how documented are we” question — it never touches the project. Onlyannotatewrites. Confusing the two is how a reporting task becomes a source mutation.auditexit code is swallowed by a pipe.docs-ts.cjs audit … --min-coverage 80 | tailreportstail’s status, so a failed gate looks green. UsePIPESTATUS[0], or don’t pipe when gating.auditcounts symbols, not quality. A/** */block containing “TODO” counts as documented. It measures presence, not usefulness — do not treat 100% as “well documented” (--summaries deriveexists precisely because comments go stale).annotaterewrites source IN PLACE — it writes TSDoc into the real.tsfiles (up to N per run). Run on a clean git tree and/or--dry-runfirst; git is the only backup. Default skips already-documented symbols;--forceoverwrites existing TSDoc (removes the old block, not append). Onlysummary/@param/@returns/@remarksare written — never@throws/@example/@deprecated/@stability.annotatewrites LF line-endings — ts-morph inserts\n, so on a CRLF repo the touched files become mixed-EOL until git normalizes them (.gitattributes/core.autocrlf). Cosmetic; the diff stays additive.
References
Section titled “References”| File | Content |
|---|---|
references/scene-prefab-walker.md | JSON shape notes for Cocos Creator 3.x + walker algorithm (~50 LOC) |
references/ts-morph-ccclass.md | @ccclass decorator extraction spec |
references/dependency-cruiser-config.md | Custom rule snippets for Cocos project layout |
references/docs-extraction.md | docs capability: cref grammar, TSDoc→XML mapping, JSON↔XML, vs docs-xml.py |
rules/code-quality-cocos.md | Owns the annotation obligation — when/what to annotate. This skill owns the tooling only. |
t1k-cocos-base-doc-flywheel | Owns the annotation quality bar — behaviour+intent+side-effect prose, the --summaries derive trap, and MCP verification that the result is actually discoverable. |