@puredesktop/puredesktop-ui-bridge 1.0.0-beta.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/package.json +4 -2
  2. package/src/agents/appAgentConnectors.test.ts +37 -0
  3. package/src/agents/appAgentConnectors.ts +138 -0
  4. package/src/agents/runtime/agentLiveReducer.test.ts +72 -72
  5. package/src/agents/runtime/agentLiveReducer.ts +139 -139
  6. package/src/agents/runtime/agentRunEventTypes.ts +115 -115
  7. package/src/agents/runtime/contextWindowUsage.test.ts +38 -38
  8. package/src/agents/runtime/contextWindowUsage.ts +25 -25
  9. package/src/agents/runtime/index.ts +24 -24
  10. package/src/agents/runtime/mapAgentMessages.ts +79 -54
  11. package/src/agents/runtime/mapAgentSnapshot.test.ts +98 -0
  12. package/src/agents/runtime/mapAgentSnapshot.ts +124 -71
  13. package/src/agents/runtime/mergeUsageTurn.ts +23 -23
  14. package/src/agents/runtime/pendingToolCalls.test.ts +85 -85
  15. package/src/agents/runtime/pendingToolCalls.ts +14 -14
  16. package/src/agents/runtime/toolRequiresApproval.ts +20 -20
  17. package/src/agents/runtime/unresolvedToolCalls.ts +42 -42
  18. package/src/bridge/agentModelTiers.ts +50 -50
  19. package/src/bridge/agentToolHandlers.ts +23 -23
  20. package/src/bridge/agentToolHelpers.test.ts +27 -27
  21. package/src/bridge/agentToolHelpers.ts +20 -20
  22. package/src/bridge/agentTypes.ts +377 -294
  23. package/src/bridge/agents.d.mts +144 -113
  24. package/src/bridge/agents.mjs +287 -233
  25. package/src/bridge/agents.ts +77 -62
  26. package/src/bridge/appSettings.d.mts +9 -9
  27. package/src/bridge/appSettings.mjs +18 -18
  28. package/src/bridge/appSettings.ts +4 -4
  29. package/src/bridge/applyThemeFromHost.d.mts +7 -7
  30. package/src/bridge/applyThemeFromHost.mjs +33 -33
  31. package/src/bridge/assets.d.mts +66 -66
  32. package/src/bridge/assets.mjs +121 -121
  33. package/src/bridge/calendarDraftIntent.ts +55 -0
  34. package/src/bridge/calendarInviteIntent.ts +64 -0
  35. package/src/bridge/catalog.d.mts +5 -5
  36. package/src/bridge/catalog.mjs +24 -24
  37. package/src/bridge/catalog.ts +1 -1
  38. package/src/bridge/client.d.mts +19 -19
  39. package/src/bridge/client.mjs +102 -102
  40. package/src/bridge/collectionAssetAdapter.ts +63 -63
  41. package/src/bridge/collectionAssets.d.mts +1 -1
  42. package/src/bridge/collectionAssets.mjs +2 -2
  43. package/src/bridge/collectionAssets.ts +1 -1
  44. package/src/bridge/collectionDocumentHtml.test.ts +71 -71
  45. package/src/bridge/collectionDocumentHtml.ts +118 -118
  46. package/src/bridge/collectionImagePaste.test.ts +32 -32
  47. package/src/bridge/collectionImagePaste.ts +130 -130
  48. package/src/bridge/context.mjs +12 -12
  49. package/src/bridge/credentials.mjs +22 -22
  50. package/src/bridge/dialog.d.mts +5 -5
  51. package/src/bridge/dialog.mjs +13 -13
  52. package/src/bridge/events.d.mts +14 -14
  53. package/src/bridge/events.mjs +12 -12
  54. package/src/bridge/filePreviewKind.test.ts +43 -43
  55. package/src/bridge/filePreviewKind.ts +76 -76
  56. package/src/bridge/fs.d.mts +41 -41
  57. package/src/bridge/fs.mjs +82 -82
  58. package/src/bridge/fs.test.ts +16 -16
  59. package/src/bridge/fs.ts +10 -10
  60. package/src/bridge/googleAuth.ts +159 -0
  61. package/src/bridge/googleProviderConfig.ts +73 -0
  62. package/src/bridge/index.ts +12 -12
  63. package/src/bridge/inlinePreview.d.mts +35 -35
  64. package/src/bridge/inlinePreview.mjs +99 -99
  65. package/src/bridge/inlinePreview.test.ts +56 -56
  66. package/src/bridge/inlinePreview.ts +13 -13
  67. package/src/bridge/methods.d.mts +125 -115
  68. package/src/bridge/methods.mjs +143 -132
  69. package/src/bridge/os.d.mts +11 -11
  70. package/src/bridge/os.mjs +26 -26
  71. package/src/bridge/plugins.d.mts +9 -9
  72. package/src/bridge/plugins.mjs +31 -31
  73. package/src/bridge/plugins.ts +5 -5
  74. package/src/bridge/preferences.d.mts +7 -7
  75. package/src/bridge/preferences.mjs +17 -17
  76. package/src/bridge/preferences.ts +13 -13
  77. package/src/bridge/printDocument.test.ts +47 -47
  78. package/src/bridge/printDocument.ts +75 -75
  79. package/src/bridge/pureRender/adapters.test.ts +144 -144
  80. package/src/bridge/pureRender/adapters.ts +175 -175
  81. package/src/bridge/pureRender/assets.test.ts +44 -44
  82. package/src/bridge/pureRender/base.css +76 -76
  83. package/src/bridge/pureRender/compiler.test.ts +279 -279
  84. package/src/bridge/pureRender/compiler.ts +660 -660
  85. package/src/bridge/pureRender/document.test.ts +283 -283
  86. package/src/bridge/pureRender/document.ts +35 -35
  87. package/src/bridge/pureRender/extraction.test.ts +432 -432
  88. package/src/bridge/pureRender/extraction.ts +1023 -1023
  89. package/src/bridge/pureRender/flow.css +3 -3
  90. package/src/bridge/pureRender/index.ts +66 -66
  91. package/src/bridge/pureRender/normalize.test.ts +442 -442
  92. package/src/bridge/pureRender/normalize.ts +682 -682
  93. package/src/bridge/pureRender/presets.ts +365 -365
  94. package/src/bridge/pureRender/profiles/book.css +19 -19
  95. package/src/bridge/pureRender/profiles/manuscript.css +11 -11
  96. package/src/bridge/pureRender/profiles/writer.css +10 -10
  97. package/src/bridge/pureRender/reset.css +5 -5
  98. package/src/bridge/pureRender/samples.ts +94 -94
  99. package/src/bridge/pureRender/styles.ts +164 -164
  100. package/src/bridge/pureRender/theme.test.ts +53 -53
  101. package/src/bridge/pureRender/theme.ts +258 -258
  102. package/src/bridge/pureRender/tokens/default.css +36 -36
  103. package/src/bridge/pureRender/tokens/default.json +32 -32
  104. package/src/bridge/pureRender/types.ts +264 -264
  105. package/src/bridge/pureRender/visualLayoutInspection.test.ts +57 -57
  106. package/src/bridge/pureRender/visualLayoutInspection.ts +161 -161
  107. package/src/bridge/react/useDebouncedEffect.ts +21 -21
  108. package/src/bridge/react/useIpc.tsx +75 -75
  109. package/src/bridge/react/usePlatformAgentRunLiveState.tsx +78 -78
  110. package/src/bridge/react/usePlatformAgentSessionDrive.test.tsx +134 -0
  111. package/src/bridge/react/usePlatformAgentSessionDrive.tsx +749 -729
  112. package/src/bridge/react/usePlatformAgentSessions.tsx +60 -60
  113. package/src/bridge/react/usePlatformAgentTools.tsx +82 -82
  114. package/src/bridge/react/usePlatformAppManifest.tsx +32 -32
  115. package/src/bridge/react/usePlatformBridge.tsx +56 -56
  116. package/src/bridge/react/usePlatformDeepLink.tsx +57 -57
  117. package/src/bridge/react/usePlatformFileBinaryDataUrl.tsx +54 -54
  118. package/src/bridge/react/usePlatformFilePreview.tsx +92 -92
  119. package/src/bridge/react/usePlatformPreferences.tsx +77 -77
  120. package/src/bridge/react/usePlatformThemeDocumentAttrs.ts +35 -35
  121. package/src/bridge/react/usePlatformThemeFromBridge.tsx +16 -16
  122. package/src/bridge/react/usePlatformViewportResource.test.tsx +106 -106
  123. package/src/bridge/react/usePlatformViewportResource.tsx +72 -72
  124. package/src/bridge/react/useScheduledTask.tsx +59 -59
  125. package/src/bridge/render.d.mts +31 -31
  126. package/src/bridge/render.mjs +62 -62
  127. package/src/bridge/render.ts +8 -8
  128. package/src/bridge/screenAnnotation.test.ts +103 -103
  129. package/src/bridge/screenAnnotation.ts +269 -269
  130. package/src/bridge/theme.d.mts +3 -3
  131. package/src/bridge/theme.mjs +9 -9
  132. package/src/bridge/types.ts +447 -439
  133. package/src/bridge/vision.d.mts +22 -0
  134. package/src/bridge/vision.mjs +20 -0
  135. package/src/bridge/watch.d.mts +9 -9
  136. package/src/bridge/watch.mjs +34 -34
  137. package/src/bridge/watch.ts +1 -1
  138. package/src/bridge/window.d.mts +44 -44
  139. package/src/bridge/window.mjs +33 -33
  140. package/src/chrome/index.ts +1 -1
  141. package/src/commitments/commitments.test.ts +201 -0
  142. package/src/commitments/commitments.ts +358 -0
  143. package/src/components/accessibility/AccessibilityReviewDialog.test.tsx +104 -104
  144. package/src/components/accessibility/AccessibilityReviewDialog.tsx +350 -350
  145. package/src/components/accessibility/accessibilityReview.test.ts +101 -101
  146. package/src/components/accessibility/accessibilityReview.ts +639 -639
  147. package/src/components/accessibility/index.ts +16 -16
  148. package/src/components/agent-feedback/ScreenAnnotationAgentDialog.tsx +509 -509
  149. package/src/components/agent-feedback/index.ts +5 -5
  150. package/src/components/agents/AgentComposer.tsx +135 -34
  151. package/src/components/agents/AgentContextUsageBar.tsx +127 -127
  152. package/src/components/agents/AgentDrawerPanel.test.tsx +361 -0
  153. package/src/components/agents/AgentDrawerPanel.tsx +122 -82
  154. package/src/components/agents/AgentFollowUpList.tsx +56 -0
  155. package/src/components/agents/AgentMarkdown.tsx +12 -12
  156. package/src/components/agents/AgentMessageBubble.tsx +171 -82
  157. package/src/components/agents/AgentMessageList.tsx +50 -47
  158. package/src/components/agents/AgentModelMenu.tsx +59 -55
  159. package/src/components/agents/AgentQuestionPromptList.tsx +284 -0
  160. package/src/components/agents/AgentThinkingBlock.tsx +66 -66
  161. package/src/components/agents/AgentToolApprovalActions.tsx +65 -65
  162. package/src/components/agents/AgentToolCallCard.tsx +13 -8
  163. package/src/components/agents/AgentToolPendingList.tsx +39 -39
  164. package/src/components/agents/AgentToolPendingReview.tsx +118 -118
  165. package/src/components/agents/agentPanelStyles.ts +150 -79
  166. package/src/components/agents/agentToolDisplay.ts +87 -0
  167. package/src/components/agents/agentTypes.ts +139 -96
  168. package/src/components/agents/formatToolCallArguments.test.ts +16 -16
  169. package/src/components/agents/formatToolCallArguments.ts +9 -9
  170. package/src/components/agents/index.ts +40 -40
  171. package/src/components/assets/AssetLibraryDialog.tsx +5 -5
  172. package/src/components/assets/asset-library/AssetLibraryDialog.tsx +43 -43
  173. package/src/components/assets/asset-library/AssetLibraryWorkspace.tsx +54 -54
  174. package/src/components/assets/asset-library/detail/AssetLibraryDetailActions.tsx +68 -68
  175. package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.tsx +56 -56
  176. package/src/components/assets/asset-library/detail/AssetLibraryDetailPane.tsx +90 -90
  177. package/src/components/assets/asset-library/detail/AssetLibraryDetailPreview.tsx +67 -67
  178. package/src/components/assets/asset-library/detail/AssetLibraryInlinePreview.tsx +87 -87
  179. package/src/components/assets/asset-library/detail/AssetLibraryInlineSourceField.tsx +29 -29
  180. package/src/components/assets/asset-library/detail/AssetLibraryMetadataFields.tsx +34 -34
  181. package/src/components/assets/asset-library/detail/AssetLibraryUsagePanel.tsx +46 -46
  182. package/src/components/assets/asset-library/detail/AssetLibraryVersionsPanel.tsx +145 -145
  183. package/src/components/assets/asset-library/helpers/assetKind.ts +74 -74
  184. package/src/components/assets/asset-library/helpers.ts +41 -41
  185. package/src/components/assets/asset-library/hooks/useAssetDetailDraft.ts +81 -81
  186. package/src/components/assets/asset-library/hooks/useAssetLibraryDialog.ts +233 -233
  187. package/src/components/assets/asset-library/hooks/useAssetLibraryMutations.ts +266 -266
  188. package/src/components/assets/asset-library/hooks/useAssetLibrarySelectionSync.ts +24 -24
  189. package/src/components/assets/asset-library/hooks/useAssetLibraryVersions.ts +145 -145
  190. package/src/components/assets/asset-library/hooks/useInlineAssetPreview.ts +44 -44
  191. package/src/components/assets/asset-library/index.ts +19 -19
  192. package/src/components/assets/asset-library/layout/assetLibraryLayout.ts +201 -201
  193. package/src/components/assets/asset-library/shared/fieldStyles.ts +62 -62
  194. package/src/components/assets/asset-library/sidebar/AssetLibraryFilterPills.tsx +89 -89
  195. package/src/components/assets/asset-library/sidebar/AssetLibraryList.tsx +91 -91
  196. package/src/components/assets/asset-library/sidebar/AssetLibraryListRow.tsx +99 -99
  197. package/src/components/assets/asset-library/sidebar/AssetLibraryListStatus.tsx +24 -24
  198. package/src/components/assets/asset-library/sidebar/AssetLibrarySidebar.tsx +48 -48
  199. package/src/components/assets/asset-library/sidebar/AssetLibrarySidebarActions.tsx +38 -38
  200. package/src/components/assets/asset-library/sidebar/AssetLibrarySidebarToolbar.tsx +78 -78
  201. package/src/components/assets/asset-library/sidebar/AssetListThumbnail.tsx +86 -86
  202. package/src/components/assets/asset-library/types.ts +128 -128
  203. package/src/components/assets/asset-library/utils/assetLibraryUtils.ts +181 -181
  204. package/src/components/assets/asset-library/utils/pathBasename.ts +5 -5
  205. package/src/components/assets/asset-library/utils/sanitizeUploadFileName.ts +7 -7
  206. package/src/components/assets/asset-library/utils/uploadCollectionAsset.ts +52 -52
  207. package/src/components/chrome/OverlayActionCapsule.test.tsx +82 -82
  208. package/src/components/chrome/OverlayActionCapsule.tsx +90 -90
  209. package/src/components/chrome/PanelTabStrip.tsx +113 -113
  210. package/src/components/chrome/PlatformIcon.tsx +27 -27
  211. package/src/components/chrome/PureAppWordmark.tsx +94 -89
  212. package/src/components/chrome/ShellWindowControls.tsx +58 -51
  213. package/src/components/chrome/ThemeModeButton.tsx +16 -16
  214. package/src/components/chrome/Titlebar.tsx +79 -79
  215. package/src/components/chrome/WorkspaceTabStrip.tsx +321 -300
  216. package/src/components/chrome/index.ts +31 -31
  217. package/src/components/chrome/workspaceTabTypes.ts +29 -29
  218. package/src/components/common/buttons/Button.tsx +241 -241
  219. package/src/components/common/buttons/ChoiceChip.tsx +73 -73
  220. package/src/components/common/buttons/CleanButton.tsx +34 -34
  221. package/src/components/common/buttons/IconButton.tsx +89 -89
  222. package/src/components/common/buttons/QuietAction.tsx +29 -29
  223. package/src/components/common/buttons/SegmentedControl.tsx +67 -67
  224. package/src/components/common/buttons/TextActionButton.tsx +55 -55
  225. package/src/components/common/buttons/TextLink.tsx +38 -38
  226. package/src/components/common/canvas/CanvasElementFrame.test.tsx +79 -79
  227. package/src/components/common/canvas/CanvasElementFrame.tsx +182 -182
  228. package/src/components/common/canvas/canvasGeometry.test.ts +66 -66
  229. package/src/components/common/canvas/canvasGeometry.ts +133 -133
  230. package/src/components/common/canvas/index.ts +27 -27
  231. package/src/components/common/canvas/useCanvasDragResize.test.tsx +152 -152
  232. package/src/components/common/canvas/useCanvasDragResize.ts +161 -161
  233. package/src/components/common/cards/OpenReviewCard.tsx +209 -0
  234. package/src/components/common/cards/index.ts +5 -0
  235. package/src/components/common/chat/ChatAssistantMessage.tsx +81 -81
  236. package/src/components/common/chat/ChatBox.test.tsx +61 -0
  237. package/src/components/common/chat/ChatBox.tsx +193 -189
  238. package/src/components/common/chat/ChatMarkdown.tsx +109 -109
  239. package/src/components/common/chat/ChatModelMenu.tsx +290 -258
  240. package/src/components/common/chat/ChatStatusRow.tsx +24 -24
  241. package/src/components/common/chat/ChatThinkingIndicator.tsx +54 -54
  242. package/src/components/common/chat/ChatThread.tsx +59 -59
  243. package/src/components/common/chat/ChatToolRow.tsx +147 -141
  244. package/src/components/common/chat/ChatUserBubble.tsx +45 -45
  245. package/src/components/common/chat/chatUtils.ts +7 -7
  246. package/src/components/common/chat/index.ts +24 -24
  247. package/src/components/common/connections/ConnectionSetup.tsx +534 -529
  248. package/src/components/common/connections/index.ts +26 -26
  249. package/src/components/common/containers/AppFrame.test.tsx +87 -41
  250. package/src/components/common/containers/AppFrame.tsx +66 -65
  251. package/src/components/common/containers/AppHeader.tsx +60 -60
  252. package/src/components/common/containers/AutoFillGrid.tsx +43 -37
  253. package/src/components/common/containers/Collapsible.tsx +43 -43
  254. package/src/components/common/containers/CollapsibleGrid.tsx +185 -174
  255. package/src/components/common/containers/MotionScope.tsx +32 -32
  256. package/src/components/common/containers/PageHeader.tsx +35 -35
  257. package/src/components/common/containers/PanelToolbarHeader.tsx +114 -113
  258. package/src/components/common/containers/QuietDisclosure.tsx +91 -91
  259. package/src/components/common/containers/QuietSurface.tsx +40 -41
  260. package/src/components/common/containers/ScrollPanel.tsx +33 -33
  261. package/src/components/common/containers/StatusBar.tsx +42 -42
  262. package/src/components/common/containers/SurfacePanel.tsx +66 -66
  263. package/src/components/common/containers/ToolbarStrip.tsx +80 -80
  264. package/src/components/common/containers/flex.ts +117 -117
  265. package/src/components/common/containers/useOpacityPresence.ts +80 -0
  266. package/src/components/common/containers/useOpenTransition.ts +33 -33
  267. package/src/components/common/context/ContextSelector.tsx +277 -269
  268. package/src/components/common/context/index.ts +7 -7
  269. package/src/components/common/desk/ActionReader.tsx +270 -270
  270. package/src/components/common/desk/ActivityLedger.tsx +143 -143
  271. package/src/components/common/desk/CreationDesk.tsx +139 -139
  272. package/src/components/common/desk/DailyBrief.tsx +160 -160
  273. package/src/components/common/desk/DeskCard.tsx +157 -157
  274. package/src/components/common/desk/index.ts +30 -30
  275. package/src/components/common/dropdown/ContextMenu.tsx +87 -87
  276. package/src/components/common/dropdown/MenuButtonDropdown.tsx +121 -121
  277. package/src/components/common/dropdown/MenuDropdown.tsx +63 -63
  278. package/src/components/common/dropdown/MenuDropdownEntry.tsx +51 -51
  279. package/src/components/common/dropdown/MenuDropdownItem.tsx +82 -82
  280. package/src/components/common/dropdown/MenuDropdownSubmenu.tsx +145 -145
  281. package/src/components/common/dropdown/MenuPanel.tsx +75 -69
  282. package/src/components/common/dropdown/MenuPortal.tsx +164 -162
  283. package/src/components/common/dropdown/MenuPortalLayer.tsx +6 -6
  284. package/src/components/common/dropdown/SelectMenu.tsx +246 -243
  285. package/src/components/common/dropdown/SelectMenuControl.tsx +23 -23
  286. package/src/components/common/dropdown/SelectMenuOptions.tsx +60 -38
  287. package/src/components/common/dropdown/menuPortalConstants.ts +11 -11
  288. package/src/components/common/dropdown/menuTypes.ts +71 -71
  289. package/src/components/common/dropdown/menuViewportPosition.test.ts +139 -139
  290. package/src/components/common/dropdown/menuViewportPosition.ts +122 -122
  291. package/src/components/common/dropdown/selectMenuLayout.test.ts +42 -42
  292. package/src/components/common/dropdown/selectMenuLayout.ts +123 -123
  293. package/src/components/common/dropdown/useMenuAnchorPosition.ts +109 -109
  294. package/src/components/common/dropdown/useSelectMenuAnchor.ts +30 -30
  295. package/src/components/common/evidence/StructuredEvidenceView.test.tsx +77 -77
  296. package/src/components/common/evidence/StructuredEvidenceView.tsx +312 -312
  297. package/src/components/common/evidence/index.ts +13 -13
  298. package/src/components/common/feedback/Badge.tsx +35 -33
  299. package/src/components/common/feedback/CapabilityPills.tsx +36 -36
  300. package/src/components/common/feedback/EmptyState.tsx +166 -132
  301. package/src/components/common/feedback/InfoHint.tsx +67 -67
  302. package/src/components/common/feedback/InlineBanner.tsx +82 -82
  303. package/src/components/common/feedback/PlatformChip.tsx +104 -104
  304. package/src/components/common/feedback/QuietPill.tsx +75 -75
  305. package/src/components/common/feedback/WorkProgressPanel.tsx +156 -156
  306. package/src/components/common/feedback/index.ts +33 -33
  307. package/src/components/common/files/FileTable.tsx +225 -0
  308. package/src/components/common/inputs/BareInput.tsx +31 -31
  309. package/src/components/common/inputs/BareTextarea.tsx +10 -10
  310. package/src/components/common/inputs/Checkbox.tsx +13 -13
  311. package/src/components/common/inputs/EditableSecretField.tsx +292 -0
  312. package/src/components/common/inputs/FieldControlShell.tsx +49 -49
  313. package/src/components/common/inputs/FormField.tsx +40 -40
  314. package/src/components/common/inputs/HybridSearchField.tsx +295 -280
  315. package/src/components/common/inputs/InlineComposer.tsx +197 -197
  316. package/src/components/common/inputs/PaletteCirclePicker.tsx +26 -26
  317. package/src/components/common/inputs/PaletteDropdown.tsx +418 -413
  318. package/src/components/common/inputs/Radio.tsx +19 -19
  319. package/src/components/common/inputs/SearchField.tsx +128 -128
  320. package/src/components/common/inputs/SelectField.tsx +170 -169
  321. package/src/components/common/inputs/SurfacePalettePicker.tsx +54 -54
  322. package/src/components/common/inputs/TextAreaField.tsx +22 -22
  323. package/src/components/common/inputs/TextField.tsx +51 -51
  324. package/src/components/common/inputs/ToggleSwitch.tsx +110 -110
  325. package/src/components/common/inputs/WorkspacePicker.tsx +349 -349
  326. package/src/components/common/inputs/fieldStyles.ts +141 -137
  327. package/src/components/common/layout/PanelGroup.tsx +485 -479
  328. package/src/components/common/layout/index.ts +31 -31
  329. package/src/components/common/layout/panelLayoutConstants.ts +7 -7
  330. package/src/components/common/layout/panelLayoutPersistence.ts +35 -35
  331. package/src/components/common/layout/panelLayoutState.test.ts +38 -38
  332. package/src/components/common/layout/panelLayoutState.ts +174 -174
  333. package/src/components/common/layout/panelLayoutTypes.ts +19 -19
  334. package/src/components/common/layout/tabs/Tabs.tsx +136 -136
  335. package/src/components/common/lists/listRowStyles.ts +32 -32
  336. package/src/components/common/lists/quiet-ledger/QuietActivityList.tsx +64 -64
  337. package/src/components/common/lists/quiet-ledger/QuietLedgerRow.tsx +119 -119
  338. package/src/components/common/lists/quiet-ledger/index.ts +9 -9
  339. package/src/components/common/lists/reorderable/DragHandle.tsx +65 -65
  340. package/src/components/common/lists/reorderable/ReorderableList.tsx +280 -280
  341. package/src/components/common/lists/reorderable/ReorderableListRow.tsx +102 -102
  342. package/src/components/common/lists/reorderable/ReorderableSections.tsx +344 -344
  343. package/src/components/common/lists/reorderable/ReorderableSectionsDemo.tsx +94 -94
  344. package/src/components/common/lists/reorderable/index.ts +15 -15
  345. package/src/components/common/lists/reorderable/reorderableUtils.test.ts +28 -28
  346. package/src/components/common/lists/reorderable/reorderableUtils.ts +23 -23
  347. package/src/components/common/lists/reorderable/types.ts +40 -40
  348. package/src/components/common/lists/reorderable/useReorderableDragState.ts +49 -49
  349. package/src/components/common/media/ImageReferencePicker.tsx +242 -242
  350. package/src/components/common/menubar/MenuBar.tsx +78 -78
  351. package/src/components/common/menubar/MenuBarTrigger.tsx +70 -70
  352. package/src/components/common/narrative/NarrativeMention.tsx +74 -74
  353. package/src/components/common/navigation/NavigationCardRow.tsx +98 -0
  354. package/src/components/common/navigation/PathBreadcrumbs.tsx +78 -78
  355. package/src/components/common/navigation/UnderlineTabs.tsx +83 -83
  356. package/src/components/common/navigation/index.ts +15 -0
  357. package/src/components/common/overlays/InstallAppPromptDialog.tsx +59 -59
  358. package/src/components/common/overlays/Modal.tsx +292 -285
  359. package/src/components/common/overlays/ModalChromeHeader.tsx +105 -105
  360. package/src/components/common/overlays/ObjectActionStrip.tsx +80 -80
  361. package/src/components/common/people/AutoUpdateReviewList.tsx +182 -182
  362. package/src/components/common/people/EntityList.tsx +122 -122
  363. package/src/components/common/people/EntityPortrait.tsx +64 -64
  364. package/src/components/common/people/LinkedDossierList.tsx +99 -99
  365. package/src/components/common/people/OpportunityList.tsx +94 -94
  366. package/src/components/common/people/PeopleSourceList.tsx +145 -145
  367. package/src/components/common/people/RelationshipDossier.tsx +168 -168
  368. package/src/components/common/people/RelationshipMap.tsx +362 -362
  369. package/src/components/common/people/index.ts +40 -40
  370. package/src/components/common/preview/FileAudioPreview.tsx +89 -89
  371. package/src/components/common/preview/FileImagePreview.tsx +88 -88
  372. package/src/components/common/preview/FilePdfPreview.tsx +87 -87
  373. package/src/components/common/preview/FileTextPreview.tsx +96 -96
  374. package/src/components/common/preview/FileVideoPreview.tsx +87 -87
  375. package/src/components/common/preview/PlatformFilePreview.tsx +166 -166
  376. package/src/components/common/preview/previewLayout.ts +27 -27
  377. package/src/components/common/render/Each.tsx +42 -42
  378. package/src/components/common/research/EvidenceDossier.tsx +904 -894
  379. package/src/components/common/research/index.ts +7 -7
  380. package/src/components/common/tiles/CatalogCard.tsx +116 -116
  381. package/src/components/common/tiles/Tile.tsx +45 -45
  382. package/src/components/common/tiles/TileGrid.tsx +19 -13
  383. package/src/components/common/typography/Heading.tsx +27 -27
  384. package/src/components/common/typography/Kicker.tsx +36 -30
  385. package/src/components/common/typography/Text.tsx +80 -80
  386. package/src/components/credentials/CredentialsPanel.tsx +236 -169
  387. package/src/components/credentials/credentialProviderIcon.tsx +79 -0
  388. package/src/components/credentials/credentialsTypes.ts +14 -14
  389. package/src/components/credentials/lobeIcons.d.ts +4 -0
  390. package/src/components/data/DataChart.tsx +913 -913
  391. package/src/components/data/dataTable.ts +99 -99
  392. package/src/components/editor/EditorCommentPromptDialog.tsx +124 -124
  393. package/src/components/editor/EditorLinkPromptDialog.tsx +65 -65
  394. package/src/components/print-design/PrintDesignPanel.test.tsx +1446 -1446
  395. package/src/components/print-design/PrintDesignPanel.tsx +3045 -3043
  396. package/src/components/print-design/index.ts +9 -9
  397. package/src/components/proofing/PagedProofDialog.tsx +453 -453
  398. package/src/components/proofing/index.ts +4 -4
  399. package/src/editor/DocumentEditor.tsx +28 -28
  400. package/src/editor/EditorViewModeToggle.tsx +38 -35
  401. package/src/editor/index.ts +98 -97
  402. package/src/editor/toolbarOverlays.ts +8 -8
  403. package/src/index.ts +231 -209
  404. package/src/theme/ThemeProvider.tsx +115 -113
  405. package/src/theme/appAccents.ts +115 -87
  406. package/src/theme/buildThemeBridgePayload.ts +23 -23
  407. package/src/theme/composePlatformTheme.test.ts +47 -30
  408. package/src/theme/composePlatformTheme.ts +23 -23
  409. package/src/theme/platformFont.d.mts +7 -7
  410. package/src/theme/platformFont.mjs +20 -20
  411. package/src/theme/platformFont.ts +6 -6
  412. package/src/theme/reportsShellChromeSelectors.ts +136 -136
  413. package/src/theme/styled.d.ts +5 -5
  414. package/src/theme/surfacePalettes.ts +179 -178
  415. package/src/theme/surfaceRoleSelectors.ts +113 -113
  416. package/src/theme/themeVars.ts +13 -13
  417. package/src/theme/themes/dark.ts +59 -59
  418. package/src/theme/themes/light.ts +60 -60
  419. package/src/theme/themes/palette.ts +44 -44
  420. package/src/theme/themes/shared.ts +68 -68
  421. package/src/theme/tokens.ts +114 -114
  422. package/src/theme/utils/GlobalStyles.ts +88 -88
  423. package/src/theme/utils/appFrameDocumentStyles.d.mts +5 -5
  424. package/src/theme/utils/appFrameDocumentStyles.mjs +89 -89
  425. package/src/theme/utils/appFrameDocumentStyles.ts +5 -5
  426. package/src/theme/utils/applyTheme.test.ts +19 -0
  427. package/src/theme/utils/applyTheme.ts +59 -50
  428. package/src/theme/utils/cssVariables.ts +49 -49
  429. package/src/theme/utils/useInjectThemeIntoIframe.ts +40 -40
  430. package/src/utils/extensionIconMap.ts +123 -123
  431. package/src/utils/generalUtils.ts +157 -157
  432. package/src/writing/DraftAssistantDialog.tsx +279 -279
  433. package/src/writing/WritingStyleManager.tsx +416 -416
  434. package/src/writing/condenseWritingStyle.ts +103 -103
  435. package/src/writing/draftTextWithAgent.ts +134 -134
  436. package/src/writing/index.ts +39 -39
  437. package/src/writing/styleStore.ts +32 -32
  438. package/src/writing/writingStyle.test.ts +122 -122
  439. package/src/writing/writingStyle.ts +217 -217
@@ -1,269 +1,269 @@
1
- import {
2
- callAgentRunModel,
3
- createAgentSession,
4
- resolveAgentRunToolCalls,
5
- startAgentRun,
6
- } from './agents.js'
7
- import { startScreenCapture } from './window.mjs'
8
- import type {
9
- PlatformScreenCaptureOption,
10
- PlatformScreenCaptureRect,
11
- PlatformScreenCaptureResult,
12
- } from './window.mjs'
13
-
14
- /**
15
- * Shared screen-annotation capture → agent flow. Any app can call
16
- * {@link captureAndSendToAgent}: it opens the shell's chromeless capture
17
- * overlay, resolves the text under the selection (content mode), and starts an
18
- * agent run with the annotated image attached. App-specific wording and tools
19
- * are supplied via `buildMessage`.
20
- *
21
- * Requires the `agents` permission in plugin.json.
22
- */
23
-
24
- const DEFAULT_MAX_STEPS = 8
25
-
26
- export interface TextCandidate {
27
- text: string
28
- rect: PlatformScreenCaptureRect
29
- }
30
-
31
- function rectsIntersect(
32
- a: PlatformScreenCaptureRect,
33
- b: PlatformScreenCaptureRect,
34
- ): boolean {
35
- return (
36
- a.x < b.x + b.width &&
37
- a.x + a.width > b.x &&
38
- a.y < b.y + b.height &&
39
- a.y + a.height > b.y
40
- )
41
- }
42
-
43
- /**
44
- * Pure core: pick the text of candidates whose rect overlaps the selection, in
45
- * order, deduped + whitespace-normalized. Separated from the DOM so it is
46
- * unit-testable (jsdom has no layout).
47
- */
48
- export function selectTextFromCandidates(
49
- candidates: TextCandidate[],
50
- selection: PlatformScreenCaptureRect,
51
- ): string {
52
- const seen = new Set<string>()
53
- const parts: string[] = []
54
- for (const candidate of candidates) {
55
- if (!rectsIntersect(candidate.rect, selection)) continue
56
- const text = candidate.text.replace(/\s+/g, ' ').trim()
57
- if (!text || seen.has(text)) continue
58
- seen.add(text)
59
- parts.push(text)
60
- }
61
- return parts.join('\n\n')
62
- }
63
-
64
- const DEFAULT_BLOCK_SELECTOR =
65
- 'p, li, h1, h2, h3, h4, h5, h6, blockquote, figcaption, td, th, pre, dt, dd'
66
-
67
- export interface ResolveSelectionTextOptions {
68
- /** Root to search within. Defaults to the active editor / contenteditable. */
69
- root?: ParentNode | null
70
- /** Block-level selector to collect. */
71
- selector?: string
72
- }
73
-
74
- /**
75
- * Resolve the text that intersects an app-local selection rect (CSS px relative
76
- * to the app's own document viewport). Reads block elements inside the editor
77
- * surface; returns '' when nothing meaningful overlaps.
78
- */
79
- export function resolveSelectionText(
80
- selection: PlatformScreenCaptureRect,
81
- options: ResolveSelectionTextOptions = {},
82
- ): string {
83
- const root =
84
- options.root ??
85
- document.querySelector('.ProseMirror, [contenteditable="true"]')
86
- if (!root) return ''
87
- const selector = options.selector ?? DEFAULT_BLOCK_SELECTOR
88
- const blocks = Array.from(root.querySelectorAll<HTMLElement>(selector))
89
- const candidates: TextCandidate[] = blocks.map(element => {
90
- const r = element.getBoundingClientRect()
91
- return {
92
- text: element.textContent ?? '',
93
- rect: { x: r.left, y: r.top, width: r.width, height: r.height },
94
- }
95
- })
96
- return selectTextFromCandidates(candidates, selection)
97
- }
98
-
99
- export interface ScreenAnnotationResult {
100
- capture: PlatformScreenCaptureResult
101
- /** Text resolved under the selection (content mode); '' in vibe mode. */
102
- resolvedText: string
103
- }
104
-
105
- /** In-progress + terminal states a caller can reflect with quiet UI. */
106
- export type CaptureAgentStatus =
107
- | 'working'
108
- | 'applied'
109
- | 'no-changes'
110
- | 'needs-approval'
111
- | 'error'
112
-
113
- export interface CaptureAgentOutcome {
114
- sessionId: string | null
115
- status: 'applied' | 'no-changes' | 'needs-approval' | 'error' | 'cancelled'
116
- error?: string
117
- }
118
-
119
- export interface CaptureAndSendOptions {
120
- appSlug: string
121
- /** What this capture transforms, shown in the overlay (e.g. "book content", "page design"). */
122
- label?: string
123
- /** Contextual option controls rendered in the overlay (e.g. design scope). */
124
- options?: PlatformScreenCaptureOption[]
125
- /** Build the agent user message from the capture + resolved text. */
126
- buildMessage?: (result: ScreenAnnotationResult) => string
127
- /** Session title (string or builder). */
128
- title?: string | ((result: ScreenAnnotationResult) => string)
129
- /** Resolve text under the selection in content mode. Defaults to {@link resolveSelectionText}. */
130
- resolveText?: (rect: PlatformScreenCaptureRect) => string
131
- /** Total model + tool-resolution turns to drive. Default 8. */
132
- maxSteps?: number
133
- /** Progress callback for quiet UI: 'working' first, then a terminal status. */
134
- onStatus?: (status: CaptureAgentStatus) => void
135
- }
136
-
137
- /**
138
- * Guidance for interpreting pen marks. The marks (circles, underlines, arrows)
139
- * indicate the focus; their scope is a judgment call the agent must make.
140
- */
141
- export function penFocusGuidance(): string {
142
- return [
143
- 'The user drew marks on the screenshot — focus on what they marked, not the whole captured region.',
144
- 'Marks may circle, underline, or point at content. Use judgment about scope: the user may mean exactly the marked words, the sentence that contains them, or the whole paragraph/section.',
145
- 'Infer the most sensible scope from the marks and the note together. If it is genuinely ambiguous, prefer the smallest coherent unit (usually the sentence) unless the note implies a larger change.',
146
- ].join('\n')
147
- }
148
-
149
- /** Generic fallback message when an app doesn't supply `buildMessage`. */
150
- export function defaultAnnotationMessage({
151
- capture,
152
- resolvedText,
153
- }: ScreenAnnotationResult): string {
154
- const note = capture.note.trim()
155
- return [
156
- capture.mode === 'content'
157
- ? 'The user captured and annotated a region of this app and wants a change applied there.'
158
- : 'The user captured and annotated a region of the app UI (vibe mode).',
159
- '',
160
- note ? `Note from the user:\n${note}` : 'No extra note.',
161
- capture.hasMarks ? `\n${penFocusGuidance()}` : '',
162
- resolvedText
163
- ? `\nText in the captured region (for reference — the marks show the focus):\n"""\n${resolvedText}\n"""`
164
- : '',
165
- '',
166
- 'Use the attached annotated screenshot (with the user’s drawing) to make the change.',
167
- ]
168
- .filter(line => line !== '')
169
- .join('\n')
170
- }
171
-
172
- interface DataUrlImage {
173
- mediaType: string
174
- dataBase64: string
175
- }
176
-
177
- function splitDataUrl(dataUrl: string): DataUrlImage | null {
178
- const match = /^data:([^;]+);base64,(.+)$/s.exec(dataUrl)
179
- if (!match) return null
180
- return { mediaType: match[1], dataBase64: match[2] }
181
- }
182
-
183
- /**
184
- * Open the capture overlay and, on send, run an agent end to end: call the
185
- * model, then route + resolve its tool calls so the edit is actually applied
186
- * (not left pending). Content mode targets the app's own agent (scope 'app');
187
- * vibe mode targets a global agent. `onStatus` reports progress so the caller
188
- * can show quiet feedback. Returns an outcome describing what happened.
189
- */
190
- export async function captureAndSendToAgent(
191
- options: CaptureAndSendOptions,
192
- ): Promise<CaptureAgentOutcome> {
193
- const capture = await startScreenCapture({
194
- label: options.label,
195
- options: options.options,
196
- })
197
- if (!capture) return { sessionId: null, status: 'cancelled' }
198
-
199
- const resolveText = options.resolveText ?? resolveSelectionText
200
- const resolvedText =
201
- capture.mode === 'content' ? resolveText(capture.rect) : ''
202
- const result: ScreenAnnotationResult = { capture, resolvedText }
203
-
204
- const buildMessage = options.buildMessage ?? defaultAnnotationMessage
205
- const message = buildMessage(result)
206
- const image = splitDataUrl(capture.imageDataUrl)
207
- const title =
208
- typeof options.title === 'function'
209
- ? options.title(result)
210
- : options.title ?? 'Screen annotation'
211
-
212
- const scope = capture.mode === 'content' ? ('app' as const) : ('global' as const)
213
-
214
- options.onStatus?.('working')
215
- try {
216
- const record = await createAgentSession({
217
- scope,
218
- ...(scope === 'app' ? { appSlug: options.appSlug } : {}),
219
- title,
220
- })
221
- const session = {
222
- scope,
223
- ...(scope === 'app' ? { appSlug: options.appSlug } : {}),
224
- sessionId: record.sessionId,
225
- }
226
-
227
- let snapshot = await startAgentRun({
228
- session,
229
- message,
230
- ...(image ? { images: [image] } : {}),
231
- })
232
- const runId = snapshot.runId
233
- const maxSteps = options.maxSteps ?? DEFAULT_MAX_STEPS
234
- let appliedTools = false
235
-
236
- for (let step = 0; step < maxSteps; step += 1) {
237
- if (snapshot.state === 'ready') {
238
- snapshot = await callAgentRunModel({ runId, sessionId: record.sessionId })
239
- continue
240
- }
241
- if (snapshot.state === 'pending_tools') {
242
- const resolved = await resolveAgentRunToolCalls({ runId, session })
243
- if (resolved.state === 'pending_tools') {
244
- // A tool still needs explicit approval — hand off to the drawer.
245
- options.onStatus?.('needs-approval')
246
- return { sessionId: record.sessionId, status: 'needs-approval' }
247
- }
248
- appliedTools = true
249
- snapshot = resolved
250
- continue
251
- }
252
- break
253
- }
254
-
255
- if (snapshot.state === 'failed') {
256
- const error = snapshot.error ?? 'The agent run failed.'
257
- options.onStatus?.('error')
258
- return { sessionId: record.sessionId, status: 'error', error }
259
- }
260
-
261
- const status = appliedTools ? 'applied' : 'no-changes'
262
- options.onStatus?.(status)
263
- return { sessionId: record.sessionId, status }
264
- } catch (cause) {
265
- const error = cause instanceof Error ? cause.message : String(cause)
266
- options.onStatus?.('error')
267
- return { sessionId: null, status: 'error', error }
268
- }
269
- }
1
+ import {
2
+ callAgentRunModel,
3
+ createAgentSession,
4
+ resolveAgentRunToolCalls,
5
+ startAgentRun,
6
+ } from './agents.js'
7
+ import { startScreenCapture } from './window.mjs'
8
+ import type {
9
+ PlatformScreenCaptureOption,
10
+ PlatformScreenCaptureRect,
11
+ PlatformScreenCaptureResult,
12
+ } from './window.mjs'
13
+
14
+ /**
15
+ * Shared screen-annotation capture → agent flow. Any app can call
16
+ * {@link captureAndSendToAgent}: it opens the shell's chromeless capture
17
+ * overlay, resolves the text under the selection (content mode), and starts an
18
+ * agent run with the annotated image attached. App-specific wording and tools
19
+ * are supplied via `buildMessage`.
20
+ *
21
+ * Requires the `agents` permission in plugin.json.
22
+ */
23
+
24
+ const DEFAULT_MAX_STEPS = 8
25
+
26
+ export interface TextCandidate {
27
+ text: string
28
+ rect: PlatformScreenCaptureRect
29
+ }
30
+
31
+ function rectsIntersect(
32
+ a: PlatformScreenCaptureRect,
33
+ b: PlatformScreenCaptureRect,
34
+ ): boolean {
35
+ return (
36
+ a.x < b.x + b.width &&
37
+ a.x + a.width > b.x &&
38
+ a.y < b.y + b.height &&
39
+ a.y + a.height > b.y
40
+ )
41
+ }
42
+
43
+ /**
44
+ * Pure core: pick the text of candidates whose rect overlaps the selection, in
45
+ * order, deduped + whitespace-normalized. Separated from the DOM so it is
46
+ * unit-testable (jsdom has no layout).
47
+ */
48
+ export function selectTextFromCandidates(
49
+ candidates: TextCandidate[],
50
+ selection: PlatformScreenCaptureRect,
51
+ ): string {
52
+ const seen = new Set<string>()
53
+ const parts: string[] = []
54
+ for (const candidate of candidates) {
55
+ if (!rectsIntersect(candidate.rect, selection)) continue
56
+ const text = candidate.text.replace(/\s+/g, ' ').trim()
57
+ if (!text || seen.has(text)) continue
58
+ seen.add(text)
59
+ parts.push(text)
60
+ }
61
+ return parts.join('\n\n')
62
+ }
63
+
64
+ const DEFAULT_BLOCK_SELECTOR =
65
+ 'p, li, h1, h2, h3, h4, h5, h6, blockquote, figcaption, td, th, pre, dt, dd'
66
+
67
+ export interface ResolveSelectionTextOptions {
68
+ /** Root to search within. Defaults to the active editor / contenteditable. */
69
+ root?: ParentNode | null
70
+ /** Block-level selector to collect. */
71
+ selector?: string
72
+ }
73
+
74
+ /**
75
+ * Resolve the text that intersects an app-local selection rect (CSS px relative
76
+ * to the app's own document viewport). Reads block elements inside the editor
77
+ * surface; returns '' when nothing meaningful overlaps.
78
+ */
79
+ export function resolveSelectionText(
80
+ selection: PlatformScreenCaptureRect,
81
+ options: ResolveSelectionTextOptions = {},
82
+ ): string {
83
+ const root =
84
+ options.root ??
85
+ document.querySelector('.ProseMirror, [contenteditable="true"]')
86
+ if (!root) return ''
87
+ const selector = options.selector ?? DEFAULT_BLOCK_SELECTOR
88
+ const blocks = Array.from(root.querySelectorAll<HTMLElement>(selector))
89
+ const candidates: TextCandidate[] = blocks.map(element => {
90
+ const r = element.getBoundingClientRect()
91
+ return {
92
+ text: element.textContent ?? '',
93
+ rect: { x: r.left, y: r.top, width: r.width, height: r.height },
94
+ }
95
+ })
96
+ return selectTextFromCandidates(candidates, selection)
97
+ }
98
+
99
+ export interface ScreenAnnotationResult {
100
+ capture: PlatformScreenCaptureResult
101
+ /** Text resolved under the selection (content mode); '' in vibe mode. */
102
+ resolvedText: string
103
+ }
104
+
105
+ /** In-progress + terminal states a caller can reflect with quiet UI. */
106
+ export type CaptureAgentStatus =
107
+ | 'working'
108
+ | 'applied'
109
+ | 'no-changes'
110
+ | 'needs-approval'
111
+ | 'error'
112
+
113
+ export interface CaptureAgentOutcome {
114
+ sessionId: string | null
115
+ status: 'applied' | 'no-changes' | 'needs-approval' | 'error' | 'cancelled'
116
+ error?: string
117
+ }
118
+
119
+ export interface CaptureAndSendOptions {
120
+ appSlug: string
121
+ /** What this capture transforms, shown in the overlay (e.g. "book content", "page design"). */
122
+ label?: string
123
+ /** Contextual option controls rendered in the overlay (e.g. design scope). */
124
+ options?: PlatformScreenCaptureOption[]
125
+ /** Build the agent user message from the capture + resolved text. */
126
+ buildMessage?: (result: ScreenAnnotationResult) => string
127
+ /** Session title (string or builder). */
128
+ title?: string | ((result: ScreenAnnotationResult) => string)
129
+ /** Resolve text under the selection in content mode. Defaults to {@link resolveSelectionText}. */
130
+ resolveText?: (rect: PlatformScreenCaptureRect) => string
131
+ /** Total model + tool-resolution turns to drive. Default 8. */
132
+ maxSteps?: number
133
+ /** Progress callback for quiet UI: 'working' first, then a terminal status. */
134
+ onStatus?: (status: CaptureAgentStatus) => void
135
+ }
136
+
137
+ /**
138
+ * Guidance for interpreting pen marks. The marks (circles, underlines, arrows)
139
+ * indicate the focus; their scope is a judgment call the agent must make.
140
+ */
141
+ export function penFocusGuidance(): string {
142
+ return [
143
+ 'The user drew marks on the screenshot — focus on what they marked, not the whole captured region.',
144
+ 'Marks may circle, underline, or point at content. Use judgment about scope: the user may mean exactly the marked words, the sentence that contains them, or the whole paragraph/section.',
145
+ 'Infer the most sensible scope from the marks and the note together. If it is genuinely ambiguous, prefer the smallest coherent unit (usually the sentence) unless the note implies a larger change.',
146
+ ].join('\n')
147
+ }
148
+
149
+ /** Generic fallback message when an app doesn't supply `buildMessage`. */
150
+ export function defaultAnnotationMessage({
151
+ capture,
152
+ resolvedText,
153
+ }: ScreenAnnotationResult): string {
154
+ const note = capture.note.trim()
155
+ return [
156
+ capture.mode === 'content'
157
+ ? 'The user captured and annotated a region of this app and wants a change applied there.'
158
+ : 'The user captured and annotated a region of the app UI (vibe mode).',
159
+ '',
160
+ note ? `Note from the user:\n${note}` : 'No extra note.',
161
+ capture.hasMarks ? `\n${penFocusGuidance()}` : '',
162
+ resolvedText
163
+ ? `\nText in the captured region (for reference — the marks show the focus):\n"""\n${resolvedText}\n"""`
164
+ : '',
165
+ '',
166
+ 'Use the attached annotated screenshot (with the user’s drawing) to make the change.',
167
+ ]
168
+ .filter(line => line !== '')
169
+ .join('\n')
170
+ }
171
+
172
+ interface DataUrlImage {
173
+ mediaType: string
174
+ dataBase64: string
175
+ }
176
+
177
+ function splitDataUrl(dataUrl: string): DataUrlImage | null {
178
+ const match = /^data:([^;]+);base64,(.+)$/s.exec(dataUrl)
179
+ if (!match) return null
180
+ return { mediaType: match[1], dataBase64: match[2] }
181
+ }
182
+
183
+ /**
184
+ * Open the capture overlay and, on send, run an agent end to end: call the
185
+ * model, then route + resolve its tool calls so the edit is actually applied
186
+ * (not left pending). Content mode targets the app's own agent (scope 'app');
187
+ * vibe mode targets a global agent. `onStatus` reports progress so the caller
188
+ * can show quiet feedback. Returns an outcome describing what happened.
189
+ */
190
+ export async function captureAndSendToAgent(
191
+ options: CaptureAndSendOptions,
192
+ ): Promise<CaptureAgentOutcome> {
193
+ const capture = await startScreenCapture({
194
+ label: options.label,
195
+ options: options.options,
196
+ })
197
+ if (!capture) return { sessionId: null, status: 'cancelled' }
198
+
199
+ const resolveText = options.resolveText ?? resolveSelectionText
200
+ const resolvedText =
201
+ capture.mode === 'content' ? resolveText(capture.rect) : ''
202
+ const result: ScreenAnnotationResult = { capture, resolvedText }
203
+
204
+ const buildMessage = options.buildMessage ?? defaultAnnotationMessage
205
+ const message = buildMessage(result)
206
+ const image = splitDataUrl(capture.imageDataUrl)
207
+ const title =
208
+ typeof options.title === 'function'
209
+ ? options.title(result)
210
+ : options.title ?? 'Screen annotation'
211
+
212
+ const scope = capture.mode === 'content' ? ('app' as const) : ('global' as const)
213
+
214
+ options.onStatus?.('working')
215
+ try {
216
+ const record = await createAgentSession({
217
+ scope,
218
+ ...(scope === 'app' ? { appSlug: options.appSlug } : {}),
219
+ title,
220
+ })
221
+ const session = {
222
+ scope,
223
+ ...(scope === 'app' ? { appSlug: options.appSlug } : {}),
224
+ sessionId: record.sessionId,
225
+ }
226
+
227
+ let snapshot = await startAgentRun({
228
+ session,
229
+ message,
230
+ ...(image ? { images: [image] } : {}),
231
+ })
232
+ const runId = snapshot.runId
233
+ const maxSteps = options.maxSteps ?? DEFAULT_MAX_STEPS
234
+ let appliedTools = false
235
+
236
+ for (let step = 0; step < maxSteps; step += 1) {
237
+ if (snapshot.state === 'ready') {
238
+ snapshot = await callAgentRunModel({ runId, sessionId: record.sessionId })
239
+ continue
240
+ }
241
+ if (snapshot.state === 'pending_tools') {
242
+ const resolved = await resolveAgentRunToolCalls({ runId, session })
243
+ if (resolved.state === 'pending_tools') {
244
+ // A tool still needs explicit approval — hand off to the drawer.
245
+ options.onStatus?.('needs-approval')
246
+ return { sessionId: record.sessionId, status: 'needs-approval' }
247
+ }
248
+ appliedTools = true
249
+ snapshot = resolved
250
+ continue
251
+ }
252
+ break
253
+ }
254
+
255
+ if (snapshot.state === 'failed') {
256
+ const error = snapshot.error ?? 'The agent run failed.'
257
+ options.onStatus?.('error')
258
+ return { sessionId: record.sessionId, status: 'error', error }
259
+ }
260
+
261
+ const status = appliedTools ? 'applied' : 'no-changes'
262
+ options.onStatus?.(status)
263
+ return { sessionId: record.sessionId, status }
264
+ } catch (cause) {
265
+ const error = cause instanceof Error ? cause.message : String(cause)
266
+ options.onStatus?.('error')
267
+ return { sessionId: null, status: 'error', error }
268
+ }
269
+ }
@@ -1,3 +1,3 @@
1
- export function setSurfacePalette(
2
- paletteId: string,
3
- ): Promise<import('./types.ts').PlatformShellPreferences>
1
+ export function setSurfacePalette(
2
+ paletteId: string,
3
+ ): Promise<import('./types.ts').PlatformShellPreferences>
@@ -1,9 +1,9 @@
1
- import { bridge } from './client.mjs'
2
- import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
-
4
- /** Ask the shell to store a surface palette for the calling app (whole desktop theme). */
5
- export async function setSurfacePalette(paletteId) {
6
- return bridge.call(PLATFORM_BRIDGE_METHODS.THEME_SET_SURFACE_PALETTE, [
7
- { paletteId },
8
- ])
9
- }
1
+ import { bridge } from './client.mjs'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ /** Ask the shell to store a surface palette for the calling app (whole desktop theme). */
5
+ export async function setSurfacePalette(paletteId) {
6
+ return bridge.call(PLATFORM_BRIDGE_METHODS.THEME_SET_SURFACE_PALETTE, [
7
+ { paletteId },
8
+ ])
9
+ }