@adoptai/genui-components 0.1.58 → 0.1.60

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 (54) hide show
  1. package/dist/builders/BlockForm.d.ts +5 -1
  2. package/dist/builders/BlockForm.d.ts.map +1 -1
  3. package/dist/builders/BuilderForm.d.ts +22 -1
  4. package/dist/builders/BuilderForm.d.ts.map +1 -1
  5. package/dist/builders/index.d.ts +1 -1
  6. package/dist/builders/index.d.ts.map +1 -1
  7. package/dist/composites/decision-card/resolver.cjs +289 -13
  8. package/dist/composites/decision-card/resolver.cjs.map +1 -1
  9. package/dist/composites/decision-card/resolver.d.ts +2 -1
  10. package/dist/composites/decision-card/resolver.d.ts.map +1 -1
  11. package/dist/composites/decision-card/resolver.js +289 -13
  12. package/dist/composites/decision-card/resolver.js.map +1 -1
  13. package/dist/composites/document-field-extraction/resolver.cjs +1920 -0
  14. package/dist/composites/document-field-extraction/resolver.cjs.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 +901 -63
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.js +901 -63
  31. package/dist/index.js.map +1 -1
  32. package/dist/renderer.cjs +810 -45
  33. package/dist/renderer.cjs.map +1 -1
  34. package/dist/renderer.js +810 -45
  35. package/dist/renderer.js.map +1 -1
  36. package/dist/resolver.cjs +810 -45
  37. package/dist/resolver.cjs.map +1 -1
  38. package/dist/resolver.d.ts.map +1 -1
  39. package/dist/resolver.js +810 -45
  40. package/dist/resolver.js.map +1 -1
  41. package/dist/schemas/decision-card.d.ts +37 -0
  42. package/dist/schemas/decision-card.d.ts.map +1 -1
  43. package/dist/schemas/index.cjs +113 -8
  44. package/dist/schemas/index.cjs.map +1 -1
  45. package/dist/schemas/index.d.ts +155 -0
  46. package/dist/schemas/index.d.ts.map +1 -1
  47. package/dist/schemas/index.js +113 -8
  48. package/dist/schemas/index.js.map +1 -1
  49. package/dist/schemas/tabby-auth.d.ts +58 -0
  50. package/dist/schemas/tabby-auth.d.ts.map +1 -0
  51. package/dist/schemas/workflow-stepper.d.ts +60 -0
  52. package/dist/schemas/workflow-stepper.d.ts.map +1 -1
  53. package/dist/tool-definitions.json +135 -4
  54. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5227,7 +5227,32 @@ var workflowStepperSchema = z.object({
5227
5227
  n: z.number().int().positive().optional(),
5228
5228
  title: z.string(),
5229
5229
  sub: z.string().optional(),
5230
- status: z.enum(["done", "active", "review", "pending", "blocked", "failed"]),
5230
+ status: z.enum([
5231
+ "done",
5232
+ "active",
5233
+ "running",
5234
+ "review",
5235
+ "pending",
5236
+ "blocked",
5237
+ "failed"
5238
+ ]),
5239
+ // Optional quality-gate verdict for a step run by an executor (e.g. a
5240
+ // pipeline). Surfaces a subtle trust badge; flags hint at issues a human
5241
+ // should review (the full list lives in the escalation dock).
5242
+ eval: z.object({
5243
+ score: z.number().min(0).max(1).nullable().optional(),
5244
+ verdict: z.enum(["good", "bad"]).optional(),
5245
+ reasoning: z.string().optional(),
5246
+ judge_ok: z.boolean().optional(),
5247
+ data_quality_flags: z.array(
5248
+ z.object({
5249
+ field: z.string().optional(),
5250
+ issue: z.string().optional(),
5251
+ severity: z.enum(["low", "medium", "high"]).optional(),
5252
+ details: z.string().optional()
5253
+ })
5254
+ ).optional()
5255
+ }).optional(),
5231
5256
  assignees: z.array(
5232
5257
  z.object({
5233
5258
  name: z.string(),
@@ -5263,7 +5288,32 @@ var workflowStepperTool = {
5263
5288
  n: { type: "number", description: "Step number; defaults to index + 1" },
5264
5289
  title: { type: "string" },
5265
5290
  sub: { type: "string", description: "Short status caption, e.g. '7 accounts \xB7 2 exceptions'" },
5266
- status: { type: "string", enum: ["done", "active", "review", "pending", "blocked", "failed"] },
5291
+ status: {
5292
+ type: "string",
5293
+ enum: ["done", "active", "running", "review", "pending", "blocked", "failed"]
5294
+ },
5295
+ eval: {
5296
+ type: "object",
5297
+ description: "Optional quality-gate verdict for an executor-run step.",
5298
+ properties: {
5299
+ score: { type: "number" },
5300
+ verdict: { type: "string", enum: ["good", "bad"] },
5301
+ reasoning: { type: "string" },
5302
+ judge_ok: { type: "boolean" },
5303
+ data_quality_flags: {
5304
+ type: "array",
5305
+ items: {
5306
+ type: "object",
5307
+ properties: {
5308
+ field: { type: "string" },
5309
+ issue: { type: "string" },
5310
+ severity: { type: "string", enum: ["low", "medium", "high"] },
5311
+ details: { type: "string" }
5312
+ }
5313
+ }
5314
+ }
5315
+ }
5316
+ },
5267
5317
  assignees: {
5268
5318
  type: "array",
5269
5319
  maxItems: 6,
@@ -5485,7 +5535,14 @@ var decisionCardSchema = z.object({
5485
5535
  z.object({
5486
5536
  id: z.string().optional(),
5487
5537
  label: z.string(),
5488
- recommended: z.boolean().optional()
5538
+ recommended: z.boolean().optional(),
5539
+ value: z.number().optional(),
5540
+ adjust: z.object({
5541
+ min: z.number(),
5542
+ max: z.number(),
5543
+ step: z.number().optional(),
5544
+ unit: z.string().optional()
5545
+ }).optional()
5489
5546
  })
5490
5547
  ).min(1).max(5),
5491
5548
  source: z.object({
@@ -5493,7 +5550,8 @@ var decisionCardSchema = z.object({
5493
5550
  url: z.string().optional()
5494
5551
  }).optional(),
5495
5552
  resolved: z.object({
5496
- option: z.string()
5553
+ option: z.string(),
5554
+ value: z.number().optional()
5497
5555
  }).optional()
5498
5556
  });
5499
5557
  var decisionCardTool = {
@@ -5536,13 +5594,28 @@ var decisionCardTool = {
5536
5594
  type: "array",
5537
5595
  minItems: 1,
5538
5596
  maxItems: 5,
5539
- description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary",
5597
+ description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary. An option that carries a numeric figure the user may want to tune (e.g. 'Book reserve' at 50 units) should set `value` (your suggested figure) and `adjust` ({min,max[,step,unit]}) \u2014 the card then lets the user fine-tune the number within that range before confirming.",
5540
5598
  items: {
5541
5599
  type: "object",
5542
5600
  properties: {
5543
5601
  id: { type: "string" },
5544
5602
  label: { type: "string" },
5545
- recommended: { type: "boolean" }
5603
+ recommended: { type: "boolean" },
5604
+ value: {
5605
+ type: "number",
5606
+ description: "Suggested numeric figure for this option (the starting point of the adjuster)"
5607
+ },
5608
+ adjust: {
5609
+ type: "object",
5610
+ description: "Allow the user to tune `value` within this inclusive range before resolving",
5611
+ properties: {
5612
+ min: { type: "number" },
5613
+ max: { type: "number" },
5614
+ step: { type: "number", description: "Increment granularity; defaults to a sensible step for the range" },
5615
+ unit: { type: "string", description: "Short unit suffix shown after the number, e.g. 'units', '%', 'hrs'" }
5616
+ },
5617
+ required: ["min", "max"]
5618
+ }
5546
5619
  },
5547
5620
  required: ["label"]
5548
5621
  }
@@ -5559,7 +5632,8 @@ var decisionCardTool = {
5559
5632
  type: "object",
5560
5633
  description: "Pre-resolved state for transcript replay",
5561
5634
  properties: {
5562
- option: { type: "string" }
5635
+ option: { type: "string" },
5636
+ value: { type: "number", description: "Adjusted figure the user confirmed, when the option was adjustable" }
5563
5637
  },
5564
5638
  required: ["option"]
5565
5639
  }
@@ -5567,6 +5641,36 @@ var decisionCardTool = {
5567
5641
  required: ["type", "title", "question", "options"]
5568
5642
  }
5569
5643
  };
5644
+ var tabbyAuthSchema = z.object({
5645
+ type: z.literal("tabby-auth"),
5646
+ app: z.string(),
5647
+ url: z.string(),
5648
+ workspace: z.string().optional(),
5649
+ state: z.enum(["pending", "connected"]).optional(),
5650
+ ctaLabel: z.string().optional(),
5651
+ steps: z.array(z.string()).optional(),
5652
+ description: z.string().optional(),
5653
+ iconUrl: z.string().optional()
5654
+ });
5655
+ var tabbyAuthTool = {
5656
+ name: "render_tabby_auth",
5657
+ 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.",
5658
+ input_schema: {
5659
+ type: "object",
5660
+ properties: {
5661
+ type: { type: "string", enum: ["tabby-auth"] },
5662
+ app: { type: "string" },
5663
+ url: { type: "string" },
5664
+ workspace: { type: "string" },
5665
+ state: { type: "string", enum: ["pending", "connected"] },
5666
+ ctaLabel: { type: "string" },
5667
+ steps: { type: "array", items: { type: "string" } },
5668
+ description: { type: "string" },
5669
+ iconUrl: { type: "string" }
5670
+ },
5671
+ required: ["type", "app", "url"]
5672
+ }
5673
+ };
5570
5674
 
5571
5675
  // src/schemas/buildRenderUITool.ts
5572
5676
  function buildRenderUITool(selectedSchemas) {
@@ -5687,7 +5791,8 @@ var schemaRegistry = {
5687
5791
  "pipeline-preview": { schema: pipelinePreviewSchema, tool: pipelinePreviewTool },
5688
5792
  "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5689
5793
  "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5690
- "decision-card": { schema: decisionCardSchema, tool: decisionCardTool }
5794
+ "decision-card": { schema: decisionCardSchema, tool: decisionCardTool },
5795
+ "tabby-auth": { schema: tabbyAuthSchema, tool: tabbyAuthTool }
5691
5796
  };
5692
5797
 
5693
5798
  // src/shared/ColumnSettingsPanel.tsx
@@ -6400,17 +6505,17 @@ function SparklineTableResolver(p) {
6400
6505
  // src/composites/heatmap-table/resolver.tsx
6401
6506
  init_theme();
6402
6507
  init_ThemeContext();
6403
- function heatColor(z61) {
6404
- const clamped = Math.max(-3, Math.min(3, z61));
6508
+ function heatColor(z62) {
6509
+ const clamped = Math.max(-3, Math.min(3, z62));
6405
6510
  const abs = Math.abs(clamped);
6406
6511
  const lightness = 95 - abs * 8;
6407
6512
  const hue = clamped >= 0 ? 142 : 0;
6408
6513
  return `hsl(${hue} 60% ${lightness}%)`;
6409
6514
  }
6410
- function heatTextColor(z61) {
6411
- const abs = Math.abs(z61);
6412
- if (abs > 2) return z61 >= 0 ? "#14532d" : "#7f1d1d";
6413
- if (abs > 1) return z61 >= 0 ? "#166534" : "#991b1b";
6515
+ function heatTextColor(z62) {
6516
+ const abs = Math.abs(z62);
6517
+ if (abs > 2) return z62 >= 0 ? "#14532d" : "#7f1d1d";
6518
+ if (abs > 1) return z62 >= 0 ? "#166534" : "#991b1b";
6414
6519
  return "var(--foreground)";
6415
6520
  }
6416
6521
  var th2 = {
@@ -17474,6 +17579,8 @@ var STATUS_COLORS3 = {
17474
17579
  done: "#15803d",
17475
17580
  active: "",
17476
17581
  // filled from theme ACCENT at render time
17582
+ running: "",
17583
+ // filled from theme ACCENT at render time (executor in flight)
17477
17584
  review: "#f59e0b",
17478
17585
  pending: "#9ca3af",
17479
17586
  blocked: "#b45309",
@@ -17482,6 +17589,7 @@ var STATUS_COLORS3 = {
17482
17589
  var STATUS_LABELS = {
17483
17590
  done: "Complete",
17484
17591
  active: "In progress",
17592
+ running: "Running",
17485
17593
  review: "In review",
17486
17594
  pending: "Pending",
17487
17595
  blocked: "Blocked",
@@ -17585,6 +17693,26 @@ function IndexDot({ step, index, accent }) {
17585
17693
  if (step.status === "failed") {
17586
17694
  return /* @__PURE__ */ jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#dc2626", color: "white" }), children: /* @__PURE__ */ jsx("span", { style: { fontSize: 10 }, children: "!" }) });
17587
17695
  }
17696
+ if (step.status === "running") {
17697
+ return /* @__PURE__ */ jsxs("div", { style: __spreadProps(__spreadValues({}, base), { position: "relative", background: `${accent}1f`, color: accent }), children: [
17698
+ /* @__PURE__ */ jsx(
17699
+ "span",
17700
+ {
17701
+ className: "wfs-anim",
17702
+ "aria-hidden": "true",
17703
+ style: {
17704
+ position: "absolute",
17705
+ inset: 0,
17706
+ borderRadius: "50%",
17707
+ border: `1.5px solid ${accent}33`,
17708
+ borderTopColor: accent,
17709
+ animation: "wfsSpin 0.8s linear infinite"
17710
+ }
17711
+ }
17712
+ ),
17713
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 9 }, children: n })
17714
+ ] });
17715
+ }
17588
17716
  if (step.status === "active") {
17589
17717
  return /* @__PURE__ */ jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: accent, color: "white" }), children: n });
17590
17718
  }
@@ -17593,6 +17721,44 @@ function IndexDot({ step, index, accent }) {
17593
17721
  }
17594
17722
  return /* @__PURE__ */ jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#f2f2f2", color: "#9ca3af" }), children: n });
17595
17723
  }
17724
+ function EvalBadge({ step }) {
17725
+ var _a2;
17726
+ const ev = step.eval;
17727
+ if (!ev || ev.judge_ok === false) return null;
17728
+ const score = typeof ev.score === "number" ? ev.score : null;
17729
+ const flags = (_a2 = ev.data_quality_flags) != null ? _a2 : [];
17730
+ const bad = ev.verdict === "bad" || score !== null && score < 0.8;
17731
+ const tip = flags.length > 0 ? flags.map((f) => {
17732
+ var _a3;
17733
+ return `${(_a3 = f.severity) != null ? _a3 : "?"}: ${f.details || f.issue || f.field || "issue"}`;
17734
+ }).join("\n") : ev.reasoning || void 0;
17735
+ const label = score !== null ? score.toFixed(2) : bad ? "flagged" : "ok";
17736
+ return /* @__PURE__ */ jsxs(
17737
+ "span",
17738
+ {
17739
+ title: tip,
17740
+ "data-testid": `workflow-stepper-eval-${step.id}`,
17741
+ style: {
17742
+ display: "inline-flex",
17743
+ alignItems: "center",
17744
+ gap: 3,
17745
+ fontSize: 9,
17746
+ fontWeight: 700,
17747
+ padding: "1px 6px",
17748
+ borderRadius: 9999,
17749
+ background: bad ? "#fff7ed" : "#dcfce7",
17750
+ color: bad ? "#b45309" : "#15803d",
17751
+ whiteSpace: "nowrap",
17752
+ flexShrink: 0
17753
+ },
17754
+ children: [
17755
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: bad ? "\u26A0" : "\u2713" }),
17756
+ label,
17757
+ flags.length > 0 ? ` \xB7 ${flags.length}` : ""
17758
+ ]
17759
+ }
17760
+ );
17761
+ }
17596
17762
  var CARD_MIN = 132;
17597
17763
  var CARD_GAP = 16;
17598
17764
  var AUTO_COMPACT_BELOW = 360;
@@ -17617,6 +17783,7 @@ var KEYFRAMES = `
17617
17783
  @keyframes wfsLampPulse{0%,100%{box-shadow:0 0 0 0 var(--wfs-accent,#6366f1)73}50%{box-shadow:0 0 0 4px transparent}}
17618
17784
  @keyframes wfsRise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
17619
17785
  @keyframes wfsShimmer{0%{background-position:-200px 0}100%{background-position:calc(200px + 100%) 0}}
17786
+ @keyframes wfsSpin{to{transform:rotate(360deg)}}
17620
17787
  .wfs-rise{animation:wfsRise 0.32s cubic-bezier(0.22,1,0.36,1) both}
17621
17788
  @media (prefers-reduced-motion: reduce){
17622
17789
  .wfs-anim,.wfs-rise,.wfs-shim{animation:none !important}
@@ -17697,7 +17864,7 @@ function WorkflowStepperRenderer({
17697
17864
  const steps = (_a2 = data.steps) != null ? _a2 : [];
17698
17865
  const activeStepId = (_d = (_c = data.active_step) != null ? _c : (_b = steps.find((s) => s.status === "active")) == null ? void 0 : _b.id) != null ? _d : null;
17699
17866
  const interactive = typeof onSelectStep === "function";
17700
- const statusColor3 = (s) => s === "active" ? ACCENT2 : STATUS_COLORS3[s];
17867
+ const statusColor3 = (s) => s === "active" || s === "running" ? ACCENT2 : STATUS_COLORS3[s];
17701
17868
  const doneCount = steps.filter((s) => s.status === "done").length;
17702
17869
  const rootRef = React45.useRef(null);
17703
17870
  const containerW = useContainerWidth(rootRef);
@@ -17925,6 +18092,7 @@ function WorkflowStepperRenderer({
17925
18092
  var _a3;
17926
18093
  const isSelected = selectedStep === step.id;
17927
18094
  const isActive = step.status === "active";
18095
+ const isRunning = step.status === "running";
17928
18096
  const reached = step.status !== "pending";
17929
18097
  const clickable = interactive && reached;
17930
18098
  const color = statusColor3(step.status);
@@ -18021,36 +18189,41 @@ function WorkflowStepperRenderer({
18021
18189
  }
18022
18190
  }
18023
18191
  ),
18024
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
18025
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
18192
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 4 }, children: [
18193
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, minWidth: 0 }, children: [
18026
18194
  /* @__PURE__ */ jsx(IndexDot, { step, index: i, accent: ACCENT2 }),
18027
18195
  /* @__PURE__ */ jsx(
18028
18196
  "span",
18029
18197
  {
18030
- className: isActive ? "wfs-anim" : void 0,
18198
+ className: isActive || isRunning ? "wfs-anim" : void 0,
18031
18199
  style: {
18032
18200
  width: 6,
18033
18201
  height: 6,
18034
18202
  borderRadius: "50%",
18035
18203
  background: color,
18036
- animation: isActive ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
18204
+ flexShrink: 0,
18205
+ animation: isActive || isRunning ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
18037
18206
  }
18038
18207
  }
18039
18208
  )
18040
18209
  ] }),
18041
- /* @__PURE__ */ jsx(
18042
- "span",
18043
- {
18044
- style: {
18045
- fontSize: 9,
18046
- fontWeight: 600,
18047
- letterSpacing: "0.05em",
18048
- textTransform: "uppercase",
18049
- color
18050
- },
18051
- children: STATUS_LABELS[step.status]
18052
- }
18053
- )
18210
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4, minWidth: 0 }, children: [
18211
+ /* @__PURE__ */ jsx(EvalBadge, { step }),
18212
+ /* @__PURE__ */ jsx(
18213
+ "span",
18214
+ {
18215
+ style: {
18216
+ fontSize: 9,
18217
+ fontWeight: 600,
18218
+ letterSpacing: "0.05em",
18219
+ textTransform: "uppercase",
18220
+ color,
18221
+ whiteSpace: "nowrap"
18222
+ },
18223
+ children: STATUS_LABELS[step.status]
18224
+ }
18225
+ )
18226
+ ] })
18054
18227
  ] }),
18055
18228
  /* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
18056
18229
  /* @__PURE__ */ jsx(
@@ -18240,12 +18413,14 @@ var BADGE_TITLE = {
18240
18413
  var BADGE_STYLE = {
18241
18414
  SC: { bg: "#dcfce7", fg: "#15803d" },
18242
18415
  CN: { bg: "#eff6ff", fg: "#0364ff" },
18416
+ // theme-ok (SECONDARY)
18243
18417
  AB: { bg: "#fff7ed", fg: "#92400e" },
18244
18418
  SW: { bg: "#fef2f2", fg: "#dc2626" }
18245
18419
  };
18246
18420
  var STATE_DOT = {
18247
18421
  ok: "#15803d",
18248
18422
  corrected: "#0364ff",
18423
+ // theme-ok (SECONDARY)
18249
18424
  missing: "#dc2626",
18250
18425
  warn: "#f59e0b"
18251
18426
  };
@@ -18608,6 +18783,7 @@ var BADGE_DOT = {
18608
18783
  missing: "#dc2626",
18609
18784
  red: "#dc2626",
18610
18785
  corrected: "#0364ff"
18786
+ // theme-ok (SECONDARY)
18611
18787
  };
18612
18788
  function FieldDetails({
18613
18789
  summary,
@@ -19899,8 +20075,15 @@ function useContainerWidth2(ref) {
19899
20075
  var KEYFRAMES2 = `
19900
20076
  @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
19901
20077
  .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
20078
+ .dc-range{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:9999px;outline:none;cursor:pointer;background:transparent}
20079
+ .dc-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border-radius:50%;background:white;border:2px solid var(--dc-thumb,#ff5000);box-shadow:0 1px 3px rgba(0,0,0,0.18);cursor:grab;transition:transform 0.12s}
20080
+ .dc-range::-webkit-slider-thumb:hover{transform:scale(1.12)}
20081
+ .dc-range:active::-webkit-slider-thumb{cursor:grabbing}
20082
+ .dc-range::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:white;border:2px solid var(--dc-thumb,#ff5000);box-shadow:0 1px 3px rgba(0,0,0,0.18);cursor:grab}
20083
+ .dc-range::-moz-range-track{height:4px;border-radius:9999px;background:transparent}
19902
20084
  @media (prefers-reduced-motion: reduce){
19903
20085
  .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
20086
+ .dc-range::-webkit-slider-thumb{transition:none}
19904
20087
  }`;
19905
20088
  function SparkCheck({ size, color }) {
19906
20089
  return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
@@ -19946,17 +20129,239 @@ function FlagPill({ flag }) {
19946
20129
  }
19947
20130
  );
19948
20131
  }
20132
+ function formatFigure(value, unit) {
20133
+ const body = Number.isInteger(value) ? `${value}` : `${Math.round(value * 100) / 100}`;
20134
+ if (!unit) return body;
20135
+ return unit === "%" ? `${body}%` : `${body} ${unit}`;
20136
+ }
20137
+ function clampToRange(raw, adjust) {
20138
+ var _a2;
20139
+ const step = (_a2 = adjust.step) != null ? _a2 : Number.isInteger(adjust.min) && Number.isInteger(adjust.max) ? 1 : (adjust.max - adjust.min) / 100;
20140
+ const snapped = Math.round((raw - adjust.min) / step) * step + adjust.min;
20141
+ const fixed = Math.round(snapped * 1e6) / 1e6;
20142
+ return Math.min(adjust.max, Math.max(adjust.min, fixed));
20143
+ }
20144
+ function ValueAdjuster({
20145
+ option,
20146
+ accent,
20147
+ border,
20148
+ muted,
20149
+ onConfirm,
20150
+ onBack
20151
+ }) {
20152
+ var _a2, _b;
20153
+ const adjust = option.adjust;
20154
+ const suggested = clampToRange((_a2 = option.value) != null ? _a2 : adjust.min, adjust);
20155
+ const [value, setValue] = React45.useState(suggested);
20156
+ const [text, setText] = React45.useState(String(suggested));
20157
+ const step = (_b = adjust.step) != null ? _b : Number.isInteger(adjust.min) && Number.isInteger(adjust.max) ? 1 : (adjust.max - adjust.min) / 100;
20158
+ const pct = adjust.max > adjust.min ? (value - adjust.min) / (adjust.max - adjust.min) * 100 : 0;
20159
+ const suggestedPct = adjust.max > adjust.min ? (suggested - adjust.min) / (adjust.max - adjust.min) * 100 : 0;
20160
+ const moved = value !== suggested;
20161
+ const commit = (raw) => {
20162
+ const v = clampToRange(raw, adjust);
20163
+ setValue(v);
20164
+ setText(String(v));
20165
+ };
20166
+ return /* @__PURE__ */ jsxs(
20167
+ "div",
20168
+ {
20169
+ className: "dc-rise",
20170
+ "data-testid": "decision-card-adjuster",
20171
+ style: {
20172
+ display: "flex",
20173
+ flexDirection: "column",
20174
+ gap: 12,
20175
+ border: `1px solid ${border}`,
20176
+ borderRadius: 10,
20177
+ padding: "12px 14px",
20178
+ background: "#fafafa"
20179
+ },
20180
+ children: [
20181
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 8 }, children: [
20182
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.06em", color: muted }, children: [
20183
+ "Adjust \xB7 ",
20184
+ option.label
20185
+ ] }),
20186
+ /* @__PURE__ */ jsx("span", { style: { flex: 1 } }),
20187
+ /* @__PURE__ */ jsx(
20188
+ "button",
20189
+ {
20190
+ type: "button",
20191
+ onClick: onBack,
20192
+ "data-testid": "decision-card-adjust-back",
20193
+ style: { border: "none", background: "none", padding: 0, cursor: "pointer", fontSize: 12, fontWeight: 600, color: muted },
20194
+ children: "Back"
20195
+ }
20196
+ )
20197
+ ] }),
20198
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 6 }, children: [
20199
+ /* @__PURE__ */ jsx(
20200
+ "input",
20201
+ {
20202
+ value: text,
20203
+ onChange: (e) => {
20204
+ setText(e.target.value);
20205
+ const n = Number(e.target.value);
20206
+ if (Number.isFinite(n)) setValue(clampToRange(n, adjust));
20207
+ },
20208
+ onBlur: () => commit(Number(text) || suggested),
20209
+ onKeyDown: (e) => {
20210
+ if (e.key === "Enter") {
20211
+ const v = clampToRange(Number(text) || suggested, adjust);
20212
+ commit(v);
20213
+ onConfirm(v);
20214
+ } else if (e.key === "ArrowUp") {
20215
+ e.preventDefault();
20216
+ commit(value + step);
20217
+ } else if (e.key === "ArrowDown") {
20218
+ e.preventDefault();
20219
+ commit(value - step);
20220
+ }
20221
+ },
20222
+ inputMode: "decimal",
20223
+ "aria-label": `${option.label} value`,
20224
+ "data-testid": "decision-card-adjust-input",
20225
+ style: {
20226
+ width: `${Math.max(3, String(text).length + 1)}ch`,
20227
+ fontSize: 26,
20228
+ fontWeight: 700,
20229
+ fontVariantNumeric: "tabular-nums",
20230
+ letterSpacing: "-0.02em",
20231
+ color: "var(--foreground)",
20232
+ border: "none",
20233
+ borderBottom: `2px solid ${accent}`,
20234
+ background: "transparent",
20235
+ outline: "none",
20236
+ padding: 0
20237
+ }
20238
+ }
20239
+ ),
20240
+ adjust.unit && /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: muted }, children: adjust.unit }),
20241
+ moved && /* @__PURE__ */ jsxs(
20242
+ "button",
20243
+ {
20244
+ type: "button",
20245
+ onClick: () => commit(suggested),
20246
+ "data-testid": "decision-card-adjust-reset",
20247
+ style: {
20248
+ marginLeft: 8,
20249
+ border: "none",
20250
+ background: "none",
20251
+ padding: 0,
20252
+ cursor: "pointer",
20253
+ fontSize: 11.5,
20254
+ fontWeight: 600,
20255
+ color: muted,
20256
+ textDecoration: "underline",
20257
+ textUnderlineOffset: 2
20258
+ },
20259
+ children: [
20260
+ "Reset to suggested (",
20261
+ formatFigure(suggested, adjust.unit),
20262
+ ")"
20263
+ ]
20264
+ }
20265
+ )
20266
+ ] }),
20267
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
20268
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative", height: 16, display: "flex", alignItems: "center" }, children: [
20269
+ /* @__PURE__ */ jsx(
20270
+ "div",
20271
+ {
20272
+ "aria-hidden": "true",
20273
+ style: {
20274
+ position: "absolute",
20275
+ left: 0,
20276
+ right: 0,
20277
+ height: 4,
20278
+ borderRadius: 9999,
20279
+ background: `linear-gradient(to right, ${accent} ${pct}%, #e8e8e8 ${pct}%)`
20280
+ }
20281
+ }
20282
+ ),
20283
+ moved && /* @__PURE__ */ jsx(
20284
+ "div",
20285
+ {
20286
+ "aria-hidden": "true",
20287
+ title: `Suggested: ${formatFigure(suggested, adjust.unit)}`,
20288
+ style: {
20289
+ position: "absolute",
20290
+ left: `${suggestedPct}%`,
20291
+ transform: "translateX(-50%)",
20292
+ width: 2,
20293
+ height: 10,
20294
+ borderRadius: 1,
20295
+ background: muted,
20296
+ opacity: 0.55
20297
+ }
20298
+ }
20299
+ ),
20300
+ /* @__PURE__ */ jsx(
20301
+ "input",
20302
+ {
20303
+ type: "range",
20304
+ className: "dc-range",
20305
+ min: adjust.min,
20306
+ max: adjust.max,
20307
+ step,
20308
+ value,
20309
+ onChange: (e) => commit(Number(e.target.value)),
20310
+ "aria-label": `${option.label} slider`,
20311
+ "data-testid": "decision-card-adjust-slider",
20312
+ style: { position: "relative", ["--dc-thumb"]: accent }
20313
+ }
20314
+ )
20315
+ ] }),
20316
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 10.5, fontWeight: 600, color: muted, fontVariantNumeric: "tabular-nums" }, children: [
20317
+ /* @__PURE__ */ jsx("span", { children: formatFigure(adjust.min, adjust.unit) }),
20318
+ /* @__PURE__ */ jsx("span", { children: formatFigure(adjust.max, adjust.unit) })
20319
+ ] })
20320
+ ] }),
20321
+ /* @__PURE__ */ jsxs(
20322
+ "button",
20323
+ {
20324
+ type: "button",
20325
+ onClick: () => onConfirm(value),
20326
+ "data-testid": "decision-card-adjust-confirm",
20327
+ style: {
20328
+ alignSelf: "flex-start",
20329
+ border: `1px solid ${accent}`,
20330
+ background: accent,
20331
+ color: "white",
20332
+ borderRadius: 8,
20333
+ fontSize: 13,
20334
+ fontWeight: 600,
20335
+ padding: "9px 16px",
20336
+ cursor: "pointer",
20337
+ fontVariantNumeric: "tabular-nums",
20338
+ transition: "opacity 0.15s"
20339
+ },
20340
+ onMouseEnter: (e) => e.currentTarget.style.opacity = "0.88",
20341
+ onMouseLeave: (e) => e.currentTarget.style.opacity = "1",
20342
+ children: [
20343
+ option.label,
20344
+ " \xB7 ",
20345
+ formatFigure(value, adjust.unit)
20346
+ ]
20347
+ }
20348
+ )
20349
+ ]
20350
+ }
20351
+ );
20352
+ }
19949
20353
  function DecisionCardRenderer({
19950
20354
  data,
19951
20355
  resolved = null,
19952
20356
  onResolve,
19953
20357
  onOpenSource
19954
20358
  }) {
19955
- var _a2, _b;
20359
+ var _a2, _b, _c;
19956
20360
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
19957
20361
  const rootRef = React45.useRef(null);
19958
20362
  const width = useContainerWidth2(rootRef);
19959
20363
  const stacked = width > 0 && width < STACK_BELOW;
20364
+ const [adjustingIdx, setAdjustingIdx] = React45.useState(null);
19960
20365
  const options = (_a2 = data.options) != null ? _a2 : [];
19961
20366
  const recommendedIdx = Math.max(
19962
20367
  0,
@@ -20111,7 +20516,20 @@ function DecisionCardRenderer({
20111
20516
  ]
20112
20517
  }
20113
20518
  ) : /* @__PURE__ */ jsxs(Fragment, { children: [
20114
- /* @__PURE__ */ jsx(
20519
+ adjustingIdx != null && ((_b = options[adjustingIdx]) == null ? void 0 : _b.adjust) ? /* @__PURE__ */ jsx(
20520
+ ValueAdjuster,
20521
+ {
20522
+ option: options[adjustingIdx],
20523
+ accent: ACCENT2,
20524
+ border: BORDER4,
20525
+ muted: MUTED2,
20526
+ onBack: () => setAdjustingIdx(null),
20527
+ onConfirm: (value) => {
20528
+ setAdjustingIdx(null);
20529
+ onResolve == null ? void 0 : onResolve(options[adjustingIdx].label, value);
20530
+ }
20531
+ }
20532
+ ) : /* @__PURE__ */ jsx(
20115
20533
  "div",
20116
20534
  {
20117
20535
  style: {
@@ -20121,15 +20539,21 @@ function DecisionCardRenderer({
20121
20539
  gap: 8
20122
20540
  },
20123
20541
  children: options.map((opt, idx) => {
20124
- var _a3;
20542
+ var _a3, _b2;
20125
20543
  const primary = idx === recommendedIdx;
20126
- return /* @__PURE__ */ jsx(
20544
+ const adjustable = Boolean(opt.adjust);
20545
+ return /* @__PURE__ */ jsxs(
20127
20546
  "button",
20128
20547
  {
20129
20548
  type: "button",
20130
- onClick: () => onResolve == null ? void 0 : onResolve(opt.label),
20549
+ onClick: () => adjustable ? setAdjustingIdx(idx) : onResolve == null ? void 0 : onResolve(opt.label),
20550
+ "data-adjustable": adjustable || void 0,
20131
20551
  style: {
20132
20552
  width: stacked ? "100%" : "auto",
20553
+ display: "inline-flex",
20554
+ alignItems: "center",
20555
+ justifyContent: stacked ? "flex-start" : "center",
20556
+ gap: 7,
20133
20557
  textAlign: stacked ? "left" : "center",
20134
20558
  border: `1px solid ${primary ? ACCENT2 : BORDER4}`,
20135
20559
  background: primary ? ACCENT2 : "white",
@@ -20157,7 +20581,28 @@ function DecisionCardRenderer({
20157
20581
  e.currentTarget.style.background = "white";
20158
20582
  }
20159
20583
  },
20160
- children: opt.label
20584
+ children: [
20585
+ opt.label,
20586
+ adjustable && typeof opt.value === "number" && /* @__PURE__ */ jsxs(
20587
+ "span",
20588
+ {
20589
+ style: {
20590
+ fontSize: 11.5,
20591
+ fontWeight: 700,
20592
+ fontVariantNumeric: "tabular-nums",
20593
+ padding: "1px 7px",
20594
+ borderRadius: 9999,
20595
+ background: primary ? "rgba(255,255,255,0.22)" : "#f2f2f2",
20596
+ color: primary ? "white" : MUTED2,
20597
+ lineHeight: 1.5
20598
+ },
20599
+ children: [
20600
+ formatFigure(opt.value, (_b2 = opt.adjust) == null ? void 0 : _b2.unit),
20601
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { marginLeft: 4, opacity: 0.8 }, children: "\u270E" })
20602
+ ]
20603
+ }
20604
+ )
20605
+ ]
20161
20606
  },
20162
20607
  (_a3 = opt.id) != null ? _a3 : opt.label
20163
20608
  );
@@ -20196,7 +20641,7 @@ function DecisionCardRenderer({
20196
20641
  strokeLinejoin: "round"
20197
20642
  }
20198
20643
  ) }),
20199
- (_b = data.source.label) != null ? _b : "View source for this figure"
20644
+ (_c = data.source.label) != null ? _c : "View source for this figure"
20200
20645
  ]
20201
20646
  }
20202
20647
  )
@@ -20205,20 +20650,27 @@ function DecisionCardRenderer({
20205
20650
  }
20206
20651
  );
20207
20652
  }
20653
+ function composeResolution(p, option, value) {
20654
+ var _a2, _b, _c;
20655
+ if (value == null) return option;
20656
+ const unit = (_c = (_b = ((_a2 = p.options) != null ? _a2 : []).find((o) => o.label === option)) == null ? void 0 : _b.adjust) == null ? void 0 : _c.unit;
20657
+ return `${option} \xB7 ${formatFigure(value, unit)}`;
20658
+ }
20208
20659
  function DecisionCardResolver(p) {
20209
- var _a2, _b, _c, _d;
20660
+ var _a2, _b;
20210
20661
  const { resolvedDecisions, onDecisionResolve, onDecisionSource } = useGenUIInteraction();
20211
20662
  const decisionId = (_a2 = p.id) != null ? _a2 : p.title;
20212
20663
  const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
20213
- const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
20664
+ const initial = hostResolved != null ? hostResolved : p.resolved ? composeResolution(p, p.resolved.option, p.resolved.value) : null;
20214
20665
  const [localResolved, setLocalResolved] = React45.useState(initial);
20215
20666
  React45.useEffect(() => {
20216
20667
  if (hostResolved !== void 0) setLocalResolved(hostResolved);
20217
20668
  }, [hostResolved]);
20218
20669
  const resolved = hostResolved != null ? hostResolved : localResolved;
20219
- const handleResolve = (option) => {
20220
- setLocalResolved(option);
20221
- onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, option);
20670
+ const handleResolve = (option, value) => {
20671
+ const resolution = composeResolution(p, option, value);
20672
+ setLocalResolved(resolution);
20673
+ onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, resolution);
20222
20674
  };
20223
20675
  const handleSource = () => {
20224
20676
  var _a3;
@@ -20227,7 +20679,7 @@ function DecisionCardResolver(p) {
20227
20679
  window.open(p.source.url, "_blank", "noopener,noreferrer");
20228
20680
  }
20229
20681
  };
20230
- return /* @__PURE__ */ jsx(ComponentActions, { filename: (_d = p.title) != null ? _d : "decision-card", children: /* @__PURE__ */ jsx(
20682
+ return /* @__PURE__ */ jsx(ComponentActions, { filename: (_b = p.title) != null ? _b : "decision-card", children: /* @__PURE__ */ jsx(
20231
20683
  DecisionCardRenderer,
20232
20684
  {
20233
20685
  data: p,
@@ -20237,6 +20689,317 @@ function DecisionCardResolver(p) {
20237
20689
  }
20238
20690
  ) });
20239
20691
  }
20692
+ init_ThemeContext();
20693
+ var CONNECTED_GREEN3 = "#15803d";
20694
+ var CONNECTED_GREEN_BG = "#dcfce7";
20695
+ var PENDING_AMBER = "#92400e";
20696
+ var PENDING_AMBER_BG = "#fff7ed";
20697
+ var CARD_TITLE = "Authentication required";
20698
+ var TRUST_FOOTER = "Credentials not stored by Adopt";
20699
+ var DEFAULT_STEPS = (app, ctaLabel, connected) => connected ? [
20700
+ `Click ${ctaLabel} below to open ${app} in a new tab.`,
20701
+ "Confirm you are signed in \u2014 re-authenticate if prompted.",
20702
+ "Return here \u2014 the request continues automatically."
20703
+ ] : [
20704
+ `Click ${ctaLabel} below to open the sign-in page.`,
20705
+ `Sign in with your ${app} credentials \u2014 SSO is supported.`,
20706
+ "Return here \u2014 the request resumes automatically."
20707
+ ];
20708
+ function humanizeApp(raw) {
20709
+ const v = raw.trim();
20710
+ if (!v) return v;
20711
+ const looksLikeSlug = /^[a-z0-9]+([_-][a-z0-9]+)*$/.test(v);
20712
+ if (!looksLikeSlug) return v;
20713
+ return v.split(/[_-]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
20714
+ }
20715
+ function ShieldIcon({ color }) {
20716
+ return /* @__PURE__ */ jsxs(
20717
+ "svg",
20718
+ {
20719
+ width: "13",
20720
+ height: "13",
20721
+ viewBox: "0 0 24 24",
20722
+ fill: "none",
20723
+ stroke: color,
20724
+ strokeWidth: "2",
20725
+ strokeLinecap: "round",
20726
+ strokeLinejoin: "round",
20727
+ "aria-hidden": "true",
20728
+ style: { flexShrink: 0 },
20729
+ children: [
20730
+ /* @__PURE__ */ jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
20731
+ /* @__PURE__ */ jsx("path", { d: "m9 12 2 2 4-4" })
20732
+ ]
20733
+ }
20734
+ );
20735
+ }
20736
+ function ExternalIcon() {
20737
+ return /* @__PURE__ */ jsxs(
20738
+ "svg",
20739
+ {
20740
+ width: "13",
20741
+ height: "13",
20742
+ viewBox: "0 0 24 24",
20743
+ fill: "none",
20744
+ stroke: "currentColor",
20745
+ strokeWidth: "2",
20746
+ strokeLinecap: "round",
20747
+ strokeLinejoin: "round",
20748
+ "aria-hidden": "true",
20749
+ style: { flexShrink: 0 },
20750
+ children: [
20751
+ /* @__PURE__ */ jsx("path", { d: "M15 3h6v6" }),
20752
+ /* @__PURE__ */ jsx("path", { d: "M10 14 21 3" }),
20753
+ /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" })
20754
+ ]
20755
+ }
20756
+ );
20757
+ }
20758
+ function TabbyAuthResolver(p) {
20759
+ var _a2, _b, _c;
20760
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
20761
+ const [cardHovered, setCardHovered] = useState(false);
20762
+ const [btnHovered, setBtnHovered] = useState(false);
20763
+ const [imgFailed, setImgFailed] = useState(false);
20764
+ const app = humanizeApp(p.app || "the app");
20765
+ const connected = p.state === "connected";
20766
+ const accent = connected ? CONNECTED_GREEN3 : ACCENT2;
20767
+ const ctaLabel = (_a2 = p.ctaLabel) != null ? _a2 : connected ? `Open ${app}` : `Connect ${app}`;
20768
+ const subtitle = p.workspace ? `${app} \xB7 ${p.workspace} workspace` : app;
20769
+ const steps = ((_b = p.steps) == null ? void 0 : _b.length) ? p.steps : DEFAULT_STEPS(app, ctaLabel, connected);
20770
+ 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.`;
20771
+ const iconSrc = p.iconUrl || brandIconUrl(app);
20772
+ const showImg = Boolean(iconSrc) && !imgFailed;
20773
+ const initial = app.charAt(0).toUpperCase();
20774
+ const badge = connected ? { label: "Connected", bg: CONNECTED_GREEN_BG, color: CONNECTED_GREEN3 } : { label: "Pending sign-in", bg: PENDING_AMBER_BG, color: PENDING_AMBER };
20775
+ const sectionPad = "13px 16px";
20776
+ return /* @__PURE__ */ jsx(ComponentActions, { filename: `${app} authentication`, children: /* @__PURE__ */ jsx("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "10px" }, children: /* @__PURE__ */ jsxs(
20777
+ "div",
20778
+ {
20779
+ onMouseEnter: () => setCardHovered(true),
20780
+ onMouseLeave: () => setCardHovered(false),
20781
+ style: {
20782
+ display: "flex",
20783
+ flexDirection: "row",
20784
+ alignItems: "stretch",
20785
+ borderRadius: "0.75rem",
20786
+ border: `1px solid ${cardHovered ? "#d2d2d2" : BORDER4}`,
20787
+ background: "white",
20788
+ overflow: "hidden",
20789
+ 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)",
20790
+ transition: "box-shadow 0.18s ease, border-color 0.18s ease"
20791
+ },
20792
+ children: [
20793
+ /* @__PURE__ */ jsx("div", { style: { width: "3px", flexShrink: 0, background: accent } }),
20794
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }, children: [
20795
+ /* @__PURE__ */ jsxs(
20796
+ "div",
20797
+ {
20798
+ style: {
20799
+ display: "flex",
20800
+ alignItems: "flex-start",
20801
+ gap: "12px",
20802
+ padding: sectionPad
20803
+ },
20804
+ children: [
20805
+ /* @__PURE__ */ jsx(
20806
+ "div",
20807
+ {
20808
+ style: {
20809
+ position: "relative",
20810
+ width: "34px",
20811
+ height: "34px",
20812
+ borderRadius: "9px",
20813
+ flexShrink: 0,
20814
+ display: "flex",
20815
+ alignItems: "center",
20816
+ justifyContent: "center",
20817
+ background: showImg ? "white" : "#fff3ee",
20818
+ boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.06)",
20819
+ overflow: "hidden"
20820
+ },
20821
+ children: showImg ? /* @__PURE__ */ jsx(
20822
+ "img",
20823
+ {
20824
+ src: iconSrc,
20825
+ alt: app,
20826
+ onError: () => setImgFailed(true),
20827
+ style: { width: "22px", height: "22px", objectFit: "contain" }
20828
+ }
20829
+ ) : /* @__PURE__ */ jsx(
20830
+ "span",
20831
+ {
20832
+ style: {
20833
+ fontFamily: "var(--font-serif)",
20834
+ fontSize: "17px",
20835
+ fontWeight: 400,
20836
+ color: ACCENT2,
20837
+ lineHeight: 1
20838
+ },
20839
+ children: initial
20840
+ }
20841
+ )
20842
+ }
20843
+ ),
20844
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "2px" }, children: [
20845
+ /* @__PURE__ */ jsx(
20846
+ "span",
20847
+ {
20848
+ style: {
20849
+ fontFamily: "var(--font-serif)",
20850
+ fontSize: "15px",
20851
+ fontWeight: 400,
20852
+ color: "var(--foreground)",
20853
+ letterSpacing: "-0.01em",
20854
+ lineHeight: 1.2
20855
+ },
20856
+ children: CARD_TITLE
20857
+ }
20858
+ ),
20859
+ /* @__PURE__ */ jsx(
20860
+ "span",
20861
+ {
20862
+ style: {
20863
+ fontSize: "12px",
20864
+ color: MUTED2,
20865
+ whiteSpace: "nowrap",
20866
+ overflow: "hidden",
20867
+ textOverflow: "ellipsis"
20868
+ },
20869
+ children: subtitle
20870
+ }
20871
+ )
20872
+ ] }),
20873
+ /* @__PURE__ */ jsxs(
20874
+ "span",
20875
+ {
20876
+ style: {
20877
+ display: "inline-flex",
20878
+ alignItems: "center",
20879
+ gap: "5px",
20880
+ flexShrink: 0,
20881
+ fontSize: "10.5px",
20882
+ fontWeight: 600,
20883
+ padding: "3px 9px",
20884
+ borderRadius: "9999px",
20885
+ background: badge.bg,
20886
+ color: badge.color,
20887
+ whiteSpace: "nowrap"
20888
+ },
20889
+ children: [
20890
+ /* @__PURE__ */ jsx(
20891
+ "span",
20892
+ {
20893
+ style: {
20894
+ width: "6px",
20895
+ height: "6px",
20896
+ borderRadius: "9999px",
20897
+ background: badge.color
20898
+ }
20899
+ }
20900
+ ),
20901
+ badge.label
20902
+ ]
20903
+ }
20904
+ )
20905
+ ]
20906
+ }
20907
+ ),
20908
+ /* @__PURE__ */ jsxs(
20909
+ "div",
20910
+ {
20911
+ style: {
20912
+ borderTop: `1px solid ${BORDER4}`,
20913
+ padding: sectionPad,
20914
+ display: "flex",
20915
+ flexDirection: "column",
20916
+ gap: "12px"
20917
+ },
20918
+ children: [
20919
+ description && /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "12.5px", lineHeight: 1.5, color: "var(--foreground)" }, children: description }),
20920
+ /* @__PURE__ */ jsx("ol", { style: { margin: 0, padding: 0, listStyle: "none", display: "flex", flexDirection: "column", gap: "8px" }, children: steps.map((step, i) => /* @__PURE__ */ jsxs("li", { style: { display: "flex", alignItems: "flex-start", gap: "10px" }, children: [
20921
+ /* @__PURE__ */ jsx(
20922
+ "span",
20923
+ {
20924
+ style: {
20925
+ flexShrink: 0,
20926
+ width: "18px",
20927
+ height: "18px",
20928
+ borderRadius: "9999px",
20929
+ background: accent,
20930
+ color: "white",
20931
+ fontSize: "10.5px",
20932
+ fontWeight: 600,
20933
+ display: "flex",
20934
+ alignItems: "center",
20935
+ justifyContent: "center",
20936
+ marginTop: "1px"
20937
+ },
20938
+ children: i + 1
20939
+ }
20940
+ ),
20941
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "12.5px", lineHeight: 1.45, color: "var(--foreground)" }, children: step })
20942
+ ] }, i)) })
20943
+ ]
20944
+ }
20945
+ ),
20946
+ /* @__PURE__ */ jsxs(
20947
+ "div",
20948
+ {
20949
+ style: {
20950
+ borderTop: `1px solid ${BORDER4}`,
20951
+ padding: sectionPad,
20952
+ background: "#fbfbfb",
20953
+ display: "flex",
20954
+ alignItems: "center",
20955
+ justifyContent: "space-between",
20956
+ gap: "12px",
20957
+ flexWrap: "wrap"
20958
+ },
20959
+ children: [
20960
+ /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px", color: MUTED2, fontSize: "11.5px" }, children: [
20961
+ /* @__PURE__ */ jsx(ShieldIcon, { color: CONNECTED_GREEN3 }),
20962
+ TRUST_FOOTER
20963
+ ] }),
20964
+ /* @__PURE__ */ jsxs(
20965
+ "a",
20966
+ {
20967
+ href: p.url,
20968
+ target: "_blank",
20969
+ rel: "noopener noreferrer",
20970
+ onMouseEnter: () => setBtnHovered(true),
20971
+ onMouseLeave: () => setBtnHovered(false),
20972
+ style: {
20973
+ display: "inline-flex",
20974
+ alignItems: "center",
20975
+ gap: "7px",
20976
+ flexShrink: 0,
20977
+ borderRadius: "8px",
20978
+ padding: "8px 15px",
20979
+ fontSize: "12.5px",
20980
+ fontWeight: 600,
20981
+ textDecoration: "none",
20982
+ whiteSpace: "nowrap",
20983
+ cursor: "pointer",
20984
+ color: "white",
20985
+ border: "1px solid transparent",
20986
+ background: btnHovered ? connected ? "#126a33" : ACCENT_SOFT2 : accent,
20987
+ transition: "background 0.15s ease"
20988
+ },
20989
+ children: [
20990
+ /* @__PURE__ */ jsx(ExternalIcon, {}),
20991
+ ctaLabel
20992
+ ]
20993
+ }
20994
+ )
20995
+ ]
20996
+ }
20997
+ )
20998
+ ] })
20999
+ ]
21000
+ }
21001
+ ) }) });
21002
+ }
20240
21003
  function resolveUI(rawPayload) {
20241
21004
  const payload = coercePayload(rawPayload);
20242
21005
  switch (payload.type) {
@@ -20358,6 +21121,8 @@ function resolveUI(rawPayload) {
20358
21121
  return /* @__PURE__ */ jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
20359
21122
  case "decision-card":
20360
21123
  return /* @__PURE__ */ jsx(DecisionCardResolver, __spreadValues({}, payload));
21124
+ case "tabby-auth":
21125
+ return /* @__PURE__ */ jsx(TabbyAuthResolver, __spreadValues({}, payload));
20361
21126
  default: {
20362
21127
  return /* @__PURE__ */ jsx(
20363
21128
  "div",
@@ -21711,7 +22476,9 @@ function BlockForm({
21711
22476
  onEntityCreate,
21712
22477
  hideActions,
21713
22478
  dense,
21714
- variant = "form"
22479
+ variant = "form",
22480
+ fieldSuggestions,
22481
+ onApplySuggestion
21715
22482
  }) {
21716
22483
  var _a2;
21717
22484
  const t = useTheme();
@@ -21742,20 +22509,85 @@ function BlockForm({
21742
22509
  }
21743
22510
  ),
21744
22511
  ((_a2 = block.context) == null ? void 0 : _a2.type) && /* @__PURE__ */ jsx(ContextSlot, { payload: block.context }),
21745
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: dense ? "8px" : isEscalation ? "10px" : "12px" }, children: (block.fields || []).map((field) => /* @__PURE__ */ jsx("div", { "data-field-key": fieldKey(block.id, field.name), children: /* @__PURE__ */ jsx(
21746
- FieldRenderer,
21747
- {
21748
- field,
21749
- value: state.getValue(block.id, field.name),
21750
- onChange: (v) => state.setFieldValue(block.id, field.name, v),
21751
- disabled,
21752
- error: state.getError(block.id, field.name),
21753
- dense,
21754
- onFileUpload,
21755
- onEntitySearch,
21756
- onEntityCreate
21757
- }
21758
- ) }, `${block.id}:${field.name}`)) }),
22512
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: dense ? "8px" : isEscalation ? "10px" : "12px" }, children: (block.fields || []).map((field) => {
22513
+ var _a3;
22514
+ const suggestion = (fieldSuggestions || []).filter((sg) => {
22515
+ var _a4;
22516
+ return sg.field === field.name && ((_a4 = sg.block_id) != null ? _a4 : block.id) === block.id;
22517
+ }).slice(-1)[0];
22518
+ const current = state.getValue(block.id, field.name);
22519
+ const showSuggestion = suggestion != null && current !== suggestion.value;
22520
+ return /* @__PURE__ */ jsxs("div", { "data-field-key": fieldKey(block.id, field.name), children: [
22521
+ /* @__PURE__ */ jsx(
22522
+ FieldRenderer,
22523
+ {
22524
+ field,
22525
+ value: current,
22526
+ onChange: (v) => state.setFieldValue(block.id, field.name, v),
22527
+ disabled,
22528
+ error: state.getError(block.id, field.name),
22529
+ dense,
22530
+ onFileUpload,
22531
+ onEntitySearch,
22532
+ onEntityCreate
22533
+ }
22534
+ ),
22535
+ showSuggestion && !disabled ? /* @__PURE__ */ jsxs(
22536
+ "div",
22537
+ {
22538
+ "data-testid": `builder-suggestion-${field.name}`,
22539
+ style: {
22540
+ display: "flex",
22541
+ alignItems: "center",
22542
+ flexWrap: "wrap",
22543
+ gap: "6px",
22544
+ marginTop: "5px",
22545
+ padding: "5px 9px",
22546
+ borderRadius: "8px",
22547
+ border: `1px dashed ${t.BORDER}`,
22548
+ background: "#fafafa",
22549
+ fontSize: "11.5px",
22550
+ lineHeight: 1.4
22551
+ },
22552
+ children: [
22553
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { color: t.ACCENT, fontSize: "11px" }, children: "\u2726" }),
22554
+ /* @__PURE__ */ jsxs("span", { style: { color: t.MUTED, fontWeight: 600 }, children: [
22555
+ "Suggested:",
22556
+ " ",
22557
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--foreground)", fontVariantNumeric: "tabular-nums" }, children: (_a3 = suggestion.label) != null ? _a3 : String(suggestion.value) })
22558
+ ] }),
22559
+ suggestion.note ? /* @__PURE__ */ jsxs("span", { style: { color: t.MUTED }, children: [
22560
+ "\xB7 ",
22561
+ suggestion.note
22562
+ ] }) : null,
22563
+ /* @__PURE__ */ jsx("span", { style: { flex: 1 } }),
22564
+ /* @__PURE__ */ jsx(
22565
+ "button",
22566
+ {
22567
+ type: "button",
22568
+ "data-testid": `builder-suggestion-apply-${field.name}`,
22569
+ onClick: () => {
22570
+ state.setFieldValue(block.id, field.name, suggestion.value);
22571
+ onApplySuggestion == null ? void 0 : onApplySuggestion(suggestion);
22572
+ },
22573
+ style: {
22574
+ font: "inherit",
22575
+ fontSize: "11.5px",
22576
+ fontWeight: 700,
22577
+ color: t.ACCENT,
22578
+ background: "transparent",
22579
+ border: "none",
22580
+ padding: 0,
22581
+ cursor: "pointer"
22582
+ },
22583
+ children: "Apply"
22584
+ }
22585
+ )
22586
+ ]
22587
+ }
22588
+ ) : null
22589
+ ] }, `${block.id}:${field.name}`);
22590
+ }) }),
21759
22591
  hideActions ? null : /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px", paddingTop: isEscalation ? "2px" : "4px" }, children: [
21760
22592
  errorCount > 0 ? /* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", fontWeight: 600, color: "#dc2626" }, children: [
21761
22593
  errorCount,
@@ -22043,7 +22875,9 @@ function BuilderFormResolver({
22043
22875
  submitRef,
22044
22876
  hideActions,
22045
22877
  dense,
22046
- onValidationError
22878
+ onValidationError,
22879
+ fieldSuggestions,
22880
+ onApplySuggestion
22047
22881
  }) {
22048
22882
  var _a2;
22049
22883
  const state = useBuilderState(builder.blocks);
@@ -22120,7 +22954,9 @@ function BuilderFormResolver({
22120
22954
  onEntitySearch,
22121
22955
  onEntityCreate,
22122
22956
  hideActions,
22123
- dense
22957
+ dense,
22958
+ fieldSuggestions,
22959
+ onApplySuggestion
22124
22960
  }
22125
22961
  );
22126
22962
  default:
@@ -22137,7 +22973,9 @@ function BuilderFormResolver({
22137
22973
  onEntitySearch,
22138
22974
  onEntityCreate,
22139
22975
  dense,
22140
- hideActions
22976
+ hideActions,
22977
+ fieldSuggestions,
22978
+ onApplySuggestion
22141
22979
  }
22142
22980
  );
22143
22981
  }