@tangle-network/agent-app 0.45.47 → 0.45.48

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 (78) hide show
  1. package/dist/{DesignCanvas-P2ZVK6FM.js → DesignCanvas-QY2CA5GI.js} +2 -2
  2. package/dist/{DesignCanvasEditor-DGNCA54P.js → DesignCanvasEditor-CJ7PLX7A.js} +3 -3
  3. package/dist/{IntakeInterview-3ZIQMZS6.js → IntakeInterview-NJXKH35Q.js} +2 -2
  4. package/dist/InvitationsPanel-F2VY4TSL.js +9 -0
  5. package/dist/InviteAcceptPage-UT4452KT.js +7 -0
  6. package/dist/MembersPanel-N5CBOUXC.js +9 -0
  7. package/dist/{TimelineEditor-OTNPJ3SN.js → TimelineEditor-IYNKBSUX.js} +2 -2
  8. package/dist/assistant/index.d.ts +35 -10
  9. package/dist/assistant/index.js +234 -89
  10. package/dist/assistant/index.js.map +1 -1
  11. package/dist/chat-react/index.js +2 -1
  12. package/dist/chat-react/index.js.map +1 -1
  13. package/dist/{chunk-IUSO2XRE.js → chunk-5BACNOVR.js} +13 -14
  14. package/dist/chunk-5BACNOVR.js.map +1 -0
  15. package/dist/chunk-AULM4X7U.js +77 -0
  16. package/dist/chunk-AULM4X7U.js.map +1 -0
  17. package/dist/{chunk-ZX5UT4HF.js → chunk-C7AQW6US.js} +321 -240
  18. package/dist/chunk-C7AQW6US.js.map +1 -0
  19. package/dist/{chunk-VCPZ3HTN.js → chunk-DB2D2JBQ.js} +51 -27
  20. package/dist/chunk-DB2D2JBQ.js.map +1 -0
  21. package/dist/{chunk-TL37E5YY.js → chunk-DS2WE62K.js} +3 -3
  22. package/dist/{chunk-TL37E5YY.js.map → chunk-DS2WE62K.js.map} +1 -1
  23. package/dist/{chunk-PE67O2LH.js → chunk-GT4GTRGQ.js} +18 -13
  24. package/dist/chunk-GT4GTRGQ.js.map +1 -0
  25. package/dist/{chunk-BT4QFCTB.js → chunk-HSBJB46C.js} +13 -1
  26. package/dist/chunk-HSBJB46C.js.map +1 -0
  27. package/dist/{chunk-54FYYXAX.js → chunk-J6OJTFNE.js} +13 -10
  28. package/dist/chunk-J6OJTFNE.js.map +1 -0
  29. package/dist/chunk-MLG6XKPV.js +44 -0
  30. package/dist/chunk-MLG6XKPV.js.map +1 -0
  31. package/dist/{chunk-F4XLTVQ3.js → chunk-R6KGLGEJ.js} +18 -17
  32. package/dist/chunk-R6KGLGEJ.js.map +1 -0
  33. package/dist/{chunk-B62EZF52.js → chunk-RILGAFEL.js} +3 -3
  34. package/dist/{chunk-65OZT566.js → chunk-T7XPIBCX.js} +16 -14
  35. package/dist/chunk-T7XPIBCX.js.map +1 -0
  36. package/dist/{chunk-VOJB7MVG.js → chunk-XPFNEKHS.js} +70 -28
  37. package/dist/chunk-XPFNEKHS.js.map +1 -0
  38. package/dist/{chunk-GNPN6ED4.js → chunk-XVRHISF3.js} +127 -165
  39. package/dist/chunk-XVRHISF3.js.map +1 -0
  40. package/dist/design-canvas-react/index.js +14 -12
  41. package/dist/design-canvas-react/index.js.map +1 -1
  42. package/dist/design-canvas-react/lazy.js +1 -1
  43. package/dist/intakes-react/index.js +1 -1
  44. package/dist/intakes-react/lazy.js +1 -1
  45. package/dist/sequences-react/index.js +2 -2
  46. package/dist/studio/index.d.ts +13 -1
  47. package/dist/studio/index.js +13 -1
  48. package/dist/studio-react/index.js +100 -63
  49. package/dist/studio-react/index.js.map +1 -1
  50. package/dist/studio-react/studio.css +0 -56
  51. package/dist/teams-react/index.js +4 -3
  52. package/dist/teams-react/lazy.js +3 -3
  53. package/dist/web-react/index.d.ts +15 -11
  54. package/dist/web-react/index.js +6 -4
  55. package/dist/work-product-react/index.js +3 -21
  56. package/dist/work-product-react/index.js.map +1 -1
  57. package/package.json +3 -3
  58. package/dist/InvitationsPanel-F56UOQXA.js +0 -8
  59. package/dist/InviteAcceptPage-P3QJC3C6.js +0 -7
  60. package/dist/MembersPanel-XNLF3SA4.js +0 -8
  61. package/dist/chunk-54FYYXAX.js.map +0 -1
  62. package/dist/chunk-65OZT566.js.map +0 -1
  63. package/dist/chunk-BT4QFCTB.js.map +0 -1
  64. package/dist/chunk-F4XLTVQ3.js.map +0 -1
  65. package/dist/chunk-GNPN6ED4.js.map +0 -1
  66. package/dist/chunk-IUSO2XRE.js.map +0 -1
  67. package/dist/chunk-PE67O2LH.js.map +0 -1
  68. package/dist/chunk-VCPZ3HTN.js.map +0 -1
  69. package/dist/chunk-VOJB7MVG.js.map +0 -1
  70. package/dist/chunk-ZX5UT4HF.js.map +0 -1
  71. /package/dist/{DesignCanvas-P2ZVK6FM.js.map → DesignCanvas-QY2CA5GI.js.map} +0 -0
  72. /package/dist/{DesignCanvasEditor-DGNCA54P.js.map → DesignCanvasEditor-CJ7PLX7A.js.map} +0 -0
  73. /package/dist/{IntakeInterview-3ZIQMZS6.js.map → IntakeInterview-NJXKH35Q.js.map} +0 -0
  74. /package/dist/{InvitationsPanel-F56UOQXA.js.map → InvitationsPanel-F2VY4TSL.js.map} +0 -0
  75. /package/dist/{InviteAcceptPage-P3QJC3C6.js.map → InviteAcceptPage-UT4452KT.js.map} +0 -0
  76. /package/dist/{MembersPanel-XNLF3SA4.js.map → MembersPanel-N5CBOUXC.js.map} +0 -0
  77. /package/dist/{TimelineEditor-OTNPJ3SN.js.map → TimelineEditor-IYNKBSUX.js.map} +0 -0
  78. /package/dist/{chunk-B62EZF52.js.map → chunk-RILGAFEL.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  WorkProductCard,
6
6
  workProductPartsFromMessageParts
7
- } from "./chunk-54FYYXAX.js";
7
+ } from "./chunk-J6OJTFNE.js";
8
8
  import {
9
9
  ChevronDown,
10
10
  OVERLAY_SHADOW,
@@ -12,7 +12,7 @@ import {
12
12
  PopoverSurface,
13
13
  usePending,
14
14
  usePopover
15
- } from "./chunk-GNPN6ED4.js";
15
+ } from "./chunk-XVRHISF3.js";
16
16
  import {
17
17
  UNTITLED_SESSION_LABEL,
18
18
  mergeSessionPages,
@@ -21,9 +21,6 @@ import {
21
21
  import {
22
22
  attachmentPartsFromMessageParts
23
23
  } from "./chunk-5ZTFZBS6.js";
24
- import {
25
- formatBytes
26
- } from "./chunk-KWXUBMXU.js";
27
24
  import {
28
25
  cancelStatusFor,
29
26
  fieldAcceptsFreeText,
@@ -40,7 +37,7 @@ import {
40
37
  } from "./chunk-YJMCRXQQ.js";
41
38
 
42
39
  // src/web-react/index.tsx
43
- import { useEffect as useEffect11, useMemo as useMemo7, useRef as useRef10, useState as useState14, memo } from "react";
40
+ import { useEffect as useEffect11, useMemo as useMemo7, useRef as useRef11, useState as useState14, memo } from "react";
44
41
  import { InlineToolItem } from "@tangle-network/ui/run";
45
42
 
46
43
  // src/web-react/smooth-text.ts
@@ -102,7 +99,7 @@ function BrandMark({ size = 24, className }) {
102
99
  }
103
100
 
104
101
  // src/web-react/durable-plan-card.tsx
105
- import { useEffect as useEffect3, useState as useState3 } from "react";
102
+ import { useEffect as useEffect3, useLayoutEffect, useRef as useRef3, useState as useState3 } from "react";
106
103
 
107
104
  // src/web-react/interaction-question-card.tsx
108
105
  import { useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
@@ -302,32 +299,43 @@ function QuestionOptionList({
302
299
  multi,
303
300
  selectedValues,
304
301
  disabled,
305
- onToggle
302
+ onToggle,
303
+ answered = false
306
304
  }) {
307
305
  return /* @__PURE__ */ jsx2(Fragment, { children: options.map((option, optionIndex) => {
308
306
  const inputId = `${idPrefix}-${optionIndex}`;
309
307
  const checked = selectedValues.includes(option.value);
310
- return /* @__PURE__ */ jsxs("label", { htmlFor: inputId, className: "flex cursor-pointer gap-2 rounded-lg border border-strong p-3 transition-colors hover:bg-accent", children: [
311
- /* @__PURE__ */ jsx2(
312
- "input",
313
- {
314
- id: inputId,
315
- type: multi ? "checkbox" : "radio",
316
- name: groupName,
317
- value: option.value,
318
- checked,
319
- disabled,
320
- onChange: () => onToggle(option.value),
321
- "aria-labelledby": `${inputId}-label`,
322
- "aria-describedby": option.description ? `${inputId}-description` : void 0,
323
- className: "mt-0.5 h-4 w-4 shrink-0 accent-primary"
324
- }
325
- ),
326
- /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
327
- /* @__PURE__ */ jsx2("span", { id: `${inputId}-label`, className: "block text-sm font-medium leading-5 text-foreground", children: option.label }),
328
- option.description && /* @__PURE__ */ jsx2("span", { id: `${inputId}-description`, className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: option.description })
329
- ] })
330
- ] }, `${option.value}-${optionIndex}`);
308
+ const highlighted = answered && checked;
309
+ return /* @__PURE__ */ jsxs(
310
+ "label",
311
+ {
312
+ htmlFor: inputId,
313
+ className: `flex gap-2 rounded-lg border p-3 transition-colors ${highlighted ? "border-primary bg-primary/5" : "border-strong"} ${disabled ? "cursor-default" : "cursor-pointer hover:bg-accent"}`,
314
+ children: [
315
+ /* @__PURE__ */ jsx2(
316
+ "input",
317
+ {
318
+ id: inputId,
319
+ type: multi ? "checkbox" : "radio",
320
+ name: groupName,
321
+ value: option.value,
322
+ checked,
323
+ disabled,
324
+ onChange: () => onToggle(option.value),
325
+ "aria-labelledby": `${inputId}-label`,
326
+ "aria-describedby": option.description ? `${inputId}-description` : void 0,
327
+ className: "mt-0.5 h-4 w-4 shrink-0 accent-primary"
328
+ }
329
+ ),
330
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
331
+ /* @__PURE__ */ jsx2("span", { id: `${inputId}-label`, className: "block text-sm font-medium leading-5 text-foreground", children: option.label }),
332
+ option.description && /* @__PURE__ */ jsx2("span", { id: `${inputId}-description`, className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: option.description })
333
+ ] }),
334
+ highlighted && /* @__PURE__ */ jsx2(CheckGlyph, { className: "mt-0.5 h-4 w-4 shrink-0 text-primary" })
335
+ ]
336
+ },
337
+ `${option.value}-${optionIndex}`
338
+ );
331
339
  }) });
332
340
  }
333
341
  function selectField(field) {
@@ -364,7 +372,6 @@ function InteractionQuestionCard({
364
372
  onResolved,
365
373
  onLateAnswer,
366
374
  kindLabel,
367
- sourceNote,
368
375
  timeoutNote,
369
376
  renderMarkdown,
370
377
  className
@@ -460,113 +467,116 @@ function InteractionQuestionCard({
460
467
  } else if (submitting) {
461
468
  submitLabel = "Submitting\u2026";
462
469
  }
463
- return /* @__PURE__ */ jsxs("div", { className: `rounded-xl border border-card-edge bg-card p-4 ${className ?? ""}`, children: [
464
- /* @__PURE__ */ jsxs("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
465
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
470
+ return (
471
+ // `dark:[color-scheme:dark]` keeps the native radios/checkboxes on the
472
+ // dark control scheme without it they paint light-scheme white on the
473
+ // dark card.
474
+ /* @__PURE__ */ jsxs("div", { className: `rounded-xl border border-card-edge bg-card p-4 dark:[color-scheme:dark] ${className ?? ""}`, children: [
475
+ /* @__PURE__ */ jsxs("div", { className: "mb-3 flex flex-wrap items-center gap-2", children: [
466
476
  /* @__PURE__ */ jsx2(InteractionBadge, { variant: "outline", children: kindLabel ?? "Question" }),
467
477
  /* @__PURE__ */ jsx2(InteractionBadge, { variant: answered ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS[status] })
468
478
  ] }),
469
- /* @__PURE__ */ jsx2("span", { className: "text-xs text-muted-foreground", children: sourceNote ?? "The agent asked for input" })
470
- ] }),
471
- interaction.title.trim() && interaction.fields.every((field) => field.label !== interaction.title) && /* @__PURE__ */ jsx2("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: interaction.title }),
472
- interaction.body && (renderMarkdown ? /* @__PURE__ */ jsx2("div", { className: "mb-3 text-sm leading-5 text-muted-foreground", children: renderMarkdown(interaction.body) }) : /* @__PURE__ */ jsx2("p", { className: "mb-3 text-sm leading-5 text-muted-foreground", children: interaction.body })),
473
- /* @__PURE__ */ jsx2("div", { className: "space-y-4", children: interaction.fields.map((field) => {
474
- const value = values[field.name] ?? {};
475
- const select = selectField(field);
476
- const freeText = freeTextField(field);
477
- return /* @__PURE__ */ jsxs("fieldset", { className: "space-y-2", children: [
478
- /* @__PURE__ */ jsx2("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
479
- select ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
480
- /* @__PURE__ */ jsx2(
481
- QuestionOptionList,
479
+ interaction.title.trim() && interaction.fields.every((field) => field.label !== interaction.title) && /* @__PURE__ */ jsx2("p", { className: "mb-3 text-[15px] font-semibold leading-snug text-foreground", children: interaction.title }),
480
+ interaction.body && (renderMarkdown ? /* @__PURE__ */ jsx2("div", { className: "mb-3 text-sm leading-5 text-muted-foreground", children: renderMarkdown(interaction.body) }) : /* @__PURE__ */ jsx2("p", { className: "mb-3 text-sm leading-5 text-muted-foreground", children: interaction.body })),
481
+ /* @__PURE__ */ jsx2("div", { className: "space-y-4", children: interaction.fields.map((field) => {
482
+ const value = values[field.name] ?? {};
483
+ const select = selectField(field);
484
+ const freeText = freeTextField(field);
485
+ return /* @__PURE__ */ jsxs("fieldset", { className: "space-y-2", children: [
486
+ /* @__PURE__ */ jsx2("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
487
+ select ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
488
+ /* @__PURE__ */ jsx2(
489
+ QuestionOptionList,
490
+ {
491
+ groupName: `${interaction.id}-${field.name}`,
492
+ idPrefix: `${interaction.id}-${field.name}`,
493
+ options: select.options,
494
+ multi: select.multi === true,
495
+ selectedValues: value.selected ?? [],
496
+ disabled,
497
+ onToggle: (optionValue) => toggleSelected(select, optionValue),
498
+ answered
499
+ }
500
+ ),
501
+ select.allowCustom === true && /* @__PURE__ */ jsx2(
502
+ "input",
503
+ {
504
+ type: "text",
505
+ value: value.custom ?? "",
506
+ disabled,
507
+ onChange: (event) => setFieldValue(field.name, { custom: event.target.value }),
508
+ placeholder: "Other \u2014 type your own answer",
509
+ "aria-label": `Custom answer for ${field.label}`,
510
+ className: FIELD_INPUT_CLASSES
511
+ }
512
+ )
513
+ ] }) : field.type === "boolean" ? /* @__PURE__ */ jsx2("div", { className: "flex gap-4", children: ["true", "false"].map((boolValue) => /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm text-foreground", children: [
514
+ /* @__PURE__ */ jsx2(
515
+ "input",
516
+ {
517
+ type: "radio",
518
+ name: `${interaction.id}-${field.name}`,
519
+ value: boolValue,
520
+ checked: (value.selected ?? [])[0] === boolValue,
521
+ disabled,
522
+ onChange: () => setFieldValue(field.name, { selected: [boolValue] }),
523
+ className: "h-4 w-4 accent-primary"
524
+ }
525
+ ),
526
+ boolValue === "true" ? "Yes" : "No"
527
+ ] }, boolValue)) }) : field.type === "number" ? /* @__PURE__ */ jsx2(
528
+ "input",
482
529
  {
483
- groupName: `${interaction.id}-${field.name}`,
484
- idPrefix: `${interaction.id}-${field.name}`,
485
- options: select.options,
486
- multi: select.multi === true,
487
- selectedValues: value.selected ?? [],
530
+ type: "number",
531
+ value: value.text ?? "",
488
532
  disabled,
489
- onToggle: (optionValue) => toggleSelected(select, optionValue)
533
+ "aria-label": field.label,
534
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
535
+ className: FIELD_INPUT_CLASSES
490
536
  }
491
- ),
492
- select.allowCustom === true && /* @__PURE__ */ jsx2(
537
+ ) : field.type === "secret" ? /* @__PURE__ */ jsx2(
493
538
  "input",
494
539
  {
495
- type: "text",
496
- value: value.custom ?? "",
540
+ type: "password",
541
+ value: value.text ?? "",
497
542
  disabled,
498
- onChange: (event) => setFieldValue(field.name, { custom: event.target.value }),
499
- placeholder: "Other \u2014 type your own answer",
500
- "aria-label": `Custom answer for ${field.label}`,
543
+ "aria-label": field.label,
544
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
545
+ placeholder: field.placeholder,
546
+ maxLength: freeText ? textFieldMaxLength(freeText) : void 0,
501
547
  className: FIELD_INPUT_CLASSES
502
548
  }
503
- )
504
- ] }) : field.type === "boolean" ? /* @__PURE__ */ jsx2("div", { className: "flex gap-4", children: ["true", "false"].map((boolValue) => /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm text-foreground", children: [
505
- /* @__PURE__ */ jsx2(
506
- "input",
549
+ ) : /* @__PURE__ */ jsx2(
550
+ "textarea",
507
551
  {
508
- type: "radio",
509
- name: `${interaction.id}-${field.name}`,
510
- value: boolValue,
511
- checked: (value.selected ?? [])[0] === boolValue,
552
+ value: value.text ?? "",
512
553
  disabled,
513
- onChange: () => setFieldValue(field.name, { selected: [boolValue] }),
514
- className: "h-4 w-4 accent-primary"
554
+ "aria-label": field.label,
555
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
556
+ rows: 3,
557
+ maxLength: freeText ? textFieldMaxLength(freeText) : void 0,
558
+ placeholder: field.type === "text" ? field.placeholder : void 0,
559
+ className: FIELD_INPUT_CLASSES
515
560
  }
516
- ),
517
- boolValue === "true" ? "Yes" : "No"
518
- ] }, boolValue)) }) : field.type === "number" ? /* @__PURE__ */ jsx2(
519
- "input",
520
- {
521
- type: "number",
522
- value: value.text ?? "",
523
- disabled,
524
- "aria-label": field.label,
525
- onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
526
- className: FIELD_INPUT_CLASSES
527
- }
528
- ) : field.type === "secret" ? /* @__PURE__ */ jsx2(
529
- "input",
530
- {
531
- type: "password",
532
- value: value.text ?? "",
533
- disabled,
534
- "aria-label": field.label,
535
- onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
536
- placeholder: field.placeholder,
537
- maxLength: freeText ? textFieldMaxLength(freeText) : void 0,
538
- className: FIELD_INPUT_CLASSES
539
- }
540
- ) : /* @__PURE__ */ jsx2(
541
- "textarea",
542
- {
543
- value: value.text ?? "",
544
- disabled,
545
- "aria-label": field.label,
546
- onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
547
- rows: 3,
548
- maxLength: freeText ? textFieldMaxLength(freeText) : void 0,
549
- placeholder: field.type === "text" ? field.placeholder : void 0,
550
- className: FIELD_INPUT_CLASSES
551
- }
552
- )
553
- ] }, field.name);
554
- }) }),
555
- error && /* @__PURE__ */ jsx2("p", { role: "alert", className: "mt-3 text-xs text-destructive", children: error }),
556
- terminalNote && /* @__PURE__ */ jsx2("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
557
- (showSubmitButton || showTimeoutNote) && /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-wrap items-center justify-end gap-2", children: [
558
- showTimeoutNote && /* @__PURE__ */ jsx2("div", { className: "mr-auto text-xs text-muted-foreground", children: timeoutNote }),
559
- showSubmitButton && /* @__PURE__ */ jsx2(InteractionActionButton, { onClick: () => void submit(), disabled: disabled || !answerData, children: submitLabel })
560
- ] }),
561
- answered && /* @__PURE__ */ jsx2("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
562
- /* @__PURE__ */ jsx2(CheckGlyph, { className: "h-3 w-3" }),
563
- "Answered"
564
- ] }) }),
565
- lateAnswerSent && /* @__PURE__ */ jsx2("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
566
- /* @__PURE__ */ jsx2(CheckGlyph, { className: "h-3 w-3" }),
567
- "Sent as new message"
568
- ] }) })
569
- ] });
561
+ )
562
+ ] }, field.name);
563
+ }) }),
564
+ error && /* @__PURE__ */ jsx2("p", { role: "alert", className: "mt-3 text-xs text-destructive", children: error }),
565
+ terminalNote && /* @__PURE__ */ jsx2("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
566
+ (showSubmitButton || showTimeoutNote) && /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-wrap items-center justify-end gap-2", children: [
567
+ showTimeoutNote && /* @__PURE__ */ jsx2("div", { className: "mr-auto text-xs text-muted-foreground", children: timeoutNote }),
568
+ showSubmitButton && /* @__PURE__ */ jsx2(InteractionActionButton, { onClick: () => void submit(), disabled: disabled || !answerData, children: submitLabel })
569
+ ] }),
570
+ answered && /* @__PURE__ */ jsx2("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
571
+ /* @__PURE__ */ jsx2(CheckGlyph, { className: "h-3 w-3" }),
572
+ "Answered"
573
+ ] }) }),
574
+ lateAnswerSent && /* @__PURE__ */ jsx2("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
575
+ /* @__PURE__ */ jsx2(CheckGlyph, { className: "h-3 w-3" }),
576
+ "Sent as new message"
577
+ ] }) })
578
+ ] })
579
+ );
570
580
  }
571
581
 
572
582
  // src/web-react/durable-plan-card.tsx
@@ -587,6 +597,7 @@ function statusLabel(plan) {
587
597
  return "Preparing";
588
598
  }
589
599
  }
600
+ var COLLAPSED_MAX_HEIGHT = 320;
590
601
  function DurablePlanCard({
591
602
  plan,
592
603
  canWrite,
@@ -602,6 +613,12 @@ function DurablePlanCard({
602
613
  useEffect3(() => setLocalError(null), [plan.planId, plan.revision, plan.status]);
603
614
  const actionable = plan.status === "pending";
604
615
  const disabled = !canWrite || !actionable || deciding !== null;
616
+ const bodyRef = useRef3(null);
617
+ const [overflows, setOverflows] = useState3(false);
618
+ useLayoutEffect(() => {
619
+ const el = bodyRef.current;
620
+ if (el) setOverflows(el.scrollHeight > COLLAPSED_MAX_HEIGHT);
621
+ }, [plan.body, renderMarkdown]);
605
622
  async function submit(decision) {
606
623
  const trimmed = feedback.trim();
607
624
  if (decision === "rejected" && !trimmed) {
@@ -622,16 +639,24 @@ function DurablePlanCard({
622
639
  plan.revision
623
640
  ] })
624
641
  ] }),
625
- plan.title && /* @__PURE__ */ jsx3("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: plan.title }),
642
+ plan.title && /* @__PURE__ */ jsx3("p", { className: "mb-3 text-[15px] font-semibold leading-snug text-foreground", children: plan.title }),
626
643
  /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
627
- /* @__PURE__ */ jsx3("div", { className: "overflow-hidden text-sm", style: expanded ? void 0 : { maxHeight: 320 }, children: renderMarkdown ? renderMarkdown(plan.body) : /* @__PURE__ */ jsx3("p", { className: "whitespace-pre-wrap leading-5", children: plan.body }) }),
628
- !expanded && /* @__PURE__ */ jsx3("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-card to-transparent" }),
629
644
  /* @__PURE__ */ jsx3(
645
+ "div",
646
+ {
647
+ ref: bodyRef,
648
+ className: "overflow-hidden text-sm",
649
+ style: expanded || !overflows ? void 0 : { maxHeight: COLLAPSED_MAX_HEIGHT },
650
+ children: renderMarkdown ? renderMarkdown(plan.body) : /* @__PURE__ */ jsx3("p", { className: "whitespace-pre-wrap leading-5", children: plan.body })
651
+ }
652
+ ),
653
+ overflows && !expanded && /* @__PURE__ */ jsx3("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-card to-transparent" }),
654
+ overflows && /* @__PURE__ */ jsx3(
630
655
  "button",
631
656
  {
632
657
  type: "button",
633
658
  onClick: () => setExpanded((value) => !value),
634
- className: "mt-1 text-xs text-muted-foreground hover:text-foreground",
659
+ className: "relative z-10 mt-1 text-xs text-muted-foreground hover:text-foreground",
635
660
  children: expanded ? "Collapse plan" : "Show full plan"
636
661
  }
637
662
  )
@@ -660,7 +685,7 @@ function DurablePlanCard({
660
685
  }
661
686
 
662
687
  // src/web-react/interaction-plan-card.tsx
663
- import { useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
688
+ import { useLayoutEffect as useLayoutEffect2, useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
664
689
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
665
690
  function CheckGlyph2({ className }) {
666
691
  return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M20 6 9 17l-5-5" }) });
@@ -677,7 +702,25 @@ var TERMINAL_NOTES2 = interactionTerminalNotes("plan", {
677
702
  declined: "The agent was asked to revise the plan."
678
703
  });
679
704
  var DEFAULT_RE_REQUEST_LABEL = "Ask agent to re-submit the plan";
680
- var COLLAPSED_MAX_HEIGHT = 320;
705
+ var COLLAPSED_MAX_HEIGHT2 = 320;
706
+ function submittedFieldText(field, values) {
707
+ const answer = fieldAnswer(field, values);
708
+ if (answer === null) return null;
709
+ if (Array.isArray(answer)) {
710
+ const options = field.type === "select" ? field.options : void 0;
711
+ return answer.map((value) => options?.find((option) => option.value === value)?.label ?? value).join(", ");
712
+ }
713
+ return String(answer);
714
+ }
715
+ function useBodyOverflows(body, renderMarkdown) {
716
+ const bodyRef = useRef4(null);
717
+ const [overflows, setOverflows] = useState4(false);
718
+ useLayoutEffect2(() => {
719
+ const el = bodyRef.current;
720
+ if (el) setOverflows(el.scrollHeight > COLLAPSED_MAX_HEIGHT2);
721
+ }, [body, renderMarkdown]);
722
+ return { bodyRef, overflows };
723
+ }
681
724
  function InteractionPlanCard({
682
725
  interaction,
683
726
  canWrite,
@@ -694,7 +737,8 @@ function InteractionPlanCard({
694
737
  const [localStatus, setLocalStatus] = useState4(null);
695
738
  const [reRequested, setReRequested] = useState4(false);
696
739
  const [error, setError] = useState4(null);
697
- const submitInFlightRef = useRef3(false);
740
+ const submitInFlightRef = useRef4(false);
741
+ const { bodyRef, overflows } = useBodyOverflows(interaction.body, renderMarkdown);
698
742
  const status = isTerminalInteractionStatus(interaction.status) ? interaction.status : localStatus ?? interaction.status;
699
743
  const reRequestable = isLateAnswerableStatus(status) && onReRequest !== void 0;
700
744
  const canReRequest = canWrite && reRequestable && !reRequested;
@@ -755,31 +799,30 @@ function InteractionPlanCard({
755
799
  }
756
800
  const terminalNote = TERMINAL_NOTES2[status];
757
801
  const approved = status === "answered";
802
+ const submittedValues = interaction.answers ? fieldValuesFromAnswers(interaction.fields, interaction.answers) : values;
758
803
  return /* @__PURE__ */ jsxs3("div", { className: `rounded-xl border border-card-edge bg-card p-4 ${className ?? ""}`, children: [
759
- /* @__PURE__ */ jsxs3("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
760
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-2", children: [
761
- /* @__PURE__ */ jsx4(InteractionBadge, { variant: "outline", children: "Plan" }),
762
- /* @__PURE__ */ jsx4(InteractionBadge, { variant: approved ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS2[status] })
763
- ] }),
764
- /* @__PURE__ */ jsx4("span", { className: "text-xs text-muted-foreground", children: "The agent proposed a plan" })
804
+ /* @__PURE__ */ jsxs3("div", { className: "mb-3 flex flex-wrap items-center gap-2", children: [
805
+ /* @__PURE__ */ jsx4(InteractionBadge, { variant: "outline", children: "Plan" }),
806
+ /* @__PURE__ */ jsx4(InteractionBadge, { variant: approved ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS2[status] })
765
807
  ] }),
766
- interaction.title.trim() && /* @__PURE__ */ jsx4("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: interaction.title }),
808
+ interaction.title.trim() && /* @__PURE__ */ jsx4("p", { className: "mb-3 text-[15px] font-semibold leading-snug text-foreground", children: interaction.title }),
767
809
  interaction.body && /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
768
810
  /* @__PURE__ */ jsx4(
769
811
  "div",
770
812
  {
813
+ ref: bodyRef,
771
814
  className: "overflow-hidden text-sm text-foreground",
772
- style: expanded ? void 0 : { maxHeight: COLLAPSED_MAX_HEIGHT },
815
+ style: expanded || !overflows ? void 0 : { maxHeight: COLLAPSED_MAX_HEIGHT2 },
773
816
  children: renderMarkdown ? renderMarkdown(interaction.body) : /* @__PURE__ */ jsx4("p", { className: "whitespace-pre-wrap leading-5", children: interaction.body })
774
817
  }
775
818
  ),
776
- !expanded && /* @__PURE__ */ jsx4("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-card to-transparent" }),
777
- /* @__PURE__ */ jsxs3(
819
+ overflows && !expanded && /* @__PURE__ */ jsx4("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-card to-transparent" }),
820
+ overflows && /* @__PURE__ */ jsxs3(
778
821
  "button",
779
822
  {
780
823
  type: "button",
781
824
  onClick: () => setExpanded((prev) => !prev),
782
- className: "mt-1 inline-flex items-center gap-1 text-xs text-muted-foreground transition hover:text-foreground",
825
+ className: "relative z-10 mt-1 inline-flex items-center gap-1 text-xs text-muted-foreground transition hover:text-foreground",
783
826
  children: [
784
827
  /* @__PURE__ */ jsx4(ChevronDownGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
785
828
  expanded ? "Collapse plan" : "Show full plan"
@@ -787,7 +830,7 @@ function InteractionPlanCard({
787
830
  }
788
831
  )
789
832
  ] }),
790
- interaction.fields.length > 0 && /* @__PURE__ */ jsx4("div", { className: "mt-3 space-y-4", children: interaction.fields.map((field) => /* @__PURE__ */ jsxs3("fieldset", { className: "space-y-2", children: [
833
+ interaction.fields.length > 0 && status === "pending" && /* @__PURE__ */ jsx4("div", { className: "mt-3 space-y-4", children: interaction.fields.map((field) => /* @__PURE__ */ jsxs3("fieldset", { className: "space-y-2", children: [
791
834
  /* @__PURE__ */ jsx4("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
792
835
  fieldAcceptsFreeText(field) ? /* @__PURE__ */ jsx4(
793
836
  "textarea",
@@ -812,6 +855,14 @@ function InteractionPlanCard({
812
855
  }
813
856
  )
814
857
  ] }, field.name)) }),
858
+ interaction.fields.length > 0 && status !== "pending" && /* @__PURE__ */ jsx4("div", { className: "mt-3 space-y-2", children: interaction.fields.map((field) => {
859
+ const text = submittedFieldText(field, submittedValues);
860
+ if (!text) return null;
861
+ return /* @__PURE__ */ jsxs3("div", { children: [
862
+ /* @__PURE__ */ jsx4("p", { className: "text-xs font-medium text-muted-foreground", children: field.label }),
863
+ /* @__PURE__ */ jsx4("p", { className: "mt-0.5 whitespace-pre-wrap text-sm text-foreground", children: text })
864
+ ] }, field.name);
865
+ }) }),
815
866
  error && /* @__PURE__ */ jsx4("p", { className: "mt-3 text-xs text-destructive", children: error }),
816
867
  terminalNote && /* @__PURE__ */ jsx4("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
817
868
  canReRequest && /* @__PURE__ */ jsx4("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsx4(InteractionActionButton, { variant: "outline", onClick: () => void requestReSubmission(), disabled: submitting !== null, children: submitting === "requesting" ? "Asking\u2026" : reRequestLabel ?? DEFAULT_RE_REQUEST_LABEL }) }),
@@ -938,6 +989,12 @@ function WarningGlyph({ className }) {
938
989
  function iconForMediaType(mediaType) {
939
990
  return mediaType?.startsWith("image/") ? ImageGlyph : FileGlyph;
940
991
  }
992
+ function formatDisplayBytes(bytes) {
993
+ if (bytes < 1024) return `${bytes} B`;
994
+ if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
995
+ const mb = bytes / (1024 * 1024);
996
+ return `${mb >= 10 ? Math.round(mb) : mb.toFixed(1)} MB`;
997
+ }
941
998
  function attachmentDisplayName(part) {
942
999
  if (typeof part.name === "string" && part.name.trim().length > 0) return part.name;
943
1000
  const base = part.path.split("/").pop() ?? "";
@@ -1001,7 +1058,7 @@ function useAttachmentObjectUrl(blob) {
1001
1058
  function AttachmentThumbnailError({ name }) {
1002
1059
  return /* @__PURE__ */ jsxs4("span", { className: "inline-flex h-16 w-16 shrink-0 flex-col items-center justify-center gap-1 rounded-md border border-destructive/40 bg-destructive/10 px-1 text-center text-destructive", children: [
1003
1060
  /* @__PURE__ */ jsx6(WarningGlyph, { className: "h-4 w-4 shrink-0" }),
1004
- /* @__PURE__ */ jsx6("span", { className: "line-clamp-2 text-[10px] leading-tight", children: name })
1061
+ /* @__PURE__ */ jsx6("span", { className: "line-clamp-2 text-[11px] leading-tight", children: name })
1005
1062
  ] });
1006
1063
  }
1007
1064
  function AttachmentUnavailable({ shape }) {
@@ -1013,7 +1070,7 @@ function AttachmentUnavailable({ shape }) {
1013
1070
  className: "inline-flex h-16 w-16 shrink-0 flex-col items-center justify-center gap-1 rounded-md border border-border bg-muted px-1 text-center text-muted-foreground",
1014
1071
  children: [
1015
1072
  /* @__PURE__ */ jsx6(WarningGlyph, { className: "h-4 w-4 shrink-0" }),
1016
- /* @__PURE__ */ jsx6("span", { className: "line-clamp-2 text-[10px] leading-tight", children: "Attachment unavailable" })
1073
+ /* @__PURE__ */ jsx6("span", { className: "line-clamp-2 text-[11px] leading-tight", children: "Attachment unavailable" })
1017
1074
  ]
1018
1075
  }
1019
1076
  );
@@ -1114,7 +1171,7 @@ function AttachmentChip({ part, resolveFileUrl, fetchFile }) {
1114
1171
  displayName,
1115
1172
  typeof part.size === "number" && /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground/70", children: [
1116
1173
  "\xB7 ",
1117
- formatBytes(part.size)
1174
+ formatDisplayBytes(part.size)
1118
1175
  ] })
1119
1176
  ]
1120
1177
  }
@@ -1311,10 +1368,11 @@ async function streamChatTurn(opts) {
1311
1368
  import {
1312
1369
  useCallback as useCallback2,
1313
1370
  useEffect as useEffect5,
1314
- useRef as useRef4,
1371
+ useRef as useRef5,
1315
1372
  useState as useState6
1316
1373
  } from "react";
1317
1374
  import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1375
+ var IS_APPLE_PLATFORM = typeof navigator !== "undefined" && /Mac|iPhone|iPad|iPod/i.test(navigator.platform);
1318
1376
  function SendGlyph({ className }) {
1319
1377
  return /* @__PURE__ */ jsx7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx7("path", { d: "M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" }) });
1320
1378
  }
@@ -1385,13 +1443,13 @@ function ChatComposer({
1385
1443
  const isControlled = value !== void 0;
1386
1444
  const [internal, setInternal] = useState6(initialValue ?? "");
1387
1445
  const text = isControlled ? value : internal;
1388
- const textRef = useRef4(text);
1446
+ const textRef = useRef5(text);
1389
1447
  textRef.current = text;
1390
- const textareaRef = useRef4(null);
1391
- const fileInputRef = useRef4(null);
1392
- const folderInputRef = useRef4(null);
1448
+ const textareaRef = useRef5(null);
1449
+ const fileInputRef = useRef5(null);
1450
+ const folderInputRef = useRef5(null);
1393
1451
  const [dragOver, setDragOver] = useState6(false);
1394
- const dragDepth = useRef4(0);
1452
+ const dragDepth = useRef5(0);
1395
1453
  const setText = useCallback2(
1396
1454
  (next) => {
1397
1455
  if (!isControlled) setInternal(next);
@@ -1405,8 +1463,8 @@ function ChatComposer({
1405
1463
  el.style.height = "auto";
1406
1464
  el.style.height = `${Math.min(el.scrollHeight, MAX_HEIGHT)}px`;
1407
1465
  }, [text]);
1408
- const prevSeedRef = useRef4(null);
1409
- const pendingCaretRef = useRef4(null);
1466
+ const prevSeedRef = useRef5(null);
1467
+ const pendingCaretRef = useRef5(null);
1410
1468
  useEffect5(() => {
1411
1469
  const prev = prevSeedRef.current;
1412
1470
  prevSeedRef.current = seed ?? null;
@@ -1430,7 +1488,7 @@ function ChatComposer({
1430
1488
  el.focus();
1431
1489
  el.setSelectionRange(text.length, text.length);
1432
1490
  }, [text]);
1433
- const restoreCaretRef = useRef4(null);
1491
+ const restoreCaretRef = useRef5(null);
1434
1492
  useEffect5(() => {
1435
1493
  const pending = restoreCaretRef.current;
1436
1494
  if (!pending || pending.text !== text) return;
@@ -1754,8 +1812,8 @@ function ChatComposer({
1754
1812
  }
1755
1813
  ),
1756
1814
  focusShortcut && /* @__PURE__ */ jsx7("div", { className: "mt-1.5 flex justify-end px-1", children: /* @__PURE__ */ jsxs5("span", { className: "text-xs text-muted-foreground", children: [
1757
- /* @__PURE__ */ jsx7("kbd", { className: "rounded border border-border bg-background px-1 py-0.5 text-[10px]", children: "Cmd" }),
1758
- /* @__PURE__ */ jsx7("kbd", { className: "ml-0.5 rounded border border-border bg-background px-1 py-0.5 text-[10px]", children: "L" }),
1815
+ /* @__PURE__ */ jsx7("kbd", { className: "rounded border border-border bg-background px-1 py-0.5 text-[11px]", children: IS_APPLE_PLATFORM ? "Cmd" : "Ctrl" }),
1816
+ /* @__PURE__ */ jsx7("kbd", { className: "ml-0.5 rounded border border-border bg-background px-1 py-0.5 text-[11px]", children: "L" }),
1759
1817
  /* @__PURE__ */ jsx7("span", { className: "ml-1", children: "to focus" })
1760
1818
  ] }) })
1761
1819
  ]
@@ -1764,7 +1822,7 @@ function ChatComposer({
1764
1822
  }
1765
1823
 
1766
1824
  // src/web-react/durable-plan-flow.ts
1767
- import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef5, useState as useState7 } from "react";
1825
+ import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef6, useState as useState7 } from "react";
1768
1826
  var DurablePlanClientError = class extends Error {
1769
1827
  constructor(message, status, code, currentPlan) {
1770
1828
  super(message);
@@ -1855,8 +1913,8 @@ function useDurablePlanFlow(options) {
1855
1913
  const [deciding, setDeciding] = useState7(null);
1856
1914
  const [restoring, setRestoring] = useState7(false);
1857
1915
  const [error, setError] = useState7(null);
1858
- const attachments = useRef5(/* @__PURE__ */ new Map());
1859
- const decisionInFlight = useRef5(false);
1916
+ const attachments = useRef6(/* @__PURE__ */ new Map());
1917
+ const decisionInFlight = useRef6(false);
1860
1918
  useEffect6(() => setPlan(options.plan), [options.plan]);
1861
1919
  const apply = useCallback3(async (result) => {
1862
1920
  setPlan(result.plan);
@@ -2132,7 +2190,7 @@ function useChatInteractions(options = {}) {
2132
2190
  }
2133
2191
 
2134
2192
  // src/web-react/use-file-mentions.ts
2135
- import { useCallback as useCallback5, useMemo as useMemo4, useRef as useRef6, useState as useState9 } from "react";
2193
+ import { useCallback as useCallback5, useMemo as useMemo4, useRef as useRef7, useState as useState9 } from "react";
2136
2194
  var FILE_MENTION_KIND = "file";
2137
2195
  function toMentionItem(file) {
2138
2196
  return { id: file.path, label: file.name, detail: file.path, kind: FILE_MENTION_KIND };
@@ -2191,9 +2249,9 @@ function useFileMentions(options) {
2191
2249
  } = options;
2192
2250
  const fetchImpl = options.fetchImpl ?? fetch;
2193
2251
  const [state, setState] = useState9({ kind: "idle" });
2194
- const stateRef = useRef6(state);
2252
+ const stateRef = useRef7(state);
2195
2253
  stateRef.current = state;
2196
- const inFlightRef = useRef6(null);
2254
+ const inFlightRef = useRef7(null);
2197
2255
  const [mentions, setMentions] = useState9([]);
2198
2256
  const load = useCallback5(() => {
2199
2257
  if (inFlightRef.current) return inFlightRef.current;
@@ -2421,9 +2479,9 @@ function FlowWaterfall({ trace }) {
2421
2479
  style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
2422
2480
  }
2423
2481
  ) }),
2424
- /* @__PURE__ */ jsx8("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
2482
+ /* @__PURE__ */ jsx8("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
2425
2483
  ] }, i)),
2426
- /* @__PURE__ */ jsxs6("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
2484
+ /* @__PURE__ */ jsxs6("p", { className: "pt-0.5 text-right font-mono text-[11px] tabular-nums text-muted-foreground/60", children: [
2427
2485
  (trace.totalMs / 1e3).toFixed(1),
2428
2486
  "s",
2429
2487
  cost ? ` \xB7 ${cost}` : ""
@@ -2447,8 +2505,8 @@ function MissionActivityLane({ activity, startedAt, nowMs }) {
2447
2505
  run.detail
2448
2506
  ] })
2449
2507
  ] }),
2450
- tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 font-mono text-[10px] text-warning", children: [run.iteration !== void 0 ? `iter ${run.iteration}` : null, run.phase ?? null].filter(Boolean).join(" \xB7 ") }),
2451
- /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
2508
+ tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 font-mono text-[11px] text-warning", children: [run.iteration !== void 0 ? `iter ${run.iteration}` : null, run.phase ?? null].filter(Boolean).join(" \xB7 ") }),
2509
+ /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[11px] tabular-nums text-muted-foreground/70", children: [
2452
2510
  tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx8("span", { children: run.status }),
2453
2511
  cost && /* @__PURE__ */ jsx8("span", { children: cost }),
2454
2512
  duration && /* @__PURE__ */ jsx8("span", { children: duration })
@@ -2460,7 +2518,7 @@ function MissionActivityLane({ activity, startedAt, nowMs }) {
2460
2518
  {
2461
2519
  type: "button",
2462
2520
  onClick: () => setExpanded((v) => !v),
2463
- className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
2521
+ className: "flex items-center gap-1 py-0.5 text-[11px] font-medium text-muted-foreground/70 transition hover:text-foreground",
2464
2522
  children: [
2465
2523
  /* @__PURE__ */ jsx8(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
2466
2524
  "timeline"
@@ -2496,11 +2554,11 @@ function ActivityRow({
2496
2554
  record.detail
2497
2555
  ] })
2498
2556
  ] }),
2499
- tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-warning/10 px-2 py-0.5 font-mono text-[10px] text-warning", children: [record.iteration !== void 0 ? `iter ${record.iteration}` : null, record.phase ?? null].filter(Boolean).join(" \xB7 ") }),
2557
+ tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-warning/10 px-2 py-0.5 font-mono text-[11px] text-warning", children: [record.iteration !== void 0 ? `iter ${record.iteration}` : null, record.phase ?? null].filter(Boolean).join(" \xB7 ") }),
2500
2558
  /* @__PURE__ */ jsx8(
2501
2559
  "span",
2502
2560
  {
2503
- className: `shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium ${tone === "ok" ? "bg-success/10 text-success" : tone === "error" ? "bg-destructive/10 text-destructive" : tone === "live" ? "bg-warning/10 text-warning" : "bg-secondary text-muted-foreground"}`,
2561
+ className: `shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium ${tone === "ok" ? "bg-success/10 text-success" : tone === "error" ? "bg-destructive/10 text-destructive" : tone === "live" ? "bg-warning/10 text-warning" : "bg-secondary text-muted-foreground"}`,
2504
2562
  children: record.status
2505
2563
  }
2506
2564
  ),
@@ -2585,7 +2643,7 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
2585
2643
  }
2586
2644
 
2587
2645
  // src/web-react/provenance.tsx
2588
- import { useCallback as useCallback7, useEffect as useEffect8, useId, useRef as useRef7, useState as useState11 } from "react";
2646
+ import { useCallback as useCallback7, useEffect as useEffect8, useId, useRef as useRef8, useState as useState11 } from "react";
2589
2647
 
2590
2648
  // src/web-react/provenance-model.ts
2591
2649
  var PROVENANCE_BASES = ["extracted", "entered", "computed", "asserted"];
@@ -2812,7 +2870,7 @@ function SourceRow({
2812
2870
  const openable = status === "ready" && (onOpenSource !== void 0 || source.href !== void 0);
2813
2871
  return /* @__PURE__ */ jsxs7("li", { className: "rounded-md border border-card-edge bg-card px-2.5 py-2", children: [
2814
2872
  /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
2815
- /* @__PURE__ */ jsx9("span", { className: "text-[13px] font-medium text-foreground", children: source.label }),
2873
+ /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-foreground", children: source.label }),
2816
2874
  source.locator && /* @__PURE__ */ jsx9("span", { className: "text-[11px] text-muted-foreground", children: source.locator }),
2817
2875
  openable && (onOpenSource ? /* @__PURE__ */ jsxs7(
2818
2876
  "button",
@@ -2880,8 +2938,8 @@ function ProvenanceValue({
2880
2938
  className
2881
2939
  }) {
2882
2940
  const [open, setOpen] = useState11(defaultOpen);
2883
- const triggerRef = useRef7(null);
2884
- const rootRef = useRef7(null);
2941
+ const triggerRef = useRef8(null);
2942
+ const rootRef = useRef8(null);
2885
2943
  const panelId = useId();
2886
2944
  const standing = rollUpProvenanceStanding(record, confidencePolicy);
2887
2945
  const basisMeta = provenanceBasisMeta(record.basis);
@@ -2938,7 +2996,7 @@ function ProvenanceValue({
2938
2996
  /* @__PURE__ */ jsxs7(
2939
2997
  "span",
2940
2998
  {
2941
- className: `ml-1.5 inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium ${BASIS_TONES[record.basis]}`,
2999
+ className: `ml-1.5 inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[11px] font-medium ${BASIS_TONES[record.basis]}`,
2942
3000
  children: [
2943
3001
  /* @__PURE__ */ jsx9(BasisGlyph, { basis: record.basis, className: "h-3 w-3" }),
2944
3002
  basisMeta.label
@@ -2970,7 +3028,7 @@ function ProvenanceValue({
2970
3028
  "aria-expanded": open,
2971
3029
  "aria-controls": panelId,
2972
3030
  "aria-label": provenanceTriggerLabel(record, standing),
2973
- className: `inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition hover:brightness-105 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${BASIS_TONES[record.basis]}`,
3031
+ className: `inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[11px] font-medium transition hover:brightness-105 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${BASIS_TONES[record.basis]}`,
2974
3032
  children: [
2975
3033
  /* @__PURE__ */ jsx9(BasisGlyph, { basis: record.basis, className: "h-3 w-3" }),
2976
3034
  /* @__PURE__ */ jsx9("span", { "aria-hidden": true, children: basisMeta.label })
@@ -2980,7 +3038,7 @@ function ProvenanceValue({
2980
3038
  standing !== "settled" && // Legible at rest: what to do about the value does not wait for
2981
3039
  // someone to open the panel. `aria-hidden` because the trigger's
2982
3040
  // accessible name already carries it — this is the visual half.
2983
- /* @__PURE__ */ jsx9("span", { "aria-hidden": true, className: `text-[10px] font-medium ${STANDING_TONES[standing]}`, children: standingMeta.label })
3041
+ /* @__PURE__ */ jsx9("span", { "aria-hidden": true, className: `text-[11px] font-medium ${STANDING_TONES[standing]}`, children: standingMeta.label })
2984
3042
  ] }),
2985
3043
  open && /* @__PURE__ */ jsxs7(
2986
3044
  "div",
@@ -3019,7 +3077,7 @@ function ProvenanceValue({
3019
3077
  )),
3020
3078
  loading.length > 0 && sources.length === 0 && /* @__PURE__ */ jsx9("p", { role: "status", className: "text-[11px] text-muted-foreground", children: "Looking up where this came from\u2026" }),
3021
3079
  inputs.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "border-t border-border pt-2", children: [
3022
- /* @__PURE__ */ jsx9("p", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: record.derivation ? `Computed from ${record.derivation}` : "Computed from" }),
3080
+ /* @__PURE__ */ jsx9("p", { className: "text-[11px] font-medium uppercase tracking-[0.05em] text-muted-foreground", children: record.derivation ? `Computed from ${record.derivation}` : "Computed from" }),
3023
3081
  /* @__PURE__ */ jsx9("ul", { className: "mt-1.5 space-y-1.5", children: inputs.map((input, index) => /* @__PURE__ */ jsx9("li", { children: /* @__PURE__ */ jsx9(
3024
3082
  ProvenanceValue,
3025
3083
  {
@@ -3047,7 +3105,7 @@ function ProvenanceLegend({ bases, className }) {
3047
3105
  /* @__PURE__ */ jsxs7(
3048
3106
  "span",
3049
3107
  {
3050
- className: `inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium ${BASIS_TONES[basis]}`,
3108
+ className: `inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[11px] font-medium ${BASIS_TONES[basis]}`,
3051
3109
  children: [
3052
3110
  /* @__PURE__ */ jsx9(BasisGlyph, { basis, className: "h-3 w-3" }),
3053
3111
  meta.label
@@ -3107,7 +3165,7 @@ function SeatPaywall({
3107
3165
  const recurringUsage = offer ? usd(offer.recurring.includedCreditsCents) : `$${includedUsageUsd}`;
3108
3166
  const introductory = offer?.introductory ?? null;
3109
3167
  return /* @__PURE__ */ jsx10("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs8("div", { className: "w-full max-w-md rounded-2xl border border-card-edge bg-card p-8", children: [
3110
- /* @__PURE__ */ jsx10("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
3168
+ /* @__PURE__ */ jsx10("p", { className: "text-[11px] font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: product }),
3111
3169
  /* @__PURE__ */ jsxs8("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
3112
3170
  "Unlock ",
3113
3171
  product
@@ -3142,8 +3200,7 @@ function SeatPaywall({
3142
3200
  ] })
3143
3201
  ] }),
3144
3202
  /* @__PURE__ */ jsx10("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
3145
- `Full access to ${product}`,
3146
- `${recurringUsage}/mo of AI usage included`
3203
+ `Full access to ${product}`
3147
3204
  ]).map((benefit, i) => /* @__PURE__ */ jsx10(Benefit, { children: benefit }, i)) }),
3148
3205
  /* @__PURE__ */ jsx10(
3149
3206
  "button",
@@ -3152,7 +3209,7 @@ function SeatPaywall({
3152
3209
  disabled: pending,
3153
3210
  onClick: () => run(onCheckout),
3154
3211
  className: "mt-7 inline-flex w-full items-center justify-center rounded-xl bg-primary px-4 py-2.5 text-sm font-medium text-primary-foreground transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-70",
3155
- children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
3212
+ children: pending ? "Opening checkout\u2026" : ctaLabel ?? "Continue to checkout"
3156
3213
  }
3157
3214
  ),
3158
3215
  footnote && /* @__PURE__ */ jsx10("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
@@ -3165,7 +3222,7 @@ import {
3165
3222
  useEffect as useEffect9,
3166
3223
  useId as useId2,
3167
3224
  useMemo as useMemo5,
3168
- useRef as useRef8,
3225
+ useRef as useRef9,
3169
3226
  useState as useState12
3170
3227
  } from "react";
3171
3228
  import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -3177,7 +3234,7 @@ function rethrowAsync(error) {
3177
3234
  function useInfiniteScroll(onLoadMore, { enabled, root, rootMargin = "300px" }) {
3178
3235
  const [sentinel, setSentinel] = useState12(null);
3179
3236
  const sentinelRef = useCallback8((node) => setSentinel(node), []);
3180
- const onLoadMoreRef = useRef8(onLoadMore);
3237
+ const onLoadMoreRef = useRef9(onLoadMore);
3181
3238
  useEffect9(() => {
3182
3239
  onLoadMoreRef.current = onLoadMore;
3183
3240
  }, [onLoadMore]);
@@ -3214,16 +3271,16 @@ function useSessionHistory({
3214
3271
  const [nextCursor, setNextCursor] = useState12(initialPage.nextCursor ?? null);
3215
3272
  const [phase, setPhase] = useState12("idle");
3216
3273
  const [reloadKey, setReloadKey] = useState12(0);
3217
- const seqRef = useRef8(0);
3218
- const resetAbortRef = useRef8(null);
3219
- const loadMoreAbortRef = useRef8(null);
3220
- const loadingMoreRef = useRef8(false);
3221
- const lastOpRef = useRef8("first");
3222
- const nextCursorRef = useRef8(nextCursor);
3274
+ const seqRef = useRef9(0);
3275
+ const resetAbortRef = useRef9(null);
3276
+ const loadMoreAbortRef = useRef9(null);
3277
+ const loadingMoreRef = useRef9(false);
3278
+ const lastOpRef = useRef9("first");
3279
+ const nextCursorRef = useRef9(nextCursor);
3223
3280
  nextCursorRef.current = nextCursor;
3224
- const viewRef = useRef8({ q, sort, fetchPage });
3281
+ const viewRef = useRef9({ q, sort, fetchPage });
3225
3282
  viewRef.current = { q, sort, fetchPage };
3226
- const seedRef = useRef8(initialPage);
3283
+ const seedRef = useRef9(initialPage);
3227
3284
  seedRef.current = initialPage;
3228
3285
  const isDefaultView = q === "" && sort === defaultSort;
3229
3286
  const seedKey = useMemo5(() => seedSignature(initialPage), [initialPage]);
@@ -3552,7 +3609,7 @@ function SessionHistoryPanel({
3552
3609
  contentWidth = "reading",
3553
3610
  className
3554
3611
  }) {
3555
- const scrollRef = useRef8(null);
3612
+ const scrollRef = useRef9(null);
3556
3613
  const sentinelRef = useInfiniteScroll(history.loadMore, {
3557
3614
  enabled: history.hasMore && !history.isLoadingMore && !history.isError,
3558
3615
  root: scrollRef,
@@ -3953,7 +4010,7 @@ import {
3953
4010
  useEffect as useEffect10,
3954
4011
  useId as useId3,
3955
4012
  useMemo as useMemo6,
3956
- useRef as useRef9,
4013
+ useRef as useRef10,
3957
4014
  useState as useState13
3958
4015
  } from "react";
3959
4016
 
@@ -4352,10 +4409,10 @@ function RecordGrid({
4352
4409
  const [draftErrors, setDraftErrors] = useState13({});
4353
4410
  const [draftError, setDraftError] = useState13(null);
4354
4411
  const [creating, setCreating] = useState13(false);
4355
- const cellRefs = useRef9(/* @__PURE__ */ new Map());
4356
- const settling = useRef9(false);
4357
- const draftCounter = useRef9(0);
4358
- const editingRef = useRef9(null);
4412
+ const cellRefs = useRef10(/* @__PURE__ */ new Map());
4413
+ const settling = useRef10(false);
4414
+ const draftCounter = useRef10(0);
4415
+ const editingRef = useRef10(null);
4359
4416
  const setEditing = useCallback9((next) => {
4360
4417
  editingRef.current = next;
4361
4418
  setEditingState(next);
@@ -4670,7 +4727,7 @@ function RecordGrid({
4670
4727
  className: "w-full border-collapse text-left text-sm",
4671
4728
  onKeyDown: handleGridKeyDown,
4672
4729
  children: [
4673
- /* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs10("tr", { role: "row", className: "border-b border-border text-[11px] uppercase tracking-wide text-muted-foreground", children: [
4730
+ /* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs10("tr", { role: "row", className: "border-b border-border text-[11px] uppercase tracking-[0.05em] text-muted-foreground", children: [
4674
4731
  columns.map((column) => /* @__PURE__ */ jsx12(
4675
4732
  "th",
4676
4733
  {
@@ -5210,7 +5267,7 @@ function RunDrillIn({ run, onClose }) {
5210
5267
  }
5211
5268
  ),
5212
5269
  /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
5213
- /* @__PURE__ */ jsx13("p", { className: "truncate text-sm font-semibold", children: run.title }),
5270
+ /* @__PURE__ */ jsx13("p", { className: "truncate text-[15px] font-semibold", children: run.title }),
5214
5271
  /* @__PURE__ */ jsx13("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
5215
5272
  ] }),
5216
5273
  /* @__PURE__ */ jsx13(
@@ -5230,12 +5287,12 @@ function RunDrillIn({ run, onClose }) {
5230
5287
  /* @__PURE__ */ jsxs11("div", { className: "flex items-baseline gap-2 border-b border-border px-3 py-1.5", children: [
5231
5288
  /* @__PURE__ */ jsx13("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
5232
5289
  /* @__PURE__ */ jsx13("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
5233
- /* @__PURE__ */ jsx13("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
5290
+ /* @__PURE__ */ jsx13("span", { className: "shrink-0 text-[11px] tabular-nums text-muted-foreground", children: new Date(step.at).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) })
5234
5291
  ] }),
5235
5292
  step.detail && /* @__PURE__ */ jsx13("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap px-3 py-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: step.detail })
5236
5293
  ] }, i))
5237
5294
  ] }),
5238
- /* @__PURE__ */ jsx13("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground", children: "Readonly drill-in. Follow up in the main chat." })
5295
+ /* @__PURE__ */ jsx13("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground", children: "Read-only transcript \u2014 reply in the main chat." })
5239
5296
  ] });
5240
5297
  }
5241
5298
  function pendingApprovalOf(call) {
@@ -5249,19 +5306,24 @@ function ChatEmptyState({
5249
5306
  subline = "Describe the outcome you want. The agent works through it step by step, and pauses for your approval before anything irreversible.",
5250
5307
  doors
5251
5308
  }) {
5309
+ const doorCount = Math.min(doors?.length ?? 0, 3);
5310
+ const doorsGridClass = doorCount === 1 ? "mx-auto max-w-sm sm:grid-cols-1" : doorCount === 2 ? "sm:grid-cols-2" : "sm:grid-cols-3";
5252
5311
  return /* @__PURE__ */ jsxs11("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
5253
5312
  /* @__PURE__ */ jsx13("span", { className: "mb-5 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 ring-1 ring-primary/15", children: /* @__PURE__ */ jsx13(BrandMark, { size: 32, className: "shrink-0" }) }),
5254
- /* @__PURE__ */ jsx13("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
5255
- /* @__PURE__ */ jsx13("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
5313
+ /* @__PURE__ */ jsx13("p", { className: "text-[11px] font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: productName }),
5314
+ /* @__PURE__ */ jsx13("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground", children: headline }),
5256
5315
  subline && /* @__PURE__ */ jsx13("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
5257
- doors && doors.length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs11(
5316
+ doors && doors.length > 0 && /* @__PURE__ */ jsx13("div", { className: `mt-7 grid w-full gap-2.5 ${doorsGridClass}`, children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs11(
5258
5317
  "button",
5259
5318
  {
5260
5319
  type: "button",
5261
5320
  onClick: door.onSelect,
5262
5321
  className: "group flex min-h-[44px] flex-col items-start rounded-xl border border-border bg-card px-4 py-3 text-left transition hover:border-primary/40 hover:bg-accent",
5263
5322
  children: [
5264
- /* @__PURE__ */ jsx13("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
5323
+ /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-2 text-sm font-semibold text-foreground", children: [
5324
+ door.icon,
5325
+ door.label
5326
+ ] }),
5265
5327
  door.description && /* @__PURE__ */ jsx13("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
5266
5328
  ]
5267
5329
  },
@@ -5349,7 +5411,7 @@ function proposalPreview(call) {
5349
5411
  const a = call.args ?? {};
5350
5412
  const asString = (v) => typeof v === "string" && v.trim() ? v.trim() : null;
5351
5413
  const asList = (v) => Array.isArray(v) ? v.map((x) => typeof x === "string" ? x : null).filter((x) => !!x) : asString(v) ? [asString(v)] : [];
5352
- const verbPhrase = asString(a.summary) ?? asString(a.description) ?? (asString(a.type) ? `${String(a.type).replace(/_/g, " ")}${asString(a.title) ? `: ${asString(a.title)}` : ""}` : null);
5414
+ const verbPhrase = asString(a.summary) ?? asString(a.description) ?? null;
5353
5415
  const destinations = [
5354
5416
  ...asList(a.destinations),
5355
5417
  ...asList(a.channels),
@@ -5358,6 +5420,7 @@ function proposalPreview(call) {
5358
5420
  ];
5359
5421
  const dest = destinations.length ? ` to ${destinations.join(" and ")}` : "";
5360
5422
  const summary = verbPhrase ? `${verbPhrase}${dest}` : destinations.length ? `Publish to ${destinations.join(" and ")}` : null;
5423
+ const typeSlug = summary === null ? asString(a.type) : null;
5361
5424
  const meta = [];
5362
5425
  const cost = a.cost ?? a.price ?? a.estimatedCost;
5363
5426
  if (typeof cost === "number" && cost > 0) meta.push(`~$${cost < 0.01 ? cost.toFixed(4) : cost.toFixed(2)}`);
@@ -5365,7 +5428,7 @@ function proposalPreview(call) {
5365
5428
  const reach = a.reach ?? a.audience ?? a.estimatedReach;
5366
5429
  if (typeof reach === "number" && reach > 0) meta.push(`reaches ~${reach.toLocaleString()}`);
5367
5430
  else if (asString(reach)) meta.push(asString(reach));
5368
- return { summary, meta };
5431
+ return { summary, meta, typeSlug };
5369
5432
  }
5370
5433
  function truncate(v, max = 240) {
5371
5434
  const s = typeof v === "string" ? v : JSON.stringify(v);
@@ -5400,14 +5463,14 @@ function DefaultToolDetail({ call }) {
5400
5463
  const envelope = typeof result === "object" && result !== null ? result : null;
5401
5464
  return /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
5402
5465
  call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs11("div", { children: [
5403
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
5466
+ /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
5404
5467
  /* @__PURE__ */ jsx13(KvRows, { data: call.args })
5405
5468
  ] }),
5406
5469
  envelope ? /* @__PURE__ */ jsxs11("div", { children: [
5407
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: envelope.ok === false ? "Failed" : "Result" }),
5470
+ /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: envelope.ok === false ? "Failed" : "Result" }),
5408
5471
  envelope.ok === false ? /* @__PURE__ */ jsx13("p", { className: "text-xs text-destructive", children: envelope.message ?? "Tool failed" }) : envelope.result && typeof envelope.result === "object" ? /* @__PURE__ */ jsx13(KvRows, { data: envelope.result }) : envelope.result != null ? /* @__PURE__ */ jsx13("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(envelope.result) }) : null
5409
5472
  ] }) : result != null ? /* @__PURE__ */ jsxs11("div", { children: [
5410
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Result" }),
5473
+ /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Result" }),
5411
5474
  /* @__PURE__ */ jsx13("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(result) })
5412
5475
  ] }) : null
5413
5476
  ] });
@@ -5420,28 +5483,29 @@ function ProposalCard({
5420
5483
  renderers
5421
5484
  }) {
5422
5485
  const [expanded, setExpanded] = useState14(false);
5423
- const { summary, meta } = proposalPreview(call);
5486
+ const { summary, meta, typeSlug } = proposalPreview(call);
5424
5487
  const custom = renderers?.[call.name]?.(call, message);
5425
5488
  const { pending: deciding, run: decide } = usePending();
5426
5489
  return /* @__PURE__ */ jsxs11("div", { className: "w-full max-w-full rounded-xl border border-warning/50 bg-warning/[0.06] text-sm shadow-sm ring-1 ring-warning/10", children: [
5427
5490
  /* @__PURE__ */ jsxs11("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
5428
5491
  /* @__PURE__ */ jsx13("span", { className: "mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-warning/15 text-warning", children: /* @__PURE__ */ jsx13(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
5429
5492
  /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
5430
- /* @__PURE__ */ jsx13("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-strong", children: "Needs your approval" }),
5493
+ /* @__PURE__ */ jsx13("p", { className: "text-[11px] font-semibold uppercase tracking-[0.05em] text-warning-strong", children: approval ? "Needs your approval" : "Awaiting approval" }),
5431
5494
  /* @__PURE__ */ jsx13("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
5432
- summary && /* @__PURE__ */ jsx13("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
5495
+ summary && /* @__PURE__ */ jsx13("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: summary }),
5496
+ typeSlug && /* @__PURE__ */ jsx13("p", { className: "mt-1 font-mono text-xs text-muted-foreground", children: typeSlug }),
5433
5497
  meta.length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx13("span", { className: "rounded-full bg-secondary px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
5434
5498
  ] })
5435
5499
  ] }),
5436
5500
  /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
5437
- approval ? /* @__PURE__ */ jsxs11(Fragment7, { children: [
5501
+ approval && /* @__PURE__ */ jsxs11(Fragment7, { children: [
5438
5502
  /* @__PURE__ */ jsx13(
5439
5503
  "button",
5440
5504
  {
5441
5505
  type: "button",
5442
5506
  disabled: deciding,
5443
5507
  onClick: () => decide(() => approval.onApprove(pending.proposalId, call.id)),
5444
- className: "inline-flex min-h-[40px] flex-1 items-center justify-center rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground shadow-sm transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-60 sm:flex-none sm:min-w-[160px]",
5508
+ className: "inline-flex min-h-[40px] flex-1 items-center justify-center rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-60 sm:flex-none sm:min-w-[160px]",
5445
5509
  children: "Approve & run"
5446
5510
  }
5447
5511
  ),
@@ -5455,7 +5519,7 @@ function ProposalCard({
5455
5519
  children: "Reject"
5456
5520
  }
5457
5521
  )
5458
- ] }) : /* @__PURE__ */ jsx13("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
5522
+ ] }),
5459
5523
  /* @__PURE__ */ jsxs11(
5460
5524
  "button",
5461
5525
  {
@@ -5473,14 +5537,27 @@ function ProposalCard({
5473
5537
  expanded && /* @__PURE__ */ jsx13("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx13(DefaultToolDetail, { call }) })
5474
5538
  ] });
5475
5539
  }
5540
+ function formatFollowupWhen(when) {
5541
+ const date = new Date(when);
5542
+ if (Number.isNaN(date.getTime())) return when;
5543
+ const day = date.toLocaleDateString([], { weekday: "short", month: "short", day: "numeric" });
5544
+ const time = date.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" });
5545
+ return `${day} \xB7 ${time}`;
5546
+ }
5476
5547
  function FollowupCard({ call }) {
5477
5548
  const a = call.args ?? {};
5478
5549
  const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
5479
- return /* @__PURE__ */ jsx13("div", { className: "flex items-start gap-2", children: /* @__PURE__ */ jsx13("div", { className: "min-w-0 flex-1 overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]", children: /* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center gap-2.5 px-3 py-2", children: [
5480
- /* @__PURE__ */ jsx13("span", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)] border border-border bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx13(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
5481
- /* @__PURE__ */ jsx13("span", { className: "shrink-0 whitespace-nowrap text-xs font-medium text-foreground", children: friendlyToolTitle(call) }),
5482
- when && /* @__PURE__ */ jsx13("span", { className: "hidden min-w-0 flex-1 truncate font-mono text-xs text-muted-foreground sm:inline", children: when })
5483
- ] }) }) });
5550
+ const failed = toolCallFailed(call);
5551
+ const errorText = failed ? toolOutcomeOf(call)?.message ?? "Scheduling failed" : null;
5552
+ return /* @__PURE__ */ jsx13("div", { className: "flex items-start gap-2", children: /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1 overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]", children: [
5553
+ /* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center gap-2.5 px-3 py-2", children: [
5554
+ /* @__PURE__ */ jsx13("span", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)] border border-border bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx13(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
5555
+ /* @__PURE__ */ jsx13("span", { className: "shrink-0 whitespace-nowrap text-xs font-medium text-foreground", children: friendlyToolTitle(call) }),
5556
+ when && /* @__PURE__ */ jsx13("span", { title: when, className: "hidden min-w-0 flex-1 truncate font-mono text-xs tabular-nums text-muted-foreground sm:inline", children: formatFollowupWhen(when) }),
5557
+ /* @__PURE__ */ jsx13("span", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: call.status === "running" ? /* @__PURE__ */ jsx13("svg", { className: "h-3 w-3 shrink-0 animate-spin text-[var(--accent-text)]", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx13("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }) : /* @__PURE__ */ jsx13("span", { className: `h-1.5 w-1.5 shrink-0 rounded-full ${failed ? "bg-[var(--surface-danger-text)]" : "bg-[var(--surface-success-text)]"}` }) })
5558
+ ] }),
5559
+ errorText && /* @__PURE__ */ jsx13("div", { className: "border-t border-border px-3 py-2 text-xs text-[var(--surface-danger-text)]", children: errorText })
5560
+ ] }) });
5484
5561
  }
5485
5562
  function toolRowTitle(call) {
5486
5563
  if (call.name === "sandbox_run_command") return "Ran command";
@@ -5500,7 +5577,6 @@ function ToolCallCard({
5500
5577
  }) {
5501
5578
  const pending = call.status === "done" ? pendingApprovalOf(call) : null;
5502
5579
  const kind = blockKindOf(call);
5503
- const failed = toolCallFailed(call);
5504
5580
  if (pending) {
5505
5581
  return /* @__PURE__ */ jsx13(
5506
5582
  ProposalCard,
@@ -5513,7 +5589,7 @@ function ToolCallCard({
5513
5589
  }
5514
5590
  );
5515
5591
  }
5516
- if (kind === "followup" && !failed) {
5592
+ if (kind === "followup") {
5517
5593
  return /* @__PURE__ */ jsx13(FollowupCard, { call });
5518
5594
  }
5519
5595
  const custom = renderers?.[call.name]?.(call, message);
@@ -5529,8 +5605,13 @@ function ToolCallCard({
5529
5605
  {
5530
5606
  type: "button",
5531
5607
  onClick: () => onOpenRun(call, message),
5532
- className: "rounded border border-border bg-card px-2 py-1 text-[11px] font-medium transition hover:bg-accent",
5533
- children: "Open full transcript \u2192"
5608
+ "aria-label": "Open full transcript",
5609
+ title: "Open full transcript",
5610
+ className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent hover:text-foreground",
5611
+ children: /* @__PURE__ */ jsxs11("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
5612
+ /* @__PURE__ */ jsx13("path", { d: "M7 17 17 7" }),
5613
+ /* @__PURE__ */ jsx13("path", { d: "M7 7h10v10" })
5614
+ ] })
5534
5615
  }
5535
5616
  ) : void 0
5536
5617
  }
@@ -5628,7 +5709,7 @@ function SegmentedBody({
5628
5709
  // The fold is a quiet disclosure line, not a filled box — the
5629
5710
  // canonical rows inside it carry the row chrome.
5630
5711
  /* @__PURE__ */ jsxs11("details", { children: [
5631
- /* @__PURE__ */ jsxs11("summary", { className: "cursor-pointer select-none rounded-md px-1 py-0.5 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground", children: [
5712
+ /* @__PURE__ */ jsxs11("summary", { className: "cursor-pointer select-none rounded-md py-0.5 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground", children: [
5632
5713
  "Worked through ",
5633
5714
  g.calls.length,
5634
5715
  " steps"
@@ -5641,7 +5722,7 @@ function SegmentedBody({
5641
5722
  streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx13(StreamingCaret, {})
5642
5723
  ] });
5643
5724
  }
5644
- var QUIET_META_LANE_CLASS = "mt-1 flex h-[18px] items-center gap-2 text-[11px] tracking-wide text-muted-foreground opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100 motion-reduce:transition-none [@media(hover:none)]:opacity-100";
5725
+ var QUIET_META_LANE_CLASS = "mt-1 flex h-[18px] items-center gap-2 text-[11px] tabular-nums text-muted-foreground opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100 motion-reduce:transition-none [@media(hover:none)]:opacity-100";
5645
5726
  function copyTextOf(msg) {
5646
5727
  const textRuns = msg.segments?.filter((s) => s.kind === "text") ?? [];
5647
5728
  if (textRuns.length > 0) return textRuns.map((s) => s.content).join("\n\n");
@@ -5649,7 +5730,7 @@ function copyTextOf(msg) {
5649
5730
  }
5650
5731
  function CopyMessageButton({ text }) {
5651
5732
  const [copied, setCopied] = useState14(false);
5652
- const timerRef = useRef10(null);
5733
+ const timerRef = useRef11(null);
5653
5734
  useEffect11(
5654
5735
  () => () => {
5655
5736
  if (timerRef.current !== null) clearTimeout(timerRef.current);
@@ -5705,9 +5786,9 @@ function AssistantMessageImpl({
5705
5786
  const body = useMemo7(() => renderBody(content), [renderBody, content]);
5706
5787
  const segments = msg.segments;
5707
5788
  const hasAnswerText = content !== "" || (segments?.some((s) => s.kind === "text" && s.content.trim() !== "") ?? false);
5708
- const reasoningScrollRef = useRef10(null);
5709
- const thinkStartRef = useRef10(null);
5710
- const thinkMsRef = useRef10(null);
5789
+ const reasoningScrollRef = useRef11(null);
5790
+ const thinkStartRef = useRef11(null);
5791
+ const thinkMsRef = useRef11(null);
5711
5792
  if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
5712
5793
  thinkStartRef.current = performance.now();
5713
5794
  }
@@ -5723,8 +5804,8 @@ function AssistantMessageImpl({
5723
5804
  );
5724
5805
  const quiet = chrome === "quiet";
5725
5806
  return /* @__PURE__ */ jsxs11("div", { className: `mx-auto w-full max-w-3xl px-6 ${quiet ? "group pb-1 pt-3" : "py-3"}`, children: [
5726
- !quiet && /* @__PURE__ */ jsxs11("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
5727
- /* @__PURE__ */ jsx13("span", { className: "font-semibold uppercase", children: agentLabel }),
5807
+ !quiet && /* @__PURE__ */ jsxs11("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tabular-nums text-muted-foreground", children: [
5808
+ /* @__PURE__ */ jsx13("span", { className: "font-semibold uppercase tracking-[0.05em]", children: agentLabel }),
5728
5809
  msg.modelUsed && /* @__PURE__ */ jsx13("span", { className: "font-mono normal-case", children: msg.modelUsed }),
5729
5810
  formatTokensPerSecond(msg) && /* @__PURE__ */ jsx13("span", { children: formatTokensPerSecond(msg) }),
5730
5811
  formatModelCost(msg, models) && /* @__PURE__ */ jsx13("span", { children: formatModelCost(msg, models) })
@@ -5742,7 +5823,7 @@ function AssistantMessageImpl({
5742
5823
  thinkingSeconds >= 1 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
5743
5824
  ] })
5744
5825
  ) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
5745
- /* @__PURE__ */ jsx13("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
5826
+ /* @__PURE__ */ jsx13("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-xs leading-relaxed text-muted-foreground", children: reasoning })
5746
5827
  ] }),
5747
5828
  segments && segments.length > 0 ? /* @__PURE__ */ jsx13(
5748
5829
  SegmentedBody,
@@ -5822,8 +5903,8 @@ function useThinkingSeconds(active) {
5822
5903
  function ThinkingRow({ agentLabel, chrome = "labeled" }) {
5823
5904
  const seconds = useThinkingSeconds(true);
5824
5905
  return /* @__PURE__ */ jsxs11("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
5825
- chrome !== "quiet" && /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
5826
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
5906
+ chrome !== "quiet" && /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: agentLabel }),
5907
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 text-[15px] text-muted-foreground", children: [
5827
5908
  /* @__PURE__ */ jsx13("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx13("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
5828
5909
  "Thinking",
5829
5910
  seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
@@ -5870,7 +5951,7 @@ function ChatMessages({
5870
5951
  resolveAttachmentUrl,
5871
5952
  workProductCards
5872
5953
  }) {
5873
- const messageClassName = messageSize === "large" ? "agent-app-message-copy text-[17px] leading-[1.75]" : "agent-app-message-copy text-base leading-[1.75]";
5954
+ const messageClassName = messageSize === "large" ? "agent-app-message-copy text-[16px] leading-[1.6]" : "agent-app-message-copy text-[15px] leading-[1.6]";
5874
5955
  const renderBody = useMemo7(
5875
5956
  () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx13("p", { className: "whitespace-pre-wrap", children: content })),
5876
5957
  [renderMarkdown]
@@ -5889,7 +5970,7 @@ function ChatMessages({
5889
5970
  messages.map(
5890
5971
  (msg) => msg.role === "user" ? /* @__PURE__ */ jsxs11("div", { className: `mx-auto w-full max-w-3xl px-6 ${quiet ? "group pb-1 pt-3" : "py-3"}`, children: [
5891
5972
  /* @__PURE__ */ jsxs11("div", { className: `ml-auto w-fit ${quiet ? "max-w-[72%]" : "max-w-[85%]"}`, children: [
5892
- !quiet && /* @__PURE__ */ jsx13("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
5973
+ !quiet && /* @__PURE__ */ jsx13("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: userLabel }),
5893
5974
  /* @__PURE__ */ jsx13(
5894
5975
  "div",
5895
5976
  {
@@ -6047,4 +6128,4 @@ export {
6047
6128
  useThinkingSeconds,
6048
6129
  ChatMessages
6049
6130
  };
6050
- //# sourceMappingURL=chunk-ZX5UT4HF.js.map
6131
+ //# sourceMappingURL=chunk-C7AQW6US.js.map