@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
@@ -29,9 +29,9 @@ import { EnvVarForm } from "../environment/EnvVarForm";
29
29
  import type { EnvVarFormVariable } from "../environment/EnvVarForm";
30
30
  import { VisibilityToggle } from "../library/VisibilityToggle";
31
31
  import { Tabs, type TabItem } from "../tabs/Tabs";
32
- import { ResourceActionBar } from "../resource-detail/ResourceActionBar";
32
+ import { ResourceDetailShell } from "../resource-detail/ResourceDetailShell";
33
33
  import { Section } from "../resource-detail/Section";
34
- import type { DetailAction } from "../resource-detail/types";
34
+ import type { DetailAction, ResourceHeaderMeta } from "../resource-detail/types";
35
35
  import { InlineEditText } from "../inline-edit/InlineEditText";
36
36
  import { InlineEditTextarea } from "../inline-edit/InlineEditTextarea";
37
37
  import { InlineEditImage } from "../inline-edit/InlineEditImage";
@@ -253,20 +253,16 @@ export function McpServerDetailView({
253
253
  credentials.refetch();
254
254
  }
255
255
 
256
- setShowCredentialForm(false);
257
-
258
256
  if (mcpServer?.metadata?.id) {
259
257
  const envKeys = Object.keys(mcpServer.spec?.env ?? {});
260
258
  const connectOrg = activeOrg ?? org;
261
- if (options.saveForFuture) {
262
- await connection.connect(mcpServer.metadata.id, connectOrg, undefined, envKeys);
263
- } else {
264
- await connection.connect(mcpServer.metadata.id, connectOrg, values, envKeys);
265
- }
259
+ await connection.connect(mcpServer.metadata.id, connectOrg, values, envKeys);
266
260
  refetch();
267
261
  }
262
+
263
+ setShowCredentialForm(false);
268
264
  } catch {
269
- // error state is managed by the hooks
265
+ // error state is managed by the hooks — form stays open for retry
270
266
  }
271
267
  },
272
268
  [credentials, mcpServer, connection, refetch],
@@ -359,40 +355,85 @@ export function McpServerDetailView({
359
355
  return <ErrorMessage error={error} retry={refetch} className={className} />;
360
356
  if (!mcpServer) return <NotFoundState className={className} />;
361
357
 
362
- return (
363
- <div className={cn("flex flex-col gap-6", className)}>
364
- {status?.validationState === ValidationState.invalid &&
365
- status.validationMessage && (
366
- <ValidationBanner message={status.validationMessage} />
367
- )}
358
+ const meta = mcpServer.metadata;
359
+ const lastDiscoveredAt = capabilities?.lastDiscoveredAt
360
+ ? timestampDate(capabilities.lastDiscoveredAt)
361
+ : null;
362
+
363
+ const headerMeta: ResourceHeaderMeta = {
364
+ name: meta?.name || meta?.slug || "Untitled",
365
+ nameElement: editable && saveMcpField ? (
366
+ <InlineEditText
367
+ value={meta?.name || ""}
368
+ onSave={(v) => saveMcpField("name", v)}
369
+ isSaving={isUpdating}
370
+ variant="heading"
371
+ placeholder="Server name"
372
+ validate={(v) => (v.trim() ? null : "Name is required")}
373
+ />
374
+ ) : undefined,
375
+ id: meta?.id || "",
376
+ org: meta?.org,
377
+ slug: meta?.slug,
378
+ qualifiedSlug: meta?.slug
379
+ ? (meta.org ? `${meta.org}/${meta.slug}` : meta.slug)
380
+ : undefined,
381
+ icon: editable && saveMcpField ? (
382
+ <InlineEditImage
383
+ value={spec?.iconUrl ?? ""}
384
+ onSave={(v) => saveMcpField("iconUrl", v || undefined)}
385
+ isSaving={isUpdating}
386
+ fallback={<McpServerIcon className="size-6 text-muted-foreground" />}
387
+ size="md"
388
+ />
389
+ ) : spec?.iconUrl ? undefined : <McpServerIcon className="size-6 text-muted-foreground" />,
390
+ iconUrl: editable ? undefined : spec?.iconUrl || undefined,
391
+ createdAt: specAudit?.createdAt ? timestampDate(specAudit.createdAt) : null,
392
+ updatedAt: specAudit?.updatedAt ? timestampDate(specAudit.updatedAt) : null,
393
+ };
394
+
395
+ const isPublic = meta?.visibility === ApiResourceVisibility.visibility_public;
396
+ const visibilityControl =
397
+ onVisibilityChange && meta ? (
398
+ <VisibilityToggle
399
+ visibility={meta.visibility}
400
+ onVisibilityChange={onVisibilityChange}
401
+ isPending={isVisibilityPending}
402
+ />
403
+ ) : isPublic ? (
404
+ <span className="shrink-0 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground">
405
+ Public
406
+ </span>
407
+ ) : undefined;
408
+
409
+ const headerMetaExtra = (
410
+ <>
411
+ {status && <ValidationStateBadge state={status.validationState} />}
412
+ {lastDiscoveredAt && (
413
+ <>
414
+ <Dot />
415
+ <span>Discovered {formatDate(lastDiscoveredAt)}</span>
416
+ </>
417
+ )}
418
+ </>
419
+ );
368
420
 
369
- <div className="flex items-start justify-between gap-4">
370
- <Header
371
- server={mcpServer}
372
- createdAt={
373
- specAudit?.createdAt ? timestampDate(specAudit.createdAt) : null
374
- }
375
- updatedAt={
376
- specAudit?.updatedAt ? timestampDate(specAudit.updatedAt) : null
377
- }
378
- lastDiscoveredAt={
379
- capabilities?.lastDiscoveredAt
380
- ? timestampDate(capabilities.lastDiscoveredAt)
381
- : null
382
- }
383
- onVisibilityChange={onVisibilityChange}
384
- isVisibilityPending={isVisibilityPending}
385
- editable={editable}
386
- isSaving={isUpdating}
387
- saveMcpField={saveMcpField}
388
- />
389
- <ResourceActionBar
390
- primaryAction={primaryAction}
391
- actions={actions}
392
- className="shrink-0"
393
- />
394
- </div>
421
+ const headerBanner =
422
+ status?.validationState === ValidationState.invalid &&
423
+ status.validationMessage ? (
424
+ <ValidationBanner message={status.validationMessage} />
425
+ ) : undefined;
395
426
 
427
+ return (
428
+ <ResourceDetailShell
429
+ header={headerMeta}
430
+ visibilityControl={visibilityControl}
431
+ headerMetaExtra={headerMetaExtra}
432
+ headerBanner={headerBanner}
433
+ primaryAction={primaryAction}
434
+ actions={actions}
435
+ className={className}
436
+ >
396
437
  {(editable || spec?.description) && (
397
438
  <Section title="Description">
398
439
  {editable && saveMcpField ? (
@@ -443,8 +484,6 @@ export function McpServerDetailView({
443
484
  onConnect={handleConnectClick}
444
485
  onClearConnectionError={combinedClearError}
445
486
  hasDiscoveredTools={hasDiscoveredTools}
446
- toolCount={tools.length}
447
- policyCount={totalPolicyCount}
448
487
  credentialsLoading={credentials.isLoading}
449
488
  oauthPhase={oauth.phase}
450
489
  authMode={credentials.authMode}
@@ -552,7 +591,7 @@ export function McpServerDetailView({
552
591
  {(editable || (spec && spec.tags.length > 0)) && (
553
592
  <TagsSection tags={spec?.tags ?? []} editable={editable} isSaving={isUpdating} saveMcpField={saveMcpField} />
554
593
  )}
555
- </div>
594
+ </ResourceDetailShell>
556
595
  );
557
596
  }
558
597
 
@@ -635,8 +674,6 @@ function ConnectBar({
635
674
  onConnect,
636
675
  onClearConnectionError,
637
676
  hasDiscoveredTools,
638
- toolCount,
639
- policyCount,
640
677
  credentialsLoading,
641
678
  oauthPhase,
642
679
  authMode,
@@ -670,8 +707,6 @@ function ConnectBar({
670
707
  readonly onConnect: () => void;
671
708
  readonly onClearConnectionError: () => void;
672
709
  readonly hasDiscoveredTools: boolean;
673
- readonly toolCount: number;
674
- readonly policyCount: number;
675
710
  readonly credentialsLoading: boolean;
676
711
  readonly oauthPhase: OAuthConnectPhase;
677
712
  readonly authMode: "manual" | "oauth";
@@ -743,7 +778,7 @@ function ConnectBar({
743
778
  }
744
779
  if (isOrgOAuthApp && showOAuthPrimary) return "Using your OAuth app";
745
780
  if (manualOverride) return "Entering token manually";
746
- if (hasDiscoveredTools) return formatConnectionSummary(toolCount, policyCount);
781
+ if (hasDiscoveredTools) return "Connected";
747
782
  return "Not connected yet";
748
783
  })();
749
784
 
@@ -1086,13 +1121,6 @@ function oauthPhaseLabel(phase: OAuthConnectPhase): string {
1086
1121
  }
1087
1122
  }
1088
1123
 
1089
- function formatConnectionSummary(toolCount: number, policyCount: number): string {
1090
- const toolLabel = `${toolCount} tool${toolCount !== 1 ? "s" : ""}`;
1091
- if (policyCount === 0) return toolLabel;
1092
- const policyLabel = `${policyCount} ${policyCount !== 1 ? "policies" : "policy"}`;
1093
- return `${toolLabel}, ${policyLabel}`;
1094
- }
1095
-
1096
1124
  function formatTokenExpiry(expiresAtSeconds: bigint): string | null {
1097
1125
  if (expiresAtSeconds === BigInt(0)) return null;
1098
1126
  const nowSeconds = BigInt(Math.floor(Date.now() / 1000));
@@ -1128,119 +1156,6 @@ function ValidationBanner({ message }: { readonly message: string }) {
1128
1156
  );
1129
1157
  }
1130
1158
 
1131
- function Header({
1132
- server,
1133
- createdAt,
1134
- updatedAt,
1135
- lastDiscoveredAt,
1136
- onVisibilityChange,
1137
- isVisibilityPending,
1138
- editable,
1139
- isSaving,
1140
- saveMcpField,
1141
- }: {
1142
- readonly server: McpServer;
1143
- readonly createdAt: Date | null;
1144
- readonly updatedAt: Date | null;
1145
- readonly lastDiscoveredAt: Date | null;
1146
- readonly onVisibilityChange?: (v: ApiResourceVisibility) => void;
1147
- readonly isVisibilityPending?: boolean;
1148
- readonly editable?: boolean;
1149
- readonly isSaving?: boolean;
1150
- readonly saveMcpField?: <K extends keyof import("@stigmer/sdk").McpServerInput>(
1151
- field: K,
1152
- value: import("@stigmer/sdk").McpServerInput[K],
1153
- ) => Promise<boolean>;
1154
- }) {
1155
- const meta = server.metadata;
1156
- const spec = server.spec;
1157
- const status = server.status;
1158
- const displayName = meta?.name || meta?.slug || "Untitled";
1159
- const isPublic =
1160
- meta?.visibility === ApiResourceVisibility.visibility_public;
1161
-
1162
- return (
1163
- <div className="flex items-start gap-3">
1164
- {editable && saveMcpField ? (
1165
- <InlineEditImage
1166
- value={spec?.iconUrl ?? ""}
1167
- onSave={(v) => saveMcpField("iconUrl", v || undefined)}
1168
- isSaving={isSaving}
1169
- fallback={<McpServerIcon className="size-6 text-muted-foreground" />}
1170
- size="md"
1171
- />
1172
- ) : spec?.iconUrl ? (
1173
- <img
1174
- src={spec.iconUrl}
1175
- alt=""
1176
- className="mt-0.5 size-8 shrink-0 rounded object-cover"
1177
- />
1178
- ) : (
1179
- <McpServerIcon className="mt-1 size-6 shrink-0 text-muted-foreground" />
1180
- )}
1181
- <div className="min-w-0 flex-1">
1182
- <div className="flex items-center gap-2">
1183
- {editable && saveMcpField ? (
1184
- <InlineEditText
1185
- value={meta?.name || ""}
1186
- onSave={(v) => saveMcpField("name", v)}
1187
- isSaving={isSaving}
1188
- variant="heading"
1189
- placeholder="Server name"
1190
- validate={(v) => (v.trim() ? null : "Name is required")}
1191
- />
1192
- ) : (
1193
- <h2 className="truncate text-lg font-semibold text-foreground">
1194
- {displayName}
1195
- </h2>
1196
- )}
1197
- {onVisibilityChange && meta ? (
1198
- <VisibilityToggle
1199
- visibility={meta.visibility}
1200
- onVisibilityChange={onVisibilityChange}
1201
- isPending={isVisibilityPending}
1202
- />
1203
- ) : (
1204
- isPublic && (
1205
- <span className="shrink-0 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground">
1206
- Public
1207
- </span>
1208
- )
1209
- )}
1210
- </div>
1211
- {meta?.slug && (
1212
- <span className="mt-0.5 block truncate font-mono text-xs text-muted-foreground">
1213
- {meta.org ? `${meta.org}/${meta.slug}` : meta.slug}
1214
- </span>
1215
- )}
1216
- <div className="mt-0.5 flex flex-wrap items-center gap-x-1.5 text-xs text-muted-foreground">
1217
- {meta?.org && <span>{meta.org}</span>}
1218
- {status && (
1219
- <ValidationStateBadge state={status.validationState} />
1220
- )}
1221
- {lastDiscoveredAt && (
1222
- <>
1223
- <Dot />
1224
- <span>Discovered {formatDate(lastDiscoveredAt)}</span>
1225
- </>
1226
- )}
1227
- {createdAt && (
1228
- <>
1229
- <Dot />
1230
- <span>Created {formatDate(createdAt)}</span>
1231
- </>
1232
- )}
1233
- {updatedAt && (
1234
- <>
1235
- <Dot />
1236
- <span>Updated {formatDate(updatedAt)}</span>
1237
- </>
1238
- )}
1239
- </div>
1240
- </div>
1241
- </div>
1242
- );
1243
- }
1244
1159
 
1245
1160
  function ValidationStateBadge({
1246
1161
  state,
@@ -1289,6 +1204,20 @@ function ServerConfigSection({
1289
1204
  value: import("@stigmer/sdk").McpServerInput[K],
1290
1205
  ) => Promise<boolean>;
1291
1206
  }) {
1207
+ const [headersEditing, setHeadersEditing] = useState(false);
1208
+ const [queryParamsEditing, setQueryParamsEditing] = useState(false);
1209
+
1210
+ const currentHttpConfig = useMemo(() => {
1211
+ if (serverType?.case !== "http") return null;
1212
+ const v = serverType.value;
1213
+ return {
1214
+ url: v.url,
1215
+ headers: v.headers && Object.keys(v.headers).length > 0 ? { ...v.headers } : undefined,
1216
+ queryParams: v.queryParams && Object.keys(v.queryParams).length > 0 ? { ...v.queryParams } : undefined,
1217
+ timeoutSeconds: v.timeoutSeconds || undefined,
1218
+ };
1219
+ }, [serverType]);
1220
+
1292
1221
  const handleTransportChange = useCallback(
1293
1222
  async (newType: string) => {
1294
1223
  if (!saveMcpField) return false;
@@ -1304,6 +1233,46 @@ function ServerConfigSection({
1304
1233
  [saveMcpField],
1305
1234
  );
1306
1235
 
1236
+ const headerRows: KeyValueRow[] = useMemo(() => {
1237
+ if (!currentHttpConfig?.headers) return [];
1238
+ return Object.entries(currentHttpConfig.headers).map(([key, value]) => ({ key, value }));
1239
+ }, [currentHttpConfig?.headers]);
1240
+
1241
+ const queryParamRows: KeyValueRow[] = useMemo(() => {
1242
+ if (!currentHttpConfig?.queryParams) return [];
1243
+ return Object.entries(currentHttpConfig.queryParams).map(([key, value]) => ({ key, value }));
1244
+ }, [currentHttpConfig?.queryParams]);
1245
+
1246
+ const handleHeadersSave = useCallback(
1247
+ async (rows: KeyValueRow[]) => {
1248
+ if (!saveMcpField || !currentHttpConfig) return false;
1249
+ const headers: Record<string, string> = {};
1250
+ for (const row of rows) {
1251
+ if (row.key.trim()) headers[row.key.trim()] = row.value;
1252
+ }
1253
+ return saveMcpField("http", {
1254
+ ...currentHttpConfig,
1255
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
1256
+ });
1257
+ },
1258
+ [saveMcpField, currentHttpConfig],
1259
+ );
1260
+
1261
+ const handleQueryParamsSave = useCallback(
1262
+ async (rows: KeyValueRow[]) => {
1263
+ if (!saveMcpField || !currentHttpConfig) return false;
1264
+ const queryParams: Record<string, string> = {};
1265
+ for (const row of rows) {
1266
+ if (row.key.trim()) queryParams[row.key.trim()] = row.value;
1267
+ }
1268
+ return saveMcpField("http", {
1269
+ ...currentHttpConfig,
1270
+ queryParams: Object.keys(queryParams).length > 0 ? queryParams : undefined,
1271
+ });
1272
+ },
1273
+ [saveMcpField, currentHttpConfig],
1274
+ );
1275
+
1307
1276
  return (
1308
1277
  <Section title="Server Configuration">
1309
1278
  <div className="flex flex-col gap-2 p-3">
@@ -1390,10 +1359,7 @@ function ServerConfigSection({
1390
1359
  <InlineEditText
1391
1360
  value={serverType.value.url}
1392
1361
  onSave={async (v) =>
1393
- saveMcpField("http", {
1394
- url: v,
1395
- timeoutSeconds: serverType.value.timeoutSeconds || undefined,
1396
- })
1362
+ saveMcpField("http", { ...currentHttpConfig!, url: v })
1397
1363
  }
1398
1364
  isSaving={isSaving}
1399
1365
  placeholder="https://example.com/mcp"
@@ -1414,7 +1380,7 @@ function ServerConfigSection({
1414
1380
  value={serverType.value.timeoutSeconds > 0 ? String(serverType.value.timeoutSeconds) : ""}
1415
1381
  onSave={async (v) =>
1416
1382
  saveMcpField("http", {
1417
- url: serverType.value.url,
1383
+ ...currentHttpConfig!,
1418
1384
  timeoutSeconds: v ? Number(v) : undefined,
1419
1385
  })
1420
1386
  }
@@ -1435,10 +1401,144 @@ function ServerConfigSection({
1435
1401
  </>
1436
1402
  )}
1437
1403
  </div>
1404
+
1405
+ {serverType?.case === "http" && (editable || headerRows.length > 0) && (
1406
+ <HttpKeyValueSubsection
1407
+ title="Headers"
1408
+ count={headerRows.length}
1409
+ rows={headerRows}
1410
+ editable={editable}
1411
+ isSaving={isSaving}
1412
+ editing={headersEditing}
1413
+ onEditingChange={setHeadersEditing}
1414
+ onSave={handleHeadersSave}
1415
+ keyLabel="Header name"
1416
+ />
1417
+ )}
1418
+
1419
+ {serverType?.case === "http" && (editable || queryParamRows.length > 0) && (
1420
+ <HttpKeyValueSubsection
1421
+ title="Query Parameters"
1422
+ count={queryParamRows.length}
1423
+ rows={queryParamRows}
1424
+ editable={editable}
1425
+ isSaving={isSaving}
1426
+ editing={queryParamsEditing}
1427
+ onEditingChange={setQueryParamsEditing}
1428
+ onSave={handleQueryParamsSave}
1429
+ keyLabel="Parameter name"
1430
+ />
1431
+ )}
1438
1432
  </Section>
1439
1433
  );
1440
1434
  }
1441
1435
 
1436
+ /** Renders a key-value subsection (headers or query params) within ServerConfigSection. */
1437
+ function HttpKeyValueSubsection({
1438
+ title,
1439
+ count,
1440
+ rows,
1441
+ editable,
1442
+ isSaving,
1443
+ editing,
1444
+ onEditingChange,
1445
+ onSave,
1446
+ keyLabel,
1447
+ }: {
1448
+ readonly title: string;
1449
+ readonly count: number;
1450
+ readonly rows: readonly KeyValueRow[];
1451
+ readonly editable?: boolean;
1452
+ readonly isSaving?: boolean;
1453
+ readonly editing: boolean;
1454
+ readonly onEditingChange: (v: boolean) => void;
1455
+ readonly onSave: (rows: KeyValueRow[]) => Promise<boolean>;
1456
+ readonly keyLabel: string;
1457
+ }) {
1458
+ return (
1459
+ <div className="border-t border-border">
1460
+ <div className="flex items-center justify-between px-3 py-2">
1461
+ <div className="flex items-center gap-1.5">
1462
+ <span className="text-xs font-medium text-muted-foreground">{title}</span>
1463
+ {count > 0 && (
1464
+ <span className="inline-flex min-w-[1.25rem] items-center justify-center rounded-full bg-muted px-1 py-px text-[10px] font-medium leading-none text-muted-foreground">
1465
+ {count}
1466
+ </span>
1467
+ )}
1468
+ </div>
1469
+ {editable && (
1470
+ <button
1471
+ type="button"
1472
+ onClick={() => onEditingChange(!editing)}
1473
+ className="text-[11px] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground"
1474
+ >
1475
+ {editing ? "Done" : "Edit"}
1476
+ </button>
1477
+ )}
1478
+ </div>
1479
+ {editable && editing ? (
1480
+ <InlineEditKeyValue
1481
+ value={[...rows]}
1482
+ onSave={onSave}
1483
+ isSaving={isSaving}
1484
+ editing={editing}
1485
+ onEditingChange={onEditingChange}
1486
+ keyLabel={keyLabel}
1487
+ showValue
1488
+ valueLabel="Value"
1489
+ />
1490
+ ) : (
1491
+ <div className="flex flex-col divide-y divide-border">
1492
+ {rows.map((row) => (
1493
+ <div key={row.key} className="flex items-start gap-2 px-3 py-1.5">
1494
+ <code className="shrink-0 font-mono text-xs font-medium text-foreground">
1495
+ {row.key}
1496
+ </code>
1497
+ <span className="min-w-0 break-all font-mono text-xs text-muted-foreground">
1498
+ {renderHeaderValue(row.value)}
1499
+ </span>
1500
+ </div>
1501
+ ))}
1502
+ </div>
1503
+ )}
1504
+ </div>
1505
+ );
1506
+ }
1507
+
1508
+ const ENV_VAR_PLACEHOLDER = /\$\{([^}]+)\}/g;
1509
+
1510
+ /** Renders a header value, highlighting ${VAR} placeholders with a variable badge. */
1511
+ function renderHeaderValue(value: string): React.ReactNode {
1512
+ if (!ENV_VAR_PLACEHOLDER.test(value)) return value;
1513
+
1514
+ ENV_VAR_PLACEHOLDER.lastIndex = 0;
1515
+ const parts: React.ReactNode[] = [];
1516
+ let lastIndex = 0;
1517
+ let match: RegExpExecArray | null;
1518
+
1519
+ while ((match = ENV_VAR_PLACEHOLDER.exec(value)) !== null) {
1520
+ if (match.index > lastIndex) {
1521
+ parts.push(value.slice(lastIndex, match.index));
1522
+ }
1523
+ parts.push(
1524
+ <span
1525
+ key={match.index}
1526
+ className="inline-flex items-center gap-0.5 rounded bg-primary-subtle px-1 py-px text-[10px] font-medium text-primary"
1527
+ title={`Resolved from environment variable: ${match[1]}`}
1528
+ >
1529
+ {match[0]}
1530
+ </span>,
1531
+ );
1532
+ lastIndex = match.index + match[0].length;
1533
+ }
1534
+
1535
+ if (lastIndex < value.length) {
1536
+ parts.push(value.slice(lastIndex));
1537
+ }
1538
+
1539
+ return <>{parts}</>;
1540
+ }
1541
+
1442
1542
  function SourceSection({
1443
1543
  spec,
1444
1544
  }: {
@@ -1669,6 +1769,19 @@ function ToolsTabContent({
1669
1769
  }: {
1670
1770
  readonly tools: readonly DiscoveredTool[];
1671
1771
  }) {
1772
+ const [search, setSearch] = useState("");
1773
+ const [expandedTool, setExpandedTool] = useState<string | null>(null);
1774
+
1775
+ const filtered = useMemo(() => {
1776
+ if (!search.trim()) return tools;
1777
+ const q = search.toLowerCase();
1778
+ return tools.filter(
1779
+ (t) =>
1780
+ t.name.toLowerCase().includes(q) ||
1781
+ t.description?.toLowerCase().includes(q),
1782
+ );
1783
+ }, [tools, search]);
1784
+
1672
1785
  if (tools.length === 0) {
1673
1786
  return (
1674
1787
  <div className="px-3 py-8 text-center">
@@ -1680,20 +1793,97 @@ function ToolsTabContent({
1680
1793
  );
1681
1794
  }
1682
1795
 
1796
+ const isFiltered = search.trim().length > 0;
1797
+
1683
1798
  return (
1684
- <div className="flex flex-col divide-y divide-border">
1685
- {tools.map((tool) => (
1686
- <div key={tool.name} className="px-3 py-2.5">
1687
- <code className="font-mono text-sm font-medium text-foreground">
1688
- {tool.name}
1689
- </code>
1690
- {tool.description && (
1691
- <p className="mt-0.5 text-xs text-muted-foreground">
1692
- {tool.description}
1693
- </p>
1799
+ <div className="flex flex-col">
1800
+ <div className="flex items-center gap-2 px-3 pb-2">
1801
+ <div className="relative flex-1">
1802
+ <SearchIcon className="pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
1803
+ <input
1804
+ type="text"
1805
+ value={search}
1806
+ onChange={(e) => setSearch(e.target.value)}
1807
+ placeholder="Search tools…"
1808
+ aria-label="Search tools"
1809
+ className="w-full rounded-md border border-border bg-background py-1.5 pl-7 pr-7 text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
1810
+ />
1811
+ {isFiltered && (
1812
+ <button
1813
+ type="button"
1814
+ onClick={() => setSearch("")}
1815
+ aria-label="Clear search"
1816
+ className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
1817
+ >
1818
+ <CloseIcon className="size-3" />
1819
+ </button>
1694
1820
  )}
1695
1821
  </div>
1696
- ))}
1822
+ <span className="shrink-0 text-[10px] text-muted-foreground">
1823
+ {isFiltered ? `${filtered.length} of ${tools.length}` : tools.length}
1824
+ </span>
1825
+ </div>
1826
+
1827
+ {filtered.length === 0 ? (
1828
+ <div className="px-3 py-6 text-center">
1829
+ <p className="text-xs text-muted-foreground">
1830
+ No tools matching &ldquo;{search}&rdquo;
1831
+ </p>
1832
+ </div>
1833
+ ) : (
1834
+ <div className="max-h-96 overflow-y-auto">
1835
+ <div className="flex flex-col divide-y divide-border">
1836
+ {filtered.map((tool) => {
1837
+ const isExpanded = expandedTool === tool.name;
1838
+ const hasSchema =
1839
+ tool.inputSchema != null &&
1840
+ Object.keys(tool.inputSchema).length > 0;
1841
+
1842
+ return (
1843
+ <div key={tool.name}>
1844
+ <button
1845
+ type="button"
1846
+ onClick={() =>
1847
+ setExpandedTool(isExpanded ? null : tool.name)
1848
+ }
1849
+ className="flex w-full items-start gap-2 px-3 py-2.5 text-left transition-colors hover:bg-muted-faint"
1850
+ aria-expanded={isExpanded}
1851
+ >
1852
+ <ChevronIcon
1853
+ className={cn(
1854
+ "mt-0.5 size-3 shrink-0 text-muted-foreground transition-transform",
1855
+ isExpanded && "rotate-90",
1856
+ )}
1857
+ />
1858
+ <div className="min-w-0 flex-1">
1859
+ <code className="font-mono text-sm font-medium text-foreground">
1860
+ {tool.name}
1861
+ </code>
1862
+ {tool.description && (
1863
+ <p className="mt-0.5 text-xs text-muted-foreground">
1864
+ {tool.description}
1865
+ </p>
1866
+ )}
1867
+ </div>
1868
+ {hasSchema && (
1869
+ <span className="mt-0.5 shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
1870
+ schema
1871
+ </span>
1872
+ )}
1873
+ </button>
1874
+ {isExpanded && hasSchema && (
1875
+ <div className="border-t border-border bg-muted-faint px-3 py-2">
1876
+ <pre className="max-h-64 overflow-auto whitespace-pre-wrap break-words rounded border border-border bg-background p-2 font-mono text-[11px] text-foreground">
1877
+ {JSON.stringify(tool.inputSchema, null, 2)}
1878
+ </pre>
1879
+ </div>
1880
+ )}
1881
+ </div>
1882
+ );
1883
+ })}
1884
+ </div>
1885
+ </div>
1886
+ )}
1697
1887
  </div>
1698
1888
  );
1699
1889
  }
@@ -1707,9 +1897,33 @@ function PoliciesTabContent({
1707
1897
  readonly classifiedPolicies: readonly ToolApprovalPolicy[];
1708
1898
  readonly hasDiscoveredTools: boolean;
1709
1899
  }) {
1710
- const hasPinnedPolicies = pinnedPolicies.length > 0;
1711
- const hasClassifiedPolicies = classifiedPolicies.length > 0;
1712
- const hasAnyPolicies = hasPinnedPolicies || hasClassifiedPolicies;
1900
+ const [search, setSearch] = useState("");
1901
+
1902
+ const totalCount = pinnedPolicies.length + classifiedPolicies.length;
1903
+ const hasAnyPolicies = totalCount > 0;
1904
+
1905
+ const filteredPinned = useMemo(() => {
1906
+ if (!search.trim()) return pinnedPolicies;
1907
+ const q = search.toLowerCase();
1908
+ return pinnedPolicies.filter(
1909
+ (p) =>
1910
+ p.toolName.toLowerCase().includes(q) ||
1911
+ p.message?.toLowerCase().includes(q),
1912
+ );
1913
+ }, [pinnedPolicies, search]);
1914
+
1915
+ const filteredClassified = useMemo(() => {
1916
+ if (!search.trim()) return classifiedPolicies;
1917
+ const q = search.toLowerCase();
1918
+ return classifiedPolicies.filter(
1919
+ (p) =>
1920
+ p.toolName.toLowerCase().includes(q) ||
1921
+ p.message?.toLowerCase().includes(q),
1922
+ );
1923
+ }, [classifiedPolicies, search]);
1924
+
1925
+ const filteredTotal = filteredPinned.length + filteredClassified.length;
1926
+ const isFiltered = search.trim().length > 0;
1713
1927
 
1714
1928
  if (!hasAnyPolicies) {
1715
1929
  return (
@@ -1726,19 +1940,56 @@ function PoliciesTabContent({
1726
1940
 
1727
1941
  return (
1728
1942
  <div className="flex flex-col">
1729
- {hasPinnedPolicies && (
1730
- <PolicyGroup
1731
- icon={<PinIcon className="size-3.5" />}
1732
- label="Pinned"
1733
- policies={pinnedPolicies}
1734
- />
1735
- )}
1736
- {hasClassifiedPolicies && (
1737
- <PolicyGroup
1738
- icon={<SparklesIcon className="size-3.5" />}
1739
- label="Auto-classified"
1740
- policies={classifiedPolicies}
1741
- />
1943
+ <div className="flex items-center gap-2 px-3 pb-2">
1944
+ <div className="relative flex-1">
1945
+ <SearchIcon className="pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
1946
+ <input
1947
+ type="text"
1948
+ value={search}
1949
+ onChange={(e) => setSearch(e.target.value)}
1950
+ placeholder="Search policies…"
1951
+ aria-label="Search policies"
1952
+ className="w-full rounded-md border border-border bg-background py-1.5 pl-7 pr-7 text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
1953
+ />
1954
+ {isFiltered && (
1955
+ <button
1956
+ type="button"
1957
+ onClick={() => setSearch("")}
1958
+ aria-label="Clear search"
1959
+ className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
1960
+ >
1961
+ <CloseIcon className="size-3" />
1962
+ </button>
1963
+ )}
1964
+ </div>
1965
+ <span className="shrink-0 text-[10px] text-muted-foreground">
1966
+ {isFiltered ? `${filteredTotal} of ${totalCount}` : totalCount}
1967
+ </span>
1968
+ </div>
1969
+
1970
+ {filteredTotal === 0 ? (
1971
+ <div className="px-3 py-6 text-center">
1972
+ <p className="text-xs text-muted-foreground">
1973
+ No policies matching &ldquo;{search}&rdquo;
1974
+ </p>
1975
+ </div>
1976
+ ) : (
1977
+ <div className="max-h-96 overflow-y-auto">
1978
+ {filteredPinned.length > 0 && (
1979
+ <PolicyGroup
1980
+ icon={<PinIcon className="size-3.5" />}
1981
+ label="Pinned"
1982
+ policies={filteredPinned}
1983
+ />
1984
+ )}
1985
+ {filteredClassified.length > 0 && (
1986
+ <PolicyGroup
1987
+ icon={<SparklesIcon className="size-3.5" />}
1988
+ label="Auto-classified"
1989
+ policies={filteredClassified}
1990
+ />
1991
+ )}
1992
+ </div>
1742
1993
  )}
1743
1994
  </div>
1744
1995
  );
@@ -1771,7 +2022,10 @@ function PolicyGroup({
1771
2022
  <code className="font-mono text-sm font-medium text-foreground">
1772
2023
  {policy.toolName}
1773
2024
  </code>
1774
- <ShieldIcon className="size-3 text-amber-500 dark:text-amber-400" />
2025
+ <span className="inline-flex items-center gap-1 rounded bg-amber-500/10 px-1.5 py-0.5 text-[10px] font-medium text-amber-600 dark:text-amber-400">
2026
+ <ShieldIcon className="size-2.5" />
2027
+ requires approval
2028
+ </span>
1775
2029
  </div>
1776
2030
  {policy.message && (
1777
2031
  <p className="mt-0.5 text-xs text-muted-foreground">
@@ -2055,6 +2309,58 @@ function ExternalLinkIcon({ className }: { readonly className?: string }) {
2055
2309
  );
2056
2310
  }
2057
2311
 
2312
+ function SearchIcon({ className }: { readonly className?: string }) {
2313
+ return (
2314
+ <svg
2315
+ className={className}
2316
+ viewBox="0 0 16 16"
2317
+ fill="none"
2318
+ stroke="currentColor"
2319
+ strokeWidth="1.5"
2320
+ strokeLinecap="round"
2321
+ strokeLinejoin="round"
2322
+ aria-hidden="true"
2323
+ >
2324
+ <circle cx="7" cy="7" r="4.5" />
2325
+ <path d="m10.5 10.5 3 3" />
2326
+ </svg>
2327
+ );
2328
+ }
2329
+
2330
+ function CloseIcon({ className }: { readonly className?: string }) {
2331
+ return (
2332
+ <svg
2333
+ className={className}
2334
+ viewBox="0 0 16 16"
2335
+ fill="none"
2336
+ stroke="currentColor"
2337
+ strokeWidth="2"
2338
+ strokeLinecap="round"
2339
+ strokeLinejoin="round"
2340
+ aria-hidden="true"
2341
+ >
2342
+ <path d="m4 4 8 8M12 4l-8 8" />
2343
+ </svg>
2344
+ );
2345
+ }
2346
+
2347
+ function ChevronIcon({ className }: { readonly className?: string }) {
2348
+ return (
2349
+ <svg
2350
+ className={className}
2351
+ viewBox="0 0 16 16"
2352
+ fill="none"
2353
+ stroke="currentColor"
2354
+ strokeWidth="2"
2355
+ strokeLinecap="round"
2356
+ strokeLinejoin="round"
2357
+ aria-hidden="true"
2358
+ >
2359
+ <path d="m6 4 4 4-4 4" />
2360
+ </svg>
2361
+ );
2362
+ }
2363
+
2058
2364
  function Spinner() {
2059
2365
  return (
2060
2366
  <svg