@tangle-network/agent-app 0.60.178 → 0.60.180

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 (60) hide show
  1. package/dist/agent-profiles/d1.js +3 -3
  2. package/dist/agent-profiles/index.js +3 -3
  3. package/dist/assistant/index.js +7 -5
  4. package/dist/assistant/index.js.map +1 -1
  5. package/dist/channels/index.js +1 -1
  6. package/dist/chat-routes/index.js +4 -4
  7. package/dist/{chunk-GIJY3YCH.js → chunk-3RHAF2P5.js} +11 -13
  8. package/dist/chunk-3RHAF2P5.js.map +1 -0
  9. package/dist/{chunk-IAFPBYQQ.js → chunk-6ZUVYAKB.js} +506 -315
  10. package/dist/chunk-6ZUVYAKB.js.map +1 -0
  11. package/dist/{chunk-ER3KSBA4.js → chunk-75ZIWV4U.js} +4 -4
  12. package/dist/{chunk-7PSYT35Z.js → chunk-7BYY7QKC.js} +5 -5
  13. package/dist/{chunk-7PSYT35Z.js.map → chunk-7BYY7QKC.js.map} +1 -1
  14. package/dist/chunk-A2GG4D4A.js +43 -0
  15. package/dist/chunk-A2GG4D4A.js.map +1 -0
  16. package/dist/{chunk-6CKNC32J.js → chunk-AJZ3EJB5.js} +2 -2
  17. package/dist/chunk-ATQQCG4I.js +194 -0
  18. package/dist/chunk-ATQQCG4I.js.map +1 -0
  19. package/dist/{chunk-4WEUWCA4.js → chunk-EQRVOMMS.js} +2 -2
  20. package/dist/{chunk-ARBBJWZA.js → chunk-KOTNMTHV.js} +3 -3
  21. package/dist/{chunk-LSUELMHY.js → chunk-LN5RBVGP.js} +6 -33
  22. package/dist/{chunk-LSUELMHY.js.map → chunk-LN5RBVGP.js.map} +1 -1
  23. package/dist/{chunk-CPNJRLPN.js → chunk-WSEXFTN4.js} +46 -7
  24. package/dist/chunk-WSEXFTN4.js.map +1 -0
  25. package/dist/{chunk-NO2YNV5C.js → chunk-YXLN4PXK.js} +2 -2
  26. package/dist/hub-approvals/index.js +1 -1
  27. package/dist/hub-approvals/types.d.ts +16 -1
  28. package/dist/hub-approvals-react/feedback.d.ts +25 -5
  29. package/dist/hub-approvals-react/index.d.ts +1 -0
  30. package/dist/hub-approvals-react/index.js +413 -257
  31. package/dist/hub-approvals-react/index.js.map +1 -1
  32. package/dist/hub-approvals-react/media.d.ts +12 -0
  33. package/dist/integrations-react/index.js +1 -1
  34. package/dist/preset-cloudflare/index.js +2 -2
  35. package/dist/public-consultation/index.d.ts +1 -1
  36. package/dist/sandbox/index.js +4 -4
  37. package/dist/stories/app-shell/interaction-evidence.d.ts +31 -0
  38. package/dist/studio-react/index.js +2 -2
  39. package/dist/theme/tokens.css +158 -0
  40. package/dist/tools/index.js +4 -4
  41. package/dist/web-react/action-dialog.d.ts +2 -2
  42. package/dist/web-react/agent-profile-editor.js +1 -1
  43. package/dist/web-react/agent-profile-form-kit.d.ts +1 -1
  44. package/dist/web-react/async/index.js +1 -1
  45. package/dist/web-react/index.d.ts +2 -0
  46. package/dist/web-react/index.js +12 -5
  47. package/dist/web-react/review-inbox.d.ts +33 -0
  48. package/dist/work-product/index.js +2 -2
  49. package/dist/workspace-react/index.js +1 -1
  50. package/package.json +2 -2
  51. package/dist/chunk-CPNJRLPN.js.map +0 -1
  52. package/dist/chunk-GIJY3YCH.js.map +0 -1
  53. package/dist/chunk-IAFPBYQQ.js.map +0 -1
  54. package/dist/chunk-QJYJOMMO.js +0 -78
  55. package/dist/chunk-QJYJOMMO.js.map +0 -1
  56. /package/dist/{chunk-ER3KSBA4.js.map → chunk-75ZIWV4U.js.map} +0 -0
  57. /package/dist/{chunk-6CKNC32J.js.map → chunk-AJZ3EJB5.js.map} +0 -0
  58. /package/dist/{chunk-4WEUWCA4.js.map → chunk-EQRVOMMS.js.map} +0 -0
  59. /package/dist/{chunk-ARBBJWZA.js.map → chunk-KOTNMTHV.js.map} +0 -0
  60. /package/dist/{chunk-NO2YNV5C.js.map → chunk-YXLN4PXK.js.map} +0 -0
@@ -1,3 +1,7 @@
1
+ import {
2
+ HubPreviewFeedback,
3
+ ReviewFeedbackForm
4
+ } from "../chunk-ATQQCG4I.js";
1
5
  import {
2
6
  HUB_APPROVAL_ACTIVE_PHASES,
3
7
  HUB_APPROVAL_OPEN_PHASES,
@@ -7,12 +11,12 @@ import {
7
11
  formatWhen,
8
12
  hubActionReceipt,
9
13
  presentHubAction
10
- } from "../chunk-CPNJRLPN.js";
14
+ } from "../chunk-WSEXFTN4.js";
11
15
 
12
16
  // src/hub-approvals-react/dock.tsx
13
- import { useEffect as useEffect3, useMemo, useRef, useState as useState4 } from "react";
17
+ import { useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState4 } from "react";
14
18
  import { Check, ChevronDown, ExternalLink, Loader2, X } from "lucide-react";
15
- import { Button as Button3, Label as Label2, RadioGroup, RadioGroupItem } from "@tangle-network/ui/primitives";
19
+ import { Button as Button3, Label, RadioGroup, RadioGroupItem } from "@tangle-network/ui/primitives";
16
20
 
17
21
  // src/hub-approvals-react/parts.tsx
18
22
  import { useState } from "react";
@@ -219,93 +223,365 @@ function linkedText(value) {
219
223
  return value.split(/(https?:\/\/[^\s<>"']+)/g).map((part, index) => /^https?:\/\//i.test(part) ? /* @__PURE__ */ jsx2("a", { href: part, onClick: (event) => event.preventDefault(), title: "Link shown for review", className: "text-[#1155cc] underline", children: part }, index) : part);
220
224
  }
221
225
 
226
+ // src/hub-approvals-react/media.tsx
227
+ import { useEffect as useEffect2, useId, useRef, useState as useState3 } from "react";
228
+ import { Bookmark, Camera, ChevronLeft, ChevronRight as ChevronRight2, Heart, MessageCircle, MoreHorizontal, Repeat2, Search, Send, Share2, ThumbsDown, ThumbsUp } from "lucide-react";
229
+ import { Button as Button2 } from "@tangle-network/ui/primitives";
230
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
231
+ var CHANNELS = {
232
+ x: "X",
233
+ linkedin: "LinkedIn",
234
+ slack: "Slack",
235
+ instagram: "Instagram",
236
+ facebook: "Facebook",
237
+ tiktok: "TikTok",
238
+ youtube: "YouTube"
239
+ };
240
+ function previewMediaSource(value, kind) {
241
+ if (!value) return void 0;
242
+ if (kind === "image" && embeddedPreviewImage(value)) return value;
243
+ if (kind === "video" && /^data:video\/(?:mp4|webm|ogg);base64,[a-z0-9+/=\s]+$/i.test(value)) return value;
244
+ if (!value.startsWith("blob:") || typeof window === "undefined") return void 0;
245
+ try {
246
+ const url = new URL(value);
247
+ return window.location.origin !== "null" && url.origin === window.location.origin ? value : void 0;
248
+ } catch {
249
+ return void 0;
250
+ }
251
+ }
252
+ function useReducedMotion() {
253
+ const [reduced, setReduced] = useState3(true);
254
+ useEffect2(() => {
255
+ const preference = window.matchMedia("(prefers-reduced-motion: reduce)");
256
+ const update = () => setReduced(preference.matches);
257
+ update();
258
+ preference.addEventListener("change", update);
259
+ return () => preference.removeEventListener("change", update);
260
+ }, []);
261
+ return reduced;
262
+ }
263
+ function MediaAsset({ media, active = true, fit = "cover" }) {
264
+ const source = previewMediaSource(media.src, media.kind);
265
+ const video = useRef(null);
266
+ const [failed, setFailed] = useState3(false);
267
+ useEffect2(() => {
268
+ setFailed(false);
269
+ }, [source]);
270
+ useEffect2(() => {
271
+ const element = video.current;
272
+ if (!element || !source) return;
273
+ const preference = window.matchMedia("(prefers-reduced-motion: reduce)");
274
+ let visible = false;
275
+ const update = () => {
276
+ element.loop = !preference.matches;
277
+ if (!active || !visible || document.hidden) element.pause();
278
+ else if (!preference.matches) void element.play().catch(() => {
279
+ });
280
+ };
281
+ const observer = new IntersectionObserver(([entry]) => {
282
+ visible = entry?.isIntersecting ?? false;
283
+ update();
284
+ });
285
+ observer.observe(element);
286
+ const preferenceChanged = () => {
287
+ if (preference.matches) element.pause();
288
+ update();
289
+ };
290
+ preference.addEventListener("change", preferenceChanged);
291
+ document.addEventListener("visibilitychange", update);
292
+ return () => {
293
+ observer.disconnect();
294
+ preference.removeEventListener("change", preferenceChanged);
295
+ document.removeEventListener("visibilitychange", update);
296
+ element.pause();
297
+ };
298
+ }, [source, active]);
299
+ const style = { width: "100%", height: "100%", objectFit: fit };
300
+ if (!source || failed) return /* @__PURE__ */ jsxs3("p", { role: "status", className: "flex h-full min-h-32 items-center justify-center p-5 text-center text-sm text-muted-foreground", children: [
301
+ media.alt || "Media",
302
+ " \u2014 ",
303
+ failed ? "could not be displayed" : "not embedded in this preview"
304
+ ] });
305
+ return media.kind === "video" ? /* @__PURE__ */ jsx3(
306
+ "video",
307
+ {
308
+ ref: video,
309
+ src: source,
310
+ poster: previewMediaSource(media.poster, "image"),
311
+ controls: true,
312
+ muted: true,
313
+ playsInline: true,
314
+ preload: "metadata",
315
+ "aria-label": media.alt || "Video preview",
316
+ style,
317
+ onError: () => setFailed(true)
318
+ }
319
+ ) : /* @__PURE__ */ jsx3("img", { src: source, alt: media.alt, style, onError: () => setFailed(true) });
320
+ }
321
+ function ratio(media, fallback) {
322
+ return media?.width && media.height && Number.isFinite(media.width / media.height) && media.width > 0 && media.height > 0 ? `${media.width} / ${media.height}` : fallback;
323
+ }
324
+ function Carousel({ media, square = false }) {
325
+ const id = useId();
326
+ const viewport = useRef(null);
327
+ const [index, setIndex] = useState3(0);
328
+ const reduced = useReducedMotion();
329
+ const go = (next) => {
330
+ const element = viewport.current;
331
+ if (element) element.scrollTo({ left: element.clientWidth * next, behavior: reduced ? "auto" : "smooth" });
332
+ };
333
+ return /* @__PURE__ */ jsxs3("div", { className: "relative", "data-hub-media-carousel": true, children: [
334
+ /* @__PURE__ */ jsx3(
335
+ "div",
336
+ {
337
+ ref: viewport,
338
+ id,
339
+ role: "region",
340
+ "aria-roledescription": "carousel",
341
+ "aria-label": "Post media",
342
+ tabIndex: 0,
343
+ "data-hub-media-carousel-scroll": true,
344
+ className: "flex overflow-x-auto",
345
+ style: { scrollSnapType: "x mandatory", overscrollBehaviorX: "contain", scrollbarWidth: "none", touchAction: "pan-x pan-y" },
346
+ onScroll: (event) => setIndex(Math.max(0, Math.min(media.length - 1, Math.round(event.currentTarget.scrollLeft / (event.currentTarget.clientWidth || 1))))),
347
+ onKeyDown: (event) => {
348
+ if (event.target !== event.currentTarget) return;
349
+ if (event.key === "ArrowRight") {
350
+ event.preventDefault();
351
+ go(Math.min(media.length - 1, index + 1));
352
+ }
353
+ if (event.key === "ArrowLeft") {
354
+ event.preventDefault();
355
+ go(Math.max(0, index - 1));
356
+ }
357
+ },
358
+ children: media.map((asset, position) => /* @__PURE__ */ jsx3(
359
+ "div",
360
+ {
361
+ role: "group",
362
+ "aria-roledescription": "slide",
363
+ "aria-label": `${position + 1} of ${media.length}`,
364
+ "data-hub-media-slide": position,
365
+ style: { flex: "0 0 100%", minWidth: 0, scrollSnapAlign: "start", aspectRatio: ratio(media[0], square ? "1" : "16 / 9") },
366
+ children: /* @__PURE__ */ jsx3(MediaAsset, { media: asset, active: index === position })
367
+ },
368
+ `${position}:${asset.src}`
369
+ ))
370
+ }
371
+ ),
372
+ media.length > 1 && /* @__PURE__ */ jsxs3(Fragment, { children: [
373
+ /* @__PURE__ */ jsxs3("span", { className: "pointer-events-none absolute right-3 top-3 rounded-full bg-black/65 px-2 py-1 text-xs tabular-nums text-white", "aria-hidden": true, children: [
374
+ index + 1,
375
+ "/",
376
+ media.length
377
+ ] }),
378
+ /* @__PURE__ */ jsx3(
379
+ "button",
380
+ {
381
+ type: "button",
382
+ "aria-label": "Previous slide",
383
+ "aria-controls": id,
384
+ disabled: index === 0,
385
+ onClick: () => go(index - 1),
386
+ className: "absolute left-2 top-1/2 flex size-9 -translate-y-1/2 items-center justify-center rounded-full bg-white/90 text-[#262626] shadow-sm disabled:hidden",
387
+ children: /* @__PURE__ */ jsx3(ChevronLeft, { "aria-hidden": true, className: "size-5" })
388
+ }
389
+ ),
390
+ /* @__PURE__ */ jsx3(
391
+ "button",
392
+ {
393
+ type: "button",
394
+ "aria-label": "Next slide",
395
+ "aria-controls": id,
396
+ disabled: index === media.length - 1,
397
+ onClick: () => go(index + 1),
398
+ className: "absolute right-2 top-1/2 flex size-9 -translate-y-1/2 items-center justify-center rounded-full bg-white/90 text-[#262626] shadow-sm disabled:hidden",
399
+ children: /* @__PURE__ */ jsx3(ChevronRight2, { "aria-hidden": true, className: "size-5" })
400
+ }
401
+ ),
402
+ /* @__PURE__ */ jsx3("div", { className: "absolute bottom-3 left-1/2 flex -translate-x-1/2 gap-1", "aria-hidden": true, children: media.map((_, position) => /* @__PURE__ */ jsx3("span", { className: `size-1.5 rounded-full ${position === index ? "bg-[#0095f6]" : "bg-white/75"}` }, position)) }),
403
+ /* @__PURE__ */ jsxs3("p", { className: "sr-only", "aria-live": "polite", children: [
404
+ "Slide ",
405
+ index + 1,
406
+ " of ",
407
+ media.length
408
+ ] })
409
+ ] })
410
+ ] });
411
+ }
412
+ function Avatar({ name, square = false }) {
413
+ return /* @__PURE__ */ jsx3("span", { "aria-hidden": true, className: `flex size-10 shrink-0 items-center justify-center bg-[#eef0f2] text-base font-semibold text-[#536471] ${square ? "rounded-sm" : "rounded-full"}`, children: name?.charAt(0).toUpperCase() || "?" });
414
+ }
415
+ function ChromeActions({ channel, vertical = false }) {
416
+ const actions = channel === "youtube" ? [["Like", /* @__PURE__ */ jsx3(ThumbsUp, {})], ["Dislike", /* @__PURE__ */ jsx3(ThumbsDown, {})], ["Comments", /* @__PURE__ */ jsx3(MessageCircle, {})], ["Share", /* @__PURE__ */ jsx3(Share2, {})]] : channel === "tiktok" ? [["Like", /* @__PURE__ */ jsx3(Heart, {})], ["Comment", /* @__PURE__ */ jsx3(MessageCircle, {})], ["Share", /* @__PURE__ */ jsx3(Share2, {})]] : channel === "instagram" && vertical ? [["Like", /* @__PURE__ */ jsx3(Heart, {})], ["Comment", /* @__PURE__ */ jsx3(MessageCircle, {})], ["Repost", /* @__PURE__ */ jsx3(Repeat2, {})], ["Share", /* @__PURE__ */ jsx3(Send, {})], ["More", /* @__PURE__ */ jsx3(MoreHorizontal, {})]] : channel === "linkedin" || channel === "facebook" ? [["Like", /* @__PURE__ */ jsx3(ThumbsUp, {})], ["Comment", /* @__PURE__ */ jsx3(MessageCircle, {})], [channel === "linkedin" ? "Repost" : "Share", channel === "linkedin" ? /* @__PURE__ */ jsx3(Repeat2, {}) : /* @__PURE__ */ jsx3(Share2, {})]] : channel === "x" ? [["Reply", /* @__PURE__ */ jsx3(MessageCircle, {})], ["Repost", /* @__PURE__ */ jsx3(Repeat2, {})], ["Like", /* @__PURE__ */ jsx3(Heart, {})], ["Bookmark", /* @__PURE__ */ jsx3(Bookmark, {})], ["Share", /* @__PURE__ */ jsx3(Share2, {})]] : [["Like", /* @__PURE__ */ jsx3(Heart, {})], ["Comment", /* @__PURE__ */ jsx3(MessageCircle, {})], ["Share", /* @__PURE__ */ jsx3(Send, {})], ["Save", /* @__PURE__ */ jsx3(Bookmark, {})]];
417
+ return /* @__PURE__ */ jsx3("div", { "aria-label": "Feed controls shown for context", className: vertical ? "flex flex-col items-center gap-5" : "flex items-center justify-between gap-3", children: actions.map(([label, icon]) => /* @__PURE__ */ jsxs3("span", { title: label, "aria-label": label, className: `flex items-center gap-1.5 [&>svg]:size-5 ${vertical ? "flex-col text-[10px]" : "text-[13px]"}`, children: [
418
+ icon,
419
+ (channel === "facebook" || channel === "linkedin" || vertical && channel === "youtube") && /* @__PURE__ */ jsx3("span", { children: label })
420
+ ] }, label)) });
421
+ }
422
+ function VerticalPreview({ preview, account, media }) {
423
+ const [guides, setGuides] = useState3(false);
424
+ const frame = useRef(null);
425
+ const top = useRef(null);
426
+ const caption = useRef(null);
427
+ const rail = useRef(null);
428
+ const [insets, setInsets] = useState3({});
429
+ const name = preview.displayName ?? account ?? "Account unavailable";
430
+ const title = preview.channel === "youtube" ? "Shorts" : preview.channel === "instagram" || preview.channel === "facebook" ? "Reels" : "For You";
431
+ useEffect2(() => {
432
+ const update = () => {
433
+ if (!frame.current || !top.current || !caption.current || !rail.current) return;
434
+ const bounds = frame.current.getBoundingClientRect();
435
+ setInsets({
436
+ top: top.current.getBoundingClientRect().bottom - bounds.top,
437
+ bottom: bounds.bottom - caption.current.getBoundingClientRect().top,
438
+ right: bounds.right - rail.current.getBoundingClientRect().left + 8,
439
+ left: 16
440
+ });
441
+ };
442
+ const observer = new ResizeObserver(update);
443
+ for (const element of [frame.current, top.current, caption.current, rail.current]) if (element) observer.observe(element);
444
+ update();
445
+ return () => observer.disconnect();
446
+ }, [preview.text, preview.channel]);
447
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-auto w-full max-w-[360px] space-y-2", children: [
448
+ /* @__PURE__ */ jsxs3("div", { ref: frame, "data-hub-media-vertical": true, className: "relative isolate aspect-[9/16] overflow-hidden rounded-xl bg-black text-white [color-scheme:dark]", children: [
449
+ /* @__PURE__ */ jsx3("div", { className: "absolute inset-0", children: media[0] ? /* @__PURE__ */ jsx3(MediaAsset, { media: media[0] }) : /* @__PURE__ */ jsx3("p", { className: "p-5 text-sm", children: "Media not embedded in this preview" }) }),
450
+ /* @__PURE__ */ jsxs3("div", { ref: top, className: "pointer-events-none absolute inset-x-0 top-0 flex items-center justify-between bg-gradient-to-b from-black/65 to-transparent px-4 pb-5 pt-4", children: [
451
+ /* @__PURE__ */ jsxs3("span", { className: "text-lg font-semibold", children: [
452
+ preview.channel === "tiktok" && /* @__PURE__ */ jsx3("span", { className: "mr-4 text-white/70", children: "Following" }),
453
+ title
454
+ ] }),
455
+ preview.channel === "instagram" ? /* @__PURE__ */ jsx3(Camera, { "aria-hidden": true, className: "size-5" }) : /* @__PURE__ */ jsx3(Search, { "aria-hidden": true, className: "size-5" })
456
+ ] }),
457
+ /* @__PURE__ */ jsx3("div", { ref: rail, className: "pointer-events-none absolute bottom-40 right-3 drop-shadow-md", children: /* @__PURE__ */ jsx3(ChromeActions, { channel: preview.channel, vertical: true }) }),
458
+ /* @__PURE__ */ jsxs3("div", { ref: caption, className: "pointer-events-none absolute bottom-14 left-0 right-14 bg-gradient-to-t from-black/70 to-transparent px-4 pb-3 pt-8 text-sm drop-shadow-md", children: [
459
+ /* @__PURE__ */ jsx3("p", { className: "break-words font-semibold", children: preview.handle ?? name }),
460
+ preview.sponsored && /* @__PURE__ */ jsx3("p", { className: "mt-1 text-xs", children: "Sponsored" }),
461
+ /* @__PURE__ */ jsx3("p", { className: "mt-1 line-clamp-4 whitespace-pre-wrap break-words leading-5", children: preview.text }),
462
+ preview.callToAction && /* @__PURE__ */ jsx3("p", { className: "mt-2 rounded-md border border-white/70 px-3 py-2 text-center font-semibold", children: preview.callToAction })
463
+ ] }),
464
+ guides && /* @__PURE__ */ jsx3("div", { "data-hub-media-safe-zone": true, "aria-label": "Area clear of this preview\u2019s caption and controls", className: "pointer-events-none absolute border-2 border-dashed border-white/90", style: { ...insets, boxShadow: "0 0 0 999px rgb(0 0 0 / 25%)" } })
465
+ ] }),
466
+ /* @__PURE__ */ jsx3(Button2, { type: "button", variant: "outline", "aria-pressed": guides, onClick: () => setGuides((value) => !value), children: guides ? "Hide caption safe zones" : "Show caption safe zones" }),
467
+ guides && /* @__PURE__ */ jsx3("p", { className: "text-xs leading-5 text-muted-foreground", children: "Guide follows this preview\u2019s caption and controls. Placement and device can change the area." })
468
+ ] });
469
+ }
470
+ function HubMediaPreview({ preview, account }) {
471
+ const media = preview.media ?? preview.images?.map((image) => ({ kind: "image", src: image.url, alt: image.alt ?? "" })) ?? [];
472
+ const name = preview.displayName ?? account ?? "Account unavailable";
473
+ const count = /* @__PURE__ */ jsxs3("p", { "data-hub-media-character-count": true, className: "text-right text-xs tabular-nums text-muted-foreground", children: [
474
+ [...preview.text].length,
475
+ " characters"
476
+ ] });
477
+ if (preview.placement === "vertical") return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
478
+ /* @__PURE__ */ jsx3("article", { "aria-label": `${CHANNELS[preview.channel]} ${preview.channel === "youtube" ? "Shorts" : "vertical"} preview`, "data-hub-media-channel": preview.channel, children: /* @__PURE__ */ jsx3(VerticalPreview, { preview, account, media }) }),
479
+ count
480
+ ] });
481
+ const x = preview.channel === "x";
482
+ const instagram = preview.channel === "instagram";
483
+ const imageGrid = x && preview.placement !== "carousel" && media.length > 1 && media.length <= 4 && media.every((asset) => asset.kind === "image");
484
+ return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
485
+ /* @__PURE__ */ jsxs3(
486
+ "article",
487
+ {
488
+ "aria-label": `${CHANNELS[preview.channel]} ${preview.sponsored ? "sponsored " : ""}feed preview`,
489
+ "data-hub-media-channel": preview.channel,
490
+ className: `overflow-hidden border border-[#d8dee3] bg-white text-[#0f1419] [color-scheme:light] ${x ? "rounded-2xl" : "rounded-lg"}`,
491
+ children: [
492
+ /* @__PURE__ */ jsxs3("header", { className: "flex min-w-0 items-start gap-3 px-4 pt-4", children: [
493
+ /* @__PURE__ */ jsx3(Avatar, { name: preview.displayName ?? account, square: preview.channel === "linkedin" }),
494
+ /* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1 text-sm", children: [
495
+ /* @__PURE__ */ jsxs3("p", { className: "break-words font-semibold", children: [
496
+ name,
497
+ preview.handle && /* @__PURE__ */ jsx3("span", { className: "ml-1.5 font-normal text-[#536471]", children: preview.handle })
498
+ ] }),
499
+ preview.sponsored && /* @__PURE__ */ jsx3("p", { className: "mt-0.5 text-xs text-[#536471]", children: preview.channel === "linkedin" || x ? "Promoted" : "Sponsored" })
500
+ ] }),
501
+ /* @__PURE__ */ jsx3(MoreHorizontal, { "aria-hidden": true, className: "size-5 shrink-0 text-[#536471]" })
502
+ ] }),
503
+ !instagram && /* @__PURE__ */ jsx3("p", { className: "whitespace-pre-wrap break-words px-4 py-3 text-[15px] leading-6", children: linkedText(preview.text) }),
504
+ media.length > 0 && /* @__PURE__ */ jsx3("div", { className: x ? "mx-4 overflow-hidden rounded-xl border border-[#d8dee3]" : "", children: imageGrid ? /* @__PURE__ */ jsx3("div", { "data-hub-media-image-grid": true, className: "grid aspect-[16/9] grid-cols-2 gap-0.5 overflow-hidden", children: media.map((asset, index) => /* @__PURE__ */ jsx3("div", { className: `min-h-0 overflow-hidden ${media.length === 3 && index === 0 ? "row-span-2" : ""}`, children: /* @__PURE__ */ jsx3(MediaAsset, { media: asset }) }, index)) }) : /* @__PURE__ */ jsx3(Carousel, { media, square: instagram }) }),
505
+ preview.link && /* @__PURE__ */ jsxs3("div", { className: "border-b border-[#d8dee3] bg-[#f3f6f8] px-4 py-3", children: [
506
+ /* @__PURE__ */ jsx3("p", { className: "truncate text-xs text-[#536471]", children: preview.link.url.replace(/^https?:\/\//, "") }),
507
+ preview.link.title && /* @__PURE__ */ jsx3("p", { className: "mt-1 break-words text-sm font-semibold", children: preview.link.title }),
508
+ preview.link.description && /* @__PURE__ */ jsx3("p", { className: "mt-1 line-clamp-2 text-sm text-[#536471]", children: preview.link.description }),
509
+ preview.callToAction && /* @__PURE__ */ jsx3("span", { className: "mt-2 inline-block rounded border border-[#536471] px-3 py-1.5 text-sm font-semibold", children: preview.callToAction })
510
+ ] }),
511
+ /* @__PURE__ */ jsx3("div", { className: "px-4 py-3 text-[#536471]", children: /* @__PURE__ */ jsx3(ChromeActions, { channel: preview.channel }) }),
512
+ instagram && /* @__PURE__ */ jsxs3("p", { className: "whitespace-pre-wrap break-words px-4 pb-4 text-sm leading-5", children: [
513
+ /* @__PURE__ */ jsx3("strong", { className: "mr-1.5", children: preview.handle ?? name }),
514
+ linkedText(preview.text)
515
+ ] }),
516
+ /* @__PURE__ */ jsx3("p", { className: "sr-only", children: "Preview controls cannot post, buy, like, or share." })
517
+ ]
518
+ }
519
+ ),
520
+ count
521
+ ] });
522
+ }
523
+
222
524
  // src/hub-approvals-react/preview.tsx
223
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
525
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
224
526
  function initial(name) {
225
527
  return (name?.trim().replace(/^@/, "").charAt(0) || "?").toUpperCase();
226
528
  }
227
529
  function Panel({ children, className = "" }) {
228
- return /* @__PURE__ */ jsx3("div", { className: `rounded-lg border border-border bg-background ${className}`, children });
530
+ return /* @__PURE__ */ jsx4("div", { className: `rounded-lg border border-border bg-background ${className}`, children });
229
531
  }
230
532
  function PullRequestPreview({ preview }) {
231
- return /* @__PURE__ */ jsxs3("div", { className: "space-y-3", children: [
232
- /* @__PURE__ */ jsxs3(Panel, { className: "px-3 py-3", children: [
233
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-2 text-sm text-muted-foreground", children: [
234
- /* @__PURE__ */ jsx3(GitPullRequest, { "aria-hidden": true, className: "size-4 shrink-0" }),
235
- preview.repository && /* @__PURE__ */ jsx3("span", { className: "font-medium text-foreground", children: preview.repository }),
236
- preview.head && preview.base && /* @__PURE__ */ jsxs3("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
237
- /* @__PURE__ */ jsx3(Chip, { mono: true, children: preview.head }),
238
- /* @__PURE__ */ jsx3(ArrowRight, { "aria-label": "into", className: "size-4 shrink-0" }),
239
- /* @__PURE__ */ jsx3(Chip, { mono: true, children: preview.base })
533
+ return /* @__PURE__ */ jsxs4("div", { className: "space-y-3", children: [
534
+ /* @__PURE__ */ jsxs4(Panel, { className: "px-3 py-3", children: [
535
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2 text-sm text-muted-foreground", children: [
536
+ /* @__PURE__ */ jsx4(GitPullRequest, { "aria-hidden": true, className: "size-4 shrink-0" }),
537
+ preview.repository && /* @__PURE__ */ jsx4("span", { className: "font-medium text-foreground", children: preview.repository }),
538
+ preview.head && preview.base && /* @__PURE__ */ jsxs4("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
539
+ /* @__PURE__ */ jsx4(Chip, { mono: true, children: preview.head }),
540
+ /* @__PURE__ */ jsx4(ArrowRight, { "aria-label": "into", className: "size-4 shrink-0" }),
541
+ /* @__PURE__ */ jsx4(Chip, { mono: true, children: preview.base })
240
542
  ] }),
241
- preview.draft && /* @__PURE__ */ jsx3("span", { className: "rounded-md border border-border px-1.5 py-0.5 text-sm text-muted-foreground", children: "Draft" })
543
+ preview.draft && /* @__PURE__ */ jsx4("span", { className: "rounded-md border border-border px-1.5 py-0.5 text-sm text-muted-foreground", children: "Draft" })
242
544
  ] }),
243
- preview.title && /* @__PURE__ */ jsx3("p", { className: "mt-2 text-base font-semibold leading-6 text-foreground", children: preview.title }),
244
- preview.body && /* @__PURE__ */ jsx3("p", { className: "mt-1 line-clamp-3 whitespace-pre-line text-sm leading-6 text-muted-foreground sm:line-clamp-4", children: preview.body })
545
+ preview.title && /* @__PURE__ */ jsx4("p", { className: "mt-2 text-base font-semibold leading-6 text-foreground", children: preview.title }),
546
+ preview.body && /* @__PURE__ */ jsx4("p", { className: "mt-1 line-clamp-3 whitespace-pre-line text-sm leading-6 text-muted-foreground sm:line-clamp-4", children: preview.body })
245
547
  ] }),
246
- preview.files.length > 0 && /* @__PURE__ */ jsx3(ApprovalDiffSummary, { files: preview.files })
548
+ preview.files.length > 0 && /* @__PURE__ */ jsx4(ApprovalDiffSummary, { files: preview.files })
247
549
  ] });
248
550
  }
249
- function PostPreview({ preview, account }) {
250
- if (preview.channel === "slack") {
251
- return /* @__PURE__ */ jsxs3(Panel, { className: "px-3 py-3", children: [
252
- /* @__PURE__ */ jsx3("p", { className: "text-sm font-semibold text-foreground", children: preview.where ?? "Slack" }),
253
- /* @__PURE__ */ jsxs3("div", { className: "mt-2 flex gap-3", children: [
254
- /* @__PURE__ */ jsx3("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-md bg-muted text-sm font-semibold text-foreground", children: initial(account) }),
255
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0", children: [
256
- /* @__PURE__ */ jsx3("p", { className: "text-sm font-semibold text-foreground", children: account ?? "Your account" }),
257
- /* @__PURE__ */ jsx3("p", { className: "whitespace-pre-wrap break-words text-sm leading-6 text-foreground", children: linkedText(preview.text) })
258
- ] })
259
- ] })
260
- ] });
261
- }
262
- const x = preview.channel === "x";
263
- const length = [...preview.text].length;
264
- return /* @__PURE__ */ jsxs3(Panel, { className: "px-4 py-3", children: [
265
- /* @__PURE__ */ jsxs3("div", { className: "flex gap-3", children: [
266
- /* @__PURE__ */ jsx3("span", { className: `flex size-10 shrink-0 items-center justify-center rounded-full text-base font-semibold ${x ? "bg-foreground text-background" : "bg-[#0a66c2] text-white"}`, children: initial(account) }),
267
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
268
- /* @__PURE__ */ jsxs3("p", { className: "flex flex-wrap items-baseline gap-x-1.5 text-sm", children: [
269
- /* @__PURE__ */ jsx3("span", { className: "font-semibold text-foreground", children: account ?? "Your account" }),
270
- /* @__PURE__ */ jsx3("span", { className: "text-muted-foreground", children: x ? "\xB7 now" : "\xB7 Post \xB7 Anyone" })
271
- ] }),
272
- /* @__PURE__ */ jsx3("p", { className: `mt-1 whitespace-pre-wrap break-words text-foreground ${x ? "text-base leading-6" : "text-sm leading-6"}`, children: linkedText(preview.text) }),
273
- preview.images && preview.images.length > 0 && /* @__PURE__ */ jsx3("div", { className: "mt-3 grid grid-cols-2 gap-0.5 overflow-hidden rounded-xl border border-border", children: preview.images.map((image, index) => /* @__PURE__ */ jsx3("div", { className: `${preview.images.length === 1 ? "col-span-2 aspect-[16/9]" : "aspect-square"} overflow-hidden bg-muted`, children: embeddedPreviewImage(image.url) ? /* @__PURE__ */ jsx3("img", { src: image.url, alt: image.alt ?? `Post image ${index + 1}`, className: "size-full object-cover" }) : /* @__PURE__ */ jsx3("p", { className: "p-3 text-sm text-muted-foreground", children: "Image not embedded in this preview" }) }, index)) }),
274
- preview.link && /* @__PURE__ */ jsx3("div", { className: "mt-3 overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsxs3("div", { className: "px-3 py-2", children: [
275
- /* @__PURE__ */ jsx3("p", { className: "truncate text-sm text-muted-foreground", children: preview.link.url.replace(/^https?:\/\//, "") }),
276
- preview.link.title && /* @__PURE__ */ jsx3("p", { className: "truncate text-sm font-semibold text-foreground", children: preview.link.title }),
277
- preview.link.description && /* @__PURE__ */ jsx3("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: preview.link.description })
278
- ] }) })
551
+ function SlackPreview({ preview, account }) {
552
+ return /* @__PURE__ */ jsxs4(Panel, { className: "px-3 py-3", children: [
553
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-semibold text-foreground", children: preview.where ?? "Slack" }),
554
+ /* @__PURE__ */ jsxs4("div", { className: "mt-2 flex gap-3", children: [
555
+ /* @__PURE__ */ jsx4("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-md bg-muted text-sm font-semibold text-foreground", children: initial(account) }),
556
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
557
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-semibold text-foreground", children: account ?? "Your account" }),
558
+ /* @__PURE__ */ jsx4("p", { className: "whitespace-pre-wrap break-words text-sm leading-6 text-foreground", children: linkedText(preview.text) })
279
559
  ] })
280
- ] }),
281
- /* @__PURE__ */ jsxs3("p", { className: "mt-2 text-right text-sm tabular-nums text-muted-foreground", children: [
282
- length,
283
- " characters"
284
560
  ] })
285
561
  ] });
286
562
  }
287
563
  function PaymentPreview({ preview }) {
288
- return /* @__PURE__ */ jsxs3(Panel, { className: "px-4 py-3", children: [
289
- /* @__PURE__ */ jsx3("p", { className: "text-sm text-muted-foreground", children: preview.label.charAt(0).toUpperCase() + preview.label.slice(1) }),
290
- preview.amount !== void 0 && /* @__PURE__ */ jsx3("p", { className: "mt-0.5 text-2xl font-semibold tabular-nums text-foreground", children: formatMinorAmount(preview.amount, preview.currency) }),
291
- /* @__PURE__ */ jsxs3("div", { className: "mt-2 space-y-1 text-sm", children: [
292
- preview.customer && /* @__PURE__ */ jsxs3("p", { className: "text-muted-foreground", children: [
564
+ return /* @__PURE__ */ jsxs4(Panel, { className: "px-4 py-3", children: [
565
+ /* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground", children: preview.label.charAt(0).toUpperCase() + preview.label.slice(1) }),
566
+ preview.amount !== void 0 && /* @__PURE__ */ jsx4("p", { className: "mt-0.5 text-2xl font-semibold tabular-nums text-foreground", children: formatMinorAmount(preview.amount, preview.currency) }),
567
+ /* @__PURE__ */ jsxs4("div", { className: "mt-2 space-y-1 text-sm", children: [
568
+ preview.customer && /* @__PURE__ */ jsxs4("p", { className: "text-muted-foreground", children: [
293
569
  "Customer ",
294
- /* @__PURE__ */ jsx3("span", { className: `text-foreground ${preview.customer.startsWith("cus_") ? "font-mono" : ""}`, children: preview.customer })
570
+ /* @__PURE__ */ jsx4("span", { className: `text-foreground ${preview.customer.startsWith("cus_") ? "font-mono" : ""}`, children: preview.customer })
295
571
  ] }),
296
- preview.description && /* @__PURE__ */ jsx3("p", { className: "text-foreground", children: preview.description })
572
+ preview.description && /* @__PURE__ */ jsx4("p", { className: "text-foreground", children: preview.description })
297
573
  ] })
298
574
  ] });
299
575
  }
300
576
  function SpeechPreview({ preview }) {
301
- return /* @__PURE__ */ jsxs3(Panel, { className: "px-4 py-3", children: [
302
- /* @__PURE__ */ jsx3("blockquote", { className: "border-l-2 border-[var(--accent-text)] pl-3 text-base leading-7 text-foreground", children: preview.text }),
303
- (preview.voice || preview.seconds) && /* @__PURE__ */ jsxs3("div", { className: "mt-3 flex flex-wrap gap-2", children: [
304
- preview.voice && /* @__PURE__ */ jsxs3(Chip, { children: [
577
+ return /* @__PURE__ */ jsxs4(Panel, { className: "px-4 py-3", children: [
578
+ /* @__PURE__ */ jsx4("blockquote", { className: "border-l-2 border-[var(--accent-text)] pl-3 text-base leading-7 text-foreground", children: preview.text }),
579
+ (preview.voice || preview.seconds) && /* @__PURE__ */ jsxs4("div", { className: "mt-3 flex flex-wrap gap-2", children: [
580
+ preview.voice && /* @__PURE__ */ jsxs4(Chip, { children: [
305
581
  "Voice: ",
306
582
  preview.voice
307
583
  ] }),
308
- preview.seconds && /* @__PURE__ */ jsxs3(Chip, { children: [
584
+ preview.seconds && /* @__PURE__ */ jsxs4(Chip, { children: [
309
585
  "About ",
310
586
  preview.seconds,
311
587
  " s"
@@ -314,241 +590,120 @@ function SpeechPreview({ preview }) {
314
590
  ] });
315
591
  }
316
592
  function CallPreview({ preview }) {
317
- return /* @__PURE__ */ jsxs3(Panel, { className: "flex gap-3 px-4 py-3", children: [
318
- /* @__PURE__ */ jsx3("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx3(Phone, { "aria-hidden": true, className: "size-5 text-foreground" }) }),
319
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0 space-y-1 text-sm", children: [
320
- /* @__PURE__ */ jsx3("p", { className: "text-base font-semibold tabular-nums text-foreground", children: preview.to ?? "Unknown number" }),
321
- preview.from && /* @__PURE__ */ jsxs3("p", { className: "text-muted-foreground", children: [
593
+ return /* @__PURE__ */ jsxs4(Panel, { className: "flex gap-3 px-4 py-3", children: [
594
+ /* @__PURE__ */ jsx4("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx4(Phone, { "aria-hidden": true, className: "size-5 text-foreground" }) }),
595
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0 space-y-1 text-sm", children: [
596
+ /* @__PURE__ */ jsx4("p", { className: "text-base font-semibold tabular-nums text-foreground", children: preview.to ?? "Unknown number" }),
597
+ preview.from && /* @__PURE__ */ jsxs4("p", { className: "text-muted-foreground", children: [
322
598
  "From ",
323
- /* @__PURE__ */ jsx3("span", { className: "tabular-nums text-foreground", children: preview.from })
599
+ /* @__PURE__ */ jsx4("span", { className: "tabular-nums text-foreground", children: preview.from })
324
600
  ] }),
325
- preview.purpose && /* @__PURE__ */ jsx3("p", { className: "leading-6 text-foreground", children: preview.purpose })
601
+ preview.purpose && /* @__PURE__ */ jsx4("p", { className: "leading-6 text-foreground", children: preview.purpose })
326
602
  ] })
327
603
  ] });
328
604
  }
329
605
  function EventPreview({ preview }) {
330
606
  const start = preview.start ? new Date(preview.start) : null;
331
607
  const valid = start && !Number.isNaN(start.getTime());
332
- return /* @__PURE__ */ jsxs3(Panel, { className: "flex gap-4 px-4 py-3", children: [
333
- /* @__PURE__ */ jsxs3("div", { className: "flex w-14 shrink-0 flex-col items-center overflow-hidden rounded-lg border border-border text-center", children: [
334
- /* @__PURE__ */ jsx3("span", { className: "w-full bg-[var(--surface-danger-bg)] py-0.5 text-sm font-semibold uppercase text-[var(--surface-danger-text)]", children: valid ? start.toLocaleDateString(void 0, { month: "short" }) : /* @__PURE__ */ jsx3(CalendarDays, { "aria-hidden": true, className: "mx-auto size-4" }) }),
335
- /* @__PURE__ */ jsx3("span", { className: "py-1 text-xl font-semibold tabular-nums text-foreground", children: valid ? start.getDate() : "\u2013" })
608
+ return /* @__PURE__ */ jsxs4(Panel, { className: "flex gap-4 px-4 py-3", children: [
609
+ /* @__PURE__ */ jsxs4("div", { className: "flex w-14 shrink-0 flex-col items-center overflow-hidden rounded-lg border border-border text-center", children: [
610
+ /* @__PURE__ */ jsx4("span", { className: "w-full bg-[var(--surface-danger-bg)] py-0.5 text-sm font-semibold uppercase text-[var(--surface-danger-text)]", children: valid ? start.toLocaleDateString(void 0, { month: "short" }) : /* @__PURE__ */ jsx4(CalendarDays, { "aria-hidden": true, className: "mx-auto size-4" }) }),
611
+ /* @__PURE__ */ jsx4("span", { className: "py-1 text-xl font-semibold tabular-nums text-foreground", children: valid ? start.getDate() : "\u2013" })
336
612
  ] }),
337
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0 space-y-1 text-sm", children: [
338
- /* @__PURE__ */ jsx3("p", { className: "text-base font-semibold text-foreground", children: preview.title ?? "Untitled event" }),
339
- preview.start && /* @__PURE__ */ jsx3("p", { className: "text-foreground", children: formatWhen(preview.start, preview.end) }),
340
- preview.location && /* @__PURE__ */ jsxs3("p", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
341
- /* @__PURE__ */ jsx3(MapPin, { "aria-hidden": true, className: "size-4 shrink-0" }),
613
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0 space-y-1 text-sm", children: [
614
+ /* @__PURE__ */ jsx4("p", { className: "text-base font-semibold text-foreground", children: preview.title ?? "Untitled event" }),
615
+ preview.start && /* @__PURE__ */ jsx4("p", { className: "text-foreground", children: formatWhen(preview.start, preview.end) }),
616
+ preview.location && /* @__PURE__ */ jsxs4("p", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
617
+ /* @__PURE__ */ jsx4(MapPin, { "aria-hidden": true, className: "size-4 shrink-0" }),
342
618
  preview.location
343
619
  ] }),
344
- preview.attendees.length > 0 && /* @__PURE__ */ jsxs3("p", { className: "flex items-start gap-1.5 text-muted-foreground", children: [
345
- /* @__PURE__ */ jsx3(Users, { "aria-hidden": true, className: "mt-0.5 size-4 shrink-0" }),
346
- /* @__PURE__ */ jsx3("span", { className: "break-words", children: preview.attendees.join(", ") })
620
+ preview.attendees.length > 0 && /* @__PURE__ */ jsxs4("p", { className: "flex items-start gap-1.5 text-muted-foreground", children: [
621
+ /* @__PURE__ */ jsx4(Users, { "aria-hidden": true, className: "mt-0.5 size-4 shrink-0" }),
622
+ /* @__PURE__ */ jsx4("span", { className: "break-words", children: preview.attendees.join(", ") })
347
623
  ] }),
348
- preview.description && /* @__PURE__ */ jsx3("p", { className: "line-clamp-3 leading-6 text-foreground", children: preview.description })
624
+ preview.description && /* @__PURE__ */ jsx4("p", { className: "line-clamp-3 leading-6 text-foreground", children: preview.description })
349
625
  ] })
350
626
  ] });
351
627
  }
352
628
  function HubActionPreviewView({ preview, account }) {
353
629
  switch (preview.kind) {
354
630
  case "pull-request":
355
- return /* @__PURE__ */ jsx3(PullRequestPreview, { preview });
631
+ return /* @__PURE__ */ jsx4(PullRequestPreview, { preview });
356
632
  case "files":
357
- return preview.files.length > 0 ? /* @__PURE__ */ jsx3(ApprovalDiffSummary, { files: preview.files }) : null;
633
+ return preview.files.length > 0 ? /* @__PURE__ */ jsx4(ApprovalDiffSummary, { files: preview.files }) : null;
358
634
  case "commit":
359
- return /* @__PURE__ */ jsxs3(Panel, { className: "px-3 py-3", children: [
360
- /* @__PURE__ */ jsxs3("p", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
361
- /* @__PURE__ */ jsx3(GitCommitHorizontal, { "aria-hidden": true, className: "size-4 shrink-0" }),
635
+ return /* @__PURE__ */ jsxs4(Panel, { className: "px-3 py-3", children: [
636
+ /* @__PURE__ */ jsxs4("p", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
637
+ /* @__PURE__ */ jsx4(GitCommitHorizontal, { "aria-hidden": true, className: "size-4 shrink-0" }),
362
638
  preview.repository ?? "Commit"
363
639
  ] }),
364
- preview.message && /* @__PURE__ */ jsx3("p", { className: "mt-2 whitespace-pre-line text-sm leading-6 text-foreground", children: preview.message }),
365
- /* @__PURE__ */ jsx3("div", { className: "mt-2", children: /* @__PURE__ */ jsx3(HubFieldList, { fields: [
640
+ preview.message && /* @__PURE__ */ jsx4("p", { className: "mt-2 whitespace-pre-line text-sm leading-6 text-foreground", children: preview.message }),
641
+ /* @__PURE__ */ jsx4("div", { className: "mt-2", children: /* @__PURE__ */ jsx4(HubFieldList, { fields: [
366
642
  ...preview.tree ? [{ label: "Tree", value: preview.tree.slice(0, 7), mono: true }] : [],
367
643
  ...preview.parents.map((parent) => ({ label: "Parent", value: parent.slice(0, 7), mono: true }))
368
644
  ] }) })
369
645
  ] });
370
646
  case "branch":
371
- return /* @__PURE__ */ jsxs3(Panel, { className: "flex flex-wrap items-center gap-2 px-3 py-3 text-sm", children: [
372
- /* @__PURE__ */ jsx3(GitBranch, { "aria-hidden": true, className: "size-4 shrink-0 text-muted-foreground" }),
373
- preview.branch && /* @__PURE__ */ jsx3(Chip, { mono: true, children: preview.branch }),
374
- preview.sha && /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
647
+ return /* @__PURE__ */ jsxs4(Panel, { className: "flex flex-wrap items-center gap-2 px-3 py-3 text-sm", children: [
648
+ /* @__PURE__ */ jsx4(GitBranch, { "aria-hidden": true, className: "size-4 shrink-0 text-muted-foreground" }),
649
+ preview.branch && /* @__PURE__ */ jsx4(Chip, { mono: true, children: preview.branch }),
650
+ preview.sha && /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
375
651
  "at ",
376
- /* @__PURE__ */ jsx3("span", { className: "font-mono text-foreground", children: preview.sha.slice(0, 7) })
652
+ /* @__PURE__ */ jsx4("span", { className: "font-mono text-foreground", children: preview.sha.slice(0, 7) })
377
653
  ] })
378
654
  ] });
379
655
  case "issue":
380
- return /* @__PURE__ */ jsxs3(Panel, { className: "px-3 py-3", children: [
381
- preview.verdict && /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium capitalize text-foreground", children: preview.verdict }),
382
- preview.title && /* @__PURE__ */ jsx3("p", { className: "text-base font-semibold leading-6 text-foreground", children: preview.title }),
383
- preview.body && /* @__PURE__ */ jsx3("p", { className: "mt-1 line-clamp-6 whitespace-pre-line text-sm leading-6 text-foreground", children: preview.body })
656
+ return /* @__PURE__ */ jsxs4(Panel, { className: "px-3 py-3", children: [
657
+ preview.verdict && /* @__PURE__ */ jsx4("p", { className: "text-sm font-medium capitalize text-foreground", children: preview.verdict }),
658
+ preview.title && /* @__PURE__ */ jsx4("p", { className: "text-base font-semibold leading-6 text-foreground", children: preview.title }),
659
+ preview.body && /* @__PURE__ */ jsx4("p", { className: "mt-1 line-clamp-6 whitespace-pre-line text-sm leading-6 text-foreground", children: preview.body })
384
660
  ] });
385
661
  case "email":
386
- return /* @__PURE__ */ jsx3(EmailPreview, { preview, account });
662
+ return /* @__PURE__ */ jsx4(EmailPreview, { preview, account });
387
663
  case "post":
388
- return /* @__PURE__ */ jsx3(PostPreview, { preview, account });
664
+ return preview.channel === "slack" ? /* @__PURE__ */ jsx4(SlackPreview, { preview, account }) : /* @__PURE__ */ jsx4(HubMediaPreview, { preview, account });
389
665
  case "ad":
390
- return /* @__PURE__ */ jsxs3(Panel, { className: "overflow-hidden", children: [
391
- /* @__PURE__ */ jsxs3("div", { className: "space-y-1 px-4 py-3", children: [
392
- /* @__PURE__ */ jsx3("p", { className: "text-sm font-semibold text-foreground", children: preview.advertiser ?? account ?? "Advertiser unavailable" }),
393
- /* @__PURE__ */ jsxs3("p", { className: "text-sm text-muted-foreground", children: [
666
+ return /* @__PURE__ */ jsxs4(Panel, { className: "overflow-hidden", children: [
667
+ /* @__PURE__ */ jsxs4("div", { className: "space-y-1 px-4 py-3", children: [
668
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-semibold text-foreground", children: preview.advertiser ?? account ?? "Advertiser unavailable" }),
669
+ /* @__PURE__ */ jsxs4("p", { className: "text-sm text-muted-foreground", children: [
394
670
  "Sponsored \xB7 ",
395
671
  preview.placement
396
672
  ] }),
397
- preview.text && /* @__PURE__ */ jsx3("p", { className: "whitespace-pre-wrap break-words text-sm leading-6 text-foreground", children: preview.text })
673
+ preview.text && /* @__PURE__ */ jsx4("p", { className: "whitespace-pre-wrap break-words text-sm leading-6 text-foreground", children: preview.text })
398
674
  ] }),
399
- preview.image && (embeddedPreviewImage(preview.image) ? /* @__PURE__ */ jsx3("img", { src: preview.image, alt: preview.headline ?? "Ad creative", className: "aspect-[1.91/1] w-full object-cover" }) : /* @__PURE__ */ jsx3("p", { className: "bg-muted p-4 text-sm text-muted-foreground", children: "Creative image not embedded in this preview" })),
400
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-3 bg-muted/40 px-4 py-3", children: [
401
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
402
- preview.destination && /* @__PURE__ */ jsx3("p", { className: "truncate text-sm text-muted-foreground", children: preview.destination }),
403
- preview.headline && /* @__PURE__ */ jsx3("p", { className: "break-words font-semibold text-foreground", children: preview.headline })
675
+ preview.image && (previewMediaSource(preview.image, "image") ? /* @__PURE__ */ jsx4("img", { src: preview.image, alt: preview.headline ?? "Ad creative", className: "aspect-[1.91/1] w-full object-cover" }) : /* @__PURE__ */ jsx4("p", { className: "bg-muted p-4 text-sm text-muted-foreground", children: "Creative image not embedded in this preview" })),
676
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-3 bg-muted/40 px-4 py-3", children: [
677
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0 flex-1", children: [
678
+ preview.destination && /* @__PURE__ */ jsx4("p", { className: "truncate text-sm text-muted-foreground", children: preview.destination }),
679
+ preview.headline && /* @__PURE__ */ jsx4("p", { className: "break-words font-semibold text-foreground", children: preview.headline })
404
680
  ] }),
405
- preview.callToAction && /* @__PURE__ */ jsx3("span", { className: "rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground", children: preview.callToAction })
681
+ preview.callToAction && /* @__PURE__ */ jsx4("span", { className: "rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground", children: preview.callToAction })
406
682
  ] })
407
683
  ] });
408
684
  case "page":
409
- return /* @__PURE__ */ jsxs3(Panel, { className: "overflow-hidden", children: [
410
- /* @__PURE__ */ jsxs3("div", { className: "border-b border-border px-4 py-2", children: [
411
- /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium text-foreground", children: preview.title ?? "Page preview" }),
412
- preview.url && /* @__PURE__ */ jsx3("p", { className: "truncate text-sm text-muted-foreground", children: preview.url })
685
+ return /* @__PURE__ */ jsxs4(Panel, { className: "overflow-hidden", children: [
686
+ /* @__PURE__ */ jsxs4("div", { className: "border-b border-border px-4 py-2", children: [
687
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-medium text-foreground", children: preview.title ?? "Page preview" }),
688
+ preview.url && /* @__PURE__ */ jsx4("p", { className: "truncate text-sm text-muted-foreground", children: preview.url })
413
689
  ] }),
414
- embeddedPreviewImage(preview.screenshot) ? /* @__PURE__ */ jsx3("img", { src: preview.screenshot, alt: preview.title ?? "Page screenshot", className: "h-auto w-full" }) : /* @__PURE__ */ jsx3("p", { className: "p-4 text-sm text-muted-foreground", children: "A captured screenshot is needed to preview this page." })
690
+ previewMediaSource(preview.screenshot, "image") ? /* @__PURE__ */ jsx4("img", { src: preview.screenshot, alt: preview.title ?? "Page screenshot", className: "h-auto w-full" }) : /* @__PURE__ */ jsx4("p", { className: "p-4 text-sm text-muted-foreground", children: "A captured screenshot is needed to preview this page." })
415
691
  ] });
416
692
  case "payment":
417
- return /* @__PURE__ */ jsx3(PaymentPreview, { preview });
693
+ return /* @__PURE__ */ jsx4(PaymentPreview, { preview });
418
694
  case "speech":
419
- return /* @__PURE__ */ jsx3(SpeechPreview, { preview });
695
+ return /* @__PURE__ */ jsx4(SpeechPreview, { preview });
420
696
  case "call":
421
- return /* @__PURE__ */ jsx3(CallPreview, { preview });
697
+ return /* @__PURE__ */ jsx4(CallPreview, { preview });
422
698
  case "event":
423
- return /* @__PURE__ */ jsx3(EventPreview, { preview });
699
+ return /* @__PURE__ */ jsx4(EventPreview, { preview });
424
700
  case "fields":
425
- return preview.fields.length > 0 ? /* @__PURE__ */ jsx3(Panel, { className: "px-3 py-3", children: /* @__PURE__ */ jsx3(HubFieldList, { fields: preview.fields }) }) : null;
701
+ return preview.fields.length > 0 ? /* @__PURE__ */ jsx4(Panel, { className: "px-3 py-3", children: /* @__PURE__ */ jsx4(HubFieldList, { fields: preview.fields }) }) : null;
426
702
  }
427
703
  }
428
704
 
429
- // src/hub-approvals-react/feedback.tsx
430
- import { useEffect as useEffect2, useId, useState as useState3 } from "react";
431
- import { Button as Button2, Input, Label, Textarea } from "@tangle-network/ui/primitives";
432
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
433
- function HubPreviewFeedback({ item, onFeedback, drafts }) {
434
- const id = useId();
435
- const saved = item.feedback;
436
- const original = item.input && typeof item.input === "object" && !Array.isArray(item.input) ? item.input : {};
437
- const prior = saved?.editedInput && typeof saved.editedInput === "object" && !Array.isArray(saved.editedInput) ? saved.editedInput : original;
438
- const kind = presentHubAction(item).preview.kind;
439
- const field = kind === "email" ? typeof original.html === "string" ? "html" : typeof original.body === "string" ? "body" : "text" : typeof original.commentary === "string" ? "commentary" : "text";
440
- const draft = drafts?.get(item.id);
441
- const [score, setScore] = useState3(draft?.score ?? (saved ? String(saved.score) : ""));
442
- const [comment, setComment] = useState3(draft?.comment ?? saved?.comment ?? "");
443
- const [editing, setEditing] = useState3(draft?.editing ?? false);
444
- const [edited, setEdited] = useState3(draft?.edited ?? saved?.editedInput !== void 0);
445
- const [subject, setSubject] = useState3(draft?.subject ?? String(prior.subject ?? ""));
446
- const [body, setBody] = useState3(draft?.body ?? String(prior[field] ?? ""));
447
- const [payload, setPayload] = useState3(draft?.payload ?? JSON.stringify(prior, null, 2));
448
- const [busy, setBusy] = useState3(false);
449
- const [status, setStatus] = useState3((draft ? draft.saved : saved) ? "Feedback saved" : "");
450
- const [error, setError] = useState3("");
451
- useEffect2(() => {
452
- drafts?.set(item.id, { score, comment, editing, edited, subject, body, payload, saved: status === "Feedback saved" });
453
- }, [drafts, item.id, score, comment, editing, edited, subject, body, payload, status]);
454
- async function save() {
455
- if (busy) return;
456
- if (score.trim() === "" || !Number.isInteger(Number(score)) || Number(score) < 0 || Number(score) > 100) {
457
- setError("Enter a score from 0 to 100.");
458
- return;
459
- }
460
- setBusy(true);
461
- setError("");
462
- setStatus("");
463
- try {
464
- const editedInput = edited ? kind === "email" ? { ...original, subject, [field]: body } : kind === "post" ? { ...original, [field]: body } : JSON.parse(payload) : saved?.editedInput;
465
- await onFeedback(item, {
466
- score: Number(score),
467
- comment,
468
- ...editedInput !== void 0 && JSON.stringify(editedInput) !== JSON.stringify(item.input) ? { editedInput } : {}
469
- });
470
- setStatus("Feedback saved");
471
- } catch (cause) {
472
- setError(cause instanceof Error ? cause.message : "Feedback could not be saved. Your edits are kept here.");
473
- } finally {
474
- setBusy(false);
475
- }
476
- }
477
- return /* @__PURE__ */ jsxs4("form", { "aria-label": "Preview feedback", className: "space-y-3 border-t border-border pt-3", onSubmit: (event) => {
478
- event.preventDefault();
479
- void save();
480
- }, children: [
481
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-end gap-3", children: [
482
- /* @__PURE__ */ jsxs4("div", { className: "w-36 space-y-1", children: [
483
- /* @__PURE__ */ jsx4(Label, { htmlFor: `${id}-score`, children: "Score (0\u2013100)" }),
484
- /* @__PURE__ */ jsx4(
485
- Input,
486
- {
487
- id: `${id}-score`,
488
- type: "number",
489
- inputMode: "numeric",
490
- min: 0,
491
- max: 100,
492
- step: 1,
493
- required: true,
494
- value: score,
495
- placeholder: "Unscored",
496
- disabled: busy,
497
- onChange: (event) => {
498
- setScore(event.target.value);
499
- setStatus("");
500
- }
501
- }
502
- )
503
- ] }),
504
- /* @__PURE__ */ jsx4(Button2, { type: "button", variant: "outline", "aria-expanded": editing, disabled: busy, onClick: () => {
505
- setEditing((value) => !value);
506
- setStatus("");
507
- }, children: "Edit to teach" })
508
- ] }),
509
- /* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
510
- /* @__PURE__ */ jsx4(Label, { htmlFor: `${id}-comment`, children: "Comment" }),
511
- /* @__PURE__ */ jsx4(Textarea, { id: `${id}-comment`, value: comment, rows: 2, disabled: busy, onChange: (event) => {
512
- setComment(event.target.value);
513
- setStatus("");
514
- } })
515
- ] }),
516
- editing && /* @__PURE__ */ jsxs4("div", { className: "space-y-3", children: [
517
- /* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground", children: "Your edit is saved as a teaching example. Live approval applies to the original held payload." }),
518
- kind === "email" && /* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
519
- /* @__PURE__ */ jsx4(Label, { htmlFor: `${id}-subject`, children: "Subject" }),
520
- /* @__PURE__ */ jsx4(Input, { id: `${id}-subject`, value: subject, disabled: busy, onChange: (event) => {
521
- setSubject(event.target.value);
522
- setEdited(true);
523
- setStatus("");
524
- } })
525
- ] }),
526
- kind === "email" || kind === "post" ? /* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
527
- /* @__PURE__ */ jsx4(Label, { htmlFor: `${id}-body`, children: kind === "email" ? "Body" : "Post text" }),
528
- /* @__PURE__ */ jsx4(Textarea, { id: `${id}-body`, value: body, rows: 6, disabled: busy, onChange: (event) => {
529
- setBody(event.target.value);
530
- setEdited(true);
531
- setStatus("");
532
- } })
533
- ] }) : /* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
534
- /* @__PURE__ */ jsx4(Label, { htmlFor: `${id}-payload`, children: "Payload" }),
535
- /* @__PURE__ */ jsx4(Textarea, { id: `${id}-payload`, value: payload, rows: 6, disabled: busy, onChange: (event) => {
536
- setPayload(event.target.value);
537
- setEdited(true);
538
- setStatus("");
539
- } })
540
- ] })
541
- ] }),
542
- error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "text-sm text-[var(--surface-danger-text)]", children: error }),
543
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-3", children: [
544
- /* @__PURE__ */ jsx4(Button2, { type: "submit", variant: "outline", disabled: busy, children: busy ? "Saving feedback\u2026" : "Save feedback" }),
545
- /* @__PURE__ */ jsx4("p", { role: "status", className: "text-sm text-muted-foreground", children: status })
546
- ] })
547
- ] });
548
- }
549
-
550
705
  // src/hub-approvals-react/dock.tsx
551
- import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
706
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
552
707
  var DONE_VISIBLE_MS = 6e3;
553
708
  function useNow(intervalMs) {
554
709
  const [now, setNow] = useState4(() => Date.now());
@@ -593,7 +748,7 @@ function Progress({ item }) {
593
748
  }
594
749
  function HubApprovalDock({ items, onDecide, permissions, onOpen, focusId, onFeedback, className = "" }) {
595
750
  const now = useNow(3e4);
596
- const watched = useRef(/* @__PURE__ */ new Map());
751
+ const watched = useRef2(/* @__PURE__ */ new Map());
597
752
  const [settled, setSettled] = useState4({});
598
753
  const [dismissed, setDismissed] = useState4(/* @__PURE__ */ new Set());
599
754
  const [submitting, setSubmitting] = useState4(null);
@@ -602,7 +757,7 @@ function HubApprovalDock({ items, onDecide, permissions, onOpen, focusId, onFeed
602
757
  const [collapsed, setCollapsed] = useState4(false);
603
758
  const [permissionsOpen, setPermissionsOpen] = useState4(false);
604
759
  const [scope, setScope] = useState4(null);
605
- const feedbackDrafts = useRef(/* @__PURE__ */ new Map());
760
+ const feedbackDrafts = useRef2(/* @__PURE__ */ new Map());
606
761
  const [feedbackSaving, setFeedbackSaving] = useState4(false);
607
762
  useEffect3(() => {
608
763
  const finishedNow = {};
@@ -664,7 +819,7 @@ function HubApprovalDock({ items, onDecide, permissions, onOpen, focusId, onFeed
664
819
  setSubmitting(null);
665
820
  }
666
821
  }
667
- const card = /* @__PURE__ */ jsxs5(Fragment, { children: [
822
+ const card = /* @__PURE__ */ jsxs5(Fragment2, { children: [
668
823
  /* @__PURE__ */ jsxs5("div", { className: "flex items-start gap-3 px-4 pt-3", children: [
669
824
  /* @__PURE__ */ jsx5(HubProviderMark, { providerId: presentation.provider.id, name: presentation.provider.name, size: 28 }),
670
825
  /* @__PURE__ */ jsxs5("div", { className: "min-w-0 flex-1", children: [
@@ -721,7 +876,7 @@ function HubApprovalDock({ items, onDecide, permissions, onOpen, focusId, onFeed
721
876
  className: "gap-1.5",
722
877
  children: scopes.map((option) => /* @__PURE__ */ jsxs5("div", { className: "flex min-h-8 items-center gap-2", children: [
723
878
  /* @__PURE__ */ jsx5(RadioGroupItem, { id: `hub-scope-${active.id}-${option.id}`, value: option.id }),
724
- /* @__PURE__ */ jsx5(Label2, { htmlFor: `hub-scope-${active.id}-${option.id}`, className: "cursor-pointer text-sm font-normal text-foreground", children: option.label })
879
+ /* @__PURE__ */ jsx5(Label, { htmlFor: `hub-scope-${active.id}-${option.id}`, className: "cursor-pointer text-sm font-normal text-foreground", children: option.label })
725
880
  ] }, option.id))
726
881
  }
727
882
  ),
@@ -732,7 +887,7 @@ function HubApprovalDock({ items, onDecide, permissions, onOpen, focusId, onFeed
732
887
  ] })
733
888
  ] }),
734
889
  /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2", children: [
735
- decidable && /* @__PURE__ */ jsxs5(Fragment, { children: [
890
+ decidable && /* @__PURE__ */ jsxs5(Fragment2, { children: [
736
891
  /* @__PURE__ */ jsx5(Button3, { disabled: feedbackSaving, onClick: () => void decide({ kind: "approve" }, "Approving\u2026"), children: active.executionMode === "dry-run" ? "Approve live" : "Approve" }),
737
892
  /* @__PURE__ */ jsx5(Button3, { disabled: feedbackSaving, variant: "outline", onClick: () => void decide({ kind: "deny" }, "Denying\u2026"), children: "Deny" }),
738
893
  scopes.length > 0 && /* @__PURE__ */ jsx5(Button3, { variant: "ghost", "aria-expanded": permissionsOpen, onClick: () => setPermissionsOpen((value) => !value), children: permissionsOpen ? "Fewer options" : "Allow future calls\u2026" })
@@ -784,7 +939,7 @@ function HubApprovalDock({ items, onDecide, permissions, onOpen, focusId, onFeed
784
939
 
785
940
  // src/hub-approvals-react/list.tsx
786
941
  import { useEffect as useEffect4, useState as useState5 } from "react";
787
- import { ChevronRight as ChevronRight2, ShieldCheck } from "lucide-react";
942
+ import { ChevronRight as ChevronRight3, ShieldCheck } from "lucide-react";
788
943
  import { Button as Button4 } from "@tangle-network/ui/primitives";
789
944
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
790
945
  var GROUPS = [
@@ -845,7 +1000,7 @@ function HubApprovalsList({ items, onSelect, selectedId, className = "" }) {
845
1000
  ] }),
846
1001
  /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1", children: [
847
1002
  /* @__PURE__ */ jsx6(HubApprovalPhasePill, { phase: item.phase, label: openPhaseLabel(item, "Owner") }),
848
- /* @__PURE__ */ jsx6(ChevronRight2, { "aria-hidden": true, className: "size-4 text-muted-foreground" })
1003
+ /* @__PURE__ */ jsx6(ChevronRight3, { "aria-hidden": true, className: "size-4 text-muted-foreground" })
849
1004
  ] })
850
1005
  ]
851
1006
  }
@@ -856,7 +1011,7 @@ function HubApprovalsList({ items, onSelect, selectedId, className = "" }) {
856
1011
  }
857
1012
 
858
1013
  // src/hub-approvals-react/row.tsx
859
- import { useEffect as useEffect5, useRef as useRef2, useState as useState7 } from "react";
1014
+ import { useEffect as useEffect5, useRef as useRef3, useState as useState7 } from "react";
860
1015
  import { ChevronDown as ChevronDown2 } from "lucide-react";
861
1016
  import { Button as Button5 } from "@tangle-network/ui/primitives";
862
1017
 
@@ -926,12 +1081,12 @@ function HubApprovalReceipts({ items, message, at }) {
926
1081
  }
927
1082
 
928
1083
  // src/hub-approvals-react/row.tsx
929
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1084
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
930
1085
  function HubApprovalRow({ item, expanded: controlled, onExpandedChange, onReview, actions, onFeedback }) {
931
1086
  const [own, setOwn] = useState7(false);
932
1087
  const expanded = controlled ?? own;
933
- const ref = useRef2(null);
934
- const feedbackDrafts = useRef2(/* @__PURE__ */ new Map());
1088
+ const ref = useRef3(null);
1089
+ const feedbackDrafts = useRef3(/* @__PURE__ */ new Map());
935
1090
  const [feedbackSaving, setFeedbackSaving] = useState7(false);
936
1091
  const presentation = presentHubAction(item);
937
1092
  const title = item.phase === "done" ? hubActionReceipt(item).title : presentation.title;
@@ -965,7 +1120,7 @@ function HubApprovalRow({ item, expanded: controlled, onExpandedChange, onReview
965
1120
  ] }),
966
1121
  !expanded && item.phase === "unknown" && /* @__PURE__ */ jsx8("p", { className: "px-3 pb-3 text-sm text-[var(--surface-warning-text)]", children: HUB_APPROVAL_UNKNOWN_WARNING }),
967
1122
  expanded && /* @__PURE__ */ jsxs8("div", { className: "space-y-3 border-t border-border px-3 pb-3 pt-3", children: [
968
- item.phase === "done" || item.phase === "failed" || item.phase === "unknown" ? /* @__PURE__ */ jsx8(HubActionReceiptCard, { item, className: "border-0 px-0 py-0 shadow-none" }) : /* @__PURE__ */ jsxs8(Fragment2, { children: [
1123
+ item.phase === "done" || item.phase === "failed" || item.phase === "unknown" ? /* @__PURE__ */ jsx8(HubActionReceiptCard, { item, className: "border-0 px-0 py-0 shadow-none" }) : /* @__PURE__ */ jsxs8(Fragment3, { children: [
969
1124
  /* @__PURE__ */ jsx8(HubActionPreviewView, { preview: presentation.preview, account: item.account }),
970
1125
  /* @__PURE__ */ jsx8(HubRawDetails, { sections: [{ label: "Call", value: { action: item.actionPath, input: item.input } }] })
971
1126
  ] }),
@@ -993,6 +1148,7 @@ export {
993
1148
  HubApprovalsList,
994
1149
  HubPreviewFeedback,
995
1150
  HubProviderMark,
1151
+ ReviewFeedbackForm,
996
1152
  openPhaseLabel
997
1153
  };
998
1154
  //# sourceMappingURL=index.js.map