html2pptx-local-mcp 1.1.37 → 1.1.38
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.
package/app/docs/content.js
CHANGED
|
@@ -170,17 +170,20 @@ const SKILL_INSTALL_COMMAND_EN = `# Choose the command for your agent
|
|
|
170
170
|
# Claude Code
|
|
171
171
|
npx skills add https://html2pptx.app -a claude-code
|
|
172
172
|
|
|
173
|
+
# Grok Build
|
|
174
|
+
npx --yes --package html2pptx-local-mcp@latest html2pptx-install-skills grok
|
|
175
|
+
|
|
173
176
|
# Codex
|
|
174
177
|
npx skills add https://html2pptx.app -a codex
|
|
175
178
|
|
|
176
179
|
# Cursor
|
|
177
180
|
npx skills add https://html2pptx.app -a cursor
|
|
178
181
|
|
|
179
|
-
#
|
|
180
|
-
npx skills add https://html2pptx.app -a
|
|
182
|
+
# VS Code (GitHub Copilot)
|
|
183
|
+
npx skills add https://html2pptx.app -a github-copilot
|
|
181
184
|
|
|
182
|
-
#
|
|
183
|
-
npx
|
|
185
|
+
# Antigravity
|
|
186
|
+
npx skills add https://html2pptx.app -a antigravity
|
|
184
187
|
|
|
185
188
|
# Preview published skills without installing
|
|
186
189
|
npx skills add https://html2pptx.app --list
|
|
@@ -197,17 +200,20 @@ const SKILL_INSTALL_COMMAND_JA = `# 使うエージェントのコマンドを
|
|
|
197
200
|
# Claude Code
|
|
198
201
|
npx skills add https://html2pptx.app -a claude-code
|
|
199
202
|
|
|
203
|
+
# Grok Build
|
|
204
|
+
npx --yes --package html2pptx-local-mcp@latest html2pptx-install-skills grok
|
|
205
|
+
|
|
200
206
|
# Codex
|
|
201
207
|
npx skills add https://html2pptx.app -a codex
|
|
202
208
|
|
|
203
209
|
# Cursor
|
|
204
210
|
npx skills add https://html2pptx.app -a cursor
|
|
205
211
|
|
|
206
|
-
#
|
|
207
|
-
npx skills add https://html2pptx.app -a
|
|
212
|
+
# VS Code (GitHub Copilot)
|
|
213
|
+
npx skills add https://html2pptx.app -a github-copilot
|
|
208
214
|
|
|
209
|
-
#
|
|
210
|
-
npx
|
|
215
|
+
# Antigravity
|
|
216
|
+
npx skills add https://html2pptx.app -a antigravity
|
|
211
217
|
|
|
212
218
|
# インストールせずに公開Skillを確認
|
|
213
219
|
npx skills add https://html2pptx.app --list
|
|
@@ -432,44 +438,54 @@ export const DOCS_COPY = {
|
|
|
432
438
|
'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.',
|
|
433
439
|
|
|
434
440
|
navSections: [
|
|
435
|
-
{ id: 'overview', label: 'Service Overview', children: [
|
|
441
|
+
{ id: 'overview', label: 'Service Overview', desc: 'What html2pptx is, architecture, channels, comparison, and CSS support.', children: [
|
|
436
442
|
{ id: 'overview-channels', label: 'Channels' },
|
|
437
443
|
{ id: 'overview-comparison', label: 'Comparison' },
|
|
438
444
|
{ id: 'overview-css', label: 'CSS Support' },
|
|
439
445
|
]},
|
|
440
|
-
{ id: 'quickstart', label: 'Quick Start' },
|
|
441
|
-
{ id: 'api-reference', label: 'API Reference', children: [
|
|
446
|
+
{ id: 'quickstart', label: 'Quick Start', desc: 'Your first authenticated HTML-to-PPTX export in four steps.' },
|
|
447
|
+
{ id: 'api-reference', label: 'API Reference', desc: 'REST endpoints, supported and forbidden HTML elements, and response headers.', children: [
|
|
442
448
|
{ id: 'api-html-elements', label: 'HTML Elements' },
|
|
443
449
|
{ id: 'api-html-forbidden', label: 'Forbidden' },
|
|
444
450
|
]},
|
|
445
|
-
{ id: 'skills', label: 'Skills Integration', children: [
|
|
451
|
+
{ id: 'skills', label: 'Skills Integration', desc: 'Use the html2pptx skill inside Claude Code and Codex agents.', children: [
|
|
446
452
|
{ id: 'skills-setup', label: 'Setup' },
|
|
447
453
|
{ id: 'skills-local-editor', label: 'Local Visual Editor' },
|
|
448
454
|
{ id: 'skills-capabilities', label: 'Capabilities' },
|
|
449
455
|
]},
|
|
450
|
-
{ id: 'mcp', label: 'MCP Integration', children: [
|
|
456
|
+
{ id: 'mcp', label: 'MCP Integration', desc: 'Connect AI agents via the Model Context Protocol — remote and local.', children: [
|
|
451
457
|
{ id: 'mcp-setup', label: 'Setup' },
|
|
452
458
|
{ id: 'mcp-auth', label: 'Authentication' },
|
|
453
459
|
{ id: 'mcp-tools', label: 'Tools' },
|
|
454
460
|
{ id: 'mcp-example', label: 'Example' },
|
|
455
461
|
]},
|
|
456
|
-
{ id: 'cli', label: 'CLI Tool', children: [
|
|
462
|
+
{ id: 'cli', label: 'CLI Tool', desc: 'Install and run the command-line tool for exports.', children: [
|
|
457
463
|
{ id: 'cli-install', label: 'Installation' },
|
|
458
464
|
{ id: 'cli-commands', label: 'Commands' },
|
|
459
465
|
{ id: 'cli-examples', label: 'Examples' },
|
|
460
466
|
]},
|
|
461
|
-
{ id: 'use-cases', label: 'Use Cases' },
|
|
462
|
-
{ id: 'plans', label: 'Plans & Pricing', children: [
|
|
467
|
+
{ id: 'use-cases', label: 'Use Cases', desc: 'Common ways teams use html2pptx in production.' },
|
|
468
|
+
{ id: 'plans', label: 'Plans & Pricing', desc: 'Subscription tiers, pricing, and per-plan rate limits.', children: [
|
|
463
469
|
{ id: 'plans-rate-limits', label: 'Rate Limits' },
|
|
464
470
|
]},
|
|
465
|
-
{ id: 'security', label: 'Security & Limits', children: [
|
|
471
|
+
{ id: 'security', label: 'Security & Limits', desc: 'Security model, limits, and the pre-publish checklist.', children: [
|
|
466
472
|
{ id: 'security-checklist', label: 'Checklist' },
|
|
467
473
|
]},
|
|
468
|
-
{ id: 'faq', label: 'FAQ', children: [
|
|
474
|
+
{ id: 'faq', label: 'FAQ', desc: 'Frequently asked questions and troubleshooting.', children: [
|
|
469
475
|
{ id: 'faq-troubleshoot', label: 'Troubleshoot' },
|
|
470
476
|
]},
|
|
471
477
|
],
|
|
472
478
|
|
|
479
|
+
searchCopy: {
|
|
480
|
+
rootCrumb: 'Docs',
|
|
481
|
+
buttonLabel: 'Search docs…',
|
|
482
|
+
placeholder: 'Search documentation…',
|
|
483
|
+
noResults: 'No results found',
|
|
484
|
+
hintNavigate: 'navigate',
|
|
485
|
+
hintSelect: 'select',
|
|
486
|
+
hintClose: 'close',
|
|
487
|
+
},
|
|
488
|
+
|
|
473
489
|
/* --- Section 1: Service Overview --- */
|
|
474
490
|
overviewTitle: 'Service Overview',
|
|
475
491
|
overviewSubtitle: 'What is html2pptx.app',
|
|
@@ -842,7 +858,7 @@ html2pptx edit ./html2pptx/slides.html --no-open`,
|
|
|
842
858
|
{ 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.' },
|
|
843
859
|
],
|
|
844
860
|
skillsSetupTitle: 'Setup',
|
|
845
|
-
skillsSetupLead: 'Pick the agent you actually use and run the matching command. The skills CLI handles Claude Code, Codex, Cursor, and
|
|
861
|
+
skillsSetupLead: 'Pick the agent you actually use and run the matching command. The skills CLI handles Claude Code, Codex, Cursor, VS Code (GitHub Copilot), and Antigravity; Grok Build uses its own installer. The tab list mirrors the MCP setup tabs below so the same agent appears in the same place in both sections.',
|
|
846
862
|
skillsEditorTabs: [
|
|
847
863
|
{
|
|
848
864
|
id: 'claude-code',
|
|
@@ -881,28 +897,30 @@ html2pptx edit ./html2pptx/slides.html --no-open`,
|
|
|
881
897
|
],
|
|
882
898
|
},
|
|
883
899
|
{
|
|
884
|
-
id: '
|
|
885
|
-
label: '
|
|
886
|
-
icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/
|
|
900
|
+
id: 'vscode',
|
|
901
|
+
label: 'VS Code',
|
|
902
|
+
icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/visual-studio-code/default.svg',
|
|
887
903
|
steps: [
|
|
888
|
-
{ title: 'Install the html2pptx skill', body: 'Register the published html2pptx skills into
|
|
904
|
+
{ title: 'Install the html2pptx skill', body: 'Register the published html2pptx skills into VS Code (GitHub Copilot) via the skills CLI. Skills land under `~/.copilot/skills/`.', code: `npx skills add https://html2pptx.app -a github-copilot` },
|
|
889
905
|
],
|
|
906
|
+
tip: 'The skills CLI agent ID is `github-copilot`; the GitHub Copilot extension inside VS Code picks the skill up after a reload.',
|
|
890
907
|
},
|
|
891
908
|
{
|
|
892
|
-
id: '
|
|
893
|
-
label: '
|
|
909
|
+
id: 'antigravity',
|
|
910
|
+
label: 'Antigravity',
|
|
911
|
+
icon: 'https://cdn.jsdelivr.net/npm/@lobehub/icons-static-svg/icons/antigravity-color.svg',
|
|
894
912
|
steps: [
|
|
895
|
-
{ title: '
|
|
913
|
+
{ title: 'Install the html2pptx skill', body: 'Register the published html2pptx skills into Antigravity via the skills CLI. Skills land under `~/.gemini/antigravity/skills/`.', code: `npx skills add https://html2pptx.app -a antigravity` },
|
|
896
914
|
],
|
|
897
|
-
tip: '
|
|
915
|
+
tip: 'Antigravity (Google) shares the same skills CLI flow as Claude Code — restart Antigravity after installing so the IDE picks up the new skill.',
|
|
898
916
|
},
|
|
899
917
|
],
|
|
900
918
|
skillsSetupSteps: [
|
|
901
919
|
{
|
|
902
920
|
step: '1',
|
|
903
921
|
title: 'Install MCP + Skill',
|
|
904
|
-
icons: ['claude-code', 'codex', 'cursor'],
|
|
905
|
-
body: '
|
|
922
|
+
icons: ['claude-code', 'grok-build', 'codex', 'cursor', 'vscode', 'antigravity'],
|
|
923
|
+
body: 'Pick the command for the agent you actually use: Claude Code, Codex, Cursor, VS Code (GitHub Copilot), or Antigravity. For Grok Build, use the Grok-specific installer. For other supported agents or multiple targets, drop the `-a` flag and use the interactive selector. Avoid `--yes` unless you intentionally want to install into every detected agent directory.',
|
|
906
924
|
code: SKILL_INSTALL_COMMAND_EN,
|
|
907
925
|
},
|
|
908
926
|
{
|
|
@@ -1359,44 +1377,54 @@ echo 'HTML2PPTX_API_KEY=sk_live_xxxx' >> .env`,
|
|
|
1359
1377
|
'html2pptx.app の包括的なドキュメント。HTML/CSSを完全に編集可能なPowerPointファイルに変換する唯一のAPI。REST API、Skills統合、MCPプロトコル、クイックスタートガイド、HTML変換契約を網羅しています。',
|
|
1360
1378
|
|
|
1361
1379
|
navSections: [
|
|
1362
|
-
{ id: 'overview', label: 'サービス概要', children: [
|
|
1380
|
+
{ id: 'overview', label: 'サービス概要', desc: 'html2pptxの概要・アーキテクチャ・チャネル・比較・CSS対応。', children: [
|
|
1363
1381
|
{ id: 'overview-channels', label: 'チャネル' },
|
|
1364
1382
|
{ id: 'overview-comparison', label: '比較' },
|
|
1365
1383
|
{ id: 'overview-css', label: 'CSS対応' },
|
|
1366
1384
|
]},
|
|
1367
|
-
{ id: 'quickstart', label: 'クイックスタート' },
|
|
1368
|
-
{ id: 'api-reference', label: 'APIリファレンス', children: [
|
|
1385
|
+
{ id: 'quickstart', label: 'クイックスタート', desc: '認証付きでHTMLをPPTXに変換する最初の4ステップ。' },
|
|
1386
|
+
{ id: 'api-reference', label: 'APIリファレンス', desc: 'RESTエンドポイント、対応/禁止HTML要素、レスポンスヘッダー。', children: [
|
|
1369
1387
|
{ id: 'api-html-elements', label: '対応HTML要素' },
|
|
1370
1388
|
{ id: 'api-html-forbidden', label: '使用禁止要素' },
|
|
1371
1389
|
]},
|
|
1372
|
-
{ id: 'skills', label: 'Skills統合', children: [
|
|
1390
|
+
{ id: 'skills', label: 'Skills統合', desc: 'Claude Code や Codex エージェントで html2pptx skill を使う。', children: [
|
|
1373
1391
|
{ id: 'skills-setup', label: 'セットアップ' },
|
|
1374
1392
|
{ id: 'skills-local-editor', label: 'ローカル編集' },
|
|
1375
1393
|
{ id: 'skills-capabilities', label: '機能一覧' },
|
|
1376
1394
|
]},
|
|
1377
|
-
{ id: 'mcp', label: 'MCP統合', children: [
|
|
1395
|
+
{ id: 'mcp', label: 'MCP統合', desc: 'Model Context Protocol でAIエージェントと連携(リモート/ローカル)。', children: [
|
|
1378
1396
|
{ id: 'mcp-setup', label: 'セットアップ' },
|
|
1379
1397
|
{ id: 'mcp-auth', label: '認証方法' },
|
|
1380
1398
|
{ id: 'mcp-tools', label: 'ツール一覧' },
|
|
1381
1399
|
{ id: 'mcp-example', label: '使用例' },
|
|
1382
1400
|
]},
|
|
1383
|
-
{ id: 'cli', label: 'CLIツール', children: [
|
|
1401
|
+
{ id: 'cli', label: 'CLIツール', desc: 'エクスポート用のコマンドラインツールの導入と実行。', children: [
|
|
1384
1402
|
{ id: 'cli-install', label: 'インストール' },
|
|
1385
1403
|
{ id: 'cli-commands', label: 'コマンド' },
|
|
1386
1404
|
{ id: 'cli-examples', label: '使用例' },
|
|
1387
1405
|
]},
|
|
1388
|
-
{ id: 'use-cases', label: '活用事例' },
|
|
1389
|
-
{ id: 'plans', label: 'プラン・料金', children: [
|
|
1406
|
+
{ id: 'use-cases', label: '活用事例', desc: '本番環境での html2pptx の代表的な活用方法。' },
|
|
1407
|
+
{ id: 'plans', label: 'プラン・料金', desc: 'サブスクプラン、料金、プランごとのレート制限。', children: [
|
|
1390
1408
|
{ id: 'plans-rate-limits', label: 'レート制限' },
|
|
1391
1409
|
]},
|
|
1392
|
-
{ id: 'security', label: 'セキュリティ・制限', children: [
|
|
1410
|
+
{ id: 'security', label: 'セキュリティ・制限', desc: 'セキュリティモデル・制限・公開前チェックリスト。', children: [
|
|
1393
1411
|
{ id: 'security-checklist', label: 'チェックリスト' },
|
|
1394
1412
|
]},
|
|
1395
|
-
{ id: 'faq', label: 'FAQ', children: [
|
|
1413
|
+
{ id: 'faq', label: 'FAQ', desc: 'よくある質問とトラブルシューティング。', children: [
|
|
1396
1414
|
{ id: 'faq-troubleshoot', label: 'トラブルシュート' },
|
|
1397
1415
|
]},
|
|
1398
1416
|
],
|
|
1399
1417
|
|
|
1418
|
+
searchCopy: {
|
|
1419
|
+
rootCrumb: 'ドキュメント',
|
|
1420
|
+
buttonLabel: 'ドキュメントを検索…',
|
|
1421
|
+
placeholder: 'ドキュメントを検索…',
|
|
1422
|
+
noResults: '結果が見つかりません',
|
|
1423
|
+
hintNavigate: '移動',
|
|
1424
|
+
hintSelect: '選択',
|
|
1425
|
+
hintClose: '閉じる',
|
|
1426
|
+
},
|
|
1427
|
+
|
|
1400
1428
|
/* --- Section 1: サービス概要 --- */
|
|
1401
1429
|
overviewTitle: 'サービス概要',
|
|
1402
1430
|
overviewSubtitle: 'html2pptx.app とは',
|
|
@@ -1768,7 +1796,7 @@ html2pptx edit ./html2pptx/slides.html --no-open`,
|
|
|
1768
1796
|
{ issue: '別タブが読み取り専用になる', fix: '同じHTMLを複数タブで編集して競合しないよう、エディタはタブロックを使います。編集権限のあるタブを使うか、画面上の移譲操作を行ってください。' },
|
|
1769
1797
|
],
|
|
1770
1798
|
skillsSetupTitle: 'セットアップ',
|
|
1771
|
-
skillsSetupLead: '実際に使うエージェントのタブを開き、そのコマンドだけ実行してください。skills CLI は Claude Code / Codex / Cursor /
|
|
1799
|
+
skillsSetupLead: '実際に使うエージェントのタブを開き、そのコマンドだけ実行してください。skills CLI は Claude Code / Codex / Cursor / VS Code (GitHub Copilot) / Antigravity に対応し、Grok Build のみ Grok 専用 installer を使います。タブの並びは下の MCP セットアップと同じ順序にしてあるので、同じエージェントは両セクションの同じ位置にあります。',
|
|
1772
1800
|
skillsEditorTabs: [
|
|
1773
1801
|
{
|
|
1774
1802
|
id: 'claude-code',
|
|
@@ -1807,28 +1835,30 @@ html2pptx edit ./html2pptx/slides.html --no-open`,
|
|
|
1807
1835
|
],
|
|
1808
1836
|
},
|
|
1809
1837
|
{
|
|
1810
|
-
id: '
|
|
1811
|
-
label: '
|
|
1812
|
-
icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/
|
|
1838
|
+
id: 'vscode',
|
|
1839
|
+
label: 'VS Code',
|
|
1840
|
+
icon: 'https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/visual-studio-code/default.svg',
|
|
1813
1841
|
steps: [
|
|
1814
|
-
{ title: 'html2pptx Skill をインストール', body: '公開済みの html2pptx skills を skills CLI から
|
|
1842
|
+
{ title: 'html2pptx Skill をインストール', body: '公開済みの html2pptx skills を skills CLI から VS Code (GitHub Copilot) に登録します。skills は `~/.copilot/skills/` に配置されます。', code: `npx skills add https://html2pptx.app -a github-copilot` },
|
|
1815
1843
|
],
|
|
1844
|
+
tip: 'skills CLI でのエージェント ID は `github-copilot` です。インストール後、VS Code の GitHub Copilot 拡張を再読み込みすると skill が認識されます。',
|
|
1816
1845
|
},
|
|
1817
1846
|
{
|
|
1818
|
-
id: '
|
|
1819
|
-
label: '
|
|
1847
|
+
id: 'antigravity',
|
|
1848
|
+
label: 'Antigravity',
|
|
1849
|
+
icon: 'https://cdn.jsdelivr.net/npm/@lobehub/icons-static-svg/icons/antigravity-color.svg',
|
|
1820
1850
|
steps: [
|
|
1821
|
-
{ title: '
|
|
1851
|
+
{ title: 'html2pptx Skill をインストール', body: '公開済みの html2pptx skills を skills CLI から Antigravity に登録します。skills は `~/.gemini/antigravity/skills/` に配置されます。', code: `npx skills add https://html2pptx.app -a antigravity` },
|
|
1822
1852
|
],
|
|
1823
|
-
tip: '
|
|
1853
|
+
tip: 'Antigravity (Google) は Claude Code と同じく skills CLI でそのまま導入できます。インストール後に Antigravity を再起動すると skill が読み込まれます。',
|
|
1824
1854
|
},
|
|
1825
1855
|
],
|
|
1826
1856
|
skillsSetupSteps: [
|
|
1827
1857
|
{
|
|
1828
1858
|
step: '1',
|
|
1829
1859
|
title: 'MCP + スキルをインストール',
|
|
1830
|
-
icons: ['claude-code', 'codex', 'cursor'],
|
|
1831
|
-
body: 'Claude Code
|
|
1860
|
+
icons: ['claude-code', 'grok-build', 'codex', 'cursor', 'vscode', 'antigravity'],
|
|
1861
|
+
body: 'Claude Code / Codex / Cursor / VS Code (GitHub Copilot) / Antigravity のうち、実際に使うエージェントのコマンドを選んで実行してください。Grok Build のみ Grok 専用 installer を使います。その他の対応エージェントや複数指定の場合は `-a` を付けずに対話形式で選択します。`--yes` は検出された全エージェントのディレクトリへ入るため、全対応が必要な場合以外は使わないでください。',
|
|
1832
1862
|
code: SKILL_INSTALL_COMMAND_JA,
|
|
1833
1863
|
},
|
|
1834
1864
|
{
|
|
@@ -18,7 +18,7 @@ declare function normalizeBaseUrl(raw: string): URL;
|
|
|
18
18
|
declare function readRegisteredEditorBaseUrl(root: string): Promise<string | null>;
|
|
19
19
|
declare function resolveEditorBaseUrl(root: string, explicitBaseUrl: string | undefined): Promise<URL>;
|
|
20
20
|
declare function buildEditorUrl(baseUrl: URL, rel: string, bridgeUrl: string, sessionToken: string): URL;
|
|
21
|
-
declare function createBridgeServer(ctx: BridgeContext): import("http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
21
|
+
declare function createBridgeServer(ctx: BridgeContext): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
22
22
|
declare function listen(server: ReturnType<typeof createBridgeServer>, requestedPort: number): Promise<number>;
|
|
23
23
|
export declare function editCommand(input: string | undefined, options?: EditOptions): Promise<void>;
|
|
24
24
|
export declare const editCommandInternalsForTest: {
|
|
@@ -8,11 +8,13 @@ import * as p from "@clack/prompts";
|
|
|
8
8
|
import pc from "picocolors";
|
|
9
9
|
const AUTO_PORT = 0;
|
|
10
10
|
const MAX_WRITE_BYTES = 5 * 1024 * 1024;
|
|
11
|
-
const MAX_ASSET_BYTES =
|
|
11
|
+
const MAX_ASSET_BYTES = 64 * 1024 * 1024;
|
|
12
12
|
const ALLOWED_EXTENSIONS = [".html", ".htm"];
|
|
13
13
|
const ALLOWED_EXT = new Set(ALLOWED_EXTENSIONS);
|
|
14
14
|
const ASSET_IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".avif"];
|
|
15
|
-
const
|
|
15
|
+
const ASSET_VIDEO_EXTENSIONS = [".mp4", ".webm", ".mov", ".m4v", ".ogv"];
|
|
16
|
+
const ASSET_VIDEO_EXT = new Set(ASSET_VIDEO_EXTENSIONS);
|
|
17
|
+
const ASSET_MEDIA_EXT = new Set([...ASSET_IMAGE_EXTENSIONS, ...ASSET_VIDEO_EXTENSIONS]);
|
|
16
18
|
const ASSET_CONTENT_TYPES = {
|
|
17
19
|
".png": "image/png",
|
|
18
20
|
".jpg": "image/jpeg",
|
|
@@ -21,6 +23,11 @@ const ASSET_CONTENT_TYPES = {
|
|
|
21
23
|
".webp": "image/webp",
|
|
22
24
|
".svg": "image/svg+xml",
|
|
23
25
|
".avif": "image/avif",
|
|
26
|
+
".mp4": "video/mp4",
|
|
27
|
+
".webm": "video/webm",
|
|
28
|
+
".mov": "video/quicktime",
|
|
29
|
+
".m4v": "video/x-m4v",
|
|
30
|
+
".ogv": "video/ogg",
|
|
24
31
|
};
|
|
25
32
|
const ASSET_CONTENT_TYPE_EXT = {
|
|
26
33
|
"image/png": ".png",
|
|
@@ -29,6 +36,11 @@ const ASSET_CONTENT_TYPE_EXT = {
|
|
|
29
36
|
"image/webp": ".webp",
|
|
30
37
|
"image/svg+xml": ".svg",
|
|
31
38
|
"image/avif": ".avif",
|
|
39
|
+
"video/mp4": ".mp4",
|
|
40
|
+
"video/webm": ".webm",
|
|
41
|
+
"video/quicktime": ".mov",
|
|
42
|
+
"video/x-m4v": ".m4v",
|
|
43
|
+
"video/ogg": ".ogv",
|
|
32
44
|
};
|
|
33
45
|
const DISALLOWED_TOP_DIRECTORIES = [
|
|
34
46
|
"public",
|
|
@@ -460,8 +472,8 @@ async function safeAssetPath(ctx, rel) {
|
|
|
460
472
|
throw new Error("path escape");
|
|
461
473
|
}
|
|
462
474
|
const ext = extname(abs).toLowerCase();
|
|
463
|
-
if (!
|
|
464
|
-
throw new Error("only image files are allowed");
|
|
475
|
+
if (!ASSET_MEDIA_EXT.has(ext)) {
|
|
476
|
+
throw new Error("only image, GIF, and video files are allowed");
|
|
465
477
|
}
|
|
466
478
|
const real = await resolveReal(abs);
|
|
467
479
|
if (real !== ctx.root && !real.startsWith(ctx.root + sep)) {
|
|
@@ -477,18 +489,21 @@ async function safeAssetPath(ctx, rel) {
|
|
|
477
489
|
}
|
|
478
490
|
function assetExt(name, contentType) {
|
|
479
491
|
const fromName = extname(String(name || "")).toLowerCase();
|
|
480
|
-
if (
|
|
492
|
+
if (ASSET_MEDIA_EXT.has(fromName))
|
|
481
493
|
return fromName;
|
|
482
494
|
return ASSET_CONTENT_TYPE_EXT[String(contentType || "").toLowerCase()] || "";
|
|
483
495
|
}
|
|
484
496
|
function assetSlug(name) {
|
|
485
|
-
const base = String(name || "
|
|
497
|
+
const base = String(name || "asset").replace(/\.[^.]+$/, "");
|
|
486
498
|
const slug = base
|
|
487
499
|
.normalize("NFKD")
|
|
488
500
|
.replace(/[^\w.-]+/g, "-")
|
|
489
501
|
.replace(/^[-.]+|[-.]+$/g, "")
|
|
490
502
|
.toLowerCase();
|
|
491
|
-
return slug || "
|
|
503
|
+
return slug || "asset";
|
|
504
|
+
}
|
|
505
|
+
function assetKind(ext) {
|
|
506
|
+
return ASSET_VIDEO_EXT.has(ext) ? "video" : "image";
|
|
492
507
|
}
|
|
493
508
|
function assetDirRel(scope, htmlDirRel) {
|
|
494
509
|
if (scope === "global")
|
|
@@ -530,10 +545,11 @@ async function handleAssetGet(ctx, req, reqUrl, res) {
|
|
|
530
545
|
if (absDir === ctx.root || absDir.startsWith(ctx.root + sep)) {
|
|
531
546
|
const names = await readdir(absDir);
|
|
532
547
|
assets = names
|
|
533
|
-
.filter((name) =>
|
|
548
|
+
.filter((name) => ASSET_MEDIA_EXT.has(extname(name).toLowerCase()))
|
|
534
549
|
.map((name) => ({
|
|
535
550
|
name,
|
|
536
551
|
src: toPosixPath(relative(htmlDirAbs, join(absDir, name))),
|
|
552
|
+
kind: assetKind(extname(name).toLowerCase()),
|
|
537
553
|
}));
|
|
538
554
|
}
|
|
539
555
|
}
|
|
@@ -576,21 +592,21 @@ async function handleAssetPost(ctx, req, res) {
|
|
|
576
592
|
}
|
|
577
593
|
const { file, scope: rawScope, name, contentType, dataBase64 } = body || {};
|
|
578
594
|
if (typeof dataBase64 !== "string" || !dataBase64) {
|
|
579
|
-
sendJson(res, 400, { error: "missing
|
|
595
|
+
sendJson(res, 400, { error: "missing asset data" });
|
|
580
596
|
return;
|
|
581
597
|
}
|
|
582
598
|
const buf = Buffer.from(dataBase64, "base64");
|
|
583
599
|
if (!buf.length) {
|
|
584
|
-
sendJson(res, 400, { error: "empty
|
|
600
|
+
sendJson(res, 400, { error: "empty asset data" });
|
|
585
601
|
return;
|
|
586
602
|
}
|
|
587
603
|
if (buf.length > MAX_ASSET_BYTES) {
|
|
588
|
-
sendJson(res, 413, { error: "
|
|
604
|
+
sendJson(res, 413, { error: "asset too large (>64MB)" });
|
|
589
605
|
return;
|
|
590
606
|
}
|
|
591
607
|
const ext = assetExt(name, contentType);
|
|
592
|
-
if (!
|
|
593
|
-
sendJson(res, 400, { error: "unsupported
|
|
608
|
+
if (!ASSET_MEDIA_EXT.has(ext)) {
|
|
609
|
+
sendJson(res, 400, { error: "unsupported asset type" });
|
|
594
610
|
return;
|
|
595
611
|
}
|
|
596
612
|
const scope = rawScope === "global" ? "global" : "project";
|
|
@@ -617,6 +633,7 @@ async function handleAssetPost(ctx, req, res) {
|
|
|
617
633
|
name: fileName,
|
|
618
634
|
path: toPosixPath(relative(ctx.root, absTarget)),
|
|
619
635
|
src: toPosixPath(relative(htmlDirAbs, absTarget)),
|
|
636
|
+
kind: assetKind(ext),
|
|
620
637
|
bytes: buf.length,
|
|
621
638
|
reused: alreadyIdentical,
|
|
622
639
|
policy: buildPolicy(ctx),
|
package/cli/dist/index.js
CHANGED
|
File without changes
|
|
@@ -4228,6 +4228,15 @@ ${slidesArg.join('\n\n')}
|
|
|
4228
4228
|
{text.layers}
|
|
4229
4229
|
</button>
|
|
4230
4230
|
<span className="cv-inspector__zoom">{Math.round(viewScale * 100)}%</span>
|
|
4231
|
+
<button
|
|
4232
|
+
type="button"
|
|
4233
|
+
className="cv-inspector__close"
|
|
4234
|
+
onClick={exitFocus}
|
|
4235
|
+
aria-label={text.panel?.closeEditPanel || 'Close'}
|
|
4236
|
+
title={text.overview || 'Overview'}
|
|
4237
|
+
>
|
|
4238
|
+
<X size={19} strokeWidth={2.25} />
|
|
4239
|
+
</button>
|
|
4231
4240
|
</div>
|
|
4232
4241
|
<div className="cv-inspector__ctx">
|
|
4233
4242
|
<span className="cv-inspector__tag"><{selection.element?.tagName?.toLowerCase?.() || 'node'}></span>
|
|
@@ -4255,7 +4264,7 @@ ${slidesArg.join('\n\n')}
|
|
|
4255
4264
|
key={`${selection.key || selection.selector || selection.element?.tagName || 'selection'}:${inspectorNonce}`}
|
|
4256
4265
|
selector={selection.selector}
|
|
4257
4266
|
element={selection.element}
|
|
4258
|
-
onClose={
|
|
4267
|
+
onClose={exitFocus}
|
|
4259
4268
|
onChange={onPanelChange}
|
|
4260
4269
|
labels={text.panel}
|
|
4261
4270
|
assetTools={{
|
|
@@ -4506,11 +4515,13 @@ ${slidesArg.join('\n\n')}
|
|
|
4506
4515
|
.cv-zoomhud { position: absolute; bottom: 16px; right: 16px; display: flex; align-items: center; gap: 2px; padding: 5px 8px; border-radius: 10px; background: rgba(255,255,255,0.96); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); border: 1px solid #e6e6e6; box-shadow: 0 4px 16px rgba(0,0,0,0.1); z-index: 8; }
|
|
4507
4516
|
.cv-zoomhud__label { min-width: 44px; text-align: center; font-size: 12px; font-weight: 600; color: #3a3a3a; font-variant-numeric: tabular-nums; }
|
|
4508
4517
|
|
|
4509
|
-
.cv-inspector { width: 280px; flex: 0 0 280px; display: flex; flex-direction: column; background: #ffffff; border-
|
|
4518
|
+
.cv-inspector { order: -1; width: 280px; flex: 0 0 280px; display: flex; flex-direction: column; background: #ffffff; border-right: 1px solid #e6e6e6; overflow-x: hidden; overflow-y: auto; min-height: 0; scrollbar-gutter: stable; }
|
|
4510
4519
|
.cv-inspector__tabs { display: flex; align-items: center; gap: 2px; padding: 8px 10px; border-bottom: 1px solid #ececec; flex: 0 0 auto; }
|
|
4511
4520
|
.cv-inspector__tabs button { border: none; background: transparent; font-size: 12.5px; font-weight: 600; color: #9a9a9a; padding: 5px 10px; border-radius: 6px; cursor: pointer; }
|
|
4512
4521
|
.cv-inspector__tabs button.is-active { color: #1a1a1a; background: #f0f0f0; }
|
|
4513
4522
|
.cv-inspector__zoom { margin-left: auto; font-size: 11px; color: #9a9a9a; font-variant-numeric: tabular-nums; padding-right: 4px; }
|
|
4523
|
+
.cv-inspector__close { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; margin-left: 2px; border: none; background: transparent; color: #6a6a6a; border-radius: 8px; cursor: pointer; flex: 0 0 auto; }
|
|
4524
|
+
.cv-inspector__close:hover { background: #ececec; color: #111; }
|
|
4514
4525
|
.cv-inspector__ctx { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid #ececec; flex: 0 0 auto; }
|
|
4515
4526
|
.cv-inspector__tag { font-family: ui-monospace, monospace; font-size: 11px; font-weight: 600; color: var(--cv-sel); background: var(--cv-sel-soft); padding: 2px 7px; border-radius: 5px; white-space: nowrap; }
|
|
4516
4527
|
.cv-inspector__sel { font-size: 11px; color: #9a9a9a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
@@ -4540,7 +4551,8 @@ ${slidesArg.join('\n\n')}
|
|
|
4540
4551
|
|
|
4541
4552
|
@keyframes cv-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
|
|
4542
4553
|
|
|
4543
|
-
|
|
4554
|
+
/* While editing an element the inspector replaces the slide/layer list on the left */
|
|
4555
|
+
.cv-main:has(.cv-inspector) .cv-leftpanel {
|
|
4544
4556
|
display: none;
|
|
4545
4557
|
}
|
|
4546
4558
|
|
|
@@ -4576,6 +4588,7 @@ ${slidesArg.join('\n\n')}
|
|
|
4576
4588
|
}
|
|
4577
4589
|
|
|
4578
4590
|
.cv-main:has(.cv-inspector) .cv-leftpanel {
|
|
4591
|
+
display: flex;
|
|
4579
4592
|
grid-column: 1;
|
|
4580
4593
|
}
|
|
4581
4594
|
|
|
@@ -4613,6 +4626,8 @@ ${slidesArg.join('\n\n')}
|
|
|
4613
4626
|
width: 248px;
|
|
4614
4627
|
min-width: 0;
|
|
4615
4628
|
flex: none;
|
|
4629
|
+
border-left: 1px solid #e6e6e6;
|
|
4630
|
+
border-right: 0;
|
|
4616
4631
|
}
|
|
4617
4632
|
|
|
4618
4633
|
.cv-lp-section--slides .cv-lp-pages {
|
|
@@ -4691,6 +4706,7 @@ ${slidesArg.join('\n\n')}
|
|
|
4691
4706
|
|
|
4692
4707
|
.cv-leftpanel,
|
|
4693
4708
|
.cv-main:has(.cv-inspector) .cv-leftpanel {
|
|
4709
|
+
display: flex;
|
|
4694
4710
|
grid-column: 1;
|
|
4695
4711
|
grid-row: 2;
|
|
4696
4712
|
}
|
|
@@ -4707,6 +4723,7 @@ ${slidesArg.join('\n\n')}
|
|
|
4707
4723
|
max-width: none;
|
|
4708
4724
|
border-top: 1px solid #e6e6e6;
|
|
4709
4725
|
border-left: 0;
|
|
4726
|
+
border-right: 0;
|
|
4710
4727
|
}
|
|
4711
4728
|
|
|
4712
4729
|
.cv-lp-section--slides .cv-lp-pages {
|
package/package.json
CHANGED
|
@@ -420,6 +420,10 @@ Extract the download URL from the `Download:` text block in the response. Then o
|
|
|
420
420
|
|
|
421
421
|
Do NOT ask the user to manually download — always automate the full flow.
|
|
422
422
|
|
|
423
|
+
#### Step 9: Open the local editor (mandatory)
|
|
424
|
+
|
|
425
|
+
After the PPTX is downloaded and opened, immediately perform the mandatory editor handoff (see "Mandatory editor handoff after HTML generation"). This is not optional and must run even when the user only asked for a PPTX export — do not stop at the PPTX/HTML and do not ask whether to open the editor.
|
|
426
|
+
|
|
423
427
|
### Output directory structure
|
|
424
428
|
|
|
425
429
|
All generated files MUST be saved under `./html2pptx/`:
|
|
@@ -575,6 +579,8 @@ If the user clicks Export PPTX inside the local editor, the browser must only sh
|
|
|
575
579
|
|
|
576
580
|
Whenever this skill finishes generating or materially updating a slide HTML file, always hand it off to the local visual editor. Prefer `html2pptx_open_local_slide_editor` because it starts the loopback UI and bridge together; do not use hosted edit-slide as a fallback. Do this even if the user did not separately ask for preview.
|
|
577
581
|
|
|
582
|
+
This handoff is unconditional and applies to EVERY slide generation path, including when the user only asked for a PPTX export. Do not merely offer it, and do not ask "shall I open the editor?" — open it. The only thing that ever requires asking first is adding the local stdio MCP config when it is not yet present (see below); the act of opening the editor itself is never gated on user confirmation. Treat "stopped at HTML/PPTX without opening the editor" as a skill failure.
|
|
583
|
+
|
|
578
584
|
Required behavior:
|
|
579
585
|
|
|
580
586
|
1. Save the deck under `./html2pptx/<fileName>.html`.
|