t1k:cocos:base:migrate
| Field | Value |
|---|---|
| Module | base |
| Version | 1.14.0 |
| Effort | high |
| Tools | — |
Keywords: atomic, cocos, idempotent, js2ts, manifest, migration, orchestrator, pipeline, rollback
How to invoke
Section titled “How to invoke”/t1k:cocos:base:migrateWhen to use
Section titled “When to use”Khi muốn chạy CẢ pipeline JS->TS cho nhiều file/1 scene bằng 1 lệnh, thay vì gọi tay từng stage. Orchestrator MỎNG: chỉ điều phối + closure + topo-sort + gate + manifest, mọi logic nằm ở skill stage.
Pipeline 5 pha: dep-graph + 4 .d.ts (Phase0) → js2ts (Phase1) → tsc-validate (Phase2) → uuid-verify gen-meta+attach (Phase3, editor ĐÓNG) → uuid-verify verify=editor-compile-verify (Phase4).
Cách hoạt động — 5 PHA ĐỒNG BỘ (atomic theo closure)
Section titled “Cách hoạt động — 5 PHA ĐỒNG BỘ (atomic theo closure)”Khác bản cũ (1 vòng for trộn gate + side-effect mỗi file): tách thành các pha; pha side-effect (Phase3) CHỈ chạy khi pha validate (Phase2) xanh toàn bộ closure. Sai thì sai đồng bộ (STOP cả batch, prefab chưa đụng — sửa rule 1 chỗ, áp lại); đúng thì đúng đồng bộ (attach cả closure).
- Resolve target:
--scene <path>(mọi component custom scene tham chiếu) HOẶC danh sách<file.js>. - Closure = extends + require transitive (internal): base class + mọi require-dep được thêm để convert TRƯỚC (tsc-validate cần dep là module
.cvmới type-check sạch; gate attach cần @property inherited). Topo-sort base+require-first. - Phase 0 PRECONDITION (smart-refresh hash-gated): dep-graph + 4
.d.tsCHỈ regenerate khi nguồn đổi (hoặc--force-refresh). Stamp hash vào manifest. - Phase 1 CONVERT (js2ts cả closure). GATE 1 (100% convert) + GATE dependency-holdout (§ Gotcha 6): holdout CÓ consumer trong closure → STOP NGAY Phase 1 (KHÔNG bypass).
- Phase 2 VALIDATE (tsc-validate cả closure, 1 lượt filter-arg). GATE 2: 0 SYNTAX (TS1xxx) → else STOP (chưa attach gì). [dry-run] write-real
.cv.ts→ validate → cleanup. - Phase 3 ATTACH (chỉ
--write+--editor-closed): gen-meta single-writer cả closure → attach re-point CHỈ nhóm A. GATE 3: @property completeness → fail → STOP + ROLLBACK. - Phase 4 VERIFY: mở editor lại → dangling + isPlugin + editor-compile-verify.
Trạng thái mỗi file lưu ở manifest tmp/migrate-state.json (SSOT): file “current” (mọi hash khớp) → skip; “stale” → redo. Idempotent: re-run --write cho kết quả y hệt (uuid đã persist). --resync ép coi mọi file stale → reprocess đồng loạt.
Định tuyến nhóm file A/B/C (DATA-driven theo registry)
Section titled “Định tuyến nhóm file A/B/C (DATA-driven theo registry)”| Nhóm | Điều kiện | gen-meta | attach (re-point prefab) |
|---|---|---|---|
| A Component CÓ prefab-ref | isComponent && uuid trong prefab/scene | ✅ | ✅ (blast-radius DUY NHẤT) |
| B Component KHÔNG prefab-ref | isComponent && 0 ref (logic/base/runtime-add) | ✅ | ❌ n/a |
| C Non-component | !isComponent (object/class/global/ES) | ✅ | ❌ n/a |
- gen-meta CHO MỌI nhóm — non-component vẫn cần
.cv.ts.metađể file TS khácrequire/importresolve runtime. Không attach ≠ không gen-meta. - attach CHỈ nhóm A = phần DUY NHẤT sửa prefab. B/C revert = chỉ xoá
.cv.ts/.meta. - single-writer/editor-đóng áp MỌI nhóm (gen-meta là một lần GHI single-writer).
# KẾ HOẠCH (mặc định — KHÔNG chạy stage, KHÔNG ghi). In closure + routing A/B/C + cột "cur" (manifest-current):node .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --scene Client/assets/scene/main.firenode .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs Client/assets/script/scripts/MapPage.js
# DRY-RUN (write-real .cv.ts → tsc-validate THẬT → cleanup; KHÔNG attach/meta/sửa prefab):node .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --scene Client/assets/scene/main.fire --run
# THỰC THI (editor ĐÓNG — single-writer uuid): ghi .cv.ts + gen-meta + attach re-point prefab/scene:node .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --scene <p> --run --write --editor-closed
# FULL-434 LIỀN MẠCH (§12): target = TOÀN BỘ registry (1 closure, topo toàn cục). KHÔNG cần --scene/<file>.# ⚠ blast radius ≈ MỌI prefab/scene → BẮT BUỘC: baseline git sạch + editor ĐÓNG. Luôn --plan → --run (dry) TRƯỚC.node .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --all # plan: closure 434 + A/B/Cnode .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --all --run # dry: validate cả 434 (0 holdout/syntax)node .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --all --run --write --editor-closed # THỰC THI full
# 2 PHA (khuyến nghị diện rộng): convert+validate trước (0 blast radius), attach sau:node .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --scene <p> --run --write --no-attachnode .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --scene <p> --run --write --editor-closed
# ROLLBACK (sau gate-fail Phase3 hoặc muốn revert run gần nhất): git checkout prefab/scene + xoá .meta tool tạo:node .claude/skills/t1k-cocos-base-migrate/scripts/migrate.cjs --rollbackFlags:
--all— target = TOÀN BỘ registry (full-434 liền mạch §12): closure = mọi entry, topo base+require-first toàn cục. BỎ QUA--scene/<file>nếu truyền kèm. Blast radius ≈ mọi prefab/scene → luôn--plan→--run(dry) trước--write.--editor-closed— BẮT BUỘC trước Phase 3--write(xác nhận editor ĐÓNG → single-writer uuid).--no-attach— pha 1: chỉ js2ts + tsc-validate, KHÔNG re-point prefab (rollback = xoá.cv.ts).--allow-holdout— cho phép leaf-holdout (requiredBy ∉ closure) tách khỏi batch. KHÔNG bypass dependency-holdout.--resync— ép coi MỌI file STALE → reprocess đồng loạt (dùng sau khi sửa 1 bug codemod, áp lại toàn bộ).--force-refresh— ép Phase 0 regenerate registry (dep-graph) + 4.d.ts.--rollback— thực thi rollback theomanifest.lastRun.repointed(git checkout + xoá.metatool tạo). KHÔNG tự chạy khi không có cờ này.--manifest <p>(mặc địnhtmp/migrate-state.json) ·--registry <p>·--script-root <p>·--assets-root <p>·--force(bỏ qua gate-fail attach, chuyển uuid-verify).
Config — .claude/cocos-migrate.json (SSOT đường dẫn, KHÔNG hardcode)
Section titled “Config — .claude/cocos-migrate.json (SSOT đường dẫn, KHÔNG hardcode)”Mọi đường dẫn project lấy từ .claude/cocos-migrate.json (dùng chung cho t1k-cocos-base-uuid-verify + t1k-cocos-base-tsc-validate). Thứ tự ưu tiên: CLI flag > config > built-in fallback. Project khác chỉ cần sửa file này, KHÔNG đụng code skill:
{ "scriptRoot": "Client/assets/script", "assetsRoot": "Client/assets", "registry": "tmp/dep-registry.json", "creatorDts": "Client/creator.d.ts", "tsconfig": "Client/tsconfig.json" }Thiếu config → dùng fallback (giá trị trên). Sai 1 key → CLI flag tương ứng override.
Output
Section titled “Output”- Plan: bảng topo-order —
# | grp(A/B/C) | isComp | .cv.ts | JS-ref | cur(manifest-current) | base/req-dep | file+ tổng A/B/C. - Run: từng Phase 0–4 với gate; SUMMARY
file | grp | phase1 | phase2 | phase3. Manifesttmp/migrate-state.jsonghi trạng thái +lastRun.repointed(cho rollback).
⚠️ Blast radius (đọc trước khi —write)
Section titled “⚠️ Blast radius (đọc trước khi —write)”attach re-point component ở MỌI prefab/scene tham chiếu nó (class uuid phải nhất quán toàn cục), KHÔNG chỉ scene bạn truyền. VD --scene main.fire nhưng LocalLabel/ClickButton/FullScreenWidget dùng khắp project → —write sẽ sửa hàng chục file. Luôn chạy --plan rồi --run (dry) trước --run --write. Revert = git checkout các prefab/scene.
Gotchas
Section titled “Gotchas”- Mặc định KHÔNG chạy gì —
--planchỉ đọc + in. Phải--runmới chạy stage;--run --write --editor-closedmới ghi. An toàn theo preview-first. - Base+require-first BẮT BUỘC — closure = extends + require transitive (internal). gate attach cần @property inherited; tsc-validate cần dep là module
.cv(bare cc.Class.js= TS2306). Orchestrator tự convert dep TRƯỚC. Base engine (cc.*, extendsAbs=null) → bỏ qua đúng. - SYNTAX-FAIL (TS1xxx) chặn cả batch ở Gate 2 (không —force) — Phase 3 KHÔNG chạy, 0 prefab bị đụng. Type residual (TS2xxx) KHÔNG chặn (any-safe).
- isPlugin auto-fix nằm ở
gen-meta/attach(uuid-verify) — orchestrator hưởng sẵn. - Phase 4 verify cần editor đã reimport để library entry phản ánh đúng (editor-compile-verify). Chạy
--writevới editor đóng → mở editor lại → reload → rồi tin kết quảverify. - GATE dependency-holdout (§ Cách hoạt động bước 4) — chặn RẺ ở Phase 1. 5 holdout js2ts đã biết: leaf (
Item,ItemAdvanced,DraftMenu—requiredBy=0) vs dependency (EffectManager2 cc.Class/file,LeaderboardDatastatics-getter). Dependency-holdout missing-module = TS2xxx NON-blocking → lọt Gate 2, chỉ lộ ở Phase 4 (đắt, SAU side-effect) → vì vậy GATE đặt ở Phase 1: holdout CÓ consumer trong closure → STOP NGAY, KHÔNG cho--allow-holdoutbypass.--allow-holdoutCHỈ tách leaf. EffectManager/LeaderboardData cần thêm js2ts support TRƯỚC khi closure chứa chúng chạy (chưa làm — gate sẽ STOP an toàn). - Chạy với editor ĐÓNG (single-writer uuid — canonical 2026-06-01). uuid là
crypto.randomUUID()→ KHÔNG value-reproducible; “tất định” ở đây = single-writer / process-deterministic / stateful-idempotent: một khi.cv.ts.metapersist thì re-run giữ nguyên uuid (idempotent).--editor-closedBẮT BUỘC trước Phase 3--write(tool là writer DUY NHẤT). Editor mở lúc attach → 2 writer → uuid khác/isPlugin:true→ mất đồng bộ. Chi tiết:t1k-cocos-base-uuid-verifygotcha 10. - Manifest
tmp/migrate-state.jsonlà SSOT trạng thái — file “current” (srcHash + codemodHash + dtsHash + registryHash khớp) → skip; lệch → STALE → redo.--resyncép redo toàn bộ. Idempotent chỉ ở--write(.cv.tspersist); dry-run luôn write-real→cleanup nên không “current-skip”. - Rollback dựa
git checkout— yêu cầu prefab/scene SẠCH trước--write(commit/stash trước). Gate-fail Phase 3 → in lệnh rollback (KHÔNG tự chạy);--rollbackthực thi theomanifest.lastRun.repointed. JS +.js.metaKHÔNG bao giờ bị đụng.
See also
Section titled “See also”t1k-cocos-base-js2ts·t1k-cocos-base-tsc-validate·t1k-cocos-base-uuid-verify(các stage).t1k-cocos-base-dep-graph— registry (results[].extendsAbs/requiresdùng để topo-sort).plans/reports/2026-05-29-js-to-ts-migration-brainstorm.md§5.2/§9 — vai trò orchestrator.