@zaip-ai/cli 3.8.0 → 4.1.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 +5 -5
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +11 -6
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/agent-adapters.js +1 -1
- package/dist/services/agent-adapters.js.map +1 -1
- package/dist/services/backup-gitignore.d.ts +9 -0
- package/dist/services/backup-gitignore.d.ts.map +1 -0
- package/dist/services/backup-gitignore.js +66 -0
- package/dist/services/backup-gitignore.js.map +1 -0
- package/dist/services/backup-gitignore.test.d.ts +2 -0
- package/dist/services/backup-gitignore.test.d.ts.map +1 -0
- package/dist/services/backup-gitignore.test.js +27 -0
- package/dist/services/backup-gitignore.test.js.map +1 -0
- package/dist/services/codex-config-template.d.ts +2 -2
- package/dist/services/codex-config-template.d.ts.map +1 -1
- package/dist/services/codex-config-template.js +4 -3
- package/dist/services/codex-config-template.js.map +1 -1
- package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
- package/dist/services/codex-conversation-lifecycle-hook.js +15 -7
- package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
- package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
- package/dist/services/codex-pre-tool-hook-template.js +10 -11
- package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
- package/dist/services/codex-pre-tool-hook-template.test.d.ts +2 -0
- package/dist/services/codex-pre-tool-hook-template.test.d.ts.map +1 -0
- package/dist/services/codex-pre-tool-hook-template.test.js +33 -0
- package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -0
- package/dist/services/codex-subagent-hook-template.d.ts +1 -1
- package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
- package/dist/services/codex-subagent-hook-template.js +3 -0
- package/dist/services/codex-subagent-hook-template.js.map +1 -1
- package/dist/services/codex-windows-hook-command.d.ts +3 -0
- package/dist/services/codex-windows-hook-command.d.ts.map +1 -0
- package/dist/services/codex-windows-hook-command.js +10 -0
- package/dist/services/codex-windows-hook-command.js.map +1 -0
- package/dist/services/codex-windows-hook-command.test.d.ts +2 -0
- package/dist/services/codex-windows-hook-command.test.d.ts.map +1 -0
- package/dist/services/codex-windows-hook-command.test.js +44 -0
- package/dist/services/codex-windows-hook-command.test.js.map +1 -0
- package/dist/services/global-codex-config.d.ts.map +1 -1
- package/dist/services/global-codex-config.js +27 -13
- package/dist/services/global-codex-config.js.map +1 -1
- package/dist/services/global-codex-config.test.js +27 -2
- package/dist/services/global-codex-config.test.js.map +1 -1
- package/dist/services/install-agents-template.d.ts.map +1 -1
- package/dist/services/install-agents-template.js +43 -127
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/install-template-policy.d.ts.map +1 -1
- package/dist/services/install-template-policy.js +2 -0
- package/dist/services/install-template-policy.js.map +1 -1
- package/dist/services/legacy-records-migration.d.ts +15 -0
- package/dist/services/legacy-records-migration.d.ts.map +1 -0
- package/dist/services/legacy-records-migration.js +109 -0
- package/dist/services/legacy-records-migration.js.map +1 -0
- package/dist/services/local-state-migration.d.ts +8 -1
- package/dist/services/local-state-migration.d.ts.map +1 -1
- package/dist/services/local-state-migration.js +67 -32
- package/dist/services/local-state-migration.js.map +1 -1
- package/dist/services/logger.d.ts.map +1 -1
- package/dist/services/logger.js +2 -0
- package/dist/services/logger.js.map +1 -1
- package/dist/services/project-model-migration.d.ts +3 -0
- package/dist/services/project-model-migration.d.ts.map +1 -0
- package/dist/services/project-model-migration.js +163 -0
- package/dist/services/project-model-migration.js.map +1 -0
- package/dist/services/project-model-migration.test.d.ts +2 -0
- package/dist/services/project-model-migration.test.d.ts.map +1 -0
- package/dist/services/project-model-migration.test.js +62 -0
- package/dist/services/project-model-migration.test.js.map +1 -0
- package/dist/services/template-manifest.d.ts.map +1 -1
- package/dist/services/template-manifest.js +2 -0
- package/dist/services/template-manifest.js.map +1 -1
- package/dist/services/transactional-files.d.ts +1 -0
- package/dist/services/transactional-files.d.ts.map +1 -1
- package/dist/services/transactional-files.js +3 -0
- package/dist/services/transactional-files.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/README-ENG.md +88 -32
- package/templates/.agents/README.md +57 -30
- package/templates/.agents/config/agents/discovery.json +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -1
- package/templates/.agents/config/project.yaml +21 -7
- package/templates/.agents/dashboard/.zaip-managed.json +184 -112
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-D2PL4UOu.js → CostCalculationGuidePage-f4ZGJRg3.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-CocoP9CA.js → DashboardHelpDialog-DlN5EMmD.js} +238 -124
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-D255_hNf.js → PricingSettingsDialog-v9zGRTlk.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BRdoeTWk.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-BTFSLQ69.js → TraceabilityWorkspace-B_5u4Xnp.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{cost-monitor-BsMfGfQi.css → cost-monitor-C2AFYBu_.css} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-D7PrDZy9.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-058lag33.js → dashboard-localization-CF7B1Hjn.js} +88 -32
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DeFPiN32.js → icons-vendor-Cv3WBFIF.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-C4rLXrz_.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-BIWcbEAc.js → react-vendor-mHgsmxb6.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-fZZL0ohD.js → traceability-B0CPyEVq.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +6 -6
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/AppDashboardContent.tsx +11 -1
- package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +3 -2
- package/templates/.agents/dashboard/apps/frontend/src/AppLoadingPanels.tsx +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +9 -13
- package/templates/.agents/dashboard/apps/frontend/src/cost-monitor-population.test.tsx +4 -2
- package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +9 -5
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api-settings.ts +3 -2
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +2 -2
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-identity.test.ts +3 -3
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-identity.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.test.ts +2 -1
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +40 -3
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +12 -1
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +19 -0
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +3 -1
- package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-app-model.tsx +14 -23
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +3 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +2 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionTable.tsx +2 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.period-values.test.tsx +66 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.tsx +29 -34
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.embedded.test.ts +11 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +1 -13
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostPeriodAverageCards.test.tsx +23 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostPeriodAverageCards.tsx +2 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableDisplay.ts +6 -11
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +6 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +10 -12
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-group-page-totals.ts +23 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-group-period-values.tsx +34 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-embedded.css +0 -7
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-formatters.ts +4 -9
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-presentation.ts +2 -3
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/DeveloperAttributionPanel.tsx +2 -12
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +2 -2
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +1 -6
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +34 -36
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewCharts.tsx +12 -3
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.tsx +12 -14
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +4 -4
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +23 -4
- package/templates/.agents/dashboard/modules/operations/src/react/OverviewCostKpi.tsx +30 -2
- package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +2 -13
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts +8 -1
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +8 -16
- package/templates/.agents/dashboard/modules/operations/src/react/WorkColumnState.tsx +34 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operations-average-unmeasured.test.ts +10 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-content-visibility.ts +3 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +4 -3
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +12 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +1 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-skeleton.css +80 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations.css +2 -11
- package/templates/.agents/dashboard/modules/operations/src/react/overview-cost-card.test.tsx +36 -0
- package/templates/.agents/dashboard/modules/operations/src/react/overview-metric-format.test.ts +11 -0
- package/templates/.agents/dashboard/modules/operations/src/react/overview-metric-format.ts +28 -3
- package/templates/.agents/dashboard/modules/operations/src/react/overview-metric-stats.ts +44 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-card-label.ts +5 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-column-state.ts +11 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-item-filter.ts +13 -0
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +157 -157
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +153 -153
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +159 -159
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +31 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +74 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-identity.test.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.test.ts +25 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +51 -16
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-ui-security.ts +37 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +11 -33
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +12 -13
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.test.ts +71 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +141 -25
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-worktree-sources.test.ts +60 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-rebuild-fingerprint-options.ts +13 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +26 -2
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +5 -0
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/packages/ui/src/DashboardHeader.test.mjs +5 -0
- package/templates/.agents/dashboard/packages/ui/src/DashboardHeader.tsx +4 -4
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +4 -0
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +4 -4
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +1 -1
- package/templates/.agents/dashboard/tests/e2e/specs/performance-work-row-identity.ts +6 -0
- package/templates/.agents/design/.zaip-managed.json +13 -9
- package/templates/.agents/design/apps/catalog/dist/assets/index-DkpQYoyC.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/index.html +1 -1
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.test.tsx +8 -4
- package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.tsx +10 -3
- package/templates/.agents/design/apps/catalog/src/components/DashboardFiltersSpecimen.tsx +0 -15
- package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +3 -3
- package/templates/.agents/design/apps/catalog/src/stories/DashboardFilters.stories.tsx +0 -1
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +1 -1
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/rules/autonomy-decision.md +2 -2
- package/templates/.agents/rules/workflow.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +65 -54
- package/templates/.agents/runtime/checksums.sha256 +5 -5
- package/templates/.agents/runtime/manifest.json +1 -1
- package/templates/.agents/runtime/provenance.json +4 -4
- package/templates/.agents/runtime/sbom.cdx.json +1 -1
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/SKILL.md +7 -7
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.mjs +32 -7
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.test.mjs +134 -1
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-lease.mjs +57 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/scheduled-ready-queue-contract.test.mjs +9 -6
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
- package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +18 -6
- package/templates/.agents/skills/zaip-skill-instalar-agendamento/SKILL.md +2 -2
- package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +6 -0
- package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +47 -5
- package/templates/.agents/zaip-aios/README.md +4 -4
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/01-primeiros-passos.md +4 -3
- package/templates/.agents/zaip-aios/guides/03-tasks.md +5 -4
- package/templates/.agents/zaip-aios/guides/04-specs.md +4 -1
- package/templates/.agents/zaip-aios/guides/05-prds.md +7 -3
- package/templates/.agents/zaip-aios/guides/06-execucao.md +9 -4
- package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +9 -5
- package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +10 -2
- package/templates/.agents/zaip-aios/guides/12-instalacao-e-upgrade.md +10 -5
- package/templates/.agents/zaip-aios/guides/13-boas-praticas.md +12 -1
- package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +3 -1
- package/templates/.agents/zaip-aios/guides/16-lifecycle-e-reconciliacao.md +12 -7
- package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +1 -1
- package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +4 -0
- package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +19 -15
- package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +12 -8
- package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +4 -3
- package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +9 -7
- package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +38 -22
- package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +1 -1
- package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +14 -5
- package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +6 -0
- package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +129 -11
- package/templates/template-manifest.json +270 -186
- package/templates/tsconfig.base.json +22 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-0f_x2TzJ.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-zhY2JoLc.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Dh95Yodm.js +0 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { formatSummaryMetricValue } from "./overview-metric-format.js";
|
|
1
|
+
import { formatSummaryMetricValue, unmeasuredZeroDescription } from "./overview-metric-format.js";
|
|
2
|
+
import { overviewMetricStats } from "./overview-metric-stats.js";
|
|
2
3
|
|
|
3
4
|
export { formatSummaryMetricValue } from "./overview-metric-format.js";
|
|
4
5
|
|
|
@@ -104,6 +105,7 @@ export function OperationsOverview({
|
|
|
104
105
|
tasks = data.tasks,
|
|
105
106
|
factualCostTotal,
|
|
106
107
|
factualCostFact,
|
|
108
|
+
costLoading = false,
|
|
107
109
|
resolveRunCost,
|
|
108
110
|
includeLegacyEffort: _includeLegacyEffort = false,
|
|
109
111
|
}: {
|
|
@@ -141,6 +143,7 @@ export function OperationsOverview({
|
|
|
141
143
|
factualCostTotal?: number | null | undefined;
|
|
142
144
|
/** Measurement completeness for the matching Cost Monitor snapshot. */
|
|
143
145
|
factualCostFact?: FactualCostFact | undefined;
|
|
146
|
+
costLoading?: boolean | undefined;
|
|
144
147
|
resolveRunCost?: ((runId: string) => number | null) | undefined;
|
|
145
148
|
includeLegacyEffort?: boolean;
|
|
146
149
|
}) {
|
|
@@ -392,39 +395,23 @@ export function OperationsOverview({
|
|
|
392
395
|
? (overviewMetrics?.latest_task_created_at ?? null)
|
|
393
396
|
: findLatestCreatedAt(tasks)
|
|
394
397
|
: (selectedMacroAggregate?.latest_created_at ?? findLatestCreatedAt(selectedMacros));
|
|
395
|
-
const metricStats =
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
),
|
|
413
|
-
],
|
|
414
|
-
[
|
|
415
|
-
factualCostAverageLabel(
|
|
416
|
-
overviewView === "tasks" ? factualCostFact : undefined,
|
|
417
|
-
selectedCount,
|
|
418
|
-
locale,
|
|
419
|
-
),
|
|
420
|
-
formatSummaryMetricValue(
|
|
421
|
-
averageCost,
|
|
422
|
-
selectedCount,
|
|
423
|
-
(value) => formatCurrency(value, currency, locale),
|
|
424
|
-
locale,
|
|
425
|
-
),
|
|
426
|
-
],
|
|
427
|
-
] as const;
|
|
398
|
+
const metricStats = overviewMetricStats({
|
|
399
|
+
averageCost,
|
|
400
|
+
averageDuration,
|
|
401
|
+
averageTokens,
|
|
402
|
+
costLabel: factualCostAverageLabel(
|
|
403
|
+
overviewView === "tasks" ? factualCostFact : undefined,
|
|
404
|
+
selectedCount,
|
|
405
|
+
locale,
|
|
406
|
+
),
|
|
407
|
+
count: selectedCount,
|
|
408
|
+
formatCost: (value) => formatCurrency(value, currency, locale),
|
|
409
|
+
formatDuration: (value) => formatDurationMs(value, locale),
|
|
410
|
+
formatTokens: (value) => formatCompactNumber(value, locale),
|
|
411
|
+
locale,
|
|
412
|
+
timeLabel: text.averageTime,
|
|
413
|
+
tokensLabel: text.averageTokens,
|
|
414
|
+
});
|
|
428
415
|
const aggregateTopTasks: EntityMetric[] = (overviewMetrics?.top_tasks ?? []).map((metric) => ({
|
|
429
416
|
id: metric.task_id,
|
|
430
417
|
title: tasks.find((task) => task.id === metric.task_id)?.title ?? metric.task_id,
|
|
@@ -605,6 +592,12 @@ export function OperationsOverview({
|
|
|
605
592
|
metricPopulationCount,
|
|
606
593
|
(value) => formatDurationMs(value, locale),
|
|
607
594
|
locale,
|
|
595
|
+
true,
|
|
596
|
+
)}
|
|
597
|
+
description={unmeasuredZeroDescription(
|
|
598
|
+
totalDurationMetric,
|
|
599
|
+
metricPopulationCount,
|
|
600
|
+
locale,
|
|
608
601
|
)}
|
|
609
602
|
/>{" "}
|
|
610
603
|
<Kpi
|
|
@@ -615,8 +608,8 @@ export function OperationsOverview({
|
|
|
615
608
|
? `0 / ${metricUnit} (0 / hora)`
|
|
616
609
|
: `0 / ${metricUnit} (0 / hour)`
|
|
617
610
|
: locale === "pt-BR"
|
|
618
|
-
? "
|
|
619
|
-
: "
|
|
611
|
+
? "Sem tokens medidos para calcular médias"
|
|
612
|
+
: "No measured tokens for averages"
|
|
620
613
|
: locale === "pt-BR"
|
|
621
614
|
? `${formatCompactNumber(tokensPerTask, locale)} / ${metricUnit} (${formatCompactNumber(tokensPerHour, locale, 0)} / hora)`
|
|
622
615
|
: `${formatCompactNumber(tokensPerTask, locale)} / ${metricUnit} (${formatCompactNumber(tokensPerHour, locale, 0)} / hour)`
|
|
@@ -635,9 +628,12 @@ export function OperationsOverview({
|
|
|
635
628
|
metricPopulationCount,
|
|
636
629
|
(value) => formatCompactNumber(value, locale),
|
|
637
630
|
locale,
|
|
631
|
+
true,
|
|
638
632
|
)}
|
|
633
|
+
description={unmeasuredZeroDescription(totalTokensMetric, metricPopulationCount, locale)}
|
|
639
634
|
/>{" "}
|
|
640
635
|
<OverviewCostKpi
|
|
636
|
+
loading={costLoading && overviewView === "tasks"}
|
|
641
637
|
fact={overviewView === "tasks" ? factualCostFact : undefined}
|
|
642
638
|
unit={metricUnit}
|
|
643
639
|
locale={locale}
|
|
@@ -658,6 +654,7 @@ export function OperationsOverview({
|
|
|
658
654
|
<div className="operations-chart-grid">
|
|
659
655
|
{" "}
|
|
660
656
|
<OperationsOverviewCharts
|
|
657
|
+
costLoading={costLoading && overviewView === "tasks"}
|
|
661
658
|
locale={locale}
|
|
662
659
|
copy={copy}
|
|
663
660
|
text={text}
|
|
@@ -685,6 +682,7 @@ export function OperationsOverview({
|
|
|
685
682
|
}}
|
|
686
683
|
/>
|
|
687
684
|
<OperationsOverviewTopPanel
|
|
685
|
+
costLoading={costLoading && overviewView === "tasks"}
|
|
688
686
|
copy={{ empty: copy.emptyTop, hint: topHint, title: copy.topTitle }}
|
|
689
687
|
currency={currency}
|
|
690
688
|
locale={locale}
|
package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewCharts.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import type { OverviewClassification } from "./operations-page-contract.js";
|
|
|
5
5
|
import type { OperationsLocale } from "./status-labels.js";
|
|
6
6
|
import type { WorkStage } from "./work-board-model.js";
|
|
7
7
|
export function OperationsOverviewCharts({
|
|
8
|
+
costLoading = false,
|
|
8
9
|
locale,
|
|
9
10
|
copy,
|
|
10
11
|
text,
|
|
@@ -17,6 +18,7 @@ export function OperationsOverviewCharts({
|
|
|
17
18
|
onStatusSelect,
|
|
18
19
|
onClassificationSelect,
|
|
19
20
|
}: {
|
|
21
|
+
costLoading?: boolean;
|
|
20
22
|
locale: OperationsLocale;
|
|
21
23
|
copy: ReturnType<typeof overviewCopy>;
|
|
22
24
|
text: ReturnType<typeof overviewText>;
|
|
@@ -151,9 +153,16 @@ export function OperationsOverviewCharts({
|
|
|
151
153
|
<PanelHeader hint={copy.averageHint} title={copy.averageTitle} />{" "}
|
|
152
154
|
<div className="operations-type-summary">
|
|
153
155
|
{" "}
|
|
154
|
-
{metricStats.map(([label, value]) => (
|
|
155
|
-
<div key={label}>
|
|
156
|
-
<span>{label}</span>
|
|
156
|
+
{metricStats.map(([label, value], index) => (
|
|
157
|
+
<div aria-busy={(costLoading && index === 2) || undefined} key={label}>
|
|
158
|
+
<span>{label}</span>{" "}
|
|
159
|
+
<strong>
|
|
160
|
+
{costLoading && index === 2 ? (
|
|
161
|
+
<i className="operations-skeleton-line" aria-hidden="true" />
|
|
162
|
+
) : (
|
|
163
|
+
value
|
|
164
|
+
)}
|
|
165
|
+
</strong>{" "}
|
|
157
166
|
</div>
|
|
158
167
|
))}{" "}
|
|
159
168
|
</div>{" "}
|
package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.tsx
CHANGED
|
@@ -10,13 +10,10 @@ import type { OperationsLocale } from "./status-labels.js";
|
|
|
10
10
|
type OverviewView = "tasks" | "specs" | "prds";
|
|
11
11
|
|
|
12
12
|
const duration = (value: number | null, locale: OperationsLocale) =>
|
|
13
|
-
value === null
|
|
14
|
-
? locale === "pt-BR"
|
|
15
|
-
? "Indisponível"
|
|
16
|
-
: "Unavailable"
|
|
17
|
-
: formatDurationMs(value, locale);
|
|
13
|
+
value === null ? "0" : formatDurationMs(value, locale);
|
|
18
14
|
|
|
19
15
|
export function OperationsOverviewTopPanel({
|
|
16
|
+
costLoading = false,
|
|
20
17
|
copy,
|
|
21
18
|
currency,
|
|
22
19
|
locale,
|
|
@@ -28,6 +25,7 @@ export function OperationsOverviewTopPanel({
|
|
|
28
25
|
topEntities,
|
|
29
26
|
view,
|
|
30
27
|
}: {
|
|
28
|
+
costLoading?: boolean;
|
|
31
29
|
copy: { empty: string; hint: string; title: string };
|
|
32
30
|
currency: "BRL" | "USD";
|
|
33
31
|
locale: OperationsLocale;
|
|
@@ -108,16 +106,16 @@ export function OperationsOverviewTopPanel({
|
|
|
108
106
|
</div>
|
|
109
107
|
<div>
|
|
110
108
|
<span>{text.topFiveCost}</span>
|
|
111
|
-
<strong>
|
|
112
|
-
{
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
<strong aria-busy={costLoading || undefined}>
|
|
110
|
+
{costLoading ? (
|
|
111
|
+
<i className="operations-skeleton-line" aria-hidden="true" />
|
|
112
|
+
) : topCost === null ? (
|
|
113
|
+
duration(null, locale)
|
|
114
|
+
) : (
|
|
115
|
+
formatCurrency(topCost, currency, locale)
|
|
116
|
+
)}
|
|
115
117
|
</strong>
|
|
116
|
-
<small>
|
|
117
|
-
{summary.tokens === null
|
|
118
|
-
? text.tokensUnavailable
|
|
119
|
-
: `${formatCompactNumber(summary.tokens, locale)} tokens`}
|
|
120
|
-
</small>
|
|
118
|
+
<small>{`${formatCompactNumber(summary.tokens, locale)} tokens`}</small>
|
|
121
119
|
</div>
|
|
122
120
|
</div>
|
|
123
121
|
</>
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { OperationsMainContent } from "./OperationsMainContent.js";
|
|
14
14
|
import { OperationsViewTabs } from "./OperationsPageNavigation.js";
|
|
15
15
|
import { OperationsPageLoading, OperationsPageOverview } from "./OperationsPageOverview.js";
|
|
16
|
+
import { shouldRenderOperationsContent } from "./operations-content-visibility.js";
|
|
16
17
|
import {
|
|
17
18
|
type OperationsPageProps,
|
|
18
19
|
resolveOperationsPeriodControl,
|
|
@@ -77,7 +78,7 @@ export function OperationsPage({
|
|
|
77
78
|
capabilityNavigation,
|
|
78
79
|
currency,
|
|
79
80
|
data,
|
|
80
|
-
dashboardTitle = "Dashboard
|
|
81
|
+
dashboardTitle = "Dashboard ZAIP AIOS",
|
|
81
82
|
lastUpdatedAt = data.summary.latest_token_collected_at ?? null,
|
|
82
83
|
loading,
|
|
83
84
|
onLoadingChange,
|
|
@@ -110,6 +111,7 @@ export function OperationsPage({
|
|
|
110
111
|
settings,
|
|
111
112
|
factualCostTotal,
|
|
112
113
|
factualCostFact,
|
|
114
|
+
costLoading,
|
|
113
115
|
factualCostPeriods,
|
|
114
116
|
resolveRunCost,
|
|
115
117
|
}: OperationsPageProps) {
|
|
@@ -662,6 +664,7 @@ export function OperationsPage({
|
|
|
662
664
|
query={query}
|
|
663
665
|
factualCostTotal={factualCostTotal}
|
|
664
666
|
factualCostFact={factualCostFact}
|
|
667
|
+
costLoading={costLoading}
|
|
665
668
|
resolveRunCost={resolveRunCost}
|
|
666
669
|
runs={runs}
|
|
667
670
|
searchInputRef={searchInputRef}
|
|
@@ -758,6 +761,3 @@ export function OperationsPage({
|
|
|
758
761
|
}
|
|
759
762
|
|
|
760
763
|
/** Loading is never a valid zero-valued Operations projection. */
|
|
761
|
-
export function shouldRenderOperationsContent(loading: boolean): boolean {
|
|
762
|
-
return !loading;
|
|
763
|
-
}
|
|
@@ -20,6 +20,7 @@ export function OperationsPageOverview({
|
|
|
20
20
|
defaultDateRange,
|
|
21
21
|
factualCostTotal,
|
|
22
22
|
factualCostFact,
|
|
23
|
+
costLoading,
|
|
23
24
|
includeLegacyEffort,
|
|
24
25
|
locale,
|
|
25
26
|
onOpenTask,
|
|
@@ -49,6 +50,7 @@ export function OperationsPageOverview({
|
|
|
49
50
|
defaultDateRange: OperationDateRange;
|
|
50
51
|
factualCostTotal: OverviewProps["factualCostTotal"];
|
|
51
52
|
factualCostFact: OverviewProps["factualCostFact"];
|
|
53
|
+
costLoading: OverviewProps["costLoading"];
|
|
52
54
|
includeLegacyEffort: boolean;
|
|
53
55
|
locale: OperationsLocale;
|
|
54
56
|
onOpenTask: OverviewProps["onOpenTask"];
|
|
@@ -77,6 +79,7 @@ export function OperationsPageOverview({
|
|
|
77
79
|
currency={currency}
|
|
78
80
|
factualCostTotal={factualCostTotal}
|
|
79
81
|
factualCostFact={factualCostFact}
|
|
82
|
+
costLoading={costLoading}
|
|
80
83
|
datePreset={datePreset}
|
|
81
84
|
dateRange={dateRange}
|
|
82
85
|
locale={locale}
|
|
@@ -163,13 +166,29 @@ export function OperationsPageLoading({ locale }: { locale: OperationsLocale })
|
|
|
163
166
|
return (
|
|
164
167
|
<section
|
|
165
168
|
aria-busy="true"
|
|
166
|
-
aria-
|
|
169
|
+
aria-label={
|
|
170
|
+
locale === "pt-BR" ? "Carregando o período selecionado" : "Loading selected period"
|
|
171
|
+
}
|
|
167
172
|
className="operations-content-skeleton"
|
|
168
173
|
role="status"
|
|
169
174
|
>
|
|
170
|
-
<
|
|
171
|
-
{
|
|
172
|
-
|
|
175
|
+
<div className="operations-skeleton-kpis" aria-hidden="true">
|
|
176
|
+
{["tasks", "specs", "prds", "duration", "tokens", "cost"].map((metric) => (
|
|
177
|
+
<article className="operations-skeleton-block" key={metric}>
|
|
178
|
+
<i className="operations-skeleton-line is-short" />
|
|
179
|
+
<i className="operations-skeleton-line is-value" />
|
|
180
|
+
<i className="operations-skeleton-line" />
|
|
181
|
+
</article>
|
|
182
|
+
))}
|
|
183
|
+
</div>
|
|
184
|
+
<div className="operations-skeleton-panels" aria-hidden="true">
|
|
185
|
+
{["status", "classification", "average", "top"].map((panel) => (
|
|
186
|
+
<article className="operations-skeleton-block" key={panel}>
|
|
187
|
+
<i className="operations-skeleton-line is-short" />
|
|
188
|
+
<i className="operations-skeleton-chart" />
|
|
189
|
+
</article>
|
|
190
|
+
))}
|
|
191
|
+
</div>
|
|
173
192
|
</section>
|
|
174
193
|
);
|
|
175
194
|
}
|
|
@@ -5,7 +5,11 @@ import {
|
|
|
5
5
|
overviewCostRateHint,
|
|
6
6
|
} from "./OperationsOverview.helpers.js";
|
|
7
7
|
import type { FactualCostFact } from "./operations-page-contract.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
formatRoundedCurrency,
|
|
10
|
+
formatSummaryMetricValue,
|
|
11
|
+
unmeasuredZeroDescription,
|
|
12
|
+
} from "./overview-metric-format.js";
|
|
9
13
|
import type { OperationsLocale } from "./status-labels.js";
|
|
10
14
|
|
|
11
15
|
/** Compact presentation, preserving completeness and matching population semantics. */
|
|
@@ -19,6 +23,7 @@ export function OverviewCostKpi({
|
|
|
19
23
|
perHour,
|
|
20
24
|
total,
|
|
21
25
|
label,
|
|
26
|
+
loading = false,
|
|
22
27
|
}: {
|
|
23
28
|
fact: FactualCostFact | undefined;
|
|
24
29
|
unit: string;
|
|
@@ -29,17 +34,40 @@ export function OverviewCostKpi({
|
|
|
29
34
|
perHour: number | null;
|
|
30
35
|
total: number | null;
|
|
31
36
|
label?: string | undefined;
|
|
37
|
+
loading?: boolean;
|
|
32
38
|
}) {
|
|
39
|
+
if (loading)
|
|
40
|
+
return (
|
|
41
|
+
<article
|
|
42
|
+
aria-busy="true"
|
|
43
|
+
aria-label={locale === "pt-BR" ? "Carregando custo estimado" : "Loading estimated cost"}
|
|
44
|
+
className="operations-kpi"
|
|
45
|
+
role="status"
|
|
46
|
+
>
|
|
47
|
+
<span>{label ?? (locale === "pt-BR" ? "Custo Estimado" : "Estimated Cost")}</span>
|
|
48
|
+
<strong>
|
|
49
|
+
<i className="operations-skeleton-line is-value" aria-hidden="true" />
|
|
50
|
+
</strong>
|
|
51
|
+
<small>
|
|
52
|
+
<i className="operations-skeleton-line" aria-hidden="true" />
|
|
53
|
+
</small>
|
|
54
|
+
</article>
|
|
55
|
+
);
|
|
33
56
|
return (
|
|
34
57
|
<Kpi
|
|
35
58
|
hint={overviewCostRateHint(fact, unit, locale, currency, count, perItem, perHour)}
|
|
36
|
-
description={
|
|
59
|
+
description={
|
|
60
|
+
unmeasuredZeroDescription(total, count, locale) ??
|
|
61
|
+
factualCostMetricHint(fact, unit, locale) ??
|
|
62
|
+
undefined
|
|
63
|
+
}
|
|
37
64
|
label={label ?? factualCostMetricLabel(fact, locale)}
|
|
38
65
|
value={formatSummaryMetricValue(
|
|
39
66
|
total,
|
|
40
67
|
count,
|
|
41
68
|
(value) => formatRoundedCurrency(value, currency, locale),
|
|
42
69
|
locale,
|
|
70
|
+
true,
|
|
43
71
|
)}
|
|
44
72
|
/>
|
|
45
73
|
);
|
|
@@ -69,23 +69,12 @@ export function TaskDetailsDialog({
|
|
|
69
69
|
label={copy.duration}
|
|
70
70
|
value={formatOperationDuration(telemetry.durationMs, locale)}
|
|
71
71
|
/>
|
|
72
|
-
<Detail
|
|
73
|
-
label="Tokens"
|
|
74
|
-
value={
|
|
75
|
-
telemetry.tokens === null
|
|
76
|
-
? locale === "pt-BR"
|
|
77
|
-
? "Indisponível"
|
|
78
|
-
: "Unavailable"
|
|
79
|
-
: formatCompactNumber(telemetry.tokens, locale)
|
|
80
|
-
}
|
|
81
|
-
/>
|
|
72
|
+
<Detail label="Tokens" value={formatCompactNumber(telemetry.tokens, locale)} />
|
|
82
73
|
<Detail
|
|
83
74
|
label={locale === "pt-BR" ? "Custo" : "Cost"}
|
|
84
75
|
value={
|
|
85
76
|
telemetry.costBrl === null
|
|
86
|
-
?
|
|
87
|
-
? "Indisponível"
|
|
88
|
-
: "Unavailable"
|
|
77
|
+
? "0"
|
|
89
78
|
: new Intl.NumberFormat(locale, { style: "currency", currency: "BRL" }).format(
|
|
90
79
|
telemetry.costBrl,
|
|
91
80
|
)
|
package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { mergeManualWorkOrder, sortWorkItems } from "./UnifiedWorkBoard.js";
|
|
2
|
+
import { mergeManualWorkOrder, sortWorkItems, workColumnState } from "./UnifiedWorkBoard.js";
|
|
3
3
|
|
|
4
4
|
describe("UnifiedWorkBoard priority path", () => {
|
|
5
|
+
it("does not claim an unrequested or in-flight column is empty", () => {
|
|
6
|
+
expect(workColumnState(0, 0, undefined)).toBe("loading");
|
|
7
|
+
expect(workColumnState(0, 2, { loading: false, error: null })).toBe("loading");
|
|
8
|
+
expect(workColumnState(0, 0, { loading: true, error: null })).toBe("loading");
|
|
9
|
+
expect(workColumnState(0, 0, { loading: false, error: null })).toBe("empty");
|
|
10
|
+
expect(workColumnState(0, 0, { loading: false, error: "falhou" })).toBe("error");
|
|
11
|
+
});
|
|
5
12
|
const item = (id: string, rank: number | null, createdAt = "2026-08-04T10:00:00.000Z") =>
|
|
6
13
|
({ kind: "task", row: { id, manual_order: rank, updated_at: createdAt } }) as never;
|
|
7
14
|
|
|
@@ -18,6 +18,7 @@ import { TaskDetailsDialog } from "./TaskDetailsDialog.js";
|
|
|
18
18
|
import { taskOrigin } from "./task-origin.js";
|
|
19
19
|
import { useCurrentTime } from "./use-current-time.js";
|
|
20
20
|
import { useInfiniteColumn } from "./use-infinite-column.js";
|
|
21
|
+
import { WorkColumnState } from "./WorkColumnState.js";
|
|
21
22
|
import {
|
|
22
23
|
isWorkItemVisible,
|
|
23
24
|
type MacroWorkProgress,
|
|
@@ -30,6 +31,9 @@ import {
|
|
|
30
31
|
workStageLabel,
|
|
31
32
|
workStages,
|
|
32
33
|
} from "./work-board-model.js";
|
|
34
|
+
import { openWorkCardLabel } from "./work-card-label.js";
|
|
35
|
+
import { workColumnState } from "./work-column-state.js";
|
|
36
|
+
import { filterWorkItems } from "./work-item-filter.js";
|
|
33
37
|
import "./unified-work-board.css";
|
|
34
38
|
|
|
35
39
|
type WorkItem =
|
|
@@ -323,6 +327,7 @@ function WorkColumn({
|
|
|
323
327
|
totalItems,
|
|
324
328
|
onLoadMore,
|
|
325
329
|
);
|
|
330
|
+
const displayState = workColumnState(items.length, totalItems, state);
|
|
326
331
|
return (
|
|
327
332
|
<article className={`operations-column is-${stage}`}>
|
|
328
333
|
<header>
|
|
@@ -371,9 +376,7 @@ function WorkColumn({
|
|
|
371
376
|
totalsByTask={totalsByTask}
|
|
372
377
|
/>
|
|
373
378
|
))}
|
|
374
|
-
{
|
|
375
|
-
<p className="operations-empty">{locale === "pt-BR" ? "Sem itens" : "No items"}</p>
|
|
376
|
-
) : null}
|
|
379
|
+
<WorkColumnState error={state?.error} locale={locale} state={displayState} />
|
|
377
380
|
{hasMore ? (
|
|
378
381
|
<div
|
|
379
382
|
aria-live="polite"
|
|
@@ -543,9 +546,8 @@ function WorkCard({
|
|
|
543
546
|
);
|
|
544
547
|
}
|
|
545
548
|
|
|
546
|
-
export
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
+
export { openWorkCardLabel } from "./work-card-label.js";
|
|
550
|
+
export { workColumnState } from "./work-column-state.js";
|
|
549
551
|
|
|
550
552
|
/** Replaces only visible-column slots, preserving the global order of all other work. */
|
|
551
553
|
export function mergeManualWorkOrder(
|
|
@@ -561,16 +563,6 @@ export function mergeManualWorkOrder(
|
|
|
561
563
|
);
|
|
562
564
|
}
|
|
563
565
|
|
|
564
|
-
export function filterWorkItems(items: readonly WorkItem[], query: string): WorkItem[] {
|
|
565
|
-
const normalized = query.trim().toLocaleLowerCase();
|
|
566
|
-
if (!normalized) return [...items];
|
|
567
|
-
return items.filter((item) =>
|
|
568
|
-
[item.row.id, item.row.title, item.kind].some((value) =>
|
|
569
|
-
value.toLocaleLowerCase().includes(normalized),
|
|
570
|
-
),
|
|
571
|
-
);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
566
|
function WorkColumnDialog({
|
|
575
567
|
items,
|
|
576
568
|
locale,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { OperationsLocale } from "./status-labels.js";
|
|
2
|
+
|
|
3
|
+
export function WorkColumnState({
|
|
4
|
+
state,
|
|
5
|
+
error,
|
|
6
|
+
locale,
|
|
7
|
+
}: {
|
|
8
|
+
state: "loading" | "empty" | "error" | "content";
|
|
9
|
+
error: string | null | undefined;
|
|
10
|
+
locale: OperationsLocale;
|
|
11
|
+
}) {
|
|
12
|
+
if (state === "loading")
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
aria-busy="true"
|
|
16
|
+
aria-label={locale === "pt-BR" ? "Carregando itens da coluna" : "Loading column items"}
|
|
17
|
+
className="operations-column-skeleton"
|
|
18
|
+
role="status"
|
|
19
|
+
>
|
|
20
|
+
<span />
|
|
21
|
+
<span />
|
|
22
|
+
<span />
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
if (state === "error")
|
|
26
|
+
return (
|
|
27
|
+
<p className="operations-empty" role="alert">
|
|
28
|
+
{error}
|
|
29
|
+
</p>
|
|
30
|
+
);
|
|
31
|
+
return state === "empty" ? (
|
|
32
|
+
<p className="operations-empty">{locale === "pt-BR" ? "Sem itens" : "No items"}</p>
|
|
33
|
+
) : null;
|
|
34
|
+
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
|
|
12
12
|
describe("formatOperationDuration", () => {
|
|
13
13
|
it("preserves unavailable and observed zero as different states", () => {
|
|
14
|
-
expect(formatOperationDuration(null, "pt-BR")).toBe("
|
|
14
|
+
expect(formatOperationDuration(null, "pt-BR")).toBe("0");
|
|
15
15
|
expect(formatOperationDuration(0, "pt-BR")).toBe("0 seg");
|
|
16
16
|
});
|
|
17
17
|
|
|
@@ -9,7 +9,7 @@ export interface OperationalTiming {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export function formatOperationDuration(value: number | null, locale: OperationsLocale): string {
|
|
12
|
-
if (value === null) return
|
|
12
|
+
if (value === null) return "0";
|
|
13
13
|
if (value === 0) return locale === "pt-BR" ? "0 seg" : "0 sec";
|
|
14
14
|
return formatDurationMs(value, locale);
|
|
15
15
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { formatExecutionAverageHint } from "./OperationsOverview.js";
|
|
3
|
+
|
|
4
|
+
it("keeps the known macro average when execution days are unavailable", () => {
|
|
5
|
+
expect(formatExecutionAverageHint(3_600_000, 3, 0, "pt-BR")).toBe("20 min / item");
|
|
6
|
+
expect(formatExecutionAverageHint(3_600_000, 3, 0, "en-US")).toBe("20 min / item");
|
|
7
|
+
expect(formatExecutionAverageHint(0, 3, 0, "pt-BR")).toBe(
|
|
8
|
+
"Sem tempo medido para calcular médias",
|
|
9
|
+
);
|
|
10
|
+
});
|
package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts
CHANGED
|
@@ -38,7 +38,7 @@ describe("Operations persisted aggregate display", () => {
|
|
|
38
38
|
expect(totals).toMatchObject({ duration_ms: null, tokens: 0, cost_brl: 0 });
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
it("preserves unavailable aggregate
|
|
41
|
+
it("preserves unavailable aggregate facts and opts overview cards into disclosed zero", () => {
|
|
42
42
|
const overview = ["OperationsOverview.tsx", "overview-metric-format.ts"]
|
|
43
43
|
.map((file) => readFileSync(new URL(file, import.meta.url), "utf8"))
|
|
44
44
|
.join("\n");
|
|
@@ -52,8 +52,9 @@ describe("Operations persisted aggregate display", () => {
|
|
|
52
52
|
expect(overview).toMatch(
|
|
53
53
|
/durationMs: totalDurationMetric,\s*tokens: totalTokensMetric,\s*costBrl: rateCost/,
|
|
54
54
|
);
|
|
55
|
-
expect(overview).toContain("
|
|
56
|
-
expect(overview).
|
|
55
|
+
expect(overview).toContain("overviewMetricStats");
|
|
56
|
+
expect(overview).toMatch(/populationCount === 0 \|\| displayUnmeasuredAsZero\s*\? "0"/);
|
|
57
|
+
expect(overview).toMatch(/unmeasuredZeroDescription\(\s*totalDurationMetric/);
|
|
57
58
|
expect(overview).not.toContain("allPhaseMetrics.tokens ?? 0");
|
|
58
59
|
expect(overview).not.toContain("executionMetrics.durationMs ?? 0");
|
|
59
60
|
});
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
+
import { createElement } from "react";
|
|
3
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
2
4
|
import { describe, expect, it } from "vitest";
|
|
3
5
|
import { readAppCompositionSource } from "../../../../apps/frontend/src/__tests__/app-composition-support.js";
|
|
4
|
-
import { resolveOperationsPeriodControl
|
|
6
|
+
import { resolveOperationsPeriodControl } from "./OperationsPage.js";
|
|
7
|
+
import { OperationsPageLoading } from "./OperationsPageOverview.js";
|
|
8
|
+
import { shouldRenderOperationsContent } from "./operations-content-visibility.js";
|
|
5
9
|
import { workListTypeOnViewChange } from "./operations-page-contract.js";
|
|
6
10
|
|
|
7
11
|
describe("overview period filter", () => {
|
|
12
|
+
it("renders independent KPI and panel skeletons without fake zeros or unavailable values", () => {
|
|
13
|
+
const html = renderToStaticMarkup(createElement(OperationsPageLoading, { locale: "pt-BR" }));
|
|
14
|
+
expect(html.match(/operations-skeleton-block/g)).toHaveLength(10);
|
|
15
|
+
expect(html).not.toContain("Indisponível");
|
|
16
|
+
expect(html).not.toContain(">0<");
|
|
17
|
+
expect(html).toContain('aria-busy="true"');
|
|
18
|
+
});
|
|
8
19
|
it("passes activity-filtered entities and Runs to every overview metric", () => {
|
|
9
20
|
const overview = readFileSync(new URL("OperationsPageOverview.tsx", import.meta.url), "utf8");
|
|
10
21
|
|
package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts
CHANGED
|
@@ -97,6 +97,7 @@ export interface OperationsPageProps {
|
|
|
97
97
|
/** Timestamp of the immutable projection supplied by the composition root. */
|
|
98
98
|
lastUpdatedAt?: string | null;
|
|
99
99
|
loading: boolean;
|
|
100
|
+
costLoading?: boolean | undefined;
|
|
100
101
|
onLoadingChange?: (loading: boolean) => void;
|
|
101
102
|
currency: "BRL" | "USD";
|
|
102
103
|
locale: OperationsLocale;
|