@agent-native/core 0.83.0 → 0.84.1

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 (508) hide show
  1. package/README.md +2 -2
  2. package/corpus/README.md +1 -1
  3. package/corpus/core/CHANGELOG.md +34 -0
  4. package/corpus/core/README.md +2 -2
  5. package/corpus/core/docs/content/cloneable-saas.mdx +2 -2
  6. package/corpus/core/docs/content/evals.mdx +34 -12
  7. package/corpus/core/docs/content/faq.mdx +1 -1
  8. package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  9. package/corpus/core/docs/content/locales/ar-SA/evals.mdx +7 -0
  10. package/corpus/core/docs/content/locales/ar-SA/faq.mdx +1 -1
  11. package/corpus/core/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  12. package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  13. package/corpus/core/docs/content/locales/de-DE/evals.mdx +8 -0
  14. package/corpus/core/docs/content/locales/de-DE/faq.mdx +1 -1
  15. package/corpus/core/docs/content/locales/de-DE/template-chat.mdx +1 -1
  16. package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  17. package/corpus/core/docs/content/locales/es-ES/evals.mdx +8 -0
  18. package/corpus/core/docs/content/locales/es-ES/faq.mdx +1 -1
  19. package/corpus/core/docs/content/locales/es-ES/template-chat.mdx +1 -1
  20. package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  21. package/corpus/core/docs/content/locales/fr-FR/evals.mdx +8 -0
  22. package/corpus/core/docs/content/locales/fr-FR/faq.mdx +1 -1
  23. package/corpus/core/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  24. package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  25. package/corpus/core/docs/content/locales/hi-IN/evals.mdx +8 -0
  26. package/corpus/core/docs/content/locales/hi-IN/faq.mdx +1 -1
  27. package/corpus/core/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  28. package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  29. package/corpus/core/docs/content/locales/ja-JP/evals.mdx +7 -0
  30. package/corpus/core/docs/content/locales/ja-JP/faq.mdx +1 -1
  31. package/corpus/core/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  32. package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  33. package/corpus/core/docs/content/locales/ko-KR/evals.mdx +7 -0
  34. package/corpus/core/docs/content/locales/ko-KR/faq.mdx +1 -1
  35. package/corpus/core/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  36. package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  37. package/corpus/core/docs/content/locales/pt-BR/evals.mdx +8 -0
  38. package/corpus/core/docs/content/locales/pt-BR/faq.mdx +1 -1
  39. package/corpus/core/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  40. package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  41. package/corpus/core/docs/content/locales/zh-CN/evals.mdx +7 -0
  42. package/corpus/core/docs/content/locales/zh-CN/faq.mdx +1 -1
  43. package/corpus/core/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  44. package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  45. package/corpus/core/docs/content/locales/zh-TW/evals.mdx +7 -0
  46. package/corpus/core/docs/content/locales/zh-TW/faq.mdx +1 -1
  47. package/corpus/core/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  48. package/corpus/core/docs/content/template-chat.mdx +1 -1
  49. package/corpus/core/package.json +1 -1
  50. package/corpus/core/src/agent/engine/builtin.ts +1 -1
  51. package/corpus/core/src/agent/engine/output-tokens.ts +1 -1
  52. package/corpus/core/src/agent/harness/acp-adapter.ts +28 -4
  53. package/corpus/core/src/agent/harness/ai-sdk-adapter.ts +3 -0
  54. package/corpus/core/src/agent/harness/translate.ts +3 -0
  55. package/corpus/core/src/agent/harness/types.ts +1 -0
  56. package/corpus/core/src/agent/model-config.ts +34 -13
  57. package/corpus/core/src/agent/production-agent.ts +87 -10
  58. package/corpus/core/src/agent/thread-data-builder.ts +29 -4
  59. package/corpus/core/src/agent/tool-call-journal.ts +109 -48
  60. package/corpus/core/src/agent/types.ts +6 -1
  61. package/corpus/core/src/cli/design-connect.ts +106 -0
  62. package/corpus/core/src/cli/gateway-helpers.ts +17 -0
  63. package/corpus/core/src/cli/recap.ts +0 -2
  64. package/corpus/core/src/cli/skills.ts +54 -16
  65. package/corpus/core/src/cli/workspace-dev.ts +29 -5
  66. package/corpus/core/src/client/AssistantChat.tsx +89 -42
  67. package/corpus/core/src/client/DefaultSpinner.tsx +8 -1
  68. package/corpus/core/src/client/chat/message-components.tsx +49 -1
  69. package/corpus/core/src/client/chat/repo-helpers.ts +71 -0
  70. package/corpus/core/src/client/chat/run-recovery.tsx +15 -5
  71. package/corpus/core/src/client/components/ApiKeySettings.tsx +8 -8
  72. package/corpus/core/src/client/components/CodeRequiredDialog.tsx +26 -15
  73. package/corpus/core/src/client/components/MissingKeyCard.tsx +13 -6
  74. package/corpus/core/src/client/composer/TiptapComposer.tsx +4 -3
  75. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +0 -1
  76. package/corpus/core/src/client/guided-questions.tsx +21 -27
  77. package/corpus/core/src/client/integrations/IntegrationCard.tsx +1 -1
  78. package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +1 -1
  79. package/corpus/core/src/client/onboarding/OnboardingBanner.tsx +2 -2
  80. package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +23 -19
  81. package/corpus/core/src/client/resources/ResourceEditor.tsx +18 -10
  82. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  83. package/corpus/core/src/client/settings/SettingsPanel.tsx +8 -3
  84. package/corpus/core/src/client/settings/useBuilderStatus.ts +8 -41
  85. package/corpus/core/src/client/useProductionAgent.ts +6 -2
  86. package/corpus/core/src/deploy/build.ts +1 -1
  87. package/corpus/core/src/eval/define-eval.ts +4 -1
  88. package/corpus/core/src/eval/report.ts +23 -8
  89. package/corpus/core/src/eval/runner.ts +41 -6
  90. package/corpus/core/src/eval/types.ts +11 -0
  91. package/corpus/core/src/observability/traces.ts +3 -3
  92. package/corpus/core/src/onboarding/default-steps.ts +1 -1
  93. package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
  94. package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
  95. package/corpus/core/src/server/agent-chat-plugin.ts +177 -81
  96. package/corpus/core/src/server/core-routes-plugin.ts +7 -1
  97. package/corpus/core/src/server/open-route.ts +59 -40
  98. package/corpus/core/src/shared/reasoning-effort.ts +2 -0
  99. package/corpus/core/src/sharing/access.ts +22 -2
  100. package/corpus/core/src/sharing/registry.ts +18 -0
  101. package/corpus/core/src/styles/agent-native.css +104 -20
  102. package/corpus/core/src/styles/rich-markdown-editor.css +11 -10
  103. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +10 -10
  104. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +10 -10
  105. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +6 -5
  106. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +9 -9
  107. package/corpus/templates/analytics/app/global.css +4 -0
  108. package/corpus/templates/analytics/app/lib/chart-theme.ts +13 -0
  109. package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +22 -24
  110. package/corpus/templates/analytics/changelog/2026-06-30-dashboard-charts-now-use-theme-aware-tooltip-and-grid-colors.md +6 -0
  111. package/corpus/templates/analytics/changelog/2026-06-30-fixed-ask-composer-spacing-so-the-chat-field-has-a-comfortab.md +6 -0
  112. package/corpus/templates/calendar/AGENTS.md +4 -0
  113. package/corpus/templates/calendar/actions/connect-google-calendar.ts +80 -0
  114. package/corpus/templates/calendar/changelog/2026-06-30-calendar-now-gives-the-agent-a-safe-google-connection-link-i.md +6 -0
  115. package/corpus/templates/calendar/server/plugins/agent-chat.ts +4 -0
  116. package/corpus/templates/content/AGENTS.md +9 -2
  117. package/corpus/templates/content/actions/_database-row-batch.ts +230 -0
  118. package/corpus/templates/content/actions/_database-utils.ts +17 -9
  119. package/corpus/templates/content/actions/_notion-action-utils.ts +26 -0
  120. package/corpus/templates/content/actions/connect-notion-status.ts +13 -4
  121. package/corpus/templates/content/actions/create-and-link-notion-page.ts +23 -0
  122. package/corpus/templates/content/actions/delete-database-items.ts +55 -0
  123. package/corpus/templates/content/actions/delete-document.ts +4 -4
  124. package/corpus/templates/content/actions/disconnect-notion.ts +16 -0
  125. package/corpus/templates/content/actions/duplicate-database-item.ts +1 -1
  126. package/corpus/templates/content/actions/duplicate-database-items.ts +191 -0
  127. package/corpus/templates/content/actions/link-notion-page.ts +10 -7
  128. package/corpus/templates/content/actions/list-notion-links.ts +3 -4
  129. package/corpus/templates/content/actions/pull-notion-page.ts +7 -9
  130. package/corpus/templates/content/actions/push-notion-page.ts +7 -9
  131. package/corpus/templates/content/actions/refresh-notion-sync-status.ts +24 -0
  132. package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +23 -0
  133. package/corpus/templates/content/actions/search-notion-pages.ts +67 -0
  134. package/corpus/templates/content/actions/unlink-notion-page.ts +23 -0
  135. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +5 -5
  136. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +27 -34
  137. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +16 -13
  138. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +10 -10
  139. package/corpus/templates/content/app/components/editor/NotionConflictBanner.tsx +1 -1
  140. package/corpus/templates/content/app/components/editor/NotionSyncBar.tsx +18 -9
  141. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +27 -34
  142. package/corpus/templates/content/app/components/editor/database/navigation-state.ts +10 -4
  143. package/corpus/templates/content/app/components/sidebar/NotionButton.tsx +32 -17
  144. package/corpus/templates/content/app/global.css +6 -5
  145. package/corpus/templates/content/app/hooks/use-content-database.ts +35 -0
  146. package/corpus/templates/content/app/hooks/use-notion.ts +108 -99
  147. package/corpus/templates/content/changelog/2026-06-30-editor-floating-toolbars-now-use-theme-aware-colors-in-light.md +6 -0
  148. package/corpus/templates/content/package.json +3 -0
  149. package/corpus/templates/content/parity/README.md +69 -0
  150. package/corpus/templates/content/parity/eval-scenarios.ts +118 -0
  151. package/corpus/templates/content/parity/exceptions.allowlist.ts +17 -0
  152. package/corpus/templates/content/parity/matrix.md +28 -0
  153. package/corpus/templates/content/parity/matrix.ts +606 -0
  154. package/corpus/templates/content/parity/matrix.types.ts +42 -0
  155. package/corpus/templates/content/parity/parity-evals.eval.ts +4 -0
  156. package/corpus/templates/content/parity/render-matrix.ts +90 -0
  157. package/corpus/templates/content/parity/scenario-to-eval.ts +57 -0
  158. package/corpus/templates/content/shared/api.ts +11 -0
  159. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +6 -1
  160. package/corpus/templates/design/actions/add-localhost-screens.ts +63 -8
  161. package/corpus/templates/design/actions/apply-motion-edit.ts +12 -46
  162. package/corpus/templates/design/actions/list-design-native-assets.ts +2 -1
  163. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +49 -1
  164. package/corpus/templates/design/actions/navigate.ts +3 -12
  165. package/corpus/templates/design/actions/open-visual-edit.ts +341 -0
  166. package/corpus/templates/design/actions/view-screen.ts +1 -1
  167. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +1 -1
  168. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +345 -14
  169. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +71 -91
  170. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +25 -27
  171. package/corpus/templates/design/app/components/design/DeviceFrame.tsx +1 -1
  172. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +2 -2
  173. package/corpus/templates/design/app/components/design/EditPanel.tsx +1111 -570
  174. package/corpus/templates/design/app/components/design/LayersPanel.tsx +162 -32
  175. package/corpus/templates/design/app/components/design/MotionDock.tsx +268 -240
  176. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1038 -150
  177. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -1
  178. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +81 -102
  179. package/corpus/templates/design/app/components/design/StatesPanel.tsx +6 -6
  180. package/corpus/templates/design/app/components/design/TokensPanel.tsx +11 -11
  181. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -7
  182. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1129 -155
  183. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +130 -37
  184. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +24 -11
  185. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +184 -162
  186. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +137 -79
  187. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +13 -13
  188. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +8 -8
  189. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +2 -2
  190. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +4 -4
  191. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +3 -3
  192. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -7
  193. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +14 -11
  194. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +4 -4
  195. package/corpus/templates/design/app/components/design/inspector/index.ts +2 -0
  196. package/corpus/templates/design/app/components/design/types.ts +19 -0
  197. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +61 -78
  198. package/corpus/templates/design/app/components/layout/Header.tsx +0 -1
  199. package/corpus/templates/design/app/components/layout/Layout.tsx +3 -2
  200. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  201. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +5 -4
  202. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
  203. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +2 -2
  204. package/corpus/templates/design/app/global.css +56 -0
  205. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -5
  206. package/corpus/templates/design/app/hooks/use-navigation-state.ts +6 -7
  207. package/corpus/templates/design/app/hooks/use-question-flow.ts +3 -2
  208. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +6 -4
  209. package/corpus/templates/design/app/i18n/zh-TW.ts +5 -14
  210. package/corpus/templates/design/app/i18n-data.ts +63 -188
  211. package/corpus/templates/design/app/lib/agent-chat.ts +13 -0
  212. package/corpus/templates/design/app/pages/DesignEditor.tsx +1428 -384
  213. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +9 -5
  214. package/corpus/templates/design/app/pages/DesignSystems.tsx +2 -2
  215. package/corpus/templates/design/app/pages/Index.tsx +49 -26
  216. package/corpus/templates/design/app/pages/NotFound.tsx +25 -8
  217. package/corpus/templates/design/app/pages/VisualEdit.tsx +17 -5
  218. package/corpus/templates/design/app/routes/examples.tsx +1 -7
  219. package/corpus/templates/design/app/routes/templates.tsx +7 -4
  220. package/corpus/templates/design/changelog/2026-06-30-board-shapes-and-auto-layout-controls-are-clearer.md +6 -0
  221. package/corpus/templates/design/changelog/2026-06-30-component-selections-now-use-purple-component-chrome-and-sho.md +6 -0
  222. package/corpus/templates/design/changelog/2026-06-30-constraints-now-stay-tucked-into-a-compact-inspector-preview.md +6 -0
  223. package/corpus/templates/design/changelog/2026-06-30-creating-a-component-now-opens-in-a-compact-inspector-popove.md +6 -0
  224. package/corpus/templates/design/changelog/2026-06-30-design-cards-no-longer-show-legacy-project-type-badges.md +6 -0
  225. package/corpus/templates/design/changelog/2026-06-30-design-chat-now-keeps-new-turns-in-the-visible-design-agent-.md +6 -0
  226. package/corpus/templates/design/changelog/2026-06-30-design-editor-panels-now-keep-their-compact-text-sizing-cons.md +6 -0
  227. package/corpus/templates/design/changelog/2026-06-30-design-no-longer-shows-the-connected-local-code-warning-bann.md +6 -0
  228. package/corpus/templates/design/changelog/2026-06-30-design-now-opens-to-the-files-panel-unless-a-generation-is-a.md +6 -0
  229. package/corpus/templates/design/changelog/2026-06-30-design-opens-with-a-cleaner-empty-canvas-and-loading-preview.md +6 -0
  230. package/corpus/templates/design/changelog/2026-06-30-design-tools-use-simpler-less-decorative-icons.md +6 -0
  231. package/corpus/templates/design/changelog/2026-06-30-dragging-absolute-elements-no-longer-shows-coordinate-labels.md +6 -0
  232. package/corpus/templates/design/changelog/2026-06-30-fixed-all-screens-opening-too-zoomed-in-by-default.md +6 -0
  233. package/corpus/templates/design/changelog/2026-06-30-fixed-the-public-design-assets-sidebar-so-native-components-.md +6 -0
  234. package/corpus/templates/design/changelog/2026-06-30-fixed-the-screen-overview-board-so-empty-board-space-no-long.md +6 -0
  235. package/corpus/templates/design/changelog/2026-06-30-full-view-screens-can-now-scroll-while-remaining-editable.md +6 -0
  236. package/corpus/templates/design/changelog/2026-06-30-inspector-element-headers-show-the-selected-html-tag-and-the.md +6 -0
  237. package/corpus/templates/design/changelog/2026-06-30-inspector-inputs-stay-compact-across-desktop-breakpoints.md +6 -0
  238. package/corpus/templates/design/changelog/2026-06-30-layers-can-be-multi-selected-from-the-canvas-and-edited-toge.md +6 -0
  239. package/corpus/templates/design/changelog/2026-06-30-local-visual-edit-links-can-edit-localhost-frames-without-si.md +6 -0
  240. package/corpus/templates/design/changelog/2026-06-30-localhost-visual-edit-frames-can-now-be-selected-and-edited.md +6 -0
  241. package/corpus/templates/design/changelog/2026-06-30-marquee-selection-now-works-inside-screens-multi-selected-la.md +6 -0
  242. package/corpus/templates/design/changelog/2026-06-30-motion-is-now-available-from-the-persistent-left-rail-and-th.md +6 -0
  243. package/corpus/templates/design/changelog/2026-06-30-motion-timeline-collapse-and-reopen-animations-feel-smoother.md +6 -0
  244. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +6 -0
  245. package/corpus/templates/design/changelog/2026-06-30-new-board-shapes-now-start-with-neutral-gray-styling.md +6 -0
  246. package/corpus/templates/design/changelog/2026-06-30-new-designs-open-into-a-steadier-loading-state-before-the-ed.md +6 -0
  247. package/corpus/templates/design/changelog/2026-06-30-new-designs-show-a-loading-state-during-handoff-and-keep-edi.md +6 -0
  248. package/corpus/templates/design/changelog/2026-06-30-public-visual-edit-design-links-now-open-directly-instead-of.md +6 -0
  249. package/corpus/templates/design/changelog/2026-06-30-removed-the-confusing-states-section-from-the-design-editor-.md +6 -0
  250. package/corpus/templates/design/changelog/2026-06-30-removed-the-templates-gallery-from-design-navigation.md +6 -0
  251. package/corpus/templates/design/changelog/2026-06-30-share-stays-visible-as-soon-as-editable-designs-load.md +6 -0
  252. package/corpus/templates/design/changelog/2026-06-30-signed-out-save-and-share-controls-use-simpler-labels-and-op.md +6 -0
  253. package/corpus/templates/design/changelog/2026-06-30-text-added-on-the-canvas-now-focuses-cleanly-with-the-right-.md +6 -0
  254. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-is-simpler-and-its-bottom.md +6 -0
  255. package/corpus/templates/design/changelog/2026-06-30-the-design-editor-loading-skeleton-now-follows-the-current-t.md +6 -0
  256. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-child-layout-controls-o.md +6 -0
  257. package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-no-longer-shows-the-ask-ai-section-abov.md +6 -0
  258. package/corpus/templates/design/changelog/2026-06-30-the-design-review-panel-no-longer-shows-a-separate-inline-au.md +6 -0
  259. package/corpus/templates/design/changelog/2026-06-30-the-empty-designs-page-now-focuses-on-a-single-primary-new-d.md +6 -0
  260. package/corpus/templates/design/changelog/2026-06-30-the-layers-panel-header-stays-as-layers-while-multiple-items.md +6 -0
  261. package/corpus/templates/design/changelog/2026-06-30-the-missing-design-screen-now-uses-a-neutral-back-button.md +6 -0
  262. package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-now-closes-without-squeezing-the-canvas-.md +6 -0
  263. package/corpus/templates/design/changelog/2026-06-30-the-new-design-connect-ai-setup-now-lines-up-with-the-compos.md +6 -0
  264. package/corpus/templates/design/changelog/2026-06-30-the-screen-overview-board-now-blends-into-the-canvas-and-new.md +6 -0
  265. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-drops-now-show-screen-guides.md +6 -0
  266. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-keep-a-transparent-backdrop-and-.md +6 -0
  267. package/corpus/templates/design/changelog/2026-06-30-top-level-canvas-layers-now-select-reliably-from-all-screens.md +6 -0
  268. package/corpus/templates/design/changelog/2026-06-30-visual-edit-can-open-and-refresh-localhost-screens-in-one-au.md +6 -0
  269. package/corpus/templates/design/e2e/helpers.ts +15 -4
  270. package/corpus/templates/design/server/db/index.ts +52 -0
  271. package/corpus/templates/design/server/plugins/agent-chat.ts +5 -0
  272. package/corpus/templates/design/server/plugins/auth.ts +1 -0
  273. package/corpus/templates/design/server/plugins/core-routes.ts +4 -0
  274. package/corpus/templates/design/shared/board-file.ts +380 -5
  275. package/corpus/templates/design/shared/board-objects.ts +2 -2
  276. package/corpus/templates/design/shared/code-layer.ts +50 -6
  277. package/corpus/templates/design/shared/motion-compiler.ts +27 -0
  278. package/corpus/templates/macros/app/components/DailyProgress.tsx +41 -37
  279. package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
  280. package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
  281. package/corpus/templates/macros/app/components/VoiceDictation.tsx +1 -1
  282. package/corpus/templates/macros/app/components/WeeklyCaloriesChart.tsx +1 -1
  283. package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
  284. package/corpus/templates/macros/app/components/WeightTracker.tsx +1 -1
  285. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -1
  286. package/corpus/templates/macros/app/routes/_index.tsx +5 -5
  287. package/corpus/templates/macros/app/routes/analytics.tsx +1 -1
  288. package/corpus/templates/macros/changelog/2026-06-30-dashboard-loading-and-chart-surfaces-now-use-theme-aware-col.md +6 -0
  289. package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +14 -11
  290. package/corpus/templates/mail/app/global.css +3 -2
  291. package/corpus/templates/mail/changelog/2026-06-30-compose-floating-toolbars-now-use-theme-aware-colors-in-ligh.md +6 -0
  292. package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -2
  293. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +3 -3
  294. package/corpus/templates/slides/app/global.css +10 -0
  295. package/corpus/templates/slides/app/pages/Index.tsx +55 -51
  296. package/corpus/templates/slides/changelog/2026-06-30-deck-thumbnails-collapse-cleanly-to-one-column-when-the-chat.md +6 -0
  297. package/dist/agent/engine/anthropic-engine.d.ts +2 -2
  298. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  299. package/dist/agent/engine/builder-engine.d.ts +2 -2
  300. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  301. package/dist/agent/engine/builtin.js +1 -1
  302. package/dist/agent/engine/builtin.js.map +1 -1
  303. package/dist/agent/engine/output-tokens.js +1 -1
  304. package/dist/agent/engine/output-tokens.js.map +1 -1
  305. package/dist/agent/harness/acp-adapter.d.ts +4 -1
  306. package/dist/agent/harness/acp-adapter.d.ts.map +1 -1
  307. package/dist/agent/harness/acp-adapter.js +19 -2
  308. package/dist/agent/harness/acp-adapter.js.map +1 -1
  309. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  310. package/dist/agent/harness/ai-sdk-adapter.js +3 -0
  311. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  312. package/dist/agent/harness/translate.d.ts.map +1 -1
  313. package/dist/agent/harness/translate.js +3 -0
  314. package/dist/agent/harness/translate.js.map +1 -1
  315. package/dist/agent/harness/types.d.ts +1 -0
  316. package/dist/agent/harness/types.d.ts.map +1 -1
  317. package/dist/agent/harness/types.js.map +1 -1
  318. package/dist/agent/model-config.d.ts +21 -20
  319. package/dist/agent/model-config.d.ts.map +1 -1
  320. package/dist/agent/model-config.js +31 -13
  321. package/dist/agent/model-config.js.map +1 -1
  322. package/dist/agent/production-agent.d.ts.map +1 -1
  323. package/dist/agent/production-agent.js +85 -10
  324. package/dist/agent/production-agent.js.map +1 -1
  325. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  326. package/dist/agent/thread-data-builder.js +27 -6
  327. package/dist/agent/thread-data-builder.js.map +1 -1
  328. package/dist/agent/tool-call-journal.d.ts +11 -9
  329. package/dist/agent/tool-call-journal.d.ts.map +1 -1
  330. package/dist/agent/tool-call-journal.js +92 -40
  331. package/dist/agent/tool-call-journal.js.map +1 -1
  332. package/dist/agent/types.d.ts +5 -1
  333. package/dist/agent/types.d.ts.map +1 -1
  334. package/dist/agent/types.js.map +1 -1
  335. package/dist/cli/design-connect.d.ts.map +1 -1
  336. package/dist/cli/design-connect.js +84 -0
  337. package/dist/cli/design-connect.js.map +1 -1
  338. package/dist/cli/gateway-helpers.d.ts +4 -0
  339. package/dist/cli/gateway-helpers.d.ts.map +1 -1
  340. package/dist/cli/gateway-helpers.js +9 -0
  341. package/dist/cli/gateway-helpers.js.map +1 -1
  342. package/dist/cli/recap.d.ts.map +1 -1
  343. package/dist/cli/recap.js +0 -2
  344. package/dist/cli/recap.js.map +1 -1
  345. package/dist/cli/skills.d.ts.map +1 -1
  346. package/dist/cli/skills.js +54 -16
  347. package/dist/cli/skills.js.map +1 -1
  348. package/dist/cli/workspace-dev.d.ts.map +1 -1
  349. package/dist/cli/workspace-dev.js +33 -6
  350. package/dist/cli/workspace-dev.js.map +1 -1
  351. package/dist/client/AssistantChat.d.ts.map +1 -1
  352. package/dist/client/AssistantChat.js +72 -26
  353. package/dist/client/AssistantChat.js.map +1 -1
  354. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  355. package/dist/client/DefaultSpinner.js +8 -1
  356. package/dist/client/DefaultSpinner.js.map +1 -1
  357. package/dist/client/chat/message-components.d.ts +7 -1
  358. package/dist/client/chat/message-components.d.ts.map +1 -1
  359. package/dist/client/chat/message-components.js +37 -1
  360. package/dist/client/chat/message-components.js.map +1 -1
  361. package/dist/client/chat/repo-helpers.d.ts +1 -0
  362. package/dist/client/chat/repo-helpers.d.ts.map +1 -1
  363. package/dist/client/chat/repo-helpers.js +59 -0
  364. package/dist/client/chat/repo-helpers.js.map +1 -1
  365. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  366. package/dist/client/chat/run-recovery.js +4 -4
  367. package/dist/client/chat/run-recovery.js.map +1 -1
  368. package/dist/client/components/ApiKeySettings.js +8 -8
  369. package/dist/client/components/ApiKeySettings.js.map +1 -1
  370. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  371. package/dist/client/components/CodeRequiredDialog.js +24 -15
  372. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  373. package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
  374. package/dist/client/components/MissingKeyCard.js +11 -6
  375. package/dist/client/components/MissingKeyCard.js.map +1 -1
  376. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  377. package/dist/client/composer/TiptapComposer.js +4 -3
  378. package/dist/client/composer/TiptapComposer.js.map +1 -1
  379. package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
  380. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  381. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  382. package/dist/client/guided-questions.d.ts.map +1 -1
  383. package/dist/client/guided-questions.js +6 -6
  384. package/dist/client/guided-questions.js.map +1 -1
  385. package/dist/client/integrations/IntegrationCard.js +1 -1
  386. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  387. package/dist/client/integrations/IntegrationsPanel.js +1 -1
  388. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  389. package/dist/client/onboarding/OnboardingBanner.js +2 -2
  390. package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
  391. package/dist/client/onboarding/OnboardingPanel.js +23 -19
  392. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  393. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  394. package/dist/client/resources/ResourceEditor.js +13 -10
  395. package/dist/client/resources/ResourceEditor.js.map +1 -1
  396. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  397. package/dist/client/resources/ResourcesPanel.js +2 -1
  398. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  399. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  400. package/dist/client/settings/SettingsPanel.js +8 -3
  401. package/dist/client/settings/SettingsPanel.js.map +1 -1
  402. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  403. package/dist/client/settings/useBuilderStatus.js +6 -38
  404. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  405. package/dist/client/useProductionAgent.d.ts +2 -1
  406. package/dist/client/useProductionAgent.d.ts.map +1 -1
  407. package/dist/client/useProductionAgent.js.map +1 -1
  408. package/dist/collab/awareness.d.ts +2 -2
  409. package/dist/collab/awareness.d.ts.map +1 -1
  410. package/dist/collab/routes.d.ts +1 -1
  411. package/dist/deploy/build.js +1 -1
  412. package/dist/deploy/build.js.map +1 -1
  413. package/dist/eval/define-eval.d.ts.map +1 -1
  414. package/dist/eval/define-eval.js +2 -1
  415. package/dist/eval/define-eval.js.map +1 -1
  416. package/dist/eval/report.d.ts.map +1 -1
  417. package/dist/eval/report.js +19 -4
  418. package/dist/eval/report.js.map +1 -1
  419. package/dist/eval/runner.d.ts.map +1 -1
  420. package/dist/eval/runner.js +38 -6
  421. package/dist/eval/runner.js.map +1 -1
  422. package/dist/eval/types.d.ts +11 -0
  423. package/dist/eval/types.d.ts.map +1 -1
  424. package/dist/eval/types.js.map +1 -1
  425. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  426. package/dist/notifications/routes.d.ts +3 -3
  427. package/dist/observability/routes.d.ts +5 -5
  428. package/dist/observability/traces.d.ts.map +1 -1
  429. package/dist/observability/traces.js.map +1 -1
  430. package/dist/onboarding/default-steps.js +1 -1
  431. package/dist/onboarding/default-steps.js.map +1 -1
  432. package/dist/progress/routes.d.ts +1 -1
  433. package/dist/resources/handlers.d.ts +1 -1
  434. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  435. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  436. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  437. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  438. package/dist/server/agent-chat-plugin.d.ts +3 -0
  439. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  440. package/dist/server/agent-chat-plugin.js +134 -72
  441. package/dist/server/agent-chat-plugin.js.map +1 -1
  442. package/dist/server/core-routes-plugin.d.ts +3 -0
  443. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  444. package/dist/server/core-routes-plugin.js +4 -1
  445. package/dist/server/core-routes-plugin.js.map +1 -1
  446. package/dist/server/open-route.d.ts +9 -0
  447. package/dist/server/open-route.d.ts.map +1 -1
  448. package/dist/server/open-route.js +48 -38
  449. package/dist/server/open-route.js.map +1 -1
  450. package/dist/shared/reasoning-effort.js +3 -0
  451. package/dist/shared/reasoning-effort.js.map +1 -1
  452. package/dist/sharing/access.d.ts.map +1 -1
  453. package/dist/sharing/access.js +18 -2
  454. package/dist/sharing/access.js.map +1 -1
  455. package/dist/sharing/registry.d.ts +10 -0
  456. package/dist/sharing/registry.d.ts.map +1 -1
  457. package/dist/sharing/registry.js.map +1 -1
  458. package/dist/styles/agent-native.css +104 -20
  459. package/dist/styles/rich-markdown-editor.css +11 -10
  460. package/docs/content/cloneable-saas.mdx +2 -2
  461. package/docs/content/evals.mdx +34 -12
  462. package/docs/content/faq.mdx +1 -1
  463. package/docs/content/locales/ar-SA/cloneable-saas.mdx +2 -2
  464. package/docs/content/locales/ar-SA/evals.mdx +7 -0
  465. package/docs/content/locales/ar-SA/faq.mdx +1 -1
  466. package/docs/content/locales/ar-SA/template-chat.mdx +1 -1
  467. package/docs/content/locales/de-DE/cloneable-saas.mdx +2 -2
  468. package/docs/content/locales/de-DE/evals.mdx +8 -0
  469. package/docs/content/locales/de-DE/faq.mdx +1 -1
  470. package/docs/content/locales/de-DE/template-chat.mdx +1 -1
  471. package/docs/content/locales/es-ES/cloneable-saas.mdx +2 -2
  472. package/docs/content/locales/es-ES/evals.mdx +8 -0
  473. package/docs/content/locales/es-ES/faq.mdx +1 -1
  474. package/docs/content/locales/es-ES/template-chat.mdx +1 -1
  475. package/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  476. package/docs/content/locales/fr-FR/evals.mdx +8 -0
  477. package/docs/content/locales/fr-FR/faq.mdx +1 -1
  478. package/docs/content/locales/fr-FR/template-chat.mdx +1 -1
  479. package/docs/content/locales/hi-IN/cloneable-saas.mdx +2 -2
  480. package/docs/content/locales/hi-IN/evals.mdx +8 -0
  481. package/docs/content/locales/hi-IN/faq.mdx +1 -1
  482. package/docs/content/locales/hi-IN/template-chat.mdx +1 -1
  483. package/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  484. package/docs/content/locales/ja-JP/evals.mdx +7 -0
  485. package/docs/content/locales/ja-JP/faq.mdx +1 -1
  486. package/docs/content/locales/ja-JP/template-chat.mdx +1 -1
  487. package/docs/content/locales/ko-KR/cloneable-saas.mdx +2 -2
  488. package/docs/content/locales/ko-KR/evals.mdx +7 -0
  489. package/docs/content/locales/ko-KR/faq.mdx +1 -1
  490. package/docs/content/locales/ko-KR/template-chat.mdx +1 -1
  491. package/docs/content/locales/pt-BR/cloneable-saas.mdx +2 -2
  492. package/docs/content/locales/pt-BR/evals.mdx +8 -0
  493. package/docs/content/locales/pt-BR/faq.mdx +1 -1
  494. package/docs/content/locales/pt-BR/template-chat.mdx +1 -1
  495. package/docs/content/locales/zh-CN/cloneable-saas.mdx +2 -2
  496. package/docs/content/locales/zh-CN/evals.mdx +7 -0
  497. package/docs/content/locales/zh-CN/faq.mdx +1 -1
  498. package/docs/content/locales/zh-CN/template-chat.mdx +1 -1
  499. package/docs/content/locales/zh-TW/cloneable-saas.mdx +2 -2
  500. package/docs/content/locales/zh-TW/evals.mdx +7 -0
  501. package/docs/content/locales/zh-TW/faq.mdx +1 -1
  502. package/docs/content/locales/zh-TW/template-chat.mdx +1 -1
  503. package/docs/content/template-chat.mdx +1 -1
  504. package/package.json +1 -1
  505. package/corpus/templates/content/server/routes/api/notion/disconnect.post.ts +0 -12
  506. package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +0 -157
  507. package/corpus/templates/design/app/lib/design-templates.ts +0 -1305
  508. package/corpus/templates/design/app/pages/Templates.tsx +0 -279
@@ -8,16 +8,18 @@
8
8
  * told about any tool call that started but whose outcome was never recorded.
9
9
  *
10
10
  * IMPORTANT — this is a pure read-over-the-ledger view. There is no new
11
- * recording hook anywhere in the hot path. The classification reuses the exact
12
- * positional `tool_start` → `tool_done` matching that `thread-data-builder.ts`
13
- * already relies on to rebuild durable turns:
11
+ * recording hook anywhere in the hot path. Classification uses input-aware
12
+ * `tool_start` → `tool_done` matching when a `tool_done` event carries its
13
+ * input, while preserving the legacy positional fallback that older ledger
14
+ * events and `thread-data-builder.ts` rely on:
14
15
  *
15
16
  * - `tool_start` events carry `{ tool, input }` (no tool-call id at this
16
17
  * layer; the ledger event stream omits it).
17
- * - `tool_done` events carry `{ tool, result }`.
18
- * - A `tool_done` is matched to the OLDEST still-open `tool_start` for the
19
- * same tool name (FIFO per tool), mirroring how the dispatch loop emits a
20
- * start immediately before its matching done.
18
+ * - `tool_done` events carry `{ tool, input?, result }`.
19
+ * - A `tool_done` with input is matched to the open start with the same tool
20
+ * name and deep-canonicalized input.
21
+ * - A legacy `tool_done` without input is matched to the OLDEST still-open
22
+ * `tool_start` for the same tool name (FIFO per tool).
21
23
  *
22
24
  * A `tool_start` with no matching `tool_done` is the dangerous case: the call
23
25
  * began, its side effect may or may not have landed, and the interruption ate
@@ -36,23 +38,49 @@ const INPUT_SIGNATURE_MAX_CHARS = 120;
36
38
  /** Max length of a per-tool-call result summary surfaced in the resume note. */
37
39
  const RESULT_SUMMARY_MAX_CHARS = 400;
38
40
  function inputSignature(input) {
39
- if (!input)
41
+ if (input == null)
40
42
  return "";
41
- let sig;
42
43
  try {
43
- // Stable key order so the same logical input produces the same signature
44
- // regardless of how the engine serialized the object.
45
- const sorted = Object.keys(input)
46
- .sort()
47
- .reduce((acc, k) => {
48
- acc[k] = input[k];
49
- return acc;
50
- }, {});
51
- sig = JSON.stringify(sorted);
44
+ return JSON.stringify(canonicalizeForSignature(input));
52
45
  }
53
46
  catch {
54
- sig = String(input);
47
+ return String(input);
48
+ }
49
+ }
50
+ function canonicalizeForSignature(input, seen = new WeakSet()) {
51
+ if (input == null)
52
+ return input;
53
+ if (typeof input === "bigint")
54
+ return input.toString();
55
+ if (typeof input === "function" || typeof input === "symbol") {
56
+ return String(input);
57
+ }
58
+ if (typeof input !== "object")
59
+ return input;
60
+ if (seen.has(input))
61
+ return "[Circular]";
62
+ seen.add(input);
63
+ if (Array.isArray(input)) {
64
+ const output = input.map((value) => value === undefined
65
+ ? "[Undefined]"
66
+ : canonicalizeForSignature(value, seen));
67
+ seen.delete(input);
68
+ return output;
69
+ }
70
+ const object = input;
71
+ const output = {};
72
+ for (const key of Object.keys(object).sort()) {
73
+ const value = object[key];
74
+ output[key] =
75
+ value === undefined
76
+ ? "[Undefined]"
77
+ : canonicalizeForSignature(value, seen);
55
78
  }
79
+ seen.delete(input);
80
+ return output;
81
+ }
82
+ function displayInputSignature(input) {
83
+ const sig = inputSignature(input);
56
84
  return sig.length > INPUT_SIGNATURE_MAX_CHARS
57
85
  ? sig.slice(0, INPUT_SIGNATURE_MAX_CHARS)
58
86
  : sig;
@@ -65,10 +93,9 @@ function inputSignature(input) {
65
93
  * doesn't leave phantom open tool calls.
66
94
  */
67
95
  export function classifyToolCallJournal(events) {
68
- // Open tool_start entries awaiting a matching tool_done, in FIFO order. We
69
- // index by tool name so a tool_done matches the OLDEST open start for that
70
- // same tool the dispatch loop always emits start-then-done per call, so the
71
- // first unmatched start of a given name is the one this done belongs to.
96
+ // Open tool_start entries awaiting a matching tool_done. We index by tool
97
+ // name first, then prefer matching input signatures when the done event
98
+ // carries input. Older ledger entries without done input fall back to FIFO.
72
99
  const openByTool = new Map();
73
100
  const completed = [];
74
101
  let order = 0;
@@ -81,9 +108,9 @@ export function classifyToolCallJournal(events) {
81
108
  }
82
109
  if (event.type === "tool_start") {
83
110
  const tool = event.tool ?? "unknown";
84
- const input = (event.input ?? undefined);
111
+ const input = event.input ?? undefined;
85
112
  const entry = {
86
- key: `${tool}#${order}:${inputSignature(input)}`,
113
+ key: `${tool}#${order}:${displayInputSignature(input)}`,
87
114
  tool,
88
115
  ...(input ? { input } : {}),
89
116
  order,
@@ -99,8 +126,14 @@ export function classifyToolCallJournal(events) {
99
126
  if (event.type === "tool_done") {
100
127
  const tool = event.tool ?? "unknown";
101
128
  const queue = openByTool.get(tool);
102
- const entry = queue?.shift();
129
+ const entry = takeMatchingOpenEntry(queue, event);
103
130
  if (entry) {
131
+ if (isNonCompletedToolDone(event)) {
132
+ // Failed/blocked calls reached a terminal tool_done, but their side
133
+ // effect did not complete. Drop the matching start instead of
134
+ // classifying it as completed or interrupted.
135
+ continue;
136
+ }
104
137
  entry.result = event.result ?? "";
105
138
  completed.push(entry);
106
139
  }
@@ -118,6 +151,37 @@ export function classifyToolCallJournal(events) {
118
151
  interrupted.sort((a, b) => a.order - b.order);
119
152
  return { completed, interrupted };
120
153
  }
154
+ function takeMatchingOpenEntry(queue, event) {
155
+ if (!queue || queue.length === 0)
156
+ return undefined;
157
+ if (event.input !== undefined) {
158
+ const doneSig = inputSignature(event.input);
159
+ const index = queue.findIndex((entry) => inputSignature(entry.input) === doneSig);
160
+ if (index >= 0)
161
+ return queue.splice(index, 1)[0];
162
+ }
163
+ return queue.shift();
164
+ }
165
+ function isNonCompletedToolDone(event) {
166
+ if (event.completedSideEffect === false)
167
+ return true;
168
+ if (event.isError === true)
169
+ return true;
170
+ const result = (event.result ?? "").trim();
171
+ if (!result)
172
+ return false;
173
+ // Legacy run events did not persist isError. Keep known non-execution results
174
+ // from becoming durable "completed" write calls after deploy.
175
+ return (result.startsWith("Error: Unknown tool") ||
176
+ result.startsWith("Error running ") ||
177
+ result.startsWith("Invalid action parameters for ") ||
178
+ result.startsWith("Plan mode blocked ") ||
179
+ result.startsWith("Skipped ") ||
180
+ result.startsWith("Stopped after ") ||
181
+ result.startsWith("The tool was not executed") ||
182
+ result.startsWith("Awaiting human approval") ||
183
+ result.includes(" did NOT execute"));
184
+ }
121
185
  /** True when the journal has nothing worth telling a resuming model about. */
122
186
  export function isJournalEmpty(journal) {
123
187
  return journal.completed.length === 0 && journal.interrupted.length === 0;
@@ -137,7 +201,7 @@ export function isJournalEmpty(journal) {
137
201
  * including every fresh call, which must execute normally.
138
202
  */
139
203
  export function findCompletedJournalEntry(journal, toolName, input, consumedKeys) {
140
- const wantSig = inputSignature(normalizeInputForSignature(input));
204
+ const wantSig = inputSignature(input);
141
205
  for (const entry of journal.completed) {
142
206
  if (entry.tool !== toolName)
143
207
  continue;
@@ -150,18 +214,6 @@ export function findCompletedJournalEntry(journal, toolName, input, consumedKeys
150
214
  }
151
215
  return undefined;
152
216
  }
153
- /**
154
- * Coerce an arbitrary tool input into the `Record<string, string>` shape the
155
- * journal recorded at `tool_start` so signatures compare apples-to-apples. The
156
- * ledger stores `tool_start.input` as a string map; the live call's `input` is
157
- * the parsed object — both pass through `inputSignature`, which sorts keys and
158
- * JSON-stringifies, so a plain object compares correctly.
159
- */
160
- function normalizeInputForSignature(input) {
161
- if (input == null || typeof input !== "object")
162
- return undefined;
163
- return input;
164
- }
165
217
  function summarizeResult(result) {
166
218
  if (!result)
167
219
  return "(no result recorded)";
@@ -175,7 +227,7 @@ function summarizeResult(result) {
175
227
  function describeInput(input) {
176
228
  if (!input)
177
229
  return "";
178
- const sig = inputSignature(input);
230
+ const sig = displayInputSignature(input);
179
231
  return sig && sig !== "{}" ? ` input: ${sig}` : "";
180
232
  }
181
233
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tool-call-journal.js","sourceRoot":"","sources":["../../src/agent/tool-call-journal.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Per-turn tool-call journal — derived (not separately recorded) from the\n * existing run-event ledger. Borrowed from Flue's durable-execution journal:\n * when an agent run resumes after an interruption (gateway/transport drop, cold\n * start, soft-timeout auto-continue), we classify the tool calls already in the\n * ledger so the resumed model does NOT re-execute side effects it already\n * completed (re-sending an email, re-creating a ticket) and so it is explicitly\n * told about any tool call that started but whose outcome was never recorded.\n *\n * IMPORTANT — this is a pure read-over-the-ledger view. There is no new\n * recording hook anywhere in the hot path. The classification reuses the exact\n * positional `tool_start` → `tool_done` matching that `thread-data-builder.ts`\n * already relies on to rebuild durable turns:\n *\n * - `tool_start` events carry `{ tool, input }` (no tool-call id at this\n * layer; the ledger event stream omits it).\n * - `tool_done` events carry `{ tool, result }`.\n * - A `tool_done` is matched to the OLDEST still-open `tool_start` for the\n * same tool name (FIFO per tool), mirroring how the dispatch loop emits a\n * start immediately before its matching done.\n *\n * A `tool_start` with no matching `tool_done` is the dangerous case: the call\n * began, its side effect may or may not have landed, and the interruption ate\n * the result. We surface those as \"interrupted / unknown outcome\" so the model\n * decides rather than blindly re-running.\n *\n * Two layers of protection are built on this: (1) a prompt-level note on resume\n * (see `run-loop-with-resume.ts`) telling the model what already completed, and\n * (2) tool-layer enforcement in `production-agent.ts`/`runToolCall`, which uses\n * `findCompletedJournalEntry(...)` to refuse re-executing a journaled-complete\n * write tool — returning the journaled result instead of running the side\n * effect again. Layer 2 is the stronger guarantee.\n */\n\nimport type { AgentChatEvent } from \"./types.js\";\n\n/** A single recorded tool-call ledger entry, classified by outcome. */\nexport interface ToolCallJournalEntry {\n /**\n * Stable-ish identity for this tool call within the turn. The ledger event\n * stream has no tool-call id, so we key by tool name + a short input\n * signature + positional order, exactly enough to disambiguate repeats of the\n * same tool within one turn for human/model-readable reporting.\n */\n key: string;\n /** Tool / action name (from the `tool_start` event). */\n tool: string;\n /** Tool input captured at `tool_start`, if any. */\n input?: Record<string, string>;\n /** 0-based position of the `tool_start` among all tool calls in the turn. */\n order: number;\n /** Result text from the matched `tool_done`, when the call completed. */\n result?: string;\n}\n\n/** Result of classifying one turn's ledger events. */\nexport interface ToolCallJournal {\n /** Tool calls with a matching `tool_done` — already ran, do NOT re-run. */\n completed: ToolCallJournalEntry[];\n /**\n * Tool calls with a `tool_start` but no matching `tool_done` — interrupted,\n * outcome unknown. The model must decide whether re-running is safe.\n */\n interrupted: ToolCallJournalEntry[];\n}\n\n/** Max length of an input signature included in a journal key (debug-readable). */\nconst INPUT_SIGNATURE_MAX_CHARS = 120;\n\n/** Max length of a per-tool-call result summary surfaced in the resume note. */\nconst RESULT_SUMMARY_MAX_CHARS = 400;\n\nfunction inputSignature(input: Record<string, string> | undefined): string {\n if (!input) return \"\";\n let sig: string;\n try {\n // Stable key order so the same logical input produces the same signature\n // regardless of how the engine serialized the object.\n const sorted = Object.keys(input)\n .sort()\n .reduce<Record<string, string>>((acc, k) => {\n acc[k] = input[k];\n return acc;\n }, {});\n sig = JSON.stringify(sorted);\n } catch {\n sig = String(input);\n }\n return sig.length > INPUT_SIGNATURE_MAX_CHARS\n ? sig.slice(0, INPUT_SIGNATURE_MAX_CHARS)\n : sig;\n}\n\n/**\n * Classify a single turn's recorded events into completed vs interrupted tool\n * calls. Pure and side-effect free — given the same events it always returns\n * the same journal. A `clear` event resets the per-turn tally exactly as the\n * thread rebuild does, so partial streamed output that was discarded on resume\n * doesn't leave phantom open tool calls.\n */\nexport function classifyToolCallJournal(\n events: readonly AgentChatEvent[],\n): ToolCallJournal {\n // Open tool_start entries awaiting a matching tool_done, in FIFO order. We\n // index by tool name so a tool_done matches the OLDEST open start for that\n // same tool — the dispatch loop always emits start-then-done per call, so the\n // first unmatched start of a given name is the one this done belongs to.\n const openByTool = new Map<string, ToolCallJournalEntry[]>();\n const completed: ToolCallJournalEntry[] = [];\n let order = 0;\n\n for (const event of events) {\n if (event.type === \"clear\") {\n // Discarded partial output: drop any not-yet-completed starts so they\n // aren't reported as interrupted. Already-completed entries stay.\n openByTool.clear();\n continue;\n }\n\n if (event.type === \"tool_start\") {\n const tool = event.tool ?? \"unknown\";\n const input = (event.input ?? undefined) as\n | Record<string, string>\n | undefined;\n const entry: ToolCallJournalEntry = {\n key: `${tool}#${order}:${inputSignature(input)}`,\n tool,\n ...(input ? { input } : {}),\n order,\n };\n order += 1;\n const queue = openByTool.get(tool);\n if (queue) queue.push(entry);\n else openByTool.set(tool, [entry]);\n continue;\n }\n\n if (event.type === \"tool_done\") {\n const tool = event.tool ?? \"unknown\";\n const queue = openByTool.get(tool);\n const entry = queue?.shift();\n if (entry) {\n entry.result = event.result ?? \"\";\n completed.push(entry);\n }\n // A tool_done with no open start is ignored — it can't be re-associated\n // and re-reporting a duplicate done would be noise.\n continue;\n }\n }\n\n // Anything still open never received a tool_done → interrupted / unknown.\n const interrupted: ToolCallJournalEntry[] = [];\n for (const queue of openByTool.values()) {\n for (const entry of queue) interrupted.push(entry);\n }\n interrupted.sort((a, b) => a.order - b.order);\n\n return { completed, interrupted };\n}\n\n/** True when the journal has nothing worth telling a resuming model about. */\nexport function isJournalEmpty(journal: ToolCallJournal): boolean {\n return journal.completed.length === 0 && journal.interrupted.length === 0;\n}\n\n/**\n * Find a COMPLETED journal entry that matches a tool call about to be\n * dispatched, by tool name + input signature (position-independent — a resumed\n * call may sit at a different order than the original). Used by the tool-layer\n * hard-block in production-agent.ts/runToolCall to skip re-executing a side\n * effect that already completed in a prior interrupted chunk: when this returns\n * an entry, the loop returns `entry.result` instead of running the action.\n *\n * Returns the FIRST unmatched completed entry for that (name + input); the\n * caller is expected to claim it (mark it consumed) so two identical fresh\n * calls in the same turn don't both short-circuit on one journaled completion.\n * Returns undefined when there is no completed entry for this exact call —\n * including every fresh call, which must execute normally.\n */\nexport function findCompletedJournalEntry(\n journal: ToolCallJournal,\n toolName: string,\n input: unknown,\n consumedKeys?: Set<string>,\n): ToolCallJournalEntry | undefined {\n const wantSig = inputSignature(normalizeInputForSignature(input));\n for (const entry of journal.completed) {\n if (entry.tool !== toolName) continue;\n if (inputSignature(entry.input) !== wantSig) continue;\n if (consumedKeys?.has(entry.key)) continue;\n consumedKeys?.add(entry.key);\n return entry;\n }\n return undefined;\n}\n\n/**\n * Coerce an arbitrary tool input into the `Record<string, string>` shape the\n * journal recorded at `tool_start` so signatures compare apples-to-apples. The\n * ledger stores `tool_start.input` as a string map; the live call's `input` is\n * the parsed object — both pass through `inputSignature`, which sorts keys and\n * JSON-stringifies, so a plain object compares correctly.\n */\nfunction normalizeInputForSignature(\n input: unknown,\n): Record<string, string> | undefined {\n if (input == null || typeof input !== \"object\") return undefined;\n return input as Record<string, string>;\n}\n\nfunction summarizeResult(result: string | undefined): string {\n if (!result) return \"(no result recorded)\";\n const oneLine = result.replace(/\\s+/g, \" \").trim();\n if (oneLine.length === 0) return \"(empty result)\";\n return oneLine.length > RESULT_SUMMARY_MAX_CHARS\n ? oneLine.slice(0, RESULT_SUMMARY_MAX_CHARS) + \"…\"\n : oneLine;\n}\n\nfunction describeInput(input: Record<string, string> | undefined): string {\n if (!input) return \"\";\n const sig = inputSignature(input);\n return sig && sig !== \"{}\" ? ` input: ${sig}` : \"\";\n}\n\n/**\n * Build the structured resume note injected on auto-continue. Returns `null`\n * when there are no completed or interrupted tool calls to report, so the\n * caller can preserve the exact pre-existing \"continue from where you left off\"\n * behavior on normal resumes (no regression for turns with no tool activity).\n *\n * The note is intentionally a flat, model-readable block: a list of already-run\n * tool calls (with short results) the model must NOT re-run, and a separate list\n * of interrupted calls whose outcome is unknown for the model to decide on.\n */\nexport function buildResumeJournalNote(\n journal: ToolCallJournal,\n): string | null {\n if (isJournalEmpty(journal)) return null;\n\n const lines: string[] = [];\n lines.push(\n \"Tool-call journal from the interrupted attempt (derived from the durable run ledger):\",\n );\n\n if (journal.completed.length > 0) {\n lines.push(\"\");\n lines.push(\n \"Already completed (do NOT re-run these — their side effects already happened; reuse the results below):\",\n );\n for (const entry of journal.completed) {\n lines.push(\n `- ${entry.tool}${describeInput(entry.input)} → ${summarizeResult(entry.result)}`,\n );\n }\n }\n\n if (journal.interrupted.length > 0) {\n lines.push(\"\");\n lines.push(\n \"Interrupted / unknown outcome (these started but no result was recorded before the cut-off — do not assume they succeeded OR failed; if re-running could duplicate a side effect, verify state first):\",\n );\n for (const entry of journal.interrupted) {\n lines.push(\n `- ${entry.tool}${describeInput(entry.input)} → (no result recorded)`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"tool-call-journal.js","sourceRoot":"","sources":["../../src/agent/tool-call-journal.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Per-turn tool-call journal — derived (not separately recorded) from the\n * existing run-event ledger. Borrowed from Flue's durable-execution journal:\n * when an agent run resumes after an interruption (gateway/transport drop, cold\n * start, soft-timeout auto-continue), we classify the tool calls already in the\n * ledger so the resumed model does NOT re-execute side effects it already\n * completed (re-sending an email, re-creating a ticket) and so it is explicitly\n * told about any tool call that started but whose outcome was never recorded.\n *\n * IMPORTANT — this is a pure read-over-the-ledger view. There is no new\n * recording hook anywhere in the hot path. Classification uses input-aware\n * `tool_start` → `tool_done` matching when a `tool_done` event carries its\n * input, while preserving the legacy positional fallback that older ledger\n * events and `thread-data-builder.ts` rely on:\n *\n * - `tool_start` events carry `{ tool, input }` (no tool-call id at this\n * layer; the ledger event stream omits it).\n * - `tool_done` events carry `{ tool, input?, result }`.\n * - A `tool_done` with input is matched to the open start with the same tool\n * name and deep-canonicalized input.\n * - A legacy `tool_done` without input is matched to the OLDEST still-open\n * `tool_start` for the same tool name (FIFO per tool).\n *\n * A `tool_start` with no matching `tool_done` is the dangerous case: the call\n * began, its side effect may or may not have landed, and the interruption ate\n * the result. We surface those as \"interrupted / unknown outcome\" so the model\n * decides rather than blindly re-running.\n *\n * Two layers of protection are built on this: (1) a prompt-level note on resume\n * (see `run-loop-with-resume.ts`) telling the model what already completed, and\n * (2) tool-layer enforcement in `production-agent.ts`/`runToolCall`, which uses\n * `findCompletedJournalEntry(...)` to refuse re-executing a journaled-complete\n * write tool — returning the journaled result instead of running the side\n * effect again. Layer 2 is the stronger guarantee.\n */\n\nimport type { AgentChatEvent, AgentToolInput } from \"./types.js\";\n\n/** A single recorded tool-call ledger entry, classified by outcome. */\nexport interface ToolCallJournalEntry {\n /**\n * Stable-ish identity for this tool call within the turn. The ledger event\n * stream has no tool-call id, so we key by tool name + a short input\n * signature + positional order, exactly enough to disambiguate repeats of the\n * same tool within one turn for human/model-readable reporting.\n */\n key: string;\n /** Tool / action name (from the `tool_start` event). */\n tool: string;\n /** Tool input captured at `tool_start`, if any. */\n input?: AgentToolInput;\n /** 0-based position of the `tool_start` among all tool calls in the turn. */\n order: number;\n /** Result text from the matched `tool_done`, when the call completed. */\n result?: string;\n}\n\n/** Result of classifying one turn's ledger events. */\nexport interface ToolCallJournal {\n /** Tool calls with a matching `tool_done` — already ran, do NOT re-run. */\n completed: ToolCallJournalEntry[];\n /**\n * Tool calls with a `tool_start` but no matching `tool_done` — interrupted,\n * outcome unknown. The model must decide whether re-running is safe.\n */\n interrupted: ToolCallJournalEntry[];\n}\n\n/** Max length of an input signature included in a journal key (debug-readable). */\nconst INPUT_SIGNATURE_MAX_CHARS = 120;\n\n/** Max length of a per-tool-call result summary surfaced in the resume note. */\nconst RESULT_SUMMARY_MAX_CHARS = 400;\n\nfunction inputSignature(input: unknown): string {\n if (input == null) return \"\";\n try {\n return JSON.stringify(canonicalizeForSignature(input));\n } catch {\n return String(input);\n }\n}\n\nfunction canonicalizeForSignature(\n input: unknown,\n seen = new WeakSet(),\n): unknown {\n if (input == null) return input;\n if (typeof input === \"bigint\") return input.toString();\n if (typeof input === \"function\" || typeof input === \"symbol\") {\n return String(input);\n }\n if (typeof input !== \"object\") return input;\n\n if (seen.has(input)) return \"[Circular]\";\n seen.add(input);\n if (Array.isArray(input)) {\n const output = input.map((value) =>\n value === undefined\n ? \"[Undefined]\"\n : canonicalizeForSignature(value, seen),\n );\n seen.delete(input);\n return output;\n }\n\n const object = input as Record<string, unknown>;\n const output: Record<string, unknown> = {};\n for (const key of Object.keys(object).sort()) {\n const value = object[key];\n output[key] =\n value === undefined\n ? \"[Undefined]\"\n : canonicalizeForSignature(value, seen);\n }\n seen.delete(input);\n return output;\n}\n\nfunction displayInputSignature(input: unknown): string {\n const sig = inputSignature(input);\n return sig.length > INPUT_SIGNATURE_MAX_CHARS\n ? sig.slice(0, INPUT_SIGNATURE_MAX_CHARS)\n : sig;\n}\n\n/**\n * Classify a single turn's recorded events into completed vs interrupted tool\n * calls. Pure and side-effect free — given the same events it always returns\n * the same journal. A `clear` event resets the per-turn tally exactly as the\n * thread rebuild does, so partial streamed output that was discarded on resume\n * doesn't leave phantom open tool calls.\n */\nexport function classifyToolCallJournal(\n events: readonly AgentChatEvent[],\n): ToolCallJournal {\n // Open tool_start entries awaiting a matching tool_done. We index by tool\n // name first, then prefer matching input signatures when the done event\n // carries input. Older ledger entries without done input fall back to FIFO.\n const openByTool = new Map<string, ToolCallJournalEntry[]>();\n const completed: ToolCallJournalEntry[] = [];\n let order = 0;\n\n for (const event of events) {\n if (event.type === \"clear\") {\n // Discarded partial output: drop any not-yet-completed starts so they\n // aren't reported as interrupted. Already-completed entries stay.\n openByTool.clear();\n continue;\n }\n\n if (event.type === \"tool_start\") {\n const tool = event.tool ?? \"unknown\";\n const input = event.input ?? undefined;\n const entry: ToolCallJournalEntry = {\n key: `${tool}#${order}:${displayInputSignature(input)}`,\n tool,\n ...(input ? { input } : {}),\n order,\n };\n order += 1;\n const queue = openByTool.get(tool);\n if (queue) queue.push(entry);\n else openByTool.set(tool, [entry]);\n continue;\n }\n\n if (event.type === \"tool_done\") {\n const tool = event.tool ?? \"unknown\";\n const queue = openByTool.get(tool);\n const entry = takeMatchingOpenEntry(queue, event);\n if (entry) {\n if (isNonCompletedToolDone(event)) {\n // Failed/blocked calls reached a terminal tool_done, but their side\n // effect did not complete. Drop the matching start instead of\n // classifying it as completed or interrupted.\n continue;\n }\n entry.result = event.result ?? \"\";\n completed.push(entry);\n }\n // A tool_done with no open start is ignored — it can't be re-associated\n // and re-reporting a duplicate done would be noise.\n continue;\n }\n }\n\n // Anything still open never received a tool_done → interrupted / unknown.\n const interrupted: ToolCallJournalEntry[] = [];\n for (const queue of openByTool.values()) {\n for (const entry of queue) interrupted.push(entry);\n }\n interrupted.sort((a, b) => a.order - b.order);\n\n return { completed, interrupted };\n}\n\nfunction takeMatchingOpenEntry(\n queue: ToolCallJournalEntry[] | undefined,\n event: Extract<AgentChatEvent, { type: \"tool_done\" }>,\n): ToolCallJournalEntry | undefined {\n if (!queue || queue.length === 0) return undefined;\n if (event.input !== undefined) {\n const doneSig = inputSignature(event.input);\n const index = queue.findIndex(\n (entry) => inputSignature(entry.input) === doneSig,\n );\n if (index >= 0) return queue.splice(index, 1)[0];\n }\n return queue.shift();\n}\n\nfunction isNonCompletedToolDone(\n event: Extract<AgentChatEvent, { type: \"tool_done\" }>,\n): boolean {\n if (event.completedSideEffect === false) return true;\n if (event.isError === true) return true;\n\n const result = (event.result ?? \"\").trim();\n if (!result) return false;\n\n // Legacy run events did not persist isError. Keep known non-execution results\n // from becoming durable \"completed\" write calls after deploy.\n return (\n result.startsWith(\"Error: Unknown tool\") ||\n result.startsWith(\"Error running \") ||\n result.startsWith(\"Invalid action parameters for \") ||\n result.startsWith(\"Plan mode blocked \") ||\n result.startsWith(\"Skipped \") ||\n result.startsWith(\"Stopped after \") ||\n result.startsWith(\"The tool was not executed\") ||\n result.startsWith(\"Awaiting human approval\") ||\n result.includes(\" did NOT execute\")\n );\n}\n\n/** True when the journal has nothing worth telling a resuming model about. */\nexport function isJournalEmpty(journal: ToolCallJournal): boolean {\n return journal.completed.length === 0 && journal.interrupted.length === 0;\n}\n\n/**\n * Find a COMPLETED journal entry that matches a tool call about to be\n * dispatched, by tool name + input signature (position-independent — a resumed\n * call may sit at a different order than the original). Used by the tool-layer\n * hard-block in production-agent.ts/runToolCall to skip re-executing a side\n * effect that already completed in a prior interrupted chunk: when this returns\n * an entry, the loop returns `entry.result` instead of running the action.\n *\n * Returns the FIRST unmatched completed entry for that (name + input); the\n * caller is expected to claim it (mark it consumed) so two identical fresh\n * calls in the same turn don't both short-circuit on one journaled completion.\n * Returns undefined when there is no completed entry for this exact call —\n * including every fresh call, which must execute normally.\n */\nexport function findCompletedJournalEntry(\n journal: ToolCallJournal,\n toolName: string,\n input: unknown,\n consumedKeys?: Set<string>,\n): ToolCallJournalEntry | undefined {\n const wantSig = inputSignature(input);\n for (const entry of journal.completed) {\n if (entry.tool !== toolName) continue;\n if (inputSignature(entry.input) !== wantSig) continue;\n if (consumedKeys?.has(entry.key)) continue;\n consumedKeys?.add(entry.key);\n return entry;\n }\n return undefined;\n}\n\nfunction summarizeResult(result: string | undefined): string {\n if (!result) return \"(no result recorded)\";\n const oneLine = result.replace(/\\s+/g, \" \").trim();\n if (oneLine.length === 0) return \"(empty result)\";\n return oneLine.length > RESULT_SUMMARY_MAX_CHARS\n ? oneLine.slice(0, RESULT_SUMMARY_MAX_CHARS) + \"…\"\n : oneLine;\n}\n\nfunction describeInput(input: unknown): string {\n if (!input) return \"\";\n const sig = displayInputSignature(input);\n return sig && sig !== \"{}\" ? ` input: ${sig}` : \"\";\n}\n\n/**\n * Build the structured resume note injected on auto-continue. Returns `null`\n * when there are no completed or interrupted tool calls to report, so the\n * caller can preserve the exact pre-existing \"continue from where you left off\"\n * behavior on normal resumes (no regression for turns with no tool activity).\n *\n * The note is intentionally a flat, model-readable block: a list of already-run\n * tool calls (with short results) the model must NOT re-run, and a separate list\n * of interrupted calls whose outcome is unknown for the model to decide on.\n */\nexport function buildResumeJournalNote(\n journal: ToolCallJournal,\n): string | null {\n if (isJournalEmpty(journal)) return null;\n\n const lines: string[] = [];\n lines.push(\n \"Tool-call journal from the interrupted attempt (derived from the durable run ledger):\",\n );\n\n if (journal.completed.length > 0) {\n lines.push(\"\");\n lines.push(\n \"Already completed (do NOT re-run these — their side effects already happened; reuse the results below):\",\n );\n for (const entry of journal.completed) {\n lines.push(\n `- ${entry.tool}${describeInput(entry.input)} → ${summarizeResult(entry.result)}`,\n );\n }\n }\n\n if (journal.interrupted.length > 0) {\n lines.push(\"\");\n lines.push(\n \"Interrupted / unknown outcome (these started but no result was recorded before the cut-off — do not assume they succeeded OR failed; if re-running could duplicate a side effect, verify state first):\",\n );\n for (const entry of journal.interrupted) {\n lines.push(\n `- ${entry.tool}${describeInput(entry.input)} → (no result recorded)`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n"]}
@@ -191,6 +191,7 @@ export interface AgentChatRequest {
191
191
  */
192
192
  approvedToolCalls?: string[];
193
193
  }
194
+ export type AgentToolInput = Record<string, unknown>;
194
195
  export type AgentChatEvent = {
195
196
  type: "text";
196
197
  text: string;
@@ -206,11 +207,14 @@ export type AgentChatEvent = {
206
207
  } | {
207
208
  type: "tool_start";
208
209
  tool: string;
209
- input: Record<string, string>;
210
+ input: AgentToolInput;
210
211
  } | {
211
212
  type: "tool_done";
212
213
  tool: string;
214
+ input?: AgentToolInput;
213
215
  result: string;
216
+ isError?: boolean;
217
+ completedSideEffect?: boolean;
214
218
  mcpApp?: AgentMcpAppPayload;
215
219
  chatUI?: ActionChatUIConfig;
216
220
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ActionChatUIConfig } from \"../action-ui.js\";\nimport type { AgentMcpAppPayload } from \"../mcp-client/app-result.js\";\nimport type { ReasoningEffort } from \"../shared/reasoning-effort.js\";\n\nexport interface AgentNativeJsonSchema {\n type?: string | string[];\n description?: string;\n enum?: unknown[];\n const?: unknown;\n properties?: Record<string, AgentNativeJsonSchema>;\n required?: string[];\n additionalProperties?: boolean | AgentNativeJsonSchema;\n items?: AgentNativeJsonSchema;\n oneOf?: AgentNativeJsonSchema[];\n anyOf?: AgentNativeJsonSchema[];\n allOf?: AgentNativeJsonSchema[];\n not?: AgentNativeJsonSchema;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n minimum?: number;\n maximum?: number;\n minItems?: number;\n maxItems?: number;\n}\n\nexport interface ActionTool {\n description: string;\n parameters?: AgentNativeJsonSchema & {\n type: \"object\";\n properties: Record<string, AgentNativeJsonSchema>;\n required?: string[];\n };\n}\n\n/** @deprecated Use `ActionTool` instead */\nexport type ScriptTool = ActionTool;\n\nexport interface AgentMessage {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport type AgentChatStructuredContentPart =\n | { type: \"text\"; text: string }\n | {\n type: \"tool-call\";\n id?: string;\n toolCallId?: string;\n name?: string;\n toolName?: string;\n input?: unknown;\n args?: unknown;\n }\n | {\n type: \"tool-result\";\n toolCallId: string;\n /** Persisted for replay; omitted in older rows is backfilled server-side. */\n toolName?: string;\n toolInput?: string;\n content: string;\n isError?: boolean;\n };\n\nexport interface AgentChatStructuredMessage {\n role: \"user\" | \"assistant\";\n content: AgentChatStructuredContentPart[];\n}\n\nexport interface AgentChatReference {\n type: \"file\" | \"skill\" | \"mention\" | \"agent\" | \"custom-agent\";\n path: string;\n name: string;\n source: string;\n refType?: string;\n refId?: string;\n slotKey?: string;\n slotLabel?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface MentionProviderItem {\n id: string;\n label: string;\n description?: string;\n icon?: string;\n refType: string;\n refId?: string;\n refPath?: string;\n slotKey?: string;\n slotLabel?: string;\n metadata?: Record<string, unknown>;\n clearsSlots?: string[];\n relatedReferences?: MentionProviderReference[];\n}\n\nexport interface MentionProviderReference {\n label: string;\n icon?: string;\n source?: string;\n refType: string;\n refId?: string | null;\n refPath?: string | null;\n slotKey?: string;\n slotLabel?: string;\n metadata?: Record<string, unknown>;\n clearsSlots?: string[];\n relatedReferences?: MentionProviderReference[];\n}\n\nexport interface MentionProvider {\n label: string;\n icon?: string;\n search: (\n query: string,\n /** The H3 event for the current request — use to make internal API calls */\n event?: any,\n ) => MentionProviderItem[] | Promise<MentionProviderItem[]>;\n}\n\nexport interface AgentChatAttachment {\n type: string;\n name: string;\n data?: string;\n contentType?: string;\n text?: string;\n}\n\nexport interface AgentChatScope {\n type: string;\n id: string;\n label?: string;\n}\n\nexport interface AgentChatRequest {\n message: string;\n /**\n * User-visible text to persist in chat history. `message` may be normalized\n * for the model (for example mention markup or internal continuation text).\n */\n displayMessage?: string;\n history?: AgentMessage[];\n /**\n * Provider-neutral transcript used for run recovery. Unlike `history`,\n * this preserves assistant tool calls and matching tool results so\n * continuation turns do not re-run completed read-only tools.\n */\n structuredHistory?: AgentChatStructuredMessage[];\n references?: AgentChatReference[];\n threadId?: string;\n attachments?: AgentChatAttachment[];\n /** Internal retry/continuation requests should not create visible user turns. */\n internalContinuation?: boolean;\n /**\n * Internal marker set ONLY by the durable-background self-dispatch (see\n * `AGENT_CHAT_BACKGROUND_RUN_FIELD`). Present when the agent-chat handler is\n * re-entered as the background worker: it carries the pre-claimed `runId` and\n * logical `turnId` so the worker runs the loop inline with the background\n * soft-timeout instead of re-claiming the slot or re-dispatching. Untrusted\n * on its own — the `_process-run` route HMAC-verifies the dispatch before\n * invoking the handler. Absent on every normal client request.\n */\n __backgroundRun?: {\n runId: string;\n turnId?: string;\n /**\n * Number of server-driven background→background continuations already\n * chained into this logical turn (0 on the first chunk). The worker\n * increments this when it re-fires `_process-run` at a soft-timeout\n * boundary and refuses to chain past `MAX_BACKGROUND_RUN_CONTINUATIONS`.\n */\n continuationCount?: number;\n };\n /**\n * Stable identity for the logical assistant turn this request belongs to.\n * The client sends the SAME turnId for the initial POST and every\n * auto-continuation re-POST of one turn, so the server can fold each\n * continuation run's output onto a single durable assistant message instead\n * of dropping the earlier chunks. Defaults to the run id when absent.\n */\n turnId?: string;\n /** Execution mode for this turn. Plan mode is read-only and proposes before acting. */\n mode?: \"act\" | \"plan\";\n /** Per-request model override (ephemeral, from the composer model picker). */\n model?: string;\n /** Per-request engine override (sent alongside model for cross-provider switches). */\n engine?: string;\n /** Per-request reasoning effort override (ephemeral, from the composer picker). */\n effort?: ReasoningEffort;\n /** Usage-tracking label for this call (e.g. \"chat\", \"summarize\"). Default: \"chat\". */\n usageLabel?: string;\n /** Stable browser tab id so screen/url context and navigation commands are tab-scoped. */\n browserTabId?: string;\n /** Resource scope for this chat thread, e.g. the deck currently bound to the tab. */\n scope?: AgentChatScope | null;\n /** When true, expose this chat turn as a user-visible run in RunsTray. */\n trackInRunsTray?: boolean;\n /**\n * Approval grants for human-in-the-loop actions. Each entry is a stable\n * approval key (see the `approval_required` event's `approvalKey`). When the\n * agent calls an action declared `needsApproval`, the loop pauses and emits\n * `approval_required`; the client re-issues the turn (typically an empty\n * continuation) with the approved call's key here so the gate lets it run.\n * Keys not present here keep the action paused. The model never sees or sets\n * this — it is supplied by the human's approve affordance.\n */\n approvedToolCalls?: string[];\n}\n\nexport type AgentChatEvent =\n | { type: \"text\"; text: string }\n | { type: \"thinking\"; text: string }\n | { type: \"activity\"; label: string; tool?: string }\n | { type: \"stream_keepalive\" }\n | { type: \"tool_start\"; tool: string; input: Record<string, string> }\n | {\n type: \"tool_done\";\n tool: string;\n result: string;\n mcpApp?: AgentMcpAppPayload;\n chatUI?: ActionChatUIConfig;\n }\n | {\n /**\n * The agent tried to call an action declared `needsApproval` and the loop\n * paused instead of executing it. The client should surface an\n * approve/deny affordance; on approve, re-issue the turn with\n * `approvedToolCalls: [approvalKey]` so the gate lets this call run.\n */\n type: \"approval_required\";\n tool: string;\n input: Record<string, string>;\n /** Stable key the client echoes back in `approvedToolCalls` to approve. */\n approvalKey: string;\n /** The model-side tool-call id for this paused call, when available. */\n toolCallId?: string;\n }\n | {\n type: \"agent_call\";\n agent: string;\n status: \"start\" | \"done\" | \"error\";\n }\n | { type: \"agent_call_text\"; agent: string; text: string }\n | {\n type: \"agent_task\";\n taskId: string;\n threadId: string;\n description: string;\n status: \"running\" | \"completed\" | \"errored\";\n }\n | {\n type: \"agent_task_update\";\n taskId: string;\n preview: string;\n currentStep?: string;\n }\n | {\n type: \"agent_task_complete\";\n taskId: string;\n summary: string;\n }\n | { type: \"done\" }\n | {\n type: \"error\";\n error: string;\n /**\n * Optional machine-readable error code. Builder gateway uses codes\n * like \"credits-limit-monthly\" / \"unauthorized\" / \"gateway_not_enabled\"\n * so the chat UI can render a structured CTA (e.g. upgrade button).\n */\n errorCode?: string;\n /** Optional link paired with errorCode — e.g. Builder billing page. */\n upgradeUrl?: string;\n /** Optional details for expandable UI/debugging. */\n details?: string;\n /** True when the user can reasonably continue/retry from partial work. */\n recoverable?: boolean;\n }\n /**\n * Legacy SSE terminal event. New streams emit\n * `{ type: \"error\", errorCode: \"missing_credentials\" }` instead.\n */\n | { type: \"missing_api_key\" }\n | { type: \"loop_limit\"; maxIterations?: number }\n | {\n /**\n * An in-loop `Processor` aborted the run via `abort()` (which throws a\n * `TripWire`). The loop catches it, emits this event, stops cleanly, and\n * surfaces the reason as a final assistant message. Structural hook for\n * real-time guardrails and a proof-of-done / coverage gate.\n */\n type: \"tripwire\";\n reason: string;\n /** Name of the processor that aborted, when it declared one. */\n processor?: string;\n }\n | {\n type: \"auto_continue\";\n reason:\n | \"run_timeout\"\n | \"loop_limit\"\n | \"no_progress\"\n | \"stream_ended\"\n | \"gateway_timeout\"\n | \"network_interrupted\";\n maxIterations?: number;\n }\n | { type: \"clear\" };\n\nexport interface RunEvent {\n seq: number;\n event: AgentChatEvent;\n}\n\nexport type RunStatus = \"running\" | \"completed\" | \"errored\" | \"aborted\";\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ActionChatUIConfig } from \"../action-ui.js\";\nimport type { AgentMcpAppPayload } from \"../mcp-client/app-result.js\";\nimport type { ReasoningEffort } from \"../shared/reasoning-effort.js\";\n\nexport interface AgentNativeJsonSchema {\n type?: string | string[];\n description?: string;\n enum?: unknown[];\n const?: unknown;\n properties?: Record<string, AgentNativeJsonSchema>;\n required?: string[];\n additionalProperties?: boolean | AgentNativeJsonSchema;\n items?: AgentNativeJsonSchema;\n oneOf?: AgentNativeJsonSchema[];\n anyOf?: AgentNativeJsonSchema[];\n allOf?: AgentNativeJsonSchema[];\n not?: AgentNativeJsonSchema;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n minimum?: number;\n maximum?: number;\n minItems?: number;\n maxItems?: number;\n}\n\nexport interface ActionTool {\n description: string;\n parameters?: AgentNativeJsonSchema & {\n type: \"object\";\n properties: Record<string, AgentNativeJsonSchema>;\n required?: string[];\n };\n}\n\n/** @deprecated Use `ActionTool` instead */\nexport type ScriptTool = ActionTool;\n\nexport interface AgentMessage {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport type AgentChatStructuredContentPart =\n | { type: \"text\"; text: string }\n | {\n type: \"tool-call\";\n id?: string;\n toolCallId?: string;\n name?: string;\n toolName?: string;\n input?: unknown;\n args?: unknown;\n }\n | {\n type: \"tool-result\";\n toolCallId: string;\n /** Persisted for replay; omitted in older rows is backfilled server-side. */\n toolName?: string;\n toolInput?: string;\n content: string;\n isError?: boolean;\n };\n\nexport interface AgentChatStructuredMessage {\n role: \"user\" | \"assistant\";\n content: AgentChatStructuredContentPart[];\n}\n\nexport interface AgentChatReference {\n type: \"file\" | \"skill\" | \"mention\" | \"agent\" | \"custom-agent\";\n path: string;\n name: string;\n source: string;\n refType?: string;\n refId?: string;\n slotKey?: string;\n slotLabel?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface MentionProviderItem {\n id: string;\n label: string;\n description?: string;\n icon?: string;\n refType: string;\n refId?: string;\n refPath?: string;\n slotKey?: string;\n slotLabel?: string;\n metadata?: Record<string, unknown>;\n clearsSlots?: string[];\n relatedReferences?: MentionProviderReference[];\n}\n\nexport interface MentionProviderReference {\n label: string;\n icon?: string;\n source?: string;\n refType: string;\n refId?: string | null;\n refPath?: string | null;\n slotKey?: string;\n slotLabel?: string;\n metadata?: Record<string, unknown>;\n clearsSlots?: string[];\n relatedReferences?: MentionProviderReference[];\n}\n\nexport interface MentionProvider {\n label: string;\n icon?: string;\n search: (\n query: string,\n /** The H3 event for the current request — use to make internal API calls */\n event?: any,\n ) => MentionProviderItem[] | Promise<MentionProviderItem[]>;\n}\n\nexport interface AgentChatAttachment {\n type: string;\n name: string;\n data?: string;\n contentType?: string;\n text?: string;\n}\n\nexport interface AgentChatScope {\n type: string;\n id: string;\n label?: string;\n}\n\nexport interface AgentChatRequest {\n message: string;\n /**\n * User-visible text to persist in chat history. `message` may be normalized\n * for the model (for example mention markup or internal continuation text).\n */\n displayMessage?: string;\n history?: AgentMessage[];\n /**\n * Provider-neutral transcript used for run recovery. Unlike `history`,\n * this preserves assistant tool calls and matching tool results so\n * continuation turns do not re-run completed read-only tools.\n */\n structuredHistory?: AgentChatStructuredMessage[];\n references?: AgentChatReference[];\n threadId?: string;\n attachments?: AgentChatAttachment[];\n /** Internal retry/continuation requests should not create visible user turns. */\n internalContinuation?: boolean;\n /**\n * Internal marker set ONLY by the durable-background self-dispatch (see\n * `AGENT_CHAT_BACKGROUND_RUN_FIELD`). Present when the agent-chat handler is\n * re-entered as the background worker: it carries the pre-claimed `runId` and\n * logical `turnId` so the worker runs the loop inline with the background\n * soft-timeout instead of re-claiming the slot or re-dispatching. Untrusted\n * on its own — the `_process-run` route HMAC-verifies the dispatch before\n * invoking the handler. Absent on every normal client request.\n */\n __backgroundRun?: {\n runId: string;\n turnId?: string;\n /**\n * Number of server-driven background→background continuations already\n * chained into this logical turn (0 on the first chunk). The worker\n * increments this when it re-fires `_process-run` at a soft-timeout\n * boundary and refuses to chain past `MAX_BACKGROUND_RUN_CONTINUATIONS`.\n */\n continuationCount?: number;\n };\n /**\n * Stable identity for the logical assistant turn this request belongs to.\n * The client sends the SAME turnId for the initial POST and every\n * auto-continuation re-POST of one turn, so the server can fold each\n * continuation run's output onto a single durable assistant message instead\n * of dropping the earlier chunks. Defaults to the run id when absent.\n */\n turnId?: string;\n /** Execution mode for this turn. Plan mode is read-only and proposes before acting. */\n mode?: \"act\" | \"plan\";\n /** Per-request model override (ephemeral, from the composer model picker). */\n model?: string;\n /** Per-request engine override (sent alongside model for cross-provider switches). */\n engine?: string;\n /** Per-request reasoning effort override (ephemeral, from the composer picker). */\n effort?: ReasoningEffort;\n /** Usage-tracking label for this call (e.g. \"chat\", \"summarize\"). Default: \"chat\". */\n usageLabel?: string;\n /** Stable browser tab id so screen/url context and navigation commands are tab-scoped. */\n browserTabId?: string;\n /** Resource scope for this chat thread, e.g. the deck currently bound to the tab. */\n scope?: AgentChatScope | null;\n /** When true, expose this chat turn as a user-visible run in RunsTray. */\n trackInRunsTray?: boolean;\n /**\n * Approval grants for human-in-the-loop actions. Each entry is a stable\n * approval key (see the `approval_required` event's `approvalKey`). When the\n * agent calls an action declared `needsApproval`, the loop pauses and emits\n * `approval_required`; the client re-issues the turn (typically an empty\n * continuation) with the approved call's key here so the gate lets it run.\n * Keys not present here keep the action paused. The model never sees or sets\n * this — it is supplied by the human's approve affordance.\n */\n approvedToolCalls?: string[];\n}\n\nexport type AgentToolInput = Record<string, unknown>;\n\nexport type AgentChatEvent =\n | { type: \"text\"; text: string }\n | { type: \"thinking\"; text: string }\n | { type: \"activity\"; label: string; tool?: string }\n | { type: \"stream_keepalive\" }\n | { type: \"tool_start\"; tool: string; input: AgentToolInput }\n | {\n type: \"tool_done\";\n tool: string;\n input?: AgentToolInput;\n result: string;\n isError?: boolean;\n completedSideEffect?: boolean;\n mcpApp?: AgentMcpAppPayload;\n chatUI?: ActionChatUIConfig;\n }\n | {\n /**\n * The agent tried to call an action declared `needsApproval` and the loop\n * paused instead of executing it. The client should surface an\n * approve/deny affordance; on approve, re-issue the turn with\n * `approvedToolCalls: [approvalKey]` so the gate lets this call run.\n */\n type: \"approval_required\";\n tool: string;\n input: Record<string, string>;\n /** Stable key the client echoes back in `approvedToolCalls` to approve. */\n approvalKey: string;\n /** The model-side tool-call id for this paused call, when available. */\n toolCallId?: string;\n }\n | {\n type: \"agent_call\";\n agent: string;\n status: \"start\" | \"done\" | \"error\";\n }\n | { type: \"agent_call_text\"; agent: string; text: string }\n | {\n type: \"agent_task\";\n taskId: string;\n threadId: string;\n description: string;\n status: \"running\" | \"completed\" | \"errored\";\n }\n | {\n type: \"agent_task_update\";\n taskId: string;\n preview: string;\n currentStep?: string;\n }\n | {\n type: \"agent_task_complete\";\n taskId: string;\n summary: string;\n }\n | { type: \"done\" }\n | {\n type: \"error\";\n error: string;\n /**\n * Optional machine-readable error code. Builder gateway uses codes\n * like \"credits-limit-monthly\" / \"unauthorized\" / \"gateway_not_enabled\"\n * so the chat UI can render a structured CTA (e.g. upgrade button).\n */\n errorCode?: string;\n /** Optional link paired with errorCode — e.g. Builder billing page. */\n upgradeUrl?: string;\n /** Optional details for expandable UI/debugging. */\n details?: string;\n /** True when the user can reasonably continue/retry from partial work. */\n recoverable?: boolean;\n }\n /**\n * Legacy SSE terminal event. New streams emit\n * `{ type: \"error\", errorCode: \"missing_credentials\" }` instead.\n */\n | { type: \"missing_api_key\" }\n | { type: \"loop_limit\"; maxIterations?: number }\n | {\n /**\n * An in-loop `Processor` aborted the run via `abort()` (which throws a\n * `TripWire`). The loop catches it, emits this event, stops cleanly, and\n * surfaces the reason as a final assistant message. Structural hook for\n * real-time guardrails and a proof-of-done / coverage gate.\n */\n type: \"tripwire\";\n reason: string;\n /** Name of the processor that aborted, when it declared one. */\n processor?: string;\n }\n | {\n type: \"auto_continue\";\n reason:\n | \"run_timeout\"\n | \"loop_limit\"\n | \"no_progress\"\n | \"stream_ended\"\n | \"gateway_timeout\"\n | \"network_interrupted\";\n maxIterations?: number;\n }\n | { type: \"clear\" };\n\nexport interface RunEvent {\n seq: number;\n event: AgentChatEvent;\n}\n\nexport type RunStatus = \"running\" | \"completed\" | \"errored\" | \"aborted\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"design-connect.d.ts","sourceRoot":"","sources":["../../src/cli/design-connect.ts"],"names":[],"mappings":"AAGA,OAAa,EAEX,KAAK,MAAM,EAEZ,MAAM,WAAW,CAAC;AAcnB,QAAA,MAAM,iBAAiB,YACrB,QAAQ,EACR,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,cAAc,CACN,CAAC;AAEX,KAAK,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;mFAG+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,6BAA6B,CAAC;IACtC,UAAU,EAAE,WAAW,CAAC;IACxB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,KAAK,CAAC;QAClB,SAAS,EAAE,eAAe,CAAC;QAC3B,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;QAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,qBAAqB,CAAC;IAChC;;kFAE8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACrB;AAyBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CA6DxE;AAiED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA+CvE;AA6DD,wBAAsB,4BAA4B,CAChD,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3D,OAAO,CAAC,qBAAqB,CAAC,CA0ChC;AA0FD,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CA4O9B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmBnE;AAiBD;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,mBAAmB,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAsDf;AAqCD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,mBAqD7C"}
1
+ {"version":3,"file":"design-connect.d.ts","sourceRoot":"","sources":["../../src/cli/design-connect.ts"],"names":[],"mappings":"AAGA,OAAa,EAEX,KAAK,MAAM,EAEZ,MAAM,WAAW,CAAC;AAcnB,QAAA,MAAM,iBAAiB,YACrB,QAAQ,EACR,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,cAAc,CACN,CAAC;AAEX,KAAK,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;mFAG+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,6BAA6B,CAAC;IACtC,UAAU,EAAE,WAAW,CAAC;IACxB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,KAAK,CAAC;QAClB,SAAS,EAAE,eAAe,CAAC;QAC3B,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;QAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,qBAAqB,CAAC;IAChC;;kFAE8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACrB;AAyBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CA6DxE;AAiED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA+CvE;AA6DD,wBAAsB,4BAA4B,CAChD,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3D,OAAO,CAAC,qBAAqB,CAAC,CA0ChC;AAkKD,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CA8Q9B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmBnE;AAiBD;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,mBAAmB,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAsDf;AAqCD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,mBAqD7C"}
@@ -328,6 +328,61 @@ function sendJson(res, statusCode, body) {
328
328
  });
329
329
  res.end(`${JSON.stringify(body, null, 2)}\n`);
330
330
  }
331
+ function sameOrigin(a, b) {
332
+ try {
333
+ return new URL(a).origin === new URL(b).origin;
334
+ }
335
+ catch {
336
+ return false;
337
+ }
338
+ }
339
+ function resolvePreviewSnapshotUrl(devServerUrl, rawUrl) {
340
+ const base = normalizeHttpUrl(devServerUrl);
341
+ const parsed = new URL(rawUrl?.trim() || "/", `${base}/`);
342
+ parsed.hash = "";
343
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
344
+ throw new Error("Snapshot URL must use http(s).");
345
+ }
346
+ if (!sameOrigin(parsed.toString(), base)) {
347
+ throw new Error("Snapshot URL must stay on the connected dev server.");
348
+ }
349
+ return parsed.toString();
350
+ }
351
+ async function fetchPreviewSnapshot(devServerUrl, targetUrl, redirects = 0) {
352
+ if (redirects > 5) {
353
+ throw new Error("Too many redirects while fetching preview snapshot.");
354
+ }
355
+ const controller = new AbortController();
356
+ const timeout = setTimeout(() => controller.abort(), 10_000);
357
+ try {
358
+ const response = await fetch(targetUrl, {
359
+ method: "GET",
360
+ redirect: "manual",
361
+ signal: controller.signal,
362
+ headers: {
363
+ accept: "text/html,application/xhtml+xml;q=0.9,*/*;q=0.8",
364
+ },
365
+ });
366
+ const location = response.headers.get("location");
367
+ if (location && response.status >= 300 && response.status < 400) {
368
+ const redirected = new URL(location, targetUrl);
369
+ redirected.hash = "";
370
+ if (!sameOrigin(redirected.toString(), devServerUrl)) {
371
+ throw new Error("Snapshot redirect left the connected dev server.");
372
+ }
373
+ return fetchPreviewSnapshot(devServerUrl, redirected.toString(), redirects + 1);
374
+ }
375
+ return {
376
+ url: response.url || targetUrl,
377
+ status: response.status,
378
+ contentType: response.headers.get("content-type") ?? "",
379
+ html: await response.text(),
380
+ };
381
+ }
382
+ finally {
383
+ clearTimeout(timeout);
384
+ }
385
+ }
331
386
  /** Read the full request body as a UTF-8 string. */
332
387
  async function readRequestBody(req) {
333
388
  return new Promise((resolve, reject) => {
@@ -423,6 +478,35 @@ export async function startDesignConnectBridge(manifest) {
423
478
  sendJson(res, 200, { ok: true, source: manifest.source });
424
479
  return;
425
480
  }
481
+ if (pathname === "/snapshot") {
482
+ if (req.method !== "GET") {
483
+ sendJson(res, 405, { ok: false, error: "method not allowed" });
484
+ return;
485
+ }
486
+ void (async () => {
487
+ try {
488
+ const requestUrl = new URL(req.url ?? "/", manifest.bridgeUrl);
489
+ const targetUrl = resolvePreviewSnapshotUrl(manifest.devServerUrl, requestUrl.searchParams.get("url") ??
490
+ requestUrl.searchParams.get("path"));
491
+ const snapshot = await fetchPreviewSnapshot(manifest.devServerUrl, targetUrl);
492
+ sendJson(res, snapshot.status >= 400 ? snapshot.status : 200, {
493
+ ok: snapshot.status < 400,
494
+ source: manifest.source,
495
+ url: snapshot.url,
496
+ status: snapshot.status,
497
+ contentType: snapshot.contentType,
498
+ html: snapshot.html,
499
+ });
500
+ }
501
+ catch (err) {
502
+ sendJson(res, 400, {
503
+ ok: false,
504
+ error: err instanceof Error ? err.message : String(err),
505
+ });
506
+ }
507
+ })();
508
+ return;
509
+ }
426
510
  // ── Token-gated write endpoints (POST only) ───────────────────────────
427
511
  if (pathname === "/read-file" ||
428
512
  pathname === "/write-file" ||