@zaip-ai/cli 1.3.2 → 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 (81) 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 +401 -381
  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-BXy6nti1.js → DashboardHelpDialog-D8qqeIPE.js} +30 -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-CTH2wDs5.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-read-model-launch-progress.ts +18 -0
  36. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-stale-seed.ts +50 -0
  37. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +9 -6
  38. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +45 -73
  39. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +79 -2
  40. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-item-index.test.ts +56 -0
  41. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +26 -8
  42. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +45 -4
  43. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.mjs +58 -0
  44. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.test.mjs +81 -0
  45. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +171 -71
  46. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +152 -11
  47. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +4 -9
  48. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +9 -1
  49. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-period-transition.spec.ts +232 -0
  50. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +26 -5
  51. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  52. package/templates/.agents/requirements/comparative-audit.md +1 -1
  53. package/templates/.agents/requirements/context-engine.md +1 -1
  54. package/templates/.agents/requirements/cost-observability.md +1 -1
  55. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  56. package/templates/.agents/requirements/data-export.md +1 -1
  57. package/templates/.agents/requirements/design-system.md +1 -1
  58. package/templates/.agents/requirements/execution-engine.md +1 -1
  59. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  60. package/templates/.agents/requirements/model-orchestration.md +1 -1
  61. package/templates/.agents/requirements/public-distribution.md +1 -1
  62. package/templates/.agents/requirements/software-architecture.md +1 -1
  63. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  64. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  65. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  66. package/templates/.agents/runtime/bin/zaip.mjs +7 -7
  67. package/templates/.agents/runtime/checksums.sha256 +3 -3
  68. package/templates/.agents/runtime/provenance.json +3 -3
  69. package/templates/.agents/runtime/sbom.cdx.json +1595 -3491
  70. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +16 -0
  71. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +19 -20
  72. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.test.mjs +143 -0
  73. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +14 -0
  74. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +3 -1
  75. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +21 -0
  76. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +3 -0
  77. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +29 -0
  78. package/templates/template-manifest.json +536 -932
  79. package/templates/.agents/dashboard/.tmp-run-list.json +0 -254
  80. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DKwP1stV.js +0 -68
  81. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CuMcoUni.js +0 -2
@@ -79,14 +79,10 @@ namespace ZaipDashboardLauncher
79
79
 
80
80
  private static int WaitForLaunchStatus(Process process, string statusPath, string workspaceRoot)
81
81
  {
82
- // The Node launcher coalesces concurrent clicks and may wait for a
83
- // healthy build/handoff. Keep this wrapper alive for that bounded
84
- // handoff instead of showing a second failure dialog.
85
- // A waiting click can spend the Node lock window (210 s) behind
86
- // the current leader, then still needs the bounded 180 s server
87
- // startup window if that leader fails before publishing a session.
88
- var deadline = DateTime.UtcNow.AddSeconds(420);
89
- while (DateTime.UtcNow < deadline)
82
+ // A cold local read model has no useful fixed wall-clock limit.
83
+ // Keep this wrapper attached until Node publishes a real result;
84
+ // errors still surface when Node reports them or exits.
85
+ while (true)
90
86
  {
91
87
  try
92
88
  {
@@ -125,7 +121,6 @@ namespace ZaipDashboardLauncher
125
121
  }
126
122
  Thread.Sleep(100);
127
123
  }
128
- return ReportFailure("O dashboard ainda não publicou uma sessão pronta após 420 segundos. O processo local pode continuar registrando detalhes no log temporário; feche esta mensagem e tente novamente após verificar o log.");
129
124
  }
130
125
 
131
126
  private static bool VerifyDashboardLaunch(string workspaceRoot, out string error)
@@ -11,6 +11,9 @@ export default defineConfig({
11
11
  timeout: 180_000,
12
12
  expect: { timeout: 60_000 },
13
13
  retries: process.env.CI ? 1 : 0,
14
+ // CI shares one SQLite runtime across the suite. Serializing browser workers
15
+ // keeps the measured latency gates independent from runner CPU count.
16
+ ...(process.env.CI ? { workers: 1 } : {}),
14
17
  reporter: process.env.CI ? "github" : "list",
15
18
  use: {
16
19
  baseURL: `${baseURL}/?token=e2e-token`,
@@ -22,7 +25,10 @@ export default defineConfig({
22
25
  cwd: workspaceRoot,
23
26
  url: `${baseURL}/api/v2/health`,
24
27
  reuseExistingServer: false,
25
- timeout: 120_000,
28
+ // The canonical SQLite rebuild is intentionally unbounded in production.
29
+ // Keep only a broad test-runner safety envelope so a large clean workspace
30
+ // is not killed by the former two-minute startup deadline.
31
+ timeout: 3_000_000,
26
32
  env: {
27
33
  ZAIP_UI_TOKEN: "e2e-token",
28
34
  ZAIP_SERVER_PORT: serverPort,
@@ -31,6 +37,8 @@ export default defineConfig({
31
37
  // Match the Windows launcher: first paint uses the latest validated
32
38
  // immutable seed while canonical refresh work stays off the served path.
33
39
  ZAIP_SQLITE_PREFER_LAST_VALID_SEED: "1",
40
+ // Keep pre-bind progress observable if the web-server health gate times out.
41
+ ZAIP_DASHBOARD_LAUNCH_PROGRESS: "1",
34
42
  },
35
43
  },
36
44
  });
@@ -0,0 +1,232 @@
1
+ import { expect, type Page, test } from "@playwright/test";
2
+
3
+ const COST_MONITOR_PATH = "/api/v2/cost-monitor";
4
+ const STALE_SUMMARY_SENTINEL = "SENTINELA-RESPOSTA-ANTIGA";
5
+ const fiveSeconds = 5_000;
6
+
7
+ test("refreshes Cost Monitor within five seconds when Todo o Período is selected in place", async ({
8
+ page,
9
+ }) => {
10
+ await openDashboard(page);
11
+ await openCostMonitor(page);
12
+
13
+ const summary = waitForCostSummary(page, "all");
14
+ const startedAt = Date.now();
15
+ await periodControl(page).selectOption("all");
16
+ await summary;
17
+ await expectCostMonitorReady(page);
18
+
19
+ expect(Date.now() - startedAt).toBeLessThan(fiveSeconds);
20
+ await expect(periodControl(page)).toHaveValue("all");
21
+ });
22
+
23
+ test("loads Cost Monitor within five seconds when the user enters after choosing Todo o Período", async ({
24
+ page,
25
+ }) => {
26
+ await openDashboard(page);
27
+
28
+ await periodControl(page).selectOption("all");
29
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0, { timeout: 60_000 });
30
+
31
+ const summary = waitForCostSummary(page, "all");
32
+ const startedAt = Date.now();
33
+ await page
34
+ .getByRole("navigation", { name: "Áreas do dashboard" })
35
+ .getByRole("button", { name: /Monitor de Custos/ })
36
+ .click();
37
+ await summary;
38
+ await expectCostMonitorReady(page);
39
+
40
+ expect(Date.now() - startedAt).toBeLessThan(fiveSeconds);
41
+ });
42
+
43
+ test("shows one retry after a summary 503 and does not retry in a loop", async ({ page }) => {
44
+ let summaries = 0;
45
+ await page.route("**/api/v2/cost-monitor**", async (route) => {
46
+ const url = new URL(route.request().url());
47
+ if (url.searchParams.get("scope") !== "summary") return route.continue();
48
+ summaries += 1;
49
+ if (summaries === 1)
50
+ return route.fulfill({
51
+ status: 503,
52
+ contentType: "application/json",
53
+ body: JSON.stringify({ error: "summary temporarily unavailable" }),
54
+ });
55
+ return route.continue();
56
+ });
57
+
58
+ await openDashboard(page);
59
+ await openCostMonitor(page, false);
60
+ const retry = page.locator(".app-loading-panel-error").getByRole("button", {
61
+ name: "Tentar novamente",
62
+ });
63
+ await expect(retry).toBeVisible();
64
+
65
+ await retry.click();
66
+ await expectCostMonitorReady(page);
67
+ await page.waitForTimeout(750);
68
+ expect(summaries).toBe(2);
69
+ });
70
+
71
+ test("does not let a late all-time summary overwrite the newer period", async ({ page }) => {
72
+ let priorPeriodBody: string | null = null;
73
+ page.on("response", (response) => {
74
+ const url = new URL(response.url());
75
+ if (
76
+ response.status() === 200 &&
77
+ url.pathname === COST_MONITOR_PATH &&
78
+ url.searchParams.get("scope") === "summary" &&
79
+ url.searchParams.has("from")
80
+ )
81
+ void response.text().then((body) => {
82
+ priorPeriodBody ??= body;
83
+ });
84
+ });
85
+ await page.addInitScript(() => {
86
+ type Probe = {
87
+ allTimeBody: string | null;
88
+ allTimeFinished: boolean;
89
+ allTimeStarted: boolean;
90
+ releaseAllTime: null | (() => Promise<void>);
91
+ };
92
+ const probe: Probe = {
93
+ allTimeBody: null,
94
+ allTimeFinished: false,
95
+ allTimeStarted: false,
96
+ releaseAllTime: null,
97
+ };
98
+ const originalFetch = window.fetch.bind(window);
99
+ Object.assign(window, { __costSummaryStaleProbe: probe });
100
+ window.fetch = (input, init) => {
101
+ const url = new URL(
102
+ typeof input === "string" ? input : input instanceof URL ? input.href : input.url,
103
+ window.location.href,
104
+ );
105
+ const isAllTimeSummary =
106
+ url.pathname === "/api/v2/cost-monitor" &&
107
+ url.searchParams.get("scope") === "summary" &&
108
+ !url.searchParams.has("from") &&
109
+ !url.searchParams.has("to");
110
+ if (!isAllTimeSummary || probe.allTimeStarted) return originalFetch(input, init);
111
+
112
+ probe.allTimeStarted = true;
113
+ return new Promise<Response>((resolve, reject) => {
114
+ probe.releaseAllTime = async () => {
115
+ try {
116
+ resolve(
117
+ new Response(probe.allTimeBody, {
118
+ headers: { "content-type": "application/json" },
119
+ status: 200,
120
+ }),
121
+ );
122
+ } catch (error) {
123
+ reject(error);
124
+ } finally {
125
+ probe.allTimeFinished = true;
126
+ }
127
+ };
128
+ });
129
+ };
130
+ });
131
+
132
+ await openDashboard(page);
133
+ await openCostMonitor(page);
134
+ await expect.poll(() => priorPeriodBody).not.toBeNull();
135
+ const staleBody = withStaleSummarySentinel(priorPeriodBody!);
136
+ await page.evaluate((body) => {
137
+ window.__costSummaryStaleProbe.allTimeBody = body;
138
+ }, staleBody);
139
+
140
+ await periodControl(page).selectOption("all");
141
+ await expect
142
+ .poll(() => page.evaluate(() => window.__costSummaryStaleProbe.allTimeStarted))
143
+ .toBe(true);
144
+
145
+ const latestSummary = waitForCostSummary(page, "this-month");
146
+ await periodControl(page).selectOption("this-month");
147
+ await page.evaluate(async () => await window.__costSummaryStaleProbe.releaseAllTime?.());
148
+ await expect
149
+ .poll(() => page.evaluate(() => window.__costSummaryStaleProbe.allTimeFinished))
150
+ .toBe(true);
151
+ await latestSummary;
152
+ await expect(periodControl(page)).toHaveValue("this-month");
153
+ await expectCostMonitorReady(page);
154
+ await expect(page.locator(".cost-content-daily")).not.toContainText(STALE_SUMMARY_SENTINEL);
155
+ });
156
+
157
+ declare global {
158
+ interface Window {
159
+ __costSummaryStaleProbe: {
160
+ allTimeBody: string | null;
161
+ allTimeFinished: boolean;
162
+ allTimeStarted: boolean;
163
+ releaseAllTime: null | (() => Promise<void>);
164
+ };
165
+ }
166
+ }
167
+
168
+ async function openDashboard(page: Page) {
169
+ const operations = page.waitForResponse(
170
+ (response) =>
171
+ response.status() === 200 &&
172
+ response.url().includes("/api/v2/operations") &&
173
+ response.url().includes("scope=quick"),
174
+ );
175
+ await page.goto("/?token=e2e-token");
176
+ await operations;
177
+ }
178
+
179
+ async function openCostMonitor(page: Page, expectReady = true) {
180
+ const summary = expectReady ? waitForCostSummary(page, "this-month") : null;
181
+ await page
182
+ .getByRole("navigation", { name: "Áreas do dashboard" })
183
+ .getByRole("button", { name: /Monitor de Custos/ })
184
+ .click();
185
+ if (!expectReady) return;
186
+ await summary;
187
+ await expectCostMonitorReady(page);
188
+ }
189
+
190
+ function periodControl(page: Page) {
191
+ return page.locator(".dashboard-global-controls").getByRole("combobox", { name: "Período" });
192
+ }
193
+
194
+ function waitForCostSummary(page: Page, preset: "all" | "this-month") {
195
+ return page.waitForResponse((response) => {
196
+ if (response.status() !== 200) return false;
197
+ const url = new URL(response.url());
198
+ if (url.pathname !== COST_MONITOR_PATH || url.searchParams.get("scope") !== "summary")
199
+ return false;
200
+ return preset === "all"
201
+ ? !url.searchParams.has("from") && !url.searchParams.has("to")
202
+ : url.searchParams.has("from") && url.searchParams.has("to");
203
+ });
204
+ }
205
+
206
+ async function expectCostMonitorReady(page: Page) {
207
+ await expect(page.locator(".cost-tabs")).toBeVisible({ timeout: fiveSeconds });
208
+ const dailyTable = page.locator(".cost-content-daily table");
209
+ await expect(dailyTable).toBeVisible({ timeout: fiveSeconds });
210
+ await expect(dailyTable).not.toHaveAttribute("aria-busy", "true");
211
+ await expect(page.locator(".cost-content-daily tbody tr").first()).toBeVisible({
212
+ timeout: fiveSeconds,
213
+ });
214
+ await expect(page.locator(".app-loading-panel[aria-busy='true']")).toHaveCount(0);
215
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0);
216
+ }
217
+
218
+ function withStaleSummarySentinel(body: string) {
219
+ const projection = JSON.parse(body) as {
220
+ groups?: { daily?: Array<{ key: string; label: string }> };
221
+ };
222
+ const firstDailyRow = projection.groups?.daily?.[0];
223
+ if (firstDailyRow === undefined)
224
+ throw new Error(
225
+ "The Cost summary fixture must contain a daily row for stale-response detection.",
226
+ );
227
+ projection.groups!.daily = [
228
+ { ...firstDailyRow, key: STALE_SUMMARY_SENTINEL, label: STALE_SUMMARY_SENTINEL },
229
+ ...projection.groups!.daily!,
230
+ ];
231
+ return JSON.stringify(projection);
232
+ }
@@ -164,6 +164,9 @@ test("exports Kanban, Lista and Cost Monitor through a save picker while the das
164
164
 
165
165
  test("renders the modern read-only dashboard and meets accessibility gates", async ({ page }) => {
166
166
  await openDashboard(page);
167
+ const globalPeriod = page.getByRole("combobox", { name: /Per/ }).first();
168
+ await expect(globalPeriod).toHaveValue("this-month");
169
+ await selectPopulatedAllTime(page);
167
170
  await expect(page.getByRole("navigation", { name: "Dashboard Zaip AIOS menu" })).toBeVisible();
168
171
  const capabilityNav = page.getByRole("navigation", { name: "Áreas do dashboard" });
169
172
  const globalControls = page.locator(".dashboard-global-controls");
@@ -233,7 +236,7 @@ test("renders the modern read-only dashboard and meets accessibility gates", asy
233
236
  const period = globalControls.getByRole("combobox", { name: "Período" });
234
237
  await expect(startDate).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
235
238
  await expect(endDate).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
236
- await expect(period).toHaveValue("this-month");
239
+ await expect(period).toHaveValue("all");
237
240
  const initialStart = await startDate.inputValue();
238
241
  const today = await endDate.inputValue();
239
242
  await expect(page.getByLabel("Data inicial nos filtros")).toHaveValue(initialStart);
@@ -274,6 +277,7 @@ test("loads a quick Operations summary without full snapshot hydration", async (
274
277
  });
275
278
 
276
279
  await openDashboard(page);
280
+ await selectPopulatedAllTime(page);
277
281
  expect(operationsRequests.some((url) => url.includes("scope=quick"))).toBe(true);
278
282
  expect(operationsRequests.some((url) => url.includes("scope=detail"))).toBe(false);
279
283
  expect(operationsRequests.some((url) => url.includes("/snapshot"))).toBe(false);
@@ -403,6 +407,7 @@ test("embeds traceability and keeps global settings and help available", async (
403
407
 
404
408
  test("groups macro work in All and reveals descendant Tasks only in Tasks", async ({ page }) => {
405
409
  await openDashboard(page);
410
+ await selectPopulatedAllTime(page);
406
411
  await selectOperations(page);
407
412
  const board = page.getByLabel("Kanban de trabalho");
408
413
  await expect(board.locator(".operations-task-card").first()).toBeVisible();
@@ -448,10 +453,12 @@ test("groups macro work in All and reveals descendant Tasks only in Tasks", asyn
448
453
  }
449
454
  });
450
455
 
451
- test("shows the observed default-month macro duration consistently for SPEC and PRD", async ({
456
+ test("shows the observed all-time macro duration consistently for SPEC and PRD", async ({
452
457
  page,
453
458
  }) => {
454
- const response = await openDashboard(page);
459
+ await openDashboard(page);
460
+ await expect(page.getByRole("combobox", { name: /Per/ }).first()).toHaveValue("this-month");
461
+ const response = await selectPopulatedAllTime(page);
455
462
  const projection = (await response.json()) as {
456
463
  summary: {
457
464
  overview_metrics?: {
@@ -466,8 +473,6 @@ test("shows the observed default-month macro duration consistently for SPEC and
466
473
  };
467
474
  };
468
475
  };
469
- await expect(page.getByRole("combobox", { name: /Per/ }).first()).toHaveValue("this-month");
470
-
471
476
  for (const kind of ["SPECs", "PRDs"] as const) {
472
477
  const macroKey = kind === "SPECs" ? "specs" : "prds";
473
478
  const macroMetric = projection.summary.overview_metrics?.macro_metrics?.[macroKey];
@@ -654,6 +659,22 @@ async function openDashboard(page: import("@playwright/test").Page) {
654
659
  return operations;
655
660
  }
656
661
 
662
+ async function selectPopulatedAllTime(page: import("@playwright/test").Page) {
663
+ const response = page.waitForResponse((candidate) => {
664
+ if (
665
+ candidate.status() !== 200 ||
666
+ !candidate.url().includes("/api/v2/operations") ||
667
+ !candidate.url().includes("scope=quick")
668
+ ) {
669
+ return false;
670
+ }
671
+ const url = new URL(candidate.url());
672
+ return !url.searchParams.has("from") && !url.searchParams.has("to");
673
+ });
674
+ await page.getByRole("combobox", { name: /Per/ }).first().selectOption("all");
675
+ return response;
676
+ }
677
+
657
678
  async function selectOperations(page: import("@playwright/test").Page) {
658
679
  await page
659
680
  .getByRole("navigation", { name: "Áreas do dashboard" })
@@ -6,7 +6,7 @@ title: Garantia adaptativa e execução autônoma
6
6
  status: active
7
7
  version: 3
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Garantia adaptativa e execução autônoma
@@ -6,7 +6,7 @@ title: Auditoria comparativa e plano de evolução
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Auditoria comparativa e plano de evolução
@@ -6,7 +6,7 @@ title: Contexto mínimo, seguro e navegável
6
6
  status: active
7
7
  version: 8
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Context engine
@@ -6,7 +6,7 @@ title: Tokens, custos e cobertura
6
6
  status: active
7
7
  version: 10
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Cost observability
@@ -6,7 +6,7 @@ title: Inicialização e hidratação confiável do dashboard
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Inicialização e hidratação confiável do dashboard
@@ -6,7 +6,7 @@ title: Exportação contextual de dados para Excel
6
6
  status: proposed
7
7
  version: 2
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Exportação contextual de dados
@@ -6,7 +6,7 @@ title: Contrato visual e catálogo executável
6
6
  status: active
7
7
  version: 3
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Design system
@@ -6,7 +6,7 @@ title: Preparação, materialização e DAG
6
6
  status: active
7
7
  version: 11
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Execution engine
@@ -6,7 +6,7 @@ title: Projeções operacionais e analíticas
6
6
  status: active
7
7
  version: 14
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Kanban and dashboard
@@ -6,7 +6,7 @@ title: Seleção automática e observável de modelo e effort
6
6
  status: active
7
7
  version: 7
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Orquestração de modelos
@@ -6,7 +6,7 @@ title: Distribuição pública e ativação
6
6
  status: active
7
7
  version: 3
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Distribuição pública e ativação
@@ -6,7 +6,7 @@ title: Layout modular e limites de código-fonte
6
6
  status: active
7
7
  version: 5
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Software architecture
@@ -6,7 +6,7 @@ title: Melhorias estratégicas de custo, qualidade e resiliência
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Melhorias estratégicas de custo, qualidade e resiliência
@@ -6,7 +6,7 @@ title: Ciclo de vida do trabalho
6
6
  status: active
7
7
  version: 24
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Work lifecycle
@@ -6,7 +6,7 @@ title: Evidências, custo por Task e autonomia por SPEC
6
6
  status: active
7
7
  version: 1
8
8
  source_change: null
9
- source_release: "1.3.2"
9
+ source_release: "1.3.4"
10
10
  ---
11
11
 
12
12
  # Evidências, custo por Task e autonomia por SPEC