@zaip-ai/cli 3.7.0 → 4.0.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/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +6 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +22 -4
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/adapters.test.js +24 -0
- package/dist/services/adapters.test.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-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/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/sqlite-bootstrap.d.ts.map +1 -1
- package/dist/services/sqlite-bootstrap.js +9 -1
- package/dist/services/sqlite-bootstrap.js.map +1 -1
- 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 +90 -34
- package/templates/.agents/README.md +59 -32
- package/templates/.agents/config/agents/catalog.yaml +23 -23
- package/templates/.agents/config/agents/discovery.json +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-analyst.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-auditor.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-data-analyst.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-integrator.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +3 -3
- package/templates/.agents/config/clients/codex/agents/zaip-agent-refactoring-specialist.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-reviewer.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-security-auditor.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-writer.toml +2 -2
- package/templates/.agents/config/clients.yaml +1 -1
- package/templates/.agents/config/pricing/models.json +57 -1
- package/templates/.agents/config/project.yaml +21 -7
- package/templates/.agents/dashboard/.zaip-managed.json +195 -115
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-C5NgEcVh.js → CostCalculationGuidePage-f4ZGJRg3.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-BDQR0U4a.js → DashboardHelpDialog-DlN5EMmD.js} +249 -136
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-CGYcJ5EB.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-Ckxk_izu.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-jvdDfNKs.js → dashboard-localization-CF7B1Hjn.js} +90 -34
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-x8xxL9yW.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-CNOXIJHN.js → react-vendor-mHgsmxb6.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-CcpbpT1s.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/CostMonitorContent.tsx +2 -2
- 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 +173 -173
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +120 -120
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +173 -173
- 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/agent-catalog-settings.test.ts +15 -15
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +2 -2
- 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 +15 -23
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +1 -1
- package/templates/.agents/dashboard/tests/e2e/specs/performance-matrix-types.ts +15 -0
- package/templates/.agents/dashboard/tests/e2e/specs/performance-observability.ts +30 -0
- 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 +6 -6
- 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 +73 -64
- 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-adapters/SKILL.md +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/SKILL.md +5 -5
- package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +5 -3
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +40 -5
- 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 +54 -6
- 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 +5 -1
- package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +19 -15
- package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +13 -9
- 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 +40 -25
- package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +8 -8
- 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 +310 -218
- package/templates/tsconfig.base.json +22 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-OulA4CoX.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-j3aUYH5G.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CqfSgtk9.js +0 -2
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { CostMonitorProjection } from "@zaip-ai/dashboard-cost-monitor/contracts";
|
|
2
2
|
import type { CostCurrency, CostLocale } from "@zaip-ai/dashboard-cost-monitor/react";
|
|
3
3
|
import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contracts";
|
|
4
|
-
import * as React from "react";
|
|
5
4
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
6
5
|
import type { LoadingArea } from "./AppLoadingPanels.js";
|
|
7
6
|
import {
|
|
@@ -136,9 +135,9 @@ export function useDashboardAppModel() {
|
|
|
136
135
|
const [fxRate, setFxRate] = useState<FxRate | null>(null);
|
|
137
136
|
const [pathname, setPathname] = useState(window.location.pathname);
|
|
138
137
|
const [operationsLoading, setOperationsLoading] = useState(true);
|
|
139
|
-
const [, setOperationsSurfaceLoading] = useState(false);
|
|
138
|
+
const [operationsSurfaceLoading, setOperationsSurfaceLoading] = useState(false);
|
|
140
139
|
const [, setCostSurfaceLoading] = useState(false);
|
|
141
|
-
const [
|
|
140
|
+
const [, setPeriodTransitionPending] = useState(false);
|
|
142
141
|
const [loadingArea, setLoadingArea] = useState<LoadingArea | null>("operations");
|
|
143
142
|
const [failedArea, setFailedArea] = useState<LoadingArea | null>(null);
|
|
144
143
|
const [refreshDialog, setRefreshDialog] = useState<
|
|
@@ -307,8 +306,8 @@ export function useDashboardAppModel() {
|
|
|
307
306
|
setLastUpdatedAt(projection.summary.latest_token_collected_at ?? null);
|
|
308
307
|
}
|
|
309
308
|
} else if (refreshProjection) {
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
const snapshot: Awaited<ReturnType<typeof api.refreshProjection>> =
|
|
310
|
+
await api.refreshProjection(currency, period);
|
|
312
311
|
if (!isCurrentRequest()) return false;
|
|
313
312
|
setOperations(snapshot.operations);
|
|
314
313
|
quickOverviewMetricsRef.current = snapshot.operations.summary.overview_metrics;
|
|
@@ -582,16 +581,11 @@ export function useDashboardAppModel() {
|
|
|
582
581
|
void loadCostSummary();
|
|
583
582
|
}, [costs?.currency, currency, loadCostSummary]);
|
|
584
583
|
|
|
585
|
-
//
|
|
586
|
-
//
|
|
587
|
-
//
|
|
588
|
-
// today's Operations range. The request itself remains deliberately
|
|
589
|
-
// unbounded. The in-flight guard prevents duplicate requests.
|
|
584
|
+
// Hydrate factual cost independently after the compact Operations fold. The
|
|
585
|
+
// cost cards retain skeletons while this narrower request is in flight;
|
|
586
|
+
// unrelated metrics and the board can render without waiting for it.
|
|
590
587
|
useEffect(() => {
|
|
591
|
-
if (
|
|
592
|
-
(dashboardView !== "cost-monitor" && operationsPeriod.preset !== "all") ||
|
|
593
|
-
costSummaryAbortRef.current !== null
|
|
594
|
-
)
|
|
588
|
+
if (operations === null || failedArea === "costs" || costSummaryAbortRef.current !== null)
|
|
595
589
|
return;
|
|
596
590
|
if (
|
|
597
591
|
shouldLoadCostSummary({
|
|
@@ -601,7 +595,7 @@ export function useDashboardAppModel() {
|
|
|
601
595
|
})
|
|
602
596
|
)
|
|
603
597
|
void loadCostSummary();
|
|
604
|
-
}, [costs?.currency, currency,
|
|
598
|
+
}, [costs?.currency, currency, failedArea, loadCostSummary, operations]);
|
|
605
599
|
|
|
606
600
|
const selectDashboardView = createDashboardViewSelector({
|
|
607
601
|
setDashboardView,
|
|
@@ -648,12 +642,9 @@ export function useDashboardAppModel() {
|
|
|
648
642
|
setFxRate,
|
|
649
643
|
setPricing,
|
|
650
644
|
);
|
|
651
|
-
//
|
|
652
|
-
//
|
|
653
|
-
//
|
|
654
|
-
// The stale snapshot is useful only while the initial screen still waits
|
|
655
|
-
// for data. Once Operations has arrived, the normal dashboard is the
|
|
656
|
-
// clearest confirmation that it opened; do not leave a duplicate toast.
|
|
645
|
+
// Operations uses independent skeleton cards and a loading toast while a
|
|
646
|
+
// period changes. Only the cross-currency first fold still needs the global
|
|
647
|
+
// gate to avoid formatting BRL values as USD before Cost Monitor responds.
|
|
657
648
|
return {
|
|
658
649
|
loadMoreBoard,
|
|
659
650
|
overviewStatusPageKey,
|
|
@@ -671,8 +662,7 @@ export function useDashboardAppModel() {
|
|
|
671
662
|
setOperationsLoading,
|
|
672
663
|
operations,
|
|
673
664
|
error,
|
|
674
|
-
globalLoadingPending:
|
|
675
|
-
periodTransitionPending || (currency === "USD" && costs?.currency !== currency),
|
|
665
|
+
globalLoadingPending: currency === "USD" && costs?.currency !== currency,
|
|
676
666
|
costLocale,
|
|
677
667
|
refresh: async () => {
|
|
678
668
|
await refresh();
|
|
@@ -727,6 +717,7 @@ export function useDashboardAppModel() {
|
|
|
727
717
|
factualCostFact,
|
|
728
718
|
factualCostPeriods,
|
|
729
719
|
setOperationsSurfaceLoading,
|
|
720
|
+
operationsSurfaceLoading,
|
|
730
721
|
currentCostByRun,
|
|
731
722
|
loadOperationsEntityPage,
|
|
732
723
|
loadOperationsLifecyclePage,
|
package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts
CHANGED
|
@@ -63,8 +63,8 @@ describe("CompactLifecycleCostTable filtered subtotal", () => {
|
|
|
63
63
|
};
|
|
64
64
|
const render = (key: string) =>
|
|
65
65
|
table!.props.columns.find((column) => column.key === key)?.render?.(unknownRow);
|
|
66
|
-
expect(render("duration")).toBe("
|
|
67
|
-
expect(render("cost")).toBe("
|
|
66
|
+
expect(render("duration")).toBe("0");
|
|
67
|
+
expect(render("cost")).toBe("0");
|
|
68
68
|
expect(render("tokens")).toBe("15");
|
|
69
69
|
const partialRow = {
|
|
70
70
|
metrics: {
|
|
@@ -113,7 +113,7 @@ describe("CompactLifecycleCostTable filtered subtotal", () => {
|
|
|
113
113
|
table!.props.columns.find((column) => column.key === key)?.footer;
|
|
114
114
|
expect(footer("runs")).toBe("0");
|
|
115
115
|
expect(footer("tokens")).toBe("0");
|
|
116
|
-
expect(footer("duration")).toBe("
|
|
116
|
+
expect(footer("duration")).toBe("0");
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
it("does not render a subtotal row when all lifecycle metrics are unavailable", () => {
|
package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx
CHANGED
|
@@ -82,8 +82,7 @@ export function CompactLifecycleCostTable({
|
|
|
82
82
|
onOpenTrace?: (id: string) => void;
|
|
83
83
|
}) {
|
|
84
84
|
const metric = (value: KnownMetric, format: (known: number) => string) => {
|
|
85
|
-
if (value.known_sum === 0 && !value.complete && value.coverage_ratio === 0)
|
|
86
|
-
return locale === "pt-BR" ? "Indisponível" : "Unavailable";
|
|
85
|
+
if (value.known_sum === 0 && !value.complete && value.coverage_ratio === 0) return "0";
|
|
87
86
|
const formatted = format(value.known_sum ?? 0);
|
|
88
87
|
return value.complete
|
|
89
88
|
? formatted
|
|
@@ -91,7 +90,7 @@ export function CompactLifecycleCostTable({
|
|
|
91
90
|
};
|
|
92
91
|
const durationMetric = (row: CompactLifecycleCostRow) => {
|
|
93
92
|
const effective = compactLifecycleDurationMs(row);
|
|
94
|
-
if (effective === null) return
|
|
93
|
+
if (effective === null) return "0";
|
|
95
94
|
return metric(row.metrics.duration, (value) =>
|
|
96
95
|
value === 0 ? "0" : formatDurationMs(value, locale),
|
|
97
96
|
);
|
package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionTable.tsx
CHANGED
|
@@ -40,7 +40,7 @@ function formatCount(value: number | null, locale: CostLocale): string {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function formatDuration(value: number | null, locale: CostLocale): string {
|
|
43
|
-
if (value === null) return
|
|
43
|
+
if (value === null) return "0";
|
|
44
44
|
return value === 0 ? "0" : formatDurationMs(value, locale);
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -49,11 +49,7 @@ function formatBrlCurrency(value: number | null, locale: CostLocale): string {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function formatTokens(value: number | null, locale: CostLocale): string {
|
|
52
|
-
return value
|
|
53
|
-
? locale === "pt-BR"
|
|
54
|
-
? "Indisponível"
|
|
55
|
-
: "Unavailable"
|
|
56
|
-
: formatCompactNumber(value, locale);
|
|
52
|
+
return formatCompactNumber(value, locale);
|
|
57
53
|
}
|
|
58
54
|
|
|
59
55
|
function partialMetric(
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { CostGroupsTable, formatAuditableCurrency } from "./CostTables.js";
|
|
4
|
+
|
|
5
|
+
const unavailableGroup = {
|
|
6
|
+
key: "unknown",
|
|
7
|
+
label: "Sem telemetria",
|
|
8
|
+
latest_started_at: "2026-07-24T20:00:00.000Z",
|
|
9
|
+
run_count: 2,
|
|
10
|
+
task_count: 1,
|
|
11
|
+
prd_count: 0,
|
|
12
|
+
spec_count: 0,
|
|
13
|
+
evidence_count: 0,
|
|
14
|
+
test_count: 0,
|
|
15
|
+
event_count: 2,
|
|
16
|
+
total_tokens: null,
|
|
17
|
+
estimated_usd: null,
|
|
18
|
+
estimated_brl: null,
|
|
19
|
+
duration_ms: null,
|
|
20
|
+
duration: { known_sum: 0, unknown: 2, complete: false, coverage_ratio: 0 },
|
|
21
|
+
coverage: { events: 2, tokens: 0, usd: 0, brl: 0 },
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
describe("period group values", () => {
|
|
25
|
+
it("discloses presentation zero without changing null sorting", () => {
|
|
26
|
+
const table = CostGroupsTable({
|
|
27
|
+
rows: [unavailableGroup],
|
|
28
|
+
currency: "BRL",
|
|
29
|
+
locale: "pt-BR",
|
|
30
|
+
period: "daily",
|
|
31
|
+
});
|
|
32
|
+
const columns = table.props.columns as Array<{
|
|
33
|
+
key: string;
|
|
34
|
+
render: (row: typeof unavailableGroup) => string | ReactElement;
|
|
35
|
+
sortValue?: (row: typeof unavailableGroup) => unknown;
|
|
36
|
+
footer?: ReactElement<{ "aria-label"?: string }>;
|
|
37
|
+
}>;
|
|
38
|
+
const column = (key: string) => columns.find((candidate) => candidate.key === key)!;
|
|
39
|
+
const duration = column("duration").render(unavailableGroup) as ReactElement<{
|
|
40
|
+
title: string;
|
|
41
|
+
children: string;
|
|
42
|
+
}>;
|
|
43
|
+
const tokens = column("tokens").render(unavailableGroup) as ReactElement<{
|
|
44
|
+
title: string;
|
|
45
|
+
children: string;
|
|
46
|
+
}>;
|
|
47
|
+
const cost = column("cost").render(unavailableGroup) as ReactElement<{
|
|
48
|
+
title: string;
|
|
49
|
+
children: string;
|
|
50
|
+
}>;
|
|
51
|
+
expect(duration.props.title).toBe(
|
|
52
|
+
"Zero exibido por falta de medição; não é um valor observado.",
|
|
53
|
+
);
|
|
54
|
+
expect([duration.props.children, tokens.props.children, cost.props.children]).toEqual([
|
|
55
|
+
"0",
|
|
56
|
+
"0",
|
|
57
|
+
formatAuditableCurrency(0, "BRL", "pt-BR"),
|
|
58
|
+
]);
|
|
59
|
+
expect(
|
|
60
|
+
[column("duration"), column("tokens"), column("cost")].map((entry) =>
|
|
61
|
+
entry.sortValue?.(unavailableGroup),
|
|
62
|
+
),
|
|
63
|
+
).toEqual([null, null, null]);
|
|
64
|
+
expect(column("duration").footer?.props["aria-label"]).not.toContain("Indisponível");
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { DataTable } from "@zaip-ai/dashboard-ui";
|
|
2
|
-
import type { CostGroupRow
|
|
2
|
+
import type { CostGroupRow } from "../contracts.js";
|
|
3
3
|
import { MoreVerticalIcon } from "./CostTableIcons.js";
|
|
4
4
|
import { costPeriodHeading } from "./CostTables.js";
|
|
5
|
+
import { costGroupConversationCount, costGroupPageTotals } from "./cost-group-page-totals.js";
|
|
6
|
+
import { createCostGroupPeriodValues } from "./cost-group-period-values.js";
|
|
5
7
|
import type { CostCurrency, CostLocale } from "./cost-monitor-copy.js";
|
|
6
|
-
import { localizedDescription
|
|
8
|
+
import { localizedDescription } from "./cost-table-metrics.js";
|
|
7
9
|
import {
|
|
8
10
|
costGroupsScrollLabel,
|
|
9
11
|
costPeriodTotalAriaLabel,
|
|
@@ -47,8 +49,6 @@ export {
|
|
|
47
49
|
import {
|
|
48
50
|
displayCostGroupLabel,
|
|
49
51
|
formatAuditableCompactNumber,
|
|
50
|
-
formatAuditableCurrency,
|
|
51
|
-
formatDurationCoverage,
|
|
52
52
|
formatFactualCount,
|
|
53
53
|
hasKnownDuration,
|
|
54
54
|
sortCostValue,
|
|
@@ -102,25 +102,10 @@ export function CostGroupsTable({
|
|
|
102
102
|
showAgentIdentity || showModelLifecycleDetails ? (value ?? 0) : value,
|
|
103
103
|
locale,
|
|
104
104
|
);
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
(row as { conversation_count?: number | null }).conversation_count ?? null;
|
|
110
|
-
const pageTotals = {
|
|
111
|
-
runs: rows.reduce((sum, row) => sum + row.run_count, 0),
|
|
112
|
-
tasks: sumNumbers(rows.map((row) => row.task_count)),
|
|
113
|
-
prds: sumNumbers(rows.map((row) => row.prd_count)),
|
|
114
|
-
specs: sumNumbers(rows.map((row) => row.spec_count)),
|
|
115
|
-
evidences: sumNumbers(rows.map((row) => row.evidence_count)),
|
|
116
|
-
tests: sumNumbers(rows.map((row) => row.test_count)),
|
|
117
|
-
conversations: sumNumbers(rows.map(conversationCount)),
|
|
118
|
-
durationKnownMs: rows.reduce((sum, row) => sum + row.duration.known_sum, 0),
|
|
119
|
-
durationPartial: rows.some((row) => !row.duration.complete),
|
|
120
|
-
tokens: sumNumbers(rows.map((row) => row.total_tokens)),
|
|
121
|
-
usd: sumNumbers(rows.map((row) => row.estimated_usd)),
|
|
122
|
-
brl: sumNumbers(rows.map((row) => row.estimated_brl)),
|
|
123
|
-
};
|
|
105
|
+
const periodValues = createCostGroupPeriodValues(currency, locale, period);
|
|
106
|
+
const periodDescription =
|
|
107
|
+
periodValues.description === undefined ? {} : { description: periodValues.description };
|
|
108
|
+
const pageTotals = costGroupPageTotals(rows);
|
|
124
109
|
const totals =
|
|
125
110
|
suppliedTotals === undefined
|
|
126
111
|
? pageTotals
|
|
@@ -131,14 +116,14 @@ export function CostGroupsTable({
|
|
|
131
116
|
specs: suppliedTotals.spec_count,
|
|
132
117
|
evidences: suppliedTotals.evidence_count,
|
|
133
118
|
tests: suppliedTotals.test_count,
|
|
134
|
-
conversations:
|
|
119
|
+
conversations: costGroupConversationCount(suppliedTotals) ?? pageTotals.conversations,
|
|
135
120
|
durationKnownMs: suppliedTotals.duration.known_sum,
|
|
136
121
|
durationPartial: !suppliedTotals.duration.complete,
|
|
137
122
|
tokens: suppliedTotals.total_tokens,
|
|
138
123
|
usd: suppliedTotals.estimated_usd,
|
|
139
124
|
brl: suppliedTotals.estimated_brl,
|
|
140
125
|
};
|
|
141
|
-
const totalDurationDisplay =
|
|
126
|
+
const totalDurationDisplay = periodValues.duration(
|
|
142
127
|
suppliedTotals?.duration ?? {
|
|
143
128
|
known_sum: totals.durationKnownMs,
|
|
144
129
|
unknown: totals.durationPartial ? 1 : 0,
|
|
@@ -152,7 +137,7 @@ export function CostGroupsTable({
|
|
|
152
137
|
showModelLifecycleDetails ? (totals.tokens ?? 0) : totals.tokens,
|
|
153
138
|
locale,
|
|
154
139
|
);
|
|
155
|
-
const totalCostDisplay =
|
|
140
|
+
const totalCostDisplay = periodValues.currency(currency === "BRL" ? totals.brl : totals.usd);
|
|
156
141
|
const totalAriaLabel = costPeriodTotalAriaLabel({
|
|
157
142
|
locale,
|
|
158
143
|
duration: totalDurationDisplay,
|
|
@@ -294,8 +279,8 @@ export function CostGroupsTable({
|
|
|
294
279
|
{
|
|
295
280
|
key: "conversations",
|
|
296
281
|
label: "Conversations",
|
|
297
|
-
render: (row: CostGroupRow) => displayCount(
|
|
298
|
-
sortValue: (row: CostGroupRow) =>
|
|
282
|
+
render: (row: CostGroupRow) => displayCount(costGroupConversationCount(row)),
|
|
283
|
+
sortValue: (row: CostGroupRow) => costGroupConversationCount(row) ?? 0,
|
|
299
284
|
align: "right" as const,
|
|
300
285
|
footer: displayCount(totals.conversations),
|
|
301
286
|
description: localizedDescription(
|
|
@@ -355,7 +340,10 @@ export function CostGroupsTable({
|
|
|
355
340
|
{
|
|
356
341
|
key: "duration",
|
|
357
342
|
label: "Tempo",
|
|
358
|
-
render: (row) =>
|
|
343
|
+
render: (row) =>
|
|
344
|
+
period !== undefined && !hasKnownDuration(row.duration)
|
|
345
|
+
? periodValues.disclose("0", true)
|
|
346
|
+
: periodValues.duration(row.duration),
|
|
359
347
|
sortValue: (row) =>
|
|
360
348
|
hasKnownDuration(row.duration)
|
|
361
349
|
? row.duration.known_sum
|
|
@@ -364,19 +352,23 @@ export function CostGroupsTable({
|
|
|
364
352
|
: null,
|
|
365
353
|
align: "right",
|
|
366
354
|
footer: <output aria-label={totalAriaLabel}>{totalDurationDisplay}</output>,
|
|
355
|
+
...periodDescription,
|
|
367
356
|
},
|
|
368
357
|
{
|
|
369
358
|
key: "tokens",
|
|
370
359
|
label: "Tokens",
|
|
371
|
-
render: (row) =>
|
|
372
|
-
formatAuditableCompactNumber(
|
|
360
|
+
render: (row) => {
|
|
361
|
+
const displayed = formatAuditableCompactNumber(
|
|
373
362
|
showModelLifecycleDetails ? (row.total_tokens ?? 0) : row.total_tokens,
|
|
374
363
|
locale,
|
|
375
|
-
)
|
|
364
|
+
);
|
|
365
|
+
return periodValues.disclose(displayed, row.total_tokens === null);
|
|
366
|
+
},
|
|
376
367
|
sortValue: (row) =>
|
|
377
368
|
showModelLifecycleDetails ? (row.total_tokens ?? 0) : row.total_tokens,
|
|
378
369
|
align: "right",
|
|
379
370
|
footer: <output aria-label={totalAriaLabel}>{totalTokensDisplay}</output>,
|
|
371
|
+
...periodDescription,
|
|
380
372
|
},
|
|
381
373
|
{
|
|
382
374
|
key: "cost",
|
|
@@ -392,14 +384,17 @@ export function CostGroupsTable({
|
|
|
392
384
|
: locale === "pt-BR"
|
|
393
385
|
? "Custos"
|
|
394
386
|
: "Costs",
|
|
395
|
-
render: (row) =>
|
|
396
|
-
|
|
387
|
+
render: (row) => {
|
|
388
|
+
const observed = currency === "BRL" ? row.estimated_brl : row.estimated_usd;
|
|
389
|
+
return periodValues.disclose(periodValues.currency(observed), observed === null);
|
|
390
|
+
},
|
|
397
391
|
sortValue: (row) =>
|
|
398
392
|
showModelLifecycleDetails
|
|
399
393
|
? (sortCostValue(currency, row.estimated_brl, row.estimated_usd) ?? 0)
|
|
400
394
|
: sortCostValue(currency, row.estimated_brl, row.estimated_usd),
|
|
401
395
|
align: "right",
|
|
402
396
|
footer: <output aria-label={totalAriaLabel}>{totalCostDisplay}</output>,
|
|
397
|
+
...periodDescription,
|
|
403
398
|
},
|
|
404
399
|
...(onOpenTrace
|
|
405
400
|
? [
|
|
@@ -264,7 +264,7 @@ export function CostMonitorContent({
|
|
|
264
264
|
) : null}
|
|
265
265
|
{(["providers", "agents", "models"] as const).map((key) =>
|
|
266
266
|
view === key && !dimensionalDetailPending && !detailLoading && detailError === null ? (
|
|
267
|
-
|
|
267
|
+
<div key={key}>
|
|
268
268
|
<CostGroupsTable
|
|
269
269
|
currency={currency}
|
|
270
270
|
key={key}
|
|
@@ -294,7 +294,7 @@ export function CostMonitorContent({
|
|
|
294
294
|
: {})}
|
|
295
295
|
/>
|
|
296
296
|
{groupPager}
|
|
297
|
-
|
|
297
|
+
</div>
|
|
298
298
|
) : null,
|
|
299
299
|
)}
|
|
300
300
|
{view === "daily" || view === "monthly" || view === "annual" ? (
|
package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.embedded.test.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
describe("embedded Cost Monitor", () => {
|
|
5
|
+
it("keeps global filters as the sole embedded filter surface", () => {
|
|
6
|
+
const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
|
|
7
|
+
expect(page).not.toContain('className="cost-embedded-filters"');
|
|
8
|
+
expect(page).toContain("<CostMonitorContent");
|
|
9
|
+
expect(page).toContain("<CostFilters");
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -83,7 +83,7 @@ export {
|
|
|
83
83
|
export function CostMonitorPage({
|
|
84
84
|
capabilityNavigation,
|
|
85
85
|
data,
|
|
86
|
-
dashboardTitle = "Dashboard
|
|
86
|
+
dashboardTitle = "Dashboard ZAIP AIOS",
|
|
87
87
|
embedded = false,
|
|
88
88
|
globalFilters,
|
|
89
89
|
lastUpdatedAt,
|
|
@@ -708,18 +708,6 @@ export function CostMonitorPage({
|
|
|
708
708
|
</div>
|
|
709
709
|
) : null}
|
|
710
710
|
</div>{" "}
|
|
711
|
-
{embedded && view !== "developers" ? (
|
|
712
|
-
<details className="cost-embedded-filters">
|
|
713
|
-
<summary>{locale === "pt-BR" ? "Filtros de custos" : "Cost filters"}</summary>
|
|
714
|
-
<CostFilters
|
|
715
|
-
available={data.filters_available}
|
|
716
|
-
hideQuery
|
|
717
|
-
locale={locale}
|
|
718
|
-
onChange={setFilters}
|
|
719
|
-
value={filters}
|
|
720
|
-
/>
|
|
721
|
-
</details>
|
|
722
|
-
) : null}
|
|
723
711
|
{/* CostMonitorContent owns `view === "models" && useAggregateGroups ? (` and `rows={groups.models}`. */}{" "}
|
|
724
712
|
<CostMonitorContent
|
|
725
713
|
canonicalDurationTotal={canonicalDurationTotal}
|
package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostPeriodAverageCards.test.tsx
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { CostPeriodAverageCards } from "./CostPeriodAverageCards.js";
|
|
4
|
+
|
|
5
|
+
describe("CostPeriodAverageCards", () => {
|
|
6
|
+
const props = { currency: "BRL", locale: "pt-BR", period: "daily", rows: [] } as const;
|
|
7
|
+
|
|
8
|
+
it("shows zero for loaded missing numeric averages without changing the source", () => {
|
|
9
|
+
const element = CostPeriodAverageCards({ ...props, average: null }) as ReactElement<{
|
|
10
|
+
metrics: readonly { value: string }[];
|
|
11
|
+
}>;
|
|
12
|
+
expect(element.props.metrics.map((metric) => metric.value)).toEqual(Array(6).fill("0"));
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("keeps loading distinct from a loaded zero", () => {
|
|
16
|
+
const element = CostPeriodAverageCards({ ...props, loading: true }) as ReactElement<{
|
|
17
|
+
role: string;
|
|
18
|
+
children: string;
|
|
19
|
+
}>;
|
|
20
|
+
expect(element.props.role).toBe("status");
|
|
21
|
+
expect(element.props.children).toContain("Carregando médias");
|
|
22
|
+
});
|
|
23
|
+
});
|
package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostPeriodAverageCards.tsx
CHANGED
|
@@ -39,7 +39,8 @@ export function CostPeriodAverageCards({
|
|
|
39
39
|
tokens: null,
|
|
40
40
|
cost: null,
|
|
41
41
|
});
|
|
42
|
-
|
|
42
|
+
// A loaded missing metric is presented as zero; the API retains null/coverage.
|
|
43
|
+
const unavailable = "0";
|
|
43
44
|
return (
|
|
44
45
|
<PeriodAverageCards
|
|
45
46
|
ariaLabel={periodAverageAriaLabel(period, locale)}
|
|
@@ -22,11 +22,7 @@ export function formatAuditableNumber(value: number | null, locale: CostLocale):
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function formatFactualCount(value: number | null, locale: CostLocale): string {
|
|
25
|
-
return value
|
|
26
|
-
? locale === "pt-BR"
|
|
27
|
-
? "Indisponível"
|
|
28
|
-
: "Unavailable"
|
|
29
|
-
: formatAuditableNumber(value, locale);
|
|
25
|
+
return formatAuditableNumber(value, locale);
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
export function formatAuditableCompactNumber(value: number | null, locale: CostLocale): string {
|
|
@@ -38,12 +34,12 @@ export function formatAuditableCurrency(
|
|
|
38
34
|
currency: CostCurrency,
|
|
39
35
|
locale: CostLocale,
|
|
40
36
|
): string {
|
|
41
|
-
if (value === null) return
|
|
37
|
+
if (value === null) return "0";
|
|
42
38
|
return formatCurrency(value, currency, locale);
|
|
43
39
|
}
|
|
44
40
|
|
|
45
41
|
export function formatAuditableDuration(value: number | null, locale: CostLocale): string {
|
|
46
|
-
if (value === null) return
|
|
42
|
+
if (value === null) return "0";
|
|
47
43
|
return value === 0 ? "0" : formatDurationMs(value, locale);
|
|
48
44
|
}
|
|
49
45
|
|
|
@@ -71,8 +67,8 @@ export const formatInvocationMultiplierPair = (
|
|
|
71
67
|
export function invocationMetricDescription(locale: CostLocale, metric: string): string {
|
|
72
68
|
const source =
|
|
73
69
|
locale === "pt-BR"
|
|
74
|
-
? "Valor da projeção SQLite/API desta Invocação de Agente.
|
|
75
|
-
: "Value from this Agent Invocation's SQLite/API projection. A
|
|
70
|
+
? "Valor da projeção SQLite/API desta Invocação de Agente. O zero exibido para um fato não medido não altera o valor canônico nulo."
|
|
71
|
+
: "Value from this Agent Invocation's SQLite/API projection. A displayed zero for an unmeasured fact does not change its canonical null value.";
|
|
76
72
|
const details: Record<string, readonly [string, string]> = {
|
|
77
73
|
duration: [
|
|
78
74
|
"Tempo factual da invocação, quando capturado ou reconciliado.",
|
|
@@ -171,8 +167,7 @@ export function invocationMetricDescription(locale: CostLocale, metric: string):
|
|
|
171
167
|
}
|
|
172
168
|
|
|
173
169
|
export function formatDurationCoverage(value: DurationCoverage, locale: CostLocale): string {
|
|
174
|
-
if (value.known_sum <= 0 && !value.complete)
|
|
175
|
-
return locale === "pt-BR" ? "Indisponível" : "Unavailable";
|
|
170
|
+
if (value.known_sum <= 0 && !value.complete) return "0";
|
|
176
171
|
return value.known_sum <= 0 ? "0" : formatDurationMs(value.known_sum, locale);
|
|
177
172
|
}
|
|
178
173
|
|
|
@@ -176,10 +176,10 @@ describe("grouped cost availability", () => {
|
|
|
176
176
|
...model,
|
|
177
177
|
duration: { known_sum: 0, unknown: 1, complete: false, coverage_ratio: 0 },
|
|
178
178
|
}),
|
|
179
|
-
).toBe("
|
|
179
|
+
).toBe("0");
|
|
180
180
|
expect(
|
|
181
181
|
columns.find((column) => column.key === "cost")?.render?.({ ...model, estimated_brl: null }),
|
|
182
|
-
).toBe("
|
|
182
|
+
).toBe("0");
|
|
183
183
|
expect(
|
|
184
184
|
columns
|
|
185
185
|
.find((column) => column.key === "tokens")
|
|
@@ -324,14 +324,14 @@ describe("grouped cost availability", () => {
|
|
|
324
324
|
expect(column(key)?.description).toContain("projeção SQLite/API");
|
|
325
325
|
expect(column(key)?.hidden).not.toBe(true);
|
|
326
326
|
}
|
|
327
|
-
expect(column("duration")?.render?.(unavailableRun)).toBe("
|
|
327
|
+
expect(column("duration")?.render?.(unavailableRun)).toBe("0");
|
|
328
328
|
expect(column("inputTokens")?.render?.(unavailableRun)).toBe("0");
|
|
329
329
|
expect(column("inputRate")?.render?.(unavailableRun)).toBe("0,00");
|
|
330
|
-
expect(column("contextMultiplier")?.render?.(unavailableRun)).toBe("
|
|
330
|
+
expect(column("contextMultiplier")?.render?.(unavailableRun)).toBe("0");
|
|
331
331
|
expect(column("inputCost")?.render?.(unavailableRun)).toContain("0,00");
|
|
332
332
|
expect(column("fxRate")?.render?.(unavailableRun)).toBe("R$ 0,00");
|
|
333
|
-
expect(column("recordedBrl")?.render?.(unavailableRun)).toBe("
|
|
334
|
-
expect(column("cost")?.render?.(unavailableRun)).toBe("
|
|
333
|
+
expect(column("recordedBrl")?.render?.(unavailableRun)).toBe("0");
|
|
334
|
+
expect(column("cost")?.render?.(unavailableRun)).toBe("0");
|
|
335
335
|
});
|
|
336
336
|
it("provides a clear scroll label for the detailed Runs table", () => {
|
|
337
337
|
expect(costRunsScrollLabel("pt-BR")).toBe(
|
|
@@ -107,11 +107,11 @@ describe("monetary formatting", () => {
|
|
|
107
107
|
expect(ratio(106.73, 19.583444)).toBeCloseTo(5.45, 2);
|
|
108
108
|
expect(ratio(100, 0)).toBeNull();
|
|
109
109
|
});
|
|
110
|
-
it("
|
|
110
|
+
it("shows zero for unmeasured metrics without changing their source values", () => {
|
|
111
111
|
expect(formatRate(null, "pt-BR")).toBe("0,00");
|
|
112
112
|
expect(formatUsd(null, "en-US")).toContain("0.00");
|
|
113
|
-
expect(formatAuditableCurrency(null, "BRL", "pt-BR")).toBe("
|
|
114
|
-
expect(formatAuditableDuration(null, "pt-BR")).toBe("
|
|
113
|
+
expect(formatAuditableCurrency(null, "BRL", "pt-BR")).toBe("0");
|
|
114
|
+
expect(formatAuditableDuration(null, "pt-BR")).toBe("0");
|
|
115
115
|
expect(formatAuditableCompactNumber(null, "pt-BR")).toBe("0");
|
|
116
116
|
});
|
|
117
117
|
});
|
|
@@ -134,7 +134,7 @@ describe("duration coverage", () => {
|
|
|
134
134
|
{ known_sum: 0, unknown: 2, complete: false, coverage_ratio: 0 },
|
|
135
135
|
"pt-BR",
|
|
136
136
|
),
|
|
137
|
-
).toBe("
|
|
137
|
+
).toBe("0");
|
|
138
138
|
});
|
|
139
139
|
it("does not treat financial tokens as elapsed-time evidence", () => {
|
|
140
140
|
expect(
|
|
@@ -242,9 +242,7 @@ describe("grouped cost availability", () => {
|
|
|
242
242
|
]);
|
|
243
243
|
expect(columns.find((column) => column.key === "tests")?.render(unavailable)).toBe("—");
|
|
244
244
|
expect(columns.find((column) => column.key === "evidences")?.render(unavailable)).toBe("—");
|
|
245
|
-
expect(columns.find((column) => column.key === "duration")?.render(unavailable)).toBe(
|
|
246
|
-
"Indisponível",
|
|
247
|
-
);
|
|
245
|
+
expect(columns.find((column) => column.key === "duration")?.render(unavailable)).toBe("0");
|
|
248
246
|
});
|
|
249
247
|
it("marks incomplete aggregates in place without adding source or coverage columns", () => {
|
|
250
248
|
const partial = {
|
|
@@ -349,13 +347,13 @@ describe("grouped cost availability", () => {
|
|
|
349
347
|
}>;
|
|
350
348
|
const column = (key: string) => columns.find((candidate) => candidate.key === key);
|
|
351
349
|
expect(table.props.scrollLabel).toBe(costGroupsScrollLabel("pt-BR"));
|
|
352
|
-
expect(column("duration")?.render(unavailableGroup)).toBe("
|
|
350
|
+
expect(column("duration")?.render(unavailableGroup)).toBe("0");
|
|
353
351
|
expect(column("tokens")?.render(unavailableGroup)).toBe("0");
|
|
354
|
-
expect(column("cost")?.render(unavailableGroup)).toBe("
|
|
352
|
+
expect(column("cost")?.render(unavailableGroup)).toBe("0");
|
|
355
353
|
expect(column("duration")?.sortValue?.(unavailableGroup)).toBeNull();
|
|
356
354
|
expect(column("tokens")?.sortValue?.(unavailableGroup)).toBeNull();
|
|
357
355
|
expect(column("cost")?.sortValue?.(unavailableGroup)).toBeNull();
|
|
358
|
-
const totalSummary = "Total geral — Tempo:
|
|
356
|
+
const totalSummary = "Total geral — Tempo: 0; Tokens: 0; BRL: 0";
|
|
359
357
|
const footerLabel = (key: string) => {
|
|
360
358
|
const footer = column(key)?.footer as { props?: { "aria-label"?: string } } | undefined;
|
|
361
359
|
return footer?.props?.["aria-label"];
|
|
@@ -455,7 +453,7 @@ describe("grouped cost availability", () => {
|
|
|
455
453
|
for (const key of ["tasks", "prds", "specs", "tests", "evidences", "tokens"]) {
|
|
456
454
|
expect(columns.find((c) => c.key === key)?.render?.(missing)).toBe("0");
|
|
457
455
|
}
|
|
458
|
-
expect(columns.find((c) => c.key === "duration")?.render?.(missing)).toBe("
|
|
459
|
-
expect(columns.find((c) => c.key === "cost")?.render?.(missing)).toBe("
|
|
456
|
+
expect(columns.find((c) => c.key === "duration")?.render?.(missing)).toBe("0");
|
|
457
|
+
expect(columns.find((c) => c.key === "cost")?.render?.(missing)).toBe("0");
|
|
460
458
|
});
|
|
461
459
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CostGroupRow } from "../contracts.js";
|
|
2
|
+
import { sumNumbers } from "./cost-table-metrics.js";
|
|
3
|
+
|
|
4
|
+
export function costGroupConversationCount(row: unknown): number | null {
|
|
5
|
+
return (row as { conversation_count?: number | null }).conversation_count ?? null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function costGroupPageTotals(rows: readonly CostGroupRow[]) {
|
|
9
|
+
return {
|
|
10
|
+
runs: rows.reduce((sum, row) => sum + row.run_count, 0),
|
|
11
|
+
tasks: sumNumbers(rows.map((row) => row.task_count)),
|
|
12
|
+
prds: sumNumbers(rows.map((row) => row.prd_count)),
|
|
13
|
+
specs: sumNumbers(rows.map((row) => row.spec_count)),
|
|
14
|
+
evidences: sumNumbers(rows.map((row) => row.evidence_count)),
|
|
15
|
+
tests: sumNumbers(rows.map((row) => row.test_count)),
|
|
16
|
+
conversations: sumNumbers(rows.map(costGroupConversationCount)),
|
|
17
|
+
durationKnownMs: rows.reduce((sum, row) => sum + row.duration.known_sum, 0),
|
|
18
|
+
durationPartial: rows.some((row) => !row.duration.complete),
|
|
19
|
+
tokens: sumNumbers(rows.map((row) => row.total_tokens)),
|
|
20
|
+
usd: sumNumbers(rows.map((row) => row.estimated_usd)),
|
|
21
|
+
brl: sumNumbers(rows.map((row) => row.estimated_brl)),
|
|
22
|
+
};
|
|
23
|
+
}
|