@zaip-ai/cli 3.2.0 → 3.4.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/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +5 -3
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/agent-catalog-upgrade.d.ts +3 -0
- package/dist/services/agent-catalog-upgrade.d.ts.map +1 -0
- package/dist/services/agent-catalog-upgrade.js +35 -0
- package/dist/services/agent-catalog-upgrade.js.map +1 -0
- package/dist/services/install-agents-template.d.ts.map +1 -1
- package/dist/services/install-agents-template.js +22 -22
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/install-template-policy.d.ts +3 -0
- package/dist/services/install-template-policy.d.ts.map +1 -0
- package/dist/services/install-template-policy.js +21 -0
- package/dist/services/install-template-policy.js.map +1 -0
- package/dist/services/logger.js +24 -8
- package/dist/services/logger.js.map +1 -1
- package/dist/services/logger.test.js +33 -6
- package/dist/services/logger.test.js.map +1 -1
- package/dist/services/sqlite-bootstrap.d.ts +1 -0
- package/dist/services/sqlite-bootstrap.d.ts.map +1 -1
- package/dist/services/sqlite-bootstrap.js +10 -1
- package/dist/services/sqlite-bootstrap.js.map +1 -1
- package/package.json +2 -2
- package/templates/.agents/README-ENG.md +2 -1
- package/templates/.agents/README.md +2 -1
- package/templates/.agents/config/agents/catalog.yaml +1 -0
- package/templates/.agents/config/agents/discovery.json +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +2 -2
- package/templates/.agents/dashboard/.zaip-managed.json +278 -126
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-CEDZjl4V.js → CostCalculationGuidePage-C5NgEcVh.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-BzaUTZDx.js → DashboardHelpDialog-CCMVnkkI.js} +4 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-21cCJik-.js → PricingSettingsDialog-CGYcJ5EB.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-BAvLPAee.js → ProjectSettingsPage-DVCPPV75.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-wqW52uCx.js → TraceabilityWorkspace-CqK3Psfy.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{cost-monitor-PoJA2PI1.css → cost-monitor-BsMfGfQi.css} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-j3aUYH5G.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-BkAm8-h4.js → dashboard-localization-jvdDfNKs.js} +2 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DEmo6Tn2.js → icons-vendor-x8xxL9yW.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cl5EWx8R.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cwylbh_N.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CadYsm83.js → react-vendor-CNOXIJHN.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-BzKK8kK3.js → traceability-CcpbpT1s.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +7 -7
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/App.tsx +12 -1
- package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.test.tsx +33 -0
- package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.tsx +58 -0
- package/templates/.agents/dashboard/apps/frontend/src/app-work-board-options.ts +41 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-runtime-status.ts +25 -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.ts +5 -1
- package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.test.ts +140 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.ts +28 -41
- package/templates/.agents/dashboard/apps/frontend/src/use-runtime-status.ts +38 -0
- package/templates/.agents/dashboard/apps/frontend/src/workspace-status.css +33 -0
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +25 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +17 -19
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +13 -167
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.tsx +2 -9
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +8 -8
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +29 -52
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.test.ts +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +4 -27
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +4 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/agent-model-presentation.test.ts +26 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-embedded.css +7 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-loaders.ts +173 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-props.ts +47 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-selectors.ts +1 -7
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-page-range.ts +3 -9
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +44 -83
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +11 -111
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +47 -181
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +63 -91
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-monitor-unavailable.test.ts +55 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-summary-duration.test.ts +189 -0
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsEntityFilters.tsx +82 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +4 -1
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +5 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +22 -31
- package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.test.tsx +13 -1
- package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.tsx +16 -3
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +11 -27
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +44 -193
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportColumns.ts +186 -0
- package/templates/.agents/dashboard/modules/operations/src/react/export/excel-agent-participations.test.ts +28 -0
- package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +2 -1
- package/templates/.agents/dashboard/modules/operations/src/react/export/xlsx-runtime-e2e.test.ts +55 -31
- package/templates/.agents/dashboard/modules/operations/src/react/operations-export-duration.ts +13 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-filter-panel.css +4 -0
- package/templates/.agents/dashboard/modules/operations/src/react/use-operation-filter-feedback.ts +18 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +11 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +10 -2
- package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +1 -1
- 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 +406 -332
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +352 -280
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +2 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +4 -2
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +406 -332
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +95 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +102 -12
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +75 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-costs-routes.ts +10 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-lifecycle-diagnostics.ts +50 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-macro-population.test.ts +165 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-page-filters.ts +65 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +111 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +53 -63
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +19 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.test.ts +19 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.ts +11 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-read-projections.ts +19 -12
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +46 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.test.ts +10 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +4 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +43 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +46 -11
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts +188 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-summary-details.test.ts +85 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-summary-details.ts +147 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.test.ts +94 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +96 -55
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-force-canonical.test.ts +58 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-macro-classification.test.ts +172 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-projections.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +4 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +7 -7
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +2 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-period-averages.ts +10 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-agent-dimension.ts +18 -82
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-cached-cost-page.ts +169 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-developer.ts +205 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.ts +13 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-filtered-dimension.ts +22 -23
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-financial.ts +42 -209
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-model-dimension.ts +18 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-provider-dimension.ts +9 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +76 -83
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-view-page.ts +25 -161
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +18 -45
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +15 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-filesystem.ts +16 -16
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-keeps-orphan-telemetry-out-kanban-without.test.ts +2 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +47 -22
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +16 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +13 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-rebuild-result.ts +15 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-base-views.ts +4 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts +19 -42
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-macro-classification.ts +48 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-summary-cursor.ts +15 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-token-active-allocation.ts +46 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-stages.ts +60 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +5 -1
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-claims.test.mjs +7 -1
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +17 -2
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-ownership.mjs +65 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-ownership.test.mjs +72 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +32 -9
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +39 -45
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +5 -2
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/scripts/qualify-macro-overview.mjs +50 -0
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +1 -18
- package/templates/.agents/dashboard/tests/e2e/specs/export-row-identity.spec.ts +20 -0
- package/templates/.agents/dashboard/tests/e2e/specs/export-row-identity.ts +20 -0
- package/templates/.agents/design/.zaip-managed.json +82 -74
- package/templates/.agents/design/apps/catalog/dist/assets/index-0W0Gj_Gs.css +1 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-32GZO95T.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/{index-D_lfqoyx.js → index-BP8IxOxt.js} +3 -3
- package/templates/.agents/design/apps/catalog/dist/assets/{index-BOjCcUaU.js → index-QJsgr9Ht.js} +3 -3
- package/templates/.agents/design/apps/catalog/dist/index.html +2 -2
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-CvaciY0C.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Color-6AOWCN3U-Cm-yJJz_.js → Color-6AOWCN3U-DwBV1A1Y.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-3dqK5g3e.js +142 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-2OCgtT0I.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DocsRenderer-JROSPFPF-Belk4jRr.js → DocsRenderer-JROSPFPF-CODg0rSl.js} +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Primitives-BmeKjJW4.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WithTooltip-7X4HQR7L-DoPvjkS1.js → WithTooltip-7X4HQR7L-C5MI-3uZ.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatus.stories-Tb_iQqVK.js +17 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatusSpecimen-CD54pw0-.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-DRQKCCAG-B1itKXEN.js → chunk-DRQKCCAG-KSn75jcy.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-W22LQPXL-C-Eb5SPY.js → chunk-W22LQPXL-C4LS1Thf.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{components-DnyKLwhj.js → components-DV1BRgMY.js} +5 -5
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-BU_68im1.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/iframe-0W0Gj_Gs.css +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{iframe-DcXBsFPz.js → iframe-CBbPFx5G.js} +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{react-18-CRM89QRf.js → react-18-C9IPGXtb.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-CEv2qkJT.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{syntaxhighlighter-YFXUGROL-B03jQGTF.js → syntaxhighlighter-YFXUGROL-ZgDQjyWI.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{theming-4ZyufAga.js → theming-Cx9-gH6l.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/iframe.html +2 -2
- package/templates/.agents/design/apps/catalog/dist/storybook/index.json +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/a11y-2/manager-bundle.js +3 -3
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/docs-1/manager-bundle.js +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +60 -60
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/apps/catalog/src/components/DashboardFiltersSpecimen.tsx +61 -0
- package/templates/.agents/design/apps/catalog/src/components/Primitives.tsx +24 -0
- package/templates/.agents/design/apps/catalog/src/components/WorkspaceStatusSpecimen.tsx +26 -0
- package/templates/.agents/design/apps/catalog/src/design-contract.test.ts +27 -13
- package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +38 -0
- package/templates/.agents/design/apps/catalog/src/pages/DesignSystemPage.tsx +15 -1
- package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +18 -0
- package/templates/.agents/design/apps/catalog/src/stories/DashboardFilters.stories.tsx +7 -0
- package/templates/.agents/design/apps/catalog/src/stories/WorkspaceStatus.stories.tsx +9 -0
- package/templates/.agents/design/apps/catalog/src/styles/components.css +83 -2
- package/templates/.agents/design/apps/catalog/src/styles.css +2 -0
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/design/tokens.json +32 -0
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +18 -4
- 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 +1 -0
- package/templates/.agents/rules/workflow.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +28 -26
- 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-aios/SKILL.md +0 -1
- package/templates/.agents/skills/zaip-skill-author-skills/scripts/audit-skill-catalog.mjs +1 -0
- package/templates/.agents/skills/zaip-skill-config/SKILL.md +1 -1
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +13 -0
- package/templates/.agents/skills/zaip-skill-execution/references/autonomous-continuation.md +17 -0
- package/templates/.agents/skills/zaip-skill-execution/references/correction-cycle.md +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +4 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +4 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/references/release-identity.md +2 -2
- package/templates/.agents/skills/zaip-skill-github-setup/SKILL.md +2 -2
- package/templates/.agents/skills/zaip-skill-move-prd/SKILL.md +4 -0
- package/templates/.agents/skills/zaip-skill-move-spec/SKILL.md +4 -0
- package/templates/.agents/skills/zaip-skill-prd/SKILL.md +3 -3
- package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +15 -8
- package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +13 -12
- package/templates/.agents/skills/zaip-skill-setup/SKILL.md +50 -13
- package/templates/.agents/skills/zaip-skill-setup/agents/openai.yaml +2 -2
- package/templates/.agents/skills/zaip-skill-spec/SKILL.md +2 -2
- package/templates/.agents/skills/zaip-skill-update-version-doc/SKILL.md +39 -0
- package/templates/.agents/skills/zaip-skill-update-version-doc/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-update-version-doc/scripts/update-version-doc.mjs +21 -0
- package/templates/.agents/skills/zaip-skill-update-version-doc/scripts/update-version-doc.test.mjs +32 -0
- package/templates/.agents/zaip-aios/README.md +2 -1
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +7 -3
- package/templates/template-manifest.json +436 -256
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-06__WZco.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cmlx8OYH.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DqZKJS8y.js +0 -2
- package/templates/.agents/design/apps/catalog/dist/assets/index-BEmIE7WE.css +0 -1
- package/templates/.agents/design/apps/catalog/dist/assets/index-BJV597iq.js +0 -72
- package/templates/.agents/design/apps/catalog/dist/assets/index-B_WhrCZe.js +0 -72
- package/templates/.agents/design/apps/catalog/dist/assets/index-CqqYWY2f.js +0 -9
- package/templates/.agents/design/apps/catalog/dist/assets/index-CqtYXZfV.js +0 -72
- package/templates/.agents/design/apps/catalog/dist/assets/index-D9pj7Jlf.js +0 -9
- package/templates/.agents/design/apps/catalog/dist/assets/index-i_PO2k9R.js +0 -9
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-Cstn1UwA.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-D1WopB2L.js +0 -137
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DQ9PJ3N3.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-D0OSgxWz.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/iframe-BEmIE7WE.css +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-C3tkVMIp.js +0 -1
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
|
-
import { resolve } from "node:path";
|
|
3
|
+
import { basename, resolve } from "node:path";
|
|
4
4
|
import { serve } from "@hono/node-server";
|
|
5
5
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
6
6
|
import { WorkspaceFileSystem, type WorkspaceLayout } from "@zaip-ai/core";
|
|
7
7
|
import { fxRateSchema, PricingRepository, pricingCatalogSchema } from "@zaip-ai/costs";
|
|
8
8
|
import { type Context, Hono } from "hono";
|
|
9
9
|
import { getCookie, setCookie } from "hono/cookie";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type ActiveCodexTelemetryCapture,
|
|
12
|
+
captureActiveCodexTelemetry,
|
|
13
|
+
} from "./active-codex-telemetry.js";
|
|
11
14
|
import { runAgentAdapterSync } from "./agent-adapter-sync.js";
|
|
12
15
|
import {
|
|
13
16
|
type AgentAdapterSyncResult,
|
|
@@ -30,6 +33,7 @@ import {
|
|
|
30
33
|
requireV2Layout,
|
|
31
34
|
V2WorkspaceRequiredError,
|
|
32
35
|
} from "./server-http-contracts.js";
|
|
36
|
+
import { lifecycleManifestState } from "./server-lifecycle-diagnostics.js";
|
|
33
37
|
import { registerOperationsRoutes } from "./server-operations-routes.js";
|
|
34
38
|
import { projectionPeriodFilter } from "./server-period.js";
|
|
35
39
|
import { buildFirstFoldQuickProjection, dashboardSnapshot } from "./server-read-projections.js";
|
|
@@ -131,9 +135,8 @@ function shouldBootstrapBrowserSession(context: Context): boolean {
|
|
|
131
135
|
*/
|
|
132
136
|
|
|
133
137
|
/**
|
|
134
|
-
* SQLite
|
|
135
|
-
*
|
|
136
|
-
* treating a missing manifest as a broken workspace.
|
|
138
|
+
* SQLite snapshots intentionally exclude derived lifecycle manifests. Manifest
|
|
139
|
+
* health is therefore always read from the canonical filesystem.
|
|
137
140
|
*/
|
|
138
141
|
|
|
139
142
|
export function createDashboardApp(
|
|
@@ -162,6 +165,8 @@ export function createDashboardApp(
|
|
|
162
165
|
if (isSqliteSnapshot) await refreshSqliteSnapshotInWorker(workspaceRoot, filesystem);
|
|
163
166
|
});
|
|
164
167
|
const workspaceKey = dashboardWorkspaceKey(workspaceRoot);
|
|
168
|
+
const workspace = resolve(workspaceRoot);
|
|
169
|
+
const workspaceName = basename(workspace);
|
|
165
170
|
const syncAgentAdapters = options.syncAgentAdapters ?? (() => runAgentAdapterSync(workspaceRoot));
|
|
166
171
|
let catalogWriteTail = Promise.resolve();
|
|
167
172
|
type DashboardSnapshot = Awaited<ReturnType<typeof dashboardSnapshot>>;
|
|
@@ -213,6 +218,7 @@ export function createDashboardApp(
|
|
|
213
218
|
let observedSnapshotRevision: string | null = null;
|
|
214
219
|
const projectionRefreshDiagnostics = createProjectionRefreshDiagnostics();
|
|
215
220
|
let activeCaptureFailure: { code: string; occurred_at: string; cause: string } | null = null;
|
|
221
|
+
let activeCapture: ActiveCodexTelemetryCapture | null = null;
|
|
216
222
|
let projectionRefreshInFlight: Promise<void> | null = null;
|
|
217
223
|
let projectionRefreshRequested = false;
|
|
218
224
|
const rebuildProjection = async () => {
|
|
@@ -263,7 +269,8 @@ export function createDashboardApp(
|
|
|
263
269
|
? { captureActiveTelemetry: () => captureActiveCodexTelemetry(workspaceRoot) }
|
|
264
270
|
: {}),
|
|
265
271
|
onRefreshFailure: projectionRefreshDiagnostics.record,
|
|
266
|
-
onCaptureSuccess: () => {
|
|
272
|
+
onCaptureSuccess: (result) => {
|
|
273
|
+
activeCapture = result;
|
|
267
274
|
activeCaptureFailure = null;
|
|
268
275
|
},
|
|
269
276
|
onCaptureFailure: (error) => {
|
|
@@ -403,20 +410,30 @@ export function createDashboardApp(
|
|
|
403
410
|
registerBrowserLeaseRoute(app, API_PREFIX, options.launcherOwned === true);
|
|
404
411
|
app.on(["GET", "HEAD"], `${API_PREFIX}/health`, async (context) => {
|
|
405
412
|
try {
|
|
406
|
-
const layout = await
|
|
413
|
+
const [layout, manifestState] = await Promise.all([
|
|
414
|
+
readLayout(),
|
|
415
|
+
lifecycleManifestState(canonicalFilesystem),
|
|
416
|
+
]);
|
|
407
417
|
return headOrJson(context, {
|
|
408
418
|
kind: RUNTIME_KIND,
|
|
409
419
|
workspaceKey,
|
|
420
|
+
workspace,
|
|
421
|
+
workspace_name: workspaceName,
|
|
422
|
+
server_pid: process.pid,
|
|
410
423
|
service: "zaip-aios-dashboard",
|
|
411
424
|
status:
|
|
412
|
-
|
|
425
|
+
manifestState === "initialized" && activeCaptureFailure === null
|
|
426
|
+
? projectionRefreshDiagnostics.healthStatus
|
|
427
|
+
: "degraded",
|
|
413
428
|
api_version: 2,
|
|
414
429
|
workspace_layout: layout.version,
|
|
430
|
+
lifecycle_manifest_state: manifestState,
|
|
415
431
|
read_only: true,
|
|
416
432
|
storage: isSqliteSnapshot ? filesystem.metadata() : { storage_mode: "filesystem" },
|
|
417
433
|
snapshot_state: snapshotState,
|
|
418
434
|
projection_refresh_failure: projectionRefreshDiagnostics.failure,
|
|
419
435
|
active_capture_failure: activeCaptureFailure,
|
|
436
|
+
active_capture: activeCapture,
|
|
420
437
|
});
|
|
421
438
|
} catch (error) {
|
|
422
439
|
return headOrJson(
|
|
@@ -424,6 +441,9 @@ export function createDashboardApp(
|
|
|
424
441
|
{
|
|
425
442
|
kind: RUNTIME_KIND,
|
|
426
443
|
workspaceKey,
|
|
444
|
+
workspace,
|
|
445
|
+
workspace_name: workspaceName,
|
|
446
|
+
server_pid: process.pid,
|
|
427
447
|
service: "zaip-aios-dashboard",
|
|
428
448
|
status: "unavailable",
|
|
429
449
|
api_version: 2,
|
|
@@ -438,7 +458,12 @@ export function createDashboardApp(
|
|
|
438
458
|
// intentionally remains a lightweight process/layout probe.
|
|
439
459
|
app.on(["GET", "HEAD"], `${API_PREFIX}/ready`, async (context) => {
|
|
440
460
|
try {
|
|
441
|
-
const layout = await
|
|
461
|
+
const [layout, manifestState] = await Promise.all([
|
|
462
|
+
readLayout(),
|
|
463
|
+
lifecycleManifestState(canonicalFilesystem),
|
|
464
|
+
]);
|
|
465
|
+
const readinessStatus =
|
|
466
|
+
manifestState === "initialized" && activeCaptureFailure === null ? "ready" : "degraded";
|
|
442
467
|
if (isSqliteSnapshot) {
|
|
443
468
|
const revision = readCommittedSnapshotRevision(workspaceRoot);
|
|
444
469
|
if (observedSnapshotRevision !== null && observedSnapshotRevision !== revision) {
|
|
@@ -453,8 +478,12 @@ export function createDashboardApp(
|
|
|
453
478
|
return headOrJson(context, {
|
|
454
479
|
kind: RUNTIME_KIND,
|
|
455
480
|
workspaceKey,
|
|
456
|
-
|
|
481
|
+
workspace,
|
|
482
|
+
workspace_name: workspaceName,
|
|
483
|
+
server_pid: process.pid,
|
|
484
|
+
status: readinessStatus,
|
|
457
485
|
workspace_layout: layout.version,
|
|
486
|
+
lifecycle_manifest_state: manifestState,
|
|
458
487
|
storage_mode: metadata.storage_mode,
|
|
459
488
|
activity_count: metadata.activity_count,
|
|
460
489
|
// Readiness is only an immutable-generation probe. The default
|
|
@@ -464,6 +493,7 @@ export function createDashboardApp(
|
|
|
464
493
|
snapshot_state: snapshotState,
|
|
465
494
|
projection_refresh_failure: projectionRefreshDiagnostics.failure,
|
|
466
495
|
active_capture_failure: activeCaptureFailure,
|
|
496
|
+
active_capture: activeCapture,
|
|
467
497
|
snapshot_revision: revision,
|
|
468
498
|
});
|
|
469
499
|
}
|
|
@@ -474,8 +504,13 @@ export function createDashboardApp(
|
|
|
474
504
|
return headOrJson(context, {
|
|
475
505
|
kind: RUNTIME_KIND,
|
|
476
506
|
workspaceKey,
|
|
477
|
-
|
|
507
|
+
workspace,
|
|
508
|
+
workspace_name: workspaceName,
|
|
509
|
+
server_pid: process.pid,
|
|
510
|
+
status: readinessStatus,
|
|
511
|
+
lifecycle_manifest_state: manifestState,
|
|
478
512
|
source_latest_at: projection.summary.source_latest_at,
|
|
513
|
+
active_capture: activeCapture,
|
|
479
514
|
});
|
|
480
515
|
} catch (error) {
|
|
481
516
|
return headOrJson(
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { expect, it } from "vitest";
|
|
4
|
+
import { prepareMultiProviderFixture } from "./sqlite-read-model-multi-provider-fixture.js";
|
|
5
|
+
import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
|
|
6
|
+
|
|
7
|
+
it.each([
|
|
8
|
+
"draft",
|
|
9
|
+
"planned",
|
|
10
|
+
"executing",
|
|
11
|
+
"verifying",
|
|
12
|
+
"completed",
|
|
13
|
+
"blocked",
|
|
14
|
+
"cancelled",
|
|
15
|
+
"failed",
|
|
16
|
+
])("preserves measured time, tokens and cost across all cost groupings for canonical Task status %s", async (status) => {
|
|
17
|
+
const parent = resolve(import.meta.dirname, "../../../../../../.tmp/sqlite-read-model-tests");
|
|
18
|
+
await mkdir(parent, { recursive: true });
|
|
19
|
+
const root = await mkdtemp(join(parent, "cost-filter-matrix-"));
|
|
20
|
+
let fs: SqliteReadModelFileSystem | undefined;
|
|
21
|
+
try {
|
|
22
|
+
const { started, usage, finished } = await prepareMultiProviderFixture(root);
|
|
23
|
+
await mkdir(join(root, ".agents/records/tasks/2026/08"), { recursive: true });
|
|
24
|
+
for (const [id, priority] of [
|
|
25
|
+
["TASK-MULTI", "high"],
|
|
26
|
+
["TASK-LOW", "low"],
|
|
27
|
+
]) {
|
|
28
|
+
await writeFile(
|
|
29
|
+
join(root, `.agents/records/tasks/2026/08/${id}.md`),
|
|
30
|
+
`---\nid: ${id}\ntitle: ${id}\nstatus: ${priority === "low" ? status : "completed"}\npriority: ${priority}\nrisk: standard\ncreated_at: 2026-08-04T12:00:00.000Z\n---\n`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const events = [
|
|
34
|
+
{
|
|
35
|
+
...started,
|
|
36
|
+
task_id: "TASK-LOW",
|
|
37
|
+
work_type: "rework",
|
|
38
|
+
agent_invocation_id: "AINV-LOW",
|
|
39
|
+
root_agent_invocation_id: "AINV-LOW",
|
|
40
|
+
execution_id: "EXEC-LOW",
|
|
41
|
+
conversation_id: "CONV-LOW",
|
|
42
|
+
},
|
|
43
|
+
usage(2, "openai", "gpt-a", 7, 3.5),
|
|
44
|
+
{ ...finished, sequence: 3 },
|
|
45
|
+
].map((event, index) => ({
|
|
46
|
+
...event,
|
|
47
|
+
run_id: "RUN-LOW",
|
|
48
|
+
event_id: `RUN-LOW:${index + 1}`,
|
|
49
|
+
occurred_at: index === 0 ? "2026-08-04T18:00:00.000Z" : "2026-08-04T18:01:00.000Z",
|
|
50
|
+
...(event.type === "usage.recorded"
|
|
51
|
+
? {
|
|
52
|
+
source_started_at: "2026-08-04T18:00:00.000Z",
|
|
53
|
+
source_finished_at: "2026-08-04T18:01:00.000Z",
|
|
54
|
+
}
|
|
55
|
+
: {}),
|
|
56
|
+
}));
|
|
57
|
+
await writeFile(
|
|
58
|
+
join(root, ".agents/records/runs/2026/08/RUN-LOW.jsonl"),
|
|
59
|
+
events.map((event) => JSON.stringify(event)).join("\n") + "\n",
|
|
60
|
+
);
|
|
61
|
+
await rebuildSqliteReadModel(root);
|
|
62
|
+
fs = new SqliteReadModelFileSystem(root);
|
|
63
|
+
const summary = fs.costMonitorSummaryAggregate({ from: null, to: null });
|
|
64
|
+
// Summary first paint remains aggregate-only, but its controls retain
|
|
65
|
+
// factual filter choices from the same SQLite population.
|
|
66
|
+
expect(summary.run_metrics).toBeUndefined();
|
|
67
|
+
expect(summary.filters_available).toMatchObject({
|
|
68
|
+
providers: expect.arrayContaining(["anthropic", "openai"]),
|
|
69
|
+
agents: expect.arrayContaining(["agent"]),
|
|
70
|
+
models: expect.arrayContaining(["claude-b", "gpt-a"]),
|
|
71
|
+
statuses: expect.arrayContaining(["completed"]),
|
|
72
|
+
priorities: expect.arrayContaining(["high", "low"]),
|
|
73
|
+
risks: expect.arrayContaining(["standard"]),
|
|
74
|
+
phases: expect.arrayContaining(["execution"]),
|
|
75
|
+
origins: expect.arrayContaining(["task"]),
|
|
76
|
+
work_types: expect.arrayContaining(["new", "rework"]),
|
|
77
|
+
});
|
|
78
|
+
const selectedSummary = fs.costMonitorSummaryAggregate({
|
|
79
|
+
from: null,
|
|
80
|
+
to: null,
|
|
81
|
+
priorities: ["low"],
|
|
82
|
+
risks: ["standard"],
|
|
83
|
+
origins: ["task"],
|
|
84
|
+
workTypes: ["rework"],
|
|
85
|
+
});
|
|
86
|
+
expect(selectedSummary.run_metrics).toBeUndefined();
|
|
87
|
+
expect(selectedSummary.filters_available).toMatchObject({
|
|
88
|
+
priorities: ["low"],
|
|
89
|
+
risks: ["standard"],
|
|
90
|
+
origins: ["task"],
|
|
91
|
+
work_types: ["rework"],
|
|
92
|
+
providers: ["openai"],
|
|
93
|
+
models: ["gpt-a"],
|
|
94
|
+
});
|
|
95
|
+
for (const view of [
|
|
96
|
+
"cost_monitor_daily",
|
|
97
|
+
"cost_monitor_monthly",
|
|
98
|
+
"cost_monitor_annual",
|
|
99
|
+
"cost_monitor_tasks",
|
|
100
|
+
"cost_monitor_executions",
|
|
101
|
+
"cost_monitor_conversations",
|
|
102
|
+
"cost_monitor_zaip_agents",
|
|
103
|
+
"cost_monitor_models",
|
|
104
|
+
"cost_monitor_providers",
|
|
105
|
+
"cost_monitor_agent_invocations",
|
|
106
|
+
] as const) {
|
|
107
|
+
for (const filter of [
|
|
108
|
+
{ priority: "low" },
|
|
109
|
+
{ workType: "rework" },
|
|
110
|
+
{ priority: "low", workType: "rework" },
|
|
111
|
+
{ priority: "low", status },
|
|
112
|
+
{ priority: "low", risk: "standard", origin: "task", status, workType: "rework" },
|
|
113
|
+
]) {
|
|
114
|
+
const page = fs.viewPage(view, filter);
|
|
115
|
+
expect(page.total_count, `${view} ${JSON.stringify(filter)}`).toBeGreaterThan(0);
|
|
116
|
+
const tokens = page.rows.reduce((sum, row) => sum + Number(row.total_tokens ?? 0), 0);
|
|
117
|
+
expect(tokens, `${view} ${JSON.stringify(filter)} tokens`).toBe(7);
|
|
118
|
+
for (const [metric, expected] of Object.entries({
|
|
119
|
+
total_duration: 60_000,
|
|
120
|
+
total_cost_usd: 0.7,
|
|
121
|
+
total_cost_brl: 3.5,
|
|
122
|
+
})) {
|
|
123
|
+
const key =
|
|
124
|
+
view === "cost_monitor_agent_invocations"
|
|
125
|
+
? ({
|
|
126
|
+
total_duration: "duration_ms",
|
|
127
|
+
total_cost_usd: "cost_usd",
|
|
128
|
+
total_cost_brl: "cost_brl",
|
|
129
|
+
}[metric] ?? metric)
|
|
130
|
+
: metric;
|
|
131
|
+
const total = page.rows.reduce((sum, row) => sum + Number(row[key] ?? 0), 0);
|
|
132
|
+
expect(total, `${view} ${JSON.stringify(filter)} ${metric}`).toBeCloseTo(expected, 6);
|
|
133
|
+
}
|
|
134
|
+
expect(fs.viewPage(view, { ...filter, offset: 200 }).rows).toEqual([]);
|
|
135
|
+
}
|
|
136
|
+
expect(fs.viewPage(view, { priority: "high", workType: "rework" }).total_count, view).toBe(0);
|
|
137
|
+
}
|
|
138
|
+
if (status === "blocked") {
|
|
139
|
+
fs.close();
|
|
140
|
+
fs = undefined;
|
|
141
|
+
const unknown = [
|
|
142
|
+
{
|
|
143
|
+
...started,
|
|
144
|
+
task_id: "TASK-LOW",
|
|
145
|
+
agent_invocation_id: "AINV-GAP",
|
|
146
|
+
root_agent_invocation_id: "AINV-GAP",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
...usage(2, "openai", "unknown-model", 5, 0),
|
|
150
|
+
source_started_at: undefined,
|
|
151
|
+
source_finished_at: undefined,
|
|
152
|
+
cost: { usd: null, brl: null, fx_rate: null },
|
|
153
|
+
},
|
|
154
|
+
{ ...finished, sequence: 3, duration_ms: null, duration_provenance: "unavailable" },
|
|
155
|
+
].map((event, index) => ({
|
|
156
|
+
...event,
|
|
157
|
+
run_id: "RUN-GAP",
|
|
158
|
+
event_id: `RUN-GAP:${index + 1}`,
|
|
159
|
+
occurred_at: "2026-08-04T18:02:00.000Z",
|
|
160
|
+
}));
|
|
161
|
+
await writeFile(
|
|
162
|
+
join(root, ".agents/records/runs/2026/08/RUN-GAP.jsonl"),
|
|
163
|
+
unknown.map((event) => JSON.stringify(event)).join("\n") + "\n",
|
|
164
|
+
);
|
|
165
|
+
await rebuildSqliteReadModel(root);
|
|
166
|
+
fs = new SqliteReadModelFileSystem(root);
|
|
167
|
+
for (const view of [
|
|
168
|
+
"cost_monitor_daily",
|
|
169
|
+
"cost_monitor_monthly",
|
|
170
|
+
"cost_monitor_annual",
|
|
171
|
+
] as const) {
|
|
172
|
+
const page = fs.viewPage(view, { priority: "low" });
|
|
173
|
+
expect(page.rows).toHaveLength(1);
|
|
174
|
+
expect(page.rows[0], view).toMatchObject({
|
|
175
|
+
total_tokens: 12,
|
|
176
|
+
total_duration: 60_000,
|
|
177
|
+
duration_known: 60_000,
|
|
178
|
+
duration_unknown: 1,
|
|
179
|
+
total_cost_brl: 3.5,
|
|
180
|
+
});
|
|
181
|
+
expect(page.totals, view).toMatchObject({ total_duration: 60_000, duration_unknown: 1 });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
} finally {
|
|
185
|
+
fs?.close();
|
|
186
|
+
await rm(root, { recursive: true, force: true });
|
|
187
|
+
}
|
|
188
|
+
});
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-summary-details.test.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import { expect, it } from "vitest";
|
|
3
|
+
import { buildCostSummaryDetails } from "./sqlite-cost-summary-details.js";
|
|
4
|
+
import type { SqliteQueryContext } from "./sqlite-query-context.js";
|
|
5
|
+
|
|
6
|
+
it("decodes historical filter dimensions once while preserving canonical status and financial totals", () => {
|
|
7
|
+
const database = new DatabaseSync(":memory:");
|
|
8
|
+
const reads = { usage: 0, task: 0 };
|
|
9
|
+
const population = 1000;
|
|
10
|
+
try {
|
|
11
|
+
database.function("observe_usage", (id) => {
|
|
12
|
+
reads.usage += 1;
|
|
13
|
+
return id;
|
|
14
|
+
});
|
|
15
|
+
database.function("observe_task", (id) => {
|
|
16
|
+
reads.task += 1;
|
|
17
|
+
return id;
|
|
18
|
+
});
|
|
19
|
+
database.exec(`
|
|
20
|
+
CREATE TABLE runs (agent_run_id TEXT, task_id TEXT, model TEXT, provider TEXT,
|
|
21
|
+
total_tokens REAL, cost_usd REAL, cost_brl REAL, zaip_agent TEXT,
|
|
22
|
+
status TEXT, phase TEXT, prd_id TEXT, spec_id TEXT, work_key TEXT);
|
|
23
|
+
CREATE TABLE usage_source (id TEXT, provider TEXT, model TEXT);
|
|
24
|
+
CREATE TABLE task_source (id TEXT, status TEXT, priority TEXT, risk TEXT);
|
|
25
|
+
CREATE VIEW invocation_usage AS SELECT observe_usage(id) AS agent_invocation_id,
|
|
26
|
+
provider, model FROM usage_source;
|
|
27
|
+
CREATE VIEW canonical_work_items AS SELECT 'task' AS entity_kind,
|
|
28
|
+
observe_task(id) AS id, status, priority, risk FROM task_source;
|
|
29
|
+
CREATE TABLE cost_invocation_dimension_facts (agent_invocation_id TEXT,
|
|
30
|
+
model TEXT, total_tokens REAL, cost_usd REAL, cost_brl REAL);
|
|
31
|
+
CREATE INDEX cost_facts_invocation ON cost_invocation_dimension_facts(agent_invocation_id);
|
|
32
|
+
`);
|
|
33
|
+
const run = database.prepare(
|
|
34
|
+
"INSERT INTO runs VALUES (?,?,'model-a','provider-a',100,1,5,'rafa','executing','execution',NULL,NULL,'new')",
|
|
35
|
+
);
|
|
36
|
+
const usage = database.prepare("INSERT INTO usage_source VALUES (?,'provider-a','model-a')");
|
|
37
|
+
const task = database.prepare(
|
|
38
|
+
"INSERT INTO task_source VALUES (?,'completed','high','standard')",
|
|
39
|
+
);
|
|
40
|
+
const fact = database.prepare(
|
|
41
|
+
"INSERT INTO cost_invocation_dimension_facts VALUES (?,'model-a',80,0.8,4)",
|
|
42
|
+
);
|
|
43
|
+
for (let index = 0; index < population; index += 1) {
|
|
44
|
+
run.run(`run-${index}`, `task-${index}`);
|
|
45
|
+
usage.run(`run-${index}`);
|
|
46
|
+
task.run(`task-${index}`);
|
|
47
|
+
fact.run(`run-${index}`);
|
|
48
|
+
}
|
|
49
|
+
database.exec(
|
|
50
|
+
"INSERT INTO runs VALUES (NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'blocked','conversation',NULL,NULL,'rework')",
|
|
51
|
+
);
|
|
52
|
+
const details = buildCostSummaryDetails(
|
|
53
|
+
{ database } as SqliteQueryContext,
|
|
54
|
+
"WITH selected AS MATERIALIZED (SELECT * FROM runs)",
|
|
55
|
+
[],
|
|
56
|
+
(value) => (typeof value === "number" ? value : 0),
|
|
57
|
+
(value) => (typeof value === "number" ? value : null),
|
|
58
|
+
);
|
|
59
|
+
expect(details.filters_available).toEqual({
|
|
60
|
+
providers: ["provider-a", "unavailable"],
|
|
61
|
+
models: ["model-a", "unavailable"],
|
|
62
|
+
agents: ["rafa"],
|
|
63
|
+
statuses: ["blocked", "completed"],
|
|
64
|
+
priorities: ["high", "none"],
|
|
65
|
+
risks: ["none", "standard"],
|
|
66
|
+
phases: ["conversation", "execution"],
|
|
67
|
+
origins: ["conversation", "task"],
|
|
68
|
+
work_types: ["new", "rework"],
|
|
69
|
+
});
|
|
70
|
+
expect(details.model_groups.find((group) => group.key === "model-a")).toMatchObject({
|
|
71
|
+
total_tokens: population * 80,
|
|
72
|
+
estimated_brl: population * 4,
|
|
73
|
+
});
|
|
74
|
+
expect(details.model_groups.find((group) => group.key === "unavailable")).toMatchObject({
|
|
75
|
+
total_tokens: population * 20,
|
|
76
|
+
estimated_brl: population,
|
|
77
|
+
});
|
|
78
|
+
// Count decoded rows, not elapsed time: an inlined view causes quadratic
|
|
79
|
+
// nested scans even on a fast machine and must fail this regression.
|
|
80
|
+
expect(reads.usage).toBe(population);
|
|
81
|
+
expect(reads.task).toBe(population);
|
|
82
|
+
} finally {
|
|
83
|
+
database.close();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { CostSummarySource } from "@zaip-ai/dashboard-cost-monitor/server";
|
|
2
|
+
import type { SqliteQueryContext } from "./sqlite-query-context.js";
|
|
3
|
+
|
|
4
|
+
type NumberValue = (value: unknown) => number;
|
|
5
|
+
type NullableValue = (value: unknown) => number | null;
|
|
6
|
+
type CostSummaryDetails = {
|
|
7
|
+
model_groups: NonNullable<CostSummarySource["model_groups"]>;
|
|
8
|
+
filters_available: NonNullable<CostSummarySource["filters_available"]>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function buildCostSummaryDetails(
|
|
12
|
+
context: SqliteQueryContext,
|
|
13
|
+
selected: string,
|
|
14
|
+
values: readonly (string | number | null)[],
|
|
15
|
+
number: NumberValue,
|
|
16
|
+
nullable: NullableValue,
|
|
17
|
+
): CostSummaryDetails {
|
|
18
|
+
const summaryModelRows = context.database
|
|
19
|
+
.prepare(`${selected},
|
|
20
|
+
segment_totals AS (
|
|
21
|
+
SELECT agent_invocation_id, SUM(total_tokens) AS total_tokens,
|
|
22
|
+
SUM(cost_usd) AS cost_usd, SUM(cost_brl) AS cost_brl
|
|
23
|
+
FROM cost_invocation_dimension_facts
|
|
24
|
+
WHERE total_tokens IS NOT NULL OR cost_usd IS NOT NULL OR cost_brl IS NOT NULL
|
|
25
|
+
GROUP BY agent_invocation_id
|
|
26
|
+
), components AS (
|
|
27
|
+
-- Agent facts can contain several observed models. Attribute their
|
|
28
|
+
-- financial components to the model segment, never to a mixed parent.
|
|
29
|
+
SELECT CASE WHEN f.model IS NULL OR trim(f.model) = '' OR lower(f.model) IN ('unavailable', 'unknown', 'mixed')
|
|
30
|
+
THEN 'unavailable' ELSE f.model END AS key,
|
|
31
|
+
SUM(f.total_tokens) AS total_tokens, SUM(f.cost_usd) AS total_cost_usd,
|
|
32
|
+
SUM(f.cost_brl) AS total_cost_brl
|
|
33
|
+
FROM selected s JOIN cost_invocation_dimension_facts f
|
|
34
|
+
ON f.agent_invocation_id=s.agent_run_id
|
|
35
|
+
WHERE s.agent_run_id IS NOT NULL
|
|
36
|
+
GROUP BY key
|
|
37
|
+
UNION ALL
|
|
38
|
+
-- Non-agent financial facts have no invocation segments, so their
|
|
39
|
+
-- observed model remains the only factual dimension.
|
|
40
|
+
SELECT CASE WHEN model IS NULL OR trim(model) = '' OR lower(model) IN ('unavailable', 'unknown', 'mixed')
|
|
41
|
+
THEN 'unavailable' ELSE model END AS key,
|
|
42
|
+
SUM(total_tokens), SUM(cost_usd), SUM(cost_brl)
|
|
43
|
+
FROM selected WHERE agent_run_id IS NULL GROUP BY key
|
|
44
|
+
UNION ALL
|
|
45
|
+
-- Preserve any consolidated invocation remainder as Sem dimensão so
|
|
46
|
+
-- the model chart reconciles to the same financial population.
|
|
47
|
+
SELECT 'unavailable' AS key,
|
|
48
|
+
SUM(s.total_tokens - COALESCE(st.total_tokens, 0)),
|
|
49
|
+
SUM(s.cost_usd - COALESCE(st.cost_usd, 0)),
|
|
50
|
+
SUM(s.cost_brl - COALESCE(st.cost_brl, 0))
|
|
51
|
+
FROM selected s LEFT JOIN segment_totals st ON st.agent_invocation_id=s.agent_run_id
|
|
52
|
+
WHERE s.agent_run_id IS NOT NULL
|
|
53
|
+
AND (s.total_tokens <> COALESCE(st.total_tokens, 0)
|
|
54
|
+
OR s.cost_usd <> COALESCE(st.cost_usd, 0)
|
|
55
|
+
OR s.cost_brl <> COALESCE(st.cost_brl, 0))
|
|
56
|
+
)
|
|
57
|
+
SELECT key, 0 AS invocation_count, NULL AS task_count,
|
|
58
|
+
NULL AS total_duration, 0 AS duration_unknown, 0 AS duration_known,
|
|
59
|
+
0 AS source_event_count, SUM(total_tokens) AS total_tokens,
|
|
60
|
+
SUM(total_cost_usd) AS total_cost_usd, SUM(total_cost_brl) AS total_cost_brl
|
|
61
|
+
FROM components GROUP BY key ORDER BY total_cost_brl DESC, key`)
|
|
62
|
+
.all(...values) as Array<Record<string, unknown>>;
|
|
63
|
+
const model_groups = summaryModelRows.map((row) => {
|
|
64
|
+
const duration = nullable(row.total_duration);
|
|
65
|
+
const durationUnknown = number(row.duration_unknown);
|
|
66
|
+
const durationKnown = nullable(row.duration_known) ?? duration ?? 0;
|
|
67
|
+
return {
|
|
68
|
+
key: String(row.key ?? "unavailable"),
|
|
69
|
+
label: String(row.label ?? row.key ?? "unavailable"),
|
|
70
|
+
latest_started_at: "",
|
|
71
|
+
run_count: number(row.invocation_count),
|
|
72
|
+
task_count: nullable(row.task_count),
|
|
73
|
+
prd_count: 0,
|
|
74
|
+
spec_count: 0,
|
|
75
|
+
evidence_count: 0,
|
|
76
|
+
test_count: 0,
|
|
77
|
+
event_count: number(row.source_event_count),
|
|
78
|
+
total_tokens: nullable(row.total_tokens),
|
|
79
|
+
estimated_usd: nullable(row.total_cost_usd),
|
|
80
|
+
estimated_brl: nullable(row.total_cost_brl),
|
|
81
|
+
duration_ms: duration,
|
|
82
|
+
duration: {
|
|
83
|
+
known_sum: durationKnown,
|
|
84
|
+
unknown: durationUnknown,
|
|
85
|
+
complete: durationUnknown === 0,
|
|
86
|
+
coverage_ratio: durationUnknown === 0 ? 1 : 0,
|
|
87
|
+
},
|
|
88
|
+
coverage: { events: 0, tokens: 0, usd: 0, brl: 0 },
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
const availabilityRows = context.database
|
|
92
|
+
.prepare(`${selected},
|
|
93
|
+
usage AS MATERIALIZED (
|
|
94
|
+
SELECT agent_invocation_id, provider, model FROM invocation_usage
|
|
95
|
+
), canonical_tasks AS MATERIALIZED (
|
|
96
|
+
SELECT id, status, priority, risk FROM canonical_work_items WHERE entity_kind='task'
|
|
97
|
+
), dimensions AS (
|
|
98
|
+
SELECT 'providers' AS dimension, COALESCE(NULLIF(trim(u.provider), ''), 'unavailable') AS value
|
|
99
|
+
FROM selected s JOIN usage u ON u.agent_invocation_id=s.agent_run_id
|
|
100
|
+
UNION ALL
|
|
101
|
+
SELECT 'models', COALESCE(NULLIF(trim(u.model), ''), 'unavailable')
|
|
102
|
+
FROM selected s JOIN usage u ON u.agent_invocation_id=s.agent_run_id
|
|
103
|
+
UNION ALL
|
|
104
|
+
SELECT 'providers', COALESCE(NULLIF(trim(s.provider), ''), 'unavailable')
|
|
105
|
+
FROM selected s WHERE s.agent_run_id IS NULL
|
|
106
|
+
UNION ALL
|
|
107
|
+
SELECT 'models', COALESCE(NULLIF(trim(s.model), ''), 'unavailable')
|
|
108
|
+
FROM selected s WHERE s.agent_run_id IS NULL
|
|
109
|
+
UNION ALL
|
|
110
|
+
SELECT 'agents', NULLIF(trim(s.zaip_agent), '') FROM selected s
|
|
111
|
+
UNION ALL
|
|
112
|
+
SELECT 'statuses', COALESCE(NULLIF(trim(task.status), ''), NULLIF(trim(s.status), ''), 'none')
|
|
113
|
+
FROM selected s LEFT JOIN canonical_tasks task ON task.id=s.task_id
|
|
114
|
+
UNION ALL
|
|
115
|
+
SELECT 'priorities', COALESCE(NULLIF(trim(task.priority), ''), 'none')
|
|
116
|
+
FROM selected s LEFT JOIN canonical_tasks task ON task.id=s.task_id
|
|
117
|
+
UNION ALL
|
|
118
|
+
SELECT 'risks', COALESCE(NULLIF(trim(task.risk), ''), 'none')
|
|
119
|
+
FROM selected s LEFT JOIN canonical_tasks task ON task.id=s.task_id
|
|
120
|
+
UNION ALL
|
|
121
|
+
SELECT 'phases', NULLIF(trim(s.phase), '') FROM selected s
|
|
122
|
+
UNION ALL
|
|
123
|
+
SELECT 'origins', CASE WHEN s.prd_id IS NOT NULL THEN 'prd'
|
|
124
|
+
WHEN s.spec_id IS NOT NULL THEN 'spec' WHEN s.task_id IS NOT NULL THEN 'task'
|
|
125
|
+
ELSE 'conversation' END FROM selected s
|
|
126
|
+
UNION ALL
|
|
127
|
+
SELECT 'work_types', NULLIF(trim(s.work_key), '') FROM selected s
|
|
128
|
+
) SELECT dimension, value FROM dimensions WHERE value IS NOT NULL GROUP BY dimension, value
|
|
129
|
+
ORDER BY dimension, value`)
|
|
130
|
+
.all(...values) as Array<{ dimension: string; value: string }>;
|
|
131
|
+
const filters_available: Required<NonNullable<CostSummarySource["filters_available"]>> = {
|
|
132
|
+
providers: [],
|
|
133
|
+
agents: [],
|
|
134
|
+
models: [],
|
|
135
|
+
statuses: [],
|
|
136
|
+
priorities: [],
|
|
137
|
+
risks: [],
|
|
138
|
+
phases: [],
|
|
139
|
+
origins: [],
|
|
140
|
+
work_types: [],
|
|
141
|
+
};
|
|
142
|
+
for (const row of availabilityRows) {
|
|
143
|
+
const dimension = row.dimension as keyof typeof filters_available;
|
|
144
|
+
if (dimension in filters_available) filters_available[dimension].push(row.value);
|
|
145
|
+
}
|
|
146
|
+
return { model_groups, filters_available };
|
|
147
|
+
}
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.test.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import {
|
|
4
|
+
hasReconciledMacroDistributions,
|
|
5
|
+
readFirstFoldAllTime,
|
|
6
|
+
} from "./sqlite-first-fold-cache.js";
|
|
7
|
+
import type { SqliteFirstFoldAllTime } from "./sqlite-read-model-first-fold-types.js";
|
|
8
|
+
|
|
9
|
+
function cachedFirstFold(
|
|
10
|
+
specs: { entityCount: number; statusCount: number; classificationCount: number },
|
|
11
|
+
prds: { entityCount: number; statusCount: number; classificationCount: number },
|
|
12
|
+
) {
|
|
13
|
+
const macro = (item: {
|
|
14
|
+
entityCount: number;
|
|
15
|
+
statusCount: number;
|
|
16
|
+
classificationCount: number;
|
|
17
|
+
}) => ({
|
|
18
|
+
entity_count: item.entityCount,
|
|
19
|
+
status_counts: { executing: item.statusCount },
|
|
20
|
+
classification_counts: { structured: item.classificationCount },
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
macro_metrics: { specs: macro(specs), prds: macro(prds) },
|
|
24
|
+
} as unknown as SqliteFirstFoldAllTime;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe("first-fold all-time cache", () => {
|
|
28
|
+
it("rejects a legacy macro cache that would render zero panels beside populated cards", () => {
|
|
29
|
+
expect(
|
|
30
|
+
hasReconciledMacroDistributions(
|
|
31
|
+
cachedFirstFold(
|
|
32
|
+
{ entityCount: 66, statusCount: 0, classificationCount: 0 },
|
|
33
|
+
{ entityCount: 16, statusCount: 0, classificationCount: 0 },
|
|
34
|
+
),
|
|
35
|
+
),
|
|
36
|
+
).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("accepts fully reconciled SPEC and PRD panels", () => {
|
|
40
|
+
expect(
|
|
41
|
+
hasReconciledMacroDistributions(
|
|
42
|
+
cachedFirstFold(
|
|
43
|
+
{ entityCount: 66, statusCount: 66, classificationCount: 66 },
|
|
44
|
+
{ entityCount: 16, statusCount: 16, classificationCount: 16 },
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("rejects malformed legacy count maps before summing them", () => {
|
|
51
|
+
const legacy = cachedFirstFold(
|
|
52
|
+
{ entityCount: 1, statusCount: 1, classificationCount: 1 },
|
|
53
|
+
{ entityCount: 1, statusCount: 1, classificationCount: 1 },
|
|
54
|
+
) as unknown as { macro_metrics: { specs: { status_counts: unknown } } };
|
|
55
|
+
legacy.macro_metrics.specs.status_counts = undefined;
|
|
56
|
+
|
|
57
|
+
expect(hasReconciledMacroDistributions(legacy as unknown as SqliteFirstFoldAllTime)).toBe(
|
|
58
|
+
false,
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("recomputes a persisted legacy payload whose macro panels are missing", () => {
|
|
63
|
+
const database = new DatabaseSync(":memory:");
|
|
64
|
+
try {
|
|
65
|
+
database.exec(`
|
|
66
|
+
CREATE TABLE zaip_aios_activities (payload_type TEXT, payload_json TEXT, recorded_at TEXT);
|
|
67
|
+
INSERT INTO zaip_aios_activities VALUES ('first_fold_all_time_cache', '{"aggregate":{}}', '2026-09-15T00:00:00.000Z');
|
|
68
|
+
CREATE VIEW zaip_vw_first_fold_overview_all_time AS SELECT 0 AS task_count, 0 AS completed_task_count, 1 AS spec_count, 0 AS completed_spec_count, 1 AS prd_count, 0 AS completed_prd_count, 0 AS total_run_count, 0 AS agent_invocation_count, NULL AS llm_call_count, NULL AS total_duration_ms, NULL AS total_tokens, NULL AS total_cost_usd, NULL AS total_cost_brl, 0 AS execution_day_count, NULL AS latest_task_created_at, NULL AS start_day, NULL AS end_day;
|
|
69
|
+
CREATE VIEW zaip_vw_first_fold_task_status_all_time AS SELECT 'draft' AS status, 0 AS task_count WHERE 0;
|
|
70
|
+
CREATE VIEW zaip_vw_first_fold_task_risk_all_time AS SELECT 'standard' AS risk, 0 AS task_count WHERE 0;
|
|
71
|
+
CREATE VIEW zaip_vw_first_fold_top_tasks_all_time AS SELECT 1 AS rank WHERE 0;
|
|
72
|
+
CREATE VIEW zaip_vw_first_fold_task_metrics_all_time AS SELECT NULL AS average_duration_ms_per_task, NULL AS average_tokens_per_task, NULL AS average_cost_usd_per_task, NULL AS average_cost_brl_per_task, NULL AS latest_task_created_at;
|
|
73
|
+
CREATE VIEW zaip_vw_first_fold_spec_status_all_time AS SELECT 'executing' AS stage, 1 AS entity_count;
|
|
74
|
+
CREATE VIEW zaip_vw_first_fold_prd_status_all_time AS SELECT 'executing' AS stage, 1 AS entity_count;
|
|
75
|
+
CREATE VIEW zaip_vw_first_fold_spec_classification_all_time AS SELECT 'structured' AS classification, 1 AS entity_count;
|
|
76
|
+
CREATE VIEW zaip_vw_first_fold_prd_classification_all_time AS SELECT 'structured' AS classification, 1 AS entity_count;
|
|
77
|
+
CREATE VIEW zaip_vw_first_fold_spec_metrics_all_time AS SELECT 1 AS entity_count, 0 AS total_run_count, NULL AS total_duration_ms, NULL AS total_tokens, NULL AS total_cost_usd, NULL AS total_cost_brl, NULL AS average_duration_ms, NULL AS average_tokens, NULL AS average_cost_usd, NULL AS average_cost_brl, NULL AS latest_created_at;
|
|
78
|
+
CREATE VIEW zaip_vw_first_fold_prd_metrics_all_time AS SELECT 1 AS entity_count, 0 AS total_run_count, NULL AS total_duration_ms, NULL AS total_tokens, NULL AS total_cost_usd, NULL AS total_cost_brl, NULL AS average_duration_ms, NULL AS average_tokens, NULL AS average_cost_usd, NULL AS average_cost_brl, NULL AS latest_created_at;
|
|
79
|
+
CREATE VIEW zaip_vw_first_fold_top_specs_all_time AS SELECT 1 AS rank WHERE 0;
|
|
80
|
+
CREATE VIEW zaip_vw_first_fold_top_prds_all_time AS SELECT 1 AS rank WHERE 0;
|
|
81
|
+
`);
|
|
82
|
+
const rebuilt = readFirstFoldAllTime(database, () => 0);
|
|
83
|
+
|
|
84
|
+
expect(rebuilt.macro_metrics.specs).toMatchObject({
|
|
85
|
+
entity_count: 1,
|
|
86
|
+
status_counts: { executing: 1 },
|
|
87
|
+
classification_counts: { structured: 1 },
|
|
88
|
+
});
|
|
89
|
+
expect(rebuilt.macro_metrics.prds.entity_count).toBe(1);
|
|
90
|
+
} finally {
|
|
91
|
+
database.close();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
});
|