@zaip-ai/cli 2.6.0 → 3.1.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 (312) hide show
  1. package/README.md +36 -13
  2. package/dist/services/adapters.d.ts +1 -1
  3. package/dist/services/adapters.d.ts.map +1 -1
  4. package/dist/services/adapters.js +5 -2
  5. package/dist/services/adapters.js.map +1 -1
  6. package/dist/services/agent-adapters.js +12 -9
  7. package/dist/services/agent-adapters.js.map +1 -1
  8. package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
  9. package/dist/services/codex-conversation-lifecycle-hook.js +32 -21
  10. package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
  11. package/dist/services/install-agents-template.js +9 -1
  12. package/dist/services/install-agents-template.js.map +1 -1
  13. package/dist/services/runtime-template.test.js +25 -2
  14. package/dist/services/runtime-template.test.js.map +1 -1
  15. package/dist/services/transactional-files.d.ts.map +1 -1
  16. package/dist/services/transactional-files.js +59 -14
  17. package/dist/services/transactional-files.js.map +1 -1
  18. package/package.json +1 -1
  19. package/templates/.agents/README-ENG.md +75 -10
  20. package/templates/.agents/README.md +76 -10
  21. package/templates/.agents/config/agents/catalog.yaml +3 -0
  22. package/templates/.agents/config/agents/discovery.json +2 -2
  23. package/templates/.agents/config/clients/codex/agents/zaip-agent-analyst.toml +1 -1
  24. package/templates/.agents/config/clients/codex/agents/zaip-agent-auditor.toml +1 -1
  25. package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +1 -1
  26. package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +1 -1
  27. package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +1 -1
  28. package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +1 -1
  29. package/templates/.agents/config/clients/codex/agents/zaip-agent-data-analyst.toml +1 -1
  30. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +1 -1
  31. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +2 -2
  32. package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +1 -1
  33. package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +1 -1
  34. package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +1 -1
  35. package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +1 -1
  36. package/templates/.agents/config/clients/codex/agents/zaip-agent-integrator.toml +1 -1
  37. package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +1 -1
  38. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +13 -10
  39. package/templates/.agents/config/clients/codex/agents/zaip-agent-refactoring-specialist.toml +1 -1
  40. package/templates/.agents/config/clients/codex/agents/zaip-agent-reviewer.toml +1 -1
  41. package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +1 -1
  42. package/templates/.agents/config/clients/codex/agents/zaip-agent-security-auditor.toml +1 -1
  43. package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +1 -1
  44. package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +1 -1
  45. package/templates/.agents/config/clients/codex/agents/zaip-agent-writer.toml +1 -1
  46. package/templates/.agents/config/project.yaml +10 -1
  47. package/templates/.agents/dashboard/.zaip-managed.json +274 -138
  48. package/templates/.agents/dashboard/README.md +16 -0
  49. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-CGxeQak4.js → CostCalculationGuidePage-CEDZjl4V.js} +1 -1
  50. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-tzS7YxYB.js → DashboardHelpDialog-DIWDmvAS.js} +930 -550
  51. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-DEbCi1gP.js → PricingSettingsDialog-BBRBKaHa.js} +1 -1
  52. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-B9GWkEyN.css +1 -0
  53. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BAvLPAee.js +3 -0
  54. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-t1Om0Abw.js → TraceabilityWorkspace-C9dDhj34.js} +1 -1
  55. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-06__WZco.js +68 -0
  56. package/templates/.agents/dashboard/apps/frontend/dist/assets/dashboard-localization-CoAVMZN6.js +828 -0
  57. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DiGC-dsJ.js → icons-vendor-DEmo6Tn2.js} +1 -1
  58. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-BVzw_Wux.js +2 -0
  59. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-kPO6yNed.js → react-vendor-CadYsm83.js} +1 -1
  60. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-BzKK8kK3.js +1 -0
  61. package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
  62. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  63. package/templates/.agents/dashboard/apps/frontend/src/AppDashboardContent.tsx +10 -5
  64. package/templates/.agents/dashboard/apps/frontend/src/AutonomySettings.tsx +82 -0
  65. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.dom.test.ts +38 -7
  66. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +164 -171
  67. package/templates/.agents/dashboard/apps/frontend/src/__tests__/app-composition-support.ts +6 -1
  68. package/templates/.agents/dashboard/apps/frontend/src/cost-monitor-population.test.tsx +149 -0
  69. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api-settings.ts +2 -1
  70. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +19 -0
  71. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +22 -1
  72. package/templates/.agents/dashboard/apps/frontend/src/dashboard-cost-facts.test.ts +54 -0
  73. package/templates/.agents/dashboard/apps/frontend/src/dashboard-cost-facts.ts +20 -2
  74. package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.test.ts +37 -43
  75. package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +9 -251
  76. package/templates/.agents/dashboard/apps/frontend/src/dashboard-project-overview.ts +34 -7
  77. package/templates/.agents/dashboard/apps/frontend/src/dashboard-view-actions.test.ts +51 -0
  78. package/templates/.agents/dashboard/apps/frontend/src/dashboard-view-actions.ts +3 -1
  79. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +35 -0
  80. package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +19 -4
  81. package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +5 -3
  82. package/templates/.agents/dashboard/apps/frontend/src/project-installation-status.test.ts +112 -23
  83. package/templates/.agents/dashboard/apps/frontend/src/project-installation-status.ts +49 -12
  84. package/templates/.agents/dashboard/apps/frontend/src/project-settings-copy.ts +181 -0
  85. package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +11 -1
  86. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +34 -51
  87. package/templates/.agents/dashboard/apps/frontend/src/project-settings-state.css +55 -0
  88. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +12 -0
  89. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +1 -1
  90. package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.ts +1 -2
  91. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +6 -0
  92. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +2 -0
  93. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +3 -1
  94. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-task-pagination.ts +4 -15
  95. package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-app-model.tsx +2 -2
  96. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  97. package/templates/.agents/dashboard/modules/cost-monitor/src/complete-cost-average.test.ts +73 -0
  98. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +9 -0
  99. package/templates/.agents/dashboard/modules/cost-monitor/src/period-averages.ts +60 -0
  100. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +8 -22
  101. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +2 -3
  102. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostPeriodAverageCards.tsx +32 -8
  103. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +3 -2
  104. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +1 -42
  105. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +2 -1
  106. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +3 -2
  107. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +8 -2
  108. package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
  109. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  110. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview-keeps-structure-classes-mutually-exclusive.test.ts +4 -3
  111. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +66 -3
  112. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +71 -1
  113. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +36 -30
  114. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +5 -14
  115. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +3 -0
  116. package/templates/.agents/dashboard/modules/operations/src/react/OverviewCostKpi.tsx +46 -0
  117. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +28 -1
  118. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +11 -4
  119. package/templates/.agents/dashboard/modules/operations/src/react/index.ts +1 -0
  120. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +2 -2
  121. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +28 -8
  122. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +19 -2
  123. package/templates/.agents/dashboard/modules/operations/src/react/overview-cost-card.test.tsx +89 -0
  124. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +3 -3
  125. package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +2 -1
  126. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  127. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  128. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  129. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  130. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +279 -245
  131. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +247 -215
  132. package/templates/.agents/dashboard/packages/local-runtime/package.json +2 -2
  133. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +15 -25
  134. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +279 -245
  135. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +1 -1
  136. package/templates/.agents/dashboard/packages/local-runtime/src/project-installation-summary.test.ts +142 -0
  137. package/templates/.agents/dashboard/packages/local-runtime/src/project-installation-summary.ts +190 -0
  138. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +65 -0
  139. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +67 -66
  140. package/templates/.agents/dashboard/packages/local-runtime/src/server-browser-lease.test.ts +91 -0
  141. package/templates/.agents/dashboard/packages/local-runtime/src/server-browser-lease.ts +24 -4
  142. package/templates/.agents/dashboard/packages/local-runtime/src/server-hono-security.test.ts +17 -0
  143. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-routes.ts +21 -2
  144. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +94 -2
  145. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.ts +62 -12
  146. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.test.ts +26 -0
  147. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +4 -1
  148. package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.test.ts +97 -0
  149. package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.ts +10 -13
  150. package/templates/.agents/dashboard/packages/local-runtime/src/server-trace-routes.ts +2 -10
  151. package/templates/.agents/dashboard/packages/local-runtime/src/server-traceability-index.test.ts +84 -0
  152. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +15 -1
  153. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-calendar.ts +17 -0
  154. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cold-parse.test.ts +78 -0
  155. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-dimension-facts.test.ts +12 -1
  156. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.test.ts +94 -0
  157. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts +5 -5
  158. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-duration-lookup.test.ts +59 -0
  159. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-entity-label-views.test.ts +72 -0
  160. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-file-index.test.ts +69 -0
  161. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +3 -1
  162. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-force-canonical.test.ts +3 -1
  163. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-refresh.test.ts +2 -0
  164. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-projections.ts +9 -0
  165. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-runs.ts +4 -5
  166. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-period-averages.ts +46 -0
  167. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-provider-alias-parity.test.ts +50 -0
  168. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.test.ts +171 -0
  169. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.ts +36 -16
  170. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-filtered-dimension.ts +13 -2
  171. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +25 -7
  172. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-temporal-dimension.ts +2 -0
  173. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical-parsing.ts +7 -0
  174. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +5 -15
  175. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +34 -10
  176. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-filesystem.ts +17 -3
  177. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-keeps-orphan-telemetry-out-kanban-without.test.ts +1 -1
  178. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +11 -0
  179. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +5 -4
  180. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.test.ts +54 -1
  181. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +7 -3
  182. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +4 -1
  183. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-risk-population.test.ts +98 -0
  184. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-base-views.ts +29 -16
  185. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts +2 -1
  186. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +2 -0
  187. package/templates/.agents/dashboard/packages/local-runtime/src/verify-project-settings.mjs +57 -0
  188. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  189. package/templates/.agents/dashboard/scripts/qualify-observability.mjs +130 -0
  190. package/templates/.agents/dashboard/scripts/verify-autonomy-settings.mjs +175 -0
  191. package/templates/.agents/dashboard/scripts/verify-observability.mjs +254 -0
  192. package/templates/.agents/dashboard/scripts/verify-project-setup.mjs +64 -0
  193. package/templates/.agents/dashboard/tests/e2e/lease-global-setup.ts +37 -0
  194. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  195. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +5 -3
  196. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-period-transition.spec.ts +22 -1
  197. package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +17 -8
  198. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +47 -6
  199. package/templates/.agents/dashboard/tests/e2e/specs/lease-lifetime.spec.ts +14 -0
  200. package/templates/.agents/dashboard/tests/observability-fixture.mjs +200 -0
  201. package/templates/.agents/design/.zaip-managed.json +84 -40
  202. package/templates/.agents/design/apps/catalog/dist/assets/index-BJV597iq.js +72 -0
  203. package/templates/.agents/design/apps/catalog/dist/assets/index-BOjCcUaU.js +72 -0
  204. package/templates/.agents/design/apps/catalog/dist/assets/index-B_WhrCZe.js +72 -0
  205. package/templates/.agents/design/apps/catalog/dist/assets/index-CqtYXZfV.js +72 -0
  206. package/templates/.agents/design/apps/catalog/dist/assets/index-D_lfqoyx.js +72 -0
  207. package/templates/.agents/design/apps/catalog/dist/assets/index-i_PO2k9R.js +9 -0
  208. package/templates/.agents/design/apps/catalog/dist/index.html +1 -1
  209. package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-Cstn1UwA.js +1 -0
  210. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Color-6AOWCN3U-B-kAgAjB.js → Color-6AOWCN3U-Cm-yJJz_.js} +1 -1
  211. package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-D1WopB2L.js +137 -0
  212. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DQ9PJ3N3.js +1 -0
  213. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DocsRenderer-JROSPFPF-BVN7xHtv.js → DocsRenderer-JROSPFPF-Belk4jRr.js} +4 -4
  214. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WithTooltip-7X4HQR7L-CDHtKYkz.js → WithTooltip-7X4HQR7L-DoPvjkS1.js} +1 -1
  215. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-DRQKCCAG-D6AsDkMK.js → chunk-DRQKCCAG-B1itKXEN.js} +1 -1
  216. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-W22LQPXL-B4m5uloN.js → chunk-W22LQPXL-C-Eb5SPY.js} +1 -1
  217. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{components-CN8YyTUg.js → components-DnyKLwhj.js} +5 -5
  218. package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-D0OSgxWz.js +1 -0
  219. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{iframe-9yZfIsdT.js → iframe-DcXBsFPz.js} +3 -3
  220. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{react-18-BoCSnq6H.js → react-18-CRM89QRf.js} +1 -1
  221. package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-C3tkVMIp.js +1 -0
  222. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{syntaxhighlighter-YFXUGROL-Bnn_nMwJ.js → syntaxhighlighter-YFXUGROL-B03jQGTF.js} +1 -1
  223. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{theming-DS_ue2sb.js → theming-4ZyufAga.js} +1 -1
  224. package/templates/.agents/design/apps/catalog/dist/storybook/iframe.html +1 -1
  225. package/templates/.agents/design/apps/catalog/dist/storybook/index.json +1 -1
  226. package/templates/.agents/design/apps/catalog/package.json +2 -2
  227. package/templates/.agents/design/apps/catalog/src/components/AutonomySpecimen.tsx +15 -0
  228. package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.test.tsx +19 -0
  229. package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.tsx +45 -0
  230. package/templates/.agents/design/apps/catalog/src/components/EstimatedCostSpecimen.tsx +48 -0
  231. package/templates/.agents/design/apps/catalog/src/components/ProjectStatusSpecimen.tsx +169 -0
  232. package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +55 -0
  233. package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +60 -0
  234. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  235. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  236. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  237. package/templates/.agents/requirements/comparative-audit.md +1 -1
  238. package/templates/.agents/requirements/context-engine.md +1 -1
  239. package/templates/.agents/requirements/cost-observability.md +1 -1
  240. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  241. package/templates/.agents/requirements/data-export.md +1 -1
  242. package/templates/.agents/requirements/design-system.md +1 -1
  243. package/templates/.agents/requirements/execution-engine.md +1 -1
  244. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  245. package/templates/.agents/requirements/model-orchestration.md +1 -1
  246. package/templates/.agents/requirements/public-distribution.md +1 -1
  247. package/templates/.agents/requirements/software-architecture.md +1 -1
  248. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  249. package/templates/.agents/requirements/work-lifecycle.md +5 -5
  250. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  251. package/templates/.agents/rules/astra-diagnostic.md +3 -1
  252. package/templates/.agents/rules/autonomy-decision.md +10 -2
  253. package/templates/.agents/rules/core.md +12 -1
  254. package/templates/.agents/rules/run-lifecycle-closure.md +8 -6
  255. package/templates/.agents/rules/workflow.md +2 -2
  256. package/templates/.agents/runtime/VERSION +1 -1
  257. package/templates/.agents/runtime/bin/zaip.mjs +383 -350
  258. package/templates/.agents/runtime/checksums.sha256 +6 -6
  259. package/templates/.agents/runtime/manifest.json +1 -1
  260. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  261. package/templates/.agents/runtime/provenance.json +5 -5
  262. package/templates/.agents/runtime/sbom.cdx.json +3 -3
  263. package/templates/.agents/skills/zaip-skill-dev-environment/SKILL.md +2 -0
  264. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +28 -5
  265. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +17 -3
  266. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +8 -9
  267. package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +10 -6
  268. package/templates/.agents/skills/zaip-skill-github-deploy/references/release-identity.md +17 -12
  269. package/templates/.agents/skills/zaip-skill-move-prd/SKILL.md +2 -0
  270. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +2 -0
  271. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +21 -23
  272. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +37 -13
  273. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +2 -0
  274. package/templates/.agents/skills/zaip-skill-tool-setup/SKILL.md +2 -0
  275. package/templates/.agents/zaip-aios/INDEX.md +9 -1
  276. package/templates/.agents/zaip-aios/README.md +24 -2
  277. package/templates/.agents/zaip-aios/VERSION +1 -1
  278. package/templates/.agents/zaip-aios/guides/01-primeiros-passos.md +5 -1
  279. package/templates/.agents/zaip-aios/guides/03-tasks.md +15 -2
  280. package/templates/.agents/zaip-aios/guides/04-specs.md +13 -0
  281. package/templates/.agents/zaip-aios/guides/05-prds.md +13 -0
  282. package/templates/.agents/zaip-aios/guides/06-execucao.md +19 -4
  283. package/templates/.agents/zaip-aios/guides/07-revisao-e-validacao.md +14 -0
  284. package/templates/.agents/zaip-aios/guides/08-contexto-e-tokens.md +4 -3
  285. package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +17 -9
  286. package/templates/.agents/zaip-aios/guides/10-seguranca.md +9 -0
  287. package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +69 -0
  288. package/templates/.agents/zaip-aios/guides/12-instalacao-e-upgrade.md +9 -4
  289. package/templates/.agents/zaip-aios/guides/13-boas-praticas.md +7 -1
  290. package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +18 -0
  291. package/templates/.agents/zaip-aios/guides/16-lifecycle-e-reconciliacao.md +54 -3
  292. package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +10 -2
  293. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +186 -5
  294. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +21 -15
  295. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +18 -2
  296. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +14 -2
  297. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +190 -489
  298. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +72 -13
  299. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +18 -0
  300. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +18 -1
  301. package/templates/template-manifest.json +454 -274
  302. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-1L7Qw-Gq.js +0 -3
  303. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-EInWr641.css +0 -1
  304. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-B6aZfo5f.js +0 -68
  305. package/templates/.agents/dashboard/apps/frontend/dist/assets/dashboard-localization-CLJ0lT9v.js +0 -231
  306. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DgTmNHN5.js +0 -2
  307. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DQpKX9c1.js +0 -1
  308. package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-BWY-80s4.js +0 -1
  309. package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-Be2mDUQj.js +0 -27
  310. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DRx9blDs.js +0 -1
  311. package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-EwuTh8Zk.js +0 -1
  312. package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-DyL61NPT.js +0 -1
@@ -84,7 +84,7 @@ describe("taskStatusDistribution", () => {
84
84
  );
85
85
 
86
86
  expect(distribution.map(({ key, label, count }) => ({ key, label, count }))).toEqual([
87
- { key: "definition", label: "Definição (PRD + Requisitos)", count: 2 },
87
+ { key: "definition", label: "Definição (PRD + Requisitos)", count: 0 },
88
88
  { key: "planning", label: "Planejamento (SPEC + Change)", count: 0 },
89
89
  { key: "ready", label: "Pronto para Executar", count: 2 },
90
90
  { key: "executing", label: "Execução", count: 1 },
@@ -117,7 +117,7 @@ describe("taskStatusDistribution", () => {
117
117
  );
118
118
 
119
119
  expect(visible.map(({ key, count }) => ({ key, count }))).toEqual([
120
- { key: "definition", count: 1 },
120
+ { key: "definition", count: 0 },
121
121
  { key: "planning", count: 0 },
122
122
  { key: "ready", count: 2 },
123
123
  { key: "executing", count: 1 },
@@ -127,7 +127,8 @@ describe("taskStatusDistribution", () => {
127
127
  { key: "cancelled", count: 1 },
128
128
  { key: "failed", count: 1 },
129
129
  ]);
130
- expect(visible.reduce((total, item) => total + item.count, 0)).toBe(8);
130
+ // Draft Tasks stay in the list, outside the PRD/SPEC pipeline stages.
131
+ expect(visible.reduce((total, item) => total + item.count, 0)).toBe(7);
131
132
  });
132
133
  });
133
134
  describe("macroStatusDistribution", () => {
@@ -7,6 +7,8 @@ import {
7
7
  sumObserved,
8
8
  } from "./execution-metrics.js";
9
9
  import { formatDurationInHours, formatRoundedDuration } from "./format-rounded-duration.js";
10
+ import type { FactualCostFact } from "./operations-page-contract.js";
11
+ import { formatRoundedCurrency } from "./overview-metric-format.js";
10
12
  import type { OperationsLocale } from "./status-labels.js";
11
13
  import type { WorkStage } from "./work-board-model.js";
12
14
 
@@ -365,6 +367,7 @@ export function canonicalMacroMetric(
365
367
  /** Selects currency totals without treating Operations' BRL aggregate as USD. */
366
368
  export function resolveOverviewCostTotal({
367
369
  currency,
370
+ factualSnapshotFact,
368
371
  factualSnapshotTotal,
369
372
  macroCostTotal,
370
373
  overviewView,
@@ -372,6 +375,7 @@ export function resolveOverviewCostTotal({
372
375
  operationsBrlTotal,
373
376
  }: {
374
377
  currency: "BRL" | "USD";
378
+ factualSnapshotFact?: FactualCostFact | undefined;
375
379
  factualSnapshotTotal: number | null | undefined;
376
380
  macroCostTotal?: number | null | undefined;
377
381
  overviewView?: OverviewView;
@@ -379,12 +383,67 @@ export function resolveOverviewCostTotal({
379
383
  operationsBrlTotal: number | null;
380
384
  }): number | null {
381
385
  if (overviewView !== undefined && overviewView !== "tasks") return macroCostTotal ?? null;
382
- if (factualSnapshotTotal !== null && factualSnapshotTotal !== undefined)
383
- return factualSnapshotTotal;
386
+ if (factualSnapshotFact !== undefined)
387
+ return factualSnapshotFact.state === "unavailable" ? null : factualSnapshotFact.knownSum;
388
+ // Explicit null is authoritative unavailability, not permission to use a partial fallback.
389
+ if (factualSnapshotTotal !== undefined) return factualSnapshotTotal;
384
390
  if (resolvedRunTotal !== null) return resolvedRunTotal;
385
391
  return currency === "BRL" ? operationsBrlTotal : null;
386
392
  }
387
393
 
394
+ export function factualCostMetricLabel(
395
+ _fact: FactualCostFact | undefined,
396
+ locale: OperationsLocale,
397
+ ): string {
398
+ return locale === "pt-BR" ? "Custo Estimado" : "Estimated cost";
399
+ }
400
+
401
+ export function factualCostMetricHint(
402
+ fact: FactualCostFact | undefined,
403
+ metricUnit: string,
404
+ locale: OperationsLocale,
405
+ ): string | null {
406
+ if (fact?.state !== "partial") return null;
407
+ const { known, total } = fact.coverage;
408
+ return locale === "pt-BR"
409
+ ? `${known} de ${total} runs com custo conhecido. Taxas estimadas: subtotal conhecido dividido pelas ${metricUnit}s e horas registradas do recorte; cobertura parcial, sem estimar custos ausentes.`
410
+ : `${known} of ${total} runs have known cost. Estimated rates: known subtotal divided by the selected ${metricUnit}s and recorded hours; partial coverage, missing costs are not estimated.`;
411
+ }
412
+
413
+ export function factualCostAverageLabel(
414
+ fact: FactualCostFact | undefined,
415
+ _populationCount: number | null,
416
+ locale: OperationsLocale,
417
+ ): string {
418
+ const base = locale === "pt-BR" ? "Custo médio" : "Average cost";
419
+ if (fact?.state !== "partial") return base;
420
+ const partial = locale === "pt-BR" ? "cobertura parcial" : "partial coverage";
421
+ return `${base} — ${partial} (${fact.coverage.known}/${fact.coverage.total} runs)`;
422
+ }
423
+
424
+ /** Rates allocate observed spend across the selected population, not missing spend. */
425
+ export function overviewCostForRates(fact: FactualCostFact | undefined, total: number | null) {
426
+ return fact?.state === "unavailable" ? null : total;
427
+ }
428
+
429
+ export function overviewCostRateHint(
430
+ fact: FactualCostFact | undefined,
431
+ unit: string,
432
+ locale: OperationsLocale,
433
+ currency: "BRL" | "USD",
434
+ _count: number | null,
435
+ perItem: number | null,
436
+ perHour: number | null,
437
+ ): string {
438
+ const formatRate = (value: number | null) =>
439
+ fact?.state === "unavailable" || value === null || !Number.isFinite(value)
440
+ ? "—"
441
+ : formatRoundedCurrency(value, currency, locale);
442
+ const item = formatRate(perItem);
443
+ const hour = formatRate(perHour);
444
+ return `${item} / ${unit} (${hour} / ${locale === "pt-BR" ? "hora" : "hour"})`;
445
+ }
446
+
388
447
  export function partialOverviewMetrics(data: OperationsProjection) {
389
448
  return data.summary.overview_metrics;
390
449
  }
@@ -450,18 +509,20 @@ export function Kpi({
450
509
  label,
451
510
  value,
452
511
  hint,
512
+ description,
453
513
  featured = false,
454
514
  onSelect,
455
515
  }: {
456
516
  label: string;
457
517
  value: string;
458
518
  hint: string;
519
+ description?: string | undefined;
459
520
  featured?: boolean;
460
521
  onSelect?: (() => void) | undefined;
461
522
  }) {
462
523
  const content = (
463
524
  <>
464
- <span>{label}</span>
525
+ <span title={description}>{label}</span>
465
526
  <strong>{value}</strong>
466
527
  <small>{hint}</small>
467
528
  </>
@@ -469,6 +530,7 @@ export function Kpi({
469
530
  if (onSelect !== undefined) {
470
531
  return (
471
532
  <button
533
+ aria-description={description}
472
534
  aria-pressed={featured}
473
535
  aria-label={`${label}: ${value}. ${hint}`}
474
536
  className={`operations-kpi is-selectable${featured ? " is-featured" : ""}`}
@@ -481,6 +543,7 @@ export function Kpi({
481
543
  }
482
544
  return (
483
545
  <article
546
+ aria-description={description}
484
547
  aria-label={`${label}: ${value}. ${hint}`}
485
548
  className={`operations-kpi${featured ? " is-featured" : ""}`}
486
549
  >
@@ -5,10 +5,14 @@ import {
5
5
  executionMetricTotals,
6
6
  operationalRootExecutionDuration,
7
7
  } from "./execution-metrics.js";
8
+ import { overviewCostForRates, overviewCostRateHint } from "./OperationsOverview.helpers.js";
8
9
  import {
9
10
  aggregateMacroMetrics,
10
11
  aggregateTaskMetrics,
11
12
  countExecutionDays,
13
+ factualCostAverageLabel,
14
+ factualCostMetricHint,
15
+ factualCostMetricLabel,
12
16
  formatExecutionAverageHint,
13
17
  formatSummaryMetricValue,
14
18
  formatTokenThroughputHint,
@@ -128,6 +132,61 @@ describe("partial overview charts", () => {
128
132
  });
129
133
  });
130
134
  describe("overview aggregate source", () => {
135
+ it("allocates known spend without imputing unknown costs and labels partial coverage", () => {
136
+ const fact = { state: "partial", knownSum: 12.5, coverage: { known: 3, total: 5 } } as const;
137
+ expect(factualCostMetricLabel(fact, "pt-BR")).toBe("Custo Estimado");
138
+ expect(factualCostMetricHint(fact, "tarefa", "pt-BR")).toContain("3 de 5 runs");
139
+ expect(factualCostAverageLabel(fact, 2, "pt-BR")).toContain("cobertura parcial (3/5 runs)");
140
+ expect(overviewCostForRates(fact, 12.5)).toBe(12.5);
141
+ expect(overviewCostForRates({ ...fact, knownSum: 0 }, 0)).toBe(0);
142
+ expect(
143
+ overviewCostForRates({ ...fact, state: "complete", coverage: { known: 5, total: 5 } }, 0),
144
+ ).toBe(0);
145
+ expect(overviewCostRateHint(fact, "tarefa", "pt-BR", "BRL", 2, null, null)).toBe(
146
+ "— / tarefa (— / hora)",
147
+ );
148
+ expect(
149
+ resolveOverviewCostTotal({
150
+ currency: "BRL",
151
+ factualSnapshotFact: fact,
152
+ factualSnapshotTotal: null,
153
+ overviewView: "tasks",
154
+ resolvedRunTotal: 99,
155
+ operationsBrlTotal: 99,
156
+ }),
157
+ ).toBe(12.5);
158
+ const source = readOverviewSource();
159
+ const costCard = readOverviewSource("OverviewCostKpi.tsx");
160
+ expect(costCard).toContain("factualCostMetricLabel(fact, locale)");
161
+ expect(costCard).toContain("overviewCostRateHint(");
162
+ expect(source).toContain("factualCostAverageLabel(");
163
+ });
164
+ it("keeps complete zero and unavailable facts distinct", () => {
165
+ expect(
166
+ resolveOverviewCostTotal({
167
+ currency: "USD",
168
+ factualSnapshotFact: {
169
+ state: "complete",
170
+ knownSum: 0,
171
+ coverage: { known: 0, total: 0 },
172
+ },
173
+ factualSnapshotTotal: null,
174
+ overviewView: "tasks",
175
+ resolvedRunTotal: 1,
176
+ operationsBrlTotal: 1,
177
+ }),
178
+ ).toBe(0);
179
+ expect(
180
+ resolveOverviewCostTotal({
181
+ currency: "USD",
182
+ factualSnapshotFact: { state: "unavailable", knownSum: null, coverage: null },
183
+ factualSnapshotTotal: 1,
184
+ overviewView: "tasks",
185
+ resolvedRunTotal: 1,
186
+ operationsBrlTotal: 1,
187
+ }),
188
+ ).toBeNull();
189
+ });
131
190
  it("keeps aggregate-only Top 5 USD factual and leaves a missing value unavailable", () => {
132
191
  const source = readOverviewSource();
133
192
  const topPanelSource = readOverviewSource("OperationsOverviewTopPanel.tsx");
@@ -158,6 +217,17 @@ describe("overview aggregate source", () => {
158
217
  }),
159
218
  ).toBeNull();
160
219
  });
220
+ it("does not replace authoritative unavailable cost with a known-zero partial fallback", () => {
221
+ expect(
222
+ resolveOverviewCostTotal({
223
+ currency: "BRL",
224
+ factualSnapshotTotal: null,
225
+ overviewView: "tasks",
226
+ resolvedRunTotal: 0,
227
+ operationsBrlTotal: 0,
228
+ }),
229
+ ).toBeNull();
230
+ });
161
231
  it("uses a selected macro's factual USD total rather than the global Task snapshot", () => {
162
232
  expect(
163
233
  resolveOverviewCostTotal({
@@ -361,7 +431,7 @@ describe("overviewMetricAverages", () => {
361
431
  expect(averages).toEqual({ durationMs: null, tokens: null, costBrl: null });
362
432
  const source = readOverviewSource();
363
433
  expect(source).toContain(
364
- "durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: totalCostMetric",
434
+ "durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: rateCost",
365
435
  );
366
436
  expect(formatSummaryMetricValue(null, 0, (value) => String(value), "pt-BR")).toBe("0");
367
437
  expect(formatSummaryMetricValue(null, 0, (value) => String(value), "en-US")).toBe("0");
@@ -1,4 +1,4 @@
1
- import { formatRoundedCurrency, formatSummaryMetricValue } from "./overview-metric-format.js";
1
+ import { formatSummaryMetricValue } from "./overview-metric-format.js";
2
2
 
3
3
  export { formatSummaryMetricValue } from "./overview-metric-format.js";
4
4
 
@@ -18,11 +18,13 @@ import {
18
18
  aggregateTaskMetrics,
19
19
  canonicalMacroMetric,
20
20
  countExecutionDays,
21
+ factualCostAverageLabel,
21
22
  findLatestCreatedAt,
22
23
  formatExecutionAverageHint,
23
24
  Kpi,
24
25
  macroClassificationStats,
25
26
  overviewCopy,
27
+ overviewCostForRates,
26
28
  overviewMetricAverages,
27
29
  overviewText,
28
30
  partialOverviewMetrics,
@@ -39,8 +41,10 @@ import {
39
41
  } from "./OperationsOverview.helpers.js";
40
42
  import { OperationsOverviewCharts } from "./OperationsOverviewCharts.js";
41
43
  import { OperationsOverviewTopPanel } from "./OperationsOverviewTopPanel.js";
44
+ import { OverviewCostKpi } from "./OverviewCostKpi.js";
42
45
  import type { OperationDatePreset, OperationDateRange } from "./operation-date-range.js";
43
46
  import type {
47
+ FactualCostFact,
44
48
  OverviewClassification,
45
49
  OverviewClassificationPage,
46
50
  OverviewStatusKind,
@@ -55,6 +59,9 @@ export {
55
59
  aggregateTaskMetrics,
56
60
  canonicalMacroMetric,
57
61
  countExecutionDays,
62
+ factualCostAverageLabel,
63
+ factualCostMetricHint,
64
+ factualCostMetricLabel,
58
65
  findLatestCreatedAt,
59
66
  findLatestTaskCreatedAt,
60
67
  formatExecutionAverageHint,
@@ -96,6 +103,7 @@ export function OperationsOverview({
96
103
  specs = data.specs,
97
104
  tasks = data.tasks,
98
105
  factualCostTotal,
106
+ factualCostFact,
99
107
  resolveRunCost,
100
108
  includeLegacyEffort: _includeLegacyEffort = false,
101
109
  }: {
@@ -131,6 +139,8 @@ export function OperationsOverview({
131
139
  tasks?: OperationsProjection["tasks"];
132
140
  /** Factual Cost Monitor snapshot total for the selected locale/currency. */
133
141
  factualCostTotal?: number | null | undefined;
142
+ /** Measurement completeness for the matching Cost Monitor snapshot. */
143
+ factualCostFact?: FactualCostFact | undefined;
134
144
  resolveRunCost?: ((runId: string) => number | null) | undefined;
135
145
  includeLegacyEffort?: boolean;
136
146
  }) {
@@ -304,6 +314,7 @@ export function OperationsOverview({
304
314
  // from Cost Monitor's factual per-Run estimates; never relabel BRL as USD.
305
315
  const totalCostMetric = resolveOverviewCostTotal({
306
316
  currency,
317
+ factualSnapshotFact: overviewView === "tasks" ? factualCostFact : undefined,
307
318
  factualSnapshotTotal: factualCostTotal,
308
319
  macroCostTotal: canonicalMacroMetric(
309
320
  selectedMacroAggregate !== undefined,
@@ -314,14 +325,18 @@ export function OperationsOverview({
314
325
  resolvedRunTotal: selectedCurrencyCost,
315
326
  operationsBrlTotal: overviewMetrics?.cost_brl ?? allPhaseMetrics.costBrl,
316
327
  });
328
+ const rateCost = overviewCostForRates(
329
+ overviewView === "tasks" ? factualCostFact : undefined,
330
+ totalCostMetric,
331
+ );
317
332
  const hourlyCost =
318
- totalDurationMetric === null || totalDurationMetric <= 0 || totalCostMetric === null
333
+ totalDurationMetric === null || totalDurationMetric <= 0 || rateCost === null
319
334
  ? null
320
- : (totalCostMetric * 3_600_000) / totalDurationMetric;
335
+ : (rateCost * 3_600_000) / totalDurationMetric;
321
336
  const costPerTask =
322
- totalCostMetric === null || metricPopulationCount === null || metricPopulationCount === 0
337
+ rateCost === null || metricPopulationCount === null || metricPopulationCount === 0
323
338
  ? null
324
- : totalCostMetric / metricPopulationCount;
339
+ : rateCost / metricPopulationCount;
325
340
  const tokensPerTask =
326
341
  totalTokensMetric === null || metricPopulationCount === null || metricPopulationCount === 0
327
342
  ? null
@@ -332,7 +347,7 @@ export function OperationsOverview({
332
347
  : (totalTokensMetric * 3_600_000) / totalDurationMetric;
333
348
  const averageMetricTotals =
334
349
  overviewView === "tasks"
335
- ? { durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: totalCostMetric }
350
+ ? { durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: rateCost }
336
351
  : {
337
352
  durationMs: canonicalMacroMetric(
338
353
  selectedMacroAggregate !== undefined,
@@ -397,7 +412,11 @@ export function OperationsOverview({
397
412
  ),
398
413
  ],
399
414
  [
400
- text.averageCost,
415
+ factualCostAverageLabel(
416
+ overviewView === "tasks" ? factualCostFact : undefined,
417
+ selectedCount,
418
+ locale,
419
+ ),
401
420
  formatSummaryMetricValue(
402
421
  averageCost,
403
422
  selectedCount,
@@ -618,35 +637,22 @@ export function OperationsOverview({
618
637
  locale,
619
638
  )}
620
639
  />{" "}
621
- <Kpi
622
- hint={
623
- hourlyCost === null || costPerTask === null
624
- ? metricPopulationCount === 0
625
- ? locale === "pt-BR"
626
- ? `${formatRoundedCurrency(0, currency, locale)} / ${metricUnit} (${formatRoundedCurrency(0, currency, locale)} / hora)`
627
- : `${formatRoundedCurrency(0, currency, locale)} / ${metricUnit} (${formatRoundedCurrency(0, currency, locale)} / hour)`
628
- : locale === "pt-BR"
629
- ? "Custo por tarefa e por hora indispon\u00edvel"
630
- : "Cost per task and hour unavailable"
631
- : locale === "pt-BR"
632
- ? `${formatRoundedCurrency(costPerTask, currency, locale)} / ${metricUnit} (${formatRoundedCurrency(hourlyCost, currency, locale)} / hora)`
633
- : `${formatRoundedCurrency(costPerTask, currency, locale)} / ${metricUnit} (${formatRoundedCurrency(hourlyCost, currency, locale)} / hour)`
634
- }
640
+ <OverviewCostKpi
641
+ fact={overviewView === "tasks" ? factualCostFact : undefined}
642
+ unit={metricUnit}
643
+ locale={locale}
644
+ currency={currency}
645
+ count={metricPopulationCount}
646
+ perItem={costPerTask}
647
+ perHour={hourlyCost}
648
+ total={totalCostMetric}
635
649
  label={
636
650
  overviewView === "tasks"
637
- ? locale === "pt-BR"
638
- ? "Custo Estimado"
639
- : "Estimated cost"
651
+ ? undefined
640
652
  : locale === "pt-BR"
641
653
  ? `Custo de ${copy.shortPlural}`
642
654
  : `${copy.shortPlural} cost`
643
655
  }
644
- value={formatSummaryMetricValue(
645
- totalCostMetric,
646
- metricPopulationCount,
647
- (value) => formatRoundedCurrency(value, currency, locale),
648
- locale,
649
- )}
650
656
  />{" "}
651
657
  </div>
652
658
  <div className="operations-chart-grid">
@@ -119,6 +119,7 @@ export function OperationsPage({
119
119
  repositoryName,
120
120
  settings,
121
121
  factualCostTotal,
122
+ factualCostFact,
122
123
  factualCostPeriods,
123
124
  resolveRunCost,
124
125
  }: OperationsPageProps) {
@@ -147,6 +148,7 @@ export function OperationsPage({
147
148
  dateRange: controlledDateRange,
148
149
  fallbackPreset: localDatePreset,
149
150
  fallbackRange: localDateRange,
151
+ allTimeRange: defaultDateRange,
150
152
  });
151
153
  const isPeriodControlled = periodControl.controlled;
152
154
  const dateRange = periodControl.dateRange;
@@ -161,20 +163,8 @@ export function OperationsPage({
161
163
  },
162
164
  [isPeriodControlled, onDateChange, onPeriodChange],
163
165
  );
164
- // A controlled parent initially owns the range selected before the factual
165
- // Cost summary arrives. Once it does, synchronize only All Time's displayed
166
- // coverage range; requestPeriodForOperations still omits both bounds.
167
- useEffect(() => {
168
- if (
169
- datePreset !== "all" ||
170
- (dateRange.start === defaultDateRange.start && dateRange.end === defaultDateRange.end)
171
- )
172
- return;
173
- updatePeriod("all", defaultDateRange);
174
- }, [datePreset, dateRange.end, dateRange.start, defaultDateRange, updatePeriod]);
175
- useEffect(() => {
176
- if (!isPeriodControlled && datePreset === "all") setLocalDateRange(defaultDateRange);
177
- }, [datePreset, defaultDateRange, isPeriodControlled]);
166
+ // Coverage is derived display data, not a user selection. Never feed it
167
+ // back through onDateChange: a delayed effect can overwrite a newer period.
178
168
  const showFilterLoading = useCallback(() => {
179
169
  setFilterLoading(true);
180
170
  if (filterLoadingTimer.current !== null) window.clearTimeout(filterLoadingTimer.current);
@@ -680,6 +670,7 @@ export function OperationsPage({
680
670
  prds={prds}
681
671
  query={query}
682
672
  factualCostTotal={factualCostTotal}
673
+ factualCostFact={factualCostFact}
683
674
  resolveRunCost={resolveRunCost}
684
675
  runs={runs}
685
676
  searchInputRef={searchInputRef}
@@ -19,6 +19,7 @@ export function OperationsPageOverview({
19
19
  dateRange,
20
20
  defaultDateRange,
21
21
  factualCostTotal,
22
+ factualCostFact,
22
23
  includeLegacyEffort,
23
24
  locale,
24
25
  onOpenTask,
@@ -47,6 +48,7 @@ export function OperationsPageOverview({
47
48
  dateRange: OperationDateRange;
48
49
  defaultDateRange: OperationDateRange;
49
50
  factualCostTotal: OverviewProps["factualCostTotal"];
51
+ factualCostFact: OverviewProps["factualCostFact"];
50
52
  includeLegacyEffort: boolean;
51
53
  locale: OperationsLocale;
52
54
  onOpenTask: OverviewProps["onOpenTask"];
@@ -74,6 +76,7 @@ export function OperationsPageOverview({
74
76
  data={data}
75
77
  currency={currency}
76
78
  factualCostTotal={factualCostTotal}
79
+ factualCostFact={factualCostFact}
77
80
  datePreset={datePreset}
78
81
  dateRange={dateRange}
79
82
  locale={locale}
@@ -0,0 +1,46 @@
1
+ import {
2
+ factualCostMetricHint,
3
+ factualCostMetricLabel,
4
+ Kpi,
5
+ overviewCostRateHint,
6
+ } from "./OperationsOverview.helpers.js";
7
+ import type { FactualCostFact } from "./operations-page-contract.js";
8
+ import { formatRoundedCurrency, formatSummaryMetricValue } from "./overview-metric-format.js";
9
+ import type { OperationsLocale } from "./status-labels.js";
10
+
11
+ /** Compact presentation, preserving completeness and matching population semantics. */
12
+ export function OverviewCostKpi({
13
+ fact,
14
+ unit,
15
+ locale,
16
+ currency,
17
+ count,
18
+ perItem,
19
+ perHour,
20
+ total,
21
+ label,
22
+ }: {
23
+ fact: FactualCostFact | undefined;
24
+ unit: string;
25
+ locale: OperationsLocale;
26
+ currency: "BRL" | "USD";
27
+ count: number | null;
28
+ perItem: number | null;
29
+ perHour: number | null;
30
+ total: number | null;
31
+ label?: string | undefined;
32
+ }) {
33
+ return (
34
+ <Kpi
35
+ hint={overviewCostRateHint(fact, unit, locale, currency, count, perItem, perHour)}
36
+ description={factualCostMetricHint(fact, unit, locale) ?? undefined}
37
+ label={label ?? factualCostMetricLabel(fact, locale)}
38
+ value={formatSummaryMetricValue(
39
+ total,
40
+ count,
41
+ (value) => formatRoundedCurrency(value, currency, locale),
42
+ locale,
43
+ )}
44
+ />
45
+ );
46
+ }
@@ -2,9 +2,36 @@ import { readFileSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { describe, expect, it } from "vitest";
4
4
  import type { DashboardTaskProjection, MacroProjection, RunProjection } from "../contracts.js";
5
- import { buildWorkListRows, formatWorkListDuration } from "./UnifiedWorkList.js";
5
+ import {
6
+ buildWorkListRows,
7
+ formatWorkListDuration,
8
+ workListStageLabel,
9
+ } from "./UnifiedWorkList.js";
6
10
 
7
11
  describe("buildWorkListRows", () => {
12
+ it("retains unexecuted Task drafts without labeling them as SPEC planning", () => {
13
+ const task = {
14
+ id: "TASK-DRAFT",
15
+ title: "Unprepared work",
16
+ status: "draft",
17
+ progress: 0,
18
+ spec_id: null,
19
+ execution_started: false,
20
+ execution_count: 0,
21
+ attempt_count: 0,
22
+ } as DashboardTaskProjection;
23
+ const [row] = buildWorkListRows({
24
+ allSpecs: [],
25
+ allTasks: [task],
26
+ changes: [],
27
+ items: [{ kind: "task", row: task }],
28
+ runs: [],
29
+ });
30
+ expect(row?.stage).toBe("draft");
31
+ if (row === undefined) throw new Error("Expected the draft to remain visible in the list");
32
+ expect(workListStageLabel(row.stage, "pt-BR")).toBe("Rascunho");
33
+ expect(workListStageLabel(row.stage, "en-US")).toBe("Draft");
34
+ });
8
35
  it("labels only active missing time as in progress and preserves temporal absence elsewhere", () => {
9
36
  expect(formatWorkListDuration(null, "executing", "pt-BR")).toBe("Em andamento");
10
37
  expect(formatWorkListDuration(null, "blocked", "pt-BR")).toBe("Sem atribuição temporal");
@@ -26,10 +26,11 @@ import {
26
26
  type WorkItem =
27
27
  | { kind: "task"; row: DashboardTaskProjection }
28
28
  | { kind: "prd" | "spec"; row: MacroProjection };
29
+ type WorkListStage = WorkStage | "draft" | "unstaged";
29
30
 
30
31
  interface WorkListRow {
31
32
  item: WorkItem;
32
- stage: WorkStage;
33
+ stage: WorkListStage;
33
34
  risk: string | null;
34
35
  progress: string;
35
36
  durationMs: number | null;
@@ -109,7 +110,7 @@ export function UnifiedWorkList({
109
110
  label: "Status",
110
111
  render: ({ stage }) => (
111
112
  <span className={`operations-status is-${stage}`}>
112
- {workStageLabel(stage, locale)}
113
+ {workListStageLabel(stage, locale)}
113
114
  </span>
114
115
  ),
115
116
  sortValue: ({ stage }) => stage,
@@ -214,7 +215,7 @@ export function UnifiedWorkList({
214
215
 
215
216
  export function formatWorkListDuration(
216
217
  durationMs: number | null,
217
- stage: WorkStage,
218
+ stage: WorkListStage,
218
219
  locale: OperationsLocale,
219
220
  ): string {
220
221
  if (durationMs !== null) return formatRoundedDuration(durationMs);
@@ -224,6 +225,12 @@ export function formatWorkListDuration(
224
225
  );
225
226
  }
226
227
 
228
+ export function workListStageLabel(stage: WorkListStage, locale: OperationsLocale): string {
229
+ if (stage === "draft") return locale === "pt-BR" ? "Rascunho" : "Draft";
230
+ if (stage === "unstaged") return locale === "pt-BR" ? "Sem etapa" : "Unstaged";
231
+ return workStageLabel(stage, locale);
232
+ }
233
+
227
234
  export function buildWorkListRows({
228
235
  allSpecs,
229
236
  allTasks,
@@ -269,7 +276,7 @@ export function buildWorkListRows({
269
276
  }
270
277
  return {
271
278
  item,
272
- stage: taskWorkStage(task) ?? "planning",
279
+ stage: taskWorkStage(task) ?? (task.status === "draft" ? "draft" : "unstaged"),
273
280
  risk: task.risk ?? null,
274
281
  progress: `${Math.round(task.progress)}%`,
275
282
  durationMs: taskUsage?.durationMs ?? (hasProvenNoTaskActivity(task, relatedRuns) ? 0 : null),
@@ -6,6 +6,7 @@ export * from "./MacroBoard.js";
6
6
  export * from "./MacroPlanningDialog.js";
7
7
  export * from "./OperationsPage.js";
8
8
  export * from "./operation-date-range.js";
9
+ export type { FactualCostFact } from "./operations-page-contract.js";
9
10
  export * from "./PrdDocumentDialog.js";
10
11
  export * from "./TaskBoard.js";
11
12
  export * from "./TaskDetailsDialog.js";
@@ -49,8 +49,8 @@ describe("Operations persisted aggregate display", () => {
49
49
  expect(overview).toContain("const totalDurationMetric = scopedOverviewMetric(");
50
50
  expect(overview).toContain("selectedMacroTotals?.durationMs,");
51
51
  expect(overview).toContain("const totalCostMetric =");
52
- expect(overview).toContain(
53
- "durationMs: totalDurationMetric, tokens: totalTokensMetric, costBrl: totalCostMetric",
52
+ expect(overview).toMatch(
53
+ /durationMs: totalDurationMetric,\s*tokens: totalTokensMetric,\s*costBrl: rateCost/,
54
54
  );
55
55
  expect(overview).toContain("formatSummaryMetricValue(\n averageDuration,");
56
56
  expect(overview).toContain('populationCount === 0 ? "0"');