@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/resolver.cjs CHANGED
@@ -5245,7 +5245,32 @@ var workflowStepperSchema = zod.z.object({
5245
5245
  n: zod.z.number().int().positive().optional(),
5246
5246
  title: zod.z.string(),
5247
5247
  sub: zod.z.string().optional(),
5248
- status: zod.z.enum(["done", "active", "review", "pending", "blocked", "failed"]),
5248
+ status: zod.z.enum([
5249
+ "done",
5250
+ "active",
5251
+ "running",
5252
+ "review",
5253
+ "pending",
5254
+ "blocked",
5255
+ "failed"
5256
+ ]),
5257
+ // Optional quality-gate verdict for a step run by an executor (e.g. a
5258
+ // pipeline). Surfaces a subtle trust badge; flags hint at issues a human
5259
+ // should review (the full list lives in the escalation dock).
5260
+ eval: zod.z.object({
5261
+ score: zod.z.number().min(0).max(1).nullable().optional(),
5262
+ verdict: zod.z.enum(["good", "bad"]).optional(),
5263
+ reasoning: zod.z.string().optional(),
5264
+ judge_ok: zod.z.boolean().optional(),
5265
+ data_quality_flags: zod.z.array(
5266
+ zod.z.object({
5267
+ field: zod.z.string().optional(),
5268
+ issue: zod.z.string().optional(),
5269
+ severity: zod.z.enum(["low", "medium", "high"]).optional(),
5270
+ details: zod.z.string().optional()
5271
+ })
5272
+ ).optional()
5273
+ }).optional(),
5249
5274
  assignees: zod.z.array(
5250
5275
  zod.z.object({
5251
5276
  name: zod.z.string(),
@@ -5281,7 +5306,32 @@ var workflowStepperTool = {
5281
5306
  n: { type: "number", description: "Step number; defaults to index + 1" },
5282
5307
  title: { type: "string" },
5283
5308
  sub: { type: "string", description: "Short status caption, e.g. '7 accounts \xB7 2 exceptions'" },
5284
- status: { type: "string", enum: ["done", "active", "review", "pending", "blocked", "failed"] },
5309
+ status: {
5310
+ type: "string",
5311
+ enum: ["done", "active", "running", "review", "pending", "blocked", "failed"]
5312
+ },
5313
+ eval: {
5314
+ type: "object",
5315
+ description: "Optional quality-gate verdict for an executor-run step.",
5316
+ properties: {
5317
+ score: { type: "number" },
5318
+ verdict: { type: "string", enum: ["good", "bad"] },
5319
+ reasoning: { type: "string" },
5320
+ judge_ok: { type: "boolean" },
5321
+ data_quality_flags: {
5322
+ type: "array",
5323
+ items: {
5324
+ type: "object",
5325
+ properties: {
5326
+ field: { type: "string" },
5327
+ issue: { type: "string" },
5328
+ severity: { type: "string", enum: ["low", "medium", "high"] },
5329
+ details: { type: "string" }
5330
+ }
5331
+ }
5332
+ }
5333
+ }
5334
+ },
5285
5335
  assignees: {
5286
5336
  type: "array",
5287
5337
  maxItems: 6,
@@ -5503,7 +5553,14 @@ var decisionCardSchema = zod.z.object({
5503
5553
  zod.z.object({
5504
5554
  id: zod.z.string().optional(),
5505
5555
  label: zod.z.string(),
5506
- recommended: zod.z.boolean().optional()
5556
+ recommended: zod.z.boolean().optional(),
5557
+ value: zod.z.number().optional(),
5558
+ adjust: zod.z.object({
5559
+ min: zod.z.number(),
5560
+ max: zod.z.number(),
5561
+ step: zod.z.number().optional(),
5562
+ unit: zod.z.string().optional()
5563
+ }).optional()
5507
5564
  })
5508
5565
  ).min(1).max(5),
5509
5566
  source: zod.z.object({
@@ -5511,7 +5568,8 @@ var decisionCardSchema = zod.z.object({
5511
5568
  url: zod.z.string().optional()
5512
5569
  }).optional(),
5513
5570
  resolved: zod.z.object({
5514
- option: zod.z.string()
5571
+ option: zod.z.string(),
5572
+ value: zod.z.number().optional()
5515
5573
  }).optional()
5516
5574
  });
5517
5575
  var decisionCardTool = {
@@ -5554,13 +5612,28 @@ var decisionCardTool = {
5554
5612
  type: "array",
5555
5613
  minItems: 1,
5556
5614
  maxItems: 5,
5557
- description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary",
5615
+ 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.",
5558
5616
  items: {
5559
5617
  type: "object",
5560
5618
  properties: {
5561
5619
  id: { type: "string" },
5562
5620
  label: { type: "string" },
5563
- recommended: { type: "boolean" }
5621
+ recommended: { type: "boolean" },
5622
+ value: {
5623
+ type: "number",
5624
+ description: "Suggested numeric figure for this option (the starting point of the adjuster)"
5625
+ },
5626
+ adjust: {
5627
+ type: "object",
5628
+ description: "Allow the user to tune `value` within this inclusive range before resolving",
5629
+ properties: {
5630
+ min: { type: "number" },
5631
+ max: { type: "number" },
5632
+ step: { type: "number", description: "Increment granularity; defaults to a sensible step for the range" },
5633
+ unit: { type: "string", description: "Short unit suffix shown after the number, e.g. 'units', '%', 'hrs'" }
5634
+ },
5635
+ required: ["min", "max"]
5636
+ }
5564
5637
  },
5565
5638
  required: ["label"]
5566
5639
  }
@@ -5577,7 +5650,8 @@ var decisionCardTool = {
5577
5650
  type: "object",
5578
5651
  description: "Pre-resolved state for transcript replay",
5579
5652
  properties: {
5580
- option: { type: "string" }
5653
+ option: { type: "string" },
5654
+ value: { type: "number", description: "Adjusted figure the user confirmed, when the option was adjustable" }
5581
5655
  },
5582
5656
  required: ["option"]
5583
5657
  }
@@ -5585,6 +5659,36 @@ var decisionCardTool = {
5585
5659
  required: ["type", "title", "question", "options"]
5586
5660
  }
5587
5661
  };
5662
+ var tabbyAuthSchema = zod.z.object({
5663
+ type: zod.z.literal("tabby-auth"),
5664
+ app: zod.z.string(),
5665
+ url: zod.z.string(),
5666
+ workspace: zod.z.string().optional(),
5667
+ state: zod.z.enum(["pending", "connected"]).optional(),
5668
+ ctaLabel: zod.z.string().optional(),
5669
+ steps: zod.z.array(zod.z.string()).optional(),
5670
+ description: zod.z.string().optional(),
5671
+ iconUrl: zod.z.string().optional()
5672
+ });
5673
+ var tabbyAuthTool = {
5674
+ name: "render_tabby_auth",
5675
+ 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.",
5676
+ input_schema: {
5677
+ type: "object",
5678
+ properties: {
5679
+ type: { type: "string", enum: ["tabby-auth"] },
5680
+ app: { type: "string" },
5681
+ url: { type: "string" },
5682
+ workspace: { type: "string" },
5683
+ state: { type: "string", enum: ["pending", "connected"] },
5684
+ ctaLabel: { type: "string" },
5685
+ steps: { type: "array", items: { type: "string" } },
5686
+ description: { type: "string" },
5687
+ iconUrl: { type: "string" }
5688
+ },
5689
+ required: ["type", "app", "url"]
5690
+ }
5691
+ };
5588
5692
 
5589
5693
  // src/schemas/index.ts
5590
5694
  var schemaRegistry = {
@@ -5646,7 +5750,8 @@ var schemaRegistry = {
5646
5750
  "pipeline-preview": { schema: pipelinePreviewSchema, tool: pipelinePreviewTool },
5647
5751
  "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5648
5752
  "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5649
- "decision-card": { schema: decisionCardSchema, tool: decisionCardTool }
5753
+ "decision-card": { schema: decisionCardSchema, tool: decisionCardTool },
5754
+ "tabby-auth": { schema: tabbyAuthSchema, tool: tabbyAuthTool }
5650
5755
  };
5651
5756
 
5652
5757
  // src/schemas/coercePayload.ts
@@ -6384,17 +6489,17 @@ function SparklineTableResolver(p) {
6384
6489
  // src/composites/heatmap-table/resolver.tsx
6385
6490
  init_theme();
6386
6491
  init_ThemeContext();
6387
- function heatColor(z60) {
6388
- const clamped = Math.max(-3, Math.min(3, z60));
6492
+ function heatColor(z61) {
6493
+ const clamped = Math.max(-3, Math.min(3, z61));
6389
6494
  const abs = Math.abs(clamped);
6390
6495
  const lightness = 95 - abs * 8;
6391
6496
  const hue = clamped >= 0 ? 142 : 0;
6392
6497
  return `hsl(${hue} 60% ${lightness}%)`;
6393
6498
  }
6394
- function heatTextColor(z60) {
6395
- const abs = Math.abs(z60);
6396
- if (abs > 2) return z60 >= 0 ? "#14532d" : "#7f1d1d";
6397
- if (abs > 1) return z60 >= 0 ? "#166534" : "#991b1b";
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";
6398
6503
  return "var(--foreground)";
6399
6504
  }
6400
6505
  var th2 = {
@@ -17452,6 +17557,8 @@ var STATUS_COLORS3 = {
17452
17557
  done: "#15803d",
17453
17558
  active: "",
17454
17559
  // filled from theme ACCENT at render time
17560
+ running: "",
17561
+ // filled from theme ACCENT at render time (executor in flight)
17455
17562
  review: "#f59e0b",
17456
17563
  pending: "#9ca3af",
17457
17564
  blocked: "#b45309",
@@ -17460,6 +17567,7 @@ var STATUS_COLORS3 = {
17460
17567
  var STATUS_LABELS = {
17461
17568
  done: "Complete",
17462
17569
  active: "In progress",
17570
+ running: "Running",
17463
17571
  review: "In review",
17464
17572
  pending: "Pending",
17465
17573
  blocked: "Blocked",
@@ -17563,6 +17671,26 @@ function IndexDot({ step, index, accent }) {
17563
17671
  if (step.status === "failed") {
17564
17672
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#dc2626", color: "white" }), children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 10 }, children: "!" }) });
17565
17673
  }
17674
+ if (step.status === "running") {
17675
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: __spreadProps(__spreadValues({}, base), { position: "relative", background: `${accent}1f`, color: accent }), children: [
17676
+ /* @__PURE__ */ jsxRuntime.jsx(
17677
+ "span",
17678
+ {
17679
+ className: "wfs-anim",
17680
+ "aria-hidden": "true",
17681
+ style: {
17682
+ position: "absolute",
17683
+ inset: 0,
17684
+ borderRadius: "50%",
17685
+ border: `1.5px solid ${accent}33`,
17686
+ borderTopColor: accent,
17687
+ animation: "wfsSpin 0.8s linear infinite"
17688
+ }
17689
+ }
17690
+ ),
17691
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 9 }, children: n })
17692
+ ] });
17693
+ }
17566
17694
  if (step.status === "active") {
17567
17695
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: accent, color: "white" }), children: n });
17568
17696
  }
@@ -17571,6 +17699,44 @@ function IndexDot({ step, index, accent }) {
17571
17699
  }
17572
17700
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#f2f2f2", color: "#9ca3af" }), children: n });
17573
17701
  }
17702
+ function EvalBadge({ step }) {
17703
+ var _a;
17704
+ const ev = step.eval;
17705
+ if (!ev || ev.judge_ok === false) return null;
17706
+ const score = typeof ev.score === "number" ? ev.score : null;
17707
+ const flags = (_a = ev.data_quality_flags) != null ? _a : [];
17708
+ const bad = ev.verdict === "bad" || score !== null && score < 0.8;
17709
+ const tip = flags.length > 0 ? flags.map((f) => {
17710
+ var _a2;
17711
+ return `${(_a2 = f.severity) != null ? _a2 : "?"}: ${f.details || f.issue || f.field || "issue"}`;
17712
+ }).join("\n") : ev.reasoning || void 0;
17713
+ const label = score !== null ? score.toFixed(2) : bad ? "flagged" : "ok";
17714
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17715
+ "span",
17716
+ {
17717
+ title: tip,
17718
+ "data-testid": `workflow-stepper-eval-${step.id}`,
17719
+ style: {
17720
+ display: "inline-flex",
17721
+ alignItems: "center",
17722
+ gap: 3,
17723
+ fontSize: 9,
17724
+ fontWeight: 700,
17725
+ padding: "1px 6px",
17726
+ borderRadius: 9999,
17727
+ background: bad ? "#fff7ed" : "#dcfce7",
17728
+ color: bad ? "#b45309" : "#15803d",
17729
+ whiteSpace: "nowrap",
17730
+ flexShrink: 0
17731
+ },
17732
+ children: [
17733
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: bad ? "\u26A0" : "\u2713" }),
17734
+ label,
17735
+ flags.length > 0 ? ` \xB7 ${flags.length}` : ""
17736
+ ]
17737
+ }
17738
+ );
17739
+ }
17574
17740
  var CARD_MIN = 132;
17575
17741
  var CARD_GAP = 16;
17576
17742
  var AUTO_COMPACT_BELOW = 360;
@@ -17595,6 +17761,7 @@ var KEYFRAMES = `
17595
17761
  @keyframes wfsLampPulse{0%,100%{box-shadow:0 0 0 0 var(--wfs-accent,#6366f1)73}50%{box-shadow:0 0 0 4px transparent}}
17596
17762
  @keyframes wfsRise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
17597
17763
  @keyframes wfsShimmer{0%{background-position:-200px 0}100%{background-position:calc(200px + 100%) 0}}
17764
+ @keyframes wfsSpin{to{transform:rotate(360deg)}}
17598
17765
  .wfs-rise{animation:wfsRise 0.32s cubic-bezier(0.22,1,0.36,1) both}
17599
17766
  @media (prefers-reduced-motion: reduce){
17600
17767
  .wfs-anim,.wfs-rise,.wfs-shim{animation:none !important}
@@ -17675,7 +17842,7 @@ function WorkflowStepperRenderer({
17675
17842
  const steps = (_a = data.steps) != null ? _a : [];
17676
17843
  const activeStepId = (_d = (_c = data.active_step) != null ? _c : (_b = steps.find((s) => s.status === "active")) == null ? void 0 : _b.id) != null ? _d : null;
17677
17844
  const interactive = typeof onSelectStep === "function";
17678
- const statusColor3 = (s) => s === "active" ? ACCENT2 : STATUS_COLORS3[s];
17845
+ const statusColor3 = (s) => s === "active" || s === "running" ? ACCENT2 : STATUS_COLORS3[s];
17679
17846
  const doneCount = steps.filter((s) => s.status === "done").length;
17680
17847
  const rootRef = React45__default.default.useRef(null);
17681
17848
  const containerW = useContainerWidth(rootRef);
@@ -17903,6 +18070,7 @@ function WorkflowStepperRenderer({
17903
18070
  var _a2;
17904
18071
  const isSelected = selectedStep === step.id;
17905
18072
  const isActive = step.status === "active";
18073
+ const isRunning = step.status === "running";
17906
18074
  const reached = step.status !== "pending";
17907
18075
  const clickable = interactive && reached;
17908
18076
  const color = statusColor3(step.status);
@@ -17999,36 +18167,41 @@ function WorkflowStepperRenderer({
17999
18167
  }
18000
18168
  }
18001
18169
  ),
18002
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
18003
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
18170
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 4 }, children: [
18171
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, minWidth: 0 }, children: [
18004
18172
  /* @__PURE__ */ jsxRuntime.jsx(IndexDot, { step, index: i, accent: ACCENT2 }),
18005
18173
  /* @__PURE__ */ jsxRuntime.jsx(
18006
18174
  "span",
18007
18175
  {
18008
- className: isActive ? "wfs-anim" : void 0,
18176
+ className: isActive || isRunning ? "wfs-anim" : void 0,
18009
18177
  style: {
18010
18178
  width: 6,
18011
18179
  height: 6,
18012
18180
  borderRadius: "50%",
18013
18181
  background: color,
18014
- animation: isActive ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
18182
+ flexShrink: 0,
18183
+ animation: isActive || isRunning ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
18015
18184
  }
18016
18185
  }
18017
18186
  )
18018
18187
  ] }),
18019
- /* @__PURE__ */ jsxRuntime.jsx(
18020
- "span",
18021
- {
18022
- style: {
18023
- fontSize: 9,
18024
- fontWeight: 600,
18025
- letterSpacing: "0.05em",
18026
- textTransform: "uppercase",
18027
- color
18028
- },
18029
- children: STATUS_LABELS[step.status]
18030
- }
18031
- )
18188
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4, minWidth: 0 }, children: [
18189
+ /* @__PURE__ */ jsxRuntime.jsx(EvalBadge, { step }),
18190
+ /* @__PURE__ */ jsxRuntime.jsx(
18191
+ "span",
18192
+ {
18193
+ style: {
18194
+ fontSize: 9,
18195
+ fontWeight: 600,
18196
+ letterSpacing: "0.05em",
18197
+ textTransform: "uppercase",
18198
+ color,
18199
+ whiteSpace: "nowrap"
18200
+ },
18201
+ children: STATUS_LABELS[step.status]
18202
+ }
18203
+ )
18204
+ ] })
18032
18205
  ] }),
18033
18206
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [
18034
18207
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -18218,12 +18391,14 @@ var BADGE_TITLE = {
18218
18391
  var BADGE_STYLE = {
18219
18392
  SC: { bg: "#dcfce7", fg: "#15803d" },
18220
18393
  CN: { bg: "#eff6ff", fg: "#0364ff" },
18394
+ // theme-ok (SECONDARY)
18221
18395
  AB: { bg: "#fff7ed", fg: "#92400e" },
18222
18396
  SW: { bg: "#fef2f2", fg: "#dc2626" }
18223
18397
  };
18224
18398
  var STATE_DOT = {
18225
18399
  ok: "#15803d",
18226
18400
  corrected: "#0364ff",
18401
+ // theme-ok (SECONDARY)
18227
18402
  missing: "#dc2626",
18228
18403
  warn: "#f59e0b"
18229
18404
  };
@@ -18586,6 +18761,7 @@ var BADGE_DOT = {
18586
18761
  missing: "#dc2626",
18587
18762
  red: "#dc2626",
18588
18763
  corrected: "#0364ff"
18764
+ // theme-ok (SECONDARY)
18589
18765
  };
18590
18766
  function FieldDetails({
18591
18767
  summary,
@@ -19766,8 +19942,15 @@ function useContainerWidth2(ref) {
19766
19942
  var KEYFRAMES2 = `
19767
19943
  @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
19768
19944
  .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
19945
+ .dc-range{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:9999px;outline:none;cursor:pointer;background:transparent}
19946
+ .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}
19947
+ .dc-range::-webkit-slider-thumb:hover{transform:scale(1.12)}
19948
+ .dc-range:active::-webkit-slider-thumb{cursor:grabbing}
19949
+ .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}
19950
+ .dc-range::-moz-range-track{height:4px;border-radius:9999px;background:transparent}
19769
19951
  @media (prefers-reduced-motion: reduce){
19770
19952
  .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
19953
+ .dc-range::-webkit-slider-thumb{transition:none}
19771
19954
  }`;
19772
19955
  function SparkCheck({ size, color }) {
19773
19956
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -19813,17 +19996,239 @@ function FlagPill({ flag }) {
19813
19996
  }
19814
19997
  );
19815
19998
  }
19999
+ function formatFigure(value, unit) {
20000
+ const body = Number.isInteger(value) ? `${value}` : `${Math.round(value * 100) / 100}`;
20001
+ if (!unit) return body;
20002
+ return unit === "%" ? `${body}%` : `${body} ${unit}`;
20003
+ }
20004
+ function clampToRange(raw, adjust) {
20005
+ var _a;
20006
+ const step = (_a = adjust.step) != null ? _a : Number.isInteger(adjust.min) && Number.isInteger(adjust.max) ? 1 : (adjust.max - adjust.min) / 100;
20007
+ const snapped = Math.round((raw - adjust.min) / step) * step + adjust.min;
20008
+ const fixed = Math.round(snapped * 1e6) / 1e6;
20009
+ return Math.min(adjust.max, Math.max(adjust.min, fixed));
20010
+ }
20011
+ function ValueAdjuster({
20012
+ option,
20013
+ accent,
20014
+ border,
20015
+ muted,
20016
+ onConfirm,
20017
+ onBack
20018
+ }) {
20019
+ var _a, _b;
20020
+ const adjust = option.adjust;
20021
+ const suggested = clampToRange((_a = option.value) != null ? _a : adjust.min, adjust);
20022
+ const [value, setValue] = React45__default.default.useState(suggested);
20023
+ const [text, setText] = React45__default.default.useState(String(suggested));
20024
+ const step = (_b = adjust.step) != null ? _b : Number.isInteger(adjust.min) && Number.isInteger(adjust.max) ? 1 : (adjust.max - adjust.min) / 100;
20025
+ const pct = adjust.max > adjust.min ? (value - adjust.min) / (adjust.max - adjust.min) * 100 : 0;
20026
+ const suggestedPct = adjust.max > adjust.min ? (suggested - adjust.min) / (adjust.max - adjust.min) * 100 : 0;
20027
+ const moved = value !== suggested;
20028
+ const commit = (raw) => {
20029
+ const v = clampToRange(raw, adjust);
20030
+ setValue(v);
20031
+ setText(String(v));
20032
+ };
20033
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20034
+ "div",
20035
+ {
20036
+ className: "dc-rise",
20037
+ "data-testid": "decision-card-adjuster",
20038
+ style: {
20039
+ display: "flex",
20040
+ flexDirection: "column",
20041
+ gap: 12,
20042
+ border: `1px solid ${border}`,
20043
+ borderRadius: 10,
20044
+ padding: "12px 14px",
20045
+ background: "#fafafa"
20046
+ },
20047
+ children: [
20048
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 8 }, children: [
20049
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.06em", color: muted }, children: [
20050
+ "Adjust \xB7 ",
20051
+ option.label
20052
+ ] }),
20053
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1 } }),
20054
+ /* @__PURE__ */ jsxRuntime.jsx(
20055
+ "button",
20056
+ {
20057
+ type: "button",
20058
+ onClick: onBack,
20059
+ "data-testid": "decision-card-adjust-back",
20060
+ style: { border: "none", background: "none", padding: 0, cursor: "pointer", fontSize: 12, fontWeight: 600, color: muted },
20061
+ children: "Back"
20062
+ }
20063
+ )
20064
+ ] }),
20065
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 6 }, children: [
20066
+ /* @__PURE__ */ jsxRuntime.jsx(
20067
+ "input",
20068
+ {
20069
+ value: text,
20070
+ onChange: (e) => {
20071
+ setText(e.target.value);
20072
+ const n = Number(e.target.value);
20073
+ if (Number.isFinite(n)) setValue(clampToRange(n, adjust));
20074
+ },
20075
+ onBlur: () => commit(Number(text) || suggested),
20076
+ onKeyDown: (e) => {
20077
+ if (e.key === "Enter") {
20078
+ const v = clampToRange(Number(text) || suggested, adjust);
20079
+ commit(v);
20080
+ onConfirm(v);
20081
+ } else if (e.key === "ArrowUp") {
20082
+ e.preventDefault();
20083
+ commit(value + step);
20084
+ } else if (e.key === "ArrowDown") {
20085
+ e.preventDefault();
20086
+ commit(value - step);
20087
+ }
20088
+ },
20089
+ inputMode: "decimal",
20090
+ "aria-label": `${option.label} value`,
20091
+ "data-testid": "decision-card-adjust-input",
20092
+ style: {
20093
+ width: `${Math.max(3, String(text).length + 1)}ch`,
20094
+ fontSize: 26,
20095
+ fontWeight: 700,
20096
+ fontVariantNumeric: "tabular-nums",
20097
+ letterSpacing: "-0.02em",
20098
+ color: "var(--foreground)",
20099
+ border: "none",
20100
+ borderBottom: `2px solid ${accent}`,
20101
+ background: "transparent",
20102
+ outline: "none",
20103
+ padding: 0
20104
+ }
20105
+ }
20106
+ ),
20107
+ adjust.unit && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13, fontWeight: 600, color: muted }, children: adjust.unit }),
20108
+ moved && /* @__PURE__ */ jsxRuntime.jsxs(
20109
+ "button",
20110
+ {
20111
+ type: "button",
20112
+ onClick: () => commit(suggested),
20113
+ "data-testid": "decision-card-adjust-reset",
20114
+ style: {
20115
+ marginLeft: 8,
20116
+ border: "none",
20117
+ background: "none",
20118
+ padding: 0,
20119
+ cursor: "pointer",
20120
+ fontSize: 11.5,
20121
+ fontWeight: 600,
20122
+ color: muted,
20123
+ textDecoration: "underline",
20124
+ textUnderlineOffset: 2
20125
+ },
20126
+ children: [
20127
+ "Reset to suggested (",
20128
+ formatFigure(suggested, adjust.unit),
20129
+ ")"
20130
+ ]
20131
+ }
20132
+ )
20133
+ ] }),
20134
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
20135
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", height: 16, display: "flex", alignItems: "center" }, children: [
20136
+ /* @__PURE__ */ jsxRuntime.jsx(
20137
+ "div",
20138
+ {
20139
+ "aria-hidden": "true",
20140
+ style: {
20141
+ position: "absolute",
20142
+ left: 0,
20143
+ right: 0,
20144
+ height: 4,
20145
+ borderRadius: 9999,
20146
+ background: `linear-gradient(to right, ${accent} ${pct}%, #e8e8e8 ${pct}%)`
20147
+ }
20148
+ }
20149
+ ),
20150
+ moved && /* @__PURE__ */ jsxRuntime.jsx(
20151
+ "div",
20152
+ {
20153
+ "aria-hidden": "true",
20154
+ title: `Suggested: ${formatFigure(suggested, adjust.unit)}`,
20155
+ style: {
20156
+ position: "absolute",
20157
+ left: `${suggestedPct}%`,
20158
+ transform: "translateX(-50%)",
20159
+ width: 2,
20160
+ height: 10,
20161
+ borderRadius: 1,
20162
+ background: muted,
20163
+ opacity: 0.55
20164
+ }
20165
+ }
20166
+ ),
20167
+ /* @__PURE__ */ jsxRuntime.jsx(
20168
+ "input",
20169
+ {
20170
+ type: "range",
20171
+ className: "dc-range",
20172
+ min: adjust.min,
20173
+ max: adjust.max,
20174
+ step,
20175
+ value,
20176
+ onChange: (e) => commit(Number(e.target.value)),
20177
+ "aria-label": `${option.label} slider`,
20178
+ "data-testid": "decision-card-adjust-slider",
20179
+ style: { position: "relative", ["--dc-thumb"]: accent }
20180
+ }
20181
+ )
20182
+ ] }),
20183
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 10.5, fontWeight: 600, color: muted, fontVariantNumeric: "tabular-nums" }, children: [
20184
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatFigure(adjust.min, adjust.unit) }),
20185
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatFigure(adjust.max, adjust.unit) })
20186
+ ] })
20187
+ ] }),
20188
+ /* @__PURE__ */ jsxRuntime.jsxs(
20189
+ "button",
20190
+ {
20191
+ type: "button",
20192
+ onClick: () => onConfirm(value),
20193
+ "data-testid": "decision-card-adjust-confirm",
20194
+ style: {
20195
+ alignSelf: "flex-start",
20196
+ border: `1px solid ${accent}`,
20197
+ background: accent,
20198
+ color: "white",
20199
+ borderRadius: 8,
20200
+ fontSize: 13,
20201
+ fontWeight: 600,
20202
+ padding: "9px 16px",
20203
+ cursor: "pointer",
20204
+ fontVariantNumeric: "tabular-nums",
20205
+ transition: "opacity 0.15s"
20206
+ },
20207
+ onMouseEnter: (e) => e.currentTarget.style.opacity = "0.88",
20208
+ onMouseLeave: (e) => e.currentTarget.style.opacity = "1",
20209
+ children: [
20210
+ option.label,
20211
+ " \xB7 ",
20212
+ formatFigure(value, adjust.unit)
20213
+ ]
20214
+ }
20215
+ )
20216
+ ]
20217
+ }
20218
+ );
20219
+ }
19816
20220
  function DecisionCardRenderer({
19817
20221
  data,
19818
20222
  resolved = null,
19819
20223
  onResolve,
19820
20224
  onOpenSource
19821
20225
  }) {
19822
- var _a, _b;
20226
+ var _a, _b, _c;
19823
20227
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
19824
20228
  const rootRef = React45__default.default.useRef(null);
19825
20229
  const width = useContainerWidth2(rootRef);
19826
20230
  const stacked = width > 0 && width < STACK_BELOW;
20231
+ const [adjustingIdx, setAdjustingIdx] = React45__default.default.useState(null);
19827
20232
  const options = (_a = data.options) != null ? _a : [];
19828
20233
  const recommendedIdx = Math.max(
19829
20234
  0,
@@ -19978,7 +20383,20 @@ function DecisionCardRenderer({
19978
20383
  ]
19979
20384
  }
19980
20385
  ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19981
- /* @__PURE__ */ jsxRuntime.jsx(
20386
+ adjustingIdx != null && ((_b = options[adjustingIdx]) == null ? void 0 : _b.adjust) ? /* @__PURE__ */ jsxRuntime.jsx(
20387
+ ValueAdjuster,
20388
+ {
20389
+ option: options[adjustingIdx],
20390
+ accent: ACCENT2,
20391
+ border: BORDER4,
20392
+ muted: MUTED2,
20393
+ onBack: () => setAdjustingIdx(null),
20394
+ onConfirm: (value) => {
20395
+ setAdjustingIdx(null);
20396
+ onResolve == null ? void 0 : onResolve(options[adjustingIdx].label, value);
20397
+ }
20398
+ }
20399
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
19982
20400
  "div",
19983
20401
  {
19984
20402
  style: {
@@ -19988,15 +20406,21 @@ function DecisionCardRenderer({
19988
20406
  gap: 8
19989
20407
  },
19990
20408
  children: options.map((opt, idx) => {
19991
- var _a2;
20409
+ var _a2, _b2;
19992
20410
  const primary = idx === recommendedIdx;
19993
- return /* @__PURE__ */ jsxRuntime.jsx(
20411
+ const adjustable = Boolean(opt.adjust);
20412
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19994
20413
  "button",
19995
20414
  {
19996
20415
  type: "button",
19997
- onClick: () => onResolve == null ? void 0 : onResolve(opt.label),
20416
+ onClick: () => adjustable ? setAdjustingIdx(idx) : onResolve == null ? void 0 : onResolve(opt.label),
20417
+ "data-adjustable": adjustable || void 0,
19998
20418
  style: {
19999
20419
  width: stacked ? "100%" : "auto",
20420
+ display: "inline-flex",
20421
+ alignItems: "center",
20422
+ justifyContent: stacked ? "flex-start" : "center",
20423
+ gap: 7,
20000
20424
  textAlign: stacked ? "left" : "center",
20001
20425
  border: `1px solid ${primary ? ACCENT2 : BORDER4}`,
20002
20426
  background: primary ? ACCENT2 : "white",
@@ -20024,7 +20448,28 @@ function DecisionCardRenderer({
20024
20448
  e.currentTarget.style.background = "white";
20025
20449
  }
20026
20450
  },
20027
- children: opt.label
20451
+ children: [
20452
+ opt.label,
20453
+ adjustable && typeof opt.value === "number" && /* @__PURE__ */ jsxRuntime.jsxs(
20454
+ "span",
20455
+ {
20456
+ style: {
20457
+ fontSize: 11.5,
20458
+ fontWeight: 700,
20459
+ fontVariantNumeric: "tabular-nums",
20460
+ padding: "1px 7px",
20461
+ borderRadius: 9999,
20462
+ background: primary ? "rgba(255,255,255,0.22)" : "#f2f2f2",
20463
+ color: primary ? "white" : MUTED2,
20464
+ lineHeight: 1.5
20465
+ },
20466
+ children: [
20467
+ formatFigure(opt.value, (_b2 = opt.adjust) == null ? void 0 : _b2.unit),
20468
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: { marginLeft: 4, opacity: 0.8 }, children: "\u270E" })
20469
+ ]
20470
+ }
20471
+ )
20472
+ ]
20028
20473
  },
20029
20474
  (_a2 = opt.id) != null ? _a2 : opt.label
20030
20475
  );
@@ -20063,7 +20508,7 @@ function DecisionCardRenderer({
20063
20508
  strokeLinejoin: "round"
20064
20509
  }
20065
20510
  ) }),
20066
- (_b = data.source.label) != null ? _b : "View source for this figure"
20511
+ (_c = data.source.label) != null ? _c : "View source for this figure"
20067
20512
  ]
20068
20513
  }
20069
20514
  )
@@ -20072,20 +20517,27 @@ function DecisionCardRenderer({
20072
20517
  }
20073
20518
  );
20074
20519
  }
20520
+ function composeResolution(p, option, value) {
20521
+ var _a, _b, _c;
20522
+ if (value == null) return option;
20523
+ const unit = (_c = (_b = ((_a = p.options) != null ? _a : []).find((o) => o.label === option)) == null ? void 0 : _b.adjust) == null ? void 0 : _c.unit;
20524
+ return `${option} \xB7 ${formatFigure(value, unit)}`;
20525
+ }
20075
20526
  function DecisionCardResolver(p) {
20076
- var _a, _b, _c, _d;
20527
+ var _a, _b;
20077
20528
  const { resolvedDecisions, onDecisionResolve, onDecisionSource } = useGenUIInteraction();
20078
20529
  const decisionId = (_a = p.id) != null ? _a : p.title;
20079
20530
  const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
20080
- const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
20531
+ const initial = hostResolved != null ? hostResolved : p.resolved ? composeResolution(p, p.resolved.option, p.resolved.value) : null;
20081
20532
  const [localResolved, setLocalResolved] = React45__default.default.useState(initial);
20082
20533
  React45__default.default.useEffect(() => {
20083
20534
  if (hostResolved !== void 0) setLocalResolved(hostResolved);
20084
20535
  }, [hostResolved]);
20085
20536
  const resolved = hostResolved != null ? hostResolved : localResolved;
20086
- const handleResolve = (option) => {
20087
- setLocalResolved(option);
20088
- onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, option);
20537
+ const handleResolve = (option, value) => {
20538
+ const resolution = composeResolution(p, option, value);
20539
+ setLocalResolved(resolution);
20540
+ onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, resolution);
20089
20541
  };
20090
20542
  const handleSource = () => {
20091
20543
  var _a2;
@@ -20094,7 +20546,7 @@ function DecisionCardResolver(p) {
20094
20546
  window.open(p.source.url, "_blank", "noopener,noreferrer");
20095
20547
  }
20096
20548
  };
20097
- return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_d = p.title) != null ? _d : "decision-card", children: /* @__PURE__ */ jsxRuntime.jsx(
20549
+ return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_b = p.title) != null ? _b : "decision-card", children: /* @__PURE__ */ jsxRuntime.jsx(
20098
20550
  DecisionCardRenderer,
20099
20551
  {
20100
20552
  data: p,
@@ -20104,6 +20556,317 @@ function DecisionCardResolver(p) {
20104
20556
  }
20105
20557
  ) });
20106
20558
  }
20559
+ init_ThemeContext();
20560
+ var CONNECTED_GREEN3 = "#15803d";
20561
+ var CONNECTED_GREEN_BG = "#dcfce7";
20562
+ var PENDING_AMBER = "#92400e";
20563
+ var PENDING_AMBER_BG = "#fff7ed";
20564
+ var CARD_TITLE = "Authentication required";
20565
+ var TRUST_FOOTER = "Credentials not stored by Adopt";
20566
+ var DEFAULT_STEPS = (app, ctaLabel, connected) => connected ? [
20567
+ `Click ${ctaLabel} below to open ${app} in a new tab.`,
20568
+ "Confirm you are signed in \u2014 re-authenticate if prompted.",
20569
+ "Return here \u2014 the request continues automatically."
20570
+ ] : [
20571
+ `Click ${ctaLabel} below to open the sign-in page.`,
20572
+ `Sign in with your ${app} credentials \u2014 SSO is supported.`,
20573
+ "Return here \u2014 the request resumes automatically."
20574
+ ];
20575
+ function humanizeApp(raw) {
20576
+ const v = raw.trim();
20577
+ if (!v) return v;
20578
+ const looksLikeSlug = /^[a-z0-9]+([_-][a-z0-9]+)*$/.test(v);
20579
+ if (!looksLikeSlug) return v;
20580
+ return v.split(/[_-]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
20581
+ }
20582
+ function ShieldIcon({ color }) {
20583
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20584
+ "svg",
20585
+ {
20586
+ width: "13",
20587
+ height: "13",
20588
+ viewBox: "0 0 24 24",
20589
+ fill: "none",
20590
+ stroke: color,
20591
+ strokeWidth: "2",
20592
+ strokeLinecap: "round",
20593
+ strokeLinejoin: "round",
20594
+ "aria-hidden": "true",
20595
+ style: { flexShrink: 0 },
20596
+ children: [
20597
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
20598
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 12 2 2 4-4" })
20599
+ ]
20600
+ }
20601
+ );
20602
+ }
20603
+ function ExternalIcon() {
20604
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20605
+ "svg",
20606
+ {
20607
+ width: "13",
20608
+ height: "13",
20609
+ viewBox: "0 0 24 24",
20610
+ fill: "none",
20611
+ stroke: "currentColor",
20612
+ strokeWidth: "2",
20613
+ strokeLinecap: "round",
20614
+ strokeLinejoin: "round",
20615
+ "aria-hidden": "true",
20616
+ style: { flexShrink: 0 },
20617
+ children: [
20618
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 3h6v6" }),
20619
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 14 21 3" }),
20620
+ /* @__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" })
20621
+ ]
20622
+ }
20623
+ );
20624
+ }
20625
+ function TabbyAuthResolver(p) {
20626
+ var _a, _b, _c;
20627
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
20628
+ const [cardHovered, setCardHovered] = React45.useState(false);
20629
+ const [btnHovered, setBtnHovered] = React45.useState(false);
20630
+ const [imgFailed, setImgFailed] = React45.useState(false);
20631
+ const app = humanizeApp(p.app || "the app");
20632
+ const connected = p.state === "connected";
20633
+ const accent = connected ? CONNECTED_GREEN3 : ACCENT2;
20634
+ const ctaLabel = (_a = p.ctaLabel) != null ? _a : connected ? `Open ${app}` : `Connect ${app}`;
20635
+ const subtitle = p.workspace ? `${app} \xB7 ${p.workspace} workspace` : app;
20636
+ const steps = ((_b = p.steps) == null ? void 0 : _b.length) ? p.steps : DEFAULT_STEPS(app, ctaLabel, connected);
20637
+ 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.`;
20638
+ const iconSrc = p.iconUrl || brandIconUrl(app);
20639
+ const showImg = Boolean(iconSrc) && !imgFailed;
20640
+ const initial = app.charAt(0).toUpperCase();
20641
+ const badge = connected ? { label: "Connected", bg: CONNECTED_GREEN_BG, color: CONNECTED_GREEN3 } : { label: "Pending sign-in", bg: PENDING_AMBER_BG, color: PENDING_AMBER };
20642
+ const sectionPad = "13px 16px";
20643
+ 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(
20644
+ "div",
20645
+ {
20646
+ onMouseEnter: () => setCardHovered(true),
20647
+ onMouseLeave: () => setCardHovered(false),
20648
+ style: {
20649
+ display: "flex",
20650
+ flexDirection: "row",
20651
+ alignItems: "stretch",
20652
+ borderRadius: "0.75rem",
20653
+ border: `1px solid ${cardHovered ? "#d2d2d2" : BORDER4}`,
20654
+ background: "white",
20655
+ overflow: "hidden",
20656
+ 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)",
20657
+ transition: "box-shadow 0.18s ease, border-color 0.18s ease"
20658
+ },
20659
+ children: [
20660
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "3px", flexShrink: 0, background: accent } }),
20661
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }, children: [
20662
+ /* @__PURE__ */ jsxRuntime.jsxs(
20663
+ "div",
20664
+ {
20665
+ style: {
20666
+ display: "flex",
20667
+ alignItems: "flex-start",
20668
+ gap: "12px",
20669
+ padding: sectionPad
20670
+ },
20671
+ children: [
20672
+ /* @__PURE__ */ jsxRuntime.jsx(
20673
+ "div",
20674
+ {
20675
+ style: {
20676
+ position: "relative",
20677
+ width: "34px",
20678
+ height: "34px",
20679
+ borderRadius: "9px",
20680
+ flexShrink: 0,
20681
+ display: "flex",
20682
+ alignItems: "center",
20683
+ justifyContent: "center",
20684
+ background: showImg ? "white" : "#fff3ee",
20685
+ boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.06)",
20686
+ overflow: "hidden"
20687
+ },
20688
+ children: showImg ? /* @__PURE__ */ jsxRuntime.jsx(
20689
+ "img",
20690
+ {
20691
+ src: iconSrc,
20692
+ alt: app,
20693
+ onError: () => setImgFailed(true),
20694
+ style: { width: "22px", height: "22px", objectFit: "contain" }
20695
+ }
20696
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
20697
+ "span",
20698
+ {
20699
+ style: {
20700
+ fontFamily: "var(--font-serif)",
20701
+ fontSize: "17px",
20702
+ fontWeight: 400,
20703
+ color: ACCENT2,
20704
+ lineHeight: 1
20705
+ },
20706
+ children: initial
20707
+ }
20708
+ )
20709
+ }
20710
+ ),
20711
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "2px" }, children: [
20712
+ /* @__PURE__ */ jsxRuntime.jsx(
20713
+ "span",
20714
+ {
20715
+ style: {
20716
+ fontFamily: "var(--font-serif)",
20717
+ fontSize: "15px",
20718
+ fontWeight: 400,
20719
+ color: "var(--foreground)",
20720
+ letterSpacing: "-0.01em",
20721
+ lineHeight: 1.2
20722
+ },
20723
+ children: CARD_TITLE
20724
+ }
20725
+ ),
20726
+ /* @__PURE__ */ jsxRuntime.jsx(
20727
+ "span",
20728
+ {
20729
+ style: {
20730
+ fontSize: "12px",
20731
+ color: MUTED2,
20732
+ whiteSpace: "nowrap",
20733
+ overflow: "hidden",
20734
+ textOverflow: "ellipsis"
20735
+ },
20736
+ children: subtitle
20737
+ }
20738
+ )
20739
+ ] }),
20740
+ /* @__PURE__ */ jsxRuntime.jsxs(
20741
+ "span",
20742
+ {
20743
+ style: {
20744
+ display: "inline-flex",
20745
+ alignItems: "center",
20746
+ gap: "5px",
20747
+ flexShrink: 0,
20748
+ fontSize: "10.5px",
20749
+ fontWeight: 600,
20750
+ padding: "3px 9px",
20751
+ borderRadius: "9999px",
20752
+ background: badge.bg,
20753
+ color: badge.color,
20754
+ whiteSpace: "nowrap"
20755
+ },
20756
+ children: [
20757
+ /* @__PURE__ */ jsxRuntime.jsx(
20758
+ "span",
20759
+ {
20760
+ style: {
20761
+ width: "6px",
20762
+ height: "6px",
20763
+ borderRadius: "9999px",
20764
+ background: badge.color
20765
+ }
20766
+ }
20767
+ ),
20768
+ badge.label
20769
+ ]
20770
+ }
20771
+ )
20772
+ ]
20773
+ }
20774
+ ),
20775
+ /* @__PURE__ */ jsxRuntime.jsxs(
20776
+ "div",
20777
+ {
20778
+ style: {
20779
+ borderTop: `1px solid ${BORDER4}`,
20780
+ padding: sectionPad,
20781
+ display: "flex",
20782
+ flexDirection: "column",
20783
+ gap: "12px"
20784
+ },
20785
+ children: [
20786
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12.5px", lineHeight: 1.5, color: "var(--foreground)" }, children: description }),
20787
+ /* @__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: [
20788
+ /* @__PURE__ */ jsxRuntime.jsx(
20789
+ "span",
20790
+ {
20791
+ style: {
20792
+ flexShrink: 0,
20793
+ width: "18px",
20794
+ height: "18px",
20795
+ borderRadius: "9999px",
20796
+ background: accent,
20797
+ color: "white",
20798
+ fontSize: "10.5px",
20799
+ fontWeight: 600,
20800
+ display: "flex",
20801
+ alignItems: "center",
20802
+ justifyContent: "center",
20803
+ marginTop: "1px"
20804
+ },
20805
+ children: i + 1
20806
+ }
20807
+ ),
20808
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12.5px", lineHeight: 1.45, color: "var(--foreground)" }, children: step })
20809
+ ] }, i)) })
20810
+ ]
20811
+ }
20812
+ ),
20813
+ /* @__PURE__ */ jsxRuntime.jsxs(
20814
+ "div",
20815
+ {
20816
+ style: {
20817
+ borderTop: `1px solid ${BORDER4}`,
20818
+ padding: sectionPad,
20819
+ background: "#fbfbfb",
20820
+ display: "flex",
20821
+ alignItems: "center",
20822
+ justifyContent: "space-between",
20823
+ gap: "12px",
20824
+ flexWrap: "wrap"
20825
+ },
20826
+ children: [
20827
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px", color: MUTED2, fontSize: "11.5px" }, children: [
20828
+ /* @__PURE__ */ jsxRuntime.jsx(ShieldIcon, { color: CONNECTED_GREEN3 }),
20829
+ TRUST_FOOTER
20830
+ ] }),
20831
+ /* @__PURE__ */ jsxRuntime.jsxs(
20832
+ "a",
20833
+ {
20834
+ href: p.url,
20835
+ target: "_blank",
20836
+ rel: "noopener noreferrer",
20837
+ onMouseEnter: () => setBtnHovered(true),
20838
+ onMouseLeave: () => setBtnHovered(false),
20839
+ style: {
20840
+ display: "inline-flex",
20841
+ alignItems: "center",
20842
+ gap: "7px",
20843
+ flexShrink: 0,
20844
+ borderRadius: "8px",
20845
+ padding: "8px 15px",
20846
+ fontSize: "12.5px",
20847
+ fontWeight: 600,
20848
+ textDecoration: "none",
20849
+ whiteSpace: "nowrap",
20850
+ cursor: "pointer",
20851
+ color: "white",
20852
+ border: "1px solid transparent",
20853
+ background: btnHovered ? connected ? "#126a33" : ACCENT_SOFT2 : accent,
20854
+ transition: "background 0.15s ease"
20855
+ },
20856
+ children: [
20857
+ /* @__PURE__ */ jsxRuntime.jsx(ExternalIcon, {}),
20858
+ ctaLabel
20859
+ ]
20860
+ }
20861
+ )
20862
+ ]
20863
+ }
20864
+ )
20865
+ ] })
20866
+ ]
20867
+ }
20868
+ ) }) });
20869
+ }
20107
20870
  function resolveUI(rawPayload) {
20108
20871
  const payload = coercePayload(rawPayload);
20109
20872
  switch (payload.type) {
@@ -20225,6 +20988,8 @@ function resolveUI(rawPayload) {
20225
20988
  return /* @__PURE__ */ jsxRuntime.jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
20226
20989
  case "decision-card":
20227
20990
  return /* @__PURE__ */ jsxRuntime.jsx(DecisionCardResolver, __spreadValues({}, payload));
20991
+ case "tabby-auth":
20992
+ return /* @__PURE__ */ jsxRuntime.jsx(TabbyAuthResolver, __spreadValues({}, payload));
20228
20993
  default: {
20229
20994
  return /* @__PURE__ */ jsxRuntime.jsx(
20230
20995
  "div",