@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
@@ -6,7 +6,6 @@ import {
6
6
  } from "@zaip-ai/dashboard-ui";
7
7
  import type { CostGroupRow, CostRunRow, DurationCoverage } from "../contracts.js";
8
8
  import { MoreVerticalIcon } from "./CostTableIcons.js";
9
- import { durationContributors } from "./cost-duration.js";
10
9
  import type { CostCurrency, CostLocale } from "./cost-monitor-copy.js";
11
10
  import {
12
11
  agentRunModelPresentation,
@@ -14,8 +13,25 @@ import {
14
13
  localizedDescription,
15
14
  sumNumbers,
16
15
  } from "./cost-table-metrics.js";
16
+ import {
17
+ costGroupsScrollLabel,
18
+ costPeriodTotalAriaLabel,
19
+ costRunsDurationTotal,
20
+ costRunsScrollLabel,
21
+ formatBrlRate,
22
+ formatCostPeriodLabel,
23
+ formatDateTime,
24
+ formatMultiplierPair,
25
+ formatRate,
26
+ formatReasoningEffort,
27
+ formatServiceTier,
28
+ formatUsd,
29
+ isCompactRunColumnVisible,
30
+ } from "./cost-table-presentation.js";
31
+ import type { CostGroupTotals } from "./use-cost-group-page.js";
17
32
 
18
33
  export { CostModelsAuditTable } from "./CostModelsAuditTable.js";
34
+
19
35
  export {
20
36
  agentRunModelPresentation,
21
37
  contextUpliftUsd,
@@ -26,22 +42,37 @@ export {
26
42
  scenario,
27
43
  sumNumbers,
28
44
  } from "./cost-table-metrics.js";
45
+ export {
46
+ costGroupsScrollLabel,
47
+ costPeriodTotalAriaLabel,
48
+ costRunsDurationTotal,
49
+ costRunsScrollLabel,
50
+ formatBrlRate,
51
+ formatCostPeriodLabel,
52
+ formatDateTime,
53
+ formatMultiplierPair,
54
+ formatRate,
55
+ formatReasoningEffort,
56
+ formatServiceTier,
57
+ formatUsd,
58
+ isCompactRunColumnVisible,
59
+ } from "./cost-table-presentation.js";
29
60
 
30
- const unavailableMetricLabels: Readonly<Record<CostLocale, string>> = {
31
- "pt-BR": "Indisponível",
32
- "en-US": "Unavailable",
33
- };
34
- function unavailableMetricLabel(locale: CostLocale): string {
35
- return unavailableMetricLabels[locale];
61
+ export function displayCostGroupLabel(label: string, locale: CostLocale): string {
62
+ const normalized = label.trim().toLowerCase();
63
+ return normalized.length === 0 || normalized === "unknown"
64
+ ? locale === "pt-BR"
65
+ ? "Sem modelo/provedor atribuído"
66
+ : "No model/provider assigned"
67
+ : label;
36
68
  }
37
69
 
38
70
  export function formatAuditableNumber(value: number | null, locale: CostLocale): string {
39
- if (value === null) return unavailableMetricLabel(locale);
40
- return new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value);
71
+ return new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value ?? 0);
41
72
  }
42
73
 
43
74
  export function formatAuditableCompactNumber(value: number | null, locale: CostLocale): string {
44
- return value === null ? unavailableMetricLabel(locale) : formatCompactNumber(value, locale);
75
+ return formatCompactNumber(value ?? 0, locale);
45
76
  }
46
77
 
47
78
  export function formatAuditableCurrency(
@@ -49,16 +80,162 @@ export function formatAuditableCurrency(
49
80
  currency: CostCurrency,
50
81
  locale: CostLocale,
51
82
  ): string {
52
- return value === null ? unavailableMetricLabel(locale) : formatCurrency(value, currency, locale);
83
+ return formatCurrency(value ?? 0, currency, locale);
53
84
  }
54
85
 
55
86
  export function formatAuditableDuration(value: number | null, locale: CostLocale): string {
56
- return value === null ? unavailableMetricLabel(locale) : formatDurationMs(value, locale);
87
+ if (value === null) return locale === "pt-BR" ? "Indisponível" : "Unavailable";
88
+ return value === 0 ? "0" : formatDurationMs(value, locale);
89
+ }
90
+
91
+ const formatInvocationNumber = (value: number | null, locale: CostLocale) =>
92
+ formatAuditableNumber(value, locale);
93
+ const formatInvocationCurrency = (
94
+ value: number | null,
95
+ currency: CostCurrency,
96
+ locale: CostLocale,
97
+ ) => formatAuditableCurrency(value, currency, locale);
98
+ const formatInvocationDuration = (value: number | null, locale: CostLocale) =>
99
+ formatAuditableDuration(value, locale);
100
+ const formatInvocationRate = (value: number | null, locale: CostLocale) =>
101
+ formatRate(value, locale);
102
+ const formatInvocationUsd = (value: number | null, locale: CostLocale) => formatUsd(value, locale);
103
+ const formatInvocationBrlRate = (value: number | null, locale: CostLocale) =>
104
+ formatBrlRate(value, locale);
105
+ const formatInvocationMultiplierPair = (
106
+ input: number | null,
107
+ output: number | null,
108
+ locale: CostLocale,
109
+ ) => formatMultiplierPair(input, output, locale);
110
+
111
+ function invocationMetricDescription(locale: CostLocale, metric: string): string {
112
+ const source =
113
+ locale === "pt-BR"
114
+ ? "Valor da projeção SQLite/API desta Invocação de Agente. Fato canônico nulo permanece indisponível e não é convertido em zero."
115
+ : "Value from this Agent Invocation's SQLite/API projection. A null canonical fact remains unavailable and is not converted to zero.";
116
+ const details: Record<string, readonly [string, string]> = {
117
+ duration: [
118
+ "Tempo factual da invocação, quando capturado ou reconciliado.",
119
+ "Factual invocation duration, when captured or reconciled.",
120
+ ],
121
+ inputTokens: [
122
+ "Input total informado pela fonte; inclui a parcela de cache.",
123
+ "Source-reported total input; includes the cached portion.",
124
+ ],
125
+ cachedInputTokens: [
126
+ "Parcela de cache já incluída no input total.",
127
+ "Cached portion already included in total input.",
128
+ ],
129
+ outputTokens: [
130
+ "Output total informado pela fonte; inclui a parcela de raciocínio.",
131
+ "Source-reported total output; includes the reasoning portion.",
132
+ ],
133
+ reasoningTokens: [
134
+ "Parcela de raciocínio já incluída no output total.",
135
+ "Reasoning portion already included in total output.",
136
+ ],
137
+ totalTokens: [
138
+ "Soma de entrada e saída quando ambas são conhecidas; caso contrário, total informado pela fonte.",
139
+ "Input plus output when both are known; otherwise the source-reported total.",
140
+ ],
141
+ inputRate: [
142
+ "Tarifa efetiva de entrada em USD por milhão de tokens.",
143
+ "Effective input rate in USD per million tokens.",
144
+ ],
145
+ cacheRate: [
146
+ "Tarifa efetiva de entrada em cache em USD por milhão de tokens.",
147
+ "Effective cached-input rate in USD per million tokens.",
148
+ ],
149
+ outputRate: [
150
+ "Tarifa efetiva de saída em USD por milhão de tokens.",
151
+ "Effective output rate in USD per million tokens.",
152
+ ],
153
+ reasoningRate: [
154
+ "Tarifa efetiva de raciocínio em USD por milhão de tokens.",
155
+ "Effective reasoning rate in USD per million tokens.",
156
+ ],
157
+ contextMultiplier: [
158
+ "Multiplicadores de contexto de entrada/saída aplicados aos segmentos internos.",
159
+ "Input/output context multipliers applied to internal segments.",
160
+ ],
161
+ inputCost: [
162
+ "Custo USD de entrada calculado com tokens e tarifa efetiva.",
163
+ "Input USD cost calculated from tokens and the effective rate.",
164
+ ],
165
+ cacheCost: [
166
+ "Custo USD da entrada em cache calculado com tokens e tarifa efetiva.",
167
+ "Cached-input USD cost calculated from tokens and the effective rate.",
168
+ ],
169
+ outputCost: [
170
+ "Custo USD de saída calculado com tokens e tarifa efetiva.",
171
+ "Output USD cost calculated from tokens and the effective rate.",
172
+ ],
173
+ reasoningCost: [
174
+ "Custo USD de raciocínio calculado com tokens e tarifa efetiva.",
175
+ "Reasoning USD cost calculated from tokens and the effective rate.",
176
+ ],
177
+ standardCost: [
178
+ "Custo USD no cenário Standard, antes do acréscimo de velocidade.",
179
+ "USD cost in the Standard scenario, before the speed uplift.",
180
+ ],
181
+ speedUplift: [
182
+ "Acréscimo USD do cenário Priority/Fast, já incluído no custo efetivo.",
183
+ "USD uplift from the Priority/Fast scenario, already included in the effective cost.",
184
+ ],
185
+ finalUsd: [
186
+ "Custo final estimado da API em USD, somando os componentes de custo desta invocação.",
187
+ "Estimated final API cost in USD, summing this invocation's cost components.",
188
+ ],
189
+ fxRate: [
190
+ "Câmbio BRL/USD atual aplicado para converter o custo final atual.",
191
+ "Current BRL/USD exchange rate used to convert the current final cost.",
192
+ ],
193
+ recordedFxRate: [
194
+ "Câmbio BRL/USD registrado no período da atividade.",
195
+ "BRL/USD exchange rate recorded for the activity period.",
196
+ ],
197
+ recordedBrl: [
198
+ "Custo final BRL registrado no período, preservado para auditoria histórica.",
199
+ "Final BRL cost recorded in the period, retained for historical audit.",
200
+ ],
201
+ cost: [
202
+ "Custo final atual: USD estimado ou sua conversão BRL pelo câmbio atual selecionado.",
203
+ "Current final cost: estimated USD or its BRL conversion at the selected current exchange rate.",
204
+ ],
205
+ };
206
+ const detail = details[metric] ?? [
207
+ "Métrica numérica desta invocação.",
208
+ "Numeric metric for this invocation.",
209
+ ];
210
+ return `${detail[locale === "pt-BR" ? 0 : 1]} ${source}`;
57
211
  }
58
212
 
59
213
  export function formatDurationCoverage(value: DurationCoverage, locale: CostLocale): string {
60
- if (value.complete || value.coverage_ratio > 0) return formatDurationMs(value.known_sum, locale);
61
- return unavailableMetricLabel(locale);
214
+ // `known_sum` is a factual elapsed-time observation even when another
215
+ // activity in the population is unavailable. Keep completeness and the
216
+ // unknown count as coverage metadata; hiding the known portion would turn a
217
+ // true observation into an indistinguishable absence.
218
+ if (value.known_sum <= 0 && !value.complete)
219
+ return locale === "pt-BR" ? "Indisponível" : "Unavailable";
220
+ return value.known_sum <= 0 ? "0" : formatDurationMs(value.known_sum, locale);
221
+ }
222
+
223
+ export function hasKnownDuration(value: DurationCoverage): boolean {
224
+ return value.known_sum > 0 || value.coverage_ratio > 0;
225
+ }
226
+
227
+ export function formatTokenBackedDuration(
228
+ value: DurationCoverage,
229
+ _totalTokens: number | null,
230
+ locale: CostLocale,
231
+ ): string {
232
+ // Token presence is a financial observation, not evidence of elapsed time.
233
+ return formatDurationCoverage(value, locale);
234
+ }
235
+
236
+ export function costRunsFooterLabel(locale: CostLocale, pageOnly: boolean): string {
237
+ if (!pageOnly) return locale === "pt-BR" ? "Total" : "Total";
238
+ return locale === "pt-BR" ? "Subtotal da página" : "Page subtotal";
62
239
  }
63
240
 
64
241
  /** Keeps table ordering tied to the raw monetary value, not its localized label. */
@@ -85,25 +262,38 @@ export function CostRunsTable({
85
262
  currency,
86
263
  locale,
87
264
  compact = false,
265
+ pagination,
88
266
  }: {
89
267
  rows: readonly CostRunRow[];
90
268
  onOpenRun: (runId: string) => void;
91
269
  currency: CostCurrency;
92
270
  locale: CostLocale;
93
271
  compact?: boolean;
272
+ pagination?: {
273
+ offset: number;
274
+ limit: number;
275
+ total: number | null;
276
+ has_more: boolean;
277
+ loading: boolean;
278
+ error: string | null;
279
+ onChange: (offset: number) => void;
280
+ onRetry: () => void;
281
+ };
94
282
  }) {
283
+ const footerLabel = costRunsFooterLabel(locale, pagination !== undefined);
95
284
  const total = (key: keyof CostRunRow) => sumNumbers(rows.map((row) => row[key]));
285
+ const totalTokens = sumNumbers(rows.map(inclusiveTokenTotal));
96
286
  const durationTotal = costRunsDurationTotal(rows);
97
287
  const show = (select: (row: CostRunRow) => number | string | null) =>
98
288
  !compact || isCompactRunColumnVisible(rows, select);
99
- return (
289
+ const table = (
100
290
  <DataTable
101
291
  columns={[
102
292
  {
103
293
  key: "startedAt",
104
294
  label: locale === "pt-BR" ? "Data e hora" : "Date and time",
105
295
  render: (row) => formatDateTime(row.started_at, locale),
106
- footer: locale === "pt-BR" ? "Total" : "Total",
296
+ footer: footerLabel,
107
297
  },
108
298
  {
109
299
  key: "run",
@@ -129,20 +319,12 @@ export function CostRunsTable({
129
319
  },
130
320
  {
131
321
  key: "duration",
132
- label: locale === "pt-BR" ? "Tempo de execução" : "Execution time",
133
- render: (row) =>
134
- row.duration_provenance === "legacy_inferred" ? (
135
- <>
136
- <span>{formatAuditableDuration(row.duration_ms, locale)}</span>
137
- <small>{locale === "pt-BR" ? "Tempo inferido" : "Inferred time"}</small>
138
- </>
139
- ) : (
140
- formatAuditableDuration(row.duration_ms, locale)
141
- ),
322
+ label: locale === "pt-BR" ? "Tempo" : "Time",
323
+ description: invocationMetricDescription(locale, "duration"),
324
+ render: (row) => formatInvocationDuration(row.duration_ms, locale),
142
325
  sortValue: (row) => row.duration_ms,
143
326
  align: "right",
144
- footer: formatAuditableDuration(durationTotal, locale),
145
- hidden: !show((row) => row.duration_ms),
327
+ footer: formatInvocationDuration(durationTotal, locale),
146
328
  },
147
329
  {
148
330
  key: "agent",
@@ -182,120 +364,88 @@ export function CostRunsTable({
182
364
  },
183
365
  {
184
366
  key: "inputTokens",
185
- label: locale === "pt-BR" ? "Tokens entrada" : "Input tokens",
186
- render: (row) => formatAuditableNumber(row.input_tokens, locale),
367
+ label: locale === "pt-BR" ? "Input total" : "Total input",
368
+ description: invocationMetricDescription(locale, "inputTokens"),
369
+ render: (row) => formatInvocationNumber(row.input_tokens, locale),
187
370
  sortValue: (row) => row.input_tokens,
188
371
  align: "right",
189
- footer: formatAuditableNumber(total("input_tokens"), locale),
190
- hidden: !show((row) => row.input_tokens),
372
+ footer: formatInvocationNumber(total("input_tokens"), locale),
191
373
  },
192
374
  {
193
375
  key: "cachedInputTokens",
194
376
  label: locale === "pt-BR" ? "Tokens cache" : "Cached tokens",
195
- render: (row) => formatAuditableNumber(row.cached_input_tokens, locale),
377
+ description: invocationMetricDescription(locale, "cachedInputTokens"),
378
+ render: (row) => formatInvocationNumber(row.cached_input_tokens, locale),
196
379
  sortValue: (row) => row.cached_input_tokens,
197
380
  align: "right",
198
- footer: formatAuditableNumber(total("cached_input_tokens"), locale),
199
- hidden: !show((row) => row.cached_input_tokens),
200
- },
201
- {
202
- key: "uncachedInputTokens",
203
- label: locale === "pt-BR" ? "Entrada sem cache" : "Uncached input",
204
- render: (row) => formatAuditableNumber(row.uncached_input_tokens, locale),
205
- sortValue: (row) => row.uncached_input_tokens,
206
- align: "right",
207
- footer: formatAuditableNumber(total("uncached_input_tokens"), locale),
208
- hidden: !show((row) => row.uncached_input_tokens),
381
+ footer: formatInvocationNumber(total("cached_input_tokens"), locale),
209
382
  },
210
383
  {
211
384
  key: "outputTokens",
212
- label: locale === "pt-BR" ? "Tokens saída" : "Output tokens",
213
- render: (row) => formatAuditableNumber(row.output_tokens, locale),
385
+ label: locale === "pt-BR" ? "Output total" : "Total output",
386
+ description: invocationMetricDescription(locale, "outputTokens"),
387
+ render: (row) => formatInvocationNumber(row.output_tokens, locale),
214
388
  sortValue: (row) => row.output_tokens,
215
389
  align: "right",
216
- footer: formatAuditableNumber(total("output_tokens"), locale),
217
- hidden: !show((row) => row.output_tokens),
390
+ footer: formatInvocationNumber(total("output_tokens"), locale),
218
391
  },
219
392
  {
220
393
  key: "reasoningTokens",
221
394
  label: locale === "pt-BR" ? "Tokens raciocínio" : "Reasoning tokens",
222
- render: (row) => formatAuditableNumber(row.reasoning_tokens, locale),
395
+ description: invocationMetricDescription(locale, "reasoningTokens"),
396
+ render: (row) => formatInvocationNumber(row.reasoning_tokens, locale),
223
397
  sortValue: (row) => row.reasoning_tokens,
224
398
  align: "right",
225
- footer: formatAuditableNumber(total("reasoning_tokens"), locale),
226
- hidden: !show((row) => row.reasoning_tokens),
227
- },
228
- {
229
- key: "visibleOutputTokens",
230
- label: locale === "pt-BR" ? "Saída visível" : "Visible output",
231
- render: (row) => formatAuditableNumber(row.visible_output_tokens, locale),
232
- sortValue: (row) => row.visible_output_tokens,
233
- align: "right",
234
- footer: formatAuditableNumber(total("visible_output_tokens"), locale),
235
- hidden: !show((row) => row.visible_output_tokens),
399
+ footer: formatInvocationNumber(total("reasoning_tokens"), locale),
236
400
  },
237
401
  {
238
402
  key: "totalTokens",
239
403
  label: locale === "pt-BR" ? "Total tokens" : "Total tokens",
240
- render: (row) =>
241
- formatAuditableNumber(
242
- row.input_tokens !== null && row.output_tokens !== null
243
- ? row.input_tokens + row.output_tokens
244
- : row.total_tokens,
245
- locale,
246
- ),
247
- sortValue: (row) =>
248
- row.input_tokens !== null && row.output_tokens !== null
249
- ? row.input_tokens + row.output_tokens
250
- : row.total_tokens,
404
+ description: invocationMetricDescription(locale, "totalTokens"),
405
+ render: (row) => formatInvocationNumber(inclusiveTokenTotal(row), locale),
406
+ sortValue: (row) => inclusiveTokenTotal(row),
251
407
  align: "right",
252
- footer: formatAuditableNumber(total("total_tokens"), locale),
253
- hidden: !show((row) => row.total_tokens),
408
+ footer: formatInvocationNumber(totalTokens, locale),
254
409
  },
255
410
  {
256
411
  key: "inputRate",
257
412
  label: "USD/M entrada",
258
- render: (row) => formatRate(row.input_rate_usd_per_million, locale),
413
+ description: invocationMetricDescription(locale, "inputRate"),
414
+ render: (row) => formatInvocationRate(row.input_rate_usd_per_million, locale),
259
415
  align: "right",
260
- hidden: !show((row) => row.input_rate_usd_per_million),
261
416
  },
262
417
  {
263
418
  key: "cacheRate",
264
419
  label: "USD/M cache",
265
- render: (row) => formatRate(row.cached_input_rate_usd_per_million, locale),
420
+ description: invocationMetricDescription(locale, "cacheRate"),
421
+ render: (row) => formatInvocationRate(row.cached_input_rate_usd_per_million, locale),
266
422
  align: "right",
267
- hidden: !show((row) => row.cached_input_rate_usd_per_million),
268
423
  },
269
424
  {
270
425
  key: "outputRate",
271
426
  label: "USD/M saída",
272
- render: (row) => formatRate(row.output_rate_usd_per_million, locale),
427
+ description: invocationMetricDescription(locale, "outputRate"),
428
+ render: (row) => formatInvocationRate(row.output_rate_usd_per_million, locale),
273
429
  align: "right",
274
- hidden: !show((row) => row.output_rate_usd_per_million),
275
430
  },
276
431
  {
277
432
  key: "reasoningRate",
278
433
  label: "USD/M raciocínio",
279
- render: (row) => formatRate(row.reasoning_rate_usd_per_million, locale),
434
+ description: invocationMetricDescription(locale, "reasoningRate"),
435
+ render: (row) => formatInvocationRate(row.reasoning_rate_usd_per_million, locale),
280
436
  align: "right",
281
- hidden: !show((row) => row.reasoning_rate_usd_per_million),
282
437
  },
283
438
  {
284
439
  key: "contextMultiplier",
285
440
  label: "Mult. contexto E/S",
286
- description: localizedDescription(
287
- locale,
288
- "Multiplicadores aplicados aos segmentos de uso desta Invocação de Agente quando o limite de contexto do modelo é ultrapassado. O total da invocação agrega os segmentos sem expor cada Chamada LLM.",
289
- "Multipliers applied to this Agent Invocation's usage segments when the model context limit is exceeded. The invocation total aggregates segments without exposing each LLM Call.",
290
- ),
441
+ description: invocationMetricDescription(locale, "contextMultiplier"),
291
442
  render: (row) =>
292
- formatMultiplierPair(
443
+ formatInvocationMultiplierPair(
293
444
  row.context_input_multiplier,
294
445
  row.context_output_multiplier,
295
446
  locale,
296
447
  ),
297
448
  align: "right",
298
- hidden: !show((row) => row.context_input_multiplier),
299
449
  },
300
450
  {
301
451
  key: "speedMultiplier",
@@ -312,101 +462,96 @@ export function CostRunsTable({
312
462
  {
313
463
  key: "inputCost",
314
464
  label: "USD entrada",
315
- render: (row) => formatUsd(row.input_cost_usd, locale),
465
+ description: invocationMetricDescription(locale, "inputCost"),
466
+ render: (row) => formatInvocationUsd(row.input_cost_usd, locale),
316
467
  align: "right",
317
- footer: formatUsd(total("input_cost_usd"), locale),
318
- hidden: !show((row) => row.input_cost_usd),
468
+ footer: formatInvocationUsd(total("input_cost_usd"), locale),
319
469
  },
320
470
  {
321
471
  key: "cacheCost",
322
472
  label: "USD cache",
323
- render: (row) => formatUsd(row.cached_input_cost_usd, locale),
473
+ description: invocationMetricDescription(locale, "cacheCost"),
474
+ render: (row) => formatInvocationUsd(row.cached_input_cost_usd, locale),
324
475
  align: "right",
325
- footer: formatUsd(total("cached_input_cost_usd"), locale),
326
- hidden: !show((row) => row.cached_input_cost_usd),
476
+ footer: formatInvocationUsd(total("cached_input_cost_usd"), locale),
327
477
  },
328
478
  {
329
479
  key: "outputCost",
330
480
  label: "USD saída",
331
- render: (row) => formatUsd(row.output_cost_usd, locale),
481
+ description: invocationMetricDescription(locale, "outputCost"),
482
+ render: (row) => formatInvocationUsd(row.output_cost_usd, locale),
332
483
  align: "right",
333
- footer: formatUsd(total("output_cost_usd"), locale),
334
- hidden: !show((row) => row.output_cost_usd),
484
+ footer: formatInvocationUsd(total("output_cost_usd"), locale),
335
485
  },
336
486
  {
337
487
  key: "reasoningCost",
338
488
  label: "USD raciocínio",
339
- render: (row) => formatUsd(row.reasoning_cost_usd, locale),
489
+ description: invocationMetricDescription(locale, "reasoningCost"),
490
+ render: (row) => formatInvocationUsd(row.reasoning_cost_usd, locale),
340
491
  align: "right",
341
- footer: formatUsd(total("reasoning_cost_usd"), locale),
342
- hidden: !show((row) => row.reasoning_cost_usd),
492
+ footer: formatInvocationUsd(total("reasoning_cost_usd"), locale),
343
493
  },
344
494
  {
345
495
  key: "standardCost",
346
496
  label: "USD padrão",
347
- render: (row) => formatUsd(row.standard_cost_usd, locale),
497
+ description: invocationMetricDescription(locale, "standardCost"),
498
+ render: (row) => formatInvocationUsd(row.standard_cost_usd, locale),
348
499
  align: "right",
349
- footer: formatUsd(total("standard_cost_usd"), locale),
350
- hidden: !show((row) => row.standard_cost_usd),
500
+ footer: formatInvocationUsd(total("standard_cost_usd"), locale),
351
501
  },
352
502
  {
353
503
  key: "speedUplift",
354
504
  label: "USD acréscimo rápido",
355
- description: localizedDescription(
356
- locale,
357
- "Parcela adicional causada pela velocidade Priority/Fast. Este valor já está incluído no custo efetivo e no total; é exibido separadamente apenas para auditoria.",
358
- "Additional amount caused by Priority/Fast speed. This value is already included in the effective cost and total; it is shown separately for auditing only.",
359
- ),
360
- render: (row) => formatUsd(row.speed_uplift_usd, locale),
505
+ description: invocationMetricDescription(locale, "speedUplift"),
506
+ render: (row) => formatInvocationUsd(row.speed_uplift_usd, locale),
361
507
  align: "right",
362
- footer: formatUsd(total("speed_uplift_usd"), locale),
363
- hidden: !show((row) => row.speed_uplift_usd),
508
+ footer: formatInvocationUsd(total("speed_uplift_usd"), locale),
364
509
  },
365
510
  {
366
511
  key: "finalUsd",
367
512
  label: locale === "pt-BR" ? "USD estimado API" : "Estimated API USD",
368
- render: (row) => formatUsd(row.estimated_usd, locale),
513
+ description: invocationMetricDescription(locale, "finalUsd"),
514
+ render: (row) => formatInvocationUsd(row.estimated_usd, locale),
369
515
  align: "right",
370
- footer: formatUsd(total("estimated_usd"), locale),
371
- hidden: !show((row) => row.estimated_usd),
516
+ footer: formatInvocationUsd(total("estimated_usd"), locale),
372
517
  },
373
518
  {
374
519
  key: "fxRate",
375
520
  label: locale === "pt-BR" ? "Cotação atual" : "Current exchange rate",
376
- render: (row) => formatBrlRate(row.fx_rate, locale),
521
+ description: invocationMetricDescription(locale, "fxRate"),
522
+ render: (row) => formatInvocationBrlRate(row.fx_rate, locale),
377
523
  align: "right",
378
- hidden: !show((row) => row.fx_rate),
379
524
  },
380
525
  {
381
526
  key: "recordedFxRate",
382
527
  label: locale === "pt-BR" ? "Cotação no período" : "Period exchange rate",
383
- render: (row) => formatBrlRate(row.recorded_fx_rate, locale),
528
+ description: invocationMetricDescription(locale, "recordedFxRate"),
529
+ render: (row) => formatInvocationBrlRate(row.recorded_fx_rate, locale),
384
530
  align: "right",
385
- hidden: !show((row) => row.recorded_fx_rate),
386
531
  },
387
532
  {
388
533
  key: "recordedBrl",
389
534
  label: locale === "pt-BR" ? "Custo Final no Período" : "Period final cost",
390
- render: (row) => formatAuditableCurrency(row.recorded_brl, "BRL", locale),
535
+ description: invocationMetricDescription(locale, "recordedBrl"),
536
+ render: (row) => formatInvocationCurrency(row.recorded_brl, "BRL", locale),
391
537
  align: "right",
392
- footer: formatAuditableCurrency(total("recorded_brl"), "BRL", locale),
393
- hidden: !show((row) => row.recorded_brl),
538
+ footer: formatInvocationCurrency(total("recorded_brl"), "BRL", locale),
394
539
  },
395
540
  {
396
541
  key: "cost",
397
542
  label: locale === "pt-BR" ? "Custo Final atual" : "Current final cost",
543
+ description: invocationMetricDescription(locale, "cost"),
398
544
  render: (row) => {
399
545
  const value = currency === "BRL" ? row.estimated_brl : row.estimated_usd;
400
- return formatAuditableCurrency(value, currency, locale);
546
+ return formatInvocationCurrency(value, currency, locale);
401
547
  },
402
548
  sortValue: (row) => sortCostValue(currency, row.estimated_brl, row.estimated_usd),
403
549
  align: "right",
404
- footer: formatAuditableCurrency(
550
+ footer: formatInvocationCurrency(
405
551
  total(currency === "BRL" ? "estimated_brl" : "estimated_usd"),
406
552
  currency,
407
553
  locale,
408
554
  ),
409
- hidden: !show((row) => (currency === "BRL" ? row.estimated_brl : row.estimated_usd)),
410
555
  },
411
556
  {
412
557
  key: "trace",
@@ -427,7 +572,7 @@ export function CostRunsTable({
427
572
  },
428
573
  ]}
429
574
  locale={locale}
430
- pageSize={100}
575
+ pageSize={pagination ? null : 100}
431
576
  rowKey={(row) => row.run_id}
432
577
  onRowClick={(row) => onOpenRun(row.run_id)}
433
578
  rows={rows}
@@ -436,156 +581,86 @@ export function CostRunsTable({
436
581
  sortable
437
582
  />
438
583
  );
584
+ return pagination ? (
585
+ <>
586
+ {table}
587
+ <CostRunServerPagination locale={locale} pagination={pagination} />
588
+ </>
589
+ ) : (
590
+ table
591
+ );
439
592
  }
440
593
 
441
- export function costRunsDurationTotal(rows: readonly CostRunRow[]): number | null {
442
- return sumNumbers(durationContributors(rows).map((row) => row.duration_ms));
443
- }
444
-
445
- export function isCompactRunColumnVisible(
446
- rows: readonly CostRunRow[],
447
- select: (row: CostRunRow) => number | string | null,
448
- ): boolean {
449
- return rows.some((row) => {
450
- const value = select(row);
451
- return value !== null && value !== 0 && value !== "";
452
- });
453
- }
454
-
455
- export function formatRate(value: number | null, locale: CostLocale): string {
456
- if (value === null) return unavailableMetricLabel(locale);
457
- return new Intl.NumberFormat(locale, {
458
- minimumFractionDigits: 2,
459
- maximumFractionDigits: 2,
460
- }).format(value);
461
- }
462
-
463
- export function formatBrlRate(value: number | null, locale: CostLocale): string {
464
- if (value === null) return unavailableMetricLabel(locale);
465
- return `R$ ${new Intl.NumberFormat(locale, {
466
- minimumFractionDigits: 2,
467
- maximumFractionDigits: 2,
468
- }).format(value)}`;
469
- }
470
-
471
- export function formatUsd(value: number | null, locale: CostLocale): string {
472
- if (value === null) return unavailableMetricLabel(locale);
473
- return new Intl.NumberFormat(locale, {
474
- style: "currency",
475
- currency: "USD",
476
- minimumFractionDigits: 2,
477
- maximumFractionDigits: 2,
478
- }).format(value);
479
- }
480
-
481
- function formatMultiplier(value: number | null, locale: CostLocale): string {
482
- return value === null
483
- ? unavailableMetricLabel(locale)
484
- : `${value.toLocaleString("en-US", { maximumFractionDigits: 3 })}×`;
485
- }
486
-
487
- export function formatMultiplierPair(
488
- input: number | null,
489
- output: number | null,
490
- locale: CostLocale,
491
- ): string {
492
- if (input === null || output === null) return unavailableMetricLabel(locale);
493
- return `${formatMultiplier(input, locale)} / ${formatMultiplier(output, locale)}`;
494
- }
495
-
496
- function formatRuntimeDetail(
497
- value: string | null,
498
- kind: "effort" | "speed",
499
- locale: CostLocale,
500
- ): string {
501
- if (value === null || value.trim() === "" || value.trim().toLowerCase() === "unknown") return "-";
502
- if (locale !== "pt-BR") return value;
503
- const labels: Record<string, string> = {
504
- low: "Leve",
505
- medium: "Médio",
506
- high: "Alto",
507
- xhigh: "Extra alto",
508
- max: "Ultra",
509
- default: kind === "speed" ? "Padrão" : "Padrão",
510
- priority: "Rápido",
511
- };
512
- return labels[value] ?? value;
513
- }
514
-
515
- export function formatReasoningEffort(
516
- effective: string | null,
517
- requested: string | null,
518
- locale: CostLocale,
519
- ): string {
520
- const effectiveValue = normalizedRuntimeValue(effective);
521
- if (effectiveValue !== null) return formatRuntimeDetail(effectiveValue, "effort", locale);
522
- const requestedValue = normalizedRuntimeValue(requested);
523
- if (requestedValue === null) return "-";
524
- const formatted = formatRuntimeDetail(requestedValue, "effort", locale);
525
- return locale === "pt-BR"
526
- ? `${formatted} (solicitado; efetivo -)`
527
- : `${formatted} (requested; effective -)`;
528
- }
529
-
530
- export function formatServiceTier(value: string | null, locale: CostLocale): string {
531
- const normalized = normalizedRuntimeValue(value);
532
- if (normalized === null) return locale === "pt-BR" ? "Padrão" : "Standard";
533
- return formatRuntimeDetail(normalized, "speed", locale);
534
- }
535
-
536
- function normalizedRuntimeValue(value: string | null): string | null {
537
- const normalized = value?.trim() ?? "";
538
- return normalized === "" || normalized.toLowerCase() === "unknown" ? null : normalized;
539
- }
540
-
541
- export function costRunsScrollLabel(locale: CostLocale): string {
542
- return locale === "pt-BR"
543
- ? "Tabela de custos por invocação com rolagem horizontal"
544
- : "Agent invocation costs table with horizontal scrolling";
545
- }
546
-
547
- export function costGroupsScrollLabel(locale: CostLocale): string {
548
- return locale === "pt-BR"
549
- ? "Tabela de custos agrupados com rolagem horizontal"
550
- : "Grouped costs table with horizontal scrolling";
551
- }
552
-
553
- export function formatDateTime(value: string, locale: CostLocale): string {
554
- if (!value || Number.isNaN(Date.parse(value))) return "—";
555
- return new Intl.DateTimeFormat(locale, {
556
- dateStyle: "short",
557
- timeStyle: "medium",
558
- }).format(new Date(value));
559
- }
560
-
561
- export function formatCostPeriodLabel(
562
- value: string,
563
- period: "daily" | "monthly" | "annual",
564
- locale: CostLocale,
565
- ): string {
566
- if (period === "annual") return value.slice(0, 4);
567
- if (period === "monthly") return value.slice(0, 7);
568
- const date = new Date(`${value}T12:00:00.000Z`);
569
- if (Number.isNaN(date.getTime())) return value;
570
- return new Intl.DateTimeFormat(locale, { dateStyle: "short", timeZone: "UTC" }).format(date);
594
+ function inclusiveTokenTotal(
595
+ row: Pick<CostRunRow, "input_tokens" | "output_tokens" | "total_tokens">,
596
+ ): number | null {
597
+ return row.input_tokens !== null && row.output_tokens !== null
598
+ ? row.input_tokens + row.output_tokens
599
+ : row.total_tokens;
571
600
  }
572
601
 
573
- export function costPeriodTotalAriaLabel({
602
+ function CostRunServerPagination({
574
603
  locale,
575
- duration,
576
- tokens,
577
- cost,
578
- currency,
604
+ pagination,
579
605
  }: {
580
606
  locale: CostLocale;
581
- duration: string;
582
- tokens: string;
583
- cost: string;
584
- currency: CostCurrency;
585
- }): string {
586
- return locale === "pt-BR"
587
- ? `Total geral — Tempo: ${duration}; Tokens: ${tokens}; ${currency}: ${cost}`
588
- : `Grand total — Time: ${duration}; Tokens: ${tokens}; Cost (${currency}): ${cost}`;
607
+ pagination: NonNullable<Parameters<typeof CostRunsTable>[0]["pagination"]>;
608
+ }) {
609
+ const first = pagination.total === 0 ? 0 : pagination.offset + 1;
610
+ const last =
611
+ pagination.total === null
612
+ ? pagination.offset + pagination.limit
613
+ : Math.min(pagination.offset + pagination.limit, pagination.total);
614
+ const previous = Math.max(0, pagination.offset - pagination.limit);
615
+ const next = pagination.offset + pagination.limit;
616
+ return (
617
+ <nav
618
+ aria-label={locale === "pt-BR" ? "Paginação das invocações" : "Invocation pagination"}
619
+ className="ui-table-pagination"
620
+ >
621
+ <button
622
+ disabled={pagination.loading || pagination.offset === 0}
623
+ onClick={() => pagination.onChange(previous)}
624
+ type="button"
625
+ >
626
+ {locale === "pt-BR" ? "Anterior" : "Previous"}
627
+ </button>
628
+ <span aria-live="polite">
629
+ {pagination.loading
630
+ ? locale === "pt-BR"
631
+ ? "Carregando invocações…"
632
+ : "Loading invocations…"
633
+ : pagination.total === null
634
+ ? `${first}–${last}${pagination.has_more ? "+" : ""}`
635
+ : `${first}–${last} ${locale === "pt-BR" ? "de" : "of"} ${pagination.total}`}
636
+ </span>
637
+ <button
638
+ disabled={
639
+ pagination.loading ||
640
+ (!pagination.has_more && (pagination.total === null || next >= pagination.total))
641
+ }
642
+ onClick={() => pagination.onChange(next)}
643
+ type="button"
644
+ >
645
+ {locale === "pt-BR" ? "Próxima" : "Next"}
646
+ </button>
647
+ {pagination.error ? (
648
+ <span role="status">
649
+ {pagination.error}{" "}
650
+ <button onClick={pagination.onRetry} type="button">
651
+ {locale === "pt-BR" ? "Tentar novamente" : "Retry"}
652
+ </button>
653
+ </span>
654
+ ) : null}
655
+ </nav>
656
+ );
657
+ }
658
+
659
+ function costPeriodHeading(period: "daily" | "monthly" | "annual", locale: CostLocale): string {
660
+ if (locale === "en-US") {
661
+ return period === "daily" ? "Day" : period === "monthly" ? "Month" : "Year";
662
+ }
663
+ return period === "daily" ? "Dia" : period === "monthly" ? "Mês" : "Ano";
589
664
  }
590
665
 
591
666
  export function CostGroupsTable({
@@ -595,8 +670,11 @@ export function CostGroupsTable({
595
670
  onOpenTrace,
596
671
  period,
597
672
  showDateTime = true,
673
+ showAgentIdentity = false,
674
+ showInvocationTasks = false,
598
675
  dateHeading,
599
676
  labelHeading,
677
+ totals: suppliedTotals,
600
678
  }: {
601
679
  rows: readonly CostGroupRow[];
602
680
  currency: CostCurrency;
@@ -604,19 +682,15 @@ export function CostGroupsTable({
604
682
  onOpenTrace?: (taskId: string) => void;
605
683
  period?: "daily" | "monthly" | "annual";
606
684
  showDateTime?: boolean;
685
+ showAgentIdentity?: boolean;
686
+ showInvocationTasks?: boolean;
607
687
  dateHeading?: string;
608
688
  labelHeading?: string;
689
+ totals?: CostGroupTotals;
609
690
  }) {
610
- const totals = {
691
+ const pageTotals = {
611
692
  runs: rows.reduce((sum, row) => sum + row.run_count, 0),
612
- tasks: rows.reduce(
613
- (sum, row) =>
614
- sum +
615
- (period === undefined
616
- ? row.task_count
617
- : (row.taskDaysActive ?? row.tasksActive ?? row.task_count)),
618
- 0,
619
- ),
693
+ tasks: rows.reduce((sum, row) => sum + (row.task_count ?? 0), 0),
620
694
  prds: rows.reduce((sum, row) => sum + row.prd_count, 0),
621
695
  specs: rows.reduce((sum, row) => sum + row.spec_count, 0),
622
696
  evidences: rows.reduce((sum, row) => sum + row.evidence_count, 0),
@@ -627,11 +701,33 @@ export function CostGroupsTable({
627
701
  usd: sumNumbers(rows.map((row) => row.estimated_usd)),
628
702
  brl: sumNumbers(rows.map((row) => row.estimated_brl)),
629
703
  };
630
- const totalDurationDisplay = !totals.durationPartial
631
- ? formatAuditableDuration(totals.durationKnownMs, locale)
632
- : totals.durationKnownMs === 0
633
- ? unavailableMetricLabel(locale)
634
- : formatDurationMs(totals.durationKnownMs, locale);
704
+ const totals =
705
+ suppliedTotals === undefined
706
+ ? pageTotals
707
+ : {
708
+ runs: suppliedTotals.run_count,
709
+ tasks: suppliedTotals.task_count ?? 0,
710
+ prds: suppliedTotals.prd_count,
711
+ specs: suppliedTotals.spec_count,
712
+ evidences: suppliedTotals.evidence_count,
713
+ tests: suppliedTotals.test_count,
714
+ durationKnownMs: suppliedTotals.duration.known_sum,
715
+ durationPartial: !suppliedTotals.duration.complete,
716
+ tokens: suppliedTotals.total_tokens,
717
+ usd: suppliedTotals.estimated_usd,
718
+ brl: suppliedTotals.estimated_brl,
719
+ };
720
+ const totalDurationDisplay = formatDurationCoverage(
721
+ suppliedTotals?.duration ?? {
722
+ known_sum: totals.durationKnownMs,
723
+ unknown: totals.durationPartial ? 1 : 0,
724
+ complete: !totals.durationPartial,
725
+ // Group-level coverage is intentionally preserved separately from the
726
+ // factual known sum. Individual rows retain their original provenance.
727
+ coverage_ratio: totals.durationPartial ? 0 : 1,
728
+ },
729
+ locale,
730
+ );
635
731
  const totalTokensDisplay = formatAuditableCompactNumber(totals.tokens, locale);
636
732
  const totalCostDisplay = formatAuditableCurrency(
637
733
  currency === "BRL" ? totals.brl : totals.usd,
@@ -656,52 +752,70 @@ export function CostGroupsTable({
656
752
  hidden: !showDateTime,
657
753
  footer: showDateTime ? <output aria-label={totalLabel}>Total</output> : undefined,
658
754
  },
755
+ ...(showAgentIdentity
756
+ ? [
757
+ {
758
+ key: "persona",
759
+ label: locale === "pt-BR" ? "Persona" : "Persona",
760
+ render: (row: CostGroupRow) => row.persona ?? "",
761
+ },
762
+ {
763
+ key: "job",
764
+ label: locale === "pt-BR" ? "Cargo" : "Job",
765
+ render: (row: CostGroupRow) => row.job ?? "",
766
+ },
767
+ ]
768
+ : []),
659
769
  {
660
770
  key: "label",
661
771
  label:
662
772
  period === undefined
663
773
  ? (labelHeading ?? (locale === "pt-BR" ? "Grupo" : "Group"))
664
- : locale === "pt-BR"
665
- ? "Período"
666
- : "Period",
667
- render: (row) =>
668
- period === undefined ? (
774
+ : costPeriodHeading(period, locale),
775
+ render: (row) => {
776
+ if (period !== undefined) {
777
+ return <strong>{formatCostPeriodLabel(row.key, period, locale)}</strong>;
778
+ }
779
+ const displayLabel = displayCostGroupLabel(row.label, locale);
780
+ const unavailableLabel = displayLabel !== row.label;
781
+ return (
669
782
  <>
670
- <strong>{row.label}</strong>
671
- {row.key === row.label ? null : <small>{row.key}</small>}
783
+ <strong>{displayLabel}</strong>
784
+ {unavailableLabel || row.key === row.label ? null : <small>{row.key}</small>}
672
785
  </>
673
- ) : (
674
- <strong>{formatCostPeriodLabel(row.key, period, locale)}</strong>
675
- ),
786
+ );
787
+ },
676
788
  sortValue: (row) => row.key,
677
789
  footer: showDateTime ? undefined : <output aria-label={totalLabel}>Total</output>,
678
790
  },
679
- {
680
- key: "runs",
681
- label: locale === "pt-BR" ? "Invocações" : "Agent invocations",
682
- render: (row) => row.run_count,
683
- align: "right",
684
- footer: totals.runs,
685
- },
686
- {
687
- key: "tasks",
688
- label:
689
- period === undefined
690
- ? locale === "pt-BR"
691
- ? "Tarefas ativas"
692
- : "Active tasks"
693
- : locale === "pt-BR"
694
- ? "Dias-tarefa ativos"
695
- : "Active task-days",
696
- render: (row) =>
697
- period === undefined
698
- ? row.task_count
699
- : (row.taskDaysActive ?? row.tasksActive ?? row.task_count),
700
- align: "right",
701
- footer: totals.tasks,
702
- },
703
791
  ...(period === undefined
704
- ? []
792
+ ? [
793
+ {
794
+ key: "runs",
795
+ label: locale === "pt-BR" ? "Invocações" : "Agent invocations",
796
+ render: (row: CostGroupRow) => row.run_count,
797
+ align: "right" as const,
798
+ footer: totals.runs,
799
+ },
800
+ ...(showAgentIdentity
801
+ ? []
802
+ : [
803
+ {
804
+ key: "tasks",
805
+ label:
806
+ showAgentIdentity || showInvocationTasks
807
+ ? locale === "pt-BR"
808
+ ? "Tarefas com invocação"
809
+ : "Tasks with invocations"
810
+ : locale === "pt-BR"
811
+ ? "Tarefas criadas"
812
+ : "Tasks created",
813
+ render: (row: CostGroupRow) => row.task_count ?? 0,
814
+ align: "right" as const,
815
+ footer: totals.tasks,
816
+ },
817
+ ]),
818
+ ]
705
819
  : [
706
820
  {
707
821
  key: "prds",
@@ -718,25 +832,39 @@ export function CostGroupsTable({
718
832
  footer: totals.specs,
719
833
  },
720
834
  {
721
- key: "evidences",
722
- label: locale === "pt-BR" ? "Evidências" : "Evidence",
723
- render: (row: CostGroupRow) => row.evidence_count,
835
+ key: "tasks",
836
+ label: locale === "pt-BR" ? "Tarefas criadas" : "Tasks created",
837
+ render: (row: CostGroupRow) => row.task_count ?? 0,
724
838
  align: "right" as const,
725
- footer: totals.evidences,
839
+ footer: totals.tasks,
840
+ },
841
+ {
842
+ key: "runs",
843
+ label: "Runs",
844
+ render: (row: CostGroupRow) => row.run_count,
845
+ align: "right" as const,
846
+ footer: totals.runs,
726
847
  },
727
848
  {
728
849
  key: "tests",
729
- label: "Tests",
850
+ label: locale === "pt-BR" ? "Testes" : "Tests",
730
851
  render: (row: CostGroupRow) => row.test_count,
731
852
  align: "right" as const,
732
853
  footer: totals.tests,
733
854
  },
855
+ {
856
+ key: "evidences",
857
+ label: locale === "pt-BR" ? "Evidências" : "Evidence",
858
+ render: (row: CostGroupRow) => row.evidence_count,
859
+ align: "right" as const,
860
+ footer: totals.evidences,
861
+ },
734
862
  ]),
735
863
  {
736
864
  key: "duration",
737
865
  label: "Tempo",
738
- render: (row) => formatDurationCoverage(row.duration, locale),
739
- sortValue: (row) => (row.duration.coverage_ratio > 0 ? row.duration.known_sum : null),
866
+ render: (row) => formatTokenBackedDuration(row.duration, row.total_tokens, locale),
867
+ sortValue: (row) => (hasKnownDuration(row.duration) ? row.duration.known_sum : null),
740
868
  align: "right",
741
869
  footer: <output aria-label={totalAriaLabel}>{totalDurationDisplay}</output>,
742
870
  },
@@ -750,7 +878,14 @@ export function CostGroupsTable({
750
878
  },
751
879
  {
752
880
  key: "cost",
753
- label: locale === "pt-BR" ? "Custo" : "Cost",
881
+ label:
882
+ period === undefined
883
+ ? locale === "pt-BR"
884
+ ? "Custo"
885
+ : "Cost"
886
+ : locale === "pt-BR"
887
+ ? "Custos"
888
+ : "Costs",
754
889
  render: (row) =>
755
890
  formatAuditableCurrency(
756
891
  currency === "BRL" ? row.estimated_brl : row.estimated_usd,
@@ -783,7 +918,13 @@ export function CostGroupsTable({
783
918
  ]
784
919
  : []),
785
920
  ]}
786
- defaultSort={period === undefined ? null : { key: "label", direction: "desc" }}
921
+ defaultSort={
922
+ showAgentIdentity
923
+ ? { key: "cost", direction: "desc" }
924
+ : period === undefined
925
+ ? null
926
+ : { key: "label", direction: "desc" }
927
+ }
787
928
  locale={locale}
788
929
  pageSize={100}
789
930
  rowKey={(row) => row.key}