@zaip-ai/cli 3.4.0 → 3.6.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/adapters.d.ts +1 -1
- package/dist/services/adapters.js +1 -1
- package/dist/services/stack-install.d.ts.map +1 -1
- package/dist/services/stack-install.js +19 -9
- package/dist/services/stack-install.js.map +1 -1
- package/dist/services/stack-node.d.ts.map +1 -1
- package/dist/services/stack-node.js +1 -1
- package/dist/services/stack-node.js.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/config/agents/discovery.json +1 -1
- package/templates/.agents/dashboard/.zaip-managed.json +95 -51
- package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-BDQR0U4a.js +2938 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-DRI_XwUf.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-B9GWkEyN.css → ProjectSettingsPage-CQMhvzvJ.css} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-D46WWIKr.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-OulA4CoX.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CqK3Psfy.js → TraceabilityWorkspace-BKBpJyLh.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-Ckxk_izu.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-Cl5EWx8R.js → index-Bas2TVju.js} +2 -2
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CqfSgtk9.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CxrG_wRI.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-OBJXZOwe.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +2 -2
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/AppDashboardContent.tsx +0 -2
- package/templates/.agents/dashboard/apps/frontend/src/DashboardGlobalSettings.tsx +7 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsCard.tsx +18 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsField.tsx +21 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.dom.test.ts +12 -1
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +16 -28
- package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +25 -4
- package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.test.tsx +26 -8
- package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.tsx +9 -28
- package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.css +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-help-dialog.css +2 -2
- package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.ts +4 -1
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +20 -9
- package/templates/.agents/dashboard/apps/frontend/src/pricing-settings-dialog.css +5 -5
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-copy.ts +13 -4
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +25 -1
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-workspace.css +28 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +39 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.test.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/workspace-status.css +1 -14
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsEntityFilters.tsx +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.tsx +2 -2
- 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/dist/server.cjs +2 -2
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +73 -73
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +38 -6
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +2 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +3 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +2 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-pricing-provenance.test.ts +75 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +2 -2
- 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/specs/dashboard.spec.ts +4 -6
- package/templates/.agents/dashboard/tests/e2e/specs/work-board-hydration.ts +38 -0
- package/templates/.agents/design/.zaip-managed.json +83 -51
- package/templates/.agents/design/apps/catalog/dist/assets/index-Cv4VfxTQ.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-D1JaPXfV.css +1 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-D2miO4-O.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-mvD5mwcC.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/index.html +2 -2
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{CatalogShell-CvaciY0C.js → CatalogShell-BJ8b4xZr.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Color-6AOWCN3U-DwBV1A1Y.js → Color-6AOWCN3U-CQLHzznn.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-kxWwSKin.js +146 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DashboardFilters.stories-Chm_dXV7.js +9 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DashboardFiltersSpecimen-9CaCbGIZ.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DesignSystem.stories-2OCgtT0I.js → DesignSystem.stories-ED52wFjY.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DocsRenderer-JROSPFPF-CODg0rSl.js → DocsRenderer-JROSPFPF-BcLgM80v.js} +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Primitives-BmeKjJW4.js → Primitives-DV6Bpudf.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WithTooltip-7X4HQR7L-C5MI-3uZ.js → WithTooltip-7X4HQR7L-BKNiAz_E.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WorkspaceStatus.stories-Tb_iQqVK.js → WorkspaceStatus.stories-BL19HGOo.js} +2 -2
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatusSpecimen-DQnSS6s9.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-DRQKCCAG-KSn75jcy.js → chunk-DRQKCCAG-DZBcXL-p.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-W22LQPXL-C4LS1Thf.js → chunk-W22LQPXL-CF3y2mfo.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{components-DV1BRgMY.js → components-BVjxMRGq.js} +5 -5
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-Do9sjqiW.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{iframe-CBbPFx5G.js → iframe-CTWGZcEe.js} +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{react-18-C9IPGXtb.js → react-18-B9_a4mHb.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-NrUxok8K.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{syntaxhighlighter-YFXUGROL-ZgDQjyWI.js → syntaxhighlighter-YFXUGROL-F_p8E2xc.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{theming-Cx9-gH6l.js → theming-fbSD9ZLF.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/iframe.html +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/index.json +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/a11y-2/manager-bundle.js +3 -3
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/docs-1/manager-bundle.js +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +60 -60
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/apps/catalog/src/components/DashboardFiltersSpecimen.tsx +26 -21
- package/templates/.agents/design/apps/catalog/src/components/StackVersionFieldSpecimen.tsx +66 -0
- package/templates/.agents/design/apps/catalog/src/components/WorkspaceStatusSpecimen.tsx +23 -7
- package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +20 -6
- package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +14 -0
- package/templates/.agents/design/apps/catalog/src/stories/WorkspaceStatus.stories.tsx +5 -2
- package/templates/.agents/design/apps/catalog/src/styles/components.css +1 -1
- package/templates/.agents/design/apps/catalog/src/styles/stack-version-field.css +79 -0
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- 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 +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/rules/workflow.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +46 -15
- package/templates/.agents/runtime/checksums.sha256 +5 -5
- package/templates/.agents/runtime/manifest.json +1 -1
- package/templates/.agents/runtime/provenance.json +4 -4
- package/templates/.agents/runtime/sbom.cdx.json +1 -1
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +1 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +5 -4
- package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +7 -7
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.mjs +1 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.test.mjs +9 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +25 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.mjs +2 -6
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.test.mjs +15 -1
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/template-manifest.json +216 -140
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-DVCPPV75.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cwylbh_N.css +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-3dqK5g3e.js +0 -142
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatusSpecimen-CD54pw0-.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-BU_68im1.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-CEv2qkJT.js +0 -1
|
@@ -4,30 +4,48 @@ import { describe, expect, it } from "vitest";
|
|
|
4
4
|
import { WorkspaceStatus } from "./WorkspaceStatus.js";
|
|
5
5
|
|
|
6
6
|
describe("workspace diagnostics", () => {
|
|
7
|
+
it("does not render a global workspace banner when the runtime is healthy", () => {
|
|
8
|
+
const html = renderToStaticMarkup(
|
|
9
|
+
createElement(WorkspaceStatus, {
|
|
10
|
+
status: {
|
|
11
|
+
workspace: "C:/projects/zaip-growth",
|
|
12
|
+
workspace_name: "zaip-growth",
|
|
13
|
+
workspaceKey: "growth",
|
|
14
|
+
status: "ok",
|
|
15
|
+
lifecycle_manifest_state: "initialized",
|
|
16
|
+
},
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
expect(html).toBe("");
|
|
20
|
+
});
|
|
21
|
+
|
|
7
22
|
it.each([
|
|
8
|
-
"initialized",
|
|
9
23
|
"missing",
|
|
10
24
|
"invalid",
|
|
11
|
-
] as const)("
|
|
25
|
+
] as const)("keeps the %s lifecycle warning without exposing the served path", (state) => {
|
|
12
26
|
const html = renderToStaticMarkup(
|
|
13
27
|
createElement(WorkspaceStatus, {
|
|
14
28
|
status: {
|
|
15
29
|
workspace: "C:/projects/zaip-growth",
|
|
16
30
|
workspace_name: "zaip-growth",
|
|
17
31
|
workspaceKey: "growth",
|
|
18
|
-
status:
|
|
32
|
+
status: "degraded",
|
|
19
33
|
lifecycle_manifest_state: state,
|
|
20
34
|
},
|
|
21
35
|
}),
|
|
22
36
|
);
|
|
23
|
-
expect(html).toContain("C:/projects/zaip-growth");
|
|
37
|
+
expect(html).not.toContain("C:/projects/zaip-growth");
|
|
38
|
+
expect(html).not.toContain("zaip-growth");
|
|
24
39
|
if (state === "missing") expect(html).toContain("Lifecycle não inicializado");
|
|
25
40
|
if (state === "invalid") expect(html).toContain("Manifesto do lifecycle inválido");
|
|
26
|
-
|
|
41
|
+
expect(html).toContain("manifest rebuild --confirm-full-scan");
|
|
27
42
|
});
|
|
43
|
+
|
|
28
44
|
it("keeps unknown health explicit", () => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
)
|
|
45
|
+
const html = renderToStaticMarkup(
|
|
46
|
+
createElement(WorkspaceStatus, { status: null, unavailable: true }),
|
|
47
|
+
);
|
|
48
|
+
expect(html).toContain("Não foi possível consultar a saúde do Dashboard");
|
|
49
|
+
expect(html).not.toContain("Workspace indisponível");
|
|
32
50
|
});
|
|
33
51
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useLayoutEffect, useRef } from "react";
|
|
2
1
|
import type { DashboardRuntimeStatus } from "./dashboard-runtime-status.js";
|
|
3
2
|
import "./workspace-status.css";
|
|
4
3
|
|
|
@@ -10,32 +9,10 @@ export function WorkspaceStatus({
|
|
|
10
9
|
unavailable?: boolean;
|
|
11
10
|
}) {
|
|
12
11
|
const manifest = status?.lifecycle_manifest_state;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const element = banner.current;
|
|
16
|
-
if (!element) return;
|
|
17
|
-
const update = () =>
|
|
18
|
-
document.documentElement.style.setProperty(
|
|
19
|
-
"--dashboard-workspace-height",
|
|
20
|
-
`${element.getBoundingClientRect().height}px`,
|
|
21
|
-
);
|
|
22
|
-
update();
|
|
23
|
-
const observer = new ResizeObserver(update);
|
|
24
|
-
observer.observe(element);
|
|
25
|
-
return () => {
|
|
26
|
-
observer.disconnect();
|
|
27
|
-
document.documentElement.style.removeProperty("--dashboard-workspace-height");
|
|
28
|
-
};
|
|
29
|
-
}, []);
|
|
12
|
+
if (manifest === "initialized" && status?.status === "ok" && !unavailable) return null;
|
|
13
|
+
|
|
30
14
|
return (
|
|
31
|
-
<aside
|
|
32
|
-
<div className="workspace-status__identity">
|
|
33
|
-
<strong>{status?.workspace_name ?? "Dashboard"}</strong>
|
|
34
|
-
<span>
|
|
35
|
-
{status?.workspace ??
|
|
36
|
-
(unavailable ? "Workspace indisponível" : "Identificando workspace…")}
|
|
37
|
-
</span>
|
|
38
|
-
</div>
|
|
15
|
+
<aside className="workspace-status" aria-label="Saúde do Dashboard">
|
|
39
16
|
{manifest === "missing" || manifest === "invalid" ? (
|
|
40
17
|
<div className="workspace-status__warning" role="alert">
|
|
41
18
|
<strong>
|
|
@@ -43,7 +20,7 @@ export function WorkspaceStatus({
|
|
|
43
20
|
? "Lifecycle não inicializado"
|
|
44
21
|
: "Manifesto do lifecycle inválido"}
|
|
45
22
|
</strong>
|
|
46
|
-
<p>Os dados deste workspace estão indisponíveis. Na pasta
|
|
23
|
+
<p>Os dados deste workspace estão indisponíveis. Na pasta do projeto, execute:</p>
|
|
47
24
|
<code>node .agents/runtime/bin/zaip.mjs manifest rebuild --confirm-full-scan</code>
|
|
48
25
|
</div>
|
|
49
26
|
) : status?.status === "degraded" || unavailable ? (
|
|
@@ -52,7 +29,11 @@ export function WorkspaceStatus({
|
|
|
52
29
|
? "Não foi possível consultar a saúde do Dashboard. Tentando novamente…"
|
|
53
30
|
: "Dashboard degradado: a atualização dos dados ou da telemetria requer atenção."}
|
|
54
31
|
</p>
|
|
55
|
-
) :
|
|
32
|
+
) : (
|
|
33
|
+
<p className="workspace-status__warning" role="status">
|
|
34
|
+
Identificando a saúde do Dashboard…
|
|
35
|
+
</p>
|
|
36
|
+
)}
|
|
56
37
|
</aside>
|
|
57
38
|
);
|
|
58
39
|
}
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
border-radius: 11px;
|
|
101
101
|
background: rgba(5, 12, 23, 0.58);
|
|
102
102
|
}
|
|
103
|
-
.dashboard-help-document-header button {
|
|
103
|
+
.dashboard-help .dashboard-help-document-header button {
|
|
104
104
|
min-height: 32px;
|
|
105
105
|
border: 1px solid transparent;
|
|
106
106
|
border-radius: 8px;
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
color: #7f91aa;
|
|
110
110
|
font-size: 0.7rem;
|
|
111
111
|
}
|
|
112
|
-
.dashboard-help-document-header button.is-active {
|
|
112
|
+
.dashboard-help .dashboard-help-document-header button.is-active {
|
|
113
113
|
border-color: rgba(56, 189, 248, 0.24);
|
|
114
114
|
background: rgba(14, 165, 233, 0.11);
|
|
115
115
|
color: #bae6fd;
|
|
@@ -142,7 +142,10 @@ export function projectEntityPage(
|
|
|
142
142
|
executions:
|
|
143
143
|
kind === "executions" || kind === "conversations"
|
|
144
144
|
? (page.rows.map((row, index) => {
|
|
145
|
-
const run = runs[index]
|
|
145
|
+
const run = runs[index];
|
|
146
|
+
if (run === undefined) {
|
|
147
|
+
throw new Error("Operations entity page must have a projected run for every row.");
|
|
148
|
+
}
|
|
146
149
|
const id = run.execution_id ?? run.conversation_id;
|
|
147
150
|
const status = row.status ?? "unavailable";
|
|
148
151
|
return {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contracts";
|
|
1
2
|
import { describe, expect, it } from "vitest";
|
|
2
3
|
import {
|
|
3
4
|
isCurrentOperationsPageRequest,
|
|
@@ -5,6 +6,7 @@ import {
|
|
|
5
6
|
isCurrentPeriodTransition,
|
|
6
7
|
mergeBoardPages,
|
|
7
8
|
} from "./App.js";
|
|
9
|
+
import type { OperationsBoardPage } from "./dashboard-api.js";
|
|
8
10
|
import { requestPeriodForOperations } from "./operations-period.js";
|
|
9
11
|
|
|
10
12
|
describe("Operations period request contract", () => {
|
|
@@ -90,14 +92,18 @@ describe("Operations period request contract", () => {
|
|
|
90
92
|
const pending = [a, b, c].map(() => Promise.withResolvers<void>());
|
|
91
93
|
const applied: string[] = [];
|
|
92
94
|
const reply = async (version: number, period: typeof a, label: string, slot: number) => {
|
|
93
|
-
|
|
95
|
+
const deferred = pending[slot];
|
|
96
|
+
if (deferred === undefined) throw new Error(`Missing deferred reply for slot ${slot}.`);
|
|
97
|
+
await deferred.promise;
|
|
94
98
|
if (isCurrentOperationsPeriodRequest(version, 3, period, c)) applied.push(label);
|
|
95
99
|
};
|
|
96
100
|
const requests = [reply(1, a, "A", 0), reply(2, b, "B", 1), reply(3, c, "C", 2)];
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
for (const slot of [2, 1, 0]) {
|
|
103
|
+
const deferred = pending[slot];
|
|
104
|
+
if (deferred === undefined) throw new Error(`Missing deferred reply for slot ${slot}.`);
|
|
105
|
+
deferred.resolve();
|
|
106
|
+
}
|
|
101
107
|
await Promise.all(requests);
|
|
102
108
|
|
|
103
109
|
expect(applied).toEqual(["C"]);
|
|
@@ -114,7 +120,9 @@ describe("Operations period request contract", () => {
|
|
|
114
120
|
controller: AbortController,
|
|
115
121
|
slot: number,
|
|
116
122
|
) => {
|
|
117
|
-
|
|
123
|
+
const deferred = pending[slot];
|
|
124
|
+
if (deferred === undefined) throw new Error(`Missing deferred reply for slot ${slot}.`);
|
|
125
|
+
await deferred.promise;
|
|
118
126
|
if (isCurrentOperationsPageRequest(version, 2, controller.signal)) applied.push(label);
|
|
119
127
|
};
|
|
120
128
|
const requests = [
|
|
@@ -123,8 +131,11 @@ describe("Operations period request contract", () => {
|
|
|
123
131
|
];
|
|
124
132
|
|
|
125
133
|
oldRequest.abort();
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
for (const slot of [1, 0]) {
|
|
135
|
+
const deferred = pending[slot];
|
|
136
|
+
if (deferred === undefined) throw new Error(`Missing deferred reply for slot ${slot}.`);
|
|
137
|
+
deferred.resolve();
|
|
138
|
+
}
|
|
128
139
|
await Promise.all(requests);
|
|
129
140
|
|
|
130
141
|
expect(applied).toEqual(["new-filter-page"]);
|
|
@@ -137,14 +148,14 @@ describe("Operations period request contract", () => {
|
|
|
137
148
|
tasks: [],
|
|
138
149
|
changes: [],
|
|
139
150
|
summary: { overview_metrics: { partial: false, total_tasks: 5 } },
|
|
140
|
-
} as
|
|
151
|
+
} as unknown as OperationsProjection;
|
|
141
152
|
const board = {
|
|
142
153
|
prds: [],
|
|
143
154
|
specs: [],
|
|
144
155
|
tasks: [{ id: "TASK-1" }],
|
|
145
156
|
changes: [],
|
|
146
157
|
overview_metrics: { partial: false, total_tasks: 999 },
|
|
147
|
-
} as
|
|
158
|
+
} as unknown as OperationsBoardPage;
|
|
148
159
|
expect(mergeBoardPages(quick, [board]).summary.overview_metrics).toEqual(
|
|
149
160
|
quick.summary.overview_metrics,
|
|
150
161
|
);
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
.pricing-dialog > header > div {
|
|
31
31
|
max-width: 820px;
|
|
32
32
|
}
|
|
33
|
+
.pricing-dialog small {
|
|
34
|
+
color: #8391a7;
|
|
35
|
+
}
|
|
33
36
|
.pricing-dialog > header small {
|
|
34
37
|
color: #77bff2;
|
|
35
38
|
font-size: 11px;
|
|
@@ -46,9 +49,6 @@
|
|
|
46
49
|
color: #94a3b8;
|
|
47
50
|
line-height: 1.55;
|
|
48
51
|
}
|
|
49
|
-
.pricing-dialog small {
|
|
50
|
-
color: #8391a7;
|
|
51
|
-
}
|
|
52
52
|
.pricing-dialog button {
|
|
53
53
|
border: 1px solid #34445e;
|
|
54
54
|
border-radius: 11px;
|
|
@@ -103,8 +103,8 @@
|
|
|
103
103
|
color: #edf5ff;
|
|
104
104
|
font-size: 15px;
|
|
105
105
|
}
|
|
106
|
-
.pricing-fx-copy p,
|
|
107
|
-
.pricing-table-heading p {
|
|
106
|
+
.pricing-dialog .pricing-fx-copy p,
|
|
107
|
+
.pricing-dialog .pricing-table-heading p {
|
|
108
108
|
margin: 7px 0 0;
|
|
109
109
|
color: #8e9bb1;
|
|
110
110
|
font-size: 13px;
|
|
@@ -15,6 +15,10 @@ export const projectSettingsCopy = {
|
|
|
15
15
|
framework: "Framework ZAIP-AIOS",
|
|
16
16
|
frameworkHint: "Ativa ou desativa o framework para este projeto.",
|
|
17
17
|
identity: "Identidade do projeto",
|
|
18
|
+
workspacePath: "Caminho do projeto",
|
|
19
|
+
workspacePathHint: "Pasta local usada por esta instância do Dashboard.",
|
|
20
|
+
workspacePathLoading: "Identificando caminho…",
|
|
21
|
+
workspacePathUnavailable: "Caminho indisponível",
|
|
18
22
|
stack: "Stack e linguagens",
|
|
19
23
|
execution: "Execução",
|
|
20
24
|
assurance: "Assurance",
|
|
@@ -57,8 +61,9 @@ export const projectSettingsCopy = {
|
|
|
57
61
|
available: "Criado",
|
|
58
62
|
artifactUnavailable: "Ainda não criado",
|
|
59
63
|
componentGuide:
|
|
60
|
-
"Preencha cada responsabilidade separadamente.
|
|
61
|
-
versionHint:
|
|
64
|
+
"Preencha cada responsabilidade separadamente. Use a versão exata do software e, para serviços em nuvem ou hospedagem, informe Serviço em nuvem.",
|
|
65
|
+
versionHint:
|
|
66
|
+
"Software: 22.16.0 ou 17.6, sem prefixos (^, ~, >=). Serviço gerenciado: Serviço em nuvem. Hospedagem: Serviço em nuvem.",
|
|
62
67
|
referenceHint:
|
|
63
68
|
"Ex.: npm:hono, docker:node:22.16.0-bookworm-slim, service:supabase ou provider:cloudflare-pages.",
|
|
64
69
|
overrides: "Opções avançadas (JSON)",
|
|
@@ -103,6 +108,10 @@ export const projectSettingsCopy = {
|
|
|
103
108
|
framework: "ZAIP-AIOS framework",
|
|
104
109
|
frameworkHint: "Enable or disable the framework for this project.",
|
|
105
110
|
identity: "Project identity",
|
|
111
|
+
workspacePath: "Project path",
|
|
112
|
+
workspacePathHint: "Local folder used by this Dashboard instance.",
|
|
113
|
+
workspacePathLoading: "Identifying path…",
|
|
114
|
+
workspacePathUnavailable: "Path unavailable",
|
|
106
115
|
stack: "Stack and languages",
|
|
107
116
|
execution: "Execution",
|
|
108
117
|
assurance: "Assurance",
|
|
@@ -145,9 +154,9 @@ export const projectSettingsCopy = {
|
|
|
145
154
|
available: "Created",
|
|
146
155
|
artifactUnavailable: "Not created yet",
|
|
147
156
|
componentGuide:
|
|
148
|
-
"Fill each responsibility separately.
|
|
157
|
+
"Fill each responsibility separately. Use an exact software version and, for cloud services or hosting, enter Cloud service.",
|
|
149
158
|
versionHint:
|
|
150
|
-
"
|
|
159
|
+
"Software: 22.16.0 or 17.6, without prefixes (^, ~, >=). Managed service: Cloud service. Hosting: Cloud service.",
|
|
151
160
|
referenceHint:
|
|
152
161
|
"E.g. npm:hono, docker:node:22.16.0-bookworm-slim, service:supabase, or provider:cloudflare-pages.",
|
|
153
162
|
overrides: "Advanced options (JSON)",
|
|
@@ -34,6 +34,18 @@ export type StackComponentId = (typeof stackComponentDefinitions)[number]["id"];
|
|
|
34
34
|
export type StackComponentDraft = { name: string; version: string; reference: string };
|
|
35
35
|
export type StackComponentsDraft = Record<StackComponentId, StackComponentDraft>;
|
|
36
36
|
|
|
37
|
+
const descriptiveVersionComponentIds = new Set<StackComponentId>([
|
|
38
|
+
"database",
|
|
39
|
+
"auth_storage",
|
|
40
|
+
"backend_hosting",
|
|
41
|
+
"frontend_hosting",
|
|
42
|
+
"site_hosting",
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
export function acceptsDescriptiveVersion(id: StackComponentId): boolean {
|
|
46
|
+
return descriptiveVersionComponentIds.has(id);
|
|
47
|
+
}
|
|
48
|
+
|
|
37
49
|
export function projectSettingsDraft(config: ProjectConfigSettings): {
|
|
38
50
|
components: StackComponentsDraft;
|
|
39
51
|
otherOverrides: string;
|
|
@@ -110,11 +122,23 @@ export function buildProjectSettingsPayload(
|
|
|
110
122
|
} = parsed;
|
|
111
123
|
for (const definition of stackComponentDefinitions) {
|
|
112
124
|
const version = components[definition.id].version.trim();
|
|
113
|
-
if (
|
|
125
|
+
if (
|
|
126
|
+
version !== "" &&
|
|
127
|
+
!acceptsDescriptiveVersion(definition.id) &&
|
|
128
|
+
!/^\d+\.\d+(?:\.\d+)?(?:[-+][0-9A-Za-z.-]+)?$/.test(version)
|
|
129
|
+
) {
|
|
114
130
|
throw new Error(
|
|
115
131
|
`A versão de ${components[definition.id].name || definition.defaultName} deve ser exata, como 22.16.0 ou 17.6, sem ^, ~, >= ou latest.`,
|
|
116
132
|
);
|
|
117
133
|
}
|
|
134
|
+
if (
|
|
135
|
+
acceptsDescriptiveVersion(definition.id) &&
|
|
136
|
+
(version.length > 120 || /[\r\n]/.test(version))
|
|
137
|
+
) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`A referência de ${components[definition.id].name || definition.defaultName} deve ter uma única linha com até 120 caracteres.`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
118
142
|
}
|
|
119
143
|
const normalized = Object.fromEntries(
|
|
120
144
|
stackComponentDefinitions.map((definition) => [
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.project-settings-workspace-path {
|
|
2
|
+
display: block;
|
|
3
|
+
min-width: 0;
|
|
4
|
+
padding: 10px 12px;
|
|
5
|
+
border: 1px solid #cbd7e5;
|
|
6
|
+
border-radius: 12px;
|
|
7
|
+
background: #f8fafc;
|
|
8
|
+
overflow-wrap: anywhere;
|
|
9
|
+
color: #0f172a;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.project-settings-workspace-field {
|
|
13
|
+
grid-column: 1 / -1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.project-stack-row input.is-reference-value {
|
|
17
|
+
border-color: #9edcf2;
|
|
18
|
+
background-color: #effaff;
|
|
19
|
+
color: #075985;
|
|
20
|
+
font-weight: 650;
|
|
21
|
+
-webkit-text-fill-color: #075985;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.project-stack-row input.is-reference-value:hover,
|
|
25
|
+
.project-stack-row input.is-reference-value:focus-visible {
|
|
26
|
+
border-color: #00b0f0;
|
|
27
|
+
background-color: #f5fcff;
|
|
28
|
+
}
|
|
@@ -111,6 +111,45 @@ describe("project settings form mapping", () => {
|
|
|
111
111
|
).toThrow("deve ser exata");
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
+
it("accepts descriptive references only for managed services and hosting", () => {
|
|
115
|
+
const components = projectSettingsDraft(config).components;
|
|
116
|
+
const payload = buildProjectSettingsPayload(
|
|
117
|
+
config,
|
|
118
|
+
{
|
|
119
|
+
...components,
|
|
120
|
+
database: { ...components.database, version: "Serviço em nuvem" },
|
|
121
|
+
auth_storage: { ...components.auth_storage, version: "Serviço em nuvem" },
|
|
122
|
+
backend_hosting: {
|
|
123
|
+
...components.backend_hosting,
|
|
124
|
+
version: "Serviço em nuvem",
|
|
125
|
+
},
|
|
126
|
+
frontend_hosting: { ...components.frontend_hosting, version: "Serviço em nuvem" },
|
|
127
|
+
site_hosting: { ...components.site_hosting, version: "Serviço em nuvem" },
|
|
128
|
+
},
|
|
129
|
+
"{}",
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
expect(payload.stack.overrides.components).toMatchObject({
|
|
133
|
+
database: { version: "Serviço em nuvem" },
|
|
134
|
+
auth_storage: { version: "Serviço em nuvem" },
|
|
135
|
+
backend_hosting: {
|
|
136
|
+
version: "Serviço em nuvem",
|
|
137
|
+
},
|
|
138
|
+
frontend_hosting: { version: "Serviço em nuvem" },
|
|
139
|
+
site_hosting: { version: "Serviço em nuvem" },
|
|
140
|
+
});
|
|
141
|
+
expect(() =>
|
|
142
|
+
buildProjectSettingsPayload(
|
|
143
|
+
config,
|
|
144
|
+
{
|
|
145
|
+
...components,
|
|
146
|
+
backend_api: { ...components.backend_api, version: "Serviço em nuvem" },
|
|
147
|
+
},
|
|
148
|
+
"{}",
|
|
149
|
+
),
|
|
150
|
+
).toThrow("deve ser exata");
|
|
151
|
+
});
|
|
152
|
+
|
|
114
153
|
it("keeps observability and on-demand testing tools editable with pinned-or-empty versions", () => {
|
|
115
154
|
const configured = {
|
|
116
155
|
...config,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
1
|
import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contracts";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import type { DashboardApiClient, OperationsPageFilters, WorkBoardStage } from "./dashboard-api.js";
|
|
4
4
|
import type { OperationsPeriodState } from "./operations-period.js";
|
|
5
5
|
import { useAppWorkBoard } from "./use-app-work-board.js";
|
|
@@ -8,21 +8,8 @@
|
|
|
8
8
|
border-bottom: 1px solid var(--border, rgba(255, 255, 255, 0.12));
|
|
9
9
|
font-size: 12px;
|
|
10
10
|
}
|
|
11
|
-
.dashboard-header {
|
|
12
|
-
top: var(--dashboard-workspace-height, 0px);
|
|
13
|
-
}
|
|
14
|
-
.workspace-status__identity {
|
|
15
|
-
display: flex;
|
|
16
|
-
flex-wrap: wrap;
|
|
17
|
-
gap: 4px 16px;
|
|
18
|
-
align-items: baseline;
|
|
19
|
-
}
|
|
20
|
-
.workspace-status__identity span {
|
|
21
|
-
overflow-wrap: anywhere;
|
|
22
|
-
min-width: 0;
|
|
23
|
-
}
|
|
24
11
|
.workspace-status__warning {
|
|
25
|
-
margin:
|
|
12
|
+
margin: 0;
|
|
26
13
|
color: var(--error-text, #fecaca);
|
|
27
14
|
}
|
|
28
15
|
.workspace-status__warning p {
|
package/templates/.agents/dashboard/modules/operations/src/react/OperationsEntityFilters.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { OperationsLocale } from "./status-labels.js";
|
|
2
2
|
import { riskLabel } from "./status-labels.js";
|
|
3
|
-
import { taskOriginLabel, taskOriginOptions
|
|
3
|
+
import { type TaskOrigin, taskOriginLabel, taskOriginOptions } from "./task-origin.js";
|
|
4
4
|
import { workStageLabel, workStages } from "./work-board-model.js";
|
|
5
5
|
|
|
6
6
|
/** Work filters belong to the visible shared header, not the retired hero. */
|
|
@@ -4,10 +4,10 @@ import { formatRoundedDuration } from "./format-rounded-duration.js";
|
|
|
4
4
|
import type { OperationsLocale } from "./status-labels.js";
|
|
5
5
|
import { WorkTypeFilters } from "./UnifiedWorkBoard.js";
|
|
6
6
|
import {
|
|
7
|
-
workStageLabel,
|
|
8
|
-
workStages,
|
|
9
7
|
type WorkStage,
|
|
10
8
|
type WorkTypeFilter,
|
|
9
|
+
workStageLabel,
|
|
10
|
+
workStages,
|
|
11
11
|
} from "./work-board-model.js";
|
|
12
12
|
|
|
13
13
|
export type PagedWorkListRow = Record<string, unknown>;
|