@stigmer/react 3.12.3 → 3.12.5

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 (493) hide show
  1. package/agent/steps/IdentityStep.d.ts.map +1 -1
  2. package/agent/steps/IdentityStep.js +2 -1
  3. package/agent/steps/IdentityStep.js.map +1 -1
  4. package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
  5. package/agent-instance/AgentInstanceDetailPanel.js +2 -1
  6. package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
  7. package/api-key/CreateApiKeyForm.d.ts.map +1 -1
  8. package/api-key/CreateApiKeyForm.js +2 -1
  9. package/api-key/CreateApiKeyForm.js.map +1 -1
  10. package/attachment/AttachmentChipList.js +16 -6
  11. package/attachment/AttachmentChipList.js.map +1 -1
  12. package/attachment/index.d.ts +1 -1
  13. package/attachment/index.d.ts.map +1 -1
  14. package/attachment/index.js.map +1 -1
  15. package/attachment/useAttachments.d.ts +51 -8
  16. package/attachment/useAttachments.d.ts.map +1 -1
  17. package/attachment/useAttachments.js +74 -3
  18. package/attachment/useAttachments.js.map +1 -1
  19. package/channel/ChannelConversationsDialog.d.ts.map +1 -1
  20. package/channel/ChannelConversationsDialog.js +2 -1
  21. package/channel/ChannelConversationsDialog.js.map +1 -1
  22. package/channel/ChannelTemplatesDialog.d.ts.map +1 -1
  23. package/channel/ChannelTemplatesDialog.js +2 -1
  24. package/channel/ChannelTemplatesDialog.js.map +1 -1
  25. package/channel/ConnectSlackDialog.d.ts.map +1 -1
  26. package/channel/ConnectSlackDialog.js +2 -1
  27. package/channel/ConnectSlackDialog.js.map +1 -1
  28. package/channel/connect/ServingAppSection.d.ts.map +1 -1
  29. package/channel/connect/ServingAppSection.js +2 -1
  30. package/channel/connect/ServingAppSection.js.map +1 -1
  31. package/channel-app/CreateChannelAppForm.d.ts.map +1 -1
  32. package/channel-app/CreateChannelAppForm.js +2 -1
  33. package/channel-app/CreateChannelAppForm.js.map +1 -1
  34. package/composer/SessionComposer.d.ts.map +1 -1
  35. package/composer/SessionComposer.js +17 -10
  36. package/composer/SessionComposer.js.map +1 -1
  37. package/conversation/ConversationComposer.d.ts +19 -3
  38. package/conversation/ConversationComposer.d.ts.map +1 -1
  39. package/conversation/ConversationComposer.js +4 -4
  40. package/conversation/ConversationComposer.js.map +1 -1
  41. package/conversation/ConversationListPane.d.ts.map +1 -1
  42. package/conversation/ConversationListPane.js +2 -1
  43. package/conversation/ConversationListPane.js.map +1 -1
  44. package/conversation/ConversationTemplatePickerDialog.d.ts +63 -0
  45. package/conversation/ConversationTemplatePickerDialog.d.ts.map +1 -0
  46. package/conversation/ConversationTemplatePickerDialog.js +151 -0
  47. package/conversation/ConversationTemplatePickerDialog.js.map +1 -0
  48. package/conversation/ConversationTimelineView.d.ts.map +1 -1
  49. package/conversation/ConversationTimelineView.js +2 -1
  50. package/conversation/ConversationTimelineView.js.map +1 -1
  51. package/conversation/ConversationsWorkbench.d.ts.map +1 -1
  52. package/conversation/ConversationsWorkbench.js +16 -5
  53. package/conversation/ConversationsWorkbench.js.map +1 -1
  54. package/conversation/index.d.ts +3 -1
  55. package/conversation/index.d.ts.map +1 -1
  56. package/conversation/index.js +1 -0
  57. package/conversation/index.js.map +1 -1
  58. package/conversation/useConversationParticipation.d.ts +41 -4
  59. package/conversation/useConversationParticipation.d.ts.map +1 -1
  60. package/conversation/useConversationParticipation.js +13 -2
  61. package/conversation/useConversationParticipation.js.map +1 -1
  62. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
  63. package/cursor-accounts/CursorAccountsConsole.js +2 -1
  64. package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
  65. package/cursor-accounts/MemberKeysPanel.d.ts.map +1 -1
  66. package/cursor-accounts/MemberKeysPanel.js +2 -1
  67. package/cursor-accounts/MemberKeysPanel.js.map +1 -1
  68. package/dashboard/DashboardFailedRuns.d.ts.map +1 -1
  69. package/dashboard/DashboardFailedRuns.js +2 -1
  70. package/dashboard/DashboardFailedRuns.js.map +1 -1
  71. package/dependency-graph/DependencyGraph.d.ts.map +1 -1
  72. package/dependency-graph/DependencyGraph.js +2 -1
  73. package/dependency-graph/DependencyGraph.js.map +1 -1
  74. package/dependency-graph/DependencyTreeNode.d.ts.map +1 -1
  75. package/dependency-graph/DependencyTreeNode.js +2 -1
  76. package/dependency-graph/DependencyTreeNode.js.map +1 -1
  77. package/environment/EnvironmentPicker.d.ts.map +1 -1
  78. package/environment/EnvironmentPicker.js +2 -1
  79. package/environment/EnvironmentPicker.js.map +1 -1
  80. package/error/SecretFlowErrorGuide.d.ts.map +1 -1
  81. package/error/SecretFlowErrorGuide.js +2 -1
  82. package/error/SecretFlowErrorGuide.js.map +1 -1
  83. package/execution/ArtifactContentBody.d.ts.map +1 -1
  84. package/execution/ArtifactContentBody.js +2 -1
  85. package/execution/ArtifactContentBody.js.map +1 -1
  86. package/execution/ArtifactsWidget.d.ts.map +1 -1
  87. package/execution/ArtifactsWidget.js +2 -1
  88. package/execution/ArtifactsWidget.js.map +1 -1
  89. package/execution/FileChangeProgressBar.d.ts.map +1 -1
  90. package/execution/FileChangeProgressBar.js +2 -1
  91. package/execution/FileChangeProgressBar.js.map +1 -1
  92. package/execution/TodoList.d.ts.map +1 -1
  93. package/execution/TodoList.js +2 -1
  94. package/execution/TodoList.js.map +1 -1
  95. package/execution/WriteBacksWidget.d.ts.map +1 -1
  96. package/execution/WriteBacksWidget.js +2 -1
  97. package/execution/WriteBacksWidget.js.map +1 -1
  98. package/execution/tool-categories.d.ts +5 -22
  99. package/execution/tool-categories.d.ts.map +1 -1
  100. package/execution/tool-categories.js +8 -38
  101. package/execution/tool-categories.js.map +1 -1
  102. package/iam-policy/PeopleWithAccess.d.ts.map +1 -1
  103. package/iam-policy/PeopleWithAccess.js +2 -1
  104. package/iam-policy/PeopleWithAccess.js.map +1 -1
  105. package/iam-policy/PrincipalPicker.d.ts.map +1 -1
  106. package/iam-policy/PrincipalPicker.js +2 -1
  107. package/iam-policy/PrincipalPicker.js.map +1 -1
  108. package/iam-policy/RoleSelector.d.ts.map +1 -1
  109. package/iam-policy/RoleSelector.js +2 -1
  110. package/iam-policy/RoleSelector.js.map +1 -1
  111. package/identity-account/AccountPreferencesPanel.d.ts +35 -0
  112. package/identity-account/AccountPreferencesPanel.d.ts.map +1 -0
  113. package/identity-account/AccountPreferencesPanel.js +187 -0
  114. package/identity-account/AccountPreferencesPanel.js.map +1 -0
  115. package/identity-account/index.d.ts +8 -0
  116. package/identity-account/index.d.ts.map +1 -1
  117. package/identity-account/index.js +4 -0
  118. package/identity-account/index.js.map +1 -1
  119. package/identity-account/useAccountExecutionDefaults.d.ts +36 -0
  120. package/identity-account/useAccountExecutionDefaults.d.ts.map +1 -0
  121. package/identity-account/useAccountExecutionDefaults.js +46 -0
  122. package/identity-account/useAccountExecutionDefaults.js.map +1 -0
  123. package/identity-account/useMyIdentityAccount.d.ts +55 -0
  124. package/identity-account/useMyIdentityAccount.d.ts.map +1 -0
  125. package/identity-account/useMyIdentityAccount.js +37 -0
  126. package/identity-account/useMyIdentityAccount.js.map +1 -0
  127. package/identity-account/useUpdateIdentityAccount.d.ts +42 -0
  128. package/identity-account/useUpdateIdentityAccount.d.ts.map +1 -0
  129. package/identity-account/useUpdateIdentityAccount.js +53 -0
  130. package/identity-account/useUpdateIdentityAccount.js.map +1 -0
  131. package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -1
  132. package/identity-provider/CreateIdentityProviderForm.js +2 -1
  133. package/identity-provider/CreateIdentityProviderForm.js.map +1 -1
  134. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  135. package/identity-provider/IdentityProviderDetailPanel.js +2 -1
  136. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  137. package/identity-provider/IdentityProviderWizard.d.ts.map +1 -1
  138. package/identity-provider/IdentityProviderWizard.js +2 -1
  139. package/identity-provider/IdentityProviderWizard.js.map +1 -1
  140. package/index.d.ts +14 -10
  141. package/index.d.ts.map +1 -1
  142. package/index.js +11 -5
  143. package/index.js.map +1 -1
  144. package/internal/StandingContextField.d.ts +37 -0
  145. package/internal/StandingContextField.d.ts.map +1 -0
  146. package/internal/StandingContextField.js +24 -0
  147. package/internal/StandingContextField.js.map +1 -0
  148. package/internal/element-resets.d.ts +17 -0
  149. package/internal/element-resets.d.ts.map +1 -0
  150. package/internal/element-resets.js +32 -0
  151. package/internal/element-resets.js.map +1 -0
  152. package/internal/file-tree/FileTreeNode.d.ts.map +1 -1
  153. package/internal/file-tree/FileTreeNode.js +2 -1
  154. package/internal/file-tree/FileTreeNode.js.map +1 -1
  155. package/internal/markdown-components.d.ts +7 -0
  156. package/internal/markdown-components.d.ts.map +1 -1
  157. package/internal/markdown-components.js +15 -5
  158. package/internal/markdown-components.js.map +1 -1
  159. package/invitation/InvitationManager.d.ts.map +1 -1
  160. package/invitation/InvitationManager.js +2 -1
  161. package/invitation/InvitationManager.js.map +1 -1
  162. package/library/InstanceVisibilitySelector.d.ts.map +1 -1
  163. package/library/InstanceVisibilitySelector.js +9 -2
  164. package/library/InstanceVisibilitySelector.js.map +1 -1
  165. package/library/ResourceVisibilityControl.d.ts +13 -3
  166. package/library/ResourceVisibilityControl.d.ts.map +1 -1
  167. package/library/ResourceVisibilityControl.js +33 -5
  168. package/library/ResourceVisibilityControl.js.map +1 -1
  169. package/library/VisibilityOptionRow.d.ts +6 -0
  170. package/library/VisibilityOptionRow.d.ts.map +1 -1
  171. package/library/VisibilityOptionRow.js +11 -1
  172. package/library/VisibilityOptionRow.js.map +1 -1
  173. package/library/VisibilitySelector.d.ts.map +1 -1
  174. package/library/VisibilitySelector.js +14 -2
  175. package/library/VisibilitySelector.js.map +1 -1
  176. package/library/index.d.ts +4 -2
  177. package/library/index.d.ts.map +1 -1
  178. package/library/index.js +2 -1
  179. package/library/index.js.map +1 -1
  180. package/library/useCanSetPublicVisibility.d.ts +30 -0
  181. package/library/useCanSetPublicVisibility.d.ts.map +1 -0
  182. package/library/useCanSetPublicVisibility.js +41 -0
  183. package/library/useCanSetPublicVisibility.js.map +1 -0
  184. package/library/visibilityLevels.d.ts +32 -1
  185. package/library/visibilityLevels.d.ts.map +1 -1
  186. package/library/visibilityLevels.js +34 -14
  187. package/library/visibilityLevels.js.map +1 -1
  188. package/manifest/ApplyManifestDialog.d.ts.map +1 -1
  189. package/manifest/ApplyManifestDialog.js +2 -1
  190. package/manifest/ApplyManifestDialog.js.map +1 -1
  191. package/mcp-server/steps/IdentityTransportStep.d.ts.map +1 -1
  192. package/mcp-server/steps/IdentityTransportStep.js +2 -1
  193. package/mcp-server/steps/IdentityTransportStep.js.map +1 -1
  194. package/mcp-server/useMcpServerConnect.d.ts +8 -5
  195. package/mcp-server/useMcpServerConnect.d.ts.map +1 -1
  196. package/mcp-server/useMcpServerConnect.js +2 -1
  197. package/mcp-server/useMcpServerConnect.js.map +1 -1
  198. package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
  199. package/mcp-server/useMcpServerOAuthConnect.js +7 -2
  200. package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
  201. package/oauth-app/CreateOAuthAppForm.d.ts +2 -2
  202. package/oauth-app/CreateOAuthAppForm.d.ts.map +1 -1
  203. package/oauth-app/CreateOAuthAppForm.js +13 -4
  204. package/oauth-app/CreateOAuthAppForm.js.map +1 -1
  205. package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
  206. package/oauth-app/OAuthAppDetailPanel.js +32 -5
  207. package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
  208. package/organization/OrgPreferencesPanel.d.ts +32 -0
  209. package/organization/OrgPreferencesPanel.d.ts.map +1 -0
  210. package/organization/OrgPreferencesPanel.js +90 -0
  211. package/organization/OrgPreferencesPanel.js.map +1 -0
  212. package/organization/OrgProfilePanel.d.ts.map +1 -1
  213. package/organization/OrgProfilePanel.js +5 -4
  214. package/organization/OrgProfilePanel.js.map +1 -1
  215. package/organization/index.d.ts +2 -0
  216. package/organization/index.d.ts.map +1 -1
  217. package/organization/index.js +1 -0
  218. package/organization/index.js.map +1 -1
  219. package/package.json +4 -4
  220. package/platform-client/CreatePlatformClientForm.d.ts.map +1 -1
  221. package/platform-client/CreatePlatformClientForm.js +2 -1
  222. package/platform-client/CreatePlatformClientForm.js.map +1 -1
  223. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
  224. package/platform-client/PlatformClientDetailPanel.js +2 -1
  225. package/platform-client/PlatformClientDetailPanel.js.map +1 -1
  226. package/pricing-governance/BaselineEditor.d.ts.map +1 -1
  227. package/pricing-governance/BaselineEditor.js +2 -1
  228. package/pricing-governance/BaselineEditor.js.map +1 -1
  229. package/pricing-governance/PricingGovernanceConsole.d.ts.map +1 -1
  230. package/pricing-governance/PricingGovernanceConsole.js +2 -1
  231. package/pricing-governance/PricingGovernanceConsole.js.map +1 -1
  232. package/provider-standing/ProviderStandingAccessNotice.d.ts +11 -0
  233. package/provider-standing/ProviderStandingAccessNotice.d.ts.map +1 -0
  234. package/provider-standing/ProviderStandingAccessNotice.js +14 -0
  235. package/provider-standing/ProviderStandingAccessNotice.js.map +1 -0
  236. package/provider-standing/ProviderStandingConsole.d.ts +24 -0
  237. package/provider-standing/ProviderStandingConsole.d.ts.map +1 -0
  238. package/provider-standing/ProviderStandingConsole.js +98 -0
  239. package/provider-standing/ProviderStandingConsole.js.map +1 -0
  240. package/provider-standing/index.d.ts +6 -0
  241. package/provider-standing/index.d.ts.map +1 -0
  242. package/provider-standing/index.js +6 -0
  243. package/provider-standing/index.js.map +1 -0
  244. package/provider-standing/useProviderStanding.d.ts +34 -0
  245. package/provider-standing/useProviderStanding.d.ts.map +1 -0
  246. package/provider-standing/useProviderStanding.js +26 -0
  247. package/provider-standing/useProviderStanding.js.map +1 -0
  248. package/provider.d.ts +12 -0
  249. package/provider.d.ts.map +1 -1
  250. package/provider.js +12 -0
  251. package/provider.js.map +1 -1
  252. package/resource-creation/StepIndicator.d.ts.map +1 -1
  253. package/resource-creation/StepIndicator.js +2 -1
  254. package/resource-creation/StepIndicator.js.map +1 -1
  255. package/schedule/ScheduleDetailView.d.ts.map +1 -1
  256. package/schedule/ScheduleDetailView.js +3 -2
  257. package/schedule/ScheduleDetailView.js.map +1 -1
  258. package/schedule/ScheduleRunsTable.d.ts.map +1 -1
  259. package/schedule/ScheduleRunsTable.js +2 -1
  260. package/schedule/ScheduleRunsTable.js.map +1 -1
  261. package/session/NewSessionViewer.d.ts +10 -1
  262. package/session/NewSessionViewer.d.ts.map +1 -1
  263. package/session/NewSessionViewer.js +2 -1
  264. package/session/NewSessionViewer.js.map +1 -1
  265. package/session/facets/ArtifactsTab.d.ts.map +1 -1
  266. package/session/facets/ArtifactsTab.js +2 -1
  267. package/session/facets/ArtifactsTab.js.map +1 -1
  268. package/session/facets/ChangesTab.d.ts.map +1 -1
  269. package/session/facets/ChangesTab.js +2 -1
  270. package/session/facets/ChangesTab.js.map +1 -1
  271. package/session/facets/UsageTab.d.ts +10 -3
  272. package/session/facets/UsageTab.d.ts.map +1 -1
  273. package/session/facets/UsageTab.js +42 -6
  274. package/session/facets/UsageTab.js.map +1 -1
  275. package/session/index.d.ts +1 -1
  276. package/session/index.d.ts.map +1 -1
  277. package/session/index.js.map +1 -1
  278. package/session/useNewSessionFlow.d.ts +27 -1
  279. package/session/useNewSessionFlow.d.ts.map +1 -1
  280. package/session/useNewSessionFlow.js +45 -8
  281. package/session/useNewSessionFlow.js.map +1 -1
  282. package/session/useSessionUsage.d.ts +25 -0
  283. package/session/useSessionUsage.d.ts.map +1 -1
  284. package/session/useSessionUsage.js +11 -0
  285. package/session/useSessionUsage.js.map +1 -1
  286. package/settings/AccountPreferencesSection.d.ts +3 -0
  287. package/settings/AccountPreferencesSection.d.ts.map +1 -0
  288. package/settings/AccountPreferencesSection.js +10 -0
  289. package/settings/AccountPreferencesSection.js.map +1 -0
  290. package/settings/OrgPreferencesSection.d.ts +3 -0
  291. package/settings/OrgPreferencesSection.d.ts.map +1 -0
  292. package/settings/OrgPreferencesSection.js +13 -0
  293. package/settings/OrgPreferencesSection.js.map +1 -0
  294. package/settings/index.d.ts +2 -0
  295. package/settings/index.d.ts.map +1 -1
  296. package/settings/index.js +2 -0
  297. package/settings/index.js.map +1 -1
  298. package/settings/settings-nav.d.ts.map +1 -1
  299. package/settings/settings-nav.js +23 -1
  300. package/settings/settings-nav.js.map +1 -1
  301. package/settings/useSettingsNavGroups.d.ts.map +1 -1
  302. package/settings/useSettingsNavGroups.js +4 -1
  303. package/settings/useSettingsNavGroups.js.map +1 -1
  304. package/sharing/ShareAgentDialog.d.ts.map +1 -1
  305. package/sharing/ShareAgentDialog.js +2 -1
  306. package/sharing/ShareAgentDialog.js.map +1 -1
  307. package/sidebar/WorkspaceSidebar.d.ts.map +1 -1
  308. package/sidebar/WorkspaceSidebar.js +2 -1
  309. package/sidebar/WorkspaceSidebar.js.map +1 -1
  310. package/skill/SkillFileBrowser.d.ts.map +1 -1
  311. package/skill/SkillFileBrowser.js +2 -1
  312. package/skill/SkillFileBrowser.js.map +1 -1
  313. package/skill/internal/fetchAndUnpackArtifact.d.ts +1 -1
  314. package/skill/internal/fetchAndUnpackArtifact.d.ts.map +1 -1
  315. package/skill/internal/fetchAndUnpackArtifact.js +47 -3
  316. package/skill/internal/fetchAndUnpackArtifact.js.map +1 -1
  317. package/skill/useSkillDiff.d.ts.map +1 -1
  318. package/skill/useSkillDiff.js +7 -1
  319. package/skill/useSkillDiff.js.map +1 -1
  320. package/skill/useSkillUpload.d.ts.map +1 -1
  321. package/skill/useSkillUpload.js +22 -4
  322. package/skill/useSkillUpload.js.map +1 -1
  323. package/src/__tests__/bare-host-resets.layout.test.tsx +184 -0
  324. package/src/agent/steps/IdentityStep.tsx +2 -1
  325. package/src/agent-instance/AgentInstanceDetailPanel.tsx +2 -1
  326. package/src/api-key/CreateApiKeyForm.tsx +2 -1
  327. package/src/attachment/AttachmentChipList.tsx +19 -8
  328. package/src/attachment/__tests__/AttachmentChipList.test.tsx +12 -0
  329. package/src/attachment/__tests__/useAttachments.test.ts +293 -0
  330. package/src/attachment/index.ts +1 -0
  331. package/src/attachment/useAttachments.ts +143 -11
  332. package/src/channel/ChannelConversationsDialog.tsx +2 -1
  333. package/src/channel/ChannelTemplatesDialog.tsx +2 -1
  334. package/src/channel/ConnectSlackDialog.tsx +2 -1
  335. package/src/channel/connect/ServingAppSection.tsx +2 -1
  336. package/src/channel-app/CreateChannelAppForm.tsx +2 -1
  337. package/src/composer/SessionComposer.tsx +23 -14
  338. package/src/conversation/ConversationComposer.tsx +38 -4
  339. package/src/conversation/ConversationListPane.tsx +2 -5
  340. package/src/conversation/ConversationTemplatePickerDialog.tsx +441 -0
  341. package/src/conversation/ConversationTimelineView.tsx +2 -1
  342. package/src/conversation/ConversationsWorkbench.tsx +40 -4
  343. package/src/conversation/__tests__/ConversationComposer.test.tsx +56 -1
  344. package/src/conversation/__tests__/ConversationTemplatePickerDialog.test.tsx +224 -0
  345. package/src/conversation/__tests__/useConversationParticipation.test.tsx +45 -4
  346. package/src/conversation/index.ts +4 -0
  347. package/src/conversation/useConversationParticipation.ts +58 -6
  348. package/src/cursor-accounts/CursorAccountsConsole.tsx +2 -1
  349. package/src/cursor-accounts/MemberKeysPanel.tsx +2 -1
  350. package/src/dashboard/DashboardFailedRuns.tsx +2 -1
  351. package/src/dependency-graph/DependencyGraph.tsx +2 -1
  352. package/src/dependency-graph/DependencyTreeNode.tsx +2 -1
  353. package/src/environment/EnvironmentPicker.tsx +2 -1
  354. package/src/error/SecretFlowErrorGuide.tsx +3 -2
  355. package/src/execution/ArtifactContentBody.tsx +2 -1
  356. package/src/execution/ArtifactsWidget.tsx +2 -1
  357. package/src/execution/FileChangeProgressBar.tsx +2 -1
  358. package/src/execution/TodoList.tsx +2 -1
  359. package/src/execution/WriteBacksWidget.tsx +2 -1
  360. package/src/execution/tool-categories.ts +17 -41
  361. package/src/iam-policy/PeopleWithAccess.tsx +2 -1
  362. package/src/iam-policy/PrincipalPicker.tsx +2 -0
  363. package/src/iam-policy/RoleSelector.tsx +2 -1
  364. package/src/identity-account/AccountPreferencesPanel.tsx +446 -0
  365. package/src/identity-account/__tests__/AccountPreferencesPanel.test.tsx +233 -0
  366. package/src/identity-account/__tests__/useAccountExecutionDefaults.test.tsx +116 -0
  367. package/src/identity-account/__tests__/useMyIdentityAccount.test.tsx +121 -0
  368. package/src/identity-account/index.ts +11 -0
  369. package/src/identity-account/useAccountExecutionDefaults.ts +63 -0
  370. package/src/identity-account/useMyIdentityAccount.ts +75 -0
  371. package/src/identity-account/useUpdateIdentityAccount.ts +73 -0
  372. package/src/identity-provider/CreateIdentityProviderForm.tsx +2 -1
  373. package/src/identity-provider/IdentityProviderDetailPanel.tsx +2 -1
  374. package/src/identity-provider/IdentityProviderWizard.tsx +2 -1
  375. package/src/index.ts +37 -2
  376. package/src/internal/StandingContextField.tsx +92 -0
  377. package/src/internal/element-resets.ts +33 -0
  378. package/src/internal/file-tree/FileTreeNode.tsx +2 -1
  379. package/src/internal/markdown-components.tsx +15 -5
  380. package/src/invitation/InvitationManager.tsx +3 -2
  381. package/src/library/InstanceVisibilitySelector.tsx +9 -2
  382. package/src/library/ResourceVisibilityControl.tsx +46 -13
  383. package/src/library/VisibilityOptionRow.tsx +28 -6
  384. package/src/library/VisibilitySelector.tsx +14 -2
  385. package/src/library/__tests__/VisibilitySelector.test.tsx +48 -1
  386. package/src/library/__tests__/visibilityLevels.test.ts +67 -1
  387. package/src/library/index.ts +6 -1
  388. package/src/library/useCanSetPublicVisibility.ts +56 -0
  389. package/src/library/visibilityLevels.ts +65 -14
  390. package/src/manifest/ApplyManifestDialog.tsx +2 -1
  391. package/src/mcp-server/__tests__/useMcpServerConnect.asyncLane.test.tsx +117 -0
  392. package/src/mcp-server/steps/IdentityTransportStep.tsx +3 -2
  393. package/src/mcp-server/useMcpServerConnect.ts +9 -6
  394. package/src/mcp-server/useMcpServerOAuthConnect.ts +7 -2
  395. package/src/oauth-app/CreateOAuthAppForm.tsx +58 -3
  396. package/src/oauth-app/OAuthAppDetailPanel.tsx +84 -3
  397. package/src/organization/OrgPreferencesPanel.tsx +221 -0
  398. package/src/organization/OrgProfilePanel.tsx +5 -4
  399. package/src/organization/__tests__/OrgPreferencesPanel.test.tsx +145 -0
  400. package/src/organization/__tests__/OrgProfilePanel.test.tsx +108 -0
  401. package/src/organization/index.ts +2 -0
  402. package/src/platform-client/CreatePlatformClientForm.tsx +4 -3
  403. package/src/platform-client/PlatformClientDetailPanel.tsx +4 -3
  404. package/src/pricing-governance/BaselineEditor.tsx +3 -2
  405. package/src/pricing-governance/PricingGovernanceConsole.tsx +2 -1
  406. package/src/provider-standing/ProviderStandingAccessNotice.tsx +36 -0
  407. package/src/provider-standing/ProviderStandingConsole.tsx +216 -0
  408. package/src/provider-standing/__tests__/ProviderStandingConsole.test.tsx +143 -0
  409. package/src/provider-standing/index.ts +8 -0
  410. package/src/provider-standing/useProviderStanding.ts +50 -0
  411. package/src/provider.tsx +12 -0
  412. package/src/resource-creation/StepIndicator.tsx +2 -1
  413. package/src/schedule/ScheduleDetailView.tsx +3 -2
  414. package/src/schedule/ScheduleRunsTable.tsx +2 -1
  415. package/src/session/NewSessionViewer.tsx +12 -0
  416. package/src/session/__tests__/UsageTab.test.tsx +136 -0
  417. package/src/session/__tests__/useNewSessionFlow.test.tsx +151 -0
  418. package/src/session/__tests__/useSessionUsage.test.ts +19 -0
  419. package/src/session/facets/ArtifactsTab.tsx +2 -1
  420. package/src/session/facets/ChangesTab.tsx +2 -1
  421. package/src/session/facets/UsageTab.tsx +98 -6
  422. package/src/session/index.ts +1 -0
  423. package/src/session/useNewSessionFlow.ts +76 -9
  424. package/src/session/useSessionUsage.ts +37 -0
  425. package/src/settings/AccountPreferencesSection.tsx +25 -0
  426. package/src/settings/OrgPreferencesSection.tsx +35 -0
  427. package/src/settings/__tests__/settings-nav.test.ts +27 -0
  428. package/src/settings/__tests__/useSettingsNavGroups.test.tsx +11 -1
  429. package/src/settings/index.ts +2 -0
  430. package/src/settings/settings-nav.ts +25 -0
  431. package/src/settings/useSettingsNavGroups.ts +8 -1
  432. package/src/sharing/ShareAgentDialog.tsx +2 -1
  433. package/src/sidebar/WorkspaceSidebar.tsx +2 -1
  434. package/src/skill/SkillFileBrowser.tsx +2 -1
  435. package/src/skill/__tests__/SkillFileBrowser.test.tsx +10 -2
  436. package/src/skill/__tests__/fetchAndUnpackArtifact.test.ts +90 -0
  437. package/src/skill/__tests__/useSkillUpload.test.ts +69 -0
  438. package/src/skill/internal/fetchAndUnpackArtifact.ts +54 -4
  439. package/src/skill/useSkillDiff.ts +7 -1
  440. package/src/skill/useSkillUpload.ts +25 -6
  441. package/src/workflow/ApprovalFormBuilder.tsx +5 -27
  442. package/src/workflow/FailedRunsWidget.tsx +2 -1
  443. package/src/workflow/PendingApprovalsWidget.tsx +2 -1
  444. package/src/workflow/facets/WorkflowArtifactsTab.tsx +2 -1
  445. package/src/workflow/facets/WorkflowUsageTab.tsx +2 -1
  446. package/src/workflow/inspector/WorkflowSummaryPanel.tsx +2 -1
  447. package/src/workflow/inspector/tabs/BranchesTab.tsx +2 -1
  448. package/src/workflow/inspector/tabs/IterationTab.tsx +2 -1
  449. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +2 -1
  450. package/src/workspace/ExplorerTree.tsx +2 -1
  451. package/src/workspace/WorkspaceContentSearch.tsx +2 -1
  452. package/src/workspace/WorkspaceFileSearch.tsx +2 -1
  453. package/src/workspace/WorkspaceSummary.tsx +2 -1
  454. package/styles.css +1 -1
  455. package/workflow/ApprovalFormBuilder.d.ts.map +1 -1
  456. package/workflow/ApprovalFormBuilder.js +8 -5
  457. package/workflow/ApprovalFormBuilder.js.map +1 -1
  458. package/workflow/FailedRunsWidget.d.ts.map +1 -1
  459. package/workflow/FailedRunsWidget.js +2 -1
  460. package/workflow/FailedRunsWidget.js.map +1 -1
  461. package/workflow/PendingApprovalsWidget.d.ts.map +1 -1
  462. package/workflow/PendingApprovalsWidget.js +2 -1
  463. package/workflow/PendingApprovalsWidget.js.map +1 -1
  464. package/workflow/facets/WorkflowArtifactsTab.d.ts.map +1 -1
  465. package/workflow/facets/WorkflowArtifactsTab.js +2 -1
  466. package/workflow/facets/WorkflowArtifactsTab.js.map +1 -1
  467. package/workflow/facets/WorkflowUsageTab.d.ts.map +1 -1
  468. package/workflow/facets/WorkflowUsageTab.js +2 -1
  469. package/workflow/facets/WorkflowUsageTab.js.map +1 -1
  470. package/workflow/inspector/WorkflowSummaryPanel.d.ts.map +1 -1
  471. package/workflow/inspector/WorkflowSummaryPanel.js +2 -1
  472. package/workflow/inspector/WorkflowSummaryPanel.js.map +1 -1
  473. package/workflow/inspector/tabs/BranchesTab.d.ts.map +1 -1
  474. package/workflow/inspector/tabs/BranchesTab.js +2 -1
  475. package/workflow/inspector/tabs/BranchesTab.js.map +1 -1
  476. package/workflow/inspector/tabs/IterationTab.d.ts.map +1 -1
  477. package/workflow/inspector/tabs/IterationTab.js +2 -1
  478. package/workflow/inspector/tabs/IterationTab.js.map +1 -1
  479. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  480. package/workflow/instance/WorkflowInstanceDetailPanel.js +2 -1
  481. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  482. package/workspace/ExplorerTree.d.ts.map +1 -1
  483. package/workspace/ExplorerTree.js +2 -1
  484. package/workspace/ExplorerTree.js.map +1 -1
  485. package/workspace/WorkspaceContentSearch.d.ts.map +1 -1
  486. package/workspace/WorkspaceContentSearch.js +2 -1
  487. package/workspace/WorkspaceContentSearch.js.map +1 -1
  488. package/workspace/WorkspaceFileSearch.d.ts.map +1 -1
  489. package/workspace/WorkspaceFileSearch.js +2 -1
  490. package/workspace/WorkspaceFileSearch.js.map +1 -1
  491. package/workspace/WorkspaceSummary.d.ts.map +1 -1
  492. package/workspace/WorkspaceSummary.js +2 -1
  493. package/workspace/WorkspaceSummary.js.map +1 -1
@@ -1,16 +1,22 @@
1
1
  import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
2
2
  import { ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
3
3
  import type { JsonObject } from "@bufbuild/protobuf";
4
- import { ToolKind, resolveToolKind, resolveToolKindByName } from "@stigmer/sdk";
4
+ import {
5
+ ToolKind,
6
+ resolveToolKind,
7
+ resolveToolKindByName,
8
+ shellIntentFromArgs,
9
+ } from "@stigmer/sdk";
5
10
 
6
11
  /**
7
12
  * Discriminated tool categories for type-aware rendering.
8
13
  *
9
14
  * This is the presentation taxonomy. Classification (name -> kind) lives in
10
15
  * `@stigmer/sdk`'s `resolveToolKind` (single source of truth, shared with the
11
- * runner and Go CLI); this file maps each {@link ToolKind} to its presentation
12
- * metadata (label, primary argument). `"mcp"` covers tools originating from an
13
- * MCP server, whose names are dynamic.
16
+ * runner, @stigmer/ink, and the CLI's headless renderers); this file maps each
17
+ * {@link ToolKind} to its presentation metadata (label, primary argument).
18
+ * `"mcp"` covers tools originating from an MCP server, whose names are
19
+ * dynamic.
14
20
  */
15
21
  export type ToolCategory =
16
22
  | "shell"
@@ -497,42 +503,12 @@ export function extractIntentFromPreview(
497
503
  }
498
504
  }
499
505
 
500
- /**
501
- * The tool-call argument that carries a model-authored intent phrase for
502
- * SHELL tools (stigmer#276) a short human description of what the command
503
- * does and why, rendered as the row title with the command as secondary text.
504
- *
505
- * Two writers populate it, converged on one wire key by design: the native
506
- * harness's tool-intent middleware (`backend/services/runner/src/middleware/
507
- * tool-intent.ts`, `INTENT_ARG`) extends the shell tool's bind-time schema
508
- * with it, and the Cursor harness's built-in Shell tool carries it natively.
509
- * The shared, machine-checked contract is
510
- * `test/fixtures/tool-view/intent-title.json` — keep all three in lockstep.
511
- */
512
- export const SHELL_INTENT_ARG_FIELD = "description";
513
-
514
- /**
515
- * The intent-title extraction core: SHELL-kind-scoped on purpose, because
516
- * `description` means other things on other tools (a task tool's description
517
- * is the sub-agent subject, never a row title). Blank and non-string values
518
- * degrade to null — the caller falls back to the category label.
519
- */
520
- function extractIntentFromArgs(kind: ToolKind, args: JsonObject | undefined): string | null {
521
- if (kind !== ToolKind.SHELL || !args) return null;
522
- const value = args[SHELL_INTENT_ARG_FIELD];
523
- if (typeof value !== "string") return null;
524
- const trimmed = value.trim();
525
- return trimmed.length > 0 ? trimmed : null;
526
- }
527
-
528
- /**
529
- * Extracts the model-authored intent phrase from a SHELL tool call, or null
530
- * when absent (legacy executions, models that skipped the optional arg, and
531
- * every non-shell kind). See {@link SHELL_INTENT_ARG_FIELD}.
532
- */
533
- export function extractShellIntent(toolCall: ToolCall): string | null {
534
- return extractIntentFromArgs(resolveToolKind(toolCall), toolCall.args);
535
- }
506
+ // Intent-title extraction lives in @stigmer/sdk's tool-view module — the
507
+ // cross-surface single source of truth the intent-title.json fixture pins —
508
+ // so React, Ink, and the CLI's headless renderers share one implementation.
509
+ // Re-exported here because this module is where React's public tool-view API
510
+ // surfaced them first (#677).
511
+ export { SHELL_INTENT_ARG_FIELD, extractShellIntent } from "@stigmer/sdk";
536
512
 
537
513
  /**
538
514
  * Preview-string twin of {@link extractShellIntent} for surfaces that carry a
@@ -556,7 +532,7 @@ export function extractShellIntentFromPreview(
556
532
  try {
557
533
  const parsed = JSON.parse(argsPreview);
558
534
  if (typeof parsed !== "object" || parsed === null) return null;
559
- return extractIntentFromArgs(kind, parsed as JsonObject);
535
+ return shellIntentFromArgs(kind, parsed as JsonObject);
560
536
  } catch {
561
537
  return null;
562
538
  }
@@ -4,6 +4,7 @@ import { useCallback, useState } from "react";
4
4
  import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
5
5
  import type { PrincipalAccess } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
6
6
  import { cn } from "@stigmer/theme";
7
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
7
8
  import { getUserMessage } from "@stigmer/sdk";
8
9
  import { useShareFlow, type ShareFlowResource } from "./useShareFlow.js";
9
10
  import { GrantAccessForm } from "./GrantAccessForm.js";
@@ -83,7 +84,7 @@ export function PeopleWithAccess({
83
84
  )}
84
85
 
85
86
  {!isLoading && accessList.length > 0 && (
86
- <ul className="stg:space-y-1 stg:mt-2" aria-label="People with access">
87
+ <ul className={cn(UNSTYLED_LIST, "stg:space-y-1 stg:mt-2")} aria-label="People with access">
87
88
  {accessList.map((entry) => (
88
89
  <AccessEntry
89
90
  key={entry.principal?.id ?? "unknown"}
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useId, useMemo, useRef, useState } from "react";
4
4
  import type { ApiResourceRefView } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
5
5
  import { cn } from "@stigmer/theme";
6
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
6
7
  import { getUserMessage } from "@stigmer/sdk";
7
8
  import { useResourceAccess } from "./useResourceAccess.js";
8
9
  import { ProviderBadge, providerLabel } from "./ProviderBadge.js";
@@ -238,6 +239,7 @@ export function PrincipalPicker({
238
239
  role="listbox"
239
240
  aria-label="Organization members"
240
241
  className={cn(
242
+ UNSTYLED_LIST,
241
243
  "stg:absolute stg:z-10 stg:mt-1 stg:max-h-56 stg:w-full stg:overflow-auto stg:rounded-md stg:border stg:border-border stg:bg-popover stg:py-1 stg:shadow-md",
242
244
  )}
243
245
  >
@@ -4,6 +4,7 @@ import { useId } from "react";
4
4
  import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
5
5
  import type { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
6
6
  import { cn } from "@stigmer/theme";
7
+ import { UNSTYLED_FIELDSET } from "../internal/element-resets.js";
7
8
  import { useRoleSelector } from "./useRoleSelector.js";
8
9
 
9
10
  /** Props for {@link RoleSelector}. */
@@ -73,7 +74,7 @@ export function RoleSelector({
73
74
  }
74
75
 
75
76
  return (
76
- <fieldset className={cn("stg:space-y-1.5", className)}>
77
+ <fieldset className={cn(UNSTYLED_FIELDSET, "stg:space-y-1.5", className)}>
77
78
  <legend className="stg:text-xs stg:font-medium stg:text-foreground">Role</legend>
78
79
  <div className="stg:flex stg:flex-wrap stg:gap-2">
79
80
  {options.map((opt) => {
@@ -0,0 +1,446 @@
1
+ "use client";
2
+
3
+ import { type FormEvent, useCallback, useEffect, useId, useMemo, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage, toIdentityAccountUpdateInput } from "@stigmer/sdk";
6
+ import type { IdentityAccount } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
7
+ import { useMyIdentityAccount } from "./useMyIdentityAccount.js";
8
+ import { useUpdateIdentityAccount } from "./useUpdateIdentityAccount.js";
9
+ import { useResourceAvailable, ApiResourceKind } from "../deployment-mode.js";
10
+ import { useModelRegistry } from "../models/index.js";
11
+ import { HARNESS_META, type HarnessOption } from "../models/harness.js";
12
+ import { CloudFeatureNotice } from "../internal/CloudFeatureNotice.js";
13
+ import { StandingContextField } from "../internal/StandingContextField.js";
14
+ import { SpinnerIcon } from "../internal/SpinnerIcon.js";
15
+
16
+ /** Props for {@link AccountPreferencesPanel}. */
17
+ export interface AccountPreferencesPanelProps {
18
+ /** Fired with the updated resource after a successful save. */
19
+ readonly onUpdated?: (account: IdentityAccount) => void;
20
+ /** Additional CSS class names for the root container. */
21
+ readonly className?: string;
22
+ }
23
+
24
+ /**
25
+ * Self-contained editor for the current user's declared preferences
26
+ * (`IdentityAccountSpec.preferences.standing_context`).
27
+ *
28
+ * The declared text is snapshotted into the user's own eligible agent
29
+ * executions and delivered to the agent as background context.
30
+ * Self-service: the account is resolved via `whoAmI()` and updated
31
+ * through the caller's self-ownership permission — no explicit
32
+ * permission check is needed. On save, calls `identityAccount.update()`
33
+ * with the complete mapped input (full-spec-replace safety) and fires
34
+ * `onUpdated`.
35
+ *
36
+ * Cloud-only: the OSS local server has no IdentityAccount (local mode
37
+ * is single-user, so the organization's preferences cover it). In local
38
+ * mode the panel renders a {@link CloudFeatureNotice} instead.
39
+ *
40
+ * All visual properties flow through `--stgm-*` design tokens. Zero
41
+ * dependencies on Console routing, auth context, or layout — platform
42
+ * builders can embed it directly:
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * <AccountPreferencesPanel />
47
+ * ```
48
+ */
49
+ export function AccountPreferencesPanel({
50
+ onUpdated,
51
+ className,
52
+ }: AccountPreferencesPanelProps) {
53
+ const baseId = useId();
54
+ const available = useResourceAvailable(ApiResourceKind.identity_account);
55
+
56
+ if (!available) {
57
+ return (
58
+ <CloudFeatureNotice className={className}>
59
+ Personal preferences require Stigmer Cloud. Local mode is
60
+ single-user, so the organization&apos;s preferences apply to every
61
+ execution — set standing context there instead.
62
+ </CloudFeatureNotice>
63
+ );
64
+ }
65
+
66
+ return (
67
+ <AccountPreferencesForm
68
+ baseId={baseId}
69
+ onUpdated={onUpdated}
70
+ className={className}
71
+ />
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Inner form, mounted only when IdentityAccount is available — keeps the
77
+ * data hooks from issuing doomed RPCs against a local server.
78
+ */
79
+ function AccountPreferencesForm({
80
+ baseId,
81
+ onUpdated,
82
+ className,
83
+ }: {
84
+ readonly baseId: string;
85
+ readonly onUpdated?: (account: IdentityAccount) => void;
86
+ readonly className?: string;
87
+ }) {
88
+ const {
89
+ account,
90
+ isLoading: isFetching,
91
+ error: fetchError,
92
+ refetch,
93
+ } = useMyIdentityAccount();
94
+
95
+ const {
96
+ update,
97
+ isUpdating,
98
+ error: updateError,
99
+ clearError,
100
+ } = useUpdateIdentityAccount();
101
+
102
+ const [standingContext, setStandingContext] = useState("");
103
+ const [defaultHarness, setDefaultHarness] = useState("");
104
+ const [defaultNativeModel, setDefaultNativeModel] = useState("");
105
+ const [defaultCursorModel, setDefaultCursorModel] = useState("");
106
+
107
+ const serverPreferences = account?.spec?.preferences;
108
+ const serverStandingContext = serverPreferences?.standingContext ?? "";
109
+ const serverDefaultHarness = serverPreferences?.defaultHarness ?? "";
110
+ const serverDefaultNativeModel = serverPreferences?.defaultNativeModel ?? "";
111
+ const serverDefaultCursorModel = serverPreferences?.defaultCursorModel ?? "";
112
+
113
+ // Sync the form fields when server data changes.
114
+ useEffect(() => {
115
+ if (!account) return;
116
+ const prefs = account.spec?.preferences;
117
+ setStandingContext(prefs?.standingContext ?? "");
118
+ setDefaultHarness(prefs?.defaultHarness ?? "");
119
+ setDefaultNativeModel(prefs?.defaultNativeModel ?? "");
120
+ setDefaultCursorModel(prefs?.defaultCursorModel ?? "");
121
+ }, [account]);
122
+
123
+ const hasChanges = useMemo(
124
+ () =>
125
+ standingContext.trim() !== serverStandingContext ||
126
+ defaultHarness !== serverDefaultHarness ||
127
+ defaultNativeModel !== serverDefaultNativeModel ||
128
+ defaultCursorModel !== serverDefaultCursorModel,
129
+ [
130
+ standingContext,
131
+ defaultHarness,
132
+ defaultNativeModel,
133
+ defaultCursorModel,
134
+ serverStandingContext,
135
+ serverDefaultHarness,
136
+ serverDefaultNativeModel,
137
+ serverDefaultCursorModel,
138
+ ],
139
+ );
140
+
141
+ const canSubmit = hasChanges && !isUpdating;
142
+
143
+ const handleDiscard = useCallback(() => {
144
+ setStandingContext(serverStandingContext);
145
+ setDefaultHarness(serverDefaultHarness);
146
+ setDefaultNativeModel(serverDefaultNativeModel);
147
+ setDefaultCursorModel(serverDefaultCursorModel);
148
+ clearError();
149
+ }, [
150
+ serverStandingContext,
151
+ serverDefaultHarness,
152
+ serverDefaultNativeModel,
153
+ serverDefaultCursorModel,
154
+ clearError,
155
+ ]);
156
+
157
+ const handleSubmit = useCallback(
158
+ async (e: FormEvent) => {
159
+ e.preventDefault();
160
+ if (!canSubmit || !account) return;
161
+
162
+ clearError();
163
+ try {
164
+ // update() is a full-spec replace: spread the complete mapped input
165
+ // so unedited spec fields survive. `preferences` is a nested message,
166
+ // so the override spreads the mapper's COMPLETE preferences too —
167
+ // fields this form does not own (added by later phases) survive.
168
+ const mapped = toIdentityAccountUpdateInput(account);
169
+ const updated = await update({
170
+ ...mapped,
171
+ preferences: {
172
+ ...mapped.preferences,
173
+ standingContext: standingContext.trim() || undefined,
174
+ defaultHarness: defaultHarness || undefined,
175
+ defaultNativeModel: defaultNativeModel || undefined,
176
+ defaultCursorModel: defaultCursorModel || undefined,
177
+ },
178
+ });
179
+ refetch();
180
+ onUpdated?.(updated);
181
+ } catch {
182
+ // error state is managed by useUpdateIdentityAccount
183
+ }
184
+ },
185
+ [
186
+ canSubmit,
187
+ account,
188
+ standingContext,
189
+ defaultHarness,
190
+ defaultNativeModel,
191
+ defaultCursorModel,
192
+ update,
193
+ clearError,
194
+ refetch,
195
+ onUpdated,
196
+ ],
197
+ );
198
+
199
+ // -----------------------------------------------------------------------
200
+ // Loading state
201
+ // -----------------------------------------------------------------------
202
+
203
+ if (isFetching && !account) {
204
+ return (
205
+ <div
206
+ className={cn("stg:space-y-4", className)}
207
+ aria-busy="true"
208
+ aria-label="Loading account preferences"
209
+ >
210
+ <div className="stg:bg-muted-subtle stg:h-28 stg:animate-pulse stg:rounded" />
211
+ <div className="stg:bg-muted-subtle stg:h-8 stg:w-32 stg:animate-pulse stg:rounded" />
212
+ </div>
213
+ );
214
+ }
215
+
216
+ // -----------------------------------------------------------------------
217
+ // Fetch error
218
+ // -----------------------------------------------------------------------
219
+
220
+ if (fetchError) {
221
+ return (
222
+ <div className={cn("stg:space-y-3", className)} role="alert">
223
+ <p className="stg:text-destructive stg:text-sm">
224
+ {getUserMessage(fetchError)}
225
+ </p>
226
+ <button
227
+ type="button"
228
+ onClick={refetch}
229
+ className={cn(
230
+ "stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium",
231
+ "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
232
+ )}
233
+ >
234
+ Retry
235
+ </button>
236
+ </div>
237
+ );
238
+ }
239
+
240
+ if (!account) return null;
241
+
242
+ // -----------------------------------------------------------------------
243
+ // Render
244
+ // -----------------------------------------------------------------------
245
+
246
+ return (
247
+ <form onSubmit={handleSubmit} className={cn("stg:space-y-4", className)}>
248
+ <StandingContextField
249
+ id={`${baseId}-standing-context`}
250
+ value={standingContext}
251
+ onChange={setStandingContext}
252
+ disabled={isUpdating}
253
+ placeholder={
254
+ "e.g. Keep answers terse. I prefer TypeScript examples. My timezone is IST."
255
+ }
256
+ helperText="Shared with agents as background context — not instructions. Applies only to executions you start and is visible on those execution records."
257
+ />
258
+
259
+ <div className="stg:space-y-3">
260
+ <div>
261
+ <h3 className="stg:text-xs stg:font-medium stg:text-foreground">
262
+ Execution defaults
263
+ </h3>
264
+ <p className="stg:text-[0.65rem] stg:text-muted-foreground">
265
+ Seed new sessions across your devices and the CLI. An explicit
266
+ pick in the composer always wins for that device.
267
+ </p>
268
+ </div>
269
+
270
+ <DefaultHarnessRadioGroup
271
+ baseId={baseId}
272
+ value={defaultHarness}
273
+ onChange={setDefaultHarness}
274
+ disabled={isUpdating}
275
+ />
276
+
277
+ <div className="stg:grid stg:gap-3 stg:sm:grid-cols-2">
278
+ <DefaultModelSelect
279
+ id={`${baseId}-default-native-model`}
280
+ harness="native"
281
+ label={`Default model — ${HARNESS_META.native.label}`}
282
+ value={defaultNativeModel}
283
+ onChange={setDefaultNativeModel}
284
+ disabled={isUpdating}
285
+ />
286
+ <DefaultModelSelect
287
+ id={`${baseId}-default-cursor-model`}
288
+ harness="cursor"
289
+ label={`Default model — ${HARNESS_META.cursor.label}`}
290
+ value={defaultCursorModel}
291
+ onChange={setDefaultCursorModel}
292
+ disabled={isUpdating}
293
+ />
294
+ </div>
295
+ </div>
296
+
297
+ {updateError && (
298
+ <p className="stg:text-destructive stg:text-[0.65rem]" role="alert">
299
+ {getUserMessage(updateError)}
300
+ </p>
301
+ )}
302
+
303
+ <div className="stg:flex stg:items-center stg:gap-2">
304
+ <button
305
+ type="submit"
306
+ disabled={!canSubmit}
307
+ className={cn(
308
+ "stg:inline-flex stg:items-center stg:gap-1.5 stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs stg:font-medium",
309
+ "stg:bg-primary stg:text-primary-foreground stg:hover:bg-primary-hover",
310
+ "stg:disabled:pointer-events-none stg:disabled:opacity-40",
311
+ )}
312
+ >
313
+ {isUpdating && <SpinnerIcon size={12} />}
314
+ Save changes
315
+ </button>
316
+
317
+ {hasChanges && !isUpdating && (
318
+ <button
319
+ type="button"
320
+ onClick={handleDiscard}
321
+ className={cn(
322
+ "stg:rounded-md stg:px-3 stg:py-1.5 stg:text-xs",
323
+ "stg:text-muted-foreground stg:hover:text-foreground stg:hover:bg-accent-hover",
324
+ )}
325
+ >
326
+ Discard
327
+ </button>
328
+ )}
329
+ </div>
330
+ </form>
331
+ );
332
+ }
333
+
334
+ /**
335
+ * Only harnesses with a shipped runtime are offerable as a default — must
336
+ * stay in lockstep with the proto's `default_harness` in-list validation.
337
+ */
338
+ const OFFERABLE_HARNESSES: readonly HarnessOption[] = ["native", "cursor"];
339
+
340
+ /**
341
+ * Default-harness choice: Platform default plus each shipped harness.
342
+ * A mutually exclusive, always-visible set — radio group, not a select.
343
+ */
344
+ function DefaultHarnessRadioGroup({
345
+ baseId,
346
+ value,
347
+ onChange,
348
+ disabled,
349
+ }: {
350
+ readonly baseId: string;
351
+ readonly value: string;
352
+ readonly onChange: (value: string) => void;
353
+ readonly disabled: boolean;
354
+ }) {
355
+ const name = `${baseId}-default-harness`;
356
+ const options: readonly { value: string; label: string }[] = [
357
+ { value: "", label: "Platform default" },
358
+ ...OFFERABLE_HARNESSES.map((h) => ({ value: h, label: HARNESS_META[h].label })),
359
+ ];
360
+
361
+ return (
362
+ <fieldset className="stg:space-y-1" disabled={disabled}>
363
+ <legend className="stg:text-xs stg:font-medium stg:text-foreground">
364
+ Default harness
365
+ </legend>
366
+ <div className="stg:flex stg:flex-wrap stg:gap-x-4 stg:gap-y-1">
367
+ {options.map((option) => (
368
+ <label
369
+ key={option.value}
370
+ className={cn(
371
+ "stg:inline-flex stg:cursor-pointer stg:items-center stg:gap-1.5 stg:text-xs stg:text-foreground",
372
+ disabled && "stg:cursor-default stg:opacity-50",
373
+ )}
374
+ >
375
+ <input
376
+ type="radio"
377
+ name={name}
378
+ value={option.value}
379
+ checked={value === option.value}
380
+ onChange={() => onChange(option.value)}
381
+ disabled={disabled}
382
+ className="stg:accent-primary stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring"
383
+ />
384
+ {option.label}
385
+ </label>
386
+ ))}
387
+ </div>
388
+ </fieldset>
389
+ );
390
+ }
391
+
392
+ /**
393
+ * Per-harness default model select, fed by the harness-filtered registry.
394
+ *
395
+ * A saved model that the registry no longer lists is rendered as its own
396
+ * "(unavailable)" option so the select never lies about the stored value;
397
+ * composers self-heal such a preference to the platform default on read.
398
+ */
399
+ function DefaultModelSelect({
400
+ id,
401
+ harness,
402
+ label,
403
+ value,
404
+ onChange,
405
+ disabled,
406
+ }: {
407
+ readonly id: string;
408
+ readonly harness: HarnessOption;
409
+ readonly label: string;
410
+ readonly value: string;
411
+ readonly onChange: (value: string) => void;
412
+ readonly disabled: boolean;
413
+ }) {
414
+ const { models, isLoading } = useModelRegistry({ harness });
415
+ const isStale = value !== "" && !isLoading && !models.some((m) => m.modelId === value);
416
+
417
+ return (
418
+ <div className="stg:space-y-1">
419
+ <label
420
+ htmlFor={id}
421
+ className="stg:text-xs stg:font-medium stg:text-foreground"
422
+ >
423
+ {label}
424
+ </label>
425
+ <select
426
+ id={id}
427
+ value={value}
428
+ onChange={(e) => onChange(e.target.value)}
429
+ disabled={disabled || isLoading}
430
+ className={cn(
431
+ "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",
432
+ "stg:focus-visible:outline-none stg:focus-visible:ring-1 stg:focus-visible:ring-ring",
433
+ "stg:disabled:pointer-events-none stg:disabled:opacity-50",
434
+ )}
435
+ >
436
+ <option value="">Platform default</option>
437
+ {isStale && <option value={value}>{value} (unavailable)</option>}
438
+ {models.map((model) => (
439
+ <option key={model.modelId} value={model.modelId}>
440
+ {model.displayName || model.modelId}
441
+ </option>
442
+ ))}
443
+ </select>
444
+ </div>
445
+ );
446
+ }