@zaip-ai/cli 1.0.8 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) 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 +2 -2
  5. package/dist/services/agent-adapters.js.map +1 -1
  6. package/dist/services/agent-adapters.test.js +5 -0
  7. package/dist/services/agent-adapters.test.js.map +1 -1
  8. package/dist/services/logger.test.js +2 -2
  9. package/dist/services/runtime-template.test.js +6 -6
  10. package/dist/services/template-manifest.d.ts.map +1 -1
  11. package/dist/services/template-manifest.js +5 -0
  12. package/dist/services/template-manifest.js.map +1 -1
  13. package/package.json +1 -1
  14. package/templates/.agents/architecture/software-architecture.md +131 -0
  15. package/templates/.agents/branding/brandbook.docx +0 -0
  16. package/templates/.agents/branding/brandbook.md +60 -0
  17. package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
  18. package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -1
  19. package/templates/.agents/dashboard/.tmp-run-list.json +254 -0
  20. package/templates/.agents/dashboard/.zaip-managed.json +252 -136
  21. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-Z60df2r-.js → CostCalculationGuidePage-DxR_pgSV.js} +1 -1
  22. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-4jZLTWE_.js +2156 -0
  23. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Coc6pA-1.js → PricingSettingsDialog-CKcsqb-r.js} +1 -1
  24. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BomxqCBU.css +1 -0
  25. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-DmmJD2Th.js +3 -0
  26. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BwtitWa_.js +1 -0
  27. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-N5Csr0RP.js +68 -0
  28. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DFBuc_qp.js → icons-vendor-C0fj2uU9.js} +1 -1
  29. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-C4aIB1PV.js +2 -0
  30. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CCQOHdVI.js → react-vendor-BEsJ-FYH.js} +1 -1
  31. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-pC2_0J8x.js → traceability-B6y6Gw12.js} +1 -1
  32. package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
  33. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  34. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +204 -32
  35. package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +11 -11
  36. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +14 -7
  37. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +4 -2
  38. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +3 -1
  39. package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +14 -11
  40. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +19 -4
  41. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +24 -2
  42. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +22 -1
  43. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +3 -1
  44. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +36 -26
  45. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +2 -2
  46. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +40 -6
  47. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +39 -1
  48. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +89 -23
  49. package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +219 -29
  50. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +61 -7
  51. package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +3 -6
  52. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +2 -2
  53. package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +3 -4
  54. package/templates/.agents/dashboard/apps/frontend/vite.config.ts +4 -1
  55. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  56. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +89 -19
  57. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +31 -16
  58. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +43 -14
  59. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +5 -5
  60. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +1 -1
  61. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +67 -42
  62. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +115 -39
  63. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +188 -38
  64. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +75 -17
  65. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +147 -58
  66. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +5 -2
  67. package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +2 -2
  68. package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +2 -1
  69. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +18 -7
  70. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +95 -9
  71. package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +29 -17
  72. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +0 -24
  73. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +225 -424
  74. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +24 -15
  75. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +6 -1
  76. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-monitor-projection-agents.test.ts +31 -0
  77. package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-summary-projection-duration.test.ts +414 -0
  78. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  79. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +26 -23
  80. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +31 -11
  81. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +3 -1
  82. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +51 -21
  83. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +47 -5
  84. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +1 -4
  85. package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +32 -10
  86. package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +9 -3
  87. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +13 -5
  88. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +12 -4
  89. package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +1 -4
  90. package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +1 -2
  91. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +385 -4
  92. package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +481 -61
  93. package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +14 -1
  94. package/templates/.agents/dashboard/modules/operations/src/react/export/xlsx-runtime-e2e.test.ts +248 -0
  95. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +4 -4
  96. package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +6 -4
  97. package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +4 -1
  98. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +1 -1
  99. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +1 -1
  100. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +46 -6
  101. package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +1 -4
  102. package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +82 -6
  103. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +2 -1
  104. package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +1 -1
  105. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +19 -7
  106. package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +4 -1
  107. package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +11 -5
  108. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  109. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  110. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  111. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  112. package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
  113. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  114. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +152 -149
  115. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs.metafile.json +7333 -0
  116. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +149 -146
  117. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  118. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +15 -7
  119. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +44 -13
  120. package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +5 -2
  121. package/templates/.agents/dashboard/packages/local-runtime/scripts/source-size-runtime-scripts/sqlite-read-model-fixture.mjs +397 -0
  122. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +472 -145
  123. package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +15 -3
  124. package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +129 -31
  125. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +153 -150
  126. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +6 -2
  127. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +3 -3
  128. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +55 -16
  129. package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +23 -13
  130. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +19 -4
  131. package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +7 -3
  132. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +132 -9
  133. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +126 -60
  134. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +16 -2
  135. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +1861 -350
  136. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +1218 -352
  137. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +119 -42
  138. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +45 -20
  139. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  140. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  141. package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +7 -5
  142. package/templates/.agents/design/.zaip-managed.json +3 -3
  143. package/templates/.agents/design/apps/catalog/package.json +1 -1
  144. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  145. package/templates/.agents/growth/estrategia-bootstrap-90-dias.md +169 -0
  146. package/templates/.agents/growth/strategy.md +27 -0
  147. package/templates/.agents/marketing/estrategia-marketing-zaip-90-dias.md +197 -0
  148. package/templates/.agents/marketing/strategy.md +29 -0
  149. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  150. package/templates/.agents/requirements/comparative-audit.md +1 -1
  151. package/templates/.agents/requirements/context-engine.md +1 -1
  152. package/templates/.agents/requirements/cost-observability.md +1 -1
  153. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  154. package/templates/.agents/requirements/data-export.md +1 -1
  155. package/templates/.agents/requirements/design-system.md +1 -1
  156. package/templates/.agents/requirements/execution-engine.md +1 -1
  157. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  158. package/templates/.agents/requirements/model-orchestration.md +1 -1
  159. package/templates/.agents/requirements/public-distribution.md +1 -1
  160. package/templates/.agents/requirements/software-architecture.md +1 -1
  161. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  162. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  163. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  164. package/templates/.agents/runtime/VERSION +1 -1
  165. package/templates/.agents/runtime/bin/zaip.mjs +30 -29
  166. package/templates/.agents/runtime/checksums.sha256 +6 -6
  167. package/templates/.agents/runtime/manifest.json +1 -1
  168. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  169. package/templates/.agents/runtime/provenance.json +5 -5
  170. package/templates/.agents/runtime/sbom.cdx.json +3 -3
  171. package/templates/.agents/sales/playbook.md +32 -0
  172. package/templates/.agents/sales/roteiro-comercial-zaip.md +252 -0
  173. package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
  174. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +9 -2
  175. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-framework.md +39 -0
  176. package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +1 -1
  177. package/templates/.agents/skills/zaip-skill-enforce-architecture/SKILL.md +2 -0
  178. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +6 -0
  179. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +6 -0
  180. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +39 -82
  181. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +13 -8
  182. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +44 -14
  183. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +19 -9
  184. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +29 -5
  185. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +77 -0
  186. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +6 -0
  187. package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +28 -5
  188. package/templates/.agents/zaip-aios/INDEX.md +10 -0
  189. package/templates/.agents/zaip-aios/README.md +2 -1
  190. package/templates/.agents/zaip-aios/VERSION +1 -1
  191. package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +76 -0
  192. package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +72 -0
  193. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +330 -0
  194. package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +52 -0
  195. package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +69 -0
  196. package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +483 -0
  197. package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +85 -0
  198. package/templates/.agents/zaip-aios/guides/25-fontes-de-precos-openai.md +18 -0
  199. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +44 -0
  200. package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +167 -0
  201. package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +144 -0
  202. package/templates/.agents/zaip-aios/guides/assets/diagrams/lifecycles-task-spec-prd.png +0 -0
  203. package/templates/.agents/zaip-aios/guides/assets/diagrams/prd-lifecycle.png +0 -0
  204. package/templates/.agents/zaip-aios/guides/assets/diagrams/spec-lifecycle.png +0 -0
  205. package/templates/.agents/zaip-aios/guides/assets/diagrams/task-lifecycle.png +0 -0
  206. package/templates/template-manifest.json +313 -177
  207. package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-Cs6dzDmW.js +0 -1505
  208. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +0 -1
  209. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +0 -3
  210. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +0 -1
  211. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +0 -68
  212. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +0 -2
@@ -24,14 +24,11 @@ import {
24
24
  classifyTraceDocument,
25
25
  timestampsFromContent,
26
26
  } from "@zaip-ai/dashboard-traceability/server";
27
- import type {
28
- TaskTrace,
29
- TraceDocument,
30
- } from "../../../modules/traceability/src/contracts.js";
31
27
  import { type CompactRunMetric, LifecycleManifestStore } from "@zaip-ai/lifecycle-manifests";
32
28
  import { type Context, Hono } from "hono";
33
29
  import { getCookie, setCookie } from "hono/cookie";
34
30
  import type { ContentfulStatusCode } from "hono/utils/http-status";
31
+ import type { TaskTrace, TraceDocument } from "../../../modules/traceability/src/contracts.js";
35
32
  import { runAgentAdapterSync } from "./agent-adapter-sync.js";
36
33
  import {
37
34
  type AgentAdapterSyncResult,
@@ -39,7 +36,11 @@ import {
39
36
  persistAgentCatalogUpdate,
40
37
  readAgentCatalogSettings,
41
38
  } from "./agent-catalog-settings.js";
42
- import { persistProjectSettings, readProjectOverview, readProjectSettings } from "./project-settings.js";
39
+ import {
40
+ persistProjectSettings,
41
+ readProjectOverview,
42
+ readProjectSettings,
43
+ } from "./project-settings.js";
43
44
  import {
44
45
  type BoardClassification,
45
46
  boardFilters,
@@ -264,7 +265,7 @@ async function buildFirstFoldQuickProjection(
264
265
  const aggregate =
265
266
  filter.from === null && filter.to === null
266
267
  ? filesystem.firstFoldViewportAllTime().aggregate
267
- : cachedMonthlyQuick?.aggregate ?? filesystem.firstFoldAggregate(filter);
268
+ : (cachedMonthlyQuick?.aggregate ?? filesystem.firstFoldAggregate(filter));
268
269
  return {
269
270
  ...projection,
270
271
  summary: {
@@ -314,10 +315,12 @@ function buildSqliteOperationsProjection(
314
315
  const tasks = includeEntities ? page("task") : [];
315
316
  const specs = includeEntities ? page("spec") : [];
316
317
  const prds = includeEntities ? page("prd") : [];
317
- const aggregate = allTime?.aggregate ?? cachedMonthlyQuick?.aggregate ?? filesystem.firstFoldAggregate(filter);
318
+ const aggregate =
319
+ allTime?.aggregate ?? cachedMonthlyQuick?.aggregate ?? filesystem.firstFoldAggregate(filter);
318
320
  const taskCount = allTime?.aggregate.task_count ?? tasks.length;
319
321
  const allTimeTopTasks =
320
- filter.from === null && filter.to === null &&
322
+ filter.from === null &&
323
+ filter.to === null &&
321
324
  (fullAllTime !== null || options.includeTopTasks === true)
322
325
  ? (fullAllTime?.top_tasks ?? filesystem.firstFoldTopTasksAllTime())
323
326
  : null;
@@ -334,7 +337,7 @@ function buildSqliteOperationsProjection(
334
337
  const macroMetrics =
335
338
  fullAllTime === null
336
339
  ? undefined
337
- : Object.fromEntries(
340
+ : (Object.fromEntries(
338
341
  (["specs", "prds"] as const).map((kind) => {
339
342
  const metric = fullAllTime.macro_metrics[kind];
340
343
  return [
@@ -368,7 +371,7 @@ function buildSqliteOperationsProjection(
368
371
  }),
369
372
  ) as NonNullable<
370
373
  NonNullable<OperationsProjection["summary"]["overview_metrics"]>["macro_metrics"]
371
- >;
374
+ >);
372
375
  const statuses: Record<string, number> = allTime?.task_status_counts ?? {};
373
376
  const risks: Record<string, number> = allTime?.task_risk_counts ?? {};
374
377
  if (allTime === null) {
@@ -535,8 +538,7 @@ function buildSqliteOperationsProjection(
535
538
  task_completion_rate:
536
539
  taskCount === 0
537
540
  ? 0
538
- : (allTime?.aggregate.completed_task_count ?? statuses.completed ?? 0) /
539
- taskCount,
541
+ : (allTime?.aggregate.completed_task_count ?? statuses.completed ?? 0) / taskCount,
540
542
  terminal_runs: 0,
541
543
  successful_runs: 0,
542
544
  terminal_success_rate: 0,
@@ -647,7 +649,8 @@ function buildSqliteTaskTrace(
647
649
  ): TaskTrace {
648
650
  const initial = filesystem.canonicalTraceFiles([taskId]);
649
651
  const taskFile = initial.find(
650
- (row) => row.path.includes("/.agents/records/tasks/") || row.path.includes(".agents/records/tasks/"),
652
+ (row) =>
653
+ row.path.includes("/.agents/records/tasks/") || row.path.includes(".agents/records/tasks/"),
651
654
  );
652
655
  if (taskFile === undefined) throw new Error(`Canonical Task ${taskId} was not found`);
653
656
  const scalar = (key: string): string | null => {
@@ -667,8 +670,7 @@ function buildSqliteTaskTrace(
667
670
  const documents = filesystem
668
671
  .canonicalTraceFiles(markers)
669
672
  .filter(
670
- (row) =>
671
- /\.(?:md|json|jsonl|txt|log)$/i.test(row.path) && row.content.length <= 250_000,
673
+ (row) => /\.(?:md|json|jsonl|txt|log)$/i.test(row.path) && row.content.length <= 250_000,
672
674
  )
673
675
  .map((row) => {
674
676
  const classification = classifyTraceDocument(row.path);
@@ -677,9 +679,7 @@ function buildSqliteTaskTrace(
677
679
  id: createHash("sha256").update(row.path).digest("hex").slice(0, 16),
678
680
  path: row.path,
679
681
  title:
680
- row.content.match(/^#\s+(.+)$/m)?.[1]?.trim() ??
681
- row.path.split("/").at(-1) ??
682
- row.path,
682
+ row.content.match(/^#\s+(.+)$/m)?.[1]?.trim() ?? row.path.split("/").at(-1) ?? row.path,
683
683
  ...classification,
684
684
  content: row.content,
685
685
  ...timestamps,
@@ -742,10 +742,17 @@ export function createDashboardApp(
742
742
  const snapshotState = options.snapshotState ?? "current";
743
743
  const canonicalFilesystem = options.canonicalFilesystem ?? new WorkspaceFileSystem(workspaceRoot);
744
744
  const reconcileOpen = options.reconcileOpenWork ?? reconcileOpenWork;
745
- const refreshReadModel = options.refreshReadModel ?? (async () => {
746
- if (!isSqliteSnapshot) return;
747
- await filesystem.rebuildAndRefresh(() => rebuildSqliteReadModel(workspaceRoot));
748
- });
745
+ const refreshReadModel =
746
+ options.refreshReadModel ??
747
+ (async () => {
748
+ if (!isSqliteSnapshot) return;
749
+ // Explicit user refreshes must replace the immutable generation with the
750
+ // current canonical records. Keep stale-seed fallback exclusively for
751
+ // startup warmth, never for this visible convergence request.
752
+ await filesystem.rebuildAndRefresh(() =>
753
+ rebuildSqliteReadModel(workspaceRoot, { forceCanonical: true }),
754
+ );
755
+ });
749
756
  const workspaceKey = dashboardWorkspaceKey(workspaceRoot);
750
757
  const syncAgentAdapters = options.syncAgentAdapters ?? (() => runAgentAdapterSync(workspaceRoot));
751
758
  let catalogWriteTail = Promise.resolve();
@@ -764,7 +771,8 @@ export function createDashboardApp(
764
771
  // so retain their expensive board projection until an explicit refresh
765
772
  // clears this map rather than expiring it on the short snapshot TTL.
766
773
  if (
767
- !fresh && cached !== undefined &&
774
+ !fresh &&
775
+ cached !== undefined &&
768
776
  (key.startsWith("operations:board:") || Date.now() - cached.cachedAt < SNAPSHOT_CACHE_TTL_MS)
769
777
  )
770
778
  return cached.payload as T;
@@ -794,6 +802,16 @@ export function createDashboardApp(
794
802
  aggregatePayloads.clear();
795
803
  aggregateInFlight.clear();
796
804
  };
805
+ let projectionRefreshInFlight: Promise<void> | null = null;
806
+ const rebuildProjection = async () => {
807
+ if (projectionRefreshInFlight !== null) return projectionRefreshInFlight;
808
+ projectionRefreshInFlight = refreshReadModel()
809
+ .then(() => clearSnapshotCache())
810
+ .finally(() => {
811
+ projectionRefreshInFlight = null;
812
+ });
813
+ return projectionRefreshInFlight;
814
+ };
797
815
  const readSnapshot = (context: Context) => {
798
816
  const key = snapshotKey(context);
799
817
  const cached = cachedSnapshots.get(key);
@@ -807,7 +825,8 @@ export function createDashboardApp(
807
825
  return pending;
808
826
  }
809
827
  context.header("X-ZAIP-Snapshot-Cache", "miss");
810
- const inFlight = readLayout().then((layout) => dashboardSnapshot(filesystem, workspaceRoot, context, layout))
828
+ const inFlight = readLayout()
829
+ .then((layout) => dashboardSnapshot(filesystem, workspaceRoot, context, layout))
811
830
  .then((snapshot) => {
812
831
  cachedSnapshots.set(key, { snapshot, cachedAt: Date.now() });
813
832
  return snapshot;
@@ -850,13 +869,15 @@ export function createDashboardApp(
850
869
  // CLI. It does not mutate the disposable SQLite read model, so it remains
851
870
  // available while the dashboard serves a read-only snapshot.
852
871
  const reconcileWrite =
853
- context.req.method === "POST" &&
854
- context.req.path === `${API_PREFIX}/reconcile-open-work`;
872
+ context.req.method === "POST" && context.req.path === `${API_PREFIX}/reconcile-open-work`;
873
+ const projectionRefreshWrite =
874
+ context.req.method === "POST" && context.req.path === `${API_PREFIX}/refresh-projection`;
855
875
  if (
856
876
  context.req.method !== "GET" &&
857
877
  context.req.method !== "HEAD" &&
858
878
  !settingsWrite &&
859
- !reconcileWrite
879
+ !reconcileWrite &&
880
+ !projectionRefreshWrite
860
881
  ) {
861
882
  context.header(
862
883
  "Allow",
@@ -868,7 +889,9 @@ export function createDashboardApp(
868
889
  ? "GET, HEAD, PUT"
869
890
  : context.req.path === `${API_PREFIX}/reconcile-open-work`
870
891
  ? "POST"
871
- : "GET, HEAD",
892
+ : context.req.path === `${API_PREFIX}/refresh-projection`
893
+ ? "POST"
894
+ : "GET, HEAD",
872
895
  );
873
896
  return context.json({ error: "Dashboard API is read-only" }, 405);
874
897
  }
@@ -976,7 +999,13 @@ export function createDashboardApp(
976
999
  try {
977
1000
  const requestStartedAt = performance.now();
978
1001
  const scope = context.req.query("scope");
979
- if (scope !== "overview" && scope !== "quick" && scope !== "detail" && scope !== "board" && scope !== "classification")
1002
+ if (
1003
+ scope !== "overview" &&
1004
+ scope !== "quick" &&
1005
+ scope !== "detail" &&
1006
+ scope !== "board" &&
1007
+ scope !== "classification"
1008
+ )
980
1009
  return headOrJson(context, (await readSnapshot(context)).operations);
981
1010
  const layout = await readLayout();
982
1011
  const layoutMs = performance.now() - requestStartedAt;
@@ -988,52 +1017,80 @@ export function createDashboardApp(
988
1017
  50,
989
1018
  Math.max(1, Number.parseInt(context.req.query("limit") ?? "10", 10) || 10),
990
1019
  );
991
- const board = await readAggregate(`operations:board:${from ?? ""}:${to ?? ""}`, async () => {
992
- const projection = await buildFirstFoldQuickProjection(
993
- filesystem,
994
- layout,
995
- { from, to },
996
- { includeBoardTasks: true },
997
- );
998
- return {
999
- projection,
1000
- priority: await readWorkPriority(canonicalFilesystem, knownWorkIds(projection)),
1001
- };
1002
- });
1020
+ const board = await readAggregate(
1021
+ `operations:board:${from ?? ""}:${to ?? ""}`,
1022
+ async () => {
1023
+ const projection = await buildFirstFoldQuickProjection(
1024
+ filesystem,
1025
+ layout,
1026
+ { from, to },
1027
+ { includeBoardTasks: true },
1028
+ );
1029
+ return {
1030
+ projection,
1031
+ priority: await readWorkPriority(canonicalFilesystem, knownWorkIds(projection)),
1032
+ };
1033
+ },
1034
+ );
1003
1035
  const filters = boardFilters(context);
1004
1036
  const pageKey = JSON.stringify({ from, to, stage, offset, limit, ...filters });
1005
1037
  const page = await readAggregate(`operations:board-page:${pageKey}`, async () =>
1006
1038
  boardPage(board.projection, stage, offset, limit, board.priority.item_ids, filters),
1007
1039
  );
1008
- return headOrJson(
1009
- context,
1010
- page,
1011
- 200,
1012
- true,
1013
- );
1040
+ return headOrJson(context, page, 200, true);
1014
1041
  }
1015
1042
  if (scope === "classification") {
1016
1043
  const kind = context.req.query("kind");
1017
1044
  const classification = context.req.query("classification");
1018
1045
  if (kind !== "task" && kind !== "spec" && kind !== "prd")
1019
1046
  return headOrJson(context, { error: "A valid work kind is required" }, 400);
1020
- if (!['lite', 'standard', 'critical', 'empty', 'structured', 'rework'].includes(classification ?? ''))
1047
+ if (
1048
+ !["lite", "standard", "critical", "empty", "structured", "rework"].includes(
1049
+ classification ?? "",
1050
+ )
1051
+ )
1021
1052
  return headOrJson(context, { error: "A valid classification is required" }, 400);
1022
1053
  const offset = Math.max(0, Number.parseInt(context.req.query("offset") ?? "0", 10) || 0);
1023
- const limit = Math.min(50, Math.max(1, Number.parseInt(context.req.query("limit") ?? "50", 10) || 50));
1024
- const projection = await readAggregate(`operations:classification:${from ?? ""}:${to ?? ""}`, () =>
1025
- buildFirstFoldQuickProjection(filesystem, layout, { from, to }, { includeBoardTasks: true }),
1054
+ const limit = Math.min(
1055
+ 50,
1056
+ Math.max(1, Number.parseInt(context.req.query("limit") ?? "50", 10) || 50),
1057
+ );
1058
+ const projection = await readAggregate(
1059
+ `operations:classification:${from ?? ""}:${to ?? ""}`,
1060
+ () =>
1061
+ buildFirstFoldQuickProjection(
1062
+ filesystem,
1063
+ layout,
1064
+ { from, to },
1065
+ { includeBoardTasks: true },
1066
+ ),
1067
+ );
1068
+ return headOrJson(
1069
+ context,
1070
+ classificationPage(
1071
+ projection,
1072
+ kind,
1073
+ classification as BoardClassification,
1074
+ offset,
1075
+ limit,
1076
+ ),
1077
+ 200,
1078
+ true,
1026
1079
  );
1027
- return headOrJson(context, classificationPage(projection, kind, classification as BoardClassification, offset, limit), 200, true);
1028
1080
  }
1029
1081
  if (scope === "quick") {
1030
1082
  const projectionStartedAt = performance.now();
1031
1083
  const quick = await readAggregate(
1032
1084
  `operations:quick:${from ?? ""}:${to ?? ""}`,
1033
1085
  () =>
1034
- buildFirstFoldQuickProjection(filesystem, layout, { from, to }, {
1035
- includeTopTasks: from === null && to === null,
1036
- }),
1086
+ buildFirstFoldQuickProjection(
1087
+ filesystem,
1088
+ layout,
1089
+ { from, to },
1090
+ {
1091
+ includeTopTasks: from === null && to === null,
1092
+ },
1093
+ ),
1037
1094
  context.req.query("fresh") === "1",
1038
1095
  );
1039
1096
  if (
@@ -1046,8 +1103,7 @@ export function createDashboardApp(
1046
1103
  [
1047
1104
  `layout;dur=${Math.round(layoutMs * 10) / 10}`,
1048
1105
  `projection;dur=${Math.round((performance.now() - projectionStartedAt) * 10) / 10}`,
1049
- ...Object.entries(timings)
1050
- .map(([name, duration]) => `${name};dur=${duration}`)
1106
+ ...Object.entries(timings).map(([name, duration]) => `${name};dur=${duration}`),
1051
1107
  ].join(", "),
1052
1108
  );
1053
1109
  }
@@ -1242,8 +1298,7 @@ export function createDashboardApp(
1242
1298
  // canonical records, then atomically rebuild and reopen the snapshot
1243
1299
  // before the response exposes fresh projections.
1244
1300
  const reconciledIds = await reconcileOpen(canonicalFilesystem, workspaceRoot);
1245
- await refreshReadModel();
1246
- clearSnapshotCache();
1301
+ await rebuildProjection();
1247
1302
  return context.json({
1248
1303
  ...(await readSnapshot(context)),
1249
1304
  reconciliation: reconciledIds,
@@ -1254,6 +1309,17 @@ export function createDashboardApp(
1254
1309
  }
1255
1310
  });
1256
1311
 
1312
+ app.post(`${API_PREFIX}/refresh-projection`, async (context) => {
1313
+ try {
1314
+ await readLayout();
1315
+ await rebuildProjection();
1316
+ return context.json(await readSnapshot(context));
1317
+ } catch (error) {
1318
+ if (error instanceof V2WorkspaceRequiredError) throw error;
1319
+ return context.json({ error: error instanceof Error ? error.message : String(error) }, 400);
1320
+ }
1321
+ });
1322
+
1257
1323
  app.on(["GET", "HEAD"], `${API_PREFIX}/cost-monitor`, async (context) => {
1258
1324
  try {
1259
1325
  const scope = context.req.query("scope") ?? "summary";
@@ -1535,7 +1601,7 @@ async function dashboardSnapshot(
1535
1601
  context: Context,
1536
1602
  cachedLayout?: WorkspaceLayout,
1537
1603
  ) {
1538
- const layout = cachedLayout ?? await requireV2Layout(filesystem);
1604
+ const layout = cachedLayout ?? (await requireV2Layout(filesystem));
1539
1605
  const { from, to } = projectionPeriodFilter(context);
1540
1606
  const currency = selectedCurrency(context);
1541
1607
  const operations =
@@ -110,7 +110,14 @@ export const SQLITE_VIEW_CONTRACTS = [
110
110
  ],
111
111
  ["cost_monitor_zaip_agents", "cost-monitor", canonicalRunMetrics, "agent totals", "offset", xlsx],
112
112
  ["cost_monitor_models", "cost-monitor", canonicalRunMetrics, "model totals", "offset", xlsx],
113
- ["cost_monitor_providers", "cost-monitor", canonicalRunMetrics, "provider totals", "offset", xlsx],
113
+ [
114
+ "cost_monitor_providers",
115
+ "cost-monitor",
116
+ canonicalRunMetrics,
117
+ "provider totals",
118
+ "offset",
119
+ xlsx,
120
+ ],
114
121
  ["cost_monitor_tasks", "cost-monitor", canonicalRunMetrics, "task totals", "offset", xlsx],
115
122
  ["cost_monitor_specs", "cost-monitor", canonicalRunMetrics, "SPEC totals", "offset", xlsx],
116
123
  ["cost_monitor_prds", "cost-monitor", canonicalRunMetrics, "PRD totals", "offset", xlsx],
@@ -171,7 +178,14 @@ export const SQLITE_VIEW_CONTRACTS = [
171
178
  "offset",
172
179
  xlsx,
173
180
  ],
174
- ["operations_daily", "operations", canonicalRunMetrics, "daily operations totals", "offset", xlsx],
181
+ [
182
+ "operations_daily",
183
+ "operations",
184
+ canonicalRunMetrics,
185
+ "daily operations totals",
186
+ "offset",
187
+ xlsx,
188
+ ],
175
189
  [
176
190
  "operations_monthly",
177
191
  "operations",