@ohos-ports/slides-grab 1.5.0-beta.0

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 (115) hide show
  1. package/LICENSE +21 -0
  2. package/README-ko.md +292 -0
  3. package/README.md +301 -0
  4. package/bin/ohos-postinstall.cjs +118 -0
  5. package/bin/ppt-agent.js +620 -0
  6. package/convert.cjs +20 -0
  7. package/native/@img/sharp-libvips-openharmony-arm64/lib/glib-2.0/include/glibconfig.h +220 -0
  8. package/native/@img/sharp-libvips-openharmony-arm64/lib/index.js +1 -0
  9. package/native/@img/sharp-libvips-openharmony-arm64/lib/libexpat.so +0 -0
  10. package/native/@img/sharp-libvips-openharmony-arm64/lib/libffi.so +0 -0
  11. package/native/@img/sharp-libvips-openharmony-arm64/lib/libjpeg.so +0 -0
  12. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpcre2-8.so.0 +0 -0
  13. package/native/@img/sharp-libvips-openharmony-arm64/lib/libvips-cpp.so.42.20.3 +0 -0
  14. package/native/@img/sharp-libvips-openharmony-arm64/lib/libvips.so.42.20.3 +0 -0
  15. package/native/@img/sharp-libvips-openharmony-arm64/package.json +13 -0
  16. package/native/@img/sharp-openharmony-arm64/lib/sharp-openharmony-arm64.node +0 -0
  17. package/native/@img/sharp-openharmony-arm64/package.json +16 -0
  18. package/package.json +95 -0
  19. package/runtimes/claude-code/agents/design-critic-agent.md +23 -0
  20. package/runtimes/codex/agents/slides-grab-design-critic.md +22 -0
  21. package/scripts/build-viewer.js +444 -0
  22. package/scripts/design-gate.js +258 -0
  23. package/scripts/download-video.js +213 -0
  24. package/scripts/editor-server.js +1167 -0
  25. package/scripts/figma-export.js +169 -0
  26. package/scripts/generate-image.js +116 -0
  27. package/scripts/generate-images.js +164 -0
  28. package/scripts/html2pdf.js +822 -0
  29. package/scripts/html2png.js +246 -0
  30. package/scripts/html2pptx.js +162 -0
  31. package/scripts/import-template.js +86 -0
  32. package/scripts/install-runtime.js +216 -0
  33. package/scripts/render-tldraw.js +44 -0
  34. package/scripts/validate-slides.js +221 -0
  35. package/skills/slides-grab/SKILL.md +65 -0
  36. package/skills/slides-grab/references/presentation-workflow-reference.md +61 -0
  37. package/skills/slides-grab-card-news/SKILL.md +35 -0
  38. package/skills/slides-grab-design/SKILL.md +88 -0
  39. package/skills/slides-grab-design/references/beautiful-slide-defaults.md +88 -0
  40. package/skills/slides-grab-design/references/design-gate.md +349 -0
  41. package/skills/slides-grab-design/references/design-rules.md +76 -0
  42. package/skills/slides-grab-design/references/design-system-full.md +568 -0
  43. package/skills/slides-grab-design/references/detailed-design-rules.md +70 -0
  44. package/skills/slides-grab-export/SKILL.md +55 -0
  45. package/skills/slides-grab-export/references/export-rules.md +27 -0
  46. package/skills/slides-grab-export/references/html2pptx.md +627 -0
  47. package/skills/slides-grab-export/references/ooxml.md +427 -0
  48. package/skills/slides-grab-export/references/pptx-skill-reference.md +189 -0
  49. package/skills/slides-grab-html/SKILL.md +67 -0
  50. package/skills/slides-grab-image/SKILL.md +82 -0
  51. package/skills/slides-grab-plan/SKILL.md +68 -0
  52. package/skills/slides-grab-plan/references/design-md-to-slides-conversion.md +135 -0
  53. package/skills/slides-grab-plan/references/outline-format.md +47 -0
  54. package/skills/slides-grab-plan/references/plan-workflow-reference.md +140 -0
  55. package/src/codex-imagen.js +182 -0
  56. package/src/design-diversity-data.js +6932 -0
  57. package/src/design-gate-report.js +244 -0
  58. package/src/design-gate-state.js +329 -0
  59. package/src/design-import.js +164 -0
  60. package/src/design-md-parser.js +415 -0
  61. package/src/design-styles-data.js +1928 -0
  62. package/src/design-styles.js +209 -0
  63. package/src/editor/codex-edit.js +584 -0
  64. package/src/editor/edit-subprocess.js +170 -0
  65. package/src/editor/editor-codex-prompt.md +50 -0
  66. package/src/editor/editor.html +1785 -0
  67. package/src/editor/js/editor-bbox.js +332 -0
  68. package/src/editor/js/editor-chat.js +56 -0
  69. package/src/editor/js/editor-direct-edit.js +238 -0
  70. package/src/editor/js/editor-dom.js +59 -0
  71. package/src/editor/js/editor-init.js +405 -0
  72. package/src/editor/js/editor-navigation.js +54 -0
  73. package/src/editor/js/editor-select.js +558 -0
  74. package/src/editor/js/editor-send.js +175 -0
  75. package/src/editor/js/editor-sse.js +163 -0
  76. package/src/editor/js/editor-state.js +41 -0
  77. package/src/editor/js/editor-type.js +71 -0
  78. package/src/editor/js/editor-utils.js +167 -0
  79. package/src/editor/js/model-registry.js +37 -0
  80. package/src/editor/screenshot.js +82 -0
  81. package/src/export-resolution.cjs +68 -0
  82. package/src/figma.js +71 -0
  83. package/src/html2pptx-scale.cjs +120 -0
  84. package/src/html2pptx.cjs +1262 -0
  85. package/src/image-contract.js +329 -0
  86. package/src/image-native.js +468 -0
  87. package/src/nano-banana.js +841 -0
  88. package/src/ohos-browser-bridge.cjs +272 -0
  89. package/src/pptx-raster-export.cjs +299 -0
  90. package/src/resolve.js +110 -0
  91. package/src/slide-mode.cjs +72 -0
  92. package/src/template-fidelity.js +267 -0
  93. package/src/template-import.js +505 -0
  94. package/src/template-layout.js +261 -0
  95. package/src/template-pack.js +255 -0
  96. package/src/tldraw/render.js +473 -0
  97. package/src/validation/cli.js +120 -0
  98. package/src/validation/core.js +1023 -0
  99. package/templates/chart.html +121 -0
  100. package/templates/closing.html +54 -0
  101. package/templates/content.html +50 -0
  102. package/templates/contents.html +60 -0
  103. package/templates/cover.html +64 -0
  104. package/templates/custom/.gitkeep +0 -0
  105. package/templates/custom/README.md +7 -0
  106. package/templates/design-styles/README.md +20 -0
  107. package/templates/design-styles/preview.html +4438 -0
  108. package/templates/diagram-tldraw.html +56 -0
  109. package/templates/diagram.html +98 -0
  110. package/templates/quote.html +31 -0
  111. package/templates/section-divider.html +43 -0
  112. package/templates/split-layout.html +43 -0
  113. package/templates/statistics.html +55 -0
  114. package/templates/team.html +49 -0
  115. package/templates/timeline.html +59 -0
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { mkdir } from 'node:fs/promises';
4
+ import { spawn } from 'node:child_process';
5
+ import { basename, resolve } from 'node:path';
6
+ import { pathToFileURL } from 'node:url';
7
+
8
+ const DEFAULT_SLIDES_DIR = 'slides';
9
+ const DEFAULT_OUTPUT_TEMPLATE = '%(title).80B-%(id)s.%(ext)s';
10
+
11
+ function printUsage() {
12
+ process.stdout.write(
13
+ [
14
+ 'Usage: node scripts/download-video.js [options]',
15
+ '',
16
+ 'Options:',
17
+ ' --url <url> Video page URL to download with yt-dlp',
18
+ ` --slides-dir <path> Slide directory (default: ${DEFAULT_SLIDES_DIR})`,
19
+ ' --output-name <name> Optional output stem inside <slides-dir>/assets/',
20
+ ' -h, --help Show this help message',
21
+ '',
22
+ 'Examples:',
23
+ ' node scripts/download-video.js --url https://www.youtube.com/watch?v=dQw4w9WgXcQ',
24
+ ' node scripts/download-video.js --url https://youtu.be/demo --slides-dir decks/q2 --output-name hero-video',
25
+ ].join('\n'),
26
+ );
27
+ process.stdout.write('\n');
28
+ }
29
+
30
+ function readOptionValue(args, index, optionName) {
31
+ const next = args[index + 1];
32
+ if (!next || next.startsWith('-')) {
33
+ throw new Error(`Missing value for ${optionName}.`);
34
+ }
35
+ return next;
36
+ }
37
+
38
+ function sanitizeOutputName(value) {
39
+ const trimmed = typeof value === 'string' ? value.trim() : '';
40
+ if (!trimmed) {
41
+ return '';
42
+ }
43
+
44
+ const baseName = basename(trimmed).replace(/\.[^.]+$/, '');
45
+ if (!baseName || baseName === '.' || baseName === '..') {
46
+ throw new Error('--output-name must be a simple file stem.');
47
+ }
48
+ if (baseName !== trimmed.replace(/\.[^.]+$/, '')) {
49
+ throw new Error('--output-name must not include path separators.');
50
+ }
51
+ return baseName;
52
+ }
53
+
54
+ export function parseCliArgs(args) {
55
+ const options = {
56
+ url: '',
57
+ slidesDir: DEFAULT_SLIDES_DIR,
58
+ outputName: '',
59
+ help: false,
60
+ };
61
+
62
+ for (let index = 0; index < args.length; index += 1) {
63
+ const arg = args[index];
64
+
65
+ if (arg === '-h' || arg === '--help') {
66
+ options.help = true;
67
+ continue;
68
+ }
69
+
70
+ if (arg === '--url') {
71
+ options.url = readOptionValue(args, index, '--url');
72
+ index += 1;
73
+ continue;
74
+ }
75
+
76
+ if (arg.startsWith('--url=')) {
77
+ options.url = arg.slice('--url='.length);
78
+ continue;
79
+ }
80
+
81
+ if (arg === '--slides-dir') {
82
+ options.slidesDir = readOptionValue(args, index, '--slides-dir');
83
+ index += 1;
84
+ continue;
85
+ }
86
+
87
+ if (arg.startsWith('--slides-dir=')) {
88
+ options.slidesDir = arg.slice('--slides-dir='.length);
89
+ continue;
90
+ }
91
+
92
+ if (arg === '--output-name') {
93
+ options.outputName = readOptionValue(args, index, '--output-name');
94
+ index += 1;
95
+ continue;
96
+ }
97
+
98
+ if (arg.startsWith('--output-name=')) {
99
+ options.outputName = arg.slice('--output-name='.length);
100
+ continue;
101
+ }
102
+
103
+ throw new Error(`Unknown option: ${arg}`);
104
+ }
105
+
106
+ if (typeof options.slidesDir !== 'string' || options.slidesDir.trim() === '') {
107
+ throw new Error('--slides-dir must be a non-empty string.');
108
+ }
109
+
110
+ options.slidesDir = options.slidesDir.trim();
111
+ options.outputName = sanitizeOutputName(options.outputName);
112
+ options.url = typeof options.url === 'string' ? options.url.trim() : '';
113
+
114
+ if (!options.help && !options.url) {
115
+ throw new Error('--url is required.');
116
+ }
117
+
118
+ return options;
119
+ }
120
+
121
+ function buildOutputTemplate(outputName) {
122
+ return outputName ? `${outputName}.%(ext)s` : DEFAULT_OUTPUT_TEMPLATE;
123
+ }
124
+
125
+ export function buildYtDlpArgs({ url, assetsDir, outputName = '' }) {
126
+ return [
127
+ '--no-playlist',
128
+ '--restrict-filenames',
129
+ '--format',
130
+ 'mp4/bestvideo+bestaudio/best',
131
+ '--merge-output-format',
132
+ 'mp4',
133
+ '--paths',
134
+ assetsDir,
135
+ '--output',
136
+ buildOutputTemplate(outputName),
137
+ '--print',
138
+ 'after_move:filepath',
139
+ url,
140
+ ];
141
+ }
142
+
143
+ function runYtDlp(args) {
144
+ return new Promise((resolvePromise, rejectPromise) => {
145
+ const child = spawn('yt-dlp', args, {
146
+ cwd: process.cwd(),
147
+ stdio: ['ignore', 'pipe', 'pipe'],
148
+ });
149
+
150
+ let stdout = '';
151
+ let stderr = '';
152
+
153
+ child.stdout.on('data', (chunk) => {
154
+ stdout += chunk.toString();
155
+ });
156
+ child.stderr.on('data', (chunk) => {
157
+ stderr += chunk.toString();
158
+ });
159
+ child.on('error', (error) => {
160
+ if (error.code === 'ENOENT') {
161
+ rejectPromise(new Error('yt-dlp is not installed or not available in PATH.'));
162
+ return;
163
+ }
164
+ rejectPromise(error);
165
+ });
166
+ child.on('close', (code) => {
167
+ if (code === 0) {
168
+ resolvePromise({ stdout, stderr });
169
+ return;
170
+ }
171
+ rejectPromise(new Error(`yt-dlp failed (${code})\n${stderr || stdout}`.trim()));
172
+ });
173
+ });
174
+ }
175
+
176
+ async function main() {
177
+ const options = parseCliArgs(process.argv.slice(2));
178
+ if (options.help) {
179
+ printUsage();
180
+ return;
181
+ }
182
+
183
+ const slidesDir = resolve(process.cwd(), options.slidesDir);
184
+ const assetsDir = resolve(slidesDir, 'assets');
185
+ await mkdir(assetsDir, { recursive: true });
186
+
187
+ const { stdout } = await runYtDlp(buildYtDlpArgs({
188
+ url: options.url,
189
+ assetsDir,
190
+ outputName: options.outputName,
191
+ }));
192
+
193
+ const downloadedPath = stdout
194
+ .split(/\r?\n/)
195
+ .map((line) => line.trim())
196
+ .filter(Boolean)
197
+ .at(-1);
198
+
199
+ if (!downloadedPath) {
200
+ throw new Error('yt-dlp completed but did not report the downloaded file path.');
201
+ }
202
+
203
+ const assetReference = `./assets/${basename(downloadedPath)}`;
204
+ process.stdout.write(`Downloaded video: ${downloadedPath}\n`);
205
+ process.stdout.write(`Use in slide HTML: ${assetReference}\n`);
206
+ }
207
+
208
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
209
+ main().catch((error) => {
210
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
211
+ process.exit(1);
212
+ });
213
+ }