@adoptai/genui-components 0.1.58 → 0.1.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/composites/document-field-extraction/resolver.cjs +1920 -0
  2. package/dist/composites/document-field-extraction/resolver.cjs.map +1 -0
  3. package/dist/composites/document-field-extraction/resolver.js +1913 -0
  4. package/dist/composites/document-field-extraction/resolver.js.map +1 -0
  5. package/dist/composites/tabby-auth/resolver.cjs +597 -0
  6. package/dist/composites/tabby-auth/resolver.cjs.map +1 -0
  7. package/dist/composites/tabby-auth/resolver.d.ts +3 -0
  8. package/dist/composites/tabby-auth/resolver.d.ts.map +1 -0
  9. package/dist/composites/tabby-auth/resolver.js +595 -0
  10. package/dist/composites/tabby-auth/resolver.js.map +1 -0
  11. package/dist/composites/workflow-stepper/resolver.cjs +86 -18
  12. package/dist/composites/workflow-stepper/resolver.cjs.map +1 -1
  13. package/dist/composites/workflow-stepper/resolver.d.ts.map +1 -1
  14. package/dist/composites/workflow-stepper/resolver.js +86 -18
  15. package/dist/composites/workflow-stepper/resolver.js.map +1 -1
  16. package/dist/index.cjs +492 -27
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.js +492 -27
  19. package/dist/index.js.map +1 -1
  20. package/dist/renderer.cjs +492 -27
  21. package/dist/renderer.cjs.map +1 -1
  22. package/dist/renderer.js +492 -27
  23. package/dist/renderer.js.map +1 -1
  24. package/dist/resolver.cjs +492 -27
  25. package/dist/resolver.cjs.map +1 -1
  26. package/dist/resolver.d.ts.map +1 -1
  27. package/dist/resolver.js +492 -27
  28. package/dist/resolver.js.map +1 -1
  29. package/dist/schemas/index.cjs +84 -3
  30. package/dist/schemas/index.cjs.map +1 -1
  31. package/dist/schemas/index.d.ts +118 -0
  32. package/dist/schemas/index.d.ts.map +1 -1
  33. package/dist/schemas/index.js +84 -3
  34. package/dist/schemas/index.js.map +1 -1
  35. package/dist/schemas/tabby-auth.d.ts +58 -0
  36. package/dist/schemas/tabby-auth.d.ts.map +1 -0
  37. package/dist/schemas/workflow-stepper.d.ts +60 -0
  38. package/dist/schemas/workflow-stepper.d.ts.map +1 -1
  39. package/dist/tool-definitions.json +102 -3
  40. 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,
@@ -5585,6 +5635,36 @@ var decisionCardTool = {
5585
5635
  required: ["type", "title", "question", "options"]
5586
5636
  }
5587
5637
  };
5638
+ var tabbyAuthSchema = zod.z.object({
5639
+ type: zod.z.literal("tabby-auth"),
5640
+ app: zod.z.string(),
5641
+ url: zod.z.string(),
5642
+ workspace: zod.z.string().optional(),
5643
+ state: zod.z.enum(["pending", "connected"]).optional(),
5644
+ ctaLabel: zod.z.string().optional(),
5645
+ steps: zod.z.array(zod.z.string()).optional(),
5646
+ description: zod.z.string().optional(),
5647
+ iconUrl: zod.z.string().optional()
5648
+ });
5649
+ var tabbyAuthTool = {
5650
+ name: "render_tabby_auth",
5651
+ 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.",
5652
+ input_schema: {
5653
+ type: "object",
5654
+ properties: {
5655
+ type: { type: "string", enum: ["tabby-auth"] },
5656
+ app: { type: "string" },
5657
+ url: { type: "string" },
5658
+ workspace: { type: "string" },
5659
+ state: { type: "string", enum: ["pending", "connected"] },
5660
+ ctaLabel: { type: "string" },
5661
+ steps: { type: "array", items: { type: "string" } },
5662
+ description: { type: "string" },
5663
+ iconUrl: { type: "string" }
5664
+ },
5665
+ required: ["type", "app", "url"]
5666
+ }
5667
+ };
5588
5668
 
5589
5669
  // src/schemas/index.ts
5590
5670
  var schemaRegistry = {
@@ -5646,7 +5726,8 @@ var schemaRegistry = {
5646
5726
  "pipeline-preview": { schema: pipelinePreviewSchema, tool: pipelinePreviewTool },
5647
5727
  "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5648
5728
  "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5649
- "decision-card": { schema: decisionCardSchema, tool: decisionCardTool }
5729
+ "decision-card": { schema: decisionCardSchema, tool: decisionCardTool },
5730
+ "tabby-auth": { schema: tabbyAuthSchema, tool: tabbyAuthTool }
5650
5731
  };
5651
5732
 
5652
5733
  // src/schemas/coercePayload.ts
@@ -6384,17 +6465,17 @@ function SparklineTableResolver(p) {
6384
6465
  // src/composites/heatmap-table/resolver.tsx
6385
6466
  init_theme();
6386
6467
  init_ThemeContext();
6387
- function heatColor(z60) {
6388
- const clamped = Math.max(-3, Math.min(3, z60));
6468
+ function heatColor(z61) {
6469
+ const clamped = Math.max(-3, Math.min(3, z61));
6389
6470
  const abs = Math.abs(clamped);
6390
6471
  const lightness = 95 - abs * 8;
6391
6472
  const hue = clamped >= 0 ? 142 : 0;
6392
6473
  return `hsl(${hue} 60% ${lightness}%)`;
6393
6474
  }
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";
6475
+ function heatTextColor(z61) {
6476
+ const abs = Math.abs(z61);
6477
+ if (abs > 2) return z61 >= 0 ? "#14532d" : "#7f1d1d";
6478
+ if (abs > 1) return z61 >= 0 ? "#166534" : "#991b1b";
6398
6479
  return "var(--foreground)";
6399
6480
  }
6400
6481
  var th2 = {
@@ -17452,6 +17533,8 @@ var STATUS_COLORS3 = {
17452
17533
  done: "#15803d",
17453
17534
  active: "",
17454
17535
  // filled from theme ACCENT at render time
17536
+ running: "",
17537
+ // filled from theme ACCENT at render time (executor in flight)
17455
17538
  review: "#f59e0b",
17456
17539
  pending: "#9ca3af",
17457
17540
  blocked: "#b45309",
@@ -17460,6 +17543,7 @@ var STATUS_COLORS3 = {
17460
17543
  var STATUS_LABELS = {
17461
17544
  done: "Complete",
17462
17545
  active: "In progress",
17546
+ running: "Running",
17463
17547
  review: "In review",
17464
17548
  pending: "Pending",
17465
17549
  blocked: "Blocked",
@@ -17563,6 +17647,26 @@ function IndexDot({ step, index, accent }) {
17563
17647
  if (step.status === "failed") {
17564
17648
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#dc2626", color: "white" }), children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 10 }, children: "!" }) });
17565
17649
  }
17650
+ if (step.status === "running") {
17651
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: __spreadProps(__spreadValues({}, base), { position: "relative", background: `${accent}1f`, color: accent }), children: [
17652
+ /* @__PURE__ */ jsxRuntime.jsx(
17653
+ "span",
17654
+ {
17655
+ className: "wfs-anim",
17656
+ "aria-hidden": "true",
17657
+ style: {
17658
+ position: "absolute",
17659
+ inset: 0,
17660
+ borderRadius: "50%",
17661
+ border: `1.5px solid ${accent}33`,
17662
+ borderTopColor: accent,
17663
+ animation: "wfsSpin 0.8s linear infinite"
17664
+ }
17665
+ }
17666
+ ),
17667
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 9 }, children: n })
17668
+ ] });
17669
+ }
17566
17670
  if (step.status === "active") {
17567
17671
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: accent, color: "white" }), children: n });
17568
17672
  }
@@ -17571,6 +17675,44 @@ function IndexDot({ step, index, accent }) {
17571
17675
  }
17572
17676
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: __spreadProps(__spreadValues({}, base), { background: "#f2f2f2", color: "#9ca3af" }), children: n });
17573
17677
  }
17678
+ function EvalBadge({ step }) {
17679
+ var _a;
17680
+ const ev = step.eval;
17681
+ if (!ev || ev.judge_ok === false) return null;
17682
+ const score = typeof ev.score === "number" ? ev.score : null;
17683
+ const flags = (_a = ev.data_quality_flags) != null ? _a : [];
17684
+ const bad = ev.verdict === "bad" || score !== null && score < 0.8;
17685
+ const tip = flags.length > 0 ? flags.map((f) => {
17686
+ var _a2;
17687
+ return `${(_a2 = f.severity) != null ? _a2 : "?"}: ${f.details || f.issue || f.field || "issue"}`;
17688
+ }).join("\n") : ev.reasoning || void 0;
17689
+ const label = score !== null ? score.toFixed(2) : bad ? "flagged" : "ok";
17690
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17691
+ "span",
17692
+ {
17693
+ title: tip,
17694
+ "data-testid": `workflow-stepper-eval-${step.id}`,
17695
+ style: {
17696
+ display: "inline-flex",
17697
+ alignItems: "center",
17698
+ gap: 3,
17699
+ fontSize: 9,
17700
+ fontWeight: 700,
17701
+ padding: "1px 6px",
17702
+ borderRadius: 9999,
17703
+ background: bad ? "#fff7ed" : "#dcfce7",
17704
+ color: bad ? "#b45309" : "#15803d",
17705
+ whiteSpace: "nowrap",
17706
+ flexShrink: 0
17707
+ },
17708
+ children: [
17709
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: bad ? "\u26A0" : "\u2713" }),
17710
+ label,
17711
+ flags.length > 0 ? ` \xB7 ${flags.length}` : ""
17712
+ ]
17713
+ }
17714
+ );
17715
+ }
17574
17716
  var CARD_MIN = 132;
17575
17717
  var CARD_GAP = 16;
17576
17718
  var AUTO_COMPACT_BELOW = 360;
@@ -17595,6 +17737,7 @@ var KEYFRAMES = `
17595
17737
  @keyframes wfsLampPulse{0%,100%{box-shadow:0 0 0 0 var(--wfs-accent,#6366f1)73}50%{box-shadow:0 0 0 4px transparent}}
17596
17738
  @keyframes wfsRise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
17597
17739
  @keyframes wfsShimmer{0%{background-position:-200px 0}100%{background-position:calc(200px + 100%) 0}}
17740
+ @keyframes wfsSpin{to{transform:rotate(360deg)}}
17598
17741
  .wfs-rise{animation:wfsRise 0.32s cubic-bezier(0.22,1,0.36,1) both}
17599
17742
  @media (prefers-reduced-motion: reduce){
17600
17743
  .wfs-anim,.wfs-rise,.wfs-shim{animation:none !important}
@@ -17675,7 +17818,7 @@ function WorkflowStepperRenderer({
17675
17818
  const steps = (_a = data.steps) != null ? _a : [];
17676
17819
  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
17820
  const interactive = typeof onSelectStep === "function";
17678
- const statusColor3 = (s) => s === "active" ? ACCENT2 : STATUS_COLORS3[s];
17821
+ const statusColor3 = (s) => s === "active" || s === "running" ? ACCENT2 : STATUS_COLORS3[s];
17679
17822
  const doneCount = steps.filter((s) => s.status === "done").length;
17680
17823
  const rootRef = React45__default.default.useRef(null);
17681
17824
  const containerW = useContainerWidth(rootRef);
@@ -17903,6 +18046,7 @@ function WorkflowStepperRenderer({
17903
18046
  var _a2;
17904
18047
  const isSelected = selectedStep === step.id;
17905
18048
  const isActive = step.status === "active";
18049
+ const isRunning = step.status === "running";
17906
18050
  const reached = step.status !== "pending";
17907
18051
  const clickable = interactive && reached;
17908
18052
  const color = statusColor3(step.status);
@@ -17999,36 +18143,41 @@ function WorkflowStepperRenderer({
17999
18143
  }
18000
18144
  }
18001
18145
  ),
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: [
18146
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 4 }, children: [
18147
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, minWidth: 0 }, children: [
18004
18148
  /* @__PURE__ */ jsxRuntime.jsx(IndexDot, { step, index: i, accent: ACCENT2 }),
18005
18149
  /* @__PURE__ */ jsxRuntime.jsx(
18006
18150
  "span",
18007
18151
  {
18008
- className: isActive ? "wfs-anim" : void 0,
18152
+ className: isActive || isRunning ? "wfs-anim" : void 0,
18009
18153
  style: {
18010
18154
  width: 6,
18011
18155
  height: 6,
18012
18156
  borderRadius: "50%",
18013
18157
  background: color,
18014
- animation: isActive ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
18158
+ flexShrink: 0,
18159
+ animation: isActive || isRunning ? "wfsLampPulse 1.8s ease-in-out infinite" : "none"
18015
18160
  }
18016
18161
  }
18017
18162
  )
18018
18163
  ] }),
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
- )
18164
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4, minWidth: 0 }, children: [
18165
+ /* @__PURE__ */ jsxRuntime.jsx(EvalBadge, { step }),
18166
+ /* @__PURE__ */ jsxRuntime.jsx(
18167
+ "span",
18168
+ {
18169
+ style: {
18170
+ fontSize: 9,
18171
+ fontWeight: 600,
18172
+ letterSpacing: "0.05em",
18173
+ textTransform: "uppercase",
18174
+ color,
18175
+ whiteSpace: "nowrap"
18176
+ },
18177
+ children: STATUS_LABELS[step.status]
18178
+ }
18179
+ )
18180
+ ] })
18032
18181
  ] }),
18033
18182
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [
18034
18183
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -18218,12 +18367,14 @@ var BADGE_TITLE = {
18218
18367
  var BADGE_STYLE = {
18219
18368
  SC: { bg: "#dcfce7", fg: "#15803d" },
18220
18369
  CN: { bg: "#eff6ff", fg: "#0364ff" },
18370
+ // theme-ok (SECONDARY)
18221
18371
  AB: { bg: "#fff7ed", fg: "#92400e" },
18222
18372
  SW: { bg: "#fef2f2", fg: "#dc2626" }
18223
18373
  };
18224
18374
  var STATE_DOT = {
18225
18375
  ok: "#15803d",
18226
18376
  corrected: "#0364ff",
18377
+ // theme-ok (SECONDARY)
18227
18378
  missing: "#dc2626",
18228
18379
  warn: "#f59e0b"
18229
18380
  };
@@ -18586,6 +18737,7 @@ var BADGE_DOT = {
18586
18737
  missing: "#dc2626",
18587
18738
  red: "#dc2626",
18588
18739
  corrected: "#0364ff"
18740
+ // theme-ok (SECONDARY)
18589
18741
  };
18590
18742
  function FieldDetails({
18591
18743
  summary,
@@ -20104,6 +20256,317 @@ function DecisionCardResolver(p) {
20104
20256
  }
20105
20257
  ) });
20106
20258
  }
20259
+ init_ThemeContext();
20260
+ var CONNECTED_GREEN3 = "#15803d";
20261
+ var CONNECTED_GREEN_BG = "#dcfce7";
20262
+ var PENDING_AMBER = "#92400e";
20263
+ var PENDING_AMBER_BG = "#fff7ed";
20264
+ var CARD_TITLE = "Authentication required";
20265
+ var TRUST_FOOTER = "Credentials not stored by Adopt";
20266
+ var DEFAULT_STEPS = (app, ctaLabel, connected) => connected ? [
20267
+ `Click ${ctaLabel} below to open ${app} in a new tab.`,
20268
+ "Confirm you are signed in \u2014 re-authenticate if prompted.",
20269
+ "Return here \u2014 the request continues automatically."
20270
+ ] : [
20271
+ `Click ${ctaLabel} below to open the sign-in page.`,
20272
+ `Sign in with your ${app} credentials \u2014 SSO is supported.`,
20273
+ "Return here \u2014 the request resumes automatically."
20274
+ ];
20275
+ function humanizeApp(raw) {
20276
+ const v = raw.trim();
20277
+ if (!v) return v;
20278
+ const looksLikeSlug = /^[a-z0-9]+([_-][a-z0-9]+)*$/.test(v);
20279
+ if (!looksLikeSlug) return v;
20280
+ return v.split(/[_-]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
20281
+ }
20282
+ function ShieldIcon({ color }) {
20283
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20284
+ "svg",
20285
+ {
20286
+ width: "13",
20287
+ height: "13",
20288
+ viewBox: "0 0 24 24",
20289
+ fill: "none",
20290
+ stroke: color,
20291
+ strokeWidth: "2",
20292
+ strokeLinecap: "round",
20293
+ strokeLinejoin: "round",
20294
+ "aria-hidden": "true",
20295
+ style: { flexShrink: 0 },
20296
+ children: [
20297
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
20298
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 12 2 2 4-4" })
20299
+ ]
20300
+ }
20301
+ );
20302
+ }
20303
+ function ExternalIcon() {
20304
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20305
+ "svg",
20306
+ {
20307
+ width: "13",
20308
+ height: "13",
20309
+ viewBox: "0 0 24 24",
20310
+ fill: "none",
20311
+ stroke: "currentColor",
20312
+ strokeWidth: "2",
20313
+ strokeLinecap: "round",
20314
+ strokeLinejoin: "round",
20315
+ "aria-hidden": "true",
20316
+ style: { flexShrink: 0 },
20317
+ children: [
20318
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 3h6v6" }),
20319
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 14 21 3" }),
20320
+ /* @__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" })
20321
+ ]
20322
+ }
20323
+ );
20324
+ }
20325
+ function TabbyAuthResolver(p) {
20326
+ var _a, _b, _c;
20327
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
20328
+ const [cardHovered, setCardHovered] = React45.useState(false);
20329
+ const [btnHovered, setBtnHovered] = React45.useState(false);
20330
+ const [imgFailed, setImgFailed] = React45.useState(false);
20331
+ const app = humanizeApp(p.app || "the app");
20332
+ const connected = p.state === "connected";
20333
+ const accent = connected ? CONNECTED_GREEN3 : ACCENT2;
20334
+ const ctaLabel = (_a = p.ctaLabel) != null ? _a : connected ? `Open ${app}` : `Connect ${app}`;
20335
+ const subtitle = p.workspace ? `${app} \xB7 ${p.workspace} workspace` : app;
20336
+ const steps = ((_b = p.steps) == null ? void 0 : _b.length) ? p.steps : DEFAULT_STEPS(app, ctaLabel, connected);
20337
+ 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.`;
20338
+ const iconSrc = p.iconUrl || brandIconUrl(app);
20339
+ const showImg = Boolean(iconSrc) && !imgFailed;
20340
+ const initial = app.charAt(0).toUpperCase();
20341
+ const badge = connected ? { label: "Connected", bg: CONNECTED_GREEN_BG, color: CONNECTED_GREEN3 } : { label: "Pending sign-in", bg: PENDING_AMBER_BG, color: PENDING_AMBER };
20342
+ const sectionPad = "13px 16px";
20343
+ 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(
20344
+ "div",
20345
+ {
20346
+ onMouseEnter: () => setCardHovered(true),
20347
+ onMouseLeave: () => setCardHovered(false),
20348
+ style: {
20349
+ display: "flex",
20350
+ flexDirection: "row",
20351
+ alignItems: "stretch",
20352
+ borderRadius: "0.75rem",
20353
+ border: `1px solid ${cardHovered ? "#d2d2d2" : BORDER4}`,
20354
+ background: "white",
20355
+ overflow: "hidden",
20356
+ 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)",
20357
+ transition: "box-shadow 0.18s ease, border-color 0.18s ease"
20358
+ },
20359
+ children: [
20360
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "3px", flexShrink: 0, background: accent } }),
20361
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }, children: [
20362
+ /* @__PURE__ */ jsxRuntime.jsxs(
20363
+ "div",
20364
+ {
20365
+ style: {
20366
+ display: "flex",
20367
+ alignItems: "flex-start",
20368
+ gap: "12px",
20369
+ padding: sectionPad
20370
+ },
20371
+ children: [
20372
+ /* @__PURE__ */ jsxRuntime.jsx(
20373
+ "div",
20374
+ {
20375
+ style: {
20376
+ position: "relative",
20377
+ width: "34px",
20378
+ height: "34px",
20379
+ borderRadius: "9px",
20380
+ flexShrink: 0,
20381
+ display: "flex",
20382
+ alignItems: "center",
20383
+ justifyContent: "center",
20384
+ background: showImg ? "white" : "#fff3ee",
20385
+ boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.06)",
20386
+ overflow: "hidden"
20387
+ },
20388
+ children: showImg ? /* @__PURE__ */ jsxRuntime.jsx(
20389
+ "img",
20390
+ {
20391
+ src: iconSrc,
20392
+ alt: app,
20393
+ onError: () => setImgFailed(true),
20394
+ style: { width: "22px", height: "22px", objectFit: "contain" }
20395
+ }
20396
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
20397
+ "span",
20398
+ {
20399
+ style: {
20400
+ fontFamily: "var(--font-serif)",
20401
+ fontSize: "17px",
20402
+ fontWeight: 400,
20403
+ color: ACCENT2,
20404
+ lineHeight: 1
20405
+ },
20406
+ children: initial
20407
+ }
20408
+ )
20409
+ }
20410
+ ),
20411
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "2px" }, children: [
20412
+ /* @__PURE__ */ jsxRuntime.jsx(
20413
+ "span",
20414
+ {
20415
+ style: {
20416
+ fontFamily: "var(--font-serif)",
20417
+ fontSize: "15px",
20418
+ fontWeight: 400,
20419
+ color: "var(--foreground)",
20420
+ letterSpacing: "-0.01em",
20421
+ lineHeight: 1.2
20422
+ },
20423
+ children: CARD_TITLE
20424
+ }
20425
+ ),
20426
+ /* @__PURE__ */ jsxRuntime.jsx(
20427
+ "span",
20428
+ {
20429
+ style: {
20430
+ fontSize: "12px",
20431
+ color: MUTED2,
20432
+ whiteSpace: "nowrap",
20433
+ overflow: "hidden",
20434
+ textOverflow: "ellipsis"
20435
+ },
20436
+ children: subtitle
20437
+ }
20438
+ )
20439
+ ] }),
20440
+ /* @__PURE__ */ jsxRuntime.jsxs(
20441
+ "span",
20442
+ {
20443
+ style: {
20444
+ display: "inline-flex",
20445
+ alignItems: "center",
20446
+ gap: "5px",
20447
+ flexShrink: 0,
20448
+ fontSize: "10.5px",
20449
+ fontWeight: 600,
20450
+ padding: "3px 9px",
20451
+ borderRadius: "9999px",
20452
+ background: badge.bg,
20453
+ color: badge.color,
20454
+ whiteSpace: "nowrap"
20455
+ },
20456
+ children: [
20457
+ /* @__PURE__ */ jsxRuntime.jsx(
20458
+ "span",
20459
+ {
20460
+ style: {
20461
+ width: "6px",
20462
+ height: "6px",
20463
+ borderRadius: "9999px",
20464
+ background: badge.color
20465
+ }
20466
+ }
20467
+ ),
20468
+ badge.label
20469
+ ]
20470
+ }
20471
+ )
20472
+ ]
20473
+ }
20474
+ ),
20475
+ /* @__PURE__ */ jsxRuntime.jsxs(
20476
+ "div",
20477
+ {
20478
+ style: {
20479
+ borderTop: `1px solid ${BORDER4}`,
20480
+ padding: sectionPad,
20481
+ display: "flex",
20482
+ flexDirection: "column",
20483
+ gap: "12px"
20484
+ },
20485
+ children: [
20486
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12.5px", lineHeight: 1.5, color: "var(--foreground)" }, children: description }),
20487
+ /* @__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: [
20488
+ /* @__PURE__ */ jsxRuntime.jsx(
20489
+ "span",
20490
+ {
20491
+ style: {
20492
+ flexShrink: 0,
20493
+ width: "18px",
20494
+ height: "18px",
20495
+ borderRadius: "9999px",
20496
+ background: accent,
20497
+ color: "white",
20498
+ fontSize: "10.5px",
20499
+ fontWeight: 600,
20500
+ display: "flex",
20501
+ alignItems: "center",
20502
+ justifyContent: "center",
20503
+ marginTop: "1px"
20504
+ },
20505
+ children: i + 1
20506
+ }
20507
+ ),
20508
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12.5px", lineHeight: 1.45, color: "var(--foreground)" }, children: step })
20509
+ ] }, i)) })
20510
+ ]
20511
+ }
20512
+ ),
20513
+ /* @__PURE__ */ jsxRuntime.jsxs(
20514
+ "div",
20515
+ {
20516
+ style: {
20517
+ borderTop: `1px solid ${BORDER4}`,
20518
+ padding: sectionPad,
20519
+ background: "#fbfbfb",
20520
+ display: "flex",
20521
+ alignItems: "center",
20522
+ justifyContent: "space-between",
20523
+ gap: "12px",
20524
+ flexWrap: "wrap"
20525
+ },
20526
+ children: [
20527
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "6px", color: MUTED2, fontSize: "11.5px" }, children: [
20528
+ /* @__PURE__ */ jsxRuntime.jsx(ShieldIcon, { color: CONNECTED_GREEN3 }),
20529
+ TRUST_FOOTER
20530
+ ] }),
20531
+ /* @__PURE__ */ jsxRuntime.jsxs(
20532
+ "a",
20533
+ {
20534
+ href: p.url,
20535
+ target: "_blank",
20536
+ rel: "noopener noreferrer",
20537
+ onMouseEnter: () => setBtnHovered(true),
20538
+ onMouseLeave: () => setBtnHovered(false),
20539
+ style: {
20540
+ display: "inline-flex",
20541
+ alignItems: "center",
20542
+ gap: "7px",
20543
+ flexShrink: 0,
20544
+ borderRadius: "8px",
20545
+ padding: "8px 15px",
20546
+ fontSize: "12.5px",
20547
+ fontWeight: 600,
20548
+ textDecoration: "none",
20549
+ whiteSpace: "nowrap",
20550
+ cursor: "pointer",
20551
+ color: "white",
20552
+ border: "1px solid transparent",
20553
+ background: btnHovered ? connected ? "#126a33" : ACCENT_SOFT2 : accent,
20554
+ transition: "background 0.15s ease"
20555
+ },
20556
+ children: [
20557
+ /* @__PURE__ */ jsxRuntime.jsx(ExternalIcon, {}),
20558
+ ctaLabel
20559
+ ]
20560
+ }
20561
+ )
20562
+ ]
20563
+ }
20564
+ )
20565
+ ] })
20566
+ ]
20567
+ }
20568
+ ) }) });
20569
+ }
20107
20570
  function resolveUI(rawPayload) {
20108
20571
  const payload = coercePayload(rawPayload);
20109
20572
  switch (payload.type) {
@@ -20225,6 +20688,8 @@ function resolveUI(rawPayload) {
20225
20688
  return /* @__PURE__ */ jsxRuntime.jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
20226
20689
  case "decision-card":
20227
20690
  return /* @__PURE__ */ jsxRuntime.jsx(DecisionCardResolver, __spreadValues({}, payload));
20691
+ case "tabby-auth":
20692
+ return /* @__PURE__ */ jsxRuntime.jsx(TabbyAuthResolver, __spreadValues({}, payload));
20228
20693
  default: {
20229
20694
  return /* @__PURE__ */ jsxRuntime.jsx(
20230
20695
  "div",