@cat-factory/app 0.302.1 → 0.303.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/README.md +16 -0
- package/app/app.config.ts +19 -10
- package/app/assets/css/main.css +13 -13
- package/app/assets/css/prose.css +22 -22
- package/app/assets/css/tokens.css +298 -0
- package/app/components/assistant/AssistantModal.vue +22 -22
- package/app/components/auth/AuthGate.vue +1 -1
- package/app/components/auth/BackendMisconfiguredScreen.vue +10 -10
- package/app/components/auth/LoginScreen.vue +34 -36
- package/app/components/auth/ResetPasswordScreen.vue +12 -12
- package/app/components/auth/UserMenu.vue +4 -4
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +27 -25
- package/app/components/binaryOutput/BinaryOutputReport.vue +15 -15
- package/app/components/binaryOutput/StoredAssetView.vue +5 -5
- package/app/components/board/AddTaskModal.vue +17 -20
- package/app/components/board/AgentFailureCard.vue +11 -11
- package/app/components/board/AgentFailureHistory.vue +2 -2
- package/app/components/board/BoardCanvas.vue +6 -5
- package/app/components/board/CreateInitiativeModal.vue +8 -10
- package/app/components/board/DependencyConnectOverlay.vue +1 -1
- package/app/components/board/FailureHistoryList.vue +7 -7
- package/app/components/board/RecurringPipelineModal.vue +17 -17
- package/app/components/board/ReviewFrictionDialog.vue +6 -6
- package/app/components/board/StepExecutionHistory.vue +13 -13
- package/app/components/board/TaskDependencyEdges.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +10 -10
- package/app/components/board/nodes/BlockNode.vue +29 -29
- package/app/components/board/nodes/DecisionBadge.vue +2 -2
- package/app/components/board/nodes/EpicNode.vue +14 -10
- package/app/components/board/nodes/FrameSwimlanes.vue +7 -9
- package/app/components/board/nodes/InitiativeCard.vue +8 -8
- package/app/components/board/nodes/LaneGroup.vue +1 -1
- package/app/components/board/nodes/LaneTask.vue +2 -2
- package/app/components/board/nodes/ResizeGrips.vue +4 -4
- package/app/components/board/nodes/TaskCard.vue +18 -18
- package/app/components/board/nodes/TaskLane.vue +5 -5
- package/app/components/board/nodes/TaskPipelineMini.vue +18 -18
- package/app/components/bootstrap/AdoptionReviewModal.vue +29 -26
- package/app/components/bootstrap/BootstrapModal.vue +21 -23
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +30 -33
- package/app/components/bugFishing/BugFishingWindow.vue +49 -49
- package/app/components/clarity/ClarityReviewWindow.vue +30 -30
- package/app/components/common/AsyncViewError.vue +5 -5
- package/app/components/common/ClarificationItem.vue +8 -13
- package/app/components/common/ConfirmDialog.vue +4 -2
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +3 -3
- package/app/components/common/InterviewGateNotice.vue +7 -7
- package/app/components/common/KeyboardShortcutsHelp.vue +1 -1
- package/app/components/common/MarkdownProse.vue +14 -13
- package/app/components/consensus/ConsensusSessionWindow.vue +26 -26
- package/app/components/context/ContextAttachmentFields.vue +17 -17
- package/app/components/docs/DocInterviewWindow.vue +14 -14
- package/app/components/documents/ContextDocumentPicker.vue +17 -17
- package/app/components/documents/DocumentImportModal.vue +7 -7
- package/app/components/documents/DocumentSourceConnectModal.vue +3 -3
- package/app/components/documents/DocumentSyncState.vue +5 -5
- package/app/components/documents/DocumentTemplatesModal.vue +15 -15
- package/app/components/documents/RepoContextDocPicker.vue +5 -5
- package/app/components/documents/SpawnPreviewModal.vue +12 -12
- package/app/components/documents/StartFromDesignModal.vue +11 -11
- package/app/components/documents/TaskContextDocs.vue +5 -5
- package/app/components/environments/EnvSetupStepper.vue +6 -6
- package/app/components/environments/EnvironmentStatusPanel.vue +17 -17
- package/app/components/environments/steps/EnvPickStep.vue +3 -3
- package/app/components/environments/steps/EnvPreflightStep.vue +9 -9
- package/app/components/environments/steps/EnvReviewStep.vue +25 -22
- package/app/components/environments/steps/EnvSaveStep.vue +7 -5
- package/app/components/environments/steps/JourneyStepNav.vue +1 -1
- package/app/components/focus/BlockFocusView.vue +17 -19
- package/app/components/followUp/FollowUpWindow.vue +23 -23
- package/app/components/forkDecision/ForkDecisionWindow.vue +37 -39
- package/app/components/foundational/FoundationalContractSummary.vue +7 -7
- package/app/components/foundational/FoundationalServiceCatalogList.vue +11 -11
- package/app/components/foundational/FoundationalServiceManager.vue +1 -1
- package/app/components/foundational/FoundationalServiceRegistry.vue +13 -13
- package/app/components/foundational/FoundationalServiceSources.vue +13 -13
- package/app/components/foundational/FoundationalSuppressions.vue +7 -7
- package/app/components/foundational/ServiceCatalogConnection.vue +10 -10
- package/app/components/fragments/FragmentLibraryManager.vue +41 -44
- package/app/components/fragments/FragmentSelector.vue +13 -13
- package/app/components/fragments/GitHubDocUrlImport.vue +1 -1
- package/app/components/gates/GateFailingCheckList.vue +5 -5
- package/app/components/gates/GateResultView.vue +50 -47
- package/app/components/github/AddServiceFromRepoModal.vue +14 -14
- package/app/components/github/BranchProtectionPreflight.vue +13 -13
- package/app/components/github/GitHubConnect.vue +7 -7
- package/app/components/github/GitHubOnboarding.vue +7 -7
- package/app/components/github/GitHubPanel.vue +37 -40
- package/app/components/github/RepoTreeBrowser.vue +18 -18
- package/app/components/humanTest/HumanTestWindow.vue +30 -33
- package/app/components/initiative/InitiativePlanNotice.vue +5 -5
- package/app/components/initiative/InitiativePlanReview.vue +27 -29
- package/app/components/initiative/InitiativePlanningWindow.vue +10 -10
- package/app/components/initiative/InitiativeTrackerWindow.vue +71 -65
- package/app/components/inputGate/InputGateNotice.vue +2 -4
- package/app/components/judge/JudgeResultView.vue +30 -32
- package/app/components/kaizen/KaizenPanel.vue +40 -36
- package/app/components/kaizen/KaizenStepStatus.vue +21 -21
- package/app/components/layout/AccountAuditLog.vue +10 -10
- package/app/components/layout/AccountDeploymentSettings.vue +20 -20
- package/app/components/layout/AccountFailureKindRules.vue +13 -13
- package/app/components/layout/AccountFoundationalSettings.vue +1 -1
- package/app/components/layout/AccountFragmentSettings.vue +1 -1
- package/app/components/layout/AccountModelPolicySettings.vue +9 -9
- package/app/components/layout/AccountPlatformAlertSettings.vue +11 -11
- package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
- package/app/components/layout/AccountRunCredentialSettings.vue +5 -5
- package/app/components/layout/AccountSkillSettings.vue +1 -1
- package/app/components/layout/AccountTeamSettings.vue +23 -15
- package/app/components/layout/AiProvidersBanner.vue +11 -8
- package/app/components/layout/AppearanceSwitcher.vue +108 -0
- package/app/components/layout/BoardSwitcher.vue +8 -11
- package/app/components/layout/BoardToolbar.vue +3 -3
- package/app/components/layout/CommandBar.vue +7 -9
- package/app/components/layout/ConnectionStatusBanner.vue +2 -2
- package/app/components/layout/DefaultTestEnvBanner.vue +5 -5
- package/app/components/layout/GitHubPatBanner.vue +5 -5
- package/app/components/layout/GitHubPatPermissionsBanner.vue +16 -10
- package/app/components/layout/InfraSetupBanner.vue +6 -6
- package/app/components/layout/IntegrationsHub.vue +15 -15
- package/app/components/layout/LanguageSwitcher.vue +5 -5
- package/app/components/layout/ModelProvidersHub.vue +13 -16
- package/app/components/layout/NotificationsInbox.vue +10 -10
- package/app/components/layout/PersonalSetupModal.vue +8 -8
- package/app/components/layout/ProviderConfigBanner.vue +4 -4
- package/app/components/layout/RolePrompt.vue +7 -7
- package/app/components/layout/SideBar.vue +6 -4
- package/app/components/layout/SpendWarningBanner.vue +17 -14
- package/app/components/layout/TranslationWarningBanner.vue +4 -4
- package/app/components/layout/UiModeSwitcher.vue +13 -13
- package/app/components/layout/UiRoleSwitcher.vue +8 -8
- package/app/components/layout/WorkspaceMembersSettings.vue +15 -11
- package/app/components/media/ArtifactLightbox.vue +13 -13
- package/app/components/media/ImageCompare.vue +31 -24
- package/app/components/merge/MergeEffortChips.vue +2 -2
- package/app/components/notifications/NotificationSettingsPanel.vue +14 -12
- package/app/components/observability/OutcomeFilterChips.vue +6 -6
- package/app/components/observability/RunFailureSummary.vue +28 -25
- package/app/components/observability/StepMetricsBar.vue +26 -28
- package/app/components/observability/StepModelActivity.vue +2 -2
- package/app/components/observability/ToolCallList.vue +24 -24
- package/app/components/outcome/OutcomeSummaryWindow.vue +47 -47
- package/app/components/palettes/AgentPalette.vue +8 -8
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
- package/app/components/panels/AgentStepDetail.vue +52 -51
- package/app/components/panels/AttemptEntryHeader.vue +4 -6
- package/app/components/panels/DecisionModal.vue +7 -7
- package/app/components/panels/GenericStructuredResultView.vue +7 -7
- package/app/components/panels/InspectorPanel.vue +17 -17
- package/app/components/panels/MergerResultView.vue +19 -19
- package/app/components/panels/ObservabilityPanel.vue +115 -123
- package/app/components/panels/OperatorDashboardPanel.vue +89 -97
- package/app/components/panels/ReportsPanel.vue +69 -66
- package/app/components/panels/ReportsSpendBreakdown.vue +9 -9
- package/app/components/panels/ResultWindowShell.vue +38 -38
- package/app/components/panels/RunDetailLoadState.vue +2 -2
- package/app/components/panels/StepContainerStatus.vue +9 -9
- package/app/components/panels/StepDelegatedStatus.logic.spec.ts +135 -0
- package/app/components/panels/StepDelegatedStatus.logic.ts +160 -0
- package/app/components/panels/StepDelegatedStatus.vue +181 -0
- package/app/components/panels/StepEffortReport.vue +16 -15
- package/app/components/panels/StepFragmentAdherence.vue +14 -10
- package/app/components/panels/StepMetadataCard.vue +74 -45
- package/app/components/panels/StepReproductionReport.vue +25 -21
- package/app/components/panels/StepRunMeta.vue +20 -20
- package/app/components/panels/StepTestReport.logic.spec.ts +8 -3
- package/app/components/panels/StepTestReport.logic.ts +4 -4
- package/app/components/panels/StepTestReport.vue +28 -28
- package/app/components/panels/StepToolServers.vue +14 -11
- package/app/components/panels/StepValidationReport.vue +7 -7
- package/app/components/panels/inspector/ContainerSummary.vue +9 -9
- package/app/components/panels/inspector/DocReferenceRepos.vue +3 -3
- package/app/components/panels/inspector/EnvProbeReport.vue +24 -27
- package/app/components/panels/inspector/EpicChildren.vue +8 -12
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +11 -11
- package/app/components/panels/inspector/FrontendConfig.vue +37 -41
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +6 -6
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +16 -19
- package/app/components/panels/inspector/ServiceConnections.vue +2 -2
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
- package/app/components/panels/inspector/ServiceSelfTests.vue +21 -17
- package/app/components/panels/inspector/ServiceTestConfig.vue +51 -59
- package/app/components/panels/inspector/ServiceTestSecrets.vue +5 -5
- package/app/components/panels/inspector/ServiceTestingContext.vue +3 -3
- package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAgentConfig.vue +3 -3
- package/app/components/panels/inspector/TaskAprioriBranches.vue +8 -5
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +11 -11
- package/app/components/panels/inspector/TaskExecution.vue +17 -17
- package/app/components/panels/inspector/TaskReviewTarget.vue +2 -2
- package/app/components/panels/inspector/TaskRunSettings.vue +35 -37
- package/app/components/panels/inspector/TaskStructure.vue +3 -3
- package/app/components/pipeline/AgentKindIcon.vue +1 -1
- package/app/components/pipeline/AgentPromptEditor.vue +17 -17
- package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -56
- package/app/components/pipeline/EstimateThresholdFields.vue +4 -4
- package/app/components/pipeline/GateConfigFields.vue +13 -10
- package/app/components/pipeline/IterationCapPrompt.vue +4 -2
- package/app/components/pipeline/PipelineBuilder.vue +47 -55
- package/app/components/pipeline/PipelineHealthModal.vue +27 -29
- package/app/components/pipeline/PipelinePicker.vue +10 -10
- package/app/components/pipeline/PipelinePreview.vue +10 -10
- package/app/components/pipeline/PipelineProgress.vue +64 -67
- package/app/components/prReview/PrReviewPhaseBadge.vue +7 -7
- package/app/components/prReview/PrReviewWindow.vue +75 -77
- package/app/components/providers/AiPresetMismatchDialog.vue +5 -5
- package/app/components/providers/AiProviderOnboardingModal.vue +9 -9
- package/app/components/providers/ApiKeysSection.vue +13 -13
- package/app/components/providers/PersonalCredentialModal.vue +2 -2
- package/app/components/providers/PersonalSubscriptionSection.vue +10 -10
- package/app/components/providers/SignInRequiredNotice.vue +1 -1
- package/app/components/providers/VendorCredentialsModal.vue +10 -10
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +13 -13
- package/app/components/ralph/RalphLoopResultView.vue +28 -30
- package/app/components/recurring/RecurrenceEditor.vue +2 -2
- package/app/components/requirements/RequirementsReviewWindow.vue +51 -58
- package/app/components/riskPolicy/RiskPolicyPicker.vue +12 -15
- package/app/components/riskPolicy/RiskPolicyPreview.vue +14 -14
- package/app/components/sandbox/SandboxPanel.vue +58 -59
- package/app/components/settings/AccountSettingsPanel.vue +1 -1
- package/app/components/settings/ApiTokensPanel.vue +10 -10
- package/app/components/settings/BudgetSettings.vue +18 -22
- package/app/components/settings/CapabilityCredentialsPanel.vue +15 -15
- package/app/components/settings/CloudflareHandlerSection.vue +20 -20
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +13 -13
- package/app/components/settings/ConnectionTestVerdict.vue +3 -3
- package/app/components/settings/ConnectionWarnings.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +27 -35
- package/app/components/settings/CustomManifestTypeEditor.vue +10 -10
- package/app/components/settings/DefaultProvisionTypeSection.vue +6 -6
- package/app/components/settings/InfraHandlersConfigurator.vue +24 -22
- package/app/components/settings/InfrastructureBackendPicker.vue +6 -6
- package/app/components/settings/InfrastructureWindow.vue +5 -5
- package/app/components/settings/IssueTrackerPanel.vue +29 -23
- package/app/components/settings/KubernetesEngineForm.vue +11 -11
- package/app/components/settings/KubernetesEnvironmentForm.vue +4 -4
- package/app/components/settings/LocalContainerPoolSettings.vue +6 -11
- package/app/components/settings/LocalModelEndpointsPanel.vue +20 -18
- package/app/components/settings/McpAuthorizeScreen.vue +13 -15
- package/app/components/settings/McpOAuthCallbackScreen.vue +16 -10
- package/app/components/settings/MergeClassRulesEditor.vue +6 -9
- package/app/components/settings/MergeRolePolicyEditor.vue +16 -16
- package/app/components/settings/ModelConfigurationPanel.vue +23 -30
- package/app/components/settings/ModelPresetHealthModal.vue +15 -13
- package/app/components/settings/ObservabilityConnectionPanel.vue +4 -4
- package/app/components/settings/OpenRouterCatalogPanel.vue +23 -19
- package/app/components/settings/PackageRegistriesPanel.vue +8 -8
- package/app/components/settings/ProviderConnectionTab.vue +8 -11
- package/app/components/settings/ProviderManifestEditor.vue +9 -9
- package/app/components/settings/ProviderPreferenceEditor.vue +8 -8
- package/app/components/settings/RiskPolicyCreateForm.vue +10 -10
- package/app/components/settings/RiskPolicyEditorRow.vue +14 -14
- package/app/components/settings/RiskPolicyHealthModal.vue +15 -13
- package/app/components/settings/RiskPolicyInheritedRow.vue +1 -1
- package/app/components/settings/RiskPolicyPanel.vue +10 -15
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +7 -7
- package/app/components/settings/SharedStacksPanel.vue +9 -12
- package/app/components/settings/TaskSourceCard.vue +4 -4
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +6 -6
- package/app/components/settings/ToolServerChecklist.vue +36 -29
- package/app/components/settings/UsageSettings.vue +15 -15
- package/app/components/settings/UserSecretsSection.vue +9 -12
- package/app/components/settings/WorkspaceMetadataSettings.vue +5 -5
- package/app/components/settings/WorkspaceSettingsPanel.vue +47 -47
- package/app/components/skills/ReviewSkillQueue.vue +10 -10
- package/app/components/skills/SkillLibraryManager.vue +23 -20
- package/app/components/slack/SlackPanel.vue +13 -17
- package/app/components/spec/ServiceSpecWindow.vue +45 -42
- package/app/components/tasks/BugHuntModal.vue +24 -27
- package/app/components/tasks/ContextIssuePicker.vue +11 -11
- package/app/components/tasks/TaskContextIssues.vue +3 -3
- package/app/components/tasks/TaskImportModal.vue +7 -7
- package/app/components/tasks/TaskSourceConnectModal.vue +10 -8
- package/app/components/testing/TestReportWindow.vue +99 -82
- package/app/components/theme/ThemeImportModal.vue +115 -0
- package/app/components/tutorial/TutorialCatalogue.vue +9 -9
- package/app/components/tutorial/TutorialNudge.vue +5 -5
- package/app/components/tutorial/TutorialOverlay.vue +12 -12
- package/app/components/tutorial/TutorialPrompt.vue +6 -9
- package/app/components/vcs/GitLabConnect.vue +4 -4
- package/app/components/vcs/VcsConnectSurfaces.vue +2 -2
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +36 -36
- package/app/composables/api/client.ts +6 -1
- package/app/composables/usePipelineErrorToast.ts +17 -0
- package/app/modular/agent-kinds.ts +24 -0
- package/app/pages/index.vue +5 -5
- package/app/plugins/theme.client.ts +125 -0
- package/app/spa-loading-template.html +52 -14
- package/app/stores/agents.ts +1 -1
- package/app/stores/theme.spec.ts +56 -0
- package/app/stores/theme.ts +87 -0
- package/app/types/domain.ts +19 -0
- package/app/types/execution.ts +4 -0
- package/app/utils/agentOutput.ts +1 -1
- package/app/utils/binaryOutput.ts +6 -6
- package/app/utils/bootstrapSteps.ts +14 -14
- package/app/utils/catalog.ts +87 -83
- package/app/utils/colorTint.ts +10 -0
- package/app/utils/failureKinds.ts +1 -0
- package/app/utils/observability.ts +3 -3
- package/app/utils/pipelineRender.ts +13 -17
- package/app/utils/swimlanes.ts +4 -4
- package/app/utils/theme/bootPalette.spec.ts +54 -0
- package/app/utils/theme/bootPalette.ts +108 -0
- package/app/utils/theme/builtins.spec.ts +38 -0
- package/app/utils/theme/builtins.ts +55 -0
- package/app/utils/theme/css.ts +162 -0
- package/app/utils/theme/doc.ts +353 -0
- package/app/utils/theme/link.ts +93 -0
- package/app/utils/theme/presets.ts +509 -0
- package/app/utils/theme/theme.spec.ts +224 -0
- package/i18n/locales/de.json +61 -4
- package/i18n/locales/en.json +70 -4
- package/i18n/locales/es.json +61 -4
- package/i18n/locales/fr.json +61 -4
- package/i18n/locales/he.json +61 -4
- package/i18n/locales/it.json +61 -4
- package/i18n/locales/ja.json +61 -4
- package/i18n/locales/pl.json +61 -4
- package/i18n/locales/tr.json +61 -4
- package/i18n/locales/uk.json +61 -4
- package/nuxt.config.ts +37 -11
- package/package.json +10 -9
|
@@ -150,10 +150,10 @@ const STATUS_KEYS: Record<'done' | 'failed' | 'running' | 'other', string> = {
|
|
|
150
150
|
other: 'reports.status.other',
|
|
151
151
|
}
|
|
152
152
|
const STATUS_CLASSES: Record<'done' | 'failed' | 'running' | 'other', string> = {
|
|
153
|
-
done: 'bg-
|
|
154
|
-
failed: 'bg-
|
|
155
|
-
running: 'bg-
|
|
156
|
-
other: 'bg-
|
|
153
|
+
done: 'bg-app-success-500',
|
|
154
|
+
failed: 'bg-app-error-500',
|
|
155
|
+
running: 'bg-app-info-500',
|
|
156
|
+
other: 'bg-app-500',
|
|
157
157
|
}
|
|
158
158
|
/** `te`-guarded so a locale missing the key shows the raw status, never a raw message key. */
|
|
159
159
|
function statusLabel(status: 'done' | 'failed' | 'running' | 'other'): string {
|
|
@@ -186,25 +186,27 @@ watch(
|
|
|
186
186
|
<Transition name="reports-fade">
|
|
187
187
|
<div
|
|
188
188
|
v-if="open"
|
|
189
|
-
class="fixed inset-0 z-[60] flex flex-col bg-
|
|
189
|
+
class="fixed inset-0 z-[60] flex flex-col bg-app-950/96 backdrop-blur-sm"
|
|
190
190
|
role="dialog"
|
|
191
191
|
aria-modal="true"
|
|
192
192
|
data-testid="reports-panel"
|
|
193
193
|
>
|
|
194
|
-
<header class="flex flex-wrap items-center gap-3 border-b border-
|
|
194
|
+
<header class="flex flex-wrap items-center gap-3 border-b border-default px-6 py-4">
|
|
195
195
|
<div
|
|
196
|
-
class="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-
|
|
196
|
+
class="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-app-secondary-500/15"
|
|
197
197
|
>
|
|
198
|
-
<UIcon name="i-lucide-chart-column" class="h-5 w-5 text-
|
|
198
|
+
<UIcon name="i-lucide-chart-column" class="h-5 w-5 text-app-secondary-400" />
|
|
199
199
|
</div>
|
|
200
200
|
<div class="min-w-0">
|
|
201
|
-
<h1 class="truncate text-base font-semibold text-
|
|
202
|
-
|
|
201
|
+
<h1 class="truncate text-base font-semibold text-highlighted">
|
|
202
|
+
{{ t('reports.title') }}
|
|
203
|
+
</h1>
|
|
204
|
+
<p v-if="accountName" class="truncate text-xs text-dimmed">{{ accountName }}</p>
|
|
203
205
|
</div>
|
|
204
206
|
<!-- Filters in ONE row above the charts: window, then board scope. -->
|
|
205
207
|
<div class="ms-auto flex flex-wrap items-center gap-1.5">
|
|
206
208
|
<select
|
|
207
|
-
class="rounded-lg border border-
|
|
209
|
+
class="rounded-lg border border-default bg-default px-2.5 py-1.5 text-[12px] text-default"
|
|
208
210
|
:value="reports.workspaceFilter ?? ''"
|
|
209
211
|
:aria-label="t('reports.filter.board')"
|
|
210
212
|
data-testid="reports-board-filter"
|
|
@@ -217,15 +219,15 @@ watch(
|
|
|
217
219
|
{{ board.name }}
|
|
218
220
|
</option>
|
|
219
221
|
</select>
|
|
220
|
-
<div class="me-1 flex rounded-lg border border-
|
|
222
|
+
<div class="me-1 flex rounded-lg border border-default p-0.5 text-[12px]">
|
|
221
223
|
<button
|
|
222
224
|
v-for="opt in WINDOWS"
|
|
223
225
|
:key="opt.value"
|
|
224
226
|
class="rounded-md px-2.5 py-1 transition"
|
|
225
227
|
:class="
|
|
226
228
|
reports.window === opt.value
|
|
227
|
-
? 'bg-
|
|
228
|
-
: 'text-
|
|
229
|
+
? 'bg-elevated text-app-100'
|
|
230
|
+
: 'text-muted hover:text-default'
|
|
229
231
|
"
|
|
230
232
|
:data-testid="`reports-window-${opt.value}`"
|
|
231
233
|
@click="reports.setWindow(opt.value)"
|
|
@@ -234,7 +236,7 @@ watch(
|
|
|
234
236
|
</button>
|
|
235
237
|
</div>
|
|
236
238
|
<button
|
|
237
|
-
class="rounded-lg border border-
|
|
239
|
+
class="rounded-lg border border-default p-1.5 text-muted transition hover:text-default"
|
|
238
240
|
:aria-label="t('reports.refresh')"
|
|
239
241
|
:title="t('reports.refresh')"
|
|
240
242
|
@click="refresh"
|
|
@@ -246,7 +248,7 @@ watch(
|
|
|
246
248
|
/>
|
|
247
249
|
</button>
|
|
248
250
|
<button
|
|
249
|
-
class="rounded-lg border border-
|
|
251
|
+
class="rounded-lg border border-default p-1.5 text-muted transition hover:text-default"
|
|
250
252
|
:aria-label="t('common.close')"
|
|
251
253
|
@click="close"
|
|
252
254
|
>
|
|
@@ -258,24 +260,24 @@ watch(
|
|
|
258
260
|
<div class="flex-1 overflow-y-auto px-6 py-5">
|
|
259
261
|
<div
|
|
260
262
|
v-if="failed"
|
|
261
|
-
class="mx-auto max-w-2xl rounded-lg border border-
|
|
263
|
+
class="mx-auto max-w-2xl rounded-lg border border-app-error-800/60 bg-app-error-950/40 p-4 text-sm text-app-error-200"
|
|
262
264
|
>
|
|
263
265
|
<p>{{ t('reports.error') }}</p>
|
|
264
|
-
<p v-if="error" class="mt-1 text-xs text-
|
|
266
|
+
<p v-if="error" class="mt-1 text-xs text-app-error-300/80">{{ error }}</p>
|
|
265
267
|
<button
|
|
266
|
-
class="mt-2 rounded-md border border-
|
|
268
|
+
class="mt-2 rounded-md border border-app-error-700 px-3 py-1 text-xs hover:bg-app-error-900/40"
|
|
267
269
|
@click="refresh"
|
|
268
270
|
>
|
|
269
271
|
{{ t('reports.retry') }}
|
|
270
272
|
</button>
|
|
271
273
|
</div>
|
|
272
274
|
|
|
273
|
-
<div v-else-if="loading && !view" class="py-16 text-center text-sm text-
|
|
275
|
+
<div v-else-if="loading && !view" class="py-16 text-center text-sm text-muted">
|
|
274
276
|
{{ t('reports.loading') }}
|
|
275
277
|
</div>
|
|
276
278
|
|
|
277
279
|
<div v-else-if="view" class="mx-auto flex max-w-5xl flex-col gap-6">
|
|
278
|
-
<p class="text-[11px] text-
|
|
280
|
+
<p class="text-[11px] text-dimmed">
|
|
279
281
|
{{
|
|
280
282
|
t('reports.period', {
|
|
281
283
|
from: d(new Date(view.since), 'short'),
|
|
@@ -288,14 +290,14 @@ watch(
|
|
|
288
290
|
account that spent nothing produce the same empty breakdown. -->
|
|
289
291
|
<p
|
|
290
292
|
v-if="rollupState === 'none'"
|
|
291
|
-
class="rounded-lg border border-
|
|
293
|
+
class="rounded-lg border border-app-warning-800/60 bg-app-warning-950/30 px-3 py-2 text-xs text-app-warning-200"
|
|
292
294
|
data-testid="reports-rollup-none"
|
|
293
295
|
>
|
|
294
296
|
{{ t('reports.rollup.none') }}
|
|
295
297
|
</p>
|
|
296
298
|
<p
|
|
297
299
|
v-else-if="rollupState === 'stale'"
|
|
298
|
-
class="rounded-lg border border-
|
|
300
|
+
class="rounded-lg border border-app-warning-800/60 bg-app-warning-950/30 px-3 py-2 text-xs text-app-warning-200"
|
|
299
301
|
data-testid="reports-rollup-stale"
|
|
300
302
|
>
|
|
301
303
|
{{
|
|
@@ -306,7 +308,7 @@ watch(
|
|
|
306
308
|
</p>
|
|
307
309
|
<p
|
|
308
310
|
v-else-if="rollupState === 'current'"
|
|
309
|
-
class="text-[11px] text-
|
|
311
|
+
class="text-[11px] text-dimmed"
|
|
310
312
|
data-testid="reports-rollup-current"
|
|
311
313
|
>
|
|
312
314
|
{{
|
|
@@ -318,47 +320,50 @@ watch(
|
|
|
318
320
|
|
|
319
321
|
<!-- Headline totals. A stat tile, not a chart: these are single numbers. -->
|
|
320
322
|
<section>
|
|
321
|
-
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-
|
|
323
|
+
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
|
|
322
324
|
{{ t('reports.totals.title') }}
|
|
323
325
|
</h2>
|
|
324
326
|
<div class="grid grid-cols-2 gap-3 sm:grid-cols-4">
|
|
325
|
-
<div class="rounded-lg border border-
|
|
326
|
-
<p
|
|
327
|
+
<div class="rounded-lg border border-default bg-default/40 p-3">
|
|
328
|
+
<p
|
|
329
|
+
class="text-2xl font-semibold text-app-secondary-300"
|
|
330
|
+
data-testid="reports-metered"
|
|
331
|
+
>
|
|
327
332
|
{{ money(view.totals.meteredCost) }}
|
|
328
333
|
</p>
|
|
329
|
-
<p class="text-xs text-
|
|
334
|
+
<p class="text-xs text-dimmed">{{ t('reports.totals.metered') }}</p>
|
|
330
335
|
</div>
|
|
331
|
-
<div class="rounded-lg border border-
|
|
332
|
-
<p class="text-2xl font-semibold text-
|
|
336
|
+
<div class="rounded-lg border border-default bg-default/40 p-3">
|
|
337
|
+
<p class="text-2xl font-semibold text-app-warning-300">
|
|
333
338
|
{{ money(view.totals.subscriptionCost) }}
|
|
334
339
|
</p>
|
|
335
|
-
<p class="text-xs text-
|
|
340
|
+
<p class="text-xs text-dimmed">{{ t('reports.totals.subscription') }}</p>
|
|
336
341
|
</div>
|
|
337
|
-
<div class="rounded-lg border border-
|
|
338
|
-
<p class="text-2xl font-semibold text-
|
|
342
|
+
<div class="rounded-lg border border-default bg-default/40 p-3">
|
|
343
|
+
<p class="text-2xl font-semibold text-highlighted">
|
|
339
344
|
{{ n(view.totals.calls, 'decimal') }}
|
|
340
345
|
</p>
|
|
341
|
-
<p class="text-xs text-
|
|
346
|
+
<p class="text-xs text-dimmed">{{ t('reports.totals.calls') }}</p>
|
|
342
347
|
</div>
|
|
343
|
-
<div class="rounded-lg border border-
|
|
344
|
-
<p class="text-2xl font-semibold text-
|
|
348
|
+
<div class="rounded-lg border border-default bg-default/40 p-3">
|
|
349
|
+
<p class="text-2xl font-semibold text-highlighted">
|
|
345
350
|
{{ formatTokens(view.totals.inputTokens + view.totals.outputTokens) }}
|
|
346
351
|
</p>
|
|
347
|
-
<p class="text-xs text-
|
|
352
|
+
<p class="text-xs text-dimmed">{{ t('reports.totals.tokens') }}</p>
|
|
348
353
|
</div>
|
|
349
354
|
</div>
|
|
350
|
-
<p class="mt-1.5 text-[10px] text-
|
|
355
|
+
<p class="mt-1.5 text-[10px] text-dimmed">
|
|
351
356
|
{{ t('reports.totals.illustrative') }}
|
|
352
357
|
</p>
|
|
353
358
|
</section>
|
|
354
359
|
|
|
355
360
|
<!-- Spend over time. One axis, two stacked series, legend always present. -->
|
|
356
361
|
<section>
|
|
357
|
-
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-
|
|
362
|
+
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
|
|
358
363
|
{{ t('reports.trend.title') }}
|
|
359
364
|
</h2>
|
|
360
|
-
<div class="rounded-lg border border-
|
|
361
|
-
<div v-if="!hasSpend" class="py-6 text-center text-xs text-
|
|
365
|
+
<div class="rounded-lg border border-default bg-default/40 p-4">
|
|
366
|
+
<div v-if="!hasSpend" class="py-6 text-center text-xs text-dimmed">
|
|
362
367
|
{{ t('reports.trend.empty') }}
|
|
363
368
|
</div>
|
|
364
369
|
<div v-else class="flex h-28 items-end gap-0.5" data-testid="reports-trend">
|
|
@@ -369,18 +374,18 @@ watch(
|
|
|
369
374
|
:title="trendTooltip(point)"
|
|
370
375
|
>
|
|
371
376
|
<div
|
|
372
|
-
class="w-full rounded-t-sm bg-
|
|
377
|
+
class="w-full rounded-t-sm bg-app-warning-600"
|
|
373
378
|
:style="{ height: `${columnPct(point.subscriptionCost, maxTrend)}%` }"
|
|
374
379
|
/>
|
|
375
380
|
<div
|
|
376
|
-
class="w-full rounded-sm bg-
|
|
381
|
+
class="w-full rounded-sm bg-app-secondary-500"
|
|
377
382
|
:style="{ height: `${columnPct(point.meteredCost, maxTrend)}%` }"
|
|
378
383
|
/>
|
|
379
384
|
</div>
|
|
380
385
|
</div>
|
|
381
|
-
<div class="mt-2 flex items-center gap-4 text-[11px] text-
|
|
386
|
+
<div class="mt-2 flex items-center gap-4 text-[11px] text-dimmed">
|
|
382
387
|
<span class="flex items-center gap-1" :title="t('reports.legend.meteredHint')">
|
|
383
|
-
<span class="h-2 w-2 rounded-sm bg-
|
|
388
|
+
<span class="h-2 w-2 rounded-sm bg-app-secondary-500" />{{
|
|
384
389
|
t('reports.legend.metered')
|
|
385
390
|
}}
|
|
386
391
|
</span>
|
|
@@ -388,7 +393,7 @@ watch(
|
|
|
388
393
|
class="flex items-center gap-1"
|
|
389
394
|
:title="t('reports.legend.subscriptionHint')"
|
|
390
395
|
>
|
|
391
|
-
<span class="h-2 w-2 rounded-sm bg-
|
|
396
|
+
<span class="h-2 w-2 rounded-sm bg-app-warning-600" />{{
|
|
392
397
|
t('reports.legend.subscription')
|
|
393
398
|
}}
|
|
394
399
|
</span>
|
|
@@ -399,7 +404,7 @@ watch(
|
|
|
399
404
|
<!-- Spend by model + by agent kind: the two axes a run has no single value for. -->
|
|
400
405
|
<div class="grid gap-6 md:grid-cols-2">
|
|
401
406
|
<section>
|
|
402
|
-
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-
|
|
407
|
+
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
|
|
403
408
|
{{ t('reports.spend.byModel') }}
|
|
404
409
|
</h2>
|
|
405
410
|
<ReportsSpendBreakdown
|
|
@@ -410,7 +415,7 @@ watch(
|
|
|
410
415
|
/>
|
|
411
416
|
</section>
|
|
412
417
|
<section>
|
|
413
|
-
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-
|
|
418
|
+
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
|
|
414
419
|
{{ t('reports.spend.byAgentKind') }}
|
|
415
420
|
</h2>
|
|
416
421
|
<ReportsSpendBreakdown
|
|
@@ -429,7 +434,7 @@ watch(
|
|
|
429
434
|
breakdowns the projection caps, and each says so under its own card. -->
|
|
430
435
|
<div class="grid gap-6 md:grid-cols-2">
|
|
431
436
|
<section>
|
|
432
|
-
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-
|
|
437
|
+
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
|
|
433
438
|
{{ t('reports.spend.byTicket') }}
|
|
434
439
|
</h2>
|
|
435
440
|
<ReportsSpendBreakdown
|
|
@@ -441,7 +446,7 @@ watch(
|
|
|
441
446
|
/>
|
|
442
447
|
</section>
|
|
443
448
|
<section>
|
|
444
|
-
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-
|
|
449
|
+
<h2 class="mb-2 text-xs font-semibold uppercase tracking-wide text-dimmed">
|
|
445
450
|
{{ t('reports.spend.byRun') }}
|
|
446
451
|
</h2>
|
|
447
452
|
<ReportsSpendBreakdown
|
|
@@ -457,18 +462,18 @@ watch(
|
|
|
457
462
|
<!-- The shared axis: spend AND activity for the same grouping, side by side. -->
|
|
458
463
|
<section class="flex flex-col gap-3">
|
|
459
464
|
<div class="flex flex-wrap items-center gap-2">
|
|
460
|
-
<h2 class="text-xs font-semibold uppercase tracking-wide text-
|
|
465
|
+
<h2 class="text-xs font-semibold uppercase tracking-wide text-dimmed">
|
|
461
466
|
{{ t('reports.breakdown.title') }}
|
|
462
467
|
</h2>
|
|
463
|
-
<div class="flex rounded-lg border border-
|
|
468
|
+
<div class="flex rounded-lg border border-default p-0.5 text-[12px]">
|
|
464
469
|
<button
|
|
465
470
|
v-for="opt in DIMENSIONS"
|
|
466
471
|
:key="opt.value"
|
|
467
472
|
class="rounded-md px-2.5 py-1 transition"
|
|
468
473
|
:class="
|
|
469
474
|
dimension === opt.value
|
|
470
|
-
? 'bg-
|
|
471
|
-
: 'text-
|
|
475
|
+
? 'bg-elevated text-app-100'
|
|
476
|
+
: 'text-muted hover:text-default'
|
|
472
477
|
"
|
|
473
478
|
:data-testid="`reports-dimension-${opt.value}`"
|
|
474
479
|
@click="dimension = opt.value"
|
|
@@ -479,7 +484,9 @@ watch(
|
|
|
479
484
|
</div>
|
|
480
485
|
<div class="grid gap-6 md:grid-cols-2">
|
|
481
486
|
<div>
|
|
482
|
-
<h3 class="mb-2 text-[11px] text-
|
|
487
|
+
<h3 class="mb-2 text-[11px] text-dimmed">
|
|
488
|
+
{{ t('reports.spend.heading') }}
|
|
489
|
+
</h3>
|
|
483
490
|
<ReportsSpendBreakdown
|
|
484
491
|
:rows="spendByDimension"
|
|
485
492
|
:currency="currency"
|
|
@@ -488,13 +495,13 @@ watch(
|
|
|
488
495
|
/>
|
|
489
496
|
</div>
|
|
490
497
|
<div>
|
|
491
|
-
<h3 class="mb-2 text-[11px] text-
|
|
498
|
+
<h3 class="mb-2 text-[11px] text-dimmed">
|
|
492
499
|
{{ t('reports.activity.heading') }}
|
|
493
500
|
</h3>
|
|
494
|
-
<div class="rounded-lg border border-
|
|
501
|
+
<div class="rounded-lg border border-default bg-default/40 p-4">
|
|
495
502
|
<div
|
|
496
503
|
v-if="!activityByDimension.length"
|
|
497
|
-
class="py-4 text-center text-xs text-
|
|
504
|
+
class="py-4 text-center text-xs text-dimmed"
|
|
498
505
|
>
|
|
499
506
|
{{ t('reports.activity.empty') }}
|
|
500
507
|
</div>
|
|
@@ -507,10 +514,8 @@ watch(
|
|
|
507
514
|
data-testid="reports-activity-row"
|
|
508
515
|
>
|
|
509
516
|
<div class="mb-1 flex items-baseline justify-between gap-2">
|
|
510
|
-
<span class="min-w-0 truncate text-
|
|
511
|
-
|
|
512
|
-
}}</span>
|
|
513
|
-
<span class="shrink-0 tabular-nums text-slate-400">
|
|
517
|
+
<span class="min-w-0 truncate text-toned">{{ sliceLabel(row) }}</span>
|
|
518
|
+
<span class="shrink-0 tabular-nums text-muted">
|
|
514
519
|
{{ t('reports.activity.runs', { count: row.runs }, row.runs) }}
|
|
515
520
|
</span>
|
|
516
521
|
</div>
|
|
@@ -527,7 +532,7 @@ watch(
|
|
|
527
532
|
</div>
|
|
528
533
|
<!-- The status counts in text: the reserved status hues are
|
|
529
534
|
red-green adjacent, so identity is never colour alone. -->
|
|
530
|
-
<p class="mt-1 flex flex-wrap gap-x-2 text-[10px] text-
|
|
535
|
+
<p class="mt-1 flex flex-wrap gap-x-2 text-[10px] text-dimmed">
|
|
531
536
|
<span v-for="segment in activitySegments(row)" :key="segment.status">
|
|
532
537
|
{{ n(segment.count, 'decimal') }} {{ statusLabel(segment.status) }}
|
|
533
538
|
</span>
|
|
@@ -540,9 +545,7 @@ watch(
|
|
|
540
545
|
</p>
|
|
541
546
|
</li>
|
|
542
547
|
</ul>
|
|
543
|
-
<div
|
|
544
|
-
class="mt-3 flex flex-wrap items-center gap-3 text-[11px] text-slate-500"
|
|
545
|
-
>
|
|
548
|
+
<div class="mt-3 flex flex-wrap items-center gap-3 text-[11px] text-dimmed">
|
|
546
549
|
<span
|
|
547
550
|
v-for="status in ['done', 'failed', 'running', 'other'] as const"
|
|
548
551
|
:key="status"
|
|
@@ -33,23 +33,23 @@ const max = computed(() => maxOf(props.rows, spendMagnitude))
|
|
|
33
33
|
</script>
|
|
34
34
|
|
|
35
35
|
<template>
|
|
36
|
-
<div class="rounded-lg border border-
|
|
37
|
-
<div v-if="!rows.length" class="py-4 text-center text-xs text-
|
|
36
|
+
<div class="rounded-lg border border-default bg-default/40 p-4">
|
|
37
|
+
<div v-if="!rows.length" class="py-4 text-center text-xs text-dimmed">
|
|
38
38
|
{{ t('reports.spend.empty') }}
|
|
39
39
|
</div>
|
|
40
40
|
<ul v-else class="flex flex-col gap-2.5" :data-testid="testId">
|
|
41
41
|
<li v-for="row in rows" :key="row.key" class="text-xs" data-testid="reports-spend-row">
|
|
42
42
|
<div class="mb-1 flex items-baseline justify-between gap-2">
|
|
43
|
-
<span class="min-w-0 truncate text-
|
|
43
|
+
<span class="min-w-0 truncate text-toned">{{ labelOf(row) }}</span>
|
|
44
44
|
<!-- The metered figure alone is the slice's SPEND. The subscription cost rides
|
|
45
45
|
beside it, in its own series colour and explicitly named, because it is the
|
|
46
46
|
illustrative cost of flat-rate quota usage — adding the two into one currency
|
|
47
47
|
figure would report money that was never billed. -->
|
|
48
|
-
<span class="shrink-0 tabular-nums text-
|
|
48
|
+
<span class="shrink-0 tabular-nums text-muted">
|
|
49
49
|
{{ money(row.meteredCost) }}
|
|
50
50
|
<span
|
|
51
51
|
v-if="row.subscriptionCost > 0"
|
|
52
|
-
class="text-
|
|
52
|
+
class="text-app-warning-400"
|
|
53
53
|
:title="t('reports.legend.subscriptionHint')"
|
|
54
54
|
>
|
|
55
55
|
{{ t('reports.spend.subscriptionAside', { value: money(row.subscriptionCost) }) }}
|
|
@@ -58,15 +58,15 @@ const max = computed(() => maxOf(props.rows, spendMagnitude))
|
|
|
58
58
|
</div>
|
|
59
59
|
<div class="flex h-1.5 gap-[2px]">
|
|
60
60
|
<div
|
|
61
|
-
class="h-1.5 rounded-full bg-
|
|
61
|
+
class="h-1.5 rounded-full bg-app-secondary-500"
|
|
62
62
|
:style="{ width: `${segmentPct(row.meteredCost, max)}%` }"
|
|
63
63
|
/>
|
|
64
64
|
<div
|
|
65
|
-
class="h-1.5 rounded-full bg-
|
|
65
|
+
class="h-1.5 rounded-full bg-app-warning-600"
|
|
66
66
|
:style="{ width: `${segmentPct(row.subscriptionCost, max)}%` }"
|
|
67
67
|
/>
|
|
68
68
|
</div>
|
|
69
|
-
<p class="mt-1 text-[10px] text-
|
|
69
|
+
<p class="mt-1 text-[10px] text-dimmed">
|
|
70
70
|
{{ t('reports.spend.calls', { count: row.calls }, row.calls) }} ·
|
|
71
71
|
{{
|
|
72
72
|
t('reports.spend.tokens', {
|
|
@@ -77,7 +77,7 @@ const max = computed(() => maxOf(props.rows, spendMagnitude))
|
|
|
77
77
|
</p>
|
|
78
78
|
</li>
|
|
79
79
|
</ul>
|
|
80
|
-
<p v-if="cap" class="mt-3 text-[10px] text-
|
|
80
|
+
<p v-if="cap" class="mt-3 text-[10px] text-dimmed" :data-testid="`${testId}-capped`">
|
|
81
81
|
{{
|
|
82
82
|
t('reports.spend.capped', { shown: n(cap.returned), omitted: n(cap.omitted) }, cap.omitted)
|
|
83
83
|
}}
|