@zaip-ai/cli 4.9.0 → 5.1.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 (213) hide show
  1. package/dist/services/adapter-hook-sources.d.ts +3 -0
  2. package/dist/services/adapter-hook-sources.d.ts.map +1 -1
  3. package/dist/services/adapter-hook-sources.js +3 -0
  4. package/dist/services/adapter-hook-sources.js.map +1 -1
  5. package/dist/services/adapters.d.ts +1 -1
  6. package/dist/services/adapters.d.ts.map +1 -1
  7. package/dist/services/adapters.js +5 -2
  8. package/dist/services/adapters.js.map +1 -1
  9. package/dist/services/adapters.test.js +1 -1
  10. package/dist/services/adapters.test.js.map +1 -1
  11. package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
  12. package/dist/services/codex-conversation-lifecycle-hook.js +16 -6
  13. package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
  14. package/dist/services/codex-hook-activation.d.ts +1 -1
  15. package/dist/services/codex-hook-activation.d.ts.map +1 -1
  16. package/dist/services/codex-hook-activation.js +116 -10
  17. package/dist/services/codex-hook-activation.js.map +1 -1
  18. package/dist/services/codex-pre-tool-cli-capture-template.d.ts +2 -0
  19. package/dist/services/codex-pre-tool-cli-capture-template.d.ts.map +1 -0
  20. package/dist/services/codex-pre-tool-cli-capture-template.js +104 -0
  21. package/dist/services/codex-pre-tool-cli-capture-template.js.map +1 -0
  22. package/dist/services/codex-pre-tool-cloud-template.d.ts +2 -0
  23. package/dist/services/codex-pre-tool-cloud-template.d.ts.map +1 -0
  24. package/dist/services/codex-pre-tool-cloud-template.js +190 -0
  25. package/dist/services/codex-pre-tool-cloud-template.js.map +1 -0
  26. package/dist/services/codex-pre-tool-dependencies.test-support.d.ts +2 -0
  27. package/dist/services/codex-pre-tool-dependencies.test-support.d.ts.map +1 -0
  28. package/dist/services/codex-pre-tool-dependencies.test-support.js +9 -0
  29. package/dist/services/codex-pre-tool-dependencies.test-support.js.map +1 -0
  30. package/dist/services/codex-pre-tool-hook-fixture.test-support.d.ts +5 -0
  31. package/dist/services/codex-pre-tool-hook-fixture.test-support.d.ts.map +1 -0
  32. package/dist/services/codex-pre-tool-hook-fixture.test-support.js +19 -0
  33. package/dist/services/codex-pre-tool-hook-fixture.test-support.js.map +1 -0
  34. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.d.ts +2 -0
  35. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.d.ts.map +1 -0
  36. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.js +107 -0
  37. package/dist/services/codex-pre-tool-hook-template-bootstrap.test.js.map +1 -0
  38. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  39. package/dist/services/codex-pre-tool-hook-template.js +96 -210
  40. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  41. package/dist/services/codex-pre-tool-hook-template.test.js +32 -80
  42. package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -1
  43. package/dist/services/codex-pre-tool-host-context-template.d.ts +2 -0
  44. package/dist/services/codex-pre-tool-host-context-template.d.ts.map +1 -0
  45. package/dist/services/codex-pre-tool-host-context-template.js +139 -0
  46. package/dist/services/codex-pre-tool-host-context-template.js.map +1 -0
  47. package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
  48. package/dist/services/codex-pre-tool-support-template.js +61 -101
  49. package/dist/services/codex-pre-tool-support-template.js.map +1 -1
  50. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  51. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  52. package/dist/services/codex-subagent-hook-template.js +13 -2
  53. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  54. package/dist/services/codex-validation-runtime-template.d.ts.map +1 -1
  55. package/dist/services/codex-validation-runtime-template.js +10 -4
  56. package/dist/services/codex-validation-runtime-template.js.map +1 -1
  57. package/dist/services/runtime-template-test-support.d.ts +1 -0
  58. package/dist/services/runtime-template-test-support.d.ts.map +1 -1
  59. package/dist/services/runtime-template-test-support.js +23 -2
  60. package/dist/services/runtime-template-test-support.js.map +1 -1
  61. package/dist/services/runtime-template.test.js +4 -23
  62. package/dist/services/runtime-template.test.js.map +1 -1
  63. package/package.json +1 -1
  64. package/templates/.agents/README-ENG.md +58 -7
  65. package/templates/.agents/README.md +46 -10
  66. package/templates/.agents/config/agents/discovery.json +1 -1
  67. package/templates/.agents/dashboard/.zaip-managed.json +174 -86
  68. package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-BW7Vy1cp.js → CostCalculationGuidePage-uR-asJv_.js} +1 -1
  69. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cp_hEVd8.js → DashboardHelpDialog-CngnpoLL.js} +87 -13
  70. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Prcs-ydy.js → PricingSettingsDialog-Bszw3ekd.js} +1 -1
  71. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-Cu40wAFF.js → ProjectSettingsPage-IJ1znG4w.js} +1 -1
  72. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-Bh3YBd3C.js → TraceabilityWorkspace-CsBpHqq_.js} +1 -1
  73. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-B0Jwz_rk.js +68 -0
  74. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-CF7B1Hjn.js → dashboard-localization-D41g5rdo.js} +58 -7
  75. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DOhy6D2-.js → icons-vendor-CjGGux6h.js} +1 -1
  76. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Bedlm0f7.js +2 -0
  77. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CkPC-yMz.js → react-vendor-B9jZSAKf.js} +1 -1
  78. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-BEdGoIDm.js → traceability-DFpwb0TN.js} +1 -1
  79. package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
  80. package/templates/.agents/dashboard/apps/frontend/package.json +2 -2
  81. package/templates/.agents/dashboard/apps/frontend/src/AppDashboardContent.tsx +3 -0
  82. package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +16 -7
  83. package/templates/.agents/dashboard/apps/frontend/src/__tests__/app-composition-support.ts +1 -0
  84. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +1 -1
  85. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +2 -0
  86. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.navigation.test.tsx +125 -0
  87. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +67 -9
  88. package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-app-model.tsx +15 -15
  89. package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-locale.ts +18 -0
  90. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  91. package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +10 -3
  92. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.run-page.test.ts +5 -1
  93. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.period-values.test.tsx +2 -2
  94. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +5 -5
  95. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +36 -43
  96. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-loaders.ts +1 -0
  97. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-formatters.ts +6 -4
  98. package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +2 -2
  99. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +1 -1
  100. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +11 -25
  101. package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-summary-defaults.ts +26 -0
  102. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  103. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +11 -16
  104. package/templates/.agents/dashboard/modules/operations/src/planning-contracts.ts +14 -0
  105. package/templates/.agents/dashboard/modules/operations/src/react/DecisionTable.tsx +65 -0
  106. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +5 -71
  107. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +4 -39
  108. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.navigation.test.tsx +150 -0
  109. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.tsx +7 -3
  110. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +14 -43
  111. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +3 -0
  112. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-contract.ts +51 -0
  113. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +12 -3
  114. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +1 -0
  115. package/templates/.agents/dashboard/modules/operations/src/react/use-operations-default-range.ts +16 -0
  116. package/templates/.agents/dashboard/modules/operations/src/react/use-operations-filter-sync.ts +66 -0
  117. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  118. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  119. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  120. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  121. package/templates/.agents/dashboard/packages/local-runtime/dashboard-build-fingerprint.mjs +87 -0
  122. package/templates/.agents/dashboard/packages/local-runtime/dashboard-build-fingerprint.test.mjs +48 -0
  123. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +193 -191
  124. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +169 -169
  125. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  126. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-frontend.mjs +29 -0
  127. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +5 -0
  128. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +193 -191
  129. package/templates/.agents/dashboard/packages/local-runtime/src/active-capture-failure.test.ts +38 -0
  130. package/templates/.agents/dashboard/packages/local-runtime/src/active-capture-failure.ts +35 -0
  131. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +53 -2
  132. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +18 -1
  133. package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +8 -2
  134. package/templates/.agents/dashboard/packages/local-runtime/src/server-capture-projection-order.test.ts +118 -0
  135. package/templates/.agents/dashboard/packages/local-runtime/src/server-cost-run-search.test.ts +90 -0
  136. package/templates/.agents/dashboard/packages/local-runtime/src/server-cost-run-search.ts +86 -0
  137. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-routes.ts +8 -1
  138. package/templates/.agents/dashboard/packages/local-runtime/src/server-projection-loaders.ts +13 -0
  139. package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +30 -74
  140. package/templates/.agents/dashboard/packages/local-runtime/src/server-route-handlers.ts +42 -0
  141. package/templates/.agents/dashboard/packages/local-runtime/src/server-routes.test.ts +60 -0
  142. package/templates/.agents/dashboard/packages/local-runtime/src/server-run-projections.test.ts +12 -2
  143. package/templates/.agents/dashboard/packages/local-runtime/src/server-telemetry-command.test.ts +29 -4
  144. package/templates/.agents/dashboard/packages/local-runtime/src/server-telemetry-refresh.ts +7 -0
  145. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +51 -54
  146. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +28 -45
  147. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts +5 -0
  148. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.test.ts +49 -0
  149. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.ts +44 -1
  150. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-cached-cost-page.ts +11 -10
  151. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +1 -1
  152. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-item-index.test.ts +18 -1
  153. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-build.mjs +12 -5
  154. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-paths.mjs +8 -0
  155. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +1 -0
  156. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  157. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  158. package/templates/.agents/dashboard/tests/e2e/qualify-top-five-trace.mjs +53 -0
  159. package/templates/.agents/dashboard/tests/e2e/verify-top-five-served.mjs +78 -0
  160. package/templates/.agents/design/.zaip-managed.json +14 -6
  161. package/templates/.agents/design/apps/catalog/dist/assets/index-BGxXxXTo.js +72 -0
  162. package/templates/.agents/design/apps/catalog/dist/index.html +1 -1
  163. package/templates/.agents/design/apps/catalog/package.json +1 -1
  164. package/templates/.agents/design/apps/catalog/src/components/TopEntitiesSpecimen.tsx +45 -0
  165. package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +3 -1
  166. package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +2 -0
  167. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  168. package/templates/.agents/requirements/autonomous-assurance.md +11 -2
  169. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  170. package/templates/.agents/requirements/comparative-audit.md +1 -1
  171. package/templates/.agents/requirements/context-engine.md +1 -1
  172. package/templates/.agents/requirements/cost-observability.md +1 -1
  173. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  174. package/templates/.agents/requirements/data-export.md +1 -1
  175. package/templates/.agents/requirements/design-system.md +1 -1
  176. package/templates/.agents/requirements/execution-engine.md +1 -1
  177. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  178. package/templates/.agents/requirements/model-orchestration.md +1 -1
  179. package/templates/.agents/requirements/public-distribution.md +1 -1
  180. package/templates/.agents/requirements/software-architecture.md +1 -1
  181. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  182. package/templates/.agents/requirements/work-lifecycle.md +2 -1
  183. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  184. package/templates/.agents/rules/run-lifecycle-closure.md +2 -1
  185. package/templates/.agents/rules/workflow.md +1 -0
  186. package/templates/.agents/runtime/VERSION +1 -1
  187. package/templates/.agents/runtime/bin/zaip.mjs +1178 -764
  188. package/templates/.agents/runtime/checksums.sha256 +6 -6
  189. package/templates/.agents/runtime/manifest.json +1 -1
  190. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  191. package/templates/.agents/runtime/provenance.json +5 -5
  192. package/templates/.agents/runtime/sbom.cdx.json +59 -59
  193. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
  194. package/templates/.agents/skills/zaip-skill-execution/references/controlled-release-recovery.md +14 -0
  195. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +1 -1
  196. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +5 -1
  197. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract-cli.test.mjs +53 -0
  198. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.mjs +12 -0
  199. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.test.mjs +26 -32
  200. package/templates/.agents/skills/zaip-skill-maintenance-enter/SKILL.md +23 -0
  201. package/templates/.agents/skills/zaip-skill-maintenance-enter/agents/openai.yaml +4 -0
  202. package/templates/.agents/skills/zaip-skill-maintenance-enter/scripts/maintenance.mjs +213 -0
  203. package/templates/.agents/skills/zaip-skill-maintenance-enter/scripts/maintenance.test.mjs +207 -0
  204. package/templates/.agents/skills/zaip-skill-maintenance-exit/SKILL.md +21 -0
  205. package/templates/.agents/skills/zaip-skill-maintenance-exit/agents/openai.yaml +4 -0
  206. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +2 -0
  207. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +37 -8
  208. package/templates/.agents/zaip-aios/VERSION +1 -1
  209. package/templates/.agents/zaip-aios/guides/10-seguranca.md +2 -2
  210. package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +38 -0
  211. package/templates/template-manifest.json +259 -135
  212. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Co2Jiuzh.js +0 -68
  213. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-qVSJnJ0_.js +0 -2
@@ -76,10 +76,13 @@ describe("date time formatting", () => {
76
76
  });
77
77
  });
78
78
  describe("formatAuditableNumber", () => {
79
- it("renders unavailable numeric metrics as presentation zero", () => {
80
- expect(formatAuditableNumber(null, "pt-BR")).toBe("0");
81
- expect(formatAuditableNumber(null, "en-US")).toBe("0");
79
+ it("distinguishes unavailable numeric metrics from an observed zero", () => {
80
+ expect(formatAuditableNumber(null, "pt-BR")).toBe("—");
81
+ expect(formatAuditableNumber(null, "en-US")).toBe("—");
82
82
  expect(formatAuditableNumber(0, "pt-BR")).toBe("0");
83
+ expect(formatAuditableCompactNumber(null, "pt-BR")).toBe("—");
84
+ expect(formatAuditableCurrency(null, "BRL", "pt-BR")).toBe("—");
85
+ expect(formatAuditableDuration(null, "pt-BR")).toBe("—");
83
86
  });
84
87
  it("keeps observed positive values", () => {
85
88
  expect(formatAuditableNumber(1234, "pt-BR")).toBe("1.234");
@@ -107,12 +110,12 @@ describe("monetary formatting", () => {
107
110
  expect(ratio(106.73, 19.583444)).toBeCloseTo(5.45, 2);
108
111
  expect(ratio(100, 0)).toBeNull();
109
112
  });
110
- it("shows zero for unmeasured metrics without changing their source values", () => {
113
+ it("preserves unavailable values separately from observed zero", () => {
111
114
  expect(formatRate(null, "pt-BR")).toBe("0,00");
112
115
  expect(formatUsd(null, "en-US")).toContain("0.00");
113
- expect(formatAuditableCurrency(null, "BRL", "pt-BR")).toBe("0");
114
- expect(formatAuditableDuration(null, "pt-BR")).toBe("0");
115
- expect(formatAuditableCompactNumber(null, "pt-BR")).toBe("0");
116
+ expect(formatAuditableCurrency(null, "BRL", "pt-BR")).toBe("—");
117
+ expect(formatAuditableDuration(null, "pt-BR")).toBe("—");
118
+ expect(formatAuditableCompactNumber(null, "pt-BR")).toBe("—");
116
119
  });
117
120
  });
118
121
  describe("duration coverage", () => {
@@ -143,14 +146,14 @@ describe("duration coverage", () => {
143
146
  1_100,
144
147
  "pt-BR",
145
148
  ),
146
- ).toBe(formatAuditableDuration(null, "pt-BR"));
149
+ ).toBe("0");
147
150
  expect(
148
151
  formatTokenBackedDuration(
149
152
  { known_sum: 0, unknown: 2, complete: false, coverage_ratio: 0 },
150
153
  null,
151
154
  "pt-BR",
152
155
  ),
153
- ).toBe(formatAuditableDuration(null, "pt-BR"));
156
+ ).toBe("0");
154
157
  });
155
158
  });
156
159
  describe("runtime availability", () => {
@@ -185,27 +188,26 @@ describe("grouped cost availability", () => {
185
188
  duration: { known_sum: 0, unknown: 2, complete: false, coverage_ratio: 0 },
186
189
  coverage: { events: 2, tokens: 0, usd: 0, brl: 0 },
187
190
  } as const;
191
+ const completeDeveloperRow = {
192
+ account_id: "42",
193
+ login_snapshot: "dev-42",
194
+ prd_count: 1,
195
+ spec_count: 2,
196
+ task_count: 3,
197
+ run_count: 4,
198
+ test_count: null,
199
+ evidence_count: null,
200
+ total_duration_ms: 60_000,
201
+ total_tokens: 50,
202
+ total_cost_brl: 1.5,
203
+ duration_covered_runs: 4,
204
+ token_covered_runs: 4,
205
+ brl_covered_runs: 4,
206
+ } satisfies CostDeveloperAttributionRow;
188
207
  it("uses the requested Cost Monitor developer metric columns without Operations source or coverage", () => {
189
208
  const table = CostDeveloperAttributionTable({
190
209
  locale: "pt-BR",
191
- rows: [
192
- {
193
- account_id: "42",
194
- login_snapshot: "dev-42",
195
- prd_count: 1,
196
- spec_count: 2,
197
- task_count: 3,
198
- run_count: 4,
199
- test_count: null,
200
- evidence_count: null,
201
- total_duration_ms: 60_000,
202
- total_tokens: 50,
203
- total_cost_brl: 1.5,
204
- duration_covered_runs: 4,
205
- token_covered_runs: 4,
206
- brl_covered_runs: 4,
207
- },
208
- ],
210
+ rows: [completeDeveloperRow],
209
211
  });
210
212
  const columns = table.props.columns as Array<{
211
213
  key: string;
@@ -246,17 +248,7 @@ describe("grouped cost availability", () => {
246
248
  });
247
249
  it("marks incomplete aggregates in place without adding source or coverage columns", () => {
248
250
  const partial = {
249
- account_id: "42",
250
- login_snapshot: "dev-42",
251
- prd_count: 1,
252
- spec_count: 2,
253
- task_count: 3,
254
- run_count: 4,
255
- test_count: null,
256
- evidence_count: null,
257
- total_duration_ms: 60_000,
258
- total_tokens: 50,
259
- total_cost_brl: 1.5,
251
+ ...completeDeveloperRow,
260
252
  duration_covered_runs: 3,
261
253
  token_covered_runs: 2,
262
254
  brl_covered_runs: 2,
@@ -348,12 +340,12 @@ describe("grouped cost availability", () => {
348
340
  const column = (key: string) => columns.find((candidate) => candidate.key === key);
349
341
  expect(table.props.scrollLabel).toBe(costGroupsScrollLabel("pt-BR"));
350
342
  expect(column("duration")?.render(unavailableGroup)).toBe("0");
351
- expect(column("tokens")?.render(unavailableGroup)).toBe("0");
352
- expect(column("cost")?.render(unavailableGroup)).toBe("0");
343
+ expect(column("tokens")?.render(unavailableGroup)).toBe("—");
344
+ expect(column("cost")?.render(unavailableGroup)).toBe("—");
353
345
  expect(column("duration")?.sortValue?.(unavailableGroup)).toBeNull();
354
346
  expect(column("tokens")?.sortValue?.(unavailableGroup)).toBeNull();
355
347
  expect(column("cost")?.sortValue?.(unavailableGroup)).toBeNull();
356
- const totalSummary = "Total geral — Tempo: 0; Tokens: 0; BRL: 0";
348
+ const totalSummary = "Total geral — Tempo: 0; Tokens: —; BRL: —";
357
349
  const footerLabel = (key: string) => {
358
350
  const footer = column(key)?.footer as { props?: { "aria-label"?: string } } | undefined;
359
351
  return footer?.props?.["aria-label"];
@@ -450,10 +442,11 @@ describe("grouped cost availability", () => {
450
442
  render?: (row: CostGroupRow) => unknown;
451
443
  footer?: unknown;
452
444
  }>;
453
- for (const key of ["tasks", "prds", "specs", "tests", "evidences", "tokens"]) {
445
+ for (const key of ["tasks", "prds", "specs", "tests", "evidences"]) {
454
446
  expect(columns.find((c) => c.key === key)?.render?.(missing)).toBe("0");
455
447
  }
448
+ expect(columns.find((c) => c.key === "tokens")?.render?.(missing)).toBe("—");
456
449
  expect(columns.find((c) => c.key === "duration")?.render?.(missing)).toBe("0");
457
- expect(columns.find((c) => c.key === "cost")?.render?.(missing)).toBe("0");
450
+ expect(columns.find((c) => c.key === "cost")?.render?.(missing)).toBe("—");
458
451
  });
459
452
  });
@@ -167,6 +167,7 @@ function costMonitorQuery({
167
167
  ["status", filters.status],
168
168
  ] as const;
169
169
  for (const [key, value] of manifestFilters) if (value) query.set(key, value);
170
+ if (filters.query) query.set("query", filters.query);
170
171
  }
171
172
  if (refresh) query.set("refresh", refresh);
172
173
  return query;
@@ -18,7 +18,9 @@ export function displayCostGroupLabel(label: string, locale: CostLocale): string
18
18
  }
19
19
 
20
20
  export function formatAuditableNumber(value: number | null, locale: CostLocale): string {
21
- return new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value ?? 0);
21
+ return value === null
22
+ ? "—"
23
+ : new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value);
22
24
  }
23
25
 
24
26
  export function formatFactualCount(value: number | null, locale: CostLocale): string {
@@ -26,7 +28,7 @@ export function formatFactualCount(value: number | null, locale: CostLocale): st
26
28
  }
27
29
 
28
30
  export function formatAuditableCompactNumber(value: number | null, locale: CostLocale): string {
29
- return formatCompactNumber(value ?? 0, locale);
31
+ return value === null ? "—" : formatCompactNumber(value, locale);
30
32
  }
31
33
 
32
34
  export function formatAuditableCurrency(
@@ -34,12 +36,12 @@ export function formatAuditableCurrency(
34
36
  currency: CostCurrency,
35
37
  locale: CostLocale,
36
38
  ): string {
37
- if (value === null) return "0";
39
+ if (value === null) return "—";
38
40
  return formatCurrency(value, currency, locale);
39
41
  }
40
42
 
41
43
  export function formatAuditableDuration(value: number | null, locale: CostLocale): string {
42
- if (value === null) return "0";
44
+ if (value === null) return "—";
43
45
  return value === 0 ? "0" : formatDurationMs(value, locale);
44
46
  }
45
47
 
@@ -10,11 +10,11 @@ import {
10
10
 
11
11
  export function aggregateRows(
12
12
  rows: readonly CostRunRow[],
13
- select: (row: CostRunRow) => string,
13
+ select: (row: CostRunRow) => string | null,
14
14
  label: (key: string) => string = (key) => key,
15
15
  durationScope: DurationAggregationScope = "all_invocations",
16
16
  ): CostGroupRow[] {
17
- const keys = [...new Set(rows.map(select))];
17
+ const keys = [...new Set(rows.map(select).filter((key): key is string => key !== null))];
18
18
  const durationContributorIds = new Set(
19
19
  durationAggregationRows(rows, durationScope).map((row) => row.run_id),
20
20
  );
@@ -81,7 +81,7 @@ export function buildCostMonitorProjection(
81
81
  execution_id: run.execution_id,
82
82
  conversation_id: run.conversation_id,
83
83
  task_id: run.task_id,
84
- task_title: task?.title ?? run.task_id ?? run.conversation_id,
84
+ task_title: task?.title ?? run.task_id ?? run.conversation_id ?? run.id,
85
85
  task_status: task?.status ?? run.status,
86
86
  priority: task?.priority ?? "none",
87
87
  risk: task?.risk ?? "none",
@@ -1,7 +1,6 @@
1
1
  import type {
2
2
  OperationsProjection,
3
3
  RunProjection,
4
- UsageMetricProjection,
5
4
  UsageProjection,
6
5
  } from "@zaip-ai/dashboard-operations/contracts";
7
6
  import {
@@ -16,6 +15,7 @@ import {
16
15
  } from "@zaip-ai/dashboard-operations/server";
17
16
  import type { CostGroupRow, CostMonitorProjection } from "../contracts.js";
18
17
  import { buildCostMonitorProjection, usageForRuns } from "./build-cost-monitor-projection.js";
18
+ import { emptyOrigins } from "./cost-summary-defaults.js";
19
19
 
20
20
  /** Fast Cost Monitor first fold backed only by the durable lifecycle summary. */
21
21
  export function buildCostSummaryProjection(
@@ -288,6 +288,8 @@ export interface CostSummarySource {
288
288
  >;
289
289
  run_metrics?: Array<{
290
290
  id: string;
291
+ entrypoint?: string | null;
292
+ run_purpose?: string | null;
291
293
  started_at: string;
292
294
  finished_at: string | null;
293
295
  task_id: string | null;
@@ -366,11 +368,16 @@ function summaryRunProjection(
366
368
  ? run.status
367
369
  : "completed",
368
370
  phase,
369
- entrypoint: run.task_id === null ? "conversation" : "task",
371
+ entrypoint:
372
+ run.entrypoint === "observation"
373
+ ? "observation"
374
+ : run.task_id === null
375
+ ? "conversation"
376
+ : "task",
370
377
  work_type: "new",
371
378
  run_role: run.run_kind === "subrun" ? "subagent" : "orchestrator",
372
379
  run_kind: run.run_kind ?? "run",
373
- run_purpose: "execution",
380
+ run_purpose: run.run_purpose === "observation" ? "observation" : "execution",
374
381
  requires_finalizer: false,
375
382
  parent_run_id: run.parent_run_id,
376
383
  client: "unknown",
@@ -386,7 +393,7 @@ function summaryRunProjection(
386
393
  terminal_call_count: null,
387
394
  failed_call_count: 0,
388
395
  cancelled_call_count: 0,
389
- conversation_id: run.conversation_id ?? run.id,
396
+ conversation_id: run.entrypoint === "observation" ? null : (run.conversation_id ?? run.id),
390
397
  execution_id: run.execution_id ?? null,
391
398
  task_id: run.task_id,
392
399
  spec_id: run.spec_id ?? null,
@@ -739,24 +746,3 @@ function knownRuns(eligibleRuns: number, unknownRuns: number): number {
739
746
  function runPopulation(eligible_runs: number, known_runs: number) {
740
747
  return { eligible_runs, known_runs, unknown_runs: eligible_runs - known_runs };
741
748
  }
742
-
743
- function emptyMetric(): UsageMetricProjection {
744
- return {
745
- events: 0,
746
- tokens: { input: null, cached_input: null, output: null, reasoning: null, total: null },
747
- cost: { usd: null, brl: null },
748
- coverage: { events: 0, tokens: 0, usd: 0, brl: 0 },
749
- };
750
- }
751
-
752
- function emptyOrigins(): CostMonitorProjection["origins"] {
753
- const usage = (): UsageProjection => ({
754
- conversation: emptyMetric(),
755
- planning: emptyMetric(),
756
- execution: emptyMetric(),
757
- total: emptyMetric(),
758
- new_work: emptyMetric(),
759
- rework: emptyMetric(),
760
- });
761
- return { conversation: usage(), task: usage(), spec: usage(), prd: usage() };
762
- }
@@ -0,0 +1,26 @@
1
+ import type {
2
+ UsageMetricProjection,
3
+ UsageProjection,
4
+ } from "@zaip-ai/dashboard-operations/contracts";
5
+ import type { CostMonitorProjection } from "../contracts.js";
6
+
7
+ function emptyMetric(): UsageMetricProjection {
8
+ return {
9
+ events: 0,
10
+ tokens: { input: null, cached_input: null, output: null, reasoning: null, total: null },
11
+ cost: { usd: null, brl: null },
12
+ coverage: { events: 0, tokens: 0, usd: 0, brl: 0 },
13
+ };
14
+ }
15
+
16
+ export function emptyOrigins(): CostMonitorProjection["origins"] {
17
+ const usage = (): UsageProjection => ({
18
+ conversation: emptyMetric(),
19
+ planning: emptyMetric(),
20
+ execution: emptyMetric(),
21
+ total: emptyMetric(),
22
+ new_work: emptyMetric(),
23
+ rework: emptyMetric(),
24
+ });
25
+ return { conversation: usage(), task: usage(), spec: usage(), prd: usage() };
26
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-operations",
3
- "version": "4.9.0",
3
+ "version": "5.1.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -355,11 +355,18 @@ export interface RunProjection {
355
355
  artifact_path: string;
356
356
  status: "running" | "completed" | "failed" | "cancelled";
357
357
  phase: string;
358
- entrypoint: "conversation" | "task" | "spec" | "prd";
358
+ entrypoint: "observation" | "conversation" | "task" | "spec" | "prd";
359
359
  work_type: "new" | "rework";
360
360
  run_role: "intake" | "orchestrator" | "subagent";
361
361
  run_kind: "run" | "subrun";
362
- run_purpose: "intake" | "orchestration" | "execution" | "review" | "audit" | "finalization";
362
+ run_purpose:
363
+ | "observation"
364
+ | "intake"
365
+ | "orchestration"
366
+ | "execution"
367
+ | "review"
368
+ | "audit"
369
+ | "finalization";
363
370
  requires_finalizer: boolean;
364
371
  parent_run_id: string | null;
365
372
  client: string;
@@ -378,7 +385,7 @@ export interface RunProjection {
378
385
  terminal_call_count: number | null;
379
386
  failed_call_count: number | null;
380
387
  cancelled_call_count: number | null;
381
- conversation_id: string;
388
+ conversation_id: string | null;
382
389
  client_thread_id?: string | null;
383
390
  client_turn_id?: string | null;
384
391
  is_active?: boolean;
@@ -600,16 +607,4 @@ export interface TaskDetailProjection {
600
607
  artifact_path: string;
601
608
  }
602
609
 
603
- export interface PrdDetailProjection {
604
- id: string;
605
- title: string;
606
- body: string;
607
- artifact_path: string;
608
- }
609
-
610
- export interface SpecDetailProjection {
611
- id: string;
612
- title: string;
613
- body: string;
614
- artifact_path: string;
615
- }
610
+ export type { PrdDetailProjection, SpecDetailProjection } from "./planning-contracts.js";
@@ -0,0 +1,14 @@
1
+ /** Canonical detail payloads for PRD and SPEC drilldowns. */
2
+ export interface PrdDetailProjection {
3
+ id: string;
4
+ title: string;
5
+ body: string;
6
+ artifact_path: string;
7
+ }
8
+
9
+ export interface SpecDetailProjection {
10
+ id: string;
11
+ title: string;
12
+ body: string;
13
+ artifact_path: string;
14
+ }
@@ -0,0 +1,65 @@
1
+ import { DataTable, formatDateTime } from "@zaip-ai/dashboard-ui";
2
+ import { useState } from "react";
3
+ import type { DecisionProjection } from "../contracts.js";
4
+ import { EntityDetailsDialog } from "./EntityDetailsDialog.js";
5
+ import { DecisionOriginBadge, DecisionStageBadge } from "./EntityTableBadges.js";
6
+ import type { OperationsLocale } from "./status-labels.js";
7
+ import { sortByDateDesc } from "./table-order.js";
8
+
9
+ export function DecisionTable({
10
+ rows,
11
+ locale,
12
+ }: {
13
+ rows: readonly DecisionProjection[];
14
+ locale: OperationsLocale;
15
+ }) {
16
+ const [selected, setSelected] = useState<DecisionProjection | null>(null);
17
+ const orderedRows = sortByDateDesc(rows, (row) => row.created_at);
18
+ return (
19
+ <>
20
+ <DataTable
21
+ columns={[
22
+ {
23
+ key: "date",
24
+ label: "Data de criação",
25
+ render: (row) => formatDateTime(row.created_at),
26
+ },
27
+ {
28
+ key: "title",
29
+ label: "Decisão",
30
+ render: (row) => (
31
+ <>
32
+ <strong>{row.title}</strong>
33
+ <small>{row.id}</small>
34
+ </>
35
+ ),
36
+ },
37
+ {
38
+ key: "origin",
39
+ label: "Origem",
40
+ render: (row) => <DecisionOriginBadge origin={row.origin} />,
41
+ },
42
+ {
43
+ key: "stage",
44
+ label: "Fase",
45
+ render: (row) => <DecisionStageBadge scopeType={row.scope_type} />,
46
+ },
47
+ { key: "scope", label: "Escopo", render: (row) => `${row.scope_type}: ${row.scope_id}` },
48
+ ]}
49
+ locale={locale}
50
+ rowKey={(row) => row.id}
51
+ onRowClick={setSelected}
52
+ rows={orderedRows}
53
+ showColumnInfo
54
+ sortable
55
+ />
56
+ {selected ? (
57
+ <EntityDetailsDialog
58
+ details={{ kind: "decision", row: selected }}
59
+ locale={locale}
60
+ onClose={() => setSelected(null)}
61
+ />
62
+ ) : null}
63
+ </>
64
+ );
65
+ }
@@ -5,12 +5,7 @@ import {
5
5
  formatDateTime,
6
6
  } from "@zaip-ai/dashboard-ui";
7
7
  import { useState } from "react";
8
- import type {
9
- ChangeProjection,
10
- DecisionProjection,
11
- ExecutionProjection,
12
- RunProjection,
13
- } from "../contracts.js";
8
+ import type { ChangeProjection, ExecutionProjection, RunProjection } from "../contracts.js";
14
9
  import { buildConversationRows } from "./conversation-rows.js";
15
10
  import { EntityDetailsDialog } from "./EntityDetailsDialog.js";
16
11
  import { displayedDuration, formatDisplayedDuration } from "./operation-duration.js";
@@ -569,6 +564,7 @@ function runPurposeLabel(purpose: RunProjection["run_purpose"], locale: Operatio
569
564
  review: "Revisão",
570
565
  audit: "Auditoria",
571
566
  finalization: "Finalização",
567
+ observation: "Observação",
572
568
  }[purpose];
573
569
  }
574
570
 
@@ -701,7 +697,7 @@ export function canBuildCanonicalConversationRows(
701
697
  } => execution.kind === "interaction" && execution.origin.type === "interaction",
702
698
  )
703
699
  .every((execution) => execution.origin.conversation_id.trim().length > 0) &&
704
- rows.every((row) => row.id.trim().length > 0 && row.conversation_id.trim().length > 0)
700
+ rows.every((row) => row.id.trim().length > 0 && (row.conversation_id?.trim().length ?? 0) > 0)
705
701
  );
706
702
  }
707
703
 
@@ -721,68 +717,6 @@ function CanonicalEntityLoadingState({
721
717
  );
722
718
  }
723
719
 
724
- export function DecisionTable({
725
- rows,
726
- locale,
727
- }: {
728
- rows: readonly DecisionProjection[];
729
- locale: OperationsLocale;
730
- }) {
731
- const [selected, setSelected] = useState<DecisionProjection | null>(null);
732
- const orderedRows = sortByDateDesc(rows, (row) => row.created_at);
733
- return (
734
- <>
735
- <DataTable
736
- columns={[
737
- {
738
- key: "date",
739
- label: "Data de criação",
740
- render: (row) => formatDateTime(row.created_at),
741
- },
742
- {
743
- key: "title",
744
- label: "Decisão",
745
- render: (row) => (
746
- <>
747
- <strong>{row.title}</strong>
748
- <small>{row.id}</small>
749
- </>
750
- ),
751
- },
752
- {
753
- key: "origin",
754
- label: "Origem",
755
- render: (row) => <DecisionOriginBadge origin={row.origin} />,
756
- },
757
- {
758
- key: "stage",
759
- label: "Fase",
760
- render: (row) => <DecisionStageBadge scopeType={row.scope_type} />,
761
- },
762
- { key: "scope", label: "Escopo", render: (row) => `${row.scope_type}: ${row.scope_id}` },
763
- ]}
764
- locale={locale}
765
- rowKey={(row) => row.id}
766
- onRowClick={setSelected}
767
- rows={orderedRows}
768
- showColumnInfo
769
- sortable
770
- />
771
- {selected ? (
772
- <EntityDetailsDialog
773
- details={{ kind: "decision", row: selected }}
774
- locale={locale}
775
- onClose={() => setSelected(null)}
776
- />
777
- ) : null}
778
- </>
779
- );
780
- }
720
+ export { DecisionTable } from "./DecisionTable.js";
781
721
 
782
- import {
783
- DecisionOriginBadge,
784
- DecisionStageBadge,
785
- EntryBadge,
786
- RiskBadge,
787
- StatusBadge,
788
- } from "./EntityTableBadges.js";
722
+ import { EntryBadge, RiskBadge, StatusBadge } from "./EntityTableBadges.js";
@@ -1,3 +1,4 @@
1
+ import type { OperationsOverviewProps } from "./operations-overview-contract.js";
1
2
  import { formatSummaryMetricValue, unmeasuredZeroDescription } from "./overview-metric-format.js";
2
3
  import { overviewMetricStats } from "./overview-metric-stats.js";
3
4
 
@@ -94,6 +95,7 @@ export function OperationsOverview({
94
95
  onDatePresetChange,
95
96
  onOpenTask,
96
97
  onOpenDocument,
98
+ onOpenMacro,
97
99
  onLoadStatus,
98
100
  statusPage,
99
101
  onLoadStatusPage,
@@ -109,45 +111,7 @@ export function OperationsOverview({
109
111
  costLoading = false,
110
112
  resolveRunCost,
111
113
  includeLegacyEffort: _includeLegacyEffort = false,
112
- }: {
113
- currency: "BRL" | "USD";
114
- data: OperationsProjection;
115
- /** App-controlled range paired with datePreset; retained by Page while loading. */
116
- dateRange?: OperationDateRange;
117
- datePreset: OperationDatePreset;
118
- locale: OperationsLocale;
119
- onDatePresetChange: (preset: OperationDatePreset) => void;
120
- onOpenTask: (taskId: string) => Promise<boolean>;
121
- onOpenDocument: (kind: "prd" | "spec", id: string) => void;
122
- onLoadStatus?: ((stage: WorkStage, kind: OverviewStatusKind, offset: number) => void) | undefined;
123
- statusPage?:
124
- | ((stage: WorkStage, kind: OverviewStatusKind) => OverviewStatusPage | undefined)
125
- | undefined;
126
- onLoadStatusPage?:
127
- | ((stage: WorkStage, kind: OverviewStatusKind, offset: number) => void)
128
- | undefined;
129
- classificationPage?:
130
- | ((
131
- kind: OverviewStatusKind,
132
- classification: OverviewClassification,
133
- ) => OverviewClassificationPage | undefined)
134
- | undefined;
135
- onLoadClassificationPage?:
136
- | ((kind: OverviewStatusKind, classification: OverviewClassification, offset: number) => void)
137
- | undefined;
138
- onLoadMacroMetrics?: (() => void) | undefined;
139
- prds?: OperationsProjection["prds"];
140
- runs?: OperationsProjection["runs"];
141
- specs?: OperationsProjection["specs"];
142
- tasks?: OperationsProjection["tasks"];
143
- /** Factual Cost Monitor snapshot total for the selected locale/currency. */
144
- factualCostTotal?: number | null | undefined;
145
- /** Measurement completeness for the matching Cost Monitor snapshot. */
146
- factualCostFact?: FactualCostFact | undefined;
147
- costLoading?: boolean | undefined;
148
- resolveRunCost?: ((runId: string) => number | null) | undefined;
149
- includeLegacyEffort?: boolean;
150
- }) {
114
+ }: OperationsOverviewProps) {
151
115
  const [overviewView, setOverviewView] = useState<OverviewView>("tasks");
152
116
  const [selectedStatus, setSelectedStatus] = useState<WorkStage | null>(null);
153
117
  const [selectedClassification, setSelectedClassification] =
@@ -687,6 +651,7 @@ export function OperationsOverview({
687
651
  currency={currency}
688
652
  locale={locale}
689
653
  maxDuration={maxDuration}
654
+ onOpenMacro={onOpenMacro}
690
655
  onOpenTask={onOpenTask}
691
656
  summary={topEntitiesSummary}
692
657
  text={text}