@stigmer/react 3.12.4 → 3.12.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/agent/AgentDetailView.js +2 -2
  2. package/agent/AgentDetailView.js.map +1 -1
  3. package/agent/index.d.ts +0 -1
  4. package/agent/index.d.ts.map +1 -1
  5. package/agent/index.js +0 -1
  6. package/agent/index.js.map +1 -1
  7. package/agent/useUpdateAgent.d.ts +3 -3
  8. package/agent/useUpdateAgent.js +3 -3
  9. package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
  10. package/agent-instance/AgentInstanceDetailPanel.js +5 -7
  11. package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
  12. package/agent-instance/useUpdateAgentInstance.d.ts +1 -1
  13. package/agent-instance/useUpdateAgentInstance.js +1 -1
  14. package/attachment/AttachmentChipList.js +16 -6
  15. package/attachment/AttachmentChipList.js.map +1 -1
  16. package/attachment/index.d.ts +1 -1
  17. package/attachment/index.d.ts.map +1 -1
  18. package/attachment/index.js.map +1 -1
  19. package/attachment/useAttachments.d.ts +51 -8
  20. package/attachment/useAttachments.d.ts.map +1 -1
  21. package/attachment/useAttachments.js +74 -3
  22. package/attachment/useAttachments.js.map +1 -1
  23. package/channel/AgentChannelsPanel.d.ts.map +1 -1
  24. package/channel/AgentChannelsPanel.js +10 -5
  25. package/channel/AgentChannelsPanel.js.map +1 -1
  26. package/channel/ChannelRunConfigDialog.d.ts +51 -0
  27. package/channel/ChannelRunConfigDialog.d.ts.map +1 -0
  28. package/channel/ChannelRunConfigDialog.js +121 -0
  29. package/channel/ChannelRunConfigDialog.js.map +1 -0
  30. package/channel/index.d.ts +2 -0
  31. package/channel/index.d.ts.map +1 -1
  32. package/channel/index.js +1 -0
  33. package/channel/index.js.map +1 -1
  34. package/channel/useSaveAgentChannel.d.ts.map +1 -1
  35. package/channel/useSaveAgentChannel.js +6 -3
  36. package/channel/useSaveAgentChannel.js.map +1 -1
  37. package/channel-app/ChannelAppDetailPanel.js +9 -9
  38. package/channel-app/ChannelAppDetailPanel.js.map +1 -1
  39. package/composer/ComposerToolbar.d.ts +6 -1
  40. package/composer/ComposerToolbar.d.ts.map +1 -1
  41. package/composer/ComposerToolbar.js +2 -2
  42. package/composer/ComposerToolbar.js.map +1 -1
  43. package/composer/SessionComposer.d.ts +9 -0
  44. package/composer/SessionComposer.d.ts.map +1 -1
  45. package/composer/SessionComposer.js +39 -13
  46. package/composer/SessionComposer.js.map +1 -1
  47. package/conversation/ConversationComposer.d.ts +19 -3
  48. package/conversation/ConversationComposer.d.ts.map +1 -1
  49. package/conversation/ConversationComposer.js +4 -4
  50. package/conversation/ConversationComposer.js.map +1 -1
  51. package/conversation/ConversationTemplatePickerDialog.d.ts +63 -0
  52. package/conversation/ConversationTemplatePickerDialog.d.ts.map +1 -0
  53. package/conversation/ConversationTemplatePickerDialog.js +151 -0
  54. package/conversation/ConversationTemplatePickerDialog.js.map +1 -0
  55. package/conversation/ConversationsWorkbench.d.ts.map +1 -1
  56. package/conversation/ConversationsWorkbench.js +16 -5
  57. package/conversation/ConversationsWorkbench.js.map +1 -1
  58. package/conversation/index.d.ts +3 -1
  59. package/conversation/index.d.ts.map +1 -1
  60. package/conversation/index.js +1 -0
  61. package/conversation/index.js.map +1 -1
  62. package/conversation/useConversationParticipation.d.ts +41 -4
  63. package/conversation/useConversationParticipation.d.ts.map +1 -1
  64. package/conversation/useConversationParticipation.js +13 -2
  65. package/conversation/useConversationParticipation.js.map +1 -1
  66. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
  67. package/cursor-accounts/CursorAccountsConsole.js +12 -3
  68. package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
  69. package/cursor-accounts/cursor-account-coverage.d.ts +30 -1
  70. package/cursor-accounts/cursor-account-coverage.d.ts.map +1 -1
  71. package/cursor-accounts/cursor-account-coverage.js +21 -0
  72. package/cursor-accounts/cursor-account-coverage.js.map +1 -1
  73. package/execution/useCreateAgentExecution.d.ts +15 -0
  74. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  75. package/execution/useCreateAgentExecution.js +5 -0
  76. package/execution/useCreateAgentExecution.js.map +1 -1
  77. package/identity-account/AccountPreferencesPanel.d.ts +36 -0
  78. package/identity-account/AccountPreferencesPanel.d.ts.map +1 -0
  79. package/identity-account/AccountPreferencesPanel.js +202 -0
  80. package/identity-account/AccountPreferencesPanel.js.map +1 -0
  81. package/identity-account/index.d.ts +8 -0
  82. package/identity-account/index.d.ts.map +1 -1
  83. package/identity-account/index.js +4 -0
  84. package/identity-account/index.js.map +1 -1
  85. package/identity-account/useAccountExecutionDefaults.d.ts +36 -0
  86. package/identity-account/useAccountExecutionDefaults.d.ts.map +1 -0
  87. package/identity-account/useAccountExecutionDefaults.js +46 -0
  88. package/identity-account/useAccountExecutionDefaults.js.map +1 -0
  89. package/identity-account/useMyIdentityAccount.d.ts +55 -0
  90. package/identity-account/useMyIdentityAccount.d.ts.map +1 -0
  91. package/identity-account/useMyIdentityAccount.js +37 -0
  92. package/identity-account/useMyIdentityAccount.js.map +1 -0
  93. package/identity-account/useUpdateIdentityAccount.d.ts +42 -0
  94. package/identity-account/useUpdateIdentityAccount.d.ts.map +1 -0
  95. package/identity-account/useUpdateIdentityAccount.js +53 -0
  96. package/identity-account/useUpdateIdentityAccount.js.map +1 -0
  97. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  98. package/identity-provider/IdentityProviderDetailPanel.js +16 -15
  99. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  100. package/index.d.ts +15 -13
  101. package/index.d.ts.map +1 -1
  102. package/index.js +11 -8
  103. package/index.js.map +1 -1
  104. package/internal/StandingContextField.d.ts +37 -0
  105. package/internal/StandingContextField.d.ts.map +1 -0
  106. package/internal/StandingContextField.js +24 -0
  107. package/internal/StandingContextField.js.map +1 -0
  108. package/library/InstanceVisibilitySelector.d.ts.map +1 -1
  109. package/library/InstanceVisibilitySelector.js +9 -2
  110. package/library/InstanceVisibilitySelector.js.map +1 -1
  111. package/library/ResourceVisibilityControl.d.ts +13 -3
  112. package/library/ResourceVisibilityControl.d.ts.map +1 -1
  113. package/library/ResourceVisibilityControl.js +33 -5
  114. package/library/ResourceVisibilityControl.js.map +1 -1
  115. package/library/VisibilityOptionRow.d.ts +6 -0
  116. package/library/VisibilityOptionRow.d.ts.map +1 -1
  117. package/library/VisibilityOptionRow.js +11 -1
  118. package/library/VisibilityOptionRow.js.map +1 -1
  119. package/library/VisibilitySelector.d.ts.map +1 -1
  120. package/library/VisibilitySelector.js +14 -2
  121. package/library/VisibilitySelector.js.map +1 -1
  122. package/library/index.d.ts +4 -2
  123. package/library/index.d.ts.map +1 -1
  124. package/library/index.js +2 -1
  125. package/library/index.js.map +1 -1
  126. package/library/useCanSetPublicVisibility.d.ts +30 -0
  127. package/library/useCanSetPublicVisibility.d.ts.map +1 -0
  128. package/library/useCanSetPublicVisibility.js +41 -0
  129. package/library/useCanSetPublicVisibility.js.map +1 -0
  130. package/library/visibilityLevels.d.ts +32 -1
  131. package/library/visibilityLevels.d.ts.map +1 -1
  132. package/library/visibilityLevels.js +34 -14
  133. package/library/visibilityLevels.js.map +1 -1
  134. package/mcp-server/McpServerDetailView.js +2 -2
  135. package/mcp-server/McpServerDetailView.js.map +1 -1
  136. package/mcp-server/index.d.ts +0 -1
  137. package/mcp-server/index.d.ts.map +1 -1
  138. package/mcp-server/index.js +0 -1
  139. package/mcp-server/index.js.map +1 -1
  140. package/mcp-server/internal/definitionDrift.d.ts +14 -12
  141. package/mcp-server/internal/definitionDrift.d.ts.map +1 -1
  142. package/mcp-server/internal/definitionDrift.js +22 -19
  143. package/mcp-server/internal/definitionDrift.js.map +1 -1
  144. package/mcp-server/useMcpServerConnect.d.ts +8 -5
  145. package/mcp-server/useMcpServerConnect.d.ts.map +1 -1
  146. package/mcp-server/useMcpServerConnect.js +2 -1
  147. package/mcp-server/useMcpServerConnect.js.map +1 -1
  148. package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
  149. package/mcp-server/useMcpServerOAuthConnect.js +7 -2
  150. package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
  151. package/mcp-server/useUpdateMcpServer.d.ts +3 -3
  152. package/mcp-server/useUpdateMcpServer.js +3 -3
  153. package/models/ModelSelector.d.ts +33 -1
  154. package/models/ModelSelector.d.ts.map +1 -1
  155. package/models/ModelSelector.js +37 -4
  156. package/models/ModelSelector.js.map +1 -1
  157. package/models/index.d.ts +2 -0
  158. package/models/index.d.ts.map +1 -1
  159. package/models/index.js +1 -0
  160. package/models/index.js.map +1 -1
  161. package/models/registry.d.ts +16 -0
  162. package/models/registry.d.ts.map +1 -1
  163. package/models/registry.js +13 -0
  164. package/models/registry.js.map +1 -1
  165. package/models/thinking-mode.d.ts +27 -0
  166. package/models/thinking-mode.d.ts.map +1 -0
  167. package/models/thinking-mode.js +32 -0
  168. package/models/thinking-mode.js.map +1 -0
  169. package/oauth-app/CreateOAuthAppForm.d.ts +2 -2
  170. package/oauth-app/CreateOAuthAppForm.d.ts.map +1 -1
  171. package/oauth-app/CreateOAuthAppForm.js +13 -4
  172. package/oauth-app/CreateOAuthAppForm.js.map +1 -1
  173. package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
  174. package/oauth-app/OAuthAppDetailPanel.js +50 -22
  175. package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
  176. package/organization/OrgPreferencesPanel.d.ts +32 -0
  177. package/organization/OrgPreferencesPanel.d.ts.map +1 -0
  178. package/organization/OrgPreferencesPanel.js +90 -0
  179. package/organization/OrgPreferencesPanel.js.map +1 -0
  180. package/organization/OrgProfilePanel.d.ts.map +1 -1
  181. package/organization/OrgProfilePanel.js +5 -4
  182. package/organization/OrgProfilePanel.js.map +1 -1
  183. package/organization/index.d.ts +2 -0
  184. package/organization/index.d.ts.map +1 -1
  185. package/organization/index.js +1 -0
  186. package/organization/index.js.map +1 -1
  187. package/package.json +4 -4
  188. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
  189. package/platform-client/PlatformClientDetailPanel.js +12 -13
  190. package/platform-client/PlatformClientDetailPanel.js.map +1 -1
  191. package/schedule/ScheduleDetailView.d.ts.map +1 -1
  192. package/schedule/ScheduleDetailView.js +21 -10
  193. package/schedule/ScheduleDetailView.js.map +1 -1
  194. package/schedule/ScheduleForm.d.ts.map +1 -1
  195. package/schedule/ScheduleForm.js +13 -3
  196. package/schedule/ScheduleForm.js.map +1 -1
  197. package/session/NewSessionViewer.d.ts +10 -1
  198. package/session/NewSessionViewer.d.ts.map +1 -1
  199. package/session/NewSessionViewer.js +2 -1
  200. package/session/NewSessionViewer.js.map +1 -1
  201. package/session/run-config.d.ts +9 -0
  202. package/session/run-config.d.ts.map +1 -1
  203. package/session/run-config.js +5 -0
  204. package/session/run-config.js.map +1 -1
  205. package/session/useNewSessionFlow.d.ts +27 -1
  206. package/session/useNewSessionFlow.d.ts.map +1 -1
  207. package/session/useNewSessionFlow.js +51 -8
  208. package/session/useNewSessionFlow.js.map +1 -1
  209. package/session/useSessionConversation.d.ts +12 -1
  210. package/session/useSessionConversation.d.ts.map +1 -1
  211. package/session/useSessionConversation.js +15 -24
  212. package/session/useSessionConversation.js.map +1 -1
  213. package/session/useSessionPageFlow.d.ts.map +1 -1
  214. package/session/useSessionPageFlow.js +14 -10
  215. package/session/useSessionPageFlow.js.map +1 -1
  216. package/session/useUpdateSession.d.ts +18 -24
  217. package/session/useUpdateSession.d.ts.map +1 -1
  218. package/session/useUpdateSession.js +18 -24
  219. package/session/useUpdateSession.js.map +1 -1
  220. package/settings/AccountPreferencesSection.d.ts +3 -0
  221. package/settings/AccountPreferencesSection.d.ts.map +1 -0
  222. package/settings/AccountPreferencesSection.js +10 -0
  223. package/settings/AccountPreferencesSection.js.map +1 -0
  224. package/settings/OrgPreferencesSection.d.ts +3 -0
  225. package/settings/OrgPreferencesSection.d.ts.map +1 -0
  226. package/settings/OrgPreferencesSection.js +13 -0
  227. package/settings/OrgPreferencesSection.js.map +1 -0
  228. package/settings/index.d.ts +2 -0
  229. package/settings/index.d.ts.map +1 -1
  230. package/settings/index.js +2 -0
  231. package/settings/index.js.map +1 -1
  232. package/settings/settings-nav.d.ts.map +1 -1
  233. package/settings/settings-nav.js +17 -1
  234. package/settings/settings-nav.js.map +1 -1
  235. package/src/agent/AgentDetailView.tsx +2 -2
  236. package/src/agent/index.ts +0 -2
  237. package/src/agent/useUpdateAgent.ts +3 -3
  238. package/src/agent-instance/AgentInstanceDetailPanel.tsx +5 -7
  239. package/src/agent-instance/__tests__/AgentInstanceDetailPanel.test.tsx +75 -0
  240. package/src/agent-instance/useUpdateAgentInstance.ts +1 -1
  241. package/src/attachment/AttachmentChipList.tsx +19 -8
  242. package/src/attachment/__tests__/AttachmentChipList.test.tsx +12 -0
  243. package/src/attachment/__tests__/useAttachments.test.ts +293 -0
  244. package/src/attachment/index.ts +1 -0
  245. package/src/attachment/useAttachments.ts +143 -11
  246. package/src/channel/AgentChannelsPanel.tsx +26 -1
  247. package/src/channel/ChannelRunConfigDialog.tsx +351 -0
  248. package/src/channel/__tests__/ChannelRunConfigDialog.test.tsx +210 -0
  249. package/src/channel/index.ts +2 -0
  250. package/src/channel/useSaveAgentChannel.ts +6 -3
  251. package/src/channel-app/ChannelAppDetailPanel.tsx +9 -9
  252. package/src/channel-app/__tests__/channelAppWhatsApp.test.tsx +2 -0
  253. package/src/channel-app/__tests__/channelAppWipeSafety.test.tsx +87 -0
  254. package/src/composer/ComposerToolbar.tsx +9 -0
  255. package/src/composer/SessionComposer.tsx +59 -16
  256. package/src/composer/__tests__/SessionComposer-thinkingMode.test.tsx +176 -0
  257. package/src/conversation/ConversationComposer.tsx +38 -4
  258. package/src/conversation/ConversationTemplatePickerDialog.tsx +441 -0
  259. package/src/conversation/ConversationsWorkbench.tsx +40 -4
  260. package/src/conversation/__tests__/ConversationComposer.test.tsx +56 -1
  261. package/src/conversation/__tests__/ConversationTemplatePickerDialog.test.tsx +224 -0
  262. package/src/conversation/__tests__/useConversationParticipation.test.tsx +45 -4
  263. package/src/conversation/index.ts +4 -0
  264. package/src/conversation/useConversationParticipation.ts +58 -6
  265. package/src/cursor-accounts/CursorAccountsConsole.tsx +40 -5
  266. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +32 -0
  267. package/src/cursor-accounts/__tests__/cursor-account-coverage.test.ts +58 -1
  268. package/src/cursor-accounts/cursor-account-coverage.ts +55 -0
  269. package/src/execution/useCreateAgentExecution.ts +19 -0
  270. package/src/identity-account/AccountPreferencesPanel.tsx +532 -0
  271. package/src/identity-account/__tests__/AccountPreferencesPanel.test.tsx +267 -0
  272. package/src/identity-account/__tests__/useAccountExecutionDefaults.test.tsx +116 -0
  273. package/src/identity-account/__tests__/useMyIdentityAccount.test.tsx +121 -0
  274. package/src/identity-account/index.ts +11 -0
  275. package/src/identity-account/useAccountExecutionDefaults.ts +63 -0
  276. package/src/identity-account/useMyIdentityAccount.ts +75 -0
  277. package/src/identity-account/useUpdateIdentityAccount.ts +73 -0
  278. package/src/identity-provider/IdentityProviderDetailPanel.tsx +18 -15
  279. package/src/identity-provider/__tests__/IdentityProviderDetailPanel.test.tsx +80 -0
  280. package/src/index.ts +26 -4
  281. package/src/internal/StandingContextField.tsx +92 -0
  282. package/src/library/InstanceVisibilitySelector.tsx +9 -2
  283. package/src/library/ResourceVisibilityControl.tsx +46 -13
  284. package/src/library/VisibilityOptionRow.tsx +28 -6
  285. package/src/library/VisibilitySelector.tsx +14 -2
  286. package/src/library/__tests__/VisibilitySelector.test.tsx +48 -1
  287. package/src/library/__tests__/visibilityLevels.test.ts +67 -1
  288. package/src/library/index.ts +6 -1
  289. package/src/library/useCanSetPublicVisibility.ts +56 -0
  290. package/src/library/visibilityLevels.ts +65 -14
  291. package/src/mcp-server/McpServerDetailView.tsx +2 -2
  292. package/src/mcp-server/__tests__/useMcpServerConnect.asyncLane.test.tsx +117 -0
  293. package/src/mcp-server/index.ts +0 -2
  294. package/src/mcp-server/internal/definitionDrift.ts +22 -20
  295. package/src/mcp-server/useMcpServerConnect.ts +9 -6
  296. package/src/mcp-server/useMcpServerOAuthConnect.ts +7 -2
  297. package/src/mcp-server/useUpdateMcpServer.ts +3 -3
  298. package/src/models/ModelSelector.tsx +94 -1
  299. package/src/models/index.ts +2 -0
  300. package/src/models/registry.ts +29 -0
  301. package/src/models/thinking-mode.ts +48 -0
  302. package/src/oauth-app/CreateOAuthAppForm.tsx +58 -3
  303. package/src/oauth-app/OAuthAppDetailPanel.tsx +103 -20
  304. package/src/oauth-app/__tests__/OAuthAppDetailPanel.test.tsx +94 -0
  305. package/src/organization/OrgPreferencesPanel.tsx +221 -0
  306. package/src/organization/OrgProfilePanel.tsx +5 -4
  307. package/src/organization/__tests__/OrgPreferencesPanel.test.tsx +145 -0
  308. package/src/organization/__tests__/OrgProfilePanel.test.tsx +108 -0
  309. package/src/organization/index.ts +2 -0
  310. package/src/platform-client/PlatformClientDetailPanel.tsx +14 -13
  311. package/src/platform-client/__tests__/PlatformClientDetailPanel.test.tsx +82 -0
  312. package/src/schedule/ScheduleDetailView.tsx +29 -4
  313. package/src/schedule/ScheduleForm.tsx +14 -1
  314. package/src/session/NewSessionViewer.tsx +12 -0
  315. package/src/session/__tests__/useNewSessionFlow.test.tsx +151 -0
  316. package/src/session/run-config.ts +16 -0
  317. package/src/session/useNewSessionFlow.ts +82 -9
  318. package/src/session/useSessionConversation.ts +32 -40
  319. package/src/session/useSessionPageFlow.ts +14 -11
  320. package/src/session/useUpdateSession.ts +18 -24
  321. package/src/settings/AccountPreferencesSection.tsx +25 -0
  322. package/src/settings/OrgPreferencesSection.tsx +35 -0
  323. package/src/settings/__tests__/settings-nav.test.ts +27 -0
  324. package/src/settings/index.ts +2 -0
  325. package/src/settings/settings-nav.ts +18 -0
  326. package/src/workflow/ApprovalFormBuilder.tsx +20 -27
  327. package/src/workflow/WorkflowDetailView.tsx +2 -2
  328. package/src/workflow/__tests__/WorkflowInstanceDetailPanel.test.tsx +83 -0
  329. package/src/workflow/index.ts +0 -2
  330. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +6 -7
  331. package/src/workflow/useUpdateWorkflow.ts +3 -3
  332. package/styles.css +1 -1
  333. package/workflow/ApprovalFormBuilder.d.ts.map +1 -1
  334. package/workflow/ApprovalFormBuilder.js +10 -5
  335. package/workflow/ApprovalFormBuilder.js.map +1 -1
  336. package/workflow/WorkflowDetailView.js +2 -2
  337. package/workflow/WorkflowDetailView.js.map +1 -1
  338. package/workflow/index.d.ts +0 -1
  339. package/workflow/index.d.ts.map +1 -1
  340. package/workflow/index.js +0 -1
  341. package/workflow/index.js.map +1 -1
  342. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  343. package/workflow/instance/WorkflowInstanceDetailPanel.js +6 -7
  344. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  345. package/workflow/useUpdateWorkflow.d.ts +3 -3
  346. package/workflow/useUpdateWorkflow.js +3 -3
  347. package/agent/internal/agentToInput.d.ts +0 -15
  348. package/agent/internal/agentToInput.d.ts.map +0 -1
  349. package/agent/internal/agentToInput.js +0 -84
  350. package/agent/internal/agentToInput.js.map +0 -1
  351. package/mcp-server/internal/mcpServerToInput.d.ts +0 -12
  352. package/mcp-server/internal/mcpServerToInput.d.ts.map +0 -1
  353. package/mcp-server/internal/mcpServerToInput.js +0 -84
  354. package/mcp-server/internal/mcpServerToInput.js.map +0 -1
  355. package/session/session-spec-converters.d.ts +0 -24
  356. package/session/session-spec-converters.d.ts.map +0 -1
  357. package/session/session-spec-converters.js +0 -72
  358. package/session/session-spec-converters.js.map +0 -1
  359. package/src/agent/internal/__tests__/agentToInput.test.ts +0 -145
  360. package/src/agent/internal/agentToInput.ts +0 -102
  361. package/src/mcp-server/__tests__/mcpServerToInput.test.ts +0 -201
  362. package/src/mcp-server/internal/mcpServerToInput.ts +0 -98
  363. package/src/session/__tests__/session-spec-converters.test.ts +0 -183
  364. package/src/session/session-spec-converters.ts +0 -86
  365. package/src/workflow/internal/workflowToInput.ts +0 -96
  366. package/workflow/internal/workflowToInput.d.ts +0 -12
  367. package/workflow/internal/workflowToInput.d.ts.map +0 -1
  368. package/workflow/internal/workflowToInput.js +0 -73
  369. package/workflow/internal/workflowToInput.js.map +0 -1
@@ -9,15 +9,17 @@ import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_
9
9
  import type { McpServerUsage as ProtoMcpServerUsage } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
10
10
  import type { WorkspaceEntry as ProtoWorkspaceEntry } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
11
11
  import type { ApiResourceReference as ProtoApiResourceReference } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
12
- import type {
13
- AttachmentInput,
14
- EnvVarInput,
15
- McpServerUsageInput,
16
- ResourceRef,
17
- WorkspaceEntryInput,
12
+ import {
13
+ toSessionUpdateInput,
14
+ type AttachmentInput,
15
+ type EnvVarInput,
16
+ type McpServerUsageInput,
17
+ type ResourceRef,
18
+ type WorkspaceEntryInput,
18
19
  } from "@stigmer/sdk";
19
20
  import { isTerminalPhase } from "../execution/execution-phases.js";
20
21
  import type { ServiceTierOption } from "../models/service-tier.js";
22
+ import type { ThinkingModeOption } from "../models/thinking-mode.js";
21
23
  import { useStigmer } from "../hooks.js";
22
24
  import { toError } from "../internal/toError.js";
23
25
  import { useConversationStoreRef } from "../internal/store/index.js";
@@ -32,11 +34,6 @@ import { useSession } from "./useSession.js";
32
34
  import { useSessionExecutions } from "./useSessionExecutions.js";
33
35
  import { useUpdateSession } from "./useUpdateSession.js";
34
36
  import { useLocalSessionWorker } from "./useLocalSessionWorker.js";
35
- import {
36
- specWorkspaceToInput,
37
- specMcpUsagesToInput,
38
- specSkillRefsToInput,
39
- } from "./session-spec-converters.js";
40
37
 
41
38
  /**
42
39
  * Cadence for re-discovering the session's executions while the live stream
@@ -111,6 +108,16 @@ export interface SendFollowUpOptions {
111
108
  * @see {@link SharedAgentExecutionFields.serviceTier}
112
109
  */
113
110
  readonly serviceTier?: ServiceTierOption;
111
+ /**
112
+ * Thinking mode for this execution's model calls (stigmer/stigmer#772).
113
+ *
114
+ * Only set when the user actively selected `"enabled"`; `undefined`
115
+ * preserves the unspecified-vs-explicit distinction (unset resolves to
116
+ * disabled on the platform side — never the provider account default).
117
+ *
118
+ * @see {@link SharedAgentExecutionFields.thinkingMode}
119
+ */
120
+ readonly thinkingMode?: ThinkingModeOption;
114
121
  /**
115
122
  * Marks this execution as a Build-from-plan turn.
116
123
  *
@@ -674,6 +681,7 @@ export function useSessionConversation(
674
681
  attachments: options?.attachments,
675
682
  interactionMode: options?.interactionMode,
676
683
  serviceTier: options?.serviceTier,
684
+ thinkingMode: options?.thinkingMode,
677
685
  buildFromPlan: options?.buildFromPlan,
678
686
  autoApproveAll: options?.autoApproveAll,
679
687
  workspaceFileRefs: options?.workspaceFileRefs,
@@ -818,13 +826,13 @@ export function useSessionConversation(
818
826
  // ---------------------------------------------------------------------------
819
827
 
820
828
  /**
821
- * Converts the existing Session proto into a SessionInput suitable for
822
- * the update RPC (which uses replace semantics — the full spec is sent).
823
- *
824
- * For each session-level collection (workspace, MCP servers, skills):
825
- * if an override is provided, it replaces the existing value; otherwise
826
- * the current session value is preserved by converting it back to input
827
- * format.
829
+ * Builds the SessionInput for the update RPC (which uses replace
830
+ * semantics — the full spec is sent) by spreading the SDK's complete
831
+ * generated mapper and overriding only the session-level collections the
832
+ * caller provided. An override replaces the existing value; an omitted
833
+ * field keeps the fetched session's value (an empty-array override
834
+ * clears the collection normalized to absent, the mappers' canonical
835
+ * shape).
828
836
  */
829
837
  function buildUpdateInput(
830
838
  session: Session,
@@ -835,30 +843,14 @@ function buildUpdateInput(
835
843
  skillRefs?: ResourceRef[];
836
844
  },
837
845
  ) {
838
- const meta = session.metadata!;
839
- const spec = session.spec;
840
-
841
- const workspaceEntries =
842
- overrides.workspaceEntries ?? specWorkspaceToInput(spec);
843
-
844
- const mcpServerUsages =
845
- overrides.mcpServerUsages ?? specMcpUsagesToInput(spec);
846
-
847
- const skillRefs = overrides.skillRefs ?? specSkillRefsToInput(spec);
846
+ const mapped = toSessionUpdateInput(session);
847
+ const workspaceEntries = overrides.workspaceEntries ?? mapped.workspaceEntries;
848
+ const mcpServerUsages = overrides.mcpServerUsages ?? mapped.mcpServerUsages;
849
+ const skillRefs = overrides.skillRefs ?? mapped.skillRefs;
848
850
 
849
851
  return {
850
- name: meta.name,
851
- org: meta.org,
852
- agentInstanceId: overrides.agentInstanceId ?? (spec?.agentInstanceId || undefined),
853
- subject: spec?.subject || undefined,
854
- harnessStateId: spec?.harnessStateId || undefined,
855
- harness: spec?.harness,
856
- cursorMode: spec?.cursorMode,
857
- executionTarget: spec?.executionTarget,
858
- metadata:
859
- spec?.metadata && Object.keys(spec.metadata).length > 0
860
- ? { ...spec.metadata }
861
- : undefined,
852
+ ...mapped,
853
+ agentInstanceId: overrides.agentInstanceId ?? mapped.agentInstanceId,
862
854
  workspaceEntries: workspaceEntries?.length ? workspaceEntries : undefined,
863
855
  mcpServerUsages: mcpServerUsages?.length ? mcpServerUsages : undefined,
864
856
  skillRefs: skillRefs?.length ? skillRefs : undefined,
@@ -18,7 +18,7 @@ import { useSessionConversation, type UseSessionConversationReturn } from "./use
18
18
  import { resolveExecutionRuntimeEnv, type RuntimeEnvProvider } from "./runtime-env.js";
19
19
  import { useAgentRefFromSession } from "./useAgentRefFromSession.js";
20
20
  import { usePersistedModel, type UsePersistedModelReturn } from "./usePersistedModel.js";
21
- import { specMcpUsagesToInput, specSkillRefsToInput } from "./session-spec-converters.js";
21
+ import { toSessionUpdateInput } from "@stigmer/sdk";
22
22
  import type { SessionAudience } from "./audience.js";
23
23
  import { assertValidRunConfig, type SessionRunConfig } from "./run-config.js";
24
24
 
@@ -267,6 +267,7 @@ export function useSessionPageFlow(
267
267
  // callback's identity must not churn on every render (DD-010).
268
268
  const pinnedModelName = runConfig?.modelName;
269
269
  const pinnedServiceTier = runConfig?.serviceTier;
270
+ const pinnedThinkingMode = runConfig?.thinkingMode;
270
271
 
271
272
  const stigmer = useStigmer();
272
273
  const conv = useSessionConversation(sessionId, org);
@@ -401,16 +402,14 @@ export function useSessionPageFlow(
401
402
  }
402
403
  }
403
404
 
404
- // MCP server usages
405
- const mcpInputs = specMcpUsagesToInput(spec);
406
- if (mcpInputs?.length) {
407
- setMcpServerUsages(mcpInputs);
405
+ // MCP server usages and skill references, hydrated through the SDK's
406
+ // complete update-input mapper (the canonical proto → input lens).
407
+ const mapped = toSessionUpdateInput(conv.session);
408
+ if (mapped.mcpServerUsages?.length) {
409
+ setMcpServerUsages(mapped.mcpServerUsages);
408
410
  }
409
-
410
- // Skill references
411
- const skillInputs = specSkillRefsToInput(spec);
412
- if (skillInputs?.length) {
413
- setSkillRefs(skillInputs);
411
+ if (mapped.skillRefs?.length) {
412
+ setSkillRefs(mapped.skillRefs);
414
413
  }
415
414
  }, [conv.session, workspace]);
416
415
 
@@ -480,6 +479,10 @@ export function useSessionPageFlow(
480
479
  serviceTier: pinnedModelName
481
480
  ? (pinnedServiceTier === "fast" ? "fast" : undefined)
482
481
  : context?.serviceTier,
482
+ // The tier's #772 twin, same pin-wins + only-explicit-enabled rule.
483
+ thinkingMode: pinnedModelName
484
+ ? (pinnedThinkingMode === "enabled" ? "enabled" : undefined)
485
+ : context?.thinkingMode,
483
486
  buildFromPlan: context?.buildFromPlan,
484
487
  // Sourced from the session-scoped preference set at the approval gate,
485
488
  // not from the composer (the pre-arm toggle was removed).
@@ -490,7 +493,7 @@ export function useSessionPageFlow(
490
493
 
491
494
  sessionVariables.clear();
492
495
  },
493
- [conv.sendFollowUp, modelId, pinnedModelName, pinnedServiceTier, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer, autoApproveAll, getRuntimeEnv],
496
+ [conv.sendFollowUp, modelId, pinnedModelName, pinnedServiceTier, pinnedThinkingMode, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer, autoApproveAll, getRuntimeEnv],
494
497
  );
495
498
 
496
499
  // -------------------------------------------------------------------------
@@ -25,40 +25,34 @@ export interface UseUpdateSessionReturn {
25
25
  * by the backend to identify the resource) and all spec fields.
26
26
  *
27
27
  * **Full-replace semantics.** The backend replaces the entire spec with
28
- * what you send — there is no field mask. Round-trip every spec field
29
- * you do not intend to change, *including `metadata`*: an update built
30
- * from a reconstructed partial spec silently wipes the fields it omits
31
- * (workspace entries, MCP servers, and `stigmer.ai/*` metadata keys such
32
- * as the embedder session context). To change only the subject, prefer
33
- * the field-level `session.updateSubject()` RPC instead of this hook.
28
+ * what you send — there is no field mask. Spread the SDK's complete
29
+ * `toSessionUpdateInput()` mapper and override only the fields you
30
+ * change: an update built from a reconstructed partial spec silently
31
+ * wipes the fields it omits (workspace entries, MCP servers, and
32
+ * `stigmer.ai/*` metadata keys such as the embedder session context).
33
+ * To change only the subject, prefer the field-level
34
+ * `session.updateSubject()` RPC instead of this hook.
34
35
  *
35
36
  * Typically composed into higher-level hooks like
36
- * {@link useSessionConversation} (whose update path round-trips the
37
- * fetched spec) rather than used directly. Platform builders who need
38
- * direct session mutation can use this hook standalone.
37
+ * {@link useSessionConversation} (whose update path spreads the mapper
38
+ * over a freshly fetched session) rather than used directly. Platform
39
+ * builders who need direct session mutation can use this hook
40
+ * standalone.
39
41
  *
40
42
  * @example
41
43
  * ```tsx
44
+ * import { toSessionUpdateInput } from "@stigmer/sdk";
45
+ *
42
46
  * function TagSession({ session }: { session: Session }) {
43
47
  * const { update, isUpdating } = useUpdateSession();
44
48
  *
45
49
  * async function handleTag() {
46
- * const spec = session.spec;
50
+ * const mapped = toSessionUpdateInput(session);
47
51
  * await update({
48
- * name: session.metadata!.name,
49
- * org: session.metadata!.org,
50
- * // Full replace: carry over every fetched spec field...
51
- * agentInstanceId: spec?.agentInstanceId,
52
- * subject: spec?.subject,
53
- * harnessStateId: spec?.harnessStateId,
54
- * harness: spec?.harness,
55
- * cursorMode: spec?.cursorMode,
56
- * executionTarget: spec?.executionTarget,
57
- * // ...including the spec lists (workspaceEntries, mcpServerUsages,
58
- * // skillRefs), converted from the fetched proto exactly as
59
- * // useSessionConversation's update path does...
60
- * // ...then apply the one change on top of the carried metadata.
61
- * metadata: { ...spec?.metadata, "acme/reviewed": "true" },
52
+ * ...mapped,
53
+ * // Nested values follow the same rule: spread the mapper's
54
+ * // complete value, then apply the one change on top.
55
+ * metadata: { ...mapped.metadata, "acme/reviewed": "true" },
62
56
  * });
63
57
  * }
64
58
  *
@@ -0,0 +1,25 @@
1
+ "use client";
2
+
3
+ import { useId } from "react";
4
+ import { AccountPreferencesPanel } from "../identity-account/AccountPreferencesPanel.js";
5
+
6
+ /** Settings section for editing the current user's declared preferences. */
7
+ export function AccountPreferencesSection() {
8
+ const headingId = useId();
9
+
10
+ return (
11
+ <section aria-labelledby={headingId}>
12
+ <h2
13
+ id={headingId}
14
+ className="stg:text-foreground stg:mb-1 stg:text-sm stg:font-semibold"
15
+ >
16
+ Account Preferences
17
+ </h2>
18
+ <p className="stg:text-muted-foreground stg:mb-6 stg:text-xs">
19
+ Personal standing context shared with agents on executions you run.
20
+ </p>
21
+
22
+ <AccountPreferencesPanel />
23
+ </section>
24
+ );
25
+ }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import { useId } from "react";
4
+ import { OrgPreferencesPanel } from "../organization/OrgPreferencesPanel.js";
5
+ import { useOrg } from "../organization/OrgProvider.js";
6
+
7
+ /** Settings section for editing the active organization's declared preferences. */
8
+ export function OrgPreferencesSection() {
9
+ const headingId = useId();
10
+ const { activeOrg } = useOrg();
11
+ const orgId = activeOrg?.metadata?.id ?? "";
12
+
13
+ return (
14
+ <section aria-labelledby={headingId}>
15
+ <h2
16
+ id={headingId}
17
+ className="stg:text-foreground stg:mb-1 stg:text-sm stg:font-semibold"
18
+ >
19
+ Organization Preferences
20
+ </h2>
21
+ <p className="stg:text-muted-foreground stg:mb-6 stg:text-xs">
22
+ Standing context shared with agents on every execution run by this
23
+ organization&apos;s members.
24
+ </p>
25
+
26
+ {!orgId ? (
27
+ <p className="stg:text-muted-foreground stg:py-4 stg:text-center stg:text-xs">
28
+ Select an organization to view its preferences.
29
+ </p>
30
+ ) : (
31
+ <OrgPreferencesPanel orgId={orgId} />
32
+ )}
33
+ </section>
34
+ );
35
+ }
@@ -0,0 +1,27 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { SETTINGS_NAV_GROUPS } from "../settings-nav";
3
+
4
+ // The nav model is the single source for the sidebar AND both client-app
5
+ // landing grids — these entries disappearing would silently orphan the
6
+ // preference pages everywhere at once.
7
+ describe("SETTINGS_NAV_GROUPS preference entries", () => {
8
+ it("lists org preferences in the Organization group", () => {
9
+ const organization = SETTINGS_NAV_GROUPS.find(
10
+ (g) => g.label === "Organization",
11
+ );
12
+ expect(organization).toBeDefined();
13
+ expect(
14
+ organization!.items.find((i) => i.href === "/settings/org-preferences")
15
+ ?.label,
16
+ ).toBe("Preferences");
17
+ });
18
+
19
+ it("lists account preferences in the Account group", () => {
20
+ const account = SETTINGS_NAV_GROUPS.find((g) => g.label === "Account");
21
+ expect(account).toBeDefined();
22
+ expect(
23
+ account!.items.find((i) => i.href === "/settings/account-preferences")
24
+ ?.label,
25
+ ).toBe("Preferences");
26
+ });
27
+ });
@@ -10,6 +10,8 @@ export { BillingSection } from "./BillingSection.js";
10
10
  export type { BillingSectionProps } from "./BillingSection.js";
11
11
  export { MembersSection } from "./MembersSection.js";
12
12
  export { OrgProfileSection } from "./OrgProfileSection.js";
13
+ export { OrgPreferencesSection } from "./OrgPreferencesSection.js";
14
+ export { AccountPreferencesSection } from "./AccountPreferencesSection.js";
13
15
  export { EnvironmentsSection } from "./EnvironmentsSection.js";
14
16
  export { InvitationsSection } from "./InvitationsSection.js";
15
17
  export { IdentityProvidersSection } from "./IdentityProvidersSection.js";
@@ -13,6 +13,8 @@ import {
13
13
  Plug,
14
14
  Scale,
15
15
  ShieldCheck,
16
+ SlidersHorizontal,
17
+ UserCog,
16
18
  Users,
17
19
  } from "lucide-react";
18
20
 
@@ -55,6 +57,11 @@ export const SETTINGS_NAV_GROUPS: readonly SettingsNavGroup[] = [
55
57
  "Manage your team, organization identity, and identity providers.",
56
58
  items: [
57
59
  { href: "/settings/org-profile", label: "Org Profile", icon: Building2 },
60
+ {
61
+ href: "/settings/org-preferences",
62
+ label: "Preferences",
63
+ icon: SlidersHorizontal,
64
+ },
58
65
  { href: "/settings/members", label: "Members", icon: Users },
59
66
  { href: "/settings/invitations", label: "Invitations", icon: Link },
60
67
  {
@@ -92,6 +99,17 @@ export const SETTINGS_NAV_GROUPS: readonly SettingsNavGroup[] = [
92
99
  { href: "/settings/usage", label: "Usage", icon: BarChart3 },
93
100
  ],
94
101
  },
102
+ {
103
+ label: "Account",
104
+ description: "Personal settings that apply to you across the platform.",
105
+ items: [
106
+ {
107
+ href: "/settings/account-preferences",
108
+ label: "Preferences",
109
+ icon: UserCog,
110
+ },
111
+ ],
112
+ },
95
113
  ];
96
114
 
97
115
  /**
@@ -24,11 +24,17 @@ interface FormFieldEntry {
24
24
  enumValues: string;
25
25
  }
26
26
 
27
+ // ESCALATE carries the outcome-by-name contract (stigmer/stigmer#781): the
28
+ // timeout resolves to the outcome NAMED "escalate" and follows its routing,
29
+ // so the gate must declare that outcome — no extra config fields (the
30
+ // pre-#779 option wrote an `escalation_task` field the proto never had).
31
+ // The builder hints when the outcome is missing; the server validator is
32
+ // the enforcement.
27
33
  const TIMEOUT_POLICY_OPTIONS = [
28
34
  { value: "HUMAN_INPUT_TIMEOUT_FAIL", label: "Fail — task errors on timeout" },
29
35
  { value: "HUMAN_INPUT_TIMEOUT_APPROVE", label: "Auto-approve — proceed as approved" },
30
36
  { value: "HUMAN_INPUT_TIMEOUT_DENY", label: "Auto-deny — proceed as denied" },
31
- { value: "HUMAN_INPUT_TIMEOUT_ESCALATE", label: "Escalate — branch to escalation task" },
37
+ { value: "HUMAN_INPUT_TIMEOUT_ESCALATE", label: "Escalate — route via the 'escalate' outcome" },
32
38
  ] as const;
33
39
 
34
40
  const TIMEOUT_UNITS = [
@@ -107,8 +113,7 @@ export const ApprovalFormBuilder = memo(function ApprovalFormBuilder({
107
113
  <TimeoutSection
108
114
  timeout={typeof cfg.timeout === "number" ? cfg.timeout : 0}
109
115
  onTimeout={typeof cfg.on_timeout === "string" ? cfg.on_timeout : ""}
110
- escalationTask={typeof cfg.escalation_task === "string" ? cfg.escalation_task : ""}
111
- allTaskNames={allTaskNames}
116
+ hasEscalateOutcome={extractOutcomes(cfg).some((o) => o.name === "escalate")}
112
117
  onUpdateConfig={onUpdateConfig}
113
118
  />
114
119
  <StringListSection
@@ -619,14 +624,12 @@ function FormFieldRow({
619
624
  function TimeoutSection({
620
625
  timeout,
621
626
  onTimeout,
622
- escalationTask,
623
- allTaskNames,
627
+ hasEscalateOutcome,
624
628
  onUpdateConfig,
625
629
  }: {
626
630
  timeout: number;
627
631
  onTimeout: string;
628
- escalationTask: string;
629
- allTaskNames: readonly string[];
632
+ hasEscalateOutcome: boolean;
630
633
  onUpdateConfig: (fieldPath: string, value: unknown) => void;
631
634
  }) {
632
635
  const bestUnit = useMemo(() => {
@@ -665,8 +668,6 @@ function TimeoutSection({
665
668
  [timeout, unit, onUpdateConfig],
666
669
  );
667
670
 
668
- const isEscalate = onTimeout === "HUMAN_INPUT_TIMEOUT_ESCALATE";
669
-
670
671
  return (
671
672
  <CollapsibleSection title="Timeout">
672
673
  <div className="stg:flex stg:items-center stg:gap-1">
@@ -707,27 +708,19 @@ function TimeoutSection({
707
708
  <option key={opt.value} value={opt.value}>{opt.label}</option>
708
709
  ))}
709
710
  </select>
711
+ {onTimeout === "HUMAN_INPUT_TIMEOUT_ESCALATE" && !hasEscalateOutcome && (
712
+ <p
713
+ role="alert"
714
+ className="stg:text-[10px] stg:text-[var(--stgm-warning,#d97706)]"
715
+ >
716
+ Escalate needs an outcome named &quot;escalate&quot; with routing —
717
+ the timeout resolves to it. Add the outcome above, or the server
718
+ will reject this workflow.
719
+ </p>
720
+ )}
710
721
  </div>
711
722
  )}
712
723
 
713
- {isEscalate && (
714
- <div className="stg:mt-1.5 stg:flex stg:flex-col stg:gap-1">
715
- <label className="stg:text-[10px] stg:text-[var(--stgm-muted-foreground,#737373)]">
716
- Escalation task
717
- </label>
718
- <select
719
- value={escalationTask}
720
- onChange={(e) => onUpdateConfig("escalation_task", e.target.value || undefined)}
721
- className={cn(smallInputClass)}
722
- aria-label="Escalation target task"
723
- >
724
- <option value="">— Select escalation task —</option>
725
- {allTaskNames.map((name) => (
726
- <option key={name} value={name}>{name}</option>
727
- ))}
728
- </select>
729
- </div>
730
- )}
731
724
  </CollapsibleSection>
732
725
  );
733
726
  }
@@ -9,7 +9,7 @@ import { ValidationState } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/
9
9
  import type { WorkflowInput } from "@stigmer/sdk";
10
10
  import { useWorkflow } from "./useWorkflow.js";
11
11
  import { useUpdateWorkflow } from "./useUpdateWorkflow.js";
12
- import { workflowToInput } from "./internal/workflowToInput.js";
12
+ import { toWorkflowUpdateInput } from "@stigmer/sdk";
13
13
  import { useWorkflowExecutionList } from "./useWorkflowExecutionList.js";
14
14
  import { useWorkflowDashboardSummary } from "./useWorkflowDashboardSummary.js";
15
15
  import { WorkflowOverviewGraph } from "./WorkflowOverviewGraph.js";
@@ -189,7 +189,7 @@ export function WorkflowDetailView({
189
189
  value: WorkflowInput[K],
190
190
  ): Promise<boolean> => {
191
191
  if (!workflow) return false;
192
- const input = workflowToInput(workflow);
192
+ const input = toWorkflowUpdateInput(workflow);
193
193
  (input as unknown as Record<string, unknown>)[field] = value;
194
194
  try {
195
195
  const updated = await update(input);
@@ -0,0 +1,83 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
3
+ import { create } from "@bufbuild/protobuf";
4
+ import {
5
+ WorkflowInstanceSchema,
6
+ type WorkflowInstance,
7
+ } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/api_pb";
8
+ import { WorkflowExecutionVisibility } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/spec_pb";
9
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
10
+ import type { WorkflowInstanceInput } from "@stigmer/sdk";
11
+ import { StigmerContext } from "../../context";
12
+ import { WorkflowInstanceDetailPanel } from "../instance/WorkflowInstanceDetailPanel";
13
+
14
+ /**
15
+ * Regression suite for the full-spec-replace wipe bug: before the
16
+ * generated-mapper migration, saving environment edits in this panel
17
+ * silently reset `execution_visibility` (run observability, which has its
18
+ * own dedicated updateExecutionVisibility RPC and control). The panel
19
+ * must spread `toWorkflowInstanceUpdateInput` and override only the
20
+ * environment refs.
21
+ */
22
+
23
+ const INSTANCE: WorkflowInstance = create(WorkflowInstanceSchema, {
24
+ metadata: {
25
+ id: "wfi-1",
26
+ name: "Nightly Triage",
27
+ slug: "nightly-triage",
28
+ org: "acme",
29
+ },
30
+ spec: {
31
+ workflowId: "wf-1",
32
+ description: "Runs every night.",
33
+ environmentRefs: [
34
+ { org: "acme", slug: "prod", kind: ApiResourceKind.environment },
35
+ ],
36
+ executionVisibility: WorkflowExecutionVisibility.organization,
37
+ },
38
+ });
39
+
40
+ function renderPanel(update: ReturnType<typeof vi.fn>) {
41
+ const client = {
42
+ workflowInstance: { update },
43
+ iamPolicy: {
44
+ checkMyPermission: vi.fn(async () => ({ isAuthorized: true })),
45
+ },
46
+ environment: {
47
+ list: vi.fn(async () => ({ items: [], totalCount: 0 })),
48
+ },
49
+ } as never;
50
+ return render(
51
+ <StigmerContext.Provider value={client}>
52
+ <WorkflowInstanceDetailPanel instance={INSTANCE} org="acme" onClose={() => {}} />
53
+ </StigmerContext.Provider>,
54
+ );
55
+ }
56
+
57
+ afterEach(cleanup);
58
+
59
+ describe("WorkflowInstanceDetailPanel save payload", () => {
60
+ it("round-trips execution_visibility on an environments-only save (the wipe bug)", async () => {
61
+ const update = vi.fn(async (_input: WorkflowInstanceInput) => INSTANCE);
62
+ renderPanel(update);
63
+
64
+ fireEvent.click(await screen.findByRole("button", { name: "Edit" }));
65
+ fireEvent.click(screen.getByRole("button", { name: "Save" }));
66
+
67
+ await waitFor(() => expect(update).toHaveBeenCalledTimes(1));
68
+ const input = update.mock.calls[0]![0];
69
+
70
+ // The wipe-bug guard: run visibility is edited elsewhere and must
71
+ // survive an environment save untouched.
72
+ expect(input.executionVisibility).toBe(
73
+ WorkflowExecutionVisibility.organization,
74
+ );
75
+ expect(input.workflowId).toBe("wf-1");
76
+ expect(input.description).toBe("Runs every night.");
77
+ // The form-owned field.
78
+ expect(input.environmentRefs).toEqual([{ org: "acme", slug: "prod" }]);
79
+ // Addressing fields.
80
+ expect(input.org).toBe("acme");
81
+ expect(input.slug).toBe("nightly-triage");
82
+ });
83
+ });
@@ -481,8 +481,6 @@ export {
481
481
  type UseUpdateWorkflowReturn,
482
482
  } from "./useUpdateWorkflow.js";
483
483
 
484
- export { workflowToInput } from "./internal/workflowToInput.js";
485
-
486
484
  // Starter YAML template for new workflow creation
487
485
  export { STARTER_WORKFLOW_YAML } from "./starter-workflow-yaml.js";
488
486
 
@@ -9,7 +9,7 @@ import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apires
9
9
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
10
10
  import { WorkflowExecutionVisibility } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/spec_pb";
11
11
  import type { ResourceRef } from "@stigmer/sdk";
12
- import { getUserMessage } from "@stigmer/sdk";
12
+ import { getUserMessage, toWorkflowInstanceUpdateInput } from "@stigmer/sdk";
13
13
  import { useUpdateWorkflowInstance } from "./useUpdateWorkflowInstance.js";
14
14
  import { useDeleteWorkflowInstance } from "./useDeleteWorkflowInstance.js";
15
15
  import { RunVisibilityControl } from "./RunVisibilityControl.js";
@@ -104,20 +104,19 @@ export function WorkflowInstanceDetailPanel({
104
104
 
105
105
  const handleSaveEnvs = useCallback(async () => {
106
106
  try {
107
+ // Full-spec-replace safety: spread the complete mapped input so
108
+ // unlisted spec fields (e.g. execution_visibility, which has its
109
+ // own dedicated control above) survive an environment-only save.
107
110
  await update({
108
- name: meta?.name ?? "",
109
- org: meta?.org ?? org,
110
- workflowId: spec?.workflowId ?? "",
111
- description: spec?.description,
111
+ ...toWorkflowInstanceUpdateInput(instance),
112
112
  environmentRefs: editEnvRefs,
113
- visibility: meta?.visibility,
114
113
  });
115
114
  setIsEditingEnvs(false);
116
115
  onUpdated?.();
117
116
  } catch {
118
117
  // error displayed by hook
119
118
  }
120
- }, [update, meta, spec, org, editEnvRefs, onUpdated]);
119
+ }, [update, instance, editEnvRefs, onUpdated]);
121
120
 
122
121
  const handleDelete = useCallback(async () => {
123
122
  setDeleteError(null);
@@ -23,9 +23,9 @@ export interface UseUpdateWorkflowReturn {
23
23
  *
24
24
  * Wraps `stigmer.workflow.update(input)` with loading and error state.
25
25
  * The caller must provide a **complete** `WorkflowInput` -- the backend
26
- * performs full spec replacement. Use `workflowToInput()` to reconstruct
27
- * the input from a fetched workflow, modify the desired field, and pass
28
- * the result here.
26
+ * performs full spec replacement. Use `toWorkflowUpdateInput()` (from
27
+ * `@stigmer/sdk`) to reconstruct the input from a fetched workflow,
28
+ * modify the desired field, and pass the result here.
29
29
  */
30
30
  export function useUpdateWorkflow(): UseUpdateWorkflowReturn {
31
31
  const stigmer = useStigmer();