@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
|
@@ -1,45 +1,18 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { copyFile, mkdir, readdir, rename, rm, stat } from "node:fs/promises";
|
|
3
|
-
import { dirname, join, resolve } from "node:path";
|
|
4
1
|
import { DatabaseSync } from "node:sqlite";
|
|
5
2
|
|
|
6
|
-
export async function pruneSnapshotCache(directory: string, activePath: string): Promise<void> {
|
|
7
|
-
const entries = await readdir(directory, { withFileTypes: true }).catch(() => []);
|
|
8
|
-
const stale = await Promise.all(
|
|
9
|
-
entries
|
|
10
|
-
.filter(
|
|
11
|
-
(entry) =>
|
|
12
|
-
entry.isFile() &&
|
|
13
|
-
entry.name.endsWith(".sqlite") &&
|
|
14
|
-
resolve(directory, entry.name) !== activePath,
|
|
15
|
-
)
|
|
16
|
-
.map(async (entry) => ({
|
|
17
|
-
path: resolve(directory, entry.name),
|
|
18
|
-
mtime: (await stat(resolve(directory, entry.name))).mtimeMs,
|
|
19
|
-
})),
|
|
20
|
-
);
|
|
21
|
-
for (const entry of stale.sort((a, b) => b.mtime - a.mtime).slice(1))
|
|
22
|
-
await rm(entry.path, { force: true }).catch(() => {});
|
|
23
|
-
for (const entry of entries) {
|
|
24
|
-
if (!entry.isFile() || !entry.name.includes(".sqlite.") || !entry.name.includes(".tmp"))
|
|
25
|
-
continue;
|
|
26
|
-
const candidate = resolve(directory, entry.name);
|
|
27
|
-
if (Date.now() - (await stat(candidate)).mtimeMs > 60_000)
|
|
28
|
-
await rm(candidate, { force: true }).catch(() => {});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
3
|
export function readSnapshotFileCount(
|
|
33
4
|
path: string,
|
|
34
5
|
fingerprint: string,
|
|
35
6
|
schemaVersion: string,
|
|
36
7
|
hasRequiredPayloads: (database: DatabaseSync) => boolean,
|
|
37
8
|
): number | null {
|
|
9
|
+
let database: DatabaseSync | undefined;
|
|
38
10
|
try {
|
|
39
|
-
|
|
11
|
+
database = new DatabaseSync(path, { readOnly: true });
|
|
12
|
+
const reader = database;
|
|
40
13
|
const value = (key: string) =>
|
|
41
14
|
(
|
|
42
|
-
|
|
15
|
+
reader.prepare("SELECT value FROM zaip_vw_read_model_metadata WHERE key = ?").get(key) as
|
|
43
16
|
| { value?: string }
|
|
44
17
|
| undefined
|
|
45
18
|
)?.value;
|
|
@@ -50,58 +23,11 @@ export function readSnapshotFileCount(
|
|
|
50
23
|
hasRequiredPayloads(database)
|
|
51
24
|
? files
|
|
52
25
|
: null;
|
|
53
|
-
database.close();
|
|
54
|
-
return result;
|
|
55
|
-
} catch {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function mostRecentCompatibleSnapshot(
|
|
61
|
-
directory: string,
|
|
62
|
-
schemaVersion: string,
|
|
63
|
-
hasRequiredPayloads: (database: DatabaseSync) => boolean,
|
|
64
|
-
): Promise<{ path: string; files: number } | null> {
|
|
65
|
-
const entries = await readdir(directory, { withFileTypes: true }).catch(() => []);
|
|
66
|
-
const candidates = await Promise.all(
|
|
67
|
-
entries
|
|
68
|
-
.filter((entry) => entry.isFile() && entry.name.endsWith(".sqlite"))
|
|
69
|
-
.map(async (entry) => ({
|
|
70
|
-
path: join(directory, entry.name),
|
|
71
|
-
mtime: (await stat(join(directory, entry.name))).mtimeMs,
|
|
72
|
-
})),
|
|
73
|
-
);
|
|
74
|
-
for (const candidate of candidates.sort((left, right) => right.mtime - left.mtime)) {
|
|
75
|
-
const files = readCompatibleSnapshotFileCount(
|
|
76
|
-
candidate.path,
|
|
77
|
-
schemaVersion,
|
|
78
|
-
hasRequiredPayloads,
|
|
79
|
-
);
|
|
80
|
-
if (files !== null) return { path: candidate.path, files };
|
|
81
|
-
}
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function readCompatibleSnapshotFileCount(
|
|
86
|
-
path: string,
|
|
87
|
-
schemaVersion: string,
|
|
88
|
-
hasRequiredPayloads: (database: DatabaseSync) => boolean,
|
|
89
|
-
): number | null {
|
|
90
|
-
try {
|
|
91
|
-
const database = new DatabaseSync(path, { readOnly: true });
|
|
92
|
-
const value = (key: string) =>
|
|
93
|
-
(
|
|
94
|
-
database.prepare("SELECT value FROM zaip_vw_read_model_metadata WHERE key = ?").get(key) as
|
|
95
|
-
| { value?: string }
|
|
96
|
-
| undefined
|
|
97
|
-
)?.value;
|
|
98
|
-
const files = Number(value("source_file_count") ?? 0);
|
|
99
|
-
const result =
|
|
100
|
-
value("schema_version") === schemaVersion && hasRequiredPayloads(database) ? files : null;
|
|
101
|
-
database.close();
|
|
102
26
|
return result;
|
|
103
27
|
} catch {
|
|
104
28
|
return null;
|
|
29
|
+
} finally {
|
|
30
|
+
database?.close();
|
|
105
31
|
}
|
|
106
32
|
}
|
|
107
33
|
|
|
@@ -112,18 +38,13 @@ export function installLegacyViewAliases(database: DatabaseSync): void {
|
|
|
112
38
|
for (const { name } of views) {
|
|
113
39
|
const alias = name.slice("zaip_vw_".length);
|
|
114
40
|
const quoted = (identifier: string) => `"${identifier.replaceAll('"', '""')}"`;
|
|
41
|
+
// A transaction may still have a staging table with a legacy public name.
|
|
42
|
+
// The table is already the intended source in that connection, so a TEMP
|
|
43
|
+
// alias would collide and make the complete transaction impossible.
|
|
44
|
+
const existing = database
|
|
45
|
+
.prepare("SELECT 1 FROM sqlite_temp_master WHERE name=? LIMIT 1")
|
|
46
|
+
.get(alias);
|
|
47
|
+
if (existing !== undefined) continue;
|
|
115
48
|
database.exec(`CREATE TEMP VIEW ${quoted(alias)} AS SELECT * FROM main.${quoted(name)}`);
|
|
116
49
|
}
|
|
117
50
|
}
|
|
118
|
-
|
|
119
|
-
export async function materializeSnapshot(source: string, destination: string): Promise<void> {
|
|
120
|
-
await mkdir(dirname(destination), { recursive: true });
|
|
121
|
-
const temporaryPath = `${destination}.${process.pid}.${randomUUID()}.tmp`;
|
|
122
|
-
await copyFile(source, temporaryPath);
|
|
123
|
-
try {
|
|
124
|
-
await rename(temporaryPath, destination);
|
|
125
|
-
} catch (error) {
|
|
126
|
-
await rm(temporaryPath, { force: true });
|
|
127
|
-
throw error;
|
|
128
|
-
}
|
|
129
|
-
}
|
package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-claims.test.mjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
claimDashboardLaunch,
|
|
7
|
+
host,
|
|
8
|
+
requestBackgroundProjectionRefresh,
|
|
9
|
+
workspaceKey,
|
|
10
|
+
} from "./start-dashboard.mjs";
|
|
11
|
+
|
|
12
|
+
const temporaryDirectories = [];
|
|
13
|
+
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
await Promise.all(
|
|
16
|
+
temporaryDirectories.splice(0).map((path) => rm(path, { recursive: true, force: true })),
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe("dashboard launch claims", () => {
|
|
21
|
+
it("blocks the new launch before SQLite when the superseded launcher will not exit", async () => {
|
|
22
|
+
const directory = await temporaryDirectory();
|
|
23
|
+
const path = join(directory, "dashboard-launch.json");
|
|
24
|
+
await writeFile(
|
|
25
|
+
path,
|
|
26
|
+
JSON.stringify({ kind: "zaip-dashboard-sqlite-launch", workspaceKey, launcherPid: 1234 }),
|
|
27
|
+
);
|
|
28
|
+
const stops = [];
|
|
29
|
+
await expect(
|
|
30
|
+
claimDashboardLaunch(
|
|
31
|
+
{ launchPort: 4317, token: "newest-token" },
|
|
32
|
+
{
|
|
33
|
+
path,
|
|
34
|
+
stopProcessTreeImpl: async (pid) => stops.push(pid),
|
|
35
|
+
isKnownDashboardLauncherImpl: async () => true,
|
|
36
|
+
isProcessAliveImpl: async () => true,
|
|
37
|
+
delayImpl: async () => {},
|
|
38
|
+
},
|
|
39
|
+
),
|
|
40
|
+
).rejects.toThrow("Could not stop the superseded dashboard launcher");
|
|
41
|
+
expect(stops).toEqual([1234]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("recovers a recent claim lock immediately when its owner PID is dead", async () => {
|
|
45
|
+
const directory = await temporaryDirectory();
|
|
46
|
+
const path = join(directory, "launch.json");
|
|
47
|
+
const lockPath = join(directory, "claim.lock");
|
|
48
|
+
await mkdir(lockPath);
|
|
49
|
+
await writeFile(join(lockPath, "owner"), "999999", "utf8");
|
|
50
|
+
await claimDashboardLaunch(
|
|
51
|
+
{ launchPort: 4317, token: "new-token" },
|
|
52
|
+
{ path, lockPath, isProcessAliveImpl: async () => false },
|
|
53
|
+
);
|
|
54
|
+
await expect(readFile(path, "utf8")).resolves.toContain('"launchPort": 4317');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("requests a coalesced projection refresh after reusing a warm session", async () => {
|
|
58
|
+
const calls = [];
|
|
59
|
+
await requestBackgroundProjectionRefresh(
|
|
60
|
+
{ port: 4417, token: "warm-token" },
|
|
61
|
+
async (url, init) => calls.push({ url, init }),
|
|
62
|
+
);
|
|
63
|
+
expect(calls).toEqual([
|
|
64
|
+
{
|
|
65
|
+
url: `http://${host}:4417/api/v2/refresh-projection`,
|
|
66
|
+
init: expect.objectContaining({
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: { "x-zaip-session": "warm-token" },
|
|
69
|
+
}),
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
async function temporaryDirectory() {
|
|
76
|
+
const path = await mkdtemp(join(tmpdir(), "zaip-dashboard-launch-claims-"));
|
|
77
|
+
temporaryDirectories.push(path);
|
|
78
|
+
return path;
|
|
79
|
+
}
|
|
@@ -9,6 +9,18 @@ export async function createDashboardLaunchPage({ port, host, runtimeKind, healt
|
|
|
9
9
|
detail: "Abrindo a página de preparação.",
|
|
10
10
|
};
|
|
11
11
|
let progressSteps = [{ phase: progress.phase, detail: progress.detail }];
|
|
12
|
+
const browserLeases = new Set();
|
|
13
|
+
let resolveBrowserDeparture;
|
|
14
|
+
const browserDeparture = new Promise((resolve) => {
|
|
15
|
+
resolveBrowserDeparture = resolve;
|
|
16
|
+
});
|
|
17
|
+
const browserLeaseGraceMs = 12_000;
|
|
18
|
+
let browserDepartureTimer = null;
|
|
19
|
+
const scheduleBrowserDeparture = () => {
|
|
20
|
+
if (browserLeases.size > 0 || browserDepartureTimer !== null) return;
|
|
21
|
+
browserDepartureTimer = setTimeout(() => resolveBrowserDeparture(), browserLeaseGraceMs);
|
|
22
|
+
browserDepartureTimer.unref?.();
|
|
23
|
+
};
|
|
12
24
|
progress = { ...progress, steps: progressSteps };
|
|
13
25
|
const connections = new Set();
|
|
14
26
|
let resolveRedirectObserved;
|
|
@@ -36,6 +48,18 @@ export async function createDashboardLaunchPage({ port, host, runtimeKind, healt
|
|
|
36
48
|
response.end(JSON.stringify({ ...progress, failure }));
|
|
37
49
|
return;
|
|
38
50
|
}
|
|
51
|
+
if (request.url?.startsWith("/api/v2/browser-lease")) {
|
|
52
|
+
if (browserDepartureTimer !== null) clearTimeout(browserDepartureTimer);
|
|
53
|
+
browserDepartureTimer = null;
|
|
54
|
+
browserLeases.add(response);
|
|
55
|
+
response.writeHead(200, { "Content-Type": "text/event-stream", "Cache-Control": "no-store" });
|
|
56
|
+
response.write("event: lease\ndata: active\n\n");
|
|
57
|
+
response.once("close", () => {
|
|
58
|
+
browserLeases.delete(response);
|
|
59
|
+
scheduleBrowserDeparture();
|
|
60
|
+
});
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
39
63
|
if (request.url?.startsWith(healthPath)) {
|
|
40
64
|
response.writeHead(503, { "Content-Type": "application/json; charset=utf-8" });
|
|
41
65
|
response.end(JSON.stringify({ kind: "zaip-dashboard-launcher", status: "starting" }));
|
|
@@ -70,6 +94,7 @@ export async function createDashboardLaunchPage({ port, host, runtimeKind, healt
|
|
|
70
94
|
function setProgressBar(percent,phase){lastProgressPercent=percent;document.getElementById("bar").style.width=percent+"%";document.getElementById("track").setAttribute("aria-valuenow",String(percent));document.getElementById("track").setAttribute("aria-valuetext",phase)}
|
|
71
95
|
function showHandoff(target){handoffTarget=target;stopCompilationTicker();setProgressBar(100,"Dashboard pronto");document.querySelector(".launch-overlay").setAttribute("aria-busy","false");document.getElementById("handoff").style.display="block";document.getElementById("phase").textContent="Dashboard pronto";document.getElementById("detail").textContent="Concluindo a abertura da tela principal.";document.getElementById("activity").textContent="Preparação concluída."}
|
|
72
96
|
function showFailure(next,percent=lastProgressPercent){terminalFailure=true;clearInterval(progressPoll);stopCompilationTicker();document.querySelector(".launch-overlay").setAttribute("aria-busy","false");document.getElementById("phase").textContent=next.phase;document.getElementById("detail").textContent="A preparação não foi concluída. Consulte a mensagem abaixo para agir.";setProgressBar(percent,next.phase);document.getElementById("handoff").style.display="none";document.getElementById("failure").textContent=next.detail;document.getElementById("failure").style.display="block";document.querySelector(".progress").classList.add("terminal-failure")}
|
|
97
|
+
const browserLease=new EventSource("/api/v2/browser-lease");
|
|
73
98
|
async function updateProgress(){if(progressRequestInFlight||terminalFailure)return terminalFailure;progressRequestInFlight=true;try{const r=await fetch("/api/v2/progress",{cache:"no-store",signal:AbortSignal.timeout(1000)});const p=await r.json();if(terminalFailure)return true;const percent=Math.max(4,Math.min(100,Number(p.percent)||4));if(p.failure){showFailure(p.failure,percent);return true}if(!handoffTarget){for(const step of Array.isArray(p.steps)?p.steps:[p])recordStep(step);const nextStepKey=p.phase+"\\u0000"+(p.detail??"");if(nextStepKey!==activeStepKey){activeStepKey=nextStepKey;activeStepStartedAt=Date.now()}document.getElementById("phase").textContent=p.phase;const compiling=p.phase.startsWith("Atualizando ");if(compiling){if(compilationStartedAt===null){compilationStartedAt=Date.now();compilationDetail=p.detail;if(!reducedMotion)compilationTicker=setInterval(renderCompilationElapsed,1000)}renderCompilationElapsed()}else{stopCompilationTicker();document.getElementById("detail").textContent=p.detail}renderActivityElapsed()}if(!terminalFailure&&!handoffTarget)setProgressBar(percent,p.phase)}catch{}finally{progressRequestInFlight=false}return terminalFailure}
|
|
74
99
|
const progressPoll=setInterval(updateProgress,250);
|
|
75
100
|
async function waitForDashboard(){try{if(await updateProgress())return;const ready=await fetch("/api/v2/ready",{cache:"no-store",signal:AbortSignal.timeout(1000)});const next=await ready.json();if(next.failure){showFailure(next.failure);return}if(next.target){showHandoff(next.target);clearInterval(progressPoll);setTimeout(()=>location.replace(next.target),0);return}const response=await fetch("${healthPath}",{cache:"no-store",signal:AbortSignal.timeout(1000)});const payload=await response.json();if(response.ok&&payload.kind==="${runtimeKind}"){clearInterval(progressPoll);location.reload();return}}catch{}setTimeout(waitForDashboard,250)}
|
|
@@ -120,6 +145,7 @@ export async function createDashboardLaunchPage({ port, host, runtimeKind, healt
|
|
|
120
145
|
},
|
|
121
146
|
waitForRedirect: async (timeoutMs = 1_500) =>
|
|
122
147
|
Promise.race([redirectObserved, delay(timeoutMs).then(() => false)]),
|
|
148
|
+
waitForBrowserDeparture: () => browserDeparture,
|
|
123
149
|
closeAfterHandoffGrace: (graceMs = 12_000) => {
|
|
124
150
|
const timer = setTimeout(() => {
|
|
125
151
|
void server.close();
|
|
@@ -153,6 +179,7 @@ export async function createDashboardLaunchPage({ port, host, runtimeKind, healt
|
|
|
153
179
|
if (error) rejectClose(error);
|
|
154
180
|
else resolveClose();
|
|
155
181
|
};
|
|
182
|
+
if (browserDepartureTimer !== null) clearTimeout(browserDepartureTimer);
|
|
156
183
|
server.close(finish);
|
|
157
184
|
forceTimer = setTimeout(() => {
|
|
158
185
|
server.closeAllConnections?.();
|
|
@@ -39,20 +39,20 @@ export async function awaitOwnedDashboardExit({
|
|
|
39
39
|
currentSession,
|
|
40
40
|
clearOwnedDashboardSession,
|
|
41
41
|
recordPortStatus,
|
|
42
|
-
removeGeneratedReadModel,
|
|
43
42
|
processRef = process,
|
|
44
43
|
}) {
|
|
45
44
|
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
46
45
|
processRef.once(signal, () => child.kill(signal));
|
|
47
46
|
}
|
|
48
|
-
const exitCode =
|
|
49
|
-
child.
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
const exitCode =
|
|
48
|
+
child.exitCode ??
|
|
49
|
+
(await new Promise((resolveExit, rejectExit) => {
|
|
50
|
+
child.once("error", rejectExit);
|
|
51
|
+
child.once("exit", (code) => resolveExit(code ?? 0));
|
|
52
|
+
}));
|
|
52
53
|
await clearOwnedDashboardSession();
|
|
53
54
|
if (currentSession !== null) {
|
|
54
55
|
await recordPortStatus(currentSession, "closed");
|
|
55
|
-
await removeGeneratedReadModel(currentSession.dbPath);
|
|
56
56
|
}
|
|
57
57
|
return exitCode;
|
|
58
58
|
}
|
|
@@ -40,12 +40,10 @@ async function acquireRefreshLock(lockPath, isProcessAlive) {
|
|
|
40
40
|
export async function startSeedRefresh(options) {
|
|
41
41
|
const {
|
|
42
42
|
appendLog,
|
|
43
|
-
cacheDirectory,
|
|
44
43
|
isRunning,
|
|
45
44
|
isProcessAlive,
|
|
46
45
|
lockPath,
|
|
47
46
|
packageRoot,
|
|
48
|
-
randomBytes,
|
|
49
47
|
refreshLogPath,
|
|
50
48
|
refreshStatusPath,
|
|
51
49
|
sqliteDirectory,
|
|
@@ -62,10 +60,7 @@ export async function startSeedRefresh(options) {
|
|
|
62
60
|
appendLog("Skipped duplicate background SQLite seed refresh; a worker is already running.");
|
|
63
61
|
return;
|
|
64
62
|
}
|
|
65
|
-
const refreshPath = resolve(
|
|
66
|
-
sqliteDirectory,
|
|
67
|
-
`refresh-${process.pid}-${randomBytes(4).toString("hex")}.sqlite`,
|
|
68
|
-
);
|
|
63
|
+
const refreshPath = resolve(sqliteDirectory, "zaip-aios-dashboard.sqlite");
|
|
69
64
|
mkdirSync(dirname(refreshStatusPath), { recursive: true });
|
|
70
65
|
const descriptor = openSync(refreshLogPath, "a");
|
|
71
66
|
let worker;
|
|
@@ -81,8 +76,6 @@ export async function startSeedRefresh(options) {
|
|
|
81
76
|
ZAIP_SQLITE_DB_PATH: refreshPath,
|
|
82
77
|
ZAIP_SQLITE_PREFER_LAST_VALID_SEED: "0",
|
|
83
78
|
ZAIP_DASHBOARD_LAUNCH_PROGRESS: "0",
|
|
84
|
-
ZAIP_SQLITE_REFRESH_CLEANUP: "1",
|
|
85
|
-
ZAIP_SQLITE_CACHE_DIR: cacheDirectory,
|
|
86
79
|
},
|
|
87
80
|
stdio: ["ignore", descriptor, descriptor],
|
|
88
81
|
detached: true,
|
|
@@ -101,7 +94,6 @@ export async function startSeedRefresh(options) {
|
|
|
101
94
|
status: "running",
|
|
102
95
|
pid: worker.pid,
|
|
103
96
|
path: refreshPath,
|
|
104
|
-
cacheDirectory,
|
|
105
97
|
startedAt: new Date().toISOString(),
|
|
106
98
|
});
|
|
107
99
|
} catch (error) {
|
|
@@ -130,7 +122,7 @@ export async function startSeedRefresh(options) {
|
|
|
130
122
|
});
|
|
131
123
|
worker.unref();
|
|
132
124
|
appendLog(
|
|
133
|
-
`Started
|
|
125
|
+
`Started transactional refresh of the persistent SQLite database at ${refreshPath}; worker log ${refreshLogPath}.`,
|
|
134
126
|
);
|
|
135
127
|
} finally {
|
|
136
128
|
try {
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createServer } from "node:net";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
|
|
5
|
+
export function isPortFree(host, port) {
|
|
6
|
+
return new Promise((resolvePort) => {
|
|
7
|
+
const server = createServer();
|
|
8
|
+
server.unref();
|
|
9
|
+
server.once("error", () => resolvePort(false));
|
|
10
|
+
server.listen({ host, port }, () => server.close(() => resolvePort(true)));
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function startDashboardServer({
|
|
15
|
+
serverPath,
|
|
16
|
+
token,
|
|
17
|
+
excludedPorts,
|
|
18
|
+
initialPort = null,
|
|
19
|
+
onProgress = () => {},
|
|
20
|
+
onChildStarted = () => {},
|
|
21
|
+
maxAttempts,
|
|
22
|
+
dbPath,
|
|
23
|
+
packageRoot,
|
|
24
|
+
workspaceRoot,
|
|
25
|
+
frontendRoot,
|
|
26
|
+
compileCacheDirectory,
|
|
27
|
+
findPort,
|
|
28
|
+
waitForDashboard,
|
|
29
|
+
stopProcessTree,
|
|
30
|
+
sanitize,
|
|
31
|
+
formatError,
|
|
32
|
+
appendLog,
|
|
33
|
+
}) {
|
|
34
|
+
const failures = [];
|
|
35
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
36
|
+
const port =
|
|
37
|
+
attempt === 1 && Number.isInteger(initialPort)
|
|
38
|
+
? initialPort
|
|
39
|
+
: await findPort({ excludedPorts: [...excludedPorts] });
|
|
40
|
+
excludedPorts.add(port);
|
|
41
|
+
let stderr = "";
|
|
42
|
+
let startupTelemetryBuffer = "";
|
|
43
|
+
let snapshotCache = null;
|
|
44
|
+
const child = spawn(process.execPath, [serverPath], {
|
|
45
|
+
cwd: packageRoot,
|
|
46
|
+
env: {
|
|
47
|
+
...process.env,
|
|
48
|
+
ZAIP_WORKSPACE: workspaceRoot,
|
|
49
|
+
ZAIP_UI_ROOT: frontendRoot,
|
|
50
|
+
ZAIP_UI_TOKEN: token,
|
|
51
|
+
ZAIP_SERVER_PORT: String(port),
|
|
52
|
+
NODE_COMPILE_CACHE: compileCacheDirectory,
|
|
53
|
+
NODE_NO_WARNINGS: "1",
|
|
54
|
+
ZAIP_DASHBOARD_LAUNCH_PROGRESS: "1",
|
|
55
|
+
ZAIP_SQLITE_PREFER_LAST_VALID_SEED: "0",
|
|
56
|
+
ZAIP_SQLITE_DB_PATH: dbPath,
|
|
57
|
+
},
|
|
58
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
59
|
+
windowsHide: true,
|
|
60
|
+
});
|
|
61
|
+
onChildStarted(child);
|
|
62
|
+
child.stderr?.setEncoding("utf8");
|
|
63
|
+
child.stderr?.on("data", (chunk) => {
|
|
64
|
+
stderr = `${stderr}${chunk}`.slice(-4_000);
|
|
65
|
+
startupTelemetryBuffer = `${startupTelemetryBuffer}${String(chunk)}`;
|
|
66
|
+
const lines = startupTelemetryBuffer.split("\n");
|
|
67
|
+
startupTelemetryBuffer = lines.pop() ?? "";
|
|
68
|
+
for (const line of lines)
|
|
69
|
+
reportStartupProgress(line, onProgress, (value) => {
|
|
70
|
+
snapshotCache = value;
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
try {
|
|
74
|
+
await waitForDashboard(port, child);
|
|
75
|
+
for (const timing of sanitize(stderr)
|
|
76
|
+
.split("\n")
|
|
77
|
+
.filter(
|
|
78
|
+
(line) =>
|
|
79
|
+
line.includes('"event":"dashboard_sqlite_read_model"') ||
|
|
80
|
+
line.includes('"event":"dashboard_sqlite_startup_phase"'),
|
|
81
|
+
))
|
|
82
|
+
appendLog(timing);
|
|
83
|
+
return { child, port, dbPath, snapshotCache };
|
|
84
|
+
} catch (error) {
|
|
85
|
+
await stopProcessTree(child.pid);
|
|
86
|
+
const detail = sanitize(stderr)
|
|
87
|
+
.split("\n")
|
|
88
|
+
.filter(
|
|
89
|
+
(line) =>
|
|
90
|
+
!line.includes("ExperimentalWarning") && !line.includes("node --trace-warnings"),
|
|
91
|
+
)
|
|
92
|
+
.join("\n")
|
|
93
|
+
.trim();
|
|
94
|
+
failures.push(
|
|
95
|
+
`porta ${port}: ${error.message}${detail ? ` — ${formatError(detail, 600)}` : ""}`,
|
|
96
|
+
);
|
|
97
|
+
appendLog(`Dashboard start attempt ${attempt} failed on port ${port}: ${error.message}`);
|
|
98
|
+
if (error.retryable === false) break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Não foi possível iniciar o dashboard após os fallbacks. ${failures.join(" | ")}`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function reportStartupProgress(line, onProgress, setSnapshotCache) {
|
|
107
|
+
try {
|
|
108
|
+
const event = JSON.parse(line);
|
|
109
|
+
if (event?.event === "dashboard_sqlite_rebuild_progress")
|
|
110
|
+
onProgress({
|
|
111
|
+
percent: event.percent,
|
|
112
|
+
phase: "Configurando o banco SQLite local",
|
|
113
|
+
detail:
|
|
114
|
+
"Esta é a instalação/atualização da cópia local descartável; nenhum servidor externo é instalado.",
|
|
115
|
+
});
|
|
116
|
+
if (event?.event === "dashboard_sqlite_startup_phase" && event.phase === "main_entered")
|
|
117
|
+
onProgress({
|
|
118
|
+
percent: 50,
|
|
119
|
+
phase: "Lendo os registros do projeto",
|
|
120
|
+
detail: "Preparando o read model SQLite local.",
|
|
121
|
+
});
|
|
122
|
+
if (event?.event === "dashboard_sqlite_read_model") {
|
|
123
|
+
setSnapshotCache(event.cache);
|
|
124
|
+
onProgress({
|
|
125
|
+
percent: 82,
|
|
126
|
+
phase: "Banco local pronto",
|
|
127
|
+
detail:
|
|
128
|
+
event.cache === "rebuilt"
|
|
129
|
+
? "O read model SQLite foi reconstruído para os dados atuais."
|
|
130
|
+
: "Uma cópia local do read model foi preparada.",
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (event?.event === "dashboard_sqlite_startup_phase" && event.phase === "listening")
|
|
134
|
+
onProgress({
|
|
135
|
+
percent: 88,
|
|
136
|
+
phase: "Iniciando a interface",
|
|
137
|
+
detail: "Verificando saúde e disponibilidade dos dados.",
|
|
138
|
+
});
|
|
139
|
+
} catch {
|
|
140
|
+
// Only structured startup telemetry affects user-facing progress.
|
|
141
|
+
}
|
|
142
|
+
}
|