@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.
Files changed (332) hide show
  1. package/README.md +86 -1
  2. package/dist/commands/init.d.ts +1 -0
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.js +26 -0
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +3 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/services/adapters.js +4 -4
  11. package/dist/services/adapters.js.map +1 -1
  12. package/dist/services/codex-config-template.d.ts +2 -2
  13. package/dist/services/codex-config-template.d.ts.map +1 -1
  14. package/dist/services/codex-config-template.js +3 -3
  15. package/dist/services/codex-config-template.js.map +1 -1
  16. package/dist/services/codex-rules.d.ts +1 -1
  17. package/dist/services/codex-rules.d.ts.map +1 -1
  18. package/dist/services/codex-rules.js +9 -24
  19. package/dist/services/codex-rules.js.map +1 -1
  20. package/dist/services/delivery-git-preflight.d.ts +23 -0
  21. package/dist/services/delivery-git-preflight.d.ts.map +1 -0
  22. package/dist/services/delivery-git-preflight.js +69 -0
  23. package/dist/services/delivery-git-preflight.js.map +1 -0
  24. package/dist/services/doctor.d.ts.map +1 -1
  25. package/dist/services/doctor.js +13 -1
  26. package/dist/services/doctor.js.map +1 -1
  27. package/dist/services/install-agents-template.d.ts.map +1 -1
  28. package/dist/services/install-agents-template.js +22 -28
  29. package/dist/services/install-agents-template.js.map +1 -1
  30. package/dist/services/install-profile.d.ts +8 -0
  31. package/dist/services/install-profile.d.ts.map +1 -0
  32. package/dist/services/install-profile.js +56 -0
  33. package/dist/services/install-profile.js.map +1 -0
  34. package/dist/services/logger.d.ts.map +1 -1
  35. package/dist/services/logger.js +6 -5
  36. package/dist/services/logger.js.map +1 -1
  37. package/dist/services/stack-git.d.ts +9 -0
  38. package/dist/services/stack-git.d.ts.map +1 -0
  39. package/dist/services/stack-git.js +188 -0
  40. package/dist/services/stack-git.js.map +1 -0
  41. package/dist/services/stack-install.d.ts +14 -0
  42. package/dist/services/stack-install.d.ts.map +1 -0
  43. package/dist/services/stack-install.js +176 -0
  44. package/dist/services/stack-install.js.map +1 -0
  45. package/dist/services/stack-node.d.ts +12 -0
  46. package/dist/services/stack-node.d.ts.map +1 -0
  47. package/dist/services/stack-node.js +150 -0
  48. package/dist/services/stack-node.js.map +1 -0
  49. package/dist/services/stack-package-manager.d.ts +12 -0
  50. package/dist/services/stack-package-manager.d.ts.map +1 -0
  51. package/dist/services/stack-package-manager.js +178 -0
  52. package/dist/services/stack-package-manager.js.map +1 -0
  53. package/dist/services/stack-plan.d.ts +35 -0
  54. package/dist/services/stack-plan.d.ts.map +1 -0
  55. package/dist/services/stack-plan.js +130 -0
  56. package/dist/services/stack-plan.js.map +1 -0
  57. package/dist/services/stack-terraform.d.ts +13 -0
  58. package/dist/services/stack-terraform.d.ts.map +1 -0
  59. package/dist/services/stack-terraform.js +274 -0
  60. package/dist/services/stack-terraform.js.map +1 -0
  61. package/dist/services/template-manifest.d.ts.map +1 -1
  62. package/dist/services/template-manifest.js +14 -1
  63. package/dist/services/template-manifest.js.map +1 -1
  64. package/dist/types.d.ts +4 -0
  65. package/dist/types.d.ts.map +1 -1
  66. package/package.json +1 -1
  67. package/templates/.agents/.env.example +34 -0
  68. package/templates/{README.md → .agents/README.md} +124 -60
  69. package/templates/.agents/config/agents/catalog.yaml +23 -23
  70. package/templates/.agents/config/clients/codex/agents/zaip-agent-analyst.toml +1 -0
  71. package/templates/.agents/config/clients/codex/agents/zaip-agent-auditor.toml +1 -0
  72. package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +5 -4
  73. package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +1 -0
  74. package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +1 -0
  75. package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +10 -7
  76. package/templates/.agents/config/clients/codex/agents/zaip-agent-data-analyst.toml +1 -0
  77. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +1 -0
  78. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -0
  79. package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +5 -4
  80. package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +1 -0
  81. package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +1 -0
  82. package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +1 -0
  83. package/templates/.agents/config/clients/codex/agents/zaip-agent-integrator.toml +1 -0
  84. package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +5 -4
  85. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -0
  86. package/templates/.agents/config/clients/codex/agents/zaip-agent-refactoring-specialist.toml +1 -0
  87. package/templates/.agents/config/clients/codex/agents/zaip-agent-reviewer.toml +1 -0
  88. package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +1 -0
  89. package/templates/.agents/config/clients/codex/agents/zaip-agent-security-auditor.toml +1 -0
  90. package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +1 -0
  91. package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +5 -4
  92. package/templates/.agents/config/clients/codex/agents/zaip-agent-writer.toml +1 -0
  93. package/templates/.agents/config/pricing/models.json +25 -1
  94. package/templates/.agents/config/project.yaml +2 -0
  95. package/templates/.agents/dashboard/.zaip-managed.json +214 -94
  96. package/templates/.agents/dashboard/DATA-DICTIONARY.md +1 -1
  97. package/templates/.agents/dashboard/README.md +58 -19
  98. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-DwVZOmMV.js → CostCalculationGuidePage-snUCQYTC.js} +1 -1
  99. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog--czwAlcH.js → DashboardHelpDialog-oZVlf-l5.js} +787 -723
  100. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-CyjMXkm8.js → PricingSettingsDialog-BPtVUGgs.js} +1 -1
  101. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-3Awyaovx.js +3 -0
  102. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-BomxqCBU.css → ProjectSettingsPage-GgzpZ_PY.css} +1 -1
  103. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CAqYVin1.js → TraceabilityWorkspace-BYjVOHI_.js} +1 -1
  104. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DbaLbU2q.js +68 -0
  105. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DXBOtWNI.js → icons-vendor-TPUT2IUt.js} +1 -1
  106. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cmlx8OYH.css +1 -0
  107. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-ZJFXmK7m.js +2 -0
  108. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-DaNXQPyk.js → react-vendor-Ct48XHGL.js} +1 -1
  109. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-I4AKqVDX.js → traceability-BDe4_Ubl.js} +1 -1
  110. package/templates/.agents/dashboard/apps/frontend/dist/index.html +6 -6
  111. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +73 -67
  112. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +35 -7
  113. package/templates/.agents/dashboard/apps/frontend/src/AppWorkBoard.ts +55 -0
  114. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +15 -2
  115. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +33 -6
  116. package/templates/.agents/dashboard/apps/frontend/src/app-loading-boundary.css +98 -0
  117. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +5 -5
  118. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api-reconciliation.ts +33 -0
  119. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +75 -0
  120. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +9 -8
  121. package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +15 -3
  122. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +0 -104
  123. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +61 -0
  124. package/templates/.agents/dashboard/apps/frontend/src/project-stack-versions.css +117 -0
  125. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +78 -2
  126. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +28 -0
  127. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +8 -5
  128. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +180 -1
  129. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +7 -4
  130. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +13 -7
  131. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +14 -0
  132. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableDisplay.ts +211 -0
  133. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +152 -157
  134. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +155 -142
  135. package/templates/.agents/dashboard/modules/cost-monitor/src/react/InvocationManifestQuery.test.ts +145 -0
  136. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +7 -5
  137. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +4 -1
  138. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +4 -1
  139. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +4 -1
  140. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +4 -4
  141. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +79 -1
  142. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +105 -11
  143. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +477 -327
  144. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +430 -285
  145. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +14 -2
  146. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +6 -26
  147. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +1 -1
  148. package/templates/.agents/dashboard/packages/local-runtime/scripts/verify-persistent-launch.mjs +268 -0
  149. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +482 -332
  150. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +243 -1
  151. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +252 -41
  152. package/templates/.agents/dashboard/packages/local-runtime/src/server-agent-assets.ts +39 -0
  153. package/templates/.agents/dashboard/packages/local-runtime/src/server-browser-lease.ts +33 -0
  154. package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-refresh.test.ts +148 -11
  155. package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-result.test.ts +68 -0
  156. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +19 -0
  157. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.ts +39 -43
  158. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-revision.test.ts +42 -0
  159. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-revision.ts +26 -0
  160. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +34 -0
  161. package/templates/.agents/dashboard/packages/local-runtime/src/server-startup.ts +30 -0
  162. package/templates/.agents/dashboard/packages/local-runtime/src/server-work-reconciliation.test.ts +89 -0
  163. package/templates/.agents/dashboard/packages/local-runtime/src/server-work-reconciliation.ts +88 -0
  164. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +68 -7
  165. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +11 -5
  166. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +129 -99
  167. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-agent-productivity.test.ts +111 -0
  168. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-agent-productivity.ts +140 -0
  169. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.test.ts +127 -4
  170. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.ts +145 -5
  171. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-aggregates.ts +156 -23
  172. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts +18 -9
  173. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-projection.ts +52 -0
  174. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-persistence.ts +35 -13
  175. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-force-canonical.test.ts +56 -0
  176. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-cache.test.ts +29 -0
  177. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-cache.ts +136 -0
  178. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-refresh.test.ts +251 -0
  179. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +22 -7
  180. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-cache.test-support.ts +1 -1
  181. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical-parsing.ts +42 -0
  182. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +793 -0
  183. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider-duration.test.ts +270 -0
  184. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider-fixture.ts +3 -2
  185. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +18 -4
  186. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.test.ts +87 -0
  187. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +105 -16
  188. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +131 -59
  189. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +1000 -1115
  190. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-cache.ts +13 -92
  191. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-claims.test.mjs +79 -0
  192. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +27 -0
  193. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.mjs +6 -6
  194. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-prerequisites.mjs +1 -1
  195. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-refresh.mjs +2 -10
  196. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-server.mjs +142 -0
  197. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +231 -239
  198. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +18 -29
  199. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +6 -0
  200. package/templates/.agents/dashboard/stack-dependencies.json +14 -0
  201. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  202. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  203. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +47 -0
  204. package/templates/.agents/requirements/comparative-audit.md +1 -1
  205. package/templates/.agents/requirements/context-engine.md +1 -1
  206. package/templates/.agents/requirements/cost-observability.md +1 -1
  207. package/templates/.agents/requirements/dashboard-launch.md +2 -2
  208. package/templates/.agents/requirements/data-export.md +1 -1
  209. package/templates/.agents/requirements/design-system.md +1 -1
  210. package/templates/.agents/requirements/execution-engine.md +1 -1
  211. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  212. package/templates/.agents/requirements/model-orchestration.md +1 -1
  213. package/templates/.agents/requirements/public-distribution.md +1 -1
  214. package/templates/.agents/requirements/software-architecture.md +1 -1
  215. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  216. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  217. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  218. package/templates/.agents/rules/autonomy-decision.md +1 -1
  219. package/templates/.agents/rules/cloud-hostinger-autonomy.md +21 -0
  220. package/templates/.agents/rules/core.md +5 -4
  221. package/templates/.agents/rules/local-sqlite-storage.md +18 -0
  222. package/templates/.agents/rules/meta-mcp.md +21 -0
  223. package/templates/.agents/rules/workflow.md +1 -0
  224. package/templates/.agents/runtime/bin/zaip.mjs +305 -137
  225. package/templates/.agents/runtime/checksums.sha256 +2 -2
  226. package/templates/.agents/runtime/provenance.json +2 -2
  227. package/templates/.agents/skills/zaip-skill-api-to-mcp/SKILL.md +4 -0
  228. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +25 -9
  229. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-framework.md +2 -2
  230. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +2 -2
  231. package/templates/.agents/skills/zaip-skill-change/references/observable-evidence.md +15 -0
  232. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +13 -5
  233. package/templates/.agents/skills/zaip-skill-data-analyst/SKILL.md +10 -5
  234. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +5 -4
  235. package/templates/.agents/skills/zaip-skill-frontend-launcher/SKILL.md +4 -3
  236. package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +5 -3
  237. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +5 -5
  238. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.mjs +78 -13
  239. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.test.mjs +59 -0
  240. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/yaml-parser.mjs +157 -0
  241. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +11 -6
  242. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/SKILL.md +17 -0
  243. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/agents/openai.yaml +7 -0
  244. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/autonomous-cloud-inputs.example.json +41 -0
  245. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/autonomous-runner.md +84 -0
  246. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/operational-contract.md +19 -0
  247. package/templates/.agents/skills/zaip-skill-local-credentials/SKILL.md +43 -0
  248. package/templates/.agents/skills/zaip-skill-local-credentials/agents/openai.yaml +6 -0
  249. package/templates/.agents/skills/zaip-skill-local-credentials/references/dotenv-resolution.md +47 -0
  250. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +8 -3
  251. package/templates/.agents/skills/zaip-skill-meta-ads/SKILL.md +16 -0
  252. package/templates/.agents/skills/zaip-skill-meta-ads/agents/openai.yaml +4 -0
  253. package/templates/.agents/skills/zaip-skill-meta-ads/references/setup.md +3 -0
  254. package/templates/.agents/skills/zaip-skill-meta-ads-setup/SKILL.md +24 -0
  255. package/templates/.agents/skills/zaip-skill-meta-ads-setup/agents/openai.yaml +4 -0
  256. package/templates/.agents/skills/zaip-skill-meta-ads-setup/references/diagnostics.md +13 -0
  257. package/templates/.agents/skills/zaip-skill-meta-ads-setup/references/official-sources.md +10 -0
  258. package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/SKILL.md +12 -0
  259. package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/agents/openai.yaml +4 -0
  260. package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/references/LICENSE +21 -0
  261. package/templates/.agents/skills/zaip-skill-meta-devtools-api-health/references/upstream.md +77 -0
  262. package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/SKILL.md +12 -0
  263. package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/agents/openai.yaml +4 -0
  264. package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/references/LICENSE +21 -0
  265. package/templates/.agents/skills/zaip-skill-meta-devtools-api-integration/references/upstream.md +126 -0
  266. package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/SKILL.md +12 -0
  267. package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/agents/openai.yaml +4 -0
  268. package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/references/LICENSE +21 -0
  269. package/templates/.agents/skills/zaip-skill-meta-devtools-app-health-check/references/upstream.md +67 -0
  270. package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/SKILL.md +12 -0
  271. package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/agents/openai.yaml +4 -0
  272. package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/references/LICENSE +21 -0
  273. package/templates/.agents/skills/zaip-skill-meta-devtools-app-review-prep/references/upstream.md +69 -0
  274. package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/SKILL.md +12 -0
  275. package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/agents/openai.yaml +4 -0
  276. package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/references/LICENSE +21 -0
  277. package/templates/.agents/skills/zaip-skill-meta-devtools-compliance-check/references/upstream.md +79 -0
  278. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/SKILL.md +14 -0
  279. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/agents/openai.yaml +4 -0
  280. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/references/LICENSE +21 -0
  281. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-access-token/references/upstream.md +144 -0
  282. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/SKILL.md +12 -0
  283. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/agents/openai.yaml +4 -0
  284. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/references/LICENSE +21 -0
  285. package/templates/.agents/skills/zaip-skill-meta-devtools-debug-webhooks/references/upstream.md +83 -0
  286. package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/SKILL.md +10 -0
  287. package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/agents/openai.yaml +4 -0
  288. package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/references/LICENSE +21 -0
  289. package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/references/setup.md +11 -0
  290. package/templates/.agents/skills/zaip-skill-meta-devtools-search-docs/references/upstream.md +55 -0
  291. package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/SKILL.md +12 -0
  292. package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/agents/openai.yaml +4 -0
  293. package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/references/LICENSE +21 -0
  294. package/templates/.agents/skills/zaip-skill-meta-devtools-webhook-setup/references/upstream.md +56 -0
  295. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +12 -7
  296. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +11 -4
  297. package/templates/.agents/skills/zaip-skill-tool-setup/SKILL.md +6 -4
  298. package/templates/.agents/skills/zaip-skill-tool-setup/references/codex-config.md +4 -2
  299. package/templates/.agents/skills/zaip-skill-tool-setup/references/secrets.md +1 -0
  300. package/templates/.agents/tools/catalog.yaml +6 -0
  301. package/templates/.agents/tools/cloud-runner-dns.mjs +28 -0
  302. package/templates/.agents/tools/cloud-runner-terraform.mjs +212 -0
  303. package/templates/.agents/tools/cloud-runner.integration.test.mjs +239 -0
  304. package/templates/.agents/tools/cloud-runner.mjs +786 -0
  305. package/templates/.agents/tools/cloud-runner.test.mjs +534 -0
  306. package/templates/.agents/tools/cloud-terraform-plan-policy.mjs +262 -0
  307. package/templates/.agents/tools/mcp/development/meta-devtools/README.md +14 -0
  308. package/templates/.agents/tools/mcp/development/meta-devtools/manifest.yaml +28 -0
  309. package/templates/.agents/tools/mcp/infra/cloudflare/manifest.yaml +2 -3
  310. package/templates/.agents/tools/mcp/infra/hostinger/manifest.yaml +1 -3
  311. package/templates/.agents/tools/mcp/marketing/meta-ads/README.md +15 -13
  312. package/templates/.agents/tools/mcp/marketing/meta-ads/manifest.yaml +15 -10
  313. package/templates/.agents/tools/profiles/development.yaml +3 -0
  314. package/templates/infra/terraform/.terraform.lock.hcl +42 -0
  315. package/templates/infra/terraform/README.md +31 -0
  316. package/templates/infra/terraform/backend.tf.json +13 -0
  317. package/templates/infra/terraform/deployment-inputs.example.yaml +22 -0
  318. package/templates/infra/terraform/fixtures/approved-targets.json +32 -0
  319. package/templates/infra/terraform/fixtures/plan-approved.json +67 -0
  320. package/templates/infra/terraform/main.tf +77 -0
  321. package/templates/infra/terraform/outputs.tf +20 -0
  322. package/templates/infra/terraform/terraform.tfvars.example +26 -0
  323. package/templates/infra/terraform/variables.tf +91 -0
  324. package/templates/infra/terraform/versions.tf +18 -0
  325. package/templates/scripts/validate-cloud-hostinger-contract.mjs +89 -0
  326. package/templates/scripts/validate-cloud-terraform-plan.mjs +1 -0
  327. package/templates/template-manifest.json +613 -173
  328. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-B_Oj6Dlf.js +0 -3
  329. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-C09KmlSw.js +0 -68
  330. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CblPpexd.js +0 -2
  331. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-hPPfVGQv.css +0 -1
  332. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-stale-seed.ts +0 -50
@@ -17,6 +17,68 @@ import {
17
17
  } from "./operations-detail-hydration.js";
18
18
 
19
19
  export const projectionRefreshDebounceMs = 5_000;
20
+ export const snapshotReadyPollMs = 2_000;
21
+ export const snapshotReadyPollAttempts = 90;
22
+ export const snapshotRevisionVisiblePollMs = 5_000;
23
+ export const snapshotRevisionHiddenPollMs = 10_000;
24
+ export const snapshotRevisionHiddenFailurePollMs = 30_000;
25
+ export const snapshotReadyPollExhaustedMessage =
26
+ "A atualização do snapshot não foi concluída. Os dados exibidos podem estar desatualizados.";
27
+
28
+ export function shouldPollSnapshotReady(snapshotUpdating: boolean, attempts: number): boolean {
29
+ return snapshotUpdating && attempts < snapshotReadyPollAttempts;
30
+ }
31
+
32
+ export function snapshotRevisionPollDelay(
33
+ visibilityState: DocumentVisibilityState,
34
+ consecutiveFailures: number,
35
+ ): number {
36
+ if (visibilityState === "visible") return snapshotRevisionVisiblePollMs;
37
+ return consecutiveFailures > 0
38
+ ? snapshotRevisionHiddenFailurePollMs
39
+ : snapshotRevisionHiddenPollMs;
40
+ }
41
+
42
+ export function shouldRefreshForSnapshotRevision(
43
+ previousRevision: string | null,
44
+ nextRevision: string | undefined,
45
+ ): boolean {
46
+ return (
47
+ previousRevision !== null &&
48
+ typeof nextRevision === "string" &&
49
+ nextRevision.length > 0 &&
50
+ previousRevision !== nextRevision
51
+ );
52
+ }
53
+
54
+ export function isCommittedSnapshotRevision(
55
+ snapshotState: "current" | "updating" | undefined,
56
+ snapshotRevision: string | undefined,
57
+ ): snapshotRevision is string {
58
+ return (
59
+ (snapshotState === "current" || snapshotState === "updating") &&
60
+ typeof snapshotRevision === "string" &&
61
+ snapshotRevision.length > 0
62
+ );
63
+ }
64
+
65
+ export function settleSnapshotRevisionRefresh({
66
+ observedRevision,
67
+ pendingRevision,
68
+ requestedRevision,
69
+ succeeded,
70
+ }: {
71
+ observedRevision: string | null;
72
+ pendingRevision: string | null;
73
+ requestedRevision: string;
74
+ succeeded: boolean;
75
+ }): { observedRevision: string | null; pendingRevision: string | null } {
76
+ if (!succeeded) return { observedRevision, pendingRevision };
77
+ return {
78
+ observedRevision: requestedRevision,
79
+ pendingRevision: pendingRevision === requestedRevision ? null : pendingRevision,
80
+ };
81
+ }
20
82
 
21
83
  export function shouldRefreshVisibleProjection({
22
84
  inFlight,
@@ -48,6 +110,8 @@ export function useAppEffects({
48
110
  pricing,
49
111
  refresh,
50
112
  refreshVersion,
113
+ snapshotUpdating,
114
+ setSnapshotUpdating,
51
115
  setError,
52
116
  setFxRate,
53
117
  setPathname,
@@ -68,8 +132,11 @@ export function useAppEffects({
68
132
  visible?: boolean,
69
133
  reconcileOpenWork?: boolean,
70
134
  refreshProjection?: boolean,
71
- ) => Promise<void>;
135
+ reloadCostSummary?: boolean,
136
+ ) => Promise<boolean>;
72
137
  refreshVersion: MutableRefObject<number>;
138
+ snapshotUpdating: boolean;
139
+ setSnapshotUpdating: Dispatch<SetStateAction<boolean>>;
73
140
  setError: Dispatch<SetStateAction<string | null>>;
74
141
  setFxRate: Dispatch<SetStateAction<Awaited<ReturnType<DashboardApiClient["fxRate"]>> | null>>;
75
142
  setPathname: Dispatch<SetStateAction<string>>;
@@ -77,6 +144,9 @@ export function useAppEffects({
77
144
  }) {
78
145
  const projectionRefreshInFlight = useRef(false);
79
146
  const lastProjectionRefreshAt = useRef(0);
147
+ const observedSnapshotRevision = useRef<string | null>(null);
148
+ const snapshotRevisionRefreshInFlight = useRef(false);
149
+ const pendingSnapshotRevisionRefresh = useRef<string | null>(null);
80
150
  useEffect(() => {
81
151
  void refresh();
82
152
  return () => {
@@ -124,6 +194,115 @@ export function useAppEffects({
124
194
  };
125
195
  }, [refresh]);
126
196
 
197
+ useEffect(() => {
198
+ if (!snapshotUpdating) return;
199
+ let cancelled = false;
200
+ let attempts = 0;
201
+ let timeout: number | null = null;
202
+ const pollReady = async () => {
203
+ if (cancelled || !shouldPollSnapshotReady(true, attempts)) return;
204
+ attempts += 1;
205
+ try {
206
+ const ready = await api.ready();
207
+ if (cancelled) return;
208
+ if (ready.snapshot_state === "current") {
209
+ setSnapshotUpdating(false);
210
+ // Promotion produced a new immutable SQLite generation. Reload its
211
+ // Operations and Cost Monitor summaries by GET; never rebuild or
212
+ // reconcile as part of the readiness poll.
213
+ await refresh(false, false, false, true);
214
+ return;
215
+ }
216
+ } catch {
217
+ // Keep the validated stale seed visible within the bounded poll window.
218
+ }
219
+ if (cancelled) return;
220
+ if (shouldPollSnapshotReady(true, attempts)) {
221
+ timeout = window.setTimeout(() => void pollReady(), snapshotReadyPollMs);
222
+ return;
223
+ }
224
+ // Stop the progress indicator after the bounded window, while retaining
225
+ // an explicit visible warning that the stale snapshot remains on screen.
226
+ setSnapshotUpdating(false);
227
+ setError(snapshotReadyPollExhaustedMessage);
228
+ };
229
+ void pollReady();
230
+ return () => {
231
+ cancelled = true;
232
+ if (timeout !== null) window.clearTimeout(timeout);
233
+ };
234
+ }, [api, refresh, setError, setSnapshotUpdating, snapshotUpdating]);
235
+
236
+ useEffect(() => {
237
+ let cancelled = false;
238
+ let consecutiveFailures = 0;
239
+ let timeout: number | null = null;
240
+
241
+ const refreshChangedRevision = () => {
242
+ if (cancelled || snapshotRevisionRefreshInFlight.current) return;
243
+ const requestedRevision = pendingSnapshotRevisionRefresh.current;
244
+ if (requestedRevision === null) return;
245
+ snapshotRevisionRefreshInFlight.current = true;
246
+ // A committed revision is discovered by GET /ready. Its data reload
247
+ // remains GET-only: it must never start a projection rebuild or
248
+ // lifecycle reconciliation from a tab that happened to stay open.
249
+ void refresh(false, false, false, true)
250
+ .then((succeeded) => {
251
+ const settled = settleSnapshotRevisionRefresh({
252
+ observedRevision: observedSnapshotRevision.current,
253
+ pendingRevision: pendingSnapshotRevisionRefresh.current,
254
+ requestedRevision,
255
+ succeeded,
256
+ });
257
+ // A failed GET leaves the exact revision pending. The following
258
+ // passive readiness poll retries it without changing the UI state.
259
+ observedSnapshotRevision.current = settled.observedRevision;
260
+ pendingSnapshotRevisionRefresh.current = settled.pendingRevision;
261
+ })
262
+ .finally(() => {
263
+ snapshotRevisionRefreshInFlight.current = false;
264
+ // A newer committed revision that arrived while this GET was in
265
+ // flight can run immediately; retrying the same rejected revision
266
+ // waits for the normal passive polling cadence.
267
+ if (pendingSnapshotRevisionRefresh.current !== requestedRevision) {
268
+ refreshChangedRevision();
269
+ }
270
+ });
271
+ };
272
+
273
+ const pollRevision = async () => {
274
+ try {
275
+ const ready = await api.ready();
276
+ if (cancelled) return;
277
+ consecutiveFailures = 0;
278
+ const previousRevision = observedSnapshotRevision.current;
279
+ if (isCommittedSnapshotRevision(ready.snapshot_state, ready.snapshot_revision)) {
280
+ if (previousRevision === null) {
281
+ observedSnapshotRevision.current = ready.snapshot_revision;
282
+ }
283
+ if (shouldRefreshForSnapshotRevision(previousRevision, ready.snapshot_revision)) {
284
+ pendingSnapshotRevisionRefresh.current = ready.snapshot_revision;
285
+ refreshChangedRevision();
286
+ }
287
+ }
288
+ } catch {
289
+ consecutiveFailures += 1;
290
+ }
291
+ if (!cancelled) {
292
+ timeout = window.setTimeout(
293
+ () => void pollRevision(),
294
+ snapshotRevisionPollDelay(document.visibilityState, consecutiveFailures),
295
+ );
296
+ }
297
+ };
298
+
299
+ void pollRevision();
300
+ return () => {
301
+ cancelled = true;
302
+ if (timeout !== null) window.clearTimeout(timeout);
303
+ };
304
+ }, [api, refresh]);
305
+
127
306
  useEffect(() => {
128
307
  if (
129
308
  !shouldHydrateOperationsDetails(
@@ -135,6 +135,8 @@ export interface CostGroupRow {
135
135
  run_count: number;
136
136
  /** Null when a paged source does not provide a factual task attribution. */
137
137
  task_count: number | null;
138
+ /** Distinct factual conversation memberships for the displayed model. */
139
+ conversation_count?: number | null;
138
140
  /** Canonical export fields; task_count remains the active-task alias. */
139
141
  tasksCreated?: number;
140
142
  tasksActive?: number | null;
@@ -143,10 +145,11 @@ export interface CostGroupRow {
143
145
  /** Stable ZAIP identity details for the Agent aggregation only. */
144
146
  persona?: string | null;
145
147
  job?: string | null;
146
- prd_count: number;
147
- spec_count: number;
148
- evidence_count: number;
149
- test_count: number;
148
+ /** Creation-run attribution is unavailable when canonical linkage is absent. */
149
+ prd_count: number | null;
150
+ spec_count: number | null;
151
+ evidence_count: number | null;
152
+ test_count: number | null;
150
153
  event_count: number;
151
154
  total_tokens: number | null;
152
155
  estimated_usd: number | null;
@@ -290,16 +290,22 @@ export function CostMonitorContent({
290
290
  locale={locale}
291
291
  loading={groupPageLoading}
292
292
  rows={groups[key]}
293
- {...(key === "models" || key === "providers"
294
- ? { totals: summaryTotals }
295
- : groupPage?.totals === undefined
293
+ {...(key === "models"
294
+ ? groupPage?.totals === undefined
296
295
  ? {}
297
- : { totals: groupPage.totals })}
296
+ : { totals: groupPage.totals }
297
+ : key === "providers"
298
+ ? { totals: summaryTotals }
299
+ : groupPage?.totals === undefined
300
+ ? {}
301
+ : { totals: groupPage.totals })}
298
302
  {...(key === "agents"
299
303
  ? { showDateTime: false, showAgentIdentity: true }
300
- : key === "models" || key === "providers"
301
- ? { showDateTime: false, showInvocationTasks: true }
302
- : {})}
304
+ : key === "models"
305
+ ? { showDateTime: false, showModelLifecycleDetails: true }
306
+ : key === "providers"
307
+ ? { showDateTime: false, showInvocationTasks: true }
308
+ : {})}
303
309
  />
304
310
  {groupPager}
305
311
  </>
@@ -204,6 +204,17 @@ export function CostMonitorPage({
204
204
  const [detailLoading, setDetailLoading] = useState(false);
205
205
  const [detailError, setDetailError] = useState<string | null>(null);
206
206
  const [detailAttempt, setDetailAttempt] = useState(0);
207
+ // The summary object is replaced only when the host receives a newer
208
+ // snapshot. Keep this revision separate from tabs and filters so the active
209
+ // remote table is reloaded without remounting the Cost Monitor surface.
210
+ const dataRevisionRef = useRef({ data, revision: 0 });
211
+ if (dataRevisionRef.current.data !== data) {
212
+ dataRevisionRef.current = {
213
+ data,
214
+ revision: dataRevisionRef.current.revision + 1,
215
+ };
216
+ }
217
+ const dataRevision = dataRevisionRef.current.revision;
207
218
  const loadDetailRef = useRef(loadDetail);
208
219
  loadDetailRef.current = loadDetail;
209
220
  const text = costCopy[locale];
@@ -267,6 +278,7 @@ export function CostMonitorPage({
267
278
  globalQuery: globalFilters?.query ?? "",
268
279
  filters,
269
280
  limit: groupPageLimit,
281
+ revision: dataRevision,
270
282
  ...(groupView === null ? {} : { load: loadGroupPage }),
271
283
  });
272
284
  const displayedGroupPage = groupPageState.page ?? groupPageState.stalePage;
@@ -285,6 +297,7 @@ export function CostMonitorPage({
285
297
  range: compactPageRange,
286
298
  query: globalFilters?.query,
287
299
  filters,
300
+ revision: dataRevision,
288
301
  });
289
302
  // Server pagination is safe only when every active Run filter is part of the
290
303
  // endpoint contract. Unsupported local text/metadata filters retain the
@@ -309,6 +322,7 @@ export function CostMonitorPage({
309
322
  // must not silently add a date range and bypass the fast all-time page.
310
323
  range: groupPageRange,
311
324
  refresh: lastUpdatedAt,
325
+ revision: dataRevision,
312
326
  load: loadRunPage,
313
327
  });
314
328
  useEffect(
@@ -0,0 +1,211 @@
1
+ import { formatCompactNumber, formatCurrency, formatDurationMs } from "@zaip-ai/dashboard-ui";
2
+ import type { CostRunRow, DurationCoverage } from "../contracts.js";
3
+ import type { CostCurrency, CostLocale } from "./cost-monitor-copy.js";
4
+ import {
5
+ formatBrlRate,
6
+ formatMultiplierPair,
7
+ formatRate,
8
+ formatUsd,
9
+ } from "./cost-table-presentation.js";
10
+
11
+ export function displayCostGroupLabel(label: string, locale: CostLocale): string {
12
+ const normalized = label.trim().toLowerCase();
13
+ return normalized.length === 0 || normalized === "unknown"
14
+ ? locale === "pt-BR"
15
+ ? "Sem modelo/provedor atribuído"
16
+ : "No model/provider assigned"
17
+ : label;
18
+ }
19
+
20
+ export function formatAuditableNumber(value: number | null, locale: CostLocale): string {
21
+ return new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value ?? 0);
22
+ }
23
+
24
+ export function formatFactualCount(value: number | null, locale: CostLocale): string {
25
+ return value === null
26
+ ? locale === "pt-BR"
27
+ ? "Indisponível"
28
+ : "Unavailable"
29
+ : formatAuditableNumber(value, locale);
30
+ }
31
+
32
+ export function formatAuditableCompactNumber(value: number | null, locale: CostLocale): string {
33
+ return formatCompactNumber(value ?? 0, locale);
34
+ }
35
+
36
+ export function formatAuditableCurrency(
37
+ value: number | null,
38
+ currency: CostCurrency,
39
+ locale: CostLocale,
40
+ ): string {
41
+ if (value === null) return locale === "pt-BR" ? "Indisponível" : "Unavailable";
42
+ return formatCurrency(value, currency, locale);
43
+ }
44
+
45
+ export function formatAuditableDuration(value: number | null, locale: CostLocale): string {
46
+ if (value === null) return locale === "pt-BR" ? "Indisponível" : "Unavailable";
47
+ return value === 0 ? "0" : formatDurationMs(value, locale);
48
+ }
49
+
50
+ export const formatInvocationNumber = (value: number | null, locale: CostLocale) =>
51
+ formatAuditableNumber(value, locale);
52
+ export const formatInvocationCurrency = (
53
+ value: number | null,
54
+ currency: CostCurrency,
55
+ locale: CostLocale,
56
+ ) => formatAuditableCurrency(value, currency, locale);
57
+ export const formatInvocationDuration = (value: number | null, locale: CostLocale) =>
58
+ formatAuditableDuration(value, locale);
59
+ export const formatInvocationRate = (value: number | null, locale: CostLocale) =>
60
+ formatRate(value, locale);
61
+ export const formatInvocationUsd = (value: number | null, locale: CostLocale) =>
62
+ formatUsd(value, locale);
63
+ export const formatInvocationBrlRate = (value: number | null, locale: CostLocale) =>
64
+ formatBrlRate(value, locale);
65
+ export const formatInvocationMultiplierPair = (
66
+ input: number | null,
67
+ output: number | null,
68
+ locale: CostLocale,
69
+ ) => formatMultiplierPair(input, output, locale);
70
+
71
+ export function invocationMetricDescription(locale: CostLocale, metric: string): string {
72
+ const source =
73
+ locale === "pt-BR"
74
+ ? "Valor da projeção SQLite/API desta Invocação de Agente. Fato canônico nulo permanece indisponível e não é convertido em zero."
75
+ : "Value from this Agent Invocation's SQLite/API projection. A null canonical fact remains unavailable and is not converted to zero.";
76
+ const details: Record<string, readonly [string, string]> = {
77
+ duration: [
78
+ "Tempo factual da invocação, quando capturado ou reconciliado.",
79
+ "Factual invocation duration, when captured or reconciled.",
80
+ ],
81
+ inputTokens: [
82
+ "Input total informado pela fonte; inclui a parcela de cache.",
83
+ "Source-reported total input; includes the cached portion.",
84
+ ],
85
+ cachedInputTokens: [
86
+ "Parcela de cache já incluída no input total.",
87
+ "Cached portion already included in total input.",
88
+ ],
89
+ outputTokens: [
90
+ "Output total informado pela fonte; inclui a parcela de raciocínio.",
91
+ "Source-reported total output; includes the reasoning portion.",
92
+ ],
93
+ reasoningTokens: [
94
+ "Parcela de raciocínio já incluída no output total.",
95
+ "Reasoning portion already included in total output.",
96
+ ],
97
+ totalTokens: [
98
+ "Soma de entrada e saída quando ambas são conhecidas; caso contrário, total informado pela fonte.",
99
+ "Input plus output when both are known; otherwise the source-reported total.",
100
+ ],
101
+ inputRate: [
102
+ "Tarifa efetiva de entrada em USD por milhão de tokens.",
103
+ "Effective input rate in USD per million tokens.",
104
+ ],
105
+ cacheRate: [
106
+ "Tarifa efetiva de entrada em cache em USD por milhão de tokens.",
107
+ "Effective cached-input rate in USD per million tokens.",
108
+ ],
109
+ outputRate: [
110
+ "Tarifa efetiva de saída em USD por milhão de tokens.",
111
+ "Effective output rate in USD per million tokens.",
112
+ ],
113
+ reasoningRate: [
114
+ "Tarifa efetiva de raciocínio em USD por milhão de tokens.",
115
+ "Effective reasoning rate in USD per million tokens.",
116
+ ],
117
+ contextMultiplier: [
118
+ "Multiplicadores de contexto de entrada/saída aplicados aos segmentos internos.",
119
+ "Input/output context multipliers applied to internal segments.",
120
+ ],
121
+ inputCost: [
122
+ "Custo USD de entrada calculado com tokens e tarifa efetiva.",
123
+ "Input USD cost calculated from tokens and the effective rate.",
124
+ ],
125
+ cacheCost: [
126
+ "Custo USD da entrada em cache calculado com tokens e tarifa efetiva.",
127
+ "Cached-input USD cost calculated with tokens and the effective rate.",
128
+ ],
129
+ outputCost: [
130
+ "Custo USD de saída calculado com tokens e tarifa efetiva.",
131
+ "Output USD cost calculated with tokens and the effective rate.",
132
+ ],
133
+ reasoningCost: [
134
+ "Custo USD de raciocínio calculado com tokens e tarifa efetiva.",
135
+ "Reasoning USD cost calculated with tokens and the effective rate.",
136
+ ],
137
+ standardCost: [
138
+ "Custo USD no cenário Standard, antes do acréscimo de velocidade.",
139
+ "USD cost in the Standard scenario, before the speed uplift.",
140
+ ],
141
+ speedUplift: [
142
+ "Acréscimo USD do cenário Priority/Fast, já incluído no custo efetivo.",
143
+ "USD uplift from the Priority/Fast scenario, already included in the effective cost.",
144
+ ],
145
+ finalUsd: [
146
+ "Custo final estimado da API em USD, somando os componentes de custo desta invocação.",
147
+ "Estimated final API cost in USD, summing this invocation's cost components.",
148
+ ],
149
+ fxRate: [
150
+ "Câmbio BRL/USD atual aplicado para converter o custo final atual.",
151
+ "Current BRL/USD exchange rate used to convert the current final cost.",
152
+ ],
153
+ recordedFxRate: [
154
+ "Câmbio BRL/USD registrado no período da atividade.",
155
+ "BRL/USD exchange rate recorded for the activity period.",
156
+ ],
157
+ recordedBrl: [
158
+ "Custo final BRL registrado no período, preservado para auditoria histórica.",
159
+ "Final BRL cost recorded in the period, retained for historical audit.",
160
+ ],
161
+ cost: [
162
+ "Custo final atual: USD estimado ou sua conversão BRL pelo câmbio atual selecionado.",
163
+ "Current final cost: estimated USD or its BRL conversion at the selected current exchange rate.",
164
+ ],
165
+ };
166
+ const detail = details[metric] ?? [
167
+ "Métrica numérica desta invocação.",
168
+ "Numeric metric for this invocation.",
169
+ ];
170
+ return `${detail[locale === "pt-BR" ? 0 : 1]} ${source}`;
171
+ }
172
+
173
+ export function formatDurationCoverage(value: DurationCoverage, locale: CostLocale): string {
174
+ if (value.known_sum <= 0 && !value.complete)
175
+ return locale === "pt-BR" ? "Indisponível" : "Unavailable";
176
+ return value.known_sum <= 0 ? "0" : formatDurationMs(value.known_sum, locale);
177
+ }
178
+
179
+ export function hasKnownDuration(value: DurationCoverage): boolean {
180
+ return value.known_sum > 0 || value.coverage_ratio > 0;
181
+ }
182
+
183
+ export function formatTokenBackedDuration(
184
+ value: DurationCoverage,
185
+ _totalTokens: number | null,
186
+ locale: CostLocale,
187
+ ): string {
188
+ return formatDurationCoverage(value, locale);
189
+ }
190
+
191
+ export function costRunsFooterLabel(locale: CostLocale, pageOnly: boolean): string {
192
+ if (!pageOnly) return "Total";
193
+ return locale === "pt-BR" ? "Subtotal da página" : "Page subtotal";
194
+ }
195
+
196
+ export function sortCostValue(
197
+ currency: CostCurrency,
198
+ brl: number | null,
199
+ usd: number | null,
200
+ ): number | null {
201
+ return currency === "BRL" ? brl : usd;
202
+ }
203
+
204
+ export function runOriginBadge(row: Pick<CostRunRow, "prd_id" | "spec_id" | "task_id">): {
205
+ label: "PRD" | "SPEC" | "Tarefa avulsa";
206
+ tone: "prd" | "spec" | "task";
207
+ } {
208
+ if (row.prd_id !== null) return { label: "PRD", tone: "prd" };
209
+ if (row.spec_id !== null) return { label: "SPEC", tone: "spec" };
210
+ return { label: "Tarefa avulsa", tone: "task" };
211
+ }