@stigmer/react 0.0.71 → 0.0.73
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/agent/AgentEnvForm.d.ts +2 -0
- package/agent/AgentEnvForm.d.ts.map +1 -1
- package/agent/AgentEnvForm.js.map +1 -1
- package/agent/AgentPicker.d.ts +2 -0
- package/agent/AgentPicker.d.ts.map +1 -1
- package/agent/AgentPicker.js.map +1 -1
- package/agent/agentSetupReducer.d.ts +69 -7
- package/agent/agentSetupReducer.d.ts.map +1 -1
- package/agent/agentSetupReducer.js.map +1 -1
- package/agent/useAgentCount.d.ts +2 -0
- package/agent/useAgentCount.d.ts.map +1 -1
- package/agent/useAgentCount.js.map +1 -1
- package/attachment/AttachmentChipList.d.ts +15 -0
- package/attachment/AttachmentChipList.d.ts.map +1 -1
- package/attachment/AttachmentChipList.js +15 -0
- package/attachment/AttachmentChipList.js.map +1 -1
- package/attachment/useAttachments.d.ts +14 -0
- package/attachment/useAttachments.d.ts.map +1 -1
- package/attachment/useAttachments.js.map +1 -1
- package/composer/useComposer.d.ts +5 -0
- package/composer/useComposer.d.ts.map +1 -1
- package/composer/useComposer.js.map +1 -1
- package/execution/ExecutionPhaseBadge.d.ts +1 -1
- package/execution/ExecutionPhaseBadge.js +1 -1
- package/execution/McpToolDetail.d.ts +16 -8
- package/execution/McpToolDetail.d.ts.map +1 -1
- package/execution/McpToolDetail.js +0 -6
- package/execution/McpToolDetail.js.map +1 -1
- package/execution/TodoList.d.ts +8 -0
- package/execution/TodoList.d.ts.map +1 -1
- package/execution/TodoList.js +8 -0
- package/execution/TodoList.js.map +1 -1
- package/execution/ToolArgsView.d.ts +1 -0
- package/execution/ToolArgsView.d.ts.map +1 -1
- package/execution/ToolArgsView.js.map +1 -1
- package/execution/UsageWidget.d.ts +1 -1
- package/execution/UsageWidget.js +1 -1
- package/execution/file-path-resolver.d.ts +10 -0
- package/execution/file-path-resolver.d.ts.map +1 -1
- package/execution/file-path-resolver.js.map +1 -1
- package/execution/index.d.ts +1 -1
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js.map +1 -1
- package/execution/useArtifactContent.d.ts +33 -0
- package/execution/useArtifactContent.d.ts.map +1 -1
- package/execution/useArtifactContent.js +33 -0
- package/execution/useArtifactContent.js.map +1 -1
- package/execution/useSubmitApproval.d.ts +2 -0
- package/execution/useSubmitApproval.d.ts.map +1 -1
- package/execution/useSubmitApproval.js.map +1 -1
- package/github/GitHubRepoPicker.d.ts +13 -0
- package/github/GitHubRepoPicker.d.ts.map +1 -1
- package/github/GitHubRepoPicker.js +13 -0
- package/github/GitHubRepoPicker.js.map +1 -1
- package/github/useGitHubConnection.d.ts +29 -1
- package/github/useGitHubConnection.d.ts.map +1 -1
- package/github/useGitHubConnection.js +29 -1
- package/github/useGitHubConnection.js.map +1 -1
- package/github/useGitHubRepos.d.ts +31 -0
- package/github/useGitHubRepos.d.ts.map +1 -1
- package/github/useGitHubRepos.js +31 -0
- package/github/useGitHubRepos.js.map +1 -1
- package/github/useGitHubSearch.d.ts +25 -0
- package/github/useGitHubSearch.d.ts.map +1 -1
- package/github/useGitHubSearch.js +25 -0
- package/github/useGitHubSearch.js.map +1 -1
- package/iam-policy/GrantAccessForm.d.ts +39 -0
- package/iam-policy/GrantAccessForm.d.ts.map +1 -0
- package/iam-policy/GrantAccessForm.js +75 -0
- package/iam-policy/GrantAccessForm.js.map +1 -0
- package/iam-policy/OrgMembersPanel.d.ts +28 -0
- package/iam-policy/OrgMembersPanel.d.ts.map +1 -0
- package/iam-policy/OrgMembersPanel.js +192 -0
- package/iam-policy/OrgMembersPanel.js.map +1 -0
- package/iam-policy/RoleSelector.d.ts +37 -0
- package/iam-policy/RoleSelector.d.ts.map +1 -0
- package/iam-policy/RoleSelector.js +42 -0
- package/iam-policy/RoleSelector.js.map +1 -0
- package/iam-policy/index.d.ts +12 -0
- package/iam-policy/index.d.ts.map +1 -0
- package/iam-policy/index.js +12 -0
- package/iam-policy/index.js.map +1 -0
- package/iam-policy/useCreateIamPolicy.d.ts +35 -0
- package/iam-policy/useCreateIamPolicy.d.ts.map +1 -0
- package/iam-policy/useCreateIamPolicy.js +46 -0
- package/iam-policy/useCreateIamPolicy.js.map +1 -0
- package/iam-policy/useDeleteIamPolicy.d.ts +34 -0
- package/iam-policy/useDeleteIamPolicy.d.ts.map +1 -0
- package/iam-policy/useDeleteIamPolicy.js +45 -0
- package/iam-policy/useDeleteIamPolicy.js.map +1 -0
- package/iam-policy/useGrantableRoles.d.ts +28 -0
- package/iam-policy/useGrantableRoles.d.ts.map +1 -0
- package/iam-policy/useGrantableRoles.js +32 -0
- package/iam-policy/useGrantableRoles.js.map +1 -0
- package/iam-policy/usePrincipalsCount.d.ts +31 -0
- package/iam-policy/usePrincipalsCount.d.ts.map +1 -0
- package/iam-policy/usePrincipalsCount.js +72 -0
- package/iam-policy/usePrincipalsCount.js.map +1 -0
- package/iam-policy/useResourceAccess.d.ts +51 -0
- package/iam-policy/useResourceAccess.d.ts.map +1 -0
- package/iam-policy/useResourceAccess.js +85 -0
- package/iam-policy/useResourceAccess.js.map +1 -0
- package/iam-policy/useRevokeOrgAccess.d.ts +36 -0
- package/iam-policy/useRevokeOrgAccess.d.ts.map +1 -0
- package/iam-policy/useRevokeOrgAccess.js +48 -0
- package/iam-policy/useRevokeOrgAccess.js.map +1 -0
- package/iam-policy/useRoleSelector.d.ts +52 -0
- package/iam-policy/useRoleSelector.d.ts.map +1 -0
- package/iam-policy/useRoleSelector.js +50 -0
- package/iam-policy/useRoleSelector.js.map +1 -0
- package/iam-policy/useWhoAmI.d.ts +30 -0
- package/iam-policy/useWhoAmI.d.ts.map +1 -0
- package/iam-policy/useWhoAmI.js +56 -0
- package/iam-policy/useWhoAmI.js.map +1 -0
- package/identity-provider/CreateIdentityProviderForm.d.ts +39 -0
- package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -0
- package/identity-provider/CreateIdentityProviderForm.js +102 -0
- package/identity-provider/CreateIdentityProviderForm.js.map +1 -0
- package/identity-provider/IdentityProviderDetailPanel.d.ts +42 -0
- package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -0
- package/identity-provider/IdentityProviderDetailPanel.js +156 -0
- package/identity-provider/IdentityProviderDetailPanel.js.map +1 -0
- package/identity-provider/IdentityProviderListPanel.d.ts +41 -0
- package/identity-provider/IdentityProviderListPanel.d.ts.map +1 -0
- package/identity-provider/IdentityProviderListPanel.js +110 -0
- package/identity-provider/IdentityProviderListPanel.js.map +1 -0
- package/identity-provider/IdentityProviderWizard.d.ts +40 -0
- package/identity-provider/IdentityProviderWizard.d.ts.map +1 -0
- package/identity-provider/IdentityProviderWizard.js +180 -0
- package/identity-provider/IdentityProviderWizard.js.map +1 -0
- package/identity-provider/ProviderPicker.d.ts +28 -0
- package/identity-provider/ProviderPicker.d.ts.map +1 -0
- package/identity-provider/ProviderPicker.js +64 -0
- package/identity-provider/ProviderPicker.js.map +1 -0
- package/identity-provider/SsoLoginPrompt.d.ts +51 -0
- package/identity-provider/SsoLoginPrompt.d.ts.map +1 -0
- package/identity-provider/SsoLoginPrompt.js +119 -0
- package/identity-provider/SsoLoginPrompt.js.map +1 -0
- package/identity-provider/index.d.ts +14 -0
- package/identity-provider/index.d.ts.map +1 -0
- package/identity-provider/index.js +14 -0
- package/identity-provider/index.js.map +1 -0
- package/identity-provider/presets.d.ts +65 -0
- package/identity-provider/presets.d.ts.map +1 -0
- package/identity-provider/presets.js +200 -0
- package/identity-provider/presets.js.map +1 -0
- package/identity-provider/useCreateIdentityProvider.d.ts +37 -0
- package/identity-provider/useCreateIdentityProvider.d.ts.map +1 -0
- package/identity-provider/useCreateIdentityProvider.js +48 -0
- package/identity-provider/useCreateIdentityProvider.js.map +1 -0
- package/identity-provider/useDeleteIdentityProvider.d.ts +34 -0
- package/identity-provider/useDeleteIdentityProvider.d.ts.map +1 -0
- package/identity-provider/useDeleteIdentityProvider.js +45 -0
- package/identity-provider/useDeleteIdentityProvider.js.map +1 -0
- package/identity-provider/useIdentityProvider.d.ts +37 -0
- package/identity-provider/useIdentityProvider.d.ts.map +1 -0
- package/identity-provider/useIdentityProvider.js +62 -0
- package/identity-provider/useIdentityProvider.js.map +1 -0
- package/identity-provider/useIdentityProviderList.d.ts +48 -0
- package/identity-provider/useIdentityProviderList.d.ts.map +1 -0
- package/identity-provider/useIdentityProviderList.js +75 -0
- package/identity-provider/useIdentityProviderList.js.map +1 -0
- package/identity-provider/useOidcDiscovery.d.ts +39 -0
- package/identity-provider/useOidcDiscovery.d.ts.map +1 -0
- package/identity-provider/useOidcDiscovery.js +76 -0
- package/identity-provider/useOidcDiscovery.js.map +1 -0
- package/identity-provider/useSsoProvider.d.ts +50 -0
- package/identity-provider/useSsoProvider.d.ts.map +1 -0
- package/identity-provider/useSsoProvider.js +83 -0
- package/identity-provider/useSsoProvider.js.map +1 -0
- package/identity-provider/useUpdateIdentityProvider.d.ts +38 -0
- package/identity-provider/useUpdateIdentityProvider.d.ts.map +1 -0
- package/identity-provider/useUpdateIdentityProvider.js +49 -0
- package/identity-provider/useUpdateIdentityProvider.js.map +1 -0
- package/index.d.ts +14 -5
- package/index.d.ts.map +1 -1
- package/index.js +10 -2
- package/index.js.map +1 -1
- package/internal/CloudFeatureNotice.d.ts +12 -0
- package/internal/CloudFeatureNotice.d.ts.map +1 -1
- package/internal/CloudFeatureNotice.js +12 -0
- package/internal/CloudFeatureNotice.js.map +1 -1
- package/invitation/InvitationCreatedAlert.d.ts +35 -0
- package/invitation/InvitationCreatedAlert.d.ts.map +1 -0
- package/invitation/InvitationCreatedAlert.js +60 -0
- package/invitation/InvitationCreatedAlert.js.map +1 -0
- package/invitation/InvitationManager.d.ts +44 -0
- package/invitation/InvitationManager.d.ts.map +1 -0
- package/invitation/InvitationManager.js +248 -0
- package/invitation/InvitationManager.js.map +1 -0
- package/invitation/InvitationRedemption.d.ts +69 -0
- package/invitation/InvitationRedemption.d.ts.map +1 -0
- package/invitation/InvitationRedemption.js +140 -0
- package/invitation/InvitationRedemption.js.map +1 -0
- package/invitation/index.d.ts +17 -0
- package/invitation/index.d.ts.map +1 -0
- package/invitation/index.js +9 -0
- package/invitation/index.js.map +1 -0
- package/invitation/useCreateInvitation.d.ts +52 -0
- package/invitation/useCreateInvitation.d.ts.map +1 -0
- package/invitation/useCreateInvitation.js +55 -0
- package/invitation/useCreateInvitation.js.map +1 -0
- package/invitation/useInvitationPreview.d.ts +51 -0
- package/invitation/useInvitationPreview.d.ts.map +1 -0
- package/invitation/useInvitationPreview.js +80 -0
- package/invitation/useInvitationPreview.js.map +1 -0
- package/invitation/useOrgInvitations.d.ts +36 -0
- package/invitation/useOrgInvitations.d.ts.map +1 -0
- package/invitation/useOrgInvitations.js +65 -0
- package/invitation/useOrgInvitations.js.map +1 -0
- package/invitation/useRedeemInvitation.d.ts +47 -0
- package/invitation/useRedeemInvitation.d.ts.map +1 -0
- package/invitation/useRedeemInvitation.js +53 -0
- package/invitation/useRedeemInvitation.js.map +1 -0
- package/invitation/useRevokeInvitation.d.ts +35 -0
- package/invitation/useRevokeInvitation.d.ts.map +1 -0
- package/invitation/useRevokeInvitation.js +47 -0
- package/invitation/useRevokeInvitation.js.map +1 -0
- package/library/detect-skill-package.d.ts +1 -0
- package/library/detect-skill-package.d.ts.map +1 -1
- package/library/detect-skill-package.js.map +1 -1
- package/library/detect-stigmer-resource.d.ts +1 -0
- package/library/detect-stigmer-resource.d.ts.map +1 -1
- package/library/detect-stigmer-resource.js.map +1 -1
- package/library/parse-resource-yaml.d.ts +4 -0
- package/library/parse-resource-yaml.d.ts.map +1 -1
- package/library/parse-resource-yaml.js.map +1 -1
- package/mcp-server/McpServerDetailView.d.ts +2 -2
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/index.d.ts +1 -1
- package/mcp-server/index.d.ts.map +1 -1
- package/mcp-server/index.js.map +1 -1
- package/mcp-server/mcpServerSetupReducer.d.ts +54 -0
- package/mcp-server/mcpServerSetupReducer.d.ts.map +1 -1
- package/mcp-server/mcpServerSetupReducer.js.map +1 -1
- package/models/ModelSelector.d.ts +9 -0
- package/models/ModelSelector.d.ts.map +1 -1
- package/models/ModelSelector.js +9 -0
- package/models/ModelSelector.js.map +1 -1
- package/models/registry.d.ts +11 -1
- package/models/registry.d.ts.map +1 -1
- package/models/registry.js.map +1 -1
- package/models/useModelRegistry.d.ts +20 -0
- package/models/useModelRegistry.d.ts.map +1 -1
- package/models/useModelRegistry.js +20 -0
- package/models/useModelRegistry.js.map +1 -1
- package/organization/OrgProfilePanel.d.ts +31 -0
- package/organization/OrgProfilePanel.d.ts.map +1 -0
- package/organization/OrgProfilePanel.js +147 -0
- package/organization/OrgProfilePanel.js.map +1 -0
- package/organization/index.d.ts +6 -0
- package/organization/index.d.ts.map +1 -1
- package/organization/index.js +3 -0
- package/organization/index.js.map +1 -1
- package/organization/useOrganization.d.ts +31 -0
- package/organization/useOrganization.d.ts.map +1 -0
- package/organization/useOrganization.js +56 -0
- package/organization/useOrganization.js.map +1 -0
- package/organization/useUpdateOrganization.d.ts +40 -0
- package/organization/useUpdateOrganization.d.ts.map +1 -0
- package/organization/useUpdateOrganization.js +51 -0
- package/organization/useUpdateOrganization.js.map +1 -0
- package/package.json +4 -4
- package/provider.d.ts +1 -0
- package/provider.d.ts.map +1 -1
- package/provider.js.map +1 -1
- package/search/useResourceList.d.ts +4 -2
- package/search/useResourceList.d.ts.map +1 -1
- package/search/useResourceList.js +2 -1
- package/search/useResourceList.js.map +1 -1
- package/search/useResourceSearch.d.ts +10 -2
- package/search/useResourceSearch.d.ts.map +1 -1
- package/search/useResourceSearch.js +2 -1
- package/search/useResourceSearch.js.map +1 -1
- package/session/group-sessions.d.ts +23 -0
- package/session/group-sessions.d.ts.map +1 -1
- package/session/group-sessions.js +23 -0
- package/session/group-sessions.js.map +1 -1
- package/session/index.d.ts +1 -1
- package/session/index.d.ts.map +1 -1
- package/session/index.js.map +1 -1
- package/session/useCreateSession.d.ts +11 -2
- package/session/useCreateSession.d.ts.map +1 -1
- package/session/useCreateSession.js.map +1 -1
- package/session/useSession.d.ts +24 -0
- package/session/useSession.d.ts.map +1 -1
- package/session/useSession.js +24 -0
- package/session/useSession.js.map +1 -1
- package/session/useSessionArtifacts.d.ts +1 -0
- package/session/useSessionArtifacts.d.ts.map +1 -1
- package/session/useSessionArtifacts.js.map +1 -1
- package/session/useSessionConversation.d.ts +7 -0
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionExecutions.d.ts +23 -0
- package/session/useSessionExecutions.d.ts.map +1 -1
- package/session/useSessionExecutions.js +23 -0
- package/session/useSessionExecutions.js.map +1 -1
- package/session/useSessionList.d.ts +19 -0
- package/session/useSessionList.d.ts.map +1 -1
- package/session/useSessionList.js +19 -0
- package/session/useSessionList.js.map +1 -1
- package/session/useSessionWriteBacks.d.ts +1 -0
- package/session/useSessionWriteBacks.d.ts.map +1 -1
- package/session/useSessionWriteBacks.js.map +1 -1
- package/session/useUpdateSession.d.ts +22 -0
- package/session/useUpdateSession.d.ts.map +1 -1
- package/session/useUpdateSession.js +22 -0
- package/session/useUpdateSession.js.map +1 -1
- package/skill/SkillPicker.d.ts +15 -0
- package/skill/SkillPicker.d.ts.map +1 -1
- package/skill/SkillPicker.js +15 -0
- package/skill/SkillPicker.js.map +1 -1
- package/src/agent/AgentEnvForm.tsx +2 -0
- package/src/agent/AgentPicker.tsx +2 -0
- package/src/agent/agentSetupReducer.ts +109 -20
- package/src/agent/useAgentCount.ts +2 -0
- package/src/attachment/AttachmentChipList.tsx +15 -0
- package/src/attachment/useAttachments.ts +14 -0
- package/src/composer/useComposer.ts +5 -0
- package/src/execution/ExecutionPhaseBadge.tsx +1 -1
- package/src/execution/McpToolDetail.tsx +18 -6
- package/src/execution/TodoList.tsx +8 -0
- package/src/execution/ToolArgsView.tsx +1 -0
- package/src/execution/UsageWidget.tsx +1 -1
- package/src/execution/file-path-resolver.ts +28 -4
- package/src/execution/index.ts +5 -1
- package/src/execution/useArtifactContent.ts +33 -0
- package/src/execution/useSubmitApproval.ts +2 -0
- package/src/github/GitHubRepoPicker.tsx +13 -0
- package/src/github/useGitHubConnection.ts +29 -1
- package/src/github/useGitHubRepos.ts +31 -0
- package/src/github/useGitHubSearch.ts +25 -0
- package/src/iam-policy/GrantAccessForm.tsx +198 -0
- package/src/iam-policy/OrgMembersPanel.tsx +572 -0
- package/src/iam-policy/RoleSelector.tsx +105 -0
- package/src/iam-policy/index.ts +51 -0
- package/src/iam-policy/useCreateIamPolicy.ts +66 -0
- package/src/iam-policy/useDeleteIamPolicy.ts +65 -0
- package/src/iam-policy/useGrantableRoles.ts +45 -0
- package/src/iam-policy/usePrincipalsCount.ts +96 -0
- package/src/iam-policy/useResourceAccess.ts +128 -0
- package/src/iam-policy/useRevokeOrgAccess.ts +74 -0
- package/src/iam-policy/useRoleSelector.ts +97 -0
- package/src/iam-policy/useWhoAmI.ts +78 -0
- package/src/identity-provider/CreateIdentityProviderForm.tsx +308 -0
- package/src/identity-provider/IdentityProviderDetailPanel.tsx +583 -0
- package/src/identity-provider/IdentityProviderListPanel.tsx +370 -0
- package/src/identity-provider/IdentityProviderWizard.tsx +684 -0
- package/src/identity-provider/ProviderPicker.tsx +152 -0
- package/src/identity-provider/SsoLoginPrompt.tsx +404 -0
- package/src/identity-provider/index.ts +67 -0
- package/src/identity-provider/presets.ts +262 -0
- package/src/identity-provider/useCreateIdentityProvider.ts +68 -0
- package/src/identity-provider/useDeleteIdentityProvider.ts +65 -0
- package/src/identity-provider/useIdentityProvider.ts +86 -0
- package/src/identity-provider/useIdentityProviderList.ts +100 -0
- package/src/identity-provider/useOidcDiscovery.ts +124 -0
- package/src/identity-provider/useSsoProvider.ts +99 -0
- package/src/identity-provider/useUpdateIdentityProvider.ts +69 -0
- package/src/index.ts +121 -1
- package/src/internal/CloudFeatureNotice.tsx +12 -0
- package/src/invitation/InvitationCreatedAlert.tsx +185 -0
- package/src/invitation/InvitationManager.tsx +842 -0
- package/src/invitation/InvitationRedemption.tsx +434 -0
- package/src/invitation/index.ts +16 -0
- package/src/invitation/useCreateInvitation.ts +83 -0
- package/src/invitation/useInvitationPreview.ts +103 -0
- package/src/invitation/useOrgInvitations.ts +88 -0
- package/src/invitation/useRedeemInvitation.ts +82 -0
- package/src/invitation/useRevokeInvitation.ts +66 -0
- package/src/library/detect-skill-package.ts +4 -1
- package/src/library/detect-stigmer-resource.ts +4 -1
- package/src/library/parse-resource-yaml.ts +12 -2
- package/src/mcp-server/McpServerDetailView.tsx +2 -1
- package/src/mcp-server/index.ts +4 -1
- package/src/mcp-server/mcpServerSetupReducer.ts +86 -8
- package/src/models/ModelSelector.tsx +9 -0
- package/src/models/registry.ts +11 -1
- package/src/models/useModelRegistry.ts +20 -0
- package/src/organization/OrgProfilePanel.tsx +451 -0
- package/src/organization/index.ts +6 -0
- package/src/organization/useOrganization.ts +79 -0
- package/src/organization/useUpdateOrganization.ts +71 -0
- package/src/provider.tsx +1 -0
- package/src/search/useResourceList.ts +6 -3
- package/src/search/useResourceSearch.ts +12 -3
- package/src/session/group-sessions.ts +23 -0
- package/src/session/index.ts +1 -0
- package/src/session/useCreateSession.ts +19 -3
- package/src/session/useSession.ts +24 -0
- package/src/session/useSessionArtifacts.ts +1 -0
- package/src/session/useSessionConversation.ts +7 -0
- package/src/session/useSessionExecutions.ts +23 -0
- package/src/session/useSessionList.ts +19 -0
- package/src/session/useSessionWriteBacks.ts +1 -0
- package/src/session/useUpdateSession.ts +22 -0
- package/src/skill/SkillPicker.tsx +15 -0
- package/src/usage/OrgUsagePanel.tsx +465 -0
- package/src/usage/date-range.ts +86 -0
- package/src/usage/index.ts +13 -0
- package/src/usage/useOrgUsageReport.ts +110 -0
- package/src/workspace/FolderBrowser.tsx +9 -0
- package/src/workspace/WorkspaceEditor.tsx +17 -0
- package/src/workspace/useFolderListing.ts +24 -0
- package/src/workspace/useWorkspaceEntries.ts +38 -0
- package/styles.css +1 -1
- package/usage/OrgUsagePanel.d.ts +24 -0
- package/usage/OrgUsagePanel.d.ts.map +1 -0
- package/usage/OrgUsagePanel.js +134 -0
- package/usage/OrgUsagePanel.js.map +1 -0
- package/usage/date-range.d.ts +36 -0
- package/usage/date-range.d.ts.map +1 -0
- package/usage/date-range.js +69 -0
- package/usage/date-range.js.map +1 -0
- package/usage/index.d.ts +7 -0
- package/usage/index.d.ts.map +1 -0
- package/usage/index.js +4 -0
- package/usage/index.js.map +1 -0
- package/usage/useOrgUsageReport.d.ts +48 -0
- package/usage/useOrgUsageReport.d.ts.map +1 -0
- package/usage/useOrgUsageReport.js +72 -0
- package/usage/useOrgUsageReport.js.map +1 -0
- package/workspace/FolderBrowser.d.ts +9 -0
- package/workspace/FolderBrowser.d.ts.map +1 -1
- package/workspace/FolderBrowser.js +9 -0
- package/workspace/FolderBrowser.js.map +1 -1
- package/workspace/WorkspaceEditor.d.ts +17 -0
- package/workspace/WorkspaceEditor.d.ts.map +1 -1
- package/workspace/WorkspaceEditor.js +17 -0
- package/workspace/WorkspaceEditor.js.map +1 -1
- package/workspace/useFolderListing.d.ts +24 -0
- package/workspace/useFolderListing.d.ts.map +1 -1
- package/workspace/useFolderListing.js +24 -0
- package/workspace/useFolderListing.js.map +1 -1
- package/workspace/useWorkspaceEntries.d.ts +38 -0
- package/workspace/useWorkspaceEntries.d.ts.map +1 -1
- package/workspace/useWorkspaceEntries.js +25 -0
- package/workspace/useWorkspaceEntries.js.map +1 -1
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { cn } from "@stigmer/theme";
|
|
5
|
+
import { getUserMessage } from "@stigmer/sdk";
|
|
6
|
+
import type { ModelUsage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/usage_pb";
|
|
7
|
+
import type {
|
|
8
|
+
DailyCostEntry,
|
|
9
|
+
GetOrgUsageReportOutput,
|
|
10
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
|
|
11
|
+
import { formatCost, formatTokenCount } from "../execution/UsageWidget";
|
|
12
|
+
import { useOrgUsageReport } from "./useOrgUsageReport";
|
|
13
|
+
import {
|
|
14
|
+
DATE_RANGE_PRESETS,
|
|
15
|
+
dateRangeFromPreset,
|
|
16
|
+
formatDateRange,
|
|
17
|
+
presetLabel,
|
|
18
|
+
type DateRangePreset,
|
|
19
|
+
} from "./date-range";
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Public API
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
/** Props for {@link OrgUsagePanel}. */
|
|
26
|
+
export interface OrgUsagePanelProps {
|
|
27
|
+
/** Organization ID (`metadata.id`) to fetch usage for. */
|
|
28
|
+
readonly orgId: string;
|
|
29
|
+
/** Additional CSS class names for the root container. */
|
|
30
|
+
readonly className?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Self-contained dashboard panel showing organization-wide LLM usage metrics.
|
|
35
|
+
*
|
|
36
|
+
* Displays summary cards (total cost, LLM calls, tokens), a daily cost
|
|
37
|
+
* bar chart, and per-model breakdown with call counts and token splits.
|
|
38
|
+
* Data is fetched via `getOrgUsageReport` with a configurable date range.
|
|
39
|
+
*
|
|
40
|
+
* All visual properties flow through `--stgm-*` design tokens. Zero
|
|
41
|
+
* Console dependencies — safe for platform builder embedding.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <OrgUsagePanel orgId={activeOrg.metadata.id} />
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function OrgUsagePanel({ orgId, className }: OrgUsagePanelProps) {
|
|
49
|
+
const [preset, setPreset] = useState<DateRangePreset>("30d");
|
|
50
|
+
const dateRange = dateRangeFromPreset(preset);
|
|
51
|
+
const { report, isLoading, error } = useOrgUsageReport(orgId, dateRange);
|
|
52
|
+
|
|
53
|
+
if (isLoading) {
|
|
54
|
+
return (
|
|
55
|
+
<div
|
|
56
|
+
className={cn("space-y-4", className)}
|
|
57
|
+
aria-busy="true"
|
|
58
|
+
aria-label="Loading usage data"
|
|
59
|
+
>
|
|
60
|
+
<div className="flex gap-2">
|
|
61
|
+
{DATE_RANGE_PRESETS.map((p) => (
|
|
62
|
+
<div
|
|
63
|
+
key={p}
|
|
64
|
+
className="h-7 w-16 animate-pulse rounded-md bg-muted/40"
|
|
65
|
+
/>
|
|
66
|
+
))}
|
|
67
|
+
</div>
|
|
68
|
+
<div className="grid grid-cols-3 gap-3">
|
|
69
|
+
{Array.from({ length: 3 }, (_, i) => (
|
|
70
|
+
<div
|
|
71
|
+
key={i}
|
|
72
|
+
className="h-[72px] animate-pulse rounded-lg bg-muted/40"
|
|
73
|
+
/>
|
|
74
|
+
))}
|
|
75
|
+
</div>
|
|
76
|
+
<div className="h-40 animate-pulse rounded-lg bg-muted/40" />
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (error) {
|
|
82
|
+
return (
|
|
83
|
+
<p className={cn("text-destructive text-xs", className)} role="alert">
|
|
84
|
+
{getUserMessage(error)}
|
|
85
|
+
</p>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!report) return null;
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div className={cn("space-y-6", className)}>
|
|
93
|
+
<DateRangeSelector
|
|
94
|
+
activePreset={preset}
|
|
95
|
+
onPresetChange={setPreset}
|
|
96
|
+
dateRange={dateRange}
|
|
97
|
+
/>
|
|
98
|
+
|
|
99
|
+
<SummaryCards report={report} />
|
|
100
|
+
|
|
101
|
+
{report.dailyCosts.length > 0 && (
|
|
102
|
+
<DailyCostChart entries={report.dailyCosts} />
|
|
103
|
+
)}
|
|
104
|
+
|
|
105
|
+
{report.modelBreakdown.length > 0 && (
|
|
106
|
+
<ModelBreakdownList models={report.modelBreakdown} />
|
|
107
|
+
)}
|
|
108
|
+
|
|
109
|
+
{report.modelBreakdown.length === 0 && <EmptyState />}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// DateRangeSelector (internal)
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
|
|
118
|
+
function DateRangeSelector({
|
|
119
|
+
activePreset,
|
|
120
|
+
onPresetChange,
|
|
121
|
+
dateRange,
|
|
122
|
+
}: {
|
|
123
|
+
activePreset: DateRangePreset;
|
|
124
|
+
onPresetChange: (preset: DateRangePreset) => void;
|
|
125
|
+
dateRange: { from: string; to: string };
|
|
126
|
+
}) {
|
|
127
|
+
return (
|
|
128
|
+
<div
|
|
129
|
+
className="flex items-center justify-between gap-3"
|
|
130
|
+
role="group"
|
|
131
|
+
aria-label="Date range"
|
|
132
|
+
>
|
|
133
|
+
<div className="flex gap-1.5">
|
|
134
|
+
{DATE_RANGE_PRESETS.map((p) => (
|
|
135
|
+
<button
|
|
136
|
+
key={p}
|
|
137
|
+
type="button"
|
|
138
|
+
onClick={() => onPresetChange(p)}
|
|
139
|
+
aria-pressed={p === activePreset}
|
|
140
|
+
className={cn(
|
|
141
|
+
"rounded-md px-2.5 py-1 text-xs font-medium transition-colors",
|
|
142
|
+
p === activePreset
|
|
143
|
+
? "bg-primary text-primary-foreground"
|
|
144
|
+
: "bg-muted text-muted-foreground hover:text-foreground hover:bg-accent",
|
|
145
|
+
)}
|
|
146
|
+
>
|
|
147
|
+
{presetLabel(p)}
|
|
148
|
+
</button>
|
|
149
|
+
))}
|
|
150
|
+
</div>
|
|
151
|
+
<span className="text-xs tabular-nums text-muted-foreground">
|
|
152
|
+
{formatDateRange(dateRange)}
|
|
153
|
+
</span>
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// SummaryCards (internal)
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
|
|
162
|
+
function SummaryCards({ report }: { report: GetOrgUsageReportOutput }) {
|
|
163
|
+
const { totalLlmCalls, totalTokens } = report.modelBreakdown.reduce(
|
|
164
|
+
(acc, m) => ({
|
|
165
|
+
totalLlmCalls: acc.totalLlmCalls + m.callCount,
|
|
166
|
+
totalTokens:
|
|
167
|
+
acc.totalTokens +
|
|
168
|
+
m.inputTokens +
|
|
169
|
+
m.outputTokens +
|
|
170
|
+
m.cacheCreationTokens +
|
|
171
|
+
m.cacheReadTokens,
|
|
172
|
+
}),
|
|
173
|
+
{ totalLlmCalls: 0, totalTokens: 0 },
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const cards: { label: string; value: string }[] = [
|
|
177
|
+
{ label: "Total Cost", value: formatCost(report.totalCostUsd) },
|
|
178
|
+
{ label: "LLM Calls", value: formatCompactNumber(totalLlmCalls) },
|
|
179
|
+
{ label: "Tokens", value: formatCompactNumber(totalTokens) },
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<div
|
|
184
|
+
className="grid grid-cols-3 gap-3"
|
|
185
|
+
role="group"
|
|
186
|
+
aria-label="Usage summary"
|
|
187
|
+
>
|
|
188
|
+
{cards.map((card) => (
|
|
189
|
+
<div
|
|
190
|
+
key={card.label}
|
|
191
|
+
className="rounded-lg border border-border bg-card px-3.5 py-3"
|
|
192
|
+
>
|
|
193
|
+
<div className="text-lg font-semibold tabular-nums text-foreground">
|
|
194
|
+
{card.value}
|
|
195
|
+
</div>
|
|
196
|
+
<div className="text-xs text-muted-foreground">{card.label}</div>
|
|
197
|
+
</div>
|
|
198
|
+
))}
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// DailyCostChart (internal) — CSS-only bar chart
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
const CHART_HEIGHT_PX = 128;
|
|
208
|
+
|
|
209
|
+
function DailyCostChart({ entries }: { entries: readonly DailyCostEntry[] }) {
|
|
210
|
+
const maxCost = Math.max(...entries.map((e) => e.estimatedCostUsd), 0);
|
|
211
|
+
const [hoveredIdx, setHoveredIdx] = useState<number | null>(null);
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<div>
|
|
215
|
+
<h3 className="mb-2 text-xs font-semibold text-foreground">
|
|
216
|
+
Daily Cost
|
|
217
|
+
</h3>
|
|
218
|
+
<div className="rounded-lg border border-border bg-card px-3 pb-2 pt-3">
|
|
219
|
+
{/* Tooltip */}
|
|
220
|
+
<div className="mb-1 h-4">
|
|
221
|
+
{hoveredIdx !== null && entries[hoveredIdx] && (
|
|
222
|
+
<span className="text-xs tabular-nums text-muted-foreground">
|
|
223
|
+
{formatChartDate(entries[hoveredIdx].date)}
|
|
224
|
+
{" \u00B7 "}
|
|
225
|
+
{formatCost(entries[hoveredIdx].estimatedCostUsd)}
|
|
226
|
+
{" \u00B7 "}
|
|
227
|
+
{formatTokenCount(entries[hoveredIdx].totalTokens)} tokens
|
|
228
|
+
</span>
|
|
229
|
+
)}
|
|
230
|
+
</div>
|
|
231
|
+
|
|
232
|
+
{/* Bars */}
|
|
233
|
+
<div
|
|
234
|
+
className="flex items-end gap-px"
|
|
235
|
+
style={{ height: CHART_HEIGHT_PX }}
|
|
236
|
+
role="img"
|
|
237
|
+
aria-label="Daily cost bar chart"
|
|
238
|
+
>
|
|
239
|
+
{entries.map((entry, i) => {
|
|
240
|
+
const ratio =
|
|
241
|
+
maxCost > 0 ? entry.estimatedCostUsd / maxCost : 0;
|
|
242
|
+
const heightPx = Math.max(ratio * CHART_HEIGHT_PX, 2);
|
|
243
|
+
|
|
244
|
+
return (
|
|
245
|
+
<div
|
|
246
|
+
key={entry.date}
|
|
247
|
+
className="group relative flex-1"
|
|
248
|
+
style={{ height: CHART_HEIGHT_PX }}
|
|
249
|
+
onMouseEnter={() => setHoveredIdx(i)}
|
|
250
|
+
onMouseLeave={() => setHoveredIdx(null)}
|
|
251
|
+
>
|
|
252
|
+
<div
|
|
253
|
+
className={cn(
|
|
254
|
+
"absolute inset-x-0 bottom-0 rounded-t-sm transition-colors",
|
|
255
|
+
hoveredIdx === i
|
|
256
|
+
? "bg-chart-1"
|
|
257
|
+
: "bg-chart-1/70",
|
|
258
|
+
)}
|
|
259
|
+
style={{ height: heightPx }}
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
);
|
|
263
|
+
})}
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
{/* X-axis labels — show first, middle, and last */}
|
|
267
|
+
{entries.length > 0 && (
|
|
268
|
+
<div className="mt-1.5 flex justify-between">
|
|
269
|
+
<span className="text-[0.6rem] tabular-nums text-muted-foreground">
|
|
270
|
+
{formatChartDate(entries[0].date)}
|
|
271
|
+
</span>
|
|
272
|
+
{entries.length > 2 && (
|
|
273
|
+
<span className="text-[0.6rem] tabular-nums text-muted-foreground">
|
|
274
|
+
{formatChartDate(
|
|
275
|
+
entries[Math.floor(entries.length / 2)].date,
|
|
276
|
+
)}
|
|
277
|
+
</span>
|
|
278
|
+
)}
|
|
279
|
+
{entries.length > 1 && (
|
|
280
|
+
<span className="text-[0.6rem] tabular-nums text-muted-foreground">
|
|
281
|
+
{formatChartDate(entries[entries.length - 1].date)}
|
|
282
|
+
</span>
|
|
283
|
+
)}
|
|
284
|
+
</div>
|
|
285
|
+
)}
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ---------------------------------------------------------------------------
|
|
292
|
+
// ModelBreakdownList (internal)
|
|
293
|
+
// ---------------------------------------------------------------------------
|
|
294
|
+
|
|
295
|
+
function ModelBreakdownList({
|
|
296
|
+
models,
|
|
297
|
+
}: {
|
|
298
|
+
models: readonly ModelUsage[];
|
|
299
|
+
}) {
|
|
300
|
+
return (
|
|
301
|
+
<div>
|
|
302
|
+
<h3 className="mb-2 text-xs font-semibold text-foreground">
|
|
303
|
+
Model Breakdown
|
|
304
|
+
</h3>
|
|
305
|
+
<div
|
|
306
|
+
className="rounded-lg border border-border bg-card"
|
|
307
|
+
role="table"
|
|
308
|
+
aria-label="Model usage breakdown"
|
|
309
|
+
>
|
|
310
|
+
<div
|
|
311
|
+
role="row"
|
|
312
|
+
className="grid grid-cols-[1fr_auto_auto_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"
|
|
313
|
+
>
|
|
314
|
+
<span role="columnheader">Model</span>
|
|
315
|
+
<span role="columnheader" className="text-right">
|
|
316
|
+
Calls
|
|
317
|
+
</span>
|
|
318
|
+
<span role="columnheader" className="text-right">
|
|
319
|
+
Input
|
|
320
|
+
</span>
|
|
321
|
+
<span role="columnheader" className="text-right">
|
|
322
|
+
Output
|
|
323
|
+
</span>
|
|
324
|
+
<span role="columnheader" className="text-right">
|
|
325
|
+
Cost
|
|
326
|
+
</span>
|
|
327
|
+
</div>
|
|
328
|
+
{models.map((m) => {
|
|
329
|
+
const totalInput =
|
|
330
|
+
m.inputTokens + m.cacheCreationTokens + m.cacheReadTokens;
|
|
331
|
+
const hasCache = m.cacheReadTokens > 0 || m.cacheCreationTokens > 0;
|
|
332
|
+
|
|
333
|
+
return (
|
|
334
|
+
<div
|
|
335
|
+
key={`${m.model}\0${m.provider}`}
|
|
336
|
+
className="border-b border-border/50 px-3.5 py-2 last:border-b-0"
|
|
337
|
+
>
|
|
338
|
+
<div
|
|
339
|
+
role="row"
|
|
340
|
+
className="grid grid-cols-[1fr_auto_auto_auto_auto] gap-x-4"
|
|
341
|
+
>
|
|
342
|
+
<div role="cell" className="min-w-0">
|
|
343
|
+
<span className="block truncate text-xs font-medium text-foreground">
|
|
344
|
+
{m.model}
|
|
345
|
+
</span>
|
|
346
|
+
<span className="text-[0.65rem] text-muted-foreground">
|
|
347
|
+
{m.provider}
|
|
348
|
+
</span>
|
|
349
|
+
</div>
|
|
350
|
+
<span
|
|
351
|
+
role="cell"
|
|
352
|
+
className="self-center text-right text-xs tabular-nums text-muted-foreground"
|
|
353
|
+
>
|
|
354
|
+
{formatCompactNumber(m.callCount)}
|
|
355
|
+
</span>
|
|
356
|
+
<span
|
|
357
|
+
role="cell"
|
|
358
|
+
className="self-center text-right text-xs tabular-nums text-muted-foreground"
|
|
359
|
+
>
|
|
360
|
+
{formatCompactNumber(totalInput)}
|
|
361
|
+
</span>
|
|
362
|
+
<span
|
|
363
|
+
role="cell"
|
|
364
|
+
className="self-center text-right text-xs tabular-nums text-muted-foreground"
|
|
365
|
+
>
|
|
366
|
+
{formatCompactNumber(m.outputTokens)}
|
|
367
|
+
</span>
|
|
368
|
+
<span
|
|
369
|
+
role="cell"
|
|
370
|
+
className="self-center text-right text-xs tabular-nums text-foreground"
|
|
371
|
+
>
|
|
372
|
+
{formatCost(m.estimatedCostUsd)}
|
|
373
|
+
</span>
|
|
374
|
+
</div>
|
|
375
|
+
{hasCache && (
|
|
376
|
+
<div className="mt-0.5 text-[0.6rem] tabular-nums text-muted-foreground">
|
|
377
|
+
cache{" "}
|
|
378
|
+
{m.cacheReadTokens > 0 &&
|
|
379
|
+
`${formatCompactNumber(m.cacheReadTokens)} read`}
|
|
380
|
+
{m.cacheReadTokens > 0 && m.cacheCreationTokens > 0 &&
|
|
381
|
+
" · "}
|
|
382
|
+
{m.cacheCreationTokens > 0 &&
|
|
383
|
+
`${formatCompactNumber(m.cacheCreationTokens)} write`}
|
|
384
|
+
</div>
|
|
385
|
+
)}
|
|
386
|
+
</div>
|
|
387
|
+
);
|
|
388
|
+
})}
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// ---------------------------------------------------------------------------
|
|
395
|
+
// EmptyState (internal)
|
|
396
|
+
// ---------------------------------------------------------------------------
|
|
397
|
+
|
|
398
|
+
function EmptyState() {
|
|
399
|
+
return (
|
|
400
|
+
<div className="flex flex-col items-center justify-center py-12 text-center">
|
|
401
|
+
<ChartIcon className="text-muted-foreground mb-3 size-8" />
|
|
402
|
+
<p className="text-sm font-medium text-foreground">No usage data yet</p>
|
|
403
|
+
<p className="mt-1 max-w-xs text-xs text-muted-foreground">
|
|
404
|
+
Usage data will appear here once agents start running executions
|
|
405
|
+
in this organization.
|
|
406
|
+
</p>
|
|
407
|
+
</div>
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function ChartIcon({ className }: { className?: string }) {
|
|
412
|
+
return (
|
|
413
|
+
<svg
|
|
414
|
+
width="24"
|
|
415
|
+
height="24"
|
|
416
|
+
viewBox="0 0 24 24"
|
|
417
|
+
fill="none"
|
|
418
|
+
stroke="currentColor"
|
|
419
|
+
strokeWidth="1.5"
|
|
420
|
+
strokeLinecap="round"
|
|
421
|
+
strokeLinejoin="round"
|
|
422
|
+
className={className}
|
|
423
|
+
aria-hidden="true"
|
|
424
|
+
>
|
|
425
|
+
<path d="M3 3v18h18" />
|
|
426
|
+
<path d="M7 16l4-8 4 4 4-6" />
|
|
427
|
+
</svg>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// ---------------------------------------------------------------------------
|
|
432
|
+
// Formatting helpers
|
|
433
|
+
// ---------------------------------------------------------------------------
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Format a number with compact suffixes for dashboard cards.
|
|
437
|
+
* Examples: 847 -> "847", 2_340 -> "2.3K", 1_200_000 -> "1.2M"
|
|
438
|
+
*/
|
|
439
|
+
function formatCompactNumber(n: number): string {
|
|
440
|
+
if (n >= 1_000_000) {
|
|
441
|
+
const v = n / 1_000_000;
|
|
442
|
+
return v >= 100 ? `${Math.round(v)}M` : `${trimTrailingZero(v.toFixed(1))}M`;
|
|
443
|
+
}
|
|
444
|
+
if (n >= 1_000) {
|
|
445
|
+
const v = n / 1_000;
|
|
446
|
+
return v >= 100 ? `${Math.round(v)}K` : `${trimTrailingZero(v.toFixed(1))}K`;
|
|
447
|
+
}
|
|
448
|
+
return String(n);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function trimTrailingZero(s: string): string {
|
|
452
|
+
return s.endsWith(".0") ? s.slice(0, -2) : s;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Format a YYYY-MM-DD date for chart axis labels (e.g. "Apr 02").
|
|
457
|
+
*/
|
|
458
|
+
function formatChartDate(iso: string): string {
|
|
459
|
+
const [y, m, d] = iso.split("-").map(Number);
|
|
460
|
+
const date = new Date(y, m - 1, d);
|
|
461
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
462
|
+
month: "short",
|
|
463
|
+
day: "2-digit",
|
|
464
|
+
}).format(date);
|
|
465
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date range presets and utilities for usage report queries.
|
|
3
|
+
*
|
|
4
|
+
* Preset values match common billing-dashboard patterns (7-day, 14-day,
|
|
5
|
+
* 30-day windows). All dates are formatted as YYYY-MM-DD strings to
|
|
6
|
+
* align with the `GetOrgUsageReportInput` proto contract.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** A closed date range where both ends are ISO date strings (YYYY-MM-DD). */
|
|
10
|
+
export interface DateRange {
|
|
11
|
+
/** Start date (inclusive) in YYYY-MM-DD format. */
|
|
12
|
+
readonly from: string;
|
|
13
|
+
/** End date (inclusive) in YYYY-MM-DD format. */
|
|
14
|
+
readonly to: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Supported preset window sizes for usage reports. */
|
|
18
|
+
export type DateRangePreset = "7d" | "14d" | "30d";
|
|
19
|
+
|
|
20
|
+
/** All available presets in display order. */
|
|
21
|
+
export const DATE_RANGE_PRESETS: readonly DateRangePreset[] = [
|
|
22
|
+
"7d",
|
|
23
|
+
"14d",
|
|
24
|
+
"30d",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
/** Human-readable label for each preset. */
|
|
28
|
+
export function presetLabel(preset: DateRangePreset): string {
|
|
29
|
+
switch (preset) {
|
|
30
|
+
case "7d":
|
|
31
|
+
return "7 days";
|
|
32
|
+
case "14d":
|
|
33
|
+
return "14 days";
|
|
34
|
+
case "30d":
|
|
35
|
+
return "30 days";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Compute a {@link DateRange} from a preset, anchored to today.
|
|
41
|
+
*
|
|
42
|
+
* The `to` date is always today (inclusive). The `from` date is
|
|
43
|
+
* `days - 1` calendar days before today so the range contains exactly
|
|
44
|
+
* `days` calendar days.
|
|
45
|
+
*/
|
|
46
|
+
export function dateRangeFromPreset(preset: DateRangePreset): DateRange {
|
|
47
|
+
const days = Number.parseInt(preset, 10);
|
|
48
|
+
const to = new Date();
|
|
49
|
+
const from = new Date(to);
|
|
50
|
+
from.setDate(from.getDate() - (days - 1));
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
from: formatDate(from),
|
|
54
|
+
to: formatDate(to),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Format a `Date` as a YYYY-MM-DD string in local time. */
|
|
59
|
+
function formatDate(d: Date): string {
|
|
60
|
+
const y = d.getFullYear();
|
|
61
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
62
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
63
|
+
return `${y}-${m}-${day}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Format a date range for display (e.g. "Mar 30 -- Apr 06").
|
|
68
|
+
*
|
|
69
|
+
* Uses short month names and zero-padded days for a compact, scannable
|
|
70
|
+
* representation in the date-range selector.
|
|
71
|
+
*/
|
|
72
|
+
export function formatDateRange(range: DateRange): string {
|
|
73
|
+
const from = parseLocalDate(range.from);
|
|
74
|
+
const to = parseLocalDate(range.to);
|
|
75
|
+
const fmt = new Intl.DateTimeFormat("en-US", {
|
|
76
|
+
month: "short",
|
|
77
|
+
day: "2-digit",
|
|
78
|
+
});
|
|
79
|
+
return `${fmt.format(from)} \u2013 ${fmt.format(to)}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Parse a YYYY-MM-DD string into a local Date (avoids timezone shift). */
|
|
83
|
+
function parseLocalDate(iso: string): Date {
|
|
84
|
+
const [y, m, d] = iso.split("-").map(Number);
|
|
85
|
+
return new Date(y, m - 1, d);
|
|
86
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { useOrgUsageReport } from "./useOrgUsageReport";
|
|
2
|
+
export type { UseOrgUsageReportReturn } from "./useOrgUsageReport";
|
|
3
|
+
|
|
4
|
+
export { OrgUsagePanel } from "./OrgUsagePanel";
|
|
5
|
+
export type { OrgUsagePanelProps } from "./OrgUsagePanel";
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
DATE_RANGE_PRESETS,
|
|
9
|
+
dateRangeFromPreset,
|
|
10
|
+
formatDateRange,
|
|
11
|
+
presetLabel,
|
|
12
|
+
} from "./date-range";
|
|
13
|
+
export type { DateRange, DateRangePreset } from "./date-range";
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useState } from "react";
|
|
4
|
+
import { create } from "@bufbuild/protobuf";
|
|
5
|
+
import {
|
|
6
|
+
GetOrgUsageReportInputSchema,
|
|
7
|
+
type GetOrgUsageReportOutput,
|
|
8
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
|
|
9
|
+
import type { ModelUsage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/usage_pb";
|
|
10
|
+
import { useStigmer } from "../hooks";
|
|
11
|
+
import { toError } from "../internal/toError";
|
|
12
|
+
import type { DateRange } from "./date-range";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Lightweight summary of an agent's usage within an org report.
|
|
16
|
+
*
|
|
17
|
+
* Re-exported as a plain interface so consumers don't need to depend
|
|
18
|
+
* on `@stigmer/protos` directly for type-safe rendering.
|
|
19
|
+
*/
|
|
20
|
+
export type { ModelUsage };
|
|
21
|
+
|
|
22
|
+
/** Return value of {@link useOrgUsageReport}. */
|
|
23
|
+
export interface UseOrgUsageReportReturn {
|
|
24
|
+
/** The raw report from the server, or `null` before the first successful fetch. */
|
|
25
|
+
readonly report: GetOrgUsageReportOutput | null;
|
|
26
|
+
/** `true` while a fetch is in flight. */
|
|
27
|
+
readonly isLoading: boolean;
|
|
28
|
+
/** Error from the last failed request, or `null` when healthy. */
|
|
29
|
+
readonly error: Error | null;
|
|
30
|
+
/** Discard cached data and re-fetch from the server. */
|
|
31
|
+
readonly refetch: () => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Data hook that fetches the organization-level usage report.
|
|
36
|
+
*
|
|
37
|
+
* Calls `stigmer.agentExecution.getOrgUsageReport` with the provided
|
|
38
|
+
* org ID and date range. The server returns aggregated totals, a
|
|
39
|
+
* per-model breakdown, the top agents by cost, and a daily cost trend.
|
|
40
|
+
*
|
|
41
|
+
* Pass `null` as `orgId` to skip fetching (stable no-op). Call
|
|
42
|
+
* `refetch()` to re-query manually.
|
|
43
|
+
*
|
|
44
|
+
* @param orgId - Organization ID, or `null` to skip.
|
|
45
|
+
* @param dateRange - Closed date range (YYYY-MM-DD strings).
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* const range = dateRangeFromPreset("30d");
|
|
50
|
+
* const { report, isLoading, error } = useOrgUsageReport(orgId, range);
|
|
51
|
+
*
|
|
52
|
+
* if (isLoading) return <Skeleton />;
|
|
53
|
+
* if (error) return <ErrorMessage error={error} />;
|
|
54
|
+
* if (!report) return null;
|
|
55
|
+
*
|
|
56
|
+
* return <div>Total cost: {formatCost(report.totalCostUsd)}</div>;
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function useOrgUsageReport(
|
|
60
|
+
orgId: string | null,
|
|
61
|
+
dateRange: DateRange,
|
|
62
|
+
): UseOrgUsageReportReturn {
|
|
63
|
+
const stigmer = useStigmer();
|
|
64
|
+
const [report, setReport] = useState<GetOrgUsageReportOutput | null>(null);
|
|
65
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
66
|
+
const [error, setError] = useState<Error | null>(null);
|
|
67
|
+
const [fetchKey, setFetchKey] = useState(0);
|
|
68
|
+
|
|
69
|
+
const refetch = useCallback(() => setFetchKey((k) => k + 1), []);
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!orgId) {
|
|
73
|
+
setReport(null);
|
|
74
|
+
setIsLoading(false);
|
|
75
|
+
setError(null);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const cancelled = { current: false };
|
|
80
|
+
setIsLoading(true);
|
|
81
|
+
setError(null);
|
|
82
|
+
|
|
83
|
+
stigmer.agentExecution
|
|
84
|
+
.getOrgUsageReport(
|
|
85
|
+
create(GetOrgUsageReportInputSchema, {
|
|
86
|
+
orgId,
|
|
87
|
+
fromDate: dateRange.from,
|
|
88
|
+
toDate: dateRange.to,
|
|
89
|
+
}),
|
|
90
|
+
)
|
|
91
|
+
.then(
|
|
92
|
+
(result) => {
|
|
93
|
+
if (cancelled.current) return;
|
|
94
|
+
setReport(result);
|
|
95
|
+
setIsLoading(false);
|
|
96
|
+
},
|
|
97
|
+
(err) => {
|
|
98
|
+
if (cancelled.current) return;
|
|
99
|
+
setError(toError(err));
|
|
100
|
+
setIsLoading(false);
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
return () => {
|
|
105
|
+
cancelled.current = true;
|
|
106
|
+
};
|
|
107
|
+
}, [orgId, dateRange.from, dateRange.to, stigmer, fetchKey]);
|
|
108
|
+
|
|
109
|
+
return { report, isLoading, error, refetch };
|
|
110
|
+
}
|
|
@@ -35,6 +35,15 @@ export interface FolderBrowserProps {
|
|
|
35
35
|
*
|
|
36
36
|
* All visual properties flow through `--stgm-*` tokens.
|
|
37
37
|
* No Console-specific dependencies.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <FolderBrowser
|
|
42
|
+
* onSelect={(path) => workspace.addLocalPath(path)}
|
|
43
|
+
* onCancel={() => setShowBrowser(false)}
|
|
44
|
+
* initialPath="/Users/dev/projects"
|
|
45
|
+
* />
|
|
46
|
+
* ```
|
|
38
47
|
*/
|
|
39
48
|
export function FolderBrowser({
|
|
40
49
|
onSelect,
|