@stigmer/react 3.2.2 → 3.3.0

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 (513) hide show
  1. package/agent/AgentDetailView.d.ts.map +1 -1
  2. package/agent/AgentDetailView.js +6 -3
  3. package/agent/AgentDetailView.js.map +1 -1
  4. package/agent/steps/ReviewStep.d.ts.map +1 -1
  5. package/agent/steps/ReviewStep.js +2 -3
  6. package/agent/steps/ReviewStep.js.map +1 -1
  7. package/billing/BaselineEditor.d.ts +9 -0
  8. package/billing/BaselineEditor.d.ts.map +1 -0
  9. package/billing/BaselineEditor.js +253 -0
  10. package/billing/BaselineEditor.js.map +1 -0
  11. package/billing/ModelCatalogPanel.d.ts +28 -0
  12. package/billing/ModelCatalogPanel.d.ts.map +1 -0
  13. package/billing/ModelCatalogPanel.js +102 -0
  14. package/billing/ModelCatalogPanel.js.map +1 -0
  15. package/billing/ModelGovernanceDetail.d.ts +8 -0
  16. package/billing/ModelGovernanceDetail.d.ts.map +1 -0
  17. package/billing/ModelGovernanceDetail.js +64 -0
  18. package/billing/ModelGovernanceDetail.js.map +1 -0
  19. package/billing/OperatorAccessNotice.d.ts +12 -0
  20. package/billing/OperatorAccessNotice.d.ts.map +1 -0
  21. package/billing/OperatorAccessNotice.js +15 -0
  22. package/billing/OperatorAccessNotice.js.map +1 -0
  23. package/billing/PricingGovernanceConsole.d.ts +57 -0
  24. package/billing/PricingGovernanceConsole.d.ts.map +1 -0
  25. package/billing/PricingGovernanceConsole.js +164 -0
  26. package/billing/PricingGovernanceConsole.js.map +1 -0
  27. package/billing/PricingGovernancePanel.d.ts +26 -0
  28. package/billing/PricingGovernancePanel.d.ts.map +1 -0
  29. package/billing/PricingGovernancePanel.js +64 -0
  30. package/billing/PricingGovernancePanel.js.map +1 -0
  31. package/billing/RetireConfirm.d.ts +9 -0
  32. package/billing/RetireConfirm.d.ts.map +1 -0
  33. package/billing/RetireConfirm.js +19 -0
  34. package/billing/RetireConfirm.js.map +1 -0
  35. package/billing/form-primitives.d.ts +18 -0
  36. package/billing/form-primitives.d.ts.map +1 -0
  37. package/billing/form-primitives.js +19 -0
  38. package/billing/form-primitives.js.map +1 -0
  39. package/billing/governance-primitives.d.ts +33 -0
  40. package/billing/governance-primitives.d.ts.map +1 -0
  41. package/billing/governance-primitives.js +43 -0
  42. package/billing/governance-primitives.js.map +1 -0
  43. package/billing/index.d.ts +18 -0
  44. package/billing/index.d.ts.map +1 -1
  45. package/billing/index.js +9 -0
  46. package/billing/index.js.map +1 -1
  47. package/billing/pricing-format.d.ts +12 -0
  48. package/billing/pricing-format.d.ts.map +1 -0
  49. package/billing/pricing-format.js +50 -0
  50. package/billing/pricing-format.js.map +1 -0
  51. package/billing/useDecidePricingOverride.d.ts +46 -0
  52. package/billing/useDecidePricingOverride.d.ts.map +1 -0
  53. package/billing/useDecidePricingOverride.js +44 -0
  54. package/billing/useDecidePricingOverride.js.map +1 -0
  55. package/billing/useModelGovernanceView.d.ts +103 -0
  56. package/billing/useModelGovernanceView.d.ts.map +1 -0
  57. package/billing/useModelGovernanceView.js +144 -0
  58. package/billing/useModelGovernanceView.js.map +1 -0
  59. package/billing/useModelPricingBaselines.d.ts +40 -0
  60. package/billing/useModelPricingBaselines.d.ts.map +1 -0
  61. package/billing/useModelPricingBaselines.js +32 -0
  62. package/billing/useModelPricingBaselines.js.map +1 -0
  63. package/billing/usePricingGovernance.d.ts +39 -0
  64. package/billing/usePricingGovernance.d.ts.map +1 -0
  65. package/billing/usePricingGovernance.js +31 -0
  66. package/billing/usePricingGovernance.js.map +1 -0
  67. package/billing/useRetireModelPricingBaseline.d.ts +31 -0
  68. package/billing/useRetireModelPricingBaseline.d.ts.map +1 -0
  69. package/billing/useRetireModelPricingBaseline.js +36 -0
  70. package/billing/useRetireModelPricingBaseline.js.map +1 -0
  71. package/billing/useUpsertModelPricingBaseline.d.ts +38 -0
  72. package/billing/useUpsertModelPricingBaseline.d.ts.map +1 -0
  73. package/billing/useUpsertModelPricingBaseline.js +37 -0
  74. package/billing/useUpsertModelPricingBaseline.js.map +1 -0
  75. package/channel/AgentChannelsPanel.d.ts.map +1 -1
  76. package/channel/AgentChannelsPanel.js +11 -5
  77. package/channel/AgentChannelsPanel.js.map +1 -1
  78. package/composer/SessionComposer.d.ts +1 -1
  79. package/cursor-accounts/CursorAccountEditor.d.ts +28 -0
  80. package/cursor-accounts/CursorAccountEditor.d.ts.map +1 -0
  81. package/cursor-accounts/CursorAccountEditor.js +51 -0
  82. package/cursor-accounts/CursorAccountEditor.js.map +1 -0
  83. package/cursor-accounts/CursorAccountsAccessNotice.d.ts +11 -0
  84. package/cursor-accounts/CursorAccountsAccessNotice.d.ts.map +1 -0
  85. package/cursor-accounts/CursorAccountsAccessNotice.js +14 -0
  86. package/cursor-accounts/CursorAccountsAccessNotice.js.map +1 -0
  87. package/cursor-accounts/CursorAccountsConsole.d.ts +28 -0
  88. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -0
  89. package/cursor-accounts/CursorAccountsConsole.js +275 -0
  90. package/cursor-accounts/CursorAccountsConsole.js.map +1 -0
  91. package/cursor-accounts/cursor-account-format.d.ts +10 -0
  92. package/cursor-accounts/cursor-account-format.d.ts.map +1 -0
  93. package/cursor-accounts/cursor-account-format.js +26 -0
  94. package/cursor-accounts/cursor-account-format.js.map +1 -0
  95. package/cursor-accounts/index.d.ts +18 -0
  96. package/cursor-accounts/index.d.ts.map +1 -0
  97. package/cursor-accounts/index.js +13 -0
  98. package/cursor-accounts/index.js.map +1 -0
  99. package/cursor-accounts/useCursorAccountView.d.ts +30 -0
  100. package/cursor-accounts/useCursorAccountView.d.ts.map +1 -0
  101. package/cursor-accounts/useCursorAccountView.js +25 -0
  102. package/cursor-accounts/useCursorAccountView.js.map +1 -0
  103. package/cursor-accounts/useCursorAccounts.d.ts +33 -0
  104. package/cursor-accounts/useCursorAccounts.d.ts.map +1 -0
  105. package/cursor-accounts/useCursorAccounts.js +25 -0
  106. package/cursor-accounts/useCursorAccounts.js.map +1 -0
  107. package/cursor-accounts/useCursorMemberKeyActions.d.ts +49 -0
  108. package/cursor-accounts/useCursorMemberKeyActions.d.ts.map +1 -0
  109. package/cursor-accounts/useCursorMemberKeyActions.js +38 -0
  110. package/cursor-accounts/useCursorMemberKeyActions.js.map +1 -0
  111. package/cursor-accounts/useDeleteCursorAccount.d.ts +30 -0
  112. package/cursor-accounts/useDeleteCursorAccount.d.ts.map +1 -0
  113. package/cursor-accounts/useDeleteCursorAccount.js +32 -0
  114. package/cursor-accounts/useDeleteCursorAccount.js.map +1 -0
  115. package/cursor-accounts/useSyncCursorAccount.d.ts +23 -0
  116. package/cursor-accounts/useSyncCursorAccount.d.ts.map +1 -0
  117. package/cursor-accounts/useSyncCursorAccount.js +31 -0
  118. package/cursor-accounts/useSyncCursorAccount.js.map +1 -0
  119. package/cursor-accounts/useUpsertCursorAccount.d.ts +26 -0
  120. package/cursor-accounts/useUpsertCursorAccount.d.ts.map +1 -0
  121. package/cursor-accounts/useUpsertCursorAccount.js +34 -0
  122. package/cursor-accounts/useUpsertCursorAccount.js.map +1 -0
  123. package/datastore/CollectionRecordsBrowser.d.ts +34 -0
  124. package/datastore/CollectionRecordsBrowser.d.ts.map +1 -0
  125. package/datastore/CollectionRecordsBrowser.js +209 -0
  126. package/datastore/CollectionRecordsBrowser.js.map +1 -0
  127. package/datastore/CollectionSchemaView.d.ts +29 -0
  128. package/datastore/CollectionSchemaView.d.ts.map +1 -0
  129. package/datastore/CollectionSchemaView.js +93 -0
  130. package/datastore/CollectionSchemaView.js.map +1 -0
  131. package/datastore/DatastoreDetailView.d.ts +44 -0
  132. package/datastore/DatastoreDetailView.d.ts.map +1 -0
  133. package/datastore/DatastoreDetailView.js +76 -0
  134. package/datastore/DatastoreDetailView.js.map +1 -0
  135. package/datastore/DatastoreSyncReport.d.ts +19 -0
  136. package/datastore/DatastoreSyncReport.d.ts.map +1 -0
  137. package/datastore/DatastoreSyncReport.js +45 -0
  138. package/datastore/DatastoreSyncReport.js.map +1 -0
  139. package/datastore/DeleteDatastoreDialog.d.ts +35 -0
  140. package/datastore/DeleteDatastoreDialog.d.ts.map +1 -0
  141. package/datastore/DeleteDatastoreDialog.js +90 -0
  142. package/datastore/DeleteDatastoreDialog.js.map +1 -0
  143. package/datastore/FieldValueControl.d.ts +55 -0
  144. package/datastore/FieldValueControl.d.ts.map +1 -0
  145. package/datastore/FieldValueControl.js +138 -0
  146. package/datastore/FieldValueControl.js.map +1 -0
  147. package/datastore/RecordFilterBuilder.d.ts +30 -0
  148. package/datastore/RecordFilterBuilder.d.ts.map +1 -0
  149. package/datastore/RecordFilterBuilder.js +122 -0
  150. package/datastore/RecordFilterBuilder.js.map +1 -0
  151. package/datastore/RecordFormPanel.d.ts +45 -0
  152. package/datastore/RecordFormPanel.d.ts.map +1 -0
  153. package/datastore/RecordFormPanel.js +215 -0
  154. package/datastore/RecordFormPanel.js.map +1 -0
  155. package/datastore/index.d.ts +43 -0
  156. package/datastore/index.d.ts.map +1 -0
  157. package/datastore/index.js +22 -0
  158. package/datastore/index.js.map +1 -0
  159. package/datastore/recordFilter.d.ts +54 -0
  160. package/datastore/recordFilter.d.ts.map +1 -0
  161. package/datastore/recordFilter.js +93 -0
  162. package/datastore/recordFilter.js.map +1 -0
  163. package/datastore/recordValues.d.ts +85 -0
  164. package/datastore/recordValues.d.ts.map +1 -0
  165. package/datastore/recordValues.js +282 -0
  166. package/datastore/recordValues.js.map +1 -0
  167. package/datastore/useDatastore.d.ts +39 -0
  168. package/datastore/useDatastore.d.ts.map +1 -0
  169. package/datastore/useDatastore.js +44 -0
  170. package/datastore/useDatastore.js.map +1 -0
  171. package/datastore/useDatastoreCount.d.ts +48 -0
  172. package/datastore/useDatastoreCount.d.ts.map +1 -0
  173. package/datastore/useDatastoreCount.js +27 -0
  174. package/datastore/useDatastoreCount.js.map +1 -0
  175. package/datastore/useDatastoreDescription.d.ts +54 -0
  176. package/datastore/useDatastoreDescription.d.ts.map +1 -0
  177. package/datastore/useDatastoreDescription.js +50 -0
  178. package/datastore/useDatastoreDescription.js.map +1 -0
  179. package/datastore/useDatastoreList.d.ts +57 -0
  180. package/datastore/useDatastoreList.d.ts.map +1 -0
  181. package/datastore/useDatastoreList.js +29 -0
  182. package/datastore/useDatastoreList.js.map +1 -0
  183. package/datastore/useDatastoreSearch.d.ts +19 -0
  184. package/datastore/useDatastoreSearch.d.ts.map +1 -0
  185. package/datastore/useDatastoreSearch.js +22 -0
  186. package/datastore/useDatastoreSearch.js.map +1 -0
  187. package/datastore/useDeleteDatastore.d.ts +53 -0
  188. package/datastore/useDeleteDatastore.d.ts.map +1 -0
  189. package/datastore/useDeleteDatastore.js +40 -0
  190. package/datastore/useDeleteDatastore.js.map +1 -0
  191. package/datastore/useDeleteRecord.d.ts +34 -0
  192. package/datastore/useDeleteRecord.d.ts.map +1 -0
  193. package/datastore/useDeleteRecord.js +43 -0
  194. package/datastore/useDeleteRecord.js.map +1 -0
  195. package/datastore/useInsertRecord.d.ts +50 -0
  196. package/datastore/useInsertRecord.d.ts.map +1 -0
  197. package/datastore/useInsertRecord.js +55 -0
  198. package/datastore/useInsertRecord.js.map +1 -0
  199. package/datastore/useRecordCollection.d.ts +104 -0
  200. package/datastore/useRecordCollection.d.ts.map +1 -0
  201. package/datastore/useRecordCollection.js +136 -0
  202. package/datastore/useRecordCollection.js.map +1 -0
  203. package/datastore/useRecordList.d.ts +66 -0
  204. package/datastore/useRecordList.d.ts.map +1 -0
  205. package/datastore/useRecordList.js +58 -0
  206. package/datastore/useRecordList.js.map +1 -0
  207. package/datastore/useUpdateRecord.d.ts +52 -0
  208. package/datastore/useUpdateRecord.d.ts.map +1 -0
  209. package/datastore/useUpdateRecord.js +55 -0
  210. package/datastore/useUpdateRecord.js.map +1 -0
  211. package/environment/EnvironmentListPanel.d.ts.map +1 -1
  212. package/environment/EnvironmentListPanel.js +12 -7
  213. package/environment/EnvironmentListPanel.js.map +1 -1
  214. package/execution/index.d.ts +1 -2
  215. package/execution/index.d.ts.map +1 -1
  216. package/execution/index.js +0 -1
  217. package/execution/index.js.map +1 -1
  218. package/execution/useLiveAgentExecution.d.ts +17 -1
  219. package/execution/useLiveAgentExecution.d.ts.map +1 -1
  220. package/execution/useLiveAgentExecution.js +19 -4
  221. package/execution/useLiveAgentExecution.js.map +1 -1
  222. package/iam-policy/index.d.ts +1 -1
  223. package/iam-policy/index.d.ts.map +1 -1
  224. package/iam-policy/index.js.map +1 -1
  225. package/iam-policy/useCheckPermission.d.ts +32 -11
  226. package/iam-policy/useCheckPermission.d.ts.map +1 -1
  227. package/iam-policy/useCheckPermission.js +24 -19
  228. package/iam-policy/useCheckPermission.js.map +1 -1
  229. package/index.d.ts +16 -10
  230. package/index.d.ts.map +1 -1
  231. package/index.js +16 -5
  232. package/index.js.map +1 -1
  233. package/internal/useInViewport.d.ts +24 -0
  234. package/internal/useInViewport.d.ts.map +1 -0
  235. package/internal/useInViewport.js +49 -0
  236. package/internal/useInViewport.js.map +1 -0
  237. package/library/VisibilitySelector.d.ts +22 -6
  238. package/library/VisibilitySelector.d.ts.map +1 -1
  239. package/library/VisibilitySelector.js +12 -4
  240. package/library/VisibilitySelector.js.map +1 -1
  241. package/library/index.d.ts +1 -8
  242. package/library/index.d.ts.map +1 -1
  243. package/library/index.js +0 -4
  244. package/library/index.js.map +1 -1
  245. package/library/useApplyResource.d.ts +12 -12
  246. package/library/useApplyResource.d.ts.map +1 -1
  247. package/library/useApplyResource.js +16 -25
  248. package/library/useApplyResource.js.map +1 -1
  249. package/library/useExportResource.d.ts +13 -9
  250. package/library/useExportResource.d.ts.map +1 -1
  251. package/library/useExportResource.js +18 -36
  252. package/library/useExportResource.js.map +1 -1
  253. package/manifest/ApplyManifestDialog.d.ts +48 -0
  254. package/manifest/ApplyManifestDialog.d.ts.map +1 -0
  255. package/manifest/ApplyManifestDialog.js +135 -0
  256. package/manifest/ApplyManifestDialog.js.map +1 -0
  257. package/manifest/EditResourceYamlDialog.d.ts +51 -0
  258. package/manifest/EditResourceYamlDialog.d.ts.map +1 -0
  259. package/manifest/EditResourceYamlDialog.js +104 -0
  260. package/manifest/EditResourceYamlDialog.js.map +1 -0
  261. package/manifest/RedactedSecretsNotice.d.ts +14 -0
  262. package/manifest/RedactedSecretsNotice.d.ts.map +1 -0
  263. package/manifest/RedactedSecretsNotice.js +14 -0
  264. package/manifest/RedactedSecretsNotice.js.map +1 -0
  265. package/manifest/YamlEditor.d.ts +44 -0
  266. package/manifest/YamlEditor.d.ts.map +1 -0
  267. package/manifest/YamlEditor.js +216 -0
  268. package/manifest/YamlEditor.js.map +1 -0
  269. package/manifest/index.d.ts +13 -0
  270. package/manifest/index.d.ts.map +1 -0
  271. package/manifest/index.js +13 -0
  272. package/manifest/index.js.map +1 -0
  273. package/manifest/useApplyManifest.d.ts +82 -0
  274. package/manifest/useApplyManifest.d.ts.map +1 -0
  275. package/manifest/useApplyManifest.js +180 -0
  276. package/manifest/useApplyManifest.js.map +1 -0
  277. package/manifest/useEditResourceYaml.d.ts +106 -0
  278. package/manifest/useEditResourceYaml.d.ts.map +1 -0
  279. package/manifest/useEditResourceYaml.js +168 -0
  280. package/manifest/useEditResourceYaml.js.map +1 -0
  281. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  282. package/mcp-server/McpServerDetailView.js +4 -3
  283. package/mcp-server/McpServerDetailView.js.map +1 -1
  284. package/mcp-server/steps/ReviewStep.d.ts.map +1 -1
  285. package/mcp-server/steps/ReviewStep.js +2 -3
  286. package/mcp-server/steps/ReviewStep.js.map +1 -1
  287. package/package.json +4 -4
  288. package/resource-creation/templates/workflow-templates.js +4 -4
  289. package/session/SessionViewer.js +8 -1
  290. package/session/SessionViewer.js.map +1 -1
  291. package/session/audience.d.ts +6 -1
  292. package/session/audience.d.ts.map +1 -1
  293. package/session/useEditSessionPrep.js +3 -3
  294. package/session/useEditSessionPrep.js.map +1 -1
  295. package/settings/index.d.ts +2 -1
  296. package/settings/index.d.ts.map +1 -1
  297. package/settings/index.js +2 -1
  298. package/settings/index.js.map +1 -1
  299. package/settings/settings-nav.d.ts +22 -0
  300. package/settings/settings-nav.d.ts.map +1 -1
  301. package/settings/settings-nav.js +32 -1
  302. package/settings/settings-nav.js.map +1 -1
  303. package/settings/useSettingsNavGroups.d.ts +29 -0
  304. package/settings/useSettingsNavGroups.d.ts.map +1 -0
  305. package/settings/useSettingsNavGroups.js +61 -0
  306. package/settings/useSettingsNavGroups.js.map +1 -0
  307. package/skill/SkillDetailView.d.ts.map +1 -1
  308. package/skill/SkillDetailView.js +4 -3
  309. package/skill/SkillDetailView.js.map +1 -1
  310. package/src/access/__tests__/useManageAccess.test.tsx +104 -0
  311. package/src/agent/AgentDetailView.tsx +9 -3
  312. package/src/agent/steps/ReviewStep.tsx +2 -3
  313. package/src/billing/BaselineEditor.tsx +619 -0
  314. package/src/billing/ModelCatalogPanel.tsx +283 -0
  315. package/src/billing/ModelGovernanceDetail.tsx +289 -0
  316. package/src/billing/OperatorAccessNotice.tsx +32 -0
  317. package/src/billing/PricingGovernanceConsole.tsx +465 -0
  318. package/src/billing/PricingGovernancePanel.tsx +166 -0
  319. package/src/billing/RetireConfirm.tsx +82 -0
  320. package/src/billing/__tests__/ModelCatalogPanel.test.tsx +253 -0
  321. package/src/billing/__tests__/PricingGovernanceConsole.test.tsx +410 -0
  322. package/src/billing/__tests__/useModelGovernanceView.test.tsx +308 -0
  323. package/src/billing/form-primitives.tsx +68 -0
  324. package/src/billing/governance-primitives.tsx +133 -0
  325. package/src/billing/index.ts +37 -0
  326. package/src/billing/pricing-format.ts +53 -0
  327. package/src/billing/useDecidePricingOverride.ts +78 -0
  328. package/src/billing/useModelGovernanceView.ts +290 -0
  329. package/src/billing/useModelPricingBaselines.ts +69 -0
  330. package/src/billing/usePricingGovernance.ts +57 -0
  331. package/src/billing/useRetireModelPricingBaseline.ts +65 -0
  332. package/src/billing/useUpsertModelPricingBaseline.ts +72 -0
  333. package/src/channel/AgentChannelsPanel.tsx +27 -1
  334. package/src/composer/SessionComposer.tsx +1 -1
  335. package/src/cursor-accounts/CursorAccountEditor.tsx +181 -0
  336. package/src/cursor-accounts/CursorAccountsAccessNotice.tsx +36 -0
  337. package/src/cursor-accounts/CursorAccountsConsole.tsx +810 -0
  338. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +384 -0
  339. package/src/cursor-accounts/cursor-account-format.ts +29 -0
  340. package/src/cursor-accounts/index.ts +29 -0
  341. package/src/cursor-accounts/useCursorAccountView.ts +49 -0
  342. package/src/cursor-accounts/useCursorAccounts.ts +49 -0
  343. package/src/cursor-accounts/useCursorMemberKeyActions.ts +106 -0
  344. package/src/cursor-accounts/useDeleteCursorAccount.ts +62 -0
  345. package/src/cursor-accounts/useSyncCursorAccount.ts +54 -0
  346. package/src/cursor-accounts/useUpsertCursorAccount.ts +57 -0
  347. package/src/datastore/CollectionRecordsBrowser.tsx +544 -0
  348. package/src/datastore/CollectionSchemaView.tsx +247 -0
  349. package/src/datastore/DatastoreDetailView.tsx +201 -0
  350. package/src/datastore/DatastoreSyncReport.tsx +105 -0
  351. package/src/datastore/DeleteDatastoreDialog.tsx +202 -0
  352. package/src/datastore/FieldValueControl.tsx +289 -0
  353. package/src/datastore/RecordFilterBuilder.tsx +411 -0
  354. package/src/datastore/RecordFormPanel.tsx +432 -0
  355. package/src/datastore/__tests__/CollectionRecordsBrowser.test.tsx +207 -0
  356. package/src/datastore/__tests__/DeleteDatastoreDialog.test.tsx +133 -0
  357. package/src/datastore/__tests__/FieldValueControl.test.tsx +160 -0
  358. package/src/datastore/__tests__/RecordFilterBuilder.test.tsx +141 -0
  359. package/src/datastore/__tests__/RecordFormPanel.test.tsx +227 -0
  360. package/src/datastore/__tests__/recordFilter.test.ts +156 -0
  361. package/src/datastore/__tests__/recordMutations.test.tsx +195 -0
  362. package/src/datastore/__tests__/recordValues.test.ts +359 -0
  363. package/src/datastore/__tests__/schemaAndSyncViews.test.tsx +142 -0
  364. package/src/datastore/__tests__/useDatastoreDescription.test.tsx +143 -0
  365. package/src/datastore/__tests__/useRecordCollection.test.tsx +250 -0
  366. package/src/datastore/__tests__/useRecordList.test.tsx +85 -0
  367. package/src/datastore/index.ts +111 -0
  368. package/src/datastore/recordFilter.ts +140 -0
  369. package/src/datastore/recordValues.ts +327 -0
  370. package/src/datastore/useDatastore.ts +67 -0
  371. package/src/datastore/useDatastoreCount.ts +67 -0
  372. package/src/datastore/useDatastoreDescription.ts +90 -0
  373. package/src/datastore/useDatastoreList.ts +79 -0
  374. package/src/datastore/useDatastoreSearch.ts +39 -0
  375. package/src/datastore/useDeleteDatastore.ts +87 -0
  376. package/src/datastore/useDeleteRecord.ts +77 -0
  377. package/src/datastore/useInsertRecord.ts +92 -0
  378. package/src/datastore/useRecordCollection.ts +256 -0
  379. package/src/datastore/useRecordList.ts +131 -0
  380. package/src/datastore/useUpdateRecord.ts +95 -0
  381. package/src/environment/EnvironmentListPanel.tsx +24 -0
  382. package/src/execution/__tests__/useArtifactInspection.test.tsx +12 -2
  383. package/src/execution/__tests__/useLiveAgentExecution.test.tsx +125 -0
  384. package/src/execution/index.ts +4 -7
  385. package/src/execution/useLiveAgentExecution.ts +41 -3
  386. package/src/iam-policy/__tests__/useCheckPermission.test.tsx +221 -0
  387. package/src/iam-policy/index.ts +1 -0
  388. package/src/iam-policy/useCheckPermission.ts +45 -19
  389. package/src/index.ts +167 -18
  390. package/src/internal/__tests__/useInViewport.test.tsx +115 -0
  391. package/src/internal/useInViewport.ts +63 -0
  392. package/src/library/VisibilitySelector.tsx +50 -9
  393. package/src/library/__tests__/VisibilitySelector.test.tsx +38 -0
  394. package/src/library/index.ts +4 -21
  395. package/src/library/useApplyResource.ts +27 -34
  396. package/src/library/useExportResource.ts +21 -40
  397. package/src/manifest/ApplyManifestDialog.tsx +315 -0
  398. package/src/manifest/EditResourceYamlDialog.tsx +265 -0
  399. package/src/manifest/RedactedSecretsNotice.tsx +30 -0
  400. package/src/manifest/YamlEditor.tsx +272 -0
  401. package/src/manifest/__tests__/EditResourceYamlDialog.test.tsx +118 -0
  402. package/src/manifest/__tests__/useApplyManifest.test.tsx +237 -0
  403. package/src/manifest/__tests__/useEditResourceYaml.test.tsx +252 -0
  404. package/src/manifest/index.ts +33 -0
  405. package/src/manifest/useApplyManifest.ts +270 -0
  406. package/src/manifest/useEditResourceYaml.ts +273 -0
  407. package/src/mcp-server/McpServerDetailView.tsx +7 -3
  408. package/src/mcp-server/steps/ReviewStep.tsx +2 -3
  409. package/src/resource-creation/templates/workflow-templates.ts +4 -4
  410. package/src/session/SessionViewer.tsx +7 -1
  411. package/src/session/__tests__/audienceWiring.test.tsx +31 -1
  412. package/src/session/audience.ts +6 -1
  413. package/src/session/useEditSessionPrep.ts +3 -3
  414. package/src/settings/__tests__/useSettingsNavGroups.test.tsx +138 -0
  415. package/src/settings/index.ts +5 -1
  416. package/src/settings/settings-nav.ts +43 -0
  417. package/src/settings/useSettingsNavGroups.ts +81 -0
  418. package/src/skill/SkillDetailView.tsx +7 -3
  419. package/src/workflow/WorkflowAgentCallTranscript.tsx +279 -0
  420. package/src/workflow/WorkflowDetailView.tsx +7 -3
  421. package/src/workflow/WorkflowExecutionViewer.tsx +20 -77
  422. package/src/workflow/WorkflowTaskApprovalSummary.tsx +45 -8
  423. package/src/workflow/WorkflowYamlEditor.tsx +6 -270
  424. package/src/workflow/__tests__/WorkflowAgentCallTranscript.liveregion.test.tsx +124 -0
  425. package/src/workflow/__tests__/{WorkflowAgentExecutionDocument.test.tsx → WorkflowAgentCallTranscript.test.tsx} +146 -121
  426. package/src/workflow/__tests__/WorkflowExecutionViewer.approvals.test.tsx +81 -220
  427. package/src/workflow/__tests__/WorkflowExecutionViewer.reconciliation.test.tsx +17 -16
  428. package/src/workflow/__tests__/WorkflowTaskApprovalSummary.test.tsx +52 -2
  429. package/src/workflow/__tests__/WorkflowTaskThread.test.tsx +168 -185
  430. package/src/workflow/__tests__/agent-call-live-experience.test.ts +4 -4
  431. package/src/workflow/__tests__/task-approval.test.ts +119 -0
  432. package/src/workflow/__tests__/task-presentation.test.ts +35 -1
  433. package/src/workflow/__tests__/useWorkflowExecutionPanel.test.ts +0 -57
  434. package/src/workflow/index.ts +6 -3
  435. package/src/workflow/task-detail/index.ts +3 -0
  436. package/src/workflow/task-detail/task-approval.ts +95 -1
  437. package/src/workflow/thread/WorkflowTaskThread.tsx +96 -252
  438. package/src/workflow/thread/task-presentation.ts +8 -2
  439. package/src/workflow/useWorkflowExecutionPanel.ts +0 -47
  440. package/styles.css +1 -1
  441. package/workflow/CanvasTransitionEdge.d.ts +1 -1
  442. package/workflow/WorkflowAgentCallTranscript.d.ts +87 -0
  443. package/workflow/WorkflowAgentCallTranscript.d.ts.map +1 -0
  444. package/workflow/WorkflowAgentCallTranscript.js +98 -0
  445. package/workflow/WorkflowAgentCallTranscript.js.map +1 -0
  446. package/workflow/WorkflowDetailView.d.ts.map +1 -1
  447. package/workflow/WorkflowDetailView.js +4 -3
  448. package/workflow/WorkflowDetailView.js.map +1 -1
  449. package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
  450. package/workflow/WorkflowExecutionViewer.js +23 -52
  451. package/workflow/WorkflowExecutionViewer.js.map +1 -1
  452. package/workflow/WorkflowTaskApprovalSummary.d.ts +1 -1
  453. package/workflow/WorkflowTaskApprovalSummary.d.ts.map +1 -1
  454. package/workflow/WorkflowTaskApprovalSummary.js +18 -1
  455. package/workflow/WorkflowTaskApprovalSummary.js.map +1 -1
  456. package/workflow/WorkflowYamlEditor.d.ts +2 -42
  457. package/workflow/WorkflowYamlEditor.d.ts.map +1 -1
  458. package/workflow/WorkflowYamlEditor.js +5 -214
  459. package/workflow/WorkflowYamlEditor.js.map +1 -1
  460. package/workflow/index.d.ts +2 -2
  461. package/workflow/index.d.ts.map +1 -1
  462. package/workflow/index.js +2 -2
  463. package/workflow/index.js.map +1 -1
  464. package/workflow/task-detail/index.d.ts +1 -1
  465. package/workflow/task-detail/index.d.ts.map +1 -1
  466. package/workflow/task-detail/index.js +1 -1
  467. package/workflow/task-detail/index.js.map +1 -1
  468. package/workflow/task-detail/task-approval.d.ts +44 -1
  469. package/workflow/task-detail/task-approval.d.ts.map +1 -1
  470. package/workflow/task-detail/task-approval.js +47 -0
  471. package/workflow/task-detail/task-approval.js.map +1 -1
  472. package/workflow/thread/WorkflowTaskThread.d.ts +17 -25
  473. package/workflow/thread/WorkflowTaskThread.d.ts.map +1 -1
  474. package/workflow/thread/WorkflowTaskThread.js +60 -105
  475. package/workflow/thread/WorkflowTaskThread.js.map +1 -1
  476. package/workflow/thread/task-presentation.d.ts.map +1 -1
  477. package/workflow/thread/task-presentation.js +7 -2
  478. package/workflow/thread/task-presentation.js.map +1 -1
  479. package/workflow/useWorkflowExecutionPanel.d.ts +0 -12
  480. package/workflow/useWorkflowExecutionPanel.d.ts.map +1 -1
  481. package/workflow/useWorkflowExecutionPanel.js +0 -12
  482. package/workflow/useWorkflowExecutionPanel.js.map +1 -1
  483. package/execution/agent-execution-document.d.ts +0 -31
  484. package/execution/agent-execution-document.d.ts.map +0 -1
  485. package/execution/agent-execution-document.js +0 -48
  486. package/execution/agent-execution-document.js.map +0 -1
  487. package/library/ImportResourceDialog.d.ts +0 -43
  488. package/library/ImportResourceDialog.d.ts.map +0 -1
  489. package/library/ImportResourceDialog.js +0 -90
  490. package/library/ImportResourceDialog.js.map +0 -1
  491. package/library/parse-resource-yaml.d.ts +0 -63
  492. package/library/parse-resource-yaml.d.ts.map +0 -1
  493. package/library/parse-resource-yaml.js +0 -407
  494. package/library/parse-resource-yaml.js.map +0 -1
  495. package/library/serialize-resource-yaml.d.ts +0 -103
  496. package/library/serialize-resource-yaml.d.ts.map +0 -1
  497. package/library/serialize-resource-yaml.js +0 -565
  498. package/library/serialize-resource-yaml.js.map +0 -1
  499. package/library/useImportResource.d.ts +0 -84
  500. package/library/useImportResource.d.ts.map +0 -1
  501. package/library/useImportResource.js +0 -188
  502. package/library/useImportResource.js.map +0 -1
  503. package/src/execution/__tests__/agent-execution-document.test.ts +0 -45
  504. package/src/execution/agent-execution-document.ts +0 -54
  505. package/src/library/ImportResourceDialog.tsx +0 -227
  506. package/src/library/parse-resource-yaml.ts +0 -630
  507. package/src/library/serialize-resource-yaml.ts +0 -756
  508. package/src/library/useImportResource.ts +0 -253
  509. package/src/workflow/WorkflowAgentExecutionDocument.tsx +0 -283
  510. package/workflow/WorkflowAgentExecutionDocument.d.ts +0 -79
  511. package/workflow/WorkflowAgentExecutionDocument.d.ts.map +0 -1
  512. package/workflow/WorkflowAgentExecutionDocument.js +0 -87
  513. package/workflow/WorkflowAgentExecutionDocument.js.map +0 -1
@@ -0,0 +1,384 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { cleanup, render, screen, waitFor } from "@testing-library/react";
3
+ import userEvent from "@testing-library/user-event";
4
+ import type { ReactNode } from "react";
5
+ import { create } from "@bufbuild/protobuf";
6
+ import { timestampFromDate } from "@bufbuild/protobuf/wkt";
7
+ import { StigmerError } from "@stigmer/sdk";
8
+ import {
9
+ CursorAccountSchema,
10
+ CursorMemberKeySchema,
11
+ CursorTeamMemberSchema,
12
+ CursorMemberSpendSchema,
13
+ CursorAccountSyncSnapshotSchema,
14
+ } from "@stigmer/protos/ai/stigmer/platform/cursoraccount/v1/cursor_account_pb";
15
+ import {
16
+ CursorAccountSummarySchema,
17
+ CursorAccountViewSchema,
18
+ CursorMemberKeyViewSchema,
19
+ CursorMemberKeyState,
20
+ } from "@stigmer/protos/ai/stigmer/platform/cursoraccount/v1/io_pb";
21
+ import { StigmerContext } from "../../context";
22
+ import { FetchCacheContext } from "../../internal/FetchCacheProvider";
23
+ import { CursorAccountsConsole } from "../CursorAccountsConsole";
24
+
25
+ interface MockCursorAccounts {
26
+ listAccounts: ReturnType<typeof vi.fn>;
27
+ getAccountView: ReturnType<typeof vi.fn>;
28
+ upsertAccount: ReturnType<typeof vi.fn>;
29
+ deleteAccount: ReturnType<typeof vi.fn>;
30
+ addMemberKey: ReturnType<typeof vi.fn>;
31
+ removeMemberKey: ReturnType<typeof vi.fn>;
32
+ setMemberKeyEnabled: ReturnType<typeof vi.fn>;
33
+ syncAccount: ReturnType<typeof vi.fn>;
34
+ }
35
+
36
+ function createMockStigmer(cursorAccounts: Partial<MockCursorAccounts> = {}) {
37
+ return {
38
+ cursorAccounts: {
39
+ listAccounts: vi.fn().mockResolvedValue({ accounts: [] }),
40
+ getAccountView: vi.fn(),
41
+ upsertAccount: vi.fn(),
42
+ deleteAccount: vi.fn(),
43
+ addMemberKey: vi.fn(),
44
+ removeMemberKey: vi.fn(),
45
+ setMemberKeyEnabled: vi.fn(),
46
+ syncAccount: vi.fn(),
47
+ ...cursorAccounts,
48
+ },
49
+ } as never;
50
+ }
51
+
52
+ function wrapper(client: unknown) {
53
+ return function Wrapper({ children }: { children: ReactNode }) {
54
+ return (
55
+ <FetchCacheContext.Provider value={null}>
56
+ <StigmerContext.Provider value={client as never}>
57
+ {children}
58
+ </StigmerContext.Provider>
59
+ </FetchCacheContext.Provider>
60
+ );
61
+ };
62
+ }
63
+
64
+ function scenarAccount(overrides: Record<string, unknown> = {}) {
65
+ return create(CursorAccountSchema, {
66
+ accountId: "acc-1",
67
+ displayName: "scenar team",
68
+ adminApiKey: "***REDACTED***",
69
+ enabled: true,
70
+ orgIds: ["org-a"],
71
+ memberKeys: [
72
+ create(CursorMemberKeySchema, {
73
+ keyId: "k-1",
74
+ apiKey: "***REDACTED***",
75
+ boundEmail: "zane@scenar.ai",
76
+ cursorKeyName: "stigmer-prod",
77
+ enabled: true,
78
+ }),
79
+ ],
80
+ ...overrides,
81
+ });
82
+ }
83
+
84
+ function scenarSummary() {
85
+ return create(CursorAccountSummarySchema, {
86
+ account: scenarAccount(),
87
+ enabledKeyCount: 1,
88
+ lastSyncedAt: timestampFromDate(new Date("2026-07-22T12:00:00Z")),
89
+ });
90
+ }
91
+
92
+ function scenarView() {
93
+ return create(CursorAccountViewSchema, {
94
+ account: scenarAccount(),
95
+ snapshot: create(CursorAccountSyncSnapshotSchema, {
96
+ accountId: "acc-1",
97
+ syncedAt: timestampFromDate(new Date("2026-07-22T12:00:00Z")),
98
+ members: [
99
+ create(CursorTeamMemberSchema, {
100
+ userId: "u1",
101
+ email: "zane@scenar.ai",
102
+ name: "Zane S",
103
+ role: "owner",
104
+ }),
105
+ create(CursorTeamMemberSchema, {
106
+ userId: "u2",
107
+ email: "uncovered@scenar.ai",
108
+ name: "Uncovered U",
109
+ role: "member",
110
+ }),
111
+ ],
112
+ spend: [
113
+ create(CursorMemberSpendSchema, {
114
+ userId: "u1",
115
+ email: "zane@scenar.ai",
116
+ includedSpendUsdMicros: 169342n,
117
+ }),
118
+ ],
119
+ }),
120
+ keyViews: [
121
+ create(CursorMemberKeyViewSchema, {
122
+ key: scenarAccount().memberKeys[0],
123
+ state: CursorMemberKeyState.member_key_active,
124
+ spend: create(CursorMemberSpendSchema, {
125
+ userId: "u1",
126
+ email: "zane@scenar.ai",
127
+ includedSpendUsdMicros: 169342n,
128
+ }),
129
+ }),
130
+ ],
131
+ membersWithoutKeys: [
132
+ create(CursorTeamMemberSchema, {
133
+ userId: "u2",
134
+ email: "uncovered@scenar.ai",
135
+ name: "Uncovered U",
136
+ role: "member",
137
+ }),
138
+ ],
139
+ });
140
+ }
141
+
142
+ afterEach(() => {
143
+ cleanup();
144
+ });
145
+
146
+ describe("CursorAccountsConsole", () => {
147
+ it("renders the empty state with onboarding guidance", async () => {
148
+ const client = createMockStigmer();
149
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
150
+
151
+ await waitFor(() =>
152
+ expect(screen.getByText(/No Cursor accounts yet/)).toBeTruthy(),
153
+ );
154
+ });
155
+
156
+ it("lists accounts with routability at a glance", async () => {
157
+ const notRoutable = create(CursorAccountSummarySchema, {
158
+ account: scenarAccount({
159
+ accountId: "acc-2",
160
+ displayName: "empty team",
161
+ memberKeys: [],
162
+ orgIds: [],
163
+ isPlatformDefault: true,
164
+ }),
165
+ enabledKeyCount: 0,
166
+ });
167
+ const client = createMockStigmer({
168
+ listAccounts: vi
169
+ .fn()
170
+ .mockResolvedValue({ accounts: [scenarSummary(), notRoutable] }),
171
+ });
172
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
173
+
174
+ await waitFor(() => expect(screen.getByText("scenar team")).toBeTruthy());
175
+ expect(screen.getByText("empty team")).toBeTruthy();
176
+ expect(screen.getByText("Not routable")).toBeTruthy();
177
+ expect(screen.getByText("platform default")).toBeTruthy();
178
+ });
179
+
180
+ it("shows the designed access notice on PERMISSION_DENIED", async () => {
181
+ const client = createMockStigmer({
182
+ listAccounts: vi
183
+ .fn()
184
+ .mockRejectedValue(
185
+ new StigmerError("permission-denied", "only platform operators", 7),
186
+ ),
187
+ });
188
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
189
+
190
+ await waitFor(() =>
191
+ expect(screen.getByText("Platform operator access required")).toBeTruthy(),
192
+ );
193
+ expect(screen.queryByText(/only platform operators/)).toBeNull();
194
+ });
195
+
196
+ it("opens the detail view with key coverage, spend, and gap list", async () => {
197
+ const client = createMockStigmer({
198
+ listAccounts: vi.fn().mockResolvedValue({ accounts: [scenarSummary()] }),
199
+ getAccountView: vi.fn().mockResolvedValue(scenarView()),
200
+ });
201
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
202
+
203
+ await waitFor(() => expect(screen.getByText("scenar team")).toBeTruthy());
204
+ await userEvent.click(screen.getByRole("button", { name: /scenar team/ }));
205
+
206
+ await waitFor(() => expect(screen.getByText(/zane@scenar\.ai/)).toBeTruthy());
207
+ // Spend joined to the key row: 169342 micro-USD = $0.17.
208
+ expect(screen.getByText(/\$0\.17 this cycle/)).toBeTruthy();
209
+ // Coverage gap: the active member with no key, by name and email.
210
+ expect(screen.getByText(/uncovered@scenar\.ai/)).toBeTruthy();
211
+ expect(screen.getByText("Active")).toBeTruthy();
212
+ });
213
+
214
+ it("adds a member key and refreshes both views", async () => {
215
+ const addMemberKey = vi.fn().mockResolvedValue(scenarAccount());
216
+ const client = createMockStigmer({
217
+ listAccounts: vi.fn().mockResolvedValue({ accounts: [scenarSummary()] }),
218
+ getAccountView: vi.fn().mockResolvedValue(scenarView()),
219
+ addMemberKey,
220
+ });
221
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
222
+
223
+ await waitFor(() => expect(screen.getByText("scenar team")).toBeTruthy());
224
+ await userEvent.click(screen.getByRole("button", { name: /scenar team/ }));
225
+ await waitFor(() =>
226
+ expect(screen.getByLabelText(/User-scoped API key/)).toBeTruthy(),
227
+ );
228
+
229
+ await userEvent.type(
230
+ screen.getByLabelText(/User-scoped API key/),
231
+ "key_user_plain",
232
+ );
233
+ await userEvent.click(screen.getByRole("button", { name: "Add key" }));
234
+
235
+ await waitFor(() =>
236
+ expect(addMemberKey).toHaveBeenCalledWith({
237
+ accountId: "acc-1",
238
+ apiKey: "key_user_plain",
239
+ label: undefined,
240
+ }),
241
+ );
242
+ });
243
+
244
+ it("surfaces Cursor's own explanation when a wrong key class is added", async () => {
245
+ const client = createMockStigmer({
246
+ listAccounts: vi.fn().mockResolvedValue({ accounts: [scenarSummary()] }),
247
+ getAccountView: vi.fn().mockResolvedValue(scenarView()),
248
+ addMemberKey: vi
249
+ .fn()
250
+ .mockRejectedValue(
251
+ new StigmerError(
252
+ "invalid-argument",
253
+ "Key rejected by Cursor — This is a team API key from the dashboard's Team API Keys tab",
254
+ 3,
255
+ ),
256
+ ),
257
+ });
258
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
259
+
260
+ await waitFor(() => expect(screen.getByText("scenar team")).toBeTruthy());
261
+ await userEvent.click(screen.getByRole("button", { name: /scenar team/ }));
262
+ await waitFor(() =>
263
+ expect(screen.getByLabelText(/User-scoped API key/)).toBeTruthy(),
264
+ );
265
+
266
+ await userEvent.type(screen.getByLabelText(/User-scoped API key/), "wrong-class");
267
+ await userEvent.click(screen.getByRole("button", { name: "Add key" }));
268
+
269
+ await waitFor(() =>
270
+ expect(screen.getByText(/Team API Keys tab/i)).toBeTruthy(),
271
+ );
272
+ });
273
+
274
+ it("creates an account through the editor", async () => {
275
+ const upsertAccount = vi.fn().mockResolvedValue(scenarAccount());
276
+ const client = createMockStigmer({
277
+ listAccounts: vi.fn().mockResolvedValue({ accounts: [] }),
278
+ upsertAccount,
279
+ });
280
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
281
+
282
+ await waitFor(() =>
283
+ expect(screen.getByRole("button", { name: "Add account" })).toBeTruthy(),
284
+ );
285
+ await userEvent.click(screen.getByRole("button", { name: "Add account" }));
286
+
287
+ await userEvent.type(screen.getByLabelText(/Display name/), "new team");
288
+ await userEvent.type(
289
+ screen.getByLabelText(/Team Admin API key/),
290
+ "key_admin_plain",
291
+ );
292
+ await userEvent.type(
293
+ screen.getByLabelText(/Assigned organization ids/),
294
+ "org-x org-y",
295
+ );
296
+ await userEvent.click(screen.getByRole("button", { name: "Create account" }));
297
+
298
+ await waitFor(() => expect(upsertAccount).toHaveBeenCalledTimes(1));
299
+ const submitted = upsertAccount.mock.calls[0][0].account;
300
+ expect(submitted.displayName).toBe("new team");
301
+ expect(submitted.adminApiKey).toBe("key_admin_plain");
302
+ expect(submitted.orgIds).toEqual(["org-x", "org-y"]);
303
+ expect(submitted.enabled).toBe(true);
304
+ });
305
+
306
+ it("bulk-imports keys one per line, keeping failed lines for retry", async () => {
307
+ const accountWithNewKey = scenarAccount({
308
+ memberKeys: [
309
+ scenarAccount().memberKeys[0],
310
+ create(CursorMemberKeySchema, {
311
+ keyId: "k-new",
312
+ apiKey: "***REDACTED***",
313
+ boundEmail: "morgan@scenar.ai",
314
+ enabled: true,
315
+ }),
316
+ ],
317
+ });
318
+ const addMemberKey = vi
319
+ .fn()
320
+ .mockResolvedValueOnce(accountWithNewKey)
321
+ .mockRejectedValueOnce(
322
+ new StigmerError("invalid-argument", "Key rejected by Cursor", 3),
323
+ );
324
+ const syncAccount = vi.fn().mockResolvedValue(scenarView());
325
+ const client = createMockStigmer({
326
+ listAccounts: vi.fn().mockResolvedValue({ accounts: [scenarSummary()] }),
327
+ getAccountView: vi.fn().mockResolvedValue(scenarView()),
328
+ addMemberKey,
329
+ syncAccount,
330
+ });
331
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
332
+
333
+ await waitFor(() => expect(screen.getByText("scenar team")).toBeTruthy());
334
+ await userEvent.click(screen.getByRole("button", { name: /scenar team/ }));
335
+ await waitFor(() =>
336
+ expect(screen.getByRole("button", { name: "Import keys" })).toBeTruthy(),
337
+ );
338
+
339
+ await userEvent.click(screen.getByRole("button", { name: "Import keys" }));
340
+ const textarea = screen.getByLabelText(/one user-scoped API key per line/);
341
+ await userEvent.type(textarea, "key_good_1234{Enter}key_bad_5678");
342
+ await userEvent.click(screen.getByRole("button", { name: "Import 2 keys" }));
343
+
344
+ await waitFor(() => expect(addMemberKey).toHaveBeenCalledTimes(2));
345
+ expect(addMemberKey).toHaveBeenNthCalledWith(1, {
346
+ accountId: "acc-1",
347
+ apiKey: "key_good_1234",
348
+ });
349
+ expect(addMemberKey).toHaveBeenNthCalledWith(2, {
350
+ accountId: "acc-1",
351
+ apiKey: "key_bad_5678",
352
+ });
353
+
354
+ // Per-line outcomes: success bound to its member, failure with the error.
355
+ await waitFor(() =>
356
+ expect(screen.getByText(/added — bound to morgan@scenar\.ai/)).toBeTruthy(),
357
+ );
358
+ expect(screen.getByText(/Key rejected by Cursor/)).toBeTruthy();
359
+ // Only the failed key remains in the box for retry.
360
+ expect((textarea as HTMLTextAreaElement).value).toBe("key_bad_5678");
361
+ // The roster sync runs automatically after the import.
362
+ await waitFor(() => expect(syncAccount).toHaveBeenCalledWith("acc-1"));
363
+ });
364
+
365
+ it("keeps the stored admin key when the editor's masked value is untouched", async () => {
366
+ const upsertAccount = vi.fn().mockResolvedValue(scenarAccount());
367
+ const client = createMockStigmer({
368
+ listAccounts: vi.fn().mockResolvedValue({ accounts: [scenarSummary()] }),
369
+ getAccountView: vi.fn().mockResolvedValue(scenarView()),
370
+ upsertAccount,
371
+ });
372
+ render(<CursorAccountsConsole />, { wrapper: wrapper(client) });
373
+
374
+ await waitFor(() => expect(screen.getByText("scenar team")).toBeTruthy());
375
+ await userEvent.click(screen.getByRole("button", { name: /scenar team/ }));
376
+ await waitFor(() => expect(screen.getByRole("button", { name: "Edit" })).toBeTruthy());
377
+ await userEvent.click(screen.getByRole("button", { name: "Edit" }));
378
+
379
+ await userEvent.click(screen.getByRole("button", { name: "Save changes" }));
380
+
381
+ await waitFor(() => expect(upsertAccount).toHaveBeenCalledTimes(1));
382
+ expect(upsertAccount.mock.calls[0][0].account.adminApiKey).toBe("***REDACTED***");
383
+ });
384
+ });
@@ -0,0 +1,29 @@
1
+ import type { Timestamp } from "@bufbuild/protobuf/wkt";
2
+
3
+ // BigInt literals (0n) require an ES2020 target, which not every consuming
4
+ // app's tsconfig guarantees — the constructor form is target-agnostic (the
5
+ // billing pricing-format precedent).
6
+ const ZERO = BigInt(0);
7
+
8
+ /**
9
+ * Micro-USD to a display dollar string (e.g. `169342n` → `"$0.17"`).
10
+ * Spend figures are Cursor-reported cycle totals — two decimals is the
11
+ * honest precision for a monitoring surface.
12
+ */
13
+ export function formatSpendMicros(micros: bigint): string {
14
+ const dollars = Number(micros) / 1_000_000;
15
+ return `$${dollars.toFixed(2)}`;
16
+ }
17
+
18
+ /** Proto Timestamp to a compact local date-time (e.g. "Jul 22, 14:05"). */
19
+ export function formatSyncTime(ts: Timestamp | undefined): string {
20
+ if (!ts || ts.seconds === ZERO) {
21
+ return "never";
22
+ }
23
+ return new Date(Number(ts.seconds) * 1000).toLocaleString(undefined, {
24
+ month: "short",
25
+ day: "numeric",
26
+ hour: "2-digit",
27
+ minute: "2-digit",
28
+ });
29
+ }
@@ -0,0 +1,29 @@
1
+ // Data hooks
2
+ export { useCursorAccounts } from "./useCursorAccounts.js";
3
+ export type { UseCursorAccountsReturn } from "./useCursorAccounts.js";
4
+ export { useCursorAccountView } from "./useCursorAccountView.js";
5
+ export type { UseCursorAccountViewReturn } from "./useCursorAccountView.js";
6
+
7
+ // Behavior hooks
8
+ export { useUpsertCursorAccount } from "./useUpsertCursorAccount.js";
9
+ export type { UseUpsertCursorAccountReturn } from "./useUpsertCursorAccount.js";
10
+ export { useDeleteCursorAccount } from "./useDeleteCursorAccount.js";
11
+ export type {
12
+ DeleteCursorAccountInput,
13
+ UseDeleteCursorAccountReturn,
14
+ } from "./useDeleteCursorAccount.js";
15
+ export { useCursorMemberKeyActions } from "./useCursorMemberKeyActions.js";
16
+ export type {
17
+ AddCursorMemberKeyInput,
18
+ RemoveCursorMemberKeyInput,
19
+ UseCursorMemberKeyActionsReturn,
20
+ } from "./useCursorMemberKeyActions.js";
21
+ export { useSyncCursorAccount } from "./useSyncCursorAccount.js";
22
+ export type { UseSyncCursorAccountReturn } from "./useSyncCursorAccount.js";
23
+
24
+ // Styled components
25
+ export { CursorAccountsConsole } from "./CursorAccountsConsole.js";
26
+ export type { CursorAccountsConsoleProps } from "./CursorAccountsConsole.js";
27
+ export { CursorAccountEditor } from "./CursorAccountEditor.js";
28
+ export type { CursorAccountEditorProps } from "./CursorAccountEditor.js";
29
+ export { CursorAccountsAccessNotice } from "./CursorAccountsAccessNotice.js";
@@ -0,0 +1,49 @@
1
+ "use client";
2
+
3
+ import type { CursorAccountView } from "@stigmer/protos/ai/stigmer/platform/cursoraccount/v1/io_pb";
4
+ import { useStigmer } from "../hooks.js";
5
+ import { useFetch } from "../internal/useFetch.js";
6
+
7
+ /** Return value of {@link useCursorAccountView}. */
8
+ export interface UseCursorAccountViewReturn {
9
+ /** The detail view, or `null` before the first successful fetch. */
10
+ readonly view: CursorAccountView | null;
11
+ /** `true` while the initial fetch is in flight. */
12
+ readonly isLoading: boolean;
13
+ /** `true` while a background refetch is in flight and stale data is shown. */
14
+ readonly isRefetching: boolean;
15
+ /** Error from the last failed request, or `null` when healthy. */
16
+ readonly error: Error | null;
17
+ /** Discard cached data and re-fetch from the server. */
18
+ readonly refetch: () => void;
19
+ }
20
+
21
+ /**
22
+ * Data hook for one Cursor account's detail view: the redacted account,
23
+ * the latest roster/spend snapshot, and the server-computed coverage
24
+ * join (per-key owner state and cycle spend, active members without
25
+ * keys).
26
+ *
27
+ * Pass `null` as `accountId` to skip fetching (e.g. while the console is
28
+ * on the list phase).
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * const { view, isLoading, refetch } = useCursorAccountView(accountId);
33
+ * ```
34
+ */
35
+ export function useCursorAccountView(
36
+ accountId: string | null,
37
+ ): UseCursorAccountViewReturn {
38
+ const stigmer = useStigmer();
39
+
40
+ const { data: view, isLoading, isRefetching, error, refetch } = useFetch(
41
+ accountId
42
+ ? () => stigmer.cursorAccounts.getAccountView(accountId)
43
+ : null,
44
+ [accountId, stigmer],
45
+ null as CursorAccountView | null,
46
+ );
47
+
48
+ return { view, isLoading, isRefetching, error, refetch };
49
+ }
@@ -0,0 +1,49 @@
1
+ "use client";
2
+
3
+ import type { CursorAccountsResponse } from "@stigmer/protos/ai/stigmer/platform/cursoraccount/v1/io_pb";
4
+ import { useStigmer } from "../hooks.js";
5
+ import { useFetch } from "../internal/useFetch.js";
6
+
7
+ /** Return value of {@link useCursorAccounts}. */
8
+ export interface UseCursorAccountsReturn {
9
+ /** The account summaries, or `null` before the first successful fetch. */
10
+ readonly accounts: CursorAccountsResponse | null;
11
+ /** `true` while the initial fetch is in flight. */
12
+ readonly isLoading: boolean;
13
+ /** `true` while a background refetch is in flight and stale data is shown. */
14
+ readonly isRefetching: boolean;
15
+ /** Error from the last failed request, or `null` when healthy. */
16
+ readonly error: Error | null;
17
+ /** Discard cached data and re-fetch from the server. */
18
+ readonly refetch: () => void;
19
+ }
20
+
21
+ /**
22
+ * Data hook that lists every managed Cursor account with its routing and
23
+ * sync summary (enabled member key count, last-synced timestamp). Key
24
+ * material is always redacted server-side.
25
+ *
26
+ * Platform-operator surface: the caller needs
27
+ * `can_manage_cursor_accounts` on `platform:stigmer`.
28
+ *
29
+ * Pass `enabled: false` to skip fetching (stable no-op).
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * const { accounts, isLoading, refetch } = useCursorAccounts();
34
+ * ```
35
+ */
36
+ export function useCursorAccounts(
37
+ options?: { readonly enabled?: boolean },
38
+ ): UseCursorAccountsReturn {
39
+ const stigmer = useStigmer();
40
+ const enabled = options?.enabled ?? true;
41
+
42
+ const { data: accounts, isLoading, isRefetching, error, refetch } = useFetch(
43
+ enabled ? () => stigmer.cursorAccounts.listAccounts() : null,
44
+ [enabled, stigmer],
45
+ null as CursorAccountsResponse | null,
46
+ );
47
+
48
+ return { accounts, isLoading, isRefetching, error, refetch };
49
+ }
@@ -0,0 +1,106 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import type { CursorAccount } from "@stigmer/protos/ai/stigmer/platform/cursoraccount/v1/cursor_account_pb";
5
+ import { useStigmer } from "../hooks.js";
6
+ import { toError } from "../internal/toError.js";
7
+
8
+ /** Input for adding one member key. */
9
+ export interface AddCursorMemberKeyInput {
10
+ readonly accountId: string;
11
+ /**
12
+ * Plaintext user-scoped Cursor API key. The server identifies it via
13
+ * Cursor's `/v1/me` and binds it to its owning team member; admin and
14
+ * service-account keys are rejected with Cursor's own explanation —
15
+ * surface the error verbatim.
16
+ */
17
+ readonly apiKey: string;
18
+ /** Optional operator label. */
19
+ readonly label?: string;
20
+ }
21
+
22
+ /** Input for removing one member key. */
23
+ export interface RemoveCursorMemberKeyInput {
24
+ readonly accountId: string;
25
+ readonly keyId: string;
26
+ /**
27
+ * Removal is refused while live sessions are pinned to this key.
28
+ * `force: true` overrides; prefer disabling (always safe).
29
+ */
30
+ readonly force?: boolean;
31
+ }
32
+
33
+ /** Return value of {@link useCursorMemberKeyActions}. */
34
+ export interface UseCursorMemberKeyActionsReturn {
35
+ /** Add one execution-capable member key. Returns the redacted account. */
36
+ readonly addKey: (input: AddCursorMemberKeyInput) => Promise<CursorAccount>;
37
+ /** Remove one member key (live-pin guarded). */
38
+ readonly removeKey: (input: RemoveCursorMemberKeyInput) => Promise<CursorAccount>;
39
+ /** Enable/disable one key for NEW-session selection (pins unaffected). */
40
+ readonly setKeyEnabled: (
41
+ accountId: string,
42
+ keyId: string,
43
+ enabled: boolean,
44
+ ) => Promise<CursorAccount>;
45
+ /** `true` while any key mutation is in flight. */
46
+ readonly isSubmitting: boolean;
47
+ /** Error from the last failed attempt, or `null` when healthy. */
48
+ readonly error: Error | null;
49
+ /** Reset `error` to `null`. */
50
+ readonly clearError: () => void;
51
+ }
52
+
53
+ /**
54
+ * Behavior hook bundling the member-key mutations of one Cursor account —
55
+ * add, remove, enable/disable. One hook because the console's key panel
56
+ * performs all three and they share submit/error surfaces.
57
+ *
58
+ * Rotation is deliberately remove + add (no in-place key swap), so the
59
+ * server-side `/v1/me` identity binding can never go stale.
60
+ */
61
+ export function useCursorMemberKeyActions(): UseCursorMemberKeyActionsReturn {
62
+ const stigmer = useStigmer();
63
+ const [isSubmitting, setIsSubmitting] = useState(false);
64
+ const [error, setError] = useState<Error | null>(null);
65
+
66
+ const run = useCallback(
67
+ async (op: () => Promise<CursorAccount>): Promise<CursorAccount> => {
68
+ setIsSubmitting(true);
69
+ setError(null);
70
+ try {
71
+ return await op();
72
+ } catch (e) {
73
+ const err = toError(e);
74
+ setError(err);
75
+ throw err;
76
+ } finally {
77
+ setIsSubmitting(false);
78
+ }
79
+ },
80
+ [],
81
+ );
82
+
83
+ const addKey = useCallback(
84
+ (input: AddCursorMemberKeyInput) =>
85
+ run(() => stigmer.cursorAccounts.addMemberKey(input)),
86
+ [run, stigmer.cursorAccounts],
87
+ );
88
+
89
+ const removeKey = useCallback(
90
+ (input: RemoveCursorMemberKeyInput) =>
91
+ run(() => stigmer.cursorAccounts.removeMemberKey(input)),
92
+ [run, stigmer.cursorAccounts],
93
+ );
94
+
95
+ const setKeyEnabled = useCallback(
96
+ (accountId: string, keyId: string, enabled: boolean) =>
97
+ run(() =>
98
+ stigmer.cursorAccounts.setMemberKeyEnabled({ accountId, keyId, enabled }),
99
+ ),
100
+ [run, stigmer.cursorAccounts],
101
+ );
102
+
103
+ const clearError = useCallback(() => setError(null), []);
104
+
105
+ return { addKey, removeKey, setKeyEnabled, isSubmitting, error, clearError };
106
+ }