@adoptai/genui-components 0.1.57 → 0.1.59

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 (56) hide show
  1. package/dist/composites/document-field-extraction/FieldAuditLog.d.ts +27 -0
  2. package/dist/composites/document-field-extraction/FieldAuditLog.d.ts.map +1 -0
  3. package/dist/composites/document-field-extraction/FieldDetail.d.ts +22 -0
  4. package/dist/composites/document-field-extraction/FieldDetail.d.ts.map +1 -0
  5. package/dist/composites/document-field-extraction/FieldDetails.d.ts +18 -0
  6. package/dist/composites/document-field-extraction/FieldDetails.d.ts.map +1 -0
  7. package/dist/composites/document-field-extraction/bboxTransform.d.ts +25 -0
  8. package/dist/composites/document-field-extraction/bboxTransform.d.ts.map +1 -0
  9. package/dist/composites/document-field-extraction/fieldLabels.d.ts +2 -0
  10. package/dist/composites/document-field-extraction/fieldLabels.d.ts.map +1 -0
  11. package/dist/composites/document-field-extraction/resolver.cjs +1920 -0
  12. package/dist/composites/document-field-extraction/resolver.cjs.map +1 -0
  13. package/dist/composites/document-field-extraction/resolver.d.ts +16 -0
  14. package/dist/composites/document-field-extraction/resolver.d.ts.map +1 -0
  15. package/dist/composites/document-field-extraction/resolver.js +1913 -0
  16. package/dist/composites/document-field-extraction/resolver.js.map +1 -0
  17. package/dist/composites/tabby-auth/resolver.cjs +597 -0
  18. package/dist/composites/tabby-auth/resolver.cjs.map +1 -0
  19. package/dist/composites/tabby-auth/resolver.d.ts +3 -0
  20. package/dist/composites/tabby-auth/resolver.d.ts.map +1 -0
  21. package/dist/composites/tabby-auth/resolver.js +595 -0
  22. package/dist/composites/tabby-auth/resolver.js.map +1 -0
  23. package/dist/composites/workflow-stepper/resolver.cjs +86 -18
  24. package/dist/composites/workflow-stepper/resolver.cjs.map +1 -1
  25. package/dist/composites/workflow-stepper/resolver.d.ts.map +1 -1
  26. package/dist/composites/workflow-stepper/resolver.js +86 -18
  27. package/dist/composites/workflow-stepper/resolver.js.map +1 -1
  28. package/dist/index.cjs +2661 -345
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.ts +5 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2456 -144
  33. package/dist/index.js.map +1 -1
  34. package/dist/renderer.cjs +2482 -281
  35. package/dist/renderer.cjs.map +1 -1
  36. package/dist/renderer.js +2339 -138
  37. package/dist/renderer.js.map +1 -1
  38. package/dist/resolver.cjs +2481 -280
  39. package/dist/resolver.cjs.map +1 -1
  40. package/dist/resolver.d.ts.map +1 -1
  41. package/dist/resolver.js +2339 -138
  42. package/dist/resolver.js.map +1 -1
  43. package/dist/schemas/document-field-extraction.d.ts +258 -0
  44. package/dist/schemas/document-field-extraction.d.ts.map +1 -0
  45. package/dist/schemas/index.cjs +262 -3
  46. package/dist/schemas/index.cjs.map +1 -1
  47. package/dist/schemas/index.d.ts +376 -0
  48. package/dist/schemas/index.d.ts.map +1 -1
  49. package/dist/schemas/index.js +262 -3
  50. package/dist/schemas/index.js.map +1 -1
  51. package/dist/schemas/tabby-auth.d.ts +58 -0
  52. package/dist/schemas/tabby-auth.d.ts.map +1 -0
  53. package/dist/schemas/workflow-stepper.d.ts +60 -0
  54. package/dist/schemas/workflow-stepper.d.ts.map +1 -1
  55. package/dist/tool-definitions.json +326 -3
  56. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React41 = require('react');
4
+ var React45 = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var dagre = require('@dagrejs/dagre');
7
7
  var reactDom = require('react-dom');
@@ -37,7 +37,7 @@ function _interopNamespace(e) {
37
37
  return Object.freeze(n);
38
38
  }
39
39
 
40
- var React41__default = /*#__PURE__*/_interopDefault(React41);
40
+ var React45__default = /*#__PURE__*/_interopDefault(React45);
41
41
  var dagre__default = /*#__PURE__*/_interopDefault(dagre);
42
42
  var XLSX__namespace = /*#__PURE__*/_interopNamespace(XLSX);
43
43
  var Papa__default = /*#__PURE__*/_interopDefault(Papa);
@@ -111,14 +111,14 @@ var init_theme = __esm({
111
111
  }
112
112
  });
113
113
  function GenUIThemeProvider({ colors, children }) {
114
- const merged = React41.useMemo(
114
+ const merged = React45.useMemo(
115
115
  () => colors ? __spreadValues(__spreadValues({}, exports.DEFAULT_TOKENS), colors) : exports.DEFAULT_TOKENS,
116
116
  [colors]
117
117
  );
118
118
  return /* @__PURE__ */ jsxRuntime.jsx(GenUIThemeContext.Provider, { value: merged, children });
119
119
  }
120
120
  function useTheme() {
121
- return React41.useContext(GenUIThemeContext);
121
+ return React45.useContext(GenUIThemeContext);
122
122
  }
123
123
  exports.DEFAULT_TOKENS = void 0; var GenUIThemeContext;
124
124
  var init_ThemeContext = __esm({
@@ -134,7 +134,7 @@ var init_ThemeContext = __esm({
134
134
  SECONDARY: exports.SECONDARY,
135
135
  CHART_PALETTE: [...exports.CHART_PALETTE]
136
136
  };
137
- GenUIThemeContext = React41.createContext(exports.DEFAULT_TOKENS);
137
+ GenUIThemeContext = React45.createContext(exports.DEFAULT_TOKENS);
138
138
  }
139
139
  });
140
140
  function renderInline(text) {
@@ -864,11 +864,11 @@ async function getMermaid(t) {
864
864
  }
865
865
  function MermaidFallback({ diagram, title }) {
866
866
  const tokens = useTheme();
867
- const [svg, setSvg] = React41.useState("");
868
- const [err, setErr] = React41.useState(false);
869
- const [full, setFull] = React41.useState(false);
870
- const idRef = React41.useRef(0);
871
- React41.useEffect(() => {
867
+ const [svg, setSvg] = React45.useState("");
868
+ const [err, setErr] = React45.useState(false);
869
+ const [full, setFull] = React45.useState(false);
870
+ const idRef = React45.useRef(0);
871
+ React45.useEffect(() => {
872
872
  const id = ++renderSeq;
873
873
  idRef.current = id;
874
874
  setErr(false);
@@ -937,7 +937,7 @@ function FullscreenModalInner({ nodes, edges, title, onClose }) {
937
937
  ] }) });
938
938
  }
939
939
  function FullscreenModal({ nodes, edges, title, onClose }) {
940
- React41.useEffect(() => {
940
+ React45.useEffect(() => {
941
941
  const h = (e) => {
942
942
  if (e.key === "Escape") onClose();
943
943
  };
@@ -950,8 +950,8 @@ function FullscreenModal({ nodes, edges, title, onClose }) {
950
950
  );
951
951
  }
952
952
  function usePrefersReducedMotion() {
953
- const [reduced, setReduced] = React41.useState(false);
954
- React41.useEffect(() => {
953
+ const [reduced, setReduced] = React45.useState(false);
954
+ React45.useEffect(() => {
955
955
  var _a2;
956
956
  if (typeof matchMedia === "undefined") return;
957
957
  const mq = matchMedia("(prefers-reduced-motion: reduce)");
@@ -995,9 +995,9 @@ function topoOrder(nodeIds, edges) {
995
995
  }
996
996
  function useAutoplay(order, enabled) {
997
997
  const reduced = usePrefersReducedMotion();
998
- const [step, setStep] = React41.useState(0);
998
+ const [step, setStep] = React45.useState(0);
999
999
  const key = order.join("|");
1000
- React41.useEffect(() => {
1000
+ React45.useEffect(() => {
1001
1001
  if (!enabled || reduced || order.length === 0) {
1002
1002
  setStep(0);
1003
1003
  return;
@@ -1019,7 +1019,7 @@ function useAutoplay(order, enabled) {
1019
1019
  timer = setTimeout(tick, 850);
1020
1020
  return () => clearTimeout(timer);
1021
1021
  }, [enabled, reduced, key]);
1022
- return React41.useMemo(() => {
1022
+ return React45.useMemo(() => {
1023
1023
  const m = {};
1024
1024
  order.forEach((id, i) => {
1025
1025
  m[id] = i < step ? "done" : i === step ? "active" : "pending";
@@ -1041,13 +1041,13 @@ function resolveStates(nodes, nodeStates) {
1041
1041
  }
1042
1042
  function Inner({ diagram, title, autoplay, nodeStates }) {
1043
1043
  const tokens = useTheme();
1044
- const [full, setFull] = React41.useState(false);
1045
- const [focused, setFocused] = React41.useState(false);
1046
- const [boxW, setBoxW] = React41.useState(640);
1047
- const containerRef = React41.useRef(null);
1048
- const parsed = React41.useMemo(() => parseMermaidFlow(diagram), [diagram]);
1049
- const layout = React41.useMemo(() => parsed ? computeLayout(parsed) : null, [parsed]);
1050
- const themedEdges = React41.useMemo(
1044
+ const [full, setFull] = React45.useState(false);
1045
+ const [focused, setFocused] = React45.useState(false);
1046
+ const [boxW, setBoxW] = React45.useState(640);
1047
+ const containerRef = React45.useRef(null);
1048
+ const parsed = React45.useMemo(() => parseMermaidFlow(diagram), [diagram]);
1049
+ const layout = React45.useMemo(() => parsed ? computeLayout(parsed) : null, [parsed]);
1050
+ const themedEdges = React45.useMemo(
1051
1051
  () => {
1052
1052
  var _a2;
1053
1053
  return ((_a2 = layout == null ? void 0 : layout.edges) != null ? _a2 : []).map((e) => __spreadProps(__spreadValues({}, e), {
@@ -1059,7 +1059,7 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1059
1059
  },
1060
1060
  [layout, tokens.ACCENT, tokens.MUTED]
1061
1061
  );
1062
- const order = React41.useMemo(
1062
+ const order = React45.useMemo(
1063
1063
  () => {
1064
1064
  var _a2, _b;
1065
1065
  return topoOrder(((_a2 = layout == null ? void 0 : layout.nodes) != null ? _a2 : []).map((n) => n.id), (_b = layout == null ? void 0 : layout.edges) != null ? _b : []);
@@ -1067,19 +1067,19 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1067
1067
  [layout]
1068
1068
  );
1069
1069
  const autoStatus = useAutoplay(order, !!autoplay);
1070
- const staticStatus = React41.useMemo(() => {
1070
+ const staticStatus = React45.useMemo(() => {
1071
1071
  var _a2;
1072
1072
  return resolveStates((_a2 = layout == null ? void 0 : layout.nodes) != null ? _a2 : [], nodeStates);
1073
1073
  }, [layout, nodeStates]);
1074
1074
  const statusMap = autoplay ? autoStatus : staticStatus;
1075
- const displayNodes = React41.useMemo(
1075
+ const displayNodes = React45.useMemo(
1076
1076
  () => {
1077
1077
  var _a2;
1078
1078
  return ((_a2 = layout == null ? void 0 : layout.nodes) != null ? _a2 : []).map((n) => __spreadProps(__spreadValues({}, n), { data: __spreadProps(__spreadValues({}, n.data), { status: statusMap[n.id] }) }));
1079
1079
  },
1080
1080
  [layout, statusMap]
1081
1081
  );
1082
- const displayEdges = React41.useMemo(
1082
+ const displayEdges = React45.useMemo(
1083
1083
  () => themedEdges.map((e) => {
1084
1084
  const ss = statusMap[e.source];
1085
1085
  const ts = statusMap[e.target];
@@ -1099,13 +1099,13 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1099
1099
  const [nodes, setNodes, onNC] = react.useNodesState(displayNodes);
1100
1100
  const [edges, setEdges, onEC] = react.useEdgesState(displayEdges);
1101
1101
  const rf = react.useReactFlow();
1102
- React41.useEffect(() => {
1102
+ React45.useEffect(() => {
1103
1103
  setNodes(displayNodes);
1104
1104
  }, [displayNodes, setNodes]);
1105
- React41.useEffect(() => {
1105
+ React45.useEffect(() => {
1106
1106
  setEdges(displayEdges);
1107
1107
  }, [displayEdges, setEdges]);
1108
- React41.useEffect(() => {
1108
+ React45.useEffect(() => {
1109
1109
  const id = requestAnimationFrame(() => {
1110
1110
  try {
1111
1111
  rf.fitView({ padding: 0.1 });
@@ -1114,14 +1114,14 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1114
1114
  });
1115
1115
  return () => cancelAnimationFrame(id);
1116
1116
  }, [layout, rf]);
1117
- const handleClickOutside = React41.useCallback((e) => {
1117
+ const handleClickOutside = React45.useCallback((e) => {
1118
1118
  if (containerRef.current && !containerRef.current.contains(e.target)) setFocused(false);
1119
1119
  }, []);
1120
- React41.useEffect(() => {
1120
+ React45.useEffect(() => {
1121
1121
  document.addEventListener("mousedown", handleClickOutside);
1122
1122
  return () => document.removeEventListener("mousedown", handleClickOutside);
1123
1123
  }, [handleClickOutside]);
1124
- React41.useEffect(() => {
1124
+ React45.useEffect(() => {
1125
1125
  const el = containerRef.current;
1126
1126
  if (!el) return;
1127
1127
  let raf = 0;
@@ -1280,15 +1280,15 @@ __export(PdfViewer_exports, {
1280
1280
  PdfViewer: () => PdfViewer
1281
1281
  });
1282
1282
  function PdfViewer({ url, base64, onLoadSuccess }) {
1283
- const [numPages, setNumPages] = React41.useState(0);
1284
- const [currentPage, setCurrentPage] = React41.useState(1);
1285
- const [loading, setLoading] = React41.useState(true);
1286
- const handleLoad = React41.useCallback(({ numPages: n }) => {
1283
+ const [numPages, setNumPages] = React45.useState(0);
1284
+ const [currentPage, setCurrentPage] = React45.useState(1);
1285
+ const [loading, setLoading] = React45.useState(true);
1286
+ const handleLoad = React45.useCallback(({ numPages: n }) => {
1287
1287
  setNumPages(n);
1288
1288
  setLoading(false);
1289
1289
  onLoadSuccess == null ? void 0 : onLoadSuccess(n);
1290
1290
  }, [onLoadSuccess]);
1291
- React41.useEffect(() => {
1291
+ React45.useEffect(() => {
1292
1292
  if (numPages <= 1) return;
1293
1293
  const handler = (e) => {
1294
1294
  var _a2;
@@ -1384,13 +1384,13 @@ __export(ExcelViewer_exports, {
1384
1384
  ExcelViewer: () => ExcelViewer
1385
1385
  });
1386
1386
  function ExcelViewer({ url, base64, onLoadSuccess }) {
1387
- const [sheetNames, setSheetNames] = React41.useState([]);
1388
- const [activeSheet, setActiveSheet] = React41.useState(0);
1389
- const [data, setData] = React41.useState([]);
1390
- const [loading, setLoading] = React41.useState(true);
1391
- const [error, setError] = React41.useState(null);
1392
- const wbRef = React41.useRef(null);
1393
- React41.useEffect(() => {
1387
+ const [sheetNames, setSheetNames] = React45.useState([]);
1388
+ const [activeSheet, setActiveSheet] = React45.useState(0);
1389
+ const [data, setData] = React45.useState([]);
1390
+ const [loading, setLoading] = React45.useState(true);
1391
+ const [error, setError] = React45.useState(null);
1392
+ const wbRef = React45.useRef(null);
1393
+ React45.useEffect(() => {
1394
1394
  let cancelled = false;
1395
1395
  setLoading(true);
1396
1396
  setError(null);
@@ -1448,7 +1448,7 @@ function ExcelViewer({ url, base64, onLoadSuccess }) {
1448
1448
  const rows = XLSX__namespace.utils.sheet_to_json(wbRef.current.Sheets[wbRef.current.SheetNames[idx]], { header: 1 });
1449
1449
  setData(rows);
1450
1450
  };
1451
- React41.useEffect(() => {
1451
+ React45.useEffect(() => {
1452
1452
  if (sheetNames.length <= 1) return;
1453
1453
  const handler = (e) => {
1454
1454
  var _a2;
@@ -1573,10 +1573,10 @@ __export(CsvViewer_exports, {
1573
1573
  });
1574
1574
  function CsvViewer({ url, base64, delimiter, maxRows }) {
1575
1575
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
1576
- const [rows, setRows] = React41.useState([]);
1577
- const [loading, setLoading] = React41.useState(true);
1578
- const [error, setError] = React41.useState(null);
1579
- React41.useEffect(() => {
1576
+ const [rows, setRows] = React45.useState([]);
1577
+ const [loading, setLoading] = React45.useState(true);
1578
+ const [error, setError] = React45.useState(null);
1579
+ React45.useEffect(() => {
1580
1580
  let cancelled = false;
1581
1581
  setLoading(true);
1582
1582
  setError(null);
@@ -1695,10 +1695,10 @@ __export(TextViewer_exports, {
1695
1695
  });
1696
1696
  function TextViewer({ url, base64, markdown = false, maxLines }) {
1697
1697
  const { MUTED: MUTED2 } = useTheme();
1698
- const [text, setText] = React41.useState("");
1699
- const [loading, setLoading] = React41.useState(true);
1700
- const [error, setError] = React41.useState(null);
1701
- React41.useEffect(() => {
1698
+ const [text, setText] = React45.useState("");
1699
+ const [loading, setLoading] = React45.useState(true);
1700
+ const [error, setError] = React45.useState(null);
1701
+ React45.useEffect(() => {
1702
1702
  let cancelled = false;
1703
1703
  setLoading(true);
1704
1704
  setError(null);
@@ -1796,10 +1796,10 @@ function sanitize(html) {
1796
1796
  }
1797
1797
  function DocxViewer({ url, base64 }) {
1798
1798
  const { MUTED: MUTED2, BORDER: BORDER4 } = useTheme();
1799
- const [html, setHtml] = React41.useState("");
1800
- const [loading, setLoading] = React41.useState(true);
1801
- const [error, setError] = React41.useState(null);
1802
- React41.useEffect(() => {
1799
+ const [html, setHtml] = React45.useState("");
1800
+ const [loading, setLoading] = React45.useState(true);
1801
+ const [error, setError] = React45.useState(null);
1802
+ React45.useEffect(() => {
1803
1803
  let cancelled = false;
1804
1804
  setLoading(true);
1805
1805
  setError(null);
@@ -5255,7 +5255,32 @@ var workflowStepperSchema = zod.z.object({
5255
5255
  n: zod.z.number().int().positive().optional(),
5256
5256
  title: zod.z.string(),
5257
5257
  sub: zod.z.string().optional(),
5258
- status: zod.z.enum(["done", "active", "review", "pending", "blocked", "failed"]),
5258
+ status: zod.z.enum([
5259
+ "done",
5260
+ "active",
5261
+ "running",
5262
+ "review",
5263
+ "pending",
5264
+ "blocked",
5265
+ "failed"
5266
+ ]),
5267
+ // Optional quality-gate verdict for a step run by an executor (e.g. a
5268
+ // pipeline). Surfaces a subtle trust badge; flags hint at issues a human
5269
+ // should review (the full list lives in the escalation dock).
5270
+ eval: zod.z.object({
5271
+ score: zod.z.number().min(0).max(1).nullable().optional(),
5272
+ verdict: zod.z.enum(["good", "bad"]).optional(),
5273
+ reasoning: zod.z.string().optional(),
5274
+ judge_ok: zod.z.boolean().optional(),
5275
+ data_quality_flags: zod.z.array(
5276
+ zod.z.object({
5277
+ field: zod.z.string().optional(),
5278
+ issue: zod.z.string().optional(),
5279
+ severity: zod.z.enum(["low", "medium", "high"]).optional(),
5280
+ details: zod.z.string().optional()
5281
+ })
5282
+ ).optional()
5283
+ }).optional(),
5259
5284
  assignees: zod.z.array(
5260
5285
  zod.z.object({
5261
5286
  name: zod.z.string(),
@@ -5291,7 +5316,32 @@ var workflowStepperTool = {
5291
5316
  n: { type: "number", description: "Step number; defaults to index + 1" },
5292
5317
  title: { type: "string" },
5293
5318
  sub: { type: "string", description: "Short status caption, e.g. '7 accounts \xB7 2 exceptions'" },
5294
- status: { type: "string", enum: ["done", "active", "review", "pending", "blocked", "failed"] },
5319
+ status: {
5320
+ type: "string",
5321
+ enum: ["done", "active", "running", "review", "pending", "blocked", "failed"]
5322
+ },
5323
+ eval: {
5324
+ type: "object",
5325
+ description: "Optional quality-gate verdict for an executor-run step.",
5326
+ properties: {
5327
+ score: { type: "number" },
5328
+ verdict: { type: "string", enum: ["good", "bad"] },
5329
+ reasoning: { type: "string" },
5330
+ judge_ok: { type: "boolean" },
5331
+ data_quality_flags: {
5332
+ type: "array",
5333
+ items: {
5334
+ type: "object",
5335
+ properties: {
5336
+ field: { type: "string" },
5337
+ issue: { type: "string" },
5338
+ severity: { type: "string", enum: ["low", "medium", "high"] },
5339
+ details: { type: "string" }
5340
+ }
5341
+ }
5342
+ }
5343
+ }
5344
+ },
5295
5345
  assignees: {
5296
5346
  type: "array",
5297
5347
  maxItems: 6,
@@ -5315,6 +5365,183 @@ var workflowStepperTool = {
5315
5365
  required: ["type", "title", "steps"]
5316
5366
  }
5317
5367
  };
5368
+ var bbox = zod.z.tuple([zod.z.number(), zod.z.number(), zod.z.number(), zod.z.number()]);
5369
+ var fieldSchema = zod.z.object({
5370
+ field_key: zod.z.string(),
5371
+ label: zod.z.string(),
5372
+ value: zod.z.string(),
5373
+ page: zod.z.number(),
5374
+ // 0-indexed, matches PageDimension.page
5375
+ bbox: bbox.nullable().optional(),
5376
+ confidence: zod.z.number().optional(),
5377
+ confidence_tier: zod.z.enum(["green", "amber", "red"]).optional(),
5378
+ badge: zod.z.enum(["SC", "CN", "AB", "SW"]).optional(),
5379
+ state: zod.z.enum(["ok", "corrected", "missing", "warn"]).optional(),
5380
+ entity_type: zod.z.string().optional(),
5381
+ is_primary: zod.z.boolean().optional(),
5382
+ // Set after a human correction (extractor output, or an optimistic in-card
5383
+ // edit) so the editable field card can show old → new and who changed it.
5384
+ previous_value: zod.z.string().nullable().optional(),
5385
+ corrected_by: zod.z.string().nullable().optional()
5386
+ });
5387
+ var pageSchema = zod.z.object({
5388
+ page: zod.z.number(),
5389
+ // 0-indexed
5390
+ imageUrl: zod.z.string().optional(),
5391
+ // host-resolved from the durable image_ref
5392
+ width_pt: zod.z.number(),
5393
+ height_pt: zod.z.number()
5394
+ });
5395
+ var summaryStatSchema = zod.z.object({
5396
+ field_key: zod.z.string(),
5397
+ label: zod.z.string(),
5398
+ value: zod.z.string(),
5399
+ caption: zod.z.string().nullable().optional()
5400
+ });
5401
+ var summaryFactSchema = zod.z.object({
5402
+ field_key: zod.z.string(),
5403
+ label: zod.z.string(),
5404
+ value: zod.z.string(),
5405
+ badge: zod.z.string().nullable().optional()
5406
+ });
5407
+ var summarySchema = zod.z.object({
5408
+ display_name: zod.z.string().nullable().optional(),
5409
+ short_name: zod.z.string().nullable().optional(),
5410
+ organization: zod.z.string().nullable().optional(),
5411
+ domain: zod.z.string().nullable().optional(),
5412
+ domain_group: zod.z.string().nullable().optional(),
5413
+ tax_year: zod.z.union([zod.z.string(), zod.z.number()]).nullable().optional(),
5414
+ crumbs: zod.z.array(zod.z.string()).optional(),
5415
+ tags: zod.z.array(zod.z.string()).optional(),
5416
+ stats: zod.z.array(summaryStatSchema).optional(),
5417
+ facts: zod.z.array(summaryFactSchema).optional()
5418
+ });
5419
+ var documentFieldExtractionSchema = zod.z.object({
5420
+ type: zod.z.literal("document-field-extraction"),
5421
+ doc_type: zod.z.string().optional(),
5422
+ // Original uploaded filename (e.g. "2024_gl.pdf"); preferred over doc_type for
5423
+ // the card title since doc_type is often the "generic_fallback" schema name.
5424
+ file_name: zod.z.string().optional(),
5425
+ // Server-side token; resolved by the host into pages/fields before render.
5426
+ payload_ref: zod.z.string().optional(),
5427
+ // Present for persisted workstream docs; absent for pre-existing cards.
5428
+ store_id: zod.z.string().optional(),
5429
+ doc_id: zod.z.string().optional(),
5430
+ pages: zod.z.array(pageSchema).max(100).optional(),
5431
+ fields: zod.z.array(fieldSchema).max(1e3).optional(),
5432
+ // Page-count metadata for the Details tab ("N of M pages extracted").
5433
+ page_count: zod.z.number().optional(),
5434
+ pages_processed: zod.z.number().optional(),
5435
+ // Deterministic document summary for the Details tab.
5436
+ summary: summarySchema.nullable().optional()
5437
+ });
5438
+ var documentFieldExtractionTool = {
5439
+ name: "render_document_field_extraction",
5440
+ description: "Render extracted document fields as an interactive overlay on the page image(s) \u2014 colored bounding boxes per field plus a synced field-card list. Use after the extract_document tool returns; pass the returned payload_ref (the host expands it). For invoices, statements, tax forms, receipts, KYC/loan docs, POs where the user wants to SEE where each value sits on the page.",
5441
+ input_schema: {
5442
+ type: "object",
5443
+ properties: {
5444
+ type: { type: "string", enum: ["document-field-extraction"] },
5445
+ doc_type: { type: "string" },
5446
+ file_name: {
5447
+ type: "string",
5448
+ description: "Original uploaded filename; shown as the card title."
5449
+ },
5450
+ payload_ref: {
5451
+ type: "string",
5452
+ description: "Durable store key returned by extract_document; the GenUI host expands it into pages/fields at render time. Pass this verbatim \u2014 do NOT hand-build pages/fields."
5453
+ },
5454
+ store_id: {
5455
+ type: "string",
5456
+ description: "Docstore store id; present for persisted workstream docs. The host uses this to open the editable viewer."
5457
+ },
5458
+ doc_id: {
5459
+ type: "string",
5460
+ description: "Docstore document id; present for persisted workstream docs. Required for the editable viewer."
5461
+ },
5462
+ pages: {
5463
+ type: "array",
5464
+ items: {
5465
+ type: "object",
5466
+ properties: {
5467
+ page: { type: "number", description: "0-indexed page number" },
5468
+ imageUrl: { type: "string" },
5469
+ width_pt: { type: "number" },
5470
+ height_pt: { type: "number" }
5471
+ },
5472
+ required: ["page", "width_pt", "height_pt"]
5473
+ }
5474
+ },
5475
+ fields: {
5476
+ type: "array",
5477
+ items: {
5478
+ type: "object",
5479
+ properties: {
5480
+ field_key: { type: "string" },
5481
+ label: { type: "string" },
5482
+ value: { type: "string" },
5483
+ page: { type: "number", description: "0-indexed page number" },
5484
+ bbox: {
5485
+ type: "array",
5486
+ items: { type: "number" },
5487
+ description: "[x0,y0,x1,y1] PDF points, origin bottom-left; null if unlocated"
5488
+ },
5489
+ confidence: { type: "number" },
5490
+ confidence_tier: { type: "string", enum: ["green", "amber", "red"] },
5491
+ badge: { type: "string", enum: ["SC", "CN", "AB", "SW"] },
5492
+ state: { type: "string", enum: ["ok", "corrected", "missing", "warn"] },
5493
+ entity_type: { type: "string" },
5494
+ is_primary: { type: "boolean" }
5495
+ },
5496
+ required: ["field_key", "label", "value", "page"]
5497
+ }
5498
+ },
5499
+ page_count: { type: "number" },
5500
+ pages_processed: { type: "number" },
5501
+ summary: {
5502
+ type: "object",
5503
+ description: "Deterministic document summary for the Details tab (display_name, organization, domain, stats, facts, tags). Produced by the extractor \u2014 pass through verbatim.",
5504
+ properties: {
5505
+ display_name: { type: "string" },
5506
+ short_name: { type: "string" },
5507
+ organization: { type: "string" },
5508
+ domain: { type: "string" },
5509
+ domain_group: { type: "string" },
5510
+ tax_year: { type: "string" },
5511
+ crumbs: { type: "array", items: { type: "string" } },
5512
+ tags: { type: "array", items: { type: "string" } },
5513
+ stats: {
5514
+ type: "array",
5515
+ items: {
5516
+ type: "object",
5517
+ properties: {
5518
+ field_key: { type: "string" },
5519
+ label: { type: "string" },
5520
+ value: { type: "string" },
5521
+ caption: { type: "string" }
5522
+ },
5523
+ required: ["field_key", "label", "value"]
5524
+ }
5525
+ },
5526
+ facts: {
5527
+ type: "array",
5528
+ items: {
5529
+ type: "object",
5530
+ properties: {
5531
+ field_key: { type: "string" },
5532
+ label: { type: "string" },
5533
+ value: { type: "string" },
5534
+ badge: { type: "string" }
5535
+ },
5536
+ required: ["field_key", "label", "value"]
5537
+ }
5538
+ }
5539
+ }
5540
+ }
5541
+ },
5542
+ required: ["type"]
5543
+ }
5544
+ };
5318
5545
  var decisionCardSchema = zod.z.object({
5319
5546
  type: zod.z.literal("decision-card"),
5320
5547
  id: zod.z.string().optional(),
@@ -5418,6 +5645,36 @@ var decisionCardTool = {
5418
5645
  required: ["type", "title", "question", "options"]
5419
5646
  }
5420
5647
  };
5648
+ var tabbyAuthSchema = zod.z.object({
5649
+ type: zod.z.literal("tabby-auth"),
5650
+ app: zod.z.string(),
5651
+ url: zod.z.string(),
5652
+ workspace: zod.z.string().optional(),
5653
+ state: zod.z.enum(["pending", "connected"]).optional(),
5654
+ ctaLabel: zod.z.string().optional(),
5655
+ steps: zod.z.array(zod.z.string()).optional(),
5656
+ description: zod.z.string().optional(),
5657
+ iconUrl: zod.z.string().optional()
5658
+ });
5659
+ var tabbyAuthTool = {
5660
+ name: "render_tabby_auth",
5661
+ description: "Render a dedicated, trustworthy sign-in card when a harness skill needs the member to authenticate with a third-party app (e.g. Sage Intacct, Airbnb, an ERP) before a `call_web_api` request can proceed. Use this for the `login_required` path instead of a raw markdown link or a connect-integration card. `app` is the human display name (drives the title context, subtitle, and CTA). `url` is the login/short-link the prominent CTA opens in a new tab. `workspace` adds a subtitle suffix ('{app} \xB7 {workspace} workspace'). `state='pending'` (default) is the first-time connect; `state='connected'` is the verify/re-auth case (session already live) with a green badge and an Open deep-link. `steps` overrides the default numbered instructions; `description` is a one-line intro. The card title ('Authentication required') and the 'Credentials not stored by Adopt' trust footer are hardcoded brand constants \u2014 never supplied here.",
5662
+ input_schema: {
5663
+ type: "object",
5664
+ properties: {
5665
+ type: { type: "string", enum: ["tabby-auth"] },
5666
+ app: { type: "string" },
5667
+ url: { type: "string" },
5668
+ workspace: { type: "string" },
5669
+ state: { type: "string", enum: ["pending", "connected"] },
5670
+ ctaLabel: { type: "string" },
5671
+ steps: { type: "array", items: { type: "string" } },
5672
+ description: { type: "string" },
5673
+ iconUrl: { type: "string" }
5674
+ },
5675
+ required: ["type", "app", "url"]
5676
+ }
5677
+ };
5421
5678
 
5422
5679
  // src/schemas/buildRenderUITool.ts
5423
5680
  function buildRenderUITool(selectedSchemas) {
@@ -5537,7 +5794,9 @@ var schemaRegistry = {
5537
5794
  "integrations-list": { schema: integrationsListSchema, tool: integrationsListTool },
5538
5795
  "pipeline-preview": { schema: pipelinePreviewSchema, tool: pipelinePreviewTool },
5539
5796
  "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5540
- "decision-card": { schema: decisionCardSchema, tool: decisionCardTool }
5797
+ "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5798
+ "decision-card": { schema: decisionCardSchema, tool: decisionCardTool },
5799
+ "tabby-auth": { schema: tabbyAuthSchema, tool: tabbyAuthTool }
5541
5800
  };
5542
5801
 
5543
5802
  // src/shared/ColumnSettingsPanel.tsx
@@ -5589,16 +5848,16 @@ init_theme();
5589
5848
  var DOT_COLOR = "#aaaaaa";
5590
5849
  var DOT_HOVER = "#555555";
5591
5850
  function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "component" }) {
5592
- const [open, setOpen] = React41.useState(false);
5593
- const [view, setView] = React41.useState("main");
5594
- const contentRef = React41.useRef(null);
5595
- const menuRef = React41.useRef(null);
5596
- const btnRef = React41.useRef(null);
5597
- const close = React41.useCallback(() => {
5851
+ const [open, setOpen] = React45.useState(false);
5852
+ const [view, setView] = React45.useState("main");
5853
+ const contentRef = React45.useRef(null);
5854
+ const menuRef = React45.useRef(null);
5855
+ const btnRef = React45.useRef(null);
5856
+ const close = React45.useCallback(() => {
5598
5857
  setOpen(false);
5599
5858
  setView("main");
5600
5859
  }, []);
5601
- React41.useEffect(() => {
5860
+ React45.useEffect(() => {
5602
5861
  if (!open) return;
5603
5862
  const handler = (e) => {
5604
5863
  var _a2, _b;
@@ -5609,7 +5868,7 @@ function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "c
5609
5868
  document.addEventListener("mousedown", handler);
5610
5869
  return () => document.removeEventListener("mousedown", handler);
5611
5870
  }, [open, close]);
5612
- const handleDownloadPNG = React41.useCallback(async () => {
5871
+ const handleDownloadPNG = React45.useCallback(async () => {
5613
5872
  if (!contentRef.current) return;
5614
5873
  try {
5615
5874
  const url = await htmlToImage.toPng(contentRef.current, { backgroundColor: "white", pixelRatio: 2 });
@@ -5621,7 +5880,7 @@ function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "c
5621
5880
  }
5622
5881
  close();
5623
5882
  }, [filename, close]);
5624
- const handleCSV = React41.useCallback(() => {
5883
+ const handleCSV = React45.useCallback(() => {
5625
5884
  onDownloadCSV == null ? void 0 : onDownloadCSV();
5626
5885
  close();
5627
5886
  }, [onDownloadCSV, close]);
@@ -5733,12 +5992,12 @@ function MenuButton({ label, onClick }) {
5733
5992
  );
5734
5993
  }
5735
5994
  function useColumnVisibility(columns) {
5736
- const [hidden, setHidden] = React41.useState(/* @__PURE__ */ new Set());
5737
- const visibleColumns = React41.useMemo(
5995
+ const [hidden, setHidden] = React45.useState(/* @__PURE__ */ new Set());
5996
+ const visibleColumns = React45.useMemo(
5738
5997
  () => columns.filter((c) => !hidden.has(c.key)),
5739
5998
  [columns, hidden]
5740
5999
  );
5741
- const toggle = React41.useCallback((key) => {
6000
+ const toggle = React45.useCallback((key) => {
5742
6001
  setHidden((prev) => {
5743
6002
  const next = new Set(prev);
5744
6003
  if (next.has(key)) next.delete(key);
@@ -5746,8 +6005,8 @@ function useColumnVisibility(columns) {
5746
6005
  return next;
5747
6006
  });
5748
6007
  }, []);
5749
- const showAll = React41.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
5750
- const hideAll = React41.useCallback(
6008
+ const showAll = React45.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
6009
+ const hideAll = React45.useCallback(
5751
6010
  () => setHidden(new Set(columns.map((c) => c.key))),
5752
6011
  [columns]
5753
6012
  );
@@ -5998,9 +6257,9 @@ function AlertResolver(p) {
5998
6257
  // src/composites/stat-grid/resolver.tsx
5999
6258
  init_Markdown();
6000
6259
  function FitText({ children, max = 22, min = 13, title, className, style }) {
6001
- const ref = React41.useRef(null);
6002
- const [size, setSize] = React41.useState(max);
6003
- React41.useLayoutEffect(() => {
6260
+ const ref = React45.useRef(null);
6261
+ const [size, setSize] = React45.useState(max);
6262
+ React45.useLayoutEffect(() => {
6004
6263
  const el = ref.current;
6005
6264
  if (!el) return void 0;
6006
6265
  const fit = () => {
@@ -6092,7 +6351,7 @@ init_ThemeContext();
6092
6351
  function TabsPanelResolver(p) {
6093
6352
  var _a2;
6094
6353
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
6095
- const [activeIdx, setActiveIdx] = React41.useState(0);
6354
+ const [activeIdx, setActiveIdx] = React45.useState(0);
6096
6355
  const activeTab = p.tabs[activeIdx];
6097
6356
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: "tabs-panel", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "0" }, children: [
6098
6357
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6250,17 +6509,17 @@ function SparklineTableResolver(p) {
6250
6509
  // src/composites/heatmap-table/resolver.tsx
6251
6510
  init_theme();
6252
6511
  init_ThemeContext();
6253
- function heatColor(z60) {
6254
- const clamped = Math.max(-3, Math.min(3, z60));
6512
+ function heatColor(z62) {
6513
+ const clamped = Math.max(-3, Math.min(3, z62));
6255
6514
  const abs = Math.abs(clamped);
6256
6515
  const lightness = 95 - abs * 8;
6257
6516
  const hue = clamped >= 0 ? 142 : 0;
6258
6517
  return `hsl(${hue} 60% ${lightness}%)`;
6259
6518
  }
6260
- function heatTextColor(z60) {
6261
- const abs = Math.abs(z60);
6262
- if (abs > 2) return z60 >= 0 ? "#14532d" : "#7f1d1d";
6263
- if (abs > 1) return z60 >= 0 ? "#166534" : "#991b1b";
6519
+ function heatTextColor(z62) {
6520
+ const abs = Math.abs(z62);
6521
+ if (abs > 2) return z62 >= 0 ? "#14532d" : "#7f1d1d";
6522
+ if (abs > 1) return z62 >= 0 ? "#166534" : "#991b1b";
6264
6523
  return "var(--foreground)";
6265
6524
  }
6266
6525
  var th2 = {
@@ -6358,7 +6617,7 @@ var thStyle2 = {
6358
6617
  function ScreenerTableResolver(p) {
6359
6618
  var _a2, _b, _c, _d, _e, _f;
6360
6619
  const { ACCENT: ACCENT2, BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
6361
- const [activeFilters, setActiveFilters] = React41.useState(new Set((_a2 = p.activeFilters) != null ? _a2 : []));
6620
+ const [activeFilters, setActiveFilters] = React45.useState(new Set((_a2 = p.activeFilters) != null ? _a2 : []));
6362
6621
  const { visibleColumns, hidden, toggle, showAll, hideAll, allColumns } = useColumnVisibility((_b = p.columns) != null ? _b : []);
6363
6622
  const toggleFilter = (f) => setActiveFilters((prev) => {
6364
6623
  const next = new Set(prev);
@@ -6428,7 +6687,7 @@ var th3 = {
6428
6687
  };
6429
6688
  function GroupRows({ group, columns, depth }) {
6430
6689
  var _a2, _b;
6431
- const [open, setOpen] = React41.useState(true);
6690
+ const [open, setOpen] = React45.useState(true);
6432
6691
  const indent = depth * 14;
6433
6692
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6434
6693
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6533,7 +6792,7 @@ var dotColor = {
6533
6792
  function NewsFeedResolver(p) {
6534
6793
  var _a2, _b;
6535
6794
  const { ACCENT: ACCENT2, MUTED: MUTED2 } = useTheme();
6536
- const [filter, setFilter] = React41.useState(null);
6795
+ const [filter, setFilter] = React45.useState(null);
6537
6796
  const sentiments = ["positive", "neutral", "negative"].filter(
6538
6797
  (s) => {
6539
6798
  var _a3;
@@ -6575,9 +6834,9 @@ function NewsFeedResolver(p) {
6575
6834
  ] }) });
6576
6835
  }
6577
6836
  function useSeriesToggle(seriesKeys) {
6578
- const [hidden, setHidden] = React41.useState(/* @__PURE__ */ new Set());
6579
- const isVisible = React41.useCallback((key) => !hidden.has(key), [hidden]);
6580
- const toggle = React41.useCallback((key) => {
6837
+ const [hidden, setHidden] = React45.useState(/* @__PURE__ */ new Set());
6838
+ const isVisible = React45.useCallback((key) => !hidden.has(key), [hidden]);
6839
+ const toggle = React45.useCallback((key) => {
6581
6840
  setHidden((prev) => {
6582
6841
  const next = new Set(prev);
6583
6842
  if (next.has(key)) next.delete(key);
@@ -6585,7 +6844,7 @@ function useSeriesToggle(seriesKeys) {
6585
6844
  return next;
6586
6845
  });
6587
6846
  }, []);
6588
- const showAll = React41.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
6847
+ const showAll = React45.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
6589
6848
  return { hidden, isVisible, toggle, showAll, allKeys: seriesKeys };
6590
6849
  }
6591
6850
 
@@ -6894,7 +7153,7 @@ function WaterfallChartResolver(p) {
6894
7153
  ] }) });
6895
7154
  }
6896
7155
  init_ThemeContext();
6897
- var FlowGraph2 = React41__default.default.lazy(
7156
+ var FlowGraph2 = React45__default.default.lazy(
6898
7157
  () => Promise.resolve().then(() => (init_FlowGraph(), FlowGraph_exports)).then((m) => ({ default: m.FlowGraph }))
6899
7158
  );
6900
7159
  function FlowCanvasRenderer({
@@ -6935,7 +7194,7 @@ function FlowCanvasRenderer({
6935
7194
  overflow: "hidden",
6936
7195
  background: "#ffffff",
6937
7196
  position: "relative"
6938
- }, diagram ? {} : { height: "320px" }), children: diagram ? /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(FlowGraph2, { diagram, title, autoplay, nodeStates }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
7197
+ }, diagram ? {} : { height: "320px" }), children: diagram ? /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(FlowGraph2, { diagram, title, autoplay, nodeStates }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
6939
7198
  position: "absolute",
6940
7199
  inset: 0,
6941
7200
  display: "flex",
@@ -7168,7 +7427,7 @@ function TrialBalanceResolver(p) {
7168
7427
  gDebit += a.debit;
7169
7428
  gCredit += a.credit;
7170
7429
  });
7171
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
7430
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
7172
7431
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: 4, style: {
7173
7432
  padding: "8px 12px",
7174
7433
  fontSize: "12px",
@@ -7705,7 +7964,7 @@ function ItemRow({ item }) {
7705
7964
  ] });
7706
7965
  }
7707
7966
  function Section({ section }) {
7708
- const [open, setOpen] = React41.useState(true);
7967
+ const [open, setOpen] = React45.useState(true);
7709
7968
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7710
7969
  /* @__PURE__ */ jsxRuntime.jsxs(
7711
7970
  "button",
@@ -7827,7 +8086,7 @@ function ReconciliationViewResolver(p) {
7827
8086
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
7828
8087
  const sourceA = (_a2 = p.sourceA) != null ? _a2 : { label: "Source A" };
7829
8088
  const sourceB = (_b = p.sourceB) != null ? _b : { label: "Source B" };
7830
- const [activeTab, setActiveTab] = React41.useState("matched");
8089
+ const [activeTab, setActiveTab] = React45.useState("matched");
7831
8090
  const balanceA = (_d = (_c = p.summary) == null ? void 0 : _c.balanceA) != null ? _d : 0;
7832
8091
  const balanceB = (_f = (_e = p.summary) == null ? void 0 : _e.balanceB) != null ? _f : 0;
7833
8092
  const difference = (_h = (_g = p.summary) == null ? void 0 : _g.difference) != null ? _h : balanceA - balanceB;
@@ -8470,7 +8729,7 @@ function ChangesView({ changes }) {
8470
8729
  }
8471
8730
  function EventCard({ event }) {
8472
8731
  var _a2;
8473
- const [showChanges, setShowChanges] = React41.useState(false);
8732
+ const [showChanges, setShowChanges] = React45.useState(false);
8474
8733
  const ac = (_a2 = actionConfig[event.action]) != null ? _a2 : actionConfig.commented;
8475
8734
  const hasChanges = event.changes && event.changes.length > 0;
8476
8735
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "12px", position: "relative" }, children: [
@@ -8528,23 +8787,23 @@ function AuditTrailResolver(p) {
8528
8787
  }
8529
8788
  init_Markdown();
8530
8789
  function useFullscreen(ref) {
8531
- const [isFullscreen, setIsFullscreen] = React41.useState(false);
8532
- React41.useEffect(() => {
8790
+ const [isFullscreen, setIsFullscreen] = React45.useState(false);
8791
+ React45.useEffect(() => {
8533
8792
  const handler = () => {
8534
8793
  setIsFullscreen(!!document.fullscreenElement);
8535
8794
  };
8536
8795
  document.addEventListener("fullscreenchange", handler);
8537
8796
  return () => document.removeEventListener("fullscreenchange", handler);
8538
8797
  }, []);
8539
- const enter = React41.useCallback(() => {
8798
+ const enter = React45.useCallback(() => {
8540
8799
  var _a2, _b;
8541
8800
  (_b = (_a2 = ref.current) == null ? void 0 : _a2.requestFullscreen) == null ? void 0 : _b.call(_a2);
8542
8801
  }, [ref]);
8543
- const exit = React41.useCallback(() => {
8802
+ const exit = React45.useCallback(() => {
8544
8803
  var _a2;
8545
8804
  if (document.fullscreenElement) (_a2 = document.exitFullscreen) == null ? void 0 : _a2.call(document);
8546
8805
  }, []);
8547
- const toggle = React41.useCallback(() => {
8806
+ const toggle = React45.useCallback(() => {
8548
8807
  if (isFullscreen) exit();
8549
8808
  else enter();
8550
8809
  }, [isFullscreen, enter, exit]);
@@ -8554,10 +8813,10 @@ function useFullscreen(ref) {
8554
8813
  // src/composites/document-preview/resolver.tsx
8555
8814
  init_theme();
8556
8815
  init_ThemeContext();
8557
- var PdfViewer2 = React41__default.default.lazy(
8816
+ var PdfViewer2 = React45__default.default.lazy(
8558
8817
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
8559
8818
  );
8560
- var ExcelViewer2 = React41__default.default.lazy(
8819
+ var ExcelViewer2 = React45__default.default.lazy(
8561
8820
  () => Promise.resolve().then(() => (init_ExcelViewer(), ExcelViewer_exports)).then((m) => ({ default: m.ExcelViewer }))
8562
8821
  );
8563
8822
  var highlightColors = {
@@ -8607,8 +8866,8 @@ function DownloadIcon() {
8607
8866
  function DocumentPreviewResolver(p) {
8608
8867
  var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
8609
8868
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
8610
- const [currentPage, setCurrentPage] = React41.useState(0);
8611
- const containerRef = React41.useRef(null);
8869
+ const [currentPage, setCurrentPage] = React45.useState(0);
8870
+ const containerRef = React45.useRef(null);
8612
8871
  const { isFullscreen, toggle } = useFullscreen(containerRef);
8613
8872
  const hasRealFile = !!(((_a2 = p.source) == null ? void 0 : _a2.url) || ((_b = p.source) == null ? void 0 : _b.base64));
8614
8873
  const isPdf = p.documentType === "pdf";
@@ -8616,9 +8875,9 @@ function DocumentPreviewResolver(p) {
8616
8875
  const totalPages = ((_c = p.pages) != null ? _c : []).length;
8617
8876
  const page = p.pages[currentPage];
8618
8877
  const pageHighlights = ((_d = p.highlights) != null ? _d : []).filter((h) => h.pageIndex === currentPage);
8619
- const handlePdfLoad = React41.useCallback(() => {
8878
+ const handlePdfLoad = React45.useCallback(() => {
8620
8879
  }, []);
8621
- const handleExcelLoad = React41.useCallback(() => {
8880
+ const handleExcelLoad = React45.useCallback(() => {
8622
8881
  }, []);
8623
8882
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_e = p.title) != null ? _e : "document-preview", children: /* @__PURE__ */ jsxRuntime.jsxs(
8624
8883
  "div",
@@ -8731,7 +8990,7 @@ function DocumentPreviewResolver(p) {
8731
8990
  display: "flex",
8732
8991
  flexDirection: "column"
8733
8992
  }, children: [
8734
- hasRealFile && isPdf ? /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: (_q = p.source) == null ? void 0 : _q.url, base64: (_r = p.source) == null ? void 0 : _r.base64, onLoadSuccess: handlePdfLoad }) }) : hasRealFile && isExcel ? /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ExcelViewer2, { url: (_s = p.source) == null ? void 0 : _s.url, base64: (_t = p.source) == null ? void 0 : _t.base64, onLoadSuccess: handleExcelLoad }) }) : (page == null ? void 0 : page.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: page.imageUrl, alt: page.label, style: { maxWidth: "100%", borderRadius: "4px" } }) }) : (page == null ? void 0 : page.content) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontFamily: "var(--font-sans, system-ui)", fontSize: "13px", color: "var(--foreground)", lineHeight: 1.6, margin: 0, padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content: page.content }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "120px", color: MUTED2, fontSize: "13px" }, children: [
8993
+ hasRealFile && isPdf ? /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: (_q = p.source) == null ? void 0 : _q.url, base64: (_r = p.source) == null ? void 0 : _r.base64, onLoadSuccess: handlePdfLoad }) }) : hasRealFile && isExcel ? /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ExcelViewer2, { url: (_s = p.source) == null ? void 0 : _s.url, base64: (_t = p.source) == null ? void 0 : _t.base64, onLoadSuccess: handleExcelLoad }) }) : (page == null ? void 0 : page.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: page.imageUrl, alt: page.label, style: { maxWidth: "100%", borderRadius: "4px" } }) }) : (page == null ? void 0 : page.content) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontFamily: "var(--font-sans, system-ui)", fontSize: "13px", color: "var(--foreground)", lineHeight: 1.6, margin: 0, padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content: page.content }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "120px", color: MUTED2, fontSize: "13px" }, children: [
8735
8994
  "No content available for ",
8736
8995
  (_u = page == null ? void 0 : page.label) != null ? _u : "this page"
8737
8996
  ] }),
@@ -8794,7 +9053,7 @@ function ConfidenceBar({ confidence, height = 6 }) {
8794
9053
  }
8795
9054
  function StepCard({ step, isLast }) {
8796
9055
  var _a2;
8797
- const [expanded, setExpanded] = React41.useState(false);
9056
+ const [expanded, setExpanded] = React45.useState(false);
8798
9057
  const cfg = stepTypeConfig[step.stepType];
8799
9058
  const detail = (_a2 = step.detail) != null ? _a2 : "";
8800
9059
  const isLong = detail.length > 100;
@@ -9299,7 +9558,7 @@ function ExampleRow({ example }) {
9299
9558
  );
9300
9559
  }
9301
9560
  function PartSection({ part, defaultOpen }) {
9302
- const [open, setOpen] = React41.useState(defaultOpen);
9561
+ const [open, setOpen] = React45.useState(defaultOpen);
9303
9562
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9304
9563
  /* @__PURE__ */ jsxRuntime.jsxs(
9305
9564
  "button",
@@ -9429,7 +9688,7 @@ function EngagementPipelineResolver(p) {
9429
9688
  const defaultActive = phases.findIndex(
9430
9689
  (ph) => ph.status === "in-progress" || ph.status === "blocked"
9431
9690
  );
9432
- const [activeIdx, setActiveIdx] = React41.useState(defaultActive >= 0 ? defaultActive : 0);
9691
+ const [activeIdx, setActiveIdx] = React45.useState(defaultActive >= 0 ? defaultActive : 0);
9433
9692
  const activePhase = phases[activeIdx];
9434
9693
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_b = p.title) != null ? _b : "engagement-pipeline", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "12px" }, children: [
9435
9694
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
@@ -9513,7 +9772,7 @@ function EngagementPipelineResolver(p) {
9513
9772
  const color = (_a3 = statusColor2[phase.status]) != null ? _a3 : "#d6d3d1";
9514
9773
  const isCurrent = i === activeIdx;
9515
9774
  const size = isCurrent ? 28 : 20;
9516
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
9775
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
9517
9776
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
9518
9777
  "div",
9519
9778
  {
@@ -9820,7 +10079,7 @@ function Avatar({ name, avatar, hovered }) {
9820
10079
  function EntityCardGridResolver(p) {
9821
10080
  var _a2, _b;
9822
10081
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
9823
- const [hoveredId, setHoveredId] = React41.useState(null);
10082
+ const [hoveredId, setHoveredId] = React45.useState(null);
9824
10083
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_a2 = p.title) != null ? _a2 : "entity-card-grid", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "10px" }, children: [
9825
10084
  p.title && /* @__PURE__ */ jsxRuntime.jsx(
9826
10085
  "p",
@@ -10076,7 +10335,7 @@ function StepRow({ step }) {
10076
10335
  function JobTrackerResolver(p) {
10077
10336
  var _a2, _b, _c, _d, _e, _f, _g;
10078
10337
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, PAPER: PAPER2 } = useTheme();
10079
- const [stepsOpen, setStepsOpen] = React41.useState(true);
10338
+ const [stepsOpen, setStepsOpen] = React45.useState(true);
10080
10339
  const barColor = (_a2 = statusColors2[p.status]) != null ? _a2 : MUTED2;
10081
10340
  const badge = (_b = statusBadgeConfig[p.status]) != null ? _b : statusBadgeConfig.queued;
10082
10341
  const progress = (_c = p.progress) != null ? _c : p.status === "completed" ? 100 : 0;
@@ -10516,7 +10775,7 @@ function CitationCard({
10516
10775
  );
10517
10776
  }
10518
10777
  function FollowUpItem({ text }) {
10519
- const [hovered, setHovered] = React41.useState(false);
10778
+ const [hovered, setHovered] = React45.useState(false);
10520
10779
  return /* @__PURE__ */ jsxRuntime.jsxs(
10521
10780
  "span",
10522
10781
  {
@@ -10541,7 +10800,7 @@ function CitationMarker({
10541
10800
  index,
10542
10801
  onClick
10543
10802
  }) {
10544
- const [hovered, setHovered] = React41.useState(false);
10803
+ const [hovered, setHovered] = React45.useState(false);
10545
10804
  return /* @__PURE__ */ jsxRuntime.jsx(
10546
10805
  "sup",
10547
10806
  {
@@ -10570,7 +10829,7 @@ function CitationMarker({
10570
10829
  function CitedAnswerResolver(p) {
10571
10830
  var _a2, _b, _c, _d, _e;
10572
10831
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, SECONDARY: SECONDARY2 } = useTheme();
10573
- const [expandedIds, setExpandedIds] = React41.useState(/* @__PURE__ */ new Set());
10832
+ const [expandedIds, setExpandedIds] = React45.useState(/* @__PURE__ */ new Set());
10574
10833
  const toggleCitation = (id) => {
10575
10834
  setExpandedIds((prev) => {
10576
10835
  const next = new Set(prev);
@@ -10874,7 +11133,7 @@ function TransactionFeedResolver(p) {
10874
11133
  var _a2, _b, _c, _d, _e;
10875
11134
  const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
10876
11135
  const currency = (_a2 = p.currency) != null ? _a2 : "USD";
10877
- const [hoveredIndex, setHoveredIndex] = React41.useState(null);
11136
+ const [hoveredIndex, setHoveredIndex] = React45.useState(null);
10878
11137
  const hasBalance = ((_b = p.transactions) != null ? _b : []).some((tx) => tx.balance != null);
10879
11138
  const totalInflows = p.transactions.filter((tx) => tx.amount > 0 && tx.status !== "reversed").reduce((sum, tx) => sum + tx.amount, 0);
10880
11139
  const totalOutflows = p.transactions.filter((tx) => tx.amount < 0 && tx.status !== "reversed").reduce((sum, tx) => sum + tx.amount, 0);
@@ -11031,7 +11290,7 @@ function formatDate2(dateStr) {
11031
11290
  }
11032
11291
  function FileRow({ item }) {
11033
11292
  var _a2;
11034
- const [hovered, setHovered] = React41.useState(false);
11293
+ const [hovered, setHovered] = React45.useState(false);
11035
11294
  const cfg = getDocConfig(item.docType);
11036
11295
  return /* @__PURE__ */ jsxRuntime.jsxs(
11037
11296
  "div",
@@ -11107,8 +11366,8 @@ function FileRow({ item }) {
11107
11366
  );
11108
11367
  }
11109
11368
  function GroupSection({ groupName, items }) {
11110
- const [open, setOpen] = React41.useState(true);
11111
- const [headerHovered, setHeaderHovered] = React41.useState(false);
11369
+ const [open, setOpen] = React45.useState(true);
11370
+ const [headerHovered, setHeaderHovered] = React45.useState(false);
11112
11371
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11113
11372
  /* @__PURE__ */ jsxRuntime.jsxs(
11114
11373
  "button",
@@ -11297,15 +11556,15 @@ function isExpirySoon(expiresAt) {
11297
11556
 
11298
11557
  // src/shared/viewers/PreviewHost.tsx
11299
11558
  init_ThemeContext();
11300
- var PdfViewer3 = React41.lazy(
11559
+ var PdfViewer3 = React45.lazy(
11301
11560
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
11302
11561
  );
11303
- var ExcelViewer3 = React41.lazy(
11562
+ var ExcelViewer3 = React45.lazy(
11304
11563
  () => Promise.resolve().then(() => (init_ExcelViewer(), ExcelViewer_exports)).then((m) => ({ default: m.ExcelViewer }))
11305
11564
  );
11306
- var CsvViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_CsvViewer(), CsvViewer_exports)).then((m) => ({ default: m.CsvViewer })));
11307
- var TextViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_TextViewer(), TextViewer_exports)).then((m) => ({ default: m.TextViewer })));
11308
- var DocxViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
11565
+ var CsvViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_CsvViewer(), CsvViewer_exports)).then((m) => ({ default: m.CsvViewer })));
11566
+ var TextViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_TextViewer(), TextViewer_exports)).then((m) => ({ default: m.TextViewer })));
11567
+ var DocxViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
11309
11568
  var PEEK_ROWS = 20;
11310
11569
  var PEEK_LINES = 40;
11311
11570
  function PreviewHost({ kind, source, mode = "full" }) {
@@ -11335,7 +11594,7 @@ function PreviewHost({ kind, source, mode = "full" }) {
11335
11594
  default:
11336
11595
  return null;
11337
11596
  }
11338
- return /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback, children: viewer });
11597
+ return /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback, children: viewer });
11339
11598
  }
11340
11599
 
11341
11600
  // src/shared/PreviewModal.tsx
@@ -11351,7 +11610,7 @@ function PreviewModal({
11351
11610
  onDownload
11352
11611
  }) {
11353
11612
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
11354
- React41.useEffect(() => {
11613
+ React45.useEffect(() => {
11355
11614
  if (!open) return;
11356
11615
  const onKey = (e) => {
11357
11616
  if (e.key === "Escape") onClose();
@@ -11524,17 +11783,17 @@ function FileCard({
11524
11783
  previewDisabled = false
11525
11784
  }) {
11526
11785
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
11527
- const [cardHover, setCardHover] = React41.useState(false);
11528
- const [btnHover, setBtnHover] = React41.useState(false);
11529
- const [pvHover, setPvHover] = React41.useState(false);
11786
+ const [cardHover, setCardHover] = React45.useState(false);
11787
+ const [btnHover, setBtnHover] = React45.useState(false);
11788
+ const [pvHover, setPvHover] = React45.useState(false);
11530
11789
  const previewKind = previewKindFor(fileType, filename);
11531
11790
  const canPreview = !previewDisabled && previewKind !== null && (!!previewUrl || !!fetchPreviewBlob);
11532
- const [peekOpen, setPeekOpen] = React41.useState(false);
11533
- const [modalOpen, setModalOpen] = React41.useState(false);
11534
- const [source, setSource] = React41.useState(previewUrl ? { url: previewUrl } : null);
11535
- const [pvLoading, setPvLoading] = React41.useState(false);
11536
- const [pvError, setPvError] = React41.useState(null);
11537
- const ensureSource = React41.useCallback(async () => {
11791
+ const [peekOpen, setPeekOpen] = React45.useState(false);
11792
+ const [modalOpen, setModalOpen] = React45.useState(false);
11793
+ const [source, setSource] = React45.useState(previewUrl ? { url: previewUrl } : null);
11794
+ const [pvLoading, setPvLoading] = React45.useState(false);
11795
+ const [pvError, setPvError] = React45.useState(null);
11796
+ const ensureSource = React45.useCallback(async () => {
11538
11797
  if (source) return source;
11539
11798
  if (previewUrl) {
11540
11799
  const s = { url: previewUrl };
@@ -11556,7 +11815,7 @@ function FileCard({
11556
11815
  setPvLoading(false);
11557
11816
  }
11558
11817
  }, [source, previewUrl, fetchPreviewBlob]);
11559
- const togglePeek = React41.useCallback(async () => {
11818
+ const togglePeek = React45.useCallback(async () => {
11560
11819
  if (peekOpen) {
11561
11820
  setPeekOpen(false);
11562
11821
  return;
@@ -11564,7 +11823,7 @@ function FileCard({
11564
11823
  setPeekOpen(true);
11565
11824
  await ensureSource();
11566
11825
  }, [peekOpen, ensureSource]);
11567
- const openModal = React41.useCallback(async () => {
11826
+ const openModal = React45.useCallback(async () => {
11568
11827
  const s = await ensureSource();
11569
11828
  if (s) setModalOpen(true);
11570
11829
  }, [ensureSource]);
@@ -11679,7 +11938,7 @@ function FileCard({
11679
11938
  whiteSpace: "nowrap"
11680
11939
  },
11681
11940
  children: [
11682
- metaTokens.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
11941
+ metaTokens.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
11683
11942
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#c4c4c4" }, children: "\xB7" }),
11684
11943
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: t })
11685
11944
  ] }, i)),
@@ -12023,7 +12282,7 @@ function ServiceCard({ item, isHovered, onHover, onLeave: onLeave2 }) {
12023
12282
  function OpsDashboardResolver(p) {
12024
12283
  var _a2, _b, _c;
12025
12284
  const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
12026
- const [hoveredId, setHoveredId] = React41.useState(null);
12285
+ const [hoveredId, setHoveredId] = React45.useState(null);
12027
12286
  const hasRunning = ((_a2 = p.items) != null ? _a2 : []).some((item) => item.state === "running");
12028
12287
  return /* @__PURE__ */ jsxRuntime.jsxs(ComponentActions, { filename: (_b = p.title) != null ? _b : "ops-dashboard", children: [
12029
12288
  hasRunning && /* @__PURE__ */ jsxRuntime.jsx("style", { children: PULSE_KEYFRAMES }),
@@ -12076,8 +12335,8 @@ function formatDate3(value) {
12076
12335
  }
12077
12336
  }
12078
12337
  function CopyButton({ value, rowHovered }) {
12079
- const [copied, setCopied] = React41.useState(false);
12080
- const [btnHovered, setBtnHovered] = React41.useState(false);
12338
+ const [copied, setCopied] = React45.useState(false);
12339
+ const [btnHovered, setBtnHovered] = React45.useState(false);
12081
12340
  const handleCopy = () => {
12082
12341
  navigator.clipboard.writeText(value).then(() => {
12083
12342
  setCopied(true);
@@ -12169,7 +12428,7 @@ function ValueCell({ item }) {
12169
12428
  }
12170
12429
  }
12171
12430
  function KVRow({ item, isLast, index }) {
12172
- const [hovered, setHovered] = React41.useState(false);
12431
+ const [hovered, setHovered] = React45.useState(false);
12173
12432
  const altBg = index % 2 === 1 ? "#fcfcfc" : "white";
12174
12433
  return /* @__PURE__ */ jsxRuntime.jsxs(
12175
12434
  "div",
@@ -12254,7 +12513,7 @@ function KeyValueListResolver(p) {
12254
12513
  var _a4;
12255
12514
  return sum + ((_a4 = g.items) != null ? _a4 : []).length;
12256
12515
  }, 0);
12257
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12516
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12258
12517
  /* @__PURE__ */ jsxRuntime.jsxs(
12259
12518
  "div",
12260
12519
  {
@@ -12432,7 +12691,7 @@ function BalanceSheetResolver(p) {
12432
12691
  /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
12433
12692
  ((_p = p.sections) != null ? _p : []).map((section) => {
12434
12693
  var _a3;
12435
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12694
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12436
12695
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan, style: {
12437
12696
  padding: "8px 12px",
12438
12697
  fontSize: "12px",
@@ -12445,7 +12704,7 @@ function BalanceSheetResolver(p) {
12445
12704
  }, children: (_a3 = categoryLabels2[section.category]) != null ? _a3 : section.category }) }),
12446
12705
  section.subsections.map((sub, si) => {
12447
12706
  var _a4;
12448
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12707
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12449
12708
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan, style: {
12450
12709
  padding: "6px 10px 6px 24px",
12451
12710
  fontSize: "12px",
@@ -12621,7 +12880,7 @@ function IncomeStatementResolver(p) {
12621
12880
  textAlign: "left",
12622
12881
  whiteSpace: "nowrap"
12623
12882
  }, children: "\xA0" }),
12624
- periods.map((period) => /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12883
+ periods.map((period) => /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12625
12884
  /* @__PURE__ */ jsxRuntime.jsx("th", { style: {
12626
12885
  fontSize: "11px",
12627
12886
  fontWeight: 500,
@@ -12652,7 +12911,7 @@ function IncomeStatementResolver(p) {
12652
12911
  sections.map((section, si) => {
12653
12912
  var _a3;
12654
12913
  const isSubtotal = section.sectionType === "subtotal";
12655
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12914
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12656
12915
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: colCount, style: {
12657
12916
  padding: "8px 12px",
12658
12917
  fontSize: "12px",
@@ -12683,7 +12942,7 @@ function IncomeStatementResolver(p) {
12683
12942
  var _a5;
12684
12943
  const val = (_a5 = amounts[pi]) != null ? _a5 : 0;
12685
12944
  const isNeg = val < 0;
12686
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12945
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12687
12946
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12688
12947
  padding: "6px 10px",
12689
12948
  fontSize: "13px",
@@ -12718,7 +12977,7 @@ function IncomeStatementResolver(p) {
12718
12977
  var _a3;
12719
12978
  const val = (_a3 = grossProfit[pi]) != null ? _a3 : 0;
12720
12979
  const isNeg = val < 0;
12721
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12980
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12722
12981
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12723
12982
  padding: "8px 10px",
12724
12983
  fontSize: "12px",
@@ -12753,7 +13012,7 @@ function IncomeStatementResolver(p) {
12753
13012
  var _a3;
12754
13013
  const val = (_a3 = operatingIncome[pi]) != null ? _a3 : 0;
12755
13014
  const isNeg = val < 0;
12756
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
13015
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12757
13016
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12758
13017
  padding: "8px 10px",
12759
13018
  fontSize: "12px",
@@ -12787,7 +13046,7 @@ function IncomeStatementResolver(p) {
12787
13046
  var _a3;
12788
13047
  const val = (_a3 = netIncome[pi]) != null ? _a3 : 0;
12789
13048
  const isNeg = val < 0;
12790
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
13049
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12791
13050
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12792
13051
  padding: "10px 10px",
12793
13052
  fontSize: "13px",
@@ -13007,7 +13266,7 @@ function CashFlowStatementResolver(p) {
13007
13266
  /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
13008
13267
  activities.map((activity, ai) => {
13009
13268
  var _a3, _b2, _c2;
13010
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
13269
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
13011
13270
  ai > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
13012
13271
  "td",
13013
13272
  {
@@ -15420,8 +15679,8 @@ var PRIORITY_STYLES = {
15420
15679
  function EscalationCardResolver(p) {
15421
15680
  var _a2, _b, _c, _d;
15422
15681
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
15423
- const [cardHovered, setCardHovered] = React41.useState(false);
15424
- const [btnHovered, setBtnHovered] = React41.useState(false);
15682
+ const [cardHovered, setCardHovered] = React45.useState(false);
15683
+ const [btnHovered, setBtnHovered] = React45.useState(false);
15425
15684
  const priorityStyle = p.priority ? PRIORITY_STYLES[p.priority] : null;
15426
15685
  const railColor = (_a2 = priorityStyle == null ? void 0 : priorityStyle.color) != null ? _a2 : ACCENT2;
15427
15686
  const iconBg = (_b = priorityStyle == null ? void 0 : priorityStyle.bg) != null ? _b : "#fff2ec";
@@ -16268,9 +16527,9 @@ var CONNECTED_GREEN = "#15803d";
16268
16527
  function ConnectIntegrationResolver(p) {
16269
16528
  var _a2;
16270
16529
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16271
- const [cardHovered, setCardHovered] = React41.useState(false);
16272
- const [btnHovered, setBtnHovered] = React41.useState(false);
16273
- const [imgFailed, setImgFailed] = React41.useState(false);
16530
+ const [cardHovered, setCardHovered] = React45.useState(false);
16531
+ const [btnHovered, setBtnHovered] = React45.useState(false);
16532
+ const [imgFailed, setImgFailed] = React45.useState(false);
16274
16533
  const name = (p.integrationName || "Integration").trim();
16275
16534
  const initial = name.charAt(0).toUpperCase();
16276
16535
  const iconSrc = p.iconUrl || brandIconUrl(name);
@@ -16432,9 +16691,9 @@ function IntegrationsListResolver(p) {
16432
16691
  var _a2, _b;
16433
16692
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16434
16693
  const integrations = Array.isArray(p.integrations) ? p.integrations : [];
16435
- const [rowHover, setRowHover] = React41.useState(null);
16436
- const [btnHover, setBtnHover] = React41.useState(null);
16437
- const [failed, setFailed] = React41.useState({});
16694
+ const [rowHover, setRowHover] = React45.useState(null);
16695
+ const [btnHover, setBtnHover] = React45.useState(null);
16696
+ const [failed, setFailed] = React45.useState({});
16438
16697
  const connectedCount = integrations.filter((i) => i.status === "connected").length;
16439
16698
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_a2 = p.title) != null ? _a2 : "integrations", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "11px" }, children: [
16440
16699
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
@@ -16917,13 +17176,13 @@ var ellipsis = {
16917
17176
  function PipelinePreviewResolver(p) {
16918
17177
  var _a2, _b, _c, _d, _e, _f, _g;
16919
17178
  const { MUTED: MUTED2, PAPER: PAPER2, BORDER: BORDER4, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16920
- const [btnHovered, setBtnHovered] = React41.useState(false);
17179
+ const [btnHovered, setBtnHovered] = React45.useState(false);
16921
17180
  const stateCfg = STATE_CONFIG[(_a2 = p.state) != null ? _a2 : "draft"];
16922
17181
  const destinations = (_b = p.destinations) != null ? _b : [];
16923
17182
  const steps = (_c = p.steps) != null ? _c : [];
16924
17183
  const workstreams = (_d = p.workstreams) != null ? _d : [];
16925
17184
  const scheduleLabel = p.schedule ? p.schedule.type === "manual" ? "Manual" : (_f = (_e = p.schedule.label) != null ? _e : p.schedule.cron) != null ? _f : "Scheduled" : null;
16926
- const { nodes, edges, viewBox, vbW, vbH } = React41.useMemo(() => {
17185
+ const { nodes, edges, viewBox, vbW, vbH } = React45.useMemo(() => {
16927
17186
  const res = layoutGraph(steps);
16928
17187
  const b = layoutBounds(res.nodes);
16929
17188
  const pad = 24;
@@ -16937,7 +17196,7 @@ function PipelinePreviewResolver(p) {
16937
17196
  vbH: h
16938
17197
  };
16939
17198
  }, [steps]);
16940
- const nodeMap = React41.useMemo(() => {
17199
+ const nodeMap = React45.useMemo(() => {
16941
17200
  const m = {};
16942
17201
  nodes.forEach((n) => m[n.id] = n);
16943
17202
  return m;
@@ -17313,17 +17572,19 @@ var DEFAULT_INTERACTION = {
17313
17572
  onDecisionResolve: void 0,
17314
17573
  onDecisionSource: void 0
17315
17574
  };
17316
- var GenUIInteractionContext = React41.createContext(DEFAULT_INTERACTION);
17575
+ var GenUIInteractionContext = React45.createContext(DEFAULT_INTERACTION);
17317
17576
  function GenUIInteractionProvider({ value, children }) {
17318
17577
  return /* @__PURE__ */ jsxRuntime.jsx(GenUIInteractionContext.Provider, { value, children });
17319
17578
  }
17320
17579
  function useGenUIInteraction() {
17321
- return React41.useContext(GenUIInteractionContext);
17580
+ return React45.useContext(GenUIInteractionContext);
17322
17581
  }
17323
17582
  var STATUS_COLORS3 = {
17324
17583
  done: "#15803d",
17325
17584
  active: "",
17326
17585
  // filled from theme ACCENT at render time
17586
+ running: "",
17587
+ // filled from theme ACCENT at render time (executor in flight)
17327
17588
  review: "#f59e0b",
17328
17589
  pending: "#9ca3af",
17329
17590
  blocked: "#b45309",
@@ -17332,6 +17593,7 @@ var STATUS_COLORS3 = {
17332
17593
  var STATUS_LABELS = {
17333
17594
  done: "Complete",
17334
17595
  active: "In progress",
17596
+ running: "Running",
17335
17597
  review: "In review",
17336
17598
  pending: "Pending",
17337
17599
  blocked: "Blocked",
@@ -17435,6 +17697,26 @@ function IndexDot({ step, index, accent }) {
17435
17697
  if (step.status === "failed") {
17436
17698
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#dc2626", color: "white" }), children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 10 }, children: "!" }) });
17437
17699
  }
17700
+ if (step.status === "running") {
17701
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: __spreadProps(__spreadValues({}, base), { position: "relative", background: `${accent}1f`, color: accent }), children: [
17702
+ /* @__PURE__ */ jsxRuntime.jsx(
17703
+ "span",
17704
+ {
17705
+ className: "wfs-anim",
17706
+ "aria-hidden": "true",
17707
+ style: {
17708
+ position: "absolute",
17709
+ inset: 0,
17710
+ borderRadius: "50%",
17711
+ border: `1.5px solid ${accent}33`,
17712
+ borderTopColor: accent,
17713
+ animation: "wfsSpin 0.8s linear infinite"
17714
+ }
17715
+ }
17716
+ ),
17717
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 9 }, children: n })
17718
+ ] });
17719
+ }
17438
17720
  if (step.status === "active") {
17439
17721
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: accent, color: "white" }), children: n });
17440
17722
  }
@@ -17443,12 +17725,50 @@ function IndexDot({ step, index, accent }) {
17443
17725
  }
17444
17726
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#f2f2f2", color: "#9ca3af" }), children: n });
17445
17727
  }
17728
+ function EvalBadge({ step }) {
17729
+ var _a2;
17730
+ const ev = step.eval;
17731
+ if (!ev || ev.judge_ok === false) return null;
17732
+ const score = typeof ev.score === "number" ? ev.score : null;
17733
+ const flags = (_a2 = ev.data_quality_flags) != null ? _a2 : [];
17734
+ const bad = ev.verdict === "bad" || score !== null && score < 0.8;
17735
+ const tip = flags.length > 0 ? flags.map((f) => {
17736
+ var _a3;
17737
+ return `${(_a3 = f.severity) != null ? _a3 : "?"}: ${f.details || f.issue || f.field || "issue"}`;
17738
+ }).join("\n") : ev.reasoning || void 0;
17739
+ const label = score !== null ? score.toFixed(2) : bad ? "flagged" : "ok";
17740
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17741
+ "span",
17742
+ {
17743
+ title: tip,
17744
+ "data-testid": `workflow-stepper-eval-${step.id}`,
17745
+ style: {
17746
+ display: "inline-flex",
17747
+ alignItems: "center",
17748
+ gap: 3,
17749
+ fontSize: 9,
17750
+ fontWeight: 700,
17751
+ padding: "1px 6px",
17752
+ borderRadius: 9999,
17753
+ background: bad ? "#fff7ed" : "#dcfce7",
17754
+ color: bad ? "#b45309" : "#15803d",
17755
+ whiteSpace: "nowrap",
17756
+ flexShrink: 0
17757
+ },
17758
+ children: [
17759
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: bad ? "\u26A0" : "\u2713" }),
17760
+ label,
17761
+ flags.length > 0 ? ` \xB7 ${flags.length}` : ""
17762
+ ]
17763
+ }
17764
+ );
17765
+ }
17446
17766
  var CARD_MIN = 132;
17447
17767
  var CARD_GAP = 16;
17448
17768
  var AUTO_COMPACT_BELOW = 360;
17449
17769
  function useContainerWidth(ref) {
17450
- const [w, setW] = React41__default.default.useState(0);
17451
- React41__default.default.useLayoutEffect(() => {
17770
+ const [w, setW] = React45__default.default.useState(0);
17771
+ React45__default.default.useLayoutEffect(() => {
17452
17772
  const el = ref.current;
17453
17773
  if (!el || typeof ResizeObserver === "undefined") return;
17454
17774
  const ro = new ResizeObserver((entries) => {
@@ -17467,6 +17787,7 @@ var KEYFRAMES = `
17467
17787
  @keyframes wfsLampPulse{0%,100%{box-shadow:0 0 0 0 var(--wfs-accent,#6366f1)73}50%{box-shadow:0 0 0 4px transparent}}
17468
17788
  @keyframes wfsRise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
17469
17789
  @keyframes wfsShimmer{0%{background-position:-200px 0}100%{background-position:calc(200px + 100%) 0}}
17790
+ @keyframes wfsSpin{to{transform:rotate(360deg)}}
17470
17791
  .wfs-rise{animation:wfsRise 0.32s cubic-bezier(0.22,1,0.36,1) both}
17471
17792
  @media (prefers-reduced-motion: reduce){
17472
17793
  .wfs-anim,.wfs-rise,.wfs-shim{animation:none !important}
@@ -17547,17 +17868,17 @@ function WorkflowStepperRenderer({
17547
17868
  const steps = (_a2 = data.steps) != null ? _a2 : [];
17548
17869
  const activeStepId = (_d = (_c = data.active_step) != null ? _c : (_b = steps.find((s) => s.status === "active")) == null ? void 0 : _b.id) != null ? _d : null;
17549
17870
  const interactive = typeof onSelectStep === "function";
17550
- const statusColor3 = (s) => s === "active" ? ACCENT2 : STATUS_COLORS3[s];
17871
+ const statusColor3 = (s) => s === "active" || s === "running" ? ACCENT2 : STATUS_COLORS3[s];
17551
17872
  const doneCount = steps.filter((s) => s.status === "done").length;
17552
- const rootRef = React41__default.default.useRef(null);
17873
+ const rootRef = React45__default.default.useRef(null);
17553
17874
  const containerW = useContainerWidth(rootRef);
17554
17875
  let resolved = density === "auto" ? "full" : density;
17555
17876
  if (density === "auto" && containerW > 0) {
17556
17877
  const needed = steps.length * CARD_MIN + Math.max(0, steps.length - 1) * CARD_GAP;
17557
17878
  resolved = containerW < AUTO_COMPACT_BELOW || needed > containerW * 1.6 ? "compact" : "full";
17558
17879
  }
17559
- const scrollerRef = React41__default.default.useRef(null);
17560
- React41__default.default.useEffect(() => {
17880
+ const scrollerRef = React45__default.default.useRef(null);
17881
+ React45__default.default.useEffect(() => {
17561
17882
  if (resolved !== "full" || loading) return;
17562
17883
  const sc = scrollerRef.current;
17563
17884
  if (!sc) return;
@@ -17568,11 +17889,11 @@ function WorkflowStepperRenderer({
17568
17889
  el.scrollIntoView({ inline: "center", block: "nearest", behavior: "smooth" });
17569
17890
  }
17570
17891
  }, [resolved, loading, selectedStep, activeStepId]);
17571
- const [edges, setEdges] = React41__default.default.useState({
17892
+ const [edges, setEdges] = React45__default.default.useState({
17572
17893
  left: false,
17573
17894
  right: false
17574
17895
  });
17575
- const updateEdges = React41__default.default.useCallback(() => {
17896
+ const updateEdges = React45__default.default.useCallback(() => {
17576
17897
  const sc = scrollerRef.current;
17577
17898
  if (!sc) return;
17578
17899
  const max = sc.scrollWidth - sc.clientWidth;
@@ -17581,7 +17902,7 @@ function WorkflowStepperRenderer({
17581
17902
  const right = sl < max - 1;
17582
17903
  setEdges((prev) => prev.left === left && prev.right === right ? prev : { left, right });
17583
17904
  }, []);
17584
- React41__default.default.useLayoutEffect(() => {
17905
+ React45__default.default.useLayoutEffect(() => {
17585
17906
  if (resolved !== "full" || loading) return;
17586
17907
  updateEdges();
17587
17908
  const sc = scrollerRef.current;
@@ -17637,7 +17958,7 @@ function WorkflowStepperRenderer({
17637
17958
  const reached = s.status !== "pending";
17638
17959
  const clickable = interactive && reached;
17639
17960
  const size = act ? 11 : done ? 9 : 8;
17640
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
17961
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
17641
17962
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17642
17963
  "span",
17643
17964
  {
@@ -17775,12 +18096,13 @@ function WorkflowStepperRenderer({
17775
18096
  var _a3;
17776
18097
  const isSelected = selectedStep === step.id;
17777
18098
  const isActive = step.status === "active";
18099
+ const isRunning = step.status === "running";
17778
18100
  const reached = step.status !== "pending";
17779
18101
  const clickable = interactive && reached;
17780
18102
  const color = statusColor3(step.status);
17781
18103
  const humans = ((_a3 = step.assignees) != null ? _a3 : []).filter((a) => a.kind === "human");
17782
18104
  const roleCaption = humans.map((h) => h.role).filter(Boolean).slice(0, 2).join(" \xB7 ");
17783
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
18105
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
17784
18106
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17785
18107
  "div",
17786
18108
  {
@@ -17871,36 +18193,41 @@ function WorkflowStepperRenderer({
17871
18193
  }
17872
18194
  }
17873
18195
  ),
17874
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
17875
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
18196
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 4 }, children: [
18197
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, minWidth: 0 }, children: [
17876
18198
  /* @__PURE__ */ jsxRuntime.jsx(IndexDot, { step, index: i, accent: ACCENT2 }),
17877
18199
  /* @__PURE__ */ jsxRuntime.jsx(
17878
18200
  "span",
17879
18201
  {
17880
- className: isActive ? "wfs-anim" : void 0,
18202
+ className: isActive || isRunning ? "wfs-anim" : void 0,
17881
18203
  style: {
17882
18204
  width: 6,
17883
18205
  height: 6,
17884
18206
  borderRadius: "50%",
17885
18207
  background: color,
17886
- animation: isActive ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
18208
+ flexShrink: 0,
18209
+ animation: isActive || isRunning ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
17887
18210
  }
17888
18211
  }
17889
18212
  )
17890
18213
  ] }),
17891
- /* @__PURE__ */ jsxRuntime.jsx(
17892
- "span",
17893
- {
17894
- style: {
17895
- fontSize: 9,
17896
- fontWeight: 600,
17897
- letterSpacing: "0.05em",
17898
- textTransform: "uppercase",
17899
- color
17900
- },
17901
- children: STATUS_LABELS[step.status]
17902
- }
17903
- )
18214
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4, minWidth: 0 }, children: [
18215
+ /* @__PURE__ */ jsxRuntime.jsx(EvalBadge, { step }),
18216
+ /* @__PURE__ */ jsxRuntime.jsx(
18217
+ "span",
18218
+ {
18219
+ style: {
18220
+ fontSize: 9,
18221
+ fontWeight: 600,
18222
+ letterSpacing: "0.05em",
18223
+ textTransform: "uppercase",
18224
+ color,
18225
+ whiteSpace: "nowrap"
18226
+ },
18227
+ children: STATUS_LABELS[step.status]
18228
+ }
18229
+ )
18230
+ ] })
17904
18231
  ] }),
17905
18232
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [
17906
18233
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -18034,97 +18361,1767 @@ function WorkflowStepperResolver(p) {
18034
18361
  ] }) });
18035
18362
  }
18036
18363
  init_ThemeContext();
18037
- var SEVERITY_COLORS = {
18038
- high: { color: "#dc2626", bg: "#fef2f2" },
18039
- medium: { color: "#f59e0b", bg: "#fff7ed" },
18040
- low: { color: "#777777", bg: "#f2f2f2" }
18364
+
18365
+ // src/composites/document-field-extraction/bboxTransform.ts
18366
+ function bboxToRect(bbox2, page, px) {
18367
+ if (!bbox2 || bbox2.length !== 4) return null;
18368
+ const { wPts, hPts } = page;
18369
+ const { wPx, hPx } = px;
18370
+ if (!wPts || !hPts || !wPx || !hPx) return null;
18371
+ const [x0, y0, x1, y1] = bbox2;
18372
+ const sx = wPx / wPts;
18373
+ const sy = hPx / hPts;
18374
+ return {
18375
+ left: x0 * sx,
18376
+ width: (x1 - x0) * sx,
18377
+ // Flip Y: the box's TOP in screen space is the page height minus its upper
18378
+ // PDF-point edge (y1), because PDF y grows upward from the bottom.
18379
+ top: (hPts - y1) * sy,
18380
+ height: (y1 - y0) * sy
18381
+ };
18382
+ }
18383
+
18384
+ // src/composites/document-field-extraction/FieldDetail.tsx
18385
+ init_ThemeContext();
18386
+
18387
+ // src/composites/document-field-extraction/fieldLabels.ts
18388
+ var LABEL_DISPLAY = {
18389
+ "employer identification number": "Employer ID (EIN)",
18390
+ "company or business name": "Company Name",
18391
+ "total revenue": "Total Revenue",
18392
+ "net income": "Net Income",
18393
+ "tax year": "Tax Year",
18394
+ "invoice number": "Invoice Number",
18395
+ "invoice date": "Invoice Date",
18396
+ "total amount due": "Total Amount Due",
18397
+ "vendor name": "Vendor Name",
18398
+ "receipt total": "Receipt Total",
18399
+ "transaction date": "Transaction Date",
18400
+ "merchant name": "Merchant Name"
18041
18401
  };
18042
- var GREEN3 = "#15803d";
18043
- var GREEN_SOFT = "#dcfce7";
18044
- var STACK_BELOW = 380;
18045
- function formatAmount2(amount, currency = "USD") {
18402
+ function prettyLabel(label) {
18403
+ var _a2;
18404
+ return (_a2 = LABEL_DISPLAY[label]) != null ? _a2 : label.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
18405
+ }
18406
+ var TIER_COLORS = {
18407
+ green: "#15803d",
18408
+ amber: "#f59e0b",
18409
+ red: "#dc2626"
18410
+ };
18411
+ var BADGE_TITLE = {
18412
+ SC: "High confidence",
18413
+ CN: "Medium confidence",
18414
+ AB: "Low confidence",
18415
+ SW: "Very low confidence"
18416
+ };
18417
+ var BADGE_STYLE = {
18418
+ SC: { bg: "#dcfce7", fg: "#15803d" },
18419
+ CN: { bg: "#eff6ff", fg: "#0364ff" },
18420
+ // theme-ok (SECONDARY)
18421
+ AB: { bg: "#fff7ed", fg: "#92400e" },
18422
+ SW: { bg: "#fef2f2", fg: "#dc2626" }
18423
+ };
18424
+ var STATE_DOT = {
18425
+ ok: "#15803d",
18426
+ corrected: "#0364ff",
18427
+ // theme-ok (SECONDARY)
18428
+ missing: "#dc2626",
18429
+ warn: "#f59e0b"
18430
+ };
18431
+ function hexToRgba(hex, alpha) {
18432
+ const h = hex.replace("#", "");
18433
+ const r = parseInt(h.slice(0, 2), 16);
18434
+ const g = parseInt(h.slice(2, 4), 16);
18435
+ const b = parseInt(h.slice(4, 6), 16);
18436
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
18437
+ }
18438
+ function badgeStyle(f) {
18046
18439
  var _a2, _b;
18047
- const abs = Math.abs(amount);
18048
- const sign = amount < 0 ? "-" : "";
18049
- let body;
18050
- if (abs >= 1e6) body = `${(abs / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;
18051
- else if (abs >= 1e3) body = `${(abs / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;
18052
- else body = `${abs}`;
18053
- let symbol = "$";
18054
- try {
18055
- const parts = new Intl.NumberFormat("en-US", {
18056
- style: "currency",
18057
- currency,
18058
- maximumFractionDigits: 0
18059
- }).formatToParts(0);
18060
- symbol = (_b = (_a2 = parts.find((p) => p.type === "currency")) == null ? void 0 : _a2.value) != null ? _b : "$";
18061
- } catch (e) {
18062
- symbol = "$";
18063
- }
18064
- return `${sign}${symbol}${body}`;
18440
+ return (_b = BADGE_STYLE[(_a2 = f.badge) != null ? _a2 : ""]) != null ? _b : { bg: "#f6f6f6", fg: "#777777" };
18065
18441
  }
18066
- function useContainerWidth2(ref) {
18067
- const [w, setW] = React41__default.default.useState(0);
18068
- React41__default.default.useLayoutEffect(() => {
18069
- const el = ref.current;
18070
- if (!el || typeof ResizeObserver === "undefined") return;
18071
- const ro = new ResizeObserver((entries) => {
18072
- var _a2;
18073
- const cr = (_a2 = entries[0]) == null ? void 0 : _a2.contentRect;
18074
- if (cr) setW(cr.width);
18075
- });
18076
- ro.observe(el);
18077
- setW(el.getBoundingClientRect().width);
18078
- return () => ro.disconnect();
18079
- }, [ref]);
18080
- return w;
18442
+ function dotColor2(f) {
18443
+ var _a2, _b;
18444
+ return (_b = STATE_DOT[(_a2 = f.state) != null ? _a2 : "ok"]) != null ? _b : "#15803d";
18081
18445
  }
18082
- var KEYFRAMES2 = `
18083
- @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
18084
- .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
18085
- @media (prefers-reduced-motion: reduce){
18086
- .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
18087
- }`;
18088
- function SparkCheck({ size, color }) {
18089
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
18090
- "path",
18091
- {
18092
- d: "M5 13l4 4L19 7",
18093
- stroke: color,
18094
- strokeWidth: 2.5,
18095
- strokeLinecap: "round",
18096
- strokeLinejoin: "round"
18097
- }
18098
- ) });
18446
+ function fieldColor(f, secondary) {
18447
+ var _a2, _b;
18448
+ if (f.state === "corrected") return secondary;
18449
+ return (_b = TIER_COLORS[(_a2 = f.confidence_tier) != null ? _a2 : "amber"]) != null ? _b : TIER_COLORS.amber;
18099
18450
  }
18100
- function FlagPill({ flag }) {
18451
+ function confidenceLabel(f) {
18101
18452
  var _a2;
18102
- const sev = (_a2 = flag.severity) != null ? _a2 : "medium";
18103
- const { color, bg } = SEVERITY_COLORS[sev];
18453
+ if (typeof f.confidence === "number" && !Number.isNaN(f.confidence)) {
18454
+ return `${Math.round(f.confidence * 100)}%`;
18455
+ }
18456
+ return (_a2 = f.badge) != null ? _a2 : "\u2014";
18457
+ }
18458
+ function FieldDetail({
18459
+ field,
18460
+ selected,
18461
+ onSelect,
18462
+ onSave,
18463
+ correctionCount = 0,
18464
+ cardRef
18465
+ }) {
18466
+ var _a2, _b, _c, _d;
18467
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18468
+ const [editing, setEditing] = React45__default.default.useState(false);
18469
+ const [draft, setDraft] = React45__default.default.useState("");
18470
+ const [saving, setSaving] = React45__default.default.useState(false);
18471
+ const [saveError, setSaveError] = React45__default.default.useState(null);
18472
+ const textareaRef = React45__default.default.useRef(null);
18473
+ const color = fieldColor(field, SECONDARY2);
18474
+ const corrected = field.state === "corrected";
18475
+ const startEdit = (e) => {
18476
+ e.stopPropagation();
18477
+ setDraft(field.value || "");
18478
+ setSaveError(null);
18479
+ setEditing(true);
18480
+ setTimeout(() => {
18481
+ var _a3, _b2;
18482
+ (_a3 = textareaRef.current) == null ? void 0 : _a3.focus();
18483
+ (_b2 = textareaRef.current) == null ? void 0 : _b2.select();
18484
+ }, 0);
18485
+ };
18486
+ const cancelEdit = (e) => {
18487
+ e.stopPropagation();
18488
+ setEditing(false);
18489
+ setSaveError(null);
18490
+ };
18491
+ const save = async (e) => {
18492
+ var _a3, _b2;
18493
+ e.stopPropagation();
18494
+ if (!onSave || draft === field.value) {
18495
+ setEditing(false);
18496
+ return;
18497
+ }
18498
+ setSaving(true);
18499
+ setSaveError(null);
18500
+ try {
18501
+ await onSave(field.field_key, draft);
18502
+ setEditing(false);
18503
+ } catch (err) {
18504
+ const msg = ((_b2 = (_a3 = err == null ? void 0 : err.response) == null ? void 0 : _a3.data) == null ? void 0 : _b2.detail) || "Save failed. Try again.";
18505
+ setSaveError(msg);
18506
+ } finally {
18507
+ setSaving(false);
18508
+ }
18509
+ };
18510
+ const handleKeyDown = (e) => {
18511
+ if (e.key === "Escape") cancelEdit(e);
18512
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) void save(e);
18513
+ };
18104
18514
  return /* @__PURE__ */ jsxRuntime.jsxs(
18105
- "span",
18515
+ "div",
18106
18516
  {
18517
+ ref: cardRef,
18518
+ "data-testid": "field-card",
18519
+ "data-field-key": field.field_key,
18520
+ "data-selected": selected ? "true" : "false",
18521
+ role: "button",
18522
+ tabIndex: 0,
18523
+ onClick: () => !editing && onSelect(selected ? null : field.field_key),
18524
+ onKeyDown: (e) => {
18525
+ if (!editing && e.key === "Enter") onSelect(selected ? null : field.field_key);
18526
+ },
18107
18527
  style: {
18108
- display: "inline-flex",
18109
- alignItems: "center",
18110
- gap: 5,
18111
- fontSize: 11,
18112
- fontWeight: 600,
18113
- padding: "3px 9px",
18114
- borderRadius: 9999,
18115
- background: bg,
18116
- color,
18117
- lineHeight: 1.2
18528
+ display: "flex",
18529
+ flexDirection: "column",
18530
+ gap: "4px",
18531
+ padding: "8px 10px",
18532
+ borderRadius: "0.5rem",
18533
+ border: `1px solid ${selected ? color : BORDER4}`,
18534
+ background: selected ? hexToRgba(color, 0.06) : "white",
18535
+ cursor: editing ? "default" : "pointer",
18536
+ transition: "background 0.15s, border-color 0.15s"
18118
18537
  },
18119
18538
  children: [
18120
- /* @__PURE__ */ jsxRuntime.jsx(
18121
- "span",
18122
- {
18123
- "aria-hidden": "true",
18124
- style: { width: 6, height: 6, borderRadius: "50%", background: color, flexShrink: 0 }
18125
- }
18126
- ),
18127
- flag.field ? `${flag.field}: ${flag.issue}` : flag.issue
18539
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", minWidth: 0 }, children: [
18540
+ /* @__PURE__ */ jsxRuntime.jsx(
18541
+ "span",
18542
+ {
18543
+ title: (_c = (_b = BADGE_TITLE[(_a2 = field.badge) != null ? _a2 : ""]) != null ? _b : field.badge) != null ? _c : "",
18544
+ style: {
18545
+ fontSize: "10px",
18546
+ fontWeight: 700,
18547
+ padding: "2px 6px",
18548
+ borderRadius: "4px",
18549
+ flexShrink: 0,
18550
+ letterSpacing: "0.02em",
18551
+ minWidth: "34px",
18552
+ textAlign: "center",
18553
+ fontVariantNumeric: "tabular-nums",
18554
+ background: badgeStyle(field).bg,
18555
+ color: badgeStyle(field).fg
18556
+ },
18557
+ children: confidenceLabel(field)
18558
+ }
18559
+ ),
18560
+ /* @__PURE__ */ jsxRuntime.jsx(
18561
+ "span",
18562
+ {
18563
+ title: prettyLabel(field.label),
18564
+ style: {
18565
+ fontSize: "12.5px",
18566
+ fontWeight: 600,
18567
+ color: "var(--foreground)",
18568
+ flex: 1,
18569
+ minWidth: 0,
18570
+ whiteSpace: "nowrap",
18571
+ overflow: "hidden",
18572
+ textOverflow: "ellipsis"
18573
+ },
18574
+ children: prettyLabel(field.label)
18575
+ }
18576
+ ),
18577
+ field.is_primary && /* @__PURE__ */ jsxRuntime.jsx(
18578
+ "span",
18579
+ {
18580
+ style: {
18581
+ fontSize: "9px",
18582
+ fontWeight: 600,
18583
+ textTransform: "uppercase",
18584
+ letterSpacing: "0.04em",
18585
+ color: MUTED2,
18586
+ flexShrink: 0
18587
+ },
18588
+ children: "Primary"
18589
+ }
18590
+ ),
18591
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: [
18592
+ "p.",
18593
+ field.page + 1
18594
+ ] }),
18595
+ !editing && onSave && /* @__PURE__ */ jsxRuntime.jsx(
18596
+ "button",
18597
+ {
18598
+ type: "button",
18599
+ onClick: startEdit,
18600
+ title: "Edit value",
18601
+ "aria-label": "Edit value",
18602
+ style: {
18603
+ border: `1px solid ${BORDER4}`,
18604
+ borderRadius: "6px",
18605
+ background: "white",
18606
+ cursor: "pointer",
18607
+ padding: "3px 5px",
18608
+ lineHeight: 1,
18609
+ flexShrink: 0,
18610
+ display: "inline-flex",
18611
+ alignItems: "center",
18612
+ justifyContent: "center"
18613
+ },
18614
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: MUTED2, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
18615
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
18616
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
18617
+ ] })
18618
+ }
18619
+ )
18620
+ ] }),
18621
+ editing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { onClick: (e) => e.stopPropagation(), style: { display: "flex", flexDirection: "column", gap: "5px" }, children: [
18622
+ /* @__PURE__ */ jsxRuntime.jsx(
18623
+ "textarea",
18624
+ {
18625
+ ref: textareaRef,
18626
+ value: draft,
18627
+ onChange: (e) => setDraft(e.target.value),
18628
+ onKeyDown: handleKeyDown,
18629
+ rows: 3,
18630
+ placeholder: "Enter value\u2026",
18631
+ style: {
18632
+ width: "100%",
18633
+ boxSizing: "border-box",
18634
+ resize: "vertical",
18635
+ fontSize: "13px",
18636
+ fontFamily: "var(--font-sans)",
18637
+ color: "var(--foreground)",
18638
+ padding: "6px 8px",
18639
+ borderRadius: "0.4rem",
18640
+ border: `1px solid ${BORDER4}`
18641
+ }
18642
+ }
18643
+ ),
18644
+ saveError && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: TIER_COLORS.red }, children: saveError }),
18645
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
18646
+ /* @__PURE__ */ jsxRuntime.jsx(
18647
+ "button",
18648
+ {
18649
+ type: "button",
18650
+ onClick: save,
18651
+ disabled: saving,
18652
+ title: "Save (\u2318\u21B5)",
18653
+ style: {
18654
+ display: "inline-flex",
18655
+ alignItems: "center",
18656
+ gap: "4px",
18657
+ fontSize: "11px",
18658
+ fontWeight: 600,
18659
+ padding: "4px 10px",
18660
+ borderRadius: "0.4rem",
18661
+ border: "none",
18662
+ background: "var(--foreground)",
18663
+ color: "white",
18664
+ cursor: saving ? "default" : "pointer",
18665
+ opacity: saving ? 0.7 : 1
18666
+ },
18667
+ children: saving ? "Saving\u2026" : "Save"
18668
+ }
18669
+ ),
18670
+ /* @__PURE__ */ jsxRuntime.jsx(
18671
+ "button",
18672
+ {
18673
+ type: "button",
18674
+ onClick: cancelEdit,
18675
+ disabled: saving,
18676
+ title: "Cancel (Esc)",
18677
+ style: {
18678
+ fontSize: "11px",
18679
+ fontWeight: 600,
18680
+ padding: "4px 10px",
18681
+ borderRadius: "0.4rem",
18682
+ border: `1px solid ${BORDER4}`,
18683
+ background: "white",
18684
+ color: MUTED2,
18685
+ cursor: saving ? "default" : "pointer"
18686
+ },
18687
+ children: "Cancel"
18688
+ }
18689
+ )
18690
+ ] })
18691
+ ] }) : corrected ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px", paddingLeft: "2px" }, children: [
18692
+ field.previous_value != null && field.previous_value !== "" && /* @__PURE__ */ jsxRuntime.jsx(
18693
+ "span",
18694
+ {
18695
+ style: {
18696
+ fontSize: "11.5px",
18697
+ color: MUTED2,
18698
+ textDecoration: "line-through",
18699
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18700
+ wordBreak: "break-word"
18701
+ },
18702
+ children: field.previous_value
18703
+ }
18704
+ ),
18705
+ /* @__PURE__ */ jsxRuntime.jsx(
18706
+ "span",
18707
+ {
18708
+ style: {
18709
+ fontSize: "12.5px",
18710
+ fontWeight: 600,
18711
+ color: "var(--foreground)",
18712
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18713
+ wordBreak: "break-word"
18714
+ },
18715
+ children: field.value || "\u2014"
18716
+ }
18717
+ ),
18718
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
18719
+ field.corrected_by && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: SECONDARY2 }, title: `Corrected by ${field.corrected_by}`, children: field.corrected_by }),
18720
+ correctionCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
18721
+ "span",
18722
+ {
18723
+ style: {
18724
+ fontSize: "10.5px",
18725
+ fontWeight: 600,
18726
+ color: MUTED2,
18727
+ background: PAPER2,
18728
+ borderRadius: "9999px",
18729
+ padding: "1px 7px"
18730
+ },
18731
+ children: [
18732
+ correctionCount,
18733
+ " ",
18734
+ correctionCount === 1 ? "event" : "events"
18735
+ ]
18736
+ }
18737
+ )
18738
+ ] })
18739
+ ] }) : (
18740
+ // Bottom row: monospace value + right-edge validation dot (file explorer).
18741
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", paddingLeft: "2px" }, children: [
18742
+ /* @__PURE__ */ jsxRuntime.jsx(
18743
+ "span",
18744
+ {
18745
+ style: {
18746
+ fontSize: "12.5px",
18747
+ color: MUTED2,
18748
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18749
+ flex: 1,
18750
+ minWidth: 0,
18751
+ whiteSpace: "nowrap",
18752
+ overflow: "hidden",
18753
+ textOverflow: "ellipsis"
18754
+ },
18755
+ title: field.value || "\u2014",
18756
+ children: field.value || "\u2014"
18757
+ }
18758
+ ),
18759
+ /* @__PURE__ */ jsxRuntime.jsx(
18760
+ "span",
18761
+ {
18762
+ title: (_d = field.state) != null ? _d : "ok",
18763
+ style: {
18764
+ width: "8px",
18765
+ height: "8px",
18766
+ borderRadius: "9999px",
18767
+ flexShrink: 0,
18768
+ background: dotColor2(field)
18769
+ }
18770
+ }
18771
+ )
18772
+ ] })
18773
+ )
18774
+ ]
18775
+ }
18776
+ );
18777
+ }
18778
+
18779
+ // src/composites/document-field-extraction/FieldDetails.tsx
18780
+ init_ThemeContext();
18781
+ var BADGE_DOT = {
18782
+ // gen-ui semantic dot colors
18783
+ ok: "#15803d",
18784
+ green: "#15803d",
18785
+ warn: "#f59e0b",
18786
+ amber: "#f59e0b",
18787
+ missing: "#dc2626",
18788
+ red: "#dc2626",
18789
+ corrected: "#0364ff"
18790
+ // theme-ok (SECONDARY)
18791
+ };
18792
+ function FieldDetails({
18793
+ summary,
18794
+ fileName,
18795
+ pageCount,
18796
+ pagesProcessed
18797
+ }) {
18798
+ var _a2, _b, _c, _d, _e, _f;
18799
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18800
+ if (!summary) {
18801
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18802
+ "div",
18803
+ {
18804
+ style: {
18805
+ height: "100%",
18806
+ display: "flex",
18807
+ flexDirection: "column",
18808
+ alignItems: "center",
18809
+ justifyContent: "center",
18810
+ gap: "6px",
18811
+ color: MUTED2,
18812
+ textAlign: "center",
18813
+ padding: "24px"
18814
+ },
18815
+ children: [
18816
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "26px", lineHeight: 1 }, children: "\u{1F4C4}" }),
18817
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "14px", fontWeight: 600, color: "var(--foreground)" }, children: "No summary yet" }),
18818
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", maxWidth: "280px" }, children: "This document has no extracted summary." })
18819
+ ]
18820
+ }
18821
+ );
18822
+ }
18823
+ const header = buildHeader(summary);
18824
+ const crumb = buildCrumbLine(summary);
18825
+ const facts = buildFacts(summary, fileName, pageCount, pagesProcessed);
18826
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "100%", overflowY: "auto", paddingRight: "4px" }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "14px" }, children: [
18827
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { style: { display: "flex", flexDirection: "column", gap: "3px" }, children: [
18828
+ /* @__PURE__ */ jsxRuntime.jsx(
18829
+ "h2",
18830
+ {
18831
+ title: header.title,
18832
+ style: {
18833
+ margin: 0,
18834
+ fontFamily: "var(--font-serif)",
18835
+ fontSize: "20px",
18836
+ fontWeight: 400,
18837
+ letterSpacing: "-0.01em",
18838
+ color: "var(--foreground)",
18839
+ overflow: "hidden",
18840
+ textOverflow: "ellipsis",
18841
+ whiteSpace: "nowrap"
18842
+ },
18843
+ children: header.title
18844
+ }
18845
+ ),
18846
+ header.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: header.subtitle })
18847
+ ] }),
18848
+ (summary.domain || summary.display_name || summary.domain_group || ((_b = (_a2 = summary.tags) == null ? void 0 : _a2.length) != null ? _b : 0) > 0) && /* @__PURE__ */ jsxRuntime.jsxs(
18849
+ "section",
18850
+ {
18851
+ style: {
18852
+ display: "flex",
18853
+ flexDirection: "column",
18854
+ gap: "6px",
18855
+ padding: "12px 14px",
18856
+ borderRadius: "0.75rem",
18857
+ border: `1px solid ${BORDER4}`,
18858
+ background: PAPER2
18859
+ },
18860
+ children: [
18861
+ summary.domain_group && /* @__PURE__ */ jsxRuntime.jsx(
18862
+ "span",
18863
+ {
18864
+ style: {
18865
+ fontSize: "10px",
18866
+ fontWeight: 600,
18867
+ textTransform: "uppercase",
18868
+ letterSpacing: "0.06em",
18869
+ color: MUTED2
18870
+ },
18871
+ children: summary.domain_group
18872
+ }
18873
+ ),
18874
+ /* @__PURE__ */ jsxRuntime.jsx(
18875
+ "h3",
18876
+ {
18877
+ style: {
18878
+ margin: 0,
18879
+ fontSize: "14px",
18880
+ fontWeight: 600,
18881
+ color: "var(--foreground)"
18882
+ },
18883
+ children: summary.domain || summary.display_name
18884
+ }
18885
+ ),
18886
+ crumb && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: crumb }),
18887
+ ((_d = (_c = summary.tags) == null ? void 0 : _c.length) != null ? _d : 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "5px", marginTop: "2px" }, children: summary.tags.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
18888
+ "span",
18889
+ {
18890
+ style: {
18891
+ fontSize: "10px",
18892
+ fontWeight: 600,
18893
+ padding: "2px 8px",
18894
+ borderRadius: "9999px",
18895
+ background: "white",
18896
+ border: `1px solid ${BORDER4}`,
18897
+ color: MUTED2
18898
+ },
18899
+ children: t
18900
+ },
18901
+ t
18902
+ )) })
18903
+ ]
18904
+ }
18905
+ ),
18906
+ ((_f = (_e = summary.stats) == null ? void 0 : _e.length) != null ? _f : 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx(
18907
+ "div",
18908
+ {
18909
+ style: {
18910
+ display: "grid",
18911
+ gridTemplateColumns: "repeat(auto-fit, minmax(130px, 1fr))",
18912
+ gap: "8px"
18913
+ },
18914
+ children: summary.stats.map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
18915
+ "div",
18916
+ {
18917
+ style: {
18918
+ display: "flex",
18919
+ flexDirection: "column",
18920
+ gap: "2px",
18921
+ padding: "10px 12px",
18922
+ borderRadius: "0.6rem",
18923
+ border: `1px solid ${BORDER4}`,
18924
+ background: "white"
18925
+ },
18926
+ children: [
18927
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: MUTED2 }, children: s.label }),
18928
+ /* @__PURE__ */ jsxRuntime.jsx(
18929
+ "span",
18930
+ {
18931
+ title: s.value,
18932
+ style: {
18933
+ fontSize: "15px",
18934
+ fontWeight: 600,
18935
+ color: "var(--foreground)",
18936
+ overflow: "hidden",
18937
+ textOverflow: "ellipsis",
18938
+ whiteSpace: "nowrap"
18939
+ },
18940
+ children: s.value
18941
+ }
18942
+ ),
18943
+ s.caption && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "10px", color: MUTED2 }, children: s.caption })
18944
+ ]
18945
+ },
18946
+ s.field_key
18947
+ ))
18948
+ }
18949
+ ),
18950
+ facts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
18951
+ /* @__PURE__ */ jsxRuntime.jsxs(
18952
+ "div",
18953
+ {
18954
+ style: {
18955
+ display: "flex",
18956
+ alignItems: "center",
18957
+ gap: "6px",
18958
+ fontSize: "11px",
18959
+ fontWeight: 600,
18960
+ textTransform: "uppercase",
18961
+ letterSpacing: "0.04em",
18962
+ color: MUTED2
18963
+ },
18964
+ children: [
18965
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u25A4" }),
18966
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Document details" })
18967
+ ]
18968
+ }
18969
+ ),
18970
+ /* @__PURE__ */ jsxRuntime.jsx(
18971
+ "dl",
18972
+ {
18973
+ style: {
18974
+ margin: 0,
18975
+ display: "grid",
18976
+ gridTemplateColumns: "minmax(110px, auto) 1fr",
18977
+ rowGap: "6px",
18978
+ columnGap: "14px"
18979
+ },
18980
+ children: facts.map((f) => {
18981
+ var _a3;
18982
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
18983
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { style: { fontSize: "12px", color: MUTED2 }, children: f.label }),
18984
+ /* @__PURE__ */ jsxRuntime.jsxs(
18985
+ "dd",
18986
+ {
18987
+ title: typeof f.value === "string" ? f.value : void 0,
18988
+ style: {
18989
+ margin: 0,
18990
+ fontSize: "12px",
18991
+ color: "var(--foreground)",
18992
+ display: "flex",
18993
+ alignItems: "center",
18994
+ gap: "6px",
18995
+ wordBreak: "break-word"
18996
+ },
18997
+ children: [
18998
+ f.badge && /* @__PURE__ */ jsxRuntime.jsx(
18999
+ "span",
19000
+ {
19001
+ style: {
19002
+ width: "7px",
19003
+ height: "7px",
19004
+ borderRadius: "9999px",
19005
+ flexShrink: 0,
19006
+ background: (_a3 = BADGE_DOT[f.badge]) != null ? _a3 : SECONDARY2
19007
+ }
19008
+ }
19009
+ ),
19010
+ f.value
19011
+ ]
19012
+ }
19013
+ )
19014
+ ] }, f.key);
19015
+ })
19016
+ }
19017
+ )
19018
+ ] })
19019
+ ] }) });
19020
+ }
19021
+ function buildHeader(summary) {
19022
+ const form = [summary.short_name, summary.display_name].filter(Boolean);
19023
+ const title = summary.organization || form.shift() || summary.domain || "Document";
19024
+ const parts = summary.organization ? [...form] : form;
19025
+ if (summary.tax_year) parts.push(`TY ${summary.tax_year}`);
19026
+ return { title, subtitle: parts.join(" \xB7 ") };
19027
+ }
19028
+ function buildCrumbLine(summary) {
19029
+ const parts = [...summary.crumbs || [], summary.short_name].filter(Boolean);
19030
+ if (parts.length > 0) return parts.join(" \xB7 ");
19031
+ return summary.domain && summary.display_name ? summary.display_name : "";
19032
+ }
19033
+ function buildFacts(summary, fileName, pageCount, pagesProcessed) {
19034
+ const rows = [];
19035
+ if (fileName) rows.push({ key: "file", label: "File", value: fileName });
19036
+ if (summary.display_name) {
19037
+ rows.push({ key: "doctype", label: "Document type", value: summary.display_name });
19038
+ }
19039
+ if (summary.tax_year != null && summary.tax_year !== "") {
19040
+ rows.push({ key: "year", label: "Tax year", value: String(summary.tax_year) });
19041
+ }
19042
+ for (const f of summary.facts || []) {
19043
+ rows.push({ key: f.field_key, label: f.label, value: f.value, badge: f.badge });
19044
+ }
19045
+ if (pageCount) {
19046
+ rows.push({
19047
+ key: "pages",
19048
+ label: "Pages processed",
19049
+ value: `${pagesProcessed != null ? pagesProcessed : pageCount} / ${pageCount}`
19050
+ });
19051
+ }
19052
+ return rows;
19053
+ }
19054
+
19055
+ // src/composites/document-field-extraction/FieldAuditLog.tsx
19056
+ init_ThemeContext();
19057
+ function initials(name) {
19058
+ return name.trim().split(/\s+/).slice(0, 2).map((w) => {
19059
+ var _a2;
19060
+ return ((_a2 = w[0]) != null ? _a2 : "").toUpperCase();
19061
+ }).join("");
19062
+ }
19063
+ function formatTs(ts) {
19064
+ if (!ts) return "\u2014";
19065
+ const d = new Date(ts);
19066
+ if (Number.isNaN(d.getTime())) return ts;
19067
+ return d.toLocaleString(void 0, {
19068
+ month: "short",
19069
+ day: "numeric",
19070
+ hour: "2-digit",
19071
+ minute: "2-digit"
19072
+ });
19073
+ }
19074
+ function FieldAuditLog({
19075
+ events = [],
19076
+ loading = false,
19077
+ fields = []
19078
+ }) {
19079
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
19080
+ const fieldLabelMap = React45__default.default.useMemo(() => {
19081
+ var _a2;
19082
+ const map = {};
19083
+ for (const f of fields) map[f.field_key] = (_a2 = f.label) != null ? _a2 : f.field_key;
19084
+ return map;
19085
+ }, [fields]);
19086
+ if (loading) {
19087
+ return /* @__PURE__ */ jsxRuntime.jsx(
19088
+ "div",
19089
+ {
19090
+ style: {
19091
+ flex: 1,
19092
+ display: "flex",
19093
+ alignItems: "center",
19094
+ justifyContent: "center",
19095
+ padding: "32px 20px",
19096
+ fontSize: "13px",
19097
+ color: MUTED2
19098
+ },
19099
+ children: "Loading audit trail\u2026"
19100
+ }
19101
+ );
19102
+ }
19103
+ if (events.length === 0) {
19104
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19105
+ "div",
19106
+ {
19107
+ style: {
19108
+ flex: 1,
19109
+ display: "flex",
19110
+ flexDirection: "column",
19111
+ alignItems: "center",
19112
+ justifyContent: "center",
19113
+ gap: "6px",
19114
+ padding: "32px 20px",
19115
+ textAlign: "center"
19116
+ },
19117
+ children: [
19118
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "13.5px", fontWeight: 600, color: "var(--foreground)" }, children: "No changes yet" }),
19119
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2, maxWidth: "240px", lineHeight: 1.5 }, children: "Field corrections will appear here." })
19120
+ ]
19121
+ }
19122
+ );
19123
+ }
19124
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "hidden" }, children: [
19125
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "8px 14px 6px", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
19126
+ "span",
19127
+ {
19128
+ style: {
19129
+ fontSize: "11.5px",
19130
+ fontWeight: 600,
19131
+ color: MUTED2,
19132
+ textTransform: "uppercase",
19133
+ letterSpacing: "0.04em"
19134
+ },
19135
+ children: [
19136
+ events.length,
19137
+ " ",
19138
+ events.length === 1 ? "change" : "changes"
19139
+ ]
19140
+ }
19141
+ ) }),
19142
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { style: { listStyle: "none", margin: 0, padding: "0 0 16px", overflowY: "auto", flex: 1, minHeight: 0 }, children: events.map((ev) => {
19143
+ var _a2, _b;
19144
+ const rawLabel = (_a2 = fieldLabelMap[ev.field_key]) != null ? _a2 : ev.field_key;
19145
+ const label = prettyLabel(rawLabel);
19146
+ const isAI = ev.actor_type === "system" || ev.event_type === "ai_corrected" || ev.event_type === "ai_extracted";
19147
+ const actor = isAI ? "AI" : ev.actor_name || "Unknown";
19148
+ const eventLabel = isAI ? "Re-extracted" : "Corrected";
19149
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19150
+ "li",
19151
+ {
19152
+ "data-testid": "audit-row",
19153
+ style: { display: "flex", gap: "10px", padding: "10px 14px", borderBottom: `1px solid ${BORDER4}` },
19154
+ children: [
19155
+ /* @__PURE__ */ jsxRuntime.jsx(
19156
+ "div",
19157
+ {
19158
+ title: isAI ? "AI extraction" : actor,
19159
+ style: {
19160
+ flexShrink: 0,
19161
+ width: "28px",
19162
+ height: "28px",
19163
+ borderRadius: "50%",
19164
+ background: isAI ? "#dcfce7" : "#eff6ff",
19165
+ color: isAI ? "#15803d" : SECONDARY2,
19166
+ fontSize: "10.5px",
19167
+ fontWeight: 700,
19168
+ display: "flex",
19169
+ alignItems: "center",
19170
+ justifyContent: "center",
19171
+ marginTop: "1px"
19172
+ },
19173
+ children: isAI ? "\u2728" : initials(actor)
19174
+ }
19175
+ ),
19176
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "3px", flex: 1, minWidth: 0 }, children: [
19177
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "6px", flexWrap: "wrap" }, children: [
19178
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12.5px", fontWeight: 600, color: isAI ? "#15803d" : "var(--foreground)" }, children: actor }),
19179
+ /* @__PURE__ */ jsxRuntime.jsx(
19180
+ "span",
19181
+ {
19182
+ style: {
19183
+ fontSize: "10.5px",
19184
+ fontWeight: 600,
19185
+ color: MUTED2,
19186
+ background: PAPER2,
19187
+ borderRadius: "4px",
19188
+ padding: "1px 6px",
19189
+ whiteSpace: "nowrap",
19190
+ flexShrink: 0
19191
+ },
19192
+ children: eventLabel
19193
+ }
19194
+ ),
19195
+ /* @__PURE__ */ jsxRuntime.jsx(
19196
+ "span",
19197
+ {
19198
+ style: {
19199
+ fontSize: "12px",
19200
+ color: MUTED2,
19201
+ flex: 1,
19202
+ minWidth: 0,
19203
+ whiteSpace: "nowrap",
19204
+ overflow: "hidden",
19205
+ textOverflow: "ellipsis"
19206
+ },
19207
+ children: label
19208
+ }
19209
+ ),
19210
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: formatTs(ev.created_at) })
19211
+ ] }),
19212
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
19213
+ ev.previous_value != null && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19214
+ /* @__PURE__ */ jsxRuntime.jsx(
19215
+ "span",
19216
+ {
19217
+ style: {
19218
+ fontSize: "12px",
19219
+ fontFamily: "ui-monospace, monospace",
19220
+ color: MUTED2,
19221
+ textDecoration: "line-through"
19222
+ },
19223
+ children: ev.previous_value
19224
+ }
19225
+ ),
19226
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: BORDER4 }, children: "\u2192" })
19227
+ ] }),
19228
+ /* @__PURE__ */ jsxRuntime.jsx(
19229
+ "span",
19230
+ {
19231
+ style: {
19232
+ fontSize: "12px",
19233
+ fontFamily: "ui-monospace, monospace",
19234
+ fontWeight: 600,
19235
+ color: "var(--foreground)"
19236
+ },
19237
+ children: (_b = ev.new_value) != null ? _b : "\u2014"
19238
+ }
19239
+ )
19240
+ ] }),
19241
+ ev.reason && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: "2px 0 0", fontSize: "11.5px", color: MUTED2, fontStyle: "italic" }, children: [
19242
+ "\u201C",
19243
+ ev.reason,
19244
+ "\u201D"
19245
+ ] })
19246
+ ] })
19247
+ ]
19248
+ },
19249
+ ev.id
19250
+ );
19251
+ }) })
19252
+ ] });
19253
+ }
19254
+ var TIER_COLORS2 = {
19255
+ green: "#15803d",
19256
+ amber: "#f59e0b",
19257
+ red: "#dc2626"
19258
+ };
19259
+ function fieldColor2(f, secondary) {
19260
+ var _a2, _b;
19261
+ if (f.state === "corrected") return secondary;
19262
+ return (_b = TIER_COLORS2[(_a2 = f.confidence_tier) != null ? _a2 : "amber"]) != null ? _b : TIER_COLORS2.amber;
19263
+ }
19264
+ function hexToRgba2(hex, alpha) {
19265
+ const h = hex.replace("#", "");
19266
+ const r = parseInt(h.slice(0, 2), 16);
19267
+ const g = parseInt(h.slice(2, 4), 16);
19268
+ const b = parseInt(h.slice(4, 6), 16);
19269
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
19270
+ }
19271
+ function PageOverlay({
19272
+ page,
19273
+ fields,
19274
+ selectedKey,
19275
+ onSelect,
19276
+ secondary
19277
+ }) {
19278
+ const { PAPER: PAPER2, MUTED: MUTED2 } = useTheme();
19279
+ const imgRef = React45__default.default.useRef(null);
19280
+ const selectedBoxRef = React45__default.default.useRef(null);
19281
+ const [px, setPx] = React45__default.default.useState(null);
19282
+ React45__default.default.useEffect(() => {
19283
+ const el = imgRef.current;
19284
+ if (!el) return;
19285
+ const measure = () => {
19286
+ if (el.clientWidth && el.clientHeight) {
19287
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19288
+ }
19289
+ };
19290
+ measure();
19291
+ if (typeof ResizeObserver === "undefined") return;
19292
+ const ro = new ResizeObserver(measure);
19293
+ ro.observe(el);
19294
+ return () => ro.disconnect();
19295
+ }, [page.imageUrl]);
19296
+ React45__default.default.useEffect(() => {
19297
+ if (!selectedKey) return;
19298
+ if (!fields.some((f) => f.field_key === selectedKey && f.bbox)) return;
19299
+ const el = selectedBoxRef.current;
19300
+ if (el && typeof el.scrollIntoView === "function") {
19301
+ el.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
19302
+ }
19303
+ }, [selectedKey, fields, px]);
19304
+ const pagePts = { wPts: page.width_pt, hPts: page.height_pt };
19305
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: "100%", lineHeight: 0 }, children: [
19306
+ page.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
19307
+ "img",
19308
+ {
19309
+ ref: imgRef,
19310
+ src: page.imageUrl,
19311
+ alt: `Page ${page.page + 1}`,
19312
+ onLoad: () => {
19313
+ const el = imgRef.current;
19314
+ if (el && el.clientWidth && el.clientHeight) {
19315
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19316
+ }
19317
+ },
19318
+ style: { display: "block", width: "100%", height: "auto" }
19319
+ }
19320
+ ) : (
19321
+ // No resolved image (host couldn't resolve the raster) — keep the
19322
+ // aspect box so cards still make sense, but show nothing to overlay on.
19323
+ /* @__PURE__ */ jsxRuntime.jsxs(
19324
+ "div",
19325
+ {
19326
+ style: {
19327
+ width: "100%",
19328
+ aspectRatio: `${page.width_pt} / ${page.height_pt}`,
19329
+ background: PAPER2,
19330
+ display: "flex",
19331
+ alignItems: "center",
19332
+ justifyContent: "center",
19333
+ fontSize: "12px",
19334
+ color: MUTED2,
19335
+ lineHeight: 1.4
19336
+ },
19337
+ children: [
19338
+ "Page ",
19339
+ page.page + 1,
19340
+ " image unavailable"
19341
+ ]
19342
+ }
19343
+ )
19344
+ ),
19345
+ px && page.imageUrl && fields.map((f) => {
19346
+ var _a2;
19347
+ const rect = bboxToRect((_a2 = f.bbox) != null ? _a2 : null, pagePts, px);
19348
+ if (!rect) return null;
19349
+ const color = fieldColor2(f, secondary);
19350
+ const selected = selectedKey === f.field_key;
19351
+ return /* @__PURE__ */ jsxRuntime.jsx(
19352
+ "div",
19353
+ {
19354
+ ref: selected ? selectedBoxRef : null,
19355
+ "data-testid": "bbox-rect",
19356
+ "data-field-key": f.field_key,
19357
+ "data-selected": selected ? "true" : "false",
19358
+ onClick: () => onSelect(selected ? null : f.field_key),
19359
+ title: `${f.label}: ${f.value}`,
19360
+ style: {
19361
+ position: "absolute",
19362
+ left: `${rect.left}px`,
19363
+ top: `${rect.top}px`,
19364
+ width: `${rect.width}px`,
19365
+ height: `${rect.height}px`,
19366
+ border: `1px solid ${color}`,
19367
+ background: hexToRgba2(color, selected ? 0.28 : 0.12),
19368
+ boxShadow: selected ? `0 0 0 2px ${hexToRgba2(color, 0.5)}` : "none",
19369
+ borderRadius: "2px",
19370
+ cursor: "pointer",
19371
+ transition: "background 0.15s, box-shadow 0.15s"
19372
+ }
19373
+ },
19374
+ f.field_key
19375
+ );
19376
+ })
19377
+ ] });
19378
+ }
19379
+ function ExtractionDetail({
19380
+ pages,
19381
+ orderedFields,
19382
+ fieldsByPage,
19383
+ selectedKey,
19384
+ setSelectedKey,
19385
+ onFieldSave,
19386
+ correctionCounts,
19387
+ tab,
19388
+ setTab,
19389
+ editable,
19390
+ summary,
19391
+ fileName,
19392
+ pageCount,
19393
+ pagesProcessed,
19394
+ auditEvents,
19395
+ auditLoading
19396
+ }) {
19397
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
19398
+ const selectedCardRef = React45__default.default.useRef(null);
19399
+ React45__default.default.useEffect(() => {
19400
+ if (!selectedKey || tab !== "fields") return;
19401
+ const el = selectedCardRef.current;
19402
+ if (el && typeof el.scrollIntoView === "function") {
19403
+ el.scrollIntoView({ behavior: "smooth", block: "nearest" });
19404
+ }
19405
+ }, [selectedKey, tab]);
19406
+ const tabs = [
19407
+ { key: "details", label: "Details" },
19408
+ { key: "fields", label: "Fields", count: orderedFields.length }
19409
+ ];
19410
+ if (editable) tabs.push({ key: "audit", label: "Audit Trails", count: (auditEvents == null ? void 0 : auditEvents.length) || void 0 });
19411
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19412
+ "div",
19413
+ {
19414
+ style: {
19415
+ display: "grid",
19416
+ gridTemplateColumns: "minmax(0, 3fr) minmax(260px, 1fr)",
19417
+ gap: "12px",
19418
+ height: "100%",
19419
+ minHeight: 0
19420
+ },
19421
+ children: [
19422
+ /* @__PURE__ */ jsxRuntime.jsx(
19423
+ "div",
19424
+ {
19425
+ style: {
19426
+ display: "flex",
19427
+ flexDirection: "column",
19428
+ gap: "10px",
19429
+ borderRadius: "0.75rem",
19430
+ border: `1px solid ${BORDER4}`,
19431
+ overflowY: "auto",
19432
+ minHeight: 0
19433
+ },
19434
+ children: pages.map((pg) => /* @__PURE__ */ jsxRuntime.jsx(
19435
+ PageOverlay,
19436
+ {
19437
+ page: pg,
19438
+ fields: fieldsByPage(pg.page),
19439
+ selectedKey,
19440
+ onSelect: (key) => {
19441
+ setSelectedKey(key);
19442
+ if (key) setTab("fields");
19443
+ },
19444
+ secondary: SECONDARY2
19445
+ },
19446
+ pg.page
19447
+ ))
19448
+ }
19449
+ ),
19450
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", minWidth: 0, minHeight: 0 }, children: [
19451
+ /* @__PURE__ */ jsxRuntime.jsx(
19452
+ "div",
19453
+ {
19454
+ style: {
19455
+ display: "flex",
19456
+ gap: "16px",
19457
+ borderBottom: `1px solid ${BORDER4}`,
19458
+ flexShrink: 0,
19459
+ marginBottom: "10px"
19460
+ },
19461
+ children: tabs.map((t) => {
19462
+ const active = tab === t.key;
19463
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19464
+ "button",
19465
+ {
19466
+ type: "button",
19467
+ onClick: () => setTab(t.key),
19468
+ "data-testid": `tab-${t.key}`,
19469
+ style: {
19470
+ appearance: "none",
19471
+ background: "transparent",
19472
+ borderTop: "none",
19473
+ borderLeft: "none",
19474
+ borderRight: "none",
19475
+ borderBottom: `2px solid ${active ? SECONDARY2 : "transparent"}`,
19476
+ padding: "6px 2px",
19477
+ marginBottom: "-1px",
19478
+ cursor: "pointer",
19479
+ fontSize: "13px",
19480
+ fontWeight: 600,
19481
+ color: active ? SECONDARY2 : MUTED2,
19482
+ display: "inline-flex",
19483
+ alignItems: "center",
19484
+ gap: "6px"
19485
+ },
19486
+ children: [
19487
+ t.label,
19488
+ typeof t.count === "number" && /* @__PURE__ */ jsxRuntime.jsx(
19489
+ "span",
19490
+ {
19491
+ style: {
19492
+ fontSize: "11px",
19493
+ fontWeight: 600,
19494
+ padding: "1px 7px",
19495
+ borderRadius: "9999px",
19496
+ background: active ? "#eff6ff" : PAPER2,
19497
+ color: active ? SECONDARY2 : MUTED2
19498
+ },
19499
+ children: t.count
19500
+ }
19501
+ )
19502
+ ]
19503
+ },
19504
+ t.key
19505
+ );
19506
+ })
19507
+ }
19508
+ ),
19509
+ tab === "details" ? /* @__PURE__ */ jsxRuntime.jsx(
19510
+ FieldDetails,
19511
+ {
19512
+ summary,
19513
+ fileName,
19514
+ pageCount,
19515
+ pagesProcessed
19516
+ }
19517
+ ) : tab === "audit" ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: 0, overflowY: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(
19518
+ FieldAuditLog,
19519
+ {
19520
+ events: auditEvents != null ? auditEvents : [],
19521
+ loading: auditLoading != null ? auditLoading : false,
19522
+ fields: orderedFields.map((f) => ({ field_key: f.field_key, label: f.label }))
19523
+ }
19524
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs(
19525
+ "div",
19526
+ {
19527
+ style: {
19528
+ display: "flex",
19529
+ flexDirection: "column",
19530
+ minHeight: 0,
19531
+ overflowY: "auto",
19532
+ paddingRight: "4px"
19533
+ },
19534
+ children: [
19535
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "12px", color: MUTED2, padding: "0 0 8px 2px", flexShrink: 0 }, children: [
19536
+ orderedFields.length,
19537
+ " extracted"
19538
+ ] }),
19539
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: orderedFields.map((f) => {
19540
+ var _a2;
19541
+ const selected = selectedKey === f.field_key;
19542
+ return /* @__PURE__ */ jsxRuntime.jsx(
19543
+ FieldDetail,
19544
+ {
19545
+ field: f,
19546
+ selected,
19547
+ onSelect: setSelectedKey,
19548
+ onSave: onFieldSave,
19549
+ correctionCount: (_a2 = correctionCounts == null ? void 0 : correctionCounts[f.field_key]) != null ? _a2 : 0,
19550
+ cardRef: selected ? selectedCardRef : void 0
19551
+ },
19552
+ f.field_key
19553
+ );
19554
+ }) })
19555
+ ]
19556
+ }
19557
+ )
19558
+ ] })
19559
+ ]
19560
+ }
19561
+ );
19562
+ }
19563
+ function ExtractionModal({
19564
+ open,
19565
+ onClose,
19566
+ title,
19567
+ children
19568
+ }) {
19569
+ const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
19570
+ React45__default.default.useEffect(() => {
19571
+ if (!open) return;
19572
+ const onKey = (e) => {
19573
+ if (e.key === "Escape") onClose();
19574
+ };
19575
+ window.addEventListener("keydown", onKey);
19576
+ const prev = document.body.style.overflow;
19577
+ document.body.style.overflow = "hidden";
19578
+ return () => {
19579
+ window.removeEventListener("keydown", onKey);
19580
+ document.body.style.overflow = prev;
19581
+ };
19582
+ }, [open, onClose]);
19583
+ if (!open || typeof document === "undefined") return null;
19584
+ return reactDom.createPortal(
19585
+ /* @__PURE__ */ jsxRuntime.jsx(
19586
+ "div",
19587
+ {
19588
+ role: "dialog",
19589
+ "aria-modal": "true",
19590
+ "aria-label": title,
19591
+ onClick: onClose,
19592
+ style: {
19593
+ position: "fixed",
19594
+ inset: 0,
19595
+ zIndex: 2147483e3,
19596
+ background: "rgba(0,0,0,0.5)",
19597
+ display: "flex",
19598
+ alignItems: "center",
19599
+ justifyContent: "center",
19600
+ padding: "4vh 4vw",
19601
+ backdropFilter: "blur(2px)"
19602
+ },
19603
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
19604
+ "div",
19605
+ {
19606
+ onClick: (e) => e.stopPropagation(),
19607
+ style: {
19608
+ width: "90vw",
19609
+ height: "90vh",
19610
+ background: "white",
19611
+ borderRadius: "0.875rem",
19612
+ border: `1px solid ${BORDER4}`,
19613
+ boxShadow: "0 20px 60px rgba(0,0,0,0.30)",
19614
+ display: "flex",
19615
+ flexDirection: "column",
19616
+ overflow: "hidden"
19617
+ },
19618
+ children: [
19619
+ /* @__PURE__ */ jsxRuntime.jsxs(
19620
+ "div",
19621
+ {
19622
+ style: {
19623
+ display: "flex",
19624
+ alignItems: "center",
19625
+ gap: "10px",
19626
+ padding: "11px 16px",
19627
+ borderBottom: `1px solid ${BORDER4}`,
19628
+ flexShrink: 0
19629
+ },
19630
+ children: [
19631
+ /* @__PURE__ */ jsxRuntime.jsx(
19632
+ "span",
19633
+ {
19634
+ style: {
19635
+ flex: 1,
19636
+ minWidth: 0,
19637
+ fontFamily: "var(--font-serif)",
19638
+ fontSize: "16px",
19639
+ fontWeight: 400,
19640
+ letterSpacing: "-0.01em",
19641
+ color: "var(--foreground)",
19642
+ overflow: "hidden",
19643
+ textOverflow: "ellipsis",
19644
+ whiteSpace: "nowrap"
19645
+ },
19646
+ children: title
19647
+ }
19648
+ ),
19649
+ /* @__PURE__ */ jsxRuntime.jsx(
19650
+ "button",
19651
+ {
19652
+ type: "button",
19653
+ "aria-label": "Close",
19654
+ onClick: onClose,
19655
+ style: {
19656
+ border: `1px solid ${BORDER4}`,
19657
+ borderRadius: "8px",
19658
+ background: "white",
19659
+ cursor: "pointer",
19660
+ padding: "5px 9px",
19661
+ fontSize: "13px",
19662
+ color: MUTED2,
19663
+ lineHeight: 1
19664
+ },
19665
+ children: "\u2715"
19666
+ }
19667
+ )
19668
+ ]
19669
+ }
19670
+ ),
19671
+ /* @__PURE__ */ jsxRuntime.jsx(
19672
+ "div",
19673
+ {
19674
+ style: {
19675
+ flex: 1,
19676
+ minHeight: 0,
19677
+ overflow: "hidden",
19678
+ display: "flex",
19679
+ flexDirection: "column",
19680
+ padding: "14px 16px"
19681
+ },
19682
+ children
19683
+ }
19684
+ )
19685
+ ]
19686
+ }
19687
+ )
19688
+ }
19689
+ ),
19690
+ document.body
19691
+ );
19692
+ }
19693
+ function DocumentFieldExtractionResolver(p) {
19694
+ var _a2, _b;
19695
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
19696
+ const [selectedKey, setSelectedKey] = React45__default.default.useState(null);
19697
+ const [open, setOpen] = React45__default.default.useState(false);
19698
+ const [tab, setTab] = React45__default.default.useState("fields");
19699
+ const pages = (_a2 = p.pages) != null ? _a2 : [];
19700
+ const fields = (_b = p.fields) != null ? _b : [];
19701
+ const editable = typeof p.onFieldSave === "function";
19702
+ const onLoadAudit = p.onLoadAudit;
19703
+ React45__default.default.useEffect(() => {
19704
+ if (tab === "audit" && onLoadAudit) {
19705
+ onLoadAudit();
19706
+ }
19707
+ }, [tab, onLoadAudit]);
19708
+ const correctionCounts = React45__default.default.useMemo(() => {
19709
+ var _a3, _b2;
19710
+ const counts = {};
19711
+ for (const ev of (_a3 = p.auditEvents) != null ? _a3 : []) {
19712
+ const human = ev.actor_type !== "system" && ev.event_type !== "ai_extracted";
19713
+ if (human) counts[ev.field_key] = ((_b2 = counts[ev.field_key]) != null ? _b2 : 0) + 1;
19714
+ }
19715
+ return counts;
19716
+ }, [p.auditEvents]);
19717
+ const orderedFields = [...fields].sort((a, b) => {
19718
+ var _a3, _b2;
19719
+ if (!!a.is_primary !== !!b.is_primary) return a.is_primary ? -1 : 1;
19720
+ return ((_a3 = b.confidence) != null ? _a3 : 0) - ((_b2 = a.confidence) != null ? _b2 : 0);
19721
+ });
19722
+ const fieldsByPage = (pageNo) => fields.filter((f) => f.page === pageNo);
19723
+ const csvCols = [
19724
+ { key: "label", label: "Field" },
19725
+ { key: "value", label: "Value" },
19726
+ { key: "page", label: "Page" },
19727
+ { key: "confidence", label: "Confidence" },
19728
+ { key: "badge", label: "Badge" },
19729
+ { key: "state", label: "State" }
19730
+ ];
19731
+ const csvRows = orderedFields.map((f) => {
19732
+ var _a3, _b2, _c;
19733
+ return {
19734
+ label: f.label,
19735
+ value: f.value,
19736
+ page: f.page + 1,
19737
+ confidence: (_a3 = f.confidence) != null ? _a3 : "",
19738
+ badge: (_b2 = f.badge) != null ? _b2 : "",
19739
+ state: (_c = f.state) != null ? _c : ""
19740
+ };
19741
+ });
19742
+ const title = p.file_name || (p.doc_type ? `${p.doc_type} \u2014 extracted fields` : "Extracted fields");
19743
+ const tierCounts = fields.reduce(
19744
+ (acc, f) => {
19745
+ var _a3;
19746
+ const t = (_a3 = f.confidence_tier) != null ? _a3 : "amber";
19747
+ if (t === "green") acc.high += 1;
19748
+ else if (t === "red") acc.low += 1;
19749
+ else acc.med += 1;
19750
+ return acc;
19751
+ },
19752
+ { high: 0, med: 0, low: 0 }
19753
+ );
19754
+ const chips = [
19755
+ { n: tierCounts.high, label: "high", color: TIER_COLORS2.green },
19756
+ { n: tierCounts.med, label: "medium", color: TIER_COLORS2.amber },
19757
+ { n: tierCounts.low, label: "low", color: TIER_COLORS2.red }
19758
+ ].filter((c) => c.n > 0);
19759
+ const thumb = pages.find((pg) => pg.imageUrl);
19760
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19761
+ ComponentActions,
19762
+ {
19763
+ filename: "document-fields",
19764
+ onDownloadCSV: () => downloadCSV(csvCols, csvRows, "document-fields"),
19765
+ children: [
19766
+ /* @__PURE__ */ jsxRuntime.jsxs(
19767
+ "div",
19768
+ {
19769
+ role: "button",
19770
+ tabIndex: 0,
19771
+ onClick: () => setOpen(true),
19772
+ onKeyDown: (e) => {
19773
+ if (e.key === "Enter" || e.key === " ") {
19774
+ e.preventDefault();
19775
+ setOpen(true);
19776
+ }
19777
+ },
19778
+ style: {
19779
+ display: "flex",
19780
+ alignItems: "stretch",
19781
+ gap: "12px",
19782
+ padding: "12px",
19783
+ width: "100%",
19784
+ maxWidth: "440px",
19785
+ borderRadius: "0.75rem",
19786
+ border: `1px solid ${BORDER4}`,
19787
+ background: "white",
19788
+ cursor: "pointer",
19789
+ textAlign: "left",
19790
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.05)"
19791
+ },
19792
+ children: [
19793
+ /* @__PURE__ */ jsxRuntime.jsx(
19794
+ "div",
19795
+ {
19796
+ style: {
19797
+ width: "64px",
19798
+ flexShrink: 0,
19799
+ borderRadius: "0.5rem",
19800
+ border: `1px solid ${BORDER4}`,
19801
+ background: PAPER2,
19802
+ overflow: "hidden",
19803
+ display: "flex",
19804
+ alignItems: "center",
19805
+ justifyContent: "center"
19806
+ },
19807
+ children: (thumb == null ? void 0 : thumb.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx(
19808
+ "img",
19809
+ {
19810
+ src: thumb.imageUrl,
19811
+ alt: "Document preview",
19812
+ style: { width: "100%", height: "auto", display: "block" }
19813
+ }
19814
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "22px", lineHeight: 1, padding: "16px 0" }, children: "\u{1F4C4}" })
19815
+ }
19816
+ ),
19817
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "6px" }, children: [
19818
+ /* @__PURE__ */ jsxRuntime.jsx(
19819
+ "p",
19820
+ {
19821
+ style: {
19822
+ fontFamily: "var(--font-serif)",
19823
+ fontSize: "15px",
19824
+ fontWeight: 400,
19825
+ color: "var(--foreground)",
19826
+ letterSpacing: "-0.01em",
19827
+ margin: 0,
19828
+ overflow: "hidden",
19829
+ textOverflow: "ellipsis",
19830
+ whiteSpace: "nowrap"
19831
+ },
19832
+ children: p.file_name || p.doc_type || "Document"
19833
+ }
19834
+ ),
19835
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "12px", color: MUTED2 }, children: [
19836
+ fields.length,
19837
+ " field",
19838
+ fields.length === 1 ? "" : "s",
19839
+ " extracted \xB7 ",
19840
+ pages.length,
19841
+ " page",
19842
+ pages.length === 1 ? "" : "s"
19843
+ ] }),
19844
+ chips.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "5px" }, children: chips.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
19845
+ "span",
19846
+ {
19847
+ style: {
19848
+ display: "inline-flex",
19849
+ alignItems: "center",
19850
+ gap: "4px",
19851
+ fontSize: "10px",
19852
+ fontWeight: 600,
19853
+ padding: "2px 7px",
19854
+ borderRadius: "9999px",
19855
+ background: hexToRgba2(c.color, 0.12),
19856
+ color: c.color
19857
+ },
19858
+ children: [
19859
+ /* @__PURE__ */ jsxRuntime.jsx(
19860
+ "span",
19861
+ {
19862
+ style: {
19863
+ width: "6px",
19864
+ height: "6px",
19865
+ borderRadius: "9999px",
19866
+ background: c.color
19867
+ }
19868
+ }
19869
+ ),
19870
+ c.n,
19871
+ " ",
19872
+ c.label
19873
+ ]
19874
+ },
19875
+ c.label
19876
+ )) }),
19877
+ /* @__PURE__ */ jsxRuntime.jsx(
19878
+ "span",
19879
+ {
19880
+ style: {
19881
+ marginTop: "2px",
19882
+ alignSelf: "flex-start",
19883
+ fontSize: "12px",
19884
+ fontWeight: 600,
19885
+ padding: "6px 12px",
19886
+ borderRadius: "0.5rem",
19887
+ background: "var(--foreground)",
19888
+ color: "white"
19889
+ },
19890
+ children: "View & edit fields"
19891
+ }
19892
+ )
19893
+ ] })
19894
+ ]
19895
+ }
19896
+ ),
19897
+ /* @__PURE__ */ jsxRuntime.jsx(ExtractionModal, { open, onClose: () => setOpen(false), title, children: /* @__PURE__ */ jsxRuntime.jsx(
19898
+ ExtractionDetail,
19899
+ {
19900
+ pages,
19901
+ orderedFields,
19902
+ fieldsByPage,
19903
+ selectedKey,
19904
+ setSelectedKey,
19905
+ onFieldSave: p.onFieldSave,
19906
+ correctionCounts,
19907
+ tab,
19908
+ setTab,
19909
+ editable,
19910
+ summary: p.summary,
19911
+ fileName: p.file_name,
19912
+ pageCount: p.page_count,
19913
+ pagesProcessed: p.pages_processed,
19914
+ auditEvents: p.auditEvents,
19915
+ auditLoading: p.auditLoading
19916
+ }
19917
+ ) })
19918
+ ]
19919
+ }
19920
+ );
19921
+ }
19922
+ function DocumentFieldExtractionSkeleton() {
19923
+ const { BORDER: BORDER4, PAPER: PAPER2 } = useTheme();
19924
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19925
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
19926
+ @keyframes dfeSkeletonPulse {
19927
+ 0%, 100% { opacity: 1; }
19928
+ 50% { opacity: 0.45; }
19929
+ }
19930
+ ` }),
19931
+ /* @__PURE__ */ jsxRuntime.jsxs(
19932
+ "div",
19933
+ {
19934
+ "aria-busy": "true",
19935
+ "aria-label": "Loading extracted document",
19936
+ style: {
19937
+ display: "flex",
19938
+ alignItems: "stretch",
19939
+ gap: "12px",
19940
+ padding: "12px",
19941
+ width: "100%",
19942
+ maxWidth: "440px",
19943
+ borderRadius: "0.75rem",
19944
+ border: `1px solid ${BORDER4}`,
19945
+ background: "white",
19946
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.05)"
19947
+ },
19948
+ children: [
19949
+ /* @__PURE__ */ jsxRuntime.jsx(
19950
+ "div",
19951
+ {
19952
+ style: {
19953
+ width: "64px",
19954
+ flexShrink: 0,
19955
+ borderRadius: "0.5rem",
19956
+ border: `1px solid ${BORDER4}`,
19957
+ background: PAPER2,
19958
+ minHeight: "82px",
19959
+ animation: "dfeSkeletonPulse 1.6s ease-in-out infinite"
19960
+ }
19961
+ }
19962
+ ),
19963
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "8px", paddingTop: "2px" }, children: [
19964
+ /* @__PURE__ */ jsxRuntime.jsx(
19965
+ "div",
19966
+ {
19967
+ style: {
19968
+ height: "14px",
19969
+ width: "65%",
19970
+ borderRadius: "4px",
19971
+ background: PAPER2,
19972
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.08s infinite"
19973
+ }
19974
+ }
19975
+ ),
19976
+ /* @__PURE__ */ jsxRuntime.jsx(
19977
+ "div",
19978
+ {
19979
+ style: {
19980
+ height: "11px",
19981
+ width: "45%",
19982
+ borderRadius: "4px",
19983
+ background: PAPER2,
19984
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.14s infinite"
19985
+ }
19986
+ }
19987
+ ),
19988
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "5px" }, children: [
19989
+ /* @__PURE__ */ jsxRuntime.jsx(
19990
+ "div",
19991
+ {
19992
+ style: {
19993
+ height: "18px",
19994
+ width: "66px",
19995
+ borderRadius: "9999px",
19996
+ background: PAPER2,
19997
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.2s infinite"
19998
+ }
19999
+ }
20000
+ ),
20001
+ /* @__PURE__ */ jsxRuntime.jsx(
20002
+ "div",
20003
+ {
20004
+ style: {
20005
+ height: "18px",
20006
+ width: "56px",
20007
+ borderRadius: "9999px",
20008
+ background: PAPER2,
20009
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.25s infinite"
20010
+ }
20011
+ }
20012
+ )
20013
+ ] }),
20014
+ /* @__PURE__ */ jsxRuntime.jsx(
20015
+ "div",
20016
+ {
20017
+ style: {
20018
+ height: "28px",
20019
+ width: "122px",
20020
+ borderRadius: "0.5rem",
20021
+ background: PAPER2,
20022
+ marginTop: "2px",
20023
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.3s infinite"
20024
+ }
20025
+ }
20026
+ )
20027
+ ] })
20028
+ ]
20029
+ }
20030
+ )
20031
+ ] });
20032
+ }
20033
+ init_ThemeContext();
20034
+ var SEVERITY_COLORS = {
20035
+ high: { color: "#dc2626", bg: "#fef2f2" },
20036
+ medium: { color: "#f59e0b", bg: "#fff7ed" },
20037
+ low: { color: "#777777", bg: "#f2f2f2" }
20038
+ };
20039
+ var GREEN3 = "#15803d";
20040
+ var GREEN_SOFT = "#dcfce7";
20041
+ var STACK_BELOW = 380;
20042
+ function formatAmount2(amount, currency = "USD") {
20043
+ var _a2, _b;
20044
+ const abs = Math.abs(amount);
20045
+ const sign = amount < 0 ? "-" : "";
20046
+ let body;
20047
+ if (abs >= 1e6) body = `${(abs / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;
20048
+ else if (abs >= 1e3) body = `${(abs / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;
20049
+ else body = `${abs}`;
20050
+ let symbol = "$";
20051
+ try {
20052
+ const parts = new Intl.NumberFormat("en-US", {
20053
+ style: "currency",
20054
+ currency,
20055
+ maximumFractionDigits: 0
20056
+ }).formatToParts(0);
20057
+ symbol = (_b = (_a2 = parts.find((p) => p.type === "currency")) == null ? void 0 : _a2.value) != null ? _b : "$";
20058
+ } catch (e) {
20059
+ symbol = "$";
20060
+ }
20061
+ return `${sign}${symbol}${body}`;
20062
+ }
20063
+ function useContainerWidth2(ref) {
20064
+ const [w, setW] = React45__default.default.useState(0);
20065
+ React45__default.default.useLayoutEffect(() => {
20066
+ const el = ref.current;
20067
+ if (!el || typeof ResizeObserver === "undefined") return;
20068
+ const ro = new ResizeObserver((entries) => {
20069
+ var _a2;
20070
+ const cr = (_a2 = entries[0]) == null ? void 0 : _a2.contentRect;
20071
+ if (cr) setW(cr.width);
20072
+ });
20073
+ ro.observe(el);
20074
+ setW(el.getBoundingClientRect().width);
20075
+ return () => ro.disconnect();
20076
+ }, [ref]);
20077
+ return w;
20078
+ }
20079
+ var KEYFRAMES2 = `
20080
+ @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
20081
+ .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
20082
+ @media (prefers-reduced-motion: reduce){
20083
+ .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
20084
+ }`;
20085
+ function SparkCheck({ size, color }) {
20086
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
20087
+ "path",
20088
+ {
20089
+ d: "M5 13l4 4L19 7",
20090
+ stroke: color,
20091
+ strokeWidth: 2.5,
20092
+ strokeLinecap: "round",
20093
+ strokeLinejoin: "round"
20094
+ }
20095
+ ) });
20096
+ }
20097
+ function FlagPill({ flag }) {
20098
+ var _a2;
20099
+ const sev = (_a2 = flag.severity) != null ? _a2 : "medium";
20100
+ const { color, bg } = SEVERITY_COLORS[sev];
20101
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20102
+ "span",
20103
+ {
20104
+ style: {
20105
+ display: "inline-flex",
20106
+ alignItems: "center",
20107
+ gap: 5,
20108
+ fontSize: 11,
20109
+ fontWeight: 600,
20110
+ padding: "3px 9px",
20111
+ borderRadius: 9999,
20112
+ background: bg,
20113
+ color,
20114
+ lineHeight: 1.2
20115
+ },
20116
+ children: [
20117
+ /* @__PURE__ */ jsxRuntime.jsx(
20118
+ "span",
20119
+ {
20120
+ "aria-hidden": "true",
20121
+ style: { width: 6, height: 6, borderRadius: "50%", background: color, flexShrink: 0 }
20122
+ }
20123
+ ),
20124
+ flag.field ? `${flag.field}: ${flag.issue}` : flag.issue
18128
20125
  ]
18129
20126
  }
18130
20127
  );
@@ -18137,7 +20134,7 @@ function DecisionCardRenderer({
18137
20134
  }) {
18138
20135
  var _a2, _b;
18139
20136
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
18140
- const rootRef = React41__default.default.useRef(null);
20137
+ const rootRef = React45__default.default.useRef(null);
18141
20138
  const width = useContainerWidth2(rootRef);
18142
20139
  const stacked = width > 0 && width < STACK_BELOW;
18143
20140
  const options = (_a2 = data.options) != null ? _a2 : [];
@@ -18394,8 +20391,8 @@ function DecisionCardResolver(p) {
18394
20391
  const decisionId = (_a2 = p.id) != null ? _a2 : p.title;
18395
20392
  const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
18396
20393
  const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
18397
- const [localResolved, setLocalResolved] = React41__default.default.useState(initial);
18398
- React41__default.default.useEffect(() => {
20394
+ const [localResolved, setLocalResolved] = React45__default.default.useState(initial);
20395
+ React45__default.default.useEffect(() => {
18399
20396
  if (hostResolved !== void 0) setLocalResolved(hostResolved);
18400
20397
  }, [hostResolved]);
18401
20398
  const resolved = hostResolved != null ? hostResolved : localResolved;
@@ -18420,6 +20417,317 @@ function DecisionCardResolver(p) {
18420
20417
  }
18421
20418
  ) });
18422
20419
  }
20420
+ init_ThemeContext();
20421
+ var CONNECTED_GREEN3 = "#15803d";
20422
+ var CONNECTED_GREEN_BG = "#dcfce7";
20423
+ var PENDING_AMBER = "#92400e";
20424
+ var PENDING_AMBER_BG = "#fff7ed";
20425
+ var CARD_TITLE = "Authentication required";
20426
+ var TRUST_FOOTER = "Credentials not stored by Adopt";
20427
+ var DEFAULT_STEPS = (app, ctaLabel, connected) => connected ? [
20428
+ `Click ${ctaLabel} below to open ${app} in a new tab.`,
20429
+ "Confirm you are signed in \u2014 re-authenticate if prompted.",
20430
+ "Return here \u2014 the request continues automatically."
20431
+ ] : [
20432
+ `Click ${ctaLabel} below to open the sign-in page.`,
20433
+ `Sign in with your ${app} credentials \u2014 SSO is supported.`,
20434
+ "Return here \u2014 the request resumes automatically."
20435
+ ];
20436
+ function humanizeApp(raw) {
20437
+ const v = raw.trim();
20438
+ if (!v) return v;
20439
+ const looksLikeSlug = /^[a-z0-9]+([_-][a-z0-9]+)*$/.test(v);
20440
+ if (!looksLikeSlug) return v;
20441
+ return v.split(/[_-]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
20442
+ }
20443
+ function ShieldIcon({ color }) {
20444
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20445
+ "svg",
20446
+ {
20447
+ width: "13",
20448
+ height: "13",
20449
+ viewBox: "0 0 24 24",
20450
+ fill: "none",
20451
+ stroke: color,
20452
+ strokeWidth: "2",
20453
+ strokeLinecap: "round",
20454
+ strokeLinejoin: "round",
20455
+ "aria-hidden": "true",
20456
+ style: { flexShrink: 0 },
20457
+ children: [
20458
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
20459
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 12 2 2 4-4" })
20460
+ ]
20461
+ }
20462
+ );
20463
+ }
20464
+ function ExternalIcon() {
20465
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20466
+ "svg",
20467
+ {
20468
+ width: "13",
20469
+ height: "13",
20470
+ viewBox: "0 0 24 24",
20471
+ fill: "none",
20472
+ stroke: "currentColor",
20473
+ strokeWidth: "2",
20474
+ strokeLinecap: "round",
20475
+ strokeLinejoin: "round",
20476
+ "aria-hidden": "true",
20477
+ style: { flexShrink: 0 },
20478
+ children: [
20479
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 3h6v6" }),
20480
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 14 21 3" }),
20481
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" })
20482
+ ]
20483
+ }
20484
+ );
20485
+ }
20486
+ function TabbyAuthResolver(p) {
20487
+ var _a2, _b, _c;
20488
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
20489
+ const [cardHovered, setCardHovered] = React45.useState(false);
20490
+ const [btnHovered, setBtnHovered] = React45.useState(false);
20491
+ const [imgFailed, setImgFailed] = React45.useState(false);
20492
+ const app = humanizeApp(p.app || "the app");
20493
+ const connected = p.state === "connected";
20494
+ const accent = connected ? CONNECTED_GREEN3 : ACCENT2;
20495
+ const ctaLabel = (_a2 = p.ctaLabel) != null ? _a2 : connected ? `Open ${app}` : `Connect ${app}`;
20496
+ const subtitle = p.workspace ? `${app} \xB7 ${p.workspace} workspace` : app;
20497
+ const steps = ((_b = p.steps) == null ? void 0 : _b.length) ? p.steps : DEFAULT_STEPS(app, ctaLabel, connected);
20498
+ const description = (_c = p.description) != null ? _c : connected ? `Your ${app} session is active. Open ${app} to continue, or re-authenticate if prompted.` : `Your ${app} account is not yet connected to this workspace. Complete sign-in once to enable automatic access.`;
20499
+ const iconSrc = p.iconUrl || brandIconUrl(app);
20500
+ const showImg = Boolean(iconSrc) && !imgFailed;
20501
+ const initial = app.charAt(0).toUpperCase();
20502
+ const badge = connected ? { label: "Connected", bg: CONNECTED_GREEN_BG, color: CONNECTED_GREEN3 } : { label: "Pending sign-in", bg: PENDING_AMBER_BG, color: PENDING_AMBER };
20503
+ const sectionPad = "13px 16px";
20504
+ return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: `${app} authentication`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "10px" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
20505
+ "div",
20506
+ {
20507
+ onMouseEnter: () => setCardHovered(true),
20508
+ onMouseLeave: () => setCardHovered(false),
20509
+ style: {
20510
+ display: "flex",
20511
+ flexDirection: "row",
20512
+ alignItems: "stretch",
20513
+ borderRadius: "0.75rem",
20514
+ border: `1px solid ${cardHovered ? "#d2d2d2" : BORDER4}`,
20515
+ background: "white",
20516
+ overflow: "hidden",
20517
+ boxShadow: cardHovered ? "0 1px 3px rgba(0,0,0,0.05), 0 6px 18px rgba(0,0,0,0.06)" : "0 1px 2px rgba(0,0,0,0.03)",
20518
+ transition: "box-shadow 0.18s ease, border-color 0.18s ease"
20519
+ },
20520
+ children: [
20521
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "3px", flexShrink: 0, background: accent } }),
20522
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }, children: [
20523
+ /* @__PURE__ */ jsxRuntime.jsxs(
20524
+ "div",
20525
+ {
20526
+ style: {
20527
+ display: "flex",
20528
+ alignItems: "flex-start",
20529
+ gap: "12px",
20530
+ padding: sectionPad
20531
+ },
20532
+ children: [
20533
+ /* @__PURE__ */ jsxRuntime.jsx(
20534
+ "div",
20535
+ {
20536
+ style: {
20537
+ position: "relative",
20538
+ width: "34px",
20539
+ height: "34px",
20540
+ borderRadius: "9px",
20541
+ flexShrink: 0,
20542
+ display: "flex",
20543
+ alignItems: "center",
20544
+ justifyContent: "center",
20545
+ background: showImg ? "white" : "#fff3ee",
20546
+ boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.06)",
20547
+ overflow: "hidden"
20548
+ },
20549
+ children: showImg ? /* @__PURE__ */ jsxRuntime.jsx(
20550
+ "img",
20551
+ {
20552
+ src: iconSrc,
20553
+ alt: app,
20554
+ onError: () => setImgFailed(true),
20555
+ style: { width: "22px", height: "22px", objectFit: "contain" }
20556
+ }
20557
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
20558
+ "span",
20559
+ {
20560
+ style: {
20561
+ fontFamily: "var(--font-serif)",
20562
+ fontSize: "17px",
20563
+ fontWeight: 400,
20564
+ color: ACCENT2,
20565
+ lineHeight: 1
20566
+ },
20567
+ children: initial
20568
+ }
20569
+ )
20570
+ }
20571
+ ),
20572
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "2px" }, children: [
20573
+ /* @__PURE__ */ jsxRuntime.jsx(
20574
+ "span",
20575
+ {
20576
+ style: {
20577
+ fontFamily: "var(--font-serif)",
20578
+ fontSize: "15px",
20579
+ fontWeight: 400,
20580
+ color: "var(--foreground)",
20581
+ letterSpacing: "-0.01em",
20582
+ lineHeight: 1.2
20583
+ },
20584
+ children: CARD_TITLE
20585
+ }
20586
+ ),
20587
+ /* @__PURE__ */ jsxRuntime.jsx(
20588
+ "span",
20589
+ {
20590
+ style: {
20591
+ fontSize: "12px",
20592
+ color: MUTED2,
20593
+ whiteSpace: "nowrap",
20594
+ overflow: "hidden",
20595
+ textOverflow: "ellipsis"
20596
+ },
20597
+ children: subtitle
20598
+ }
20599
+ )
20600
+ ] }),
20601
+ /* @__PURE__ */ jsxRuntime.jsxs(
20602
+ "span",
20603
+ {
20604
+ style: {
20605
+ display: "inline-flex",
20606
+ alignItems: "center",
20607
+ gap: "5px",
20608
+ flexShrink: 0,
20609
+ fontSize: "10.5px",
20610
+ fontWeight: 600,
20611
+ padding: "3px 9px",
20612
+ borderRadius: "9999px",
20613
+ background: badge.bg,
20614
+ color: badge.color,
20615
+ whiteSpace: "nowrap"
20616
+ },
20617
+ children: [
20618
+ /* @__PURE__ */ jsxRuntime.jsx(
20619
+ "span",
20620
+ {
20621
+ style: {
20622
+ width: "6px",
20623
+ height: "6px",
20624
+ borderRadius: "9999px",
20625
+ background: badge.color
20626
+ }
20627
+ }
20628
+ ),
20629
+ badge.label
20630
+ ]
20631
+ }
20632
+ )
20633
+ ]
20634
+ }
20635
+ ),
20636
+ /* @__PURE__ */ jsxRuntime.jsxs(
20637
+ "div",
20638
+ {
20639
+ style: {
20640
+ borderTop: `1px solid ${BORDER4}`,
20641
+ padding: sectionPad,
20642
+ display: "flex",
20643
+ flexDirection: "column",
20644
+ gap: "12px"
20645
+ },
20646
+ children: [
20647
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12.5px", lineHeight: 1.5, color: "var(--foreground)" }, children: description }),
20648
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { style: { margin: 0, padding: 0, listStyle: "none", display: "flex", flexDirection: "column", gap: "8px" }, children: steps.map((step, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: { display: "flex", alignItems: "flex-start", gap: "10px" }, children: [
20649
+ /* @__PURE__ */ jsxRuntime.jsx(
20650
+ "span",
20651
+ {
20652
+ style: {
20653
+ flexShrink: 0,
20654
+ width: "18px",
20655
+ height: "18px",
20656
+ borderRadius: "9999px",
20657
+ background: accent,
20658
+ color: "white",
20659
+ fontSize: "10.5px",
20660
+ fontWeight: 600,
20661
+ display: "flex",
20662
+ alignItems: "center",
20663
+ justifyContent: "center",
20664
+ marginTop: "1px"
20665
+ },
20666
+ children: i + 1
20667
+ }
20668
+ ),
20669
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12.5px", lineHeight: 1.45, color: "var(--foreground)" }, children: step })
20670
+ ] }, i)) })
20671
+ ]
20672
+ }
20673
+ ),
20674
+ /* @__PURE__ */ jsxRuntime.jsxs(
20675
+ "div",
20676
+ {
20677
+ style: {
20678
+ borderTop: `1px solid ${BORDER4}`,
20679
+ padding: sectionPad,
20680
+ background: "#fbfbfb",
20681
+ display: "flex",
20682
+ alignItems: "center",
20683
+ justifyContent: "space-between",
20684
+ gap: "12px",
20685
+ flexWrap: "wrap"
20686
+ },
20687
+ children: [
20688
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px", color: MUTED2, fontSize: "11.5px" }, children: [
20689
+ /* @__PURE__ */ jsxRuntime.jsx(ShieldIcon, { color: CONNECTED_GREEN3 }),
20690
+ TRUST_FOOTER
20691
+ ] }),
20692
+ /* @__PURE__ */ jsxRuntime.jsxs(
20693
+ "a",
20694
+ {
20695
+ href: p.url,
20696
+ target: "_blank",
20697
+ rel: "noopener noreferrer",
20698
+ onMouseEnter: () => setBtnHovered(true),
20699
+ onMouseLeave: () => setBtnHovered(false),
20700
+ style: {
20701
+ display: "inline-flex",
20702
+ alignItems: "center",
20703
+ gap: "7px",
20704
+ flexShrink: 0,
20705
+ borderRadius: "8px",
20706
+ padding: "8px 15px",
20707
+ fontSize: "12.5px",
20708
+ fontWeight: 600,
20709
+ textDecoration: "none",
20710
+ whiteSpace: "nowrap",
20711
+ cursor: "pointer",
20712
+ color: "white",
20713
+ border: "1px solid transparent",
20714
+ background: btnHovered ? connected ? "#126a33" : ACCENT_SOFT2 : accent,
20715
+ transition: "background 0.15s ease"
20716
+ },
20717
+ children: [
20718
+ /* @__PURE__ */ jsxRuntime.jsx(ExternalIcon, {}),
20719
+ ctaLabel
20720
+ ]
20721
+ }
20722
+ )
20723
+ ]
20724
+ }
20725
+ )
20726
+ ] })
20727
+ ]
20728
+ }
20729
+ ) }) });
20730
+ }
18423
20731
  function resolveUI(rawPayload) {
18424
20732
  const payload = coercePayload(rawPayload);
18425
20733
  switch (payload.type) {
@@ -18537,8 +20845,12 @@ function resolveUI(rawPayload) {
18537
20845
  return /* @__PURE__ */ jsxRuntime.jsx(PipelinePreviewResolver, __spreadValues({}, payload));
18538
20846
  case "workflow-stepper":
18539
20847
  return /* @__PURE__ */ jsxRuntime.jsx(WorkflowStepperResolver, __spreadValues({}, payload));
20848
+ case "document-field-extraction":
20849
+ return /* @__PURE__ */ jsxRuntime.jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
18540
20850
  case "decision-card":
18541
20851
  return /* @__PURE__ */ jsxRuntime.jsx(DecisionCardResolver, __spreadValues({}, payload));
20852
+ case "tabby-auth":
20853
+ return /* @__PURE__ */ jsxRuntime.jsx(TabbyAuthResolver, __spreadValues({}, payload));
18542
20854
  default: {
18543
20855
  return /* @__PURE__ */ jsxRuntime.jsx(
18544
20856
  "div",
@@ -18580,7 +20892,7 @@ function InlineSpinner() {
18580
20892
  }
18581
20893
  function GenUIRenderer({ payload }) {
18582
20894
  return /* @__PURE__ */ jsxRuntime.jsx(
18583
- React41.Suspense,
20895
+ React45.Suspense,
18584
20896
  {
18585
20897
  fallback: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", padding: "8px 0" }, children: [
18586
20898
  /* @__PURE__ */ jsxRuntime.jsx(InlineSpinner, {}),
@@ -18721,7 +21033,7 @@ var INPUT_ERROR = { borderColor: "#dc2626" };
18721
21033
  var SELECT_EXTRA = { cursor: "pointer" };
18722
21034
  function useInputBase() {
18723
21035
  const { BORDER: BORDER4 } = useTheme();
18724
- return React41.useMemo(() => ({
21036
+ return React45.useMemo(() => ({
18725
21037
  font: "inherit",
18726
21038
  fontSize: "13px",
18727
21039
  padding: "7px 10px",
@@ -18802,7 +21114,7 @@ function SelectField({ field, value, onChange, disabled, error }) {
18802
21114
  }
18803
21115
  function MultiSelectField({ field, value, onChange, disabled }) {
18804
21116
  const { MUTED: MUTED2, ACCENT: ACCENT2, BORDER: BORDER4 } = useTheme();
18805
- const [hovered, setHovered] = React41.useState(null);
21117
+ const [hovered, setHovered] = React45.useState(null);
18806
21118
  const options = field.options || [];
18807
21119
  const selected = Array.isArray(value) ? value : [];
18808
21120
  const toggle = (optValue) => {
@@ -18919,8 +21231,8 @@ function DocGlyph({ color }) {
18919
21231
  }
18920
21232
  function FileUploadField({ field, value, onChange, disabled, onFileUpload, error, dense }) {
18921
21233
  const { MUTED: MUTED2, ACCENT: ACCENT2, BORDER: BORDER4, PAPER: PAPER2 } = useTheme();
18922
- const keyRef = React41__default.default.useRef(0);
18923
- const [entries, setEntries] = React41.useState(() => {
21234
+ const keyRef = React45__default.default.useRef(0);
21235
+ const [entries, setEntries] = React45.useState(() => {
18924
21236
  const arr = Array.isArray(value) ? value : value && typeof value === "object" ? [value] : [];
18925
21237
  return arr.map((item) => {
18926
21238
  var _a2, _b;
@@ -18928,11 +21240,11 @@ function FileUploadField({ field, value, onChange, disabled, onFileUpload, error
18928
21240
  return { key: keyRef.current += 1, name: (_b = (_a2 = r.filename) != null ? _a2 : r.name) != null ? _b : "file", size: r.size, status: "done", result: r };
18929
21241
  });
18930
21242
  });
18931
- const entriesRef = React41__default.default.useRef(entries);
21243
+ const entriesRef = React45__default.default.useRef(entries);
18932
21244
  entriesRef.current = entries;
18933
- const [dragOver, setDragOver] = React41.useState(false);
18934
- const inputRef = React41__default.default.useRef(null);
18935
- React41__default.default.useEffect(() => {
21245
+ const [dragOver, setDragOver] = React45.useState(false);
21246
+ const inputRef = React45__default.default.useRef(null);
21247
+ React45__default.default.useEffect(() => {
18936
21248
  ensureFileUploadKeyframes();
18937
21249
  }, []);
18938
21250
  const interactive = !disabled;
@@ -19063,24 +21375,24 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
19063
21375
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, PAPER: PAPER2 } = useTheme();
19064
21376
  const base = useInputBase();
19065
21377
  const source = field.source || "";
19066
- const [open, setOpen] = React41.useState(false);
19067
- const [query, setQuery] = React41.useState("");
19068
- const [results, setResults] = React41.useState([]);
19069
- const [loading, setLoading] = React41.useState(false);
19070
- const [err, setErr] = React41.useState(null);
19071
- const [hi, setHi] = React41.useState(0);
19072
- const [selectedLabel, setSelectedLabel] = React41.useState(null);
19073
- const [creating, setCreating] = React41.useState(false);
19074
- const [createVals, setCreateVals] = React41.useState({});
19075
- const [createBusy, setCreateBusy] = React41.useState(false);
19076
- const boxRef = React41.useRef(null);
19077
- const seq = React41.useRef(0);
21378
+ const [open, setOpen] = React45.useState(false);
21379
+ const [query, setQuery] = React45.useState("");
21380
+ const [results, setResults] = React45.useState([]);
21381
+ const [loading, setLoading] = React45.useState(false);
21382
+ const [err, setErr] = React45.useState(null);
21383
+ const [hi, setHi] = React45.useState(0);
21384
+ const [selectedLabel, setSelectedLabel] = React45.useState(null);
21385
+ const [creating, setCreating] = React45.useState(false);
21386
+ const [createVals, setCreateVals] = React45.useState({});
21387
+ const [createBusy, setCreateBusy] = React45.useState(false);
21388
+ const boxRef = React45.useRef(null);
21389
+ const seq = React45.useRef(0);
19078
21390
  const allowCreate = !!field.allow_create && !!onEntityCreate;
19079
- const createFields = React41.useMemo(
21391
+ const createFields = React45.useMemo(
19080
21392
  () => field.create_fields && field.create_fields.length ? field.create_fields : [{ name: "name", label: "Name", field_type: "text", required: true, placeholder: "" }],
19081
21393
  [field.create_fields]
19082
21394
  );
19083
- const runSearch = React41.useCallback(
21395
+ const runSearch = React45.useCallback(
19084
21396
  (q) => {
19085
21397
  if (!onEntitySearch || !source) return;
19086
21398
  const my = ++seq.current;
@@ -19102,12 +21414,12 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
19102
21414
  },
19103
21415
  [onEntitySearch, source]
19104
21416
  );
19105
- React41.useEffect(() => {
21417
+ React45.useEffect(() => {
19106
21418
  if (!open || creating) return;
19107
21419
  const id = setTimeout(() => runSearch(query), 200);
19108
21420
  return () => clearTimeout(id);
19109
21421
  }, [open, creating, query, runSearch]);
19110
- React41.useEffect(() => {
21422
+ React45.useEffect(() => {
19111
21423
  if (!open) return;
19112
21424
  const onDoc = (e) => {
19113
21425
  if (boxRef.current && !boxRef.current.contains(e.target)) {
@@ -19122,7 +21434,7 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
19122
21434
  if (disabled) return;
19123
21435
  setOpen(true);
19124
21436
  };
19125
- const select = React41.useCallback((opt) => {
21437
+ const select = React45.useCallback((opt) => {
19126
21438
  onChange({ value: opt.value, label: opt.label });
19127
21439
  setSelectedLabel(opt.label);
19128
21440
  setQuery("");
@@ -19136,14 +21448,14 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
19136
21448
  const otherRequired = createFields.filter((f) => f !== nameField && f.required);
19137
21449
  const showCreateRow = allowCreate && !creating && query.trim().length > 0;
19138
21450
  const totalRows = results.length + (showCreateRow ? 1 : 0);
19139
- const beginCreate = React41.useCallback(() => {
21451
+ const beginCreate = React45.useCallback(() => {
19140
21452
  const init = {};
19141
21453
  if (nameField && query.trim()) init[nameField.name] = query.trim();
19142
21454
  setCreateVals(init);
19143
21455
  setErr(null);
19144
21456
  setCreating(true);
19145
21457
  }, [nameField, query]);
19146
- const submitCreate = React41.useCallback((vals) => {
21458
+ const submitCreate = React45.useCallback((vals) => {
19147
21459
  if (!onEntityCreate || !source) return;
19148
21460
  const payload = vals || createVals;
19149
21461
  for (const f of createFields) {
@@ -19156,7 +21468,7 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
19156
21468
  setErr(null);
19157
21469
  onEntityCreate(source, payload).then((opt) => select(opt)).catch(() => setErr("Couldn't create \u2014 you may not have permission")).finally(() => setCreateBusy(false));
19158
21470
  }, [onEntityCreate, source, createFields, createVals, select]);
19159
- const handleCreateRow = React41.useCallback(() => {
21471
+ const handleCreateRow = React45.useCallback(() => {
19160
21472
  const q = query.trim();
19161
21473
  if (!q || !nameField) return;
19162
21474
  if (otherRequired.length === 0) {
@@ -19338,11 +21650,11 @@ function _fileExt(path, type) {
19338
21650
  function FileMapField({ field, value, onChange, disabled }) {
19339
21651
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, PAPER: PAPER2 } = useTheme();
19340
21652
  const cfg = field.file_map || null;
19341
- const categories = React41.useMemo(() => (cfg == null ? void 0 : cfg.categories) || [], [cfg]);
19342
- const fileList = React41.useMemo(() => (cfg == null ? void 0 : cfg.files) || [], [cfg]);
21653
+ const categories = React45.useMemo(() => (cfg == null ? void 0 : cfg.categories) || [], [cfg]);
21654
+ const fileList = React45.useMemo(() => (cfg == null ? void 0 : cfg.files) || [], [cfg]);
19343
21655
  const suggestions = (cfg == null ? void 0 : cfg.suggestions) || {};
19344
21656
  const confidence = (cfg == null ? void 0 : cfg.confidence) || {};
19345
- const initial = React41.useMemo(() => {
21657
+ const initial = React45.useMemo(() => {
19346
21658
  const a = {};
19347
21659
  if (value && typeof value === "object" && !Array.isArray(value)) {
19348
21660
  for (const [grp, paths] of Object.entries(value))
@@ -19354,15 +21666,15 @@ function FileMapField({ field, value, onChange, disabled }) {
19354
21666
  for (const f of fileList) if (!(f.path in a)) a[f.path] = _FILEMAP_UNASSIGNED;
19355
21667
  return a;
19356
21668
  }, []);
19357
- const [assignment, setAssignment] = React41.useState(initial);
19358
- const [collapsed, setCollapsed] = React41.useState({});
19359
- const [menuFor, setMenuFor] = React41.useState(null);
19360
- const boardRef = React41.useRef(null);
19361
- const fileByPath = React41.useMemo(
21669
+ const [assignment, setAssignment] = React45.useState(initial);
21670
+ const [collapsed, setCollapsed] = React45.useState({});
21671
+ const [menuFor, setMenuFor] = React45.useState(null);
21672
+ const boardRef = React45.useRef(null);
21673
+ const fileByPath = React45.useMemo(
19362
21674
  () => Object.fromEntries(fileList.map((f) => [f.path, f])),
19363
21675
  [fileList]
19364
21676
  );
19365
- const groupFrom = React41.useCallback((a) => {
21677
+ const groupFrom = React45.useCallback((a) => {
19366
21678
  const g = { [_FILEMAP_UNASSIGNED]: [] };
19367
21679
  for (const c of categories) g[c.id] = [];
19368
21680
  for (const f of fileList) {
@@ -19372,16 +21684,16 @@ function FileMapField({ field, value, onChange, disabled }) {
19372
21684
  }
19373
21685
  return g;
19374
21686
  }, [categories, fileList]);
19375
- const grouped = React41.useMemo(() => groupFrom(assignment), [assignment, groupFrom]);
19376
- const emit = React41.useCallback((g) => onChange(g), [onChange]);
19377
- const emittedRef = React41.useRef(false);
19378
- React41.useEffect(() => {
21687
+ const grouped = React45.useMemo(() => groupFrom(assignment), [assignment, groupFrom]);
21688
+ const emit = React45.useCallback((g) => onChange(g), [onChange]);
21689
+ const emittedRef = React45.useRef(false);
21690
+ React45.useEffect(() => {
19379
21691
  if (!emittedRef.current) {
19380
21692
  emittedRef.current = true;
19381
21693
  emit(grouped);
19382
21694
  }
19383
21695
  }, [grouped, emit]);
19384
- React41.useEffect(() => {
21696
+ React45.useEffect(() => {
19385
21697
  if (!menuFor) return;
19386
21698
  const onDoc = (e) => {
19387
21699
  if (boardRef.current && !boardRef.current.contains(e.target)) setMenuFor(null);
@@ -19389,7 +21701,7 @@ function FileMapField({ field, value, onChange, disabled }) {
19389
21701
  document.addEventListener("mousedown", onDoc);
19390
21702
  return () => document.removeEventListener("mousedown", onDoc);
19391
21703
  }, [menuFor]);
19392
- const move = React41.useCallback((path, grp) => {
21704
+ const move = React45.useCallback((path, grp) => {
19393
21705
  setMenuFor(null);
19394
21706
  setAssignment((prev) => {
19395
21707
  const next = __spreadProps(__spreadValues({}, prev), { [path]: grp });
@@ -19539,7 +21851,7 @@ function FieldRenderer({ field, value, onChange, disabled, error, onFileUpload,
19539
21851
  ] });
19540
21852
  }
19541
21853
  init_ThemeContext();
19542
- var SlotErrorBoundary = class extends React41__default.default.Component {
21854
+ var SlotErrorBoundary = class extends React45__default.default.Component {
19543
21855
  constructor(props) {
19544
21856
  super(props);
19545
21857
  this.state = { hasError: false };
@@ -19624,7 +21936,7 @@ function BuilderRecap({ builder, state }) {
19624
21936
  return String(value);
19625
21937
  };
19626
21938
  const decisionField = (b) => (b.fields || []).find((f) => f.field_type === "select") || (b.fields || [])[0];
19627
- const rows = React41.useMemo(
21939
+ const rows = React45.useMemo(
19628
21940
  () => blocks.map((b) => {
19629
21941
  const df = decisionField(b);
19630
21942
  const decision = df ? display(df, state.getValue(b.id, df.name)) : "";
@@ -19634,7 +21946,7 @@ function BuilderRecap({ builder, state }) {
19634
21946
  // eslint-disable-next-line react-hooks/exhaustive-deps
19635
21947
  [blocks, state.values]
19636
21948
  );
19637
- const counts = React41.useMemo(() => {
21949
+ const counts = React45.useMemo(() => {
19638
21950
  const m = /* @__PURE__ */ new Map();
19639
21951
  for (const r of rows) {
19640
21952
  const k = r.decision || "\u2014";
@@ -19772,7 +22084,7 @@ function isRequiredMissing(fieldType, v) {
19772
22084
  }
19773
22085
  function useBuilderState(blocks) {
19774
22086
  const isMultiBlock = blocks.length > 1;
19775
- const [values, setValues] = React41.useState(() => {
22087
+ const [values, setValues] = React45.useState(() => {
19776
22088
  const init = {};
19777
22089
  for (const block of blocks) {
19778
22090
  for (const field of block.fields || []) {
@@ -19781,17 +22093,17 @@ function useBuilderState(blocks) {
19781
22093
  }
19782
22094
  return init;
19783
22095
  });
19784
- const [errors, setErrors] = React41.useState({});
19785
- const [currentBlock, setCurrentBlock] = React41.useState(0);
19786
- const getValue = React41.useCallback(
22096
+ const [errors, setErrors] = React45.useState({});
22097
+ const [currentBlock, setCurrentBlock] = React45.useState(0);
22098
+ const getValue = React45.useCallback(
19787
22099
  (blockId, name) => values[fieldKey(blockId, name)],
19788
22100
  [values]
19789
22101
  );
19790
- const getError = React41.useCallback(
22102
+ const getError = React45.useCallback(
19791
22103
  (blockId, name) => errors[fieldKey(blockId, name)],
19792
22104
  [errors]
19793
22105
  );
19794
- const setFieldValue = React41.useCallback((blockId, name, value) => {
22106
+ const setFieldValue = React45.useCallback((blockId, name, value) => {
19795
22107
  const k = fieldKey(blockId, name);
19796
22108
  setValues((prev) => __spreadProps(__spreadValues({}, prev), { [k]: value }));
19797
22109
  setErrors((prev) => {
@@ -19801,7 +22113,7 @@ function useBuilderState(blocks) {
19801
22113
  return next;
19802
22114
  });
19803
22115
  }, []);
19804
- const validateBlock = React41.useCallback(
22116
+ const validateBlock = React45.useCallback(
19805
22117
  (blockIdx) => {
19806
22118
  const block = blocks[blockIdx];
19807
22119
  if (!block) return true;
@@ -19835,7 +22147,7 @@ function useBuilderState(blocks) {
19835
22147
  },
19836
22148
  [blocks, values]
19837
22149
  );
19838
- const validateAllDetailed = React41.useCallback(() => {
22150
+ const validateAllDetailed = React45.useCallback(() => {
19839
22151
  let firstBlockIndex = -1;
19840
22152
  let firstKey = null;
19841
22153
  let firstBlockId = null;
@@ -19863,7 +22175,7 @@ function useBuilderState(blocks) {
19863
22175
  if (firstBlockIndex >= 0) setCurrentBlock(firstBlockIndex);
19864
22176
  return { firstKey, firstBlockId, firstName, firstBlockIndex, failingKeys };
19865
22177
  }, [blocks, values]);
19866
- const validateAll = React41.useCallback(
22178
+ const validateAll = React45.useCallback(
19867
22179
  () => validateAllDetailed().failingKeys.length === 0,
19868
22180
  [validateAllDetailed]
19869
22181
  );
@@ -19896,7 +22208,7 @@ function BlockForm({
19896
22208
  }) {
19897
22209
  var _a2;
19898
22210
  const t = useTheme();
19899
- const S4 = React41.useMemo(() => makeStyles(t), [t]);
22211
+ const S4 = React45.useMemo(() => makeStyles(t), [t]);
19900
22212
  const block = builder.blocks[0];
19901
22213
  const isEscalation = variant === "escalation";
19902
22214
  const errorCount = ((block == null ? void 0 : block.fields) || []).reduce(
@@ -20037,7 +22349,7 @@ init_ThemeContext();
20037
22349
  function StepperBuilder({ builder, state, onSubmit, onCancel, disabled, onFileUpload, onEntitySearch, onEntityCreate, dense }) {
20038
22350
  var _a2;
20039
22351
  const t = useTheme();
20040
- const S4 = React41.useMemo(() => makeStyles2(t), [t]);
22352
+ const S4 = React45.useMemo(() => makeStyles2(t), [t]);
20041
22353
  const { blocks } = builder;
20042
22354
  const total = blocks.length;
20043
22355
  const idx = Math.min(Math.max(state.currentBlock, 0), Math.max(total - 1, 0));
@@ -20236,7 +22548,7 @@ function BuilderFormResolver({
20236
22548
  `[BuilderForm] builder "${builder.builder_id}" declared builder_kind="${declaredKind}" with ${blockCount} blocks; rendering as stepper to avoid dropping blocks.`
20237
22549
  );
20238
22550
  }
20239
- const buildSubmission = React41.useCallback(() => {
22551
+ const buildSubmission = React45.useCallback(() => {
20240
22552
  const blocks = (builder.blocks || []).map((b) => ({
20241
22553
  id: b.id,
20242
22554
  title: b.title,
@@ -20248,7 +22560,7 @@ function BuilderFormResolver({
20248
22560
  blocks
20249
22561
  }, blocks.length === 1 ? { values: blocks[0].values } : {});
20250
22562
  }, [builder, kind, state.getValue]);
20251
- const handleSubmit = React41.useCallback(() => {
22563
+ const handleSubmit = React45.useCallback(() => {
20252
22564
  if (disabled) return;
20253
22565
  const failure = state.validateAllDetailed();
20254
22566
  if (failure.failingKeys.length > 0) {
@@ -20257,15 +22569,15 @@ function BuilderFormResolver({
20257
22569
  }
20258
22570
  onSubmit(buildSubmission());
20259
22571
  }, [disabled, state.validateAllDetailed, onSubmit, buildSubmission, onValidationError]);
20260
- const onChangeRef = React41.useRef(onChange);
20261
- React41.useEffect(() => {
22572
+ const onChangeRef = React45.useRef(onChange);
22573
+ React45.useEffect(() => {
20262
22574
  onChangeRef.current = onChange;
20263
22575
  });
20264
- React41.useEffect(() => {
22576
+ React45.useEffect(() => {
20265
22577
  var _a3;
20266
22578
  (_a3 = onChangeRef.current) == null ? void 0 : _a3.call(onChangeRef, buildSubmission());
20267
22579
  }, [state.values]);
20268
- React41.useEffect(() => {
22580
+ React45.useEffect(() => {
20269
22581
  if (!submitRef) return;
20270
22582
  submitRef.current = handleSubmit;
20271
22583
  return () => {
@@ -20324,7 +22636,7 @@ function BuilderFormResolver({
20324
22636
  }
20325
22637
  }
20326
22638
  function resolveBuilder(payload, callbacks) {
20327
- return React41__default.default.createElement(BuilderFormResolver, __spreadValues({
22639
+ return React45__default.default.createElement(BuilderFormResolver, __spreadValues({
20328
22640
  builder: payload
20329
22641
  }, callbacks));
20330
22642
  }
@@ -20348,9 +22660,13 @@ exports.DEFAULT_INTERACTION = DEFAULT_INTERACTION;
20348
22660
  exports.DataTableResolver = DataTableResolver;
20349
22661
  exports.DecisionCardRenderer = DecisionCardRenderer;
20350
22662
  exports.DecisionCardResolver = DecisionCardResolver;
22663
+ exports.DocumentFieldExtractionResolver = DocumentFieldExtractionResolver;
22664
+ exports.DocumentFieldExtractionSkeleton = DocumentFieldExtractionSkeleton;
20351
22665
  exports.DocumentPreviewResolver = DocumentPreviewResolver;
20352
22666
  exports.EngagementPipelineResolver = EngagementPipelineResolver;
20353
22667
  exports.FIELD_REGISTRY = FIELD_REGISTRY;
22668
+ exports.FieldAuditLog = FieldAuditLog;
22669
+ exports.FieldDetails = FieldDetails;
20354
22670
  exports.FieldRenderer = FieldRenderer;
20355
22671
  exports.FileCard = FileCard;
20356
22672
  exports.FitText = FitText;