@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.
- package/dist/services/adapter-hook-sources.d.ts +3 -0
- package/dist/services/adapter-hook-sources.d.ts.map +1 -1
- package/dist/services/adapter-hook-sources.js +3 -0
- package/dist/services/adapter-hook-sources.js.map +1 -1
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +5 -2
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/adapters.test.js +1 -1
- package/dist/services/adapters.test.js.map +1 -1
- package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
- package/dist/services/codex-conversation-lifecycle-hook.js +16 -6
- package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
- package/dist/services/codex-hook-activation.d.ts +1 -1
- package/dist/services/codex-hook-activation.d.ts.map +1 -1
- package/dist/services/codex-hook-activation.js +116 -10
- package/dist/services/codex-hook-activation.js.map +1 -1
- package/dist/services/codex-pre-tool-cli-capture-template.d.ts +2 -0
- package/dist/services/codex-pre-tool-cli-capture-template.d.ts.map +1 -0
- package/dist/services/codex-pre-tool-cli-capture-template.js +104 -0
- package/dist/services/codex-pre-tool-cli-capture-template.js.map +1 -0
- package/dist/services/codex-pre-tool-cloud-template.d.ts +2 -0
- package/dist/services/codex-pre-tool-cloud-template.d.ts.map +1 -0
- package/dist/services/codex-pre-tool-cloud-template.js +190 -0
- package/dist/services/codex-pre-tool-cloud-template.js.map +1 -0
- package/dist/services/codex-pre-tool-dependencies.test-support.d.ts +2 -0
- package/dist/services/codex-pre-tool-dependencies.test-support.d.ts.map +1 -0
- package/dist/services/codex-pre-tool-dependencies.test-support.js +9 -0
- package/dist/services/codex-pre-tool-dependencies.test-support.js.map +1 -0
- package/dist/services/codex-pre-tool-hook-fixture.test-support.d.ts +5 -0
- package/dist/services/codex-pre-tool-hook-fixture.test-support.d.ts.map +1 -0
- package/dist/services/codex-pre-tool-hook-fixture.test-support.js +19 -0
- package/dist/services/codex-pre-tool-hook-fixture.test-support.js.map +1 -0
- package/dist/services/codex-pre-tool-hook-template-bootstrap.test.d.ts +2 -0
- package/dist/services/codex-pre-tool-hook-template-bootstrap.test.d.ts.map +1 -0
- package/dist/services/codex-pre-tool-hook-template-bootstrap.test.js +107 -0
- package/dist/services/codex-pre-tool-hook-template-bootstrap.test.js.map +1 -0
- package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
- package/dist/services/codex-pre-tool-hook-template.js +96 -210
- package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
- package/dist/services/codex-pre-tool-hook-template.test.js +32 -80
- package/dist/services/codex-pre-tool-hook-template.test.js.map +1 -1
- package/dist/services/codex-pre-tool-host-context-template.d.ts +2 -0
- package/dist/services/codex-pre-tool-host-context-template.d.ts.map +1 -0
- package/dist/services/codex-pre-tool-host-context-template.js +139 -0
- package/dist/services/codex-pre-tool-host-context-template.js.map +1 -0
- package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
- package/dist/services/codex-pre-tool-support-template.js +61 -101
- package/dist/services/codex-pre-tool-support-template.js.map +1 -1
- package/dist/services/codex-subagent-hook-template.d.ts +1 -1
- package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
- package/dist/services/codex-subagent-hook-template.js +13 -2
- package/dist/services/codex-subagent-hook-template.js.map +1 -1
- package/dist/services/codex-validation-runtime-template.d.ts.map +1 -1
- package/dist/services/codex-validation-runtime-template.js +10 -4
- package/dist/services/codex-validation-runtime-template.js.map +1 -1
- package/dist/services/runtime-template-test-support.d.ts +1 -0
- package/dist/services/runtime-template-test-support.d.ts.map +1 -1
- package/dist/services/runtime-template-test-support.js +23 -2
- package/dist/services/runtime-template-test-support.js.map +1 -1
- package/dist/services/runtime-template.test.js +4 -23
- package/dist/services/runtime-template.test.js.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/README-ENG.md +58 -7
- package/templates/.agents/README.md +46 -10
- package/templates/.agents/config/agents/discovery.json +1 -1
- package/templates/.agents/dashboard/.zaip-managed.json +174 -86
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-BW7Vy1cp.js → CostCalculationGuidePage-uR-asJv_.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cp_hEVd8.js → DashboardHelpDialog-CngnpoLL.js} +87 -13
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Prcs-ydy.js → PricingSettingsDialog-Bszw3ekd.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-Cu40wAFF.js → ProjectSettingsPage-IJ1znG4w.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-Bh3YBd3C.js → TraceabilityWorkspace-CsBpHqq_.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-B0Jwz_rk.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-CF7B1Hjn.js → dashboard-localization-D41g5rdo.js} +58 -7
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DOhy6D2-.js → icons-vendor-CjGGux6h.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Bedlm0f7.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CkPC-yMz.js → react-vendor-B9jZSAKf.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-BEdGoIDm.js → traceability-DFpwb0TN.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
- package/templates/.agents/dashboard/apps/frontend/package.json +2 -2
- package/templates/.agents/dashboard/apps/frontend/src/AppDashboardContent.tsx +3 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +16 -7
- package/templates/.agents/dashboard/apps/frontend/src/__tests__/app-composition-support.ts +1 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +2 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.navigation.test.tsx +125 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +67 -9
- package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-app-model.tsx +15 -15
- package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-locale.ts +18 -0
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +10 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.run-page.test.ts +5 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.period-values.test.tsx +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +5 -5
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +36 -43
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-loaders.ts +1 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-formatters.ts +6 -4
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +11 -25
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-summary-defaults.ts +26 -0
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/src/contracts.ts +11 -16
- package/templates/.agents/dashboard/modules/operations/src/planning-contracts.ts +14 -0
- package/templates/.agents/dashboard/modules/operations/src/react/DecisionTable.tsx +65 -0
- package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +5 -71
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +4 -39
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.navigation.test.tsx +150 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewTopPanel.tsx +7 -3
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +14 -43
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +3 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-contract.ts +51 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +12 -3
- package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +1 -0
- package/templates/.agents/dashboard/modules/operations/src/react/use-operations-default-range.ts +16 -0
- package/templates/.agents/dashboard/modules/operations/src/react/use-operations-filter-sync.ts +66 -0
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dashboard-build-fingerprint.mjs +87 -0
- package/templates/.agents/dashboard/packages/local-runtime/dashboard-build-fingerprint.test.mjs +48 -0
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +193 -191
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +169 -169
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-frontend.mjs +29 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +5 -0
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +193 -191
- package/templates/.agents/dashboard/packages/local-runtime/src/active-capture-failure.test.ts +38 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/active-capture-failure.ts +35 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +53 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +18 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +8 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-capture-projection-order.test.ts +118 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-cost-run-search.test.ts +90 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-cost-run-search.ts +86 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-routes.ts +8 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-projection-loaders.ts +13 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +30 -74
- package/templates/.agents/dashboard/packages/local-runtime/src/server-route-handlers.ts +42 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-routes.test.ts +60 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-run-projections.test.ts +12 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-telemetry-command.test.ts +29 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/server-telemetry-refresh.ts +7 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +51 -54
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +28 -45
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts +5 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.test.ts +49 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-invocation-page.ts +44 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-cached-cost-page.ts +11 -10
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-item-index.test.ts +18 -1
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-build.mjs +12 -5
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-paths.mjs +8 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +1 -0
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/qualify-top-five-trace.mjs +53 -0
- package/templates/.agents/dashboard/tests/e2e/verify-top-five-served.mjs +78 -0
- package/templates/.agents/design/.zaip-managed.json +14 -6
- package/templates/.agents/design/apps/catalog/dist/assets/index-BGxXxXTo.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/index.html +1 -1
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/apps/catalog/src/components/TopEntitiesSpecimen.tsx +45 -0
- package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +3 -1
- package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +2 -0
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/requirements/autonomous-assurance.md +11 -2
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +1 -1
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +2 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/rules/run-lifecycle-closure.md +2 -1
- package/templates/.agents/rules/workflow.md +1 -0
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +1178 -764
- package/templates/.agents/runtime/checksums.sha256 +6 -6
- package/templates/.agents/runtime/manifest.json +1 -1
- package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
- package/templates/.agents/runtime/provenance.json +5 -5
- package/templates/.agents/runtime/sbom.cdx.json +59 -59
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -1
- package/templates/.agents/skills/zaip-skill-execution/references/controlled-release-recovery.md +14 -0
- package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +5 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract-cli.test.mjs +53 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.mjs +12 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.test.mjs +26 -32
- package/templates/.agents/skills/zaip-skill-maintenance-enter/SKILL.md +23 -0
- package/templates/.agents/skills/zaip-skill-maintenance-enter/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-maintenance-enter/scripts/maintenance.mjs +213 -0
- package/templates/.agents/skills/zaip-skill-maintenance-enter/scripts/maintenance.test.mjs +207 -0
- package/templates/.agents/skills/zaip-skill-maintenance-exit/SKILL.md +21 -0
- package/templates/.agents/skills/zaip-skill-maintenance-exit/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +2 -0
- package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +37 -8
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/10-seguranca.md +2 -2
- package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +38 -0
- package/templates/template-manifest.json +259 -135
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Co2Jiuzh.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-qVSJnJ0_.js +0 -2
|
@@ -35,12 +35,12 @@ export function AppOverlays({
|
|
|
35
35
|
documentDetail,
|
|
36
36
|
helpOpen,
|
|
37
37
|
loadingArea,
|
|
38
|
-
operations,
|
|
39
38
|
reconciliationResult,
|
|
40
39
|
refreshDialog,
|
|
41
40
|
showTrace,
|
|
42
41
|
trace,
|
|
43
42
|
traceLink,
|
|
43
|
+
traceMacroLoading,
|
|
44
44
|
traceLoadingTaskId,
|
|
45
45
|
closeDocument,
|
|
46
46
|
onCloseHelp,
|
|
@@ -65,8 +65,14 @@ export function AppOverlays({
|
|
|
65
65
|
trace: TaskTrace | null;
|
|
66
66
|
traceLink:
|
|
67
67
|
| { kind: "change"; row: ChangeProjection }
|
|
68
|
-
| {
|
|
68
|
+
| {
|
|
69
|
+
kind: "macro";
|
|
70
|
+
label: "PRD" | "SPEC";
|
|
71
|
+
row: MacroProjection;
|
|
72
|
+
projection: OperationsProjection;
|
|
73
|
+
}
|
|
69
74
|
| null;
|
|
75
|
+
traceMacroLoading: { label: "PRD" | "SPEC"; id: string } | null;
|
|
70
76
|
traceLoadingTaskId: string | null;
|
|
71
77
|
closeDocument: () => void;
|
|
72
78
|
onCloseHelp: () => void;
|
|
@@ -112,9 +118,9 @@ export function AppOverlays({
|
|
|
112
118
|
onOpenTrace(taskId);
|
|
113
119
|
}}
|
|
114
120
|
row={traceLink.row}
|
|
115
|
-
runs={
|
|
116
|
-
specs={
|
|
117
|
-
tasks={
|
|
121
|
+
runs={traceLink.projection.runs}
|
|
122
|
+
specs={traceLink.projection.specs}
|
|
123
|
+
tasks={traceLink.projection.tasks}
|
|
118
124
|
/>
|
|
119
125
|
) : null}
|
|
120
126
|
{documentDetail ? (
|
|
@@ -190,8 +196,11 @@ export function AppOverlays({
|
|
|
190
196
|
onDismiss={onDismissReconciliation}
|
|
191
197
|
/>
|
|
192
198
|
) : null}
|
|
193
|
-
{loadingArea !== null && refreshDialog === null ? (
|
|
194
|
-
<DashboardLoadingNotice
|
|
199
|
+
{(loadingArea !== null || traceMacroLoading !== null) && refreshDialog === null ? (
|
|
200
|
+
<DashboardLoadingNotice
|
|
201
|
+
area={traceMacroLoading === null ? (loadingArea ?? "operations") : "operations"}
|
|
202
|
+
locale={costLocale}
|
|
203
|
+
/>
|
|
195
204
|
) : null}
|
|
196
205
|
</>
|
|
197
206
|
);
|
|
@@ -73,7 +73,7 @@ describe("Cost period refresh", () => {
|
|
|
73
73
|
expect(activeCostReload).toContain(
|
|
74
74
|
"[costs?.currency, currency, failedArea, loadCostSummary, operations]",
|
|
75
75
|
);
|
|
76
|
-
expect(app).toContain("}, [api, currency, operationsPeriod]);");
|
|
76
|
+
expect(app).toContain("}, [api, currency, operationsPeriod, currencyRef]);");
|
|
77
77
|
expect(app).toContain("costsLoadedRef.current = false;");
|
|
78
78
|
});
|
|
79
79
|
|
|
@@ -37,6 +37,7 @@ function renderPeriod(preset: "today" | "yesterday", loading = false) {
|
|
|
37
37
|
onDateChange: vi.fn(),
|
|
38
38
|
onLocaleChange: vi.fn(),
|
|
39
39
|
onOpenDocument: vi.fn(),
|
|
40
|
+
onOpenMacro: vi.fn(),
|
|
40
41
|
onOpenTask: vi.fn(async () => false),
|
|
41
42
|
onPriorityChange: vi.fn(async () => undefined),
|
|
42
43
|
onRefresh: vi.fn(),
|
|
@@ -92,6 +93,7 @@ describe("App-owned Operations period render", () => {
|
|
|
92
93
|
onDateChange: vi.fn(),
|
|
93
94
|
onLocaleChange: vi.fn(),
|
|
94
95
|
onOpenDocument: vi.fn(),
|
|
96
|
+
onOpenMacro: vi.fn(),
|
|
95
97
|
onOpenTask: vi.fn(async () => false),
|
|
96
98
|
onPriorityChange: vi.fn(async () => undefined),
|
|
97
99
|
onRefresh: vi.fn(),
|
package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.navigation.test.tsx
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
const browserRequire = createRequire(
|
|
6
|
+
fileURLToPath(new URL("../../../tests/e2e/package.json", import.meta.url)),
|
|
7
|
+
);
|
|
8
|
+
const { chromium, expect: browserExpect } = browserRequire("@playwright/test");
|
|
9
|
+
|
|
10
|
+
describe("macro trace navigation from a compact overview", () => {
|
|
11
|
+
it("hydrates exact macro details, keeps linked rows, and ignores stale macro and Task requests", async () => {
|
|
12
|
+
const esbuild = browserRequire("esbuild");
|
|
13
|
+
const harness = await esbuild.build({
|
|
14
|
+
bundle: true,
|
|
15
|
+
format: "iife",
|
|
16
|
+
logLevel: "silent",
|
|
17
|
+
platform: "browser",
|
|
18
|
+
write: false,
|
|
19
|
+
stdin: {
|
|
20
|
+
contents: `
|
|
21
|
+
import React, { useState } from "react";
|
|
22
|
+
import { createRoot } from "react-dom/client";
|
|
23
|
+
import { useAppTraceDocuments } from "./use-app-trace-documents.js";
|
|
24
|
+
|
|
25
|
+
const pending = [];
|
|
26
|
+
window.__macroTraceProbe = { pending };
|
|
27
|
+
const api = {
|
|
28
|
+
operations: (_period, _scope, signal) => new Promise((resolve) => {
|
|
29
|
+
pending.push({ resolve, signal });
|
|
30
|
+
}),
|
|
31
|
+
taskTrace: async (id) => ({ task_id: id, task_title: id }),
|
|
32
|
+
prd: async (id) => ({ id, title: id, body: "Full document", artifact_path: "prds/one.md" }),
|
|
33
|
+
};
|
|
34
|
+
function Harness() {
|
|
35
|
+
const [error, setError] = useState(null);
|
|
36
|
+
const [, setFailedArea] = useState(null);
|
|
37
|
+
const [, setLoadingArea] = useState(null);
|
|
38
|
+
const state = useAppTraceDocuments({
|
|
39
|
+
api,
|
|
40
|
+
operations: { prds: [], specs: [], tasks: [], runs: [], changes: [] },
|
|
41
|
+
isOperationsDetailLoaded: () => false,
|
|
42
|
+
setError,
|
|
43
|
+
setFailedArea,
|
|
44
|
+
setLoadingArea,
|
|
45
|
+
});
|
|
46
|
+
return <>
|
|
47
|
+
<button onClick={() => void state.openTraceMacro("SPEC", "SPEC-TARGET")}>Open SPEC</button>
|
|
48
|
+
<button onClick={() => void state.openTraceMacro("PRD", "PRD-TARGET")}>Open PRD</button>
|
|
49
|
+
<button onClick={() => void state.openTrace("TASK-TARGET")}>Open Task</button>
|
|
50
|
+
<button onClick={() => void state.openDocument("prd", "PRD-TARGET")}>Read PRD</button>
|
|
51
|
+
<output id="state">{JSON.stringify({
|
|
52
|
+
macro: state.traceLink?.kind === "macro" ? state.traceLink.row.id : null,
|
|
53
|
+
kind: state.traceLink?.kind === "macro" ? state.traceLink.row.kind : null,
|
|
54
|
+
linkedTaskIds: state.traceLink?.kind === "macro"
|
|
55
|
+
? state.traceLink.projection.tasks.map((row) => row.id) : [],
|
|
56
|
+
loading: state.traceMacroLoading?.id ?? null,
|
|
57
|
+
task: state.trace?.task_id ?? null,
|
|
58
|
+
document: state.documentDetail?.preview.id ?? null,
|
|
59
|
+
error,
|
|
60
|
+
})}</output>
|
|
61
|
+
</>;
|
|
62
|
+
}
|
|
63
|
+
createRoot(document.getElementById("root")).render(<Harness />);
|
|
64
|
+
`,
|
|
65
|
+
loader: "tsx",
|
|
66
|
+
resolveDir: fileURLToPath(new URL(".", import.meta.url)),
|
|
67
|
+
sourcefile: "macro-trace-navigation-harness.tsx",
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
const browser = await chromium.launch({ headless: true });
|
|
71
|
+
try {
|
|
72
|
+
const page = await browser.newPage();
|
|
73
|
+
const pageErrors: string[] = [];
|
|
74
|
+
page.on("pageerror", (error: Error) => pageErrors.push(error.message));
|
|
75
|
+
await page.setContent('<div id="root"></div>');
|
|
76
|
+
await page.addScriptTag({ content: harness.outputFiles[0].text });
|
|
77
|
+
const state = () => page.locator("#state");
|
|
78
|
+
const resolve = (index: number, prds: unknown[], specs: unknown[]) =>
|
|
79
|
+
page.evaluate(
|
|
80
|
+
({ index, prds, specs }: { index: number; prds: unknown[]; specs: unknown[] }) => {
|
|
81
|
+
const request = (
|
|
82
|
+
window as typeof window & {
|
|
83
|
+
__macroTraceProbe: { pending: Array<{ resolve: (value: unknown) => void }> };
|
|
84
|
+
}
|
|
85
|
+
).__macroTraceProbe.pending[index];
|
|
86
|
+
if (!request) throw new Error(`Missing pending macro request ${index}`);
|
|
87
|
+
request.resolve({
|
|
88
|
+
prds,
|
|
89
|
+
specs,
|
|
90
|
+
tasks: [{ id: "TASK-LINKED" }],
|
|
91
|
+
runs: [],
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
{ index, prds, specs },
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
await page.getByRole("button", { name: "Open SPEC" }).click();
|
|
98
|
+
await browserExpect(state()).toContainText('"loading":"SPEC-TARGET"');
|
|
99
|
+
await page.getByRole("button", { name: "Open PRD" }).click();
|
|
100
|
+
await browserExpect(state()).toContainText('"loading":"PRD-TARGET"');
|
|
101
|
+
await resolve(0, [], [{ id: "SPEC-TARGET", kind: "spec" }]);
|
|
102
|
+
await browserExpect(state()).toContainText('"macro":null');
|
|
103
|
+
await resolve(1, [{ id: "PRD-TARGET", kind: "prd" }], []);
|
|
104
|
+
await browserExpect(state()).toContainText('"macro":"PRD-TARGET"');
|
|
105
|
+
await browserExpect(state()).toContainText('"linkedTaskIds":["TASK-LINKED"]');
|
|
106
|
+
await page.getByRole("button", { name: "Read PRD" }).click();
|
|
107
|
+
await browserExpect(state()).toContainText('"document":"PRD-TARGET"');
|
|
108
|
+
|
|
109
|
+
await page.getByRole("button", { name: "Open SPEC" }).click();
|
|
110
|
+
await page.getByRole("button", { name: "Open Task" }).click();
|
|
111
|
+
await browserExpect(state()).toContainText('"task":"TASK-TARGET"');
|
|
112
|
+
await resolve(2, [], [{ id: "SPEC-TARGET", kind: "spec" }]);
|
|
113
|
+
await browserExpect(state()).toContainText('"macro":null');
|
|
114
|
+
|
|
115
|
+
await page.getByRole("button", { name: "Open PRD" }).click();
|
|
116
|
+
await resolve(3, [{ id: "PRD-OTHER", kind: "prd" }], []);
|
|
117
|
+
await browserExpect(state()).toContainText('"error":"PRD PRD-TARGET not found"');
|
|
118
|
+
await browserExpect(state()).toContainText('"loading":null');
|
|
119
|
+
expect(pageErrors).toEqual([]);
|
|
120
|
+
await page.close();
|
|
121
|
+
} finally {
|
|
122
|
+
await browser.close();
|
|
123
|
+
}
|
|
124
|
+
}, 60_000);
|
|
125
|
+
});
|
|
@@ -13,12 +13,14 @@ import type { DashboardApiClient } from "./dashboard-api.js";
|
|
|
13
13
|
export function useAppTraceDocuments({
|
|
14
14
|
api,
|
|
15
15
|
operations,
|
|
16
|
+
isOperationsDetailLoaded,
|
|
16
17
|
setError,
|
|
17
18
|
setFailedArea,
|
|
18
19
|
setLoadingArea,
|
|
19
20
|
}: {
|
|
20
21
|
api: DashboardApiClient;
|
|
21
22
|
operations: OperationsProjection | null;
|
|
23
|
+
isOperationsDetailLoaded: () => boolean;
|
|
22
24
|
setError: Dispatch<SetStateAction<string | null>>;
|
|
23
25
|
setFailedArea: Dispatch<SetStateAction<LoadingArea | null>>;
|
|
24
26
|
setLoadingArea: Dispatch<SetStateAction<LoadingArea | null>>;
|
|
@@ -34,16 +36,31 @@ export function useAppTraceDocuments({
|
|
|
34
36
|
} | null>(null);
|
|
35
37
|
const [traceLink, setTraceLink] = useState<
|
|
36
38
|
| { kind: "change"; row: ChangeProjection }
|
|
37
|
-
| {
|
|
39
|
+
| {
|
|
40
|
+
kind: "macro";
|
|
41
|
+
label: "PRD" | "SPEC";
|
|
42
|
+
row: MacroProjection;
|
|
43
|
+
projection: OperationsProjection;
|
|
44
|
+
}
|
|
38
45
|
| null
|
|
39
46
|
>(null);
|
|
40
47
|
const documentRequestId = useRef(0);
|
|
41
48
|
const traceRequestId = useRef(0);
|
|
49
|
+
const macroRequestId = useRef(0);
|
|
50
|
+
const macroAbortController = useRef<AbortController | null>(null);
|
|
51
|
+
const [traceMacroLoading, setTraceMacroLoading] = useState<{
|
|
52
|
+
label: "PRD" | "SPEC";
|
|
53
|
+
id: string;
|
|
54
|
+
} | null>(null);
|
|
42
55
|
const traceAbortController = useRef<AbortController | null>(null);
|
|
43
56
|
const [traceLoadingTaskId, setTraceLoadingTaskId] = useState<string | null>(null);
|
|
44
57
|
const [selectedTraceTaskId, setSelectedTraceTaskId] = useState("");
|
|
45
58
|
|
|
46
59
|
async function openTrace(taskId: string) {
|
|
60
|
+
macroRequestId.current += 1;
|
|
61
|
+
macroAbortController.current?.abort();
|
|
62
|
+
setTraceMacroLoading(null);
|
|
63
|
+
setTraceLink(null);
|
|
47
64
|
const requestId = ++traceRequestId.current;
|
|
48
65
|
traceAbortController.current?.abort();
|
|
49
66
|
const controller = new AbortController();
|
|
@@ -92,18 +109,58 @@ export function useAppTraceDocuments({
|
|
|
92
109
|
setTraceLink({ kind: "change", row });
|
|
93
110
|
}
|
|
94
111
|
|
|
95
|
-
function openTraceMacro(label: "PRD" | "SPEC", id: string) {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
async function openTraceMacro(label: "PRD" | "SPEC", id: string) {
|
|
113
|
+
const requestId = ++macroRequestId.current;
|
|
114
|
+
macroAbortController.current?.abort();
|
|
115
|
+
macroAbortController.current = null;
|
|
116
|
+
traceRequestId.current += 1;
|
|
117
|
+
traceAbortController.current?.abort();
|
|
118
|
+
traceAbortController.current = null;
|
|
119
|
+
setTraceLoadingTaskId(null);
|
|
120
|
+
setLoadingArea((current) => (current === "traceability" ? null : current));
|
|
121
|
+
setError(null);
|
|
122
|
+
setFailedArea(null);
|
|
99
123
|
setTrace(null);
|
|
100
|
-
setTraceLink(
|
|
124
|
+
setTraceLink(null);
|
|
125
|
+
const rows = label === "PRD" ? operations?.prds : operations?.specs;
|
|
126
|
+
const existing = rows?.find((macro) => macro.id === id && macro.kind === label.toLowerCase());
|
|
127
|
+
if (existing && operations && isOperationsDetailLoaded()) {
|
|
128
|
+
setTraceMacroLoading(null);
|
|
129
|
+
setTraceLink({ kind: "macro", label, row: existing, projection: operations });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const controller = new AbortController();
|
|
133
|
+
macroAbortController.current = controller;
|
|
134
|
+
setTraceMacroLoading({ label, id });
|
|
135
|
+
try {
|
|
136
|
+
// The compact first fold has ranking IDs but omits macro and linked Task rows.
|
|
137
|
+
// Hydrate only after the user requests this traceability dialog.
|
|
138
|
+
const projection = await api.operations(undefined, "detail", controller.signal);
|
|
139
|
+
if (requestId !== macroRequestId.current || controller.signal.aborted) return;
|
|
140
|
+
const row = (label === "PRD" ? projection.prds : projection.specs).find(
|
|
141
|
+
(macro) => macro.id === id && macro.kind === label.toLowerCase(),
|
|
142
|
+
);
|
|
143
|
+
if (!row) throw new Error(`${label} ${id} not found`);
|
|
144
|
+
setTraceLink({ kind: "macro", label, row, projection });
|
|
145
|
+
} catch (cause) {
|
|
146
|
+
if (requestId !== macroRequestId.current || controller.signal.aborted) return;
|
|
147
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
148
|
+
} finally {
|
|
149
|
+
if (requestId === macroRequestId.current) {
|
|
150
|
+
if (macroAbortController.current === controller) macroAbortController.current = null;
|
|
151
|
+
setTraceMacroLoading(null);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
101
154
|
}
|
|
102
155
|
|
|
103
156
|
async function openDocument(kind: "prd" | "spec", id: string) {
|
|
104
|
-
const preview =
|
|
105
|
-
(macro) => macro.id === id
|
|
106
|
-
|
|
157
|
+
const preview =
|
|
158
|
+
(kind === "prd" ? operations?.prds : operations?.specs)?.find((macro) => macro.id === id) ??
|
|
159
|
+
(traceLink?.kind === "macro"
|
|
160
|
+
? (kind === "prd" ? traceLink.projection.prds : traceLink.projection.specs).find(
|
|
161
|
+
(macro) => macro.id === id,
|
|
162
|
+
)
|
|
163
|
+
: undefined);
|
|
107
164
|
if (!preview) return;
|
|
108
165
|
const requestId = ++documentRequestId.current;
|
|
109
166
|
const label = kind === "prd" ? "PRD" : "SPEC";
|
|
@@ -143,6 +200,7 @@ export function useAppTraceDocuments({
|
|
|
143
200
|
setTraceTasks,
|
|
144
201
|
trace,
|
|
145
202
|
traceLink,
|
|
203
|
+
traceMacroLoading,
|
|
146
204
|
traceLoadingTaskId,
|
|
147
205
|
traceTasks,
|
|
148
206
|
};
|
|
@@ -62,6 +62,7 @@ import { useAppTraceDocuments } from "./use-app-trace-documents.js";
|
|
|
62
62
|
import { useAppTraceTaskPagination } from "./use-app-trace-task-pagination.js";
|
|
63
63
|
import { useAppWorkBoard } from "./use-app-work-board.js";
|
|
64
64
|
import { useAppWorkListPage } from "./use-app-work-list-page.js";
|
|
65
|
+
import { useDashboardLocale } from "./use-dashboard-locale.js";
|
|
65
66
|
import { useOperationsDetailExport } from "./use-operations-detail-export.js";
|
|
66
67
|
import { useSnapshotNotice } from "./use-snapshot-notice.js";
|
|
67
68
|
import "./loading-feedback.css";
|
|
@@ -103,18 +104,8 @@ export function useDashboardAppModel() {
|
|
|
103
104
|
useState<OverviewClassificationPages>({});
|
|
104
105
|
const [costs, setCosts] = useState<CostMonitorProjection | null>(null);
|
|
105
106
|
const [displayedCosts, setDisplayedCosts] = useState<CostMonitorProjection | null>(null);
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
window.localStorage.getItem(currencyKey) === "USD" ? "USD" : "BRL",
|
|
109
|
-
);
|
|
110
|
-
const currencyRef = useRef(currency);
|
|
111
|
-
currencyRef.current = currency;
|
|
112
|
-
// Language is the global selector's source of truth for the paired display
|
|
113
|
-
// currency, so Operations and Cost Monitor cannot diverge.
|
|
114
|
-
const changeDashboardLocale = useCallback((next: CostLocale) => {
|
|
115
|
-
setCostLocale(next);
|
|
116
|
-
setCurrency(next === "en-US" ? "USD" : "BRL");
|
|
117
|
-
}, []);
|
|
107
|
+
const { costLocale, currency, setCurrency, currencyRef, changeDashboardLocale } =
|
|
108
|
+
useDashboardLocale();
|
|
118
109
|
const [operationsPeriod, setOperationsPeriod] = useState(() => defaultOperationsPeriod);
|
|
119
110
|
// All Time may update its displayed factual range without changing the
|
|
120
111
|
// unbounded request identity. Keep the refresh callback stable for that
|
|
@@ -174,6 +165,7 @@ export function useDashboardAppModel() {
|
|
|
174
165
|
cancelled = true;
|
|
175
166
|
};
|
|
176
167
|
}, [api, applyDashboardIdentity]);
|
|
168
|
+
const operationsDetailLoadedRef = useRef(false);
|
|
177
169
|
const {
|
|
178
170
|
closeDocument,
|
|
179
171
|
documentDetail,
|
|
@@ -181,6 +173,7 @@ export function useDashboardAppModel() {
|
|
|
181
173
|
openTrace,
|
|
182
174
|
openTraceChange,
|
|
183
175
|
openTraceMacro,
|
|
176
|
+
traceMacroLoading,
|
|
184
177
|
selectedTraceTaskId,
|
|
185
178
|
setSelectedTraceTaskId,
|
|
186
179
|
setTrace,
|
|
@@ -191,7 +184,14 @@ export function useDashboardAppModel() {
|
|
|
191
184
|
traceLink,
|
|
192
185
|
traceLoadingTaskId,
|
|
193
186
|
traceTasks,
|
|
194
|
-
} = useAppTraceDocuments({
|
|
187
|
+
} = useAppTraceDocuments({
|
|
188
|
+
api,
|
|
189
|
+
operations,
|
|
190
|
+
isOperationsDetailLoaded: () => operationsDetailLoadedRef.current,
|
|
191
|
+
setError,
|
|
192
|
+
setFailedArea,
|
|
193
|
+
setLoadingArea,
|
|
194
|
+
});
|
|
195
195
|
const { loadMoreTraceTasks, traceTasksHasMore, traceTasksLoading } = useAppTraceTaskPagination(
|
|
196
196
|
api,
|
|
197
197
|
traceTasks,
|
|
@@ -205,7 +205,6 @@ export function useDashboardAppModel() {
|
|
|
205
205
|
const costSummaryRequestVersion = useRef(0);
|
|
206
206
|
const costSummaryAbortRef = useRef<AbortController | null>(null);
|
|
207
207
|
const costsLoadedRef = useRef(false);
|
|
208
|
-
const operationsDetailLoadedRef = useRef(false);
|
|
209
208
|
const operationsDetailCancelRef = useRef<(() => void) | null>(null);
|
|
210
209
|
const operationsDetailAbortRef = useRef<AbortController | null>(null);
|
|
211
210
|
const operationsPageAbortRef = useRef<AbortController | null>(null);
|
|
@@ -571,7 +570,7 @@ export function useDashboardAppModel() {
|
|
|
571
570
|
setLoadingArea((current) => (current === "costs" ? null : current));
|
|
572
571
|
if (costSummaryAbortRef.current === controller) costSummaryAbortRef.current = null;
|
|
573
572
|
}
|
|
574
|
-
}, [api, currency, operationsPeriod]);
|
|
573
|
+
}, [api, currency, operationsPeriod, currencyRef]);
|
|
575
574
|
|
|
576
575
|
// The global language selector can request USD while Operations is active.
|
|
577
576
|
// Acquire its coherent Cost Monitor snapshot here instead of requiring a
|
|
@@ -695,6 +694,7 @@ export function useDashboardAppModel() {
|
|
|
695
694
|
openTraceChange,
|
|
696
695
|
openTraceMacro,
|
|
697
696
|
selectedTraceTaskId,
|
|
697
|
+
traceMacroLoading,
|
|
698
698
|
trace,
|
|
699
699
|
traceLoadingTaskId,
|
|
700
700
|
traceTasksHasMore,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CostCurrency, CostLocale } from "@zaip-ai/dashboard-cost-monitor/react";
|
|
2
|
+
import { useCallback, useRef, useState } from "react";
|
|
3
|
+
import { currencyKey, savedLocale } from "./app-preferences.js";
|
|
4
|
+
export function useDashboardLocale() {
|
|
5
|
+
const [costLocale, setCostLocale] = useState<CostLocale>(savedLocale);
|
|
6
|
+
const [currency, setCurrency] = useState<CostCurrency>(() =>
|
|
7
|
+
window.localStorage.getItem(currencyKey) === "USD" ? "USD" : "BRL",
|
|
8
|
+
);
|
|
9
|
+
const currencyRef = useRef(currency);
|
|
10
|
+
currencyRef.current = currency;
|
|
11
|
+
// Language is the global selector's source of truth for the paired display
|
|
12
|
+
// currency, so Operations and Cost Monitor cannot diverge.
|
|
13
|
+
const changeDashboardLocale = useCallback((next: CostLocale) => {
|
|
14
|
+
setCostLocale(next);
|
|
15
|
+
setCurrency(next === "en-US" ? "USD" : "BRL");
|
|
16
|
+
}, []);
|
|
17
|
+
return { costLocale, currency, setCurrency, currencyRef, changeDashboardLocale };
|
|
18
|
+
}
|
|
@@ -69,7 +69,7 @@ export interface CostRunRow {
|
|
|
69
69
|
run_id: string;
|
|
70
70
|
/** Lifecycle Execution that owns this Run, retained for the Executions tab period filter. */
|
|
71
71
|
execution_id: string | null;
|
|
72
|
-
conversation_id: string;
|
|
72
|
+
conversation_id: string | null;
|
|
73
73
|
task_id: string | null;
|
|
74
74
|
task_title: string;
|
|
75
75
|
task_status: string;
|
|
@@ -81,7 +81,14 @@ export interface CostRunRow {
|
|
|
81
81
|
parent_run_id: string | null;
|
|
82
82
|
run_role: "intake" | "orchestrator" | "subagent";
|
|
83
83
|
run_kind: "run" | "subrun";
|
|
84
|
-
run_purpose:
|
|
84
|
+
run_purpose:
|
|
85
|
+
| "observation"
|
|
86
|
+
| "intake"
|
|
87
|
+
| "orchestration"
|
|
88
|
+
| "execution"
|
|
89
|
+
| "review"
|
|
90
|
+
| "audit"
|
|
91
|
+
| "finalization";
|
|
85
92
|
requires_finalizer: boolean;
|
|
86
93
|
client: string;
|
|
87
94
|
agent: string;
|
|
@@ -95,7 +102,7 @@ export interface CostRunRow {
|
|
|
95
102
|
call_count: number | null;
|
|
96
103
|
status: string;
|
|
97
104
|
phase: string;
|
|
98
|
-
origin: "conversation" | "task" | "spec" | "prd";
|
|
105
|
+
origin: "observation" | "conversation" | "task" | "spec" | "prd";
|
|
99
106
|
work_type: "new" | "rework";
|
|
100
107
|
started_at: string;
|
|
101
108
|
finished_at: string | null;
|
package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.run-page.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { loadCostMonitorRunPage } from "./CostFilters.js";
|
|
2
|
+
import { emptyCostFilters, loadCostMonitorRunPage } from "./CostFilters.js";
|
|
3
3
|
|
|
4
4
|
describe("Cost Monitor invocation page loading", () => {
|
|
5
5
|
it("uses a ten-row default for the remote invocation page", async () => {
|
|
@@ -7,6 +7,7 @@ describe("Cost Monitor invocation page loading", () => {
|
|
|
7
7
|
await loadCostMonitorRunPage({
|
|
8
8
|
currency: "BRL",
|
|
9
9
|
offset: 0,
|
|
10
|
+
filters: { ...emptyCostFilters, query: "target title" },
|
|
10
11
|
fetcher: async (url) => {
|
|
11
12
|
calls.push(String(url));
|
|
12
13
|
return new Response(JSON.stringify({ runs: [] }), { status: 200 });
|
|
@@ -14,5 +15,8 @@ describe("Cost Monitor invocation page loading", () => {
|
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
expect(new URL(calls[0]!, "http://dashboard.local").searchParams.get("limit")).toBe("10");
|
|
18
|
+
expect(new URL(calls[0]!, "http://dashboard.local").searchParams.get("query")).toBe(
|
|
19
|
+
"target title",
|
|
20
|
+
);
|
|
17
21
|
});
|
|
18
22
|
});
|
|
@@ -22,7 +22,7 @@ const unavailableGroup = {
|
|
|
22
22
|
} as const;
|
|
23
23
|
|
|
24
24
|
describe("period group values", () => {
|
|
25
|
-
it("
|
|
25
|
+
it("preserves unavailable tokens alongside disclosed presentation zeros and null sorting", () => {
|
|
26
26
|
const table = CostGroupsTable({
|
|
27
27
|
rows: [unavailableGroup],
|
|
28
28
|
currency: "BRL",
|
|
@@ -53,7 +53,7 @@ describe("period group values", () => {
|
|
|
53
53
|
);
|
|
54
54
|
expect([duration.props.children, tokens.props.children, cost.props.children]).toEqual([
|
|
55
55
|
"0",
|
|
56
|
-
"
|
|
56
|
+
"—",
|
|
57
57
|
formatAuditableCurrency(0, "BRL", "pt-BR"),
|
|
58
58
|
]);
|
|
59
59
|
expect(
|
|
@@ -179,7 +179,7 @@ describe("grouped cost availability", () => {
|
|
|
179
179
|
).toBe("0");
|
|
180
180
|
expect(
|
|
181
181
|
columns.find((column) => column.key === "cost")?.render?.({ ...model, estimated_brl: null }),
|
|
182
|
-
).toBe("
|
|
182
|
+
).toBe("—");
|
|
183
183
|
expect(
|
|
184
184
|
columns
|
|
185
185
|
.find((column) => column.key === "tokens")
|
|
@@ -324,14 +324,14 @@ describe("grouped cost availability", () => {
|
|
|
324
324
|
expect(column(key)?.description).toContain("projeção SQLite/API");
|
|
325
325
|
expect(column(key)?.hidden).not.toBe(true);
|
|
326
326
|
}
|
|
327
|
-
expect(column("duration")?.render?.(unavailableRun)).toBe("
|
|
328
|
-
expect(column("inputTokens")?.render?.(unavailableRun)).toBe("
|
|
327
|
+
expect(column("duration")?.render?.(unavailableRun)).toBe("—");
|
|
328
|
+
expect(column("inputTokens")?.render?.(unavailableRun)).toBe("—");
|
|
329
329
|
expect(column("inputRate")?.render?.(unavailableRun)).toBe("0,00");
|
|
330
330
|
expect(column("contextMultiplier")?.render?.(unavailableRun)).toBe("0");
|
|
331
331
|
expect(column("inputCost")?.render?.(unavailableRun)).toContain("0,00");
|
|
332
332
|
expect(column("fxRate")?.render?.(unavailableRun)).toBe("R$ 0,00");
|
|
333
|
-
expect(column("recordedBrl")?.render?.(unavailableRun)).toBe("
|
|
334
|
-
expect(column("cost")?.render?.(unavailableRun)).toBe("
|
|
333
|
+
expect(column("recordedBrl")?.render?.(unavailableRun)).toBe("—");
|
|
334
|
+
expect(column("cost")?.render?.(unavailableRun)).toBe("—");
|
|
335
335
|
});
|
|
336
336
|
it("provides a clear scroll label for the detailed Runs table", () => {
|
|
337
337
|
expect(costRunsScrollLabel("pt-BR")).toBe(
|