@adoptai/genui-components 0.1.60 → 0.1.62

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 (37) hide show
  1. package/dist/composites/decision-card/resolver.cjs +7 -4
  2. package/dist/composites/decision-card/resolver.cjs.map +1 -1
  3. package/dist/composites/decision-card/resolver.d.ts +7 -1
  4. package/dist/composites/decision-card/resolver.d.ts.map +1 -1
  5. package/dist/composites/decision-card/resolver.js +7 -5
  6. package/dist/composites/decision-card/resolver.js.map +1 -1
  7. package/dist/composites/decision-queue/resolver.d.ts +33 -0
  8. package/dist/composites/decision-queue/resolver.d.ts.map +1 -0
  9. package/dist/composites/workflow-stepper/resolver.cjs +2 -1
  10. package/dist/composites/workflow-stepper/resolver.cjs.map +1 -1
  11. package/dist/composites/workflow-stepper/resolver.js +2 -1
  12. package/dist/composites/workflow-stepper/resolver.js.map +1 -1
  13. package/dist/index.cjs +495 -10
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.js +495 -10
  16. package/dist/index.js.map +1 -1
  17. package/dist/renderer.cjs +495 -10
  18. package/dist/renderer.cjs.map +1 -1
  19. package/dist/renderer.js +495 -10
  20. package/dist/renderer.js.map +1 -1
  21. package/dist/resolver.cjs +495 -10
  22. package/dist/resolver.cjs.map +1 -1
  23. package/dist/resolver.d.ts.map +1 -1
  24. package/dist/resolver.js +495 -10
  25. package/dist/resolver.js.map +1 -1
  26. package/dist/schemas/decision-queue.d.ts +227 -0
  27. package/dist/schemas/decision-queue.d.ts.map +1 -0
  28. package/dist/schemas/index.cjs +162 -0
  29. package/dist/schemas/index.cjs.map +1 -1
  30. package/dist/schemas/index.d.ts +227 -0
  31. package/dist/schemas/index.d.ts.map +1 -1
  32. package/dist/schemas/index.js +162 -0
  33. package/dist/schemas/index.js.map +1 -1
  34. package/dist/shared/InteractionContext.d.ts +10 -0
  35. package/dist/shared/InteractionContext.d.ts.map +1 -1
  36. package/dist/tool-definitions.json +203 -3
  37. package/package.json +1 -1
package/dist/renderer.cjs CHANGED
@@ -5659,6 +5659,167 @@ var decisionCardTool = {
5659
5659
  required: ["type", "title", "question", "options"]
5660
5660
  }
5661
5661
  };
5662
+ var decisionQueueItemSchema = zod.z.object({
5663
+ id: zod.z.string().optional(),
5664
+ decision_type: zod.z.string().optional(),
5665
+ title: zod.z.string(),
5666
+ question: zod.z.string(),
5667
+ amount: zod.z.number().optional(),
5668
+ currency: zod.z.string().optional(),
5669
+ amount_label: zod.z.string().optional(),
5670
+ severity: zod.z.enum(["low", "medium", "high"]).optional(),
5671
+ flags: zod.z.array(
5672
+ zod.z.object({
5673
+ field: zod.z.string().optional(),
5674
+ issue: zod.z.string(),
5675
+ severity: zod.z.enum(["low", "medium", "high"]).optional()
5676
+ })
5677
+ ).max(6).optional(),
5678
+ options: zod.z.array(
5679
+ zod.z.object({
5680
+ id: zod.z.string().optional(),
5681
+ label: zod.z.string(),
5682
+ recommended: zod.z.boolean().optional(),
5683
+ value: zod.z.number().optional(),
5684
+ adjust: zod.z.object({
5685
+ min: zod.z.number(),
5686
+ max: zod.z.number(),
5687
+ step: zod.z.number().optional(),
5688
+ unit: zod.z.string().optional()
5689
+ }).optional()
5690
+ })
5691
+ ).min(1).max(5),
5692
+ source: zod.z.object({
5693
+ label: zod.z.string().optional(),
5694
+ url: zod.z.string().optional()
5695
+ }).optional()
5696
+ });
5697
+ var decisionQueueSchema = zod.z.object({
5698
+ type: zod.z.literal("decision-queue"),
5699
+ id: zod.z.string().optional(),
5700
+ title: zod.z.string().optional(),
5701
+ description: zod.z.string().optional(),
5702
+ submit_label: zod.z.string().optional(),
5703
+ items: zod.z.array(decisionQueueItemSchema).min(2).max(12),
5704
+ resolved: zod.z.object({
5705
+ decisions: zod.z.array(
5706
+ zod.z.object({
5707
+ id: zod.z.string().optional(),
5708
+ title: zod.z.string(),
5709
+ option: zod.z.string(),
5710
+ value: zod.z.number().optional()
5711
+ })
5712
+ )
5713
+ }).optional()
5714
+ });
5715
+ var OPTION_ITEM_JSON = {
5716
+ type: "object",
5717
+ properties: {
5718
+ id: { type: "string" },
5719
+ label: { type: "string" },
5720
+ recommended: { type: "boolean" },
5721
+ value: {
5722
+ type: "number",
5723
+ description: "Suggested numeric figure for this option (starting point of the adjuster)"
5724
+ },
5725
+ adjust: {
5726
+ type: "object",
5727
+ description: "Allow the user to tune `value` within this inclusive range before deciding",
5728
+ properties: {
5729
+ min: { type: "number" },
5730
+ max: { type: "number" },
5731
+ step: { type: "number" },
5732
+ unit: { type: "string", description: "Short unit suffix, e.g. 'units', '%', 'hrs'" }
5733
+ },
5734
+ required: ["min", "max"]
5735
+ }
5736
+ },
5737
+ required: ["label"]
5738
+ };
5739
+ var decisionQueueTool = {
5740
+ name: "render_decision_queue",
5741
+ description: "Render a SEQUENTIAL QUEUE of 2-12 related human-in-the-loop judgments, decided one at a time at full decision-card richness (amount at stake, data-quality flags, adjustable figures, source links) and submitted TOGETHER as one reply. Use whenever MORE THAN ONE decision is pending in the same turn \u2014 never emit multiple loose decision-cards. Give deferrable items an explicit 'leave open'-style option so the user can always complete the queue. For a single judgment use decision-card; for typed field input (names, dates, uploads) use render_builder.",
5742
+ input_schema: {
5743
+ type: "object",
5744
+ properties: {
5745
+ type: { type: "string", enum: ["decision-queue"] },
5746
+ id: { type: "string", description: "Stable id for update-in-place rendering" },
5747
+ title: {
5748
+ type: "string",
5749
+ description: "Batch headline shown in the header, e.g. 'Reconciliation exceptions'"
5750
+ },
5751
+ description: { type: "string", description: "One-line context above the queue" },
5752
+ submit_label: { type: "string", description: "CTA label; defaults to 'Submit N decisions'" },
5753
+ items: {
5754
+ type: "array",
5755
+ minItems: 2,
5756
+ maxItems: 12,
5757
+ description: "The pending judgments, in the order the user should take them. Each is a full decision-card body (no `type`).",
5758
+ items: {
5759
+ type: "object",
5760
+ properties: {
5761
+ id: { type: "string" },
5762
+ decision_type: {
5763
+ type: "string",
5764
+ description: "Short category eyebrow, e.g. 'Duplicate', 'Capitalization'"
5765
+ },
5766
+ title: { type: "string" },
5767
+ question: { type: "string" },
5768
+ amount: { type: "number" },
5769
+ currency: { type: "string" },
5770
+ amount_label: { type: "string" },
5771
+ severity: { type: "string", enum: ["low", "medium", "high"] },
5772
+ flags: {
5773
+ type: "array",
5774
+ maxItems: 6,
5775
+ items: {
5776
+ type: "object",
5777
+ properties: {
5778
+ field: { type: "string" },
5779
+ issue: { type: "string" },
5780
+ severity: { type: "string", enum: ["low", "medium", "high"] }
5781
+ },
5782
+ required: ["issue"]
5783
+ }
5784
+ },
5785
+ options: {
5786
+ type: "array",
5787
+ minItems: 1,
5788
+ maxItems: 5,
5789
+ items: OPTION_ITEM_JSON
5790
+ },
5791
+ source: {
5792
+ type: "object",
5793
+ properties: { label: { type: "string" }, url: { type: "string" } }
5794
+ }
5795
+ },
5796
+ required: ["title", "question", "options"]
5797
+ }
5798
+ },
5799
+ resolved: {
5800
+ type: "object",
5801
+ description: "Pre-resolved state for transcript replay",
5802
+ properties: {
5803
+ decisions: {
5804
+ type: "array",
5805
+ items: {
5806
+ type: "object",
5807
+ properties: {
5808
+ id: { type: "string" },
5809
+ title: { type: "string" },
5810
+ option: { type: "string" },
5811
+ value: { type: "number" }
5812
+ },
5813
+ required: ["title", "option"]
5814
+ }
5815
+ }
5816
+ },
5817
+ required: ["decisions"]
5818
+ }
5819
+ },
5820
+ required: ["type", "items"]
5821
+ }
5822
+ };
5662
5823
  var tabbyAuthSchema = zod.z.object({
5663
5824
  type: zod.z.literal("tabby-auth"),
5664
5825
  app: zod.z.string(),
@@ -5751,6 +5912,7 @@ var schemaRegistry = {
5751
5912
  "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5752
5913
  "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5753
5914
  "decision-card": { schema: decisionCardSchema, tool: decisionCardTool },
5915
+ "decision-queue": { schema: decisionQueueSchema, tool: decisionQueueTool },
5754
5916
  "tabby-auth": { schema: tabbyAuthSchema, tool: tabbyAuthTool }
5755
5917
  };
5756
5918
 
@@ -6489,17 +6651,17 @@ function SparklineTableResolver(p) {
6489
6651
  // src/composites/heatmap-table/resolver.tsx
6490
6652
  init_theme();
6491
6653
  init_ThemeContext();
6492
- function heatColor(z61) {
6493
- const clamped = Math.max(-3, Math.min(3, z61));
6654
+ function heatColor(z62) {
6655
+ const clamped = Math.max(-3, Math.min(3, z62));
6494
6656
  const abs = Math.abs(clamped);
6495
6657
  const lightness = 95 - abs * 8;
6496
6658
  const hue = clamped >= 0 ? 142 : 0;
6497
6659
  return `hsl(${hue} 60% ${lightness}%)`;
6498
6660
  }
6499
- function heatTextColor(z61) {
6500
- const abs = Math.abs(z61);
6501
- if (abs > 2) return z61 >= 0 ? "#14532d" : "#7f1d1d";
6502
- if (abs > 1) return z61 >= 0 ? "#166534" : "#991b1b";
6661
+ function heatTextColor(z62) {
6662
+ const abs = Math.abs(z62);
6663
+ if (abs > 2) return z62 >= 0 ? "#14532d" : "#7f1d1d";
6664
+ if (abs > 1) return z62 >= 0 ? "#166534" : "#991b1b";
6503
6665
  return "var(--foreground)";
6504
6666
  }
6505
6667
  var th2 = {
@@ -17547,7 +17709,8 @@ var DEFAULT_INTERACTION = {
17547
17709
  onStepSelect: void 0,
17548
17710
  resolvedDecisions: void 0,
17549
17711
  onDecisionResolve: void 0,
17550
- onDecisionSource: void 0
17712
+ onDecisionSource: void 0,
17713
+ onDecisionQueueSubmit: void 0
17551
17714
  };
17552
17715
  var GenUIInteractionContext = React45.createContext(DEFAULT_INTERACTION);
17553
17716
  function useGenUIInteraction() {
@@ -20221,7 +20384,8 @@ function DecisionCardRenderer({
20221
20384
  data,
20222
20385
  resolved = null,
20223
20386
  onResolve,
20224
- onOpenSource
20387
+ onOpenSource,
20388
+ eyebrow
20225
20389
  }) {
20226
20390
  var _a, _b, _c;
20227
20391
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
@@ -20327,7 +20491,7 @@ function DecisionCardRenderer({
20327
20491
  },
20328
20492
  children: [
20329
20493
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0, display: "flex", flexDirection: "column", gap: 4 }, children: [
20330
- /* @__PURE__ */ jsxRuntime.jsx(
20494
+ eyebrow === null ? null : /* @__PURE__ */ jsxRuntime.jsx(
20331
20495
  "span",
20332
20496
  {
20333
20497
  style: {
@@ -20337,7 +20501,7 @@ function DecisionCardRenderer({
20337
20501
  fontWeight: 700,
20338
20502
  color: ACCENT2
20339
20503
  },
20340
- children: data.decision_type ? `Decision needs you \xB7 ${data.decision_type}` : "Decision needs you"
20504
+ children: eyebrow !== void 0 ? eyebrow : data.decision_type ? `Decision needs you \xB7 ${data.decision_type}` : "Decision needs you"
20341
20505
  }
20342
20506
  ),
20343
20507
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -20557,6 +20721,325 @@ function DecisionCardResolver(p) {
20557
20721
  ) });
20558
20722
  }
20559
20723
  init_ThemeContext();
20724
+ var GREEN4 = "#15803d";
20725
+ var KEYFRAMES3 = `
20726
+ @keyframes dqSettle{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
20727
+ .dq-settle{animation:dqSettle 0.24s cubic-bezier(0.22,1,0.36,1) both}
20728
+ @keyframes dqFocus{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
20729
+ .dq-focus{animation:dqFocus 0.28s cubic-bezier(0.22,1,0.36,1) both}
20730
+ @media (prefers-reduced-motion: reduce){
20731
+ .dq-settle,.dq-focus{animation:none !important;opacity:1 !important;transform:none !important}
20732
+ }`;
20733
+ function figureOf(item, decision) {
20734
+ var _a, _b, _c;
20735
+ if (decision.value == null) return decision.option;
20736
+ const unit = (_c = (_b = ((_a = item.options) != null ? _a : []).find((o) => o.label === decision.option)) == null ? void 0 : _b.adjust) == null ? void 0 : _c.unit;
20737
+ return `${decision.option} \xB7 ${formatFigure(decision.value, unit)}`;
20738
+ }
20739
+ function composeQueueMessage(items, decisions) {
20740
+ const lines = items.map((item, i) => {
20741
+ const d = decisions[i];
20742
+ return `${i + 1}. ${item.title} \u2192 ${d ? figureOf(item, d) : "(undecided)"}`;
20743
+ });
20744
+ const done = decisions.filter(Boolean).length;
20745
+ return `Decisions (${done}/${items.length}):
20746
+ ${lines.join("\n")}`;
20747
+ }
20748
+ function Check({ size, color }) {
20749
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 13l4 4L19 7", stroke: color, strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round" }) });
20750
+ }
20751
+ function amountChip(item) {
20752
+ if (typeof item.amount !== "number") return null;
20753
+ const abs = Math.abs(item.amount);
20754
+ const sign = item.amount < 0 ? "-" : "";
20755
+ if (abs >= 1e6) return `${sign}$${(abs / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;
20756
+ if (abs >= 1e3) return `${sign}$${(abs / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;
20757
+ return `${sign}$${abs}`;
20758
+ }
20759
+ function DecisionQueueRenderer({
20760
+ data,
20761
+ submitted = null,
20762
+ onSubmit,
20763
+ hideSubmit,
20764
+ submitRef,
20765
+ onReady
20766
+ }) {
20767
+ var _a;
20768
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
20769
+ const items = (_a = data.items) != null ? _a : [];
20770
+ const [decisions, setDecisions] = React45__default.default.useState(
20771
+ () => items.map(() => void 0)
20772
+ );
20773
+ const firstUndecided = decisions.findIndex((d) => !d);
20774
+ const [focusIdx, setFocusIdx] = React45__default.default.useState(firstUndecided >= 0 ? firstUndecided : null);
20775
+ const isSubmitted = submitted != null;
20776
+ const shown = isSubmitted ? items.map(
20777
+ (item, i) => {
20778
+ var _a2;
20779
+ return (_a2 = submitted.find((d) => d.id && d.id === item.id || d.title === item.title)) != null ? _a2 : submitted[i];
20780
+ }
20781
+ ) : decisions;
20782
+ const decidedCount = shown.filter(Boolean).length;
20783
+ const allDecided = decidedCount === items.length;
20784
+ const decide = (idx, option, value) => {
20785
+ const item = items[idx];
20786
+ const next = decisions.slice();
20787
+ next[idx] = { id: item.id, title: item.title, option, value };
20788
+ setDecisions(next);
20789
+ const order = [...Array(items.length).keys()];
20790
+ const after = order.slice(idx + 1).concat(order.slice(0, idx + 1));
20791
+ const target = after.find((j) => j !== idx && !next[j]);
20792
+ setFocusIdx(target != null ? target : null);
20793
+ };
20794
+ const handleSubmit = () => {
20795
+ if (!allDecided || isSubmitted) return;
20796
+ const final = decisions;
20797
+ onSubmit == null ? void 0 : onSubmit(final, composeQueueMessage(items, final));
20798
+ };
20799
+ const onReadyRef = React45__default.default.useRef(onReady);
20800
+ React45__default.default.useEffect(() => {
20801
+ onReadyRef.current = onReady;
20802
+ });
20803
+ React45__default.default.useEffect(() => {
20804
+ if (!onReadyRef.current) return;
20805
+ const msg = allDecided ? composeQueueMessage(items, decisions) : null;
20806
+ onReadyRef.current(allDecided && !isSubmitted, msg, decisions.filter(Boolean));
20807
+ }, [decisions, allDecided, isSubmitted]);
20808
+ React45__default.default.useEffect(() => {
20809
+ if (!submitRef) return;
20810
+ submitRef.current = handleSubmit;
20811
+ return () => {
20812
+ submitRef.current = null;
20813
+ };
20814
+ }, [submitRef, allDecided, isSubmitted, decisions]);
20815
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20816
+ "div",
20817
+ {
20818
+ "data-testid": "decision-queue",
20819
+ "data-submitted": isSubmitted || void 0,
20820
+ style: {
20821
+ position: "relative",
20822
+ width: "100%",
20823
+ minWidth: 0,
20824
+ boxSizing: "border-box",
20825
+ borderRadius: "0.75rem",
20826
+ border: `1px solid ${BORDER4}`,
20827
+ background: "white",
20828
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.04)",
20829
+ padding: "16px 18px",
20830
+ display: "flex",
20831
+ flexDirection: "column",
20832
+ gap: 12,
20833
+ overflow: "hidden"
20834
+ },
20835
+ children: [
20836
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: KEYFRAMES3 }),
20837
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 3 }, children: [
20838
+ /* @__PURE__ */ jsxRuntime.jsx(
20839
+ "span",
20840
+ {
20841
+ style: {
20842
+ fontSize: 10.5,
20843
+ textTransform: "uppercase",
20844
+ letterSpacing: "0.07em",
20845
+ fontWeight: 700,
20846
+ color: isSubmitted ? GREEN4 : ACCENT2
20847
+ },
20848
+ children: isSubmitted ? "Decisions submitted" : "Decisions need you"
20849
+ }
20850
+ ),
20851
+ data.title && /* @__PURE__ */ jsxRuntime.jsx(
20852
+ "p",
20853
+ {
20854
+ style: {
20855
+ fontFamily: "var(--font-serif)",
20856
+ fontSize: 16,
20857
+ fontWeight: 400,
20858
+ color: "var(--foreground)",
20859
+ letterSpacing: "-0.01em",
20860
+ margin: 0,
20861
+ lineHeight: 1.25
20862
+ },
20863
+ children: data.title
20864
+ }
20865
+ ),
20866
+ data.description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: 12.5, color: MUTED2, margin: 0, lineHeight: 1.45 }, children: data.description })
20867
+ ] }),
20868
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: items.map((item, idx) => {
20869
+ var _a2, _b, _c;
20870
+ const decision = shown[idx];
20871
+ const focused = !isSubmitted && focusIdx === idx;
20872
+ if (focused) {
20873
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dq-focus", "data-testid": `decision-queue-focus-${idx}`, children: /* @__PURE__ */ jsxRuntime.jsx(
20874
+ DecisionCardRenderer,
20875
+ {
20876
+ data: __spreadValues({ type: "decision-card" }, item),
20877
+ resolved: null,
20878
+ onResolve: (option, value) => decide(idx, option, value),
20879
+ eyebrow: `${idx + 1} of ${items.length}${item.decision_type ? ` \xB7 ${item.decision_type}` : ""}`
20880
+ }
20881
+ ) }, (_a2 = item.id) != null ? _a2 : `q-${idx}`);
20882
+ }
20883
+ if (decision) {
20884
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20885
+ "button",
20886
+ {
20887
+ type: "button",
20888
+ className: "dq-settle",
20889
+ onClick: isSubmitted ? void 0 : () => setFocusIdx(idx),
20890
+ disabled: isSubmitted,
20891
+ title: isSubmitted ? void 0 : "Change this decision",
20892
+ "data-testid": `decision-queue-receipt-${idx}`,
20893
+ style: {
20894
+ display: "flex",
20895
+ alignItems: "center",
20896
+ gap: 8,
20897
+ width: "100%",
20898
+ textAlign: "left",
20899
+ border: "1px solid #dcfce7",
20900
+ background: "#f6fef9",
20901
+ borderRadius: 8,
20902
+ padding: "7px 11px",
20903
+ cursor: isSubmitted ? "default" : "pointer",
20904
+ font: "inherit"
20905
+ },
20906
+ children: [
20907
+ /* @__PURE__ */ jsxRuntime.jsx(Check, { size: 13, color: GREEN4 }),
20908
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12.5, fontWeight: 600, color: "var(--foreground)", minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: item.title }),
20909
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: { color: MUTED2, fontSize: 12 }, children: "\u2192" }),
20910
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12.5, fontWeight: 600, color: GREEN4, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" }, children: figureOf(item, decision) }),
20911
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1 } }),
20912
+ !isSubmitted && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 11, fontWeight: 600, color: MUTED2 }, children: "Change" })
20913
+ ]
20914
+ },
20915
+ (_b = item.id) != null ? _b : `q-${idx}`
20916
+ );
20917
+ }
20918
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20919
+ "button",
20920
+ {
20921
+ type: "button",
20922
+ onClick: isSubmitted ? void 0 : () => setFocusIdx(idx),
20923
+ disabled: isSubmitted,
20924
+ "data-testid": `decision-queue-upcoming-${idx}`,
20925
+ style: {
20926
+ display: "flex",
20927
+ alignItems: "center",
20928
+ gap: 8,
20929
+ width: "100%",
20930
+ textAlign: "left",
20931
+ border: `1px dashed ${BORDER4}`,
20932
+ background: "white",
20933
+ borderRadius: 8,
20934
+ padding: "7px 11px",
20935
+ cursor: isSubmitted ? "default" : "pointer",
20936
+ font: "inherit",
20937
+ opacity: 0.75
20938
+ },
20939
+ children: [
20940
+ /* @__PURE__ */ jsxRuntime.jsx(
20941
+ "span",
20942
+ {
20943
+ "aria-hidden": "true",
20944
+ style: { width: 13, height: 13, borderRadius: "50%", border: `1.5px solid ${MUTED2}`, flexShrink: 0, boxSizing: "border-box" }
20945
+ }
20946
+ ),
20947
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 12.5, fontWeight: 600, color: MUTED2, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: [
20948
+ item.decision_type ? `${item.decision_type} \xB7 ` : "",
20949
+ item.title
20950
+ ] }),
20951
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1 } }),
20952
+ amountChip(item) && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 11.5, fontWeight: 700, color: MUTED2, fontVariantNumeric: "tabular-nums" }, children: amountChip(item) })
20953
+ ]
20954
+ },
20955
+ (_c = item.id) != null ? _c : `q-${idx}`
20956
+ );
20957
+ }) }),
20958
+ /* @__PURE__ */ jsxRuntime.jsxs(
20959
+ "div",
20960
+ {
20961
+ style: {
20962
+ display: "flex",
20963
+ alignItems: "center",
20964
+ gap: 10,
20965
+ paddingTop: 10,
20966
+ borderTop: `1px solid #f0f0f0`
20967
+ },
20968
+ children: [
20969
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-flex", gap: 4 }, "aria-hidden": "true", children: items.map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
20970
+ "span",
20971
+ {
20972
+ style: {
20973
+ width: 7,
20974
+ height: 7,
20975
+ borderRadius: "50%",
20976
+ background: shown[i] ? isSubmitted ? GREEN4 : ACCENT2 : "#e8e8e8",
20977
+ transition: "background 0.2s"
20978
+ }
20979
+ },
20980
+ `dot-${i}`
20981
+ )) }),
20982
+ /* @__PURE__ */ jsxRuntime.jsxs(
20983
+ "span",
20984
+ {
20985
+ style: { fontSize: 11.5, fontWeight: 600, color: MUTED2, fontVariantNumeric: "tabular-nums" },
20986
+ "data-testid": "decision-queue-progress",
20987
+ children: [
20988
+ decidedCount,
20989
+ "/",
20990
+ items.length,
20991
+ " decided"
20992
+ ]
20993
+ }
20994
+ ),
20995
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1 } }),
20996
+ isSubmitted ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12.5, fontWeight: 600, color: GREEN4 }, children: [
20997
+ /* @__PURE__ */ jsxRuntime.jsx(Check, { size: 14, color: GREEN4 }),
20998
+ "Submitted"
20999
+ ] }) : hideSubmit ? null : /* @__PURE__ */ jsxRuntime.jsx(
21000
+ "button",
21001
+ {
21002
+ type: "button",
21003
+ onClick: handleSubmit,
21004
+ disabled: !allDecided,
21005
+ "data-testid": "decision-queue-submit",
21006
+ style: {
21007
+ border: `1px solid ${allDecided ? ACCENT2 : BORDER4}`,
21008
+ background: allDecided ? ACCENT2 : "#f6f6f6",
21009
+ color: allDecided ? "white" : MUTED2,
21010
+ borderRadius: 8,
21011
+ fontSize: 13,
21012
+ fontWeight: 600,
21013
+ padding: "8px 16px",
21014
+ cursor: allDecided ? "pointer" : "default",
21015
+ fontVariantNumeric: "tabular-nums",
21016
+ transition: "background 0.15s, border-color 0.15s, color 0.15s"
21017
+ },
21018
+ children: data.submit_label || `Submit ${items.length} decision${items.length === 1 ? "" : "s"}`
21019
+ }
21020
+ )
21021
+ ]
21022
+ }
21023
+ )
21024
+ ]
21025
+ }
21026
+ );
21027
+ }
21028
+ function DecisionQueueResolver(p) {
21029
+ var _a, _b, _c, _d, _e, _f;
21030
+ const { resolvedDecisions, onDecisionQueueSubmit } = useGenUIInteraction();
21031
+ const queueId = (_b = (_a = p.id) != null ? _a : p.title) != null ? _b : "decision-queue";
21032
+ const replayed = (_d = (_c = p.resolved) == null ? void 0 : _c.decisions) != null ? _d : null;
21033
+ const [localSubmitted, setLocalSubmitted] = React45__default.default.useState(null);
21034
+ const hostLocked = (resolvedDecisions == null ? void 0 : resolvedDecisions[queueId]) != null;
21035
+ const submitted = (_e = replayed != null ? replayed : localSubmitted) != null ? _e : hostLocked ? [] : null;
21036
+ const handleSubmit = (decisions, message) => {
21037
+ setLocalSubmitted(decisions);
21038
+ onDecisionQueueSubmit == null ? void 0 : onDecisionQueueSubmit(queueId, decisions, message);
21039
+ };
21040
+ return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_f = p.title) != null ? _f : "decision-queue", children: /* @__PURE__ */ jsxRuntime.jsx(DecisionQueueRenderer, { data: p, submitted, onSubmit: handleSubmit }) });
21041
+ }
21042
+ init_ThemeContext();
20560
21043
  var CONNECTED_GREEN3 = "#15803d";
20561
21044
  var CONNECTED_GREEN_BG = "#dcfce7";
20562
21045
  var PENDING_AMBER = "#92400e";
@@ -20988,6 +21471,8 @@ function resolveUI(rawPayload) {
20988
21471
  return /* @__PURE__ */ jsxRuntime.jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
20989
21472
  case "decision-card":
20990
21473
  return /* @__PURE__ */ jsxRuntime.jsx(DecisionCardResolver, __spreadValues({}, payload));
21474
+ case "decision-queue":
21475
+ return /* @__PURE__ */ jsxRuntime.jsx(DecisionQueueResolver, __spreadValues({}, payload));
20991
21476
  case "tabby-auth":
20992
21477
  return /* @__PURE__ */ jsxRuntime.jsx(TabbyAuthResolver, __spreadValues({}, payload));
20993
21478
  default: {