@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
@@ -143,7 +143,9 @@ export function ExecutionTable({
143
143
  {
144
144
  durationMs: row.duration_ms,
145
145
  provenance:
146
- row.duration_ms === null && row.status === "running" ? "in_progress" : "factual",
146
+ row.duration_ms === null && row.status === "running"
147
+ ? "in_progress"
148
+ : "factual",
147
149
  },
148
150
  locale,
149
151
  ),
@@ -282,13 +284,21 @@ export function RunTable({
282
284
  value === null || value === undefined ? "—" : formatCurrency(value, "USD", locale);
283
285
  const provenance = (value: RunProjection["duration_provenance"]) =>
284
286
  value === "observed"
285
- ? locale === "pt-BR" ? "Observada" : "Observed"
287
+ ? locale === "pt-BR"
288
+ ? "Observada"
289
+ : "Observed"
286
290
  : value === "reconciled"
287
- ? locale === "pt-BR" ? "Reconciliada" : "Reconciled"
291
+ ? locale === "pt-BR"
292
+ ? "Reconciliada"
293
+ : "Reconciled"
288
294
  : value === "estimated"
289
- ? locale === "pt-BR" ? "Estimada por tokens" : "Token-estimated"
295
+ ? locale === "pt-BR"
296
+ ? "Estimada por tokens"
297
+ : "Token-estimated"
290
298
  : value === "legacy_inferred"
291
- ? locale === "pt-BR" ? "Inferida histórica" : "Legacy inferred"
299
+ ? locale === "pt-BR"
300
+ ? "Inferida histórica"
301
+ : "Legacy inferred"
292
302
  : "—";
293
303
  return (
294
304
  <>
@@ -351,7 +361,9 @@ export function RunTable({
351
361
  render: (row) => (
352
362
  <>
353
363
  <strong>{displayedRunAgent(row)}</strong>
354
- <small>{[row.agent_persona, row.agent_job].filter(Boolean).join(" · ") || "—"}</small>
364
+ <small>
365
+ {[row.agent_persona, row.agent_job].filter(Boolean).join(" · ") || "—"}
366
+ </small>
355
367
  </>
356
368
  ),
357
369
  },
@@ -384,7 +396,7 @@ export function RunTable({
384
396
  ? locale === "pt-BR"
385
397
  ? "Em andamento"
386
398
  : "In progress"
387
- : provenance(row.duration_provenance);
399
+ : provenance(row.duration_provenance);
388
400
  },
389
401
  },
390
402
  {
@@ -462,7 +474,8 @@ export function RunTable({
462
474
  {
463
475
  key: "context_multiplier",
464
476
  label: locale === "pt-BR" ? "Mult. contexto E/S" : "Context mult. I/O",
465
- render: (row) => `${multiplier(row.context_input_multiplier)} / ${multiplier(row.context_output_multiplier)}`,
477
+ render: (row) =>
478
+ `${multiplier(row.context_input_multiplier)} / ${multiplier(row.context_output_multiplier)}`,
466
479
  },
467
480
  {
468
481
  key: "speed_multiplier",
@@ -477,7 +490,7 @@ export function RunTable({
477
490
  ? locale === "pt-BR"
478
491
  ? "Standard (contexto longo)"
479
492
  : "Standard (long context)"
480
- : row.pricing_scenario ?? "—",
493
+ : (row.pricing_scenario ?? "—"),
481
494
  },
482
495
  {
483
496
  key: "input_cost",
@@ -521,7 +534,12 @@ export function RunTable({
521
534
  render: (row) => usd(row.cost_variance_usd),
522
535
  align: "right",
523
536
  },
524
- { key: "fx_rate", label: "USD/BRL", render: (row) => number(row.fx_rate), align: "right" },
537
+ {
538
+ key: "fx_rate",
539
+ label: "USD/BRL",
540
+ render: (row) => number(row.fx_rate),
541
+ align: "right",
542
+ },
525
543
  {
526
544
  key: "cost",
527
545
  label: locale === "pt-BR" ? "Custo total BRL" : "Total cost BRL",
@@ -608,7 +626,9 @@ export function ConversationTable({
608
626
  {
609
627
  durationMs: row.duration_ms,
610
628
  provenance:
611
- row.duration_ms === null && row.status === "running" ? "in_progress" : row.duration_provenance,
629
+ row.duration_ms === null && row.status === "running"
630
+ ? "in_progress"
631
+ : row.duration_provenance,
612
632
  },
613
633
  locale,
614
634
  ),
@@ -110,7 +110,9 @@ describe("partial overview charts", () => {
110
110
  describe("overview aggregate source", () => {
111
111
  it("keeps aggregate-only Top 5 USD factual and leaves a missing value unavailable", () => {
112
112
  const source = readFileSync(new URL("OperationsOverview.tsx", import.meta.url), "utf8");
113
- expect(source).toContain('costBrl: currency === "USD" ? metric.total_cost_usd ?? null : metric.cost_brl');
113
+ expect(source).toMatch(
114
+ /costBrl:\s*currency === "USD"\s*\?\s*\(metric\.total_cost_usd \?\? null\)\s*:\s*metric\.cost_brl/,
115
+ );
114
116
  expect(source).toContain("topEntitiesCost === null");
115
117
  });
116
118
 
@@ -30,6 +30,12 @@ import {
30
30
  summarizeTopEntityMetrics,
31
31
  } from "./OperationsOverview.helpers.js";
32
32
  import type { OperationDatePreset, OperationDateRange } from "./operation-date-range.js";
33
+ import type {
34
+ OverviewClassification,
35
+ OverviewClassificationPage,
36
+ OverviewStatusKind,
37
+ OverviewStatusPage,
38
+ } from "./operations-page-contract.js";
33
39
  import { type OperationsLocale, riskLabel } from "./status-labels.js";
34
40
  import {
35
41
  macroWorkStage,
@@ -38,12 +44,6 @@ import {
38
44
  workStageLabel,
39
45
  workStages,
40
46
  } from "./work-board-model.js";
41
- import type {
42
- OverviewClassification,
43
- OverviewClassificationPage,
44
- OverviewStatusKind,
45
- OverviewStatusPage,
46
- } from "./operations-page-contract.js";
47
47
  import "./operations-overview.css";
48
48
 
49
49
  export {
@@ -188,10 +188,21 @@ export function OperationsOverview({
188
188
  onOpenTask: (taskId: string) => Promise<boolean>;
189
189
  onOpenDocument: (kind: "prd" | "spec", id: string) => void;
190
190
  onLoadStatus?: ((stage: WorkStage, kind: OverviewStatusKind, offset: number) => void) | undefined;
191
- statusPage?: ((stage: WorkStage, kind: OverviewStatusKind) => OverviewStatusPage | undefined) | undefined;
192
- onLoadStatusPage?: ((stage: WorkStage, kind: OverviewStatusKind, offset: number) => void) | undefined;
193
- classificationPage?: ((kind: OverviewStatusKind, classification: OverviewClassification) => OverviewClassificationPage | undefined) | undefined;
194
- onLoadClassificationPage?: ((kind: OverviewStatusKind, classification: OverviewClassification, offset: number) => void) | undefined;
191
+ statusPage?:
192
+ | ((stage: WorkStage, kind: OverviewStatusKind) => OverviewStatusPage | undefined)
193
+ | undefined;
194
+ onLoadStatusPage?:
195
+ | ((stage: WorkStage, kind: OverviewStatusKind, offset: number) => void)
196
+ | undefined;
197
+ classificationPage?:
198
+ | ((
199
+ kind: OverviewStatusKind,
200
+ classification: OverviewClassification,
201
+ ) => OverviewClassificationPage | undefined)
202
+ | undefined;
203
+ onLoadClassificationPage?:
204
+ | ((kind: OverviewStatusKind, classification: OverviewClassification, offset: number) => void)
205
+ | undefined;
195
206
  prds?: OperationsProjection["prds"];
196
207
  runs?: OperationsProjection["runs"];
197
208
  specs?: OperationsProjection["specs"];
@@ -203,7 +214,8 @@ export function OperationsOverview({
203
214
  }) {
204
215
  const [overviewView, setOverviewView] = useState<OverviewView>("tasks");
205
216
  const [selectedStatus, setSelectedStatus] = useState<WorkStage | null>(null);
206
- const [selectedClassification, setSelectedClassification] = useState<OverviewClassification | null>(null);
217
+ const [selectedClassification, setSelectedClassification] =
218
+ useState<OverviewClassification | null>(null);
207
219
  const completed = tasks.filter((task) => task.status === "completed").length;
208
220
  const completedSpecs = specs.filter((spec) => spec.work_status === "completed").length;
209
221
  const completedPrds = prds.filter((prd) => prd.work_status === "completed").length;
@@ -360,9 +372,9 @@ export function OperationsOverview({
360
372
  const averageTokens = selectedMacroAggregate?.average_tokens ?? aggregateAverages.tokens;
361
373
  const averageCost =
362
374
  overviewView !== "tasks"
363
- ? (currency === "USD"
375
+ ? ((currency === "USD"
364
376
  ? selectedMacroAggregate?.average_cost_usd
365
- : selectedMacroAggregate?.average_cost_brl) ?? null
377
+ : selectedMacroAggregate?.average_cost_brl) ?? null)
366
378
  : aggregateAverages.costBrl;
367
379
  const latestCreatedAt =
368
380
  overviewView === "tasks"
@@ -393,7 +405,7 @@ export function OperationsOverview({
393
405
  tokens: metric.total_tokens,
394
406
  // EntityMetric predates the global locale selector. It is a selected
395
407
  // display-currency bucket here, never a BRL value relabelled as USD.
396
- costBrl: currency === "USD" ? metric.total_cost_usd ?? null : metric.cost_brl,
408
+ costBrl: currency === "USD" ? (metric.total_cost_usd ?? null) : metric.cost_brl,
397
409
  runCount: metric.run_count,
398
410
  }));
399
411
  const aggregateTopMacros: EntityMetric[] = (selectedMacroAggregate?.top_entities ?? []).map(
@@ -403,7 +415,7 @@ export function OperationsOverview({
403
415
  durationMs: metric.duration_ms,
404
416
  durationProvenance: metric.duration_ms === null ? "unavailable" : "observed",
405
417
  tokens: metric.total_tokens,
406
- costBrl: currency === "USD" ? metric.total_cost_usd ?? null : metric.cost_brl,
418
+ costBrl: currency === "USD" ? (metric.total_cost_usd ?? null) : metric.cost_brl,
407
419
  runCount: metric.run_count,
408
420
  }),
409
421
  );
@@ -443,7 +455,9 @@ export function OperationsOverview({
443
455
  (overviewView === "tasks" && runs.length === 0 && aggregateTopTasks.length > 0) ||
444
456
  (overviewView !== "tasks" && runs.length === 0 && aggregateTopMacros.length > 0);
445
457
  const topEntitiesCost =
446
- currency === "USD" && !usesAggregateTopEntities && (runs.length === 0 || resolveRunCost === undefined)
458
+ currency === "USD" &&
459
+ !usesAggregateTopEntities &&
460
+ (runs.length === 0 || resolveRunCost === undefined)
447
461
  ? null
448
462
  : topEntitiesSummary.costBrl;
449
463
  const topHint =
@@ -795,7 +809,12 @@ export function OperationsOverview({
795
809
  setSelectedStatus(null);
796
810
  onOpenDocument(kind, id);
797
811
  }}
798
- items={statusPage?.(selectedStatus, overviewView === "tasks" ? "task" : overviewView === "specs" ? "spec" : "prd")?.items ?? []}
812
+ items={
813
+ statusPage?.(
814
+ selectedStatus,
815
+ overviewView === "tasks" ? "task" : overviewView === "specs" ? "spec" : "prd",
816
+ )?.items ?? []
817
+ }
799
818
  kind={overviewView === "tasks" ? "task" : overviewView === "specs" ? "spec" : "prd"}
800
819
  onLoadMore={(offset) =>
801
820
  onLoadStatusPage?.(
@@ -804,7 +823,10 @@ export function OperationsOverview({
804
823
  offset,
805
824
  )
806
825
  }
807
- page={statusPage?.(selectedStatus, overviewView === "tasks" ? "task" : overviewView === "specs" ? "spec" : "prd")}
826
+ page={statusPage?.(
827
+ selectedStatus,
828
+ overviewView === "tasks" ? "task" : overviewView === "specs" ? "spec" : "prd",
829
+ )}
808
830
  />
809
831
  )}
810
832
  {selectedClassification === null ? null : (
@@ -812,8 +834,12 @@ export function OperationsOverview({
812
834
  eyebrow={locale === "pt-BR" ? copy.classificationTitle : "Classification"}
813
835
  label={
814
836
  overviewView === "tasks"
815
- ? riskLabel(selectedClassification as OperationsProjection["tasks"][number]["risk"], locale)
816
- : classificationStats.find((item) => item.key === selectedClassification)?.label ?? selectedClassification
837
+ ? riskLabel(
838
+ selectedClassification as OperationsProjection["tasks"][number]["risk"],
839
+ locale,
840
+ )
841
+ : (classificationStats.find((item) => item.key === selectedClassification)?.label ??
842
+ selectedClassification)
817
843
  }
818
844
  locale={locale}
819
845
  onClose={() => setSelectedClassification(null)}
@@ -967,7 +993,11 @@ function FilteredStatusDialog({
967
993
  );
968
994
  }
969
995
 
970
- function statusTypeLabel(kind: OverviewStatusKind, count: number, locale: OperationsLocale): string {
996
+ function statusTypeLabel(
997
+ kind: OverviewStatusKind,
998
+ count: number,
999
+ locale: OperationsLocale,
1000
+ ): string {
971
1001
  if (kind === "prd") return count === 1 ? "PRD" : "PRDs";
972
1002
  if (kind === "spec") return count === 1 ? "SPEC" : "SPECs";
973
1003
  return locale === "pt-BR" ? (count === 1 ? "tarefa" : "tarefas") : count === 1 ? "task" : "tasks";
@@ -40,7 +40,13 @@ import {
40
40
  import { macrosWithPeriodActivity } from "./operations-period-scope.js";
41
41
  import { matchesQuery } from "./operations-query.js";
42
42
  import { viewLabels } from "./operations-view-labels.js";
43
- import { aggregateManifestPeriodSummary, aggregatePeriodSummary } from "./period-summary.js";
43
+ import { applyFactualPeriodCosts, applyFactualPeriodDurations } from "./PeriodSummaryTable.js";
44
+ import {
45
+ aggregateManifestPeriodSummary,
46
+ aggregatePeriodSummary,
47
+ type PeriodGranularity,
48
+ type PeriodSummaryRow,
49
+ } from "./period-summary.js";
44
50
  import { periodSummaryPopulation } from "./period-summary-population.js";
45
51
  import { scopeRunsToEntities } from "./run-scope.js";
46
52
  import { type OperationsLocale, riskLabel } from "./status-labels.js";
@@ -63,12 +69,24 @@ import "./operations-date-filters.css";
63
69
  import "./operations-filter-panel.css";
64
70
  import "./operations-responsive.css";
65
71
 
72
+ /** Applies Cost Monitor duration facts only to the Operations period exports that share them. */
73
+ export function factualDurationRowsForExport(
74
+ granularity: PeriodGranularity,
75
+ rows: readonly PeriodSummaryRow[],
76
+ factualRows?: readonly { key: string; duration_ms: number | null }[],
77
+ ): PeriodSummaryRow[] {
78
+ return granularity === "month" || granularity === "year"
79
+ ? applyFactualPeriodDurations(rows, factualRows)
80
+ : [...rows];
81
+ }
82
+
66
83
  export function OperationsPage({
67
84
  alternateContent,
68
85
  boardTotals,
69
86
  boardKindTotals,
70
87
  boardStates,
71
88
  boardExportSource,
89
+ detailExportSource,
72
90
  capabilityNavigation,
73
91
  currency,
74
92
  data,
@@ -383,8 +401,25 @@ export function OperationsPage({
383
401
  ),
384
402
  granularity,
385
403
  );
404
+ // Export the exact period facts shown in the report. In particular, the
405
+ // compact Operations summary can carry a stale/missing cost while Cost
406
+ // Monitor has the factual selected-currency amount for the same key.
407
+ // Keep null when neither source has a factual value.
408
+ const costRows = applyFactualPeriodCosts(
409
+ periodRows,
410
+ currency,
411
+ factualCostPeriods?.[granularity],
412
+ );
413
+ // The monthly and annual Cost Monitor groups carry the factual duration
414
+ // for the same snapshot. Only fill an unavailable Operations value;
415
+ // never derive time or overwrite a known period duration.
416
+ const displayedRows = factualDurationRowsForExport(
417
+ granularity,
418
+ costRows,
419
+ factualCostPeriods?.[granularity],
420
+ );
386
421
  // Keep the period XLSX contract identical to Cost Monitor.
387
- return periodRows.map((row) => ({
422
+ return displayedRows.map((row) => ({
388
423
  key: row.key,
389
424
  prds: row.prds,
390
425
  specs: row.specs,
@@ -414,6 +449,7 @@ export function OperationsPage({
414
449
  conversationRuns,
415
450
  decisions,
416
451
  executions,
452
+ factualCostPeriods,
417
453
  prds,
418
454
  resolveRunCost,
419
455
  runs,
@@ -425,6 +461,7 @@ export function OperationsPage({
425
461
  data.filters,
426
462
  dailyPeriods,
427
463
  matchesSelectedDate,
464
+ currency,
428
465
  ]);
429
466
  const isLoading = loading || filterLoading;
430
467
  useEffect(() => onLoadingChange?.(isLoading), [isLoading, onLoadingChange]);
@@ -690,7 +727,12 @@ export function OperationsPage({
690
727
  risk: riskFilter,
691
728
  origin: originFilter,
692
729
  })
693
- : undefined
730
+ : detailExportSource?.(view, {
731
+ query,
732
+ status: statusFilter,
733
+ risk: riskFilter,
734
+ origin: originFilter,
735
+ })
694
736
  }
695
737
  view={`operations-${view}`}
696
738
  />
@@ -713,8 +755,8 @@ export function OperationsPage({
713
755
  locale={locale}
714
756
  onBoardTypeChange={onBoardTypeChange}
715
757
  onEntityPageChange={onEntityPageChange}
716
- onLoadMoreBoard={onLoadMoreBoard}
717
- onWorkListTypeChange={onWorkListTypeChange}
758
+ onLoadMoreBoard={onLoadMoreBoard}
759
+ onWorkListTypeChange={onWorkListTypeChange}
718
760
  onOpenDocument={onOpenDocument}
719
761
  onOpenTask={onOpenTask}
720
762
  onPriorityChange={onPriorityChange}
@@ -11,10 +11,7 @@ export function OperationsViewTabs({
11
11
  onChange: (view: OperationsView) => void;
12
12
  view: OperationsView;
13
13
  }) {
14
- const views = [
15
- "work-kanban",
16
- "work-list",
17
- ] as const;
14
+ const views = ["work-kanban", "work-list"] as const;
18
15
  return (
19
16
  <nav aria-label="Entidades do ciclo de trabalho">
20
17
  {views.map((key) => (
@@ -43,20 +43,17 @@ export function PeriodSummaryTable({
43
43
  Record<string, import("./period-summary.js").ManifestDailyPeriod>
44
44
  >;
45
45
  factualCostPeriods?: Partial<
46
- Record<PeriodGranularity, readonly { key: string; estimated_usd: number | null; estimated_brl: number | null }[]>
46
+ Record<
47
+ PeriodGranularity,
48
+ readonly { key: string; estimated_usd: number | null; estimated_brl: number | null }[]
49
+ >
47
50
  >;
48
51
  }) {
49
52
  const calculatedRows =
50
53
  // Persisted Operations periods carry BRL-only aggregates. USD must be
51
54
  // rebuilt from the selected-currency per-Run resolver or remain null.
52
55
  manifestDailyPeriods === undefined || currency === "USD"
53
- ? aggregatePeriodSummary(
54
- data,
55
- granularity,
56
- resolveRunCost,
57
- includeLegacyEffort,
58
- legacyRange,
59
- )
56
+ ? aggregatePeriodSummary(data, granularity, resolveRunCost, includeLegacyEffort, legacyRange)
60
57
  : aggregateManifestPeriodSummary(manifestDailyPeriods, granularity);
61
58
  const rows = applyFactualPeriodCosts(calculatedRows, currency, factualCostPeriods?.[granularity]);
62
59
  const summarizedTotal = summarizePeriodRows(rows);
@@ -197,17 +194,42 @@ export function PeriodSummaryTable({
197
194
  export function applyFactualPeriodCosts<T extends { key: string; costBrl: number | null }>(
198
195
  rows: readonly T[],
199
196
  currency: "BRL" | "USD",
200
- factualRows?: readonly { key: string; estimated_usd: number | null; estimated_brl: number | null }[],
197
+ factualRows?: readonly {
198
+ key: string;
199
+ estimated_usd: number | null;
200
+ estimated_brl: number | null;
201
+ }[],
201
202
  ): T[] {
202
203
  if (factualRows === undefined) return [...rows];
203
204
  const costByKey = new Map(
204
- factualRows.map((row) => [row.key, currency === "USD" ? row.estimated_usd : row.estimated_brl] as const),
205
+ factualRows.map(
206
+ (row) => [row.key, currency === "USD" ? row.estimated_usd : row.estimated_brl] as const,
207
+ ),
205
208
  );
206
209
  return rows.map((row) =>
207
210
  costByKey.has(row.key) ? { ...row, costBrl: costByKey.get(row.key) ?? null } : row,
208
211
  );
209
212
  }
210
213
 
214
+ /**
215
+ * Fills an unavailable Operations duration only when Cost Monitor has an
216
+ * observed period fact. A missing/null Cost Monitor value remains unavailable.
217
+ */
218
+ export function applyFactualPeriodDurations<T extends { key: string; durationMs: number | null }>(
219
+ rows: readonly T[],
220
+ factualRows?: readonly { key: string; duration_ms: number | null }[],
221
+ ): T[] {
222
+ if (factualRows === undefined) return [...rows];
223
+ const durationByKey = new Map(factualRows.map((row) => [row.key, row.duration_ms] as const));
224
+ return rows.map((row) => {
225
+ if (row.durationMs !== null) return row;
226
+ const factualDuration = durationByKey.get(row.key);
227
+ return factualDuration === undefined || factualDuration === null
228
+ ? row
229
+ : { ...row, durationMs: factualDuration };
230
+ });
231
+ }
232
+
211
233
  /** Empty period totals display zero without inventing duration for any Run. */
212
234
  export function periodTotalDurationMs(
213
235
  durationMs: number | null,
@@ -59,11 +59,16 @@ export function TaskDetailsDialog({
59
59
  {!summary || hasSummarySpecId ? (
60
60
  <Detail label="SPEC" value={detail.task.spec_id ?? "Task-first"} />
61
61
  ) : null}
62
- {!summary || hasChangeId ? <Detail label="Change" value={detail.task.change_id} /> : null}
62
+ {!summary || hasChangeId ? (
63
+ <Detail label="Change" value={detail.task.change_id} />
64
+ ) : null}
63
65
  {!summary || summaryRunCount !== null ? (
64
66
  <Detail label="Runs" value={String(summary ? summaryRunCount : runs.length)} />
65
67
  ) : null}
66
- <Detail label={copy.duration} value={formatOperationDuration(telemetry.durationMs, locale)} />
68
+ <Detail
69
+ label={copy.duration}
70
+ value={formatOperationDuration(telemetry.durationMs, locale)}
71
+ />
67
72
  <Detail
68
73
  label="Tokens"
69
74
  value={
@@ -137,7 +142,8 @@ function recoverExactTelemetry(runs: readonly OperationsProjection["runs"][numbe
137
142
  );
138
143
  return {
139
144
  durationMs:
140
- rootExecutionRuns.length === 0 || rootExecutionRuns.some((run) => operationalDurationMs(run) === null)
145
+ rootExecutionRuns.length === 0 ||
146
+ rootExecutionRuns.some((run) => operationalDurationMs(run) === null)
141
147
  ? null
142
148
  : rootExecutionRuns.reduce((total, run) => total + (operationalDurationMs(run) ?? 0), 0),
143
149
  tokens:
@@ -13,8 +13,8 @@ import { formatCardCreatedAt } from "./format-card-created-at.js";
13
13
  import { formatRoundedDuration } from "./format-rounded-duration.js";
14
14
  import { MacroPlanningDialog } from "./MacroPlanningDialog.js";
15
15
  import { type OperationsLocale, riskLabel } from "./status-labels.js";
16
- import { TaskDetailsDialog } from "./TaskDetailsDialog.js";
17
16
  import { taskTotals } from "./TaskBoard.js";
17
+ import { TaskDetailsDialog } from "./TaskDetailsDialog.js";
18
18
  import { taskOrigin } from "./task-origin.js";
19
19
  import { useCurrentTime } from "./use-current-time.js";
20
20
  import { useInfiniteColumn } from "./use-infinite-column.js";
@@ -60,7 +60,12 @@ export function UnifiedWorkBoard({
60
60
  allTasks: readonly DashboardTaskProjection[];
61
61
  boardTotals?: Partial<Record<WorkStage, number>> | undefined;
62
62
  boardKindTotals?:
63
- | Partial<Record<WorkStage, { all: number; task: number; prd: number; spec: number }>>
63
+ | Partial<
64
+ Record<
65
+ WorkStage,
66
+ { all: number; task: number; "standalone-task": number; prd: number; spec: number }
67
+ >
68
+ >
64
69
  | undefined;
65
70
  boardStates?: Partial<Record<WorkStage, { loading: boolean; error: string | null }>> | undefined;
66
71
  changes: readonly ChangeProjection[];
@@ -166,7 +171,10 @@ export function UnifiedWorkBoard({
166
171
  totalItems={
167
172
  typeFilter === "all"
168
173
  ? (boardKindTotals?.[stage]?.all ?? boardTotals?.[stage] ?? rows.length)
169
- : typeFilter === "task" || typeFilter === "prd" || typeFilter === "spec"
174
+ : typeFilter === "task" ||
175
+ typeFilter === "standalone-task" ||
176
+ typeFilter === "prd" ||
177
+ typeFilter === "spec"
170
178
  ? (boardKindTotals?.[stage]?.[typeFilter] ?? rows.length)
171
179
  : rows.length
172
180
  }
@@ -244,7 +252,7 @@ export function WorkTypeFilters({
244
252
  all: "Tudo",
245
253
  prd: "PRDs",
246
254
  spec: "SPECs",
247
- "standalone-task": "Tarefas Avulsas",
255
+ "standalone-task": "Tarefa Avulsa",
248
256
  }
249
257
  : {
250
258
  task: "Tasks",
@@ -253,7 +261,7 @@ export function WorkTypeFilters({
253
261
  spec: "SPECs",
254
262
  "standalone-task": "Standalone Tasks",
255
263
  };
256
- const filterOrder: readonly WorkTypeFilter[] = ["all", "task", "prd", "spec"];
264
+ const filterOrder: readonly WorkTypeFilter[] = ["all", "task", "standalone-task", "prd", "spec"];
257
265
  return (
258
266
  <nav
259
267
  aria-label={locale === "pt-BR" ? "Filtrar tipo de trabalho" : "Filter work type"}
@@ -1,6 +1,6 @@
1
- import { describe, expect, it } from "vitest";
2
1
  import { readFileSync } from "node:fs";
3
2
  import { fileURLToPath } from "node:url";
3
+ import { describe, expect, it } from "vitest";
4
4
  import type { DashboardTaskProjection, MacroProjection, RunProjection } from "../contracts.js";
5
5
  import { buildWorkListRows, formatWorkListDuration } from "./UnifiedWorkList.js";
6
6
 
@@ -12,7 +12,10 @@ describe("buildWorkListRows", () => {
12
12
  });
13
13
 
14
14
  it("keeps the operational list to its eight standard columns", () => {
15
- const source = readFileSync(fileURLToPath(new URL("./UnifiedWorkList.tsx", import.meta.url)), "utf8");
15
+ const source = readFileSync(
16
+ fileURLToPath(new URL("./UnifiedWorkList.tsx", import.meta.url)),
17
+ "utf8",
18
+ );
16
19
  const keys = [...source.matchAll(/key: "([^"]+)"/g)].map((match) => match[1]);
17
20
  expect(keys.slice(0, 8)).toEqual([
18
21
  "item",
@@ -32,12 +35,17 @@ describe("buildWorkListRows", () => {
32
35
  expect(source).toContain('label: locale === "pt-BR" ? "Tempo" : "Time"');
33
36
  expect(source).toContain('label: "Tokens"');
34
37
  expect(source).toContain('label: locale === "pt-BR" ? "Custo" : "Cost"');
35
- expect(keys).not.toEqual(expect.arrayContaining(["runs", "lifecycleElapsed", "executions", "tasks", "duration"]));
38
+ expect(keys).not.toEqual(
39
+ expect.arrayContaining(["runs", "lifecycleElapsed", "executions", "tasks", "duration"]),
40
+ );
36
41
  expect(source).not.toContain("taskOriginLabel");
37
42
  });
38
43
 
39
44
  it("propagates the selected type so the server can fetch that canonical collection", () => {
40
- const source = readFileSync(fileURLToPath(new URL("./UnifiedWorkList.tsx", import.meta.url)), "utf8");
45
+ const source = readFileSync(
46
+ fileURLToPath(new URL("./UnifiedWorkList.tsx", import.meta.url)),
47
+ "utf8",
48
+ );
41
49
  expect(source).toContain("onTypeChange?.(kind)");
42
50
  });
43
51
 
@@ -8,10 +8,7 @@ import type {
8
8
  } from "../contracts.js";
9
9
  import { formatRoundedDuration } from "./format-rounded-duration.js";
10
10
  import { MacroPlanningDialog } from "./MacroPlanningDialog.js";
11
- import {
12
- formatDisplayedDuration,
13
- operationalDurationMs,
14
- } from "./operation-duration.js";
11
+ import { formatDisplayedDuration, operationalDurationMs } from "./operation-duration.js";
15
12
  import { type OperationsLocale, riskLabel } from "./status-labels.js";
16
13
  import { WorkTypeFilters } from "./UnifiedWorkBoard.js";
17
14
  import {
@@ -40,8 +40,7 @@ export function buildConversationRows(
40
40
  // retain the root conversation_id but legitimately have a Task
41
41
  // entrypoint/task_id and a delivery Execution. Link by the
42
42
  // conversation ID so that continuation is not dropped.
43
- (run) =>
44
- run.conversation_id === id || executionIds.has(run.execution_id ?? ""),
43
+ (run) => run.conversation_id === id || executionIds.has(run.execution_id ?? ""),
45
44
  )
46
45
  .map((run) => [run.id, run]),
47
46
  ).values(),