@zaip-ai/cli 1.3.7 → 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 +86 -1
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +26 -0
- 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 +3 -1
- 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-install.d.ts +14 -0
- package/dist/services/stack-install.d.ts.map +1 -0
- package/dist/services/stack-install.js +176 -0
- package/dist/services/stack-install.js.map +1 -0
- package/dist/services/stack-node.d.ts +12 -0
- package/dist/services/stack-node.d.ts.map +1 -0
- package/dist/services/stack-node.js +150 -0
- package/dist/services/stack-node.js.map +1 -0
- package/dist/services/stack-package-manager.d.ts +12 -0
- package/dist/services/stack-package-manager.d.ts.map +1 -0
- package/dist/services/stack-package-manager.js +178 -0
- package/dist/services/stack-package-manager.js.map +1 -0
- package/dist/services/stack-plan.d.ts +35 -0
- package/dist/services/stack-plan.d.ts.map +1 -0
- package/dist/services/stack-plan.js +130 -0
- package/dist/services/stack-plan.js.map +1 -0
- 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 +4 -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 +214 -94
- 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--czwAlcH.js → DashboardHelpDialog-oZVlf-l5.js} +787 -723
- 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/{ProjectSettingsPage-BomxqCBU.css → ProjectSettingsPage-GgzpZ_PY.css} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CAqYVin1.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/ProjectSettingsPage.tsx +15 -2
- package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +33 -6
- 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 +9 -8
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +15 -3
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +0 -104
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +61 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-stack-versions.css +117 -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 +477 -327
- 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 +243 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +252 -41
- 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/stack-dependencies.json +14 -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 +613 -173
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-B_Oj6Dlf.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-CblPpexd.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
|
@@ -9,7 +9,12 @@ type CostDimensionAggregateRow = {
|
|
|
9
9
|
key: string;
|
|
10
10
|
label: string;
|
|
11
11
|
invocation_count: number;
|
|
12
|
-
task_count: number;
|
|
12
|
+
task_count: number | null;
|
|
13
|
+
conversation_count: number;
|
|
14
|
+
prd_count: number | null;
|
|
15
|
+
spec_count: number | null;
|
|
16
|
+
test_count: number | null;
|
|
17
|
+
evidence_count: number | null;
|
|
13
18
|
total_duration: number | null;
|
|
14
19
|
source_event_count: number | null;
|
|
15
20
|
total_tokens: number | null;
|
|
@@ -72,7 +77,7 @@ export function buildCostDimensionAggregates(
|
|
|
72
77
|
);
|
|
73
78
|
const activities = database
|
|
74
79
|
.prepare(`SELECT activity_row_id, agent_invocation_id, task_id, duration_ms,
|
|
75
|
-
source_event_count, provider, model, total_tokens, cost_usd, cost_brl,
|
|
80
|
+
source_event_count, provider, model, total_tokens, cost_usd, cost_brl, run_id,
|
|
76
81
|
activity_source_kind, zaip_agent, zaip_agent_persona, zaip_agent_job,
|
|
77
82
|
execution_id, conversation_id, occurred_at, occurred_day_sp, llm_call_count,
|
|
78
83
|
input_tokens, cached_input_tokens, output_tokens, reasoning_tokens
|
|
@@ -99,6 +104,11 @@ export function buildCostDimensionAggregates(
|
|
|
99
104
|
label: key,
|
|
100
105
|
invocation_count: 0,
|
|
101
106
|
task_count: 0,
|
|
107
|
+
conversation_count: 0,
|
|
108
|
+
prd_count: 0,
|
|
109
|
+
spec_count: 0,
|
|
110
|
+
test_count: 0,
|
|
111
|
+
evidence_count: 0,
|
|
102
112
|
total_duration: null,
|
|
103
113
|
source_event_count: null,
|
|
104
114
|
total_tokens: null,
|
|
@@ -174,31 +184,127 @@ export function buildCostDimensionAggregates(
|
|
|
174
184
|
}
|
|
175
185
|
}
|
|
176
186
|
}
|
|
177
|
-
|
|
178
|
-
|
|
187
|
+
// Productivity is a creation fact, never inferred from a later Run that
|
|
188
|
+
// happened to reference the Task. A multi-model creation Run has no
|
|
189
|
+
// defensible single owner, so its entities remain unavailable by model.
|
|
190
|
+
const modelsByCreationRun = new Map<string, Set<string>>();
|
|
191
|
+
for (const [id, invocationSegments] of segmentsByInvocation) {
|
|
192
|
+
const keys = [
|
|
193
|
+
...new Set(
|
|
194
|
+
invocationSegments
|
|
195
|
+
.filter((segment) => {
|
|
196
|
+
const model = observedDimensionValue(segment.model);
|
|
197
|
+
const provider = observedDimensionValue(segment.provider);
|
|
198
|
+
return (
|
|
199
|
+
model !== null &&
|
|
200
|
+
provider !== null &&
|
|
201
|
+
allowedProviders.has(provider) &&
|
|
202
|
+
(typeof segment.total_tokens === "number" ||
|
|
203
|
+
typeof segment.cost_usd === "number" ||
|
|
204
|
+
typeof segment.cost_brl === "number")
|
|
205
|
+
);
|
|
206
|
+
})
|
|
207
|
+
.map((segment) => observedDimensionValue(segment.model)!),
|
|
208
|
+
),
|
|
209
|
+
];
|
|
210
|
+
const runId = activityByInvocation.get(id)?.run_id;
|
|
211
|
+
if (typeof runId !== "string") continue;
|
|
212
|
+
const observed = modelsByCreationRun.get(runId) ?? new Set<string>();
|
|
213
|
+
for (const key of keys) observed.add(key);
|
|
214
|
+
modelsByCreationRun.set(runId, observed);
|
|
215
|
+
}
|
|
216
|
+
const modelByCreationRun = new Map(
|
|
217
|
+
[...modelsByCreationRun].flatMap(([runId, models]) =>
|
|
218
|
+
models.size === 1 ? [[runId, [...models][0]!] as const] : [],
|
|
219
|
+
),
|
|
179
220
|
);
|
|
221
|
+
const createdSpecsByModel = new Map<string, Set<string>>();
|
|
222
|
+
const createdPrdsByModel = new Map<string, Set<string>>();
|
|
223
|
+
for (const item of database
|
|
224
|
+
.prepare(
|
|
225
|
+
"SELECT entity_kind, id, creation_run_id FROM canonical_work_items WHERE creation_run_id IS NOT NULL",
|
|
226
|
+
)
|
|
227
|
+
.all() as Array<{ entity_kind: string; id: string; creation_run_id: string }>) {
|
|
228
|
+
const model = modelByCreationRun.get(item.creation_run_id);
|
|
229
|
+
if (model === undefined) continue;
|
|
230
|
+
const target =
|
|
231
|
+
item.entity_kind === "spec"
|
|
232
|
+
? createdSpecsByModel
|
|
233
|
+
: item.entity_kind === "prd"
|
|
234
|
+
? createdPrdsByModel
|
|
235
|
+
: null;
|
|
236
|
+
if (target === null) continue;
|
|
237
|
+
const values = target.get(model) ?? new Set<string>();
|
|
238
|
+
values.add(item.id);
|
|
239
|
+
target.set(model, values);
|
|
240
|
+
}
|
|
241
|
+
const artifactsByModel = new Map<string, { tests: number; evidences: number }>();
|
|
242
|
+
for (const artifact of database
|
|
243
|
+
.prepare(
|
|
244
|
+
"SELECT path, artifact_kind, artifact_run_id FROM files WHERE artifact_run_id IS NOT NULL AND artifact_kind IN ('validation', 'evidence')",
|
|
245
|
+
)
|
|
246
|
+
.all() as Array<{ path: string; artifact_kind: string; artifact_run_id: string }>) {
|
|
247
|
+
if (artifact.artifact_kind === "validation" && !artifact.path.includes("/artifacts/tests/"))
|
|
248
|
+
continue;
|
|
249
|
+
const model = modelByCreationRun.get(artifact.artifact_run_id);
|
|
250
|
+
if (model === undefined) continue;
|
|
251
|
+
const current = artifactsByModel.get(model) ?? { tests: 0, evidences: 0 };
|
|
252
|
+
if (artifact.artifact_kind === "validation") current.tests += 1;
|
|
253
|
+
else current.evidences += 1;
|
|
254
|
+
artifactsByModel.set(model, current);
|
|
255
|
+
}
|
|
256
|
+
for (const [model, artifacts] of artifactsByModel) {
|
|
257
|
+
const row = ensure("model", model);
|
|
258
|
+
row.test_count = artifacts.tests;
|
|
259
|
+
row.evidence_count = artifacts.evidences;
|
|
260
|
+
}
|
|
261
|
+
for (const [model, specs] of createdSpecsByModel) ensure("model", model).spec_count = specs.size;
|
|
262
|
+
for (const [model, prds] of createdPrdsByModel) ensure("model", model).prd_count = prds.size;
|
|
263
|
+
const modelTasks = new Map<string, Set<string>>();
|
|
264
|
+
const modelConversations = new Map<string, Set<string>>();
|
|
265
|
+
const providerTasks = new Map<string, Set<string>>();
|
|
180
266
|
for (const [id, invocationSegments] of segmentsByInvocation) {
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
for (const
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
267
|
+
const activity = activityByInvocation.get(id);
|
|
268
|
+
const taskId = activity?.task_id;
|
|
269
|
+
for (const segment of invocationSegments) {
|
|
270
|
+
const provider = observedDimensionValue(segment.provider);
|
|
271
|
+
const model = observedDimensionValue(segment.model);
|
|
272
|
+
const hasFinancialFact =
|
|
273
|
+
typeof segment.total_tokens === "number" ||
|
|
274
|
+
typeof segment.cost_usd === "number" ||
|
|
275
|
+
typeof segment.cost_brl === "number";
|
|
276
|
+
if (provider === null || !allowedProviders.has(provider) || !hasFinancialFact) continue;
|
|
277
|
+
if (model !== null) {
|
|
278
|
+
if (typeof taskId === "string" && activity?.activity_source_kind !== "unassisted_turn") {
|
|
279
|
+
const tasks = modelTasks.get(model) ?? new Set<string>();
|
|
280
|
+
tasks.add(taskId);
|
|
281
|
+
modelTasks.set(model, tasks);
|
|
282
|
+
}
|
|
195
283
|
}
|
|
196
|
-
|
|
284
|
+
const conversationId = activity?.conversation_id;
|
|
285
|
+
const isConversation =
|
|
286
|
+
typeof conversationId === "string" &&
|
|
287
|
+
(activity?.activity_source_kind === "unassisted_turn" || typeof taskId !== "string");
|
|
288
|
+
if (isConversation) {
|
|
289
|
+
const conversationModel = model ?? "unavailable";
|
|
290
|
+
const conversations = modelConversations.get(conversationModel) ?? new Set<string>();
|
|
291
|
+
conversations.add(conversationId);
|
|
292
|
+
modelConversations.set(conversationModel, conversations);
|
|
293
|
+
}
|
|
294
|
+
if (typeof taskId !== "string") continue;
|
|
295
|
+
const tasks = providerTasks.get(provider) ?? new Set<string>();
|
|
296
|
+
tasks.add(taskId);
|
|
297
|
+
providerTasks.set(provider, tasks);
|
|
197
298
|
}
|
|
198
299
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
300
|
+
// A Task participates once per observed model. It can therefore appear in
|
|
301
|
+
// more than one Modelos LLM row, and the model footer is intentionally the
|
|
302
|
+
// sum of those row memberships.
|
|
303
|
+
for (const [model, tasks] of modelTasks) ensure("model", model).task_count = tasks.size;
|
|
304
|
+
for (const [model, conversations] of modelConversations)
|
|
305
|
+
ensure("model", model).conversation_count = conversations.size;
|
|
306
|
+
for (const [provider, tasks] of providerTasks)
|
|
307
|
+
ensure("provider", provider).task_count = tasks.size;
|
|
202
308
|
for (const activity of activities) {
|
|
203
309
|
if (typeof activity.agent_invocation_id === "string") continue;
|
|
204
310
|
const hasFinancialFact =
|
|
@@ -212,7 +318,6 @@ export function buildCostDimensionAggregates(
|
|
|
212
318
|
const key = observedDimensionValue(activity[dimension]) ?? "unavailable";
|
|
213
319
|
const target = ensure(dimension, key);
|
|
214
320
|
target.invocation_count += 1;
|
|
215
|
-
if (typeof activity.task_id === "string") target.task_count += 1;
|
|
216
321
|
if (typeof activity.duration_ms === "number")
|
|
217
322
|
target.total_duration = (target.total_duration ?? 0) + activity.duration_ms;
|
|
218
323
|
if (typeof activity.source_event_count === "number")
|
|
@@ -221,6 +326,29 @@ export function buildCostDimensionAggregates(
|
|
|
221
326
|
add(target, "total_cost_usd", activity.cost_usd);
|
|
222
327
|
add(target, "total_cost_brl", activity.cost_brl);
|
|
223
328
|
}
|
|
329
|
+
const model = observedDimensionValue(activity.model);
|
|
330
|
+
const conversationId = activity.conversation_id;
|
|
331
|
+
if (model !== null) {
|
|
332
|
+
if (
|
|
333
|
+
typeof activity.task_id === "string" &&
|
|
334
|
+
activity.activity_source_kind !== "unassisted_turn"
|
|
335
|
+
) {
|
|
336
|
+
const tasks = modelTasks.get(model) ?? new Set<string>();
|
|
337
|
+
tasks.add(activity.task_id);
|
|
338
|
+
modelTasks.set(model, tasks);
|
|
339
|
+
ensure("model", model).task_count = tasks.size;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (
|
|
343
|
+
typeof conversationId === "string" &&
|
|
344
|
+
(activity.activity_source_kind === "unassisted_turn" || typeof activity.task_id !== "string")
|
|
345
|
+
) {
|
|
346
|
+
const conversationModel = model ?? "unavailable";
|
|
347
|
+
const conversations = modelConversations.get(conversationModel) ?? new Set<string>();
|
|
348
|
+
conversations.add(conversationId);
|
|
349
|
+
modelConversations.set(conversationModel, conversations);
|
|
350
|
+
ensure("model", conversationModel).conversation_count = conversations.size;
|
|
351
|
+
}
|
|
224
352
|
}
|
|
225
353
|
const base = Object.fromEntries(
|
|
226
354
|
dimensions.map((dimension) => [
|
|
@@ -256,6 +384,11 @@ export function buildCostDimensionAggregates(
|
|
|
256
384
|
occurred_at: "",
|
|
257
385
|
invocation_count: 0,
|
|
258
386
|
task_count: 0,
|
|
387
|
+
conversation_count: 0,
|
|
388
|
+
prd_count: null,
|
|
389
|
+
spec_count: null,
|
|
390
|
+
test_count: null,
|
|
391
|
+
evidence_count: null,
|
|
259
392
|
llm_call_count: null,
|
|
260
393
|
total_duration: null,
|
|
261
394
|
duration_unknown: 0,
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts
CHANGED
|
@@ -3,39 +3,48 @@ import type { DatabaseSync } from "node:sqlite";
|
|
|
3
3
|
/** Freezes legacy Cost facts and their entity labels once for fast date-only pages. */
|
|
4
4
|
export function materializeCostGroupDailyProjection(database: DatabaseSync): void {
|
|
5
5
|
database.exec(`
|
|
6
|
-
CREATE TABLE cost_group_daily_projection AS SELECT * FROM zaip_vw_cost_monitor_group_daily_cache;
|
|
7
|
-
|
|
6
|
+
CREATE TABLE IF NOT EXISTS cost_group_daily_projection AS SELECT * FROM zaip_vw_cost_monitor_group_daily_cache LIMIT 0;
|
|
7
|
+
DELETE FROM cost_group_daily_projection;
|
|
8
|
+
INSERT INTO cost_group_daily_projection SELECT * FROM zaip_vw_cost_monitor_group_daily_cache;
|
|
9
|
+
CREATE INDEX IF NOT EXISTS cost_group_daily_projection_lookup ON cost_group_daily_projection(group_kind, day, group_value);
|
|
8
10
|
|
|
9
11
|
-- The public entity views expand canonical records and activities. Reading
|
|
10
12
|
-- them for every grouped page was the remaining multi-second cost, most
|
|
11
13
|
-- visibly for conversations. Persist exactly the three presentation fields
|
|
12
14
|
-- the old LEFT JOIN supplied, keyed by the already-materialized population.
|
|
13
|
-
CREATE TABLE cost_group_entity_projection
|
|
15
|
+
CREATE TABLE IF NOT EXISTS cost_group_entity_projection(group_kind TEXT, group_value TEXT, title TEXT, status TEXT, risk TEXT);
|
|
16
|
+
DELETE FROM cost_group_entity_projection;
|
|
17
|
+
INSERT INTO cost_group_entity_projection
|
|
18
|
+
WITH tasks AS MATERIALIZED (SELECT * FROM zaip_vw_tasks),
|
|
19
|
+
specs AS MATERIALIZED (SELECT * FROM zaip_vw_specs),
|
|
20
|
+
prds AS MATERIALIZED (SELECT * FROM zaip_vw_prds),
|
|
21
|
+
executions AS MATERIALIZED (SELECT * FROM zaip_vw_executions),
|
|
22
|
+
conversations AS MATERIALIZED (SELECT * FROM zaip_vw_conversations)
|
|
14
23
|
SELECT 'task' AS group_kind, groups.group_value, entity.title, entity.status, entity.risk
|
|
15
24
|
FROM (SELECT DISTINCT group_value FROM cost_group_daily_projection
|
|
16
25
|
WHERE group_kind = 'task' AND group_value IS NOT NULL) groups
|
|
17
|
-
LEFT JOIN
|
|
26
|
+
LEFT JOIN tasks entity ON entity.id = groups.group_value
|
|
18
27
|
UNION ALL
|
|
19
28
|
SELECT 'spec', groups.group_value, entity.title, entity.status, entity.risk
|
|
20
29
|
FROM (SELECT DISTINCT group_value FROM cost_group_daily_projection
|
|
21
30
|
WHERE group_kind = 'spec' AND group_value IS NOT NULL) groups
|
|
22
|
-
LEFT JOIN
|
|
31
|
+
LEFT JOIN specs entity ON entity.id = groups.group_value
|
|
23
32
|
UNION ALL
|
|
24
33
|
SELECT 'prd', groups.group_value, entity.title, entity.status, entity.risk
|
|
25
34
|
FROM (SELECT DISTINCT group_value FROM cost_group_daily_projection
|
|
26
35
|
WHERE group_kind = 'prd' AND group_value IS NOT NULL) groups
|
|
27
|
-
LEFT JOIN
|
|
36
|
+
LEFT JOIN prds entity ON entity.id = groups.group_value
|
|
28
37
|
UNION ALL
|
|
29
38
|
SELECT 'execution', groups.group_value, NULL, entity.status, NULL
|
|
30
39
|
FROM (SELECT DISTINCT group_value FROM cost_group_daily_projection
|
|
31
40
|
WHERE group_kind = 'execution' AND group_value IS NOT NULL) groups
|
|
32
|
-
LEFT JOIN
|
|
41
|
+
LEFT JOIN executions entity ON entity.id = groups.group_value
|
|
33
42
|
UNION ALL
|
|
34
43
|
SELECT 'conversation', groups.group_value, NULL, entity.status, NULL
|
|
35
44
|
FROM (SELECT DISTINCT group_value FROM cost_group_daily_projection
|
|
36
45
|
WHERE group_kind = 'conversation' AND group_value IS NOT NULL) groups
|
|
37
|
-
LEFT JOIN
|
|
38
|
-
CREATE UNIQUE INDEX cost_group_entity_projection_lookup
|
|
46
|
+
LEFT JOIN conversations entity ON entity.id = groups.group_value;
|
|
47
|
+
CREATE UNIQUE INDEX IF NOT EXISTS cost_group_entity_projection_lookup
|
|
39
48
|
ON cost_group_entity_projection(group_kind, group_value);
|
|
40
49
|
`);
|
|
41
50
|
}
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-projection.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
2
|
+
|
|
3
|
+
// Expand the persisted usage payloads once so the join can use an automatic
|
|
4
|
+
// index instead of decoding every historical segment for each invocation.
|
|
5
|
+
export const costInvocationProjectionSelect = `WITH usage AS MATERIALIZED (SELECT * FROM invocation_usage)
|
|
6
|
+
SELECT i.*,
|
|
7
|
+
COUNT(u.usage_index) AS pricing_segment_count,
|
|
8
|
+
CASE WHEN COUNT(DISTINCT COALESCE(u.provider, '') || '|' || COALESCE(u.model, '') || '|' || COALESCE(u.service_tier, 'default') || '|' || COALESCE(CAST(u.context_input_multiplier AS TEXT), '') || '|' || COALESCE(CAST(u.context_output_multiplier AS TEXT), '')) > 1 THEN 1 ELSE 0 END AS pricing_mixed,
|
|
9
|
+
SUM(u.uncached_input_tokens) AS uncached_input_tokens,
|
|
10
|
+
SUM(u.visible_output_tokens) AS visible_output_tokens,
|
|
11
|
+
CASE COUNT(DISTINCT u.input_rate_usd_per_million) WHEN 1 THEN MIN(u.input_rate_usd_per_million) ELSE NULL END AS input_rate_usd_per_million,
|
|
12
|
+
CASE COUNT(DISTINCT u.cached_input_rate_usd_per_million) WHEN 1 THEN MIN(u.cached_input_rate_usd_per_million) ELSE NULL END AS cached_input_rate_usd_per_million,
|
|
13
|
+
CASE COUNT(DISTINCT u.output_rate_usd_per_million) WHEN 1 THEN MIN(u.output_rate_usd_per_million) ELSE NULL END AS output_rate_usd_per_million,
|
|
14
|
+
CASE COUNT(DISTINCT u.reasoning_rate_usd_per_million) WHEN 1 THEN MIN(u.reasoning_rate_usd_per_million) ELSE NULL END AS reasoning_rate_usd_per_million,
|
|
15
|
+
CASE COUNT(DISTINCT u.context_input_multiplier) WHEN 1 THEN MIN(u.context_input_multiplier) ELSE NULL END AS context_input_multiplier,
|
|
16
|
+
CASE COUNT(DISTINCT u.context_output_multiplier) WHEN 1 THEN MIN(u.context_output_multiplier) ELSE NULL END AS context_output_multiplier,
|
|
17
|
+
CASE COUNT(DISTINCT u.speed_cost_multiplier) WHEN 1 THEN MIN(u.speed_cost_multiplier) ELSE NULL END AS speed_cost_multiplier,
|
|
18
|
+
CASE COUNT(DISTINCT u.pricing_scenario) WHEN 1 THEN MIN(u.pricing_scenario) ELSE 'mixed' END AS pricing_scenario,
|
|
19
|
+
SUM(u.standard_cost_usd) AS standard_cost_usd,
|
|
20
|
+
SUM(u.speed_uplift_usd) AS speed_uplift_usd,
|
|
21
|
+
SUM(u.input_cost_usd) AS input_cost_usd,
|
|
22
|
+
SUM(u.cached_input_cost_usd) AS cached_input_cost_usd,
|
|
23
|
+
SUM(u.output_cost_usd) AS output_cost_usd,
|
|
24
|
+
SUM(u.reasoning_cost_usd) AS reasoning_cost_usd,
|
|
25
|
+
SUM(u.calculated_cost_usd) AS calculated_cost_usd,
|
|
26
|
+
SUM(u.recorded_cost_usd) AS recorded_cost_usd,
|
|
27
|
+
CASE COUNT(DISTINCT CASE WHEN u.recorded_cost_usd IS NOT NULL THEN u.fx_rate END)
|
|
28
|
+
WHEN 1 THEN MIN(CASE WHEN u.recorded_cost_usd IS NOT NULL THEN u.fx_rate END)
|
|
29
|
+
ELSE NULL
|
|
30
|
+
END AS recorded_fx_rate,
|
|
31
|
+
SUM(CASE WHEN u.recorded_cost_usd IS NOT NULL THEN u.cost_brl END) AS recorded_brl,
|
|
32
|
+
(SELECT json_extract(fx.content, '$.rate')
|
|
33
|
+
FROM files fx
|
|
34
|
+
WHERE fx.path LIKE '.agents/config/pricing/fx/%.json'
|
|
35
|
+
ORDER BY CASE WHEN fx.path LIKE '%/current-usd-brl.json' THEN 0 ELSE 1 END,
|
|
36
|
+
json_extract(fx.content, '$.as_of') DESC
|
|
37
|
+
LIMIT 1) AS current_fx_rate,
|
|
38
|
+
SUM(u.cost_variance_usd) AS cost_variance_usd,
|
|
39
|
+
CASE COUNT(DISTINCT u.pricing_model) WHEN 1 THEN MIN(u.pricing_model) ELSE NULL END AS audit_pricing_model,
|
|
40
|
+
CASE COUNT(DISTINCT u.pricing_source) WHEN 1 THEN MIN(u.pricing_source) ELSE NULL END AS audit_pricing_source
|
|
41
|
+
FROM invocations i LEFT JOIN usage u USING(agent_invocation_id)
|
|
42
|
+
GROUP BY i.agent_invocation_id`;
|
|
43
|
+
|
|
44
|
+
export function readCostInvocationProjection(
|
|
45
|
+
database: DatabaseSync,
|
|
46
|
+
): Array<Record<string, unknown>> {
|
|
47
|
+
const sql = costInvocationProjectionSelect
|
|
48
|
+
.replaceAll(/\binvocation_usage\b/g, "zaip_vw_invocation_usage")
|
|
49
|
+
.replaceAll(/\binvocations\b/g, "zaip_vw_invocations")
|
|
50
|
+
.replaceAll(/\bfiles\b/g, "zaip_vw_files");
|
|
51
|
+
return database.prepare(sql).all() as Array<Record<string, unknown>>;
|
|
52
|
+
}
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-persistence.ts
CHANGED
|
@@ -96,20 +96,8 @@ export function persistFirstFoldPayloads(
|
|
|
96
96
|
for (const path of paths) {
|
|
97
97
|
const database = new DatabaseSync(path);
|
|
98
98
|
try {
|
|
99
|
-
const insert = database.prepare(`INSERT INTO zaip_aios_activities(
|
|
100
|
-
activity_row_id, activity_source_kind, activity_key, source_path, source_hash,
|
|
101
|
-
recorded_at, run_role, root_run_id, payload_type, payload_json
|
|
102
|
-
) VALUES (?, 'technical_payload', ?, ?, '', datetime('now'), 'technical', 'technical', ?, ?)`);
|
|
103
99
|
database.exec("BEGIN;");
|
|
104
|
-
|
|
105
|
-
insert.run(
|
|
106
|
-
`TECH-${randomUUID().toLowerCase()}`,
|
|
107
|
-
key,
|
|
108
|
-
`sqlite://${payloadType}/${key.split(":")[1]}`,
|
|
109
|
-
payloadType,
|
|
110
|
-
payloads[payloadType],
|
|
111
|
-
);
|
|
112
|
-
}
|
|
100
|
+
persistFirstFoldPayloadsInDatabase(database, payloads);
|
|
113
101
|
database.exec("COMMIT;");
|
|
114
102
|
} catch (error) {
|
|
115
103
|
database.exec("ROLLBACK;");
|
|
@@ -119,3 +107,37 @@ export function persistFirstFoldPayloads(
|
|
|
119
107
|
}
|
|
120
108
|
}
|
|
121
109
|
}
|
|
110
|
+
|
|
111
|
+
/** Adds first-fold payloads to the caller's current transaction. */
|
|
112
|
+
export function persistFirstFoldPayloadsInDatabase(
|
|
113
|
+
database: DatabaseSync,
|
|
114
|
+
payloads: FirstFoldPayloads,
|
|
115
|
+
): void {
|
|
116
|
+
const insert = database.prepare(`INSERT INTO zaip_aios_activities(
|
|
117
|
+
activity_row_id, activity_source_kind, activity_key, source_path, source_hash,
|
|
118
|
+
recorded_at, run_role, root_run_id, payload_type, payload_json
|
|
119
|
+
) VALUES (?, 'technical_payload', ?, ?, '', datetime('now'), 'technical', 'technical', ?, ?)`);
|
|
120
|
+
for (const [payloadType, key] of technicalPayloads) {
|
|
121
|
+
const existing = database
|
|
122
|
+
.prepare(
|
|
123
|
+
"SELECT activity_row_id,payload_json FROM zaip_aios_activities WHERE payload_type=? AND activity_key=?",
|
|
124
|
+
)
|
|
125
|
+
.get(payloadType, key) as { activity_row_id: string; payload_json: string } | undefined;
|
|
126
|
+
if (existing) {
|
|
127
|
+
if (existing.payload_json !== payloads[payloadType])
|
|
128
|
+
database
|
|
129
|
+
.prepare(
|
|
130
|
+
"UPDATE zaip_aios_activities SET payload_json=?,recorded_at=datetime('now') WHERE activity_row_id=?",
|
|
131
|
+
)
|
|
132
|
+
.run(payloads[payloadType], existing.activity_row_id);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
insert.run(
|
|
136
|
+
`TECH-${randomUUID().toLowerCase()}`,
|
|
137
|
+
key,
|
|
138
|
+
`sqlite://${payloadType}/${key.split(":")[1]}`,
|
|
139
|
+
payloadType,
|
|
140
|
+
payloads[payloadType],
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { DatabaseSync } from "node:sqlite";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { rebuildSqliteReadModel } from "./sqlite-read-model.js";
|
|
6
|
+
|
|
7
|
+
const roots: string[] = [];
|
|
8
|
+
|
|
9
|
+
async function fixture(): Promise<string> {
|
|
10
|
+
const directory = resolve(import.meta.dirname, "../../../../..", ".local/sqlite/tests");
|
|
11
|
+
await mkdir(directory, { recursive: true });
|
|
12
|
+
const root = await mkdtemp(join(directory, "force-canonical-"));
|
|
13
|
+
roots.push(root);
|
|
14
|
+
await mkdir(join(root, ".agents/config"), { recursive: true });
|
|
15
|
+
await writeFile(join(root, ".agents/config/project.yaml"), "zaip:\n enabled: true\n");
|
|
16
|
+
return root;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
afterEach(async () => {
|
|
20
|
+
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("forceCanonical SQLite refresh", () => {
|
|
24
|
+
it("bypasses a healthy generation and verifies canonical sources again", async () => {
|
|
25
|
+
const root = await fixture();
|
|
26
|
+
const initial = await rebuildSqliteReadModel(root);
|
|
27
|
+
await expect(rebuildSqliteReadModel(root)).resolves.toMatchObject({
|
|
28
|
+
cache: "generation",
|
|
29
|
+
refresh: { processed_sources: 0 },
|
|
30
|
+
});
|
|
31
|
+
await expect(rebuildSqliteReadModel(root, { forceCanonical: true })).resolves.toMatchObject({
|
|
32
|
+
cache: "rebuilt",
|
|
33
|
+
path: initial.path,
|
|
34
|
+
refresh: { processed_sources: 1 },
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("rebuilds a generation whose persisted schema marker is incompatible", async () => {
|
|
39
|
+
const root = await fixture();
|
|
40
|
+
const initial = await rebuildSqliteReadModel(root);
|
|
41
|
+
const database = new DatabaseSync(initial.path);
|
|
42
|
+
try {
|
|
43
|
+
database
|
|
44
|
+
.prepare(
|
|
45
|
+
"UPDATE zaip_aios_activities SET payload_json=json_set(payload_json, '$.value', 'invalid') WHERE payload_type='metadata' AND activity_key='metadata:schema_version'",
|
|
46
|
+
)
|
|
47
|
+
.run();
|
|
48
|
+
} finally {
|
|
49
|
+
database.close();
|
|
50
|
+
}
|
|
51
|
+
await expect(rebuildSqliteReadModel(root)).resolves.toMatchObject({
|
|
52
|
+
cache: "rebuilt",
|
|
53
|
+
path: initial.path,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-cache.test.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { affectedTemporalIntervals } from "./sqlite-incremental-cache.js";
|
|
3
|
+
|
|
4
|
+
describe("temporal delta dependencies", () => {
|
|
5
|
+
it("includes old overlap neighbors after removal while excluding disjoint history", () => {
|
|
6
|
+
const old = [
|
|
7
|
+
{ activityRowId: "removed", startMs: 10, endMs: 20 },
|
|
8
|
+
{ activityRowId: "neighbor", startMs: 18, endMs: 30 },
|
|
9
|
+
{ activityRowId: "chain", startMs: 29, endMs: 40 },
|
|
10
|
+
{ activityRowId: "untouched", startMs: 100, endMs: 120 },
|
|
11
|
+
];
|
|
12
|
+
const result = affectedTemporalIntervals(old, old.slice(1), new Set(["removed"]));
|
|
13
|
+
expect([...result.ids].sort()).toEqual(["chain", "neighbor", "removed"]);
|
|
14
|
+
expect(result.intervals.map((row) => row.activityRowId)).toEqual(["neighbor", "chain"]);
|
|
15
|
+
});
|
|
16
|
+
it("covers both old and new components of a moved interval without crossing a gap", () => {
|
|
17
|
+
const history = [
|
|
18
|
+
{ activityRowId: "old-neighbor", startMs: 0, endMs: 10 },
|
|
19
|
+
{ activityRowId: "gap", startMs: 30, endMs: 40 },
|
|
20
|
+
{ activityRowId: "new-neighbor", startMs: 100, endMs: 110 },
|
|
21
|
+
];
|
|
22
|
+
const result = affectedTemporalIntervals(
|
|
23
|
+
[...history, { activityRowId: "moved", startMs: 5, endMs: 15 }],
|
|
24
|
+
[...history, { activityRowId: "moved", startMs: 105, endMs: 115 }],
|
|
25
|
+
new Set(["moved"]),
|
|
26
|
+
);
|
|
27
|
+
expect([...result.ids].sort()).toEqual(["moved", "new-neighbor", "old-neighbor"]);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
3
|
+
|
|
4
|
+
/** Parsed canonical records survive worker restarts in the same transaction as their facts. */
|
|
5
|
+
export class SqliteParsedSourceCache {
|
|
6
|
+
constructor(private readonly database: DatabaseSync) {}
|
|
7
|
+
|
|
8
|
+
read<T>(kind: string, path: string, hash: string, parse: () => T): T {
|
|
9
|
+
const key = `parsed_source:${kind}:${path}`;
|
|
10
|
+
const cached = this.database
|
|
11
|
+
.prepare(
|
|
12
|
+
"SELECT source_hash, payload_json FROM zaip_aios_activities WHERE payload_type='parsed_source' AND activity_key=?",
|
|
13
|
+
)
|
|
14
|
+
.get(key) as { source_hash: string; payload_json: string } | undefined;
|
|
15
|
+
if (cached?.source_hash === hash) {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(cached.payload_json) as T;
|
|
18
|
+
} catch {
|
|
19
|
+
/* A damaged derived cache is repaired from this source only. */
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const value = parse();
|
|
23
|
+
this.database
|
|
24
|
+
.prepare(
|
|
25
|
+
"DELETE FROM zaip_aios_activities WHERE payload_type='parsed_source' AND activity_key=?",
|
|
26
|
+
)
|
|
27
|
+
.run(key);
|
|
28
|
+
this.database
|
|
29
|
+
.prepare(`INSERT INTO zaip_aios_activities(
|
|
30
|
+
activity_row_id, activity_source_kind, activity_key, source_path, source_hash,
|
|
31
|
+
recorded_at, run_role, root_run_id, payload_type, payload_json
|
|
32
|
+
) VALUES (?, 'technical_payload', ?, ?, ?, ?, 'technical', 'technical', 'parsed_source', ?)`)
|
|
33
|
+
.run(
|
|
34
|
+
`TECH-${randomUUID()}`,
|
|
35
|
+
key,
|
|
36
|
+
path,
|
|
37
|
+
hash,
|
|
38
|
+
new Date().toISOString(),
|
|
39
|
+
JSON.stringify(value),
|
|
40
|
+
);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type CachedTemporalInterval = { activityRowId: string; startMs: number; endMs: number };
|
|
46
|
+
|
|
47
|
+
/** Upserts changed derived rows while keeping untouched row identities and processing timestamps. */
|
|
48
|
+
export type IncrementalPayloadRow = {
|
|
49
|
+
row_key: string;
|
|
50
|
+
payload_json: string;
|
|
51
|
+
occurred_day_sp?: string | null;
|
|
52
|
+
};
|
|
53
|
+
export function synchronizePayloadRows(
|
|
54
|
+
database: DatabaseSync,
|
|
55
|
+
type: string,
|
|
56
|
+
select: string | readonly IncrementalPayloadRow[],
|
|
57
|
+
): void {
|
|
58
|
+
const previous = new Map(
|
|
59
|
+
(
|
|
60
|
+
database
|
|
61
|
+
.prepare(
|
|
62
|
+
"SELECT activity_row_id,activity_key,payload_json FROM zaip_aios_activities WHERE payload_type=?",
|
|
63
|
+
)
|
|
64
|
+
.all(type) as Array<{ activity_row_id: string; activity_key: string; payload_json: string }>
|
|
65
|
+
).map((row) => [row.activity_key, row]),
|
|
66
|
+
);
|
|
67
|
+
const insert = database.prepare(`INSERT INTO zaip_aios_activities(
|
|
68
|
+
activity_row_id,activity_source_kind,activity_key,source_path,source_hash,recorded_at,run_role,root_run_id,payload_type,payload_json,occurred_day_sp
|
|
69
|
+
) VALUES (?,'technical_payload',?,?,'',?,'technical','technical',?,?,?)`);
|
|
70
|
+
const update = database.prepare(
|
|
71
|
+
"UPDATE zaip_aios_activities SET payload_json=?,recorded_at=?,occurred_day_sp=? WHERE activity_row_id=?",
|
|
72
|
+
);
|
|
73
|
+
const remove = database.prepare("DELETE FROM zaip_aios_activities WHERE activity_row_id=?");
|
|
74
|
+
const rows =
|
|
75
|
+
typeof select === "string"
|
|
76
|
+
? (database.prepare(select).all() as IncrementalPayloadRow[])
|
|
77
|
+
: select;
|
|
78
|
+
for (const row of rows) {
|
|
79
|
+
const key = `${type}:${row.row_key}`;
|
|
80
|
+
const old = previous.get(key);
|
|
81
|
+
let payload = row.payload_json;
|
|
82
|
+
if (type === "source_state" && old) {
|
|
83
|
+
const value = JSON.parse(payload);
|
|
84
|
+
const original = JSON.parse(old.payload_json);
|
|
85
|
+
if (value.source_hash === original.source_hash)
|
|
86
|
+
value.last_processed_at = original.last_processed_at;
|
|
87
|
+
payload = JSON.stringify(value);
|
|
88
|
+
}
|
|
89
|
+
if (!old)
|
|
90
|
+
insert.run(
|
|
91
|
+
`TECH-${randomUUID()}`,
|
|
92
|
+
key,
|
|
93
|
+
`sqlite://${type}`,
|
|
94
|
+
new Date().toISOString(),
|
|
95
|
+
type,
|
|
96
|
+
payload,
|
|
97
|
+
row.occurred_day_sp ?? null,
|
|
98
|
+
);
|
|
99
|
+
else if (payload !== old.payload_json)
|
|
100
|
+
update.run(
|
|
101
|
+
payload,
|
|
102
|
+
new Date().toISOString(),
|
|
103
|
+
row.occurred_day_sp ?? null,
|
|
104
|
+
old.activity_row_id,
|
|
105
|
+
);
|
|
106
|
+
previous.delete(key);
|
|
107
|
+
}
|
|
108
|
+
for (const row of previous.values()) remove.run(row.activity_row_id);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Include the connected old/new overlap component so neighbors are recalculated consistently. */
|
|
112
|
+
export function affectedTemporalIntervals(
|
|
113
|
+
oldIntervals: readonly CachedTemporalInterval[],
|
|
114
|
+
newIntervals: readonly CachedTemporalInterval[],
|
|
115
|
+
dirtyIds: ReadonlySet<string>,
|
|
116
|
+
): { ids: Set<string>; intervals: CachedTemporalInterval[] } {
|
|
117
|
+
const ids = new Set(dirtyIds);
|
|
118
|
+
const ranges = [...oldIntervals, ...newIntervals].filter((interval) =>
|
|
119
|
+
ids.has(interval.activityRowId),
|
|
120
|
+
);
|
|
121
|
+
let changed = true;
|
|
122
|
+
while (changed) {
|
|
123
|
+
changed = false;
|
|
124
|
+
for (const interval of newIntervals) {
|
|
125
|
+
if (ids.has(interval.activityRowId)) continue;
|
|
126
|
+
if (
|
|
127
|
+
ranges.some((range) => interval.startMs < range.endMs && interval.endMs > range.startMs)
|
|
128
|
+
) {
|
|
129
|
+
ids.add(interval.activityRowId);
|
|
130
|
+
ranges.push(interval);
|
|
131
|
+
changed = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { ids, intervals: newIntervals.filter((interval) => ids.has(interval.activityRowId)) };
|
|
136
|
+
}
|