@zaip-ai/cli 3.3.0 → 3.5.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 (288) hide show
  1. package/dist/services/adapters.d.ts +1 -1
  2. package/dist/services/adapters.d.ts.map +1 -1
  3. package/dist/services/adapters.js +4 -3
  4. package/dist/services/adapters.js.map +1 -1
  5. package/dist/services/agent-catalog-upgrade.d.ts +3 -0
  6. package/dist/services/agent-catalog-upgrade.d.ts.map +1 -0
  7. package/dist/services/agent-catalog-upgrade.js +35 -0
  8. package/dist/services/agent-catalog-upgrade.js.map +1 -0
  9. package/dist/services/install-agents-template.d.ts.map +1 -1
  10. package/dist/services/install-agents-template.js +22 -22
  11. package/dist/services/install-agents-template.js.map +1 -1
  12. package/dist/services/install-template-policy.d.ts +3 -0
  13. package/dist/services/install-template-policy.d.ts.map +1 -0
  14. package/dist/services/install-template-policy.js +21 -0
  15. package/dist/services/install-template-policy.js.map +1 -0
  16. package/dist/services/logger.test.js +12 -2
  17. package/dist/services/logger.test.js.map +1 -1
  18. package/dist/services/sqlite-bootstrap.d.ts +1 -0
  19. package/dist/services/sqlite-bootstrap.d.ts.map +1 -1
  20. package/dist/services/sqlite-bootstrap.js +10 -1
  21. package/dist/services/sqlite-bootstrap.js.map +1 -1
  22. package/package.json +2 -2
  23. package/templates/.agents/config/agents/discovery.json +1 -1
  24. package/templates/.agents/dashboard/.zaip-managed.json +286 -126
  25. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-BBFDrn64.js → CostCalculationGuidePage-C5NgEcVh.js} +1 -1
  26. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cd-qo9w7.js → DashboardHelpDialog-CCMVnkkI.js} +1 -1
  27. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-J7L5m8lk.js → PricingSettingsDialog-CGYcJ5EB.js} +1 -1
  28. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-B9GWkEyN.css → ProjectSettingsPage-CQMhvzvJ.css} +1 -1
  29. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-D46WWIKr.js +3 -0
  30. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-BzVtGLWS.js → TraceabilityWorkspace-BKBpJyLh.js} +1 -1
  31. package/templates/.agents/dashboard/apps/frontend/dist/assets/{cost-monitor-PoJA2PI1.css → cost-monitor-BsMfGfQi.css} +1 -1
  32. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-j3aUYH5G.js +68 -0
  33. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-CWzf_RiP.js → icons-vendor-x8xxL9yW.js} +1 -1
  34. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Bas2TVju.js +2 -0
  35. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CxrG_wRI.css +1 -0
  36. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CtHdbZk3.js → react-vendor-CNOXIJHN.js} +1 -1
  37. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-BKrDH2TR.js → traceability-CcpbpT1s.js} +1 -1
  38. package/templates/.agents/dashboard/apps/frontend/dist/index.html +7 -7
  39. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  40. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +12 -1
  41. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsCard.tsx +5 -0
  42. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsField.tsx +21 -0
  43. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.dom.test.ts +12 -1
  44. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +16 -28
  45. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +25 -4
  46. package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.test.tsx +51 -0
  47. package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.tsx +39 -0
  48. package/templates/.agents/dashboard/apps/frontend/src/app-work-board-options.ts +41 -0
  49. package/templates/.agents/dashboard/apps/frontend/src/dashboard-runtime-status.ts +25 -0
  50. package/templates/.agents/dashboard/apps/frontend/src/project-settings-copy.ts +13 -4
  51. package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +25 -1
  52. package/templates/.agents/dashboard/apps/frontend/src/project-settings-workspace.css +28 -0
  53. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +39 -0
  54. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +1 -1
  55. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +5 -1
  56. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.test.ts +140 -0
  57. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.ts +28 -41
  58. package/templates/.agents/dashboard/apps/frontend/src/use-runtime-status.ts +38 -0
  59. package/templates/.agents/dashboard/apps/frontend/src/workspace-status.css +20 -0
  60. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  61. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +25 -3
  62. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +17 -19
  63. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +13 -167
  64. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.tsx +2 -9
  65. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +8 -8
  66. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +29 -52
  67. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.test.ts +1 -1
  68. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +2 -2
  69. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +4 -27
  70. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +2 -2
  71. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +4 -3
  72. package/templates/.agents/dashboard/modules/cost-monitor/src/react/agent-model-presentation.test.ts +26 -0
  73. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-embedded.css +7 -0
  74. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-loaders.ts +173 -0
  75. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-props.ts +47 -0
  76. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-selectors.ts +1 -7
  77. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-page-range.ts +3 -9
  78. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +44 -83
  79. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +11 -111
  80. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +47 -181
  81. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +63 -91
  82. package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-monitor-unavailable.test.ts +55 -0
  83. package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-summary-duration.test.ts +189 -0
  84. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  85. package/templates/.agents/dashboard/modules/operations/src/react/OperationsEntityFilters.tsx +82 -0
  86. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +22 -31
  87. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.test.tsx +13 -1
  88. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.tsx +16 -3
  89. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +11 -27
  90. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +44 -193
  91. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportColumns.ts +186 -0
  92. package/templates/.agents/dashboard/modules/operations/src/react/export/excel-agent-participations.test.ts +28 -0
  93. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +2 -1
  94. package/templates/.agents/dashboard/modules/operations/src/react/operations-export-duration.ts +13 -0
  95. package/templates/.agents/dashboard/modules/operations/src/react/operations-filter-panel.css +4 -0
  96. package/templates/.agents/dashboard/modules/operations/src/react/use-operation-filter-feedback.ts +18 -0
  97. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +11 -0
  98. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +10 -2
  99. package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +1 -1
  100. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  101. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  102. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  103. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  104. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +395 -341
  105. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +346 -294
  106. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  107. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +2 -1
  108. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +42 -8
  109. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +395 -341
  110. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +95 -0
  111. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +102 -12
  112. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +2 -3
  113. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +1 -1
  114. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +75 -1
  115. package/templates/.agents/dashboard/packages/local-runtime/src/server-costs-routes.ts +10 -0
  116. package/templates/.agents/dashboard/packages/local-runtime/src/server-lifecycle-diagnostics.ts +50 -0
  117. package/templates/.agents/dashboard/packages/local-runtime/src/server-macro-population.test.ts +165 -0
  118. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-page-filters.ts +65 -0
  119. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +111 -0
  120. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +53 -63
  121. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +19 -5
  122. package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.ts +11 -2
  123. package/templates/.agents/dashboard/packages/local-runtime/src/server-read-projections.ts +16 -9
  124. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +46 -2
  125. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.test.ts +10 -2
  126. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +4 -3
  127. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +43 -1
  128. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +46 -11
  129. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts +188 -0
  130. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-summary-details.test.ts +85 -0
  131. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-summary-details.ts +147 -0
  132. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +64 -54
  133. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-macro-classification.test.ts +172 -0
  134. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-projections.ts +1 -1
  135. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +2 -1
  136. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +7 -7
  137. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +2 -1
  138. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-period-averages.ts +10 -1
  139. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-pricing-provenance.test.ts +39 -0
  140. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-agent-dimension.ts +18 -82
  141. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-cached-cost-page.ts +169 -0
  142. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-developer.ts +205 -0
  143. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.ts +13 -4
  144. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-filtered-dimension.ts +22 -23
  145. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-financial.ts +42 -209
  146. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-model-dimension.ts +18 -4
  147. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-provider-dimension.ts +9 -2
  148. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +76 -83
  149. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-view-page.ts +25 -161
  150. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +20 -47
  151. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +2 -2
  152. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-filesystem.ts +16 -16
  153. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +1 -1
  154. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +47 -22
  155. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +3 -2
  156. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +11 -0
  157. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-rebuild-result.ts +15 -0
  158. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-base-views.ts +4 -4
  159. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts +15 -56
  160. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-macro-classification.ts +48 -0
  161. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-summary-cursor.ts +15 -0
  162. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-token-active-allocation.ts +46 -0
  163. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-stages.ts +60 -0
  164. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +5 -1
  165. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-claims.test.mjs +7 -1
  166. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +17 -2
  167. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-ownership.mjs +65 -0
  168. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-ownership.test.mjs +72 -0
  169. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +32 -9
  170. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +39 -45
  171. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +5 -2
  172. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  173. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  174. package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +1 -18
  175. package/templates/.agents/dashboard/tests/e2e/specs/export-row-identity.spec.ts +20 -0
  176. package/templates/.agents/dashboard/tests/e2e/specs/export-row-identity.ts +20 -0
  177. package/templates/.agents/design/.zaip-managed.json +105 -69
  178. package/templates/.agents/design/apps/catalog/dist/assets/index-0W0Gj_Gs.css +1 -0
  179. package/templates/.agents/design/apps/catalog/dist/assets/index-32GZO95T.js +72 -0
  180. package/templates/.agents/design/apps/catalog/dist/assets/{index-D_lfqoyx.js → index-BP8IxOxt.js} +3 -3
  181. package/templates/.agents/design/apps/catalog/dist/assets/index-D1JaPXfV.css +1 -0
  182. package/templates/.agents/design/apps/catalog/dist/assets/index-D2miO4-O.js +72 -0
  183. package/templates/.agents/design/apps/catalog/dist/assets/{index-BOjCcUaU.js → index-QJsgr9Ht.js} +3 -3
  184. package/templates/.agents/design/apps/catalog/dist/assets/{index-CqtYXZfV.js → index-mvD5mwcC.js} +3 -3
  185. package/templates/.agents/design/apps/catalog/dist/index.html +2 -2
  186. package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-BJ8b4xZr.js +1 -0
  187. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Color-6AOWCN3U-Cm-yJJz_.js → Color-6AOWCN3U-CQLHzznn.js} +1 -1
  188. package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-kxWwSKin.js +146 -0
  189. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DashboardFilters.stories-Chm_dXV7.js +9 -0
  190. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DashboardFiltersSpecimen-9CaCbGIZ.js +1 -0
  191. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-ED52wFjY.js +1 -0
  192. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DocsRenderer-JROSPFPF-Belk4jRr.js → DocsRenderer-JROSPFPF-BcLgM80v.js} +4 -4
  193. package/templates/.agents/design/apps/catalog/dist/storybook/assets/Primitives-DV6Bpudf.js +1 -0
  194. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WithTooltip-7X4HQR7L-DoPvjkS1.js → WithTooltip-7X4HQR7L-BKNiAz_E.js} +1 -1
  195. package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatus.stories-BL19HGOo.js +17 -0
  196. package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatusSpecimen-DQnSS6s9.js +1 -0
  197. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-DRQKCCAG-B1itKXEN.js → chunk-DRQKCCAG-DZBcXL-p.js} +1 -1
  198. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-W22LQPXL-C-Eb5SPY.js → chunk-W22LQPXL-CF3y2mfo.js} +1 -1
  199. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{components-DnyKLwhj.js → components-BVjxMRGq.js} +5 -5
  200. package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-Do9sjqiW.js +1 -0
  201. package/templates/.agents/design/apps/catalog/dist/storybook/assets/iframe-0W0Gj_Gs.css +1 -0
  202. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{iframe-DcXBsFPz.js → iframe-CTWGZcEe.js} +4 -4
  203. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{react-18-CRM89QRf.js → react-18-B9_a4mHb.js} +1 -1
  204. package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-NrUxok8K.js +1 -0
  205. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{syntaxhighlighter-YFXUGROL-B03jQGTF.js → syntaxhighlighter-YFXUGROL-F_p8E2xc.js} +1 -1
  206. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{theming-4ZyufAga.js → theming-fbSD9ZLF.js} +1 -1
  207. package/templates/.agents/design/apps/catalog/dist/storybook/iframe.html +2 -2
  208. package/templates/.agents/design/apps/catalog/dist/storybook/index.json +1 -1
  209. package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/a11y-2/manager-bundle.js +3 -3
  210. package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +3 -3
  211. package/templates/.agents/design/apps/catalog/package.json +1 -1
  212. package/templates/.agents/design/apps/catalog/src/components/DashboardFiltersSpecimen.tsx +61 -0
  213. package/templates/.agents/design/apps/catalog/src/components/Primitives.tsx +24 -0
  214. package/templates/.agents/design/apps/catalog/src/components/StackVersionFieldSpecimen.tsx +70 -0
  215. package/templates/.agents/design/apps/catalog/src/components/WorkspaceStatusSpecimen.tsx +42 -0
  216. package/templates/.agents/design/apps/catalog/src/design-contract.test.ts +27 -13
  217. package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +52 -0
  218. package/templates/.agents/design/apps/catalog/src/pages/DesignSystemPage.tsx +15 -1
  219. package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +32 -0
  220. package/templates/.agents/design/apps/catalog/src/stories/DashboardFilters.stories.tsx +7 -0
  221. package/templates/.agents/design/apps/catalog/src/stories/WorkspaceStatus.stories.tsx +12 -0
  222. package/templates/.agents/design/apps/catalog/src/styles/components.css +84 -3
  223. package/templates/.agents/design/apps/catalog/src/styles/stack-version-field.css +17 -0
  224. package/templates/.agents/design/apps/catalog/src/styles.css +2 -0
  225. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  226. package/templates/.agents/design/tokens.json +32 -0
  227. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  228. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  229. package/templates/.agents/requirements/comparative-audit.md +1 -1
  230. package/templates/.agents/requirements/context-engine.md +1 -1
  231. package/templates/.agents/requirements/cost-observability.md +1 -1
  232. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  233. package/templates/.agents/requirements/data-export.md +1 -1
  234. package/templates/.agents/requirements/design-system.md +1 -1
  235. package/templates/.agents/requirements/execution-engine.md +1 -1
  236. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  237. package/templates/.agents/requirements/model-orchestration.md +1 -1
  238. package/templates/.agents/requirements/public-distribution.md +9 -3
  239. package/templates/.agents/requirements/software-architecture.md +1 -1
  240. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  241. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  242. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  243. package/templates/.agents/rules/autonomy-decision.md +1 -0
  244. package/templates/.agents/rules/workflow.md +2 -2
  245. package/templates/.agents/runtime/VERSION +1 -1
  246. package/templates/.agents/runtime/bin/zaip.mjs +27 -26
  247. package/templates/.agents/runtime/checksums.sha256 +5 -5
  248. package/templates/.agents/runtime/manifest.json +1 -1
  249. package/templates/.agents/runtime/provenance.json +4 -4
  250. package/templates/.agents/runtime/sbom.cdx.json +1 -1
  251. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +13 -0
  252. package/templates/.agents/skills/zaip-skill-execution/references/autonomous-continuation.md +17 -0
  253. package/templates/.agents/skills/zaip-skill-execution/references/correction-cycle.md +2 -2
  254. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -6
  255. package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +1 -1
  256. package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +11 -9
  257. package/templates/.agents/skills/zaip-skill-github-deploy/references/release-identity.md +2 -2
  258. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.mjs +1 -2
  259. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.test.mjs +9 -1
  260. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +23 -0
  261. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.mjs +2 -6
  262. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.test.mjs +15 -1
  263. package/templates/.agents/skills/zaip-skill-move-prd/SKILL.md +4 -0
  264. package/templates/.agents/skills/zaip-skill-move-spec/SKILL.md +4 -0
  265. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +3 -3
  266. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +11 -8
  267. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +13 -12
  268. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +17 -2
  269. package/templates/.agents/skills/zaip-skill-setup/agents/openai.yaml +1 -1
  270. package/templates/.agents/skills/zaip-skill-spec/SKILL.md +2 -2
  271. package/templates/.agents/zaip-aios/VERSION +1 -1
  272. package/templates/template-manifest.json +445 -245
  273. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BpsAFy0g.js +0 -3
  274. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor--iPcnZdx.js +0 -68
  275. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cmlx8OYH.css +0 -1
  276. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DfdlGa7c.js +0 -2
  277. package/templates/.agents/design/apps/catalog/dist/assets/index-BEmIE7WE.css +0 -1
  278. package/templates/.agents/design/apps/catalog/dist/assets/index-BJV597iq.js +0 -72
  279. package/templates/.agents/design/apps/catalog/dist/assets/index-B_WhrCZe.js +0 -72
  280. package/templates/.agents/design/apps/catalog/dist/assets/index-CqqYWY2f.js +0 -9
  281. package/templates/.agents/design/apps/catalog/dist/assets/index-D9pj7Jlf.js +0 -9
  282. package/templates/.agents/design/apps/catalog/dist/assets/index-i_PO2k9R.js +0 -9
  283. package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-Cstn1UwA.js +0 -1
  284. package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-D1WopB2L.js +0 -137
  285. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DQ9PJ3N3.js +0 -1
  286. package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-D0OSgxWz.js +0 -1
  287. package/templates/.agents/design/apps/catalog/dist/storybook/assets/iframe-BEmIE7WE.css +0 -1
  288. package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-C3tkVMIp.js +0 -1
@@ -5,19 +5,16 @@ import type {
5
5
  UsageProjection,
6
6
  } from "@zaip-ai/dashboard-operations/contracts";
7
7
  import {
8
- canonicalAllTimeDurationMs,
9
8
  isAfterLegacyEffortCutoff,
10
9
  LEGACY_EFFORT_DAILY_MS,
11
10
  LEGACY_EFFORT_SNAPSHOT,
12
11
  saoPauloPeriodKey,
13
12
  } from "@zaip-ai/dashboard-operations/contracts";
14
13
  import {
15
- normalizeTokenBackedDailyDuration,
16
14
  hybridDailyDuration as sharedHybridDailyDuration,
17
15
  rootExecutionDurationByDay as sharedRootExecutionDurationByDay,
18
16
  } from "@zaip-ai/dashboard-operations/server";
19
17
  import type { CostGroupRow, CostMonitorProjection } from "../contracts.js";
20
- import { estimatedDurationMs, TOKEN_DURATION_ESTIMATE_BASIS } from "../duration-estimate.js";
21
18
  import { buildCostMonitorProjection, usageForRuns } from "./build-cost-monitor-projection.js";
22
19
 
23
20
  /** Fast Cost Monitor first fold backed only by the durable lifecycle summary. */
@@ -69,9 +66,8 @@ export function buildCostSummaryProjection(
69
66
  for (const day of Object.keys(LEGACY_EFFORT_DAILY_MS))
70
67
  if (!dailyPeriods.has(day)) dailyPeriods.set(day, emptyPeriodSummary());
71
68
  }
72
- // Prefer the compact Run projection whenever it is available: it already
73
- // assigns the shared effective duration to every tokenized Run. Falling
74
- // back to root-only summary timing would turn a tokenized day into 0 s.
69
+ // Prefer persisted SQLite duration facts; legacy inputs retain their
70
+ // observed coverage without deriving elapsed time from token volume.
75
71
  const periodEntries = [...dailyPeriods].filter(([key]) =>
76
72
  inRange(key, operations.filters.from, operations.filters.to),
77
73
  );
@@ -105,32 +101,13 @@ export function buildCostSummaryProjection(
105
101
  if (hasRunMetrics) return factualDurationByDay.get(key) ?? emptyDuration();
106
102
  return dailyDurationSource(key, period);
107
103
  };
108
- const durationBudget = periodEntries.reduce(
109
- (total, [key, period]) => total + durationForDay(key, period).value.known_sum,
110
- 0,
111
- );
112
- const normalizedDurationBudget =
113
- !hasRunMetrics &&
114
- !hasCanonicalSqliteFacts &&
115
- operations.filters.from === null &&
116
- operations.filters.to === null
117
- ? canonicalAllTimeDurationMs(durationBudget)
118
- : durationBudget;
119
104
  const factualDailyRows = new Map(
120
105
  (summary.daily_rows ?? []).map((row) => [row.key, row] as const),
121
106
  );
122
107
  const projectedDaily = periodEntries.map(([key, period]) =>
123
108
  periodRow(key, period, fxRate, durationForDay(key, period), factualDailyRows.get(key)),
124
109
  );
125
- // Canonical SQLite duration is already deduplicated and assigned to the
126
- // correct São Paulo calendar day. Rebalancing it by token population would
127
- // preserve only the all-time total while corrupting each daily row.
128
- const daily = hasCanonicalSqliteFacts
129
- ? projectedDaily
130
- : normalizeTokenBackedGroupBudget(
131
- projectedDaily.map(ensureTokenBackedGroupDuration),
132
- normalizedDurationBudget,
133
- );
110
+ const daily = projectedDaily;
134
111
  const runCount = daily.reduce((total, row) => total + row.run_count, 0);
135
112
  const eventCount = daily.reduce((total, row) => total + row.event_count, 0);
136
113
  // A completely unavailable population must not become a factual zero merely
@@ -199,15 +176,18 @@ export function buildCostSummaryProjection(
199
176
  coverage,
200
177
  },
201
178
  filters_available: {
202
- providers: available?.filters_available.providers ?? [],
203
- agents: available?.filters_available.agents ?? [],
204
- models: available?.filters_available.models ?? [],
205
- statuses: available?.filters_available.statuses ?? [],
206
- priorities: available?.filters_available.priorities ?? [],
207
- risks: available?.filters_available.risks ?? [],
208
- phases: available?.filters_available.phases ?? [],
209
- origins: available?.filters_available.origins ?? [],
210
- work_types: available?.filters_available.work_types ?? [],
179
+ providers:
180
+ summary.filters_available?.providers ?? available?.filters_available.providers ?? [],
181
+ agents: summary.filters_available?.agents ?? available?.filters_available.agents ?? [],
182
+ models: summary.filters_available?.models ?? available?.filters_available.models ?? [],
183
+ statuses: summary.filters_available?.statuses ?? available?.filters_available.statuses ?? [],
184
+ priorities:
185
+ summary.filters_available?.priorities ?? available?.filters_available.priorities ?? [],
186
+ risks: summary.filters_available?.risks ?? available?.filters_available.risks ?? [],
187
+ phases: summary.filters_available?.phases ?? available?.filters_available.phases ?? [],
188
+ origins: summary.filters_available?.origins ?? available?.filters_available.origins ?? [],
189
+ work_types:
190
+ summary.filters_available?.work_types ?? available?.filters_available.work_types ?? [],
211
191
  },
212
192
  configured_agents: available?.configured_agents ?? [],
213
193
  // Compact Run facts preserve total tokens and cost even though component
@@ -240,7 +220,32 @@ export function buildCostSummaryProjection(
240
220
  }
241
221
 
242
222
  function dailyDurationSource(key: string, period: PeriodSummary): DurationSource {
243
- return sharedHybridDailyDuration(key, period) as DurationSource;
223
+ // Preserve the immutable historical aggregate shared with Operations.
224
+ // This fallback is used only without canonical SQLite or compact Run facts,
225
+ // and never allocates that historical aggregate to individual tokenized Runs.
226
+ if ((LEGACY_EFFORT_DAILY_MS[key as keyof typeof LEGACY_EFFORT_DAILY_MS] ?? 0) > 0)
227
+ return sharedHybridDailyDuration(key, period) as DurationSource;
228
+ // The legacy period bucket can carry a persisted factual duration. It is
229
+ // meaningful independently of Run transport and must survive this compact
230
+ // projection. Tokens and financial usage, however, are never timing data.
231
+ if (period.duration !== undefined) {
232
+ const knownRunCount = knownRuns(period.runs, period.duration.unknown);
233
+ return {
234
+ value: period.duration,
235
+ population: runPopulation(period.runs, knownRunCount),
236
+ };
237
+ }
238
+ // A bucket with Runs but no factual duration remains unavailable. In
239
+ // particular, do not convert a tokenized bucket into an hour or a zero.
240
+ return {
241
+ value: {
242
+ known_sum: 0,
243
+ unknown: period.runs,
244
+ complete: period.runs === 0,
245
+ coverage_ratio: period.runs === 0 ? 1 : 0,
246
+ },
247
+ population: runPopulation(period.runs, 0),
248
+ };
244
249
  }
245
250
 
246
251
  function emptyPeriodSummary(): PeriodSummary {
@@ -258,6 +263,8 @@ function emptyPeriodSummary(): PeriodSummary {
258
263
 
259
264
  export interface CostSummarySource {
260
265
  periods: { daily: Record<string, PeriodSummary> };
266
+ /** Distinct compact dimensions for first-fold filter controls. */
267
+ filters_available?: Partial<CostMonitorProjection["filters_available"]>;
261
268
  /**
262
269
  * SQLite's selected financial facts, retained for compact summaries where
263
270
  * no Run transport is present. Values are factual and currency-specific.
@@ -300,7 +307,12 @@ export interface CostSummarySource {
300
307
  duration_ms: number | null;
301
308
  /** Raw factual invocation duration, never a token estimate. */
302
309
  source_duration_ms?: number | null;
303
- duration_provenance?: "observed" | "estimated" | "unavailable";
310
+ duration_provenance?:
311
+ | "observed"
312
+ | "reconciled"
313
+ | "legacy_inferred"
314
+ | "estimated"
315
+ | "unavailable";
304
316
  estimation_basis?: string | null;
305
317
  duration_started_at?: string | null;
306
318
  total_tokens: number | null;
@@ -402,63 +414,23 @@ function summaryRunProjection(
402
414
  function effectiveSummaryRun(
403
415
  run: NonNullable<CostSummarySource["run_metrics"]>[number],
404
416
  ): NonNullable<CostSummarySource["run_metrics"]>[number] {
405
- if (run.duration_ms !== null)
417
+ const duration_ms = run.source_duration_ms ?? run.duration_ms;
418
+ const provenance =
419
+ run.source_duration_ms !== null && run.source_duration_ms !== undefined
420
+ ? "observed"
421
+ : (run.duration_provenance ?? "legacy_inferred");
422
+ if (
423
+ typeof duration_ms === "number" &&
424
+ duration_ms >= 0 &&
425
+ (provenance === "observed" || provenance === "reconciled" || provenance === "legacy_inferred")
426
+ )
406
427
  return {
407
428
  ...run,
408
- duration_provenance: run.duration_provenance ?? "unavailable",
409
- estimation_basis:
410
- run.duration_provenance === "estimated" ? (run.estimation_basis ?? null) : null,
429
+ duration_ms,
430
+ duration_provenance: provenance,
431
+ estimation_basis: null,
411
432
  };
412
- const duration_ms = estimatedDurationMs(run.total_tokens);
413
- return duration_ms === null
414
- ? { ...run, duration_provenance: "unavailable", estimation_basis: null }
415
- : {
416
- ...run,
417
- duration_ms,
418
- duration_provenance: "estimated",
419
- estimation_basis: TOKEN_DURATION_ESTIMATE_BASIS,
420
- };
421
- }
422
-
423
- function ensureTokenBackedGroupDuration(row: CostGroupRow): CostGroupRow {
424
- if ((row.total_tokens ?? 0) <= 0 || (row.duration_ms ?? 0) > 0) return row;
425
- const duration_ms = estimatedDurationMs(row.total_tokens);
426
- if (duration_ms === null || duration_ms <= 0) return row;
427
- const coverageCounts = row.coverage_counts;
428
- return {
429
- ...row,
430
- duration_ms,
431
- duration: { known_sum: duration_ms, unknown: 0, complete: true, coverage_ratio: 1 },
432
- ...(coverageCounts === undefined
433
- ? {}
434
- : {
435
- coverage_counts: {
436
- ...coverageCounts,
437
- ...(coverageCounts.metrics === undefined
438
- ? {}
439
- : {
440
- metrics: {
441
- ...coverageCounts.metrics,
442
- duration: {
443
- eligible_runs: row.run_count,
444
- known_runs: row.run_count,
445
- unknown_runs: 0,
446
- },
447
- },
448
- }),
449
- },
450
- }),
451
- };
452
- }
453
-
454
- function normalizeTokenBackedGroupBudget(
455
- rows: readonly CostGroupRow[],
456
- budget: number,
457
- ): CostGroupRow[] {
458
- return normalizeTokenBackedDailyDuration(rows, budget).map((row) => ({
459
- ...row,
460
- duration_ms: row.duration.complete ? row.duration.known_sum : null,
461
- }));
433
+ return { ...run, duration_ms: null, duration_provenance: "unavailable", estimation_basis: null };
462
434
  }
463
435
 
464
436
  interface KnownValue {
@@ -0,0 +1,55 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildCostMonitorProjection } from "./build-cost-monitor-projection.js";
3
+ import {
4
+ fxRate,
5
+ gpt54Catalog,
6
+ metric,
7
+ operationsWithPricedRun,
8
+ usage,
9
+ } from "./build-cost-monitor-projection.test-fixtures.js";
10
+
11
+ describe("Factual duration and cost", () => {
12
+ it("retains token-bearing Runs when a cost cannot be established", () => {
13
+ const operations = operationsWithPricedRun();
14
+ const source = operations.runs[0];
15
+ if (!source) throw new Error("priced Run fixture is missing");
16
+ operations.runs = [
17
+ {
18
+ ...source,
19
+ id: "RUN-UNKNOWN-MODEL",
20
+ model: "unknown-model",
21
+ effective_model: "unknown-model",
22
+ service_tier: null,
23
+ usage: usage(metric({ tokens: 1_000, input: 900, cached: 800, output: 100, events: 1 })),
24
+ },
25
+ {
26
+ ...source,
27
+ id: "RUN-UNKNOWN-TOKENS",
28
+ model: "gpt-5.4",
29
+ effective_model: "gpt-5.4",
30
+ service_tier: null,
31
+ usage: usage(metric({ tokens: 1_000, input: 900, output: 100, events: 1 })),
32
+ },
33
+ ];
34
+ const projection = buildCostMonitorProjection(operations, {
35
+ catalog: gpt54Catalog(),
36
+ fxRate: fxRate(5.5),
37
+ currency: "BRL",
38
+ });
39
+ expect(projection.runs).toHaveLength(2);
40
+ expect(projection.runs).toEqual(
41
+ expect.arrayContaining([
42
+ expect.objectContaining({
43
+ run_id: "RUN-UNKNOWN-MODEL",
44
+ total_tokens: 1_000,
45
+ estimated_brl: null,
46
+ }),
47
+ expect.objectContaining({
48
+ run_id: "RUN-UNKNOWN-TOKENS",
49
+ total_tokens: 1_000,
50
+ estimated_brl: null,
51
+ }),
52
+ ]),
53
+ );
54
+ });
55
+ });
@@ -0,0 +1,189 @@
1
+ import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contracts";
2
+ import { describe, expect, it } from "vitest";
3
+ import {
4
+ buildCostSummaryProjection,
5
+ type CostSummarySource,
6
+ } from "./build-cost-summary-projection.js";
7
+
8
+ describe("Factual duration and cost", () => {
9
+ it("keeps tokenized compact Runs without factual timing unavailable", () => {
10
+ const summary: CostSummarySource = {
11
+ periods: {
12
+ daily: {
13
+ "2026-08-07": {
14
+ prds: 0,
15
+ specs: 0,
16
+ tasks: 0,
17
+ validations: 0,
18
+ evidences: 0,
19
+ runs: 1,
20
+ usage: {
21
+ total_tokens: { known_sum: 4_000_000, unknown: 0, complete: true, coverage_ratio: 1 },
22
+ cost: {
23
+ known_sum: 1,
24
+ unknown: 0,
25
+ complete: true,
26
+ coverage_ratio: 1,
27
+ currency: "BRL",
28
+ },
29
+ },
30
+ },
31
+ },
32
+ },
33
+ run_metrics: [
34
+ {
35
+ id: "TOKEN-ONLY",
36
+ started_at: "2026-08-07T12:00:00.000Z",
37
+ finished_at: null,
38
+ task_id: null,
39
+ phase: "execution",
40
+ parent_run_id: null,
41
+ status: null,
42
+ duration_ms: null,
43
+ total_tokens: 4_000_000,
44
+ cost: 1,
45
+ currency: "BRL",
46
+ events: 1,
47
+ },
48
+ ],
49
+ };
50
+ const operations = {
51
+ filters: { from: "2026-08-07", to: "2026-08-07" },
52
+ summary: { task_count: 0 },
53
+ prds: [],
54
+ specs: [],
55
+ } as unknown as OperationsProjection;
56
+ const projection = buildCostSummaryProjection(summary, operations, "BRL", null);
57
+ expect(projection.groups.daily[0]?.duration).toMatchObject({
58
+ known_sum: 0,
59
+ unknown: 1,
60
+ complete: false,
61
+ });
62
+ expect(projection.groups.daily[0]?.duration_ms).toBeNull();
63
+ });
64
+
65
+ it("keeps a tokenized legacy period without factual duration unavailable", () => {
66
+ const summary: CostSummarySource = {
67
+ periods: {
68
+ daily: {
69
+ "2026-08-07": {
70
+ prds: 0,
71
+ specs: 0,
72
+ tasks: 0,
73
+ validations: 0,
74
+ evidences: 0,
75
+ runs: 1,
76
+ usage: {
77
+ total_tokens: { known_sum: 4_000_000, unknown: 0, complete: true, coverage_ratio: 1 },
78
+ cost: {
79
+ known_sum: 1,
80
+ unknown: 0,
81
+ complete: true,
82
+ coverage_ratio: 1,
83
+ currency: "BRL",
84
+ },
85
+ },
86
+ },
87
+ },
88
+ },
89
+ };
90
+ const operations = {
91
+ filters: { from: "2026-08-07", to: "2026-08-07" },
92
+ summary: { task_count: 0 },
93
+ prds: [],
94
+ specs: [],
95
+ } as unknown as OperationsProjection;
96
+ const projection = buildCostSummaryProjection(summary, operations, "BRL", null);
97
+ expect(projection.groups.daily[0]).toMatchObject({
98
+ total_tokens: 4_000_000,
99
+ duration_ms: null,
100
+ duration: { known_sum: 0, unknown: 1, complete: false },
101
+ });
102
+ });
103
+
104
+ it("uses the canonical root duration and excludes child and conversation duration", () => {
105
+ const summary: CostSummarySource = {
106
+ periods: {
107
+ daily: {
108
+ "2026-07-24": {
109
+ prds: 0,
110
+ specs: 0,
111
+ tasks: 0,
112
+ validations: 0,
113
+ evidences: 0,
114
+ runs: 3,
115
+ usage: {
116
+ total_tokens: { known_sum: 3, unknown: 0, complete: true, coverage_ratio: 1 },
117
+ cost: {
118
+ known_sum: 3,
119
+ unknown: 0,
120
+ complete: true,
121
+ coverage_ratio: 1,
122
+ currency: "BRL",
123
+ },
124
+ },
125
+ duration: { known_sum: 60_109_200, unknown: 0, complete: true, coverage_ratio: 1 },
126
+ },
127
+ },
128
+ },
129
+ run_metrics: [
130
+ {
131
+ id: "ROOT",
132
+ started_at: "2026-07-24T20:00:00.000Z",
133
+ finished_at: null,
134
+ task_id: null,
135
+ phase: "execution",
136
+ parent_run_id: null,
137
+ status: null,
138
+ duration_ms: 23_241_600,
139
+ total_tokens: 1,
140
+ cost: 1,
141
+ currency: "BRL",
142
+ events: 1,
143
+ },
144
+ {
145
+ id: "CHILD",
146
+ started_at: "2026-07-24T20:01:00.000Z",
147
+ finished_at: null,
148
+ task_id: null,
149
+ phase: "execution",
150
+ parent_run_id: "ROOT",
151
+ status: null,
152
+ duration_ms: 36_867_600,
153
+ total_tokens: 1,
154
+ cost: 1,
155
+ currency: "BRL",
156
+ events: 1,
157
+ },
158
+ {
159
+ id: "CONVERSATION",
160
+ started_at: "2026-07-24T20:02:00.000Z",
161
+ finished_at: null,
162
+ task_id: null,
163
+ phase: "conversation",
164
+ parent_run_id: null,
165
+ status: null,
166
+ duration_ms: 1_000,
167
+ total_tokens: 1,
168
+ cost: 1,
169
+ currency: "BRL",
170
+ events: 1,
171
+ },
172
+ ],
173
+ canonical_daily_duration_ms: { "2026-07-24": 23_241_600 },
174
+ };
175
+ const operations = {
176
+ filters: { from: null, to: null },
177
+ summary: { task_count: 0 },
178
+ prds: [],
179
+ specs: [],
180
+ } as unknown as OperationsProjection;
181
+ const row = buildCostSummaryProjection(summary, operations, "BRL", null).groups.daily.find(
182
+ (value) => value.key === "2026-07-24",
183
+ )!;
184
+
185
+ expect(row.duration.known_sum).toBe(23_241_600);
186
+ expect(row.duration.coverage_ratio).toBe(1);
187
+ expect(row.run_count).toBe(3);
188
+ });
189
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-operations",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -0,0 +1,82 @@
1
+ import type { OperationsLocale } from "./status-labels.js";
2
+ import { riskLabel } from "./status-labels.js";
3
+ import { taskOriginLabel, taskOriginOptions, type TaskOrigin } from "./task-origin.js";
4
+ import { workStageLabel, workStages } from "./work-board-model.js";
5
+
6
+ /** Work filters belong to the visible shared header, not the retired hero. */
7
+ export function OperationsEntityFilters({
8
+ locale,
9
+ query,
10
+ status,
11
+ risk,
12
+ origin,
13
+ onQuery,
14
+ onStatus,
15
+ onRisk,
16
+ onOrigin,
17
+ }: {
18
+ locale: OperationsLocale;
19
+ query: string;
20
+ status: string;
21
+ risk: string;
22
+ origin: TaskOrigin | "";
23
+ onQuery: (value: string) => void;
24
+ onStatus: (value: string) => void;
25
+ onRisk: (value: string) => void;
26
+ onOrigin: (value: TaskOrigin | "") => void;
27
+ }) {
28
+ const all = locale === "pt-BR" ? "Todos" : "All";
29
+ return (
30
+ <div className="operations-entity-filters">
31
+ <label>
32
+ <span>{locale === "pt-BR" ? "Busca" : "Search"}</span>
33
+ <input
34
+ aria-label={locale === "pt-BR" ? "Busca" : "Search"}
35
+ value={query}
36
+ onChange={(e) => onQuery(e.target.value)}
37
+ />
38
+ </label>
39
+ <label>
40
+ <span>Status</span>
41
+ <select aria-label="Status" value={status} onChange={(e) => onStatus(e.target.value)}>
42
+ <option value="">{all}</option>
43
+ {workStages.map((stage) => (
44
+ <option key={stage} value={stage}>
45
+ {workStageLabel(stage, locale)}
46
+ </option>
47
+ ))}
48
+ </select>
49
+ </label>
50
+ <label>
51
+ <span>{locale === "pt-BR" ? "Risco" : "Risk"}</span>
52
+ <select
53
+ aria-label={locale === "pt-BR" ? "Risco" : "Risk"}
54
+ value={risk}
55
+ onChange={(e) => onRisk(e.target.value)}
56
+ >
57
+ <option value="">{all}</option>
58
+ {["lite", "standard", "critical"].map((value) => (
59
+ <option key={value} value={value}>
60
+ {riskLabel(value, locale)}
61
+ </option>
62
+ ))}
63
+ </select>
64
+ </label>
65
+ <label>
66
+ <span>{locale === "pt-BR" ? "Origem" : "Origin"}</span>
67
+ <select
68
+ aria-label={locale === "pt-BR" ? "Origem" : "Origin"}
69
+ value={origin}
70
+ onChange={(e) => onOrigin(e.target.value as TaskOrigin | "")}
71
+ >
72
+ <option value="">{all}</option>
73
+ {taskOriginOptions.map((value) => (
74
+ <option key={value} value={value}>
75
+ {taskOriginLabel(value)}
76
+ </option>
77
+ ))}
78
+ </select>
79
+ </label>
80
+ </div>
81
+ );
82
+ }
@@ -2,6 +2,7 @@ import { DashboardHeader } from "@zaip-ai/dashboard-ui";
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
3
  import { ExcelExportAction } from "./export/ExcelExportAction.js";
4
4
  import { OperationDateFilters } from "./OperationDateFilters.js";
5
+ import { OperationsEntityFilters } from "./OperationsEntityFilters.js";
5
6
  import {
6
7
  ChevronDownIcon,
7
8
  FilterIcon,
@@ -17,6 +18,7 @@ import {
17
18
  resolveOperationsPeriodControl,
18
19
  workListTypeOnViewChange,
19
20
  } from "./operations-page-contract.js";
21
+ import { useOperationFilterFeedback } from "./use-operation-filter-feedback.js";
20
22
 
21
23
  export {
22
24
  type DashboardGlobalFilters,
@@ -33,17 +35,16 @@ import {
33
35
  type OperationDatePreset,
34
36
  type OperationDateRange,
35
37
  } from "./operation-date-range.js";
38
+ import { factualDurationRowsForExport } from "./operations-export-duration.js";
36
39
  import type { OperationsView } from "./operations-page-filters.js";
37
40
  import { macrosWithPeriodActivity } from "./operations-period-scope.js";
38
41
  import { matchesQuery } from "./operations-query.js";
39
42
  import { viewLabels } from "./operations-view-labels.js";
40
- import { applyFactualPeriodCosts, applyFactualPeriodDurations } from "./PeriodSummaryTable.js";
41
- import {
42
- aggregateManifestPeriodSummary,
43
- aggregatePeriodSummary,
44
- type PeriodGranularity,
45
- type PeriodSummaryRow,
46
- } from "./period-summary.js";
43
+ import { applyFactualPeriodCosts } from "./PeriodSummaryTable.js";
44
+
45
+ export { factualDurationRowsForExport } from "./operations-export-duration.js";
46
+
47
+ import { aggregateManifestPeriodSummary, aggregatePeriodSummary } from "./period-summary.js";
47
48
  import { periodSummaryPopulation } from "./period-summary-population.js";
48
49
  import { scopeRunsToEntities } from "./run-scope.js";
49
50
  import { riskLabel } from "./status-labels.js";
@@ -66,17 +67,6 @@ import "./operations-date-filters.css";
66
67
  import "./operations-filter-panel.css";
67
68
  import "./operations-responsive.css";
68
69
 
69
- /** Applies Cost Monitor duration facts only to the Operations period exports that share them. */
70
- export function factualDurationRowsForExport(
71
- granularity: PeriodGranularity,
72
- rows: readonly PeriodSummaryRow[],
73
- factualRows?: readonly { key: string; duration_ms: number | null }[],
74
- ): PeriodSummaryRow[] {
75
- return granularity === "month" || granularity === "year"
76
- ? applyFactualPeriodDurations(rows, factualRows)
77
- : [...rows];
78
- }
79
-
80
70
  export function OperationsPage({
81
71
  alternateContent,
82
72
  boardTotals,
@@ -130,8 +120,7 @@ export function OperationsPage({
130
120
  const [statusFilter, setStatusFilter] = useState("");
131
121
  const [riskFilter, setRiskFilter] = useState("");
132
122
  const [originFilter, setOriginFilter] = useState<TaskOrigin | "">("");
133
- const [filterLoading, setFilterLoading] = useState(false);
134
- const filterLoadingTimer = useRef<number | null>(null);
123
+ const { filterLoading, showFilterLoading } = useOperationFilterFeedback();
135
124
  const searchInputRef = useRef<HTMLInputElement>(null);
136
125
  const defaultDateRange = useMemo(() => {
137
126
  const operationsRange = initialOperationsDateRange(
@@ -165,17 +154,6 @@ export function OperationsPage({
165
154
  );
166
155
  // Coverage is derived display data, not a user selection. Never feed it
167
156
  // back through onDateChange: a delayed effect can overwrite a newer period.
168
- const showFilterLoading = useCallback(() => {
169
- setFilterLoading(true);
170
- if (filterLoadingTimer.current !== null) window.clearTimeout(filterLoadingTimer.current);
171
- filterLoadingTimer.current = window.setTimeout(() => setFilterLoading(false), 220);
172
- }, []);
173
- useEffect(
174
- () => () => {
175
- if (filterLoadingTimer.current !== null) window.clearTimeout(filterLoadingTimer.current);
176
- },
177
- [],
178
- );
179
157
  const renderedAlternateContent =
180
158
  typeof alternateContent === "function"
181
159
  ? alternateContent({ query, datePreset, ...(datePreset === "all" ? {} : { dateRange }) })
@@ -467,6 +445,19 @@ export function OperationsPage({
467
445
  </span>
468
446
  ) : null}
469
447
  </div>
448
+ {!renderedAlternateContent ? (
449
+ <OperationsEntityFilters
450
+ locale={locale}
451
+ query={query}
452
+ status={statusFilter}
453
+ risk={riskFilter}
454
+ origin={originFilter}
455
+ onQuery={setQuery}
456
+ onStatus={setStatusFilter}
457
+ onRisk={setRiskFilter}
458
+ onOrigin={setOriginFilter}
459
+ />
460
+ ) : null}
470
461
  <OperationDateFilters
471
462
  ariaLabelSuffix={locale === "pt-BR" ? " nos filtros" : " in filters"}
472
463
  dateRange={dateRange}