docs(site): [SITE-01] inventory sources and reconcile demo coverage

This commit is contained in:
Harvey Zhao committed 2026-09-14 06:21:25 +08:00
1 parent d62ab13a35
commit d74ecc43cc
21 files changed
+22389 -56

No files matched your search

+2
View File
@@ -11,3 +11,5 @@ refactor/baselines/core-vendor/*.txt text eol=lf
refactor/baselines/thumbnail-vendor/* text eol=lf whitespace=-blank-at-eof
# Preserve the exact upstream WebVTT reference bytes, including license trailing lines.
refactor/baselines/multiple-subtitles-vendor/* text eol=lf whitespace=-blank-at-eof
# Preserve upstream documentation-site license bytes, including final blank lines.
refactor/baselines/site-vendor/*.txt text eol=lf whitespace=-blank-at-eof
+87
View File
@@ -0,0 +1,87 @@
# ArtPlayer documentation site
This workspace builds the static API documentation served at `/document/`.
The separate repository `docs/index.html` is the online player/editor; it is
not a VitePress page. Keep both URL surfaces compatible.
## Sources and generated files
| Source | Responsibility | Output or consumer |
| --- | --- | --- |
| `docs/index.md`, `docs/start`, `docs/component`, `docs/advanced` | Chinese API documentation | `/document/` |
| `docs/en` | English counterparts | `/document/en/` |
| `docs/plugin/danmuku.md` | Dedicated Chinese Danmuku guide | `/document/plugin/danmuku.html` |
| `docs/.vitepress/config.js` | Navigation, base URL, output path, page head | Repository `docs/document/` |
| `docs/vite.config.ts` | Search plugin configuration | VitePress/Vite integration; real search acceptance remains pending |
| `docs/public/main.js` | Run Code links and first-visit language redirect | Copied into the built site |
| `docs/public/style.css` | Documentation presentation | Copied into the built site |
Edit Markdown and public sources here. Do not edit the generated repository
`docs/document/`. The current inventory contains 27 Markdown pages: 14 Chinese
and 13 English. Danmuku has no English counterpart yet. Other plugins currently
use their package README, architecture notes and linked editor examples;
navigation links alone are not complete API documentation.
## Related tooling
Run commands from the repository root with its pinned Node version and Yarn
Classic 1.22.22. Maintain the root lockfile only.
```sh
yarn workspace artplayer-vitepress dev
yarn build:docs
yarn workspace artplayer-vitepress preview
node refactor/scripts/site-inventory.mjs --check
```
`build:docs` currently delegates through `npm run build` to this workspace's
VitePress script. This does not install dependencies or create another lockfile;
the command orchestration will be modernized in SITE-03.
The repository generators have different ownership:
- `scripts/build-types.mjs`: core public declaration sources to existing `types/`.
- `scripts/build-ts.js`: standalone editor declarations and the editor library list.
- `scripts/build-test.js`: extracts Chinese Run Code blocks into `docs/test/test.js`.
It is currently a smoke generator with a fixed 100 ms completion delay, not
proof of asynchronous playback or plugin success. SITE-02 owns its replacement.
- `scripts/build-i18n.js`: core language source bundles and copies to `docs/compiled/i18n/`.
- `scripts/build-docs.js`: this VitePress build.
- `scripts/build-llm.js` and `scripts/trans-docs.js`: explicit remote DeepSeek
operations, with a required key. They are not part of `ci:build` or `build:all`.
Do not invoke them just to inspect or regenerate local documentation.
## Browser boundaries and ownership
The editor's `prod` choice is stored in localStorage and changes the core script
only. The `libs` query still selects plugin scripts independently. `example`
takes precedence over `code`. Editor Run dispatches the example cleanup event,
destroys existing players, then evaluates the code. Preserve these contracts
when moving its JS to TypeScript; use an isolated origin for automated tests.
The mobile page preserves the query during redirect but has its own loader and
uses the development core. The ESM, i18n, iframe and generated smoke pages each
have separate dependencies. See the repository
[site inventory](../../refactor/site-inventory.md) for the full entrypoint map,
source fingerprints, asset provenance and assigned follow-up work.
`main.js` installs one document click listener under `window['run-code-init']`;
its lifetime is the page. Run Code opens the separate editor. The development
hostname check is currently exactly `localhost`; `127.0.0.1` follows the remote
link path. The language redirect writes `lang-init` and can navigate to the
English root on a first non-Chinese visit. SITE-03/SITE-05 must test these paths
before modifying routing or VitePress client lifecycle behavior.
## Delivery and remaining acceptance
`scripts/projects.js` excludes this workspace from the 21 library builds.
VitePress emits the static site, and the Pages workflow deploys the validated
repository `docs/` artifact. The manifest currently has neither library
entrypoints nor `private: true`; that absence is not npm publication intent.
REL-01 must explicitly classify its release handling. Its independent planned
major still advances from 1.1.0 to 2.0.0 under the agreed version policy.
SITE-02/03 own generators and browser source organization; SITE-04 owns bilingual
API completeness; SITE-05 owns build, links and real search; SITE-07 owns vendor
provenance and distribution notices; EX-03 owns complete demo execution. Three
release review rounds and remote CI/Pages evidence remain separate requirements.
+14
View File
@@ -0,0 +1,14 @@
{
"schemaVersion": 1,
"note": "Append-only additions to BASE-04. This records path ownership, not browser acceptance; the original 29-example snapshot remains unchanged.",
"examples": [
{
"source": "docs/assets/example/asr.local.js",
"route": "/?libs=./uncompiled/artplayer-plugin-asr/index.js&example=asr.local",
"introducedBy": "2cede66933e92b253bab4b3b2502f0268b22b087",
"owner": "PKG-ASR-05",
"finalDemoOwner": "EX-03",
"note": "Local audio capture demo with simulated subtitles; does not contact a recognition service. No menu link. Runtime evidence remains with the owning task."
}
]
}
@@ -0,0 +1,61 @@
{
"task": "SITE-01",
"node": "v24.21.0",
"baseline": "d62ab13a35c756ea567c426d4fbe00d893dd7e2b",
"targeted": {
"command": "node --test refactor/scripts/demos.test.mjs refactor/scripts/site-inventory.test.mjs",
"pass": 3,
"fail": 0,
"log": "refactor/.cache/site-tests.log",
"sha256": "ae5aca5e96da5e5a1f9ef9db81c510b4d64ed0497cb2ebe856b33e267bccc85f"
},
"before": {
"pass": 0,
"fail": 1,
"reason": "Demo file coverage drift: missing asr.local.js",
"log": "refactor/.cache/site-demo-before.log",
"sha256": "1fdf244c9783a10c8ae70fccc4d932d3999e1f76a0bc8ad51734b79ac60b957d"
},
"scriptExtraction": {
"pages": 36,
"oldRegexEqualsCurrent": true
},
"targetedLint": {
"exitCode": 0,
"log": "refactor/.cache/site-lint.log"
},
"fullBaseline": {
"command": "yarn test:baseline",
"exitCode": 0,
"pass": 517,
"fail": 0,
"skipped": 0,
"durationMs": 129550.3754,
"log": "refactor/.cache/site-baseline-suite.log",
"sha256": "3fa91c86eecc5a473761accfeb754f0935eff5a621370b031155e3a7030564d5"
},
"browserRun": false,
"remoteCiRun": false,
"rootLint": {
"exitCode": 0,
"errors": 0,
"existingWarnings": 1,
"log": "refactor/.cache/site-root-lint.log",
"sha256": "2eb55dab2763460e909607f1a17426503877eb50ae9ff4fba24d451364c16092"
},
"strictToolchain": {
"exitCode": 0,
"log": "refactor/.cache/site-toolchain.log",
"sha256": "96a2f051474efb8ac032f71a077401dad8a7fdc166fdf11498da8a9aaccadfc7"
},
"sourceInputs": {
"refactor/scripts/site-inventory.mjs": "aa748b5c0b4a62e15220b8427fab6bbbd616cc7a5ea53be3c71e9a5630c8a184",
"refactor/scripts/site-provenance.mjs": "f92eccfd9fcdd17632c6ba03ad77dec9b55a1e9a0e696a6f155ad8ccbbb40513",
"refactor/scripts/site-inventory.test.mjs": "4b6c4095697396798491b0aba09924de57490095c58c255834b319d8a7d1fbc1",
"refactor/scripts/demos.mjs": "4b9e2cfd6292b9048ca7c61160fcda0f4fcd166039801aa2b853842cfad2ff3a",
"refactor/scripts/demos.test.mjs": "55a16dc5d8037d14ea8041bb55b43bd5b6b9710c4c9f3ed1a3906473ee123e47",
"refactor/site-inventory.md": "392b7021bdabcfa1aba671d748b4c4df260c7fd2e5cc1c0c0d64c52572dea62a",
"packages/artplayer-vitepress/README.md": "621b2680fa00a3761eb5145e1bec346c196e2fc5afe0643d301216e90b9545ee"
},
"note": "Logs and hashes describe this local run. No runtime assets, dependency lock or consumer declarations changed; no package build/browser/remote workflow acceptance is inferred."
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 - present Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,259 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
This project incorporates components from the projects listed below. The original copyright notices and the licenses
under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted
herein, whether by implication, estoppel or otherwise.
%% nodejs path library (https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158)
=========================================
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF nodejs path library NOTICES AND INFORMATION
%% markedjs NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/)
Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=========================================
END OF markedjs NOTICES AND INFORMATION
%% typescript version 2.7.2 (https://github.com/Microsoft/TypeScript)
=========================================
Copyright (c) Microsoft Corporation. All rights reserved.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================
END OF typescript NOTICES AND INFORMATION
%% HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
=========================================
Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). This software or document includes material copied
from or derived from HTML 5.1 W3C Working Draft (http://www.w3.org/TR/2015/WD-html51-20151008/.)
THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF
THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY
PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE
DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.
The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to this document or its contents
without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders.
=========================================
END OF HTML 5.1 W3C Working Draft NOTICES AND INFORMATION
%% JS Beautifier version 1.6.2 (https://github.com/beautify-web/js-beautify)
=========================================
The MIT License (MIT)
Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF js-beautify NOTICES AND INFORMATION
%% Ionic documentation version 1.2.4 (https://github.com/driftyco/ionic-site)
=========================================
Copyright Drifty Co. http://drifty.com/.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================
END OF Ionic documentation NOTICES AND INFORMATION
%% vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
=========================================
The MIT License (MIT)
Copyright (c) 2015 David Owens II
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF vscode-swift NOTICES AND INFORMATION
@@ -0,0 +1,9 @@
Tencent is pleased to support the open source community by making vConsole available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
If you have downloaded a copy of the vConsole binary from Tencent, please note that the vConsole binary is licensed under the MIT License.
If you have downloaded a copy of the vConsole source code from Tencent, please note that vConsole source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of vConsole into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within vConsole.
A copy of the MIT License is included in this file.
@@ -0,0 +1,57 @@
# SITE-01 文档/示例/生成链清点
起点 `d62ab13a35c756ea567c426d4fbe00d893dd7e2b`。本任务建立可重跑的当前清单、
核实静态资产来源,并修复示例路径台账漂移。没有修改生产包 API、声明、DOM、
播放器生命周期、静态资源内容、版本或发布入口。
## 实现与维护
- site-inventory.mjs 复用现有 demo 枚举,使用已安装 MarkdownIt 14.1.0 和
TypeScript 5.9.3 枚举文档标题/声明成员;记录 22 包、27 Markdown、30 示例、
36 HTML、963 声明成员和 204 资产。成员可能重载/继承/含 runtime 类型,
标题候选不是语义通过证明;逐项保留 SITE-04 owner。
- site-provenance.mjs 显式 --network 下载三个固定版本,验证 SHA-512/SHA-1,
只读归档,按文件与本地比较。网络失败直接失败,不回退缓存或执行安装脚本。
下载和读取复用现有 releases 工具;浏览器验证不是该脚本的职责。
- 文档站新增 README,解释 VitePress/编辑器分工、源与生成目录、语言路由、
生命周期、Yarn 命令、外部生成步骤和站点分发边界。
- 无新依赖或锁变更;新增脚本是维护检查入口,不加入产品页面。
- site-vendor 原始 notice 文本固定 LF,并仅对该取证目录允许上游末尾空行,
防止 Windows checkout 改变冻结字节;不删改许可证原文来通过 whitespace 检查。
## 已复现问题
原 demos.test.mjs 因 asr.local.js 不在 BASE-04 中失败,错误是 Demo file coverage
drift。该示例已由 PKG-ASR-05 提交引入。保留原 29 示例快照,增添有完整提交、
路由和 owner 的 demo-additions.json。验证合并后的完整集合,仍拒绝未登记新增、
旧路径丢失和菜单/包遗漏。额外反例拒绝重复登记、错误路由、未知 owner、越界路径、
缺来源提交;没有通过删断言或全量重写历史快照解决。
触及旧脚本时修正 lint 指出的 process import 和 script src regex 的冗余零下界;
后者仍要求 script 与 src 间至少一个属性分隔字符。脚本外部接口不变。
一次 ESLint 写文件返回 UNKNOWN,确认文件完整后单独重试成功;测试文件的 node:test
采用与仓库其它基线测试相同的定向规则说明,不引入 Vitest 或更换实际测试 runner。
## 来源与未完成事项
详见 [清单说明](../site-inventory.md) 与 [冻结证据](../baselines/site-provenance.json)。
vConsole 3.15.0 字节一致;Monaco 0.30.1 的 98/99 字节一致,余下 CSS 仅换行差异。
本次取得原始 LICENSE/ThirdPartyNotices,保存在 refactor 取证目录,分发装配归 SITE-07。
console bundle 源码与组件完整版本、6 字体授权依据和样本来源仍开放。
thumbnail 示例与 npm 1.0.3 实际 VTT 实现/声明不一致,不能直接替换成 auto-thumbnail。
EX-03 接续旧 URL 的修复与迁移解释。原 36 HTML 路径全部保留;文档站静态部署与
缺 private 字段分开记录,REL-01 需显式发布分类,不能从缺字段推断 npm 发布意图。
新增 SITE-07 作为 SITE-05 前置,承接 notices/资产处置;加强 SITE-02 的坏代码块
终止反例、SITE-03 的移动失败恢复/加载顺序/路由验证,以及 SITE-04 的双语成员覆盖。
相关风险仍为 open,没有把清点视为发布接受或虚构免验。
## 验证与回退
最终命令和结果见 [验证记录](../baselines/site-inventory-validation.json)。定向检查包括
真实当前清单、历史加增量的路径校验、错误输入反例、目标 lint、计划和风险登记。
不需要重建生产 dist;没有运行播放器实播、完整文档构建、远端 CI/Pages/npm。
回退 SITE-01 提交恢复旧检查器和任务/清单;生产行为无需数据迁移。
后续从 SITE-02 的声明/示例生成器开始,SITE-07 独立处置第三方分发来源。
+11 -8
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 238 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 239 项,范围 22 个包及工作区/示例。
状态:todo 60 / doing 15 / blocked 0 / done 163 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 60 / doing 15 / blocked 0 / done 164 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -35,7 +35,7 @@
| artplayer-proxy-mediabunny | 1.2.0 | PKG-MB-01, PKG-MB-02, PKG-MB-03, PKG-MB-04, PKG-MB-05, PKG-MB-06, PKG-MB-07, PKG-MB-08, PKG-MB-09, PKG-MB-10 |
| artplayer-tool-iframe | 1.1.0 | PKG-IFRAME-01, PKG-IFRAME-02, PKG-IFRAME-03, PKG-IFRAME-04, PKG-IFRAME-05, PKG-IFRAME-06 |
| artplayer-tool-thumbnail | 4.4.0 | PKG-TOOL-THUMB-01, PKG-TOOL-THUMB-02, PKG-TOOL-THUMB-03, PKG-TOOL-THUMB-04, PKG-TOOL-THUMB-05, PKG-TOOL-THUMB-06 |
| artplayer-vitepress | 1.1.0 | SITE-01, SITE-02, SITE-03, SITE-04, SITE-05, SITE-06 |
| artplayer-vitepress | 1.1.0 | SITE-01, SITE-02, SITE-03, SITE-04, SITE-05, SITE-06, SITE-07 |
## 0 规划
@@ -380,12 +380,13 @@
| ID | 范围 / 步骤 | 前置依赖 | 交付物 | 验收条件 | 风险 | 状态 |
| --- | --- | --- | --- | --- | --- | --- |
| SITE-01 | artplayer-vitepress<br>清点文档/示例/生成链 | BASE-04, BASE-05 | 中英文文档、插件页面、demo URL、编辑器声明与生成目录清单;六类 HTML 入口、prod/libs/code/example 加载行为及移动重定向 | 所有公开 API/插件有对应页面或明确补充任务;核实 BASE-DEMO-01 的历史 thumbnail 插件来源及 29 示例/36 HTML 路径;明确 BASE-05 所记录站点实际分发与未设 private 的 manifest 意图;接续 VENDOR-05/06/07/08 和 BASE-SITE-01/BASE-MEDIA-01,核对字体、Monaco、vConsole、console bundle 与样本来源及分发范围 | M | todo |
| SITE-02 | artplayer-vitepress<br>整理声明与示例生成器 | SITE-01, ENG-04, ENG-06 | build-ts/build-test 生成链的可验证 TS 脚本 | 不靠字符串拼接掩盖声明错误,生成示例有真实断言或仅标 smoke;替换固定 100ms 成功判定,明确异步错误、清理和生成覆盖限制 | M | todo |
| SITE-03 | artplayer-vitepress<br>整理 i18n/文档/LLM 生成流程 | SITE-02 | build-i18n/build-docs/build-llm/trans-docs 的任务边界和错误处理 | 原命令兼容、生成可复现,翻译步骤不隐式运行远程服务 | M | todo |
| SITE-04 | artplayer-vitepress<br>交叉核对逐包持续维护的文档 | CORE-21, SITE-03, PKG-CHAPTER-04, PKG-AMBILIGHT-04, PKG-AUDIO-04, PKG-AUTO-THUMB-04, PKG-VTT-THUMB-04, PKG-HLS-04, PKG-DASH-04, PKG-MULTI-SUB-04, PKG-JASSUB-04, PKG-MASK-04, PKG-ASR-04, PKG-ADS-04, PKG-VAST-04, PKG-CAST-04, PKG-DPIP-04, PKG-CANVAS-04, PKG-IFRAME-04, PKG-TOOL-THUMB-04, PKG-DANMUKU-06, PKG-MB-08 | 已随实现更新的中文/英文 API、包内实现地图、旧 JS 示例及已知能力限制的全包核对 | 未把缺环境的能力写成已验证,静态核对不等待设备任务;最终 demo 仍由 EX-03 验收 | M | todo |
| SITE-05 | artplayer-vitepress<br>构建文档站和验证链接/示例 | SITE-04, EX-01, EX-02 | VitePress 构建、链接与嵌入 demo 检查 | 文档构建、链接、嵌入路径与声明注入通过;真实完整 demo 保留 EX-03 独立门槛;核对 ENG-PM-01 登记的搜索 peer 范围和真实搜索行为 | M | todo |
| SITE-01 | artplayer-vitepress, workspace<br>清点文档/示例/生成链 | BASE-04, BASE-05 | 中英文文档、插件页面、demo URL、编辑器声明与生成目录清单;六类 HTML 入口、prod/libs/code/example 加载行为及移动重定向 | 所有公开 API/插件有对应页面或明确补充任务;核实 BASE-DEMO-01 的历史 thumbnail 插件来源及 29 示例/36 HTML 路径;明确 BASE-05 所记录站点实际分发与未设 private 的 manifest 意图;接续 VENDOR-05/06/07/08 和 BASE-SITE-01/BASE-MEDIA-01,核对字体、Monaco、vConsole、console bundle 与样本来源及分发范围 | M | done |
| SITE-02 | artplayer-vitepress<br>整理声明与示例生成器 | SITE-01, ENG-04, ENG-06 | build-ts/build-test 生成链的可验证 TS 脚本 | 不靠字符串拼接掩盖声明错误,生成示例有真实断言或仅标 smoke;替换固定 100ms 成功判定,明确异步错误、清理和生成覆盖限制;坏代码块解析必须终止,覆盖 malformed 分支不推进 regexp 的回归 | M | todo |
| SITE-03 | artplayer-vitepress<br>整理 i18n/文档/LLM 生成流程 | SITE-02 | build-i18n/build-docs/build-llm/trans-docs 的任务边界和错误处理 | 原命令兼容、生成可复现,翻译步骤不隐式运行远程服务;覆盖移动 loader 失败恢复 define、脚本依赖顺序、localhost/127.0.0.1 Run Code 目标和语言重定向 | M | todo |
| SITE-04 | artplayer-vitepress<br>交叉核对逐包持续维护的文档 | CORE-21, SITE-03, PKG-CHAPTER-04, PKG-AMBILIGHT-04, PKG-AUDIO-04, PKG-AUTO-THUMB-04, PKG-VTT-THUMB-04, PKG-HLS-04, PKG-DASH-04, PKG-MULTI-SUB-04, PKG-JASSUB-04, PKG-MASK-04, PKG-ASR-04, PKG-ADS-04, PKG-VAST-04, PKG-CAST-04, PKG-DPIP-04, PKG-CANVAS-04, PKG-IFRAME-04, PKG-TOOL-THUMB-04, PKG-DANMUKU-06, PKG-MB-08 | 已随实现更新的中文/英文 API、包内实现地图、旧 JS 示例及已知能力限制的全包核对 | 未把缺环境的能力写成已验证,静态核对不等待设备任务;最终 demo 仍由 EX-03 验收;按 SITE-01 声明成员/候选标题清单逐项语义核对,补齐缺失的双语插件说明和 Danmuku 英文入口 | M | todo |
| SITE-05 | artplayer-vitepress<br>构建文档站和验证链接/示例 | SITE-04, EX-01, EX-02, SITE-07 | VitePress 构建、链接与嵌入 demo 检查 | 文档构建、链接、嵌入路径与声明注入通过;真实完整 demo 保留 EX-03 独立门槛;核对 ENG-PM-01 登记的搜索 peer 范围和真实搜索行为 | M | todo |
| SITE-06 | artplayer-vitepress<br>文档站交付验收 | SITE-05 | 维护指南和站点变更记录 | 未手改 generated 目录,旧 URL 可用、部署与检查分离 | M | todo |
| SITE-07 | artplayer-vitepress, workspace<br>整理站点第三方资产与来源说明 | SITE-01 | Monaco/vConsole/console bundle/字体和样本的冻结来源、可复现构建或替代与站点 notices | 接续 SITE-01 的字节与换行差异证据;完整许可随实际分发,consoleLog/global/CSS/worker 与旧 URL 兼容;缺字体/媒体使用依据明确处置;资产变更后执行编辑器/移动/字幕/示例回归,不以来源指纹替代授权或运行证据 | H | todo |
| EX-01 | example/react.js, workspace<br>验证 React 消费者与 TS | CORE-22, ENG-07 | React 挂载/卸载/重挂载、引用和插件样例 | 真实 tarball + TS 消费通过,保留既有 React 集成 API | M | done |
| EX-02 | example/vue.js, workspace<br>验证 Vue 消费者与更新卸载 | CORE-22, ENG-07 | Vue 实例/ref、参数更新、卸载及插件样例 | 旧 JS 组件用法无需修改,重复挂载不泄漏 | M | done |
| EX-03 | workspace<br>验证全部原生 demo 与外部播放集成 | EX-01, EX-02, PKG-CHAPTER-06, PKG-AMBILIGHT-06, PKG-AUDIO-06, PKG-AUTO-THUMB-06, PKG-VTT-THUMB-06, PKG-HLS-06, PKG-DASH-06, PKG-MULTI-SUB-06, PKG-JASSUB-06, PKG-MASK-06, PKG-ASR-06, PKG-ADS-06, PKG-VAST-06, PKG-CAST-06, PKG-DPIP-06, PKG-DANMUKU-09, PKG-CANVAS-06, PKG-MB-10, PKG-IFRAME-06, PKG-TOOL-THUMB-06 | 8082 全 demo、HLS/DASH/FLV/MPEGTS/WebTorrent 集成记录 | 旧 URL/参数/脚本加载保持;网络/SDK 限制明确,不静默跳过;覆盖编辑器重复 Run 和 ESM/i18n/mobile/iframe,记录实际候选脚本及状态隔离证据;依据 BASE-04 路径台账逐项消除 not-run,处理 BASE-DEMO-01 | H | todo |
@@ -604,6 +605,8 @@
- PKG-TOOL-THUMB-02: [记录](baselines/thumbnail-behavior-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-02-behavior.md)
- PKG-TOOL-THUMB-03: [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-input-checkpoint.md) [记录](baselines/thumbnail-input-checkpoint.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-lifecycle.md) [记录](baselines/thumbnail-lifecycle-validation.json)
- PKG-TOOL-THUMB-04: [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-runtime-types.md) [记录](baselines/thumbnail-runtime-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-public-types.md) [记录](baselines/thumbnail-public-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-emitter.md) [记录](baselines/thumbnail-emitter-validation.json)
- SITE-01: [记录](site-inventory.md) [记录](baselines/site-inventory.json) [记录](baselines/site-provenance.json) [记录](baselines/demo-additions.json) [记录](changes/2026-09-14-SITE-01-site-inventory.md) [记录](baselines/site-inventory-validation.json)
- 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)
- 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)
+16
View File
@@ -1,5 +1,21 @@
# 进度与证据
## SITE-01 文档/示例/生成链清点完成
建立当前 22 包、27 Markdown、30 示例、36 HTML、963 声明成员和 204 资产
的可重跑清单。增加文档站维护地图;核对六类执行 HTML、查询/存储/移动加载、
声明注入和生成链。修复 BASE-04 漏登记 asr.local.js 导致的真实路径校验失败,
保留历史快照并用有提交来源的增量记录覆盖新增路径。固定 npm 对照确认 vConsole
3.15.0 字节一致,Monaco 0.30.1 的 98/99 字节一致、余下 CSS 仅换行不同;
取得 notices,console bundle/字体/样本和历史 thumbnail 差异仍需处置。新增
SITE-07 接续资产/notice 并成为 SITE-05 前置。517 项完整基线测试无失败/跳过,
目标和根 lint(0 error/1 既有 warning)、严格工具链、清单/计划/风险校验通过。
见[变更](changes/2026-09-14-SITE-01-site-inventory.md)、[清单](site-inventory.md)
和[验证](baselines/site-inventory-validation.json)。没有执行实播、完整站点构建或
远端 CI/部署;来源指纹与标题候选不作为授权/语义/发布通过。当前 239 项:
164 done、15 doing、60 todo。下一步 SITE-02 声明/示例生成器;VAST 兼容选择和
Auto Thumbnail 首帧仍开放。
## EX-02 Vue 消费者完成
Vue 示例入口和配置职责完成 TS 整理;保留挂载时读取 option、原 getInstance
+5 -5
View File
@@ -24,15 +24,15 @@
| BASE-SOURCE-01 | open / 源码/产物事实 | 工作区 5.4.1 与采集时真实发布 5.4.0 不同 | BASE-08, REL-01 |
| BASE-SOURCE-02 | open / 源码/产物事实 | registry gitHead 与发布包版本对应不可靠 | ENG-07, REL-01 |
| BASE-SITE-01 | open / 源码/产物事实 | 文档站实际为静态站点但 manifest 未设 private | SITE-01, REL-01 |
| BASE-MEDIA-01 | open / 待取证 | 示例媒体和字体的完整来源/授权链待核实 | BASE-08, SITE-01, EX-03 |
| BASE-MEDIA-01 | open / 待取证 | 示例媒体和字体的完整来源/授权链待核实 | BASE-08, SITE-01, EX-03, SITE-07 |
| VENDOR-01 | resolved / 源码/产物事实 | screenfull 来源、版本与许可闭环 | CORE-12 |
| VENDOR-02 | resolved / 源码/产物事实 | hint.css 来源、版本与许可闭环 | CORE-12 |
| VENDOR-03 | resolved / 已复现 | webvtt-parser 来源、版本与许可闭环 | PKG-MULTI-SUB-01 |
| VENDOR-04 | open / 源码/产物事实 | jassub-code-and-workers 来源、版本与许可闭环 | PKG-JASSUB-01, PKG-JASSUB-06 |
| VENDOR-05 | open / 源码/产物事实 | jassub-font-assets 来源、版本与许可闭环 | PKG-JASSUB-01, SITE-01, PKG-JASSUB-06 |
| VENDOR-06 | open / 待取证 | monaco-static-assets 来源、版本与许可闭环 | SITE-01, SITE-05 |
| VENDOR-07 | open / 待取证 | vconsole 来源、版本与许可闭环 | SITE-01 |
| VENDOR-08 | open / 待取证 | console-bundle 来源、版本与许可闭环 | SITE-01 |
| VENDOR-05 | open / 源码/产物事实 | jassub-font-assets 来源、版本与许可闭环 | PKG-JASSUB-01, SITE-01, PKG-JASSUB-06, SITE-07 |
| VENDOR-06 | open / 源码/产物事实 | monaco-static-assets 来源、版本与许可闭环 | SITE-01, SITE-05, SITE-07 |
| VENDOR-07 | open / 源码/产物事实 | vconsole 来源、版本与许可闭环 | SITE-01, SITE-07 |
| VENDOR-08 | open / 待取证 | console-bundle 来源、版本与许可闭环 | SITE-01, SITE-07 |
| SDK-01 | open / 源码/产物事实 | hls.js 实际集成验证范围 | PKG-HLS-05, EX-03 |
| SDK-02 | open / 待取证 | dash.js 实际集成验证范围 | PKG-DASH-01, EX-03, PKG-DASH-05 |
| SDK-03 | open / 待取证 | flv.js 实际集成验证范围 | EX-03 |
+31 -14
View File
@@ -249,7 +249,8 @@
],
"evidence": [
"docs/assets/example/thumbnail.js",
"refactor/baselines/demo-inventory.json"
"refactor/baselines/demo-inventory.json",
"refactor/site-inventory.md"
],
"compatibleResolution": "核实旧外部插件和链接,不自动替换为不同 API 的 auto-thumbnail。",
"closureCriteria": "示例依赖有来源,旧参数/URL 的保留或迁移解释完整。"
@@ -440,7 +441,8 @@
"REL-01"
],
"evidence": [
"refactor/baselines/distribution.json"
"refactor/baselines/distribution.json",
"refactor/site-inventory.md"
],
"compatibleResolution": "区分站点部署和库 npm 发布;自身 next-major 要求保留。",
"closureCriteria": "发布流程显式列出站点处理方式,不机械将其当库发布。"
@@ -453,11 +455,14 @@
"owners": [
"BASE-08",
"SITE-01",
"EX-03"
"EX-03",
"SITE-07"
],
"evidence": [
"docs/assets/sample",
"docs/assets/jassub"
"docs/assets/jassub",
"refactor/site-inventory.md",
"refactor/baselines/site-provenance.json"
],
"compatibleResolution": "复用现有样本时记录来源;缺许可的公开分发样本需补证据或可兼容替代,不能从文件名猜授权。",
"closureCriteria": "候选实际分发样本有来源、许可/使用依据和测试映射。"
@@ -569,7 +574,8 @@
"owners": [
"PKG-JASSUB-01",
"SITE-01",
"PKG-JASSUB-06"
"PKG-JASSUB-06",
"SITE-07"
],
"evidence": [
"refactor/third-party.json",
@@ -583,7 +589,9 @@
"refactor/changes/2026-09-13-PKG-JASSUB-01-baseline.md",
"refactor/baselines/jassub-provenance.json",
"refactor/baselines/jassub-provenance-validation.json",
"refactor/changes/2026-09-14-PKG-JASSUB-01-provenance.md"
"refactor/changes/2026-09-14-PKG-JASSUB-01-provenance.md",
"refactor/site-inventory.md",
"refactor/baselines/site-provenance.json"
],
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。"
@@ -591,15 +599,18 @@
{
"id": "VENDOR-06",
"title": "monaco-static-assets 来源、版本与许可闭环",
"confirmation": "unverified",
"confirmation": "source-observed",
"status": "open",
"owners": [
"SITE-01",
"SITE-05"
"SITE-05",
"SITE-07"
],
"evidence": [
"refactor/third-party.json",
"docs/assets/js/vs"
"docs/assets/js/vs",
"refactor/site-inventory.md",
"refactor/baselines/site-provenance.json"
],
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。"
@@ -607,14 +618,17 @@
{
"id": "VENDOR-07",
"title": "vconsole 来源、版本与许可闭环",
"confirmation": "unverified",
"confirmation": "source-observed",
"status": "open",
"owners": [
"SITE-01"
"SITE-01",
"SITE-07"
],
"evidence": [
"refactor/third-party.json",
"docs/assets/js/vconsole.min.js"
"docs/assets/js/vconsole.min.js",
"refactor/site-inventory.md",
"refactor/baselines/site-provenance.json"
],
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。"
@@ -625,11 +639,14 @@
"confirmation": "unverified",
"status": "open",
"owners": [
"SITE-01"
"SITE-01",
"SITE-07"
],
"evidence": [
"refactor/third-party.json",
"docs/assets/js/console.js"
"docs/assets/js/console.js",
"refactor/site-inventory.md",
"refactor/baselines/site-provenance.json"
],
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。"
+27 -22
View File
@@ -1,15 +1,17 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { hash, refactorDir } from './releases.mjs'
const root = path.resolve(refactorDir, '..')
const read = name => fs.readFileSync(path.join(root, name), 'utf8').replaceAll('\r\n', '\n')
function htmlFiles(dir = 'docs') {
return fs.readdirSync(path.join(root, dir), { withFileTypes: true }).flatMap(entry => {
return fs.readdirSync(path.join(root, dir), { withFileTypes: true }).flatMap((entry) => {
const name = `${dir}/${entry.name}`
if (entry.isDirectory()) return ['compiled', 'uncompiled', 'node_modules'].includes(entry.name) ? [] : htmlFiles(name)
if (entry.isDirectory())
return ['compiled', 'uncompiled', 'node_modules'].includes(entry.name) ? [] : htmlFiles(name)
return entry.name.endsWith('.html') ? [name] : []
}).sort()
}
@@ -19,38 +21,40 @@ function menuLinks() {
export function captureDemoInventory() {
const links = menuLinks()
const inventory = JSON.parse(read('refactor/package-inventory.json'))
const examples = fs.readdirSync(path.join(root, 'docs/assets/example')).filter(name => name.endsWith('.js')).sort().map(file => {
const examples = fs.readdirSync(path.join(root, 'docs/assets/example')).filter(name => name.endsWith('.js')).sort().map((file) => {
const name = file.slice(0, -3)
const source = `docs/assets/example/${file}`
const linked = links.filter(link => new URL(link, 'http://localhost:8082').searchParams.get('example') === name)
const libs = [...new Set(linked.flatMap(link => (new URL(link, 'http://localhost:8082').searchParams.get('libs') || '').split('\n').filter(Boolean)))]
return { name, source, sha256Lf: hash(read(source)), menuLinks: linked, route: linked[0] || `/?example=${name}`, libs,
status: 'not-run', owner: 'EX-03',
note: name === 'thumbnail' ? 'References artplayer-plugin-thumbnail, which is absent from the 22 current workspace packages; dependency and route need reconciliation.' : linked.length ? 'Existing menu route; SDK and media loading have not been validated.' : 'No menu link; example route follows common.js loader. Required globals are not automatically loaded.' }
return { name, source, sha256Lf: hash(read(source)), menuLinks: linked, route: linked[0] || `/?example=${name}`, libs, status: 'not-run', owner: 'EX-03', note: name === 'thumbnail' ? 'References artplayer-plugin-thumbnail, which is absent from the 22 current workspace packages; dependency and route need reconciliation.' : linked.length ? 'Existing menu route; SDK and media loading have not been validated.' : 'No menu link; example route follows common.js loader. Required globals are not automatically loaded.' }
})
const pages = htmlFiles().map(source => {
const pages = htmlFiles().map((source) => {
const text = read(source)
const uncommented = text.replace(/<!--[\s\S]*?-->/g, '')
return { source, route: `/${source.slice(5)}`.replace(/index\.html$/, ''), sha256Lf: hash(text),
kind: source.startsWith('docs/document/') ? 'generated-docs' : source.includes('googlebc') ? 'site-verification' : source === 'docs/upscaler/index.html' ? 'standalone-tool' : 'demo-or-editor',
scriptSources: [...uncommented.matchAll(/<script\b[^>]*\bsrc=["']([^"']+)["']/g)].map(match => match[1]),
status: 'not-run', owner: source.includes('googlebc') ? 'SITE-01' : 'EX-03' }
return { source, route: `/${source.slice(5)}`.replace(/index\.html$/, ''), sha256Lf: hash(text), kind: source.startsWith('docs/document/') ? 'generated-docs' : source.includes('googlebc') ? 'site-verification' : source === 'docs/upscaler/index.html' ? 'standalone-tool' : 'demo-or-editor', scriptSources: [...uncommented.matchAll(/<script\b[^>]+\bsrc=["']([^"']+)["']/g)].map(match => match[1]), status: 'not-run', owner: source.includes('googlebc') ? 'SITE-01' : 'EX-03' }
})
return { schemaVersion: 1, task: 'BASE-04', sourceCommit: '94893929', capturedAt: new Date().toISOString(),
note: 'Historical source inventory, not browser or network evidence. ScriptSources excludes comments but does not resolve inline scripts, import maps or dynamic SDK loading. Hashes use LF and describe this capture; check validates coverage, not current content identity.',
examples, pages,
packages: inventory.packages.map(pkg => ({ name: pkg.name, examples: examples.filter(example => example.libs.some(lib => lib.includes(`/${pkg.name}/`))).map(example => example.name), status: 'not-run', owner: pkg.name === 'artplayer-vitepress' ? 'SITE-01' : 'EX-03' })),
editor: { source: 'docs/assets/js/common.js', sha256Lf: hash(read('docs/assets/js/common.js')), storage: ['prod', 'ts', 'code', 'log'], isolation: 'Use separate test origin; record keys, do not erase user browser data.', core: { prodTrue: './compiled/artplayer.js', otherwise: './uncompiled/artplayer/index.js' }, pluginSources: 'URL libs parameter; independent of prod toggle', execution: 'Run evaluates editor text; TS mode alone is not strict tsc validation.', runtimeStatus: 'not-run' },
}
return { schemaVersion: 1, task: 'BASE-04', sourceCommit: '94893929', capturedAt: new Date().toISOString(), note: 'Historical source inventory, not browser or network evidence. ScriptSources excludes comments but does not resolve inline scripts, import maps or dynamic SDK loading. Hashes use LF and describe this capture; check validates coverage, not current content identity.', examples, pages, packages: inventory.packages.map(pkg => ({ name: pkg.name, examples: examples.filter(example => example.libs.some(lib => lib.includes(`/${pkg.name}/`))).map(example => example.name), status: 'not-run', owner: pkg.name === 'artplayer-vitepress' ? 'SITE-01' : 'EX-03' })), editor: { source: 'docs/assets/js/common.js', sha256Lf: hash(read('docs/assets/js/common.js')), storage: ['prod', 'ts', 'code', 'log'], isolation: 'Use separate test origin; record keys, do not erase user browser data.', core: { prodTrue: './compiled/artplayer.js', otherwise: './uncompiled/artplayer/index.js' }, pluginSources: 'URL libs parameter; independent of prod toggle', execution: 'Run evaluates editor text; TS mode alone is not strict tsc validation.', runtimeStatus: 'not-run' } }
}
export function validateDemoInventory(inventory) {
export function validateDemoInventory(inventory, additions = JSON.parse(read('refactor/baselines/demo-additions.json'))) {
assert.equal(inventory.schemaVersion, 1)
assert.deepEqual(inventory.examples.map(item => item.source).sort(), fs.readdirSync(path.join(root, 'docs/assets/example')).filter(name => name.endsWith('.js')).map(name => `docs/assets/example/${name}`).sort(), 'Demo file coverage drift')
assert.equal(additions.schemaVersion, 1)
const taskIds = new Set(JSON.parse(read('refactor/tasks.json')).tasks.map(task => task.id))
for (const addition of additions.examples) {
assert(/^docs\/assets\/example\/[a-z0-9.]+\.js$/.test(addition.source), 'Invalid added example path')
assert(/^[a-f0-9]{40}$/.test(addition.introducedBy), 'Missing introduction commit')
assert(taskIds.has(addition.owner) && addition.finalDemoOwner === 'EX-03', 'Missing added example owner')
assert.equal(new URL(addition.route, 'http://localhost:8082').searchParams.get('example'), path.basename(addition.source, '.js'), 'Added route does not select its example')
}
const sources = [...inventory.examples, ...additions.examples].map(item => item.source)
assert.equal(new Set(sources).size, sources.length, 'Duplicate baseline/addition paths')
assert.deepEqual(sources.sort(), fs.readdirSync(path.join(root, 'docs/assets/example')).filter(name => name.endsWith('.js')).map(name => `docs/assets/example/${name}`).sort(), 'Demo file coverage drift')
assert.deepEqual(inventory.pages.map(item => item.source).sort(), htmlFiles(), 'HTML route coverage drift')
assert.deepEqual(inventory.examples.flatMap(item => item.menuLinks).sort(), menuLinks().sort(), 'Editor link coverage drift')
assert.deepEqual(inventory.packages.map(item => item.name).sort(), JSON.parse(read('refactor/package-inventory.json')).packages.map(item => item.name).sort(), 'Package demo coverage drift')
const names = new Set(inventory.examples.map(item => item.name))
for (const pkg of inventory.packages) for (const name of pkg.examples) assert(names.has(name), `Unknown example: ${name}`)
for (const pkg of inventory.packages) {
for (const name of pkg.examples) assert(names.has(name), `Unknown example: ${name}`)
}
assert(inventory.examples.find(item => item.name === 'thumbnail').note.includes('absent'), 'Missing historical plugin exception')
}
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
@@ -58,13 +62,14 @@ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.me
if (process.argv.includes('--capture')) {
assert(!fs.existsSync(filename), 'Do not overwrite the historical inventory; reconcile changes explicitly')
const inventory = captureDemoInventory()
validateDemoInventory(inventory)
validateDemoInventory(inventory, { schemaVersion: 1, examples: [] })
fs.writeFileSync(filename, `${JSON.stringify(inventory, null, 2)}\n`)
}
else {
assert(process.argv.slice(2).every(arg => arg === '--check'), 'Use --capture or --check')
const inventory = JSON.parse(fs.readFileSync(filename, 'utf8'))
validateDemoInventory(inventory)
console.log(`Demo coverage: ${inventory.examples.length} examples, ${inventory.pages.length} HTML paths, ${inventory.packages.length} packages; no browser pass implied`)
const additions = JSON.parse(read('refactor/baselines/demo-additions.json'))
console.log(`Demo coverage: ${inventory.examples.length} historical + ${additions.examples.length} added examples, ${inventory.pages.length} HTML paths, ${inventory.packages.length} packages; no browser pass implied`)
}
}
+18
View File
@@ -1,6 +1,7 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
// eslint-disable-next-line test/no-import-node-test -- Runs with the repository baseline node:test suite.
import test from 'node:test'
import { validateDemoInventory } from './demos.mjs'
import { refactorDir } from './releases.mjs'
@@ -19,3 +20,20 @@ test('Demo inventory rejects missing files, routes and ecosystem packages', () =
assert.throws(() => validateDemoInventory(changed))
}
})
test('Demo additions require complete paths, specific routes and task ownership', () => {
const inventory = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/demo-inventory.json'), 'utf8'))
const additions = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/demo-additions.json'), 'utf8'))
for (const mutate of [
value => value.examples.pop(),
value => value.examples.push(value.examples[0]),
value => value.examples[0].route = '/?example=index',
value => value.examples[0].owner = 'UNKNOWN-01',
value => value.examples[0].source = 'docs/assets/example/../example/asr.local.js',
value => value.examples[0].introducedBy = '',
]) {
const changed = structuredClone(additions)
mutate(changed)
assert.throws(() => validateDemoInventory(inventory, changed))
}
})
+106
View File
@@ -0,0 +1,106 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import MarkdownIt from 'markdown-it'
import ts from 'typescript'
import { captureDemoInventory } from './demos.mjs'
import { hash, refactorDir } from './releases.mjs'
const root = path.resolve(refactorDir, '..')
const filename = path.join(refactorDir, 'baselines/site-inventory.json')
const read = file => fs.readFileSync(path.join(root, file), 'utf8').replaceAll('\r\n', '\n')
const json = file => JSON.parse(read(file))
const markdown = new MarkdownIt({ html: true })
function files(dir) {
return fs.readdirSync(path.join(root, dir), { withFileTypes: true }).flatMap((entry) => {
const file = `${dir}/${entry.name}`
return entry.isDirectory() ? ['node_modules', '.vitepress', 'dist'].includes(entry.name) ? [] : files(file) : [file]
}).sort()
}
function headings(file) {
const tokens = markdown.parse(read(file), {})
return tokens.flatMap((token, index) => token.type === 'heading_open' ? [{ text: tokens[index + 1].content, line: token.map[0] + 1 }] : [])
}
function fingerprint(file) {
const bytes = fs.readFileSync(path.join(root, file))
return { file, bytes: bytes.length, sha256: hash(bytes) }
}
export function captureSiteInventory() {
const demo = captureDemoInventory()
const historical = json('refactor/baselines/demo-inventory.json')
const docs = files('packages/artplayer-vitepress/docs').filter(file => file.endsWith('.md')).map((file) => {
const relative = file.replace('packages/artplayer-vitepress/docs/', '')
const english = relative.startsWith('en/')
const peer = `packages/artplayer-vitepress/docs/${english ? relative.slice(3) : `en/${relative}`}`
return { file, sha256Lf: hash(read(file)), language: english ? 'en' : 'zh', route: `/document/${relative.replace(/index\.md$/, '').replace(/\.md$/, '.html')}`, headings: headings(file), runCodeMarkers: (read(file).match(/className="run-code"/g) || []).length, translation: fs.existsSync(path.join(root, peer)) ? peer : null, translationOwner: fs.existsSync(path.join(root, peer)) ? null : 'SITE-04' }
})
const api = files('packages/artplayer/public').filter(file => /\.ts$/.test(file)).flatMap((file) => {
const source = ts.createSourceFile(file, read(file), ts.ScriptTarget.Latest, true)
const rows = []
function visit(node) {
if ((ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) && node.name) {
const members = node.members || (ts.isTypeAliasDeclaration(node) && ts.isTypeLiteralNode(node.type) ? node.type.members : [])
for (const member of members) {
if (!member.name && !ts.isConstructSignatureDeclaration(member) && !ts.isConstructorDeclaration(member))
continue
const name = member.name?.getText(source).replace(/^['"]|['"]$/g, '') || 'constructor'
const matches = docs.flatMap(doc => doc.headings.filter(heading => heading.text.replaceAll('`', '').split(/[ .()]/).includes(name)).map(heading => ({ file: doc.file, line: heading.line })))
rows.push({ file, declaration: node.name.text, name, line: source.getLineAndCharacterOfPosition(member.getStart(source)).line + 1, candidateHeadings: matches, semanticReviewOwner: 'SITE-04' })
}
}
ts.forEachChild(node, visit)
}
visit(source)
return rows
})
const config = read('packages/artplayer-vitepress/docs/.vitepress/config.js')
const packages = json('refactor/package-inventory.json').packages.map((pkg) => {
const dir = `packages/${pkg.name}`
const readme = `${dir}/README.md`
const architecture = `${dir}/ARCHITECTURE.md`
const examples = demo.examples.filter(example => example.libs.some(lib => lib.includes(`/${pkg.name}/`))).map(example => example.name)
return { name: pkg.name, readme: fs.existsSync(path.join(root, readme)) ? readme : null, architecture: fs.existsSync(path.join(root, architecture)) ? architecture : null, examples, sidebarMentionsPackage: config.includes(pkg.name), dedicatedPages: pkg.name === 'artplayer' || pkg.name === 'artplayer-vitepress' ? docs.map(doc => doc.file) : docs.filter(doc => doc.file.endsWith(`/plugin/${pkg.name.replace('artplayer-plugin-', '')}.md`)).map(doc => doc.file), contentReviewOwner: 'SITE-04', demoExecutionOwner: 'EX-03' }
})
const scriptFiles = ['scripts/build-types.mjs', 'scripts/build-ts.js', 'scripts/editor-types.mjs', 'scripts/plugin-editor-types.mjs', 'scripts/build-test.js', 'scripts/build-i18n.js', 'scripts/build-docs.js', 'scripts/build-llm.js', 'scripts/trans-docs.js', 'scripts/projects.js', 'docs/assets/js/common.js', 'docs/assets/js/mobile.js', 'packages/artplayer-vitepress/docs/public/main.js', 'packages/artplayer-vitepress/docs/vite.config.ts', 'packages/artplayer-vitepress/docs/.vitepress/config.js']
const assets = [...files('docs/assets/sample'), ...files('docs/assets/jassub').filter(file => /\.(?:ttf|otf|woff2?)$/i.test(file)), ...files('docs/assets/js/vs'), 'docs/assets/js/vconsole.min.js', 'docs/assets/js/console.js'].map(fingerprint)
return {
schemaVersion: 1,
task: 'SITE-01',
note: 'Read-only source inventory. Heading matches are candidates, never semantic API coverage. Asset identity is not permission. No runtime, remote Pages or npm acceptance is implied.',
counts: { packages: packages.length, markdown: docs.length, examples: demo.examples.length, html: demo.pages.length, declarationMembers: api.length, assets: assets.length },
docs,
api,
packages,
examples: demo.examples,
pages: demo.pages,
baselinePaths: { examplesAdded: demo.examples.filter(row => !historical.examples.some(old => old.source === row.source)).map(row => row.source), examplesRemoved: historical.examples.filter(row => !demo.examples.some(now => now.source === row.source)).map(row => row.source), htmlAdded: demo.pages.filter(row => !historical.pages.some(old => old.source === row.source)).map(row => row.source), htmlRemoved: historical.pages.filter(row => !demo.pages.some(now => now.source === row.source)).map(row => row.source) },
editorDeclarations: [...read('docs/assets/js/common.js').matchAll(/'\.\/assets\/ts\/([^']+\.d\.ts)'/g)].map(match => ({ file: `docs/assets/ts/${match[1]}`, exists: fs.existsSync(path.join(root, 'docs/assets/ts', match[1])), owner: 'SITE-02' })),
scripts: scriptFiles.map(file => ({ file, sha256Lf: hash(read(file)) })),
generationCommands: Object.fromEntries(Object.entries(json('package.json').scripts).filter(([name]) => /^(?:build:(?:types|ts|test|i18n|docs|llm|all)|ci:build)$/.test(name))),
siteManifest: json('packages/artplayer-vitepress/package.json'),
assets,
}
}
export function validateSiteInventory(value) {
assert.equal(value.schemaVersion, 1)
const tasks = new Map(json('refactor/tasks.json').tasks.map(task => [task.id, task]))
for (const owner of ['SITE-02', 'SITE-03', 'SITE-04', 'SITE-05', 'EX-03', 'REL-01']) assert(tasks.has(owner), `Missing follow-up: ${owner}`)
for (const item of value.editorDeclarations) assert(item.exists, `Missing editor declaration: ${item.file}`)
assert.equal(new Set(value.packages.map(pkg => pkg.name)).size, 22)
for (const file of ['docs/index.html', 'docs/mobile.html', 'docs/esm.html', 'docs/i18n.html', 'docs/iframe.html', 'docs/test/index.html']) assert(value.pages.some(page => page.source === file), `Missing HTML entry: ${file}`)
assert.deepEqual(value, captureSiteInventory(), 'Site inventory drift; inspect changes before --write')
}
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
assert.equal(process.argv.length, 3, 'Use --write or --check')
assert(['--write', '--check'].includes(process.argv[2]), 'Use --write or --check')
const value = process.argv[2] === '--write' ? captureSiteInventory() : JSON.parse(fs.readFileSync(filename, 'utf8'))
validateSiteInventory(value)
if (process.argv[2] === '--write')
fs.writeFileSync(filename, `${JSON.stringify(value, null, 2)}\n`)
console.log(`Site inventory: ${JSON.stringify(value.counts)}; semantic/browser review remains separate`)
}
+19
View File
@@ -0,0 +1,19 @@
import assert from 'node:assert/strict'
// eslint-disable-next-line test/no-import-node-test -- Runs with the repository baseline node:test suite.
import test from 'node:test'
import { captureSiteInventory, validateSiteInventory } from './site-inventory.mjs'
test('Site inventory detects omitted HTML, declarations and fingerprint drift', () => {
const snapshot = captureSiteInventory()
validateSiteInventory(snapshot)
for (const mutate of [
value => value.pages = value.pages.filter(page => page.source !== 'docs/mobile.html'),
value => value.editorDeclarations.pop(),
value => value.assets[0].sha256 = 'changed',
value => value.api.pop(),
]) {
const changed = structuredClone(snapshot)
mutate(changed)
assert.throws(() => validateSiteInventory(changed))
}
})
+63
View File
@@ -0,0 +1,63 @@
import assert from 'node:assert/strict'
import { Buffer } from 'node:buffer'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { archiveFiles, hash, readMember, refactorDir } from './releases.mjs'
assert.deepEqual(process.argv.slice(2), ['--network'], 'Explicit --network required; this command does not execute downloaded code')
const root = path.resolve(refactorDir, '..')
const cache = fs.mkdtempSync(path.join(refactorDir, '.cache/site-provenance-'))
const report = { task: 'SITE-01', capturedAt: new Date().toISOString(), cache, packages: [], passed: false }
const json = (file, value) => fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`)
try {
for (const [name, version] of [['artplayer-plugin-thumbnail', '1.0.3'], ['vconsole', '3.15.0'], ['monaco-editor', '0.30.1']]) {
const registry = `https://registry.npmjs.org/${name}/${version}`
const metadataResponse = await fetch(registry, { redirect: 'error', signal: AbortSignal.timeout(30000) })
assert(metadataResponse.ok, `${registry}: ${metadataResponse.status}`)
const metadata = await metadataResponse.json()
assert.equal(metadata.name, name)
assert.equal(metadata.version, version)
const url = new URL(metadata.dist.tarball)
assert.equal(url.origin, 'https://registry.npmjs.org')
const response = await fetch(url, { redirect: 'error', signal: AbortSignal.timeout(60000) })
assert(response.ok, `${url}: ${response.status}`)
const bytes = Buffer.from(await response.arrayBuffer())
assert.equal(`sha512-${hash(bytes, 'sha512', 'base64')}`, metadata.dist.integrity)
assert.equal(hash(bytes, 'sha1'), metadata.dist.shasum)
const archive = path.join(cache, `${name}-${version}.tgz`)
fs.writeFileSync(archive, bytes)
const members = archiveFiles(archive)
const manifest = JSON.parse(readMember(archive, 'package/package.json'))
const row = { name, version, registry, tarball: url.href, integrity: metadata.dist.integrity, sha256: hash(bytes), repository: metadata.repository, manifest, files: members, matches: [], notices: [] }
report.packages.push(row)
for (const member of members.filter(member => /(?:license|thirdpartynotices|notice)(?:\.\w+)?$/i.test(member))) {
const content = readMember(archive, member)
const target = `${name}-${path.basename(member)}.txt`
fs.writeFileSync(path.join(cache, target), content)
row.notices.push({ member, cached: target, sha256: hash(content) })
}
if (name === 'artplayer-plugin-thumbnail') {
for (const member of members.filter(member => /(?:README\.md|src\/index\.js|types\/.*\.d\.ts)$/i.test(member))) fs.writeFileSync(path.join(cache, `${name}-${member.replaceAll('/', '_')}.txt`), readMember(archive, member))
}
else {
const mappings = name === 'vconsole'
? [['docs/assets/js/vconsole.min.js', 'package/dist/vconsole.min.js']]
: fs.readdirSync(path.join(root, 'docs/assets/js/vs'), { recursive: true, withFileTypes: true }).filter(entry => entry.isFile()).map((entry) => {
const relative = path.relative(path.join(root, 'docs/assets/js/vs'), path.join(entry.parentPath, entry.name)).replaceAll('\\', '/')
return [`docs/assets/js/vs/${relative}`, `package/min/vs/${relative}`]
}).sort(([a], [b]) => a.localeCompare(b))
for (const [file, member] of mappings) {
const local = fs.readFileSync(path.join(root, file))
const upstream = members.includes(member) ? readMember(archive, member) : null
row.matches.push({ file, member, sha256: hash(local), upstreamSha256: upstream && hash(upstream), equal: upstream !== null && local.equals(upstream), equalLf: upstream !== null && local.toString('utf8').replaceAll('\r\n', '\n') === upstream.toString('utf8').replaceAll('\r\n', '\n') })
}
}
console.log(`${name}@${version}: ${row.matches.filter(item => item.equal).length}/${row.matches.length} exact local matches, ${row.notices.length} upstream notice files`)
}
report.passed = true
}
finally {
json(path.join(cache, 'report.json'), report)
console.log(`Provenance evidence: ${cache}`)
}
+114
View File
@@ -0,0 +1,114 @@
# 文档站、示例与生成链清单
SITE-01 在 `d62ab13a35c756ea567c426d4fbe00d893dd7e2b` 后核对当前源码。
可重跑清单见 [site-inventory.json](baselines/site-inventory.json);它登记
22 包、27 Markdown、30 示例、36 HTML、963 条声明成员和 204 个资产指纹。
成员统计包括继承接口、重载和 runtime 声明,不能当作 963 个不同公开 API。
标题匹配只是人工核对的候选位置;所有成员均明确交由 SITE-04 检查语义和中英文说明。
## 页面与内容责任
- 中文 14 页、英文 13 页;核心安装、选项、i18n、四类组件、六类高级说明有对应页面。
- Danmuku 有中文独立页,缺英文页;其余 15 插件使用包 README 和编辑器链接,缺独立双语指南。
- 2 proxy、2 tool 有包 README 和示例。包内维护文档不等于站点双语使用文档。
- 清单逐包列出 README、ARCHITECTURE、菜单引用和示例;SITE-04 负责补充双语入口及缺失说明,
不要求为了统一形式机械复制 20 份 README。SITE-05 验证实际生成页面和链接。
- 本次补齐文档站自己的 [维护地图](../packages/artplayer-vitepress/README.md)。
VitePress 导航仍显示 `5.3.x`,目标版本文案由 REL-09/SITE-04 同候选同步。
清单用 Markdown parser 读取真正的标题,用 TypeScript AST 枚举声明成员;
不会把代码块中的 `##` 当作标题,也不把同名标题自动判定为该接口已经有文档。
声明文件/符号/成员/行号和候选页面可追溯。接口语义、锚点可达性与运行正确性仍需人工和浏览器验证。
## 六类执行 HTML 与其它路径
| 入口 | 当前加载行为 | 后续责任 |
| --- | --- | --- |
| `/` | `console.js` → 按 localStorage.prod 选核心 → Monaco AMD loader → common.js | SITE-03 / EX-03 |
| `/mobile.html` | vConsole、uncompiled 核心、独立 mobile.js loader | SITE-03 / EX-03 |
| `/esm.html` | import map 指向 compiled ESM,含 Danmuku、Document PiP、印尼语 | EX-03 |
| `/i18n.html` | script 载入 compiled 核心及语言,读取旧语言 global 别名 | SITE-03 / EX-03 |
| `/iframe.html` | uncompiled 核心和 iframe tool,调用 inject | PKG-IFRAME-05 / EX-03 |
| `/test/` | Mocha/Chai、compiled 包及远程 SDK、生成 test.js | SITE-02 / EX-03 |
另外 28 个 `docs/document/**/*.html` 是现存生成站点路径(包含 404);Google
验证页保持原路径/内容;`/upscaler/` 是独立工具入口,不能按 VitePress 重建范围删除。
共 36 HTML,与 BASE-04 路径集合一致。现有生成 HTML 不证明来自当前源码的成功构建。
原 29 个示例路径全部保留;第 30 个 `asr.local.js` 来自提交
`2cede66933e92b253bab4b3b2502f0268b22b087`,无菜单链接,使用 ASR 插件的显式 libs URL。
它采集本地音频并显示模拟字幕,不是远程识别演示。原 BASE-04 保持原样;新增路径见
[demo-additions.json](baselines/demo-additions.json)。`demos.mjs --check` 将两者合并验证完整集合,
未知新增、遗漏旧路径、重复登记、错误路由或未知 owner 均不能通过。
## 查询参数、状态和编辑器声明
`prod` 是 localStorage 键/勾选项,不是已实现的查询参数;只选择核心产物,
不会重写 libs 中的插件路径。`libs` URI 解码后按换行分隔,依扩展名加载 JS/CSS,
Promise.all 等待全部完成;这不保证列表中脚本按顺序执行。
`example` 优先于 `code`;均不存在时桌面取 index.js,移动取 mobile.js。
桌面移动重定向保留 location.search。桌面 Run 先发送 `artplayer:example:cleanup`,
销毁已有实例再 eval;重启将 libs/code 写入 URL。不要把 TS 模式视为严格类型编译证明。
当前编辑器注入 22 个 d.ts(20 个生态包、核心、i18n),逐个 fetch 后 addExtraLib/createModel。
来源是核心 public 经 build:types/build:ts,以及各生态包 types 经 build:ts。
仅存在性检查不证明请求成功或 Monaco 诊断有效,真实编辑器验收归 EX-03。
loadScript 暂时覆盖 window.define:桌面成功/失败均恢复,移动失败分支没有恢复;
重复运行和加载失败顺序需要 SITE-03 / EX-03 修复与回归。
## 生成流程和分发
| 命令/脚本 | 输入 → 输出 | 当前边界/责任 |
| --- | --- | --- |
| build:types | 核心 public → types | 已有严格生成检查,不手改输出 |
| build:ts | 核心及插件声明 → assets/ts、common.js 的 libUris | 大部分语义转换,仍有字符串 fallback;SITE-02 |
| build:test | 中文 Run Code → docs/test/test.js | 排除 en/plugin/public/.vitepress;100ms done 只是 smoke,含生成时间戳;SITE-02 |
| build:i18n | 核心语言源 → dist/i18n、compiled/i18n | 排除内置语言/发布辅助,逐包构建;SITE-03 |
| build:docs | VitePress 源 → docs/document | 当前 npm 子进程只是运行脚本;SITE-03 统一 Yarn 编排 |
| build:llm | 英文文档、编辑器声明、示例 → docs/llms.txt | 明确远程 DeepSeek 操作;SITE-03 |
| trans-docs.js | 中文 Markdown → 英文 Markdown | 明确远程 DeepSeek 操作;SITE-03 |
build:test 的 malformed 分支在 continue 前不推进 regexp,存在同一坏块重复扫描的源码路径;
SITE-02 必须加入可终止的坏文档反例。未运行该路径或把它计作已修复。
build:all/ci:build 当前不调用远程翻译或 LLM。SITE-03 应保留这一边界。
`scripts/projects.js` 明确排除 VitePress 的库构建;配置 base=/document/,输出到仓库 docs/document。
Pages 工作流消费已验证的 docs artifact,部署与检查分离。manifest 未设 private,且没有
库入口;这不足以推断作者希望发布 npm。REL-01/CI-03 必须显式区分 21 库与 1 静态站点,
站点 1.1.0→2.0.0 的版本要求保留。本次没有改 private、版本、发布列表或执行远端部署。
## 第三方与媒体来源
冻结 registry/SHA-512 tarball 对照见 [site-provenance.json](baselines/site-provenance.json)。
抓取脚本只下载、校验和读取归档,不执行包脚本;原始包缓存保留,报告记录确切 URL 和哈希。
| 对象 | 本次取证 | 未完成部分 |
| --- | --- | --- |
| Monaco | npm 0.30.1 的 99 个对应文件:98 字节一致,editor.main.css 仅 5 处 CRLF/LF 差异;取得 LICENSE/ThirdPartyNotices | 站点 notices 装配、真实编辑器与 worker;SITE-07 / SITE-05 |
| vConsole | npm 3.15.0 dist 与本地逐字节一致,取得 LICENSE | 站点完整 notice 与移动使用验收;SITE-07 / EX-03 |
| console.js | Parcel bundle 含 react/react-dom/console-feed/styled-components,暴露 consoleLog;末尾指向不存在的 /index.js.map | 无冻结构建源/锁/完整组件版本;SITE-07 复原来源或可复现替换,不能直接认作自有 TS |
| JASSUB 字体 | 沿用既有 11 字体上游逐字节证据和内嵌元数据 | 6 字体授权依据、其它字体 notice 仍开放;PKG-JASSUB-06 / SITE-07 |
| 样本媒体 | 当前 sample 目录逐文件指纹;已有 URL/样本绑定可追溯 | 托管位置不证明授权,BASE-MEDIA-01 与 EX-03 保留 |
上游 notices 原文保留在 `baselines/site-vendor/` 作为取证材料,尚未复制到发布站点。
没有更新 VENDOR-05/06/07/08 为 closed,也没有下载媒体来替代缺失的使用依据。
旧 `thumbnail.js` 在 `a33df191a4216897d4fd4526927a822fd8b543a1` 从工具示例改成
`artplayerPluginThumbnail({width, number, scale})`。官方 registry 列出的 1.0.0–1.0.3
manifest 均指向 VTT 包入口;实际验证的 1.0.3 tarball 源码导出 artplayerPluginVttThumbnail,
读取 option.vtt,声明却使用 artplayerPluginThumbnail 名称。不能把 npm 包名当成此示例的
可用依赖,也不能直接别名到 auto-thumbnail。EX-03 要保留旧 URL 并给出明确修复/迁移解释;
BASE-DEMO-01 保持开放。本次没有改变示例运行行为。
## 重跑与限制
```sh
node refactor/scripts/site-inventory.mjs --check
node refactor/scripts/demos.mjs --check
node --test refactor/scripts/demos.test.mjs refactor/scripts/site-inventory.test.mjs
node refactor/scripts/site-provenance.mjs --network
```
清单变化先检查差异,再 `site-inventory.mjs --write`,不能把重生成当作消除内容问题。
本任务是入口/来源和生成链清点,没有执行完整文档构建、公开页面请求、播放器实播、搜索、
真机或远端 CI。SITE-02/03/04/05/07 与 EX-03 的验收继续独立推进。
+36 -7
View File
@@ -4084,17 +4084,25 @@
"phase": "6 文档与消费者",
"title": "清点文档/示例/生成链",
"scope": [
"artplayer-vitepress"
"artplayer-vitepress",
"workspace"
],
"dependsOn": [
"BASE-04",
"BASE-05"
],
"status": "todo",
"status": "done",
"risk": "M",
"deliverable": "中英文文档、插件页面、demo URL、编辑器声明与生成目录清单;六类 HTML 入口、prod/libs/code/example 加载行为及移动重定向",
"acceptance": "所有公开 API/插件有对应页面或明确补充任务;核实 BASE-DEMO-01 的历史 thumbnail 插件来源及 29 示例/36 HTML 路径;明确 BASE-05 所记录站点实际分发与未设 private 的 manifest 意图;接续 VENDOR-05/06/07/08 和 BASE-SITE-01/BASE-MEDIA-01,核对字体、Monaco、vConsole、console bundle 与样本来源及分发范围",
"evidence": []
"evidence": [
"site-inventory.md",
"baselines/site-inventory.json",
"baselines/site-provenance.json",
"baselines/demo-additions.json",
"changes/2026-09-14-SITE-01-site-inventory.md",
"baselines/site-inventory-validation.json"
]
},
{
"id": "SITE-02",
@@ -4111,7 +4119,7 @@
"status": "todo",
"risk": "M",
"deliverable": "build-ts/build-test 生成链的可验证 TS 脚本",
"acceptance": "不靠字符串拼接掩盖声明错误,生成示例有真实断言或仅标 smoke;替换固定 100ms 成功判定,明确异步错误、清理和生成覆盖限制",
"acceptance": "不靠字符串拼接掩盖声明错误,生成示例有真实断言或仅标 smoke;替换固定 100ms 成功判定,明确异步错误、清理和生成覆盖限制;坏代码块解析必须终止,覆盖 malformed 分支不推进 regexp 的回归",
"evidence": []
},
{
@@ -4127,7 +4135,7 @@
"status": "todo",
"risk": "M",
"deliverable": "build-i18n/build-docs/build-llm/trans-docs 的任务边界和错误处理",
"acceptance": "原命令兼容、生成可复现,翻译步骤不隐式运行远程服务",
"acceptance": "原命令兼容、生成可复现,翻译步骤不隐式运行远程服务;覆盖移动 loader 失败恢复 define、脚本依赖顺序、localhost/127.0.0.1 Run Code 目标和语言重定向",
"evidence": []
},
{
@@ -4164,7 +4172,7 @@
"status": "todo",
"risk": "M",
"deliverable": "已随实现更新的中文/英文 API、包内实现地图、旧 JS 示例及已知能力限制的全包核对",
"acceptance": "未把缺环境的能力写成已验证,静态核对不等待设备任务;最终 demo 仍由 EX-03 验收",
"acceptance": "未把缺环境的能力写成已验证,静态核对不等待设备任务;最终 demo 仍由 EX-03 验收;按 SITE-01 声明成员/候选标题清单逐项语义核对,补齐缺失的双语插件说明和 Danmuku 英文入口",
"evidence": []
},
{
@@ -4177,7 +4185,8 @@
"dependsOn": [
"SITE-04",
"EX-01",
"EX-02"
"EX-02",
"SITE-07"
],
"status": "todo",
"risk": "M",
@@ -4201,6 +4210,26 @@
"acceptance": "未手改 generated 目录,旧 URL 可用、部署与检查分离",
"evidence": []
},
{
"id": "SITE-07",
"phase": "6 文档与消费者",
"title": "整理站点第三方资产与来源说明",
"scope": [
"artplayer-vitepress",
"workspace"
],
"dependsOn": [
"SITE-01"
],
"status": "todo",
"risk": "H",
"deliverable": "Monaco/vConsole/console bundle/字体和样本的冻结来源、可复现构建或替代与站点 notices",
"acceptance": "接续 SITE-01 的字节与换行差异证据;完整许可随实际分发,consoleLog/global/CSS/worker 与旧 URL 兼容;缺字体/媒体使用依据明确处置;资产变更后执行编辑器/移动/字幕/示例回归,不以来源指纹替代授权或运行证据",
"evidence": [
"site-inventory.md",
"baselines/site-provenance.json"
]
},
{
"id": "EX-01",
"phase": "6 文档与消费者",