@flanksource/clicky-ui 0.3.30 → 0.3.31

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 (130) hide show
  1. package/dist/comments/CommentCard.cjs +110 -262
  2. package/dist/comments/CommentCard.cjs.map +1 -1
  3. package/dist/comments/CommentCard.d.ts +3 -1
  4. package/dist/comments/CommentCard.d.ts.map +1 -1
  5. package/dist/comments/CommentCard.js +105 -257
  6. package/dist/comments/CommentCard.js.map +1 -1
  7. package/dist/comments/CommentCardParts.cjs +95 -0
  8. package/dist/comments/CommentCardParts.cjs.map +1 -0
  9. package/dist/comments/CommentCardParts.d.ts +17 -0
  10. package/dist/comments/CommentCardParts.d.ts.map +1 -0
  11. package/dist/comments/CommentCardParts.js +95 -0
  12. package/dist/comments/CommentCardParts.js.map +1 -0
  13. package/dist/comments/CommentSidePanel.cjs +14 -7
  14. package/dist/comments/CommentSidePanel.cjs.map +1 -1
  15. package/dist/comments/CommentSidePanel.d.ts +3 -1
  16. package/dist/comments/CommentSidePanel.d.ts.map +1 -1
  17. package/dist/comments/CommentSidePanel.js +14 -7
  18. package/dist/comments/CommentSidePanel.js.map +1 -1
  19. package/dist/comments/CommentThread.cjs +2 -0
  20. package/dist/comments/CommentThread.cjs.map +1 -1
  21. package/dist/comments/CommentThread.d.ts +2 -1
  22. package/dist/comments/CommentThread.d.ts.map +1 -1
  23. package/dist/comments/CommentThread.js +2 -0
  24. package/dist/comments/CommentThread.js.map +1 -1
  25. package/dist/comments/CommentThreadList.cjs +50 -34
  26. package/dist/comments/CommentThreadList.cjs.map +1 -1
  27. package/dist/comments/CommentThreadList.d.ts +3 -1
  28. package/dist/comments/CommentThreadList.d.ts.map +1 -1
  29. package/dist/comments/CommentThreadList.js +50 -34
  30. package/dist/comments/CommentThreadList.js.map +1 -1
  31. package/dist/components/ComboboxMenu.cjs +4 -1
  32. package/dist/components/ComboboxMenu.cjs.map +1 -1
  33. package/dist/components/ComboboxMenu.d.ts.map +1 -1
  34. package/dist/components/ComboboxMenu.js +5 -2
  35. package/dist/components/ComboboxMenu.js.map +1 -1
  36. package/dist/components/ComboboxTags.cjs +5 -1
  37. package/dist/components/ComboboxTags.cjs.map +1 -1
  38. package/dist/components/ComboboxTags.d.ts.map +1 -1
  39. package/dist/components/ComboboxTags.js +6 -2
  40. package/dist/components/ComboboxTags.js.map +1 -1
  41. package/dist/components/ConnectionLoggingPolicy.cjs +24 -35
  42. package/dist/components/ConnectionLoggingPolicy.cjs.map +1 -1
  43. package/dist/components/ConnectionLoggingPolicy.d.ts.map +1 -1
  44. package/dist/components/ConnectionLoggingPolicy.js +24 -35
  45. package/dist/components/ConnectionLoggingPolicy.js.map +1 -1
  46. package/dist/components/MultiSelect.cjs.map +1 -1
  47. package/dist/components/MultiSelect.d.ts +7 -0
  48. package/dist/components/MultiSelect.d.ts.map +1 -1
  49. package/dist/components/MultiSelect.js.map +1 -1
  50. package/dist/components/filter-bar-multi.cjs +10 -1
  51. package/dist/components/filter-bar-multi.cjs.map +1 -1
  52. package/dist/components/filter-bar-multi.d.ts.map +1 -1
  53. package/dist/components/filter-bar-multi.js +11 -2
  54. package/dist/components/filter-bar-multi.js.map +1 -1
  55. package/dist/data/ai/SessionViewer.model.cjs +23 -8
  56. package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
  57. package/dist/data/ai/SessionViewer.model.d.ts +8 -0
  58. package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
  59. package/dist/data/ai/SessionViewer.model.js +23 -8
  60. package/dist/data/ai/SessionViewer.model.js.map +1 -1
  61. package/dist/data/ai/SessionViewer.rows.cjs +9 -1
  62. package/dist/data/ai/SessionViewer.rows.cjs.map +1 -1
  63. package/dist/data/ai/SessionViewer.rows.js +9 -1
  64. package/dist/data/ai/SessionViewer.rows.js.map +1 -1
  65. package/dist/data/ai/SpecRuntimeEditor/VerifySection.cjs +24 -2
  66. package/dist/data/ai/SpecRuntimeEditor/VerifySection.cjs.map +1 -1
  67. package/dist/data/ai/SpecRuntimeEditor/VerifySection.d.ts.map +1 -1
  68. package/dist/data/ai/SpecRuntimeEditor/VerifySection.js +25 -3
  69. package/dist/data/ai/SpecRuntimeEditor/VerifySection.js.map +1 -1
  70. package/dist/data/ai/SpecRuntimeEditor/summaries.cjs.map +1 -1
  71. package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts.map +1 -1
  72. package/dist/data/ai/SpecRuntimeEditor/summaries.js.map +1 -1
  73. package/dist/data/ai/SpecRuntimeEditor.model.cjs +4 -0
  74. package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
  75. package/dist/data/ai/SpecRuntimeEditor.model.d.ts +4 -0
  76. package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
  77. package/dist/data/ai/SpecRuntimeEditor.model.js +4 -0
  78. package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
  79. package/dist/data/test-runner/TestRunner.cjs +6 -4
  80. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  81. package/dist/data/test-runner/TestRunner.d.ts +10 -1
  82. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  83. package/dist/data/test-runner/TestRunner.js +6 -4
  84. package/dist/data/test-runner/TestRunner.js.map +1 -1
  85. package/dist/data/verification/VerificationResults.cjs +99 -0
  86. package/dist/data/verification/VerificationResults.cjs.map +1 -0
  87. package/dist/data/verification/VerificationResults.d.ts +27 -0
  88. package/dist/data/verification/VerificationResults.d.ts.map +1 -0
  89. package/dist/data/verification/VerificationResults.js +99 -0
  90. package/dist/data/verification/VerificationResults.js.map +1 -0
  91. package/dist/data/verification/adapterViews.cjs +116 -0
  92. package/dist/data/verification/adapterViews.cjs.map +1 -0
  93. package/dist/data/verification/adapterViews.d.ts +13 -0
  94. package/dist/data/verification/adapterViews.d.ts.map +1 -0
  95. package/dist/data/verification/adapterViews.js +116 -0
  96. package/dist/data/verification/adapterViews.js.map +1 -0
  97. package/dist/data/verification/adapters.cjs +26 -0
  98. package/dist/data/verification/adapters.cjs.map +1 -0
  99. package/dist/data/verification/adapters.d.ts +6 -0
  100. package/dist/data/verification/adapters.d.ts.map +1 -0
  101. package/dist/data/verification/adapters.js +26 -0
  102. package/dist/data/verification/adapters.js.map +1 -0
  103. package/dist/data/verification/index.d.ts +5 -0
  104. package/dist/data/verification/index.d.ts.map +1 -0
  105. package/dist/data/verification/verify-report.cjs +58 -0
  106. package/dist/data/verification/verify-report.cjs.map +1 -0
  107. package/dist/data/verification/verify-report.d.ts +96 -0
  108. package/dist/data/verification/verify-report.d.ts.map +1 -0
  109. package/dist/data/verification/verify-report.js +58 -0
  110. package/dist/data/verification/verify-report.js.map +1 -0
  111. package/dist/data/verification/verifyReportTests.cjs +83 -0
  112. package/dist/data/verification/verifyReportTests.cjs.map +1 -0
  113. package/dist/data/verification/verifyReportTests.d.ts +13 -0
  114. package/dist/data/verification/verifyReportTests.d.ts.map +1 -0
  115. package/dist/data/verification/verifyReportTests.js +83 -0
  116. package/dist/data/verification/verifyReportTests.js.map +1 -0
  117. package/dist/data/version-info.cjs +3 -3
  118. package/dist/data/version-info.js +3 -3
  119. package/dist/data.cjs +10 -0
  120. package/dist/data.cjs.map +1 -1
  121. package/dist/data.d.ts +1 -0
  122. package/dist/data.d.ts.map +1 -1
  123. package/dist/data.js +10 -0
  124. package/dist/data.js.map +1 -1
  125. package/dist/index.cjs +10 -0
  126. package/dist/index.cjs.map +1 -1
  127. package/dist/index.js +10 -0
  128. package/dist/index.js.map +1 -1
  129. package/dist/styles.css +1 -1
  130. package/package.json +1 -1
@@ -0,0 +1,116 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/utils.js";
3
+ import { Icon } from "../Icon.js";
4
+ import { JsonView } from "../JsonView.js";
5
+ import { TestOutput } from "../test-runner/TestFailureDetail.js";
6
+ import { UiPause } from "../../icons/components/UiPause.js";
7
+ import { UiError } from "../../icons/components/UiError.js";
8
+ import { UiPass } from "../../icons/components/UiPass.js";
9
+ function checklistItemState(item) {
10
+ if (item.failed) return "failed";
11
+ if (item.passed) return "passed";
12
+ return "pending";
13
+ }
14
+ const CHECKLIST_ICONS = {
15
+ passed: { icon: UiPass, tone: "text-emerald-600" },
16
+ failed: { icon: UiError, tone: "text-red-600" },
17
+ pending: { icon: UiPause, tone: "text-muted-foreground" }
18
+ };
19
+ function ChecklistItemRow({ item }) {
20
+ const { icon, tone } = CHECKLIST_ICONS[checklistItemState(item)];
21
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-1.5 text-xs", children: [
22
+ /* @__PURE__ */ jsx(Icon, { icon, className: cn("mt-0.5 shrink-0 text-sm", tone) }),
23
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
24
+ item.name,
25
+ item.message ? /* @__PURE__ */ jsx("span", { className: "block text-[11px] text-muted-foreground", children: item.message }) : null
26
+ ] })
27
+ ] });
28
+ }
29
+ function ChecklistDetail({ node }) {
30
+ const items = node.children && node.children.length > 0 ? node.children : [node];
31
+ return /* @__PURE__ */ jsx("div", { className: "space-y-2 p-density-4", children: /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: items.map((item, index) => /* @__PURE__ */ jsx(ChecklistItemRow, { item }, item.task_id ?? index)) }) });
32
+ }
33
+ function readCelTrace(detail) {
34
+ if (detail && typeof detail === "object" && !Array.isArray(detail)) {
35
+ const value = detail.cel_trace;
36
+ if (typeof value === "string" && value.length > 0) return value;
37
+ }
38
+ return void 0;
39
+ }
40
+ function comparisonValue(hasCelGate, value) {
41
+ if (value === void 0) return void 0;
42
+ if (hasCelGate) return value;
43
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) return void 0;
44
+ return value;
45
+ }
46
+ function formatCelValue(value) {
47
+ if (typeof value === "string") return value;
48
+ try {
49
+ return JSON.stringify(value);
50
+ } catch {
51
+ return String(value);
52
+ }
53
+ }
54
+ function CelDetails({ node }) {
55
+ if (node.passed) return null;
56
+ const context = node.context;
57
+ const vars = Object.entries((context == null ? void 0 : context.cel_vars) ?? {});
58
+ const expression = readCelTrace(node.detail) || (context == null ? void 0 : context.cel_expression);
59
+ const hasCelGate = !!expression;
60
+ const expected = comparisonValue(hasCelGate, context == null ? void 0 : context.expected);
61
+ const actual = comparisonValue(hasCelGate, context == null ? void 0 : context.actual);
62
+ const hasComparison = expected !== void 0 || actual !== void 0;
63
+ if (!expression && vars.length === 0 && !hasComparison) return null;
64
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1 rounded border border-border bg-muted/30 px-2 py-1.5", children: [
65
+ expression && /* @__PURE__ */ jsxs("div", { children: [
66
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] uppercase text-muted-foreground", children: "expression" }),
67
+ /* @__PURE__ */ jsx("code", { className: "block overflow-x-auto whitespace-pre text-[11px]", children: expression })
68
+ ] }),
69
+ vars.length > 0 && /* @__PURE__ */ jsx("table", { className: "w-full table-fixed text-[11px]", children: /* @__PURE__ */ jsx("tbody", { children: vars.map(([name, value]) => /* @__PURE__ */ jsxs("tr", { className: "align-top", children: [
70
+ /* @__PURE__ */ jsx("td", { className: "w-1/3 truncate pr-2 font-medium text-muted-foreground", children: name }),
71
+ /* @__PURE__ */ jsx("td", { className: "break-words font-mono", children: formatCelValue(value) })
72
+ ] }, name)) }) }),
73
+ expected !== void 0 && /* @__PURE__ */ jsxs("div", { className: "text-[11px]", children: [
74
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "expected " }),
75
+ /* @__PURE__ */ jsx("span", { className: "font-mono", children: formatCelValue(expected) })
76
+ ] }),
77
+ actual !== void 0 && /* @__PURE__ */ jsxs("div", { className: "text-[11px]", children: [
78
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "actual " }),
79
+ /* @__PURE__ */ jsx("span", { className: "font-mono", children: formatCelValue(actual) })
80
+ ] })
81
+ ] });
82
+ }
83
+ function FixtureDetail({ node }) {
84
+ const context = node.context;
85
+ const command = (context == null ? void 0 : context.command) ?? node.command;
86
+ const cwd = (context == null ? void 0 : context.cwd) ?? node.work_dir;
87
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4 p-density-4", children: [
88
+ node.message && /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap break-words text-sm", children: node.message }),
89
+ command && /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
90
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Command" }),
91
+ /* @__PURE__ */ jsx("code", { className: "block overflow-x-auto whitespace-pre rounded bg-muted px-2 py-1.5 text-xs", children: command }),
92
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 text-[10px] text-muted-foreground", children: [
93
+ cwd && /* @__PURE__ */ jsxs("span", { children: [
94
+ "in ",
95
+ cwd
96
+ ] }),
97
+ typeof (context == null ? void 0 : context.exit_code) === "number" && /* @__PURE__ */ jsxs("span", { className: context.exit_code === 0 ? void 0 : "text-red-600", children: [
98
+ "exit ",
99
+ context.exit_code
100
+ ] })
101
+ ] })
102
+ ] }),
103
+ /* @__PURE__ */ jsx(TestOutput, { node }),
104
+ /* @__PURE__ */ jsx(CelDetails, { node }),
105
+ node.detail != null && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
106
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Detail" }),
107
+ /* @__PURE__ */ jsx(JsonView, { data: node.detail })
108
+ ] })
109
+ ] });
110
+ }
111
+ export {
112
+ CelDetails,
113
+ ChecklistDetail,
114
+ FixtureDetail
115
+ };
116
+ //# sourceMappingURL=adapterViews.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapterViews.js","sources":["../../../src/data/verification/adapterViews.tsx"],"sourcesContent":["// Detail-body components for the verification node adapters. Split from\n// adapters.ts (react/only-export-components: a file mixing component\n// declarations with the plain TestNodeAdapter/registry exports loses Fast\n// Refresh). Ported from gavel's VerificationStepOutput.tsx (the checklist list\n// and the CelDetails block).\n\nimport { cn } from \"../../lib/utils\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport { UiError, UiPass, UiPause } from \"../../icons\";\nimport { JsonView } from \"../JsonView\";\nimport { TestOutput, type Test, type FixtureContext } from \"../test-runner\";\n\n// ── Checklist: the synthesized \"Acceptance criteria\" node and its items ────\n\ntype ChecklistState = \"passed\" | \"failed\" | \"pending\";\n\nfunction checklistItemState(item: Test): ChecklistState {\n if (item.failed) return \"failed\";\n if (item.passed) return \"passed\";\n return \"pending\";\n}\n\nconst CHECKLIST_ICONS: Record<ChecklistState, { icon: StaticIconComponent; tone: string }> = {\n passed: { icon: UiPass, tone: \"text-emerald-600\" },\n failed: { icon: UiError, tone: \"text-red-600\" },\n pending: { icon: UiPause, tone: \"text-muted-foreground\" },\n};\n\nfunction ChecklistItemRow({ item }: { item: Test }) {\n const { icon, tone } = CHECKLIST_ICONS[checklistItemState(item)];\n return (\n <li className=\"flex items-start gap-1.5 text-xs\">\n <Icon icon={icon} className={cn(\"mt-0.5 shrink-0 text-sm\", tone)} />\n <span className=\"min-w-0\">\n {item.name}\n {item.message ? (\n <span className=\"block text-[11px] text-muted-foreground\">{item.message}</span>\n ) : null}\n </span>\n </li>\n );\n}\n\n/** Renders every checklist item for the \"Acceptance criteria\" parent, or the\n * single item itself when a leaf criterion is selected directly. */\nexport function ChecklistDetail({ node }: { node: Test }) {\n const items = node.children && node.children.length > 0 ? node.children : [node];\n return (\n <div className=\"space-y-2 p-density-4\">\n <ul className=\"space-y-1\">\n {items.map((item, index) => (\n <ChecklistItemRow key={item.task_id ?? index} item={item} />\n ))}\n </ul>\n </div>\n );\n}\n\n// ── Fixture / CEL: the failing-step detail (command + CelDetails) ──────────\n\nfunction readCelTrace(detail: unknown): string | undefined {\n if (detail && typeof detail === \"object\" && !Array.isArray(detail)) {\n const value = (detail as Record<string, unknown>).cel_trace;\n if (typeof value === \"string\" && value.length > 0) return value;\n }\n return undefined;\n}\n\n// A command step with no CEL assertion stores the whole command result object\n// in `actual` — the command/output is already rendered above, so dumping it\n// again as JSON is noise. Anything a CEL expression compared is shown as-is,\n// structured values included. `hasCelGate` mirrors gavel's own gate: a plain\n// `context.cel_expression`, or a trace recorded in `node.detail` when the\n// expression itself wasn't preserved on `context`.\nfunction comparisonValue(hasCelGate: boolean, value: unknown): unknown {\n if (value === undefined) return undefined;\n if (hasCelGate) return value;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) return undefined;\n return value;\n}\n\nfunction formatCelValue(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n// CEL detail is rendered only for a failing node: the expression and the\n// values it saw are what explain the verdict.\nexport function CelDetails({ node }: { node: Test }) {\n if (node.passed) return null;\n const context = node.context as FixtureContext | undefined;\n const vars = Object.entries(context?.cel_vars ?? {});\n const expression = readCelTrace(node.detail) || context?.cel_expression;\n const hasCelGate = !!expression;\n const expected = comparisonValue(hasCelGate, context?.expected);\n const actual = comparisonValue(hasCelGate, context?.actual);\n const hasComparison = expected !== undefined || actual !== undefined;\n if (!expression && vars.length === 0 && !hasComparison) return null;\n return (\n <div className=\"space-y-1 rounded border border-border bg-muted/30 px-2 py-1.5\">\n {expression && (\n <div>\n <span className=\"text-[10px] uppercase text-muted-foreground\">expression</span>\n <code className=\"block overflow-x-auto whitespace-pre text-[11px]\">{expression}</code>\n </div>\n )}\n {vars.length > 0 && (\n <table className=\"w-full table-fixed text-[11px]\">\n <tbody>\n {vars.map(([name, value]) => (\n <tr key={name} className=\"align-top\">\n <td className=\"w-1/3 truncate pr-2 font-medium text-muted-foreground\">{name}</td>\n <td className=\"break-words font-mono\">{formatCelValue(value)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n {expected !== undefined && (\n <div className=\"text-[11px]\">\n <span className=\"text-muted-foreground\">expected </span>\n <span className=\"font-mono\">{formatCelValue(expected)}</span>\n </div>\n )}\n {actual !== undefined && (\n <div className=\"text-[11px]\">\n <span className=\"text-muted-foreground\">actual </span>\n <span className=\"font-mono\">{formatCelValue(actual)}</span>\n </div>\n )}\n </div>\n );\n}\n\nexport function FixtureDetail({ node }: { node: Test }) {\n const context = node.context as FixtureContext | undefined;\n const command = context?.command ?? node.command;\n const cwd = context?.cwd ?? node.work_dir;\n return (\n <div className=\"space-y-4 p-density-4\">\n {node.message && (\n <p className=\"whitespace-pre-wrap break-words text-sm\">{node.message}</p>\n )}\n {command && (\n <div className=\"min-w-0 space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">Command</div>\n <code className=\"block overflow-x-auto whitespace-pre rounded bg-muted px-2 py-1.5 text-xs\">\n {command}\n </code>\n <div className=\"flex flex-wrap items-center gap-2 text-[10px] text-muted-foreground\">\n {cwd && <span>in {cwd}</span>}\n {typeof context?.exit_code === \"number\" && (\n <span className={context.exit_code === 0 ? undefined : \"text-red-600\"}>\n exit {context.exit_code}\n </span>\n )}\n </div>\n </div>\n )}\n <TestOutput node={node} />\n <CelDetails node={node} />\n {node.detail != null && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">Detail</div>\n <JsonView data={node.detail} />\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const adapterViews = require("./adapterViews.cjs");
5
+ const adapter = require("../test-runner/adapter.cjs");
6
+ function isChecklistNode(node) {
7
+ return node.framework === "checklist";
8
+ }
9
+ const checklistAdapter = {
10
+ id: "verification-checklist",
11
+ match: isChecklistNode,
12
+ renderDetail: ({ node }) => /* @__PURE__ */ jsxRuntime.jsx(adapterViews.ChecklistDetail, { node })
13
+ };
14
+ function isFixtureNode(node) {
15
+ return node.context !== void 0;
16
+ }
17
+ const fixtureAdapter = {
18
+ id: "verification-fixture",
19
+ match: isFixtureNode,
20
+ renderDetail: ({ node }) => /* @__PURE__ */ jsxRuntime.jsx(adapterViews.FixtureDetail, { node })
21
+ };
22
+ function verificationAdapters() {
23
+ return adapter.createTestRunnerRegistry([checklistAdapter, fixtureAdapter]);
24
+ }
25
+ exports.verificationAdapters = verificationAdapters;
26
+ //# sourceMappingURL=adapters.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.cjs","sources":["../../../src/data/verification/adapters.tsx"],"sourcesContent":["// Domain node adapters for VerificationResults: a checklist adapter for the\n// synthesized \"Acceptance criteria\" node and its items, and a fixture/CEL\n// adapter for the failing-step detail. Rendering lives in adapterViews.tsx —\n// split out so this file's only exports are the registry (react/only-export-\n// components forbids mixing component declarations with plain exports).\n\nimport { ChecklistDetail, FixtureDetail } from \"./adapterViews\";\nimport {\n createTestRunnerRegistry,\n type Test,\n type TestNodeAdapter,\n type TestNodeAdapterRegistry,\n} from \"../test-runner\";\n\nfunction isChecklistNode(node: Test): boolean {\n return node.framework === \"checklist\";\n}\n\nconst checklistAdapter: TestNodeAdapter = {\n id: \"verification-checklist\",\n match: isChecklistNode,\n renderDetail: ({ node }) => <ChecklistDetail node={node} />,\n};\n\nfunction isFixtureNode(node: Test): boolean {\n return node.context !== undefined;\n}\n\nconst fixtureAdapter: TestNodeAdapter = {\n id: \"verification-fixture\",\n match: isFixtureNode,\n renderDetail: ({ node }) => <FixtureDetail node={node} />,\n};\n\n/** Default node adapters for VerificationResults: checklist items and\n * fixture/CEL steps. Registration order matters only when a node could match\n * both — a checklist node never carries a `context`, so the two never race. */\nexport function verificationAdapters(): TestNodeAdapterRegistry {\n return createTestRunnerRegistry([checklistAdapter, fixtureAdapter]);\n}\n"],"names":["jsx","ChecklistDetail","FixtureDetail","createTestRunnerRegistry"],"mappings":";;;;;AAcA,SAAS,gBAAgB,MAAqB;AAC5C,SAAO,KAAK,cAAc;AAC5B;AAEA,MAAM,mBAAoC;AAAA,EACxC,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,cAAc,CAAC,EAAE,WAAWA,2BAAAA,IAACC,aAAAA,mBAAgB,KAAA,CAAY;AAC3D;AAEA,SAAS,cAAc,MAAqB;AAC1C,SAAO,KAAK,YAAY;AAC1B;AAEA,MAAM,iBAAkC;AAAA,EACtC,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,cAAc,CAAC,EAAE,WAAWD,2BAAAA,IAACE,aAAAA,iBAAc,KAAA,CAAY;AACzD;AAKO,SAAS,uBAAgD;AAC9D,SAAOC,iCAAyB,CAAC,kBAAkB,cAAc,CAAC;AACpE;;"}
@@ -0,0 +1,6 @@
1
+ import { TestNodeAdapterRegistry } from '../test-runner';
2
+ /** Default node adapters for VerificationResults: checklist items and
3
+ * fixture/CEL steps. Registration order matters only when a node could match
4
+ * both — a checklist node never carries a `context`, so the two never race. */
5
+ export declare function verificationAdapters(): TestNodeAdapterRegistry;
6
+ //# sourceMappingURL=adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../../src/data/verification/adapters.tsx"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,gBAAgB,CAAC;AAsBxB;;gFAEgF;AAChF,wBAAgB,oBAAoB,IAAI,uBAAuB,CAE9D"}
@@ -0,0 +1,26 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { ChecklistDetail, FixtureDetail } from "./adapterViews.js";
3
+ import { createTestRunnerRegistry } from "../test-runner/adapter.js";
4
+ function isChecklistNode(node) {
5
+ return node.framework === "checklist";
6
+ }
7
+ const checklistAdapter = {
8
+ id: "verification-checklist",
9
+ match: isChecklistNode,
10
+ renderDetail: ({ node }) => /* @__PURE__ */ jsx(ChecklistDetail, { node })
11
+ };
12
+ function isFixtureNode(node) {
13
+ return node.context !== void 0;
14
+ }
15
+ const fixtureAdapter = {
16
+ id: "verification-fixture",
17
+ match: isFixtureNode,
18
+ renderDetail: ({ node }) => /* @__PURE__ */ jsx(FixtureDetail, { node })
19
+ };
20
+ function verificationAdapters() {
21
+ return createTestRunnerRegistry([checklistAdapter, fixtureAdapter]);
22
+ }
23
+ export {
24
+ verificationAdapters
25
+ };
26
+ //# sourceMappingURL=adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.js","sources":["../../../src/data/verification/adapters.tsx"],"sourcesContent":["// Domain node adapters for VerificationResults: a checklist adapter for the\n// synthesized \"Acceptance criteria\" node and its items, and a fixture/CEL\n// adapter for the failing-step detail. Rendering lives in adapterViews.tsx —\n// split out so this file's only exports are the registry (react/only-export-\n// components forbids mixing component declarations with plain exports).\n\nimport { ChecklistDetail, FixtureDetail } from \"./adapterViews\";\nimport {\n createTestRunnerRegistry,\n type Test,\n type TestNodeAdapter,\n type TestNodeAdapterRegistry,\n} from \"../test-runner\";\n\nfunction isChecklistNode(node: Test): boolean {\n return node.framework === \"checklist\";\n}\n\nconst checklistAdapter: TestNodeAdapter = {\n id: \"verification-checklist\",\n match: isChecklistNode,\n renderDetail: ({ node }) => <ChecklistDetail node={node} />,\n};\n\nfunction isFixtureNode(node: Test): boolean {\n return node.context !== undefined;\n}\n\nconst fixtureAdapter: TestNodeAdapter = {\n id: \"verification-fixture\",\n match: isFixtureNode,\n renderDetail: ({ node }) => <FixtureDetail node={node} />,\n};\n\n/** Default node adapters for VerificationResults: checklist items and\n * fixture/CEL steps. Registration order matters only when a node could match\n * both — a checklist node never carries a `context`, so the two never race. */\nexport function verificationAdapters(): TestNodeAdapterRegistry {\n return createTestRunnerRegistry([checklistAdapter, fixtureAdapter]);\n}\n"],"names":[],"mappings":";;;AAcA,SAAS,gBAAgB,MAAqB;AAC5C,SAAO,KAAK,cAAc;AAC5B;AAEA,MAAM,mBAAoC;AAAA,EACxC,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,cAAc,CAAC,EAAE,WAAW,oBAAC,mBAAgB,KAAA,CAAY;AAC3D;AAEA,SAAS,cAAc,MAAqB;AAC1C,SAAO,KAAK,YAAY;AAC1B;AAEA,MAAM,iBAAkC;AAAA,EACtC,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,cAAc,CAAC,EAAE,WAAW,oBAAC,iBAAc,KAAA,CAAY;AACzD;AAKO,SAAS,uBAAgD;AAC9D,SAAO,yBAAyB,CAAC,kBAAkB,cAAc,CAAC;AACpE;"}
@@ -0,0 +1,5 @@
1
+ export { emptyVerifySummary, summarizeVerifyNodes, type VerifyChecklistItem, type VerifyNode, type VerifyNodeContext, type VerifyNodeProgress, type VerifyReport, type VerifyState, type VerifySummary, } from './verify-report';
2
+ export { verifyReportCounts, verifyReportTests } from './verifyReportTests';
3
+ export { verificationAdapters } from './adapters';
4
+ export { VerificationResults, type VerificationResultsProps } from './VerificationResults';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/verification/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function emptyVerifySummary() {
4
+ return {
5
+ total: 0,
6
+ passed: 0,
7
+ failed: 0,
8
+ warned: 0,
9
+ skipped: 0,
10
+ pending: 0,
11
+ running: 0,
12
+ timedout: 0
13
+ };
14
+ }
15
+ function leafBucket(node) {
16
+ if (node.failed) return "failed";
17
+ if (node.timed_out) return "timedout";
18
+ if (node.warned) return "warned";
19
+ if (node.skipped) return "skipped";
20
+ if (node.running) return "running";
21
+ if (node.pending) return "pending";
22
+ if (node.passed) return "passed";
23
+ return null;
24
+ }
25
+ function addVerifySummary(target, source) {
26
+ target.total += source.total;
27
+ target.passed += source.passed;
28
+ target.failed += source.failed;
29
+ target.warned += source.warned;
30
+ target.skipped += source.skipped;
31
+ target.pending += source.pending;
32
+ target.running += source.running;
33
+ target.timedout += source.timedout;
34
+ }
35
+ function summarizeVerifyNodes(nodes) {
36
+ const summary = emptyVerifySummary();
37
+ const walk = (list) => {
38
+ for (const node of list) {
39
+ if (node.summary) {
40
+ addVerifySummary(summary, node.summary);
41
+ continue;
42
+ }
43
+ if (node.children && node.children.length > 0) {
44
+ walk(node.children);
45
+ continue;
46
+ }
47
+ const bucket = leafBucket(node);
48
+ if (bucket === null) continue;
49
+ summary[bucket] += 1;
50
+ summary.total += 1;
51
+ }
52
+ };
53
+ walk(nodes);
54
+ return summary;
55
+ }
56
+ exports.emptyVerifySummary = emptyVerifySummary;
57
+ exports.summarizeVerifyNodes = summarizeVerifyNodes;
58
+ //# sourceMappingURL=verify-report.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-report.cjs","sources":["../../../src/data/verification/verify-report.ts"],"sourcesContent":["// Wire types for captain's VerifyReport — the shared shape a captain workflow\n// run and a gavel todo attempt both produce for their verification step. The Go\n// twin is written from the same spec, so field names and nesting here are\n// canonical; do not deviate without updating both sides.\n\nexport type VerifyState =\n | \"queued\"\n | \"running\"\n | \"passed\"\n | \"failed\"\n | \"errored\"\n | \"warned\"\n | \"skipped\"\n | \"cancelled\"\n | \"timed_out\";\n\nexport interface VerifySummary {\n total: number;\n passed: number;\n failed: number;\n warned: number;\n skipped: number;\n pending: number;\n running: number;\n timedout: number;\n}\n\nexport interface VerifyNodeProgress {\n phase?: string;\n done: number;\n total: number;\n}\n\n/** Mirrors the test-runner's `FixtureContext` — a fixture/CEL step's evidence. */\nexport interface VerifyNodeContext {\n command?: string;\n exit_code?: number;\n cwd?: string;\n cel_expression?: string;\n cel_vars?: Record<string, unknown>;\n expected?: unknown;\n actual?: unknown;\n}\n\nexport interface VerifyNode {\n name: string;\n framework?: string;\n task_id?: string;\n file?: string;\n line?: number;\n message?: string;\n command?: string;\n work_dir?: string;\n stdout?: string;\n stderr?: string;\n /** Duration in nanoseconds. */\n duration?: number;\n passed?: boolean;\n failed?: boolean;\n warned?: boolean;\n skipped?: boolean;\n pending?: boolean;\n running?: boolean;\n timed_out?: boolean;\n progress?: VerifyNodeProgress;\n context?: VerifyNodeContext;\n detail?: unknown;\n children?: VerifyNode[];\n /**\n * Pre-computed summary for a group node whose children were elided (e.g. a\n * fixture runner reporting a large suite without every leaf). When present,\n * `summarizeVerifyNodes` and `verifyReportTests` both take this summary as\n * the node's contribution and do not recurse into `children`, mirroring\n * Go's `SummarizeNodes` (captain/pkg/api/verify_report.go).\n */\n summary?: VerifySummary;\n}\n\nexport interface VerifyChecklistItem {\n item: string;\n passed?: boolean | null;\n message?: string;\n}\n\nexport interface VerifyReport {\n kind: string;\n name?: string;\n ran: boolean;\n passed: boolean;\n reason?: string;\n feedback?: string;\n iteration?: number;\n summary: VerifySummary;\n tests?: VerifyNode[];\n checklist?: VerifyChecklistItem[];\n state: VerifyState;\n started_at?: string;\n finished_at?: string;\n /** Duration in nanoseconds. */\n duration?: number;\n}\n\nexport function emptyVerifySummary(): VerifySummary {\n return {\n total: 0,\n passed: 0,\n failed: 0,\n warned: 0,\n skipped: 0,\n pending: 0,\n running: 0,\n timedout: 0,\n };\n}\n\n/** A single leaf `VerifyNode`'s classification, by the same precedence order\n * Go's `SummarizeNodes` applies: failed → timed-out → warned → skipped →\n * running → pending → passed. Returns null for a leaf carrying no status\n * flag at all (excluded from every bucket, including `total`). */\nfunction leafBucket(node: VerifyNode): keyof Omit<VerifySummary, \"total\"> | null {\n if (node.failed) return \"failed\";\n if (node.timed_out) return \"timedout\";\n if (node.warned) return \"warned\";\n if (node.skipped) return \"skipped\";\n if (node.running) return \"running\";\n if (node.pending) return \"pending\";\n if (node.passed) return \"passed\";\n return null;\n}\n\nfunction addVerifySummary(target: VerifySummary, source: VerifySummary): void {\n target.total += source.total;\n target.passed += source.passed;\n target.failed += source.failed;\n target.warned += source.warned;\n target.skipped += source.skipped;\n target.pending += source.pending;\n target.running += source.running;\n target.timedout += source.timedout;\n}\n\n/**\n * Mirrors captain's `SummarizeNodes` (captain/pkg/api/verify_report.go): tallies\n * only leaf nodes (a node with children is a container and is never itself\n * counted — its children are) into a `VerifySummary`, applying the same\n * failed → timed-out → warned → skipped → running → pending → passed\n * precedence per leaf. Used to build a `VerifyReport.summary` that stays\n * consistent with its `tests`, the way captain's `Validate` requires.\n *\n * A node carrying its own `summary` (a group whose children were elided)\n * contributes that summary directly and is never recursed into, even when it\n * also carries `children` — parity with Go's `SummarizeNodes`.\n */\nexport function summarizeVerifyNodes(nodes: VerifyNode[]): VerifySummary {\n const summary = emptyVerifySummary();\n const walk = (list: VerifyNode[]) => {\n for (const node of list) {\n if (node.summary) {\n addVerifySummary(summary, node.summary);\n continue;\n }\n if (node.children && node.children.length > 0) {\n walk(node.children);\n continue;\n }\n const bucket = leafBucket(node);\n if (bucket === null) continue;\n summary[bucket] += 1;\n summary.total += 1;\n }\n };\n walk(nodes);\n return summary;\n}\n"],"names":[],"mappings":";;AAsGO,SAAS,qBAAoC;AAClD,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,EAAA;AAEd;AAMA,SAAS,WAAW,MAA6D;AAC/E,MAAI,KAAK,OAAQ,QAAO;AACxB,MAAI,KAAK,UAAW,QAAO;AAC3B,MAAI,KAAK,OAAQ,QAAO;AACxB,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,OAAQ,QAAO;AACxB,SAAO;AACT;AAEA,SAAS,iBAAiB,QAAuB,QAA6B;AAC5E,SAAO,SAAS,OAAO;AACvB,SAAO,UAAU,OAAO;AACxB,SAAO,UAAU,OAAO;AACxB,SAAO,UAAU,OAAO;AACxB,SAAO,WAAW,OAAO;AACzB,SAAO,WAAW,OAAO;AACzB,SAAO,WAAW,OAAO;AACzB,SAAO,YAAY,OAAO;AAC5B;AAcO,SAAS,qBAAqB,OAAoC;AACvE,QAAM,UAAU,mBAAA;AAChB,QAAM,OAAO,CAAC,SAAuB;AACnC,eAAW,QAAQ,MAAM;AACvB,UAAI,KAAK,SAAS;AAChB,yBAAiB,SAAS,KAAK,OAAO;AACtC;AAAA,MACF;AACA,UAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAC7C,aAAK,KAAK,QAAQ;AAClB;AAAA,MACF;AACA,YAAM,SAAS,WAAW,IAAI;AAC9B,UAAI,WAAW,KAAM;AACrB,cAAQ,MAAM,KAAK;AACnB,cAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AACA,OAAK,KAAK;AACV,SAAO;AACT;;;"}
@@ -0,0 +1,96 @@
1
+ export type VerifyState = "queued" | "running" | "passed" | "failed" | "errored" | "warned" | "skipped" | "cancelled" | "timed_out";
2
+ export interface VerifySummary {
3
+ total: number;
4
+ passed: number;
5
+ failed: number;
6
+ warned: number;
7
+ skipped: number;
8
+ pending: number;
9
+ running: number;
10
+ timedout: number;
11
+ }
12
+ export interface VerifyNodeProgress {
13
+ phase?: string;
14
+ done: number;
15
+ total: number;
16
+ }
17
+ /** Mirrors the test-runner's `FixtureContext` — a fixture/CEL step's evidence. */
18
+ export interface VerifyNodeContext {
19
+ command?: string;
20
+ exit_code?: number;
21
+ cwd?: string;
22
+ cel_expression?: string;
23
+ cel_vars?: Record<string, unknown>;
24
+ expected?: unknown;
25
+ actual?: unknown;
26
+ }
27
+ export interface VerifyNode {
28
+ name: string;
29
+ framework?: string;
30
+ task_id?: string;
31
+ file?: string;
32
+ line?: number;
33
+ message?: string;
34
+ command?: string;
35
+ work_dir?: string;
36
+ stdout?: string;
37
+ stderr?: string;
38
+ /** Duration in nanoseconds. */
39
+ duration?: number;
40
+ passed?: boolean;
41
+ failed?: boolean;
42
+ warned?: boolean;
43
+ skipped?: boolean;
44
+ pending?: boolean;
45
+ running?: boolean;
46
+ timed_out?: boolean;
47
+ progress?: VerifyNodeProgress;
48
+ context?: VerifyNodeContext;
49
+ detail?: unknown;
50
+ children?: VerifyNode[];
51
+ /**
52
+ * Pre-computed summary for a group node whose children were elided (e.g. a
53
+ * fixture runner reporting a large suite without every leaf). When present,
54
+ * `summarizeVerifyNodes` and `verifyReportTests` both take this summary as
55
+ * the node's contribution and do not recurse into `children`, mirroring
56
+ * Go's `SummarizeNodes` (captain/pkg/api/verify_report.go).
57
+ */
58
+ summary?: VerifySummary;
59
+ }
60
+ export interface VerifyChecklistItem {
61
+ item: string;
62
+ passed?: boolean | null;
63
+ message?: string;
64
+ }
65
+ export interface VerifyReport {
66
+ kind: string;
67
+ name?: string;
68
+ ran: boolean;
69
+ passed: boolean;
70
+ reason?: string;
71
+ feedback?: string;
72
+ iteration?: number;
73
+ summary: VerifySummary;
74
+ tests?: VerifyNode[];
75
+ checklist?: VerifyChecklistItem[];
76
+ state: VerifyState;
77
+ started_at?: string;
78
+ finished_at?: string;
79
+ /** Duration in nanoseconds. */
80
+ duration?: number;
81
+ }
82
+ export declare function emptyVerifySummary(): VerifySummary;
83
+ /**
84
+ * Mirrors captain's `SummarizeNodes` (captain/pkg/api/verify_report.go): tallies
85
+ * only leaf nodes (a node with children is a container and is never itself
86
+ * counted — its children are) into a `VerifySummary`, applying the same
87
+ * failed → timed-out → warned → skipped → running → pending → passed
88
+ * precedence per leaf. Used to build a `VerifyReport.summary` that stays
89
+ * consistent with its `tests`, the way captain's `Validate` requires.
90
+ *
91
+ * A node carrying its own `summary` (a group whose children were elided)
92
+ * contributes that summary directly and is never recursed into, even when it
93
+ * also carries `children` — parity with Go's `SummarizeNodes`.
94
+ */
95
+ export declare function summarizeVerifyNodes(nodes: VerifyNode[]): VerifySummary;
96
+ //# sourceMappingURL=verify-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-report.d.ts","sourceRoot":"","sources":["../../../src/data/verification/verify-report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ function emptyVerifySummary() {
2
+ return {
3
+ total: 0,
4
+ passed: 0,
5
+ failed: 0,
6
+ warned: 0,
7
+ skipped: 0,
8
+ pending: 0,
9
+ running: 0,
10
+ timedout: 0
11
+ };
12
+ }
13
+ function leafBucket(node) {
14
+ if (node.failed) return "failed";
15
+ if (node.timed_out) return "timedout";
16
+ if (node.warned) return "warned";
17
+ if (node.skipped) return "skipped";
18
+ if (node.running) return "running";
19
+ if (node.pending) return "pending";
20
+ if (node.passed) return "passed";
21
+ return null;
22
+ }
23
+ function addVerifySummary(target, source) {
24
+ target.total += source.total;
25
+ target.passed += source.passed;
26
+ target.failed += source.failed;
27
+ target.warned += source.warned;
28
+ target.skipped += source.skipped;
29
+ target.pending += source.pending;
30
+ target.running += source.running;
31
+ target.timedout += source.timedout;
32
+ }
33
+ function summarizeVerifyNodes(nodes) {
34
+ const summary = emptyVerifySummary();
35
+ const walk = (list) => {
36
+ for (const node of list) {
37
+ if (node.summary) {
38
+ addVerifySummary(summary, node.summary);
39
+ continue;
40
+ }
41
+ if (node.children && node.children.length > 0) {
42
+ walk(node.children);
43
+ continue;
44
+ }
45
+ const bucket = leafBucket(node);
46
+ if (bucket === null) continue;
47
+ summary[bucket] += 1;
48
+ summary.total += 1;
49
+ }
50
+ };
51
+ walk(nodes);
52
+ return summary;
53
+ }
54
+ export {
55
+ emptyVerifySummary,
56
+ summarizeVerifyNodes
57
+ };
58
+ //# sourceMappingURL=verify-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-report.js","sources":["../../../src/data/verification/verify-report.ts"],"sourcesContent":["// Wire types for captain's VerifyReport — the shared shape a captain workflow\n// run and a gavel todo attempt both produce for their verification step. The Go\n// twin is written from the same spec, so field names and nesting here are\n// canonical; do not deviate without updating both sides.\n\nexport type VerifyState =\n | \"queued\"\n | \"running\"\n | \"passed\"\n | \"failed\"\n | \"errored\"\n | \"warned\"\n | \"skipped\"\n | \"cancelled\"\n | \"timed_out\";\n\nexport interface VerifySummary {\n total: number;\n passed: number;\n failed: number;\n warned: number;\n skipped: number;\n pending: number;\n running: number;\n timedout: number;\n}\n\nexport interface VerifyNodeProgress {\n phase?: string;\n done: number;\n total: number;\n}\n\n/** Mirrors the test-runner's `FixtureContext` — a fixture/CEL step's evidence. */\nexport interface VerifyNodeContext {\n command?: string;\n exit_code?: number;\n cwd?: string;\n cel_expression?: string;\n cel_vars?: Record<string, unknown>;\n expected?: unknown;\n actual?: unknown;\n}\n\nexport interface VerifyNode {\n name: string;\n framework?: string;\n task_id?: string;\n file?: string;\n line?: number;\n message?: string;\n command?: string;\n work_dir?: string;\n stdout?: string;\n stderr?: string;\n /** Duration in nanoseconds. */\n duration?: number;\n passed?: boolean;\n failed?: boolean;\n warned?: boolean;\n skipped?: boolean;\n pending?: boolean;\n running?: boolean;\n timed_out?: boolean;\n progress?: VerifyNodeProgress;\n context?: VerifyNodeContext;\n detail?: unknown;\n children?: VerifyNode[];\n /**\n * Pre-computed summary for a group node whose children were elided (e.g. a\n * fixture runner reporting a large suite without every leaf). When present,\n * `summarizeVerifyNodes` and `verifyReportTests` both take this summary as\n * the node's contribution and do not recurse into `children`, mirroring\n * Go's `SummarizeNodes` (captain/pkg/api/verify_report.go).\n */\n summary?: VerifySummary;\n}\n\nexport interface VerifyChecklistItem {\n item: string;\n passed?: boolean | null;\n message?: string;\n}\n\nexport interface VerifyReport {\n kind: string;\n name?: string;\n ran: boolean;\n passed: boolean;\n reason?: string;\n feedback?: string;\n iteration?: number;\n summary: VerifySummary;\n tests?: VerifyNode[];\n checklist?: VerifyChecklistItem[];\n state: VerifyState;\n started_at?: string;\n finished_at?: string;\n /** Duration in nanoseconds. */\n duration?: number;\n}\n\nexport function emptyVerifySummary(): VerifySummary {\n return {\n total: 0,\n passed: 0,\n failed: 0,\n warned: 0,\n skipped: 0,\n pending: 0,\n running: 0,\n timedout: 0,\n };\n}\n\n/** A single leaf `VerifyNode`'s classification, by the same precedence order\n * Go's `SummarizeNodes` applies: failed → timed-out → warned → skipped →\n * running → pending → passed. Returns null for a leaf carrying no status\n * flag at all (excluded from every bucket, including `total`). */\nfunction leafBucket(node: VerifyNode): keyof Omit<VerifySummary, \"total\"> | null {\n if (node.failed) return \"failed\";\n if (node.timed_out) return \"timedout\";\n if (node.warned) return \"warned\";\n if (node.skipped) return \"skipped\";\n if (node.running) return \"running\";\n if (node.pending) return \"pending\";\n if (node.passed) return \"passed\";\n return null;\n}\n\nfunction addVerifySummary(target: VerifySummary, source: VerifySummary): void {\n target.total += source.total;\n target.passed += source.passed;\n target.failed += source.failed;\n target.warned += source.warned;\n target.skipped += source.skipped;\n target.pending += source.pending;\n target.running += source.running;\n target.timedout += source.timedout;\n}\n\n/**\n * Mirrors captain's `SummarizeNodes` (captain/pkg/api/verify_report.go): tallies\n * only leaf nodes (a node with children is a container and is never itself\n * counted — its children are) into a `VerifySummary`, applying the same\n * failed → timed-out → warned → skipped → running → pending → passed\n * precedence per leaf. Used to build a `VerifyReport.summary` that stays\n * consistent with its `tests`, the way captain's `Validate` requires.\n *\n * A node carrying its own `summary` (a group whose children were elided)\n * contributes that summary directly and is never recursed into, even when it\n * also carries `children` — parity with Go's `SummarizeNodes`.\n */\nexport function summarizeVerifyNodes(nodes: VerifyNode[]): VerifySummary {\n const summary = emptyVerifySummary();\n const walk = (list: VerifyNode[]) => {\n for (const node of list) {\n if (node.summary) {\n addVerifySummary(summary, node.summary);\n continue;\n }\n if (node.children && node.children.length > 0) {\n walk(node.children);\n continue;\n }\n const bucket = leafBucket(node);\n if (bucket === null) continue;\n summary[bucket] += 1;\n summary.total += 1;\n }\n };\n walk(nodes);\n return summary;\n}\n"],"names":[],"mappings":"AAsGO,SAAS,qBAAoC;AAClD,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,EAAA;AAEd;AAMA,SAAS,WAAW,MAA6D;AAC/E,MAAI,KAAK,OAAQ,QAAO;AACxB,MAAI,KAAK,UAAW,QAAO;AAC3B,MAAI,KAAK,OAAQ,QAAO;AACxB,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,QAAS,QAAO;AACzB,MAAI,KAAK,OAAQ,QAAO;AACxB,SAAO;AACT;AAEA,SAAS,iBAAiB,QAAuB,QAA6B;AAC5E,SAAO,SAAS,OAAO;AACvB,SAAO,UAAU,OAAO;AACxB,SAAO,UAAU,OAAO;AACxB,SAAO,UAAU,OAAO;AACxB,SAAO,WAAW,OAAO;AACzB,SAAO,WAAW,OAAO;AACzB,SAAO,WAAW,OAAO;AACzB,SAAO,YAAY,OAAO;AAC5B;AAcO,SAAS,qBAAqB,OAAoC;AACvE,QAAM,UAAU,mBAAA;AAChB,QAAM,OAAO,CAAC,SAAuB;AACnC,eAAW,QAAQ,MAAM;AACvB,UAAI,KAAK,SAAS;AAChB,yBAAiB,SAAS,KAAK,OAAO;AACtC;AAAA,MACF;AACA,UAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAC7C,aAAK,KAAK,QAAQ;AAClB;AAAA,MACF;AACA,YAAM,SAAS,WAAW,IAAI;AAC9B,UAAI,WAAW,KAAM;AACrB,cAAQ,MAAM,KAAK;AACnB,cAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AACA,OAAK,KAAK;AACV,SAAO;AACT;"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const status = require("../test-runner/status.cjs");
4
+ const ACCEPTANCE_CRITERIA_ID = "acceptance-criteria";
5
+ function coerceDuration(duration) {
6
+ return typeof duration === "number" && Number.isFinite(duration) ? duration : void 0;
7
+ }
8
+ function verifySummaryToTestSummary(summary) {
9
+ return {
10
+ Total: summary.total,
11
+ Passed: summary.passed,
12
+ Failed: summary.failed,
13
+ Warned: summary.warned,
14
+ Skipped: summary.skipped,
15
+ Pending: summary.pending,
16
+ Running: summary.running,
17
+ Duration: 0
18
+ };
19
+ }
20
+ function verifyNodeTest(node) {
21
+ const test = { name: node.name };
22
+ if (node.framework !== void 0) test.framework = node.framework;
23
+ if (node.task_id !== void 0) test.task_id = node.task_id;
24
+ if (node.file !== void 0) test.file = node.file;
25
+ if (node.line !== void 0) test.line = node.line;
26
+ if (node.message !== void 0) test.message = node.message;
27
+ if (node.command !== void 0) test.command = node.command;
28
+ if (node.work_dir !== void 0) test.work_dir = node.work_dir;
29
+ if (node.stdout !== void 0) test.stdout = node.stdout;
30
+ if (node.stderr !== void 0) test.stderr = node.stderr;
31
+ const duration = coerceDuration(node.duration);
32
+ if (duration !== void 0) test.duration = duration;
33
+ if (node.passed !== void 0) test.passed = node.passed;
34
+ if (node.failed !== void 0) test.failed = node.failed;
35
+ if (node.warned !== void 0) test.warned = node.warned;
36
+ if (node.skipped !== void 0) test.skipped = node.skipped;
37
+ if (node.pending !== void 0) test.pending = node.pending;
38
+ if (node.running !== void 0) test.running = node.running;
39
+ if (node.timed_out !== void 0) test.timed_out = node.timed_out;
40
+ if (node.progress !== void 0) test.progress = node.progress;
41
+ if (node.context !== void 0) test.context = node.context;
42
+ if (node.detail !== void 0) test.detail = node.detail;
43
+ if (node.summary !== void 0) {
44
+ test.summary = verifySummaryToTestSummary(node.summary);
45
+ } else if (node.children !== void 0) {
46
+ test.children = node.children.map(verifyNodeTest);
47
+ }
48
+ return test;
49
+ }
50
+ function checklistItemTest(item, index) {
51
+ const test = {
52
+ name: item.item || `Criterion ${index + 1}`,
53
+ framework: "checklist",
54
+ task_id: `${ACCEPTANCE_CRITERIA_ID}:${index}`,
55
+ passed: item.passed === true,
56
+ failed: item.passed === false,
57
+ pending: item.passed !== true && item.passed !== false,
58
+ detail: item
59
+ };
60
+ if (item.message !== void 0) test.message = item.message;
61
+ return test;
62
+ }
63
+ function checklistTest(checklist) {
64
+ if (checklist.length === 0) return null;
65
+ const children = checklist.map(checklistItemTest);
66
+ return {
67
+ name: "Acceptance criteria",
68
+ framework: "checklist",
69
+ task_id: ACCEPTANCE_CRITERIA_ID,
70
+ children
71
+ };
72
+ }
73
+ function verifyReportTests(report) {
74
+ const tests = (report.tests ?? []).map(verifyNodeTest);
75
+ const checklist = checklistTest(report.checklist ?? []);
76
+ return checklist ? [...tests, checklist] : tests;
77
+ }
78
+ function verifyReportCounts(report) {
79
+ return status.aggregateStatusCounts(verifyReportTests(report));
80
+ }
81
+ exports.verifyReportCounts = verifyReportCounts;
82
+ exports.verifyReportTests = verifyReportTests;
83
+ //# sourceMappingURL=verifyReportTests.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyReportTests.cjs","sources":["../../../src/data/verification/verifyReportTests.ts"],"sourcesContent":["// Projects a captain VerifyReport onto the shared test-runner Test model, so\n// VerificationResults can render it with the same TestRunner every other\n// fixture/test surface uses. Ported from gavel's verificationAttempts.ts\n// (executionNodeTest / checklistTest), adapted to VerifyReport's node shape\n// (which already carries boolean status flags, unlike gavel's execution\n// snapshot which carried a single `state` string to translate).\n\nimport { aggregateStatusCounts, type StatusCounts, type Test, type TestSummary } from \"../test-runner\";\nimport type { VerifyChecklistItem, VerifyNode, VerifyReport, VerifySummary } from \"./verify-report\";\n\nconst ACCEPTANCE_CRITERIA_ID = \"acceptance-criteria\";\n\nfunction coerceDuration(duration: unknown): number | undefined {\n return typeof duration === \"number\" && Number.isFinite(duration) ? duration : undefined;\n}\n\n/**\n * Projects a `VerifySummary` onto the test-runner's `TestSummary` shape (see\n * `test-runner/types.ts`), so `sum()`/`aggregateStatusCounts` (test-runner\n * `status.ts`) read a summary-carrying node's counts directly instead of\n * recursing into (possibly elided) children.\n *\n * `TestSummary` has no `timedout` counter — `countsFromSummary` in\n * `status.ts` always reports 0 for it — so a non-zero `VerifySummary.timedout`\n * does not survive this projection. `Duration` is likewise not carried by\n * `VerifySummary`, so it is reported as 0.\n */\nfunction verifySummaryToTestSummary(summary: VerifySummary): TestSummary {\n return {\n Total: summary.total,\n Passed: summary.passed,\n Failed: summary.failed,\n Warned: summary.warned,\n Skipped: summary.skipped,\n Pending: summary.pending,\n Running: summary.running,\n Duration: 0,\n };\n}\n\n// Every field below is optional on both VerifyNode and Test, and the project\n// compiles with exactOptionalPropertyTypes — so an absent field must be an\n// absent key, not a key explicitly set to undefined. Each is assigned only\n// when present rather than copied through in one object literal.\nfunction verifyNodeTest(node: VerifyNode): Test {\n const test: Test = { name: node.name };\n if (node.framework !== undefined) test.framework = node.framework;\n if (node.task_id !== undefined) test.task_id = node.task_id;\n if (node.file !== undefined) test.file = node.file;\n if (node.line !== undefined) test.line = node.line;\n if (node.message !== undefined) test.message = node.message;\n if (node.command !== undefined) test.command = node.command;\n if (node.work_dir !== undefined) test.work_dir = node.work_dir;\n if (node.stdout !== undefined) test.stdout = node.stdout;\n if (node.stderr !== undefined) test.stderr = node.stderr;\n const duration = coerceDuration(node.duration);\n if (duration !== undefined) test.duration = duration;\n if (node.passed !== undefined) test.passed = node.passed;\n if (node.failed !== undefined) test.failed = node.failed;\n if (node.warned !== undefined) test.warned = node.warned;\n if (node.skipped !== undefined) test.skipped = node.skipped;\n if (node.pending !== undefined) test.pending = node.pending;\n if (node.running !== undefined) test.running = node.running;\n if (node.timed_out !== undefined) test.timed_out = node.timed_out;\n if (node.progress !== undefined) test.progress = node.progress;\n if (node.context !== undefined) test.context = node.context;\n if (node.detail !== undefined) test.detail = node.detail;\n // A node carrying its own `summary` (elided children) contributes that\n // summary directly and is never recursed into, even if `children` is also\n // present — parity with Go's `SummarizeNodes` and `summarizeVerifyNodes`.\n if (node.summary !== undefined) {\n test.summary = verifySummaryToTestSummary(node.summary);\n } else if (node.children !== undefined) {\n test.children = node.children.map(verifyNodeTest);\n }\n return test;\n}\n\nfunction checklistItemTest(item: VerifyChecklistItem, index: number): Test {\n const test: Test = {\n name: item.item || `Criterion ${index + 1}`,\n framework: \"checklist\",\n task_id: `${ACCEPTANCE_CRITERIA_ID}:${index}`,\n passed: item.passed === true,\n failed: item.passed === false,\n pending: item.passed !== true && item.passed !== false,\n detail: item,\n };\n if (item.message !== undefined) test.message = item.message;\n return test;\n}\n\n/**\n * Synthesizes the \"Acceptance criteria\" parent node gavel's checklistTest\n * ports. Deliberately carries no status flags of its own — `status.ts`'s\n * `testStatus` checks `pending` before `failed`, so a container explicitly\n * flagged both `failed` and `pending` (one item failed, another is still\n * unjudged) would render as queued instead of failed. Leaving the container\n * status-less lets the shared roll-up (`statusIconFor`/`statusToneFor`: failed\n * → warned → running → pending → passed, via `sum()` over the children) decide\n * instead.\n */\nfunction checklistTest(checklist: VerifyChecklistItem[]): Test | null {\n if (checklist.length === 0) return null;\n const children = checklist.map(checklistItemTest);\n return {\n name: \"Acceptance criteria\",\n framework: \"checklist\",\n task_id: ACCEPTANCE_CRITERIA_ID,\n children,\n };\n}\n\n/** Maps a VerifyReport onto the TestRunner's Test forest, appending a\n * synthesized \"Acceptance criteria\" node for the checklist when present. */\nexport function verifyReportTests(report: VerifyReport): Test[] {\n const tests = (report.tests ?? []).map(verifyNodeTest);\n const checklist = checklistTest(report.checklist ?? []);\n return checklist ? [...tests, checklist] : tests;\n}\n\n/**\n * Status roll-up across the *rendered* forest: `report.tests` plus the\n * synthesized checklist leaves. This is **not** `report.summary` — the\n * producer's tests-only tally (see `summarizeVerifyNodes` in ./verify-report)\n * — since it also counts checklist items, which never appear in `tests`.\n */\nexport function verifyReportCounts(report: VerifyReport): StatusCounts {\n return aggregateStatusCounts(verifyReportTests(report));\n}\n"],"names":["aggregateStatusCounts"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { StatusCounts, Test } from '../test-runner';
2
+ import { VerifyReport } from './verify-report';
3
+ /** Maps a VerifyReport onto the TestRunner's Test forest, appending a
4
+ * synthesized "Acceptance criteria" node for the checklist when present. */
5
+ export declare function verifyReportTests(report: VerifyReport): Test[];
6
+ /**
7
+ * Status roll-up across the *rendered* forest: `report.tests` plus the
8
+ * synthesized checklist leaves. This is **not** `report.summary` — the
9
+ * producer's tests-only tally (see `summarizeVerifyNodes` in ./verify-report)
10
+ * — since it also counts checklist items, which never appear in `tests`.
11
+ */
12
+ export declare function verifyReportCounts(report: VerifyReport): StatusCounts;
13
+ //# sourceMappingURL=verifyReportTests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyReportTests.d.ts","sourceRoot":"","sources":["../../../src/data/verification/verifyReportTests.ts"],"names":[],"mappings":"AAOA,OAAO,EAAyB,KAAK,YAAY,EAAE,KAAK,IAAI,EAAoB,MAAM,gBAAgB,CAAC;AACvG,OAAO,KAAK,EAAmC,YAAY,EAAiB,MAAM,iBAAiB,CAAC;AAyGpG;6EAC6E;AAC7E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,CAI9D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAErE"}