@stigmer/react 3.12.5 → 3.12.7

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 (329) 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/channel/AgentChannelsPanel.d.ts.map +1 -1
  15. package/channel/AgentChannelsPanel.js +10 -5
  16. package/channel/AgentChannelsPanel.js.map +1 -1
  17. package/channel/ChannelRunConfigDialog.d.ts +51 -0
  18. package/channel/ChannelRunConfigDialog.d.ts.map +1 -0
  19. package/channel/ChannelRunConfigDialog.js +121 -0
  20. package/channel/ChannelRunConfigDialog.js.map +1 -0
  21. package/channel/index.d.ts +2 -0
  22. package/channel/index.d.ts.map +1 -1
  23. package/channel/index.js +1 -0
  24. package/channel/index.js.map +1 -1
  25. package/channel/useSaveAgentChannel.d.ts.map +1 -1
  26. package/channel/useSaveAgentChannel.js +6 -3
  27. package/channel/useSaveAgentChannel.js.map +1 -1
  28. package/channel-app/ChannelAppDetailPanel.js +9 -9
  29. package/channel-app/ChannelAppDetailPanel.js.map +1 -1
  30. package/composer/ComposerToolbar.d.ts +24 -1
  31. package/composer/ComposerToolbar.d.ts.map +1 -1
  32. package/composer/ComposerToolbar.js +7 -2
  33. package/composer/ComposerToolbar.js.map +1 -1
  34. package/composer/SessionComposer.d.ts +19 -0
  35. package/composer/SessionComposer.d.ts.map +1 -1
  36. package/composer/SessionComposer.js +24 -5
  37. package/composer/SessionComposer.js.map +1 -1
  38. package/composer/index.d.ts +1 -0
  39. package/composer/index.d.ts.map +1 -1
  40. package/composer/index.js.map +1 -1
  41. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
  42. package/cursor-accounts/CursorAccountsConsole.js +12 -3
  43. package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
  44. package/cursor-accounts/cursor-account-coverage.d.ts +30 -1
  45. package/cursor-accounts/cursor-account-coverage.d.ts.map +1 -1
  46. package/cursor-accounts/cursor-account-coverage.js +21 -0
  47. package/cursor-accounts/cursor-account-coverage.js.map +1 -1
  48. package/execution/MessageThread.d.ts.map +1 -1
  49. package/execution/MessageThread.js +8 -11
  50. package/execution/MessageThread.js.map +1 -1
  51. package/execution/useCreateAgentExecution.d.ts +15 -0
  52. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  53. package/execution/useCreateAgentExecution.js +5 -0
  54. package/execution/useCreateAgentExecution.js.map +1 -1
  55. package/execution/useFileChangeContent.d.ts +2 -6
  56. package/execution/useFileChangeContent.d.ts.map +1 -1
  57. package/execution/useFileChangeContent.js +4 -12
  58. package/execution/useFileChangeContent.js.map +1 -1
  59. package/identity-account/AccountPreferencesPanel.d.ts +2 -1
  60. package/identity-account/AccountPreferencesPanel.d.ts.map +1 -1
  61. package/identity-account/AccountPreferencesPanel.js +33 -18
  62. package/identity-account/AccountPreferencesPanel.js.map +1 -1
  63. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  64. package/identity-provider/IdentityProviderDetailPanel.js +16 -15
  65. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  66. package/index.d.ts +10 -7
  67. package/index.d.ts.map +1 -1
  68. package/index.js +8 -4
  69. package/index.js.map +1 -1
  70. package/internal/download.d.ts +8 -0
  71. package/internal/download.d.ts.map +1 -0
  72. package/internal/download.js +25 -0
  73. package/internal/download.js.map +1 -0
  74. package/library/useExportResource.d.ts.map +1 -1
  75. package/library/useExportResource.js +3 -17
  76. package/library/useExportResource.js.map +1 -1
  77. package/mcp-server/McpServerDetailView.js +2 -2
  78. package/mcp-server/McpServerDetailView.js.map +1 -1
  79. package/mcp-server/index.d.ts +0 -1
  80. package/mcp-server/index.d.ts.map +1 -1
  81. package/mcp-server/index.js +0 -1
  82. package/mcp-server/index.js.map +1 -1
  83. package/mcp-server/internal/definitionDrift.d.ts +14 -12
  84. package/mcp-server/internal/definitionDrift.d.ts.map +1 -1
  85. package/mcp-server/internal/definitionDrift.js +22 -19
  86. package/mcp-server/internal/definitionDrift.js.map +1 -1
  87. package/mcp-server/useUpdateMcpServer.d.ts +3 -3
  88. package/mcp-server/useUpdateMcpServer.js +3 -3
  89. package/memory/MemoryListPanel.d.ts +35 -0
  90. package/memory/MemoryListPanel.d.ts.map +1 -0
  91. package/memory/MemoryListPanel.js +141 -0
  92. package/memory/MemoryListPanel.js.map +1 -0
  93. package/memory/index.d.ts +8 -0
  94. package/memory/index.d.ts.map +1 -0
  95. package/memory/index.js +12 -0
  96. package/memory/index.js.map +1 -0
  97. package/memory/memoryGroups.d.ts +31 -0
  98. package/memory/memoryGroups.d.ts.map +1 -0
  99. package/memory/memoryGroups.js +52 -0
  100. package/memory/memoryGroups.js.map +1 -0
  101. package/memory/useConfirmMemory.d.ts +31 -0
  102. package/memory/useConfirmMemory.d.ts.map +1 -0
  103. package/memory/useConfirmMemory.js +43 -0
  104. package/memory/useConfirmMemory.js.map +1 -0
  105. package/memory/useDeleteMemory.d.ts +30 -0
  106. package/memory/useDeleteMemory.d.ts.map +1 -0
  107. package/memory/useDeleteMemory.js +42 -0
  108. package/memory/useDeleteMemory.js.map +1 -0
  109. package/memory/useMemories.d.ts +33 -0
  110. package/memory/useMemories.d.ts.map +1 -0
  111. package/memory/useMemories.js +42 -0
  112. package/memory/useMemories.js.map +1 -0
  113. package/memory/useRejectMemory.d.ts +34 -0
  114. package/memory/useRejectMemory.d.ts.map +1 -0
  115. package/memory/useRejectMemory.js +46 -0
  116. package/memory/useRejectMemory.js.map +1 -0
  117. package/memory/useUpdateMemoryContent.d.ts +32 -0
  118. package/memory/useUpdateMemoryContent.d.ts.map +1 -0
  119. package/memory/useUpdateMemoryContent.js +48 -0
  120. package/memory/useUpdateMemoryContent.js.map +1 -0
  121. package/models/ModelSelector.d.ts +33 -1
  122. package/models/ModelSelector.d.ts.map +1 -1
  123. package/models/ModelSelector.js +37 -4
  124. package/models/ModelSelector.js.map +1 -1
  125. package/models/index.d.ts +2 -0
  126. package/models/index.d.ts.map +1 -1
  127. package/models/index.js +1 -0
  128. package/models/index.js.map +1 -1
  129. package/models/registry.d.ts +16 -0
  130. package/models/registry.d.ts.map +1 -1
  131. package/models/registry.js +13 -0
  132. package/models/registry.js.map +1 -1
  133. package/models/thinking-mode.d.ts +27 -0
  134. package/models/thinking-mode.d.ts.map +1 -0
  135. package/models/thinking-mode.js +32 -0
  136. package/models/thinking-mode.js.map +1 -0
  137. package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
  138. package/oauth-app/OAuthAppDetailPanel.js +21 -20
  139. package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
  140. package/package.json +4 -4
  141. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
  142. package/platform-client/PlatformClientDetailPanel.js +12 -13
  143. package/platform-client/PlatformClientDetailPanel.js.map +1 -1
  144. package/schedule/ScheduleDetailView.d.ts.map +1 -1
  145. package/schedule/ScheduleDetailView.js +21 -10
  146. package/schedule/ScheduleDetailView.js.map +1 -1
  147. package/schedule/ScheduleForm.d.ts.map +1 -1
  148. package/schedule/ScheduleForm.js +13 -3
  149. package/schedule/ScheduleForm.js.map +1 -1
  150. package/session/NewSessionViewer.d.ts.map +1 -1
  151. package/session/NewSessionViewer.js +9 -1
  152. package/session/NewSessionViewer.js.map +1 -1
  153. package/session/SessionViewer.d.ts +14 -1
  154. package/session/SessionViewer.d.ts.map +1 -1
  155. package/session/SessionViewer.js +21 -25
  156. package/session/SessionViewer.js.map +1 -1
  157. package/session/TranscriptExportMenu.d.ts +24 -0
  158. package/session/TranscriptExportMenu.d.ts.map +1 -0
  159. package/session/TranscriptExportMenu.js +26 -0
  160. package/session/TranscriptExportMenu.js.map +1 -0
  161. package/session/index.d.ts +4 -0
  162. package/session/index.d.ts.map +1 -1
  163. package/session/index.js +2 -0
  164. package/session/index.js.map +1 -1
  165. package/session/run-config.d.ts +9 -0
  166. package/session/run-config.d.ts.map +1 -1
  167. package/session/run-config.js +5 -0
  168. package/session/run-config.js.map +1 -1
  169. package/session/useExportTranscript.d.ts +44 -0
  170. package/session/useExportTranscript.d.ts.map +1 -0
  171. package/session/useExportTranscript.js +109 -0
  172. package/session/useExportTranscript.js.map +1 -0
  173. package/session/useNewSessionFlow.d.ts +11 -0
  174. package/session/useNewSessionFlow.d.ts.map +1 -1
  175. package/session/useNewSessionFlow.js +20 -6
  176. package/session/useNewSessionFlow.js.map +1 -1
  177. package/session/useSessionConversation.d.ts +12 -1
  178. package/session/useSessionConversation.d.ts.map +1 -1
  179. package/session/useSessionConversation.js +21 -42
  180. package/session/useSessionConversation.js.map +1 -1
  181. package/session/useSessionExecutions.d.ts +2 -14
  182. package/session/useSessionExecutions.d.ts.map +1 -1
  183. package/session/useSessionExecutions.js +4 -26
  184. package/session/useSessionExecutions.js.map +1 -1
  185. package/session/useSessionPageFlow.d.ts +23 -10
  186. package/session/useSessionPageFlow.d.ts.map +1 -1
  187. package/session/useSessionPageFlow.js +75 -19
  188. package/session/useSessionPageFlow.js.map +1 -1
  189. package/session/useUpdateSession.d.ts +18 -24
  190. package/session/useUpdateSession.d.ts.map +1 -1
  191. package/session/useUpdateSession.js +18 -24
  192. package/session/useUpdateSession.js.map +1 -1
  193. package/settings/MemorySection.d.ts +12 -0
  194. package/settings/MemorySection.d.ts.map +1 -0
  195. package/settings/MemorySection.js +21 -0
  196. package/settings/MemorySection.js.map +1 -0
  197. package/settings/index.d.ts +1 -0
  198. package/settings/index.d.ts.map +1 -1
  199. package/settings/index.js +1 -0
  200. package/settings/index.js.map +1 -1
  201. package/settings/settings-nav.d.ts.map +1 -1
  202. package/settings/settings-nav.js +2 -1
  203. package/settings/settings-nav.js.map +1 -1
  204. package/src/__tests__/public-api.test.ts +21 -0
  205. package/src/agent/AgentDetailView.tsx +2 -2
  206. package/src/agent/index.ts +0 -2
  207. package/src/agent/useUpdateAgent.ts +3 -3
  208. package/src/agent-instance/AgentInstanceDetailPanel.tsx +5 -7
  209. package/src/agent-instance/__tests__/AgentInstanceDetailPanel.test.tsx +75 -0
  210. package/src/agent-instance/useUpdateAgentInstance.ts +1 -1
  211. package/src/channel/AgentChannelsPanel.tsx +26 -1
  212. package/src/channel/ChannelRunConfigDialog.tsx +351 -0
  213. package/src/channel/__tests__/ChannelRunConfigDialog.test.tsx +210 -0
  214. package/src/channel/index.ts +2 -0
  215. package/src/channel/useSaveAgentChannel.ts +6 -3
  216. package/src/channel-app/ChannelAppDetailPanel.tsx +9 -9
  217. package/src/channel-app/__tests__/channelAppWhatsApp.test.tsx +2 -0
  218. package/src/channel-app/__tests__/channelAppWipeSafety.test.tsx +87 -0
  219. package/src/composer/ComposerToolbar.tsx +67 -0
  220. package/src/composer/SessionComposer.tsx +49 -3
  221. package/src/composer/__tests__/ComposerToolbar-autoApprove.test.tsx +80 -0
  222. package/src/composer/__tests__/SessionComposer-thinkingMode.test.tsx +176 -0
  223. package/src/composer/index.ts +1 -0
  224. package/src/cursor-accounts/CursorAccountsConsole.tsx +40 -5
  225. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +32 -0
  226. package/src/cursor-accounts/__tests__/cursor-account-coverage.test.ts +58 -1
  227. package/src/cursor-accounts/cursor-account-coverage.ts +55 -0
  228. package/src/execution/MessageThread.tsx +8 -11
  229. package/src/execution/useCreateAgentExecution.ts +19 -0
  230. package/src/execution/useFileChangeContent.ts +5 -12
  231. package/src/identity-account/AccountPreferencesPanel.tsx +154 -68
  232. package/src/identity-account/__tests__/AccountPreferencesPanel.test.tsx +36 -2
  233. package/src/identity-provider/IdentityProviderDetailPanel.tsx +18 -15
  234. package/src/identity-provider/__tests__/IdentityProviderDetailPanel.test.tsx +80 -0
  235. package/src/index.ts +36 -2
  236. package/src/internal/download.ts +29 -0
  237. package/src/library/useExportResource.ts +3 -19
  238. package/src/mcp-server/McpServerDetailView.tsx +2 -2
  239. package/src/mcp-server/index.ts +0 -2
  240. package/src/mcp-server/internal/definitionDrift.ts +22 -20
  241. package/src/mcp-server/useUpdateMcpServer.ts +3 -3
  242. package/src/memory/MemoryListPanel.tsx +532 -0
  243. package/src/memory/__tests__/MemoryListPanel.test.tsx +259 -0
  244. package/src/memory/__tests__/memoryHooks.test.tsx +220 -0
  245. package/src/memory/index.ts +19 -0
  246. package/src/memory/memoryGroups.ts +64 -0
  247. package/src/memory/useConfirmMemory.ts +62 -0
  248. package/src/memory/useDeleteMemory.ts +61 -0
  249. package/src/memory/useMemories.ts +66 -0
  250. package/src/memory/useRejectMemory.ts +65 -0
  251. package/src/memory/useUpdateMemoryContent.ts +67 -0
  252. package/src/models/ModelSelector.tsx +94 -1
  253. package/src/models/index.ts +2 -0
  254. package/src/models/registry.ts +29 -0
  255. package/src/models/thinking-mode.ts +48 -0
  256. package/src/oauth-app/OAuthAppDetailPanel.tsx +23 -21
  257. package/src/oauth-app/__tests__/OAuthAppDetailPanel.test.tsx +94 -0
  258. package/src/platform-client/PlatformClientDetailPanel.tsx +14 -13
  259. package/src/platform-client/__tests__/PlatformClientDetailPanel.test.tsx +82 -0
  260. package/src/schedule/ScheduleDetailView.tsx +29 -4
  261. package/src/schedule/ScheduleForm.tsx +14 -1
  262. package/src/session/NewSessionViewer.tsx +15 -1
  263. package/src/session/SessionViewer.tsx +48 -49
  264. package/src/session/TranscriptExportMenu.tsx +78 -0
  265. package/src/session/__tests__/SessionViewer-autoApproveToggle.test.tsx +178 -0
  266. package/src/session/__tests__/SessionViewer-transcriptExport.test.tsx +151 -0
  267. package/src/session/__tests__/TranscriptExportMenu.test.tsx +97 -0
  268. package/src/session/__tests__/useExportTranscript.test.tsx +187 -0
  269. package/src/session/__tests__/useNewSessionFlow.test.tsx +33 -0
  270. package/src/session/__tests__/useSessionPageFlow.autoApprove.test.tsx +176 -2
  271. package/src/session/index.ts +9 -0
  272. package/src/session/run-config.ts +16 -0
  273. package/src/session/useExportTranscript.ts +171 -0
  274. package/src/session/useNewSessionFlow.ts +34 -7
  275. package/src/session/useSessionConversation.ts +42 -56
  276. package/src/session/useSessionExecutions.ts +5 -26
  277. package/src/session/useSessionPageFlow.ts +98 -32
  278. package/src/session/useUpdateSession.ts +18 -24
  279. package/src/settings/MemorySection.tsx +45 -0
  280. package/src/settings/index.ts +1 -0
  281. package/src/settings/settings-nav.ts +2 -0
  282. package/src/usage/useExportCSV.ts +2 -14
  283. package/src/workflow/ApprovalFormBuilder.tsx +20 -5
  284. package/src/workflow/WorkflowDetailView.tsx +2 -2
  285. package/src/workflow/__tests__/WorkflowInstanceDetailPanel.test.tsx +83 -0
  286. package/src/workflow/index.ts +0 -2
  287. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +6 -7
  288. package/src/workflow/useUpdateWorkflow.ts +3 -3
  289. package/styles.css +1 -1
  290. package/usage/useExportCSV.d.ts.map +1 -1
  291. package/usage/useExportCSV.js +2 -13
  292. package/usage/useExportCSV.js.map +1 -1
  293. package/workflow/ApprovalFormBuilder.d.ts.map +1 -1
  294. package/workflow/ApprovalFormBuilder.js +10 -8
  295. package/workflow/ApprovalFormBuilder.js.map +1 -1
  296. package/workflow/WorkflowDetailView.js +2 -2
  297. package/workflow/WorkflowDetailView.js.map +1 -1
  298. package/workflow/index.d.ts +0 -1
  299. package/workflow/index.d.ts.map +1 -1
  300. package/workflow/index.js +0 -1
  301. package/workflow/index.js.map +1 -1
  302. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  303. package/workflow/instance/WorkflowInstanceDetailPanel.js +6 -7
  304. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  305. package/workflow/useUpdateWorkflow.d.ts +3 -3
  306. package/workflow/useUpdateWorkflow.js +3 -3
  307. package/agent/internal/agentToInput.d.ts +0 -15
  308. package/agent/internal/agentToInput.d.ts.map +0 -1
  309. package/agent/internal/agentToInput.js +0 -84
  310. package/agent/internal/agentToInput.js.map +0 -1
  311. package/mcp-server/internal/mcpServerToInput.d.ts +0 -12
  312. package/mcp-server/internal/mcpServerToInput.d.ts.map +0 -1
  313. package/mcp-server/internal/mcpServerToInput.js +0 -84
  314. package/mcp-server/internal/mcpServerToInput.js.map +0 -1
  315. package/session/session-spec-converters.d.ts +0 -24
  316. package/session/session-spec-converters.d.ts.map +0 -1
  317. package/session/session-spec-converters.js +0 -72
  318. package/session/session-spec-converters.js.map +0 -1
  319. package/src/agent/internal/__tests__/agentToInput.test.ts +0 -145
  320. package/src/agent/internal/agentToInput.ts +0 -102
  321. package/src/mcp-server/__tests__/mcpServerToInput.test.ts +0 -201
  322. package/src/mcp-server/internal/mcpServerToInput.ts +0 -98
  323. package/src/session/__tests__/session-spec-converters.test.ts +0 -183
  324. package/src/session/session-spec-converters.ts +0 -86
  325. package/src/workflow/internal/workflowToInput.ts +0 -96
  326. package/workflow/internal/workflowToInput.d.ts +0 -12
  327. package/workflow/internal/workflowToInput.d.ts.map +0 -1
  328. package/workflow/internal/workflowToInput.js +0 -73
  329. package/workflow/internal/workflowToInput.js.map +0 -1
package/settings/index.js CHANGED
@@ -6,6 +6,7 @@ export { MembersSection } from "./MembersSection.js";
6
6
  export { OrgProfileSection } from "./OrgProfileSection.js";
7
7
  export { OrgPreferencesSection } from "./OrgPreferencesSection.js";
8
8
  export { AccountPreferencesSection } from "./AccountPreferencesSection.js";
9
+ export { MemorySection } from "./MemorySection.js";
9
10
  export { EnvironmentsSection } from "./EnvironmentsSection.js";
10
11
  export { InvitationsSection } from "./InvitationsSection.js";
11
12
  export { IdentityProvidersSection } from "./IdentityProvidersSection.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"settings-nav.d.ts","sourceRoot":"","sources":["../../src/settings/settings-nav.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAoB3C,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC3B,mDAAmD;QACnD,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;CAC5C;AAED,2DAA2D;AAC3D,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EA4D1D,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,EAAE,gBAwBzC,CAAC"}
1
+ {"version":3,"file":"settings-nav.d.ts","sourceRoot":"","sources":["../../src/settings/settings-nav.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAqB3C,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC3B,mDAAmD;QACnD,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;CAC5C;AAED,2DAA2D;AAC3D,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EA6D1D,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,EAAE,gBAwBzC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { Activity, AppWindow, BarChart3, Box, Building2, CreditCard, KeyRound, Link, MessageSquare, MousePointerClick, Plug, Scale, ShieldCheck, SlidersHorizontal, UserCog, Users, } from "lucide-react";
1
+ import { Activity, AppWindow, BarChart3, Box, Brain, Building2, CreditCard, KeyRound, Link, MessageSquare, MousePointerClick, Plug, Scale, ShieldCheck, SlidersHorizontal, UserCog, Users, } from "lucide-react";
2
2
  /** Canonical settings sidebar/grouped navigation model. */
3
3
  export const SETTINGS_NAV_GROUPS = [
4
4
  {
@@ -56,6 +56,7 @@ export const SETTINGS_NAV_GROUPS = [
56
56
  label: "Preferences",
57
57
  icon: UserCog,
58
58
  },
59
+ { href: "/settings/memory", label: "Memory", icon: Brain },
59
60
  ],
60
61
  },
61
62
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"settings-nav.js","sourceRoot":"","sources":["../../src/settings/settings-nav.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,GAAG,EACH,SAAS,EACT,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,aAAa,EACb,iBAAiB,EACjB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,KAAK,GACN,MAAM,cAAc,CAAC;AAiCtB,2DAA2D;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAgC;IAC9D;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,kEAAkE;QACpE,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YACxE;gBACE,IAAI,EAAE,2BAA2B;gBACjC,KAAK,EAAE,aAAa;gBACpB,IAAI,EAAE,iBAAiB;aACxB;YACD,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE;YAC5D,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE;YACnE;gBACE,IAAI,EAAE,8BAA8B;gBACpC,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,WAAW;aAClB;SACF;KACF;IACD;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,mFAAmF;QACrF,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE;YACjE;gBACE,IAAI,EAAE,4BAA4B;gBAClC,KAAK,EAAE,kBAAkB;gBACzB,IAAI,EAAE,IAAI;aACX;YACD,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE;YACpE,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE;YACtE;gBACE,IAAI,EAAE,wBAAwB;gBAC9B,KAAK,EAAE,cAAc;gBACrB,IAAI,EAAE,aAAa;aACpB;SACF;KACF;IACD;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,sCAAsC;QACnD,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;YACjE,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;SAC7D;KACF;IACD;QACE,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,0DAA0D;QACvE,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,+BAA+B;gBACrC,KAAK,EAAE,aAAa;gBACpB,IAAI,EAAE,OAAO;aACd;SACF;KACF;CACF,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAqB;IAC3D,KAAK,EAAE,UAAU;IACjB,WAAW,EACT,kEAAkE;IACpE,KAAK,EAAE;QACL;YACE,IAAI,EAAE,8BAA8B;YACpC,KAAK,EAAE,oBAAoB;YAC3B,IAAI,EAAE,KAAK;YACX,kBAAkB,EAAE,0BAA0B;SAC/C;QACD;YACE,IAAI,EAAE,2BAA2B;YACjC,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,iBAAiB;YACvB,kBAAkB,EAAE,4BAA4B;SACjD;QACD;YACE,IAAI,EAAE,6BAA6B;YACnC,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,QAAQ;YACd,kBAAkB,EAAE,4BAA4B;SACjD;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"settings-nav.js","sourceRoot":"","sources":["../../src/settings/settings-nav.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,GAAG,EACH,KAAK,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,aAAa,EACb,iBAAiB,EACjB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,KAAK,GACN,MAAM,cAAc,CAAC;AAiCtB,2DAA2D;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAgC;IAC9D;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,kEAAkE;QACpE,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YACxE;gBACE,IAAI,EAAE,2BAA2B;gBACjC,KAAK,EAAE,aAAa;gBACpB,IAAI,EAAE,iBAAiB;aACxB;YACD,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE;YAC5D,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE;YACnE;gBACE,IAAI,EAAE,8BAA8B;gBACpC,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,WAAW;aAClB;SACF;KACF;IACD;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,mFAAmF;QACrF,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE;YACjE;gBACE,IAAI,EAAE,4BAA4B;gBAClC,KAAK,EAAE,kBAAkB;gBACzB,IAAI,EAAE,IAAI;aACX;YACD,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE;YACpE,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE;YACtE;gBACE,IAAI,EAAE,wBAAwB;gBAC9B,KAAK,EAAE,cAAc;gBACrB,IAAI,EAAE,aAAa;aACpB;SACF;KACF;IACD;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,sCAAsC;QACnD,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;YACjE,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;SAC7D;KACF;IACD;QACE,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,0DAA0D;QACvE,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,+BAA+B;gBACrC,KAAK,EAAE,aAAa;gBACpB,IAAI,EAAE,OAAO;aACd;YACD,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE;SAC3D;KACF;CACF,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAqB;IAC3D,KAAK,EAAE,UAAU;IACjB,WAAW,EACT,kEAAkE;IACpE,KAAK,EAAE;QACL;YACE,IAAI,EAAE,8BAA8B;YACpC,KAAK,EAAE,oBAAoB;YAC3B,IAAI,EAAE,KAAK;YACX,kBAAkB,EAAE,0BAA0B;SAC/C;QACD;YACE,IAAI,EAAE,2BAA2B;YACjC,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,iBAAiB;YACvB,kBAAkB,EAAE,4BAA4B;SACjD;QACD;YACE,IAAI,EAAE,6BAA6B;YACnC,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,QAAQ;YACd,kBAAkB,EAAE,4BAA4B;SACjD;KACF;CACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import type { SessionRunConfig } from "../index.js";
4
+
5
+ // Root-surface pin (oss#802): the package's exports map exposes only the root
6
+ // barrel, so a type an embedder must name has to be re-exported from
7
+ // src/index.ts. The type-only import above is enforced by the typecheck gate
8
+ // (`tsc --noEmit`), which fails this file if the root export regresses —
9
+ // vitest alone would not catch it (esbuild strips types unchecked).
10
+ describe("public API surface", () => {
11
+ it("SessionRunConfig is importable from the package root", () => {
12
+ // Compile-time is the real assertion; construct a value against the type
13
+ // so the import cannot be flagged unused.
14
+ const pinned: SessionRunConfig = {
15
+ modelName: "claude-opus-5",
16
+ serviceTier: "fast",
17
+ thinkingMode: "enabled",
18
+ };
19
+ expect(pinned.modelName).toBe("claude-opus-5");
20
+ });
21
+ });
@@ -13,7 +13,7 @@ import type { AgentInstance } from "@stigmer/protos/ai/stigmer/agentic/agentinst
13
13
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
14
14
  import { useAgent } from "./useAgent.js";
15
15
  import { useUpdateAgent } from "./useUpdateAgent.js";
16
- import { agentToInput } from "./internal/agentToInput.js";
16
+ import { toAgentUpdateInput } from "@stigmer/sdk";
17
17
  import { toError } from "../internal/toError.js";
18
18
  import { ErrorMessage } from "../error/ErrorMessage.js";
19
19
  import { VisibilityBadge } from "../library/VisibilitySelector.js";
@@ -253,7 +253,7 @@ export function AgentDetailView({
253
253
  ): Promise<boolean> => {
254
254
  if (!agent) return false;
255
255
  setSaveError(null);
256
- const input = agentToInput(agent);
256
+ const input = toAgentUpdateInput(agent);
257
257
  (input as unknown as Record<string, unknown>)[field] = value;
258
258
  try {
259
259
  const updated = await update(input);
@@ -54,8 +54,6 @@ export type { UseCreateAgentReturn } from "./useCreateAgent.js";
54
54
  export { useUpdateAgent } from "./useUpdateAgent.js";
55
55
  export type { UseUpdateAgentReturn } from "./useUpdateAgent.js";
56
56
 
57
- export { agentToInput } from "./internal/agentToInput.js";
58
-
59
57
  export { AgentCreationWizard } from "./AgentCreationWizard.js";
60
58
  export type {
61
59
  AgentCreationWizardProps,
@@ -23,9 +23,9 @@ export interface UseUpdateAgentReturn {
23
23
  *
24
24
  * Wraps `stigmer.agent.update(input)` with loading and error state.
25
25
  * The caller must provide a **complete** `AgentInput` — the backend
26
- * performs full spec replacement. Use `agentToInput()` to reconstruct
27
- * the input from a fetched agent, modify the desired field, and pass
28
- * the result here.
26
+ * performs full spec replacement. Use `toAgentUpdateInput()` (from
27
+ * `@stigmer/sdk`) to reconstruct the input from a fetched agent, modify
28
+ * the desired field, and pass the result here.
29
29
  */
30
30
  export function useUpdateAgent(): UseUpdateAgentReturn {
31
31
  const stigmer = useStigmer();
@@ -8,7 +8,7 @@ import type { AgentInstance } from "@stigmer/protos/ai/stigmer/agentic/agentinst
8
8
  import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
9
9
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
10
10
  import type { ResourceRef } from "@stigmer/sdk";
11
- import { getUserMessage } from "@stigmer/sdk";
11
+ import { getUserMessage, toAgentInstanceUpdateInput } from "@stigmer/sdk";
12
12
  import { useUpdateAgentInstance } from "./useUpdateAgentInstance.js";
13
13
  import { useDeleteAgentInstance } from "./useDeleteAgentInstance.js";
14
14
  import { VisibilityBadge } from "../library/VisibilitySelector.js";
@@ -75,20 +75,18 @@ export function AgentInstanceDetailPanel({
75
75
 
76
76
  const handleSaveEnvs = useCallback(async () => {
77
77
  try {
78
+ // Full-spec-replace safety: spread the complete mapped input so
79
+ // any spec field this form does not edit survives the save.
78
80
  await update({
79
- name: meta?.name ?? "",
80
- org: meta?.org ?? org,
81
- agentId: spec?.agentId ?? "",
82
- description: spec?.description,
81
+ ...toAgentInstanceUpdateInput(instance),
83
82
  environmentRefs: editEnvRefs,
84
- visibility: meta?.visibility,
85
83
  });
86
84
  setIsEditingEnvs(false);
87
85
  onUpdated?.();
88
86
  } catch {
89
87
  // error displayed by hook
90
88
  }
91
- }, [update, meta, spec, org, editEnvRefs, onUpdated]);
89
+ }, [update, instance, editEnvRefs, onUpdated]);
92
90
 
93
91
  const handleDelete = useCallback(async () => {
94
92
  setDeleteError(null);
@@ -0,0 +1,75 @@
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
+ AgentInstanceSchema,
6
+ type AgentInstance,
7
+ } from "@stigmer/protos/ai/stigmer/agentic/agentinstance/v1/api_pb";
8
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
9
+ import type { AgentInstanceInput } from "@stigmer/sdk";
10
+ import { StigmerContext } from "../../context";
11
+ import { AgentInstanceDetailPanel } from "../AgentInstanceDetailPanel";
12
+
13
+ /**
14
+ * Regression suite for the full-spec-replace wipe bug: the environment
15
+ * editor must spread `toAgentInstanceUpdateInput` and override only the
16
+ * environment refs, so agent_id/description (and any future spec field)
17
+ * survive an environments-only save.
18
+ */
19
+
20
+ const INSTANCE: AgentInstance = create(AgentInstanceSchema, {
21
+ metadata: {
22
+ id: "inst-1",
23
+ name: "Prod Support Bot",
24
+ slug: "prod-support-bot",
25
+ org: "acme",
26
+ },
27
+ spec: {
28
+ agentId: "agent-1",
29
+ description: "Production instance.",
30
+ environmentRefs: [
31
+ { org: "acme", slug: "prod", kind: ApiResourceKind.environment },
32
+ ],
33
+ },
34
+ });
35
+
36
+ function renderPanel(update: ReturnType<typeof vi.fn>) {
37
+ const client = {
38
+ agentInstance: { update },
39
+ iamPolicy: {
40
+ checkMyPermission: vi.fn(async () => ({ isAuthorized: true })),
41
+ },
42
+ environment: {
43
+ list: vi.fn(async () => ({ items: [], totalCount: 0 })),
44
+ },
45
+ } as never;
46
+ return render(
47
+ <StigmerContext.Provider value={client}>
48
+ <AgentInstanceDetailPanel instance={INSTANCE} org="acme" onClose={() => {}} />
49
+ </StigmerContext.Provider>,
50
+ );
51
+ }
52
+
53
+ afterEach(cleanup);
54
+
55
+ describe("AgentInstanceDetailPanel save payload", () => {
56
+ it("round-trips agent_id and description on an environments-only save", async () => {
57
+ const update = vi.fn(async (_input: AgentInstanceInput) => INSTANCE);
58
+ renderPanel(update);
59
+
60
+ fireEvent.click(await screen.findByRole("button", { name: "Edit" }));
61
+ fireEvent.click(screen.getByRole("button", { name: "Save" }));
62
+
63
+ await waitFor(() => expect(update).toHaveBeenCalledTimes(1));
64
+ const input = update.mock.calls[0]![0];
65
+
66
+ // The wipe-bug guard: fields the environment editor does not render.
67
+ expect(input.agentId).toBe("agent-1");
68
+ expect(input.description).toBe("Production instance.");
69
+ // The form-owned field.
70
+ expect(input.environmentRefs).toEqual([{ org: "acme", slug: "prod" }]);
71
+ // Addressing fields.
72
+ expect(input.org).toBe("acme");
73
+ expect(input.slug).toBe("prod-support-bot");
74
+ });
75
+ });
@@ -32,7 +32,7 @@ export interface UseUpdateAgentInstanceReturn {
32
32
  *
33
33
  * const handleSave = async () => {
34
34
  * await update({
35
- * ...agentInstanceToInput(instance),
35
+ * ...toAgentInstanceUpdateInput(instance),
36
36
  * environmentRefs: newRefs,
37
37
  * });
38
38
  * refetch();
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useCallback, useState } from "react";
4
- import { FileCode2, KeyRound, LayoutTemplate, MessageSquare, MoreHorizontal, Share2, Trash2 } from "lucide-react";
4
+ import { FileCode2, KeyRound, LayoutTemplate, MessageSquare, MoreHorizontal, Share2, SlidersHorizontal, Trash2 } from "lucide-react";
5
5
  import { cn } from "@stigmer/theme";
6
6
  import { getUserMessage } from "@stigmer/sdk";
7
7
  import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
@@ -25,6 +25,7 @@ import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
25
25
  import { TruncatedText } from "../internal/truncated-text.js";
26
26
  import { ChannelConversationsDialog } from "./ChannelConversationsDialog.js";
27
27
  import { ChannelCredentialsDialog } from "./ChannelCredentialsDialog.js";
28
+ import { ChannelRunConfigDialog } from "./ChannelRunConfigDialog.js";
28
29
  import { ChannelTemplatesDialog } from "./ChannelTemplatesDialog.js";
29
30
  import { ConnectSlackDialog } from "./ConnectSlackDialog.js";
30
31
  import { ConnectWhatsAppDialog } from "./ConnectWhatsAppDialog.js";
@@ -160,6 +161,7 @@ export function AgentChannelsPanel({
160
161
 
161
162
  // The channel being edited as YAML (the kind-agnostic manifest flow).
162
163
  const [editingYaml, setEditingYaml] = useState<AgentChannel | null>(null);
164
+ const [editingRunConfig, setEditingRunConfig] = useState<AgentChannel | null>(null);
163
165
 
164
166
  const handleConnect = useCallback(
165
167
  (channel: AgentChannel | null, provider: ChannelProviderDescriptor) => {
@@ -305,6 +307,7 @@ export function AgentChannelsPanel({
305
307
  onViewConversations={() => setViewingConversations(channel)}
306
308
  onViewTemplates={() => setViewingTemplates(channel)}
307
309
  onEditYaml={() => setEditingYaml(channel)}
310
+ onEditRunConfig={() => setEditingRunConfig(channel)}
308
311
  refetch={refetch}
309
312
  />
310
313
  );
@@ -390,6 +393,17 @@ export function AgentChannelsPanel({
390
393
  />
391
394
  )}
392
395
 
396
+ {editingRunConfig && (
397
+ <ChannelRunConfigDialog
398
+ open
399
+ onOpenChange={(open) => {
400
+ if (!open) setEditingRunConfig(null);
401
+ }}
402
+ channel={editingRunConfig}
403
+ onSaved={refetch}
404
+ />
405
+ )}
406
+
393
407
  <ConfirmDialog
394
408
  state={confirmState}
395
409
  onConfirm={handleConfirm}
@@ -415,6 +429,7 @@ interface ChannelCardProps {
415
429
  readonly onViewConversations: () => void;
416
430
  readonly onViewTemplates: () => void;
417
431
  readonly onEditYaml: () => void;
432
+ readonly onEditRunConfig: () => void;
418
433
  readonly refetch: () => void;
419
434
  }
420
435
 
@@ -429,6 +444,7 @@ function ChannelCard({
429
444
  onViewConversations,
430
445
  onViewTemplates,
431
446
  onEditYaml,
447
+ onEditRunConfig,
432
448
  refetch,
433
449
  }: ChannelCardProps) {
434
450
  const meta = channel.metadata;
@@ -584,6 +600,15 @@ function ChannelCard({
584
600
  Templates
585
601
  </ActionMenu.Item>
586
602
  )}
603
+ {canEdit && (
604
+ <ActionMenu.Item
605
+ icon={<SlidersHorizontal />}
606
+ onSelect={onEditRunConfig}
607
+ data-cursor-target="channel-run-config"
608
+ >
609
+ Run settings
610
+ </ActionMenu.Item>
611
+ )}
587
612
  {canEdit && (
588
613
  <ActionMenu.Item
589
614
  icon={<KeyRound />}
@@ -0,0 +1,351 @@
1
+ "use client";
2
+
3
+ import { useCallback, useId, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage, type RunConfigInput } from "@stigmer/sdk";
6
+ import type { AgentChannel } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/api_pb";
7
+ import { Button } from "../button/Button.js";
8
+ import { DialogShell } from "../internal/DialogShell.js";
9
+ import { ModelSelector } from "../models/ModelSelector.js";
10
+ import type { HarnessOption } from "../models/harness.js";
11
+ import {
12
+ fromProtoServiceTier,
13
+ toProtoServiceTier,
14
+ type ServiceTierOption,
15
+ } from "../models/service-tier.js";
16
+ import {
17
+ fromProtoThinkingMode,
18
+ toProtoThinkingMode,
19
+ type ThinkingModeOption,
20
+ } from "../models/thinking-mode.js";
21
+ import { agentChannelToInput, useSaveAgentChannel } from "./useSaveAgentChannel.js";
22
+
23
+ /** Props for {@link ChannelRunConfigDialog}. */
24
+ export interface ChannelRunConfigDialogProps {
25
+ /** Whether the dialog is open. */
26
+ readonly open: boolean;
27
+ /** Called when the dialog requests an open-state change. */
28
+ readonly onOpenChange: (open: boolean) => void;
29
+ /** The channel whose run settings are edited. */
30
+ readonly channel: AgentChannel;
31
+ /** Called after a successful save (hosts typically pass `refetch`). */
32
+ readonly onSaved?: () => void;
33
+ /**
34
+ * When `false`, renders as an in-flow open dialog instead of a
35
+ * top-layer modal — for embedding in constrained surfaces
36
+ * (documentation demos, visual tests). Interactive hosts keep the
37
+ * default.
38
+ * @default true
39
+ */
40
+ readonly modal?: boolean;
41
+ }
42
+
43
+ /**
44
+ * Edits an installed channel's run settings (`AgentChannelSpec.run_config`)
45
+ * — the console's first run_config editor (stigmer/stigmer#792), replacing
46
+ * the Edit-YAML detour for the model pin the write-time validation guards
47
+ * (stigmer/stigmer#774).
48
+ *
49
+ * Speaks the schedule form's vocabulary (DD-018 D-5): the model pin uses
50
+ * the composer's own {@link ModelSelector} (with the fast-tier and
51
+ * thinking switches, #357/#772) and the budget is the one run bound a
52
+ * user owns; `max_tool_rounds` is an operator knob, API-reachable only —
53
+ * preserved verbatim on save, never rendered.
54
+ *
55
+ * The harness dropdown is a browsing scope for the picker, initialized to
56
+ * cursor (the platform's channel-serving default): channels carry no
57
+ * per-channel harness — the serving harness is a platform property — and
58
+ * the write-time model-pin validation judges the pin against any harness
59
+ * section, so pinning under either scope is legitimate.
60
+ *
61
+ * Saves are full-input applies via {@link agentChannelToInput}, so the
62
+ * agent reference, provider marker, credential bindings, and install
63
+ * status all survive; clearing the model with no budget set is an
64
+ * explicit reset to the platform defaults (`run_config` absent). Untouched
65
+ * variant switches stay off the wire — unspecified-vs-explicit is a
66
+ * load-bearing ledger distinction (#357).
67
+ *
68
+ * Built on the native `<dialog>` element, matching the SDK's modal
69
+ * convention. Most hosts mount it via {@link AgentChannelsPanel}'s
70
+ * channel card action.
71
+ */
72
+ export function ChannelRunConfigDialog({
73
+ open,
74
+ onOpenChange,
75
+ channel,
76
+ onSaved,
77
+ modal = true,
78
+ }: ChannelRunConfigDialogProps) {
79
+ // Instance-scoped title id (oss#593): hosts legitimately mount this
80
+ // dialog more than once per page; duplicate DOM ids would break the
81
+ // aria-labelledby association for every copy after the first.
82
+ const titleId = useId();
83
+
84
+ const handleClose = useCallback(() => {
85
+ onOpenChange(false);
86
+ }, [onOpenChange]);
87
+
88
+ return (
89
+ <DialogShell
90
+ open={open}
91
+ onOpenChange={onOpenChange}
92
+ modal={modal}
93
+ width="md"
94
+ aria-labelledby={titleId}
95
+ >
96
+ {/* Body mounts only while open so its draft resets per session —
97
+ reopening never resumes stale, unsaved edits. */}
98
+ {open && (
99
+ <ChannelRunConfigDialogBody
100
+ channel={channel}
101
+ onSaved={onSaved}
102
+ onClose={handleClose}
103
+ titleId={titleId}
104
+ />
105
+ )}
106
+ </DialogShell>
107
+ );
108
+ }
109
+
110
+ function ChannelRunConfigDialogBody({
111
+ channel,
112
+ onSaved,
113
+ onClose,
114
+ titleId,
115
+ }: {
116
+ readonly channel: AgentChannel;
117
+ readonly onSaved?: () => void;
118
+ readonly onClose: () => void;
119
+ /** Heading id minted by the outer dialog for its aria-labelledby. */
120
+ readonly titleId: string;
121
+ }) {
122
+ const channelName =
123
+ channel.metadata?.name || channel.metadata?.slug || "this channel";
124
+ const stored = channel.spec?.runConfig;
125
+
126
+ const { save, isPending, error, clearError } = useSaveAgentChannel();
127
+
128
+ const [modelName, setModelName] = useState(stored?.modelName ?? "");
129
+ const [harness, setHarness] = useState<HarnessOption>("cursor");
130
+ const [serviceTier, setServiceTier] = useState<ServiceTierOption>(
131
+ fromProtoServiceTier(stored?.serviceTier) ?? "standard",
132
+ );
133
+ const [thinkingMode, setThinkingMode] = useState<ThinkingModeOption>(
134
+ fromProtoThinkingMode(stored?.thinkingMode) ?? "disabled",
135
+ );
136
+ const [budgetUsd, setBudgetUsd] = useState(
137
+ stored && stored.maxCostUsd > 0 ? String(stored.maxCostUsd) : "",
138
+ );
139
+
140
+ const handleSave = useCallback(async () => {
141
+ try {
142
+ // Full-input apply: only run_config changes. An all-empty draft
143
+ // clears the block entirely — the proto's "empty = inherit" contract
144
+ // (DD-018 D-2) — while `max_tool_rounds`, which this editor never
145
+ // renders, survives verbatim (operator knob, DD-018 D-5).
146
+ await save({
147
+ ...agentChannelToInput(channel),
148
+ runConfig: buildRunConfig(
149
+ modelName,
150
+ budgetUsd,
151
+ serviceTier,
152
+ thinkingMode,
153
+ stored?.maxToolRounds ?? 0,
154
+ ),
155
+ });
156
+ onSaved?.();
157
+ onClose();
158
+ } catch {
159
+ // Surfaced through the hook's error state below.
160
+ }
161
+ }, [budgetUsd, channel, modelName, onClose, onSaved, save, serviceTier, stored, thinkingMode]);
162
+
163
+ return (
164
+ <div className="stg:flex stg:flex-col">
165
+ <div className="stg:flex stg:items-start stg:justify-between stg:gap-3 stg:border-b stg:border-border stg:px-5 stg:py-4">
166
+ <div className="stg:min-w-0">
167
+ <h2
168
+ id={titleId}
169
+ className="stg:text-sm stg:font-semibold stg:text-foreground"
170
+ >
171
+ Run settings
172
+ </h2>
173
+ <p className="stg:mt-0.5 stg:truncate stg:text-xs stg:text-muted-foreground">
174
+ {channelName}
175
+ </p>
176
+ </div>
177
+ <button
178
+ type="button"
179
+ onClick={onClose}
180
+ aria-label="Close dialog"
181
+ className={cn(
182
+ "stg:rounded stg:p-1 stg:text-muted-foreground",
183
+ "stg:hover:bg-accent-hover stg:hover:text-foreground",
184
+ "stg:focus:outline-none stg:focus:ring-1 stg:focus:ring-ring",
185
+ )}
186
+ >
187
+ <CloseIcon />
188
+ </button>
189
+ </div>
190
+
191
+ <div className="stg:space-y-4 stg:px-5 stg:py-4">
192
+ {/* Engine & model — the composer's own picker (DD-018 D-5), the
193
+ same shape as the schedule form's. Nothing is pinned until a
194
+ model is picked. */}
195
+ <div className="stg:space-y-1">
196
+ <span className={labelClasses}>
197
+ Model{" "}
198
+ <span className="stg:font-normal stg:text-muted-foreground">(optional)</span>
199
+ </span>
200
+ <div className="stg:flex stg:items-center stg:gap-2">
201
+ <ModelSelector
202
+ value={modelName}
203
+ onValueChange={setModelName}
204
+ initialHarness={harness}
205
+ onHarnessChange={setHarness}
206
+ serviceTier={serviceTier}
207
+ onServiceTierChange={setServiceTier}
208
+ thinkingMode={thinkingMode}
209
+ onThinkingModeChange={setThinkingMode}
210
+ placeholderLabel="Platform default"
211
+ disabled={isPending}
212
+ />
213
+ {modelName !== "" && (
214
+ <button
215
+ type="button"
216
+ onClick={() => {
217
+ setModelName("");
218
+ setServiceTier("standard");
219
+ setThinkingMode("disabled");
220
+ }}
221
+ disabled={isPending}
222
+ className={cn(
223
+ "stg:rounded-md stg:px-2 stg:py-1 stg:text-[0.65rem] stg:text-muted-foreground",
224
+ "stg:hover:text-foreground stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring",
225
+ "stg:disabled:pointer-events-none stg:disabled:opacity-50",
226
+ )}
227
+ >
228
+ Reset to platform default
229
+ </button>
230
+ )}
231
+ </div>
232
+ <p className={hintClasses}>
233
+ Every conversation turn on this channel runs the pinned model.
234
+ Unpinned, the platform&rsquo;s default engine and model apply.
235
+ </p>
236
+ </div>
237
+
238
+ {/* Budget — the one run bound that matters for an unattended
239
+ surface (DD-018 D-5). Clamped by the platform profile;
240
+ tool-round bounds stay API-only. */}
241
+ <div className="stg:space-y-1">
242
+ <label htmlFor={`${titleId}-budget`} className={labelClasses}>
243
+ Budget per run (USD){" "}
244
+ <span className="stg:font-normal stg:text-muted-foreground">(optional)</span>
245
+ </label>
246
+ <input
247
+ id={`${titleId}-budget`}
248
+ type="number"
249
+ min="0"
250
+ step="0.5"
251
+ inputMode="decimal"
252
+ value={budgetUsd}
253
+ onChange={(e) => setBudgetUsd(e.target.value)}
254
+ placeholder="Platform default"
255
+ disabled={isPending}
256
+ className={cn(inputClasses, "stg:max-w-40")}
257
+ />
258
+ <p className={hintClasses}>
259
+ Caps each turn&rsquo;s estimated spend. The platform profile
260
+ bounds this value; the lower cap wins.
261
+ </p>
262
+ </div>
263
+
264
+ {error && (
265
+ <div
266
+ role="alert"
267
+ className="stg:rounded-md stg:border stg:border-destructive/30 stg:bg-destructive-subtle stg:px-3 stg:py-2 stg:text-xs stg:text-destructive"
268
+ >
269
+ {getUserMessage(error)}
270
+ </div>
271
+ )}
272
+ </div>
273
+
274
+ <div className="stg:flex stg:justify-end stg:gap-2 stg:border-t stg:border-border stg:px-5 stg:py-3">
275
+ <Button
276
+ variant="ghost"
277
+ size="sm"
278
+ onClick={() => {
279
+ clearError();
280
+ onClose();
281
+ }}
282
+ disabled={isPending}
283
+ >
284
+ Cancel
285
+ </Button>
286
+ <Button
287
+ variant="primary"
288
+ size="sm"
289
+ onClick={() => void handleSave()}
290
+ disabled={isPending}
291
+ >
292
+ Save
293
+ </Button>
294
+ </div>
295
+ </div>
296
+ );
297
+ }
298
+
299
+ /**
300
+ * Assemble the run_config the save writes. The schedule form's
301
+ * `buildRunConfig` contract (#357/#772) plus the edit-surface rule from
302
+ * the schedule detail view's `normalizeRunConfig`: fields this editor
303
+ * does not own (`max_tool_rounds`) are preserved verbatim, and an
304
+ * all-empty result clears the block ("empty = inherit").
305
+ */
306
+ function buildRunConfig(
307
+ modelName: string,
308
+ budgetUsd: string,
309
+ serviceTier: ServiceTierOption,
310
+ thinkingMode: ThinkingModeOption,
311
+ storedMaxToolRounds: number,
312
+ ): RunConfigInput | undefined {
313
+ const model = modelName.trim();
314
+ const cost = Number.parseFloat(budgetUsd);
315
+
316
+ const config: RunConfigInput = {};
317
+ if (model !== "") config.modelName = model;
318
+ if (Number.isFinite(cost) && cost > 0) config.maxCostUsd = cost;
319
+ if (storedMaxToolRounds > 0) config.maxToolRounds = storedMaxToolRounds;
320
+ // Carried only when the user actively chose the variant AND pinned a
321
+ // model (both are per-model; the server refuses them without one). An
322
+ // untouched switch stays absent — unspecified-vs-explicit is a
323
+ // load-bearing ledger distinction (#357/#772).
324
+ if (serviceTier === "fast" && model !== "") {
325
+ config.serviceTier = toProtoServiceTier(serviceTier);
326
+ }
327
+ if (thinkingMode === "enabled" && model !== "") {
328
+ config.thinkingMode = toProtoThinkingMode(thinkingMode);
329
+ }
330
+
331
+ return Object.keys(config).length > 0 ? config : undefined;
332
+ }
333
+
334
+ const labelClasses = "stg:block stg:text-xs stg:font-medium stg:text-foreground";
335
+
336
+ const hintClasses = "stg:text-[0.65rem] stg:text-muted-foreground";
337
+
338
+ const inputClasses = cn(
339
+ "stg:w-full stg:rounded-md stg:border stg:border-input stg:bg-background stg:px-2.5 stg:py-1.5 stg:text-xs stg:text-foreground",
340
+ "stg:placeholder:text-muted-foreground",
341
+ "stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring",
342
+ "stg:disabled:pointer-events-none stg:disabled:opacity-50",
343
+ );
344
+
345
+ function CloseIcon() {
346
+ return (
347
+ <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" aria-hidden="true">
348
+ <path d="m3 3 8 8M11 3l-8 8" />
349
+ </svg>
350
+ );
351
+ }