@zaip-ai/cli 1.0.7 → 1.0.8

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 (410) hide show
  1. package/README.md +6 -4
  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 +15 -5
  5. package/dist/services/adapters.js.map +1 -1
  6. package/dist/services/adapters.test.js +1 -1
  7. package/dist/services/agent-adapters.d.ts +9 -0
  8. package/dist/services/agent-adapters.d.ts.map +1 -1
  9. package/dist/services/agent-adapters.js +38 -3
  10. package/dist/services/agent-adapters.js.map +1 -1
  11. package/dist/services/agent-adapters.test.js +8 -1
  12. package/dist/services/agent-adapters.test.js.map +1 -1
  13. package/dist/services/codex-config-template.d.ts +2 -1
  14. package/dist/services/codex-config-template.d.ts.map +1 -1
  15. package/dist/services/codex-config-template.js +13 -2
  16. package/dist/services/codex-config-template.js.map +1 -1
  17. package/dist/services/codex-rules.d.ts +1 -1
  18. package/dist/services/codex-rules.d.ts.map +1 -1
  19. package/dist/services/codex-rules.js +31 -7
  20. package/dist/services/codex-rules.js.map +1 -1
  21. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  22. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  23. package/dist/services/codex-subagent-hook-template.js +4 -1
  24. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  25. package/dist/services/doctor.d.ts.map +1 -1
  26. package/dist/services/doctor.js +3 -1
  27. package/dist/services/doctor.js.map +1 -1
  28. package/dist/services/global-codex-config.d.ts +6 -3
  29. package/dist/services/global-codex-config.d.ts.map +1 -1
  30. package/dist/services/global-codex-config.js +82 -13
  31. package/dist/services/global-codex-config.js.map +1 -1
  32. package/dist/services/global-codex-config.test.js +57 -10
  33. package/dist/services/global-codex-config.test.js.map +1 -1
  34. package/dist/services/install-agents-template.d.ts.map +1 -1
  35. package/dist/services/install-agents-template.js +15 -2
  36. package/dist/services/install-agents-template.js.map +1 -1
  37. package/dist/services/logger.js +1 -1
  38. package/dist/services/logger.js.map +1 -1
  39. package/dist/services/logger.test.js +3 -3
  40. package/dist/services/logger.test.js.map +1 -1
  41. package/dist/services/runtime-template.test.js +21 -5
  42. package/dist/services/runtime-template.test.js.map +1 -1
  43. package/dist/services/template-manifest.d.ts.map +1 -1
  44. package/dist/services/template-manifest.js +2 -0
  45. package/dist/services/template-manifest.js.map +1 -1
  46. package/package.json +1 -1
  47. package/templates/.agents/config/agents/catalog.yaml +310 -10
  48. package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +30 -0
  49. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +5 -5
  50. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
  51. package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +30 -0
  52. package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +30 -0
  53. package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +30 -0
  54. package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +8 -8
  55. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +5 -3
  56. package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +30 -0
  57. package/templates/.agents/config/project.yaml +1 -1
  58. package/templates/.agents/dashboard/.zaip-managed.json +659 -163
  59. package/templates/.agents/dashboard/DATA-DICTIONARY.md +2227 -0
  60. package/templates/.agents/dashboard/README.md +48 -97
  61. package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-Z60df2r-.js +1 -0
  62. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cv-JcoxP.js → DashboardHelpDialog-Cs6dzDmW.js} +294 -109
  63. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-Coc6pA-1.js +1 -0
  64. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +1 -0
  65. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +3 -0
  66. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +1 -0
  67. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-CaKwQP43.css +1 -0
  68. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +1 -0
  69. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +68 -0
  70. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-C98LGC-Q.js → dashboard-localization-CLJ0lT9v.js} +1 -1
  71. package/templates/.agents/dashboard/apps/frontend/dist/assets/icons-vendor-DFBuc_qp.js +1 -0
  72. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +2 -0
  73. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +1 -0
  74. package/templates/.agents/dashboard/apps/frontend/dist/assets/react-vendor-CCQOHdVI.js +9 -0
  75. package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-D9-fqq9M.js +1 -0
  76. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DFY7ZDlu.css +1 -0
  77. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-pC2_0J8x.js +1 -0
  78. package/templates/.agents/dashboard/apps/frontend/dist/index.html +9 -2
  79. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  80. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +952 -595
  81. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +48 -0
  82. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingPanels.tsx +2 -0
  83. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +247 -0
  84. package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +95 -0
  85. package/templates/.agents/dashboard/apps/frontend/src/AppSetupRoutes.tsx +87 -0
  86. package/templates/.agents/dashboard/apps/frontend/src/CostCalculationGuidePage.tsx +641 -0
  87. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +159 -0
  88. package/templates/.agents/dashboard/apps/frontend/src/DashboardCapabilityNav.tsx +13 -13
  89. package/templates/.agents/dashboard/apps/frontend/src/DashboardGlobalSettings.tsx +56 -0
  90. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +257 -313
  91. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +149 -0
  92. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +35 -0
  93. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +111 -12
  94. package/templates/.agents/dashboard/apps/frontend/src/app-preferences.ts +15 -0
  95. package/templates/.agents/dashboard/apps/frontend/src/app-session-token.ts +20 -0
  96. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.css +267 -0
  97. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.test.ts +69 -0
  98. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +70 -0
  99. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +111 -0
  100. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +432 -13
  101. package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +1 -1
  102. package/templates/.agents/dashboard/apps/frontend/src/main.tsx +1 -0
  103. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.test.ts +55 -0
  104. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.ts +36 -0
  105. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.test.ts +126 -0
  106. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.ts +181 -0
  107. package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +138 -0
  108. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +105 -0
  109. package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +6 -3
  110. package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +9 -5
  111. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +24 -0
  112. package/templates/.agents/dashboard/apps/frontend/src/period-transition-overlay.css +44 -0
  113. package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +121 -62
  114. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +471 -2
  115. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +84 -17
  116. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +44 -0
  117. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +196 -39
  118. package/templates/.agents/dashboard/apps/frontend/src/snapshot-notice.ts +15 -0
  119. package/templates/.agents/dashboard/apps/frontend/src/sqlite-cost-adapters.ts +26 -0
  120. package/templates/.agents/dashboard/apps/frontend/src/styles.css +14 -2
  121. package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +38 -2
  122. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +187 -0
  123. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +190 -0
  124. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +121 -0
  125. package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +398 -0
  126. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +141 -0
  127. package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +45 -0
  128. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +46 -0
  129. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +37 -0
  130. package/templates/.agents/dashboard/apps/frontend/vite.config.ts +55 -5
  131. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  132. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +47 -6
  133. package/templates/.agents/dashboard/modules/cost-monitor/src/duration-estimate.ts +13 -0
  134. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +64 -0
  135. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +275 -0
  136. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +100 -15
  137. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +131 -40
  138. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +137 -19
  139. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.test.ts +2 -0
  140. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +13 -10
  141. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +303 -0
  142. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +226 -6
  143. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +479 -402
  144. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostSummary.tsx +5 -13
  145. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +312 -72
  146. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +373 -321
  147. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +17 -0
  148. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +25 -6
  149. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +0 -2
  150. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-helpers.ts +17 -0
  151. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-responsive.css +6 -3
  152. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-row-filters.ts +123 -0
  153. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +8 -3
  154. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +32 -0
  155. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +52 -14
  156. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-presentation.ts +121 -0
  157. package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +3 -0
  158. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.test.ts +68 -0
  159. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +32 -5
  160. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +108 -0
  161. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +12 -0
  162. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +60 -0
  163. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +106 -0
  164. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.test.ts +2 -2
  165. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +5 -3
  166. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-pricing-fallback.test.ts +53 -0
  167. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.basics.test.ts +34 -0
  168. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +168 -137
  169. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +188 -29
  170. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +956 -0
  171. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +775 -0
  172. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +95 -0
  173. package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
  174. package/templates/.agents/dashboard/modules/cost-monitor/src/server/refactor-map-xr9l.json +61 -0
  175. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.test.ts +41 -0
  176. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.ts +55 -11
  177. package/templates/.agents/dashboard/modules/operations/package.json +2 -1
  178. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +182 -0
  179. package/templates/.agents/dashboard/modules/operations/src/duration-population.test.ts +63 -1
  180. package/templates/.agents/dashboard/modules/operations/src/duration-population.ts +60 -5
  181. package/templates/.agents/dashboard/modules/operations/src/react/EntityDetailsDialog.tsx +14 -3
  182. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.test.ts +44 -1
  183. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +325 -18
  184. package/templates/.agents/dashboard/modules/operations/src/react/MacroPlanningDialog.tsx +1 -0
  185. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.test.ts +9 -5
  186. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.tsx +2 -2
  187. package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +168 -0
  188. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +95 -6
  189. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +365 -14
  190. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +532 -131
  191. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +314 -358
  192. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +68 -0
  193. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +169 -0
  194. package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +51 -8
  195. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.test.tsx +32 -0
  196. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.tsx +62 -6
  197. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.test.ts +55 -0
  198. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.tsx +27 -19
  199. package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +99 -42
  200. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts +19 -0
  201. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +255 -34
  202. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +163 -8
  203. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +101 -68
  204. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.test.ts +72 -1
  205. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +78 -16
  206. package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +6 -4
  207. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +50 -1
  208. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +143 -9
  209. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +29 -4
  210. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog-content.css +49 -0
  211. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog.css +93 -50
  212. package/templates/.agents/dashboard/modules/operations/src/react/manual-work-priority.test.ts +82 -0
  213. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts +29 -2
  214. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.ts +22 -1
  215. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +77 -4
  216. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +65 -5
  217. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +54 -0
  218. package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +19 -0
  219. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +149 -12
  220. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +27 -0
  221. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +136 -0
  222. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.test.ts +160 -0
  223. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.ts +47 -0
  224. package/templates/.agents/dashboard/modules/operations/src/react/operations-query.ts +10 -0
  225. package/templates/.agents/dashboard/modules/operations/src/react/operations-responsive.css +3 -0
  226. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-labels.ts +28 -0
  227. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +24 -7
  228. package/templates/.agents/dashboard/modules/operations/src/react/operations.css +42 -0
  229. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.test.ts +54 -0
  230. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.ts +32 -0
  231. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +165 -6
  232. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +148 -6
  233. package/templates/.agents/dashboard/modules/operations/src/react/popup-localization.test.ts +1 -1
  234. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css +132 -0
  235. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css.test.ts +13 -0
  236. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.header.test.ts +16 -0
  237. package/templates/.agents/dashboard/modules/operations/src/react/use-infinite-column.ts +11 -5
  238. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +5 -3
  239. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +4 -83
  240. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.test.ts +291 -15
  241. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.ts +182 -472
  242. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.test.ts +40 -0
  243. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.ts +19 -6
  244. package/templates/.agents/dashboard/modules/operations/src/server/canonical-run-projection.ts +31 -6
  245. package/templates/.agents/dashboard/modules/operations/src/server/daily-duration-projection.ts +220 -0
  246. package/templates/.agents/dashboard/modules/operations/src/server/execution-duration-projection.ts +28 -0
  247. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +27 -2
  248. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +22 -13
  249. package/templates/.agents/dashboard/modules/operations/src/server/filter.test.ts +3 -3
  250. package/templates/.agents/dashboard/modules/operations/src/server/filter.ts +7 -2
  251. package/templates/.agents/dashboard/modules/operations/src/server/index.ts +3 -0
  252. package/templates/.agents/dashboard/modules/operations/src/server/macro.ts +3 -12
  253. package/templates/.agents/dashboard/modules/operations/src/server/manifest-usage.ts +65 -0
  254. package/templates/.agents/dashboard/modules/operations/src/server/operations-projection-aggregates.ts +297 -0
  255. package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +324 -0
  256. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.test.ts +505 -0
  257. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.ts +609 -0
  258. package/templates/.agents/dashboard/modules/operations/src/server/runs.ts +18 -19
  259. package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +76 -0
  260. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  261. package/templates/.agents/dashboard/modules/traceability/src/server/build-task-trace.ts +3 -1
  262. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  263. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  264. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  265. package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
  266. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  267. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +1756 -0
  268. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +1608 -0
  269. package/templates/.agents/dashboard/packages/local-runtime/package.json +8 -3
  270. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +12 -0
  271. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +83 -0
  272. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +28 -0
  273. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +262 -0
  274. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +41 -0
  275. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +105 -0
  276. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +1643 -107
  277. package/templates/.agents/dashboard/packages/local-runtime/src/agent-adapter-sync.ts +30 -0
  278. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.test.ts +3 -2
  279. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.ts +5 -0
  280. package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +72 -33
  281. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +335 -4
  282. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +392 -1
  283. package/templates/.agents/dashboard/packages/local-runtime/src/runtime.mjs +5 -5
  284. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +71 -0
  285. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +179 -0
  286. package/templates/.agents/dashboard/packages/local-runtime/src/server-cross-layer-parity.test.ts +245 -0
  287. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models-route.ts +64 -0
  288. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.test.ts +204 -0
  289. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.ts +194 -0
  290. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +163 -0
  291. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +354 -0
  292. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.test.ts +74 -0
  293. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +113 -0
  294. package/templates/.agents/dashboard/packages/local-runtime/src/server-overview.test.ts +68 -0
  295. package/templates/.agents/dashboard/packages/local-runtime/src/server-period.ts +47 -0
  296. package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +483 -0
  297. package/templates/.agents/dashboard/packages/local-runtime/src/server-settings.test.ts +5 -2
  298. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +163 -84
  299. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +145 -0
  300. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +551 -266
  301. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +1145 -308
  302. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.test.ts +53 -0
  303. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +708 -0
  304. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +2232 -0
  305. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +6151 -0
  306. package/templates/.agents/dashboard/packages/local-runtime/src/work-priority-contract.test.ts +33 -0
  307. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +41 -0
  308. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +210 -0
  309. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +437 -190
  310. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +299 -24
  311. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  312. package/templates/.agents/dashboard/packages/windows-launcher/LauncherVerificationBehaviorTests.cs +206 -0
  313. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +95 -8
  314. package/templates/.agents/dashboard/packages/windows-launcher/build-dashboard-launcher.ps1 +2 -2
  315. package/templates/.agents/dashboard/packages/windows-launcher/run-launcher-verification-tests.ps1 +22 -0
  316. package/templates/.agents/dashboard/read-model.dbml +2201 -0
  317. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  318. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +1 -1
  319. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +214 -41
  320. package/templates/.agents/dashboard/work-priority.json +34 -0
  321. package/templates/.agents/dashboard/zaip-dashboard-linux.sh +45 -0
  322. package/templates/.agents/dashboard/zaip-dashboard-mac.command +3 -0
  323. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  324. package/templates/.agents/design/.zaip-managed.json +3 -3
  325. package/templates/.agents/design/apps/catalog/package.json +1 -1
  326. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  327. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  328. package/templates/.agents/requirements/comparative-audit.md +1 -1
  329. package/templates/.agents/requirements/context-engine.md +1 -1
  330. package/templates/.agents/requirements/cost-observability.md +1 -1
  331. package/templates/.agents/requirements/dashboard-launch.md +24 -0
  332. package/templates/.agents/requirements/data-export.md +1 -1
  333. package/templates/.agents/requirements/design-system.md +1 -1
  334. package/templates/.agents/requirements/execution-engine.md +1 -1
  335. package/templates/.agents/requirements/kanban-dashboard.md +4 -3
  336. package/templates/.agents/requirements/model-orchestration.md +1 -1
  337. package/templates/.agents/requirements/public-distribution.md +9 -6
  338. package/templates/.agents/requirements/software-architecture.md +1 -1
  339. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  340. package/templates/.agents/requirements/work-lifecycle.md +9 -3
  341. package/templates/.agents/requirements/zaip-strategic-95.md +4 -4
  342. package/templates/.agents/rules/autonomy-decision.md +15 -0
  343. package/templates/.agents/rules/core.md +1 -1
  344. package/templates/.agents/rules/run-lifecycle-closure.md +1 -1
  345. package/templates/.agents/rules/specialist-routing.md +19 -0
  346. package/templates/.agents/rules/workflow.md +1 -1
  347. package/templates/.agents/runtime/VERSION +1 -1
  348. package/templates/.agents/runtime/bin/zaip.mjs +114 -64
  349. package/templates/.agents/runtime/checksums.sha256 +6 -4
  350. package/templates/.agents/runtime/manifest.json +3 -1
  351. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -0
  352. package/templates/.agents/runtime/provenance.json +11 -0
  353. package/templates/.agents/runtime/sbom.cdx.json +1929 -39
  354. package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
  355. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +15 -0
  356. package/templates/.agents/skills/zaip-skill-brand-governance/agents/openai.yaml +4 -0
  357. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +30 -0
  358. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +25 -0
  359. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/agents/openai.yaml +4 -0
  360. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/SKILL.md +18 -0
  361. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/agents/openai.yaml +6 -0
  362. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.mjs +71 -0
  363. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.test.mjs +60 -0
  364. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/scheduled-ready-queue-contract.test.mjs +111 -0
  365. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +2 -2
  366. package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +3 -1
  367. package/templates/.agents/skills/zaip-skill-general-operations/SKILL.md +12 -0
  368. package/templates/.agents/skills/zaip-skill-general-operations/agents/openai.yaml +4 -0
  369. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -7
  370. package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +2 -2
  371. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +11 -38
  372. package/templates/.agents/skills/zaip-skill-governance-compliance/SKILL.md +12 -0
  373. package/templates/.agents/skills/zaip-skill-governance-compliance/agents/openai.yaml +4 -0
  374. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +15 -0
  375. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/agents/openai.yaml +4 -0
  376. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/references/growth-revops-framework.md +25 -0
  377. package/templates/.agents/skills/zaip-skill-instalar-agendamento/SKILL.md +17 -0
  378. package/templates/.agents/skills/zaip-skill-instalar-agendamento/agents/openai.yaml +6 -0
  379. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +3 -3
  380. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +76 -27
  381. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +128 -24
  382. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +122 -4
  383. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +66 -19
  384. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +193 -7
  385. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +14 -0
  386. package/templates/.agents/skills/zaip-skill-sales-methodology/agents/openai.yaml +4 -0
  387. package/templates/.agents/skills/zaip-skill-sales-methodology/references/sales-process-framework.md +77 -0
  388. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +5 -0
  389. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +96 -0
  390. package/templates/.agents/skills/zaip-skill-sqlite-read-model/agents/openai.yaml +4 -0
  391. package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +18 -0
  392. package/templates/.agents/zaip-aios/INDEX.md +1 -0
  393. package/templates/.agents/zaip-aios/README.md +37 -8
  394. package/templates/.agents/zaip-aios/VERSION +1 -1
  395. package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +43 -6
  396. package/templates/.agents/zaip-aios/guides/10-seguranca.md +21 -7
  397. package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +32 -0
  398. package/templates/template-manifest.json +945 -214
  399. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-CLYIi7Vo.js +0 -1
  400. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-DTDNVQGX.css +0 -1
  401. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-CzEggcRb.js +0 -1
  402. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-05YKn6Z4.js +0 -3
  403. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-YO3yqtgV.css +0 -1
  404. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8AzCnl3a.js +0 -77
  405. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DdBYQ_8D.css +0 -1
  406. package/templates/.agents/dashboard/apps/frontend/src/AgentCatalogSettingsPage.tsx +0 -617
  407. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings-page.css +0 -660
  408. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings.test.ts +0 -249
  409. package/templates/.agents/dashboard/dashboard.config.json +0 -4
  410. package/templates/.agents/dashboard/zaip-dashboard.exe +0 -0
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-local-runtime",
3
- "version": "1.0.0",
3
+ "version": "1.0.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
- "build": "node ../../../../scripts/build-package.mjs src/server.ts dist/server.js",
7
+ "build": "node scripts/build-sqlite-runtime.mjs",
8
8
  "clean": "node ../../../../scripts/clean.mjs",
9
- "dashboard:open": "node ./src/start-dashboard.mjs",
9
+ "dashboard:open": "node ./start-dashboard.mjs",
10
+ "sqlite:rebuild": "node scripts/rebuild-sqlite-read-model.mjs",
11
+ "sqlite:verify": "node scripts/build-sqlite-runtime.mjs && node scripts/rebuild-sqlite-read-model.mjs",
12
+ "sqlite:validate": "node scripts/build-sqlite-runtime.mjs && node scripts/validate-sqlite-read-model.mjs",
13
+ "launcher:unix:contract": "node scripts/test-unix-launchers.mjs",
10
14
  "test": "vitest run --passWithNoTests",
11
15
  "typecheck": "tsc --noEmit"
12
16
  },
@@ -17,6 +21,7 @@
17
21
  "@zaip-ai/dashboard-cost-monitor": "workspace:*",
18
22
  "@zaip-ai/dashboard-data-export": "workspace:*",
19
23
  "@zaip-ai/dashboard-frontend": "workspace:*",
24
+ "@zaip-ai/lifecycle-manifests": "workspace:*",
20
25
  "@zaip-ai/dashboard-operations": "workspace:*",
21
26
  "@zaip-ai/dashboard-traceability": "workspace:*",
22
27
  "hono": "4.12.34",
@@ -0,0 +1,12 @@
1
+ import { spawn } from "node:child_process";
2
+ import { resolve } from "node:path";
3
+
4
+ const root = resolve(import.meta.dirname, "../../../../..");
5
+ const run = (cwd, args) => new Promise((resolveRun, rejectRun) => {
6
+ const child = spawn(process.execPath, args, { cwd, stdio: "inherit", windowsHide: true });
7
+ child.once("error", rejectRun);
8
+ child.once("exit", (code) => code === 0 ? resolveRun(undefined) : rejectRun(new Error(`build failed: ${code}`)));
9
+ });
10
+ await run(resolve(root, ".agents/dashboard/apps/frontend"), [resolve(root, "node_modules/vite/bin/vite.js"), "build"]);
11
+ await run(resolve(root, ".agents/dashboard/packages/local-runtime"), [resolve(root, ".agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs")]);
12
+ process.stdout.write("SQLite dashboard artifacts rebuilt.\n");
@@ -0,0 +1,83 @@
1
+ import { createRequire } from "node:module";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, resolve } from "node:path";
4
+
5
+ const root = resolve(import.meta.dirname, "../../../../..");
6
+ const packageRoot = resolve(root, ".agents/dashboard/packages/local-runtime");
7
+ const require = createRequire(resolve(root, "package.json"));
8
+ const { build } = require("esbuild");
9
+ await mkdir(resolve(packageRoot, "dist"), { recursive: true });
10
+ const buildOptions = {
11
+ bundle: true,
12
+ platform: "node",
13
+ format: "cjs",
14
+ target: "node22",
15
+ // The launcher pays V8's parse/compile cost before `main` can run. This is
16
+ // a distributed runtime artifact, so preserve external source maps while
17
+ // minimizing the executable JavaScript it must evaluate on every click.
18
+ minify: true,
19
+ sourcemap: true,
20
+ alias: {
21
+ "@hono/node-server/serve-static": resolve(root, "node_modules/.pnpm/@hono+node-server@2.0.10_hono@4.12.34/node_modules/@hono/node-server/dist/serve-static.mjs"),
22
+ "@hono/node-server": resolve(root, "node_modules/.pnpm/@hono+node-server@2.0.10_hono@4.12.34/node_modules/@hono/node-server/dist/index.mjs"),
23
+ "hono/cookie": resolve(root, "node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/helper/cookie/index.js"),
24
+ "hono/utils/mime": resolve(root, "node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/utils/mime.js"),
25
+ "hono/ws": resolve(root, "node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/helper/websocket/index.js"),
26
+ "hono": resolve(root, "node_modules/.pnpm/hono@4.12.34/node_modules/hono/dist/index.js"),
27
+ "zod": resolve(root, "node_modules/.pnpm/zod@4.4.3/node_modules/zod"),
28
+ "@zaip-ai/core": resolve(root, "packages/core/src/index.ts"),
29
+ "@zaip-ai/costs": resolve(root, "packages/costs/src/index.ts"),
30
+ "@zaip-ai/decisions": resolve(root, "packages/decisions/src/index.ts"),
31
+ "@zaip-ai/lifecycle-manifests": resolve(root, "packages/lifecycle-manifests/src/index.ts"),
32
+ "@zaip-ai/specs": resolve(root, "packages/specs/src/index.ts"),
33
+ "@zaip-ai/tasks": resolve(root, "packages/tasks/src/index.ts"),
34
+ "@zaip-ai/dashboard-operations/contracts": resolve(root, ".agents/dashboard/modules/operations/src/contracts.ts"),
35
+ "@zaip-ai/dashboard-operations/work-board-model": resolve(root, ".agents/dashboard/modules/operations/src/work-board-model.ts"),
36
+ "@zaip-ai/dashboard-operations/server": resolve(root, ".agents/dashboard/modules/operations/src/server/index.ts"),
37
+ "@zaip-ai/dashboard-traceability/server": resolve(root, ".agents/dashboard/modules/traceability/src/server/index.ts"),
38
+ "@zaip-ai/dashboard-cost-monitor/server": resolve(root, ".agents/dashboard/modules/cost-monitor/src/server/index.ts"),
39
+ },
40
+ };
41
+ const buildResults = await Promise.all([
42
+ // The local rebuild and validation helpers import CommonJS directly.
43
+ build({
44
+ ...buildOptions,
45
+ entryPoints: [resolve(packageRoot, "src/server.ts")],
46
+ outfile: resolve(packageRoot, "dist/server.cjs"),
47
+ metafile: process.env.ZAIP_RUNTIME_METAFILE === "1",
48
+ }),
49
+ // `server.js` is the portable runtime consumed by the launchers and copied
50
+ // verbatim to server.mjs/release. Keep that distributed ESM artifact in the
51
+ // same build invocation as the CJS helper so it cannot retain an older Run
52
+ // transport parser than the live read model.
53
+ build({
54
+ ...buildOptions,
55
+ format: "esm",
56
+ banner: {
57
+ js: 'import { createRequire as __zaipCreateRequire } from "node:module"; const require = __zaipCreateRequire(import.meta.url);',
58
+ },
59
+ entryPoints: [resolve(packageRoot, "src/server.ts")],
60
+ outfile: resolve(packageRoot, "dist/server.js"),
61
+ }),
62
+ // Keep the standalone read-model artifact coherent with the bundled server.
63
+ // Tooling and diagnostics may import it directly during a live refresh.
64
+ build({
65
+ ...buildOptions,
66
+ entryPoints: [resolve(packageRoot, "src/sqlite-read-model.ts")],
67
+ outfile: resolve(packageRoot, "dist/sqlite-read-model.cjs"),
68
+ }),
69
+ ]);
70
+ const distributedServer = resolve(packageRoot, "dist/server.js");
71
+ await writeFile(
72
+ distributedServer,
73
+ (await readFile(distributedServer, "utf8")).replace(/[ \t]+$/gm, ""),
74
+ "utf8",
75
+ );
76
+ if (process.env.ZAIP_RUNTIME_METAFILE === "1") {
77
+ await writeFile(
78
+ resolve(packageRoot, "dist/server.cjs.metafile.json"),
79
+ JSON.stringify(buildResults[0].metafile, null, 2),
80
+ "utf8",
81
+ );
82
+ }
83
+ process.stdout.write("SQLite dashboard runtime rebuilt.\n");
@@ -0,0 +1,28 @@
1
+ import { rm } from "node:fs/promises";
2
+ import { relative, resolve } from "node:path";
3
+
4
+ const workspaceRoot = resolve(import.meta.dirname, "../../../../..");
5
+ process.env.ZAIP_UI_ROOT ??= resolve(workspaceRoot, ".agents/dashboard/apps/frontend/dist");
6
+ const { default: runtime } = await import("../dist/server.cjs");
7
+ const { rebuildSqliteReadModel, validateSqliteReadModelSchema } = runtime;
8
+ const cleanupPath = process.env.ZAIP_SQLITE_REFRESH_CLEANUP === "1" ? process.env.ZAIP_SQLITE_DB_PATH : null;
9
+ try {
10
+ const result = await rebuildSqliteReadModel(workspaceRoot);
11
+ const schema = validateSqliteReadModelSchema(result.path);
12
+ process.stdout.write(`${JSON.stringify({ storage_mode: "sqlite_read_model", ...result, schema })}\n`);
13
+ } finally {
14
+ // The background seed refresher owns only its generated refresh-*.sqlite
15
+ // path. Cleanup belongs to this worker so a launcher exit cannot leak it.
16
+ if (typeof cleanupPath === "string") {
17
+ const refreshDirectory = resolve(workspaceRoot, ".local", "dashboard-sqlite");
18
+ const candidate = resolve(cleanupPath);
19
+ const name = relative(refreshDirectory, candidate);
20
+ const safeGeneratedRefresh =
21
+ name !== "" &&
22
+ !name.startsWith("..") &&
23
+ !name.includes("/") &&
24
+ !name.includes("\\") &&
25
+ /^refresh-\d+-[0-9a-f]+\.sqlite$/i.test(name);
26
+ if (safeGeneratedRefresh) await rm(candidate, { force: true }).catch(() => {});
27
+ }
28
+ }
@@ -0,0 +1,262 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, mkdir, readFile, rm, utimes, writeFile } from "node:fs/promises";
3
+ import { join, resolve } from "node:path";
4
+ import { createRequire } from "node:module";
5
+ import { DatabaseSync } from "node:sqlite";
6
+
7
+ const root = resolve(import.meta.dirname, "../../../../..");
8
+ const sqliteTestTempRoot = resolve(root, ".tmp", "sqlite-read-model-tests");
9
+ async function createSqliteTestDirectory(prefix) {
10
+ await mkdir(sqliteTestTempRoot, { recursive: true });
11
+ return mkdtemp(join(sqliteTestTempRoot, prefix));
12
+ }
13
+ const require = createRequire(resolve(root, "package.json"));
14
+ const { build } = require("esbuild");
15
+
16
+ /** Bundle only the read-model entry: importing server.cjs constructs the default
17
+ * app and opens the canonical DB, which makes a second rebuild EBUSY on Windows. */
18
+ async function loadReadModelRuntime() {
19
+ const directory = await createSqliteTestDirectory("bundle-");
20
+ const outfile = join(directory, "sqlite-read-model.cjs");
21
+ await build({
22
+ entryPoints: [resolve(root, ".agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts")],
23
+ outfile,
24
+ bundle: true,
25
+ platform: "node",
26
+ format: "cjs",
27
+ target: "node22",
28
+ alias: {
29
+ "@zaip-ai/core": resolve(root, "packages/core/src/index.ts"),
30
+ "@zaip-ai/costs": resolve(root, "packages/costs/src/index.ts"),
31
+ },
32
+ });
33
+ return { runtime: require(outfile), directory };
34
+ }
35
+
36
+ async function loadCostAdapterRuntime() {
37
+ const directory = await createSqliteTestDirectory("adapter-");
38
+ const outfile = join(directory, "sqlite-cost-adapters.cjs");
39
+ await build({
40
+ entryPoints: [resolve(root, ".agents/dashboard/apps/frontend/src/sqlite-cost-adapters.ts")],
41
+ outfile,
42
+ bundle: true,
43
+ platform: "node",
44
+ format: "cjs",
45
+ target: "node22",
46
+ });
47
+ return { runtime: require(outfile), directory };
48
+ }
49
+
50
+ async function fixture() {
51
+ const directory = await createSqliteTestDirectory("parity-");
52
+ await mkdir(join(directory, ".agents/records/lifecycle/views"), { recursive: true });
53
+ await mkdir(join(directory, ".agents/records/lifecycle/chunks"), { recursive: true });
54
+ await mkdir(join(directory, ".agents/config"), { recursive: true });
55
+ await writeFile(join(directory, ".agents/config/project.yaml"), "zaip:\n enabled: true\n");
56
+ await mkdir(join(directory, ".agents/config/agents"), { recursive: true });
57
+ await writeFile(join(directory, ".agents/config/agents/catalog.yaml"), "agents:\n - id: agent-a\n codex_name: agent-a\n persona: { nome: ana, cargo: quality_engineer }\n role: reviewer\n");
58
+ await mkdir(join(directory, ".agents/records/telemetry/2026/08/writers/w/chunks"), { recursive: true });
59
+ const summary = (id, hash, occurred_at, segments) => ({ schema_version: 1, agent_invocation_id: id, summary_hash: hash, root_agent_invocation_id: id, parent_agent_invocation_id: null, invocation_kind: "orchestrator", delegation_depth: 0, execution_id: null, task_id: null, spec_id: null, prd_id: null, change_id: null, run_id: id, occurred_at, status: "completed", coverage: "complete", source_event_count: 1, llm_call_count: 2, historical_cost: { estimated_usd: 2, estimated_brl: 10 }, quantitative_coverage: { tokens: "complete", duration_ms: "complete" }, quantitative_metrics: { duration_ms: { known_sum: 100 }, tokens_total: { known_sum: 15 }, estimated_usd: { known_sum: 2 }, estimated_brl: { known_sum: 10 } }, usage_segments: segments });
60
+ const mixed = [{ provider: "openai", model: "a", service_tier: null, reasoning_effort: null, coverage: "complete", tokens: { input: 2, cached_input: 1, output: 3, reasoning: 4, total: 10 }, historical_cost: { estimated_usd: 1, estimated_brl: 5 } }, { provider: "other", model: "b", service_tier: null, reasoning_effort: null, coverage: "complete", tokens: { input: 5, cached_input: 0, output: 0, reasoning: 0, total: 5 }, historical_cost: { estimated_usd: 1, estimated_brl: 5 } }];
61
+ const canonical = { ...summary("AINV-edge", "hash-edge", "2026-08-01T01:00:00.000Z", mixed), execution_id: "EXEC-a", task_id: "TASK-a", conversation_id: "CONV-a", zaip_agent: "agent-a", phase: "execution" };
62
+ const augustBefore = { ...summary("AINV-aug-before", "hash-aug-before", "2026-08-05T04:00:00.000Z", mixed), zaip_agent: "agent-a", phase: "execution", quantitative_metrics: { duration_ms: { known_sum: 200 }, tokens_total: { known_sum: 15 }, estimated_usd: { known_sum: 2 }, estimated_brl: { known_sum: 10 } } };
63
+ const unavailable = { ...summary("AINV-unavailable", "hash-unavailable", "2026-08-15T04:00:00.000Z", []), llm_call_count: null, status: "failed", zaip_agent: "agent-b", phase: "review", historical_cost: null, quantitative_coverage: { tokens: "unavailable", duration_ms: "unavailable" }, quantitative_metrics: { duration_ms: { known_sum: null }, tokens_total: { known_sum: null }, estimated_usd: { known_sum: null }, estimated_brl: { known_sum: null } } };
64
+ const augustInside = { ...summary("AINV-aug-inside", "hash-aug-inside", "2026-08-20T04:00:00.000Z", mixed), zaip_agent: "agent-a", phase: "execution", quantitative_metrics: { duration_ms: { known_sum: 300 }, tokens_total: { known_sum: 15 }, estimated_usd: { known_sum: 2 }, estimated_brl: { known_sum: 10 } } };
65
+ const lifecycle = [
66
+ { operation: "upsert", entity: { kind: "task", id: "TASK-a", updated_at: "2026-07-31T22:00:00.000Z", data: { title: "Causal task", status: "active", risk: "critical", created_at: "2026-07-31T22:00:00.000Z" } } },
67
+ { operation: "upsert", entity: { kind: "task", id: "TASK-zero", updated_at: "2026-08-10T22:00:00.000Z", data: { title: "Task without invocation", status: "ready", risk: "lite", created_at: "2026-08-10T22:00:00.000Z" } } },
68
+ { operation: "upsert", entity: { kind: "spec", id: "SPEC-zero", updated_at: "2026-08-10T22:00:00.000Z", data: { title: "SPEC without invocation", status: "ready", risk: "lite", created_at: "2026-08-10T22:00:00.000Z" } } },
69
+ { operation: "upsert", entity: { kind: "prd", id: "PRD-zero", updated_at: "2026-08-10T22:00:00.000Z", data: { title: "PRD without invocation", status: "ready", risk: "lite", created_at: "2026-08-10T22:00:00.000Z" } } },
70
+ { operation: "upsert", entity: { kind: "execution", id: "EXEC-a", updated_at: "2026-07-31T22:00:00.000Z", data: { status: "completed", created_at: "2026-07-31T22:00:00.000Z" } } },
71
+ { operation: "upsert", entity: { kind: "conversation", id: "CONV-a", updated_at: "2026-07-31T22:00:00.000Z", data: { status: "active", created_at: "2026-07-31T22:00:00.000Z" } } },
72
+ { operation: "upsert", entity: { kind: "decision", id: "DEC-edge", updated_at: "2026-07-31T22:00:00.000Z", data: { status: "accepted", risk: "standard", created_at: "2026-07-31T22:00:00.000Z" } } },
73
+ { operation: "upsert", entity: { kind: "change", id: "CHG-edge", updated_at: "2026-07-31T22:00:00.000Z", data: { status: "active", risk: "critical", created_at: "2026-07-31T22:00:00.000Z" } } },
74
+ ];
75
+ await writeFile(join(directory, ".agents/records/lifecycle/chunks/entities.jsonl"), `${lifecycle.map(JSON.stringify).join("\n")}\n`);
76
+ await writeFile(join(directory, ".agents/records/telemetry/2026/08/writers/w/chunks/c.jsonl"), `${JSON.stringify(canonical)}\n${JSON.stringify(canonical)}\n${JSON.stringify(augustBefore)}\n${JSON.stringify(unavailable)}\n${JSON.stringify(augustInside)}\n`);
77
+ await writeFile(join(directory, ".agents/records/telemetry/2026/08/writers/w/manifest.json"), JSON.stringify({ chunks: [{ path: ".agents/records/telemetry/2026/08/writers/w/chunks/c.jsonl" }] }));
78
+ const canonicalRun = ({ runId, invocationId, occurredAt, duration, status = "completed", agent = "agent-a", phase = "execution", executionId = null, taskId = null, conversationId, segments = [] }) => {
79
+ const started = {
80
+ schema_version: 2, event_id: `${runId}:000001`, run_id: runId, sequence: 1, occurred_at: occurredAt, type: "run.started",
81
+ attribution_status: "attributed", phase, run_role: "orchestrator", run_purpose: phase === "execution" ? "execution" : "orchestration",
82
+ requires_finalizer: false, execution_kind: phase === "execution" ? "delivery" : "interaction", execution_eligibility: [phase === "execution" ? "delivery" : "interaction"],
83
+ entrypoint: taskId === null ? "conversation" : "task", work_type: "new", storage_mode: "tracked_sanitized", client: "codex",
84
+ agent, agent_name: agent, provider: segments.length > 0 ? segments[0].provider : null, model: segments.length > 0 ? segments[0].model : "unknown", reasoning_effort: null,
85
+ client_thread_id: `thread-${runId}`, client_turn_id: `turn-${runId}`, conversation_id: conversationId, execution_id: executionId,
86
+ task_id: taskId, spec_id: null, prd_id: null, change_id: null, parent_run_id: null, continuation_of_run_id: null, retry_of_run_id: null,
87
+ ...(invocationId === null ? {} : { agent_invocation_id: invocationId, root_agent_invocation_id: invocationId, parent_agent_invocation_id: null, invocation_kind: "orchestrator", delegation_depth: 0 }),
88
+ };
89
+ const usage = segments.map((segment, index) => ({
90
+ schema_version: 2, event_id: `${runId}:${String(index + 2).padStart(6, "0")}`, run_id: runId, sequence: index + 2, occurred_at: occurredAt,
91
+ type: "usage.recorded", phase, activity_kind: "model_usage", classification_source: "explicit",
92
+ tokens: { ...segment.tokens, source: "provider_reported" }, cost: { usd: segment.cost.usd, brl: segment.cost.brl, fx_rate: 5 },
93
+ provider: segment.provider, model: segment.model, source_segment_key: `${runId}:${index}`, model_call_id: `MCALL-${runId}-${index}`,
94
+ runtime: { reasoning_effort: null, service_tier: null }, supersedes_event_id: null,
95
+ duration_ms: null, duration_provenance: null,
96
+ }));
97
+ const finished = { schema_version: 2, event_id: `${runId}:${String(usage.length + 2).padStart(6, "0")}`, run_id: runId, sequence: usage.length + 2, occurred_at: occurredAt, type: "run.finished", phase, status, duration_ms: duration, duration_provenance: duration === null ? "unavailable" : "observed" };
98
+ return [...[started], ...usage, finished].map(JSON.stringify).join("\n") + "\n";
99
+ };
100
+ await mkdir(join(directory, ".agents/records/runs/2026/07"), { recursive: true });
101
+ await mkdir(join(directory, ".agents/records/runs/2026/08"), { recursive: true });
102
+ const canonicalSegments = [
103
+ { provider: "openai", model: "a", tokens: { input: 2, cached_input: 1, output: 3, reasoning: 4, total: 10 }, cost: { usd: 1, brl: 5 } },
104
+ { provider: "other", model: "b", tokens: { input: 5, cached_input: 0, output: 0, reasoning: 0, total: 5 }, cost: { usd: 1, brl: 5 } },
105
+ ];
106
+ const runs = [
107
+ ["2026/07/RUN-edge.jsonl", { runId: "RUN-edge", invocationId: "AINV-edge", occurredAt: "2026-08-01T01:00:00.000Z", duration: 100, executionId: "EXEC-a", taskId: "TASK-a", conversationId: "CONV-a", segments: canonicalSegments }],
108
+ ["2026/08/RUN-aug-before.jsonl", { runId: "RUN-aug-before", invocationId: "AINV-aug-before", occurredAt: "2026-08-05T04:00:00.000Z", duration: 200, executionId: "EXEC-before", conversationId: "CONV-before", segments: canonicalSegments }],
109
+ ["2026/08/RUN-unavailable.jsonl", { runId: "RUN-unavailable", invocationId: "AINV-unavailable", occurredAt: "2026-08-15T04:00:00.000Z", duration: null, status: "failed", agent: "agent-b", phase: "conversation", conversationId: "CONV-unavailable", segments: [] }],
110
+ ["2026/08/RUN-aug-inside.jsonl", { runId: "RUN-aug-inside", invocationId: "AINV-aug-inside", occurredAt: "2026-08-20T04:00:00.000Z", duration: 300, executionId: "EXEC-inside", conversationId: "CONV-inside", segments: canonicalSegments }],
111
+ ["2026/08/RUN-unassisted.jsonl", { runId: "RUN-unassisted", invocationId: null, occurredAt: "2026-08-20T05:00:00.000Z", duration: null, agent: "root", phase: "conversation", conversationId: "CONV-unassisted", segments: [] }],
112
+ ];
113
+ for (const [path, value] of runs) await writeFile(join(directory, ".agents/records/runs", path), canonicalRun(value));
114
+ return directory;
115
+ }
116
+
117
+ async function verify(runtime, rootPath, intervals) {
118
+ await runtime.rebuildSqliteReadModel(rootPath);
119
+ const filesystem = new runtime.SqliteReadModelFileSystem(rootPath);
120
+ try {
121
+ for (const [from, to] of intervals) {
122
+ const aggregate = filesystem.firstFoldAggregate({ from, to });
123
+ if (rootPath.includes("zaip-dashboard-sqlite-parity-") && from === null && to === null)
124
+ assert.deepEqual(aggregate, { days: 4, total_run_count: 5, agent_invocation_count: 3, llm_call_count: 6, duration_ms: 600, total_tokens: 45, cost_brl: 30, execution_day_count: 3 });
125
+ }
126
+ if (rootPath.includes("zaip-dashboard-sqlite-parity-")) {
127
+ const database = new DatabaseSync(process.env.ZAIP_SQLITE_DB_PATH, { readOnly: true });
128
+ try {
129
+ const schema = runtime.validateSqliteReadModelSchema(process.env.ZAIP_SQLITE_DB_PATH);
130
+ assert.deepEqual(schema, { schemaVersion: "59", tableCount: 5, viewCount: 107, indexCount: 15 });
131
+ const objects = new Map(database.prepare("SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view')").all().map((row) => [row.name, row.type]));
132
+ const names = new Set(objects.keys());
133
+ for (const name of ["zaip_aios_activities", "agent_runs", "root_runs", "sub_runs", "overview", "overview_daily", "overview_monthly", "overview_annual", "task_summary", "task_summary_daily", "spec_summary", "spec_summary_daily", "prd_summary", "prd_summary_daily", "task_status_daily", "task_risk_daily", "tasks", "specs", "prds", "executions", "conversations", "decisions", "changes", "work_items", "cost_monitor_group_daily", "cost_monitor_daily", "cost_monitor_agent_invocations", "operations_work_list", "operations_agent_invocations", "first_fold_overview", "first_fold_task", "first_fold_spec", "first_fold_prd"]) assert.ok(name === "zaip_aios_activities" ? names.has(name) : names.has(`zaip_vw_${name}`), `missing ${name}`);
134
+ assert.equal(names.has("zaip_vw_sub_runs"), true);
135
+ for (const name of ["canonical_artifacts", "invocations", "invocation_usage", "work_items", "daily_aggregate_cache", "daily_aggregates", "overview", "overview_daily", "overview_monthly", "overview_annual", "operations_overview", "cost_monitor_overview", "cost_monitor_group_daily_cache", "cost_monitor_group_daily", "task_summary", "spec_summary", "prd_summary"]) assert.equal(objects.get(`zaip_vw_${name}`), "view", `${name} must be a prefixed view`);
136
+ assert.equal([...objects.entries()].filter(([name, type]) => type === "view" && !name.startsWith("zaip_vw_")).length, 0, "all persisted views must use zaip_vw_");
137
+ assert.equal([...objects.entries()].filter(([name, type]) => type === "view" && name.startsWith("zaip_vw_vw_")).length, 0, "view prefix must not be duplicated");
138
+ assert.deepEqual([...objects.entries()].filter(([, type]) => type === "table").map(([name]) => name).sort(), ["cost_invocation_dimension_facts", "zaip_aios_activities", "zaip_dim_llm_model", "zaip_dim_provider", "zaip_dim_zaip_agent"]);
139
+ const fact = database.prepare("SELECT activity_source_kind, agent_run_role, llm_call_count, provider, model, zaip_agent_persona, zaip_agent_job FROM zaip_aios_activities WHERE agent_run_id = ?").get("AINV-edge");
140
+ assert.deepEqual({ ...fact }, { activity_source_kind: "agent_run", agent_run_role: "root", llm_call_count: 2, provider: "openai", model: "mixed", zaip_agent_persona: "ana", zaip_agent_job: "quality_engineer" });
141
+ assert.equal(database.prepare("SELECT COUNT(*) AS count FROM zaip_aios_activities WHERE payload_type IS NULL").get().count, 3);
142
+ assert.equal(database.prepare("SELECT COUNT(*) AS count FROM zaip_aios_activities WHERE payload_type IS NULL AND total_tokens IS NULL").get().count, 0);
143
+ assert.equal(database.prepare("SELECT value FROM zaip_vw_read_model_metadata WHERE key='canonical_run_count'").get().value, "5");
144
+ assert.equal(database.prepare("SELECT value FROM zaip_vw_read_model_metadata WHERE key='unassisted_activity_count'").get().value, "0");
145
+ assert.equal(database.prepare("SELECT value FROM zaip_vw_read_model_metadata WHERE key='excluded_unknown_token_run_count'").get().value, "2");
146
+ assert.equal(database.prepare("SELECT COUNT(*) AS count FROM zaip_vw_files WHERE path LIKE '.agents/records/lifecycle/%'").get().count, 0);
147
+ assert.equal(database.prepare("SELECT llm_call_count FROM zaip_vw_daily_aggregates WHERE day = ?").get("2026-07-31").llm_call_count, 2);
148
+ assert.equal(database.prepare("SELECT llm_call_count FROM zaip_vw_overview WHERE period_kind = 'month' AND period_key = '2026-08'").get().llm_call_count, 4);
149
+ const dictionary = await readFile(join(root, ".agents/dashboard/DATA-DICTIONARY.md"), "utf8");
150
+ const headings = [...dictionary.matchAll(/^### `([^`]+)`\r?$/gm)];
151
+ const sections = new Map(headings.map((heading, index) => [heading[1], dictionary.slice(heading.index, index + 1 < headings.length ? headings[index + 1].index : dictionary.length)]));
152
+ for (const { name, type } of database.prepare("SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'").all()) {
153
+ const section = sections.get(name.startsWith("zaip_vw_") ? name.slice("zaip_vw_".length) : name);
154
+ assert.ok(section, `DATA-DICTIONARY.md must document ${type} ${name}`);
155
+ }
156
+ } finally { database.close(); }
157
+ assert.equal(filesystem.invocationTotals({ from: "2026-07-31T00:00:00Z", to: "2026-07-31T23:59:59Z" }).invocation_count, 1);
158
+ assert.equal(filesystem.invocationCostRows({ from: "2026-07-31", to: "2026-07-31", providers: ["openai"] }).length, 1);
159
+ const row = filesystem.invocationCostRows({ from: "2026-07-31", to: "2026-07-31" })[0];
160
+ assert.equal(row.provider, "mixed"); assert.equal(row.model, "mixed");
161
+ assert.equal(row.input_tokens, 7); assert.equal(row.cached_input_tokens, 1);
162
+ assert.equal(row.output_tokens, 3); assert.equal(row.reasoning_tokens, 4);
163
+ assert.equal(row.total_tokens, 15); assert.equal(row.cost_brl, 10);
164
+ assert.equal(filesystem.invocationCostRows({ from: "2026-08-15", to: "2026-08-15" }).find((value) => value.agent_invocation_id === "AINV-unavailable"), undefined);
165
+ const augustMonthly = filesystem.viewPage("cost_monitor_monthly", { from: "2026-08-11", to: "2026-08-31" });
166
+ assert.equal(augustMonthly.total_count, 1); assert.equal(augustMonthly.rows[0].period_key, "2026-08"); assert.equal(augustMonthly.rows[0].invocation_count, 1); assert.equal(augustMonthly.rows[0].total_duration, 300); assert.equal(augustMonthly.rows[0].total_tokens, 15); assert.equal(augustMonthly.rows[0].total_cost_brl, 10);
167
+ const augustAnnual = filesystem.viewPage("cost_monitor_annual", { from: "2026-08-11", to: "2026-08-31" });
168
+ assert.equal(augustAnnual.total_count, 1); assert.equal(augustAnnual.rows[0].period_key, "2026"); assert.equal(augustAnnual.rows[0].invocation_count, 1); assert.equal(augustAnnual.rows[0].total_duration, 300); assert.equal(augustAnnual.rows[0].total_tokens, 15); assert.equal(augustAnnual.rows[0].total_cost_brl, 10);
169
+ // This fixture spans the Sao Paulo months 2026-07 and 2026-08.
170
+ const monthly2026 = filesystem.viewPage("cost_monitor_monthly", { limit: 50, offset: 0 }).rows.filter((row) => String(row.key ?? row.period_key).startsWith("2026-"));
171
+ const annual2026 = filesystem.viewPage("cost_monitor_annual", { limit: 50, offset: 0 });
172
+ assert.equal(monthly2026.length >= 2, true);
173
+ assert.equal(annual2026.total_count, 1);
174
+ assert.equal(annual2026.rows[0].key ?? annual2026.rows[0].period_key, "2026");
175
+ for (const metric of ["prd_count", "spec_count", "task_count", "validation_count", "evidence_count", "total_run_count", "total_duration", "total_tokens", "total_cost_usd", "total_cost_brl"]) {
176
+ const sum = monthly2026.reduce((total, row) => total + Number(row[metric] ?? 0), 0);
177
+ assert.equal(Number(annual2026.rows[0][metric] ?? 0), sum, `annual ${metric} must equal the monthly sum`);
178
+ }
179
+ const completedAugust = filesystem.viewPage("cost_monitor_monthly", { from: "2026-08-11", to: "2026-08-31", status: "completed" });
180
+ assert.equal(completedAugust.total_count, 1); assert.equal(completedAugust.rows[0].invocation_count, 1); assert.equal(completedAugust.rows[0].total_duration, 300);
181
+ const failedAugust = filesystem.viewPage("cost_monitor_monthly", { from: "2026-08-11", to: "2026-08-31", status: "failed", agent: "agent-b", phase: "conversation" });
182
+ assert.equal(failedAugust.total_count, 1); assert.equal(failedAugust.rows[0].invocation_count, 0); assert.equal(failedAugust.rows[0].total_run_count, 0); assert.equal(failedAugust.rows[0].total_duration, null);
183
+ const filteredAnnual = filesystem.viewPage("cost_monitor_annual", { from: "2026-08-11", to: "2026-08-31", query: "AINV-aug-inside", provider: "openai", model: "a", agent: "agent-a", phase: "execution", status: "completed" });
184
+ assert.equal(filteredAnnual.total_count, 1); assert.equal(filteredAnnual.rows[0].invocation_count, 1); assert.equal(filteredAnnual.rows[0].total_duration, 300);
185
+ const filteredCalls = filesystem.viewPage("cost_monitor_agent_invocations", { from: "2026-07-31", to: "2026-07-31", query: "edge", agent: "agent-a", phase: "execution", status: "completed" });
186
+ assert.equal(filteredCalls.total_count, 1); assert.equal(filteredCalls.rows[0].agent_invocation_id, "AINV-edge");
187
+ assert.equal(filesystem.viewPage("cost_monitor_agent_invocations", { from: "2026-07-31", to: "2026-07-31", status: "failed" }).total_count, 0);
188
+ const operationCalls = filesystem.viewPage("operations_agent_invocations", { query: "edge", status: "completed", agent: "agent-a", phase: "execution" });
189
+ assert.equal(operationCalls.total_count, 1);
190
+ const operationExecutions = filesystem.viewPage("operations_executions", { query: "EXEC-a", status: "completed" });
191
+ assert.equal(operationExecutions.total_count, 1);
192
+ assert.equal(filesystem.viewPage("operations_changes", { query: "edge", status: "active" }).total_count, 0);
193
+ assert.equal(filesystem.viewPage("operations_decisions", { query: "edge", status: "accepted" }).total_count, 0);
194
+ assert.equal(filesystem.viewPage("cost_monitor_monthly", { from: "2026-08-11", to: "2026-08-31", query: "AINV-unavailable" }).total_count, 0);
195
+ for (const groupedView of ["cost_monitor_providers", "cost_monitor_models"]) {
196
+ const grouped = filesystem.viewPage(groupedView, { from: "2026-07-31", to: "2026-07-31", provider: "openai", model: "a", agent: "agent-a", phase: "execution", status: "completed", limit: 50 });
197
+ const mixed = grouped.rows.find((row) => row.key === "mixed");
198
+ assert.ok(mixed); assert.equal(mixed.total_duration, 100);
199
+ }
200
+ const agentGroups = filesystem.viewPage("cost_monitor_zaip_agents", { from: "2026-07-31", to: "2026-07-31", provider: "openai", model: "a", phase: "execution", status: "completed" });
201
+ assert.equal(agentGroups.total_count, 1); assert.equal(agentGroups.rows[0].key, "agent-a"); assert.equal(agentGroups.rows[0].invocation_count, 1);
202
+ const overview = filesystem.overviewPage("day", 0, 50);
203
+ assert.equal(overview.total, 4);
204
+ assert.equal(overview.rows.reduce((count, value) => count + Number(value.invocation_count), 0), 3);
205
+ for (const view of Object.keys(runtime.sqliteViewMetadata)) assert.ok(filesystem.viewPage(view, { limit: 1 }).rows.length <= 1, `view page ${view}`);
206
+ assert.equal(filesystem.viewPage("first_fold_top_tasks", {}).limit, 5);
207
+ assert.equal(filesystem.viewPage("cost_monitor_agent_invocations", {}).limit, 100);
208
+ const planDatabase = new DatabaseSync(process.env.ZAIP_SQLITE_DB_PATH, { readOnly: true });
209
+ try {
210
+ const plan = planDatabase.prepare("EXPLAIN QUERY PLAN SELECT agent_run_id FROM zaip_aios_activities WHERE activity_source_kind=? AND occurred_day_sp>=? AND occurred_day_sp<=?").all("agent_run", "2026-07-31", "2026-08-31");
211
+ assert.match(plan.map((value) => value.detail).join(" "), /zaip_activities_agent_run/);
212
+ } finally { planDatabase.close(); }
213
+ }
214
+ } finally { try { filesystem.close(); } catch { /* fixture may already be closed */ } }
215
+ }
216
+
217
+ const canonicalDb = process.env.ZAIP_SQLITE_DB_PATH;
218
+ const runtimeBundle = await loadReadModelRuntime();
219
+ const adapterBundle = await loadCostAdapterRuntime();
220
+ const canonicalTestDirectory = await createSqliteTestDirectory("canonical-");
221
+ try {
222
+ assert.equal(adapterBundle.runtime.costGroupDuration({ cost_monitor_total_duration: null }), null);
223
+ assert.equal(adapterBundle.runtime.costGroupDuration({ total_duration: null, cost_monitor_total_duration: 999 }), null);
224
+ assert.deepEqual(adapterBundle.runtime.legacyKnownMetric(null), { known_sum: 0, unknown: 1, complete: false, coverage_ratio: 0 });
225
+ assert.deepEqual(adapterBundle.runtime.legacyKnownMetric(0), { known_sum: 0, unknown: 0, complete: true, coverage_ratio: 1 });
226
+ process.env.ZAIP_SQLITE_DB_PATH = join(canonicalTestDirectory, "read-model.sqlite");
227
+ await verify(runtimeBundle.runtime, root, [[null, null]]);
228
+ const liveDatabase = new DatabaseSync(process.env.ZAIP_SQLITE_DB_PATH, { readOnly: true });
229
+ try {
230
+ const daily = liveDatabase
231
+ .prepare("SELECT day, total_duration FROM zaip_vw_daily_aggregates WHERE day IN ('2026-07-22', '2026-07-23') ORDER BY day")
232
+ .all();
233
+ const byDay = new Map(daily.map((row) => [row.day, row.total_duration]));
234
+ assert.ok((byDay.get("2026-07-22") ?? 0) >= 100 * 60_000, "2026-07-22 must retain roughly 103 measurable minutes");
235
+ assert.ok((byDay.get("2026-07-22") ?? 0) <= 106 * 60_000, "2026-07-22 must not exceed its reconciled interval union");
236
+ assert.ok((byDay.get("2026-07-23") ?? 0) >= 61 * 60_000, "2026-07-23 must retain at least 61 measurable minutes");
237
+ assert.equal(liveDatabase.prepare("SELECT COUNT(*) AS count FROM zaip_vw_daily_aggregates WHERE total_duration > 86400000").get().count, 0, "daily duration must not exceed 24 hours");
238
+ process.stdout.write(`SQLite live daily durations: ${JSON.stringify(daily)}\n`);
239
+ } finally { liveDatabase.close(); }
240
+ const temp = await fixture();
241
+ try {
242
+ process.env.ZAIP_SQLITE_DB_PATH = join(temp, ".local/dashboard-sqlite/read-model.sqlite");
243
+ const nested = join(temp, ".agents/records/tasks/nested/task.md");
244
+ await mkdir(resolve(nested, ".."), { recursive: true });
245
+ await writeFile(nested, "# before\n");
246
+ await runtimeBundle.runtime.rebuildSqliteReadModel(temp);
247
+ await writeFile(nested, "# after\n");
248
+ const changedAt = new Date(Date.now() + 2_000);
249
+ await utimes(nested, changedAt, changedAt);
250
+ await runtimeBundle.runtime.rebuildSqliteReadModel(temp);
251
+ const changed = new runtimeBundle.runtime.SqliteReadModelFileSystem(temp);
252
+ try { assert.match(await changed.readText(".agents/records/tasks/nested/task.md"), /after/); } finally { changed.close(); }
253
+ await verify(runtimeBundle.runtime, temp, [[null, null], ["2026-08-15", "2026-08-15"], ["2026-08-16", "2026-08-16"]]);
254
+ } finally { await rm(temp, { recursive: true, force: true }); }
255
+ process.stdout.write("SQLite daily aggregate parity passed: canonical all-time/ranges plus known-zero and all-unknown/null fixture.\n");
256
+ } finally {
257
+ await rm(runtimeBundle.directory, { recursive: true, force: true });
258
+ await rm(adapterBundle.directory, { recursive: true, force: true });
259
+ await rm(canonicalTestDirectory, { recursive: true, force: true });
260
+ if (canonicalDb === undefined) delete process.env.ZAIP_SQLITE_DB_PATH;
261
+ else process.env.ZAIP_SQLITE_DB_PATH = canonicalDb;
262
+ }
@@ -0,0 +1,41 @@
1
+ import assert from "node:assert/strict";
2
+ import { execFileSync } from "node:child_process";
3
+ import { readFile } from "node:fs/promises";
4
+ import { resolve } from "node:path";
5
+
6
+ const workspaceRoot = resolve(import.meta.dirname, "../../../../..");
7
+ const launchers = [
8
+ ".agents/dashboard/zaip-dashboard-linux.sh",
9
+ ".agents/dashboard/zaip-dashboard-mac.command",
10
+ ];
11
+
12
+ const stagedModes = new Map(
13
+ execFileSync("git", ["ls-files", "--stage", "--", ...launchers], {
14
+ cwd: workspaceRoot,
15
+ encoding: "utf8",
16
+ })
17
+ .trim()
18
+ .split("\n")
19
+ .filter(Boolean)
20
+ .map((line) => {
21
+ const [mode, , , path] = line.split(/\s+/, 4);
22
+ return [path, mode];
23
+ }),
24
+ );
25
+
26
+ for (const launcher of launchers) {
27
+ const source = await readFile(resolve(workspaceRoot, launcher), "utf8");
28
+ assert.ok(source.startsWith("#!/usr/bin/env sh"), `${launcher} must be a POSIX shell launcher`);
29
+ assert.equal(stagedModes.get(launcher), "100755", `${launcher} must be versioned as executable`);
30
+ }
31
+
32
+ const linuxLauncher = await readFile(resolve(workspaceRoot, launchers[0]), "utf8");
33
+ assert.match(linuxLauncher, /command -v node/, "Linux launcher must resolve Node from PATH");
34
+ assert.match(linuxLauncher, /ZAIP_NODE/, "Linux launcher must allow an explicit Node executable");
35
+ assert.match(linuxLauncher, /Node\.js 22 ou superior/, "Linux launcher must report an actionable Node version failure");
36
+ assert.match(linuxLauncher, /node:sqlite/, "Linux launcher must verify node:sqlite");
37
+ assert.match(linuxLauncher, /exec "\$node_bin" "\$runtime" "\$@"/, "Linux launcher must preserve arguments and runtime exit code");
38
+
39
+ const macLauncher = await readFile(resolve(workspaceRoot, launchers[1]), "utf8");
40
+ assert.match(macLauncher, /exec .*zaip-dashboard-linux\.sh.*"\$@"/, "macOS launcher must delegate and preserve arguments/exit code");
41
+ process.stdout.write("Unix dashboard launcher contract passed.\n");
@@ -0,0 +1,105 @@
1
+ import assert from "node:assert/strict";
2
+ import { DatabaseSync } from "node:sqlite";
3
+ import { resolve } from "node:path";
4
+
5
+ const workspaceRoot = resolve(import.meta.dirname, "../../../../..");
6
+ const databasePath = process.env.ZAIP_SQLITE_DB_PATH ?? resolve(workspaceRoot, ".local/dashboard-sqlite/read-model.sqlite");
7
+ const runtime = await import("../dist/server.cjs");
8
+ const schema = runtime.validateSqliteReadModelSchema(databasePath);
9
+ const database = new DatabaseSync(databasePath, { readOnly: true });
10
+
11
+ try {
12
+ const metrics = database.prepare(`
13
+ SELECT
14
+ COUNT(*) AS activity_count,
15
+ COUNT(DISTINCT run_id) AS distinct_run_count,
16
+ SUM(total_tokens IS NOT NULL) AS token_known_count,
17
+ SUM(total_tokens > 0) AS positive_token_count,
18
+ SUM(total_tokens = 0) AS zero_token_count,
19
+ SUM(total_tokens IS NULL) AS unknown_token_count,
20
+ SUM(total_tokens > 0 AND duration_ms IS NULL) AS positive_token_unknown_duration_count,
21
+ SUM(total_tokens > 0 AND duration_ms IS NULL AND duration_provenance IS NOT NULL) AS positive_token_unknown_duration_with_provenance_count,
22
+ SUM(total_tokens IS NOT NULL AND (cost_usd IS NULL OR cost_brl IS NULL)) AS known_token_missing_cost_count,
23
+ SUM(source_duration_ms IS NOT NULL) AS factual_duration_count,
24
+ SUM(duration_provenance = 'estimated') AS estimated_duration_count,
25
+ SUM(activity_source_kind = 'agent_run') AS agent_run_count,
26
+ SUM(activity_source_kind = 'unassisted_turn') AS unassisted_turn_count
27
+ FROM zaip_aios_activities
28
+ WHERE payload_type IS NULL
29
+ `).get();
30
+ const excluded = database.prepare(`
31
+ SELECT COUNT(*) AS count
32
+ FROM zaip_vw_files
33
+ WHERE path LIKE '.agents/records/lifecycle/%'
34
+ OR path LIKE '.agents/records/telemetry/%'
35
+ `).get();
36
+ const schemaObjects = new Map(database.prepare("SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view')").all().map(({ name, type }) => [name, type]));
37
+ const metadata = Object.fromEntries(database.prepare("SELECT key, value FROM zaip_vw_read_model_metadata").all().map(({ key, value }) => [key, value]));
38
+ const invocationAudit = database.prepare(`
39
+ SELECT
40
+ COUNT(*) AS invocation_count,
41
+ SUM(invocation_kind = 'delegated') AS delegated_invocation_count,
42
+ SUM(duration_ms IS NULL) AS missing_duration_count,
43
+ SUM(total_tokens IS NULL) AS missing_tokens_count,
44
+ SUM(cost_usd IS NULL OR cost_brl IS NULL) AS missing_effective_cost_count,
45
+ SUM(calculated_cost_usd IS NULL) AS missing_calculated_cost_count,
46
+ SUM(ABS(
47
+ COALESCE(input_cost_usd, 0) +
48
+ COALESCE(cached_input_cost_usd, 0) +
49
+ COALESCE(output_cost_usd, 0) +
50
+ COALESCE(reasoning_cost_usd, 0) -
51
+ COALESCE(calculated_cost_usd, 0)
52
+ ) > 0.000002) AS component_mismatch_count
53
+ FROM zaip_vw_operations_agent_invocations
54
+ `).get();
55
+
56
+ assert.equal(metrics.activity_count, metrics.distinct_run_count, "A fato deve ter exatamente uma linha por run_id");
57
+ assert.equal(metrics.unknown_token_count, 0, "A fato não deve conter Runs com total_tokens desconhecido");
58
+ assert.equal(metrics.positive_token_unknown_duration_with_provenance_count, 0, "Duração ausente deve permanecer NULL, sem proveniência inventada");
59
+ assert.equal(metrics.known_token_missing_cost_count, 0, "Token conhecido exige custo conhecido ou estimado");
60
+ assert.equal(excluded.count, 0, "Lifecycle e telemetria agregada não podem entrar no snapshot");
61
+ assert.equal(Number(metadata.canonical_run_count), metrics.activity_count + Number(metadata.excluded_unknown_token_run_count), "A fato mais os Runs excluídos deve coincidir com a origem canônica");
62
+ assert.equal(Number(metadata.agent_run_count), metrics.agent_run_count, "agent_run_count deve coincidir com a fato");
63
+ assert.equal(Number(metadata.unassisted_turn_count), metrics.unassisted_turn_count, "unassisted_turn_count deve coincidir com a fato");
64
+ assert.equal(invocationAudit.invocation_count, metrics.agent_run_count, "A view de invocações deve preservar uma linha por Agent Run");
65
+ assert.equal(invocationAudit.missing_tokens_count, 0, "Toda invocação contabilizada deve expor tokens totais");
66
+ assert.equal(invocationAudit.missing_effective_cost_count, 0, "Toda invocação contabilizada deve expor custo efetivo USD e BRL");
67
+ assert.equal(invocationAudit.missing_calculated_cost_count, 0, "Toda invocação deve permitir reproduzir o custo pelo Guide");
68
+ assert.equal(invocationAudit.component_mismatch_count, 0, "As parcelas de custo devem somar o custo calculado");
69
+
70
+ assert.equal(schemaObjects.get("canonical_artifacts"), undefined, "canonical_artifacts must not be a physical or unprefixed object");
71
+ assert.equal(schemaObjects.get("zaip_vw_canonical_artifacts"), "view", "canonical_artifacts must be a prefixed view");
72
+ assert.deepEqual(
73
+ [...schemaObjects].filter(([, type]) => type === "table").map(([name]) => name).sort(),
74
+ ["cost_invocation_dimension_facts", "zaip_aios_activities", "zaip_dim_llm_model", "zaip_dim_provider", "zaip_dim_zaip_agent"],
75
+ "the isolated candidate must persist exactly the fact, dimensions, and financial dimension fact",
76
+ );
77
+ assert.equal([...schemaObjects].filter(([name, type]) => type === "view" && (!name.startsWith("zaip_vw_") || name.startsWith("zaip_vw_vw_"))).length, 0, "Each view must have exactly one zaip_vw_ prefix");
78
+
79
+ const costEntityViews = [
80
+ ["zaip_vw_cost_monitor_tasks", "task_id"],
81
+ ["zaip_vw_cost_monitor_specs", "spec_id"],
82
+ ["zaip_vw_cost_monitor_prds", "prd_id"],
83
+ ["zaip_vw_cost_monitor_executions", "execution_id"],
84
+ ["zaip_vw_cost_monitor_conversations", "conversation_id"],
85
+ ];
86
+ let invalidCostEntityRowCount = 0;
87
+ for (const [view, id] of costEntityViews) {
88
+ const result = database.prepare(`
89
+ SELECT COUNT(*) AS count
90
+ FROM ${view}
91
+ WHERE ${id} IS NULL
92
+ OR title IS NULL
93
+ OR TRIM(title) = ''
94
+ OR occurred_at IS NULL
95
+ OR occurred_at LIKE '1969-%'
96
+ OR occurred_at LIKE '1970-%'
97
+ `).get();
98
+ invalidCostEntityRowCount += Number(result.count);
99
+ }
100
+ assert.equal(invalidCostEntityRowCount, 0, "Cost entity views require canonical IDs, titles, and non-epoch timestamps");
101
+
102
+ process.stdout.write(`${JSON.stringify({ database_path: databasePath, schema_version: metadata.schema_version, ...schema, ...metrics, ...invocationAudit, excluded_derived_source_count: excluded.count, invalid_cost_entity_row_count: invalidCostEntityRowCount })}\n`);
103
+ } finally {
104
+ database.close();
105
+ }