@zaip-ai/cli 2.6.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -13
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +5 -2
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/agent-adapters.js +12 -9
- package/dist/services/agent-adapters.js.map +1 -1
- package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
- package/dist/services/codex-conversation-lifecycle-hook.js +32 -21
- package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
- package/dist/services/install-agents-template.js +9 -1
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/runtime-template.test.js +25 -2
- package/dist/services/runtime-template.test.js.map +1 -1
- package/dist/services/transactional-files.d.ts.map +1 -1
- package/dist/services/transactional-files.js +59 -14
- package/dist/services/transactional-files.js.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/README-ENG.md +75 -10
- package/templates/.agents/README.md +76 -10
- package/templates/.agents/config/agents/catalog.yaml +3 -0
- package/templates/.agents/config/agents/discovery.json +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-analyst.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-auditor.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-data-analyst.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +2 -2
- package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-integrator.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +13 -10
- package/templates/.agents/config/clients/codex/agents/zaip-agent-refactoring-specialist.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-reviewer.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-security-auditor.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-writer.toml +1 -1
- package/templates/.agents/config/project.yaml +10 -1
- package/templates/.agents/dashboard/.zaip-managed.json +274 -138
- package/templates/.agents/dashboard/README.md +16 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-CGxeQak4.js → CostCalculationGuidePage-CEDZjl4V.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-tzS7YxYB.js → DashboardHelpDialog-DIWDmvAS.js} +930 -550
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-DEbCi1gP.js → PricingSettingsDialog-BBRBKaHa.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-B9GWkEyN.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BAvLPAee.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-t1Om0Abw.js → TraceabilityWorkspace-C9dDhj34.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-06__WZco.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/dashboard-localization-CoAVMZN6.js +828 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DiGC-dsJ.js → icons-vendor-DEmo6Tn2.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-BVzw_Wux.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-kPO6yNed.js → react-vendor-CadYsm83.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-BzKK8kK3.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/AppDashboardContent.tsx +10 -5
- package/templates/.agents/dashboard/apps/frontend/src/AutonomySettings.tsx +82 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.dom.test.ts +38 -7
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +164 -171
- package/templates/.agents/dashboard/apps/frontend/src/__tests__/app-composition-support.ts +6 -1
- package/templates/.agents/dashboard/apps/frontend/src/cost-monitor-population.test.tsx +149 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api-settings.ts +2 -1
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +19 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +22 -1
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-cost-facts.test.ts +54 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-cost-facts.ts +20 -2
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.test.ts +37 -43
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +9 -251
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-project-overview.ts +34 -7
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-view-actions.test.ts +51 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-view-actions.ts +3 -1
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +35 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +19 -4
- package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +5 -3
- package/templates/.agents/dashboard/apps/frontend/src/project-installation-status.test.ts +112 -23
- package/templates/.agents/dashboard/apps/frontend/src/project-installation-status.ts +49 -12
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-copy.ts +181 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +11 -1
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +34 -51
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-state.css +55 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +12 -0
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.ts +1 -2
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +6 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +2 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +3 -1
- package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-task-pagination.ts +4 -15
- package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-app-model.tsx +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/complete-cost-average.test.ts +73 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +9 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/period-averages.ts +60 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +8 -22
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +2 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostPeriodAverageCards.tsx +32 -8
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +3 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +1 -42
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +2 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +3 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +8 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview-keeps-structure-classes-mutually-exclusive.test.ts +4 -3
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +66 -3
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +71 -1
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +36 -30
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +5 -14
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +3 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OverviewCostKpi.tsx +46 -0
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +28 -1
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +11 -4
- package/templates/.agents/dashboard/modules/operations/src/react/index.ts +1 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +2 -2
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +28 -8
- package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +19 -2
- package/templates/.agents/dashboard/modules/operations/src/react/overview-cost-card.test.tsx +89 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +3 -3
- package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +2 -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 +279 -245
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +247 -215
- package/templates/.agents/dashboard/packages/local-runtime/package.json +2 -2
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +15 -25
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +279 -245
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/project-installation-summary.test.ts +142 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/project-installation-summary.ts +190 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +65 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +67 -66
- package/templates/.agents/dashboard/packages/local-runtime/src/server-browser-lease.test.ts +91 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-browser-lease.ts +24 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/server-hono-security.test.ts +17 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-routes.ts +21 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +94 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.ts +62 -12
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.test.ts +26 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +4 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.test.ts +97 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.ts +10 -13
- package/templates/.agents/dashboard/packages/local-runtime/src/server-trace-routes.ts +2 -10
- package/templates/.agents/dashboard/packages/local-runtime/src/server-traceability-index.test.ts +84 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +15 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-calendar.ts +17 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cold-parse.test.ts +78 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.test.ts +12 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.test.ts +94 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts +5 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-duration-lookup.test.ts +59 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-entity-label-views.test.ts +72 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-file-index.test.ts +69 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +3 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-force-canonical.test.ts +3 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-refresh.test.ts +2 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-projections.ts +9 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-runs.ts +4 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-period-averages.ts +46 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-provider-alias-parity.test.ts +50 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.test.ts +171 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.ts +36 -16
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-filtered-dimension.ts +13 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +25 -7
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-temporal-dimension.ts +2 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical-parsing.ts +7 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +5 -15
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +34 -10
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-filesystem.ts +17 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-keeps-orphan-telemetry-out-kanban-without.test.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +11 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +5 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.test.ts +54 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +7 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +4 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-risk-population.test.ts +98 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-base-views.ts +29 -16
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts +2 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +2 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/verify-project-settings.mjs +57 -0
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/scripts/qualify-observability.mjs +130 -0
- package/templates/.agents/dashboard/scripts/verify-autonomy-settings.mjs +175 -0
- package/templates/.agents/dashboard/scripts/verify-observability.mjs +254 -0
- package/templates/.agents/dashboard/scripts/verify-project-setup.mjs +64 -0
- package/templates/.agents/dashboard/tests/e2e/lease-global-setup.ts +37 -0
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +5 -3
- package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-period-transition.spec.ts +22 -1
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +17 -8
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +47 -6
- package/templates/.agents/dashboard/tests/e2e/specs/lease-lifetime.spec.ts +14 -0
- package/templates/.agents/dashboard/tests/observability-fixture.mjs +200 -0
- package/templates/.agents/design/.zaip-managed.json +84 -40
- package/templates/.agents/design/apps/catalog/dist/assets/index-BJV597iq.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-BOjCcUaU.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-B_WhrCZe.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-CqtYXZfV.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-D_lfqoyx.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-i_PO2k9R.js +9 -0
- package/templates/.agents/design/apps/catalog/dist/index.html +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-Cstn1UwA.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Color-6AOWCN3U-B-kAgAjB.js → Color-6AOWCN3U-Cm-yJJz_.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-D1WopB2L.js +137 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DQ9PJ3N3.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DocsRenderer-JROSPFPF-BVN7xHtv.js → DocsRenderer-JROSPFPF-Belk4jRr.js} +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WithTooltip-7X4HQR7L-CDHtKYkz.js → WithTooltip-7X4HQR7L-DoPvjkS1.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-DRQKCCAG-D6AsDkMK.js → chunk-DRQKCCAG-B1itKXEN.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-W22LQPXL-B4m5uloN.js → chunk-W22LQPXL-C-Eb5SPY.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{components-CN8YyTUg.js → components-DnyKLwhj.js} +5 -5
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-D0OSgxWz.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{iframe-9yZfIsdT.js → iframe-DcXBsFPz.js} +3 -3
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{react-18-BoCSnq6H.js → react-18-CRM89QRf.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-C3tkVMIp.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{syntaxhighlighter-YFXUGROL-Bnn_nMwJ.js → syntaxhighlighter-YFXUGROL-B03jQGTF.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{theming-DS_ue2sb.js → theming-4ZyufAga.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/iframe.html +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/index.json +1 -1
- package/templates/.agents/design/apps/catalog/package.json +2 -2
- package/templates/.agents/design/apps/catalog/src/components/AutonomySpecimen.tsx +15 -0
- package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.test.tsx +19 -0
- package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.tsx +45 -0
- package/templates/.agents/design/apps/catalog/src/components/EstimatedCostSpecimen.tsx +48 -0
- package/templates/.agents/design/apps/catalog/src/components/ProjectStatusSpecimen.tsx +169 -0
- package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +55 -0
- package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +60 -0
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +1 -1
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +5 -5
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/rules/astra-diagnostic.md +3 -1
- package/templates/.agents/rules/autonomy-decision.md +10 -2
- package/templates/.agents/rules/core.md +12 -1
- package/templates/.agents/rules/run-lifecycle-closure.md +8 -6
- package/templates/.agents/rules/workflow.md +2 -2
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +383 -350
- package/templates/.agents/runtime/checksums.sha256 +6 -6
- package/templates/.agents/runtime/manifest.json +1 -1
- package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
- package/templates/.agents/runtime/provenance.json +5 -5
- package/templates/.agents/runtime/sbom.cdx.json +3 -3
- package/templates/.agents/skills/zaip-skill-dev-environment/SKILL.md +2 -0
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +28 -5
- package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +17 -3
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +8 -9
- package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +10 -6
- package/templates/.agents/skills/zaip-skill-github-deploy/references/release-identity.md +17 -12
- package/templates/.agents/skills/zaip-skill-move-prd/SKILL.md +2 -0
- package/templates/.agents/skills/zaip-skill-prd/SKILL.md +2 -0
- package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +21 -23
- package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +37 -13
- package/templates/.agents/skills/zaip-skill-setup/SKILL.md +2 -0
- package/templates/.agents/skills/zaip-skill-tool-setup/SKILL.md +2 -0
- package/templates/.agents/zaip-aios/INDEX.md +9 -1
- package/templates/.agents/zaip-aios/README.md +24 -2
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/01-primeiros-passos.md +5 -1
- package/templates/.agents/zaip-aios/guides/03-tasks.md +15 -2
- package/templates/.agents/zaip-aios/guides/04-specs.md +13 -0
- package/templates/.agents/zaip-aios/guides/05-prds.md +13 -0
- package/templates/.agents/zaip-aios/guides/06-execucao.md +19 -4
- package/templates/.agents/zaip-aios/guides/07-revisao-e-validacao.md +14 -0
- package/templates/.agents/zaip-aios/guides/08-contexto-e-tokens.md +4 -3
- package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +17 -9
- package/templates/.agents/zaip-aios/guides/10-seguranca.md +9 -0
- package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +69 -0
- package/templates/.agents/zaip-aios/guides/12-instalacao-e-upgrade.md +9 -4
- package/templates/.agents/zaip-aios/guides/13-boas-praticas.md +7 -1
- package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +18 -0
- package/templates/.agents/zaip-aios/guides/16-lifecycle-e-reconciliacao.md +54 -3
- package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +10 -2
- package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +186 -5
- package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +21 -15
- package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +18 -2
- package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +14 -2
- package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +190 -489
- package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +72 -13
- package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +18 -0
- package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +18 -1
- package/templates/template-manifest.json +454 -274
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-1L7Qw-Gq.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-EInWr641.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-B6aZfo5f.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/dashboard-localization-CLJ0lT9v.js +0 -231
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DgTmNHN5.js +0 -2
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DQpKX9c1.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-BWY-80s4.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-Be2mDUQj.js +0 -27
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DRx9blDs.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-EwuTh8Zk.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-DyL61NPT.js +0 -1
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
saoPauloDay,
|
|
18
18
|
type TemporalInterval,
|
|
19
19
|
} from "./sqlite-read-model-canonical.js";
|
|
20
|
+
import { isCanonicalLifecyclePath } from "./sqlite-read-model-canonical-parsing.js";
|
|
20
21
|
import { reportSqliteReadModelLaunchProgress } from "./sqlite-read-model-launch-progress.js";
|
|
21
22
|
import {
|
|
22
23
|
hasReusableSnapshotPayloads,
|
|
@@ -596,6 +597,7 @@ export async function rebuildSqliteReadModel(
|
|
|
596
597
|
() => [...readCanonicalEntities([row])],
|
|
597
598
|
))
|
|
598
599
|
if (entity.creationRunId) changedCreationRunIds.add(entity.creationRunId);
|
|
600
|
+
reportLaunchProgress("projection_entities", 75, "Entidades canônicas interpretadas.");
|
|
599
601
|
const insertCanonicalWorkItem = database.prepare(
|
|
600
602
|
"INSERT INTO canonical_work_items(entity_kind, id, title, status, stage, risk, spec_id, change_id, creation_run_id, completed_run_id, occurred_at, occurred_day_sp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
601
603
|
);
|
|
@@ -627,6 +629,7 @@ export async function rebuildSqliteReadModel(
|
|
|
627
629
|
decisions: [] as CanonicalDecision[],
|
|
628
630
|
};
|
|
629
631
|
for (const row of canonicalRows) {
|
|
632
|
+
if (!isCanonicalLifecyclePath(row.path)) continue;
|
|
630
633
|
const parsed = parsedSources.read("lifecycle", row.path, sourceHashFor(row.path), () =>
|
|
631
634
|
readCanonicalLifecycleRecords([row]),
|
|
632
635
|
);
|
|
@@ -645,6 +648,7 @@ export async function rebuildSqliteReadModel(
|
|
|
645
648
|
canonicalLifecycle.decisions = [
|
|
646
649
|
...new Map(canonicalLifecycle.decisions.map((item) => [item.id, item])).values(),
|
|
647
650
|
];
|
|
651
|
+
reportLaunchProgress("projection_lifecycle", 76, "Registros de ciclo de vida interpretados.");
|
|
648
652
|
const insertCanonicalExecution = database.prepare(
|
|
649
653
|
"INSERT INTO canonical_executions(id, status, kind, origin_type, origin_id, created_at, occurred_day_sp, finished_at, source_path) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
650
654
|
);
|
|
@@ -695,6 +699,7 @@ export async function rebuildSqliteReadModel(
|
|
|
695
699
|
saoPauloDay(entity.createdAt),
|
|
696
700
|
entity.sourcePath,
|
|
697
701
|
);
|
|
702
|
+
reportLaunchProgress("projection_runs_started", 77, "Construindo fatos das invocações.");
|
|
698
703
|
const runMaterialization = materializeCanonicalRuns({
|
|
699
704
|
database,
|
|
700
705
|
previousActivities,
|
|
@@ -712,6 +717,11 @@ export async function rebuildSqliteReadModel(
|
|
|
712
717
|
// Run canonical and attach deterministic shares only to the macro read
|
|
713
718
|
// model. Payload rows stay outside `activities`, preventing global
|
|
714
719
|
// Run/Cost totals from counting that Run more than once.
|
|
720
|
+
reportLaunchProgress(
|
|
721
|
+
"projection_dimensions_started",
|
|
722
|
+
78,
|
|
723
|
+
"Construindo dimensões e agregados.",
|
|
724
|
+
);
|
|
715
725
|
materializeDashboardProjections({
|
|
716
726
|
...runMaterialization,
|
|
717
727
|
database,
|
|
@@ -722,6 +732,7 @@ export async function rebuildSqliteReadModel(
|
|
|
722
732
|
skipped,
|
|
723
733
|
fingerprint,
|
|
724
734
|
});
|
|
735
|
+
reportLaunchProgress("projection_overview_started", 79, "Construindo a visão geral.");
|
|
725
736
|
refreshFirstFoldPayloads(workspaceRoot, database);
|
|
726
737
|
database.exec("COMMIT;");
|
|
727
738
|
reportLaunchProgress(
|
|
@@ -4,10 +4,9 @@ import { DatabaseSync } from "node:sqlite";
|
|
|
4
4
|
import { hasRequiredFirstFoldPayloads } from "./sqlite-first-fold-persistence.js";
|
|
5
5
|
import type { SqliteReadModelSourceCheckpoint } from "./sqlite-read-model-source-fingerprint.js";
|
|
6
6
|
export const dbRelativePath = ".local/sqlite/zaip-aios-dashboard.sqlite";
|
|
7
|
-
// Schema
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
export const readModelSchemaVersion = "75";
|
|
7
|
+
// Schema 79 installs bounded execution/conversation label views and shared daily groups.
|
|
8
|
+
// Old snapshots must rebuild even when their canonical hashes still match.
|
|
9
|
+
export const readModelSchemaVersion = "79";
|
|
11
10
|
export const requiredPersistedTables = [
|
|
12
11
|
"zaip_aios_activities",
|
|
13
12
|
"zaip_dim_llm_model",
|
|
@@ -32,6 +31,8 @@ export const requiredIndexes = [
|
|
|
32
31
|
"zaip_activities_period_invocation",
|
|
33
32
|
"zaip_activities_status",
|
|
34
33
|
"zaip_activities_payload",
|
|
34
|
+
"zaip_activities_duration_activity",
|
|
35
|
+
"zaip_activities_file_path",
|
|
35
36
|
"zaip_activities_work_item_identity",
|
|
36
37
|
"cost_dimension_facts_day_model",
|
|
37
38
|
"cost_dimension_facts_day_provider",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, mkdtemp, rename, rm, stat, utimes, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
-
import { afterEach, describe, expect, it } from "vitest";
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
4
4
|
import {
|
|
5
5
|
type SqliteReadModelSourceCandidate,
|
|
6
6
|
sourceFingerprint,
|
|
@@ -21,6 +21,7 @@ const checkpoints = (candidates: SqliteReadModelSourceCandidate[]) =>
|
|
|
21
21
|
new Map(candidates.map((candidate) => [candidate.source, candidate]));
|
|
22
22
|
|
|
23
23
|
afterEach(async () => {
|
|
24
|
+
vi.restoreAllMocks();
|
|
24
25
|
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
|
|
25
26
|
});
|
|
26
27
|
|
|
@@ -49,6 +50,7 @@ describe("persistent source fingerprint checkpoints", () => {
|
|
|
49
50
|
|
|
50
51
|
it("reuses historical content hashes across serialized checkpoints and detects additions and removals", async () => {
|
|
51
52
|
const { root, path } = await fixture();
|
|
53
|
+
vi.spyOn(Date, "now").mockReturnValue(Date.now() + 5_000);
|
|
52
54
|
const initial = await sourceFingerprint(root);
|
|
53
55
|
const previous = checkpoints(JSON.parse(JSON.stringify(initial.candidates)));
|
|
54
56
|
expect(initial.hashedFiles).toBe(1);
|
|
@@ -86,6 +88,57 @@ describe("persistent source fingerprint checkpoints", () => {
|
|
|
86
88
|
expect(changed).toMatchObject({ hashedFiles: 1, reusedFiles: 0 });
|
|
87
89
|
});
|
|
88
90
|
|
|
91
|
+
it("rehashes recent colliding metadata and the first settled checkpoint before reuse", async () => {
|
|
92
|
+
const { root, path } = await fixture();
|
|
93
|
+
const metadata = await stat(path);
|
|
94
|
+
const clock = vi.spyOn(Date, "now").mockReturnValue(metadata.ctimeMs);
|
|
95
|
+
const initial = await sourceFingerprint(root);
|
|
96
|
+
// Even a corrupted/stale hash with otherwise identical metadata cannot be
|
|
97
|
+
// trusted while writes can collide within the filesystem timestamp tick.
|
|
98
|
+
const stale = checkpoints(
|
|
99
|
+
initial.candidates.map((item) => ({ ...item, contentHash: "stale" })),
|
|
100
|
+
);
|
|
101
|
+
const recent = await sourceFingerprint(root, { previous: stale });
|
|
102
|
+
expect(recent).toMatchObject({ hashedFiles: 1, reusedFiles: 0 });
|
|
103
|
+
expect(recent.candidates[0]?.contentHash).toBe(initial.candidates[0]?.contentHash);
|
|
104
|
+
const serialized = checkpoints(JSON.parse(JSON.stringify(recent.candidates)));
|
|
105
|
+
clock.mockReturnValue(metadata.ctimeMs + 2_001);
|
|
106
|
+
const settled = await sourceFingerprint(root, { previous: serialized });
|
|
107
|
+
expect(settled).toMatchObject({ hashedFiles: 1, reusedFiles: 0 });
|
|
108
|
+
const reused = await sourceFingerprint(root, { previous: checkpoints(settled.candidates) });
|
|
109
|
+
expect(reused).toMatchObject({
|
|
110
|
+
hashedFiles: 0,
|
|
111
|
+
reusedFiles: 1,
|
|
112
|
+
fingerprint: settled.fingerprint,
|
|
113
|
+
});
|
|
114
|
+
const legacy = checkpoints(
|
|
115
|
+
settled.candidates.map((item) => ({
|
|
116
|
+
...item,
|
|
117
|
+
contentHash: "stale",
|
|
118
|
+
fileIdentity: item.fileIdentity.replace("settled-v2:", ""),
|
|
119
|
+
})),
|
|
120
|
+
);
|
|
121
|
+
const upgraded = await sourceFingerprint(root, { previous: legacy });
|
|
122
|
+
expect(upgraded).toMatchObject({
|
|
123
|
+
hashedFiles: 1,
|
|
124
|
+
reusedFiles: 0,
|
|
125
|
+
fingerprint: settled.fingerprint,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("detects rapid real same-size rewrites with restored mtime across repeated scans", async () => {
|
|
130
|
+
const { root, path } = await fixture();
|
|
131
|
+
const timestamp = new Date("2026-01-01T00:00:00Z");
|
|
132
|
+
let previous = await sourceFingerprint(root);
|
|
133
|
+
for (let iteration = 0; iteration < 20; iteration += 1) {
|
|
134
|
+
await writeFile(path, iteration % 2 ? "# first\n" : "# other\n");
|
|
135
|
+
await utimes(path, timestamp, timestamp);
|
|
136
|
+
const next = await sourceFingerprint(root, { previous: checkpoints(previous.candidates) });
|
|
137
|
+
expect(next.candidates[0]?.contentHash).not.toBe(previous.candidates[0]?.contentHash);
|
|
138
|
+
previous = next;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
89
142
|
it("detects atomic file replacement and allows explicit complete content verification", async () => {
|
|
90
143
|
const { root, path } = await fixture();
|
|
91
144
|
const initial = await sourceFingerprint(root);
|
|
@@ -83,8 +83,10 @@ export async function sourceFingerprint(
|
|
|
83
83
|
let hashedFiles = 0;
|
|
84
84
|
let reusedFiles = 0;
|
|
85
85
|
// Persisted checkpoints avoid rereading unchanged history across workers.
|
|
86
|
-
//
|
|
87
|
-
//
|
|
86
|
+
// Windows can report identical ctime even in nanoseconds for rapid writes.
|
|
87
|
+
// Never cache a recent timestamp. Mark those hashes as unstable so that the
|
|
88
|
+
// first scan after the settling window also rehashes before allowing reuse.
|
|
89
|
+
// Explicit verification still bypasses this metadata shortcut entirely.
|
|
88
90
|
for (let offset = 0; offset < candidates.length; offset += 32) {
|
|
89
91
|
candidatesWithMetadata.push(
|
|
90
92
|
...(
|
|
@@ -94,17 +96,19 @@ export async function sourceFingerprint(
|
|
|
94
96
|
try {
|
|
95
97
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
96
98
|
const metadata = await stat(candidate);
|
|
99
|
+
const metadataSettled = Date.now() - metadata.ctimeMs > 2_000;
|
|
97
100
|
const current = {
|
|
98
101
|
path: candidate,
|
|
99
102
|
source,
|
|
100
103
|
mtimeMs: metadata.mtimeMs,
|
|
101
104
|
ctimeMs: metadata.ctimeMs,
|
|
102
105
|
size: metadata.size,
|
|
103
|
-
fileIdentity:
|
|
106
|
+
fileIdentity: `settled-v2:${metadata.dev}:${metadata.ino}:${metadata.birthtimeMs}${metadataSettled ? "" : ":recent"}`,
|
|
104
107
|
};
|
|
105
108
|
const previous = options.previous?.get(source);
|
|
106
109
|
if (
|
|
107
110
|
!options.verifyContent &&
|
|
111
|
+
metadataSettled &&
|
|
108
112
|
previous !== undefined &&
|
|
109
113
|
previous.mtimeMs === current.mtimeMs &&
|
|
110
114
|
previous.ctimeMs === current.ctimeMs &&
|
|
@@ -46,8 +46,11 @@ describe("SQLite dashboard read model", () => {
|
|
|
46
46
|
await writeFile(join(root, ".agents/config/project.yaml"), "zaip:\n enabled: true\n");
|
|
47
47
|
const task = join(root, ".agents/records/tasks/task.md");
|
|
48
48
|
await writeFile(task, "# initial\n");
|
|
49
|
+
const settledFilesystemTime = Date.now() + 5_000;
|
|
49
50
|
vi.useFakeTimers({ toFake: ["Date"] });
|
|
50
51
|
vi.setSystemTime(new Date("2026-09-05T02:59:00Z"));
|
|
52
|
+
// Calendar projection time is independent of the real fixture's ctime.
|
|
53
|
+
vi.spyOn(Date, "now").mockReturnValue(settledFilesystemTime);
|
|
51
54
|
const first = await rebuildSqliteReadModel(root);
|
|
52
55
|
await expect(rebuildSqliteReadModel(root)).resolves.toMatchObject({ cache: "generation" });
|
|
53
56
|
await rm(task);
|
|
@@ -174,7 +177,7 @@ describe("SQLite dashboard read model", () => {
|
|
|
174
177
|
metadata
|
|
175
178
|
.prepare("SELECT value FROM zaip_vw_read_model_metadata WHERE key='schema_version'")
|
|
176
179
|
.get(),
|
|
177
|
-
).toEqual({ value: "
|
|
180
|
+
).toEqual({ value: "79" });
|
|
178
181
|
} finally {
|
|
179
182
|
metadata.close();
|
|
180
183
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
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 { createDashboardApp } from "./server.js";
|
|
5
|
+
import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
|
|
6
|
+
|
|
7
|
+
it("serves risk counts over the same non-draft population as total and statuses", async () => {
|
|
8
|
+
const parent = resolve(import.meta.dirname, "../../../../../../.local/sqlite/tests");
|
|
9
|
+
await mkdir(parent, { recursive: true });
|
|
10
|
+
const root = await mkdtemp(join(parent, "risk-population-"));
|
|
11
|
+
let filesystem: SqliteReadModelFileSystem | undefined;
|
|
12
|
+
try {
|
|
13
|
+
const records = join(root, ".agents/records/tasks/2026/09");
|
|
14
|
+
await mkdir(records, { recursive: true });
|
|
15
|
+
await mkdir(join(root, ".agents/config"), { recursive: true });
|
|
16
|
+
await writeFile(
|
|
17
|
+
join(root, ".agents/config/project.yaml"),
|
|
18
|
+
"schema_version: 1\nzaip:\n enabled: true\nproject:\n id: sqlite-test\n name: sqlite-test\n timezone: UTC\nstack:\n id: zaip-aios-stack\n overrides: {}\nclients:\n codex: true\n claude: true\ntracking:\n enabled: true\n currency: BRL\n storage_mode: tracked_sanitized\n",
|
|
19
|
+
);
|
|
20
|
+
await writeFile(
|
|
21
|
+
join(root, ".agents/config/framework.lock.yaml"),
|
|
22
|
+
"lock_version: 1\nframework:\n version: 2.6.0\n distribution_sha256: null\nlayout:\n version: 3\nresolved_profile:\n id: null\n sha256: null\nmanaged_files: {}\n",
|
|
23
|
+
);
|
|
24
|
+
for (const [id, status, risk] of [
|
|
25
|
+
["TASK-DRAFT", "draft", "critical"],
|
|
26
|
+
["TASK-PLANNED", "planned", "lite"],
|
|
27
|
+
["TASK-SECOND", "planned", "lite"],
|
|
28
|
+
["TASK-COMPLETED", "completed", "standard"],
|
|
29
|
+
]) {
|
|
30
|
+
await writeFile(
|
|
31
|
+
join(records, `${id}.md`),
|
|
32
|
+
`---\nid: ${id}\ntitle: ${id}\nstatus: ${status}\nrisk: ${risk}\ncreated_at: 2026-09-${id === "TASK-COMPLETED" ? "02" : "01"}T12:00:00.000Z\n---\n`,
|
|
33
|
+
"utf8",
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
await rebuildSqliteReadModel(root);
|
|
37
|
+
filesystem = new SqliteReadModelFileSystem(root);
|
|
38
|
+
expect(filesystem.firstFoldViewportAllTime().task_risk_counts).toEqual({
|
|
39
|
+
lite: 2,
|
|
40
|
+
standard: 1,
|
|
41
|
+
});
|
|
42
|
+
expect(filesystem.firstFoldAllTime().task_risk_counts).toEqual({ lite: 2, standard: 1 });
|
|
43
|
+
for (const view of [
|
|
44
|
+
"cost_monitor_daily",
|
|
45
|
+
"cost_monitor_monthly",
|
|
46
|
+
"cost_monitor_annual",
|
|
47
|
+
] as const) {
|
|
48
|
+
const page = filesystem.viewPage(view, { limit: 10 });
|
|
49
|
+
const daily = view === "cost_monitor_daily";
|
|
50
|
+
expect(page.rows).toHaveLength(daily ? 2 : 1);
|
|
51
|
+
expect(page.totals).toMatchObject({ task_count: 3 });
|
|
52
|
+
expect(page).toMatchObject({ period_averages: { BRL: { tasks: daily ? 1.5 : 3 } } });
|
|
53
|
+
}
|
|
54
|
+
const first = filesystem.viewPage("cost_monitor_daily", { limit: 1, offset: 0 });
|
|
55
|
+
const second = filesystem.viewPage("cost_monitor_daily", { limit: 1, offset: 1 });
|
|
56
|
+
expect(first.rows[0]).toMatchObject({ task_count: 1 });
|
|
57
|
+
expect(second.rows[0]).toMatchObject({ task_count: 2 });
|
|
58
|
+
expect(first.period_averages).toEqual(second.period_averages);
|
|
59
|
+
expect(first).toMatchObject({
|
|
60
|
+
period_averages: { BRL: { tasks: 1.5, cost: null, tokens: null } },
|
|
61
|
+
});
|
|
62
|
+
expect(
|
|
63
|
+
filesystem.viewPage("cost_monitor_daily", { limit: 1, query: "2026-09-01" }),
|
|
64
|
+
).toMatchObject({ total_count: 1, period_averages: { BRL: { tasks: 2 } } });
|
|
65
|
+
const app = createDashboardApp(root, "fixture-only", undefined, {
|
|
66
|
+
filesystem,
|
|
67
|
+
watchSources: false,
|
|
68
|
+
});
|
|
69
|
+
for (const scope of ["quick", "overview"]) {
|
|
70
|
+
const response = await app.request(`/api/v2/operations?scope=${scope}`, {
|
|
71
|
+
headers: { "x-zaip-session": "fixture-only" },
|
|
72
|
+
});
|
|
73
|
+
expect(response.status, await response.clone().text()).toBe(200);
|
|
74
|
+
const data = (await response.json()) as {
|
|
75
|
+
summary: {
|
|
76
|
+
overview_metrics: {
|
|
77
|
+
task_count: number;
|
|
78
|
+
task_status_counts: Record<string, number>;
|
|
79
|
+
task_risk_counts: Record<string, number>;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
const metric = data.summary.overview_metrics;
|
|
84
|
+
expect(metric.task_count).toBe(3);
|
|
85
|
+
expect(metric.task_status_counts).toEqual({ planned: 2, completed: 1 });
|
|
86
|
+
expect(metric.task_risk_counts).toEqual({ lite: 2, standard: 1 });
|
|
87
|
+
expect(
|
|
88
|
+
Object.values(metric.task_risk_counts).reduce<number>(
|
|
89
|
+
(sum, count) => sum + Number(count),
|
|
90
|
+
0,
|
|
91
|
+
),
|
|
92
|
+
).toBe(metric.task_count);
|
|
93
|
+
}
|
|
94
|
+
} finally {
|
|
95
|
+
filesystem?.close();
|
|
96
|
+
await rm(root, { recursive: true, force: true });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
@@ -16,8 +16,13 @@ export const baseViewSql = `
|
|
|
16
16
|
WHERE agent_invocation_id IS NOT NULL;
|
|
17
17
|
CREATE INDEX zaip_activities_status ON zaip_aios_activities(activity_source_kind, status, phase);
|
|
18
18
|
CREATE INDEX IF NOT EXISTS zaip_activities_payload ON zaip_aios_activities(payload_type, activity_key);
|
|
19
|
+
CREATE INDEX zaip_activities_duration_activity ON zaip_aios_activities(CAST(json_extract(payload_json, '$.activity_row_id') AS TEXT)) WHERE payload_type='duration_allocation';
|
|
20
|
+
-- File lookups must not parse every JSON payload (including its full
|
|
21
|
+
-- content) on each read. The file view uses this path-only index for
|
|
22
|
+
-- binary equality and cheap LIKE scans without changing their semantics.
|
|
23
|
+
CREATE INDEX zaip_activities_file_path ON zaip_aios_activities(json_extract(payload_json, '$.path')) WHERE payload_type='file';
|
|
19
24
|
CREATE INDEX zaip_activities_work_item_identity ON zaip_aios_activities(json_extract(payload_json, '$.entity_kind'), json_extract(payload_json, '$.id')) WHERE payload_type='work_item';
|
|
20
|
-
CREATE VIEW files AS SELECT json_extract(payload_json, '$.path') AS path, json_extract(payload_json, '$.content') AS content, json_extract(payload_json, '$.mtime_ms') AS mtime_ms, json_extract(payload_json, '$.size_bytes') AS size_bytes, json_extract(payload_json, '$.content_sha256') AS content_sha256, json_extract(payload_json, '$.artifact_kind') AS artifact_kind, json_extract(payload_json, '$.artifact_id') AS artifact_id, json_extract(payload_json, '$.artifact_occurred_at') AS artifact_occurred_at, json_extract(payload_json, '$.artifact_occurred_day_sp') AS artifact_occurred_day_sp, json_extract(payload_json, '$.artifact_task_id') AS artifact_task_id, json_extract(payload_json, '$.artifact_change_id') AS artifact_change_id, json_extract(payload_json, '$.artifact_run_id') AS artifact_run_id FROM zaip_aios_activities WHERE payload_type='file';
|
|
25
|
+
CREATE VIEW files AS SELECT json_extract(payload_json, '$.path') AS path, json_extract(payload_json, '$.content') AS content, json_extract(payload_json, '$.mtime_ms') AS mtime_ms, json_extract(payload_json, '$.size_bytes') AS size_bytes, json_extract(payload_json, '$.content_sha256') AS content_sha256, json_extract(payload_json, '$.artifact_kind') AS artifact_kind, json_extract(payload_json, '$.artifact_id') AS artifact_id, json_extract(payload_json, '$.artifact_occurred_at') AS artifact_occurred_at, json_extract(payload_json, '$.artifact_occurred_day_sp') AS artifact_occurred_day_sp, json_extract(payload_json, '$.artifact_task_id') AS artifact_task_id, json_extract(payload_json, '$.artifact_change_id') AS artifact_change_id, json_extract(payload_json, '$.artifact_run_id') AS artifact_run_id FROM zaip_aios_activities INDEXED BY zaip_activities_file_path WHERE payload_type='file';
|
|
21
26
|
CREATE VIEW read_model_source_state AS SELECT json_extract(payload_json, '$.source_path') AS source_path, json_extract(payload_json, '$.source_hash') AS source_hash, json_extract(payload_json, '$.mtime_ms') AS mtime_ms, json_extract(payload_json, '$.ctime_ms') AS ctime_ms, json_extract(payload_json, '$.size_bytes') AS size_bytes, json_extract(payload_json, '$.file_identity') AS file_identity, json_extract(payload_json, '$.source_kind') AS source_kind, json_extract(payload_json, '$.last_processed_at') AS last_processed_at FROM zaip_aios_activities WHERE payload_type='source_state';
|
|
22
27
|
CREATE VIEW read_model_metadata AS SELECT json_extract(payload_json, '$.key') AS key, json_extract(payload_json, '$.value') AS value FROM zaip_aios_activities WHERE payload_type='metadata';
|
|
23
28
|
CREATE VIEW canonical_work_items AS SELECT json_extract(payload_json, '$.entity_kind') AS entity_kind, json_extract(payload_json, '$.id') AS id, json_extract(payload_json, '$.title') AS title, json_extract(payload_json, '$.status') AS status, json_extract(payload_json, '$.stage') AS stage, json_extract(payload_json, '$.risk') AS risk, json_extract(payload_json, '$.spec_id') AS spec_id, json_extract(payload_json, '$.change_id') AS change_id, json_extract(payload_json, '$.creation_run_id') AS creation_run_id, json_extract(payload_json, '$.completed_run_id') AS completed_run_id, json_extract(payload_json, '$.occurred_at') AS occurred_at, json_extract(payload_json, '$.occurred_day_sp') AS occurred_day_sp FROM zaip_aios_activities WHERE payload_type='work_item';
|
|
@@ -29,12 +34,13 @@ export const baseViewSql = `
|
|
|
29
34
|
CREATE VIEW attributed_token_active_facts AS SELECT json_extract(payload_json, '$.activity_row_id') AS activity_row_id, json_extract(payload_json, '$.occurred_day_sp') AS occurred_day_sp, json_extract(payload_json, '$.attributed_token_active_ms') AS attributed_token_active_ms FROM zaip_aios_activities WHERE payload_type='duration_allocation';
|
|
30
35
|
CREATE VIEW canonical_artifacts AS SELECT artifact_kind, artifact_id, artifact_occurred_at AS occurred_at, artifact_occurred_day_sp AS occurred_day_sp, artifact_task_id AS task_id, artifact_change_id AS change_id, artifact_run_id AS run_id, path AS source_path FROM files WHERE artifact_kind IS NOT NULL AND artifact_occurred_at IS NOT NULL;
|
|
31
36
|
CREATE VIEW activities AS
|
|
32
|
-
SELECT a.*,
|
|
37
|
+
SELECT a.*, (
|
|
38
|
+
SELECT SUM(json_extract(f.payload_json, '$.attributed_token_active_ms'))
|
|
39
|
+
FROM zaip_aios_activities f INDEXED BY zaip_activities_duration_activity
|
|
40
|
+
WHERE f.payload_type='duration_allocation'
|
|
41
|
+
AND CAST(json_extract(f.payload_json, '$.activity_row_id') AS TEXT)=a.activity_row_id
|
|
42
|
+
) AS attributed_token_active_ms
|
|
33
43
|
FROM zaip_aios_activities a
|
|
34
|
-
LEFT JOIN (
|
|
35
|
-
SELECT activity_row_id, SUM(attributed_token_active_ms) AS attributed_token_active_ms
|
|
36
|
-
FROM attributed_token_active_facts GROUP BY activity_row_id
|
|
37
|
-
) f USING(activity_row_id)
|
|
38
44
|
WHERE a.payload_type IS NULL;
|
|
39
45
|
-- Macro-only allocations are persisted as technical payloads to keep
|
|
40
46
|
-- the global Run population unique. SPEC summaries opt into this
|
|
@@ -64,21 +70,27 @@ export const baseViewSql = `
|
|
|
64
70
|
CREATE VIEW specs AS SELECT id, title, status, risk, occurred_at, occurred_day_sp FROM work_items WHERE entity_kind = 'spec';
|
|
65
71
|
CREATE VIEW prds AS SELECT id, title, status, risk, occurred_at, occurred_day_sp FROM work_items WHERE entity_kind = 'prd';
|
|
66
72
|
CREATE VIEW executions AS
|
|
67
|
-
|
|
73
|
+
WITH projected_executions AS MATERIALIZED (
|
|
74
|
+
SELECT id, status, created_at, occurred_day_sp FROM canonical_executions
|
|
75
|
+
)
|
|
76
|
+
SELECT id, status, created_at AS occurred_at, occurred_day_sp FROM projected_executions
|
|
68
77
|
UNION ALL
|
|
69
78
|
SELECT execution_id, MAX(status), MIN(occurred_at), MIN(occurred_day_sp)
|
|
70
|
-
FROM
|
|
71
|
-
WHERE execution_id IS NOT NULL
|
|
72
|
-
AND NOT EXISTS (SELECT 1 FROM
|
|
79
|
+
FROM zaip_aios_activities
|
|
80
|
+
WHERE payload_type IS NULL AND execution_id IS NOT NULL
|
|
81
|
+
AND NOT EXISTS (SELECT 1 FROM projected_executions c WHERE c.id=zaip_aios_activities.execution_id)
|
|
73
82
|
GROUP BY execution_id;
|
|
74
83
|
CREATE VIEW conversations AS
|
|
84
|
+
WITH projected_executions AS MATERIALIZED (
|
|
85
|
+
SELECT status, created_at, occurred_day_sp, origin_type, origin_id FROM canonical_executions
|
|
86
|
+
)
|
|
75
87
|
SELECT origin_id AS id, MAX(status) AS status, MIN(created_at) AS occurred_at, MIN(occurred_day_sp) AS occurred_day_sp
|
|
76
|
-
FROM
|
|
88
|
+
FROM projected_executions WHERE origin_type='interaction' AND origin_id IS NOT NULL GROUP BY origin_id
|
|
77
89
|
UNION ALL
|
|
78
90
|
SELECT conversation_id, MAX(status), MIN(occurred_at), MIN(occurred_day_sp)
|
|
79
|
-
FROM
|
|
80
|
-
WHERE conversation_id IS NOT NULL
|
|
81
|
-
AND NOT EXISTS (SELECT 1 FROM
|
|
91
|
+
FROM zaip_aios_activities
|
|
92
|
+
WHERE payload_type IS NULL AND conversation_id IS NOT NULL
|
|
93
|
+
AND NOT EXISTS (SELECT 1 FROM projected_executions c WHERE c.origin_type='interaction' AND c.origin_id=zaip_aios_activities.conversation_id)
|
|
82
94
|
GROUP BY conversation_id;
|
|
83
95
|
CREATE VIEW decisions AS SELECT id, title, origin, scope_type, scope_id, NULL AS status, NULL AS risk, created_at AS occurred_at, occurred_day_sp, source_path FROM canonical_decisions;
|
|
84
96
|
CREATE VIEW changes AS SELECT id, title, status, risk, source_type, source_id, requirement_ids_json, acceptance_ids_json, task_ids_json, result, created_at AS occurred_at, occurred_day_sp, source_path FROM canonical_changes;
|
|
@@ -123,7 +135,8 @@ export const baseViewSql = `
|
|
|
123
135
|
FROM attributed_token_active_facts GROUP BY occurred_day_sp
|
|
124
136
|
), work_item_days AS (
|
|
125
137
|
SELECT entity_kind AS kind, id, occurred_day_sp AS day FROM canonical_work_items
|
|
126
|
-
|
|
138
|
+
WHERE entity_kind <> 'task' OR COALESCE(status, 'draft') <> 'draft'
|
|
139
|
+
UNION ALL SELECT 'task', task_id, MIN(occurred_day_sp) FROM activities WHERE task_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM canonical_work_items c WHERE c.entity_kind='task' AND c.id=activities.task_id) GROUP BY task_id HAVING COALESCE(MAX(work_item_status), 'draft') <> 'draft'
|
|
127
140
|
UNION ALL SELECT 'spec', spec_id, MIN(occurred_day_sp) FROM activities WHERE spec_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM canonical_work_items c WHERE c.entity_kind='spec' AND c.id=activities.spec_id) GROUP BY spec_id
|
|
128
141
|
UNION ALL SELECT 'prd', prd_id, MIN(occurred_day_sp) FROM activities WHERE prd_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM canonical_work_items c WHERE c.entity_kind='prd' AND c.id=activities.prd_id) GROUP BY prd_id
|
|
129
142
|
), work_item_daily AS (
|
|
@@ -276,7 +289,7 @@ export const baseViewSql = `
|
|
|
276
289
|
-- SPEC/PRD rows have the same canonical population as the big
|
|
277
290
|
-- numbers. A macro without direct invocation remains visible with
|
|
278
291
|
-- factual NULL usage/cost/time, never a fabricated zero.
|
|
279
|
-
CREATE VIEW cost_monitor_group_daily_cache AS SELECT occurred_day_sp AS day, 'execution' AS group_kind, execution_id AS group_value, COUNT(*) AS invocation_count, SUM(llm_call_count) AS llm_call_count, SUM(duration_ms) AS total_duration, SUM(input_tokens) AS total_input_tokens, SUM(cached_input_tokens) AS total_cached_input_tokens, SUM(output_tokens) AS total_output_tokens, SUM(reasoning_tokens) AS total_reasoning_tokens, SUM(total_tokens) AS total_tokens, SUM(cost_usd) AS total_cost_usd, SUM(cost_brl) AS total_cost_brl FROM
|
|
292
|
+
CREATE VIEW cost_monitor_group_daily_cache AS WITH group_invocations AS MATERIALIZED (SELECT occurred_day_sp, execution_id, zaip_agent, provider, model, task_id, spec_id, prd_id, conversation_id, llm_call_count, duration_ms, input_tokens, cached_input_tokens, output_tokens, reasoning_tokens, total_tokens, cost_usd, cost_brl FROM invocations) SELECT occurred_day_sp AS day, 'execution' AS group_kind, execution_id AS group_value, COUNT(*) AS invocation_count, SUM(llm_call_count) AS llm_call_count, SUM(duration_ms) AS total_duration, SUM(input_tokens) AS total_input_tokens, SUM(cached_input_tokens) AS total_cached_input_tokens, SUM(output_tokens) AS total_output_tokens, SUM(reasoning_tokens) AS total_reasoning_tokens, SUM(total_tokens) AS total_tokens, SUM(cost_usd) AS total_cost_usd, SUM(cost_brl) AS total_cost_brl FROM group_invocations WHERE execution_id IS NOT NULL GROUP BY occurred_day_sp, execution_id UNION ALL SELECT occurred_day_sp, 'zaip_agent', zaip_agent, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE zaip_agent IS NOT NULL GROUP BY occurred_day_sp, zaip_agent UNION ALL SELECT occurred_day_sp, 'provider', provider, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE provider IS NOT NULL GROUP BY occurred_day_sp, provider UNION ALL SELECT occurred_day_sp, 'model', model, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE model IS NOT NULL GROUP BY occurred_day_sp, model UNION ALL SELECT occurred_day_sp, 'task', task_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE task_id IS NOT NULL GROUP BY occurred_day_sp, task_id UNION ALL SELECT occurred_day_sp, 'spec', spec_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE spec_id IS NOT NULL GROUP BY occurred_day_sp, spec_id UNION ALL SELECT occurred_day_sp, 'prd', prd_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE prd_id IS NOT NULL GROUP BY occurred_day_sp, prd_id UNION ALL SELECT occurred_day_sp, 'conversation', conversation_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE conversation_id IS NOT NULL GROUP BY occurred_day_sp, conversation_id;
|
|
280
293
|
CREATE VIEW daily_aggregates AS SELECT * FROM daily_aggregate_cache;
|
|
281
294
|
CREATE VIEW overview AS
|
|
282
295
|
SELECT 'day' AS period_kind, day AS period_key, day AS start_day, day AS end_day, prd_count, spec_count, task_count, validation_count, evidence_count, activity_count, root_run_count, sub_run_count, total_run_count, invocation_count, cost_monitor_invocation_count, llm_call_count, source_event_count, total_root_run_duration, total_sub_run_duration, operations_total_duration, cost_monitor_total_duration, total_duration, total_tokens, total_cost_usd, total_cost_brl FROM daily_aggregates
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts
CHANGED
|
@@ -174,7 +174,8 @@ export const dashboardViewSql = ` CREATE VIEW vw_operations_work_list AS
|
|
|
174
174
|
CREATE VIEW vw_first_fold_task_risk_all_time AS
|
|
175
175
|
WITH counts AS (
|
|
176
176
|
SELECT COALESCE(risk, 'standard') AS risk, COUNT(*) AS task_count
|
|
177
|
-
FROM task_summary
|
|
177
|
+
FROM task_summary WHERE COALESCE(status, 'draft') <> 'draft'
|
|
178
|
+
GROUP BY COALESCE(risk, 'standard')
|
|
178
179
|
), total AS (SELECT SUM(task_count) AS task_count FROM counts)
|
|
179
180
|
SELECT counts.risk, counts.task_count,
|
|
180
181
|
CASE WHEN total.task_count = 0 THEN 0.0 ELSE CAST(counts.task_count AS REAL) / total.task_count END AS task_percentage
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
const roots: string[] = [];
|
|
14
14
|
|
|
15
15
|
afterEach(async () => {
|
|
16
|
+
vi.restoreAllMocks();
|
|
16
17
|
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
|
|
17
18
|
});
|
|
18
19
|
|
|
@@ -60,6 +61,7 @@ describe("SQLite snapshot seed publication", () => {
|
|
|
60
61
|
await mkdir(join(root, ".agents", "config"), { recursive: true });
|
|
61
62
|
await writeFile(join(root, ".agents", "config", "project.yaml"), "zaip:\n enabled: true\n");
|
|
62
63
|
const destination = join(root, ".local", "dashboard-sqlite", "read-model.sqlite");
|
|
64
|
+
vi.spyOn(Date, "now").mockReturnValue(Date.now() + 5_000);
|
|
63
65
|
vi.stubEnv("ZAIP_SQLITE_DB_PATH", destination);
|
|
64
66
|
try {
|
|
65
67
|
await expect(rebuildSqliteReadModel(root)).resolves.toMatchObject({ cache: "rebuilt" });
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { stripVTControlCharacters } from "node:util";
|
|
6
|
+
|
|
7
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const root = resolve(here, "../../../../..");
|
|
9
|
+
const prefix = ".agents/dashboard/packages/local-runtime/src/";
|
|
10
|
+
const mode = process.argv[2];
|
|
11
|
+
if (!["test", "integration", "check"].includes(mode))
|
|
12
|
+
throw new Error("Expected test|integration|check");
|
|
13
|
+
if (!existsSync(resolve(root, "node_modules/vitest/vitest.mjs"))) {
|
|
14
|
+
if (spawnSync("git", ["symbolic-ref", "-q", "HEAD"], { cwd: root }).status !== 1)
|
|
15
|
+
throw new Error("Prepare dependencies in the Task checkout first");
|
|
16
|
+
const pnpm = resolve(dirname(process.execPath), "node_modules/corepack/dist/pnpm.js");
|
|
17
|
+
execute([pnpm, "install", "--offline", "--frozen-lockfile", "--ignore-scripts"], 300_000);
|
|
18
|
+
}
|
|
19
|
+
function execute(args, timeout = 120_000) {
|
|
20
|
+
const result = spawnSync(process.execPath, args, {
|
|
21
|
+
cwd: root,
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
windowsHide: true,
|
|
24
|
+
timeout,
|
|
25
|
+
maxBuffer: 4_000_000,
|
|
26
|
+
});
|
|
27
|
+
const output = stripVTControlCharacters((result.stdout ?? "") + "\n" + (result.stderr ?? ""));
|
|
28
|
+
if (result.status !== 0) {
|
|
29
|
+
process.stderr.write(output);
|
|
30
|
+
throw new Error("Settings validation failed: " + (result.error?.message ?? result.status));
|
|
31
|
+
}
|
|
32
|
+
return output;
|
|
33
|
+
}
|
|
34
|
+
if (mode === "check") {
|
|
35
|
+
execute([
|
|
36
|
+
"node_modules/typescript/bin/tsc",
|
|
37
|
+
"--noEmit",
|
|
38
|
+
"--project",
|
|
39
|
+
".agents/dashboard/packages/local-runtime/tsconfig.json",
|
|
40
|
+
]);
|
|
41
|
+
console.log(JSON.stringify({ kind: "settings_typecheck", passed: true, mode }));
|
|
42
|
+
} else {
|
|
43
|
+
const file =
|
|
44
|
+
mode === "test" ? "project-installation-summary.test.ts" : "project-settings.test.ts";
|
|
45
|
+
const output = execute([
|
|
46
|
+
"node_modules/vitest/vitest.mjs",
|
|
47
|
+
"run",
|
|
48
|
+
prefix + file,
|
|
49
|
+
"--maxWorkers=1",
|
|
50
|
+
]);
|
|
51
|
+
const tests = output
|
|
52
|
+
.split("\n")
|
|
53
|
+
.find((line) => /^\s*Tests\s/.test(line))
|
|
54
|
+
?.trim();
|
|
55
|
+
if (!tests || !/\b[1-9]\d* passed\b/.test(tests)) throw new Error("No settings tests executed");
|
|
56
|
+
console.log(JSON.stringify({ kind: "settings_" + mode, passed: true, mode, tests, output }));
|
|
57
|
+
}
|