@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
@@ -1,43 +1,123 @@
1
+ import type { CostMonitorProjection } from "@zaip-ai/dashboard-cost-monitor/contracts";
1
2
  import type {
2
- LoadCompactCostPage,
3
3
  CompactLifecycleCostPage,
4
+ LoadCompactCostPage,
4
5
  LoadCostMonitorDetail,
5
6
  LoadCostRunPage,
6
7
  } from "@zaip-ai/dashboard-cost-monitor/react";
7
8
  import { useCallback } from "react";
8
- import type { CostMonitorProjection } from "@zaip-ai/dashboard-cost-monitor/contracts";
9
9
  export type LoadCostGroupPage = import("@zaip-ai/dashboard-cost-monitor/react").LoadCostGroupPage;
10
+
10
11
  import type { DashboardApiClient, SqliteViewPage } from "./dashboard-api.js";
11
- import { costGroupDuration, legacyKnownMetric, nullableSqlNumber, requiredSqlNumber } from "./sqlite-cost-adapters.js";
12
+ import {
13
+ costGroupDuration,
14
+ legacyKnownMetric,
15
+ nullableSqlNumber,
16
+ requiredSqlNumber,
17
+ } from "./sqlite-cost-adapters.js";
12
18
 
13
19
  type CostGroupLoadRequest = Parameters<LoadCostGroupPage>[0];
14
20
 
15
21
  function costGroupQueryOptions(request: CostGroupLoadRequest, offset: number, limit: number) {
16
22
  const { filters, query } = request;
17
- return { offset, limit, ...(query === undefined || query === "" ? {} : { query }), ...(filters.provider ? { provider: filters.provider } : {}), ...(filters.model ? { model: filters.model } : {}), ...(filters.agent ? { agent: filters.agent } : {}), ...(filters.phase ? { phase: filters.phase } : {}), ...(filters.status ? { status: filters.status } : {}), ...(filters.origin ? { origin: filters.origin } : {}), ...(filters.workType ? { workType: filters.workType } : {}), ...(filters.priority ? { priority: filters.priority } : {}), ...(filters.risk ? { risk: filters.risk } : {}) };
23
+ return {
24
+ offset,
25
+ limit,
26
+ ...(query === undefined || query === "" ? {} : { query }),
27
+ ...(filters.provider ? { provider: filters.provider } : {}),
28
+ ...(filters.model ? { model: filters.model } : {}),
29
+ ...(filters.agent ? { agent: filters.agent } : {}),
30
+ ...(filters.phase ? { phase: filters.phase } : {}),
31
+ ...(filters.status ? { status: filters.status } : {}),
32
+ ...(filters.origin ? { origin: filters.origin } : {}),
33
+ ...(filters.workType ? { workType: filters.workType } : {}),
34
+ ...(filters.priority ? { priority: filters.priority } : {}),
35
+ ...(filters.risk ? { risk: filters.risk } : {}),
36
+ };
18
37
  }
19
38
 
20
39
  function adaptSqliteCostGroup(row: Record<string, unknown>) {
21
40
  const duration = costGroupDuration(row);
22
41
  const durationUnknown = Number(row.duration_unknown ?? (duration === null ? 1 : 0));
23
42
  const durationKnown = nullableSqlNumber(row.duration_known) ?? duration ?? 0;
24
- return { key: String(row.key ?? row.period_key ?? "total"), label: String(row.label ?? row.key ?? row.period_key ?? ""), latest_started_at: typeof row.latest_started_at === "string" ? row.latest_started_at : "", persona: typeof row.persona === "string" ? row.persona : null, job: typeof row.job === "string" ? row.job : null, run_count: Number(row.total_run_count ?? row.invocation_count ?? 0), task_count: nullableSqlNumber(row.task_count), prd_count: Number(row.prd_count ?? 0), spec_count: Number(row.spec_count ?? 0), evidence_count: Number(row.evidence_count ?? 0), test_count: Number(row.validation_count ?? 0), event_count: Number(row.source_event_count ?? 0), total_tokens: nullableSqlNumber(row.total_tokens), estimated_usd: nullableSqlNumber(row.total_cost_usd), estimated_brl: nullableSqlNumber(row.total_cost_brl), duration_ms: duration, duration: { known_sum: durationKnown, unknown: durationUnknown, complete: durationUnknown === 0, coverage_ratio: durationUnknown === 0 ? 1 : 0 }, coverage: { events: 0, tokens: 0, usd: 0, brl: 0 } };
43
+ return {
44
+ key: String(row.key ?? row.period_key ?? "total"),
45
+ label: String(row.label ?? row.key ?? row.period_key ?? ""),
46
+ latest_started_at: typeof row.latest_started_at === "string" ? row.latest_started_at : "",
47
+ persona: typeof row.persona === "string" ? row.persona : null,
48
+ job: typeof row.job === "string" ? row.job : null,
49
+ run_count: Number(row.total_run_count ?? row.invocation_count ?? 0),
50
+ task_count: nullableSqlNumber(row.task_count),
51
+ prd_count: Number(row.prd_count ?? 0),
52
+ spec_count: Number(row.spec_count ?? 0),
53
+ evidence_count: Number(row.evidence_count ?? 0),
54
+ test_count: Number(row.validation_count ?? 0),
55
+ event_count: Number(row.source_event_count ?? 0),
56
+ total_tokens: nullableSqlNumber(row.total_tokens),
57
+ estimated_usd: nullableSqlNumber(row.total_cost_usd),
58
+ estimated_brl: nullableSqlNumber(row.total_cost_brl),
59
+ duration_ms: duration,
60
+ duration: {
61
+ known_sum: durationKnown,
62
+ unknown: durationUnknown,
63
+ complete: durationUnknown === 0,
64
+ coverage_ratio: durationUnknown === 0 ? 1 : 0,
65
+ },
66
+ coverage: { events: 0, tokens: 0, usd: 0, brl: 0 },
67
+ };
25
68
  }
26
69
 
27
- export async function loadSqliteCostGroupPage(api: DashboardApiClient, request: CostGroupLoadRequest) {
70
+ export async function loadSqliteCostGroupPage(
71
+ api: DashboardApiClient,
72
+ request: CostGroupLoadRequest,
73
+ ) {
28
74
  const { from, limit, offset, signal, to, view } = request;
29
75
  const selectedRange = from === undefined || to === undefined ? undefined : { from, to };
30
76
  if (view === "daily") {
31
- const page = await api.sqliteViewPage("cost_monitor_daily", selectedRange, costGroupQueryOptions(request, offset, limit), signal);
32
- return { offset: page.offset, limit: page.limit, total_count: page.total_count, has_more: page.has_more, rows: page.rows.map(adaptSqliteCostGroup), ...(page.totals === undefined ? {} : { totals: adaptSqliteCostGroup(page.totals) }) };
77
+ const page = await api.sqliteViewPage(
78
+ "cost_monitor_daily",
79
+ selectedRange,
80
+ costGroupQueryOptions(request, offset, limit),
81
+ signal,
82
+ );
83
+ return {
84
+ offset: page.offset,
85
+ limit: page.limit,
86
+ total_count: page.total_count,
87
+ has_more: page.has_more,
88
+ rows: page.rows.map(adaptSqliteCostGroup),
89
+ ...(page.totals === undefined ? {} : { totals: adaptSqliteCostGroup(page.totals) }),
90
+ };
33
91
  }
34
- const sqlView = ({ monthly: "cost_monitor_monthly", annual: "cost_monitor_annual", agents: "cost_monitor_zaip_agents", models: "cost_monitor_models", providers: "cost_monitor_providers" } as const)[view];
35
- const page = await api.sqliteViewPage(sqlView, selectedRange, costGroupQueryOptions(request, offset, limit), signal);
36
- return { offset: page.offset, limit: page.limit, total_count: page.total_count, has_more: page.has_more, rows: page.rows.map(adaptSqliteCostGroup), ...(page.totals === undefined ? {} : { totals: adaptSqliteCostGroup(page.totals) }) };
92
+ const sqlView = (
93
+ {
94
+ monthly: "cost_monitor_monthly",
95
+ annual: "cost_monitor_annual",
96
+ agents: "cost_monitor_zaip_agents",
97
+ models: "cost_monitor_models",
98
+ providers: "cost_monitor_providers",
99
+ } as const
100
+ )[view];
101
+ const page = await api.sqliteViewPage(
102
+ sqlView,
103
+ selectedRange,
104
+ costGroupQueryOptions(request, offset, limit),
105
+ signal,
106
+ );
107
+ return {
108
+ offset: page.offset,
109
+ limit: page.limit,
110
+ total_count: page.total_count,
111
+ has_more: page.has_more,
112
+ rows: page.rows.map(adaptSqliteCostGroup),
113
+ ...(page.totals === undefined ? {} : { totals: adaptSqliteCostGroup(page.totals) }),
114
+ };
37
115
  }
38
116
 
39
117
  /** Adapts a sparse SQLite invocation row to the complete CostRunRow contract. */
40
- export function adaptSqliteCostRun(row: Record<string, unknown>): CostMonitorProjection["runs"][number] {
118
+ export function adaptSqliteCostRun(
119
+ row: Record<string, unknown>,
120
+ ): CostMonitorProjection["runs"][number] {
41
121
  const text = (value: unknown, fallback: string) => (typeof value === "string" ? value : fallback);
42
122
  const nullableNumber = (value: unknown) => (typeof value === "number" ? value : null);
43
123
  const invocationId = text(row.agent_invocation_id, "unavailable");
@@ -46,8 +126,10 @@ export function adaptSqliteCostRun(row: Record<string, unknown>): CostMonitorPro
46
126
  const prdId = typeof row.prd_id === "string" ? row.prd_id : null;
47
127
  const phase = text(row.phase, "execution");
48
128
  const durationProvenance =
49
- row.duration_provenance === "observed" || row.duration_provenance === "reconciled" ||
50
- row.duration_provenance === "estimated" || row.duration_provenance === "legacy_inferred"
129
+ row.duration_provenance === "observed" ||
130
+ row.duration_provenance === "reconciled" ||
131
+ row.duration_provenance === "estimated" ||
132
+ row.duration_provenance === "legacy_inferred"
51
133
  ? row.duration_provenance
52
134
  : "unavailable";
53
135
  const calculatedUsd = Object.hasOwn(row, "calculated_cost_usd")
@@ -80,7 +162,8 @@ export function adaptSqliteCostRun(row: Record<string, unknown>): CostMonitorPro
80
162
  spec_id: specId,
81
163
  prd_id: prdId,
82
164
  change_id: typeof row.change_id === "string" ? row.change_id : null,
83
- parent_run_id: typeof row.parent_agent_invocation_id === "string" ? row.parent_agent_invocation_id : null,
165
+ parent_run_id:
166
+ typeof row.parent_agent_invocation_id === "string" ? row.parent_agent_invocation_id : null,
84
167
  run_role: row.invocation_kind === "subagent" ? "subagent" : "orchestrator",
85
168
  run_kind: row.run_kind === "subrun" ? "subrun" : "run",
86
169
  run_purpose: "execution",
@@ -92,12 +175,14 @@ export function adaptSqliteCostRun(row: Record<string, unknown>): CostMonitorPro
92
175
  model: text(row.model, "unavailable"),
93
176
  requested_model: text(row.requested_model, "unavailable"),
94
177
  reasoning_effort: typeof row.reasoning_effort === "string" ? row.reasoning_effort : null,
95
- effective_reasoning_effort: typeof row.effective_reasoning_effort === "string" ? row.effective_reasoning_effort : null,
178
+ effective_reasoning_effort:
179
+ typeof row.effective_reasoning_effort === "string" ? row.effective_reasoning_effort : null,
96
180
  service_tier: typeof row.service_tier === "string" ? row.service_tier : null,
97
181
  call_count: nullableNumber(row.llm_call_count),
98
182
  status: text(row.status, "completed"),
99
183
  phase,
100
- origin: prdId !== null ? "prd" : specId !== null ? "spec" : taskId !== null ? "task" : "conversation",
184
+ origin:
185
+ prdId !== null ? "prd" : specId !== null ? "spec" : taskId !== null ? "task" : "conversation",
101
186
  work_type: row.work_type === "rework" ? "rework" : "new",
102
187
  started_at: text(row.occurred_at, ""),
103
188
  finished_at: typeof row.finished_at === "string" ? row.finished_at : null,
@@ -146,9 +231,18 @@ export function adaptSqliteCompactLifecyclePage(
146
231
  const totals = page.totals;
147
232
  const subtotalMetric = (key: string) => legacyKnownMetric(totals?.[key]);
148
233
  return {
149
- data_source: "lifecycle_daily_read_models", snapshot_id: null, source_latest_at: null, kind, offset: page.offset, limit: page.limit, total: page.total_count, has_more: page.has_more, next_cursor: null,
234
+ data_source: "lifecycle_daily_read_models",
235
+ snapshot_id: null,
236
+ source_latest_at: null,
237
+ kind,
238
+ offset: page.offset,
239
+ limit: page.limit,
240
+ total: page.total_count,
241
+ has_more: page.has_more,
242
+ next_cursor: null,
150
243
  subtotal: {
151
- entity_count: typeof totals?.entity_count === "number" ? totals.entity_count : page.total_count,
244
+ entity_count:
245
+ typeof totals?.entity_count === "number" ? totals.entity_count : page.total_count,
152
246
  run_count: subtotalMetric("invocation_count"),
153
247
  metrics: {
154
248
  duration: subtotalMetric("total_duration"),
@@ -157,34 +251,130 @@ export function adaptSqliteCompactLifecyclePage(
157
251
  cost_usd: subtotalMetric("total_cost_usd"),
158
252
  },
159
253
  },
160
- rows: page.rows.map((row) => ({ id: String(row.task_id ?? row.spec_id ?? row.prd_id ?? row.execution_id ?? row.conversation_id ?? row.id ?? "unavailable"), title: String(row.title ?? row.task_id ?? row.spec_id ?? row.prd_id ?? row.execution_id ?? row.conversation_id ?? "Unavailable"), kind: kind === "tasks" ? "task" : kind === "specs" ? "spec" : kind === "prds" ? "prd" : kind === "executions" ? "execution" : "conversation", status: typeof row.status === "string" ? row.status : null, risk: typeof row.risk === "string" ? row.risk : null, occurred_at: typeof row.occurred_at === "string" ? row.occurred_at : typeof row.started_at === "string" ? row.started_at : typeof row.last_day === "string" ? `${row.last_day}T12:00:00.000Z` : "", parent_id: null, run_count: Number(row.invocation_count ?? 0), cost_currency: "BRL", metrics: { duration: legacyKnownMetric(row.total_duration), total_tokens: legacyKnownMetric(row.total_tokens), cost: legacyKnownMetric(row.total_cost_brl) } })),
254
+ rows: page.rows.map((row) => ({
255
+ id: String(
256
+ row.task_id ??
257
+ row.spec_id ??
258
+ row.prd_id ??
259
+ row.execution_id ??
260
+ row.conversation_id ??
261
+ row.id ??
262
+ "unavailable",
263
+ ),
264
+ title: String(
265
+ row.title ??
266
+ row.task_id ??
267
+ row.spec_id ??
268
+ row.prd_id ??
269
+ row.execution_id ??
270
+ row.conversation_id ??
271
+ "Unavailable",
272
+ ),
273
+ kind:
274
+ kind === "tasks"
275
+ ? "task"
276
+ : kind === "specs"
277
+ ? "spec"
278
+ : kind === "prds"
279
+ ? "prd"
280
+ : kind === "executions"
281
+ ? "execution"
282
+ : "conversation",
283
+ status: typeof row.status === "string" ? row.status : null,
284
+ risk: typeof row.risk === "string" ? row.risk : null,
285
+ occurred_at:
286
+ typeof row.occurred_at === "string"
287
+ ? row.occurred_at
288
+ : typeof row.started_at === "string"
289
+ ? row.started_at
290
+ : typeof row.last_day === "string"
291
+ ? `${row.last_day}T12:00:00.000Z`
292
+ : "",
293
+ parent_id: null,
294
+ run_count: Number(row.invocation_count ?? 0),
295
+ cost_currency: "BRL",
296
+ metrics: {
297
+ duration: legacyKnownMetric(row.total_duration),
298
+ total_tokens: legacyKnownMetric(row.total_tokens),
299
+ cost: legacyKnownMetric(row.total_cost_brl),
300
+ },
301
+ })),
161
302
  };
162
303
  }
163
304
 
164
305
  export function useAppCostLoaders(api: DashboardApiClient) {
165
- const loadCostDetail = useCallback<LoadCostMonitorDetail>(
166
- async () => { throw new Error("SQLite Cost Monitor loads the selected paginated view; full detail is disabled."); },
167
- [api],
168
- );
306
+ const loadCostDetail = useCallback<LoadCostMonitorDetail>(async () => {
307
+ throw new Error(
308
+ "SQLite Cost Monitor loads the selected paginated view; full detail is disabled.",
309
+ );
310
+ }, []);
169
311
  const loadCostReadModelPage = useCallback<LoadCompactCostPage>(
170
312
  async ({ filters, from, kind, limit, offset, query, signal, to }) => {
171
- const view = ({ tasks: "cost_monitor_tasks", specs: "cost_monitor_specs", prds: "cost_monitor_prds", executions: "cost_monitor_executions", conversations: "cost_monitor_conversations" } as const)[kind];
172
- const page = await api.sqliteViewPage(view, from === undefined || to === undefined ? undefined : { from, to }, { offset, limit, ...(query === undefined || query === "" ? {} : { query }), ...(filters.provider ? { provider: filters.provider } : {}), ...(filters.model ? { model: filters.model } : {}), ...(filters.agent ? { agent: filters.agent } : {}), ...(filters.phase ? { phase: filters.phase } : {}), ...(filters.status ? { status: filters.status } : {}), ...(filters.origin ? { origin: filters.origin } : {}), ...(filters.workType ? { workType: filters.workType } : {}), ...(filters.priority ? { priority: filters.priority } : {}), ...(filters.risk ? { risk: filters.risk } : {}) }, signal);
313
+ const view = (
314
+ {
315
+ tasks: "cost_monitor_tasks",
316
+ specs: "cost_monitor_specs",
317
+ prds: "cost_monitor_prds",
318
+ executions: "cost_monitor_executions",
319
+ conversations: "cost_monitor_conversations",
320
+ } as const
321
+ )[kind];
322
+ const page = await api.sqliteViewPage(
323
+ view,
324
+ from === undefined || to === undefined ? undefined : { from, to },
325
+ {
326
+ offset,
327
+ limit,
328
+ ...(query === undefined || query === "" ? {} : { query }),
329
+ ...(filters.provider ? { provider: filters.provider } : {}),
330
+ ...(filters.model ? { model: filters.model } : {}),
331
+ ...(filters.agent ? { agent: filters.agent } : {}),
332
+ ...(filters.phase ? { phase: filters.phase } : {}),
333
+ ...(filters.status ? { status: filters.status } : {}),
334
+ ...(filters.origin ? { origin: filters.origin } : {}),
335
+ ...(filters.workType ? { workType: filters.workType } : {}),
336
+ ...(filters.priority ? { priority: filters.priority } : {}),
337
+ ...(filters.risk ? { risk: filters.risk } : {}),
338
+ },
339
+ signal,
340
+ );
173
341
  return adaptSqliteCompactLifecyclePage(kind, page);
174
342
  },
175
343
  [api],
176
344
  );
177
345
  const loadCostRunPage = useCallback<LoadCostRunPage>(
178
346
  async ({ filters, from, offset, signal, to }) => {
179
- const page = await api.sqliteViewPage("cost_monitor_agent_invocations", from === undefined || to === undefined ? undefined : { from, to }, { offset, limit: 100, ...(filters?.query ? { query: filters.query } : {}), ...(filters?.provider ? { provider: filters.provider } : {}), ...(filters?.model ? { model: filters.model } : {}), ...(filters?.agent ? { agent: filters.agent } : {}), ...(filters?.phase ? { phase: filters.phase } : {}), ...(filters?.status ? { status: filters.status } : {}) }, signal);
347
+ const page = await api.sqliteViewPage(
348
+ "cost_monitor_agent_invocations",
349
+ from === undefined || to === undefined ? undefined : { from, to },
350
+ {
351
+ offset,
352
+ limit: 100,
353
+ ...(filters?.query ? { query: filters.query } : {}),
354
+ ...(filters?.provider ? { provider: filters.provider } : {}),
355
+ ...(filters?.model ? { model: filters.model } : {}),
356
+ ...(filters?.agent ? { agent: filters.agent } : {}),
357
+ ...(filters?.phase ? { phase: filters.phase } : {}),
358
+ ...(filters?.status ? { status: filters.status } : {}),
359
+ },
360
+ signal,
361
+ );
180
362
  return {
181
363
  page_only: true,
182
364
  runs: page.rows.map(adaptSqliteCostRun),
183
- run_page: { offset: page.offset, limit: page.limit, total: page.total_count, has_more: page.has_more },
365
+ run_page: {
366
+ offset: page.offset,
367
+ limit: page.limit,
368
+ total: page.total_count,
369
+ has_more: page.has_more,
370
+ },
184
371
  };
185
372
  },
186
373
  [api],
187
374
  );
188
- const loadCostGroupPage = useCallback<LoadCostGroupPage>((request) => loadSqliteCostGroupPage(api, request), [api]);
375
+ const loadCostGroupPage = useCallback<LoadCostGroupPage>(
376
+ (request) => loadSqliteCostGroupPage(api, request),
377
+ [api],
378
+ );
189
379
  return { loadCostDetail, loadCostReadModelPage, loadCostRunPage, loadCostGroupPage };
190
380
  }
@@ -1,6 +1,12 @@
1
1
  import type { CostCurrency, CostLocale } from "@zaip-ai/dashboard-cost-monitor/react";
2
2
  import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contracts";
3
- import { type Dispatch, type MutableRefObject, type SetStateAction, useEffect } from "react";
3
+ import {
4
+ type Dispatch,
5
+ type MutableRefObject,
6
+ type SetStateAction,
7
+ useEffect,
8
+ useRef,
9
+ } from "react";
4
10
  import { pricingSetupPath, projectSetupPath } from "./AppSetupRoutes.js";
5
11
  import { currencyKey, localeKey } from "./app-preferences.js";
6
12
  import type { DashboardView } from "./DashboardCapabilityNav.js";
@@ -10,6 +16,24 @@ import {
10
16
  shouldHydrateOperationsDetails,
11
17
  } from "./operations-detail-hydration.js";
12
18
 
19
+ export const projectionRefreshDebounceMs = 5_000;
20
+
21
+ export function shouldRefreshVisibleProjection({
22
+ inFlight,
23
+ lastRefreshAt,
24
+ now,
25
+ visibilityState,
26
+ }: {
27
+ inFlight: boolean;
28
+ lastRefreshAt: number;
29
+ now: number;
30
+ visibilityState: DocumentVisibilityState;
31
+ }): boolean {
32
+ return (
33
+ visibilityState === "visible" && !inFlight && now - lastRefreshAt >= projectionRefreshDebounceMs
34
+ );
35
+ }
36
+
13
37
  export function useAppEffects({
14
38
  api,
15
39
  costLocale,
@@ -40,13 +64,19 @@ export function useAppEffects({
40
64
  operationsPageAbortRef: MutableRefObject<AbortController | null>;
41
65
  pathname: string;
42
66
  pricing: PricingCatalog | null;
43
- refresh: (visible?: boolean, reconcileOpenWork?: boolean) => Promise<void>;
67
+ refresh: (
68
+ visible?: boolean,
69
+ reconcileOpenWork?: boolean,
70
+ refreshProjection?: boolean,
71
+ ) => Promise<void>;
44
72
  refreshVersion: MutableRefObject<number>;
45
73
  setError: Dispatch<SetStateAction<string | null>>;
46
74
  setFxRate: Dispatch<SetStateAction<Awaited<ReturnType<DashboardApiClient["fxRate"]>> | null>>;
47
75
  setPathname: Dispatch<SetStateAction<string>>;
48
76
  setPricing: Dispatch<SetStateAction<PricingCatalog | null>>;
49
77
  }) {
78
+ const projectionRefreshInFlight = useRef(false);
79
+ const lastProjectionRefreshAt = useRef(0);
50
80
  useEffect(() => {
51
81
  void refresh();
52
82
  return () => {
@@ -66,6 +96,34 @@ export function useAppEffects({
66
96
  refreshVersion,
67
97
  ]);
68
98
 
99
+ useEffect(() => {
100
+ const refreshVisibleProjection = () => {
101
+ const now = Date.now();
102
+ // Focus and visibilitychange commonly arrive together. Coalesce them
103
+ // rather than polling or rebuilding during ordinary navigation.
104
+ if (
105
+ !shouldRefreshVisibleProjection({
106
+ inFlight: projectionRefreshInFlight.current,
107
+ lastRefreshAt: lastProjectionRefreshAt.current,
108
+ now,
109
+ visibilityState: document.visibilityState,
110
+ })
111
+ )
112
+ return;
113
+ lastProjectionRefreshAt.current = now;
114
+ projectionRefreshInFlight.current = true;
115
+ void refresh(false, false, true).finally(() => {
116
+ projectionRefreshInFlight.current = false;
117
+ });
118
+ };
119
+ window.addEventListener("focus", refreshVisibleProjection);
120
+ document.addEventListener("visibilitychange", refreshVisibleProjection);
121
+ return () => {
122
+ window.removeEventListener("focus", refreshVisibleProjection);
123
+ document.removeEventListener("visibilitychange", refreshVisibleProjection);
124
+ };
125
+ }, [refresh]);
126
+
69
127
  useEffect(() => {
70
128
  if (
71
129
  !shouldHydrateOperationsDetails(
@@ -93,11 +151,7 @@ export function useAppEffects({
93
151
  useEffect(() => window.localStorage.setItem(currencyKey, currency), [currency]);
94
152
 
95
153
  useEffect(() => {
96
- if (
97
- !["/", pricingSetupPath, projectSetupPath].includes(
98
- window.location.pathname,
99
- )
100
- ) {
154
+ if (!["/", pricingSetupPath, projectSetupPath].includes(window.location.pathname)) {
101
155
  window.history.replaceState(null, "", `/${window.location.search}${window.location.hash}`);
102
156
  setPathname("/");
103
157
  }
@@ -153,8 +153,7 @@ export function useAppOperationsPages({
153
153
  typeof row.source_duration_ms === "number" ? row.source_duration_ms : null,
154
154
  duration_provenance:
155
155
  typeof row.duration_provenance === "string" ? row.duration_provenance : null,
156
- llm_call_count:
157
- typeof row.llm_call_count === "number" ? row.llm_call_count : null,
156
+ llm_call_count: typeof row.llm_call_count === "number" ? row.llm_call_count : null,
158
157
  input_tokens: typeof row.input_tokens === "number" ? row.input_tokens : null,
159
158
  cached_input_tokens:
160
159
  typeof row.cached_input_tokens === "number" ? row.cached_input_tokens : null,
@@ -198,12 +197,10 @@ export function useAppOperationsPages({
198
197
  typeof row.standard_cost_usd === "number" ? row.standard_cost_usd : null,
199
198
  speed_uplift_usd:
200
199
  typeof row.speed_uplift_usd === "number" ? row.speed_uplift_usd : null,
201
- input_cost_usd:
202
- typeof row.input_cost_usd === "number" ? row.input_cost_usd : null,
200
+ input_cost_usd: typeof row.input_cost_usd === "number" ? row.input_cost_usd : null,
203
201
  cached_input_cost_usd:
204
202
  typeof row.cached_input_cost_usd === "number" ? row.cached_input_cost_usd : null,
205
- output_cost_usd:
206
- typeof row.output_cost_usd === "number" ? row.output_cost_usd : null,
203
+ output_cost_usd: typeof row.output_cost_usd === "number" ? row.output_cost_usd : null,
207
204
  reasoning_cost_usd:
208
205
  typeof row.reasoning_cost_usd === "number" ? row.reasoning_cost_usd : null,
209
206
  calculated_cost_usd:
@@ -9,7 +9,8 @@ describe("Trabalho (Lista) canonical pagination", () => {
9
9
  it("keeps a server-selected PRD/SPEC kind instead of refetching every kind", () => {
10
10
  expect(selectedWorkListKinds("spec")).toEqual(["spec"]);
11
11
  expect(selectedWorkListKinds("prd")).toEqual(["prd"]);
12
- expect(selectedWorkListKinds("")).toEqual(["prd", "spec", "task"]);
12
+ expect(selectedWorkListKinds("standalone-task")).toEqual(["standalone-task"]);
13
+ expect(selectedWorkListKinds("")).toEqual(["prd", "spec", "task", "standalone-task"]);
13
14
  });
14
15
 
15
16
  it("retains the List type through search/status changes without mutating the Kanban snapshot", () => {
@@ -32,7 +33,6 @@ describe("Trabalho (Lista) canonical pagination", () => {
32
33
  expect(kanban).toEqual({ query: "kanban", status: "ready", risk: "", kind: "" });
33
34
  });
34
35
 
35
-
36
36
  it("continues from the returned offset until the canonical total is complete", async () => {
37
37
  const loadPage = vi
38
38
  .fn()
@@ -1,4 +1,4 @@
1
- export type WorkListKind = "prd" | "spec" | "task";
1
+ export type WorkListKind = "prd" | "spec" | "task" | "standalone-task";
2
2
 
3
3
  export type WorkListFilters = {
4
4
  query: string;
@@ -16,11 +16,10 @@ export function normalizeWorkListFilters(
16
16
  return { ...filters, kind: filters.kind ?? previous.kind ?? "" };
17
17
  }
18
18
 
19
-
20
19
  export function selectedWorkListKinds(kind: string | undefined): readonly WorkListKind[] {
21
- return kind === "prd" || kind === "spec" || kind === "task"
20
+ return kind === "prd" || kind === "spec" || kind === "task" || kind === "standalone-task"
22
21
  ? [kind]
23
- : ["prd", "spec", "task"];
22
+ : ["prd", "spec", "task", "standalone-task"];
24
23
  }
25
24
 
26
25
  export async function collectWorkListPages<T>(
@@ -61,7 +61,10 @@ export default defineConfig({
61
61
  if (normalized.includes("/modules/cost-monitor/")) return "cost-monitor";
62
62
  if (normalized.includes("/modules/operations/")) return "operations";
63
63
  if (normalized.includes("/modules/traceability/")) return "traceability";
64
- if (id.includes("node_modules/.pnpm/react@") || id.includes("node_modules/.pnpm/react-dom@"))
64
+ if (
65
+ id.includes("node_modules/.pnpm/react@") ||
66
+ id.includes("node_modules/.pnpm/react-dom@")
67
+ )
65
68
  return "react-vendor";
66
69
  if (id.includes("node_modules/.pnpm/lucide-react@")) return "icons-vendor";
67
70
  return undefined;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-cost-monitor",
3
- "version": "1.0.8",
3
+ "version": "1.3.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {