html2pptx-local-mcp 1.1.17

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.
@@ -0,0 +1,2082 @@
1
+ export const DOCS_LANGUAGES = ['en', 'ja'];
2
+
3
+ /* ------------------------------------------------------------------ */
4
+ /* Code samples */
5
+ /* ------------------------------------------------------------------ */
6
+
7
+ const CURL_EXAMPLE = `curl -X POST https://html2pptx.app/api/export/jobs \\
8
+ -H "Authorization: Bearer sk_live_xxxx" \\
9
+ -H "Content-Type: application/json" \\
10
+ -H "Idempotency-Key: my-unique-request-id-123" \\
11
+ -d '{
12
+ "fileName": "quarterly-review.pptx",
13
+ "html": "<section class=\\"slide\\" style=\\"width:1600px;height:900px;padding:64px\\"><h1>Hello</h1><p>Generated via API</p></section>",
14
+ "css": ".slide { font-family: Arial, sans-serif; background: #fff; }",
15
+ "autoEmbedFonts": false,
16
+ "responseFormat": "url",
17
+ "metadata": {
18
+ "channel": "api",
19
+ "source": "docs-quickstart"
20
+ }
21
+ }'
22
+
23
+ # Response (200 OK):
24
+ # {
25
+ # "jobId": "5d934729-a0db-4aa9-bc65-e7a3e7e52b32",
26
+ # "status": "queued",
27
+ # "createdAt": "2026-04-02T10:30:00Z",
28
+ # "fileName": "quarterly-review.pptx",
29
+ # "slideCount": 1
30
+ # }
31
+ # Response headers include: x-request-id: req_abc123...
32
+
33
+ # Poll for completion:
34
+ curl -s https://html2pptx.app/api/export/jobs/5d934729-a0db-4aa9-bc65-e7a3e7e52b32 \\
35
+ -H "Authorization: Bearer sk_live_xxxx"
36
+
37
+ # Response (200 OK, when completed with responseFormat "url"):
38
+ # {
39
+ # "jobId": "5d934729-a0db-4aa9-bc65-e7a3e7e52b32",
40
+ # "status": "completed",
41
+ # "createdAt": "2026-04-02T10:30:00Z",
42
+ # "completedAt": "2026-04-02T10:30:12Z",
43
+ # "fileName": "quarterly-review.pptx",
44
+ # "slideCount": 1,
45
+ # "mimeType": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
46
+ # "downloadUrl": "https://storage.example.com/quarterly-review.pptx?token=..."
47
+ # }`;
48
+
49
+ const JS_EXAMPLE = `const response = await fetch("https://html2pptx.app/api/export/jobs", {
50
+ method: "POST",
51
+ headers: {
52
+ "Authorization": "Bearer sk_live_xxxx",
53
+ "Content-Type": "application/json",
54
+ "Idempotency-Key": "my-unique-request-id-123",
55
+ },
56
+ body: JSON.stringify({
57
+ fileName: "quarterly-review.pptx",
58
+ html: \`<section class="slide" style="width:1600px;height:900px">
59
+ <h1>Hello World</h1>
60
+ <p>Generated via API</p>
61
+ </section>\`,
62
+ css: ".slide { font-family: Arial, sans-serif; background: #fff; }",
63
+ autoEmbedFonts: false,
64
+ responseFormat: "url",
65
+ metadata: { channel: "api", source: "docs-js" },
66
+ }),
67
+ });
68
+
69
+ const { jobId } = await response.json();
70
+ const requestId = response.headers.get("x-request-id");
71
+ console.log("Job created:", jobId, "Request ID:", requestId);
72
+
73
+ // Poll for completion
74
+ const poll = async (id) => {
75
+ const res = await fetch(\`https://html2pptx.app/api/export/jobs/\${id}\`, {
76
+ headers: { "Authorization": "Bearer sk_live_xxxx" },
77
+ });
78
+ const data = await res.json();
79
+ if (data.status === "completed") return data;
80
+ if (data.status === "failed") throw new Error(data.message || data.error);
81
+ await new Promise(r => setTimeout(r, 2000));
82
+ return poll(id);
83
+ };
84
+
85
+ const completed = await poll(jobId);
86
+ // With responseFormat "url", use downloadUrl directly
87
+ console.log("Download URL:", completed.downloadUrl);
88
+ // With responseFormat "base64", decode fileBase64
89
+ // const bytes = Uint8Array.from(atob(completed.fileBase64), c => c.charCodeAt(0));`;
90
+
91
+ const PYTHON_EXAMPLE = `import requests
92
+ import time
93
+
94
+ API_KEY = "sk_live_xxxx"
95
+ BASE_URL = "https://html2pptx.app"
96
+
97
+ # 1. Create export job
98
+ resp = requests.post(
99
+ f"{BASE_URL}/api/export/jobs",
100
+ headers={
101
+ "Authorization": f"Bearer {API_KEY}",
102
+ "Content-Type": "application/json",
103
+ "Idempotency-Key": "my-unique-request-id-123",
104
+ },
105
+ json={
106
+ "fileName": "quarterly-review.pptx",
107
+ "html": '<section class="slide" style="width:1600px;height:900px"><h1>Hello</h1></section>',
108
+ "css": ".slide { font-family: Arial, sans-serif; }",
109
+ "autoEmbedFonts": False,
110
+ "responseFormat": "url",
111
+ "metadata": {"channel": "api", "source": "docs-python"},
112
+ },
113
+ )
114
+ job_id = resp.json()["jobId"]
115
+ request_id = resp.headers.get("x-request-id")
116
+ print(f"Job created: {job_id} (request-id: {request_id})")
117
+
118
+ # 2. Poll for completion
119
+ while True:
120
+ status_resp = requests.get(
121
+ f"{BASE_URL}/api/export/jobs/{job_id}",
122
+ headers={"Authorization": f"Bearer {API_KEY}"},
123
+ )
124
+ data = status_resp.json()
125
+ if data["status"] == "completed":
126
+ break
127
+ if data["status"] == "failed":
128
+ raise RuntimeError(data.get("message") or data.get("error"))
129
+ time.sleep(2)
130
+
131
+ # 3. Download the PPTX file (responseFormat "url")
132
+ download_resp = requests.get(data["downloadUrl"])
133
+ with open("output.pptx", "wb") as f:
134
+ f.write(download_resp.content)
135
+ print("Saved to output.pptx")`;
136
+
137
+ const JOB_RESPONSE_EXAMPLE = `{
138
+ "jobId": "5d934729-a0db-4aa9-bc65-e7a3e7e52b32",
139
+ "status": "queued",
140
+ "createdAt": "2026-04-02T10:30:00Z",
141
+ "fileName": "quarterly-review.pptx",
142
+ "slideCount": 1
143
+ }`;
144
+
145
+ const JOB_STATUS_EXAMPLE = `{
146
+ "jobId": "5d934729-a0db-4aa9-bc65-e7a3e7e52b32",
147
+ "status": "completed",
148
+ "createdAt": "2026-04-02T10:30:00Z",
149
+ "completedAt": "2026-04-02T10:30:12Z",
150
+ "fileName": "quarterly-review.pptx",
151
+ "slideCount": 3,
152
+ "mimeType": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
153
+ "downloadUrl": "https://storage.example.com/quarterly-review.pptx?token=..."
154
+ }`;
155
+
156
+ const SLIDE_SAMPLE_CODE = `<section class="slide" style="width: 1600px; height: 900px;">
157
+ <header class="hero">
158
+ <div class="eyebrow">Quarterly review</div>
159
+ <h1>Presentation-ready HTML</h1>
160
+ <p>Build the layout once, confirm it in the preview, then export.</p>
161
+ </header>
162
+
163
+ <section class="grid">
164
+ <article class="card">...</article>
165
+ <article class="card">...</article>
166
+ </section>
167
+ </section>`;
168
+
169
+ const SKILL_INSTALL_COMMAND_EN = `# Choose the command for your agent
170
+ # Claude Code
171
+ npx skills add https://html2pptx.app -a claude-code
172
+
173
+ # Codex
174
+ npx skills add https://html2pptx.app -a codex
175
+
176
+ # Cursor
177
+ npx skills add https://html2pptx.app -a cursor
178
+
179
+ # Windsurf
180
+ npx skills add https://html2pptx.app -a windsurf
181
+
182
+ # Preview published skills without installing
183
+ npx skills add https://html2pptx.app --list
184
+
185
+ # More agents / multiple targets: use the interactive selector
186
+ npx skills add https://html2pptx.app
187
+
188
+ # Install remote MCP and local MCP for edit-slide
189
+ npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude`;
190
+
191
+ const SKILL_INSTALL_COMMAND_JA = `# 使うエージェントのコマンドを選択
192
+ # Claude Code
193
+ npx skills add https://html2pptx.app -a claude-code
194
+
195
+ # Codex
196
+ npx skills add https://html2pptx.app -a codex
197
+
198
+ # Cursor
199
+ npx skills add https://html2pptx.app -a cursor
200
+
201
+ # Windsurf
202
+ npx skills add https://html2pptx.app -a windsurf
203
+
204
+ # インストールせずに公開Skillを確認
205
+ npx skills add https://html2pptx.app --list
206
+
207
+ # その他のエージェント / 複数指定は対話形式で選択
208
+ npx skills add https://html2pptx.app
209
+
210
+ # Remote MCP と edit-slide 用 Local MCP をまとめて追加
211
+ npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude`;
212
+
213
+ const SKILL_INVOCATION_EXAMPLE = `# 例: Claude Code でスライド作成 → PPTX出力
214
+
215
+ > 「この会議メモから5枚のプレゼンを作って、PPTXで出力して」
216
+
217
+ # エージェントが自動で実行するフロー:
218
+ # 1. SKILL.md を読み込み、html2pptx.app のHTML契約を理解
219
+ # 2. 会議メモを解析し、スライド構成を設計
220
+ # 3. .slide クラス + 明示サイズ付きのスライドセーフHTMLを生成(1600x900 はデフォルト例)
221
+ # 4. diagnose でマークアップを検証(safe / needs-rewrite / out-of-scope)
222
+ # 5. html2pptx.app API にエクスポートジョブを送信
223
+ # 6. 完了をポーリングし、completed payload をユーザーに返却
224
+
225
+ # APIキーの設定(環境変数)
226
+ export HTML2PPTX_API_KEY="sk_live_xxxx"`;
227
+
228
+ const SKILL_AVAILABLE_LIST = [
229
+ {
230
+ name: 'html-to-pptx-slide-authoring',
231
+ description: 'スライド用HTML/CSSの作成・診断・修正。HTMLがPPTXに正しく変換されるかを事前チェックし、問題があれば自動で書き換え。',
232
+ capabilities: ['HTML診断(safe / needs-rewrite / out-of-scope)', 'マークアップ自動書き換え', 'スライドHTML新規生成', '入力バリデーション'],
233
+ },
234
+ {
235
+ name: 'pptx-studio-export-automation',
236
+ description: 'APIジョブの作成・ステータス管理・エラーハンドリング。REST API / MCP の使い分け判断も含む。',
237
+ capabilities: ['エクスポートジョブ作成', 'ポーリング&完了待機', 'エラー分析&リトライ', 'プラン制限の事前チェック'],
238
+ },
239
+ {
240
+ name: 'edit-slide',
241
+ description: 'ローカルHTMLスライドをlocalhost上のvisual editorで開き、localhost bridge 経由で同じファイルに保存。',
242
+ capabilities: ['html2pptx_open_local_slide_editor', 'PowerPoint風UIで視覚編集', 'ローカルHTMLへの自動保存', '変更検知と競合防止'],
243
+ },
244
+ ];
245
+
246
+ const MCP_INSTALL_EXAMPLE = `# Remote MCP と edit-slide 用 Local MCP をまとめて追加
247
+ npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude`;
248
+
249
+ const MCP_CONFIG_EXAMPLE = `// 方法2: 設定ファイルに手動追加
250
+
251
+ // Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json
252
+ // VS Code: .vscode/mcp.json
253
+ // Claude Code: .claude/settings.json → mcpServers
254
+
255
+ {
256
+ "mcpServers": {
257
+ "html2pptx-local": {
258
+ "type": "stdio",
259
+ "command": "node",
260
+ "args": [
261
+ "/Users/<you>/.html2pptx/bin/html2pptx-local-mcp-launcher.mjs"
262
+ ],
263
+ "env": {}
264
+ }
265
+ }
266
+ }`;
267
+
268
+ const MCP_USAGE_EXAMPLE = `# Example conversation in Claude Desktop with html2pptx.app MCP:
269
+
270
+ User: "Create a presentation about our Q1 2026 results."
271
+
272
+ Claude (via MCP):
273
+ 1. Calls html2pptx_list_export_plans to inspect available plans
274
+ 2. Generates slide HTML from the conversation context
275
+ 3. Calls html2pptx_create_export_job with the HTML payload
276
+ 4. Calls html2pptx_wait_for_export_job to poll until completion
277
+ 5. Returns the resulting PPTX payload or follow-up instructions
278
+
279
+ # Behind the scenes, the MCP tools handle:
280
+ # - Authentication with your configured API key
281
+ # - Proper HTML contract formatting (.slide class, explicit slide dimensions)
282
+ # - Status polling with exponential backoff
283
+ # - Error handling and retry logic`;
284
+
285
+ const REPORT_EXAMPLE = `const slides = quarterly_data.map((quarter, i) => \`
286
+ <section class="slide" style="width:1600px;height:900px;padding:60px;font-family:'Noto Sans JP',sans-serif;">
287
+ <h2 style="color:#1a1a2e;font-size:36px;">Q\${i+1} Results</h2>
288
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:40px;margin-top:40px;">
289
+ <div style="background:#f0f4ff;border-radius:16px;padding:32px;">
290
+ <p style="font-size:14px;color:#6b7280;">Revenue</p>
291
+ <p style="font-size:48px;font-weight:700;color:#1a1a2e;">\${quarter.revenue}</p>
292
+ </div>
293
+ <div style="background:#f0fdf4;border-radius:16px;padding:32px;">
294
+ <p style="font-size:14px;color:#6b7280;">Growth</p>
295
+ <p style="font-size:48px;font-weight:700;color:#16a34a;">\${quarter.growth}%</p>
296
+ </div>
297
+ </div>
298
+ </section>
299
+ \`).join("\\n");
300
+
301
+ const resp = await fetch("/api/export/jobs", {
302
+ method: "POST",
303
+ headers: { "Authorization": "Bearer sk_live_xxxx", "Content-Type": "application/json" },
304
+ body: JSON.stringify({ fileName: "q-report.pptx", html: slides }),
305
+ });`;
306
+
307
+ const PROPOSAL_TEMPLATE_EXAMPLE = `// Sales proposal template with dynamic client data
308
+ function generateProposal(client) {
309
+ return \`
310
+ <section class="slide" style="width:1600px;height:900px;padding:60px;background:linear-gradient(135deg,#1a1a2e,#16213e);">
311
+ <h1 style="color:#fff;font-size:48px;">\${client.companyName} 御中</h1>
312
+ <p style="color:#a0aec0;font-size:24px;margin-top:20px;">ご提案書 - \${client.projectName}</p>
313
+ <div style="position:absolute;bottom:60px;left:60px;color:#718096;font-size:14px;">
314
+ \${new Date().toLocaleDateString('ja-JP')} | Confidential
315
+ </div>
316
+ </section>
317
+ <section class="slide" style="width:1600px;height:900px;padding:60px;">
318
+ <h2 style="font-size:36px;color:#1a1a2e;">提案概要</h2>
319
+ <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:30px;margin-top:40px;">
320
+ \${client.features.map(f => \`
321
+ <div style="background:#f7fafc;border-radius:12px;padding:24px;">
322
+ <h3 style="font-size:20px;color:#2d3748;">\${f.title}</h3>
323
+ <p style="font-size:14px;color:#718096;margin-top:8px;">\${f.description}</p>
324
+ </div>
325
+ \`).join('')}
326
+ </div>
327
+ </section>
328
+ \`;
329
+ }`;
330
+
331
+ const SAAS_EMBED_EXAMPLE = `// Backend route: POST /api/dashboard/export-pptx
332
+ app.post("/api/dashboard/export-pptx", async (req, res) => {
333
+ const { dashboardId } = req.body;
334
+ const dashboard = await getDashboard(dashboardId);
335
+
336
+ // Render each widget as a slide
337
+ const slides = dashboard.widgets.map(widget => \`
338
+ <section class="slide" style="width:1600px;height:900px;padding:40px;">
339
+ <h2 style="font-size:28px;color:#1a1a2e;">\${widget.title}</h2>
340
+ <div style="margin-top:20px;">\${widget.renderToHTML()}</div>
341
+ </section>
342
+ \`).join("");
343
+
344
+ // Call html2pptx.app API
345
+ const job = await fetch(process.env.HTML2PPTX_API_URL + "/api/export/jobs", {
346
+ method: "POST",
347
+ headers: {
348
+ "Authorization": \`Bearer \${process.env.HTML2PPTX_API_KEY}\`,
349
+ "Content-Type": "application/json",
350
+ },
351
+ body: JSON.stringify({
352
+ fileName: \`\${dashboard.name}.pptx\`,
353
+ html: slides,
354
+ }),
355
+ });
356
+
357
+ const { jobId } = await job.json();
358
+ res.json({ jobId, statusUrl: \`/api/export/jobs/\${jobId}\` });
359
+ });`;
360
+
361
+ const ERROR_CODES_EXAMPLE = `{
362
+ "type": "https://html2pptx.app/errors/slides-limit-exceeded",
363
+ "status": 422,
364
+ "title": "Slides limit exceeded",
365
+ "detail": "Plan Starter supports up to 200 slides per job. You submitted 260 slides.",
366
+ "instance": "/api/export/jobs",
367
+ "error": "slides_limit_exceeded",
368
+ "message": "Plan Starter supports up to 200 slides per job.",
369
+ "slideCount": 260
370
+ }`;
371
+
372
+ const PLANS_RESPONSE_EXAMPLE = `{
373
+ "recommendedPlanId": "founding_beta",
374
+ "plans": [
375
+ {
376
+ "id": "free_web",
377
+ "name": "Free Preview",
378
+ "includes": { "api": true, "skills": true, "mcp": true },
379
+ "limits": {
380
+ "requestsPerMinute": 3,
381
+ "dailyRequestLimit": 100,
382
+ "monthlyRequestLimit": 0,
383
+ "monthlyReviewThreshold": 1000,
384
+ "monthlyUpgradePromptThreshold": 2000,
385
+ "maxSlidesPerJob": 50,
386
+ "concurrentJobs": 1,
387
+ "apiKeys": 1,
388
+ "maxPayloadBytes": 1048576
389
+ }
390
+ }
391
+ ],
392
+ "note": "Free Preview is generous for personal use. Paid tiers unlock commercial operation, team sharing, automation throughput, and support."
393
+ }`;
394
+
395
+ const WEB_EXPORT_EXAMPLE = `const create = await fetch("/api/web-export/jobs", {
396
+ method: "POST",
397
+ headers: { "Content-Type": "application/json" },
398
+ body: JSON.stringify({
399
+ fileName: "studio-export.pptx",
400
+ html: document.querySelector("#slides-root").innerHTML,
401
+ css: ".slide { width: 1600px; height: 900px; }",
402
+ }),
403
+ });
404
+
405
+ const queued = await create.json();
406
+ console.log("Hosted web export job:", queued.jobId);`;
407
+
408
+ /* ------------------------------------------------------------------ */
409
+ /* Docs copy -- English */
410
+ /* ------------------------------------------------------------------ */
411
+
412
+ export const DOCS_COPY = {
413
+ en: {
414
+ lang: 'en',
415
+ languageLabel: 'English',
416
+ metaTitle: 'Documentation | html2pptx.app',
417
+ metaDescription:
418
+ 'Comprehensive documentation for html2pptx.app: the only API that converts HTML/CSS to fully editable PowerPoint files. REST API, Skills integration, MCP protocol, quickstart guides, and the HTML contract for reliable PowerPoint generation.',
419
+
420
+ navSections: [
421
+ { id: 'overview', label: 'Service Overview', children: [
422
+ { id: 'overview-channels', label: 'Channels' },
423
+ { id: 'overview-comparison', label: 'Comparison' },
424
+ { id: 'overview-css', label: 'CSS Support' },
425
+ ]},
426
+ { id: 'quickstart', label: 'Quick Start' },
427
+ { id: 'api-reference', label: 'API Reference', children: [
428
+ { id: 'api-html-elements', label: 'HTML Elements' },
429
+ { id: 'api-html-forbidden', label: 'Forbidden' },
430
+ ]},
431
+ { id: 'skills', label: 'Skills Integration', children: [
432
+ { id: 'skills-setup', label: 'Setup' },
433
+ { id: 'skills-local-editor', label: 'Local Visual Editor' },
434
+ { id: 'skills-capabilities', label: 'Capabilities' },
435
+ ]},
436
+ { id: 'mcp', label: 'MCP Integration', children: [
437
+ { id: 'mcp-setup', label: 'Setup' },
438
+ { id: 'mcp-auth', label: 'Authentication' },
439
+ { id: 'mcp-tools', label: 'Tools' },
440
+ { id: 'mcp-example', label: 'Example' },
441
+ ]},
442
+ { id: 'cli', label: 'CLI Tool', children: [
443
+ { id: 'cli-install', label: 'Installation' },
444
+ { id: 'cli-commands', label: 'Commands' },
445
+ { id: 'cli-examples', label: 'Examples' },
446
+ ]},
447
+ { id: 'use-cases', label: 'Use Cases' },
448
+ { id: 'plans', label: 'Plans & Pricing', children: [
449
+ { id: 'plans-rate-limits', label: 'Rate Limits' },
450
+ ]},
451
+ { id: 'security', label: 'Security & Limits', children: [
452
+ { id: 'security-checklist', label: 'Checklist' },
453
+ ]},
454
+ { id: 'faq', label: 'FAQ', children: [
455
+ { id: 'faq-troubleshoot', label: 'Troubleshoot' },
456
+ ]},
457
+ ],
458
+
459
+ /* --- Section 1: Service Overview --- */
460
+ overviewTitle: 'Service Overview',
461
+ overviewSubtitle: 'What is html2pptx.app',
462
+ overviewDescription:
463
+ 'html2pptx.app converts your HTML and CSS into fully editable PowerPoint files -- not screenshots. Your text stays editable, layouts are preserved, and CSS properties like Flexbox, Grid, gradients, and shadows are faithfully reproduced. The result is a production-ready presentation file.',
464
+ overviewHighlight: 'html2pptx.app is the only API that produces fully editable PowerPoint from HTML/CSS.',
465
+ overviewArchTitle: 'Architecture',
466
+ overviewArchDescription: 'html2pptx.app follows a four-stage pipeline that separates concerns for reliability and scalability:',
467
+ overviewArchSteps: [
468
+ { label: 'Client', detail: 'Your application, agent, or script sends HTML/CSS via REST API. Any language or platform that can make HTTP requests works.' },
469
+ { label: 'API Gateway', detail: 'Handles authentication (Bearer / X-API-Key), rate limiting per plan tier, request validation, and the initial job creation request.' },
470
+ { label: 'Durable Queue', detail: 'Job metadata is stored in Convex, large request payloads are stored in object storage, and Cloud Tasks can dispatch processing without losing jobs on worker restart.' },
471
+ { label: 'Private Worker', detail: 'The private renderer loads the saved job, converts your HTML/CSS into a fully editable PowerPoint file, and updates the durable job state as it progresses.' },
472
+ { label: 'PPTX Output', detail: 'The generated PowerPoint file is uploaded to cloud storage and a time-limited signed URL is returned for download. Files are retained for 24 hours.' },
473
+ ],
474
+ overviewComparisonTitle: 'How html2pptx.app Compares',
475
+ overviewComparison: [
476
+ { feature: 'Conversion method', html2pptx: 'Fully editable PowerPoint output', others: 'Screenshot/raster image per slide' },
477
+ { feature: 'Text editability', html2pptx: 'Fully editable text boxes', others: 'Flat image -- no text editing' },
478
+ { feature: 'CSS support', html2pptx: 'Flexbox, Grid, gradients, shadows, transforms', others: 'Limited or none' },
479
+ { feature: 'SVG handling', html2pptx: 'Converted to high-quality PNG images', others: 'Converted to PNG' },
480
+ { feature: 'File size', html2pptx: 'Usually compact, depends on embedded imagery', others: 'Large (embedded images)' },
481
+ { feature: 'Font embedding', html2pptx: 'Automatic web font embedding', others: 'Not supported' },
482
+ ],
483
+ overviewChannelsTitle: 'Three Integration Channels',
484
+ overviewChannels: [
485
+ {
486
+ title: 'REST API',
487
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>',
488
+ body: 'Standard HTTP endpoints for creating HTML-to-PPTX export jobs and polling status. Best for backend integrations, internal tools, and SaaS embedding. Works with any language -- curl, JavaScript, Python, Go, Ruby, and more. Template publishing is not a REST API surface.',
489
+ },
490
+ {
491
+ title: 'Skills',
492
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/claude/default.svg',
493
+ body: 'Register the html2pptx skill for agent tools like Claude Code and Codex. The agent can diagnose, rewrite, export slide-safe HTML, open local editing, and publish HTML template drafts through the built-in remote MCP workflow. Ideal for AI-powered workflows where the agent manages the full pipeline.',
494
+ },
495
+ {
496
+ title: 'MCP (Model Context Protocol)',
497
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="2"/><path d="M16.24 7.76a6 6 0 010 8.49m-8.48-.01a6 6 0 010-8.49m11.31-2.82a10 10 0 010 14.14m-14.14 0a10 10 0 010-14.14"/></svg>',
498
+ body: 'Expose the backend to AI agents via the MCP protocol. Use the remote HTTP endpoint at /mcp for export, docs, catalog, and template publishing tools; use local stdio MCP or direct CLI for opening local HTML in edit-slide. HTML template drafts must be created through remote MCP after validation.',
499
+ },
500
+ ],
501
+ overviewCssTitle: 'Supported CSS Features',
502
+ overviewCssFeatures: [
503
+ { category: 'Layout', features: 'display: flex, display: grid, position: absolute/relative, gap, align-items, justify-content' },
504
+ { category: 'Box Model', features: 'padding, margin, width, height, box-sizing, overflow: hidden' },
505
+ { category: 'Background', features: 'background-color, linear-gradient(), radial-gradient(), background-image (URL/base64)' },
506
+ { category: 'Border', features: 'border, border-radius (including per-corner), border-color, border-width' },
507
+ { category: 'Shadow', features: 'box-shadow (single and multiple), text-shadow' },
508
+ { category: 'Typography', features: 'font-family, font-size, font-weight, color, text-align, line-height, letter-spacing' },
509
+ { category: 'Transform', features: 'transform: rotate(), scale(), translate(), skew()' },
510
+ { category: 'Visual', features: 'opacity, visibility, z-index, object-fit' },
511
+ ],
512
+ overviewUseCasesTitle: 'Use Cases',
513
+ overviewUseCases: [
514
+ 'Automated report generation from live data sources',
515
+ 'Agent-powered presentation creation from text prompts',
516
+ 'Internal tool integration for recurring slide decks',
517
+ 'SaaS export feature embedding (dashboard-to-PPTX)',
518
+ 'Brand-compliant template population',
519
+ 'Meeting notes to presentation conversion via AI agents',
520
+ ],
521
+ overviewFeaturesTitle: 'Supported Features',
522
+ overviewFeatures: [
523
+ 'SVGs are converted to high-quality images for reliable output',
524
+ 'Automatic web font embedding (Google Fonts, custom fonts)',
525
+ 'Flexbox and CSS Grid layout support with faithful PowerPoint reproduction',
526
+ 'Gradients, shadows, and border-radius faithfully reproduced in PowerPoint',
527
+ 'Base64 and URL image handling with automatic optimization',
528
+ 'Explicit slide canvases with custom width/height/layout support. 1600x900px (13.333in x 7.5in) remains the default example',
529
+ 'Multi-slide support (each .slide element becomes one PPTX slide)',
530
+ 'Japanese font support (Noto Sans JP, Yu Gothic, Meiryo)',
531
+ 'Hosted Studio and hosted web export for manual use in the browser',
532
+ ],
533
+
534
+ /* --- Section 2: Quick Start --- */
535
+ quickstartTitle: 'Quick Start',
536
+ quickstartSubtitle: 'Your first authenticated export in 4 steps',
537
+ quickstartIntro: 'The REST API is asynchronous: create a job, poll status, then decode the returned fileBase64 when the job is completed.',
538
+ quickstartSteps: [
539
+ {
540
+ step: '1',
541
+ title: 'Sign Up',
542
+ body: 'Create an account at <a href="https://html2pptx.app" target="_blank" rel="noopener noreferrer" class="text-blue-600 underline hover:text-blue-800">html2pptx.app</a>. Free Preview lets you validate output quality, and Founder Beta unlocks API keys for real API usage.',
543
+ },
544
+ {
545
+ step: '2',
546
+ title: 'Get API Key',
547
+ body: 'Navigate to the Dashboard and click "Create API Key". Copy and store it securely -- it will only be shown once. Your key starts with sk_live_ and should be treated as a secret.',
548
+ },
549
+ {
550
+ step: '3',
551
+ title: 'Send First Request',
552
+ body: 'POST your HTML slide content to /api/export/jobs with your API key in the Authorization header. The API returns a jobId that you can use to track the export.',
553
+ },
554
+ {
555
+ step: '4',
556
+ title: 'Download PPTX',
557
+ body: 'Poll GET /api/export/jobs/{jobId} until status is "completed" (typically 5-15 seconds). The response includes a downloadUrl for the PPTX file. Use responseFormat: "base64" if you need the file content inline.',
558
+ },
559
+ ],
560
+ quickstartCurlTitle: 'curl',
561
+ quickstartCurlCode: CURL_EXAMPLE,
562
+ quickstartJsTitle: 'JavaScript (fetch)',
563
+ quickstartJsCode: JS_EXAMPLE,
564
+ quickstartPythonTitle: 'Python (requests)',
565
+ quickstartPythonCode: PYTHON_EXAMPLE,
566
+ quickstartCodeTabs: [
567
+ { label: 'curl', code: CURL_EXAMPLE },
568
+ { label: 'JavaScript', icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/javascript/default.svg', code: JS_EXAMPLE },
569
+ { label: 'Python', icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/python/default.svg', code: PYTHON_EXAMPLE },
570
+ ],
571
+
572
+ /* --- Section 3: API Reference --- */
573
+ apiTitle: 'API Reference',
574
+ apiBaseUrl: 'Base URL: https://html2pptx.app',
575
+ apiContentType: 'All request and response bodies use application/json. The create endpoint accepts top-level html/css/fileName fields plus optional width/height/layout controls; there is no nested payload wrapper.',
576
+
577
+ apiAuthTitle: 'Authentication',
578
+ apiAuthDescription:
579
+ 'All commercial API endpoints require authentication. Include your API key in one of the following headers. Keys are scoped per environment (test vs. production) and can be rotated from the Dashboard.',
580
+ apiAuthMethods: [
581
+ { header: 'Authorization', value: 'Bearer sk_live_xxxx', note: 'Recommended -- standard Bearer token format used by most HTTP clients and libraries' },
582
+ { header: 'X-API-Key', value: 'sk_live_xxxx', note: 'Alternative header for environments where Authorization is reserved (e.g., API gateways, proxies)' },
583
+ ],
584
+ apiRateLimitTitle: 'Rate Limiting',
585
+ apiRateLimitDescription: 'Every REST API response includes headers that describe your current per-minute window, daily limit, and monthly fair-use status. Limits are enforced per API key for REST calls and per authenticated principal for remote MCP calls.',
586
+ apiRateLimitHeaders: [
587
+ { header: 'x-request-id', description: 'Unique request identifier included in every API response. Useful for debugging and when contacting support.' },
588
+ { header: 'X-Plan-Id', description: 'The effective plan ID applied to the request.' },
589
+ { header: 'X-RateLimit-Limit', description: 'Maximum requests allowed in the current one-minute window.' },
590
+ { header: 'X-RateLimit-Remaining', description: 'Requests remaining in the current window.' },
591
+ { header: 'Retry-After', description: 'Seconds to wait before retrying after a 429 response.' },
592
+ { header: 'X-Daily-Limit', description: 'Returned on plans with a daily export cap.' },
593
+ { header: 'X-Daily-Remaining', description: 'Remaining jobs in the current UTC day.' },
594
+ { header: 'X-Monthly-Used', description: 'Exports accepted in the current UTC month.' },
595
+ { header: 'X-Fair-Use-State', description: 'Monthly fair-use status such as normal, review, or upgrade_recommended.' },
596
+ ],
597
+ apiOperationalTitle: 'Job Lifecycle Notes',
598
+ apiOperationalItems: [
599
+ 'POST /api/export/jobs returns immediately with a queued job descriptor. It does not block until the PPTX is finished.',
600
+ 'Use the public status route at GET /api/export/jobs/{jobId}. Do not rely on any upstream worker URL that may appear in internal payloads.',
601
+ 'The completed REST response currently includes fileBase64 and mimeType. Decode fileBase64 to write the PPTX to disk or return it to the browser.',
602
+ 'Job ownership is bound to the API key or authenticated MCP principal that created the job. A different key cannot read the same jobId.',
603
+ 'Slide count is derived server-side from sanitized .slide roots. Client-provided counts are ignored for enforcement.',
604
+ ],
605
+
606
+ apiEndpoints: [
607
+ {
608
+ method: 'POST',
609
+ path: '/api/export/jobs',
610
+ title: 'Create Export Job',
611
+ description: 'Creates a new PPTX export job from top-level HTML/CSS fields plus optional presentation size controls. The response is a queued job descriptor; use GET /api/export/jobs/{jobId} to retrieve terminal results.',
612
+ requestTitle: 'Request Body',
613
+ requestFields: [
614
+ { field: 'fileName', type: 'string', required: false, default: 'export.pptx', description: 'Output filename for the generated PPTX. Must end with .pptx extension.' },
615
+ { field: 'html', type: 'string', required: true, default: '--', description: 'HTML content containing one or more elements with .slide class. Each .slide becomes one PPTX slide. Required.' },
616
+ { field: 'css', type: 'string', required: false, default: '""', description: 'Optional CSS applied globally to the submitted HTML.' },
617
+ { field: 'autoEmbedFonts', type: 'boolean', required: false, default: 'false', description: 'Attempt to detect and embed fonts into the generated PPTX.' },
618
+ { field: 'width', type: 'number', required: false, default: '--', description: 'Optional PPTX slide width in inches. Use with height for custom presentation sizes.' },
619
+ { field: 'height', type: 'number', required: false, default: '--', description: 'Optional PPTX slide height in inches. Use with width for custom presentation sizes.' },
620
+ { field: 'layout', type: 'string', required: false, default: '--', description: 'Optional PPTX layout preset or custom layout name. Common presets: LAYOUT_16x9, LAYOUT_16x10, LAYOUT_4x3, LAYOUT_WIDE.' },
621
+ { field: 'metadata', type: 'object', required: false, default: '{}', description: 'Opaque metadata forwarded to the worker. Useful for request tracing on your side.' },
622
+ { field: 'responseFormat', type: 'string', required: false, default: '"url"', description: 'Controls how the completed PPTX file is delivered. "url" returns a presigned download URL (default). "base64" returns the file inline as base64. "both" returns both. Replaces the deprecated includeFileBase64 parameter.' },
623
+ { field: 'callbackUrl', type: 'string', required: false, default: '--', description: 'An HTTPS URL to receive a webhook POST when the job completes or fails. The worker sends the full job result to this URL with an x-signature-sha256 HMAC header for verification. Only https:// URLs are accepted.' },
624
+ ],
625
+ requestHeaders: [
626
+ { header: 'Idempotency-Key', description: 'Optional. A unique string to prevent duplicate job creation on retries. The server caches the response for 24 hours; sending the same key returns the original response without creating a new job.' },
627
+ ],
628
+ responseTitle: 'Response (200 OK)',
629
+ responseCode: JOB_RESPONSE_EXAMPLE,
630
+ errors: [
631
+ { code: '400', description: 'Invalid request body -- missing required fields or malformed JSON.' },
632
+ { code: '401', description: 'Missing or invalid API key. Ensure the Authorization or X-API-Key header is set with a valid sk_live_ key.' },
633
+ { code: '403', description: 'API key does not have permission for this operation. Check plan limits or key scope.' },
634
+ { code: '413', description: 'Request entity too large. The total request body exceeds your plan limit or the worker hard cap.' },
635
+ { code: '422', description: 'The sanitized HTML resolves to more slides than your plan allows.' },
636
+ { code: '429', description: 'Rate limit exceeded, daily limit exceeded, monthly fair-use review triggered, or concurrent job limit exceeded. Check Retry-After and usage headers.' },
637
+ { code: '502', description: 'Bad gateway -- the worker backend is temporarily unavailable. Retry after a short delay.' },
638
+ { code: '503', description: 'Service unavailable -- the system is under maintenance or experiencing high load. Retry with exponential backoff.' },
639
+ ],
640
+ },
641
+ {
642
+ method: 'GET',
643
+ path: '/api/export/jobs/{jobId}',
644
+ title: 'Check Job Status',
645
+ description: 'Retrieves the current status of an export job. Poll this endpoint until status is "completed" or "failed". When the job completes, the REST API returns the PPTX as fileBase64.',
646
+ requestTitle: 'Path Parameters',
647
+ requestFields: [
648
+ { field: 'jobId', type: 'string', required: true, default: '--', description: 'The job ID returned from the POST /api/export/jobs endpoint.' },
649
+ ],
650
+ responseTitle: 'Response (200 OK)',
651
+ responseCode: JOB_STATUS_EXAMPLE,
652
+ statusValues: [
653
+ { status: 'queued', description: 'Job is waiting in the processing queue.' },
654
+ { status: 'processing', description: 'Worker is actively converting HTML to PowerPoint.' },
655
+ { status: 'completed', description: 'Conversion finished successfully. fileBase64 and mimeType are available.' },
656
+ { status: 'failed', description: 'Conversion failed. The message field contains a human-readable description.' },
657
+ ],
658
+ errors: [
659
+ { code: '401', description: 'Missing or invalid API key.' },
660
+ { code: '404', description: 'Job not found -- either the jobId is invalid or the job belongs to a different API key.' },
661
+ { code: '429', description: 'Status polling rate limit exceeded.' },
662
+ ],
663
+ },
664
+ {
665
+ method: 'GET',
666
+ path: '/api/export/plans',
667
+ title: 'List Plans',
668
+ description: 'Returns the public plan catalog plus the recommended default plan. No authentication required.',
669
+ requestTitle: 'Parameters',
670
+ requestFields: [],
671
+ responseTitle: 'Response (200 OK)',
672
+ responseCode: PLANS_RESPONSE_EXAMPLE,
673
+ errors: [],
674
+ },
675
+ {
676
+ method: 'GET',
677
+ path: '/api/openapi.json',
678
+ title: 'OpenAPI Specification',
679
+ description: 'Returns the OpenAPI 3.x specification for the html2pptx.app API. Useful for generating client SDKs, importing into Postman, or browsing the API schema.',
680
+ requestTitle: 'Parameters',
681
+ requestFields: [],
682
+ responseTitle: 'Response (200 OK)',
683
+ responseCode: '// Returns the full OpenAPI 3.x JSON document',
684
+ errors: [],
685
+ },
686
+ ],
687
+
688
+ apiVersioningTitle: 'API Versioning',
689
+ apiVersioningDescription: 'Versioned endpoints are available under the /api/v1/ prefix. The original unversioned endpoints remain fully supported for backwards compatibility.',
690
+ apiVersioningEndpoints: [
691
+ { path: '/api/v1/export/jobs', description: 'Create export job (POST) or list jobs' },
692
+ { path: '/api/v1/export/jobs/{jobId}', description: 'Get job status by ID' },
693
+ { path: '/api/v1/export/plans', description: 'List available plans' },
694
+ { path: '/api/v1/export/usage', description: 'Get current usage and quota' },
695
+ { path: '/api/v1/export/keys', description: 'Manage API keys' },
696
+ ],
697
+
698
+ apiIdempotencyTitle: 'Idempotency',
699
+ apiIdempotencyDescription: 'Send an Idempotency-Key header with POST /api/export/jobs to prevent duplicate job creation on retries. The server caches the response for 24 hours. If the same key is sent again within that window, the original response is returned without creating a new job. Keys must be unique strings (UUIDs recommended).',
700
+
701
+ apiWebhookTitle: 'Webhook Callback',
702
+ apiWebhookDescription: 'Add a callbackUrl field (HTTPS only) to the POST /api/export/jobs request body. When the job completes or fails, the worker sends a POST request to your callback URL with the full job result as the JSON body. The request includes an x-signature-sha256 header containing an HMAC-SHA256 signature for payload verification. This eliminates the need for polling in many integration scenarios.',
703
+
704
+ apiErrorsTitle: 'Error Response Format',
705
+ apiErrorsDescription: 'All error responses follow the RFC 9457 Problem Details format with additional legacy fields for backwards compatibility:',
706
+ apiErrorsCode: ERROR_CODES_EXAMPLE,
707
+
708
+ apiContractTitle: 'HTML Contract',
709
+ apiContractDescription: 'The HTML you send must follow these rules for reliable conversion.',
710
+ apiContractRules: [
711
+ 'Each slide must have the class .slide -- this is the boundary marker for slide separation',
712
+ 'Each .slide must have explicit dimensions. 1600px x 900px (16:9 ratio at 13.333in x 7.5in) is the default example, and API/MCP callers can also set width, height, or layout for portrait/custom output',
713
+ 'Supported CSS: flexbox, grid, linear-gradient, radial-gradient, box-shadow, text-shadow, border-radius, transform (rotate, scale, translate, skew), opacity',
714
+ 'Fonts: system fonts (Arial, Helvetica, Noto Sans JP) work by default. Enable autoEmbedFonts for Google Fonts or custom @font-face declarations',
715
+ 'Images: both base64 data URIs and absolute URLs are supported. Relative paths will fail -- always use absolute URLs',
716
+ 'SVGs: inline SVG elements are supported and are converted to high-quality PNG images',
717
+ 'Avoid: script tags, iframes, canvas elements, anchor tags, form elements, SVG external references, CSS animations, @keyframes, and runtime-dependent state',
718
+ 'Nesting: deeply nested elements (> 10 levels) may impact output quality. Keep your HTML structure flat where possible',
719
+ 'Text wrapping: text boxes default to no-wrap to prevent unexpected line breaks in PPTX. If you need text to wrap within a container (e.g. long paragraphs), add white-space: normal to that element',
720
+ ],
721
+
722
+ apiHtmlElementsTitle: 'Supported HTML Elements',
723
+ apiHtmlElementsDescription: 'Each HTML element is converted to the most appropriate PowerPoint object for maximum editability.',
724
+ apiHtmlElements: [
725
+ { element: 'div, section, article', pptx: 'Shape with fill', notes: 'Background colors, gradients, borders, and rounded corners are preserved.' },
726
+ { element: 'p, h1-h6, span, b, em, strong, i, small', pptx: 'Text box', notes: 'Text is fully editable in PowerPoint. Font size, weight, style, color, alignment, and line-height are all converted. Inline elements (span, b, em, etc.) become styled text runs within the same text box.' },
727
+ { element: 'img', pptx: 'Image', notes: 'Supports absolute URLs and base64 data URIs. CSS object-fit (contain, cover, fill, scale-down) and object-position are respected. Rounded corners are applied via clipping.' },
728
+ { element: 'table, tr, td, th', pptx: 'Native PPTX table', notes: 'Full table support with cell-level text styling, background fill, borders (solid/dashed/dotted), padding, text alignment, and colspan/rowspan.' },
729
+ { element: 'ul, ol, li', pptx: 'Bulleted / Numbered list', notes: 'Simple lists become editable bullet or numbered lists. Complex lists (with images or flex/grid inside) are converted as images.' },
730
+ { element: 'svg', pptx: 'Image (PNG)', notes: 'SVGs are converted to high-quality PNG images.' },
731
+ { element: 'canvas', pptx: 'Image (PNG)', notes: 'Canvas content is embedded as a PNG image.' },
732
+ { element: 'Icon elements (FontAwesome, Material Icons, etc.)', pptx: 'Image', notes: 'Icon fonts are automatically detected and converted to images.' },
733
+ ],
734
+ apiHtmlForbiddenTitle: 'Forbidden Elements',
735
+ apiHtmlForbiddenDescription: 'The following elements are stripped during input sanitization for security and compatibility:',
736
+ apiHtmlForbidden: [
737
+ { element: 'script, iframe, object, embed', reason: 'Security: active content removed' },
738
+ { element: 'link, meta, base', reason: 'Security: external references removed' },
739
+ { element: 'form', reason: 'Interactive elements not supported in PPTX' },
740
+ { element: 'style', reason: 'Use inline styles or the css parameter instead' },
741
+ { element: 'a', reason: 'Anchor tags stripped for security' },
742
+ { element: 'foreignobject, image (SVG), feimage, use', reason: 'SVG external references removed' },
743
+ { element: 'animate, animateMotion, animateTransform, set, discard, mpath', reason: 'SVG animations not supported' },
744
+ ],
745
+
746
+ /* --- Section 4: Skills Integration --- */
747
+ skillsTitle: 'Skills Integration',
748
+ skillsSubtitle: 'What are Skills',
749
+ skillsDescription:
750
+ 'Skills are packaged capabilities that extend AI coding agents with domain-specific knowledge and workflows. The html2pptx.app skill teaches your agent how to author slide-safe HTML, validate it against the PPTX conversion contract, optionally open the local visual editor, export through the remote MCP workflow, and publish HTML template drafts through its built-in remote MCP publishing workflow. Install once, and your agent can convert natural language instructions into production-ready PowerPoint files or creator-owned HTML drafts.',
751
+ skillsHowItWorks: 'The skill bundles four core capabilities: (1) HTML authoring knowledge -- the rules for writing HTML/CSS that converts cleanly to editable PowerPoint, (2) MCP-based export automation -- connecting to the remote html2pptx.app MCP server to create jobs, poll status, and retrieve results, (3) local visual editing -- opening edit-slide through a localhost bridge when the user wants to inspect or tweak the HTML before export, and (4) template publishing -- requiring HTML drafts to go through the remote MCP validate/publish loop. The agent should ask before adding a local MCP server because that changes the user’s MCP configuration.',
752
+ skillsCompatibility: 'Works with 18+ AI agents including Claude Code, Cursor, GitHub Copilot, Windsurf, Cline, Codex, and more. Use the skills CLI command for the specific agent you use, or the interactive selector for other supported agents.',
753
+ skillsWorkflowTitle: 'Workflow',
754
+ skillsWorkflow: [
755
+ 'Agent receives a user request (e.g., "Create a deck from these meeting notes")',
756
+ 'Agent reads the skill definition to understand the html2pptx.app HTML contract',
757
+ 'Agent generates slide-safe HTML with .slide class elements and explicit dimensions. 1600x900 is the default example',
758
+ 'Agent validates the markup against the conversion contract',
759
+ 'If visual review is needed, the agent opens the local edit-slide editor through local stdio MCP, then re-reads the edited HTML from disk',
760
+ 'Agent connects to remote MCP and calls html2pptx_create_export_job',
761
+ 'Agent polls with html2pptx_wait_for_export_job until completed',
762
+ 'If the user wants to create an HTML template draft, the agent uses the html2pptx skill and remote MCP: infer title/tags from the HTML, run AI security preflight, validate, fix errors, save a draft, then return draftUrl for dashboard review',
763
+ 'Agent returns the completed job summary to the user',
764
+ ],
765
+ skillsLocalEditorTitle: 'Local Visual Editor',
766
+ skillsLocalEditorLead:
767
+ 'The edit-slide skill lets an agent open a local HTML slide deck in a PowerPoint-style visual editor served from an available loopback origin such as http://localhost:<port>. Hosted edit-slide is not allowed for local file editing. The local dev script chooses a free port and registers it in .html2pptx/edit-slide/editor-server.json inside the current project. The deck file stays on the user machine and is read/written through a localhost bridge started by the local stdio MCP tool. If the local MCP server is not already configured, the agent should explain that it will change MCP settings and ask the user before adding it.',
768
+ skillsLocalEditorCode: `# Use the local MCP tool only
769
+ html2pptx_open_local_slide_editor({ "filePath": "html2pptx/slides.html" })
770
+
771
+ # Claude Code local MCP setup
772
+ npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude`,
773
+ skillsLocalEditorFlowTitle: 'How the local editor flow works',
774
+ skillsLocalEditorFlow: [
775
+ { label: '1. Choose remote or local MCP', detail: 'Use remote MCP for normal PPTX export and catalog/docs tools. Use local stdio MCP or `html2pptx edit <file>` when the agent must open or edit a local `.html` / `.htm` file through edit-slide. If local MCP is missing, use direct CLI when the local editor app is running or ask before installing it.' },
776
+ { label: '2. Start bridge', detail: '`html2pptx_open_local_slide_editor` starts a tiny HTTP server on `127.0.0.1`. Unless a port is specified, the OS assigns a free port. Access is scoped to the current working directory.' },
777
+ { label: '3. Open editor', detail: 'The command opens `http://localhost:<editor-port>/edit-slide?file=...&bridge=http://127.0.0.1:<bridge-port>#bridgeToken=...`. The one-time token is kept in the URL fragment and the editor removes it from the address bar after startup.' },
778
+ { label: '4. Load local file', detail: 'The browser editor presents the token and fetches the selected `.html` or `.htm` file from the localhost bridge. No marketplace draft or public page is created.' },
779
+ { label: '5. Edit visually', detail: 'Users can click slide elements and adjust text, typography, color, size, padding, margin, radius, border, opacity, and other properties from the right panel.' },
780
+ { label: '6. Save to disk', detail: 'Edits are serialized back into the same HTML file through the bridge with an optimistic file hash. No version history, backups, or audit log are created.' },
781
+ { label: '7. Continue with the agent', detail: 'After manual edits, the agent should re-read the HTML file from disk. If the user wants PowerPoint output, handle it as a separate agent task with the html2pptx skills.' },
782
+ ],
783
+ skillsLocalEditorPrivacyTitle: 'Privacy and file access model',
784
+ skillsLocalEditorPrivacy: [
785
+ 'The bridge binds to `127.0.0.1` only. Other users cannot open the local bridge from the network.',
786
+ 'Each bridge run generates a per-session token that the editor must present for local reads and writes. The visible URL is redacted after startup.',
787
+ 'The slide preview uses no-referrer handling so external images or fonts do not receive the tokenized editor URL.',
788
+ 'Only `.html` and `.htm` files under the current working directory are accepted.',
789
+ 'Sensitive project directories such as `app/`, `components/`, `lib/`, `.git/`, `.next/`, and `node_modules/` are blocked.',
790
+ 'Visual editing does not publish or upload the deck. The Export PPTX button only displays a prompt telling the user to ask Claude Code or another agent to use the html2pptx skills for PowerPoint output.',
791
+ 'Adding the local stdio MCP server is a configuration change in the user’s agent environment. Skills and agents should not add it silently; ask first, then proceed only after confirmation.',
792
+ 'Editor state is project-local under `.html2pptx/edit-slide/`. No version history, backups, or audit log are created.',
793
+ ],
794
+ skillsLocalEditorTroubleshootingTitle: 'Common issues',
795
+ skillsLocalEditorTroubleshooting: [
796
+ { issue: 'The local editor tool is not available', fix: 'Ask before adding local MCP with `npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude`.' },
797
+ { issue: '`html2pptx edit` cannot find the local editor', fix: 'Start `node scripts/dev-studio.mjs` first, or pass the active loopback URL with `--base-url http://localhost:<port>`. Hosted edit-slide is never used.' },
798
+ { issue: 'The editor opens but the deck does not load', fix: 'Confirm the path is relative to the directory where the command was run and the file extension is `.html` or `.htm`.' },
799
+ { issue: 'Changes do not save', fix: 'Keep the local MCP session running. Stopping it stops the localhost bridge.' },
800
+ { issue: 'The agent wants to add local MCP', fix: 'Confirm with the user first. Local MCP is optional and only needed for MCP-driven local edit-slide sessions; remote MCP can still export PPTX without local file access.' },
801
+ { issue: 'Another tab is read-only', fix: 'The editor uses a local tab lock to avoid two tabs writing to the same file. Use the active tab or click the transfer edit control.' },
802
+ ],
803
+ skillsSetupTitle: 'Setup',
804
+ skillsSetupSteps: [
805
+ {
806
+ step: '1',
807
+ title: 'Install MCP + Skill',
808
+ icons: ['claude-code', 'codex', 'cursor', 'windsurf'],
809
+ body: 'Choose the command for the agent you actually use: Claude Code, Codex, Cursor, or Windsurf. For other supported agents or multiple targets, use the interactive selector. Avoid --yes unless you intentionally want to install into every detected agent directory.',
810
+ code: SKILL_INSTALL_COMMAND_EN,
811
+ },
812
+ {
813
+ step: '2',
814
+ title: 'Configure API key',
815
+ body: 'Create an API key in the html2pptx.app dashboard and set it as an environment variable.',
816
+ code: `# Set API key as environment variable
817
+ export HTML2PPTX_API_KEY="sk_live_xxxx"
818
+
819
+ # Or add to your .env file
820
+ echo 'HTML2PPTX_API_KEY=sk_live_xxxx' >> .env`,
821
+ },
822
+ {
823
+ step: '3',
824
+ title: 'Try it out',
825
+ body: 'Launch your editor and give it a natural language instruction to create slides. The skill handles everything automatically.',
826
+ code: SKILL_INVOCATION_EXAMPLE,
827
+ },
828
+ ],
829
+ skillsAvailableTitle: 'Available Skills',
830
+ skillsAvailable: SKILL_AVAILABLE_LIST,
831
+ skillsCapabilitiesTitle: 'Skill Capabilities',
832
+ skillsCapabilities: [
833
+ { title: 'Diagnose HTML', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>', body: 'Classify markup as safe, needs-rewrite, or out-of-scope before attempting export. Catches issues like missing .slide elements, unsupported CSS, or dynamic content.' },
834
+ { title: 'Rewrite Markup', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>', body: 'Transform web-shaped HTML (responsive layouts, percentage-based sizing, scroll containers) into fixed-size .slide structures suitable for PPTX conversion.' },
835
+ { title: 'Generate Slides', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>', body: 'Create new slide-safe HTML from scratch given a text prompt, topic outline, or data payload. Applies best practices for visual hierarchy and readability.' },
836
+ { title: 'Validate Output', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><polyline points="9 12 11 14 15 10"/></svg>', body: 'Run the generated HTML through a pre-flight check against the html2pptx.app HTML contract before making the API call, preventing wasted export quota on invalid input.' },
837
+ { title: 'Publish Templates', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="m7 8 5-5 5 5"/><path d="M5 21h14"/></svg>', body: 'For marketplace HTML drafts, the html2pptx skill includes AI security preflight, remote MCP validation, and draft creation. Web, CLI, local MCP, and generic REST flows do not create template drafts.' },
838
+ ],
839
+
840
+ /* --- Section 5: MCP Integration --- */
841
+ mcpTitle: 'MCP Integration',
842
+ mcpSubtitle: 'What is MCP',
843
+ mcpDescription:
844
+ 'MCP (Model Context Protocol) is an open protocol that exposes backend capabilities to AI agents through a standardized tool interface. html2pptx.app supports two MCP surfaces: the remote HTTP MCP endpoint at /mcp for export, usage, docs, templates, catalog, and HTML template publishing workflows, and the local stdio MCP server for local edit-slide sessions through a localhost bridge. Use remote MCP when the agent needs to convert HTML to PPTX or create an HTML template draft. Use local stdio MCP or `html2pptx edit <file>` when the agent must open, preview, or edit a local HTML file on the user machine; local MCP does not publish templates.',
845
+ mcpSetupTitle: 'Installation & Setup',
846
+ mcpSetupLead: 'Claude Code users can run the one-command installer to add both remote MCP and local edit-slide MCP. Use the remote-only command when local visual editing is not needed.',
847
+ mcpEditorTabs: [
848
+ {
849
+ id: 'claude-code',
850
+ label: 'Claude Code',
851
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/claude/default.svg',
852
+ recommended: true,
853
+ steps: [
854
+ { title: 'Set up the remote server (recommended)', body: 'Run the following command in your terminal.', code: `claude mcp add --transport http html2pptx https://html2pptx.app/mcp` },
855
+ { title: 'Manual setup for Claude Code', body: 'If the command above does not work, run the following to add the MCP server manually.', code: `claude mcp add html2pptx --transport http https://html2pptx.app/mcp` },
856
+ { title: 'One-command remote + local setup', body: 'Installs the remote MCP for exports/docs/templates and the local MCP for edit-slide. It runs from the published package, so no repository checkout is required. The local MCP is registered through a stable launcher for reliable Claude Code startup.', code: `npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude` },
857
+ ],
858
+ tip: 'To make the MCP server available across all projects, install it with the --scope user flag:\nclaude mcp add --scope user --transport http html2pptx https://html2pptx.app/mcp',
859
+ },
860
+ {
861
+ id: 'codex',
862
+ label: 'Codex',
863
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/openai/light.svg',
864
+ steps: [
865
+ { title: 'Run the CLI command (recommended)', body: 'Run the following command in your terminal. OAuth authentication will start automatically.', code: `codex mcp add html2pptx --url https://html2pptx.app/mcp` },
866
+ { title: 'Optional local stdio MCP for edit-slide', body: 'Use this when Codex needs to launch local edit-slide for a `.html` file. It runs from the published package, so no repository checkout is required. The editor app and localhost bridge use free ports. Codex should ask before adding it because it modifies the local MCP configuration.', code: `codex mcp add html2pptx-local -- npx -y html2pptx-local-mcp@latest html2pptx-mcp` },
867
+ { title: 'Manual setup via codex.json', body: 'Alternatively, create or edit codex.json in your project root.', code: `{\n "mcpServers": {\n "html2pptx": {\n "type": "url",\n "url": "https://html2pptx.app/mcp"\n }\n }\n}` },
868
+ ],
869
+ },
870
+ {
871
+ id: 'cursor',
872
+ label: 'Cursor',
873
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/cursor/light.svg',
874
+ steps: [
875
+ { title: 'Add to .cursor/mcp.json', body: 'Create .cursor/mcp.json in your project root and add the following.', code: `{\n "mcpServers": {\n "html2pptx": {\n "url": "https://html2pptx.app/mcp"\n }\n }\n}` },
876
+ ],
877
+ },
878
+ {
879
+ id: 'vscode',
880
+ label: 'VS Code',
881
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/visual-studio-code/default.svg',
882
+ steps: [
883
+ { title: 'Run the CLI command (recommended)', body: 'Run the following command in your terminal.', code: `code --add-mcp '{"name":"html2pptx","type":"http","url":"https://html2pptx.app/mcp"}'` },
884
+ { title: 'Manual setup via .vscode/mcp.json', body: 'Alternatively, create .vscode/mcp.json in your project root.', code: `{\n "servers": {\n "html2pptx": {\n "type": "http",\n "url": "https://html2pptx.app/mcp"\n }\n }\n}` },
885
+ ],
886
+ },
887
+ {
888
+ id: 'windsurf',
889
+ label: 'Windsurf',
890
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/windsurf/default.svg',
891
+ steps: [
892
+ { title: 'Add to mcp_config.json', body: 'Edit ~/.codeium/windsurf/mcp_config.json and add the following. Restart Windsurf after saving.', code: `{\n "mcpServers": {\n "html2pptx": {\n "serverUrl": "https://html2pptx.app/mcp"\n }\n }\n}` },
893
+ ],
894
+ },
895
+ {
896
+ id: 'cline',
897
+ label: 'Cline',
898
+ steps: [
899
+ { title: 'Add via Cline sidebar', body: 'Open the Cline sidebar > Configure tab > "Configure MCP Servers" and add the following.', code: `{\n "mcpServers": {\n "html2pptx": {\n "url": "https://html2pptx.app/mcp",\n "type": "streamableHttp"\n }\n }\n}` },
900
+ ],
901
+ },
902
+ ],
903
+ mcpToolsTitle: 'Available MCP Tools',
904
+ mcpTools: [
905
+ { tool: 'html2pptx_list_export_plans', description: 'List the current commercial plan catalog and recommended plan.' },
906
+ { tool: 'html2pptx_create_export_job', description: 'Create an export job from HTML/CSS content. Supports optional width, height, layout, waitForCompletion, timeoutMs, and responseFormat ("url" | "base64" | "both").' },
907
+ { tool: 'html2pptx_get_export_job', description: 'Get the current status of an export job by jobId.' },
908
+ { tool: 'html2pptx_wait_for_export_job', description: 'Poll until the job completes or fails. Handles retries and backoff inside the tool.' },
909
+ { tool: 'html2pptx_get_docs', description: 'Fetch html2pptx.app documentation to understand the API contract, HTML requirements, and integration guides.' },
910
+ { tool: 'html2pptx_get_usage', description: 'Fetch the current usage and quota status for your plan. Shows weekly export count, remaining quota, plan limits, and reset timing.' },
911
+ { tool: 'html2pptx_list_templates', description: 'List available marketplace templates with metadata and optional category filtering.' },
912
+ { tool: 'html2pptx_get_template_html', description: 'Fetch a template source HTML and design prompt so agents can study or remix it.' },
913
+ { tool: 'html2pptx_validate_template_html', description: 'Dry-run marketplace HTML validation after AI security preflight. Required before creating an HTML template draft.' },
914
+ { tool: 'html2pptx_publish_template', description: 'Upload validated HTML, infer missing title/description/category/tags, and create a creator-owned HTML draft by default. The tool returns draftUrl; the user reviews and presses the final publish button in the dashboard.' },
915
+ { tool: 'html2pptx_open_local_slide_editor', description: 'Local stdio MCP only. Starts the existing CLI localhost bridge for a local .html/.htm slide file and opens the no-code editor without publishing the HTML. Not available from remote /mcp because remote servers cannot access user files.' },
916
+ { tool: 'html2pptx_stop_local_slide_editor', description: 'Local stdio MCP only. Stops a local editor bridge session started by html2pptx_open_local_slide_editor.' },
917
+ ],
918
+ mcpResourcesTitle: 'MCP Resources (Documentation)',
919
+ mcpResourcesDescription: 'The MCP server provides documentation as Resources. Agents can read these before creating export jobs to understand the API contract and HTML requirements.',
920
+ mcpResources: [
921
+ { uri: 'docs://html2pptx/overview', name: 'Service Overview', description: 'Architecture, CSS support, comparison with alternatives' },
922
+ { uri: 'docs://html2pptx/quickstart', name: 'Quickstart', description: 'First API call in 4 steps' },
923
+ { uri: 'docs://html2pptx/api-reference', name: 'API Reference', description: 'Endpoints, authentication, error codes' },
924
+ { uri: 'docs://html2pptx/html-contract', name: 'HTML Contract', description: 'HTML structure requirements and supported CSS' },
925
+ { uri: 'docs://html2pptx/skills', name: 'Skills Integration', description: 'Skill definitions for AI agents' },
926
+ { uri: 'docs://html2pptx/mcp', name: 'MCP Integration', description: 'MCP server setup and usage' },
927
+ ],
928
+ mcpLlmsTxtTitle: 'llms.txt (AI-Optimized Docs)',
929
+ mcpLlmsTxtDescription: 'html2pptx.app supports the llms.txt standard. Structured Markdown documentation optimized for AI agents and LLMs to efficiently understand the service.',
930
+ mcpLlmsTxtEndpoints: [
931
+ { url: 'https://html2pptx.app/llms.txt', description: 'Concise index (~100 lines) — service overview, API spec, supported CSS' },
932
+ { url: 'https://html2pptx.app/llms-full.txt', description: 'Complete documentation (~900 lines) — full Markdown of all sections' },
933
+ ],
934
+ mcpProgressTitle: 'Progress & Logging',
935
+ mcpProgressDescription: 'The MCP server provides real-time feedback during job processing:',
936
+ mcpProgressItems: [
937
+ { feature: 'notifications/progress', description: 'Sent during job polling to indicate progress percentage and current status. MCP clients can display a progress bar or status indicator.' },
938
+ { feature: 'notifications/message', description: 'Sent for job lifecycle events such as job created, processing started, completed, or failed. Provides human-readable log messages for debugging.' },
939
+ ],
940
+
941
+ mcpResourceLinkTitle: 'ResourceLink',
942
+ mcpResourceLinkDescription: 'When a job completes with a downloadUrl, the MCP response includes a resource content block with a ResourceLink. This enables MCP clients to natively handle the generated file -- for example, offering a direct download button or embedding the file reference in the conversation context.',
943
+
944
+ mcpAuthTitle: 'Authentication',
945
+ mcpAuthDescription: 'The MCP server supports two authentication methods. Choose the one that best fits your use case. API keys are fine for export, docs, usage, and catalog tools, but html2pptx_publish_template requires a WorkOS-bound user token because template drafts need a creator identity.',
946
+ mcpAuthMethods: [
947
+ {
948
+ method: 'API Key (Recommended)',
949
+ description: 'Use an API key from the dashboard. API keys do not expire (unless you set an expiration date), so you never need to re-authenticate. This is the recommended method for regular export/docs/catalog MCP usage. It cannot create creator-owned template drafts.',
950
+ setup: 'Generate an API key from the dashboard, then pass it as a Bearer token. Most MCP clients handle this automatically when you add the server.',
951
+ pros: ['No token expiration — stable, long-lived sessions', 'Simple setup — just paste the key', 'Best for daily use and automation'],
952
+ },
953
+ {
954
+ method: 'OAuth (Browser Login)',
955
+ description: 'Sign in with your Google or email account via WorkOS AuthKit. The access token is valid for 24 hours, after which you will need to re-authenticate. This identity-bound method is required for html2pptx_publish_template.',
956
+ setup: 'When you add the MCP server, your browser will open the login page automatically. Sign in to authorize.',
957
+ pros: ['No API key management needed', 'Good for quick trials and evaluation'],
958
+ note: 'OAuth sessions expire after 24 hours of inactivity. For uninterrupted access, we recommend using an API key instead.',
959
+ },
960
+ ],
961
+
962
+ mcpErrorRecoveryTitle: 'Error Recovery Guidance',
963
+ mcpErrorRecoveryDescription: 'MCP error messages include actionable guidance designed for LLM agents to self-recover. For example: "Wait 30s and retry" for rate limits, "Call html2pptx_get_docs for the HTML contract" for validation errors, or "Reduce slide count to N" for plan limit errors. This enables agents to automatically diagnose and resolve issues without user intervention.',
964
+
965
+ mcpExampleTitle: 'Example Usage',
966
+ mcpExampleCode: MCP_USAGE_EXAMPLE,
967
+
968
+ /* --- Section 6: Studio & Web Export --- */
969
+ studioTitle: 'Studio & Hosted Web Export',
970
+ studioLead: 'html2pptx.app also includes a browser-facing Studio and a hosted same-origin web export route. Use these surfaces for manual authoring, visual checks, and lightweight in-browser export flows.',
971
+ studioCards: [
972
+ {
973
+ title: 'Studio',
974
+ body: 'The Studio is the manual authoring environment. It is useful when you want to paste HTML/CSS, inspect the visual result, iterate on layout, and export without building your own API client first.',
975
+ },
976
+ {
977
+ title: 'Hosted Web Export',
978
+ body: 'The hosted web export route is a browser-oriented wrapper around the same backend worker. It is designed for same-origin web app usage, not for backend-to-backend automation or third-party embedding.',
979
+ },
980
+ {
981
+ title: 'When to use each',
982
+ body: 'Use REST API for product integrations and backend automation, Skills/MCP for agent workflows, Studio for manual authoring, and hosted web export for first-party browser UI flows.',
983
+ },
984
+ ],
985
+ studioWorkflowTitle: 'How these public surfaces fit together',
986
+ studioWorkflow: [
987
+ 'Studio is public and can be used to write or preview slide-oriented HTML manually.',
988
+ 'Hosted web export calls /api/web-export/jobs from the browser and is guarded as a same-origin web surface.',
989
+ 'REST API remains the canonical automation contract for backend systems and production pipelines.',
990
+ 'If you need reproducible server-side exports, prefer the authenticated REST API over hosted web export.',
991
+ 'The same core worker and sanitization pipeline sit behind Studio previews, hosted web export, API, Skills, and MCP.',
992
+ 'Template publishing is deliberately narrower: web UI, CLI, local MCP, and REST API cannot create marketplace drafts. Draft creation is HTML-only and must go through remote MCP validation and draft saving. The agent can infer title/tags from the HTML, but the user presses the final dashboard publish button.',
993
+ ],
994
+ studioExampleTitle: 'Hosted web export example',
995
+ studioExampleCode: WEB_EXPORT_EXAMPLE,
996
+
997
+ /* --- Section 6b: CLI Tool --- */
998
+ cliTitle: 'CLI Tool',
999
+ cliSubtitle: 'What is the CLI',
1000
+ cliDescription:
1001
+ 'The html2pptx CLI lets you convert HTML files to PowerPoint directly from your terminal, open local HTML in edit-slide, and browse templates. It supports both interactive mode (guided prompts for first-time users) and direct mode (flags for scripting, CI/CD, and AI agents like Claude Code). Template draft creation is HTML-only via remote MCP and is intentionally rejected by the CLI.',
1002
+ cliInstallTitle: 'Installation',
1003
+ cliInstallSteps: [
1004
+ { label: 'Install globally', command: 'npm install -g html2pptx-cli' },
1005
+ { label: 'Or run directly with npx', command: 'npx html2pptx-cli convert slides.html' },
1006
+ ],
1007
+ cliSetupTitle: 'Initial Setup',
1008
+ cliSetupDescription: 'Before converting files, configure your API key. This is a one-time setup that saves your credentials to ~/.html2pptx/config.json (owner-only permissions).',
1009
+ cliSetupCode: 'html2pptx init',
1010
+ cliCommandsTitle: 'Commands',
1011
+ cliCommands: [
1012
+ { command: 'html2pptx login', description: 'Configure your API key interactively. Shows a link to the dashboard where you can generate a key.' },
1013
+ { command: 'html2pptx logout', description: 'Remove your stored API key from ~/.html2pptx/config.json.' },
1014
+ { command: 'html2pptx convert [file]', description: 'Convert an HTML file to PPTX. Run without arguments for interactive mode, or pass a file path for direct mode.' },
1015
+ { command: 'html2pptx status', description: 'Check your current usage, remaining quota, rate limits, and plan details.' },
1016
+ { command: 'html2pptx whoami', description: 'Verify your API key and show authentication status, plan name, and usage.' },
1017
+ { command: 'html2pptx config', description: 'Display current configuration (API key, base URL).' },
1018
+ { command: 'html2pptx templates list', description: 'Browse all available templates with title, category, and slide count.' },
1019
+ { command: 'html2pptx templates get <id>', description: 'Get template details including download URLs. Use --prompt for the design prompt, --html for source code.' },
1020
+ { command: 'html2pptx templates publish', description: 'Disabled. Template publishing is HTML-only via remote MCP.' },
1021
+ { command: 'html2pptx --help', description: 'Show help and available commands.' },
1022
+ { command: 'html2pptx --version', description: 'Show the installed CLI version.' },
1023
+ ],
1024
+ cliOptionsTitle: 'Convert Options',
1025
+ cliOptions: [
1026
+ { flag: '-o, --output <file>', description: 'Output PPTX filename (default: input filename with .pptx extension)' },
1027
+ { flag: '-s, --size <size>', description: 'Slide size: "16:9", "4:3", or custom "WxH" (e.g. 1920x1080)' },
1028
+ { flag: '--css <file>', description: 'External CSS file to include alongside the HTML' },
1029
+ { flag: '--json', description: 'Output result as JSON for scripting and CI/CD pipelines' },
1030
+ { flag: '--open', description: 'Automatically open the PPTX file after conversion' },
1031
+ { flag: '--base-url <url>', description: 'API base URL (default: https://html2pptx.app)' },
1032
+ ],
1033
+ cliExamplesTitle: 'Examples',
1034
+ cliExamples: [
1035
+ { title: 'Direct mode (for scripts & AI agents)', code: '# One-liner conversion\nhtml2pptx convert ./slides.html -o presentation.pptx -s 16:9\n\n# With external CSS\nhtml2pptx convert ./slides.html --css ./styles.css -o deck.pptx\n\n# JSON output for scripting\nhtml2pptx convert ./slides.html --json\n# {"success":true,"file":"slides.pptx","size":"1.2 MB","duration":"3.2s"}' },
1036
+ { title: 'Interactive mode (for first-time users)', code: '# Just run convert without arguments\nhtml2pptx convert\n\n# The CLI will guide you through:\n# > HTML file to convert\n# > Slide size selection\n# > Output filename' },
1037
+ { title: 'Account management', code: '# Check authentication\nhtml2pptx whoami\n# Plan: Starter\n# Usage: 1 / 120 exports today\n# Remaining: 119\n\n# Check detailed usage\nhtml2pptx status\n# Plan: Starter\n# Daily Usage: 42 / 120 exports ████████████░░░░░░░░\n# Remaining: 78\n# Rate Limit: 5 req/min\n# Max Slides: 50 per job\n\n# Remove credentials\nhtml2pptx logout' },
1038
+ { title: 'Templates', code: '# List all templates\nhtml2pptx templates list\n\n# Get template with design prompt\nhtml2pptx templates get atlantis-pizza-corp --prompt\n\n# Get template with HTML source (JSON output)\nhtml2pptx templates get atlantis-pizza-corp --prompt --html --json\n\n# Draft creation is remote-MCP-only:\n# AI security preflight -> html2pptx_validate_template_html -> html2pptx_publish_template -> dashboard review' },
1039
+ ],
1040
+
1041
+ /* --- Section 7: Use Cases --- */
1042
+ useCasesTitle: 'Use Cases & Examples',
1043
+ useCasesIntro: 'html2pptx.app is designed for automated, repeatable slide generation. Here are the most common integration patterns:',
1044
+ useCases: [
1045
+ {
1046
+ title: 'Automated Quarterly Reports',
1047
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>',
1048
+ body: 'Generate quarterly performance decks from live data. Pull metrics from your database, format them as slide HTML with charts and KPI cards, and export via the API. Schedule with cron or trigger from your BI pipeline for fully hands-off reporting.',
1049
+ code: REPORT_EXAMPLE,
1050
+ },
1051
+ {
1052
+ title: 'Sales Proposal Templates',
1053
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>',
1054
+ body: 'Define brand-compliant slide templates in HTML/CSS once, then populate them with dynamic content for each campaign or client pitch. Variables like company name, project details, and pricing are injected at generation time. Marketing teams maintain the templates; sales reps get pixel-perfect branded decks instantly.',
1055
+ code: PROPOSAL_TEMPLATE_EXAMPLE,
1056
+ },
1057
+ {
1058
+ title: 'Agent-Powered Presentations',
1059
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="3"/><line x1="8" y1="16" x2="8" y2="16.01"/><line x1="16" y1="16" x2="16" y2="16.01"/></svg>',
1060
+ body: 'Let AI agents create presentation decks from meeting notes, research summaries, or project briefs. Using Skills or MCP integration, the agent understands the html2pptx.app HTML contract, generates compliant slides, and delivers a download link. Users simply describe what they want in natural language.',
1061
+ code: null,
1062
+ },
1063
+ {
1064
+ title: 'SaaS Export Embedding',
1065
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>',
1066
+ body: 'Add "Export to PowerPoint" functionality to your SaaS product. Render your app\'s dashboards, analytics views, or reports as slide HTML and call the html2pptx.app API from your backend. Users get native PPTX files with editable text and shapes -- not flat screenshots.',
1067
+ code: SAAS_EMBED_EXAMPLE,
1068
+ },
1069
+ ],
1070
+
1071
+ /* --- Section 8: Plans & Pricing --- */
1072
+ plansTitle: 'Plans & Pricing',
1073
+ plansDescription: 'Choose the plan that fits your usage. The current public catalog is defined in code and enforced in the API gateway: requests per minute, daily guardrails, maximum slides per job, concurrent jobs, API key count, and payload size all vary by plan.',
1074
+ plansTable: [
1075
+ { plan: 'Free Preview', exports: '100 per day / 3 rpm', slides: '50 per job', support: 'Community', price: '¥0' },
1076
+ { plan: 'Founder Beta', exports: '300 per day / 5 rpm', slides: '100 per job', support: 'Self-serve', price: '¥980/mo' },
1077
+ { plan: 'Starter', exports: '1,000 per day / 15 rpm', slides: '200 per job', support: 'Email', price: '¥2,980/mo' },
1078
+ { plan: 'Business', exports: '5,000 per day / 60 rpm', slides: '300 per job', support: 'Priority', price: '¥9,800/mo' },
1079
+ { plan: 'Enterprise / OEM', exports: 'Custom', slides: '500+ per job', support: 'Dedicated', price: '¥49,800/mo〜' },
1080
+ ],
1081
+ plansUpgradeNote: 'Upgrade anytime from the Dashboard. Changes take effect immediately with prorated billing. Downgrade at the end of the current billing period.',
1082
+
1083
+ plansRateLimitsTitle: 'Rate Limits & Quotas by Plan',
1084
+ plansRateLimitsDescription: 'Each plan enforces the following limits. All channels (REST API, Skills, MCP) share the same quotas.',
1085
+ plansRateLimits: [
1086
+ {
1087
+ plan: 'Free Preview',
1088
+ rpm: '3 req/min',
1089
+ daily: '100/day',
1090
+ monthly: 'Unlimited*',
1091
+ slidesPerJob: '50 slides',
1092
+ concurrent: '1 job',
1093
+ apiKeys: '1 key',
1094
+ payload: '1 MB',
1095
+ fairUse: 'Review at 1,000/mo, prompt at 2,000/mo',
1096
+ },
1097
+ {
1098
+ plan: 'Founder Beta',
1099
+ rpm: '5 req/min',
1100
+ daily: '300/day',
1101
+ monthly: 'Unlimited*',
1102
+ slidesPerJob: '100 slides',
1103
+ concurrent: '2 jobs',
1104
+ apiKeys: '3 keys',
1105
+ payload: '2 MB',
1106
+ fairUse: 'Review at 3,000/mo, prompt at 5,000/mo',
1107
+ },
1108
+ {
1109
+ plan: 'Starter',
1110
+ rpm: '15 req/min',
1111
+ daily: '1,000/day',
1112
+ monthly: 'Unlimited*',
1113
+ slidesPerJob: '200 slides',
1114
+ concurrent: '5 jobs',
1115
+ apiKeys: '10 keys',
1116
+ payload: '5 MB',
1117
+ fairUse: 'Review at 10,000/mo, prompt at 20,000/mo',
1118
+ },
1119
+ {
1120
+ plan: 'Business',
1121
+ rpm: '60 req/min',
1122
+ daily: '5,000/day',
1123
+ monthly: 'Unlimited*',
1124
+ slidesPerJob: '300 slides',
1125
+ concurrent: '20 jobs',
1126
+ apiKeys: '50 keys',
1127
+ payload: '10 MB',
1128
+ fairUse: 'Review at 50,000/mo, prompt at 100,000/mo',
1129
+ },
1130
+ {
1131
+ plan: 'Enterprise / OEM',
1132
+ rpm: '120 req/min',
1133
+ daily: 'Custom',
1134
+ monthly: 'Custom',
1135
+ slidesPerJob: '500 slides',
1136
+ concurrent: '50 jobs',
1137
+ apiKeys: '100 keys',
1138
+ payload: '25 MB',
1139
+ fairUse: 'Custom terms',
1140
+ },
1141
+ ],
1142
+ plansRateLimitsNote: '* Unlimited = within fair-use policy. MCP protocol requests are rate-limited at 3x the plan RPM to account for protocol overhead (initialize, tools/list, etc.).',
1143
+
1144
+ /* --- Section 9: Security --- */
1145
+ securityTitle: 'Security & Limits',
1146
+ securityLead: 'Public API, Skills, MCP, Studio, and hosted web export are all routed through the same security-sensitive conversion pipeline. The practical controls below are the ones that matter when you integrate or expose the product.',
1147
+ securityLayers: [
1148
+ {
1149
+ title: 'Authentication and authorization',
1150
+ body: 'REST API uses API keys. Remote MCP supports commercial API keys or WorkOS-backed authenticated sessions. Job lookup is bound to the same API key or authenticated principal that created the job.',
1151
+ },
1152
+ {
1153
+ title: 'SVG and untrusted markup',
1154
+ body: 'Public API and MCP sanitize incoming HTML. Inline SVG is converted to PNG images for reliable output.',
1155
+ },
1156
+ {
1157
+ title: 'Worker isolation',
1158
+ body: 'Export jobs run in isolated contexts with enforced request body limits and automatic cleanup of expired jobs.',
1159
+ },
1160
+ {
1161
+ title: 'Usage controls',
1162
+ body: 'Per-minute rate limiting, daily guardrails, monthly fair-use review thresholds, maximum slides per job, maximum payload size, and concurrent job limits are all enforced server-side based on the active plan.',
1163
+ },
1164
+ ],
1165
+ securityChecklistTitle: 'Recommended production practices',
1166
+ securityChecklist: [
1167
+ 'Treat API keys as secrets and rotate them from the dashboard when they are exposed.',
1168
+ 'Use the REST API for backend automation and same-origin hosted web export only for first-party browser flows.',
1169
+ 'Poll the public job status route with backoff instead of hammering the status endpoint.',
1170
+ 'Keep slide markup deterministic: explicit slide dimensions, predictable CSS, and no runtime-dependent content. 1600x900 remains the default example.',
1171
+ 'With responseFormat: "base64", fileBase64 can be large; decode it in streaming or binary-safe code paths on your side.',
1172
+ 'For agent integrations, decide whether the client should use local stdio MCP or remote /mcp before rollout.',
1173
+ ],
1174
+
1175
+ /* --- Section 10: FAQ --- */
1176
+ faqTitle: 'FAQ',
1177
+ faqItems: [
1178
+ {
1179
+ question: 'How is html2pptx.app different from other HTML-to-PPTX solutions?',
1180
+ answer: 'Most alternatives take a screenshot of your HTML and embed it as a flat image in each slide. html2pptx.app produces fully editable PowerPoint output -- CSS properties like flexbox, gradients, border-radius, and shadows are faithfully reproduced. The result is editable text, high-quality shapes, and smaller file sizes.',
1181
+ },
1182
+ {
1183
+ question: 'Can I convert any HTML to PPTX?',
1184
+ answer: 'Not reliably. html2pptx.app is optimized for slide-oriented HTML with .slide class elements and explicit dimensions. 1600x900 is the default example, but portrait and other custom sizes are also supported. Arbitrary web pages, interactive apps, scroll-based layouts, and pages with JavaScript-dependent rendering are not supported. The HTML contract section describes the exact requirements.',
1185
+ },
1186
+ {
1187
+ question: 'What becomes a separate slide?',
1188
+ answer: 'Each element with the .slide class becomes one slide in the output PPTX. If your HTML contains 5 elements with class="slide", the output will have 5 slides. Define clear slide boundaries for predictable results.',
1189
+ },
1190
+ {
1191
+ question: 'Will exported content remain editable in PowerPoint?',
1192
+ answer: 'Yes, in most cases. Text stays fully editable and shapes remain adjustable in PowerPoint. Inline SVG is converted to high-quality PNG images for reliable output.',
1193
+ },
1194
+ {
1195
+ question: 'How long does export take?',
1196
+ answer: 'Most single-slide jobs complete in 3-5 seconds. Multi-slide decks (10-50 slides) typically take 8-20 seconds depending on complexity, image count, and font embedding. The worker processes slides in parallel where possible. Poll the job status endpoint every 2 seconds for optimal responsiveness.',
1197
+ },
1198
+ {
1199
+ question: 'Which fonts are supported?',
1200
+ answer: 'System fonts (Arial, Helvetica, Times New Roman, etc.) work by default. For web fonts, enable autoEmbedFonts: true -- html2pptx.app will download the font files from Google Fonts or your custom @font-face URLs and embed them into the PPTX. Japanese fonts like Noto Sans JP, Yu Gothic, Meiryo, and Hiragino are fully supported.',
1201
+ },
1202
+ {
1203
+ question: 'Is there a free plan?',
1204
+ answer: 'Yes. The current public catalog includes an Early Access tier with limited API, Skills, and MCP usage. Check GET /api/export/plans for the current plan metadata because limits are enforced from code and may evolve during early rollout.',
1205
+ },
1206
+ {
1207
+ question: 'Can I use SVGs in my slides?',
1208
+ answer: 'Yes. Inline SVG is supported and is converted to high-quality PNG images for reliable output across all PowerPoint environments.',
1209
+ },
1210
+ {
1211
+ question: 'What is the maximum file size?',
1212
+ answer: 'The HTML payload should stay under 5MB. Generated PPTX files vary by content but typically range from 100KB to 10MB. Jobs with many high-resolution images embedded as base64 will produce larger files. Consider using URL references for large images.',
1213
+ },
1214
+ {
1215
+ question: 'How secure is the service?',
1216
+ answer: 'html2pptx.app implements multiple security layers: jobs are bound to the creating principal; API keys are hashed at rest; request body limits and concurrent job limits are enforced server-side. Use the REST API for server-side automation and treat hosted web export as a browser surface.',
1217
+ },
1218
+ {
1219
+ question: 'Does html2pptx.app support Japanese text and CJK characters?',
1220
+ answer: 'Yes, fully. Japanese, Chinese, and Korean characters render correctly. For best results, specify a CJK font in your CSS (e.g., font-family: "Noto Sans JP", sans-serif) and enable autoEmbedFonts to ensure portable rendering on machines without the font installed.',
1221
+ },
1222
+ {
1223
+ question: 'How do I handle errors?',
1224
+ answer: 'Check the job status endpoint. If status is "failed", the error field contains a human-readable description. All API errors return a structured JSON body following RFC 9457 Problem Details format with type, status, title, detail, and instance fields, plus legacy error and message fields for backwards compatibility. Common issues: missing .slide elements (400), expired API key (401), rate limit exceeded (429), oversized content (413).',
1225
+ },
1226
+ {
1227
+ question: 'Can I use CSS Grid for complex slide layouts?',
1228
+ answer: 'Yes. CSS Grid is fully supported including grid-template-columns, grid-template-rows, gap, and grid placement properties. This makes it easy to create multi-column layouts, dashboard-style cards, and complex visual arrangements that convert cleanly to PPTX.',
1229
+ },
1230
+ {
1231
+ question: 'Is there a webhook for job completion?',
1232
+ answer: 'Yes. Add a callbackUrl field (HTTPS only) to your POST /api/export/jobs request. The worker will POST the full job result to your callback URL when the job completes or fails, with an x-signature-sha256 HMAC header for verification. Alternatively, you can still use polling on GET /api/export/jobs/{jobId} with a 2-second interval. For MCP users, html2pptx_wait_for_export_job handles polling automatically.',
1233
+ },
1234
+ ],
1235
+ faqTroubleshootTitle: 'Troubleshooting',
1236
+ faqTroubleshootItems: [
1237
+ { issue: 'Job stuck in "queued" status', solution: 'The private worker may be offline or overloaded. Wait 30 seconds and retry. If persistent, check worker health from the Dashboard or contact support.' },
1238
+ { issue: 'Slides appear blank', solution: 'Ensure your HTML contains elements with class="slide" and that those elements have visible content. Also verify that CSS is included in the payload and not relying on external stylesheets.' },
1239
+ { issue: 'Fonts look different in PPTX', solution: 'Enable autoEmbedFonts: true to embed web fonts. If using custom fonts, ensure the @font-face URLs are publicly accessible. Fallback to system-safe fonts like Arial or Noto Sans for maximum compatibility.' },
1240
+ { issue: '429 Rate limit error', solution: 'Check the X-RateLimit-Reset header for when your window resets. Implement exponential backoff in your polling logic. Upgrade your plan for higher request limits.' },
1241
+ { issue: 'Layout differs from browser preview', solution: 'Use explicit dimensions on .slide elements with inline styles. 1600x900 is the default example, but custom aspect ratios also work when your slide HTML and requested width/height/layout match. Avoid responsive/percentage-based layouts, media queries, and viewport-relative units (vh, vw).' },
1242
+ { issue: 'Images not appearing in PPTX', solution: 'Use absolute URLs (https://...) or base64 data URIs for images. Relative paths and localhost URLs will fail. Ensure image URLs are publicly accessible from the worker.' },
1243
+ { issue: 'PPTX file size is too large', solution: 'Large files are usually caused by embedded base64 images or image-heavy content. Use URL references instead, or compress images before embedding.' },
1244
+ ],
1245
+ },
1246
+
1247
+ /* ------------------------------------------------------------------ */
1248
+ /* Docs copy -- Japanese */
1249
+ /* ------------------------------------------------------------------ */
1250
+ ja: {
1251
+ lang: 'ja',
1252
+ languageLabel: '日本語',
1253
+ metaTitle: 'ドキュメント | html2pptx.app',
1254
+ metaDescription:
1255
+ 'html2pptx.app の包括的なドキュメント。HTML/CSSを完全に編集可能なPowerPointファイルに変換する唯一のAPI。REST API、Skills統合、MCPプロトコル、クイックスタートガイド、HTML変換契約を網羅しています。',
1256
+
1257
+ navSections: [
1258
+ { id: 'overview', label: 'サービス概要', children: [
1259
+ { id: 'overview-channels', label: 'チャネル' },
1260
+ { id: 'overview-comparison', label: '比較' },
1261
+ { id: 'overview-css', label: 'CSS対応' },
1262
+ ]},
1263
+ { id: 'quickstart', label: 'クイックスタート' },
1264
+ { id: 'api-reference', label: 'APIリファレンス', children: [
1265
+ { id: 'api-html-elements', label: '対応HTML要素' },
1266
+ { id: 'api-html-forbidden', label: '使用禁止要素' },
1267
+ ]},
1268
+ { id: 'skills', label: 'Skills統合', children: [
1269
+ { id: 'skills-setup', label: 'セットアップ' },
1270
+ { id: 'skills-local-editor', label: 'ローカル編集' },
1271
+ { id: 'skills-capabilities', label: '機能一覧' },
1272
+ ]},
1273
+ { id: 'mcp', label: 'MCP統合', children: [
1274
+ { id: 'mcp-setup', label: 'セットアップ' },
1275
+ { id: 'mcp-auth', label: '認証方法' },
1276
+ { id: 'mcp-tools', label: 'ツール一覧' },
1277
+ { id: 'mcp-example', label: '使用例' },
1278
+ ]},
1279
+ { id: 'cli', label: 'CLIツール', children: [
1280
+ { id: 'cli-install', label: 'インストール' },
1281
+ { id: 'cli-commands', label: 'コマンド' },
1282
+ { id: 'cli-examples', label: '使用例' },
1283
+ ]},
1284
+ { id: 'use-cases', label: '活用事例' },
1285
+ { id: 'plans', label: 'プラン・料金', children: [
1286
+ { id: 'plans-rate-limits', label: 'レート制限' },
1287
+ ]},
1288
+ { id: 'security', label: 'セキュリティ・制限', children: [
1289
+ { id: 'security-checklist', label: 'チェックリスト' },
1290
+ ]},
1291
+ { id: 'faq', label: 'FAQ', children: [
1292
+ { id: 'faq-troubleshoot', label: 'トラブルシュート' },
1293
+ ]},
1294
+ ],
1295
+
1296
+ /* --- Section 1: サービス概要 --- */
1297
+ overviewTitle: 'サービス概要',
1298
+ overviewSubtitle: 'html2pptx.app とは',
1299
+ overviewDescription:
1300
+ 'html2pptx.app はHTML/CSSを完全に編集可能なPowerPointファイルに変換します -- スクリーンショットではありません。テキストは編集可能なまま、レイアウトは保持され、Flexbox、Grid、グラデーション、シャドウなどのCSSプロパティが忠実に再現されます。結果は本番利用可能なプレゼンテーションファイルです。',
1301
+ overviewHighlight: 'html2pptx.app は、HTML/CSSから完全に編集可能なPowerPointを生成する唯一のAPIです。',
1302
+ overviewArchTitle: 'アーキテクチャ',
1303
+ overviewArchDescription: 'html2pptx.app は信頼性とスケーラビリティのために関心事を分離した4段階パイプラインを採用しています:',
1304
+ overviewArchSteps: [
1305
+ { label: 'Client', detail: 'アプリケーション、エージェント、またはスクリプトがREST API経由でHTML/CSSを送信。HTTPリクエストが可能な言語やプラットフォームであればすべて対応。' },
1306
+ { label: 'API Gateway', detail: '認証 (Bearer / X-API-Key)、プランごとのレート制限、リクエストバリデーション、耐久性のあるメッセージキューへのジョブキューイングを処理。' },
1307
+ { label: 'Private Worker', detail: 'HTML/CSSを完全に編集可能なPowerPointファイルに変換。テキストは編集可能なまま、レイアウトは保持され、CSSスタイリングが忠実に再現されます。' },
1308
+ { label: 'PPTX Output', detail: '生成されたPowerPointファイルはクラウドストレージにアップロードされ、時間制限付き署名URLが返されます。ファイルは24時間保持。' },
1309
+ ],
1310
+ overviewComparisonTitle: 'html2pptx.app と他社の比較',
1311
+ overviewComparison: [
1312
+ { feature: '変換方式', html2pptx: '完全に編集可能なPowerPoint出力', others: 'スクリーンショット/ラスター画像' },
1313
+ { feature: 'テキスト編集', html2pptx: '完全に編集可能なテキストボックス', others: 'フラット画像 -- テキスト編集不可' },
1314
+ { feature: 'CSS対応', html2pptx: 'Flexbox、Grid、グラデーション、シャドウ、transform', others: '限定的または非対応' },
1315
+ { feature: 'SVG処理', html2pptx: '高品質なPNG画像に変換', others: 'PNG画像に変換' },
1316
+ { feature: 'ファイルサイズ', html2pptx: '通常はコンパクト(埋め込み画像量に依存)', others: '大きい(埋め込み画像)' },
1317
+ { feature: 'フォント埋め込み', html2pptx: 'Webフォント自動埋め込み', others: '非対応' },
1318
+ ],
1319
+ overviewChannelsTitle: '3つの統合チャネル',
1320
+ overviewChannels: [
1321
+ {
1322
+ title: 'REST API',
1323
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>',
1324
+ body: 'HTML-to-PPTX エクスポートジョブの作成とステータスポーリングのための標準HTTPエンドポイント。バックエンド統合、社内ツール、SaaS組み込みに最適。curl、JavaScript、Python、Go、Rubyなど、あらゆる言語で利用可能。テンプレート公開は REST API の役割ではありません。',
1325
+ },
1326
+ {
1327
+ title: 'Skills',
1328
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/claude/default.svg',
1329
+ body: 'Claude Code や Codex などのエージェントツール向けに html2pptx スキルを登録。エージェントがHTMLの診断、書き換え、エクスポート、ローカル編集、HTMLテンプレートdraft公開まで内蔵のremote MCPワークフローで実行。AIワークフローでエージェントがパイプライン全体を管理する場合に最適。',
1330
+ },
1331
+ {
1332
+ title: 'MCP (Model Context Protocol)',
1333
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="2"/><path d="M16.24 7.76a6 6 0 010 8.49m-8.48-.01a6 6 0 010-8.49m11.31-2.82a10 10 0 010 14.14m-14.14 0a10 10 0 010-14.14"/></svg>',
1334
+ body: 'MCPプロトコル経由でAIエージェントにバックエンドを公開。remote HTTP MCP (`/mcp`) はエクスポート、docs、catalog、テンプレート公開に使い、local stdio MCP はローカルHTMLを edit-slide で開く場合だけ使います。HTMLテンプレートdraftは、検証後にremote MCP経由で作成します。',
1335
+ },
1336
+ ],
1337
+ overviewCssTitle: '対応CSSプロパティ',
1338
+ overviewCssFeatures: [
1339
+ { category: 'レイアウト', features: 'display: flex, display: grid, position: absolute/relative, gap, align-items, justify-content' },
1340
+ { category: 'ボックスモデル', features: 'padding, margin, width, height, box-sizing, overflow: hidden' },
1341
+ { category: '背景', features: 'background-color, linear-gradient(), radial-gradient(), background-image (URL/base64)' },
1342
+ { category: 'ボーダー', features: 'border, border-radius (各角個別指定対応), border-color, border-width' },
1343
+ { category: 'シャドウ', features: 'box-shadow (単一・複数対応), text-shadow' },
1344
+ { category: 'タイポグラフィ', features: 'font-family, font-size, font-weight, color, text-align, line-height, letter-spacing' },
1345
+ { category: 'トランスフォーム', features: 'transform: rotate(), scale(), translate(), skew()' },
1346
+ { category: 'ビジュアル', features: 'opacity, visibility, z-index, object-fit' },
1347
+ ],
1348
+ overviewUseCasesTitle: 'ユースケース',
1349
+ overviewUseCases: [
1350
+ 'ライブデータからの自動レポート生成',
1351
+ 'テキストプロンプトからのエージェント連携プレゼン作成',
1352
+ '定期スライドデッキの社内ツール統合',
1353
+ 'SaaSダッシュボードからPPTXへのエクスポート機能',
1354
+ 'ブランド準拠テンプレートへの動的コンテンツ投入',
1355
+ 'AIエージェントによる会議メモからプレゼン変換',
1356
+ ],
1357
+ overviewFeaturesTitle: '対応機能',
1358
+ overviewFeatures: [
1359
+ 'SVGは高品質な画像に変換され、安定した出力を実現',
1360
+ 'Webフォント自動埋め込み(Google Fonts、カスタムフォント)',
1361
+ 'Flexbox / CSS Grid レイアウトのPowerPointへの忠実な再現',
1362
+ 'グラデーション・シャドウ・border-radiusのPowerPointでの忠実な再現',
1363
+ 'Base64 / URL画像の自動最適化ハンドリング',
1364
+ '明示サイズのスライドキャンバスに対応。1600x900px (13.333in x 7.5in) はデフォルト例で、width / height / layout によるカスタムサイズも利用可能',
1365
+ 'マルチスライド対応(各 .slide 要素が1枚のPPTXスライドに)',
1366
+ '日本語フォント対応(Noto Sans JP、游ゴシック、メイリオ)',
1367
+ 'Studio と Hosted Web Export をブラウザからそのまま利用可能',
1368
+ ],
1369
+
1370
+ /* --- Section 2: クイックスタート --- */
1371
+ quickstartTitle: 'クイックスタート',
1372
+ quickstartSubtitle: '4ステップで最初の認証付きエクスポート',
1373
+ quickstartIntro: 'REST API は非同期です。まずジョブを作成し、状態をポーリングし、completed になったら downloadUrl から .pptx をダウンロードします。',
1374
+ quickstartSteps: [
1375
+ {
1376
+ step: '1',
1377
+ title: 'サインアップ',
1378
+ body: '<a href="https://html2pptx.app" target="_blank" rel="noopener noreferrer" class="text-blue-600 underline hover:text-blue-800">html2pptx.app</a> でアカウントを作成します。Free Preview で出力品質を確認し、API利用が必要になったら Founder Beta へ進みます。',
1379
+ },
1380
+ {
1381
+ step: '2',
1382
+ title: 'APIキーの取得',
1383
+ body: 'ダッシュボードに移動し、「APIキーを作成」をクリック。コピーして安全に保管してください。キーは一度だけ表示されます。sk_live_ で始まるキーはシークレットとして扱ってください。',
1384
+ },
1385
+ {
1386
+ step: '3',
1387
+ title: '最初のリクエストを送信',
1388
+ body: 'HTMLスライドコンテンツを /api/export/jobs にPOSTします。Authorizationヘッダーにアプリキーを含めてください。APIはエクスポートを追跡するためのjobIdを返します。',
1389
+ },
1390
+ {
1391
+ step: '4',
1392
+ title: 'PPTXをダウンロード',
1393
+ body: 'GET /api/export/jobs/{jobId} をポーリングし、statusが "completed" になるまで待ちます(通常5-15秒)。レスポンスに含まれる downloadUrl から .pptx ファイルをダウンロードします。responseFormat: "base64" を指定すれば fileBase64 でも取得可能です。',
1394
+ },
1395
+ ],
1396
+ quickstartCurlTitle: 'curl',
1397
+ quickstartCurlCode: CURL_EXAMPLE,
1398
+ quickstartJsTitle: 'JavaScript (fetch)',
1399
+ quickstartJsCode: JS_EXAMPLE,
1400
+ quickstartPythonTitle: 'Python (requests)',
1401
+ quickstartPythonCode: PYTHON_EXAMPLE,
1402
+ quickstartCodeTabs: [
1403
+ { label: 'curl', code: CURL_EXAMPLE },
1404
+ { label: 'JavaScript', icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/javascript/default.svg', code: JS_EXAMPLE },
1405
+ { label: 'Python', icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/python/default.svg', code: PYTHON_EXAMPLE },
1406
+ ],
1407
+
1408
+ /* --- Section 3: APIリファレンス --- */
1409
+ apiTitle: 'APIリファレンス',
1410
+ apiBaseUrl: 'ベースURL: https://html2pptx.app',
1411
+ apiContentType: 'すべてのリクエスト・レスポンスボディは application/json を使用します。作成エンドポイントは html/css/fileName に加えて optional な width / height / layout もトップレベルで受け取り、payload ラッパーは使いません。',
1412
+
1413
+ apiAuthTitle: '認証',
1414
+ apiAuthDescription:
1415
+ 'すべての商用APIエンドポイントは認証が必要です。以下のいずれかのヘッダーにAPIキーを含めてください。キーは環境ごと(テスト/本番)にスコープされ、ダッシュボードからローテーション可能です。',
1416
+ apiAuthMethods: [
1417
+ { header: 'Authorization', value: 'Bearer sk_live_xxxx', note: '推奨 -- ほとんどのHTTPクライアント・ライブラリで使用される標準的なBearerトークン形式' },
1418
+ { header: 'X-API-Key', value: 'sk_live_xxxx', note: '代替 -- Authorizationが予約されている環境(APIゲートウェイ、プロキシなど)向け' },
1419
+ ],
1420
+ apiRateLimitTitle: 'レート制限',
1421
+ apiRateLimitDescription: 'すべてのREST APIレスポンスには、現在の1分ウィンドウ、日次上限、月次の公平利用状態を示すヘッダーが含まれます。REST は API キー単位、remote MCP は認証済み principal 単位で制限されます。',
1422
+ apiRateLimitHeaders: [
1423
+ { header: 'x-request-id', description: 'すべてのAPIレスポンスに含まれるリクエスト識別子。デバッグやサポートへの問い合わせ時に有用。' },
1424
+ { header: 'X-Plan-Id', description: 'このリクエストに適用されたプランID。' },
1425
+ { header: 'X-RateLimit-Limit', description: '現在の1分ウィンドウで許可される最大リクエスト数。' },
1426
+ { header: 'X-RateLimit-Remaining', description: '現在のウィンドウの残りリクエスト数。' },
1427
+ { header: 'Retry-After', description: '429 を受けたあとに再試行するまで待つ秒数。' },
1428
+ { header: 'X-Daily-Limit', description: '日次ジョブ上限を持つプランで返される。' },
1429
+ { header: 'X-Daily-Remaining', description: '現在のUTC日次ウィンドウで残っているジョブ数。' },
1430
+ { header: 'X-Monthly-Used', description: '現在のUTC月次ウィンドウで受け付けたジョブ数。' },
1431
+ { header: 'X-Fair-Use-State', description: 'normal / review / upgrade_recommended のような月次公平利用状態。' },
1432
+ ],
1433
+ apiOperationalTitle: '運用上のポイント',
1434
+ apiOperationalItems: [
1435
+ 'POST /api/export/jobs は同期完了ではなく、queued 状態のジョブ記述子を即時返します。',
1436
+ 'ジョブ確認は GET /api/export/jobs/{jobId} を使用してください。上流ワーカー由来の内部URLには依存しないでください。',
1437
+ 'REST の completed レスポンスには downloadUrl が含まれます。responseFormat: "base64" を指定した場合は fileBase64 も含まれます。',
1438
+ 'ジョブ参照は、作成した API キーまたは remote MCP principal に結び付けられています。別キーでは同じ jobId を読めません。',
1439
+ 'スライド数制限は、サニタイズ後の .slide 数からサーバー側で再計算され、クライアント申告値は使われません。',
1440
+ ],
1441
+
1442
+ apiEndpoints: [
1443
+ {
1444
+ method: 'POST',
1445
+ path: '/api/export/jobs',
1446
+ title: 'エクスポートジョブの作成',
1447
+ description: 'トップレベルの HTML/CSS フィールドと optional なプレゼンサイズ指定から新しいPPTXエクスポートジョブを作成します。レスポンスは queued 状態のジョブ記述子で、最終結果は GET /api/export/jobs/{jobId} で取得します。',
1448
+ requestTitle: 'リクエストボディ',
1449
+ requestFields: [
1450
+ { field: 'fileName', type: 'string', required: false, default: 'export.pptx', description: '生成されるPPTXの出力ファイル名。.pptx拡張子で終わる必要あり。' },
1451
+ { field: 'html', type: 'string', required: true, default: '--', description: '.slideクラスを持つ要素を1つ以上含むHTMLコンテンツ。各 .slide が1枚のPPTXスライドに変換されます。' },
1452
+ { field: 'css', type: 'string', required: false, default: '""', description: '送信したHTMLにグローバル適用されるCSS。' },
1453
+ { field: 'autoEmbedFonts', type: 'boolean', required: false, default: 'false', description: 'フォントを検出してPPTXへ埋め込むかどうか。' },
1454
+ { field: 'width', type: 'number', required: false, default: '--', description: 'PPTXスライド幅(インチ)。カスタムサイズ指定時は height とセットで使用。' },
1455
+ { field: 'height', type: 'number', required: false, default: '--', description: 'PPTXスライド高さ(インチ)。カスタムサイズ指定時は width とセットで使用。' },
1456
+ { field: 'layout', type: 'string', required: false, default: '--', description: 'PPTXレイアウトのプリセットまたはカスタム名。代表例: LAYOUT_16x9, LAYOUT_16x10, LAYOUT_4x3, LAYOUT_WIDE。' },
1457
+ { field: 'metadata', type: 'object', required: false, default: '{}', description: 'ワーカーへ透過的に渡される任意メタデータ。追跡用途に便利です。' },
1458
+ { field: 'responseFormat', type: 'string', required: false, default: '"url"', description: '完成したPPTXの配信方法を制御。"url"(デフォルト)は署名付きダウンロードURL、"base64"はインラインbase64、"both"は両方を返します。非推奨の includeFileBase64 パラメータを置き換えます。' },
1459
+ { field: 'callbackUrl', type: 'string', required: false, default: '--', description: 'ジョブ完了/失敗時にWebhook POSTを受け取るHTTPS URL。ワーカーがジョブ結果をこのURLにPOSTし、x-signature-sha256 HMACヘッダーで検証可能。https:// URLのみ受け付け。' },
1460
+ ],
1461
+ requestHeaders: [
1462
+ { header: 'Idempotency-Key', description: '任意。リトライ時の重複ジョブ作成を防ぐ一意の文字列。サーバーは24時間レスポンスをキャッシュし、同じキーで再送すると新しいジョブを作成せず元のレスポンスを返します。' },
1463
+ ],
1464
+ responseTitle: 'レスポンス (200 OK)',
1465
+ responseCode: JOB_RESPONSE_EXAMPLE,
1466
+ errors: [
1467
+ { code: '400', description: '無効なリクエストボディ -- 必須フィールドの欠落または JSON 形式不正。' },
1468
+ { code: '401', description: 'APIキーが未設定または無効。AuthorizationまたはX-API-Keyヘッダーに有効なsk_live_キーが設定されているか確認。' },
1469
+ { code: '403', description: 'APIキーにこの操作の権限がない。プラン制限またはキースコープを確認。' },
1470
+ { code: '413', description: 'リクエストエンティティが大きすぎる。プラン上限またはワーカーのハード上限を超過しています。' },
1471
+ { code: '422', description: 'サニタイズ後のHTMLがプランの最大スライド数を超えています。' },
1472
+ { code: '429', description: 'レート制限、日次上限、月次公平利用ポリシー、または concurrentJobs の上限を超えています。Retry-After や usage ヘッダーを確認してください。' },
1473
+ { code: '502', description: 'バッドゲートウェイ -- ワーカーバックエンドが一時的に利用不可。短い遅延後にリトライ。' },
1474
+ { code: '503', description: 'サービス利用不可 -- システムがメンテナンス中または高負荷状態。指数バックオフでリトライ。' },
1475
+ ],
1476
+ },
1477
+ {
1478
+ method: 'GET',
1479
+ path: '/api/export/jobs/{jobId}',
1480
+ title: 'ジョブステータスの確認',
1481
+ description: 'エクスポートジョブの現在のステータスを取得します。status が "completed" または "failed" になるまでポーリングしてください。REST API では completed 時に fileBase64 が返ります。',
1482
+ requestTitle: 'パスパラメータ',
1483
+ requestFields: [
1484
+ { field: 'jobId', type: 'string', required: true, default: '--', description: 'POST /api/export/jobs から返されたジョブID。' },
1485
+ ],
1486
+ responseTitle: 'レスポンス (200 OK)',
1487
+ responseCode: JOB_STATUS_EXAMPLE,
1488
+ statusValues: [
1489
+ { status: 'queued', description: 'ジョブが処理キューで待機中。' },
1490
+ { status: 'processing', description: 'ワーカーがHTMLのレンダリングとPPTXシェイプへの変換を実行中。' },
1491
+ { status: 'completed', description: '変換が正常に完了。fileBase64 と mimeType が利用可能。' },
1492
+ { status: 'failed', description: '変換失敗。message フィールドに人間が読める説明が入ります。' },
1493
+ ],
1494
+ errors: [
1495
+ { code: '401', description: 'APIキーが未設定または無効' },
1496
+ { code: '404', description: 'ジョブが見つからない -- jobIdが無効か、別のAPIキーに属するジョブ' },
1497
+ { code: '429', description: 'ステータスポーリングのレート制限超過。' },
1498
+ ],
1499
+ },
1500
+ {
1501
+ method: 'GET',
1502
+ path: '/api/export/plans',
1503
+ title: 'プラン一覧の取得',
1504
+ description: 'recommendedPlanId を含む公開プランカタログを返します。認証不要です。',
1505
+ requestTitle: 'パラメータ',
1506
+ requestFields: [],
1507
+ responseTitle: 'レスポンス (200 OK)',
1508
+ responseCode: PLANS_RESPONSE_EXAMPLE,
1509
+ errors: [],
1510
+ },
1511
+ {
1512
+ method: 'GET',
1513
+ path: '/api/openapi.json',
1514
+ title: 'OpenAPI仕様',
1515
+ description: 'html2pptx.app APIのOpenAPI 3.x仕様を返します。クライアントSDKの生成、Postmanへのインポート、APIスキーマの参照に便利です。',
1516
+ requestTitle: 'パラメータ',
1517
+ requestFields: [],
1518
+ responseTitle: 'レスポンス (200 OK)',
1519
+ responseCode: '// OpenAPI 3.x JSONドキュメント全体を返します',
1520
+ errors: [],
1521
+ },
1522
+ ],
1523
+
1524
+ apiVersioningTitle: 'APIバージョニング',
1525
+ apiVersioningDescription: 'バージョン付きエンドポイントが /api/v1/ プレフィックスで利用可能です。元のバージョンなしエンドポイントも後方互換性のため引き続きサポートされます。',
1526
+ apiVersioningEndpoints: [
1527
+ { path: '/api/v1/export/jobs', description: 'エクスポートジョブの作成(POST)またはジョブ一覧' },
1528
+ { path: '/api/v1/export/jobs/{jobId}', description: 'IDでジョブステータスを取得' },
1529
+ { path: '/api/v1/export/plans', description: '利用可能なプラン一覧' },
1530
+ { path: '/api/v1/export/usage', description: '現在の使用状況とクォータを取得' },
1531
+ { path: '/api/v1/export/keys', description: 'APIキーの管理' },
1532
+ ],
1533
+
1534
+ apiIdempotencyTitle: 'べき等性(Idempotency)',
1535
+ apiIdempotencyDescription: 'POST /api/export/jobs に Idempotency-Key ヘッダーを送信すると、リトライ時の重複ジョブ作成を防止できます。サーバーは24時間レスポンスをキャッシュします。同じキーが再度送信された場合、新しいジョブを作成せずに元のレスポンスを返します。キーにはUUID等の一意の文字列を推奨します。',
1536
+
1537
+ apiWebhookTitle: 'Webhookコールバック',
1538
+ apiWebhookDescription: 'POST /api/export/jobs のリクエストボディに callbackUrl フィールド(HTTPSのみ)を追加できます。ジョブが完了または失敗すると、ワーカーがコールバックURLにジョブ結果全体をJSONボディとしてPOSTします。リクエストには x-signature-sha256 ヘッダー(HMAC-SHA256署名)が含まれ、ペイロードの検証が可能です。多くの統合シナリオでポーリングが不要になります。',
1539
+
1540
+ apiErrorsTitle: 'エラーレスポンス形式',
1541
+ apiErrorsDescription: 'すべてのエラーレスポンスはRFC 9457 Problem Details形式に従い、後方互換性のためのレガシーフィールドも含みます:',
1542
+ apiErrorsCode: ERROR_CODES_EXAMPLE,
1543
+
1544
+ apiContractTitle: 'HTML契約',
1545
+ apiContractDescription: '信頼性の高い変換のために、送信するHTMLは以下のルールに従う必要があります。',
1546
+ apiContractRules: [
1547
+ '各スライドには .slide クラスが必要 -- これがスライド分割の境界マーカー',
1548
+ '各 .slide には明示サイズが必要。1600px x 900px (16:9比率、13.333in x 7.5in) はデフォルト例で、API/MCP では width / height / layout による縦長・カスタム出力も指定可能',
1549
+ '対応CSS: flexbox、grid、linear-gradient、radial-gradient、box-shadow、text-shadow、border-radius、transform (rotate、scale、translate、skew)、opacity',
1550
+ 'フォント: システムフォント (Arial、Helvetica、Noto Sans JP) はデフォルトで動作。Google Fontsやカスタム@font-face宣言にはautoEmbedFontsを有効化',
1551
+ '画像: base64データURIと絶対URLの両方に対応。相対パスは失敗する -- 必ず絶対URLを使用',
1552
+ 'SVG: インラインSVG要素に対応。高品質なPNG画像に変換されます',
1553
+ '使用不可: scriptタグ、iframe、canvas要素、アンカータグ、form要素、SVG外部参照、CSSアニメーション、@keyframes、ランタイム依存のstate',
1554
+ 'ネスト: 深くネストされた要素(10レベル超)は出力品質に影響する可能性あり。HTML構造はできるだけフラットに',
1555
+ 'テキスト折り返し: テキストボックスはデフォルトで折り返しなし(nowrap)。長い段落など折り返しが必要な場合は、その要素に white-space: normal を指定してください',
1556
+ ],
1557
+
1558
+ apiHtmlElementsTitle: '対応HTML要素',
1559
+ apiHtmlElementsDescription: '各HTML要素は、最大限の編集性を確保するため、最適なPowerPointオブジェクトに変換されます。',
1560
+ apiHtmlElements: [
1561
+ { element: 'div, section, article', pptx: 'シェイプ(塗りつぶし)', notes: '背景色、グラデーション、ボーダー、角丸が保持されます。' },
1562
+ { element: 'p, h1-h6, span, b, em, strong, i, small', pptx: 'テキストボックス', notes: 'テキストはPowerPointで完全に編集可能。フォントサイズ、太さ、スタイル、色、配置、行間がすべて変換されます。インライン要素(span, b, em等)は同じテキストボックス内のスタイル付きテキストランになります。' },
1563
+ { element: 'img', pptx: '画像', notes: '絶対URLとbase64データURIに対応。CSS object-fit(contain, cover, fill, scale-down)とobject-positionが適用されます。角丸はクリッピングで再現。' },
1564
+ { element: 'table, tr, td, th', pptx: 'ネイティブPPTXテーブル', notes: 'セル単位のテキストスタイル、背景塗りつぶし、ボーダー(solid/dashed/dotted)、パディング、テキスト配置、colspan/rowspanに完全対応。' },
1565
+ { element: 'ul, ol, li', pptx: '箇条書き / 番号リスト', notes: 'シンプルなリストは編集可能な箇条書き・番号リストに変換。複雑なリスト(画像やflex/gridを含む場合)は画像として変換されます。' },
1566
+ { element: 'svg', pptx: '画像(PNG)', notes: 'SVGは高品質なPNG画像に変換されます。' },
1567
+ { element: 'canvas', pptx: '画像(PNG)', notes: 'Canvas内容はPNG画像として埋め込まれます。' },
1568
+ { element: 'アイコン要素(FontAwesome, Material Icons等)', pptx: '画像', notes: 'アイコンフォントは自動検出され、画像に変換されます。' },
1569
+ ],
1570
+ apiHtmlForbiddenTitle: '使用禁止要素',
1571
+ apiHtmlForbiddenDescription: '以下の要素はセキュリティと互換性のため、入力サニタイズ時に自動的に除去されます:',
1572
+ apiHtmlForbidden: [
1573
+ { element: 'script, iframe, object, embed', reason: 'セキュリティ: アクティブコンテンツを除去' },
1574
+ { element: 'link, meta, base', reason: 'セキュリティ: 外部参照を除去' },
1575
+ { element: 'form', reason: 'インタラクティブ要素はPPTX非対応' },
1576
+ { element: 'style', reason: 'インラインスタイルまたはcssパラメータを使用してください' },
1577
+ { element: 'a', reason: 'セキュリティ: アンカータグを除去' },
1578
+ { element: 'foreignobject, image (SVG), feimage, use', reason: 'SVG外部参照を除去' },
1579
+ { element: 'animate, animateMotion, animateTransform, set, discard, mpath', reason: 'SVGアニメーションは非対応' },
1580
+ ],
1581
+
1582
+ /* --- Section 4: Skills統合 --- */
1583
+ skillsTitle: 'Skills統合ガイド',
1584
+ skillsSubtitle: 'Skillsとは',
1585
+ skillsDescription:
1586
+ 'Skillsは、AIコーディングエージェントにドメイン固有の知識とワークフローを追加するパッケージ機能です。html2pptx.app のスキルをインストールすると、エージェントがスライド用HTMLの作成方法を理解し、PPTX変換契約に対する検証を行い、必要に応じてローカル Visual Editor を開き、remote MCP のワークフローでエクスポートし、内蔵のremote MCP公開ワークフローでHTMLテンプレートdraftを作成できます。自然言語の指示だけで、本番品質のPowerPointファイルや作成者所有のHTML draftを生成できます。',
1587
+ skillsHowItWorks: 'スキルには4つのコア機能がバンドルされています: (1) HTMLオーサリング知識 -- 高品質なPowerPointに変換されるHTML/CSSの書き方ルール、(2) MCPベースのエクスポート自動化 -- remote MCP に接続してジョブ作成・ステータスポーリング・結果取得を行う仕組み、(3) ローカル Visual Editor -- ユーザーがPPTX出力前にHTMLを目視確認・微調整したい場合に edit-slide を localhost bridge 経由で開く仕組み、(4) テンプレート公開 -- HTML draft を remote MCP の validate/publish ループに限定する仕組みです。local MCP の追加はユーザーのMCP設定を変更するため、エージェントは必ず事前に確認します。',
1588
+ skillsCompatibility: 'Claude Code、Cursor、GitHub Copilot、Windsurf、Cline、Codex 等 18以上のAIエージェントに対応。使うエージェントに対応する skills CLI コマンドを選ぶか、その他の対応エージェントは対話形式で選択します。',
1589
+ skillsWorkflowTitle: 'ワークフロー',
1590
+ skillsWorkflow: [
1591
+ 'エージェントがユーザーリクエストを受信(例: 「この会議メモからデッキを作成して」)',
1592
+ 'エージェントがスキル定義を読み取り、html2pptx.appのHTML契約を理解',
1593
+ 'エージェントが .slide クラス要素と明示サイズ付きのスライドセーフHTMLを生成。1600x900 はデフォルト例',
1594
+ 'エージェントが変換契約に対してマークアップを検証',
1595
+ '目視確認が必要な場合は、local stdio MCP で edit-slide を開き、編集後のHTMLをディスクから再読み込み',
1596
+ 'エージェントが remote MCP に接続し html2pptx_create_export_job を呼び出し',
1597
+ 'エージェントが html2pptx_wait_for_export_job で完了をポーリング',
1598
+ 'HTMLテンプレートdraftを作る場合は、html2pptx スキルと remote MCP でHTMLから題名・タグを推定し、AIセキュリティ事前診断、検証、エラー修正、下書き保存を行い、draftUrlを返却',
1599
+ 'エージェントが completed 状態のジョブサマリーをユーザーに返却',
1600
+ ],
1601
+ skillsLocalEditorTitle: 'ローカル Visual Editor',
1602
+ skillsLocalEditorLead:
1603
+ 'edit-slide スキルを使うと、エージェントが作成したローカルHTMLスライドを、http://localhost:<port> のような空き loopback origin で動くPowerPoint風のノーコード編集画面で開けます。ローカルファイル編集に hosted edit-slide は使えません。ローカル dev script が空きポートを選び、現在のプロジェクト内の .html2pptx/edit-slide/editor-server.json に登録します。スライドHTMLファイルはユーザーのPC上に残り、CLI または local stdio MCP が起動する localhost bridge 経由で読み書きされます。local MCP が未設定の場合は、local editor が動いていれば `html2pptx edit <file>` を使い、MCP設定を変更する場合はユーザー確認を取ってから追加します。',
1604
+ skillsLocalEditorCode: `# local MCP tool だけを使う
1605
+ html2pptx_open_local_slide_editor({ "filePath": "html2pptx/slides.html" })
1606
+
1607
+ # Claude Code local MCP setup
1608
+ npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude`,
1609
+ skillsLocalEditorFlowTitle: 'ローカル編集の仕組み',
1610
+ skillsLocalEditorFlow: [
1611
+ { label: '1. remote / local MCP を選ぶ', detail: '通常のPPTX出力、docs、template、usage 取得は remote MCP を使えます。ローカル `.html` / `.htm` を edit-slide で開いて編集する場合は local stdio MCP または `html2pptx edit <file>` を使います。local MCP が未設定なら、直接CLIを使うか、追加前にユーザーへ確認します。' },
1612
+ { label: '2. bridge を起動', detail: '`html2pptx_open_local_slide_editor` が `127.0.0.1` に小さなHTTPサーバーを起動します。ポートは指定しない限りOSが選ぶ空きポートになります。アクセス範囲はコマンドを実行したカレントディレクトリ内に限定されます。' },
1613
+ { label: '3. エディタを開く', detail: 'コマンドが `http://localhost:<editor-port>/edit-slide?file=...&bridge=http://127.0.0.1:<bridge-port>#bridgeToken=...` を開きます。ワンタイム token は URL fragment に置かれ、起動後にエディタがアドレスバーから消します。' },
1614
+ { label: '4. ローカルHTMLを読み込む', detail: 'ブラウザの編集画面が token を提示し、localhost bridge から対象の `.html` / `.htm` ファイルを取得します。マーケットプレイス下書きや公開ページは作成されません。' },
1615
+ { label: '5. ノーコードで編集', detail: 'スライド上の要素をクリックし、右パネルからテキスト、タイポグラフィ、色、サイズ、余白、角丸、ボーダー、不透明度などを調整できます。' },
1616
+ { label: '6. 同じファイルへ保存', detail: '編集内容はHTMLとして再シリアライズされ、楽観的ロック用のファイルハッシュ付きで同じHTMLファイルへ保存されます。バージョン履歴、バックアップ、監査ログは作成されません。' },
1617
+ { label: '7. エージェント作業へ戻る', detail: 'ユーザーが画面で編集した後は、エージェントがHTMLファイルを再読み込みします。PowerPoint出力が必要なら、html2pptx skills を使う別のエージェント作業として実行します。' },
1618
+ ],
1619
+ skillsLocalEditorPrivacyTitle: 'プライバシーとファイルアクセス',
1620
+ skillsLocalEditorPrivacy: [
1621
+ 'bridge は `127.0.0.1` のみに bind します。ネットワーク上の他ユーザーはその bridge を開けません。',
1622
+ 'bridge 起動ごとにセッショントークンを生成し、エディタはローカル読み書き時にその token を提示する必要があります。表示URLからは起動後に token を除去します。',
1623
+ 'スライドプレビューは no-referrer を使うため、外部画像やフォントに token 付き editor URL が送られにくくなっています。',
1624
+ '読み書きできるのは、カレントディレクトリ配下の `.html` / `.htm` ファイルだけです。',
1625
+ '`app/`、`components/`、`lib/`、`.git/`、`.next/`、`node_modules/` などのプロジェクトソースや内部ディレクトリはブロックされます。',
1626
+ 'ノーコード編集だけではデッキは公開・アップロードされません。Export PPTX ボタンは `Claude Codeや各エージェントに、html2pptx skillsを使って、HTMLをPowerPoint出力してください。` という案内だけを表示し、直接変換は行いません。',
1627
+ 'local stdio MCP の追加はユーザーのエージェント環境設定を変更します。Skills やエージェントは黙って追加せず、事前に確認してから実行します。',
1628
+ 'エディタ状態はプロジェクトごとに `.html2pptx/edit-slide/` に保存されます。バージョン履歴、バックアップ、監査ログは作成されません。',
1629
+ ],
1630
+ skillsLocalEditorTroubleshootingTitle: 'よくあるつまずき',
1631
+ skillsLocalEditorTroubleshooting: [
1632
+ { issue: 'local editor tool が使えない', fix: '`npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude` で local MCP を追加してよいか、先にユーザーへ確認してください。' },
1633
+ { issue: '`html2pptx edit` が local editor を見つけられない', fix: '`node scripts/dev-studio.mjs` を先に起動するか、`--base-url http://localhost:<port>` で loopback URL を渡してください。hosted edit-slide は使いません。' },
1634
+ { issue: '画面は開くがスライドが読み込まれない', fix: 'コマンドを実行したディレクトリからの相対パスになっているか、拡張子が `.html` / `.htm` かを確認してください。' },
1635
+ { issue: '編集内容が保存されない', fix: 'local MCP セッションを終了しないでください。bridge が止まると保存できません。' },
1636
+ { issue: 'エージェントが local MCP を追加しようとする', fix: '先にユーザーへ確認してください。local MCP は MCP 経由でローカル edit-slide を開く場合だけ必要です。CLI の `html2pptx edit <file>` でも local editor を開けます。' },
1637
+ { issue: '別タブが読み取り専用になる', fix: '同じHTMLを複数タブで編集して競合しないよう、エディタはタブロックを使います。編集権限のあるタブを使うか、画面上の移譲操作を行ってください。' },
1638
+ ],
1639
+ skillsSetupTitle: 'セットアップ',
1640
+ skillsSetupSteps: [
1641
+ {
1642
+ step: '1',
1643
+ title: 'MCP + スキルをインストール',
1644
+ icons: ['claude-code', 'codex', 'cursor', 'windsurf'],
1645
+ body: 'Claude Code、Codex、Cursor、Windsurf のうち、実際に使うエージェントのコマンドを選んで実行してください。その他の対応エージェントや複数指定の場合は対話形式で選択します。--yes は検出された全エージェントのディレクトリへ入るため、全対応が必要な場合以外は使わないでください。',
1646
+ code: SKILL_INSTALL_COMMAND_JA,
1647
+ },
1648
+ {
1649
+ step: '2',
1650
+ title: 'APIキーの設定',
1651
+ body: 'html2pptx.app ダッシュボードでAPIキーを作成し、環境変数に設定します。',
1652
+ code: `# 環境変数にAPIキーを設定
1653
+ export HTML2PPTX_API_KEY="sk_live_xxxx"
1654
+
1655
+ # または .env ファイルに追加
1656
+ echo 'HTML2PPTX_API_KEY=sk_live_xxxx' >> .env`,
1657
+ },
1658
+ {
1659
+ step: '3',
1660
+ title: '使ってみる',
1661
+ body: 'エディタを起動して、自然言語でスライド作成を指示するだけ。スキルが自動でHTMLの生成・検証・API呼び出し・PPTX出力まで処理します。',
1662
+ code: SKILL_INVOCATION_EXAMPLE,
1663
+ },
1664
+ ],
1665
+ skillsAvailableTitle: '利用可能なスキル',
1666
+ skillsAvailable: SKILL_AVAILABLE_LIST,
1667
+ skillsCapabilitiesTitle: 'スキルの機能詳細',
1668
+ skillsCapabilities: [
1669
+ { title: 'HTML診断', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>', body: 'エクスポート前にマークアップをsafe、needs-rewrite、out-of-scopeに分類。.slide要素の欠落、非対応CSS、動的コンテンツなどの問題を検出。' },
1670
+ { title: 'マークアップ書き換え', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>', body: 'Web形式のHTML(レスポンシブレイアウト、パーセントベースのサイジング、スクロールコンテナ)をPPTX変換に適した固定サイズの.slide構造に変換。' },
1671
+ { title: 'スライド生成', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>', body: 'テキストプロンプト、トピックアウトライン、データペイロードからスライドセーフHTMLを新規作成。視覚的階層と可読性のベストプラクティスを適用。' },
1672
+ { title: '出力検証', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><polyline points="9 12 11 14 15 10"/></svg>', body: '生成されたHTMLを html2pptx.app のHTML契約に対してプリフライトチェックし、無効な入力によるエクスポートクォータの無駄遣いを防止。' },
1673
+ { title: 'テンプレート公開', icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="m7 8 5-5 5 5"/><path d="M5 21h14"/></svg>', body: 'マーケットプレイス向けHTML draftは、html2pptx スキル内のAIセキュリティ事前診断、remote MCP検証、draft作成フローで扱います。Web、CLI、local MCP、汎用RESTではテンプレートdraftを作成しません。' },
1674
+ ],
1675
+
1676
+ /* --- Section 5: MCP統合 --- */
1677
+ mcpTitle: 'MCP統合ガイド',
1678
+ mcpSubtitle: 'MCPとは',
1679
+ mcpDescription:
1680
+ 'MCP (Model Context Protocol) は、標準化されたツールインターフェースを通じてAIエージェントにバックエンド機能を公開するオープンプロトコルです。html2pptx.app は2種類のMCPサーフェスを提供します。remote HTTP MCP (`/mcp`) はエクスポート、usage、docs、templates、catalog、HTMLテンプレート公開に使います。local stdio MCP は localhost bridge 経由でローカルHTMLを edit-slide で開くために使います。HTMLをPPTXに変換する、またはHTMLテンプレートdraftを作るなら remote MCP、ユーザーPC上の `.html` を開いてプレビュー・編集するなら local MCP を選びます。local MCP はテンプレート公開には使いません。',
1681
+ mcpSetupTitle: 'インストール & セットアップ',
1682
+ mcpSetupLead: 'Claude Code では1コマンドインストーラで remote MCP と edit-slide 用 local MCP をまとめて追加できます。ローカル編集が不要な場合だけ remote-only コマンドを使ってください。',
1683
+ mcpEditorTabs: [
1684
+ {
1685
+ id: 'claude-code',
1686
+ label: 'Claude Code',
1687
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/claude/default.svg',
1688
+ recommended: true,
1689
+ steps: [
1690
+ { title: 'リモートサーバーをセットアップ(推奨)', body: 'ターミナルで以下のコマンドを実行してください。', code: `claude mcp add --transport http html2pptx https://html2pptx.app/mcp` },
1691
+ { title: '手動セットアップ', body: 'コマンドが使えない場合は、以下を実行してMCPサーバーを手動で追加してください。', code: `claude mcp add html2pptx --transport http https://html2pptx.app/mcp` },
1692
+ { title: 'Remote + Local を1コマンドで追加', body: 'PPTX出力・docs・templates 用の remote MCP と、edit-slide 用の local MCP をまとめて追加します。公開パッケージから導入するため、リポジトリの checkout は不要です。local MCP は Claude Code が安定して起動できるよう stable launcher として登録されます。', code: `npx -y html2pptx-local-mcp@latest html2pptx-install-mcp claude` },
1693
+ ],
1694
+ tip: 'すべてのプロジェクトでMCPサーバーを使用するには --scope user フラグを追加してください:\nclaude mcp add --scope user --transport http html2pptx https://html2pptx.app/mcp',
1695
+ },
1696
+ {
1697
+ id: 'codex',
1698
+ label: 'Codex',
1699
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/openai/light.svg',
1700
+ steps: [
1701
+ { title: 'CLIコマンドで追加(推奨)', body: 'ターミナルで以下のコマンドを実行してください。OAuth認証が自動的に開始されます。', code: `codex mcp add html2pptx --url https://html2pptx.app/mcp` },
1702
+ { title: 'edit-slide 用 local stdio MCP(任意)', body: 'Codex がローカル `.html` を edit-slide で開く必要がある場合だけ追加します。公開パッケージから起動するため、リポジトリのcheckoutは不要です。エディタ本体と localhost bridge は空きポートを使います。MCP設定を変更するため、Codex は実行前にユーザー確認を取ってください。', code: `codex mcp add html2pptx-local -- npx -y html2pptx-local-mcp@latest html2pptx-mcp` },
1703
+ { title: 'codex.json で手動セットアップ', body: 'コマンドが使えない場合は、プロジェクトルートの codex.json に以下を追加してください。', code: `{\n "mcpServers": {\n "html2pptx": {\n "type": "url",\n "url": "https://html2pptx.app/mcp"\n }\n }\n}` },
1704
+ ],
1705
+ },
1706
+ {
1707
+ id: 'cursor',
1708
+ label: 'Cursor',
1709
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/cursor/light.svg',
1710
+ steps: [
1711
+ { title: '.cursor/mcp.json に追加', body: 'プロジェクトルートに .cursor/mcp.json を作成し、以下を追加してください。', code: `{\n "mcpServers": {\n "html2pptx": {\n "url": "https://html2pptx.app/mcp"\n }\n }\n}` },
1712
+ ],
1713
+ },
1714
+ {
1715
+ id: 'vscode',
1716
+ label: 'VS Code',
1717
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/visual-studio-code/default.svg',
1718
+ steps: [
1719
+ { title: 'CLIコマンドで追加(推奨)', body: 'ターミナルで以下のコマンドを実行してください。', code: `code --add-mcp '{"name":"html2pptx","type":"http","url":"https://html2pptx.app/mcp"}'` },
1720
+ { title: '.vscode/mcp.json で手動セットアップ', body: 'コマンドが使えない場合は、プロジェクトルートに .vscode/mcp.json を作成してください。', code: `{\n "servers": {\n "html2pptx": {\n "type": "http",\n "url": "https://html2pptx.app/mcp"\n }\n }\n}` },
1721
+ ],
1722
+ },
1723
+ {
1724
+ id: 'windsurf',
1725
+ label: 'Windsurf',
1726
+ icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/windsurf/default.svg',
1727
+ steps: [
1728
+ { title: 'mcp_config.json に追加', body: '~/.codeium/windsurf/mcp_config.json を編集し、以下を追加してください。保存後 Windsurf を再起動してください。', code: `{\n "mcpServers": {\n "html2pptx": {\n "serverUrl": "https://html2pptx.app/mcp"\n }\n }\n}` },
1729
+ ],
1730
+ },
1731
+ {
1732
+ id: 'cline',
1733
+ label: 'Cline',
1734
+ steps: [
1735
+ { title: 'Cline サイドバーから追加', body: 'Cline サイドバー > Configure タブ > 「Configure MCP Servers」を開き、以下を追加してください。', code: `{\n "mcpServers": {\n "html2pptx": {\n "url": "https://html2pptx.app/mcp",\n "type": "streamableHttp"\n }\n }\n}` },
1736
+ ],
1737
+ },
1738
+ ],
1739
+ mcpToolsTitle: '利用可能なMCPツール',
1740
+ mcpTools: [
1741
+ { tool: 'html2pptx_list_export_plans', description: '現在の商用プラン一覧と推奨プランを取得。' },
1742
+ { tool: 'html2pptx_create_export_job', description: 'HTML/CSS からエクスポートジョブを作成。width、height、layout、waitForCompletion、timeoutMs、responseFormat ("url" | "base64" | "both") などのオプションにも対応。' },
1743
+ { tool: 'html2pptx_get_export_job', description: 'jobId を指定してジョブの現在状態を取得。' },
1744
+ { tool: 'html2pptx_wait_for_export_job', description: '完了または失敗までジョブを自動ポーリング。内部でリトライとバックオフを処理。' },
1745
+ { tool: 'html2pptx_get_docs', description: 'html2pptx.app のドキュメントを取得。API契約、HTML要件、統合ガイドを理解するために使用。' },
1746
+ { tool: 'html2pptx_get_usage', description: '現在のプランの使用状況とクォータを取得。週間エクスポート数、残りクォータ、プラン制限、リセットタイミングを表示。' },
1747
+ { tool: 'html2pptx_list_templates', description: '利用可能なマーケットプレイステンプレートを、メタデータと任意のカテゴリ絞り込み付きで取得。' },
1748
+ { tool: 'html2pptx_get_template_html', description: 'テンプレートのHTMLソースとデザインプロンプトを取得。エージェントが研究・リミックスするために使用。' },
1749
+ { tool: 'html2pptx_validate_template_html', description: 'AIセキュリティ事前診断後に行うマーケットプレイスHTMLのdry-run検証。HTMLテンプレートdraft作成前に必須。' },
1750
+ { tool: 'html2pptx_publish_template', description: '検証済みHTMLをアップロードし、不足している題名・説明・カテゴリ・タグを推定して、作成者所有のHTML draftをデフォルト作成。draftUrlを返し、最終公開ボタンはユーザーがdashboardで押します。' },
1751
+ { tool: 'html2pptx_open_local_slide_editor', description: 'ローカル stdio MCP 専用。既存CLIの localhost bridge をローカル .html/.htm スライドファイル向けに起動し、HTMLを公開せずノーコードエディタを開く。remote /mcp ではユーザーPC上のファイルにアクセスできないため、このツールは提供されません。' },
1752
+ { tool: 'html2pptx_stop_local_slide_editor', description: 'ローカル stdio MCP 専用。html2pptx_open_local_slide_editor で開始したローカル編集 bridge セッションを停止。' },
1753
+ ],
1754
+ mcpResourcesTitle: 'MCP Resources(ドキュメント参照)',
1755
+ mcpResourcesDescription: 'MCPサーバーはドキュメントをResourcesとして提供します。エージェントはエクスポート前にこれらを読み込んで、API契約やHTML要件を理解できます。',
1756
+ mcpResources: [
1757
+ { uri: 'docs://html2pptx/overview', name: 'サービス概要', description: 'アーキテクチャ、CSS対応、他社比較' },
1758
+ { uri: 'docs://html2pptx/quickstart', name: 'クイックスタート', description: '4ステップで最初のAPIコール' },
1759
+ { uri: 'docs://html2pptx/api-reference', name: 'APIリファレンス', description: 'エンドポイント、認証、エラーコード' },
1760
+ { uri: 'docs://html2pptx/html-contract', name: 'HTML契約', description: 'HTML構造要件と対応CSSプロパティ' },
1761
+ { uri: 'docs://html2pptx/skills', name: 'Skills統合', description: 'AIエージェント向けスキル定義' },
1762
+ { uri: 'docs://html2pptx/mcp', name: 'MCP統合', description: 'MCPサーバーの設定と使い方' },
1763
+ ],
1764
+ mcpLlmsTxtTitle: 'llms.txt(AI向けドキュメント)',
1765
+ mcpLlmsTxtDescription: 'html2pptx.app は llms.txt 標準に対応しています。AIエージェントやLLMがサービスの仕様を効率的に理解するための、構造化されたMarkdownドキュメントを提供します。',
1766
+ mcpLlmsTxtEndpoints: [
1767
+ { url: 'https://html2pptx.app/llms.txt', description: '簡潔なインデックス(約100行)— サービス概要、API仕様、対応CSS一覧' },
1768
+ { url: 'https://html2pptx.app/llms-full.txt', description: '完全なドキュメント(約900行)— 全セクションのMarkdown版' },
1769
+ ],
1770
+ mcpProgressTitle: '進捗通知・ログ',
1771
+ mcpProgressDescription: 'MCPサーバーはジョブ処理中にリアルタイムのフィードバックを提供します:',
1772
+ mcpProgressItems: [
1773
+ { feature: 'notifications/progress', description: 'ジョブポーリング中に進捗率と現在のステータスを通知。MCPクライアントはプログレスバーやステータスインジケーターを表示可能。' },
1774
+ { feature: 'notifications/message', description: 'ジョブ作成、処理開始、完了、失敗などのライフサイクルイベントを通知。デバッグ用の人間が読めるログメッセージを提供。' },
1775
+ ],
1776
+
1777
+ mcpResourceLinkTitle: 'ResourceLink',
1778
+ mcpResourceLinkDescription: 'ジョブが downloadUrl 付きで完了すると、MCPレスポンスに ResourceLink を含む resource コンテンツブロックが追加されます。これにより、MCPクライアントが生成ファイルをネイティブに処理可能になります -- 例えば、直接ダウンロードボタンの表示や、会話コンテキストへのファイル参照の埋め込みなど。',
1779
+
1780
+ mcpAuthTitle: '認証方法',
1781
+ mcpAuthDescription: 'MCPサーバーは2つの認証方法に対応しています。用途に合わせて選択してください。APIキーはエクスポート、docs、usage、catalog には使えますが、html2pptx_publish_template は作成者IDが必要なため WorkOS-bound user token が必要です。',
1782
+ mcpAuthMethods: [
1783
+ {
1784
+ method: 'APIキー(推奨)',
1785
+ description: 'ダッシュボードで発行したAPIキーを使用します。APIキーには有効期限がない(設定しない限り)ため、再認証の必要がありません。エクスポート、docs、catalog の日常的なMCP利用にはこちらを推奨します。作成者所有のテンプレートdraftは作成できません。',
1786
+ setup: 'ダッシュボードでAPIキーを発行し、Bearerトークンとして設定してください。ほとんどのMCPクライアントはサーバー追加時に自動で処理します。',
1787
+ pros: ['トークン期限切れなし — 安定した長期セッション', 'シンプルな設定 — キーを貼るだけ', '日常利用や自動化に最適'],
1788
+ },
1789
+ {
1790
+ method: 'OAuth(ブラウザログイン)',
1791
+ description: 'WorkOS AuthKit経由でGoogleアカウントやメールアドレスでログインします。アクセストークンの有効期限は24時間で、期限切れ後は再認証が必要です。html2pptx_publish_template にはこの identity-bound な認証が必要です。',
1792
+ setup: 'MCPサーバーを追加すると、ブラウザでログイン画面が自動的に開きます。サインインして認証を完了してください。',
1793
+ pros: ['APIキー管理が不要', 'お試しや評価に最適'],
1794
+ note: 'OAuthセッションは24時間で期限切れになります。途切れないアクセスが必要な場合は、APIキーの利用を推奨します。',
1795
+ },
1796
+ ],
1797
+
1798
+ mcpErrorRecoveryTitle: 'エラーリカバリーガイダンス',
1799
+ mcpErrorRecoveryDescription: 'MCPのエラーメッセージには、LLMエージェントが自己回復するための実行可能なガイダンスが含まれます。例: レート制限時は「30秒待ってリトライ」、バリデーションエラー時は「html2pptx_get_docs を呼んでHTML契約を確認」、プラン制限エラー時は「スライド数をN枚に削減」など。エージェントがユーザーの介入なしに問題を自動診断・解決できます。',
1800
+
1801
+ mcpExampleTitle: '使用例',
1802
+ mcpExampleCode: MCP_USAGE_EXAMPLE,
1803
+
1804
+ /* --- Section 6: Studio & Hosted Web Export --- */
1805
+ studioTitle: 'Studio・Hosted Web Export',
1806
+ studioLead: 'html2pptx.app には、ブラウザから使う Studio と Hosted Web Export もあります。これらは手動編集、目視確認、軽量なブラウザ内エクスポート向けの公開サーフェスです。',
1807
+ studioCards: [
1808
+ {
1809
+ title: 'Studio',
1810
+ body: 'Studio は手動オーサリング環境です。HTML/CSS を貼り付けて見た目を調整し、ブラウザ上で確認してからエクスポートできます。',
1811
+ },
1812
+ {
1813
+ title: 'Hosted Web Export',
1814
+ body: 'Hosted Web Export は、同一オリジンのWebアプリから使うためのブラウザ向けエンドポイントです。バックエンド自動化や外部公開APIの代わりではありません。',
1815
+ },
1816
+ {
1817
+ title: '使い分け',
1818
+ body: 'バックエンド連携は REST API、エージェント連携は Skills/MCP、手動編集は Studio、ファーストパーティのブラウザUIからの軽量エクスポートは Hosted Web Export を使うのが基本です。',
1819
+ },
1820
+ ],
1821
+ studioWorkflowTitle: '公開サーフェスの役割分担',
1822
+ studioWorkflow: [
1823
+ 'Studio は公開された手動編集UIです。',
1824
+ 'Hosted Web Export は /api/web-export/jobs を使う same-origin ブラウザ向けサーフェスです。',
1825
+ 'REST API はサーバー連携・自動化の正式インターフェースです。',
1826
+ '再現性の高い本番自動化には Hosted Web Export ではなく REST API を使用してください。',
1827
+ 'Studio、Hosted Web Export、API、Skills、MCP はすべて同じ変換品質とセキュリティ基準を共有します。',
1828
+ 'テンプレート公開だけは意図的に狭くしています。Web UI、CLI、local MCP、REST API は marketplace draft を作れません。draft作成はHTMLのみで、remote MCP の検証・下書き保存フローを通します。エージェントはHTMLから題名・タグを推定できますが、最終公開ボタンはユーザーがdashboardで押します。',
1829
+ ],
1830
+ studioExampleTitle: 'Hosted Web Export の例',
1831
+ studioExampleCode: WEB_EXPORT_EXAMPLE,
1832
+
1833
+ /* --- Section 6b: CLIツール --- */
1834
+ cliTitle: 'CLIツール',
1835
+ cliSubtitle: 'CLIとは',
1836
+ cliDescription:
1837
+ 'html2pptx CLI を使えば、ターミナルから直接HTMLファイルをPowerPointに変換し、ローカルHTMLを edit-slide で開き、テンプレートを参照できます。初めてのユーザー向けの対話モード(ガイド付きプロンプト)と、スクリプト・CI/CD・AIエージェント(Claude Code等)向けのダイレクトモード(フラグ指定)の両方に対応しています。テンプレートdraft作成はHTMLのみremote MCP限定で、CLIでは意図的に拒否します。',
1838
+ cliInstallTitle: 'インストール',
1839
+ cliInstallSteps: [
1840
+ { label: 'グローバルインストール', command: 'npm install -g html2pptx-cli' },
1841
+ { label: 'npxで直接実行', command: 'npx html2pptx-cli convert slides.html' },
1842
+ ],
1843
+ cliSetupTitle: '初期設定',
1844
+ cliSetupDescription: 'ファイルを変換する前に、APIキーを設定してください。この設定は一度だけ行えば ~/.html2pptx/config.json に保存されます(所有者のみアクセス可)。',
1845
+ cliSetupCode: 'html2pptx init',
1846
+ cliCommandsTitle: 'コマンド一覧',
1847
+ cliCommands: [
1848
+ { command: 'html2pptx login', description: 'APIキーを対話的に設定します。ダッシュボードへのリンクが表示され、キーを生成できます。' },
1849
+ { command: 'html2pptx logout', description: '保存されたAPIキーを ~/.html2pptx/config.json から削除します。' },
1850
+ { command: 'html2pptx convert [file]', description: 'HTMLファイルをPPTXに変換します。引数なしで対話モード、ファイルパス指定でダイレクトモードになります。' },
1851
+ { command: 'html2pptx status', description: '現在の使用量、残りクォータ、レート制限、プラン詳細を確認します。' },
1852
+ { command: 'html2pptx whoami', description: 'APIキーの有効性を検証し、認証状態・プラン名・使用量を表示します。' },
1853
+ { command: 'html2pptx config', description: '現在の設定(APIキー、ベースURL)を表示します。' },
1854
+ { command: 'html2pptx templates list', description: '利用可能なテンプレート一覧を表示します。' },
1855
+ { command: 'html2pptx templates get <id>', description: 'テンプレートの詳細を取得します。--prompt でデザインプロンプト、--html でソースコードを含めます。' },
1856
+ { command: 'html2pptx templates publish', description: '無効化されています。テンプレート公開はHTMLのみremote MCP経由です。' },
1857
+ { command: 'html2pptx --help', description: 'ヘルプとコマンド一覧を表示します。' },
1858
+ { command: 'html2pptx --version', description: 'インストール済みのCLIバージョンを表示します。' },
1859
+ ],
1860
+ cliOptionsTitle: 'convert オプション',
1861
+ cliOptions: [
1862
+ { flag: '-o, --output <file>', description: '出力PPTXファイル名(デフォルト: 入力ファイル名の拡張子を .pptx に変更)' },
1863
+ { flag: '-s, --size <size>', description: 'スライドサイズ: "16:9"、"4:3"、またはカスタム "WxH"(例: 1920x1080)' },
1864
+ { flag: '--css <file>', description: 'HTMLと一緒に適用する外部CSSファイル' },
1865
+ { flag: '--json', description: 'スクリプトやCI/CDパイプライン向けにJSON形式で結果を出力' },
1866
+ { flag: '--open', description: '変換後にPPTXファイルを自動で開く' },
1867
+ { flag: '--base-url <url>', description: 'APIベースURL(デフォルト: https://html2pptx.app)' },
1868
+ ],
1869
+ cliExamplesTitle: '使用例',
1870
+ cliExamples: [
1871
+ { title: 'ダイレクトモード(スクリプト・AIエージェント向け)', code: '# ワンライナーで変換\nhtml2pptx convert ./slides.html -o presentation.pptx -s 16:9\n\n# 外部CSSを指定\nhtml2pptx convert ./slides.html --css ./styles.css -o deck.pptx\n\n# JSON出力(スクリプト連携用)\nhtml2pptx convert ./slides.html --json\n# {"success":true,"file":"slides.pptx","size":"1.2 MB","duration":"3.2s"}' },
1872
+ { title: '対話モード(初めてのユーザー向け)', code: '# 引数なしで実行するだけ\nhtml2pptx convert\n\n# CLIがガイドします:\n# > 変換するHTMLファイル\n# > スライドサイズの選択\n# > 出力ファイル名' },
1873
+ { title: 'アカウント管理', code: '# 認証状態を確認\nhtml2pptx whoami\n# Plan: Starter\n# Usage: 1 / 120 exports today\n# Remaining: 119\n\n# 詳細な使用量を確認\nhtml2pptx status\n# Plan: Starter\n# Daily Usage: 42 / 120 exports ████████████░░░░░░░░\n# Remaining: 78\n# Rate Limit: 5 req/min\n# Max Slides: 50 per job\n\n# ログアウト\nhtml2pptx logout' },
1874
+ { title: 'テンプレート', code: '# テンプレート一覧\nhtml2pptx templates list\n\n# デザインプロンプト付きで取得\nhtml2pptx templates get atlantis-pizza-corp --prompt\n\n# HTMLソース付きでJSON出力\nhtml2pptx templates get atlantis-pizza-corp --prompt --html --json\n\n# 下書き作成はremote MCP限定:\n# AI security preflight -> html2pptx_validate_template_html -> html2pptx_publish_template -> dashboard review' },
1875
+ ],
1876
+
1877
+ /* --- Section 7: 活用事例 --- */
1878
+ useCasesTitle: '活用事例',
1879
+ useCasesIntro: 'html2pptx.app は自動化された反復可能なスライド生成のために設計されています。最も一般的な統合パターンをご紹介します:',
1880
+ useCases: [
1881
+ {
1882
+ title: '四半期レポートの自動生成',
1883
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>',
1884
+ body: 'ライブデータから四半期パフォーマンスデッキを自動生成。データベースからメトリクスを取得し、チャートやKPIカードを含むスライドHTMLにフォーマットしてAPI経由でエクスポート。cronでスケジュールするか、BIパイプラインからトリガーすることで完全にハンズフリーのレポーティングを実現。',
1885
+ code: REPORT_EXAMPLE,
1886
+ },
1887
+ {
1888
+ title: '営業提案書のテンプレート化',
1889
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>',
1890
+ body: 'ブランド準拠のスライドテンプレートをHTML/CSSで一度定義し、キャンペーンやクライアントピッチごとに動的コンテンツを投入。会社名、プロジェクト詳細、価格などの変数は生成時にインジェクション。マーケティングチームがテンプレートを管理し、営業担当者はピクセルパーフェクトなブランデッドデッキを即座に取得。',
1891
+ code: PROPOSAL_TEMPLATE_EXAMPLE,
1892
+ },
1893
+ {
1894
+ title: 'AIエージェントによるプレゼン自動作成',
1895
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="3"/><line x1="8" y1="16" x2="8" y2="16.01"/><line x1="16" y1="16" x2="16" y2="16.01"/></svg>',
1896
+ body: 'AIエージェントに会議メモ、リサーチサマリー、プロジェクト概要からプレゼンテーションデッキを作成させます。Skills またはMCP統合により、エージェントは html2pptx.app のHTML契約を理解し、準拠したスライドを生成してダウンロードリンクを提供。ユーザーは自然言語で欲しいものを説明するだけ。',
1897
+ code: null,
1898
+ },
1899
+ {
1900
+ title: 'SaaSアプリへのPPTXエクスポート機能追加',
1901
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>',
1902
+ body: 'SaaS製品に「PowerPointにエクスポート」機能を追加。ダッシュボード、分析ビュー、レポートをスライドHTMLとしてレンダリングし、バックエンドから html2pptx.app API を呼び出します。ユーザーはフラットなスクリーンショットではなく、編集可能なテキストとシェイプを含むネイティブPPTXファイルを取得。',
1903
+ code: SAAS_EMBED_EXAMPLE,
1904
+ },
1905
+ ],
1906
+
1907
+ /* --- Section 8: プラン・料金 --- */
1908
+ plansTitle: 'プラン・料金',
1909
+ plansDescription: '利用状況に合ったプランを選択してください。現在の公開カタログはコードで定義されており、requests per minute、日次ガードレール、最大スライド数、concurrentJobs、API キー数、payload サイズがプランごとに異なります。',
1910
+ plansTable: [
1911
+ { plan: 'Free Preview', exports: '日100件 / 3 rpm', slides: '50枚/ジョブ', support: 'コミュニティ', price: '0円' },
1912
+ { plan: 'Founder Beta', exports: '日300件 / 5 rpm', slides: '100枚/ジョブ', support: 'セルフサービス', price: '980円/月' },
1913
+ { plan: 'Starter', exports: '日1,000件 / 15 rpm', slides: '200枚/ジョブ', support: 'メール', price: '2,980円/月' },
1914
+ { plan: 'Business', exports: '日5,000件 / 60 rpm', slides: '300枚/ジョブ', support: '優先', price: '9,800円/月' },
1915
+ { plan: 'Enterprise / OEM', exports: '個別設計', slides: '500枚+/ジョブ', support: '専任', price: '49,800円/月〜' },
1916
+ ],
1917
+ plansUpgradeNote: 'ダッシュボードからいつでもアップグレード可能。変更は即時反映され、日割り請求となります。ダウングレードは現在の請求期間終了時に適用。',
1918
+
1919
+ plansRateLimitsTitle: 'プラン別レート制限・クォータ',
1920
+ plansRateLimitsDescription: '各プランには以下の制限が適用されます。全チャネル(REST API、Skills、MCP)で共通のクォータです。',
1921
+ plansRateLimits: [
1922
+ {
1923
+ plan: 'Free Preview',
1924
+ rpm: '3回/分',
1925
+ daily: '100回/日',
1926
+ monthly: '無制限*',
1927
+ slidesPerJob: '50枚',
1928
+ concurrent: '1ジョブ',
1929
+ apiKeys: '1個',
1930
+ payload: '1 MB',
1931
+ fairUse: '月1,000回でレビュー、月2,000回でアップグレード提案',
1932
+ },
1933
+ {
1934
+ plan: 'Founder Beta',
1935
+ rpm: '5回/分',
1936
+ daily: '300回/日',
1937
+ monthly: '無制限*',
1938
+ slidesPerJob: '100枚',
1939
+ concurrent: '2ジョブ',
1940
+ apiKeys: '3個',
1941
+ payload: '2 MB',
1942
+ fairUse: '月3,000回でレビュー、月5,000回でアップグレード提案',
1943
+ },
1944
+ {
1945
+ plan: 'Starter',
1946
+ rpm: '15回/分',
1947
+ daily: '1,000回/日',
1948
+ monthly: '無制限*',
1949
+ slidesPerJob: '200枚',
1950
+ concurrent: '5ジョブ',
1951
+ apiKeys: '10個',
1952
+ payload: '5 MB',
1953
+ fairUse: '月10,000回でレビュー、月20,000回でアップグレード提案',
1954
+ },
1955
+ {
1956
+ plan: 'Business',
1957
+ rpm: '60回/分',
1958
+ daily: '5,000回/日',
1959
+ monthly: '無制限*',
1960
+ slidesPerJob: '300枚',
1961
+ concurrent: '20ジョブ',
1962
+ apiKeys: '50個',
1963
+ payload: '10 MB',
1964
+ fairUse: '月50,000回でレビュー、月100,000回でアップグレード提案',
1965
+ },
1966
+ {
1967
+ plan: 'Enterprise / OEM',
1968
+ rpm: '120回/分',
1969
+ daily: '個別設計',
1970
+ monthly: '個別設計',
1971
+ slidesPerJob: '500枚',
1972
+ concurrent: '50ジョブ',
1973
+ apiKeys: '100個',
1974
+ payload: '25 MB',
1975
+ fairUse: '個別契約',
1976
+ },
1977
+ ],
1978
+ plansRateLimitsNote: '* 無制限 = 公平利用ポリシーの範囲内です。MCPプロトコルのリクエストはプランRPMの3倍でレート制限されます(initialize、tools/list等のプロトコルオーバーヘッド分)。',
1979
+
1980
+ /* --- Section 9: セキュリティ --- */
1981
+ securityTitle: 'セキュリティ・制限',
1982
+ securityLead: '公開 API、Skills、MCP、Studio、Hosted Web Export は、同じ変換パイプラインの上にあります。実際に重要なのは、認証、ジョブ所有権、SVG 方針、ワーカー隔離、サーバー側制限の理解です。',
1983
+ securityLayers: [
1984
+ {
1985
+ title: '認証と認可',
1986
+ body: 'REST API は API キー、remote MCP は商用 API キーまたは WorkOS 認証済みセッションを利用します。ジョブ参照は、そのジョブを作成した API キーまたは principal に紐付きます。',
1987
+ },
1988
+ {
1989
+ title: 'SVG と未信頼マークアップ',
1990
+ body: '公開 API と MCP は受信HTMLをサニタイズし、インライン SVG を安全に処理します。SVG は高品質な PNG 画像に変換されます。',
1991
+ },
1992
+ {
1993
+ title: 'ワーカー隔離',
1994
+ body: 'プライベートワーカーは分離ブラウザコンテキストでレンダリングし、任意の外部ネットワーク要求を遮断し、リクエストボディ上限と job TTL を適用します。',
1995
+ },
1996
+ {
1997
+ title: '利用制御',
1998
+ body: '1分あたりのリクエスト数、日次ガードレール、月次の公平利用レビュー閾値、1ジョブあたりの最大スライド数、最大 payload サイズ、同時実行数はすべてサーバー側で強制されます。',
1999
+ },
2000
+ ],
2001
+ securityChecklistTitle: '本番運用での推奨事項',
2002
+ securityChecklist: [
2003
+ 'API キーはシークレットとして扱い、露出時はダッシュボードからローテーションしてください。',
2004
+ 'バックエンド自動化には REST API を使い、Hosted Web Export はファーストパーティのブラウザ用サーフェスとして扱ってください。',
2005
+ 'status ポーリングは 2 秒程度の間隔とバックオフを前提にしてください。',
2006
+ 'スライドHTMLは明示サイズ、決定的な CSS、ランタイム依存の少ない構造にしてください。1600x900 はデフォルト例です。',
2007
+ 'fileBase64 は大きくなる場合があります。保存側はバイナリ安全なコードパスで処理してください。',
2008
+ 'エージェント連携では、ローカル stdio MCP と remote /mcp のどちらを使うかを事前に決めてください。',
2009
+ ],
2010
+
2011
+ /* --- Section 10: FAQ --- */
2012
+ faqTitle: 'FAQ',
2013
+ faqItems: [
2014
+ {
2015
+ question: '他社のHTML-to-PPTXソリューションとの違いは?',
2016
+ answer: 'ほとんどの代替サービスはHTMLのスクリーンショットを撮り、各スライドにフラット画像として埋め込みます。html2pptx.app はネイティブシェイプ変換を行います -- CSSを解析し、flexbox、グラデーション、border-radius、シャドウなどのプロパティをネイティブPPTX Officeシェイプにマッピングします。結果は完全に編集可能なテキスト、スケーラブルなベクターグラフィックス、小さいファイルサイズです。',
2017
+ },
2018
+ {
2019
+ question: 'どんなHTMLでもPPTXに変換できますか?',
2020
+ answer: '安定した変換は保証されません。html2pptx.app は .slide クラス要素と明示サイズを持つスライド指向のHTMLに最適化されています。1600x900 はデフォルト例ですが、縦長やカスタムサイズにも対応しています。任意のWebページ、インタラクティブアプリ、スクロールベースのレイアウト、JavaScript依存のレンダリングを持つページは非対応です。HTML契約セクションに正確な要件が記載されています。',
2021
+ },
2022
+ {
2023
+ question: '何が1枚のスライドになりますか?',
2024
+ answer: '.slide クラスを持つ各要素が出力PPTXの1スライドになります。HTMLに class="slide" を持つ要素が5つあれば、出力は5スライドになります。予測可能な結果のために、明確なスライド境界を定義してください。',
2025
+ },
2026
+ {
2027
+ question: 'エクスポート後のコンテンツはPowerPointで編集可能ですか?',
2028
+ answer: 'はい、ほとんどの場合。テキストは編集可能なテキストボックスに変換され、シンプルな図形もPowerPoint上で編集できます。インラインSVGは高品質なPNG画像に変換されます。',
2029
+ },
2030
+ {
2031
+ question: 'エクスポートにはどのくらい時間がかかりますか?',
2032
+ answer: '単一スライドのジョブは通常3-5秒で完了します。マルチスライドデッキ(10-50スライド)は、複雑さ、画像数、フォント埋め込みに応じて8-20秒かかります。ワーカーは可能な場合スライドを並列処理します。最適なレスポンシブ性のため、ジョブステータスエンドポイントを2秒間隔でポーリングしてください。',
2033
+ },
2034
+ {
2035
+ question: 'どのフォントに対応していますか?',
2036
+ answer: 'システムフォント(Arial、Helvetica、Times New Romanなど)はデフォルトで動作します。Webフォントの場合、autoEmbedFonts: true を有効にしてください -- html2pptx.app がGoogle Fontsやカスタム@font-face URLからフォントファイルをダウンロードしてPPTXに埋め込みます。Noto Sans JP、游ゴシック、メイリオ、ヒラギノなどの日本語フォントにも完全対応しています。',
2037
+ },
2038
+ {
2039
+ question: '無料プランはありますか?',
2040
+ answer: 'はい。現在の公開カタログには Early Access ティアがあり、制限付きで API / Skills / MCP を利用できます。正確な上限はコードと GET /api/export/plans のレスポンスが正です。',
2041
+ },
2042
+ {
2043
+ question: 'スライドでSVGは使えますか?',
2044
+ answer: 'はい。インラインSVGに対応しています。公開APIでは安全のためPNG画像に変換されます。',
2045
+ },
2046
+ {
2047
+ question: '最大ファイルサイズは?',
2048
+ answer: 'HTMLペイロードは5MB以下を推奨。生成されるPPTXファイルはコンテンツにより異なりますが、通常100KB〜10MBの範囲です。多数の高解像度画像をbase64で埋め込んだジョブはファイルサイズが大きくなります。大きな画像にはURL参照の使用を検討してください。',
2049
+ },
2050
+ {
2051
+ question: 'セキュリティ対策は?',
2052
+ answer: '複数の防御を実装しています。ワーカーの外部要求遮断、ジョブ所有者バインディング、APIキーのハッシュ保存、リクエストボディ上限、同時実行数制限、公開SVGのサニタイズとPNG化などです。バックエンド自動化では Hosted Web Export ではなく REST API を使うのが推奨です。',
2053
+ },
2054
+ {
2055
+ question: '日本語テキストやCJK文字に対応していますか?',
2056
+ answer: 'はい、完全対応しています。日本語、中国語、韓国語の文字は正しくレンダリングされます。最良の結果のためには、CSSでCJKフォントを指定し(例: font-family: "Noto Sans JP", sans-serif)、autoEmbedFontsを有効にしてフォントがインストールされていないマシンでもポータブルなレンダリングを確保してください。',
2057
+ },
2058
+ {
2059
+ question: 'エラーの対処方法は?',
2060
+ answer: 'ジョブステータスエンドポイントを確認してください。statusが "failed" の場合、errorフィールドに人間が読める説明が含まれます。すべてのAPIエラーはRFC 9457 Problem Details形式に準拠し、type、status、title、detail、instanceフィールドに加え、後方互換のためのerrorとmessageフィールドも返します。一般的な問題: .slide要素の欠落 (400)、期限切れAPIキー (401)、レート制限超過 (429)、コンテンツの超過サイズ (413)。',
2061
+ },
2062
+ {
2063
+ question: 'CSS Gridで複雑なスライドレイアウトは作れますか?',
2064
+ answer: 'はい。CSS Gridは grid-template-columns、grid-template-rows、gap、グリッド配置プロパティを含め完全に対応しています。マルチカラムレイアウト、ダッシュボードスタイルのカード、複雑なビジュアル配置を簡単に作成でき、PPTXにクリーンに変換されます。',
2065
+ },
2066
+ {
2067
+ question: 'ジョブ完了のWebhookはありますか?',
2068
+ answer: 'はい。POST /api/export/jobs のリクエストボディに callbackUrl フィールド(HTTPSのみ)を追加してください。ジョブ完了または失敗時に、ワーカーがコールバックURLにジョブ結果全体をPOSTします(x-signature-sha256 HMACヘッダー付き)。あるいは従来通り GET /api/export/jobs/{jobId} を2秒間隔でポーリングすることも可能です。MCPユーザーの場合、html2pptx_wait_for_export_job がポーリングを自動処理します。',
2069
+ },
2070
+ ],
2071
+ faqTroubleshootTitle: 'トラブルシューティング',
2072
+ faqTroubleshootItems: [
2073
+ { issue: 'ジョブが "queued" ステータスのまま', solution: 'プライベートワーカーがオフラインまたは過負荷の可能性があります。30秒待ってリトライしてください。続く場合はダッシュボードからワーカーの状態を確認するか、サポートにお問い合わせください。' },
2074
+ { issue: 'スライドが空白で表示される', solution: 'HTMLに class="slide" を持つ要素が含まれ、それらの要素に可視コンテンツがあることを確認。CSSがペイロードに含まれ、外部スタイルシートに依存していないかも確認。' },
2075
+ { issue: 'PPTXでフォントが異なる', solution: 'autoEmbedFonts: true を有効にしてWebフォントを埋め込み。カスタムフォント使用時は@font-face URLが公開アクセス可能であることを確認。最大の互換性にはArial、Noto Sansなどのシステムセーフフォントを使用。' },
2076
+ { issue: '429レート制限エラー', solution: 'X-RateLimit-Resetヘッダーでウィンドウリセット時刻を確認。ポーリングロジックに指数バックオフを実装。より高いリクエスト制限にはプランのアップグレードを検討。' },
2077
+ { issue: 'レイアウトがブラウザプレビューと異なる', solution: '.slide要素にはインラインスタイルで明示サイズを指定してください。1600x900 はデフォルト例ですが、width / height / layout と一致するカスタム比率でも問題ありません。レスポンシブ/パーセントベースのレイアウト、メディアクエリ、ビューポート相対単位(vh、vw)は避けてください。' },
2078
+ { issue: '画像がPPTXに表示されない', solution: '画像には絶対URL(https://...)またはbase64データURIを使用。相対パスやlocalhostのURLは失敗します。画像URLがワーカーから公開アクセス可能であることを確認。' },
2079
+ { issue: 'PPTXファイルサイズが大きすぎる', solution: '大きなファイルは通常、埋め込みbase64画像や画像の多いコンテンツが原因。代わりにURL参照を使用するか、埋め込み前に画像を圧縮してください。' },
2080
+ ],
2081
+ },
2082
+ };