@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
|
@@ -1,11 +1,44 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
+
import { type SqliteReadModelFileSystem, sqliteReadModelPath } from "./sqlite-read-model.js";
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
readModelSchemaVersion,
|
|
7
|
+
requiredIndexes,
|
|
8
|
+
requiredPersistedTables,
|
|
9
|
+
requiredViews,
|
|
10
|
+
} from "./sqlite-read-model-schema.js";
|
|
11
|
+
|
|
12
|
+
/** The worker validates integrity and schema before emitting this receipt. */
|
|
13
|
+
export function validateSnapshotWorkerReceipt(stdout: string, destination: string): void {
|
|
14
|
+
const result = JSON.parse(stdout) as {
|
|
15
|
+
storage_mode?: unknown;
|
|
16
|
+
path?: unknown;
|
|
17
|
+
schema?: {
|
|
18
|
+
schemaVersion?: unknown;
|
|
19
|
+
tableCount?: unknown;
|
|
20
|
+
viewCount?: unknown;
|
|
21
|
+
indexCount?: unknown;
|
|
22
|
+
};
|
|
23
|
+
} | null;
|
|
24
|
+
const schema = result?.schema;
|
|
25
|
+
if (
|
|
26
|
+
result?.storage_mode !== "sqlite_read_model" ||
|
|
27
|
+
typeof result.path !== "string" ||
|
|
28
|
+
resolve(result.path) !== resolve(destination) ||
|
|
29
|
+
schema?.schemaVersion !== readModelSchemaVersion ||
|
|
30
|
+
schema.tableCount !== requiredPersistedTables.length ||
|
|
31
|
+
typeof schema.viewCount !== "number" ||
|
|
32
|
+
!Number.isSafeInteger(schema.viewCount) ||
|
|
33
|
+
schema.viewCount < requiredViews.length ||
|
|
34
|
+
typeof schema.indexCount !== "number" ||
|
|
35
|
+
!Number.isSafeInteger(schema.indexCount) ||
|
|
36
|
+
schema.indexCount < requiredIndexes.length
|
|
37
|
+
)
|
|
38
|
+
throw new Error(
|
|
39
|
+
"SQLite refresh worker did not return a valid schema receipt for this destination",
|
|
40
|
+
);
|
|
41
|
+
}
|
|
9
42
|
|
|
10
43
|
async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destination: string) {
|
|
11
44
|
const scriptCandidates = [
|
|
@@ -24,6 +57,8 @@ async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destinat
|
|
|
24
57
|
throw new Error("SQLite refresh worker script is unavailable from this runtime checkout");
|
|
25
58
|
await new Promise<void>((resolveWorker, rejectWorker) => {
|
|
26
59
|
let stderr = "";
|
|
60
|
+
let stdout = "";
|
|
61
|
+
let oversizedReceipt = false;
|
|
27
62
|
const worker = spawn(process.execPath, [script], {
|
|
28
63
|
cwd: workspaceRoot,
|
|
29
64
|
env: {
|
|
@@ -33,13 +68,18 @@ async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destinat
|
|
|
33
68
|
ZAIP_SQLITE_PREFER_LAST_VALID_SEED: "0",
|
|
34
69
|
ZAIP_DASHBOARD_LAUNCH_PROGRESS: "0",
|
|
35
70
|
},
|
|
36
|
-
stdio: ["ignore", "
|
|
71
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
37
72
|
windowsHide: true,
|
|
38
73
|
});
|
|
39
74
|
// Lease shutdown may end the serving parent while a slow snapshot rebuild
|
|
40
75
|
// is still writing. Terminate the direct child synchronously during parent
|
|
41
76
|
// exit so the next launcher cannot overlap the persistent SQLite writer.
|
|
42
77
|
const cleanupWorker = attachRefreshWorkerCleanup(worker);
|
|
78
|
+
worker.stdout?.setEncoding("utf8");
|
|
79
|
+
worker.stdout?.on("data", (chunk: string) => {
|
|
80
|
+
if (stdout.length + chunk.length > 64_000) oversizedReceipt = true;
|
|
81
|
+
if (!oversizedReceipt) stdout += chunk;
|
|
82
|
+
});
|
|
43
83
|
worker.stderr?.setEncoding("utf8");
|
|
44
84
|
worker.stderr?.on("data", (chunk: string) => {
|
|
45
85
|
stderr = `${stderr}${chunk}`.slice(-8_000);
|
|
@@ -48,13 +88,22 @@ async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destinat
|
|
|
48
88
|
cleanupWorker();
|
|
49
89
|
rejectWorker(error);
|
|
50
90
|
});
|
|
51
|
-
|
|
91
|
+
// close follows stdout drain; exit alone may precede the receipt bytes.
|
|
92
|
+
worker.once("close", (code) => {
|
|
52
93
|
cleanupWorker();
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
94
|
+
if (code !== 0) {
|
|
95
|
+
rejectWorker(
|
|
96
|
+
new Error(`SQLite refresh worker failed (${code}): ${stderr.trim() || "no stderr"}`),
|
|
97
|
+
);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
if (oversizedReceipt) throw new Error("SQLite refresh worker receipt exceeds size limit");
|
|
102
|
+
validateSnapshotWorkerReceipt(stdout, destination);
|
|
103
|
+
resolveWorker();
|
|
104
|
+
} catch (error) {
|
|
105
|
+
rejectWorker(error);
|
|
106
|
+
}
|
|
58
107
|
});
|
|
59
108
|
});
|
|
60
109
|
}
|
|
@@ -88,6 +137,7 @@ export async function refreshSqliteSnapshotInWorker(
|
|
|
88
137
|
) {
|
|
89
138
|
const destination = sqliteReadModelPath(workspaceRoot);
|
|
90
139
|
await rebuildPersistentDatabaseInWorker(workspaceRoot, destination);
|
|
91
|
-
|
|
140
|
+
// Integrity/schema checking belongs to the worker, not the HTTP event loop.
|
|
141
|
+
// Zero exit alone is insufficient: its exact-destination receipt is mandatory.
|
|
92
142
|
filesystem.refresh();
|
|
93
143
|
}
|
|
@@ -19,6 +19,32 @@ afterEach(() => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
describe("snapshot source synchronization", () => {
|
|
22
|
+
it("reports capture failure separately while refreshing canonical data", async () => {
|
|
23
|
+
vi.useFakeTimers();
|
|
24
|
+
const error = new Error("capture timed out");
|
|
25
|
+
const onCaptureFailure = vi.fn();
|
|
26
|
+
const onRefreshFailure = vi.fn();
|
|
27
|
+
const onCaptureSuccess = vi.fn();
|
|
28
|
+
const capture = vi.fn().mockRejectedValueOnce(error).mockResolvedValue(undefined);
|
|
29
|
+
const refresh = vi.fn(async () => undefined);
|
|
30
|
+
startSnapshotSynchronization({
|
|
31
|
+
workspaceRoot: "C:/workspace",
|
|
32
|
+
staleSeed: false,
|
|
33
|
+
watchSources: true,
|
|
34
|
+
refresh,
|
|
35
|
+
captureActiveTelemetry: capture,
|
|
36
|
+
onCaptureFailure,
|
|
37
|
+
onCaptureSuccess,
|
|
38
|
+
onRefreshFailure,
|
|
39
|
+
});
|
|
40
|
+
await vi.advanceTimersByTimeAsync(301);
|
|
41
|
+
expect(onCaptureFailure).toHaveBeenCalledWith(error);
|
|
42
|
+
expect(onRefreshFailure).not.toHaveBeenCalled();
|
|
43
|
+
expect(refresh).toHaveBeenCalledTimes(1);
|
|
44
|
+
await vi.advanceTimersByTimeAsync(60_000);
|
|
45
|
+
expect(onCaptureSuccess).toHaveBeenCalledTimes(1);
|
|
46
|
+
expect(refresh).toHaveBeenCalledTimes(2);
|
|
47
|
+
});
|
|
22
48
|
it("watches current data for both creation and alteration refreshes", async () => {
|
|
23
49
|
vi.useFakeTimers();
|
|
24
50
|
const refresh = vi.fn(async () => undefined);
|
package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts
CHANGED
|
@@ -8,6 +8,8 @@ export function startSnapshotSynchronization(input: {
|
|
|
8
8
|
refresh: () => Promise<void>;
|
|
9
9
|
/** Exact active-Codex collection, separate from projection and lifecycle repair. */
|
|
10
10
|
captureActiveTelemetry?: () => Promise<void>;
|
|
11
|
+
onCaptureFailure?: (error: unknown) => void;
|
|
12
|
+
onCaptureSuccess?: () => void;
|
|
11
13
|
/** Report failed asynchronous refreshes; a stale snapshot must never look healthy. */
|
|
12
14
|
onRefreshFailure?: (input: { trigger: "stale_seed" | "source_change"; error: unknown }) => void;
|
|
13
15
|
}): void {
|
|
@@ -40,7 +42,8 @@ export function startSnapshotSynchronization(input: {
|
|
|
40
42
|
if (input.captureActiveTelemetry === undefined) return scheduleRefresh();
|
|
41
43
|
void input
|
|
42
44
|
.captureActiveTelemetry()
|
|
43
|
-
.
|
|
45
|
+
.then(() => input.onCaptureSuccess?.())
|
|
46
|
+
.catch((error: unknown) => input.onCaptureFailure?.(error))
|
|
44
47
|
.finally(scheduleRefresh);
|
|
45
48
|
};
|
|
46
49
|
// Run at most once a minute. File watchers only project canonical changes;
|
package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.test.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { createV2WorkspaceLayout } from "@zaip-ai/core";
|
|
5
|
+
import { afterEach, expect, it, vi } from "vitest";
|
|
6
|
+
import { buildSqliteTaskTrace } from "./server-sqlite-task-trace.js";
|
|
7
|
+
import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
|
|
8
|
+
import { prepareMultiProviderFixture } from "./sqlite-read-model-multi-provider-fixture.js";
|
|
9
|
+
|
|
10
|
+
const roots: string[] = [];
|
|
11
|
+
const readers: SqliteReadModelFileSystem[] = [];
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
vi.restoreAllMocks();
|
|
14
|
+
for (const reader of readers.splice(0)) reader.close();
|
|
15
|
+
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
|
|
16
|
+
});
|
|
17
|
+
const taskId = "TASK-2026-09-10-12-00-TRACE-AAAA";
|
|
18
|
+
const layout = createV2WorkspaceLayout(
|
|
19
|
+
{
|
|
20
|
+
schema_version: 1,
|
|
21
|
+
project: { id: "trace", name: "Trace", timezone: "America/Sao_Paulo" },
|
|
22
|
+
stack: { id: "zaip-aios-stack", overrides: {} },
|
|
23
|
+
clients: { codex: true, claude: false },
|
|
24
|
+
tracking: { enabled: true, currency: "BRL", storage_mode: "tracked_sanitized" },
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
lock_version: 2,
|
|
28
|
+
framework: { version: "3.0.0", distribution_sha256: null },
|
|
29
|
+
layout: { version: 3 },
|
|
30
|
+
resolved_profile: { id: null, sha256: null },
|
|
31
|
+
managed_files: {},
|
|
32
|
+
},
|
|
33
|
+
);
|
|
34
|
+
const taskContent = (id: string, title: string) =>
|
|
35
|
+
`---\nid: ${id}\ntitle: ${title}\nstatus: completed\nrisk: standard\ncreated_at: 2026-09-10T15:00:00.000Z\n---\n# ${title}\n`;
|
|
36
|
+
async function fixture(files: Record<string, string>) {
|
|
37
|
+
const root = await mkdtemp(join(tmpdir(), "zaip-trace-bounded-"));
|
|
38
|
+
roots.push(root);
|
|
39
|
+
await prepareMultiProviderFixture(root);
|
|
40
|
+
for (const [path, content] of Object.entries(files)) {
|
|
41
|
+
const target = join(root, path);
|
|
42
|
+
await mkdir(dirname(target), { recursive: true });
|
|
43
|
+
await writeFile(target, content);
|
|
44
|
+
}
|
|
45
|
+
await rebuildSqliteReadModel(root);
|
|
46
|
+
const filesystem = new SqliteReadModelFileSystem(root);
|
|
47
|
+
readers.push(filesystem);
|
|
48
|
+
return filesystem;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
it("resolves the exact Task and filters oversized history before transport without losing documents", async () => {
|
|
52
|
+
const path = layout.activePath("task", taskId);
|
|
53
|
+
const small = ".agents/records/changes/trace/artifacts/tests/notes.md";
|
|
54
|
+
const large = ".agents/records/changes/trace/artifacts/tests/oversized.md";
|
|
55
|
+
const astral = ".agents/records/changes/trace/artifacts/tests/astral.md";
|
|
56
|
+
const shadowId = "TASK-2026-09-10-11-00-SHADOW-AAAA";
|
|
57
|
+
const filesystem = await fixture({
|
|
58
|
+
[path]: taskContent(taskId, "Requested Task"),
|
|
59
|
+
[layout.activePath("task", shadowId)]: taskContent(shadowId, `References ${taskId}`),
|
|
60
|
+
[small]: `# ${taskId}\n${"x".repeat(250_000 - taskId.length - 3)}`,
|
|
61
|
+
[large]: `${taskId}\n${"x".repeat(250_001)}`,
|
|
62
|
+
[astral]: `${taskId}\n${"😀".repeat(130_000)}`,
|
|
63
|
+
});
|
|
64
|
+
const expected = filesystem
|
|
65
|
+
.canonicalTraceFiles([taskId])
|
|
66
|
+
.filter((row) => row.content.length <= 250_000)
|
|
67
|
+
.map((row) => row.path);
|
|
68
|
+
expect(expected).toContain(small);
|
|
69
|
+
expect(expected).not.toContain(large);
|
|
70
|
+
expect(expected).not.toContain(astral);
|
|
71
|
+
const scan = vi.spyOn(filesystem, "canonicalTraceFiles");
|
|
72
|
+
const trace = await buildSqliteTaskTrace(filesystem, layout, taskId);
|
|
73
|
+
expect(trace.task_title).toBe("Requested Task");
|
|
74
|
+
expect(trace.task_id).toBe(taskId);
|
|
75
|
+
expect(trace.documents.map((row) => row.path)).toEqual(expected);
|
|
76
|
+
expect(scan).toHaveBeenCalledOnce();
|
|
77
|
+
expect(scan.mock.calls[0]?.[1]).toBe(250_000);
|
|
78
|
+
expect(scan.mock.results[0]?.value.map((row: { path: string }) => row.path)).not.toContain(large);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("rejects a mismatched Task identity instead of tracing a document that mentions it", async () => {
|
|
82
|
+
const filesystem = await fixture({
|
|
83
|
+
[layout.activePath("task", taskId)]: taskContent("TASK-2026-09-10-11-00-WRONG-AAAA", taskId),
|
|
84
|
+
});
|
|
85
|
+
await expect(buildSqliteTaskTrace(filesystem, layout, taskId)).rejects.toThrow(
|
|
86
|
+
/identity mismatch/,
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("retains the canonical divergent-layout guard and rejects invalid bounds", async () => {
|
|
91
|
+
const filesystem = await fixture({
|
|
92
|
+
[layout.activePath("task", taskId)]: taskContent(taskId, "Active"),
|
|
93
|
+
[`.agents/data/tasks/2026/09/10/${taskId}.md`]: taskContent(taskId, "Divergent"),
|
|
94
|
+
});
|
|
95
|
+
await expect(buildSqliteTaskTrace(filesystem, layout, taskId)).rejects.toThrow(/Divergent/);
|
|
96
|
+
expect(() => filesystem.canonicalTraceFiles([taskId], -1)).toThrow(/Invalid trace content bound/);
|
|
97
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import type
|
|
2
|
+
import { resolveArtifactReadPath, type WorkspaceLayout } from "@zaip-ai/core";
|
|
3
3
|
import type { TaskTrace, TraceDocument } from "@zaip-ai/dashboard-traceability/contracts";
|
|
4
4
|
import {
|
|
5
5
|
buildTraceStageRecords,
|
|
@@ -8,26 +8,23 @@ import {
|
|
|
8
8
|
} from "@zaip-ai/dashboard-traceability/server";
|
|
9
9
|
import type { SqliteReadModelFileSystem } from "./sqlite-read-model.js";
|
|
10
10
|
|
|
11
|
-
export function buildSqliteTaskTrace(
|
|
11
|
+
export async function buildSqliteTaskTrace(
|
|
12
12
|
filesystem: SqliteReadModelFileSystem,
|
|
13
13
|
layout: WorkspaceLayout,
|
|
14
14
|
taskId: string,
|
|
15
|
-
): TaskTrace {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
row.path.includes("/.agents/records/tasks/") ||
|
|
22
|
-
row.path.includes(".agents/records/tasks/"),
|
|
23
|
-
);
|
|
24
|
-
if (taskFile === undefined) throw new Error(`Canonical Task ${taskId} was not found`);
|
|
15
|
+
): Promise<TaskTrace> {
|
|
16
|
+
// Resolve the exact canonical identity, not the first Task mentioning it.
|
|
17
|
+
// This also avoids scanning all historical contents just to locate one Task.
|
|
18
|
+
const taskPath = await resolveArtifactReadPath(filesystem, layout, "task", taskId);
|
|
19
|
+
if (taskPath === null) throw new Error(`Canonical Task ${taskId} was not found`);
|
|
20
|
+
const taskFile = { path: taskPath, content: await filesystem.readText(taskPath) };
|
|
25
21
|
const scalar = (key: string): string | null => {
|
|
26
22
|
const frontMatter = /^---\r?\n([\s\S]*?)\r?\n---/.exec(taskFile.content)?.[1] ?? "";
|
|
27
23
|
const value = new RegExp(`^${key}:\\s*(.+?)\\s*$`, "m").exec(frontMatter)?.[1]?.trim();
|
|
28
24
|
if (value === undefined || value === "null") return null;
|
|
29
25
|
return value.replace(/^['"]|['"]$/g, "");
|
|
30
26
|
};
|
|
27
|
+
if (scalar("id") !== taskId) throw new Error(`Canonical Task identity mismatch: ${taskId}`);
|
|
31
28
|
const relatedId = (key: string, prefix: string): string | null =>
|
|
32
29
|
scalar(key) ?? new RegExp(`\\b${prefix}[A-Z0-9-]+`).exec(taskFile.content)?.[0] ?? null;
|
|
33
30
|
const changeId = relatedId("change_id", "CHG-") ?? taskId;
|
|
@@ -37,7 +34,7 @@ export function buildSqliteTaskTrace(
|
|
|
37
34
|
(value): value is string => value !== null,
|
|
38
35
|
);
|
|
39
36
|
const documents = filesystem
|
|
40
|
-
.canonicalTraceFiles(markers)
|
|
37
|
+
.canonicalTraceFiles(markers, 250_000)
|
|
41
38
|
.filter(
|
|
42
39
|
(row) => /\.(?:md|json|jsonl|txt|log)$/i.test(row.path) && row.content.length <= 250_000,
|
|
43
40
|
)
|
|
@@ -10,15 +10,7 @@ import type { DashboardRouteContext } from "./server-route-context.js";
|
|
|
10
10
|
import { buildSqliteTaskTrace } from "./server-sqlite-task-trace.js";
|
|
11
11
|
import { SqliteReadModelFileSystem } from "./sqlite-read-model.js";
|
|
12
12
|
export function registerTraceRoutes(app: Hono, dependencies: DashboardRouteContext) {
|
|
13
|
-
const {
|
|
14
|
-
filesystem,
|
|
15
|
-
canonicalFilesystem,
|
|
16
|
-
isSqliteSnapshot,
|
|
17
|
-
readLayout,
|
|
18
|
-
readSnapshot,
|
|
19
|
-
readAggregate,
|
|
20
|
-
clearSnapshotCache,
|
|
21
|
-
} = dependencies;
|
|
13
|
+
const { filesystem, readLayout } = dependencies;
|
|
22
14
|
app.on(["GET", "HEAD"], `${API_PREFIX}/tasks/:id`, async (context) => {
|
|
23
15
|
try {
|
|
24
16
|
const layout = await readLayout();
|
|
@@ -53,7 +45,7 @@ export function registerTraceRoutes(app: Hono, dependencies: DashboardRouteConte
|
|
|
53
45
|
return headOrJson(
|
|
54
46
|
context,
|
|
55
47
|
filesystem instanceof SqliteReadModelFileSystem
|
|
56
|
-
? buildSqliteTaskTrace(filesystem, layout, taskId)
|
|
48
|
+
? await buildSqliteTaskTrace(filesystem, layout, taskId)
|
|
57
49
|
: await buildTaskTrace(filesystem, layout, taskId),
|
|
58
50
|
);
|
|
59
51
|
} catch (error) {
|
package/templates/.agents/dashboard/packages/local-runtime/src/server-traceability-index.test.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { serializeMarkdown, WorkspaceFileSystem } from "@zaip-ai/core";
|
|
2
|
+
import { expect, it } from "vitest";
|
|
3
|
+
import { createDashboardApp } from "./server.js";
|
|
4
|
+
import { withSqliteReadModelFixture } from "./server.test-fixtures.js";
|
|
5
|
+
import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
|
|
6
|
+
|
|
7
|
+
it("indexes draft and terminal Tasks in SQLite without adding drafts to Kanban", async () => {
|
|
8
|
+
await withSqliteReadModelFixture("trace-index", async ({ root }) => {
|
|
9
|
+
const at = "2026-09-11T10:00:00.000Z";
|
|
10
|
+
const canonical = new WorkspaceFileSystem(root);
|
|
11
|
+
for (const [i, status] of ["draft", "cancelled", "blocked"].entries()) {
|
|
12
|
+
await canonical.writeTextAtomic(
|
|
13
|
+
`.agents/records/tasks/2026/09/task-${i}.md`,
|
|
14
|
+
serializeMarkdown({
|
|
15
|
+
metadata: {
|
|
16
|
+
schema_version: 2,
|
|
17
|
+
id: `TASK-INDEX-${i}`,
|
|
18
|
+
title: `Task ${status}`,
|
|
19
|
+
status,
|
|
20
|
+
revision: 1,
|
|
21
|
+
change_id: `CHG-INDEX-${i}`,
|
|
22
|
+
short_name: `index-${i}`,
|
|
23
|
+
objective: "Identity fixture",
|
|
24
|
+
risk: "standard",
|
|
25
|
+
priority: "medium",
|
|
26
|
+
owner: null,
|
|
27
|
+
requirement_ids: ["REQ-WORK-001"],
|
|
28
|
+
acceptance_ids: ["AC-WORK-001-09"],
|
|
29
|
+
depends_on: [],
|
|
30
|
+
write_scopes: ["proof"],
|
|
31
|
+
plan_revision: null,
|
|
32
|
+
plan_hash: null,
|
|
33
|
+
created_at: at,
|
|
34
|
+
updated_at: at,
|
|
35
|
+
started_at: null,
|
|
36
|
+
finished_at: null,
|
|
37
|
+
result: null,
|
|
38
|
+
},
|
|
39
|
+
body: "# Identity fixture\n",
|
|
40
|
+
}),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
await rebuildSqliteReadModel(root);
|
|
44
|
+
const sqlite = new SqliteReadModelFileSystem(root);
|
|
45
|
+
try {
|
|
46
|
+
const app = createDashboardApp(root, "fixture", undefined, { filesystem: sqlite });
|
|
47
|
+
const request = async (query: string) => {
|
|
48
|
+
const response = await app.request(`/api/v2/operations?${query}`, {
|
|
49
|
+
headers: { "x-zaip-session": "fixture" },
|
|
50
|
+
});
|
|
51
|
+
expect(response.status).toBe(200);
|
|
52
|
+
return response.json() as Promise<{
|
|
53
|
+
total: number;
|
|
54
|
+
tasks: { id: string; status: string }[];
|
|
55
|
+
}>;
|
|
56
|
+
};
|
|
57
|
+
const first = await request("scope=traceability&offset=0&limit=2");
|
|
58
|
+
const second = await request("scope=traceability&offset=2&limit=2");
|
|
59
|
+
expect(first.total).toBe(3);
|
|
60
|
+
expect(first.tasks).toHaveLength(2);
|
|
61
|
+
expect(second.tasks).toHaveLength(1);
|
|
62
|
+
expect([...first.tasks, ...second.tasks].map((task) => task.id)).toEqual([
|
|
63
|
+
"TASK-INDEX-2",
|
|
64
|
+
"TASK-INDEX-1",
|
|
65
|
+
"TASK-INDEX-0",
|
|
66
|
+
]);
|
|
67
|
+
expect(second.tasks[0]?.status).toBe("draft");
|
|
68
|
+
for (const stage of [
|
|
69
|
+
"definition",
|
|
70
|
+
"planning",
|
|
71
|
+
"ready",
|
|
72
|
+
"executing",
|
|
73
|
+
"completed",
|
|
74
|
+
"blocked",
|
|
75
|
+
]) {
|
|
76
|
+
const board = await request(`scope=board&stage=${stage}&kind=all-tasks`);
|
|
77
|
+
expect(board.tasks.map((task: { id: string }) => task.id)).not.toContain("TASK-INDEX-0");
|
|
78
|
+
}
|
|
79
|
+
expect((await request("scope=traceability&offset=3&limit=2")).tasks).toEqual([]);
|
|
80
|
+
} finally {
|
|
81
|
+
sqlite.close();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -212,6 +212,7 @@ export function createDashboardApp(
|
|
|
212
212
|
};
|
|
213
213
|
let observedSnapshotRevision: string | null = null;
|
|
214
214
|
const projectionRefreshDiagnostics = createProjectionRefreshDiagnostics();
|
|
215
|
+
let activeCaptureFailure: { code: string; occurred_at: string; cause: string } | null = null;
|
|
215
216
|
let projectionRefreshInFlight: Promise<void> | null = null;
|
|
216
217
|
let projectionRefreshRequested = false;
|
|
217
218
|
const rebuildProjection = async () => {
|
|
@@ -262,6 +263,16 @@ export function createDashboardApp(
|
|
|
262
263
|
? { captureActiveTelemetry: () => captureActiveCodexTelemetry(workspaceRoot) }
|
|
263
264
|
: {}),
|
|
264
265
|
onRefreshFailure: projectionRefreshDiagnostics.record,
|
|
266
|
+
onCaptureSuccess: () => {
|
|
267
|
+
activeCaptureFailure = null;
|
|
268
|
+
},
|
|
269
|
+
onCaptureFailure: (error) => {
|
|
270
|
+
activeCaptureFailure = {
|
|
271
|
+
code: "active_telemetry_capture_failed",
|
|
272
|
+
occurred_at: new Date().toISOString(),
|
|
273
|
+
cause: error instanceof Error ? error.name : "unknown_error",
|
|
274
|
+
};
|
|
275
|
+
},
|
|
265
276
|
});
|
|
266
277
|
const reconcileWork = createWorkReconciliation({
|
|
267
278
|
reconcile: (mode) =>
|
|
@@ -397,13 +408,15 @@ export function createDashboardApp(
|
|
|
397
408
|
kind: RUNTIME_KIND,
|
|
398
409
|
workspaceKey,
|
|
399
410
|
service: "zaip-aios-dashboard",
|
|
400
|
-
status:
|
|
411
|
+
status:
|
|
412
|
+
activeCaptureFailure === null ? projectionRefreshDiagnostics.healthStatus : "degraded",
|
|
401
413
|
api_version: 2,
|
|
402
414
|
workspace_layout: layout.version,
|
|
403
415
|
read_only: true,
|
|
404
416
|
storage: isSqliteSnapshot ? filesystem.metadata() : { storage_mode: "filesystem" },
|
|
405
417
|
snapshot_state: snapshotState,
|
|
406
418
|
projection_refresh_failure: projectionRefreshDiagnostics.failure,
|
|
419
|
+
active_capture_failure: activeCaptureFailure,
|
|
407
420
|
});
|
|
408
421
|
} catch (error) {
|
|
409
422
|
return headOrJson(
|
|
@@ -450,6 +463,7 @@ export function createDashboardApp(
|
|
|
450
463
|
day_count: metadata.daily_aggregate_count,
|
|
451
464
|
snapshot_state: snapshotState,
|
|
452
465
|
projection_refresh_failure: projectionRefreshDiagnostics.failure,
|
|
466
|
+
active_capture_failure: activeCaptureFailure,
|
|
453
467
|
snapshot_revision: revision,
|
|
454
468
|
});
|
|
455
469
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Intl's immutable formatter is reusable; timestamps and results are never cached.
|
|
2
|
+
const dateFormatter = new Intl.DateTimeFormat("en", {
|
|
3
|
+
timeZone: "America/Sao_Paulo",
|
|
4
|
+
year: "numeric",
|
|
5
|
+
month: "2-digit",
|
|
6
|
+
day: "2-digit",
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export function saoPauloDay(timestamp: string): string {
|
|
10
|
+
const values = Object.fromEntries(
|
|
11
|
+
dateFormatter
|
|
12
|
+
.formatToParts(new Date(timestamp))
|
|
13
|
+
.filter((part) => part.type !== "literal")
|
|
14
|
+
.map((part) => [part.type, part.value]),
|
|
15
|
+
) as { year: string; month: string; day: string };
|
|
16
|
+
return `${values.year}-${values.month}-${values.day}`;
|
|
17
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { expect, it, vi } from "vitest";
|
|
2
|
+
import { saoPauloDay } from "./sqlite-calendar.js";
|
|
3
|
+
import { readCanonicalLifecycleRecords } from "./sqlite-read-model-canonical.js";
|
|
4
|
+
import { isCanonicalLifecyclePath } from "./sqlite-read-model-canonical-parsing.js";
|
|
5
|
+
|
|
6
|
+
it("reuses only the immutable formatter and preserves calendar, DST and invalid input behavior", () => {
|
|
7
|
+
const cases = [
|
|
8
|
+
["2024-03-01T02:59:59Z", "2024-02-29"],
|
|
9
|
+
["2026-01-01T02:59:59Z", "2025-12-31"],
|
|
10
|
+
["2026-01-01T03:00:00Z", "2026-01-01"],
|
|
11
|
+
["2018-11-04T02:59:59Z", "2018-11-03"],
|
|
12
|
+
["2018-11-04T03:00:00Z", "2018-11-04"],
|
|
13
|
+
["2019-02-17T02:00:00Z", "2019-02-16"],
|
|
14
|
+
] as const;
|
|
15
|
+
const formatterConstructor = vi.spyOn(Intl, "DateTimeFormat");
|
|
16
|
+
try {
|
|
17
|
+
for (let index = 0; index < 100; index++)
|
|
18
|
+
for (const [timestamp, expected] of cases) expect(saoPauloDay(timestamp)).toBe(expected);
|
|
19
|
+
expect(() => saoPauloDay("invalid")).toThrow(RangeError);
|
|
20
|
+
expect(formatterConstructor).not.toHaveBeenCalled();
|
|
21
|
+
} finally {
|
|
22
|
+
formatterConstructor.mockRestore();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("ignores irrelevant source content before YAML parsing and keeps both lifecycle layouts", () => {
|
|
27
|
+
const ignored = [
|
|
28
|
+
".agents/records/tasks/2026/09/task.md",
|
|
29
|
+
".agents/records/changes/2026/09/C/artifacts/tests/test.md",
|
|
30
|
+
".agents/records/runs/run.jsonl",
|
|
31
|
+
".agents/records/executions/E/other.md",
|
|
32
|
+
".agents/records/changes/C/decisions/other.txt",
|
|
33
|
+
"elsewhere/executions/E/execution.md",
|
|
34
|
+
].map((path) => ({
|
|
35
|
+
path,
|
|
36
|
+
get content(): string {
|
|
37
|
+
throw new Error("Irrelevant content must never be inspected");
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
expect(readCanonicalLifecycleRecords(ignored)).toEqual({
|
|
41
|
+
executions: [],
|
|
42
|
+
changes: [],
|
|
43
|
+
decisions: [],
|
|
44
|
+
});
|
|
45
|
+
for (const layout of ["data", "records"]) {
|
|
46
|
+
const rows = [
|
|
47
|
+
{
|
|
48
|
+
path: `.agents/${layout}/executions/2026/09/E/execution.md`,
|
|
49
|
+
content:
|
|
50
|
+
"---\nid: E\ncreated_at: 2026-09-15T00:00:00Z\nstatus: blocked\norigin:\n type: interaction\n conversation_id: C\n---\n",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
path: `.agents/${layout}/changes/2026/09/H/change.md`,
|
|
54
|
+
content:
|
|
55
|
+
"---\nid: H\ncreated_at: 2026-09-15T00:00:00Z\nsource:\n type: task\n task_id: T\n---\n",
|
|
56
|
+
},
|
|
57
|
+
...["changes", "executions"].map((kind) => ({
|
|
58
|
+
path: `.agents/${layout}/${kind}/E/artifacts/decisions/D.md`,
|
|
59
|
+
content: `---\nid: D-${kind}\ncreated_at: 2026-09-15T00:00:00Z\norigin: human\nscope_type: execution\nscope_id: E\n---\n`,
|
|
60
|
+
})),
|
|
61
|
+
];
|
|
62
|
+
expect(rows.every((row) => isCanonicalLifecyclePath(row.path))).toBe(true);
|
|
63
|
+
const result = readCanonicalLifecycleRecords([...ignored, ...rows]);
|
|
64
|
+
expect(result.executions).toHaveLength(1);
|
|
65
|
+
expect(result.executions[0]).toMatchObject({ id: "E", originId: "C", status: "blocked" });
|
|
66
|
+
expect(result.changes).toHaveLength(1);
|
|
67
|
+
expect(result.changes[0]).toMatchObject({ id: "H", sourceId: "T" });
|
|
68
|
+
expect(result.decisions).toHaveLength(2);
|
|
69
|
+
expect(
|
|
70
|
+
readCanonicalLifecycleRecords([
|
|
71
|
+
{
|
|
72
|
+
path: `.agents/${layout}/executions/E/execution.md`,
|
|
73
|
+
content: "---\nid: [invalid\n---\n",
|
|
74
|
+
},
|
|
75
|
+
]).executions,
|
|
76
|
+
).toEqual([]);
|
|
77
|
+
}
|
|
78
|
+
});
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.test.ts
CHANGED
|
@@ -258,8 +258,19 @@ describe("cost invocation dimension rebuild", () => {
|
|
|
258
258
|
expect(factRows(database, "cost_invocation_dimension_facts")).toEqual(
|
|
259
259
|
factRows(database, "legacy_cost_invocation_dimension_facts"),
|
|
260
260
|
);
|
|
261
|
+
// SQLite versions bundled with supported Node runtimes may serialize REALs
|
|
262
|
+
// with different precision. The contract is exact legacy JSON parity on
|
|
263
|
+
// that engine, not a hard-coded decimal spelling from SQLite 3.49.
|
|
264
|
+
const expectedCosts = database
|
|
265
|
+
.prepare(`
|
|
266
|
+
SELECT json_extract(payload, '$.cost_usd') AS cost_usd,
|
|
267
|
+
json_extract(payload, '$.cost_brl') AS cost_brl
|
|
268
|
+
FROM (SELECT json_object('cost_usd', ?, 'cost_brl', ?) AS payload)
|
|
269
|
+
`)
|
|
270
|
+
.get(0.1 + 0.2, 1234567.8912345679);
|
|
271
|
+
expect(expectedCosts).toEqual({ cost_usd: expect.any(Number), cost_brl: expect.any(Number) });
|
|
261
272
|
expect(factRows(database, "cost_invocation_dimension_facts")).toContainEqual(
|
|
262
|
-
expect.objectContaining({ residual: 0,
|
|
273
|
+
expect.objectContaining({ residual: 0, ...expectedCosts }),
|
|
263
274
|
);
|
|
264
275
|
});
|
|
265
276
|
|