@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,7 +1,8 @@
1
1
  "use client";
2
2
 
3
- import { useCallback, useEffect, useState } from "react";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
4
  import { getUserMessage, type McpServerUsageInput, type ResourceRef } from "@stigmer/sdk";
5
+ import type { AccountExecutionDefaults } from "../identity-account/useAccountExecutionDefaults.js";
5
6
  import type { AgentResolution } from "../agent/index.js";
6
7
  import { useDefaultAgent } from "../agent/index.js";
7
8
  import { useModelRegistry } from "../models/index.js";
@@ -102,6 +103,26 @@ export interface UseNewSessionFlowOptions {
102
103
  * @default DEFAULT_HARNESS ("native")
103
104
  */
104
105
  readonly defaultHarness?: HarnessOption;
106
+ /**
107
+ * The user's account-level execution defaults
108
+ * (`IdentityAccountPreferences.default_*`), typically from
109
+ * `useAccountExecutionDefaults()`. A SEED in the layered precedence —
110
+ * explicit device-local choices always outrank it:
111
+ *
112
+ * - harness: stored choice > `accountDefaults.harness` >
113
+ * {@link defaultHarness} > platform default. May arrive after mount
114
+ * (whoAmI resolves async); a late value still seeds unless the user
115
+ * has already picked a harness this mount.
116
+ * - model: stored per-harness choice > the account's model for the
117
+ * active harness (validated against the registry; a stale model
118
+ * silently falls through) > the harness default.
119
+ *
120
+ * Seeded values are never persisted to localStorage — the account
121
+ * preference keeps applying until the user decides. Ignored for the
122
+ * `"guest"` audience (platform share policy owns guest config), and
123
+ * consumers must not fetch identity for guest/embed surfaces.
124
+ */
125
+ readonly accountDefaults?: AccountExecutionDefaults;
105
126
  /**
106
127
  * Who this flow serves. `"guest"` adapts the orchestration to the
107
128
  * guest principal's permission model: the org default-agent lookup
@@ -162,7 +183,12 @@ export interface UseNewSessionFlowReturn {
162
183
  /** Switch the harness. Resets the model if invalid for the new harness. */
163
184
  readonly setHarness: (harness: HarnessOption) => void;
164
185
 
165
- /** Currently selected model ID (persisted per-harness to localStorage). */
186
+ /**
187
+ * The model an untouched send will run: the explicit device pick when
188
+ * one exists (persisted per-harness to localStorage), else the account
189
+ * default for the active harness. `undefined` resolves to the harness
190
+ * default downstream.
191
+ */
166
192
  readonly modelId: string | undefined;
167
193
  /** Update the selected model. Automatically persists to localStorage. */
168
194
  readonly setModelId: (id: string) => void;
@@ -269,6 +295,10 @@ export function useNewSessionFlow(
269
295
  sessionContext,
270
296
  } = options;
271
297
  const isGuest = options.audience === "guest";
298
+ // Guests never inherit account defaults — the platform share policy owns
299
+ // guest execution config (GUEST_HARNESS reasoning), and identity-derived
300
+ // preferences must never shape a share/embed surface.
301
+ const accountDefaults = isGuest ? undefined : options.accountDefaults;
272
302
  // Guests never carry a client pin: guest execution config is owned by
273
303
  // the server-side share policy (GUEST_HARNESS reasoning). Validated at
274
304
  // render so a statically-wrong pin (fast tier, no model) fails in the
@@ -293,13 +323,30 @@ export function useNewSessionFlow(
293
323
  // touch localStorage: a browser previously used in the Console must not
294
324
  // leak its stored harness into a share/embed session.
295
325
  if (isGuest) return GUEST_HARNESS;
296
- if (typeof window === "undefined") return defaultHarness ?? DEFAULT_HARNESS;
326
+ if (typeof window === "undefined")
327
+ return accountDefaults?.harness ?? defaultHarness ?? DEFAULT_HARNESS;
297
328
  // Only explicit user choices are persisted (see setHarness), so a
298
- // stored value always outranks the embedder's defaultHarness.
329
+ // stored value always outranks the account default and the embedder's
330
+ // defaultHarness.
299
331
  const stored = localStorage.getItem(STORAGE_KEY_HARNESS);
300
332
  if (stored === "native" || stored === "cursor") return stored;
301
- return defaultHarness ?? DEFAULT_HARNESS;
333
+ return accountDefaults?.harness ?? defaultHarness ?? DEFAULT_HARNESS;
302
334
  });
335
+ // Set once the user picks a harness this mount — a late-arriving account
336
+ // default must never override an explicit choice (the composer's
337
+ // userOverrodeModel idiom).
338
+ const harnessTouchedRef = useRef(false);
339
+
340
+ // Account defaults resolve async (whoAmI): when the harness seed arrives
341
+ // after mount, apply it once — unless the user has picked or a stored
342
+ // choice exists. Never persisted: seeding must not masquerade as a user
343
+ // choice, or the account preference would stop applying elsewhere.
344
+ useEffect(() => {
345
+ const seed = accountDefaults?.harness;
346
+ if (isGuest || harnessTouchedRef.current || !seed) return;
347
+ if (typeof window !== "undefined" && localStorage.getItem(STORAGE_KEY_HARNESS)) return;
348
+ setHarnessRaw(seed);
349
+ }, [isGuest, accountDefaults?.harness]);
303
350
 
304
351
  const stigmer = useStigmer();
305
352
  const { getModel, isLoading: isModelsLoading } = useModelRegistry({ harness });
@@ -326,8 +373,26 @@ export function useNewSessionFlow(
326
373
 
327
374
  const validModelId = modelId && getModel(modelId) ? modelId : undefined;
328
375
 
376
+ // The account's model for the active harness, registry-validated the same
377
+ // way as the stored choice (a stale/removed preference silently falls
378
+ // through to the harness default — self-healing). Derived, never written
379
+ // into `modelId` state: the persist effect below stores only explicit
380
+ // choices, and a derived seed cannot leak into localStorage.
381
+ const accountModelForHarness =
382
+ harness === "cursor" ? accountDefaults?.cursorModel : accountDefaults?.nativeModel;
383
+ const accountModelId =
384
+ accountModelForHarness && getModel(accountModelForHarness)
385
+ ? accountModelForHarness
386
+ : undefined;
387
+
388
+ // Layered precedence: explicit device pick > account default. The result
389
+ // feeds the composer's model pill AND the submit path, so the pill always
390
+ // shows what an untouched send will run (#663).
391
+ const effectiveModelId = validModelId ?? accountModelId;
392
+
329
393
  const setHarness = useCallback(
330
394
  (h: HarnessOption) => {
395
+ harnessTouchedRef.current = true;
331
396
  setHarnessRaw(h);
332
397
  // Guests have no harness picker; if a caller invokes this anyway, the
333
398
  // guest surface must never write into the Console's preference keys.
@@ -415,8 +480,10 @@ export function useNewSessionFlow(
415
480
  // The owner pin wins over the composer and the restored
416
481
  // preference (#664); the pinned tier is stamped only as
417
482
  // "fast" — standard stays off the wire, preserving the #357
418
- // UNSPECIFIED-vs-explicit telemetry distinction.
419
- modelName: pinnedModelName ?? selectedModel ?? validModelId,
483
+ // UNSPECIFIED-vs-explicit telemetry distinction. The effective
484
+ // model carries the account-default seed explicitly (DD-003:
485
+ // the preference is a seed; the execution spec is the record).
486
+ modelName: pinnedModelName ?? selectedModel ?? effectiveModelId,
420
487
  runtimeEnv,
421
488
  attachments: context?.attachments,
422
489
  interactionMode: context?.interactionMode,
@@ -514,7 +581,7 @@ export function useNewSessionFlow(
514
581
  autoApproveAll,
515
582
  adapter,
516
583
  getRuntimeEnv,
517
- validModelId,
584
+ effectiveModelId,
518
585
  pinnedModelName,
519
586
  pinnedServiceTier,
520
587
  workspace,
@@ -539,7 +606,7 @@ export function useNewSessionFlow(
539
606
  return {
540
607
  harness,
541
608
  setHarness,
542
- modelId: validModelId,
609
+ modelId: effectiveModelId,
543
610
  setModelId,
544
611
  agentRef,
545
612
  setAgentRef,
@@ -41,6 +41,25 @@ export interface ModelCostEntry {
41
41
  readonly callCount: number;
42
42
  }
43
43
 
44
+ /**
45
+ * Per-execution model provenance from billing records (stigmer/stigmer#362).
46
+ */
47
+ export interface ExecutionUsageEntry {
48
+ /** Execution identifier (`metadata.id`). */
49
+ readonly executionId: string;
50
+ /**
51
+ * Billing-resolved primary model — what the provider actually served.
52
+ * For a Cursor Auto execution this is the after-the-fact answer to
53
+ * "which model did Auto pick", which the requested model (empty by
54
+ * definition there) can never give.
55
+ */
56
+ readonly resolvedModel: string;
57
+ /** Billable cost in USD for this execution. */
58
+ readonly billableCostUsd: number;
59
+ /** `true` while this execution's records are still provisional. */
60
+ readonly isEstimated: boolean;
61
+ }
62
+
44
63
  /** Return value of {@link useSessionUsage}. */
45
64
  export interface UseSessionUsageReturn {
46
65
  /** Aggregate estimated cost in USD across all models. */
@@ -59,6 +78,13 @@ export interface UseSessionUsageReturn {
59
78
  readonly llmCallCount: number;
60
79
  /** Per-model cost and token breakdown. */
61
80
  readonly modelBreakdown: readonly ModelCostEntry[];
81
+ /**
82
+ * Per-execution resolved model + cost, chronological, from billing
83
+ * records (#362). Empty until the first authoritative record lands —
84
+ * the streaming fallback deliberately contributes none, because the
85
+ * runner only knows what it REQUESTED, never what the provider served.
86
+ */
87
+ readonly executionBreakdown: readonly ExecutionUsageEntry[];
62
88
  /** Model with the highest usage in this session. */
63
89
  readonly primaryModel: string;
64
90
  /** Provider of the primary model. */
@@ -82,6 +108,7 @@ const EMPTY: UseSessionUsageReturn = {
82
108
  cacheCreationTokens: 0,
83
109
  llmCallCount: 0,
84
110
  modelBreakdown: [],
111
+ executionBreakdown: [],
85
112
  primaryModel: "",
86
113
  primaryProvider: "",
87
114
  hasUsage: false,
@@ -122,6 +149,12 @@ function mapReport(report: GetSessionUsageReportOutput): UseSessionUsageReturn {
122
149
  cacheCreationTokens: Number(agg.cacheCreationInputTokens),
123
150
  llmCallCount,
124
151
  modelBreakdown: report.modelBreakdown.map(mapModelUsage),
152
+ executionBreakdown: report.executions.map((e) => ({
153
+ executionId: e.executionId,
154
+ resolvedModel: e.primaryModel,
155
+ billableCostUsd: microsToUsd(e.billableCostMicros),
156
+ isEstimated: e.isEstimated,
157
+ })),
125
158
  primaryModel: agg.primaryModel,
126
159
  primaryProvider: agg.primaryProvider,
127
160
  hasUsage: llmCallCount > 0 || totalTokens > 0 || billableCost > 0,
@@ -169,6 +202,10 @@ function aggregateStreamingUsage(
169
202
  cacheReadTokens,
170
203
  cacheCreationTokens,
171
204
  llmCallCount: turnCount,
205
+ // No executionBreakdown here on purpose: the runner only knows the
206
+ // REQUESTED model; resolved-model rows exist only once billing
207
+ // records land (#362).
208
+ executionBreakdown: [],
172
209
  modelBreakdown: model
173
210
  ? [
174
211
  {
@@ -0,0 +1,25 @@
1
+ "use client";
2
+
3
+ import { useId } from "react";
4
+ import { AccountPreferencesPanel } from "../identity-account/AccountPreferencesPanel.js";
5
+
6
+ /** Settings section for editing the current user's declared preferences. */
7
+ export function AccountPreferencesSection() {
8
+ const headingId = useId();
9
+
10
+ return (
11
+ <section aria-labelledby={headingId}>
12
+ <h2
13
+ id={headingId}
14
+ className="stg:text-foreground stg:mb-1 stg:text-sm stg:font-semibold"
15
+ >
16
+ Account Preferences
17
+ </h2>
18
+ <p className="stg:text-muted-foreground stg:mb-6 stg:text-xs">
19
+ Personal standing context shared with agents on executions you run.
20
+ </p>
21
+
22
+ <AccountPreferencesPanel />
23
+ </section>
24
+ );
25
+ }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import { useId } from "react";
4
+ import { OrgPreferencesPanel } from "../organization/OrgPreferencesPanel.js";
5
+ import { useOrg } from "../organization/OrgProvider.js";
6
+
7
+ /** Settings section for editing the active organization's declared preferences. */
8
+ export function OrgPreferencesSection() {
9
+ const headingId = useId();
10
+ const { activeOrg } = useOrg();
11
+ const orgId = activeOrg?.metadata?.id ?? "";
12
+
13
+ return (
14
+ <section aria-labelledby={headingId}>
15
+ <h2
16
+ id={headingId}
17
+ className="stg:text-foreground stg:mb-1 stg:text-sm stg:font-semibold"
18
+ >
19
+ Organization Preferences
20
+ </h2>
21
+ <p className="stg:text-muted-foreground stg:mb-6 stg:text-xs">
22
+ Standing context shared with agents on every execution run by this
23
+ organization&apos;s members.
24
+ </p>
25
+
26
+ {!orgId ? (
27
+ <p className="stg:text-muted-foreground stg:py-4 stg:text-center stg:text-xs">
28
+ Select an organization to view its preferences.
29
+ </p>
30
+ ) : (
31
+ <OrgPreferencesPanel orgId={orgId} />
32
+ )}
33
+ </section>
34
+ );
35
+ }
@@ -0,0 +1,27 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { SETTINGS_NAV_GROUPS } from "../settings-nav";
3
+
4
+ // The nav model is the single source for the sidebar AND both client-app
5
+ // landing grids — these entries disappearing would silently orphan the
6
+ // preference pages everywhere at once.
7
+ describe("SETTINGS_NAV_GROUPS preference entries", () => {
8
+ it("lists org preferences in the Organization group", () => {
9
+ const organization = SETTINGS_NAV_GROUPS.find(
10
+ (g) => g.label === "Organization",
11
+ );
12
+ expect(organization).toBeDefined();
13
+ expect(
14
+ organization!.items.find((i) => i.href === "/settings/org-preferences")
15
+ ?.label,
16
+ ).toBe("Preferences");
17
+ });
18
+
19
+ it("lists account preferences in the Account group", () => {
20
+ const account = SETTINGS_NAV_GROUPS.find((g) => g.label === "Account");
21
+ expect(account).toBeDefined();
22
+ expect(
23
+ account!.items.find((i) => i.href === "/settings/account-preferences")
24
+ ?.label,
25
+ ).toBe("Preferences");
26
+ });
27
+ });
@@ -48,6 +48,7 @@ describe("useSettingsNavGroups", () => {
48
48
  verdicts = {
49
49
  can_manage_model_pricing: true,
50
50
  can_manage_cursor_accounts: true,
51
+ can_view_provider_standing: true,
51
52
  };
52
53
  render(<GroupsProbe />);
53
54
 
@@ -56,7 +57,7 @@ describe("useSettingsNavGroups", () => {
56
57
  `${BASE_LABELS},${PLATFORM_SETTINGS_NAV_GROUP.label}`,
57
58
  );
58
59
  expect(el.getAttribute("data-platform-items")).toBe(
59
- "Pricing Governance,Cursor Accounts",
60
+ "Pricing Governance,Cursor Accounts,Provider Standing",
60
61
  );
61
62
  });
62
63
 
@@ -78,6 +79,15 @@ describe("useSettingsNavGroups", () => {
78
79
  );
79
80
  });
80
81
 
82
+ it("filters per item: standing-only operator sees only Provider Standing", () => {
83
+ verdicts = { can_view_provider_standing: true };
84
+ render(<GroupsProbe />);
85
+
86
+ expect(screen.getByTestId("groups").getAttribute("data-platform-items")).toBe(
87
+ "Provider Standing",
88
+ );
89
+ });
90
+
81
91
  it("returns exactly the base groups when not authorized", () => {
82
92
  function IdentityProbe() {
83
93
  const groups = useSettingsNavGroups();
@@ -10,6 +10,8 @@ export { BillingSection } from "./BillingSection.js";
10
10
  export type { BillingSectionProps } from "./BillingSection.js";
11
11
  export { MembersSection } from "./MembersSection.js";
12
12
  export { OrgProfileSection } from "./OrgProfileSection.js";
13
+ export { OrgPreferencesSection } from "./OrgPreferencesSection.js";
14
+ export { AccountPreferencesSection } from "./AccountPreferencesSection.js";
13
15
  export { EnvironmentsSection } from "./EnvironmentsSection.js";
14
16
  export { InvitationsSection } from "./InvitationsSection.js";
15
17
  export { IdentityProvidersSection } from "./IdentityProvidersSection.js";
@@ -1,5 +1,6 @@
1
1
  import type { ComponentType } from "react";
2
2
  import {
3
+ Activity,
3
4
  AppWindow,
4
5
  BarChart3,
5
6
  Box,
@@ -12,6 +13,8 @@ import {
12
13
  Plug,
13
14
  Scale,
14
15
  ShieldCheck,
16
+ SlidersHorizontal,
17
+ UserCog,
15
18
  Users,
16
19
  } from "lucide-react";
17
20
 
@@ -54,6 +57,11 @@ export const SETTINGS_NAV_GROUPS: readonly SettingsNavGroup[] = [
54
57
  "Manage your team, organization identity, and identity providers.",
55
58
  items: [
56
59
  { href: "/settings/org-profile", label: "Org Profile", icon: Building2 },
60
+ {
61
+ href: "/settings/org-preferences",
62
+ label: "Preferences",
63
+ icon: SlidersHorizontal,
64
+ },
57
65
  { href: "/settings/members", label: "Members", icon: Users },
58
66
  { href: "/settings/invitations", label: "Invitations", icon: Link },
59
67
  {
@@ -91,6 +99,17 @@ export const SETTINGS_NAV_GROUPS: readonly SettingsNavGroup[] = [
91
99
  { href: "/settings/usage", label: "Usage", icon: BarChart3 },
92
100
  ],
93
101
  },
102
+ {
103
+ label: "Account",
104
+ description: "Personal settings that apply to you across the platform.",
105
+ items: [
106
+ {
107
+ href: "/settings/account-preferences",
108
+ label: "Preferences",
109
+ icon: UserCog,
110
+ },
111
+ ],
112
+ },
94
113
  ];
95
114
 
96
115
  /**
@@ -123,5 +142,11 @@ export const PLATFORM_SETTINGS_NAV_GROUP: SettingsNavGroup = {
123
142
  icon: MousePointerClick,
124
143
  requiredPermission: "can_manage_cursor_accounts",
125
144
  },
145
+ {
146
+ href: "/settings/provider-standing",
147
+ label: "Provider Standing",
148
+ icon: Activity,
149
+ requiredPermission: "can_view_provider_standing",
150
+ },
126
151
  ],
127
152
  };
@@ -52,14 +52,21 @@ export function useSettingsNavGroups(): readonly SettingsNavGroup[] {
52
52
  "can_manage_cursor_accounts",
53
53
  { fail: "closed" },
54
54
  );
55
+ const providerStanding = useCheckPermission(
56
+ PLATFORM_RESOURCE,
57
+ "can_view_provider_standing",
58
+ { fail: "closed" },
59
+ );
55
60
 
56
61
  const pricingAllowed = pricing.allowed;
57
62
  const cursorAccountsAllowed = cursorAccounts.allowed;
63
+ const providerStandingAllowed = providerStanding.allowed;
58
64
 
59
65
  return useMemo(() => {
60
66
  const verdicts: Record<string, boolean> = {
61
67
  can_manage_model_pricing: pricingAllowed,
62
68
  can_manage_cursor_accounts: cursorAccountsAllowed,
69
+ can_view_provider_standing: providerStandingAllowed,
63
70
  };
64
71
 
65
72
  const visibleItems = PLATFORM_SETTINGS_NAV_GROUP.items.filter(
@@ -77,5 +84,5 @@ export function useSettingsNavGroups(): readonly SettingsNavGroup[] {
77
84
  ...SETTINGS_NAV_GROUPS,
78
85
  { ...PLATFORM_SETTINGS_NAV_GROUP, items: visibleItems },
79
86
  ];
80
- }, [pricingAllowed, cursorAccountsAllowed]);
87
+ }, [pricingAllowed, cursorAccountsAllowed, providerStandingAllowed]);
81
88
  }
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useId, useMemo, useRef, useState, type FormEvent } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
5
  import { DialogShell } from "../internal/DialogShell.js";
6
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
6
7
  import {
7
8
  MAX_ALLOWED_ORIGINS,
8
9
  StigmerError,
@@ -1316,7 +1317,7 @@ function OriginsEditor({
1316
1317
  </p>
1317
1318
 
1318
1319
  {draft.allowedOrigins.length > 0 && (
1319
- <ul className="stg:mt-2 stg:flex stg:flex-col stg:divide-y stg:divide-border stg:rounded-md stg:border stg:border-border">
1320
+ <ul className={cn(UNSTYLED_LIST, "stg:mt-2 stg:flex stg:flex-col stg:divide-y stg:divide-border stg:rounded-md stg:border stg:border-border")}>
1320
1321
  {draft.allowedOrigins.map((origin) => (
1321
1322
  <li
1322
1323
  key={origin}
@@ -15,6 +15,7 @@ import type { RecentActivityEntry, RecentActivityGroup } from "../activity/types
15
15
  import { groupRecentActivityByTime } from "../activity/group-activity.js";
16
16
  import { formatRelativeTime } from "../activity/format-relative-time.js";
17
17
  import { recentActivityStatusBadge } from "../activity/entry-status-badge.js";
18
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
18
19
  import { ScrollArea } from "../internal/scroll-area.js";
19
20
  import {
20
21
  Tooltip,
@@ -313,7 +314,7 @@ function ActivityGroupList({
313
314
  <p className="stg:text-sidebar-muted-foreground stg:mb-1 stg:px-2 stg:text-[10px] stg:font-medium stg:tracking-wider stg:uppercase">
314
315
  {group.label}
315
316
  </p>
316
- <ul className="stg:space-y-0.5" role="list">
317
+ <ul className={`${UNSTYLED_LIST} stg:space-y-0.5`} role="list">
317
318
  {group.entries.map((entry) => (
318
319
  <ActivityEntry
319
320
  key={entry.id}
@@ -3,6 +3,7 @@
3
3
  import { useMemo, useState } from "react";
4
4
  import Markdown from "react-markdown";
5
5
  import { cn } from "@stigmer/theme";
6
+ import { UNSTYLED_LIST } from "../internal/element-resets.js";
6
7
  import { MARKDOWN_COMPONENTS, REMARK_PLUGINS, stripFrontmatter } from "../internal/markdown-components.js";
7
8
  import { buildFileTree, FileTreeNode } from "../internal/file-tree/index.js";
8
9
  import { useSkillArtifact } from "./useSkillArtifact.js";
@@ -132,7 +133,7 @@ export function SkillFileBrowser({
132
133
  className="stg:border-b stg:border-border stg:md:border-b-0 stg:md:border-r stg:overflow-y-auto"
133
134
  aria-label="Skill package file tree"
134
135
  >
135
- <ul className="stg:py-1" role="tree">
136
+ <ul className={cn(UNSTYLED_LIST, "stg:py-1")} role="tree">
136
137
  {treeNodes.map((node) => (
137
138
  <FileTreeNode
138
139
  key={node.path}
@@ -2,7 +2,7 @@ import { describe, it, expect, vi, afterEach } from "vitest";
2
2
  import { render, screen, fireEvent } from "@testing-library/react";
3
3
  import type { ReactNode } from "react";
4
4
  import { zipSync, strToU8 } from "fflate";
5
- import type { Stigmer } from "@stigmer/sdk";
5
+ import { StigmerError, type Stigmer } from "@stigmer/sdk";
6
6
  import { StigmerContext } from "../../context";
7
7
  import { SkillFileBrowser } from "../SkillFileBrowser";
8
8
 
@@ -12,14 +12,22 @@ function wrapperFor(stigmer: Stigmer) {
12
12
  );
13
13
  }
14
14
 
15
+ /** Connect's Unimplemented code — what a pre-transfer-lane server answers. */
16
+ const CODE_UNIMPLEMENTED = 12;
17
+
15
18
  /**
16
19
  * Builds a real ZIP (via fflate, the same library the unpacker uses) and a
17
20
  * Stigmer client whose `skill.getArtifact` serves it — so tests exercise the
18
21
  * genuine fetch → unzip → browse path instead of stubbing the unpacker.
22
+ * The download-URL mint answers Unimplemented (a pre-transfer-lane server),
23
+ * pinning that the browser degrades to the unary lane it always used.
19
24
  */
20
25
  function makeStigmerServing(files: Record<string, Uint8Array>) {
21
26
  const getArtifact = vi.fn().mockResolvedValue({ artifact: zipSync(files) });
22
- return { skill: { getArtifact } } as unknown as Stigmer;
27
+ const getArtifactDownloadUrl = vi
28
+ .fn()
29
+ .mockRejectedValue(new StigmerError("unknown", "unimplemented", CODE_UNIMPLEMENTED));
30
+ return { skill: { getArtifact, getArtifactDownloadUrl } } as unknown as Stigmer;
23
31
  }
24
32
 
25
33
  function renderBrowser(stigmer: Stigmer) {
@@ -0,0 +1,90 @@
1
+ // Pins for the artifact fetch lane selection (stigmer#701): URL-first via
2
+ // getArtifactDownloadUrl, with the two deliberate browser degrade arms —
3
+ // Unimplemented mint (pre-lane server) and a failed URL fetch (the shape a
4
+ // missing bucket CORS policy takes in a browser).
5
+ import { describe, expect, it, vi } from "vitest";
6
+ import { strToU8, zipSync } from "fflate";
7
+ import { StigmerError, type Stigmer } from "@stigmer/sdk";
8
+ import { fetchAndUnpackArtifact } from "../internal/fetchAndUnpackArtifact.js";
9
+
10
+ const CODE_UNIMPLEMENTED = 12;
11
+ const ZIP = zipSync({ "SKILL.md": strToU8("# hi") });
12
+
13
+ function stigmerWith(overrides: {
14
+ mint?: ReturnType<typeof vi.fn>;
15
+ unary?: ReturnType<typeof vi.fn>;
16
+ fetch?: unknown;
17
+ }): Stigmer {
18
+ return {
19
+ skill: {
20
+ getArtifactDownloadUrl: overrides.mint,
21
+ getArtifact: overrides.unary,
22
+ },
23
+ fetch: overrides.fetch,
24
+ } as unknown as Stigmer;
25
+ }
26
+
27
+ describe("fetchAndUnpackArtifact lane selection", () => {
28
+ it("fetches via the minted download URL, never the unary lane", async () => {
29
+ const mint = vi.fn().mockResolvedValue({ url: "https://r2.example/skills/get" });
30
+ const unary = vi.fn();
31
+ const fetchImpl = vi.fn(async () => new Response(new Uint8Array(ZIP).buffer, { status: 200 }));
32
+
33
+ const result = await fetchAndUnpackArtifact(
34
+ stigmerWith({ mint, unary, fetch: fetchImpl }),
35
+ "skills/org/skill/hash.zip",
36
+ );
37
+
38
+ expect(fetchImpl).toHaveBeenCalledWith("https://r2.example/skills/get");
39
+ expect(unary).not.toHaveBeenCalled();
40
+ expect(result.contentMap.get("SKILL.md")).toBe("# hi");
41
+ });
42
+
43
+ it("degrades to the unary lane when the mint answers Unimplemented (pre-lane server)", async () => {
44
+ const mint = vi
45
+ .fn()
46
+ .mockRejectedValue(new StigmerError("unknown", "unimplemented", CODE_UNIMPLEMENTED));
47
+ const unary = vi.fn().mockResolvedValue({ artifact: ZIP });
48
+
49
+ const result = await fetchAndUnpackArtifact(
50
+ stigmerWith({ mint, unary }),
51
+ "skills/org/skill/hash.zip",
52
+ );
53
+
54
+ expect(unary).toHaveBeenCalledTimes(1);
55
+ expect(result.contentMap.get("SKILL.md")).toBe("# hi");
56
+ });
57
+
58
+ it("degrades to the unary lane when the URL fetch itself fails (browser CORS shape), warning once", async () => {
59
+ const mint = vi.fn().mockResolvedValue({ url: "https://r2.example/skills/get" });
60
+ const unary = vi.fn().mockResolvedValue({ artifact: ZIP });
61
+ const fetchImpl = vi.fn(async () => {
62
+ throw new TypeError("Failed to fetch");
63
+ });
64
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
65
+
66
+ try {
67
+ const result = await fetchAndUnpackArtifact(
68
+ stigmerWith({ mint, unary, fetch: fetchImpl }),
69
+ "skills/org/skill/hash.zip",
70
+ );
71
+ expect(unary).toHaveBeenCalledTimes(1);
72
+ expect(warn).toHaveBeenCalledTimes(1);
73
+ expect(result.contentMap.get("SKILL.md")).toBe("# hi");
74
+ } finally {
75
+ warn.mockRestore();
76
+ }
77
+ });
78
+
79
+ it("propagates a non-Unimplemented mint failure — a real error must not be masked", async () => {
80
+ const mint = vi
81
+ .fn()
82
+ .mockRejectedValue(new StigmerError("not-found", "no such artifact", 5));
83
+ const unary = vi.fn();
84
+
85
+ await expect(
86
+ fetchAndUnpackArtifact(stigmerWith({ mint, unary }), "skills/org/skill/hash.zip"),
87
+ ).rejects.toThrow(/no such artifact/);
88
+ expect(unary).not.toHaveBeenCalled();
89
+ });
90
+ });