@agent-native/core 0.144.0 → 0.144.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +1 -1
  3. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +36 -14
  4. package/corpus/templates/clips/app/components/player/player-controls.tsx +0 -3
  5. package/corpus/templates/clips/app/components/player/scrubber.tsx +2 -33
  6. package/corpus/templates/clips/app/components/player/video-player.tsx +58 -11
  7. package/corpus/templates/clips/changelog/2026-08-06-trimmed-clips-play-on-a-clean-timeline-without-cut-markers.md +6 -0
  8. package/corpus/templates/dispatch/AGENTS.md +8 -1
  9. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -0
  10. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +30 -15
  11. package/corpus/templates/dispatch/app/i18n-data.ts +131 -0
  12. package/corpus/templates/dispatch/app/routes/admin._index.tsx +4 -0
  13. package/corpus/templates/dispatch/app/routes/admin.agents.tsx +1 -0
  14. package/corpus/templates/dispatch/app/routes/admin.approvals.tsx +1 -0
  15. package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +1 -0
  16. package/corpus/templates/dispatch/app/routes/admin.apps.tsx +1 -0
  17. package/corpus/templates/dispatch/app/routes/admin.audit.tsx +1 -0
  18. package/corpus/templates/dispatch/app/routes/admin.automations.tsx +1 -0
  19. package/corpus/templates/dispatch/app/routes/admin.destinations.tsx +4 -0
  20. package/corpus/templates/dispatch/app/routes/admin.dreams.tsx +1 -0
  21. package/corpus/templates/dispatch/app/routes/admin.identities.tsx +1 -0
  22. package/corpus/templates/dispatch/app/routes/admin.integrations.tsx +4 -0
  23. package/corpus/templates/dispatch/app/routes/admin.messaging.tsx +1 -0
  24. package/corpus/templates/dispatch/app/routes/admin.metrics.tsx +1 -0
  25. package/corpus/templates/dispatch/app/routes/admin.new-app.tsx +1 -0
  26. package/corpus/templates/dispatch/app/routes/admin.operations.tsx +1 -0
  27. package/corpus/templates/dispatch/app/routes/admin.thread-debug.tsx +4 -0
  28. package/corpus/templates/dispatch/app/routes/admin.transactional-email.$appId.$id.tsx +4 -0
  29. package/corpus/templates/dispatch/app/routes/admin.transactional-email.tsx +4 -0
  30. package/corpus/templates/dispatch/app/routes/admin.tsx +1 -0
  31. package/corpus/templates/dispatch/app/routes/admin.vault.tsx +1 -0
  32. package/corpus/templates/dispatch/app/routes/admin.workspace.tsx +1 -0
  33. package/corpus/templates/dispatch/changelog/2026-08-06-dispatch-keeps-everyday-navigation-focused-while-management-.md +6 -0
  34. package/corpus/templates/slides/AGENTS.md +10 -12
  35. package/corpus/templates/slides/actions/export-pptx.ts +68 -0
  36. package/corpus/templates/slides/actions/get-deck.ts +12 -0
  37. package/corpus/templates/slides/actions/import-file.ts +130 -55
  38. package/corpus/templates/slides/actions/import-pptx.ts +108 -8
  39. package/corpus/templates/slides/actions/patch-deck.ts +51 -0
  40. package/corpus/templates/slides/actions/update-slide.ts +29 -3
  41. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +11 -0
  42. package/corpus/templates/slides/app/lib/create-deck-generation.ts +72 -11
  43. package/corpus/templates/slides/app/lib/import-uploaded-deck.ts +89 -0
  44. package/corpus/templates/slides/app/pages/Index.tsx +85 -18
  45. package/corpus/templates/slides/changelog/2026-08-06-uploaded-decks-keep-their-slides-and-visuals-when-you-improv.md +6 -0
  46. package/corpus/templates/slides/server/handlers/import/html-converter.ts +13 -2
  47. package/corpus/templates/slides/server/lib/chat-attachments.ts +2 -2
  48. package/corpus/templates/slides/server/lib/source-import.ts +167 -0
  49. package/corpus/templates/slides/server/plugins/agent-chat.ts +8 -0
  50. package/dist/client/analytics/index.d.ts +1 -1
  51. package/dist/client/analytics/index.js +1 -1
  52. package/dist/client/analytics-session.d.ts +13 -0
  53. package/dist/client/analytics-session.js +57 -0
  54. package/dist/client/analytics.d.ts +1 -0
  55. package/dist/client/analytics.js +1 -0
  56. package/dist/client/index.d.ts +1 -1
  57. package/dist/client/index.js +1 -1
  58. package/dist/client/track.js +7 -0
  59. package/dist/client/use-action.js +10 -1
  60. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  61. package/dist/jobs/scheduler.js +79 -23
  62. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  63. package/dist/notifications/routes.d.ts +3 -3
  64. package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
  65. package/dist/resources/handlers.d.ts +1 -1
  66. package/dist/secrets/routes.d.ts +9 -9
  67. package/dist/server/action-routes.js +4 -2
  68. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  69. package/dist/server/agent-run-context.d.ts +4 -2
  70. package/dist/server/agent-run-context.js +5 -3
  71. package/dist/server/core-routes-plugin.js +2 -0
  72. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +5 -1
  73. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +20 -3
  74. package/dist/tracking/index.d.ts +1 -1
  75. package/dist/tracking/providers.js +12 -1
  76. package/dist/tracking/registry.d.ts +12 -2
  77. package/dist/tracking/registry.js +27 -3
  78. package/dist/tracking/types.d.ts +8 -0
  79. package/docs/content/creating-templates.mdx +1 -1
  80. package/docs/content/getting-started-actions.mdx +38 -189
  81. package/docs/content/getting-started-database.mdx +80 -164
  82. package/docs/content/getting-started-pages.mdx +44 -155
  83. package/docs/content/getting-started.mdx +26 -106
  84. package/docs/content/observability.mdx +16 -0
  85. package/docs/content/tracking.mdx +17 -2
  86. package/package.json +1 -1
  87. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +5 -1
  88. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +20 -3
@@ -266,6 +266,7 @@ const enUS = {
266
266
  },
267
267
  dispatch: {
268
268
  nav: {
269
+ admin: "Admin",
269
270
  automations: "Automations",
270
271
  approvals: "Approvals",
271
272
  delivery: "Delivery",
@@ -276,6 +277,18 @@ const enUS = {
276
277
  agent: "Agent",
277
278
  },
278
279
  pages: {
280
+ adminDescription: "Workspace controls and operations",
281
+ adminNavigation: "Admin navigation",
282
+ adminWelcome: "Workspace control plane",
283
+ adminChooseArea:
284
+ "Manage apps, connections, automations, and operational tools from one place.",
285
+ adminChooseAreaHint: "Choose an area from the Admin navigation.",
286
+ adminWorkspace: "Workspace",
287
+ adminOperations: "Operations",
288
+ adminAutomation: "Automation & delivery",
289
+ adminConnections: "Connections",
290
+ adminAgentPlatform: "Agent platform",
291
+ adminWorkspaceExtensions: "Workspace extensions",
279
292
  dataLoadFailed: "Couldn't load data",
280
293
  dataLoadFailedDescription: "Dispatch couldn't load this data.",
281
294
  tryAgain: "Try again",
@@ -713,6 +726,7 @@ export const messagesByLocale = {
713
726
 
714
727
  dispatch: {
715
728
  nav: {
729
+ admin: "管理",
716
730
  automations: "自动化",
717
731
  approvals: "批准",
718
732
  delivery: "投递",
@@ -723,6 +737,17 @@ export const messagesByLocale = {
723
737
  agent: "代理",
724
738
  },
725
739
  pages: {
740
+ adminDescription: "工作区控制与运营",
741
+ adminNavigation: "管理导航",
742
+ adminWelcome: "工作区控制中心",
743
+ adminChooseArea: "在一个地方管理应用、连接、自动化和运营工具。",
744
+ adminChooseAreaHint: "从管理导航中选择一个区域。",
745
+ adminWorkspace: "工作区",
746
+ adminOperations: "运营",
747
+ adminAutomation: "自动化与投递",
748
+ adminConnections: "连接",
749
+ adminAgentPlatform: "代理平台",
750
+ adminWorkspaceExtensions: "工作区扩展",
726
751
  dataLoadFailed: "无法加载数据",
727
752
  dataLoadFailedDescription: "Dispatch 无法加载这些数据。",
728
753
  tryAgain: "重试",
@@ -1093,6 +1118,7 @@ export const messagesByLocale = {
1093
1118
 
1094
1119
  dispatch: {
1095
1120
  nav: {
1121
+ admin: "Administración",
1096
1122
  automations: "Automatizaciones",
1097
1123
  approvals: "Aprobaciones",
1098
1124
  delivery: "Entrega",
@@ -1103,6 +1129,19 @@ export const messagesByLocale = {
1103
1129
  agent: "Agente",
1104
1130
  },
1105
1131
  pages: {
1132
+ adminDescription: "Controles y operaciones del espacio de trabajo",
1133
+ adminNavigation: "Navegación de administración",
1134
+ adminWelcome: "Panel de control del espacio de trabajo",
1135
+ adminChooseArea:
1136
+ "Gestiona aplicaciones, conexiones, automatizaciones y herramientas operativas desde un solo lugar.",
1137
+ adminChooseAreaHint:
1138
+ "Elige un área en la navegación de administración.",
1139
+ adminWorkspace: "Espacio de trabajo",
1140
+ adminOperations: "Operaciones",
1141
+ adminAutomation: "Automatización y entrega",
1142
+ adminConnections: "Conexiones",
1143
+ adminAgentPlatform: "Plataforma de agentes",
1144
+ adminWorkspaceExtensions: "Extensiones del espacio de trabajo",
1106
1145
  dataLoadFailed: "No se pudieron cargar los datos",
1107
1146
  dataLoadFailedDescription: "Dispatch no pudo cargar estos datos.",
1108
1147
  tryAgain: "Intentar de nuevo",
@@ -1484,6 +1523,7 @@ export const messagesByLocale = {
1484
1523
 
1485
1524
  dispatch: {
1486
1525
  nav: {
1526
+ admin: "Administration",
1487
1527
  automations: "Automatisations",
1488
1528
  approvals: "Approbations",
1489
1529
  delivery: "Livraison",
@@ -1494,6 +1534,19 @@ export const messagesByLocale = {
1494
1534
  agent: "Agent",
1495
1535
  },
1496
1536
  pages: {
1537
+ adminDescription: "Contrôles et opérations de l’espace de travail",
1538
+ adminNavigation: "Navigation d’administration",
1539
+ adminWelcome: "Centre de contrôle de l’espace de travail",
1540
+ adminChooseArea:
1541
+ "Gérez les applications, connexions, automatisations et outils opérationnels depuis un seul endroit.",
1542
+ adminChooseAreaHint:
1543
+ "Choisissez une section dans la navigation d’administration.",
1544
+ adminWorkspace: "Espace de travail",
1545
+ adminOperations: "Opérations",
1546
+ adminAutomation: "Automatisation et livraison",
1547
+ adminConnections: "Connexions",
1548
+ adminAgentPlatform: "Plateforme d’agents",
1549
+ adminWorkspaceExtensions: "Extensions de l’espace de travail",
1497
1550
  dataLoadFailed: "Impossible de charger les données",
1498
1551
  dataLoadFailedDescription: "Dispatch n’a pas pu charger ces données.",
1499
1552
  tryAgain: "Réessayer",
@@ -1865,6 +1918,7 @@ export const messagesByLocale = {
1865
1918
 
1866
1919
  dispatch: {
1867
1920
  nav: {
1921
+ admin: "Administration",
1868
1922
  automations: "Automatisierungen",
1869
1923
  approvals: "Freigaben",
1870
1924
  delivery: "Zustellung",
@@ -1875,6 +1929,19 @@ export const messagesByLocale = {
1875
1929
  agent: "Agent",
1876
1930
  },
1877
1931
  pages: {
1932
+ adminDescription: "Arbeitsbereichssteuerung und -betrieb",
1933
+ adminNavigation: "Administrationsnavigation",
1934
+ adminWelcome: "Arbeitsbereichsleitstelle",
1935
+ adminChooseArea:
1936
+ "Verwalte Apps, Verbindungen, Automatisierungen und Betriebstools an einem Ort.",
1937
+ adminChooseAreaHint:
1938
+ "Wähle einen Bereich in der Administrationsnavigation.",
1939
+ adminWorkspace: "Arbeitsbereich",
1940
+ adminOperations: "Betrieb",
1941
+ adminAutomation: "Automatisierung und Zustellung",
1942
+ adminConnections: "Verbindungen",
1943
+ adminAgentPlatform: "Agentenplattform",
1944
+ adminWorkspaceExtensions: "Arbeitsbereichserweiterungen",
1878
1945
  dataLoadFailed: "Daten konnten nicht geladen werden",
1879
1946
  dataLoadFailedDescription: "Dispatch konnte diese Daten nicht laden.",
1880
1947
  tryAgain: "Erneut versuchen",
@@ -2240,6 +2307,7 @@ export const messagesByLocale = {
2240
2307
 
2241
2308
  dispatch: {
2242
2309
  nav: {
2310
+ admin: "管理",
2243
2311
  automations: "自動化",
2244
2312
  approvals: "承認",
2245
2313
  delivery: "配信",
@@ -2250,6 +2318,18 @@ export const messagesByLocale = {
2250
2318
  agent: "エージェント",
2251
2319
  },
2252
2320
  pages: {
2321
+ adminDescription: "ワークスペースの管理と運用",
2322
+ adminNavigation: "管理ナビゲーション",
2323
+ adminWelcome: "ワークスペースのコントロールプレーン",
2324
+ adminChooseArea:
2325
+ "アプリ、接続、オートメーション、運用ツールを 1 か所で管理します。",
2326
+ adminChooseAreaHint: "管理ナビゲーションから領域を選択してください。",
2327
+ adminWorkspace: "ワークスペース",
2328
+ adminOperations: "運用",
2329
+ adminAutomation: "自動化と配信",
2330
+ adminConnections: "接続",
2331
+ adminAgentPlatform: "エージェントプラットフォーム",
2332
+ adminWorkspaceExtensions: "ワークスペース拡張機能",
2253
2333
  dataLoadFailed: "データを読み込めませんでした",
2254
2334
  dataLoadFailedDescription:
2255
2335
  "Dispatch はこのデータを読み込めませんでした。",
@@ -2611,6 +2691,7 @@ export const messagesByLocale = {
2611
2691
 
2612
2692
  dispatch: {
2613
2693
  nav: {
2694
+ admin: "관리",
2614
2695
  automations: "자동화",
2615
2696
  approvals: "승인",
2616
2697
  delivery: "전달",
@@ -2621,6 +2702,17 @@ export const messagesByLocale = {
2621
2702
  agent: "에이전트",
2622
2703
  },
2623
2704
  pages: {
2705
+ adminDescription: "워크스페이스 제어 및 운영",
2706
+ adminNavigation: "관리 탐색",
2707
+ adminWelcome: "워크스페이스 제어 센터",
2708
+ adminChooseArea: "한곳에서 앱, 연결, 자동화 및 운영 도구를 관리하세요.",
2709
+ adminChooseAreaHint: "관리 탐색에서 영역을 선택하세요.",
2710
+ adminWorkspace: "워크스페이스",
2711
+ adminOperations: "운영",
2712
+ adminAutomation: "자동화 및 전달",
2713
+ adminConnections: "연결",
2714
+ adminAgentPlatform: "에이전트 플랫폼",
2715
+ adminWorkspaceExtensions: "워크스페이스 확장",
2624
2716
  dataLoadFailed: "데이터를 불러올 수 없습니다",
2625
2717
  dataLoadFailedDescription:
2626
2718
  "Dispatch에서 이 데이터를 불러오지 못했습니다.",
@@ -2991,6 +3083,7 @@ export const messagesByLocale = {
2991
3083
 
2992
3084
  dispatch: {
2993
3085
  nav: {
3086
+ admin: "Administração",
2994
3087
  automations: "Automações",
2995
3088
  approvals: "Aprovações",
2996
3089
  delivery: "Entrega",
@@ -3001,6 +3094,18 @@ export const messagesByLocale = {
3001
3094
  agent: "Agente",
3002
3095
  },
3003
3096
  pages: {
3097
+ adminDescription: "Controles e operações do espaço de trabalho",
3098
+ adminNavigation: "Navegação de administração",
3099
+ adminWelcome: "Central de controle do espaço de trabalho",
3100
+ adminChooseArea:
3101
+ "Gerencie apps, conexões, automações e ferramentas operacionais em um só lugar.",
3102
+ adminChooseAreaHint: "Escolha uma área na navegação de administração.",
3103
+ adminWorkspace: "Espaço de trabalho",
3104
+ adminOperations: "Operações",
3105
+ adminAutomation: "Automação e entrega",
3106
+ adminConnections: "Conexões",
3107
+ adminAgentPlatform: "Plataforma de agentes",
3108
+ adminWorkspaceExtensions: "Extensões do espaço de trabalho",
3004
3109
  dataLoadFailed: "Não foi possível carregar os dados",
3005
3110
  dataLoadFailedDescription:
3006
3111
  "O Dispatch não conseguiu carregar estes dados.",
@@ -3359,6 +3464,7 @@ export const messagesByLocale = {
3359
3464
 
3360
3465
  dispatch: {
3361
3466
  nav: {
3467
+ admin: "व्यवस्थापक",
3362
3468
  automations: "ऑटोमेशन",
3363
3469
  approvals: "अनुमोदन",
3364
3470
  delivery: "डिलीवरी",
@@ -3369,6 +3475,18 @@ export const messagesByLocale = {
3369
3475
  agent: "एजेंट",
3370
3476
  },
3371
3477
  pages: {
3478
+ adminDescription: "वर्कस्पेस नियंत्रण और संचालन",
3479
+ adminNavigation: "व्यवस्थापक नेविगेशन",
3480
+ adminWelcome: "वर्कस्पेस नियंत्रण केंद्र",
3481
+ adminChooseArea:
3482
+ "ऐप्स, कनेक्शन, ऑटोमेशन और संचालन टूल एक ही जगह से प्रबंधित करें।",
3483
+ adminChooseAreaHint: "व्यवस्थापक नेविगेशन से कोई क्षेत्र चुनें।",
3484
+ adminWorkspace: "वर्कस्पेस",
3485
+ adminOperations: "संचालन",
3486
+ adminAutomation: "ऑटोमेशन और डिलीवरी",
3487
+ adminConnections: "कनेक्शन",
3488
+ adminAgentPlatform: "एजेंट प्लेटफ़ॉर्म",
3489
+ adminWorkspaceExtensions: "वर्कस्पेस एक्सटेंशन",
3372
3490
  dataLoadFailed: "डेटा लोड नहीं हो सका",
3373
3491
  dataLoadFailedDescription: "Dispatch यह डेटा लोड नहीं कर सका।",
3374
3492
  tryAgain: "फिर से कोशिश करें",
@@ -3758,6 +3876,7 @@ export const messagesByLocale = {
3758
3876
 
3759
3877
  dispatch: {
3760
3878
  nav: {
3879
+ admin: "الإدارة",
3761
3880
  automations: "الأتمتة",
3762
3881
  approvals: "الموافقات",
3763
3882
  delivery: "التسليم",
@@ -3768,6 +3887,18 @@ export const messagesByLocale = {
3768
3887
  agent: "الوكيل",
3769
3888
  },
3770
3889
  pages: {
3890
+ adminDescription: "عناصر التحكم في مساحة العمل وعملياتها",
3891
+ adminNavigation: "تنقل الإدارة",
3892
+ adminWelcome: "مركز التحكم في مساحة العمل",
3893
+ adminChooseArea:
3894
+ "أدر التطبيقات والاتصالات والأتمتة وأدوات التشغيل من مكان واحد.",
3895
+ adminChooseAreaHint: "اختر قسمًا من تنقل الإدارة.",
3896
+ adminWorkspace: "مساحة العمل",
3897
+ adminOperations: "التشغيل",
3898
+ adminAutomation: "الأتمتة والتسليم",
3899
+ adminConnections: "الاتصالات",
3900
+ adminAgentPlatform: "منصة الوكلاء",
3901
+ adminWorkspaceExtensions: "امتدادات مساحة العمل",
3771
3902
  dataLoadFailed: "تعذر تحميل البيانات",
3772
3903
  dataLoadFailedDescription: "تعذر على Dispatch تحميل هذه البيانات.",
3773
3904
  tryAgain: "حاول مرة أخرى",
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ meta,
4
+ } from "@agent-native/dispatch/routes/pages/admin._index";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/agents";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/approvals";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/apps.$appId";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/apps";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/audit";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/automations";
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ meta,
4
+ } from "@agent-native/dispatch/routes/pages/destinations";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/dreams";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/identities";
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ meta,
4
+ } from "@agent-native/dispatch/routes/pages/integrations";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/messaging";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/metrics";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/new-app";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/operations";
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ meta,
4
+ } from "@agent-native/dispatch/routes/pages/thread-debug";
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ meta,
4
+ } from "@agent-native/dispatch/routes/pages/transactional-email.$appId.$id";
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ meta,
4
+ } from "@agent-native/dispatch/routes/pages/transactional-email";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/admin";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/vault";
@@ -0,0 +1 @@
1
+ export { default, meta } from "@agent-native/dispatch/routes/pages/workspace";
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-06
4
+ ---
5
+
6
+ Dispatch keeps everyday navigation focused while management tools live in a dedicated Admin area
@@ -25,6 +25,14 @@ Before building common workspace or agent UI, read `agent-native-toolkit` and
25
25
  current layout is unclear.
26
26
  - Preserve deck structure and visual consistency. Prefer focused slide edits over
27
27
  regenerating whole decks unless requested.
28
+ - When an uploaded PPTX or PDF is being improved, import it into the target deck
29
+ first with `import-pptx` or `import-file --importIntoDeck true`. Treat the
30
+ resulting `sourceImport` metadata as the source-of-truth contract: preserve
31
+ slide count, order, IDs, factual copy, notes, images, and positioned objects;
32
+ use `update-slide` for bounded visual edits and verify with `get-deck`.
33
+ - A source import with `fidelity: partial` or `imagesSkipped` is not safe to
34
+ restyle automatically. Report the exact warning rather than silently
35
+ replacing missing content.
28
36
  - Preserve freeform objects and their `data-slide-object-id` values. They are
29
37
  absolutely positioned `.fmd-slide` children; keep generated flex/grid in
30
38
  normal flow and mint ids only for duplicates. Use styled HTML, not inline SVG.
@@ -55,18 +63,8 @@ Before building common workspace or agent UI, read `agent-native-toolkit` and
55
63
 
56
64
  ## Persistence Model
57
65
 
58
- Decks are stored as a single JSON blob in the `decks.data` column. All writes
59
- go through server-side read-modify-write actions that hold a per-deck lock,
60
- so concurrent writers (human + agent, two humans) touching different slides
61
- never overwrite each other's work.
62
-
63
- **Agent actions** (`update-slide`, `add-slide`): continue to use their dedicated
64
- granular actions — they share the same in-process deck lock.
65
-
66
- **Browser editor** now calls `patch-deck` instead of a full PUT. If you are
67
- extending the editor's save path, enqueue a granular op (`patch-slide`,
68
- `delete-slide`, `reorder-slides`, `add-slide`, or `patch-deck-fields`) via
69
- `enqueueDeckOp` in `DeckContext.tsx` — do NOT add a new full-deck PUT.
66
+ Deck data lives in SQL and all writes go through server-side actions. Read
67
+ `deck-management` before changing persistence or editor save paths.
70
68
 
71
69
  ## Application State
72
70
 
@@ -182,6 +182,9 @@ export function parseSlideHtml(
182
182
  } {
183
183
  assertServerPptxExportable(html, slideNumber);
184
184
  const dims = getAspectRatioDims(aspectRatio);
185
+ if (html.includes('data-imported-pdf="true"')) {
186
+ return parseImportedPdfSlideHtml(html, dims);
187
+ }
185
188
  if (html.includes('data-imported-pptx="true"')) {
186
189
  return parseImportedSlideHtml(html, dims);
187
190
  }
@@ -371,6 +374,71 @@ export function parseSlideHtml(
371
374
 
372
375
  type SlideDims = ReturnType<typeof getAspectRatioDims>;
373
376
 
377
+ function parseImportedPdfSlideHtml(
378
+ html: string,
379
+ dims: SlideDims,
380
+ ): {
381
+ texts: TextElement[];
382
+ images: ImageElement[];
383
+ shapes: ShapeElement[];
384
+ grid?: GridElement;
385
+ bgColor: string;
386
+ } {
387
+ const outerStyle = html.match(
388
+ /class=["'][^"']*\bfmd-slide\b[^"']*["'][^>]*style=["']([^"']*)["']/i,
389
+ )?.[1];
390
+ const bgColor = colorToHex(
391
+ outerStyle
392
+ ? (getStyle(outerStyle, "background(?:-color)?") ?? "#000000") // guard:allow-raw-color - imported PDF fallback
393
+ : "#000000", // guard:allow-raw-color - imported PDF fallback
394
+ );
395
+ const src = html.match(/<img\b[^>]*\bsrc=["']([^"']+)["'][^>]*>/i)?.[1];
396
+ const outerAttrs = html.match(/<div\b([^>]*)>/i)?.[1] ?? "";
397
+ const sourceWidth = Number.parseFloat(
398
+ getAttribute(outerAttrs, "data-source-width") ?? "",
399
+ );
400
+ const sourceHeight = Number.parseFloat(
401
+ getAttribute(outerAttrs, "data-source-height") ?? "",
402
+ );
403
+ let x = 0;
404
+ let y = 0;
405
+ let w = dims.pptxInches.w;
406
+ let h = dims.pptxInches.h;
407
+ if (
408
+ Number.isFinite(sourceWidth) &&
409
+ Number.isFinite(sourceHeight) &&
410
+ sourceWidth > 0 &&
411
+ sourceHeight > 0
412
+ ) {
413
+ const sourceAspect = sourceWidth / sourceHeight;
414
+ const deckAspect = dims.pptxInches.w / dims.pptxInches.h;
415
+ if (sourceAspect > deckAspect) {
416
+ h = w / sourceAspect;
417
+ y = (dims.pptxInches.h - h) / 2;
418
+ } else {
419
+ w = h * sourceAspect;
420
+ x = (dims.pptxInches.w - w) / 2;
421
+ }
422
+ }
423
+ return {
424
+ texts: [],
425
+ images: src
426
+ ? [
427
+ {
428
+ src: decodeHtmlText(src),
429
+ x,
430
+ y,
431
+ w,
432
+ h,
433
+ order: 0,
434
+ },
435
+ ]
436
+ : [],
437
+ shapes: [],
438
+ bgColor,
439
+ };
440
+ }
441
+
374
442
  function parseImportedSlideHtml(
375
443
  html: string,
376
444
  dims: SlideDims,
@@ -68,6 +68,18 @@ export default defineAction({
68
68
  title: row.title || data?.title,
69
69
  visibility: row.visibility,
70
70
  designSystemId: row.designSystemId ?? null,
71
+ sourceImport: data?.sourceImport
72
+ ? {
73
+ mode: data.sourceImport.mode,
74
+ format: data.sourceImport.format,
75
+ fidelity: data.sourceImport.fidelity,
76
+ slideCount: data.sourceImport.slideCount,
77
+ slideIds: data.sourceImport.slideIds,
78
+ ...(typeof data.sourceImport.imagesSkipped === "number"
79
+ ? { imagesSkipped: data.sourceImport.imagesSkipped }
80
+ : {}),
81
+ }
82
+ : null,
71
83
  slideCount: slides.length,
72
84
  slideNumbering:
73
85
  'User-visible slide numbers are 1-based and match the UI. "Slide 1" means slideNumber 1 / zeroBasedIndex 0. Use slideId for edits.',