refactor(tooling): [MOD-PLUGIN-01] generate typed plugins with safe output handling

This commit is contained in:
Harvey Zhao committed 2026-09-14 10:19:19 +08:00
1 parent 07d5bfef2e
commit 28c7abb2bb
32 files changed
+958 -161

No files matched your search

+160
View File
@@ -0,0 +1,160 @@
{
"task": "MOD-PLUGIN-01",
"date": "2026-09-14",
"baselineCommit": "07d5bfef2e815e8038362bb836b9c496c7ef9862",
"environment": {
"os": "Windows",
"node": "24.21.0",
"yarn": "1.22.22",
"typescript": "5.9.3",
"classicTypescript": "4.3.5"
},
"results": {
"scaffold": {
"passed": 11,
"failed": 0,
"skipped": 0
},
"ci": {
"passed": 50,
"failed": 0
},
"strictTypes": "passed",
"toolchain": "passed",
"lint": {
"errors": 0,
"warnings": 1,
"existingWarning": "docs/assets/ts/artplayer.d.ts unused ts/no-namespace directive"
},
"generatedPackage": {
"formats": [
"UMD es2020",
"UMD es2015 legacy",
"ESM es2020"
],
"exports": [
"ESM default",
"CommonJS direct and .default",
"legacy ESM and CommonJS"
],
"types": [
"strict source",
"TS5.9.3 NodeNext .mts/.cts",
"TS4.3.5 classic positive/negative"
],
"lint": "zero warnings",
"dom": "linkedom duplicate stylesheet and no-DOM imports"
},
"baseline": {
"passed": 522,
"failed": 0,
"skipped": 0
}
},
"limitations": [
"No real browser playback or remote CI execution",
"No new real workspace; integration output is an ignored fixture",
"No all-files atomicity or killed-process recovery",
"No new dependencies or changes to yarn.lock"
],
"sourceFiles": [
{
"path": "scripts/plugin/create.js",
"sha256": "ebc413b32037561698efd3c19776681cca57f259f09fab86e8d06d419b9a6647"
},
{
"path": "scripts/plugin/cli.ts",
"sha256": "0aa466a75c6e808ab652ca5409134e8618c1b0d96908c4a27362927c2f5084e4"
},
{
"path": "scripts/plugin/render.ts",
"sha256": "339485dd33bb6bf1e2602f89d65d88e6a4aea6aa4133f19c64b6cda9de466090"
},
{
"path": "scripts/plugin/publish.ts",
"sha256": "41604d49c22c5e30e69c17a4664055c2cd6442de473b85e3550a5cc96c6aca0f"
},
{
"path": "scripts/tsconfig.scaffold.json",
"sha256": "54388f6b1cc1c4173fcce70bbacd9512469f89bb19145be6aeb8c66eb6bd6fbc"
},
{
"path": "scripts/plugin/template/package.json",
"sha256": "3a8b700ba7f662cba8324678743339acdc1db33b7f9e7f37908971ff7125c982"
},
{
"path": "scripts/plugin/template/src/index.ts.tpl",
"sha256": "53183f3a3476c1c3225cf57c167b4bd24df7d5c46949b38889ebbe9326fceb72"
},
{
"path": "scripts/plugin/template/src/stylesheet.ts.tpl",
"sha256": "c9239de63c8b3a675fb0f8b1bd9f1a33544cae29864b8d16076a379ad89a5427"
},
{
"path": "scripts/plugin/template/src/assets.d.ts.tpl",
"sha256": "abc216473dd0869001b5a88ed7add80f0449e71d1d3af872a6df9631f96e4641"
},
{
"path": "scripts/plugin/template/src/style.less",
"sha256": "64c690eacbc33b44517d1fe84c53dbce3b76d97ed54ea273c6400119b46033d2"
},
{
"path": "scripts/plugin/template/types/api.d.ts.tpl",
"sha256": "24dd42ddae63405c6752528077b435f8ee398bc233efaab064707475a049b48a"
},
{
"path": "scripts/plugin/template/types/artplayer-plugin-{{name}}.d.ts.tpl",
"sha256": "82d68fc8311076f9e9466fb0e73927390501770dc02d2fdc828a637638f69949"
},
{
"path": "scripts/plugin/template/types/artplayer-plugin-{{name}}.d.mts.tpl",
"sha256": "63dbe5a3e754f380abb7de53e3d8de7074d424892b4f724465111c139cb65b71"
},
{
"path": "scripts/plugin/template/test/plugin.test.mjs.tpl",
"sha256": "e60bf566d665ac0d77a4d41899f26b01a24acf2516204e285f87c763f5b6ff57"
},
{
"path": "scripts/plugin/template/tsconfig.json",
"sha256": "528081768e5c3a6361dd0a2cfc59f953257caeae70bd5305b2db2fe4d98009ad"
},
{
"path": "test/plugin-scaffold.test.js",
"sha256": "ac9580ea49e937abc5129324ee5de930320dea59ba556f71ad9b1612a224f981"
}
],
"logs": [
{
"path": "refactor/.cache/scaffold-initial.log",
"sha256": "6cd75297d36e46b1e4f9e462d296383dd76304d2befed6c6662d1fe21e74f5f0"
},
{
"path": "refactor/.cache/scaffold-generated-lint-initial.log",
"sha256": "99d420f2c2e4a76248b59bb8593297f127337d4eb5ddb81463e9e4ea80269bbc"
},
{
"path": "refactor/.cache/scaffold-final.log",
"sha256": "8505990bf0131dfa3598fa985cdbc7e294c6a62a2f1e905c864a082ac63f0179"
},
{
"path": "refactor/.cache/scaffold-types.log",
"sha256": "4bff36c4b15e17ba27c5065a7db072e324500a827be1e11ebb60d370271ff336"
},
{
"path": "refactor/.cache/scaffold-lint.log",
"sha256": "928ec73d5f8ea3b16e4bc051293d425692bd393df790abecb9ee320adecdff62"
},
{
"path": "refactor/.cache/scaffold-ci.log",
"sha256": "6cd851ff61057e007c24ff0898578c42dabb634096cb8b45d36bde7fd3114be0"
},
{
"path": "refactor/.cache/scaffold-toolchain.log",
"sha256": "1d5e2306c57bc1e90ae5625e0924e56cde9e27eb3cf89c64bfe735a36dd42863"
},
{
"path": "refactor/.cache/scaffold-baseline.log",
"sha256": "2ef047976b63d707e3e4fde2e3475b4d0b53c699c6120826870f0bec3816d971"
}
]
}
+7
View File
@@ -1,5 +1,12 @@
# 已实现的 JS/TS 构建与开发入口
MOD-PLUGIN-01 将 `yarn create:plugin` 的实现拆为严格 TS 渲染/文件写入/CLI,
保留旧 JS 命令入口。生成 TS 工厂、CJS/ESM 声明、分发消费测试与维护文档;
拒绝覆盖既有包/示例,失败时回退自己的写入并保留外部修改。
运行 `yarn typecheck:scaffold` 与 `yarn test:scaffold`,具体限制和模块地图见
[生成器维护指南](../scripts/plugin/README.md)。MOD-02 继续负责 dev/build/utils,
本子任务不代表全部工程脚本已经迁移。
ENG-06 保留原来的 Vite 7.3.6、Terser、三种库产物及路径,增加选包参数和 TS 入口;未切换 bundler 或运行时依赖。固定工具链仍为 Node 24.21.0 / Yarn 1.22.22。
ENG-12 将库配置的 publicDir 设为 false,防止 core/public 的声明源码被复制到 dist。
@@ -0,0 +1,73 @@
# MOD-PLUGIN-01: TypeScript plugin scaffold
## Scope and compatibility
The original generator at `07d5bfef2e815e8038362bb836b9c496c7ef9862` overwrites an
existing dotted demo file, and its README uses the hyphenated name instead of that
actual file name. The frozen implementation is executed in a fixture to reproduce
both defects. The old command and valid name/global/example mapping remain; invalid
names with empty segments and extra arguments now fail before writing. No existing
package, public declaration, built distribution, or real example was regenerated.
`MOD-PLUGIN-01` is a child dependency of MOD-02. It finishes the generator/template
part independently; development/build/shared-config migration remains with MOD-02.
## Implementation and maintenance
The checked JS command shim delegates to strict TS CLI, pure rendering and filesystem
publication modules. Rendering validates placeholders, name and output collisions.
Publication stages complete files, exclusively reserves a new package and hard-links
without replacing existing destinations. Caught failures roll back owned unchanged
files and empty directories, preserving edits and concurrent output with recovery
paths. Existing symlink/junction destinations are rejected. This is per-file atomic
publication, not all-files/crash atomicity or adversarial filesystem protection.
The new template includes TS source, a once-per-document stylesheet import with an
SSR guard, explicit shared option/result declarations, distinct CJS/ESM declaration
entries, main/module/legacy formats, direct/default CommonJS calls, package-consumer
tests and a maintenance README. The demo links to the actual dotted example.
The factory remains synchronous. New package version starts at 1.0.0; the existing
packages' independent next-major targets are unchanged.
The module map, failure recovery boundaries and reproducible commands live in
[scripts/plugin/README.md](../../scripts/plugin/README.md). New dependencies: none.
Generated manifests declare the ArtPlayer host as a peer; generation does not install
or update the root lock, inventories or release scope. Root `test:scaffold`,
`typecheck:scaffold`, lint coverage, Node tests and CI typecheck now cover this tool.
## Verification and actual limits
- Node 24.21.0, Yarn Classic 1.22.22, Windows. Strict toolchain check passed.
- `yarn typecheck:scaffold`: strict TS modules plus JS shim passed.
- `yarn test:scaffold`: 11 passed, zero skipped. Tests cover the frozen defects,
malformed template/name input, existing/competing outputs, mid-write rollback,
retention of externally edited files, redirected directories and CLI invocation
from another directory. A generated fixture is linted with zero warnings, built
through the real three-format production CLI, then consumed through actual
ESM/CJS/legacy package exports. Strict source, TS 5.9.3 NodeNext import/require and
TS 4.3.5 classic consumers pass positive and negative cases. Repeated stylesheet
loading and no-DOM import are checked with linkedom/VM, not real media playback.
- `yarn lint`: passed with the one pre-existing unused directive warning in
`docs/assets/ts/artplayer.d.ts`.
- `yarn test:ci`: 50 passed. This proves local workflow-policy regressions, not a
remote GitHub run.
- `yarn test:baseline`: 522 passed, zero skipped; frozen package/runtime/type and
refactor workflow regression checks remain intact.
- Initial integration failure was the nested Node test runner's inherited context,
which suppressed the child reporter. The runner now removes NODE_TEST_CONTEXT;
child test completion is asserted. Generated-output lint then found manifest
array ordering and the old template Less indentation; both templates corrected.
Initial logs are retained separately from the successful run.
Evidence and source/log hashes: [scaffold-validation.json](../baselines/scaffold-validation.json).
Fixtures are ignored and removed through checked paths; no 23rd real workspace was
created. No frozen reinstall was needed because dependencies and yarn.lock are
unchanged. No browser playback, device, full release or publication claims arise
from this tooling task. Future generated plugin features need their own tests.
## Rollback and next work
Revert this task's dedicated commit to restore the previous generator, templates and
script integration; that also restores its known overwrite defect. Existing package
artifacts require no rollback. MOD-02 will migrate the remaining build/development
responsibilities while preserving command behavior. Local commit only; no push/npm.
+1
View File
@@ -11,6 +11,7 @@
| `yarn typecheck` | 根/迁移包严格检查、当前与兼容 TS 消费;历史 NodeNext ESM 错误单独核对,见 typechecking.md |
| `yarn typecheck:react` / `yarn typecheck:vue` | 原 React TSX / Vue SFC 示例严格检查,ci:check 同时执行对应 lint |
| `yarn typecheck:docs-tools` / `yarn check:docs-smoke` | 严格检查 TS 示例/声明生成器及 JS/MJS 门面;只读核对确定性生成的 readiness smoke,ci:check 执行 |
| `yarn typecheck:scaffold` / `yarn test:scaffold` | 严格检查插件生成器与旧 JS 入口;生成包真实构建/类型/分发消费和写入失败回归;分别接入 ci:check 与 test:node |
| `yarn check:editor-types` | 只读核对全部编辑器声明、SDK notices 和实际 libUris;主 TS 5.9.3/历史 4.3.5 整组语义检查,ci:check 执行 |
| `yarn build:site-assets` / `yarn check:site-assets` | 从站点 browser/ TS 生成三个经典脚本;check 只读,root build:docs 先生成;完整 VitePress 构建另行验收 |
| `yarn typecheck:site-assets` | 严格检查站点 browser/ 模块;生成脚本由 typecheck:docs-tools 的 checkJs 覆盖;均进入 ci:check |
+5 -3
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 243 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 244 项,范围 22 个包及工作区/示例。
状态:todo 57 / doing 16 / blocked 0 / done 170 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 57 / doing 16 / blocked 0 / done 171 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -400,7 +400,8 @@
| ID | 范围 / 步骤 | 前置依赖 | 交付物 | 验收条件 | 风险 | 状态 |
| --- | --- | --- | --- | --- | --- | --- |
| MOD-01 | workspace<br>Bun 固定版本干净安装试点 | ENG-09 | 独立目录的 Bun 安装与 Yarn 冻结基线对比,默认仍为用户选定的 Yarn | Node 测试仍通过;安装与资源一致才决定采用;不改 bundler;不自动替换默认 packageManager 或维护锁文件 | H | todo |
| MOD-02 | workspace<br>整理剩余开发/构建脚本与插件模板 | ENG-06, SITE-03 | dev/build/utils/create-plugin 的 TS 与可测 CLI,模板同时提供旧 API | 旧脚本入口保留、新插件类型/测试/示例齐全,Lerna 改动单独取证 | M | todo |
| MOD-PLUGIN-01 | workspace<br>迁移插件生成器与类型化模板 | ENG-06, SITE-03 | 保留 create:plugin CLI;纯渲染/文件发布边界、TS 工厂/声明/测试/示例及维护指南 | 防止覆盖现有包或示例;失败回退;生成包可构建并通过严格类型、旧模块消费及测试;不自动修改既有包或运行安装发布 | M | done |
| MOD-02 | workspace<br>整理剩余开发/构建脚本与插件模板 | ENG-06, SITE-03, MOD-PLUGIN-01 | dev/build/utils/create-plugin 的 TS 与可测 CLI,模板同时提供旧 API | 旧脚本入口保留、新插件类型/测试/示例齐全,Lerna 改动单独取证 | M | todo |
| MOD-03 | workspace<br>测量并优化核心热路径 | CORE-22, ENG-08 | DOM 读写、进度更新、持久化、初始化的测量与改进 | 相同设备媒体多次比较,契约不变,收益及无效尝试记录;复用 BASE-06 的原始样本与测量限制,至少三组同环境旧新配对,不以单次变快宣称收益 | M | todo |
| MOD-04 | workspace<br>测量并优化重型插件/proxy | PKG-DANMUKU-09, PKG-MASK-06, PKG-MB-10, ENG-08 | 帧/队列/推理/音画同步与资源长期运行比较 | 不改默认算法/阈值,性能改善有证据;无收益则保留旧实现 | M | todo |
| MOD-05 | workspace<br>完成工具链与性能采用决策 | MOD-01, MOD-02, MOD-03, MOD-04 | 最终 runtime/packageManager/构建配置及性能台账 | 干净安装和全包检查通过;Bun 未采用有理由,不为状态强行切换 | M | todo |
@@ -620,6 +621,7 @@
- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json)
- EX-01: [记录](changes/2026-09-14-EX-01-react-consumer.md) [记录](baselines/react-consumer-validation.json) [记录](scripts/react-consumer.mjs)
- EX-02: [记录](changes/2026-09-14-EX-02-vue-consumer.md) [记录](baselines/vue-consumer-validation.json) [记录](scripts/vue-consumer.mjs)
- MOD-PLUGIN-01: [记录](changes/2026-09-14-MOD-PLUGIN-01-scaffold.md) [记录](baselines/scaffold-validation.json)
- PKG-FACTORY-01: [记录](baselines/factory-assignment-gaps.json) [记录](baselines/factory-compatibility-proposals.json) [记录](factory-compatibility-decision.md) [记录](changes/2026-09-12-PKG-FACTORY-01-decision.md) [记录](type-compatibility-policy.md) [记录](baselines/factory-compatibility-validation.json) [记录](changes/2026-09-13-PKG-FACTORY-01-compatible-types.md)
- CORE-25: [记录](changes/2026-09-13-CORE-25-defaults-ssr.md) [记录](baselines/defaults-ssr-validation.json)
- ENG-12: [记录](changes/2026-09-13-ENG-12-library-public.md) [记录](baselines/library-public-validation.json)
+15
View File
@@ -1,5 +1,20 @@
# 进度与证据
## MOD-PLUGIN-01 插件生成器与 TS 模板完成
生成器拆为严格 TS 的模板渲染、文件写入和 CLI,保留 create.js 旧命令入口及
合法命名规则。冻结旧脚本复现示例覆盖和 README 链接不匹配;候选拒绝覆盖,
失败时回退自己的未修改文件,保留外部修改并报告恢复路径。生成 TS 工厂、
CJS/ESM 声明、三格式分发消费测试和维护指南,不改既有包或添加真实 workspace。
11 项目标测试、522 项 baseline、50 项 CI 回归通过;生成包 lint 零 warning,
源码及新旧编译器严格检查通过,全仓 lint 保留 1 条既有 warning。初始子进程
测试报告问题及模板格式失败日志保留;详见[变更记录](changes/2026-09-14-MOD-PLUGIN-01-scaffold.md)
和[证据](baselines/scaffold-validation.json)。没有新增依赖、安装、推送或发布。
DOM 证据是 linkedom,不是未来插件功能的真实播放验收;文件写入不承诺进程
被杀后的自动恢复。244 项变为 171 done、16 doing、57 todo。下一步 MOD-02
继续 dev/build/utils 等剩余工程脚本;VAST 默认行为选择仍待用户答复。
## VTT Thumbnail 五核心组合检查点
PKG-VTT-THUMB-05 进入 doing。冻结真实核心5.1.6的197成员,和已有5.1.7、
+1
View File
@@ -261,3 +261,4 @@
| SITE-EDITOR-FAILURE-01 | resolved / 已复现 | Desktop editor evaluates raw TypeScript and cannot settle FileReader errors or boot with denied storage | SITE-03 |
| SITE-EDITOR-AMD-01 | resolved / 已复现 | Late Monaco language AMD initialization races with example dependency loading | SITE-03 |
| VTT-CORE-NAME-01 | open / 已复现 | Published VTT 1.0.1 control name conflicts with the core placeholder introduced in 5.1.7 | PKG-VTT-THUMB-05, REL-08 |
| SCAFFOLD-OUTPUT-01 | resolved / 已复现 | Plugin generation overwrites existing examples and links to a different example name | MOD-PLUGIN-01 |
+22
View File
@@ -5892,6 +5892,28 @@
"compatibleResolution": "Preserve current vtt-thumbnail and reserved core control identities; distinguish the actual working 1.0.1/5.1.6 pair from the already failing 5.1.7/5.4.0/candidate pair. Decide the supported historical pairing/migration or a compatible accommodation during release review without hiding duplicate-control failures.",
"closureCriteria": "Historical working and failing browser pairs remain reproducible; any claimed accommodation preserves reserved-control ownership and duplicate-registration contracts, or an explicit reviewed historical support/migration boundary is recorded.",
"workspaceState": "Final three-engine suite passes nine assertions of this historical rejection, not nine successful compatibility cells. No production control behavior was changed."
},
{
"id": "SCAFFOLD-OUTPUT-01",
"title": "Plugin generation overwrites existing examples and links to a different example name",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"MOD-PLUGIN-01"
],
"evidence": [
"refactor/changes/2026-09-14-MOD-PLUGIN-01-scaffold.md",
"refactor/baselines/scaffold-validation.json",
"test/plugin-scaffold.test.js"
],
"compatibleResolution": "Keep valid CLI and package/global/example names; reject existing outputs and generate the README from the actual example name.",
"closureCriteria": "Reproduce both historical defects and verify candidate collision/rollback behavior and a built typed package.",
"resolutionEvidence": [
"refactor/changes/2026-09-14-MOD-PLUGIN-01-scaffold.md",
"refactor/baselines/scaffold-validation.json",
"test/plugin-scaffold.test.js"
],
"resolutionRationale": "Frozen old generator reproduces overwrite and mismatched URL. Candidate refuses old or concurrent output, preserves external edits on rollback, generates matching dotted URLs and passes actual three-format package consumers and strict types."
}
]
}
+22 -1
View File
@@ -4427,6 +4427,26 @@
"acceptance": "Node 测试仍通过;安装与资源一致才决定采用;不改 bundler;不自动替换默认 packageManager 或维护锁文件",
"evidence": []
},
{
"id": "MOD-PLUGIN-01",
"phase": "7 工具链与性能",
"title": "迁移插件生成器与类型化模板",
"scope": [
"workspace"
],
"dependsOn": [
"ENG-06",
"SITE-03"
],
"status": "done",
"risk": "M",
"deliverable": "保留 create:plugin CLI;纯渲染/文件发布边界、TS 工厂/声明/测试/示例及维护指南",
"acceptance": "防止覆盖现有包或示例;失败回退;生成包可构建并通过严格类型、旧模块消费及测试;不自动修改既有包或运行安装发布",
"evidence": [
"changes/2026-09-14-MOD-PLUGIN-01-scaffold.md",
"baselines/scaffold-validation.json"
]
},
{
"id": "MOD-02",
"phase": "7 工具链与性能",
@@ -4436,7 +4456,8 @@
],
"dependsOn": [
"ENG-06",
"SITE-03"
"SITE-03",
"MOD-PLUGIN-01"
],
"status": "todo",
"risk": "M",
+5
View File
@@ -1,5 +1,10 @@
# 已实现的类型检查与迁移入口
`yarn typecheck:scaffold` 检查 scripts/plugin 的严格 TS 模块及旧 JS 命令入口。
模板本身保留占位符,`yarn test:scaffold` 对实际渲染包执行源码检查和
TS 5.9.3 NodeNext / TS 4.3.5 classic 消费者正反例;生成声明地图见
[插件生成器维护指南](../scripts/plugin/README.md)。
PKG-ADS-04 已协调公开声明:根入口保留历史输入,/runtime 使用准确输入,同一 JS
实现不进行字符串时长转换。CJS/ESM 桥、五种消费者模式、实际旧声明对照与真实 Monaco
生成运行已接入。`ads-source.ts` 检查源码与公开工厂的赋值关系;`ads.ts` 包含十个