@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,434 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage, iamRoleDisplayName } from "@stigmer/sdk";
6
+ import type { Invitation } from "@stigmer/protos/ai/stigmer/iam/invitation/v1/api_pb";
7
+ import { timestampDate } from "@bufbuild/protobuf/wkt";
8
+ import { useInvitationPreview } from "./useInvitationPreview";
9
+ import { useRedeemInvitation } from "./useRedeemInvitation";
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // Public API
13
+ // ---------------------------------------------------------------------------
14
+
15
+ /** Props for {@link InvitationRedemption}. */
16
+ export interface InvitationRedemptionProps {
17
+ /** The invitation token from the invite URL. */
18
+ readonly token: string;
19
+ /**
20
+ * Whether the current user is authenticated.
21
+ *
22
+ * When `false`, the component shows a "Sign in to accept" CTA
23
+ * instead of the accept button. When `true` or omitted, the
24
+ * accept button calls `redeem` directly.
25
+ *
26
+ * @default true
27
+ */
28
+ readonly isAuthenticated?: boolean;
29
+ /**
30
+ * Fired after the invitation is successfully redeemed.
31
+ *
32
+ * The returned {@link Invitation} contains the organization and
33
+ * role information needed for post-redemption navigation
34
+ * (e.g. redirecting to the org dashboard).
35
+ */
36
+ readonly onAccepted?: (invitation: Invitation) => void;
37
+ /**
38
+ * Fired when an unauthenticated user clicks "Sign in to accept".
39
+ *
40
+ * The host application controls what "sign in" means — this
41
+ * callback typically triggers a redirect to the login page with
42
+ * a return URL back to the invite page.
43
+ */
44
+ readonly onAuthRequired?: () => void;
45
+ /** Additional CSS class names for the root container. */
46
+ readonly className?: string;
47
+ }
48
+
49
+ /**
50
+ * Self-contained invite acceptance flow.
51
+ *
52
+ * Fetches the invitation preview by token (public endpoint, no auth
53
+ * required), displays the organization info and role being offered,
54
+ * and provides an accept button that redeems the invitation.
55
+ *
56
+ * Handles all states: loading, invalid (expired / revoked / fully
57
+ * redeemed), authentication required, redemption in flight,
58
+ * success, and error — with appropriate UX for each.
59
+ *
60
+ * The component is auth-agnostic: it delegates authentication
61
+ * decisions to the host application via `isAuthenticated` and
62
+ * `onAuthRequired` props. Platform builders who render this
63
+ * component only for authenticated users can ignore both props.
64
+ *
65
+ * All visual properties flow through `--stgm-*` design tokens.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * <InvitationRedemption
70
+ * token={tokenFromUrl}
71
+ * onAccepted={(inv) => router.push("/dashboard")}
72
+ * />
73
+ *
74
+ * <InvitationRedemption
75
+ * token={tokenFromUrl}
76
+ * isAuthenticated={!!currentUser}
77
+ * onAccepted={(inv) => router.push(`/org/${inv.metadata?.org}`)}
78
+ * onAuthRequired={() => router.push(`/login?return=/invite/${token}`)}
79
+ * />
80
+ * ```
81
+ */
82
+ export function InvitationRedemption({
83
+ token,
84
+ isAuthenticated = true,
85
+ onAccepted,
86
+ onAuthRequired,
87
+ className,
88
+ }: InvitationRedemptionProps) {
89
+ const { preview, isLoading, error: fetchError, refetch } = useInvitationPreview(token);
90
+ const { redeem, isRedeeming, error: redeemError, clearError } = useRedeemInvitation();
91
+ const [accepted, setAccepted] = useState<Invitation | null>(null);
92
+
93
+ const handleAccept = useCallback(async () => {
94
+ clearError();
95
+ try {
96
+ const invitation = await redeem(token);
97
+ setAccepted(invitation);
98
+ onAccepted?.(invitation);
99
+ } catch {
100
+ // error state is managed by useRedeemInvitation
101
+ }
102
+ }, [token, redeem, clearError, onAccepted]);
103
+
104
+ // Loading state
105
+ if (isLoading) {
106
+ return (
107
+ <div
108
+ className={cn("mx-auto max-w-sm", className)}
109
+ aria-busy="true"
110
+ aria-label="Loading invitation"
111
+ >
112
+ <LoadingSkeleton />
113
+ </div>
114
+ );
115
+ }
116
+
117
+ // Fetch error
118
+ if (fetchError) {
119
+ return (
120
+ <div className={cn("mx-auto max-w-sm", className)}>
121
+ <ErrorCard
122
+ message={getUserMessage(fetchError)}
123
+ onRetry={refetch}
124
+ />
125
+ </div>
126
+ );
127
+ }
128
+
129
+ // No preview returned
130
+ if (!preview) {
131
+ return (
132
+ <div className={cn("mx-auto max-w-sm", className)}>
133
+ <ErrorCard message="This invitation could not be found." />
134
+ </div>
135
+ );
136
+ }
137
+
138
+ // Redemption success
139
+ if (accepted) {
140
+ const orgName = preview.organizationName || "the organization";
141
+ const roleName = iamRoleDisplayName(preview.role);
142
+ return (
143
+ <div className={cn("mx-auto max-w-sm", className)}>
144
+ <div className="rounded-lg border border-primary/30 bg-primary-subtle p-6 text-center">
145
+ <SuccessIcon />
146
+ <h2 className="mt-3 text-base font-semibold text-foreground">
147
+ You&rsquo;ve joined {orgName}
148
+ </h2>
149
+ <p className="mt-1 text-sm text-muted-foreground">
150
+ You now have <span className="font-medium text-foreground">{roleName}</span> access.
151
+ </p>
152
+ </div>
153
+ </div>
154
+ );
155
+ }
156
+
157
+ const orgName = preview.organizationName || "Unknown organization";
158
+ const orgLogo = preview.organizationLogoUrl;
159
+ const orgInitial = orgName.charAt(0).toUpperCase();
160
+ const roleName = iamRoleDisplayName(preview.role);
161
+ const expiresAt = preview.expiresAt ? timestampDate(preview.expiresAt) : null;
162
+
163
+ return (
164
+ <div className={cn("mx-auto max-w-sm", className)}>
165
+ <div className="rounded-lg border border-border bg-card p-6">
166
+ {/* Org identity */}
167
+ <div className="flex flex-col items-center text-center">
168
+ {orgLogo ? (
169
+ <img
170
+ src={orgLogo}
171
+ alt={`${orgName} logo`}
172
+ className="size-12 rounded-full object-cover"
173
+ />
174
+ ) : (
175
+ <div className="flex size-12 items-center justify-center rounded-full bg-muted text-lg font-semibold text-muted-foreground">
176
+ {orgInitial}
177
+ </div>
178
+ )}
179
+
180
+ <h2 className="mt-3 text-base font-semibold text-foreground">
181
+ Join {orgName}
182
+ </h2>
183
+
184
+ {preview.label && (
185
+ <p className="mt-1 text-sm text-muted-foreground">
186
+ {preview.label}
187
+ </p>
188
+ )}
189
+ </div>
190
+
191
+ {/* Role + expiry details */}
192
+ <div className="mt-4 flex items-center justify-center gap-3 text-xs text-muted-foreground">
193
+ <span className="inline-flex items-center gap-1">
194
+ <ShieldIcon />
195
+ {roleName} access
196
+ </span>
197
+ {expiresAt && (
198
+ <>
199
+ <Separator />
200
+ <span>{formatExpiry(expiresAt)}</span>
201
+ </>
202
+ )}
203
+ </div>
204
+
205
+ {/* Invalid state */}
206
+ {!preview.isValid && (
207
+ <InvalidNotice reason={preview.invalidReason} />
208
+ )}
209
+
210
+ {/* Action area */}
211
+ {preview.isValid && (
212
+ <div className="mt-5">
213
+ {isAuthenticated ? (
214
+ <>
215
+ <button
216
+ type="button"
217
+ onClick={handleAccept}
218
+ disabled={isRedeeming}
219
+ className={cn(
220
+ "w-full inline-flex items-center justify-center gap-1.5 rounded-md px-4 py-2 text-sm font-medium",
221
+ "bg-primary text-primary-foreground hover:bg-primary/90",
222
+ "disabled:pointer-events-none disabled:opacity-50",
223
+ "transition-colors",
224
+ )}
225
+ >
226
+ {isRedeeming && <SpinnerIcon />}
227
+ {isRedeeming ? "Accepting\u2026" : "Accept Invitation"}
228
+ </button>
229
+ {redeemError && (
230
+ <p className="mt-2 text-center text-[0.65rem] text-destructive" role="alert">
231
+ {getUserMessage(redeemError)}
232
+ </p>
233
+ )}
234
+ </>
235
+ ) : (
236
+ <button
237
+ type="button"
238
+ onClick={onAuthRequired}
239
+ className={cn(
240
+ "w-full inline-flex items-center justify-center gap-1.5 rounded-md px-4 py-2 text-sm font-medium",
241
+ "bg-primary text-primary-foreground hover:bg-primary/90",
242
+ "transition-colors",
243
+ )}
244
+ >
245
+ Sign in to accept
246
+ </button>
247
+ )}
248
+ </div>
249
+ )}
250
+ </div>
251
+ </div>
252
+ );
253
+ }
254
+
255
+ // ---------------------------------------------------------------------------
256
+ // InvalidNotice (internal)
257
+ // ---------------------------------------------------------------------------
258
+
259
+ function InvalidNotice({ reason }: { reason: string }) {
260
+ return (
261
+ <div className="mt-4 rounded-md bg-muted/50 px-3 py-2.5 text-center">
262
+ <WarningIcon />
263
+ <p className="mt-1 text-xs text-muted-foreground">
264
+ {reason || "This invitation is no longer valid."}
265
+ </p>
266
+ </div>
267
+ );
268
+ }
269
+
270
+ // ---------------------------------------------------------------------------
271
+ // ErrorCard (internal)
272
+ // ---------------------------------------------------------------------------
273
+
274
+ function ErrorCard({
275
+ message,
276
+ onRetry,
277
+ }: {
278
+ message: string;
279
+ onRetry?: () => void;
280
+ }) {
281
+ return (
282
+ <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-6 text-center">
283
+ <p className="text-sm text-destructive">{message}</p>
284
+ {onRetry && (
285
+ <button
286
+ type="button"
287
+ onClick={onRetry}
288
+ className={cn(
289
+ "mt-3 inline-flex items-center rounded-md px-3 py-1.5 text-xs font-medium",
290
+ "text-muted-foreground hover:text-foreground hover:bg-accent/50",
291
+ "transition-colors",
292
+ )}
293
+ >
294
+ Try again
295
+ </button>
296
+ )}
297
+ </div>
298
+ );
299
+ }
300
+
301
+ // ---------------------------------------------------------------------------
302
+ // LoadingSkeleton (internal)
303
+ // ---------------------------------------------------------------------------
304
+
305
+ function LoadingSkeleton() {
306
+ return (
307
+ <div className="rounded-lg border border-border bg-card p-6 space-y-4">
308
+ <div className="flex flex-col items-center gap-3">
309
+ <div className="size-12 rounded-full bg-muted/40 animate-pulse" />
310
+ <div className="h-5 w-40 rounded bg-muted/40 animate-pulse" />
311
+ <div className="h-4 w-56 rounded bg-muted/40 animate-pulse" />
312
+ </div>
313
+ <div className="flex justify-center gap-3">
314
+ <div className="h-4 w-24 rounded bg-muted/40 animate-pulse" />
315
+ <div className="h-4 w-24 rounded bg-muted/40 animate-pulse" />
316
+ </div>
317
+ <div className="h-10 w-full rounded-md bg-muted/40 animate-pulse" />
318
+ </div>
319
+ );
320
+ }
321
+
322
+ // ---------------------------------------------------------------------------
323
+ // Formatting helpers
324
+ // ---------------------------------------------------------------------------
325
+
326
+ function formatExpiry(date: Date): string {
327
+ const now = Date.now();
328
+ const diffMs = date.getTime() - now;
329
+
330
+ if (diffMs <= 0) return "Expired";
331
+
332
+ const days = Math.ceil(diffMs / 86_400_000);
333
+ if (days === 1) return "Expires tomorrow";
334
+ if (days <= 30) return `Expires in ${days} days`;
335
+
336
+ return `Expires ${date.toLocaleDateString(undefined, {
337
+ month: "short",
338
+ day: "numeric",
339
+ year: "numeric",
340
+ })}`;
341
+ }
342
+
343
+ // ---------------------------------------------------------------------------
344
+ // Separator (internal)
345
+ // ---------------------------------------------------------------------------
346
+
347
+ function Separator() {
348
+ return (
349
+ <span className="text-border" aria-hidden="true">
350
+ &middot;
351
+ </span>
352
+ );
353
+ }
354
+
355
+ // ---------------------------------------------------------------------------
356
+ // Icons
357
+ // ---------------------------------------------------------------------------
358
+
359
+ function ShieldIcon() {
360
+ return (
361
+ <svg
362
+ width="12"
363
+ height="12"
364
+ viewBox="0 0 16 16"
365
+ fill="none"
366
+ stroke="currentColor"
367
+ strokeWidth="1.5"
368
+ strokeLinecap="round"
369
+ strokeLinejoin="round"
370
+ aria-hidden="true"
371
+ className="shrink-0"
372
+ >
373
+ <path d="M8 1.5l5.5 2v4.5c0 3.5-2.5 5.5-5.5 7-3-1.5-5.5-3.5-5.5-7V3.5L8 1.5z" />
374
+ </svg>
375
+ );
376
+ }
377
+
378
+ function WarningIcon() {
379
+ return (
380
+ <svg
381
+ width="16"
382
+ height="16"
383
+ viewBox="0 0 16 16"
384
+ fill="none"
385
+ stroke="currentColor"
386
+ strokeWidth="1.5"
387
+ strokeLinecap="round"
388
+ strokeLinejoin="round"
389
+ aria-hidden="true"
390
+ className="mx-auto text-muted-foreground"
391
+ >
392
+ <circle cx="8" cy="8" r="6" />
393
+ <path d="M8 5v3.5M8 10.5v.5" />
394
+ </svg>
395
+ );
396
+ }
397
+
398
+ function SuccessIcon() {
399
+ return (
400
+ <svg
401
+ width="24"
402
+ height="24"
403
+ viewBox="0 0 24 24"
404
+ fill="none"
405
+ stroke="currentColor"
406
+ strokeWidth="2"
407
+ strokeLinecap="round"
408
+ strokeLinejoin="round"
409
+ aria-hidden="true"
410
+ className="mx-auto text-primary"
411
+ >
412
+ <circle cx="12" cy="12" r="10" />
413
+ <path d="M8 12l2.5 2.5L16 9" />
414
+ </svg>
415
+ );
416
+ }
417
+
418
+ function SpinnerIcon() {
419
+ return (
420
+ <svg
421
+ width="14"
422
+ height="14"
423
+ viewBox="0 0 16 16"
424
+ fill="none"
425
+ stroke="currentColor"
426
+ strokeWidth="2"
427
+ strokeLinecap="round"
428
+ className="animate-spin"
429
+ aria-hidden="true"
430
+ >
431
+ <path d="M8 2a6 6 0 1 0 6 6" />
432
+ </svg>
433
+ );
434
+ }
@@ -0,0 +1,16 @@
1
+ export { useOrgInvitations } from "./useOrgInvitations";
2
+ export type { UseOrgInvitationsReturn } from "./useOrgInvitations";
3
+ export { useCreateInvitation } from "./useCreateInvitation";
4
+ export type { UseCreateInvitationReturn } from "./useCreateInvitation";
5
+ export { useRevokeInvitation } from "./useRevokeInvitation";
6
+ export type { UseRevokeInvitationReturn } from "./useRevokeInvitation";
7
+ export { useInvitationPreview } from "./useInvitationPreview";
8
+ export type { UseInvitationPreviewReturn } from "./useInvitationPreview";
9
+ export { useRedeemInvitation } from "./useRedeemInvitation";
10
+ export type { UseRedeemInvitationReturn } from "./useRedeemInvitation";
11
+ export { InvitationCreatedAlert } from "./InvitationCreatedAlert";
12
+ export type { InvitationCreatedAlertProps } from "./InvitationCreatedAlert";
13
+ export { InvitationManager } from "./InvitationManager";
14
+ export type { InvitationManagerProps } from "./InvitationManager";
15
+ export { InvitationRedemption } from "./InvitationRedemption";
16
+ export type { InvitationRedemptionProps } from "./InvitationRedemption";
@@ -0,0 +1,83 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import type { InvitationInput } from "@stigmer/sdk";
5
+ import type { Invitation } from "@stigmer/protos/ai/stigmer/iam/invitation/v1/api_pb";
6
+ import { useStigmer } from "../hooks";
7
+ import { toError } from "../internal/toError";
8
+
9
+ /** Return value of {@link useCreateInvitation}. */
10
+ export interface UseCreateInvitationReturn {
11
+ /**
12
+ * Create an invitation link for an organization.
13
+ *
14
+ * Resolves with the server-created {@link Invitation} including the
15
+ * generated token in `status.token`. Callers must capture this token
16
+ * to construct the invite URL — it is always available via `get` and
17
+ * `listByOrg`, but surfacing it immediately after creation is the
18
+ * expected UX flow.
19
+ */
20
+ readonly create: (input: InvitationInput) => Promise<Invitation>;
21
+ /** `true` while the create request is in flight. */
22
+ readonly isCreating: boolean;
23
+ /** Error from the last failed create, or `null` when healthy. */
24
+ readonly error: Error | null;
25
+ /** Reset `error` to `null`. */
26
+ readonly clearError: () => void;
27
+ }
28
+
29
+ /**
30
+ * Behavior hook that wraps `invitation.create()` with loading and
31
+ * error state.
32
+ *
33
+ * Creates an invitation resource. The caller provides an
34
+ * {@link InvitationInput} with `name`, `org`, `role`, `expiresAt`,
35
+ * and optionally `maxRedemptions` and `label`.
36
+ *
37
+ * The returned {@link Invitation} contains the server-generated token
38
+ * in `status?.token`. Use this to build the invite URL:
39
+ * `https://<host>/invite/<token>`.
40
+ *
41
+ * Creating an invitation requires `can_grant_access` on the
42
+ * organization — typically limited to admins and owners.
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * const { create, isCreating, error } = useCreateInvitation();
47
+ *
48
+ * const invitation = await create({
49
+ * name: "engineering-link",
50
+ * org: "acme",
51
+ * role: IamRole.VIEWER,
52
+ * expiresAt: new Date(Date.now() + 30 * 86_400_000),
53
+ * label: "Engineering team invite",
54
+ * });
55
+ * const inviteUrl = `${window.location.origin}/invite/${invitation.status?.token}`;
56
+ * ```
57
+ */
58
+ export function useCreateInvitation(): UseCreateInvitationReturn {
59
+ const stigmer = useStigmer();
60
+ const [isCreating, setIsCreating] = useState(false);
61
+ const [error, setError] = useState<Error | null>(null);
62
+
63
+ const clearError = useCallback(() => setError(null), []);
64
+
65
+ const create = useCallback(
66
+ async (input: InvitationInput): Promise<Invitation> => {
67
+ setIsCreating(true);
68
+ setError(null);
69
+
70
+ try {
71
+ return await stigmer.invitation.create(input);
72
+ } catch (err) {
73
+ setError(toError(err));
74
+ throw err;
75
+ } finally {
76
+ setIsCreating(false);
77
+ }
78
+ },
79
+ [stigmer],
80
+ );
81
+
82
+ return { create, isCreating, error, clearError };
83
+ }
@@ -0,0 +1,103 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import { create } from "@bufbuild/protobuf";
5
+ import type { InvitationPreview } from "@stigmer/protos/ai/stigmer/iam/invitation/v1/io_pb";
6
+ import { InvitationTokenInputSchema } from "@stigmer/protos/ai/stigmer/iam/invitation/v1/io_pb";
7
+ import { useStigmer } from "../hooks";
8
+ import { toError } from "../internal/toError";
9
+
10
+ /** Return value of {@link useInvitationPreview}. */
11
+ export interface UseInvitationPreviewReturn {
12
+ /** The invitation preview, or `null` while loading or on error. */
13
+ readonly preview: InvitationPreview | null;
14
+ /** `true` while the initial fetch or a refetch is in flight. */
15
+ readonly isLoading: boolean;
16
+ /** Error from the last failed request, or `null` when healthy. */
17
+ readonly error: Error | null;
18
+ /** Discard cached data and re-fetch the preview from the server. */
19
+ readonly refetch: () => void;
20
+ }
21
+
22
+ /**
23
+ * Data hook that fetches an {@link InvitationPreview} by its
24
+ * shareable token.
25
+ *
26
+ * Pass `null` to skip fetching (stable no-op). When the `token`
27
+ * changes, the previous in-flight request is discarded and a fresh
28
+ * fetch begins.
29
+ *
30
+ * This hook calls the `getByToken` endpoint, which is **public** —
31
+ * it requires no authentication. The server returns a safe projection
32
+ * containing only the information needed to render the invite
33
+ * acceptance page: organization name/logo, the role being offered,
34
+ * expiry, and whether the invitation is still valid.
35
+ *
36
+ * Check `preview.isValid` before offering the redemption action.
37
+ * When `false`, `preview.invalidReason` contains a human-readable
38
+ * explanation (expired, revoked, or fully redeemed).
39
+ *
40
+ * **Note**: Although authentication is not required by the server,
41
+ * the hook still requires a `StigmerProvider` ancestor because it
42
+ * needs the transport configuration (API base URL) to make the
43
+ * request.
44
+ *
45
+ * @param token - The invitation token from the invite URL, or `null`
46
+ * to skip fetching.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * const { preview, isLoading, error } = useInvitationPreview(token);
51
+ *
52
+ * if (isLoading) return <Spinner />;
53
+ * if (!preview) return <NotFound />;
54
+ * if (!preview.isValid) return <Expired reason={preview.invalidReason} />;
55
+ *
56
+ * return <p>Join {preview.organizationName} as {preview.role}</p>;
57
+ * ```
58
+ */
59
+ export function useInvitationPreview(
60
+ token: string | null,
61
+ ): UseInvitationPreviewReturn {
62
+ const stigmer = useStigmer();
63
+ const [preview, setPreview] = useState<InvitationPreview | null>(null);
64
+ const [isLoading, setIsLoading] = useState(false);
65
+ const [error, setError] = useState<Error | null>(null);
66
+ const [fetchKey, setFetchKey] = useState(0);
67
+
68
+ const refetch = useCallback(() => setFetchKey((k) => k + 1), []);
69
+
70
+ useEffect(() => {
71
+ if (!token) {
72
+ setPreview(null);
73
+ setIsLoading(false);
74
+ setError(null);
75
+ return;
76
+ }
77
+
78
+ const cancelled = { current: false };
79
+ setIsLoading(true);
80
+ setError(null);
81
+
82
+ stigmer.invitation
83
+ .getByToken(create(InvitationTokenInputSchema, { token }))
84
+ .then(
85
+ (result) => {
86
+ if (cancelled.current) return;
87
+ setPreview(result);
88
+ setIsLoading(false);
89
+ },
90
+ (err) => {
91
+ if (cancelled.current) return;
92
+ setError(toError(err));
93
+ setIsLoading(false);
94
+ },
95
+ );
96
+
97
+ return () => {
98
+ cancelled.current = true;
99
+ };
100
+ }, [token, stigmer, fetchKey]);
101
+
102
+ return { preview, isLoading, error, refetch };
103
+ }