@zaip-ai/cli 1.0.8 → 1.3.1

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 (360) hide show
  1. package/README.md +1 -1
  2. package/dist/services/adapters.d.ts +1 -1
  3. package/dist/services/adapters.js +1 -1
  4. package/dist/services/agent-adapters.js +3 -3
  5. package/dist/services/agent-adapters.js.map +1 -1
  6. package/dist/services/agent-adapters.test.js +7 -1
  7. package/dist/services/agent-adapters.test.js.map +1 -1
  8. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  9. package/dist/services/codex-pre-tool-hook-template.js +89 -7
  10. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  11. package/dist/services/codex-rules.d.ts +1 -1
  12. package/dist/services/codex-rules.d.ts.map +1 -1
  13. package/dist/services/codex-rules.js +7 -0
  14. package/dist/services/codex-rules.js.map +1 -1
  15. package/dist/services/install-agents-template.d.ts.map +1 -1
  16. package/dist/services/install-agents-template.js +1 -0
  17. package/dist/services/install-agents-template.js.map +1 -1
  18. package/dist/services/logger.test.js +2 -2
  19. package/dist/services/runtime-template.test.js +31 -7
  20. package/dist/services/runtime-template.test.js.map +1 -1
  21. package/dist/services/template-manifest.d.ts.map +1 -1
  22. package/dist/services/template-manifest.js +12 -3
  23. package/dist/services/template-manifest.js.map +1 -1
  24. package/package.json +1 -1
  25. package/templates/.agents/architecture/software-architecture.md +131 -0
  26. package/templates/.agents/branding/brandbook.docx +0 -0
  27. package/templates/.agents/branding/brandbook.md +60 -0
  28. package/templates/.agents/config/agents/catalog.yaml +7 -7
  29. package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +2 -2
  30. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +2 -2
  31. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
  32. package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +8 -8
  33. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -1
  34. package/templates/.agents/dashboard/.tmp-run-list.json +254 -0
  35. package/templates/.agents/dashboard/.zaip-managed.json +457 -173
  36. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-Z60df2r-.js → CostCalculationGuidePage-ovxurkIk.js} +1 -1
  37. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-BgVgrfhQ.js +2310 -0
  38. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Coc6pA-1.js → PricingSettingsDialog-vSvvOHQp.js} +1 -1
  39. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BomxqCBU.css +1 -0
  40. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-zH758vfs.js +3 -0
  41. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-DLn-Mz2M.js +1 -0
  42. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CaKwQP43.css → TraceabilityWorkspace-DvvavDLY.css} +1 -1
  43. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DKwP1stV.js +68 -0
  44. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-PoJA2PI1.css +1 -0
  45. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DFBuc_qp.js → icons-vendor-B_lDDHn1.js} +1 -1
  46. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-B31GMG5O.css +1 -0
  47. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CZQlsLV9.js +2 -0
  48. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CCQOHdVI.js → react-vendor-B3TJrD4O.js} +1 -1
  49. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-pC2_0J8x.js → traceability-7f1j5wx3.js} +1 -1
  50. package/templates/.agents/dashboard/apps/frontend/dist/index.html +7 -7
  51. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  52. package/templates/.agents/dashboard/apps/frontend/playwright.dom.config.ts +32 -0
  53. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +199 -140
  54. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +0 -21
  55. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +20 -11
  56. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +14 -7
  57. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +4 -2
  58. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.dom.e2e.ts +56 -0
  59. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +21 -2
  60. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +89 -19
  61. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +19 -4
  62. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +49 -3
  63. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +29 -10
  64. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +4 -4
  65. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +4 -2
  66. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +36 -26
  67. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +2 -2
  68. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +47 -6
  69. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +59 -9
  70. package/templates/.agents/dashboard/apps/frontend/src/sqlite-page-export.test.ts +32 -0
  71. package/templates/.agents/dashboard/apps/frontend/src/sqlite-page-export.ts +21 -0
  72. package/templates/.agents/dashboard/apps/frontend/src/styles.css +19 -0
  73. package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.test.ts +32 -0
  74. package/templates/.agents/dashboard/apps/frontend/src/traceability-task-pagination.ts +36 -0
  75. package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +6 -2
  76. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +137 -23
  77. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +229 -35
  78. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +61 -7
  79. package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +3 -6
  80. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +7 -1
  81. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-list-page.test.ts +163 -0
  82. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-list-page.ts +136 -0
  83. package/templates/.agents/dashboard/apps/frontend/src/use-operations-detail-export.ts +76 -0
  84. package/templates/.agents/dashboard/apps/frontend/src/work-list-load-dedup.test.ts +23 -0
  85. package/templates/.agents/dashboard/apps/frontend/src/work-list-load-dedup.ts +27 -0
  86. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +39 -15
  87. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +3 -4
  88. package/templates/.agents/dashboard/apps/frontend/vite.config.ts +4 -1
  89. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  90. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +89 -19
  91. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +31 -16
  92. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +43 -14
  93. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +5 -5
  94. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionPanel.tsx +60 -0
  95. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperAttributionTable.tsx +191 -0
  96. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.loading.test.ts +14 -0
  97. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.run-page.test.ts +18 -0
  98. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +18 -3
  99. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +1 -1
  100. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +75 -44
  101. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorLoadErrors.tsx +35 -0
  102. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +162 -40
  103. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +221 -79
  104. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.test.ts +132 -0
  105. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.tsx +70 -0
  106. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +203 -155
  107. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +164 -125
  108. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +2 -0
  109. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +3 -1
  110. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +5 -2
  111. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-page-range.ts +35 -0
  112. package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +2 -2
  113. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +2 -1
  114. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +32 -9
  115. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +37 -2
  116. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +131 -9
  117. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +34 -17
  118. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +0 -24
  119. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +225 -424
  120. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +24 -15
  121. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +6 -1
  122. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-monitor-projection-agents.test.ts +31 -0
  123. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-summary-projection-duration.test.ts +414 -0
  124. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  125. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +46 -26
  126. package/templates/.agents/dashboard/modules/operations/src/react/DeveloperAttributionPanel.test.ts +54 -0
  127. package/templates/.agents/dashboard/modules/operations/src/react/DeveloperAttributionPanel.tsx +247 -0
  128. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +31 -11
  129. package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +39 -13
  130. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +107 -2
  131. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.macro-metrics.test.ts +55 -0
  132. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +23 -29
  133. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +211 -184
  134. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.tsx +127 -0
  135. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +60 -51
  136. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +1 -4
  137. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +3 -0
  138. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.test.tsx +43 -0
  139. package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.tsx +181 -0
  140. package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +32 -10
  141. package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +9 -3
  142. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +13 -5
  143. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +16 -6
  144. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +14 -4
  145. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +1 -2
  146. package/templates/.agents/dashboard/modules/operations/src/react/developer-identities.test.ts +18 -0
  147. package/templates/.agents/dashboard/modules/operations/src/react/developer-identities.ts +30 -0
  148. package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +1 -0
  149. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +393 -4
  150. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +484 -61
  151. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +23 -1
  152. package/templates/.agents/dashboard/modules/operations/src/react/export/xlsx-runtime-e2e.test.ts +248 -0
  153. package/templates/.agents/dashboard/modules/operations/src/react/index.ts +1 -0
  154. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +4 -4
  155. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +6 -4
  156. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +4 -3
  157. package/templates/.agents/dashboard/modules/operations/src/react/operations-date-filters.css +1 -1
  158. package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +4 -1
  159. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +22 -12
  160. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.css +4 -0
  161. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +1 -1
  162. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +53 -6
  163. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +2 -4
  164. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +82 -6
  165. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +1 -0
  166. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +2 -1
  167. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +1 -1
  168. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +19 -7
  169. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +4 -1
  170. package/templates/.agents/dashboard/modules/operations/src/server/metric-coverage.ts +1 -0
  171. package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +11 -5
  172. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  173. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  174. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  175. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  176. package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
  177. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  178. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +533 -338
  179. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +506 -311
  180. package/templates/.agents/dashboard/packages/local-runtime/gitignore.template +2 -0
  181. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  182. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +15 -7
  183. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +44 -13
  184. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +8 -3
  185. package/templates/.agents/dashboard/packages/local-runtime/scripts/source-size-runtime-scripts/sqlite-read-model-fixture.mjs +397 -0
  186. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +472 -145
  187. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +15 -3
  188. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +141 -33
  189. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +533 -338
  190. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +6 -2
  191. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +3 -3
  192. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +89 -16
  193. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +33 -16
  194. package/templates/.agents/dashboard/packages/local-runtime/src/server-classification-page.test.ts +87 -0
  195. package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.test.ts +44 -0
  196. package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.ts +125 -0
  197. package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-refresh.test.ts +66 -0
  198. package/templates/.agents/dashboard/packages/local-runtime/src/server-request-authority.test.ts +61 -0
  199. package/templates/.agents/dashboard/packages/local-runtime/src/server-request-authority.ts +18 -0
  200. package/templates/.agents/dashboard/packages/local-runtime/src/server-run-projections.test.ts +42 -0
  201. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.ts +97 -0
  202. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +22 -5
  203. package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-task-trace.ts +91 -0
  204. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +7 -3
  205. package/templates/.agents/dashboard/packages/local-runtime/src/server.test-fixtures.ts +36 -0
  206. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +230 -132
  207. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +224 -182
  208. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-artifact-counts.ts +28 -0
  209. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.test.ts +63 -0
  210. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-agent-page.ts +109 -0
  211. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-aggregates.ts +497 -0
  212. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-fast-page-parity.test-support.ts +65 -0
  213. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-page.test.ts +176 -0
  214. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-page.ts +119 -0
  215. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-group-projection.ts +41 -0
  216. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.test.ts +16 -0
  217. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.ts +29 -0
  218. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +355 -0
  219. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-persistence.ts +121 -0
  220. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-timing.ts +27 -0
  221. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +16 -2
  222. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +15 -0
  223. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +223 -0
  224. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +304 -0
  225. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-cache.test-support.ts +23 -0
  226. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-first-fold-types.ts +89 -0
  227. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider-fixture.ts +227 -0
  228. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +691 -0
  229. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-source-fingerprint.ts +81 -0
  230. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +1655 -567
  231. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +2168 -1268
  232. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-cache.ts +129 -0
  233. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-install.test.ts +26 -0
  234. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-install.ts +28 -0
  235. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-snapshot-seed.test.ts +116 -0
  236. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +146 -0
  237. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.test.mjs +165 -0
  238. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-refresh.mjs +140 -0
  239. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +255 -289
  240. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +94 -88
  241. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  242. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +5 -2
  243. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  244. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +4 -1
  245. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-loading.spec.ts +142 -0
  246. package/templates/.agents/dashboard/tests/e2e/specs/cost-monitor-pagination.spec.ts +232 -0
  247. package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +743 -0
  248. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +189 -214
  249. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  250. package/templates/.agents/design/.zaip-managed.json +3 -3
  251. package/templates/.agents/design/apps/catalog/package.json +1 -1
  252. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  253. package/templates/.agents/growth/estrategia-bootstrap-90-dias.md +169 -0
  254. package/templates/.agents/growth/strategy.md +27 -0
  255. package/templates/.agents/marketing/estrategia-marketing-zaip-90-dias.md +197 -0
  256. package/templates/.agents/marketing/strategy.md +29 -0
  257. package/templates/.agents/requirements/autonomous-assurance.md +6 -6
  258. package/templates/.agents/requirements/comparative-audit.md +1 -1
  259. package/templates/.agents/requirements/context-engine.md +1 -1
  260. package/templates/.agents/requirements/cost-observability.md +1 -1
  261. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  262. package/templates/.agents/requirements/data-export.md +1 -1
  263. package/templates/.agents/requirements/design-system.md +1 -1
  264. package/templates/.agents/requirements/execution-engine.md +3 -3
  265. package/templates/.agents/requirements/kanban-dashboard.md +10 -2
  266. package/templates/.agents/requirements/model-orchestration.md +1 -1
  267. package/templates/.agents/requirements/public-distribution.md +1 -1
  268. package/templates/.agents/requirements/software-architecture.md +1 -1
  269. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  270. package/templates/.agents/requirements/work-lifecycle.md +4 -4
  271. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  272. package/templates/.agents/rules/dashboard-ui-consistency.md +14 -0
  273. package/templates/.agents/rules/frontend-lite.md +4 -4
  274. package/templates/.agents/rules/run-lifecycle-closure.md +4 -4
  275. package/templates/.agents/runtime/VERSION +1 -1
  276. package/templates/.agents/runtime/bin/zaip.mjs +1142 -1041
  277. package/templates/.agents/runtime/checksums.sha256 +6 -6
  278. package/templates/.agents/runtime/manifest.json +1 -1
  279. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  280. package/templates/.agents/runtime/provenance.json +5 -5
  281. package/templates/.agents/runtime/sbom.cdx.json +3 -3
  282. package/templates/.agents/sales/playbook.md +32 -0
  283. package/templates/.agents/sales/roteiro-comercial-zaip.md +252 -0
  284. package/templates/.agents/skills/criar-pasta-obsidian/scripts/generate-obsidian-vault.test.mjs +20 -16
  285. package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
  286. package/templates/.agents/skills/zaip-skill-agent-catalog/SKILL.md +22 -0
  287. package/templates/.agents/skills/zaip-skill-agent-catalog/agents/openai.yaml +4 -0
  288. package/templates/.agents/skills/zaip-skill-author-skills/SKILL.md +3 -2
  289. package/templates/.agents/skills/zaip-skill-author-skills/scripts/audit-skill-catalog.mjs +49 -0
  290. package/templates/.agents/skills/zaip-skill-author-skills/scripts/author-skill-scripts.test.mjs +27 -0
  291. package/templates/.agents/skills/zaip-skill-author-skills/scripts/run-skill-tests.mjs +37 -0
  292. package/templates/.agents/skills/zaip-skill-backend/SKILL.md +1 -0
  293. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +9 -2
  294. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-framework.md +39 -0
  295. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +1 -1
  296. package/templates/.agents/skills/zaip-skill-change/SKILL.md +1 -1
  297. package/templates/.agents/skills/zaip-skill-change/references/observable-evidence.md +83 -0
  298. package/templates/.agents/skills/zaip-skill-dashboard-diagnostics/SKILL.md +22 -0
  299. package/templates/.agents/skills/zaip-skill-dashboard-diagnostics/agents/openai.yaml +4 -0
  300. package/templates/.agents/skills/zaip-skill-enforce-architecture/SKILL.md +2 -0
  301. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
  302. package/templates/.agents/skills/zaip-skill-frontend/SKILL.md +4 -3
  303. package/templates/.agents/skills/zaip-skill-frontend/agents/openai.yaml +2 -2
  304. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +10 -10
  305. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +6 -0
  306. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +27 -0
  307. package/templates/.agents/skills/zaip-skill-lifecycle-closure/agents/openai.yaml +4 -0
  308. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +6 -0
  309. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +4 -0
  310. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +111 -104
  311. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-explicit-recovery.mjs +223 -0
  312. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +55 -9
  313. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +145 -14
  314. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +19 -9
  315. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +82 -5
  316. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +77 -0
  317. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +20 -0
  318. package/templates/.agents/skills/zaip-skill-release-qualification/agents/openai.yaml +4 -0
  319. package/templates/.agents/skills/zaip-skill-review/SKILL.md +5 -0
  320. package/templates/.agents/skills/zaip-skill-rules/SKILL.md +1 -1
  321. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +6 -0
  322. package/templates/.agents/skills/zaip-skill-spec/SKILL.md +4 -0
  323. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +22 -90
  324. package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +28 -5
  325. package/templates/.agents/zaip-aios/INDEX.md +57 -22
  326. package/templates/.agents/zaip-aios/README.md +24 -13
  327. package/templates/.agents/zaip-aios/VERSION +1 -1
  328. package/templates/.agents/zaip-aios/guides/02-requirements.md +5 -0
  329. package/templates/.agents/zaip-aios/guides/06-execucao.md +13 -4
  330. package/templates/.agents/zaip-aios/guides/07-revisao-e-validacao.md +7 -0
  331. package/templates/.agents/zaip-aios/guides/10-seguranca.md +23 -0
  332. package/templates/.agents/zaip-aios/guides/11-observabilidade-e-custos.md +6 -6
  333. package/templates/.agents/zaip-aios/guides/13-boas-praticas.md +3 -0
  334. package/templates/.agents/zaip-aios/guides/16-lifecycle-e-reconciliacao.md +12 -3
  335. package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +5 -5
  336. package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +76 -0
  337. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +95 -0
  338. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +366 -0
  339. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +46 -0
  340. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +74 -0
  341. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +483 -0
  342. package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +85 -0
  343. package/templates/.agents/zaip-aios/guides/25-fontes-de-precos-openai.md +19 -0
  344. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +111 -0
  345. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +172 -0
  346. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +149 -0
  347. package/templates/.agents/zaip-aios/guides/assets/diagrams/lifecycles-task-spec-prd.png +0 -0
  348. package/templates/.agents/zaip-aios/guides/assets/diagrams/prd-lifecycle.png +0 -0
  349. package/templates/.agents/zaip-aios/guides/assets/diagrams/spec-lifecycle.png +0 -0
  350. package/templates/.agents/zaip-aios/guides/assets/diagrams/task-lifecycle.png +0 -0
  351. package/templates/template-manifest.json +756 -235
  352. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-Cs6dzDmW.js +0 -1505
  353. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +0 -1
  354. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +0 -3
  355. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +0 -1
  356. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +0 -1
  357. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +0 -68
  358. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +0 -2
  359. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +0 -1
  360. package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +0 -45
@@ -1,12 +1,12 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { mkdir, mkdtemp, readFile, rm, utimes } from "node:fs/promises";
3
- import { connect, createServer } from "node:net";
3
+ import { createServer } from "node:net";
4
4
  import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
  import { afterEach, describe, expect, it } from "vitest";
7
7
  import {
8
- browserLaunchCommands,
9
8
  assertDashboardPrerequisites,
9
+ browserLaunchCommands,
10
10
  findAvailablePort,
11
11
  findAvailablePortWithFallback,
12
12
  findReusableDashboardSession,
@@ -21,7 +21,6 @@ import {
21
21
  recordPortStatus,
22
22
  registeredListenerMatches,
23
23
  runtimeKind,
24
- startDashboardLaunchPage,
25
24
  stopOwnedDashboardProcess,
26
25
  stripTerminalControlCodes,
27
26
  teardownWarning,
@@ -59,7 +58,7 @@ describe("dashboard executable session", () => {
59
58
 
60
59
  expect(source).toContain("export async function assertDashboardPrerequisites()");
61
60
  expect(source).toContain('await import("node:sqlite")');
62
- expect(source).not.toContain("builtinModules.includes(\"node:sqlite\")");
61
+ expect(source).not.toContain('builtinModules.includes("node:sqlite")');
63
62
  expect(source).toContain("Node.js 22 ou superior");
64
63
  expect(source.indexOf("await openBrowser(dashboardUrl(launchPort, token))")).toBeLessThan(
65
64
  source.indexOf("await assertDashboardPrerequisites();"),
@@ -78,8 +77,12 @@ describe("dashboard executable session", () => {
78
77
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
79
78
  expect(source).toContain("expectedBuildSignature: buildSignature,");
80
79
  expect(source).toContain('expectedSnapshotState: "current",');
81
- expect(source).toContain("Reused healthy compatible dashboard session on port ${reusable.port}");
82
- expect(source).toContain("await redirectLaunchPage(launchPage, dashboardUrl(reusable.port, reusable.token));");
80
+ expect(source).toContain(
81
+ "Reused healthy compatible dashboard session on port ${reusable.port}",
82
+ );
83
+ expect(source).toContain(
84
+ "await redirectLaunchPage(launchPage, dashboardUrl(reusable.port, reusable.token));",
85
+ );
83
86
  expect(source).toContain("const previousSessions = await previousDashboardSessions();");
84
87
  const excludedPorts = source.slice(
85
88
  source.indexOf("const excludedPorts = new Set(["),
@@ -91,13 +94,13 @@ describe("dashboard executable session", () => {
91
94
 
92
95
  it("opens preparation before checking freshness and keeps it through server health", async () => {
93
96
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
94
- const lock = source.indexOf("await withLauncherLock(async () => {");
97
+ const lock = source.indexOf("await withLauncherLock(");
95
98
  const preparation = source.indexOf("launchPage = await startDashboardLaunchPage(0);");
96
99
  const freshness = source.indexOf("const buildSignature = await ensureFreshDashboardBuild();");
97
- const server = source.indexOf("const { child, port, dbPath, snapshotCache } = await startDashboardServer(");
98
- const redirectAfterServer = source.indexOf(
99
- "await redirectLaunchPage(launchPage, dashboardUrl(port, token, snapshotCache === \"stale_seed\"));",
100
+ const server = source.indexOf(
101
+ "const { child, port, dbPath, snapshotCache } = await startDashboardServer(",
100
102
  );
103
+ const redirectAfterServer = source.indexOf("await redirectLaunchPage(", server);
101
104
 
102
105
  expect(lock).toBeGreaterThan(-1);
103
106
  expect(preparation).toBeLessThan(lock);
@@ -108,9 +111,13 @@ describe("dashboard executable session", () => {
108
111
 
109
112
  it("reports readiness failures as actionable without retrying a build storm", async () => {
110
113
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
111
- const wait = source.slice(source.indexOf("async function waitForDashboard"), source.indexOf("function exists"));
114
+ const wait = source.slice(
115
+ source.indexOf("async function waitForDashboard"),
116
+ source.indexOf("function exists"),
117
+ );
112
118
  expect(wait).toContain("Dashboard data readiness returned ${readiness.status}");
113
119
  expect(wait).toContain("unavailable.retryable = false;");
120
+ expect(wait).toContain("timedOut.retryable = false;");
114
121
  expect(wait).toContain("if (error?.retryable === false) throw error;");
115
122
  expect(wait).toContain("await delay(100);");
116
123
  });
@@ -118,38 +125,67 @@ describe("dashboard executable session", () => {
118
125
  it("streams complete structured rebuild progress records even when stderr chunks split a line", async () => {
119
126
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
120
127
 
121
- expect(source).toContain("let startupTelemetryBuffer = \"\";");
122
- expect(source).toContain("startupTelemetryBuffer = `${startupTelemetryBuffer}${String(chunk)}`;");
128
+ expect(source).toContain('let startupTelemetryBuffer = "";');
129
+ expect(source).toContain(
130
+ "startupTelemetryBuffer = `${startupTelemetryBuffer}${String(chunk)}`;",
131
+ );
123
132
  expect(source).toContain('event?.event === "dashboard_sqlite_rebuild_progress"');
124
133
  expect(source).toContain('ZAIP_DASHBOARD_LAUNCH_PROGRESS: "1"');
125
134
  });
126
135
 
127
136
  it("uses one durable cache and an append-only worker log for a stale snapshot refresh", async () => {
128
137
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
138
+ const refresh = await readFile(
139
+ new URL("./start-dashboard-refresh.mjs", import.meta.url),
140
+ "utf8",
141
+ );
142
+ expect(source).toContain(
143
+ 'const sqliteSnapshotCacheDirectory = join(sqliteReadModelDirectory, "cache");',
144
+ );
145
+ expect(refresh).toContain("ZAIP_WORKSPACE: workspaceRoot,");
146
+ expect(refresh).toContain("ZAIP_SQLITE_CACHE_DIR: cacheDirectory,");
147
+ expect(source).toContain(
148
+ 'const refreshLogPath = join(sessionDirectory, "dashboard-sqlite-refresh.log");',
149
+ );
150
+ expect(refresh).toContain('stdio: ["ignore", descriptor, descriptor]');
151
+ expect(refresh).toContain("worker log ${refreshLogPath}");
152
+ });
129
153
 
130
- expect(source).toContain('const sqliteSnapshotCacheDirectory = join(sqliteReadModelDirectory, "cache");');
131
- expect(source).toContain("ZAIP_SQLITE_CACHE_DIR: sqliteSnapshotCacheDirectory,");
132
- expect(source).toContain('const refreshLogPath = join(sessionDirectory, "dashboard-sqlite-refresh.log");');
133
- expect(source).toContain("stdio: [\"ignore\", refreshLogDescriptor, refreshLogDescriptor]");
134
- expect(source).toContain("worker log ${refreshLogPath}");
154
+ it("persists the refresh worker PID before another launcher click may coalesce it", async () => {
155
+ const refresh = await readFile(
156
+ new URL("./start-dashboard-refresh.mjs", import.meta.url),
157
+ "utf8",
158
+ );
159
+
160
+ expect(refresh).toContain("await acquireRefreshLock(lockPath, isProcessAlive)");
161
+ expect(refresh).toContain("if (await isRunning())");
162
+ expect(refresh).toContain("await writeJsonAtomic(refreshStatusPath, {");
163
+ expect(refresh).toContain("await stopProcessTree(worker.pid).catch(() => {});");
164
+ const runningBarrier = refresh.slice(0, refresh.indexOf('worker.once("error"'));
165
+ expect(runningBarrier).not.toContain("void writeJsonAtomic(refreshStatusPath, {");
135
166
  });
136
167
 
137
- it("keeps a visible, actionable handoff watchdog instead of closing the preparation page before navigation", async () => {
138
- const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
168
+ it("keeps the automatic handoff status visible instead of offering an unreliable local link", async () => {
169
+ const [source, launcherSource] = await Promise.all([
170
+ readFile(new URL("./start-dashboard-launch-page.mjs", import.meta.url), "utf8"),
171
+ readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8"),
172
+ ]);
139
173
 
140
- expect(source).toContain('id="handoff-link"');
174
+ expect(source).toContain("O dashboard está pronto. Abrindo a tela principal automaticamente…");
175
+ expect(source).not.toContain('id="handoff-link"');
141
176
  expect(source).toContain("function showHandoff(target)");
142
177
  expect(source).toContain("setTimeout(()=>location.replace(next.target),0)");
143
178
  expect(source).toContain("closeAfterHandoffGrace: (graceMs = 12_000)");
144
- expect(source).toContain("launchPage.closeAfterHandoffGrace();");
145
- expect(source).not.toContain("await launchPage.close();\n if (!redirected");
179
+ expect(launcherSource).toContain("launchPage.closeAfterHandoffGrace();");
180
+ expect(launcherSource).not.toContain("await launchPage.close();\n if (!redirected");
146
181
  });
147
182
 
148
183
  it("tears down prior owned sessions only after the new browser handoff", async () => {
149
184
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
150
- const redirect = source.indexOf(
151
- "await redirectLaunchPage(launchPage, dashboardUrl(port, token, snapshotCache === \"stale_seed\"));",
185
+ const server = source.indexOf(
186
+ "const { child, port, dbPath, snapshotCache } = await startDashboardServer(",
152
187
  );
188
+ const redirect = source.indexOf("await redirectLaunchPage(", server);
153
189
  const teardown = source.indexOf("for (const previous of previousSessions)");
154
190
 
155
191
  expect(redirect).toBeGreaterThan(-1);
@@ -217,7 +253,9 @@ describe("dashboard executable session", () => {
217
253
  );
218
254
 
219
255
  const ok = source.indexOf('if (status.StartsWith("ok", StringComparison.OrdinalIgnoreCase))');
220
- const warning = source.indexOf('if (status.StartsWith("warning", StringComparison.OrdinalIgnoreCase))');
256
+ const warning = source.indexOf(
257
+ 'if (status.StartsWith("warning", StringComparison.OrdinalIgnoreCase))',
258
+ );
221
259
  const okBranch = source.slice(ok, warning);
222
260
 
223
261
  expect(ok).toBeGreaterThan(-1);
@@ -227,7 +265,10 @@ describe("dashboard executable session", () => {
227
265
 
228
266
  it("publishes ok only after Node observed both health and readiness", async () => {
229
267
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
230
- const wait = source.slice(source.indexOf("async function waitForDashboard"), source.indexOf("function exists"));
268
+ const wait = source.slice(
269
+ source.indexOf("async function waitForDashboard"),
270
+ source.indexOf("function exists"),
271
+ );
231
272
 
232
273
  expect(wait).toContain("dashboardHealthUrl(port)");
233
274
  expect(wait).toContain("/api/v2/ready");
@@ -260,13 +301,22 @@ describe("dashboard executable session", () => {
260
301
  ]);
261
302
  });
262
303
 
304
+ it("keeps a Linux browser fallback when xdg-open is unavailable", () => {
305
+ const target = "http://127.0.0.1:4317/?token=local-session-token";
306
+
307
+ expect(browserLaunchCommands(target, "linux")).toEqual([
308
+ ["xdg-open", [target]],
309
+ ["gio", ["open", target]],
310
+ ]);
311
+ });
312
+
263
313
  it("falls back to another browser command when the first option fails", async () => {
264
314
  let calls = 0;
265
315
  const spawnImpl = () => {
266
- calls += 1;
316
+ const attempt = ++calls;
267
317
  const child = new EventEmitter();
268
318
  child.unref = () => {};
269
- queueMicrotask(() => child.emit(calls === 1 ? "error" : "spawn", new Error("failed")));
319
+ queueMicrotask(() => child.emit(attempt === 1 ? "error" : "spawn", new Error("failed")));
270
320
  return child;
271
321
  };
272
322
 
@@ -274,58 +324,6 @@ describe("dashboard executable session", () => {
274
324
  expect(calls).toBe(2);
275
325
  });
276
326
 
277
- it("serves a viewport-covering centered progress overlay while the runtime starts", async () => {
278
- const launchPage = await startDashboardLaunchPage(0);
279
- try {
280
- const page = await fetch(`http://${host}:${launchPage.port}/?token=temporary`);
281
- const health = await fetch(`http://${host}:${launchPage.port}/api/v2/health`);
282
-
283
- expect(page.status).toBe(200);
284
- const html = await page.text();
285
- expect(html).toContain('class="launch-overlay"');
286
- expect(html).toContain("position:fixed;inset:0;width:100vw;height:100vh");
287
- expect(html).toContain("display:grid;place-items:center");
288
- expect(html).toContain('aria-live="polite" role="status"');
289
- expect(html).toContain("abra o dashboard agora");
290
- expect(html).toContain("function showHandoff(target)");
291
- const progress = await fetch(`http://${host}:${launchPage.port}/api/v2/progress`);
292
- await expect(progress.json()).resolves.toMatchObject({
293
- phase: "Iniciando o launcher local",
294
- percent: expect.any(Number),
295
- });
296
- expect(health.status).toBe(503);
297
- await expect(health.json()).resolves.toEqual({
298
- kind: "zaip-dashboard-launcher",
299
- status: "starting",
300
- });
301
-
302
- launchPage.redirect("http://127.0.0.1:4317/?token=reused-session");
303
- const ready = await fetch(`http://${host}:${launchPage.port}/api/v2/ready`);
304
- await expect(ready.json()).resolves.toEqual({
305
- target: "http://127.0.0.1:4317/?token=reused-session",
306
- });
307
- await expect(launchPage.waitForRedirect(10)).resolves.toBe(true);
308
- } finally {
309
- await launchPage.close();
310
- }
311
- });
312
-
313
- it("bounds launch-page shutdown when a browser connection never finishes polling", async () => {
314
- const launchPage = await startDashboardLaunchPage(0);
315
- const connection = connect({ host, port: launchPage.port });
316
- await new Promise((resolveConnected, rejectConnected) => {
317
- connection.once("connect", resolveConnected);
318
- connection.once("error", rejectConnected);
319
- });
320
- const closed = new Promise((resolveClosed) => connection.once("close", resolveClosed));
321
- const startedAt = Date.now();
322
- await launchPage.close({ forceAfterMs: 20 });
323
- await closed;
324
-
325
- expect(Date.now() - startedAt).toBeLessThan(500);
326
- expect(connection.destroyed).toBe(true);
327
- });
328
-
329
327
  it("reuses a healthy session owned by the same workspace", async () => {
330
328
  const directory = await temporaryDirectory();
331
329
  const path = join(directory, "dashboard-session.json");
@@ -611,16 +609,23 @@ describe("dashboard executable session", () => {
611
609
  it("opens preparation before waiting and only reuses after checking the current build", async () => {
612
610
  const source = await readFile(new URL("./start-dashboard.mjs", import.meta.url), "utf8");
613
611
  const preparation = source.indexOf("launchPage = await startDashboardLaunchPage(0);");
614
- const lock = source.indexOf("await withLauncherLock(async () => {");
615
- const buildSignature = source.indexOf("const buildSignature = await ensureFreshDashboardBuild();");
612
+ const lock = source.indexOf("await withLauncherLock(");
613
+ const buildSignature = source.indexOf(
614
+ "const buildSignature = await ensureFreshDashboardBuild();",
615
+ );
616
616
  const reusable = source.indexOf("const reusable = await findReusableDashboardSession({");
617
617
 
618
618
  expect(preparation).toBeLessThan(lock);
619
619
  expect(buildSignature).toBeGreaterThan(lock);
620
620
  expect(reusable).toBeGreaterThan(buildSignature);
621
- expect(source).toContain("await redirectLaunchPage(launchPage, dashboardUrl(reusable.port, reusable.token));");
622
- expect(source).toContain('snapshotState: snapshotCache === "stale_seed" ? "updating" : "current",');
623
- expect(source).toContain("if (launchPage !== null) await launchPage.close().catch(() => {});");
621
+ expect(source).toContain(
622
+ "await redirectLaunchPage(launchPage, dashboardUrl(reusable.port, reusable.token));",
623
+ );
624
+ expect(source).toContain(
625
+ 'snapshotState: snapshotCache === "stale_seed" ? "updating" : "current",',
626
+ );
627
+ expect(source).toContain("launchPage.setFailure({");
628
+ expect(source).toContain("launchPage.closeAfterFailureObservation();");
624
629
  expect(source).toContain('await writeLauncherStatus("ok");');
625
630
  });
626
631
 
@@ -641,8 +646,9 @@ describe("dashboard executable session", () => {
641
646
  "utf8",
642
647
  );
643
648
 
644
- expect(source).toContain("DateTime.UtcNow.AddSeconds(135)");
645
- expect(source).toContain("mais de 135 segundos");
649
+ expect(source).toContain("DateTime.UtcNow.AddSeconds(420)");
650
+ expect(source).toContain("lock window (210 s)");
651
+ expect(source).toContain("bounded 180 s server");
646
652
  });
647
653
  });
648
654
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-ui",
3
- "version": "1.0.8",
3
+ "version": "1.3.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -82,7 +82,10 @@ namespace ZaipDashboardLauncher
82
82
  // The Node launcher coalesces concurrent clicks and may wait for a
83
83
  // healthy build/handoff. Keep this wrapper alive for that bounded
84
84
  // handoff instead of showing a second failure dialog.
85
- var deadline = DateTime.UtcNow.AddSeconds(135);
85
+ // A waiting click can spend the Node lock window (210 s) behind
86
+ // the current leader, then still needs the bounded 180 s server
87
+ // startup window if that leader fails before publishing a session.
88
+ var deadline = DateTime.UtcNow.AddSeconds(420);
86
89
  while (DateTime.UtcNow < deadline)
87
90
  {
88
91
  try
@@ -122,7 +125,7 @@ namespace ZaipDashboardLauncher
122
125
  }
123
126
  Thread.Sleep(100);
124
127
  }
125
- return ReportFailure("O dashboard demorou mais de 135 segundos para abrir. As tentativas foram interrompidas; tente novamente.");
128
+ return ReportFailure("O dashboard ainda não publicou uma sessão pronta após 420 segundos. O processo local pode continuar registrando detalhes no log temporário; feche esta mensagem e tente novamente após verificar o log.");
126
129
  }
127
130
 
128
131
  private static bool VerifyDashboardLaunch(string workspaceRoot, out string error)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-e2e",
3
- "version": "1.0.8",
3
+ "version": "1.3.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -22,12 +22,15 @@ export default defineConfig({
22
22
  cwd: workspaceRoot,
23
23
  url: `${baseURL}/api/v2/health`,
24
24
  reuseExistingServer: false,
25
- timeout: 30_000,
25
+ timeout: 120_000,
26
26
  env: {
27
27
  ZAIP_UI_TOKEN: "e2e-token",
28
28
  ZAIP_SERVER_PORT: serverPort,
29
29
  ZAIP_WORKSPACE: workspaceRoot,
30
30
  ZAIP_UI_ROOT: resolve(workspaceRoot, ".agents/dashboard/apps/frontend/dist"),
31
+ // Match the Windows launcher: first paint uses the latest validated
32
+ // immutable seed while canonical refresh work stays off the served path.
33
+ ZAIP_SQLITE_PREFER_LAST_VALID_SEED: "1",
31
34
  },
32
35
  },
33
36
  });
@@ -0,0 +1,142 @@
1
+ import { expect, test } from "@playwright/test";
2
+
3
+ declare global {
4
+ interface Window {
5
+ __costAbortRaceProbe: {
6
+ abortObserved: boolean;
7
+ overlayPresentAtSwitch: boolean | null;
8
+ shellInertAtSwitch: boolean | null;
9
+ switched: boolean;
10
+ };
11
+ }
12
+ }
13
+
14
+ test("releases an aborted Cost group load and keeps Operation reachable", async ({ page }) => {
15
+ await page.addInitScript(() => {
16
+ const probe = {
17
+ abortObserved: false,
18
+ overlayPresentAtSwitch: null as boolean | null,
19
+ shellInertAtSwitch: null as boolean | null,
20
+ switched: false,
21
+ };
22
+ const originalFetch = window.fetch.bind(window);
23
+ Object.assign(window, { __costAbortRaceProbe: probe });
24
+ window.fetch = (input, init) => {
25
+ const requestUrl = new URL(
26
+ typeof input === "string" ? input : input instanceof URL ? input.href : input.url,
27
+ window.location.href,
28
+ );
29
+ if (
30
+ !probe.switched &&
31
+ requestUrl.pathname === "/api/v2/sqlite-views" &&
32
+ requestUrl.searchParams.get("view") === "cost_monitor_daily"
33
+ ) {
34
+ const executionsTab = Array.from(
35
+ document.querySelectorAll<HTMLButtonElement>(".cost-tabs button"),
36
+ ).find((button) => button.textContent?.trim() === "Execuções");
37
+ if (executionsTab !== undefined) {
38
+ probe.overlayPresentAtSwitch =
39
+ document.querySelector(".period-transition-overlay") !== null;
40
+ probe.shellInertAtSwitch = executionsTab.closest("[inert]") !== null;
41
+ init?.signal?.addEventListener("abort", () => {
42
+ probe.abortObserved = true;
43
+ });
44
+ probe.switched = true;
45
+ executionsTab.click();
46
+ }
47
+ }
48
+ return originalFetch(input, init);
49
+ };
50
+ });
51
+
52
+ await openDashboard(page);
53
+ await expectGlobalMonthPreset(page);
54
+ const capabilityNav = page.getByRole("navigation", { name: "Áreas do dashboard" });
55
+ await capabilityNav.getByRole("button", { name: /Monitor de Custos/ }).click();
56
+ const costTabs = page.locator(".cost-tabs");
57
+ await expect(costTabs).toBeVisible();
58
+ await expect
59
+ .poll(() => page.evaluate(() => window.__costAbortRaceProbe))
60
+ .toMatchObject({
61
+ abortObserved: true,
62
+ overlayPresentAtSwitch: false,
63
+ shellInertAtSwitch: false,
64
+ switched: true,
65
+ });
66
+
67
+ const executionsTab = costTabs.getByRole("button", { exact: true, name: "Execuções" });
68
+ await expect(executionsTab).toHaveAttribute("aria-pressed", "true");
69
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0, { timeout: 15_000 });
70
+
71
+ await capabilityNav.getByRole("button", { name: /Operação/ }).click();
72
+ await expect(page.getByLabel("Kanban de trabalho")).toBeVisible();
73
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0);
74
+ });
75
+
76
+ test("loads every Cost Monitor tab before returning to Operation", async ({ page }) => {
77
+ const pageErrors: string[] = [];
78
+ const failedApiResponses: string[] = [];
79
+ page.on("pageerror", (error) => pageErrors.push(error.message));
80
+ page.on("response", (response) => {
81
+ if (
82
+ response.url().includes("/api/v2/") &&
83
+ !response.url().includes("/api/v2/reconcile-open-work") &&
84
+ response.status() >= 400
85
+ )
86
+ failedApiResponses.push(`${response.status()} ${response.url()}`);
87
+ });
88
+
89
+ await openDashboard(page);
90
+ await expectGlobalMonthPreset(page);
91
+ const capabilityNav = page.getByRole("navigation", { name: "Áreas do dashboard" });
92
+ await capabilityNav.getByRole("button", { name: /Monitor de Custos/ }).click();
93
+ const costTabs = page.locator(".cost-tabs");
94
+ await expect(costTabs).toBeVisible();
95
+
96
+ for (const [tab, view] of [
97
+ ["Diário", "daily"],
98
+ ["Mensal", "monthly"],
99
+ ["Anual", "annual"],
100
+ ["Visão geral", "overview"],
101
+ ["Execuções", "executions"],
102
+ ["Invocações de Agentes", "agentCalls"],
103
+ ["Zaip Agentes", "agents"],
104
+ ["Modelos LLM", "models"],
105
+ ["Provedores", "providers"],
106
+ ["Tarefas", "tasks"],
107
+ ["SPEC", "specs"],
108
+ ["PRD", "prds"],
109
+ ["Conversas", "conversations"],
110
+ ] as const) {
111
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0, { timeout: 30_000 });
112
+ const button = costTabs.getByRole("button", { exact: true, name: tab });
113
+ await button.click();
114
+ await expect(button).toHaveAttribute("aria-pressed", "true");
115
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0, { timeout: 30_000 });
116
+ await expect(page.locator(`.cost-content-${view}`)).toBeVisible();
117
+ await expect(page.locator(".cost-period-error")).toHaveCount(0);
118
+ }
119
+
120
+ await capabilityNav.getByRole("button", { name: /Operação/ }).click();
121
+ await expect(page.getByLabel("Kanban de trabalho")).toBeVisible();
122
+ await expect(page.locator(".period-transition-overlay")).toHaveCount(0);
123
+ expect(pageErrors).toEqual([]);
124
+ expect(failedApiResponses).toEqual([]);
125
+ });
126
+
127
+ async function expectGlobalMonthPreset(page: import("@playwright/test").Page) {
128
+ await expect(
129
+ page.locator(".dashboard-global-controls").getByRole("combobox", { name: "Período" }),
130
+ ).toHaveValue("this-month");
131
+ }
132
+
133
+ async function openDashboard(page: import("@playwright/test").Page) {
134
+ const operations = page.waitForResponse(
135
+ (response) =>
136
+ response.status() === 200 &&
137
+ response.url().includes("/api/v2/operations") &&
138
+ response.url().includes("scope=quick"),
139
+ );
140
+ await page.goto("/?token=e2e-token");
141
+ return operations;
142
+ }