@zaip-ai/cli 1.0.8 → 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 (212) hide show
  1. package/README.md +1 -1
  2. package/dist/services/adapters.d.ts +1 -1
  3. package/dist/services/adapters.js +1 -1
  4. package/dist/services/agent-adapters.js +2 -2
  5. package/dist/services/agent-adapters.js.map +1 -1
  6. package/dist/services/agent-adapters.test.js +5 -0
  7. package/dist/services/agent-adapters.test.js.map +1 -1
  8. package/dist/services/logger.test.js +2 -2
  9. package/dist/services/runtime-template.test.js +6 -6
  10. package/dist/services/template-manifest.d.ts.map +1 -1
  11. package/dist/services/template-manifest.js +5 -0
  12. package/dist/services/template-manifest.js.map +1 -1
  13. package/package.json +1 -1
  14. package/templates/.agents/architecture/software-architecture.md +131 -0
  15. package/templates/.agents/branding/brandbook.docx +0 -0
  16. package/templates/.agents/branding/brandbook.md +60 -0
  17. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
  18. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -1
  19. package/templates/.agents/dashboard/.tmp-run-list.json +254 -0
  20. package/templates/.agents/dashboard/.zaip-managed.json +252 -136
  21. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-Z60df2r-.js → CostCalculationGuidePage-DxR_pgSV.js} +1 -1
  22. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-4jZLTWE_.js +2156 -0
  23. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Coc6pA-1.js → PricingSettingsDialog-CKcsqb-r.js} +1 -1
  24. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BomxqCBU.css +1 -0
  25. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-DmmJD2Th.js +3 -0
  26. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BwtitWa_.js +1 -0
  27. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-N5Csr0RP.js +68 -0
  28. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DFBuc_qp.js → icons-vendor-C0fj2uU9.js} +1 -1
  29. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-C4aIB1PV.js +2 -0
  30. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CCQOHdVI.js → react-vendor-BEsJ-FYH.js} +1 -1
  31. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-pC2_0J8x.js → traceability-B6y6Gw12.js} +1 -1
  32. package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
  33. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  34. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +204 -32
  35. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +11 -11
  36. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +14 -7
  37. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +4 -2
  38. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +3 -1
  39. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +14 -11
  40. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +19 -4
  41. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +24 -2
  42. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +22 -1
  43. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +3 -1
  44. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +36 -26
  45. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +2 -2
  46. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +40 -6
  47. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +39 -1
  48. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +89 -23
  49. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +219 -29
  50. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +61 -7
  51. package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +3 -6
  52. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +2 -2
  53. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +3 -4
  54. package/templates/.agents/dashboard/apps/frontend/vite.config.ts +4 -1
  55. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  56. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +89 -19
  57. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +31 -16
  58. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +43 -14
  59. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +5 -5
  60. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +1 -1
  61. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +67 -42
  62. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +115 -39
  63. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +188 -38
  64. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +75 -17
  65. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +147 -58
  66. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +5 -2
  67. package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +2 -2
  68. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +2 -1
  69. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +18 -7
  70. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +95 -9
  71. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +29 -17
  72. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +0 -24
  73. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +225 -424
  74. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +24 -15
  75. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +6 -1
  76. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-monitor-projection-agents.test.ts +31 -0
  77. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-summary-projection-duration.test.ts +414 -0
  78. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  79. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +26 -23
  80. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +31 -11
  81. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +3 -1
  82. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +51 -21
  83. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +47 -5
  84. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +1 -4
  85. package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +32 -10
  86. package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +9 -3
  87. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +13 -5
  88. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +12 -4
  89. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +1 -4
  90. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +1 -2
  91. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +385 -4
  92. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +481 -61
  93. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +14 -1
  94. package/templates/.agents/dashboard/modules/operations/src/react/export/xlsx-runtime-e2e.test.ts +248 -0
  95. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +4 -4
  96. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +6 -4
  97. package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +4 -1
  98. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +1 -1
  99. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +1 -1
  100. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +46 -6
  101. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +1 -4
  102. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +82 -6
  103. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +2 -1
  104. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +1 -1
  105. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +19 -7
  106. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +4 -1
  107. package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +11 -5
  108. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  109. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  110. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  111. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  112. package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
  113. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  114. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +152 -149
  115. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs.metafile.json +7333 -0
  116. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +149 -146
  117. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  118. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +15 -7
  119. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +44 -13
  120. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +5 -2
  121. package/templates/.agents/dashboard/packages/local-runtime/scripts/source-size-runtime-scripts/sqlite-read-model-fixture.mjs +397 -0
  122. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +472 -145
  123. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +15 -3
  124. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +129 -31
  125. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +153 -150
  126. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +6 -2
  127. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +3 -3
  128. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +55 -16
  129. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +23 -13
  130. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +19 -4
  131. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +7 -3
  132. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +132 -9
  133. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +126 -60
  134. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +16 -2
  135. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +1861 -350
  136. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +1218 -352
  137. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +119 -42
  138. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +45 -20
  139. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  140. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  141. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +7 -5
  142. package/templates/.agents/design/.zaip-managed.json +3 -3
  143. package/templates/.agents/design/apps/catalog/package.json +1 -1
  144. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  145. package/templates/.agents/growth/estrategia-bootstrap-90-dias.md +169 -0
  146. package/templates/.agents/growth/strategy.md +27 -0
  147. package/templates/.agents/marketing/estrategia-marketing-zaip-90-dias.md +197 -0
  148. package/templates/.agents/marketing/strategy.md +29 -0
  149. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  150. package/templates/.agents/requirements/comparative-audit.md +1 -1
  151. package/templates/.agents/requirements/context-engine.md +1 -1
  152. package/templates/.agents/requirements/cost-observability.md +1 -1
  153. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  154. package/templates/.agents/requirements/data-export.md +1 -1
  155. package/templates/.agents/requirements/design-system.md +1 -1
  156. package/templates/.agents/requirements/execution-engine.md +1 -1
  157. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  158. package/templates/.agents/requirements/model-orchestration.md +1 -1
  159. package/templates/.agents/requirements/public-distribution.md +1 -1
  160. package/templates/.agents/requirements/software-architecture.md +1 -1
  161. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  162. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  163. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  164. package/templates/.agents/runtime/VERSION +1 -1
  165. package/templates/.agents/runtime/bin/zaip.mjs +30 -29
  166. package/templates/.agents/runtime/checksums.sha256 +6 -6
  167. package/templates/.agents/runtime/manifest.json +1 -1
  168. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  169. package/templates/.agents/runtime/provenance.json +5 -5
  170. package/templates/.agents/runtime/sbom.cdx.json +3 -3
  171. package/templates/.agents/sales/playbook.md +32 -0
  172. package/templates/.agents/sales/roteiro-comercial-zaip.md +252 -0
  173. package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
  174. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +9 -2
  175. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-framework.md +39 -0
  176. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +1 -1
  177. package/templates/.agents/skills/zaip-skill-enforce-architecture/SKILL.md +2 -0
  178. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +6 -0
  179. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +6 -0
  180. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +39 -82
  181. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +13 -8
  182. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +44 -14
  183. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +19 -9
  184. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +29 -5
  185. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +77 -0
  186. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +6 -0
  187. package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +28 -5
  188. package/templates/.agents/zaip-aios/INDEX.md +10 -0
  189. package/templates/.agents/zaip-aios/README.md +2 -1
  190. package/templates/.agents/zaip-aios/VERSION +1 -1
  191. package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +76 -0
  192. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +72 -0
  193. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +330 -0
  194. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +52 -0
  195. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +69 -0
  196. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +483 -0
  197. package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +85 -0
  198. package/templates/.agents/zaip-aios/guides/25-fontes-de-precos-openai.md +18 -0
  199. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +44 -0
  200. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +167 -0
  201. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +144 -0
  202. package/templates/.agents/zaip-aios/guides/assets/diagrams/lifecycles-task-spec-prd.png +0 -0
  203. package/templates/.agents/zaip-aios/guides/assets/diagrams/prd-lifecycle.png +0 -0
  204. package/templates/.agents/zaip-aios/guides/assets/diagrams/spec-lifecycle.png +0 -0
  205. package/templates/.agents/zaip-aios/guides/assets/diagrams/task-lifecycle.png +0 -0
  206. package/templates/template-manifest.json +313 -177
  207. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-Cs6dzDmW.js +0 -1505
  208. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +0 -1
  209. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +0 -3
  210. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +0 -1
  211. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +0 -68
  212. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +0 -2
@@ -12,63 +12,112 @@ import {
12
12
  withTokenBackedCompactDuration,
13
13
  } from "./CompactLifecycleCostTable.js";
14
14
  import { costPeriodDateRange, defaultCostPeriod, emptyCostFilters } from "./CostFilters.js";
15
- import {
16
- costGroupPageLabel,
17
- effectiveCostGroupQuery,
18
- reconcileCostGroupTotalsWithCards,
19
- } from "./use-cost-group-page.js";
20
15
  import {
21
16
  COST_VIEW_ORDER,
22
17
  DEFAULT_COST_VIEW,
23
18
  findRunDetails,
24
19
  groupRows,
20
+ isCostViewExportEligible,
25
21
  isCurrentCostRunPageGeneration,
26
22
  isServerCostRunPagingEligible,
27
23
  matchesGlobalFilters,
28
24
  matchesPeriodEntity,
25
+ resolveCompactCostPageRange,
29
26
  resolveCostGroupPageRange,
30
27
  selectDimensionalCostRows,
31
28
  visibleExecutionRows,
32
29
  } from "./CostMonitorPage.js";
30
+ import {
31
+ costGroupPageLabel,
32
+ effectiveCostGroupQuery,
33
+ reconcileCostGroupTotalsWithCards,
34
+ } from "./use-cost-group-page.js";
33
35
 
34
36
  describe("cost monitor navigation", () => {
37
+ it("hides Excel export from the overview while retaining it on tabular views", () => {
38
+ expect(isCostViewExportEligible("overview")).toBe(false);
39
+ expect(isCostViewExportEligible("daily")).toBe(true);
40
+ expect(isCostViewExportEligible("agentCalls")).toBe(true);
41
+ });
42
+
35
43
  it("keeps the embedded default group pager on the all-time snapshot without explicit filters", () => {
36
44
  const monthRange = costPeriodDateRange(defaultCostPeriod, new Date("2026-08-17T12:00:00.000Z"));
37
- expect(resolveCostGroupPageRange({
38
- embedded: true,
39
- globalDateRange: undefined,
40
- hasLocalCostFilters: false,
41
- period: defaultCostPeriod,
42
- runPageRange: monthRange,
43
- })).toBeUndefined();
44
- expect(resolveCostGroupPageRange({
45
- embedded: true,
46
- globalDateRange: undefined,
47
- hasLocalCostFilters: false,
48
- period: "30",
49
- runPageRange: monthRange,
50
- })).toEqual(monthRange);
51
- expect(resolveCostGroupPageRange({
52
- embedded: true,
53
- globalDateRange: { start: "2026-07-14", end: "2026-08-17" },
54
- hasLocalCostFilters: false,
55
- period: defaultCostPeriod,
56
- runPageRange: { from: "2026-07-14", to: "2026-08-17" },
57
- })).toEqual({ from: "2026-07-14", to: "2026-08-17" });
58
- expect(resolveCostGroupPageRange({
59
- embedded: true,
60
- globalDateRange: undefined,
61
- hasLocalCostFilters: true,
62
- period: defaultCostPeriod,
63
- runPageRange: monthRange,
64
- })).toEqual(monthRange);
45
+ expect(
46
+ resolveCostGroupPageRange({
47
+ embedded: true,
48
+ globalDateRange: undefined,
49
+ hasLocalCostFilters: false,
50
+ period: defaultCostPeriod,
51
+ runPageRange: monthRange,
52
+ }),
53
+ ).toBeUndefined();
54
+ expect(
55
+ resolveCostGroupPageRange({
56
+ embedded: true,
57
+ globalDateRange: undefined,
58
+ hasLocalCostFilters: false,
59
+ period: "30",
60
+ runPageRange: monthRange,
61
+ }),
62
+ ).toEqual(monthRange);
63
+ expect(
64
+ resolveCostGroupPageRange({
65
+ embedded: true,
66
+ globalDateRange: { start: "2026-07-14", end: "2026-08-17" },
67
+ hasLocalCostFilters: false,
68
+ period: defaultCostPeriod,
69
+ runPageRange: { from: "2026-07-14", to: "2026-08-17" },
70
+ }),
71
+ ).toEqual({ from: "2026-07-14", to: "2026-08-17" });
72
+ expect(
73
+ resolveCostGroupPageRange({
74
+ embedded: true,
75
+ globalDateRange: undefined,
76
+ hasLocalCostFilters: true,
77
+ period: defaultCostPeriod,
78
+ runPageRange: monthRange,
79
+ }),
80
+ ).toEqual(monthRange);
81
+ });
82
+
83
+ it("keeps compact SPEC and PRD pages and their export source on the all-time snapshot", () => {
84
+ const monthRange = costPeriodDateRange(defaultCostPeriod, new Date("2026-08-17T12:00:00.000Z"));
85
+ expect(
86
+ resolveCompactCostPageRange({
87
+ embedded: true,
88
+ globalDateRange: undefined,
89
+ hasLocalCostFilters: false,
90
+ period: defaultCostPeriod,
91
+ runPageRange: monthRange,
92
+ }),
93
+ ).toBeUndefined();
94
+ expect(
95
+ resolveCompactCostPageRange({
96
+ embedded: false,
97
+ globalDateRange: undefined,
98
+ hasLocalCostFilters: false,
99
+ period: defaultCostPeriod,
100
+ runPageRange: monthRange,
101
+ }),
102
+ ).toEqual(monthRange);
103
+ const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
104
+ expect(page).toContain("range: compactPageRange");
105
+ expect(page).toContain("...(compactPageRange === undefined ? {} : compactPageRange)");
106
+ });
107
+
108
+ it("releases the host loading gate when a global filter replaces the Cost Monitor surface", () => {
109
+ const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
110
+
111
+ expect(page).toContain("() => () => onLoadingChange?.(false)");
65
112
  });
66
113
 
67
114
  it("labels daily pagination by its continuous result range", () => {
68
- expect(costGroupPageLabel({
69
- locale: "pt-BR",
70
- page: { offset: 30, limit: 30, total_count: 35 },
71
- })).toBe("31–35 de 35");
115
+ expect(
116
+ costGroupPageLabel({
117
+ locale: "pt-BR",
118
+ page: { offset: 30, limit: 30, total_count: 35 },
119
+ }),
120
+ ).toBe("31–35 de 35");
72
121
  const content = readFileSync(new URL("./CostMonitorContent.tsx", import.meta.url), "utf8");
73
122
  expect(content).toContain("groupPageOffset + groupPage.limit");
74
123
  expect(content).toContain("groupPageOffset - groupPage.limit");
@@ -158,6 +207,8 @@ describe("cost monitor navigation", () => {
158
207
  const runHook = readFileSync(new URL("./use-cost-run-page.ts", import.meta.url), "utf8");
159
208
  const periodHook = readFileSync(new URL("./CostFilters.tsx", import.meta.url), "utf8");
160
209
  expect(compactHook).toContain("const loadRef = useRef(load)");
210
+ expect(compactHook).toContain("const [resolvedKey, setResolvedKey]");
211
+ expect(compactHook).toContain("compactPage: resolvedKey === requestKey ? page : null");
161
212
  expect(compactHook).toContain("const loadPage = loadRef.current");
162
213
  expect(compactHook).toContain("if (loadPage === undefined) return;");
163
214
  expect(compactHook).not.toContain("[attempt, load,");
@@ -198,11 +249,15 @@ describe("cost monitor navigation", () => {
198
249
  expect(isServerCostRunPagingEligible({ ...emptyCostFilters, status: "executing" })).toBe(true);
199
250
  expect(isServerCostRunPagingEligible({ ...emptyCostFilters, query: "edge" })).toBe(true);
200
251
  expect(isServerCostRunPagingEligible(emptyCostFilters, "edge")).toBe(true);
201
- expect(isServerCostRunPagingEligible({ ...emptyCostFilters, query: "local" }, "global")).toBe(false);
252
+ expect(isServerCostRunPagingEligible({ ...emptyCostFilters, query: "local" }, "global")).toBe(
253
+ false,
254
+ );
202
255
  });
203
256
  it("routes global search to lazy invocations and all active dimensions to lazy groups", () => {
204
257
  expect(effectiveCostGroupQuery(emptyCostFilters, "global-edge")).toBe("global-edge");
205
- expect(effectiveCostGroupQuery({ ...emptyCostFilters, query: "local-edge" }, "global-edge")).toBe("local-edge");
258
+ expect(
259
+ effectiveCostGroupQuery({ ...emptyCostFilters, query: "local-edge" }, "global-edge"),
260
+ ).toBe("local-edge");
206
261
  const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
207
262
  const runHook = readFileSync(new URL("./use-cost-run-page.ts", import.meta.url), "utf8");
208
263
  const groupHook = readFileSync(new URL("./use-cost-group-page.ts", import.meta.url), "utf8");
@@ -272,6 +327,27 @@ describe("cost monitor navigation", () => {
272
327
  ]);
273
328
  });
274
329
 
330
+ it("prepares Agent Invocations from every server page for export", () => {
331
+ const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
332
+ expect(page).toContain('view === "agentCalls" && serverPagingEligible');
333
+ expect(page).toContain("agentInvocationExportSource");
334
+ expect(page).toMatch(
335
+ /pageSource=\{\s*compactExportSource \?\? agentInvocationExportSource \?\? costGroupExportSource\s*\}/,
336
+ );
337
+ expect(page).toContain("if (page.runs.length === 0) return");
338
+ });
339
+
340
+ it("prepares every paginated period row for daily, monthly, and annual exports", () => {
341
+ const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
342
+
343
+ expect(page).toContain('view === "daily" ||');
344
+ expect(page).toContain('view === "monthly" ||');
345
+ expect(page).toContain('view === "annual" ||');
346
+ expect(page).toContain("...(groupPageRange === undefined ? {} : groupPageRange)");
347
+ expect(page).toContain("totalRows: firstPage.total_count");
348
+ expect(page).toContain("nextOffset >= page.total_count || !page.has_more");
349
+ });
350
+
275
351
  it("resolves an Agent Run to its own details", () => {
276
352
  const runs = [{ id: "RUN-001" }, { id: "RUN-002" }];
277
353
 
@@ -79,6 +79,11 @@ export type { LoadCostGroupPage } from "./use-cost-group-page.js";
79
79
  export type LoadCostMonitorDetail = typeof loadCostMonitorDetail;
80
80
  export type LoadCostRunPage = typeof loadCostMonitorRunPage;
81
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
+
82
87
  /**
83
88
  * The Cost period request filters Runs, while Operations is the global snapshot
84
89
  * used for shared entity detail. Keep the Executions tab on that same active
@@ -129,10 +134,20 @@ export function resolveCostGroupPageRange({
129
134
  globalDateRange === undefined &&
130
135
  period === defaultCostPeriod &&
131
136
  !hasLocalCostFilters
132
- ) return undefined;
137
+ )
138
+ return undefined;
133
139
  return runPageRange;
134
140
  }
135
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);
149
+ }
150
+
136
151
  export function CostMonitorPage({
137
152
  capabilityNavigation,
138
153
  data,
@@ -234,6 +249,13 @@ export function CostMonitorPage({
234
249
  period,
235
250
  runPageRange,
236
251
  });
252
+ const compactPageRange = resolveCompactCostPageRange({
253
+ embedded,
254
+ globalDateRange: globalFilters?.dateRange,
255
+ hasLocalCostFilters,
256
+ period,
257
+ runPageRange,
258
+ });
237
259
  const costGroupViewName = (
238
260
  candidate: CostView,
239
261
  ): "daily" | "monthly" | "annual" | "agents" | "models" | "providers" | null =>
@@ -263,7 +285,7 @@ export function CostMonitorPage({
263
285
  } = useCompactCostPage({
264
286
  view,
265
287
  load: loadReadModelPage,
266
- range: runPageRange,
288
+ range: compactPageRange,
267
289
  query: globalFilters?.query,
268
290
  filters,
269
291
  });
@@ -291,10 +313,29 @@ export function CostMonitorPage({
291
313
  useEffect(
292
314
  () =>
293
315
  onLoadingChange?.(
294
- loading || periodLoading || runPageLoading || groupPageState.loading || compactPageLoading || detailLoading,
316
+ loading ||
317
+ periodLoading ||
318
+ runPageLoading ||
319
+ groupPageState.loading ||
320
+ compactPageLoading ||
321
+ detailLoading,
295
322
  ),
296
- [compactPageLoading, detailLoading, groupPageState.loading, loading, onLoadingChange, periodLoading, runPageLoading],
323
+ [
324
+ compactPageLoading,
325
+ detailLoading,
326
+ groupPageState.loading,
327
+ loading,
328
+ onLoadingChange,
329
+ periodLoading,
330
+ runPageLoading,
331
+ ],
297
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]);
298
339
  useEffect(() => {
299
340
  if (!hasLocalCostFilters) onActiveDataChange?.(activeData);
300
341
  }, [activeData, hasLocalCostFilters, onActiveDataChange]);
@@ -474,7 +515,10 @@ export function CostMonitorPage({
474
515
  groupPageState.page === null
475
516
  ? []
476
517
  : groupView === "agents"
477
- ? includeConfiguredAgentGroups(groupPageState.page.rows, activeData.configured_agents)
518
+ ? includeConfiguredAgentGroups(
519
+ groupPageState.page.rows,
520
+ activeData.configured_agents,
521
+ )
478
522
  : [...groupPageState.page.rows],
479
523
  },
480
524
  [activeData.configured_agents, groups, groupPageState.page, groupView],
@@ -540,32 +584,134 @@ export function CostMonitorPage({
540
584
  visibleSpecs,
541
585
  ]);
542
586
  const compactExportSource =
543
- usingCompactPage &&
544
- compactKind !== null &&
545
- compactPage !== null &&
546
- loadReadModelPage !== undefined
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
547
684
  ? {
548
- totalRows: compactPage.total,
549
- pages: async function* () {
550
- const seen = new Set<string>();
551
- for (let offset = 0; offset < compactPage.total; offset += compactPage.limit) {
552
- const page = await loadReadModelPage({
553
- kind: compactKind,
554
- offset,
555
- limit: compactPage.limit,
556
- filters,
557
- ...(runPageRange === undefined ? {} : runPageRange),
558
- ...(globalFilters?.query ? { query: globalFilters.query } : {}),
559
- });
560
- const unique = page.rows
561
- .filter((row) => {
562
- if (seen.has(row.id)) return false;
563
- seen.add(row.id);
564
- return true;
565
- })
566
- .map(withTokenBackedCompactDuration);
567
- if (unique.length > 0) yield unique as unknown as readonly Record<string, unknown>[];
568
- }
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
+ };
569
715
  },
570
716
  }
571
717
  : undefined;
@@ -789,14 +935,18 @@ export function CostMonitorPage({
789
935
  </button>
790
936
  ))}
791
937
  </nav>
792
- <div className="cost-tab-export">
793
- <ExcelExportAction
794
- filters={{ ...filters, ...globalFilters, period }}
795
- {...(compactExportSource === undefined ? {} : { pageSource: compactExportSource })}
796
- rows={exportRows as unknown as readonly Record<string, unknown>[]}
797
- view={`cost-${view}`}
798
- />
799
- </div>
938
+ {isCostViewExportEligible(view) ? (
939
+ <div className="cost-tab-export">
940
+ <ExcelExportAction
941
+ filters={{ ...filters, ...globalFilters, period }}
942
+ pageSource={
943
+ compactExportSource ?? agentInvocationExportSource ?? costGroupExportSource
944
+ }
945
+ rows={exportRows as unknown as readonly Record<string, unknown>[]}
946
+ view={`cost-${view}`}
947
+ />
948
+ </div>
949
+ ) : null}
800
950
  </div>
801
951
  {/* CostMonitorContent owns `view === "models" && useAggregateGroups ? (` and `rows={groups.models}`. */}
802
952
  <CostMonitorContent
@@ -321,26 +321,58 @@ describe("grouped cost availability", () => {
321
321
  },
322
322
  });
323
323
  const columns = table.props.columns as Array<{ key: string; footer?: unknown }>;
324
- expect((columns.find((column) => column.key === "tokens")?.footer as { props: { children: unknown } }).props.children).toBe("50");
325
- expect((columns.find((column) => column.key === "cost")?.footer as { props: { children: unknown } }).props.children).toContain("20,00");
324
+ const tokenFooter = columns.find((column) => column.key === "tokens")?.footer;
325
+ const costFooter = columns.find((column) => column.key === "cost")?.footer;
326
+ expect(tokenFooter).toBeDefined();
327
+ expect(costFooter).toBeDefined();
328
+ expect((tokenFooter as { props: { children: unknown } }).props.children).toBe("50");
329
+ expect((costFooter as { props: { children: unknown } }).props.children).toContain("20,00");
326
330
  });
327
331
  it("renders ZAIP agent identity without a synthetic date column", () => {
328
332
  const table = CostGroupsTable({
329
- rows: [{ ...unavailableGroup, key: "zaip-agent-builder", label: "zaip-agent-builder", persona: "Rafa", job: "Builder" }],
333
+ rows: [
334
+ {
335
+ ...unavailableGroup,
336
+ key: "zaip-agent-builder",
337
+ label: "zaip-agent-builder",
338
+ persona: "Rafa",
339
+ job: "Builder",
340
+ },
341
+ ],
330
342
  currency: "BRL",
331
343
  locale: "pt-BR",
332
344
  showDateTime: false,
333
345
  showAgentIdentity: true,
334
346
  });
335
- const columns = table.props.columns as Array<{ key: string; label: string; hidden?: boolean; render?: (row: { persona?: string | null; job?: string | null }) => unknown }>;
347
+ const columns = table.props.columns as Array<{
348
+ key: string;
349
+ label: string;
350
+ hidden?: boolean;
351
+ render?: (row: { persona?: string | null; job?: string | null }) => unknown;
352
+ }>;
336
353
  expect(columns.find((column) => column.key === "latestStartedAt")?.hidden).toBe(true);
337
- expect(columns.find((column) => column.key === "persona")?.render?.({ persona: "Rafa" })).toBe("Rafa");
338
- expect(columns.find((column) => column.key === "job")?.render?.({ job: "Builder" })).toBe("Builder");
354
+ expect(columns.find((column) => column.key === "persona")?.render?.({ persona: "Rafa" })).toBe(
355
+ "Rafa",
356
+ );
357
+ expect(columns.find((column) => column.key === "job")?.render?.({ job: "Builder" })).toBe(
358
+ "Builder",
359
+ );
339
360
  expect(columns.find((column) => column.key === "tasks")).toBeUndefined();
361
+ expect(table.props.defaultSort).toEqual({ key: "cost", direction: "desc" });
340
362
  });
341
363
  it("keeps legacy codex identity fields blank and uses the complete paged aggregate in its footer", () => {
342
364
  const table = CostGroupsTable({
343
- rows: [{ ...unavailableGroup, key: "codex", label: "codex", run_count: 1, total_tokens: 10, estimated_brl: 1, estimated_usd: 1 }],
365
+ rows: [
366
+ {
367
+ ...unavailableGroup,
368
+ key: "codex",
369
+ label: "codex",
370
+ run_count: 1,
371
+ total_tokens: 10,
372
+ estimated_brl: 1,
373
+ estimated_usd: 1,
374
+ },
375
+ ],
344
376
  currency: "BRL",
345
377
  locale: "pt-BR",
346
378
  showDateTime: false,
@@ -355,11 +387,19 @@ describe("grouped cost availability", () => {
355
387
  duration: { known_sum: 0, unknown: 1, complete: false, coverage_ratio: 0 },
356
388
  },
357
389
  });
358
- const columns = table.props.columns as Array<{ key: string; render?: (row: { persona?: string | null; job?: string | null }) => unknown; footer?: unknown }>;
359
- expect(columns.find((column) => column.key === "persona")?.render?.({ persona: null })).toBe("");
390
+ const columns = table.props.columns as Array<{
391
+ key: string;
392
+ render?: (row: { persona?: string | null; job?: string | null }) => unknown;
393
+ footer?: unknown;
394
+ }>;
395
+ expect(columns.find((column) => column.key === "persona")?.render?.({ persona: null })).toBe(
396
+ "",
397
+ );
360
398
  expect(columns.find((column) => column.key === "job")?.render?.({ job: null })).toBe("");
361
399
  expect(columns.find((column) => column.key === "runs")?.footer).toBe(2);
362
- expect((columns.find((column) => column.key === "tokens")?.footer as { props: { children: unknown } }).props.children).toBe("30");
400
+ const tokenFooter = columns.find((column) => column.key === "tokens")?.footer;
401
+ expect(tokenFooter).toBeDefined();
402
+ expect((tokenFooter as { props: { children: unknown } }).props.children).toBe("30");
363
403
  });
364
404
  it("renders model groups without date and labels distinct invocation tasks", () => {
365
405
  const table = CostGroupsTable({
@@ -398,8 +438,9 @@ describe("grouped cost availability", () => {
398
438
  duration: { known_sum: 20_000, unknown: 1, complete: false, coverage_ratio: 0.5 },
399
439
  };
400
440
  const table = CostGroupsTable({ rows: [partial], currency: "BRL", locale: "pt-BR" });
401
- const duration = (table.props.columns as Array<{ key: string; footer?: { props: { children: unknown } } }>)
402
- .find((column) => column.key === "duration");
441
+ const duration = (
442
+ table.props.columns as Array<{ key: string; footer?: { props: { children: unknown } } }>
443
+ ).find((column) => column.key === "duration");
403
444
  expect(duration?.footer?.props.children).toBe("20 seg");
404
445
  });
405
446
  it("does not expose coverage as a detailed Run column", () => {
@@ -470,11 +511,28 @@ describe("grouped cost availability", () => {
470
511
  }>;
471
512
  const column = (key: string) => columns.find((candidate) => candidate.key === key);
472
513
  const numericKeys = [
473
- "duration", "inputTokens", "cachedInputTokens", "outputTokens", "reasoningTokens",
474
- "totalTokens", "inputRate", "cacheRate",
475
- "outputRate", "reasoningRate", "contextMultiplier", "inputCost", "cacheCost",
476
- "outputCost", "reasoningCost", "standardCost", "speedUplift", "finalUsd", "fxRate",
477
- "recordedFxRate", "recordedBrl", "cost",
514
+ "duration",
515
+ "inputTokens",
516
+ "cachedInputTokens",
517
+ "outputTokens",
518
+ "reasoningTokens",
519
+ "totalTokens",
520
+ "inputRate",
521
+ "cacheRate",
522
+ "outputRate",
523
+ "reasoningRate",
524
+ "contextMultiplier",
525
+ "inputCost",
526
+ "cacheCost",
527
+ "outputCost",
528
+ "reasoningCost",
529
+ "standardCost",
530
+ "speedUplift",
531
+ "finalUsd",
532
+ "fxRate",
533
+ "recordedFxRate",
534
+ "recordedBrl",
535
+ "cost",
478
536
  ];
479
537
  for (const key of numericKeys) {
480
538
  expect(column(key)?.description).toContain("projeção SQLite/API");