@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
@@ -0,0 +1,248 @@
1
+ import { readdirSync } from "node:fs";
2
+ import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { describe, expect, it } from "vitest";
6
+ // `exceljs` exposes this Node-specific entrypoint without a declaration file.
7
+ // The runtime export test needs the Node loader rather than ExcelJS's browser build.
8
+ // @ts-expect-error TS7016: upstream package omits declarations for `exceljs.nodejs.js`.
9
+ import ExcelJS from "../../../../../packages/data-export/node_modules/exceljs/lib/exceljs.nodejs.js";
10
+ import {
11
+ createExportSnapshot,
12
+ exportSnapshotToXlsxParts,
13
+ } from "../../../../../packages/data-export/src/index.js";
14
+ import {
15
+ AGENT_INVOCATION_EXPORT_COLUMNS,
16
+ CHANGE_EXPORT_COLUMNS,
17
+ COMPACT_LIFECYCLE_EXPORT_COLUMNS,
18
+ CONVERSATION_EXPORT_COLUMNS,
19
+ COST_GROUP_EXPORT_COLUMNS,
20
+ DECISION_EXPORT_COLUMNS,
21
+ EXECUTION_EXPORT_COLUMNS,
22
+ exportAgentInvocationRows,
23
+ exportCompactLifecycleRows,
24
+ exportConversationRows,
25
+ exportCostGroupRows,
26
+ exportExecutionRows,
27
+ exportRowsWithDurationHours,
28
+ exportWorkRows,
29
+ PERIOD_EXPORT_COLUMNS,
30
+ WORK_EXPORT_COLUMNS,
31
+ } from "./ExcelExportAction.js";
32
+
33
+ type Row = Record<string, unknown>;
34
+ type Mapper = (rows: readonly Row[]) => Row[];
35
+ type Case = { name: string; view: string; headers: readonly string[]; map: Mapper };
36
+ const enabled = process.env.ZAIP_E2E_XLSX_EXPORTS === "1";
37
+ const cases: readonly Case[] = [
38
+ {
39
+ name: "cost-daily",
40
+ view: "cost_monitor_daily",
41
+ headers: PERIOD_EXPORT_COLUMNS,
42
+ map: exportRowsWithDurationHours,
43
+ },
44
+ {
45
+ name: "cost-monthly",
46
+ view: "cost_monitor_monthly",
47
+ headers: PERIOD_EXPORT_COLUMNS,
48
+ map: exportRowsWithDurationHours,
49
+ },
50
+ {
51
+ name: "cost-annual",
52
+ view: "cost_monitor_annual",
53
+ headers: PERIOD_EXPORT_COLUMNS,
54
+ map: exportRowsWithDurationHours,
55
+ },
56
+ {
57
+ name: "cost-executions",
58
+ view: "cost_monitor_executions",
59
+ headers: COMPACT_LIFECYCLE_EXPORT_COLUMNS,
60
+ map: exportCompactLifecycleRows,
61
+ },
62
+ {
63
+ name: "cost-agent-calls",
64
+ view: "cost_monitor_agent_invocations",
65
+ headers: AGENT_INVOCATION_EXPORT_COLUMNS,
66
+ map: exportAgentInvocationRows,
67
+ },
68
+ {
69
+ name: "cost-tasks",
70
+ view: "cost_monitor_tasks",
71
+ headers: COMPACT_LIFECYCLE_EXPORT_COLUMNS,
72
+ map: exportCompactLifecycleRows,
73
+ },
74
+ {
75
+ name: "cost-specs",
76
+ view: "cost_monitor_specs",
77
+ headers: COMPACT_LIFECYCLE_EXPORT_COLUMNS,
78
+ map: exportCompactLifecycleRows,
79
+ },
80
+ {
81
+ name: "cost-prds",
82
+ view: "cost_monitor_prds",
83
+ headers: COMPACT_LIFECYCLE_EXPORT_COLUMNS,
84
+ map: exportCompactLifecycleRows,
85
+ },
86
+ {
87
+ name: "cost-conversations",
88
+ view: "cost_monitor_conversations",
89
+ headers: COMPACT_LIFECYCLE_EXPORT_COLUMNS,
90
+ map: exportCompactLifecycleRows,
91
+ },
92
+ {
93
+ name: "cost-agents",
94
+ view: "cost_monitor_zaip_agents",
95
+ headers: COST_GROUP_EXPORT_COLUMNS,
96
+ map: exportCostGroupRows,
97
+ },
98
+ {
99
+ name: "cost-models",
100
+ view: "cost_monitor_models",
101
+ headers: COST_GROUP_EXPORT_COLUMNS,
102
+ map: exportCostGroupRows,
103
+ },
104
+ {
105
+ name: "cost-providers",
106
+ view: "cost_monitor_providers",
107
+ headers: COST_GROUP_EXPORT_COLUMNS,
108
+ map: exportCostGroupRows,
109
+ },
110
+ {
111
+ name: "operations-work-list",
112
+ view: "operations_work_list",
113
+ headers: WORK_EXPORT_COLUMNS,
114
+ map: exportWorkRows,
115
+ },
116
+ {
117
+ name: "operations-work-kanban",
118
+ view: "operations_work_kanban",
119
+ headers: WORK_EXPORT_COLUMNS,
120
+ map: exportWorkRows,
121
+ },
122
+ {
123
+ name: "operations-executions",
124
+ view: "operations_executions",
125
+ headers: EXECUTION_EXPORT_COLUMNS,
126
+ map: exportExecutionRows,
127
+ },
128
+ {
129
+ name: "operations-runs",
130
+ view: "operations_agent_invocations",
131
+ headers: AGENT_INVOCATION_EXPORT_COLUMNS,
132
+ map: exportAgentInvocationRows,
133
+ },
134
+ {
135
+ name: "operations-conversations",
136
+ view: "operations_conversations",
137
+ headers: CONVERSATION_EXPORT_COLUMNS,
138
+ map: exportConversationRows,
139
+ },
140
+ {
141
+ name: "operations-changes",
142
+ view: "operations_changes",
143
+ headers: CHANGE_EXPORT_COLUMNS,
144
+ map: (rows) =>
145
+ rows.map((row) =>
146
+ Object.fromEntries(CHANGE_EXPORT_COLUMNS.map((key) => [key, row[key] ?? null])),
147
+ ),
148
+ },
149
+ {
150
+ name: "operations-decisions",
151
+ view: "operations_decisions",
152
+ headers: DECISION_EXPORT_COLUMNS,
153
+ map: (rows) =>
154
+ rows.map((row) =>
155
+ Object.fromEntries(DECISION_EXPORT_COLUMNS.map((key) => [key, row[key] ?? null])),
156
+ ),
157
+ },
158
+ {
159
+ name: "operations-daily",
160
+ view: "operations_daily",
161
+ headers: PERIOD_EXPORT_COLUMNS,
162
+ map: exportRowsWithDurationHours,
163
+ },
164
+ {
165
+ name: "operations-monthly",
166
+ view: "operations_monthly",
167
+ headers: PERIOD_EXPORT_COLUMNS,
168
+ map: exportRowsWithDurationHours,
169
+ },
170
+ {
171
+ name: "operations-annual",
172
+ view: "operations_annual",
173
+ headers: PERIOD_EXPORT_COLUMNS,
174
+ map: exportRowsWithDurationHours,
175
+ },
176
+ ];
177
+
178
+ describe.skipIf(!enabled)("runtime XLSX exports", () => {
179
+ it("writes and reopens every eligible XLSX with rows and no wholly empty column", async () => {
180
+ const root = join(tmpdir(), "zaip-aios");
181
+ const sessionPaths = await Promise.all(
182
+ readdirSync(root)
183
+ .filter((name) => name.startsWith("dashboard-sqlite-"))
184
+ .map(async (name) => {
185
+ const path = join(root, name, "dashboard-sqlite-session.json");
186
+ return { path, modified: (await stat(path).catch(() => null))?.mtimeMs ?? 0 };
187
+ }),
188
+ );
189
+ const sessionPath = sessionPaths.sort((left, right) => right.modified - left.modified)[0]?.path;
190
+ expect(sessionPath).toBeDefined();
191
+ const session = JSON.parse(await readFile(sessionPath!, "utf8")) as {
192
+ port: number;
193
+ token: string;
194
+ };
195
+ const output = join(process.cwd(), "..", "..", "..", "..", ".local", "dashboard-export-e2e");
196
+ await mkdir(output, { recursive: true });
197
+ for (const item of cases) {
198
+ const source: Row[] = [];
199
+ for (let offset = 0; ; ) {
200
+ const response = await fetch(
201
+ `http://127.0.0.1:${session.port}/api/v2/sqlite-views?view=${item.view}&offset=${offset}&limit=100`,
202
+ { headers: { "x-zaip-session": session.token } },
203
+ );
204
+ expect(response.ok, item.view).toBe(true);
205
+ const page = (await response.json()) as { rows: Row[]; total_count: number };
206
+ source.push(...page.rows);
207
+ offset += page.rows.length;
208
+ if (offset >= page.total_count) break;
209
+ expect(page.rows.length, `${item.view} pagination`).toBeGreaterThan(0);
210
+ }
211
+ const rows = item.map(source);
212
+ const chunks: Uint8Array[] = [];
213
+ await exportSnapshotToXlsxParts({
214
+ snapshot: createExportSnapshot({
215
+ id: item.name,
216
+ createdAt: new Date().toISOString(),
217
+ view: item.name,
218
+ filters: {},
219
+ totalRows: rows.length,
220
+ pages: async function* () {
221
+ yield rows;
222
+ },
223
+ }),
224
+ headers: item.headers,
225
+ writable: () => ({
226
+ ready: Promise.resolve(),
227
+ write: async (chunk) => {
228
+ chunks.push(chunk);
229
+ },
230
+ close: async () => {},
231
+ }),
232
+ });
233
+ const path = join(output, `${item.name}.xlsx`);
234
+ await writeFile(path, Buffer.concat(chunks.map((chunk) => Buffer.from(chunk))));
235
+ const workbook = new ExcelJS.Workbook();
236
+ await workbook.xlsx.load(await readFile(path));
237
+ expect(workbook.worksheets[0]?.rowCount, item.name).toBe(rows.length + 1);
238
+ const empty = item.headers.filter(
239
+ (header) =>
240
+ rows.length > 0 &&
241
+ rows.every(
242
+ (row) => row[header] === null || row[header] === undefined || row[header] === "",
243
+ ),
244
+ );
245
+ expect(empty, `${item.name} columns`).toEqual([]);
246
+ }
247
+ }, 120_000);
248
+ });
@@ -2,8 +2,8 @@ import { describe, expect, it } from "vitest";
2
2
  import {
3
3
  displayedDuration,
4
4
  elapsedDurationMs,
5
- formatLifecycleElapsedDuration,
6
5
  formatDisplayedDuration,
6
+ formatLifecycleElapsedDuration,
7
7
  formatOperationDuration,
8
8
  operationalDurationMs,
9
9
  terminalLifecycleElapsedDurationMs,
@@ -68,9 +68,9 @@ describe("formatOperationDuration", () => {
68
68
  });
69
69
  expect(running).toEqual({ durationMs: null, provenance: "in_progress" });
70
70
  expect(formatDisplayedDuration(running, "pt-BR")).toBe("Em andamento");
71
- expect(
72
- formatDisplayedDuration({ durationMs: null, provenance: "unavailable" }, "pt-BR"),
73
- ).toBe("Sem atribuição temporal");
71
+ expect(formatDisplayedDuration({ durationMs: null, provenance: "unavailable" }, "pt-BR")).toBe(
72
+ "Sem atribuição temporal",
73
+ );
74
74
  });
75
75
 
76
76
  it("keeps terminal lifecycle elapsed separate from observed duration and never uses now", () => {
@@ -39,16 +39,18 @@ export function formatDisplayedDuration(
39
39
  value: { durationMs: number | null; provenance: DurationPresentationProvenance },
40
40
  locale: OperationsLocale,
41
41
  ): string {
42
- if (value.provenance === "in_progress") return locale === "pt-BR" ? "Em andamento" : "In progress";
42
+ if (value.provenance === "in_progress")
43
+ return locale === "pt-BR" ? "Em andamento" : "In progress";
43
44
  if (value.durationMs === null || value.provenance === "unavailable")
44
45
  return locale === "pt-BR" ? "Sem atribuição temporal" : "No temporal attribution";
45
46
  return formatOperationDuration(value.durationMs, locale);
46
47
  }
47
48
 
48
49
  /** Presentation-only terminal lifecycle fallback; never analytical telemetry. */
49
- export function displayedDuration(
50
- run: OperationalTiming & { status?: string },
51
- ): { durationMs: number | null; provenance: DurationPresentationProvenance } {
50
+ export function displayedDuration(run: OperationalTiming & { status?: string }): {
51
+ durationMs: number | null;
52
+ provenance: DurationPresentationProvenance;
53
+ } {
52
54
  const factual = operationalDurationMs(run);
53
55
  if (factual !== null) return { durationMs: factual, provenance: "factual" };
54
56
  if (run.status === "running") return { durationMs: null, provenance: "in_progress" };
@@ -4,7 +4,10 @@ import { describe, expect, it } from "vitest";
4
4
  const source = readFileSync(new URL("OperationsPage.tsx", import.meta.url), "utf8");
5
5
  const globalFilterPanel = source.slice(
6
6
  source.indexOf('<div className="operations-global-filters"'),
7
- source.indexOf("filtersActive={Boolean(", source.indexOf('<div className="operations-global-filters"')),
7
+ source.indexOf(
8
+ "filtersActive={Boolean(",
9
+ source.indexOf('<div className="operations-global-filters"'),
10
+ ),
8
11
  );
9
12
 
10
13
  describe("Operations global filters", () => {
@@ -96,7 +96,7 @@ describe("overview period filter", () => {
96
96
  expect(app).toContain('currency === "USD" ? run.estimated_usd : run.estimated_brl');
97
97
  expect(app).toContain("resolveRunCost={");
98
98
  expect(app).toContain('if (currency !== "USD" || costs?.currency === currency) return;');
99
- expect(app).toContain('void loadCostSummary();');
99
+ expect(app).toContain("void loadCostSummary();");
100
100
  });
101
101
 
102
102
  it("loads the quick overview first while retaining the detail hydration fallback", () => {
@@ -22,6 +22,6 @@ describe("OperationsOverview status cards", () => {
22
22
  expect(source).toContain("onLoadMore(items.length)");
23
23
  expect(source).toContain('aria-busy="true"');
24
24
  expect(source).toContain('role="alert"');
25
- expect(source).toContain("Nenhum${kind === \"task\" ? \"a\" : \"\"}");
25
+ expect(source).toContain('Nenhum${kind === "task" ? "a" : ""}');
26
26
  });
27
27
  });
@@ -1,5 +1,9 @@
1
1
  import type { ReactNode } from "react";
2
- import type { DashboardTaskProjection, MacroProjection, OperationsProjection } from "../contracts.js";
2
+ import type {
3
+ DashboardTaskProjection,
4
+ MacroProjection,
5
+ OperationsProjection,
6
+ } from "../contracts.js";
3
7
  import type { OperationDatePreset, OperationDateRange } from "./operation-date-range.js";
4
8
  import type { OperationsView } from "./operations-page-filters.js";
5
9
  import type { OperationsLocale } from "./status-labels.js";
@@ -12,7 +16,13 @@ export interface DashboardGlobalFilters {
12
16
  }
13
17
 
14
18
  export type OverviewStatusKind = "task" | "spec" | "prd";
15
- export type OverviewClassification = "lite" | "standard" | "critical" | "empty" | "structured" | "rework";
19
+ export type OverviewClassification =
20
+ | "lite"
21
+ | "standard"
22
+ | "critical"
23
+ | "empty"
24
+ | "structured"
25
+ | "rework";
16
26
 
17
27
  /** A remounted Trabalho (Lista) selector always starts on "all". */
18
28
  export function workListTypeOnViewChange(nextView: OperationsView): WorkTypeFilter | null {
@@ -33,7 +43,10 @@ export interface OperationsPageProps {
33
43
  alternateContent?: ReactNode | ((filters: DashboardGlobalFilters) => ReactNode);
34
44
  boardTotals?: Partial<Record<WorkStage, number>>;
35
45
  boardKindTotals?: Partial<
36
- Record<WorkStage, { all: number; task: number; prd: number; spec: number }>
46
+ Record<
47
+ WorkStage,
48
+ { all: number; task: number; "standalone-task": number; prd: number; spec: number }
49
+ >
37
50
  >;
38
51
  boardStates?: Partial<Record<WorkStage, { loading: boolean; error: string | null }>>;
39
52
  /** Immutable, filtered board snapshot supplied by the composition root for XLSX. */
@@ -48,6 +61,23 @@ export interface OperationsPageProps {
48
61
  pages: () => AsyncGenerator<readonly Record<string, unknown>[]>;
49
62
  }>;
50
63
  };
64
+ /** Immutable, filtered full table collection for every Operations XLSX view. */
65
+ detailExportSource?: (
66
+ view: OperationsView,
67
+ filters: {
68
+ query: string;
69
+ status: string;
70
+ risk: string;
71
+ origin: string;
72
+ },
73
+ ) =>
74
+ | {
75
+ prepare: () => Promise<{
76
+ totalRows: number;
77
+ pages: () => AsyncGenerator<readonly Record<string, unknown>[]>;
78
+ }>;
79
+ }
80
+ | undefined;
51
81
  capabilityNavigation: ReactNode;
52
82
  data: OperationsProjection;
53
83
  dashboardTitle?: string;
@@ -115,9 +145,19 @@ export interface OperationsPageProps {
115
145
  */
116
146
  factualCostTotal?: number | null | undefined;
117
147
  /** Factual Cost Monitor rows matching the active global period. */
118
- factualCostPeriods?: Partial<
119
- Record<"day" | "month" | "year", readonly { key: string; estimated_usd: number | null; estimated_brl: number | null }[]>
120
- > | undefined;
148
+ factualCostPeriods?:
149
+ | Partial<
150
+ Record<
151
+ "day" | "month" | "year",
152
+ readonly {
153
+ key: string;
154
+ estimated_usd: number | null;
155
+ estimated_brl: number | null;
156
+ duration_ms: number | null;
157
+ }[]
158
+ >
159
+ >
160
+ | undefined;
121
161
  }
122
162
 
123
163
  /** Single-source period contract for App-controlled Operations navigation. */
@@ -25,10 +25,7 @@ describe("operations tab navigation", () => {
25
25
  });
26
26
 
27
27
  it("uses the simplified Portuguese labels", () => {
28
- const labels = readFileSync(
29
- new URL("operations-view-labels.ts", import.meta.url),
30
- "utf8",
31
- );
28
+ const labels = readFileSync(new URL("operations-view-labels.ts", import.meta.url), "utf8");
32
29
 
33
30
  expect(labels).toContain('"work-kanban": "Visão de Quadro (Kanban)"');
34
31
  expect(labels).toContain('"work-list": "Visão de Lista"');
@@ -2,7 +2,13 @@ import { describe, expect, it } from "vitest";
2
2
  import { LEGACY_EFFORT_SNAPSHOT } from "../contracts.js";
3
3
  import { executionMetricTotals } from "./execution-metrics.js";
4
4
  import { exportRowsWithDurationHours } from "./export/ExcelExportAction.js";
5
- import { applyFactualPeriodCosts, formatPeriod, periodTotalDurationMs } from "./PeriodSummaryTable.js";
5
+ import { factualDurationRowsForExport } from "./OperationsPage.js";
6
+ import {
7
+ applyFactualPeriodCosts,
8
+ applyFactualPeriodDurations,
9
+ formatPeriod,
10
+ periodTotalDurationMs,
11
+ } from "./PeriodSummaryTable.js";
6
12
  import {
7
13
  aggregateManifestPeriodSummary,
8
14
  aggregatePeriodSummary,
@@ -48,11 +54,9 @@ const data = {
48
54
  describe("aggregatePeriodSummary", () => {
49
55
  it("uses factual compact USD periods when aggregate-only transport has no Runs", () => {
50
56
  expect(
51
- applyFactualPeriodCosts(
52
- [{ key: "2026-08", costBrl: null }],
53
- "USD",
54
- [{ key: "2026-08", estimated_usd: 8.7, estimated_brl: 47.5 }],
55
- ),
57
+ applyFactualPeriodCosts([{ key: "2026-08", costBrl: null }], "USD", [
58
+ { key: "2026-08", estimated_usd: 8.7, estimated_brl: 47.5 },
59
+ ]),
56
60
  ).toEqual([{ key: "2026-08", costBrl: 8.7 }]);
57
61
  });
58
62
 
@@ -106,6 +110,78 @@ describe("aggregatePeriodSummary", () => {
106
110
  expect(augustOnly[0]?.durationMs).toBe(14_353_554);
107
111
  });
108
112
 
113
+ it("fills only unavailable monthly duration from factual Cost Monitor rows", () => {
114
+ expect(
115
+ applyFactualPeriodDurations(
116
+ [
117
+ { key: "2026-08", durationMs: null },
118
+ { key: "2026-07", durationMs: null },
119
+ { key: "2026-06", durationMs: 1_800_000 },
120
+ ],
121
+ [
122
+ { key: "2026-08", duration_ms: 3_600_000 },
123
+ { key: "2026-07", duration_ms: 7_200_000 },
124
+ { key: "2026-06", duration_ms: 9_000_000 },
125
+ ],
126
+ ),
127
+ ).toEqual([
128
+ { key: "2026-08", durationMs: 3_600_000 },
129
+ { key: "2026-07", durationMs: 7_200_000 },
130
+ { key: "2026-06", durationMs: 1_800_000 },
131
+ ]);
132
+ expect(
133
+ applyFactualPeriodDurations(
134
+ [{ key: "2026-05", durationMs: null }],
135
+ [{ key: "2026-05", duration_ms: null }],
136
+ ),
137
+ ).toEqual([{ key: "2026-05", durationMs: null }]);
138
+ });
139
+
140
+ it("keeps annual period durations factual and leaves unavailable annual facts null", () => {
141
+ expect(
142
+ applyFactualPeriodDurations(
143
+ [
144
+ { key: "2026", durationMs: null },
145
+ { key: "2025", durationMs: null },
146
+ ],
147
+ [
148
+ { key: "2026", duration_ms: 619_958_763 },
149
+ { key: "2025", duration_ms: null },
150
+ ],
151
+ ),
152
+ ).toEqual([
153
+ { key: "2026", durationMs: 619_958_763 },
154
+ { key: "2025", durationMs: null },
155
+ ]);
156
+ });
157
+
158
+ it("uses the OperationsPage annual export bridge, not a raw alias mapper", () => {
159
+ const rows = factualDurationRowsForExport(
160
+ "year",
161
+ [
162
+ {
163
+ key: "2026",
164
+ prds: 0,
165
+ specs: 0,
166
+ tasks: 0,
167
+ tasksCreated: 0,
168
+ tasksActive: 0,
169
+ taskDaysActive: 0,
170
+ runs: 0,
171
+ tests: 0,
172
+ evidences: 0,
173
+ durationMs: null,
174
+ tokens: null,
175
+ costBrl: null,
176
+ },
177
+ ],
178
+ [{ key: "2026", duration_ms: 619_958_763 }],
179
+ );
180
+ expect(exportRowsWithDurationHours(rows as unknown as Record<string, unknown>[])).toEqual([
181
+ expect.objectContaining({ key: "2026", duration_hours: 172.2107675 }),
182
+ ]);
183
+ });
184
+
109
185
  it("keeps the period summary and export on observed source duration only", () => {
110
186
  const usage = { total: { tokens: { total: null }, cost: { brl: null } } };
111
187
  const runs = [
@@ -148,9 +148,10 @@ describe("unified work board stages", () => {
148
148
  expect(isWorkItemVisible({ kind: "task", row: { spec_id: "SPEC-1" } }, "all")).toBe(true);
149
149
  });
150
150
 
151
- it("shows every Task separately only in the Tasks filter", () => {
151
+ it("separates linked Tasks from standalone Tasks", () => {
152
152
  const nestedTask = { kind: "task", row: { spec_id: "SPEC-1" } } as const;
153
153
  expect(isWorkItemVisible(nestedTask, "task")).toBe(true);
154
+ expect(isWorkItemVisible({ kind: "task", row: { spec_id: null } }, "task")).toBe(false);
154
155
  expect(isWorkItemVisible(nestedTask, "spec")).toBe(false);
155
156
  expect(isWorkItemVisible(nestedTask, "prd")).toBe(false);
156
157
  expect(isWorkItemVisible({ kind: "spec", row: { parent_id: "PRD-1" } }, "spec")).toBe(true);
@@ -20,7 +20,7 @@ export interface MacroWorkProgress {
20
20
  }
21
21
 
22
22
  export function isWorkItemVisible(item: WorkItemIdentity, typeFilter: WorkTypeFilter): boolean {
23
- if (typeFilter === "task") return item.kind === "task";
23
+ if (typeFilter === "task") return item.kind === "task" && item.row.spec_id !== null;
24
24
  if (typeFilter === "standalone-task") return item.kind === "task" && item.row.spec_id === null;
25
25
  if (typeFilter !== "all") return item.kind === typeFilter;
26
26
  return true;
@@ -145,16 +145,28 @@ describe("executionRelationshipCounts", () => {
145
145
  {
146
146
  id: "EXEC-PROJECTED",
147
147
  origin: { type: "task", task_id: "TASK-1" },
148
- dag: { nodes: [{ task_id: "TASK-1", change_id: "CHG-1", depends_on: [] }], topological_order: ["TASK-1"] },
148
+ dag: {
149
+ nodes: [{ task_id: "TASK-1", change_id: "CHG-1", depends_on: [] }],
150
+ topological_order: ["TASK-1"],
151
+ },
149
152
  },
150
153
  {
151
- runs: [{
152
- agent: "agent-orchestrator", call_count: 1, duration_ms: 60_000,
153
- duration_provenance: "reconciled", execution_id: "EXEC-PROJECTED", parent_run_id: null,
154
- run_purpose: "orchestration", status: "completed", task_id: "TASK-1",
155
- }],
154
+ runs: [
155
+ {
156
+ agent: "agent-orchestrator",
157
+ call_count: 1,
158
+ duration_ms: 60_000,
159
+ duration_provenance: "reconciled",
160
+ execution_id: "EXEC-PROJECTED",
161
+ parent_run_id: null,
162
+ run_purpose: "orchestration",
163
+ status: "completed",
164
+ task_id: "TASK-1",
165
+ },
166
+ ],
156
167
  tasks: [{ id: "TASK-1", change_id: "CHG-1" }],
157
- changes: [{ id: "CHG-1", source: { type: "task" } }], specs: [],
168
+ changes: [{ id: "CHG-1", source: { type: "task" } }],
169
+ specs: [],
158
170
  },
159
171
  );
160
172
  expect(counts.duration_ms).toBe(60_000);
@@ -34,7 +34,10 @@ export function executionRelationshipCounts(
34
34
  | "status"
35
35
  | "task_id"
36
36
  > & { usage?: Pick<RunProjection["usage"]["total"], "tokens" | "cost"> } & Partial<
37
- Pick<RunProjection, "duration_provenance" | "finished_at" | "source_duration_ms" | "started_at">
37
+ Pick<
38
+ RunProjection,
39
+ "duration_provenance" | "finished_at" | "source_duration_ms" | "started_at"
40
+ >
38
41
  >)[];
39
42
  tasks: readonly { id: string; change_id: string }[];
40
43
  changes: readonly {
@@ -215,9 +215,14 @@ export function dailyTaskProjection(
215
215
  title: row.title ?? row.id,
216
216
  short_name: row.id,
217
217
  objective: "",
218
- status: (status === "draft" || status === "planned" || status === "executing" ||
219
- status === "verifying" || status === "completed" || status === "failed" ||
220
- status === "blocked" || status === "cancelled"
218
+ status: (status === "draft" ||
219
+ status === "planned" ||
220
+ status === "executing" ||
221
+ status === "verifying" ||
222
+ status === "completed" ||
223
+ status === "failed" ||
224
+ status === "blocked" ||
225
+ status === "cancelled"
221
226
  ? status
222
227
  : "draft") as OperationsProjection["tasks"][number]["status"],
223
228
  attempt_count: status === "planned" || status === "draft" ? 0 : null,
@@ -232,8 +237,9 @@ export function dailyTaskProjection(
232
237
  write_scopes: [],
233
238
  created_at: row.occurred_at,
234
239
  updated_at: row.window_at ?? row.occurred_at,
235
- started_at: status === "executing" || status === "verifying" || terminal ? row.occurred_at : null,
236
- finished_at: terminal ? row.window_at ?? row.occurred_at : null,
240
+ started_at:
241
+ status === "executing" || status === "verifying" || terminal ? row.occurred_at : null,
242
+ finished_at: terminal ? (row.window_at ?? row.occurred_at) : null,
237
243
  result: null,
238
244
  artifact_path: "",
239
245
  progress: terminal ? 1 : 0,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-traceability",
3
- "version": "1.0.8",
3
+ "version": "1.3.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-branding",
3
- "version": "1.0.8",
3
+ "version": "1.3.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,7 +1,7 @@
1
1
  export const dashboardBrand = {
2
2
  productName: "ZAIP-AIOS",
3
3
  dashboardName: "ZAIP Dashboard",
4
- version: "1.0.8",
4
+ version: "1.3.0",
5
5
  colors: {
6
6
  background: "#080d16",
7
7
  surface: "#101827",