@stigmer/react 3.3.0 → 3.4.1

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 (344) hide show
  1. package/agent/useAgentCount.d.ts +2 -0
  2. package/agent/useAgentCount.d.ts.map +1 -1
  3. package/agent/useAgentCount.js.map +1 -1
  4. package/api-key/CreateApiKeyForm.d.ts +7 -1
  5. package/api-key/CreateApiKeyForm.d.ts.map +1 -1
  6. package/api-key/CreateApiKeyForm.js +2 -2
  7. package/api-key/CreateApiKeyForm.js.map +1 -1
  8. package/billing/index.d.ts +0 -18
  9. package/billing/index.d.ts.map +1 -1
  10. package/billing/index.js +4 -9
  11. package/billing/index.js.map +1 -1
  12. package/cursor-accounts/CursorAccountEditor.d.ts +7 -1
  13. package/cursor-accounts/CursorAccountEditor.d.ts.map +1 -1
  14. package/cursor-accounts/CursorAccountEditor.js +21 -5
  15. package/cursor-accounts/CursorAccountEditor.js.map +1 -1
  16. package/cursor-accounts/CursorAccountsConsole.d.ts +9 -5
  17. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
  18. package/cursor-accounts/CursorAccountsConsole.js +34 -140
  19. package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
  20. package/cursor-accounts/MemberCoverageTable.d.ts +29 -0
  21. package/cursor-accounts/MemberCoverageTable.d.ts.map +1 -0
  22. package/cursor-accounts/MemberCoverageTable.js +150 -0
  23. package/cursor-accounts/MemberCoverageTable.js.map +1 -0
  24. package/cursor-accounts/MemberKeysPanel.d.ts +25 -0
  25. package/cursor-accounts/MemberKeysPanel.d.ts.map +1 -0
  26. package/cursor-accounts/MemberKeysPanel.js +115 -0
  27. package/cursor-accounts/MemberKeysPanel.js.map +1 -0
  28. package/cursor-accounts/badges.d.ts +9 -0
  29. package/cursor-accounts/badges.d.ts.map +1 -0
  30. package/cursor-accounts/badges.js +10 -0
  31. package/cursor-accounts/badges.js.map +1 -0
  32. package/cursor-accounts/cursor-account-coverage.d.ts +41 -0
  33. package/cursor-accounts/cursor-account-coverage.d.ts.map +1 -0
  34. package/cursor-accounts/cursor-account-coverage.js +26 -0
  35. package/cursor-accounts/cursor-account-coverage.js.map +1 -0
  36. package/cursor-accounts/cursor-account-format.d.ts +13 -0
  37. package/cursor-accounts/cursor-account-format.d.ts.map +1 -1
  38. package/cursor-accounts/cursor-account-format.js +16 -1
  39. package/cursor-accounts/cursor-account-format.js.map +1 -1
  40. package/datastore/CollectionRecordsBrowser.js +18 -4
  41. package/datastore/CollectionRecordsBrowser.js.map +1 -1
  42. package/datastore/RecordFilterBuilder.d.ts +8 -1
  43. package/datastore/RecordFilterBuilder.d.ts.map +1 -1
  44. package/datastore/RecordFilterBuilder.js +2 -2
  45. package/datastore/RecordFilterBuilder.js.map +1 -1
  46. package/datastore/recordFilter.d.ts +9 -1
  47. package/datastore/recordFilter.d.ts.map +1 -1
  48. package/datastore/recordFilter.js +12 -1
  49. package/datastore/recordFilter.js.map +1 -1
  50. package/datastore/useDatastoreCount.d.ts +2 -0
  51. package/datastore/useDatastoreCount.d.ts.map +1 -1
  52. package/datastore/useDatastoreCount.js.map +1 -1
  53. package/execution/ExecutionProgress.d.ts.map +1 -1
  54. package/execution/ExecutionProgress.js +13 -4
  55. package/execution/ExecutionProgress.js.map +1 -1
  56. package/execution/MessageThread.d.ts.map +1 -1
  57. package/execution/MessageThread.js +10 -2
  58. package/execution/MessageThread.js.map +1 -1
  59. package/execution/useCreateAgentExecution.d.ts +31 -1
  60. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  61. package/execution/useCreateAgentExecution.js +2 -0
  62. package/execution/useCreateAgentExecution.js.map +1 -1
  63. package/index.d.ts +8 -6
  64. package/index.d.ts.map +1 -1
  65. package/index.js +8 -4
  66. package/index.js.map +1 -1
  67. package/internal/form-primitives.d.ts +10 -0
  68. package/internal/form-primitives.d.ts.map +1 -0
  69. package/{billing → internal}/form-primitives.js +5 -9
  70. package/internal/form-primitives.js.map +1 -0
  71. package/manifest/ApplyManifestDialog.d.ts +10 -5
  72. package/manifest/ApplyManifestDialog.d.ts.map +1 -1
  73. package/manifest/ApplyManifestDialog.js +30 -13
  74. package/manifest/ApplyManifestDialog.js.map +1 -1
  75. package/manifest/useApplyManifest.d.ts +6 -2
  76. package/manifest/useApplyManifest.d.ts.map +1 -1
  77. package/manifest/useApplyManifest.js +5 -5
  78. package/manifest/useApplyManifest.js.map +1 -1
  79. package/mcp-server/McpServerDetailView.d.ts +38 -2
  80. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  81. package/mcp-server/McpServerDetailView.js +21 -5
  82. package/mcp-server/McpServerDetailView.js.map +1 -1
  83. package/mcp-server/index.d.ts +7 -0
  84. package/mcp-server/index.d.ts.map +1 -1
  85. package/mcp-server/index.js +9 -0
  86. package/mcp-server/index.js.map +1 -1
  87. package/mcp-server/steps/EnvironmentAuthStep.d.ts +4 -0
  88. package/mcp-server/steps/EnvironmentAuthStep.d.ts.map +1 -1
  89. package/mcp-server/steps/EnvironmentAuthStep.js +4 -0
  90. package/mcp-server/steps/EnvironmentAuthStep.js.map +1 -1
  91. package/mcp-server/steps/IdentityTransportStep.d.ts +6 -0
  92. package/mcp-server/steps/IdentityTransportStep.d.ts.map +1 -1
  93. package/mcp-server/steps/IdentityTransportStep.js +7 -1
  94. package/mcp-server/steps/IdentityTransportStep.js.map +1 -1
  95. package/mcp-server/steps/ReviewStep.d.ts +5 -0
  96. package/mcp-server/steps/ReviewStep.d.ts.map +1 -1
  97. package/mcp-server/steps/ReviewStep.js +16 -2
  98. package/mcp-server/steps/ReviewStep.js.map +1 -1
  99. package/mcp-server/useMcpServerCount.d.ts +2 -0
  100. package/mcp-server/useMcpServerCount.d.ts.map +1 -1
  101. package/mcp-server/useMcpServerCount.js.map +1 -1
  102. package/package.json +4 -4
  103. package/pricing-governance/BaselineEditor.d.ts.map +1 -0
  104. package/{billing → pricing-governance}/BaselineEditor.js +19 -2
  105. package/pricing-governance/BaselineEditor.js.map +1 -0
  106. package/pricing-governance/ModelCatalogPanel.d.ts.map +1 -0
  107. package/pricing-governance/ModelCatalogPanel.js.map +1 -0
  108. package/pricing-governance/ModelGovernanceDetail.d.ts.map +1 -0
  109. package/pricing-governance/ModelGovernanceDetail.js.map +1 -0
  110. package/pricing-governance/OperatorAccessNotice.d.ts.map +1 -0
  111. package/pricing-governance/OperatorAccessNotice.js.map +1 -0
  112. package/pricing-governance/PricingGovernanceConsole.d.ts.map +1 -0
  113. package/{billing → pricing-governance}/PricingGovernanceConsole.js +1 -1
  114. package/pricing-governance/PricingGovernanceConsole.js.map +1 -0
  115. package/pricing-governance/PricingGovernancePanel.d.ts.map +1 -0
  116. package/pricing-governance/PricingGovernancePanel.js.map +1 -0
  117. package/pricing-governance/RetireConfirm.d.ts.map +1 -0
  118. package/{billing → pricing-governance}/RetireConfirm.js +1 -1
  119. package/pricing-governance/RetireConfirm.js.map +1 -0
  120. package/pricing-governance/governance-primitives.d.ts.map +1 -0
  121. package/pricing-governance/governance-primitives.js.map +1 -0
  122. package/pricing-governance/index.d.ts +19 -0
  123. package/pricing-governance/index.d.ts.map +1 -0
  124. package/pricing-governance/index.js +20 -0
  125. package/pricing-governance/index.js.map +1 -0
  126. package/pricing-governance/pricing-format.d.ts.map +1 -0
  127. package/pricing-governance/pricing-format.js.map +1 -0
  128. package/pricing-governance/useDecidePricingOverride.d.ts.map +1 -0
  129. package/pricing-governance/useDecidePricingOverride.js.map +1 -0
  130. package/pricing-governance/useModelGovernanceView.d.ts.map +1 -0
  131. package/pricing-governance/useModelGovernanceView.js.map +1 -0
  132. package/pricing-governance/useModelPricingBaselines.d.ts.map +1 -0
  133. package/pricing-governance/useModelPricingBaselines.js.map +1 -0
  134. package/pricing-governance/usePricingGovernance.d.ts.map +1 -0
  135. package/pricing-governance/usePricingGovernance.js.map +1 -0
  136. package/pricing-governance/useRetireModelPricingBaseline.d.ts.map +1 -0
  137. package/pricing-governance/useRetireModelPricingBaseline.js.map +1 -0
  138. package/pricing-governance/useUpsertModelPricingBaseline.d.ts.map +1 -0
  139. package/pricing-governance/useUpsertModelPricingBaseline.js.map +1 -0
  140. package/resource-creation/CreationPicker.d.ts.map +1 -1
  141. package/resource-creation/CreationPicker.js +3 -3
  142. package/resource-creation/CreationPicker.js.map +1 -1
  143. package/resource-creation/WizardNav.d.ts.map +1 -1
  144. package/resource-creation/WizardNav.js +1 -1
  145. package/resource-creation/WizardNav.js.map +1 -1
  146. package/resource-detail/Section.d.ts +8 -1
  147. package/resource-detail/Section.d.ts.map +1 -1
  148. package/resource-detail/Section.js +2 -2
  149. package/resource-detail/Section.js.map +1 -1
  150. package/resource-workbench/components/ResourceWorkbench.d.ts +9 -1
  151. package/resource-workbench/components/ResourceWorkbench.d.ts.map +1 -1
  152. package/resource-workbench/components/ResourceWorkbench.js +2 -1
  153. package/resource-workbench/components/ResourceWorkbench.js.map +1 -1
  154. package/resource-workbench/hooks/useResourceCollection.d.ts +9 -0
  155. package/resource-workbench/hooks/useResourceCollection.d.ts.map +1 -1
  156. package/resource-workbench/hooks/useResourceCollection.js +2 -2
  157. package/resource-workbench/hooks/useResourceCollection.js.map +1 -1
  158. package/search/useResourceCount.d.ts +7 -0
  159. package/search/useResourceCount.d.ts.map +1 -1
  160. package/search/useResourceCount.js +2 -1
  161. package/search/useResourceCount.js.map +1 -1
  162. package/session/NewSessionViewer.d.ts.map +1 -1
  163. package/session/NewSessionViewer.js +17 -3
  164. package/session/NewSessionViewer.js.map +1 -1
  165. package/session/SessionViewer.d.ts +2 -1
  166. package/session/SessionViewer.d.ts.map +1 -1
  167. package/session/SessionViewer.js +19 -11
  168. package/session/SessionViewer.js.map +1 -1
  169. package/session/SessionViewerLayout.d.ts +90 -0
  170. package/session/SessionViewerLayout.d.ts.map +1 -0
  171. package/session/SessionViewerLayout.js +32 -0
  172. package/session/SessionViewerLayout.js.map +1 -0
  173. package/session/index.d.ts +4 -0
  174. package/session/index.d.ts.map +1 -1
  175. package/session/index.js +10 -0
  176. package/session/index.js.map +1 -1
  177. package/session/useCreateSession.d.ts +28 -0
  178. package/session/useCreateSession.d.ts.map +1 -1
  179. package/session/useCreateSession.js +2 -1
  180. package/session/useCreateSession.js.map +1 -1
  181. package/session/useNewSessionFlow.d.ts +30 -0
  182. package/session/useNewSessionFlow.d.ts.map +1 -1
  183. package/session/useNewSessionFlow.js +7 -1
  184. package/session/useNewSessionFlow.js.map +1 -1
  185. package/session/useSessionRailViews.d.ts +2 -2
  186. package/session/useUpdateSession.d.ts +29 -10
  187. package/session/useUpdateSession.d.ts.map +1 -1
  188. package/session/useUpdateSession.js +29 -10
  189. package/session/useUpdateSession.js.map +1 -1
  190. package/skill/useSkillCount.d.ts +2 -0
  191. package/skill/useSkillCount.d.ts.map +1 -1
  192. package/skill/useSkillCount.js.map +1 -1
  193. package/src/agent/useAgentCount.ts +2 -0
  194. package/src/api-key/CreateApiKeyForm.tsx +8 -1
  195. package/src/api-key/__tests__/CreateApiKeyForm.test.tsx +58 -0
  196. package/src/billing/index.ts +5 -37
  197. package/src/cursor-accounts/CursorAccountEditor.tsx +61 -13
  198. package/src/cursor-accounts/CursorAccountsConsole.tsx +44 -400
  199. package/src/cursor-accounts/MemberCoverageTable.tsx +439 -0
  200. package/src/cursor-accounts/MemberKeysPanel.tsx +278 -0
  201. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +306 -10
  202. package/src/cursor-accounts/__tests__/cursor-account-coverage.test.ts +73 -0
  203. package/src/cursor-accounts/badges.tsx +26 -0
  204. package/src/cursor-accounts/cursor-account-coverage.ts +71 -0
  205. package/src/cursor-accounts/cursor-account-format.ts +17 -1
  206. package/src/datastore/CollectionRecordsBrowser.tsx +29 -3
  207. package/src/datastore/RecordFilterBuilder.tsx +12 -1
  208. package/src/datastore/__tests__/CollectionRecordsBrowser.test.tsx +38 -0
  209. package/src/datastore/__tests__/RecordFilterBuilder.test.tsx +14 -0
  210. package/src/datastore/__tests__/recordFilter.test.ts +13 -0
  211. package/src/datastore/recordFilter.ts +15 -1
  212. package/src/datastore/useDatastoreCount.ts +2 -0
  213. package/src/execution/ExecutionProgress.tsx +14 -4
  214. package/src/execution/MessageThread.tsx +10 -2
  215. package/src/execution/__tests__/ExecutionProgress.test.tsx +67 -0
  216. package/src/execution/__tests__/MessageThread.test.tsx +44 -0
  217. package/src/execution/__tests__/useCreateAgentExecution.test.tsx +86 -0
  218. package/src/execution/useCreateAgentExecution.ts +41 -6
  219. package/src/index.ts +43 -24
  220. package/src/{billing → internal}/form-primitives.tsx +4 -32
  221. package/src/manifest/ApplyManifestDialog.tsx +40 -16
  222. package/src/manifest/__tests__/ApplyManifestDialog.test.tsx +147 -0
  223. package/src/manifest/__tests__/useApplyManifest.test.tsx +6 -6
  224. package/src/manifest/useApplyManifest.ts +12 -8
  225. package/src/mcp-server/McpServerDetailView.tsx +52 -4
  226. package/src/mcp-server/__tests__/McpServerDetailView.test.tsx +345 -0
  227. package/src/mcp-server/index.ts +13 -0
  228. package/src/mcp-server/steps/EnvironmentAuthStep.tsx +4 -0
  229. package/src/mcp-server/steps/IdentityTransportStep.tsx +9 -1
  230. package/src/mcp-server/steps/ReviewStep.tsx +18 -1
  231. package/src/mcp-server/useMcpServerCount.ts +2 -0
  232. package/src/{billing → pricing-governance}/BaselineEditor.tsx +36 -3
  233. package/src/{billing → pricing-governance}/PricingGovernanceConsole.tsx +1 -1
  234. package/src/{billing → pricing-governance}/RetireConfirm.tsx +1 -1
  235. package/src/pricing-governance/index.ts +50 -0
  236. package/src/resource-creation/CreationPicker.tsx +7 -0
  237. package/src/resource-creation/WizardNav.tsx +1 -0
  238. package/src/resource-detail/Section.tsx +9 -1
  239. package/src/resource-workbench/components/ResourceWorkbench.tsx +13 -0
  240. package/src/resource-workbench/hooks/useResourceCollection.ts +11 -1
  241. package/src/search/useResourceCount.ts +9 -1
  242. package/src/session/NewSessionViewer.tsx +48 -61
  243. package/src/session/SessionViewer.tsx +71 -86
  244. package/src/session/SessionViewerLayout.tsx +131 -0
  245. package/src/session/__tests__/SessionViewerLayout.test.tsx +140 -0
  246. package/src/session/__tests__/useCreateSession.test.tsx +94 -0
  247. package/src/session/__tests__/useNewSessionFlow.test.tsx +33 -0
  248. package/src/session/index.ts +14 -0
  249. package/src/session/useCreateSession.ts +30 -0
  250. package/src/session/useNewSessionFlow.ts +45 -1
  251. package/src/session/useSessionRailViews.tsx +2 -2
  252. package/src/session/useUpdateSession.ts +29 -10
  253. package/src/skill/useSkillCount.ts +2 -0
  254. package/src/test/__tests__/samples.test.ts +159 -2
  255. package/src/test/index.ts +1 -1
  256. package/src/test/samples.ts +109 -14
  257. package/src/workflow/useWorkflowCount.ts +2 -0
  258. package/styles.css +1 -1
  259. package/test/index.d.ts +1 -1
  260. package/test/index.d.ts.map +1 -1
  261. package/test/index.js +1 -1
  262. package/test/index.js.map +1 -1
  263. package/test/samples.d.ts +79 -7
  264. package/test/samples.d.ts.map +1 -1
  265. package/test/samples.js +101 -14
  266. package/test/samples.js.map +1 -1
  267. package/workflow/useWorkflowCount.d.ts +2 -0
  268. package/workflow/useWorkflowCount.d.ts.map +1 -1
  269. package/workflow/useWorkflowCount.js.map +1 -1
  270. package/billing/BaselineEditor.d.ts.map +0 -1
  271. package/billing/BaselineEditor.js.map +0 -1
  272. package/billing/ModelCatalogPanel.d.ts.map +0 -1
  273. package/billing/ModelCatalogPanel.js.map +0 -1
  274. package/billing/ModelGovernanceDetail.d.ts.map +0 -1
  275. package/billing/ModelGovernanceDetail.js.map +0 -1
  276. package/billing/OperatorAccessNotice.d.ts.map +0 -1
  277. package/billing/OperatorAccessNotice.js.map +0 -1
  278. package/billing/PricingGovernanceConsole.d.ts.map +0 -1
  279. package/billing/PricingGovernanceConsole.js.map +0 -1
  280. package/billing/PricingGovernancePanel.d.ts.map +0 -1
  281. package/billing/PricingGovernancePanel.js.map +0 -1
  282. package/billing/RetireConfirm.d.ts.map +0 -1
  283. package/billing/RetireConfirm.js.map +0 -1
  284. package/billing/form-primitives.d.ts +0 -18
  285. package/billing/form-primitives.d.ts.map +0 -1
  286. package/billing/form-primitives.js.map +0 -1
  287. package/billing/governance-primitives.d.ts.map +0 -1
  288. package/billing/governance-primitives.js.map +0 -1
  289. package/billing/pricing-format.d.ts.map +0 -1
  290. package/billing/pricing-format.js.map +0 -1
  291. package/billing/useDecidePricingOverride.d.ts.map +0 -1
  292. package/billing/useDecidePricingOverride.js.map +0 -1
  293. package/billing/useModelGovernanceView.d.ts.map +0 -1
  294. package/billing/useModelGovernanceView.js.map +0 -1
  295. package/billing/useModelPricingBaselines.d.ts.map +0 -1
  296. package/billing/useModelPricingBaselines.js.map +0 -1
  297. package/billing/usePricingGovernance.d.ts.map +0 -1
  298. package/billing/usePricingGovernance.js.map +0 -1
  299. package/billing/useRetireModelPricingBaseline.d.ts.map +0 -1
  300. package/billing/useRetireModelPricingBaseline.js.map +0 -1
  301. package/billing/useUpsertModelPricingBaseline.d.ts.map +0 -1
  302. package/billing/useUpsertModelPricingBaseline.js.map +0 -1
  303. /package/{billing → pricing-governance}/BaselineEditor.d.ts +0 -0
  304. /package/{billing → pricing-governance}/ModelCatalogPanel.d.ts +0 -0
  305. /package/{billing → pricing-governance}/ModelCatalogPanel.js +0 -0
  306. /package/{billing → pricing-governance}/ModelGovernanceDetail.d.ts +0 -0
  307. /package/{billing → pricing-governance}/ModelGovernanceDetail.js +0 -0
  308. /package/{billing → pricing-governance}/OperatorAccessNotice.d.ts +0 -0
  309. /package/{billing → pricing-governance}/OperatorAccessNotice.js +0 -0
  310. /package/{billing → pricing-governance}/PricingGovernanceConsole.d.ts +0 -0
  311. /package/{billing → pricing-governance}/PricingGovernancePanel.d.ts +0 -0
  312. /package/{billing → pricing-governance}/PricingGovernancePanel.js +0 -0
  313. /package/{billing → pricing-governance}/RetireConfirm.d.ts +0 -0
  314. /package/{billing → pricing-governance}/governance-primitives.d.ts +0 -0
  315. /package/{billing → pricing-governance}/governance-primitives.js +0 -0
  316. /package/{billing → pricing-governance}/pricing-format.d.ts +0 -0
  317. /package/{billing → pricing-governance}/pricing-format.js +0 -0
  318. /package/{billing → pricing-governance}/useDecidePricingOverride.d.ts +0 -0
  319. /package/{billing → pricing-governance}/useDecidePricingOverride.js +0 -0
  320. /package/{billing → pricing-governance}/useModelGovernanceView.d.ts +0 -0
  321. /package/{billing → pricing-governance}/useModelGovernanceView.js +0 -0
  322. /package/{billing → pricing-governance}/useModelPricingBaselines.d.ts +0 -0
  323. /package/{billing → pricing-governance}/useModelPricingBaselines.js +0 -0
  324. /package/{billing → pricing-governance}/usePricingGovernance.d.ts +0 -0
  325. /package/{billing → pricing-governance}/usePricingGovernance.js +0 -0
  326. /package/{billing → pricing-governance}/useRetireModelPricingBaseline.d.ts +0 -0
  327. /package/{billing → pricing-governance}/useRetireModelPricingBaseline.js +0 -0
  328. /package/{billing → pricing-governance}/useUpsertModelPricingBaseline.d.ts +0 -0
  329. /package/{billing → pricing-governance}/useUpsertModelPricingBaseline.js +0 -0
  330. /package/src/{billing → pricing-governance}/ModelCatalogPanel.tsx +0 -0
  331. /package/src/{billing → pricing-governance}/ModelGovernanceDetail.tsx +0 -0
  332. /package/src/{billing → pricing-governance}/OperatorAccessNotice.tsx +0 -0
  333. /package/src/{billing → pricing-governance}/PricingGovernancePanel.tsx +0 -0
  334. /package/src/{billing → pricing-governance}/__tests__/ModelCatalogPanel.test.tsx +0 -0
  335. /package/src/{billing → pricing-governance}/__tests__/PricingGovernanceConsole.test.tsx +0 -0
  336. /package/src/{billing → pricing-governance}/__tests__/useModelGovernanceView.test.tsx +0 -0
  337. /package/src/{billing → pricing-governance}/governance-primitives.tsx +0 -0
  338. /package/src/{billing → pricing-governance}/pricing-format.ts +0 -0
  339. /package/src/{billing → pricing-governance}/useDecidePricingOverride.ts +0 -0
  340. /package/src/{billing → pricing-governance}/useModelGovernanceView.ts +0 -0
  341. /package/src/{billing → pricing-governance}/useModelPricingBaselines.ts +0 -0
  342. /package/src/{billing → pricing-governance}/usePricingGovernance.ts +0 -0
  343. /package/src/{billing → pricing-governance}/useRetireModelPricingBaseline.ts +0 -0
  344. /package/src/{billing → pricing-governance}/useUpsertModelPricingBaseline.ts +0 -0
@@ -0,0 +1,131 @@
1
+ "use client";
2
+
3
+ import type { ReactNode } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { ResizableSplit } from "../internal/ResizableSplit.js";
6
+
7
+ /** Props for {@link SessionViewerLayout}. */
8
+ export interface SessionViewerLayoutProps {
9
+ /**
10
+ * The conversation column — the layout's primary (left) pane. Stays
11
+ * mounted at a stable tree position across every panel open/close, so
12
+ * streaming and scroll state survive the toggle.
13
+ */
14
+ readonly conversation: ReactNode;
15
+ /**
16
+ * The session panel content, or `null` while the panel is collapsed.
17
+ * This is the single source of truth for the collapsed state: passing
18
+ * `null` collapses the split (the conversation fills the row) and hides
19
+ * the drag separator; passing content expands the panel into the
20
+ * flexible region. Hosts derive it from their panel controller, e.g.
21
+ * `panel.isOpen ? <WorkspaceSurface … /> : null`.
22
+ */
23
+ readonly panel: ReactNode | null;
24
+ /**
25
+ * The panel's toggle chip, rendered in the layout's top-right corner
26
+ * (typically the session panel chip, {@link PanelChip}). Omit it to
27
+ * render no toggle — how hosts express audiences that must never open
28
+ * the panel (the guest case in {@link SessionViewer} and
29
+ * {@link NewSessionViewer}).
30
+ */
31
+ readonly chip?: ReactNode;
32
+ /**
33
+ * Host-injected header actions, rendered beside the chip in the
34
+ * top-right corner (slot injection, as {@link SessionViewerProps.headerActions}).
35
+ */
36
+ readonly headerActions?: ReactNode;
37
+ /**
38
+ * `localStorage` key persisting the chat pane's drag-resized width
39
+ * across sessions. Each host passes its own key so the two shipped
40
+ * viewers keep distinct widths. **Omit it in deterministic hosts**
41
+ * (documentation embeds, video export): with no key the width always
42
+ * starts at the default, so every render of the same input is
43
+ * pixel-identical instead of depending on previously persisted state.
44
+ */
45
+ readonly splitStorageKey?: string;
46
+ /**
47
+ * Whether the conversation pane collapses below the `lg` breakpoint
48
+ * while the panel is open, leaving the panel full-width — the shipped
49
+ * console behavior on narrow windows.
50
+ *
51
+ * Pass `false` in fixed-canvas hosts, where the media query is
52
+ * meaningless or actively wrong: a documentation embed renders in an
53
+ * iframe whose viewport is the docs column (below `lg` on most pages),
54
+ * so the default would hide the conversation on exactly the beats that
55
+ * open the panel.
56
+ *
57
+ * @default true
58
+ */
59
+ readonly responsive?: boolean;
60
+ /**
61
+ * Accessible label for the split's drag separator. Name the pane being
62
+ * resized in the host's vocabulary (the session viewer's chat pane vs
63
+ * the launcher's composer pane).
64
+ *
65
+ * @default "Resize chat panel"
66
+ */
67
+ readonly resizeAriaLabel?: string;
68
+ /** Additional CSS classes for the root container. */
69
+ readonly className?: string;
70
+ }
71
+
72
+ /**
73
+ * The one conversation-plus-panel frame every session viewer shares —
74
+ * {@link SessionViewer} and {@link NewSessionViewer} both render it, so the
75
+ * two surfaces cannot drift apart (their behave-identically contract), and
76
+ * platform builders composing a custom session surface from
77
+ * {@link WorkspaceSurface}, {@link PanelChip}, and the session facets get
78
+ * the same geometry the shipped console uses.
79
+ *
80
+ * The layout owns exactly three things:
81
+ *
82
+ * - **The top-right control corner** — the host's `headerActions` beside
83
+ * the panel toggle `chip`, absolutely positioned over the conversation.
84
+ * - **The split geometry** — chat fills the row while the panel is
85
+ * collapsed; opening makes the chat the fixed, drag-resizable pane
86
+ * (420px default, 320–640px) and hands the flexible region to the panel.
87
+ * - **The collapse mechanics** — collapse goes through the split's
88
+ * `collapsedPane` (CSS, not conditional structure), so the conversation
89
+ * is always the same first child and an open/close toggle never
90
+ * remounts it.
91
+ *
92
+ * Everything rendered inside the panes belongs to the host: the layout
93
+ * takes opaque `ReactNode`s and never inspects them.
94
+ */
95
+ export function SessionViewerLayout({
96
+ conversation,
97
+ panel,
98
+ chip,
99
+ headerActions,
100
+ splitStorageKey,
101
+ responsive = true,
102
+ resizeAriaLabel = "Resize chat panel",
103
+ className,
104
+ }: SessionViewerLayoutProps) {
105
+ const isPanelOpen = panel != null;
106
+
107
+ return (
108
+ <div className={cn("relative flex h-full w-full flex-col", className)}>
109
+ {(headerActions != null || chip != null) && (
110
+ <div className="absolute top-2 right-6 z-10 flex items-center gap-2">
111
+ {headerActions}
112
+ {chip}
113
+ </div>
114
+ )}
115
+
116
+ <ResizableSplit
117
+ resizablePane="primary"
118
+ collapsedPane={isPanelOpen ? "none" : "secondary"}
119
+ defaultSize={420}
120
+ minSize={320}
121
+ maxSize={640}
122
+ storageKey={splitStorageKey}
123
+ responsiveCollapse={responsive && isPanelOpen ? "primary" : "none"}
124
+ ariaLabel={resizeAriaLabel}
125
+ className="min-h-0 flex-1"
126
+ primary={conversation}
127
+ secondary={panel}
128
+ />
129
+ </div>
130
+ );
131
+ }
@@ -0,0 +1,140 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { render, screen, cleanup } from "@testing-library/react";
3
+ import { SessionViewerLayout } from "../SessionViewerLayout";
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // The one conversation-plus-panel frame both shipped viewers render
7
+ // (SessionViewer + NewSessionViewer), so the two surfaces cannot drift.
8
+ // The contract under test:
9
+ // - `panel` is the single source of truth for collapsed state
10
+ // - the conversation never remounts across an open/close toggle
11
+ // - `responsive={false}` disables the below-`lg` conversation collapse
12
+ // (fixed-canvas hosts: docs embeds, video export)
13
+ // - no `splitStorageKey` means no localStorage read (deterministic hosts)
14
+ // ---------------------------------------------------------------------------
15
+
16
+ afterEach(() => {
17
+ cleanup();
18
+ vi.restoreAllMocks();
19
+ localStorage.clear();
20
+ });
21
+
22
+ function conversation() {
23
+ return <div data-testid="conversation">chat</div>;
24
+ }
25
+
26
+ function panel() {
27
+ return <div data-testid="panel">panel</div>;
28
+ }
29
+
30
+ describe("SessionViewerLayout", () => {
31
+ it("collapsed (panel null): conversation renders, panel absent, no separator exposed", () => {
32
+ render(<SessionViewerLayout conversation={conversation()} panel={null} />);
33
+ expect(screen.getByTestId("conversation").textContent).toBe("chat");
34
+ expect(screen.queryByTestId("panel")).toBeNull();
35
+ // The drag separator is CSS-hidden and aria-hidden while collapsed.
36
+ expect(screen.queryByRole("separator")).toBeNull();
37
+ });
38
+
39
+ it("open (panel provided): panel renders and the separator is operable", () => {
40
+ render(<SessionViewerLayout conversation={conversation()} panel={panel()} />);
41
+ expect(screen.getByTestId("panel").textContent).toBe("panel");
42
+ const separator = screen.getByRole("separator", { name: "Resize chat panel" });
43
+ expect(separator.getAttribute("tabindex")).toBe("0");
44
+ });
45
+
46
+ it("resizeAriaLabel names the separator in the host's vocabulary", () => {
47
+ render(
48
+ <SessionViewerLayout
49
+ conversation={conversation()}
50
+ panel={panel()}
51
+ resizeAriaLabel="Resize composer panel"
52
+ />,
53
+ );
54
+ expect(
55
+ screen.queryByRole("separator", { name: "Resize composer panel" }),
56
+ ).not.toBeNull();
57
+ });
58
+
59
+ it("never remounts the conversation across an open/close toggle", () => {
60
+ const { rerender } = render(
61
+ <SessionViewerLayout conversation={conversation()} panel={null} />,
62
+ );
63
+ const node = screen.getByTestId("conversation");
64
+
65
+ rerender(<SessionViewerLayout conversation={conversation()} panel={panel()} />);
66
+ expect(screen.getByTestId("conversation")).toBe(node);
67
+
68
+ rerender(<SessionViewerLayout conversation={conversation()} panel={null} />);
69
+ expect(screen.getByTestId("conversation")).toBe(node);
70
+ });
71
+
72
+ it("open panel sizes the conversation pane at the shared default width", () => {
73
+ render(<SessionViewerLayout conversation={conversation()} panel={panel()} />);
74
+ const pane = screen.getByTestId("conversation").parentElement!;
75
+ expect(pane.style.width).toBe("420px");
76
+ });
77
+
78
+ it("responsive (default): the open-panel conversation pane collapses below lg", () => {
79
+ const { container } = render(
80
+ <SessionViewerLayout conversation={conversation()} panel={panel()} />,
81
+ );
82
+ const pane = screen.getByTestId("conversation").parentElement!;
83
+ expect(pane.className).toContain("max-lg:hidden");
84
+ // The separator hides with it, so the panel is the full row below lg.
85
+ expect(container.querySelectorAll('[class*="max-lg:hidden"]').length).toBe(2);
86
+ });
87
+
88
+ it("responsive={false}: no below-lg collapse anywhere (fixed-canvas hosts)", () => {
89
+ const { container } = render(
90
+ <SessionViewerLayout
91
+ conversation={conversation()}
92
+ panel={panel()}
93
+ responsive={false}
94
+ />,
95
+ );
96
+ expect(container.querySelector('[class*="max-lg:hidden"]')).toBeNull();
97
+ });
98
+
99
+ it("reads no localStorage without a splitStorageKey (deterministic hosts)", () => {
100
+ const getItem = vi.spyOn(Storage.prototype, "getItem");
101
+ render(<SessionViewerLayout conversation={conversation()} panel={panel()} />);
102
+ expect(getItem).not.toHaveBeenCalled();
103
+ });
104
+
105
+ it("seeds the pane width from the host's splitStorageKey when given", () => {
106
+ localStorage.setItem("stgm-test-chat-width", "512");
107
+ render(
108
+ <SessionViewerLayout
109
+ conversation={conversation()}
110
+ panel={panel()}
111
+ splitStorageKey="stgm-test-chat-width"
112
+ />,
113
+ );
114
+ const pane = screen.getByTestId("conversation").parentElement!;
115
+ expect(pane.style.width).toBe("512px");
116
+ });
117
+
118
+ it("renders headerActions beside the chip in the top-right corner", () => {
119
+ render(
120
+ <SessionViewerLayout
121
+ conversation={conversation()}
122
+ panel={null}
123
+ headerActions={<button type="button">Share</button>}
124
+ chip={<button type="button">Toggle panel</button>}
125
+ />,
126
+ );
127
+ const actions = screen.getByRole("button", { name: "Share" });
128
+ const chip = screen.getByRole("button", { name: "Toggle panel" });
129
+ expect(actions.parentElement).toBe(chip.parentElement);
130
+ });
131
+
132
+ it("renders no control corner when both chip and headerActions are omitted", () => {
133
+ const { container } = render(
134
+ <SessionViewerLayout conversation={conversation()} panel={null} />,
135
+ );
136
+ // The corner is the only `top-2`-positioned element in the layout (the
137
+ // separator's inner hit target is also `absolute`, so match the corner).
138
+ expect(container.querySelector('[class*="top-2"]')).toBeNull();
139
+ });
140
+ });
@@ -193,6 +193,100 @@ describe("useCreateSession", () => {
193
193
  expect(callArg.executionTarget).toBeUndefined();
194
194
  });
195
195
 
196
+ describe("session metadata and sessionContext", () => {
197
+ it("passes the metadata map through to stigmer.session.create()", async () => {
198
+ const create = vi.fn().mockResolvedValue({ metadata: { id: "ses-md" } });
199
+ const client = createMockStigmer({ create });
200
+
201
+ const { result } = renderHook(() => useCreateSession(), {
202
+ wrapper: wrapper(client),
203
+ });
204
+
205
+ await act(async () => {
206
+ await result.current.create({
207
+ org: "acme",
208
+ agentInstanceId: "ain-123",
209
+ metadata: { "acme/tenant": "t-1" },
210
+ });
211
+ });
212
+
213
+ expect(create).toHaveBeenCalledWith(
214
+ expect.objectContaining({
215
+ metadata: { "acme/tenant": "t-1" },
216
+ }),
217
+ );
218
+ });
219
+
220
+ it("maps the typed sessionContext onto the reserved metadata key", async () => {
221
+ const create = vi.fn().mockResolvedValue({ metadata: { id: "ses-sc" } });
222
+ const client = createMockStigmer({ create });
223
+
224
+ const { result } = renderHook(() => useCreateSession(), {
225
+ wrapper: wrapper(client),
226
+ });
227
+
228
+ await act(async () => {
229
+ await result.current.create({
230
+ org: "acme",
231
+ agentInstanceId: "ain-123",
232
+ sessionContext: "Role: platform admin",
233
+ });
234
+ });
235
+
236
+ expect(create).toHaveBeenCalledWith(
237
+ expect.objectContaining({
238
+ metadata: { "stigmer.ai/session-context": "Role: platform admin" },
239
+ }),
240
+ );
241
+ });
242
+
243
+ it("lets the typed sessionContext win over a raw entry under the reserved key", async () => {
244
+ const create = vi.fn().mockResolvedValue({ metadata: { id: "ses-both" } });
245
+ const client = createMockStigmer({ create });
246
+
247
+ const { result } = renderHook(() => useCreateSession(), {
248
+ wrapper: wrapper(client),
249
+ });
250
+
251
+ await act(async () => {
252
+ await result.current.create({
253
+ org: "acme",
254
+ agentInstanceId: "ain-123",
255
+ metadata: {
256
+ "acme/tenant": "t-1",
257
+ "stigmer.ai/session-context": "stale raw value",
258
+ },
259
+ sessionContext: "typed value",
260
+ });
261
+ });
262
+
263
+ expect(create).toHaveBeenCalledWith(
264
+ expect.objectContaining({
265
+ metadata: {
266
+ "acme/tenant": "t-1",
267
+ "stigmer.ai/session-context": "typed value",
268
+ },
269
+ }),
270
+ );
271
+ });
272
+
273
+ it("omits metadata entirely when neither field is provided", async () => {
274
+ const create = vi.fn().mockResolvedValue({ metadata: { id: "ses-none" } });
275
+ const client = createMockStigmer({ create });
276
+
277
+ const { result } = renderHook(() => useCreateSession(), {
278
+ wrapper: wrapper(client),
279
+ });
280
+
281
+ await act(async () => {
282
+ await result.current.create({ org: "acme", agentInstanceId: "ain-123" });
283
+ });
284
+
285
+ const callArg = create.mock.calls[0][0];
286
+ expect(callArg.metadata).toBeUndefined();
287
+ });
288
+ });
289
+
196
290
  it("clearError resets the error state", async () => {
197
291
  const create = vi.fn().mockRejectedValue(new Error("fail"));
198
292
  const client = createMockStigmer({ create });
@@ -334,6 +334,39 @@ describe("useNewSessionFlow", () => {
334
334
  expect(execInput.sessionSpec.harness).toBe("cursor");
335
335
  });
336
336
 
337
+ it("forwards metadata and sessionContext verbatim in the sessionSpec", async () => {
338
+ // The typed-wins merge onto the reserved key happens downstream in
339
+ // useCreateAgentExecution (covered by its own tests); the flow's job
340
+ // is faithful forwarding.
341
+ const opts = {
342
+ ...defaultOptions(),
343
+ metadata: { "acme/tenant": "t-1" },
344
+ sessionContext: "Role: platform admin",
345
+ };
346
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: createWrapper() });
347
+
348
+ await act(async () => {
349
+ await result.current.submit("Hello");
350
+ });
351
+
352
+ const execInput = mockCreateExecution.mock.calls[0][0];
353
+ expect(execInput.sessionSpec.metadata).toEqual({ "acme/tenant": "t-1" });
354
+ expect(execInput.sessionSpec.sessionContext).toBe("Role: platform admin");
355
+ });
356
+
357
+ it("leaves metadata and sessionContext undefined when not provided", async () => {
358
+ const opts = defaultOptions();
359
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: createWrapper() });
360
+
361
+ await act(async () => {
362
+ await result.current.submit("Hello");
363
+ });
364
+
365
+ const execInput = mockCreateExecution.mock.calls[0][0];
366
+ expect(execInput.sessionSpec.metadata).toBeUndefined();
367
+ expect(execInput.sessionSpec.sessionContext).toBeUndefined();
368
+ });
369
+
337
370
  it("calls onSessionCreated with the server-assigned session id", async () => {
338
371
  const opts = defaultOptions();
339
372
  const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: createWrapper() });
@@ -109,6 +109,12 @@ export type { SessionViewerProps } from "./SessionViewer.js";
109
109
  export { NewSessionViewer } from "./NewSessionViewer.js";
110
110
  export type { NewSessionViewerProps } from "./NewSessionViewer.js";
111
111
 
112
+ // SessionViewerLayout — the conversation-plus-panel frame both viewers
113
+ // share, exported for platform builders composing a custom session surface
114
+ // at the shipped console's geometry.
115
+ export { SessionViewerLayout } from "./SessionViewerLayout.js";
116
+ export type { SessionViewerLayoutProps } from "./SessionViewerLayout.js";
117
+
112
118
  // Unified session-panel controller — drives the WorkspaceSurface open-editor
113
119
  // group, the collapsed/open state, and the rail-view FSM (for platform
114
120
  // builders embedding the surface directly).
@@ -118,6 +124,14 @@ export type {
118
124
  UseSessionPanelOptions,
119
125
  } from "./useSessionPanel.js";
120
126
 
127
+ // Session rail views — composes the session facets (Config / Changes /
128
+ // Artifacts / Usage) as the panel's rail, with the console's own labels,
129
+ // icons, badges, and contextual-visibility rules. Exported so custom
130
+ // session surfaces inherit the rail by construction instead of
131
+ // re-declaring it.
132
+ export { useSessionRailViews } from "./useSessionRailViews.js";
133
+ export type { UseSessionRailViewsOptions } from "./useSessionRailViews.js";
134
+
121
135
  // Plan draft — viewer-owned in-place edit of the session's current plan
122
136
  // (edit-as-input; the published plan.md artifact is never mutated).
123
137
  export { usePlanDraft, planDraftKey } from "./usePlanDraft.js";
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useState } from "react";
4
4
  import {
5
5
  PENDING_SUBJECT,
6
+ mergeSessionContext,
6
7
  type McpServerUsageInput,
7
8
  type ResourceRef,
8
9
  type WorkspaceEntryInput,
@@ -25,6 +26,34 @@ export interface SharedSessionFields {
25
26
  readonly mcpServerUsages?: McpServerUsageInput[];
26
27
  /** Skill references to enable for executions in this session. */
27
28
  readonly skillRefs?: ResourceRef[];
29
+ /**
30
+ * Custom key-value pairs stored on `SessionSpec.metadata`.
31
+ *
32
+ * A passthrough for embedder-owned keys (correlation IDs, tenant tags)
33
+ * and for platform-reserved `stigmer.ai/*` keys set explicitly. For the
34
+ * common case — standing user context injected into the agent's prompt —
35
+ * prefer the typed {@link sessionContext} field, which maps onto the
36
+ * reserved `stigmer.ai/session-context` key and wins over a raw entry
37
+ * under that key when both are provided.
38
+ */
39
+ readonly metadata?: Record<string, string>;
40
+ /**
41
+ * Standing, per-user context the agent receives on every turn but the
42
+ * conversation UI never renders — who the caller is, their experience
43
+ * level, their standing instructions (stigmer/stigmer#286).
44
+ *
45
+ * Stored on `SessionSpec.metadata` under `stigmer.ai/session-context`;
46
+ * the agent runner injects it into the system prompt as already-known
47
+ * background, so agents can greet the user by name and calibrate
48
+ * depth/defaults from the first turn without a visible context preamble.
49
+ *
50
+ * Personalization, not authorization: anyone who can create the session
51
+ * can set this (the same trust level as authoring the first message).
52
+ * Hidden from the conversation thread, not from the API — `session.get`
53
+ * returns it, so never put secrets here; secrets belong in `runtimeEnv`
54
+ * or Environment resources. Large values bloat every prompt.
55
+ */
56
+ readonly sessionContext?: string;
28
57
  /**
29
58
  * Execution harness for this session.
30
59
  *
@@ -172,6 +201,7 @@ export function useCreateSession(): UseCreateSessionReturn {
172
201
  workspaceEntries: input.workspaceEntries,
173
202
  mcpServerUsages: input.mcpServerUsages,
174
203
  skillRefs: input.skillRefs,
204
+ metadata: mergeSessionContext(input.metadata, input.sessionContext),
175
205
  agentInstanceId: resolvedInstanceId,
176
206
  harness: input.harness ? toProtoHarness(input.harness) : undefined,
177
207
  executionTarget: resolvedTarget
@@ -111,6 +111,36 @@ export interface UseNewSessionFlowOptions {
111
111
  * @default "integrator"
112
112
  */
113
113
  readonly audience?: SessionAudience;
114
+ /**
115
+ * Custom key-value pairs stored on the created session's
116
+ * `SessionSpec.metadata`.
117
+ *
118
+ * A passthrough for embedder-owned keys (correlation IDs, tenant tags)
119
+ * and for platform-reserved `stigmer.ai/*` keys set explicitly. For the
120
+ * common case — standing user context injected into the agent's prompt —
121
+ * prefer the typed {@link sessionContext} option, which maps onto the
122
+ * reserved `stigmer.ai/session-context` key and wins over a raw entry
123
+ * under that key when both are provided.
124
+ */
125
+ readonly metadata?: Record<string, string>;
126
+ /**
127
+ * Standing, per-user context the agent receives on every turn but the
128
+ * conversation UI never renders — who the caller is, their experience
129
+ * level, their standing instructions (stigmer/stigmer#286).
130
+ *
131
+ * Stored on the created session's `SessionSpec.metadata` under
132
+ * `stigmer.ai/session-context`; the agent runner injects it into the
133
+ * system prompt as already-known background, so agents can greet the
134
+ * user by name and calibrate depth/defaults from the first turn without
135
+ * a visible context preamble.
136
+ *
137
+ * Personalization, not authorization: anyone who can create the session
138
+ * can set this (the same trust level as authoring the first message).
139
+ * Hidden from the conversation thread, not from the API — `session.get`
140
+ * returns it, so never put secrets here; secrets belong in `runtimeEnv`
141
+ * or Environment resources. Large values bloat every prompt.
142
+ */
143
+ readonly sessionContext?: string;
114
144
  }
115
145
 
116
146
  /** Return value of {@link useNewSessionFlow}. */
@@ -217,7 +247,15 @@ export interface UseNewSessionFlowReturn {
217
247
  export function useNewSessionFlow(
218
248
  options: UseNewSessionFlowOptions,
219
249
  ): UseNewSessionFlowReturn {
220
- const { org, onSessionCreated, onError, getRuntimeEnv, defaultHarness } = options;
250
+ const {
251
+ org,
252
+ onSessionCreated,
253
+ onError,
254
+ getRuntimeEnv,
255
+ defaultHarness,
256
+ metadata,
257
+ sessionContext,
258
+ } = options;
221
259
  const isGuest = options.audience === "guest";
222
260
  const contextTarget = useExecutionTarget();
223
261
  const executionTarget = options.executionTarget ?? contextTarget;
@@ -336,6 +374,10 @@ export function useNewSessionFlow(
336
374
  : undefined,
337
375
  mcpServerUsages: mcpServerUsages.length > 0 ? mcpServerUsages : undefined,
338
376
  skillRefs: skillRefs.length > 0 ? skillRefs : undefined,
377
+ // The typed-wins merge happens downstream in useCreateAgentExecution;
378
+ // both fields are forwarded verbatim here.
379
+ metadata,
380
+ sessionContext,
339
381
  harness,
340
382
  executionTarget,
341
383
  };
@@ -440,6 +482,8 @@ export function useNewSessionFlow(
440
482
  workspace,
441
483
  mcpServerUsages,
442
484
  skillRefs,
485
+ metadata,
486
+ sessionContext,
443
487
  agentRef,
444
488
  resolution,
445
489
  defaultAgent,
@@ -55,13 +55,13 @@ export interface UseSessionRailViewsOptions {
55
55
  * (a cloud session with git workspace entries). When `true` the Changes
56
56
  * facet is offered from the start — with an honest pre-push state — instead
57
57
  * of only materializing once a write-back exists, so "where does my work
58
- * go?" always has an answer. See {@link ChangesTabProps.expectsWriteBack}.
58
+ * go?" always has an answer (the facet's `expectsWriteBack` prop).
59
59
  * @default false
60
60
  */
61
61
  readonly expectsWriteBack?: boolean;
62
62
  /**
63
63
  * Whether the session's latest execution is settled (terminal) — forwarded
64
- * to the Changes facet's pre-push states. See {@link ChangesTabProps.isSettled}.
64
+ * to the Changes facet's pre-push states (its `isSettled` prop).
65
65
  * @default false
66
66
  */
67
67
  readonly changesSettled?: boolean;
@@ -24,28 +24,47 @@ export interface UseUpdateSessionReturn {
24
24
  * {@link SessionInput} including the session's `name` and `org` (used
25
25
  * by the backend to identify the resource) and all spec fields.
26
26
  *
27
+ * **Full-replace semantics.** The backend replaces the entire spec with
28
+ * what you send — there is no field mask. Round-trip every spec field
29
+ * you do not intend to change, *including `metadata`*: an update built
30
+ * from a reconstructed partial spec silently wipes the fields it omits
31
+ * (workspace entries, MCP servers, and `stigmer.ai/*` metadata keys such
32
+ * as the embedder session context). To change only the subject, prefer
33
+ * the field-level `session.updateSubject()` RPC instead of this hook.
34
+ *
27
35
  * Typically composed into higher-level hooks like
28
- * {@link useSessionConversation} rather than used directly. Platform
29
- * builders who need direct session mutation can use this hook
30
- * standalone.
36
+ * {@link useSessionConversation} (whose update path round-trips the
37
+ * fetched spec) rather than used directly. Platform builders who need
38
+ * direct session mutation can use this hook standalone.
31
39
  *
32
40
  * @example
33
41
  * ```tsx
34
- * function RenameSession({ session }: { session: Session }) {
35
- * const { update, isUpdating, error } = useUpdateSession();
42
+ * function TagSession({ session }: { session: Session }) {
43
+ * const { update, isUpdating } = useUpdateSession();
36
44
  *
37
- * async function handleRename(newSubject: string) {
45
+ * async function handleTag() {
46
+ * const spec = session.spec;
38
47
  * await update({
39
48
  * name: session.metadata!.name,
40
49
  * org: session.metadata!.org,
41
- * agentInstanceId: session.spec?.agentInstanceId,
42
- * subject: newSubject,
50
+ * // Full replace: carry over every fetched spec field...
51
+ * agentInstanceId: spec?.agentInstanceId,
52
+ * subject: spec?.subject,
53
+ * harnessStateId: spec?.harnessStateId,
54
+ * harness: spec?.harness,
55
+ * cursorMode: spec?.cursorMode,
56
+ * executionTarget: spec?.executionTarget,
57
+ * // ...including the spec lists (workspaceEntries, mcpServerUsages,
58
+ * // skillRefs), converted from the fetched proto exactly as
59
+ * // useSessionConversation's update path does...
60
+ * // ...then apply the one change on top of the carried metadata.
61
+ * metadata: { ...spec?.metadata, "acme/reviewed": "true" },
43
62
  * });
44
63
  * }
45
64
  *
46
65
  * return (
47
- * <button onClick={() => handleRename("New subject")} disabled={isUpdating}>
48
- * Rename
66
+ * <button onClick={handleTag} disabled={isUpdating}>
67
+ * Mark reviewed
49
68
  * </button>
50
69
  * );
51
70
  * }
@@ -17,6 +17,8 @@ export interface UseSkillCountOptions {
17
17
  * @default "org"
18
18
  */
19
19
  readonly scope?: ResourceListScope;
20
+ /** Opaque token that forces a recount when its value changes. */
21
+ readonly refetchToken?: unknown;
20
22
  }
21
23
 
22
24
  /** Return value of {@link useSkillCount}. */