@puredesktop/puredesktop-ui-bridge 2.1.3 → 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.
Files changed (183) hide show
  1. package/package.json +1132 -45
  2. package/src/agents/runtime/mapAgentSnapshot.test.ts +1 -3
  3. package/src/agents/runtime/mapAgentSnapshot.ts +8 -4
  4. package/src/agents/runtime/mergeUsageTurn.ts +1 -2
  5. package/src/agents/runtime/pendingToolCalls.test.ts +1 -3
  6. package/src/agents/runtime/unresolvedToolCalls.ts +1 -2
  7. package/src/bridge/agentModelTiers.ts +9 -4
  8. package/src/bridge/agents.mjs +3 -1
  9. package/src/bridge/calendarDraftIntent.ts +12 -4
  10. package/src/bridge/calendarInviteIntent.ts +18 -5
  11. package/src/bridge/client.mjs +45 -45
  12. package/src/bridge/dialog.d.mts +8 -8
  13. package/src/bridge/dialog.mjs +40 -40
  14. package/src/bridge/dialog.test.ts +73 -73
  15. package/src/bridge/fs.d.mts +41 -41
  16. package/src/bridge/fs.mjs +56 -56
  17. package/src/bridge/fs.test.ts +83 -83
  18. package/src/bridge/fs.ts +28 -28
  19. package/src/bridge/googleAuth.ts +3 -1
  20. package/src/bridge/methods.d.mts +6 -0
  21. package/src/bridge/methods.mjs +7 -0
  22. package/src/bridge/network.d.mts +17 -17
  23. package/src/bridge/network.mjs +22 -22
  24. package/src/bridge/pureRender/base.css +324 -76
  25. package/src/bridge/pureRender/compiler.ts +1 -1
  26. package/src/bridge/pureRender/document.test.ts +2 -2
  27. package/src/bridge/pureRender/extraction.test.ts +24 -12
  28. package/src/bridge/pureRender/extraction.ts +10 -7
  29. package/src/bridge/pureRender/flow.css +17 -3
  30. package/src/bridge/pureRender/normalize.ts +28 -26
  31. package/src/bridge/pureRender/presets.ts +7 -7
  32. package/src/bridge/pureRender/profiles/book.css +122 -19
  33. package/src/bridge/pureRender/profiles/manuscript.css +57 -11
  34. package/src/bridge/pureRender/profiles/writer.css +48 -10
  35. package/src/bridge/pureRender/reset.css +20 -5
  36. package/src/bridge/pureRender/theme.ts +37 -9
  37. package/src/bridge/pureRender/tokens/default.css +45 -33
  38. package/src/bridge/react/usePlatformAgentRunLiveState.tsx +4 -1
  39. package/src/bridge/react/usePlatformAgentSessionDrive.tsx +13 -4
  40. package/src/bridge/screenAnnotation.test.ts +4 -1
  41. package/src/bridge/screenAnnotation.ts +6 -2
  42. package/src/bridge/storage.d.mts +27 -27
  43. package/src/bridge/storage.mjs +18 -18
  44. package/src/bridge/storage.test.ts +49 -49
  45. package/src/bridge/types.ts +62 -58
  46. package/src/bridge/window.d.mts +3 -1
  47. package/src/bridge/workspace.d.mts +7 -0
  48. package/src/bridge/workspace.mjs +8 -0
  49. package/src/bridge/workspace.ts +1 -0
  50. package/src/commitments/commitments.test.ts +10 -3
  51. package/src/commitments/commitments.ts +18 -4
  52. package/src/components/accessibility/AccessibilityReviewDialog.tsx +7 -2
  53. package/src/components/accessibility/accessibilityReview.test.ts +11 -4
  54. package/src/components/accessibility/accessibilityReview.ts +18 -10
  55. package/src/components/agent-feedback/ScreenAnnotationAgentDialog.tsx +9 -2
  56. package/src/components/agents/AgentContextUsageBar.tsx +5 -3
  57. package/src/components/agents/AgentDrawerPanel.test.tsx +15 -3
  58. package/src/components/agents/AgentMessageBubble.tsx +1 -3
  59. package/src/components/agents/AgentQuestionPromptList.tsx +3 -3
  60. package/src/components/agents/AgentToolApprovalActions.tsx +1 -3
  61. package/src/components/agents/agentPanelStyles.ts +1 -1
  62. package/src/components/agents/agentToolDisplay.ts +4 -1
  63. package/src/components/assets/asset-library/AssetLibraryDialog.tsx +2 -0
  64. package/src/components/assets/asset-library/AssetLibraryWorkspace.tsx +2 -0
  65. package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.test.tsx +40 -0
  66. package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.tsx +7 -3
  67. package/src/components/assets/asset-library/detail/AssetLibraryDetailPreview.tsx +8 -8
  68. package/src/components/assets/asset-library/hooks/useAssetLibraryDialog.ts +13 -2
  69. package/src/components/assets/asset-library/hooks/useAssetLibraryMutations.ts +18 -1
  70. package/src/components/assets/asset-library/sidebar/AssetLibraryListRow.tsx +9 -6
  71. package/src/components/assets/asset-library/sidebar/AssetLibrarySidebarToolbar.tsx +3 -1
  72. package/src/components/assets/asset-library/sidebar/AssetListThumbnail.tsx +1 -1
  73. package/src/components/assets/asset-library/types.ts +6 -0
  74. package/src/components/chrome/OverlayActionCapsule.tsx +2 -2
  75. package/src/components/chrome/PanelTabStrip.tsx +3 -2
  76. package/src/components/chrome/PureAppWordmark.tsx +15 -15
  77. package/src/components/chrome/WorkspaceTabStrip.tsx +19 -14
  78. package/src/components/chrome/documentChromePolicy.test.ts +34 -0
  79. package/src/components/chrome/documentChromePolicy.ts +15 -0
  80. package/src/components/chrome/index.ts +4 -0
  81. package/src/components/chrome/workspaceTabTypes.ts +2 -0
  82. package/src/components/common/buttons/Button.tsx +60 -10
  83. package/src/components/common/buttons/ChoiceChip.tsx +2 -2
  84. package/src/components/common/buttons/IconButton.tsx +26 -0
  85. package/src/components/common/buttons/SegmentedControl.tsx +23 -7
  86. package/src/components/common/canvas/CanvasElementFrame.tsx +37 -28
  87. package/src/components/common/canvas/canvasGeometry.test.ts +4 -5
  88. package/src/components/common/canvas/canvasGeometry.ts +1 -4
  89. package/src/components/common/canvas/useCanvasDragResize.test.tsx +10 -10
  90. package/src/components/common/canvas/useCanvasDragResize.ts +1 -4
  91. package/src/components/common/cards/OpenReviewCard.tsx +6 -6
  92. package/src/components/common/chat/ChatBox.test.tsx +9 -1
  93. package/src/components/common/chat/ChatBox.tsx +3 -4
  94. package/src/components/common/chat/ChatMarkdown.tsx +1 -1
  95. package/src/components/common/chat/ChatModelMenu.tsx +1 -1
  96. package/src/components/common/chat/ChatThinkingIndicator.tsx +1 -1
  97. package/src/components/common/chat/ChatThread.tsx +2 -1
  98. package/src/components/common/chat/ChatToolRow.tsx +2 -2
  99. package/src/components/common/chat/ChatUserBubble.tsx +1 -1
  100. package/src/components/common/connections/ConnectionSetup.tsx +6 -6
  101. package/src/components/common/containers/AppFrame.test.tsx +37 -36
  102. package/src/components/common/containers/AppFrame.tsx +15 -0
  103. package/src/components/common/containers/AppHeader.tsx +6 -3
  104. package/src/components/common/containers/SurfacePanel.tsx +1 -0
  105. package/src/components/common/containers/useOpacityPresence.ts +10 -15
  106. package/src/components/common/context/ContextSelector.tsx +10 -10
  107. package/src/components/common/desk/CreationDesk.tsx +23 -11
  108. package/src/components/common/desk/DailyBrief.tsx +18 -7
  109. package/src/components/common/desk/DeskCard.tsx +11 -6
  110. package/src/components/common/dropdown/MenuButtonDropdown.tsx +58 -6
  111. package/src/components/common/dropdown/MenuDropdownItem.tsx +23 -3
  112. package/src/components/common/dropdown/MenuPanel.tsx +8 -8
  113. package/src/components/common/dropdown/SelectMenu.tsx +8 -3
  114. package/src/components/common/dropdown/menuTypes.ts +2 -1
  115. package/src/components/common/evidence/StructuredEvidenceView.tsx +9 -5
  116. package/src/components/common/feedback/Badge.tsx +19 -5
  117. package/src/components/common/feedback/CapabilityPills.tsx +1 -1
  118. package/src/components/common/feedback/InfoHint.tsx +2 -2
  119. package/src/components/common/feedback/PlatformChip.tsx +9 -9
  120. package/src/components/common/feedback/QuietPill.tsx +5 -8
  121. package/src/components/common/feedback/WorkProgressPanel.tsx +14 -14
  122. package/src/components/common/files/FileTable.tsx +8 -2
  123. package/src/components/common/inputs/Checkbox.tsx +1 -1
  124. package/src/components/common/inputs/EditableSecretField.tsx +1 -3
  125. package/src/components/common/inputs/InlineComposer.tsx +2 -2
  126. package/src/components/common/inputs/PaletteDropdown.tsx +33 -23
  127. package/src/components/common/inputs/SurfacePalettePicker.tsx +1 -1
  128. package/src/components/common/inputs/ToggleSwitch.tsx +2 -2
  129. package/src/components/common/inputs/WorkspacePicker.tsx +3 -3
  130. package/src/components/common/lists/listRowStyles.ts +4 -2
  131. package/src/components/common/lists/quiet-ledger/index.ts +1 -4
  132. package/src/components/common/lists/reorderable/DragHandle.tsx +1 -1
  133. package/src/components/common/lists/reorderable/ReorderableSections.tsx +2 -1
  134. package/src/components/common/media/ImageReferencePicker.tsx +22 -14
  135. package/src/components/common/narrative/NarrativeMention.tsx +15 -9
  136. package/src/components/common/navigation/NavigationCardRow.tsx +2 -2
  137. package/src/components/common/navigation/UnderlineTabs.tsx +1 -0
  138. package/src/components/common/overlays/Modal.tsx +52 -3
  139. package/src/components/common/overlays/ObjectActionStrip.tsx +2 -2
  140. package/src/components/common/people/AutoUpdateReviewList.tsx +2 -2
  141. package/src/components/common/people/EntityList.tsx +7 -3
  142. package/src/components/common/people/EntityPortrait.tsx +6 -1
  143. package/src/components/common/people/LinkedDossierList.tsx +3 -1
  144. package/src/components/common/people/RelationshipMap.tsx +3 -9
  145. package/src/components/common/research/EvidenceDossier.tsx +24 -20
  146. package/src/components/common/tiles/CatalogCard.tsx +1 -1
  147. package/src/components/credentials/CredentialsPanel.tsx +2 -6
  148. package/src/components/data/DataChart.tsx +119 -94
  149. package/src/components/data/dataTable.ts +4 -1
  150. package/src/components/editor/DocumentAppChrome.tsx +172 -0
  151. package/src/components/editor/EditorCommentPromptDialog.tsx +1 -1
  152. package/src/components/editor/EditorLinkPromptDialog.tsx +1 -1
  153. package/src/components/print-design/PrintDesignPanel.test.tsx +8 -6
  154. package/src/components/print-design/PrintDesignPanel.tsx +18 -25
  155. package/src/components/proofing/PagedProofDialog.tsx +17 -4
  156. package/src/editor/EditorViewModeToggle.tsx +6 -2
  157. package/src/editor/index.ts +6 -0
  158. package/src/theme/ThemeProvider.tsx +5 -2
  159. package/src/theme/appAccents.test.ts +51 -0
  160. package/src/theme/appAccents.ts +151 -88
  161. package/src/theme/appIdentityCss.mjs +256 -0
  162. package/src/theme/appIdentityCss.ts +256 -0
  163. package/src/theme/composePlatformTheme.test.ts +43 -14
  164. package/src/theme/platformFont.d.mts +2 -2
  165. package/src/theme/platformFont.mjs +4 -3
  166. package/src/theme/reportsShellChromeSelectors.ts +14 -132
  167. package/src/theme/surfaceCss.mjs +37 -0
  168. package/src/theme/surfaceCss.ts +37 -0
  169. package/src/theme/surfacePalettes.ts +120 -79
  170. package/src/theme/surfaceRoleSelectors.ts +135 -71
  171. package/src/theme/themes/dark.ts +44 -43
  172. package/src/theme/themes/light.ts +40 -38
  173. package/src/theme/themes/palette.ts +32 -30
  174. package/src/theme/themes/shared.ts +17 -17
  175. package/src/theme/utils/GlobalStyles.ts +10 -6
  176. package/src/theme/utils/appFrameDocumentStyles.mjs +6 -1
  177. package/src/theme/utils/cssVariables.ts +169 -0
  178. package/src/writing/DraftAssistantDialog.tsx +85 -85
  179. package/src/writing/WritingStyleManager.tsx +6 -3
  180. package/src/writing/draftTextWithAgent.ts +47 -50
  181. package/src/writing/styleStore.ts +4 -3
  182. package/src/writing/writingStyle.test.ts +8 -2
  183. package/src/writing/writingStyle.ts +19 -8
@@ -1,18 +1,18 @@
1
- import { bridge } from './client.mjs'
2
- import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
-
4
- /**
5
- * @param {{ appSlug: string, fileName: string }} request
6
- * @returns {Promise<{ path: string, value: unknown | null }>}
7
- */
8
- export async function readPlatformStorageJson(request) {
9
- return bridge.call(PLATFORM_BRIDGE_METHODS.STORAGE_READ_JSON, [request])
10
- }
11
-
12
- /**
13
- * @param {{ appSlug: string, fileName: string, value: unknown }} request
14
- * @returns {Promise<{ path: string, ok: true }>}
15
- */
16
- export async function writePlatformStorageJson(request) {
17
- return bridge.call(PLATFORM_BRIDGE_METHODS.STORAGE_WRITE_JSON, [request])
18
- }
1
+ import { bridge } from './client.mjs'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ /**
5
+ * @param {{ appSlug: string, fileName: string }} request
6
+ * @returns {Promise<{ path: string, value: unknown | null }>}
7
+ */
8
+ export async function readPlatformStorageJson(request) {
9
+ return bridge.call(PLATFORM_BRIDGE_METHODS.STORAGE_READ_JSON, [request])
10
+ }
11
+
12
+ /**
13
+ * @param {{ appSlug: string, fileName: string, value: unknown }} request
14
+ * @returns {Promise<{ path: string, ok: true }>}
15
+ */
16
+ export async function writePlatformStorageJson(request) {
17
+ return bridge.call(PLATFORM_BRIDGE_METHODS.STORAGE_WRITE_JSON, [request])
18
+ }
@@ -1,49 +1,49 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest'
2
- import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
-
4
- const bridgeCall = vi.hoisted(() => vi.fn())
5
-
6
- vi.mock('./client.mjs', () => ({
7
- bridge: {
8
- call: bridgeCall,
9
- },
10
- }))
11
-
12
- import {
13
- readPlatformStorageJson,
14
- writePlatformStorageJson,
15
- } from './storage.mjs'
16
-
17
- beforeEach(() => {
18
- bridgeCall.mockReset()
19
- })
20
-
21
- describe('storage bridge helpers', () => {
22
- it('reads JSON storage using the shell request object shape', async () => {
23
- const request = { appSlug: 'puretasks', fileName: 'tasks.json' }
24
- bridgeCall.mockResolvedValue({ path: '/tmp/tasks.json', value: null })
25
-
26
- await readPlatformStorageJson(request)
27
-
28
- expect(bridgeCall).toHaveBeenCalledWith(
29
- PLATFORM_BRIDGE_METHODS.STORAGE_READ_JSON,
30
- [request],
31
- )
32
- })
33
-
34
- it('writes JSON storage using the shell request object shape', async () => {
35
- const request = {
36
- appSlug: 'puretasks',
37
- fileName: 'tasks.json',
38
- value: { tasks: [] },
39
- }
40
- bridgeCall.mockResolvedValue({ path: '/tmp/tasks.json', ok: true })
41
-
42
- await writePlatformStorageJson(request)
43
-
44
- expect(bridgeCall).toHaveBeenCalledWith(
45
- PLATFORM_BRIDGE_METHODS.STORAGE_WRITE_JSON,
46
- [request],
47
- )
48
- })
49
- })
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ const bridgeCall = vi.hoisted(() => vi.fn())
5
+
6
+ vi.mock('./client.mjs', () => ({
7
+ bridge: {
8
+ call: bridgeCall,
9
+ },
10
+ }))
11
+
12
+ import {
13
+ readPlatformStorageJson,
14
+ writePlatformStorageJson,
15
+ } from './storage.mjs'
16
+
17
+ beforeEach(() => {
18
+ bridgeCall.mockReset()
19
+ })
20
+
21
+ describe('storage bridge helpers', () => {
22
+ it('reads JSON storage using the shell request object shape', async () => {
23
+ const request = { appSlug: 'puretasks', fileName: 'tasks.json' }
24
+ bridgeCall.mockResolvedValue({ path: '/tmp/tasks.json', value: null })
25
+
26
+ await readPlatformStorageJson(request)
27
+
28
+ expect(bridgeCall).toHaveBeenCalledWith(
29
+ PLATFORM_BRIDGE_METHODS.STORAGE_READ_JSON,
30
+ [request],
31
+ )
32
+ })
33
+
34
+ it('writes JSON storage using the shell request object shape', async () => {
35
+ const request = {
36
+ appSlug: 'puretasks',
37
+ fileName: 'tasks.json',
38
+ value: { tasks: [] },
39
+ }
40
+ bridgeCall.mockResolvedValue({ path: '/tmp/tasks.json', ok: true })
41
+
42
+ await writePlatformStorageJson(request)
43
+
44
+ expect(bridgeCall).toHaveBeenCalledWith(
45
+ PLATFORM_BRIDGE_METHODS.STORAGE_WRITE_JSON,
46
+ [request],
47
+ )
48
+ })
49
+ })
@@ -34,6 +34,10 @@ export interface PlatformShellPreferences {
34
34
  betaFeatures?: {
35
35
  /** Enables model-backed Pure Render reference-image extraction in app panels. */
36
36
  pureRenderVisionExtraction?: boolean
37
+ /** Enables unfinished claim/fact-check review entry points. */
38
+ factCheck?: boolean
39
+ /** Enables the unfinished Manuscript More launcher menu. */
40
+ manuscriptMoreMenu?: boolean
37
41
  }
38
42
  /**
39
43
  * Host-only workspace tab session (phase 4). Plugin apps should ignore this field.
@@ -255,64 +259,64 @@ export interface PlatformAppInstallState {
255
259
  pluginRoot?: string
256
260
  }
257
261
 
258
- export interface PlatformFileReadPreviewResult {
259
- path: string
260
- content: string | null
261
- truncated: boolean
262
- encoding: 'utf-8'
263
- }
264
-
265
- export interface PlatformFileEntry {
266
- path: string
267
- name: string
268
- extension: string
269
- kind: PlatformFileKind
270
- mimeType: string
271
- byteLength: number
272
- modifiedAt: string
273
- isDirectory: boolean
274
- }
275
-
276
- export interface PlatformFileListResult {
277
- rootPath: string
278
- parentPath: string | null
279
- entries: PlatformFileEntry[]
280
- }
281
-
282
- export interface PlatformFileReadBinaryResult {
283
- path: string
284
- mimeType: string
285
- base64: string
286
- truncated: boolean
287
- byteLength: number
288
- }
289
-
290
- export interface PlatformFilePreviewUrlResult {
291
- path: string
292
- url: string
293
- mimeType: string
294
- byteLength: number
295
- }
296
-
297
- export interface PlatformFileCreateFolderResult {
298
- path: string
299
- }
300
-
301
- export interface PlatformFileRenameResult {
302
- path: string
303
- }
304
-
305
- export interface PlatformFileWriteResult {
306
- ok: true
307
- }
308
-
309
- export interface PlatformFileDeleteResult {
310
- ok: true
311
- }
312
-
313
- /** Minimal file entry fields required for inline preview in plugin iframes. */
314
- export interface PlatformFilePreviewEntry {
315
- path: string
262
+ export interface PlatformFileReadPreviewResult {
263
+ path: string
264
+ content: string | null
265
+ truncated: boolean
266
+ encoding: 'utf-8'
267
+ }
268
+
269
+ export interface PlatformFileEntry {
270
+ path: string
271
+ name: string
272
+ extension: string
273
+ kind: PlatformFileKind
274
+ mimeType: string
275
+ byteLength: number
276
+ modifiedAt: string
277
+ isDirectory: boolean
278
+ }
279
+
280
+ export interface PlatformFileListResult {
281
+ rootPath: string
282
+ parentPath: string | null
283
+ entries: PlatformFileEntry[]
284
+ }
285
+
286
+ export interface PlatformFileReadBinaryResult {
287
+ path: string
288
+ mimeType: string
289
+ base64: string
290
+ truncated: boolean
291
+ byteLength: number
292
+ }
293
+
294
+ export interface PlatformFilePreviewUrlResult {
295
+ path: string
296
+ url: string
297
+ mimeType: string
298
+ byteLength: number
299
+ }
300
+
301
+ export interface PlatformFileCreateFolderResult {
302
+ path: string
303
+ }
304
+
305
+ export interface PlatformFileRenameResult {
306
+ path: string
307
+ }
308
+
309
+ export interface PlatformFileWriteResult {
310
+ ok: true
311
+ }
312
+
313
+ export interface PlatformFileDeleteResult {
314
+ ok: true
315
+ }
316
+
317
+ /** Minimal file entry fields required for inline preview in plugin iframes. */
318
+ export interface PlatformFilePreviewEntry {
319
+ path: string
316
320
  name: string
317
321
  extension: string
318
322
  kind: PlatformFileKind
@@ -41,4 +41,6 @@ export declare function startScreenCapture(options?: {
41
41
  options?: PlatformScreenCaptureOption[]
42
42
  }): Promise<PlatformScreenCaptureResult | null>
43
43
 
44
- export declare function onScreenCaptureShortcut(listener: () => void): () => void
44
+ export declare function onScreenCaptureShortcut(
45
+ listener: () => void,
46
+ ): () => void
@@ -0,0 +1,7 @@
1
+ export interface UpdateCurrentWorkspaceTabRequest {
2
+ title?: string
3
+ }
4
+
5
+ export declare function updateCurrentWorkspaceTab(
6
+ request: UpdateCurrentWorkspaceTabRequest,
7
+ ): Promise<{ updated: boolean }>
@@ -0,0 +1,8 @@
1
+ import { bridge } from './client.mjs'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ export function updateCurrentWorkspaceTab(request) {
5
+ return bridge.call(PLATFORM_BRIDGE_METHODS.WORKSPACE_UPDATE_CURRENT_TAB, [
6
+ request,
7
+ ])
8
+ }
@@ -0,0 +1 @@
1
+ export { updateCurrentWorkspaceTab } from './workspace.mjs'
@@ -129,10 +129,15 @@ describe('commitments domain model', () => {
129
129
  ),
130
130
  '2026-06-21T13:00:00.000Z',
131
131
  )
132
- const store = { ...emptyCommitmentStore(), commitments: [resolved, dismissed] }
132
+ const store = {
133
+ ...emptyCommitmentStore(),
134
+ commitments: [resolved, dismissed],
135
+ }
133
136
 
134
137
  expect(commitmentBuckets(store, { now: NOW }).youOwe).toHaveLength(0)
135
- expect(commitmentBuckets(store, { now: NOW, includeClosed: true }).youOwe).toHaveLength(1)
138
+ expect(
139
+ commitmentBuckets(store, { now: NOW, includeClosed: true }).youOwe,
140
+ ).toHaveLength(1)
136
141
  })
137
142
 
138
143
  it('hides snoozed commitments until their snooze date', () => {
@@ -195,7 +200,9 @@ describe('commitments domain model', () => {
195
200
  )
196
201
  const store = { ...emptyCommitmentStore(), commitments: [commitment] }
197
202
 
198
- expect(commitmentsByCounterparty(store, 'mira', { now: NOW })).toHaveLength(1)
203
+ expect(commitmentsByCounterparty(store, 'mira', { now: NOW })).toHaveLength(
204
+ 1,
205
+ )
199
206
  expect(store.commitments[0].links?.[0].type).toBe('task')
200
207
  })
201
208
  })
@@ -219,7 +219,12 @@ export function reactivateSnoozedCommitments(
219
219
  commitment.status === 'snoozed' &&
220
220
  commitment.snoozedUntil &&
221
221
  commitment.snoozedUntil <= now
222
- ? { ...commitment, status: 'open', snoozedUntil: undefined, updatedAt: now }
222
+ ? {
223
+ ...commitment,
224
+ status: 'open',
225
+ snoozedUntil: undefined,
226
+ updatedAt: now,
227
+ }
223
228
  : commitment,
224
229
  ),
225
230
  }
@@ -270,13 +275,18 @@ export function commitmentBuckets(
270
275
  options: CommitmentQueryOptions = {},
271
276
  ): CommitmentBuckets {
272
277
  const now = options.now ?? new Date().toISOString()
273
- const commitments = openCommitments(store, { ...options, includeClosed: true })
278
+ const commitments = openCommitments(store, {
279
+ ...options,
280
+ includeClosed: true,
281
+ })
274
282
  const visible = commitments.filter(
275
283
  commitment => options.includeClosed || commitment.status === 'open',
276
284
  )
277
285
  return {
278
286
  youOwe: visible.filter(commitment => commitment.direction === 'you_owe'),
279
- waitingOn: visible.filter(commitment => commitment.direction === 'waiting_on'),
287
+ waitingOn: visible.filter(
288
+ commitment => commitment.direction === 'waiting_on',
289
+ ),
280
290
  dueToday: visible.filter(
281
291
  commitment => commitmentDueState(commitment, now) === 'due_today',
282
292
  ),
@@ -322,7 +332,11 @@ export function commitmentsByCounterparty(
322
332
  }
323
333
 
324
334
  function validateCommitmentSource(input: CommitmentInput | Commitment): void {
325
- if (input.source && input.source.type !== 'manual' && !input.sourceQuote?.trim()) {
335
+ if (
336
+ input.source &&
337
+ input.source.type !== 'manual' &&
338
+ !input.sourceQuote?.trim()
339
+ ) {
326
340
  throw new Error('Extracted commitments require a source quote.')
327
341
  }
328
342
  }
@@ -291,7 +291,10 @@ export function AccessibilityReviewDialog({
291
291
  setDismissed(new Set())
292
292
  }, [html])
293
293
 
294
- const applyAndDismiss = (issue: AccessibilityIssue, nextHtml: string): void => {
294
+ const applyAndDismiss = (
295
+ issue: AccessibilityIssue,
296
+ nextHtml: string,
297
+ ): void => {
295
298
  onChange(nextHtml)
296
299
  setDismissed(current => new Set(current).add(issue.id))
297
300
  }
@@ -316,7 +319,9 @@ export function AccessibilityReviewDialog({
316
319
  No chapter-level accessibility findings in this pass.
317
320
  </InlineBanner>
318
321
  ) : visibleIssues.length === 0 ? (
319
- <InlineBanner>All findings in this queue are handled or ignored.</InlineBanner>
322
+ <InlineBanner>
323
+ All findings in this queue are handled or ignored.
324
+ </InlineBanner>
320
325
  ) : (
321
326
  <StyledQueue>
322
327
  {visibleIssues.map(issue => (
@@ -58,7 +58,8 @@ describe('applyAccessibilityIssueFix', () => {
58
58
 
59
59
  describe('accessibility draft fixes', () => {
60
60
  it('drafts image alt text from nearby figure captions', () => {
61
- const html = '<figure><img src="chart.png"><figcaption>Revenue by quarter</figcaption></figure>'
61
+ const html =
62
+ '<figure><img src="chart.png"><figcaption>Revenue by quarter</figcaption></figure>'
62
63
  const issue = auditHtmlAccessibility(html).find(
63
64
  finding => finding.ruleId === 'image-missing-alt',
64
65
  )
@@ -67,12 +68,17 @@ describe('accessibility draft fixes', () => {
67
68
  const draft = getAccessibilityIssueDraft(html, issue!)
68
69
  expect(draft?.value).toBe('Revenue by quarter')
69
70
 
70
- const fixed = applyAccessibilityIssueDraft(html, issue!, 'Quarterly revenue trend')
71
+ const fixed = applyAccessibilityIssueDraft(
72
+ html,
73
+ issue!,
74
+ 'Quarterly revenue trend',
75
+ )
71
76
  expect(fixed).toContain('alt="Quarterly revenue trend"')
72
77
  })
73
78
 
74
79
  it('drafts table captions from header-like first rows', () => {
75
- const html = '<table><tr><td>Name</td><td>Value</td></tr><tr><td>A</td><td>2</td></tr></table>'
80
+ const html =
81
+ '<table><tr><td>Name</td><td>Value</td></tr><tr><td>A</td><td>2</td></tr></table>'
76
82
  const issue = auditHtmlAccessibility(html).find(
77
83
  finding => finding.ruleId === 'table-missing-caption',
78
84
  )
@@ -86,7 +92,8 @@ describe('accessibility draft fixes', () => {
86
92
  })
87
93
 
88
94
  it('drafts clearer link labels from the destination', () => {
89
- const html = '<p><a href="https://example.com/research-notes">click here</a></p>'
95
+ const html =
96
+ '<p><a href="https://example.com/research-notes">click here</a></p>'
90
97
  const issue = auditHtmlAccessibility(html).find(
91
98
  finding => finding.ruleId === 'link-ambiguous-label',
92
99
  )
@@ -120,10 +120,7 @@ function humanizePathPart(value: string): string {
120
120
  const withoutQuery = value.split(/[?#]/)[0] ?? ''
121
121
  const lastPart = withoutQuery.split('/').filter(Boolean).pop() ?? ''
122
122
  const withoutExtension = lastPart.replace(/\.[a-z0-9]+$/i, '')
123
- return withoutExtension
124
- .replace(/[-_]+/g, ' ')
125
- .replace(/\s+/g, ' ')
126
- .trim()
123
+ return withoutExtension.replace(/[-_]+/g, ' ').replace(/\s+/g, ' ').trim()
127
124
  }
128
125
 
129
126
  function readableLinkDestination(href: string): string {
@@ -186,7 +183,9 @@ function figureCaptionDraft(figure: Element): string {
186
183
  const alt = image?.getAttribute('alt')?.trim()
187
184
  if (alt) return clipDraft(alt)
188
185
 
189
- const sourceLabel = image ? humanizePathPart(image.getAttribute('src') ?? '') : ''
186
+ const sourceLabel = image
187
+ ? humanizePathPart(image.getAttribute('src') ?? '')
188
+ : ''
190
189
  if (sourceLabel) return clipDraft(sourceLabel, 100)
191
190
 
192
191
  return nearbySentence(figure) || 'Figure summary'
@@ -384,7 +383,9 @@ export function auditHtmlAccessibility(html: string): AccessibilityIssue[] {
384
383
 
385
384
  for (const media of Array.from(main.querySelectorAll('video,audio'))) {
386
385
  const target = selectorFor(media)
387
- if (!media.querySelector('track[kind="captions"],track[kind="subtitles"]')) {
386
+ if (
387
+ !media.querySelector('track[kind="captions"],track[kind="subtitles"]')
388
+ ) {
388
389
  pushIssue(issues, {
389
390
  ruleId: 'media-missing-captions',
390
391
  category: 'media',
@@ -427,7 +428,10 @@ export function auditHtmlAccessibility(html: string): AccessibilityIssue[] {
427
428
  return issues
428
429
  }
429
430
 
430
- function findTarget(document: Document, issue: AccessibilityIssue): Element | null {
431
+ function findTarget(
432
+ document: Document,
433
+ issue: AccessibilityIssue,
434
+ ): Element | null {
431
435
  const main = document.body.querySelector('main')
432
436
  return issue.target ? main?.querySelector(issue.target) ?? null : null
433
437
  }
@@ -476,7 +480,8 @@ export function applyAccessibilityIssueFix(
476
480
  header.setAttribute('scope', 'col')
477
481
  header.innerHTML = cell.innerHTML
478
482
  for (const attr of Array.from(cell.attributes)) {
479
- if (attr.name !== 'scope') header.setAttribute(attr.name, attr.value)
483
+ if (attr.name !== 'scope')
484
+ header.setAttribute(attr.name, attr.value)
480
485
  }
481
486
  cell.replaceWith(header)
482
487
  }
@@ -527,7 +532,8 @@ export function getAccessibilityIssueDraft(
527
532
  case 'table-missing-caption':
528
533
  return {
529
534
  label: 'Caption',
530
- description: 'A brief table title for readers and assistive technology.',
535
+ description:
536
+ 'A brief table title for readers and assistive technology.',
531
537
  value: tableCaptionDraft(target),
532
538
  applyLabel: 'Add caption',
533
539
  }
@@ -628,7 +634,9 @@ export function annotateAccessibilityIssue(
628
634
  target.setAttribute('data-comment-type', 'agent-review')
629
635
  target.setAttribute(
630
636
  'data-comment-text',
631
- `${issue.title}: ${issue.detail} (${issue.standard} ${issue.wcag.join(', ')})`,
637
+ `${issue.title}: ${issue.detail} (${issue.standard} ${issue.wcag.join(
638
+ ', ',
639
+ )})`,
632
640
  )
633
641
  target.setAttribute('data-comment-author', ISSUE_AUTHOR)
634
642
  target.setAttribute('data-comment-created-at', new Date().toISOString())
@@ -138,7 +138,10 @@ function drawLine(
138
138
  context.restore()
139
139
  }
140
140
 
141
- function normalizeRect(start: { x: number; y: number }, end: { x: number; y: number }): Rect {
141
+ function normalizeRect(
142
+ start: { x: number; y: number },
143
+ end: { x: number; y: number },
144
+ ): Rect {
142
145
  return {
143
146
  x: Math.min(start.x, end.x),
144
147
  y: Math.min(start.y, end.y),
@@ -158,7 +161,11 @@ function defaultSelection(canvas: HTMLCanvasElement): Rect {
158
161
  }
159
162
  }
160
163
 
161
- function drawSelectionOverlay(canvas: HTMLCanvasElement, source: HTMLCanvasElement, rect: Rect): void {
164
+ function drawSelectionOverlay(
165
+ canvas: HTMLCanvasElement,
166
+ source: HTMLCanvasElement,
167
+ rect: Rect,
168
+ ): void {
162
169
  const context = canvas.getContext('2d')
163
170
  if (!context) return
164
171
  canvas.width = source.width
@@ -48,10 +48,12 @@ export function AgentContextUsageBar({
48
48
  const percent = usage ? contextUsagePercent(usage) : undefined
49
49
  const label =
50
50
  total && usage?.contextWindowTokens
51
- ? `${prefix}${total} / ${formatAgentTokenCount(usage.contextWindowTokens)}`
51
+ ? `${prefix}${total} / ${formatAgentTokenCount(
52
+ usage.contextWindowTokens,
53
+ )}`
52
54
  : total
53
- ? `${prefix}${total} tokens`
54
- : null
55
+ ? `${prefix}${total} tokens`
56
+ : null
55
57
 
56
58
  if (!label) return null
57
59
 
@@ -1,6 +1,14 @@
1
1
  import { act } from 'react'
2
2
  import { createRoot, type Root } from 'react-dom/client'
3
- import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
3
+ import {
4
+ afterEach,
5
+ beforeAll,
6
+ beforeEach,
7
+ describe,
8
+ expect,
9
+ it,
10
+ vi,
11
+ } from 'vitest'
4
12
  import { AgentDrawerPanel } from './AgentDrawerPanel.js'
5
13
  import {
6
14
  AgentLivePhase,
@@ -205,7 +213,9 @@ describe('AgentDrawerPanel composer and steering behavior', () => {
205
213
  }),
206
214
  )
207
215
 
208
- const sendNow = host.querySelector('button[aria-label="Send follow-up now"]')
216
+ const sendNow = host.querySelector(
217
+ 'button[aria-label="Send follow-up now"]',
218
+ )
209
219
  const remove = host.querySelector('button[aria-label="Remove follow-up"]')
210
220
  const textarea = host.querySelector('textarea')
211
221
  const composerSurface = textarea?.parentElement
@@ -244,7 +254,9 @@ describe('AgentDrawerPanel composer and steering behavior', () => {
244
254
  }),
245
255
  )
246
256
 
247
- const sendNow = host.querySelector('button[aria-label="Send follow-up now"]')
257
+ const sendNow = host.querySelector(
258
+ 'button[aria-label="Send follow-up now"]',
259
+ )
248
260
 
249
261
  expect(sendNow).toBeInstanceOf(HTMLButtonElement)
250
262
  expect((sendNow as HTMLButtonElement).disabled).toBe(false)
@@ -104,9 +104,7 @@ function formatToolRowSummary(call: AgentUiToolCall): string {
104
104
  return formatAgentToolRowSummary(call)
105
105
  }
106
106
 
107
- function formatToolRowDetails(
108
- call: AgentUiToolCall,
109
- ): string[] | undefined {
107
+ function formatToolRowDetails(call: AgentUiToolCall): string[] | undefined {
110
108
  if (call.delegatedActivity) {
111
109
  return delegatedActivityDetails(call.delegatedActivity)
112
110
  }
@@ -39,7 +39,7 @@ const StyledPrompt = styled(FlexCol)`
39
39
  gap: var(--platform-spacing-sm);
40
40
  padding: 10px;
41
41
  border: 1px solid var(--platform-colors-border);
42
- border-radius: 8px;
42
+ border-radius: var(--platform-radius-sm);
43
43
  background: var(--platform-colors-bg);
44
44
  `
45
45
 
@@ -62,7 +62,7 @@ const StyledOptionButton = styled.button<{ $selected: boolean }>`
62
62
  $selected
63
63
  ? 'var(--platform-colors-accent)'
64
64
  : 'var(--platform-colors-border)'};
65
- border-radius: var(--platform-radius-sm, 6px);
65
+ border-radius: var(--platform-radius-sm);
66
66
  background: ${({ $selected }) =>
67
67
  $selected
68
68
  ? 'color-mix(in srgb, var(--platform-colors-accent) 10%, var(--platform-colors-bg))'
@@ -98,7 +98,7 @@ const StyledDeclineInput = styled.input`
98
98
  height: 28px;
99
99
  padding: 0 9px;
100
100
  border: 1px solid var(--platform-colors-border);
101
- border-radius: var(--platform-radius-sm, 6px);
101
+ border-radius: var(--platform-radius-sm);
102
102
  background: var(--platform-colors-surface);
103
103
  color: var(--platform-colors-text);
104
104
  font: inherit;
@@ -39,9 +39,7 @@ export function AgentToolApprovalActions({
39
39
  disabled={busy}
40
40
  menuPlacement="above"
41
41
  aria-label="Approve"
42
- onSelect={() =>
43
- onApproveAlwaysForSession(toolCall.name, toolCall.id)
44
- }
42
+ onSelect={() => onApproveAlwaysForSession(toolCall.name, toolCall.id)}
45
43
  />
46
44
  ) : (
47
45
  <Button
@@ -132,7 +132,7 @@ export const StyledFollowUpRow = styled.div`
132
132
  min-width: 0;
133
133
  padding: 6px 8px;
134
134
  border: 1px solid var(--platform-colors-border);
135
- border-radius: 8px;
135
+ border-radius: var(--platform-radius-sm, 0px);
136
136
  background: var(--platform-colors-bg);
137
137
  `
138
138