@zaip-ai/cli 2.6.0 → 3.0.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 (301) 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 +71 -10
  20. package/templates/.agents/README.md +72 -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 +246 -134
  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-TnrL1ZyZ.js} +915 -550
  51. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-DEbCi1gP.js → PricingSettingsDialog-DjQpBqGU.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-BQZXUnQu.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-Basaw1NR.js +824 -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-BQe3zTvL.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 +238 -226
  131. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +205 -195
  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 +238 -226
  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-cost-dimension-facts.test.ts +12 -1
  154. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-file-index.test.ts +69 -0
  155. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +3 -1
  156. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-force-canonical.test.ts +3 -1
  157. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-incremental-refresh.test.ts +2 -0
  158. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-projections.ts +9 -0
  159. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-runs.ts +1 -1
  160. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-period-averages.ts +46 -0
  161. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-provider-alias-parity.test.ts +50 -0
  162. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-filtered-dimension.ts +13 -2
  163. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +25 -7
  164. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-temporal-dimension.ts +2 -0
  165. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +34 -10
  166. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-filesystem.ts +17 -3
  167. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-keeps-orphan-telemetry-out-kanban-without.test.ts +1 -1
  168. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +9 -0
  169. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +4 -4
  170. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.test.ts +54 -1
  171. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +7 -3
  172. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +4 -1
  173. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-risk-population.test.ts +98 -0
  174. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-base-views.ts +7 -2
  175. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts +2 -1
  176. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +2 -0
  177. package/templates/.agents/dashboard/packages/local-runtime/src/verify-project-settings.mjs +57 -0
  178. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  179. package/templates/.agents/dashboard/scripts/qualify-observability.mjs +130 -0
  180. package/templates/.agents/dashboard/scripts/verify-autonomy-settings.mjs +175 -0
  181. package/templates/.agents/dashboard/scripts/verify-observability.mjs +254 -0
  182. package/templates/.agents/dashboard/scripts/verify-project-setup.mjs +64 -0
  183. package/templates/.agents/dashboard/tests/e2e/lease-global-setup.ts +37 -0
  184. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  185. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +5 -3
  186. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-period-transition.spec.ts +22 -1
  187. package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +17 -8
  188. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +47 -6
  189. package/templates/.agents/dashboard/tests/e2e/specs/lease-lifetime.spec.ts +14 -0
  190. package/templates/.agents/dashboard/tests/observability-fixture.mjs +200 -0
  191. package/templates/.agents/design/.zaip-managed.json +84 -40
  192. package/templates/.agents/design/apps/catalog/dist/assets/index-BJV597iq.js +72 -0
  193. package/templates/.agents/design/apps/catalog/dist/assets/index-BOjCcUaU.js +72 -0
  194. package/templates/.agents/design/apps/catalog/dist/assets/index-B_WhrCZe.js +72 -0
  195. package/templates/.agents/design/apps/catalog/dist/assets/index-CqtYXZfV.js +72 -0
  196. package/templates/.agents/design/apps/catalog/dist/assets/index-D_lfqoyx.js +72 -0
  197. package/templates/.agents/design/apps/catalog/dist/assets/index-i_PO2k9R.js +9 -0
  198. package/templates/.agents/design/apps/catalog/dist/index.html +1 -1
  199. package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-Cstn1UwA.js +1 -0
  200. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Color-6AOWCN3U-B-kAgAjB.js → Color-6AOWCN3U-Cm-yJJz_.js} +1 -1
  201. package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-D1WopB2L.js +137 -0
  202. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DQ9PJ3N3.js +1 -0
  203. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DocsRenderer-JROSPFPF-BVN7xHtv.js → DocsRenderer-JROSPFPF-Belk4jRr.js} +4 -4
  204. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WithTooltip-7X4HQR7L-CDHtKYkz.js → WithTooltip-7X4HQR7L-DoPvjkS1.js} +1 -1
  205. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-DRQKCCAG-D6AsDkMK.js → chunk-DRQKCCAG-B1itKXEN.js} +1 -1
  206. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-W22LQPXL-B4m5uloN.js → chunk-W22LQPXL-C-Eb5SPY.js} +1 -1
  207. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{components-CN8YyTUg.js → components-DnyKLwhj.js} +5 -5
  208. package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-D0OSgxWz.js +1 -0
  209. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{iframe-9yZfIsdT.js → iframe-DcXBsFPz.js} +3 -3
  210. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{react-18-BoCSnq6H.js → react-18-CRM89QRf.js} +1 -1
  211. package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-C3tkVMIp.js +1 -0
  212. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{syntaxhighlighter-YFXUGROL-Bnn_nMwJ.js → syntaxhighlighter-YFXUGROL-B03jQGTF.js} +1 -1
  213. package/templates/.agents/design/apps/catalog/dist/storybook/assets/{theming-DS_ue2sb.js → theming-4ZyufAga.js} +1 -1
  214. package/templates/.agents/design/apps/catalog/dist/storybook/iframe.html +1 -1
  215. package/templates/.agents/design/apps/catalog/dist/storybook/index.json +1 -1
  216. package/templates/.agents/design/apps/catalog/package.json +2 -2
  217. package/templates/.agents/design/apps/catalog/src/components/AutonomySpecimen.tsx +15 -0
  218. package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.test.tsx +19 -0
  219. package/templates/.agents/design/apps/catalog/src/components/CostPopulationSpecimen.tsx +45 -0
  220. package/templates/.agents/design/apps/catalog/src/components/EstimatedCostSpecimen.tsx +48 -0
  221. package/templates/.agents/design/apps/catalog/src/components/ProjectStatusSpecimen.tsx +169 -0
  222. package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +55 -0
  223. package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +60 -0
  224. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  225. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  226. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  227. package/templates/.agents/requirements/comparative-audit.md +1 -1
  228. package/templates/.agents/requirements/context-engine.md +1 -1
  229. package/templates/.agents/requirements/cost-observability.md +1 -1
  230. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  231. package/templates/.agents/requirements/data-export.md +1 -1
  232. package/templates/.agents/requirements/design-system.md +1 -1
  233. package/templates/.agents/requirements/execution-engine.md +1 -1
  234. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  235. package/templates/.agents/requirements/model-orchestration.md +1 -1
  236. package/templates/.agents/requirements/public-distribution.md +1 -1
  237. package/templates/.agents/requirements/software-architecture.md +1 -1
  238. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  239. package/templates/.agents/requirements/work-lifecycle.md +5 -5
  240. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  241. package/templates/.agents/rules/astra-diagnostic.md +3 -1
  242. package/templates/.agents/rules/autonomy-decision.md +10 -2
  243. package/templates/.agents/rules/core.md +12 -1
  244. package/templates/.agents/rules/run-lifecycle-closure.md +8 -6
  245. package/templates/.agents/rules/workflow.md +2 -2
  246. package/templates/.agents/runtime/VERSION +1 -1
  247. package/templates/.agents/runtime/bin/zaip.mjs +383 -350
  248. package/templates/.agents/runtime/checksums.sha256 +6 -6
  249. package/templates/.agents/runtime/manifest.json +1 -1
  250. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  251. package/templates/.agents/runtime/provenance.json +5 -5
  252. package/templates/.agents/runtime/sbom.cdx.json +3 -3
  253. package/templates/.agents/skills/zaip-skill-dev-environment/SKILL.md +2 -0
  254. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +28 -5
  255. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +17 -3
  256. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +8 -9
  257. package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +10 -6
  258. package/templates/.agents/skills/zaip-skill-move-prd/SKILL.md +2 -0
  259. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +2 -0
  260. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +21 -23
  261. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +37 -13
  262. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +2 -0
  263. package/templates/.agents/skills/zaip-skill-tool-setup/SKILL.md +2 -0
  264. package/templates/.agents/zaip-aios/INDEX.md +9 -1
  265. package/templates/.agents/zaip-aios/README.md +23 -2
  266. package/templates/.agents/zaip-aios/VERSION +1 -1
  267. package/templates/.agents/zaip-aios/guides/01-primeiros-passos.md +5 -1
  268. package/templates/.agents/zaip-aios/guides/03-tasks.md +15 -2
  269. package/templates/.agents/zaip-aios/guides/04-specs.md +13 -0
  270. package/templates/.agents/zaip-aios/guides/05-prds.md +13 -0
  271. package/templates/.agents/zaip-aios/guides/06-execucao.md +19 -4
  272. package/templates/.agents/zaip-aios/guides/07-revisao-e-validacao.md +14 -0
  273. package/templates/.agents/zaip-aios/guides/08-contexto-e-tokens.md +4 -3
  274. package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +17 -9
  275. package/templates/.agents/zaip-aios/guides/10-seguranca.md +9 -0
  276. package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +69 -0
  277. package/templates/.agents/zaip-aios/guides/12-instalacao-e-upgrade.md +9 -4
  278. package/templates/.agents/zaip-aios/guides/13-boas-praticas.md +7 -1
  279. package/templates/.agents/zaip-aios/guides/14-troubleshooting.md +18 -0
  280. package/templates/.agents/zaip-aios/guides/16-lifecycle-e-reconciliacao.md +54 -3
  281. package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +10 -2
  282. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +186 -5
  283. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +21 -15
  284. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +18 -2
  285. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +14 -2
  286. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +190 -489
  287. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +61 -13
  288. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +18 -0
  289. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +18 -1
  290. package/templates/template-manifest.json +425 -269
  291. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-1L7Qw-Gq.js +0 -3
  292. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-EInWr641.css +0 -1
  293. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-B6aZfo5f.js +0 -68
  294. package/templates/.agents/dashboard/apps/frontend/dist/assets/dashboard-localization-CLJ0lT9v.js +0 -231
  295. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DgTmNHN5.js +0 -2
  296. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DQpKX9c1.js +0 -1
  297. package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-BWY-80s4.js +0 -1
  298. package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-Be2mDUQj.js +0 -27
  299. package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DRx9blDs.js +0 -1
  300. package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-EwuTh8Zk.js +0 -1
  301. package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-DyL61NPT.js +0 -1
@@ -0,0 +1,175 @@
1
+ import assert from "node:assert/strict";
2
+ import { createHash } from "node:crypto";
3
+ import { cp, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
4
+ import { createRequire } from "node:module";
5
+ import { join, resolve } from "node:path";
6
+ import { createObservabilityFixture } from "../tests/observability-fixture.mjs";
7
+
8
+ const repository = resolve(import.meta.dirname, "../../..");
9
+ const runtimeRoot = join(repository, ".agents/dashboard/packages/local-runtime");
10
+ const require = createRequire(join(runtimeRoot, "package.json"));
11
+ const {
12
+ createDashboardApp,
13
+ rebuildSqliteReadModel,
14
+ SqliteReadModelFileSystem,
15
+ } = require("./dist/server.cjs");
16
+ const { serve } = require("@hono/node-server");
17
+ const { chromium, expect } = require("@playwright/test");
18
+ const testRoot = join(repository, ".local/sqlite/tests");
19
+ const evidenceParent = join(repository, ".local/autonomy-maintenance");
20
+ await mkdir(evidenceParent, { recursive: true });
21
+ const evidenceRoot = await mkdtemp(join(evidenceParent, "ui-"));
22
+ await mkdir(testRoot, { recursive: true });
23
+ await mkdir(evidenceRoot, { recursive: true });
24
+ const fixture = await mkdtemp(join(testRoot, "autonomy-settings-"));
25
+ const token = "synthetic-autonomy-local-only";
26
+ const report = {
27
+ synthetic: true,
28
+ platform: process.platform,
29
+ started_at: new Date().toISOString(),
30
+ candidate: "current uncommitted workspace builds; not release qualification",
31
+ evidence_directory: evidenceRoot,
32
+ checks: [],
33
+ passed: false,
34
+ };
35
+ let filesystem, server, browser, page;
36
+ try {
37
+ await createObservabilityFixture(fixture);
38
+ await mkdir(join(fixture, ".agents/config/agents"), { recursive: true });
39
+ await cp(
40
+ join(repository, ".agents/config/agents/catalog.yaml"),
41
+ join(fixture, ".agents/config/agents/catalog.yaml"),
42
+ );
43
+ await rebuildSqliteReadModel(fixture, { forceCanonical: true });
44
+ filesystem = new SqliteReadModelFileSystem(fixture);
45
+ const frontend = join(repository, ".agents/dashboard/apps/frontend/dist");
46
+ report.frontend_index_sha256 = createHash("sha256")
47
+ .update(await readFile(join(frontend, "index.html")))
48
+ .digest("hex");
49
+ report.server_sha256 = createHash("sha256")
50
+ .update(await readFile(join(runtimeRoot, "dist/server.cjs")))
51
+ .digest("hex");
52
+ const app = createDashboardApp(fixture, token, frontend, {
53
+ filesystem,
54
+ watchSources: false,
55
+ snapshotReadOnly: true,
56
+ });
57
+ server = serve({ fetch: app.fetch, hostname: "127.0.0.1", port: 0 });
58
+ await new Promise((done, fail) => {
59
+ if (server.listening) done();
60
+ else {
61
+ server.once("listening", done);
62
+ server.once("error", fail);
63
+ }
64
+ });
65
+ const origin = `http://127.0.0.1:${server.address().port}`;
66
+ report.url = `${origin}/setup-project`;
67
+ browser = await chromium.launch({ headless: true });
68
+ page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
69
+ const errors = [];
70
+ page.on("pageerror", (error) => errors.push(error.message));
71
+ await page.goto(`${origin}/setup-project?token=${token}`, { waitUntil: "domcontentloaded" });
72
+ const select = page.getByRole("combobox", { name: "Perfil de autonomia" });
73
+ await expect(select).toHaveValue("balanced");
74
+ for (const preset of ["essential", "persistent", "balanced"]) {
75
+ await select.selectOption(preset);
76
+ if (preset === "essential")
77
+ await expect(
78
+ page.getByText("Nunca usa Astra automaticamente.", { exact: false }),
79
+ ).toBeVisible();
80
+ if (preset === "persistent")
81
+ await expect(
82
+ page.getByRole("status").filter({ hasText: "Sem limite de tentativas" }),
83
+ ).toBeVisible();
84
+ const saved = page.waitForResponse(
85
+ (response) =>
86
+ response.url().endsWith("/api/v2/project-settings") &&
87
+ response.request().method() === "PUT",
88
+ );
89
+ await page.getByRole("button", { name: "Salvar configurações" }).click();
90
+ const response = await saved;
91
+ assert.equal(response.status(), 200, await response.text());
92
+ const raw = await readFile(join(fixture, ".agents/config/project.yaml"), "utf8");
93
+ assert(raw.includes(`preset: ${preset}`));
94
+ const api = await fetch(`${origin}/api/v2/project-settings`, {
95
+ headers: { "x-zaip-session": token },
96
+ });
97
+ assert.equal(api.status, 200);
98
+ const data = await api.json();
99
+ assert.equal(data.autonomy.preset, preset);
100
+ await page.reload({ waitUntil: "domcontentloaded" });
101
+ await expect(select).toHaveValue(preset);
102
+ report.checks.push({ preset, api_status: 200, yaml_persisted: true, reload_confirmed: true });
103
+ }
104
+ await select.scrollIntoViewIfNeeded();
105
+ const runtimeSelect = page.getByLabel("Runtime", { exact: true });
106
+ const executionToggle = page.getByRole("checkbox", {
107
+ name: "Incluir configuração de execução",
108
+ exact: true,
109
+ });
110
+ if (!(await executionToggle.isChecked()))
111
+ await page.getByText("Incluir configuração de execução", { exact: true }).click();
112
+ await expect(executionToggle).toBeChecked();
113
+ if (await runtimeSelect.count()) {
114
+ await runtimeSelect.selectOption("managed");
115
+ const saved = page.waitForResponse(
116
+ (r) => r.url().endsWith("/api/v2/project-settings") && r.request().method() === "PUT",
117
+ );
118
+ await page.getByRole("button", { name: "Salvar configurações" }).click();
119
+ assert.equal((await saved).status(), 200);
120
+ const raw = await readFile(join(fixture, ".agents/config/project.yaml"), "utf8");
121
+ assert(raw.includes("runtime: managed"));
122
+ await page.reload({ waitUntil: "domcontentloaded" });
123
+ await expect(runtimeSelect).toHaveValue("managed");
124
+ report.checks.push({ scenario: "managed-runtime-yaml-reload", passed: true });
125
+ } else throw new Error("Runtime selector must be available for managed-mode proof");
126
+ await page.screenshot({ path: join(evidenceRoot, "autonomy-settings.png"), fullPage: true });
127
+ await page.setViewportSize({ width: 390, height: 844 });
128
+ await expect(page.locator(".project-settings-footer")).toHaveCSS("position", "static");
129
+ const disclosure = select.locator("xpath=../..").locator("p").last();
130
+ await disclosure.scrollIntoViewIfNeeded();
131
+ assert.equal(
132
+ await disclosure.evaluate((element) => {
133
+ const box = element.getBoundingClientRect();
134
+ return element.contains(
135
+ document.elementFromPoint(box.left + box.width / 2, box.top + box.height / 2),
136
+ );
137
+ }),
138
+ true,
139
+ "Mobile policy disclosure must not be covered by the save footer",
140
+ );
141
+ report.checks.push({ scenario: "mobile-disclosure-not-obscured", passed: true });
142
+ await select.scrollIntoViewIfNeeded();
143
+ await page.screenshot({
144
+ path: join(evidenceRoot, "autonomy-settings-mobile.png"),
145
+ fullPage: true,
146
+ });
147
+ await select.locator("xpath=../..").scrollIntoViewIfNeeded();
148
+ await select
149
+ .locator("xpath=../..")
150
+ .screenshot({ path: join(evidenceRoot, "autonomy-settings-mobile-detail.png") });
151
+ assert.deepEqual(errors, []);
152
+ report.screenshot_sha256 = createHash("sha256")
153
+ .update(await readFile(join(evidenceRoot, "autonomy-settings.png")))
154
+ .digest("hex");
155
+ report.passed = true;
156
+ } catch (error) {
157
+ report.error = error.stack ?? String(error);
158
+ if (page)
159
+ report.failure_dom = await page
160
+ .locator("body")
161
+ .innerText()
162
+ .catch(() => "unavailable");
163
+ process.exitCode = 1;
164
+ } finally {
165
+ await browser?.close();
166
+ if (server) {
167
+ server.closeAllConnections();
168
+ await new Promise((done) => server.close(done));
169
+ }
170
+ filesystem?.close();
171
+ report.finished_at = new Date().toISOString();
172
+ await writeFile(join(evidenceRoot, "report.json"), `${JSON.stringify(report, null, 2)}\n`);
173
+ await rm(fixture, { recursive: true, force: true });
174
+ console.log(JSON.stringify(report));
175
+ }
@@ -0,0 +1,254 @@
1
+ import assert from "node:assert/strict";
2
+ import { execFile } from "node:child_process";
3
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
4
+ import { createRequire } from "node:module";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import { promisify } from "node:util";
7
+ import { createObservabilityFixture } from "../tests/observability-fixture.mjs";
8
+
9
+ const repository = resolve(import.meta.dirname, "../../..");
10
+ const runtimeRoot = join(repository, ".agents/dashboard/packages/local-runtime");
11
+ const runtimeRequire = createRequire(join(runtimeRoot, "package.json"));
12
+ const { createDashboardApp, rebuildSqliteReadModel, SqliteReadModelFileSystem } =
13
+ runtimeRequire("./dist/server.cjs");
14
+ const { serve } = runtimeRequire("@hono/node-server");
15
+ const { chromium } = runtimeRequire("@playwright/test");
16
+ const exec = promisify(execFile);
17
+ const testRoot = join(repository, ".local/sqlite/tests");
18
+ await mkdir(testRoot, { recursive: true });
19
+ const fixture = await mkdtemp(join(testRoot, "observability-"));
20
+ const evidenceFlag = process.argv.indexOf("--evidence");
21
+ const evidenceRoot =
22
+ evidenceFlag < 0 ? join(fixture, "evidence") : resolve(process.argv[evidenceFlag + 1]);
23
+ await mkdir(evidenceRoot, { recursive: true });
24
+ const report = {
25
+ synthetic: true,
26
+ platform: process.platform,
27
+ node_version: process.version,
28
+ candidate_version: JSON.parse(await readFile(join(repository, "package.json"), "utf8")).version,
29
+ started_at: new Date().toISOString(),
30
+ cli: [],
31
+ api: [],
32
+ dom: [],
33
+ passed: false,
34
+ };
35
+ const token = "synthetic-observability-local-only";
36
+ let filesystem, server, browser, page;
37
+ async function cli(args) {
38
+ const result = await exec(
39
+ process.execPath,
40
+ [join(repository, "packages/cli/dist/index.js"), ...args, "--workspace", fixture, "--json"],
41
+ {
42
+ cwd: fixture,
43
+ windowsHide: true,
44
+ timeout: 60_000,
45
+ maxBuffer: 4 * 1024 * 1024,
46
+ env: { ...process.env, CODEX_HOME: join(fixture, ".codex-home"), ZAIP_WORKSPACE: fixture },
47
+ },
48
+ );
49
+ return JSON.parse(result.stdout);
50
+ }
51
+ try {
52
+ const cases = await createObservabilityFixture(fixture);
53
+ for (const item of cases) {
54
+ const response = await cli(["task", "show", item.task]);
55
+ assert.equal(response.task.id, item.task);
56
+ assert.equal(response.task.status, item.status);
57
+ report.cli.push(response);
58
+ }
59
+ report.manifest = await cli(["manifest", "rebuild", "--confirm-full-scan"]);
60
+ assert.deepEqual(Object.keys(report.manifest.snapshot.periods.daily), ["2025-12-31"]);
61
+ assert.equal(report.manifest.snapshot.usage.total_tokens.known_sum, 15);
62
+ assert.equal(report.manifest.snapshot.usage.total_tokens.unknown, 1);
63
+ const manifest = JSON.parse(
64
+ await readFile(join(fixture, ".agents/records/lifecycle/entity-snapshot.json"), "utf8"),
65
+ );
66
+ for (const item of cases)
67
+ assert.equal(manifest.entities[`task:${item.task}`].status, item.status);
68
+ report.sqlite = await rebuildSqliteReadModel(fixture, { forceCanonical: true });
69
+ filesystem = new SqliteReadModelFileSystem(fixture);
70
+ const app = createDashboardApp(
71
+ fixture,
72
+ token,
73
+ join(repository, ".agents/dashboard/apps/frontend/dist"),
74
+ {
75
+ filesystem,
76
+ watchSources: false,
77
+ snapshotReadOnly: true,
78
+ },
79
+ );
80
+ server = serve({ fetch: app.fetch, hostname: "127.0.0.1", port: 0 });
81
+ await new Promise((resolveReady, reject) => {
82
+ if (server.listening) resolveReady();
83
+ else {
84
+ server.once("listening", resolveReady);
85
+ server.once("error", reject);
86
+ }
87
+ });
88
+ const origin = `http://127.0.0.1:${server.address().port}`;
89
+ report.url = origin;
90
+ async function api(route) {
91
+ const response = await fetch(`${origin}${route}`, {
92
+ headers: { "x-zaip-session": token },
93
+ signal: AbortSignal.timeout(20_000),
94
+ });
95
+ const body = await response.text();
96
+ assert.equal(response.status, 200, `${route}: ${body}`);
97
+ return JSON.parse(body);
98
+ }
99
+ for (const item of cases) {
100
+ const detail = await api(`/api/v2/tasks/${item.task}`);
101
+ const trace = await api(`/api/v2/tasks/${item.task}/trace`);
102
+ assert.equal(detail.task.id, item.task);
103
+ assert.equal(detail.task.status, item.status);
104
+ assert.equal(trace.task_id, item.task);
105
+ assert.equal(trace.change_id, item.change);
106
+ assert.equal(trace.task_progress, item.status === "completed" ? 100 : 0);
107
+ assert.equal(trace.usage.total_tokens.value, item.tokens);
108
+ assert.equal(trace.usage.total_tokens.unknown_runs, item.tokens === null ? 1 : 0);
109
+ assert.equal(trace.usage.cost.value, item.status === "failed" ? null : 0);
110
+ assert.equal(trace.usage.cost.unknown_runs, item.status === "blocked" ? 0 : 1);
111
+ if (item.status === "completed") assert.equal(trace.usage.cost.coverage_ratio, 2 / 3);
112
+ assert(trace.documents.some((document) => document.content.includes(item.run)));
113
+ if (item.status === "completed") {
114
+ const documents = trace.documents.map((document) => document.content).join("\n");
115
+ assert(documents.includes(`${item.run}-PRIOR`), "Retry predecessor omitted from trace");
116
+ assert(documents.includes(`${item.run}-FINALIZER`), "Finalizer child omitted from trace");
117
+ assert(documents.includes("retry_of_run_id"), "Retry relationship omitted from trace");
118
+ report.retry_finalizer = {
119
+ task: item.task,
120
+ predecessor: `${item.run}-PRIOR`,
121
+ finalizer: `${item.run}-FINALIZER`,
122
+ attempt: detail.task.attempt_count,
123
+ };
124
+ assert.equal(detail.task.attempt_count, 2);
125
+ }
126
+ const canonical = await filesystem.readText(`.agents/records/tasks/2026/01/${item.task}.md`);
127
+ assert(canonical.includes(item.task));
128
+ report.api.push({ detail, trace });
129
+ }
130
+ report.cost_filters = [];
131
+ for (const currency of ["BRL", "USD"]) {
132
+ const costs = await api(
133
+ `/api/v2/cost-monitor?scope=summary&currency=${currency}&from=2025-12-31&to=2025-12-31`,
134
+ );
135
+ assert.equal(costs.overview.run_count, 5, "Unknown Run disappeared from financial coverage");
136
+ assert.equal(costs.overview.total_tokens, 15);
137
+ assert.equal(costs.usage.rework.tokens.total, 15, "Observed rework was classified as new work");
138
+ assert.equal(costs.usage.new_work.tokens.total, 0);
139
+ const nextDay = await api(
140
+ `/api/v2/cost-monitor?scope=summary&currency=${currency}&from=2026-01-01&to=2026-01-01`,
141
+ );
142
+ assert.equal(nextDay.overview.run_count, 0, "UTC day leaked into Sao Paulo period");
143
+ report.cost_filters.push({ currency, costs, nextDay });
144
+ }
145
+ browser = await chromium.launch({ headless: true, timeout: 30_000 });
146
+ report.browser_version = browser.version();
147
+ page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
148
+ page.setDefaultTimeout(20_000);
149
+ report.browser_responses = [];
150
+ page.on("response", async (response) => {
151
+ if (response.url().includes("/api/v2/")) {
152
+ report.browser_responses.push({
153
+ url: response.url(),
154
+ status: response.status(),
155
+ body: await response.text().catch(() => ""),
156
+ });
157
+ }
158
+ });
159
+ await page.goto(`${origin}/?token=${token}`, { waitUntil: "domcontentloaded", timeout: 30_000 });
160
+ await page
161
+ .getByRole("navigation", { name: "Áreas do dashboard" })
162
+ .getByRole("button", { name: /Rastreabilidade/ })
163
+ .click();
164
+ const costCard = page
165
+ .locator("article")
166
+ .filter({ has: page.getByText("Custo Estimado", { exact: true }) })
167
+ .first();
168
+ assert(
169
+ (await costCard.innerText()).includes("Indisponível"),
170
+ "Partial known-zero costs were presented as an exact total",
171
+ );
172
+ // Task pagination spans lifecycle stages; explicitly load remaining stages
173
+ // through the real scrolling interaction before searching literal IDs.
174
+ const searchBox = page.getByRole("combobox", { name: "Buscar task por nome ou ID" });
175
+ await searchBox.click();
176
+ for (let attempt = 0; attempt < 12; attempt += 1) {
177
+ if ((await page.getByRole("option").count()) === cases.length) break;
178
+ await page.getByRole("listbox", { name: "Buscar task por nome ou ID" }).evaluate((element) => {
179
+ element.scrollTop = element.scrollHeight;
180
+ element.dispatchEvent(new Event("scroll", { bubbles: true }));
181
+ });
182
+ await page.waitForFunction(() => !document.body.innerText.includes("Carregando mais tasks"));
183
+ }
184
+ for (const item of cases) {
185
+ const search = page.getByRole("combobox", { name: "Buscar task por nome ou ID" });
186
+ await search.fill(item.task);
187
+ const traceResponse = page.waitForResponse(
188
+ (response) =>
189
+ response.url().endsWith(`/tasks/${item.task}/trace`) && response.status() === 200,
190
+ );
191
+ await page.locator(`[id="traceability-task-option-${item.task}"]`).click();
192
+ await traceResponse;
193
+ await page.getByText(item.task, { exact: true }).first().waitFor({ state: "visible" });
194
+ const text = await page.locator("body").innerText();
195
+ assert(text.includes(item.task), `UI omitted literal ID ${item.task}`);
196
+ if (item.status === "completed")
197
+ assert.match(text, /PROGRESSO\s+100%/, "Hydration replaced canonical completed progress");
198
+ report.dom.push({ task: item.task, text });
199
+ if (item.status === "completed") {
200
+ await page.locator('button[data-stage="execution"]').click();
201
+ for (const suffix of ["PRIOR", "FINALIZER"]) {
202
+ const literal = `${item.run}-${suffix}`;
203
+ await page.locator(".trace-stage-documents button").filter({ hasText: literal }).click();
204
+ const document = page.locator(".trace-document");
205
+ await document.waitFor({ state: "visible" });
206
+ const content = await document.locator("pre").innerText();
207
+ assert(content.includes(literal));
208
+ assert(
209
+ content.includes(
210
+ suffix === "FINALIZER" ? '"run_purpose":"finalization"' : '"status":"failed"',
211
+ ),
212
+ );
213
+ report.dom.push({ run: literal, text: content });
214
+ await document.getByRole("button").click();
215
+ }
216
+ await page
217
+ .getByRole("button", { name: "Fechar detalhes da etapa", exact: true })
218
+ .last()
219
+ .click();
220
+ }
221
+ }
222
+ await page.screenshot({ path: join(evidenceRoot, "traceability.png"), fullPage: true });
223
+ report.captured_at = new Date().toISOString();
224
+ report.passed = true;
225
+ } catch (error) {
226
+ report.error = error.stack ?? String(error);
227
+ if (page) {
228
+ report.failure_dom = await page
229
+ .locator("body")
230
+ .innerText()
231
+ .catch(() => "DOM unavailable");
232
+ await page
233
+ .screenshot({ path: join(evidenceRoot, "failure.png"), fullPage: true })
234
+ .catch(() => {});
235
+ }
236
+ process.exitCode = 1;
237
+ } finally {
238
+ await browser?.close();
239
+ if (server) {
240
+ server.closeAllConnections();
241
+ await new Promise((done) => server.close(done));
242
+ }
243
+ filesystem?.close();
244
+ report.finished_at = new Date().toISOString();
245
+ await writeFile(join(evidenceRoot, "observability.json"), `${JSON.stringify(report, null, 2)}\n`);
246
+ console.log(
247
+ JSON.stringify({ passed: report.passed, evidence: evidenceRoot, error: report.error }),
248
+ );
249
+ // Only this invocation's mkdtemp fixture is removed. Explicit evidence survives.
250
+ if (evidenceFlag >= 0) {
251
+ assert.equal(dirname(fixture), testRoot);
252
+ await rm(fixture, { recursive: true, force: true });
253
+ }
254
+ }
@@ -0,0 +1,64 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { stripVTControlCharacters } from "node:util";
6
+
7
+ // Dashboard verification is workspace tooling, not frontend source. Keep the
8
+ // repository root explicit now that this script lives beside dashboard scripts.
9
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
10
+ const mode = process.argv[2];
11
+ if (!["test", "integration", "check"].includes(mode))
12
+ throw new Error("Expected test|integration|check");
13
+
14
+ function execute(args, timeout = 180_000) {
15
+ const result = spawnSync(process.execPath, args, {
16
+ cwd: root,
17
+ encoding: "utf8",
18
+ windowsHide: true,
19
+ timeout,
20
+ maxBuffer: 8_000_000,
21
+ });
22
+ const output = stripVTControlCharacters((result.stdout ?? "") + "\n" + (result.stderr ?? ""));
23
+ if (result.status !== 0) {
24
+ process.stderr.write(output);
25
+ throw new Error("Project setup validation failed: " + (result.error?.message ?? result.status));
26
+ }
27
+ return output;
28
+ }
29
+
30
+ if (!existsSync(resolve(root, "node_modules/vitest/vitest.mjs"))) {
31
+ if (spawnSync("git", ["symbolic-ref", "-q", "HEAD"], { cwd: root }).status !== 1)
32
+ throw new Error("Prepare dependencies in the Task checkout first");
33
+ const pnpm = resolve(dirname(process.execPath), "node_modules/corepack/dist/pnpm.js");
34
+ execute([pnpm, "install", "--offline", "--frozen-lockfile", "--ignore-scripts"], 300_000);
35
+ }
36
+
37
+ if (mode === "check") {
38
+ for (const project of [
39
+ ".agents/dashboard/apps/frontend/tsconfig.json",
40
+ ".agents/design/apps/catalog/tsconfig.json",
41
+ ]) {
42
+ execute(["node_modules/typescript/bin/tsc", "--noEmit", "--project", project]);
43
+ }
44
+ console.log(JSON.stringify({ kind: "project_setup_typecheck", passed: true, mode }));
45
+ } else {
46
+ const prefix = ".agents/dashboard/apps/frontend/src/";
47
+ const files =
48
+ mode === "test"
49
+ ? ["project-installation-status.test.ts", "project-settings.test.ts"]
50
+ : ["ProjectSettingsPage.dom.test.ts"];
51
+ const output = execute([
52
+ "node_modules/vitest/vitest.mjs",
53
+ "run",
54
+ ...files.map((file) => prefix + file),
55
+ "--maxWorkers=1",
56
+ ]);
57
+ const tests = output
58
+ .split("\n")
59
+ .find((line) => /^\s*Tests\s/.test(line))
60
+ ?.trim();
61
+ if (!tests || !/\b[1-9]\d* passed\b/.test(tests))
62
+ throw new Error("No project setup tests executed");
63
+ console.log(JSON.stringify({ kind: "project_setup_" + mode, passed: true, mode, tests, output }));
64
+ }
@@ -0,0 +1,37 @@
1
+ import type { FullConfig } from "@playwright/test";
2
+
3
+ /** The suite owns one runtime across browser pages, including failed-test restarts. */
4
+ export default async function holdSuiteLease(config: FullConfig) {
5
+ const baseURL = config.projects[0]?.use.baseURL;
6
+ if (!baseURL) throw new Error("Dashboard E2E requires its explicit server URL");
7
+ const url = new URL("/api/v2/browser-lease", baseURL);
8
+ url.searchParams.set("token", "e2e-token");
9
+ const controller = new AbortController();
10
+ const response = await fetch(url, { signal: controller.signal });
11
+ if (!response.ok || !response.body) {
12
+ controller.abort();
13
+ throw new Error(`Dashboard suite lease rejected: ${response.status}`);
14
+ }
15
+ const reader = response.body.getReader();
16
+ const first = await reader.read();
17
+ if (first.done || !new TextDecoder().decode(first.value).includes("lease")) {
18
+ controller.abort();
19
+ throw new Error("Dashboard suite did not acquire its real SSE lease");
20
+ }
21
+ let failure: unknown;
22
+ const drain = (async () => {
23
+ try {
24
+ while (!(await reader.read()).done) {
25
+ /* Keep the real lease stream consumed. */
26
+ }
27
+ if (!controller.signal.aborted) failure = new Error("Dashboard suite lease ended early");
28
+ } catch (error) {
29
+ if (!controller.signal.aborted) failure = error;
30
+ }
31
+ })();
32
+ return async () => {
33
+ controller.abort();
34
+ await drain;
35
+ if (failure) throw failure;
36
+ };
37
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-e2e",
3
- "version": "2.6.0",
3
+ "version": "3.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -7,13 +7,15 @@ const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? `http://127.0.0.1:${serverPor
7
7
 
8
8
  export default defineConfig({
9
9
  testDir: "./specs",
10
+ globalSetup: "./lease-global-setup.ts",
10
11
  fullyParallel: false,
11
12
  timeout: 180_000,
12
13
  expect: { timeout: 60_000 },
13
14
  retries: process.env.CI ? 1 : 0,
14
- // CI shares one SQLite runtime across the suite. Serializing browser workers
15
- // keeps the measured latency gates independent from runner CPU count.
16
- ...(process.env.CI ? { workers: 1 } : {}),
15
+ // Every suite invocation shares one SQLite runtime, including local release
16
+ // qualification. Concurrent browser workers turn latency/export checks into
17
+ // an unintended load test whose result depends on the host CPU count.
18
+ workers: 1,
17
19
  reporter: process.env.CI ? "github" : "list",
18
20
  use: {
19
21
  baseURL: `${baseURL}/?token=e2e-token`,
@@ -4,6 +4,18 @@ const COST_MONITOR_PATH = "/api/v2/cost-monitor";
4
4
  const STALE_SUMMARY_SENTINEL = "SENTINELA-RESPOSTA-ANTIGA";
5
5
  const fiveSeconds = 5_000;
6
6
 
7
+ test("reselecting the current bounded period never opens an unfinishable transition", async ({
8
+ page,
9
+ }) => {
10
+ await openDashboard(page);
11
+ await selectThisMonth(page);
12
+ await expect(periodControl(page)).toHaveValue("this-month");
13
+ await periodControl(page).selectOption("this-month");
14
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0, { timeout: fiveSeconds });
15
+ await expect(periodControl(page)).toHaveValue("this-month");
16
+ await expect(page.getByLabel("Kanban de trabalho")).toBeVisible();
17
+ });
18
+
7
19
  test("refreshes Cost Monitor within five seconds when Todo o Período is selected in place", async ({
8
20
  page,
9
21
  }) => {
@@ -86,12 +98,14 @@ test("does not let a late all-time summary overwrite the newer period", async ({
86
98
  });
87
99
  await page.addInitScript(() => {
88
100
  type Probe = {
101
+ armed: boolean;
89
102
  allTimeBody: string | null;
90
103
  allTimeFinished: boolean;
91
104
  allTimeStarted: boolean;
92
105
  releaseAllTime: null | (() => Promise<void>);
93
106
  };
94
107
  const probe: Probe = {
108
+ armed: false,
95
109
  allTimeBody: null,
96
110
  allTimeFinished: false,
97
111
  allTimeStarted: false,
@@ -109,7 +123,8 @@ test("does not let a late all-time summary overwrite the newer period", async ({
109
123
  url.searchParams.get("scope") === "summary" &&
110
124
  !url.searchParams.has("from") &&
111
125
  !url.searchParams.has("to");
112
- if (!isAllTimeSummary || probe.allTimeStarted) return originalFetch(input, init);
126
+ if (!probe.armed || !isAllTimeSummary || probe.allTimeStarted)
127
+ return originalFetch(input, init);
113
128
 
114
129
  probe.allTimeStarted = true;
115
130
  return new Promise<Response>((resolve, reject) => {
@@ -138,7 +153,12 @@ test("does not let a late all-time summary overwrite the newer period", async ({
138
153
  const staleBody = withStaleSummarySentinel(priorPeriodBody!);
139
154
  await page.evaluate((body) => {
140
155
  window.__costSummaryStaleProbe.allTimeBody = body;
156
+ // Arm only after the bounded snapshot is ready. The default first paint
157
+ // also requests All Time; intercepting it can satisfy the later wait early
158
+ // and race React's commit rather than the stale-response guard.
159
+ window.__costSummaryStaleProbe.armed = true;
141
160
  }, staleBody);
161
+ expect(await page.evaluate(() => window.__costSummaryStaleProbe.allTimeStarted)).toBe(false);
142
162
 
143
163
  await periodControl(page).selectOption("all");
144
164
  await expect
@@ -160,6 +180,7 @@ test("does not let a late all-time summary overwrite the newer period", async ({
160
180
  declare global {
161
181
  interface Window {
162
182
  __costSummaryStaleProbe: {
183
+ armed: boolean;
163
184
  allTimeBody: string | null;
164
185
  allTimeFinished: boolean;
165
186
  allTimeStarted: boolean;