@parallelworks/ui 0.18.0 → 0.19.1

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 (349) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/memoryStore.js +152 -0
  4. package/dist/ai/adapter/mock/index.d.ts +2 -0
  5. package/dist/ai/adapter/mock/index.js +3 -0
  6. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  7. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  8. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  9. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  10. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  11. package/dist/ai/adapter/openai/errors.js +37 -0
  12. package/dist/ai/adapter/openai/index.d.ts +6 -0
  13. package/dist/ai/adapter/openai/index.js +6 -0
  14. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  15. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  16. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  17. package/dist/ai/adapter/openai/responses.js +108 -0
  18. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  19. package/dist/ai/adapter/openai/sse.js +112 -0
  20. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  21. package/dist/ai/adapter/types.d.ts +131 -0
  22. package/dist/ai/adapter/types.js +11 -0
  23. package/dist/ai/agent/classifier.d.ts +2 -0
  24. package/dist/ai/agent/classifier.js +12 -0
  25. package/dist/ai/agent/diff.d.ts +35 -0
  26. package/dist/ai/agent/diff.js +223 -0
  27. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  28. package/dist/ai/agent/diffHighlight.js +101 -0
  29. package/dist/ai/agent/index.d.ts +6 -0
  30. package/dist/ai/agent/permissions.d.ts +11 -0
  31. package/dist/ai/agent/permissions.js +29 -0
  32. package/dist/ai/agent/toolfmt.d.ts +18 -0
  33. package/dist/ai/agent/toolfmt.js +383 -0
  34. package/dist/ai/agent/transcript.d.ts +38 -0
  35. package/dist/ai/agent/transcript.js +127 -0
  36. package/dist/ai/ai.css +325 -0
  37. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  38. package/dist/ai/components/AllocationSelector.js +56 -0
  39. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  40. package/dist/ai/components/AttachmentManager.js +144 -0
  41. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  42. package/dist/ai/components/AttachmentUpload.js +179 -0
  43. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  44. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  45. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  46. package/dist/ai/components/BranchNavigator.js +57 -0
  47. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  48. package/dist/ai/components/ChatEmptyState.js +171 -0
  49. package/dist/ai/components/ChatInput.d.ts +45 -0
  50. package/dist/ai/components/ChatInput.js +265 -0
  51. package/dist/ai/components/ChatLayout.d.ts +5 -0
  52. package/dist/ai/components/ChatLayout.js +15 -0
  53. package/dist/ai/components/ChatMessage.d.ts +24 -0
  54. package/dist/ai/components/ChatMessage.js +338 -0
  55. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  56. package/dist/ai/components/ChatMessageList.js +301 -0
  57. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  58. package/dist/ai/components/ChatSidebar.js +345 -0
  59. package/dist/ai/components/ChatThread.d.ts +3 -0
  60. package/dist/ai/components/ChatThread.js +198 -0
  61. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  62. package/dist/ai/components/ComposerChrome.js +50 -0
  63. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  64. package/dist/ai/components/ComposerFrame.js +33 -0
  65. package/dist/ai/components/DragOverlay.d.ts +5 -0
  66. package/dist/ai/components/DragOverlay.js +20 -0
  67. package/dist/ai/components/ModelSelector.d.ts +6 -0
  68. package/dist/ai/components/ModelSelector.js +343 -0
  69. package/dist/ai/components/ShareDialog.d.ts +11 -0
  70. package/dist/ai/components/ShareDialog.js +260 -0
  71. package/dist/ai/components/SlashMenu.d.ts +28 -0
  72. package/dist/ai/components/SlashMenu.js +91 -0
  73. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  74. package/dist/ai/components/agent/ActivityLine.js +151 -0
  75. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  76. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  77. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  78. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  79. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  80. package/dist/ai/components/attachmentKeys.js +10 -0
  81. package/dist/ai/core/ChatProvider.d.ts +66 -0
  82. package/dist/ai/core/ChatProvider.js +848 -0
  83. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  84. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  85. package/dist/ai/core/chatReducer.d.ts +114 -0
  86. package/dist/ai/core/chatReducer.js +223 -0
  87. package/dist/ai/core/config.d.ts +47 -0
  88. package/dist/ai/core/config.js +45 -0
  89. package/dist/ai/core/events.d.ts +1 -0
  90. package/dist/ai/core/events.js +4 -0
  91. package/dist/ai/core/exportConversation.d.ts +4 -0
  92. package/dist/ai/core/exportConversation.js +42 -0
  93. package/dist/ai/core/greeting.d.ts +3 -0
  94. package/dist/ai/core/greeting.js +38 -0
  95. package/dist/ai/core/parts.d.ts +11 -0
  96. package/dist/ai/core/parts.js +84 -0
  97. package/dist/ai/core/useDragDrop.d.ts +14 -0
  98. package/dist/ai/core/useDragDrop.js +36 -0
  99. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  100. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  101. package/dist/ai/core/useSSEStream.d.ts +34 -0
  102. package/dist/ai/core/useSSEStream.js +98 -0
  103. package/dist/ai/index.d.ts +40 -0
  104. package/dist/ai/index.js +44 -0
  105. package/dist/ai/strings.d.ts +167 -0
  106. package/dist/ai/strings.js +175 -0
  107. package/dist/ai/types.d.ts +236 -0
  108. package/dist/ai/ui/Avatar.d.ts +8 -0
  109. package/dist/ai/ui/Avatar.js +35 -0
  110. package/dist/ai/ui/Dropdown.d.ts +31 -0
  111. package/dist/ai/ui/Dropdown.js +110 -0
  112. package/dist/ai/ui/Markdown.d.ts +8 -0
  113. package/dist/ai/ui/Markdown.js +79 -0
  114. package/dist/ai/ui/Notice.d.ts +21 -0
  115. package/dist/ai/ui/Notice.js +77 -0
  116. package/dist/ai/ui/buttons.d.ts +1 -0
  117. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  118. package/dist/ai/ui/codeBreaks.js +36 -0
  119. package/dist/ai/ui/prose.d.ts +1 -0
  120. package/dist/ai/ui/prose.js +13 -0
  121. package/dist/ai/ui/sidebar.d.ts +81 -0
  122. package/dist/ai/ui/sidebar.js +148 -0
  123. package/dist/ai/utils.d.ts +4 -0
  124. package/dist/ai/utils.js +23 -0
  125. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  126. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  127. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  128. package/dist/components/AddMenu.js +46 -0
  129. package/dist/components/Avatar.d.ts +1 -1
  130. package/dist/components/Avatar.js +46 -0
  131. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  132. package/dist/components/Breadcrumbs.d.ts +1 -1
  133. package/dist/components/Breadcrumbs.js +83 -0
  134. package/dist/components/Button.js +83 -0
  135. package/dist/components/Callout.js +23 -0
  136. package/dist/components/Card.js +31 -0
  137. package/dist/components/CollapsiblePanel.js +77 -0
  138. package/dist/components/ConfirmModal.js +74 -0
  139. package/dist/components/CopyToClipboard.js +81 -0
  140. package/dist/{chunks/CreateModal-BY6DLmur.js → components/CreateModal.js} +10 -189
  141. package/dist/components/DescriptionList.js +42 -0
  142. package/dist/components/Dropdown.d.ts +1 -1
  143. package/dist/components/Dropdown.js +349 -0
  144. package/dist/components/EmptyState.d.ts +1 -1
  145. package/dist/components/EmptyState.js +27 -0
  146. package/dist/components/Filter.js +32 -0
  147. package/dist/components/FilterPill.js +13 -0
  148. package/dist/components/IconButton.js +34 -0
  149. package/dist/components/Indicator.d.ts +2 -2
  150. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  151. package/dist/components/Input.d.ts +1 -1
  152. package/dist/components/Input.js +88 -0
  153. package/dist/components/LetterBadge.d.ts +1 -1
  154. package/dist/components/LetterBadge.js +13 -0
  155. package/dist/components/Listbox.js +123 -0
  156. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  157. package/dist/components/Markdown.js +15 -0
  158. package/dist/components/MarkdownImpl.d.ts +1 -1
  159. package/dist/components/MultiSelect.js +171 -0
  160. package/dist/components/Overview.js +39 -0
  161. package/dist/components/PageHeader.js +194 -0
  162. package/dist/components/Pagination.js +35 -0
  163. package/dist/components/Provider.d.ts +16 -65
  164. package/dist/{chunks/Provider-Ghua9PkN.js → components/Provider.js} +54 -20
  165. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  166. package/dist/components/SectionHeader.js +11 -0
  167. package/dist/components/SettingModeOption.js +30 -0
  168. package/dist/components/SettingRow.d.ts +1 -1
  169. package/dist/components/SettingRow.js +35 -0
  170. package/dist/components/SettingsCard.js +31 -0
  171. package/dist/components/SettingsGroup.d.ts +1 -1
  172. package/dist/components/SettingsGroup.js +17 -0
  173. package/dist/components/Sort.js +42 -0
  174. package/dist/components/StatusBadge.js +63 -0
  175. package/dist/components/SwitchToggle.js +59 -0
  176. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  177. package/dist/{chunks/Table-4OHjdKdO.js → components/Table.js} +7 -5
  178. package/dist/components/Toggle.js +20 -0
  179. package/dist/{chunks/Tooltip-Crxo_eU_.js → components/Tooltip.js} +6 -4
  180. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  181. package/dist/components/focus.d.ts +2 -0
  182. package/dist/components/focus.js +7 -0
  183. package/dist/components/ghostButton.js +7 -0
  184. package/dist/components/inputClasses.js +4 -0
  185. package/dist/components/keys.d.ts +12 -0
  186. package/dist/components/keys.js +27 -0
  187. package/dist/components/relativeTime.js +32 -0
  188. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  189. package/dist/duration.d.ts +3 -0
  190. package/dist/duration.js +17 -0
  191. package/dist/editor/Editor.js +13 -0
  192. package/dist/editor/EditorField.js +53 -0
  193. package/dist/editor/FormCodePanel.js +173 -0
  194. package/dist/editor/Monaco.d.ts +1 -20
  195. package/dist/editor/Monaco.js +112 -0
  196. package/dist/editor/index.d.ts +2 -1
  197. package/dist/editor/index.js +7 -2
  198. package/dist/editor/themes.js +91 -0
  199. package/dist/editor/workers.js +29 -0
  200. package/dist/editor/yaml.d.ts +5 -0
  201. package/dist/editor/yaml.js +15 -0
  202. package/dist/engine.d.ts +98 -0
  203. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  204. package/dist/file-explorer/FileExplorer.js +1402 -0
  205. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  206. package/dist/file-explorer/FileExplorerContext.js +370 -0
  207. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  208. package/dist/{chunks/CodePreviewEditor-4lx3kE-w.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  209. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  210. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  211. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  212. package/dist/file-explorer/FilePreview/index.js +266 -0
  213. package/dist/file-explorer/FilePreview/parse.js +63 -0
  214. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  215. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  216. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  217. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  218. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  219. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  220. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  221. package/dist/file-explorer/FileRow.d.ts +1 -1
  222. package/dist/file-explorer/FileRow.js +165 -0
  223. package/dist/file-explorer/FileRowsWindow.js +92 -0
  224. package/dist/file-explorer/FileTable.js +172 -0
  225. package/dist/file-explorer/FileTableHeaders.js +49 -0
  226. package/dist/file-explorer/LoadMoreRow.js +46 -0
  227. package/dist/file-explorer/TreeView.js +376 -0
  228. package/dist/file-explorer/helpers.d.ts +4 -4
  229. package/dist/file-explorer/helpers.js +537 -0
  230. package/dist/file-explorer/index.d.ts +3 -3
  231. package/dist/file-explorer/index.js +7 -5705
  232. package/dist/file-explorer/lib/batch.js +39 -0
  233. package/dist/file-explorer/lib/errors.js +9 -0
  234. package/dist/file-explorer/lib/paging.js +124 -0
  235. package/dist/file-explorer/lib/types.d.ts +6 -1
  236. package/dist/file-explorer/lib/utils.d.ts +1 -3
  237. package/dist/file-explorer/lib/utils.js +322 -0
  238. package/dist/file-explorer/toasts.js +400 -0
  239. package/dist/file-explorer/treeRows.js +73 -0
  240. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  241. package/dist/file-explorer/useNearEnd.js +27 -0
  242. package/dist/form/FieldWrapper.d.ts +2 -2
  243. package/dist/form/FieldWrapper.js +54 -0
  244. package/dist/form/Fields/BooleanField.js +51 -0
  245. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  246. package/dist/form/Fields/ColorField.js +33 -0
  247. package/dist/form/Fields/DropdownField.js +49 -0
  248. package/dist/form/Fields/DurationField.js +130 -0
  249. package/dist/form/Fields/LabelField.js +19 -0
  250. package/dist/form/Fields/MultiDropdownField.js +40 -0
  251. package/dist/form/Fields/NumberField.js +51 -0
  252. package/dist/form/Fields/ObjectField.js +54 -0
  253. package/dist/form/Fields/RadioField.js +49 -0
  254. package/dist/form/Fields/RangeField.js +58 -0
  255. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  256. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  257. package/dist/form/Fields/StepField.js +6 -0
  258. package/dist/form/Fields/StringField.js +37 -0
  259. package/dist/form/Fields/TextAreaField.js +31 -0
  260. package/dist/form/Fields/durationValidity.js +11 -0
  261. package/dist/form/Form.d.ts +4 -21
  262. package/dist/form/Form.js +643 -0
  263. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  264. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  265. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  266. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  267. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  268. package/dist/form/Wizard/WizardContainer.js +138 -0
  269. package/dist/form/Wizard/WizardNavigation.js +92 -0
  270. package/dist/form/Wizard/WizardStepContent.js +35 -0
  271. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  272. package/dist/form/Wizard/useWizardState.js +118 -0
  273. package/dist/form/Wizard/utils.js +34 -0
  274. package/dist/form/fieldContext.js +26 -0
  275. package/dist/form/fieldRegistry.js +50 -0
  276. package/dist/form/index.d.ts +11 -12
  277. package/dist/form/index.js +18 -2445
  278. package/dist/form/lib.d.ts +6 -1
  279. package/dist/{chunks/FieldWrapper-Bef01EWO.js → form/lib.js} +5 -104
  280. package/dist/form/types/fieldComponentTypes.d.ts +3 -2
  281. package/dist/form/types/fieldTypes.d.ts +6 -20
  282. package/dist/form/useParsedOpts.d.ts +1 -1
  283. package/dist/form/useParsedOpts.js +62 -0
  284. package/dist/form/usePrevious.js +11 -0
  285. package/dist/form/utils/checkShowIfObject.js +14 -0
  286. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  287. package/dist/form/utils/duration.js +69 -0
  288. package/dist/form/utils/getParentValue.js +23 -0
  289. package/dist/form/utils/getPlaceholder.js +9 -0
  290. package/dist/form/utils/getValueUsingPath.js +23 -0
  291. package/dist/form/utils/secondaryField.js +22 -0
  292. package/dist/graph/AnnotationBanner.js +141 -0
  293. package/dist/graph/Collapse.js +41 -0
  294. package/dist/{workflow/index.js → graph/DependencyGraph.js} +76 -1163
  295. package/dist/graph/JobSummary.js +104 -0
  296. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  297. package/dist/graph/MatrixGroup.js +107 -0
  298. package/dist/graph/Reveal.js +57 -0
  299. package/dist/graph/TreeView.js +711 -0
  300. package/dist/{workflow → graph}/index.d.ts +1 -1
  301. package/dist/graph/index.js +2 -0
  302. package/dist/{workflow → graph}/types.d.ts +3 -3
  303. package/dist/graph/types.js +6 -0
  304. package/dist/icons.d.ts +20 -21
  305. package/dist/index.d.ts +38 -40
  306. package/dist/index.js +47 -599
  307. package/dist/list/ActionToolbar.js +184 -0
  308. package/dist/list/HoverCard.js +73 -0
  309. package/dist/list/ListPage.js +145 -0
  310. package/dist/list/ListPager.js +59 -0
  311. package/dist/list/ListTable.d.ts +1 -1
  312. package/dist/list/ListTable.js +163 -0
  313. package/dist/list/ListViewControls.d.ts +2 -2
  314. package/dist/list/ListViewControls.js +372 -0
  315. package/dist/list/RowContextMenu.js +350 -0
  316. package/dist/list/UserHoverCard.js +117 -0
  317. package/dist/list/index.d.ts +9 -9
  318. package/dist/list/index.js +11 -2
  319. package/dist/list/listSearch.js +137 -0
  320. package/dist/list/listView.js +210 -0
  321. package/dist/list/textEntry.js +10 -0
  322. package/dist/logviewer/LogViewer.d.ts +1 -1
  323. package/dist/logviewer/LogViewer.js +750 -0
  324. package/dist/logviewer/index.d.ts +1 -0
  325. package/dist/logviewer/index.js +3 -742
  326. package/dist/logviewer/segments.d.ts +9 -0
  327. package/dist/logviewer/segments.js +80 -0
  328. package/dist/styles/fonts.css +4 -4
  329. package/dist/styles/theme.css +6 -4
  330. package/dist/styles.css +1 -1
  331. package/dist/theme/index.js +2 -2
  332. package/package.json +38 -14
  333. package/LICENSE +0 -202
  334. package/dist/chunks/Monaco-C1POOdVv.js +0 -1046
  335. package/dist/chunks/PageHeader-l49p1nM9.js +0 -690
  336. package/dist/chunks/SwitchToggle-CHPP8uZQ.js +0 -755
  337. package/dist/chunks/editor-9_uVtUyy.js +0 -347
  338. package/dist/chunks/list-qrojZZNv.js +0 -1411
  339. package/dist/editor/usesGitlab.d.ts +0 -97
  340. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  341. package/dist/form/types/workflow-schema.d.ts +0 -1145
  342. package/dist/form/utils/pwResolver.d.ts +0 -18
  343. package/dist/{chunks/MarkdownImpl-Bq4QhrtA.js → components/MarkdownImpl.js} +1 -1
  344. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  345. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  346. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  347. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  348. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  349. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -0,0 +1,11 @@
1
+ declare const REQUESTABLE_PERMISSION_MODES: readonly ['read-only', 'accept-edits', 'bypass-permissions'];
2
+ export declare const NAMED_PERMISSION_MODES: readonly ["read-only", "accept-edits", "bypass-permissions", "plan"];
3
+ export type PermissionMode = (typeof REQUESTABLE_PERMISSION_MODES)[number];
4
+ export type NamedPermissionMode = (typeof NAMED_PERMISSION_MODES)[number];
5
+ export declare const DEFAULT_PERMISSION_MODE: PermissionMode;
6
+ export declare function isNamedPermissionMode(mode: string | undefined): mode is NamedPermissionMode;
7
+ /** The daemon clamps a remote request to its owner's remoteMaxPermissionMode,
8
+ * so a menu offers only what that machine will honour. */
9
+ export declare function permissionModesUpTo(ceiling: string | undefined): PermissionMode[];
10
+ export declare function clampPermissionMode(mode: PermissionMode, ceiling: string | undefined): PermissionMode;
11
+ export {};
@@ -0,0 +1,29 @@
1
+ //#region src/ai/agent/permissions.ts
2
+ var REQUESTABLE_PERMISSION_MODES = [
3
+ "read-only",
4
+ "accept-edits",
5
+ "bypass-permissions"
6
+ ];
7
+ var NAMED_PERMISSION_MODES = [...REQUESTABLE_PERMISSION_MODES, "plan"];
8
+ var DEFAULT_PERMISSION_MODE = "accept-edits";
9
+ var PERMISSION_RANK = {
10
+ "read-only": 0,
11
+ plan: 1,
12
+ "accept-edits": 2,
13
+ "bypass-permissions": 3
14
+ };
15
+ function isNamedPermissionMode(mode) {
16
+ return NAMED_PERMISSION_MODES.some((m) => m === mode);
17
+ }
18
+ /** The daemon clamps a remote request to its owner's remoteMaxPermissionMode,
19
+ * so a menu offers only what that machine will honour. */
20
+ function permissionModesUpTo(ceiling) {
21
+ const max = isNamedPermissionMode(ceiling) ? PERMISSION_RANK[ceiling] : PERMISSION_RANK[DEFAULT_PERMISSION_MODE];
22
+ return REQUESTABLE_PERMISSION_MODES.filter((m) => PERMISSION_RANK[m] <= max);
23
+ }
24
+ function clampPermissionMode(mode, ceiling) {
25
+ const offered = permissionModesUpTo(ceiling);
26
+ return offered.includes(mode) ? mode : offered[offered.length - 1] ?? "read-only";
27
+ }
28
+ //#endregion
29
+ export { DEFAULT_PERMISSION_MODE, NAMED_PERMISSION_MODES, clampPermissionMode, isNamedPermissionMode, permissionModesUpTo };
@@ -0,0 +1,18 @@
1
+ export interface ToolHeader {
2
+ label: string;
3
+ arg?: string;
4
+ }
5
+ export declare function toolHeaderFor(name: string): ToolHeader;
6
+ export declare function clip(s: string, max: number): string;
7
+ export declare function sanitizeLabel(s: string): string;
8
+ export declare function sanitizePanelText(s: string): string;
9
+ export declare function summarizeToolArgs(primary: string | undefined, argsJSON: string): string;
10
+ export declare function fullToolArgs(primary: string | undefined, argsJSON: string): string;
11
+ export declare function plural(n: number, noun: string): string;
12
+ export declare function resultFailed(name: string, result: string): boolean;
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;
15
+ export declare function isGroupableTool(name: string): boolean;
16
+ export declare function rollupSentence(names: string[]): string;
17
+ export declare const AGENT_COLOR_NAMES: readonly ['blue', 'green', 'yellow', 'purple', 'cyan', 'orange', 'pink', 'red'];
18
+ export declare function agentColorHex(name: string | undefined): string | null;
@@ -0,0 +1,383 @@
1
+ //#region src/ai/agent/toolfmt.ts
2
+ var TOOL_HEADERS = {
3
+ Bash: {
4
+ label: "Bash",
5
+ arg: "command"
6
+ },
7
+ ReadFile: {
8
+ label: "Read",
9
+ arg: "path"
10
+ },
11
+ WriteFile: {
12
+ label: "Write",
13
+ arg: "path"
14
+ },
15
+ EditFile: {
16
+ label: "Update",
17
+ arg: "path"
18
+ },
19
+ GlobSearch: {
20
+ label: "Glob",
21
+ arg: "pattern"
22
+ },
23
+ GrepSearch: {
24
+ label: "Grep",
25
+ arg: "pattern"
26
+ },
27
+ WebFetch: {
28
+ label: "WebFetch",
29
+ arg: "url"
30
+ },
31
+ Task: {
32
+ label: "Task",
33
+ arg: "description"
34
+ },
35
+ Skill: {
36
+ label: "Skill",
37
+ arg: "name"
38
+ },
39
+ SendMessage: {
40
+ label: "SendMessage",
41
+ arg: "to"
42
+ },
43
+ AskUserQuestion: {
44
+ label: "AskUserQuestion",
45
+ arg: "question"
46
+ },
47
+ TodoWrite: { label: "TodoWrite" }
48
+ };
49
+ function toolHeaderFor(name) {
50
+ return TOOL_HEADERS[name] ?? { label: name };
51
+ }
52
+ function clip(s, max) {
53
+ const r = [...s];
54
+ if (r.length <= max) return s;
55
+ if (max <= 3) return r.slice(0, max).join("");
56
+ return r.slice(0, max - 3).join("") + "...";
57
+ }
58
+ function sanitizeLabel(s) {
59
+ let out = "";
60
+ for (const ch of s) {
61
+ const c = ch.codePointAt(0) ?? 0;
62
+ if (ch === "\n" || ch === " ") out += " ";
63
+ else if (c < 32 || c === 127) {} else out += ch;
64
+ }
65
+ return out;
66
+ }
67
+ function sanitizePanelText(s) {
68
+ let out = "";
69
+ for (const ch of s) {
70
+ const c = ch.codePointAt(0) ?? 0;
71
+ if (ch === " ") out += " ";
72
+ else if (ch === "\n") out += ch;
73
+ else if (c < 32 || c === 127) {} else out += ch;
74
+ }
75
+ return out;
76
+ }
77
+ var SALIENT_ARG_ORDER = [
78
+ "command",
79
+ "pattern",
80
+ "path",
81
+ "file_path",
82
+ "glob",
83
+ "url",
84
+ "query",
85
+ "output_mode",
86
+ "question",
87
+ "header"
88
+ ];
89
+ var ELIDED_ARGS = /* @__PURE__ */ new Set([
90
+ "content",
91
+ "new_string",
92
+ "old_string",
93
+ "edits",
94
+ "options"
95
+ ]);
96
+ function clipArg(s, style) {
97
+ const flat = s.replaceAll("\n", " ");
98
+ if (style.valueClip <= 0) return flat;
99
+ return clip(flat, style.valueClip);
100
+ }
101
+ function displayArg(v, style) {
102
+ return sanitizeLabel(clipArg((typeof v === "string" ? v : JSON.stringify(v)) ?? "", style));
103
+ }
104
+ function formatToolArgs(primary, argsJSON, style) {
105
+ let m;
106
+ try {
107
+ m = JSON.parse(argsJSON);
108
+ } catch {
109
+ return "";
110
+ }
111
+ if (!m || typeof m !== "object" || Object.keys(m).length === 0) return "";
112
+ const seen = /* @__PURE__ */ new Set();
113
+ const parts = [];
114
+ const add = (k) => {
115
+ if (!(k in m) || seen.has(k)) return;
116
+ seen.add(k);
117
+ const v = m[k];
118
+ const rendered = typeof v === "string" ? `${k}: "${clipArg(sanitizeLabel(v), style)}"` : `${k}: ${displayArg(v, style)}`;
119
+ parts.push(rendered);
120
+ };
121
+ if (primary && primary in m) {
122
+ seen.add(primary);
123
+ parts.push(displayArg(m[primary], style));
124
+ }
125
+ for (const k of SALIENT_ARG_ORDER) add(k);
126
+ const rest = Object.keys(m).filter((k) => !ELIDED_ARGS.has(k) && !seen.has(k)).sort();
127
+ for (const k of rest) add(k);
128
+ const joined = parts.join(", ");
129
+ if (style.totalClip <= 0) return joined;
130
+ return clip(joined, style.totalClip);
131
+ }
132
+ function summarizeToolArgs(primary, argsJSON) {
133
+ return formatToolArgs(primary, argsJSON, {
134
+ valueClip: 50,
135
+ totalClip: 100
136
+ });
137
+ }
138
+ function fullToolArgs(primary, argsJSON) {
139
+ return formatToolArgs(primary, argsJSON, {
140
+ valueClip: 0,
141
+ totalClip: 0
142
+ });
143
+ }
144
+ function plural(n, noun) {
145
+ return `${n} ${pluralNoun(n, noun)}`;
146
+ }
147
+ function pluralNoun(n, noun) {
148
+ if (n === 1) return noun;
149
+ if (/(?:s|x|ch|sh)$/.test(noun)) return `${noun}es`;
150
+ return `${noun}s`;
151
+ }
152
+ var TOOL_OUTPUT_TRUNCATION_MARKER = "\n\n... output truncated to ";
153
+ function trimToolOutputNotice(body) {
154
+ const i = body.lastIndexOf(TOOL_OUTPUT_TRUNCATION_MARKER);
155
+ if (i >= 0) return [body.slice(0, i).replace(/\n+$/, ""), true];
156
+ return [body, false];
157
+ }
158
+ function summarizeToolResult(result) {
159
+ const trimmed = result.replace(/\n+$/, "");
160
+ if (trimmed.trim() === "") return "(no output)";
161
+ const lines = trimmed.split("\n");
162
+ const first = clip((lines[0] ?? "").trim(), 100);
163
+ if (lines.length > 1) return `${first} (+${lines.length - 1} lines)`;
164
+ return first;
165
+ }
166
+ function isErrorResult(text) {
167
+ return text.trim().startsWith("Error:");
168
+ }
169
+ var RIPGREP_ERROR_PREFIX = "ripgrep error (exit ";
170
+ function resultFailed(name, result) {
171
+ const body = result.trim();
172
+ switch (name) {
173
+ case "Bash":
174
+ if (bashExitCode(body)[2]) return true;
175
+ return isErrorResult(body) && !body.includes("\n");
176
+ case "WebFetch": return webFetchFailed(body);
177
+ case "GrepSearch": return body.startsWith(RIPGREP_ERROR_PREFIX) || isErrorResult(body);
178
+ default: return isErrorResult(body);
179
+ }
180
+ }
181
+ function webFetchFailed(body) {
182
+ if (body.startsWith("Error ")) return true;
183
+ const m = body.match(/^HTTP (\d+)/);
184
+ if (m) return Number(m[1]) >= 400;
185
+ return false;
186
+ }
187
+ function trailingNote(body) {
188
+ const i = body.lastIndexOf("\n");
189
+ const last = body.slice(i + 1);
190
+ if (last.startsWith("... (")) return [body.slice(0, Math.max(i, 0)), last];
191
+ return [body, ""];
192
+ }
193
+ function contentLines(body) {
194
+ const [rest, note] = trailingNote(body);
195
+ if (rest === "") return [[], note];
196
+ return [rest.split("\n"), note];
197
+ }
198
+ function readFileSummary(body) {
199
+ if (body === "(empty file)") return "Empty file";
200
+ if (body.startsWith("Read image ")) return "Read image";
201
+ const [lines, note] = contentLines(body);
202
+ let more = 0;
203
+ const m = note.match(/^\.\.\. \(truncated, (\d+) more lines\)/);
204
+ if (m) more = Number(m[1]);
205
+ if (more > 0) return `Read ${plural(lines.length, "line")} (${more} more)`;
206
+ return `Read ${plural(lines.length, "line")}`;
207
+ }
208
+ var GREP_CONTENT_PATH = /^(.+?):\d+:/;
209
+ function grepMatchPath(line, lineNums) {
210
+ if (!lineNums) {
211
+ const i = line.indexOf(":");
212
+ return i >= 0 ? line.slice(0, i) : null;
213
+ }
214
+ const m = GREP_CONTENT_PATH.exec(line);
215
+ return m ? m[1] ?? null : null;
216
+ }
217
+ function grepSearchSummary(argsJSON, body) {
218
+ if (body === "No matches found." || body === "No results after applying offset.") return "No matches";
219
+ if (body.startsWith(RIPGREP_ERROR_PREFIX)) return summarizeToolResult(body);
220
+ const [lines, note] = contentLines(body);
221
+ let outputMode = "";
222
+ let lineNums = true;
223
+ try {
224
+ const a = JSON.parse(argsJSON);
225
+ outputMode = a.output_mode ?? "";
226
+ if (typeof a.n === "boolean") lineNums = a.n;
227
+ } catch {}
228
+ let s;
229
+ if (outputMode === "content") {
230
+ const files = /* @__PURE__ */ new Set();
231
+ let matches = 0;
232
+ for (const l of lines) {
233
+ const path = grepMatchPath(l, lineNums);
234
+ if (path === null) continue;
235
+ matches++;
236
+ files.add(path);
237
+ }
238
+ s = `Found ${plural(matches, "match")} in ${plural(files.size, "file")}`;
239
+ } else if (outputMode === "count") {
240
+ let total = 0;
241
+ for (const l of lines) {
242
+ const i = l.lastIndexOf(":");
243
+ const tail = i >= 0 ? l.slice(i + 1) : l;
244
+ const n = Number.parseInt(tail, 10);
245
+ if (!Number.isNaN(n)) total += n;
246
+ }
247
+ s = `Found ${plural(total, "match")} in ${plural(lines.length, "file")}`;
248
+ } else s = `Found ${plural(lines.length, "file")}`;
249
+ if (note !== "") s += " (truncated)";
250
+ return s;
251
+ }
252
+ function globSearchSummary(body) {
253
+ if (body === "No files matched the pattern.") return "No files matched";
254
+ const [lines, note] = contentLines(body);
255
+ let s = `Found ${plural(lines.length, "file")}`;
256
+ if (note !== "") s += " (truncated)";
257
+ return s;
258
+ }
259
+ function bashExitCode(body) {
260
+ let i = body.lastIndexOf("\nExit code: ");
261
+ if (i < 0) {
262
+ if (!body.startsWith("Exit code: ")) return [
263
+ body,
264
+ 0,
265
+ false
266
+ ];
267
+ i = 0;
268
+ }
269
+ const m = body.slice(i).replace(/^\n/, "").match(/^Exit code: (\d+)/);
270
+ const code = m ? Number(m[1]) : 0;
271
+ return [
272
+ body.slice(0, i).replace(/\n+$/, ""),
273
+ code,
274
+ true
275
+ ];
276
+ }
277
+ function bashSummary(body) {
278
+ if (body === "(no output)") return "(no output)";
279
+ const [out, code, ok] = bashExitCode(body);
280
+ if (!ok) return summarizeToolResult(body);
281
+ if (out === "") return `Exit ${code}`;
282
+ return `Exit ${code} · ${plural(out.split("\n").length, "line")}`;
283
+ }
284
+ function webFetchSummary(body) {
285
+ const m = body.match(/^HTTP (\d+)/);
286
+ if (!m) return summarizeToolResult(body);
287
+ const status = Number(m[1]);
288
+ const sep = body.indexOf("\n\n");
289
+ if (sep < 0) return clip(body.split("\n")[0] ?? "", 100);
290
+ return `HTTP ${status} · ${plural(body.slice(sep + 2).split("\n").length, "line")}`;
291
+ }
292
+ function toolSummary(name, args, result, isError, editSummaryFn) {
293
+ const [body, spilled] = trimToolOutputNotice(result.replace(/\n+$/, ""));
294
+ if (isError || body.trim() === "" || isErrorResult(body)) return summarizeToolResult(result);
295
+ let s;
296
+ switch (name) {
297
+ case "EditFile":
298
+ case "WriteFile": {
299
+ const e = editSummaryFn?.(name, args) ?? "";
300
+ return e !== "" ? e : summarizeToolResult(result);
301
+ }
302
+ case "ReadFile":
303
+ s = readFileSummary(body);
304
+ break;
305
+ case "GrepSearch":
306
+ s = grepSearchSummary(args, body);
307
+ break;
308
+ case "GlobSearch":
309
+ s = globSearchSummary(body);
310
+ break;
311
+ case "Bash":
312
+ s = bashSummary(body);
313
+ break;
314
+ case "WebFetch":
315
+ s = webFetchSummary(body);
316
+ break;
317
+ default: return summarizeToolResult(result);
318
+ }
319
+ if (spilled) s += " (output truncated)";
320
+ return s;
321
+ }
322
+ var ROLLUP_CATEGORIES = [
323
+ [(n) => n === "GrepSearch" || n === "GlobSearch", (n) => `searched for ${plural(n, "pattern")}`],
324
+ [(n) => n === "ReadFile", (n) => `read ${plural(n, "file")}`],
325
+ [(n) => n === "Bash", (n) => `ran ${plural(n, "shell command")}`],
326
+ [(n) => n === "WebFetch", (n) => `fetched ${plural(n, "URL")}`],
327
+ [(n) => n === "Skill", (n) => `loaded ${plural(n, "skill")}`],
328
+ [(n) => n === "SendMessage", (n) => `sent ${plural(n, "message")}`],
329
+ [(n) => n.startsWith("mcp__"), (n) => `called ${plural(n, "MCP tool")}`],
330
+ [() => true, (n) => `ran ${plural(n, "tool")}`]
331
+ ];
332
+ var NON_GROUPABLE_TOOLS = /* @__PURE__ */ new Set([
333
+ "EditFile",
334
+ "WriteFile",
335
+ "TodoWrite",
336
+ "Task"
337
+ ]);
338
+ function isGroupableTool(name) {
339
+ return !NON_GROUPABLE_TOOLS.has(name);
340
+ }
341
+ function rollupSentence(names) {
342
+ const counts = ROLLUP_CATEGORIES.map(() => 0);
343
+ for (const name of names) for (let i = 0; i < ROLLUP_CATEGORIES.length; i++) if (ROLLUP_CATEGORIES[i]?.[0](name)) {
344
+ counts[i] = (counts[i] ?? 0) + 1;
345
+ break;
346
+ }
347
+ const parts = [];
348
+ for (let i = 0; i < counts.length; i++) {
349
+ const n = counts[i] ?? 0;
350
+ if (n > 0) {
351
+ const cat = ROLLUP_CATEGORIES[i];
352
+ if (cat) parts.push(cat[1](n));
353
+ }
354
+ }
355
+ if (parts.length === 0) return "";
356
+ const s = parts.join(", ");
357
+ return s.charAt(0).toUpperCase() + s.slice(1);
358
+ }
359
+ var AGENT_COLOR_NAMES = [
360
+ "blue",
361
+ "green",
362
+ "yellow",
363
+ "purple",
364
+ "cyan",
365
+ "orange",
366
+ "pink",
367
+ "red"
368
+ ];
369
+ var AGENT_COLOR_HEX = {
370
+ red: "#ef4444",
371
+ blue: "#3b82f6",
372
+ green: "#22c55e",
373
+ yellow: "#eab308",
374
+ purple: "#a855f7",
375
+ orange: "#f97316",
376
+ pink: "#ec4899",
377
+ cyan: "#06b6d4"
378
+ };
379
+ function agentColorHex(name) {
380
+ return name ? AGENT_COLOR_HEX[name] ?? null : null;
381
+ }
382
+ //#endregion
383
+ export { AGENT_COLOR_NAMES, agentColorHex, bashExitCode, clip, fullToolArgs, isGroupableTool, plural, resultFailed, rollupSentence, sanitizeLabel, sanitizePanelText, summarizeToolArgs, toolHeaderFor, toolSummary };
@@ -0,0 +1,38 @@
1
+ export declare function hiddenTranscriptTool(name: string): boolean;
2
+ export declare function askQuestionFromArgs(argsJSON: string): string;
3
+ export declare function planFromArgs(argsJSON: string): string;
4
+ /** A Task call's display label the way the tool itself picks it: the
5
+ * description, else the clipped prompt, plus its custom agent type. */
6
+ export declare function taskCallFromArgs(argsJSON: string): {
7
+ description: string;
8
+ agentType: string;
9
+ };
10
+ /** The built-in "default" type is the same general-purpose agent an untyped
11
+ * Task spawns, so naming it would only add noise. */
12
+ export declare function agentTypeLabel(t: string): string;
13
+ /** The first line when the model wrote it as a heading ("# Title" or
14
+ * "**Title**"), the way reasoning summaries open, so a folded thought says
15
+ * what it was about. Prose gets no label of its own. */
16
+ export declare function thinkingHeading(raw: string): string;
17
+ /** How a turn cut short reads, whether replayed or watched live. */
18
+ export declare const INTERRUPTED_NOTICE: string;
19
+ /** The line the daemon files as the assistant's when a turn is cut short;
20
+ * it is a status, not something the model said. */
21
+ export declare function interruptionNotice(text: string): string | null;
22
+ export declare function firstNonEmptyLine(text: string, max: number): string;
23
+ export interface SubagentNotice {
24
+ id: string;
25
+ description: string;
26
+ preview: string;
27
+ /** The report itself, without the closing line addressed to the model. */
28
+ body: string;
29
+ interim: boolean;
30
+ /** The interrupted form is written for the model alone; the child's own
31
+ * block already reads interrupted, so no line is drawn for it. */
32
+ silent: boolean;
33
+ }
34
+ /** Reads a "[Background subagent <id> (<desc>) completed]" header; null for
35
+ * any other notice, which keeps its full text. */
36
+ export declare function parseSubagentNotice(text: string): SubagentNotice | null;
37
+ /** The line that marks a child's report entering the main conversation. */
38
+ export declare function subagentDeliveryLine(n: SubagentNotice): string;
@@ -0,0 +1,127 @@
1
+ import { clip, sanitizeLabel } from "./toolfmt.js";
2
+ //#region src/ai/agent/transcript.ts
3
+ var HIDDEN_TRANSCRIPT_TOOLS = /* @__PURE__ */ new Set([
4
+ "AskUserQuestion",
5
+ "TodoWrite",
6
+ "ExitPlanMode"
7
+ ]);
8
+ function hiddenTranscriptTool(name) {
9
+ return HIDDEN_TRANSCRIPT_TOOLS.has(name);
10
+ }
11
+ function parseArgs(argsJSON) {
12
+ try {
13
+ const parsed = JSON.parse(argsJSON);
14
+ return parsed && typeof parsed === "object" ? parsed : {};
15
+ } catch {
16
+ return {};
17
+ }
18
+ }
19
+ function str(v) {
20
+ return typeof v === "string" ? v : "";
21
+ }
22
+ function askQuestionFromArgs(argsJSON) {
23
+ return str(parseArgs(argsJSON)["question"]);
24
+ }
25
+ function planFromArgs(argsJSON) {
26
+ return str(parseArgs(argsJSON)["plan"]);
27
+ }
28
+ /** A Task call's display label the way the tool itself picks it: the
29
+ * description, else the clipped prompt, plus its custom agent type. */
30
+ function taskCallFromArgs(argsJSON) {
31
+ const a = parseArgs(argsJSON);
32
+ const description = str(a["description"]) || clip(str(a["prompt"]), 40);
33
+ return {
34
+ description: sanitizeLabel(description),
35
+ agentType: agentTypeLabel(str(a["subagent_type"]))
36
+ };
37
+ }
38
+ /** The built-in "default" type is the same general-purpose agent an untyped
39
+ * Task spawns, so naming it would only add noise. */
40
+ function agentTypeLabel(t) {
41
+ return t === "default" ? "" : sanitizeLabel(t);
42
+ }
43
+ /** The first line when the model wrote it as a heading ("# Title" or
44
+ * "**Title**"), the way reasoning summaries open, so a folded thought says
45
+ * what it was about. Prose gets no label of its own. */
46
+ function thinkingHeading(raw) {
47
+ const first = raw.trim().split("\n")[0]?.trim() ?? "";
48
+ let line;
49
+ if (first.startsWith("#")) line = first.replace(/^#+/, "").trim();
50
+ else if (first.length > 4 && first.startsWith("**") && first.endsWith("**")) line = first.slice(2, -2).trim();
51
+ else return "";
52
+ return clip(sanitizeLabel(line), 60);
53
+ }
54
+ var INTERRUPTED_MARKER = "[Request interrupted by the user.]";
55
+ /** How a turn cut short reads, whether replayed or watched live. */
56
+ var INTERRUPTED_NOTICE = INTERRUPTED_MARKER.slice(1, -1);
57
+ /** The line the daemon files as the assistant's when a turn is cut short;
58
+ * it is a status, not something the model said. */
59
+ function interruptionNotice(text) {
60
+ return text.trim() === INTERRUPTED_MARKER ? INTERRUPTED_NOTICE : null;
61
+ }
62
+ function firstNonEmptyLine(text, max) {
63
+ for (const line of text.split("\n")) {
64
+ const s = line.trim();
65
+ if (s !== "") return clip(s, max);
66
+ }
67
+ return "";
68
+ }
69
+ var SUBAGENT_NOTICE_HEADS = /* @__PURE__ */ new Set(["Background subagent", "Message from subagent"]);
70
+ /** Reads a "[Background subagent <id> (<desc>) completed]" header; null for
71
+ * any other notice, which keeps its full text. */
72
+ function parseSubagentNotice(text) {
73
+ const trimmed = text.trim();
74
+ const nl = trimmed.indexOf("\n");
75
+ let head = nl === -1 ? trimmed : trimmed.slice(0, nl);
76
+ let body = nl === -1 ? "" : trimmed.slice(nl + 1);
77
+ if (!head.startsWith("[") || !head.endsWith("]")) return null;
78
+ head = head.slice(1, -1);
79
+ let shell = false;
80
+ let kind;
81
+ let rest;
82
+ const sub = head.indexOf(" subagent ");
83
+ if (sub !== -1 && SUBAGENT_NOTICE_HEADS.has(`${head.slice(0, sub)} subagent`)) {
84
+ kind = head.slice(0, sub);
85
+ rest = head.slice(sub + 10);
86
+ } else {
87
+ const cmd = head.indexOf(" command ");
88
+ if (cmd === -1 || head.slice(0, cmd) !== "Background") return null;
89
+ kind = "Background";
90
+ rest = head.slice(cmd + 9);
91
+ shell = true;
92
+ }
93
+ const open = rest.indexOf(" (");
94
+ if (open === -1) return null;
95
+ const id = rest.slice(0, open);
96
+ rest = rest.slice(open + 2);
97
+ const end = rest.lastIndexOf(")");
98
+ if (end === -1) return null;
99
+ const tail = rest.slice(end + 1);
100
+ const notice = {
101
+ id,
102
+ description: rest.slice(0, end),
103
+ interim: kind === "Message from",
104
+ silent: tail.includes("was interrupted"),
105
+ preview: "",
106
+ body: ""
107
+ };
108
+ if (shell) {
109
+ notice.preview = tail.trim();
110
+ return notice;
111
+ }
112
+ const lines = body.split("\n");
113
+ const last = lines[lines.length - 1] ?? "";
114
+ if (lines.length > 0 && last.trim().startsWith("(pass ")) body = lines.slice(0, -1).join("\n");
115
+ notice.body = body.trim();
116
+ notice.preview = firstNonEmptyLine(body, 70);
117
+ return notice;
118
+ }
119
+ /** The line that marks a child's report entering the main conversation. */
120
+ function subagentDeliveryLine(n) {
121
+ const name = n.description ? `${n.id} (${n.description})` : n.id;
122
+ let label = n.interim ? `↳ message from ${name}` : `↳ ${name} reported back`;
123
+ if (n.preview) label += `: ${sanitizeLabel(n.preview)}`;
124
+ return label;
125
+ }
126
+ //#endregion
127
+ export { INTERRUPTED_NOTICE, agentTypeLabel, askQuestionFromArgs, firstNonEmptyLine, hiddenTranscriptTool, interruptionNotice, parseSubagentNotice, planFromArgs, subagentDeliveryLine, taskCallFromArgs, thinkingHeading };