@zaip-ai/cli 1.3.8 → 1.4.1
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 +58 -3
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +17 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/services/adapters.js +4 -4
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/codex-config-template.d.ts +2 -2
- package/dist/services/codex-config-template.d.ts.map +1 -1
- package/dist/services/codex-config-template.js +3 -3
- package/dist/services/codex-config-template.js.map +1 -1
- package/dist/services/codex-rules.d.ts +1 -1
- package/dist/services/codex-rules.d.ts.map +1 -1
- package/dist/services/codex-rules.js +9 -24
- package/dist/services/codex-rules.js.map +1 -1
- package/dist/services/delivery-git-preflight.d.ts +23 -0
- package/dist/services/delivery-git-preflight.d.ts.map +1 -0
- package/dist/services/delivery-git-preflight.js +69 -0
- package/dist/services/delivery-git-preflight.js.map +1 -0
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +13 -1
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/install-agents-template.d.ts.map +1 -1
- package/dist/services/install-agents-template.js +22 -28
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/install-profile.d.ts +8 -0
- package/dist/services/install-profile.d.ts.map +1 -0
- package/dist/services/install-profile.js +56 -0
- package/dist/services/install-profile.js.map +1 -0
- package/dist/services/logger.d.ts.map +1 -1
- package/dist/services/logger.js +6 -5
- package/dist/services/logger.js.map +1 -1
- package/dist/services/stack-git.d.ts +9 -0
- package/dist/services/stack-git.d.ts.map +1 -0
- package/dist/services/stack-git.js +188 -0
- package/dist/services/stack-git.js.map +1 -0
- package/dist/services/stack-plan.d.ts +3 -1
- package/dist/services/stack-plan.d.ts.map +1 -1
- package/dist/services/stack-plan.js +15 -1
- package/dist/services/stack-plan.js.map +1 -1
- package/dist/services/stack-terraform.d.ts +13 -0
- package/dist/services/stack-terraform.d.ts.map +1 -0
- package/dist/services/stack-terraform.js +274 -0
- package/dist/services/stack-terraform.js.map +1 -0
- package/dist/services/template-manifest.d.ts.map +1 -1
- package/dist/services/template-manifest.js +14 -1
- package/dist/services/template-manifest.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/.env.example +34 -0
- package/templates/{README.md → .agents/README.md} +124 -60
- package/templates/.agents/config/agents/catalog.yaml +23 -23
- package/templates/.agents/config/clients/codex/agents/zaip-agent-analyst.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-auditor.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +5 -4
- package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +10 -7
- package/templates/.agents/config/clients/codex/agents/zaip-agent-data-analyst.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +5 -4
- package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-integrator.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +5 -4
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-refactoring-specialist.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-reviewer.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-security-auditor.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +1 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +5 -4
- package/templates/.agents/config/clients/codex/agents/zaip-agent-writer.toml +1 -0
- package/templates/.agents/config/pricing/models.json +25 -1
- package/templates/.agents/config/project.yaml +2 -0
- package/templates/.agents/dashboard/.zaip-managed.json +200 -88
- package/templates/.agents/dashboard/DATA-DICTIONARY.md +1 -1
- package/templates/.agents/dashboard/README.md +58 -19
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-DwVZOmMV.js → CostCalculationGuidePage-snUCQYTC.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-VcLx9iOO.js → DashboardHelpDialog-oZVlf-l5.js} +72 -8
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-CyjMXkm8.js → PricingSettingsDialog-BPtVUGgs.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-3Awyaovx.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-DFZwIXSC.js → TraceabilityWorkspace-BYjVOHI_.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DbaLbU2q.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DXBOtWNI.js → icons-vendor-TPUT2IUt.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cmlx8OYH.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-ZJFXmK7m.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-DaNXQPyk.js → react-vendor-Ct48XHGL.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-I4AKqVDX.js → traceability-BDe4_Ubl.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +6 -6
- package/templates/.agents/dashboard/apps/frontend/src/App.tsx +73 -67
- package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +35 -7
- package/templates/.agents/dashboard/apps/frontend/src/AppWorkBoard.ts +55 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +11 -0
- package/templates/.agents/dashboard/apps/frontend/src/app-loading-boundary.css +98 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +5 -5
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api-reconciliation.ts +33 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +75 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +7 -8
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +14 -2
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +35 -0
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +78 -2
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +28 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +8 -5
- package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +180 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +7 -4
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +13 -7
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +14 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableDisplay.ts +211 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +152 -157
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +155 -142
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/InvocationManifestQuery.test.ts +145 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +7 -5
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +4 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +4 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +4 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +4 -4
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +79 -1
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +105 -11
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +482 -332
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +430 -285
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +14 -2
- package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +6 -26
- package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/verify-persistent-launch.mjs +268 -0
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +482 -332
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +90 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +112 -22
- package/templates/.agents/dashboard/packages/local-runtime/src/server-agent-assets.ts +39 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-browser-lease.ts +33 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-refresh.test.ts +148 -11
- package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-result.test.ts +68 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +19 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.ts +39 -43
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-revision.test.ts +42 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-revision.ts +26 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +34 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-startup.ts +30 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-work-reconciliation.test.ts +89 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-work-reconciliation.ts +88 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +68 -7
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +11 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +129 -99
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-agent-productivity.test.ts +111 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-agent-productivity.ts +140 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.test.ts +127 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.ts +145 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-aggregates.ts +156 -23
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts +18 -9
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-projection.ts +52 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-persistence.ts +35 -13
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-force-canonical.test.ts +56 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-cache.test.ts +29 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-cache.ts +136 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-refresh.test.ts +251 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +22 -7
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-cache.test-support.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical-parsing.ts +42 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +793 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider-duration.test.ts +270 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider-fixture.ts +3 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +18 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.test.ts +87 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +105 -16
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +131 -59
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +1000 -1115
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-cache.ts +13 -92
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-claims.test.mjs +79 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +27 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.mjs +6 -6
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-prerequisites.mjs +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-refresh.mjs +2 -10
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-server.mjs +142 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +231 -239
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +18 -29
- package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +6 -0
- package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +47 -0
- 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 +2 -2
- 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 +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/rules/autonomy-decision.md +1 -1
- package/templates/.agents/rules/cloud-hostinger-autonomy.md +21 -0
- package/templates/.agents/rules/core.md +5 -4
- package/templates/.agents/rules/local-sqlite-storage.md +18 -0
- package/templates/.agents/rules/meta-mcp.md +21 -0
- package/templates/.agents/rules/workflow.md +1 -0
- package/templates/.agents/runtime/bin/zaip.mjs +305 -137
- package/templates/.agents/runtime/checksums.sha256 +2 -2
- package/templates/.agents/runtime/provenance.json +2 -2
- package/templates/.agents/skills/zaip-skill-api-to-mcp/SKILL.md +4 -0
- package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +25 -9
- package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-framework.md +2 -2
- package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +2 -2
- package/templates/.agents/skills/zaip-skill-change/references/observable-evidence.md +15 -0
- package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +13 -5
- package/templates/.agents/skills/zaip-skill-data-analyst/SKILL.md +10 -5
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +5 -4
- package/templates/.agents/skills/zaip-skill-frontend-launcher/SKILL.md +4 -3
- package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +5 -3
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +5 -5
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.mjs +78 -13
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.test.mjs +59 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/yaml-parser.mjs +157 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +11 -6
- package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/SKILL.md +17 -0
- package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/agents/openai.yaml +7 -0
- package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/autonomous-cloud-inputs.example.json +41 -0
- package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/autonomous-runner.md +84 -0
- package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/operational-contract.md +19 -0
- package/templates/.agents/skills/zaip-skill-local-credentials/SKILL.md +43 -0
- package/templates/.agents/skills/zaip-skill-local-credentials/agents/openai.yaml +6 -0
- package/templates/.agents/skills/zaip-skill-local-credentials/references/dotenv-resolution.md +47 -0
- package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +8 -3
- package/templates/.agents/skills/zaip-skill-meta-ads/SKILL.md +16 -0
- package/templates/.agents/skills/zaip-skill-meta-ads/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-ads/references/setup.md +3 -0
- package/templates/.agents/skills/zaip-skill-meta-ads-setup/SKILL.md +24 -0
- package/templates/.agents/skills/zaip-skill-meta-ads-setup/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-ads-setup/references/diagnostics.md +13 -0
- package/templates/.agents/skills/zaip-skill-meta-ads-setup/references/official-sources.md +10 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/references/upstream.md +77 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/references/upstream.md +126 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/references/upstream.md +67 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/references/upstream.md +69 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/references/upstream.md +79 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/SKILL.md +14 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/references/upstream.md +144 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/references/upstream.md +83 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/SKILL.md +10 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/references/setup.md +11 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/references/upstream.md +55 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/references/LICENSE +21 -0
- package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/references/upstream.md +56 -0
- package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +12 -7
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +11 -4
- package/templates/.agents/skills/zaip-skill-tool-setup/SKILL.md +6 -4
- package/templates/.agents/skills/zaip-skill-tool-setup/references/codex-config.md +4 -2
- package/templates/.agents/skills/zaip-skill-tool-setup/references/secrets.md +1 -0
- package/templates/.agents/tools/catalog.yaml +6 -0
- package/templates/.agents/tools/cloud-runner-dns.mjs +28 -0
- package/templates/.agents/tools/cloud-runner-terraform.mjs +212 -0
- package/templates/.agents/tools/cloud-runner.integration.test.mjs +239 -0
- package/templates/.agents/tools/cloud-runner.mjs +786 -0
- package/templates/.agents/tools/cloud-runner.test.mjs +534 -0
- package/templates/.agents/tools/cloud-terraform-plan-policy.mjs +262 -0
- package/templates/.agents/tools/mcp/development/meta-devtools/README.md +14 -0
- package/templates/.agents/tools/mcp/development/meta-devtools/manifest.yaml +28 -0
- package/templates/.agents/tools/mcp/infra/cloudflare/manifest.yaml +2 -3
- package/templates/.agents/tools/mcp/infra/hostinger/manifest.yaml +1 -3
- package/templates/.agents/tools/mcp/marketing/meta-ads/README.md +15 -13
- package/templates/.agents/tools/mcp/marketing/meta-ads/manifest.yaml +15 -10
- package/templates/.agents/tools/profiles/development.yaml +3 -0
- package/templates/infra/terraform/.terraform.lock.hcl +42 -0
- package/templates/infra/terraform/README.md +31 -0
- package/templates/infra/terraform/backend.tf.json +13 -0
- package/templates/infra/terraform/deployment-inputs.example.yaml +22 -0
- package/templates/infra/terraform/fixtures/approved-targets.json +32 -0
- package/templates/infra/terraform/fixtures/plan-approved.json +67 -0
- package/templates/infra/terraform/main.tf +77 -0
- package/templates/infra/terraform/outputs.tf +20 -0
- package/templates/infra/terraform/terraform.tfvars.example +26 -0
- package/templates/infra/terraform/variables.tf +91 -0
- package/templates/infra/terraform/versions.tf +18 -0
- package/templates/scripts/validate-cloud-hostinger-contract.mjs +89 -0
- package/templates/scripts/validate-cloud-terraform-plan.mjs +1 -0
- package/templates/template-manifest.json +599 -167
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BwnJpl02.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-C09KmlSw.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Dyo_wpL4.js +0 -2
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-hPPfVGQv.css +0 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-stale-seed.ts +0 -50
|
@@ -23,6 +23,17 @@ import {
|
|
|
23
23
|
projectSetupPath,
|
|
24
24
|
renderAppSetupRoute,
|
|
25
25
|
} from "./AppSetupRoutes.js";
|
|
26
|
+
import {
|
|
27
|
+
type BoardStageState,
|
|
28
|
+
initialWorkBoardStages,
|
|
29
|
+
type OverviewClassification,
|
|
30
|
+
type OverviewClassificationPages,
|
|
31
|
+
type OverviewStatusKind,
|
|
32
|
+
type OverviewStatusPages,
|
|
33
|
+
overviewClassificationPageKey,
|
|
34
|
+
overviewStatusPageKey,
|
|
35
|
+
traceTaskSearchStages,
|
|
36
|
+
} from "./AppWorkBoard.js";
|
|
26
37
|
import { currencyKey, initialDashboardView, savedLocale } from "./app-preferences.js";
|
|
27
38
|
import { readDashboardSessionToken } from "./app-session-token.js";
|
|
28
39
|
import { renderDashboardAlternateContent } from "./DashboardAlternateContent.js";
|
|
@@ -39,6 +50,7 @@ import type {
|
|
|
39
50
|
WorkBoardStage,
|
|
40
51
|
} from "./dashboard-api.js";
|
|
41
52
|
import { DashboardApiClient } from "./dashboard-api.js";
|
|
53
|
+
import { reconciliationCommandOutcome } from "./dashboard-api-reconciliation.js";
|
|
42
54
|
import {
|
|
43
55
|
defaultOperationsPeriod,
|
|
44
56
|
isAllTimeDisplayRangeChange,
|
|
@@ -58,53 +70,6 @@ import { useOperationsDetailExport } from "./use-operations-detail-export.js";
|
|
|
58
70
|
import "./loading-feedback.css";
|
|
59
71
|
import "./period-transition-overlay.css";
|
|
60
72
|
|
|
61
|
-
type BoardStageState = { loading: boolean; error: string | null };
|
|
62
|
-
type OverviewStatusKind = "task" | "spec" | "prd";
|
|
63
|
-
type OverviewClassification = "lite" | "standard" | "critical" | "empty" | "structured" | "rework";
|
|
64
|
-
type OverviewStatusPage = {
|
|
65
|
-
items:
|
|
66
|
-
| OperationsProjection["tasks"]
|
|
67
|
-
| OperationsProjection["specs"]
|
|
68
|
-
| OperationsProjection["prds"];
|
|
69
|
-
total: number;
|
|
70
|
-
loading: boolean;
|
|
71
|
-
error: string | null;
|
|
72
|
-
};
|
|
73
|
-
type OverviewStatusPages = Partial<
|
|
74
|
-
Record<`${WorkBoardStage}:${OverviewStatusKind}`, OverviewStatusPage>
|
|
75
|
-
>;
|
|
76
|
-
const overviewStatusPageKey = (stage: WorkBoardStage, kind: OverviewStatusKind) =>
|
|
77
|
-
`${stage}:${kind}` as const;
|
|
78
|
-
type OverviewClassificationPages = Partial<
|
|
79
|
-
Record<`${OverviewStatusKind}:${OverviewClassification}`, OverviewStatusPage>
|
|
80
|
-
>;
|
|
81
|
-
const overviewClassificationPageKey = (
|
|
82
|
-
kind: OverviewStatusKind,
|
|
83
|
-
classification: OverviewClassification,
|
|
84
|
-
) => `${kind}:${classification}` as const;
|
|
85
|
-
const initialWorkBoardStages: readonly WorkBoardStage[] = [
|
|
86
|
-
"definition",
|
|
87
|
-
"planning",
|
|
88
|
-
"ready",
|
|
89
|
-
"executing",
|
|
90
|
-
"verifying",
|
|
91
|
-
"completed",
|
|
92
|
-
"blocked",
|
|
93
|
-
"cancelled",
|
|
94
|
-
"failed",
|
|
95
|
-
];
|
|
96
|
-
const traceTaskSearchStages: readonly WorkBoardStage[] = [
|
|
97
|
-
"completed",
|
|
98
|
-
"executing",
|
|
99
|
-
"ready",
|
|
100
|
-
"blocked",
|
|
101
|
-
"verifying",
|
|
102
|
-
"failed",
|
|
103
|
-
"cancelled",
|
|
104
|
-
"planning",
|
|
105
|
-
"definition",
|
|
106
|
-
];
|
|
107
|
-
|
|
108
73
|
export {
|
|
109
74
|
isAbortError,
|
|
110
75
|
isCurrentCostSummaryRequest,
|
|
@@ -119,6 +84,14 @@ export {
|
|
|
119
84
|
shouldLoadCostSummary,
|
|
120
85
|
} from "./AppRequestGuards.js";
|
|
121
86
|
export function App() {
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
const token = readDashboardSessionToken();
|
|
89
|
+
if (!token) return undefined;
|
|
90
|
+
// EventSource remains open for hidden tabs and reconnects after reload,
|
|
91
|
+
// giving the local runtime a browser-owned lifecycle without a fast poll.
|
|
92
|
+
const lease = new EventSource(`/api/v2/browser-lease?token=${encodeURIComponent(token)}`);
|
|
93
|
+
return () => lease.close();
|
|
94
|
+
}, []);
|
|
122
95
|
const [snapshotUpdating, setSnapshotUpdating] = useState(false);
|
|
123
96
|
const [snapshotNoticeDismissed, setSnapshotNoticeDismissed] = useState(false);
|
|
124
97
|
const [snapshotNoticeDelayElapsed, setSnapshotNoticeDelayElapsed] = useState(false);
|
|
@@ -275,7 +248,12 @@ export function App() {
|
|
|
275
248
|
// forcing a second full aggregate calculation.
|
|
276
249
|
const initialAggregateFreshRef = useRef(false);
|
|
277
250
|
const refresh = useCallback(
|
|
278
|
-
async (
|
|
251
|
+
async (
|
|
252
|
+
visible = true,
|
|
253
|
+
reconcileOpenWork = false,
|
|
254
|
+
refreshProjection = false,
|
|
255
|
+
reloadCostSummary = false,
|
|
256
|
+
) => {
|
|
279
257
|
operationsDetailCancelRef.current?.();
|
|
280
258
|
operationsDetailCancelRef.current = null;
|
|
281
259
|
operationsDetailAbortRef.current?.abort();
|
|
@@ -310,20 +288,36 @@ export function App() {
|
|
|
310
288
|
setError(null);
|
|
311
289
|
setFailedArea(null);
|
|
312
290
|
try {
|
|
313
|
-
if (reconcileOpenWork
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
291
|
+
if (reconcileOpenWork) {
|
|
292
|
+
const reconciliationResponse = await api.reconcileOpenWork(currency, period);
|
|
293
|
+
const commandOutcome = reconciliationCommandOutcome(
|
|
294
|
+
reconciliationResponse,
|
|
295
|
+
isCurrentRequest(),
|
|
296
|
+
);
|
|
297
|
+
// The compact reconciliation outcome is useful on its own. Reveal
|
|
298
|
+
// it before the optional quick GET so a historical snapshot load
|
|
299
|
+
// cannot keep the operator in the progress dialog.
|
|
300
|
+
setReconciliationResult(commandOutcome.reconciliation);
|
|
301
|
+
if (commandOutcome.dismissProgressDialog) setRefreshDialog(null);
|
|
302
|
+
if (!commandOutcome.applySnapshotState) return false;
|
|
303
|
+
setSnapshotUpdating(reconciliationResponse.snapshot_state === "updating");
|
|
304
|
+
// Reconciliation returns promptly while a new SQLite generation may
|
|
305
|
+
// still be promoted. Only read a compact Operations projection when
|
|
306
|
+
// that promotion is already complete; the revision observer handles
|
|
307
|
+
// the deferred case without fetching Cost Monitor detail data.
|
|
308
|
+
if (commandOutcome.reloadQuickProjection) {
|
|
309
|
+
const projection = await api.operations(period, "quick", undefined, true);
|
|
310
|
+
if (!isCurrentRequest()) return false;
|
|
311
|
+
initialAggregateFreshRef.current = false;
|
|
312
|
+
setOperations(projection);
|
|
313
|
+
quickOverviewMetricsRef.current = projection.summary.overview_metrics;
|
|
314
|
+
operationsDetailLoadedRef.current = false;
|
|
315
|
+
setLastUpdatedAt(projection.summary.source_latest_at);
|
|
324
316
|
}
|
|
325
|
-
|
|
326
|
-
|
|
317
|
+
} else if (refreshProjection) {
|
|
318
|
+
let snapshot: Awaited<ReturnType<typeof api.refreshProjection>>;
|
|
319
|
+
snapshot = await api.refreshProjection(currency, period);
|
|
320
|
+
if (!isCurrentRequest()) return false;
|
|
327
321
|
setOperations(snapshot.operations);
|
|
328
322
|
quickOverviewMetricsRef.current = snapshot.operations.summary.overview_metrics;
|
|
329
323
|
operationsDetailLoadedRef.current = true;
|
|
@@ -346,11 +340,11 @@ export function App() {
|
|
|
346
340
|
// An English first paint must have the factual USD summary
|
|
347
341
|
// before Operations formats currency. BRL retains the fast
|
|
348
342
|
// Operations-only path until the user opens Cost Monitor.
|
|
349
|
-
currency === "USD"
|
|
343
|
+
currency === "USD" || reloadCostSummary
|
|
350
344
|
? api.costMonitor(currency, period, "summary")
|
|
351
345
|
: Promise.resolve(null),
|
|
352
346
|
]);
|
|
353
|
-
if (!isCurrentRequest()) return;
|
|
347
|
+
if (!isCurrentRequest()) return false;
|
|
354
348
|
initialAggregateFreshRef.current = false;
|
|
355
349
|
setOperations(projection);
|
|
356
350
|
quickOverviewMetricsRef.current = projection.summary.overview_metrics;
|
|
@@ -365,10 +359,12 @@ export function App() {
|
|
|
365
359
|
setLastUpdatedAt(projection.summary.source_latest_at);
|
|
366
360
|
}
|
|
367
361
|
}
|
|
362
|
+
return true;
|
|
368
363
|
} catch (cause) {
|
|
369
|
-
if (!isCurrentRequest()) return;
|
|
364
|
+
if (!isCurrentRequest()) return false;
|
|
370
365
|
setError(cause instanceof Error ? cause.message : String(cause));
|
|
371
366
|
setFailedArea(activeDashboardView === "cost-monitor" ? "costs" : "operations");
|
|
367
|
+
return false;
|
|
372
368
|
} finally {
|
|
373
369
|
if (
|
|
374
370
|
isCurrentRequest() &&
|
|
@@ -737,8 +733,14 @@ export function App() {
|
|
|
737
733
|
setReconciliationResult(null);
|
|
738
734
|
}
|
|
739
735
|
setRefreshDialog(reconcileOpenWork ? "reconciling" : "refreshing");
|
|
740
|
-
|
|
741
|
-
|
|
736
|
+
try {
|
|
737
|
+
await refresh(false, reconcileOpenWork, !reconcileOpenWork);
|
|
738
|
+
} finally {
|
|
739
|
+
// A transport/runtime failure must not trap the user in the progress
|
|
740
|
+
// overlay. `refresh` normally reports the error on the affected panel;
|
|
741
|
+
// this also covers an unexpected rejection before it reaches that path.
|
|
742
|
+
setRefreshDialog(null);
|
|
743
|
+
}
|
|
742
744
|
};
|
|
743
745
|
useAppEffects({
|
|
744
746
|
api,
|
|
@@ -754,10 +756,12 @@ export function App() {
|
|
|
754
756
|
pricing,
|
|
755
757
|
refresh,
|
|
756
758
|
refreshVersion,
|
|
759
|
+
setSnapshotUpdating,
|
|
757
760
|
setError,
|
|
758
761
|
setFxRate,
|
|
759
762
|
setPathname,
|
|
760
763
|
setPricing,
|
|
764
|
+
snapshotUpdating,
|
|
761
765
|
});
|
|
762
766
|
|
|
763
767
|
const navigate = (nextPath: string) => {
|
|
@@ -972,7 +976,9 @@ export function App() {
|
|
|
972
976
|
navigate,
|
|
973
977
|
pathname,
|
|
974
978
|
pricing,
|
|
975
|
-
refresh
|
|
979
|
+
refresh: async () => {
|
|
980
|
+
await refresh();
|
|
981
|
+
},
|
|
976
982
|
setFxRate,
|
|
977
983
|
setPricing,
|
|
978
984
|
});
|
|
@@ -2,6 +2,22 @@ import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contrac
|
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
3
|
import { DashboardSkeleton } from "./AppLoadingPanels.js";
|
|
4
4
|
import { PeriodTransitionOverlay } from "./AppRequestGuards.js";
|
|
5
|
+
import "./app-loading-boundary.css";
|
|
6
|
+
|
|
7
|
+
const errorCopy = {
|
|
8
|
+
"pt-BR": {
|
|
9
|
+
action: "Tentar novamente",
|
|
10
|
+
guidance:
|
|
11
|
+
"Abra a pasta dashboard dentro de .agents e dê dois cliques novamente no arquivo executável.",
|
|
12
|
+
title: "Não foi possível carregar o dashboard",
|
|
13
|
+
},
|
|
14
|
+
"en-US": {
|
|
15
|
+
action: "Try again",
|
|
16
|
+
guidance:
|
|
17
|
+
"Open the dashboard folder inside .agents, then double-click the executable file again.",
|
|
18
|
+
title: "Unable to load the dashboard",
|
|
19
|
+
},
|
|
20
|
+
} as const;
|
|
5
21
|
|
|
6
22
|
export function AppLoadingBoundary({
|
|
7
23
|
children,
|
|
@@ -24,14 +40,26 @@ export function AppLoadingBoundary({
|
|
|
24
40
|
}) {
|
|
25
41
|
if (setupRoute !== null) return setupRoute;
|
|
26
42
|
if (error && operations === null) {
|
|
43
|
+
const copy = errorCopy[locale];
|
|
27
44
|
return (
|
|
28
|
-
<main className="app-
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
<main className="app-loading-boundary" aria-labelledby="dashboard-load-error-title">
|
|
46
|
+
<section className="app-loading-boundary__card" role="alert">
|
|
47
|
+
<div aria-hidden="true" className="app-loading-boundary__status-icon">
|
|
48
|
+
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
|
49
|
+
<path d="M12 8v4m0 4h.01M10.29 3.86 2.82 16.5A2 2 0 0 0 4.54 19.5h14.92a2 2 0 0 0 1.72-3L13.71 3.86a2 2 0 0 0-3.42 0Z" />
|
|
50
|
+
</svg>
|
|
51
|
+
</div>
|
|
52
|
+
<div className="app-loading-boundary__content">
|
|
53
|
+
<p className="app-loading-boundary__eyebrow">
|
|
54
|
+
{locale === "pt-BR" ? "Dashboard indisponível" : "Dashboard unavailable"}
|
|
55
|
+
</p>
|
|
56
|
+
<h1 id="dashboard-load-error-title">{copy.title}</h1>
|
|
57
|
+
<p>{copy.guidance}</p>
|
|
58
|
+
</div>
|
|
59
|
+
<button onClick={onRefresh} type="button">
|
|
60
|
+
{copy.action}
|
|
61
|
+
</button>
|
|
62
|
+
</section>
|
|
35
63
|
</main>
|
|
36
64
|
);
|
|
37
65
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contracts";
|
|
2
|
+
import type { WorkBoardStage } from "./dashboard-api.js";
|
|
3
|
+
|
|
4
|
+
export type BoardStageState = { loading: boolean; error: string | null };
|
|
5
|
+
export type OverviewStatusKind = "task" | "spec" | "prd";
|
|
6
|
+
export type OverviewClassification =
|
|
7
|
+
| "lite"
|
|
8
|
+
| "standard"
|
|
9
|
+
| "critical"
|
|
10
|
+
| "empty"
|
|
11
|
+
| "structured"
|
|
12
|
+
| "rework";
|
|
13
|
+
export type OverviewStatusPage = {
|
|
14
|
+
items:
|
|
15
|
+
| OperationsProjection["tasks"]
|
|
16
|
+
| OperationsProjection["specs"]
|
|
17
|
+
| OperationsProjection["prds"];
|
|
18
|
+
total: number;
|
|
19
|
+
loading: boolean;
|
|
20
|
+
error: string | null;
|
|
21
|
+
};
|
|
22
|
+
export type OverviewStatusPages = Partial<
|
|
23
|
+
Record<`${WorkBoardStage}:${OverviewStatusKind}`, OverviewStatusPage>
|
|
24
|
+
>;
|
|
25
|
+
export const overviewStatusPageKey = (stage: WorkBoardStage, kind: OverviewStatusKind) =>
|
|
26
|
+
`${stage}:${kind}` as const;
|
|
27
|
+
export type OverviewClassificationPages = Partial<
|
|
28
|
+
Record<`${OverviewStatusKind}:${OverviewClassification}`, OverviewStatusPage>
|
|
29
|
+
>;
|
|
30
|
+
export const overviewClassificationPageKey = (
|
|
31
|
+
kind: OverviewStatusKind,
|
|
32
|
+
classification: OverviewClassification,
|
|
33
|
+
) => `${kind}:${classification}` as const;
|
|
34
|
+
export const initialWorkBoardStages: readonly WorkBoardStage[] = [
|
|
35
|
+
"definition",
|
|
36
|
+
"planning",
|
|
37
|
+
"ready",
|
|
38
|
+
"executing",
|
|
39
|
+
"verifying",
|
|
40
|
+
"completed",
|
|
41
|
+
"blocked",
|
|
42
|
+
"cancelled",
|
|
43
|
+
"failed",
|
|
44
|
+
];
|
|
45
|
+
export const traceTaskSearchStages: readonly WorkBoardStage[] = [
|
|
46
|
+
"completed",
|
|
47
|
+
"executing",
|
|
48
|
+
"ready",
|
|
49
|
+
"blocked",
|
|
50
|
+
"verifying",
|
|
51
|
+
"failed",
|
|
52
|
+
"cancelled",
|
|
53
|
+
"planning",
|
|
54
|
+
"definition",
|
|
55
|
+
];
|
|
@@ -17,6 +17,7 @@ const componentLabels: Record<StackComponentId, { pt: string; en: string }> = {
|
|
|
17
17
|
cache_messaging: { pt: "Cache e mensageria", en: "Cache and messaging" },
|
|
18
18
|
async_queue: { pt: "Filas e processamento assíncrono", en: "Queues and async processing" },
|
|
19
19
|
backend_infrastructure: { pt: "Infraestrutura backend", en: "Backend infrastructure" },
|
|
20
|
+
backend_hosting: { pt: "Hospedagem do backend", en: "Backend hosting" },
|
|
20
21
|
web_framework: { pt: "Framework do Web App", en: "Web App framework" },
|
|
21
22
|
web_language: { pt: "Linguagem do Web App", en: "Web App language" },
|
|
22
23
|
web_build: { pt: "Build do Web App", en: "Web App build" },
|
|
@@ -26,6 +27,14 @@ const componentLabels: Record<StackComponentId, { pt: string; en: string }> = {
|
|
|
26
27
|
site_islands: { pt: "Componentes interativos", en: "Interactive components" },
|
|
27
28
|
site_build: { pt: "Build do site", en: "Site build" },
|
|
28
29
|
site_hosting: { pt: "Hospedagem do site", en: "Site hosting" },
|
|
30
|
+
prometheus: { pt: "Coleta de métricas", en: "Metrics collection" },
|
|
31
|
+
grafana: { pt: "Dashboards", en: "Dashboards" },
|
|
32
|
+
uptime_kuma: { pt: "Monitoramento de disponibilidade", en: "Availability monitoring" },
|
|
33
|
+
cadvisor: { pt: "Métricas de containers", en: "Container metrics" },
|
|
34
|
+
node_exporter: { pt: "Métricas de host", en: "Host metrics" },
|
|
35
|
+
redis_exporter: { pt: "Métricas do Redis", en: "Redis metrics" },
|
|
36
|
+
k6: { pt: "Teste de carga", en: "Load testing" },
|
|
37
|
+
autocannon: { pt: "Teste HTTP de carga", en: "HTTP load testing" },
|
|
29
38
|
};
|
|
30
39
|
|
|
31
40
|
export function StackComponentEditor({
|
|
@@ -48,6 +57,8 @@ export function StackComponentEditor({
|
|
|
48
57
|
scope: "site",
|
|
49
58
|
title: locale === "pt-BR" ? "Site e landing pages" : "Site and landing pages",
|
|
50
59
|
},
|
|
60
|
+
{ scope: "observability", title: locale === "pt-BR" ? "Observabilidade" : "Observability" },
|
|
61
|
+
{ scope: "testing", title: locale === "pt-BR" ? "Testes sob demanda" : "On-demand testing" },
|
|
51
62
|
] as const;
|
|
52
63
|
const update = (
|
|
53
64
|
id: StackComponentId,
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
.app-loading-boundary {
|
|
2
|
+
display: grid;
|
|
3
|
+
min-height: 100vh;
|
|
4
|
+
padding: 24px;
|
|
5
|
+
place-items: center;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.app-loading-boundary__card {
|
|
9
|
+
display: grid;
|
|
10
|
+
width: min(100%, 520px);
|
|
11
|
+
gap: 24px;
|
|
12
|
+
padding: clamp(24px, 5vw, 40px);
|
|
13
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
14
|
+
border-radius: 24px;
|
|
15
|
+
background: linear-gradient(145deg, rgba(17, 24, 39, 0.94), rgba(10, 14, 23, 0.98));
|
|
16
|
+
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
|
|
17
|
+
text-align: center;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.app-loading-boundary__status-icon {
|
|
21
|
+
display: grid;
|
|
22
|
+
width: 48px;
|
|
23
|
+
height: 48px;
|
|
24
|
+
margin-inline: auto;
|
|
25
|
+
border: 1px solid rgba(220, 38, 38, 0.42);
|
|
26
|
+
border-radius: 999px;
|
|
27
|
+
background: rgba(220, 38, 38, 0.14);
|
|
28
|
+
color: #fecaca;
|
|
29
|
+
place-items: center;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.app-loading-boundary__status-icon svg {
|
|
33
|
+
width: 24px;
|
|
34
|
+
height: 24px;
|
|
35
|
+
fill: none;
|
|
36
|
+
stroke: currentColor;
|
|
37
|
+
stroke-linecap: round;
|
|
38
|
+
stroke-linejoin: round;
|
|
39
|
+
stroke-width: 1.8;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.app-loading-boundary__content {
|
|
43
|
+
display: grid;
|
|
44
|
+
gap: 10px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.app-loading-boundary__eyebrow {
|
|
48
|
+
margin: 0;
|
|
49
|
+
color: #fecaca;
|
|
50
|
+
font-size: 0.75rem;
|
|
51
|
+
font-weight: 700;
|
|
52
|
+
letter-spacing: 0.12em;
|
|
53
|
+
line-height: 1.3;
|
|
54
|
+
text-transform: uppercase;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.app-loading-boundary h1 {
|
|
58
|
+
margin: 0;
|
|
59
|
+
color: #f1f5f9;
|
|
60
|
+
font-size: clamp(1.75rem, 4vw, 2.25rem);
|
|
61
|
+
font-weight: 650;
|
|
62
|
+
letter-spacing: -0.035em;
|
|
63
|
+
line-height: 1.15;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.app-loading-boundary__content > p:last-child {
|
|
67
|
+
max-width: 44ch;
|
|
68
|
+
margin: 0 auto;
|
|
69
|
+
color: #cbd5e1;
|
|
70
|
+
font-size: 1rem;
|
|
71
|
+
line-height: 1.65;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.app-loading-boundary button {
|
|
75
|
+
min-height: 44px;
|
|
76
|
+
justify-self: center;
|
|
77
|
+
border: 1px solid transparent;
|
|
78
|
+
border-radius: 999px;
|
|
79
|
+
padding: 12px 22px;
|
|
80
|
+
background: linear-gradient(135deg, #00b0f0 0%, #72f4fb 100%);
|
|
81
|
+
color: #042330;
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
font-weight: 700;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.app-loading-boundary button:hover {
|
|
87
|
+
filter: brightness(1.06);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@media (max-width: 420px) {
|
|
91
|
+
.app-loading-boundary {
|
|
92
|
+
padding: 16px;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.app-loading-boundary__card {
|
|
96
|
+
gap: 20px;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -137,7 +137,7 @@ describe("Cost period refresh", () => {
|
|
|
137
137
|
'api.operations(period, "quick", undefined, initialAggregateFreshRef.current)',
|
|
138
138
|
);
|
|
139
139
|
expect(compactRefresh).toContain(
|
|
140
|
-
'currency === "USD" ? api.costMonitor(currency, period, "summary") : Promise.resolve(null)',
|
|
140
|
+
'currency === "USD" || reloadCostSummary ? api.costMonitor(currency, period, "summary") : Promise.resolve(null)',
|
|
141
141
|
);
|
|
142
142
|
expect(refresh).toContain("setDisplayedCosts(null);");
|
|
143
143
|
expect(refresh).toContain("const activeDashboardView = dashboardViewRef.current");
|
|
@@ -168,10 +168,10 @@ describe("Cost period refresh", () => {
|
|
|
168
168
|
expect(loaders).toMatch(/api\.sqliteViewPage\(\s*"cost_monitor_agent_invocations"/);
|
|
169
169
|
expect(loaders).toContain("const loadCostGroupPage = useCallback<LoadCostGroupPage>");
|
|
170
170
|
expect(loaders).toContain("task_count: nullableSqlNumber(row.task_count)");
|
|
171
|
-
expect(loaders).toContain("prd_count:
|
|
172
|
-
expect(loaders).toContain("spec_count:
|
|
173
|
-
expect(loaders).toContain("evidence_count:
|
|
174
|
-
expect(loaders).toContain("test_count:
|
|
171
|
+
expect(loaders).toContain("prd_count: nullableSqlNumber(row.prd_count)");
|
|
172
|
+
expect(loaders).toContain("spec_count: nullableSqlNumber(row.spec_count)");
|
|
173
|
+
expect(loaders).toContain("evidence_count: nullableSqlNumber(row.evidence_count)");
|
|
174
|
+
expect(loaders).toContain("test_count: nullableSqlNumber(row.validation_count)");
|
|
175
175
|
for (const dimension of [
|
|
176
176
|
"provider",
|
|
177
177
|
"model",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReconciliationResult } from "./dashboard-api.js";
|
|
2
|
+
|
|
3
|
+
export interface ReconcileOpenWorkResponse {
|
|
4
|
+
reconciliation: ReconciliationResult;
|
|
5
|
+
snapshot_state: "current" | "updating";
|
|
6
|
+
projection_refresh_completed: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function shouldReloadQuickProjectionAfterReconciliation(
|
|
10
|
+
response: ReconcileOpenWorkResponse,
|
|
11
|
+
): boolean {
|
|
12
|
+
return response.projection_refresh_completed;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function reconciliationCommandOutcome(
|
|
16
|
+
response: ReconcileOpenWorkResponse,
|
|
17
|
+
isCurrentRequest: boolean,
|
|
18
|
+
): {
|
|
19
|
+
reconciliation: ReconciliationResult;
|
|
20
|
+
dismissProgressDialog: true;
|
|
21
|
+
applySnapshotState: boolean;
|
|
22
|
+
reloadQuickProjection: boolean;
|
|
23
|
+
} {
|
|
24
|
+
return {
|
|
25
|
+
// The command result belongs to the operator's POST, rather than to the
|
|
26
|
+
// projection request version. It must survive a passive GET race.
|
|
27
|
+
reconciliation: response.reconciliation,
|
|
28
|
+
dismissProgressDialog: true,
|
|
29
|
+
applySnapshotState: isCurrentRequest,
|
|
30
|
+
reloadQuickProjection:
|
|
31
|
+
isCurrentRequest && shouldReloadQuickProjectionAfterReconciliation(response),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { DashboardApiClient, reconciliationRequestTimeoutMs } from "./dashboard-api.js";
|
|
3
|
+
import {
|
|
4
|
+
reconciliationCommandOutcome,
|
|
5
|
+
shouldReloadQuickProjectionAfterReconciliation,
|
|
6
|
+
} from "./dashboard-api-reconciliation.js";
|
|
3
7
|
|
|
4
8
|
describe("DashboardApiClient reconciliation", () => {
|
|
5
9
|
afterEach(() => {
|
|
@@ -53,6 +57,47 @@ describe("DashboardApiClient reconciliation", () => {
|
|
|
53
57
|
);
|
|
54
58
|
});
|
|
55
59
|
|
|
60
|
+
it("accepts the compact reconciliation result and reloads only after its projection is ready", async () => {
|
|
61
|
+
vi.stubGlobal("window", globalThis);
|
|
62
|
+
const response = {
|
|
63
|
+
reconciliation: { reconciled_ids: ["TASK-1"], blocked: [], not_reconciled: [] },
|
|
64
|
+
snapshot_state: "updating" as const,
|
|
65
|
+
projection_refresh_completed: false,
|
|
66
|
+
};
|
|
67
|
+
vi.stubGlobal(
|
|
68
|
+
"fetch",
|
|
69
|
+
vi.fn(async () => new Response(JSON.stringify(response), { status: 200 })),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
await expect(new DashboardApiClient("session").reconcileOpenWork()).resolves.toEqual(response);
|
|
73
|
+
expect(shouldReloadQuickProjectionAfterReconciliation(response)).toBe(false);
|
|
74
|
+
expect(
|
|
75
|
+
shouldReloadQuickProjectionAfterReconciliation({
|
|
76
|
+
...response,
|
|
77
|
+
snapshot_state: "current",
|
|
78
|
+
projection_refresh_completed: true,
|
|
79
|
+
}),
|
|
80
|
+
).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("keeps a delayed reconciliation result visible when a passive GET supersedes its request", () => {
|
|
84
|
+
const response = {
|
|
85
|
+
reconciliation: { reconciled_ids: ["TASK-1"], blocked: [], not_reconciled: [] },
|
|
86
|
+
snapshot_state: "current" as const,
|
|
87
|
+
projection_refresh_completed: true,
|
|
88
|
+
};
|
|
89
|
+
// A passive revision GET has advanced requestVersion while the POST was
|
|
90
|
+
// in flight. Its stale quick data must not overwrite the newer screen,
|
|
91
|
+
// while the command outcome still belongs to the user's button click.
|
|
92
|
+
const afterPassiveGet = reconciliationCommandOutcome(response, false);
|
|
93
|
+
expect(afterPassiveGet).toEqual({
|
|
94
|
+
reconciliation: response.reconciliation,
|
|
95
|
+
dismissProgressDialog: true,
|
|
96
|
+
applySnapshotState: false,
|
|
97
|
+
reloadQuickProjection: false,
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
56
101
|
it("refreshes the disposable projection without calling the reconciliation route", async () => {
|
|
57
102
|
vi.stubGlobal("window", globalThis);
|
|
58
103
|
const fetchMock = vi.fn(async () => new Response(JSON.stringify({}), { status: 200 }));
|
|
@@ -70,6 +115,36 @@ describe("DashboardApiClient reconciliation", () => {
|
|
|
70
115
|
});
|
|
71
116
|
});
|
|
72
117
|
|
|
118
|
+
describe("DashboardApiClient readiness", () => {
|
|
119
|
+
afterEach(() => {
|
|
120
|
+
vi.unstubAllGlobals();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("reads a committed snapshot revision through the authenticated GET endpoint", async () => {
|
|
124
|
+
vi.stubGlobal("window", globalThis);
|
|
125
|
+
const fetchMock = vi.fn(
|
|
126
|
+
async (_path: string, _init?: RequestInit) =>
|
|
127
|
+
new Response(
|
|
128
|
+
JSON.stringify({ snapshot_state: "current", snapshot_revision: "revision-2" }),
|
|
129
|
+
{
|
|
130
|
+
status: 200,
|
|
131
|
+
},
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
135
|
+
|
|
136
|
+
await expect(new DashboardApiClient("session").ready()).resolves.toEqual({
|
|
137
|
+
snapshot_state: "current",
|
|
138
|
+
snapshot_revision: "revision-2",
|
|
139
|
+
});
|
|
140
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
141
|
+
"/api/v2/ready",
|
|
142
|
+
expect.objectContaining({ headers: { "x-zaip-session": "session" } }),
|
|
143
|
+
);
|
|
144
|
+
expect(fetchMock.mock.calls[0]?.[1]).not.toHaveProperty("method");
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
73
148
|
describe("DashboardApiClient cost monitor", () => {
|
|
74
149
|
afterEach(() => {
|
|
75
150
|
vi.unstubAllGlobals();
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
TaskDetailProjection,
|
|
11
11
|
} from "@zaip-ai/dashboard-operations/contracts";
|
|
12
12
|
import type { TaskTrace } from "@zaip-ai/dashboard-traceability/contracts";
|
|
13
|
+
import type { ReconcileOpenWorkResponse } from "./dashboard-api-reconciliation.js";
|
|
13
14
|
export interface ReconciliationBlockedItem {
|
|
14
15
|
id: string;
|
|
15
16
|
reason: string | null;
|
|
@@ -220,7 +221,11 @@ export interface CostMonitorFilters {
|
|
|
220
221
|
export class DashboardApiClient {
|
|
221
222
|
constructor(private readonly token: string) {}
|
|
222
223
|
|
|
223
|
-
ready(): Promise<{
|
|
224
|
+
ready(): Promise<{
|
|
225
|
+
snapshot_state?: "current" | "updating";
|
|
226
|
+
/** Changes only after the local SQLite snapshot is committed. */
|
|
227
|
+
snapshot_revision?: string;
|
|
228
|
+
}> {
|
|
224
229
|
return this.get("/api/v2/ready");
|
|
225
230
|
}
|
|
226
231
|
|
|
@@ -416,13 +421,7 @@ export class DashboardApiClient {
|
|
|
416
421
|
reconcileOpenWork(
|
|
417
422
|
currency: "BRL" | "USD" = "BRL",
|
|
418
423
|
period?: { from: string | null; to: string | null },
|
|
419
|
-
): Promise<{
|
|
420
|
-
operations: OperationsProjection;
|
|
421
|
-
costs: CostMonitorProjection;
|
|
422
|
-
dashboard?: { title: string; repository_name: string };
|
|
423
|
-
projection: { source_latest_at: string | null; served_at: string };
|
|
424
|
-
reconciliation: ReconciliationResult;
|
|
425
|
-
}> {
|
|
424
|
+
): Promise<ReconcileOpenWorkResponse> {
|
|
426
425
|
return this.post(
|
|
427
426
|
withPeriod(`${dashboardApiPaths.reconcileOpenWork}?currency=${currency}`, period),
|
|
428
427
|
reconciliationRequestTimeoutMs,
|