@zaip-ai/cli 1.3.1 → 1.3.4

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 (83) hide show
  1. package/LICENSE +6 -3
  2. package/README.md +11 -4
  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 +403 -383
  8. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-ovxurkIk.js → CostCalculationGuidePage-BZWjXQB-.js} +1 -1
  9. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-BgVgrfhQ.js → DashboardHelpDialog-D8qqeIPE.js} +58 -1
  10. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-vSvvOHQp.js → PricingSettingsDialog-Cm12_A0v.js} +1 -1
  11. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-zH758vfs.js → ProjectSettingsPage-DxO9F8B4.js} +1 -1
  12. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-DLn-Mz2M.js → TraceabilityWorkspace-_x0twOcS.js} +1 -1
  13. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cpp8xFij.js +68 -0
  14. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-B_lDDHn1.js → icons-vendor-CR4Fbf3g.js} +1 -1
  15. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-ncC1rxap.js +2 -0
  16. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-B3TJrD4O.js → react-vendor-DRJQbKnp.js} +1 -1
  17. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-7f1j5wx3.js → traceability-CMrDYqjR.js} +1 -1
  18. package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
  19. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +48 -3
  20. package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +44 -0
  21. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +92 -1
  22. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +2 -2
  23. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.test.ts +60 -0
  24. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.tsx +26 -9
  25. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorNavigation.tsx +189 -0
  26. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +122 -2
  27. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +70 -155
  28. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +59 -0
  29. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +55 -2
  30. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +274 -246
  31. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +255 -227
  32. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +263 -235
  33. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.test.ts +282 -0
  34. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.ts +71 -0
  35. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +70 -0
  36. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +74 -7
  37. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-launch-progress.ts +18 -0
  38. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-stale-seed.ts +50 -0
  39. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +9 -6
  40. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +45 -73
  41. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +79 -2
  42. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-item-index.test.ts +56 -0
  43. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +26 -8
  44. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +45 -4
  45. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.mjs +58 -0
  46. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.test.mjs +81 -0
  47. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +171 -71
  48. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +152 -11
  49. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +4 -9
  50. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +9 -1
  51. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-period-transition.spec.ts +232 -0
  52. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +26 -5
  53. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  54. package/templates/.agents/requirements/comparative-audit.md +1 -1
  55. package/templates/.agents/requirements/context-engine.md +1 -1
  56. package/templates/.agents/requirements/cost-observability.md +1 -1
  57. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  58. package/templates/.agents/requirements/data-export.md +1 -1
  59. package/templates/.agents/requirements/design-system.md +1 -1
  60. package/templates/.agents/requirements/execution-engine.md +1 -1
  61. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  62. package/templates/.agents/requirements/model-orchestration.md +1 -1
  63. package/templates/.agents/requirements/public-distribution.md +1 -1
  64. package/templates/.agents/requirements/software-architecture.md +1 -1
  65. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  66. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  67. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  68. package/templates/.agents/runtime/bin/zaip.mjs +7 -7
  69. package/templates/.agents/runtime/checksums.sha256 +3 -3
  70. package/templates/.agents/runtime/provenance.json +3 -3
  71. package/templates/.agents/runtime/sbom.cdx.json +1595 -3491
  72. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +16 -0
  73. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +19 -20
  74. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.test.mjs +143 -0
  75. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +14 -0
  76. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +3 -1
  77. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +21 -0
  78. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +3 -0
  79. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +44 -0
  80. package/templates/template-manifest.json +536 -932
  81. package/templates/.agents/dashboard/.tmp-run-list.json +0 -254
  82. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DKwP1stV.js +0 -68
  83. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CZQlsLV9.js +0 -2
@@ -74,11 +74,11 @@ describe("atomic Cost snapshot loading", () => {
74
74
  expect(initialLoad).not.toContain("api.snapshot(currency, period)");
75
75
  });
76
76
 
77
- it("retries a failed Cost snapshot through refresh instead of a summary-only Cost request", () => {
77
+ it("retries a failed Cost snapshot through its summary request", () => {
78
78
  const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
79
79
  const retry = app.slice(app.indexOf("const retryLastLoad"), app.indexOf("const setupRoute"));
80
80
 
81
- expect(retry).toContain('if (failedArea === "costs") void refresh();');
81
+ expect(retry).toContain('if (failedArea === "costs") void loadCostSummary();');
82
82
  expect(retry).not.toContain("loadCosts");
83
83
  });
84
84
 
@@ -0,0 +1,60 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { loadCostDeveloperAttribution } from "./CostDeveloperAttributionPanel.js";
3
+
4
+ describe("loadCostDeveloperAttribution", () => {
5
+ it("requests the active period and returns every row supplied by the API", async () => {
6
+ const rows = Array.from({ length: 11 }, (_, index) => ({
7
+ account_id: String(index + 1),
8
+ login_snapshot: `dev-${index + 1}`,
9
+ prd_count: 0,
10
+ spec_count: 0,
11
+ task_count: 1,
12
+ run_count: 1,
13
+ test_count: null,
14
+ evidence_count: null,
15
+ total_duration_ms: null,
16
+ total_tokens: null,
17
+ total_cost_brl: null,
18
+ duration_covered_runs: 0,
19
+ token_covered_runs: 0,
20
+ brl_covered_runs: 0,
21
+ }));
22
+ const fetcher = vi
23
+ .fn<typeof fetch>()
24
+ .mockResolvedValue(new Response(JSON.stringify({ rows }), { status: 200 }));
25
+
26
+ await expect(
27
+ loadCostDeveloperAttribution({
28
+ from: "2026-08-01",
29
+ to: "2026-08-31",
30
+ fetcher,
31
+ }),
32
+ ).resolves.toEqual(rows);
33
+ expect(fetcher).toHaveBeenCalledWith("/api/v2/developers?from=2026-08-01&to=2026-08-31", {});
34
+ });
35
+
36
+ it("keeps the embedded all-time population unbounded and returns all 25 developers", async () => {
37
+ const rows = Array.from({ length: 25 }, (_, index) => ({
38
+ account_id: String(index + 1),
39
+ login_snapshot: `dev-${index + 1}`,
40
+ prd_count: 0,
41
+ spec_count: 0,
42
+ task_count: 1,
43
+ run_count: 1,
44
+ test_count: null,
45
+ evidence_count: null,
46
+ total_duration_ms: null,
47
+ total_tokens: null,
48
+ total_cost_brl: null,
49
+ duration_covered_runs: 0,
50
+ token_covered_runs: 0,
51
+ brl_covered_runs: 0,
52
+ }));
53
+ const fetcher = vi
54
+ .fn<typeof fetch>()
55
+ .mockResolvedValue(new Response(JSON.stringify({ rows }), { status: 200 }));
56
+
57
+ await expect(loadCostDeveloperAttribution({ fetcher })).resolves.toHaveLength(25);
58
+ expect(fetcher).toHaveBeenCalledWith("/api/v2/developers", {});
59
+ });
60
+ });
@@ -2,6 +2,28 @@ import { useEffect, useState } from "react";
2
2
  import { type CostDeveloperAttributionRow, CostDeveloperAttributionTable } from "./CostTables.js";
3
3
  import type { CostLocale } from "./cost-monitor-copy.js";
4
4
 
5
+ export async function loadCostDeveloperAttribution({
6
+ from,
7
+ to,
8
+ signal,
9
+ fetcher = fetch,
10
+ }: {
11
+ from?: string;
12
+ to?: string;
13
+ signal?: AbortSignal;
14
+ fetcher?: typeof fetch;
15
+ }): Promise<readonly CostDeveloperAttributionRow[]> {
16
+ const params = new URLSearchParams();
17
+ if (from) params.set("from", from);
18
+ if (to) params.set("to", to);
19
+ const response = await fetcher(`/api/v2/developers${params.size === 0 ? "" : `?${params}`}`, {
20
+ ...(signal === undefined ? {} : { signal }),
21
+ });
22
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
23
+ const payload = (await response.json()) as { rows?: CostDeveloperAttributionRow[] };
24
+ return payload.rows ?? [];
25
+ }
26
+
5
27
  /** Cost-specific rendering of the factual developer aggregate endpoint. */
6
28
  export function CostDeveloperAttributionPanel({
7
29
  from,
@@ -19,18 +41,13 @@ export function CostDeveloperAttributionPanel({
19
41
  }>({ loading: true, error: null, rows: [] });
20
42
  useEffect(() => {
21
43
  const controller = new AbortController();
22
- const params = new URLSearchParams();
23
- if (from) params.set("from", from);
24
- if (to) params.set("to", to);
25
44
  setState((previous) => ({ ...previous, loading: true, error: null }));
26
- fetch(`/api/v2/developers${params.size === 0 ? "" : `?${params}`}`, {
45
+ loadCostDeveloperAttribution({
46
+ ...(from === undefined ? {} : { from }),
47
+ ...(to === undefined ? {} : { to }),
27
48
  signal: controller.signal,
28
49
  })
29
- .then(async (response) => {
30
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
31
- return response.json() as Promise<{ rows?: CostDeveloperAttributionRow[] }>;
32
- })
33
- .then((payload) => setState({ loading: false, error: null, rows: payload.rows ?? [] }))
50
+ .then((rows) => setState({ loading: false, error: null, rows }))
34
51
  .catch((error: unknown) => {
35
52
  if ((error as { name?: string }).name !== "AbortError")
36
53
  setState({
@@ -0,0 +1,189 @@
1
+ import type { CostMonitorProjection } from "../contracts.js";
2
+ import { type CostFilterState, CostFilters, type CostPeriod } from "./CostFilters.js";
3
+ import { ChevronDownIcon, ListFilterIcon, LocaleFlag, SettingsIcon } from "./CostMonitorIcons.js";
4
+ import type { CostCurrency, CostLocale, costCopy } from "./cost-monitor-copy.js";
5
+
6
+ const zaipLogoUrl = new URL("../../../../../config/src/logo_novo_azul.png", import.meta.url).href;
7
+
8
+ type CostNavigationCopy = (typeof costCopy)[CostLocale];
9
+
10
+ export type CostNavigationPopup = "filters" | "locale" | "settings" | null;
11
+
12
+ export function toggleCostNavigationPopup(
13
+ popup: CostNavigationPopup,
14
+ requestedPopup: Exclude<CostNavigationPopup, null>,
15
+ ): CostNavigationPopup {
16
+ return popup === requestedPopup ? null : requestedPopup;
17
+ }
18
+
19
+ export function CostMonitorNavigation({
20
+ currency,
21
+ filters,
22
+ loading,
23
+ locale,
24
+ onCurrencyChange,
25
+ onFiltersChange,
26
+ onLocaleChange,
27
+ onPopupChange,
28
+ onPeriodChange,
29
+ onRefresh,
30
+ period,
31
+ popup,
32
+ text,
33
+ updatedLabel,
34
+ filtersAvailable,
35
+ }: {
36
+ currency: CostCurrency;
37
+ filters: CostFilterState;
38
+ filtersAvailable: CostMonitorProjection["filters_available"];
39
+ loading: boolean;
40
+ locale: CostLocale;
41
+ onCurrencyChange: (currency: CostCurrency) => void;
42
+ onFiltersChange: (filters: CostFilterState) => void;
43
+ onLocaleChange: (locale: CostLocale) => void;
44
+ onPopupChange: (popup: CostNavigationPopup) => void;
45
+ onPeriodChange: (period: CostPeriod) => void;
46
+ onRefresh: () => void;
47
+ period: CostPeriod;
48
+ popup: CostNavigationPopup;
49
+ text: CostNavigationCopy;
50
+ updatedLabel: string;
51
+ }) {
52
+ const filtersOpen = popup === "filters";
53
+ const localeOpen = popup === "locale";
54
+ const settingsOpen = popup === "settings";
55
+ const changeLocale = (next: CostLocale) => {
56
+ onLocaleChange(next);
57
+ };
58
+
59
+ return (
60
+ <>
61
+ <nav aria-label="Navegação do Cost Monitor" className="cost-monitor-nav">
62
+ <div className="cost-monitor-brand">
63
+ <strong className="cost-monitor-title">{text.title}</strong>
64
+ <small className="cost-last-updated">{updatedLabel}</small>
65
+ </div>
66
+ <img alt="ZAIP" className="cost-monitor-logo" src={zaipLogoUrl} />
67
+ <div className="cost-nav-actions">
68
+ <button
69
+ aria-label={text.refresh}
70
+ className="cost-nav-icon cost-refresh-action"
71
+ disabled={loading}
72
+ onClick={onRefresh}
73
+ type="button"
74
+ >
75
+ ↻
76
+ </button>
77
+ <div className="cost-nav-popup-anchor cost-filter-action">
78
+ <button
79
+ className={filtersOpen ? "cost-nav-button is-active" : "cost-nav-button"}
80
+ onClick={() => onPopupChange(toggleCostNavigationPopup(popup, "filters"))}
81
+ type="button"
82
+ >
83
+ <ListFilterIcon /> {text.filters}
84
+ </button>
85
+ {filtersOpen ? (
86
+ <div className="cost-nav-popup cost-nav-filter-popup">
87
+ <CostFilters
88
+ available={filtersAvailable}
89
+ hideQuery={false}
90
+ locale={locale}
91
+ onChange={onFiltersChange}
92
+ value={filters}
93
+ />
94
+ </div>
95
+ ) : null}
96
+ </div>
97
+ <div className="cost-nav-popup-anchor cost-locale-action">
98
+ <button
99
+ className={localeOpen ? "cost-nav-button is-active" : "cost-nav-button"}
100
+ onClick={() => onPopupChange(toggleCostNavigationPopup(popup, "locale"))}
101
+ type="button"
102
+ >
103
+ <LocaleFlag locale={locale} />
104
+ {locale === "pt-BR" ? "PT-BR" : "EN-US"}
105
+ <ChevronDownIcon />
106
+ </button>
107
+ {localeOpen ? (
108
+ <div className="cost-nav-popup cost-nav-locale-popup">
109
+ <button onClick={() => changeLocale("pt-BR")} type="button">
110
+ <LocaleFlag locale="pt-BR" /> Português do Brasil {locale === "pt-BR" ? "✓" : ""}
111
+ </button>
112
+ <button onClick={() => changeLocale("en-US")} type="button">
113
+ <LocaleFlag locale="en-US" /> English {locale === "en-US" ? "✓" : ""}
114
+ </button>
115
+ </div>
116
+ ) : null}
117
+ </div>
118
+ <div className="cost-nav-popup-anchor cost-settings-action">
119
+ <button
120
+ aria-label={text.settings}
121
+ className={settingsOpen ? "cost-nav-icon is-active" : "cost-nav-icon"}
122
+ onClick={() => onPopupChange(toggleCostNavigationPopup(popup, "settings"))}
123
+ type="button"
124
+ >
125
+ <SettingsIcon />
126
+ </button>
127
+ {settingsOpen ? (
128
+ <div className="cost-nav-popup cost-nav-settings-popup">
129
+ <div className="cost-mobile-settings">
130
+ <small className="cost-mobile-updated">{updatedLabel}</small>
131
+ <button disabled={loading} onClick={onRefresh} type="button">
132
+ ↻{" "}
133
+ {loading ? (locale === "pt-BR" ? "Atualizando…" : "Refreshing…") : text.refresh}
134
+ </button>
135
+ <label>
136
+ <span>{locale === "pt-BR" ? "Idioma" : "Language"}</span>
137
+ <select
138
+ onChange={(event) => changeLocale(event.target.value as CostLocale)}
139
+ value={locale}
140
+ >
141
+ <option value="pt-BR">Português do Brasil</option>
142
+ <option value="en-US">English</option>
143
+ </select>
144
+ </label>
145
+ <div className="cost-mobile-filters">
146
+ <strong>{text.filters}</strong>
147
+ <CostFilters
148
+ available={filtersAvailable}
149
+ hideQuery={false}
150
+ locale={locale}
151
+ onChange={onFiltersChange}
152
+ value={filters}
153
+ />
154
+ </div>
155
+ </div>
156
+ <label>
157
+ <span>{text.currency}</span>
158
+ <select
159
+ onChange={(event) => onCurrencyChange(event.target.value as CostCurrency)}
160
+ value={currency}
161
+ >
162
+ <option value="BRL">BRL · R$</option>
163
+ <option value="USD">USD · $</option>
164
+ </select>
165
+ </label>
166
+ </div>
167
+ ) : null}
168
+ </div>
169
+ </div>
170
+ </nav>
171
+ <header className="cost-hero">
172
+ <p className="cost-hero-description">{text.subtitle}</p>
173
+ <label className="cost-period">
174
+ <span>{text.period}</span>
175
+ <select
176
+ onChange={(event) => onPeriodChange(event.target.value as CostPeriod)}
177
+ value={period}
178
+ >
179
+ <option value="all">{text.allTime}</option>
180
+ <option value="7">{text.last7}</option>
181
+ <option value="30">{text.last30}</option>
182
+ <option value="90">{text.last90}</option>
183
+ <option value="month">{text.thisMonth}</option>
184
+ </select>
185
+ </label>
186
+ </header>
187
+ </>
188
+ );
189
+ }
@@ -1,4 +1,6 @@
1
1
  import { readFileSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { fileURLToPath } from "node:url";
2
4
  import { describe, expect, it } from "vitest";
3
5
  import {
4
6
  allPhaseMetricTotals,
@@ -24,6 +26,7 @@ import {
24
26
  matchesPeriodEntity,
25
27
  resolveCompactCostPageRange,
26
28
  resolveCostGroupPageRange,
29
+ resolveDeveloperAttributionRange,
27
30
  selectDimensionalCostRows,
28
31
  visibleExecutionRows,
29
32
  } from "./CostMonitorPage.js";
@@ -33,13 +36,110 @@ import {
33
36
  reconcileCostGroupTotalsWithCards,
34
37
  } from "./use-cost-group-page.js";
35
38
 
39
+ declare global {
40
+ interface Window {
41
+ __costMonitorProbe: { localeChanges: number };
42
+ }
43
+ }
44
+
36
45
  describe("cost monitor navigation", () => {
46
+ it("keeps an open filter popup through the embedded DOM cycle", async () => {
47
+ const browserRequire = createRequire(
48
+ fileURLToPath(new URL("../../../../tests/e2e/package.json", import.meta.url)),
49
+ );
50
+ const esbuild = browserRequire("esbuild");
51
+ const { chromium, expect: expectPlaywright } = browserRequire("@playwright/test");
52
+ const harness = await esbuild.build({
53
+ bundle: true,
54
+ define: { "import.meta.url": '"http://localhost/"' },
55
+ format: "iife",
56
+ loader: { ".css": "text", ".png": "dataurl" },
57
+ platform: "browser",
58
+ stdin: {
59
+ contents: `
60
+ import { createRoot } from "react-dom/client";
61
+ import React, { useState } from "react";
62
+ import { CostMonitorPage } from "../../../modules/cost-monitor/src/react/CostMonitorPage.js";
63
+ const coverage = { events: 0, tokens: 0, usd: 0, brl: 0 };
64
+ const data = {
65
+ currency: "BRL",
66
+ pricing: { catalog_updated_at: null, fx_rate: null, conversion_applied: false },
67
+ filters: { from: null, to: null },
68
+ overview: { task_count: 0, run_count: 0, event_count: 0, total_tokens: 0, estimated_usd: 0, estimated_brl: 0, recorded_usd: 0, recorded_brl: 0, average_run_cost_usd: null, average_run_cost_brl: null, average_run_duration_ms: null, known_tokens_per_cycle: null, top_10_token_share: null, coverage },
69
+ filters_available: { providers: ["OpenAI"], agents: [], models: [], statuses: [], priorities: [], risks: [], phases: [], origins: [], work_types: [] },
70
+ configured_agents: [], usage: {}, origins: {}, prds: [], specs: [], runs: [],
71
+ groups: { conversations: [], tasks: [], providers: [], agents: [], models: [], daily: [], monthly: [], annual: [] },
72
+ };
73
+ const probe = { localeChanges: 0 };
74
+ Object.assign(window, { __costMonitorProbe: probe });
75
+ function Harness() {
76
+ const [embedded, setEmbedded] = useState(false);
77
+ return <>
78
+ <button onClick={() => setEmbedded((current) => !current)} type="button">Alternar incorporado</button>
79
+ <CostMonitorPage data={data as any} embedded={embedded} lastUpdatedAt={null} locale="pt-BR" loading={false} loadPeriod={async () => data as any} onLocaleChange={() => { probe.localeChanges += 1; }} onOpenTrace={() => {}} onRefresh={() => {}} />
80
+ </>;
81
+ }
82
+ createRoot(document.getElementById("root")).render(<Harness />);
83
+ `,
84
+ loader: "tsx",
85
+ resolveDir: fileURLToPath(new URL("../../../../apps/frontend/src", import.meta.url)),
86
+ sourcefile: "CostMonitorPage.browser-harness.tsx",
87
+ },
88
+ write: false,
89
+ });
90
+ const browser = await chromium.launch({ headless: true });
91
+ try {
92
+ const page = await browser.newPage();
93
+ const pageErrors: string[] = [];
94
+ page.on("pageerror", (error: Error) => pageErrors.push(error.message));
95
+ await page.setContent('<div id="root"></div>');
96
+ await page.addScriptTag({ content: harness.outputFiles[0].text });
97
+ await page.waitForTimeout(100);
98
+ expect(pageErrors).toEqual([]);
99
+
100
+ const navigation = page.getByLabel("Navegação do Cost Monitor");
101
+ await navigation.getByRole("button", { name: "Filtros" }).click();
102
+ await expectPlaywright(page.locator(".cost-nav-filter-popup")).toBeVisible();
103
+ await page.getByRole("button", { name: "Alternar incorporado" }).click();
104
+ await expectPlaywright(page.getByLabel("Navegação do Cost Monitor")).toHaveCount(0);
105
+ await page.getByRole("button", { name: "Alternar incorporado" }).click();
106
+ await expectPlaywright(page.locator(".cost-nav-filter-popup")).toBeVisible();
107
+ await navigation.getByRole("button", { name: /PT-BR/ }).click();
108
+ await page.getByRole("button", { name: /English/ }).click();
109
+ await expectPlaywright
110
+ .poll(() => page.evaluate(() => window.__costMonitorProbe.localeChanges))
111
+ .toBe(1);
112
+ } finally {
113
+ await browser.close();
114
+ }
115
+ });
116
+
37
117
  it("hides Excel export from the overview while retaining it on tabular views", () => {
38
118
  expect(isCostViewExportEligible("overview")).toBe(false);
39
119
  expect(isCostViewExportEligible("daily")).toBe(true);
40
120
  expect(isCostViewExportEligible("agentCalls")).toBe(true);
41
121
  });
42
122
 
123
+ it("keeps embedded developers all-time despite residual local filters", () => {
124
+ const monthRange = { from: "2026-08-01", to: "2026-08-31" };
125
+ expect(
126
+ resolveDeveloperAttributionRange({
127
+ embedded: true,
128
+ runPageRange: monthRange,
129
+ }),
130
+ ).toBeUndefined();
131
+ expect(
132
+ resolveDeveloperAttributionRange({
133
+ embedded: true,
134
+ globalDateRange: { start: "2026-07-01", end: "2026-08-31" },
135
+ runPageRange: { from: "2026-07-01", to: "2026-08-31" },
136
+ }),
137
+ ).toEqual({ from: "2026-07-01", to: "2026-08-31" });
138
+ expect(resolveDeveloperAttributionRange({ embedded: false, runPageRange: monthRange })).toEqual(
139
+ monthRange,
140
+ );
141
+ });
142
+
43
143
  it("keeps the embedded default group pager on the all-time snapshot without explicit filters", () => {
44
144
  const monthRange = costPeriodDateRange(defaultCostPeriod, new Date("2026-08-17T12:00:00.000Z"));
45
145
  expect(
@@ -365,16 +465,36 @@ describe("cost monitor navigation", () => {
365
465
  expect(content).toContain('{view === "developers" ? developerPanel : null}');
366
466
  });
367
467
 
468
+ it("prepares the complete developer API population with the same all-time range as the table", () => {
469
+ const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
470
+ const exportSection = page.slice(
471
+ page.indexOf("const developerExportSource"),
472
+ page.indexOf("const costGroupExportSource"),
473
+ );
474
+
475
+ expect(exportSection).toContain('view === "developers"');
476
+ expect(exportSection).toContain("loadCostDeveloperAttribution");
477
+ expect(exportSection).toContain(
478
+ "...(developerAttributionRange === undefined ? {} : developerAttributionRange)",
479
+ );
480
+ expect(exportSection).toContain("totalRows: developerRows.length");
481
+ expect(page).toContain("const developerAttributionRange = resolveDeveloperAttributionRange");
482
+ expect(page).toContain("...(developerAttributionRange === undefined");
483
+ expect(page).toMatch(
484
+ /agentInvocationExportSource \?\?\s*developerExportSource \?\?\s*costGroupExportSource/,
485
+ );
486
+ });
487
+
368
488
  it("prepares Agent Invocations from every server page for export", () => {
369
489
  const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
370
490
  const exportSection = page.slice(
371
491
  page.indexOf("const agentInvocationExportSource"),
372
- page.indexOf("const costGroupExportSource"),
492
+ page.indexOf("const developerExportSource"),
373
493
  );
374
494
  expect(page).toContain('view === "agentCalls" && serverPagingEligible');
375
495
  expect(page).toContain("agentInvocationExportSource");
376
496
  expect(page).toMatch(
377
- /pageSource=\{\s*compactExportSource \?\? agentInvocationExportSource \?\? costGroupExportSource\s*\}/,
497
+ /pageSource=\{\s*compactExportSource \?\?\s*agentInvocationExportSource \?\?\s*developerExportSource \?\?\s*costGroupExportSource\s*\}/,
378
498
  );
379
499
  expect(page).toContain("if (page.runs.length === 0) return");
380
500
  expect(exportSection.match(/limit: 100/g)).toHaveLength(2);