@zaip-ai/cli 2.6.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +71 -10
- package/templates/.agents/README.md +72 -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 +246 -134
- 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-TnrL1ZyZ.js} +915 -550
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-DEbCi1gP.js → PricingSettingsDialog-DjQpBqGU.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-BQZXUnQu.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-Basaw1NR.js +824 -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-BQe3zTvL.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 +238 -226
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +205 -195
- 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 +238 -226
- 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-cost-dimension-facts.test.ts +12 -1
- 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 +1 -1
- 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-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-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 +9 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +4 -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 +7 -2
- 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-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 +23 -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 +61 -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 +425 -269
- 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
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { cp, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import { createObservabilityFixture } from "../tests/observability-fixture.mjs";
|
|
7
|
+
|
|
8
|
+
const repository = resolve(import.meta.dirname, "../../..");
|
|
9
|
+
const runtimeRoot = join(repository, ".agents/dashboard/packages/local-runtime");
|
|
10
|
+
const require = createRequire(join(runtimeRoot, "package.json"));
|
|
11
|
+
const {
|
|
12
|
+
createDashboardApp,
|
|
13
|
+
rebuildSqliteReadModel,
|
|
14
|
+
SqliteReadModelFileSystem,
|
|
15
|
+
} = require("./dist/server.cjs");
|
|
16
|
+
const { serve } = require("@hono/node-server");
|
|
17
|
+
const { chromium, expect } = require("@playwright/test");
|
|
18
|
+
const testRoot = join(repository, ".local/sqlite/tests");
|
|
19
|
+
const evidenceParent = join(repository, ".local/autonomy-maintenance");
|
|
20
|
+
await mkdir(evidenceParent, { recursive: true });
|
|
21
|
+
const evidenceRoot = await mkdtemp(join(evidenceParent, "ui-"));
|
|
22
|
+
await mkdir(testRoot, { recursive: true });
|
|
23
|
+
await mkdir(evidenceRoot, { recursive: true });
|
|
24
|
+
const fixture = await mkdtemp(join(testRoot, "autonomy-settings-"));
|
|
25
|
+
const token = "synthetic-autonomy-local-only";
|
|
26
|
+
const report = {
|
|
27
|
+
synthetic: true,
|
|
28
|
+
platform: process.platform,
|
|
29
|
+
started_at: new Date().toISOString(),
|
|
30
|
+
candidate: "current uncommitted workspace builds; not release qualification",
|
|
31
|
+
evidence_directory: evidenceRoot,
|
|
32
|
+
checks: [],
|
|
33
|
+
passed: false,
|
|
34
|
+
};
|
|
35
|
+
let filesystem, server, browser, page;
|
|
36
|
+
try {
|
|
37
|
+
await createObservabilityFixture(fixture);
|
|
38
|
+
await mkdir(join(fixture, ".agents/config/agents"), { recursive: true });
|
|
39
|
+
await cp(
|
|
40
|
+
join(repository, ".agents/config/agents/catalog.yaml"),
|
|
41
|
+
join(fixture, ".agents/config/agents/catalog.yaml"),
|
|
42
|
+
);
|
|
43
|
+
await rebuildSqliteReadModel(fixture, { forceCanonical: true });
|
|
44
|
+
filesystem = new SqliteReadModelFileSystem(fixture);
|
|
45
|
+
const frontend = join(repository, ".agents/dashboard/apps/frontend/dist");
|
|
46
|
+
report.frontend_index_sha256 = createHash("sha256")
|
|
47
|
+
.update(await readFile(join(frontend, "index.html")))
|
|
48
|
+
.digest("hex");
|
|
49
|
+
report.server_sha256 = createHash("sha256")
|
|
50
|
+
.update(await readFile(join(runtimeRoot, "dist/server.cjs")))
|
|
51
|
+
.digest("hex");
|
|
52
|
+
const app = createDashboardApp(fixture, token, frontend, {
|
|
53
|
+
filesystem,
|
|
54
|
+
watchSources: false,
|
|
55
|
+
snapshotReadOnly: true,
|
|
56
|
+
});
|
|
57
|
+
server = serve({ fetch: app.fetch, hostname: "127.0.0.1", port: 0 });
|
|
58
|
+
await new Promise((done, fail) => {
|
|
59
|
+
if (server.listening) done();
|
|
60
|
+
else {
|
|
61
|
+
server.once("listening", done);
|
|
62
|
+
server.once("error", fail);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
const origin = `http://127.0.0.1:${server.address().port}`;
|
|
66
|
+
report.url = `${origin}/setup-project`;
|
|
67
|
+
browser = await chromium.launch({ headless: true });
|
|
68
|
+
page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
|
|
69
|
+
const errors = [];
|
|
70
|
+
page.on("pageerror", (error) => errors.push(error.message));
|
|
71
|
+
await page.goto(`${origin}/setup-project?token=${token}`, { waitUntil: "domcontentloaded" });
|
|
72
|
+
const select = page.getByRole("combobox", { name: "Perfil de autonomia" });
|
|
73
|
+
await expect(select).toHaveValue("balanced");
|
|
74
|
+
for (const preset of ["essential", "persistent", "balanced"]) {
|
|
75
|
+
await select.selectOption(preset);
|
|
76
|
+
if (preset === "essential")
|
|
77
|
+
await expect(
|
|
78
|
+
page.getByText("Nunca usa Astra automaticamente.", { exact: false }),
|
|
79
|
+
).toBeVisible();
|
|
80
|
+
if (preset === "persistent")
|
|
81
|
+
await expect(
|
|
82
|
+
page.getByRole("status").filter({ hasText: "Sem limite de tentativas" }),
|
|
83
|
+
).toBeVisible();
|
|
84
|
+
const saved = page.waitForResponse(
|
|
85
|
+
(response) =>
|
|
86
|
+
response.url().endsWith("/api/v2/project-settings") &&
|
|
87
|
+
response.request().method() === "PUT",
|
|
88
|
+
);
|
|
89
|
+
await page.getByRole("button", { name: "Salvar configurações" }).click();
|
|
90
|
+
const response = await saved;
|
|
91
|
+
assert.equal(response.status(), 200, await response.text());
|
|
92
|
+
const raw = await readFile(join(fixture, ".agents/config/project.yaml"), "utf8");
|
|
93
|
+
assert(raw.includes(`preset: ${preset}`));
|
|
94
|
+
const api = await fetch(`${origin}/api/v2/project-settings`, {
|
|
95
|
+
headers: { "x-zaip-session": token },
|
|
96
|
+
});
|
|
97
|
+
assert.equal(api.status, 200);
|
|
98
|
+
const data = await api.json();
|
|
99
|
+
assert.equal(data.autonomy.preset, preset);
|
|
100
|
+
await page.reload({ waitUntil: "domcontentloaded" });
|
|
101
|
+
await expect(select).toHaveValue(preset);
|
|
102
|
+
report.checks.push({ preset, api_status: 200, yaml_persisted: true, reload_confirmed: true });
|
|
103
|
+
}
|
|
104
|
+
await select.scrollIntoViewIfNeeded();
|
|
105
|
+
const runtimeSelect = page.getByLabel("Runtime", { exact: true });
|
|
106
|
+
const executionToggle = page.getByRole("checkbox", {
|
|
107
|
+
name: "Incluir configuração de execução",
|
|
108
|
+
exact: true,
|
|
109
|
+
});
|
|
110
|
+
if (!(await executionToggle.isChecked()))
|
|
111
|
+
await page.getByText("Incluir configuração de execução", { exact: true }).click();
|
|
112
|
+
await expect(executionToggle).toBeChecked();
|
|
113
|
+
if (await runtimeSelect.count()) {
|
|
114
|
+
await runtimeSelect.selectOption("managed");
|
|
115
|
+
const saved = page.waitForResponse(
|
|
116
|
+
(r) => r.url().endsWith("/api/v2/project-settings") && r.request().method() === "PUT",
|
|
117
|
+
);
|
|
118
|
+
await page.getByRole("button", { name: "Salvar configurações" }).click();
|
|
119
|
+
assert.equal((await saved).status(), 200);
|
|
120
|
+
const raw = await readFile(join(fixture, ".agents/config/project.yaml"), "utf8");
|
|
121
|
+
assert(raw.includes("runtime: managed"));
|
|
122
|
+
await page.reload({ waitUntil: "domcontentloaded" });
|
|
123
|
+
await expect(runtimeSelect).toHaveValue("managed");
|
|
124
|
+
report.checks.push({ scenario: "managed-runtime-yaml-reload", passed: true });
|
|
125
|
+
} else throw new Error("Runtime selector must be available for managed-mode proof");
|
|
126
|
+
await page.screenshot({ path: join(evidenceRoot, "autonomy-settings.png"), fullPage: true });
|
|
127
|
+
await page.setViewportSize({ width: 390, height: 844 });
|
|
128
|
+
await expect(page.locator(".project-settings-footer")).toHaveCSS("position", "static");
|
|
129
|
+
const disclosure = select.locator("xpath=../..").locator("p").last();
|
|
130
|
+
await disclosure.scrollIntoViewIfNeeded();
|
|
131
|
+
assert.equal(
|
|
132
|
+
await disclosure.evaluate((element) => {
|
|
133
|
+
const box = element.getBoundingClientRect();
|
|
134
|
+
return element.contains(
|
|
135
|
+
document.elementFromPoint(box.left + box.width / 2, box.top + box.height / 2),
|
|
136
|
+
);
|
|
137
|
+
}),
|
|
138
|
+
true,
|
|
139
|
+
"Mobile policy disclosure must not be covered by the save footer",
|
|
140
|
+
);
|
|
141
|
+
report.checks.push({ scenario: "mobile-disclosure-not-obscured", passed: true });
|
|
142
|
+
await select.scrollIntoViewIfNeeded();
|
|
143
|
+
await page.screenshot({
|
|
144
|
+
path: join(evidenceRoot, "autonomy-settings-mobile.png"),
|
|
145
|
+
fullPage: true,
|
|
146
|
+
});
|
|
147
|
+
await select.locator("xpath=../..").scrollIntoViewIfNeeded();
|
|
148
|
+
await select
|
|
149
|
+
.locator("xpath=../..")
|
|
150
|
+
.screenshot({ path: join(evidenceRoot, "autonomy-settings-mobile-detail.png") });
|
|
151
|
+
assert.deepEqual(errors, []);
|
|
152
|
+
report.screenshot_sha256 = createHash("sha256")
|
|
153
|
+
.update(await readFile(join(evidenceRoot, "autonomy-settings.png")))
|
|
154
|
+
.digest("hex");
|
|
155
|
+
report.passed = true;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
report.error = error.stack ?? String(error);
|
|
158
|
+
if (page)
|
|
159
|
+
report.failure_dom = await page
|
|
160
|
+
.locator("body")
|
|
161
|
+
.innerText()
|
|
162
|
+
.catch(() => "unavailable");
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
} finally {
|
|
165
|
+
await browser?.close();
|
|
166
|
+
if (server) {
|
|
167
|
+
server.closeAllConnections();
|
|
168
|
+
await new Promise((done) => server.close(done));
|
|
169
|
+
}
|
|
170
|
+
filesystem?.close();
|
|
171
|
+
report.finished_at = new Date().toISOString();
|
|
172
|
+
await writeFile(join(evidenceRoot, "report.json"), `${JSON.stringify(report, null, 2)}\n`);
|
|
173
|
+
await rm(fixture, { recursive: true, force: true });
|
|
174
|
+
console.log(JSON.stringify(report));
|
|
175
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { dirname, join, resolve } from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { createObservabilityFixture } from "../tests/observability-fixture.mjs";
|
|
8
|
+
|
|
9
|
+
const repository = resolve(import.meta.dirname, "../../..");
|
|
10
|
+
const runtimeRoot = join(repository, ".agents/dashboard/packages/local-runtime");
|
|
11
|
+
const runtimeRequire = createRequire(join(runtimeRoot, "package.json"));
|
|
12
|
+
const { createDashboardApp, rebuildSqliteReadModel, SqliteReadModelFileSystem } =
|
|
13
|
+
runtimeRequire("./dist/server.cjs");
|
|
14
|
+
const { serve } = runtimeRequire("@hono/node-server");
|
|
15
|
+
const { chromium } = runtimeRequire("@playwright/test");
|
|
16
|
+
const exec = promisify(execFile);
|
|
17
|
+
const testRoot = join(repository, ".local/sqlite/tests");
|
|
18
|
+
await mkdir(testRoot, { recursive: true });
|
|
19
|
+
const fixture = await mkdtemp(join(testRoot, "observability-"));
|
|
20
|
+
const evidenceFlag = process.argv.indexOf("--evidence");
|
|
21
|
+
const evidenceRoot =
|
|
22
|
+
evidenceFlag < 0 ? join(fixture, "evidence") : resolve(process.argv[evidenceFlag + 1]);
|
|
23
|
+
await mkdir(evidenceRoot, { recursive: true });
|
|
24
|
+
const report = {
|
|
25
|
+
synthetic: true,
|
|
26
|
+
platform: process.platform,
|
|
27
|
+
node_version: process.version,
|
|
28
|
+
candidate_version: JSON.parse(await readFile(join(repository, "package.json"), "utf8")).version,
|
|
29
|
+
started_at: new Date().toISOString(),
|
|
30
|
+
cli: [],
|
|
31
|
+
api: [],
|
|
32
|
+
dom: [],
|
|
33
|
+
passed: false,
|
|
34
|
+
};
|
|
35
|
+
const token = "synthetic-observability-local-only";
|
|
36
|
+
let filesystem, server, browser, page;
|
|
37
|
+
async function cli(args) {
|
|
38
|
+
const result = await exec(
|
|
39
|
+
process.execPath,
|
|
40
|
+
[join(repository, "packages/cli/dist/index.js"), ...args, "--workspace", fixture, "--json"],
|
|
41
|
+
{
|
|
42
|
+
cwd: fixture,
|
|
43
|
+
windowsHide: true,
|
|
44
|
+
timeout: 60_000,
|
|
45
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
46
|
+
env: { ...process.env, CODEX_HOME: join(fixture, ".codex-home"), ZAIP_WORKSPACE: fixture },
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
return JSON.parse(result.stdout);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const cases = await createObservabilityFixture(fixture);
|
|
53
|
+
for (const item of cases) {
|
|
54
|
+
const response = await cli(["task", "show", item.task]);
|
|
55
|
+
assert.equal(response.task.id, item.task);
|
|
56
|
+
assert.equal(response.task.status, item.status);
|
|
57
|
+
report.cli.push(response);
|
|
58
|
+
}
|
|
59
|
+
report.manifest = await cli(["manifest", "rebuild", "--confirm-full-scan"]);
|
|
60
|
+
assert.deepEqual(Object.keys(report.manifest.snapshot.periods.daily), ["2025-12-31"]);
|
|
61
|
+
assert.equal(report.manifest.snapshot.usage.total_tokens.known_sum, 15);
|
|
62
|
+
assert.equal(report.manifest.snapshot.usage.total_tokens.unknown, 1);
|
|
63
|
+
const manifest = JSON.parse(
|
|
64
|
+
await readFile(join(fixture, ".agents/records/lifecycle/entity-snapshot.json"), "utf8"),
|
|
65
|
+
);
|
|
66
|
+
for (const item of cases)
|
|
67
|
+
assert.equal(manifest.entities[`task:${item.task}`].status, item.status);
|
|
68
|
+
report.sqlite = await rebuildSqliteReadModel(fixture, { forceCanonical: true });
|
|
69
|
+
filesystem = new SqliteReadModelFileSystem(fixture);
|
|
70
|
+
const app = createDashboardApp(
|
|
71
|
+
fixture,
|
|
72
|
+
token,
|
|
73
|
+
join(repository, ".agents/dashboard/apps/frontend/dist"),
|
|
74
|
+
{
|
|
75
|
+
filesystem,
|
|
76
|
+
watchSources: false,
|
|
77
|
+
snapshotReadOnly: true,
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
server = serve({ fetch: app.fetch, hostname: "127.0.0.1", port: 0 });
|
|
81
|
+
await new Promise((resolveReady, reject) => {
|
|
82
|
+
if (server.listening) resolveReady();
|
|
83
|
+
else {
|
|
84
|
+
server.once("listening", resolveReady);
|
|
85
|
+
server.once("error", reject);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
const origin = `http://127.0.0.1:${server.address().port}`;
|
|
89
|
+
report.url = origin;
|
|
90
|
+
async function api(route) {
|
|
91
|
+
const response = await fetch(`${origin}${route}`, {
|
|
92
|
+
headers: { "x-zaip-session": token },
|
|
93
|
+
signal: AbortSignal.timeout(20_000),
|
|
94
|
+
});
|
|
95
|
+
const body = await response.text();
|
|
96
|
+
assert.equal(response.status, 200, `${route}: ${body}`);
|
|
97
|
+
return JSON.parse(body);
|
|
98
|
+
}
|
|
99
|
+
for (const item of cases) {
|
|
100
|
+
const detail = await api(`/api/v2/tasks/${item.task}`);
|
|
101
|
+
const trace = await api(`/api/v2/tasks/${item.task}/trace`);
|
|
102
|
+
assert.equal(detail.task.id, item.task);
|
|
103
|
+
assert.equal(detail.task.status, item.status);
|
|
104
|
+
assert.equal(trace.task_id, item.task);
|
|
105
|
+
assert.equal(trace.change_id, item.change);
|
|
106
|
+
assert.equal(trace.task_progress, item.status === "completed" ? 100 : 0);
|
|
107
|
+
assert.equal(trace.usage.total_tokens.value, item.tokens);
|
|
108
|
+
assert.equal(trace.usage.total_tokens.unknown_runs, item.tokens === null ? 1 : 0);
|
|
109
|
+
assert.equal(trace.usage.cost.value, item.status === "failed" ? null : 0);
|
|
110
|
+
assert.equal(trace.usage.cost.unknown_runs, item.status === "blocked" ? 0 : 1);
|
|
111
|
+
if (item.status === "completed") assert.equal(trace.usage.cost.coverage_ratio, 2 / 3);
|
|
112
|
+
assert(trace.documents.some((document) => document.content.includes(item.run)));
|
|
113
|
+
if (item.status === "completed") {
|
|
114
|
+
const documents = trace.documents.map((document) => document.content).join("\n");
|
|
115
|
+
assert(documents.includes(`${item.run}-PRIOR`), "Retry predecessor omitted from trace");
|
|
116
|
+
assert(documents.includes(`${item.run}-FINALIZER`), "Finalizer child omitted from trace");
|
|
117
|
+
assert(documents.includes("retry_of_run_id"), "Retry relationship omitted from trace");
|
|
118
|
+
report.retry_finalizer = {
|
|
119
|
+
task: item.task,
|
|
120
|
+
predecessor: `${item.run}-PRIOR`,
|
|
121
|
+
finalizer: `${item.run}-FINALIZER`,
|
|
122
|
+
attempt: detail.task.attempt_count,
|
|
123
|
+
};
|
|
124
|
+
assert.equal(detail.task.attempt_count, 2);
|
|
125
|
+
}
|
|
126
|
+
const canonical = await filesystem.readText(`.agents/records/tasks/2026/01/${item.task}.md`);
|
|
127
|
+
assert(canonical.includes(item.task));
|
|
128
|
+
report.api.push({ detail, trace });
|
|
129
|
+
}
|
|
130
|
+
report.cost_filters = [];
|
|
131
|
+
for (const currency of ["BRL", "USD"]) {
|
|
132
|
+
const costs = await api(
|
|
133
|
+
`/api/v2/cost-monitor?scope=summary¤cy=${currency}&from=2025-12-31&to=2025-12-31`,
|
|
134
|
+
);
|
|
135
|
+
assert.equal(costs.overview.run_count, 5, "Unknown Run disappeared from financial coverage");
|
|
136
|
+
assert.equal(costs.overview.total_tokens, 15);
|
|
137
|
+
assert.equal(costs.usage.rework.tokens.total, 15, "Observed rework was classified as new work");
|
|
138
|
+
assert.equal(costs.usage.new_work.tokens.total, 0);
|
|
139
|
+
const nextDay = await api(
|
|
140
|
+
`/api/v2/cost-monitor?scope=summary¤cy=${currency}&from=2026-01-01&to=2026-01-01`,
|
|
141
|
+
);
|
|
142
|
+
assert.equal(nextDay.overview.run_count, 0, "UTC day leaked into Sao Paulo period");
|
|
143
|
+
report.cost_filters.push({ currency, costs, nextDay });
|
|
144
|
+
}
|
|
145
|
+
browser = await chromium.launch({ headless: true, timeout: 30_000 });
|
|
146
|
+
report.browser_version = browser.version();
|
|
147
|
+
page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
|
|
148
|
+
page.setDefaultTimeout(20_000);
|
|
149
|
+
report.browser_responses = [];
|
|
150
|
+
page.on("response", async (response) => {
|
|
151
|
+
if (response.url().includes("/api/v2/")) {
|
|
152
|
+
report.browser_responses.push({
|
|
153
|
+
url: response.url(),
|
|
154
|
+
status: response.status(),
|
|
155
|
+
body: await response.text().catch(() => ""),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
await page.goto(`${origin}/?token=${token}`, { waitUntil: "domcontentloaded", timeout: 30_000 });
|
|
160
|
+
await page
|
|
161
|
+
.getByRole("navigation", { name: "Áreas do dashboard" })
|
|
162
|
+
.getByRole("button", { name: /Rastreabilidade/ })
|
|
163
|
+
.click();
|
|
164
|
+
const costCard = page
|
|
165
|
+
.locator("article")
|
|
166
|
+
.filter({ has: page.getByText("Custo Estimado", { exact: true }) })
|
|
167
|
+
.first();
|
|
168
|
+
assert(
|
|
169
|
+
(await costCard.innerText()).includes("Indisponível"),
|
|
170
|
+
"Partial known-zero costs were presented as an exact total",
|
|
171
|
+
);
|
|
172
|
+
// Task pagination spans lifecycle stages; explicitly load remaining stages
|
|
173
|
+
// through the real scrolling interaction before searching literal IDs.
|
|
174
|
+
const searchBox = page.getByRole("combobox", { name: "Buscar task por nome ou ID" });
|
|
175
|
+
await searchBox.click();
|
|
176
|
+
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
177
|
+
if ((await page.getByRole("option").count()) === cases.length) break;
|
|
178
|
+
await page.getByRole("listbox", { name: "Buscar task por nome ou ID" }).evaluate((element) => {
|
|
179
|
+
element.scrollTop = element.scrollHeight;
|
|
180
|
+
element.dispatchEvent(new Event("scroll", { bubbles: true }));
|
|
181
|
+
});
|
|
182
|
+
await page.waitForFunction(() => !document.body.innerText.includes("Carregando mais tasks"));
|
|
183
|
+
}
|
|
184
|
+
for (const item of cases) {
|
|
185
|
+
const search = page.getByRole("combobox", { name: "Buscar task por nome ou ID" });
|
|
186
|
+
await search.fill(item.task);
|
|
187
|
+
const traceResponse = page.waitForResponse(
|
|
188
|
+
(response) =>
|
|
189
|
+
response.url().endsWith(`/tasks/${item.task}/trace`) && response.status() === 200,
|
|
190
|
+
);
|
|
191
|
+
await page.locator(`[id="traceability-task-option-${item.task}"]`).click();
|
|
192
|
+
await traceResponse;
|
|
193
|
+
await page.getByText(item.task, { exact: true }).first().waitFor({ state: "visible" });
|
|
194
|
+
const text = await page.locator("body").innerText();
|
|
195
|
+
assert(text.includes(item.task), `UI omitted literal ID ${item.task}`);
|
|
196
|
+
if (item.status === "completed")
|
|
197
|
+
assert.match(text, /PROGRESSO\s+100%/, "Hydration replaced canonical completed progress");
|
|
198
|
+
report.dom.push({ task: item.task, text });
|
|
199
|
+
if (item.status === "completed") {
|
|
200
|
+
await page.locator('button[data-stage="execution"]').click();
|
|
201
|
+
for (const suffix of ["PRIOR", "FINALIZER"]) {
|
|
202
|
+
const literal = `${item.run}-${suffix}`;
|
|
203
|
+
await page.locator(".trace-stage-documents button").filter({ hasText: literal }).click();
|
|
204
|
+
const document = page.locator(".trace-document");
|
|
205
|
+
await document.waitFor({ state: "visible" });
|
|
206
|
+
const content = await document.locator("pre").innerText();
|
|
207
|
+
assert(content.includes(literal));
|
|
208
|
+
assert(
|
|
209
|
+
content.includes(
|
|
210
|
+
suffix === "FINALIZER" ? '"run_purpose":"finalization"' : '"status":"failed"',
|
|
211
|
+
),
|
|
212
|
+
);
|
|
213
|
+
report.dom.push({ run: literal, text: content });
|
|
214
|
+
await document.getByRole("button").click();
|
|
215
|
+
}
|
|
216
|
+
await page
|
|
217
|
+
.getByRole("button", { name: "Fechar detalhes da etapa", exact: true })
|
|
218
|
+
.last()
|
|
219
|
+
.click();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
await page.screenshot({ path: join(evidenceRoot, "traceability.png"), fullPage: true });
|
|
223
|
+
report.captured_at = new Date().toISOString();
|
|
224
|
+
report.passed = true;
|
|
225
|
+
} catch (error) {
|
|
226
|
+
report.error = error.stack ?? String(error);
|
|
227
|
+
if (page) {
|
|
228
|
+
report.failure_dom = await page
|
|
229
|
+
.locator("body")
|
|
230
|
+
.innerText()
|
|
231
|
+
.catch(() => "DOM unavailable");
|
|
232
|
+
await page
|
|
233
|
+
.screenshot({ path: join(evidenceRoot, "failure.png"), fullPage: true })
|
|
234
|
+
.catch(() => {});
|
|
235
|
+
}
|
|
236
|
+
process.exitCode = 1;
|
|
237
|
+
} finally {
|
|
238
|
+
await browser?.close();
|
|
239
|
+
if (server) {
|
|
240
|
+
server.closeAllConnections();
|
|
241
|
+
await new Promise((done) => server.close(done));
|
|
242
|
+
}
|
|
243
|
+
filesystem?.close();
|
|
244
|
+
report.finished_at = new Date().toISOString();
|
|
245
|
+
await writeFile(join(evidenceRoot, "observability.json"), `${JSON.stringify(report, null, 2)}\n`);
|
|
246
|
+
console.log(
|
|
247
|
+
JSON.stringify({ passed: report.passed, evidence: evidenceRoot, error: report.error }),
|
|
248
|
+
);
|
|
249
|
+
// Only this invocation's mkdtemp fixture is removed. Explicit evidence survives.
|
|
250
|
+
if (evidenceFlag >= 0) {
|
|
251
|
+
assert.equal(dirname(fixture), testRoot);
|
|
252
|
+
await rm(fixture, { recursive: true, force: true });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
// Dashboard verification is workspace tooling, not frontend source. Keep the
|
|
8
|
+
// repository root explicit now that this script lives beside dashboard scripts.
|
|
9
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
|
|
10
|
+
const mode = process.argv[2];
|
|
11
|
+
if (!["test", "integration", "check"].includes(mode))
|
|
12
|
+
throw new Error("Expected test|integration|check");
|
|
13
|
+
|
|
14
|
+
function execute(args, timeout = 180_000) {
|
|
15
|
+
const result = spawnSync(process.execPath, args, {
|
|
16
|
+
cwd: root,
|
|
17
|
+
encoding: "utf8",
|
|
18
|
+
windowsHide: true,
|
|
19
|
+
timeout,
|
|
20
|
+
maxBuffer: 8_000_000,
|
|
21
|
+
});
|
|
22
|
+
const output = stripVTControlCharacters((result.stdout ?? "") + "\n" + (result.stderr ?? ""));
|
|
23
|
+
if (result.status !== 0) {
|
|
24
|
+
process.stderr.write(output);
|
|
25
|
+
throw new Error("Project setup validation failed: " + (result.error?.message ?? result.status));
|
|
26
|
+
}
|
|
27
|
+
return output;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!existsSync(resolve(root, "node_modules/vitest/vitest.mjs"))) {
|
|
31
|
+
if (spawnSync("git", ["symbolic-ref", "-q", "HEAD"], { cwd: root }).status !== 1)
|
|
32
|
+
throw new Error("Prepare dependencies in the Task checkout first");
|
|
33
|
+
const pnpm = resolve(dirname(process.execPath), "node_modules/corepack/dist/pnpm.js");
|
|
34
|
+
execute([pnpm, "install", "--offline", "--frozen-lockfile", "--ignore-scripts"], 300_000);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (mode === "check") {
|
|
38
|
+
for (const project of [
|
|
39
|
+
".agents/dashboard/apps/frontend/tsconfig.json",
|
|
40
|
+
".agents/design/apps/catalog/tsconfig.json",
|
|
41
|
+
]) {
|
|
42
|
+
execute(["node_modules/typescript/bin/tsc", "--noEmit", "--project", project]);
|
|
43
|
+
}
|
|
44
|
+
console.log(JSON.stringify({ kind: "project_setup_typecheck", passed: true, mode }));
|
|
45
|
+
} else {
|
|
46
|
+
const prefix = ".agents/dashboard/apps/frontend/src/";
|
|
47
|
+
const files =
|
|
48
|
+
mode === "test"
|
|
49
|
+
? ["project-installation-status.test.ts", "project-settings.test.ts"]
|
|
50
|
+
: ["ProjectSettingsPage.dom.test.ts"];
|
|
51
|
+
const output = execute([
|
|
52
|
+
"node_modules/vitest/vitest.mjs",
|
|
53
|
+
"run",
|
|
54
|
+
...files.map((file) => prefix + file),
|
|
55
|
+
"--maxWorkers=1",
|
|
56
|
+
]);
|
|
57
|
+
const tests = output
|
|
58
|
+
.split("\n")
|
|
59
|
+
.find((line) => /^\s*Tests\s/.test(line))
|
|
60
|
+
?.trim();
|
|
61
|
+
if (!tests || !/\b[1-9]\d* passed\b/.test(tests))
|
|
62
|
+
throw new Error("No project setup tests executed");
|
|
63
|
+
console.log(JSON.stringify({ kind: "project_setup_" + mode, passed: true, mode, tests, output }));
|
|
64
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FullConfig } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
/** The suite owns one runtime across browser pages, including failed-test restarts. */
|
|
4
|
+
export default async function holdSuiteLease(config: FullConfig) {
|
|
5
|
+
const baseURL = config.projects[0]?.use.baseURL;
|
|
6
|
+
if (!baseURL) throw new Error("Dashboard E2E requires its explicit server URL");
|
|
7
|
+
const url = new URL("/api/v2/browser-lease", baseURL);
|
|
8
|
+
url.searchParams.set("token", "e2e-token");
|
|
9
|
+
const controller = new AbortController();
|
|
10
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
11
|
+
if (!response.ok || !response.body) {
|
|
12
|
+
controller.abort();
|
|
13
|
+
throw new Error(`Dashboard suite lease rejected: ${response.status}`);
|
|
14
|
+
}
|
|
15
|
+
const reader = response.body.getReader();
|
|
16
|
+
const first = await reader.read();
|
|
17
|
+
if (first.done || !new TextDecoder().decode(first.value).includes("lease")) {
|
|
18
|
+
controller.abort();
|
|
19
|
+
throw new Error("Dashboard suite did not acquire its real SSE lease");
|
|
20
|
+
}
|
|
21
|
+
let failure: unknown;
|
|
22
|
+
const drain = (async () => {
|
|
23
|
+
try {
|
|
24
|
+
while (!(await reader.read()).done) {
|
|
25
|
+
/* Keep the real lease stream consumed. */
|
|
26
|
+
}
|
|
27
|
+
if (!controller.signal.aborted) failure = new Error("Dashboard suite lease ended early");
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (!controller.signal.aborted) failure = error;
|
|
30
|
+
}
|
|
31
|
+
})();
|
|
32
|
+
return async () => {
|
|
33
|
+
controller.abort();
|
|
34
|
+
await drain;
|
|
35
|
+
if (failure) throw failure;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -7,13 +7,15 @@ const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? `http://127.0.0.1:${serverPor
|
|
|
7
7
|
|
|
8
8
|
export default defineConfig({
|
|
9
9
|
testDir: "./specs",
|
|
10
|
+
globalSetup: "./lease-global-setup.ts",
|
|
10
11
|
fullyParallel: false,
|
|
11
12
|
timeout: 180_000,
|
|
12
13
|
expect: { timeout: 60_000 },
|
|
13
14
|
retries: process.env.CI ? 1 : 0,
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
|
|
15
|
+
// Every suite invocation shares one SQLite runtime, including local release
|
|
16
|
+
// qualification. Concurrent browser workers turn latency/export checks into
|
|
17
|
+
// an unintended load test whose result depends on the host CPU count.
|
|
18
|
+
workers: 1,
|
|
17
19
|
reporter: process.env.CI ? "github" : "list",
|
|
18
20
|
use: {
|
|
19
21
|
baseURL: `${baseURL}/?token=e2e-token`,
|
|
@@ -4,6 +4,18 @@ const COST_MONITOR_PATH = "/api/v2/cost-monitor";
|
|
|
4
4
|
const STALE_SUMMARY_SENTINEL = "SENTINELA-RESPOSTA-ANTIGA";
|
|
5
5
|
const fiveSeconds = 5_000;
|
|
6
6
|
|
|
7
|
+
test("reselecting the current bounded period never opens an unfinishable transition", async ({
|
|
8
|
+
page,
|
|
9
|
+
}) => {
|
|
10
|
+
await openDashboard(page);
|
|
11
|
+
await selectThisMonth(page);
|
|
12
|
+
await expect(periodControl(page)).toHaveValue("this-month");
|
|
13
|
+
await periodControl(page).selectOption("this-month");
|
|
14
|
+
await expect(page.locator(".period-transition-overlay")).toHaveCount(0, { timeout: fiveSeconds });
|
|
15
|
+
await expect(periodControl(page)).toHaveValue("this-month");
|
|
16
|
+
await expect(page.getByLabel("Kanban de trabalho")).toBeVisible();
|
|
17
|
+
});
|
|
18
|
+
|
|
7
19
|
test("refreshes Cost Monitor within five seconds when Todo o Período is selected in place", async ({
|
|
8
20
|
page,
|
|
9
21
|
}) => {
|
|
@@ -86,12 +98,14 @@ test("does not let a late all-time summary overwrite the newer period", async ({
|
|
|
86
98
|
});
|
|
87
99
|
await page.addInitScript(() => {
|
|
88
100
|
type Probe = {
|
|
101
|
+
armed: boolean;
|
|
89
102
|
allTimeBody: string | null;
|
|
90
103
|
allTimeFinished: boolean;
|
|
91
104
|
allTimeStarted: boolean;
|
|
92
105
|
releaseAllTime: null | (() => Promise<void>);
|
|
93
106
|
};
|
|
94
107
|
const probe: Probe = {
|
|
108
|
+
armed: false,
|
|
95
109
|
allTimeBody: null,
|
|
96
110
|
allTimeFinished: false,
|
|
97
111
|
allTimeStarted: false,
|
|
@@ -109,7 +123,8 @@ test("does not let a late all-time summary overwrite the newer period", async ({
|
|
|
109
123
|
url.searchParams.get("scope") === "summary" &&
|
|
110
124
|
!url.searchParams.has("from") &&
|
|
111
125
|
!url.searchParams.has("to");
|
|
112
|
-
if (!isAllTimeSummary || probe.allTimeStarted)
|
|
126
|
+
if (!probe.armed || !isAllTimeSummary || probe.allTimeStarted)
|
|
127
|
+
return originalFetch(input, init);
|
|
113
128
|
|
|
114
129
|
probe.allTimeStarted = true;
|
|
115
130
|
return new Promise<Response>((resolve, reject) => {
|
|
@@ -138,7 +153,12 @@ test("does not let a late all-time summary overwrite the newer period", async ({
|
|
|
138
153
|
const staleBody = withStaleSummarySentinel(priorPeriodBody!);
|
|
139
154
|
await page.evaluate((body) => {
|
|
140
155
|
window.__costSummaryStaleProbe.allTimeBody = body;
|
|
156
|
+
// Arm only after the bounded snapshot is ready. The default first paint
|
|
157
|
+
// also requests All Time; intercepting it can satisfy the later wait early
|
|
158
|
+
// and race React's commit rather than the stale-response guard.
|
|
159
|
+
window.__costSummaryStaleProbe.armed = true;
|
|
141
160
|
}, staleBody);
|
|
161
|
+
expect(await page.evaluate(() => window.__costSummaryStaleProbe.allTimeStarted)).toBe(false);
|
|
142
162
|
|
|
143
163
|
await periodControl(page).selectOption("all");
|
|
144
164
|
await expect
|
|
@@ -160,6 +180,7 @@ test("does not let a late all-time summary overwrite the newer period", async ({
|
|
|
160
180
|
declare global {
|
|
161
181
|
interface Window {
|
|
162
182
|
__costSummaryStaleProbe: {
|
|
183
|
+
armed: boolean;
|
|
163
184
|
allTimeBody: string | null;
|
|
164
185
|
allTimeFinished: boolean;
|
|
165
186
|
allTimeStarted: boolean;
|