@zaip-ai/cli 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/README.md +6 -4
  2. package/dist/services/adapters.d.ts +1 -1
  3. package/dist/services/adapters.d.ts.map +1 -1
  4. package/dist/services/adapters.js +15 -5
  5. package/dist/services/adapters.js.map +1 -1
  6. package/dist/services/adapters.test.js +1 -1
  7. package/dist/services/agent-adapters.d.ts +9 -0
  8. package/dist/services/agent-adapters.d.ts.map +1 -1
  9. package/dist/services/agent-adapters.js +38 -3
  10. package/dist/services/agent-adapters.js.map +1 -1
  11. package/dist/services/agent-adapters.test.js +8 -1
  12. package/dist/services/agent-adapters.test.js.map +1 -1
  13. package/dist/services/codex-config-template.d.ts +2 -1
  14. package/dist/services/codex-config-template.d.ts.map +1 -1
  15. package/dist/services/codex-config-template.js +13 -2
  16. package/dist/services/codex-config-template.js.map +1 -1
  17. package/dist/services/codex-rules.d.ts +1 -1
  18. package/dist/services/codex-rules.d.ts.map +1 -1
  19. package/dist/services/codex-rules.js +31 -7
  20. package/dist/services/codex-rules.js.map +1 -1
  21. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  22. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  23. package/dist/services/codex-subagent-hook-template.js +4 -1
  24. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  25. package/dist/services/doctor.d.ts.map +1 -1
  26. package/dist/services/doctor.js +3 -1
  27. package/dist/services/doctor.js.map +1 -1
  28. package/dist/services/global-codex-config.d.ts +6 -3
  29. package/dist/services/global-codex-config.d.ts.map +1 -1
  30. package/dist/services/global-codex-config.js +82 -13
  31. package/dist/services/global-codex-config.js.map +1 -1
  32. package/dist/services/global-codex-config.test.js +57 -10
  33. package/dist/services/global-codex-config.test.js.map +1 -1
  34. package/dist/services/install-agents-template.d.ts.map +1 -1
  35. package/dist/services/install-agents-template.js +15 -2
  36. package/dist/services/install-agents-template.js.map +1 -1
  37. package/dist/services/logger.js +1 -1
  38. package/dist/services/logger.js.map +1 -1
  39. package/dist/services/logger.test.js +3 -3
  40. package/dist/services/logger.test.js.map +1 -1
  41. package/dist/services/runtime-template.test.js +21 -5
  42. package/dist/services/runtime-template.test.js.map +1 -1
  43. package/dist/services/template-manifest.d.ts.map +1 -1
  44. package/dist/services/template-manifest.js +2 -0
  45. package/dist/services/template-manifest.js.map +1 -1
  46. package/package.json +1 -1
  47. package/templates/.agents/config/agents/catalog.yaml +310 -10
  48. package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +30 -0
  49. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +5 -5
  50. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
  51. package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +30 -0
  52. package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +30 -0
  53. package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +30 -0
  54. package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +8 -8
  55. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +5 -3
  56. package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +30 -0
  57. package/templates/.agents/config/project.yaml +1 -1
  58. package/templates/.agents/dashboard/.zaip-managed.json +659 -163
  59. package/templates/.agents/dashboard/DATA-DICTIONARY.md +2227 -0
  60. package/templates/.agents/dashboard/README.md +48 -97
  61. package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-Z60df2r-.js +1 -0
  62. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cv-JcoxP.js → DashboardHelpDialog-Cs6dzDmW.js} +294 -109
  63. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-Coc6pA-1.js +1 -0
  64. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +1 -0
  65. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +3 -0
  66. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +1 -0
  67. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-CaKwQP43.css +1 -0
  68. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +1 -0
  69. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +68 -0
  70. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-C98LGC-Q.js → dashboard-localization-CLJ0lT9v.js} +1 -1
  71. package/templates/.agents/dashboard/apps/frontend/dist/assets/icons-vendor-DFBuc_qp.js +1 -0
  72. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +2 -0
  73. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +1 -0
  74. package/templates/.agents/dashboard/apps/frontend/dist/assets/react-vendor-CCQOHdVI.js +9 -0
  75. package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-D9-fqq9M.js +1 -0
  76. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DFY7ZDlu.css +1 -0
  77. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-pC2_0J8x.js +1 -0
  78. package/templates/.agents/dashboard/apps/frontend/dist/index.html +9 -2
  79. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  80. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +952 -595
  81. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +48 -0
  82. package/templates/.agents/dashboard/apps/frontend/src/AppLoadingPanels.tsx +2 -0
  83. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +247 -0
  84. package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +95 -0
  85. package/templates/.agents/dashboard/apps/frontend/src/AppSetupRoutes.tsx +87 -0
  86. package/templates/.agents/dashboard/apps/frontend/src/CostCalculationGuidePage.tsx +641 -0
  87. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +159 -0
  88. package/templates/.agents/dashboard/apps/frontend/src/DashboardCapabilityNav.tsx +13 -13
  89. package/templates/.agents/dashboard/apps/frontend/src/DashboardGlobalSettings.tsx +56 -0
  90. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +257 -313
  91. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +149 -0
  92. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +35 -0
  93. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +111 -12
  94. package/templates/.agents/dashboard/apps/frontend/src/app-preferences.ts +15 -0
  95. package/templates/.agents/dashboard/apps/frontend/src/app-session-token.ts +20 -0
  96. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.css +267 -0
  97. package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.test.ts +69 -0
  98. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +70 -0
  99. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +111 -0
  100. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +432 -13
  101. package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +1 -1
  102. package/templates/.agents/dashboard/apps/frontend/src/main.tsx +1 -0
  103. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.test.ts +55 -0
  104. package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.ts +36 -0
  105. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.test.ts +126 -0
  106. package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.ts +181 -0
  107. package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +138 -0
  108. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +105 -0
  109. package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +6 -3
  110. package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +9 -5
  111. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +24 -0
  112. package/templates/.agents/dashboard/apps/frontend/src/period-transition-overlay.css +44 -0
  113. package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +121 -62
  114. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +471 -2
  115. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +84 -17
  116. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +44 -0
  117. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +196 -39
  118. package/templates/.agents/dashboard/apps/frontend/src/snapshot-notice.ts +15 -0
  119. package/templates/.agents/dashboard/apps/frontend/src/sqlite-cost-adapters.ts +26 -0
  120. package/templates/.agents/dashboard/apps/frontend/src/styles.css +14 -2
  121. package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +38 -2
  122. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +187 -0
  123. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +190 -0
  124. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +121 -0
  125. package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +398 -0
  126. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +141 -0
  127. package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +45 -0
  128. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +46 -0
  129. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +37 -0
  130. package/templates/.agents/dashboard/apps/frontend/vite.config.ts +55 -5
  131. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  132. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +47 -6
  133. package/templates/.agents/dashboard/modules/cost-monitor/src/duration-estimate.ts +13 -0
  134. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +64 -0
  135. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +275 -0
  136. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +100 -15
  137. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +131 -40
  138. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +137 -19
  139. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.test.ts +2 -0
  140. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +13 -10
  141. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +303 -0
  142. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +226 -6
  143. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +479 -402
  144. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostSummary.tsx +5 -13
  145. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +312 -72
  146. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +373 -321
  147. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +17 -0
  148. package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +25 -6
  149. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +0 -2
  150. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-helpers.ts +17 -0
  151. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-responsive.css +6 -3
  152. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-row-filters.ts +123 -0
  153. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +8 -3
  154. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +32 -0
  155. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +52 -14
  156. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-presentation.ts +121 -0
  157. package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +3 -0
  158. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.test.ts +68 -0
  159. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +32 -5
  160. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +108 -0
  161. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +12 -0
  162. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +60 -0
  163. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +106 -0
  164. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.test.ts +2 -2
  165. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +5 -3
  166. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-pricing-fallback.test.ts +53 -0
  167. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.basics.test.ts +34 -0
  168. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +168 -137
  169. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +188 -29
  170. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +956 -0
  171. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +775 -0
  172. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +95 -0
  173. package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
  174. package/templates/.agents/dashboard/modules/cost-monitor/src/server/refactor-map-xr9l.json +61 -0
  175. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.test.ts +41 -0
  176. package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.ts +55 -11
  177. package/templates/.agents/dashboard/modules/operations/package.json +2 -1
  178. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +182 -0
  179. package/templates/.agents/dashboard/modules/operations/src/duration-population.test.ts +63 -1
  180. package/templates/.agents/dashboard/modules/operations/src/duration-population.ts +60 -5
  181. package/templates/.agents/dashboard/modules/operations/src/react/EntityDetailsDialog.tsx +14 -3
  182. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.test.ts +44 -1
  183. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +325 -18
  184. package/templates/.agents/dashboard/modules/operations/src/react/MacroPlanningDialog.tsx +1 -0
  185. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.test.ts +9 -5
  186. package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.tsx +2 -2
  187. package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +168 -0
  188. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +95 -6
  189. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +365 -14
  190. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +532 -131
  191. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +314 -358
  192. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +68 -0
  193. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +169 -0
  194. package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +51 -8
  195. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.test.tsx +32 -0
  196. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.tsx +62 -6
  197. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.test.ts +55 -0
  198. package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.tsx +27 -19
  199. package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +99 -42
  200. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts +19 -0
  201. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +255 -34
  202. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +163 -8
  203. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +101 -68
  204. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.test.ts +72 -1
  205. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +78 -16
  206. package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +6 -4
  207. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +50 -1
  208. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +143 -9
  209. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +29 -4
  210. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog-content.css +49 -0
  211. package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog.css +93 -50
  212. package/templates/.agents/dashboard/modules/operations/src/react/manual-work-priority.test.ts +82 -0
  213. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts +29 -2
  214. package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.ts +22 -1
  215. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +77 -4
  216. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +65 -5
  217. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +54 -0
  218. package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +19 -0
  219. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +149 -12
  220. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +27 -0
  221. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +136 -0
  222. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.test.ts +160 -0
  223. package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.ts +47 -0
  224. package/templates/.agents/dashboard/modules/operations/src/react/operations-query.ts +10 -0
  225. package/templates/.agents/dashboard/modules/operations/src/react/operations-responsive.css +3 -0
  226. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-labels.ts +28 -0
  227. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +24 -7
  228. package/templates/.agents/dashboard/modules/operations/src/react/operations.css +42 -0
  229. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.test.ts +54 -0
  230. package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.ts +32 -0
  231. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +165 -6
  232. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +148 -6
  233. package/templates/.agents/dashboard/modules/operations/src/react/popup-localization.test.ts +1 -1
  234. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css +132 -0
  235. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css.test.ts +13 -0
  236. package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.header.test.ts +16 -0
  237. package/templates/.agents/dashboard/modules/operations/src/react/use-infinite-column.ts +11 -5
  238. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +5 -3
  239. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +4 -83
  240. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.test.ts +291 -15
  241. package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.ts +182 -472
  242. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.test.ts +40 -0
  243. package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.ts +19 -6
  244. package/templates/.agents/dashboard/modules/operations/src/server/canonical-run-projection.ts +31 -6
  245. package/templates/.agents/dashboard/modules/operations/src/server/daily-duration-projection.ts +220 -0
  246. package/templates/.agents/dashboard/modules/operations/src/server/execution-duration-projection.ts +28 -0
  247. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +27 -2
  248. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +22 -13
  249. package/templates/.agents/dashboard/modules/operations/src/server/filter.test.ts +3 -3
  250. package/templates/.agents/dashboard/modules/operations/src/server/filter.ts +7 -2
  251. package/templates/.agents/dashboard/modules/operations/src/server/index.ts +3 -0
  252. package/templates/.agents/dashboard/modules/operations/src/server/macro.ts +3 -12
  253. package/templates/.agents/dashboard/modules/operations/src/server/manifest-usage.ts +65 -0
  254. package/templates/.agents/dashboard/modules/operations/src/server/operations-projection-aggregates.ts +297 -0
  255. package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +324 -0
  256. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.test.ts +505 -0
  257. package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.ts +609 -0
  258. package/templates/.agents/dashboard/modules/operations/src/server/runs.ts +18 -19
  259. package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +76 -0
  260. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  261. package/templates/.agents/dashboard/modules/traceability/src/server/build-task-trace.ts +3 -1
  262. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  263. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  264. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  265. package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
  266. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  267. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +1756 -0
  268. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +1608 -0
  269. package/templates/.agents/dashboard/packages/local-runtime/package.json +8 -3
  270. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +12 -0
  271. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +83 -0
  272. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +28 -0
  273. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +262 -0
  274. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +41 -0
  275. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +105 -0
  276. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +1643 -107
  277. package/templates/.agents/dashboard/packages/local-runtime/src/agent-adapter-sync.ts +30 -0
  278. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.test.ts +3 -2
  279. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.ts +5 -0
  280. package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +72 -33
  281. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +335 -4
  282. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +392 -1
  283. package/templates/.agents/dashboard/packages/local-runtime/src/runtime.mjs +5 -5
  284. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +71 -0
  285. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +179 -0
  286. package/templates/.agents/dashboard/packages/local-runtime/src/server-cross-layer-parity.test.ts +245 -0
  287. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models-route.ts +64 -0
  288. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.test.ts +204 -0
  289. package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.ts +194 -0
  290. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +163 -0
  291. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +354 -0
  292. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.test.ts +74 -0
  293. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +113 -0
  294. package/templates/.agents/dashboard/packages/local-runtime/src/server-overview.test.ts +68 -0
  295. package/templates/.agents/dashboard/packages/local-runtime/src/server-period.ts +47 -0
  296. package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +483 -0
  297. package/templates/.agents/dashboard/packages/local-runtime/src/server-settings.test.ts +5 -2
  298. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +163 -84
  299. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +145 -0
  300. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +551 -266
  301. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +1145 -308
  302. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.test.ts +53 -0
  303. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +708 -0
  304. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +2232 -0
  305. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +6151 -0
  306. package/templates/.agents/dashboard/packages/local-runtime/src/work-priority-contract.test.ts +33 -0
  307. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +41 -0
  308. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +210 -0
  309. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +437 -190
  310. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +299 -24
  311. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  312. package/templates/.agents/dashboard/packages/windows-launcher/LauncherVerificationBehaviorTests.cs +206 -0
  313. package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +95 -8
  314. package/templates/.agents/dashboard/packages/windows-launcher/build-dashboard-launcher.ps1 +2 -2
  315. package/templates/.agents/dashboard/packages/windows-launcher/run-launcher-verification-tests.ps1 +22 -0
  316. package/templates/.agents/dashboard/read-model.dbml +2201 -0
  317. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  318. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +1 -1
  319. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +214 -41
  320. package/templates/.agents/dashboard/work-priority.json +34 -0
  321. package/templates/.agents/dashboard/zaip-dashboard-linux.sh +45 -0
  322. package/templates/.agents/dashboard/zaip-dashboard-mac.command +3 -0
  323. package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
  324. package/templates/.agents/design/.zaip-managed.json +3 -3
  325. package/templates/.agents/design/apps/catalog/package.json +1 -1
  326. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  327. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  328. package/templates/.agents/requirements/comparative-audit.md +1 -1
  329. package/templates/.agents/requirements/context-engine.md +1 -1
  330. package/templates/.agents/requirements/cost-observability.md +1 -1
  331. package/templates/.agents/requirements/dashboard-launch.md +24 -0
  332. package/templates/.agents/requirements/data-export.md +1 -1
  333. package/templates/.agents/requirements/design-system.md +1 -1
  334. package/templates/.agents/requirements/execution-engine.md +1 -1
  335. package/templates/.agents/requirements/kanban-dashboard.md +4 -3
  336. package/templates/.agents/requirements/model-orchestration.md +1 -1
  337. package/templates/.agents/requirements/public-distribution.md +9 -6
  338. package/templates/.agents/requirements/software-architecture.md +1 -1
  339. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  340. package/templates/.agents/requirements/work-lifecycle.md +9 -3
  341. package/templates/.agents/requirements/zaip-strategic-95.md +4 -4
  342. package/templates/.agents/rules/autonomy-decision.md +15 -0
  343. package/templates/.agents/rules/core.md +1 -1
  344. package/templates/.agents/rules/run-lifecycle-closure.md +1 -1
  345. package/templates/.agents/rules/specialist-routing.md +19 -0
  346. package/templates/.agents/rules/workflow.md +1 -1
  347. package/templates/.agents/runtime/VERSION +1 -1
  348. package/templates/.agents/runtime/bin/zaip.mjs +114 -64
  349. package/templates/.agents/runtime/checksums.sha256 +6 -4
  350. package/templates/.agents/runtime/manifest.json +3 -1
  351. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -0
  352. package/templates/.agents/runtime/provenance.json +11 -0
  353. package/templates/.agents/runtime/sbom.cdx.json +1929 -39
  354. package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
  355. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +15 -0
  356. package/templates/.agents/skills/zaip-skill-brand-governance/agents/openai.yaml +4 -0
  357. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +30 -0
  358. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +25 -0
  359. package/templates/.agents/skills/zaip-skill-dashboard-sqlite/agents/openai.yaml +4 -0
  360. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/SKILL.md +18 -0
  361. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/agents/openai.yaml +6 -0
  362. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.mjs +71 -0
  363. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.test.mjs +60 -0
  364. package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/scheduled-ready-queue-contract.test.mjs +111 -0
  365. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +2 -2
  366. package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +3 -1
  367. package/templates/.agents/skills/zaip-skill-general-operations/SKILL.md +12 -0
  368. package/templates/.agents/skills/zaip-skill-general-operations/agents/openai.yaml +4 -0
  369. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -7
  370. package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +2 -2
  371. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +11 -38
  372. package/templates/.agents/skills/zaip-skill-governance-compliance/SKILL.md +12 -0
  373. package/templates/.agents/skills/zaip-skill-governance-compliance/agents/openai.yaml +4 -0
  374. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +15 -0
  375. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/agents/openai.yaml +4 -0
  376. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/references/growth-revops-framework.md +25 -0
  377. package/templates/.agents/skills/zaip-skill-instalar-agendamento/SKILL.md +17 -0
  378. package/templates/.agents/skills/zaip-skill-instalar-agendamento/agents/openai.yaml +6 -0
  379. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +3 -3
  380. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +76 -27
  381. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +128 -24
  382. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +122 -4
  383. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +66 -19
  384. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +193 -7
  385. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +14 -0
  386. package/templates/.agents/skills/zaip-skill-sales-methodology/agents/openai.yaml +4 -0
  387. package/templates/.agents/skills/zaip-skill-sales-methodology/references/sales-process-framework.md +77 -0
  388. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +5 -0
  389. package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +96 -0
  390. package/templates/.agents/skills/zaip-skill-sqlite-read-model/agents/openai.yaml +4 -0
  391. package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +18 -0
  392. package/templates/.agents/zaip-aios/INDEX.md +1 -0
  393. package/templates/.agents/zaip-aios/README.md +37 -8
  394. package/templates/.agents/zaip-aios/VERSION +1 -1
  395. package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +43 -6
  396. package/templates/.agents/zaip-aios/guides/10-seguranca.md +21 -7
  397. package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +32 -0
  398. package/templates/template-manifest.json +945 -214
  399. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-CLYIi7Vo.js +0 -1
  400. package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-DTDNVQGX.css +0 -1
  401. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-CzEggcRb.js +0 -1
  402. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-05YKn6Z4.js +0 -3
  403. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-YO3yqtgV.css +0 -1
  404. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8AzCnl3a.js +0 -77
  405. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DdBYQ_8D.css +0 -1
  406. package/templates/.agents/dashboard/apps/frontend/src/AgentCatalogSettingsPage.tsx +0 -617
  407. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings-page.css +0 -660
  408. package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings.test.ts +0 -249
  409. package/templates/.agents/dashboard/dashboard.config.json +0 -4
  410. package/templates/.agents/dashboard/zaip-dashboard.exe +0 -0
@@ -10,29 +10,35 @@ export function TaskDetailsDialog({
10
10
  locale = "pt-BR",
11
11
  onClose,
12
12
  onOpenTrace,
13
+ summary = false,
14
+ summaryRunCount = null,
13
15
  }: {
14
16
  detail: TaskDetailProjection;
15
- operations: OperationsProjection;
17
+ operations: {
18
+ readonly runs: readonly OperationsProjection["runs"][number][];
19
+ readonly decisions: readonly OperationsProjection["decisions"][number][];
20
+ };
16
21
  locale?: OperationsLocale;
17
22
  onClose: () => void;
18
23
  onOpenTrace: (taskId: string) => void;
24
+ summary?: boolean;
25
+ /** Exact count supplied by the compact card projection, when available. */
26
+ summaryRunCount?: number | null;
19
27
  }) {
20
28
  const copy = taskDetailsCopy(locale);
21
29
  const runs = operations.runs.filter((run) => run.task_id === detail.task.id);
22
30
  const decisions = operations.decisions.filter(
23
31
  (decision) => decision.scope_type === "change" && decision.scope_id === detail.task.change_id,
24
32
  );
25
- const operationalDurations = runs
26
- .filter((run) => run.phase === "execution" && run.parent_run_id == null)
27
- .flatMap((run) => {
28
- const durationMs = operationalDurationMs(run);
29
- return durationMs === null ? [] : [durationMs];
30
- });
31
- const duration =
32
- operationalDurations.length === 0
33
- ? null
34
- : operationalDurations.reduce((total, durationMs) => total + durationMs, 0);
35
- const tokens = runs.reduce((total, run) => total + (run.usage.total.tokens.total ?? 0), 0);
33
+ const telemetry = detail.task.telemetry
34
+ ? {
35
+ durationMs: detail.task.telemetry.duration_ms,
36
+ tokens: detail.task.telemetry.tokens,
37
+ costBrl: detail.task.telemetry.cost_brl,
38
+ }
39
+ : recoverExactTelemetry(runs);
40
+ const hasSummarySpecId = detail.task.spec_id !== null && detail.task.spec_id.trim() !== "";
41
+ const hasChangeId = detail.task.change_id.trim() !== "";
36
42
  return createPortal(
37
43
  <div className="operations-dialog-backdrop">
38
44
  <section aria-label={copy.aria} aria-modal="true" className="operations-dialog" role="dialog">
@@ -50,40 +56,71 @@ export function TaskDetailsDialog({
50
56
  <dl className="operations-detail-grid">
51
57
  <Detail label={copy.status} value={statusLabel(detail.task.status, locale)} />
52
58
  <Detail label={copy.risk} value={riskLabel(detail.task.risk, locale)} />
53
- <Detail label="SPEC" value={detail.task.spec_id ?? "Task-first"} />
54
- <Detail label="Change" value={detail.task.change_id} />
55
- <Detail label="Runs" value={String(runs.length)} />
56
- <Detail label={copy.duration} value={formatOperationDuration(duration, locale)} />
57
- <Detail label="Tokens" value={formatCompactNumber(tokens || null, locale)} />
59
+ {!summary || hasSummarySpecId ? (
60
+ <Detail label="SPEC" value={detail.task.spec_id ?? "Task-first"} />
61
+ ) : null}
62
+ {!summary || hasChangeId ? <Detail label="Change" value={detail.task.change_id} /> : null}
63
+ {!summary || summaryRunCount !== null ? (
64
+ <Detail label="Runs" value={String(summary ? summaryRunCount : runs.length)} />
65
+ ) : null}
66
+ <Detail label={copy.duration} value={formatOperationDuration(telemetry.durationMs, locale)} />
67
+ <Detail
68
+ label="Tokens"
69
+ value={
70
+ telemetry.tokens === null
71
+ ? locale === "pt-BR"
72
+ ? "Indisponível"
73
+ : "Unavailable"
74
+ : formatCompactNumber(telemetry.tokens, locale)
75
+ }
76
+ />
77
+ <Detail
78
+ label={locale === "pt-BR" ? "Custo" : "Cost"}
79
+ value={
80
+ telemetry.costBrl === null
81
+ ? locale === "pt-BR"
82
+ ? "Indisponível"
83
+ : "Unavailable"
84
+ : new Intl.NumberFormat(locale, { style: "currency", currency: "BRL" }).format(
85
+ telemetry.costBrl,
86
+ )
87
+ }
88
+ />
58
89
  <Detail label={copy.updated} value={formatDateTime(detail.task.updated_at, locale)} />
59
90
  </dl>
60
- <section>
61
- <h3>{copy.acceptanceCriteria}</h3>
62
- <div className="operations-tags">
63
- {detail.task.acceptance_ids.map((id) => (
64
- <span key={id}>{id}</span>
65
- ))}
66
- </div>
67
- </section>
68
- <section>
69
- <h3>{copy.decisions}</h3>
70
- {decisions.length === 0 ? (
71
- <p>{copy.noDecisions}</p>
72
- ) : (
73
- decisions.map((decision) => (
74
- <p key={decision.id}>
75
- <strong>{decision.origin}:</strong> {decision.title}
76
- </p>
77
- ))
78
- )}
79
- </section>
80
- <section>
81
- <h3>{copy.description}</h3>
82
- <pre>{detail.body}</pre>
83
- </section>
91
+ {!summary || detail.task.acceptance_ids.length > 0 ? (
92
+ <section>
93
+ <h3>{copy.acceptanceCriteria}</h3>
94
+ <div className="operations-tags">
95
+ {detail.task.acceptance_ids.map((id) => (
96
+ <span key={id}>{id}</span>
97
+ ))}
98
+ </div>
99
+ </section>
100
+ ) : null}
101
+ {!summary ? (
102
+ <section>
103
+ <h3>{copy.decisions}</h3>
104
+ {decisions.length === 0 ? (
105
+ <p>{copy.noDecisions}</p>
106
+ ) : (
107
+ decisions.map((decision) => (
108
+ <p key={decision.id}>
109
+ <strong>{decision.origin}:</strong> {decision.title}
110
+ </p>
111
+ ))
112
+ )}
113
+ </section>
114
+ ) : null}
115
+ {!summary && detail.body ? (
116
+ <section>
117
+ <h3>{copy.description}</h3>
118
+ <pre>{detail.body}</pre>
119
+ </section>
120
+ ) : null}
84
121
  </div>
85
122
  <footer>
86
- <span>{detail.artifact_path}</span>
123
+ {!summary && detail.artifact_path ? <span>{detail.artifact_path}</span> : null}
87
124
  <button onClick={() => onOpenTrace(detail.task.id)} type="button">
88
125
  {copy.openTraceability}
89
126
  </button>
@@ -94,6 +131,26 @@ export function TaskDetailsDialog({
94
131
  );
95
132
  }
96
133
 
134
+ function recoverExactTelemetry(runs: readonly OperationsProjection["runs"][number][]) {
135
+ const rootExecutionRuns = runs.filter(
136
+ (run) => run.phase === "execution" && run.parent_run_id == null,
137
+ );
138
+ return {
139
+ durationMs:
140
+ rootExecutionRuns.length === 0 || rootExecutionRuns.some((run) => operationalDurationMs(run) === null)
141
+ ? null
142
+ : rootExecutionRuns.reduce((total, run) => total + (operationalDurationMs(run) ?? 0), 0),
143
+ tokens:
144
+ runs.length === 0 || runs.some((run) => run.usage.total.tokens.total === null)
145
+ ? null
146
+ : runs.reduce((total, run) => total + (run.usage.total.tokens.total ?? 0), 0),
147
+ costBrl:
148
+ runs.length === 0 || runs.some((run) => run.usage.total.cost.brl === null)
149
+ ? null
150
+ : runs.reduce((total, run) => total + (run.usage.total.cost.brl ?? 0), 0),
151
+ };
152
+ }
153
+
97
154
  export function taskDetailsCopy(locale: OperationsLocale) {
98
155
  return locale === "pt-BR"
99
156
  ? {
@@ -0,0 +1,19 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { mergeManualWorkOrder, sortWorkItems } from "./UnifiedWorkBoard.js";
3
+
4
+ describe("UnifiedWorkBoard priority path", () => {
5
+ const item = (id: string, rank: number | null, createdAt = "2026-08-04T10:00:00.000Z") =>
6
+ ({ kind: "task", row: { id, manual_order: rank, updated_at: createdAt } }) as never;
7
+
8
+ it("uses optimistic ordering without a projection rebuild", () => {
9
+ const sorted = sortWorkItems([item("TASK-B", null), item("TASK-A", 0)], ["TASK-B", "TASK-A"]);
10
+ expect(sorted.map((entry) => entry.row.id)).toEqual(["TASK-B", "TASK-A"]);
11
+ });
12
+
13
+ it("only replaces slots in the moved column", () => {
14
+ const global = [item("PRD-1", 0), item("TASK-A", 1), item("TASK-B", 2)];
15
+ expect(
16
+ mergeManualWorkOrder(global, [global[1]!, global[2]!], [global[2]!, global[1]!]),
17
+ ).toEqual(["PRD-1", "TASK-B", "TASK-A"]);
18
+ });
19
+ });
@@ -13,6 +13,7 @@ import { formatCardCreatedAt } from "./format-card-created-at.js";
13
13
  import { formatRoundedDuration } from "./format-rounded-duration.js";
14
14
  import { MacroPlanningDialog } from "./MacroPlanningDialog.js";
15
15
  import { type OperationsLocale, riskLabel } from "./status-labels.js";
16
+ import { TaskDetailsDialog } from "./TaskDetailsDialog.js";
16
17
  import { taskTotals } from "./TaskBoard.js";
17
18
  import { taskOrigin } from "./task-origin.js";
18
19
  import { useCurrentTime } from "./use-current-time.js";
@@ -36,23 +37,39 @@ type WorkItem =
36
37
  | { kind: "prd" | "spec"; row: MacroProjection };
37
38
 
38
39
  export function UnifiedWorkBoard({
40
+ allPrds,
39
41
  allSpecs,
40
42
  allTasks,
43
+ boardTotals,
44
+ boardKindTotals,
45
+ boardStates,
41
46
  changes,
42
47
  locale,
43
48
  onOpenDocument,
44
49
  onOpenTask,
50
+ onPriorityChange,
51
+ onLoadMore,
52
+ onTypeChange,
45
53
  prds,
46
54
  runs,
47
55
  specs,
48
56
  tasks,
49
57
  }: {
58
+ allPrds: readonly MacroProjection[];
50
59
  allSpecs: readonly MacroProjection[];
51
60
  allTasks: readonly DashboardTaskProjection[];
61
+ boardTotals?: Partial<Record<WorkStage, number>> | undefined;
62
+ boardKindTotals?:
63
+ | Partial<Record<WorkStage, { all: number; task: number; prd: number; spec: number }>>
64
+ | undefined;
65
+ boardStates?: Partial<Record<WorkStage, { loading: boolean; error: string | null }>> | undefined;
52
66
  changes: readonly ChangeProjection[];
53
67
  locale: OperationsLocale;
54
68
  onOpenDocument: (kind: "prd" | "spec", id: string) => void;
55
69
  onOpenTask: (taskId: string) => Promise<boolean>;
70
+ onPriorityChange: (itemIds: readonly string[]) => Promise<void>;
71
+ onLoadMore?: ((stage: WorkStage) => void) | undefined;
72
+ onTypeChange?: ((value: WorkTypeFilter) => void) | undefined;
56
73
  prds: readonly MacroProjection[];
57
74
  runs: readonly RunProjection[];
58
75
  specs: readonly MacroProjection[];
@@ -62,18 +79,29 @@ export function UnifiedWorkBoard({
62
79
  const [typeFilter, setTypeFilter] = useState<WorkTypeFilter>("all");
63
80
  const [selectedStage, setSelectedStage] = useState<WorkStage | null>(null);
64
81
  const [selectedMacro, setSelectedMacro] = useState<MacroProjection | null>(null);
82
+ const [selectedTask, setSelectedTask] = useState<DashboardTaskProjection | null>(null);
65
83
  const [query, setQuery] = useState("");
66
- const totalsByTask = useMemo(() => taskTotals(runs, tasks), [runs, tasks]);
67
- const items = useMemo(
84
+ const [draggedId, setDraggedId] = useState<string | null>(null);
85
+ const [optimisticOrder, setOptimisticOrder] = useState<readonly string[] | null>(null);
86
+ // Card telemetry comes from the compact per-Task projection. Do not scan the
87
+ // complete Run collection when a card opens; absent compact telemetry remains
88
+ // unavailable instead of being reconstructed from a partial page of Runs.
89
+ const totalsByTask = useMemo(() => taskTotals([], tasks), [tasks]);
90
+ const allItems = useMemo(
68
91
  () =>
69
92
  sortWorkItems(
70
93
  [
71
- ...prds.map((row): WorkItem => ({ kind: "prd", row })),
72
- ...specs.map((row): WorkItem => ({ kind: "spec", row })),
73
- ...tasks.map((row): WorkItem => ({ kind: "task", row })),
74
- ].filter((item) => isWorkItemVisible(item, typeFilter)),
94
+ ...allPrds.map((row): WorkItem => ({ kind: "prd", row })),
95
+ ...allSpecs.map((row): WorkItem => ({ kind: "spec", row })),
96
+ ...allTasks.map((row): WorkItem => ({ kind: "task", row })),
97
+ ],
98
+ optimisticOrder,
75
99
  ),
76
- [prds, specs, tasks, typeFilter],
100
+ [allPrds, allSpecs, allTasks, optimisticOrder],
101
+ );
102
+ const items = useMemo(
103
+ () => allItems.filter((item) => isWorkItemVisible(item, typeFilter)),
104
+ [allItems, typeFilter],
77
105
  );
78
106
  const progressByMacro = useMemo(
79
107
  () =>
@@ -88,12 +116,19 @@ export function UnifiedWorkBoard({
88
116
  : items.filter((item) => itemStage(item, allTasks) === selectedStage);
89
117
  const openItem = (item: WorkItem) => {
90
118
  setSelectedStage(null);
91
- if (item.kind === "task") void onOpenTask(item.row.id);
119
+ if (item.kind === "task") setSelectedTask(item.row);
92
120
  else setSelectedMacro(item.row);
93
121
  };
94
122
  return (
95
123
  <section className="operations-unified-work">
96
- <WorkTypeFilters locale={locale} onChange={setTypeFilter} value={typeFilter} />
124
+ <WorkTypeFilters
125
+ locale={locale}
126
+ onChange={(value) => {
127
+ setTypeFilter(value);
128
+ onTypeChange?.(value);
129
+ }}
130
+ value={typeFilter}
131
+ />
97
132
  <section
98
133
  aria-label={locale === "pt-BR" ? "Kanban de trabalho" : "Work Kanban"}
99
134
  className="operations-board operations-work-board"
@@ -103,6 +138,7 @@ export function UnifiedWorkBoard({
103
138
  return (
104
139
  <WorkColumn
105
140
  changes={changes}
141
+ globalItems={allItems}
106
142
  items={rows}
107
143
  key={stage}
108
144
  locale={locale}
@@ -111,9 +147,30 @@ export function UnifiedWorkBoard({
111
147
  setQuery("");
112
148
  setSelectedStage(stage);
113
149
  }}
150
+ onLoadMore={onLoadMore === undefined ? undefined : () => onLoadMore(stage)}
114
151
  onOpenItem={openItem}
152
+ onPriorityChange={async (nextOrder) => {
153
+ const previous = optimisticOrder;
154
+ setOptimisticOrder(nextOrder);
155
+ try {
156
+ await onPriorityChange(nextOrder);
157
+ } catch {
158
+ setOptimisticOrder(previous);
159
+ }
160
+ }}
161
+ onDragEnd={() => setDraggedId(null)}
162
+ onDragStart={setDraggedId}
163
+ draggedId={draggedId}
115
164
  progressByMacro={progressByMacro}
116
165
  stage={stage}
166
+ totalItems={
167
+ typeFilter === "all"
168
+ ? (boardKindTotals?.[stage]?.all ?? boardTotals?.[stage] ?? rows.length)
169
+ : typeFilter === "task" || typeFilter === "prd" || typeFilter === "spec"
170
+ ? (boardKindTotals?.[stage]?.[typeFilter] ?? rows.length)
171
+ : rows.length
172
+ }
173
+ state={boardStates?.[stage]}
117
174
  totalsByTask={totalsByTask}
118
175
  />
119
176
  );
@@ -146,10 +203,31 @@ export function UnifiedWorkBoard({
146
203
  tasks={allTasks}
147
204
  />
148
205
  ) : null}
206
+ {selectedTask ? (
207
+ <TaskDetailsDialog
208
+ detail={{ task: selectedTask, body: "", artifact_path: selectedTask.artifact_path }}
209
+ locale={locale}
210
+ onClose={() => setSelectedTask(null)}
211
+ onOpenTrace={(taskId) => {
212
+ setSelectedTask(null);
213
+ void onOpenTask(taskId);
214
+ }}
215
+ operations={{ decisions: [], runs }}
216
+ summary
217
+ summaryRunCount={exactTaskRunCount(selectedTask)}
218
+ />
219
+ ) : null}
149
220
  </section>
150
221
  );
151
222
  }
152
223
 
224
+ function exactTaskRunCount(task: DashboardTaskProjection): number | null {
225
+ const runCount = (task as DashboardTaskProjection & { run_count?: unknown }).run_count;
226
+ return typeof runCount === "number" && Number.isInteger(runCount) && runCount >= 0
227
+ ? runCount
228
+ : null;
229
+ }
230
+
153
231
  export function WorkTypeFilters({
154
232
  locale,
155
233
  onChange,
@@ -197,26 +275,46 @@ export function WorkTypeFilters({
197
275
 
198
276
  function WorkColumn({
199
277
  changes,
278
+ globalItems,
200
279
  items,
280
+ totalItems,
281
+ state,
201
282
  locale,
202
283
  nowMs,
203
284
  onOpenColumn,
285
+ onLoadMore,
204
286
  onOpenItem,
287
+ onPriorityChange,
288
+ onDragEnd,
289
+ onDragStart,
290
+ draggedId,
205
291
  progressByMacro,
206
292
  stage,
207
293
  totalsByTask,
208
294
  }: {
209
295
  changes: readonly ChangeProjection[];
296
+ globalItems: readonly WorkItem[];
210
297
  items: readonly WorkItem[];
298
+ totalItems: number;
299
+ state: { loading: boolean; error: string | null } | undefined;
211
300
  locale: OperationsLocale;
212
301
  nowMs: number;
213
302
  onOpenColumn: () => void;
303
+ onLoadMore?: (() => void) | undefined;
214
304
  onOpenItem: (item: WorkItem) => void;
305
+ onPriorityChange: (itemIds: readonly string[]) => Promise<void>;
306
+ onDragEnd: () => void;
307
+ onDragStart: (id: string) => void;
308
+ draggedId: string | null;
215
309
  progressByMacro: ReadonlyMap<string, MacroWorkProgress>;
216
310
  stage: WorkStage;
217
311
  totalsByTask: ReturnType<typeof taskTotals>;
218
312
  }) {
219
- const { hasMore, sentinelRef, visibleCount } = useInfiniteColumn(items.length);
313
+ const { hasMore, sentinelRef, visibleCount } = useInfiniteColumn(
314
+ items.length,
315
+ totalItems,
316
+ onLoadMore,
317
+ );
220
318
  return (
221
319
  <article className={`operations-column is-${stage}`}>
222
320
  <header>
@@ -224,16 +322,16 @@ function WorkColumn({
224
322
  {workStageLabel(stage, locale)}
225
323
  </button>
226
324
  <button
227
- aria-label={`${items.length} — ${workStageLabel(stage, locale)}`}
325
+ aria-label={`${totalItems} — ${workStageLabel(stage, locale)}`}
228
326
  className="operations-column-count"
229
327
  onClick={onOpenColumn}
230
328
  type="button"
231
329
  >
232
- {items.length}
330
+ {totalItems}
233
331
  </button>
234
332
  </header>
235
333
  <div className="operations-column-body">
236
- {items.slice(0, visibleCount).map((item) => (
334
+ {items.slice(0, visibleCount).map((item, index) => (
237
335
  <WorkCard
238
336
  changes={changes}
239
337
  item={item}
@@ -241,17 +339,52 @@ function WorkColumn({
241
339
  locale={locale}
242
340
  nowMs={nowMs}
243
341
  onOpen={() => onOpenItem(item)}
342
+ onMove={(direction) => {
343
+ const next = index + direction;
344
+ if (next < 0 || next >= items.length) return;
345
+ const reordered = [...items];
346
+ [reordered[index], reordered[next]] = [reordered[next]!, reordered[index]!];
347
+ void onPriorityChange(mergeManualWorkOrder(globalItems, items, reordered));
348
+ }}
349
+ onDrop={() => {
350
+ const from = items.findIndex((candidate) => candidate.row.id === draggedId);
351
+ if (from < 0 || from === index) return;
352
+ const reordered = [...items];
353
+ const [moved] = reordered.splice(from, 1);
354
+ if (moved === undefined) return;
355
+ reordered.splice(index, 0, moved);
356
+ void onPriorityChange(mergeManualWorkOrder(globalItems, items, reordered));
357
+ }}
358
+ onDragEnd={onDragEnd}
359
+ onDragStart={() => onDragStart(item.row.id)}
360
+ order={index + 1}
244
361
  progress={progressByMacro.get(item.row.id)}
245
362
  stage={stage}
246
363
  totalsByTask={totalsByTask}
247
364
  />
248
365
  ))}
249
- {items.length === 0 ? (
366
+ {items.length === 0 && !state?.loading ? (
250
367
  <p className="operations-empty">{locale === "pt-BR" ? "Sem itens" : "No items"}</p>
251
368
  ) : null}
252
369
  {hasMore ? (
253
- <div className="operations-infinite-sentinel" ref={sentinelRef}>
254
- {visibleCount} de {items.length} · carregando mais…
370
+ <div
371
+ aria-live="polite"
372
+ className="operations-infinite-sentinel"
373
+ ref={sentinelRef}
374
+ role={state?.error ? "alert" : "status"}
375
+ >
376
+ {state?.error ? (
377
+ <>
378
+ <span>{state.error}</span>
379
+ <button onClick={onLoadMore} type="button">
380
+ Tentar novamente
381
+ </button>
382
+ </>
383
+ ) : state?.loading ? (
384
+ "Carregando mais…"
385
+ ) : (
386
+ `${visibleCount} de ${totalItems} · carregando mais…`
387
+ )}
255
388
  </div>
256
389
  ) : null}
257
390
  </div>
@@ -265,6 +398,11 @@ function WorkCard({
265
398
  locale,
266
399
  nowMs,
267
400
  onOpen,
401
+ onMove,
402
+ onDrop,
403
+ onDragEnd,
404
+ onDragStart,
405
+ order,
268
406
  progress,
269
407
  stage,
270
408
  totalsByTask,
@@ -274,6 +412,11 @@ function WorkCard({
274
412
  locale: OperationsLocale;
275
413
  nowMs: number;
276
414
  onOpen: () => void;
415
+ onMove: (direction: -1 | 1) => void;
416
+ onDrop: () => void;
417
+ onDragEnd: () => void;
418
+ onDragStart: () => void;
419
+ order: number;
277
420
  progress: MacroWorkProgress | undefined;
278
421
  stage: WorkStage;
279
422
  totalsByTask: ReturnType<typeof taskTotals>;
@@ -288,19 +431,64 @@ function WorkCard({
288
431
  ? [macro.duration_ms, macro.usage.total.tokens.total, macro.usage.total.cost.brl]
289
432
  : [totals?.durationMs ?? null, totals?.tokens ?? null, totals?.costBrl ?? null];
290
433
  return (
291
- <button
434
+ <article
292
435
  className={`operations-task-card operations-work-card is-kind-${origin}`}
293
- onClick={onOpen}
294
- type="button"
436
+ draggable={stage === "ready"}
437
+ onDragEnd={stage === "ready" ? onDragEnd : undefined}
438
+ onDragOver={stage === "ready" ? (event) => event.preventDefault() : undefined}
439
+ onDragStart={stage === "ready" ? onDragStart : undefined}
440
+ onDrop={
441
+ stage === "ready"
442
+ ? (event) => {
443
+ event.preventDefault();
444
+ onDrop();
445
+ }
446
+ : undefined
447
+ }
295
448
  >
296
- <span className={`operations-work-kind is-${item.kind}`}>{kindLabel}</span>
297
- <span className={`operations-work-status is-${stage}`}>
298
- {workStageBadgeLabel(stage, locale)}
299
- </span>
300
- {task ? (
301
- <span className={`operations-risk is-${task.risk}`}>{riskLabel(task.risk, locale)}</span>
449
+ <button
450
+ aria-label={openWorkCardLabel(locale, item.row.title)}
451
+ className="operations-work-card-open"
452
+ onClick={onOpen}
453
+ type="button"
454
+ >
455
+ {stage === "ready" ? (
456
+ <span className="operations-work-card-first-line">
457
+ <span className="operations-work-order">#{order}</span>
458
+ </span>
459
+ ) : null}
460
+ <span className={`operations-work-kind is-${item.kind}`}>{kindLabel}</span>
461
+ {order === 1 && stage === "ready" ? (
462
+ <span className="operations-work-next">Próximo</span>
463
+ ) : null}
464
+ {stage !== "ready" ? (
465
+ <span className={`operations-work-status is-${stage}`}>
466
+ {workStageBadgeLabel(stage, locale)}
467
+ </span>
468
+ ) : null}
469
+ {task ? (
470
+ <span className={`operations-risk is-${task.risk}`}>{riskLabel(task.risk, locale)}</span>
471
+ ) : null}
472
+ <strong title={item.row.title}>{item.row.title}</strong>
473
+ </button>
474
+ {stage === "ready" ? (
475
+ <div className="operations-work-reorder">
476
+ <button
477
+ aria-label={locale === "pt-BR" ? "Mover acima" : "Move up"}
478
+ onClick={() => onMove(-1)}
479
+ type="button"
480
+ >
481
+ ↑
482
+ </button>
483
+ <button
484
+ aria-label={locale === "pt-BR" ? "Mover abaixo" : "Move down"}
485
+ onClick={() => onMove(1)}
486
+ type="button"
487
+ >
488
+ ↓
489
+ </button>
490
+ </div>
302
491
  ) : null}
303
- <strong title={item.row.title}>{item.row.title}</strong>
304
492
  <small title={item.row.id}>{item.row.id}</small>
305
493
  {item.row.created_at ? (
306
494
  <small className="operations-card-created">
@@ -343,7 +531,25 @@ function WorkCard({
343
531
  </div>
344
532
  ))}
345
533
  </dl>
346
- </button>
534
+ </article>
535
+ );
536
+ }
537
+
538
+ export function openWorkCardLabel(locale: OperationsLocale, title: string): string {
539
+ return locale === "pt-BR" ? `Abrir ${title}` : `Open ${title}`;
540
+ }
541
+
542
+ /** Replaces only visible-column slots, preserving the global order of all other work. */
543
+ export function mergeManualWorkOrder(
544
+ globalItems: readonly WorkItem[],
545
+ previousColumn: readonly WorkItem[],
546
+ reorderedColumn: readonly WorkItem[],
547
+ ): string[] {
548
+ const columnIds = new Set(previousColumn.map((item) => item.row.id));
549
+ const reorderedIds = reorderedColumn.map((item) => item.row.id);
550
+ let cursor = 0;
551
+ return globalItems.map((item) =>
552
+ columnIds.has(item.row.id) ? (reorderedIds[cursor++] ?? item.row.id) : item.row.id,
347
553
  );
348
554
  }
349
555
 
@@ -448,18 +654,33 @@ function itemStage(item: WorkItem, tasks: readonly DashboardTaskProjection[]): W
448
654
  return item.kind === "task" ? taskWorkStage(item.row) : macroWorkStage(item.row, tasks);
449
655
  }
450
656
 
451
- function sortWorkItems(items: WorkItem[]): WorkItem[] {
452
- const priorityOrder = { urgent: 0, high: 1, medium: 2, low: 3 } as const;
657
+ export function sortWorkItems(
658
+ items: WorkItem[],
659
+ optimisticOrder: readonly string[] | null = null,
660
+ ): WorkItem[] {
661
+ const optimisticRanks =
662
+ optimisticOrder === null ? null : new Map(optimisticOrder.map((id, index) => [id, index]));
453
663
  return items.sort(
454
664
  (left, right) =>
455
- workItemTimestamp(right).localeCompare(workItemTimestamp(left)) ||
456
- String(itemStage(left, [])).localeCompare(String(itemStage(right, []))) ||
457
- (left.kind === "task" ? priorityOrder[left.row.priority] : 4) -
458
- (right.kind === "task" ? priorityOrder[right.row.priority] : 4) ||
459
- right.row.id.localeCompare(left.row.id),
665
+ compareManualOrder(
666
+ optimisticRanks?.get(left.row.id) ?? left.row.manual_order,
667
+ optimisticRanks?.get(right.row.id) ?? right.row.manual_order,
668
+ ) ||
669
+ workItemTimestamp(left).localeCompare(workItemTimestamp(right)) ||
670
+ left.row.id.localeCompare(right.row.id),
460
671
  );
461
672
  }
462
673
 
674
+ function compareManualOrder(
675
+ left: number | null | undefined,
676
+ right: number | null | undefined,
677
+ ): number {
678
+ if (left != null && right != null) return left - right;
679
+ if (left != null) return -1;
680
+ if (right != null) return 1;
681
+ return 0;
682
+ }
683
+
463
684
  function workItemTimestamp(item: WorkItem): string {
464
685
  return item.kind === "task"
465
686
  ? item.row.updated_at