@zaip-ai/cli 1.0.7 → 1.0.8

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 (410) hide show
  1. package/README.md +6 -4
  2. package/dist/services/adapters.d.ts +1 -1
  3. package/dist/services/adapters.d.ts.map +1 -1
  4. package/dist/services/adapters.js +15 -5
  5. package/dist/services/adapters.js.map +1 -1
  6. package/dist/services/adapters.test.js +1 -1
  7. package/dist/services/agent-adapters.d.ts +9 -0
  8. package/dist/services/agent-adapters.d.ts.map +1 -1
  9. package/dist/services/agent-adapters.js +38 -3
  10. package/dist/services/agent-adapters.js.map +1 -1
  11. package/dist/services/agent-adapters.test.js +8 -1
  12. package/dist/services/agent-adapters.test.js.map +1 -1
  13. package/dist/services/codex-config-template.d.ts +2 -1
  14. package/dist/services/codex-config-template.d.ts.map +1 -1
  15. package/dist/services/codex-config-template.js +13 -2
  16. package/dist/services/codex-config-template.js.map +1 -1
  17. package/dist/services/codex-rules.d.ts +1 -1
  18. package/dist/services/codex-rules.d.ts.map +1 -1
  19. package/dist/services/codex-rules.js +31 -7
  20. package/dist/services/codex-rules.js.map +1 -1
  21. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  22. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  23. package/dist/services/codex-subagent-hook-template.js +4 -1
  24. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  25. package/dist/services/doctor.d.ts.map +1 -1
  26. package/dist/services/doctor.js +3 -1
  27. package/dist/services/doctor.js.map +1 -1
  28. package/dist/services/global-codex-config.d.ts +6 -3
  29. package/dist/services/global-codex-config.d.ts.map +1 -1
  30. package/dist/services/global-codex-config.js +82 -13
  31. package/dist/services/global-codex-config.js.map +1 -1
  32. package/dist/services/global-codex-config.test.js +57 -10
  33. package/dist/services/global-codex-config.test.js.map +1 -1
  34. package/dist/services/install-agents-template.d.ts.map +1 -1
  35. package/dist/services/install-agents-template.js +15 -2
  36. package/dist/services/install-agents-template.js.map +1 -1
  37. package/dist/services/logger.js +1 -1
  38. package/dist/services/logger.js.map +1 -1
  39. package/dist/services/logger.test.js +3 -3
  40. package/dist/services/logger.test.js.map +1 -1
  41. package/dist/services/runtime-template.test.js +21 -5
  42. package/dist/services/runtime-template.test.js.map +1 -1
  43. package/dist/services/template-manifest.d.ts.map +1 -1
  44. package/dist/services/template-manifest.js +2 -0
  45. package/dist/services/template-manifest.js.map +1 -1
  46. package/package.json +1 -1
  47. package/templates/.agents/config/agents/catalog.yaml +310 -10
  48. package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +30 -0
  49. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +5 -5
  50. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
  51. package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +30 -0
  52. package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +30 -0
  53. package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +30 -0
  54. package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +8 -8
  55. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +5 -3
  56. package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +30 -0
  57. package/templates/.agents/config/project.yaml +1 -1
  58. package/templates/.agents/dashboard/.zaip-managed.json +659 -163
  59. package/templates/.agents/dashboard/DATA-DICTIONARY.md +2227 -0
  60. package/templates/.agents/dashboard/README.md +48 -97
  61. package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-Z60df2r-.js +1 -0
  62. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cv-JcoxP.js → DashboardHelpDialog-Cs6dzDmW.js} +294 -109
  63. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-Coc6pA-1.js +1 -0
  64. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +1 -0
  65. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +3 -0
  66. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +1 -0
  67. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-CaKwQP43.css +1 -0
  68. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +1 -0
  69. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +68 -0
  70. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-C98LGC-Q.js → dashboard-localization-CLJ0lT9v.js} +1 -1
  71. package/templates/.agents/dashboard/apps/frontend/dist/assets/icons-vendor-DFBuc_qp.js +1 -0
  72. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +2 -0
  73. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +1 -0
  74. package/templates/.agents/dashboard/apps/frontend/dist/assets/react-vendor-CCQOHdVI.js +9 -0
  75. package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-D9-fqq9M.js +1 -0
  76. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DFY7ZDlu.css +1 -0
  77. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-pC2_0J8x.js +1 -0
  78. package/templates/.agents/dashboard/apps/frontend/dist/index.html +9 -2
  79. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  80. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +952 -595
  81. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +48 -0
  82. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingPanels.tsx +2 -0
  83. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +247 -0
  84. package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +95 -0
  85. package/templates/.agents/dashboard/apps/frontend/src/AppSetupRoutes.tsx +87 -0
  86. package/templates/.agents/dashboard/apps/frontend/src/CostCalculationGuidePage.tsx +641 -0
  87. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +159 -0
  88. package/templates/.agents/dashboard/apps/frontend/src/DashboardCapabilityNav.tsx +13 -13
  89. package/templates/.agents/dashboard/apps/frontend/src/DashboardGlobalSettings.tsx +56 -0
  90. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +257 -313
  91. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +149 -0
  92. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +35 -0
  93. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +111 -12
  94. package/templates/.agents/dashboard/apps/frontend/src/app-preferences.ts +15 -0
  95. package/templates/.agents/dashboard/apps/frontend/src/app-session-token.ts +20 -0
  96. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.css +267 -0
  97. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.test.ts +69 -0
  98. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +70 -0
  99. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +111 -0
  100. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +432 -13
  101. package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +1 -1
  102. package/templates/.agents/dashboard/apps/frontend/src/main.tsx +1 -0
  103. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.test.ts +55 -0
  104. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.ts +36 -0
  105. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.test.ts +126 -0
  106. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.ts +181 -0
  107. package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +138 -0
  108. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +105 -0
  109. package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +6 -3
  110. package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +9 -5
  111. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +24 -0
  112. package/templates/.agents/dashboard/apps/frontend/src/period-transition-overlay.css +44 -0
  113. package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +121 -62
  114. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +471 -2
  115. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +84 -17
  116. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +44 -0
  117. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +196 -39
  118. package/templates/.agents/dashboard/apps/frontend/src/snapshot-notice.ts +15 -0
  119. package/templates/.agents/dashboard/apps/frontend/src/sqlite-cost-adapters.ts +26 -0
  120. package/templates/.agents/dashboard/apps/frontend/src/styles.css +14 -2
  121. package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +38 -2
  122. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +187 -0
  123. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +190 -0
  124. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +121 -0
  125. package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +398 -0
  126. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +141 -0
  127. package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +45 -0
  128. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +46 -0
  129. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +37 -0
  130. package/templates/.agents/dashboard/apps/frontend/vite.config.ts +55 -5
  131. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  132. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +47 -6
  133. package/templates/.agents/dashboard/modules/cost-monitor/src/duration-estimate.ts +13 -0
  134. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +64 -0
  135. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +275 -0
  136. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +100 -15
  137. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +131 -40
  138. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +137 -19
  139. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.test.ts +2 -0
  140. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +13 -10
  141. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +303 -0
  142. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +226 -6
  143. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +479 -402
  144. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostSummary.tsx +5 -13
  145. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +312 -72
  146. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +373 -321
  147. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +17 -0
  148. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +25 -6
  149. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +0 -2
  150. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-helpers.ts +17 -0
  151. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-responsive.css +6 -3
  152. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-row-filters.ts +123 -0
  153. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +8 -3
  154. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +32 -0
  155. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +52 -14
  156. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-presentation.ts +121 -0
  157. package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +3 -0
  158. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.test.ts +68 -0
  159. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +32 -5
  160. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +108 -0
  161. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +12 -0
  162. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +60 -0
  163. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +106 -0
  164. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.test.ts +2 -2
  165. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +5 -3
  166. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-pricing-fallback.test.ts +53 -0
  167. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.basics.test.ts +34 -0
  168. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +168 -137
  169. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +188 -29
  170. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +956 -0
  171. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +775 -0
  172. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +95 -0
  173. package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
  174. package/templates/.agents/dashboard/modules/cost-monitor/src/server/refactor-map-xr9l.json +61 -0
  175. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.test.ts +41 -0
  176. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.ts +55 -11
  177. package/templates/.agents/dashboard/modules/operations/package.json +2 -1
  178. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +182 -0
  179. package/templates/.agents/dashboard/modules/operations/src/duration-population.test.ts +63 -1
  180. package/templates/.agents/dashboard/modules/operations/src/duration-population.ts +60 -5
  181. package/templates/.agents/dashboard/modules/operations/src/react/EntityDetailsDialog.tsx +14 -3
  182. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.test.ts +44 -1
  183. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +325 -18
  184. package/templates/.agents/dashboard/modules/operations/src/react/MacroPlanningDialog.tsx +1 -0
  185. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.test.ts +9 -5
  186. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.tsx +2 -2
  187. package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +168 -0
  188. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +95 -6
  189. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +365 -14
  190. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +532 -131
  191. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +314 -358
  192. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +68 -0
  193. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +169 -0
  194. package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +51 -8
  195. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.test.tsx +32 -0
  196. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.tsx +62 -6
  197. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.test.ts +55 -0
  198. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.tsx +27 -19
  199. package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +99 -42
  200. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts +19 -0
  201. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +255 -34
  202. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +163 -8
  203. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +101 -68
  204. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.test.ts +72 -1
  205. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +78 -16
  206. package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +6 -4
  207. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +50 -1
  208. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +143 -9
  209. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +29 -4
  210. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog-content.css +49 -0
  211. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog.css +93 -50
  212. package/templates/.agents/dashboard/modules/operations/src/react/manual-work-priority.test.ts +82 -0
  213. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts +29 -2
  214. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.ts +22 -1
  215. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +77 -4
  216. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +65 -5
  217. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +54 -0
  218. package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +19 -0
  219. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +149 -12
  220. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +27 -0
  221. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +136 -0
  222. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.test.ts +160 -0
  223. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.ts +47 -0
  224. package/templates/.agents/dashboard/modules/operations/src/react/operations-query.ts +10 -0
  225. package/templates/.agents/dashboard/modules/operations/src/react/operations-responsive.css +3 -0
  226. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-labels.ts +28 -0
  227. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +24 -7
  228. package/templates/.agents/dashboard/modules/operations/src/react/operations.css +42 -0
  229. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.test.ts +54 -0
  230. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.ts +32 -0
  231. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +165 -6
  232. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +148 -6
  233. package/templates/.agents/dashboard/modules/operations/src/react/popup-localization.test.ts +1 -1
  234. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css +132 -0
  235. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css.test.ts +13 -0
  236. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.header.test.ts +16 -0
  237. package/templates/.agents/dashboard/modules/operations/src/react/use-infinite-column.ts +11 -5
  238. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +5 -3
  239. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +4 -83
  240. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.test.ts +291 -15
  241. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.ts +182 -472
  242. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.test.ts +40 -0
  243. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.ts +19 -6
  244. package/templates/.agents/dashboard/modules/operations/src/server/canonical-run-projection.ts +31 -6
  245. package/templates/.agents/dashboard/modules/operations/src/server/daily-duration-projection.ts +220 -0
  246. package/templates/.agents/dashboard/modules/operations/src/server/execution-duration-projection.ts +28 -0
  247. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +27 -2
  248. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +22 -13
  249. package/templates/.agents/dashboard/modules/operations/src/server/filter.test.ts +3 -3
  250. package/templates/.agents/dashboard/modules/operations/src/server/filter.ts +7 -2
  251. package/templates/.agents/dashboard/modules/operations/src/server/index.ts +3 -0
  252. package/templates/.agents/dashboard/modules/operations/src/server/macro.ts +3 -12
  253. package/templates/.agents/dashboard/modules/operations/src/server/manifest-usage.ts +65 -0
  254. package/templates/.agents/dashboard/modules/operations/src/server/operations-projection-aggregates.ts +297 -0
  255. package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +324 -0
  256. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.test.ts +505 -0
  257. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.ts +609 -0
  258. package/templates/.agents/dashboard/modules/operations/src/server/runs.ts +18 -19
  259. package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +76 -0
  260. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  261. package/templates/.agents/dashboard/modules/traceability/src/server/build-task-trace.ts +3 -1
  262. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  263. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  264. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  265. package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
  266. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  267. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +1756 -0
  268. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +1608 -0
  269. package/templates/.agents/dashboard/packages/local-runtime/package.json +8 -3
  270. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +12 -0
  271. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +83 -0
  272. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +28 -0
  273. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +262 -0
  274. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +41 -0
  275. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +105 -0
  276. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +1643 -107
  277. package/templates/.agents/dashboard/packages/local-runtime/src/agent-adapter-sync.ts +30 -0
  278. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.test.ts +3 -2
  279. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.ts +5 -0
  280. package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +72 -33
  281. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +335 -4
  282. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +392 -1
  283. package/templates/.agents/dashboard/packages/local-runtime/src/runtime.mjs +5 -5
  284. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +71 -0
  285. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +179 -0
  286. package/templates/.agents/dashboard/packages/local-runtime/src/server-cross-layer-parity.test.ts +245 -0
  287. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models-route.ts +64 -0
  288. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.test.ts +204 -0
  289. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.ts +194 -0
  290. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +163 -0
  291. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +354 -0
  292. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.test.ts +74 -0
  293. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +113 -0
  294. package/templates/.agents/dashboard/packages/local-runtime/src/server-overview.test.ts +68 -0
  295. package/templates/.agents/dashboard/packages/local-runtime/src/server-period.ts +47 -0
  296. package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +483 -0
  297. package/templates/.agents/dashboard/packages/local-runtime/src/server-settings.test.ts +5 -2
  298. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +163 -84
  299. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +145 -0
  300. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +551 -266
  301. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +1145 -308
  302. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.test.ts +53 -0
  303. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +708 -0
  304. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +2232 -0
  305. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +6151 -0
  306. package/templates/.agents/dashboard/packages/local-runtime/src/work-priority-contract.test.ts +33 -0
  307. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +41 -0
  308. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +210 -0
  309. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +437 -190
  310. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +299 -24
  311. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  312. package/templates/.agents/dashboard/packages/windows-launcher/LauncherVerificationBehaviorTests.cs +206 -0
  313. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +95 -8
  314. package/templates/.agents/dashboard/packages/windows-launcher/build-dashboard-launcher.ps1 +2 -2
  315. package/templates/.agents/dashboard/packages/windows-launcher/run-launcher-verification-tests.ps1 +22 -0
  316. package/templates/.agents/dashboard/read-model.dbml +2201 -0
  317. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  318. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +1 -1
  319. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +214 -41
  320. package/templates/.agents/dashboard/work-priority.json +34 -0
  321. package/templates/.agents/dashboard/zaip-dashboard-linux.sh +45 -0
  322. package/templates/.agents/dashboard/zaip-dashboard-mac.command +3 -0
  323. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  324. package/templates/.agents/design/.zaip-managed.json +3 -3
  325. package/templates/.agents/design/apps/catalog/package.json +1 -1
  326. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  327. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  328. package/templates/.agents/requirements/comparative-audit.md +1 -1
  329. package/templates/.agents/requirements/context-engine.md +1 -1
  330. package/templates/.agents/requirements/cost-observability.md +1 -1
  331. package/templates/.agents/requirements/dashboard-launch.md +24 -0
  332. package/templates/.agents/requirements/data-export.md +1 -1
  333. package/templates/.agents/requirements/design-system.md +1 -1
  334. package/templates/.agents/requirements/execution-engine.md +1 -1
  335. package/templates/.agents/requirements/kanban-dashboard.md +4 -3
  336. package/templates/.agents/requirements/model-orchestration.md +1 -1
  337. package/templates/.agents/requirements/public-distribution.md +9 -6
  338. package/templates/.agents/requirements/software-architecture.md +1 -1
  339. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  340. package/templates/.agents/requirements/work-lifecycle.md +9 -3
  341. package/templates/.agents/requirements/zaip-strategic-95.md +4 -4
  342. package/templates/.agents/rules/autonomy-decision.md +15 -0
  343. package/templates/.agents/rules/core.md +1 -1
  344. package/templates/.agents/rules/run-lifecycle-closure.md +1 -1
  345. package/templates/.agents/rules/specialist-routing.md +19 -0
  346. package/templates/.agents/rules/workflow.md +1 -1
  347. package/templates/.agents/runtime/VERSION +1 -1
  348. package/templates/.agents/runtime/bin/zaip.mjs +114 -64
  349. package/templates/.agents/runtime/checksums.sha256 +6 -4
  350. package/templates/.agents/runtime/manifest.json +3 -1
  351. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -0
  352. package/templates/.agents/runtime/provenance.json +11 -0
  353. package/templates/.agents/runtime/sbom.cdx.json +1929 -39
  354. package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
  355. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +15 -0
  356. package/templates/.agents/skills/zaip-skill-brand-governance/agents/openai.yaml +4 -0
  357. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +30 -0
  358. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +25 -0
  359. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/agents/openai.yaml +4 -0
  360. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/SKILL.md +18 -0
  361. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/agents/openai.yaml +6 -0
  362. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.mjs +71 -0
  363. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.test.mjs +60 -0
  364. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/scheduled-ready-queue-contract.test.mjs +111 -0
  365. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +2 -2
  366. package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +3 -1
  367. package/templates/.agents/skills/zaip-skill-general-operations/SKILL.md +12 -0
  368. package/templates/.agents/skills/zaip-skill-general-operations/agents/openai.yaml +4 -0
  369. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -7
  370. package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +2 -2
  371. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +11 -38
  372. package/templates/.agents/skills/zaip-skill-governance-compliance/SKILL.md +12 -0
  373. package/templates/.agents/skills/zaip-skill-governance-compliance/agents/openai.yaml +4 -0
  374. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +15 -0
  375. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/agents/openai.yaml +4 -0
  376. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/references/growth-revops-framework.md +25 -0
  377. package/templates/.agents/skills/zaip-skill-instalar-agendamento/SKILL.md +17 -0
  378. package/templates/.agents/skills/zaip-skill-instalar-agendamento/agents/openai.yaml +6 -0
  379. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +3 -3
  380. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +76 -27
  381. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +128 -24
  382. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +122 -4
  383. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +66 -19
  384. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +193 -7
  385. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +14 -0
  386. package/templates/.agents/skills/zaip-skill-sales-methodology/agents/openai.yaml +4 -0
  387. package/templates/.agents/skills/zaip-skill-sales-methodology/references/sales-process-framework.md +77 -0
  388. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +5 -0
  389. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +96 -0
  390. package/templates/.agents/skills/zaip-skill-sqlite-read-model/agents/openai.yaml +4 -0
  391. package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +18 -0
  392. package/templates/.agents/zaip-aios/INDEX.md +1 -0
  393. package/templates/.agents/zaip-aios/README.md +37 -8
  394. package/templates/.agents/zaip-aios/VERSION +1 -1
  395. package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +43 -6
  396. package/templates/.agents/zaip-aios/guides/10-seguranca.md +21 -7
  397. package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +32 -0
  398. package/templates/template-manifest.json +945 -214
  399. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-CLYIi7Vo.js +0 -1
  400. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-DTDNVQGX.css +0 -1
  401. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-CzEggcRb.js +0 -1
  402. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-05YKn6Z4.js +0 -3
  403. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-YO3yqtgV.css +0 -1
  404. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8AzCnl3a.js +0 -77
  405. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DdBYQ_8D.css +0 -1
  406. package/templates/.agents/dashboard/apps/frontend/src/AgentCatalogSettingsPage.tsx +0 -617
  407. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings-page.css +0 -660
  408. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings.test.ts +0 -249
  409. package/templates/.agents/dashboard/dashboard.config.json +0 -4
  410. package/templates/.agents/dashboard/zaip-dashboard.exe +0 -0
@@ -1,6 +1,12 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import type { CostGroupRow } from "../contracts.js";
3
- import { costChartsCopy, lastSevenDays, modelsWithObservedCost } from "./CostCharts.js";
3
+ import {
4
+ chartPhaseMetrics,
5
+ chartTokenMix,
6
+ costChartsCopy,
7
+ lastSevenDays,
8
+ modelsWithObservedCost,
9
+ } from "./CostCharts.js";
4
10
 
5
11
  describe("costChartsCopy", () => {
6
12
  it("provides complete English chart copy", () => {
@@ -16,10 +22,11 @@ describe("costChartsCopy", () => {
16
22
  tokenMix: "Token mix",
17
23
  phases: "PHASES",
18
24
  totalsByPhase: "Totals by phase",
19
- input: "Input",
20
- cache: "Cache",
21
- output: "Output",
25
+ inputWithoutCache: "Uncached input",
26
+ cachedInput: "Cached input",
27
+ visibleOutput: "Visible output",
22
28
  reasoning: "Reasoning",
29
+ total: "Total (input + output)",
23
30
  });
24
31
  });
25
32
 
@@ -31,33 +38,40 @@ describe("costChartsCopy", () => {
31
38
  composition: "COMPOSIÇÃO",
32
39
  tokenMix: "Mix de tokens",
33
40
  phases: "FASES",
34
- input: "Entrada",
35
- output: "Saída",
41
+ inputWithoutCache: "Input sem cache",
42
+ visibleOutput: "Output visível",
36
43
  reasoning: "Raciocínio",
44
+ total: "Total (input + output)",
37
45
  });
38
46
  });
39
47
  });
40
48
 
41
49
  describe("lastSevenDays", () => {
42
- it("returns today and the six preceding calendar days, filling missing costs with zero", () => {
50
+ it("uses the last daily buckets from the active interval", () => {
43
51
  const rows = [
44
52
  { key: "2026-07-10", estimated_brl: 12.5, estimated_usd: 2.3 },
45
53
  { key: "2026-07-15", estimated_brl: 8, estimated_usd: 1.5 },
46
54
  { key: "2026-07-08", estimated_brl: 99, estimated_usd: 18 },
47
55
  ] as CostGroupRow[];
48
56
 
49
- const result = lastSevenDays(rows, "BRL", new Date(2026, 6, 15, 12));
57
+ const result = lastSevenDays(rows, "BRL");
50
58
 
51
59
  expect(result.map((day) => day.key)).toEqual([
52
- "2026-07-09",
60
+ "2026-07-08",
53
61
  "2026-07-10",
54
- "2026-07-11",
55
- "2026-07-12",
56
- "2026-07-13",
57
- "2026-07-14",
58
62
  "2026-07-15",
59
63
  ]);
60
- expect(result.map((day) => day.value)).toEqual([0, 12.5, 0, 0, 0, 0, 8]);
64
+ expect(result.map((day) => day.value)).toEqual([99, 12.5, 8]);
65
+ });
66
+
67
+ it("keeps a present daily bucket with unavailable cost distinct from an absent day", () => {
68
+ const result = lastSevenDays(
69
+ [{ key: "2026-07-15", estimated_brl: null, estimated_usd: null }] as CostGroupRow[],
70
+ "BRL",
71
+ );
72
+
73
+ expect(result.at(-1)?.value).toBeNull();
74
+ expect(result).toHaveLength(1);
61
75
  });
62
76
  });
63
77
 
@@ -70,6 +84,77 @@ describe("modelsWithObservedCost", () => {
70
84
  ] as unknown as Parameters<typeof modelsWithObservedCost>[0];
71
85
 
72
86
  expect(modelsWithObservedCost(rows, "BRL").map((row) => row.key)).toEqual(["sol"]);
73
- expect(modelsWithObservedCost(rows, "USD").map((row) => row.key)).toEqual(["sol", "gpt-5"]);
87
+ expect(modelsWithObservedCost(rows, "USD").map((row) => row.key)).toEqual(["gpt-5", "sol"]);
74
88
  });
75
89
  });
90
+
91
+ describe("aggregate-only overview metrics", () => {
92
+ it("uses inclusive input/output totals for token mix and phases when the Run transport is intentionally empty", () => {
93
+ const usage = {
94
+ conversation: metric({ input: 10, cached_input: 1, output: 5, reasoning: 3, total: 15 }, 2),
95
+ planning: metric({ input: 20, cached_input: 2, output: 10, reasoning: 6, total: 30 }, 3),
96
+ execution: metric({ input: 30, cached_input: 3, output: 15, reasoning: 9, total: 45 }, 4, 12_000),
97
+ total: metric({ input: 60, cached_input: 6, output: 30, reasoning: 18, total: 90 }, 9),
98
+ };
99
+
100
+ expect(chartTokenMix([], usage, costChartsCopy("pt-BR")).map(([, value]) => value)).toEqual([
101
+ 54, 6, 12, 18, 90,
102
+ ]);
103
+ expect(chartPhaseMetrics("execution", [], usage, "BRL")).toEqual({
104
+ duration: 12_000,
105
+ tokens: 45,
106
+ cost: 4,
107
+ });
108
+ });
109
+
110
+ it("keeps observed duration zero distinct from unavailable aggregate duration", () => {
111
+ const base = {
112
+ conversation: metric({ input: 0, cached_input: 0, output: 0, reasoning: 0, total: 0 }, 0),
113
+ planning: metric({ input: 0, cached_input: 0, output: 0, reasoning: 0, total: 0 }, 0),
114
+ total: metric({ input: 0, cached_input: 0, output: 0, reasoning: 0, total: 0 }, 0),
115
+ };
116
+ expect(chartPhaseMetrics("execution", [], { ...base, execution: metric({ input: 0, cached_input: 0, output: 0, reasoning: 0, total: 0 }, 0, 0) }, "BRL").duration).toBe(0);
117
+ expect(chartPhaseMetrics("execution", [], { ...base, execution: metric({ input: 0, cached_input: 0, output: 0, reasoning: 0, total: 0 }, 0, null) }, "BRL").duration).toBeNull();
118
+ });
119
+
120
+ it("marks an invalid cached or reasoning subset unavailable without changing inclusive totals", () => {
121
+ const usage = {
122
+ total: metric({ input: 4, cached_input: 5, output: 6, reasoning: 7, total: 10 }, 1),
123
+ };
124
+ expect(chartTokenMix([], usage, costChartsCopy("en-US"))).toEqual([
125
+ ["Uncached input", null],
126
+ ["Cached input", null],
127
+ ["Visible output", null],
128
+ ["Reasoning", null],
129
+ ["Total (input + output)", 10],
130
+ ]);
131
+ });
132
+
133
+ it("preserves canonical output when a partial source total diverges", () => {
134
+ const usage = {
135
+ total: metric({ input: 400_000, cached_input: 390_000, output: 30_000, reasoning: 10_000, total: 445_099 }, 1),
136
+ };
137
+
138
+ expect(chartTokenMix([], usage, costChartsCopy("pt-BR")).map(([, value]) => value)).toEqual([
139
+ 10_000,
140
+ 390_000,
141
+ 20_000,
142
+ 10_000,
143
+ 430_000,
144
+ ]);
145
+ });
146
+ });
147
+
148
+ function metric(
149
+ tokens: { input: number; cached_input: number; output: number; reasoning: number; total: number },
150
+ brl: number,
151
+ duration_ms: number | null = null,
152
+ ) {
153
+ return {
154
+ events: 1,
155
+ duration_ms,
156
+ tokens,
157
+ cost: { usd: brl / 5, brl },
158
+ coverage: { events: 1, tokens: 1, usd: 1, brl: 1 },
159
+ };
160
+ }
@@ -1,3 +1,4 @@
1
+ import type { UsageProjection } from "@zaip-ai/dashboard-operations/contracts";
1
2
  import { formatCompactNumber, formatCurrency, formatDurationMs } from "@zaip-ai/dashboard-ui";
2
3
  import type { CostGroupRow, CostRunRow } from "../contracts.js";
3
4
  import type { CostCurrency, CostLocale } from "./cost-monitor-copy.js";
@@ -8,30 +9,32 @@ export function CostCharts({
8
9
  rows,
9
10
  daily,
10
11
  models,
12
+ summaryUsage,
11
13
  currency,
12
14
  locale,
13
15
  }: {
14
16
  rows: readonly CostRunRow[];
15
17
  daily: readonly CostGroupRow[];
16
18
  models: readonly CostGroupRow[];
19
+ /**
20
+ * The summary route intentionally omits historical Run rows, but retains
21
+ * complete usage totals by phase. Prefer those aggregates when supplied so
22
+ * an aggregate-only overview never presents them as empty data.
23
+ */
24
+ summaryUsage?: Pick<UsageProjection, "conversation" | "planning" | "execution" | "total">;
17
25
  currency: CostCurrency;
18
26
  locale: CostLocale;
19
27
  }) {
20
28
  const copy = costChartsCopy(locale);
21
- const tokenMix = [
22
- [copy.input, observed(rows.map((row) => row.input_tokens))],
23
- [copy.cache, observed(rows.map((row) => row.cached_input_tokens))],
24
- [copy.output, observed(rows.map((row) => row.output_tokens))],
25
- [copy.reasoning, observed(rows.map((row) => row.reasoning_tokens))],
26
- ] as const;
29
+ const tokenMix = chartTokenMix(rows, summaryUsage, copy);
27
30
  const availableModels = modelsWithObservedCost(models, currency);
28
31
  const maxModel = Math.max(1, ...availableModels.map((row) => cost(row, currency) ?? 0));
29
32
  const sevenDays = lastSevenDays(daily, currency);
30
- const maxDaily = Math.max(1, ...sevenDays.map((day) => day.value));
33
+ const maxDaily = Math.max(1, ...sevenDays.map((day) => day.value ?? 0));
31
34
  const trendPoints = sevenDays.map((day, index) => ({
32
35
  ...day,
33
36
  x: (index / (sevenDays.length - 1)) * 100,
34
- y: 82 - (day.value / maxDaily) * 58,
37
+ y: 82 - ((day.value ?? 0) / maxDaily) * 58,
35
38
  }));
36
39
  const points = trendPoints.map((point) => `${point.x},${point.y}`).join(" ");
37
40
  return (
@@ -73,7 +76,7 @@ export function CostCharts({
73
76
  key={point.key}
74
77
  style={{ left: `${point.x}%`, top: `${point.y}%` }}
75
78
  >
76
- {formatCurrency(point.value, currency, locale)}
79
+ {formatNullableCurrency(point.value, currency, locale)}
77
80
  </span>
78
81
  ))}
79
82
  </div>
@@ -102,7 +105,7 @@ export function CostCharts({
102
105
  }}
103
106
  />
104
107
  </i>
105
- <strong>{formatCurrency(cost(row, currency), currency, locale)}</strong>
108
+ <strong>{formatNullableCurrency(cost(row, currency), currency, locale)}</strong>
106
109
  </div>
107
110
  ))}
108
111
  </div>
@@ -119,7 +122,7 @@ export function CostCharts({
119
122
  <div key={label}>
120
123
  <i style={{ background: colors[index] }} />
121
124
  <span>{label}</span>
122
- <strong>{formatCompactNumber(value, locale)}</strong>
125
+ <strong>{formatNullableNumber(value, locale)}</strong>
123
126
  </div>
124
127
  ))}
125
128
  </div>
@@ -133,12 +136,7 @@ export function CostCharts({
133
136
  </header>
134
137
  <div className="phase-strip">
135
138
  {(["conversation", "planning", "execution"] as const).map((phase, index) => {
136
- const phaseRows = rows.filter((row) => row.phase === phase);
137
- const duration = observed(phaseRows.map((row) => row.duration_ms));
138
- const tokens = observed(phaseRows.map((row) => row.total_tokens));
139
- const phaseCost = observed(
140
- phaseRows.map((row) => (currency === "BRL" ? row.estimated_brl : row.estimated_usd)),
141
- );
139
+ const metrics = chartPhaseMetrics(phase, rows, summaryUsage, currency);
142
140
  return (
143
141
  <div key={phase}>
144
142
  <div className="phase-name">
@@ -148,15 +146,15 @@ export function CostCharts({
148
146
  <dl className="phase-metrics">
149
147
  <div>
150
148
  <dt>{locale === "pt-BR" ? "Tempo" : "Time"}</dt>
151
- <dd>{formatDurationMs(duration, locale)}</dd>
149
+ <dd>{formatNullableDuration(metrics.duration, locale)}</dd>
152
150
  </div>
153
151
  <div>
154
152
  <dt>Tokens</dt>
155
- <dd>{formatCompactNumber(tokens, locale)}</dd>
153
+ <dd>{formatNullableNumber(metrics.tokens, locale)}</dd>
156
154
  </div>
157
155
  <div>
158
156
  <dt>{locale === "pt-BR" ? "Custo" : "Cost"}</dt>
159
- <dd>{formatCurrency(phaseCost, currency, locale)}</dd>
157
+ <dd>{formatNullableCurrency(metrics.cost, currency, locale)}</dd>
160
158
  </div>
161
159
  </dl>
162
160
  </div>
@@ -168,6 +166,81 @@ export function CostCharts({
168
166
  );
169
167
  }
170
168
 
169
+ export function chartTokenMix(
170
+ rows: readonly CostRunRow[],
171
+ summaryUsage: Pick<UsageProjection, "total"> | undefined,
172
+ copy: Pick<ReturnType<typeof costChartsCopy>, "inputWithoutCache" | "cachedInput" | "visibleOutput" | "reasoning" | "total">,
173
+ ) {
174
+ const tokens = summaryUsage?.total.tokens;
175
+ const input = tokens?.input ?? observed(rows.map((row) => row.input_tokens));
176
+ const cachedInput = subsetTokenTotal(
177
+ tokens?.cached_input ?? observed(rows.map((row) => row.cached_input_tokens)),
178
+ input,
179
+ );
180
+ const output = tokens?.output ?? observed(rows.map((row) => row.output_tokens));
181
+ const reasoning = subsetTokenTotal(
182
+ tokens?.reasoning ?? observed(rows.map((row) => row.reasoning_tokens)),
183
+ output,
184
+ );
185
+ const total = inclusiveTokenTotal(
186
+ input,
187
+ output,
188
+ tokens?.total ?? observed(rows.map((row) => row.total_tokens)),
189
+ );
190
+ return [
191
+ // Cache is inside Input and reasoning is inside Output. The chart must
192
+ // show mutually exclusive remainders rather than overlapping totals.
193
+ [copy.inputWithoutCache, exclusiveTokenRemainder(input, cachedInput)],
194
+ [copy.cachedInput, cachedInput],
195
+ [copy.visibleOutput, exclusiveTokenRemainder(output, reasoning)],
196
+ [copy.reasoning, reasoning],
197
+ [copy.total, total],
198
+ ] as const;
199
+ }
200
+
201
+ export function chartPhaseMetrics(
202
+ phase: "conversation" | "planning" | "execution",
203
+ rows: readonly CostRunRow[],
204
+ summaryUsage: Pick<UsageProjection, "conversation" | "planning" | "execution"> | undefined,
205
+ currency: CostCurrency,
206
+ ) {
207
+ const phaseRows = rows.filter((row) => row.phase === phase);
208
+ const usage = summaryUsage?.[phase];
209
+ return {
210
+ // Aggregate-only data carries observed invocation duration by phase. It
211
+ // remains distinct from the canonical root-Run wall-clock duration.
212
+ duration:
213
+ usage?.duration_ms ??
214
+ observed(
215
+ phaseRows.map((row) =>
216
+ row.duration_provenance === "observed" ||
217
+ row.duration_provenance === "reconciled" ||
218
+ row.duration_provenance === "legacy_inferred"
219
+ ? row.duration_ms
220
+ : null,
221
+ ),
222
+ ),
223
+ tokens: usage?.tokens.total ?? observed(phaseRows.map((row) => row.total_tokens)),
224
+ cost:
225
+ (currency === "BRL" ? usage?.cost.brl : usage?.cost.usd) ??
226
+ observed(
227
+ phaseRows.map((row) => (currency === "BRL" ? row.estimated_brl : row.estimated_usd)),
228
+ ),
229
+ };
230
+ }
231
+
232
+ function formatNullableDuration(value: number | null, locale: CostLocale) {
233
+ return value === null || value === 0 ? "0" : formatDurationMs(value, locale);
234
+ }
235
+
236
+ function formatNullableNumber(value: number | null, locale: CostLocale) {
237
+ return formatCompactNumber(value ?? 0, locale);
238
+ }
239
+
240
+ function formatNullableCurrency(value: number | null, currency: CostCurrency, locale: CostLocale) {
241
+ return formatCurrency(value ?? 0, currency, locale);
242
+ }
243
+
171
244
  export function costChartsCopy(locale: CostLocale) {
172
245
  return locale === "pt-BR"
173
246
  ? {
@@ -182,10 +255,11 @@ export function costChartsCopy(locale: CostLocale) {
182
255
  tokenMix: "Mix de tokens",
183
256
  phases: "FASES",
184
257
  totalsByPhase: "Totais por fase",
185
- input: "Entrada",
186
- cache: "Cache",
187
- output: "Saída",
258
+ inputWithoutCache: "Input sem cache",
259
+ cachedInput: "Cache",
260
+ visibleOutput: "Output visível",
188
261
  reasoning: "Raciocínio",
262
+ total: "Total (input + output)",
189
263
  }
190
264
  : {
191
265
  analyticsView: "Analytics overview",
@@ -199,10 +273,11 @@ export function costChartsCopy(locale: CostLocale) {
199
273
  tokenMix: "Token mix",
200
274
  phases: "PHASES",
201
275
  totalsByPhase: "Totals by phase",
202
- input: "Input",
203
- cache: "Cache",
204
- output: "Output",
276
+ inputWithoutCache: "Uncached input",
277
+ cachedInput: "Cached input",
278
+ visibleOutput: "Visible output",
205
279
  reasoning: "Reasoning",
280
+ total: "Total (input + output)",
206
281
  };
207
282
  }
208
283
 
@@ -221,29 +296,45 @@ function cost(row: CostGroupRow, currency: CostCurrency) {
221
296
  }
222
297
 
223
298
  export function modelsWithObservedCost(models: readonly CostGroupRow[], currency: CostCurrency) {
224
- return models.filter((row) => cost(row, currency) !== null);
299
+ return models
300
+ .filter((row) => cost(row, currency) !== null)
301
+ .sort((left, right) => {
302
+ const difference = (cost(right, currency) ?? 0) - (cost(left, currency) ?? 0);
303
+ return difference !== 0 ? difference : left.key.localeCompare(right.key);
304
+ });
305
+ }
306
+
307
+ function subsetTokenTotal(subset: number | null, total: number | null): number | null {
308
+ if (subset === null || total === null || subset > total) return null;
309
+ return subset;
310
+ }
311
+
312
+ function exclusiveTokenRemainder(total: number | null, subset: number | null): number | null {
313
+ return total === null || subset === null ? null : total - subset;
314
+ }
315
+
316
+ function inclusiveTokenTotal(
317
+ input: number | null,
318
+ output: number | null,
319
+ reportedTotal: number | null,
320
+ ): number | null {
321
+ return input !== null && output !== null ? input + output : reportedTotal;
225
322
  }
226
323
 
227
324
  export function lastSevenDays(
228
325
  daily: readonly CostGroupRow[],
229
326
  currency: CostCurrency,
230
- now = new Date(),
231
327
  ) {
232
- const values = new Map(daily.map((row) => [row.key, cost(row, currency) ?? 0]));
233
- return Array.from({ length: 7 }, (_, index) => {
234
- const date = new Date(now.getFullYear(), now.getMonth(), now.getDate() - (6 - index));
235
- const key = localDateKey(date);
236
- return { date, key, value: values.get(key) ?? 0 };
328
+ const values = new Map(daily.map((row) => [row.key, cost(row, currency)]));
329
+ const buckets = [...values.keys()].sort().slice(-7);
330
+ return buckets.map((key) => {
331
+ const date = new Date(`${key}T12:00:00`);
332
+ // A missing calendar bucket is a real zero; a present bucket with missing
333
+ // financial telemetry remains unavailable rather than being coerced to zero.
334
+ return { date, key, value: values.get(key)! };
237
335
  });
238
336
  }
239
337
 
240
- function localDateKey(date: Date) {
241
- const year = date.getFullYear();
242
- const month = String(date.getMonth() + 1).padStart(2, "0");
243
- const day = String(date.getDate()).padStart(2, "0");
244
- return `${year}-${month}-${day}`;
245
- }
246
-
247
338
  function formatTrendDay(date: Date, locale: CostLocale) {
248
339
  return new Intl.DateTimeFormat(locale, {
249
340
  weekday: "short",
@@ -4,7 +4,8 @@ import type { CostMonitorProjection } from "../contracts.js";
4
4
  import type { CostCurrency, CostLocale } from "./cost-monitor-copy.js";
5
5
 
6
6
  export type CostPeriod = "all" | "7" | "30" | "90" | "month";
7
- export const defaultCostPeriod: CostPeriod = "all";
7
+ /** Cost Monitor opens on the current Sao Paulo month, matching Operations. */
8
+ export const defaultCostPeriod: CostPeriod = "month";
8
9
 
9
10
  export function costPeriodDateRange(
10
11
  period: CostPeriod,
@@ -38,6 +39,9 @@ export async function loadCostMonitorPeriod({
38
39
  fetcher?: typeof fetch;
39
40
  }): Promise<CostMonitorProjection> {
40
41
  const query = new URLSearchParams({ currency });
42
+ // Period and filter changes hydrate aggregate read models only. Entity
43
+ // detail is loaded through its dedicated bounded page route.
44
+ query.set("scope", "summary");
41
45
  if (from !== undefined) query.set("from", from);
42
46
  if (to !== undefined) query.set("to", to);
43
47
  if (filters) {
@@ -63,6 +67,123 @@ export async function loadCostMonitorPeriod({
63
67
  return (await response.json()) as CostMonitorProjection;
64
68
  }
65
69
 
70
+ /** Exact dimensional projection, requested only after a dimensional tab opens. */
71
+ export async function loadCostMonitorDetail({
72
+ currency,
73
+ filters,
74
+ from,
75
+ refresh,
76
+ to,
77
+ signal,
78
+ fetcher = fetch,
79
+ }: {
80
+ currency: CostCurrency;
81
+ filters?: CostFilterState;
82
+ from?: string;
83
+ refresh?: string | null;
84
+ to?: string;
85
+ signal?: AbortSignal;
86
+ fetcher?: typeof fetch;
87
+ }): Promise<CostMonitorProjection> {
88
+ const query = costMonitorQuery({
89
+ currency,
90
+ ...(filters === undefined ? {} : { filters }),
91
+ ...(from === undefined ? {} : { from }),
92
+ ...(refresh === undefined ? {} : { refresh }),
93
+ ...(to === undefined ? {} : { to }),
94
+ });
95
+ query.set("scope", "detail");
96
+ const response = await fetcher(`/api/v2/cost-monitor?${query.toString()}`, {
97
+ ...(signal === undefined ? {} : { signal }),
98
+ });
99
+ if (!response.ok)
100
+ throw new Error(
101
+ (await response.text()).trim() || `Cost Monitor detail request failed (${response.status})`,
102
+ );
103
+ return (await response.json()) as CostMonitorProjection;
104
+ }
105
+
106
+ export async function loadCostMonitorRunPage({
107
+ currency,
108
+ filters,
109
+ from,
110
+ offset,
111
+ refresh,
112
+ to,
113
+ signal,
114
+ fetcher = fetch,
115
+ }: {
116
+ currency: CostCurrency;
117
+ filters?: CostFilterState;
118
+ from?: string;
119
+ offset: number;
120
+ refresh?: string | null;
121
+ to?: string;
122
+ signal?: AbortSignal;
123
+ fetcher?: typeof fetch;
124
+ }): Promise<CostRunPage> {
125
+ const query = costMonitorQuery({
126
+ currency,
127
+ ...(filters === undefined ? {} : { filters }),
128
+ ...(from === undefined ? {} : { from }),
129
+ ...(refresh === undefined ? {} : { refresh }),
130
+ ...(to === undefined ? {} : { to }),
131
+ });
132
+ query.set("scope", "runs");
133
+ query.set("offset", String(Math.max(0, offset)));
134
+ query.set("limit", "100");
135
+ const response = await fetcher(`/api/v2/cost-monitor?${query.toString()}`, {
136
+ ...(signal === undefined ? {} : { signal }),
137
+ });
138
+ if (!response.ok) {
139
+ const detail = (await response.text()).trim();
140
+ throw new Error(detail || `Cost Monitor run page request failed (${response.status})`);
141
+ }
142
+ const payload = (await response.json()) as Pick<CostMonitorProjection, "runs" | "run_page">;
143
+ return {
144
+ page_only: true,
145
+ runs: payload.runs,
146
+ run_page: payload.run_page ?? { offset, limit: 100, total: null, has_more: false },
147
+ };
148
+ }
149
+
150
+ /** Complete contract for the incremental Run endpoint; it is not a summary projection. */
151
+ export interface CostRunPage {
152
+ page_only: true;
153
+ runs: CostMonitorProjection["runs"];
154
+ run_page: { offset: number; limit: number; total: number | null; has_more: boolean };
155
+ }
156
+
157
+ function costMonitorQuery({
158
+ currency,
159
+ filters,
160
+ from,
161
+ refresh,
162
+ to,
163
+ }: {
164
+ currency: CostCurrency;
165
+ filters?: CostFilterState;
166
+ from?: string;
167
+ refresh?: string | null;
168
+ to?: string;
169
+ }): URLSearchParams {
170
+ const query = new URLSearchParams({ currency });
171
+ if (from !== undefined) query.set("from", from);
172
+ if (to !== undefined) query.set("to", to);
173
+ if (filters) {
174
+ const manifestFilters = [
175
+ ["provider", filters.provider],
176
+ ["phase", filters.phase],
177
+ ["agent", filters.agent],
178
+ ["model", filters.model],
179
+ ["status", filters.status],
180
+ ] as const;
181
+ for (const [key, value] of manifestFilters) if (value) query.set(key, value);
182
+ }
183
+ if (refresh) query.set("refresh", refresh);
184
+ return query;
185
+ }
186
+
66
187
  export function useCostMonitorPeriod({
67
188
  currency,
68
189
  data,
@@ -91,10 +212,14 @@ export function useCostMonitorPeriod({
91
212
  const [periodLoading, setPeriodLoading] = useState(false);
92
213
  const [periodError, setPeriodError] = useState<string | null>(null);
93
214
  const initialDataRef = useRef(true);
215
+ const loadPeriodRef = useRef(loadPeriod);
216
+ loadPeriodRef.current = loadPeriod;
94
217
  const requestedRange =
95
218
  dateRange === undefined
96
219
  ? costPeriodDateRange(period)
97
220
  : { from: dateRange.start, to: dateRange.end };
221
+ const requestedFrom = requestedRange?.from;
222
+ const requestedTo = requestedRange?.to;
98
223
  const shouldFetch = shouldFetchCostPeriod({ filters, period, snapshotBacked });
99
224
  useEffect(() => {
100
225
  if (!shouldFetch) {
@@ -109,13 +234,16 @@ export function useCostMonitorPeriod({
109
234
  const controller = new AbortController();
110
235
  setPeriodLoading(true);
111
236
  setPeriodError(null);
112
- void loadPeriod({
113
- currency,
114
- filters,
115
- ...(requestedRange === undefined ? {} : { from: requestedRange.from, to: requestedRange.to }),
116
- refresh: lastUpdatedAt,
117
- signal: controller.signal,
118
- })
237
+ void loadPeriodRef
238
+ .current({
239
+ currency,
240
+ filters,
241
+ ...(requestedFrom === undefined || requestedTo === undefined
242
+ ? {}
243
+ : { from: requestedFrom, to: requestedTo }),
244
+ refresh: lastUpdatedAt,
245
+ signal: controller.signal,
246
+ })
119
247
  .then((nextPeriodData) => {
120
248
  if (controller.signal.aborted) return;
121
249
  setPeriodDataBase(data);
@@ -130,17 +258,7 @@ export function useCostMonitorPeriod({
130
258
  if (!controller.signal.aborted) setPeriodLoading(false);
131
259
  });
132
260
  return () => controller.abort();
133
- }, [
134
- currency,
135
- data,
136
- filters,
137
- lastUpdatedAt,
138
- loadPeriod,
139
- requestedRange?.from,
140
- requestedRange?.to,
141
- shouldFetch,
142
- requestedRange,
143
- ]);
261
+ }, [currency, data, filters, lastUpdatedAt, requestedFrom, requestedTo, shouldFetch]);
144
262
  return {
145
263
  activeData: activeCostPeriodData(data, periodData, periodDataBase),
146
264
  periodError,
@@ -46,6 +46,8 @@ describe("CostModelsAuditTable coverage", () => {
46
46
  expect(tables).not.toContain("Partial ·");
47
47
  expect(tables).not.toContain("durationCoverageDetail");
48
48
  expect(models).not.toContain("durationCoverageDetail");
49
+ expect(models).not.toContain("tempo observado");
50
+ expect(models).not.toContain("observed time");
49
51
  expect(models).toContain("aggregateDurationCoverage");
50
52
  });
51
53
  });