@stigmer/react 3.2.3 → 3.4.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 (460) hide show
  1. package/agent/steps/ReviewStep.d.ts.map +1 -1
  2. package/agent/steps/ReviewStep.js +2 -3
  3. package/agent/steps/ReviewStep.js.map +1 -1
  4. package/billing/index.d.ts.map +1 -1
  5. package/billing/index.js +4 -0
  6. package/billing/index.js.map +1 -1
  7. package/channel/AgentChannelsPanel.d.ts.map +1 -1
  8. package/channel/AgentChannelsPanel.js +11 -5
  9. package/channel/AgentChannelsPanel.js.map +1 -1
  10. package/composer/SessionComposer.d.ts +1 -1
  11. package/cursor-accounts/CursorAccountEditor.d.ts +34 -0
  12. package/cursor-accounts/CursorAccountEditor.d.ts.map +1 -0
  13. package/cursor-accounts/CursorAccountEditor.js +67 -0
  14. package/cursor-accounts/CursorAccountEditor.js.map +1 -0
  15. package/cursor-accounts/CursorAccountsAccessNotice.d.ts +11 -0
  16. package/cursor-accounts/CursorAccountsAccessNotice.d.ts.map +1 -0
  17. package/cursor-accounts/CursorAccountsAccessNotice.js +14 -0
  18. package/cursor-accounts/CursorAccountsAccessNotice.js.map +1 -0
  19. package/cursor-accounts/CursorAccountsConsole.d.ts +32 -0
  20. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -0
  21. package/cursor-accounts/CursorAccountsConsole.js +169 -0
  22. package/cursor-accounts/CursorAccountsConsole.js.map +1 -0
  23. package/cursor-accounts/MemberCoverageTable.d.ts +29 -0
  24. package/cursor-accounts/MemberCoverageTable.d.ts.map +1 -0
  25. package/cursor-accounts/MemberCoverageTable.js +150 -0
  26. package/cursor-accounts/MemberCoverageTable.js.map +1 -0
  27. package/cursor-accounts/MemberKeysPanel.d.ts +25 -0
  28. package/cursor-accounts/MemberKeysPanel.d.ts.map +1 -0
  29. package/cursor-accounts/MemberKeysPanel.js +115 -0
  30. package/cursor-accounts/MemberKeysPanel.js.map +1 -0
  31. package/cursor-accounts/badges.d.ts +9 -0
  32. package/cursor-accounts/badges.d.ts.map +1 -0
  33. package/cursor-accounts/badges.js +10 -0
  34. package/cursor-accounts/badges.js.map +1 -0
  35. package/cursor-accounts/cursor-account-coverage.d.ts +41 -0
  36. package/cursor-accounts/cursor-account-coverage.d.ts.map +1 -0
  37. package/cursor-accounts/cursor-account-coverage.js +26 -0
  38. package/cursor-accounts/cursor-account-coverage.js.map +1 -0
  39. package/cursor-accounts/cursor-account-format.d.ts +23 -0
  40. package/cursor-accounts/cursor-account-format.d.ts.map +1 -0
  41. package/cursor-accounts/cursor-account-format.js +41 -0
  42. package/cursor-accounts/cursor-account-format.js.map +1 -0
  43. package/cursor-accounts/index.d.ts +18 -0
  44. package/cursor-accounts/index.d.ts.map +1 -0
  45. package/cursor-accounts/index.js +13 -0
  46. package/cursor-accounts/index.js.map +1 -0
  47. package/cursor-accounts/useCursorAccountView.d.ts +30 -0
  48. package/cursor-accounts/useCursorAccountView.d.ts.map +1 -0
  49. package/cursor-accounts/useCursorAccountView.js +25 -0
  50. package/cursor-accounts/useCursorAccountView.js.map +1 -0
  51. package/cursor-accounts/useCursorAccounts.d.ts +33 -0
  52. package/cursor-accounts/useCursorAccounts.d.ts.map +1 -0
  53. package/cursor-accounts/useCursorAccounts.js +25 -0
  54. package/cursor-accounts/useCursorAccounts.js.map +1 -0
  55. package/cursor-accounts/useCursorMemberKeyActions.d.ts +49 -0
  56. package/cursor-accounts/useCursorMemberKeyActions.d.ts.map +1 -0
  57. package/cursor-accounts/useCursorMemberKeyActions.js +38 -0
  58. package/cursor-accounts/useCursorMemberKeyActions.js.map +1 -0
  59. package/cursor-accounts/useDeleteCursorAccount.d.ts +30 -0
  60. package/cursor-accounts/useDeleteCursorAccount.d.ts.map +1 -0
  61. package/cursor-accounts/useDeleteCursorAccount.js +32 -0
  62. package/cursor-accounts/useDeleteCursorAccount.js.map +1 -0
  63. package/cursor-accounts/useSyncCursorAccount.d.ts +23 -0
  64. package/cursor-accounts/useSyncCursorAccount.d.ts.map +1 -0
  65. package/cursor-accounts/useSyncCursorAccount.js +31 -0
  66. package/cursor-accounts/useSyncCursorAccount.js.map +1 -0
  67. package/cursor-accounts/useUpsertCursorAccount.d.ts +26 -0
  68. package/cursor-accounts/useUpsertCursorAccount.d.ts.map +1 -0
  69. package/cursor-accounts/useUpsertCursorAccount.js +34 -0
  70. package/cursor-accounts/useUpsertCursorAccount.js.map +1 -0
  71. package/datastore/CollectionRecordsBrowser.d.ts +34 -0
  72. package/datastore/CollectionRecordsBrowser.d.ts.map +1 -0
  73. package/datastore/CollectionRecordsBrowser.js +223 -0
  74. package/datastore/CollectionRecordsBrowser.js.map +1 -0
  75. package/datastore/CollectionSchemaView.d.ts +29 -0
  76. package/datastore/CollectionSchemaView.d.ts.map +1 -0
  77. package/datastore/CollectionSchemaView.js +93 -0
  78. package/datastore/CollectionSchemaView.js.map +1 -0
  79. package/datastore/DatastoreDetailView.d.ts +44 -0
  80. package/datastore/DatastoreDetailView.d.ts.map +1 -0
  81. package/datastore/DatastoreDetailView.js +76 -0
  82. package/datastore/DatastoreDetailView.js.map +1 -0
  83. package/datastore/DatastoreSyncReport.d.ts +19 -0
  84. package/datastore/DatastoreSyncReport.d.ts.map +1 -0
  85. package/datastore/DatastoreSyncReport.js +45 -0
  86. package/datastore/DatastoreSyncReport.js.map +1 -0
  87. package/datastore/DeleteDatastoreDialog.d.ts +35 -0
  88. package/datastore/DeleteDatastoreDialog.d.ts.map +1 -0
  89. package/datastore/DeleteDatastoreDialog.js +90 -0
  90. package/datastore/DeleteDatastoreDialog.js.map +1 -0
  91. package/datastore/FieldValueControl.d.ts +55 -0
  92. package/datastore/FieldValueControl.d.ts.map +1 -0
  93. package/datastore/FieldValueControl.js +138 -0
  94. package/datastore/FieldValueControl.js.map +1 -0
  95. package/datastore/RecordFilterBuilder.d.ts +37 -0
  96. package/datastore/RecordFilterBuilder.d.ts.map +1 -0
  97. package/datastore/RecordFilterBuilder.js +122 -0
  98. package/datastore/RecordFilterBuilder.js.map +1 -0
  99. package/datastore/RecordFormPanel.d.ts +45 -0
  100. package/datastore/RecordFormPanel.d.ts.map +1 -0
  101. package/datastore/RecordFormPanel.js +215 -0
  102. package/datastore/RecordFormPanel.js.map +1 -0
  103. package/datastore/index.d.ts +43 -0
  104. package/datastore/index.d.ts.map +1 -0
  105. package/datastore/index.js +22 -0
  106. package/datastore/index.js.map +1 -0
  107. package/datastore/recordFilter.d.ts +62 -0
  108. package/datastore/recordFilter.d.ts.map +1 -0
  109. package/datastore/recordFilter.js +104 -0
  110. package/datastore/recordFilter.js.map +1 -0
  111. package/datastore/recordValues.d.ts +85 -0
  112. package/datastore/recordValues.d.ts.map +1 -0
  113. package/datastore/recordValues.js +282 -0
  114. package/datastore/recordValues.js.map +1 -0
  115. package/datastore/useDatastore.d.ts +39 -0
  116. package/datastore/useDatastore.d.ts.map +1 -0
  117. package/datastore/useDatastore.js +44 -0
  118. package/datastore/useDatastore.js.map +1 -0
  119. package/datastore/useDatastoreCount.d.ts +48 -0
  120. package/datastore/useDatastoreCount.d.ts.map +1 -0
  121. package/datastore/useDatastoreCount.js +27 -0
  122. package/datastore/useDatastoreCount.js.map +1 -0
  123. package/datastore/useDatastoreDescription.d.ts +54 -0
  124. package/datastore/useDatastoreDescription.d.ts.map +1 -0
  125. package/datastore/useDatastoreDescription.js +50 -0
  126. package/datastore/useDatastoreDescription.js.map +1 -0
  127. package/datastore/useDatastoreList.d.ts +57 -0
  128. package/datastore/useDatastoreList.d.ts.map +1 -0
  129. package/datastore/useDatastoreList.js +29 -0
  130. package/datastore/useDatastoreList.js.map +1 -0
  131. package/datastore/useDatastoreSearch.d.ts +19 -0
  132. package/datastore/useDatastoreSearch.d.ts.map +1 -0
  133. package/datastore/useDatastoreSearch.js +22 -0
  134. package/datastore/useDatastoreSearch.js.map +1 -0
  135. package/datastore/useDeleteDatastore.d.ts +53 -0
  136. package/datastore/useDeleteDatastore.d.ts.map +1 -0
  137. package/datastore/useDeleteDatastore.js +40 -0
  138. package/datastore/useDeleteDatastore.js.map +1 -0
  139. package/datastore/useDeleteRecord.d.ts +34 -0
  140. package/datastore/useDeleteRecord.d.ts.map +1 -0
  141. package/datastore/useDeleteRecord.js +43 -0
  142. package/datastore/useDeleteRecord.js.map +1 -0
  143. package/datastore/useInsertRecord.d.ts +50 -0
  144. package/datastore/useInsertRecord.d.ts.map +1 -0
  145. package/datastore/useInsertRecord.js +55 -0
  146. package/datastore/useInsertRecord.js.map +1 -0
  147. package/datastore/useRecordCollection.d.ts +104 -0
  148. package/datastore/useRecordCollection.d.ts.map +1 -0
  149. package/datastore/useRecordCollection.js +136 -0
  150. package/datastore/useRecordCollection.js.map +1 -0
  151. package/datastore/useRecordList.d.ts +66 -0
  152. package/datastore/useRecordList.d.ts.map +1 -0
  153. package/datastore/useRecordList.js +58 -0
  154. package/datastore/useRecordList.js.map +1 -0
  155. package/datastore/useUpdateRecord.d.ts +52 -0
  156. package/datastore/useUpdateRecord.d.ts.map +1 -0
  157. package/datastore/useUpdateRecord.js +55 -0
  158. package/datastore/useUpdateRecord.js.map +1 -0
  159. package/environment/EnvironmentListPanel.d.ts.map +1 -1
  160. package/environment/EnvironmentListPanel.js +12 -7
  161. package/environment/EnvironmentListPanel.js.map +1 -1
  162. package/execution/ExecutionProgress.d.ts.map +1 -1
  163. package/execution/ExecutionProgress.js +13 -4
  164. package/execution/ExecutionProgress.js.map +1 -1
  165. package/execution/MessageThread.d.ts.map +1 -1
  166. package/execution/MessageThread.js +10 -2
  167. package/execution/MessageThread.js.map +1 -1
  168. package/execution/useCreateAgentExecution.d.ts +31 -1
  169. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  170. package/execution/useCreateAgentExecution.js +2 -0
  171. package/execution/useCreateAgentExecution.js.map +1 -1
  172. package/iam-policy/index.d.ts +1 -1
  173. package/iam-policy/index.d.ts.map +1 -1
  174. package/iam-policy/index.js.map +1 -1
  175. package/iam-policy/useCheckPermission.d.ts +32 -11
  176. package/iam-policy/useCheckPermission.d.ts.map +1 -1
  177. package/iam-policy/useCheckPermission.js +24 -19
  178. package/iam-policy/useCheckPermission.js.map +1 -1
  179. package/index.d.ts +12 -4
  180. package/index.d.ts.map +1 -1
  181. package/index.js +18 -3
  182. package/index.js.map +1 -1
  183. package/internal/form-primitives.d.ts +10 -0
  184. package/internal/form-primitives.d.ts.map +1 -0
  185. package/internal/form-primitives.js +15 -0
  186. package/internal/form-primitives.js.map +1 -0
  187. package/library/index.d.ts +0 -7
  188. package/library/index.d.ts.map +1 -1
  189. package/library/index.js +0 -4
  190. package/library/index.js.map +1 -1
  191. package/library/useApplyResource.d.ts +12 -12
  192. package/library/useApplyResource.d.ts.map +1 -1
  193. package/library/useApplyResource.js +16 -25
  194. package/library/useApplyResource.js.map +1 -1
  195. package/library/useExportResource.d.ts +13 -9
  196. package/library/useExportResource.d.ts.map +1 -1
  197. package/library/useExportResource.js +18 -36
  198. package/library/useExportResource.js.map +1 -1
  199. package/manifest/ApplyManifestDialog.d.ts +48 -0
  200. package/manifest/ApplyManifestDialog.d.ts.map +1 -0
  201. package/manifest/ApplyManifestDialog.js +135 -0
  202. package/manifest/ApplyManifestDialog.js.map +1 -0
  203. package/manifest/EditResourceYamlDialog.d.ts +51 -0
  204. package/manifest/EditResourceYamlDialog.d.ts.map +1 -0
  205. package/manifest/EditResourceYamlDialog.js +104 -0
  206. package/manifest/EditResourceYamlDialog.js.map +1 -0
  207. package/manifest/RedactedSecretsNotice.d.ts +14 -0
  208. package/manifest/RedactedSecretsNotice.d.ts.map +1 -0
  209. package/manifest/RedactedSecretsNotice.js +14 -0
  210. package/manifest/RedactedSecretsNotice.js.map +1 -0
  211. package/manifest/YamlEditor.d.ts +44 -0
  212. package/manifest/YamlEditor.d.ts.map +1 -0
  213. package/manifest/YamlEditor.js +216 -0
  214. package/manifest/YamlEditor.js.map +1 -0
  215. package/manifest/index.d.ts +13 -0
  216. package/manifest/index.d.ts.map +1 -0
  217. package/manifest/index.js +13 -0
  218. package/manifest/index.js.map +1 -0
  219. package/manifest/useApplyManifest.d.ts +82 -0
  220. package/manifest/useApplyManifest.d.ts.map +1 -0
  221. package/manifest/useApplyManifest.js +180 -0
  222. package/manifest/useApplyManifest.js.map +1 -0
  223. package/manifest/useEditResourceYaml.d.ts +106 -0
  224. package/manifest/useEditResourceYaml.d.ts.map +1 -0
  225. package/manifest/useEditResourceYaml.js +168 -0
  226. package/manifest/useEditResourceYaml.js.map +1 -0
  227. package/mcp-server/steps/ReviewStep.d.ts.map +1 -1
  228. package/mcp-server/steps/ReviewStep.js +2 -3
  229. package/mcp-server/steps/ReviewStep.js.map +1 -1
  230. package/package.json +4 -4
  231. package/pricing-governance/BaselineEditor.d.ts +9 -0
  232. package/pricing-governance/BaselineEditor.d.ts.map +1 -0
  233. package/pricing-governance/BaselineEditor.js +270 -0
  234. package/pricing-governance/BaselineEditor.js.map +1 -0
  235. package/pricing-governance/ModelCatalogPanel.d.ts +28 -0
  236. package/pricing-governance/ModelCatalogPanel.d.ts.map +1 -0
  237. package/pricing-governance/ModelCatalogPanel.js +102 -0
  238. package/pricing-governance/ModelCatalogPanel.js.map +1 -0
  239. package/pricing-governance/ModelGovernanceDetail.d.ts +8 -0
  240. package/pricing-governance/ModelGovernanceDetail.d.ts.map +1 -0
  241. package/pricing-governance/ModelGovernanceDetail.js +64 -0
  242. package/pricing-governance/ModelGovernanceDetail.js.map +1 -0
  243. package/pricing-governance/OperatorAccessNotice.d.ts +12 -0
  244. package/pricing-governance/OperatorAccessNotice.d.ts.map +1 -0
  245. package/pricing-governance/OperatorAccessNotice.js +15 -0
  246. package/pricing-governance/OperatorAccessNotice.js.map +1 -0
  247. package/pricing-governance/PricingGovernanceConsole.d.ts +57 -0
  248. package/pricing-governance/PricingGovernanceConsole.d.ts.map +1 -0
  249. package/pricing-governance/PricingGovernanceConsole.js +164 -0
  250. package/pricing-governance/PricingGovernanceConsole.js.map +1 -0
  251. package/pricing-governance/PricingGovernancePanel.d.ts +26 -0
  252. package/pricing-governance/PricingGovernancePanel.d.ts.map +1 -0
  253. package/pricing-governance/PricingGovernancePanel.js +64 -0
  254. package/pricing-governance/PricingGovernancePanel.js.map +1 -0
  255. package/pricing-governance/RetireConfirm.d.ts +9 -0
  256. package/pricing-governance/RetireConfirm.d.ts.map +1 -0
  257. package/pricing-governance/RetireConfirm.js +19 -0
  258. package/pricing-governance/RetireConfirm.js.map +1 -0
  259. package/pricing-governance/governance-primitives.d.ts +33 -0
  260. package/pricing-governance/governance-primitives.d.ts.map +1 -0
  261. package/pricing-governance/governance-primitives.js +43 -0
  262. package/pricing-governance/governance-primitives.js.map +1 -0
  263. package/pricing-governance/index.d.ts +19 -0
  264. package/pricing-governance/index.d.ts.map +1 -0
  265. package/pricing-governance/index.js +20 -0
  266. package/pricing-governance/index.js.map +1 -0
  267. package/pricing-governance/pricing-format.d.ts +12 -0
  268. package/pricing-governance/pricing-format.d.ts.map +1 -0
  269. package/pricing-governance/pricing-format.js +50 -0
  270. package/pricing-governance/pricing-format.js.map +1 -0
  271. package/pricing-governance/useDecidePricingOverride.d.ts +46 -0
  272. package/pricing-governance/useDecidePricingOverride.d.ts.map +1 -0
  273. package/pricing-governance/useDecidePricingOverride.js +44 -0
  274. package/pricing-governance/useDecidePricingOverride.js.map +1 -0
  275. package/pricing-governance/useModelGovernanceView.d.ts +103 -0
  276. package/pricing-governance/useModelGovernanceView.d.ts.map +1 -0
  277. package/pricing-governance/useModelGovernanceView.js +144 -0
  278. package/pricing-governance/useModelGovernanceView.js.map +1 -0
  279. package/pricing-governance/useModelPricingBaselines.d.ts +40 -0
  280. package/pricing-governance/useModelPricingBaselines.d.ts.map +1 -0
  281. package/pricing-governance/useModelPricingBaselines.js +32 -0
  282. package/pricing-governance/useModelPricingBaselines.js.map +1 -0
  283. package/pricing-governance/usePricingGovernance.d.ts +39 -0
  284. package/pricing-governance/usePricingGovernance.d.ts.map +1 -0
  285. package/pricing-governance/usePricingGovernance.js +31 -0
  286. package/pricing-governance/usePricingGovernance.js.map +1 -0
  287. package/pricing-governance/useRetireModelPricingBaseline.d.ts +31 -0
  288. package/pricing-governance/useRetireModelPricingBaseline.d.ts.map +1 -0
  289. package/pricing-governance/useRetireModelPricingBaseline.js +36 -0
  290. package/pricing-governance/useRetireModelPricingBaseline.js.map +1 -0
  291. package/pricing-governance/useUpsertModelPricingBaseline.d.ts +38 -0
  292. package/pricing-governance/useUpsertModelPricingBaseline.d.ts.map +1 -0
  293. package/pricing-governance/useUpsertModelPricingBaseline.js +37 -0
  294. package/pricing-governance/useUpsertModelPricingBaseline.js.map +1 -0
  295. package/resource-creation/templates/workflow-templates.js +4 -4
  296. package/session/useCreateSession.d.ts +28 -0
  297. package/session/useCreateSession.d.ts.map +1 -1
  298. package/session/useCreateSession.js +2 -1
  299. package/session/useCreateSession.js.map +1 -1
  300. package/session/useEditSessionPrep.js +3 -3
  301. package/session/useEditSessionPrep.js.map +1 -1
  302. package/session/useNewSessionFlow.d.ts +30 -0
  303. package/session/useNewSessionFlow.d.ts.map +1 -1
  304. package/session/useNewSessionFlow.js +7 -1
  305. package/session/useNewSessionFlow.js.map +1 -1
  306. package/session/useUpdateSession.d.ts +29 -10
  307. package/session/useUpdateSession.d.ts.map +1 -1
  308. package/session/useUpdateSession.js +29 -10
  309. package/session/useUpdateSession.js.map +1 -1
  310. package/settings/index.d.ts +2 -1
  311. package/settings/index.d.ts.map +1 -1
  312. package/settings/index.js +2 -1
  313. package/settings/index.js.map +1 -1
  314. package/settings/settings-nav.d.ts +22 -0
  315. package/settings/settings-nav.d.ts.map +1 -1
  316. package/settings/settings-nav.js +32 -1
  317. package/settings/settings-nav.js.map +1 -1
  318. package/settings/useSettingsNavGroups.d.ts +29 -0
  319. package/settings/useSettingsNavGroups.d.ts.map +1 -0
  320. package/settings/useSettingsNavGroups.js +61 -0
  321. package/settings/useSettingsNavGroups.js.map +1 -0
  322. package/src/agent/steps/ReviewStep.tsx +2 -3
  323. package/src/billing/index.ts +5 -0
  324. package/src/channel/AgentChannelsPanel.tsx +27 -1
  325. package/src/composer/SessionComposer.tsx +1 -1
  326. package/src/cursor-accounts/CursorAccountEditor.tsx +229 -0
  327. package/src/cursor-accounts/CursorAccountsAccessNotice.tsx +36 -0
  328. package/src/cursor-accounts/CursorAccountsConsole.tsx +454 -0
  329. package/src/cursor-accounts/MemberCoverageTable.tsx +439 -0
  330. package/src/cursor-accounts/MemberKeysPanel.tsx +278 -0
  331. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +680 -0
  332. package/src/cursor-accounts/__tests__/cursor-account-coverage.test.ts +73 -0
  333. package/src/cursor-accounts/badges.tsx +26 -0
  334. package/src/cursor-accounts/cursor-account-coverage.ts +71 -0
  335. package/src/cursor-accounts/cursor-account-format.ts +45 -0
  336. package/src/cursor-accounts/index.ts +29 -0
  337. package/src/cursor-accounts/useCursorAccountView.ts +49 -0
  338. package/src/cursor-accounts/useCursorAccounts.ts +49 -0
  339. package/src/cursor-accounts/useCursorMemberKeyActions.ts +106 -0
  340. package/src/cursor-accounts/useDeleteCursorAccount.ts +62 -0
  341. package/src/cursor-accounts/useSyncCursorAccount.ts +54 -0
  342. package/src/cursor-accounts/useUpsertCursorAccount.ts +57 -0
  343. package/src/datastore/CollectionRecordsBrowser.tsx +570 -0
  344. package/src/datastore/CollectionSchemaView.tsx +247 -0
  345. package/src/datastore/DatastoreDetailView.tsx +201 -0
  346. package/src/datastore/DatastoreSyncReport.tsx +105 -0
  347. package/src/datastore/DeleteDatastoreDialog.tsx +202 -0
  348. package/src/datastore/FieldValueControl.tsx +289 -0
  349. package/src/datastore/RecordFilterBuilder.tsx +422 -0
  350. package/src/datastore/RecordFormPanel.tsx +432 -0
  351. package/src/datastore/__tests__/CollectionRecordsBrowser.test.tsx +245 -0
  352. package/src/datastore/__tests__/DeleteDatastoreDialog.test.tsx +133 -0
  353. package/src/datastore/__tests__/FieldValueControl.test.tsx +160 -0
  354. package/src/datastore/__tests__/RecordFilterBuilder.test.tsx +155 -0
  355. package/src/datastore/__tests__/RecordFormPanel.test.tsx +227 -0
  356. package/src/datastore/__tests__/recordFilter.test.ts +169 -0
  357. package/src/datastore/__tests__/recordMutations.test.tsx +195 -0
  358. package/src/datastore/__tests__/recordValues.test.ts +359 -0
  359. package/src/datastore/__tests__/schemaAndSyncViews.test.tsx +142 -0
  360. package/src/datastore/__tests__/useDatastoreDescription.test.tsx +143 -0
  361. package/src/datastore/__tests__/useRecordCollection.test.tsx +250 -0
  362. package/src/datastore/__tests__/useRecordList.test.tsx +85 -0
  363. package/src/datastore/index.ts +111 -0
  364. package/src/datastore/recordFilter.ts +154 -0
  365. package/src/datastore/recordValues.ts +327 -0
  366. package/src/datastore/useDatastore.ts +67 -0
  367. package/src/datastore/useDatastoreCount.ts +67 -0
  368. package/src/datastore/useDatastoreDescription.ts +90 -0
  369. package/src/datastore/useDatastoreList.ts +79 -0
  370. package/src/datastore/useDatastoreSearch.ts +39 -0
  371. package/src/datastore/useDeleteDatastore.ts +87 -0
  372. package/src/datastore/useDeleteRecord.ts +77 -0
  373. package/src/datastore/useInsertRecord.ts +92 -0
  374. package/src/datastore/useRecordCollection.ts +256 -0
  375. package/src/datastore/useRecordList.ts +131 -0
  376. package/src/datastore/useUpdateRecord.ts +95 -0
  377. package/src/environment/EnvironmentListPanel.tsx +24 -0
  378. package/src/execution/ExecutionProgress.tsx +14 -4
  379. package/src/execution/MessageThread.tsx +10 -2
  380. package/src/execution/__tests__/ExecutionProgress.test.tsx +67 -0
  381. package/src/execution/__tests__/MessageThread.test.tsx +44 -0
  382. package/src/execution/__tests__/useArtifactInspection.test.tsx +12 -2
  383. package/src/execution/__tests__/useCreateAgentExecution.test.tsx +86 -0
  384. package/src/execution/useCreateAgentExecution.ts +41 -6
  385. package/src/iam-policy/__tests__/useCheckPermission.test.tsx +221 -0
  386. package/src/iam-policy/index.ts +1 -0
  387. package/src/iam-policy/useCheckPermission.ts +45 -19
  388. package/src/index.ts +172 -14
  389. package/src/internal/form-primitives.tsx +40 -0
  390. package/src/library/index.ts +0 -20
  391. package/src/library/useApplyResource.ts +27 -34
  392. package/src/library/useExportResource.ts +21 -40
  393. package/src/manifest/ApplyManifestDialog.tsx +315 -0
  394. package/src/manifest/EditResourceYamlDialog.tsx +265 -0
  395. package/src/manifest/RedactedSecretsNotice.tsx +30 -0
  396. package/src/manifest/YamlEditor.tsx +272 -0
  397. package/src/manifest/__tests__/EditResourceYamlDialog.test.tsx +118 -0
  398. package/src/manifest/__tests__/useApplyManifest.test.tsx +237 -0
  399. package/src/manifest/__tests__/useEditResourceYaml.test.tsx +252 -0
  400. package/src/manifest/index.ts +33 -0
  401. package/src/manifest/useApplyManifest.ts +270 -0
  402. package/src/manifest/useEditResourceYaml.ts +273 -0
  403. package/src/mcp-server/steps/ReviewStep.tsx +2 -3
  404. package/src/pricing-governance/BaselineEditor.tsx +652 -0
  405. package/src/pricing-governance/ModelCatalogPanel.tsx +283 -0
  406. package/src/pricing-governance/ModelGovernanceDetail.tsx +289 -0
  407. package/src/pricing-governance/OperatorAccessNotice.tsx +32 -0
  408. package/src/pricing-governance/PricingGovernanceConsole.tsx +465 -0
  409. package/src/pricing-governance/PricingGovernancePanel.tsx +166 -0
  410. package/src/pricing-governance/RetireConfirm.tsx +82 -0
  411. package/src/pricing-governance/__tests__/ModelCatalogPanel.test.tsx +253 -0
  412. package/src/pricing-governance/__tests__/PricingGovernanceConsole.test.tsx +410 -0
  413. package/src/pricing-governance/__tests__/useModelGovernanceView.test.tsx +308 -0
  414. package/src/pricing-governance/governance-primitives.tsx +133 -0
  415. package/src/pricing-governance/index.ts +50 -0
  416. package/src/pricing-governance/pricing-format.ts +53 -0
  417. package/src/pricing-governance/useDecidePricingOverride.ts +78 -0
  418. package/src/pricing-governance/useModelGovernanceView.ts +290 -0
  419. package/src/pricing-governance/useModelPricingBaselines.ts +69 -0
  420. package/src/pricing-governance/usePricingGovernance.ts +57 -0
  421. package/src/pricing-governance/useRetireModelPricingBaseline.ts +65 -0
  422. package/src/pricing-governance/useUpsertModelPricingBaseline.ts +72 -0
  423. package/src/resource-creation/templates/workflow-templates.ts +4 -4
  424. package/src/session/__tests__/useCreateSession.test.tsx +94 -0
  425. package/src/session/__tests__/useNewSessionFlow.test.tsx +33 -0
  426. package/src/session/useCreateSession.ts +30 -0
  427. package/src/session/useEditSessionPrep.ts +3 -3
  428. package/src/session/useNewSessionFlow.ts +45 -1
  429. package/src/session/useUpdateSession.ts +29 -10
  430. package/src/settings/__tests__/useSettingsNavGroups.test.tsx +138 -0
  431. package/src/settings/index.ts +5 -1
  432. package/src/settings/settings-nav.ts +43 -0
  433. package/src/settings/useSettingsNavGroups.ts +81 -0
  434. package/src/workflow/WorkflowYamlEditor.tsx +6 -270
  435. package/styles.css +1 -1
  436. package/workflow/CanvasTransitionEdge.d.ts +1 -1
  437. package/workflow/WorkflowYamlEditor.d.ts +2 -42
  438. package/workflow/WorkflowYamlEditor.d.ts.map +1 -1
  439. package/workflow/WorkflowYamlEditor.js +5 -214
  440. package/workflow/WorkflowYamlEditor.js.map +1 -1
  441. package/library/ImportResourceDialog.d.ts +0 -43
  442. package/library/ImportResourceDialog.d.ts.map +0 -1
  443. package/library/ImportResourceDialog.js +0 -90
  444. package/library/ImportResourceDialog.js.map +0 -1
  445. package/library/parse-resource-yaml.d.ts +0 -63
  446. package/library/parse-resource-yaml.d.ts.map +0 -1
  447. package/library/parse-resource-yaml.js +0 -407
  448. package/library/parse-resource-yaml.js.map +0 -1
  449. package/library/serialize-resource-yaml.d.ts +0 -103
  450. package/library/serialize-resource-yaml.d.ts.map +0 -1
  451. package/library/serialize-resource-yaml.js +0 -565
  452. package/library/serialize-resource-yaml.js.map +0 -1
  453. package/library/useImportResource.d.ts +0 -84
  454. package/library/useImportResource.d.ts.map +0 -1
  455. package/library/useImportResource.js +0 -188
  456. package/library/useImportResource.js.map +0 -1
  457. package/src/library/ImportResourceDialog.tsx +0 -227
  458. package/src/library/parse-resource-yaml.ts +0 -630
  459. package/src/library/serialize-resource-yaml.ts +0 -756
  460. package/src/library/useImportResource.ts +0 -253
@@ -0,0 +1,454 @@
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 { CursorAccount } from "@stigmer/protos/ai/stigmer/platform/cursoraccount/v1/cursor_account_pb";
7
+ import type { CursorAccountSummary } from "@stigmer/protos/ai/stigmer/platform/cursoraccount/v1/io_pb";
8
+ import { Button } from "../button/index.js";
9
+ import { StateBadge } from "./badges.js";
10
+ import { CursorAccountEditor } from "./CursorAccountEditor.js";
11
+ import { CursorAccountsAccessNotice } from "./CursorAccountsAccessNotice.js";
12
+ import { deriveCoverage } from "./cursor-account-coverage.js";
13
+ import { formatSyncTime } from "./cursor-account-format.js";
14
+ import { MemberKeysPanel } from "./MemberKeysPanel.js";
15
+ import { useCursorAccounts } from "./useCursorAccounts.js";
16
+ import { useCursorAccountView } from "./useCursorAccountView.js";
17
+ import { useCursorMemberKeyActions } from "./useCursorMemberKeyActions.js";
18
+ import { useDeleteCursorAccount } from "./useDeleteCursorAccount.js";
19
+ import { useSyncCursorAccount } from "./useSyncCursorAccount.js";
20
+ import { useUpsertCursorAccount } from "./useUpsertCursorAccount.js";
21
+
22
+ /** Props for {@link CursorAccountsConsole}. */
23
+ export interface CursorAccountsConsoleProps {
24
+ /** Additional CSS class names. */
25
+ readonly className?: string;
26
+ }
27
+
28
+ type Flow =
29
+ | { readonly phase: "list" }
30
+ | { readonly phase: "create" }
31
+ | { readonly phase: "detail"; readonly accountId: string; readonly editing: boolean };
32
+
33
+ /**
34
+ * The platform-operator console for managed Cursor accounts: the Cursor
35
+ * teams (admin keys, member execution keys, org assignments) that back
36
+ * the cursor harness, with roster coverage and per-member usage from
37
+ * the hourly sync.
38
+ *
39
+ * - **List** — every account with routability at a glance (an account
40
+ * with zero enabled member keys cannot serve executions).
41
+ * - **Detail** — org assignments, "Sync now", and the team-coverage
42
+ * table: every member and stored key classified into three explicit
43
+ * categories (on team with key / on team without key / key held but
44
+ * not on team), each row carrying Cursor's pool-usage percentages
45
+ * (first-party / API) and cycle spend dollars (included / on-demand).
46
+ * Off-team rows offer one-click copy of the account's Cursor team
47
+ * invite link when the operator has configured one.
48
+ *
49
+ * Requires `can_manage_cursor_accounts` on `platform:stigmer` —
50
+ * non-operators see the designed access notice. Key material never
51
+ * reaches this component; the server redacts it on every read.
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * <CursorAccountsConsole />
56
+ * ```
57
+ */
58
+ export function CursorAccountsConsole({ className }: CursorAccountsConsoleProps) {
59
+ const [flow, setFlow] = useState<Flow>({ phase: "list" });
60
+ const list = useCursorAccounts();
61
+
62
+ const backToList = useCallback(() => setFlow({ phase: "list" }), []);
63
+
64
+ if (list.isLoading) {
65
+ return (
66
+ <div className={cn("space-y-2", className)} aria-busy="true">
67
+ <div className="h-4 w-40 animate-pulse rounded bg-muted-subtle" />
68
+ {Array.from({ length: 3 }, (_, i) => (
69
+ <div key={i} className="h-10 animate-pulse rounded-lg bg-muted-subtle" />
70
+ ))}
71
+ </div>
72
+ );
73
+ }
74
+
75
+ if (list.error) {
76
+ // A non-operator landing here is expected (the route is reachable by
77
+ // URL) — show the designed access notice, not a raw RPC error.
78
+ if (isPermissionDenied(list.error)) {
79
+ return <CursorAccountsAccessNotice className={className} />;
80
+ }
81
+ return (
82
+ <p className={cn("text-destructive text-xs", className)} role="alert">
83
+ {getUserMessage(list.error)}
84
+ </p>
85
+ );
86
+ }
87
+
88
+ if (flow.phase === "create") {
89
+ return (
90
+ <CreatePane
91
+ className={className}
92
+ onSaved={() => {
93
+ list.refetch();
94
+ backToList();
95
+ }}
96
+ onCancel={backToList}
97
+ />
98
+ );
99
+ }
100
+
101
+ if (flow.phase === "detail") {
102
+ return (
103
+ <AccountDetail
104
+ className={className}
105
+ accountId={flow.accountId}
106
+ editing={flow.editing}
107
+ onEditingChange={(editing) =>
108
+ setFlow({ phase: "detail", accountId: flow.accountId, editing })
109
+ }
110
+ onDeleted={() => {
111
+ list.refetch();
112
+ backToList();
113
+ }}
114
+ onChanged={list.refetch}
115
+ onBack={backToList}
116
+ />
117
+ );
118
+ }
119
+
120
+ const accounts = list.accounts?.accounts ?? [];
121
+
122
+ return (
123
+ <div className={cn("space-y-3", className)}>
124
+ <div className="flex items-center justify-between gap-3">
125
+ <h3 className="text-sm font-semibold text-foreground">Cursor accounts</h3>
126
+ <Button size="sm" onClick={() => setFlow({ phase: "create" })}>
127
+ Add account
128
+ </Button>
129
+ </div>
130
+
131
+ <div className="rounded-lg border border-border bg-card">
132
+ <div
133
+ aria-hidden="true"
134
+ 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"
135
+ >
136
+ <span>Account</span>
137
+ <span>Orgs</span>
138
+ <span>Status</span>
139
+ <span>Execution keys</span>
140
+ <span className="text-right">Last synced</span>
141
+ </div>
142
+ {accounts.length === 0 ? (
143
+ <p className="px-3 py-2 text-xs text-muted-foreground">
144
+ No Cursor accounts yet. Add one with its team Admin API key, then
145
+ add member execution keys to make it routable.
146
+ </p>
147
+ ) : (
148
+ <ul role="list" aria-label="Cursor accounts" className="m-0 list-none p-0">
149
+ {accounts.map((summary) => (
150
+ <AccountRow
151
+ key={summary.account?.accountId}
152
+ summary={summary}
153
+ onOpen={() =>
154
+ setFlow({
155
+ phase: "detail",
156
+ accountId: summary.account?.accountId ?? "",
157
+ editing: false,
158
+ })
159
+ }
160
+ />
161
+ ))}
162
+ </ul>
163
+ )}
164
+ </div>
165
+ </div>
166
+ );
167
+ }
168
+
169
+ // ---------------------------------------------------------------------------
170
+ // List row (internal)
171
+ // ---------------------------------------------------------------------------
172
+
173
+ function AccountRow({
174
+ summary,
175
+ onOpen,
176
+ }: {
177
+ readonly summary: CursorAccountSummary;
178
+ readonly onOpen: () => void;
179
+ }) {
180
+ const account = summary.account;
181
+ if (!account) return null;
182
+
183
+ return (
184
+ <li className="border-b border-border last:border-b-0">
185
+ <button
186
+ type="button"
187
+ onClick={onOpen}
188
+ className={cn(
189
+ "grid w-full grid-cols-[2fr_1fr_1fr_1fr_1fr] items-center gap-2 px-3 py-2 text-left text-xs",
190
+ "transition-colors hover:bg-accent",
191
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
192
+ )}
193
+ >
194
+ <span className="min-w-0">
195
+ <span className="block truncate font-medium text-foreground">
196
+ {account.displayName}
197
+ </span>
198
+ {/* Account class is DERIVED from org_ids (DD-008): no org
199
+ assignment means the account belongs to the shared pool. */}
200
+ {account.orgIds.length === 0 && (
201
+ <span className="block text-[11px] text-muted-foreground">
202
+ shared pool
203
+ </span>
204
+ )}
205
+ </span>
206
+ <span className="text-muted-foreground">
207
+ {account.orgIds.length > 0 ? account.orgIds.length : "—"}
208
+ </span>
209
+ <span>
210
+ <StateBadge
211
+ tone={account.enabled ? "ok" : "muted"}
212
+ label={account.enabled ? "Enabled" : "Disabled"}
213
+ />
214
+ </span>
215
+ <span>
216
+ {summary.enabledKeyCount > 0 ? (
217
+ <span className="text-muted-foreground">{summary.enabledKeyCount}</span>
218
+ ) : (
219
+ <StateBadge tone="warn" label="Not routable" />
220
+ )}
221
+ </span>
222
+ <span className="text-right text-muted-foreground">
223
+ {formatSyncTime(summary.lastSyncedAt)}
224
+ </span>
225
+ </button>
226
+ </li>
227
+ );
228
+ }
229
+
230
+ // ---------------------------------------------------------------------------
231
+ // Create pane (internal)
232
+ // ---------------------------------------------------------------------------
233
+
234
+ function CreatePane({
235
+ className,
236
+ onSaved,
237
+ onCancel,
238
+ }: {
239
+ readonly className?: string;
240
+ readonly onSaved: () => void;
241
+ readonly onCancel: () => void;
242
+ }) {
243
+ const { upsert, isSubmitting, error } = useUpsertCursorAccount();
244
+
245
+ return (
246
+ <div className={className}>
247
+ <CursorAccountEditor
248
+ initial={null}
249
+ isSubmitting={isSubmitting}
250
+ submitError={error}
251
+ onSubmit={(account) => {
252
+ void upsert(account).then(onSaved, () => {
253
+ // Surfaced via submitError.
254
+ });
255
+ }}
256
+ onCancel={onCancel}
257
+ />
258
+ </div>
259
+ );
260
+ }
261
+
262
+ // ---------------------------------------------------------------------------
263
+ // Detail pane (internal)
264
+ // ---------------------------------------------------------------------------
265
+
266
+ function AccountDetail({
267
+ className,
268
+ accountId,
269
+ editing,
270
+ onEditingChange,
271
+ onDeleted,
272
+ onChanged,
273
+ onBack,
274
+ }: {
275
+ readonly className?: string;
276
+ readonly accountId: string;
277
+ readonly editing: boolean;
278
+ readonly onEditingChange: (editing: boolean) => void;
279
+ readonly onDeleted: () => void;
280
+ readonly onChanged: () => void;
281
+ readonly onBack: () => void;
282
+ }) {
283
+ const detail = useCursorAccountView(accountId);
284
+ const { upsert, isSubmitting: isSaving, error: saveError, clearError: clearSaveError } =
285
+ useUpsertCursorAccount();
286
+ const { remove, isSubmitting: isDeleting, error: deleteError } =
287
+ useDeleteCursorAccount();
288
+ const { sync, isSyncing, error: syncError } = useSyncCursorAccount();
289
+ const keyActions = useCursorMemberKeyActions();
290
+
291
+ const refreshAll = useCallback(() => {
292
+ detail.refetch();
293
+ onChanged();
294
+ }, [detail.refetch, onChanged]);
295
+
296
+ // After a bulk import, run the roster sync automatically so key badges
297
+ // (Active / Owner unknown / Owner left team) are current without a
298
+ // manual "Sync now". Sync failure still refreshes — the keys ARE added
299
+ // — and is surfaced via syncError.
300
+ const syncAfterImport = useCallback(() => {
301
+ void sync(accountId).then(refreshAll, refreshAll);
302
+ }, [sync, accountId, refreshAll]);
303
+
304
+ if (detail.isLoading) {
305
+ return (
306
+ <div className={cn("space-y-2", className)} aria-busy="true">
307
+ <div className="h-4 w-40 animate-pulse rounded bg-muted-subtle" />
308
+ <div className="h-24 animate-pulse rounded-lg bg-muted-subtle" />
309
+ </div>
310
+ );
311
+ }
312
+
313
+ if (detail.error || !detail.view?.account) {
314
+ return (
315
+ <div className={cn("space-y-2", className)}>
316
+ <p className="text-destructive text-xs" role="alert">
317
+ {detail.error ? getUserMessage(detail.error) : "Account not found."}
318
+ </p>
319
+ <Button size="sm" variant="outline" onClick={onBack}>
320
+ Back to accounts
321
+ </Button>
322
+ </div>
323
+ );
324
+ }
325
+
326
+ const view = detail.view;
327
+ const account = view.account as CursorAccount;
328
+ // Derived once here: the panel's table consumes the groups, the header
329
+ // line the member counts (active roster = covered + uncovered members —
330
+ // server-computed facts only, no role-string parsing in the client).
331
+ // The covered count is exactly one row per member because the server
332
+ // rejects a second key for an already-bound email, so the removed-seat
333
+ // count is plain list arithmetic: roster entries minus active members.
334
+ // It answers "where did my N members go?" when Cursor marks departed
335
+ // seats role:"removed" in place instead of dropping them.
336
+ const coverage = deriveCoverage(view);
337
+ const activeMemberCount =
338
+ coverage.onTeamWithKey.length + coverage.onTeamWithoutKey.length;
339
+ const removedSeatCount =
340
+ (view.snapshot?.members.length ?? 0) - activeMemberCount;
341
+
342
+ if (editing) {
343
+ return (
344
+ <div className={className}>
345
+ <CursorAccountEditor
346
+ initial={account}
347
+ isSubmitting={isSaving}
348
+ submitError={saveError}
349
+ onSubmit={(edited) => {
350
+ void upsert(edited).then(() => {
351
+ refreshAll();
352
+ onEditingChange(false);
353
+ }, () => {
354
+ // Surfaced via submitError.
355
+ });
356
+ }}
357
+ onCancel={() => {
358
+ clearSaveError();
359
+ onEditingChange(false);
360
+ }}
361
+ />
362
+ </div>
363
+ );
364
+ }
365
+
366
+ return (
367
+ <div className={cn("space-y-4", className)}>
368
+ <div className="flex flex-wrap items-center justify-between gap-2">
369
+ <div>
370
+ <h3 className="text-sm font-semibold text-foreground">
371
+ {account.displayName}
372
+ </h3>
373
+ <p className="text-[11px] text-muted-foreground">
374
+ {account.orgIds.length > 0
375
+ ? `Dedicated to ${account.orgIds.length} org(s): ${account.orgIds.join(", ")}`
376
+ : "Shared pool — serves every org with no dedicated account"}
377
+ {" · "}
378
+ {account.enabled ? "enabled" : "disabled"}
379
+ {account.onDemandUsageDisabled
380
+ ? " · on-demand usage off (usage guard active)"
381
+ : ""}
382
+ {" · synced "}
383
+ {formatSyncTime(view.snapshot?.syncedAt)}
384
+ {coverage.hasRoster
385
+ ? ` · ${activeMemberCount} ${activeMemberCount === 1 ? "member" : "members"}`
386
+ : ""}
387
+ {coverage.hasRoster && removedSeatCount > 0
388
+ ? ` · ${removedSeatCount} removed ${removedSeatCount === 1 ? "seat" : "seats"}`
389
+ : ""}
390
+ </p>
391
+ </div>
392
+ <div className="flex gap-2">
393
+ <Button size="sm" variant="outline" onClick={onBack}>
394
+ Back
395
+ </Button>
396
+ <Button
397
+ size="sm"
398
+ variant="outline"
399
+ disabled={isSyncing}
400
+ onClick={() => {
401
+ void sync(accountId).then(refreshAll, () => {
402
+ // Surfaced via syncError.
403
+ });
404
+ }}
405
+ >
406
+ {isSyncing ? "Syncing…" : "Sync now"}
407
+ </Button>
408
+ <Button size="sm" variant="outline" onClick={() => onEditingChange(true)}>
409
+ Edit
410
+ </Button>
411
+ <Button
412
+ size="sm"
413
+ variant="destructive"
414
+ disabled={isDeleting}
415
+ onClick={() => {
416
+ void remove({ accountId }).then(onDeleted, () => {
417
+ // Surfaced via deleteError (incl. the live-pin guard's
418
+ // "disable instead, or force" message).
419
+ });
420
+ }}
421
+ >
422
+ {isDeleting ? "Deleting…" : "Delete"}
423
+ </Button>
424
+ </div>
425
+ </div>
426
+
427
+ {syncError && (
428
+ <p className="text-destructive text-xs" role="alert">
429
+ {getUserMessage(syncError)}
430
+ </p>
431
+ )}
432
+ {deleteError && (
433
+ <p className="text-destructive text-xs" role="alert">
434
+ {getUserMessage(deleteError)}
435
+ </p>
436
+ )}
437
+ {view.snapshot?.syncError && (
438
+ <p className="text-xs text-muted-foreground" role="status">
439
+ Last sync was partial: {view.snapshot.syncError}
440
+ </p>
441
+ )}
442
+
443
+ <MemberKeysPanel
444
+ accountId={accountId}
445
+ view={view}
446
+ coverage={coverage}
447
+ actions={keyActions}
448
+ onChanged={refreshAll}
449
+ onImported={syncAfterImport}
450
+ />
451
+ </div>
452
+ );
453
+ }
454
+