@stigmer/react 0.5.0 → 1.0.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 (691) hide show
  1. package/activity/group-activity.d.ts +13 -0
  2. package/activity/group-activity.d.ts.map +1 -0
  3. package/activity/group-activity.js +54 -0
  4. package/activity/group-activity.js.map +1 -0
  5. package/activity/index.d.ts +4 -0
  6. package/activity/index.d.ts.map +1 -0
  7. package/activity/index.js +3 -0
  8. package/activity/index.js.map +1 -0
  9. package/activity/types.d.ts +34 -0
  10. package/activity/types.d.ts.map +1 -0
  11. package/activity/types.js +2 -0
  12. package/activity/types.js.map +1 -0
  13. package/activity/useRecentActivity.d.ts +35 -0
  14. package/activity/useRecentActivity.d.ts.map +1 -0
  15. package/activity/useRecentActivity.js +73 -0
  16. package/activity/useRecentActivity.js.map +1 -0
  17. package/agent/AgentPicker.d.ts.map +1 -1
  18. package/agent/AgentPicker.js +4 -2
  19. package/agent/AgentPicker.js.map +1 -1
  20. package/billing/BillingSection.d.ts.map +1 -1
  21. package/billing/BillingSection.js +1 -1
  22. package/billing/BillingSection.js.map +1 -1
  23. package/composer/ComposerToolbar.d.ts +5 -1
  24. package/composer/ComposerToolbar.d.ts.map +1 -1
  25. package/composer/ComposerToolbar.js +4 -3
  26. package/composer/ComposerToolbar.js.map +1 -1
  27. package/composer/ContextChip.d.ts +7 -2
  28. package/composer/ContextChip.d.ts.map +1 -1
  29. package/composer/ContextChip.js +2 -1
  30. package/composer/ContextChip.js.map +1 -1
  31. package/composer/InteractionModePicker.d.ts +40 -0
  32. package/composer/InteractionModePicker.d.ts.map +1 -0
  33. package/composer/InteractionModePicker.js +76 -0
  34. package/composer/InteractionModePicker.js.map +1 -0
  35. package/composer/SessionComposer.d.ts +64 -64
  36. package/composer/SessionComposer.d.ts.map +1 -1
  37. package/composer/SessionComposer.js +52 -11
  38. package/composer/SessionComposer.js.map +1 -1
  39. package/composer/__tests__/SessionComposer-memo.test.js +10 -5
  40. package/composer/__tests__/SessionComposer-memo.test.js.map +1 -1
  41. package/composer/index.d.ts +3 -1
  42. package/composer/index.d.ts.map +1 -1
  43. package/composer/index.js +1 -0
  44. package/composer/index.js.map +1 -1
  45. package/dashboard/DashboardFailedRuns.d.ts +19 -0
  46. package/dashboard/DashboardFailedRuns.d.ts.map +1 -0
  47. package/dashboard/DashboardFailedRuns.js +35 -0
  48. package/dashboard/DashboardFailedRuns.js.map +1 -0
  49. package/dashboard/DashboardKPICards.d.ts +19 -0
  50. package/dashboard/DashboardKPICards.d.ts.map +1 -0
  51. package/dashboard/DashboardKPICards.js +80 -0
  52. package/dashboard/DashboardKPICards.js.map +1 -0
  53. package/dashboard/OperationalDashboard.d.ts +37 -0
  54. package/dashboard/OperationalDashboard.d.ts.map +1 -0
  55. package/dashboard/OperationalDashboard.js +48 -0
  56. package/dashboard/OperationalDashboard.js.map +1 -0
  57. package/dashboard/index.d.ts +8 -0
  58. package/dashboard/index.d.ts.map +1 -0
  59. package/dashboard/index.js +9 -0
  60. package/dashboard/index.js.map +1 -0
  61. package/dashboard/types.d.ts +49 -0
  62. package/dashboard/types.d.ts.map +1 -0
  63. package/dashboard/types.js +2 -0
  64. package/dashboard/types.js.map +1 -0
  65. package/dashboard/useAgentExecutionSummary.d.ts +33 -0
  66. package/dashboard/useAgentExecutionSummary.d.ts.map +1 -0
  67. package/dashboard/useAgentExecutionSummary.js +32 -0
  68. package/dashboard/useAgentExecutionSummary.js.map +1 -0
  69. package/dashboard/useDashboardFailedRuns.d.ts +18 -0
  70. package/dashboard/useDashboardFailedRuns.d.ts.map +1 -0
  71. package/dashboard/useDashboardFailedRuns.js +86 -0
  72. package/dashboard/useDashboardFailedRuns.js.map +1 -0
  73. package/dashboard/useDashboardSummary.d.ts +32 -0
  74. package/dashboard/useDashboardSummary.d.ts.map +1 -0
  75. package/dashboard/useDashboardSummary.js +67 -0
  76. package/dashboard/useDashboardSummary.js.map +1 -0
  77. package/environment/usePersonalEnvironment.d.ts.map +1 -1
  78. package/environment/usePersonalEnvironment.js +1 -0
  79. package/environment/usePersonalEnvironment.js.map +1 -1
  80. package/execution/ContextGauge.d.ts +45 -0
  81. package/execution/ContextGauge.d.ts.map +1 -0
  82. package/execution/ContextGauge.js +82 -0
  83. package/execution/ContextGauge.js.map +1 -0
  84. package/execution/InteractionModeBadge.d.ts +24 -0
  85. package/execution/InteractionModeBadge.d.ts.map +1 -0
  86. package/execution/InteractionModeBadge.js +29 -0
  87. package/execution/InteractionModeBadge.js.map +1 -0
  88. package/execution/MessageThread.d.ts +33 -3
  89. package/execution/MessageThread.d.ts.map +1 -1
  90. package/execution/MessageThread.js +51 -9
  91. package/execution/MessageThread.js.map +1 -1
  92. package/execution/PlanCompletionCard.d.ts +23 -0
  93. package/execution/PlanCompletionCard.d.ts.map +1 -0
  94. package/execution/PlanCompletionCard.js +28 -0
  95. package/execution/PlanCompletionCard.js.map +1 -0
  96. package/execution/SummarizationBadge.d.ts +30 -0
  97. package/execution/SummarizationBadge.d.ts.map +1 -0
  98. package/execution/SummarizationBadge.js +61 -0
  99. package/execution/SummarizationBadge.js.map +1 -0
  100. package/execution/SummarizationCard.d.ts +27 -0
  101. package/execution/SummarizationCard.d.ts.map +1 -0
  102. package/execution/SummarizationCard.js +47 -0
  103. package/execution/SummarizationCard.js.map +1 -0
  104. package/execution/__tests__/PlanCompletionCard.test.d.ts +2 -0
  105. package/execution/__tests__/PlanCompletionCard.test.d.ts.map +1 -0
  106. package/execution/__tests__/PlanCompletionCard.test.js +53 -0
  107. package/execution/__tests__/PlanCompletionCard.test.js.map +1 -0
  108. package/execution/__tests__/buildThreadItems-plan-completion.test.d.ts +2 -0
  109. package/execution/__tests__/buildThreadItems-plan-completion.test.d.ts.map +1 -0
  110. package/execution/__tests__/buildThreadItems-plan-completion.test.js +137 -0
  111. package/execution/__tests__/buildThreadItems-plan-completion.test.js.map +1 -0
  112. package/execution/__tests__/useContextWindow.test.d.ts +2 -0
  113. package/execution/__tests__/useContextWindow.test.d.ts.map +1 -0
  114. package/execution/__tests__/useContextWindow.test.js +121 -0
  115. package/execution/__tests__/useContextWindow.test.js.map +1 -0
  116. package/execution/index.d.ts +12 -0
  117. package/execution/index.d.ts.map +1 -1
  118. package/execution/index.js +6 -0
  119. package/execution/index.js.map +1 -1
  120. package/execution/useContextWindow.d.ts +71 -0
  121. package/execution/useContextWindow.d.ts.map +1 -0
  122. package/execution/useContextWindow.js +91 -0
  123. package/execution/useContextWindow.js.map +1 -0
  124. package/execution/useCreateAgentExecution.d.ts +9 -0
  125. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  126. package/execution/useCreateAgentExecution.js +15 -3
  127. package/execution/useCreateAgentExecution.js.map +1 -1
  128. package/index.d.ts +11 -6
  129. package/index.d.ts.map +1 -1
  130. package/index.js +13 -3
  131. package/index.js.map +1 -1
  132. package/inline-edit/InlineEditKeyValue.d.ts +5 -1
  133. package/inline-edit/InlineEditKeyValue.d.ts.map +1 -1
  134. package/inline-edit/InlineEditKeyValue.js +3 -3
  135. package/inline-edit/InlineEditKeyValue.js.map +1 -1
  136. package/internal/VirtualizedThread.d.ts +2 -1
  137. package/internal/VirtualizedThread.d.ts.map +1 -1
  138. package/internal/VirtualizedThread.js +3 -2
  139. package/internal/VirtualizedThread.js.map +1 -1
  140. package/internal/store/index.d.ts +1 -0
  141. package/internal/store/index.d.ts.map +1 -1
  142. package/internal/store/index.js +1 -0
  143. package/internal/store/index.js.map +1 -1
  144. package/internal/store/workflow-execution-event-store.d.ts +92 -0
  145. package/internal/store/workflow-execution-event-store.d.ts.map +1 -0
  146. package/internal/store/workflow-execution-event-store.js +298 -0
  147. package/internal/store/workflow-execution-event-store.js.map +1 -0
  148. package/internal/useFetch.js +2 -2
  149. package/internal/useFetch.js.map +1 -1
  150. package/library/ScopeToggle.d.ts +13 -9
  151. package/library/ScopeToggle.d.ts.map +1 -1
  152. package/library/ScopeToggle.js +43 -22
  153. package/library/ScopeToggle.js.map +1 -1
  154. package/library/VisibilityToggle.js +14 -5
  155. package/library/VisibilityToggle.js.map +1 -1
  156. package/library/index.d.ts +1 -0
  157. package/library/index.d.ts.map +1 -1
  158. package/library/index.js +1 -0
  159. package/library/index.js.map +1 -1
  160. package/library/useExportResource.d.ts +3 -2
  161. package/library/useExportResource.d.ts.map +1 -1
  162. package/library/useExportResource.js +11 -6
  163. package/library/useExportResource.js.map +1 -1
  164. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  165. package/mcp-server/McpServerDetailView.js +169 -58
  166. package/mcp-server/McpServerDetailView.js.map +1 -1
  167. package/mcp-server/McpServerPicker.d.ts.map +1 -1
  168. package/mcp-server/McpServerPicker.js +4 -2
  169. package/mcp-server/McpServerPicker.js.map +1 -1
  170. package/models/ModelRegistryContext.d.ts +2 -0
  171. package/models/ModelRegistryContext.d.ts.map +1 -1
  172. package/models/ModelRegistryContext.js +1 -0
  173. package/models/ModelRegistryContext.js.map +1 -1
  174. package/models/ModelSelector.d.ts.map +1 -1
  175. package/models/ModelSelector.js +2 -2
  176. package/models/ModelSelector.js.map +1 -1
  177. package/models/__tests__/useModelRegistry.test.js +4 -3
  178. package/models/__tests__/useModelRegistry.test.js.map +1 -1
  179. package/models/useModelRegistry.d.ts +2 -0
  180. package/models/useModelRegistry.d.ts.map +1 -1
  181. package/models/useModelRegistry.js +3 -2
  182. package/models/useModelRegistry.js.map +1 -1
  183. package/package.json +16 -5
  184. package/provider.d.ts.map +1 -1
  185. package/provider.js +232 -22
  186. package/provider.js.map +1 -1
  187. package/resource-detail/ResourceDetailShell.d.ts +1 -1
  188. package/resource-detail/ResourceDetailShell.d.ts.map +1 -1
  189. package/resource-detail/ResourceDetailShell.js +6 -6
  190. package/resource-detail/ResourceDetailShell.js.map +1 -1
  191. package/resource-detail/types.d.ts +23 -0
  192. package/resource-detail/types.d.ts.map +1 -1
  193. package/resource-detail/useDeleteResource.d.ts +1 -1
  194. package/resource-detail/useDeleteResource.d.ts.map +1 -1
  195. package/resource-detail/useDeleteResource.js +5 -0
  196. package/resource-detail/useDeleteResource.js.map +1 -1
  197. package/resource-workbench/components/ResourceWorkbench.d.ts.map +1 -1
  198. package/resource-workbench/components/ResourceWorkbench.js +2 -1
  199. package/resource-workbench/components/ResourceWorkbench.js.map +1 -1
  200. package/session/__tests__/session-spec-converters.test.d.ts +2 -0
  201. package/session/__tests__/session-spec-converters.test.d.ts.map +1 -0
  202. package/session/__tests__/session-spec-converters.test.js +162 -0
  203. package/session/__tests__/session-spec-converters.test.js.map +1 -0
  204. package/session/__tests__/useNewSessionFlow.test.js +2 -2
  205. package/session/__tests__/useNewSessionFlow.test.js.map +1 -1
  206. package/session/__tests__/usePersistedModel.test.js +1 -1
  207. package/session/__tests__/usePersistedModel.test.js.map +1 -1
  208. package/session/group-sessions.d.ts +17 -0
  209. package/session/group-sessions.d.ts.map +1 -1
  210. package/session/group-sessions.js +46 -0
  211. package/session/group-sessions.js.map +1 -1
  212. package/session/index.d.ts +4 -2
  213. package/session/index.d.ts.map +1 -1
  214. package/session/index.js +2 -1
  215. package/session/index.js.map +1 -1
  216. package/session/session-spec-converters.d.ts +24 -0
  217. package/session/session-spec-converters.d.ts.map +1 -0
  218. package/session/session-spec-converters.js +72 -0
  219. package/session/session-spec-converters.js.map +1 -0
  220. package/session/useNewSessionFlow.d.ts.map +1 -1
  221. package/session/useNewSessionFlow.js +1 -0
  222. package/session/useNewSessionFlow.js.map +1 -1
  223. package/session/useSessionConversation.d.ts +7 -0
  224. package/session/useSessionConversation.d.ts.map +1 -1
  225. package/session/useSessionConversation.js +2 -56
  226. package/session/useSessionConversation.js.map +1 -1
  227. package/session/useSessionPageFlow.d.ts +5 -0
  228. package/session/useSessionPageFlow.d.ts.map +1 -1
  229. package/session/useSessionPageFlow.js +21 -6
  230. package/session/useSessionPageFlow.js.map +1 -1
  231. package/session/useSessionSearch.d.ts +57 -0
  232. package/session/useSessionSearch.d.ts.map +1 -0
  233. package/session/useSessionSearch.js +94 -0
  234. package/session/useSessionSearch.js.map +1 -0
  235. package/session/useSessionUsage.d.ts.map +1 -1
  236. package/session/useSessionUsage.js +65 -4
  237. package/session/useSessionUsage.js.map +1 -1
  238. package/settings/UsageSection.d.ts.map +1 -1
  239. package/settings/UsageSection.js +1 -4
  240. package/settings/UsageSection.js.map +1 -1
  241. package/skill/SkillPicker.d.ts.map +1 -1
  242. package/skill/SkillPicker.js +4 -2
  243. package/skill/SkillPicker.js.map +1 -1
  244. package/src/activity/group-activity.ts +65 -0
  245. package/src/activity/index.ts +13 -0
  246. package/src/activity/types.ts +35 -0
  247. package/src/activity/useRecentActivity.ts +131 -0
  248. package/src/agent/AgentPicker.tsx +6 -1
  249. package/src/billing/BillingSection.tsx +3 -2
  250. package/src/composer/ComposerToolbar.tsx +19 -1
  251. package/src/composer/ContextChip.tsx +20 -11
  252. package/src/composer/InteractionModePicker.tsx +189 -0
  253. package/src/composer/SessionComposer.tsx +137 -11
  254. package/src/composer/__tests__/SessionComposer-memo.test.ts +11 -6
  255. package/src/composer/index.ts +7 -0
  256. package/src/dashboard/DashboardFailedRuns.tsx +109 -0
  257. package/src/dashboard/DashboardKPICards.tsx +128 -0
  258. package/src/dashboard/OperationalDashboard.tsx +96 -0
  259. package/src/dashboard/index.ts +37 -0
  260. package/src/dashboard/types.ts +50 -0
  261. package/src/dashboard/useAgentExecutionSummary.ts +71 -0
  262. package/src/dashboard/useDashboardFailedRuns.ts +122 -0
  263. package/src/dashboard/useDashboardSummary.ts +109 -0
  264. package/src/environment/usePersonalEnvironment.ts +1 -0
  265. package/src/execution/ContextGauge.tsx +243 -0
  266. package/src/execution/InteractionModeBadge.tsx +70 -0
  267. package/src/execution/MessageThread.tsx +88 -3
  268. package/src/execution/PlanCompletionCard.tsx +105 -0
  269. package/src/execution/SummarizationBadge.tsx +188 -0
  270. package/src/execution/SummarizationCard.tsx +126 -0
  271. package/src/execution/__tests__/PlanCompletionCard.test.tsx +67 -0
  272. package/src/execution/__tests__/buildThreadItems-plan-completion.test.ts +197 -0
  273. package/src/execution/__tests__/useContextWindow.test.ts +167 -0
  274. package/src/execution/index.ts +22 -0
  275. package/src/execution/useContextWindow.ts +148 -0
  276. package/src/execution/useCreateAgentExecution.ts +26 -3
  277. package/src/index.ts +227 -0
  278. package/src/inline-edit/InlineEditKeyValue.tsx +23 -0
  279. package/src/internal/VirtualizedThread.tsx +4 -1
  280. package/src/internal/store/index.ts +6 -0
  281. package/src/internal/store/workflow-execution-event-store.ts +391 -0
  282. package/src/internal/useFetch.ts +2 -2
  283. package/src/library/ScopeToggle.tsx +88 -20
  284. package/src/library/VisibilityToggle.tsx +54 -13
  285. package/src/library/index.ts +2 -0
  286. package/src/library/useExportResource.ts +12 -9
  287. package/src/mcp-server/McpServerDetailView.tsx +509 -203
  288. package/src/mcp-server/McpServerPicker.tsx +6 -1
  289. package/src/models/ModelRegistryContext.ts +3 -0
  290. package/src/models/ModelSelector.tsx +25 -2
  291. package/src/models/__tests__/useModelRegistry.test.tsx +5 -3
  292. package/src/models/useModelRegistry.ts +5 -2
  293. package/src/provider.tsx +264 -26
  294. package/src/resource-detail/ResourceDetailShell.tsx +21 -4
  295. package/src/resource-detail/types.ts +25 -0
  296. package/src/resource-detail/useDeleteResource.ts +6 -1
  297. package/src/resource-workbench/components/ResourceWorkbench.tsx +4 -0
  298. package/src/session/__tests__/session-spec-converters.test.ts +185 -0
  299. package/src/session/__tests__/useNewSessionFlow.test.tsx +2 -2
  300. package/src/session/__tests__/usePersistedModel.test.tsx +1 -1
  301. package/src/session/group-sessions.ts +65 -0
  302. package/src/session/index.ts +8 -2
  303. package/src/session/session-spec-converters.ts +86 -0
  304. package/src/session/useNewSessionFlow.ts +1 -0
  305. package/src/session/useSessionConversation.ts +13 -64
  306. package/src/session/useSessionPageFlow.ts +29 -7
  307. package/src/session/useSessionSearch.ts +149 -0
  308. package/src/session/useSessionUsage.ts +72 -4
  309. package/src/settings/UsageSection.tsx +1 -9
  310. package/src/skill/SkillPicker.tsx +6 -1
  311. package/src/workflow/ApprovalFormBuilder.tsx +1017 -0
  312. package/src/workflow/BranchConditionBuilder.tsx +451 -0
  313. package/src/workflow/CanvasActionsContext.ts +12 -0
  314. package/src/workflow/CanvasContextMenu.tsx +364 -0
  315. package/src/workflow/CanvasTaskNode.tsx +372 -0
  316. package/src/workflow/CanvasTransitionEdge.tsx +122 -0
  317. package/src/workflow/CostByWorkflowChart.tsx +120 -0
  318. package/src/workflow/ExecutionSummaryWidget.tsx +194 -0
  319. package/src/workflow/ExecutionTrendChart.tsx +157 -0
  320. package/src/workflow/FailedRunsWidget.tsx +109 -0
  321. package/src/workflow/PendingApprovalsWidget.tsx +115 -0
  322. package/src/workflow/TaskConfigForm.tsx +618 -0
  323. package/src/workflow/TaskKindRegistryContext.ts +36 -0
  324. package/src/workflow/TaskPickerPopover.tsx +326 -0
  325. package/src/workflow/WorkflowArchitectDialog.tsx +505 -0
  326. package/src/workflow/WorkflowCanvasEditor.tsx +651 -0
  327. package/src/workflow/WorkflowCanvasInner.tsx +160 -0
  328. package/src/workflow/WorkflowDashboard.tsx +124 -0
  329. package/src/workflow/WorkflowDetailView.tsx +527 -0
  330. package/src/workflow/WorkflowEditorView.tsx +547 -0
  331. package/src/workflow/WorkflowExecutionApprovalCard.tsx +129 -0
  332. package/src/workflow/WorkflowExecutionArtifactPanel.tsx +112 -0
  333. package/src/workflow/WorkflowExecutionCostPanel.tsx +131 -0
  334. package/src/workflow/WorkflowExecutionHeader.tsx +194 -0
  335. package/src/workflow/WorkflowExecutionPhaseBadge.tsx +188 -0
  336. package/src/workflow/WorkflowExecutionTaskPanel.tsx +135 -0
  337. package/src/workflow/WorkflowExecutionTimeline.tsx +118 -0
  338. package/src/workflow/WorkflowExecutionTimelineEvent.tsx +488 -0
  339. package/src/workflow/WorkflowExecutionViewer.tsx +248 -0
  340. package/src/workflow/WorkflowInspectorPanel.tsx +568 -0
  341. package/src/workflow/WorkflowRefinePanel.tsx +411 -0
  342. package/src/workflow/WorkflowRepairCard.tsx +433 -0
  343. package/src/workflow/WorkflowRunDialog.tsx +220 -0
  344. package/src/workflow/WorkflowRunForm.tsx +245 -0
  345. package/src/workflow/WorkflowTaskList.tsx +177 -0
  346. package/src/workflow/WorkflowTaskPalette.tsx +248 -0
  347. package/src/workflow/WorkflowTopologyGraph.tsx +250 -0
  348. package/src/workflow/WorkflowYamlEditor.tsx +271 -0
  349. package/src/workflow/__tests__/starter-workflow-yaml.test.ts +57 -0
  350. package/src/workflow/canvas-constants.ts +87 -0
  351. package/src/workflow/canvas-icons.tsx +36 -0
  352. package/src/workflow/extract-workflow-yaml.ts +87 -0
  353. package/src/workflow/graph-commands.ts +675 -0
  354. package/src/workflow/index.ts +375 -0
  355. package/src/workflow/serialize-workflow-yaml.ts +546 -0
  356. package/src/workflow/starter-workflow-yaml.ts +29 -0
  357. package/src/workflow/types.ts +99 -0
  358. package/src/workflow/useCanvasKeyboardShortcuts.ts +134 -0
  359. package/src/workflow/useDiagnoseExecutionFlow.ts +378 -0
  360. package/src/workflow/useGraphHistory.ts +138 -0
  361. package/src/workflow/usePendingApprovals.ts +89 -0
  362. package/src/workflow/useRefineWorkflowFlow.ts +321 -0
  363. package/src/workflow/useResolveAgentExecutionSession.ts +57 -0
  364. package/src/workflow/useRunWorkflowFlow.ts +235 -0
  365. package/src/workflow/useTaskKindRegistry.ts +135 -0
  366. package/src/workflow/useWorkflow.ts +78 -0
  367. package/src/workflow/useWorkflowArchitectFlow.ts +303 -0
  368. package/src/workflow/useWorkflowCanvas.ts +882 -0
  369. package/src/workflow/useWorkflowCount.ts +66 -0
  370. package/src/workflow/useWorkflowDashboardSummary.ts +71 -0
  371. package/src/workflow/useWorkflowEditor.ts +106 -0
  372. package/src/workflow/useWorkflowExecution.ts +67 -0
  373. package/src/workflow/useWorkflowExecutionActions.ts +179 -0
  374. package/src/workflow/useWorkflowExecutionArtifacts.ts +57 -0
  375. package/src/workflow/useWorkflowExecutionEventLog.ts +111 -0
  376. package/src/workflow/useWorkflowExecutionEventStream.ts +244 -0
  377. package/src/workflow/useWorkflowExecutionList.ts +121 -0
  378. package/src/workflow/useWorkflowInstances.ts +62 -0
  379. package/src/workflow/useWorkflowList.ts +79 -0
  380. package/src/workflow/useWorkflowSave.ts +84 -0
  381. package/src/workflow/useWorkflowTopology.ts +229 -0
  382. package/src/workflow/useWorkflowValidation.ts +329 -0
  383. package/src/workflow/useWorkflowYaml.ts +49 -0
  384. package/src/workflow/workflow-graph-conversions.ts +796 -0
  385. package/src/workflow/workflow-graph-model.ts +83 -0
  386. package/src/workflow/workflow-yaml-diff.ts +132 -0
  387. package/styles.css +1 -1
  388. package/workflow/ApprovalFormBuilder.d.ts +24 -0
  389. package/workflow/ApprovalFormBuilder.d.ts.map +1 -0
  390. package/workflow/ApprovalFormBuilder.js +347 -0
  391. package/workflow/ApprovalFormBuilder.js.map +1 -0
  392. package/workflow/BranchConditionBuilder.d.ts +29 -0
  393. package/workflow/BranchConditionBuilder.d.ts.map +1 -0
  394. package/workflow/BranchConditionBuilder.js +170 -0
  395. package/workflow/BranchConditionBuilder.js.map +1 -0
  396. package/workflow/CanvasActionsContext.d.ts +8 -0
  397. package/workflow/CanvasActionsContext.d.ts.map +1 -0
  398. package/workflow/CanvasActionsContext.js +4 -0
  399. package/workflow/CanvasActionsContext.js.map +1 -0
  400. package/workflow/CanvasContextMenu.d.ts +59 -0
  401. package/workflow/CanvasContextMenu.d.ts.map +1 -0
  402. package/workflow/CanvasContextMenu.js +98 -0
  403. package/workflow/CanvasContextMenu.js.map +1 -0
  404. package/workflow/CanvasTaskNode.d.ts +21 -0
  405. package/workflow/CanvasTaskNode.d.ts.map +1 -0
  406. package/workflow/CanvasTaskNode.js +125 -0
  407. package/workflow/CanvasTaskNode.js.map +1 -0
  408. package/workflow/CanvasTransitionEdge.d.ts +24 -0
  409. package/workflow/CanvasTransitionEdge.d.ts.map +1 -0
  410. package/workflow/CanvasTransitionEdge.js +50 -0
  411. package/workflow/CanvasTransitionEdge.js.map +1 -0
  412. package/workflow/CostByWorkflowChart.d.ts +15 -0
  413. package/workflow/CostByWorkflowChart.d.ts.map +1 -0
  414. package/workflow/CostByWorkflowChart.js +45 -0
  415. package/workflow/CostByWorkflowChart.js.map +1 -0
  416. package/workflow/ExecutionSummaryWidget.d.ts +16 -0
  417. package/workflow/ExecutionSummaryWidget.d.ts.map +1 -0
  418. package/workflow/ExecutionSummaryWidget.js +93 -0
  419. package/workflow/ExecutionSummaryWidget.js.map +1 -0
  420. package/workflow/ExecutionTrendChart.d.ts +14 -0
  421. package/workflow/ExecutionTrendChart.d.ts.map +1 -0
  422. package/workflow/ExecutionTrendChart.js +67 -0
  423. package/workflow/ExecutionTrendChart.js.map +1 -0
  424. package/workflow/FailedRunsWidget.d.ts +19 -0
  425. package/workflow/FailedRunsWidget.d.ts.map +1 -0
  426. package/workflow/FailedRunsWidget.js +37 -0
  427. package/workflow/FailedRunsWidget.js.map +1 -0
  428. package/workflow/PendingApprovalsWidget.d.ts +19 -0
  429. package/workflow/PendingApprovalsWidget.d.ts.map +1 -0
  430. package/workflow/PendingApprovalsWidget.js +35 -0
  431. package/workflow/PendingApprovalsWidget.js.map +1 -0
  432. package/workflow/TaskConfigForm.d.ts +29 -0
  433. package/workflow/TaskConfigForm.d.ts.map +1 -0
  434. package/workflow/TaskConfigForm.js +230 -0
  435. package/workflow/TaskConfigForm.js.map +1 -0
  436. package/workflow/TaskKindRegistryContext.d.ts +24 -0
  437. package/workflow/TaskKindRegistryContext.d.ts.map +1 -0
  438. package/workflow/TaskKindRegistryContext.js +25 -0
  439. package/workflow/TaskKindRegistryContext.js.map +1 -0
  440. package/workflow/TaskPickerPopover.d.ts +33 -0
  441. package/workflow/TaskPickerPopover.d.ts.map +1 -0
  442. package/workflow/TaskPickerPopover.js +110 -0
  443. package/workflow/TaskPickerPopover.js.map +1 -0
  444. package/workflow/WorkflowArchitectDialog.d.ts +48 -0
  445. package/workflow/WorkflowArchitectDialog.d.ts.map +1 -0
  446. package/workflow/WorkflowArchitectDialog.js +129 -0
  447. package/workflow/WorkflowArchitectDialog.js.map +1 -0
  448. package/workflow/WorkflowCanvasEditor.d.ts +38 -0
  449. package/workflow/WorkflowCanvasEditor.d.ts.map +1 -0
  450. package/workflow/WorkflowCanvasEditor.js +287 -0
  451. package/workflow/WorkflowCanvasEditor.js.map +1 -0
  452. package/workflow/WorkflowCanvasInner.d.ts +32 -0
  453. package/workflow/WorkflowCanvasInner.d.ts.map +1 -0
  454. package/workflow/WorkflowCanvasInner.js +49 -0
  455. package/workflow/WorkflowCanvasInner.js.map +1 -0
  456. package/workflow/WorkflowDashboard.d.ts +35 -0
  457. package/workflow/WorkflowDashboard.d.ts.map +1 -0
  458. package/workflow/WorkflowDashboard.js +59 -0
  459. package/workflow/WorkflowDashboard.js.map +1 -0
  460. package/workflow/WorkflowDetailView.d.ts +63 -0
  461. package/workflow/WorkflowDetailView.d.ts.map +1 -0
  462. package/workflow/WorkflowDetailView.js +202 -0
  463. package/workflow/WorkflowDetailView.js.map +1 -0
  464. package/workflow/WorkflowEditorView.d.ts +43 -0
  465. package/workflow/WorkflowEditorView.d.ts.map +1 -0
  466. package/workflow/WorkflowEditorView.js +165 -0
  467. package/workflow/WorkflowEditorView.js.map +1 -0
  468. package/workflow/WorkflowExecutionApprovalCard.d.ts +27 -0
  469. package/workflow/WorkflowExecutionApprovalCard.d.ts.map +1 -0
  470. package/workflow/WorkflowExecutionApprovalCard.js +32 -0
  471. package/workflow/WorkflowExecutionApprovalCard.js.map +1 -0
  472. package/workflow/WorkflowExecutionArtifactPanel.d.ts +15 -0
  473. package/workflow/WorkflowExecutionArtifactPanel.d.ts.map +1 -0
  474. package/workflow/WorkflowExecutionArtifactPanel.js +53 -0
  475. package/workflow/WorkflowExecutionArtifactPanel.js.map +1 -0
  476. package/workflow/WorkflowExecutionCostPanel.d.ts +18 -0
  477. package/workflow/WorkflowExecutionCostPanel.d.ts.map +1 -0
  478. package/workflow/WorkflowExecutionCostPanel.js +44 -0
  479. package/workflow/WorkflowExecutionCostPanel.js.map +1 -0
  480. package/workflow/WorkflowExecutionHeader.d.ts +26 -0
  481. package/workflow/WorkflowExecutionHeader.d.ts.map +1 -0
  482. package/workflow/WorkflowExecutionHeader.js +68 -0
  483. package/workflow/WorkflowExecutionHeader.js.map +1 -0
  484. package/workflow/WorkflowExecutionPhaseBadge.d.ts +23 -0
  485. package/workflow/WorkflowExecutionPhaseBadge.d.ts.map +1 -0
  486. package/workflow/WorkflowExecutionPhaseBadge.js +99 -0
  487. package/workflow/WorkflowExecutionPhaseBadge.js.map +1 -0
  488. package/workflow/WorkflowExecutionTaskPanel.d.ts +24 -0
  489. package/workflow/WorkflowExecutionTaskPanel.d.ts.map +1 -0
  490. package/workflow/WorkflowExecutionTaskPanel.js +59 -0
  491. package/workflow/WorkflowExecutionTaskPanel.js.map +1 -0
  492. package/workflow/WorkflowExecutionTimeline.d.ts +27 -0
  493. package/workflow/WorkflowExecutionTimeline.d.ts.map +1 -0
  494. package/workflow/WorkflowExecutionTimeline.js +51 -0
  495. package/workflow/WorkflowExecutionTimeline.js.map +1 -0
  496. package/workflow/WorkflowExecutionTimelineEvent.d.ts +18 -0
  497. package/workflow/WorkflowExecutionTimelineEvent.d.ts.map +1 -0
  498. package/workflow/WorkflowExecutionTimelineEvent.js +210 -0
  499. package/workflow/WorkflowExecutionTimelineEvent.js.map +1 -0
  500. package/workflow/WorkflowExecutionViewer.d.ts +45 -0
  501. package/workflow/WorkflowExecutionViewer.d.ts.map +1 -0
  502. package/workflow/WorkflowExecutionViewer.js +75 -0
  503. package/workflow/WorkflowExecutionViewer.js.map +1 -0
  504. package/workflow/WorkflowInspectorPanel.d.ts +46 -0
  505. package/workflow/WorkflowInspectorPanel.d.ts.map +1 -0
  506. package/workflow/WorkflowInspectorPanel.js +152 -0
  507. package/workflow/WorkflowInspectorPanel.js.map +1 -0
  508. package/workflow/WorkflowRefinePanel.d.ts +30 -0
  509. package/workflow/WorkflowRefinePanel.d.ts.map +1 -0
  510. package/workflow/WorkflowRefinePanel.js +107 -0
  511. package/workflow/WorkflowRefinePanel.js.map +1 -0
  512. package/workflow/WorkflowRepairCard.d.ts +35 -0
  513. package/workflow/WorkflowRepairCard.d.ts.map +1 -0
  514. package/workflow/WorkflowRepairCard.js +113 -0
  515. package/workflow/WorkflowRepairCard.js.map +1 -0
  516. package/workflow/WorkflowRunDialog.d.ts +51 -0
  517. package/workflow/WorkflowRunDialog.d.ts.map +1 -0
  518. package/workflow/WorkflowRunDialog.js +75 -0
  519. package/workflow/WorkflowRunDialog.js.map +1 -0
  520. package/workflow/WorkflowRunForm.d.ts +62 -0
  521. package/workflow/WorkflowRunForm.d.ts.map +1 -0
  522. package/workflow/WorkflowRunForm.js +64 -0
  523. package/workflow/WorkflowRunForm.js.map +1 -0
  524. package/workflow/WorkflowTaskList.d.ts +25 -0
  525. package/workflow/WorkflowTaskList.d.ts.map +1 -0
  526. package/workflow/WorkflowTaskList.js +89 -0
  527. package/workflow/WorkflowTaskList.js.map +1 -0
  528. package/workflow/WorkflowTaskPalette.d.ts +22 -0
  529. package/workflow/WorkflowTaskPalette.d.ts.map +1 -0
  530. package/workflow/WorkflowTaskPalette.js +83 -0
  531. package/workflow/WorkflowTaskPalette.js.map +1 -0
  532. package/workflow/WorkflowTopologyGraph.d.ts +22 -0
  533. package/workflow/WorkflowTopologyGraph.d.ts.map +1 -0
  534. package/workflow/WorkflowTopologyGraph.js +123 -0
  535. package/workflow/WorkflowTopologyGraph.js.map +1 -0
  536. package/workflow/WorkflowYamlEditor.d.ts +43 -0
  537. package/workflow/WorkflowYamlEditor.d.ts.map +1 -0
  538. package/workflow/WorkflowYamlEditor.js +215 -0
  539. package/workflow/WorkflowYamlEditor.js.map +1 -0
  540. package/workflow/__tests__/starter-workflow-yaml.test.d.ts +2 -0
  541. package/workflow/__tests__/starter-workflow-yaml.test.d.ts.map +1 -0
  542. package/workflow/__tests__/starter-workflow-yaml.test.js +44 -0
  543. package/workflow/__tests__/starter-workflow-yaml.test.js.map +1 -0
  544. package/workflow/canvas-constants.d.ts +56 -0
  545. package/workflow/canvas-constants.d.ts.map +1 -0
  546. package/workflow/canvas-constants.js +74 -0
  547. package/workflow/canvas-constants.js.map +1 -0
  548. package/workflow/canvas-icons.d.ts +13 -0
  549. package/workflow/canvas-icons.d.ts.map +1 -0
  550. package/workflow/canvas-icons.js +21 -0
  551. package/workflow/canvas-icons.js.map +1 -0
  552. package/workflow/extract-workflow-yaml.d.ts +22 -0
  553. package/workflow/extract-workflow-yaml.d.ts.map +1 -0
  554. package/workflow/extract-workflow-yaml.js +63 -0
  555. package/workflow/extract-workflow-yaml.js.map +1 -0
  556. package/workflow/graph-commands.d.ts +209 -0
  557. package/workflow/graph-commands.d.ts.map +1 -0
  558. package/workflow/graph-commands.js +516 -0
  559. package/workflow/graph-commands.js.map +1 -0
  560. package/workflow/index.d.ts +66 -0
  561. package/workflow/index.d.ts.map +1 -0
  562. package/workflow/index.js +88 -0
  563. package/workflow/index.js.map +1 -0
  564. package/workflow/serialize-workflow-yaml.d.ts +39 -0
  565. package/workflow/serialize-workflow-yaml.d.ts.map +1 -0
  566. package/workflow/serialize-workflow-yaml.js +413 -0
  567. package/workflow/serialize-workflow-yaml.js.map +1 -0
  568. package/workflow/starter-workflow-yaml.d.ts +12 -0
  569. package/workflow/starter-workflow-yaml.d.ts.map +1 -0
  570. package/workflow/starter-workflow-yaml.js +30 -0
  571. package/workflow/starter-workflow-yaml.js.map +1 -0
  572. package/workflow/types.d.ts +80 -0
  573. package/workflow/types.d.ts.map +1 -0
  574. package/workflow/types.js +2 -0
  575. package/workflow/types.js.map +1 -0
  576. package/workflow/useCanvasKeyboardShortcuts.d.ts +34 -0
  577. package/workflow/useCanvasKeyboardShortcuts.d.ts.map +1 -0
  578. package/workflow/useCanvasKeyboardShortcuts.js +108 -0
  579. package/workflow/useCanvasKeyboardShortcuts.js.map +1 -0
  580. package/workflow/useDiagnoseExecutionFlow.d.ts +87 -0
  581. package/workflow/useDiagnoseExecutionFlow.d.ts.map +1 -0
  582. package/workflow/useDiagnoseExecutionFlow.js +257 -0
  583. package/workflow/useDiagnoseExecutionFlow.js.map +1 -0
  584. package/workflow/useGraphHistory.d.ts +28 -0
  585. package/workflow/useGraphHistory.d.ts.map +1 -0
  586. package/workflow/useGraphHistory.js +106 -0
  587. package/workflow/useGraphHistory.js.map +1 -0
  588. package/workflow/usePendingApprovals.d.ts +35 -0
  589. package/workflow/usePendingApprovals.d.ts.map +1 -0
  590. package/workflow/usePendingApprovals.js +50 -0
  591. package/workflow/usePendingApprovals.js.map +1 -0
  592. package/workflow/useRefineWorkflowFlow.d.ts +75 -0
  593. package/workflow/useRefineWorkflowFlow.d.ts.map +1 -0
  594. package/workflow/useRefineWorkflowFlow.js +216 -0
  595. package/workflow/useRefineWorkflowFlow.js.map +1 -0
  596. package/workflow/useResolveAgentExecutionSession.d.ts +33 -0
  597. package/workflow/useResolveAgentExecutionSession.d.ts.map +1 -0
  598. package/workflow/useResolveAgentExecutionSession.js +37 -0
  599. package/workflow/useResolveAgentExecutionSession.js.map +1 -0
  600. package/workflow/useRunWorkflowFlow.d.ts +82 -0
  601. package/workflow/useRunWorkflowFlow.d.ts.map +1 -0
  602. package/workflow/useRunWorkflowFlow.js +145 -0
  603. package/workflow/useRunWorkflowFlow.js.map +1 -0
  604. package/workflow/useTaskKindRegistry.d.ts +96 -0
  605. package/workflow/useTaskKindRegistry.d.ts.map +1 -0
  606. package/workflow/useTaskKindRegistry.js +75 -0
  607. package/workflow/useTaskKindRegistry.js.map +1 -0
  608. package/workflow/useWorkflow.d.ts +47 -0
  609. package/workflow/useWorkflow.d.ts.map +1 -0
  610. package/workflow/useWorkflow.js +53 -0
  611. package/workflow/useWorkflow.js.map +1 -0
  612. package/workflow/useWorkflowArchitectFlow.d.ts +96 -0
  613. package/workflow/useWorkflowArchitectFlow.d.ts.map +1 -0
  614. package/workflow/useWorkflowArchitectFlow.js +179 -0
  615. package/workflow/useWorkflowArchitectFlow.js.map +1 -0
  616. package/workflow/useWorkflowCanvas.d.ts +66 -0
  617. package/workflow/useWorkflowCanvas.d.ts.map +1 -0
  618. package/workflow/useWorkflowCanvas.js +628 -0
  619. package/workflow/useWorkflowCanvas.js.map +1 -0
  620. package/workflow/useWorkflowCount.d.ts +47 -0
  621. package/workflow/useWorkflowCount.d.ts.map +1 -0
  622. package/workflow/useWorkflowCount.js +26 -0
  623. package/workflow/useWorkflowCount.js.map +1 -0
  624. package/workflow/useWorkflowDashboardSummary.d.ts +34 -0
  625. package/workflow/useWorkflowDashboardSummary.d.ts.map +1 -0
  626. package/workflow/useWorkflowDashboardSummary.js +33 -0
  627. package/workflow/useWorkflowDashboardSummary.js.map +1 -0
  628. package/workflow/useWorkflowEditor.d.ts +45 -0
  629. package/workflow/useWorkflowEditor.d.ts.map +1 -0
  630. package/workflow/useWorkflowEditor.js +52 -0
  631. package/workflow/useWorkflowEditor.js.map +1 -0
  632. package/workflow/useWorkflowExecution.d.ts +37 -0
  633. package/workflow/useWorkflowExecution.d.ts.map +1 -0
  634. package/workflow/useWorkflowExecution.js +43 -0
  635. package/workflow/useWorkflowExecution.js.map +1 -0
  636. package/workflow/useWorkflowExecutionActions.d.ts +41 -0
  637. package/workflow/useWorkflowExecutionActions.d.ts.map +1 -0
  638. package/workflow/useWorkflowExecutionActions.js +86 -0
  639. package/workflow/useWorkflowExecutionActions.js.map +1 -0
  640. package/workflow/useWorkflowExecutionArtifacts.d.ts +26 -0
  641. package/workflow/useWorkflowExecutionArtifacts.d.ts.map +1 -0
  642. package/workflow/useWorkflowExecutionArtifacts.js +29 -0
  643. package/workflow/useWorkflowExecutionArtifacts.js.map +1 -0
  644. package/workflow/useWorkflowExecutionEventLog.d.ts +47 -0
  645. package/workflow/useWorkflowExecutionEventLog.d.ts.map +1 -0
  646. package/workflow/useWorkflowExecutionEventLog.js +59 -0
  647. package/workflow/useWorkflowExecutionEventLog.js.map +1 -0
  648. package/workflow/useWorkflowExecutionEventStream.d.ts +61 -0
  649. package/workflow/useWorkflowExecutionEventStream.d.ts.map +1 -0
  650. package/workflow/useWorkflowExecutionEventStream.js +161 -0
  651. package/workflow/useWorkflowExecutionEventStream.js.map +1 -0
  652. package/workflow/useWorkflowExecutionList.d.ts +49 -0
  653. package/workflow/useWorkflowExecutionList.d.ts.map +1 -0
  654. package/workflow/useWorkflowExecutionList.js +65 -0
  655. package/workflow/useWorkflowExecutionList.js.map +1 -0
  656. package/workflow/useWorkflowInstances.d.ts +30 -0
  657. package/workflow/useWorkflowInstances.d.ts.map +1 -0
  658. package/workflow/useWorkflowInstances.js +33 -0
  659. package/workflow/useWorkflowInstances.js.map +1 -0
  660. package/workflow/useWorkflowList.d.ts +57 -0
  661. package/workflow/useWorkflowList.d.ts.map +1 -0
  662. package/workflow/useWorkflowList.js +29 -0
  663. package/workflow/useWorkflowList.js.map +1 -0
  664. package/workflow/useWorkflowSave.d.ts +25 -0
  665. package/workflow/useWorkflowSave.d.ts.map +1 -0
  666. package/workflow/useWorkflowSave.js +61 -0
  667. package/workflow/useWorkflowSave.js.map +1 -0
  668. package/workflow/useWorkflowTopology.d.ts +40 -0
  669. package/workflow/useWorkflowTopology.d.ts.map +1 -0
  670. package/workflow/useWorkflowTopology.js +163 -0
  671. package/workflow/useWorkflowTopology.js.map +1 -0
  672. package/workflow/useWorkflowValidation.d.ts +27 -0
  673. package/workflow/useWorkflowValidation.d.ts.map +1 -0
  674. package/workflow/useWorkflowValidation.js +253 -0
  675. package/workflow/useWorkflowValidation.js.map +1 -0
  676. package/workflow/useWorkflowYaml.d.ts +26 -0
  677. package/workflow/useWorkflowYaml.d.ts.map +1 -0
  678. package/workflow/useWorkflowYaml.js +26 -0
  679. package/workflow/useWorkflowYaml.js.map +1 -0
  680. package/workflow/workflow-graph-conversions.d.ts +70 -0
  681. package/workflow/workflow-graph-conversions.d.ts.map +1 -0
  682. package/workflow/workflow-graph-conversions.js +634 -0
  683. package/workflow/workflow-graph-conversions.js.map +1 -0
  684. package/workflow/workflow-graph-model.d.ts +83 -0
  685. package/workflow/workflow-graph-model.d.ts.map +1 -0
  686. package/workflow/workflow-graph-model.js +5 -0
  687. package/workflow/workflow-graph-model.js.map +1 -0
  688. package/workflow/workflow-yaml-diff.d.ts +24 -0
  689. package/workflow/workflow-yaml-diff.d.ts.map +1 -0
  690. package/workflow/workflow-yaml-diff.js +96 -0
  691. package/workflow/workflow-yaml-diff.js.map +1 -0
@@ -0,0 +1,189 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import { Popover } from "@base-ui/react/popover";
5
+ import { cn } from "@stigmer/theme";
6
+ import { useStigmerPortalContainer } from "../portal-container";
7
+
8
+ /**
9
+ * Interaction mode options for agent executions.
10
+ *
11
+ * Maps to `InteractionMode` proto enum values (excluding UNSPECIFIED):
12
+ * - `"agent"` → `INTERACTION_MODE_AGENT` (full tool access)
13
+ * - `"plan"` → `INTERACTION_MODE_PLAN` (read-only analysis)
14
+ */
15
+ export type InteractionModeOption = "agent" | "plan";
16
+
17
+ const OPTIONS: readonly InteractionModeOption[] = ["agent", "plan"];
18
+
19
+ const MODE_META: Record<
20
+ InteractionModeOption,
21
+ { label: string; description: string }
22
+ > = {
23
+ agent: {
24
+ label: "Agent",
25
+ description: "Full tool access — read, write, and execute",
26
+ },
27
+ plan: {
28
+ label: "Plan",
29
+ description: "Read-only analysis — search and reason only",
30
+ },
31
+ };
32
+
33
+ /** Props for {@link InteractionModePicker}. */
34
+ export interface InteractionModePickerProps {
35
+ /** Currently selected interaction mode. */
36
+ readonly value: InteractionModeOption;
37
+ /** Called when the user picks a different mode. */
38
+ readonly onValueChange: (mode: InteractionModeOption) => void;
39
+ /** Additional CSS class names for the trigger button. */
40
+ readonly className?: string;
41
+ /** When true, disables the picker. */
42
+ readonly disabled?: boolean;
43
+ }
44
+
45
+ /**
46
+ * Compact dropdown for choosing the execution interaction mode.
47
+ *
48
+ * Renders a trigger button showing the current mode label with a
49
+ * chevron, and a popover with the available options. Each option
50
+ * shows a label and a short description.
51
+ *
52
+ * Designed to scale to additional modes (e.g. Ask) without layout
53
+ * changes. Uses `@base-ui/react` Popover for positioning and portal
54
+ * rendering, matching the pattern used by {@link ModelSelector}.
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * function ComposerToolbar() {
59
+ * const [mode, setMode] = useState<InteractionModeOption>("agent");
60
+ * return <InteractionModePicker value={mode} onValueChange={setMode} />;
61
+ * }
62
+ * ```
63
+ */
64
+ export function InteractionModePicker({
65
+ value,
66
+ onValueChange,
67
+ className,
68
+ disabled,
69
+ }: InteractionModePickerProps) {
70
+ const portalContainer = useStigmerPortalContainer();
71
+ const [open, setOpen] = useState(false);
72
+
73
+ const select = useCallback(
74
+ (mode: InteractionModeOption) => {
75
+ onValueChange(mode);
76
+ setOpen(false);
77
+ },
78
+ [onValueChange],
79
+ );
80
+
81
+ const handleKeyDown = useCallback(
82
+ (e: React.KeyboardEvent) => {
83
+ const idx = OPTIONS.indexOf(value);
84
+ let next: number | undefined;
85
+
86
+ switch (e.key) {
87
+ case "ArrowDown":
88
+ e.preventDefault();
89
+ next = idx < OPTIONS.length - 1 ? idx + 1 : 0;
90
+ break;
91
+ case "ArrowUp":
92
+ e.preventDefault();
93
+ next = idx > 0 ? idx - 1 : OPTIONS.length - 1;
94
+ break;
95
+ case "Escape":
96
+ e.preventDefault();
97
+ setOpen(false);
98
+ return;
99
+ }
100
+
101
+ if (next !== undefined) {
102
+ select(OPTIONS[next]);
103
+ }
104
+ },
105
+ [value, select],
106
+ );
107
+
108
+ return (
109
+ <Popover.Root open={open} onOpenChange={setOpen}>
110
+ <Popover.Trigger
111
+ disabled={disabled}
112
+ className={cn(
113
+ "inline-flex items-center gap-1 rounded-md px-2 py-1.5 text-xs transition-colors",
114
+ "text-muted-foreground hover:text-foreground hover:bg-accent-hover",
115
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
116
+ "disabled:pointer-events-none disabled:opacity-50",
117
+ className,
118
+ )}
119
+ >
120
+ <span className="font-medium text-foreground">
121
+ {MODE_META[value].label}
122
+ </span>
123
+ <ChevronIcon />
124
+ </Popover.Trigger>
125
+
126
+ <Popover.Portal container={portalContainer}>
127
+ <Popover.Positioner sideOffset={4}>
128
+ <Popover.Popup
129
+ role="listbox"
130
+ aria-label="Interaction mode"
131
+ onKeyDown={handleKeyDown}
132
+ className={cn(
133
+ "z-50 w-56 rounded-lg border border-border bg-popover p-1 shadow-md",
134
+ "animate-in fade-in-0 zoom-in-95",
135
+ )}
136
+ >
137
+ {OPTIONS.map((option) => {
138
+ const meta = MODE_META[option];
139
+ const isActive = value === option;
140
+
141
+ return (
142
+ <button
143
+ key={option}
144
+ type="button"
145
+ role="option"
146
+ aria-selected={isActive}
147
+ onClick={() => select(option)}
148
+ className={cn(
149
+ "flex w-full flex-col gap-0.5 rounded-md px-2.5 py-2 text-left transition-colors",
150
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
151
+ isActive
152
+ ? "bg-accent text-foreground"
153
+ : "text-foreground hover:bg-accent-hover",
154
+ )}
155
+ >
156
+ <span className="text-xs font-medium">{meta.label}</span>
157
+ <span className="text-[0.65rem] leading-snug text-muted-foreground">
158
+ {meta.description}
159
+ </span>
160
+ </button>
161
+ );
162
+ })}
163
+ </Popover.Popup>
164
+ </Popover.Positioner>
165
+ </Popover.Portal>
166
+ </Popover.Root>
167
+ );
168
+ }
169
+
170
+ function ChevronIcon() {
171
+ return (
172
+ <svg
173
+ width="12"
174
+ height="12"
175
+ viewBox="0 0 12 12"
176
+ fill="none"
177
+ className="shrink-0 text-muted-foreground"
178
+ aria-hidden="true"
179
+ >
180
+ <path
181
+ d="M3 4.5L6 7.5L9 4.5"
182
+ stroke="currentColor"
183
+ strokeWidth="1.5"
184
+ strokeLinecap="round"
185
+ strokeLinejoin="round"
186
+ />
187
+ </svg>
188
+ );
189
+ }
@@ -1,12 +1,13 @@
1
1
  "use client";
2
2
 
3
- import { memo, useCallback, useEffect, useMemo, useRef, useState, type DragEvent, type KeyboardEvent } from "react";
3
+ import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, type DragEvent, type KeyboardEvent } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
5
  import { getUserMessage, type AttachmentInput, type EnvVarInput, type McpServerUsageInput, type ResourceRef } from "@stigmer/sdk";
6
6
  import { useComposer } from "./useComposer";
7
7
  import { ComposerToolbar } from "./ComposerToolbar";
8
8
  import { type ConfigureMenuItem } from "./ConfigureMenu";
9
9
  import type { HarnessOption } from "../models/harness";
10
+ import type { InteractionModeOption } from "./InteractionModePicker";
10
11
  import { parseModelKey } from "../models/registry";
11
12
  import { ContextChip, type ChipItem } from "./ContextChip";
12
13
  import { WorkspaceEditor } from "../workspace/WorkspaceEditor";
@@ -51,6 +52,33 @@ import {
51
52
  ResolveSpinner,
52
53
  } from "./icons";
53
54
 
55
+ /**
56
+ * Imperative handle exposed by {@link SessionComposer} via `ref`.
57
+ *
58
+ * Allows parent components to programmatically set the composer's
59
+ * message text and focus the textarea. Used for features like
60
+ * "Build from Plan" where a CTA outside the composer needs to
61
+ * pre-fill and focus the input.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * const composerRef = useRef<SessionComposerHandle>(null);
66
+ *
67
+ * function handleBuildFromPlan() {
68
+ * composerRef.current?.setMessage("Implement the plan above");
69
+ * composerRef.current?.focus();
70
+ * }
71
+ *
72
+ * <SessionComposer ref={composerRef} onSubmit={handleSubmit} />
73
+ * ```
74
+ */
75
+ export interface SessionComposerHandle {
76
+ /** Replace the composer's message text. */
77
+ setMessage(message: string): void;
78
+ /** Focus the composer's textarea. */
79
+ focus(): void;
80
+ }
81
+
54
82
  /**
55
83
  * Context provided to `onSubmit` at the moment of submission.
56
84
  *
@@ -83,6 +111,16 @@ export interface SessionComposerSubmitContext {
83
111
  * `undefined` when no files were attached.
84
112
  */
85
113
  readonly attachments?: AttachmentInput[];
114
+ /**
115
+ * Interaction mode selected by the user for this execution.
116
+ *
117
+ * - `"agent"` (default): full tool access — read, write, create, delete.
118
+ * - `"plan"`: read-only analysis — read, search, list only.
119
+ *
120
+ * `undefined` when no mode picker is shown (defaults to `"agent"`).
121
+ * Pass to execution creation as `execution_config.interaction_mode`.
122
+ */
123
+ readonly interactionMode?: InteractionModeOption;
86
124
  }
87
125
 
88
126
  /** Props for {@link SessionComposer}. */
@@ -120,6 +158,22 @@ export interface SessionComposerProps {
120
158
  /** Show the harness selector in the toolbar. @default false */
121
159
  readonly showHarnessSelector?: boolean;
122
160
 
161
+ /**
162
+ * Currently selected interaction mode.
163
+ *
164
+ * When `onInteractionModeChange` is provided, renders a mode picker
165
+ * in the toolbar. Defaults to `"agent"` when omitted.
166
+ */
167
+ readonly interactionMode?: InteractionModeOption;
168
+ /**
169
+ * Called when the user switches the interaction mode.
170
+ *
171
+ * Providing this callback enables the mode picker in the toolbar.
172
+ */
173
+ readonly onInteractionModeChange?: (mode: InteractionModeOption) => void;
174
+ /** Show the interaction mode picker in the toolbar. @default false */
175
+ readonly showInteractionModePicker?: boolean;
176
+
123
177
  /** Initial model ID for the model selector. */
124
178
  readonly defaultModelId?: string;
125
179
  /** Called when the user changes the selected model. */
@@ -203,6 +257,18 @@ export interface SessionComposerProps {
203
257
  */
204
258
  readonly initialAgentRef?: ResourceRef;
205
259
 
260
+ /**
261
+ * When `true`, the agent chip renders without an X (remove) button.
262
+ *
263
+ * Used on the session page to indicate the session's default agent,
264
+ * where removing it would just re-select the same agent (a
265
+ * confusing no-op). The user can still switch agents via the
266
+ * Configure menu.
267
+ *
268
+ * @default false
269
+ */
270
+ readonly isDefaultAgent?: boolean;
271
+
206
272
  /**
207
273
  * Currently selected MCP server usages.
208
274
  * When `onMcpServerUsagesChange` is provided, a MCP server trigger
@@ -372,13 +438,16 @@ export interface SessionComposerProps {
372
438
  * />
373
439
  * ```
374
440
  */
375
- export const SessionComposer = memo(function SessionComposer({
441
+ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerProps>(function SessionComposer({
376
442
  onSubmit,
377
443
  isSubmitting = false,
378
444
  disabled = false,
379
445
  harness,
380
446
  onHarnessChange,
381
447
  showHarnessSelector = false,
448
+ interactionMode,
449
+ onInteractionModeChange,
450
+ showInteractionModePicker = false,
382
451
  defaultModelId,
383
452
  onModelChange,
384
453
  showModelSelector = true,
@@ -392,6 +461,7 @@ export const SessionComposer = memo(function SessionComposer({
392
461
  onAgentRefChange,
393
462
  onAgentResolutionChange,
394
463
  initialAgentRef,
464
+ isDefaultAgent = false,
395
465
  mcpServerUsages,
396
466
  onMcpServerUsagesChange,
397
467
  skillRefs,
@@ -407,7 +477,7 @@ export const SessionComposer = memo(function SessionComposer({
407
477
  autoFocus = false,
408
478
  ariaLabel = "Send message",
409
479
  className,
410
- }: SessionComposerProps) {
480
+ }, ref) {
411
481
  useRenderTracer("SessionComposer", { disabled, isSubmitting });
412
482
 
413
483
  const [modelId, setModelIdRaw] = useState<string | undefined>(defaultModelId);
@@ -642,12 +712,17 @@ export const SessionComposer = memo(function SessionComposer({
642
712
  const hasEnv = Object.keys(env).length > 0;
643
713
  const hasAttachments =
644
714
  attachmentInputs !== undefined && attachmentInputs.length > 0;
715
+ const effectiveMode =
716
+ showInteractionModePicker && interactionMode
717
+ ? interactionMode
718
+ : undefined;
645
719
 
646
720
  const context: SessionComposerSubmitContext | undefined =
647
- hasEnv || hasAttachments
721
+ hasEnv || hasAttachments || effectiveMode
648
722
  ? {
649
723
  runtimeEnv: hasEnv ? env : undefined,
650
724
  attachments: hasAttachments ? attachmentInputs : undefined,
725
+ interactionMode: effectiveMode,
651
726
  }
652
727
  : undefined;
653
728
 
@@ -660,7 +735,7 @@ export const SessionComposer = memo(function SessionComposer({
660
735
  attachments.clear();
661
736
  }
662
737
  },
663
- [onSubmit, modelId, stigmer, agentSetup.state, mcpSetup.pendingRuntimeEnv, sessionVariables, enableAttachments, attachments, personalEnv],
738
+ [onSubmit, modelId, stigmer, agentSetup.state, mcpSetup.pendingRuntimeEnv, sessionVariables, enableAttachments, attachments, personalEnv, showInteractionModePicker, interactionMode],
664
739
  );
665
740
 
666
741
  const composer = useComposer({
@@ -668,6 +743,11 @@ export const SessionComposer = memo(function SessionComposer({
668
743
  disabled: isDisabled,
669
744
  });
670
745
 
746
+ useImperativeHandle(ref, () => ({
747
+ setMessage: composer.setMessage,
748
+ focus: () => composer.textareaRef.current?.focus(),
749
+ }), [composer.setMessage, composer.textareaRef]);
750
+
671
751
  const handleModelChange = useCallback(
672
752
  (id: string) => {
673
753
  setModelId(id);
@@ -683,6 +763,13 @@ export const SessionComposer = memo(function SessionComposer({
683
763
  [onHarnessChange],
684
764
  );
685
765
 
766
+ const handleInteractionModeChange = useCallback(
767
+ (mode: InteractionModeOption) => {
768
+ onInteractionModeChange?.(mode);
769
+ },
770
+ [onInteractionModeChange],
771
+ );
772
+
686
773
  const handleDisplayNameResolved = useCallback(
687
774
  (key: string, name: string) => {
688
775
  setDisplayNames((prev) => {
@@ -868,14 +955,49 @@ export const SessionComposer = memo(function SessionComposer({
868
955
  }
869
956
  }, [initialAttachments, enableAttachments, attachments]);
870
957
 
958
+ // ---------------------------------------------------------------------------
959
+ // Initial MCP: seed useMcpServerSetup from mcpServerUsages prop on mount
960
+ // ---------------------------------------------------------------------------
961
+
962
+ const initialMcpSeeded = useRef(false);
963
+ const mcpSetupAddServerRef = useRef(mcpSetup.addServer);
964
+ mcpSetupAddServerRef.current = mcpSetup.addServer;
965
+ const mcpSetupSetEnabledToolsRef = useRef(mcpSetup.setEnabledTools);
966
+ mcpSetupSetEnabledToolsRef.current = mcpSetup.setEnabledTools;
967
+
968
+ useEffect(() => {
969
+ if (!showMcp || initialMcpSeeded.current || !mcpServerUsages?.length) return;
970
+ initialMcpSeeded.current = true;
971
+
972
+ for (const usage of mcpServerUsages) {
973
+ const ref = usage.mcpServerRef;
974
+ if (!ref) continue;
975
+ const savedTools = usage.enabledTools;
976
+
977
+ mcpSetupAddServerRef.current(ref).then(() => {
978
+ if (savedTools?.length) {
979
+ mcpSetupSetEnabledToolsRef.current(ref, savedTools);
980
+ }
981
+ }).catch(() => {
982
+ // Non-fatal: server may have been deleted or become inaccessible.
983
+ // The user can re-add it via the MCP picker.
984
+ });
985
+ }
986
+ }, [showMcp, mcpServerUsages]);
987
+
871
988
  // ---------------------------------------------------------------------------
872
989
  // MCP server setup: sync usageInputs to consumer
873
990
  // ---------------------------------------------------------------------------
874
991
 
992
+ const hasLoadingMcpEntries = useMemo(
993
+ () => Object.values(mcpSetup.entries).some(e => e.status === "loading"),
994
+ [mcpSetup.entries],
995
+ );
996
+
875
997
  useEffect(() => {
876
- if (!showMcp) return;
998
+ if (!showMcp || hasLoadingMcpEntries) return;
877
999
  onMcpServerUsagesChange?.(mcpSetup.usageInputs);
878
- }, [showMcp, mcpSetup.usageInputs, onMcpServerUsagesChange]);
1000
+ }, [showMcp, mcpSetup.usageInputs, onMcpServerUsagesChange, hasLoadingMcpEntries]);
879
1001
 
880
1002
  // ---------------------------------------------------------------------------
881
1003
  // Submission blocking: MCP servers must be fully configured before send
@@ -908,7 +1030,7 @@ export const SessionComposer = memo(function SessionComposer({
908
1030
  key: `agent:${refStr}`,
909
1031
  label: displayNames.get(refStr) ?? agentRef.slug,
910
1032
  type: "agent",
911
- onRemove: handleAgentChipRemove,
1033
+ onRemove: isDefaultAgent ? undefined : handleAgentChipRemove,
912
1034
  });
913
1035
  } else if (
914
1036
  agentSetup.state.status === "needsEnvVars" ||
@@ -1012,6 +1134,7 @@ export const SessionComposer = memo(function SessionComposer({
1012
1134
  return items;
1013
1135
  }, [
1014
1136
  agentRef,
1137
+ isDefaultAgent,
1015
1138
  agentSetup.state,
1016
1139
  handleAgentChipRemove,
1017
1140
  handlePendingAgentChipRemove,
@@ -1148,7 +1271,6 @@ export const SessionComposer = memo(function SessionComposer({
1148
1271
  <div className="relative">
1149
1272
  <AgentPicker
1150
1273
  org={org!}
1151
- scope="all"
1152
1274
  value={agentRef ?? null}
1153
1275
  onChange={handleAgentSelect}
1154
1276
  onDisplayNameResolved={handleDisplayNameResolved}
@@ -1169,7 +1291,6 @@ export const SessionComposer = memo(function SessionComposer({
1169
1291
  return (
1170
1292
  <McpServerPicker
1171
1293
  org={org!}
1172
- scope="all"
1173
1294
  setup={{
1174
1295
  entries: mcpSetup.entries,
1175
1296
  onServerAdded: (ref) => mcpSetup.addServer(ref),
@@ -1192,7 +1313,6 @@ export const SessionComposer = memo(function SessionComposer({
1192
1313
  return (
1193
1314
  <SkillPicker
1194
1315
  org={org!}
1195
- scope="all"
1196
1316
  value={skillRefs ?? []}
1197
1317
  onChange={onSkillRefsChange!}
1198
1318
  onDisplayNameResolved={handleDisplayNameResolved}
@@ -1429,6 +1549,9 @@ export const SessionComposer = memo(function SessionComposer({
1429
1549
  showHarnessSelector={showHarnessSelector}
1430
1550
  harness={harness}
1431
1551
  onHarnessChange={handleHarnessChange}
1552
+ showInteractionModePicker={showInteractionModePicker}
1553
+ interactionMode={interactionMode}
1554
+ onInteractionModeChange={handleInteractionModeChange}
1432
1555
  showModelSelector={showModelSelector}
1433
1556
  modelId={modelId}
1434
1557
  onModelChange={handleModelChange}
@@ -1438,6 +1561,9 @@ export const SessionComposer = memo(function SessionComposer({
1438
1561
  );
1439
1562
  });
1440
1563
 
1564
+ export const SessionComposer = memo(SessionComposerInner);
1565
+
1566
+
1441
1567
  // ---------------------------------------------------------------------------
1442
1568
  // Agent setup error — secret-flow guidance or generic fallback
1443
1569
  // ---------------------------------------------------------------------------
@@ -5,15 +5,20 @@ describe("SessionComposer — memo isolation", () => {
5
5
  it("is wrapped in React.memo (shallow prop comparison)", () => {
6
6
  // React.memo returns an exotic component with $$typeof set to
7
7
  // Symbol.for("react.memo") and a `type` field pointing at the
8
- // inner function. Regular function components have neither.
8
+ // inner component. For forwardRef components the inner type is an
9
+ // object (the forwardRef exotic), not a plain function.
9
10
  const memoSymbol = Symbol.for("react.memo");
10
- const typed = SessionComposer as unknown as { $$typeof: symbol; type: Function; compare: unknown };
11
+ const typed = SessionComposer as unknown as { $$typeof: symbol; type: unknown; compare: unknown };
11
12
 
12
13
  expect(typed.$$typeof).toBe(memoSymbol);
13
- expect(typeof typed.type).toBe("function");
14
- // The transform may rename the inner function to avoid shadowing
15
- // the outer `const SessionComposer` binding (e.g. "SessionComposer2").
16
- expect(typed.type.name).toMatch(/^SessionComposer/);
14
+ expect(typed.type).toBeTruthy();
15
+
16
+ const innerType = typed.type as { $$typeof?: symbol; render?: Function };
17
+ if (typeof typed.type === "function") {
18
+ expect((typed.type as Function).name).toMatch(/^SessionComposer/);
19
+ } else {
20
+ expect(innerType.$$typeof).toBe(Symbol.for("react.forward_ref"));
21
+ }
17
22
  });
18
23
 
19
24
  it("uses default shallow comparison (no custom areEqual)", () => {
@@ -3,6 +3,13 @@ export type { UseComposerOptions, UseComposerReturn } from "./useComposer";
3
3
 
4
4
  export { SessionComposer } from "./SessionComposer";
5
5
  export type {
6
+ SessionComposerHandle,
6
7
  SessionComposerProps,
7
8
  SessionComposerSubmitContext,
8
9
  } from "./SessionComposer";
10
+
11
+ export { InteractionModePicker } from "./InteractionModePicker";
12
+ export type {
13
+ InteractionModePickerProps,
14
+ InteractionModeOption,
15
+ } from "./InteractionModePicker";
@@ -0,0 +1,109 @@
1
+ "use client";
2
+
3
+ import { memo } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import type { DashboardFailedRun } from "./types";
6
+
7
+ export interface DashboardFailedRunsProps {
8
+ readonly failedRuns: readonly DashboardFailedRun[];
9
+ readonly isLoading: boolean;
10
+ /** Called when the user clicks "View" on a failed run. */
11
+ readonly onViewClick?: (id: string, type: DashboardFailedRun["type"]) => void;
12
+ readonly className?: string;
13
+ }
14
+
15
+ function timeAgo(date: Date): string {
16
+ const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
17
+ if (seconds < 60) return "just now";
18
+ const minutes = Math.floor(seconds / 60);
19
+ if (minutes < 60) return `${minutes}m ago`;
20
+ const hours = Math.floor(minutes / 60);
21
+ if (hours < 24) return `${hours}h ago`;
22
+ const days = Math.floor(hours / 24);
23
+ return `${days}d ago`;
24
+ }
25
+
26
+ /**
27
+ * Widget showing recent failed executions from both agent and workflow
28
+ * domains, interleaved by timestamp.
29
+ *
30
+ * Each row includes a type badge (Agent / Workflow), the execution name,
31
+ * a truncated error, and a relative timestamp.
32
+ *
33
+ * @since Unified Platform Dashboard
34
+ */
35
+ export const DashboardFailedRuns = memo(function DashboardFailedRuns({
36
+ failedRuns,
37
+ isLoading,
38
+ onViewClick,
39
+ className,
40
+ }: DashboardFailedRunsProps) {
41
+ if (isLoading) {
42
+ return (
43
+ <div
44
+ className={cn("rounded-lg border border-border bg-card p-4", className)}
45
+ aria-busy="true"
46
+ >
47
+ <div className="mb-3 h-4 w-32 animate-pulse rounded bg-muted" />
48
+ <div className="space-y-2">
49
+ {Array.from({ length: 3 }, (_, i) => (
50
+ <div key={i} className="h-10 animate-pulse rounded bg-muted/50" />
51
+ ))}
52
+ </div>
53
+ </div>
54
+ );
55
+ }
56
+
57
+ return (
58
+ <div className={cn("rounded-lg border border-border bg-card p-4", className)}>
59
+ <h3 className="mb-3 text-sm font-semibold text-foreground">
60
+ Recent Failures
61
+ </h3>
62
+ {failedRuns.length === 0 ? (
63
+ <p className="py-6 text-center text-xs text-muted-foreground">
64
+ No recent failures
65
+ </p>
66
+ ) : (
67
+ <ul className="space-y-1.5" role="list">
68
+ {failedRuns.map((run) => (
69
+ <li
70
+ key={run.id}
71
+ className="flex items-start gap-2 rounded-md px-2 py-1.5 text-xs hover:bg-muted/50"
72
+ >
73
+ <span
74
+ className={cn(
75
+ "mt-0.5 shrink-0 rounded px-1 py-0.5 text-[10px] font-medium leading-none",
76
+ run.type === "agent_execution"
77
+ ? "bg-primary/10 text-primary"
78
+ : "bg-muted text-muted-foreground",
79
+ )}
80
+ >
81
+ {run.type === "agent_execution" ? "Agent" : "Workflow"}
82
+ </span>
83
+ <div className="min-w-0 flex-1">
84
+ <p className="truncate font-medium text-foreground">
85
+ {run.name}
86
+ </p>
87
+ {run.error && (
88
+ <p className="truncate text-muted-foreground">{run.error}</p>
89
+ )}
90
+ </div>
91
+ <span className="shrink-0 text-muted-foreground">
92
+ {timeAgo(run.failedAt)}
93
+ </span>
94
+ {onViewClick && (
95
+ <button
96
+ type="button"
97
+ onClick={() => onViewClick(run.id, run.type)}
98
+ className="shrink-0 text-primary hover:underline"
99
+ >
100
+ View
101
+ </button>
102
+ )}
103
+ </li>
104
+ ))}
105
+ </ul>
106
+ )}
107
+ </div>
108
+ );
109
+ });