@zaip-ai/cli 7.5.0 → 7.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.
Files changed (118) hide show
  1. package/README.md +12 -20
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +2 -2
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/services/adapters.d.ts +1 -1
  6. package/dist/services/adapters.js +1 -1
  7. package/dist/services/codex-task-delivery-authority-template.d.ts.map +1 -1
  8. package/dist/services/codex-task-delivery-authority-template.js +39 -1
  9. package/dist/services/codex-task-delivery-authority-template.js.map +1 -1
  10. package/dist/services/global-codex-project-trust.d.ts +1 -1
  11. package/dist/services/global-codex-project-trust.d.ts.map +1 -1
  12. package/dist/services/global-codex-project-trust.js +46 -11
  13. package/dist/services/global-codex-project-trust.js.map +1 -1
  14. package/dist/services/global-codex-project-trust.test.js +35 -4
  15. package/dist/services/global-codex-project-trust.test.js.map +1 -1
  16. package/dist/services/install-agents-template.js +2 -2
  17. package/dist/services/install-agents-template.js.map +1 -1
  18. package/dist/services/install-target-windows.test.d.ts +2 -0
  19. package/dist/services/install-target-windows.test.d.ts.map +1 -0
  20. package/dist/services/install-target-windows.test.js +39 -0
  21. package/dist/services/install-target-windows.test.js.map +1 -0
  22. package/dist/services/install-target.d.ts +6 -0
  23. package/dist/services/install-target.d.ts.map +1 -0
  24. package/dist/services/install-target.js +89 -0
  25. package/dist/services/install-target.js.map +1 -0
  26. package/dist/services/install-target.test.d.ts +2 -0
  27. package/dist/services/install-target.test.d.ts.map +1 -0
  28. package/dist/services/install-target.test.js +47 -0
  29. package/dist/services/install-target.test.js.map +1 -0
  30. package/dist/services/logger.js +5 -3
  31. package/dist/services/logger.js.map +1 -1
  32. package/package.json +1 -1
  33. package/templates/.agents/config/agents/discovery.json +1 -1
  34. package/templates/.agents/dashboard/.zaip-managed.json +72 -32
  35. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-BCsdQtWG.js → ProjectSettingsPage-86kLUrXm.js} +1 -1
  36. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-BN8FwP5S.js → TraceabilityWorkspace-BZ1rH1vl.js} +1 -1
  37. package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-uIVtG2ZR.js → index-C4uiRYHu.js} +2 -2
  38. package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-DFY7ZDlu.css → traceability-s5SzQnzt.css} +1 -1
  39. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-vQx9R6BQ.js +1 -0
  40. package/templates/.agents/dashboard/apps/frontend/dist/index.html +3 -3
  41. package/templates/.agents/dashboard/apps/frontend/e2e/release-delivery-fixture.mjs +117 -0
  42. package/templates/.agents/dashboard/apps/frontend/e2e/release-delivery-lab.mjs +246 -0
  43. package/templates/.agents/dashboard/apps/frontend/e2e/release-delivery-receipt.mjs +65 -0
  44. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  45. package/templates/.agents/dashboard/apps/frontend/src/dashboard-runtime-status.ts +5 -1
  46. package/templates/.agents/dashboard/apps/frontend/src/release-delivery.test.tsx +78 -0
  47. package/templates/.agents/dashboard/apps/frontend/src/use-runtime-status.dom.test.ts +28 -6
  48. package/templates/.agents/dashboard/apps/frontend/src/use-runtime-status.ts +18 -7
  49. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  50. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  51. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  52. package/templates/.agents/dashboard/modules/traceability/src/contracts.ts +11 -0
  53. package/templates/.agents/dashboard/modules/traceability/src/react/ReleaseDeliveryPanel.tsx +60 -0
  54. package/templates/.agents/dashboard/modules/traceability/src/react/TaskTracePanel.tsx +9 -57
  55. package/templates/.agents/dashboard/modules/traceability/src/react/release-delivery-panel.css +26 -0
  56. package/templates/.agents/dashboard/modules/traceability/src/react/trace-date-format.ts +33 -0
  57. package/templates/.agents/dashboard/modules/traceability/src/react/trace-stage-labels.ts +28 -0
  58. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  59. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  60. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  61. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +236 -235
  62. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +81 -81
  63. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  64. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +236 -235
  65. package/templates/.agents/dashboard/packages/local-runtime/src/server-release-receipt.ts +71 -0
  66. package/templates/.agents/dashboard/packages/local-runtime/src/server-trace-release-delivery.ts +120 -0
  67. package/templates/.agents/dashboard/packages/local-runtime/src/server-trace-routes.ts +5 -4
  68. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  69. package/templates/.agents/dashboard/stack-dependencies.json +3 -3
  70. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  71. package/templates/.agents/design/.zaip-managed.json +4 -4
  72. package/templates/.agents/design/apps/catalog/package.json +1 -1
  73. package/templates/.agents/design/design-system-maker/build.json +94 -79
  74. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  75. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  76. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  77. package/templates/.agents/requirements/comparative-audit.md +1 -1
  78. package/templates/.agents/requirements/context-engine.md +1 -1
  79. package/templates/.agents/requirements/cost-observability.md +1 -1
  80. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  81. package/templates/.agents/requirements/data-export.md +1 -1
  82. package/templates/.agents/requirements/design-system.md +1 -1
  83. package/templates/.agents/requirements/execution-engine.md +1 -1
  84. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  85. package/templates/.agents/requirements/landing-page-forms.md +1 -1
  86. package/templates/.agents/requirements/model-orchestration.md +1 -1
  87. package/templates/.agents/requirements/public-distribution.md +1 -1
  88. package/templates/.agents/requirements/site-performance.md +1 -1
  89. package/templates/.agents/requirements/software-architecture.md +1 -1
  90. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  91. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  92. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  93. package/templates/.agents/runtime/VERSION +1 -1
  94. package/templates/.agents/runtime/bin/historical-catalog-b6b6516200bdb412c92063e887ccef329d7c5193b5610cba5346e97c71301394.mjs +318 -0
  95. package/templates/.agents/runtime/bin/zaip.mjs +149 -109
  96. package/templates/.agents/runtime/checksums.sha256 +6 -5
  97. package/templates/.agents/runtime/manifest.json +2 -1
  98. package/templates/.agents/runtime/provenance.json +4 -4
  99. package/templates/.agents/runtime/sbom.cdx.json +1 -1
  100. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.mjs +49 -70
  101. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-idempotent-intent.test.mjs +39 -0
  102. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deployment-next-release.mjs +57 -0
  103. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deployment-request.mjs +15 -0
  104. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-intent.mjs +4 -1
  105. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/{chunk-A3ZCURGS.mjs → chunk-CJ5ZQF6M.mjs} +6 -6
  106. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/{chunk-ZOGCYGYB.mjs → chunk-EQTZ3Y7R.mjs} +1 -1
  107. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/chunk-FMNUSV2P.mjs +139 -0
  108. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/{chunk-7SBOEN6U.mjs → chunk-LWS3QVJO.mjs} +2 -2
  109. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/lifecycle-records.mjs +1 -1
  110. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/manifest.json +14 -13
  111. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/native-authority.mjs +1 -1
  112. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/proof.mjs +1 -1
  113. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/run-records.mjs +1 -1
  114. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-schema.mjs +1 -1
  115. package/templates/.agents/zaip-aios/VERSION +1 -1
  116. package/templates/template-manifest.json +141 -92
  117. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-Boz50W9b.js +0 -1
  118. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/publication-proof-runtime/chunks/chunk-NJOFXS7P.mjs +0 -137
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { expect, it } from "vitest";
4
4
 
5
- it("checks health once, ignores pending capture, and reports real loading errors until reload", async () => {
5
+ it("recovers transient health failures and preserves terminal identity errors", async () => {
6
6
  const require = createRequire(
7
7
  fileURLToPath(new URL("../../../tests/e2e/package.json", import.meta.url)),
8
8
  );
@@ -43,11 +43,20 @@ it("checks health once, ignores pending capture, and reports real loading errors
43
43
  "**/api/v2/health",
44
44
  async (route: { abort: () => Promise<void>; fulfill: (value: object) => Promise<void> }) => {
45
45
  requests++;
46
- if (mode === "network") return route.abort();
46
+ if (mode === "timeout" && requests === 1) return;
47
+ if (mode === "network" || (mode === "network-once" && requests === 1)) return route.abort();
48
+ const status =
49
+ mode === "http" || (mode === "http-once" && requests === 1)
50
+ ? 503
51
+ : mode === "unauthorized"
52
+ ? 401
53
+ : mode === "forbidden"
54
+ ? 403
55
+ : 200;
47
56
  await route.fulfill({
48
- status: mode === "http" ? 503 : 200,
57
+ status,
49
58
  json: {
50
- kind: "zaip-dashboard-sqlite-runtime",
59
+ kind: mode === "wrong-runtime" ? "other-runtime" : "zaip-dashboard-sqlite-runtime",
51
60
  workspace: "fixture",
52
61
  workspace_name: "ready",
53
62
  workspaceKey: "fixture",
@@ -69,17 +78,30 @@ it("checks health once, ignores pending capture, and reports real loading errors
69
78
  await page.reload();
70
79
  await page.getByText("ready", { exact: true }).waitFor();
71
80
  expect(await page.getByRole("alert").count()).toBe(0);
72
- for (const failure of ["http", "network"]) {
81
+ for (const failure of ["timeout", "http-once", "network-once"]) {
73
82
  mode = failure;
83
+ requests = 0;
84
+ await page.reload();
85
+ await expect.poll(() => requests).toBe(1);
86
+ if (failure === "timeout") await page.clock.fastForward(4001);
87
+ await page.getByText("ready", { exact: true }).waitFor();
88
+ expect(requests).toBe(2);
89
+ expect(await page.getByRole("alert").count()).toBe(0);
90
+ }
91
+ for (const failure of ["http", "network", "unauthorized", "forbidden", "wrong-runtime"]) {
92
+ mode = failure;
93
+ requests = 0;
74
94
  await page.reload();
75
95
  await page.getByRole("alert").waitFor();
76
96
  expect(await page.getByRole("alert").innerText()).toContain("abra novamente o executável");
97
+ await page.clock.fastForward(30_000);
98
+ expect(requests).toBe(["http", "network"].includes(failure) ? 3 : 1);
77
99
  }
78
100
  mode = "healthy";
79
101
  await page.getByRole("button", { name: "Atualizar página" }).click();
80
102
  await page.getByText("ready", { exact: true }).waitFor();
81
103
  expect(await page.getByRole("alert").count()).toBe(0);
82
- expect(requests).toBe(5);
104
+ expect(requests).toBe(2);
83
105
  } finally {
84
106
  await browser.close();
85
107
  }
@@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
2
2
  import {
3
3
  type DashboardRuntimeStatus,
4
4
  readDashboardRuntimeStatus,
5
+ TransientHealthError,
5
6
  } from "./dashboard-runtime-status.js";
6
7
 
7
8
  export function useRuntimeStatus() {
@@ -10,26 +11,36 @@ export function useRuntimeStatus() {
10
11
  useEffect(() => {
11
12
  let disposed = false;
12
13
  let controller: AbortController;
13
- // Identity is checked on page load. New telemetry is not a connection failure;
14
- // users can reload the page or reopen the launcher for a fresh snapshot.
15
- async function load() {
14
+ const deadlines = [4000, 8000, 16000];
15
+ let retry: ReturnType<typeof setTimeout>;
16
+ async function load(attempt: number) {
16
17
  controller = new AbortController();
17
- const timeout = setTimeout(() => controller.abort(), 4000);
18
+ const timeout = setTimeout(() => controller.abort(), deadlines[attempt]);
18
19
  try {
19
20
  const next = await readDashboardRuntimeStatus(controller.signal);
20
21
  if (!disposed) {
21
22
  setStatus(next);
22
23
  setUnavailable(false);
23
24
  }
24
- } catch {
25
- if (!disposed) setUnavailable(true);
25
+ } catch (error) {
26
+ if (disposed) return;
27
+ const transient =
28
+ controller.signal.aborted ||
29
+ error instanceof TypeError ||
30
+ error instanceof TransientHealthError;
31
+ if (transient && attempt + 1 < deadlines.length) {
32
+ retry = setTimeout(() => void load(attempt + 1), 250 * (attempt + 1));
33
+ } else {
34
+ setUnavailable(true);
35
+ }
26
36
  } finally {
27
37
  clearTimeout(timeout);
28
38
  }
29
39
  }
30
- void load();
40
+ void load(0);
31
41
  return () => {
32
42
  disposed = true;
43
+ clearTimeout(retry);
33
44
  controller?.abort();
34
45
  };
35
46
  }, []);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-cost-monitor",
3
- "version": "7.5.0",
3
+ "version": "7.6.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-operations",
3
- "version": "7.5.0",
3
+ "version": "7.6.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-traceability",
3
- "version": "7.5.0",
3
+ "version": "7.6.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -45,7 +45,18 @@ export interface TraceObservedMetric {
45
45
  coverage_ratio: number;
46
46
  }
47
47
 
48
+ export interface ReleaseDeliveryProjection {
49
+ publication: "verified" | "unverified";
50
+ receipt_path: string | null;
51
+ task_status: string;
52
+ change_status: string | null;
53
+ execution_status: string | null;
54
+ blocker: string | null;
55
+ next_action: string | null;
56
+ }
57
+
48
58
  export interface TaskTrace {
59
+ release_delivery?: ReleaseDeliveryProjection;
49
60
  schema_version: 2;
50
61
  layout_version: 2 | 3;
51
62
  readonly: true;
@@ -0,0 +1,60 @@
1
+ import type { ReleaseDeliveryProjection } from "../contracts.js";
2
+ import "./release-delivery-panel.css";
3
+
4
+ export function ReleaseDeliveryPanel({
5
+ delivery,
6
+ locale,
7
+ }: {
8
+ delivery: ReleaseDeliveryProjection;
9
+ locale: "pt-BR" | "en-US";
10
+ }) {
11
+ const pt = locale === "pt-BR";
12
+ const statuses = [
13
+ ["Task", delivery.task_status],
14
+ ["Change", delivery.change_status],
15
+ ["Execution", delivery.execution_status],
16
+ ] as const;
17
+ const closed = statuses.every(([, status]) => status === "completed");
18
+ const published = delivery.publication === "verified";
19
+ return (
20
+ <section
21
+ className="trace-release-delivery"
22
+ aria-label={pt ? "Entrega da versão" : "Release delivery"}
23
+ >
24
+ <h3>{pt ? "Entrega da versão" : "Release delivery"}</h3>
25
+ <dl>
26
+ <div>
27
+ <dt>{pt ? "Publicação" : "Publication"}</dt>
28
+ <dd>
29
+ {published ? (pt ? "Confirmada" : "Verified") : pt ? "Sem confirmação" : "Unverified"}
30
+ </dd>
31
+ </div>
32
+ <div>
33
+ <dt>{pt ? "Fechamento no ZAIP" : "ZAIP closure"}</dt>
34
+ <dd>{closed ? (pt ? "Concluído" : "Completed") : pt ? "Pendente" : "Pending"}</dd>
35
+ </div>
36
+ {statuses.map(([label, status]) => (
37
+ <div key={label}>
38
+ <dt>{label}</dt>
39
+ <dd>{status ?? (pt ? "Sem registro" : "Unrecorded")}</dd>
40
+ </div>
41
+ ))}
42
+ </dl>
43
+ {delivery.blocker && (
44
+ <p>
45
+ <strong>{pt ? "Bloqueio" : "Blocker"}</strong> · {delivery.blocker}
46
+ </p>
47
+ )}
48
+ {delivery.next_action && (
49
+ <p>
50
+ <strong>{pt ? "Próxima ação" : "Next action"}</strong> · {delivery.next_action}
51
+ </p>
52
+ )}
53
+ {delivery.receipt_path && (
54
+ <p>
55
+ <strong>{pt ? "Comprovante" : "Receipt"}</strong> · <code>{delivery.receipt_path}</code>
56
+ </p>
57
+ )}
58
+ </section>
59
+ );
60
+ }
@@ -24,24 +24,22 @@ import {
24
24
  } from "lucide-react";
25
25
  import { useMemo, useState } from "react";
26
26
  import type { TaskTrace, TraceDocument, TraceStage } from "../contracts.js";
27
+ import { formatTraceCreatedAt, formatTraceElapsed } from "./trace-date-format.js";
27
28
  import "./traceability-navigation.css";
28
29
  import "./traceability-embedded.css";
29
30
  import "./traceability-usage.css";
30
31
  import "./traceability.css";
31
32
  import "./traceability-stage-detail.css";
32
33
  import "./traceability-stage-dialog.css";
34
+ import { ReleaseDeliveryPanel } from "./ReleaseDeliveryPanel.js";
33
35
  import { TraceDocumentDialog } from "./TraceDocumentDialog.js";
34
36
  import { TraceStageDetail } from "./TraceStageDetail.js";
35
37
  import { TraceStageDialog } from "./TraceStageDialog.js";
36
38
 
37
- export const traceStages: readonly TraceStage[] = [
38
- "definition",
39
- "planning",
40
- "execution",
41
- "decisions",
42
- "verification",
43
- "evidence",
44
- ];
39
+ import { traceStageArtifactsEn, traceStageArtifactsPt, traceStages } from "./trace-stage-labels.js";
40
+
41
+ export { traceStageArtifactsEn, traceStageArtifactsPt, traceStages } from "./trace-stage-labels.js";
42
+
45
43
  const loadingIdentifierKeys = ["task", "change", "spec", "prd"] as const;
46
44
  const loadingMetricKeys = ["coverage", "documents", "evidence", "links"] as const;
47
45
  const riskLabels = {
@@ -56,22 +54,6 @@ const stageIcons: Record<TraceStage, LucideIcon> = {
56
54
  verification: ShieldCheck,
57
55
  evidence: FileCheck2,
58
56
  };
59
- export const traceStageArtifactsPt: Record<TraceStage, string> = {
60
- definition: "PRD · Requisitos",
61
- planning: "SPEC · Change",
62
- execution: "Tarefas · DAG · Runs · arquivos",
63
- decisions: "Decisões do planejamento e da execução",
64
- verification: "Testes · revisões · evals · checks",
65
- evidence: "Evidências · resultados · rastreabilidade",
66
- };
67
- export const traceStageArtifactsEn: Record<TraceStage, string> = {
68
- definition: "PRD · Requirements",
69
- planning: "SPEC · Change",
70
- execution: "Tasks · DAG · Runs · files",
71
- decisions: "Planning and execution decisions",
72
- verification: "Tests · reviews · evals · checks",
73
- evidence: "Evidence · results · traceability",
74
- };
75
57
  export const traceStageArtifacts = traceStageArtifactsPt;
76
58
  export type TraceLocale = "pt-BR" | "en-US";
77
59
 
@@ -404,6 +386,9 @@ export function TaskTracePanel({
404
386
  </div>
405
387
  </article>
406
388
  </section>
389
+ {trace.release_delivery && (
390
+ <ReleaseDeliveryPanel delivery={trace.release_delivery} locale={locale} />
391
+ )}
407
392
  <section
408
393
  className="trace-overview trace-lineage"
409
394
  aria-label={locale === "pt-BR" ? "Identificadores vinculados" : "Linked identifiers"}
@@ -646,36 +631,3 @@ function TraceUsageStrip({
646
631
  function formatTraceDuration(durationMs: number | null, locale: TraceLocale): string {
647
632
  return durationMs === null ? "—" : formatDurationMs(durationMs, locale);
648
633
  }
649
-
650
- function formatTraceCreatedAt(value: string | null, locale: TraceLocale): string {
651
- if (value === null) return "—";
652
- const date = new Date(value);
653
- if (Number.isNaN(date.getTime())) return "—";
654
- return new Intl.DateTimeFormat(locale, {
655
- dateStyle: "short",
656
- timeStyle: "short",
657
- }).format(date);
658
- }
659
-
660
- function formatTraceElapsed(value: string | null, locale: TraceLocale): string {
661
- if (value === null) return "—";
662
- const createdAt = Date.parse(value);
663
- if (!Number.isFinite(createdAt)) return "—";
664
- const elapsedMs = Math.max(0, Date.now() - createdAt);
665
- const minutes = Math.max(1, Math.round(elapsedMs / 60_000));
666
- let unit: string;
667
- if (minutes < 60) unit = `${minutes}m`;
668
- else {
669
- const hours = Math.round(minutes / 60);
670
- if (hours < 24) unit = `${hours}h`;
671
- else {
672
- const days = Math.round(hours / 24);
673
- if (days < 7) unit = `${days}d`;
674
- else {
675
- const weeks = Math.round(days / 7);
676
- unit = locale === "pt-BR" ? `${weeks}sem` : `${weeks}w`;
677
- }
678
- }
679
- }
680
- return locale === "pt-BR" ? `Há ${unit}` : `${unit} ago`;
681
- }
@@ -0,0 +1,26 @@
1
+ .trace-release-delivery {
2
+ margin-block: 1.25rem;
3
+ padding: 1rem;
4
+ border: 1px solid var(--line);
5
+ border-radius: 12px;
6
+ overflow-wrap: anywhere;
7
+ }
8
+
9
+ .trace-release-delivery h3,
10
+ .trace-release-delivery dd {
11
+ margin: 0;
12
+ }
13
+
14
+ .trace-release-delivery dl {
15
+ display: grid;
16
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
17
+ gap: 0.75rem;
18
+ }
19
+
20
+ .trace-release-delivery dt {
21
+ color: var(--muted);
22
+ }
23
+
24
+ .trace-release-delivery p {
25
+ margin: 0.5rem 0 0;
26
+ }
@@ -0,0 +1,33 @@
1
+ import type { TraceLocale } from "./TaskTracePanel.js";
2
+ export function formatTraceCreatedAt(value: string | null, locale: TraceLocale): string {
3
+ if (value === null) return "—";
4
+ const date = new Date(value);
5
+ if (Number.isNaN(date.getTime())) return "—";
6
+ return new Intl.DateTimeFormat(locale, {
7
+ dateStyle: "short",
8
+ timeStyle: "short",
9
+ }).format(date);
10
+ }
11
+
12
+ export function formatTraceElapsed(value: string | null, locale: TraceLocale): string {
13
+ if (value === null) return "—";
14
+ const createdAt = Date.parse(value);
15
+ if (!Number.isFinite(createdAt)) return "—";
16
+ const elapsedMs = Math.max(0, Date.now() - createdAt);
17
+ const minutes = Math.max(1, Math.round(elapsedMs / 60_000));
18
+ let unit: string;
19
+ if (minutes < 60) unit = `${minutes}m`;
20
+ else {
21
+ const hours = Math.round(minutes / 60);
22
+ if (hours < 24) unit = `${hours}h`;
23
+ else {
24
+ const days = Math.round(hours / 24);
25
+ if (days < 7) unit = `${days}d`;
26
+ else {
27
+ const weeks = Math.round(days / 7);
28
+ unit = locale === "pt-BR" ? `${weeks}sem` : `${weeks}w`;
29
+ }
30
+ }
31
+ }
32
+ return locale === "pt-BR" ? `Há ${unit}` : `${unit} ago`;
33
+ }
@@ -0,0 +1,28 @@
1
+ import type { TraceStage } from "../contracts.js";
2
+
3
+ export const traceStages: readonly TraceStage[] = [
4
+ "definition",
5
+ "planning",
6
+ "execution",
7
+ "decisions",
8
+ "verification",
9
+ "evidence",
10
+ ];
11
+
12
+ export const traceStageArtifactsPt: Record<TraceStage, string> = {
13
+ definition: "PRD · Requisitos",
14
+ planning: "SPEC · Change",
15
+ execution: "Tarefas · DAG · Runs · arquivos",
16
+ decisions: "Decisões do planejamento e da execução",
17
+ verification: "Testes · revisões · evals · checks",
18
+ evidence: "Evidências · resultados · rastreabilidade",
19
+ };
20
+
21
+ export const traceStageArtifactsEn: Record<TraceStage, string> = {
22
+ definition: "PRD · Requirements",
23
+ planning: "SPEC · Change",
24
+ execution: "Tasks · DAG · Runs · files",
25
+ decisions: "Planning and execution decisions",
26
+ verification: "Tests · reviews · evals · checks",
27
+ evidence: "Evidence · results · traceability",
28
+ };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-branding",
3
- "version": "7.5.0",
3
+ "version": "7.6.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-contracts",
3
- "version": "7.5.0",
3
+ "version": "7.6.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/dashboard-data-export",
3
- "version": "7.5.0",
3
+ "version": "7.6.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {