@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
@@ -1,11 +1,44 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { existsSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
+ import { type SqliteReadModelFileSystem, sqliteReadModelPath } from "./sqlite-read-model.js";
4
5
  import {
5
- type SqliteReadModelFileSystem,
6
- sqliteReadModelPath,
7
- validateSqliteReadModelSchema,
8
- } from "./sqlite-read-model.js";
6
+ readModelSchemaVersion,
7
+ requiredIndexes,
8
+ requiredPersistedTables,
9
+ requiredViews,
10
+ } from "./sqlite-read-model-schema.js";
11
+
12
+ /** The worker validates integrity and schema before emitting this receipt. */
13
+ export function validateSnapshotWorkerReceipt(stdout: string, destination: string): void {
14
+ const result = JSON.parse(stdout) as {
15
+ storage_mode?: unknown;
16
+ path?: unknown;
17
+ schema?: {
18
+ schemaVersion?: unknown;
19
+ tableCount?: unknown;
20
+ viewCount?: unknown;
21
+ indexCount?: unknown;
22
+ };
23
+ } | null;
24
+ const schema = result?.schema;
25
+ if (
26
+ result?.storage_mode !== "sqlite_read_model" ||
27
+ typeof result.path !== "string" ||
28
+ resolve(result.path) !== resolve(destination) ||
29
+ schema?.schemaVersion !== readModelSchemaVersion ||
30
+ schema.tableCount !== requiredPersistedTables.length ||
31
+ typeof schema.viewCount !== "number" ||
32
+ !Number.isSafeInteger(schema.viewCount) ||
33
+ schema.viewCount < requiredViews.length ||
34
+ typeof schema.indexCount !== "number" ||
35
+ !Number.isSafeInteger(schema.indexCount) ||
36
+ schema.indexCount < requiredIndexes.length
37
+ )
38
+ throw new Error(
39
+ "SQLite refresh worker did not return a valid schema receipt for this destination",
40
+ );
41
+ }
9
42
 
10
43
  async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destination: string) {
11
44
  const scriptCandidates = [
@@ -24,6 +57,8 @@ async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destinat
24
57
  throw new Error("SQLite refresh worker script is unavailable from this runtime checkout");
25
58
  await new Promise<void>((resolveWorker, rejectWorker) => {
26
59
  let stderr = "";
60
+ let stdout = "";
61
+ let oversizedReceipt = false;
27
62
  const worker = spawn(process.execPath, [script], {
28
63
  cwd: workspaceRoot,
29
64
  env: {
@@ -33,13 +68,18 @@ async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destinat
33
68
  ZAIP_SQLITE_PREFER_LAST_VALID_SEED: "0",
34
69
  ZAIP_DASHBOARD_LAUNCH_PROGRESS: "0",
35
70
  },
36
- stdio: ["ignore", "ignore", "pipe"],
71
+ stdio: ["ignore", "pipe", "pipe"],
37
72
  windowsHide: true,
38
73
  });
39
74
  // Lease shutdown may end the serving parent while a slow snapshot rebuild
40
75
  // is still writing. Terminate the direct child synchronously during parent
41
76
  // exit so the next launcher cannot overlap the persistent SQLite writer.
42
77
  const cleanupWorker = attachRefreshWorkerCleanup(worker);
78
+ worker.stdout?.setEncoding("utf8");
79
+ worker.stdout?.on("data", (chunk: string) => {
80
+ if (stdout.length + chunk.length > 64_000) oversizedReceipt = true;
81
+ if (!oversizedReceipt) stdout += chunk;
82
+ });
43
83
  worker.stderr?.setEncoding("utf8");
44
84
  worker.stderr?.on("data", (chunk: string) => {
45
85
  stderr = `${stderr}${chunk}`.slice(-8_000);
@@ -48,13 +88,22 @@ async function rebuildPersistentDatabaseInWorker(workspaceRoot: string, destinat
48
88
  cleanupWorker();
49
89
  rejectWorker(error);
50
90
  });
51
- worker.once("exit", (code) => {
91
+ // close follows stdout drain; exit alone may precede the receipt bytes.
92
+ worker.once("close", (code) => {
52
93
  cleanupWorker();
53
- return code === 0
54
- ? resolveWorker()
55
- : rejectWorker(
56
- new Error(`SQLite refresh worker failed (${code}): ${stderr.trim() || "no stderr"}`),
57
- );
94
+ if (code !== 0) {
95
+ rejectWorker(
96
+ new Error(`SQLite refresh worker failed (${code}): ${stderr.trim() || "no stderr"}`),
97
+ );
98
+ return;
99
+ }
100
+ try {
101
+ if (oversizedReceipt) throw new Error("SQLite refresh worker receipt exceeds size limit");
102
+ validateSnapshotWorkerReceipt(stdout, destination);
103
+ resolveWorker();
104
+ } catch (error) {
105
+ rejectWorker(error);
106
+ }
58
107
  });
59
108
  });
60
109
  }
@@ -88,6 +137,7 @@ export async function refreshSqliteSnapshotInWorker(
88
137
  ) {
89
138
  const destination = sqliteReadModelPath(workspaceRoot);
90
139
  await rebuildPersistentDatabaseInWorker(workspaceRoot, destination);
91
- validateSqliteReadModelSchema(destination);
140
+ // Integrity/schema checking belongs to the worker, not the HTTP event loop.
141
+ // Zero exit alone is insufficient: its exact-destination receipt is mandatory.
92
142
  filesystem.refresh();
93
143
  }
@@ -19,6 +19,32 @@ afterEach(() => {
19
19
  });
20
20
 
21
21
  describe("snapshot source synchronization", () => {
22
+ it("reports capture failure separately while refreshing canonical data", async () => {
23
+ vi.useFakeTimers();
24
+ const error = new Error("capture timed out");
25
+ const onCaptureFailure = vi.fn();
26
+ const onRefreshFailure = vi.fn();
27
+ const onCaptureSuccess = vi.fn();
28
+ const capture = vi.fn().mockRejectedValueOnce(error).mockResolvedValue(undefined);
29
+ const refresh = vi.fn(async () => undefined);
30
+ startSnapshotSynchronization({
31
+ workspaceRoot: "C:/workspace",
32
+ staleSeed: false,
33
+ watchSources: true,
34
+ refresh,
35
+ captureActiveTelemetry: capture,
36
+ onCaptureFailure,
37
+ onCaptureSuccess,
38
+ onRefreshFailure,
39
+ });
40
+ await vi.advanceTimersByTimeAsync(301);
41
+ expect(onCaptureFailure).toHaveBeenCalledWith(error);
42
+ expect(onRefreshFailure).not.toHaveBeenCalled();
43
+ expect(refresh).toHaveBeenCalledTimes(1);
44
+ await vi.advanceTimersByTimeAsync(60_000);
45
+ expect(onCaptureSuccess).toHaveBeenCalledTimes(1);
46
+ expect(refresh).toHaveBeenCalledTimes(2);
47
+ });
22
48
  it("watches current data for both creation and alteration refreshes", async () => {
23
49
  vi.useFakeTimers();
24
50
  const refresh = vi.fn(async () => undefined);
@@ -8,6 +8,8 @@ export function startSnapshotSynchronization(input: {
8
8
  refresh: () => Promise<void>;
9
9
  /** Exact active-Codex collection, separate from projection and lifecycle repair. */
10
10
  captureActiveTelemetry?: () => Promise<void>;
11
+ onCaptureFailure?: (error: unknown) => void;
12
+ onCaptureSuccess?: () => void;
11
13
  /** Report failed asynchronous refreshes; a stale snapshot must never look healthy. */
12
14
  onRefreshFailure?: (input: { trigger: "stale_seed" | "source_change"; error: unknown }) => void;
13
15
  }): void {
@@ -40,7 +42,8 @@ export function startSnapshotSynchronization(input: {
40
42
  if (input.captureActiveTelemetry === undefined) return scheduleRefresh();
41
43
  void input
42
44
  .captureActiveTelemetry()
43
- .catch((error: unknown) => input.onRefreshFailure?.({ trigger: "source_change", error }))
45
+ .then(() => input.onCaptureSuccess?.())
46
+ .catch((error: unknown) => input.onCaptureFailure?.(error))
44
47
  .finally(scheduleRefresh);
45
48
  };
46
49
  // Run at most once a minute. File watchers only project canonical changes;
@@ -0,0 +1,97 @@
1
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ import { createV2WorkspaceLayout } from "@zaip-ai/core";
5
+ import { afterEach, expect, it, vi } from "vitest";
6
+ import { buildSqliteTaskTrace } from "./server-sqlite-task-trace.js";
7
+ import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
8
+ import { prepareMultiProviderFixture } from "./sqlite-read-model-multi-provider-fixture.js";
9
+
10
+ const roots: string[] = [];
11
+ const readers: SqliteReadModelFileSystem[] = [];
12
+ afterEach(async () => {
13
+ vi.restoreAllMocks();
14
+ for (const reader of readers.splice(0)) reader.close();
15
+ await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
16
+ });
17
+ const taskId = "TASK-2026-09-10-12-00-TRACE-AAAA";
18
+ const layout = createV2WorkspaceLayout(
19
+ {
20
+ schema_version: 1,
21
+ project: { id: "trace", name: "Trace", timezone: "America/Sao_Paulo" },
22
+ stack: { id: "zaip-aios-stack", overrides: {} },
23
+ clients: { codex: true, claude: false },
24
+ tracking: { enabled: true, currency: "BRL", storage_mode: "tracked_sanitized" },
25
+ },
26
+ {
27
+ lock_version: 2,
28
+ framework: { version: "3.0.0", distribution_sha256: null },
29
+ layout: { version: 3 },
30
+ resolved_profile: { id: null, sha256: null },
31
+ managed_files: {},
32
+ },
33
+ );
34
+ const taskContent = (id: string, title: string) =>
35
+ `---\nid: ${id}\ntitle: ${title}\nstatus: completed\nrisk: standard\ncreated_at: 2026-09-10T15:00:00.000Z\n---\n# ${title}\n`;
36
+ async function fixture(files: Record<string, string>) {
37
+ const root = await mkdtemp(join(tmpdir(), "zaip-trace-bounded-"));
38
+ roots.push(root);
39
+ await prepareMultiProviderFixture(root);
40
+ for (const [path, content] of Object.entries(files)) {
41
+ const target = join(root, path);
42
+ await mkdir(dirname(target), { recursive: true });
43
+ await writeFile(target, content);
44
+ }
45
+ await rebuildSqliteReadModel(root);
46
+ const filesystem = new SqliteReadModelFileSystem(root);
47
+ readers.push(filesystem);
48
+ return filesystem;
49
+ }
50
+
51
+ it("resolves the exact Task and filters oversized history before transport without losing documents", async () => {
52
+ const path = layout.activePath("task", taskId);
53
+ const small = ".agents/records/changes/trace/artifacts/tests/notes.md";
54
+ const large = ".agents/records/changes/trace/artifacts/tests/oversized.md";
55
+ const astral = ".agents/records/changes/trace/artifacts/tests/astral.md";
56
+ const shadowId = "TASK-2026-09-10-11-00-SHADOW-AAAA";
57
+ const filesystem = await fixture({
58
+ [path]: taskContent(taskId, "Requested Task"),
59
+ [layout.activePath("task", shadowId)]: taskContent(shadowId, `References ${taskId}`),
60
+ [small]: `# ${taskId}\n${"x".repeat(250_000 - taskId.length - 3)}`,
61
+ [large]: `${taskId}\n${"x".repeat(250_001)}`,
62
+ [astral]: `${taskId}\n${"😀".repeat(130_000)}`,
63
+ });
64
+ const expected = filesystem
65
+ .canonicalTraceFiles([taskId])
66
+ .filter((row) => row.content.length <= 250_000)
67
+ .map((row) => row.path);
68
+ expect(expected).toContain(small);
69
+ expect(expected).not.toContain(large);
70
+ expect(expected).not.toContain(astral);
71
+ const scan = vi.spyOn(filesystem, "canonicalTraceFiles");
72
+ const trace = await buildSqliteTaskTrace(filesystem, layout, taskId);
73
+ expect(trace.task_title).toBe("Requested Task");
74
+ expect(trace.task_id).toBe(taskId);
75
+ expect(trace.documents.map((row) => row.path)).toEqual(expected);
76
+ expect(scan).toHaveBeenCalledOnce();
77
+ expect(scan.mock.calls[0]?.[1]).toBe(250_000);
78
+ expect(scan.mock.results[0]?.value.map((row: { path: string }) => row.path)).not.toContain(large);
79
+ });
80
+
81
+ it("rejects a mismatched Task identity instead of tracing a document that mentions it", async () => {
82
+ const filesystem = await fixture({
83
+ [layout.activePath("task", taskId)]: taskContent("TASK-2026-09-10-11-00-WRONG-AAAA", taskId),
84
+ });
85
+ await expect(buildSqliteTaskTrace(filesystem, layout, taskId)).rejects.toThrow(
86
+ /identity mismatch/,
87
+ );
88
+ });
89
+
90
+ it("retains the canonical divergent-layout guard and rejects invalid bounds", async () => {
91
+ const filesystem = await fixture({
92
+ [layout.activePath("task", taskId)]: taskContent(taskId, "Active"),
93
+ [`.agents/data/tasks/2026/09/10/${taskId}.md`]: taskContent(taskId, "Divergent"),
94
+ });
95
+ await expect(buildSqliteTaskTrace(filesystem, layout, taskId)).rejects.toThrow(/Divergent/);
96
+ expect(() => filesystem.canonicalTraceFiles([taskId], -1)).toThrow(/Invalid trace content bound/);
97
+ });
@@ -1,5 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
- import type { WorkspaceLayout } from "@zaip-ai/core";
2
+ import { resolveArtifactReadPath, type WorkspaceLayout } from "@zaip-ai/core";
3
3
  import type { TaskTrace, TraceDocument } from "@zaip-ai/dashboard-traceability/contracts";
4
4
  import {
5
5
  buildTraceStageRecords,
@@ -8,26 +8,23 @@ import {
8
8
  } from "@zaip-ai/dashboard-traceability/server";
9
9
  import type { SqliteReadModelFileSystem } from "./sqlite-read-model.js";
10
10
 
11
- export function buildSqliteTaskTrace(
11
+ export async function buildSqliteTaskTrace(
12
12
  filesystem: SqliteReadModelFileSystem,
13
13
  layout: WorkspaceLayout,
14
14
  taskId: string,
15
- ): TaskTrace {
16
- const initial = filesystem.canonicalTraceFiles([taskId]);
17
- const taskFile = initial.find(
18
- (row) =>
19
- row.path.includes("/.agents/data/tasks/") ||
20
- row.path.includes(".agents/data/tasks/") ||
21
- row.path.includes("/.agents/records/tasks/") ||
22
- row.path.includes(".agents/records/tasks/"),
23
- );
24
- if (taskFile === undefined) throw new Error(`Canonical Task ${taskId} was not found`);
15
+ ): Promise<TaskTrace> {
16
+ // Resolve the exact canonical identity, not the first Task mentioning it.
17
+ // This also avoids scanning all historical contents just to locate one Task.
18
+ const taskPath = await resolveArtifactReadPath(filesystem, layout, "task", taskId);
19
+ if (taskPath === null) throw new Error(`Canonical Task ${taskId} was not found`);
20
+ const taskFile = { path: taskPath, content: await filesystem.readText(taskPath) };
25
21
  const scalar = (key: string): string | null => {
26
22
  const frontMatter = /^---\r?\n([\s\S]*?)\r?\n---/.exec(taskFile.content)?.[1] ?? "";
27
23
  const value = new RegExp(`^${key}:\\s*(.+?)\\s*$`, "m").exec(frontMatter)?.[1]?.trim();
28
24
  if (value === undefined || value === "null") return null;
29
25
  return value.replace(/^['"]|['"]$/g, "");
30
26
  };
27
+ if (scalar("id") !== taskId) throw new Error(`Canonical Task identity mismatch: ${taskId}`);
31
28
  const relatedId = (key: string, prefix: string): string | null =>
32
29
  scalar(key) ?? new RegExp(`\\b${prefix}[A-Z0-9-]+`).exec(taskFile.content)?.[0] ?? null;
33
30
  const changeId = relatedId("change_id", "CHG-") ?? taskId;
@@ -37,7 +34,7 @@ export function buildSqliteTaskTrace(
37
34
  (value): value is string => value !== null,
38
35
  );
39
36
  const documents = filesystem
40
- .canonicalTraceFiles(markers)
37
+ .canonicalTraceFiles(markers, 250_000)
41
38
  .filter(
42
39
  (row) => /\.(?:md|json|jsonl|txt|log)$/i.test(row.path) && row.content.length <= 250_000,
43
40
  )
@@ -10,15 +10,7 @@ import type { DashboardRouteContext } from "./server-route-context.js";
10
10
  import { buildSqliteTaskTrace } from "./server-sqlite-task-trace.js";
11
11
  import { SqliteReadModelFileSystem } from "./sqlite-read-model.js";
12
12
  export function registerTraceRoutes(app: Hono, dependencies: DashboardRouteContext) {
13
- const {
14
- filesystem,
15
- canonicalFilesystem,
16
- isSqliteSnapshot,
17
- readLayout,
18
- readSnapshot,
19
- readAggregate,
20
- clearSnapshotCache,
21
- } = dependencies;
13
+ const { filesystem, readLayout } = dependencies;
22
14
  app.on(["GET", "HEAD"], `${API_PREFIX}/tasks/:id`, async (context) => {
23
15
  try {
24
16
  const layout = await readLayout();
@@ -53,7 +45,7 @@ export function registerTraceRoutes(app: Hono, dependencies: DashboardRouteConte
53
45
  return headOrJson(
54
46
  context,
55
47
  filesystem instanceof SqliteReadModelFileSystem
56
- ? buildSqliteTaskTrace(filesystem, layout, taskId)
48
+ ? await buildSqliteTaskTrace(filesystem, layout, taskId)
57
49
  : await buildTaskTrace(filesystem, layout, taskId),
58
50
  );
59
51
  } catch (error) {
@@ -0,0 +1,84 @@
1
+ import { serializeMarkdown, WorkspaceFileSystem } from "@zaip-ai/core";
2
+ import { expect, it } from "vitest";
3
+ import { createDashboardApp } from "./server.js";
4
+ import { withSqliteReadModelFixture } from "./server.test-fixtures.js";
5
+ import { rebuildSqliteReadModel, SqliteReadModelFileSystem } from "./sqlite-read-model.js";
6
+
7
+ it("indexes draft and terminal Tasks in SQLite without adding drafts to Kanban", async () => {
8
+ await withSqliteReadModelFixture("trace-index", async ({ root }) => {
9
+ const at = "2026-09-11T10:00:00.000Z";
10
+ const canonical = new WorkspaceFileSystem(root);
11
+ for (const [i, status] of ["draft", "cancelled", "blocked"].entries()) {
12
+ await canonical.writeTextAtomic(
13
+ `.agents/records/tasks/2026/09/task-${i}.md`,
14
+ serializeMarkdown({
15
+ metadata: {
16
+ schema_version: 2,
17
+ id: `TASK-INDEX-${i}`,
18
+ title: `Task ${status}`,
19
+ status,
20
+ revision: 1,
21
+ change_id: `CHG-INDEX-${i}`,
22
+ short_name: `index-${i}`,
23
+ objective: "Identity fixture",
24
+ risk: "standard",
25
+ priority: "medium",
26
+ owner: null,
27
+ requirement_ids: ["REQ-WORK-001"],
28
+ acceptance_ids: ["AC-WORK-001-09"],
29
+ depends_on: [],
30
+ write_scopes: ["proof"],
31
+ plan_revision: null,
32
+ plan_hash: null,
33
+ created_at: at,
34
+ updated_at: at,
35
+ started_at: null,
36
+ finished_at: null,
37
+ result: null,
38
+ },
39
+ body: "# Identity fixture\n",
40
+ }),
41
+ );
42
+ }
43
+ await rebuildSqliteReadModel(root);
44
+ const sqlite = new SqliteReadModelFileSystem(root);
45
+ try {
46
+ const app = createDashboardApp(root, "fixture", undefined, { filesystem: sqlite });
47
+ const request = async (query: string) => {
48
+ const response = await app.request(`/api/v2/operations?${query}`, {
49
+ headers: { "x-zaip-session": "fixture" },
50
+ });
51
+ expect(response.status).toBe(200);
52
+ return response.json() as Promise<{
53
+ total: number;
54
+ tasks: { id: string; status: string }[];
55
+ }>;
56
+ };
57
+ const first = await request("scope=traceability&offset=0&limit=2");
58
+ const second = await request("scope=traceability&offset=2&limit=2");
59
+ expect(first.total).toBe(3);
60
+ expect(first.tasks).toHaveLength(2);
61
+ expect(second.tasks).toHaveLength(1);
62
+ expect([...first.tasks, ...second.tasks].map((task) => task.id)).toEqual([
63
+ "TASK-INDEX-2",
64
+ "TASK-INDEX-1",
65
+ "TASK-INDEX-0",
66
+ ]);
67
+ expect(second.tasks[0]?.status).toBe("draft");
68
+ for (const stage of [
69
+ "definition",
70
+ "planning",
71
+ "ready",
72
+ "executing",
73
+ "completed",
74
+ "blocked",
75
+ ]) {
76
+ const board = await request(`scope=board&stage=${stage}&kind=all-tasks`);
77
+ expect(board.tasks.map((task: { id: string }) => task.id)).not.toContain("TASK-INDEX-0");
78
+ }
79
+ expect((await request("scope=traceability&offset=3&limit=2")).tasks).toEqual([]);
80
+ } finally {
81
+ sqlite.close();
82
+ }
83
+ });
84
+ });
@@ -212,6 +212,7 @@ export function createDashboardApp(
212
212
  };
213
213
  let observedSnapshotRevision: string | null = null;
214
214
  const projectionRefreshDiagnostics = createProjectionRefreshDiagnostics();
215
+ let activeCaptureFailure: { code: string; occurred_at: string; cause: string } | null = null;
215
216
  let projectionRefreshInFlight: Promise<void> | null = null;
216
217
  let projectionRefreshRequested = false;
217
218
  const rebuildProjection = async () => {
@@ -262,6 +263,16 @@ export function createDashboardApp(
262
263
  ? { captureActiveTelemetry: () => captureActiveCodexTelemetry(workspaceRoot) }
263
264
  : {}),
264
265
  onRefreshFailure: projectionRefreshDiagnostics.record,
266
+ onCaptureSuccess: () => {
267
+ activeCaptureFailure = null;
268
+ },
269
+ onCaptureFailure: (error) => {
270
+ activeCaptureFailure = {
271
+ code: "active_telemetry_capture_failed",
272
+ occurred_at: new Date().toISOString(),
273
+ cause: error instanceof Error ? error.name : "unknown_error",
274
+ };
275
+ },
265
276
  });
266
277
  const reconcileWork = createWorkReconciliation({
267
278
  reconcile: (mode) =>
@@ -397,13 +408,15 @@ export function createDashboardApp(
397
408
  kind: RUNTIME_KIND,
398
409
  workspaceKey,
399
410
  service: "zaip-aios-dashboard",
400
- status: projectionRefreshDiagnostics.healthStatus,
411
+ status:
412
+ activeCaptureFailure === null ? projectionRefreshDiagnostics.healthStatus : "degraded",
401
413
  api_version: 2,
402
414
  workspace_layout: layout.version,
403
415
  read_only: true,
404
416
  storage: isSqliteSnapshot ? filesystem.metadata() : { storage_mode: "filesystem" },
405
417
  snapshot_state: snapshotState,
406
418
  projection_refresh_failure: projectionRefreshDiagnostics.failure,
419
+ active_capture_failure: activeCaptureFailure,
407
420
  });
408
421
  } catch (error) {
409
422
  return headOrJson(
@@ -450,6 +463,7 @@ export function createDashboardApp(
450
463
  day_count: metadata.daily_aggregate_count,
451
464
  snapshot_state: snapshotState,
452
465
  projection_refresh_failure: projectionRefreshDiagnostics.failure,
466
+ active_capture_failure: activeCaptureFailure,
453
467
  snapshot_revision: revision,
454
468
  });
455
469
  }
@@ -0,0 +1,17 @@
1
+ // Intl's immutable formatter is reusable; timestamps and results are never cached.
2
+ const dateFormatter = new Intl.DateTimeFormat("en", {
3
+ timeZone: "America/Sao_Paulo",
4
+ year: "numeric",
5
+ month: "2-digit",
6
+ day: "2-digit",
7
+ });
8
+
9
+ export function saoPauloDay(timestamp: string): string {
10
+ const values = Object.fromEntries(
11
+ dateFormatter
12
+ .formatToParts(new Date(timestamp))
13
+ .filter((part) => part.type !== "literal")
14
+ .map((part) => [part.type, part.value]),
15
+ ) as { year: string; month: string; day: string };
16
+ return `${values.year}-${values.month}-${values.day}`;
17
+ }
@@ -0,0 +1,78 @@
1
+ import { expect, it, vi } from "vitest";
2
+ import { saoPauloDay } from "./sqlite-calendar.js";
3
+ import { readCanonicalLifecycleRecords } from "./sqlite-read-model-canonical.js";
4
+ import { isCanonicalLifecyclePath } from "./sqlite-read-model-canonical-parsing.js";
5
+
6
+ it("reuses only the immutable formatter and preserves calendar, DST and invalid input behavior", () => {
7
+ const cases = [
8
+ ["2024-03-01T02:59:59Z", "2024-02-29"],
9
+ ["2026-01-01T02:59:59Z", "2025-12-31"],
10
+ ["2026-01-01T03:00:00Z", "2026-01-01"],
11
+ ["2018-11-04T02:59:59Z", "2018-11-03"],
12
+ ["2018-11-04T03:00:00Z", "2018-11-04"],
13
+ ["2019-02-17T02:00:00Z", "2019-02-16"],
14
+ ] as const;
15
+ const formatterConstructor = vi.spyOn(Intl, "DateTimeFormat");
16
+ try {
17
+ for (let index = 0; index < 100; index++)
18
+ for (const [timestamp, expected] of cases) expect(saoPauloDay(timestamp)).toBe(expected);
19
+ expect(() => saoPauloDay("invalid")).toThrow(RangeError);
20
+ expect(formatterConstructor).not.toHaveBeenCalled();
21
+ } finally {
22
+ formatterConstructor.mockRestore();
23
+ }
24
+ });
25
+
26
+ it("ignores irrelevant source content before YAML parsing and keeps both lifecycle layouts", () => {
27
+ const ignored = [
28
+ ".agents/records/tasks/2026/09/task.md",
29
+ ".agents/records/changes/2026/09/C/artifacts/tests/test.md",
30
+ ".agents/records/runs/run.jsonl",
31
+ ".agents/records/executions/E/other.md",
32
+ ".agents/records/changes/C/decisions/other.txt",
33
+ "elsewhere/executions/E/execution.md",
34
+ ].map((path) => ({
35
+ path,
36
+ get content(): string {
37
+ throw new Error("Irrelevant content must never be inspected");
38
+ },
39
+ }));
40
+ expect(readCanonicalLifecycleRecords(ignored)).toEqual({
41
+ executions: [],
42
+ changes: [],
43
+ decisions: [],
44
+ });
45
+ for (const layout of ["data", "records"]) {
46
+ const rows = [
47
+ {
48
+ path: `.agents/${layout}/executions/2026/09/E/execution.md`,
49
+ content:
50
+ "---\nid: E\ncreated_at: 2026-09-15T00:00:00Z\nstatus: blocked\norigin:\n type: interaction\n conversation_id: C\n---\n",
51
+ },
52
+ {
53
+ path: `.agents/${layout}/changes/2026/09/H/change.md`,
54
+ content:
55
+ "---\nid: H\ncreated_at: 2026-09-15T00:00:00Z\nsource:\n type: task\n task_id: T\n---\n",
56
+ },
57
+ ...["changes", "executions"].map((kind) => ({
58
+ path: `.agents/${layout}/${kind}/E/artifacts/decisions/D.md`,
59
+ content: `---\nid: D-${kind}\ncreated_at: 2026-09-15T00:00:00Z\norigin: human\nscope_type: execution\nscope_id: E\n---\n`,
60
+ })),
61
+ ];
62
+ expect(rows.every((row) => isCanonicalLifecyclePath(row.path))).toBe(true);
63
+ const result = readCanonicalLifecycleRecords([...ignored, ...rows]);
64
+ expect(result.executions).toHaveLength(1);
65
+ expect(result.executions[0]).toMatchObject({ id: "E", originId: "C", status: "blocked" });
66
+ expect(result.changes).toHaveLength(1);
67
+ expect(result.changes[0]).toMatchObject({ id: "H", sourceId: "T" });
68
+ expect(result.decisions).toHaveLength(2);
69
+ expect(
70
+ readCanonicalLifecycleRecords([
71
+ {
72
+ path: `.agents/${layout}/executions/E/execution.md`,
73
+ content: "---\nid: [invalid\n---\n",
74
+ },
75
+ ]).executions,
76
+ ).toEqual([]);
77
+ }
78
+ });
@@ -258,8 +258,19 @@ describe("cost invocation dimension rebuild", () => {
258
258
  expect(factRows(database, "cost_invocation_dimension_facts")).toEqual(
259
259
  factRows(database, "legacy_cost_invocation_dimension_facts"),
260
260
  );
261
+ // SQLite versions bundled with supported Node runtimes may serialize REALs
262
+ // with different precision. The contract is exact legacy JSON parity on
263
+ // that engine, not a hard-coded decimal spelling from SQLite 3.49.
264
+ const expectedCosts = database
265
+ .prepare(`
266
+ SELECT json_extract(payload, '$.cost_usd') AS cost_usd,
267
+ json_extract(payload, '$.cost_brl') AS cost_brl
268
+ FROM (SELECT json_object('cost_usd', ?, 'cost_brl', ?) AS payload)
269
+ `)
270
+ .get(0.1 + 0.2, 1234567.8912345679);
271
+ expect(expectedCosts).toEqual({ cost_usd: expect.any(Number), cost_brl: expect.any(Number) });
261
272
  expect(factRows(database, "cost_invocation_dimension_facts")).toContainEqual(
262
- expect.objectContaining({ residual: 0, cost_usd: 0.3, cost_brl: 1234567.89123457 }),
273
+ expect.objectContaining({ residual: 0, ...expectedCosts }),
263
274
  );
264
275
  });
265
276