@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
@@ -0,0 +1,94 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ import { expect, it } from "vitest";
3
+ import { materializeCostGroupDailyProjection } from "./sqlite-cost-group-projection.js";
4
+ import { baseViewSql } from "./sqlite-schema-base-views.js";
5
+
6
+ it("evaluates the invocation population once across all eight daily groups with legacy parity", () => {
7
+ const database = new DatabaseSync(":memory:");
8
+ let costReads = 0;
9
+ database.function("observed_cost", (id) => {
10
+ costReads++;
11
+ return id === 1 ? 0 : null;
12
+ });
13
+ try {
14
+ database.exec(`CREATE TABLE inputs(id INTEGER); INSERT INTO inputs VALUES (1),(2);
15
+ CREATE VIEW invocations AS SELECT '2026-09-15' AS occurred_day_sp,
16
+ 'e' AS execution_id, 'a' AS zaip_agent, 'p' AS provider, 'm' AS model,
17
+ 't' AS task_id, 's' AS spec_id, 'r' AS prd_id, 'c' AS conversation_id,
18
+ 1 AS llm_call_count, NULL AS duration_ms, 2 AS input_tokens,
19
+ NULL AS cached_input_tokens, 3 AS output_tokens, NULL AS reasoning_tokens,
20
+ 5 AS total_tokens, observed_cost(id) AS cost_usd, NULL AS cost_brl FROM inputs;`);
21
+ const definition = /CREATE VIEW cost_monitor_group_daily_cache AS ([^;]+);/.exec(
22
+ baseViewSql,
23
+ )?.[1];
24
+ if (!definition) throw new Error("Canonical daily group SQL absent");
25
+ database.exec(`CREATE VIEW measured AS ${definition};`);
26
+ const actual = database.prepare("SELECT * FROM measured ORDER BY group_kind").all();
27
+ expect(actual).toHaveLength(8);
28
+ expect(costReads).toBe(2);
29
+ const reference = definition
30
+ .replace(/WITH group_invocations AS MATERIALIZED \([^)]*\) /, "")
31
+ .replaceAll("FROM group_invocations", "FROM invocations");
32
+ costReads = 0;
33
+ const expected = database.prepare(`SELECT * FROM (${reference}) ORDER BY group_kind`).all();
34
+ expect(costReads).toBe(16);
35
+ expect(actual).toEqual(expected);
36
+ for (const row of actual) {
37
+ expect(row.invocation_count).toBe(2);
38
+ expect(row.total_cost_usd).toBe(0);
39
+ expect(row.total_cost_brl).toBeNull();
40
+ expect(row.total_duration).toBeNull();
41
+ }
42
+ } finally {
43
+ database.close();
44
+ }
45
+ });
46
+
47
+ it("materializes exact labels without evaluating unrelated entity metrics", () => {
48
+ const database = new DatabaseSync(":memory:");
49
+ let irrelevantReads = 0;
50
+ database.function("unrelated_metric", () => {
51
+ irrelevantReads++;
52
+ throw new Error("Label projection must not evaluate unrelated metrics");
53
+ });
54
+ try {
55
+ database.exec(
56
+ `CREATE TABLE zaip_vw_cost_monitor_group_daily_cache(group_kind TEXT, day TEXT, group_value TEXT, cost REAL);`,
57
+ );
58
+ const insert = database.prepare(
59
+ "INSERT INTO zaip_vw_cost_monitor_group_daily_cache VALUES (?, '2026-09-15', ?, 2)",
60
+ );
61
+ for (const kind of ["task", "spec", "prd", "execution", "conversation"]) {
62
+ insert.run(kind, kind);
63
+ insert.run(kind, "missing");
64
+ insert.run(kind, null);
65
+ database.exec(
66
+ `CREATE VIEW zaip_vw_${kind}s AS SELECT '${kind}' AS id, 'Title' AS title, 'blocked' AS status, 'standard' AS risk, unrelated_metric() AS expensive_unused;`,
67
+ );
68
+ }
69
+ materializeCostGroupDailyProjection(database);
70
+ const rows = database
71
+ .prepare("SELECT * FROM cost_group_entity_projection ORDER BY group_kind, group_value")
72
+ .all();
73
+ expect(rows).toHaveLength(10);
74
+ for (const row of rows) {
75
+ expect(row.status).toBe(row.group_value === "missing" ? null : "blocked");
76
+ const titled =
77
+ row.group_value !== "missing" && ["task", "spec", "prd"].includes(String(row.group_kind));
78
+ expect(row.title).toBe(titled ? "Title" : null);
79
+ expect(row.risk).toBe(titled ? "standard" : null);
80
+ }
81
+ expect(irrelevantReads).toBe(0);
82
+ materializeCostGroupDailyProjection(database);
83
+ expect(
84
+ database
85
+ .prepare("SELECT * FROM cost_group_entity_projection ORDER BY group_kind, group_value")
86
+ .all(),
87
+ ).toEqual(rows);
88
+ expect(database.prepare("SELECT COUNT(*) AS n FROM cost_group_daily_projection").get()?.n).toBe(
89
+ 15,
90
+ );
91
+ } finally {
92
+ database.close();
93
+ }
94
+ });
@@ -15,11 +15,11 @@ export function materializeCostGroupDailyProjection(database: DatabaseSync): voi
15
15
  CREATE TABLE IF NOT EXISTS cost_group_entity_projection(group_kind TEXT, group_value TEXT, title TEXT, status TEXT, risk TEXT);
16
16
  DELETE FROM cost_group_entity_projection;
17
17
  INSERT INTO cost_group_entity_projection
18
- WITH tasks AS MATERIALIZED (SELECT * FROM zaip_vw_tasks),
19
- specs AS MATERIALIZED (SELECT * FROM zaip_vw_specs),
20
- prds AS MATERIALIZED (SELECT * FROM zaip_vw_prds),
21
- executions AS MATERIALIZED (SELECT * FROM zaip_vw_executions),
22
- conversations AS MATERIALIZED (SELECT * FROM zaip_vw_conversations)
18
+ WITH tasks AS MATERIALIZED (SELECT id, title, status, risk FROM zaip_vw_tasks),
19
+ specs AS MATERIALIZED (SELECT id, title, status, risk FROM zaip_vw_specs),
20
+ prds AS MATERIALIZED (SELECT id, title, status, risk FROM zaip_vw_prds),
21
+ executions AS MATERIALIZED (SELECT id, status FROM zaip_vw_executions),
22
+ conversations AS MATERIALIZED (SELECT id, status FROM zaip_vw_conversations)
23
23
  SELECT 'task' AS group_kind, groups.group_value, entity.title, entity.status, entity.risk
24
24
  FROM (SELECT DISTINCT group_value FROM cost_group_daily_projection
25
25
  WHERE group_kind = 'task' AND group_value IS NOT NULL) groups
@@ -0,0 +1,59 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ import { expect, it } from "vitest";
3
+ import { baseViewSql } from "./sqlite-schema-base-views.js";
4
+
5
+ it("uses indexed duration lookup with exact legacy sums and nulls and no duplicate Run rows", () => {
6
+ const db = new DatabaseSync(":memory:");
7
+ try {
8
+ db.exec(
9
+ "CREATE TABLE zaip_aios_activities(activity_row_id TEXT, payload_type TEXT, payload_json TEXT);",
10
+ );
11
+ const insert = db.prepare("INSERT INTO zaip_aios_activities VALUES(?,?,?)");
12
+ for (const id of ["known", "zero", "unknown", "missing"]) insert.run(id, null, null);
13
+ for (const [id, values] of [
14
+ ["known", [3, 5, null]],
15
+ ["zero", [0]],
16
+ ["unknown", [null]],
17
+ ["unrelated", [900]],
18
+ ] as const)
19
+ for (const duration of values)
20
+ insert.run(
21
+ `fact-${id}`,
22
+ "duration_allocation",
23
+ JSON.stringify({ activity_row_id: id, attributed_token_active_ms: duration }),
24
+ );
25
+ insert.run(
26
+ "technical",
27
+ "other",
28
+ JSON.stringify({ activity_row_id: "known", attributed_token_active_ms: 999 }),
29
+ );
30
+ const index = /CREATE INDEX zaip_activities_duration_activity[^;]+;/.exec(baseViewSql)?.[0];
31
+ const view = /CREATE VIEW activities AS\s+([^;]+);/.exec(baseViewSql)?.[1];
32
+ if (!index || !view) throw new Error("Canonical indexed duration SQL missing");
33
+ db.exec(`${index} CREATE VIEW activities AS ${view};`);
34
+ const query =
35
+ "SELECT activity_row_id,attributed_token_active_ms FROM activities ORDER BY activity_row_id";
36
+ const actual = db.prepare(query).all();
37
+ const expected = db
38
+ .prepare(`SELECT a.activity_row_id,f.duration AS attributed_token_active_ms
39
+ FROM zaip_aios_activities a LEFT JOIN (
40
+ SELECT json_extract(payload_json,'$.activity_row_id') AS activity_row_id,
41
+ SUM(json_extract(payload_json,'$.attributed_token_active_ms')) AS duration
42
+ FROM zaip_aios_activities WHERE payload_type='duration_allocation' GROUP BY activity_row_id
43
+ ) f USING(activity_row_id) WHERE a.payload_type IS NULL ORDER BY a.activity_row_id`)
44
+ .all();
45
+ expect(actual).toEqual(expected);
46
+ expect(actual).toHaveLength(4);
47
+ expect(actual.map((row) => row.attributed_token_active_ms)).toEqual([8, null, null, 0]);
48
+ const plan = db.prepare(`EXPLAIN QUERY PLAN ${query}`).all();
49
+ expect(
50
+ plan.some((row) =>
51
+ String(row.detail).includes("zaip_activities_duration_activity (<expr>=?)"),
52
+ ),
53
+ ).toBe(true);
54
+ const labelPlan = db.prepare("EXPLAIN QUERY PLAN SELECT activity_row_id FROM activities").all();
55
+ expect(labelPlan.some((row) => String(row.detail).includes("CORRELATED"))).toBe(false);
56
+ } finally {
57
+ db.close();
58
+ }
59
+ });
@@ -0,0 +1,72 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ import { expect, it } from "vitest";
3
+ import { baseViewSql } from "./sqlite-schema-base-views.js";
4
+
5
+ it("preserves canonical precedence and legacy labels without repeated payload or metric expansion", () => {
6
+ const db = new DatabaseSync(":memory:");
7
+ let payloadReads = 0;
8
+ let metricReads = 0;
9
+ db.function("payload_origin", (value) => {
10
+ payloadReads++;
11
+ return value;
12
+ });
13
+ db.function("unused_metric", () => {
14
+ metricReads++;
15
+ return 42;
16
+ });
17
+ try {
18
+ db.exec(`
19
+ CREATE TABLE inputs(id TEXT, status TEXT, created_at TEXT, occurred_day_sp TEXT, origin_type TEXT, origin_id TEXT);
20
+ INSERT INTO inputs VALUES
21
+ ('e1','blocked','2026-09-01','2026-09-01','interaction','c1'),
22
+ ('e2','completed','2026-09-02','2026-09-02','interaction','c1'),
23
+ ('e3',NULL,'2026-09-03','2026-09-03','task','not-conversation'),
24
+ ('e4','failed','2026-09-04','2026-09-04','interaction',NULL);
25
+ CREATE VIEW canonical_executions AS SELECT id,status,created_at,occurred_day_sp,origin_type,
26
+ payload_origin(origin_id) AS origin_id FROM inputs;
27
+ CREATE TABLE zaip_aios_activities(payload_type TEXT, execution_id TEXT, conversation_id TEXT,
28
+ status TEXT, occurred_at TEXT, occurred_day_sp TEXT);
29
+ INSERT INTO zaip_aios_activities VALUES
30
+ (NULL,'e1','c1','failed','2026-08-01','2026-08-01'),
31
+ (NULL,'legacy','legacy-c','blocked','2026-09-05','2026-09-05'),
32
+ (NULL,'legacy','legacy-c','completed','2026-09-06','2026-09-06'),
33
+ (NULL,'unknown','unknown-c',NULL,NULL,NULL),
34
+ ('technical','fake','fake-c','completed','2026-01-01','2026-01-01'),
35
+ (NULL,NULL,NULL,'completed','2026-01-01','2026-01-01');
36
+ CREATE VIEW activities AS SELECT a.*, f.metric FROM zaip_aios_activities a
37
+ LEFT JOIN (SELECT execution_id, SUM(unused_metric()) AS metric FROM zaip_aios_activities GROUP BY execution_id) f
38
+ USING(execution_id) WHERE a.payload_type IS NULL;
39
+ `);
40
+ const reference = {
41
+ executions: `SELECT id,status,created_at AS occurred_at,occurred_day_sp FROM canonical_executions
42
+ UNION ALL SELECT execution_id,MAX(status),MIN(occurred_at),MIN(occurred_day_sp)
43
+ FROM activities WHERE execution_id IS NOT NULL AND NOT EXISTS
44
+ (SELECT 1 FROM canonical_executions c WHERE c.id=activities.execution_id) GROUP BY execution_id`,
45
+ conversations: `SELECT origin_id AS id,MAX(status) AS status,MIN(created_at) AS occurred_at,MIN(occurred_day_sp) AS occurred_day_sp
46
+ FROM canonical_executions WHERE origin_type='interaction' AND origin_id IS NOT NULL GROUP BY origin_id
47
+ UNION ALL SELECT conversation_id,MAX(status),MIN(occurred_at),MIN(occurred_day_sp)
48
+ FROM activities WHERE conversation_id IS NOT NULL AND NOT EXISTS
49
+ (SELECT 1 FROM canonical_executions c WHERE c.origin_type='interaction' AND c.origin_id=activities.conversation_id) GROUP BY conversation_id`,
50
+ };
51
+ for (const name of ["executions", "conversations"] as const) {
52
+ const expected = db.prepare(`SELECT * FROM (${reference[name]}) ORDER BY id`).all();
53
+ const repeatedReads = payloadReads;
54
+ payloadReads = 0;
55
+ metricReads = 0;
56
+ const definition = new RegExp(`CREATE VIEW ${name} AS\\s+([^;]+);`).exec(baseViewSql)?.[1];
57
+ if (!definition) throw new Error(`Missing canonical view ${name}`);
58
+ const actual = db.prepare(`SELECT * FROM (${definition}) ORDER BY id`).all();
59
+ expect(actual).toEqual(expected);
60
+ expect(actual.some((row) => String(row.id).startsWith("fake"))).toBe(false);
61
+ expect(metricReads).toBe(0);
62
+ if (name === "conversations") {
63
+ expect(payloadReads).toBe(4);
64
+ expect(repeatedReads).toBeGreaterThan(payloadReads);
65
+ expect(actual.find((row) => row.id === "c1")?.status).toBe("completed");
66
+ expect(actual.find((row) => row.id === "unknown-c")?.status).toBeNull();
67
+ }
68
+ }
69
+ } finally {
70
+ db.close();
71
+ }
72
+ });
@@ -0,0 +1,69 @@
1
+ import { mkdtemp, rm } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { DatabaseSync } from "node:sqlite";
5
+ import { expect, it } from "vitest";
6
+ import { rebuildSqliteReadModel, validateSqliteReadModelSchema } from "./sqlite-read-model.js";
7
+ import { prepareMultiProviderFixture } from "./sqlite-read-model-multi-provider-fixture.js";
8
+
9
+ it("indexes exact and LIKE file lookups without changing case or prefix membership", async () => {
10
+ const root = await mkdtemp(join(tmpdir(), "zaip-file-index-"));
11
+ let database: DatabaseSync | undefined;
12
+ try {
13
+ await prepareMultiProviderFixture(root);
14
+ await rebuildSqliteReadModel(root);
15
+ const path = join(root, ".local/sqlite/zaip-aios-dashboard.sqlite");
16
+ database = new DatabaseSync(path);
17
+ const reader = database;
18
+ const queries = [
19
+ {
20
+ sql: "SELECT path, content FROM zaip_vw_files WHERE path = ?",
21
+ arg: ".agents/config/project.yaml",
22
+ index: "zaip_activities_file_path",
23
+ },
24
+ {
25
+ sql: "SELECT path FROM zaip_vw_files WHERE path LIKE ? ORDER BY path",
26
+ arg: ".agents/%",
27
+ index: "zaip_activities_file_path",
28
+ },
29
+ {
30
+ sql: "SELECT path FROM zaip_vw_files WHERE path LIKE ? ORDER BY path",
31
+ arg: ".AGENTS/%",
32
+ index: "zaip_activities_file_path",
33
+ },
34
+ {
35
+ sql: "SELECT path FROM zaip_vw_files WHERE path LIKE ? ORDER BY path",
36
+ arg: ".agents/missing/%",
37
+ index: "zaip_activities_file_path",
38
+ },
39
+ {
40
+ sql: "SELECT path FROM zaip_vw_files WHERE path = ?",
41
+ arg: ".AGENTS/config/project.yaml",
42
+ index: "zaip_activities_file_path",
43
+ },
44
+ ];
45
+ const indexed = queries.map(({ sql, arg, index }) => {
46
+ const plan = reader.prepare(`EXPLAIN QUERY PLAN ${sql}`).all(arg);
47
+ expect(JSON.stringify(plan)).toContain(`USING INDEX ${index}`);
48
+ return reader.prepare(sql).all(arg);
49
+ });
50
+ expect(indexed[0]).toHaveLength(1);
51
+ expect(indexed[1]?.length).toBeGreaterThan(1);
52
+ expect(indexed[2]).toEqual(indexed[1]);
53
+ expect(indexed[3]).toEqual([]);
54
+ expect(indexed[4]).toEqual([]);
55
+ const view = database
56
+ .prepare("SELECT sql FROM sqlite_master WHERE name='zaip_vw_files'")
57
+ .get() as { sql: string };
58
+ database.exec("DROP VIEW zaip_vw_files;");
59
+ database.exec(view.sql.replace(" INDEXED BY zaip_activities_file_path", ""));
60
+ database.exec("DROP INDEX zaip_activities_file_path;");
61
+ expect(() => validateSqliteReadModelSchema(path)).toThrow(/missing required indexes/);
62
+ for (const [position, { sql, arg }] of queries.entries()) {
63
+ expect(database.prepare(sql).all(arg)).toEqual(indexed[position]);
64
+ }
65
+ } finally {
66
+ database?.close();
67
+ await rm(root, { recursive: true, force: true });
68
+ }
69
+ });
@@ -231,7 +231,9 @@ export function readFirstFoldViewport(
231
231
  SELECT COALESCE(status, 'draft') AS status, COUNT(*) AS task_count FROM items WHERE entity_kind='task' GROUP BY COALESCE(status, 'draft'))
232
232
  ), task_risk AS (
233
233
  SELECT json_group_object(risk, task_count) AS task_risk_json FROM (
234
- SELECT COALESCE(risk, 'standard') AS risk, COUNT(*) AS task_count FROM items WHERE entity_kind='task' GROUP BY COALESCE(risk, 'standard'))
234
+ SELECT COALESCE(risk, 'standard') AS risk, COUNT(*) AS task_count FROM items
235
+ WHERE entity_kind='task' AND COALESCE(status, 'draft') <> 'draft'
236
+ GROUP BY COALESCE(risk, 'standard'))
235
237
  )
236
238
  SELECT totals.*, run_totals.*, duration_totals.*, bounds.*, item_totals.*, task_status.*, task_risk.*
237
239
  FROM totals CROSS JOIN run_totals CROSS JOIN duration_totals CROSS JOIN bounds
@@ -1,7 +1,7 @@
1
1
  import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
2
2
  import { join, resolve } from "node:path";
3
3
  import { DatabaseSync } from "node:sqlite";
4
- import { afterEach, describe, expect, it } from "vitest";
4
+ import { afterEach, describe, expect, it, vi } from "vitest";
5
5
  import { rebuildSqliteReadModel } from "./sqlite-read-model.js";
6
6
 
7
7
  const roots: string[] = [];
@@ -17,12 +17,14 @@ async function fixture(): Promise<string> {
17
17
  }
18
18
 
19
19
  afterEach(async () => {
20
+ vi.restoreAllMocks();
20
21
  await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
21
22
  });
22
23
 
23
24
  describe("forceCanonical SQLite refresh", () => {
24
25
  it("bypasses a healthy generation and verifies canonical sources again", async () => {
25
26
  const root = await fixture();
27
+ vi.spyOn(Date, "now").mockReturnValue(Date.now() + 5_000);
26
28
  const initial = await rebuildSqliteReadModel(root);
27
29
  await expect(rebuildSqliteReadModel(root)).resolves.toMatchObject({
28
30
  cache: "generation",
@@ -173,6 +173,8 @@ describe("incremental refresh preserves historical facts", () => {
173
173
  it("updates and removes changed sources in place with full-build query parity and untouched historical payloads", async () => {
174
174
  const root = await fixture();
175
175
  const { started, usage, finished } = await prepareMultiProviderFixture(root);
176
+ // This scenario exercises settled historical checkpoints, not rapid writes.
177
+ vi.spyOn(Date, "now").mockReturnValue(Date.now() + 5_000);
176
178
  const first = await rebuildSqliteReadModel(root);
177
179
  const history = inspect(first.path, historySql);
178
180
  expect(history).toHaveLength(2);
@@ -15,6 +15,7 @@ import {
15
15
  knownSum,
16
16
  saoPauloDay,
17
17
  } from "./sqlite-read-model-canonical.js";
18
+ import { reportSqliteReadModelLaunchProgress as progress } from "./sqlite-read-model-launch-progress.js";
18
19
  import { readModelSchemaVersion } from "./sqlite-read-model-schema.js";
19
20
  import { baseViewSql } from "./sqlite-schema-base-views.js";
20
21
  import { dashboardViewSql } from "./sqlite-schema-dashboard-views.js";
@@ -234,6 +235,7 @@ export function materializeDashboardProjections(input: ProjectionInput) {
234
235
  }
235
236
  };
236
237
  materializeSharedCreationAllocations();
238
+ progress("projection_allocations_ready", 78, "Rateios de criação concluídos.");
237
239
  const canonicalRunCount = Number(
238
240
  (
239
241
  database
@@ -352,6 +354,7 @@ export function materializeDashboardProjections(input: ProjectionInput) {
352
354
  insertConfiguredProvider.run(configuredModel.provider);
353
355
  }
354
356
  const costDimensionAggregates = buildCostDimensionAggregates(database, agentProfiles);
357
+ progress("projection_costs_ready", 78, "Agregados de custo concluídos.");
355
358
  // The rebuild scratch tables above are intentionally TEMP only. Persist
356
359
  // their technical inputs as typed payload activities so the on-disk
357
360
  // model has one fact plus its three declared dimensions, never hidden
@@ -443,6 +446,7 @@ export function materializeDashboardProjections(input: ProjectionInput) {
443
446
  });
444
447
  }
445
448
  synchronizePayloadRows(database, "cost_dimension_aggregate_v1", dimensionPayloads);
449
+ progress("projection_payloads_ready", 78, "Projeções incrementais persistidas.");
446
450
  // Keep canonical TEMP references outside the public-view name rewriter.
447
451
  database.exec(
448
452
  hasPersistentSchema
@@ -454,6 +458,7 @@ export function materializeDashboardProjections(input: ProjectionInput) {
454
458
  .replace(/CREATE INDEX cost_dimension_facts_[A-Za-z_]+ ON [^;]+;/g, "")
455
459
  : rebuildCostInvocationDimensionFactsSql,
456
460
  );
461
+ progress("projection_facts_ready", 78, "Fatos das dimensões concluídos.");
457
462
  const viewSql = baseViewSql + dashboardViewSql;
458
463
  // Every SQLite view has a single discoverable namespace. References in
459
464
  // the view definitions are rewritten from their concise source aliases
@@ -478,6 +483,7 @@ export function materializeDashboardProjections(input: ProjectionInput) {
478
483
  },
479
484
  );
480
485
  if (!hasPersistentSchema) database.exec(deduplicatedViewSql);
486
+ progress("projection_views_ready", 78, "Views públicas preparadas.");
481
487
  // One row per stable GitHub account. Costs are summed from the single
482
488
  // canonical Run fact, while delivery is joined exclusively through the
483
489
  // Task's completed_run_id (never inferred from a branch or latest Run).
@@ -523,11 +529,14 @@ export function materializeDashboardProjections(input: ProjectionInput) {
523
529
  : developerProjectionSql,
524
530
  );
525
531
  materializeCostGroupDailyProjection(database);
532
+ progress("projection_daily_ready", 78, "Agrupamentos diários concluídos.");
526
533
  materializeOperationsWorkProjection(database);
534
+ progress("projection_operations_ready", 78, "Projeção operacional concluída.");
527
535
  // Persist the complete unfiltered invocation projection while the seed
528
536
  // still owns the compact canonical facts. Runtime pages can then slice
529
537
  // 10/100 rows without expanding the pricing view for every request.
530
538
  const costAgentInvocationProjection = readCostInvocationProjection(database);
539
+ progress("projection_invocations_ready", 78, "Projeção de invocações concluída.");
531
540
  synchronizePayloadRows(
532
541
  database,
533
542
  "cost_agent_invocation_projection_v1",
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import type { DatabaseSync } from "node:sqlite";
3
- import { pricingCatalogSchema, resolveHistoricalDeveloperAttribution } from "@zaip-ai/costs";
3
+ import { prepareHistoricalDeveloperAttribution, pricingCatalogSchema } from "@zaip-ai/costs";
4
4
  import {
5
5
  foldRunV2Records,
6
6
  parseRunV2JsonLines,
@@ -97,7 +97,7 @@ export function materializeCanonicalRuns(input: RunMaterializationInput) {
97
97
  .all() as Array<{ content: string }>
98
98
  ).flatMap((row) => {
99
99
  try {
100
- return [JSON.parse(row.content)];
100
+ return [prepareHistoricalDeveloperAttribution(JSON.parse(row.content))];
101
101
  } catch {
102
102
  return [];
103
103
  }
@@ -117,8 +117,7 @@ export function materializeCanonicalRuns(input: RunMaterializationInput) {
117
117
  };
118
118
  for (const candidate of historicalDeveloperManifests) {
119
119
  try {
120
- const resolved = resolveHistoricalDeveloperAttribution({
121
- manifest: candidate,
120
+ const resolved = candidate({
122
121
  run_id: String(JSON.parse(row.content.split(/\r?\n/u)[0] ?? "{}").run_id ?? ""),
123
122
  path: row.path,
124
123
  content: row.content,
@@ -480,7 +479,7 @@ export function materializeCanonicalRuns(input: RunMaterializationInput) {
480
479
  const audit = usagePricingAudit(record, fold, pricingCatalog, fxRate);
481
480
  insertUsageSegment.run(
482
481
  agentRunId,
483
- record.provider ?? null,
482
+ canonicalProvider(record.provider, record.model ?? started.model, started.client),
484
483
  record.model ?? null,
485
484
  audit.serviceTier,
486
485
  record.runtime?.reasoning_effort ?? null,
@@ -0,0 +1,46 @@
1
+ import { summarizeCostPeriodAverages } from "@zaip-ai/dashboard-cost-monitor/server";
2
+
3
+ export function sqlitePeriodTotals(rows: readonly Record<string, unknown>[]) {
4
+ const totals: Record<string, number | null> = {};
5
+ for (const key of [
6
+ "prd_count",
7
+ "spec_count",
8
+ "task_count",
9
+ "total_run_count",
10
+ "validation_count",
11
+ "evidence_count",
12
+ "total_duration",
13
+ "total_tokens",
14
+ "total_cost_usd",
15
+ "total_cost_brl",
16
+ ]) {
17
+ const values = rows
18
+ .map((row) => row[key])
19
+ .filter((value): value is number => typeof value === "number" && Number.isFinite(value));
20
+ totals[key] = values.length === 0 ? null : values.reduce((sum, value) => sum + value, 0);
21
+ }
22
+ totals.duration_known = totals.total_duration ?? 0;
23
+ totals.duration_unknown = rows.filter((row) => typeof row.total_duration !== "number").length;
24
+ return totals;
25
+ }
26
+
27
+ /** Compute before pagination, over exactly the filtered period population. */
28
+ export function sqlitePeriodAverages(rows: readonly Record<string, unknown>[]) {
29
+ const adapted = rows.map((row) => {
30
+ const value = (key: string) =>
31
+ typeof row[key] === "number" && Number.isFinite(row[key]) ? (row[key] as number) : null;
32
+ return {
33
+ task_count: value("task_count"),
34
+ spec_count: value("spec_count"),
35
+ prd_count: value("prd_count"),
36
+ duration_ms: value("total_duration"),
37
+ total_tokens: value("total_tokens"),
38
+ estimated_usd: value("total_cost_usd"),
39
+ estimated_brl: value("total_cost_brl"),
40
+ };
41
+ });
42
+ return {
43
+ BRL: summarizeCostPeriodAverages(adapted, "BRL"),
44
+ USD: summarizeCostPeriodAverages(adapted, "USD"),
45
+ };
46
+ }
@@ -0,0 +1,50 @@
1
+ import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { DatabaseSync } from "node:sqlite";
5
+ import { expect, it } from "vitest";
6
+ import { rebuildSqliteReadModel } from "./sqlite-read-model.js";
7
+ import { prepareMultiProviderFixture } from "./sqlite-read-model-multi-provider-fixture.js";
8
+
9
+ it.each([
10
+ "CODEX",
11
+ "codex",
12
+ "unavailable",
13
+ ])("keeps canonical activity and usage-segment provider consistent for %s without rewriting records", async (provider) => {
14
+ const root = await mkdtemp(join(tmpdir(), "zaip-provider-parity-"));
15
+ try {
16
+ const { started, usage, finished } = await prepareMultiProviderFixture(root);
17
+ const path = join(root, ".agents/records/runs/2026/08/RUN-MULTI.jsonl");
18
+ const source = `${[
19
+ { ...started, provider, model: "gpt-a" },
20
+ usage(2, provider, "gpt-a", 10, 5),
21
+ { ...finished, event_id: "RUN-MULTI:3", sequence: 3 },
22
+ ]
23
+ .map((row) => JSON.stringify(row))
24
+ .join("\n")}\n`;
25
+ await writeFile(path, source);
26
+ const result = await rebuildSqliteReadModel(root);
27
+ const database = new DatabaseSync(result.path, { readOnly: true });
28
+ try {
29
+ const expected = provider === "unavailable" ? null : "openai";
30
+ expect(
31
+ database
32
+ .prepare(
33
+ "SELECT provider FROM zaip_aios_activities WHERE run_id='RUN-MULTI' AND payload_type IS NULL",
34
+ )
35
+ .get(),
36
+ ).toMatchObject({ provider: expected });
37
+ const segments = database
38
+ .prepare(
39
+ "SELECT json_extract(payload_json,'$.provider') AS provider, json_extract(payload_json,'$.cost_brl') AS cost_brl FROM zaip_aios_activities WHERE payload_type='usage_segment' AND json_extract(payload_json,'$.agent_invocation_id')='AINV-MULTI'",
40
+ )
41
+ .all();
42
+ expect(segments).toEqual([{ provider: expected, cost_brl: 5 }]);
43
+ } finally {
44
+ database.close();
45
+ }
46
+ expect(await readFile(path, "utf8")).toBe(source);
47
+ } finally {
48
+ await rm(root, { recursive: true, force: true });
49
+ }
50
+ });