@zaip-ai/cli 1.3.0 → 1.3.1

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 (258) hide show
  1. package/README.md +1 -1
  2. package/dist/services/agent-adapters.js +1 -1
  3. package/dist/services/agent-adapters.js.map +1 -1
  4. package/dist/services/agent-adapters.test.js +2 -1
  5. package/dist/services/agent-adapters.test.js.map +1 -1
  6. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  7. package/dist/services/codex-pre-tool-hook-template.js +89 -7
  8. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  9. package/dist/services/codex-rules.d.ts +1 -1
  10. package/dist/services/codex-rules.d.ts.map +1 -1
  11. package/dist/services/codex-rules.js +7 -0
  12. package/dist/services/codex-rules.js.map +1 -1
  13. package/dist/services/install-agents-template.d.ts.map +1 -1
  14. package/dist/services/install-agents-template.js +1 -0
  15. package/dist/services/install-agents-template.js.map +1 -1
  16. package/dist/services/runtime-template.test.js +31 -7
  17. package/dist/services/runtime-template.test.js.map +1 -1
  18. package/dist/services/template-manifest.d.ts.map +1 -1
  19. package/dist/services/template-manifest.js +7 -3
  20. package/dist/services/template-manifest.js.map +1 -1
  21. package/package.json +1 -1
  22. package/templates/.agents/config/agents/catalog.yaml +7 -7
  23. package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +2 -2
  24. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +2 -2
  25. package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +8 -8
  26. package/templates/.agents/dashboard/.zaip-managed.json +373 -205
  27. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-DxR_pgSV.js → CostCalculationGuidePage-ovxurkIk.js} +1 -1
  28. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-4jZLTWE_.js → DashboardHelpDialog-BgVgrfhQ.js} +240 -86
  29. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-CKcsqb-r.js → PricingSettingsDialog-vSvvOHQp.js} +1 -1
  30. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-DmmJD2Th.js → ProjectSettingsPage-zH758vfs.js} +1 -1
  31. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-DLn-Mz2M.js +1 -0
  32. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CaKwQP43.css → TraceabilityWorkspace-DvvavDLY.css} +1 -1
  33. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DKwP1stV.js +68 -0
  34. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-PoJA2PI1.css +1 -0
  35. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-C0fj2uU9.js → icons-vendor-B_lDDHn1.js} +1 -1
  36. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-B31GMG5O.css +1 -0
  37. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CZQlsLV9.js +2 -0
  38. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-BEsJ-FYH.js → react-vendor-B3TJrD4O.js} +1 -1
  39. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-B6y6Gw12.js → traceability-7f1j5wx3.js} +1 -1
  40. package/templates/.agents/dashboard/apps/frontend/dist/index.html +7 -7
  41. package/templates/.agents/dashboard/apps/frontend/playwright.dom.config.ts +32 -0
  42. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +132 -245
  43. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +0 -21
  44. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +9 -0
  45. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.dom.e2e.ts +56 -0
  46. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +18 -1
  47. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +75 -8
  48. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +25 -1
  49. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +7 -9
  50. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +4 -4
  51. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +1 -1
  52. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +7 -0
  53. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +20 -8
  54. package/templates/.agents/dashboard/apps/frontend/src/sqlite-page-export.test.ts +32 -0
  55. package/templates/.agents/dashboard/apps/frontend/src/sqlite-page-export.ts +21 -0
  56. package/templates/.agents/dashboard/apps/frontend/src/styles.css +19 -0
  57. package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.test.ts +32 -0
  58. package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.ts +36 -0
  59. package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +6 -2
  60. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +48 -0
  61. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +31 -27
  62. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +7 -1
  63. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-list-page.test.ts +163 -0
  64. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-list-page.ts +136 -0
  65. package/templates/.agents/dashboard/apps/frontend/src/use-operations-detail-export.ts +76 -0
  66. package/templates/.agents/dashboard/apps/frontend/src/work-list-load-dedup.test.ts +23 -0
  67. package/templates/.agents/dashboard/apps/frontend/src/work-list-load-dedup.ts +27 -0
  68. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +38 -14
  69. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.tsx +60 -0
  70. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionTable.tsx +191 -0
  71. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.loading.test.ts +14 -0
  72. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.run-page.test.ts +18 -0
  73. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +18 -3
  74. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +8 -2
  75. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorLoadErrors.tsx +35 -0
  76. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +47 -1
  77. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +50 -58
  78. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.test.ts +132 -0
  79. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.tsx +70 -0
  80. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +128 -138
  81. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +17 -67
  82. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +2 -0
  83. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +3 -1
  84. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-page-range.ts +35 -0
  85. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +16 -4
  86. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +37 -2
  87. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +44 -8
  88. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +6 -1
  89. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +20 -3
  90. package/templates/.agents/dashboard/modules/operations/src/react/DeveloperAttributionPanel.test.ts +54 -0
  91. package/templates/.agents/dashboard/modules/operations/src/react/DeveloperAttributionPanel.tsx +247 -0
  92. package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +39 -13
  93. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +107 -2
  94. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.macro-metrics.test.ts +55 -0
  95. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +20 -28
  96. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +162 -165
  97. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.tsx +127 -0
  98. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +13 -46
  99. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +3 -0
  100. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.test.tsx +43 -0
  101. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.tsx +181 -0
  102. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +4 -2
  103. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +13 -0
  104. package/templates/.agents/dashboard/modules/operations/src/react/developer-identities.test.ts +18 -0
  105. package/templates/.agents/dashboard/modules/operations/src/react/developer-identities.ts +30 -0
  106. package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +1 -0
  107. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +8 -0
  108. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +3 -0
  109. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +14 -5
  110. package/templates/.agents/dashboard/modules/operations/src/react/index.ts +1 -0
  111. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +4 -3
  112. package/templates/.agents/dashboard/modules/operations/src/react/operations-date-filters.css +1 -1
  113. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +21 -11
  114. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.css +4 -0
  115. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +8 -1
  116. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +1 -0
  117. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +1 -0
  118. package/templates/.agents/dashboard/modules/operations/src/server/metric-coverage.ts +1 -0
  119. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +527 -335
  120. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +501 -309
  121. package/templates/.agents/dashboard/packages/local-runtime/gitignore.template +2 -0
  122. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +3 -1
  123. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +3 -3
  124. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +25 -15
  125. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +527 -335
  126. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +34 -0
  127. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +15 -8
  128. package/templates/.agents/dashboard/packages/local-runtime/src/server-classification-page.test.ts +87 -0
  129. package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.test.ts +44 -0
  130. package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.ts +125 -0
  131. package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-refresh.test.ts +66 -0
  132. package/templates/.agents/dashboard/packages/local-runtime/src/server-request-authority.test.ts +61 -0
  133. package/templates/.agents/dashboard/packages/local-runtime/src/server-request-authority.ts +18 -0
  134. package/templates/.agents/dashboard/packages/local-runtime/src/server-run-projections.test.ts +42 -0
  135. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.ts +97 -0
  136. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +3 -1
  137. package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.ts +91 -0
  138. package/templates/.agents/dashboard/packages/local-runtime/src/server.test-fixtures.ts +36 -0
  139. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +98 -123
  140. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +111 -135
  141. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-artifact-counts.ts +28 -0
  142. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.test.ts +63 -0
  143. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.ts +109 -0
  144. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-aggregates.ts +497 -0
  145. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-fast-page-parity.test-support.ts +65 -0
  146. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-page.test.ts +176 -0
  147. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-page.ts +119 -0
  148. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts +41 -0
  149. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.test.ts +16 -0
  150. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.ts +29 -0
  151. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +355 -0
  152. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-persistence.ts +121 -0
  153. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-timing.ts +27 -0
  154. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +15 -0
  155. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +223 -0
  156. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +304 -0
  157. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-cache.test-support.ts +23 -0
  158. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-first-fold-types.ts +89 -0
  159. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider-fixture.ts +227 -0
  160. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +691 -0
  161. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +81 -0
  162. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +440 -863
  163. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +1120 -1086
  164. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-cache.ts +129 -0
  165. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-install.test.ts +26 -0
  166. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-install.ts +28 -0
  167. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +116 -0
  168. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +146 -0
  169. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +165 -0
  170. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-refresh.mjs +140 -0
  171. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +188 -299
  172. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +51 -70
  173. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +5 -2
  174. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +4 -1
  175. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-loading.spec.ts +142 -0
  176. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-pagination.spec.ts +232 -0
  177. package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +743 -0
  178. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +183 -210
  179. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  180. package/templates/.agents/requirements/autonomous-assurance.md +6 -6
  181. package/templates/.agents/requirements/comparative-audit.md +1 -1
  182. package/templates/.agents/requirements/context-engine.md +1 -1
  183. package/templates/.agents/requirements/cost-observability.md +1 -1
  184. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  185. package/templates/.agents/requirements/data-export.md +1 -1
  186. package/templates/.agents/requirements/design-system.md +1 -1
  187. package/templates/.agents/requirements/execution-engine.md +3 -3
  188. package/templates/.agents/requirements/kanban-dashboard.md +10 -2
  189. package/templates/.agents/requirements/model-orchestration.md +1 -1
  190. package/templates/.agents/requirements/public-distribution.md +1 -1
  191. package/templates/.agents/requirements/software-architecture.md +1 -1
  192. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  193. package/templates/.agents/requirements/work-lifecycle.md +4 -4
  194. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  195. package/templates/.agents/rules/dashboard-ui-consistency.md +14 -0
  196. package/templates/.agents/rules/frontend-lite.md +4 -4
  197. package/templates/.agents/rules/run-lifecycle-closure.md +4 -4
  198. package/templates/.agents/runtime/bin/zaip.mjs +1137 -1037
  199. package/templates/.agents/runtime/checksums.sha256 +2 -2
  200. package/templates/.agents/runtime/provenance.json +2 -2
  201. package/templates/.agents/skills/criar-pasta-obsidian/scripts/generate-obsidian-vault.test.mjs +20 -16
  202. package/templates/.agents/skills/zaip-skill-agent-catalog/SKILL.md +22 -0
  203. package/templates/.agents/skills/zaip-skill-agent-catalog/agents/openai.yaml +4 -0
  204. package/templates/.agents/skills/zaip-skill-author-skills/SKILL.md +3 -2
  205. package/templates/.agents/skills/zaip-skill-author-skills/scripts/audit-skill-catalog.mjs +49 -0
  206. package/templates/.agents/skills/zaip-skill-author-skills/scripts/author-skill-scripts.test.mjs +27 -0
  207. package/templates/.agents/skills/zaip-skill-author-skills/scripts/run-skill-tests.mjs +37 -0
  208. package/templates/.agents/skills/zaip-skill-backend/SKILL.md +1 -0
  209. package/templates/.agents/skills/zaip-skill-change/SKILL.md +1 -1
  210. package/templates/.agents/skills/zaip-skill-change/references/observable-evidence.md +83 -0
  211. package/templates/.agents/skills/zaip-skill-dashboard-diagnostics/SKILL.md +22 -0
  212. package/templates/.agents/skills/zaip-skill-dashboard-diagnostics/agents/openai.yaml +4 -0
  213. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
  214. package/templates/.agents/skills/zaip-skill-frontend/SKILL.md +4 -3
  215. package/templates/.agents/skills/zaip-skill-frontend/agents/openai.yaml +2 -2
  216. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +10 -10
  217. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +27 -0
  218. package/templates/.agents/skills/zaip-skill-lifecycle-closure/agents/openai.yaml +4 -0
  219. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +4 -0
  220. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +72 -22
  221. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-explicit-recovery.mjs +223 -0
  222. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +42 -1
  223. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +101 -0
  224. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +53 -0
  225. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +20 -0
  226. package/templates/.agents/skills/zaip-skill-release-qualification/agents/openai.yaml +4 -0
  227. package/templates/.agents/skills/zaip-skill-review/SKILL.md +5 -0
  228. package/templates/.agents/skills/zaip-skill-rules/SKILL.md +1 -1
  229. package/templates/.agents/skills/zaip-skill-spec/SKILL.md +4 -0
  230. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +22 -90
  231. package/templates/.agents/zaip-aios/INDEX.md +57 -32
  232. package/templates/.agents/zaip-aios/README.md +22 -12
  233. package/templates/.agents/zaip-aios/guides/02-requirements.md +5 -0
  234. package/templates/.agents/zaip-aios/guides/06-execucao.md +13 -4
  235. package/templates/.agents/zaip-aios/guides/07-revisao-e-validacao.md +7 -0
  236. package/templates/.agents/zaip-aios/guides/10-seguranca.md +23 -0
  237. package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +6 -6
  238. package/templates/.agents/zaip-aios/guides/13-boas-praticas.md +3 -0
  239. package/templates/.agents/zaip-aios/guides/16-lifecycle-e-reconciliacao.md +12 -3
  240. package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +5 -5
  241. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +23 -0
  242. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +44 -8
  243. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +8 -14
  244. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +5 -0
  245. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +6 -6
  246. package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +8 -8
  247. package/templates/.agents/zaip-aios/guides/25-fontes-de-precos-openai.md +3 -2
  248. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +77 -10
  249. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +8 -3
  250. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +5 -0
  251. package/templates/template-manifest.json +555 -170
  252. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BwtitWa_.js +0 -1
  253. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +0 -1
  254. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-N5Csr0RP.js +0 -68
  255. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-C4aIB1PV.js +0 -2
  256. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +0 -1
  257. package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +0 -45
  258. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs.metafile.json +0 -7333
@@ -16,6 +16,7 @@ import type { EntityMetric } from "./OperationsOverview.helpers.js";
16
16
  import {
17
17
  aggregateMacroMetrics,
18
18
  aggregateTaskMetrics,
19
+ canonicalMacroMetric,
19
20
  countExecutionDays,
20
21
  findLatestCreatedAt,
21
22
  formatExecutionAverageHint,
@@ -24,11 +25,19 @@ import {
24
25
  overviewCopy,
25
26
  overviewMetricAverages,
26
27
  overviewText,
28
+ partialOverviewMetrics,
29
+ resolveOverviewCostTotal,
27
30
  riskColors,
31
+ runsForOverviewView,
32
+ scopedOverviewMetric,
33
+ selectedMacroMetricTotals,
34
+ selectedOverviewCount,
28
35
  selectTopEntities,
29
36
  statusColors,
37
+ sumKnownOverviewMetric,
30
38
  summarizeTopEntityMetrics,
31
39
  } from "./OperationsOverview.helpers.js";
40
+ import { OperationsOverviewTopPanel } from "./OperationsOverviewTopPanel.js";
32
41
  import type { OperationDatePreset, OperationDateRange } from "./operation-date-range.js";
33
42
  import type {
34
43
  OverviewClassification,
@@ -49,6 +58,7 @@ import "./operations-overview.css";
49
58
  export {
50
59
  aggregateMacroMetrics,
51
60
  aggregateTaskMetrics,
61
+ canonicalMacroMetric,
52
62
  countExecutionDays,
53
63
  findLatestCreatedAt,
54
64
  findLatestTaskCreatedAt,
@@ -57,10 +67,17 @@ export {
57
67
  macroClassificationStats,
58
68
  overviewMetricAverages,
59
69
  overviewText,
70
+ partialOverviewMetrics,
71
+ resolveOverviewCostTotal,
72
+ runsForOverviewView,
73
+ scopedOverviewMetric,
74
+ selectedMacroMetricTotals,
75
+ selectedOverviewCount,
60
76
  selectTopEntities,
61
77
  statusColors,
62
78
  summarizeTopEntityMetrics,
63
79
  summarizeTopTaskMetrics,
80
+ taskMetricAverages,
64
81
  } from "./OperationsOverview.helpers.js";
65
82
 
66
83
  type OverviewView = "tasks" | "specs" | "prds";
@@ -81,82 +98,6 @@ function formatEntityDuration(value: number | null, locale: OperationsLocale): s
81
98
  if (value !== null) return formatDurationMs(value, locale);
82
99
  return locale === "pt-BR" ? "Indisponível" : "Unavailable";
83
100
  }
84
-
85
- export function taskMetricAverages(
86
- totals: { durationMs: number | null; tokens: number | null; costBrl: number | null },
87
- taskCount: number | null,
88
- ) {
89
- return overviewMetricAverages(totals, taskCount);
90
- }
91
-
92
- export function selectedOverviewCount(
93
- view: OverviewView,
94
- overviewMetrics: OperationsProjection["summary"]["overview_metrics"] | undefined,
95
- fallback: number,
96
- ): number | null {
97
- if (view === "specs") return overviewMetrics?.selected_counts?.specs ?? fallback;
98
- if (view === "prds") return overviewMetrics?.selected_counts?.prds ?? fallback;
99
- return overviewMetrics?.task_count ?? fallback;
100
- }
101
-
102
- /**
103
- * Selects a currency-specific total without ever treating Operations' BRL
104
- * aggregate as USD. Compact Cost Monitor summaries are authoritative even
105
- * when their intentionally bounded Run collection is empty.
106
- */
107
- export function resolveOverviewCostTotal({
108
- currency,
109
- factualSnapshotTotal,
110
- macroCostTotal,
111
- overviewView,
112
- resolvedRunTotal,
113
- operationsBrlTotal,
114
- }: {
115
- currency: "BRL" | "USD";
116
- factualSnapshotTotal: number | null | undefined;
117
- /** Macro aggregates are scoped to the selected SPEC/PRD, unlike the Task snapshot. */
118
- macroCostTotal?: number | null | undefined;
119
- overviewView?: OverviewView;
120
- resolvedRunTotal: number | null;
121
- operationsBrlTotal: number | null;
122
- }): number | null {
123
- if (overviewView !== undefined && overviewView !== "tasks") return macroCostTotal ?? null;
124
- if (factualSnapshotTotal !== null && factualSnapshotTotal !== undefined)
125
- return factualSnapshotTotal;
126
- if (resolvedRunTotal !== null) return resolvedRunTotal;
127
- return currency === "BRL" ? operationsBrlTotal : null;
128
- }
129
-
130
- /**
131
- * KPI cards are sourced exclusively from the server-selected global aggregate.
132
- * Entity, board, and Cost Monitor pages are bounded/detail views, so their
133
- * collections must never replace the period-filtered big-number population.
134
- */
135
- export function partialOverviewMetrics(data: OperationsProjection) {
136
- return data.summary.overview_metrics;
137
- }
138
-
139
- export function runsForOverviewView(
140
- view: OverviewView,
141
- tasks: OperationsProjection["tasks"],
142
- macros: OperationsProjection["specs"] | OperationsProjection["prds"],
143
- runs: OperationsProjection["runs"],
144
- ): OperationsProjection["runs"] {
145
- if (view === "tasks") {
146
- const taskIds = new Set(tasks.map((task) => task.id));
147
- return runs.filter((run) => run.task_id !== null && taskIds.has(run.task_id));
148
- }
149
- const macroIds = new Set(macros.map((macro) => macro.id));
150
- const declaredRunIds = new Set(macros.flatMap((macro) => macro.run_ids));
151
- return runs.filter(
152
- (run) =>
153
- declaredRunIds.has(run.id) ||
154
- (view === "specs"
155
- ? run.spec_id !== null && macroIds.has(run.spec_id)
156
- : run.prd_id !== null && macroIds.has(run.prd_id)),
157
- );
158
- }
159
-
160
101
  export function OperationsOverview({
161
102
  currency,
162
103
  data,
@@ -170,13 +111,14 @@ export function OperationsOverview({
170
111
  onLoadStatusPage,
171
112
  classificationPage,
172
113
  onLoadClassificationPage,
114
+ onLoadMacroMetrics,
173
115
  prds = data.prds,
174
116
  runs = data.runs,
175
117
  specs = data.specs,
176
118
  tasks = data.tasks,
177
119
  factualCostTotal,
178
120
  resolveRunCost,
179
- includeLegacyEffort = false,
121
+ includeLegacyEffort: _includeLegacyEffort = false,
180
122
  }: {
181
123
  currency: "BRL" | "USD";
182
124
  data: OperationsProjection;
@@ -203,6 +145,7 @@ export function OperationsOverview({
203
145
  onLoadClassificationPage?:
204
146
  | ((kind: OverviewStatusKind, classification: OverviewClassification, offset: number) => void)
205
147
  | undefined;
148
+ onLoadMacroMetrics?: (() => void) | undefined;
206
149
  prds?: OperationsProjection["prds"];
207
150
  runs?: OperationsProjection["runs"];
208
151
  specs?: OperationsProjection["specs"];
@@ -320,10 +263,47 @@ export function OperationsOverview({
320
263
  const specCompletion = specCount === null || specCount === 0 ? 0 : completedSpecCount / specCount;
321
264
  const prdCompletion = prdCount === null || prdCount === 0 ? 0 : completedPrdCount / prdCount;
322
265
  const executionRuns = executionMetrics.runs;
323
- const totalDurationMetric = overviewMetrics?.duration_ms ?? executionMetrics.durationMs;
266
+ const selectedMacroFallbackTotals = selectedMacroMetricTotals(entityMetrics);
267
+ const metricUnit =
268
+ overviewView === "tasks" ? (locale === "pt-BR" ? "tarefa" : "task") : copy.shortPlural;
269
+ const selectedMacroTotals =
270
+ overviewView === "tasks"
271
+ ? null
272
+ : {
273
+ durationMs: canonicalMacroMetric(
274
+ selectedMacroAggregate !== undefined,
275
+ selectedMacroAggregate?.total_duration_ms,
276
+ selectedMacroFallbackTotals.durationMs,
277
+ ),
278
+ tokens: canonicalMacroMetric(
279
+ selectedMacroAggregate !== undefined,
280
+ selectedMacroAggregate?.total_tokens,
281
+ selectedMacroFallbackTotals.tokens,
282
+ ),
283
+ costBrl: canonicalMacroMetric(
284
+ selectedMacroAggregate !== undefined,
285
+ selectedMacroAggregate?.total_cost_brl,
286
+ selectedMacroFallbackTotals.costBrl,
287
+ ),
288
+ };
289
+ // The selectable SPEC/PRD cards define the metric population for every KPI.
290
+ // A global Task aggregate beside a selected macro produces contradictory
291
+ // values such as "duration unavailable" and "83 h" on the same screen.
292
+ const totalDurationMetric = scopedOverviewMetric(
293
+ overviewView,
294
+ selectedMacroTotals?.durationMs,
295
+ overviewMetrics?.duration_ms ?? executionMetrics.durationMs,
296
+ );
324
297
  const totalExecutionDays =
325
- overviewMetrics?.execution_day_count ?? countExecutionDays(executionRuns);
326
- const totalTokensMetric = overviewMetrics?.tokens ?? allPhaseMetrics.tokens;
298
+ overviewView === "tasks"
299
+ ? (overviewMetrics?.execution_day_count ?? countExecutionDays(executionRuns))
300
+ : 0;
301
+ const totalTokensMetric = scopedOverviewMetric(
302
+ overviewView,
303
+ selectedMacroTotals?.tokens,
304
+ overviewMetrics?.tokens ?? allPhaseMetrics.tokens,
305
+ );
306
+ const metricPopulationCount = overviewView === "tasks" ? taskCount : selectedCount;
327
307
  const selectedCurrencyCost =
328
308
  resolveRunCost === undefined
329
309
  ? null
@@ -337,12 +317,20 @@ export function OperationsOverview({
337
317
  : currency === "USD"
338
318
  ? selectedMacroAggregate?.total_cost_usd
339
319
  : selectedMacroAggregate?.total_cost_brl;
320
+ const selectedMacroFallbackCost =
321
+ overviewView === "tasks" || currency === "USD"
322
+ ? null
323
+ : sumKnownOverviewMetric(entityMetrics.map((entity) => entity.costBrl));
340
324
  // Operations aggregates are BRL-only. USD is valid only when it is resolved
341
325
  // from Cost Monitor's factual per-Run estimates; never relabel BRL as USD.
342
326
  const totalCostMetric = resolveOverviewCostTotal({
343
327
  currency,
344
328
  factualSnapshotTotal: factualCostTotal,
345
- macroCostTotal: selectedMacroCost,
329
+ macroCostTotal: canonicalMacroMetric(
330
+ selectedMacroAggregate !== undefined,
331
+ selectedMacroCost,
332
+ selectedMacroFallbackCost,
333
+ ),
346
334
  overviewView,
347
335
  resolvedRunTotal: selectedCurrencyCost,
348
336
  operationsBrlTotal: overviewMetrics?.cost_brl ?? allPhaseMetrics.costBrl,
@@ -352,29 +340,57 @@ export function OperationsOverview({
352
340
  ? null
353
341
  : (totalCostMetric * 3_600_000) / totalDurationMetric;
354
342
  const costPerTask =
355
- totalCostMetric === null || taskCount === null || taskCount === 0
343
+ totalCostMetric === null || metricPopulationCount === null || metricPopulationCount === 0
356
344
  ? null
357
- : totalCostMetric / taskCount;
345
+ : totalCostMetric / metricPopulationCount;
358
346
  const tokensPerTask =
359
- totalTokensMetric === null || taskCount === null || taskCount === 0
347
+ totalTokensMetric === null || metricPopulationCount === null || metricPopulationCount === 0
360
348
  ? null
361
- : totalTokensMetric / taskCount;
349
+ : totalTokensMetric / metricPopulationCount;
362
350
  const tokensPerHour =
363
351
  totalDurationMetric === null || totalDurationMetric <= 0 || totalTokensMetric === null
364
352
  ? null
365
353
  : (totalTokensMetric * 3_600_000) / totalDurationMetric;
366
- const aggregateAverages = overviewMetricAverages(
367
- { durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: totalCostMetric },
368
- selectedCount,
354
+ const averageMetricTotals =
355
+ overviewView === "tasks"
356
+ ? { durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: totalCostMetric }
357
+ : {
358
+ durationMs: canonicalMacroMetric(
359
+ selectedMacroAggregate !== undefined,
360
+ selectedMacroAggregate?.total_duration_ms,
361
+ selectedMacroFallbackTotals.durationMs,
362
+ ),
363
+ tokens: canonicalMacroMetric(
364
+ selectedMacroAggregate !== undefined,
365
+ selectedMacroAggregate?.total_tokens,
366
+ selectedMacroFallbackTotals.tokens,
367
+ ),
368
+ costBrl: canonicalMacroMetric(
369
+ selectedMacroAggregate !== undefined,
370
+ selectedMacroCost,
371
+ currency === "BRL" ? selectedMacroFallbackCost : selectedMacroFallbackTotals.costBrl,
372
+ ),
373
+ };
374
+ const aggregateAverages = overviewMetricAverages(averageMetricTotals, selectedCount);
375
+ const averageDuration = canonicalMacroMetric(
376
+ selectedMacroAggregate !== undefined,
377
+ selectedMacroAggregate?.average_duration_ms,
378
+ aggregateAverages.durationMs,
379
+ );
380
+ const averageTokens = canonicalMacroMetric(
381
+ selectedMacroAggregate !== undefined,
382
+ selectedMacroAggregate?.average_tokens,
383
+ aggregateAverages.tokens,
369
384
  );
370
- const averageDuration =
371
- selectedMacroAggregate?.average_duration_ms ?? aggregateAverages.durationMs;
372
- const averageTokens = selectedMacroAggregate?.average_tokens ?? aggregateAverages.tokens;
373
385
  const averageCost =
374
386
  overviewView !== "tasks"
375
- ? ((currency === "USD"
376
- ? selectedMacroAggregate?.average_cost_usd
377
- : selectedMacroAggregate?.average_cost_brl) ?? null)
387
+ ? canonicalMacroMetric(
388
+ selectedMacroAggregate !== undefined,
389
+ currency === "USD"
390
+ ? selectedMacroAggregate?.average_cost_usd
391
+ : selectedMacroAggregate?.average_cost_brl,
392
+ aggregateAverages.costBrl,
393
+ )
378
394
  : aggregateAverages.costBrl;
379
395
  const latestCreatedAt =
380
396
  overviewView === "tasks"
@@ -422,10 +438,15 @@ export function OperationsOverview({
422
438
  const topEntities =
423
439
  overviewView === "tasks" && runs.length === 0 && aggregateTopTasks.length > 0
424
440
  ? aggregateTopTasks
425
- : overviewView !== "tasks" && runs.length === 0 && aggregateTopMacros.length > 0
441
+ : overviewView !== "tasks" && aggregateTopMacros.length > 0
426
442
  ? aggregateTopMacros
427
443
  : selectTopEntities(entityMetrics);
428
- const maxDuration = Math.max(1, ...topEntities.map((entity) => entity.durationMs ?? 0));
444
+ const maxDuration = Math.max(
445
+ 1,
446
+ ...topEntities
447
+ .filter((entity) => entity.durationMs !== null)
448
+ .map((entity) => entity.durationMs ?? 0),
449
+ );
429
450
  const topEntitiesSummary =
430
451
  overviewView === "tasks" && runs.length === 0 && aggregateTopTasks.length > 0
431
452
  ? {
@@ -436,7 +457,7 @@ export function OperationsOverview({
436
457
  : topEntities.reduce((sum, entity) => sum + (entity.durationMs ?? 0), 0) /
437
458
  totalDurationMetric,
438
459
  }
439
- : overviewView !== "tasks" && runs.length === 0 && aggregateTopMacros.length > 0
460
+ : overviewView !== "tasks" && aggregateTopMacros.length > 0
440
461
  ? {
441
462
  ...summarizeTopEntityMetrics(topEntities, topEntities),
442
463
  durationShare:
@@ -453,7 +474,7 @@ export function OperationsOverview({
453
474
  // factual per-Run Cost Monitor resolver.
454
475
  const usesAggregateTopEntities =
455
476
  (overviewView === "tasks" && runs.length === 0 && aggregateTopTasks.length > 0) ||
456
- (overviewView !== "tasks" && runs.length === 0 && aggregateTopMacros.length > 0);
477
+ (overviewView !== "tasks" && aggregateTopMacros.length > 0);
457
478
  const topEntitiesCost =
458
479
  currency === "USD" &&
459
480
  !usesAggregateTopEntities &&
@@ -471,6 +492,7 @@ export function OperationsOverview({
471
492
  setOverviewView(view);
472
493
  setSelectedStatus(null);
473
494
  setSelectedClassification(null);
495
+ if (view !== "tasks") onLoadMacroMetrics?.();
474
496
  };
475
497
 
476
498
  return (
@@ -547,11 +569,17 @@ export function OperationsOverview({
547
569
  <Kpi
548
570
  hint={formatExecutionAverageHint(
549
571
  totalDurationMetric ?? 0,
550
- taskCount ?? 0,
572
+ metricPopulationCount ?? 0,
551
573
  totalExecutionDays,
552
574
  locale,
553
575
  )}
554
- label={text.totalExecutionTime}
576
+ label={
577
+ overviewView === "tasks"
578
+ ? text.totalExecutionTime
579
+ : locale === "pt-BR"
580
+ ? `${text.totalExecutionTime} de ${copy.shortPlural}`
581
+ : `${copy.shortPlural} ${text.totalExecutionTime.toLowerCase()}`
582
+ }
555
583
  value={formatEntityDuration(totalDurationMetric, locale)}
556
584
  />
557
585
  <Kpi
@@ -561,10 +589,18 @@ export function OperationsOverview({
561
589
  ? "Tokens por tarefa e por hora indisponíveis"
562
590
  : "Tokens per task and hour unavailable"
563
591
  : locale === "pt-BR"
564
- ? `${formatCompactNumber(tokensPerTask, locale)} / tarefa (${formatCompactNumber(tokensPerHour, locale, 0)} / hora)`
565
- : `${formatCompactNumber(tokensPerTask, locale)} / task (${formatCompactNumber(tokensPerHour, locale, 0)} / hour)`
592
+ ? `${formatCompactNumber(tokensPerTask, locale)} / ${metricUnit} (${formatCompactNumber(tokensPerHour, locale, 0)} / hora)`
593
+ : `${formatCompactNumber(tokensPerTask, locale)} / ${metricUnit} (${formatCompactNumber(tokensPerHour, locale, 0)} / hour)`
594
+ }
595
+ label={
596
+ overviewView === "tasks"
597
+ ? locale === "pt-BR"
598
+ ? "Tokens gastos"
599
+ : "Spent tokens"
600
+ : locale === "pt-BR"
601
+ ? `Tokens gastos por ${copy.shortPlural}`
602
+ : `${copy.shortPlural} tokens spent`
566
603
  }
567
- label={locale === "pt-BR" ? "Tokens gastos" : "Spent tokens"}
568
604
  value={
569
605
  totalTokensMetric === null
570
606
  ? formatEntityDuration(null, locale)
@@ -578,10 +614,18 @@ export function OperationsOverview({
578
614
  ? "Custo por tarefa e por hora indispon\u00edvel"
579
615
  : "Cost per task and hour unavailable"
580
616
  : locale === "pt-BR"
581
- ? `${formatRoundedCurrency(costPerTask, currency, locale)} / tarefa (${formatRoundedCurrency(hourlyCost, currency, locale)} / hora)`
582
- : `${formatRoundedCurrency(costPerTask, currency, locale)} / task (${formatRoundedCurrency(hourlyCost, currency, locale)} / hour)`
617
+ ? `${formatRoundedCurrency(costPerTask, currency, locale)} / ${metricUnit} (${formatRoundedCurrency(hourlyCost, currency, locale)} / hora)`
618
+ : `${formatRoundedCurrency(costPerTask, currency, locale)} / ${metricUnit} (${formatRoundedCurrency(hourlyCost, currency, locale)} / hour)`
619
+ }
620
+ label={
621
+ overviewView === "tasks"
622
+ ? locale === "pt-BR"
623
+ ? "Custo Estimado"
624
+ : "Estimated cost"
625
+ : locale === "pt-BR"
626
+ ? `Custo de ${copy.shortPlural}`
627
+ : `${copy.shortPlural} cost`
583
628
  }
584
- label={locale === "pt-BR" ? "Custo Estimado" : "Estimated cost"}
585
629
  value={
586
630
  totalCostMetric === null
587
631
  ? formatEntityDuration(null, locale)
@@ -727,65 +771,18 @@ export function OperationsOverview({
727
771
  </footer>
728
772
  </article>
729
773
 
730
- <article className="operations-panel">
731
- <PanelHeader hint={topHint} title={copy.topTitle} />
732
- {topEntities.length > 0 ? (
733
- <>
734
- <div className="operations-run-bars">
735
- {topEntities.map((entity, index) => (
736
- <button
737
- aria-label={
738
- locale === "pt-BR"
739
- ? `Abrir detalhes da tarefa ${entity.title}`
740
- : `Open details for task ${entity.title}`
741
- }
742
- className="operations-run-bar"
743
- disabled={overviewView !== "tasks"}
744
- key={entity.id}
745
- onClick={() => void onOpenTask(entity.id)}
746
- title={`${entity.title}: ${formatEntityDuration(entity.durationMs, locale)}`}
747
- type="button"
748
- >
749
- <strong>{formatEntityDuration(entity.durationMs, locale)}</strong>
750
- <i
751
- style={{
752
- height: `${Math.max(8, ((entity.durationMs ?? 0) / maxDuration) * 100)}%`,
753
- }}
754
- />
755
- <span>{`#${index + 1} ${entity.id.slice(-4)}`}</span>
756
- </button>
757
- ))}
758
- </div>
759
- <div className="operations-top-task-metrics">
760
- <div>
761
- <span>{text.accumulatedTime}</span>
762
- <strong>{formatEntityDuration(topEntitiesSummary.durationMs, locale)}</strong>
763
- <small>{`${topEntitiesSummary.runCount} ${text.associatedRuns}`}</small>
764
- </div>
765
- <div>
766
- <span>{text.concentration}</span>
767
- <strong>{formatPercent(topEntitiesSummary.durationShare, locale)}</strong>
768
- <small>{text.totalMeasuredTime}</small>
769
- </div>
770
- <div>
771
- <span>{text.topFiveCost}</span>
772
- <strong>
773
- {topEntitiesCost === null
774
- ? formatEntityDuration(null, locale)
775
- : formatCurrency(topEntitiesCost, currency, locale)}
776
- </strong>
777
- <small>
778
- {topEntitiesSummary.tokens === null
779
- ? text.tokensUnavailable
780
- : `${formatCompactNumber(topEntitiesSummary.tokens, locale)} tokens`}
781
- </small>
782
- </div>
783
- </div>
784
- </>
785
- ) : (
786
- <p className="operations-empty">{copy.emptyTop}</p>
787
- )}
788
- </article>
774
+ <OperationsOverviewTopPanel
775
+ copy={{ empty: copy.emptyTop, hint: topHint, title: copy.topTitle }}
776
+ currency={currency}
777
+ locale={locale}
778
+ maxDuration={maxDuration}
779
+ onOpenTask={onOpenTask}
780
+ summary={topEntitiesSummary}
781
+ text={text}
782
+ topCost={topEntitiesCost}
783
+ topEntities={topEntities}
784
+ view={overviewView}
785
+ />
789
786
  </div>
790
787
  {selectedStatus === null ? null : (
791
788
  <FilteredStatusDialog
@@ -0,0 +1,127 @@
1
+ import {
2
+ formatCompactNumber,
3
+ formatCurrency,
4
+ formatDurationMs,
5
+ formatPercent,
6
+ } from "@zaip-ai/dashboard-ui";
7
+ import type { EntityMetric } from "./OperationsOverview.helpers.js";
8
+ import type { OperationsLocale } from "./status-labels.js";
9
+
10
+ type OverviewView = "tasks" | "specs" | "prds";
11
+
12
+ const duration = (value: number | null, locale: OperationsLocale) =>
13
+ value === null
14
+ ? locale === "pt-BR"
15
+ ? "Indisponível"
16
+ : "Unavailable"
17
+ : formatDurationMs(value, locale);
18
+
19
+ export function OperationsOverviewTopPanel({
20
+ copy,
21
+ currency,
22
+ locale,
23
+ maxDuration,
24
+ onOpenTask,
25
+ summary,
26
+ text,
27
+ topCost,
28
+ topEntities,
29
+ view,
30
+ }: {
31
+ copy: { empty: string; hint: string; title: string };
32
+ currency: "BRL" | "USD";
33
+ locale: OperationsLocale;
34
+ maxDuration: number;
35
+ onOpenTask: (taskId: string) => Promise<boolean>;
36
+ summary: {
37
+ durationMs: number | null;
38
+ durationShare: number;
39
+ runCount: number;
40
+ tokens: number | null;
41
+ };
42
+ text: {
43
+ accumulatedTime: string;
44
+ associatedRuns: string;
45
+ concentration: string;
46
+ totalMeasuredTime: string;
47
+ topFiveCost: string;
48
+ tokensUnavailable: string;
49
+ };
50
+ topCost: number | null;
51
+ topEntities: readonly EntityMetric[];
52
+ view: OverviewView;
53
+ }) {
54
+ const entityKind = view === "specs" ? "SPEC" : "PRD";
55
+ return (
56
+ <article className="operations-panel">
57
+ <header className="operations-panel-header">
58
+ <div className="operations-panel-header-title">
59
+ <h2>{copy.title}</h2>
60
+ </div>
61
+ <small>{copy.hint}</small>
62
+ </header>
63
+ {topEntities.length === 0 ? (
64
+ <p className="operations-empty">{copy.empty}</p>
65
+ ) : (
66
+ <>
67
+ <div className="operations-run-bars">
68
+ {topEntities.map((entity, index) => {
69
+ const measuredDuration = duration(entity.durationMs, locale);
70
+ const label =
71
+ view === "tasks"
72
+ ? `${locale === "pt-BR" ? "Abrir detalhes da tarefa" : "Open task details for"} ${entity.title}: ${measuredDuration}`
73
+ : `${entityKind} ${entity.title}: ${measuredDuration}`;
74
+ return (
75
+ <button
76
+ aria-label={label}
77
+ className={`operations-run-bar${entity.durationMs === null ? " is-duration-unavailable" : ""}`}
78
+ disabled={view !== "tasks"}
79
+ key={entity.id}
80
+ onClick={() => void onOpenTask(entity.id)}
81
+ title={`${entity.title}: ${measuredDuration}`}
82
+ type="button"
83
+ >
84
+ <strong>{measuredDuration}</strong>
85
+ <i
86
+ style={{
87
+ height:
88
+ entity.durationMs === null
89
+ ? "0%"
90
+ : `${Math.max(8, (entity.durationMs / maxDuration) * 100)}%`,
91
+ }}
92
+ />
93
+ <span>{`#${index + 1} ${entity.id.slice(-4)}`}</span>
94
+ </button>
95
+ );
96
+ })}
97
+ </div>
98
+ <div className="operations-top-task-metrics">
99
+ <div>
100
+ <span>{text.accumulatedTime}</span>
101
+ <strong>{duration(summary.durationMs, locale)}</strong>
102
+ <small>{`${summary.runCount} ${text.associatedRuns}`}</small>
103
+ </div>
104
+ <div>
105
+ <span>{text.concentration}</span>
106
+ <strong>{formatPercent(summary.durationShare, locale)}</strong>
107
+ <small>{text.totalMeasuredTime}</small>
108
+ </div>
109
+ <div>
110
+ <span>{text.topFiveCost}</span>
111
+ <strong>
112
+ {topCost === null
113
+ ? duration(null, locale)
114
+ : formatCurrency(topCost, currency, locale)}
115
+ </strong>
116
+ <small>
117
+ {summary.tokens === null
118
+ ? text.tokensUnavailable
119
+ : `${formatCompactNumber(summary.tokens, locale)} tokens`}
120
+ </small>
121
+ </div>
122
+ </div>
123
+ </>
124
+ )}
125
+ </article>
126
+ );
127
+ }