@stigmer/react 0.0.71 → 0.0.73

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 (440) hide show
  1. package/agent/AgentEnvForm.d.ts +2 -0
  2. package/agent/AgentEnvForm.d.ts.map +1 -1
  3. package/agent/AgentEnvForm.js.map +1 -1
  4. package/agent/AgentPicker.d.ts +2 -0
  5. package/agent/AgentPicker.d.ts.map +1 -1
  6. package/agent/AgentPicker.js.map +1 -1
  7. package/agent/agentSetupReducer.d.ts +69 -7
  8. package/agent/agentSetupReducer.d.ts.map +1 -1
  9. package/agent/agentSetupReducer.js.map +1 -1
  10. package/agent/useAgentCount.d.ts +2 -0
  11. package/agent/useAgentCount.d.ts.map +1 -1
  12. package/agent/useAgentCount.js.map +1 -1
  13. package/attachment/AttachmentChipList.d.ts +15 -0
  14. package/attachment/AttachmentChipList.d.ts.map +1 -1
  15. package/attachment/AttachmentChipList.js +15 -0
  16. package/attachment/AttachmentChipList.js.map +1 -1
  17. package/attachment/useAttachments.d.ts +14 -0
  18. package/attachment/useAttachments.d.ts.map +1 -1
  19. package/attachment/useAttachments.js.map +1 -1
  20. package/composer/useComposer.d.ts +5 -0
  21. package/composer/useComposer.d.ts.map +1 -1
  22. package/composer/useComposer.js.map +1 -1
  23. package/execution/ExecutionPhaseBadge.d.ts +1 -1
  24. package/execution/ExecutionPhaseBadge.js +1 -1
  25. package/execution/McpToolDetail.d.ts +16 -8
  26. package/execution/McpToolDetail.d.ts.map +1 -1
  27. package/execution/McpToolDetail.js +0 -6
  28. package/execution/McpToolDetail.js.map +1 -1
  29. package/execution/TodoList.d.ts +8 -0
  30. package/execution/TodoList.d.ts.map +1 -1
  31. package/execution/TodoList.js +8 -0
  32. package/execution/TodoList.js.map +1 -1
  33. package/execution/ToolArgsView.d.ts +1 -0
  34. package/execution/ToolArgsView.d.ts.map +1 -1
  35. package/execution/ToolArgsView.js.map +1 -1
  36. package/execution/UsageWidget.d.ts +1 -1
  37. package/execution/UsageWidget.js +1 -1
  38. package/execution/file-path-resolver.d.ts +10 -0
  39. package/execution/file-path-resolver.d.ts.map +1 -1
  40. package/execution/file-path-resolver.js.map +1 -1
  41. package/execution/index.d.ts +1 -1
  42. package/execution/index.d.ts.map +1 -1
  43. package/execution/index.js.map +1 -1
  44. package/execution/useArtifactContent.d.ts +33 -0
  45. package/execution/useArtifactContent.d.ts.map +1 -1
  46. package/execution/useArtifactContent.js +33 -0
  47. package/execution/useArtifactContent.js.map +1 -1
  48. package/execution/useSubmitApproval.d.ts +2 -0
  49. package/execution/useSubmitApproval.d.ts.map +1 -1
  50. package/execution/useSubmitApproval.js.map +1 -1
  51. package/github/GitHubRepoPicker.d.ts +13 -0
  52. package/github/GitHubRepoPicker.d.ts.map +1 -1
  53. package/github/GitHubRepoPicker.js +13 -0
  54. package/github/GitHubRepoPicker.js.map +1 -1
  55. package/github/useGitHubConnection.d.ts +29 -1
  56. package/github/useGitHubConnection.d.ts.map +1 -1
  57. package/github/useGitHubConnection.js +29 -1
  58. package/github/useGitHubConnection.js.map +1 -1
  59. package/github/useGitHubRepos.d.ts +31 -0
  60. package/github/useGitHubRepos.d.ts.map +1 -1
  61. package/github/useGitHubRepos.js +31 -0
  62. package/github/useGitHubRepos.js.map +1 -1
  63. package/github/useGitHubSearch.d.ts +25 -0
  64. package/github/useGitHubSearch.d.ts.map +1 -1
  65. package/github/useGitHubSearch.js +25 -0
  66. package/github/useGitHubSearch.js.map +1 -1
  67. package/iam-policy/GrantAccessForm.d.ts +39 -0
  68. package/iam-policy/GrantAccessForm.d.ts.map +1 -0
  69. package/iam-policy/GrantAccessForm.js +75 -0
  70. package/iam-policy/GrantAccessForm.js.map +1 -0
  71. package/iam-policy/OrgMembersPanel.d.ts +28 -0
  72. package/iam-policy/OrgMembersPanel.d.ts.map +1 -0
  73. package/iam-policy/OrgMembersPanel.js +192 -0
  74. package/iam-policy/OrgMembersPanel.js.map +1 -0
  75. package/iam-policy/RoleSelector.d.ts +37 -0
  76. package/iam-policy/RoleSelector.d.ts.map +1 -0
  77. package/iam-policy/RoleSelector.js +42 -0
  78. package/iam-policy/RoleSelector.js.map +1 -0
  79. package/iam-policy/index.d.ts +12 -0
  80. package/iam-policy/index.d.ts.map +1 -0
  81. package/iam-policy/index.js +12 -0
  82. package/iam-policy/index.js.map +1 -0
  83. package/iam-policy/useCreateIamPolicy.d.ts +35 -0
  84. package/iam-policy/useCreateIamPolicy.d.ts.map +1 -0
  85. package/iam-policy/useCreateIamPolicy.js +46 -0
  86. package/iam-policy/useCreateIamPolicy.js.map +1 -0
  87. package/iam-policy/useDeleteIamPolicy.d.ts +34 -0
  88. package/iam-policy/useDeleteIamPolicy.d.ts.map +1 -0
  89. package/iam-policy/useDeleteIamPolicy.js +45 -0
  90. package/iam-policy/useDeleteIamPolicy.js.map +1 -0
  91. package/iam-policy/useGrantableRoles.d.ts +28 -0
  92. package/iam-policy/useGrantableRoles.d.ts.map +1 -0
  93. package/iam-policy/useGrantableRoles.js +32 -0
  94. package/iam-policy/useGrantableRoles.js.map +1 -0
  95. package/iam-policy/usePrincipalsCount.d.ts +31 -0
  96. package/iam-policy/usePrincipalsCount.d.ts.map +1 -0
  97. package/iam-policy/usePrincipalsCount.js +72 -0
  98. package/iam-policy/usePrincipalsCount.js.map +1 -0
  99. package/iam-policy/useResourceAccess.d.ts +51 -0
  100. package/iam-policy/useResourceAccess.d.ts.map +1 -0
  101. package/iam-policy/useResourceAccess.js +85 -0
  102. package/iam-policy/useResourceAccess.js.map +1 -0
  103. package/iam-policy/useRevokeOrgAccess.d.ts +36 -0
  104. package/iam-policy/useRevokeOrgAccess.d.ts.map +1 -0
  105. package/iam-policy/useRevokeOrgAccess.js +48 -0
  106. package/iam-policy/useRevokeOrgAccess.js.map +1 -0
  107. package/iam-policy/useRoleSelector.d.ts +52 -0
  108. package/iam-policy/useRoleSelector.d.ts.map +1 -0
  109. package/iam-policy/useRoleSelector.js +50 -0
  110. package/iam-policy/useRoleSelector.js.map +1 -0
  111. package/iam-policy/useWhoAmI.d.ts +30 -0
  112. package/iam-policy/useWhoAmI.d.ts.map +1 -0
  113. package/iam-policy/useWhoAmI.js +56 -0
  114. package/iam-policy/useWhoAmI.js.map +1 -0
  115. package/identity-provider/CreateIdentityProviderForm.d.ts +39 -0
  116. package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -0
  117. package/identity-provider/CreateIdentityProviderForm.js +102 -0
  118. package/identity-provider/CreateIdentityProviderForm.js.map +1 -0
  119. package/identity-provider/IdentityProviderDetailPanel.d.ts +42 -0
  120. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -0
  121. package/identity-provider/IdentityProviderDetailPanel.js +156 -0
  122. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -0
  123. package/identity-provider/IdentityProviderListPanel.d.ts +41 -0
  124. package/identity-provider/IdentityProviderListPanel.d.ts.map +1 -0
  125. package/identity-provider/IdentityProviderListPanel.js +110 -0
  126. package/identity-provider/IdentityProviderListPanel.js.map +1 -0
  127. package/identity-provider/IdentityProviderWizard.d.ts +40 -0
  128. package/identity-provider/IdentityProviderWizard.d.ts.map +1 -0
  129. package/identity-provider/IdentityProviderWizard.js +180 -0
  130. package/identity-provider/IdentityProviderWizard.js.map +1 -0
  131. package/identity-provider/ProviderPicker.d.ts +28 -0
  132. package/identity-provider/ProviderPicker.d.ts.map +1 -0
  133. package/identity-provider/ProviderPicker.js +64 -0
  134. package/identity-provider/ProviderPicker.js.map +1 -0
  135. package/identity-provider/SsoLoginPrompt.d.ts +51 -0
  136. package/identity-provider/SsoLoginPrompt.d.ts.map +1 -0
  137. package/identity-provider/SsoLoginPrompt.js +119 -0
  138. package/identity-provider/SsoLoginPrompt.js.map +1 -0
  139. package/identity-provider/index.d.ts +14 -0
  140. package/identity-provider/index.d.ts.map +1 -0
  141. package/identity-provider/index.js +14 -0
  142. package/identity-provider/index.js.map +1 -0
  143. package/identity-provider/presets.d.ts +65 -0
  144. package/identity-provider/presets.d.ts.map +1 -0
  145. package/identity-provider/presets.js +200 -0
  146. package/identity-provider/presets.js.map +1 -0
  147. package/identity-provider/useCreateIdentityProvider.d.ts +37 -0
  148. package/identity-provider/useCreateIdentityProvider.d.ts.map +1 -0
  149. package/identity-provider/useCreateIdentityProvider.js +48 -0
  150. package/identity-provider/useCreateIdentityProvider.js.map +1 -0
  151. package/identity-provider/useDeleteIdentityProvider.d.ts +34 -0
  152. package/identity-provider/useDeleteIdentityProvider.d.ts.map +1 -0
  153. package/identity-provider/useDeleteIdentityProvider.js +45 -0
  154. package/identity-provider/useDeleteIdentityProvider.js.map +1 -0
  155. package/identity-provider/useIdentityProvider.d.ts +37 -0
  156. package/identity-provider/useIdentityProvider.d.ts.map +1 -0
  157. package/identity-provider/useIdentityProvider.js +62 -0
  158. package/identity-provider/useIdentityProvider.js.map +1 -0
  159. package/identity-provider/useIdentityProviderList.d.ts +48 -0
  160. package/identity-provider/useIdentityProviderList.d.ts.map +1 -0
  161. package/identity-provider/useIdentityProviderList.js +75 -0
  162. package/identity-provider/useIdentityProviderList.js.map +1 -0
  163. package/identity-provider/useOidcDiscovery.d.ts +39 -0
  164. package/identity-provider/useOidcDiscovery.d.ts.map +1 -0
  165. package/identity-provider/useOidcDiscovery.js +76 -0
  166. package/identity-provider/useOidcDiscovery.js.map +1 -0
  167. package/identity-provider/useSsoProvider.d.ts +50 -0
  168. package/identity-provider/useSsoProvider.d.ts.map +1 -0
  169. package/identity-provider/useSsoProvider.js +83 -0
  170. package/identity-provider/useSsoProvider.js.map +1 -0
  171. package/identity-provider/useUpdateIdentityProvider.d.ts +38 -0
  172. package/identity-provider/useUpdateIdentityProvider.d.ts.map +1 -0
  173. package/identity-provider/useUpdateIdentityProvider.js +49 -0
  174. package/identity-provider/useUpdateIdentityProvider.js.map +1 -0
  175. package/index.d.ts +14 -5
  176. package/index.d.ts.map +1 -1
  177. package/index.js +10 -2
  178. package/index.js.map +1 -1
  179. package/internal/CloudFeatureNotice.d.ts +12 -0
  180. package/internal/CloudFeatureNotice.d.ts.map +1 -1
  181. package/internal/CloudFeatureNotice.js +12 -0
  182. package/internal/CloudFeatureNotice.js.map +1 -1
  183. package/invitation/InvitationCreatedAlert.d.ts +35 -0
  184. package/invitation/InvitationCreatedAlert.d.ts.map +1 -0
  185. package/invitation/InvitationCreatedAlert.js +60 -0
  186. package/invitation/InvitationCreatedAlert.js.map +1 -0
  187. package/invitation/InvitationManager.d.ts +44 -0
  188. package/invitation/InvitationManager.d.ts.map +1 -0
  189. package/invitation/InvitationManager.js +248 -0
  190. package/invitation/InvitationManager.js.map +1 -0
  191. package/invitation/InvitationRedemption.d.ts +69 -0
  192. package/invitation/InvitationRedemption.d.ts.map +1 -0
  193. package/invitation/InvitationRedemption.js +140 -0
  194. package/invitation/InvitationRedemption.js.map +1 -0
  195. package/invitation/index.d.ts +17 -0
  196. package/invitation/index.d.ts.map +1 -0
  197. package/invitation/index.js +9 -0
  198. package/invitation/index.js.map +1 -0
  199. package/invitation/useCreateInvitation.d.ts +52 -0
  200. package/invitation/useCreateInvitation.d.ts.map +1 -0
  201. package/invitation/useCreateInvitation.js +55 -0
  202. package/invitation/useCreateInvitation.js.map +1 -0
  203. package/invitation/useInvitationPreview.d.ts +51 -0
  204. package/invitation/useInvitationPreview.d.ts.map +1 -0
  205. package/invitation/useInvitationPreview.js +80 -0
  206. package/invitation/useInvitationPreview.js.map +1 -0
  207. package/invitation/useOrgInvitations.d.ts +36 -0
  208. package/invitation/useOrgInvitations.d.ts.map +1 -0
  209. package/invitation/useOrgInvitations.js +65 -0
  210. package/invitation/useOrgInvitations.js.map +1 -0
  211. package/invitation/useRedeemInvitation.d.ts +47 -0
  212. package/invitation/useRedeemInvitation.d.ts.map +1 -0
  213. package/invitation/useRedeemInvitation.js +53 -0
  214. package/invitation/useRedeemInvitation.js.map +1 -0
  215. package/invitation/useRevokeInvitation.d.ts +35 -0
  216. package/invitation/useRevokeInvitation.d.ts.map +1 -0
  217. package/invitation/useRevokeInvitation.js +47 -0
  218. package/invitation/useRevokeInvitation.js.map +1 -0
  219. package/library/detect-skill-package.d.ts +1 -0
  220. package/library/detect-skill-package.d.ts.map +1 -1
  221. package/library/detect-skill-package.js.map +1 -1
  222. package/library/detect-stigmer-resource.d.ts +1 -0
  223. package/library/detect-stigmer-resource.d.ts.map +1 -1
  224. package/library/detect-stigmer-resource.js.map +1 -1
  225. package/library/parse-resource-yaml.d.ts +4 -0
  226. package/library/parse-resource-yaml.d.ts.map +1 -1
  227. package/library/parse-resource-yaml.js.map +1 -1
  228. package/mcp-server/McpServerDetailView.d.ts +2 -2
  229. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  230. package/mcp-server/McpServerDetailView.js.map +1 -1
  231. package/mcp-server/index.d.ts +1 -1
  232. package/mcp-server/index.d.ts.map +1 -1
  233. package/mcp-server/index.js.map +1 -1
  234. package/mcp-server/mcpServerSetupReducer.d.ts +54 -0
  235. package/mcp-server/mcpServerSetupReducer.d.ts.map +1 -1
  236. package/mcp-server/mcpServerSetupReducer.js.map +1 -1
  237. package/models/ModelSelector.d.ts +9 -0
  238. package/models/ModelSelector.d.ts.map +1 -1
  239. package/models/ModelSelector.js +9 -0
  240. package/models/ModelSelector.js.map +1 -1
  241. package/models/registry.d.ts +11 -1
  242. package/models/registry.d.ts.map +1 -1
  243. package/models/registry.js.map +1 -1
  244. package/models/useModelRegistry.d.ts +20 -0
  245. package/models/useModelRegistry.d.ts.map +1 -1
  246. package/models/useModelRegistry.js +20 -0
  247. package/models/useModelRegistry.js.map +1 -1
  248. package/organization/OrgProfilePanel.d.ts +31 -0
  249. package/organization/OrgProfilePanel.d.ts.map +1 -0
  250. package/organization/OrgProfilePanel.js +147 -0
  251. package/organization/OrgProfilePanel.js.map +1 -0
  252. package/organization/index.d.ts +6 -0
  253. package/organization/index.d.ts.map +1 -1
  254. package/organization/index.js +3 -0
  255. package/organization/index.js.map +1 -1
  256. package/organization/useOrganization.d.ts +31 -0
  257. package/organization/useOrganization.d.ts.map +1 -0
  258. package/organization/useOrganization.js +56 -0
  259. package/organization/useOrganization.js.map +1 -0
  260. package/organization/useUpdateOrganization.d.ts +40 -0
  261. package/organization/useUpdateOrganization.d.ts.map +1 -0
  262. package/organization/useUpdateOrganization.js +51 -0
  263. package/organization/useUpdateOrganization.js.map +1 -0
  264. package/package.json +4 -4
  265. package/provider.d.ts +1 -0
  266. package/provider.d.ts.map +1 -1
  267. package/provider.js.map +1 -1
  268. package/search/useResourceList.d.ts +4 -2
  269. package/search/useResourceList.d.ts.map +1 -1
  270. package/search/useResourceList.js +2 -1
  271. package/search/useResourceList.js.map +1 -1
  272. package/search/useResourceSearch.d.ts +10 -2
  273. package/search/useResourceSearch.d.ts.map +1 -1
  274. package/search/useResourceSearch.js +2 -1
  275. package/search/useResourceSearch.js.map +1 -1
  276. package/session/group-sessions.d.ts +23 -0
  277. package/session/group-sessions.d.ts.map +1 -1
  278. package/session/group-sessions.js +23 -0
  279. package/session/group-sessions.js.map +1 -1
  280. package/session/index.d.ts +1 -1
  281. package/session/index.d.ts.map +1 -1
  282. package/session/index.js.map +1 -1
  283. package/session/useCreateSession.d.ts +11 -2
  284. package/session/useCreateSession.d.ts.map +1 -1
  285. package/session/useCreateSession.js.map +1 -1
  286. package/session/useSession.d.ts +24 -0
  287. package/session/useSession.d.ts.map +1 -1
  288. package/session/useSession.js +24 -0
  289. package/session/useSession.js.map +1 -1
  290. package/session/useSessionArtifacts.d.ts +1 -0
  291. package/session/useSessionArtifacts.d.ts.map +1 -1
  292. package/session/useSessionArtifacts.js.map +1 -1
  293. package/session/useSessionConversation.d.ts +7 -0
  294. package/session/useSessionConversation.d.ts.map +1 -1
  295. package/session/useSessionConversation.js.map +1 -1
  296. package/session/useSessionExecutions.d.ts +23 -0
  297. package/session/useSessionExecutions.d.ts.map +1 -1
  298. package/session/useSessionExecutions.js +23 -0
  299. package/session/useSessionExecutions.js.map +1 -1
  300. package/session/useSessionList.d.ts +19 -0
  301. package/session/useSessionList.d.ts.map +1 -1
  302. package/session/useSessionList.js +19 -0
  303. package/session/useSessionList.js.map +1 -1
  304. package/session/useSessionWriteBacks.d.ts +1 -0
  305. package/session/useSessionWriteBacks.d.ts.map +1 -1
  306. package/session/useSessionWriteBacks.js.map +1 -1
  307. package/session/useUpdateSession.d.ts +22 -0
  308. package/session/useUpdateSession.d.ts.map +1 -1
  309. package/session/useUpdateSession.js +22 -0
  310. package/session/useUpdateSession.js.map +1 -1
  311. package/skill/SkillPicker.d.ts +15 -0
  312. package/skill/SkillPicker.d.ts.map +1 -1
  313. package/skill/SkillPicker.js +15 -0
  314. package/skill/SkillPicker.js.map +1 -1
  315. package/src/agent/AgentEnvForm.tsx +2 -0
  316. package/src/agent/AgentPicker.tsx +2 -0
  317. package/src/agent/agentSetupReducer.ts +109 -20
  318. package/src/agent/useAgentCount.ts +2 -0
  319. package/src/attachment/AttachmentChipList.tsx +15 -0
  320. package/src/attachment/useAttachments.ts +14 -0
  321. package/src/composer/useComposer.ts +5 -0
  322. package/src/execution/ExecutionPhaseBadge.tsx +1 -1
  323. package/src/execution/McpToolDetail.tsx +18 -6
  324. package/src/execution/TodoList.tsx +8 -0
  325. package/src/execution/ToolArgsView.tsx +1 -0
  326. package/src/execution/UsageWidget.tsx +1 -1
  327. package/src/execution/file-path-resolver.ts +28 -4
  328. package/src/execution/index.ts +5 -1
  329. package/src/execution/useArtifactContent.ts +33 -0
  330. package/src/execution/useSubmitApproval.ts +2 -0
  331. package/src/github/GitHubRepoPicker.tsx +13 -0
  332. package/src/github/useGitHubConnection.ts +29 -1
  333. package/src/github/useGitHubRepos.ts +31 -0
  334. package/src/github/useGitHubSearch.ts +25 -0
  335. package/src/iam-policy/GrantAccessForm.tsx +198 -0
  336. package/src/iam-policy/OrgMembersPanel.tsx +572 -0
  337. package/src/iam-policy/RoleSelector.tsx +105 -0
  338. package/src/iam-policy/index.ts +51 -0
  339. package/src/iam-policy/useCreateIamPolicy.ts +66 -0
  340. package/src/iam-policy/useDeleteIamPolicy.ts +65 -0
  341. package/src/iam-policy/useGrantableRoles.ts +45 -0
  342. package/src/iam-policy/usePrincipalsCount.ts +96 -0
  343. package/src/iam-policy/useResourceAccess.ts +128 -0
  344. package/src/iam-policy/useRevokeOrgAccess.ts +74 -0
  345. package/src/iam-policy/useRoleSelector.ts +97 -0
  346. package/src/iam-policy/useWhoAmI.ts +78 -0
  347. package/src/identity-provider/CreateIdentityProviderForm.tsx +308 -0
  348. package/src/identity-provider/IdentityProviderDetailPanel.tsx +583 -0
  349. package/src/identity-provider/IdentityProviderListPanel.tsx +370 -0
  350. package/src/identity-provider/IdentityProviderWizard.tsx +684 -0
  351. package/src/identity-provider/ProviderPicker.tsx +152 -0
  352. package/src/identity-provider/SsoLoginPrompt.tsx +404 -0
  353. package/src/identity-provider/index.ts +67 -0
  354. package/src/identity-provider/presets.ts +262 -0
  355. package/src/identity-provider/useCreateIdentityProvider.ts +68 -0
  356. package/src/identity-provider/useDeleteIdentityProvider.ts +65 -0
  357. package/src/identity-provider/useIdentityProvider.ts +86 -0
  358. package/src/identity-provider/useIdentityProviderList.ts +100 -0
  359. package/src/identity-provider/useOidcDiscovery.ts +124 -0
  360. package/src/identity-provider/useSsoProvider.ts +99 -0
  361. package/src/identity-provider/useUpdateIdentityProvider.ts +69 -0
  362. package/src/index.ts +121 -1
  363. package/src/internal/CloudFeatureNotice.tsx +12 -0
  364. package/src/invitation/InvitationCreatedAlert.tsx +185 -0
  365. package/src/invitation/InvitationManager.tsx +842 -0
  366. package/src/invitation/InvitationRedemption.tsx +434 -0
  367. package/src/invitation/index.ts +16 -0
  368. package/src/invitation/useCreateInvitation.ts +83 -0
  369. package/src/invitation/useInvitationPreview.ts +103 -0
  370. package/src/invitation/useOrgInvitations.ts +88 -0
  371. package/src/invitation/useRedeemInvitation.ts +82 -0
  372. package/src/invitation/useRevokeInvitation.ts +66 -0
  373. package/src/library/detect-skill-package.ts +4 -1
  374. package/src/library/detect-stigmer-resource.ts +4 -1
  375. package/src/library/parse-resource-yaml.ts +12 -2
  376. package/src/mcp-server/McpServerDetailView.tsx +2 -1
  377. package/src/mcp-server/index.ts +4 -1
  378. package/src/mcp-server/mcpServerSetupReducer.ts +86 -8
  379. package/src/models/ModelSelector.tsx +9 -0
  380. package/src/models/registry.ts +11 -1
  381. package/src/models/useModelRegistry.ts +20 -0
  382. package/src/organization/OrgProfilePanel.tsx +451 -0
  383. package/src/organization/index.ts +6 -0
  384. package/src/organization/useOrganization.ts +79 -0
  385. package/src/organization/useUpdateOrganization.ts +71 -0
  386. package/src/provider.tsx +1 -0
  387. package/src/search/useResourceList.ts +6 -3
  388. package/src/search/useResourceSearch.ts +12 -3
  389. package/src/session/group-sessions.ts +23 -0
  390. package/src/session/index.ts +1 -0
  391. package/src/session/useCreateSession.ts +19 -3
  392. package/src/session/useSession.ts +24 -0
  393. package/src/session/useSessionArtifacts.ts +1 -0
  394. package/src/session/useSessionConversation.ts +7 -0
  395. package/src/session/useSessionExecutions.ts +23 -0
  396. package/src/session/useSessionList.ts +19 -0
  397. package/src/session/useSessionWriteBacks.ts +1 -0
  398. package/src/session/useUpdateSession.ts +22 -0
  399. package/src/skill/SkillPicker.tsx +15 -0
  400. package/src/usage/OrgUsagePanel.tsx +465 -0
  401. package/src/usage/date-range.ts +86 -0
  402. package/src/usage/index.ts +13 -0
  403. package/src/usage/useOrgUsageReport.ts +110 -0
  404. package/src/workspace/FolderBrowser.tsx +9 -0
  405. package/src/workspace/WorkspaceEditor.tsx +17 -0
  406. package/src/workspace/useFolderListing.ts +24 -0
  407. package/src/workspace/useWorkspaceEntries.ts +38 -0
  408. package/styles.css +1 -1
  409. package/usage/OrgUsagePanel.d.ts +24 -0
  410. package/usage/OrgUsagePanel.d.ts.map +1 -0
  411. package/usage/OrgUsagePanel.js +134 -0
  412. package/usage/OrgUsagePanel.js.map +1 -0
  413. package/usage/date-range.d.ts +36 -0
  414. package/usage/date-range.d.ts.map +1 -0
  415. package/usage/date-range.js +69 -0
  416. package/usage/date-range.js.map +1 -0
  417. package/usage/index.d.ts +7 -0
  418. package/usage/index.d.ts.map +1 -0
  419. package/usage/index.js +4 -0
  420. package/usage/index.js.map +1 -0
  421. package/usage/useOrgUsageReport.d.ts +48 -0
  422. package/usage/useOrgUsageReport.d.ts.map +1 -0
  423. package/usage/useOrgUsageReport.js +72 -0
  424. package/usage/useOrgUsageReport.js.map +1 -0
  425. package/workspace/FolderBrowser.d.ts +9 -0
  426. package/workspace/FolderBrowser.d.ts.map +1 -1
  427. package/workspace/FolderBrowser.js +9 -0
  428. package/workspace/FolderBrowser.js.map +1 -1
  429. package/workspace/WorkspaceEditor.d.ts +17 -0
  430. package/workspace/WorkspaceEditor.d.ts.map +1 -1
  431. package/workspace/WorkspaceEditor.js +17 -0
  432. package/workspace/WorkspaceEditor.js.map +1 -1
  433. package/workspace/useFolderListing.d.ts +24 -0
  434. package/workspace/useFolderListing.d.ts.map +1 -1
  435. package/workspace/useFolderListing.js +24 -0
  436. package/workspace/useFolderListing.js.map +1 -1
  437. package/workspace/useWorkspaceEntries.d.ts +38 -0
  438. package/workspace/useWorkspaceEntries.d.ts.map +1 -1
  439. package/workspace/useWorkspaceEntries.js +25 -0
  440. package/workspace/useWorkspaceEntries.js.map +1 -1
@@ -0,0 +1,572 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import { create } from "@bufbuild/protobuf";
5
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
6
+ import type { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
7
+ import type { PrincipalAccess, RoleGrant } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/io_pb";
8
+ import {
9
+ IamPolicySpecSchema,
10
+ ApiResourceRefSchema,
11
+ } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/spec_pb";
12
+ import { cn } from "@stigmer/theme";
13
+ import {
14
+ getUserMessage,
15
+ iamRoleFromString,
16
+ iamRoleToString,
17
+ } from "@stigmer/sdk";
18
+ import { useResourceAccess } from "./useResourceAccess";
19
+ import { usePrincipalsCount } from "./usePrincipalsCount";
20
+ import { useWhoAmI } from "./useWhoAmI";
21
+ import { useRevokeOrgAccess } from "./useRevokeOrgAccess";
22
+ import { useCreateIamPolicy } from "./useCreateIamPolicy";
23
+ import { useDeleteIamPolicy } from "./useDeleteIamPolicy";
24
+ import { RoleSelector } from "./RoleSelector";
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Public API
28
+ // ---------------------------------------------------------------------------
29
+
30
+ /** Props for {@link OrgMembersPanel}. */
31
+ export interface OrgMembersPanelProps {
32
+ /** Organization ID (`metadata.id`) whose members to manage. */
33
+ readonly orgId: string;
34
+ /** Exposed refetch for parent-triggered refresh. */
35
+ readonly onRefetchRef?: (refetch: () => void) => void;
36
+ /** Additional CSS class names for the root container. */
37
+ readonly className?: string;
38
+ }
39
+
40
+ /**
41
+ * Self-contained panel for managing organization members.
42
+ *
43
+ * Displays all principals with access to the organization, their
44
+ * role grants, and provides actions to change roles and remove
45
+ * members. New members are added through the invitation flow.
46
+ * The current user is identified via
47
+ * `identityAccount.whoAmI()` for self-protection (disabling
48
+ * destructive actions on yourself).
49
+ *
50
+ * All visual properties flow through `--stgm-*` design tokens.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * <OrgMembersPanel orgId={activeOrg.metadata.id} />
55
+ * ```
56
+ */
57
+ export function OrgMembersPanel({
58
+ orgId,
59
+ onRefetchRef,
60
+ className,
61
+ }: OrgMembersPanelProps) {
62
+ const resource = orgId ? { kind: "organization", id: orgId } : null;
63
+ const { members, isLoading, error, refetch } = useResourceAccess(resource);
64
+ const { count, refetch: refetchCount } = usePrincipalsCount(orgId || null);
65
+ const { account: currentAccount } = useWhoAmI();
66
+ const currentAccountId = currentAccount?.metadata?.id ?? null;
67
+
68
+ const [actionMemberId, setActionMemberId] = useState<string | null>(null);
69
+
70
+ const handleRefetch = useCallback(() => {
71
+ refetch();
72
+ refetchCount();
73
+ }, [refetch, refetchCount]);
74
+
75
+ if (onRefetchRef) {
76
+ onRefetchRef(handleRefetch);
77
+ }
78
+
79
+ if (isLoading) {
80
+ return (
81
+ <div
82
+ className={cn("space-y-2", className)}
83
+ aria-busy="true"
84
+ aria-label="Loading members"
85
+ >
86
+ {Array.from({ length: 3 }, (_, i) => (
87
+ <div
88
+ key={i}
89
+ className="bg-muted/40 h-14 animate-pulse rounded-lg"
90
+ />
91
+ ))}
92
+ </div>
93
+ );
94
+ }
95
+
96
+ if (error) {
97
+ return (
98
+ <p className={cn("text-destructive text-xs", className)} role="alert">
99
+ {getUserMessage(error)}
100
+ </p>
101
+ );
102
+ }
103
+
104
+ return (
105
+ <div className={cn("space-y-3", className)}>
106
+ {/* Header */}
107
+ <div className="flex items-center gap-2">
108
+ <span className="text-sm font-semibold text-foreground">Members</span>
109
+ {count > 0 && (
110
+ <span className="inline-flex items-center rounded-full bg-muted px-2 py-0.5 text-[0.65rem] font-medium text-muted-foreground">
111
+ {count}
112
+ </span>
113
+ )}
114
+ </div>
115
+
116
+ {/* Members list */}
117
+ {members.length === 0 ? (
118
+ <p className="text-muted-foreground py-4 text-center text-xs">
119
+ No members found.
120
+ </p>
121
+ ) : (
122
+ <div role="list" aria-label="Organization members" className="space-y-2">
123
+ {members.map((entry) => {
124
+ const memberId = entry.principal?.id ?? "";
125
+ return (
126
+ <MemberRow
127
+ key={memberId}
128
+ entry={entry}
129
+ orgId={orgId}
130
+ isSelf={memberId === currentAccountId}
131
+ isActioning={actionMemberId === memberId}
132
+ onStartAction={() => setActionMemberId(memberId)}
133
+ onEndAction={() => setActionMemberId(null)}
134
+ onMutated={handleRefetch}
135
+ />
136
+ );
137
+ })}
138
+ </div>
139
+ )}
140
+ </div>
141
+ );
142
+ }
143
+
144
+ // ---------------------------------------------------------------------------
145
+ // MemberRow (internal)
146
+ // ---------------------------------------------------------------------------
147
+
148
+ function MemberRow({
149
+ entry,
150
+ orgId,
151
+ isSelf,
152
+ isActioning,
153
+ onStartAction,
154
+ onEndAction,
155
+ onMutated,
156
+ }: {
157
+ entry: PrincipalAccess;
158
+ orgId: string;
159
+ isSelf: boolean;
160
+ isActioning: boolean;
161
+ onStartAction: () => void;
162
+ onEndAction: () => void;
163
+ onMutated: () => void;
164
+ }) {
165
+ const [actionType, setActionType] = useState<"remove" | "change-role" | null>(
166
+ null,
167
+ );
168
+
169
+ const principal = entry.principal;
170
+ const memberId = principal?.id ?? "";
171
+ const name = principal?.name || principal?.email || memberId;
172
+ const email = principal?.email ?? "";
173
+ const initial = name.charAt(0).toUpperCase();
174
+ const directRoles = entry.roles.filter((r) => !r.isInherited);
175
+
176
+ const startAction = (type: "remove" | "change-role") => {
177
+ setActionType(type);
178
+ onStartAction();
179
+ };
180
+
181
+ const cancelAction = () => {
182
+ setActionType(null);
183
+ onEndAction();
184
+ };
185
+
186
+ if (isActioning && actionType === "remove") {
187
+ return (
188
+ <RemoveConfirmation
189
+ memberId={memberId}
190
+ memberName={name}
191
+ orgId={orgId}
192
+ onDone={() => {
193
+ cancelAction();
194
+ onMutated();
195
+ }}
196
+ onCancel={cancelAction}
197
+ />
198
+ );
199
+ }
200
+
201
+ if (isActioning && actionType === "change-role") {
202
+ return (
203
+ <ChangeRoleRow
204
+ entry={entry}
205
+ orgId={orgId}
206
+ onDone={() => {
207
+ cancelAction();
208
+ onMutated();
209
+ }}
210
+ onCancel={cancelAction}
211
+ />
212
+ );
213
+ }
214
+
215
+ return (
216
+ <div
217
+ role="listitem"
218
+ className="flex items-center gap-3 rounded-lg border border-border/60 px-3 py-2.5 hover:border-border transition-colors"
219
+ >
220
+ {/* Avatar */}
221
+ <div className="flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-medium text-muted-foreground">
222
+ {initial}
223
+ </div>
224
+
225
+ {/* Name + email */}
226
+ <div className="min-w-0 flex-1">
227
+ <div className="flex items-center gap-1.5">
228
+ <span className="truncate text-sm font-medium text-foreground">
229
+ {name}
230
+ </span>
231
+ {isSelf && (
232
+ <span className="rounded bg-muted px-1.5 py-0.5 text-[0.6rem] font-medium text-muted-foreground">
233
+ You
234
+ </span>
235
+ )}
236
+ </div>
237
+ {email && email !== name && (
238
+ <span className="block truncate text-xs text-muted-foreground">
239
+ {email}
240
+ </span>
241
+ )}
242
+ </div>
243
+
244
+ {/* Role badges */}
245
+ <div className="hidden sm:flex shrink-0 items-center gap-1.5">
246
+ {directRoles.map((grant) => (
247
+ <RoleBadge key={grant.role?.code ?? ""} grant={grant} />
248
+ ))}
249
+ </div>
250
+
251
+ {/* Actions */}
252
+ {!isSelf && (
253
+ <div className="flex shrink-0 items-center gap-1">
254
+ <button
255
+ type="button"
256
+ onClick={() => startAction("change-role")}
257
+ aria-label={`Change role for ${name}`}
258
+ className="shrink-0 rounded p-1 text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors"
259
+ >
260
+ <EditIcon />
261
+ </button>
262
+ <button
263
+ type="button"
264
+ onClick={() => startAction("remove")}
265
+ aria-label={`Remove ${name}`}
266
+ className="shrink-0 rounded p-1 text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors"
267
+ >
268
+ <TrashIcon />
269
+ </button>
270
+ </div>
271
+ )}
272
+ </div>
273
+ );
274
+ }
275
+
276
+ // ---------------------------------------------------------------------------
277
+ // RoleBadge (internal)
278
+ // ---------------------------------------------------------------------------
279
+
280
+ function RoleBadge({ grant }: { grant: RoleGrant }) {
281
+ const roleName = grant.role?.name || grant.role?.code || "Unknown";
282
+ return (
283
+ <span
284
+ className={cn(
285
+ "inline-flex items-center rounded-md border px-2 py-0.5 text-[0.65rem] font-medium",
286
+ grant.isInherited
287
+ ? "border-border/50 text-muted-foreground bg-muted/50 italic"
288
+ : "border-border bg-muted text-foreground",
289
+ )}
290
+ title={
291
+ grant.isInherited
292
+ ? `Inherited from ${grant.ownerResource?.kind ?? "parent"}`
293
+ : `Directly assigned`
294
+ }
295
+ >
296
+ {roleName}
297
+ {grant.isInherited && (
298
+ <span className="ml-1 text-[0.55rem] text-muted-foreground">
299
+ (inherited)
300
+ </span>
301
+ )}
302
+ </span>
303
+ );
304
+ }
305
+
306
+ // ---------------------------------------------------------------------------
307
+ // RemoveConfirmation (internal)
308
+ // ---------------------------------------------------------------------------
309
+
310
+ function RemoveConfirmation({
311
+ memberId,
312
+ memberName,
313
+ orgId,
314
+ onDone,
315
+ onCancel,
316
+ }: {
317
+ memberId: string;
318
+ memberName: string;
319
+ orgId: string;
320
+ onDone: () => void;
321
+ onCancel: () => void;
322
+ }) {
323
+ const { revoke, isRevoking, error } = useRevokeOrgAccess();
324
+
325
+ const handleConfirm = useCallback(async () => {
326
+ try {
327
+ await revoke(memberId, orgId);
328
+ onDone();
329
+ } catch {
330
+ // error state is surfaced via the hook
331
+ }
332
+ }, [memberId, orgId, revoke, onDone]);
333
+
334
+ return (
335
+ <div
336
+ role="listitem"
337
+ className="flex items-center justify-between rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5"
338
+ >
339
+ <div className="min-w-0 flex-1">
340
+ <p className="text-xs text-foreground">
341
+ Remove <span className="font-medium">{memberName}</span> from this
342
+ organization? This revokes all their access.
343
+ </p>
344
+ {error && (
345
+ <p className="mt-0.5 text-[0.65rem] text-destructive">
346
+ {getUserMessage(error)}
347
+ </p>
348
+ )}
349
+ </div>
350
+
351
+ <div className="flex shrink-0 items-center gap-1.5 ml-3">
352
+ <button
353
+ type="button"
354
+ onClick={handleConfirm}
355
+ disabled={isRevoking}
356
+ className={cn(
357
+ "inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium",
358
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
359
+ "disabled:pointer-events-none disabled:opacity-50",
360
+ )}
361
+ >
362
+ {isRevoking && <SpinnerIcon />}
363
+ Remove
364
+ </button>
365
+ <button
366
+ type="button"
367
+ onClick={onCancel}
368
+ disabled={isRevoking}
369
+ className={cn(
370
+ "rounded-md px-2.5 py-1 text-xs",
371
+ "text-muted-foreground hover:text-foreground hover:bg-accent/50",
372
+ "disabled:pointer-events-none disabled:opacity-50",
373
+ )}
374
+ >
375
+ Cancel
376
+ </button>
377
+ </div>
378
+ </div>
379
+ );
380
+ }
381
+
382
+ // ---------------------------------------------------------------------------
383
+ // ChangeRoleRow (internal)
384
+ // ---------------------------------------------------------------------------
385
+
386
+ function ChangeRoleRow({
387
+ entry,
388
+ orgId,
389
+ onDone,
390
+ onCancel,
391
+ }: {
392
+ entry: PrincipalAccess;
393
+ orgId: string;
394
+ onDone: () => void;
395
+ onCancel: () => void;
396
+ }) {
397
+ const { create: createPolicy, isCreating } = useCreateIamPolicy();
398
+ const { remove: deletePolicy, isDeleting } = useDeleteIamPolicy();
399
+
400
+ const memberId = entry.principal?.id ?? "";
401
+ const memberName = entry.principal?.name || entry.principal?.email || memberId;
402
+ const directRoles = entry.roles.filter((r) => !r.isInherited);
403
+ const currentRoleCode = directRoles[0]?.role?.code;
404
+ const currentRole = currentRoleCode
405
+ ? iamRoleFromString(currentRoleCode) ?? null
406
+ : null;
407
+
408
+ const [selectedRole, setSelectedRole] = useState<IamRole | null>(null);
409
+ const [error, setError] = useState<Error | null>(null);
410
+
411
+ const isWorking = isCreating || isDeleting;
412
+ const canConfirm =
413
+ selectedRole !== null && selectedRole !== currentRole && !isWorking;
414
+
415
+ const handleConfirm = useCallback(async () => {
416
+ if (!selectedRole || !currentRoleCode) return;
417
+ setError(null);
418
+
419
+ try {
420
+ const deleteSpec = create(IamPolicySpecSchema, {
421
+ principal: create(ApiResourceRefSchema, {
422
+ kind: "identity_account",
423
+ id: memberId,
424
+ }),
425
+ resource: create(ApiResourceRefSchema, {
426
+ kind: "organization",
427
+ id: orgId,
428
+ }),
429
+ relation: currentRoleCode,
430
+ });
431
+ await deletePolicy(deleteSpec);
432
+
433
+ const createSpec = create(IamPolicySpecSchema, {
434
+ principal: create(ApiResourceRefSchema, {
435
+ kind: "identity_account",
436
+ id: memberId,
437
+ }),
438
+ resource: create(ApiResourceRefSchema, {
439
+ kind: "organization",
440
+ id: orgId,
441
+ }),
442
+ relation: iamRoleToString(selectedRole),
443
+ });
444
+ await createPolicy(createSpec);
445
+
446
+ onDone();
447
+ } catch (err) {
448
+ setError(err instanceof Error ? err : new Error("Failed to change role"));
449
+ }
450
+ }, [
451
+ selectedRole,
452
+ currentRoleCode,
453
+ memberId,
454
+ orgId,
455
+ deletePolicy,
456
+ createPolicy,
457
+ onDone,
458
+ ]);
459
+
460
+ return (
461
+ <div
462
+ role="listitem"
463
+ className="rounded-lg border border-primary/30 bg-primary/5 px-3 py-2.5 space-y-2"
464
+ >
465
+ <p className="text-xs text-foreground">
466
+ Change role for <span className="font-medium">{memberName}</span>
467
+ </p>
468
+
469
+ <RoleSelector
470
+ kind={ApiResourceKind.organization}
471
+ selected={selectedRole ?? currentRole}
472
+ onSelect={setSelectedRole}
473
+ disabled={isWorking}
474
+ />
475
+
476
+ {error && (
477
+ <p className="text-[0.65rem] text-destructive" role="alert">
478
+ {getUserMessage(error)}
479
+ </p>
480
+ )}
481
+
482
+ <div className="flex items-center gap-1.5">
483
+ <button
484
+ type="button"
485
+ onClick={handleConfirm}
486
+ disabled={!canConfirm}
487
+ className={cn(
488
+ "inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium",
489
+ "bg-primary text-primary-foreground hover:bg-primary/90",
490
+ "disabled:pointer-events-none disabled:opacity-40",
491
+ )}
492
+ >
493
+ {isWorking && <SpinnerIcon />}
494
+ {isWorking ? "Changing role…" : "Confirm"}
495
+ </button>
496
+ <button
497
+ type="button"
498
+ onClick={onCancel}
499
+ disabled={isWorking}
500
+ className={cn(
501
+ "rounded-md px-2.5 py-1 text-xs",
502
+ "text-muted-foreground hover:text-foreground hover:bg-accent/50",
503
+ "disabled:pointer-events-none disabled:opacity-50",
504
+ )}
505
+ >
506
+ Cancel
507
+ </button>
508
+ </div>
509
+ </div>
510
+ );
511
+ }
512
+
513
+ // ---------------------------------------------------------------------------
514
+ // Icons
515
+ // ---------------------------------------------------------------------------
516
+
517
+ function EditIcon() {
518
+ return (
519
+ <svg
520
+ width="14"
521
+ height="14"
522
+ viewBox="0 0 16 16"
523
+ fill="none"
524
+ stroke="currentColor"
525
+ strokeWidth="1.5"
526
+ strokeLinecap="round"
527
+ strokeLinejoin="round"
528
+ aria-hidden="true"
529
+ >
530
+ <path d="M11.5 1.5l3 3L5 14H2v-3L11.5 1.5z" />
531
+ </svg>
532
+ );
533
+ }
534
+
535
+ function TrashIcon() {
536
+ return (
537
+ <svg
538
+ width="14"
539
+ height="14"
540
+ viewBox="0 0 16 16"
541
+ fill="none"
542
+ stroke="currentColor"
543
+ strokeWidth="1.5"
544
+ strokeLinecap="round"
545
+ strokeLinejoin="round"
546
+ aria-hidden="true"
547
+ >
548
+ <path d="M2.5 4h11M5.5 4V2.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1V4" />
549
+ <path d="M12.5 4v9a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V4" />
550
+ <line x1="6.5" y1="7" x2="6.5" y2="11" />
551
+ <line x1="9.5" y1="7" x2="9.5" y2="11" />
552
+ </svg>
553
+ );
554
+ }
555
+
556
+ function SpinnerIcon() {
557
+ return (
558
+ <svg
559
+ width="12"
560
+ height="12"
561
+ viewBox="0 0 16 16"
562
+ fill="none"
563
+ stroke="currentColor"
564
+ strokeWidth="2"
565
+ strokeLinecap="round"
566
+ className="animate-spin"
567
+ aria-hidden="true"
568
+ >
569
+ <path d="M8 2a6 6 0 1 0 6 6" />
570
+ </svg>
571
+ );
572
+ }
@@ -0,0 +1,105 @@
1
+ "use client";
2
+
3
+ import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
4
+ import type { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
5
+ import { cn } from "@stigmer/theme";
6
+ import { useRoleSelector } from "./useRoleSelector";
7
+
8
+ /** Props for {@link RoleSelector}. */
9
+ export interface RoleSelectorProps {
10
+ /** The resource kind whose grantable roles to display. */
11
+ readonly kind: ApiResourceKind | null;
12
+ /** Fired when the user selects a role. */
13
+ readonly onSelect?: (role: IamRole) => void;
14
+ /** Externally controlled selected role — makes this a controlled component. */
15
+ readonly selected?: IamRole | null;
16
+ /** Initial role to select (uncontrolled mode). */
17
+ readonly defaultRole?: IamRole;
18
+ /** Disable all role options. */
19
+ readonly disabled?: boolean;
20
+ /** Additional CSS class names for the root container. */
21
+ readonly className?: string;
22
+ }
23
+
24
+ /**
25
+ * Styled radio-group for selecting an IAM role.
26
+ *
27
+ * Displays all grantable roles for the given resource kind as
28
+ * selectable pills, each showing the role name and description.
29
+ *
30
+ * For a headless alternative, use {@link useRoleSelector} directly.
31
+ *
32
+ * All visual properties flow through `--stgm-*` design tokens.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * <RoleSelector
37
+ * kind={ApiResourceKind.organization}
38
+ * onSelect={(role) => setRole(role)}
39
+ * />
40
+ * ```
41
+ */
42
+ export function RoleSelector({
43
+ kind,
44
+ onSelect,
45
+ selected: controlledSelected,
46
+ defaultRole,
47
+ disabled = false,
48
+ className,
49
+ }: RoleSelectorProps) {
50
+ const { options, selected: internalSelected, select } = useRoleSelector(
51
+ kind,
52
+ defaultRole,
53
+ );
54
+
55
+ const currentSelected = controlledSelected !== undefined
56
+ ? controlledSelected
57
+ : internalSelected;
58
+
59
+ const handleSelect = (role: IamRole) => {
60
+ select(role);
61
+ onSelect?.(role);
62
+ };
63
+
64
+ if (options.length === 0) {
65
+ return null;
66
+ }
67
+
68
+ return (
69
+ <fieldset className={cn("space-y-1.5", className)}>
70
+ <legend className="text-xs font-medium text-foreground">Role</legend>
71
+ <div className="flex flex-wrap gap-2">
72
+ {options.map((opt) => {
73
+ const isChecked = currentSelected === opt.role;
74
+ return (
75
+ <label
76
+ key={opt.value}
77
+ title={opt.description}
78
+ className={cn(
79
+ "inline-flex cursor-pointer flex-col rounded-md border px-3 py-1.5 text-xs transition-colors",
80
+ isChecked
81
+ ? "border-primary bg-primary-subtle text-primary font-medium"
82
+ : "border-input bg-background text-muted-foreground hover:border-border hover:text-foreground",
83
+ disabled && "pointer-events-none opacity-50",
84
+ )}
85
+ >
86
+ <input
87
+ type="radio"
88
+ name="stgm-role-selector"
89
+ value={opt.value}
90
+ checked={isChecked}
91
+ disabled={disabled}
92
+ onChange={() => handleSelect(opt.role)}
93
+ className="sr-only"
94
+ />
95
+ <span>{opt.label}</span>
96
+ <span className="text-[0.625rem] text-muted-foreground font-normal mt-0.5">
97
+ {opt.description}
98
+ </span>
99
+ </label>
100
+ );
101
+ })}
102
+ </div>
103
+ </fieldset>
104
+ );
105
+ }