@zaip-ai/cli 1.0.7 → 1.0.8
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 +6 -4
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +15 -5
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/adapters.test.js +1 -1
- package/dist/services/agent-adapters.d.ts +9 -0
- package/dist/services/agent-adapters.d.ts.map +1 -1
- package/dist/services/agent-adapters.js +38 -3
- package/dist/services/agent-adapters.js.map +1 -1
- package/dist/services/agent-adapters.test.js +8 -1
- package/dist/services/agent-adapters.test.js.map +1 -1
- package/dist/services/codex-config-template.d.ts +2 -1
- package/dist/services/codex-config-template.d.ts.map +1 -1
- package/dist/services/codex-config-template.js +13 -2
- package/dist/services/codex-config-template.js.map +1 -1
- package/dist/services/codex-rules.d.ts +1 -1
- package/dist/services/codex-rules.d.ts.map +1 -1
- package/dist/services/codex-rules.js +31 -7
- package/dist/services/codex-rules.js.map +1 -1
- 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 +4 -1
- package/dist/services/codex-subagent-hook-template.js.map +1 -1
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +3 -1
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/global-codex-config.d.ts +6 -3
- package/dist/services/global-codex-config.d.ts.map +1 -1
- package/dist/services/global-codex-config.js +82 -13
- package/dist/services/global-codex-config.js.map +1 -1
- package/dist/services/global-codex-config.test.js +57 -10
- 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 +15 -2
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/logger.js +1 -1
- package/dist/services/logger.js.map +1 -1
- package/dist/services/logger.test.js +3 -3
- package/dist/services/logger.test.js.map +1 -1
- package/dist/services/runtime-template.test.js +21 -5
- package/dist/services/runtime-template.test.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/package.json +1 -1
- package/templates/.agents/config/agents/catalog.yaml +310 -10
- package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +5 -5
- package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +8 -8
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +5 -3
- package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +30 -0
- package/templates/.agents/config/project.yaml +1 -1
- package/templates/.agents/dashboard/.zaip-managed.json +659 -163
- package/templates/.agents/dashboard/DATA-DICTIONARY.md +2227 -0
- package/templates/.agents/dashboard/README.md +48 -97
- package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-Z60df2r-.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cv-JcoxP.js → DashboardHelpDialog-Cs6dzDmW.js} +294 -109
- package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-Coc6pA-1.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-CaKwQP43.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-C98LGC-Q.js → dashboard-localization-CLJ0lT9v.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/icons-vendor-DFBuc_qp.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/react-vendor-CCQOHdVI.js +9 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-D9-fqq9M.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DFY7ZDlu.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-pC2_0J8x.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +9 -2
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/App.tsx +952 -595
- package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +48 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppLoadingPanels.tsx +2 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +247 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +95 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppSetupRoutes.tsx +87 -0
- package/templates/.agents/dashboard/apps/frontend/src/CostCalculationGuidePage.tsx +641 -0
- package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +159 -0
- package/templates/.agents/dashboard/apps/frontend/src/DashboardCapabilityNav.tsx +13 -13
- package/templates/.agents/dashboard/apps/frontend/src/DashboardGlobalSettings.tsx +56 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +257 -313
- package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +149 -0
- package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +35 -0
- package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +111 -12
- package/templates/.agents/dashboard/apps/frontend/src/app-preferences.ts +15 -0
- package/templates/.agents/dashboard/apps/frontend/src/app-session-token.ts +20 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.css +267 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.test.ts +69 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +70 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +111 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +432 -13
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/main.tsx +1 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.test.ts +55 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.ts +36 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.test.ts +126 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.ts +181 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +138 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +105 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +6 -3
- package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +9 -5
- package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +24 -0
- package/templates/.agents/dashboard/apps/frontend/src/period-transition-overlay.css +44 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +121 -62
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +471 -2
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +84 -17
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +44 -0
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +196 -39
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-notice.ts +15 -0
- package/templates/.agents/dashboard/apps/frontend/src/sqlite-cost-adapters.ts +26 -0
- package/templates/.agents/dashboard/apps/frontend/src/styles.css +14 -2
- package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +38 -2
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +187 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +190 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +121 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +398 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +141 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +45 -0
- package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +46 -0
- package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +37 -0
- package/templates/.agents/dashboard/apps/frontend/vite.config.ts +55 -5
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +47 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/duration-estimate.ts +13 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +64 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +275 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +100 -15
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +131 -40
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +137 -19
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.test.ts +2 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +13 -10
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +303 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +226 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +479 -402
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostSummary.tsx +5 -13
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +312 -72
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +373 -321
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +17 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +25 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +0 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-helpers.ts +17 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-responsive.css +6 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-row-filters.ts +123 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +8 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +32 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +52 -14
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-presentation.ts +121 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +3 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.test.ts +68 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +32 -5
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +108 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +12 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +60 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +106 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.test.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +5 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-pricing-fallback.test.ts +53 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.basics.test.ts +34 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +168 -137
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +188 -29
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +956 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +775 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +95 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/refactor-map-xr9l.json +61 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.test.ts +41 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.ts +55 -11
- package/templates/.agents/dashboard/modules/operations/package.json +2 -1
- package/templates/.agents/dashboard/modules/operations/src/contracts.ts +182 -0
- package/templates/.agents/dashboard/modules/operations/src/duration-population.test.ts +63 -1
- package/templates/.agents/dashboard/modules/operations/src/duration-population.ts +60 -5
- package/templates/.agents/dashboard/modules/operations/src/react/EntityDetailsDialog.tsx +14 -3
- package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.test.ts +44 -1
- package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +325 -18
- package/templates/.agents/dashboard/modules/operations/src/react/MacroPlanningDialog.tsx +1 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.test.ts +9 -5
- package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.tsx +2 -2
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +168 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +95 -6
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +365 -14
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +532 -131
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +314 -358
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +68 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +169 -0
- package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +51 -8
- package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.test.tsx +32 -0
- package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.tsx +62 -6
- package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.test.ts +55 -0
- package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.tsx +27 -19
- package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +99 -42
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts +19 -0
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +255 -34
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +163 -8
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +101 -68
- package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.test.ts +72 -1
- package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +78 -16
- package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +6 -4
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +50 -1
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +143 -9
- package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +29 -4
- package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog-content.css +49 -0
- package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog.css +93 -50
- package/templates/.agents/dashboard/modules/operations/src/react/manual-work-priority.test.ts +82 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts +29 -2
- package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.ts +22 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +77 -4
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +65 -5
- package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +54 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +19 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +149 -12
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +27 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +136 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.test.ts +160 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.ts +47 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-query.ts +10 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-responsive.css +3 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-view-labels.ts +28 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +24 -7
- package/templates/.agents/dashboard/modules/operations/src/react/operations.css +42 -0
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.test.ts +54 -0
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.ts +32 -0
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +165 -6
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +148 -6
- package/templates/.agents/dashboard/modules/operations/src/react/popup-localization.test.ts +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css +132 -0
- package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css.test.ts +13 -0
- package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.header.test.ts +16 -0
- package/templates/.agents/dashboard/modules/operations/src/react/use-infinite-column.ts +11 -5
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +5 -3
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +4 -83
- package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.test.ts +291 -15
- package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.ts +182 -472
- package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.test.ts +40 -0
- package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.ts +19 -6
- package/templates/.agents/dashboard/modules/operations/src/server/canonical-run-projection.ts +31 -6
- package/templates/.agents/dashboard/modules/operations/src/server/daily-duration-projection.ts +220 -0
- package/templates/.agents/dashboard/modules/operations/src/server/execution-duration-projection.ts +28 -0
- package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +27 -2
- package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +22 -13
- package/templates/.agents/dashboard/modules/operations/src/server/filter.test.ts +3 -3
- package/templates/.agents/dashboard/modules/operations/src/server/filter.ts +7 -2
- package/templates/.agents/dashboard/modules/operations/src/server/index.ts +3 -0
- package/templates/.agents/dashboard/modules/operations/src/server/macro.ts +3 -12
- package/templates/.agents/dashboard/modules/operations/src/server/manifest-usage.ts +65 -0
- package/templates/.agents/dashboard/modules/operations/src/server/operations-projection-aggregates.ts +297 -0
- package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +324 -0
- package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.test.ts +505 -0
- package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.ts +609 -0
- package/templates/.agents/dashboard/modules/operations/src/server/runs.ts +18 -19
- package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +76 -0
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/modules/traceability/src/server/build-task-trace.ts +3 -1
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +1756 -0
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +1608 -0
- package/templates/.agents/dashboard/packages/local-runtime/package.json +8 -3
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +12 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +83 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +28 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +262 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +41 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +105 -0
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +1643 -107
- package/templates/.agents/dashboard/packages/local-runtime/src/agent-adapter-sync.ts +30 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.test.ts +3 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.ts +5 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +72 -33
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +335 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +392 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/runtime.mjs +5 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +71 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +179 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-cross-layer-parity.test.ts +245 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models-route.ts +64 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.test.ts +204 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.ts +194 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +163 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +354 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.test.ts +74 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +113 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-overview.test.ts +68 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-period.ts +47 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +483 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-settings.test.ts +5 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +163 -84
- package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +145 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +551 -266
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +1145 -308
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.test.ts +53 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +708 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +2232 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +6151 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/work-priority-contract.test.ts +33 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +41 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +210 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +437 -190
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +299 -24
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/packages/windows-launcher/LauncherVerificationBehaviorTests.cs +206 -0
- package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +95 -8
- package/templates/.agents/dashboard/packages/windows-launcher/build-dashboard-launcher.ps1 +2 -2
- package/templates/.agents/dashboard/packages/windows-launcher/run-launcher-verification-tests.ps1 +22 -0
- package/templates/.agents/dashboard/read-model.dbml +2201 -0
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +1 -1
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +214 -41
- package/templates/.agents/dashboard/work-priority.json +34 -0
- package/templates/.agents/dashboard/zaip-dashboard-linux.sh +45 -0
- package/templates/.agents/dashboard/zaip-dashboard-mac.command +3 -0
- package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
- package/templates/.agents/design/.zaip-managed.json +3 -3
- package/templates/.agents/design/apps/catalog/package.json +1 -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/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 +24 -0
- 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 +4 -3
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +9 -6
- 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 +9 -3
- package/templates/.agents/requirements/zaip-strategic-95.md +4 -4
- package/templates/.agents/rules/autonomy-decision.md +15 -0
- package/templates/.agents/rules/core.md +1 -1
- package/templates/.agents/rules/run-lifecycle-closure.md +1 -1
- package/templates/.agents/rules/specialist-routing.md +19 -0
- package/templates/.agents/rules/workflow.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +114 -64
- package/templates/.agents/runtime/checksums.sha256 +6 -4
- package/templates/.agents/runtime/manifest.json +3 -1
- package/templates/.agents/runtime/pnpm-lock.sha256 +1 -0
- package/templates/.agents/runtime/provenance.json +11 -0
- package/templates/.agents/runtime/sbom.cdx.json +1929 -39
- package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
- package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +15 -0
- package/templates/.agents/skills/zaip-skill-brand-governance/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +30 -0
- package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +25 -0
- package/templates/.agents/skills/zaip-skill-dashboard-sqlite/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/SKILL.md +18 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/agents/openai.yaml +6 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.mjs +71 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.test.mjs +60 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/scheduled-ready-queue-contract.test.mjs +111 -0
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +2 -2
- package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +3 -1
- package/templates/.agents/skills/zaip-skill-general-operations/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-general-operations/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -7
- package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +11 -38
- package/templates/.agents/skills/zaip-skill-governance-compliance/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-governance-compliance/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +15 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/references/growth-revops-framework.md +25 -0
- package/templates/.agents/skills/zaip-skill-instalar-agendamento/SKILL.md +17 -0
- package/templates/.agents/skills/zaip-skill-instalar-agendamento/agents/openai.yaml +6 -0
- package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +3 -3
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +76 -27
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +128 -24
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +122 -4
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +66 -19
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +193 -7
- package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +14 -0
- package/templates/.agents/skills/zaip-skill-sales-methodology/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-sales-methodology/references/sales-process-framework.md +77 -0
- package/templates/.agents/skills/zaip-skill-setup/SKILL.md +5 -0
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +96 -0
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +18 -0
- package/templates/.agents/zaip-aios/INDEX.md +1 -0
- package/templates/.agents/zaip-aios/README.md +37 -8
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +43 -6
- package/templates/.agents/zaip-aios/guides/10-seguranca.md +21 -7
- package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +32 -0
- package/templates/template-manifest.json +945 -214
- package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-CLYIi7Vo.js +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-DTDNVQGX.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-CzEggcRb.js +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-05YKn6Z4.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-YO3yqtgV.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8AzCnl3a.js +0 -77
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DdBYQ_8D.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/src/AgentCatalogSettingsPage.tsx +0 -617
- package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings-page.css +0 -660
- package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings.test.ts +0 -249
- package/templates/.agents/dashboard/dashboard.config.json +0 -4
- package/templates/.agents/dashboard/zaip-dashboard.exe +0 -0
package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
dateRangeForPreset,
|
|
4
|
+
initialOperationsDateRange,
|
|
4
5
|
initialTaskDateRange,
|
|
5
6
|
isDateInOperationPreset,
|
|
7
|
+
isRunInOperationPreset,
|
|
6
8
|
isTaskCreatedInRange,
|
|
7
9
|
} from "./operation-date-range.js";
|
|
8
10
|
|
|
9
11
|
const today = new Date(2026, 6, 14, 12);
|
|
10
12
|
|
|
11
13
|
describe("operation date ranges", () => {
|
|
12
|
-
it("starts
|
|
14
|
+
it("starts on the earliest Task day and ends today", () => {
|
|
13
15
|
expect(
|
|
14
16
|
initialTaskDateRange(
|
|
15
17
|
[{ created_at: "2026-07-12T22:00:00.000Z" }, { created_at: "2026-07-10T15:00:00.000Z" }],
|
|
16
18
|
today,
|
|
17
19
|
),
|
|
18
|
-
).toEqual({ start: "2026-07-
|
|
20
|
+
).toEqual({ start: "2026-07-10", end: "2026-07-14" });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("uses the Sao Paulo day for the earliest Task", () => {
|
|
24
|
+
expect(initialTaskDateRange([{ created_at: "2026-07-10T02:30:00.000Z" }], today)).toEqual({
|
|
25
|
+
start: "2026-07-09",
|
|
26
|
+
end: "2026-07-14",
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("uses persisted manifest days for All Time before quick entity details load", () => {
|
|
31
|
+
expect(initialOperationsDateRange([], ["2026-07-11", "2026-08-06"], today)).toEqual({
|
|
32
|
+
start: "2026-07-11",
|
|
33
|
+
end: "2026-08-06",
|
|
34
|
+
});
|
|
19
35
|
});
|
|
20
36
|
|
|
21
37
|
it.each([
|
|
@@ -46,6 +62,17 @@ describe("operation date ranges", () => {
|
|
|
46
62
|
expect(isTaskCreatedInRange("2026-07-16T03:00:00.000Z", fifteenth)).toBe(false);
|
|
47
63
|
});
|
|
48
64
|
|
|
65
|
+
it("places a Run that starts before and finishes inside a period on its finish day", () => {
|
|
66
|
+
const augustFirst = { start: "2026-08-01", end: "2026-08-01" };
|
|
67
|
+
const run = {
|
|
68
|
+
started_at: "2026-08-01T02:30:00.000Z",
|
|
69
|
+
finished_at: "2026-08-01T03:30:00.000Z",
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
expect(isRunInOperationPreset(run, "custom", augustFirst)).toBe(true);
|
|
73
|
+
expect(isDateInOperationPreset(run.started_at, "custom", augustFirst)).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
|
|
49
76
|
it("keeps All Time unbounded while explicit This Month stays on the Sao Paulo calendar", () => {
|
|
50
77
|
const july = dateRangeForPreset("this-month", new Date("2026-08-01T02:30:00.000Z"));
|
|
51
78
|
expect(isDateInOperationPreset("2024-01-01T00:00:00.000Z", "all", july)).toBe(true);
|
|
@@ -26,10 +26,22 @@ export function initialTaskDateRange(
|
|
|
26
26
|
Number.POSITIVE_INFINITY,
|
|
27
27
|
);
|
|
28
28
|
const start = Number.isFinite(earliestTimestamp) ? new Date(earliestTimestamp) : today;
|
|
29
|
-
start.setUTCDate(start.getUTCDate() - 1);
|
|
30
29
|
return { start: toDateInputValue(start), end: toDateInputValue(today) };
|
|
31
30
|
}
|
|
32
31
|
|
|
32
|
+
/** Quick projections omit entity rows, but retain manifest day keys for All Time. */
|
|
33
|
+
export function initialOperationsDateRange(
|
|
34
|
+
tasks: readonly { created_at: string }[],
|
|
35
|
+
manifestDays: readonly string[],
|
|
36
|
+
today = new Date(),
|
|
37
|
+
): OperationDateRange {
|
|
38
|
+
if (tasks.length > 0) return initialTaskDateRange(tasks, today);
|
|
39
|
+
const days = manifestDays.filter((day) => /^\d{4}-\d{2}-\d{2}$/.test(day)).sort();
|
|
40
|
+
return days.length === 0
|
|
41
|
+
? initialTaskDateRange(tasks, today)
|
|
42
|
+
: { start: days[0]!, end: days.at(-1)! };
|
|
43
|
+
}
|
|
44
|
+
|
|
33
45
|
export function dateRangeForPreset(
|
|
34
46
|
preset: Exclude<OperationDatePreset, "all" | "custom">,
|
|
35
47
|
today = new Date(),
|
|
@@ -96,6 +108,15 @@ export function isDateInOperationPreset(
|
|
|
96
108
|
return preset === "all" || isDateInRange(value, dateRange);
|
|
97
109
|
}
|
|
98
110
|
|
|
111
|
+
/** Matches the server projection contract: a completed Run belongs to its finish day. */
|
|
112
|
+
export function isRunInOperationPreset(
|
|
113
|
+
run: { started_at: string; finished_at: string | null },
|
|
114
|
+
preset: OperationDatePreset,
|
|
115
|
+
dateRange: OperationDateRange,
|
|
116
|
+
): boolean {
|
|
117
|
+
return isDateInOperationPreset(run.finished_at ?? run.started_at, preset, dateRange);
|
|
118
|
+
}
|
|
119
|
+
|
|
99
120
|
function range(start: Date, end: Date): OperationDateRange {
|
|
100
121
|
return { start: toDateInputValue(start), end: toDateInputValue(end) };
|
|
101
122
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
displayedDuration,
|
|
4
|
+
elapsedDurationMs,
|
|
5
|
+
formatLifecycleElapsedDuration,
|
|
6
|
+
formatDisplayedDuration,
|
|
7
|
+
formatOperationDuration,
|
|
8
|
+
operationalDurationMs,
|
|
9
|
+
terminalLifecycleElapsedDurationMs,
|
|
10
|
+
} from "./operation-duration.js";
|
|
3
11
|
|
|
4
12
|
describe("formatOperationDuration", () => {
|
|
5
13
|
it("preserves unavailable and observed zero as different states", () => {
|
|
@@ -7,13 +15,78 @@ describe("formatOperationDuration", () => {
|
|
|
7
15
|
expect(formatOperationDuration(0, "pt-BR")).toBe("0 seg");
|
|
8
16
|
});
|
|
9
17
|
|
|
10
|
-
it("
|
|
18
|
+
it("keeps lifecycle elapsed separate from analytical duration", () => {
|
|
19
|
+
const run = {
|
|
20
|
+
duration_ms: 3_600_000,
|
|
21
|
+
source_duration_ms: null,
|
|
22
|
+
started_at: "2026-07-28T10:00:00Z",
|
|
23
|
+
finished_at: "2026-07-28T11:00:00Z",
|
|
24
|
+
};
|
|
25
|
+
expect(operationalDurationMs(run)).toBeNull();
|
|
26
|
+
expect(elapsedDurationMs(run)).toBe(3_600_000);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("uses an observed source duration including zero", () => {
|
|
11
30
|
expect(
|
|
12
31
|
operationalDurationMs({
|
|
13
|
-
duration_ms:
|
|
32
|
+
duration_ms: 3_600_000,
|
|
33
|
+
source_duration_ms: 0,
|
|
14
34
|
started_at: "2026-07-28T10:00:00Z",
|
|
15
35
|
finished_at: "2026-07-28T11:00:00Z",
|
|
16
36
|
}),
|
|
17
|
-
).toBe(
|
|
37
|
+
).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("uses lifecycle elapsed only as an explicitly labelled terminal fallback", () => {
|
|
41
|
+
expect(
|
|
42
|
+
displayedDuration({
|
|
43
|
+
status: "completed",
|
|
44
|
+
duration_ms: null,
|
|
45
|
+
source_duration_ms: null,
|
|
46
|
+
started_at: "2026-07-28T10:00:00Z",
|
|
47
|
+
finished_at: "2026-07-28T10:01:30Z",
|
|
48
|
+
}),
|
|
49
|
+
).toEqual({ durationMs: 90_000, provenance: "lifecycle_elapsed" });
|
|
50
|
+
expect(
|
|
51
|
+
displayedDuration({
|
|
52
|
+
status: "completed",
|
|
53
|
+
duration_ms: 60_000,
|
|
54
|
+
source_duration_ms: 60_000,
|
|
55
|
+
started_at: "2026-07-28T10:00:00Z",
|
|
56
|
+
finished_at: "2026-07-28T10:10:00Z",
|
|
57
|
+
}),
|
|
58
|
+
).toEqual({ durationMs: 60_000, provenance: "factual" });
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("labels a running Run without factual duration instead of calling it unavailable", () => {
|
|
62
|
+
const running = displayedDuration({
|
|
63
|
+
status: "running",
|
|
64
|
+
duration_ms: null,
|
|
65
|
+
source_duration_ms: null,
|
|
66
|
+
started_at: "2026-07-28T10:00:00Z",
|
|
67
|
+
finished_at: null,
|
|
68
|
+
});
|
|
69
|
+
expect(running).toEqual({ durationMs: null, provenance: "in_progress" });
|
|
70
|
+
expect(formatDisplayedDuration(running, "pt-BR")).toBe("Em andamento");
|
|
71
|
+
expect(
|
|
72
|
+
formatDisplayedDuration({ durationMs: null, provenance: "unavailable" }, "pt-BR"),
|
|
73
|
+
).toBe("Sem atribuição temporal");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("keeps terminal lifecycle elapsed separate from observed duration and never uses now", () => {
|
|
77
|
+
const terminal = {
|
|
78
|
+
status: "completed",
|
|
79
|
+
duration_ms: 60_000,
|
|
80
|
+
source_duration_ms: 60_000,
|
|
81
|
+
started_at: "2026-07-28T10:00:00Z",
|
|
82
|
+
finished_at: "2026-07-28T12:00:00Z",
|
|
83
|
+
};
|
|
84
|
+
expect(terminalLifecycleElapsedDurationMs(terminal)).toBe(7_200_000);
|
|
85
|
+
expect(formatLifecycleElapsedDuration(null, "pt-BR")).toBe(
|
|
86
|
+
formatOperationDuration(null, "pt-BR"),
|
|
87
|
+
);
|
|
88
|
+
expect(
|
|
89
|
+
terminalLifecycleElapsedDurationMs({ ...terminal, status: "running", finished_at: null }),
|
|
90
|
+
).toBeUndefined();
|
|
18
91
|
});
|
|
19
92
|
});
|
|
@@ -2,9 +2,9 @@ import { formatDurationMs } from "@zaip-ai/dashboard-ui";
|
|
|
2
2
|
import type { OperationsLocale } from "./status-labels.js";
|
|
3
3
|
|
|
4
4
|
export interface OperationalTiming {
|
|
5
|
-
duration_ms
|
|
5
|
+
duration_ms?: number | null;
|
|
6
6
|
source_duration_ms?: number | null;
|
|
7
|
-
started_at: string;
|
|
7
|
+
started_at: string | null;
|
|
8
8
|
finished_at: string | null;
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -16,12 +16,72 @@ export function formatOperationDuration(value: number | null, locale: Operations
|
|
|
16
16
|
|
|
17
17
|
/** List/detail elapsed time; analytical duration_ms remains unchanged for KPIs. */
|
|
18
18
|
export function operationalDurationMs(run: OperationalTiming): number | null {
|
|
19
|
-
if (typeof run.source_duration_ms === "number"
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
if (typeof run.source_duration_ms === "number" && run.source_duration_ms >= 0)
|
|
20
|
+
return run.source_duration_ms;
|
|
21
|
+
const provenance = (run as OperationalTiming & { duration_provenance?: string })
|
|
22
|
+
.duration_provenance;
|
|
23
|
+
if (
|
|
24
|
+
typeof run.duration_ms === "number" &&
|
|
25
|
+
run.duration_ms >= 0 &&
|
|
26
|
+
(provenance === "observed" || provenance === "reconciled" || provenance === "legacy_inferred")
|
|
27
|
+
)
|
|
28
|
+
return run.duration_ms;
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type DurationPresentationProvenance =
|
|
33
|
+
| "factual"
|
|
34
|
+
| "lifecycle_elapsed"
|
|
35
|
+
| "in_progress"
|
|
36
|
+
| "unavailable";
|
|
37
|
+
|
|
38
|
+
export function formatDisplayedDuration(
|
|
39
|
+
value: { durationMs: number | null; provenance: DurationPresentationProvenance },
|
|
40
|
+
locale: OperationsLocale,
|
|
41
|
+
): string {
|
|
42
|
+
if (value.provenance === "in_progress") return locale === "pt-BR" ? "Em andamento" : "In progress";
|
|
43
|
+
if (value.durationMs === null || value.provenance === "unavailable")
|
|
44
|
+
return locale === "pt-BR" ? "Sem atribuição temporal" : "No temporal attribution";
|
|
45
|
+
return formatOperationDuration(value.durationMs, locale);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Presentation-only terminal lifecycle fallback; never analytical telemetry. */
|
|
49
|
+
export function displayedDuration(
|
|
50
|
+
run: OperationalTiming & { status?: string },
|
|
51
|
+
): { durationMs: number | null; provenance: DurationPresentationProvenance } {
|
|
52
|
+
const factual = operationalDurationMs(run);
|
|
53
|
+
if (factual !== null) return { durationMs: factual, provenance: "factual" };
|
|
54
|
+
if (run.status === "running") return { durationMs: null, provenance: "in_progress" };
|
|
55
|
+
const lifecycle = terminalLifecycleElapsedDurationMs({ ...run, status: run.status ?? "" });
|
|
56
|
+
return lifecycle === undefined || lifecycle === null
|
|
57
|
+
? { durationMs: null, provenance: "unavailable" }
|
|
58
|
+
: { durationMs: lifecycle, provenance: "lifecycle_elapsed" };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Lifecycle elapsed time is operational context, never an analytical metric.
|
|
63
|
+
* Callers must label this separately as Tempo decorrido.
|
|
64
|
+
*/
|
|
65
|
+
export function elapsedDurationMs(run: OperationalTiming): number | null {
|
|
66
|
+
if (run.started_at === null || run.finished_at === null) return null;
|
|
22
67
|
const started = Date.parse(run.started_at);
|
|
23
68
|
const finished = Date.parse(run.finished_at);
|
|
24
69
|
return Number.isFinite(started) && Number.isFinite(finished) && finished >= started
|
|
25
70
|
? finished - started
|
|
26
71
|
: null;
|
|
27
72
|
}
|
|
73
|
+
|
|
74
|
+
/** `undefined` is ineligible; `null` is a terminal record without valid timestamps. */
|
|
75
|
+
export function terminalLifecycleElapsedDurationMs(
|
|
76
|
+
row: OperationalTiming & { status: string },
|
|
77
|
+
): number | null | undefined {
|
|
78
|
+
if (!["completed", "failed", "cancelled"].includes(row.status)) return undefined;
|
|
79
|
+
return elapsedDurationMs(row);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function formatLifecycleElapsedDuration(
|
|
83
|
+
value: number | null | undefined,
|
|
84
|
+
locale: OperationsLocale,
|
|
85
|
+
): string {
|
|
86
|
+
return value === undefined ? "—" : formatOperationDuration(value, locale);
|
|
87
|
+
}
|
package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { overviewMetricTotals } from "../server/build-operations-projection.js";
|
|
4
|
+
|
|
5
|
+
describe("Operations persisted aggregate display", () => {
|
|
6
|
+
it("removes the telemetry notice and its styling entirely", () => {
|
|
7
|
+
const overview = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
|
|
8
|
+
const styles = readFileSync(new URL("operations-overview.css", import.meta.url), "utf8");
|
|
9
|
+
|
|
10
|
+
expect(overview).not.toContain("operations-coverage-toast");
|
|
11
|
+
expect(styles).not.toContain("operations-coverage-toast");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("keeps legacy duration unavailable while preserving zero-valued tokens and cost", () => {
|
|
15
|
+
const totals = overviewMetricTotals(
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
id: "RUN-LEGACY",
|
|
19
|
+
started_at: "2026-08-03T12:00:00.000Z",
|
|
20
|
+
source_duration_ms: null,
|
|
21
|
+
duration_ms: 125,
|
|
22
|
+
duration_provenance: "legacy_inferred" as const,
|
|
23
|
+
usage: { total: { tokens: { total: 0 }, cost: { brl: 0 } } },
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "RUN-UNKNOWN",
|
|
27
|
+
started_at: "2026-08-03T12:01:00.000Z",
|
|
28
|
+
source_duration_ms: null,
|
|
29
|
+
duration_ms: null,
|
|
30
|
+
usage: { total: { tokens: { total: null }, cost: { brl: null } } },
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
{ from: "2026-08-03T00:00:00.000Z", to: "2026-08-03T23:59:59.999Z" },
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
expect(totals).toMatchObject({ duration_ms: null, tokens: 0, cost_brl: 0 });
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("preserves unavailable aggregate totals instead of rendering coerced zeroes", () => {
|
|
40
|
+
const overview = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
|
|
41
|
+
|
|
42
|
+
expect(overview).toContain("overviewMetrics?.duration_ms ??");
|
|
43
|
+
expect(overview).toContain(
|
|
44
|
+
"const totalTokensMetric = overviewMetrics?.tokens ?? allPhaseMetrics.tokens",
|
|
45
|
+
);
|
|
46
|
+
expect(overview).toContain("const totalCostMetric =");
|
|
47
|
+
expect(overview).toContain(
|
|
48
|
+
"durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: totalCostMetric",
|
|
49
|
+
);
|
|
50
|
+
expect(overview).toContain("formatEntityDuration(averageDuration, locale)");
|
|
51
|
+
expect(overview).not.toContain("allPhaseMetrics.tokens ?? 0");
|
|
52
|
+
expect(overview).not.toContain("executionMetrics.durationMs ?? 0");
|
|
53
|
+
});
|
|
54
|
+
});
|
package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
|
|
5
|
+
const globalFilterPanel = source.slice(
|
|
6
|
+
source.indexOf('<div className="operations-global-filters"'),
|
|
7
|
+
source.indexOf("filtersActive={Boolean(", source.indexOf('<div className="operations-global-filters"')),
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
describe("Operations global filters", () => {
|
|
11
|
+
it("keeps only period, dates, and reset in the dashboard header panel", () => {
|
|
12
|
+
expect(globalFilterPanel).toContain("<OperationDateFilters");
|
|
13
|
+
expect(globalFilterPanel).toContain("Limpar filtros");
|
|
14
|
+
expect(globalFilterPanel).not.toContain('"Tipo" : "Type"');
|
|
15
|
+
expect(globalFilterPanel).not.toContain("<span>Status</span>");
|
|
16
|
+
expect(globalFilterPanel).not.toContain('"Risco" : "Risk"');
|
|
17
|
+
expect(globalFilterPanel).not.toContain('"Origem da tarefa" : "Task origin"');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -1,44 +1,142 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { resolveOperationsPeriodControl, shouldRenderOperationsContent } from "./OperationsPage.js";
|
|
4
|
+
import { workListTypeOnViewChange } from "./operations-page-contract.js";
|
|
3
5
|
|
|
4
6
|
describe("overview period filter", () => {
|
|
5
|
-
it("passes
|
|
7
|
+
it("passes activity-filtered entities and Runs to every overview metric", () => {
|
|
6
8
|
const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
|
|
7
9
|
const overviewStart = source.indexOf("<OperationsOverview");
|
|
8
10
|
const overviewEnd = source.indexOf("/>", overviewStart);
|
|
9
11
|
const overview = source.slice(overviewStart, overviewEnd);
|
|
10
12
|
|
|
11
13
|
expect(overview).toContain("runs={runs}");
|
|
14
|
+
expect(overview).toContain("tasks={tasks}");
|
|
15
|
+
expect(overview).toContain("specs={specs}");
|
|
16
|
+
expect(overview).toContain("prds={prds}");
|
|
12
17
|
expect(overview).not.toContain("runs={data.runs}");
|
|
13
18
|
});
|
|
14
19
|
|
|
15
|
-
it("
|
|
20
|
+
it("replaces stale Operations content without duplicated period controls or gray bars", () => {
|
|
21
|
+
const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
|
|
22
|
+
|
|
23
|
+
expect(shouldRenderOperationsContent(true)).toBe(false);
|
|
24
|
+
expect(shouldRenderOperationsContent(false)).toBe(true);
|
|
25
|
+
expect(source).toContain("<OperationsPageLoading locale={locale} />");
|
|
26
|
+
expect(source).not.toContain('className="operations-hero operations-hero-skeleton"');
|
|
27
|
+
expect(source).toContain('className="operations-content-skeleton"');
|
|
28
|
+
expect(source).not.toContain('className="operations-content-skeleton-lines"');
|
|
29
|
+
expect(source).not.toContain('className="operations-loading-period"');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("keeps the App-controlled Yesterday selection across a loading render without remount state", () => {
|
|
33
|
+
const yesterday = { start: "2026-08-07", end: "2026-08-07" };
|
|
34
|
+
const controlled = resolveOperationsPeriodControl({
|
|
35
|
+
datePreset: "yesterday",
|
|
36
|
+
dateRange: yesterday,
|
|
37
|
+
fallbackPreset: "today",
|
|
38
|
+
fallbackRange: { start: "2026-08-08", end: "2026-08-08" },
|
|
39
|
+
});
|
|
40
|
+
const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
|
|
41
|
+
|
|
42
|
+
expect(controlled).toMatchObject({
|
|
43
|
+
controlled: true,
|
|
44
|
+
datePreset: "yesterday",
|
|
45
|
+
dateRange: yesterday,
|
|
46
|
+
});
|
|
47
|
+
expect(source).toContain("datePreset: controlledDatePreset");
|
|
48
|
+
expect(source).toContain("dateRange: controlledDateRange");
|
|
49
|
+
expect(source).toContain("onDateChange");
|
|
50
|
+
expect(source).toContain("const isPeriodControlled = periodControl.controlled;");
|
|
51
|
+
expect(source).not.toContain('className="operations-loading-period"');
|
|
52
|
+
expect(shouldRenderOperationsContent(true)).toBe(false);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("derives all big-number KPIs from the period-filtered global aggregate", () => {
|
|
16
56
|
const source = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
|
|
17
57
|
|
|
18
58
|
expect(source).toContain("const executionMetrics = executionMetricTotals(runs)");
|
|
19
|
-
expect(source).toContain("
|
|
20
|
-
expect(source).toContain("
|
|
59
|
+
expect(source).toContain("overviewMetrics?.duration_ms ?? executionMetrics.durationMs");
|
|
60
|
+
expect(source).not.toContain("effortMetricTotals");
|
|
61
|
+
expect(source).not.toContain("globalLegacyEffortMetricDuration");
|
|
62
|
+
expect(source).toContain("const overviewMetrics = partialOverviewMetrics(data);");
|
|
63
|
+
expect(source).toContain("return data.summary.overview_metrics;");
|
|
21
64
|
expect(source).toContain("overviewMetrics?.duration_ms ??");
|
|
22
|
-
expect(source).toContain("effortMetrics.durationMs");
|
|
23
65
|
expect(source).toContain("overviewMetrics?.tokens ?? allPhaseMetrics.tokens");
|
|
66
|
+
expect(source).toContain("overviewMetrics?.cost_brl ??");
|
|
67
|
+
expect(source).toContain("const selectedCurrencyCost =");
|
|
24
68
|
expect(source).not.toContain("data.summary.execution_duration_ms");
|
|
25
69
|
expect(source).not.toContain("data.summary.usage.total");
|
|
26
70
|
});
|
|
27
71
|
|
|
28
|
-
it("
|
|
72
|
+
it("renders Operations costs in the selected currency from the factual per-Run resolver", () => {
|
|
73
|
+
const source = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
|
|
74
|
+
const periods = readFileSync(new URL("PeriodSummaryTable.tsx", import.meta.url), "utf8");
|
|
75
|
+
|
|
76
|
+
expect(source).toContain('currency: "BRL" | "USD"');
|
|
77
|
+
expect(source).toContain("const selectedCurrencyCost =");
|
|
78
|
+
expect(source).toContain("formatCurrency(averageCost, currency, locale)");
|
|
79
|
+
expect(source).toContain("formatRoundedCurrency(totalCostMetric, currency, locale)");
|
|
80
|
+
expect(source).toContain("const topEntitiesCost =");
|
|
81
|
+
expect(source).toContain("formatCurrency(topEntitiesCost, currency, locale)");
|
|
82
|
+
expect(periods).toContain("resolveRunCost?: ((runId: string) => number | null)");
|
|
83
|
+
expect(periods).toContain("formatCurrency(row.costBrl, currency, locale)");
|
|
84
|
+
expect(periods).toContain('manifestDailyPeriods === undefined || currency === "USD"');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("pairs the global language selector with its currency before passing it to Operations", () => {
|
|
29
88
|
const app = readFileSync(
|
|
30
89
|
new URL("../../../../apps/frontend/src/App.tsx", import.meta.url),
|
|
31
90
|
"utf8",
|
|
32
91
|
);
|
|
33
92
|
|
|
34
|
-
expect(app).toContain("const
|
|
35
|
-
expect(app).toContain("
|
|
36
|
-
expect(app).
|
|
37
|
-
expect(app).toContain("
|
|
38
|
-
expect(app).toContain(
|
|
39
|
-
|
|
93
|
+
expect(app).toContain("const changeDashboardLocale = useCallback");
|
|
94
|
+
expect(app).toContain('setCurrency(next === "en-US" ? "USD" : "BRL")');
|
|
95
|
+
expect(app).toContain("onLocaleChange={changeDashboardLocale}");
|
|
96
|
+
expect(app).toContain('currency === "USD" ? run.estimated_usd : run.estimated_brl');
|
|
97
|
+
expect(app).toContain("resolveRunCost={");
|
|
98
|
+
expect(app).toContain('if (currency !== "USD" || costs?.currency === currency) return;');
|
|
99
|
+
expect(app).toContain('void loadCostSummary();');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("loads the quick overview first while retaining the detail hydration fallback", () => {
|
|
103
|
+
const app = readFileSync(
|
|
104
|
+
new URL("../../../../apps/frontend/src/App.tsx", import.meta.url),
|
|
105
|
+
"utf8",
|
|
40
106
|
);
|
|
107
|
+
const hydration = readFileSync(
|
|
108
|
+
new URL("../../../../apps/frontend/src/operations-detail-hydration.ts", import.meta.url),
|
|
109
|
+
"utf8",
|
|
110
|
+
);
|
|
111
|
+
const effects = readFileSync(
|
|
112
|
+
new URL("../../../../apps/frontend/src/use-app-effects.ts", import.meta.url),
|
|
113
|
+
"utf8",
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
expect(app).toContain('api.operations(period, "quick",');
|
|
117
|
+
expect(app).toContain("const requestVersion = ++refreshVersion.current;");
|
|
118
|
+
expect(app).toContain("operationsDetailLoadedRef.current = true;");
|
|
119
|
+
expect(app).toContain("isCurrentDashboardRequest(requestVersion, refreshVersion.current)");
|
|
41
120
|
expect(app).toContain("if (!isCurrentRequest()) return;");
|
|
121
|
+
expect(app).toContain("useAppEffects({");
|
|
122
|
+
expect(effects).toContain("shouldHydrateOperationsDetails(");
|
|
123
|
+
expect(effects).toContain("scheduleOperationsDetail(async (signal)");
|
|
124
|
+
expect(effects).toContain("await loadOperationsDetails(signal);");
|
|
125
|
+
expect(app).toContain('api.operations(period, "quick",');
|
|
126
|
+
expect(app).not.toContain('api.operations(period, "overview", signal)');
|
|
127
|
+
expect(hydration).toContain("operationsDetailStartDelayMs = 0");
|
|
128
|
+
expect(hydration).not.toContain("requestIdleCallback");
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("invalidates the full detail snapshot before loading a new period overview", () => {
|
|
132
|
+
const app = readFileSync(
|
|
133
|
+
new URL("../../../../apps/frontend/src/App.tsx", import.meta.url),
|
|
134
|
+
"utf8",
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
expect(app).toContain("operationsDetailLoadedRef.current = false;");
|
|
138
|
+
expect(app).toContain("costsLoadedRef.current = false;");
|
|
139
|
+
expect(app).toContain("setOperationsPeriod({ preset, range });");
|
|
42
140
|
});
|
|
43
141
|
|
|
44
142
|
it("treats completed as a Run status in the Runs view, not a work stage", () => {
|
|
@@ -49,6 +147,17 @@ describe("overview period filter", () => {
|
|
|
49
147
|
expect(source).toContain("macroWorkStage(row, data.tasks) === statusFilter");
|
|
50
148
|
});
|
|
51
149
|
|
|
150
|
+
it("resets the real List navigation callback on re-entry without changing Kanban routing", () => {
|
|
151
|
+
const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
|
|
152
|
+
|
|
153
|
+
expect(workListTypeOnViewChange("work-list")).toBe("all");
|
|
154
|
+
expect(workListTypeOnViewChange("work-kanban")).toBeNull();
|
|
155
|
+
expect(source).toContain("const nextWorkListType = workListTypeOnViewChange(nextView)");
|
|
156
|
+
expect(source).toContain("onWorkListTypeChange?.(nextWorkListType)");
|
|
157
|
+
expect(source).toContain('if (view === "work-kanban") onBoardFiltersChange?.(filters)');
|
|
158
|
+
expect(source).toContain("else onWorkListFiltersChange?.(filters)");
|
|
159
|
+
});
|
|
160
|
+
|
|
52
161
|
it("scopes task and macro metrics to the active overview entity kind", () => {
|
|
53
162
|
const source = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
|
|
54
163
|
|
|
@@ -58,6 +167,16 @@ describe("overview period filter", () => {
|
|
|
58
167
|
expect(source).toContain("run.prd_id !== null && macroIds.has(run.prd_id)");
|
|
59
168
|
});
|
|
60
169
|
|
|
170
|
+
it("keeps the overview projection run-free while details load separately", () => {
|
|
171
|
+
const source = readFileSync(
|
|
172
|
+
new URL("../server/build-operations-projection.ts", import.meta.url),
|
|
173
|
+
"utf8",
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
expect(source).toContain("readScopedRuns(filesystem, layout, normalizedFilter)");
|
|
177
|
+
expect(source).toContain("runs: options.overviewOnly ? [] : recentRunsFirst(runs)");
|
|
178
|
+
});
|
|
179
|
+
|
|
61
180
|
it("keeps duration execution-only but lets global usage cards span all filtered phases", () => {
|
|
62
181
|
const source = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
|
|
63
182
|
|
|
@@ -66,4 +185,22 @@ describe("overview period filter", () => {
|
|
|
66
185
|
expect(source).toContain("overviewMetrics?.tokens ?? allPhaseMetrics.tokens");
|
|
67
186
|
expect(source).toContain("const selectedMetricRuns = runsForOverviewView");
|
|
68
187
|
});
|
|
188
|
+
|
|
189
|
+
it("propagates period activity from Tasks and SPECs to their parent macros", () => {
|
|
190
|
+
const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
|
|
191
|
+
|
|
192
|
+
expect(source).toContain("const periodMacros = macrosWithPeriodActivity");
|
|
193
|
+
expect(source).toContain("periodMacros.specs.includes(row)");
|
|
194
|
+
expect(source).toContain("periodMacros.prds.includes(row)");
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("uses the creation-only summary population for reports and their exported rows", () => {
|
|
198
|
+
const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
|
|
199
|
+
|
|
200
|
+
expect(source).toContain(
|
|
201
|
+
"const summaryPopulation = periodSummaryPopulation(data, matchesSelectedDate);",
|
|
202
|
+
);
|
|
203
|
+
expect(source).toContain("aggregatePeriodSummary(\n summaryPopulation,");
|
|
204
|
+
expect(source).toContain("data={summaryPopulation}");
|
|
205
|
+
});
|
|
69
206
|
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
const source = readFileSync(new URL("./OperationsOverview.tsx", import.meta.url), "utf8");
|
|
5
|
+
|
|
6
|
+
describe("OperationsOverview status cards", () => {
|
|
7
|
+
it("opens a filtered dialog for Tasks, SPECs, and PRDs", () => {
|
|
8
|
+
expect(source).toContain('return item.key !== "unclassified" ?');
|
|
9
|
+
expect(source).toContain('overviewView === "tasks" ? "task"');
|
|
10
|
+
expect(source).toContain('kind={overviewView === "tasks" ? "task"');
|
|
11
|
+
expect(source).not.toContain("macroWorkStage(macro, tasks) === selectedStatus");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("uses selected-type labels, closes before document navigation, and paginates", () => {
|
|
15
|
+
expect(source).toContain("onOpenDocument(item.kind, item.id)");
|
|
16
|
+
expect(source).toContain("setSelectedStatus(null);");
|
|
17
|
+
expect(source).toContain('"Status das tarefas"');
|
|
18
|
+
expect(source).toContain('"Status das SPECs"');
|
|
19
|
+
expect(source).toContain('"Status dos PRDs"');
|
|
20
|
+
expect(source).toContain("const total = page?.total ?? items.length;");
|
|
21
|
+
expect(source).toContain("aria-label={`${label} — ${total} ${taskLabel}`}");
|
|
22
|
+
expect(source).toContain("onLoadMore(items.length)");
|
|
23
|
+
expect(source).toContain('aria-busy="true"');
|
|
24
|
+
expect(source).toContain('role="alert"');
|
|
25
|
+
expect(source).toContain("Nenhum${kind === \"task\" ? \"a\" : \"\"}");
|
|
26
|
+
});
|
|
27
|
+
});
|