@parallelworks/ui 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (622) hide show
  1. package/README.md +348 -25
  2. package/dist/ai/agent/diff.d.ts +2 -1
  3. package/dist/ai/agent/diff.js +4 -12
  4. package/dist/ai/agent/diffHighlight.d.ts +1 -1
  5. package/dist/ai/agent/diffHighlight.js +4 -3
  6. package/dist/ai/agent/index.d.ts +2 -1
  7. package/dist/ai/agent/toolStrings.d.ts +37 -0
  8. package/dist/ai/agent/toolStrings.js +35 -0
  9. package/dist/ai/agent/toolfmt.d.ts +8 -3
  10. package/dist/ai/agent/toolfmt.js +50 -65
  11. package/dist/ai/ai.css +18 -31
  12. package/dist/ai/components/AllocationSelector.js +2 -2
  13. package/dist/ai/components/AttachmentManager.js +28 -29
  14. package/dist/ai/components/AttachmentUpload.js +25 -30
  15. package/dist/ai/components/BlockedGroupBanner.js +2 -2
  16. package/dist/ai/components/BranchNavigator.js +3 -4
  17. package/dist/ai/components/ChatEmptyState.js +8 -7
  18. package/dist/ai/components/ChatInput.js +10 -12
  19. package/dist/ai/components/ChatLayout.js +3 -3
  20. package/dist/ai/components/ChatMessage.js +49 -61
  21. package/dist/ai/components/ChatMessageList.js +46 -42
  22. package/dist/ai/components/ChatSidebar.js +26 -34
  23. package/dist/ai/components/ChatStage.js +1 -1
  24. package/dist/ai/components/ComposerChrome.js +3 -4
  25. package/dist/ai/components/DragOverlay.js +6 -4
  26. package/dist/ai/components/ModelSelector.js +14 -15
  27. package/dist/ai/components/PastedText.js +18 -14
  28. package/dist/ai/components/ProviderIssueBanner.js +3 -4
  29. package/dist/ai/components/Reasoning.d.ts +12 -6
  30. package/dist/ai/components/Reasoning.js +31 -18
  31. package/dist/ai/components/ShareDialog.js +25 -28
  32. package/dist/ai/components/SlashMenu.js +3 -3
  33. package/dist/ai/components/agent/ActivityLine.d.ts +0 -5
  34. package/dist/ai/components/agent/ActivityLine.js +17 -54
  35. package/dist/ai/components/agent/AgentMessageParts.js +139 -149
  36. package/dist/ai/components/conversationActions.js +16 -16
  37. package/dist/ai/core/ChatProvider.d.ts +2 -4
  38. package/dist/ai/core/ChatProvider.js +25 -38
  39. package/dist/ai/core/exportConversation.js +4 -4
  40. package/dist/ai/core/sidebarState.d.ts +8 -6
  41. package/dist/ai/core/sidebarState.js +21 -28
  42. package/dist/ai/core/useKeyboardShortcuts.js +14 -5
  43. package/dist/ai/index.d.ts +4 -5
  44. package/dist/ai/index.js +7 -7
  45. package/dist/ai/strings.d.ts +14 -31
  46. package/dist/ai/strings.js +19 -39
  47. package/dist/ai/types.d.ts +0 -5
  48. package/dist/ai/ui/ConversationSidebar.d.ts +12 -9
  49. package/dist/ai/ui/ConversationSidebar.js +43 -87
  50. package/dist/ai/ui/Markdown.d.ts +3 -6
  51. package/dist/ai/ui/Markdown.js +6 -73
  52. package/dist/ai/ui/Notice.js +10 -12
  53. package/dist/ai/ui/chip.d.ts +2 -2
  54. package/dist/ai/ui/chip.js +1 -1
  55. package/dist/ai/ui/sidebar.d.ts +4 -20
  56. package/dist/ai/ui/sidebar.js +30 -67
  57. package/dist/ai/utils.d.ts +0 -1
  58. package/dist/ai/utils.js +1 -14
  59. package/dist/brandIcons.d.ts +51 -0
  60. package/dist/brandIcons.js +75 -0
  61. package/dist/components/Avatar.d.ts +3 -1
  62. package/dist/components/Avatar.js +34 -28
  63. package/dist/components/Button.d.ts +12 -7
  64. package/dist/components/Button.js +39 -44
  65. package/dist/components/Callout.js +18 -12
  66. package/dist/components/Card.d.ts +18 -8
  67. package/dist/components/Card.js +17 -6
  68. package/dist/components/Checkbox.d.ts +9 -0
  69. package/dist/components/Checkbox.js +30 -0
  70. package/dist/components/Combobox.d.ts +9 -1
  71. package/dist/components/Combobox.js +71 -44
  72. package/dist/components/ConfirmModal.js +11 -11
  73. package/dist/components/ContextMenu.d.ts +2 -8
  74. package/dist/components/ContextMenu.js +2 -29
  75. package/dist/components/CopyToClipboard.js +17 -36
  76. package/dist/components/CreateModal.d.ts +3 -24
  77. package/dist/components/CreateModal.js +46 -113
  78. package/dist/components/DatePicker.d.ts +31 -0
  79. package/dist/components/DatePicker.js +191 -0
  80. package/dist/components/DescriptionList.js +4 -4
  81. package/dist/components/Disclosure.d.ts +34 -0
  82. package/dist/components/Disclosure.js +46 -0
  83. package/dist/components/Drawer.d.ts +47 -0
  84. package/dist/components/Drawer.js +120 -0
  85. package/dist/components/EmptyState.d.ts +15 -10
  86. package/dist/components/EmptyState.js +13 -8
  87. package/dist/components/ExternalLink.d.ts +8 -0
  88. package/dist/components/ExternalLink.js +29 -0
  89. package/dist/components/Field.d.ts +70 -0
  90. package/dist/components/Field.js +159 -0
  91. package/dist/components/HoverCard.js +11 -14
  92. package/dist/components/IconButton.d.ts +16 -13
  93. package/dist/components/IconButton.js +27 -18
  94. package/dist/components/InfoTip.js +16 -23
  95. package/dist/components/Input.d.ts +10 -9
  96. package/dist/components/Input.js +54 -96
  97. package/dist/components/LetterBadge.js +2 -2
  98. package/dist/components/Loader.d.ts +15 -8
  99. package/dist/components/Loader.js +29 -19
  100. package/dist/components/Markdown.d.ts +7 -1
  101. package/dist/components/Markdown.js +2 -0
  102. package/dist/components/MarkdownImpl.d.ts +1 -1
  103. package/dist/components/MarkdownImpl.js +55 -14
  104. package/dist/components/Menu.js +13 -15
  105. package/dist/components/MenuEntries.js +11 -16
  106. package/dist/components/Meter.d.ts +48 -0
  107. package/dist/components/Meter.js +94 -0
  108. package/dist/components/Modal.js +11 -14
  109. package/dist/components/NumberInput.d.ts +25 -0
  110. package/dist/components/NumberInput.js +55 -0
  111. package/dist/components/Overview.js +12 -10
  112. package/dist/components/PageHeader.d.ts +2 -3
  113. package/dist/components/PageHeader.js +30 -21
  114. package/dist/components/Pagination.d.ts +27 -14
  115. package/dist/components/Pagination.js +86 -25
  116. package/dist/components/Popover.d.ts +47 -0
  117. package/dist/components/Popover.js +63 -0
  118. package/dist/components/Provider.d.ts +197 -80
  119. package/dist/components/Provider.js +200 -118
  120. package/dist/components/Radio.d.ts +1 -1
  121. package/dist/components/Radio.js +4 -4
  122. package/dist/components/RefreshButton.d.ts +15 -0
  123. package/dist/components/RefreshButton.js +53 -0
  124. package/dist/components/RunStatusIcon.d.ts +12 -0
  125. package/dist/components/RunStatusIcon.js +84 -0
  126. package/dist/components/SearchInput.d.ts +16 -0
  127. package/dist/components/SearchInput.js +52 -0
  128. package/dist/components/Section.d.ts +28 -0
  129. package/dist/components/Section.js +76 -0
  130. package/dist/components/SegmentedControl.d.ts +7 -11
  131. package/dist/components/SegmentedControl.js +25 -56
  132. package/dist/components/Select.d.ts +5 -1
  133. package/dist/components/Select.js +43 -44
  134. package/dist/components/SettingModeOption.d.ts +3 -5
  135. package/dist/components/SettingModeOption.js +5 -6
  136. package/dist/components/SettingsCard.d.ts +32 -19
  137. package/dist/components/SettingsCard.js +40 -13
  138. package/dist/components/Skeleton.d.ts +22 -0
  139. package/dist/components/Skeleton.js +34 -0
  140. package/dist/components/Slider.d.ts +16 -0
  141. package/dist/components/Slider.js +30 -0
  142. package/dist/components/Sort.js +4 -6
  143. package/dist/components/StatusBadge.d.ts +3 -1
  144. package/dist/components/StatusBadge.js +9 -32
  145. package/dist/components/StatusIcons.d.ts +0 -4
  146. package/dist/components/StatusIcons.js +5 -13
  147. package/dist/components/Switch.d.ts +5 -1
  148. package/dist/components/Switch.js +23 -6
  149. package/dist/components/Table.js +13 -20
  150. package/dist/components/Tabs.d.ts +52 -0
  151. package/dist/components/Tabs.js +75 -0
  152. package/dist/components/ThemeEditor.d.ts +29 -0
  153. package/dist/components/ThemeEditor.js +397 -0
  154. package/dist/components/Toast.d.ts +57 -0
  155. package/dist/components/Toast.js +203 -0
  156. package/dist/components/Tooltip.js +12 -15
  157. package/dist/components/buttonClasses.d.ts +18 -0
  158. package/dist/components/buttonClasses.js +31 -0
  159. package/dist/components/codeTheme.d.ts +5 -0
  160. package/dist/components/codeTheme.js +93 -0
  161. package/dist/components/fieldBox.d.ts +14 -0
  162. package/dist/components/fieldBox.js +29 -0
  163. package/dist/components/floating.d.ts +26 -5
  164. package/dist/components/floating.js +31 -9
  165. package/dist/{ai/ui/codeBreaks.js → components/markdownCodeBreaks.js} +1 -1
  166. package/dist/components/persistedState.d.ts +2 -0
  167. package/dist/components/persistedState.js +63 -0
  168. package/dist/components/relativeTime.d.ts +36 -8
  169. package/dist/components/relativeTime.js +106 -23
  170. package/dist/components/segmented.d.ts +17 -0
  171. package/dist/components/segmented.js +27 -0
  172. package/dist/components/shortcutKey.d.ts +4 -0
  173. package/dist/components/shortcutKey.js +27 -0
  174. package/dist/components/splitter.d.ts +26 -0
  175. package/dist/components/splitter.js +69 -0
  176. package/dist/components/tone.d.ts +9 -0
  177. package/dist/components/tone.js +30 -0
  178. package/dist/components/useCopy.d.ts +14 -0
  179. package/dist/components/useCopy.js +31 -0
  180. package/dist/components/useCssIsDark.d.ts +2 -0
  181. package/dist/components/useCssIsDark.js +2 -1
  182. package/dist/components/useTheme.d.ts +10 -0
  183. package/dist/components/useTheme.js +40 -0
  184. package/dist/cx.d.ts +5 -0
  185. package/dist/cx.js +11 -0
  186. package/dist/editor/Editor.js +2 -2
  187. package/dist/editor/EditorField.js +7 -10
  188. package/dist/editor/FormCodePanel.js +10 -23
  189. package/dist/editor/Monaco.js +7 -4
  190. package/dist/editor/index.d.ts +1 -1
  191. package/dist/editor/index.js +2 -2
  192. package/dist/editor/themes.d.ts +4 -0
  193. package/dist/editor/themes.js +75 -76
  194. package/dist/file-explorer/FileExplorer.js +180 -187
  195. package/dist/file-explorer/FileExplorerContext.js +36 -58
  196. package/dist/file-explorer/FilePreview/CodePreviewEditor.js +2 -1
  197. package/dist/file-explorer/FilePreview/Inline.js +9 -7
  198. package/dist/file-explorer/FilePreview/StreamedBadge.js +2 -2
  199. package/dist/file-explorer/FilePreview/Viewer.js +32 -34
  200. package/dist/file-explorer/FilePreview/index.js +60 -92
  201. package/dist/file-explorer/FileRow.js +10 -15
  202. package/dist/file-explorer/FileRowsWindow.js +2 -6
  203. package/dist/file-explorer/FileTable.js +2 -2
  204. package/dist/file-explorer/FileTableHeaders.js +8 -11
  205. package/dist/file-explorer/LoadMoreRow.js +8 -9
  206. package/dist/file-explorer/TreeView.js +16 -16
  207. package/dist/file-explorer/helpers.d.ts +1 -4
  208. package/dist/file-explorer/helpers.js +101 -114
  209. package/dist/file-explorer/lib/utils.d.ts +0 -2
  210. package/dist/file-explorer/lib/utils.js +1 -25
  211. package/dist/file-explorer/toasts.js +104 -185
  212. package/dist/form/Fields/BooleanField.js +12 -14
  213. package/dist/form/Fields/CheckboxGroupField.d.ts +1 -1
  214. package/dist/form/Fields/CheckboxGroupField.js +16 -18
  215. package/dist/form/Fields/ColorField.js +11 -11
  216. package/dist/form/Fields/DropdownField.d.ts +1 -1
  217. package/dist/form/Fields/DropdownField.js +20 -36
  218. package/dist/form/Fields/DurationField.d.ts +1 -1
  219. package/dist/form/Fields/DurationField.js +36 -50
  220. package/dist/form/Fields/LabelField.js +2 -2
  221. package/dist/form/Fields/MultiDropdownField.d.ts +1 -1
  222. package/dist/form/Fields/MultiDropdownField.js +9 -14
  223. package/dist/form/Fields/NumberField.d.ts +1 -1
  224. package/dist/form/Fields/NumberField.js +13 -48
  225. package/dist/form/Fields/ObjectField.js +3 -3
  226. package/dist/form/Fields/RadioField.d.ts +1 -1
  227. package/dist/form/Fields/RadioField.js +15 -18
  228. package/dist/form/Fields/RangeField.js +34 -35
  229. package/dist/form/Fields/StringField.d.ts +1 -1
  230. package/dist/form/Fields/StringField.js +15 -25
  231. package/dist/form/Fields/TextAreaField.js +10 -15
  232. package/dist/form/Form.d.ts +7 -2
  233. package/dist/form/Form.js +144 -49
  234. package/dist/form/FormLayout.js +18 -12
  235. package/dist/form/Wizard/WizardContainer.js +44 -18
  236. package/dist/form/Wizard/WizardNavigation.d.ts +1 -1
  237. package/dist/form/Wizard/WizardNavigation.js +31 -56
  238. package/dist/form/Wizard/WizardStepIndicator.d.ts +3 -0
  239. package/dist/form/Wizard/WizardStepIndicator.js +98 -114
  240. package/dist/form/Wizard/types.d.ts +2 -2
  241. package/dist/form/fieldFrame.d.ts +7 -0
  242. package/dist/form/fieldFrame.js +19 -0
  243. package/dist/form/index.d.ts +5 -5
  244. package/dist/form/index.js +4 -6
  245. package/dist/form/layoutCSS.js +5 -4
  246. package/dist/form/types/fieldComponentTypes.d.ts +5 -3
  247. package/dist/form/useChoiceField.js +2 -3
  248. package/dist/form/useFieldValue.d.ts +3 -0
  249. package/dist/form/useFieldValue.js +24 -7
  250. package/dist/form/utils/duration.d.ts +2 -2
  251. package/dist/form/utils/duration.js +3 -3
  252. package/dist/form/utils/fieldPath.d.ts +5 -3
  253. package/dist/form/utils/fieldPath.js +18 -3
  254. package/dist/form/utils/secondaryField.d.ts +0 -7
  255. package/dist/form/utils/secondaryField.js +1 -12
  256. package/dist/form/validation.d.ts +29 -0
  257. package/dist/form/validation.js +14 -0
  258. package/dist/format.d.ts +28 -0
  259. package/dist/format.js +64 -0
  260. package/dist/graph/AnnotationBanner.js +20 -31
  261. package/dist/graph/Connectors.js +1 -1
  262. package/dist/graph/DependencyGraph.js +51 -65
  263. package/dist/graph/GraphEditor.js +24 -28
  264. package/dist/graph/GraphEditorDialogs.js +239 -245
  265. package/dist/graph/InputDialog.js +93 -112
  266. package/dist/graph/InputsEditor.js +83 -84
  267. package/dist/graph/JobSummary.js +10 -11
  268. package/dist/graph/MatrixGroup.js +3 -3
  269. package/dist/graph/ProblemsButton.js +9 -10
  270. package/dist/graph/ShortcutsButton.js +12 -17
  271. package/dist/graph/SuggestionInput.d.ts +1 -2
  272. package/dist/graph/SuggestionInput.js +1 -3
  273. package/dist/graph/TreeView.js +47 -45
  274. package/dist/graph/WorkflowSettingsDialog.js +97 -102
  275. package/dist/graph/editorChrome.js +10 -12
  276. package/dist/graph/editorFields.d.ts +19 -16
  277. package/dist/graph/editorFields.js +97 -135
  278. package/dist/graph/editorPrimitives.js +2 -2
  279. package/dist/graph/editorRows.js +22 -25
  280. package/dist/graph/editorStrings.d.ts +16 -19
  281. package/dist/graph/editorStrings.js +11 -23
  282. package/dist/graph/fieldProblems.js +2 -2
  283. package/dist/graph/graphEditorState.d.ts +4 -4
  284. package/dist/graph/inputRefs.d.ts +0 -13
  285. package/dist/graph/inputRefs.js +121 -159
  286. package/dist/graph/settingsViews.js +5 -3
  287. package/dist/graph/stepWith.js +100 -100
  288. package/dist/graph/toolbarPanel.d.ts +8 -0
  289. package/dist/graph/toolbarPanel.js +11 -0
  290. package/dist/icons.d.ts +234 -23
  291. package/dist/icons.js +249 -264
  292. package/dist/index.d.ts +38 -21
  293. package/dist/index.js +42 -21
  294. package/dist/list/ActionToolbar.d.ts +1 -5
  295. package/dist/list/ActionToolbar.js +21 -20
  296. package/dist/list/ListPage.js +7 -7
  297. package/dist/list/ListTable.d.ts +3 -2
  298. package/dist/list/ListTable.js +33 -29
  299. package/dist/list/ListViewControls.d.ts +0 -17
  300. package/dist/list/ListViewControls.js +50 -118
  301. package/dist/list/UserHoverCard.js +24 -32
  302. package/dist/list/index.d.ts +2 -4
  303. package/dist/list/index.js +3 -5
  304. package/dist/list/listSearch.d.ts +1 -1
  305. package/dist/list/listSearch.js +19 -14
  306. package/dist/list/rowMenu.js +20 -26
  307. package/dist/logviewer/LogViewer.js +268 -382
  308. package/dist/logviewer/logviewer.css +53 -41
  309. package/dist/styles/base.css +16 -40
  310. package/dist/styles/theme.css +75 -106
  311. package/dist/styles.css +1 -1
  312. package/dist/theme/color.d.ts +40 -0
  313. package/dist/theme/color.js +228 -0
  314. package/dist/theme/contrast.d.ts +42 -0
  315. package/dist/theme/contrast.js +145 -0
  316. package/dist/theme/derive.d.ts +25 -0
  317. package/dist/theme/derive.js +475 -0
  318. package/dist/theme/fit.d.ts +35 -0
  319. package/dist/theme/fit.js +185 -0
  320. package/dist/theme/index.d.ts +14 -29
  321. package/dist/theme/index.js +20 -279
  322. package/dist/theme/model.d.ts +64 -0
  323. package/dist/theme/model.js +219 -0
  324. package/package.json +9 -5
  325. package/dist/ai/ui/Avatar.d.ts +0 -7
  326. package/dist/ai/ui/Avatar.js +0 -24
  327. package/dist/components/Filter.d.ts +0 -15
  328. package/dist/components/Filter.js +0 -32
  329. package/dist/components/FilterPill.d.ts +0 -7
  330. package/dist/components/FilterPill.js +0 -14
  331. package/dist/components/Indicator.d.ts +0 -4
  332. package/dist/components/Indicator.js +0 -44
  333. package/dist/components/SectionHeader.d.ts +0 -8
  334. package/dist/components/SectionHeader.js +0 -11
  335. package/dist/components/SettingRow.d.ts +0 -18
  336. package/dist/components/SettingRow.js +0 -35
  337. package/dist/components/SettingsGroup.d.ts +0 -8
  338. package/dist/components/SettingsGroup.js +0 -17
  339. package/dist/components/ghostButton.d.ts +0 -4
  340. package/dist/components/ghostButton.js +0 -7
  341. package/dist/components/inputClasses.d.ts +0 -1
  342. package/dist/components/inputClasses.js +0 -4
  343. package/dist/duration.d.ts +0 -3
  344. package/dist/duration.js +0 -17
  345. package/dist/form/FieldGroup.d.ts +0 -11
  346. package/dist/form/FieldGroup.js +0 -36
  347. package/dist/form/FieldWrapper.d.ts +0 -16
  348. package/dist/form/FieldWrapper.js +0 -55
  349. package/dist/form/fieldContext.d.ts +0 -19
  350. package/dist/form/fieldContext.js +0 -26
  351. package/dist/graph/Collapse.d.ts +0 -7
  352. package/dist/graph/Collapse.js +0 -15
  353. package/dist/graph/ToolbarPopover.d.ts +0 -13
  354. package/dist/graph/ToolbarPopover.js +0 -39
  355. package/dist/icons/ai/AiOutlineRollback.js +0 -16
  356. package/dist/icons/bi/BiBell.js +0 -16
  357. package/dist/icons/bi/BiBellOff.js +0 -16
  358. package/dist/icons/bi/BiBuildings.js +0 -20
  359. package/dist/icons/bi/BiError.js +0 -20
  360. package/dist/icons/bi/BiExpandVertical.js +0 -16
  361. package/dist/icons/bi/BiPause.js +0 -16
  362. package/dist/icons/bi/BiPlay.js +0 -16
  363. package/dist/icons/bi/BiRedo.js +0 -16
  364. package/dist/icons/bi/BiSolidCheckShield.js +0 -16
  365. package/dist/icons/bi/BiSolidTrashAlt.js +0 -16
  366. package/dist/icons/bi/BiStop.js +0 -16
  367. package/dist/icons/bi/BiUndo.js +0 -16
  368. package/dist/icons/bs/BsArrowsCollapse.js +0 -22
  369. package/dist/icons/bs/BsBank2.js +0 -19
  370. package/dist/icons/bs/BsBriefcase.js +0 -19
  371. package/dist/icons/bs/BsBucket.js +0 -19
  372. package/dist/icons/bs/BsCalendarX.js +0 -23
  373. package/dist/icons/bs/BsChatLeft.js +0 -19
  374. package/dist/icons/bs/BsChevronDoubleDown.js +0 -29
  375. package/dist/icons/bs/BsChevronDoubleUp.js +0 -29
  376. package/dist/icons/bs/BsClipboardCheck.js +0 -34
  377. package/dist/icons/bs/BsCurrencyDollar.js +0 -19
  378. package/dist/icons/bs/BsDash.js +0 -19
  379. package/dist/icons/bs/BsFileEarmarkZip.js +0 -23
  380. package/dist/icons/bs/BsFiles.js +0 -19
  381. package/dist/icons/bs/BsGeoAlt.js +0 -23
  382. package/dist/icons/bs/BsGrid.js +0 -19
  383. package/dist/icons/bs/BsLayers.js +0 -19
  384. package/dist/icons/bs/BsLayoutThreeColumns.js +0 -19
  385. package/dist/icons/bs/BsListUl.js +0 -22
  386. package/dist/icons/bs/BsMortarboard.js +0 -23
  387. package/dist/icons/bs/BsMusicNoteBeamed.js +0 -34
  388. package/dist/icons/bs/BsOpenai.js +0 -19
  389. package/dist/icons/bs/BsPersonPlus.js +0 -26
  390. package/dist/icons/bs/BsSearch.js +0 -19
  391. package/dist/icons/bs/BsSend.js +0 -19
  392. package/dist/icons/bs/BsShieldSlash.js +0 -22
  393. package/dist/icons/bs/BsStar.js +0 -19
  394. package/dist/icons/bs/BsStarFill.js +0 -19
  395. package/dist/icons/bs/BsStopCircle.js +0 -23
  396. package/dist/icons/bs/BsTag.js +0 -23
  397. package/dist/icons/bs/BsTelephone.js +0 -19
  398. package/dist/icons/bs/BsTerminal.js +0 -23
  399. package/dist/icons/bs/BsTerminalFill.js +0 -19
  400. package/dist/icons/bs/BsThreeDots.js +0 -19
  401. package/dist/icons/bs/BsThreeDotsVertical.js +0 -19
  402. package/dist/icons/bs/BsZoomIn.js +0 -37
  403. package/dist/icons/fa/FaAmazon.js +0 -16
  404. package/dist/icons/fa/FaAngleDown.js +0 -16
  405. package/dist/icons/fa/FaAngleLeft.js +0 -16
  406. package/dist/icons/fa/FaAngleRight.js +0 -16
  407. package/dist/icons/fa/FaAngleUp.js +0 -16
  408. package/dist/icons/fa/FaArrowDown.js +0 -16
  409. package/dist/icons/fa/FaArrowLeft.js +0 -16
  410. package/dist/icons/fa/FaArrowRight.js +0 -16
  411. package/dist/icons/fa/FaArrowUp.js +0 -16
  412. package/dist/icons/fa/FaBalanceScale.js +0 -16
  413. package/dist/icons/fa/FaCaretDown.js +0 -16
  414. package/dist/icons/fa/FaCentos.js +0 -16
  415. package/dist/icons/fa/FaChartLine.js +0 -16
  416. package/dist/icons/fa/FaChartPie.js +0 -16
  417. package/dist/icons/fa/FaCheck.js +0 -16
  418. package/dist/icons/fa/FaChevronDown.js +0 -16
  419. package/dist/icons/fa/FaChevronUp.js +0 -16
  420. package/dist/icons/fa/FaChrome.js +0 -16
  421. package/dist/icons/fa/FaCircleNotch.js +0 -16
  422. package/dist/icons/fa/FaCloud.js +0 -16
  423. package/dist/icons/fa/FaCloudDownloadAlt.js +0 -16
  424. package/dist/icons/fa/FaCog.js +0 -16
  425. package/dist/icons/fa/FaCogs.js +0 -16
  426. package/dist/icons/fa/FaComments.js +0 -16
  427. package/dist/icons/fa/FaCompress.js +0 -16
  428. package/dist/icons/fa/FaDesktop.js +0 -16
  429. package/dist/icons/fa/FaDocker.js +0 -16
  430. package/dist/icons/fa/FaDollarSign.js +0 -16
  431. package/dist/icons/fa/FaEdge.js +0 -16
  432. package/dist/icons/fa/FaEdit.js +0 -16
  433. package/dist/icons/fa/FaExclamationTriangle.js +0 -16
  434. package/dist/icons/fa/FaExpand.js +0 -16
  435. package/dist/icons/fa/FaEye.js +0 -16
  436. package/dist/icons/fa/FaEyeSlash.js +0 -16
  437. package/dist/icons/fa/FaFile.js +0 -16
  438. package/dist/icons/fa/FaFilePdf.js +0 -16
  439. package/dist/icons/fa/FaFilter.js +0 -16
  440. package/dist/icons/fa/FaFirefoxBrowser.js +0 -16
  441. package/dist/icons/fa/FaFlask.js +0 -16
  442. package/dist/icons/fa/FaFolder.js +0 -16
  443. package/dist/icons/fa/FaGithub.js +0 -16
  444. package/dist/icons/fa/FaGitlab.js +0 -16
  445. package/dist/icons/fa/FaGlobe.js +0 -16
  446. package/dist/icons/fa/FaGlobeAmericas.js +0 -16
  447. package/dist/icons/fa/FaImage.js +0 -16
  448. package/dist/icons/fa/FaInfoCircle.js +0 -16
  449. package/dist/icons/fa/FaKey.js +0 -16
  450. package/dist/icons/fa/FaLayerGroup.js +0 -16
  451. package/dist/icons/fa/FaLink.js +0 -16
  452. package/dist/icons/fa/FaLinkedin.js +0 -16
  453. package/dist/icons/fa/FaLinux.js +0 -16
  454. package/dist/icons/fa/FaList.js +0 -16
  455. package/dist/icons/fa/FaLock.js +0 -16
  456. package/dist/icons/fa/FaOpenid.js +0 -16
  457. package/dist/icons/fa/FaOpera.js +0 -16
  458. package/dist/icons/fa/FaPaperclip.js +0 -16
  459. package/dist/icons/fa/FaPlus.js +0 -16
  460. package/dist/icons/fa/FaPowerOff.js +0 -16
  461. package/dist/icons/fa/FaPrint.js +0 -16
  462. package/dist/icons/fa/FaQrcode.js +0 -16
  463. package/dist/icons/fa/FaQuestionCircle.js +0 -16
  464. package/dist/icons/fa/FaRedhat.js +0 -16
  465. package/dist/icons/fa/FaRegCircle.js +0 -16
  466. package/dist/icons/fa/FaRegFileImage.js +0 -16
  467. package/dist/icons/fa/FaRegFolder.js +0 -16
  468. package/dist/icons/fa/FaRobot.js +0 -16
  469. package/dist/icons/fa/FaRocket.js +0 -16
  470. package/dist/icons/fa/FaRunning.js +0 -16
  471. package/dist/icons/fa/FaSafari.js +0 -16
  472. package/dist/icons/fa/FaSave.js +0 -16
  473. package/dist/icons/fa/FaSearch.js +0 -16
  474. package/dist/icons/fa/FaShieldAlt.js +0 -16
  475. package/dist/icons/fa/FaSlack.js +0 -16
  476. package/dist/icons/fa/FaStar.js +0 -16
  477. package/dist/icons/fa/FaStop.js +0 -16
  478. package/dist/icons/fa/FaSuse.js +0 -16
  479. package/dist/icons/fa/FaTerminal.js +0 -16
  480. package/dist/icons/fa/FaTimes.js +0 -16
  481. package/dist/icons/fa/FaUbuntu.js +0 -16
  482. package/dist/icons/fa/FaUndoAlt.js +0 -16
  483. package/dist/icons/fa/FaUnlink.js +0 -16
  484. package/dist/icons/fa/FaUser.js +0 -16
  485. package/dist/icons/fa/FaUsers.js +0 -16
  486. package/dist/icons/fa/FaWindows.js +0 -16
  487. package/dist/icons/fa6/FaApple.js +0 -16
  488. package/dist/icons/fa6/FaArrowsRotate.js +0 -16
  489. package/dist/icons/fa6/FaDebian.js +0 -16
  490. package/dist/icons/fa6/FaFilterCircleXmark.js +0 -16
  491. package/dist/icons/fa6/FaInbox.js +0 -16
  492. package/dist/icons/fa6/FaLocationDot.js +0 -16
  493. package/dist/icons/fa6/FaRegFilePdf.js +0 -16
  494. package/dist/icons/fa6/FaRegFolderOpen.js +0 -16
  495. package/dist/icons/fa6/FaUpRightFromSquare.js +0 -16
  496. package/dist/icons/fa6/FaWandMagicSparkles.js +0 -16
  497. package/dist/icons/fa6/FaXTwitter.js +0 -16
  498. package/dist/icons/fi/FiActivity.js +0 -23
  499. package/dist/icons/fi/FiAlertCircle.js +0 -49
  500. package/dist/icons/fi/FiChevronDown.js +0 -23
  501. package/dist/icons/fi/FiClock.js +0 -31
  502. package/dist/icons/fi/FiCopy.js +0 -34
  503. package/dist/icons/fi/FiDownload.js +0 -40
  504. package/dist/icons/fi/FiFile.js +0 -27
  505. package/dist/icons/fi/FiFileText.js +0 -55
  506. package/dist/icons/fi/FiHardDrive.js +0 -55
  507. package/dist/icons/fi/FiRotateCcw.js +0 -27
  508. package/dist/icons/fi/FiUpload.js +0 -40
  509. package/dist/icons/fi/FiX.js +0 -37
  510. package/dist/icons/fi/FiZap.js +0 -23
  511. package/dist/icons/gi/GiSpy.js +0 -16
  512. package/dist/icons/go/GoGitCommit.js +0 -16
  513. package/dist/icons/go/GoGitPullRequest.js +0 -20
  514. package/dist/icons/go/GoIssueOpened.js +0 -16
  515. package/dist/icons/go/GoPlus.js +0 -16
  516. package/dist/icons/go/GoRepoForked.js +0 -28
  517. package/dist/icons/go/GoSignOut.js +0 -16
  518. package/dist/icons/go/GoSkip.js +0 -20
  519. package/dist/icons/go/GoVideo.js +0 -20
  520. package/dist/icons/gr/GrCloudComputer.js +0 -20
  521. package/dist/icons/gr/GrInbox.js +0 -20
  522. package/dist/icons/gr/GrServerCluster.js +0 -20
  523. package/dist/icons/gr/GrStorage.js +0 -20
  524. package/dist/icons/gr/GrTasks.js +0 -20
  525. package/dist/icons/hi/HiCog.js +0 -24
  526. package/dist/icons/hi/HiDuplicate.js +0 -24
  527. package/dist/icons/hi/HiOutlineArchive.js +0 -26
  528. package/dist/icons/hi/HiOutlineClipboardCopy.js +0 -26
  529. package/dist/icons/hi/HiOutlineHome.js +0 -26
  530. package/dist/icons/hi/HiQuestionMarkCircle.js +0 -24
  531. package/dist/icons/hi/HiServer.js +0 -24
  532. package/dist/icons/hi2/HiMiniCheckCircle.js +0 -24
  533. package/dist/icons/hi2/HiMiniLanguage.js +0 -28
  534. package/dist/icons/hi2/HiMiniMinusCircle.js +0 -24
  535. package/dist/icons/hi2/HiMiniXCircle.js +0 -24
  536. package/dist/icons/hi2/HiSparkles.js +0 -24
  537. package/dist/icons/im/ImSpinner5.js +0 -19
  538. package/dist/icons/io/IoIosNotifications.js +0 -16
  539. package/dist/icons/io/IoMdBuild.js +0 -16
  540. package/dist/icons/io/IoMdClose.js +0 -16
  541. package/dist/icons/io5/IoCloudUploadOutline.js +0 -32
  542. package/dist/icons/io5/IoDocumentTextOutline.js +0 -31
  543. package/dist/icons/io5/IoFileTrayFullOutline.js +0 -31
  544. package/dist/icons/io5/IoHeart.js +0 -16
  545. package/dist/icons/io5/IoHeartDislike.js +0 -16
  546. package/dist/icons/io5/IoHeartOutline.js +0 -22
  547. package/dist/icons/io5/IoInformationCircleOutline.js +0 -50
  548. package/dist/icons/io5/IoSettingsOutline.js +0 -22
  549. package/dist/icons/io5/IoWarningOutline.js +0 -40
  550. package/dist/icons/lu/LuArrowRight.js +0 -27
  551. package/dist/icons/lu/LuBadgeCheck.js +0 -27
  552. package/dist/icons/lu/LuBraces.js +0 -27
  553. package/dist/icons/lu/LuBrainCircuit.js +0 -101
  554. package/dist/icons/lu/LuCalendar.js +0 -46
  555. package/dist/icons/lu/LuCheck.js +0 -23
  556. package/dist/icons/lu/LuChevronLeft.js +0 -23
  557. package/dist/icons/lu/LuChevronRight.js +0 -23
  558. package/dist/icons/lu/LuCode.js +0 -27
  559. package/dist/icons/lu/LuExternalLink.js +0 -35
  560. package/dist/icons/lu/LuEye.js +0 -31
  561. package/dist/icons/lu/LuEyeOff.js +0 -40
  562. package/dist/icons/lu/LuFolderTree.js +0 -40
  563. package/dist/icons/lu/LuIdCard.js +0 -55
  564. package/dist/icons/lu/LuKeyboard.js +0 -71
  565. package/dist/icons/lu/LuLogs.js +0 -65
  566. package/dist/icons/lu/LuMail.js +0 -33
  567. package/dist/icons/lu/LuMegaphone.js +0 -27
  568. package/dist/icons/lu/LuMoon.js +0 -23
  569. package/dist/icons/lu/LuNetwork.js +0 -63
  570. package/dist/icons/lu/LuPartyPopper.js +0 -65
  571. package/dist/icons/lu/LuSettings2.js +0 -48
  572. package/dist/icons/lu/LuSheet.js +0 -72
  573. package/dist/icons/lu/LuShield.js +0 -23
  574. package/dist/icons/lu/LuSun.js +0 -69
  575. package/dist/icons/lu/LuTextCursorInput.js +0 -45
  576. package/dist/icons/lu/LuX.js +0 -27
  577. package/dist/icons/lu/LuZoomIn.js +0 -59
  578. package/dist/icons/lu/LuZoomOut.js +0 -49
  579. package/dist/icons/md/MdClear.js +0 -23
  580. package/dist/icons/md/MdDragHandle.js +0 -23
  581. package/dist/icons/md/MdInstallDesktop.js +0 -31
  582. package/dist/icons/md/MdOutlineAttachMoney.js +0 -23
  583. package/dist/icons/md/MdOutlineMoneyOff.js +0 -23
  584. package/dist/icons/md/MdPieChart.js +0 -23
  585. package/dist/icons/md/MdRefresh.js +0 -23
  586. package/dist/icons/md/MdReplay.js +0 -23
  587. package/dist/icons/md/MdSmartphone.js +0 -23
  588. package/dist/icons/pi/PiArrowBendUpRightBold.js +0 -19
  589. package/dist/icons/pi/PiPlugsConnectedFill.js +0 -19
  590. package/dist/icons/pi/PiRectangleDashed.js +0 -19
  591. package/dist/icons/pi/PiShareBold.js +0 -19
  592. package/dist/icons/si/SiAnthropic.js +0 -19
  593. package/dist/icons/si/SiHelm.js +0 -19
  594. package/dist/icons/si/SiKubernetes.js +0 -19
  595. package/dist/icons/tb/TbAlertTriangle.js +0 -35
  596. package/dist/icons/tb/TbAlertTriangleFilled.js +0 -19
  597. package/dist/icons/tb/TbApi.js +0 -40
  598. package/dist/icons/tb/TbBrain.js +0 -50
  599. package/dist/icons/tb/TbBuildingTunnel.js +0 -65
  600. package/dist/icons/tb/TbEdit.js +0 -35
  601. package/dist/icons/tb/TbLayoutSidebar.js +0 -27
  602. package/dist/icons/tb/TbLayoutSidebarLeftCollapse.js +0 -35
  603. package/dist/icons/tb/TbLayoutSidebarRightCollapse.js +0 -35
  604. package/dist/icons/tb/TbUser.js +0 -27
  605. package/dist/icons/tb/TbUserOff.js +0 -35
  606. package/dist/icons/tb/TbWorldShare.js +0 -55
  607. package/dist/icons/tb/TbWorldWww.js +0 -65
  608. package/dist/icons/ti/TiArrowSortedDown.js +0 -20
  609. package/dist/icons/ti/TiArrowSortedUp.js +0 -20
  610. package/dist/icons/ti/TiArrowUnsorted.js +0 -20
  611. package/dist/icons/ti/TiCancel.js +0 -20
  612. package/dist/icons/vsc/VscChromeMinimize.js +0 -19
  613. package/dist/icons/vsc/VscJson.js +0 -19
  614. package/dist/icons/vsc/VscLayoutSidebarLeft.js +0 -19
  615. package/dist/icons/vsc/VscPass.js +0 -27
  616. package/dist/icons/vsc/VscSplitHorizontal.js +0 -19
  617. package/dist/icons/vsc/VscTerminalPowershell.js +0 -19
  618. package/dist/list/ListPager.d.ts +0 -14
  619. package/dist/list/ListPager.js +0 -62
  620. package/dist/list/textEntry.d.ts +0 -2
  621. package/dist/list/textEntry.js +0 -10
  622. /package/dist/{ai/ui/codeBreaks.d.ts → components/markdownCodeBreaks.d.ts} +0 -0
package/README.md CHANGED
@@ -6,7 +6,7 @@ so an application ships only what it imports:
6
6
  | Subpath | Contents |
7
7
  | --- | --- |
8
8
  | `.` | theme contract, primitives (buttons, inputs, tables, tooltips, modals, dropdowns, settings layouts, page header), `UIProvider` |
9
- | `./theme` | `deriveTheme`, presets, `applyTheme` |
9
+ | `./theme` | theme seeds and presets, `generateTheme`, `applyTheme`, `fitSeed` |
10
10
  | `./icons` | the icon barrel |
11
11
  | `./list` | list pages, tables, row menus and list controls |
12
12
  | `./form` | `DynamicForm` and its field registry |
@@ -17,25 +17,164 @@ so an application ships only what it imports:
17
17
  | `./ai`, `./ai/openai`, `./ai/mock` | chat interface and adapters |
18
18
  | `./theme.css`, `./base.css`, `./fonts.css`, `./styles.css`, `./logviewer.css`, `./ai.css` | stylesheets |
19
19
 
20
- Hosts bind notifications, strings, navigation, data hooks and the workflow
21
- engine through `UIProvider`.
20
+ Hosts bind strings, navigation, data hooks and the workflow engine through
21
+ `UIProvider`, which also shows the package's toasts.
22
22
 
23
- ## Theme contract
23
+ ## Which component?
24
+
25
+ Each need has one component. Reach for it before styling markup by hand.
26
+
27
+ | Need | Use |
28
+ | --- | --- |
29
+ | An action | `Button`; `IconButton` for an icon alone, named by its tooltip |
30
+ | A link or another component's trigger that looks like a button | `buttonClasses()` |
31
+ | A link out of the app | `ExternalLink` |
32
+ | Work under way | `Loader`; `Skeleton` in a `LoadingRegion` for the shape of content still loading |
33
+ | Nothing to show yet, or nothing matches | `EmptyState` |
34
+ | A text field | `Input`, `Textarea`, or a control framed by `Field`, whose `actions` hold buttons that act on it |
35
+ | A number, a date | `NumberInput`, `DatePicker` |
36
+ | On or off | `Switch`; `Checkbox` in a list of things to tick, several of which may be on |
37
+ | One of a few choices, all shown | `RadioGroup` in a form; `SegmentedControl` in a toolbar, or as a field's control in a `Field group` |
38
+ | Narrowing what is shown by typing | `SearchInput`; `ListSearchControl` on a list page's toolbar |
39
+ | A value from a list | `Select`, or `Combobox` when the list needs filtering |
40
+ | Free text with suggestions, or tags | `Autocomplete`; `Combobox` with `multiple creatable` |
41
+ | A range | `Slider` |
42
+ | A titled part of a page or form | `Section` |
43
+ | More detail under a line | `Disclosure` |
44
+ | Views of one thing | `Tabs` |
45
+ | A list of actions | `ActionMenu`; `useContextMenu` for a right-click or a row's menu |
46
+ | A panel of controls anchored to a trigger | `Popover` |
47
+ | A hint for a control | `Tooltip`; `InfoTip` for help everyone must reach |
48
+ | A preview of what a link leads to | `HoverCard` |
49
+ | A task that blocks the page | `Modal`; `ConfirmModal` to confirm one action |
50
+ | A panel beside the page | `Drawer` |
51
+ | A passing notice, or the progress of work in the background | `toast` |
52
+ | How full something is, how far a task has come | `Meter`, `ProgressBar` |
53
+ | Pages of a long list | `Pagination` |
54
+ | A grouped page of settings | `SettingsCard` with `SettingRow`s |
55
+ | A person | `Avatar` |
56
+ | A status in words | `StatusBadge`, or `StatusDot` beside text that says it |
57
+ | A run's, job's or step's status beside its name | `RunStatusIcon`; `StatusBadge` with `runStatusTone` to say it in words |
58
+ | A copy action | `useCopy`, or `CopyToClipboard` for its button |
59
+ | A live relative time or duration | `RelativeTime`, `Elapsed` |
60
+ | Rendered Markdown | `Markdown` |
61
+ | A value that survives a reload | `usePersistedState` |
62
+ | Choosing the app's colors | `ThemeEditor`, applied with `useApplyTheme` |
63
+
64
+ Some pairs look alike and are split on purpose:
65
+
66
+ - **Section or Disclosure.** A `Section` is a titled part of a page or form: its
67
+ title is a heading in the page's outline, and folding it keeps its fields
68
+ mounted. A `Disclosure` is a line inside content that reveals detail beneath
69
+ it, such as a tool call's arguments, and adds nothing to the outline.
70
+ - **Popover or HoverCard.** A `Popover` opens on a press and holds controls or a
71
+ list, so keyboard and touch reach it. A `HoverCard` opens on hover or focus
72
+ and only previews what its anchor already leads to; nothing in it may be
73
+ reachable only there.
74
+ - **Menu or Popover.** A menu is a list of actions or choices that closes once
75
+ one is picked, with arrow-key navigation and type-ahead. Anything else
76
+ anchored to a trigger, such as a form or a filter panel, is a `Popover`.
77
+ - **Tabs or SegmentedControl.** `Tabs` switch between views or pages of one
78
+ thing, each with its own panel or route. A `SegmentedControl` sets a value,
79
+ such as a time range, that changes what one view shows. `Tabs` with
80
+ `variant="segmented"` look the same, so the choice rests on what pressing does.
81
+ - **SearchInput or ListSearchControl.** A `SearchInput` is a box that is
82
+ always shown and narrows what sits beside it, such as a panel's rows or a
83
+ log's lines. `ListSearchControl` belongs to a list page's toolbar: it folds to
84
+ a button, opens on ⌘F or `/`, and keeps terms as chips the list remembers.
85
+ - **StatusBadge or RunStatusIcon.** A `StatusBadge` says a status in words in
86
+ its tone, for anything. A `RunStatusIcon` shows the status of something that
87
+ ran as an icon beside its name, and turns while it runs; `runStatusTone` gives
88
+ a badge for the same status the same tone.
89
+ - **Select or Combobox.** A `Select` picks from a short list it shows in full.
90
+ A `Combobox` filters as you type, for a list long enough to search, and is the
91
+ one that takes several values, new ones, or free text (`Autocomplete`).
92
+
93
+ ## Themes
24
94
 
25
95
  Every color a component may use is one of the closed set of `--theme-*` CSS
26
- variables, and every token is computable from a tiny seed — accent +
27
- background + contrast — per surface (interface, and optionally sidebar).
28
- Presets are named seeds; a custom theme is the same seed exposed directly.
29
- Components consume only tokens and never branch on a light/dark flag.
96
+ variables. Components read only those tokens and never branch on a light or dark
97
+ flag. A theme is not the tokens but a few picked values, a seed, from which every
98
+ token is generated:
99
+
100
+ ```ts
101
+ import type { Theme } from '@parallelworks/ui/theme'
102
+
103
+ const theme: Theme = {
104
+ version: 1,
105
+ light: { interface: { base: '#f3f4f6', accent: '#06354f', contrast: 30 }, sidebar: { base: '#06354f' } },
106
+ dark: { interface: { base: '#111418', accent: '#5b9ccf' } },
107
+ code: 'balanced',
108
+ }
109
+ ```
110
+
111
+ - **`base`** is the page background. Its lightness decides the mode, so a seed
112
+ is light or dark by what it looks like. A near-white base keeps panels pure
113
+ white.
114
+ - **`accent`** is used exactly for the primary button and the selection; text on
115
+ it, links, focus rings and tints are solved from it.
116
+ - **`contrast`** runs 0 to 100, 30 by default. It spreads the surfaces apart and
117
+ raises text toward the WCAG and APCA targets below. Even 0 meets WCAG AA.
118
+ - **`sidebar`** takes its own `base` and `accent`; leave it out and the sidebar
119
+ follows the page.
120
+ - **`light` and `dark`** are both optional: a missing mode is derived from the
121
+ other, so a theme with one scheme still follows the device.
122
+ - **`code`** picks the syntax and terminal palette: `balanced`, `vivid`, `muted`
123
+ or `mono`.
124
+
125
+ A theme is plain JSON. Store it as it is; `parseTheme` reads one back (a string
126
+ or a parsed value) and returns `{ ok: false, error: { code, path } }` instead of
127
+ throwing, so an import can say which field is wrong. `serializeTheme` writes one.
128
+
129
+ ### How tokens are generated
130
+
131
+ Generation works in OKLCH. Neutrals take the base's hue with a faint tint toward
132
+ the accent; surfaces step away from the base by an amount the contrast scales,
133
+ with a knee at 30 so the upper half of the slider changes more gently. Dark text
134
+ on a tinted light base carries several times the base's chroma, as hand-made
135
+ slate and gray scales do, while light text on a dark base carries less. Each text
136
+ color is then solved: a binary search on lightness, at its own hue and chroma,
137
+ until it reaches its target against every surface it sits on.
138
+
139
+ | Pair | WCAG at 0 / 30 / 100 | APCA Lc |
140
+ | --- | --- | --- |
141
+ | Body text | 4.5 / 7 / 12 | 75 / 90 / 105 |
142
+ | Secondary text, links, status, syntax and terminal colors | 4.5 / 4.5 / 7 | 60 / 70 / 85 |
143
+ | Placeholders | 3 / 3 / 4.5 | 45 / 50 / 65 |
144
+ | Focus ring | 3 / 3 / 4.5 | |
145
+ | Control borders | 1.6 / 2.2 / 3 | |
146
+ | Text on the accent | 4.5 | |
147
+
148
+ Status colors (success, error, warning, info, favorite) and terminal colors keep
149
+ fixed hues, so red means the same thing in every theme. Syntax colors turn away
150
+ from the accent's hue when they come within 30° of it, so a keyword never looks
151
+ like a link.
152
+
153
+ Every color is mapped into sRGB with the CSS Color 4 method, which lowers
154
+ chroma at fixed lightness and hue. It is mapped into display-p3 too: where the
155
+ wider color differs from sRGB by more than one just-noticeable difference
156
+ (ΔEOK 0.02), it is emitted under `@media (color-gamut: p3)`. The contrast
157
+ targets are checked in both gamuts.
158
+
159
+ ### Applying a theme
30
160
 
31
161
  ```ts
32
- import { deriveTheme, applyTheme, THEME_PRESETS } from '@parallelworks/ui/theme'
162
+ import { applyTheme, generateTheme, schemeFor, resolveMode } from '@parallelworks/ui/theme'
33
163
 
34
- const vars = deriveTheme({ accent: '#06354f', background: '#f3f4f6' })
35
- applyTheme(document.documentElement, vars)
164
+ const prefersDark = matchMedia('(prefers-color-scheme: dark)').matches
165
+ const mode = resolveMode('system', prefersDark) // 'light' or 'dark'
166
+ applyTheme(document.documentElement, generateTheme(schemeFor(theme, mode), { code: theme.code }))
36
167
  ```
37
168
 
38
- Import the stylesheet contract once in your app:
169
+ In React, `useColorMode(preference)` follows the device while the preference is
170
+ `system`, and `useApplyTheme(theme, mode)` applies the theme to the document
171
+ root (or to an element you pass) and sets `color-scheme`. `applyTheme` sets the
172
+ display-p3 values on a wide-gamut screen. To render a theme on the server,
173
+ `themeStylesheet(selector, scheme)` returns a stylesheet with both blocks.
174
+ `deriveTheme(scheme)` returns the sRGB tokens alone.
175
+
176
+ `theme.css` defines the default theme's tokens, so a page renders before any
177
+ script runs:
39
178
 
40
179
  ```css
41
180
  /* In a Tailwind v4 build: */
@@ -55,19 +194,178 @@ so its precedence does not depend on where it loads. It includes Tailwind's
55
194
  preflight reset; a host with its own Tailwind build should use the `@source`
56
195
  route instead to avoid a double preflight.
57
196
 
197
+ ### Editing a theme
198
+
199
+ `ThemeEditor` is controlled: it takes `value` and `onChange`, with presets, a
200
+ color picker and hex field for each seed, the contrast slider, a custom sidebar,
201
+ the code palette, copy, import and reset. Pass `preference` and
202
+ `onPreferenceChange` to show the light, dark and system choice. It shows a
203
+ scoped preview of the theme beside the controls; with `preview={false}` and
204
+ `useApplyTheme`, the whole app is the preview. Its strings are in
205
+ `UIStrings.theme`.
206
+
207
+ ### Code
208
+
209
+ Code blocks in `Markdown`, highlighted diffs, the Monaco editor and the log
210
+ viewer's ANSI colors all read the `--theme-code-*` and `--theme-ansi-*` tokens,
211
+ so they follow the theme without a light or dark switch. Monaco takes only
212
+ hex, so it gets the sRGB colors and redefines its theme when the tokens change.
213
+
214
+ ### Moving a stored palette to a seed
215
+
216
+ `fitSeed(colors)` takes the colors a theme stored as tokens (any of them) and
217
+ returns the seed that comes closest, with a report:
218
+
219
+ ```ts
220
+ const { scheme, report } = fitSeed({ '--theme-app-bg': '#f4f6f8', '--theme-accent': '#0b7a75' })
221
+ report.verdict // 'faithful', 'close' or 'changed'
222
+ report.worst // the tokens furthest from what was stored
223
+ ```
224
+
225
+ Each token's distance is ΔEOK × 100, so 2 is about one just-noticeable
226
+ difference. A fit is `faithful` when the main tokens are within 2 and none is
227
+ over 5, and `close` within 5 and 10. A stored color that failed WCAG AA is
228
+ marked `correctedForContrast` and left out of the verdict, since the generated
229
+ one is meant to differ.
230
+
231
+ ### Renamed tokens
232
+
233
+ | Before | Now |
234
+ | --- | --- |
235
+ | `--theme-element` | `--theme-accent` |
236
+ | `--theme-element-text` | `--theme-accent-text` |
237
+ | `--theme-element-hover` | `--theme-accent-hover` |
238
+ | `--theme-panel`, `--theme-hover-text` | `--theme-app` |
239
+ | `--theme-muted-panel-color` | `--theme-muted-text-color` |
240
+ | `--theme-card-bg` | `--theme-panel-bg` |
241
+ | `--theme-card-hover` | `--theme-panel-hover` |
242
+ | `--theme-card-border` | `--theme-border` |
243
+ | `--theme-hover-overlay` | `--theme-hover` |
244
+ | `--theme-input-disabled-text` | `--theme-placeholder` |
245
+ | `--theme-input` | `--theme-focus` |
246
+ | `--theme-auth-shadow` | `--theme-shadow-xl` |
247
+ | `--theme-sidebar-hover-text` | `--theme-sidebar-text` |
248
+ | `--theme-bg` | `--theme-sidebar-bg` |
249
+ | `theme-element` (utility) | `theme-accent` |
250
+
251
+ ## Buttons and spinners
252
+
253
+ Every pressable thing has one look, from `buttonClasses({ variant, size, iconOnly })`:
254
+
255
+ | Variant | For |
256
+ | --- | --- |
257
+ | `primary` | the one action a view leads to |
258
+ | `secondary` | actions beside it |
259
+ | `outline`, `ghost` | toolbar and inline actions, bordered or not |
260
+ | `danger` | confirming what can't be undone |
261
+
262
+ Sizes are `xs`, `sm` and `md`. `Button` and `IconButton` apply it. An
263
+ `IconButton` is named by its tooltip, and takes `pressed` for a toggle and
264
+ `dot` for an indicator. Pass `buttonClasses()` to a host link or to another
265
+ component's trigger rather than styling a button by hand. A pressed toggle
266
+ (`aria-pressed`) and an open popup's trigger read as selected.
267
+
268
+ `Loader` is the one spinner. Inside a button, or beside text that already
269
+ says what is happening, use `<Loader inline decorative />`.
270
+
271
+ ## Toasts
272
+
273
+ `toast` shows a notice from anywhere, a component or not. `UIProvider` renders
274
+ them along the top of the window, above dialogs, where they clear a modal's
275
+ panel and stay usable while it is open: pressing one doesn't close the dialog.
276
+ A screen reader hears each one; errors interrupt, the rest wait for a pause.
277
+
278
+ ```ts
279
+ import { toast } from '@parallelworks/ui'
280
+
281
+ toast.success('Saved')
282
+ toast.error('Could not save', { action: { label: 'Retry', onClick: save } })
283
+
284
+ const id = toast.loading('Uploading…')
285
+ toast.update(id, { tone: 'success', message: 'Uploaded' })
286
+
287
+ await toast.promise(save(), { loading: 'Saving…', success: 'Saved', error: 'Could not save' })
288
+ ```
289
+
290
+ Tones are `info`, `success`, `warning` and `error`. A toast closes itself after
291
+ five seconds, eight for a warning or an error, pausing while the pointer or focus
292
+ is on it; `timeout: false` keeps it. `loading` stays until an update settles it
293
+ into a tone. Pass an `id` to replace a toast rather than stack another.
294
+
295
+ ## Host chrome
296
+
297
+ Popups, dialogs and drawers portal to `<body>` and read the tokens from the
298
+ document root. A host with fixed chrome tells overlays where it is, on the same
299
+ root:
300
+
301
+ | Variable | Meaning |
302
+ | ------------------- | ----------------------------------------------------------------------- |
303
+ | `--app-inset-top` | The height of a fixed top bar. A drawer starts below it. |
304
+ | `--app-inset-start` | The width of a fixed sidebar on the start side. A drawer at its widest leaves that strip, and never less than 2.5rem. |
305
+
306
+ ```ts
307
+ document.documentElement.style.setProperty('--app-inset-top', '56px')
308
+ document.documentElement.style.setProperty('--app-inset-start', '220px')
309
+ ```
310
+
311
+ Everything the package lays over the page stacks on one scale, set on the
312
+ document root by `base.css`. Give the host's own fixed elements a place on it,
313
+ such as `z-index: 100` for a top bar, rather than a z-index chosen to win:
314
+
315
+ | Variable | Default | For |
316
+ | ----------------- | ------- | ------------------------------------------------------ |
317
+ | `--layer-sticky` | 10 | toolbars and tab strips that stick as the page scrolls |
318
+ | `--layer-header` | 20 | the page header, which sticks above them |
319
+ | `--layer-overlay` | 1000 | a panel over the page, such as a full-screen log |
320
+ | `--layer-drawer` | 1100 | drawers |
321
+ | `--layer-modal` | 1200 | modals |
322
+ | `--layer-popover` | 1300 | menus, selects, popovers, hover cards and tooltips, so one opens over the dialog it belongs to |
323
+ | `--layer-toast` | 1400 | toasts |
324
+
325
+ In Tailwind, `z-(--layer-modal)` reads one. Override a value on `:root` to move
326
+ a layer; the defaults sit in a cascade layer, so the host's own rule wins.
327
+
58
328
  ## Icons
59
329
 
60
330
  ```tsx
61
- import { AddIcon, LoaderIcon, TrashIcon } from '@parallelworks/ui/icons'
62
- ```
331
+ import { AddIcon, TrashIcon } from '@parallelworks/ui/icons'
63
332
 
64
- The barrel re-exports a curated, stable set of icon names over `react-icons`
65
- so applications never depend on a specific icon pack directly.
333
+ <Button><AddIcon /> Add</Button>
334
+ <TrashIcon className="size-4 text-(--theme-error)" />
335
+ ```
66
336
 
67
- Each icon ships as its own module under `dist/icons/<set>/`, so an application
68
- bundles an icon only into the chunks that render it. Every module carries its
69
- icon's data, copied from its `react-icons` set at build time, and opens with that
70
- set's name and license.
337
+ `@parallelworks/ui/icons` is the one import point for interface icons. Each
338
+ name is a meaning, such as `RetryIcon` or `WarningIcon`, drawn from
339
+ [Lucide](https://lucide.dev), so every icon shares one 24px grid and one 2px
340
+ stroke. Don't import `lucide-react` directly: a name here keeps one glyph per
341
+ meaning across the apps.
342
+
343
+ - **Size and colour:** an icon is `1em` square in `currentColor`, so it follows
344
+ the text around it. A class such as `size-4` or `h-3 w-3` sets another size,
345
+ and `size` takes pixels.
346
+ - **Accessibility:** an icon is decoration, hidden from assistive technology,
347
+ unless a `title` or `aria-label` names it. Name one only when nothing beside
348
+ it says what it means.
349
+ - **Filled variants:** a filled glyph marks a state, such as `PinFilledIcon`
350
+ for pinned.
351
+ - **One name per meaning:** pick the name for what the thing is, even where a
352
+ nearby name would look similar. For compute, `ClusterIcon` is a group of
353
+ nodes, `NodeIcon` one host or node in it, and `InstanceIcon` a VM or cloud
354
+ instance. `RemoveIcon` takes an item out of a list, while `CloseIcon` closes,
355
+ dismisses or clears; they share the X glyph, the convention for both.
356
+ `DestroyIcon` tears down what was provisioned, while `TrashIcon` deletes a
357
+ record.
358
+ - **Adding an icon:** pick the [Lucide glyph](https://lucide.dev/icons) and add
359
+ `export const NameIcon = /* @__PURE__ */ icon(Glyph)` to `src/icons.tsx`,
360
+ named for what it means rather than what it shows. Reuse an existing name
361
+ when the meaning is the same.
362
+
363
+ Logos of other companies' products, such as `GitHubIcon` or `UbuntuIcon`, are
364
+ in `@parallelworks/ui/brand-icons`. They take the same props, are filled in the
365
+ text's colour, and are only for naming the product. They come from Simple Icons
366
+ (CC0) and Bootstrap Icons (MIT), and the file carries their notices.
367
+
368
+ The `UI/Icons` story shows every icon and logo by name.
71
369
 
72
370
  ## Workflow engine
73
371
 
@@ -138,7 +436,6 @@ export function Chat() {
138
436
  adapter={createMockChatAdapter()}
139
437
  currentUser={{ id: 'u1', username: 'you', name: 'You' }}
140
438
  navigation={{ toConversation: id => {}, toNewChat: () => {}, toAttachments: () => {} }}
141
- notify={{ success: console.log, error: console.error, info: console.log }}
142
439
  >
143
440
  <ChatLayout>
144
441
  <ChatThread />
@@ -191,13 +488,36 @@ const { isDirty } = useFormState({ control: form.control })
191
488
 
192
489
  `form.getValues()`, `form.reset()` and `formState.isDirty` then work as
193
490
  react-hook-form documents them. Without `form`, the form keeps its own;
194
- `onValuesChange` reports each change either way. `missingFields` marks fields
195
- as `required` errors.
491
+ `onValuesChange` reports each change either way.
492
+
493
+ ## Validation
494
+
495
+ A field with neither `optional` nor a `default` needs a value. A submit, or
496
+ Next on a wizard page, checks the fields the form shows, says "Enter a value."
497
+ under each empty one and holds until it is filled; once a field shows an
498
+ error it checks again with each change. A hidden field, a disabled one and a
499
+ boolean never hold the form.
500
+
501
+ `serverErrors` shows what the server rejected, each under its field until the
502
+ person changes it. A path may come in any convention: a workflow's
503
+ `hosts[0].cpus`, a problem response's JSON Pointer `#/hosts/0/cpus`, or
504
+ `hosts.0.cpus`. Without a message the field says to check its value. They
505
+ never hold back Next or a submit, since the server checks again, and a wizard
506
+ turns to the first page holding one. From a problem response:
507
+
508
+ ```tsx
509
+ const fieldMessages = useFieldMessages() // @parallelworks/problem/react
510
+ <DynamicForm serverErrors={save.error ? fieldMessages(save.error) : undefined} … />
511
+ ```
512
+
513
+ A field component receives the form's message as `error`; `fieldFrame(props)`
514
+ shows it through `Field`.
196
515
 
197
516
  Each field subscribes only to what it reads, so typing renders the edited
198
517
  field and whatever reads it, not the whole form. A host field component,
199
518
  passed through `fields` or `slots.formFields`, binds the same way: its own
200
- value with `useFieldValue(field.name)` (or `useController`), another input's
519
+ value with `useFieldValue(field.name)`, which also gives the form the field's
520
+ rules (a component's own `useController` would drop them), another input's
201
521
  with `useFieldAt(path)` or `useWatch`, and a pick from a list with
202
522
  `useChoiceField`, which applies `autoselect` and `secondaryField`.
203
523
 
@@ -249,7 +569,10 @@ clamped to the current grid's column count. `gap` accepts `none`, `sm`, `md`
249
569
  `$meta.labelPosition` still overrides them.
250
570
 
251
571
  A grid defaults to `align: independent`: its children start at the top and their
252
- contents flow independently. Set `align: rows` when every immediate child is a
572
+ contents flow independently, except that fields side by side line up their
573
+ controls. A label that wraps to two lines sits at the foot of a label row the
574
+ fields in that row share, so its control stays level with its neighbors'.
575
+ Set `align: rows` when every immediate child is a
253
576
  section. Adjacent sections then share a header row and one row per direct child.
254
577
  A description, help text, or validation message increases the shared row height,
255
578
  so the following rows stay aligned. A nested grid counts as one child row.
@@ -1,3 +1,4 @@
1
+ import { type ToolStrings } from './toolStrings.js';
1
2
  export declare const MAX_EDIT_DIFF_LINES = 100;
2
3
  export declare const MAX_WRITE_DIFF_LINES = 50;
3
4
  export interface EditToolArgs {
@@ -31,4 +32,4 @@ export interface WriteModel {
31
32
  truncated: boolean;
32
33
  }
33
34
  export declare function computeWriteRows(content: string): WriteModel;
34
- export declare function editSummary(toolName: string, argsJSON: string): string;
35
+ export declare function editSummary(toolName: string, argsJSON: string, t?: ToolStrings): string;
@@ -1,3 +1,4 @@
1
+ import { defaultToolStrings } from "./toolStrings.js";
1
2
  import { sanitizeLabel } from "./toolfmt.js";
2
3
  //#region src/ai/agent/diff.ts
3
4
  var MAX_EDIT_DIFF_LINES = 100;
@@ -201,23 +202,14 @@ function computeWriteRows(content) {
201
202
  truncated: lines.length > 50
202
203
  };
203
204
  }
204
- function editSummary(toolName, argsJSON) {
205
+ function editSummary(toolName, argsJSON, t = defaultToolStrings) {
205
206
  const a = parseEditArgs(argsJSON);
206
207
  if (!a) return "";
207
- const count = (n) => `${n} ${n === 1 ? "line" : "lines"}`;
208
208
  if (toolName === "EditFile") {
209
209
  const [added, removed] = lineDelta(splitLines(a.old_string ?? ""), splitLines(a.new_string ?? ""));
210
- if (added > 0 && removed > 0) return `Added ${count(added)}, removed ${count(removed)}`;
211
- if (added > 0) return `Added ${count(added)}`;
212
- if (removed > 0) return `Removed ${count(removed)}`;
213
- return "";
214
- }
215
- if (toolName === "WriteFile") {
216
- if (a.content === void 0) return "";
217
- let s = `Wrote ${count(splitLines(a.content).length)}`;
218
- if (a.path) s += ` to ${sanitizeLabel(a.path)}`;
219
- return s;
210
+ return t.edited(added, removed);
220
211
  }
212
+ if (toolName === "WriteFile" && a.content !== void 0) return t.wrote(splitLines(a.content).length, a.path ? sanitizeLabel(a.path) : "");
221
213
  return "";
222
214
  }
223
215
  //#endregion
@@ -3,4 +3,4 @@ export interface DiffToken {
3
3
  color?: string;
4
4
  }
5
5
  export declare function languageForPath(path: string | undefined): string | null;
6
- export declare function tokenizeDiffLines(lines: string[], lang: string, isDark: boolean): Promise<DiffToken[][] | null>;
6
+ export declare function tokenizeDiffLines(lines: string[], lang: string): Promise<DiffToken[][] | null>;
@@ -1,3 +1,4 @@
1
+ import { CODE_THEME } from "../../components/codeTheme.js";
1
2
  //#region src/ai/agent/diffHighlight.ts
2
3
  var EXT_LANG = {
3
4
  ts: "typescript",
@@ -72,7 +73,7 @@ function getHighlighter(lang) {
72
73
  const [{ createHighlighter }, { createJavaScriptRegexEngine }] = await Promise.all([import("shiki"), import("shiki/engine/javascript")]);
73
74
  return await createHighlighter({
74
75
  langs: [lang],
75
- themes: ["github-light", "github-dark"],
76
+ themes: [CODE_THEME],
76
77
  engine: createJavaScriptRegexEngine({ forgiving: true })
77
78
  });
78
79
  })().catch(() => null);
@@ -80,13 +81,13 @@ function getHighlighter(lang) {
80
81
  }
81
82
  return p;
82
83
  }
83
- async function tokenizeDiffLines(lines, lang, isDark) {
84
+ async function tokenizeDiffLines(lines, lang) {
84
85
  const highlighter = await getHighlighter(lang);
85
86
  if (!highlighter) return null;
86
87
  try {
87
88
  const tokens = highlighter.codeToTokensBase(lines.join("\n"), {
88
89
  lang,
89
- theme: isDark ? "github-dark" : "github-light"
90
+ theme: CODE_THEME.name
90
91
  });
91
92
  if (tokens.length !== lines.length) return null;
92
93
  return tokens.map((line) => line.map((t) => ({
@@ -2,5 +2,6 @@ export { classifyPseudoUserMessage } from './classifier.js';
2
2
  export { computeEditDiff, computeWriteRows, type DiffRow, type EditDiffModel, type EditToolArgs, editSummary, isEditDiffTool, lineDelta, MAX_EDIT_DIFF_LINES, MAX_WRITE_DIFF_LINES, parseEditArgs, type WriteModel, wordEmphasisRanges, } from './diff.js';
3
3
  export { type DiffToken, languageForPath, tokenizeDiffLines, } from './diffHighlight.js';
4
4
  export { clampPermissionMode, DEFAULT_PERMISSION_MODE, isNamedPermissionMode, NAMED_PERMISSION_MODES, type NamedPermissionMode, type PermissionMode, permissionModesUpTo, } from './permissions.js';
5
- export { AGENT_COLOR_NAMES, agentColorHex, bashExitCode, clip, fullToolArgs, isGroupableTool, plural, resultFailed, rollupSentence, sanitizeLabel, sanitizePanelText, summarizeToolArgs, type ToolHeader, toolHeaderFor, toolSummary, } from './toolfmt.js';
5
+ export { AGENT_COLOR_NAMES, agentColorHex, bashExitCode, clip, fullToolArgs, isGroupableTool, resultFailed, rollupSentence, sanitizeLabel, sanitizePanelText, summarizeToolArgs, type ToolHeader, type ToolSummaryOptions, toolHeaderFor, toolSummary, } from './toolfmt.js';
6
+ export { defaultToolStrings, type ToolStrings } from './toolStrings.js';
6
7
  export { agentTypeLabel, askQuestionFromArgs, firstNonEmptyLine, hiddenTranscriptTool, INTERRUPTED_NOTICE, interruptionNotice, parseSubagentNotice, planFromArgs, type SubagentNotice, subagentDeliveryLine, taskCallFromArgs, thinkingHeading, } from './transcript.js';
@@ -0,0 +1,37 @@
1
+ export interface ToolStrings {
2
+ /** A call that printed nothing. */
3
+ noOutput: string;
4
+ /** A result's first line, and how many lines follow it. */
5
+ firstLine: (line: string, moreLines: number) => string;
6
+ emptyFile: string;
7
+ readImage: string;
8
+ /** `more` counts the lines the read left out; 0 when it read them all. */
9
+ readLines: (lines: number, more: number) => string;
10
+ noMatches: string;
11
+ foundMatches: (matches: number, files: number) => string;
12
+ foundFiles: (files: number) => string;
13
+ noFilesMatched: string;
14
+ /** A search summary whose own output was capped. */
15
+ truncated: (summary: string) => string;
16
+ /** `lines` is 0 when the command printed nothing. */
17
+ exitCode: (code: number, lines: number) => string;
18
+ httpStatus: (status: number, lines: number) => string;
19
+ /** A summary whose result was cut down before it was recorded. */
20
+ outputTruncated: (summary: string) => string;
21
+ edited: (added: number, removed: number) => string;
22
+ /** `path` is empty when the call named none. */
23
+ wrote: (lines: number, path: string) => string;
24
+ /** One clause per kind of call in a run of quick calls, joined into a sentence. */
25
+ rollup: {
26
+ searched: (patterns: number) => string;
27
+ read: (files: number) => string;
28
+ ranCommands: (commands: number) => string;
29
+ fetched: (urls: number) => string;
30
+ loadedSkills: (skills: number) => string;
31
+ sentMessages: (messages: number) => string;
32
+ calledMcpTools: (tools: number) => string;
33
+ ranTools: (tools: number) => string;
34
+ sentence: (clauses: string[]) => string;
35
+ };
36
+ }
37
+ export declare const defaultToolStrings: ToolStrings;
@@ -0,0 +1,35 @@
1
+ //#region src/ai/agent/toolStrings.ts
2
+ var count = (n, one, many) => `${n.toLocaleString()} ${n === 1 ? one : many}`;
3
+ var defaultToolStrings = {
4
+ noOutput: "(no output)",
5
+ firstLine: (line, moreLines) => moreLines > 0 ? `${line} (+${count(moreLines, "line", "lines")})` : line,
6
+ emptyFile: "Empty file",
7
+ readImage: "Read image",
8
+ readLines: (lines, more) => more > 0 ? `Read ${count(lines, "line", "lines")} (${more.toLocaleString()} more)` : `Read ${count(lines, "line", "lines")}`,
9
+ noMatches: "No matches",
10
+ foundMatches: (matches, files) => `Found ${count(matches, "match", "matches")} in ${count(files, "file", "files")}`,
11
+ foundFiles: (files) => `Found ${count(files, "file", "files")}`,
12
+ noFilesMatched: "No files matched",
13
+ truncated: (summary) => `${summary} (truncated)`,
14
+ exitCode: (code, lines) => lines > 0 ? `Exit ${code} · ${count(lines, "line", "lines")}` : `Exit ${code}`,
15
+ httpStatus: (status, lines) => `HTTP ${status} · ${count(lines, "line", "lines")}`,
16
+ outputTruncated: (summary) => `${summary} (output truncated)`,
17
+ edited: (added, removed) => added > 0 && removed > 0 ? `Added ${count(added, "line", "lines")}, removed ${count(removed, "line", "lines")}` : added > 0 ? `Added ${count(added, "line", "lines")}` : removed > 0 ? `Removed ${count(removed, "line", "lines")}` : "",
18
+ wrote: (lines, path) => path ? `Wrote ${count(lines, "line", "lines")} to ${path}` : `Wrote ${count(lines, "line", "lines")}`,
19
+ rollup: {
20
+ searched: (n) => `searched for ${count(n, "pattern", "patterns")}`,
21
+ read: (n) => `read ${count(n, "file", "files")}`,
22
+ ranCommands: (n) => `ran ${count(n, "shell command", "shell commands")}`,
23
+ fetched: (n) => `fetched ${count(n, "URL", "URLs")}`,
24
+ loadedSkills: (n) => `loaded ${count(n, "skill", "skills")}`,
25
+ sentMessages: (n) => `sent ${count(n, "message", "messages")}`,
26
+ calledMcpTools: (n) => `called ${count(n, "MCP tool", "MCP tools")}`,
27
+ ranTools: (n) => `ran ${count(n, "tool", "tools")}`,
28
+ sentence: (clauses) => {
29
+ const s = clauses.join(", ");
30
+ return s.charAt(0).toUpperCase() + s.slice(1);
31
+ }
32
+ }
33
+ };
34
+ //#endregion
35
+ export { defaultToolStrings };
@@ -1,3 +1,4 @@
1
+ import { type ToolStrings } from './toolStrings.js';
1
2
  export interface ToolHeader {
2
3
  label: string;
3
4
  arg?: string;
@@ -8,11 +9,15 @@ export declare function sanitizeLabel(s: string): string;
8
9
  export declare function sanitizePanelText(s: string): string;
9
10
  export declare function summarizeToolArgs(primary: string | undefined, argsJSON: string): string;
10
11
  export declare function fullToolArgs(primary: string | undefined, argsJSON: string): string;
11
- export declare function plural(n: number, noun: string): string;
12
12
  export declare function resultFailed(name: string, result: string): boolean;
13
13
  export declare function bashExitCode(body: string): [string, number, boolean];
14
- export declare function toolSummary(name: string, args: string, result: string, isError: boolean, editSummaryFn?: (toolName: string, argsJSON: string) => string): string;
14
+ export interface ToolSummaryOptions {
15
+ /** The edit tools' own summary; passed in to keep this module free of the diff one. */
16
+ editSummary?: (toolName: string, argsJSON: string, strings: ToolStrings) => string;
17
+ strings?: ToolStrings;
18
+ }
19
+ export declare function toolSummary(name: string, args: string, result: string, isError: boolean, { editSummary, strings: t }?: ToolSummaryOptions): string;
15
20
  export declare function isGroupableTool(name: string): boolean;
16
- export declare function rollupSentence(names: string[]): string;
21
+ export declare function rollupSentence(names: string[], t?: ToolStrings): string;
17
22
  export declare const AGENT_COLOR_NAMES: readonly ['blue', 'green', 'yellow', 'purple', 'cyan', 'orange', 'pink', 'red'];
18
23
  export declare function agentColorHex(name: string | undefined): string | null;