@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,465 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage, isPermissionDenied } from "@stigmer/sdk";
6
+ import type { ModelPricingBaseline } from "@stigmer/protos/ai/stigmer/billing/v1/model_pricing_baseline_pb";
7
+ import { Button } from "../button/index.js";
8
+ import { Tabs } from "../tabs/Tabs.js";
9
+ import { BaselineEditor } from "./BaselineEditor.js";
10
+ import { RetireConfirm } from "./RetireConfirm.js";
11
+ import { ModelGovernanceDetail } from "./ModelGovernanceDetail.js";
12
+ import { OperatorAccessNotice } from "./OperatorAccessNotice.js";
13
+ import { GovernanceBadge, PendingOverrideCard, RateCell } from "./governance-primitives.js";
14
+ import { INPUT_CLASSES } from "./form-primitives.js";
15
+ import { ZERO } from "./pricing-format.js";
16
+ import { useDecidePricingOverride } from "./useDecidePricingOverride.js";
17
+ import { useRetireModelPricingBaseline } from "./useRetireModelPricingBaseline.js";
18
+ import { useUpsertModelPricingBaseline } from "./useUpsertModelPricingBaseline.js";
19
+ import {
20
+ useModelGovernanceView,
21
+ type ModelGovernanceRow,
22
+ } from "./useModelGovernanceView.js";
23
+
24
+ /**
25
+ * Tab ids of {@link PricingGovernanceConsole}, accepted by
26
+ * {@link PricingGovernanceConsoleProps.defaultTab}.
27
+ *
28
+ * These ids are deep-link targets: consumers wire them from their own
29
+ * routing (e.g. a `?tab=sign-offs` query param), and external surfaces
30
+ * compose URLs against them. Renaming a member is a breaking change to
31
+ * every link in the wild, not just to this component's props.
32
+ */
33
+ export type PricingGovernanceTab = "models" | "sign-offs";
34
+
35
+ /** Props for {@link PricingGovernanceConsole}. */
36
+ export interface PricingGovernanceConsoleProps {
37
+ /** Additional CSS class names. */
38
+ readonly className?: string;
39
+ /**
40
+ * The tab shown on first render. Defaults to `"models"`.
41
+ *
42
+ * Read once at mount, like a form field's `defaultValue` — changing
43
+ * it afterwards has no effect, and the user's tab choice stays local
44
+ * (the console never writes it back anywhere). Wire it from routing
45
+ * to make the tab URL-addressable:
46
+ *
47
+ * ```tsx
48
+ * // e.g. honoring a ?tab=sign-offs deep link
49
+ * const tab = new URLSearchParams(window.location.search).get("tab");
50
+ * <PricingGovernanceConsole
51
+ * defaultTab={tab === "sign-offs" ? "sign-offs" : undefined}
52
+ * />
53
+ * ```
54
+ */
55
+ readonly defaultTab?: PricingGovernanceTab;
56
+ }
57
+
58
+ const TABS: readonly { readonly id: PricingGovernanceTab; readonly label: string }[] = [
59
+ { id: "models", label: "Models" },
60
+ { id: "sign-offs", label: "Sign-Offs" },
61
+ ];
62
+
63
+ /**
64
+ * The platform-operator pricing console: a tabbed surface over the
65
+ * model registry baseline and the pricing feedback loop.
66
+ *
67
+ * - **Models** — every catalog entry joined with its governance state
68
+ * (effective vs baseline rates, ledger verification), searchable.
69
+ * Selecting a row opens a read-only detail record; editing (with an
70
+ * explicit old→new rate confirmation) and typed-confirmation
71
+ * retirement are deliberate steps from there.
72
+ * - **Sign-Offs** — pricing overrides proposed by reconciliation and
73
+ * awaiting a human decision, searchable; the tab badge shows the
74
+ * pending count from anywhere in the console.
75
+ *
76
+ * Requires `can_manage_model_pricing` on `platform:stigmer` — render it
77
+ * only in operator-scoped surfaces (non-operators see the designed
78
+ * access notice). Rates shown are raw provider prices (pre-markup),
79
+ * not customer prices.
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * <PricingGovernanceConsole />
84
+ * ```
85
+ */
86
+ export function PricingGovernanceConsole({
87
+ className,
88
+ defaultTab,
89
+ }: PricingGovernanceConsoleProps) {
90
+ const view = useModelGovernanceView();
91
+ // Seeded once from `defaultTab`, then owned locally (see the prop's
92
+ // JSDoc). The membership check is a public-API boundary guard: a JS
93
+ // consumer passing an out-of-union string must land on Models, not on
94
+ // a tabless surface.
95
+ const [activeTab, setActiveTab] = useState<PricingGovernanceTab>(() =>
96
+ defaultTab !== undefined && TABS.some((t) => t.id === defaultTab)
97
+ ? defaultTab
98
+ : "models",
99
+ );
100
+
101
+ const { decide, isSubmitting: isDeciding, error: decisionError } = useDecidePricingOverride();
102
+ const { upsert, isSubmitting: isUpserting, error: upsertError, clearError: clearUpsertError } =
103
+ useUpsertModelPricingBaseline();
104
+ const { retire, isSubmitting: isRetiring, error: retireError, clearError: clearRetireError } =
105
+ useRetireModelPricingBaseline();
106
+
107
+ const handleDecide = useCallback(
108
+ async (overrideId: string, approve: boolean) => {
109
+ try {
110
+ await decide({ overrideId, approve });
111
+ // A decision changes both the pending queue and (on approval)
112
+ // the effective rates — reload the whole view.
113
+ view.refetch();
114
+ } catch {
115
+ // Surfaced via decisionError below.
116
+ }
117
+ },
118
+ [decide, view.refetch],
119
+ );
120
+
121
+ const handleUpsert = useCallback(
122
+ async (baseline: ModelPricingBaseline, revisionNote: string) => {
123
+ await upsert({ baseline, revisionNote: revisionNote || undefined });
124
+ view.refetch();
125
+ // An edit lands back on the (refreshed) detail; a create lands on
126
+ // the list — the new row's key is derivable but focusing it before
127
+ // the refetch resolves would show stale data.
128
+ if (view.flow.phase === "detail") view.backToDetail();
129
+ else view.backToList();
130
+ },
131
+ [upsert, view.refetch, view.flow.phase, view.backToDetail, view.backToList],
132
+ );
133
+
134
+ const handleCancelEdit = useCallback(() => {
135
+ clearUpsertError();
136
+ if (view.flow.phase === "detail") view.backToDetail();
137
+ else view.backToList();
138
+ }, [clearUpsertError, view.flow.phase, view.backToDetail, view.backToList]);
139
+
140
+ const handleRetire = useCallback(
141
+ async (target: ModelPricingBaseline, revisionNote: string) => {
142
+ await retire({
143
+ modelId: target.modelId,
144
+ provider: target.provider,
145
+ harness: target.harness,
146
+ revisionNote: revisionNote || undefined,
147
+ });
148
+ view.refetch();
149
+ view.backToList();
150
+ },
151
+ [retire, view.refetch, view.backToList],
152
+ );
153
+
154
+ const handleCancelRetire = useCallback(() => {
155
+ clearRetireError();
156
+ view.backToDetail();
157
+ }, [clearRetireError, view.backToDetail]);
158
+
159
+ if (view.isLoading) {
160
+ return (
161
+ <div className={cn("space-y-2", className)} aria-busy="true">
162
+ <div className="h-4 w-40 animate-pulse rounded bg-muted-subtle" />
163
+ {Array.from({ length: 4 }, (_, i) => (
164
+ <div key={i} className="h-10 animate-pulse rounded-lg bg-muted-subtle" />
165
+ ))}
166
+ </div>
167
+ );
168
+ }
169
+
170
+ if (view.error) {
171
+ // A non-operator landing here is expected (the route is reachable by
172
+ // URL) — show the designed access notice, not a raw RPC error.
173
+ if (isPermissionDenied(view.error)) {
174
+ return <OperatorAccessNotice className={className} />;
175
+ }
176
+ return (
177
+ <p className={cn("text-destructive text-xs", className)} role="alert">
178
+ {getUserMessage(view.error)}
179
+ </p>
180
+ );
181
+ }
182
+
183
+ return (
184
+ <Tabs
185
+ className={className}
186
+ tabs={[
187
+ TABS[0],
188
+ { ...TABS[1], badge: view.pendingCount },
189
+ ]}
190
+ activeTab={activeTab}
191
+ onTabChange={(id) => setActiveTab(id as PricingGovernanceTab)}
192
+ aria-label="Pricing governance sections"
193
+ >
194
+ {activeTab === "models" ? (
195
+ <ModelsTab
196
+ view={view}
197
+ isUpserting={isUpserting}
198
+ upsertError={upsertError}
199
+ onUpsert={handleUpsert}
200
+ onCancelEdit={handleCancelEdit}
201
+ isRetiring={isRetiring}
202
+ retireError={retireError}
203
+ onRetire={handleRetire}
204
+ onCancelRetire={handleCancelRetire}
205
+ />
206
+ ) : (
207
+ <SignOffsTab
208
+ view={view}
209
+ isDeciding={isDeciding}
210
+ decisionError={decisionError}
211
+ onDecide={handleDecide}
212
+ />
213
+ )}
214
+ </Tabs>
215
+ );
216
+ }
217
+
218
+ // ---------------------------------------------------------------------------
219
+ // ModelsTab (internal)
220
+ // ---------------------------------------------------------------------------
221
+
222
+ function ModelsTab({
223
+ view,
224
+ isUpserting,
225
+ upsertError,
226
+ onUpsert,
227
+ onCancelEdit,
228
+ isRetiring,
229
+ retireError,
230
+ onRetire,
231
+ onCancelRetire,
232
+ }: {
233
+ readonly view: ReturnType<typeof useModelGovernanceView>;
234
+ readonly isUpserting: boolean;
235
+ readonly upsertError: Error | null;
236
+ readonly onUpsert: (baseline: ModelPricingBaseline, revisionNote: string) => Promise<void>;
237
+ readonly onCancelEdit: () => void;
238
+ readonly isRetiring: boolean;
239
+ readonly retireError: Error | null;
240
+ readonly onRetire: (target: ModelPricingBaseline, revisionNote: string) => Promise<void>;
241
+ readonly onCancelRetire: () => void;
242
+ }) {
243
+ const { flow, selected } = view;
244
+
245
+ if (flow.phase === "create") {
246
+ return (
247
+ <BaselineEditor
248
+ initial={null}
249
+ isSubmitting={isUpserting}
250
+ submitError={upsertError}
251
+ onSubmit={onUpsert}
252
+ onCancel={onCancelEdit}
253
+ />
254
+ );
255
+ }
256
+
257
+ // A stale detail key (e.g. the model was just retired) falls through
258
+ // to the list rather than rendering an empty record.
259
+ if (flow.phase === "detail" && selected) {
260
+ if (flow.mode === "edit") {
261
+ return (
262
+ <BaselineEditor
263
+ initial={selected.baseline}
264
+ isSubmitting={isUpserting}
265
+ submitError={upsertError}
266
+ onSubmit={onUpsert}
267
+ onCancel={onCancelEdit}
268
+ />
269
+ );
270
+ }
271
+ if (flow.mode === "retire") {
272
+ return (
273
+ <RetireConfirm
274
+ target={selected.baseline}
275
+ isSubmitting={isRetiring}
276
+ submitError={retireError}
277
+ onConfirm={onRetire}
278
+ onCancel={onCancelRetire}
279
+ />
280
+ );
281
+ }
282
+ return (
283
+ <ModelGovernanceDetail
284
+ row={selected}
285
+ onEdit={view.openEdit}
286
+ onRetire={view.openRetire}
287
+ onBack={view.backToList}
288
+ />
289
+ );
290
+ }
291
+
292
+ return (
293
+ <div className="space-y-3">
294
+ <div className="flex items-center justify-between gap-3">
295
+ <input
296
+ type="search"
297
+ className={cn(INPUT_CLASSES, "max-w-xs")}
298
+ value={view.modelQuery}
299
+ onChange={(e) => view.setModelQuery(e.target.value)}
300
+ placeholder="Search models…"
301
+ aria-label="Search models"
302
+ />
303
+ <Button size="sm" onClick={view.openCreate}>
304
+ Add model
305
+ </Button>
306
+ </div>
307
+
308
+ <div className="rounded-lg border border-border bg-card">
309
+ {/* Presentational column guide — each row is a self-describing
310
+ button (its full text content is its accessible name), so
311
+ the header is a visual aid, not an ARIA table header. */}
312
+ <div
313
+ aria-hidden="true"
314
+ className="grid grid-cols-[2fr_1fr_1fr_1fr_0.7fr_1fr] gap-2 border-b border-border px-3 py-2 text-[11px] font-medium text-muted-foreground"
315
+ >
316
+ <span>Model</span>
317
+ <span>Harness</span>
318
+ <span className="text-right">Input</span>
319
+ <span className="text-right">Output</span>
320
+ <span className="text-right">Variants</span>
321
+ <span className="text-right">Governance</span>
322
+ </div>
323
+ {view.models.length === 0 ? (
324
+ <p className="px-3 py-2 text-xs text-muted-foreground">
325
+ {view.modelQuery.trim() !== ""
326
+ ? `No models match "${view.modelQuery.trim()}".`
327
+ : "The catalog is empty — has the baseline seed migration run?"}
328
+ </p>
329
+ ) : (
330
+ <ul role="list" aria-label="Models" className="m-0 list-none p-0">
331
+ {view.models.map((row) => (
332
+ <ModelRow key={row.key} row={row} onOpen={() => view.openDetail(row.key)} />
333
+ ))}
334
+ </ul>
335
+ )}
336
+ </div>
337
+ </div>
338
+ );
339
+ }
340
+
341
+ /**
342
+ * One model row: a real button (keyboard + AT support for "open the
343
+ * record" for free) laid out on the shared column grid. Its full text
344
+ * content is its accessible name, so AT users hear the same facts the
345
+ * columns show.
346
+ */
347
+ function ModelRow({
348
+ row,
349
+ onOpen,
350
+ }: {
351
+ readonly row: ModelGovernanceRow;
352
+ readonly onOpen: () => void;
353
+ }) {
354
+ const { baseline, governance } = row;
355
+ const variantCount = Object.keys(baseline.pricingVariants).length;
356
+ const hasOverrides = (governance?.activeOverrides.length ?? 0) > 0;
357
+
358
+ return (
359
+ <li className="border-b border-border last:border-b-0">
360
+ <button
361
+ type="button"
362
+ onClick={onOpen}
363
+ className={cn(
364
+ "grid w-full grid-cols-[2fr_1fr_1fr_1fr_0.7fr_1fr] items-center gap-2 px-3 py-2 text-left text-xs",
365
+ "transition-colors hover:bg-accent",
366
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
367
+ )}
368
+ >
369
+ <span className="min-w-0">
370
+ <span className="block truncate font-medium text-foreground" title={baseline.modelId}>
371
+ {baseline.displayName || baseline.modelId}
372
+ </span>
373
+ <span className="block truncate text-[11px] text-muted-foreground">
374
+ {baseline.modelId}
375
+ {baseline.featured ? " · featured" : ""}
376
+ </span>
377
+ </span>
378
+ <span className="text-muted-foreground">{baseline.harness}</span>
379
+ <RateCell
380
+ baseline={baseline.pricing?.inputPriceMicrosPerMillion ?? ZERO}
381
+ effective={
382
+ governance?.effectiveInputMicrosPerMillion ??
383
+ baseline.pricing?.inputPriceMicrosPerMillion ??
384
+ ZERO
385
+ }
386
+ />
387
+ <RateCell
388
+ baseline={baseline.pricing?.outputPriceMicrosPerMillion ?? ZERO}
389
+ effective={
390
+ governance?.effectiveOutputMicrosPerMillion ??
391
+ baseline.pricing?.outputPriceMicrosPerMillion ??
392
+ ZERO
393
+ }
394
+ />
395
+ <span className="text-right text-muted-foreground">
396
+ {variantCount > 0 ? variantCount : "—"}
397
+ </span>
398
+ <span className="text-right">
399
+ {governance ? (
400
+ <GovernanceBadge
401
+ ledgerReconcilable={governance.ledgerReconcilable}
402
+ hasOverrides={hasOverrides}
403
+ />
404
+ ) : (
405
+ <span className="text-[10px] text-muted-foreground">—</span>
406
+ )}
407
+ </span>
408
+ </button>
409
+ </li>
410
+ );
411
+ }
412
+
413
+ // ---------------------------------------------------------------------------
414
+ // SignOffsTab (internal)
415
+ // ---------------------------------------------------------------------------
416
+
417
+ function SignOffsTab({
418
+ view,
419
+ isDeciding,
420
+ decisionError,
421
+ onDecide,
422
+ }: {
423
+ readonly view: ReturnType<typeof useModelGovernanceView>;
424
+ readonly isDeciding: boolean;
425
+ readonly decisionError: Error | null;
426
+ readonly onDecide: (overrideId: string, approve: boolean) => void;
427
+ }) {
428
+ return (
429
+ <div className="space-y-3">
430
+ <input
431
+ type="search"
432
+ className={cn(INPUT_CLASSES, "max-w-xs")}
433
+ value={view.signOffQuery}
434
+ onChange={(e) => view.setSignOffQuery(e.target.value)}
435
+ placeholder="Search sign-offs…"
436
+ aria-label="Search sign-offs"
437
+ />
438
+
439
+ {decisionError && (
440
+ <p className="text-destructive text-xs" role="alert">
441
+ {getUserMessage(decisionError)}
442
+ </p>
443
+ )}
444
+
445
+ {view.pendingOverrides.length === 0 ? (
446
+ <p className="text-xs text-muted-foreground">
447
+ {view.signOffQuery.trim() !== ""
448
+ ? `No pending sign-offs match "${view.signOffQuery.trim()}".`
449
+ : "No pricing overrides awaiting a decision."}
450
+ </p>
451
+ ) : (
452
+ <div className="space-y-2">
453
+ {view.pendingOverrides.map((override) => (
454
+ <PendingOverrideCard
455
+ key={override.overrideId}
456
+ override={override}
457
+ isSubmitting={isDeciding}
458
+ onDecide={onDecide}
459
+ />
460
+ ))}
461
+ </div>
462
+ )}
463
+ </div>
464
+ );
465
+ }
@@ -0,0 +1,166 @@
1
+ "use client";
2
+
3
+ import { cn } from "@stigmer/theme";
4
+ import { getUserMessage, isPermissionDenied } from "@stigmer/sdk";
5
+ import type {
6
+ ModelPricingGovernanceEntry,
7
+ } from "@stigmer/protos/ai/stigmer/billing/v1/io_pb";
8
+ import { OperatorAccessNotice } from "./OperatorAccessNotice.js";
9
+ import { GovernanceBadge, PendingOverrideCard, RateCell } from "./governance-primitives.js";
10
+ import { usePricingGovernance } from "./usePricingGovernance.js";
11
+ import { useDecidePricingOverride } from "./useDecidePricingOverride.js";
12
+
13
+ /** Props for {@link PricingGovernancePanel}. */
14
+ export interface PricingGovernancePanelProps {
15
+ /** Additional CSS class names. */
16
+ readonly className?: string;
17
+ }
18
+
19
+ /**
20
+ * Platform-operator panel for the pricing feedback loop: pending
21
+ * override sign-offs (approve/reject) and the effective-vs-baseline
22
+ * pricing state of every model.
23
+ *
24
+ * Prefer {@link PricingGovernanceConsole} for new surfaces — it
25
+ * composes this panel's content with the model catalog into one tabbed
26
+ * console. This standalone panel remains for consumers embedding just
27
+ * the governance view.
28
+ *
29
+ * Requires `can_manage_model_pricing` on `platform:stigmer` — render it
30
+ * only in operator-scoped surfaces. Rates shown are raw provider prices
31
+ * (pre-markup), not customer prices.
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * <PricingGovernancePanel />
36
+ * ```
37
+ */
38
+ export function PricingGovernancePanel({ className }: PricingGovernancePanelProps) {
39
+ const { governance, isLoading, error, refetch } = usePricingGovernance();
40
+ const { decide, isSubmitting, error: decisionError } = useDecidePricingOverride();
41
+
42
+ if (isLoading) {
43
+ return (
44
+ <div className={cn("space-y-2", className)} aria-busy="true">
45
+ <div className="h-4 w-40 animate-pulse rounded bg-muted-subtle" />
46
+ {Array.from({ length: 4 }, (_, i) => (
47
+ <div key={i} className="h-10 animate-pulse rounded-lg bg-muted-subtle" />
48
+ ))}
49
+ </div>
50
+ );
51
+ }
52
+
53
+ if (error) {
54
+ // A non-operator landing here is expected (the route is reachable by
55
+ // URL) — show the designed access notice, not a raw RPC error.
56
+ if (isPermissionDenied(error)) {
57
+ return <OperatorAccessNotice className={className} />;
58
+ }
59
+ return (
60
+ <p className={cn("text-destructive text-xs", className)} role="alert">
61
+ {getUserMessage(error)}
62
+ </p>
63
+ );
64
+ }
65
+
66
+ if (!governance) return null;
67
+
68
+ const onDecide = async (overrideId: string, approve: boolean) => {
69
+ try {
70
+ await decide({ overrideId, approve });
71
+ // A decision changes both the pending queue and (on approval) the
72
+ // effective rates — reload the whole view.
73
+ refetch();
74
+ } catch {
75
+ // Surfaced via decisionError below.
76
+ }
77
+ };
78
+
79
+ return (
80
+ <div className={cn("space-y-6", className)}>
81
+ <section aria-label="Pending pricing override proposals">
82
+ <h3 className="mb-2 text-xs font-semibold text-foreground">
83
+ Pending Sign-Offs
84
+ </h3>
85
+ {decisionError && (
86
+ <p className="mb-2 text-destructive text-xs" role="alert">
87
+ {getUserMessage(decisionError)}
88
+ </p>
89
+ )}
90
+ {governance.pendingOverrides.length === 0 ? (
91
+ <p className="text-xs text-muted-foreground">
92
+ No pricing overrides awaiting a decision.
93
+ </p>
94
+ ) : (
95
+ <div className="space-y-2">
96
+ {governance.pendingOverrides.map((override) => (
97
+ <PendingOverrideCard
98
+ key={override.overrideId}
99
+ override={override}
100
+ isSubmitting={isSubmitting}
101
+ onDecide={onDecide}
102
+ />
103
+ ))}
104
+ </div>
105
+ )}
106
+ </section>
107
+
108
+ <section aria-label="Model pricing state">
109
+ <h3 className="mb-2 text-xs font-semibold text-foreground">
110
+ Model Pricing
111
+ </h3>
112
+ <div className="rounded-lg border border-border bg-card" role="table"
113
+ aria-label="Model pricing governance">
114
+ <div role="row"
115
+ className="grid grid-cols-[2fr_1fr_1fr_1fr_1fr] gap-2 border-b border-border px-3 py-2 text-[11px] font-medium text-muted-foreground">
116
+ <span role="columnheader">Model</span>
117
+ <span role="columnheader">Harness</span>
118
+ <span role="columnheader" className="text-right">Input</span>
119
+ <span role="columnheader" className="text-right">Output</span>
120
+ <span role="columnheader" className="text-right">Governance</span>
121
+ </div>
122
+ {governance.entries.map((entry) => (
123
+ <GovernanceRow
124
+ key={`${entry.modelId}-${entry.harness}-${entry.variant}`}
125
+ entry={entry}
126
+ />
127
+ ))}
128
+ </div>
129
+ </section>
130
+ </div>
131
+ );
132
+ }
133
+
134
+ // ---------------------------------------------------------------------------
135
+ // GovernanceRow (internal)
136
+ // ---------------------------------------------------------------------------
137
+
138
+ function GovernanceRow({ entry }: { readonly entry: ModelPricingGovernanceEntry }) {
139
+ const hasOverrides = entry.activeOverrides.length > 0;
140
+ return (
141
+ <div role="row"
142
+ className="grid grid-cols-[2fr_1fr_1fr_1fr_1fr] items-center gap-2 border-b border-border px-3 py-2 text-xs last:border-b-0">
143
+ <span role="cell" className="truncate font-medium text-foreground"
144
+ title={entry.modelId}>
145
+ {entry.displayName || entry.modelId}
146
+ </span>
147
+ <span role="cell" className="text-muted-foreground">{entry.harness}</span>
148
+ <RateCell
149
+ role="cell"
150
+ baseline={entry.baselineInputMicrosPerMillion}
151
+ effective={entry.effectiveInputMicrosPerMillion}
152
+ />
153
+ <RateCell
154
+ role="cell"
155
+ baseline={entry.baselineOutputMicrosPerMillion}
156
+ effective={entry.effectiveOutputMicrosPerMillion}
157
+ />
158
+ <span role="cell" className="text-right">
159
+ <GovernanceBadge
160
+ ledgerReconcilable={entry.ledgerReconcilable}
161
+ hasOverrides={hasOverrides}
162
+ />
163
+ </span>
164
+ </div>
165
+ );
166
+ }