@zaip-ai/cli 1.3.2 → 1.3.5

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 (98) hide show
  1. package/LICENSE +6 -3
  2. package/README.md +8 -2
  3. package/dist/services/codex-pre-tool-hook-template.js +1 -1
  4. package/dist/services/runtime-template.test.js +9 -8
  5. package/dist/services/runtime-template.test.js.map +1 -1
  6. package/package.json +2 -2
  7. package/templates/.agents/dashboard/.zaip-managed.json +414 -394
  8. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-ovxurkIk.js → CostCalculationGuidePage-D1mpyYwh.js} +1 -1
  9. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-BXy6nti1.js → DashboardHelpDialog-CKO47D5s.js} +30 -1
  10. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-vSvvOHQp.js → PricingSettingsDialog-BuSlCbyZ.js} +1 -1
  11. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-zH758vfs.js → ProjectSettingsPage-CUHFkAhZ.js} +1 -1
  12. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CTH2wDs5.js → TraceabilityWorkspace-BmASq2gW.js} +1 -1
  13. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Csj6LiAt.js +68 -0
  14. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-B_lDDHn1.js → icons-vendor-VyTTl_ph.js} +1 -1
  15. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DIwDvCu5.js +2 -0
  16. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-hPPfVGQv.css +1 -0
  17. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-B3TJrD4O.js → react-vendor-CTC6vtln.js} +1 -1
  18. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-7f1j5wx3.js → traceability-9Mtvbwrg.js} +1 -1
  19. package/templates/.agents/dashboard/apps/frontend/dist/index.html +6 -6
  20. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +74 -10
  21. package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +44 -0
  22. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +103 -2
  23. package/templates/.agents/dashboard/apps/frontend/src/dashboard-capability-nav.css +11 -0
  24. package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +14 -0
  25. package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +3 -6
  26. package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +3 -2
  27. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +2 -2
  28. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.test.ts +60 -0
  29. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.tsx +26 -9
  30. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorNavigation.tsx +189 -0
  31. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +122 -2
  32. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +70 -155
  33. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +2 -1
  34. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +12 -4
  35. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +67 -24
  36. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +19 -4
  37. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +59 -0
  38. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +55 -2
  39. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts +25 -0
  40. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.ts +29 -0
  41. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +3 -2
  42. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +12 -2
  43. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +274 -246
  44. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +255 -227
  45. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +263 -235
  46. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.test.ts +282 -0
  47. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.ts +71 -0
  48. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-launch-progress.ts +18 -0
  49. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-stale-seed.ts +50 -0
  50. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +9 -6
  51. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +45 -73
  52. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +79 -2
  53. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-item-index.test.ts +56 -0
  54. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +26 -8
  55. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +45 -4
  56. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.mjs +58 -0
  57. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.test.mjs +81 -0
  58. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +171 -71
  59. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +152 -11
  60. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +4 -9
  61. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +9 -1
  62. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-loading.spec.ts +1 -1
  63. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-pagination.spec.ts +4 -0
  64. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-period-transition.spec.ts +238 -0
  65. package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +4 -0
  66. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +60 -17
  67. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  68. package/templates/.agents/requirements/comparative-audit.md +1 -1
  69. package/templates/.agents/requirements/context-engine.md +1 -1
  70. package/templates/.agents/requirements/cost-observability.md +1 -1
  71. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  72. package/templates/.agents/requirements/data-export.md +1 -1
  73. package/templates/.agents/requirements/design-system.md +1 -1
  74. package/templates/.agents/requirements/execution-engine.md +1 -1
  75. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  76. package/templates/.agents/requirements/model-orchestration.md +1 -1
  77. package/templates/.agents/requirements/public-distribution.md +1 -1
  78. package/templates/.agents/requirements/software-architecture.md +1 -1
  79. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  80. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  81. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  82. package/templates/.agents/runtime/bin/zaip.mjs +7 -7
  83. package/templates/.agents/runtime/checksums.sha256 +3 -3
  84. package/templates/.agents/runtime/provenance.json +3 -3
  85. package/templates/.agents/runtime/sbom.cdx.json +1595 -3491
  86. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +16 -0
  87. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +19 -20
  88. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.test.mjs +143 -0
  89. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +14 -0
  90. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +3 -1
  91. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +21 -0
  92. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +3 -0
  93. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +29 -0
  94. package/templates/template-manifest.json +539 -935
  95. package/templates/.agents/dashboard/.tmp-run-list.json +0 -254
  96. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DKwP1stV.js +0 -68
  97. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-B31GMG5O.css +0 -1
  98. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CuMcoUni.js +0 -2
@@ -25,6 +25,7 @@ export {
25
25
 
26
26
  import {
27
27
  dateRangeForPreset,
28
+ factualCostDateRange,
28
29
  initialOperationsDateRange,
29
30
  isDateInOperationPreset,
30
31
  isRunInOperationPreset,
@@ -130,10 +131,13 @@ export function OperationsPage({
130
131
  const [filterLoading, setFilterLoading] = useState(false);
131
132
  const filterLoadingTimer = useRef<number | null>(null);
132
133
  const searchInputRef = useRef<HTMLInputElement>(null);
133
- const defaultDateRange = useMemo(
134
- () => initialOperationsDateRange(data.tasks, Object.keys(data.summary.periods?.daily ?? {})),
135
- [data.summary.periods, data.tasks],
136
- );
134
+ const defaultDateRange = useMemo(() => {
135
+ const operationsRange = initialOperationsDateRange(
136
+ data.tasks,
137
+ Object.keys(data.summary.periods?.daily ?? {}),
138
+ );
139
+ return factualCostDateRange(factualCostPeriods?.day, operationsRange);
140
+ }, [data.summary.periods, data.tasks, factualCostPeriods?.day]);
137
141
  const initialDateRange = useMemo(() => dateRangeForPreset("this-month"), []);
138
142
  const [localDateRange, setLocalDateRange] = useState(() => initialDateRange);
139
143
  const [localDatePreset, setLocalDatePreset] = useState<OperationDatePreset>("all");
@@ -156,6 +160,17 @@ export function OperationsPage({
156
160
  },
157
161
  [isPeriodControlled, onDateChange, onPeriodChange],
158
162
  );
163
+ // A controlled parent initially owns the range selected before the factual
164
+ // Cost summary arrives. Once it does, synchronize only All Time's displayed
165
+ // coverage range; requestPeriodForOperations still omits both bounds.
166
+ useEffect(() => {
167
+ if (
168
+ datePreset !== "all" ||
169
+ (dateRange.start === defaultDateRange.start && dateRange.end === defaultDateRange.end)
170
+ )
171
+ return;
172
+ updatePeriod("all", defaultDateRange);
173
+ }, [datePreset, dateRange.end, dateRange.start, defaultDateRange, updatePeriod]);
159
174
  useEffect(() => {
160
175
  if (!isPeriodControlled && datePreset === "all") setLocalDateRange(defaultDateRange);
161
176
  }, [datePreset, defaultDateRange, isPeriodControlled]);
@@ -3,11 +3,13 @@ import {
3
3
  AGENT_INVOCATION_EXPORT_COLUMNS,
4
4
  COMPACT_LIFECYCLE_EXPORT_COLUMNS,
5
5
  COST_GROUP_EXPORT_COLUMNS,
6
+ DEVELOPER_EXPORT_COLUMNS,
6
7
  EXECUTION_EXPORT_COLUMNS,
7
8
  EXPORT_SUCCESS_TOAST_MS,
8
9
  exportAgentInvocationRows,
9
10
  exportCompactLifecycleRows,
10
11
  exportCostGroupRows,
12
+ exportDeveloperRows,
11
13
  exportExecutionRows,
12
14
  exportHeadersForView,
13
15
  exportPageSourceRows,
@@ -198,6 +200,63 @@ it("uses the compact work schema for Kanban and Work List", () => {
198
200
  ]);
199
201
  });
200
202
 
203
+ it("exports developer attribution with its factual schema and unavailable metrics intact", () => {
204
+ expect(DEVELOPER_EXPORT_COLUMNS).toEqual([
205
+ "account_id",
206
+ "login_snapshot",
207
+ "prd_count",
208
+ "spec_count",
209
+ "task_count",
210
+ "run_count",
211
+ "test_count",
212
+ "evidence_count",
213
+ "total_duration_hours",
214
+ "total_tokens",
215
+ "total_cost_brl",
216
+ "duration_covered_runs",
217
+ "token_covered_runs",
218
+ "brl_covered_runs",
219
+ ]);
220
+ expect(
221
+ exportDeveloperRows([
222
+ {
223
+ account_id: "42",
224
+ login_snapshot: "dev-42",
225
+ prd_count: 1,
226
+ spec_count: 2,
227
+ task_count: 3,
228
+ run_count: 4,
229
+ test_count: null,
230
+ evidence_count: null,
231
+ total_duration_ms: null,
232
+ total_tokens: null,
233
+ total_cost_brl: 1.5,
234
+ duration_covered_runs: 0,
235
+ token_covered_runs: 0,
236
+ brl_covered_runs: 4,
237
+ },
238
+ ]),
239
+ ).toEqual([
240
+ {
241
+ account_id: "42",
242
+ login_snapshot: "dev-42",
243
+ prd_count: 1,
244
+ spec_count: 2,
245
+ task_count: 3,
246
+ run_count: 4,
247
+ test_count: null,
248
+ evidence_count: null,
249
+ total_duration_hours: null,
250
+ total_tokens: null,
251
+ total_cost_brl: 1.5,
252
+ duration_covered_runs: 0,
253
+ token_covered_runs: 0,
254
+ brl_covered_runs: 4,
255
+ },
256
+ ]);
257
+ expect(exportHeadersForView("cost-developers", [])).toEqual(DEVELOPER_EXPORT_COLUMNS);
258
+ });
259
+
201
260
  it("normalizes Tasks and macros into the same populated work columns", () => {
202
261
  expect(
203
262
  exportWorkRows([
@@ -118,6 +118,26 @@ export const COST_GROUP_EXPORT_COLUMNS = [
118
118
  "duration_hours",
119
119
  ] as const;
120
120
 
121
+ // Cost Monitor developer attribution is a factual aggregate with coverage
122
+ // counters. Keep the workbook schema aligned with that table and retain null
123
+ // facts instead of allowing them to be inferred as zero by a spreadsheet.
124
+ export const DEVELOPER_EXPORT_COLUMNS = [
125
+ "account_id",
126
+ "login_snapshot",
127
+ "prd_count",
128
+ "spec_count",
129
+ "task_count",
130
+ "run_count",
131
+ "test_count",
132
+ "evidence_count",
133
+ "total_duration_hours",
134
+ "total_tokens",
135
+ "total_cost_brl",
136
+ "duration_covered_runs",
137
+ "token_covered_runs",
138
+ "brl_covered_runs",
139
+ ] as const;
140
+
121
141
  export const CONVERSATION_EXPORT_COLUMNS = [
122
142
  "conversation_id",
123
143
  "status",
@@ -334,6 +354,31 @@ export function exportCostGroupRows(
334
354
  });
335
355
  }
336
356
 
357
+ /** Normalize Cost Monitor developer facts into the fixed XLSX schema. */
358
+ export function exportDeveloperRows(
359
+ rows: readonly Record<string, unknown>[],
360
+ ): Record<string, unknown>[] {
361
+ return rows.map((row) => {
362
+ const durationMs = numberValue(row.total_duration_ms);
363
+ return {
364
+ account_id: row.account_id ?? null,
365
+ login_snapshot: row.login_snapshot ?? null,
366
+ prd_count: numberValue(row.prd_count),
367
+ spec_count: numberValue(row.spec_count),
368
+ task_count: numberValue(row.task_count),
369
+ run_count: numberValue(row.run_count),
370
+ test_count: numberValue(row.test_count),
371
+ evidence_count: numberValue(row.evidence_count),
372
+ total_duration_hours: durationMs === null ? null : durationMs / 3_600_000,
373
+ total_tokens: numberValue(row.total_tokens),
374
+ total_cost_brl: numberValue(row.total_cost_brl),
375
+ duration_covered_runs: numberValue(row.duration_covered_runs),
376
+ token_covered_runs: numberValue(row.token_covered_runs),
377
+ brl_covered_runs: numberValue(row.brl_covered_runs),
378
+ };
379
+ });
380
+ }
381
+
337
382
  export function exportConversationRows(
338
383
  rows: readonly Record<string, unknown>[],
339
384
  ): Record<string, unknown>[] {
@@ -480,6 +525,7 @@ export function exportHeadersForView(
480
525
  const isCompactLifecycleView =
481
526
  /-(?:tasks|specs|prds|conversations)$/.test(view) && !isOperationsConversationView;
482
527
  const isCostGroupView = /-(?:agents|models|providers)$/.test(view);
528
+ const isDeveloperView = view === "cost-developers";
483
529
  const isChangeView = view === "operations-changes";
484
530
  const isDecisionView = view === "operations-decisions";
485
531
  if (isPeriodView) headers.push(...PERIOD_EXPORT_COLUMNS);
@@ -489,6 +535,7 @@ export function exportHeadersForView(
489
535
  if (isAgentInvocationView) headers.push(...AGENT_INVOCATION_EXPORT_COLUMNS);
490
536
  if (isCompactLifecycleView) headers.push(...COMPACT_LIFECYCLE_EXPORT_COLUMNS);
491
537
  if (isCostGroupView) headers.push(...COST_GROUP_EXPORT_COLUMNS);
538
+ if (isDeveloperView) headers.push(...DEVELOPER_EXPORT_COLUMNS);
492
539
  if (isOperationsConversationView) headers.push(...CONVERSATION_EXPORT_COLUMNS);
493
540
  if (isChangeView) headers.push(...CHANGE_EXPORT_COLUMNS);
494
541
  if (isDecisionView) headers.push(...DECISION_EXPORT_COLUMNS);
@@ -502,6 +549,7 @@ export function exportHeadersForView(
502
549
  isAgentInvocationView ||
503
550
  isCompactLifecycleView ||
504
551
  isCostGroupView ||
552
+ isDeveloperView ||
505
553
  isOperationsConversationView ||
506
554
  isChangeView ||
507
555
  isDecisionView;
@@ -545,6 +593,7 @@ export function ExcelExportAction({ filters, pageSource, rows, view }: ExcelExpo
545
593
  const isCompactLifecycleView =
546
594
  /-(?:tasks|specs|prds|conversations)$/.test(view) && !isOperationsConversationView;
547
595
  const isCostGroupView = /-(?:agents|models|providers)$/.test(view);
596
+ const isDeveloperView = view === "cost-developers";
548
597
  const isChangeView = view === "operations-changes";
549
598
  const isDecisionView = view === "operations-decisions";
550
599
  const createSnapshot = async () => {
@@ -584,7 +633,9 @@ export function ExcelExportAction({ filters, pageSource, rows, view }: ExcelExpo
584
633
  ? exportCompactLifecycleRows
585
634
  : isCostGroupView
586
635
  ? exportCostGroupRows
587
- : exportRowsWithDurationHours,
636
+ : isDeveloperView
637
+ ? exportDeveloperRows
638
+ : exportRowsWithDurationHours,
588
639
  );
589
640
  return;
590
641
  }
@@ -610,7 +661,9 @@ export function ExcelExportAction({ filters, pageSource, rows, view }: ExcelExpo
610
661
  ? exportCompactLifecycleRows
611
662
  : isCostGroupView
612
663
  ? exportCostGroupRows
613
- : exportRowsWithDurationHours
664
+ : isDeveloperView
665
+ ? exportDeveloperRows
666
+ : exportRowsWithDurationHours
614
667
  )(rows.slice(offset, offset + 500));
615
668
  },
616
669
  });
@@ -1,6 +1,7 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import {
3
3
  dateRangeForPreset,
4
+ factualCostDateRange,
4
5
  initialOperationsDateRange,
5
6
  initialTaskDateRange,
6
7
  isDateInOperationPreset,
@@ -34,6 +35,30 @@ describe("operation date ranges", () => {
34
35
  });
35
36
  });
36
37
 
38
+ it("uses the first factual Cost Monitor day for All Time while ending today", () => {
39
+ expect(
40
+ factualCostDateRange(
41
+ [
42
+ { key: "2026-06-01", estimated_brl: null, estimated_usd: null },
43
+ { key: "2026-06-02", estimated_brl: 0, estimated_usd: 0 },
44
+ { key: "2026-06-03", estimated_brl: 1.25, estimated_usd: 0.24 },
45
+ ],
46
+ { start: "2026-07-10", end: "2026-07-14" },
47
+ today,
48
+ ),
49
+ ).toEqual({ start: "2026-06-02", end: "2026-07-14" });
50
+ });
51
+
52
+ it("keeps the Operations range when no factual Cost Monitor day is available", () => {
53
+ expect(
54
+ factualCostDateRange(
55
+ [{ key: "2026-06-01", estimated_brl: null, estimated_usd: null }],
56
+ { start: "2026-07-10", end: "2026-07-14" },
57
+ today,
58
+ ),
59
+ ).toEqual({ start: "2026-07-10", end: "2026-07-14" });
60
+ });
61
+
37
62
  it.each([
38
63
  ["today", "2026-07-14", "2026-07-14"],
39
64
  ["yesterday", "2026-07-13", "2026-07-13"],
@@ -17,6 +17,35 @@ export interface OperationDateRange {
17
17
  end: string;
18
18
  }
19
19
 
20
+ /** A daily Cost Monitor group with a factual monetary measurement. */
21
+ export interface FactualCostDay {
22
+ key: string;
23
+ estimated_brl: number | null;
24
+ estimated_usd: number | null;
25
+ }
26
+
27
+ /**
28
+ * All Time is unbounded for requests, but its disabled date controls should
29
+ * describe the actual Cost Monitor coverage rather than an Operations record.
30
+ */
31
+ export function factualCostDateRange(
32
+ days: readonly FactualCostDay[] | undefined,
33
+ fallback: OperationDateRange,
34
+ today = new Date(),
35
+ ): OperationDateRange {
36
+ const firstMeasuredDay = days
37
+ ?.map((day) => day.key)
38
+ .filter(
39
+ (key, index, keys) =>
40
+ /^\d{4}-\d{2}-\d{2}$/.test(key) &&
41
+ (days[index]!.estimated_brl !== null || days[index]!.estimated_usd !== null),
42
+ )
43
+ .sort()[0];
44
+ return firstMeasuredDay === undefined
45
+ ? fallback
46
+ : { start: firstMeasuredDay, end: toDateInputValue(today) };
47
+ }
48
+
20
49
  export function initialTaskDateRange(
21
50
  tasks: readonly { created_at: string }[],
22
51
  today = new Date(),
@@ -36,7 +36,7 @@ describe("Operations persisted aggregate display", () => {
36
36
  expect(totals).toMatchObject({ duration_ms: null, tokens: 0, cost_brl: 0 });
37
37
  });
38
38
 
39
- it("preserves unavailable aggregate totals instead of rendering coerced zeroes", () => {
39
+ it("preserves unavailable aggregate totals and renders zero only for an empty population", () => {
40
40
  const overview = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
41
41
 
42
42
  expect(overview).toContain("overviewMetrics?.duration_ms ??");
@@ -48,7 +48,8 @@ describe("Operations persisted aggregate display", () => {
48
48
  expect(overview).toContain(
49
49
  "durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: totalCostMetric",
50
50
  );
51
- expect(overview).toContain("formatEntityDuration(averageDuration, locale)");
51
+ expect(overview).toContain("formatSummaryMetricValue(\n averageDuration,");
52
+ expect(overview).toContain('populationCount === 0 ? "0"');
52
53
  expect(overview).not.toContain("allPhaseMetrics.tokens ?? 0");
53
54
  expect(overview).not.toContain("executionMetrics.durationMs ?? 0");
54
55
  });
@@ -50,6 +50,15 @@ describe("overview period filter", () => {
50
50
  expect(shouldRenderOperationsContent(true)).toBe(false);
51
51
  });
52
52
 
53
+ it("synchronizes the controlled All Time display after factual cost coverage arrives", () => {
54
+ const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
55
+
56
+ expect(source).toContain('datePreset !== "all"');
57
+ expect(source).toContain("dateRange.start === defaultDateRange.start");
58
+ expect(source).toContain('updatePeriod("all", defaultDateRange);');
59
+ expect(source).toContain("requestPeriodForOperations still omits both bounds");
60
+ });
61
+
53
62
  it("derives all big-number KPIs from the period-filtered global aggregate", () => {
54
63
  const source = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
55
64
  const helpers = readFileSync(
@@ -81,8 +90,9 @@ describe("overview period filter", () => {
81
90
 
82
91
  expect(source).toContain('currency: "BRL" | "USD"');
83
92
  expect(source).toContain("const selectedCurrencyCost =");
84
- expect(source).toContain("formatCurrency(averageCost, currency, locale)");
85
- expect(source).toContain("formatRoundedCurrency(totalCostMetric, currency, locale)");
93
+ expect(source).toContain("formatCurrency(value, currency, locale)");
94
+ expect(source).toContain("formatSummaryMetricValue(\n totalCostMetric,");
95
+ expect(source).toContain("formatRoundedCurrency(value, currency, locale)");
86
96
  expect(source).toContain("const topEntitiesCost =");
87
97
  expect(topPanel).toContain("formatCurrency(topCost, currency, locale)");
88
98
  expect(periods).toContain("resolveRunCost?: ((runId: string) => number | null)");