Skip to content

t1k:cocos:base:script-graph

FieldValue
Modulebase
Version1.14.0
Effortmedium
Tools

Keywords: ccclass, class-diagram, cocos, cocos-creator, code-index, dependency-cruiser, doc-comments, doc-xml, docs, documentation, prefab, scene, script-graph, ts-morph, tsdoc, uuid

/t1k:cocos:base:script-graph

Cocos Creator 3.x diagram adapter and TypeScript documenting tool for the T1K toolchain. Produces five outputs from Cocos project sources:

  1. classes@ccclass-decorated class diagram via ts-morph (inheritance + @property cross-refs)
  2. modules — TypeScript module import graph via dependency-cruiser
  3. scenes — Scene node hierarchy from assets/**/*.scene JSON via a custom JSON walker
  4. prefabs — Prefab component tree from assets/**/*.prefab JSON via the same walker
  5. docs — TSDoc doc-comment extraction into per-module doc-XML via ts-morph — the TypeScript analog of C#‘s <GenerateDocumentationFile> output (see Documentation extraction)

Install the full Cocos toolchain:

t1k diagram install --preset cocos

Per-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.

Terminal window
# Auto-detect and generate all diagrams
t1k diagram refresh
# Generate a specific type
node scripts/generate.cjs --type classes --out-dir /tmp/out
node scripts/generate.cjs --type modules --out-dir /tmp/out
node scripts/generate.cjs --type scenes --out-dir /tmp/out
node scripts/generate.cjs --type prefabs --out-dir /tmp/out
node scripts/generate.cjs --type docs --out-dir /tmp/out # per-module doc-XML + docs.md index
# Documentation extraction can also run standalone (the docs-xml.py analog):
node scripts/docs-ts.cjs export <src-dir> <out-dir> [--format xml|json|both] \
[--summaries comment|derive] [--layout flat|split] [--documented-only]
node scripts/docs-ts.cjs convert <module.json> [module.xml] # lossless JSON → XML
node scripts/docs-ts.cjs apply <module.json> <overrides.json> # overlay AI summaries onto the MODEL
node scripts/docs-ts.cjs annotate <src-dir> <overrides.json> # write TSDoc /** */ back INTO source
[--force] [--dry-run]
# Reproduce the docs-ts-out/{xml,json} layout (one format per subdir):
node scripts/docs-ts.cjs export assets/scripts docs-ts-out --format both --layout split
# Does this adapter apply to the current project?
node scripts/detect.cjs # exit 0 = match
# List supported capabilities
node scripts/list-capabilities.cjs
# Tool requirements (mermaid-cli global + ts-morph/dep-cruiser per project)
node scripts/requirements.cjs
CapabilityOutput
classesclasses.md — Mermaid classDiagram of @ccclass components
modulesmodules.md — Mermaid graph from dependency-cruiser --output-type mermaid
scenesscenes.md — Mermaid flowchart TD of scene node hierarchy (one section per .scene file)
prefabsprefabs.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
  • <<ccclass>> stereotype on every detected @ccclass class.
  • Inheritance edge: class X extends Y where 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.

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).
  • deriveignore 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.

The standalone docs-ts.cjs / generate.cjs --type docs are the primary 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.

The scene walker (Layer B, scenes/prefabs) and the docs extractor (ts-morph) are fully implemented. classes/modules still stub out with clear skip messages until the Mermaid Layer A/C extractors land. The adapter contract is stable; the capability surface is final at [classes, modules, scenes, prefabs, docs].

See references/scene-prefab-walker.md for the JSON walker design and references/ts-morph-ccclass.md for the class-diagram extractor spec (follow-up). The docs extractor lives in scripts/lib/ts-doc-extractor.cjs (consumed by both docs-ts.cjs and generate.cjs --type docs).

  • Cocos Creator 2.x scene JSON shape differs — this adapter targets 3.x only. detect.cjs inspects project.json/package.json before accepting.
  • JSON.parse(fs.readFileSync) reads whole-file (~50 MB upper bound documented).
  • Deeply nested prefab variants are rendered as opaque leaves in v1 — variant-aware walking is a future enhancement.
  • Unresolved UUIDs fall back to their first-8-char prefix; not a hard error.
  • Cocos Creator class graphs depend on @ccclass decorator — utility scripts without @ccclass are 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 .scene JSON are large — flat-collapse leaf transforms (Sprite, Label inside layout containers) before rendering.
  • Cocos 2.x is unsupporteddetect.cjs only matches 3.x scene JSON; running against a 2.x project no-ops with a warning.
  • docs emits 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-only to 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 run docs-ts.cjs apply.
  • docs needs per-project ts-morph — without it, generate.cjs --type docs emits a graceful stub with capabilities_skipped: ["docs"] (it does NOT hard-fail). Install with npm 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.
  • docs scans only under the scripts root<src>/assets/scripts (or <src> when it has no such subtree). The repo’s node_modules/ and *.d.ts are auto-excluded, so a repo with hundreds of installed packages still yields only project members. Pointing --src at a single module dir scopes the scan to that dir.
  • docs cref uses written type nodes, not the type checker — param types are the annotated text (Vec3, TileModel[]), so inferred-only params fall back to any. Annotate public APIs (Cocos convention anyway).
  • docs grouping ≠ asset bundles — modules are top-level assets/scripts/ dirs, not Cocos asset-bundle roots. Bundle-aware grouping is a future enhancement.
  • annotate rewrites source IN PLACE — it writes TSDoc into the real .ts files (up to N per run). Run on a clean git tree and/or --dry-run first; git is the only backup. Default skips already-documented symbols; --force overwrites existing TSDoc (removes the old block, not append). Only summary/@param/@returns/@remarks are written — never @throws/@example/@deprecated/@stability.
  • annotate writes 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.
FileContent
references/scene-prefab-walker.mdJSON shape notes for Cocos Creator 3.x + walker algorithm (~50 LOC)
references/ts-morph-ccclass.md@ccclass decorator extraction spec
references/dependency-cruiser-config.mdCustom rule snippets for Cocos project layout
references/docs-extraction.mddocs capability: cref grammar, TSDoc→XML mapping, JSON↔XML, vs docs-xml.py