@zaip-ai/cli 1.0.7 → 1.3.0

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 (444) 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 +39 -4
  10. package/dist/services/agent-adapters.js.map +1 -1
  11. package/dist/services/agent-adapters.test.js +13 -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 +7 -0
  45. package/dist/services/template-manifest.js.map +1 -1
  46. package/package.json +1 -1
  47. package/templates/.agents/architecture/software-architecture.md +131 -0
  48. package/templates/.agents/branding/brandbook.docx +0 -0
  49. package/templates/.agents/branding/brandbook.md +60 -0
  50. package/templates/.agents/config/agents/catalog.yaml +310 -10
  51. package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +30 -0
  52. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +5 -5
  53. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +2 -2
  54. package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +30 -0
  55. package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +30 -0
  56. package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +30 -0
  57. package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +8 -8
  58. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +5 -3
  59. package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +30 -0
  60. package/templates/.agents/config/project.yaml +1 -1
  61. package/templates/.agents/dashboard/.tmp-run-list.json +254 -0
  62. package/templates/.agents/dashboard/.zaip-managed.json +775 -163
  63. package/templates/.agents/dashboard/DATA-DICTIONARY.md +2227 -0
  64. package/templates/.agents/dashboard/README.md +48 -97
  65. package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-DxR_pgSV.js +1 -0
  66. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-4jZLTWE_.js +2156 -0
  67. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-CKcsqb-r.js +1 -0
  68. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BomxqCBU.css +1 -0
  69. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-DmmJD2Th.js +3 -0
  70. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BwtitWa_.js +1 -0
  71. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-CaKwQP43.css +1 -0
  72. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +1 -0
  73. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-N5Csr0RP.js +68 -0
  74. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-C98LGC-Q.js → dashboard-localization-CLJ0lT9v.js} +1 -1
  75. package/templates/.agents/dashboard/apps/frontend/dist/assets/icons-vendor-C0fj2uU9.js +1 -0
  76. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-C4aIB1PV.js +2 -0
  77. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +1 -0
  78. package/templates/.agents/dashboard/apps/frontend/dist/assets/react-vendor-BEsJ-FYH.js +9 -0
  79. package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-D9-fqq9M.js +1 -0
  80. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-B6y6Gw12.js +1 -0
  81. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DFY7ZDlu.css +1 -0
  82. package/templates/.agents/dashboard/apps/frontend/dist/index.html +9 -2
  83. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  84. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +1129 -600
  85. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +48 -0
  86. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingPanels.tsx +2 -0
  87. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +247 -0
  88. package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +95 -0
  89. package/templates/.agents/dashboard/apps/frontend/src/AppSetupRoutes.tsx +87 -0
  90. package/templates/.agents/dashboard/apps/frontend/src/CostCalculationGuidePage.tsx +641 -0
  91. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +159 -0
  92. package/templates/.agents/dashboard/apps/frontend/src/DashboardCapabilityNav.tsx +13 -13
  93. package/templates/.agents/dashboard/apps/frontend/src/DashboardGlobalSettings.tsx +56 -0
  94. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +266 -315
  95. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +151 -0
  96. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +37 -0
  97. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +114 -12
  98. package/templates/.agents/dashboard/apps/frontend/src/app-preferences.ts +15 -0
  99. package/templates/.agents/dashboard/apps/frontend/src/app-session-token.ts +20 -0
  100. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.css +267 -0
  101. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.test.ts +69 -0
  102. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +85 -0
  103. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +133 -0
  104. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +453 -13
  105. package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +1 -1
  106. package/templates/.agents/dashboard/apps/frontend/src/main.tsx +1 -0
  107. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.test.ts +55 -0
  108. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.ts +36 -0
  109. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.test.ts +126 -0
  110. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.ts +181 -0
  111. package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +138 -0
  112. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +105 -0
  113. package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +6 -3
  114. package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +9 -5
  115. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +26 -0
  116. package/templates/.agents/dashboard/apps/frontend/src/period-transition-overlay.css +44 -0
  117. package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +121 -62
  118. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +482 -3
  119. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +84 -17
  120. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +78 -0
  121. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +234 -39
  122. package/templates/.agents/dashboard/apps/frontend/src/snapshot-notice.ts +15 -0
  123. package/templates/.agents/dashboard/apps/frontend/src/sqlite-cost-adapters.ts +26 -0
  124. package/templates/.agents/dashboard/apps/frontend/src/styles.css +14 -2
  125. package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +38 -2
  126. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +253 -0
  127. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +380 -0
  128. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +175 -0
  129. package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +395 -0
  130. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +141 -0
  131. package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +45 -0
  132. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +46 -0
  133. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +36 -0
  134. package/templates/.agents/dashboard/apps/frontend/vite.config.ts +58 -5
  135. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  136. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +47 -6
  137. package/templates/.agents/dashboard/modules/cost-monitor/src/duration-estimate.ts +13 -0
  138. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +134 -0
  139. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +290 -0
  140. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +133 -19
  141. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +134 -43
  142. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +137 -19
  143. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.test.ts +2 -0
  144. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +13 -10
  145. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +328 -0
  146. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +302 -6
  147. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +627 -400
  148. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostSummary.tsx +5 -13
  149. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +370 -72
  150. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +467 -326
  151. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +17 -0
  152. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +25 -6
  153. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +0 -2
  154. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-helpers.ts +17 -0
  155. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-responsive.css +6 -3
  156. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-row-filters.ts +123 -0
  157. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +8 -3
  158. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +32 -0
  159. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +55 -14
  160. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-presentation.ts +121 -0
  161. package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +3 -0
  162. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.test.ts +68 -0
  163. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +33 -5
  164. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +119 -0
  165. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +12 -0
  166. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +146 -0
  167. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +118 -0
  168. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.test.ts +2 -2
  169. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +5 -3
  170. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-pricing-fallback.test.ts +53 -0
  171. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.basics.test.ts +34 -0
  172. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +168 -161
  173. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +188 -29
  174. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +757 -0
  175. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +784 -0
  176. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +100 -0
  177. package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
  178. package/templates/.agents/dashboard/modules/cost-monitor/src/server/refactor-map-xr9l.json +61 -0
  179. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-monitor-projection-agents.test.ts +31 -0
  180. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-summary-projection-duration.test.ts +414 -0
  181. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.test.ts +41 -0
  182. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.ts +55 -11
  183. package/templates/.agents/dashboard/modules/operations/package.json +2 -1
  184. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +185 -0
  185. package/templates/.agents/dashboard/modules/operations/src/duration-population.test.ts +63 -1
  186. package/templates/.agents/dashboard/modules/operations/src/duration-population.ts +60 -5
  187. package/templates/.agents/dashboard/modules/operations/src/react/EntityDetailsDialog.tsx +14 -3
  188. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.test.ts +44 -1
  189. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +345 -18
  190. package/templates/.agents/dashboard/modules/operations/src/react/MacroPlanningDialog.tsx +1 -0
  191. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.test.ts +9 -5
  192. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.tsx +2 -2
  193. package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +168 -0
  194. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +95 -6
  195. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +367 -14
  196. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +562 -131
  197. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +353 -355
  198. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +65 -0
  199. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +169 -0
  200. package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +73 -8
  201. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.test.tsx +32 -0
  202. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.tsx +62 -6
  203. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.test.ts +55 -0
  204. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.tsx +27 -19
  205. package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +105 -42
  206. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts +19 -0
  207. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +265 -36
  208. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +171 -8
  209. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +98 -68
  210. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.test.ts +72 -1
  211. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +78 -17
  212. package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +6 -4
  213. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +431 -1
  214. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +574 -20
  215. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +42 -4
  216. package/templates/.agents/dashboard/modules/operations/src/react/export/xlsx-runtime-e2e.test.ts +248 -0
  217. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog-content.css +49 -0
  218. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog.css +93 -50
  219. package/templates/.agents/dashboard/modules/operations/src/react/manual-work-priority.test.ts +82 -0
  220. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts +29 -2
  221. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.ts +22 -1
  222. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +77 -4
  223. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +67 -5
  224. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +54 -0
  225. package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +22 -0
  226. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +149 -12
  227. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +27 -0
  228. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +176 -0
  229. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.test.ts +160 -0
  230. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.ts +47 -0
  231. package/templates/.agents/dashboard/modules/operations/src/react/operations-query.ts +10 -0
  232. package/templates/.agents/dashboard/modules/operations/src/react/operations-responsive.css +3 -0
  233. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-labels.ts +28 -0
  234. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +21 -7
  235. package/templates/.agents/dashboard/modules/operations/src/react/operations.css +42 -0
  236. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.test.ts +54 -0
  237. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.ts +32 -0
  238. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +241 -6
  239. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +148 -6
  240. package/templates/.agents/dashboard/modules/operations/src/react/popup-localization.test.ts +1 -1
  241. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css +132 -0
  242. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css.test.ts +13 -0
  243. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.header.test.ts +16 -0
  244. package/templates/.agents/dashboard/modules/operations/src/react/use-infinite-column.ts +11 -5
  245. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +7 -4
  246. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +5 -84
  247. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.test.ts +291 -15
  248. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.ts +182 -472
  249. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.test.ts +40 -0
  250. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.ts +19 -6
  251. package/templates/.agents/dashboard/modules/operations/src/server/canonical-run-projection.ts +31 -6
  252. package/templates/.agents/dashboard/modules/operations/src/server/daily-duration-projection.ts +220 -0
  253. package/templates/.agents/dashboard/modules/operations/src/server/execution-duration-projection.ts +28 -0
  254. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +39 -2
  255. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +25 -13
  256. package/templates/.agents/dashboard/modules/operations/src/server/filter.test.ts +3 -3
  257. package/templates/.agents/dashboard/modules/operations/src/server/filter.ts +7 -2
  258. package/templates/.agents/dashboard/modules/operations/src/server/index.ts +3 -0
  259. package/templates/.agents/dashboard/modules/operations/src/server/macro.ts +3 -12
  260. package/templates/.agents/dashboard/modules/operations/src/server/manifest-usage.ts +65 -0
  261. package/templates/.agents/dashboard/modules/operations/src/server/operations-projection-aggregates.ts +297 -0
  262. package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +330 -0
  263. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.test.ts +505 -0
  264. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.ts +609 -0
  265. package/templates/.agents/dashboard/modules/operations/src/server/runs.ts +18 -19
  266. package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +76 -0
  267. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  268. package/templates/.agents/dashboard/modules/traceability/src/server/build-task-trace.ts +3 -1
  269. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  270. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  271. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  272. package/templates/.agents/dashboard/packages/contracts/src/index.ts +2 -0
  273. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  274. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +1759 -0
  275. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs.metafile.json +7333 -0
  276. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +1611 -0
  277. package/templates/.agents/dashboard/packages/local-runtime/package.json +8 -3
  278. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +20 -0
  279. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +114 -0
  280. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +31 -0
  281. package/templates/.agents/dashboard/packages/local-runtime/scripts/source-size-runtime-scripts/sqlite-read-model-fixture.mjs +397 -0
  282. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +589 -0
  283. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +53 -0
  284. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +203 -0
  285. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +1646 -107
  286. package/templates/.agents/dashboard/packages/local-runtime/src/agent-adapter-sync.ts +30 -0
  287. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.test.ts +3 -2
  288. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.ts +5 -0
  289. package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +72 -33
  290. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +339 -4
  291. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +392 -1
  292. package/templates/.agents/dashboard/packages/local-runtime/src/runtime.mjs +5 -5
  293. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +110 -0
  294. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +189 -0
  295. package/templates/.agents/dashboard/packages/local-runtime/src/server-cross-layer-parity.test.ts +245 -0
  296. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models-route.ts +64 -0
  297. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.test.ts +204 -0
  298. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.ts +194 -0
  299. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +163 -0
  300. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +354 -0
  301. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.test.ts +74 -0
  302. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +113 -0
  303. package/templates/.agents/dashboard/packages/local-runtime/src/server-overview.test.ts +68 -0
  304. package/templates/.agents/dashboard/packages/local-runtime/src/server-period.ts +47 -0
  305. package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +483 -0
  306. package/templates/.agents/dashboard/packages/local-runtime/src/server-settings.test.ts +5 -2
  307. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +178 -84
  308. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +149 -0
  309. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +675 -267
  310. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +1212 -309
  311. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.test.ts +53 -0
  312. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +722 -0
  313. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +3743 -0
  314. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +7017 -0
  315. package/templates/.agents/dashboard/packages/local-runtime/src/work-priority-contract.test.ts +33 -0
  316. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +41 -0
  317. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +210 -0
  318. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +514 -190
  319. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +324 -24
  320. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  321. package/templates/.agents/dashboard/packages/windows-launcher/LauncherVerificationBehaviorTests.cs +206 -0
  322. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +95 -8
  323. package/templates/.agents/dashboard/packages/windows-launcher/build-dashboard-launcher.ps1 +2 -2
  324. package/templates/.agents/dashboard/packages/windows-launcher/run-launcher-verification-tests.ps1 +22 -0
  325. package/templates/.agents/dashboard/read-model.dbml +2201 -0
  326. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  327. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +1 -1
  328. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +216 -41
  329. package/templates/.agents/dashboard/work-priority.json +34 -0
  330. package/templates/.agents/dashboard/zaip-dashboard-linux.sh +45 -0
  331. package/templates/.agents/dashboard/zaip-dashboard-mac.command +3 -0
  332. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  333. package/templates/.agents/design/.zaip-managed.json +3 -3
  334. package/templates/.agents/design/apps/catalog/package.json +1 -1
  335. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  336. package/templates/.agents/growth/estrategia-bootstrap-90-dias.md +169 -0
  337. package/templates/.agents/growth/strategy.md +27 -0
  338. package/templates/.agents/marketing/estrategia-marketing-zaip-90-dias.md +197 -0
  339. package/templates/.agents/marketing/strategy.md +29 -0
  340. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  341. package/templates/.agents/requirements/comparative-audit.md +1 -1
  342. package/templates/.agents/requirements/context-engine.md +1 -1
  343. package/templates/.agents/requirements/cost-observability.md +1 -1
  344. package/templates/.agents/requirements/dashboard-launch.md +24 -0
  345. package/templates/.agents/requirements/data-export.md +1 -1
  346. package/templates/.agents/requirements/design-system.md +1 -1
  347. package/templates/.agents/requirements/execution-engine.md +1 -1
  348. package/templates/.agents/requirements/kanban-dashboard.md +4 -3
  349. package/templates/.agents/requirements/model-orchestration.md +1 -1
  350. package/templates/.agents/requirements/public-distribution.md +9 -6
  351. package/templates/.agents/requirements/software-architecture.md +1 -1
  352. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  353. package/templates/.agents/requirements/work-lifecycle.md +9 -3
  354. package/templates/.agents/requirements/zaip-strategic-95.md +4 -4
  355. package/templates/.agents/rules/autonomy-decision.md +15 -0
  356. package/templates/.agents/rules/core.md +1 -1
  357. package/templates/.agents/rules/run-lifecycle-closure.md +1 -1
  358. package/templates/.agents/rules/specialist-routing.md +19 -0
  359. package/templates/.agents/rules/workflow.md +1 -1
  360. package/templates/.agents/runtime/VERSION +1 -1
  361. package/templates/.agents/runtime/bin/zaip.mjs +118 -67
  362. package/templates/.agents/runtime/checksums.sha256 +6 -4
  363. package/templates/.agents/runtime/manifest.json +3 -1
  364. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -0
  365. package/templates/.agents/runtime/provenance.json +11 -0
  366. package/templates/.agents/runtime/sbom.cdx.json +1929 -39
  367. package/templates/.agents/sales/playbook.md +32 -0
  368. package/templates/.agents/sales/roteiro-comercial-zaip.md +252 -0
  369. package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
  370. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +22 -0
  371. package/templates/.agents/skills/zaip-skill-brand-governance/agents/openai.yaml +4 -0
  372. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-framework.md +39 -0
  373. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +30 -0
  374. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +25 -0
  375. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/agents/openai.yaml +4 -0
  376. package/templates/.agents/skills/zaip-skill-enforce-architecture/SKILL.md +2 -0
  377. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/SKILL.md +18 -0
  378. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/agents/openai.yaml +6 -0
  379. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.mjs +71 -0
  380. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.test.mjs +60 -0
  381. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/scheduled-ready-queue-contract.test.mjs +111 -0
  382. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +2 -2
  383. package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +3 -1
  384. package/templates/.agents/skills/zaip-skill-general-operations/SKILL.md +12 -0
  385. package/templates/.agents/skills/zaip-skill-general-operations/agents/openai.yaml +4 -0
  386. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -7
  387. package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +2 -2
  388. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +11 -38
  389. package/templates/.agents/skills/zaip-skill-governance-compliance/SKILL.md +12 -0
  390. package/templates/.agents/skills/zaip-skill-governance-compliance/agents/openai.yaml +4 -0
  391. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +21 -0
  392. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/agents/openai.yaml +4 -0
  393. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/references/growth-revops-framework.md +25 -0
  394. package/templates/.agents/skills/zaip-skill-instalar-agendamento/SKILL.md +17 -0
  395. package/templates/.agents/skills/zaip-skill-instalar-agendamento/agents/openai.yaml +6 -0
  396. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +9 -3
  397. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +99 -93
  398. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +132 -23
  399. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +149 -1
  400. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +76 -19
  401. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +217 -7
  402. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +77 -0
  403. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +20 -0
  404. package/templates/.agents/skills/zaip-skill-sales-methodology/agents/openai.yaml +4 -0
  405. package/templates/.agents/skills/zaip-skill-sales-methodology/references/sales-process-framework.md +77 -0
  406. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +5 -0
  407. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +96 -0
  408. package/templates/.agents/skills/zaip-skill-sqlite-read-model/agents/openai.yaml +4 -0
  409. package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +41 -0
  410. package/templates/.agents/zaip-aios/INDEX.md +11 -0
  411. package/templates/.agents/zaip-aios/README.md +38 -8
  412. package/templates/.agents/zaip-aios/VERSION +1 -1
  413. package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +43 -6
  414. package/templates/.agents/zaip-aios/guides/10-seguranca.md +21 -7
  415. package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +32 -0
  416. package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +76 -0
  417. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +72 -0
  418. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +330 -0
  419. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +52 -0
  420. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +69 -0
  421. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +483 -0
  422. package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +85 -0
  423. package/templates/.agents/zaip-aios/guides/25-fontes-de-precos-openai.md +18 -0
  424. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +44 -0
  425. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +167 -0
  426. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +144 -0
  427. package/templates/.agents/zaip-aios/guides/assets/diagrams/lifecycles-task-spec-prd.png +0 -0
  428. package/templates/.agents/zaip-aios/guides/assets/diagrams/prd-lifecycle.png +0 -0
  429. package/templates/.agents/zaip-aios/guides/assets/diagrams/spec-lifecycle.png +0 -0
  430. package/templates/.agents/zaip-aios/guides/assets/diagrams/task-lifecycle.png +0 -0
  431. package/templates/template-manifest.json +1082 -215
  432. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-CLYIi7Vo.js +0 -1
  433. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-DTDNVQGX.css +0 -1
  434. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-Cv-JcoxP.js +0 -1320
  435. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-CzEggcRb.js +0 -1
  436. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-05YKn6Z4.js +0 -3
  437. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-YO3yqtgV.css +0 -1
  438. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8AzCnl3a.js +0 -77
  439. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DdBYQ_8D.css +0 -1
  440. package/templates/.agents/dashboard/apps/frontend/src/AgentCatalogSettingsPage.tsx +0 -617
  441. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings-page.css +0 -660
  442. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings.test.ts +0 -249
  443. package/templates/.agents/dashboard/dashboard.config.json +0 -4
  444. package/templates/.agents/dashboard/zaip-dashboard.exe +0 -0
@@ -3,47 +3,59 @@ import {
3
3
  type RunProjection,
4
4
  saoPauloPeriodKey,
5
5
  } from "@zaip-ai/dashboard-operations/contracts";
6
- import {
7
- EntityDetailsDialog,
8
- ExcelExportAction,
9
- ExecutionTable,
10
- } from "@zaip-ai/dashboard-operations/react";
6
+ import { EntityDetailsDialog, ExcelExportAction } from "@zaip-ai/dashboard-operations/react";
11
7
  import { DashboardHeader } from "@zaip-ai/dashboard-ui";
12
- import { type ReactNode, useEffect, useMemo, useState } from "react";
8
+ import { type ReactNode, useEffect, useMemo, useRef, useState } from "react";
13
9
  import { includeConfiguredAgentGroups } from "../agent-groups.js";
14
- import {
15
- aggregateDurationCoverage,
16
- type CostGroupRow,
17
- type CostMonitorProjection,
18
- type CostRunRow,
19
- sumKnown,
20
- } from "../contracts.js";
10
+ import type { CostMonitorProjection } from "../contracts.js";
21
11
  import { normalizeCostProvider } from "../provider.js";
22
12
  import { aggregateTaskCostRows } from "../task-cost-groups.js";
23
- import { CostCharts } from "./CostCharts.js";
13
+ import { withTokenBackedCompactDuration } from "./CompactLifecycleCostTable.js";
24
14
  import {
25
15
  type CostFilterState,
26
16
  CostFilters,
27
17
  type CostPeriod,
18
+ costPeriodDateRange,
28
19
  defaultCostPeriod,
29
20
  emptyCostFilters,
21
+ loadCostMonitorDetail,
30
22
  loadCostMonitorPeriod,
23
+ type loadCostMonitorRunPage,
31
24
  useCostMonitorPeriod,
32
25
  } from "./CostFilters.js";
26
+ import { CostMonitorContent } from "./CostMonitorContent.js";
33
27
  import { ChevronDownIcon, ListFilterIcon, LocaleFlag, SettingsIcon } from "./CostMonitorIcons.js";
34
- import { CostPeriodAverageCards } from "./CostPeriodAverageCards.js";
35
28
  import { CostSummary } from "./CostSummary.js";
36
- import { CostGroupsTable, CostModelsAuditTable, CostRunsTable } from "./CostTables.js";
37
- import { durationContributors } from "./cost-duration.js";
29
+ import {
30
+ groupRows,
31
+ matches,
32
+ matchesGlobalFilters,
33
+ matchesPeriodEntity,
34
+ } from "./cost-monitor-row-filters.js";
35
+
36
+ export {
37
+ groupRows,
38
+ matchesGlobalFilters,
39
+ matchesPeriodEntity,
40
+ } from "./cost-monitor-row-filters.js";
41
+
38
42
  import {
39
43
  type CostCurrency,
40
44
  type CostLocale,
41
45
  costCopy,
42
46
  localeCurrency,
43
47
  } from "./cost-monitor-copy.js";
44
- import { applyLegacyPeriodGroups, summarizeCostRows } from "./cost-monitor-summary.js";
45
- import { MacroCostTable } from "./MacroCostTable.js";
48
+ import { findRunDetails, selectDimensionalCostRows } from "./cost-monitor-page-helpers.js";
49
+ import { summarizeCostRows } from "./cost-monitor-summary.js";
50
+ import { COST_VIEW_ORDER, type CostView, DEFAULT_COST_VIEW } from "./cost-monitor-views.js";
46
51
  import { enrichPeriodCostGroups } from "./period-cost-groups.js";
52
+ import {
53
+ compactReadModelKind,
54
+ type LoadCompactCostPage,
55
+ useCompactCostPage,
56
+ } from "./use-compact-cost-page.js";
57
+ import { type LoadCostGroupPage, useCostGroupPage } from "./use-cost-group-page.js";
58
+ import { useCostRunPage } from "./use-cost-run-page.js";
47
59
  import "./cost-monitor.css";
48
60
  import "./cost-monitor-responsive.css";
49
61
  import "./cost-run-origin.css";
@@ -51,43 +63,91 @@ import "./cost-monitor-embedded.css";
51
63
 
52
64
  const zaipLogoUrl = new URL("../../../../../config/src/logo_novo_azul.png", import.meta.url).href;
53
65
 
54
- export type CostView =
55
- | "overview"
56
- | "agentCalls"
57
- | "executions"
58
- | "conversations"
59
- | "tasks"
60
- | "prds"
61
- | "specs"
62
- | "providers"
63
- | "agents"
64
- | "models"
65
- | "daily"
66
- | "monthly"
67
- | "annual";
68
- export const DEFAULT_COST_VIEW: CostView = "daily";
69
- export const COST_VIEW_ORDER: readonly CostView[] = [
70
- "overview",
71
- "executions",
72
- "agentCalls",
73
- "agents",
74
- "models",
75
- "providers",
76
- "tasks",
77
- "specs",
78
- "prds",
79
- "conversations",
80
- "daily",
81
- "monthly",
82
- "annual",
83
- ];
84
- type AgentCallKind = "all" | "run" | "subrun";
85
- export function findRunDetails<T extends { id: string }>(
86
- runs: readonly T[],
87
- runId: string,
88
- ): T | null {
89
- return runs.find((run) => run.id === runId) ?? null;
66
+ export {
67
+ findRunDetails,
68
+ isCurrentCostRunPageGeneration,
69
+ selectDimensionalCostRows,
70
+ } from "./cost-monitor-page-helpers.js";
71
+ export {
72
+ COST_VIEW_ORDER,
73
+ type CostView,
74
+ DEFAULT_COST_VIEW,
75
+ } from "./cost-monitor-views.js";
76
+
77
+ export type { LoadCompactCostPage } from "./use-compact-cost-page.js";
78
+ export type { LoadCostGroupPage } from "./use-cost-group-page.js";
79
+ export type LoadCostMonitorDetail = typeof loadCostMonitorDetail;
80
+ export type LoadCostRunPage = typeof loadCostMonitorRunPage;
81
+
82
+ /** The overview is a summary surface, not an exportable table view. */
83
+ export function isCostViewExportEligible(view: CostView): boolean {
84
+ return view !== "overview";
85
+ }
86
+
87
+ /**
88
+ * The Cost period request filters Runs, while Operations is the global snapshot
89
+ * used for shared entity detail. Keep the Executions tab on that same active
90
+ * Run population instead of accidentally showing an unfiltered empty/stale
91
+ * Operations table.
92
+ */
93
+ export function visibleExecutionRows<T extends { id: string }>(
94
+ executions: readonly T[],
95
+ rows: readonly Pick<CostMonitorProjection["runs"][number], "execution_id">[],
96
+ ): T[] {
97
+ const visibleIds = new Set(
98
+ rows.flatMap((row) => (row.execution_id === null ? [] : [row.execution_id])),
99
+ );
100
+ return executions.filter((execution) => visibleIds.has(execution.id));
101
+ }
102
+
103
+ /** Only filters represented by the partial Runs endpoint may use page-only data. */
104
+ export function isServerCostRunPagingEligible(filters: CostFilterState, globalQuery = ""): boolean {
105
+ return (
106
+ (globalQuery === "" || filters.query === "") &&
107
+ filters.priority === "" &&
108
+ filters.risk === "" &&
109
+ filters.origin === "" &&
110
+ filters.workType === ""
111
+ );
112
+ }
113
+
114
+ /**
115
+ * The embedded default view is backed by the App's all-time atomic snapshot.
116
+ * Keep the group pager on that same population until a period, global date, or
117
+ * local Cost filter explicitly narrows it.
118
+ */
119
+ export function resolveCostGroupPageRange({
120
+ embedded,
121
+ globalDateRange,
122
+ hasLocalCostFilters,
123
+ period,
124
+ runPageRange,
125
+ }: {
126
+ embedded: boolean;
127
+ globalDateRange: { start: string; end: string } | undefined;
128
+ hasLocalCostFilters: boolean;
129
+ period: CostPeriod;
130
+ runPageRange: { from: string; to: string } | undefined;
131
+ }): { from: string; to: string } | undefined {
132
+ if (
133
+ embedded &&
134
+ globalDateRange === undefined &&
135
+ period === defaultCostPeriod &&
136
+ !hasLocalCostFilters
137
+ )
138
+ return undefined;
139
+ return runPageRange;
140
+ }
141
+
142
+ /**
143
+ * Compact lifecycle tables share the embedded all-time snapshot contract with
144
+ * the group pager. In particular, the default month control is a display
145
+ * choice on that surface, not a hidden bound for SPEC/PRD rows or XLSX.
146
+ */
147
+ export function resolveCompactCostPageRange(args: Parameters<typeof resolveCostGroupPageRange>[0]) {
148
+ return resolveCostGroupPageRange(args);
90
149
  }
150
+
91
151
  export function CostMonitorPage({
92
152
  capabilityNavigation,
93
153
  data,
@@ -97,10 +157,15 @@ export function CostMonitorPage({
97
157
  lastUpdatedAt,
98
158
  locale,
99
159
  loading,
160
+ onLoadingChange,
100
161
  onLocaleChange,
101
162
  onOpenTrace,
102
163
  onActiveDataChange,
103
164
  onRefresh,
165
+ loadDetail = loadCostMonitorDetail,
166
+ loadRunPage,
167
+ loadReadModelPage,
168
+ loadGroupPage,
104
169
  loadPeriod = loadCostMonitorPeriod,
105
170
  operations,
106
171
  repositoryName,
@@ -119,18 +184,30 @@ export function CostMonitorPage({
119
184
  lastUpdatedAt: string | null;
120
185
  locale: CostLocale;
121
186
  loading: boolean;
187
+ onLoadingChange?: (loading: boolean) => void;
122
188
  onLocaleChange: (locale: CostLocale) => void;
123
189
  onOpenTrace: (taskId: string) => void;
124
190
  onActiveDataChange?: (data: CostMonitorProjection) => void;
191
+ /**
192
+ * Retained for host compatibility. Cost views must use bounded summary or
193
+ * page routes; activating a tab never requests the historical detail blob.
194
+ */
195
+ onDetailDataRequest?: () => void;
125
196
  onRefresh: () => void;
197
+ loadDetail?: LoadCostMonitorDetail;
198
+ loadRunPage?: LoadCostRunPage;
199
+ loadReadModelPage?: LoadCompactCostPage;
200
+ loadGroupPage?: LoadCostGroupPage;
126
201
  loadPeriod?: typeof loadCostMonitorPeriod;
127
- operations?: Pick<OperationsProjection, "runs" | "specs" | "tasks" | "executions">;
202
+ operations?: Pick<
203
+ OperationsProjection,
204
+ "runs" | "specs" | "tasks" | "executions" | "evidences" | "validations" | "summary"
205
+ >;
128
206
  repositoryName?: string;
129
207
  currency?: CostCurrency;
130
208
  onCurrencyChange?: (currency: CostCurrency) => void;
131
209
  }) {
132
210
  const [view, setView] = useState<CostView>(DEFAULT_COST_VIEW);
133
- const [agentCallKind, setAgentCallKind] = useState<AgentCallKind>("all");
134
211
  const [filters, setFilters] = useState<CostFilterState>(emptyCostFilters);
135
212
  const [localCurrency, setLocalCurrency] = useState<CostCurrency>("BRL");
136
213
  const currency = controlledCurrency ?? localCurrency;
@@ -143,6 +220,12 @@ export function CostMonitorPage({
143
220
  const [localeOpen, setLocaleOpen] = useState(false);
144
221
  const [settingsOpen, setSettingsOpen] = useState(false);
145
222
  const [selectedRun, setSelectedRun] = useState<RunProjection | null>(null);
223
+ const [detailData, setDetailData] = useState<CostMonitorProjection | null>(null);
224
+ const [detailLoading, setDetailLoading] = useState(false);
225
+ const [detailError, setDetailError] = useState<string | null>(null);
226
+ const [detailAttempt, setDetailAttempt] = useState(0);
227
+ const loadDetailRef = useRef(loadDetail);
228
+ loadDetailRef.current = loadDetail;
146
229
  const text = costCopy[locale];
147
230
  const { activeData, periodError, periodLoading } = useCostMonitorPeriod({
148
231
  currency,
@@ -155,6 +238,104 @@ export function CostMonitorPage({
155
238
  snapshotBacked: embedded,
156
239
  });
157
240
  const hasLocalCostFilters = Object.values(filters).some((value) => value !== "");
241
+ const runPageRange =
242
+ globalFilters?.dateRange === undefined
243
+ ? costPeriodDateRange(period)
244
+ : { from: globalFilters.dateRange.start, to: globalFilters.dateRange.end };
245
+ const groupPageRange = resolveCostGroupPageRange({
246
+ embedded,
247
+ globalDateRange: globalFilters?.dateRange,
248
+ hasLocalCostFilters,
249
+ period,
250
+ runPageRange,
251
+ });
252
+ const compactPageRange = resolveCompactCostPageRange({
253
+ embedded,
254
+ globalDateRange: globalFilters?.dateRange,
255
+ hasLocalCostFilters,
256
+ period,
257
+ runPageRange,
258
+ });
259
+ const costGroupViewName = (
260
+ candidate: CostView,
261
+ ): "daily" | "monthly" | "annual" | "agents" | "models" | "providers" | null =>
262
+ candidate === "daily" ||
263
+ candidate === "monthly" ||
264
+ candidate === "annual" ||
265
+ candidate === "agents" ||
266
+ candidate === "models" ||
267
+ candidate === "providers"
268
+ ? candidate
269
+ : null;
270
+ const groupView = costGroupViewName(view);
271
+ const groupPageState = useCostGroupPage({
272
+ view: groupView ?? "daily",
273
+ ...(groupPageRange === undefined ? {} : { range: groupPageRange }),
274
+ globalQuery: globalFilters?.query ?? "",
275
+ filters,
276
+ ...(groupView === null ? {} : { load: loadGroupPage }),
277
+ });
278
+ const {
279
+ compactPageOffset,
280
+ setCompactPageOffset,
281
+ compactPage,
282
+ compactPageLoading,
283
+ compactPageError,
284
+ retryCompactPage,
285
+ } = useCompactCostPage({
286
+ view,
287
+ load: loadReadModelPage,
288
+ range: compactPageRange,
289
+ query: globalFilters?.query,
290
+ filters,
291
+ });
292
+ // Server pagination is safe only when every active Run filter is part of the
293
+ // endpoint contract. Unsupported local text/metadata filters retain the
294
+ // complete active snapshot so a page cannot omit matching Runs.
295
+ const serverPagingEligible = isServerCostRunPagingEligible(filters, globalFilters?.query ?? "");
296
+ const {
297
+ runPageOffset,
298
+ setRunPageOffset,
299
+ runPageData,
300
+ runPageLoading,
301
+ runPageError,
302
+ retryRunPage,
303
+ } = useCostRunPage({
304
+ view,
305
+ eligible: view === "agentCalls" && serverPagingEligible,
306
+ currency,
307
+ filters,
308
+ globalQuery: globalFilters?.query ?? "",
309
+ range: runPageRange,
310
+ refresh: lastUpdatedAt,
311
+ load: loadRunPage,
312
+ });
313
+ useEffect(
314
+ () =>
315
+ onLoadingChange?.(
316
+ loading ||
317
+ periodLoading ||
318
+ runPageLoading ||
319
+ groupPageState.loading ||
320
+ compactPageLoading ||
321
+ detailLoading,
322
+ ),
323
+ [
324
+ compactPageLoading,
325
+ detailLoading,
326
+ groupPageState.loading,
327
+ loading,
328
+ onLoadingChange,
329
+ periodLoading,
330
+ runPageLoading,
331
+ ],
332
+ );
333
+ // A global period/filter change deliberately unmounts this surface while it
334
+ // replaces the atomic Cost Monitor snapshot. Requests belonging to the old
335
+ // surface are aborted, so their normal completion path cannot clear the
336
+ // host-level loading gate. Always release that gate on unmount; the newly
337
+ // mounted surface will immediately assert its own loading state if needed.
338
+ useEffect(() => () => onLoadingChange?.(false), [onLoadingChange]);
158
339
  useEffect(() => {
159
340
  if (!hasLocalCostFilters) onActiveDataChange?.(activeData);
160
341
  }, [activeData, hasLocalCostFilters, onActiveDataChange]);
@@ -169,6 +350,59 @@ export function CostMonitorPage({
169
350
  .filter((row) => matches(row, filters) && matchesGlobalFilters(row, globalFilters))
170
351
  .sort((left, right) => right.started_at.localeCompare(left.started_at));
171
352
  }, [activeData.runs, filters, globalFilters]);
353
+ // Summary carries exact compact group aggregates. Full Run detail is only
354
+ // for an explicit trace, never a prerequisite for opening a Cost tab.
355
+ const needsDimensionalDetail = false;
356
+ const runPageFrom = runPageRange?.from;
357
+ const runPageTo = runPageRange?.to;
358
+ useEffect(() => {
359
+ void detailAttempt;
360
+ if (!needsDimensionalDetail) {
361
+ setDetailData(null);
362
+ setDetailLoading(false);
363
+ setDetailError(null);
364
+ return;
365
+ }
366
+ const controller = new AbortController();
367
+ setDetailData(null);
368
+ setDetailLoading(true);
369
+ setDetailError(null);
370
+ void loadDetailRef
371
+ .current({
372
+ currency,
373
+ filters,
374
+ ...(runPageFrom === undefined || runPageTo === undefined
375
+ ? {}
376
+ : { from: runPageFrom, to: runPageTo }),
377
+ refresh: lastUpdatedAt,
378
+ signal: controller.signal,
379
+ })
380
+ .then(setDetailData)
381
+ .catch((cause: unknown) => {
382
+ if (!controller.signal.aborted)
383
+ setDetailError(cause instanceof Error ? cause.message : String(cause));
384
+ })
385
+ .finally(() => {
386
+ if (!controller.signal.aborted) setDetailLoading(false);
387
+ });
388
+ return () => controller.abort();
389
+ }, [currency, detailAttempt, filters, lastUpdatedAt, runPageFrom, runPageTo]);
390
+ const pagedRunRows = useMemo(
391
+ () =>
392
+ (runPageData?.runs ?? []).filter(
393
+ (row) => matches(row, filters) && matchesGlobalFilters(row, globalFilters),
394
+ ),
395
+ [filters, globalFilters, runPageData?.runs],
396
+ );
397
+ const dimensionalRows = useMemo(
398
+ () =>
399
+ selectDimensionalCostRows(rows, detailData?.runs)
400
+ .filter((row) => matches(row, filters) && matchesGlobalFilters(row, globalFilters))
401
+ .sort((left, right) => right.started_at.localeCompare(left.started_at)),
402
+ [detailData?.runs, filters, globalFilters, rows],
403
+ );
404
+ const dimensionalDetailPending =
405
+ needsDimensionalDetail && detailData === null && detailError === null;
172
406
  const macroDetails = useMemo(() => {
173
407
  if (operations === undefined) return undefined;
174
408
  const visibleRunIds = new Set(rows.map((row) => row.run_id));
@@ -177,108 +411,310 @@ export function CostMonitorPage({
177
411
  runs: operations.runs.filter((run) => visibleRunIds.has(run.id)),
178
412
  };
179
413
  }, [operations, rows]);
180
- const visiblePrds = useMemo(
181
- () => activeData.prds.filter((prd) => matchesPeriodEntity(prd, globalFilters)),
182
- [activeData.prds, globalFilters],
183
- );
184
- const visibleSpecs = useMemo(
185
- () => activeData.specs.filter((spec) => matchesPeriodEntity(spec, globalFilters)),
186
- [activeData.specs, globalFilters],
187
- );
188
- const groups = useMemo(() => {
189
- const legacy =
190
- !hasLocalCostFilters &&
191
- (globalFilters === undefined ||
192
- (globalFilters.query === "" && globalFilters.datePreset === "all"))
193
- ? (activeData.legacy_effort_baseline ?? null)
194
- : null;
195
- const periodEntities = {
414
+ const periodEntities = useMemo(
415
+ () => ({
196
416
  prds: activeData.prds.filter((prd) => matchesPeriodEntity(prd, globalFilters)),
197
417
  specs: activeData.specs.filter((spec) => matchesPeriodEntity(spec, globalFilters)),
198
418
  tasks: (operations?.tasks ?? []).filter((task) => matchesPeriodEntity(task, globalFilters)),
199
- };
419
+ evidences: (operations?.evidences ?? []).filter((evidence) =>
420
+ matchesPeriodEntity({ created_at: evidence.observed_at }, globalFilters),
421
+ ),
422
+ validations: (operations?.validations ?? []).filter((validation) =>
423
+ matchesPeriodEntity({ created_at: validation.executed_at }, globalFilters),
424
+ ),
425
+ }),
426
+ [
427
+ activeData.prds,
428
+ activeData.specs,
429
+ globalFilters,
430
+ operations?.evidences,
431
+ operations?.tasks,
432
+ operations?.validations,
433
+ ],
434
+ );
435
+ const visiblePrds = periodEntities.prds;
436
+ const visibleSpecs = periodEntities.specs;
437
+ const useAggregateGroups =
438
+ activeData.aggregate_only === true && dimensionalRows.length === 0 && !hasLocalCostFilters;
439
+ const groups = useMemo(() => {
440
+ if (useAggregateGroups) return activeData.groups;
200
441
  return {
201
442
  conversations: groupRows(
202
- rows.filter((row) => row.phase === "conversation"),
443
+ dimensionalRows,
203
444
  (row) => row.conversation_id ?? row.task_title ?? row.run_id,
204
445
  undefined,
205
446
  "all_invocations",
206
447
  ),
207
- tasks: aggregateTaskCostRows(periodEntities.tasks, rows),
448
+ tasks: aggregateTaskCostRows(periodEntities.tasks, dimensionalRows),
208
449
  providers: groupRows(
209
- rows,
450
+ dimensionalRows,
210
451
  (row) => normalizeCostProvider(row.provider),
211
452
  undefined,
212
453
  "all_invocations",
213
454
  ),
214
455
  agents: includeConfiguredAgentGroups(
215
- groupRows(rows, (row) => row.agent_name),
456
+ groupRows(dimensionalRows, (row) => row.agent_name),
216
457
  activeData.configured_agents,
217
458
  ),
218
- models: groupRows(rows, (row) => row.model),
219
- daily: applyLegacyPeriodGroups(
220
- enrichPeriodCostGroups(
221
- groupRows(
222
- rows,
223
- (row) => saoPauloPeriodKey(row.started_at, "day") ?? row.started_at.slice(0, 10),
224
- ),
225
- periodEntities,
226
- "daily",
459
+ models: groupRows(dimensionalRows, (row) => row.model),
460
+ daily: enrichPeriodCostGroups(
461
+ groupRows(
462
+ rows,
463
+ (row) => {
464
+ const timestamp = row.finished_at ?? row.started_at;
465
+ return saoPauloPeriodKey(timestamp, "day") ?? timestamp.slice(0, 10);
466
+ },
467
+ undefined,
468
+ "all_invocations",
227
469
  ),
228
- rows,
229
- "day",
230
- legacy,
470
+ periodEntities,
471
+ "daily",
231
472
  ),
232
- monthly: applyLegacyPeriodGroups(
233
- enrichPeriodCostGroups(
234
- groupRows(
235
- rows,
236
- (row) => saoPauloPeriodKey(row.started_at, "month") ?? row.started_at.slice(0, 7),
237
- ),
238
- periodEntities,
239
- "monthly",
473
+ monthly: enrichPeriodCostGroups(
474
+ groupRows(
475
+ rows,
476
+ (row) => {
477
+ const timestamp = row.finished_at ?? row.started_at;
478
+ return saoPauloPeriodKey(timestamp, "month") ?? timestamp.slice(0, 7);
479
+ },
480
+ undefined,
481
+ "all_invocations",
240
482
  ),
241
- rows,
242
- "month",
243
- legacy,
483
+ periodEntities,
484
+ "monthly",
244
485
  ),
245
- annual: applyLegacyPeriodGroups(
246
- enrichPeriodCostGroups(
247
- groupRows(
248
- rows,
249
- (row) => saoPauloPeriodKey(row.started_at, "year") ?? row.started_at.slice(0, 4),
250
- ),
251
- periodEntities,
252
- "annual",
486
+ annual: enrichPeriodCostGroups(
487
+ groupRows(
488
+ rows,
489
+ (row) => {
490
+ const timestamp = row.finished_at ?? row.started_at;
491
+ return saoPauloPeriodKey(timestamp, "year") ?? timestamp.slice(0, 4);
492
+ },
493
+ undefined,
494
+ "all_invocations",
253
495
  ),
254
- rows,
255
- "year",
256
- legacy,
496
+ periodEntities,
497
+ "annual",
257
498
  ),
258
499
  };
259
500
  }, [
260
501
  activeData.configured_agents,
261
- activeData.prds,
262
- activeData.specs,
263
- globalFilters,
264
- operations?.tasks,
502
+ periodEntities,
503
+ dimensionalRows,
265
504
  rows,
266
- hasLocalCostFilters,
267
- activeData.legacy_effort_baseline,
505
+ useAggregateGroups,
506
+ activeData.groups,
268
507
  ]);
269
- const overview = summarizeCostRows(rows, activeData.overview);
508
+ const displayGroups = useMemo(
509
+ () =>
510
+ groupView === null
511
+ ? groups
512
+ : {
513
+ ...groups,
514
+ [groupView]:
515
+ groupPageState.page === null
516
+ ? []
517
+ : groupView === "agents"
518
+ ? includeConfiguredAgentGroups(
519
+ groupPageState.page.rows,
520
+ activeData.configured_agents,
521
+ )
522
+ : [...groupPageState.page.rows],
523
+ },
524
+ [activeData.configured_agents, groups, groupPageState.page, groupView],
525
+ );
526
+ const overview = useAggregateGroups
527
+ ? activeData.overview
528
+ : {
529
+ ...summarizeCostRows(rows, activeData.overview),
530
+ task_count: periodEntities.tasks.length,
531
+ };
532
+ const canonicalDurationTotal = groups.annual.reduce(
533
+ (total, row) => total + row.duration.known_sum,
534
+ 0,
535
+ );
536
+ // Model/provider rows intentionally omit untrusted dimensions. Their footer
537
+ // remains the canonical card population for the same filters, never the
538
+ // visible subset or its paginated SQLite total.
539
+ const cardMetrics = operations?.summary.overview_metrics;
540
+ const cardDurationTotal = cardMetrics ? cardMetrics.duration_ms : canonicalDurationTotal;
541
+ const summaryTotals = {
542
+ run_count: overview.run_count,
543
+ task_count: cardMetrics?.task_count ?? overview.task_count,
544
+ prd_count: cardMetrics?.prd_count ?? cardMetrics?.selected_counts?.prds ?? 0,
545
+ spec_count: cardMetrics?.spec_count ?? cardMetrics?.selected_counts?.specs ?? 0,
546
+ evidence_count: 0,
547
+ test_count: 0,
548
+ event_count: overview.event_count,
549
+ total_tokens: cardMetrics?.tokens ?? overview.total_tokens,
550
+ estimated_usd: overview.estimated_usd,
551
+ estimated_brl: cardMetrics?.cost_brl ?? overview.estimated_brl,
552
+ duration_ms: cardDurationTotal,
553
+ duration: {
554
+ known_sum: cardDurationTotal ?? 0,
555
+ unknown: cardDurationTotal === null ? 1 : 0,
556
+ complete: cardDurationTotal !== null,
557
+ coverage_ratio: cardDurationTotal === null ? 0 : 1,
558
+ },
559
+ };
560
+ const visibleExecutions = useMemo(
561
+ () => visibleExecutionRows(operations?.executions ?? [], rows),
562
+ [operations?.executions, rows],
563
+ );
564
+ const compactKind = compactReadModelKind(view);
565
+ const usingCompactPage = compactKind !== null && loadReadModelPage !== undefined;
270
566
  const exportRows = useMemo(() => {
271
- if (view === "executions") return operations?.executions ?? [];
567
+ if (usingCompactPage) return compactPage?.rows ?? [];
568
+ if (view === "executions") return visibleExecutions;
272
569
  if (view === "conversations") return groups.conversations;
273
570
  if (view === "tasks") return groups.tasks;
274
571
  if (view === "prds") return visiblePrds;
275
572
  if (view === "specs") return visibleSpecs;
276
573
  if (view === "providers" || view === "agents") return groups[view];
277
574
  if (view === "daily" || view === "monthly" || view === "annual") return groups[view];
278
- return view === "agentCalls" && agentCallKind !== "all"
279
- ? rows.filter((row) => row.run_kind === agentCallKind)
280
- : rows;
281
- }, [agentCallKind, groups, operations?.executions, rows, view, visiblePrds, visibleSpecs]);
575
+ return rows;
576
+ }, [
577
+ compactPage?.rows,
578
+ groups,
579
+ rows,
580
+ usingCompactPage,
581
+ view,
582
+ visibleExecutions,
583
+ visiblePrds,
584
+ visibleSpecs,
585
+ ]);
586
+ const compactExportSource =
587
+ usingCompactPage && compactKind !== null && loadReadModelPage !== undefined
588
+ ? {
589
+ prepare: async () => {
590
+ const firstPage = await loadReadModelPage({
591
+ kind: compactKind,
592
+ offset: 0,
593
+ limit: 50,
594
+ filters,
595
+ ...(compactPageRange === undefined ? {} : compactPageRange),
596
+ ...(globalFilters?.query ? { query: globalFilters.query } : {}),
597
+ });
598
+ return {
599
+ totalRows: firstPage.total,
600
+ pages: async function* () {
601
+ let page = firstPage;
602
+ const seen = new Set<string>();
603
+ while (true) {
604
+ const unique = page.rows
605
+ .filter((row) => {
606
+ if (seen.has(row.id)) return false;
607
+ seen.add(row.id);
608
+ return true;
609
+ })
610
+ .map(withTokenBackedCompactDuration);
611
+ if (unique.length > 0)
612
+ yield unique as unknown as readonly Record<string, unknown>[];
613
+ const nextOffset = page.offset + page.rows.length;
614
+ if (nextOffset >= page.total || !page.has_more) return;
615
+ page = await loadReadModelPage({
616
+ kind: compactKind,
617
+ offset: nextOffset,
618
+ limit: page.limit,
619
+ filters,
620
+ ...(compactPageRange === undefined ? {} : compactPageRange),
621
+ ...(globalFilters?.query ? { query: globalFilters.query } : {}),
622
+ });
623
+ }
624
+ },
625
+ };
626
+ },
627
+ }
628
+ : undefined;
629
+ const agentInvocationExportSource =
630
+ view === "agentCalls" && serverPagingEligible && loadRunPage !== undefined
631
+ ? {
632
+ prepare: async () => {
633
+ const effectiveFilters = {
634
+ ...filters,
635
+ query: filters.query || globalFilters?.query || "",
636
+ };
637
+ const firstPage = await loadRunPage({
638
+ currency,
639
+ filters: effectiveFilters,
640
+ ...(runPageRange === undefined ? {} : runPageRange),
641
+ offset: 0,
642
+ refresh: lastUpdatedAt,
643
+ });
644
+ const totalRows = firstPage.run_page.total ?? firstPage.runs.length;
645
+ return {
646
+ totalRows,
647
+ pages: async function* () {
648
+ let page = firstPage;
649
+ while (true) {
650
+ if (page.runs.length === 0) return;
651
+ yield page.runs as unknown as readonly Record<string, unknown>[];
652
+ const nextOffset = page.run_page.offset + page.runs.length;
653
+ if (
654
+ (page.run_page.total !== null && nextOffset >= page.run_page.total) ||
655
+ !page.run_page.has_more
656
+ )
657
+ return;
658
+ page = await loadRunPage({
659
+ currency,
660
+ filters: effectiveFilters,
661
+ ...(runPageRange === undefined ? {} : runPageRange),
662
+ offset: nextOffset,
663
+ refresh: lastUpdatedAt,
664
+ });
665
+ }
666
+ },
667
+ };
668
+ },
669
+ }
670
+ : undefined;
671
+ // Period views are paginated SQLite projections too. Exporting their
672
+ // already-rendered group rows truncates the workbook to the visible page
673
+ // (and can lose the projection's factual duration). Capture the same
674
+ // paged query used by the table so an All Time selection keeps its unbound
675
+ // range and every other selection retains its exact range and filters.
676
+ const costGroupExportSource =
677
+ (view === "daily" ||
678
+ view === "monthly" ||
679
+ view === "annual" ||
680
+ view === "agents" ||
681
+ view === "models" ||
682
+ view === "providers") &&
683
+ loadGroupPage !== undefined
684
+ ? {
685
+ prepare: async () => {
686
+ const query = filters.query || globalFilters?.query || "";
687
+ const firstPage = await loadGroupPage({
688
+ view,
689
+ offset: 0,
690
+ limit: 50,
691
+ filters,
692
+ ...(query ? { query } : {}),
693
+ ...(groupPageRange === undefined ? {} : groupPageRange),
694
+ });
695
+ return {
696
+ totalRows: firstPage.total_count,
697
+ pages: async function* () {
698
+ let page = firstPage;
699
+ while (true) {
700
+ if (page.rows.length === 0) return;
701
+ yield page.rows as unknown as readonly Record<string, unknown>[];
702
+ const nextOffset = page.offset + page.rows.length;
703
+ if (nextOffset >= page.total_count || !page.has_more) return;
704
+ page = await loadGroupPage({
705
+ view,
706
+ offset: nextOffset,
707
+ limit: page.limit,
708
+ filters,
709
+ ...(query ? { query } : {}),
710
+ ...(groupPageRange === undefined ? {} : groupPageRange),
711
+ });
712
+ }
713
+ },
714
+ };
715
+ },
716
+ }
717
+ : undefined;
282
718
  const changeLocale = (next: CostLocale) => {
283
719
  onLocaleChange(next);
284
720
  setCurrency(localeCurrency(next));
@@ -480,162 +916,80 @@ export function CostMonitorPage({
480
916
  {embedded ? null : (
481
917
  <>
482
918
  <CostSummary currency={currency} locale={locale} overview={overview} />
483
- <div className="cost-coverage-note">
484
- <span>.agents/records/lifecycle + telemetry manifests</span>
485
- <strong>
486
- {overview.coverage.tokens}/{overview.coverage.events} eventos com tokens ·{" "}
487
- {overview.coverage.brl}/{overview.coverage.events} com custo
488
- </strong>
489
- </div>
490
919
  {capabilityNavigation}
491
920
  </>
492
921
  )}
493
- <nav aria-label="Visões de custo" className="cost-tabs">
494
- {COST_VIEW_ORDER.map((key) => (
495
- <button
496
- className={view === key ? "is-active" : undefined}
497
- key={key}
498
- onClick={() => setView(key)}
499
- type="button"
500
- >
501
- {text.tabs[key]}
502
- </button>
503
- ))}
504
- <ExcelExportAction
505
- filters={{ ...filters, ...globalFilters, period, agentCallKind }}
506
- rows={exportRows as unknown as readonly Record<string, unknown>[]}
507
- view={`cost-${view}`}
508
- />
509
- </nav>
510
- <section
511
- className={`cost-content cost-content-${view} ${view === "overview" ? "cost-content-overview" : ""}`}
512
- >
513
- {view === "overview" ? (
514
- <CostCharts
515
- currency={currency}
516
- daily={groups.daily}
517
- locale={locale}
518
- models={groups.models}
519
- rows={rows}
520
- />
521
- ) : null}
522
- {view === "agentCalls" ? (
523
- <>
524
- <nav
525
- aria-label={locale === "pt-BR" ? "Tipo de chamada de agente" : "Agent call type"}
526
- className="cost-run-kind-toolbar"
527
- >
528
- {(["all", "run", "subrun"] as const).map((kind) => (
529
- <button
530
- aria-pressed={agentCallKind === kind}
531
- className={agentCallKind === kind ? "is-active" : undefined}
532
- key={kind}
533
- onClick={() => setAgentCallKind(kind)}
534
- type="button"
535
- >
536
- {kind === "all"
537
- ? locale === "pt-BR"
538
- ? "Todos"
539
- : "All"
540
- : kind === "run"
541
- ? locale === "pt-BR"
542
- ? "Invocações do orquestrador"
543
- : "Orchestrator invocations"
544
- : locale === "pt-BR"
545
- ? "Invocações delegadas"
546
- : "Delegated invocations"}
547
- </button>
548
- ))}
549
- </nav>
550
- <CostRunsTable
551
- currency={currency}
552
- locale={locale}
553
- onOpenRun={openRunDetails}
554
- rows={
555
- agentCallKind === "all"
556
- ? rows
557
- : rows.filter((row) => row.run_kind === agentCallKind)
558
- }
559
- />
560
- </>
561
- ) : null}
562
- {view === "executions" ? (
563
- <ExecutionTable locale={locale} rows={operations?.executions ?? []} />
564
- ) : null}
565
- {view === "conversations" ? (
566
- <CostGroupsTable
567
- currency={currency}
568
- labelHeading={locale === "pt-BR" ? "Conversa" : "Conversation"}
569
- locale={locale}
570
- rows={groups.conversations}
571
- />
572
- ) : null}
573
- {view === "tasks" ? (
574
- <CostGroupsTable
575
- currency={currency}
576
- dateHeading={locale === "pt-BR" ? "Criada em" : "Created at"}
577
- labelHeading={locale === "pt-BR" ? "Tarefa" : "Task"}
578
- locale={locale}
579
- onOpenTrace={onOpenTrace}
580
- rows={groups.tasks}
581
- />
582
- ) : null}
583
- {view === "prds" ? (
584
- <MacroCostTable
585
- currency={currency}
586
- locale={locale}
587
- onOpenTrace={onOpenTrace}
588
- rows={visiblePrds}
589
- {...(macroDetails ? { details: macroDetails } : {})}
590
- />
591
- ) : null}
592
- {view === "specs" ? (
593
- <MacroCostTable
594
- currency={currency}
595
- locale={locale}
596
- onOpenTrace={onOpenTrace}
597
- rows={visibleSpecs}
598
- {...(macroDetails ? { details: macroDetails } : {})}
599
- />
600
- ) : null}
601
- {view === "models" ? <CostModelsAuditTable locale={locale} rows={rows} /> : null}
602
- {(["providers", "agents"] as const).map((key) =>
603
- view === key ? (
604
- <CostGroupsTable
605
- currency={currency}
922
+ <div className="cost-tabs-bar">
923
+ <nav aria-label="Visões de custo" className="cost-tabs">
924
+ {COST_VIEW_ORDER.map((key) => (
925
+ <button
926
+ aria-pressed={view === key}
927
+ className={view === key ? "is-active" : undefined}
606
928
  key={key}
607
- labelHeading={
608
- key === "agents"
609
- ? locale === "pt-BR"
610
- ? "Zaip Agentes"
611
- : "ZAIP agents"
612
- : locale === "pt-BR"
613
- ? "Provedor"
614
- : "Providers"
929
+ onClick={() => {
930
+ setView(key);
931
+ }}
932
+ type="button"
933
+ >
934
+ {text.tabs[key]}
935
+ </button>
936
+ ))}
937
+ </nav>
938
+ {isCostViewExportEligible(view) ? (
939
+ <div className="cost-tab-export">
940
+ <ExcelExportAction
941
+ filters={{ ...filters, ...globalFilters, period }}
942
+ pageSource={
943
+ compactExportSource ?? agentInvocationExportSource ?? costGroupExportSource
615
944
  }
616
- locale={locale}
617
- rows={groups[key]}
618
- />
619
- ) : null,
620
- )}
621
- {view === "daily" || view === "monthly" || view === "annual" ? (
622
- <>
623
- <CostPeriodAverageCards
624
- currency={currency}
625
- locale={locale}
626
- period={view}
627
- rows={groups[view]}
945
+ rows={exportRows as unknown as readonly Record<string, unknown>[]}
946
+ view={`cost-${view}`}
628
947
  />
629
- <CostGroupsTable
630
- currency={currency}
631
- locale={locale}
632
- period={view}
633
- rows={groups[view]}
634
- showDateTime={false}
635
- />
636
- </>
948
+ </div>
637
949
  ) : null}
638
- </section>
950
+ </div>
951
+ {/* CostMonitorContent owns `view === "models" && useAggregateGroups ? (` and `rows={groups.models}`. */}
952
+ <CostMonitorContent
953
+ canonicalDurationTotal={canonicalDurationTotal}
954
+ compactPage={compactPage}
955
+ compactPageError={compactPageError}
956
+ compactPageLoading={compactPageLoading}
957
+ compactPageOffset={compactPageOffset}
958
+ currency={currency}
959
+ detailError={detailError}
960
+ detailLoading={detailLoading}
961
+ dimensionalDetailPending={dimensionalDetailPending}
962
+ dimensionalRows={dimensionalRows}
963
+ groups={displayGroups}
964
+ groupPage={groupView === null ? null : groupPageState.page}
965
+ groupPageLoading={groupView === null ? false : groupPageState.loading}
966
+ groupPageOffset={groupPageState.offset}
967
+ setGroupPageOffset={groupPageState.setOffset}
968
+ locale={locale}
969
+ macroDetails={macroDetails}
970
+ onOpenRun={openRunDetails}
971
+ onOpenTrace={onOpenTrace}
972
+ pagedRunRows={pagedRunRows}
973
+ retryCompactPage={retryCompactPage}
974
+ retryRunPage={retryRunPage}
975
+ rows={rows}
976
+ runPageData={runPageData}
977
+ runPageError={runPageError}
978
+ runPageLoading={runPageLoading}
979
+ runPageOffset={runPageOffset}
980
+ serverPagingEligible={serverPagingEligible}
981
+ setCompactPageOffset={setCompactPageOffset}
982
+ setDetailAttempt={setDetailAttempt}
983
+ setRunPageOffset={setRunPageOffset}
984
+ summaryUsage={activeData.usage}
985
+ summaryTotals={summaryTotals}
986
+ useAggregateGroups={useAggregateGroups}
987
+ usingCompactPage={usingCompactPage}
988
+ view={view}
989
+ visibleExecutions={visibleExecutions}
990
+ visiblePrds={visiblePrds}
991
+ visibleSpecs={visibleSpecs}
992
+ />
639
993
  {selectedRun ? (
640
994
  <EntityDetailsDialog
641
995
  details={{ kind: "run", row: selectedRun }}
@@ -646,130 +1000,3 @@ export function CostMonitorPage({
646
1000
  </Root>
647
1001
  );
648
1002
  }
649
-
650
- function matches(row: CostRunRow, filter: CostFilterState): boolean {
651
- const query = filter.query.trim().toLowerCase();
652
- return (
653
- (!query ||
654
- [row.run_id, row.task_title, row.model, row.requested_model, row.agent, row.agent_name].some(
655
- (value) => value.toLowerCase().includes(query),
656
- )) &&
657
- (!filter.provider || normalizeCostProvider(row.provider) === filter.provider) &&
658
- (!filter.agent || row.agent_name === filter.agent) &&
659
- (!filter.model || row.model === filter.model) &&
660
- (!filter.status || row.task_status === filter.status) &&
661
- (!filter.priority || row.priority === filter.priority) &&
662
- (!filter.risk || row.risk === filter.risk) &&
663
- (!filter.phase || row.phase === filter.phase) &&
664
- (!filter.origin || row.origin === filter.origin) &&
665
- (!filter.workType || row.work_type === filter.workType)
666
- );
667
- }
668
-
669
- export function matchesGlobalFilters(
670
- row: CostRunRow,
671
- filters: { query: string; dateRange?: { start: string; end: string } } | undefined,
672
- ): boolean {
673
- if (!filters) return true;
674
- const query = filters.query.trim().toLocaleLowerCase();
675
- if (filters.dateRange === undefined) {
676
- return (
677
- !query ||
678
- [
679
- row.run_id,
680
- row.task_id,
681
- row.task_title,
682
- row.provider,
683
- row.agent,
684
- row.agent_name,
685
- row.model,
686
- row.requested_model,
687
- row.phase,
688
- ].some((value) => value?.toLocaleLowerCase().includes(query))
689
- );
690
- }
691
- const startedDate = saoPauloPeriodKey(row.started_at, "day") ?? row.started_at.slice(0, 10);
692
- return (
693
- startedDate >= filters.dateRange.start &&
694
- startedDate <= filters.dateRange.end &&
695
- (!query ||
696
- [
697
- row.run_id,
698
- row.task_id,
699
- row.task_title,
700
- row.provider,
701
- row.agent,
702
- row.agent_name,
703
- row.model,
704
- row.requested_model,
705
- row.phase,
706
- ].some((value) => value?.toLocaleLowerCase().includes(query)))
707
- );
708
- }
709
-
710
- export function groupRows(
711
- rows: readonly CostRunRow[],
712
- select: (row: CostRunRow) => string,
713
- label: (row: CostRunRow) => string = select,
714
- durationScope: "root_execution" | "all_execution" | "all_invocations" = "all_invocations",
715
- ): CostGroupRow[] {
716
- const contributors = durationContributors(rows, durationScope);
717
- const groups = new Map<string, CostRunRow[]>();
718
- for (const row of rows) groups.set(select(row), [...(groups.get(select(row)) ?? []), row]);
719
- return [...groups]
720
- .map(([key, items]) => ({
721
- ...(() => {
722
- const duration = aggregateDurationCoverage(
723
- contributors.filter((candidate) => items.includes(candidate)),
724
- durationScope === "all_execution" ? "all_execution" : "all_invocations",
725
- );
726
- return { duration_ms: duration.complete ? duration.known_sum : null, duration };
727
- })(),
728
- key,
729
- label: label(items[0] as CostRunRow),
730
- latest_started_at: items.reduce(
731
- (latest, row) => (row.started_at > latest ? row.started_at : latest),
732
- items[0]?.started_at ?? "",
733
- ),
734
- run_count: items.length,
735
- task_count: new Set(items.flatMap((row) => (row.task_id ? [row.task_id] : []))).size,
736
- tasksActive: new Set(items.flatMap((row) => (row.task_id ? [row.task_id] : []))).size,
737
- taskDaysActive: new Set(items.flatMap((row) => (row.task_id ? [row.task_id] : []))).size,
738
- prd_count: 0,
739
- spec_count: 0,
740
- evidence_count: 0,
741
- test_count: 0,
742
- event_count: items.reduce((sum, row) => sum + row.event_count, 0),
743
- total_tokens: sumKnown(items.map((row) => row.total_tokens)),
744
- estimated_usd: sumKnown(items.map((row) => row.estimated_usd)),
745
- estimated_brl: sumKnown(items.map((row) => row.estimated_brl)),
746
- coverage: items.reduce(
747
- (sum, row) => ({
748
- events: sum.events + row.coverage.events,
749
- tokens: sum.tokens + row.coverage.tokens,
750
- usd: sum.usd + row.coverage.usd,
751
- brl: sum.brl + row.coverage.brl,
752
- }),
753
- { events: 0, tokens: 0, usd: 0, brl: 0 },
754
- ),
755
- }))
756
- .sort((a, b) => b.latest_started_at.localeCompare(a.latest_started_at));
757
- }
758
-
759
- export function matchesPeriodEntity(
760
- entity: { id?: string; title?: string; created_at: string | null },
761
- filters: { query: string; dateRange?: { start: string; end: string } } | undefined,
762
- ): boolean {
763
- if (filters === undefined) return true;
764
- const query = filters.query.trim().toLowerCase();
765
- if (
766
- query &&
767
- ![entity.id ?? "", entity.title ?? ""].some((value) => value.toLowerCase().includes(query))
768
- ) {
769
- return false;
770
- }
771
- if (filters.dateRange === undefined) return true;
772
- if (entity.created_at === null) return false;
773
- const date = saoPauloPeriodKey(entity.created_at, "day") ?? entity.created_at.slice(0, 10);
774
- return date >= filters.dateRange.start && date <= filters.dateRange.end;
775
- }