@stigmer/react 0.3.4 → 0.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 (450) hide show
  1. package/billing/AutoRechargeCard.d.ts +38 -0
  2. package/billing/AutoRechargeCard.d.ts.map +1 -0
  3. package/billing/AutoRechargeCard.js +90 -0
  4. package/billing/AutoRechargeCard.js.map +1 -0
  5. package/billing/BillingSection.d.ts +32 -0
  6. package/billing/BillingSection.d.ts.map +1 -0
  7. package/billing/BillingSection.js +81 -0
  8. package/billing/BillingSection.js.map +1 -0
  9. package/billing/CreditBalanceCard.d.ts +25 -0
  10. package/billing/CreditBalanceCard.d.ts.map +1 -0
  11. package/billing/CreditBalanceCard.js +28 -0
  12. package/billing/CreditBalanceCard.js.map +1 -0
  13. package/billing/CreditLedgerTable.d.ts +22 -0
  14. package/billing/CreditLedgerTable.d.ts.map +1 -0
  15. package/billing/CreditLedgerTable.js +75 -0
  16. package/billing/CreditLedgerTable.js.map +1 -0
  17. package/billing/CreditPackGrid.d.ts +31 -0
  18. package/billing/CreditPackGrid.d.ts.map +1 -0
  19. package/billing/CreditPackGrid.js +35 -0
  20. package/billing/CreditPackGrid.js.map +1 -0
  21. package/billing/LowBalanceBanner.d.ts +26 -0
  22. package/billing/LowBalanceBanner.d.ts.map +1 -0
  23. package/billing/LowBalanceBanner.js +33 -0
  24. package/billing/LowBalanceBanner.js.map +1 -0
  25. package/billing/PaymentMethodCard.d.ts +35 -0
  26. package/billing/PaymentMethodCard.d.ts.map +1 -0
  27. package/billing/PaymentMethodCard.js +48 -0
  28. package/billing/PaymentMethodCard.js.map +1 -0
  29. package/billing/credit-packs.d.ts +25 -0
  30. package/billing/credit-packs.d.ts.map +1 -0
  31. package/billing/credit-packs.js +39 -0
  32. package/billing/credit-packs.js.map +1 -0
  33. package/billing/format.d.ts +39 -0
  34. package/billing/format.d.ts.map +1 -0
  35. package/billing/format.js +90 -0
  36. package/billing/format.js.map +1 -0
  37. package/billing/index.d.ts +32 -0
  38. package/billing/index.d.ts.map +1 -0
  39. package/billing/index.js +21 -0
  40. package/billing/index.js.map +1 -0
  41. package/billing/useBillingAccount.d.ts +40 -0
  42. package/billing/useBillingAccount.d.ts.map +1 -0
  43. package/billing/useBillingAccount.js +35 -0
  44. package/billing/useBillingAccount.js.map +1 -0
  45. package/billing/useBillingUsageReport.d.ts +42 -0
  46. package/billing/useBillingUsageReport.d.ts.map +1 -0
  47. package/billing/useBillingUsageReport.js +43 -0
  48. package/billing/useBillingUsageReport.js.map +1 -0
  49. package/billing/useCreateBillingPortalSession.d.ts +35 -0
  50. package/billing/useCreateBillingPortalSession.d.ts.map +1 -0
  51. package/billing/useCreateBillingPortalSession.js +50 -0
  52. package/billing/useCreateBillingPortalSession.js.map +1 -0
  53. package/billing/useCreateCheckoutSession.d.ts +54 -0
  54. package/billing/useCreateCheckoutSession.d.ts.map +1 -0
  55. package/billing/useCreateCheckoutSession.js +58 -0
  56. package/billing/useCreateCheckoutSession.js.map +1 -0
  57. package/billing/useCreditLedger.d.ts +48 -0
  58. package/billing/useCreditLedger.d.ts.map +1 -0
  59. package/billing/useCreditLedger.js +39 -0
  60. package/billing/useCreditLedger.js.map +1 -0
  61. package/billing/useCustomerModelPricing.d.ts +41 -0
  62. package/billing/useCustomerModelPricing.d.ts.map +1 -0
  63. package/billing/useCustomerModelPricing.js +37 -0
  64. package/billing/useCustomerModelPricing.js.map +1 -0
  65. package/billing/useSetAutoRechargeConfig.d.ts +50 -0
  66. package/billing/useSetAutoRechargeConfig.d.ts.map +1 -0
  67. package/billing/useSetAutoRechargeConfig.js +53 -0
  68. package/billing/useSetAutoRechargeConfig.js.map +1 -0
  69. package/composer/ComposerToolbar.js +1 -1
  70. package/composer/ComposerToolbar.js.map +1 -1
  71. package/composer/SessionComposer.d.ts +1 -1
  72. package/composer/SessionComposer.d.ts.map +1 -1
  73. package/composer/SessionComposer.js +19 -4
  74. package/composer/SessionComposer.js.map +1 -1
  75. package/composer/__tests__/SessionComposer-memo.test.d.ts +2 -0
  76. package/composer/__tests__/SessionComposer-memo.test.d.ts.map +1 -0
  77. package/composer/__tests__/SessionComposer-memo.test.js +23 -0
  78. package/composer/__tests__/SessionComposer-memo.test.js.map +1 -0
  79. package/execution/ApprovalCard.d.ts +5 -1
  80. package/execution/ApprovalCard.d.ts.map +1 -1
  81. package/execution/ApprovalCard.js +7 -3
  82. package/execution/ApprovalCard.js.map +1 -1
  83. package/execution/ExecutionPhaseBadge.d.ts +1 -1
  84. package/execution/ExecutionPhaseBadge.d.ts.map +1 -1
  85. package/execution/ExecutionPhaseBadge.js +3 -2
  86. package/execution/ExecutionPhaseBadge.js.map +1 -1
  87. package/execution/MessageEntry.d.ts +7 -3
  88. package/execution/MessageEntry.d.ts.map +1 -1
  89. package/execution/MessageEntry.js +19 -8
  90. package/execution/MessageEntry.js.map +1 -1
  91. package/execution/MessageThread.d.ts +84 -3
  92. package/execution/MessageThread.d.ts.map +1 -1
  93. package/execution/MessageThread.js +113 -65
  94. package/execution/MessageThread.js.map +1 -1
  95. package/execution/SetupProgress.d.ts +1 -1
  96. package/execution/SetupProgress.d.ts.map +1 -1
  97. package/execution/SetupProgress.js +3 -3
  98. package/execution/SetupProgress.js.map +1 -1
  99. package/execution/SubAgentSection.d.ts +5 -1
  100. package/execution/SubAgentSection.d.ts.map +1 -1
  101. package/execution/SubAgentSection.js +13 -7
  102. package/execution/SubAgentSection.js.map +1 -1
  103. package/execution/ThreadSkeleton.d.ts +22 -0
  104. package/execution/ThreadSkeleton.d.ts.map +1 -0
  105. package/execution/ThreadSkeleton.js +26 -0
  106. package/execution/ThreadSkeleton.js.map +1 -0
  107. package/execution/ToolCallGroup.d.ts +16 -1
  108. package/execution/ToolCallGroup.d.ts.map +1 -1
  109. package/execution/ToolCallGroup.js +31 -3
  110. package/execution/ToolCallGroup.js.map +1 -1
  111. package/execution/UsageWidget.d.ts +1 -1
  112. package/execution/__tests__/message-entry.test.d.ts +2 -0
  113. package/execution/__tests__/message-entry.test.d.ts.map +1 -0
  114. package/execution/__tests__/message-entry.test.js +178 -0
  115. package/execution/__tests__/message-entry.test.js.map +1 -0
  116. package/execution/__tests__/thread-keys.test.d.ts +2 -0
  117. package/execution/__tests__/thread-keys.test.d.ts.map +1 -0
  118. package/execution/__tests__/thread-keys.test.js +289 -0
  119. package/execution/__tests__/thread-keys.test.js.map +1 -0
  120. package/execution/__tests__/thread-memoization.test.d.ts +2 -0
  121. package/execution/__tests__/thread-memoization.test.d.ts.map +1 -0
  122. package/execution/__tests__/thread-memoization.test.js +262 -0
  123. package/execution/__tests__/thread-memoization.test.js.map +1 -0
  124. package/execution/__tests__/thread-skeleton.test.d.ts +2 -0
  125. package/execution/__tests__/thread-skeleton.test.d.ts.map +1 -0
  126. package/execution/__tests__/thread-skeleton.test.js +35 -0
  127. package/execution/__tests__/thread-skeleton.test.js.map +1 -0
  128. package/execution/__tests__/useExecutionStream.test.js +73 -10
  129. package/execution/__tests__/useExecutionStream.test.js.map +1 -1
  130. package/execution/__tests__/useSessionVariables-stability.test.d.ts +2 -0
  131. package/execution/__tests__/useSessionVariables-stability.test.d.ts.map +1 -0
  132. package/execution/__tests__/useSessionVariables-stability.test.js +69 -0
  133. package/execution/__tests__/useSessionVariables-stability.test.js.map +1 -0
  134. package/execution/__tests__/virtualized-thread.test.d.ts +2 -0
  135. package/execution/__tests__/virtualized-thread.test.d.ts.map +1 -0
  136. package/execution/__tests__/virtualized-thread.test.js +274 -0
  137. package/execution/__tests__/virtualized-thread.test.js.map +1 -0
  138. package/execution/index.d.ts +2 -0
  139. package/execution/index.d.ts.map +1 -1
  140. package/execution/index.js +1 -0
  141. package/execution/index.js.map +1 -1
  142. package/execution/useExecutionStream.d.ts +35 -10
  143. package/execution/useExecutionStream.d.ts.map +1 -1
  144. package/execution/useExecutionStream.js +79 -40
  145. package/execution/useExecutionStream.js.map +1 -1
  146. package/execution/useSessionVariables.d.ts.map +1 -1
  147. package/execution/useSessionVariables.js +4 -3
  148. package/execution/useSessionVariables.js.map +1 -1
  149. package/github/useGitHubConnection.d.ts.map +1 -1
  150. package/github/useGitHubConnection.js +5 -4
  151. package/github/useGitHubConnection.js.map +1 -1
  152. package/identity-account/index.d.ts +2 -0
  153. package/identity-account/index.d.ts.map +1 -0
  154. package/identity-account/index.js +2 -0
  155. package/identity-account/index.js.map +1 -0
  156. package/identity-account/useIdentityAccountGate.d.ts +81 -0
  157. package/identity-account/useIdentityAccountGate.d.ts.map +1 -0
  158. package/identity-account/useIdentityAccountGate.js +100 -0
  159. package/identity-account/useIdentityAccountGate.js.map +1 -0
  160. package/index.d.ts +10 -4
  161. package/index.d.ts.map +1 -1
  162. package/index.js +8 -2
  163. package/index.js.map +1 -1
  164. package/internal/FetchCacheProvider.d.ts +44 -0
  165. package/internal/FetchCacheProvider.d.ts.map +1 -0
  166. package/internal/FetchCacheProvider.js +61 -0
  167. package/internal/FetchCacheProvider.js.map +1 -0
  168. package/internal/JumpToLatestButton.d.ts +14 -0
  169. package/internal/JumpToLatestButton.d.ts.map +1 -0
  170. package/internal/JumpToLatestButton.js +19 -0
  171. package/internal/JumpToLatestButton.js.map +1 -0
  172. package/internal/ThreadItemWrapper.d.ts +20 -0
  173. package/internal/ThreadItemWrapper.d.ts.map +1 -0
  174. package/internal/ThreadItemWrapper.js +44 -0
  175. package/internal/ThreadItemWrapper.js.map +1 -0
  176. package/internal/VirtualizedThread.d.ts +25 -0
  177. package/internal/VirtualizedThread.d.ts.map +1 -0
  178. package/internal/VirtualizedThread.js +58 -0
  179. package/internal/VirtualizedThread.js.map +1 -0
  180. package/internal/__tests__/fetch-cache.test.d.ts +2 -0
  181. package/internal/__tests__/fetch-cache.test.d.ts.map +1 -0
  182. package/internal/__tests__/fetch-cache.test.js +182 -0
  183. package/internal/__tests__/fetch-cache.test.js.map +1 -0
  184. package/internal/__tests__/stream-controller.test.d.ts +2 -0
  185. package/internal/__tests__/stream-controller.test.d.ts.map +1 -0
  186. package/internal/__tests__/stream-controller.test.js +294 -0
  187. package/internal/__tests__/stream-controller.test.js.map +1 -0
  188. package/internal/__tests__/thread-animation.test.d.ts +2 -0
  189. package/internal/__tests__/thread-animation.test.d.ts.map +1 -0
  190. package/internal/__tests__/thread-animation.test.js +79 -0
  191. package/internal/__tests__/thread-animation.test.js.map +1 -0
  192. package/internal/__tests__/useAutoScroll.test.d.ts +2 -0
  193. package/internal/__tests__/useAutoScroll.test.d.ts.map +1 -0
  194. package/internal/__tests__/useAutoScroll.test.js +188 -0
  195. package/internal/__tests__/useAutoScroll.test.js.map +1 -0
  196. package/internal/__tests__/useFetch-cache.test.d.ts +2 -0
  197. package/internal/__tests__/useFetch-cache.test.d.ts.map +1 -0
  198. package/internal/__tests__/useFetch-cache.test.js +137 -0
  199. package/internal/__tests__/useFetch-cache.test.js.map +1 -0
  200. package/internal/dev/__tests__/use-key-stability.test.d.ts +2 -0
  201. package/internal/dev/__tests__/use-key-stability.test.d.ts.map +1 -0
  202. package/internal/dev/__tests__/use-key-stability.test.js +72 -0
  203. package/internal/dev/__tests__/use-key-stability.test.js.map +1 -0
  204. package/internal/dev/__tests__/use-render-tracer.test.d.ts +2 -0
  205. package/internal/dev/__tests__/use-render-tracer.test.d.ts.map +1 -0
  206. package/internal/dev/__tests__/use-render-tracer.test.js +55 -0
  207. package/internal/dev/__tests__/use-render-tracer.test.js.map +1 -0
  208. package/internal/dev/dom-counter.d.ts +14 -0
  209. package/internal/dev/dom-counter.d.ts.map +1 -0
  210. package/internal/dev/dom-counter.js +39 -0
  211. package/internal/dev/dom-counter.js.map +1 -0
  212. package/internal/dev/index.d.ts +6 -0
  213. package/internal/dev/index.d.ts.map +1 -0
  214. package/internal/dev/index.js +6 -0
  215. package/internal/dev/index.js.map +1 -0
  216. package/internal/dev/profiler-wrapper.d.ts +16 -0
  217. package/internal/dev/profiler-wrapper.d.ts.map +1 -0
  218. package/internal/dev/profiler-wrapper.js +31 -0
  219. package/internal/dev/profiler-wrapper.js.map +1 -0
  220. package/internal/dev/use-key-stability.d.ts +22 -0
  221. package/internal/dev/use-key-stability.d.ts.map +1 -0
  222. package/internal/dev/use-key-stability.js +67 -0
  223. package/internal/dev/use-key-stability.js.map +1 -0
  224. package/internal/dev/use-render-tracer.d.ts +13 -0
  225. package/internal/dev/use-render-tracer.d.ts.map +1 -0
  226. package/internal/dev/use-render-tracer.js +57 -0
  227. package/internal/dev/use-render-tracer.js.map +1 -0
  228. package/internal/dev/use-stream-rate.d.ts +23 -0
  229. package/internal/dev/use-stream-rate.d.ts.map +1 -0
  230. package/internal/dev/use-stream-rate.js +94 -0
  231. package/internal/dev/use-stream-rate.js.map +1 -0
  232. package/internal/fetch-cache.d.ts +72 -0
  233. package/internal/fetch-cache.d.ts.map +1 -0
  234. package/internal/fetch-cache.js +118 -0
  235. package/internal/fetch-cache.js.map +1 -0
  236. package/internal/store/__tests__/conversation-store.test.d.ts +2 -0
  237. package/internal/store/__tests__/conversation-store.test.d.ts.map +1 -0
  238. package/internal/store/__tests__/conversation-store.test.js +200 -0
  239. package/internal/store/__tests__/conversation-store.test.js.map +1 -0
  240. package/internal/store/__tests__/structural-share.test.d.ts +2 -0
  241. package/internal/store/__tests__/structural-share.test.d.ts.map +1 -0
  242. package/internal/store/__tests__/structural-share.test.js +368 -0
  243. package/internal/store/__tests__/structural-share.test.js.map +1 -0
  244. package/internal/store/conversation-store.d.ts +62 -0
  245. package/internal/store/conversation-store.d.ts.map +1 -0
  246. package/internal/store/conversation-store.js +95 -0
  247. package/internal/store/conversation-store.js.map +1 -0
  248. package/internal/store/index.d.ts +31 -0
  249. package/internal/store/index.d.ts.map +1 -0
  250. package/internal/store/index.js +54 -0
  251. package/internal/store/index.js.map +1 -0
  252. package/internal/store/structural-share.d.ts +13 -0
  253. package/internal/store/structural-share.d.ts.map +1 -0
  254. package/internal/store/structural-share.js +240 -0
  255. package/internal/store/structural-share.js.map +1 -0
  256. package/internal/stream-controller.d.ts +85 -0
  257. package/internal/stream-controller.d.ts.map +1 -0
  258. package/internal/stream-controller.js +146 -0
  259. package/internal/stream-controller.js.map +1 -0
  260. package/internal/useAutoScroll.d.ts +32 -0
  261. package/internal/useAutoScroll.d.ts.map +1 -0
  262. package/internal/useAutoScroll.js +97 -0
  263. package/internal/useAutoScroll.js.map +1 -0
  264. package/internal/useFetch.d.ts +14 -0
  265. package/internal/useFetch.d.ts.map +1 -1
  266. package/internal/useFetch.js +32 -2
  267. package/internal/useFetch.js.map +1 -1
  268. package/mcp-server/McpServerDetailView.d.ts.map +1 -1
  269. package/mcp-server/McpServerDetailView.js +3 -3
  270. package/mcp-server/McpServerDetailView.js.map +1 -1
  271. package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
  272. package/mcp-server/useMcpServerOAuthConnect.js +37 -9
  273. package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
  274. package/package.json +7 -5
  275. package/session/__tests__/useNewSessionFlow.test.js +16 -0
  276. package/session/__tests__/useNewSessionFlow.test.js.map +1 -1
  277. package/session/__tests__/usePersistedModel.test.d.ts +2 -0
  278. package/session/__tests__/usePersistedModel.test.d.ts.map +1 -0
  279. package/session/__tests__/usePersistedModel.test.js +82 -0
  280. package/session/__tests__/usePersistedModel.test.js.map +1 -0
  281. package/session/__tests__/useSession.test.d.ts +2 -0
  282. package/session/__tests__/useSession.test.d.ts.map +1 -0
  283. package/session/__tests__/useSession.test.js +130 -0
  284. package/session/__tests__/useSession.test.js.map +1 -0
  285. package/session/useNewSessionFlow.d.ts.map +1 -1
  286. package/session/useNewSessionFlow.js +12 -6
  287. package/session/useNewSessionFlow.js.map +1 -1
  288. package/session/usePersistedModel.d.ts +3 -0
  289. package/session/usePersistedModel.d.ts.map +1 -1
  290. package/session/usePersistedModel.js +27 -2
  291. package/session/usePersistedModel.js.map +1 -1
  292. package/session/useSession.d.ts.map +1 -1
  293. package/session/useSession.js +1 -1
  294. package/session/useSession.js.map +1 -1
  295. package/session/useSessionConversation.d.ts.map +1 -1
  296. package/session/useSessionConversation.js +9 -1
  297. package/session/useSessionConversation.js.map +1 -1
  298. package/session/useSessionExecutions.d.ts.map +1 -1
  299. package/session/useSessionExecutions.js +1 -1
  300. package/session/useSessionExecutions.js.map +1 -1
  301. package/session/useSessionPageFlow.js +1 -1
  302. package/session/useSessionPageFlow.js.map +1 -1
  303. package/session/useSessionUsage.d.ts +24 -40
  304. package/session/useSessionUsage.d.ts.map +1 -1
  305. package/session/useSessionUsage.js +64 -97
  306. package/session/useSessionUsage.js.map +1 -1
  307. package/settings/BillingSection.d.ts +3 -0
  308. package/settings/BillingSection.d.ts.map +1 -0
  309. package/settings/BillingSection.js +3 -0
  310. package/settings/BillingSection.js.map +1 -0
  311. package/settings/index.d.ts +2 -0
  312. package/settings/index.d.ts.map +1 -1
  313. package/settings/index.js +1 -0
  314. package/settings/index.js.map +1 -1
  315. package/settings/settings-nav.js +1 -1
  316. package/settings/settings-nav.js.map +1 -1
  317. package/src/billing/AutoRechargeCard.tsx +274 -0
  318. package/src/billing/BillingSection.tsx +255 -0
  319. package/src/billing/CreditBalanceCard.tsx +81 -0
  320. package/src/billing/CreditLedgerTable.tsx +281 -0
  321. package/src/billing/CreditPackGrid.tsx +132 -0
  322. package/src/billing/LowBalanceBanner.tsx +67 -0
  323. package/src/billing/PaymentMethodCard.tsx +133 -0
  324. package/src/billing/credit-packs.ts +54 -0
  325. package/src/billing/format.ts +97 -0
  326. package/src/billing/index.ts +51 -0
  327. package/src/billing/useBillingAccount.ts +64 -0
  328. package/src/billing/useBillingUsageReport.ts +73 -0
  329. package/src/billing/useCreateBillingPortalSession.ts +76 -0
  330. package/src/billing/useCreateCheckoutSession.ts +101 -0
  331. package/src/billing/useCreditLedger.ts +79 -0
  332. package/src/billing/useCustomerModelPricing.ts +67 -0
  333. package/src/billing/useSetAutoRechargeConfig.ts +90 -0
  334. package/src/composer/ComposerToolbar.tsx +1 -1
  335. package/src/composer/SessionComposer.tsx +22 -4
  336. package/src/composer/__tests__/SessionComposer-memo.test.ts +26 -0
  337. package/src/execution/ApprovalCard.tsx +7 -3
  338. package/src/execution/ExecutionPhaseBadge.tsx +3 -2
  339. package/src/execution/MessageEntry.tsx +27 -16
  340. package/src/execution/MessageThread.tsx +308 -131
  341. package/src/execution/SetupProgress.tsx +3 -3
  342. package/src/execution/SubAgentSection.tsx +14 -6
  343. package/src/execution/ThreadSkeleton.tsx +73 -0
  344. package/src/execution/ToolCallGroup.tsx +36 -3
  345. package/src/execution/UsageWidget.tsx +1 -1
  346. package/src/execution/__tests__/message-entry.test.tsx +236 -0
  347. package/src/execution/__tests__/thread-keys.test.ts +409 -0
  348. package/src/execution/__tests__/thread-memoization.test.ts +320 -0
  349. package/src/execution/__tests__/thread-skeleton.test.tsx +44 -0
  350. package/src/execution/__tests__/useExecutionStream.test.tsx +109 -12
  351. package/src/execution/__tests__/useSessionVariables-stability.test.ts +95 -0
  352. package/src/execution/__tests__/virtualized-thread.test.tsx +401 -0
  353. package/src/execution/index.ts +3 -0
  354. package/src/execution/useExecutionStream.ts +123 -48
  355. package/src/execution/useSessionVariables.ts +17 -12
  356. package/src/github/useGitHubConnection.ts +18 -13
  357. package/src/identity-account/index.ts +5 -0
  358. package/src/identity-account/useIdentityAccountGate.ts +163 -0
  359. package/src/index.ts +73 -0
  360. package/src/internal/FetchCacheProvider.tsx +74 -0
  361. package/src/internal/JumpToLatestButton.tsx +61 -0
  362. package/src/internal/ThreadItemWrapper.tsx +65 -0
  363. package/src/internal/VirtualizedThread.tsx +162 -0
  364. package/src/internal/__tests__/fetch-cache.test.ts +230 -0
  365. package/src/internal/__tests__/stream-controller.test.ts +395 -0
  366. package/src/internal/__tests__/thread-animation.test.tsx +121 -0
  367. package/src/internal/__tests__/useAutoScroll.test.tsx +261 -0
  368. package/src/internal/__tests__/useFetch-cache.test.ts +214 -0
  369. package/src/internal/dev/__tests__/use-key-stability.test.ts +124 -0
  370. package/src/internal/dev/__tests__/use-render-tracer.test.ts +78 -0
  371. package/src/internal/dev/dom-counter.ts +47 -0
  372. package/src/internal/dev/index.ts +5 -0
  373. package/src/internal/dev/profiler-wrapper.tsx +52 -0
  374. package/src/internal/dev/use-key-stability.ts +86 -0
  375. package/src/internal/dev/use-render-tracer.ts +70 -0
  376. package/src/internal/dev/use-stream-rate.ts +138 -0
  377. package/src/internal/fetch-cache.ts +155 -0
  378. package/src/internal/store/__tests__/conversation-store.test.ts +257 -0
  379. package/src/internal/store/__tests__/structural-share.test.ts +454 -0
  380. package/src/internal/store/conversation-store.ts +128 -0
  381. package/src/internal/store/index.ts +68 -0
  382. package/src/internal/store/structural-share.ts +318 -0
  383. package/src/internal/stream-controller.ts +201 -0
  384. package/src/internal/useAutoScroll.ts +121 -0
  385. package/src/internal/useFetch.ts +51 -2
  386. package/src/mcp-server/McpServerDetailView.tsx +15 -0
  387. package/src/mcp-server/useMcpServerOAuthConnect.ts +37 -9
  388. package/src/session/__tests__/useNewSessionFlow.test.tsx +22 -0
  389. package/src/session/__tests__/usePersistedModel.test.tsx +117 -0
  390. package/src/session/__tests__/useSession.test.tsx +187 -0
  391. package/src/session/useNewSessionFlow.ts +12 -6
  392. package/src/session/usePersistedModel.ts +28 -2
  393. package/src/session/useSession.ts +1 -0
  394. package/src/session/useSessionConversation.ts +11 -2
  395. package/src/session/useSessionExecutions.ts +1 -0
  396. package/src/session/useSessionPageFlow.ts +1 -1
  397. package/src/session/useSessionUsage.ts +102 -123
  398. package/src/settings/BillingSection.tsx +4 -0
  399. package/src/settings/index.ts +2 -0
  400. package/src/settings/settings-nav.ts +1 -1
  401. package/src/styles.css +31 -0
  402. package/src/usage/AgentBreakdownList.tsx +147 -0
  403. package/src/usage/CreditRunwayIndicator.tsx +71 -0
  404. package/src/usage/ExportButton.tsx +115 -0
  405. package/src/usage/HarnessSplitCard.tsx +103 -0
  406. package/src/usage/OrgUsagePanel.tsx +109 -45
  407. package/src/usage/index.ts +15 -0
  408. package/src/usage/useExportCSV.ts +115 -0
  409. package/src/usage/useOrgUsageReport.ts +2 -1
  410. package/src/workspace/__tests__/useWorkspaceEntries-stability.test.ts +76 -0
  411. package/src/workspace/useWorkspaceEntries.ts +16 -11
  412. package/styles.css +1 -1
  413. package/usage/AgentBreakdownList.d.ts +21 -0
  414. package/usage/AgentBreakdownList.d.ts.map +1 -0
  415. package/usage/AgentBreakdownList.js +44 -0
  416. package/usage/AgentBreakdownList.js.map +1 -0
  417. package/usage/CreditRunwayIndicator.d.ts +21 -0
  418. package/usage/CreditRunwayIndicator.d.ts.map +1 -0
  419. package/usage/CreditRunwayIndicator.js +38 -0
  420. package/usage/CreditRunwayIndicator.js.map +1 -0
  421. package/usage/ExportButton.d.ts +20 -0
  422. package/usage/ExportButton.d.ts.map +1 -0
  423. package/usage/ExportButton.js +36 -0
  424. package/usage/ExportButton.js.map +1 -0
  425. package/usage/HarnessSplitCard.d.ts +17 -0
  426. package/usage/HarnessSplitCard.d.ts.map +1 -0
  427. package/usage/HarnessSplitCard.js +38 -0
  428. package/usage/HarnessSplitCard.js.map +1 -0
  429. package/usage/OrgUsagePanel.d.ts.map +1 -1
  430. package/usage/OrgUsagePanel.js +30 -22
  431. package/usage/OrgUsagePanel.js.map +1 -1
  432. package/usage/index.d.ts +10 -0
  433. package/usage/index.d.ts.map +1 -1
  434. package/usage/index.js +5 -0
  435. package/usage/index.js.map +1 -1
  436. package/usage/useExportCSV.d.ts +23 -0
  437. package/usage/useExportCSV.d.ts.map +1 -0
  438. package/usage/useExportCSV.js +81 -0
  439. package/usage/useExportCSV.js.map +1 -0
  440. package/usage/useOrgUsageReport.d.ts +2 -1
  441. package/usage/useOrgUsageReport.d.ts.map +1 -1
  442. package/usage/useOrgUsageReport.js +2 -1
  443. package/usage/useOrgUsageReport.js.map +1 -1
  444. package/workspace/__tests__/useWorkspaceEntries-stability.test.d.ts +2 -0
  445. package/workspace/__tests__/useWorkspaceEntries-stability.test.d.ts.map +1 -0
  446. package/workspace/__tests__/useWorkspaceEntries-stability.test.js +57 -0
  447. package/workspace/__tests__/useWorkspaceEntries-stability.test.js.map +1 -0
  448. package/workspace/useWorkspaceEntries.d.ts.map +1 -1
  449. package/workspace/useWorkspaceEntries.js +5 -4
  450. package/workspace/useWorkspaceEntries.js.map +1 -1
@@ -0,0 +1,255 @@
1
+ "use client";
2
+
3
+ import { useState, useCallback } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage } from "@stigmer/sdk";
6
+ import { BillingAccountStatus } from "@stigmer/protos/ai/stigmer/billing/v1/enum_pb";
7
+ import { useDeploymentMode } from "../deployment-mode";
8
+ import { CloudFeatureNotice } from "../internal/CloudFeatureNotice";
9
+ import { useOrg } from "../organization/OrgProvider";
10
+ import { useBillingAccount } from "./useBillingAccount";
11
+ import { useCreateCheckoutSession } from "./useCreateCheckoutSession";
12
+ import { useCreateBillingPortalSession } from "./useCreateBillingPortalSession";
13
+ import { CreditBalanceCard } from "./CreditBalanceCard";
14
+ import { PaymentMethodCard } from "./PaymentMethodCard";
15
+ import { AutoRechargeCard } from "./AutoRechargeCard";
16
+ import { CreditPackGrid } from "./CreditPackGrid";
17
+ import { CreditLedgerTable } from "./CreditLedgerTable";
18
+ import { LowBalanceBanner } from "./LowBalanceBanner";
19
+
20
+ /** Props for {@link BillingSection}. */
21
+ export interface BillingSectionProps {
22
+ /**
23
+ * Whether a checkout just completed (e.g., `?checkout=success`).
24
+ *
25
+ * When `true`, an optimistic banner is shown indicating that
26
+ * credits will appear shortly. This prop is typically driven
27
+ * by the host application's URL query parameters.
28
+ */
29
+ readonly checkoutSuccess?: boolean;
30
+ /** Callback to dismiss the checkout success banner. */
31
+ readonly onDismissCheckoutSuccess?: () => void;
32
+ /** Additional CSS class names. */
33
+ readonly className?: string;
34
+ }
35
+
36
+ /**
37
+ * Top-level billing settings section.
38
+ *
39
+ * Composes the billing sub-components into a cohesive settings page:
40
+ * low-balance warning, checkout success banner, credit balance display,
41
+ * credit pack purchase grid, and transaction history. Handles the
42
+ * deployment mode gate (billing unavailable in local mode) and the
43
+ * org-not-selected state.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * // In a settings page:
48
+ * <BillingSection checkoutSuccess={searchParams.checkout === "success"} />
49
+ * ```
50
+ */
51
+ export function BillingSection({
52
+ checkoutSuccess,
53
+ onDismissCheckoutSuccess,
54
+ className,
55
+ }: BillingSectionProps) {
56
+ const { activeOrg } = useOrg();
57
+ const mode = useDeploymentMode();
58
+ const orgId = activeOrg?.metadata?.id ?? "";
59
+
60
+ return (
61
+ <section aria-labelledby="billing-heading" className={className}>
62
+ <h2
63
+ id="billing-heading"
64
+ className="text-foreground mb-1 text-sm font-semibold"
65
+ >
66
+ Billing
67
+ </h2>
68
+ <p className="text-muted-foreground mb-4 text-xs">
69
+ Manage credits, purchase credit packs, and view transaction history.
70
+ </p>
71
+
72
+ {mode === "local" ? (
73
+ <CloudFeatureNotice>
74
+ Billing is available on Stigmer Cloud. Connect to a Cloud
75
+ organization to manage credits and purchase credit packs.
76
+ </CloudFeatureNotice>
77
+ ) : !orgId ? (
78
+ <p className="text-muted-foreground py-4 text-center text-xs">
79
+ Select an organization to view billing.
80
+ </p>
81
+ ) : (
82
+ <BillingContent
83
+ orgId={orgId}
84
+ checkoutSuccess={checkoutSuccess}
85
+ onDismissCheckoutSuccess={onDismissCheckoutSuccess}
86
+ />
87
+ )}
88
+ </section>
89
+ );
90
+ }
91
+
92
+ // ---------------------------------------------------------------------------
93
+ // BillingContent (internal)
94
+ // ---------------------------------------------------------------------------
95
+
96
+ function BillingContent({
97
+ orgId,
98
+ checkoutSuccess,
99
+ onDismissCheckoutSuccess,
100
+ }: {
101
+ orgId: string;
102
+ checkoutSuccess?: boolean;
103
+ onDismissCheckoutSuccess?: () => void;
104
+ }) {
105
+ const { account, isLoading, error, refetch } = useBillingAccount(orgId);
106
+ const { createSession, isSubmitting, error: checkoutError, clearError } = useCreateCheckoutSession();
107
+ const { openPortal, isLoading: isPortalLoading } = useCreateBillingPortalSession();
108
+ const [purchasingPackId, setPurchasingPackId] = useState<string | null>(null);
109
+
110
+ const handlePurchase = useCallback(
111
+ (packId: string) => {
112
+ setPurchasingPackId(packId);
113
+ clearError();
114
+
115
+ const baseUrl = typeof window !== "undefined" ? window.location.origin : "";
116
+ const billingPath = `${baseUrl}/settings/billing`;
117
+
118
+ createSession({
119
+ orgId,
120
+ packId,
121
+ successUrl: `${billingPath}?checkout=success`,
122
+ cancelUrl: billingPath,
123
+ }).catch(() => {
124
+ setPurchasingPackId(null);
125
+ });
126
+ },
127
+ [orgId, createSession, clearError],
128
+ );
129
+
130
+ if (isLoading) {
131
+ return (
132
+ <div className="space-y-4" aria-busy="true" aria-label="Loading billing">
133
+ <div className="h-24 animate-pulse rounded-lg bg-muted-subtle" />
134
+ <div className="grid grid-cols-3 gap-3">
135
+ {Array.from({ length: 3 }, (_, i) => (
136
+ <div
137
+ key={i}
138
+ className="h-36 animate-pulse rounded-lg bg-muted-subtle"
139
+ />
140
+ ))}
141
+ </div>
142
+ <div className="h-48 animate-pulse rounded-lg bg-muted-subtle" />
143
+ </div>
144
+ );
145
+ }
146
+
147
+ if (error) {
148
+ return (
149
+ <p className="text-destructive text-xs" role="alert">
150
+ {getUserMessage(error)}
151
+ </p>
152
+ );
153
+ }
154
+
155
+ if (!account) return null;
156
+
157
+ const balance = account.balance;
158
+ if (!balance) return null;
159
+
160
+ const isLowBalance =
161
+ balance.availableMicros < account.lowBalanceThresholdMicros;
162
+
163
+ return (
164
+ <div className="space-y-6">
165
+ {checkoutSuccess && (
166
+ <CheckoutSuccessBanner onDismiss={onDismissCheckoutSuccess} />
167
+ )}
168
+
169
+ <LowBalanceBanner
170
+ availableMicros={balance.availableMicros}
171
+ thresholdMicros={account.lowBalanceThresholdMicros}
172
+ />
173
+
174
+ <CreditBalanceCard balance={balance} isLowBalance={isLowBalance} />
175
+
176
+ <PaymentMethodCard
177
+ paymentMethod={account.defaultPaymentMethod}
178
+ accountStatus={account.status}
179
+ isPortalLoading={isPortalLoading}
180
+ onManage={() => openPortal(orgId)}
181
+ />
182
+
183
+ <AutoRechargeCard
184
+ orgId={orgId}
185
+ autoRecharge={account.autoRecharge}
186
+ hasPaymentMethod={
187
+ account.defaultPaymentMethod != null &&
188
+ account.defaultPaymentMethod.paymentMethodId !== ""
189
+ }
190
+ accountStatus={account.status}
191
+ onSaved={refetch}
192
+ />
193
+
194
+ <CreditPackGrid
195
+ accountStatus={account.status}
196
+ purchasingPackId={isSubmitting ? purchasingPackId : null}
197
+ onPurchase={handlePurchase}
198
+ />
199
+
200
+ {checkoutError && (
201
+ <p className="text-destructive text-xs" role="alert">
202
+ {getUserMessage(checkoutError)}
203
+ </p>
204
+ )}
205
+
206
+ <CreditLedgerTable orgId={orgId} />
207
+ </div>
208
+ );
209
+ }
210
+
211
+ // ---------------------------------------------------------------------------
212
+ // CheckoutSuccessBanner (internal)
213
+ // ---------------------------------------------------------------------------
214
+
215
+ function CheckoutSuccessBanner({
216
+ onDismiss,
217
+ }: {
218
+ onDismiss?: () => void;
219
+ }) {
220
+ return (
221
+ <div
222
+ role="status"
223
+ className="flex items-center justify-between gap-3 rounded-lg border border-emerald-500/30 bg-emerald-500/5 px-3.5 py-3 text-xs text-emerald-700 dark:text-emerald-300"
224
+ >
225
+ <p>
226
+ <span className="font-medium">Payment received</span>
227
+ {" \u2014 "}
228
+ credits will appear in your balance shortly.
229
+ </p>
230
+ {onDismiss && (
231
+ <button
232
+ type="button"
233
+ onClick={onDismiss}
234
+ className="shrink-0 rounded p-0.5 transition-colors hover:bg-emerald-500/10"
235
+ aria-label="Dismiss"
236
+ >
237
+ <svg
238
+ width="14"
239
+ height="14"
240
+ viewBox="0 0 24 24"
241
+ fill="none"
242
+ stroke="currentColor"
243
+ strokeWidth="2"
244
+ strokeLinecap="round"
245
+ strokeLinejoin="round"
246
+ aria-hidden="true"
247
+ >
248
+ <path d="M18 6 6 18" />
249
+ <path d="m6 6 12 12" />
250
+ </svg>
251
+ </button>
252
+ )}
253
+ </div>
254
+ );
255
+ }
@@ -0,0 +1,81 @@
1
+ "use client";
2
+
3
+ import { cn } from "@stigmer/theme";
4
+ import type { CreditBalance } from "@stigmer/protos/ai/stigmer/billing/v1/billing_account_pb";
5
+ import { formatCreditBalance } from "./format";
6
+
7
+ /** Props for {@link CreditBalanceCard}. */
8
+ export interface CreditBalanceCardProps {
9
+ /** The credit balance breakdown from the billing account. */
10
+ readonly balance: CreditBalance;
11
+ /** Whether the balance is below the low-balance threshold. */
12
+ readonly isLowBalance?: boolean;
13
+ /** Additional CSS class names. */
14
+ readonly className?: string;
15
+ }
16
+
17
+ /**
18
+ * Prominent display of the organization's available credit balance.
19
+ *
20
+ * Shows the total available balance as the primary figure, with
21
+ * a secondary breakdown of promotional vs. purchased credits and
22
+ * any reserved amount. Uses semantic colors to indicate balance
23
+ * health: green for healthy, amber for low, red for zero/negative.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <CreditBalanceCard balance={account.balance} isLowBalance={isLow} />
28
+ * ```
29
+ */
30
+ export function CreditBalanceCard({
31
+ balance,
32
+ isLowBalance,
33
+ className,
34
+ }: CreditBalanceCardProps) {
35
+ const available = balance.availableMicros;
36
+ const zero = BigInt(0);
37
+ const isZeroOrNegative = available <= zero;
38
+
39
+ return (
40
+ <div
41
+ className={cn(
42
+ "rounded-lg border border-border bg-card px-4 py-4",
43
+ className,
44
+ )}
45
+ >
46
+ <div className="text-xs font-medium text-muted-foreground">
47
+ Available Credits
48
+ </div>
49
+ <div
50
+ className={cn(
51
+ "mt-1 text-2xl font-bold tabular-nums",
52
+ isZeroOrNegative
53
+ ? "text-destructive"
54
+ : isLowBalance
55
+ ? "text-warning-foreground"
56
+ : "text-foreground",
57
+ )}
58
+ >
59
+ {formatCreditBalance(available)}
60
+ </div>
61
+
62
+ <div className="mt-3 flex flex-wrap gap-x-4 gap-y-1 text-xs tabular-nums text-muted-foreground">
63
+ {balance.purchasedMicros > zero && (
64
+ <span>
65
+ Purchased: {formatCreditBalance(balance.purchasedMicros)}
66
+ </span>
67
+ )}
68
+ {balance.promotionalMicros > zero && (
69
+ <span>
70
+ Promotional: {formatCreditBalance(balance.promotionalMicros)}
71
+ </span>
72
+ )}
73
+ {balance.reservedMicros > zero && (
74
+ <span>
75
+ Reserved: {formatCreditBalance(balance.reservedMicros)}
76
+ </span>
77
+ )}
78
+ </div>
79
+ </div>
80
+ );
81
+ }
@@ -0,0 +1,281 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage } from "@stigmer/sdk";
6
+ import type { CreditLedgerEntry } from "@stigmer/protos/ai/stigmer/billing/v1/credit_pb";
7
+ import {
8
+ formatLedgerAmount,
9
+ formatCreditBalance,
10
+ formatLedgerDate,
11
+ ledgerEntryLabel,
12
+ isCredit,
13
+ isHold,
14
+ } from "./format";
15
+ import { useCreditLedger, type UseCreditLedgerOptions } from "./useCreditLedger";
16
+
17
+ /** Props for {@link CreditLedgerTable}. */
18
+ export interface CreditLedgerTableProps {
19
+ /** Organization ID to fetch ledger entries for. */
20
+ readonly orgId: string;
21
+ /** Additional CSS class names. */
22
+ readonly className?: string;
23
+ }
24
+
25
+ /**
26
+ * Paginated transaction history table showing credit ledger entries.
27
+ *
28
+ * Displays entries with type badges, signed amounts, and running
29
+ * balance. Supports pagination with simple prev/next controls.
30
+ * Uses semantic colors: green for credits, red for debits, gray
31
+ * for holds and releases.
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * <CreditLedgerTable orgId={activeOrg.metadata.id} />
36
+ * ```
37
+ */
38
+ export function CreditLedgerTable({
39
+ orgId,
40
+ className,
41
+ }: CreditLedgerTableProps) {
42
+ const [pageNum, setPageNum] = useState(1);
43
+ const options: UseCreditLedgerOptions = { pageNum, pageSize: 10 };
44
+ const { ledger, isLoading, error } = useCreditLedger(orgId, options);
45
+
46
+ if (isLoading) {
47
+ return (
48
+ <div className={cn("space-y-2", className)} aria-busy="true">
49
+ <div className="h-4 w-32 animate-pulse rounded bg-muted-subtle" />
50
+ {Array.from({ length: 5 }, (_, i) => (
51
+ <div
52
+ key={i}
53
+ className="h-10 animate-pulse rounded-lg bg-muted-subtle"
54
+ />
55
+ ))}
56
+ </div>
57
+ );
58
+ }
59
+
60
+ if (error) {
61
+ return (
62
+ <p className={cn("text-destructive text-xs", className)} role="alert">
63
+ {getUserMessage(error)}
64
+ </p>
65
+ );
66
+ }
67
+
68
+ const entries = ledger?.entries ?? [];
69
+ const totalPages = ledger?.totalPages ?? 0;
70
+
71
+ return (
72
+ <div className={className}>
73
+ <h3 className="mb-2 text-xs font-semibold text-foreground">
74
+ Transaction History
75
+ </h3>
76
+
77
+ {entries.length === 0 ? (
78
+ <EmptyLedger />
79
+ ) : (
80
+ <>
81
+ <div
82
+ className="rounded-lg border border-border bg-card"
83
+ role="table"
84
+ aria-label="Credit ledger"
85
+ >
86
+ <LedgerHeader />
87
+ {entries.map((entry) => (
88
+ <LedgerRow key={entry.entryId} entry={entry} />
89
+ ))}
90
+ </div>
91
+
92
+ {totalPages > 1 && (
93
+ <Pagination
94
+ pageNum={pageNum}
95
+ totalPages={totalPages}
96
+ onPageChange={setPageNum}
97
+ />
98
+ )}
99
+ </>
100
+ )}
101
+ </div>
102
+ );
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // LedgerHeader (internal)
107
+ // ---------------------------------------------------------------------------
108
+
109
+ function LedgerHeader() {
110
+ return (
111
+ <div
112
+ role="row"
113
+ className="grid grid-cols-[1fr_auto_auto] gap-x-4 border-b border-border px-3.5 py-2 text-[0.65rem] font-medium uppercase tracking-wider text-muted-foreground sm:grid-cols-[auto_1fr_auto_auto]"
114
+ >
115
+ <span role="columnheader" className="hidden sm:block">
116
+ Date
117
+ </span>
118
+ <span role="columnheader">Type</span>
119
+ <span role="columnheader" className="text-right">
120
+ Amount
121
+ </span>
122
+ <span role="columnheader" className="text-right">
123
+ Balance
124
+ </span>
125
+ </div>
126
+ );
127
+ }
128
+
129
+ // ---------------------------------------------------------------------------
130
+ // LedgerRow (internal)
131
+ // ---------------------------------------------------------------------------
132
+
133
+ function LedgerRow({ entry }: { entry: CreditLedgerEntry }) {
134
+ const entryType = entry.type;
135
+ const credit = isCredit(entryType);
136
+ const hold = isHold(entryType);
137
+
138
+ return (
139
+ <div
140
+ role="row"
141
+ className="grid grid-cols-[1fr_auto_auto] items-center gap-x-4 border-b border-border-muted px-3.5 py-2.5 last:border-b-0 sm:grid-cols-[auto_1fr_auto_auto]"
142
+ >
143
+ <span
144
+ role="cell"
145
+ className="hidden text-xs tabular-nums text-muted-foreground sm:block sm:w-36"
146
+ >
147
+ {entry.createdAt
148
+ ? formatLedgerDate(entry.createdAt.seconds)
149
+ : "\u2014"}
150
+ </span>
151
+
152
+ <div role="cell" className="min-w-0">
153
+ <span
154
+ className={cn(
155
+ "inline-block rounded-full px-2 py-0.5 text-[0.65rem] font-medium",
156
+ credit
157
+ ? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"
158
+ : hold
159
+ ? "bg-muted text-muted-foreground"
160
+ : "bg-destructive/10 text-destructive",
161
+ )}
162
+ >
163
+ {ledgerEntryLabel(entryType)}
164
+ </span>
165
+ {entry.source?.description && (
166
+ <span className="ml-2 text-xs text-muted-foreground">
167
+ {entry.source.description}
168
+ </span>
169
+ )}
170
+ {entry.createdAt && (
171
+ <span className="mt-0.5 block text-[0.6rem] tabular-nums text-muted-foreground sm:hidden">
172
+ {formatLedgerDate(entry.createdAt.seconds)}
173
+ </span>
174
+ )}
175
+ </div>
176
+
177
+ <span
178
+ role="cell"
179
+ className={cn(
180
+ "text-right text-xs font-medium tabular-nums",
181
+ credit
182
+ ? "text-emerald-600 dark:text-emerald-400"
183
+ : hold
184
+ ? "text-muted-foreground"
185
+ : "text-destructive",
186
+ )}
187
+ >
188
+ {formatLedgerAmount(entry.amountMicros)}
189
+ </span>
190
+
191
+ <span
192
+ role="cell"
193
+ className="text-right text-xs tabular-nums text-muted-foreground"
194
+ >
195
+ {formatCreditBalance(entry.balanceAfterMicros)}
196
+ </span>
197
+ </div>
198
+ );
199
+ }
200
+
201
+ // ---------------------------------------------------------------------------
202
+ // Pagination (internal)
203
+ // ---------------------------------------------------------------------------
204
+
205
+ function Pagination({
206
+ pageNum,
207
+ totalPages,
208
+ onPageChange,
209
+ }: {
210
+ pageNum: number;
211
+ totalPages: number;
212
+ onPageChange: (page: number) => void;
213
+ }) {
214
+ return (
215
+ <div
216
+ className="mt-3 flex items-center justify-between"
217
+ role="navigation"
218
+ aria-label="Ledger pagination"
219
+ >
220
+ <button
221
+ type="button"
222
+ disabled={pageNum <= 1}
223
+ onClick={() => onPageChange(pageNum - 1)}
224
+ className="rounded-md px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-40"
225
+ >
226
+ Previous
227
+ </button>
228
+ <span className="text-xs tabular-nums text-muted-foreground">
229
+ Page {pageNum} of {totalPages}
230
+ </span>
231
+ <button
232
+ type="button"
233
+ disabled={pageNum >= totalPages}
234
+ onClick={() => onPageChange(pageNum + 1)}
235
+ className="rounded-md px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-40"
236
+ >
237
+ Next
238
+ </button>
239
+ </div>
240
+ );
241
+ }
242
+
243
+ // ---------------------------------------------------------------------------
244
+ // EmptyLedger (internal)
245
+ // ---------------------------------------------------------------------------
246
+
247
+ function EmptyLedger() {
248
+ return (
249
+ <div className="flex flex-col items-center justify-center rounded-lg border border-border bg-card py-10 text-center">
250
+ <ReceiptIcon className="text-muted-foreground mb-3 size-8" />
251
+ <p className="text-sm font-medium text-foreground">
252
+ No transactions yet
253
+ </p>
254
+ <p className="mt-1 max-w-xs text-xs text-muted-foreground">
255
+ Credit purchases and usage charges will appear here as your
256
+ organization runs agent executions.
257
+ </p>
258
+ </div>
259
+ );
260
+ }
261
+
262
+ function ReceiptIcon({ className }: { className?: string }) {
263
+ return (
264
+ <svg
265
+ width="24"
266
+ height="24"
267
+ viewBox="0 0 24 24"
268
+ fill="none"
269
+ stroke="currentColor"
270
+ strokeWidth="1.5"
271
+ strokeLinecap="round"
272
+ strokeLinejoin="round"
273
+ className={className}
274
+ aria-hidden="true"
275
+ >
276
+ <path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z" />
277
+ <path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8" />
278
+ <path d="M12 17.5v.5M12 6v.5" />
279
+ </svg>
280
+ );
281
+ }