@stigmer/react 0.3.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/billing/AutoRechargeCard.d.ts +38 -0
- package/billing/AutoRechargeCard.d.ts.map +1 -0
- package/billing/AutoRechargeCard.js +90 -0
- package/billing/AutoRechargeCard.js.map +1 -0
- package/billing/BillingSection.d.ts +32 -0
- package/billing/BillingSection.d.ts.map +1 -0
- package/billing/BillingSection.js +81 -0
- package/billing/BillingSection.js.map +1 -0
- package/billing/CreditBalanceCard.d.ts +25 -0
- package/billing/CreditBalanceCard.d.ts.map +1 -0
- package/billing/CreditBalanceCard.js +28 -0
- package/billing/CreditBalanceCard.js.map +1 -0
- package/billing/CreditLedgerTable.d.ts +22 -0
- package/billing/CreditLedgerTable.d.ts.map +1 -0
- package/billing/CreditLedgerTable.js +75 -0
- package/billing/CreditLedgerTable.js.map +1 -0
- package/billing/CreditPackGrid.d.ts +31 -0
- package/billing/CreditPackGrid.d.ts.map +1 -0
- package/billing/CreditPackGrid.js +35 -0
- package/billing/CreditPackGrid.js.map +1 -0
- package/billing/LowBalanceBanner.d.ts +26 -0
- package/billing/LowBalanceBanner.d.ts.map +1 -0
- package/billing/LowBalanceBanner.js +33 -0
- package/billing/LowBalanceBanner.js.map +1 -0
- package/billing/PaymentMethodCard.d.ts +35 -0
- package/billing/PaymentMethodCard.d.ts.map +1 -0
- package/billing/PaymentMethodCard.js +48 -0
- package/billing/PaymentMethodCard.js.map +1 -0
- package/billing/credit-packs.d.ts +25 -0
- package/billing/credit-packs.d.ts.map +1 -0
- package/billing/credit-packs.js +39 -0
- package/billing/credit-packs.js.map +1 -0
- package/billing/format.d.ts +39 -0
- package/billing/format.d.ts.map +1 -0
- package/billing/format.js +90 -0
- package/billing/format.js.map +1 -0
- package/billing/index.d.ts +32 -0
- package/billing/index.d.ts.map +1 -0
- package/billing/index.js +21 -0
- package/billing/index.js.map +1 -0
- package/billing/useBillingAccount.d.ts +40 -0
- package/billing/useBillingAccount.d.ts.map +1 -0
- package/billing/useBillingAccount.js +35 -0
- package/billing/useBillingAccount.js.map +1 -0
- package/billing/useBillingUsageReport.d.ts +42 -0
- package/billing/useBillingUsageReport.d.ts.map +1 -0
- package/billing/useBillingUsageReport.js +43 -0
- package/billing/useBillingUsageReport.js.map +1 -0
- package/billing/useCreateBillingPortalSession.d.ts +35 -0
- package/billing/useCreateBillingPortalSession.d.ts.map +1 -0
- package/billing/useCreateBillingPortalSession.js +50 -0
- package/billing/useCreateBillingPortalSession.js.map +1 -0
- package/billing/useCreateCheckoutSession.d.ts +54 -0
- package/billing/useCreateCheckoutSession.d.ts.map +1 -0
- package/billing/useCreateCheckoutSession.js +58 -0
- package/billing/useCreateCheckoutSession.js.map +1 -0
- package/billing/useCreditLedger.d.ts +48 -0
- package/billing/useCreditLedger.d.ts.map +1 -0
- package/billing/useCreditLedger.js +39 -0
- package/billing/useCreditLedger.js.map +1 -0
- package/billing/useCustomerModelPricing.d.ts +41 -0
- package/billing/useCustomerModelPricing.d.ts.map +1 -0
- package/billing/useCustomerModelPricing.js +37 -0
- package/billing/useCustomerModelPricing.js.map +1 -0
- package/billing/useSetAutoRechargeConfig.d.ts +50 -0
- package/billing/useSetAutoRechargeConfig.d.ts.map +1 -0
- package/billing/useSetAutoRechargeConfig.js +53 -0
- package/billing/useSetAutoRechargeConfig.js.map +1 -0
- package/composer/ComposerToolbar.js +1 -1
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/SessionComposer.d.ts +1 -1
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +19 -4
- package/composer/SessionComposer.js.map +1 -1
- package/composer/__tests__/SessionComposer-memo.test.d.ts +2 -0
- package/composer/__tests__/SessionComposer-memo.test.d.ts.map +1 -0
- package/composer/__tests__/SessionComposer-memo.test.js +23 -0
- package/composer/__tests__/SessionComposer-memo.test.js.map +1 -0
- package/execution/ApprovalCard.d.ts +5 -1
- package/execution/ApprovalCard.d.ts.map +1 -1
- package/execution/ApprovalCard.js +7 -3
- package/execution/ApprovalCard.js.map +1 -1
- package/execution/ExecutionPhaseBadge.d.ts +1 -1
- package/execution/ExecutionPhaseBadge.d.ts.map +1 -1
- package/execution/ExecutionPhaseBadge.js +3 -2
- package/execution/ExecutionPhaseBadge.js.map +1 -1
- package/execution/MessageEntry.d.ts +7 -3
- package/execution/MessageEntry.d.ts.map +1 -1
- package/execution/MessageEntry.js +19 -8
- package/execution/MessageEntry.js.map +1 -1
- package/execution/MessageThread.d.ts +84 -3
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +113 -65
- package/execution/MessageThread.js.map +1 -1
- package/execution/SetupProgress.d.ts +1 -1
- package/execution/SetupProgress.d.ts.map +1 -1
- package/execution/SetupProgress.js +3 -3
- package/execution/SetupProgress.js.map +1 -1
- package/execution/SubAgentSection.d.ts +5 -1
- package/execution/SubAgentSection.d.ts.map +1 -1
- package/execution/SubAgentSection.js +13 -7
- package/execution/SubAgentSection.js.map +1 -1
- package/execution/ThreadSkeleton.d.ts +22 -0
- package/execution/ThreadSkeleton.d.ts.map +1 -0
- package/execution/ThreadSkeleton.js +26 -0
- package/execution/ThreadSkeleton.js.map +1 -0
- package/execution/ToolCallGroup.d.ts +16 -1
- package/execution/ToolCallGroup.d.ts.map +1 -1
- package/execution/ToolCallGroup.js +31 -3
- package/execution/ToolCallGroup.js.map +1 -1
- package/execution/UsageWidget.d.ts +1 -1
- package/execution/__tests__/message-entry.test.d.ts +2 -0
- package/execution/__tests__/message-entry.test.d.ts.map +1 -0
- package/execution/__tests__/message-entry.test.js +178 -0
- package/execution/__tests__/message-entry.test.js.map +1 -0
- package/execution/__tests__/thread-keys.test.d.ts +2 -0
- package/execution/__tests__/thread-keys.test.d.ts.map +1 -0
- package/execution/__tests__/thread-keys.test.js +289 -0
- package/execution/__tests__/thread-keys.test.js.map +1 -0
- package/execution/__tests__/thread-memoization.test.d.ts +2 -0
- package/execution/__tests__/thread-memoization.test.d.ts.map +1 -0
- package/execution/__tests__/thread-memoization.test.js +262 -0
- package/execution/__tests__/thread-memoization.test.js.map +1 -0
- package/execution/__tests__/thread-skeleton.test.d.ts +2 -0
- package/execution/__tests__/thread-skeleton.test.d.ts.map +1 -0
- package/execution/__tests__/thread-skeleton.test.js +35 -0
- package/execution/__tests__/thread-skeleton.test.js.map +1 -0
- package/execution/__tests__/useExecutionStream.test.js +73 -10
- package/execution/__tests__/useExecutionStream.test.js.map +1 -1
- package/execution/__tests__/useSessionVariables-stability.test.d.ts +2 -0
- package/execution/__tests__/useSessionVariables-stability.test.d.ts.map +1 -0
- package/execution/__tests__/useSessionVariables-stability.test.js +69 -0
- package/execution/__tests__/useSessionVariables-stability.test.js.map +1 -0
- package/execution/__tests__/virtualized-thread.test.d.ts +2 -0
- package/execution/__tests__/virtualized-thread.test.d.ts.map +1 -0
- package/execution/__tests__/virtualized-thread.test.js +274 -0
- package/execution/__tests__/virtualized-thread.test.js.map +1 -0
- package/execution/index.d.ts +2 -0
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +1 -0
- package/execution/index.js.map +1 -1
- package/execution/useExecutionStream.d.ts +35 -10
- package/execution/useExecutionStream.d.ts.map +1 -1
- package/execution/useExecutionStream.js +79 -40
- package/execution/useExecutionStream.js.map +1 -1
- package/execution/useSessionVariables.d.ts.map +1 -1
- package/execution/useSessionVariables.js +4 -3
- package/execution/useSessionVariables.js.map +1 -1
- package/github/useGitHubConnection.d.ts.map +1 -1
- package/github/useGitHubConnection.js +5 -4
- package/github/useGitHubConnection.js.map +1 -1
- package/identity-account/index.d.ts +2 -0
- package/identity-account/index.d.ts.map +1 -0
- package/identity-account/index.js +2 -0
- package/identity-account/index.js.map +1 -0
- package/identity-account/useIdentityAccountGate.d.ts +81 -0
- package/identity-account/useIdentityAccountGate.d.ts.map +1 -0
- package/identity-account/useIdentityAccountGate.js +100 -0
- package/identity-account/useIdentityAccountGate.js.map +1 -0
- package/index.d.ts +10 -4
- package/index.d.ts.map +1 -1
- package/index.js +8 -2
- package/index.js.map +1 -1
- package/internal/FetchCacheProvider.d.ts +44 -0
- package/internal/FetchCacheProvider.d.ts.map +1 -0
- package/internal/FetchCacheProvider.js +61 -0
- package/internal/FetchCacheProvider.js.map +1 -0
- package/internal/JumpToLatestButton.d.ts +14 -0
- package/internal/JumpToLatestButton.d.ts.map +1 -0
- package/internal/JumpToLatestButton.js +19 -0
- package/internal/JumpToLatestButton.js.map +1 -0
- package/internal/ThreadItemWrapper.d.ts +20 -0
- package/internal/ThreadItemWrapper.d.ts.map +1 -0
- package/internal/ThreadItemWrapper.js +44 -0
- package/internal/ThreadItemWrapper.js.map +1 -0
- package/internal/VirtualizedThread.d.ts +25 -0
- package/internal/VirtualizedThread.d.ts.map +1 -0
- package/internal/VirtualizedThread.js +58 -0
- package/internal/VirtualizedThread.js.map +1 -0
- package/internal/__tests__/fetch-cache.test.d.ts +2 -0
- package/internal/__tests__/fetch-cache.test.d.ts.map +1 -0
- package/internal/__tests__/fetch-cache.test.js +182 -0
- package/internal/__tests__/fetch-cache.test.js.map +1 -0
- package/internal/__tests__/stream-controller.test.d.ts +2 -0
- package/internal/__tests__/stream-controller.test.d.ts.map +1 -0
- package/internal/__tests__/stream-controller.test.js +294 -0
- package/internal/__tests__/stream-controller.test.js.map +1 -0
- package/internal/__tests__/thread-animation.test.d.ts +2 -0
- package/internal/__tests__/thread-animation.test.d.ts.map +1 -0
- package/internal/__tests__/thread-animation.test.js +79 -0
- package/internal/__tests__/thread-animation.test.js.map +1 -0
- package/internal/__tests__/useAutoScroll.test.d.ts +2 -0
- package/internal/__tests__/useAutoScroll.test.d.ts.map +1 -0
- package/internal/__tests__/useAutoScroll.test.js +188 -0
- package/internal/__tests__/useAutoScroll.test.js.map +1 -0
- package/internal/__tests__/useFetch-cache.test.d.ts +2 -0
- package/internal/__tests__/useFetch-cache.test.d.ts.map +1 -0
- package/internal/__tests__/useFetch-cache.test.js +137 -0
- package/internal/__tests__/useFetch-cache.test.js.map +1 -0
- package/internal/dev/__tests__/use-key-stability.test.d.ts +2 -0
- package/internal/dev/__tests__/use-key-stability.test.d.ts.map +1 -0
- package/internal/dev/__tests__/use-key-stability.test.js +72 -0
- package/internal/dev/__tests__/use-key-stability.test.js.map +1 -0
- package/internal/dev/__tests__/use-render-tracer.test.d.ts +2 -0
- package/internal/dev/__tests__/use-render-tracer.test.d.ts.map +1 -0
- package/internal/dev/__tests__/use-render-tracer.test.js +55 -0
- package/internal/dev/__tests__/use-render-tracer.test.js.map +1 -0
- package/internal/dev/dom-counter.d.ts +14 -0
- package/internal/dev/dom-counter.d.ts.map +1 -0
- package/internal/dev/dom-counter.js +39 -0
- package/internal/dev/dom-counter.js.map +1 -0
- package/internal/dev/index.d.ts +6 -0
- package/internal/dev/index.d.ts.map +1 -0
- package/internal/dev/index.js +6 -0
- package/internal/dev/index.js.map +1 -0
- package/internal/dev/profiler-wrapper.d.ts +16 -0
- package/internal/dev/profiler-wrapper.d.ts.map +1 -0
- package/internal/dev/profiler-wrapper.js +31 -0
- package/internal/dev/profiler-wrapper.js.map +1 -0
- package/internal/dev/use-key-stability.d.ts +22 -0
- package/internal/dev/use-key-stability.d.ts.map +1 -0
- package/internal/dev/use-key-stability.js +67 -0
- package/internal/dev/use-key-stability.js.map +1 -0
- package/internal/dev/use-render-tracer.d.ts +13 -0
- package/internal/dev/use-render-tracer.d.ts.map +1 -0
- package/internal/dev/use-render-tracer.js +57 -0
- package/internal/dev/use-render-tracer.js.map +1 -0
- package/internal/dev/use-stream-rate.d.ts +23 -0
- package/internal/dev/use-stream-rate.d.ts.map +1 -0
- package/internal/dev/use-stream-rate.js +94 -0
- package/internal/dev/use-stream-rate.js.map +1 -0
- package/internal/fetch-cache.d.ts +72 -0
- package/internal/fetch-cache.d.ts.map +1 -0
- package/internal/fetch-cache.js +118 -0
- package/internal/fetch-cache.js.map +1 -0
- package/internal/store/__tests__/conversation-store.test.d.ts +2 -0
- package/internal/store/__tests__/conversation-store.test.d.ts.map +1 -0
- package/internal/store/__tests__/conversation-store.test.js +200 -0
- package/internal/store/__tests__/conversation-store.test.js.map +1 -0
- package/internal/store/__tests__/structural-share.test.d.ts +2 -0
- package/internal/store/__tests__/structural-share.test.d.ts.map +1 -0
- package/internal/store/__tests__/structural-share.test.js +368 -0
- package/internal/store/__tests__/structural-share.test.js.map +1 -0
- package/internal/store/conversation-store.d.ts +62 -0
- package/internal/store/conversation-store.d.ts.map +1 -0
- package/internal/store/conversation-store.js +95 -0
- package/internal/store/conversation-store.js.map +1 -0
- package/internal/store/index.d.ts +31 -0
- package/internal/store/index.d.ts.map +1 -0
- package/internal/store/index.js +54 -0
- package/internal/store/index.js.map +1 -0
- package/internal/store/structural-share.d.ts +13 -0
- package/internal/store/structural-share.d.ts.map +1 -0
- package/internal/store/structural-share.js +240 -0
- package/internal/store/structural-share.js.map +1 -0
- package/internal/stream-controller.d.ts +85 -0
- package/internal/stream-controller.d.ts.map +1 -0
- package/internal/stream-controller.js +146 -0
- package/internal/stream-controller.js.map +1 -0
- package/internal/useAutoScroll.d.ts +32 -0
- package/internal/useAutoScroll.d.ts.map +1 -0
- package/internal/useAutoScroll.js +97 -0
- package/internal/useAutoScroll.js.map +1 -0
- package/internal/useFetch.d.ts +14 -0
- package/internal/useFetch.d.ts.map +1 -1
- package/internal/useFetch.js +32 -2
- package/internal/useFetch.js.map +1 -1
- package/package.json +7 -5
- package/session/__tests__/useNewSessionFlow.test.js +16 -0
- package/session/__tests__/useNewSessionFlow.test.js.map +1 -1
- package/session/__tests__/usePersistedModel.test.d.ts +2 -0
- package/session/__tests__/usePersistedModel.test.d.ts.map +1 -0
- package/session/__tests__/usePersistedModel.test.js +82 -0
- package/session/__tests__/usePersistedModel.test.js.map +1 -0
- package/session/__tests__/useSession.test.d.ts +2 -0
- package/session/__tests__/useSession.test.d.ts.map +1 -0
- package/session/__tests__/useSession.test.js +130 -0
- package/session/__tests__/useSession.test.js.map +1 -0
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +12 -6
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/usePersistedModel.d.ts +3 -0
- package/session/usePersistedModel.d.ts.map +1 -1
- package/session/usePersistedModel.js +27 -2
- package/session/usePersistedModel.js.map +1 -1
- package/session/useSession.d.ts.map +1 -1
- package/session/useSession.js +1 -1
- package/session/useSession.js.map +1 -1
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +9 -1
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionExecutions.d.ts.map +1 -1
- package/session/useSessionExecutions.js +1 -1
- package/session/useSessionExecutions.js.map +1 -1
- package/session/useSessionPageFlow.js +1 -1
- package/session/useSessionPageFlow.js.map +1 -1
- package/session/useSessionUsage.d.ts +24 -40
- package/session/useSessionUsage.d.ts.map +1 -1
- package/session/useSessionUsage.js +64 -97
- package/session/useSessionUsage.js.map +1 -1
- package/settings/BillingSection.d.ts +3 -0
- package/settings/BillingSection.d.ts.map +1 -0
- package/settings/BillingSection.js +3 -0
- package/settings/BillingSection.js.map +1 -0
- package/settings/index.d.ts +2 -0
- package/settings/index.d.ts.map +1 -1
- package/settings/index.js +1 -0
- package/settings/index.js.map +1 -1
- package/settings/settings-nav.js +1 -1
- package/settings/settings-nav.js.map +1 -1
- package/src/billing/AutoRechargeCard.tsx +274 -0
- package/src/billing/BillingSection.tsx +255 -0
- package/src/billing/CreditBalanceCard.tsx +81 -0
- package/src/billing/CreditLedgerTable.tsx +281 -0
- package/src/billing/CreditPackGrid.tsx +132 -0
- package/src/billing/LowBalanceBanner.tsx +67 -0
- package/src/billing/PaymentMethodCard.tsx +133 -0
- package/src/billing/credit-packs.ts +54 -0
- package/src/billing/format.ts +97 -0
- package/src/billing/index.ts +51 -0
- package/src/billing/useBillingAccount.ts +64 -0
- package/src/billing/useBillingUsageReport.ts +73 -0
- package/src/billing/useCreateBillingPortalSession.ts +76 -0
- package/src/billing/useCreateCheckoutSession.ts +101 -0
- package/src/billing/useCreditLedger.ts +79 -0
- package/src/billing/useCustomerModelPricing.ts +67 -0
- package/src/billing/useSetAutoRechargeConfig.ts +90 -0
- package/src/composer/ComposerToolbar.tsx +1 -1
- package/src/composer/SessionComposer.tsx +22 -4
- package/src/composer/__tests__/SessionComposer-memo.test.ts +26 -0
- package/src/execution/ApprovalCard.tsx +7 -3
- package/src/execution/ExecutionPhaseBadge.tsx +3 -2
- package/src/execution/MessageEntry.tsx +27 -16
- package/src/execution/MessageThread.tsx +308 -131
- package/src/execution/SetupProgress.tsx +3 -3
- package/src/execution/SubAgentSection.tsx +14 -6
- package/src/execution/ThreadSkeleton.tsx +73 -0
- package/src/execution/ToolCallGroup.tsx +36 -3
- package/src/execution/UsageWidget.tsx +1 -1
- package/src/execution/__tests__/message-entry.test.tsx +236 -0
- package/src/execution/__tests__/thread-keys.test.ts +409 -0
- package/src/execution/__tests__/thread-memoization.test.ts +320 -0
- package/src/execution/__tests__/thread-skeleton.test.tsx +44 -0
- package/src/execution/__tests__/useExecutionStream.test.tsx +109 -12
- package/src/execution/__tests__/useSessionVariables-stability.test.ts +95 -0
- package/src/execution/__tests__/virtualized-thread.test.tsx +401 -0
- package/src/execution/index.ts +3 -0
- package/src/execution/useExecutionStream.ts +123 -48
- package/src/execution/useSessionVariables.ts +17 -12
- package/src/github/useGitHubConnection.ts +18 -13
- package/src/identity-account/index.ts +5 -0
- package/src/identity-account/useIdentityAccountGate.ts +163 -0
- package/src/index.ts +73 -0
- package/src/internal/FetchCacheProvider.tsx +74 -0
- package/src/internal/JumpToLatestButton.tsx +61 -0
- package/src/internal/ThreadItemWrapper.tsx +65 -0
- package/src/internal/VirtualizedThread.tsx +162 -0
- package/src/internal/__tests__/fetch-cache.test.ts +230 -0
- package/src/internal/__tests__/stream-controller.test.ts +395 -0
- package/src/internal/__tests__/thread-animation.test.tsx +121 -0
- package/src/internal/__tests__/useAutoScroll.test.tsx +261 -0
- package/src/internal/__tests__/useFetch-cache.test.ts +214 -0
- package/src/internal/dev/__tests__/use-key-stability.test.ts +124 -0
- package/src/internal/dev/__tests__/use-render-tracer.test.ts +78 -0
- package/src/internal/dev/dom-counter.ts +47 -0
- package/src/internal/dev/index.ts +5 -0
- package/src/internal/dev/profiler-wrapper.tsx +52 -0
- package/src/internal/dev/use-key-stability.ts +86 -0
- package/src/internal/dev/use-render-tracer.ts +70 -0
- package/src/internal/dev/use-stream-rate.ts +138 -0
- package/src/internal/fetch-cache.ts +155 -0
- package/src/internal/store/__tests__/conversation-store.test.ts +257 -0
- package/src/internal/store/__tests__/structural-share.test.ts +454 -0
- package/src/internal/store/conversation-store.ts +128 -0
- package/src/internal/store/index.ts +68 -0
- package/src/internal/store/structural-share.ts +318 -0
- package/src/internal/stream-controller.ts +201 -0
- package/src/internal/useAutoScroll.ts +121 -0
- package/src/internal/useFetch.ts +51 -2
- package/src/session/__tests__/useNewSessionFlow.test.tsx +22 -0
- package/src/session/__tests__/usePersistedModel.test.tsx +117 -0
- package/src/session/__tests__/useSession.test.tsx +187 -0
- package/src/session/useNewSessionFlow.ts +12 -6
- package/src/session/usePersistedModel.ts +28 -2
- package/src/session/useSession.ts +1 -0
- package/src/session/useSessionConversation.ts +11 -2
- package/src/session/useSessionExecutions.ts +1 -0
- package/src/session/useSessionPageFlow.ts +1 -1
- package/src/session/useSessionUsage.ts +102 -123
- package/src/settings/BillingSection.tsx +4 -0
- package/src/settings/index.ts +2 -0
- package/src/settings/settings-nav.ts +1 -1
- package/src/styles.css +31 -0
- package/src/usage/AgentBreakdownList.tsx +147 -0
- package/src/usage/CreditRunwayIndicator.tsx +71 -0
- package/src/usage/ExportButton.tsx +115 -0
- package/src/usage/HarnessSplitCard.tsx +103 -0
- package/src/usage/OrgUsagePanel.tsx +109 -45
- package/src/usage/index.ts +15 -0
- package/src/usage/useExportCSV.ts +115 -0
- package/src/usage/useOrgUsageReport.ts +2 -1
- package/src/workspace/__tests__/useWorkspaceEntries-stability.test.ts +76 -0
- package/src/workspace/useWorkspaceEntries.ts +16 -11
- package/styles.css +1 -1
- package/usage/AgentBreakdownList.d.ts +21 -0
- package/usage/AgentBreakdownList.d.ts.map +1 -0
- package/usage/AgentBreakdownList.js +44 -0
- package/usage/AgentBreakdownList.js.map +1 -0
- package/usage/CreditRunwayIndicator.d.ts +21 -0
- package/usage/CreditRunwayIndicator.d.ts.map +1 -0
- package/usage/CreditRunwayIndicator.js +38 -0
- package/usage/CreditRunwayIndicator.js.map +1 -0
- package/usage/ExportButton.d.ts +20 -0
- package/usage/ExportButton.d.ts.map +1 -0
- package/usage/ExportButton.js +36 -0
- package/usage/ExportButton.js.map +1 -0
- package/usage/HarnessSplitCard.d.ts +17 -0
- package/usage/HarnessSplitCard.d.ts.map +1 -0
- package/usage/HarnessSplitCard.js +38 -0
- package/usage/HarnessSplitCard.js.map +1 -0
- package/usage/OrgUsagePanel.d.ts.map +1 -1
- package/usage/OrgUsagePanel.js +30 -22
- package/usage/OrgUsagePanel.js.map +1 -1
- package/usage/index.d.ts +10 -0
- package/usage/index.d.ts.map +1 -1
- package/usage/index.js +5 -0
- package/usage/index.js.map +1 -1
- package/usage/useExportCSV.d.ts +23 -0
- package/usage/useExportCSV.d.ts.map +1 -0
- package/usage/useExportCSV.js +81 -0
- package/usage/useExportCSV.js.map +1 -0
- package/usage/useOrgUsageReport.d.ts +2 -1
- package/usage/useOrgUsageReport.d.ts.map +1 -1
- package/usage/useOrgUsageReport.js +2 -1
- package/usage/useOrgUsageReport.js.map +1 -1
- package/workspace/__tests__/useWorkspaceEntries-stability.test.d.ts +2 -0
- package/workspace/__tests__/useWorkspaceEntries-stability.test.d.ts.map +1 -0
- package/workspace/__tests__/useWorkspaceEntries-stability.test.js +57 -0
- package/workspace/__tests__/useWorkspaceEntries-stability.test.js.map +1 -0
- package/workspace/useWorkspaceEntries.d.ts.map +1 -1
- package/workspace/useWorkspaceEntries.js +5 -4
- package/workspace/useWorkspaceEntries.js.map +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { create } from "@bufbuild/protobuf";
|
|
5
5
|
import { EnvironmentSecretValueInputSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/io_pb";
|
|
6
6
|
import { useStigmer } from "../hooks";
|
|
@@ -526,16 +526,21 @@ export function useGitHubConnection(
|
|
|
526
526
|
}
|
|
527
527
|
}, []);
|
|
528
528
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
529
|
+
const isConnected = token !== null;
|
|
530
|
+
|
|
531
|
+
return useMemo(
|
|
532
|
+
() => ({
|
|
533
|
+
isConnected,
|
|
534
|
+
isLoading,
|
|
535
|
+
isConnecting,
|
|
536
|
+
popupBlocked,
|
|
537
|
+
user,
|
|
538
|
+
token,
|
|
539
|
+
connect,
|
|
540
|
+
handleCallback,
|
|
541
|
+
reconcile,
|
|
542
|
+
disconnect,
|
|
543
|
+
}),
|
|
544
|
+
[isConnected, isLoading, isConnecting, popupBlocked, user, token, connect, handleCallback, reconcile, disconnect],
|
|
545
|
+
);
|
|
541
546
|
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import type { IdentityAccount } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
|
|
5
|
+
import { isNotFound } from "@stigmer/sdk";
|
|
6
|
+
import { useStigmer } from "../hooks";
|
|
7
|
+
import { toError } from "../internal/toError";
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Types
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Discriminated union representing the current state of the identity
|
|
15
|
+
* account gate.
|
|
16
|
+
*
|
|
17
|
+
* Narrow on `status` to access variant-specific data:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* if (state.status === "ready") {
|
|
21
|
+
* console.log(state.account.metadata?.id);
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export type IdentityAccountGateState =
|
|
26
|
+
| {
|
|
27
|
+
/** Resolving the caller's identity account via whoAmI. */
|
|
28
|
+
readonly status: "checking";
|
|
29
|
+
}
|
|
30
|
+
| {
|
|
31
|
+
/** whoAmI returned NOT_FOUND; provisionMyAccount is in flight. */
|
|
32
|
+
readonly status: "provisioning";
|
|
33
|
+
}
|
|
34
|
+
| {
|
|
35
|
+
/** Identity account is resolved and available. */
|
|
36
|
+
readonly status: "ready";
|
|
37
|
+
/** The resolved identity account. */
|
|
38
|
+
readonly account: IdentityAccount;
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
/** A non-recoverable error occurred. */
|
|
42
|
+
readonly status: "error";
|
|
43
|
+
/** Human-readable failure message suitable for UI display. */
|
|
44
|
+
readonly message: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Return value of {@link useIdentityAccountGate}.
|
|
49
|
+
*
|
|
50
|
+
* `retry` is always available; the consumer invokes it when
|
|
51
|
+
* `status === "error"`.
|
|
52
|
+
*/
|
|
53
|
+
export interface UseIdentityAccountGateReturn {
|
|
54
|
+
/** Current gate state. Discriminated union on `status`. */
|
|
55
|
+
readonly state: IdentityAccountGateState;
|
|
56
|
+
/** Re-attempt the identity resolution from scratch. */
|
|
57
|
+
readonly retry: () => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Hook
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Headless behavior hook that ensures the authenticated caller has an
|
|
66
|
+
* identity account before the application renders.
|
|
67
|
+
*
|
|
68
|
+
* The hook drives the following lifecycle:
|
|
69
|
+
*
|
|
70
|
+
* 1. **`checking`** — calls `whoAmI()` to look up the caller's account.
|
|
71
|
+
* 2. **`provisioning`** — `whoAmI` returned NOT_FOUND (first login after
|
|
72
|
+
* signup); the hook calls `provisionMyAccount()` to create the account
|
|
73
|
+
* and personal organization.
|
|
74
|
+
* 3. **`ready`** — an identity account is available (either pre-existing
|
|
75
|
+
* or freshly provisioned).
|
|
76
|
+
* 4. **`error`** — a non-recoverable failure occurred; `message` carries
|
|
77
|
+
* the reason. Call `retry()` to restart from step 1.
|
|
78
|
+
*
|
|
79
|
+
* The hook is a no-op when `isEnabled` is false — it immediately reports
|
|
80
|
+
* `ready` with a `null`-account shortcut so that disabled-auth deployments
|
|
81
|
+
* skip the gate entirely.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```tsx
|
|
85
|
+
* const { state, retry } = useIdentityAccountGate({ isEnabled: true });
|
|
86
|
+
*
|
|
87
|
+
* switch (state.status) {
|
|
88
|
+
* case "checking":
|
|
89
|
+
* case "provisioning":
|
|
90
|
+
* return <Spinner />;
|
|
91
|
+
* case "ready":
|
|
92
|
+
* return <>{children}</>;
|
|
93
|
+
* case "error":
|
|
94
|
+
* return <ErrorScreen message={state.message} onRetry={retry} />;
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export function useIdentityAccountGate(options: {
|
|
99
|
+
/** Set to `true` when OIDC auth is active. When `false`, the gate is bypassed. */
|
|
100
|
+
readonly isEnabled: boolean;
|
|
101
|
+
}): UseIdentityAccountGateReturn {
|
|
102
|
+
const { isEnabled } = options;
|
|
103
|
+
const stigmer = useStigmer();
|
|
104
|
+
|
|
105
|
+
const [state, setState] = useState<IdentityAccountGateState>(
|
|
106
|
+
isEnabled ? { status: "checking" } : BYPASSED_STATE,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const attemptRef = useRef(0);
|
|
110
|
+
|
|
111
|
+
const resolve = useCallback(async () => {
|
|
112
|
+
const attempt = ++attemptRef.current;
|
|
113
|
+
setState({ status: "checking" });
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
const account = await stigmer.identityAccount.whoAmI();
|
|
117
|
+
if (attempt !== attemptRef.current) return;
|
|
118
|
+
setState({ status: "ready", account });
|
|
119
|
+
} catch (whoAmIErr: unknown) {
|
|
120
|
+
if (attempt !== attemptRef.current) return;
|
|
121
|
+
|
|
122
|
+
if (!isNotFound(whoAmIErr)) {
|
|
123
|
+
setState({ status: "error", message: toError(whoAmIErr).message });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
setState({ status: "provisioning" });
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const account = await stigmer.identityAccount.provisionMyAccount();
|
|
131
|
+
if (attempt !== attemptRef.current) return;
|
|
132
|
+
setState({ status: "ready", account });
|
|
133
|
+
} catch (provisionErr: unknown) {
|
|
134
|
+
if (attempt !== attemptRef.current) return;
|
|
135
|
+
setState({ status: "error", message: toError(provisionErr).message });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}, [stigmer]);
|
|
139
|
+
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
if (!isEnabled) {
|
|
142
|
+
setState(BYPASSED_STATE);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
resolve();
|
|
146
|
+
}, [isEnabled, resolve]);
|
|
147
|
+
|
|
148
|
+
const retry = useCallback(() => {
|
|
149
|
+
if (isEnabled) resolve();
|
|
150
|
+
}, [isEnabled, resolve]);
|
|
151
|
+
|
|
152
|
+
return { state, retry };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Sentinel state used when the gate is disabled. The consumer must treat
|
|
157
|
+
* `status === "ready"` without accessing `account` when auth is disabled
|
|
158
|
+
* (there is no real identity in that mode).
|
|
159
|
+
*/
|
|
160
|
+
const BYPASSED_STATE: IdentityAccountGateState = Object.freeze({
|
|
161
|
+
status: "ready",
|
|
162
|
+
account: null as unknown as IdentityAccount,
|
|
163
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
export { StigmerProvider, type StigmerProviderProps } from "./provider";
|
|
3
3
|
export { StigmerContext } from "./context";
|
|
4
4
|
|
|
5
|
+
// Fetch cache
|
|
6
|
+
export { FetchCacheProvider } from "./internal/FetchCacheProvider";
|
|
7
|
+
export type { FetchCacheOptions } from "./internal/fetch-cache";
|
|
8
|
+
|
|
5
9
|
// Hooks
|
|
6
10
|
export { useStigmer } from "./hooks";
|
|
7
11
|
|
|
@@ -139,6 +143,7 @@ export {
|
|
|
139
143
|
SubAgentSection,
|
|
140
144
|
MessageEntry,
|
|
141
145
|
MessageThread,
|
|
146
|
+
ThreadSkeleton,
|
|
142
147
|
FollowUpInput,
|
|
143
148
|
ApprovalCard,
|
|
144
149
|
ArtifactCard,
|
|
@@ -189,6 +194,7 @@ export type {
|
|
|
189
194
|
SubAgentSectionProps,
|
|
190
195
|
MessageEntryProps,
|
|
191
196
|
MessageThreadProps,
|
|
197
|
+
ThreadSkeletonProps,
|
|
192
198
|
FollowUpInputProps,
|
|
193
199
|
ApprovalCardProps,
|
|
194
200
|
ArtifactCardProps,
|
|
@@ -417,6 +423,15 @@ export type {
|
|
|
417
423
|
UseSessionEnvPoolReturn,
|
|
418
424
|
} from "./environment";
|
|
419
425
|
|
|
426
|
+
// Identity Account — gate hook for ensuring the caller's identity account exists before app render
|
|
427
|
+
export {
|
|
428
|
+
useIdentityAccountGate,
|
|
429
|
+
} from "./identity-account";
|
|
430
|
+
export type {
|
|
431
|
+
IdentityAccountGateState,
|
|
432
|
+
UseIdentityAccountGateReturn,
|
|
433
|
+
} from "./identity-account";
|
|
434
|
+
|
|
420
435
|
// IAM Policy — data hooks, behavior hooks, headless hook, and styled components for access management
|
|
421
436
|
export {
|
|
422
437
|
useGrantableRoles,
|
|
@@ -474,6 +489,53 @@ export type {
|
|
|
474
489
|
OrgSwitcherProps,
|
|
475
490
|
} from "./organization";
|
|
476
491
|
|
|
492
|
+
// Billing — data hooks, behavior hooks, styled components, catalog, and formatting utilities
|
|
493
|
+
export {
|
|
494
|
+
useBillingAccount,
|
|
495
|
+
useCreditLedger,
|
|
496
|
+
useBillingUsageReport,
|
|
497
|
+
useCustomerModelPricing,
|
|
498
|
+
useCreateCheckoutSession,
|
|
499
|
+
useCreateBillingPortalSession,
|
|
500
|
+
useSetAutoRechargeConfig,
|
|
501
|
+
BillingSection,
|
|
502
|
+
CreditBalanceCard,
|
|
503
|
+
PaymentMethodCard,
|
|
504
|
+
AutoRechargeCard,
|
|
505
|
+
CreditPackGrid,
|
|
506
|
+
CreditLedgerTable,
|
|
507
|
+
LowBalanceBanner,
|
|
508
|
+
CREDIT_PACKS,
|
|
509
|
+
formatPackPrice,
|
|
510
|
+
formatCreditCount,
|
|
511
|
+
formatCreditBalance,
|
|
512
|
+
formatLedgerAmount,
|
|
513
|
+
ledgerEntryLabel,
|
|
514
|
+
isCredit,
|
|
515
|
+
isHold,
|
|
516
|
+
formatLedgerDate,
|
|
517
|
+
} from "./billing";
|
|
518
|
+
export type {
|
|
519
|
+
UseBillingAccountReturn,
|
|
520
|
+
UseCreditLedgerReturn,
|
|
521
|
+
UseCreditLedgerOptions,
|
|
522
|
+
UseBillingUsageReportReturn,
|
|
523
|
+
UseCustomerModelPricingReturn,
|
|
524
|
+
CreateCheckoutSessionInput,
|
|
525
|
+
UseCreateCheckoutSessionReturn,
|
|
526
|
+
UseCreateBillingPortalSessionReturn,
|
|
527
|
+
SetAutoRechargeConfigInput,
|
|
528
|
+
UseSetAutoRechargeConfigReturn,
|
|
529
|
+
BillingSectionProps,
|
|
530
|
+
CreditBalanceCardProps,
|
|
531
|
+
PaymentMethodCardProps,
|
|
532
|
+
AutoRechargeCardProps,
|
|
533
|
+
CreditPackGridProps,
|
|
534
|
+
CreditLedgerTableProps,
|
|
535
|
+
LowBalanceBannerProps,
|
|
536
|
+
CreditPackInfo,
|
|
537
|
+
} from "./billing";
|
|
538
|
+
|
|
477
539
|
// Settings — navigation structure + section components shared across app shells
|
|
478
540
|
export { SETTINGS_NAV_GROUPS } from "./settings";
|
|
479
541
|
export type { SettingsNavItem, SettingsNavGroup } from "./settings";
|
|
@@ -666,6 +728,11 @@ export type {
|
|
|
666
728
|
export {
|
|
667
729
|
useOrgUsageReport,
|
|
668
730
|
OrgUsagePanel,
|
|
731
|
+
CreditRunwayIndicator,
|
|
732
|
+
AgentBreakdownList,
|
|
733
|
+
HarnessSplitCard,
|
|
734
|
+
useExportCSV,
|
|
735
|
+
ExportButton,
|
|
669
736
|
DATE_RANGE_PRESETS,
|
|
670
737
|
dateRangeFromPreset,
|
|
671
738
|
formatDateRange,
|
|
@@ -674,6 +741,12 @@ export {
|
|
|
674
741
|
export type {
|
|
675
742
|
UseOrgUsageReportReturn,
|
|
676
743
|
OrgUsagePanelProps,
|
|
744
|
+
CreditRunwayIndicatorProps,
|
|
745
|
+
AgentBreakdownListProps,
|
|
746
|
+
HarnessSplitCardProps,
|
|
747
|
+
UseExportCSVReturn,
|
|
748
|
+
ExportFormat,
|
|
749
|
+
ExportButtonProps,
|
|
677
750
|
DateRange,
|
|
678
751
|
DateRangePreset,
|
|
679
752
|
} from "./usage";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, useRef, type ReactNode } from "react";
|
|
4
|
+
import { FetchCache, type FetchCacheOptions } from "./fetch-cache";
|
|
5
|
+
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Context
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @internal Exported for test-level injection — not part of the public API.
|
|
12
|
+
*/
|
|
13
|
+
export const FetchCacheContext = createContext<FetchCache | null>(null);
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Provider
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Provides a `FetchCache` instance to descendant `useFetch` hooks.
|
|
21
|
+
*
|
|
22
|
+
* Mount this component **above** any remount boundary (e.g. above a
|
|
23
|
+
* `key`-driven session switch) so that cached data survives when child
|
|
24
|
+
* components unmount and remount. Without this provider, `useFetch`
|
|
25
|
+
* works exactly as before — no cache, no behavior change.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* // In your app shell (above the session key boundary):
|
|
30
|
+
* <FetchCacheProvider>
|
|
31
|
+
* <SessionPageInner key={activeSessionId} id={activeSessionId} />
|
|
32
|
+
* </FetchCacheProvider>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* // With custom limits:
|
|
38
|
+
* <FetchCacheProvider maxEntries={50} ttl={120_000}>
|
|
39
|
+
* <App />
|
|
40
|
+
* </FetchCacheProvider>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function FetchCacheProvider({
|
|
44
|
+
children,
|
|
45
|
+
maxEntries,
|
|
46
|
+
ttl,
|
|
47
|
+
}: FetchCacheOptions & { children: ReactNode }) {
|
|
48
|
+
const cacheRef = useRef<FetchCache | null>(null);
|
|
49
|
+
if (!cacheRef.current) {
|
|
50
|
+
cacheRef.current = new FetchCache({ maxEntries, ttl });
|
|
51
|
+
}
|
|
52
|
+
return (
|
|
53
|
+
<FetchCacheContext.Provider value={cacheRef.current}>
|
|
54
|
+
{children}
|
|
55
|
+
</FetchCacheContext.Provider>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Hook
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Access the nearest `FetchCache` from context.
|
|
65
|
+
*
|
|
66
|
+
* Returns `null` when no `FetchCacheProvider` is mounted — callers
|
|
67
|
+
* must handle the null case gracefully (skip caching).
|
|
68
|
+
*
|
|
69
|
+
* @internal Consumed by `useFetch`; not intended for direct use by
|
|
70
|
+
* SDK consumers.
|
|
71
|
+
*/
|
|
72
|
+
export function useFetchCache(): FetchCache | null {
|
|
73
|
+
return useContext(FetchCacheContext);
|
|
74
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@stigmer/theme";
|
|
4
|
+
|
|
5
|
+
interface JumpToLatestButtonProps {
|
|
6
|
+
readonly onClick: () => void;
|
|
7
|
+
readonly visible: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Floating action button that scrolls the thread to the latest content.
|
|
12
|
+
* Always mounted in the DOM to support enter/exit CSS transitions.
|
|
13
|
+
* Hidden via opacity + pointer-events when `visible` is false.
|
|
14
|
+
*
|
|
15
|
+
* @internal Not part of the public API.
|
|
16
|
+
*/
|
|
17
|
+
export function JumpToLatestButton({ onClick, visible }: JumpToLatestButtonProps) {
|
|
18
|
+
return (
|
|
19
|
+
<button
|
|
20
|
+
type="button"
|
|
21
|
+
onClick={onClick}
|
|
22
|
+
aria-label="Jump to latest"
|
|
23
|
+
aria-hidden={!visible}
|
|
24
|
+
tabIndex={visible ? 0 : -1}
|
|
25
|
+
className={cn(
|
|
26
|
+
"absolute bottom-3 left-1/2 z-10 -translate-x-1/2",
|
|
27
|
+
"flex items-center gap-1.5 rounded-full",
|
|
28
|
+
"border border-border bg-card px-3 py-1.5",
|
|
29
|
+
"text-xs font-medium text-muted-foreground shadow-md",
|
|
30
|
+
"transition-[opacity,transform] duration-[var(--stgm-motion-duration)]",
|
|
31
|
+
"hover:bg-muted hover:text-foreground",
|
|
32
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
33
|
+
visible
|
|
34
|
+
? "pointer-events-auto translate-y-0 opacity-100"
|
|
35
|
+
: "pointer-events-none translate-y-2 opacity-0",
|
|
36
|
+
)}
|
|
37
|
+
>
|
|
38
|
+
<ChevronDownIcon />
|
|
39
|
+
Jump to latest
|
|
40
|
+
</button>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function ChevronDownIcon() {
|
|
45
|
+
return (
|
|
46
|
+
<svg
|
|
47
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
48
|
+
width="14"
|
|
49
|
+
height="14"
|
|
50
|
+
viewBox="0 0 24 24"
|
|
51
|
+
fill="none"
|
|
52
|
+
stroke="currentColor"
|
|
53
|
+
strokeWidth="2.5"
|
|
54
|
+
strokeLinecap="round"
|
|
55
|
+
strokeLinejoin="round"
|
|
56
|
+
aria-hidden="true"
|
|
57
|
+
>
|
|
58
|
+
<path d="m6 9 6 6 6-6" />
|
|
59
|
+
</svg>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useRef, useState, type ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
interface ThreadItemWrapperProps {
|
|
6
|
+
readonly animate: boolean;
|
|
7
|
+
readonly children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const ANIMATION_CLASS = "stgm-thread-item-enter";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Thin wrapper that applies the `.stgm-thread-item-enter` CSS animation
|
|
14
|
+
* on mount when `animate` is true. The class is removed after the
|
|
15
|
+
* animation completes (via `onAnimationEnd`) to free the browser from
|
|
16
|
+
* tracking a finished animation.
|
|
17
|
+
*
|
|
18
|
+
* A fallback timeout removes the class if `animationend` never fires
|
|
19
|
+
* (e.g. `prefers-reduced-motion` sets duration to ~0ms, or the test
|
|
20
|
+
* environment doesn't dispatch animation events).
|
|
21
|
+
*
|
|
22
|
+
* @internal Not part of the public API.
|
|
23
|
+
*/
|
|
24
|
+
export function ThreadItemWrapper({ animate, children }: ThreadItemWrapperProps) {
|
|
25
|
+
const [entering, setEntering] = useState(animate);
|
|
26
|
+
const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
|
27
|
+
|
|
28
|
+
const handleAnimationEnd = useCallback(() => {
|
|
29
|
+
setEntering(false);
|
|
30
|
+
if (timerRef.current !== undefined) {
|
|
31
|
+
clearTimeout(timerRef.current);
|
|
32
|
+
timerRef.current = undefined;
|
|
33
|
+
}
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
const divRef = useCallback(
|
|
37
|
+
(node: HTMLDivElement | null) => {
|
|
38
|
+
if (timerRef.current !== undefined) {
|
|
39
|
+
clearTimeout(timerRef.current);
|
|
40
|
+
timerRef.current = undefined;
|
|
41
|
+
}
|
|
42
|
+
if (node && entering) {
|
|
43
|
+
timerRef.current = setTimeout(() => {
|
|
44
|
+
setEntering(false);
|
|
45
|
+
timerRef.current = undefined;
|
|
46
|
+
}, 300);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
[entering],
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (!entering) {
|
|
53
|
+
return children;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div
|
|
58
|
+
ref={divRef}
|
|
59
|
+
className={ANIMATION_CLASS}
|
|
60
|
+
onAnimationEnd={handleAnimationEnd}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
forwardRef,
|
|
5
|
+
useCallback,
|
|
6
|
+
useMemo,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
type ComponentPropsWithRef,
|
|
10
|
+
} from "react";
|
|
11
|
+
import { Virtuoso, type VirtuosoHandle } from "react-virtuoso";
|
|
12
|
+
import { cn } from "@stigmer/theme";
|
|
13
|
+
import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
14
|
+
import { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
15
|
+
import {
|
|
16
|
+
ThreadItemRenderer,
|
|
17
|
+
type ThreadItem,
|
|
18
|
+
} from "../execution/MessageThread";
|
|
19
|
+
import { FilePathContext, type FilePathContextValue } from "../execution/FilePathContext";
|
|
20
|
+
import { SandboxContext, type SandboxContextValue } from "../execution/SandboxContext";
|
|
21
|
+
import { DevProfiler, useDomNodeCount } from "./dev";
|
|
22
|
+
import { JumpToLatestButton } from "./JumpToLatestButton";
|
|
23
|
+
import { ThreadItemWrapper } from "./ThreadItemWrapper";
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Props
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
export interface VirtualizedThreadProps {
|
|
30
|
+
readonly items: readonly ThreadItem[];
|
|
31
|
+
readonly formatToolCallSummary?: (toolCalls: readonly ToolCall[]) => string;
|
|
32
|
+
readonly onApprovalSubmit?: (
|
|
33
|
+
toolCallId: string,
|
|
34
|
+
action: ApprovalAction,
|
|
35
|
+
comment?: string,
|
|
36
|
+
) => void;
|
|
37
|
+
readonly submittingApprovalIds?: ReadonlySet<string>;
|
|
38
|
+
readonly filePathCtx: FilePathContextValue;
|
|
39
|
+
readonly sandboxCtx: SandboxContextValue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Scrollbar classes shared with the non-virtualized path
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
const SCROLLBAR_CLASSES = cn(
|
|
47
|
+
"[scrollbar-width:thin] [scrollbar-color:var(--color-border)_transparent]",
|
|
48
|
+
"[&::-webkit-scrollbar]:w-1.5",
|
|
49
|
+
"[&::-webkit-scrollbar-track]:bg-transparent",
|
|
50
|
+
"[&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-border/40",
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Custom Virtuoso components
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
const ScrollerWithA11y = forwardRef<
|
|
58
|
+
HTMLDivElement,
|
|
59
|
+
ComponentPropsWithRef<"div">
|
|
60
|
+
>(function ScrollerWithA11y(props, ref) {
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
{...props}
|
|
64
|
+
ref={ref}
|
|
65
|
+
role="log"
|
|
66
|
+
aria-live="polite"
|
|
67
|
+
aria-relevant="additions"
|
|
68
|
+
className={cn(props.className, SCROLLBAR_CLASSES)}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// VirtualizedThread
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
const NEAR_BOTTOM_THRESHOLD_PX = 80;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Internal component that renders a `MessageThread` item list via
|
|
81
|
+
* `react-virtuoso`. Handles bottom-anchored chat layout,
|
|
82
|
+
* follow-output scroll behavior, and the "Jump to latest" button.
|
|
83
|
+
*
|
|
84
|
+
* Not part of the public API — used only when `MessageThread` receives
|
|
85
|
+
* `virtualized={true}`.
|
|
86
|
+
*
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
export function VirtualizedThread({
|
|
90
|
+
items,
|
|
91
|
+
formatToolCallSummary,
|
|
92
|
+
onApprovalSubmit,
|
|
93
|
+
submittingApprovalIds,
|
|
94
|
+
filePathCtx,
|
|
95
|
+
sandboxCtx,
|
|
96
|
+
}: VirtualizedThreadProps) {
|
|
97
|
+
const virtuosoRef = useRef<VirtuosoHandle>(null);
|
|
98
|
+
const scrollerRef = useRef<HTMLDivElement | null>(null);
|
|
99
|
+
const [isAtBottom, setIsAtBottom] = useState(true);
|
|
100
|
+
|
|
101
|
+
useDomNodeCount(scrollerRef, "MessageThread:virtualized");
|
|
102
|
+
|
|
103
|
+
const handleFollowOutput = useCallback(
|
|
104
|
+
(atBottom: boolean) => (atBottom ? "smooth" : false),
|
|
105
|
+
[],
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const handleScrollerRef = useCallback((ref: HTMLElement | Window | null) => {
|
|
109
|
+
scrollerRef.current = ref instanceof HTMLDivElement ? ref : null;
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
const jumpToLatest = useCallback(() => {
|
|
113
|
+
virtuosoRef.current?.scrollToIndex({
|
|
114
|
+
index: "LAST",
|
|
115
|
+
behavior: "smooth",
|
|
116
|
+
});
|
|
117
|
+
}, []);
|
|
118
|
+
|
|
119
|
+
const renderProps = useMemo(
|
|
120
|
+
() => ({
|
|
121
|
+
formatToolCallSummary,
|
|
122
|
+
onApprovalSubmit,
|
|
123
|
+
submittingApprovalIds,
|
|
124
|
+
}),
|
|
125
|
+
[formatToolCallSummary, onApprovalSubmit, submittingApprovalIds],
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<>
|
|
130
|
+
<SandboxContext.Provider value={sandboxCtx}>
|
|
131
|
+
<FilePathContext.Provider value={filePathCtx}>
|
|
132
|
+
<DevProfiler id="MessageThread:virtualized">
|
|
133
|
+
<Virtuoso
|
|
134
|
+
ref={virtuosoRef}
|
|
135
|
+
data={items as ThreadItem[]}
|
|
136
|
+
alignToBottom
|
|
137
|
+
followOutput={handleFollowOutput}
|
|
138
|
+
atBottomStateChange={setIsAtBottom}
|
|
139
|
+
atBottomThreshold={NEAR_BOTTOM_THRESHOLD_PX}
|
|
140
|
+
computeItemKey={(_index, item) => item.key}
|
|
141
|
+
increaseViewportBy={{ top: 200, bottom: 200 }}
|
|
142
|
+
scrollerRef={handleScrollerRef}
|
|
143
|
+
className="h-full"
|
|
144
|
+
components={{ Scroller: ScrollerWithA11y }}
|
|
145
|
+
itemContent={(index, item) => (
|
|
146
|
+
<div className="pb-4 pt-0 first:pt-6">
|
|
147
|
+
<ThreadItemWrapper animate={index >= items.length - 2}>
|
|
148
|
+
<ThreadItemRenderer
|
|
149
|
+
item={item}
|
|
150
|
+
{...renderProps}
|
|
151
|
+
/>
|
|
152
|
+
</ThreadItemWrapper>
|
|
153
|
+
</div>
|
|
154
|
+
)}
|
|
155
|
+
/>
|
|
156
|
+
</DevProfiler>
|
|
157
|
+
</FilePathContext.Provider>
|
|
158
|
+
</SandboxContext.Provider>
|
|
159
|
+
<JumpToLatestButton onClick={jumpToLatest} visible={!isAtBottom} />
|
|
160
|
+
</>
|
|
161
|
+
);
|
|
162
|
+
}
|