@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
@@ -17,6 +17,7 @@ import {
17
17
  saoPauloDay,
18
18
  type TemporalInterval,
19
19
  } from "./sqlite-read-model-canonical.js";
20
+ import { isCanonicalLifecyclePath } from "./sqlite-read-model-canonical-parsing.js";
20
21
  import { reportSqliteReadModelLaunchProgress } from "./sqlite-read-model-launch-progress.js";
21
22
  import {
22
23
  hasReusableSnapshotPayloads,
@@ -596,6 +597,7 @@ export async function rebuildSqliteReadModel(
596
597
  () => [...readCanonicalEntities([row])],
597
598
  ))
598
599
  if (entity.creationRunId) changedCreationRunIds.add(entity.creationRunId);
600
+ reportLaunchProgress("projection_entities", 75, "Entidades canônicas interpretadas.");
599
601
  const insertCanonicalWorkItem = database.prepare(
600
602
  "INSERT INTO canonical_work_items(entity_kind, id, title, status, stage, risk, spec_id, change_id, creation_run_id, completed_run_id, occurred_at, occurred_day_sp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
601
603
  );
@@ -627,6 +629,7 @@ export async function rebuildSqliteReadModel(
627
629
  decisions: [] as CanonicalDecision[],
628
630
  };
629
631
  for (const row of canonicalRows) {
632
+ if (!isCanonicalLifecyclePath(row.path)) continue;
630
633
  const parsed = parsedSources.read("lifecycle", row.path, sourceHashFor(row.path), () =>
631
634
  readCanonicalLifecycleRecords([row]),
632
635
  );
@@ -645,6 +648,7 @@ export async function rebuildSqliteReadModel(
645
648
  canonicalLifecycle.decisions = [
646
649
  ...new Map(canonicalLifecycle.decisions.map((item) => [item.id, item])).values(),
647
650
  ];
651
+ reportLaunchProgress("projection_lifecycle", 76, "Registros de ciclo de vida interpretados.");
648
652
  const insertCanonicalExecution = database.prepare(
649
653
  "INSERT INTO canonical_executions(id, status, kind, origin_type, origin_id, created_at, occurred_day_sp, finished_at, source_path) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
650
654
  );
@@ -695,6 +699,7 @@ export async function rebuildSqliteReadModel(
695
699
  saoPauloDay(entity.createdAt),
696
700
  entity.sourcePath,
697
701
  );
702
+ reportLaunchProgress("projection_runs_started", 77, "Construindo fatos das invocações.");
698
703
  const runMaterialization = materializeCanonicalRuns({
699
704
  database,
700
705
  previousActivities,
@@ -712,6 +717,11 @@ export async function rebuildSqliteReadModel(
712
717
  // Run canonical and attach deterministic shares only to the macro read
713
718
  // model. Payload rows stay outside `activities`, preventing global
714
719
  // Run/Cost totals from counting that Run more than once.
720
+ reportLaunchProgress(
721
+ "projection_dimensions_started",
722
+ 78,
723
+ "Construindo dimensões e agregados.",
724
+ );
715
725
  materializeDashboardProjections({
716
726
  ...runMaterialization,
717
727
  database,
@@ -722,6 +732,7 @@ export async function rebuildSqliteReadModel(
722
732
  skipped,
723
733
  fingerprint,
724
734
  });
735
+ reportLaunchProgress("projection_overview_started", 79, "Construindo a visão geral.");
725
736
  refreshFirstFoldPayloads(workspaceRoot, database);
726
737
  database.exec("COMMIT;");
727
738
  reportLaunchProgress(
@@ -4,10 +4,9 @@ import { DatabaseSync } from "node:sqlite";
4
4
  import { hasRequiredFirstFoldPayloads } from "./sqlite-first-fold-persistence.js";
5
5
  import type { SqliteReadModelSourceCheckpoint } from "./sqlite-read-model-source-fingerprint.js";
6
6
  export const dbRelativePath = ".local/sqlite/zaip-aios-dashboard.sqlite";
7
- // Schema 75 adds the persisted latest positive-token collection timestamp.
8
- // A schema rebuild is required even when source hashes match so an older
9
- // snapshot cannot masquerade as a telemetry-fresh projection.
10
- export const readModelSchemaVersion = "75";
7
+ // Schema 79 installs bounded execution/conversation label views and shared daily groups.
8
+ // Old snapshots must rebuild even when their canonical hashes still match.
9
+ export const readModelSchemaVersion = "79";
11
10
  export const requiredPersistedTables = [
12
11
  "zaip_aios_activities",
13
12
  "zaip_dim_llm_model",
@@ -32,6 +31,8 @@ export const requiredIndexes = [
32
31
  "zaip_activities_period_invocation",
33
32
  "zaip_activities_status",
34
33
  "zaip_activities_payload",
34
+ "zaip_activities_duration_activity",
35
+ "zaip_activities_file_path",
35
36
  "zaip_activities_work_item_identity",
36
37
  "cost_dimension_facts_day_model",
37
38
  "cost_dimension_facts_day_provider",
@@ -1,6 +1,6 @@
1
1
  import { mkdir, mkdtemp, rename, rm, stat, utimes, writeFile } from "node:fs/promises";
2
2
  import { join, resolve } from "node:path";
3
- import { afterEach, describe, expect, it } from "vitest";
3
+ import { afterEach, describe, expect, it, vi } from "vitest";
4
4
  import {
5
5
  type SqliteReadModelSourceCandidate,
6
6
  sourceFingerprint,
@@ -21,6 +21,7 @@ const checkpoints = (candidates: SqliteReadModelSourceCandidate[]) =>
21
21
  new Map(candidates.map((candidate) => [candidate.source, candidate]));
22
22
 
23
23
  afterEach(async () => {
24
+ vi.restoreAllMocks();
24
25
  await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
25
26
  });
26
27
 
@@ -49,6 +50,7 @@ describe("persistent source fingerprint checkpoints", () => {
49
50
 
50
51
  it("reuses historical content hashes across serialized checkpoints and detects additions and removals", async () => {
51
52
  const { root, path } = await fixture();
53
+ vi.spyOn(Date, "now").mockReturnValue(Date.now() + 5_000);
52
54
  const initial = await sourceFingerprint(root);
53
55
  const previous = checkpoints(JSON.parse(JSON.stringify(initial.candidates)));
54
56
  expect(initial.hashedFiles).toBe(1);
@@ -86,6 +88,57 @@ describe("persistent source fingerprint checkpoints", () => {
86
88
  expect(changed).toMatchObject({ hashedFiles: 1, reusedFiles: 0 });
87
89
  });
88
90
 
91
+ it("rehashes recent colliding metadata and the first settled checkpoint before reuse", async () => {
92
+ const { root, path } = await fixture();
93
+ const metadata = await stat(path);
94
+ const clock = vi.spyOn(Date, "now").mockReturnValue(metadata.ctimeMs);
95
+ const initial = await sourceFingerprint(root);
96
+ // Even a corrupted/stale hash with otherwise identical metadata cannot be
97
+ // trusted while writes can collide within the filesystem timestamp tick.
98
+ const stale = checkpoints(
99
+ initial.candidates.map((item) => ({ ...item, contentHash: "stale" })),
100
+ );
101
+ const recent = await sourceFingerprint(root, { previous: stale });
102
+ expect(recent).toMatchObject({ hashedFiles: 1, reusedFiles: 0 });
103
+ expect(recent.candidates[0]?.contentHash).toBe(initial.candidates[0]?.contentHash);
104
+ const serialized = checkpoints(JSON.parse(JSON.stringify(recent.candidates)));
105
+ clock.mockReturnValue(metadata.ctimeMs + 2_001);
106
+ const settled = await sourceFingerprint(root, { previous: serialized });
107
+ expect(settled).toMatchObject({ hashedFiles: 1, reusedFiles: 0 });
108
+ const reused = await sourceFingerprint(root, { previous: checkpoints(settled.candidates) });
109
+ expect(reused).toMatchObject({
110
+ hashedFiles: 0,
111
+ reusedFiles: 1,
112
+ fingerprint: settled.fingerprint,
113
+ });
114
+ const legacy = checkpoints(
115
+ settled.candidates.map((item) => ({
116
+ ...item,
117
+ contentHash: "stale",
118
+ fileIdentity: item.fileIdentity.replace("settled-v2:", ""),
119
+ })),
120
+ );
121
+ const upgraded = await sourceFingerprint(root, { previous: legacy });
122
+ expect(upgraded).toMatchObject({
123
+ hashedFiles: 1,
124
+ reusedFiles: 0,
125
+ fingerprint: settled.fingerprint,
126
+ });
127
+ });
128
+
129
+ it("detects rapid real same-size rewrites with restored mtime across repeated scans", async () => {
130
+ const { root, path } = await fixture();
131
+ const timestamp = new Date("2026-01-01T00:00:00Z");
132
+ let previous = await sourceFingerprint(root);
133
+ for (let iteration = 0; iteration < 20; iteration += 1) {
134
+ await writeFile(path, iteration % 2 ? "# first\n" : "# other\n");
135
+ await utimes(path, timestamp, timestamp);
136
+ const next = await sourceFingerprint(root, { previous: checkpoints(previous.candidates) });
137
+ expect(next.candidates[0]?.contentHash).not.toBe(previous.candidates[0]?.contentHash);
138
+ previous = next;
139
+ }
140
+ });
141
+
89
142
  it("detects atomic file replacement and allows explicit complete content verification", async () => {
90
143
  const { root, path } = await fixture();
91
144
  const initial = await sourceFingerprint(root);
@@ -83,8 +83,10 @@ export async function sourceFingerprint(
83
83
  let hashedFiles = 0;
84
84
  let reusedFiles = 0;
85
85
  // Persisted checkpoints avoid rereading unchanged history across workers.
86
- // ctime and identity detect same-size edits with preserved mtime and atomic
87
- // replacement. Explicit verification bypasses this metadata shortcut.
86
+ // Windows can report identical ctime even in nanoseconds for rapid writes.
87
+ // Never cache a recent timestamp. Mark those hashes as unstable so that the
88
+ // first scan after the settling window also rehashes before allowing reuse.
89
+ // Explicit verification still bypasses this metadata shortcut entirely.
88
90
  for (let offset = 0; offset < candidates.length; offset += 32) {
89
91
  candidatesWithMetadata.push(
90
92
  ...(
@@ -94,17 +96,19 @@ export async function sourceFingerprint(
94
96
  try {
95
97
  for (let attempt = 0; attempt < 3; attempt += 1) {
96
98
  const metadata = await stat(candidate);
99
+ const metadataSettled = Date.now() - metadata.ctimeMs > 2_000;
97
100
  const current = {
98
101
  path: candidate,
99
102
  source,
100
103
  mtimeMs: metadata.mtimeMs,
101
104
  ctimeMs: metadata.ctimeMs,
102
105
  size: metadata.size,
103
- fileIdentity: `${metadata.dev}:${metadata.ino}:${metadata.birthtimeMs}`,
106
+ fileIdentity: `settled-v2:${metadata.dev}:${metadata.ino}:${metadata.birthtimeMs}${metadataSettled ? "" : ":recent"}`,
104
107
  };
105
108
  const previous = options.previous?.get(source);
106
109
  if (
107
110
  !options.verifyContent &&
111
+ metadataSettled &&
108
112
  previous !== undefined &&
109
113
  previous.mtimeMs === current.mtimeMs &&
110
114
  previous.ctimeMs === current.ctimeMs &&
@@ -46,8 +46,11 @@ describe("SQLite dashboard read model", () => {
46
46
  await writeFile(join(root, ".agents/config/project.yaml"), "zaip:\n enabled: true\n");
47
47
  const task = join(root, ".agents/records/tasks/task.md");
48
48
  await writeFile(task, "# initial\n");
49
+ const settledFilesystemTime = Date.now() + 5_000;
49
50
  vi.useFakeTimers({ toFake: ["Date"] });
50
51
  vi.setSystemTime(new Date("2026-09-05T02:59:00Z"));
52
+ // Calendar projection time is independent of the real fixture's ctime.
53
+ vi.spyOn(Date, "now").mockReturnValue(settledFilesystemTime);
51
54
  const first = await rebuildSqliteReadModel(root);
52
55
  await expect(rebuildSqliteReadModel(root)).resolves.toMatchObject({ cache: "generation" });
53
56
  await rm(task);
@@ -174,7 +177,7 @@ describe("SQLite dashboard read model", () => {
174
177
  metadata
175
178
  .prepare("SELECT value FROM zaip_vw_read_model_metadata WHERE key='schema_version'")
176
179
  .get(),
177
- ).toEqual({ value: "74" });
180
+ ).toEqual({ value: "79" });
178
181
  } finally {
179
182
  metadata.close();
180
183
  }
@@ -0,0 +1,98 @@
1
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { join, resolve } from "node:path";
3
+ import { expect, it } from "vitest";
4
+ import { createDashboardApp } from "./server.js";
5
+ import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
6
+
7
+ it("serves risk counts over the same non-draft population as total and statuses", async () => {
8
+ const parent = resolve(import.meta.dirname, "../../../../../../.local/sqlite/tests");
9
+ await mkdir(parent, { recursive: true });
10
+ const root = await mkdtemp(join(parent, "risk-population-"));
11
+ let filesystem: SqliteReadModelFileSystem | undefined;
12
+ try {
13
+ const records = join(root, ".agents/records/tasks/2026/09");
14
+ await mkdir(records, { recursive: true });
15
+ await mkdir(join(root, ".agents/config"), { recursive: true });
16
+ await writeFile(
17
+ join(root, ".agents/config/project.yaml"),
18
+ "schema_version: 1\nzaip:\n enabled: true\nproject:\n id: sqlite-test\n name: sqlite-test\n timezone: UTC\nstack:\n id: zaip-aios-stack\n overrides: {}\nclients:\n codex: true\n claude: true\ntracking:\n enabled: true\n currency: BRL\n storage_mode: tracked_sanitized\n",
19
+ );
20
+ await writeFile(
21
+ join(root, ".agents/config/framework.lock.yaml"),
22
+ "lock_version: 1\nframework:\n version: 2.6.0\n distribution_sha256: null\nlayout:\n version: 3\nresolved_profile:\n id: null\n sha256: null\nmanaged_files: {}\n",
23
+ );
24
+ for (const [id, status, risk] of [
25
+ ["TASK-DRAFT", "draft", "critical"],
26
+ ["TASK-PLANNED", "planned", "lite"],
27
+ ["TASK-SECOND", "planned", "lite"],
28
+ ["TASK-COMPLETED", "completed", "standard"],
29
+ ]) {
30
+ await writeFile(
31
+ join(records, `${id}.md`),
32
+ `---\nid: ${id}\ntitle: ${id}\nstatus: ${status}\nrisk: ${risk}\ncreated_at: 2026-09-${id === "TASK-COMPLETED" ? "02" : "01"}T12:00:00.000Z\n---\n`,
33
+ "utf8",
34
+ );
35
+ }
36
+ await rebuildSqliteReadModel(root);
37
+ filesystem = new SqliteReadModelFileSystem(root);
38
+ expect(filesystem.firstFoldViewportAllTime().task_risk_counts).toEqual({
39
+ lite: 2,
40
+ standard: 1,
41
+ });
42
+ expect(filesystem.firstFoldAllTime().task_risk_counts).toEqual({ lite: 2, standard: 1 });
43
+ for (const view of [
44
+ "cost_monitor_daily",
45
+ "cost_monitor_monthly",
46
+ "cost_monitor_annual",
47
+ ] as const) {
48
+ const page = filesystem.viewPage(view, { limit: 10 });
49
+ const daily = view === "cost_monitor_daily";
50
+ expect(page.rows).toHaveLength(daily ? 2 : 1);
51
+ expect(page.totals).toMatchObject({ task_count: 3 });
52
+ expect(page).toMatchObject({ period_averages: { BRL: { tasks: daily ? 1.5 : 3 } } });
53
+ }
54
+ const first = filesystem.viewPage("cost_monitor_daily", { limit: 1, offset: 0 });
55
+ const second = filesystem.viewPage("cost_monitor_daily", { limit: 1, offset: 1 });
56
+ expect(first.rows[0]).toMatchObject({ task_count: 1 });
57
+ expect(second.rows[0]).toMatchObject({ task_count: 2 });
58
+ expect(first.period_averages).toEqual(second.period_averages);
59
+ expect(first).toMatchObject({
60
+ period_averages: { BRL: { tasks: 1.5, cost: null, tokens: null } },
61
+ });
62
+ expect(
63
+ filesystem.viewPage("cost_monitor_daily", { limit: 1, query: "2026-09-01" }),
64
+ ).toMatchObject({ total_count: 1, period_averages: { BRL: { tasks: 2 } } });
65
+ const app = createDashboardApp(root, "fixture-only", undefined, {
66
+ filesystem,
67
+ watchSources: false,
68
+ });
69
+ for (const scope of ["quick", "overview"]) {
70
+ const response = await app.request(`/api/v2/operations?scope=${scope}`, {
71
+ headers: { "x-zaip-session": "fixture-only" },
72
+ });
73
+ expect(response.status, await response.clone().text()).toBe(200);
74
+ const data = (await response.json()) as {
75
+ summary: {
76
+ overview_metrics: {
77
+ task_count: number;
78
+ task_status_counts: Record<string, number>;
79
+ task_risk_counts: Record<string, number>;
80
+ };
81
+ };
82
+ };
83
+ const metric = data.summary.overview_metrics;
84
+ expect(metric.task_count).toBe(3);
85
+ expect(metric.task_status_counts).toEqual({ planned: 2, completed: 1 });
86
+ expect(metric.task_risk_counts).toEqual({ lite: 2, standard: 1 });
87
+ expect(
88
+ Object.values(metric.task_risk_counts).reduce<number>(
89
+ (sum, count) => sum + Number(count),
90
+ 0,
91
+ ),
92
+ ).toBe(metric.task_count);
93
+ }
94
+ } finally {
95
+ filesystem?.close();
96
+ await rm(root, { recursive: true, force: true });
97
+ }
98
+ });
@@ -16,8 +16,13 @@ export const baseViewSql = `
16
16
  WHERE agent_invocation_id IS NOT NULL;
17
17
  CREATE INDEX zaip_activities_status ON zaip_aios_activities(activity_source_kind, status, phase);
18
18
  CREATE INDEX IF NOT EXISTS zaip_activities_payload ON zaip_aios_activities(payload_type, activity_key);
19
+ CREATE INDEX zaip_activities_duration_activity ON zaip_aios_activities(CAST(json_extract(payload_json, '$.activity_row_id') AS TEXT)) WHERE payload_type='duration_allocation';
20
+ -- File lookups must not parse every JSON payload (including its full
21
+ -- content) on each read. The file view uses this path-only index for
22
+ -- binary equality and cheap LIKE scans without changing their semantics.
23
+ CREATE INDEX zaip_activities_file_path ON zaip_aios_activities(json_extract(payload_json, '$.path')) WHERE payload_type='file';
19
24
  CREATE INDEX zaip_activities_work_item_identity ON zaip_aios_activities(json_extract(payload_json, '$.entity_kind'), json_extract(payload_json, '$.id')) WHERE payload_type='work_item';
20
- CREATE VIEW files AS SELECT json_extract(payload_json, '$.path') AS path, json_extract(payload_json, '$.content') AS content, json_extract(payload_json, '$.mtime_ms') AS mtime_ms, json_extract(payload_json, '$.size_bytes') AS size_bytes, json_extract(payload_json, '$.content_sha256') AS content_sha256, json_extract(payload_json, '$.artifact_kind') AS artifact_kind, json_extract(payload_json, '$.artifact_id') AS artifact_id, json_extract(payload_json, '$.artifact_occurred_at') AS artifact_occurred_at, json_extract(payload_json, '$.artifact_occurred_day_sp') AS artifact_occurred_day_sp, json_extract(payload_json, '$.artifact_task_id') AS artifact_task_id, json_extract(payload_json, '$.artifact_change_id') AS artifact_change_id, json_extract(payload_json, '$.artifact_run_id') AS artifact_run_id FROM zaip_aios_activities WHERE payload_type='file';
25
+ CREATE VIEW files AS SELECT json_extract(payload_json, '$.path') AS path, json_extract(payload_json, '$.content') AS content, json_extract(payload_json, '$.mtime_ms') AS mtime_ms, json_extract(payload_json, '$.size_bytes') AS size_bytes, json_extract(payload_json, '$.content_sha256') AS content_sha256, json_extract(payload_json, '$.artifact_kind') AS artifact_kind, json_extract(payload_json, '$.artifact_id') AS artifact_id, json_extract(payload_json, '$.artifact_occurred_at') AS artifact_occurred_at, json_extract(payload_json, '$.artifact_occurred_day_sp') AS artifact_occurred_day_sp, json_extract(payload_json, '$.artifact_task_id') AS artifact_task_id, json_extract(payload_json, '$.artifact_change_id') AS artifact_change_id, json_extract(payload_json, '$.artifact_run_id') AS artifact_run_id FROM zaip_aios_activities INDEXED BY zaip_activities_file_path WHERE payload_type='file';
21
26
  CREATE VIEW read_model_source_state AS SELECT json_extract(payload_json, '$.source_path') AS source_path, json_extract(payload_json, '$.source_hash') AS source_hash, json_extract(payload_json, '$.mtime_ms') AS mtime_ms, json_extract(payload_json, '$.ctime_ms') AS ctime_ms, json_extract(payload_json, '$.size_bytes') AS size_bytes, json_extract(payload_json, '$.file_identity') AS file_identity, json_extract(payload_json, '$.source_kind') AS source_kind, json_extract(payload_json, '$.last_processed_at') AS last_processed_at FROM zaip_aios_activities WHERE payload_type='source_state';
22
27
  CREATE VIEW read_model_metadata AS SELECT json_extract(payload_json, '$.key') AS key, json_extract(payload_json, '$.value') AS value FROM zaip_aios_activities WHERE payload_type='metadata';
23
28
  CREATE VIEW canonical_work_items AS SELECT json_extract(payload_json, '$.entity_kind') AS entity_kind, json_extract(payload_json, '$.id') AS id, json_extract(payload_json, '$.title') AS title, json_extract(payload_json, '$.status') AS status, json_extract(payload_json, '$.stage') AS stage, json_extract(payload_json, '$.risk') AS risk, json_extract(payload_json, '$.spec_id') AS spec_id, json_extract(payload_json, '$.change_id') AS change_id, json_extract(payload_json, '$.creation_run_id') AS creation_run_id, json_extract(payload_json, '$.completed_run_id') AS completed_run_id, json_extract(payload_json, '$.occurred_at') AS occurred_at, json_extract(payload_json, '$.occurred_day_sp') AS occurred_day_sp FROM zaip_aios_activities WHERE payload_type='work_item';
@@ -29,12 +34,13 @@ export const baseViewSql = `
29
34
  CREATE VIEW attributed_token_active_facts AS SELECT json_extract(payload_json, '$.activity_row_id') AS activity_row_id, json_extract(payload_json, '$.occurred_day_sp') AS occurred_day_sp, json_extract(payload_json, '$.attributed_token_active_ms') AS attributed_token_active_ms FROM zaip_aios_activities WHERE payload_type='duration_allocation';
30
35
  CREATE VIEW canonical_artifacts AS SELECT artifact_kind, artifact_id, artifact_occurred_at AS occurred_at, artifact_occurred_day_sp AS occurred_day_sp, artifact_task_id AS task_id, artifact_change_id AS change_id, artifact_run_id AS run_id, path AS source_path FROM files WHERE artifact_kind IS NOT NULL AND artifact_occurred_at IS NOT NULL;
31
36
  CREATE VIEW activities AS
32
- SELECT a.*, f.attributed_token_active_ms
37
+ SELECT a.*, (
38
+ SELECT SUM(json_extract(f.payload_json, '$.attributed_token_active_ms'))
39
+ FROM zaip_aios_activities f INDEXED BY zaip_activities_duration_activity
40
+ WHERE f.payload_type='duration_allocation'
41
+ AND CAST(json_extract(f.payload_json, '$.activity_row_id') AS TEXT)=a.activity_row_id
42
+ ) AS attributed_token_active_ms
33
43
  FROM zaip_aios_activities a
34
- LEFT JOIN (
35
- SELECT activity_row_id, SUM(attributed_token_active_ms) AS attributed_token_active_ms
36
- FROM attributed_token_active_facts GROUP BY activity_row_id
37
- ) f USING(activity_row_id)
38
44
  WHERE a.payload_type IS NULL;
39
45
  -- Macro-only allocations are persisted as technical payloads to keep
40
46
  -- the global Run population unique. SPEC summaries opt into this
@@ -64,21 +70,27 @@ export const baseViewSql = `
64
70
  CREATE VIEW specs AS SELECT id, title, status, risk, occurred_at, occurred_day_sp FROM work_items WHERE entity_kind = 'spec';
65
71
  CREATE VIEW prds AS SELECT id, title, status, risk, occurred_at, occurred_day_sp FROM work_items WHERE entity_kind = 'prd';
66
72
  CREATE VIEW executions AS
67
- SELECT id, status, created_at AS occurred_at, occurred_day_sp FROM canonical_executions
73
+ WITH projected_executions AS MATERIALIZED (
74
+ SELECT id, status, created_at, occurred_day_sp FROM canonical_executions
75
+ )
76
+ SELECT id, status, created_at AS occurred_at, occurred_day_sp FROM projected_executions
68
77
  UNION ALL
69
78
  SELECT execution_id, MAX(status), MIN(occurred_at), MIN(occurred_day_sp)
70
- FROM activities
71
- WHERE execution_id IS NOT NULL
72
- AND NOT EXISTS (SELECT 1 FROM canonical_executions c WHERE c.id=activities.execution_id)
79
+ FROM zaip_aios_activities
80
+ WHERE payload_type IS NULL AND execution_id IS NOT NULL
81
+ AND NOT EXISTS (SELECT 1 FROM projected_executions c WHERE c.id=zaip_aios_activities.execution_id)
73
82
  GROUP BY execution_id;
74
83
  CREATE VIEW conversations AS
84
+ WITH projected_executions AS MATERIALIZED (
85
+ SELECT status, created_at, occurred_day_sp, origin_type, origin_id FROM canonical_executions
86
+ )
75
87
  SELECT origin_id AS id, MAX(status) AS status, MIN(created_at) AS occurred_at, MIN(occurred_day_sp) AS occurred_day_sp
76
- FROM canonical_executions WHERE origin_type='interaction' AND origin_id IS NOT NULL GROUP BY origin_id
88
+ FROM projected_executions WHERE origin_type='interaction' AND origin_id IS NOT NULL GROUP BY origin_id
77
89
  UNION ALL
78
90
  SELECT conversation_id, MAX(status), MIN(occurred_at), MIN(occurred_day_sp)
79
- FROM activities
80
- WHERE conversation_id IS NOT NULL
81
- AND NOT EXISTS (SELECT 1 FROM canonical_executions c WHERE c.origin_type='interaction' AND c.origin_id=activities.conversation_id)
91
+ FROM zaip_aios_activities
92
+ WHERE payload_type IS NULL AND conversation_id IS NOT NULL
93
+ AND NOT EXISTS (SELECT 1 FROM projected_executions c WHERE c.origin_type='interaction' AND c.origin_id=zaip_aios_activities.conversation_id)
82
94
  GROUP BY conversation_id;
83
95
  CREATE VIEW decisions AS SELECT id, title, origin, scope_type, scope_id, NULL AS status, NULL AS risk, created_at AS occurred_at, occurred_day_sp, source_path FROM canonical_decisions;
84
96
  CREATE VIEW changes AS SELECT id, title, status, risk, source_type, source_id, requirement_ids_json, acceptance_ids_json, task_ids_json, result, created_at AS occurred_at, occurred_day_sp, source_path FROM canonical_changes;
@@ -123,7 +135,8 @@ export const baseViewSql = `
123
135
  FROM attributed_token_active_facts GROUP BY occurred_day_sp
124
136
  ), work_item_days AS (
125
137
  SELECT entity_kind AS kind, id, occurred_day_sp AS day FROM canonical_work_items
126
- UNION ALL SELECT 'task', task_id, MIN(occurred_day_sp) FROM activities WHERE task_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM canonical_work_items c WHERE c.entity_kind='task' AND c.id=activities.task_id) GROUP BY task_id
138
+ WHERE entity_kind <> 'task' OR COALESCE(status, 'draft') <> 'draft'
139
+ UNION ALL SELECT 'task', task_id, MIN(occurred_day_sp) FROM activities WHERE task_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM canonical_work_items c WHERE c.entity_kind='task' AND c.id=activities.task_id) GROUP BY task_id HAVING COALESCE(MAX(work_item_status), 'draft') <> 'draft'
127
140
  UNION ALL SELECT 'spec', spec_id, MIN(occurred_day_sp) FROM activities WHERE spec_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM canonical_work_items c WHERE c.entity_kind='spec' AND c.id=activities.spec_id) GROUP BY spec_id
128
141
  UNION ALL SELECT 'prd', prd_id, MIN(occurred_day_sp) FROM activities WHERE prd_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM canonical_work_items c WHERE c.entity_kind='prd' AND c.id=activities.prd_id) GROUP BY prd_id
129
142
  ), work_item_daily AS (
@@ -276,7 +289,7 @@ export const baseViewSql = `
276
289
  -- SPEC/PRD rows have the same canonical population as the big
277
290
  -- numbers. A macro without direct invocation remains visible with
278
291
  -- factual NULL usage/cost/time, never a fabricated zero.
279
- CREATE VIEW cost_monitor_group_daily_cache AS SELECT occurred_day_sp AS day, 'execution' AS group_kind, execution_id AS group_value, COUNT(*) AS invocation_count, SUM(llm_call_count) AS llm_call_count, SUM(duration_ms) AS total_duration, SUM(input_tokens) AS total_input_tokens, SUM(cached_input_tokens) AS total_cached_input_tokens, SUM(output_tokens) AS total_output_tokens, SUM(reasoning_tokens) AS total_reasoning_tokens, SUM(total_tokens) AS total_tokens, SUM(cost_usd) AS total_cost_usd, SUM(cost_brl) AS total_cost_brl FROM invocations WHERE execution_id IS NOT NULL GROUP BY occurred_day_sp, execution_id UNION ALL SELECT occurred_day_sp, 'zaip_agent', zaip_agent, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM invocations WHERE zaip_agent IS NOT NULL GROUP BY occurred_day_sp, zaip_agent UNION ALL SELECT occurred_day_sp, 'provider', provider, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM invocations WHERE provider IS NOT NULL GROUP BY occurred_day_sp, provider UNION ALL SELECT occurred_day_sp, 'model', model, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM invocations WHERE model IS NOT NULL GROUP BY occurred_day_sp, model UNION ALL SELECT occurred_day_sp, 'task', task_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM invocations WHERE task_id IS NOT NULL GROUP BY occurred_day_sp, task_id UNION ALL SELECT occurred_day_sp, 'spec', spec_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM invocations WHERE spec_id IS NOT NULL GROUP BY occurred_day_sp, spec_id UNION ALL SELECT occurred_day_sp, 'prd', prd_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM invocations WHERE prd_id IS NOT NULL GROUP BY occurred_day_sp, prd_id UNION ALL SELECT occurred_day_sp, 'conversation', conversation_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM invocations WHERE conversation_id IS NOT NULL GROUP BY occurred_day_sp, conversation_id;
292
+ CREATE VIEW cost_monitor_group_daily_cache AS WITH group_invocations AS MATERIALIZED (SELECT occurred_day_sp, execution_id, zaip_agent, provider, model, task_id, spec_id, prd_id, conversation_id, llm_call_count, duration_ms, input_tokens, cached_input_tokens, output_tokens, reasoning_tokens, total_tokens, cost_usd, cost_brl FROM invocations) SELECT occurred_day_sp AS day, 'execution' AS group_kind, execution_id AS group_value, COUNT(*) AS invocation_count, SUM(llm_call_count) AS llm_call_count, SUM(duration_ms) AS total_duration, SUM(input_tokens) AS total_input_tokens, SUM(cached_input_tokens) AS total_cached_input_tokens, SUM(output_tokens) AS total_output_tokens, SUM(reasoning_tokens) AS total_reasoning_tokens, SUM(total_tokens) AS total_tokens, SUM(cost_usd) AS total_cost_usd, SUM(cost_brl) AS total_cost_brl FROM group_invocations WHERE execution_id IS NOT NULL GROUP BY occurred_day_sp, execution_id UNION ALL SELECT occurred_day_sp, 'zaip_agent', zaip_agent, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE zaip_agent IS NOT NULL GROUP BY occurred_day_sp, zaip_agent UNION ALL SELECT occurred_day_sp, 'provider', provider, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE provider IS NOT NULL GROUP BY occurred_day_sp, provider UNION ALL SELECT occurred_day_sp, 'model', model, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE model IS NOT NULL GROUP BY occurred_day_sp, model UNION ALL SELECT occurred_day_sp, 'task', task_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE task_id IS NOT NULL GROUP BY occurred_day_sp, task_id UNION ALL SELECT occurred_day_sp, 'spec', spec_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE spec_id IS NOT NULL GROUP BY occurred_day_sp, spec_id UNION ALL SELECT occurred_day_sp, 'prd', prd_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE prd_id IS NOT NULL GROUP BY occurred_day_sp, prd_id UNION ALL SELECT occurred_day_sp, 'conversation', conversation_id, COUNT(*), SUM(llm_call_count), SUM(duration_ms), SUM(input_tokens), SUM(cached_input_tokens), SUM(output_tokens), SUM(reasoning_tokens), SUM(total_tokens), SUM(cost_usd), SUM(cost_brl) FROM group_invocations WHERE conversation_id IS NOT NULL GROUP BY occurred_day_sp, conversation_id;
280
293
  CREATE VIEW daily_aggregates AS SELECT * FROM daily_aggregate_cache;
281
294
  CREATE VIEW overview AS
282
295
  SELECT 'day' AS period_kind, day AS period_key, day AS start_day, day AS end_day, prd_count, spec_count, task_count, validation_count, evidence_count, activity_count, root_run_count, sub_run_count, total_run_count, invocation_count, cost_monitor_invocation_count, llm_call_count, source_event_count, total_root_run_duration, total_sub_run_duration, operations_total_duration, cost_monitor_total_duration, total_duration, total_tokens, total_cost_usd, total_cost_brl FROM daily_aggregates
@@ -174,7 +174,8 @@ export const dashboardViewSql = ` CREATE VIEW vw_operations_work_list AS
174
174
  CREATE VIEW vw_first_fold_task_risk_all_time AS
175
175
  WITH counts AS (
176
176
  SELECT COALESCE(risk, 'standard') AS risk, COUNT(*) AS task_count
177
- FROM task_summary GROUP BY COALESCE(risk, 'standard')
177
+ FROM task_summary WHERE COALESCE(status, 'draft') <> 'draft'
178
+ GROUP BY COALESCE(risk, 'standard')
178
179
  ), total AS (SELECT SUM(task_count) AS task_count FROM counts)
179
180
  SELECT counts.risk, counts.task_count,
180
181
  CASE WHEN total.task_count = 0 THEN 0.0 ELSE CAST(counts.task_count AS REAL) / total.task_count END AS task_percentage
@@ -13,6 +13,7 @@ import {
13
13
  const roots: string[] = [];
14
14
 
15
15
  afterEach(async () => {
16
+ vi.restoreAllMocks();
16
17
  await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
17
18
  });
18
19
 
@@ -60,6 +61,7 @@ describe("SQLite snapshot seed publication", () => {
60
61
  await mkdir(join(root, ".agents", "config"), { recursive: true });
61
62
  await writeFile(join(root, ".agents", "config", "project.yaml"), "zaip:\n enabled: true\n");
62
63
  const destination = join(root, ".local", "dashboard-sqlite", "read-model.sqlite");
64
+ vi.spyOn(Date, "now").mockReturnValue(Date.now() + 5_000);
63
65
  vi.stubEnv("ZAIP_SQLITE_DB_PATH", destination);
64
66
  try {
65
67
  await expect(rebuildSqliteReadModel(root)).resolves.toMatchObject({ cache: "rebuilt" });
@@ -0,0 +1,57 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { stripVTControlCharacters } from "node:util";
6
+
7
+ const here = dirname(fileURLToPath(import.meta.url));
8
+ const root = resolve(here, "../../../../..");
9
+ const prefix = ".agents/dashboard/packages/local-runtime/src/";
10
+ const mode = process.argv[2];
11
+ if (!["test", "integration", "check"].includes(mode))
12
+ throw new Error("Expected test|integration|check");
13
+ if (!existsSync(resolve(root, "node_modules/vitest/vitest.mjs"))) {
14
+ if (spawnSync("git", ["symbolic-ref", "-q", "HEAD"], { cwd: root }).status !== 1)
15
+ throw new Error("Prepare dependencies in the Task checkout first");
16
+ const pnpm = resolve(dirname(process.execPath), "node_modules/corepack/dist/pnpm.js");
17
+ execute([pnpm, "install", "--offline", "--frozen-lockfile", "--ignore-scripts"], 300_000);
18
+ }
19
+ function execute(args, timeout = 120_000) {
20
+ const result = spawnSync(process.execPath, args, {
21
+ cwd: root,
22
+ encoding: "utf8",
23
+ windowsHide: true,
24
+ timeout,
25
+ maxBuffer: 4_000_000,
26
+ });
27
+ const output = stripVTControlCharacters((result.stdout ?? "") + "\n" + (result.stderr ?? ""));
28
+ if (result.status !== 0) {
29
+ process.stderr.write(output);
30
+ throw new Error("Settings validation failed: " + (result.error?.message ?? result.status));
31
+ }
32
+ return output;
33
+ }
34
+ if (mode === "check") {
35
+ execute([
36
+ "node_modules/typescript/bin/tsc",
37
+ "--noEmit",
38
+ "--project",
39
+ ".agents/dashboard/packages/local-runtime/tsconfig.json",
40
+ ]);
41
+ console.log(JSON.stringify({ kind: "settings_typecheck", passed: true, mode }));
42
+ } else {
43
+ const file =
44
+ mode === "test" ? "project-installation-summary.test.ts" : "project-settings.test.ts";
45
+ const output = execute([
46
+ "node_modules/vitest/vitest.mjs",
47
+ "run",
48
+ prefix + file,
49
+ "--maxWorkers=1",
50
+ ]);
51
+ const tests = output
52
+ .split("\n")
53
+ .find((line) => /^\s*Tests\s/.test(line))
54
+ ?.trim();
55
+ if (!tests || !/\b[1-9]\d* passed\b/.test(tests)) throw new Error("No settings tests executed");
56
+ console.log(JSON.stringify({ kind: "settings_" + mode, passed: true, mode, tests, output }));
57
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-ui",
3
- "version": "2.6.0",
3
+ "version": "3.1.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {