@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.
- package/package.json +4 -2
- package/src/agents/appAgentConnectors.test.ts +37 -0
- package/src/agents/appAgentConnectors.ts +138 -0
- package/src/agents/runtime/agentLiveReducer.test.ts +72 -72
- package/src/agents/runtime/agentLiveReducer.ts +139 -139
- package/src/agents/runtime/agentRunEventTypes.ts +115 -115
- package/src/agents/runtime/contextWindowUsage.test.ts +38 -38
- package/src/agents/runtime/contextWindowUsage.ts +25 -25
- package/src/agents/runtime/index.ts +24 -24
- package/src/agents/runtime/mapAgentMessages.ts +79 -54
- package/src/agents/runtime/mapAgentSnapshot.test.ts +98 -0
- package/src/agents/runtime/mapAgentSnapshot.ts +124 -71
- package/src/agents/runtime/mergeUsageTurn.ts +23 -23
- package/src/agents/runtime/pendingToolCalls.test.ts +85 -85
- package/src/agents/runtime/pendingToolCalls.ts +14 -14
- package/src/agents/runtime/toolRequiresApproval.ts +20 -20
- package/src/agents/runtime/unresolvedToolCalls.ts +42 -42
- package/src/bridge/agentModelTiers.ts +50 -50
- package/src/bridge/agentToolHandlers.ts +23 -23
- package/src/bridge/agentToolHelpers.test.ts +27 -27
- package/src/bridge/agentToolHelpers.ts +20 -20
- package/src/bridge/agentTypes.ts +377 -294
- package/src/bridge/agents.d.mts +144 -113
- package/src/bridge/agents.mjs +287 -233
- package/src/bridge/agents.ts +77 -62
- package/src/bridge/appSettings.d.mts +9 -9
- package/src/bridge/appSettings.mjs +18 -18
- package/src/bridge/appSettings.ts +4 -4
- package/src/bridge/applyThemeFromHost.d.mts +7 -7
- package/src/bridge/applyThemeFromHost.mjs +33 -33
- package/src/bridge/assets.d.mts +66 -66
- package/src/bridge/assets.mjs +121 -121
- package/src/bridge/calendarDraftIntent.ts +55 -0
- package/src/bridge/calendarInviteIntent.ts +64 -0
- package/src/bridge/catalog.d.mts +5 -5
- package/src/bridge/catalog.mjs +24 -24
- package/src/bridge/catalog.ts +1 -1
- package/src/bridge/client.d.mts +19 -19
- package/src/bridge/client.mjs +102 -102
- package/src/bridge/collectionAssetAdapter.ts +63 -63
- package/src/bridge/collectionAssets.d.mts +1 -1
- package/src/bridge/collectionAssets.mjs +2 -2
- package/src/bridge/collectionAssets.ts +1 -1
- package/src/bridge/collectionDocumentHtml.test.ts +71 -71
- package/src/bridge/collectionDocumentHtml.ts +118 -118
- package/src/bridge/collectionImagePaste.test.ts +32 -32
- package/src/bridge/collectionImagePaste.ts +130 -130
- package/src/bridge/context.mjs +12 -12
- package/src/bridge/credentials.mjs +22 -22
- package/src/bridge/dialog.d.mts +5 -5
- package/src/bridge/dialog.mjs +13 -13
- package/src/bridge/events.d.mts +14 -14
- package/src/bridge/events.mjs +12 -12
- package/src/bridge/filePreviewKind.test.ts +43 -43
- package/src/bridge/filePreviewKind.ts +76 -76
- package/src/bridge/fs.d.mts +41 -41
- package/src/bridge/fs.mjs +82 -82
- package/src/bridge/fs.test.ts +16 -16
- package/src/bridge/fs.ts +10 -10
- package/src/bridge/googleAuth.ts +159 -0
- package/src/bridge/googleProviderConfig.ts +73 -0
- package/src/bridge/index.ts +12 -12
- package/src/bridge/inlinePreview.d.mts +35 -35
- package/src/bridge/inlinePreview.mjs +99 -99
- package/src/bridge/inlinePreview.test.ts +56 -56
- package/src/bridge/inlinePreview.ts +13 -13
- package/src/bridge/methods.d.mts +125 -115
- package/src/bridge/methods.mjs +143 -132
- package/src/bridge/os.d.mts +11 -11
- package/src/bridge/os.mjs +26 -26
- package/src/bridge/plugins.d.mts +9 -9
- package/src/bridge/plugins.mjs +31 -31
- package/src/bridge/plugins.ts +5 -5
- package/src/bridge/preferences.d.mts +7 -7
- package/src/bridge/preferences.mjs +17 -17
- package/src/bridge/preferences.ts +13 -13
- package/src/bridge/printDocument.test.ts +47 -47
- package/src/bridge/printDocument.ts +75 -75
- package/src/bridge/pureRender/adapters.test.ts +144 -144
- package/src/bridge/pureRender/adapters.ts +175 -175
- package/src/bridge/pureRender/assets.test.ts +44 -44
- package/src/bridge/pureRender/base.css +76 -76
- package/src/bridge/pureRender/compiler.test.ts +279 -279
- package/src/bridge/pureRender/compiler.ts +660 -660
- package/src/bridge/pureRender/document.test.ts +283 -283
- package/src/bridge/pureRender/document.ts +35 -35
- package/src/bridge/pureRender/extraction.test.ts +432 -432
- package/src/bridge/pureRender/extraction.ts +1023 -1023
- package/src/bridge/pureRender/flow.css +3 -3
- package/src/bridge/pureRender/index.ts +66 -66
- package/src/bridge/pureRender/normalize.test.ts +442 -442
- package/src/bridge/pureRender/normalize.ts +682 -682
- package/src/bridge/pureRender/presets.ts +365 -365
- package/src/bridge/pureRender/profiles/book.css +19 -19
- package/src/bridge/pureRender/profiles/manuscript.css +11 -11
- package/src/bridge/pureRender/profiles/writer.css +10 -10
- package/src/bridge/pureRender/reset.css +5 -5
- package/src/bridge/pureRender/samples.ts +94 -94
- package/src/bridge/pureRender/styles.ts +164 -164
- package/src/bridge/pureRender/theme.test.ts +53 -53
- package/src/bridge/pureRender/theme.ts +258 -258
- package/src/bridge/pureRender/tokens/default.css +36 -36
- package/src/bridge/pureRender/tokens/default.json +32 -32
- package/src/bridge/pureRender/types.ts +264 -264
- package/src/bridge/pureRender/visualLayoutInspection.test.ts +57 -57
- package/src/bridge/pureRender/visualLayoutInspection.ts +161 -161
- package/src/bridge/react/useDebouncedEffect.ts +21 -21
- package/src/bridge/react/useIpc.tsx +75 -75
- package/src/bridge/react/usePlatformAgentRunLiveState.tsx +78 -78
- package/src/bridge/react/usePlatformAgentSessionDrive.test.tsx +134 -0
- package/src/bridge/react/usePlatformAgentSessionDrive.tsx +749 -729
- package/src/bridge/react/usePlatformAgentSessions.tsx +60 -60
- package/src/bridge/react/usePlatformAgentTools.tsx +82 -82
- package/src/bridge/react/usePlatformAppManifest.tsx +32 -32
- package/src/bridge/react/usePlatformBridge.tsx +56 -56
- package/src/bridge/react/usePlatformDeepLink.tsx +57 -57
- package/src/bridge/react/usePlatformFileBinaryDataUrl.tsx +54 -54
- package/src/bridge/react/usePlatformFilePreview.tsx +92 -92
- package/src/bridge/react/usePlatformPreferences.tsx +77 -77
- package/src/bridge/react/usePlatformThemeDocumentAttrs.ts +35 -35
- package/src/bridge/react/usePlatformThemeFromBridge.tsx +16 -16
- package/src/bridge/react/usePlatformViewportResource.test.tsx +106 -106
- package/src/bridge/react/usePlatformViewportResource.tsx +72 -72
- package/src/bridge/react/useScheduledTask.tsx +59 -59
- package/src/bridge/render.d.mts +31 -31
- package/src/bridge/render.mjs +62 -62
- package/src/bridge/render.ts +8 -8
- package/src/bridge/screenAnnotation.test.ts +103 -103
- package/src/bridge/screenAnnotation.ts +269 -269
- package/src/bridge/theme.d.mts +3 -3
- package/src/bridge/theme.mjs +9 -9
- package/src/bridge/types.ts +447 -439
- package/src/bridge/vision.d.mts +22 -0
- package/src/bridge/vision.mjs +20 -0
- package/src/bridge/watch.d.mts +9 -9
- package/src/bridge/watch.mjs +34 -34
- package/src/bridge/watch.ts +1 -1
- package/src/bridge/window.d.mts +44 -44
- package/src/bridge/window.mjs +33 -33
- package/src/chrome/index.ts +1 -1
- package/src/commitments/commitments.test.ts +201 -0
- package/src/commitments/commitments.ts +358 -0
- package/src/components/accessibility/AccessibilityReviewDialog.test.tsx +104 -104
- package/src/components/accessibility/AccessibilityReviewDialog.tsx +350 -350
- package/src/components/accessibility/accessibilityReview.test.ts +101 -101
- package/src/components/accessibility/accessibilityReview.ts +639 -639
- package/src/components/accessibility/index.ts +16 -16
- package/src/components/agent-feedback/ScreenAnnotationAgentDialog.tsx +509 -509
- package/src/components/agent-feedback/index.ts +5 -5
- package/src/components/agents/AgentComposer.tsx +135 -34
- package/src/components/agents/AgentContextUsageBar.tsx +127 -127
- package/src/components/agents/AgentDrawerPanel.test.tsx +361 -0
- package/src/components/agents/AgentDrawerPanel.tsx +122 -82
- package/src/components/agents/AgentFollowUpList.tsx +56 -0
- package/src/components/agents/AgentMarkdown.tsx +12 -12
- package/src/components/agents/AgentMessageBubble.tsx +171 -82
- package/src/components/agents/AgentMessageList.tsx +50 -47
- package/src/components/agents/AgentModelMenu.tsx +59 -55
- package/src/components/agents/AgentQuestionPromptList.tsx +284 -0
- package/src/components/agents/AgentThinkingBlock.tsx +66 -66
- package/src/components/agents/AgentToolApprovalActions.tsx +65 -65
- package/src/components/agents/AgentToolCallCard.tsx +13 -8
- package/src/components/agents/AgentToolPendingList.tsx +39 -39
- package/src/components/agents/AgentToolPendingReview.tsx +118 -118
- package/src/components/agents/agentPanelStyles.ts +150 -79
- package/src/components/agents/agentToolDisplay.ts +87 -0
- package/src/components/agents/agentTypes.ts +139 -96
- package/src/components/agents/formatToolCallArguments.test.ts +16 -16
- package/src/components/agents/formatToolCallArguments.ts +9 -9
- package/src/components/agents/index.ts +40 -40
- package/src/components/assets/AssetLibraryDialog.tsx +5 -5
- package/src/components/assets/asset-library/AssetLibraryDialog.tsx +43 -43
- package/src/components/assets/asset-library/AssetLibraryWorkspace.tsx +54 -54
- package/src/components/assets/asset-library/detail/AssetLibraryDetailActions.tsx +68 -68
- package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.tsx +56 -56
- package/src/components/assets/asset-library/detail/AssetLibraryDetailPane.tsx +90 -90
- package/src/components/assets/asset-library/detail/AssetLibraryDetailPreview.tsx +67 -67
- package/src/components/assets/asset-library/detail/AssetLibraryInlinePreview.tsx +87 -87
- package/src/components/assets/asset-library/detail/AssetLibraryInlineSourceField.tsx +29 -29
- package/src/components/assets/asset-library/detail/AssetLibraryMetadataFields.tsx +34 -34
- package/src/components/assets/asset-library/detail/AssetLibraryUsagePanel.tsx +46 -46
- package/src/components/assets/asset-library/detail/AssetLibraryVersionsPanel.tsx +145 -145
- package/src/components/assets/asset-library/helpers/assetKind.ts +74 -74
- package/src/components/assets/asset-library/helpers.ts +41 -41
- package/src/components/assets/asset-library/hooks/useAssetDetailDraft.ts +81 -81
- package/src/components/assets/asset-library/hooks/useAssetLibraryDialog.ts +233 -233
- package/src/components/assets/asset-library/hooks/useAssetLibraryMutations.ts +266 -266
- package/src/components/assets/asset-library/hooks/useAssetLibrarySelectionSync.ts +24 -24
- package/src/components/assets/asset-library/hooks/useAssetLibraryVersions.ts +145 -145
- package/src/components/assets/asset-library/hooks/useInlineAssetPreview.ts +44 -44
- package/src/components/assets/asset-library/index.ts +19 -19
- package/src/components/assets/asset-library/layout/assetLibraryLayout.ts +201 -201
- package/src/components/assets/asset-library/shared/fieldStyles.ts +62 -62
- package/src/components/assets/asset-library/sidebar/AssetLibraryFilterPills.tsx +89 -89
- package/src/components/assets/asset-library/sidebar/AssetLibraryList.tsx +91 -91
- package/src/components/assets/asset-library/sidebar/AssetLibraryListRow.tsx +99 -99
- package/src/components/assets/asset-library/sidebar/AssetLibraryListStatus.tsx +24 -24
- package/src/components/assets/asset-library/sidebar/AssetLibrarySidebar.tsx +48 -48
- package/src/components/assets/asset-library/sidebar/AssetLibrarySidebarActions.tsx +38 -38
- package/src/components/assets/asset-library/sidebar/AssetLibrarySidebarToolbar.tsx +78 -78
- package/src/components/assets/asset-library/sidebar/AssetListThumbnail.tsx +86 -86
- package/src/components/assets/asset-library/types.ts +128 -128
- package/src/components/assets/asset-library/utils/assetLibraryUtils.ts +181 -181
- package/src/components/assets/asset-library/utils/pathBasename.ts +5 -5
- package/src/components/assets/asset-library/utils/sanitizeUploadFileName.ts +7 -7
- package/src/components/assets/asset-library/utils/uploadCollectionAsset.ts +52 -52
- package/src/components/chrome/OverlayActionCapsule.test.tsx +82 -82
- package/src/components/chrome/OverlayActionCapsule.tsx +90 -90
- package/src/components/chrome/PanelTabStrip.tsx +113 -113
- package/src/components/chrome/PlatformIcon.tsx +27 -27
- package/src/components/chrome/PureAppWordmark.tsx +94 -89
- package/src/components/chrome/ShellWindowControls.tsx +58 -51
- package/src/components/chrome/ThemeModeButton.tsx +16 -16
- package/src/components/chrome/Titlebar.tsx +79 -79
- package/src/components/chrome/WorkspaceTabStrip.tsx +321 -300
- package/src/components/chrome/index.ts +31 -31
- package/src/components/chrome/workspaceTabTypes.ts +29 -29
- package/src/components/common/buttons/Button.tsx +241 -241
- package/src/components/common/buttons/ChoiceChip.tsx +73 -73
- package/src/components/common/buttons/CleanButton.tsx +34 -34
- package/src/components/common/buttons/IconButton.tsx +89 -89
- package/src/components/common/buttons/QuietAction.tsx +29 -29
- package/src/components/common/buttons/SegmentedControl.tsx +67 -67
- package/src/components/common/buttons/TextActionButton.tsx +55 -55
- package/src/components/common/buttons/TextLink.tsx +38 -38
- package/src/components/common/canvas/CanvasElementFrame.test.tsx +79 -79
- package/src/components/common/canvas/CanvasElementFrame.tsx +182 -182
- package/src/components/common/canvas/canvasGeometry.test.ts +66 -66
- package/src/components/common/canvas/canvasGeometry.ts +133 -133
- package/src/components/common/canvas/index.ts +27 -27
- package/src/components/common/canvas/useCanvasDragResize.test.tsx +152 -152
- package/src/components/common/canvas/useCanvasDragResize.ts +161 -161
- package/src/components/common/cards/OpenReviewCard.tsx +209 -0
- package/src/components/common/cards/index.ts +5 -0
- package/src/components/common/chat/ChatAssistantMessage.tsx +81 -81
- package/src/components/common/chat/ChatBox.test.tsx +61 -0
- package/src/components/common/chat/ChatBox.tsx +193 -189
- package/src/components/common/chat/ChatMarkdown.tsx +109 -109
- package/src/components/common/chat/ChatModelMenu.tsx +290 -258
- package/src/components/common/chat/ChatStatusRow.tsx +24 -24
- package/src/components/common/chat/ChatThinkingIndicator.tsx +54 -54
- package/src/components/common/chat/ChatThread.tsx +59 -59
- package/src/components/common/chat/ChatToolRow.tsx +147 -141
- package/src/components/common/chat/ChatUserBubble.tsx +45 -45
- package/src/components/common/chat/chatUtils.ts +7 -7
- package/src/components/common/chat/index.ts +24 -24
- package/src/components/common/connections/ConnectionSetup.tsx +534 -529
- package/src/components/common/connections/index.ts +26 -26
- package/src/components/common/containers/AppFrame.test.tsx +87 -41
- package/src/components/common/containers/AppFrame.tsx +66 -65
- package/src/components/common/containers/AppHeader.tsx +60 -60
- package/src/components/common/containers/AutoFillGrid.tsx +43 -37
- package/src/components/common/containers/Collapsible.tsx +43 -43
- package/src/components/common/containers/CollapsibleGrid.tsx +185 -174
- package/src/components/common/containers/MotionScope.tsx +32 -32
- package/src/components/common/containers/PageHeader.tsx +35 -35
- package/src/components/common/containers/PanelToolbarHeader.tsx +114 -113
- package/src/components/common/containers/QuietDisclosure.tsx +91 -91
- package/src/components/common/containers/QuietSurface.tsx +40 -41
- package/src/components/common/containers/ScrollPanel.tsx +33 -33
- package/src/components/common/containers/StatusBar.tsx +42 -42
- package/src/components/common/containers/SurfacePanel.tsx +66 -66
- package/src/components/common/containers/ToolbarStrip.tsx +80 -80
- package/src/components/common/containers/flex.ts +117 -117
- package/src/components/common/containers/useOpacityPresence.ts +80 -0
- package/src/components/common/containers/useOpenTransition.ts +33 -33
- package/src/components/common/context/ContextSelector.tsx +277 -269
- package/src/components/common/context/index.ts +7 -7
- package/src/components/common/desk/ActionReader.tsx +270 -270
- package/src/components/common/desk/ActivityLedger.tsx +143 -143
- package/src/components/common/desk/CreationDesk.tsx +139 -139
- package/src/components/common/desk/DailyBrief.tsx +160 -160
- package/src/components/common/desk/DeskCard.tsx +157 -157
- package/src/components/common/desk/index.ts +30 -30
- package/src/components/common/dropdown/ContextMenu.tsx +87 -87
- package/src/components/common/dropdown/MenuButtonDropdown.tsx +121 -121
- package/src/components/common/dropdown/MenuDropdown.tsx +63 -63
- package/src/components/common/dropdown/MenuDropdownEntry.tsx +51 -51
- package/src/components/common/dropdown/MenuDropdownItem.tsx +82 -82
- package/src/components/common/dropdown/MenuDropdownSubmenu.tsx +145 -145
- package/src/components/common/dropdown/MenuPanel.tsx +75 -69
- package/src/components/common/dropdown/MenuPortal.tsx +164 -162
- package/src/components/common/dropdown/MenuPortalLayer.tsx +6 -6
- package/src/components/common/dropdown/SelectMenu.tsx +246 -243
- package/src/components/common/dropdown/SelectMenuControl.tsx +23 -23
- package/src/components/common/dropdown/SelectMenuOptions.tsx +60 -38
- package/src/components/common/dropdown/menuPortalConstants.ts +11 -11
- package/src/components/common/dropdown/menuTypes.ts +71 -71
- package/src/components/common/dropdown/menuViewportPosition.test.ts +139 -139
- package/src/components/common/dropdown/menuViewportPosition.ts +122 -122
- package/src/components/common/dropdown/selectMenuLayout.test.ts +42 -42
- package/src/components/common/dropdown/selectMenuLayout.ts +123 -123
- package/src/components/common/dropdown/useMenuAnchorPosition.ts +109 -109
- package/src/components/common/dropdown/useSelectMenuAnchor.ts +30 -30
- package/src/components/common/evidence/StructuredEvidenceView.test.tsx +77 -77
- package/src/components/common/evidence/StructuredEvidenceView.tsx +312 -312
- package/src/components/common/evidence/index.ts +13 -13
- package/src/components/common/feedback/Badge.tsx +35 -33
- package/src/components/common/feedback/CapabilityPills.tsx +36 -36
- package/src/components/common/feedback/EmptyState.tsx +166 -132
- package/src/components/common/feedback/InfoHint.tsx +67 -67
- package/src/components/common/feedback/InlineBanner.tsx +82 -82
- package/src/components/common/feedback/PlatformChip.tsx +104 -104
- package/src/components/common/feedback/QuietPill.tsx +75 -75
- package/src/components/common/feedback/WorkProgressPanel.tsx +156 -156
- package/src/components/common/feedback/index.ts +33 -33
- package/src/components/common/files/FileTable.tsx +225 -0
- package/src/components/common/inputs/BareInput.tsx +31 -31
- package/src/components/common/inputs/BareTextarea.tsx +10 -10
- package/src/components/common/inputs/Checkbox.tsx +13 -13
- package/src/components/common/inputs/EditableSecretField.tsx +292 -0
- package/src/components/common/inputs/FieldControlShell.tsx +49 -49
- package/src/components/common/inputs/FormField.tsx +40 -40
- package/src/components/common/inputs/HybridSearchField.tsx +295 -280
- package/src/components/common/inputs/InlineComposer.tsx +197 -197
- package/src/components/common/inputs/PaletteCirclePicker.tsx +26 -26
- package/src/components/common/inputs/PaletteDropdown.tsx +418 -413
- package/src/components/common/inputs/Radio.tsx +19 -19
- package/src/components/common/inputs/SearchField.tsx +128 -128
- package/src/components/common/inputs/SelectField.tsx +170 -169
- package/src/components/common/inputs/SurfacePalettePicker.tsx +54 -54
- package/src/components/common/inputs/TextAreaField.tsx +22 -22
- package/src/components/common/inputs/TextField.tsx +51 -51
- package/src/components/common/inputs/ToggleSwitch.tsx +110 -110
- package/src/components/common/inputs/WorkspacePicker.tsx +349 -349
- package/src/components/common/inputs/fieldStyles.ts +141 -137
- package/src/components/common/layout/PanelGroup.tsx +485 -479
- package/src/components/common/layout/index.ts +31 -31
- package/src/components/common/layout/panelLayoutConstants.ts +7 -7
- package/src/components/common/layout/panelLayoutPersistence.ts +35 -35
- package/src/components/common/layout/panelLayoutState.test.ts +38 -38
- package/src/components/common/layout/panelLayoutState.ts +174 -174
- package/src/components/common/layout/panelLayoutTypes.ts +19 -19
- package/src/components/common/layout/tabs/Tabs.tsx +136 -136
- package/src/components/common/lists/listRowStyles.ts +32 -32
- package/src/components/common/lists/quiet-ledger/QuietActivityList.tsx +64 -64
- package/src/components/common/lists/quiet-ledger/QuietLedgerRow.tsx +119 -119
- package/src/components/common/lists/quiet-ledger/index.ts +9 -9
- package/src/components/common/lists/reorderable/DragHandle.tsx +65 -65
- package/src/components/common/lists/reorderable/ReorderableList.tsx +280 -280
- package/src/components/common/lists/reorderable/ReorderableListRow.tsx +102 -102
- package/src/components/common/lists/reorderable/ReorderableSections.tsx +344 -344
- package/src/components/common/lists/reorderable/ReorderableSectionsDemo.tsx +94 -94
- package/src/components/common/lists/reorderable/index.ts +15 -15
- package/src/components/common/lists/reorderable/reorderableUtils.test.ts +28 -28
- package/src/components/common/lists/reorderable/reorderableUtils.ts +23 -23
- package/src/components/common/lists/reorderable/types.ts +40 -40
- package/src/components/common/lists/reorderable/useReorderableDragState.ts +49 -49
- package/src/components/common/media/ImageReferencePicker.tsx +242 -242
- package/src/components/common/menubar/MenuBar.tsx +78 -78
- package/src/components/common/menubar/MenuBarTrigger.tsx +70 -70
- package/src/components/common/narrative/NarrativeMention.tsx +74 -74
- package/src/components/common/navigation/NavigationCardRow.tsx +98 -0
- package/src/components/common/navigation/PathBreadcrumbs.tsx +78 -78
- package/src/components/common/navigation/UnderlineTabs.tsx +83 -83
- package/src/components/common/navigation/index.ts +15 -0
- package/src/components/common/overlays/InstallAppPromptDialog.tsx +59 -59
- package/src/components/common/overlays/Modal.tsx +292 -285
- package/src/components/common/overlays/ModalChromeHeader.tsx +105 -105
- package/src/components/common/overlays/ObjectActionStrip.tsx +80 -80
- package/src/components/common/people/AutoUpdateReviewList.tsx +182 -182
- package/src/components/common/people/EntityList.tsx +122 -122
- package/src/components/common/people/EntityPortrait.tsx +64 -64
- package/src/components/common/people/LinkedDossierList.tsx +99 -99
- package/src/components/common/people/OpportunityList.tsx +94 -94
- package/src/components/common/people/PeopleSourceList.tsx +145 -145
- package/src/components/common/people/RelationshipDossier.tsx +168 -168
- package/src/components/common/people/RelationshipMap.tsx +362 -362
- package/src/components/common/people/index.ts +40 -40
- package/src/components/common/preview/FileAudioPreview.tsx +89 -89
- package/src/components/common/preview/FileImagePreview.tsx +88 -88
- package/src/components/common/preview/FilePdfPreview.tsx +87 -87
- package/src/components/common/preview/FileTextPreview.tsx +96 -96
- package/src/components/common/preview/FileVideoPreview.tsx +87 -87
- package/src/components/common/preview/PlatformFilePreview.tsx +166 -166
- package/src/components/common/preview/previewLayout.ts +27 -27
- package/src/components/common/render/Each.tsx +42 -42
- package/src/components/common/research/EvidenceDossier.tsx +904 -894
- package/src/components/common/research/index.ts +7 -7
- package/src/components/common/tiles/CatalogCard.tsx +116 -116
- package/src/components/common/tiles/Tile.tsx +45 -45
- package/src/components/common/tiles/TileGrid.tsx +19 -13
- package/src/components/common/typography/Heading.tsx +27 -27
- package/src/components/common/typography/Kicker.tsx +36 -30
- package/src/components/common/typography/Text.tsx +80 -80
- package/src/components/credentials/CredentialsPanel.tsx +236 -169
- package/src/components/credentials/credentialProviderIcon.tsx +79 -0
- package/src/components/credentials/credentialsTypes.ts +14 -14
- package/src/components/credentials/lobeIcons.d.ts +4 -0
- package/src/components/data/DataChart.tsx +913 -913
- package/src/components/data/dataTable.ts +99 -99
- package/src/components/editor/EditorCommentPromptDialog.tsx +124 -124
- package/src/components/editor/EditorLinkPromptDialog.tsx +65 -65
- package/src/components/print-design/PrintDesignPanel.test.tsx +1446 -1446
- package/src/components/print-design/PrintDesignPanel.tsx +3045 -3043
- package/src/components/print-design/index.ts +9 -9
- package/src/components/proofing/PagedProofDialog.tsx +453 -453
- package/src/components/proofing/index.ts +4 -4
- package/src/editor/DocumentEditor.tsx +28 -28
- package/src/editor/EditorViewModeToggle.tsx +38 -35
- package/src/editor/index.ts +98 -97
- package/src/editor/toolbarOverlays.ts +8 -8
- package/src/index.ts +231 -209
- package/src/theme/ThemeProvider.tsx +115 -113
- package/src/theme/appAccents.ts +115 -87
- package/src/theme/buildThemeBridgePayload.ts +23 -23
- package/src/theme/composePlatformTheme.test.ts +47 -30
- package/src/theme/composePlatformTheme.ts +23 -23
- package/src/theme/platformFont.d.mts +7 -7
- package/src/theme/platformFont.mjs +20 -20
- package/src/theme/platformFont.ts +6 -6
- package/src/theme/reportsShellChromeSelectors.ts +136 -136
- package/src/theme/styled.d.ts +5 -5
- package/src/theme/surfacePalettes.ts +179 -178
- package/src/theme/surfaceRoleSelectors.ts +113 -113
- package/src/theme/themeVars.ts +13 -13
- package/src/theme/themes/dark.ts +59 -59
- package/src/theme/themes/light.ts +60 -60
- package/src/theme/themes/palette.ts +44 -44
- package/src/theme/themes/shared.ts +68 -68
- package/src/theme/tokens.ts +114 -114
- package/src/theme/utils/GlobalStyles.ts +88 -88
- package/src/theme/utils/appFrameDocumentStyles.d.mts +5 -5
- package/src/theme/utils/appFrameDocumentStyles.mjs +89 -89
- package/src/theme/utils/appFrameDocumentStyles.ts +5 -5
- package/src/theme/utils/applyTheme.test.ts +19 -0
- package/src/theme/utils/applyTheme.ts +59 -50
- package/src/theme/utils/cssVariables.ts +49 -49
- package/src/theme/utils/useInjectThemeIntoIframe.ts +40 -40
- package/src/utils/extensionIconMap.ts +123 -123
- package/src/utils/generalUtils.ts +157 -157
- package/src/writing/DraftAssistantDialog.tsx +279 -279
- package/src/writing/WritingStyleManager.tsx +416 -416
- package/src/writing/condenseWritingStyle.ts +103 -103
- package/src/writing/draftTextWithAgent.ts +134 -134
- package/src/writing/index.ts +39 -39
- package/src/writing/styleStore.ts +32 -32
- package/src/writing/writingStyle.test.ts +122 -122
- 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
|
+
}
|
package/src/bridge/theme.d.mts
CHANGED
|
@@ -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>
|
package/src/bridge/theme.mjs
CHANGED
|
@@ -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
|
+
}
|