@puredesktop/puredesktop-ui-bridge 2.1.4 → 2.1.6
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 +19 -1
- package/src/agents/runtime/mapAgentSnapshot.test.ts +1 -3
- package/src/agents/runtime/mapAgentSnapshot.ts +8 -4
- package/src/agents/runtime/mergeUsageTurn.ts +1 -2
- package/src/agents/runtime/pendingToolCalls.test.ts +1 -3
- package/src/agents/runtime/unresolvedToolCalls.ts +1 -2
- package/src/bridge/agentModelTiers.ts +9 -4
- package/src/bridge/agents.mjs +3 -1
- package/src/bridge/calendarDraftIntent.ts +12 -4
- package/src/bridge/calendarInviteIntent.ts +18 -5
- package/src/bridge/client.mjs +45 -45
- package/src/bridge/dialog.d.mts +8 -8
- package/src/bridge/dialog.mjs +40 -40
- package/src/bridge/dialog.test.ts +73 -73
- package/src/bridge/fs.d.mts +41 -41
- package/src/bridge/fs.mjs +56 -56
- package/src/bridge/fs.test.ts +83 -83
- package/src/bridge/fs.ts +28 -28
- package/src/bridge/googleAuth.ts +3 -1
- package/src/bridge/methods.d.mts +6 -0
- package/src/bridge/methods.mjs +7 -0
- package/src/bridge/network.d.mts +17 -17
- package/src/bridge/network.mjs +22 -22
- package/src/bridge/pureRender/base.css +324 -76
- package/src/bridge/pureRender/compiler.ts +1 -1
- package/src/bridge/pureRender/document.test.ts +2 -2
- package/src/bridge/pureRender/extraction.test.ts +24 -12
- package/src/bridge/pureRender/extraction.ts +10 -7
- package/src/bridge/pureRender/flow.css +17 -3
- package/src/bridge/pureRender/normalize.ts +28 -26
- package/src/bridge/pureRender/presets.ts +7 -7
- package/src/bridge/pureRender/profiles/book.css +122 -19
- package/src/bridge/pureRender/profiles/manuscript.css +57 -11
- package/src/bridge/pureRender/profiles/writer.css +48 -10
- package/src/bridge/pureRender/reset.css +20 -5
- package/src/bridge/pureRender/theme.ts +37 -9
- package/src/bridge/pureRender/tokens/default.css +45 -33
- package/src/bridge/react/usePlatformAgentRunLiveState.tsx +4 -1
- package/src/bridge/react/usePlatformAgentSessionDrive.tsx +13 -4
- package/src/bridge/screenAnnotation.test.ts +4 -1
- package/src/bridge/screenAnnotation.ts +6 -2
- package/src/bridge/storage.d.mts +27 -27
- package/src/bridge/storage.mjs +18 -18
- package/src/bridge/storage.test.ts +49 -49
- package/src/bridge/types.ts +62 -58
- package/src/bridge/window.d.mts +3 -1
- package/src/bridge/workspace.d.mts +7 -0
- package/src/bridge/workspace.mjs +8 -0
- package/src/bridge/workspace.ts +1 -0
- package/src/commitments/commitments.test.ts +10 -3
- package/src/commitments/commitments.ts +18 -4
- package/src/components/accessibility/AccessibilityReviewDialog.tsx +7 -2
- package/src/components/accessibility/accessibilityReview.test.ts +11 -4
- package/src/components/accessibility/accessibilityReview.ts +18 -10
- package/src/components/agent-feedback/ScreenAnnotationAgentDialog.tsx +9 -2
- package/src/components/agents/AgentContextUsageBar.tsx +5 -3
- package/src/components/agents/AgentDrawerPanel.test.tsx +15 -3
- package/src/components/agents/AgentMessageBubble.tsx +1 -3
- package/src/components/agents/AgentQuestionPromptList.tsx +3 -3
- package/src/components/agents/AgentToolApprovalActions.tsx +1 -3
- package/src/components/agents/agentPanelStyles.ts +1 -1
- package/src/components/agents/agentToolDisplay.ts +4 -1
- package/src/components/assets/asset-library/AssetLibraryDialog.tsx +2 -0
- package/src/components/assets/asset-library/AssetLibraryWorkspace.tsx +2 -0
- package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.test.tsx +40 -0
- package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.tsx +7 -3
- package/src/components/assets/asset-library/detail/AssetLibraryDetailPreview.tsx +8 -8
- package/src/components/assets/asset-library/hooks/useAssetLibraryDialog.ts +13 -2
- package/src/components/assets/asset-library/hooks/useAssetLibraryMutations.ts +18 -1
- package/src/components/assets/asset-library/sidebar/AssetLibraryListRow.tsx +9 -6
- package/src/components/assets/asset-library/sidebar/AssetLibrarySidebarToolbar.tsx +3 -1
- package/src/components/assets/asset-library/sidebar/AssetListThumbnail.tsx +1 -1
- package/src/components/assets/asset-library/types.ts +6 -0
- package/src/components/chrome/OverlayActionCapsule.tsx +2 -2
- package/src/components/chrome/PanelTabStrip.tsx +3 -2
- package/src/components/chrome/PureAppWordmark.tsx +15 -15
- package/src/components/chrome/WorkspaceTabStrip.tsx +19 -14
- package/src/components/chrome/documentChromePolicy.test.ts +34 -0
- package/src/components/chrome/documentChromePolicy.ts +15 -0
- package/src/components/chrome/index.ts +4 -0
- package/src/components/chrome/workspaceTabTypes.ts +2 -0
- package/src/components/common/buttons/Button.tsx +60 -10
- package/src/components/common/buttons/ChoiceChip.tsx +2 -2
- package/src/components/common/buttons/IconButton.tsx +26 -0
- package/src/components/common/buttons/SegmentedControl.tsx +23 -7
- package/src/components/common/canvas/CanvasElementFrame.tsx +37 -28
- package/src/components/common/canvas/canvasGeometry.test.ts +4 -5
- package/src/components/common/canvas/canvasGeometry.ts +1 -4
- package/src/components/common/canvas/useCanvasDragResize.test.tsx +10 -10
- package/src/components/common/canvas/useCanvasDragResize.ts +1 -4
- package/src/components/common/cards/OpenReviewCard.tsx +6 -6
- package/src/components/common/chat/ChatBox.test.tsx +9 -1
- package/src/components/common/chat/ChatBox.tsx +3 -4
- package/src/components/common/chat/ChatMarkdown.tsx +1 -1
- package/src/components/common/chat/ChatModelMenu.tsx +1 -1
- package/src/components/common/chat/ChatThinkingIndicator.tsx +1 -1
- package/src/components/common/chat/ChatThread.tsx +2 -1
- package/src/components/common/chat/ChatToolRow.tsx +2 -2
- package/src/components/common/chat/ChatUserBubble.tsx +1 -1
- package/src/components/common/connections/ConnectionSetup.tsx +6 -6
- package/src/components/common/containers/AppFrame.test.tsx +37 -36
- package/src/components/common/containers/AppFrame.tsx +15 -0
- package/src/components/common/containers/AppHeader.tsx +6 -3
- package/src/components/common/containers/SurfacePanel.tsx +1 -0
- package/src/components/common/containers/useOpacityPresence.ts +10 -15
- package/src/components/common/context/ContextSelector.tsx +10 -10
- package/src/components/common/desk/CreationDesk.tsx +23 -11
- package/src/components/common/desk/DailyBrief.tsx +18 -7
- package/src/components/common/desk/DeskCard.tsx +11 -6
- package/src/components/common/dropdown/MenuButtonDropdown.tsx +58 -6
- package/src/components/common/dropdown/MenuDropdownItem.tsx +23 -3
- package/src/components/common/dropdown/MenuPanel.tsx +8 -8
- package/src/components/common/dropdown/SelectMenu.tsx +8 -3
- package/src/components/common/dropdown/menuTypes.ts +2 -1
- package/src/components/common/evidence/StructuredEvidenceView.tsx +9 -5
- package/src/components/common/feedback/Badge.tsx +19 -5
- package/src/components/common/feedback/CapabilityPills.tsx +1 -1
- package/src/components/common/feedback/InfoHint.tsx +2 -2
- package/src/components/common/feedback/PlatformChip.tsx +9 -9
- package/src/components/common/feedback/QuietPill.tsx +5 -8
- package/src/components/common/feedback/WorkProgressPanel.tsx +14 -14
- package/src/components/common/files/FileTable.tsx +8 -2
- package/src/components/common/inputs/Checkbox.tsx +1 -1
- package/src/components/common/inputs/EditableSecretField.tsx +1 -3
- package/src/components/common/inputs/InlineComposer.tsx +2 -2
- package/src/components/common/inputs/PaletteDropdown.tsx +33 -23
- package/src/components/common/inputs/SurfacePalettePicker.tsx +1 -1
- package/src/components/common/inputs/ToggleSwitch.tsx +2 -2
- package/src/components/common/inputs/WorkspacePicker.tsx +3 -3
- package/src/components/common/lists/listRowStyles.ts +4 -2
- package/src/components/common/lists/quiet-ledger/index.ts +1 -4
- package/src/components/common/lists/reorderable/DragHandle.tsx +1 -1
- package/src/components/common/lists/reorderable/ReorderableSections.tsx +2 -1
- package/src/components/common/media/ImageReferencePicker.tsx +22 -14
- package/src/components/common/narrative/NarrativeMention.tsx +15 -9
- package/src/components/common/navigation/NavigationCardRow.tsx +2 -2
- package/src/components/common/navigation/UnderlineTabs.tsx +1 -0
- package/src/components/common/overlays/Modal.tsx +52 -3
- package/src/components/common/overlays/ObjectActionStrip.tsx +2 -2
- package/src/components/common/people/AutoUpdateReviewList.tsx +2 -2
- package/src/components/common/people/EntityList.tsx +7 -3
- package/src/components/common/people/EntityPortrait.tsx +6 -1
- package/src/components/common/people/LinkedDossierList.tsx +3 -1
- package/src/components/common/people/RelationshipMap.tsx +3 -9
- package/src/components/common/research/EvidenceDossier.tsx +24 -20
- package/src/components/common/tiles/CatalogCard.tsx +1 -1
- package/src/components/credentials/CredentialsPanel.tsx +2 -6
- package/src/components/data/DataChart.tsx +119 -94
- package/src/components/data/dataTable.ts +4 -1
- package/src/components/editor/DocumentAppChrome.tsx +172 -0
- package/src/components/editor/EditorCommentPromptDialog.tsx +1 -1
- package/src/components/editor/EditorLinkPromptDialog.tsx +1 -1
- package/src/components/print-design/PrintDesignPanel.test.tsx +8 -6
- package/src/components/print-design/PrintDesignPanel.tsx +18 -25
- package/src/components/proofing/PagedProofDialog.tsx +17 -4
- package/src/editor/EditorViewModeToggle.tsx +6 -2
- package/src/editor/index.ts +6 -0
- package/src/theme/ThemeProvider.tsx +5 -2
- package/src/theme/appAccents.test.ts +51 -0
- package/src/theme/appAccents.ts +151 -88
- package/src/theme/appIdentityCss.mjs +256 -0
- package/src/theme/appIdentityCss.ts +256 -0
- package/src/theme/composePlatformTheme.test.ts +43 -14
- package/src/theme/platformFont.d.mts +2 -2
- package/src/theme/platformFont.mjs +4 -3
- package/src/theme/reportsShellChromeSelectors.ts +14 -132
- package/src/theme/surfaceCss.mjs +37 -0
- package/src/theme/surfaceCss.ts +37 -0
- package/src/theme/surfacePalettes.ts +120 -79
- package/src/theme/surfaceRoleSelectors.ts +135 -71
- package/src/theme/themes/dark.ts +44 -43
- package/src/theme/themes/light.ts +40 -38
- package/src/theme/themes/palette.ts +32 -30
- package/src/theme/themes/shared.ts +17 -17
- package/src/theme/utils/GlobalStyles.ts +10 -6
- package/src/theme/utils/appFrameDocumentStyles.mjs +6 -1
- package/src/theme/utils/cssVariables.ts +169 -0
- package/src/writing/DraftAssistantDialog.tsx +85 -85
- package/src/writing/WritingStyleManager.tsx +6 -3
- package/src/writing/draftTextWithAgent.ts +47 -50
- package/src/writing/styleStore.ts +4 -3
- package/src/writing/writingStyle.test.ts +8 -2
- package/src/writing/writingStyle.ts +19 -8
|
@@ -36,6 +36,175 @@ export function themeToCssVars(
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
walk(theme as unknown as Record<string, unknown>, [])
|
|
39
|
+
if (prefix === PLATFORM_THEME_PREFIX) {
|
|
40
|
+
lines.push(
|
|
41
|
+
'--platform-colors-background: var(--platform-colors-bg);',
|
|
42
|
+
'--platform-colors-text-primary: var(--platform-colors-text);',
|
|
43
|
+
'--platform-colors-text-muted: var(--platform-colors-text-secondary);',
|
|
44
|
+
'--platform-colors-text-tertiary: var(--platform-colors-text-disabled);',
|
|
45
|
+
'--platform-colors-border-subtle: var(--platform-colors-divider);',
|
|
46
|
+
'--platform-colors-focus-ring: var(--platform-colors-focus);',
|
|
47
|
+
'--platform-colors-surface-muted: var(--platform-colors-surface-hover);',
|
|
48
|
+
'--platform-colors-surface-subtle: var(--platform-colors-surface-hover);',
|
|
49
|
+
'--platform-colors-surface-raised: var(--platform-colors-elevated);',
|
|
50
|
+
'--platform-colors-surface-selected: var(--platform-colors-surface-active);',
|
|
51
|
+
'--platform-colors-popover: var(--platform-colors-text);',
|
|
52
|
+
'--platform-colors-popover-text: var(--platform-colors-text-inverse);',
|
|
53
|
+
theme.mode === 'dark'
|
|
54
|
+
? '--platform-colors-scrim: rgba(0, 0, 0, 0.55);'
|
|
55
|
+
: '--platform-colors-scrim: rgba(28, 26, 23, 0.42);',
|
|
56
|
+
theme.mode === 'dark'
|
|
57
|
+
? '--platform-colors-tooltip-bg: #ececef;'
|
|
58
|
+
: '--platform-colors-tooltip-bg: var(--platform-colors-text);',
|
|
59
|
+
theme.mode === 'dark'
|
|
60
|
+
? '--platform-colors-tooltip-text: #1b1b1e;'
|
|
61
|
+
: '--platform-colors-tooltip-text: var(--platform-colors-text-inverse);',
|
|
62
|
+
'--platform-colors-text-on-accent: var(--platform-colors-text-inverse);',
|
|
63
|
+
'--platform-colors-text-on-danger: var(--platform-colors-text-inverse);',
|
|
64
|
+
'--platform-colors-danger-muted: var(--platform-colors-semantic-red-muted);',
|
|
65
|
+
'--platform-colors-danger-border: var(--platform-colors-semantic-red-border);',
|
|
66
|
+
'--platform-colors-danger-text: var(--platform-colors-semantic-red-text);',
|
|
67
|
+
'--platform-colors-warning-muted: var(--platform-colors-semantic-orange-muted);',
|
|
68
|
+
'--platform-colors-warning-border: var(--platform-colors-semantic-orange-border);',
|
|
69
|
+
'--platform-colors-warning-text: var(--platform-colors-semantic-orange-text);',
|
|
70
|
+
'--platform-colors-success-muted: var(--platform-colors-semantic-green-muted);',
|
|
71
|
+
'--platform-colors-success-border: var(--platform-colors-semantic-green-border);',
|
|
72
|
+
'--platform-colors-success-text: var(--platform-colors-semantic-green-text);',
|
|
73
|
+
'--platform-colors-info-muted: var(--platform-colors-semantic-blue-muted);',
|
|
74
|
+
'--platform-colors-info-border: var(--platform-colors-semantic-blue-border);',
|
|
75
|
+
'--platform-colors-info-text: var(--platform-colors-semantic-blue-text);',
|
|
76
|
+
theme.mode === 'dark'
|
|
77
|
+
? '--platform-colors-disabled-primary: #6e6e74;'
|
|
78
|
+
: '--platform-colors-disabled-primary: #9a9aa0;',
|
|
79
|
+
|
|
80
|
+
'--page: var(--platform-colors-elevated);',
|
|
81
|
+
'--canvas: var(--platform-colors-bg);',
|
|
82
|
+
'--surface: var(--platform-colors-surface);',
|
|
83
|
+
'--chrome: var(--platform-colors-chrome-tab-strip);',
|
|
84
|
+
'--well: var(--platform-colors-surface-active);',
|
|
85
|
+
'--line: var(--platform-colors-divider);',
|
|
86
|
+
'--line-strong: var(--platform-colors-border-strong);',
|
|
87
|
+
'--ink: var(--platform-colors-text);',
|
|
88
|
+
'--ink-2: var(--platform-colors-text-secondary);',
|
|
89
|
+
'--ink-muted: var(--platform-colors-text-secondary);',
|
|
90
|
+
'--ink-faint: var(--platform-colors-text-disabled);',
|
|
91
|
+
theme.mode === 'dark'
|
|
92
|
+
? '--page-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 18px 48px rgba(0, 0, 0, 0.4);'
|
|
93
|
+
: '--page-shadow: 0 1px 2px rgba(18, 18, 22, 0.05), 0 18px 48px rgba(18, 18, 22, 0.13);',
|
|
94
|
+
'--pure-page: var(--page);',
|
|
95
|
+
'--pure-canvas: var(--canvas);',
|
|
96
|
+
'--pure-surface: var(--surface);',
|
|
97
|
+
'--pure-chrome: var(--chrome);',
|
|
98
|
+
'--pure-well: var(--well);',
|
|
99
|
+
'--pure-page-shadow: var(--page-shadow);',
|
|
100
|
+
'--pure-paper-chrome: var(--chrome);',
|
|
101
|
+
'--pure-paper-canvas: var(--canvas);',
|
|
102
|
+
'--pure-paper-surface: var(--surface);',
|
|
103
|
+
'--pure-paper-sunken: var(--well);',
|
|
104
|
+
'--pure-ink: var(--platform-colors-text);',
|
|
105
|
+
'--pure-ink-2: var(--platform-colors-text-secondary);',
|
|
106
|
+
'--pure-ink-muted: var(--platform-colors-text-secondary);',
|
|
107
|
+
'--pure-ink-faint: var(--platform-colors-text-disabled);',
|
|
108
|
+
'--pure-line: var(--platform-colors-divider);',
|
|
109
|
+
'--pure-line-strong: var(--platform-colors-border-strong);',
|
|
110
|
+
'--pure-line-ink: var(--platform-colors-text);',
|
|
111
|
+
'--pure-info: var(--platform-colors-info);',
|
|
112
|
+
'--pure-info-muted: var(--platform-colors-info-muted);',
|
|
113
|
+
'--pure-success: var(--platform-colors-success);',
|
|
114
|
+
'--pure-success-muted: var(--platform-colors-success-muted);',
|
|
115
|
+
'--pure-attention: var(--platform-colors-warning);',
|
|
116
|
+
'--pure-attention-muted: var(--platform-colors-warning-muted);',
|
|
117
|
+
'--pure-danger: var(--platform-colors-danger);',
|
|
118
|
+
'--pure-danger-muted: var(--platform-colors-danger-muted);',
|
|
119
|
+
'--pure-disabled-primary: var(--platform-colors-disabled-primary);',
|
|
120
|
+
'--pure-font-ui: var(--platform-typography-font-family);',
|
|
121
|
+
'--pure-font-mono: var(--platform-typography-font-family-mono);',
|
|
122
|
+
'--pure-font-serif: var(--platform-typography-font-family-content);',
|
|
123
|
+
'--pure-chrome-os-strip: var(--platform-colors-chrome-tab-strip);',
|
|
124
|
+
'--pure-chrome-wordmark-bar: var(--platform-colors-chrome-titlebar);',
|
|
125
|
+
'--pure-chrome-format-bar: var(--platform-colors-surface);',
|
|
126
|
+
'--pure-chrome-hairline: var(--platform-colors-divider);',
|
|
127
|
+
'--pure-chrome-ink: var(--platform-colors-text);',
|
|
128
|
+
'--pure-chrome-secondary: #6a6a70;',
|
|
129
|
+
'--pure-chrome-tertiary: #8a8a90;',
|
|
130
|
+
'--pure-chrome-faint: var(--platform-colors-text-tertiary);',
|
|
131
|
+
'--pure-chrome-accent-green: #1f9d57;',
|
|
132
|
+
'--pure-type-display-size: 34px;',
|
|
133
|
+
'--pure-type-title-size: 24px;',
|
|
134
|
+
'--pure-type-heading-size: 17px;',
|
|
135
|
+
'--pure-type-body-size: 15px;',
|
|
136
|
+
'--pure-type-small-size: 13px;',
|
|
137
|
+
'--pure-type-label-size: 11px;',
|
|
138
|
+
'--pure-radius-square: 0px;',
|
|
139
|
+
'--pure-radius-pill: 999px;',
|
|
140
|
+
|
|
141
|
+
'--factory-color-ink-2: var(--platform-colors-text-secondary);',
|
|
142
|
+
'--factory-color-soft: var(--platform-colors-text-secondary);',
|
|
143
|
+
'--factory-color-faint: var(--platform-colors-text-disabled);',
|
|
144
|
+
'--factory-color-line: var(--platform-colors-divider);',
|
|
145
|
+
'--factory-color-surface: var(--platform-colors-surface-hover);',
|
|
146
|
+
'--factory-color-control-border: var(--platform-colors-border);',
|
|
147
|
+
'--factory-color-disabled-track: var(--platform-colors-divider);',
|
|
148
|
+
'--factory-color-positive-text: var(--platform-colors-success-text);',
|
|
149
|
+
'--factory-color-paper: var(--platform-colors-surface);',
|
|
150
|
+
'--factory-color-ground: var(--platform-colors-bg);',
|
|
151
|
+
'--factory-color-ink: var(--platform-colors-text);',
|
|
152
|
+
'--factory-color-muted: var(--platform-colors-text-secondary);',
|
|
153
|
+
'--factory-color-rule: var(--platform-colors-border);',
|
|
154
|
+
'--factory-color-rule-strong: var(--platform-colors-border-strong);',
|
|
155
|
+
'--factory-color-positive: var(--platform-colors-semantic-green);',
|
|
156
|
+
'--factory-color-positive-muted: var(--platform-colors-semantic-green-muted);',
|
|
157
|
+
'--factory-font-sans: var(--platform-typography-font-family);',
|
|
158
|
+
'--factory-font-mono: var(--platform-typography-font-family-mono);',
|
|
159
|
+
'--factory-type-display-size: 30px;',
|
|
160
|
+
'--factory-type-title-size: 24px;',
|
|
161
|
+
'--factory-type-heading-size: 17px;',
|
|
162
|
+
'--factory-type-body-size: 14.5px;',
|
|
163
|
+
'--factory-type-small-size: 13px;',
|
|
164
|
+
'--factory-type-label-size: 11px;',
|
|
165
|
+
'--factory-type-line-height: 1.6;',
|
|
166
|
+
'--factory-space-1: 4px;',
|
|
167
|
+
'--factory-space-2: 8px;',
|
|
168
|
+
'--factory-space-3: 12px;',
|
|
169
|
+
'--factory-space-4: 16px;',
|
|
170
|
+
'--factory-space-6: 24px;',
|
|
171
|
+
'--factory-space-8: 32px;',
|
|
172
|
+
'--factory-radius: var(--platform-radius-md);',
|
|
173
|
+
'--factory-shadow: var(--platform-shadow-sm);',
|
|
174
|
+
|
|
175
|
+
'--print-color-ink: #16181d;',
|
|
176
|
+
'--print-color-ink-soft: #3c4049;',
|
|
177
|
+
'--print-color-muted: #71757e;',
|
|
178
|
+
'--print-color-paper: #ffffff;',
|
|
179
|
+
'--print-color-rule: #c9cbd0;',
|
|
180
|
+
'--print-color-rule-soft: #e4e5e9;',
|
|
181
|
+
'--print-color-accent: #1f39c4;',
|
|
182
|
+
'--print-font-serif: "Source Serif 4", Georgia, serif;',
|
|
183
|
+
'--print-font-sans: "Archivo", var(--platform-typography-font-family);',
|
|
184
|
+
'--print-font-mono: "JetBrains Mono", var(--platform-typography-font-family-mono);',
|
|
185
|
+
'--print-body-size: 10.6pt;',
|
|
186
|
+
'--print-leading: 1.5;',
|
|
187
|
+
'--print-measure: 34rem;',
|
|
188
|
+
'--print-rhythm: 15.9pt;',
|
|
189
|
+
'--print-type-caption: 8.4pt;',
|
|
190
|
+
'--print-type-body: 10.6pt;',
|
|
191
|
+
'--print-type-lead: 12.5pt;',
|
|
192
|
+
'--print-type-h3: 12.5pt;',
|
|
193
|
+
'--print-type-h2: 15pt;',
|
|
194
|
+
'--print-type-h1: 24pt;',
|
|
195
|
+
'--print-type-title: 30pt;',
|
|
196
|
+
'--typeset-color-ink: var(--print-color-ink);',
|
|
197
|
+
'--typeset-color-muted: var(--print-color-muted);',
|
|
198
|
+
'--typeset-color-paper: var(--print-color-paper);',
|
|
199
|
+
'--typeset-color-rule: var(--print-color-rule);',
|
|
200
|
+
'--typeset-color-accent: var(--print-color-accent);',
|
|
201
|
+
'--typeset-font-serif: var(--print-font-serif);',
|
|
202
|
+
'--typeset-font-sans: var(--print-font-sans);',
|
|
203
|
+
'--typeset-font-mono: var(--print-font-mono);',
|
|
204
|
+
'--typeset-measure: var(--print-measure);',
|
|
205
|
+
'--typeset-rhythm: var(--print-rhythm);',
|
|
206
|
+
)
|
|
207
|
+
}
|
|
39
208
|
return lines.join('\n')
|
|
40
209
|
}
|
|
41
210
|
|
|
@@ -180,99 +180,99 @@ export function DraftAssistantDialog({
|
|
|
180
180
|
closeOnBackdropClick={!generating}
|
|
181
181
|
>
|
|
182
182
|
<StyledShell>
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
<StyledBody>
|
|
184
|
+
{mode === 'rewrite' && selectionText ? (
|
|
185
|
+
<div>
|
|
186
|
+
<StyledLabel>Selected</StyledLabel>
|
|
187
|
+
<StyledSelectionQuote>{selectionText}</StyledSelectionQuote>
|
|
188
|
+
</div>
|
|
189
|
+
) : null}
|
|
190
|
+
|
|
185
191
|
<div>
|
|
186
|
-
<StyledLabel>
|
|
187
|
-
|
|
192
|
+
<StyledLabel>
|
|
193
|
+
{mode === 'rewrite' ? 'How should it change?' : 'What to draft'}
|
|
194
|
+
</StyledLabel>
|
|
195
|
+
<TextAreaField
|
|
196
|
+
autoFocus
|
|
197
|
+
value={instruction}
|
|
198
|
+
disabled={generating}
|
|
199
|
+
placeholder={
|
|
200
|
+
mode === 'rewrite'
|
|
201
|
+
? 'e.g. tighten this, make it warmer, add an example…'
|
|
202
|
+
: 'e.g. draft an opening paragraph about…'
|
|
203
|
+
}
|
|
204
|
+
onChange={event => setInstruction(event.target.value)}
|
|
205
|
+
/>
|
|
188
206
|
</div>
|
|
189
|
-
) : null}
|
|
190
|
-
|
|
191
|
-
<div>
|
|
192
|
-
<StyledLabel>
|
|
193
|
-
{mode === 'rewrite' ? 'How should it change?' : 'What to draft'}
|
|
194
|
-
</StyledLabel>
|
|
195
|
-
<TextAreaField
|
|
196
|
-
autoFocus
|
|
197
|
-
value={instruction}
|
|
198
|
-
disabled={generating}
|
|
199
|
-
placeholder={
|
|
200
|
-
mode === 'rewrite'
|
|
201
|
-
? 'e.g. tighten this, make it warmer, add an example…'
|
|
202
|
-
: 'e.g. draft an opening paragraph about…'
|
|
203
|
-
}
|
|
204
|
-
onChange={event => setInstruction(event.target.value)}
|
|
205
|
-
/>
|
|
206
|
-
</div>
|
|
207
|
-
|
|
208
|
-
<div>
|
|
209
|
-
<StyledLabel>Style</StyledLabel>
|
|
210
|
-
<WritingStyleManager
|
|
211
|
-
styles={styles}
|
|
212
|
-
selectedIds={selectedIds}
|
|
213
|
-
disabled={generating}
|
|
214
|
-
onChange={onStylesChange}
|
|
215
|
-
onSelectedChange={setSelectedIds}
|
|
216
|
-
/>
|
|
217
|
-
</div>
|
|
218
207
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
<
|
|
222
|
-
|
|
208
|
+
<div>
|
|
209
|
+
<StyledLabel>Style</StyledLabel>
|
|
210
|
+
<WritingStyleManager
|
|
211
|
+
styles={styles}
|
|
212
|
+
selectedIds={selectedIds}
|
|
223
213
|
disabled={generating}
|
|
224
|
-
onChange={
|
|
214
|
+
onChange={onStylesChange}
|
|
215
|
+
onSelectedChange={setSelectedIds}
|
|
225
216
|
/>
|
|
226
|
-
|
|
227
|
-
</StyledToggle>
|
|
228
|
-
) : null}
|
|
217
|
+
</div>
|
|
229
218
|
|
|
230
|
-
|
|
219
|
+
{context?.trim() ? (
|
|
220
|
+
<StyledToggle>
|
|
221
|
+
<Checkbox
|
|
222
|
+
checked={useContext}
|
|
223
|
+
disabled={generating}
|
|
224
|
+
onChange={event => setUseContext(event.target.checked)}
|
|
225
|
+
/>
|
|
226
|
+
Ground in this document (abstract, references…)
|
|
227
|
+
</StyledToggle>
|
|
228
|
+
) : null}
|
|
231
229
|
|
|
232
|
-
|
|
233
|
-
<StyledLabel>Preview</StyledLabel>
|
|
234
|
-
{result ? (
|
|
235
|
-
<StyledPreview dangerouslySetInnerHTML={{ __html: result }} />
|
|
236
|
-
) : (
|
|
237
|
-
<StyledPreviewEmpty>
|
|
238
|
-
{generating
|
|
239
|
-
? 'Drafting…'
|
|
240
|
-
: 'Generate a draft to preview it here.'}
|
|
241
|
-
</StyledPreviewEmpty>
|
|
242
|
-
)}
|
|
243
|
-
</div>
|
|
244
|
-
</StyledBody>
|
|
230
|
+
{error ? <InlineBanner variant="danger">{error}</InlineBanner> : null}
|
|
245
231
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
232
|
+
<div>
|
|
233
|
+
<StyledLabel>Preview</StyledLabel>
|
|
234
|
+
{result ? (
|
|
235
|
+
<StyledPreview dangerouslySetInnerHTML={{ __html: result }} />
|
|
236
|
+
) : (
|
|
237
|
+
<StyledPreviewEmpty>
|
|
238
|
+
{generating
|
|
239
|
+
? 'Drafting…'
|
|
240
|
+
: 'Generate a draft to preview it here.'}
|
|
241
|
+
</StyledPreviewEmpty>
|
|
242
|
+
)}
|
|
243
|
+
</div>
|
|
244
|
+
</StyledBody>
|
|
245
|
+
|
|
246
|
+
<StyledActions>
|
|
247
|
+
<Button
|
|
248
|
+
type="button"
|
|
249
|
+
variant="subtle"
|
|
250
|
+
size="md"
|
|
251
|
+
disabled={generating}
|
|
252
|
+
onClick={onClose}
|
|
253
|
+
>
|
|
254
|
+
Cancel
|
|
255
|
+
</Button>
|
|
256
|
+
<Button
|
|
257
|
+
type="button"
|
|
258
|
+
variant="primary"
|
|
259
|
+
size="md"
|
|
260
|
+
loading={generating}
|
|
261
|
+
disabled={generating}
|
|
262
|
+
onClick={() => void generate()}
|
|
263
|
+
>
|
|
264
|
+
{result ? 'Regenerate' : 'Generate'}
|
|
265
|
+
</Button>
|
|
266
|
+
<Button
|
|
267
|
+
type="button"
|
|
268
|
+
variant="primary"
|
|
269
|
+
size="md"
|
|
270
|
+
disabled={!result || generating}
|
|
271
|
+
onClick={() => onInsert(result)}
|
|
272
|
+
>
|
|
273
|
+
{mode === 'rewrite' ? 'Replace selection' : 'Insert'}
|
|
274
|
+
</Button>
|
|
275
|
+
</StyledActions>
|
|
276
276
|
</StyledShell>
|
|
277
277
|
</Modal>
|
|
278
278
|
)
|
|
@@ -201,7 +201,9 @@ export function WritingStyleManager({
|
|
|
201
201
|
setErrors(current => ({
|
|
202
202
|
...current,
|
|
203
203
|
[style.id]:
|
|
204
|
-
cause instanceof Error
|
|
204
|
+
cause instanceof Error
|
|
205
|
+
? cause.message
|
|
206
|
+
: 'Could not distill the style.',
|
|
205
207
|
}))
|
|
206
208
|
} finally {
|
|
207
209
|
setDistilling(current => ({ ...current, [style.id]: false }))
|
|
@@ -213,8 +215,9 @@ export function WritingStyleManager({
|
|
|
213
215
|
return (
|
|
214
216
|
<StyledRoot>
|
|
215
217
|
<StyledHint>
|
|
216
|
-
Your own named styles guide the agent’s voice — never the book’s
|
|
217
|
-
Pick which apply to this draft. Saved across books; manage them
|
|
218
|
+
Your own named styles guide the agent’s voice — never the book’s
|
|
219
|
+
content. Pick which apply to this draft. Saved across books; manage them
|
|
220
|
+
below.
|
|
218
221
|
</StyledHint>
|
|
219
222
|
|
|
220
223
|
<StyledChips>
|
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
callAgentRunModel,
|
|
3
2
|
createAgentSession,
|
|
4
3
|
deleteAgentSession,
|
|
5
|
-
|
|
4
|
+
sendAgentSessionMessage,
|
|
5
|
+
type PlatformAgentRunSnapshot,
|
|
6
|
+
type PlatformAgentSessionRecord,
|
|
6
7
|
} from '../bridge/agents.js'
|
|
7
8
|
|
|
8
|
-
interface AgentSessionRecord {
|
|
9
|
-
sessionId: string
|
|
10
|
-
config: { modelId: string }
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface AgentRunSnapshot {
|
|
14
|
-
runId: string
|
|
15
|
-
state: string
|
|
16
|
-
messages: Array<{ role: string; content: string }>
|
|
17
|
-
error?: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const MAX_TURNS = 4
|
|
21
|
-
|
|
22
9
|
export type DraftTextMode = 'write' | 'rewrite'
|
|
23
10
|
|
|
24
11
|
export interface DraftTextInput {
|
|
@@ -38,8 +25,8 @@ function systemPrompt(mode: DraftTextMode): string {
|
|
|
38
25
|
mode === 'rewrite'
|
|
39
26
|
? 'You rewrite a passage of a book to the author’s instruction, preserving its meaning.'
|
|
40
27
|
: 'You draft a passage of book prose from the author’s instruction.',
|
|
41
|
-
'Return clean HTML only —
|
|
42
|
-
'
|
|
28
|
+
'Return clean HTML only — no markdown, no code fences, no <h1>, no preamble, no commentary.',
|
|
29
|
+
'Match the structure to the request. When asked for a paragraph (or just prose), return only <p> paragraphs — no headings, no lists. Add sub-headings <h2> or lists only when the request calls for a multi-part section or the content clearly warrants structure.',
|
|
43
30
|
'Do not invent precise statistics, dates, quotations, or citations.',
|
|
44
31
|
].join('\n')
|
|
45
32
|
}
|
|
@@ -49,11 +36,19 @@ function message(input: DraftTextInput): string {
|
|
|
49
36
|
input.mode === 'rewrite' && input.selectionText
|
|
50
37
|
? `Passage to rewrite:\n"""${input.selectionText.slice(0, 6000)}"""`
|
|
51
38
|
: input.selectionText
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
? `Nearby text for context (do not repeat):\n"""${input.selectionText.slice(
|
|
40
|
+
0,
|
|
41
|
+
2000,
|
|
42
|
+
)}"""`
|
|
43
|
+
: '',
|
|
44
|
+
`Instruction: ${
|
|
45
|
+
input.instruction.trim() ||
|
|
46
|
+
(input.mode === 'rewrite' ? 'Improve this passage.' : 'Draft this.')
|
|
47
|
+
}`,
|
|
55
48
|
input.context?.trim()
|
|
56
|
-
? `\nReference material — use it for facts, terminology, and claims; do NOT copy its wording as voice and do NOT invent beyond it:\n"""${input.context
|
|
49
|
+
? `\nReference material — use it for facts, terminology, and claims; do NOT copy its wording as voice and do NOT invent beyond it:\n"""${input.context
|
|
50
|
+
.trim()
|
|
51
|
+
.slice(0, 4000)}"""`
|
|
57
52
|
: '',
|
|
58
53
|
input.styleGuidance ? `\n${input.styleGuidance}` : '',
|
|
59
54
|
'',
|
|
@@ -70,24 +65,31 @@ function cleanHtml(raw: string): string {
|
|
|
70
65
|
return value.trim()
|
|
71
66
|
}
|
|
72
67
|
|
|
73
|
-
function latestAssistant(snapshot:
|
|
68
|
+
function latestAssistant(snapshot: PlatformAgentRunSnapshot): string {
|
|
74
69
|
return (
|
|
75
70
|
[...snapshot.messages]
|
|
76
71
|
.reverse()
|
|
77
|
-
.find(entry => entry.role === 'assistant')
|
|
72
|
+
.find(entry => entry.role === 'assistant' && entry.content.trim())
|
|
78
73
|
?.content.trim() ?? ''
|
|
79
74
|
)
|
|
80
75
|
}
|
|
81
76
|
|
|
82
|
-
|
|
77
|
+
const DRAFT_APP_SLUG = 'book'
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Draft or rewrite a passage via the agent. Returns HTML (empty on failure).
|
|
81
|
+
*
|
|
82
|
+
* Stays on the single session-drive path (`sendAgentSessionMessage`) per the
|
|
83
|
+
* agent-steering docs — one server-driven turn, no manual run stepping.
|
|
84
|
+
*/
|
|
83
85
|
export async function draftTextWithAgent(
|
|
84
86
|
input: DraftTextInput,
|
|
85
87
|
): Promise<string> {
|
|
86
|
-
let session:
|
|
88
|
+
let session: PlatformAgentSessionRecord | null = null
|
|
87
89
|
try {
|
|
88
|
-
session =
|
|
90
|
+
session = await createAgentSession({
|
|
89
91
|
scope: 'app',
|
|
90
|
-
appSlug:
|
|
92
|
+
appSlug: DRAFT_APP_SLUG,
|
|
91
93
|
title: 'Draft passage',
|
|
92
94
|
config: {
|
|
93
95
|
sessionPrompt: systemPrompt(input.mode),
|
|
@@ -95,36 +97,31 @@ export async function draftTextWithAgent(
|
|
|
95
97
|
allowedTargetApps: ['__purebook_draft_text_no_tools__'],
|
|
96
98
|
defaultRequiresApproval: true,
|
|
97
99
|
},
|
|
98
|
-
}
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
})) as AgentRunSnapshot
|
|
105
|
-
|
|
106
|
-
for (let turn = 0; turn < MAX_TURNS; turn += 1) {
|
|
107
|
-
if (snapshot.state === 'ready') {
|
|
108
|
-
snapshot = (await callAgentRunModel({
|
|
109
|
-
runId: snapshot.runId,
|
|
110
|
-
sessionId: session.sessionId,
|
|
111
|
-
})) as AgentRunSnapshot
|
|
112
|
-
continue
|
|
113
|
-
}
|
|
114
|
-
break
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
const sessionRef = {
|
|
103
|
+
scope: 'app' as const,
|
|
104
|
+
appSlug: DRAFT_APP_SLUG,
|
|
105
|
+
sessionId: session.sessionId,
|
|
115
106
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
107
|
+
const driven = await sendAgentSessionMessage({
|
|
108
|
+
session: sessionRef,
|
|
109
|
+
message: message(input),
|
|
110
|
+
})
|
|
111
|
+
const snapshot = driven.snapshot
|
|
112
|
+
if (snapshot.state !== 'awaiting_user' && snapshot.state !== 'ready') {
|
|
113
|
+
throw new Error(
|
|
114
|
+
snapshot.error || `The model stopped at ${snapshot.state}.`,
|
|
115
|
+
)
|
|
119
116
|
}
|
|
120
|
-
|
|
117
|
+
return cleanHtml(latestAssistant(snapshot))
|
|
121
118
|
} finally {
|
|
122
119
|
if (session) {
|
|
123
120
|
try {
|
|
124
121
|
await deleteAgentSession({
|
|
125
122
|
scope: 'app',
|
|
123
|
+
appSlug: DRAFT_APP_SLUG,
|
|
126
124
|
sessionId: session.sessionId,
|
|
127
|
-
appSlug: 'book',
|
|
128
125
|
})
|
|
129
126
|
} catch {
|
|
130
127
|
/* best-effort cleanup */
|
|
@@ -14,9 +14,10 @@ const STORAGE_FILE = 'writing-styles.json'
|
|
|
14
14
|
|
|
15
15
|
export async function loadSharedWritingStyles(): Promise<BookWritingStyle> {
|
|
16
16
|
try {
|
|
17
|
-
const result = (await bridge.call(
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const result = (await bridge.call(
|
|
18
|
+
PLATFORM_BRIDGE_METHODS.STORAGE_READ_JSON,
|
|
19
|
+
[{ appSlug: STORAGE_SLUG, fileName: STORAGE_FILE }],
|
|
20
|
+
)) as { value?: unknown } | null
|
|
20
21
|
return normalizeWritingStyle(result?.value)
|
|
21
22
|
} catch {
|
|
22
23
|
return normalizeWritingStyle(null)
|
|
@@ -21,7 +21,11 @@ describe('normalizeWritingStyle', () => {
|
|
|
21
21
|
it('keeps current-shape styles and drops empty ones', () => {
|
|
22
22
|
const { styles } = normalizeWritingStyle({
|
|
23
23
|
styles: [
|
|
24
|
-
{
|
|
24
|
+
{
|
|
25
|
+
id: 'a',
|
|
26
|
+
name: 'Docs',
|
|
27
|
+
sources: [{ id: 's', label: 'x', text: 'hi' }],
|
|
28
|
+
},
|
|
25
29
|
{ id: 'b', name: 'Empty', sources: [], notes: '', skill: '' },
|
|
26
30
|
{ id: 'c', name: 'Notes only', notes: 'be terse' },
|
|
27
31
|
],
|
|
@@ -43,7 +47,9 @@ describe('normalizeWritingStyle', () => {
|
|
|
43
47
|
|
|
44
48
|
it('disables a skill flag when there is no skill text', () => {
|
|
45
49
|
const { styles } = normalizeWritingStyle({
|
|
46
|
-
styles: [
|
|
50
|
+
styles: [
|
|
51
|
+
{ id: 'a', name: 'X', notes: 'n', skill: '', skillEnabled: true },
|
|
52
|
+
],
|
|
47
53
|
})
|
|
48
54
|
expect(styles[0].skillEnabled).toBe(false)
|
|
49
55
|
})
|
|
@@ -88,10 +88,15 @@ function coerceStyle(item: unknown): WritingStyle | null {
|
|
|
88
88
|
: []
|
|
89
89
|
|
|
90
90
|
// Legacy migration: a flat StyleExample { label, text } becomes one source.
|
|
91
|
-
if (
|
|
91
|
+
if (
|
|
92
|
+
sources.length === 0 &&
|
|
93
|
+
typeof entry.text === 'string' &&
|
|
94
|
+
entry.text.trim()
|
|
95
|
+
) {
|
|
92
96
|
sources = [
|
|
93
97
|
{
|
|
94
|
-
id:
|
|
98
|
+
id:
|
|
99
|
+
typeof entry.id === 'string' && entry.id ? entry.id : randomId('src'),
|
|
95
100
|
label:
|
|
96
101
|
typeof entry.label === 'string' && entry.label.trim()
|
|
97
102
|
? entry.label.trim()
|
|
@@ -105,8 +110,8 @@ function coerceStyle(item: unknown): WritingStyle | null {
|
|
|
105
110
|
typeof entry.name === 'string' && entry.name.trim()
|
|
106
111
|
? entry.name.trim()
|
|
107
112
|
: typeof entry.label === 'string' && entry.label.trim()
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
? entry.label.trim()
|
|
114
|
+
: 'Untitled style'
|
|
110
115
|
const notes = typeof entry.notes === 'string' ? entry.notes : ''
|
|
111
116
|
const include = typeof entry.include === 'string' ? entry.include : ''
|
|
112
117
|
const exclude = typeof entry.exclude === 'string' ? entry.exclude : ''
|
|
@@ -142,8 +147,8 @@ export function normalizeWritingStyle(value: unknown): BookWritingStyle {
|
|
|
142
147
|
const source = Array.isArray(record.styles)
|
|
143
148
|
? record.styles
|
|
144
149
|
: Array.isArray(record.examples)
|
|
145
|
-
|
|
146
|
-
|
|
150
|
+
? record.examples
|
|
151
|
+
: []
|
|
147
152
|
const styles = source
|
|
148
153
|
.map(coerceStyle)
|
|
149
154
|
.filter((style): style is WritingStyle => style !== null)
|
|
@@ -160,11 +165,17 @@ export function styleRawGuidance(style: WritingStyle): string {
|
|
|
160
165
|
if (style.notes.trim()) lines.push(`Guidance: ${style.notes.trim()}`)
|
|
161
166
|
if (style.include.trim()) {
|
|
162
167
|
lines.push(
|
|
163
|
-
`Prefer these words and phrases where they fit naturally: ${normalizeWordList(
|
|
168
|
+
`Prefer these words and phrases where they fit naturally: ${normalizeWordList(
|
|
169
|
+
style.include,
|
|
170
|
+
)}.`,
|
|
164
171
|
)
|
|
165
172
|
}
|
|
166
173
|
if (style.exclude.trim()) {
|
|
167
|
-
lines.push(
|
|
174
|
+
lines.push(
|
|
175
|
+
`Avoid these words and phrases entirely: ${normalizeWordList(
|
|
176
|
+
style.exclude,
|
|
177
|
+
)}.`,
|
|
178
|
+
)
|
|
168
179
|
}
|
|
169
180
|
const samples = style.sources
|
|
170
181
|
.map(source => source.text.trim())
|