@ttmg/cli 0.4.1-beta.wasm1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/index.js +170 -19
  2. package/dist/index.js.map +1 -1
  3. package/dist/package.json +1 -1
  4. package/dist/public/assets/Detail-DNF1PK-R.js +1 -0
  5. package/dist/public/assets/Detail-DNF1PK-R.js.br +0 -0
  6. package/dist/public/assets/MonetizationMode-C59U6Ari.js +1 -0
  7. package/dist/public/assets/MonetizationModeSummary-BR2LJFsU.js +1 -0
  8. package/dist/public/assets/SectionHeader-CCjfBKcF.js +1 -0
  9. package/dist/public/assets/Tag-DON36Of0.js +1 -0
  10. package/dist/public/assets/baseForm-B3oZF8Vp.js +10 -0
  11. package/dist/public/assets/baseForm-B3oZF8Vp.js.br +0 -0
  12. package/dist/public/assets/baseForm-BAvk37jF.css +1 -0
  13. package/dist/public/assets/baseForm-BAvk37jF.css.br +0 -0
  14. package/dist/public/assets/{boxes-C7RoIbId.js → boxes-EbMNfQ6U.js} +1 -1
  15. package/dist/public/assets/{chevron-right-B1WBZrrD.js → chevron-right-CsmjM7t0.js} +1 -1
  16. package/dist/public/assets/col-BXewy14r.css +1 -0
  17. package/dist/public/assets/col-BXewy14r.css.br +0 -0
  18. package/dist/public/assets/col-DWGIx7fj.js +1 -0
  19. package/dist/public/assets/{compass-VJNhHwqW.js → compass-bMD5nDM8.js} +1 -1
  20. package/dist/public/assets/index-B4j49Ts7.js +1 -0
  21. package/dist/public/assets/index-B4j49Ts7.js.br +0 -0
  22. package/dist/public/assets/{index-a-rMUS2V.js → index-B5JnznvI.js} +1 -1
  23. package/dist/public/assets/index-BCV7VBUL.js +1 -0
  24. package/dist/public/assets/index-BCV7VBUL.js.br +0 -0
  25. package/dist/public/assets/index-BKOO94x-.css +1 -0
  26. package/dist/public/assets/index-BPqSXmk6.js +1 -0
  27. package/dist/public/assets/index-Bn_Zugqv.js +1 -0
  28. package/dist/public/assets/index-Bn_Zugqv.js.br +0 -0
  29. package/dist/public/assets/index-BtO50Nho.js +1 -0
  30. package/dist/public/assets/index-BtO50Nho.js.br +0 -0
  31. package/dist/public/assets/{index-C_npSvtQ.js → index-BzEQAUVA.js} +1 -1
  32. package/dist/public/assets/{index-Dn5HHf-0.js → index-CAoj7RMM.js} +1 -1
  33. package/dist/public/assets/index-CKUVWl_O.css +1 -0
  34. package/dist/public/assets/index-CMwzPrAh.css +1 -0
  35. package/dist/public/assets/index-CMwzPrAh.css.br +0 -0
  36. package/dist/public/assets/index-CYnulX57.css +1 -0
  37. package/dist/public/assets/index-CYnulX57.css.br +0 -0
  38. package/dist/public/assets/{index-BH099q_U.js → index-Ca-cQ1Oq.js} +1 -1
  39. package/dist/public/assets/{index-s_30KWiA.js → index-CdJUBcSF.js} +1 -1
  40. package/dist/public/assets/{index-bQUQ2Wmz.js → index-Cf8aH-xI.js} +1 -1
  41. package/dist/public/assets/{index-DMsjcIN8.js → index-D4lGRib1.js} +1 -1
  42. package/dist/public/assets/index-D5-FwYf-.js +1 -0
  43. package/dist/public/assets/index-D5-FwYf-.js.br +0 -0
  44. package/dist/public/assets/{index-BO5MBsdm.js → index-DH7hBDqZ.js} +1 -1
  45. package/dist/public/assets/index-DKxf26_O.css +1 -0
  46. package/dist/public/assets/index-DOMxPC_v.css +1 -0
  47. package/dist/public/assets/index-DOMxPC_v.css.br +0 -0
  48. package/dist/public/assets/index-DRr-Punk.js +1 -0
  49. package/dist/public/assets/index-DV0N-QmJ.js +1 -0
  50. package/dist/public/assets/index-DV0N-QmJ.js.br +0 -0
  51. package/dist/public/assets/index-DXEfgIqc.js +1 -0
  52. package/dist/public/assets/{index-BBR3CPkN.js → index-DaOr2P0A.js} +1 -1
  53. package/dist/public/assets/index-DaOr2P0A.js.br +0 -0
  54. package/dist/public/assets/index-Dv0bhjYp.js +1 -0
  55. package/dist/public/assets/{index-qqnHwFjO.js → index-Dx-boSFk.js} +1 -1
  56. package/dist/public/assets/{index-C1C34gtn.js → index-FYgsnJbm.js} +1 -1
  57. package/dist/public/assets/index-HqjZ5P-l.css +1 -0
  58. package/dist/public/assets/{index-BJZ4gOGZ.css → index-V1Go68Vw.css} +1 -1
  59. package/dist/public/assets/index-V1Go68Vw.css.br +0 -0
  60. package/dist/public/assets/index-VvBtuIHK.css +1 -0
  61. package/dist/public/assets/index-VvBtuIHK.css.br +0 -0
  62. package/dist/public/assets/index-VvUpVuij.js +21 -0
  63. package/dist/public/assets/index-VvUpVuij.js.br +0 -0
  64. package/dist/public/assets/index-VzIFpCiL.js +1 -0
  65. package/dist/public/assets/{index-DbxY65Om.js → index-bASdAMHs.js} +1 -1
  66. package/dist/public/assets/index-q7fKJFmZ.js +1 -0
  67. package/dist/public/assets/index-vlN_-PRJ.css +1 -0
  68. package/dist/public/assets/{layers-Biv61qtE.js → layers-C8HCSIXn.js} +1 -1
  69. package/dist/public/assets/list-checks-B6t2uu5m.js +1 -0
  70. package/dist/public/assets/{sparkles-Bv2GxrFr.js → sparkles-pLu1TMVV.js} +1 -1
  71. package/dist/public/assets/triangle-alert-Dm4_sEwV.js +1 -0
  72. package/dist/public/assets/{zap-CjkC_qWZ.js → zap-tefJh46p.js} +1 -1
  73. package/dist/public/index.html +2 -2
  74. package/dist/scripts/docs/README.md +80 -0
  75. package/dist/scripts/docs/capture.js +84 -6
  76. package/dist/scripts/docs/check.js +184 -0
  77. package/dist/scripts/docs/render.js +283 -6
  78. package/dist/scripts/docs/scenarios/devtool-guide.mjs +802 -0
  79. package/package.json +1 -1
  80. package/CHANGELOG.md +0 -256
  81. package/dist/public/assets/Card-ASGGlJ8S.js +0 -1
  82. package/dist/public/assets/Detail-DY__Zw0r.js +0 -1
  83. package/dist/public/assets/Detail-DY__Zw0r.js.br +0 -0
  84. package/dist/public/assets/MonetizationMode-sHN_4ybQ.js +0 -1
  85. package/dist/public/assets/MonetizationModeSummary-DLvyriLM.js +0 -1
  86. package/dist/public/assets/SectionHeader-B7dueBCf.js +0 -1
  87. package/dist/public/assets/Tag-BsX0d6UL.js +0 -1
  88. package/dist/public/assets/arrow-left-uixm7Sd1.js +0 -1
  89. package/dist/public/assets/baseForm-C8XfTFyG.js +0 -10
  90. package/dist/public/assets/baseForm-C8XfTFyG.js.br +0 -0
  91. package/dist/public/assets/baseForm-Dl4zA6hU.css +0 -1
  92. package/dist/public/assets/baseForm-Dl4zA6hU.css.br +0 -0
  93. package/dist/public/assets/circle-check-wUxXeINd.js +0 -1
  94. package/dist/public/assets/index-BAud2cRu.css +0 -1
  95. package/dist/public/assets/index-BBR3CPkN.js.br +0 -0
  96. package/dist/public/assets/index-BJZ4gOGZ.css.br +0 -0
  97. package/dist/public/assets/index-BNc8JtET.js +0 -1
  98. package/dist/public/assets/index-Bd-f8ERX.js +0 -1
  99. package/dist/public/assets/index-ByX5RuFA.css +0 -1
  100. package/dist/public/assets/index-C7Tmy9g3.js +0 -1
  101. package/dist/public/assets/index-CCKb9Y-j.js +0 -14
  102. package/dist/public/assets/index-CCKb9Y-j.js.br +0 -0
  103. package/dist/public/assets/index-CFd8iglC.css +0 -1
  104. package/dist/public/assets/index-CFd8iglC.css.br +0 -0
  105. package/dist/public/assets/index-CKhfKyA3.js +0 -1
  106. package/dist/public/assets/index-CKhfKyA3.js.br +0 -0
  107. package/dist/public/assets/index-Cc1ilXmc.css +0 -1
  108. package/dist/public/assets/index-DHXlsTU6.css +0 -1
  109. package/dist/public/assets/index-DHXlsTU6.css.br +0 -0
  110. package/dist/public/assets/index-DNd8ZTok.js +0 -1
  111. package/dist/public/assets/index-DNd8ZTok.js.br +0 -0
  112. package/dist/public/assets/index-DpkktYot.css +0 -1
  113. package/dist/public/assets/index-DtoDrber.js +0 -1
  114. package/dist/public/assets/index-DtoDrber.js.br +0 -0
  115. package/dist/public/assets/index-ZHPtAdJM.js +0 -1
  116. package/dist/public/assets/index-ZHPtAdJM.js.br +0 -0
  117. package/dist/public/assets/index-ZtlCPCV9.js +0 -1
  118. package/dist/public/assets/index-_6n0s04V.css +0 -1
  119. package/dist/public/assets/index-_6n0s04V.css.br +0 -0
  120. package/dist/public/assets/index-r3aSeNL1.js +0 -1
  121. package/dist/public/assets/index-t4JeqZ4a.js +0 -1
@@ -1,5 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const crypto = require('crypto');
4
+ const childProcess = require('child_process');
3
5
  const { pathToFileURL } = require('url');
4
6
 
5
7
  function parseArgs(argv) {
@@ -16,36 +18,239 @@ function parseArgs(argv) {
16
18
  async function loadRecipes(recipesPath) {
17
19
  const module = await import(pathToFileURL(recipesPath).href);
18
20
  return {
21
+ schemaVersion: module.schemaVersion || 1,
19
22
  recipes: module.recipes || module.default || [],
20
23
  locales: module.locales || ['zh-CN', 'en-US'],
21
24
  guideTitle: module.guideTitle || 'TikTok 小游戏调试工具使用指南',
25
+ guideSource: module.guideSource || null,
22
26
  guideSections: module.guideSections || {},
23
27
  guideFaqs: module.guideFaqs || {},
28
+ docVersion: module.docVersion || {},
29
+ documentationContract: module.documentationContract || {},
30
+ guideReleaseChecks: module.guideReleaseChecks || [],
31
+ screenshotInventory: module.screenshotInventory || [],
24
32
  };
25
33
  }
26
34
 
27
- function buildManifest({ recipes, locales, outputDir, guideTitle, guideSections, guideFaqs }) {
35
+ function readJsonIfExists(filePath) {
36
+ if (!fs.existsSync(filePath)) {
37
+ return null;
38
+ }
39
+ try {
40
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ function safeExec(command, cwd) {
47
+ try {
48
+ return childProcess.execSync(command, {
49
+ cwd,
50
+ encoding: 'utf8',
51
+ stdio: ['ignore', 'pipe', 'ignore'],
52
+ }).trim();
53
+ } catch {
54
+ return '';
55
+ }
56
+ }
57
+
58
+ function dropUndefined(value) {
59
+ if (Array.isArray(value)) {
60
+ return value.map(dropUndefined);
61
+ }
62
+ if (!value || typeof value !== 'object') {
63
+ return value;
64
+ }
65
+ return Object.fromEntries(
66
+ Object.entries(value)
67
+ .filter(([, nestedValue]) => nestedValue !== undefined)
68
+ .map(([key, nestedValue]) => [key, dropUndefined(nestedValue)]),
69
+ );
70
+ }
71
+
72
+ function stableStringify(value) {
73
+ if (Array.isArray(value)) {
74
+ return `[${value.map(stableStringify).join(',')}]`;
75
+ }
76
+ if (!value || typeof value !== 'object') {
77
+ return JSON.stringify(value);
78
+ }
79
+ return `{${Object.keys(value)
80
+ .sort()
81
+ .map(key => `${JSON.stringify(key)}:${stableStringify(value[key])}`)
82
+ .join(',')}}`;
83
+ }
84
+
85
+ function createScenarioFingerprint({ schemaVersion, locales, guideTitle, guideSource, recipes }) {
86
+ return crypto
87
+ .createHash('sha256')
88
+ .update(stableStringify({ schemaVersion, locales, guideTitle, guideSource, recipes }))
89
+ .digest('hex')
90
+ .slice(0, 16);
91
+ }
92
+
93
+ function screenshotPath(recipe, locale) {
94
+ return `assets/${recipe.id}.${locale}.png`;
95
+ }
96
+
97
+ function buildScreenshotIndex({ recipes, locales, outputDir, guideTitle, guideSource, scenarioFingerprint, screenshotInventory }) {
28
98
  return {
99
+ schemaVersion: 1,
29
100
  title: guideTitle,
101
+ guideSource,
102
+ scenarioFingerprint,
103
+ generatedAt: new Date().toISOString(),
104
+ outputDir,
105
+ screenshotInventory,
106
+ screenshots: recipes.flatMap(recipe =>
107
+ locales.map(locale => dropUndefined({
108
+ id: `${recipe.id}.${locale}`,
109
+ recipeId: recipe.id,
110
+ locale,
111
+ route: recipe.route,
112
+ page: recipe.page,
113
+ productArea: recipe.productArea,
114
+ fixture: recipe.fixture,
115
+ capture: recipe.capture,
116
+ doc: recipe.doc,
117
+ path: screenshotPath(recipe, locale),
118
+ })),
119
+ ),
120
+ };
121
+ }
122
+
123
+ function buildManifest({
124
+ schemaVersion,
125
+ recipes,
126
+ locales,
127
+ outputDir,
128
+ guideTitle,
129
+ guideSource,
130
+ guideSections,
131
+ guideFaqs,
132
+ scenarioFingerprint,
133
+ docVersion,
134
+ documentationContract,
135
+ guideReleaseChecks,
136
+ screenshotInventory,
137
+ }) {
138
+ return {
139
+ schemaVersion,
140
+ title: guideTitle,
141
+ guideSource,
142
+ docVersion,
143
+ documentationContract,
144
+ guideReleaseChecks,
145
+ screenshotInventory,
146
+ scenarioFingerprint,
30
147
  generatedAt: new Date().toISOString(),
31
148
  outputDir,
32
149
  locales,
33
150
  guideSections,
34
151
  guideFaqs,
35
- pages: recipes.map(recipe => ({
152
+ pages: recipes.map(recipe => dropUndefined({
36
153
  id: recipe.id,
154
+ title: recipe.title,
37
155
  route: recipe.route,
156
+ page: recipe.page,
157
+ productArea: recipe.productArea,
158
+ fixture: recipe.fixture,
159
+ capture: recipe.capture,
38
160
  captureMode: recipe.captureMode,
39
161
  waitFor: recipe.waitFor,
162
+ doc: recipe.doc,
163
+ privacy: recipe.privacy,
164
+ acceptance: recipe.acceptance,
165
+ updatePolicy: recipe.updatePolicy,
40
166
  notes: recipe.notes,
41
167
  screenshots: locales.map(locale => ({
42
168
  locale,
43
- path: `assets/${recipe.id}.${locale}.png`,
169
+ path: screenshotPath(recipe, locale),
44
170
  })),
45
171
  })),
46
172
  };
47
173
  }
48
174
 
175
+ function buildDocVersion({
176
+ repoRoot,
177
+ outputDir,
178
+ guideTitle,
179
+ guideSource,
180
+ schemaVersion,
181
+ locales,
182
+ scenarioFingerprint,
183
+ docVersion,
184
+ documentationContract,
185
+ guideReleaseChecks,
186
+ screenshotInventory,
187
+ }) {
188
+ const rootPackage = readJsonIfExists(path.join(repoRoot, 'package.json')) || {};
189
+ const cliPackage = readJsonIfExists(path.join(repoRoot, 'packages/libs/dev-tools/cli/package.json')) || {};
190
+ const gitCommit = safeExec('git rev-parse --short HEAD', repoRoot);
191
+ const gitStatus = safeExec('git status --short', repoRoot);
192
+
193
+ return dropUndefined({
194
+ schemaVersion: 1,
195
+ id: docVersion.id,
196
+ status: docVersion.status,
197
+ title: guideTitle,
198
+ generatedAt: new Date().toISOString(),
199
+ outputDir,
200
+ guideSource,
201
+ sourceOfTruth: docVersion.sourceOfTruth,
202
+ publishTiming: docVersion.publishTiming,
203
+ ownerReviewRequired: docVersion.ownerReviewRequired,
204
+ scenario: {
205
+ schemaVersion,
206
+ scenarioFingerprint,
207
+ locales,
208
+ screenshotCount: screenshotInventory.length,
209
+ screenshotIds: screenshotInventory.map(item => item.id),
210
+ },
211
+ packages: {
212
+ workspace: rootPackage.version,
213
+ cli: cliPackage.version,
214
+ ttmgPack: cliPackage.dependencies?.['ttmg-pack'],
215
+ },
216
+ git: {
217
+ commit: gitCommit || undefined,
218
+ dirty: gitStatus ? true : undefined,
219
+ },
220
+ qualityGate: {
221
+ documentationContract,
222
+ checks: guideReleaseChecks,
223
+ },
224
+ artifacts: {
225
+ manifest: 'manifest.json',
226
+ screenshotIndex: 'screenshot-index.json',
227
+ qualityGate: 'quality-gate.json',
228
+ guideDraft: 'index.md',
229
+ screenshotsDir: 'assets/',
230
+ },
231
+ });
232
+ }
233
+
234
+ function buildQualityGate({
235
+ guideTitle,
236
+ guideSource,
237
+ scenarioFingerprint,
238
+ documentationContract,
239
+ guideReleaseChecks,
240
+ screenshotInventory,
241
+ }) {
242
+ return {
243
+ schemaVersion: 1,
244
+ title: guideTitle,
245
+ guideSource,
246
+ scenarioFingerprint,
247
+ generatedAt: new Date().toISOString(),
248
+ documentationContract,
249
+ guideReleaseChecks,
250
+ screenshotInventory,
251
+ };
252
+ }
253
+
49
254
  function renderRecipeBlock(locale, recipe, headingLevel = 3) {
50
255
  const note = recipe.notes[locale];
51
256
  const purposeLabel = locale === 'zh-CN' ? '用途' : 'Purpose';
@@ -449,10 +654,67 @@ async function main() {
449
654
  throw new Error('Missing required argument: --output-dir');
450
655
  }
451
656
 
452
- const { recipes, locales, guideTitle, guideSections, guideFaqs } = await loadRecipes(recipesPath);
657
+ const {
658
+ schemaVersion,
659
+ recipes,
660
+ locales,
661
+ guideTitle,
662
+ guideSource,
663
+ guideSections,
664
+ guideFaqs,
665
+ docVersion,
666
+ documentationContract,
667
+ guideReleaseChecks,
668
+ screenshotInventory,
669
+ } = await loadRecipes(recipesPath);
453
670
  fs.mkdirSync(outputDir, { recursive: true });
454
671
 
455
- const manifest = buildManifest({ recipes, locales, outputDir, guideTitle, guideSections, guideFaqs });
672
+ const scenarioFingerprint = createScenarioFingerprint({ schemaVersion, recipes, locales, guideTitle, guideSource });
673
+ const manifest = buildManifest({
674
+ schemaVersion,
675
+ recipes,
676
+ locales,
677
+ outputDir,
678
+ guideTitle,
679
+ guideSource,
680
+ guideSections,
681
+ guideFaqs,
682
+ scenarioFingerprint,
683
+ docVersion,
684
+ documentationContract,
685
+ guideReleaseChecks,
686
+ screenshotInventory,
687
+ });
688
+ const screenshotIndex = buildScreenshotIndex({
689
+ recipes,
690
+ locales,
691
+ outputDir,
692
+ guideTitle,
693
+ guideSource,
694
+ scenarioFingerprint,
695
+ screenshotInventory,
696
+ });
697
+ const docVersionSnapshot = buildDocVersion({
698
+ repoRoot: process.cwd(),
699
+ outputDir,
700
+ guideTitle,
701
+ guideSource,
702
+ schemaVersion,
703
+ locales,
704
+ scenarioFingerprint,
705
+ docVersion,
706
+ documentationContract,
707
+ guideReleaseChecks,
708
+ screenshotInventory,
709
+ });
710
+ const qualityGate = buildQualityGate({
711
+ guideTitle,
712
+ guideSource,
713
+ scenarioFingerprint,
714
+ documentationContract,
715
+ guideReleaseChecks,
716
+ screenshotInventory,
717
+ });
456
718
  const markdown = renderMarkdown({ recipes, locales, guideTitle, guideSections, guideFaqs });
457
719
 
458
720
  fs.writeFileSync(
@@ -460,9 +722,24 @@ async function main() {
460
722
  `${JSON.stringify(manifest, null, 2)}\n`,
461
723
  'utf8',
462
724
  );
725
+ fs.writeFileSync(
726
+ path.join(outputDir, 'screenshot-index.json'),
727
+ `${JSON.stringify(screenshotIndex, null, 2)}\n`,
728
+ 'utf8',
729
+ );
730
+ fs.writeFileSync(
731
+ path.join(outputDir, 'doc-version.json'),
732
+ `${JSON.stringify(docVersionSnapshot, null, 2)}\n`,
733
+ 'utf8',
734
+ );
735
+ fs.writeFileSync(
736
+ path.join(outputDir, 'quality-gate.json'),
737
+ `${JSON.stringify(qualityGate, null, 2)}\n`,
738
+ 'utf8',
739
+ );
463
740
  fs.writeFileSync(path.join(outputDir, 'index.md'), `${markdown}\n`, 'utf8');
464
741
 
465
- console.log(`[ttmg-docs] rendered manifest and markdown into ${outputDir}`);
742
+ console.log(`[ttmg-docs] rendered manifest, screenshot index, version snapshot, quality gate and markdown into ${outputDir}`);
466
743
  }
467
744
 
468
745
  main().catch(error => {