@tangle-network/agent-app 0.43.24 → 0.43.26

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 (65) hide show
  1. package/dist/app-auth/index.d.ts +163 -0
  2. package/dist/app-auth/index.js +166 -0
  3. package/dist/app-auth/index.js.map +1 -0
  4. package/dist/assets/index.d.ts +2 -2
  5. package/dist/assistant/index.d.ts +2 -0
  6. package/dist/assistant/index.js +3 -1
  7. package/dist/assistant/index.js.map +1 -1
  8. package/dist/chat-routes/index.d.ts +276 -0
  9. package/dist/chat-routes/index.js +564 -0
  10. package/dist/chat-routes/index.js.map +1 -0
  11. package/dist/chat-store/index.d.ts +194 -0
  12. package/dist/chat-store/index.js +198 -0
  13. package/dist/chat-store/index.js.map +1 -0
  14. package/dist/chunk-4TXDD6P2.js +163 -0
  15. package/dist/chunk-4TXDD6P2.js.map +1 -0
  16. package/dist/chunk-5EQCITY3.js +20 -0
  17. package/dist/chunk-5EQCITY3.js.map +1 -0
  18. package/dist/chunk-5SV5PSU7.js +80 -0
  19. package/dist/chunk-5SV5PSU7.js.map +1 -0
  20. package/dist/chunk-7LNGJDNA.js +1 -0
  21. package/dist/chunk-7LNGJDNA.js.map +1 -0
  22. package/dist/{chunk-77RLNLFP.js → chunk-ATRJULKZ.js} +41 -5
  23. package/dist/chunk-ATRJULKZ.js.map +1 -0
  24. package/dist/{chunk-VMY4TKMN.js → chunk-FCQP75JT.js} +936 -436
  25. package/dist/chunk-FCQP75JT.js.map +1 -0
  26. package/dist/chunk-I2R2XT4M.js +62 -0
  27. package/dist/chunk-I2R2XT4M.js.map +1 -0
  28. package/dist/{chunk-3PK3T4KD.js → chunk-JJGZ54EB.js} +44 -1
  29. package/dist/chunk-JJGZ54EB.js.map +1 -0
  30. package/dist/chunk-TKVJE63N.js +304 -0
  31. package/dist/chunk-TKVJE63N.js.map +1 -0
  32. package/dist/{chunk-SAOAAA3S.js → chunk-UHXQ3KNX.js} +1 -22
  33. package/dist/chunk-UHXQ3KNX.js.map +1 -0
  34. package/dist/chunk-Y4QHNQ75.js +203 -0
  35. package/dist/chunk-Y4QHNQ75.js.map +1 -0
  36. package/dist/contract-DYbTzEDf.d.ts +122 -0
  37. package/dist/core-7qIM7svy.d.ts +21 -0
  38. package/dist/index.d.ts +6 -2
  39. package/dist/index.js +179 -92
  40. package/dist/interactions/index.d.ts +141 -0
  41. package/dist/interactions/index.js +60 -0
  42. package/dist/interactions/index.js.map +1 -0
  43. package/dist/parts-BcbitSNp.d.ts +176 -0
  44. package/dist/platform/index.d.ts +2 -270
  45. package/dist/platform/index.js +14 -278
  46. package/dist/platform/index.js.map +1 -1
  47. package/dist/preset-cloudflare/index.d.ts +0 -10
  48. package/dist/preset-cloudflare/index.js +1 -1
  49. package/dist/profile/index.d.ts +33 -2
  50. package/dist/profile/index.js +37 -1
  51. package/dist/profile/index.js.map +1 -1
  52. package/dist/sandbox/index.d.ts +47 -1
  53. package/dist/sandbox/index.js +11 -1
  54. package/dist/sso-CNOsARMJ.d.ts +285 -0
  55. package/dist/stream/index.js +1 -1
  56. package/dist/teams/index.js +9 -9
  57. package/dist/teams/invitations-api.js +3 -3
  58. package/dist/web-react/index.d.ts +229 -99
  59. package/dist/web-react/index.js +72 -22
  60. package/dist/wire-BaUF66AS.d.ts +61 -0
  61. package/package.json +25 -1
  62. package/dist/chunk-3PK3T4KD.js.map +0 -1
  63. package/dist/chunk-77RLNLFP.js.map +0 -1
  64. package/dist/chunk-SAOAAA3S.js.map +0 -1
  65. package/dist/chunk-VMY4TKMN.js.map +0 -1
@@ -1,13 +1,21 @@
1
1
  import {
2
2
  stepActivityFlowTrace
3
3
  } from "./chunk-2QI7XV2T.js";
4
+ import {
5
+ cancelStatusFor,
6
+ fieldAcceptsFreeText,
7
+ interactionFromWireRequest,
8
+ isTerminalInteractionStatus,
9
+ parseInteractionRequest,
10
+ questionInteractionContentSignature
11
+ } from "./chunk-4TXDD6P2.js";
4
12
  import {
5
13
  snapHarnessToModel,
6
14
  snapModelToHarness
7
15
  } from "./chunk-E7QYOOON.js";
8
16
 
9
17
  // src/web-react/index.tsx
10
- import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4, useState as useState6, memo } from "react";
18
+ import { useEffect as useEffect5, useMemo as useMemo6, useRef as useRef6, useState as useState9, memo } from "react";
11
19
 
12
20
  // src/web-react/smooth-text.ts
13
21
  import { useEffect, useRef, useState } from "react";
@@ -364,145 +372,6 @@ function BrandMark({ size = 24, className }) {
364
372
  return /* @__PURE__ */ jsx3(Suspense, { fallback: /* @__PURE__ */ jsx3(MarkSpacer, { size, className }), children: /* @__PURE__ */ jsx3(LazyKnot, { size, className }) });
365
373
  }
366
374
 
367
- // src/web-react/chat-interactions.ts
368
- import {
369
- InteractionRequestSchema
370
- } from "@tangle-network/agent-interface";
371
- var INTERACTION_EVENT = "interaction";
372
- var INTERACTION_CANCEL_EVENT = "interaction.cancel";
373
- var INTERACTION_RESOLVED_EVENT = "interaction.resolved";
374
- var RENDERABLE_INTERACTION_KINDS = /* @__PURE__ */ new Set(["question", "plan"]);
375
- function isRenderableInteractionKind(kind) {
376
- return RENDERABLE_INTERACTION_KINDS.has(kind);
377
- }
378
- function isSafeInteractionFieldKey(key) {
379
- return /^[A-Za-z0-9_-]+$/.test(key) && key !== "__proto__" && key !== "constructor" && key !== "prototype";
380
- }
381
- function isTerminalInteractionStatus(status) {
382
- return status !== "pending";
383
- }
384
- function canTransitionInteractionStatus(from, to) {
385
- return from === "pending" && to !== from;
386
- }
387
- function cancelStatusFor(reason) {
388
- return reason === "timeout" ? "expired" : "cancelled";
389
- }
390
- function stableValue(value) {
391
- if (Array.isArray(value)) return value.map(stableValue);
392
- if (!value || typeof value !== "object") return value;
393
- return Object.fromEntries(
394
- Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, nested]) => [key, stableValue(nested)])
395
- );
396
- }
397
- function normalizedInteractionText(value) {
398
- return (value ?? "").replace(/\s+/g, " ").trim();
399
- }
400
- function questionInteractionContentSignature(interaction) {
401
- if (interaction.kind !== "question") return null;
402
- return JSON.stringify(stableValue({
403
- kind: interaction.kind,
404
- title: normalizedInteractionText(interaction.title),
405
- body: normalizedInteractionText(interaction.body),
406
- fields: interaction.fields
407
- }));
408
- }
409
- function dedupeQuestionInteractionsByContent(interactions) {
410
- const seen = /* @__PURE__ */ new Set();
411
- return interactions.filter((interaction) => {
412
- const signature = questionInteractionContentSignature(interaction);
413
- if (!signature) return true;
414
- if (seen.has(signature)) return false;
415
- seen.add(signature);
416
- return true;
417
- });
418
- }
419
- function parseInteractionRequest(data) {
420
- const request = data?.request;
421
- if (!request || typeof request !== "object") {
422
- return { succeeded: false, error: "interaction event carried no request object" };
423
- }
424
- const validation = InteractionRequestSchema.safeParse(request);
425
- if (!validation.success) {
426
- return { succeeded: false, error: `malformed interaction request: ${validation.error.message}` };
427
- }
428
- return { succeeded: true, value: request };
429
- }
430
- function parseInteractionCancel(data) {
431
- const id = typeof data?.id === "string" && data.id ? data.id : null;
432
- if (!id) return { succeeded: false, error: "interaction.cancel event carried no id" };
433
- const reason = typeof data?.reason === "string" && data.reason ? data.reason : void 0;
434
- return { succeeded: true, value: { id, ...reason ? { reason } : {} } };
435
- }
436
- function fieldAcceptsFreeText(field) {
437
- if (field.type === "text") return true;
438
- if (field.type === "select") return field.allowCustom === true;
439
- return false;
440
- }
441
- function composerAnswerDeliveries(pending) {
442
- const deliveries = [];
443
- for (const interaction of pending) {
444
- if (interaction.kind !== "question") continue;
445
- const field = interaction.fields.find(fieldAcceptsFreeText) ?? interaction.fields[0];
446
- if (!field) continue;
447
- deliveries.push({ interactionId: interaction.id, field });
448
- }
449
- return deliveries;
450
- }
451
- function composerAnswerData(field, text) {
452
- return { [field.name]: field.type === "select" ? [text] : text };
453
- }
454
- function interactionPartKey(id) {
455
- return `interaction:${id}`;
456
- }
457
- function noticePartKey(id) {
458
- return `notice:${id}`;
459
- }
460
- function noticePart(noticeKind, id, text) {
461
- return { type: "notice", id, noticeKind, text };
462
- }
463
- function interactionFromWireRequest(request) {
464
- return {
465
- id: request.id,
466
- kind: request.kind,
467
- title: request.title,
468
- ...request.body ? { body: request.body } : {},
469
- fields: request.answerSpec.fields,
470
- status: "pending"
471
- };
472
- }
473
- function interactionToPersistedPart(request, status, cancelReason) {
474
- return {
475
- type: "interaction",
476
- id: request.id,
477
- kind: request.kind,
478
- title: request.title,
479
- ...request.body ? { body: request.body } : {},
480
- answerSpec: { fields: request.answerSpec.fields },
481
- status,
482
- ...cancelReason ? { cancelReason } : {}
483
- };
484
- }
485
- function persistedPartToInteraction(part) {
486
- if (String(part.type ?? "") !== "interaction") return null;
487
- const id = typeof part.id === "string" && part.id ? part.id : null;
488
- const kind = typeof part.kind === "string" && part.kind ? part.kind : null;
489
- const title = typeof part.title === "string" ? part.title : "";
490
- const answerSpec = part.answerSpec;
491
- const fields = Array.isArray(answerSpec?.fields) ? answerSpec.fields : null;
492
- const status = part.status;
493
- const validStatus = status && ["pending", "answered", "declined", "cancelled", "expired"].includes(status);
494
- if (!id || !kind || !fields || !validStatus) return null;
495
- return {
496
- id,
497
- kind,
498
- title,
499
- ...typeof part.body === "string" && part.body ? { body: part.body } : {},
500
- fields,
501
- status,
502
- ...typeof part.cancelReason === "string" && part.cancelReason ? { cancelReason: part.cancelReason } : {}
503
- };
504
- }
505
-
506
375
  // src/web-react/chat-stream.ts
507
376
  function dispatchChatStreamLine(line, cb) {
508
377
  let receivedContent = false;
@@ -578,9 +447,19 @@ function dispatchChatStreamLine(line, cb) {
578
447
  }
579
448
  break;
580
449
  }
581
- case "error":
582
- cb.onErrorEvent?.(String(evt.details ?? evt.error ?? "Unknown stream error"));
450
+ case "error": {
451
+ const message = String(evt.details ?? evt.error ?? "Unknown stream error");
452
+ if (cb.onErrorEvent) {
453
+ cb.onErrorEvent(message);
454
+ } else {
455
+ console.error("[chat-stream] unhandled stream error event:", message);
456
+ cb.onText?.(`
457
+
458
+ The agent hit an error and this turn stopped: ${message}`);
459
+ receivedContent = true;
460
+ }
583
461
  break;
462
+ }
584
463
  default:
585
464
  break;
586
465
  }
@@ -670,6 +549,7 @@ function UploadGlyph({ className }) {
670
549
  var MAX_HEIGHT = 168;
671
550
  function ChatComposer({
672
551
  onSend,
552
+ onSendParts,
673
553
  onCancel,
674
554
  isStreaming = false,
675
555
  disabled = false,
@@ -722,13 +602,23 @@ function ChatComposer({
722
602
  document.addEventListener("keydown", onKeyDown);
723
603
  return () => document.removeEventListener("keydown", onKeyDown);
724
604
  }, [focusShortcut, disabled]);
725
- const canSend = text.trim().length > 0 && !isStreaming && !disabled;
605
+ const readyParts = pendingFiles.filter((f) => f.status === "ready" && f.part).map((f) => f.part);
606
+ const hasSendable = onSendParts ? text.trim().length > 0 || readyParts.length > 0 : text.trim().length > 0;
607
+ const canSend = hasSendable && !isStreaming && !disabled;
726
608
  const send = useCallback(() => {
727
609
  const trimmed = text.trim();
728
- if (!trimmed || isStreaming || disabled) return;
729
- onSend(trimmed);
610
+ if (isStreaming || disabled) return;
611
+ if (onSendParts) {
612
+ const parts = pendingFiles.filter((f) => f.status === "ready" && f.part).map((f) => f.part);
613
+ if (!trimmed && parts.length === 0) return;
614
+ onSendParts(trimmed, parts);
615
+ setText("");
616
+ return;
617
+ }
618
+ if (!trimmed) return;
619
+ onSend?.(trimmed);
730
620
  setText("");
731
- }, [text, isStreaming, disabled, onSend, setText]);
621
+ }, [text, isStreaming, disabled, onSend, onSendParts, pendingFiles, setText]);
732
622
  const handleKeyDown = (e) => {
733
623
  if (e.nativeEvent.isComposing) return;
734
624
  if (e.key === "Enter" && !e.shiftKey) {
@@ -914,9 +804,618 @@ function ChatComposer({
914
804
  );
915
805
  }
916
806
 
917
- // src/web-react/mission-activity.tsx
918
- import { useCallback as useCallback2, useEffect as useEffect4, useState as useState4 } from "react";
807
+ // src/web-react/interaction-card-support.ts
808
+ function interactionStatusLabels(labels) {
809
+ return { cancelled: "Withdrawn", expired: "Expired", ...labels };
810
+ }
811
+ function interactionTerminalNotes(noun, extra) {
812
+ return {
813
+ expired: `This ${noun} expired \u2014 send a new message to continue.`,
814
+ cancelled: `The agent withdrew this ${noun}.`,
815
+ ...extra
816
+ };
817
+ }
818
+ function fieldAnswer(field, values) {
819
+ const value = values[field.name] ?? {};
820
+ if (field.type === "select") {
821
+ const custom = field.allowCustom === true ? value.custom?.trim() : void 0;
822
+ const chosen = [...value.selected ?? [], ...custom ? [custom] : []];
823
+ if (field.multi !== true && custom) return [custom];
824
+ return chosen.length > 0 ? chosen : null;
825
+ }
826
+ if (field.type === "number") {
827
+ const parsed = Number(value.text);
828
+ return value.text?.trim() && Number.isFinite(parsed) ? parsed : null;
829
+ }
830
+ if (field.type === "boolean") return value.selected ? value.selected[0] === "true" : null;
831
+ const text = value.text?.trim();
832
+ return text ? text : null;
833
+ }
834
+ function buildAnswerData(fields, values) {
835
+ const data = {};
836
+ for (const field of fields) {
837
+ const answer = fieldAnswer(field, values);
838
+ if (answer === null) {
839
+ if (field.required === false) continue;
840
+ return null;
841
+ }
842
+ data[field.name] = answer;
843
+ }
844
+ return data;
845
+ }
846
+ function isLateAnswerableStatus(status) {
847
+ return status === "expired" || status === "cancelled";
848
+ }
849
+ function hasSecretField(fields) {
850
+ return fields.some((field) => field.type === "secret");
851
+ }
852
+ function optionLabel(field, value) {
853
+ return field.options.find((option) => option.value === value)?.label ?? value;
854
+ }
855
+ function answerText(field, answer) {
856
+ if (field.type === "select" && Array.isArray(answer)) {
857
+ return answer.map((value) => optionLabel(field, value)).join(", ");
858
+ }
859
+ if (field.type === "boolean") return answer === true ? "Yes" : "No";
860
+ if (field.type === "secret") return "[secret omitted]";
861
+ return String(answer);
862
+ }
863
+ function lateAnswerMessage(interaction, data) {
864
+ const title = interaction.title.trim() || "the earlier question";
865
+ const body = interaction.body?.trim();
866
+ const answers = interaction.fields.map((field) => {
867
+ const answer = data[field.name];
868
+ if (answer === void 0) return null;
869
+ return { label: field.label.trim(), text: answerText(field, answer).trim() };
870
+ }).filter((item) => !!item && item.text.length > 0);
871
+ const only = answers.length === 1 ? answers[0] : void 0;
872
+ const answerSummary = only ? only.text : answers.map((item) => `${item.label || "Answer"}: ${item.text}`).join("\n");
873
+ return [
874
+ `Regarding your earlier question: "${title}"`,
875
+ body ? `Context: ${body}` : null,
876
+ `My answer: ${answerSummary}`
877
+ ].filter((line) => !!line).join("\n");
878
+ }
879
+ var INTERACTION_SUBMIT_TIMEOUT_MS = 3e4;
880
+ var INTERACTION_SUBMIT_TIMEOUT_MESSAGE = "Could not reach the agent. Try again.";
881
+ async function responseErrorMessage(res) {
882
+ const text = await res.text().catch(() => "");
883
+ if (text) {
884
+ try {
885
+ const parsed = JSON.parse(text);
886
+ const message = typeof parsed.error === "string" && parsed.error.trim() ? parsed.error : typeof parsed.message === "string" && parsed.message.trim() ? parsed.message : null;
887
+ if (message) return { ...typeof parsed.code === "string" ? { code: parsed.code } : {}, message };
888
+ } catch {
889
+ }
890
+ }
891
+ return { message: `Answer failed (${res.status})` };
892
+ }
893
+ function createInteractionAnswerSubmitter(options) {
894
+ const timeoutMs = options.timeoutMs ?? INTERACTION_SUBMIT_TIMEOUT_MS;
895
+ return async (submission) => {
896
+ const doFetch = options.fetchImpl ?? fetch;
897
+ const url = typeof options.url === "function" ? options.url(submission) : options.url;
898
+ const extra = typeof options.body === "function" ? options.body(submission) : options.body ?? {};
899
+ const controller = new AbortController();
900
+ const timer = setTimeout(() => controller.abort(INTERACTION_SUBMIT_TIMEOUT_MESSAGE), timeoutMs);
901
+ try {
902
+ const res = await doFetch(url, {
903
+ method: "POST",
904
+ headers: { "Content-Type": "application/json" },
905
+ signal: controller.signal,
906
+ body: JSON.stringify({
907
+ ...extra,
908
+ id: submission.id,
909
+ outcome: submission.outcome,
910
+ ...submission.data ? { data: submission.data } : {}
911
+ })
912
+ });
913
+ if (res.ok) return { ok: true };
914
+ const failure = await responseErrorMessage(res);
915
+ return { ok: false, expired: res.status === 410, message: failure.message };
916
+ } catch (err) {
917
+ if (controller.signal.aborted) {
918
+ return { ok: false, expired: false, message: INTERACTION_SUBMIT_TIMEOUT_MESSAGE };
919
+ }
920
+ return { ok: false, expired: false, message: err instanceof Error ? err.message : "Failed to submit the answer" };
921
+ } finally {
922
+ clearTimeout(timer);
923
+ }
924
+ };
925
+ }
926
+
927
+ // src/web-react/interaction-question-card.tsx
928
+ import { useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
919
929
  import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
930
+ function CheckGlyph({ className }) {
931
+ return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "M20 6 9 17l-5-5" }) });
932
+ }
933
+ var BADGE_VARIANT_CLASSES = {
934
+ outline: "border-border text-foreground",
935
+ default: "border-transparent bg-primary text-primary-foreground",
936
+ destructive: "border-transparent bg-destructive/15 text-destructive"
937
+ };
938
+ function InteractionBadge({ variant, children }) {
939
+ return /* @__PURE__ */ jsx5("span", { className: `inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium ${BADGE_VARIANT_CLASSES[variant]}`, children });
940
+ }
941
+ function InteractionActionButton({
942
+ variant = "primary",
943
+ onClick,
944
+ disabled,
945
+ children
946
+ }) {
947
+ const variantClasses = variant === "primary" ? "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90" : "border border-border bg-transparent text-foreground hover:bg-accent/40";
948
+ return /* @__PURE__ */ jsx5(
949
+ "button",
950
+ {
951
+ type: "button",
952
+ onClick,
953
+ disabled,
954
+ className: `inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium transition disabled:cursor-not-allowed disabled:opacity-40 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${variantClasses}`,
955
+ children
956
+ }
957
+ );
958
+ }
959
+ var FIELD_INPUT_CLASSES = "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50";
960
+ function QuestionOptionList({
961
+ groupName,
962
+ idPrefix,
963
+ options,
964
+ multi,
965
+ selectedValues,
966
+ disabled,
967
+ onToggle
968
+ }) {
969
+ return /* @__PURE__ */ jsx5(Fragment3, { children: options.map((option, optionIndex) => {
970
+ const inputId = `${idPrefix}-${optionIndex}`;
971
+ const checked = selectedValues.includes(option.value);
972
+ return /* @__PURE__ */ jsxs4("label", { htmlFor: inputId, className: "flex cursor-pointer gap-2 rounded-lg border border-border/70 p-3 transition-colors hover:bg-muted/50", children: [
973
+ /* @__PURE__ */ jsx5(
974
+ "input",
975
+ {
976
+ id: inputId,
977
+ type: multi ? "checkbox" : "radio",
978
+ name: groupName,
979
+ value: option.value,
980
+ checked,
981
+ disabled,
982
+ onChange: () => onToggle(option.value),
983
+ "aria-labelledby": `${inputId}-label`,
984
+ "aria-describedby": option.description ? `${inputId}-description` : void 0,
985
+ className: "mt-0.5 h-4 w-4 shrink-0 accent-primary"
986
+ }
987
+ ),
988
+ /* @__PURE__ */ jsxs4("span", { className: "min-w-0", children: [
989
+ /* @__PURE__ */ jsx5("span", { id: `${inputId}-label`, className: "block text-sm font-medium leading-5 text-foreground", children: option.label }),
990
+ option.description && /* @__PURE__ */ jsx5("span", { id: `${inputId}-description`, className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: option.description })
991
+ ] })
992
+ ] }, `${option.value}-${optionIndex}`);
993
+ }) });
994
+ }
995
+ function selectField(field) {
996
+ return field.type === "select" ? field : null;
997
+ }
998
+ function valuesWithSelected(values, field, optionValue) {
999
+ const current = values[field.name]?.selected ?? [];
1000
+ let selected = [optionValue];
1001
+ if (field.multi === true) {
1002
+ selected = current.includes(optionValue) ? current.filter((item) => item !== optionValue) : [...current, optionValue];
1003
+ }
1004
+ return { ...values, [field.name]: { ...values[field.name], selected } };
1005
+ }
1006
+ var STATUS_LABELS = interactionStatusLabels({
1007
+ pending: "Waiting for your answer",
1008
+ answered: "Answered",
1009
+ declined: "Declined"
1010
+ });
1011
+ var TERMINAL_NOTES = interactionTerminalNotes("question", {
1012
+ expired: "The original run ended. Answer now to send a new message with this context.",
1013
+ cancelled: "The agent withdrew this question. Answer now to send a new message with this context."
1014
+ });
1015
+ function InteractionQuestionCard({
1016
+ interaction,
1017
+ canWrite,
1018
+ submitAnswer,
1019
+ onResolved,
1020
+ onLateAnswer,
1021
+ className
1022
+ }) {
1023
+ const [values, setValues] = useState4({});
1024
+ const [submitting, setSubmitting] = useState4(false);
1025
+ const [localStatus, setLocalStatus] = useState4(null);
1026
+ const [lateAnswerSent, setLateAnswerSent] = useState4(false);
1027
+ const [error, setError] = useState4(null);
1028
+ const submitInFlightRef = useRef4(false);
1029
+ const status = isTerminalInteractionStatus(interaction.status) ? interaction.status : localStatus ?? interaction.status;
1030
+ const answered = status === "answered";
1031
+ const lateAnswerable = isLateAnswerableStatus(status) && onLateAnswer !== void 0;
1032
+ const secretLateAnswerBlocked = lateAnswerable && hasSecretField(interaction.fields);
1033
+ const canLateAnswer = canWrite && lateAnswerable && !lateAnswerSent && !secretLateAnswerBlocked;
1034
+ const disabled = !canWrite || status !== "pending" && !canLateAnswer || submitting;
1035
+ const answerData = useMemo2(() => buildAnswerData(interaction.fields, values), [interaction.fields, values]);
1036
+ const setFieldValue = (name, patch) => {
1037
+ setValues((prev) => ({ ...prev, [name]: { ...prev[name], ...patch } }));
1038
+ };
1039
+ const toggleSelected = (field, optionValue) => {
1040
+ setValues((prev) => valuesWithSelected(prev, field, optionValue));
1041
+ };
1042
+ async function submitLateAnswer() {
1043
+ if (submitInFlightRef.current || !canLateAnswer || !onLateAnswer) return;
1044
+ const data = buildAnswerData(interaction.fields, values);
1045
+ if (!data) return;
1046
+ submitInFlightRef.current = true;
1047
+ setSubmitting(true);
1048
+ setError(null);
1049
+ let accepted;
1050
+ try {
1051
+ accepted = await onLateAnswer(lateAnswerMessage(interaction, data));
1052
+ } catch {
1053
+ accepted = false;
1054
+ } finally {
1055
+ submitInFlightRef.current = false;
1056
+ setSubmitting(false);
1057
+ }
1058
+ if (accepted === false) {
1059
+ setError("The new message was not sent. Try again from this card.");
1060
+ return;
1061
+ }
1062
+ setLateAnswerSent(true);
1063
+ }
1064
+ async function submit() {
1065
+ if (lateAnswerable) {
1066
+ await submitLateAnswer();
1067
+ return;
1068
+ }
1069
+ if (submitInFlightRef.current || disabled || !answerData) return;
1070
+ submitInFlightRef.current = true;
1071
+ setSubmitting(true);
1072
+ setError(null);
1073
+ try {
1074
+ const result = await submitAnswer({ id: interaction.id, outcome: "accepted", data: answerData });
1075
+ if (result.ok) {
1076
+ setLocalStatus("answered");
1077
+ onResolved?.(interaction.id, "answered");
1078
+ return;
1079
+ }
1080
+ if (result.expired) {
1081
+ setLocalStatus("expired");
1082
+ onResolved?.(interaction.id, "expired");
1083
+ return;
1084
+ }
1085
+ setError(result.message);
1086
+ } finally {
1087
+ submitInFlightRef.current = false;
1088
+ setSubmitting(false);
1089
+ }
1090
+ }
1091
+ const terminalNote = secretLateAnswerBlocked ? "This question asked for a secret, so it cannot be sent as a new chat message. Ask the agent to request it again." : TERMINAL_NOTES[status];
1092
+ const showSubmitButton = status === "pending" || canWrite && lateAnswerable && !lateAnswerSent;
1093
+ let submitLabel = "Submit answer";
1094
+ if (lateAnswerable) {
1095
+ submitLabel = submitting ? "Sending\u2026" : "Send as new message";
1096
+ } else if (submitting) {
1097
+ submitLabel = "Submitting\u2026";
1098
+ }
1099
+ return /* @__PURE__ */ jsxs4("div", { className: `rounded-xl border border-border bg-card p-4 shadow-sm ${className ?? ""}`, children: [
1100
+ /* @__PURE__ */ jsxs4("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
1101
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2", children: [
1102
+ /* @__PURE__ */ jsx5(InteractionBadge, { variant: "outline", children: "Question" }),
1103
+ /* @__PURE__ */ jsx5(InteractionBadge, { variant: answered ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS[status] })
1104
+ ] }),
1105
+ /* @__PURE__ */ jsx5("span", { className: "text-xs text-muted-foreground", children: "The agent asked for input" })
1106
+ ] }),
1107
+ interaction.title.trim() && interaction.fields.every((field) => field.label !== interaction.title) && /* @__PURE__ */ jsx5("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: interaction.title }),
1108
+ interaction.body && /* @__PURE__ */ jsx5("p", { className: "mb-3 text-sm leading-5 text-muted-foreground", children: interaction.body }),
1109
+ /* @__PURE__ */ jsx5("div", { className: "space-y-4", children: interaction.fields.map((field) => {
1110
+ const value = values[field.name] ?? {};
1111
+ const select = selectField(field);
1112
+ return /* @__PURE__ */ jsxs4("fieldset", { className: "space-y-2", children: [
1113
+ /* @__PURE__ */ jsx5("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
1114
+ select ? /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1115
+ /* @__PURE__ */ jsx5(
1116
+ QuestionOptionList,
1117
+ {
1118
+ groupName: `${interaction.id}-${field.name}`,
1119
+ idPrefix: `${interaction.id}-${field.name}`,
1120
+ options: select.options,
1121
+ multi: select.multi === true,
1122
+ selectedValues: value.selected ?? [],
1123
+ disabled,
1124
+ onToggle: (optionValue) => toggleSelected(select, optionValue)
1125
+ }
1126
+ ),
1127
+ select.allowCustom === true && /* @__PURE__ */ jsx5(
1128
+ "input",
1129
+ {
1130
+ type: "text",
1131
+ value: value.custom ?? "",
1132
+ disabled,
1133
+ onChange: (event) => setFieldValue(field.name, { custom: event.target.value }),
1134
+ placeholder: "Other \u2014 type your own answer",
1135
+ "aria-label": `Custom answer for ${field.label}`,
1136
+ className: FIELD_INPUT_CLASSES
1137
+ }
1138
+ )
1139
+ ] }) : field.type === "boolean" ? /* @__PURE__ */ jsx5("div", { className: "flex gap-4", children: ["true", "false"].map((boolValue) => /* @__PURE__ */ jsxs4("label", { className: "flex cursor-pointer items-center gap-2 text-sm text-foreground", children: [
1140
+ /* @__PURE__ */ jsx5(
1141
+ "input",
1142
+ {
1143
+ type: "radio",
1144
+ name: `${interaction.id}-${field.name}`,
1145
+ value: boolValue,
1146
+ checked: (value.selected ?? [])[0] === boolValue,
1147
+ disabled,
1148
+ onChange: () => setFieldValue(field.name, { selected: [boolValue] }),
1149
+ className: "h-4 w-4 accent-primary"
1150
+ }
1151
+ ),
1152
+ boolValue === "true" ? "Yes" : "No"
1153
+ ] }, boolValue)) }) : field.type === "number" ? /* @__PURE__ */ jsx5(
1154
+ "input",
1155
+ {
1156
+ type: "number",
1157
+ value: value.text ?? "",
1158
+ disabled,
1159
+ "aria-label": field.label,
1160
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
1161
+ className: FIELD_INPUT_CLASSES
1162
+ }
1163
+ ) : field.type === "secret" ? /* @__PURE__ */ jsx5(
1164
+ "input",
1165
+ {
1166
+ type: "password",
1167
+ value: value.text ?? "",
1168
+ disabled,
1169
+ "aria-label": field.label,
1170
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
1171
+ placeholder: field.placeholder,
1172
+ className: FIELD_INPUT_CLASSES
1173
+ }
1174
+ ) : /* @__PURE__ */ jsx5(
1175
+ "textarea",
1176
+ {
1177
+ value: value.text ?? "",
1178
+ disabled,
1179
+ "aria-label": field.label,
1180
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
1181
+ rows: 3,
1182
+ placeholder: field.type === "text" ? field.placeholder : void 0,
1183
+ className: FIELD_INPUT_CLASSES
1184
+ }
1185
+ )
1186
+ ] }, field.name);
1187
+ }) }),
1188
+ error && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-xs text-destructive", children: error }),
1189
+ terminalNote && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
1190
+ showSubmitButton && /* @__PURE__ */ jsx5("div", { className: "mt-4 flex items-center justify-end gap-2", children: /* @__PURE__ */ jsx5(InteractionActionButton, { onClick: () => void submit(), disabled: disabled || !answerData, children: submitLabel }) }),
1191
+ answered && /* @__PURE__ */ jsx5("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
1192
+ /* @__PURE__ */ jsx5(CheckGlyph, { className: "h-3 w-3" }),
1193
+ "Answered"
1194
+ ] }) }),
1195
+ lateAnswerSent && /* @__PURE__ */ jsx5("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
1196
+ /* @__PURE__ */ jsx5(CheckGlyph, { className: "h-3 w-3" }),
1197
+ "Sent as new message"
1198
+ ] }) })
1199
+ ] });
1200
+ }
1201
+
1202
+ // src/web-react/interaction-plan-card.tsx
1203
+ import { useMemo as useMemo3, useRef as useRef5, useState as useState5 } from "react";
1204
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1205
+ function CheckGlyph2({ className }) {
1206
+ return /* @__PURE__ */ jsx6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" }) });
1207
+ }
1208
+ function ChevronDownGlyph({ className }) {
1209
+ return /* @__PURE__ */ jsx6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "m6 9 6 6 6-6" }) });
1210
+ }
1211
+ var STATUS_LABELS2 = interactionStatusLabels({
1212
+ pending: "Waiting for your approval",
1213
+ answered: "Approved",
1214
+ declined: "Rejected"
1215
+ });
1216
+ var TERMINAL_NOTES2 = interactionTerminalNotes("plan", {
1217
+ declined: "The agent was asked to revise the plan."
1218
+ });
1219
+ var COLLAPSED_MAX_HEIGHT = 320;
1220
+ function InteractionPlanCard({
1221
+ interaction,
1222
+ canWrite,
1223
+ submitAnswer,
1224
+ onResolved,
1225
+ renderMarkdown,
1226
+ className
1227
+ }) {
1228
+ const [values, setValues] = useState5({});
1229
+ const [expanded, setExpanded] = useState5(false);
1230
+ const [submitting, setSubmitting] = useState5(null);
1231
+ const [localStatus, setLocalStatus] = useState5(null);
1232
+ const [error, setError] = useState5(null);
1233
+ const submitInFlightRef = useRef5(false);
1234
+ const status = isTerminalInteractionStatus(interaction.status) ? interaction.status : localStatus ?? interaction.status;
1235
+ const disabled = !canWrite || status !== "pending" || submitting !== null;
1236
+ const approveData = useMemo3(() => buildAnswerData(interaction.fields, values), [interaction.fields, values]);
1237
+ const rejectData = useMemo3(() => {
1238
+ const data = {};
1239
+ for (const field of interaction.fields) {
1240
+ const answer = fieldAnswer(field, values);
1241
+ if (answer !== null) data[field.name] = answer;
1242
+ }
1243
+ return data;
1244
+ }, [interaction.fields, values]);
1245
+ async function submit(outcome) {
1246
+ const data = outcome === "accepted" ? approveData : rejectData;
1247
+ if (submitInFlightRef.current || disabled || data === null) return;
1248
+ submitInFlightRef.current = true;
1249
+ setSubmitting(outcome === "accepted" ? "approve" : "reject");
1250
+ setError(null);
1251
+ try {
1252
+ const result = await submitAnswer({ id: interaction.id, outcome, data });
1253
+ if (result.ok) {
1254
+ const resolved = outcome === "accepted" ? "answered" : "declined";
1255
+ setLocalStatus(resolved);
1256
+ onResolved?.(interaction.id, resolved);
1257
+ return;
1258
+ }
1259
+ if (result.expired) {
1260
+ setLocalStatus("expired");
1261
+ onResolved?.(interaction.id, "expired");
1262
+ return;
1263
+ }
1264
+ setError(result.message);
1265
+ } finally {
1266
+ submitInFlightRef.current = false;
1267
+ setSubmitting(null);
1268
+ }
1269
+ }
1270
+ const terminalNote = TERMINAL_NOTES2[status];
1271
+ const approved = status === "answered";
1272
+ return /* @__PURE__ */ jsxs5("div", { className: `rounded-xl border border-border bg-card p-4 shadow-sm ${className ?? ""}`, children: [
1273
+ /* @__PURE__ */ jsxs5("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
1274
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2", children: [
1275
+ /* @__PURE__ */ jsx6(InteractionBadge, { variant: "outline", children: "Plan" }),
1276
+ /* @__PURE__ */ jsx6(InteractionBadge, { variant: approved ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS2[status] })
1277
+ ] }),
1278
+ /* @__PURE__ */ jsx6("span", { className: "text-xs text-muted-foreground", children: "The agent proposed a plan" })
1279
+ ] }),
1280
+ interaction.title.trim() && /* @__PURE__ */ jsx6("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: interaction.title }),
1281
+ interaction.body && /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
1282
+ /* @__PURE__ */ jsx6(
1283
+ "div",
1284
+ {
1285
+ className: "overflow-hidden text-sm text-foreground",
1286
+ style: expanded ? void 0 : { maxHeight: COLLAPSED_MAX_HEIGHT },
1287
+ children: renderMarkdown ? renderMarkdown(interaction.body) : /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap leading-5", children: interaction.body })
1288
+ }
1289
+ ),
1290
+ !expanded && /* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-card to-transparent" }),
1291
+ /* @__PURE__ */ jsxs5(
1292
+ "button",
1293
+ {
1294
+ type: "button",
1295
+ onClick: () => setExpanded((prev) => !prev),
1296
+ className: "mt-1 inline-flex items-center gap-1 text-xs text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1297
+ children: [
1298
+ /* @__PURE__ */ jsx6(ChevronDownGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
1299
+ expanded ? "Collapse plan" : "Show full plan"
1300
+ ]
1301
+ }
1302
+ )
1303
+ ] }),
1304
+ interaction.fields.length > 0 && /* @__PURE__ */ jsx6("div", { className: "mt-3 space-y-4", children: interaction.fields.map((field) => /* @__PURE__ */ jsxs5("fieldset", { className: "space-y-2", children: [
1305
+ /* @__PURE__ */ jsx6("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
1306
+ fieldAcceptsFreeText(field) ? /* @__PURE__ */ jsx6(
1307
+ "textarea",
1308
+ {
1309
+ value: values[field.name]?.text ?? "",
1310
+ disabled,
1311
+ "aria-label": field.label,
1312
+ onChange: (event) => setValues((prev) => ({ ...prev, [field.name]: { ...prev[field.name], text: event.target.value } })),
1313
+ rows: 2,
1314
+ placeholder: field.type === "text" ? field.placeholder ?? "Optional feedback for the agent" : void 0,
1315
+ className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50"
1316
+ }
1317
+ ) : /* @__PURE__ */ jsx6(
1318
+ "input",
1319
+ {
1320
+ type: "text",
1321
+ value: values[field.name]?.text ?? "",
1322
+ disabled,
1323
+ "aria-label": field.label,
1324
+ onChange: (event) => setValues((prev) => ({ ...prev, [field.name]: { ...prev[field.name], text: event.target.value } })),
1325
+ className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50"
1326
+ }
1327
+ )
1328
+ ] }, field.name)) }),
1329
+ error && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-xs text-destructive", children: error }),
1330
+ terminalNote && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
1331
+ status === "pending" && /* @__PURE__ */ jsxs5("div", { className: "mt-4 flex items-center justify-end gap-2", children: [
1332
+ /* @__PURE__ */ jsx6(InteractionActionButton, { variant: "outline", onClick: () => void submit("declined"), disabled, children: submitting === "reject" ? "Sending\u2026" : "Request changes" }),
1333
+ /* @__PURE__ */ jsx6(InteractionActionButton, { onClick: () => void submit("accepted"), disabled: disabled || approveData === null, children: submitting === "approve" ? "Approving\u2026" : "Approve plan" })
1334
+ ] }),
1335
+ approved && /* @__PURE__ */ jsx6("div", { className: "mt-4 flex items-center justify-end", children: /* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
1336
+ /* @__PURE__ */ jsx6(CheckGlyph2, { className: "h-3 w-3" }),
1337
+ "Approved"
1338
+ ] }) })
1339
+ ] });
1340
+ }
1341
+
1342
+ // src/web-react/use-chat-interactions.ts
1343
+ import { useCallback as useCallback2, useMemo as useMemo4, useState as useState6 } from "react";
1344
+ function hasPendingContentDuplicate(list, interaction) {
1345
+ if (interaction.status !== "pending") return false;
1346
+ const signature = questionInteractionContentSignature(interaction);
1347
+ if (!signature) return false;
1348
+ return list.some((item) => item.id !== interaction.id && item.status === "pending" && questionInteractionContentSignature(item) === signature);
1349
+ }
1350
+ function upsertChatInteraction(list, interaction) {
1351
+ const index = list.findIndex((item) => item.id === interaction.id);
1352
+ if (index === -1) {
1353
+ if (hasPendingContentDuplicate(list, interaction)) return list;
1354
+ return [...list, interaction];
1355
+ }
1356
+ const existing = list[index];
1357
+ if (!existing || isTerminalInteractionStatus(existing.status)) return list;
1358
+ const next = [...list];
1359
+ next[index] = interaction;
1360
+ return next;
1361
+ }
1362
+ function cancelChatInteraction(list, cancel) {
1363
+ const index = list.findIndex((item) => item.id === cancel.id);
1364
+ const existing = list[index];
1365
+ if (!existing || existing.status !== "pending") return list;
1366
+ const next = [...list];
1367
+ next[index] = {
1368
+ ...existing,
1369
+ status: cancelStatusFor(cancel.reason),
1370
+ ...cancel.reason ? { cancelReason: cancel.reason } : {}
1371
+ };
1372
+ return next;
1373
+ }
1374
+ function resolveChatInteraction(list, id, status) {
1375
+ const index = list.findIndex((item) => item.id === id);
1376
+ const existing = list[index];
1377
+ if (!existing || existing.status !== "pending") return list;
1378
+ const next = [...list];
1379
+ next[index] = { ...existing, status };
1380
+ return next;
1381
+ }
1382
+ function terminalizePendingChatInteractions(list, status) {
1383
+ if (!list.some((item) => item.status === "pending")) return list;
1384
+ return list.map((item) => item.status === "pending" ? { ...item, status } : item);
1385
+ }
1386
+ function restoreChatInteractions(list, outstanding) {
1387
+ const outstandingIds = new Set(outstanding.map((request) => request.id));
1388
+ let next = list.map((item) => item.status === "pending" && !outstandingIds.has(item.id) ? { ...item, status: "answered" } : item);
1389
+ for (const request of outstanding) {
1390
+ next = upsertChatInteraction(next, interactionFromWireRequest(request));
1391
+ }
1392
+ return next;
1393
+ }
1394
+ function useChatInteractions() {
1395
+ const [interactions, setInteractions] = useState6([]);
1396
+ const upsert = useCallback2((interaction) => {
1397
+ setInteractions((prev) => upsertChatInteraction(prev, interaction));
1398
+ }, []);
1399
+ const applyCancel = useCallback2((cancel) => {
1400
+ setInteractions((prev) => cancelChatInteraction(prev, cancel));
1401
+ }, []);
1402
+ const markResolved = useCallback2((id, status) => {
1403
+ setInteractions((prev) => resolveChatInteraction(prev, id, status));
1404
+ }, []);
1405
+ const restore = useCallback2((outstanding) => {
1406
+ setInteractions((prev) => restoreChatInteractions(prev, outstanding));
1407
+ }, []);
1408
+ const terminalizePending = useCallback2((status) => {
1409
+ setInteractions((prev) => terminalizePendingChatInteractions(prev, status));
1410
+ }, []);
1411
+ const reset = useCallback2(() => setInteractions([]), []);
1412
+ const pending = useMemo4(() => interactions.filter((item) => item.status === "pending"), [interactions]);
1413
+ return { interactions, pending, upsert, applyCancel, markResolved, restore, terminalizePending, reset };
1414
+ }
1415
+
1416
+ // src/web-react/mission-activity.tsx
1417
+ import { useCallback as useCallback3, useEffect as useEffect4, useState as useState7 } from "react";
1418
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
920
1419
  var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
921
1420
  var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
922
1421
  var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
@@ -963,20 +1462,20 @@ function waterfallLayout(trace) {
963
1462
  });
964
1463
  }
965
1464
  function ChevronGlyph({ className }) {
966
- return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "m6 9 6 6 6-6" }) });
1465
+ 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: "m6 9 6 6 6-6" }) });
967
1466
  }
968
1467
  function RefreshGlyph({ className }) {
969
- return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
1468
+ 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: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
970
1469
  }
971
1470
  function CopyGlyph({ className }) {
972
- return /* @__PURE__ */ jsxs4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
973
- /* @__PURE__ */ jsx5("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
974
- /* @__PURE__ */ jsx5("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
1471
+ return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1472
+ /* @__PURE__ */ jsx7("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
1473
+ /* @__PURE__ */ jsx7("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
975
1474
  ] });
976
1475
  }
977
1476
  function TraceIdCopy({ traceId }) {
978
- const [copied, setCopied] = useState4(false);
979
- const copy = useCallback2(() => {
1477
+ const [copied, setCopied] = useState7(false);
1478
+ const copy = useCallback3(() => {
980
1479
  void navigator.clipboard?.writeText(traceId).then(
981
1480
  () => {
982
1481
  setCopied(true);
@@ -986,7 +1485,7 @@ function TraceIdCopy({ traceId }) {
986
1485
  }
987
1486
  );
988
1487
  }, [traceId]);
989
- return /* @__PURE__ */ jsxs4(
1488
+ return /* @__PURE__ */ jsxs6(
990
1489
  "button",
991
1490
  {
992
1491
  type: "button",
@@ -995,23 +1494,23 @@ function TraceIdCopy({ traceId }) {
995
1494
  "aria-label": "Copy trace id",
996
1495
  className: "inline-flex min-w-0 items-center gap-1.5 rounded text-left font-mono text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-card",
997
1496
  children: [
998
- /* @__PURE__ */ jsx5("span", { className: "truncate", children: traceId }),
999
- /* @__PURE__ */ jsx5(CopyGlyph, { className: "h-3 w-3 shrink-0" }),
1000
- copied && /* @__PURE__ */ jsx5("span", { className: "shrink-0 not-italic text-success", children: "copied" })
1497
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: traceId }),
1498
+ /* @__PURE__ */ jsx7(CopyGlyph, { className: "h-3 w-3 shrink-0" }),
1499
+ copied && /* @__PURE__ */ jsx7("span", { className: "shrink-0 not-italic text-success", children: "copied" })
1001
1500
  ]
1002
1501
  }
1003
1502
  );
1004
1503
  }
1005
1504
  function StatusDot({ tone }) {
1006
- return /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center", children: [
1007
- /* @__PURE__ */ jsx5(
1505
+ return /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center", children: [
1506
+ /* @__PURE__ */ jsx7(
1008
1507
  "span",
1009
1508
  {
1010
1509
  "aria-hidden": true,
1011
1510
  className: `h-2 w-2 shrink-0 rounded-full ${tone === "live" ? "animate-pulse bg-warning" : tone === "ok" ? "bg-success" : tone === "error" ? "bg-destructive" : "bg-muted-foreground/40"}`
1012
1511
  }
1013
1512
  ),
1014
- /* @__PURE__ */ jsx5("span", { className: "sr-only", children: tone })
1513
+ /* @__PURE__ */ jsx7("span", { className: "sr-only", children: tone })
1015
1514
  ] });
1016
1515
  }
1017
1516
  var BAR_CLASS = {
@@ -1023,19 +1522,19 @@ function FlowWaterfall({ trace }) {
1023
1522
  const rows = waterfallLayout(trace);
1024
1523
  if (rows.length === 0) return null;
1025
1524
  const cost = formatActivityCost(trace.costUsd);
1026
- return /* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
1027
- rows.map((row, i) => /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
1028
- /* @__PURE__ */ jsx5("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
1029
- /* @__PURE__ */ jsx5("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx5(
1525
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
1526
+ rows.map((row, i) => /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
1527
+ /* @__PURE__ */ jsx7("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
1528
+ /* @__PURE__ */ jsx7("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx7(
1030
1529
  "div",
1031
1530
  {
1032
1531
  className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-destructive/80"} ${row.approx ? "opacity-70" : ""}`,
1033
1532
  style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
1034
1533
  }
1035
1534
  ) }),
1036
- /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
1535
+ /* @__PURE__ */ jsx7("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
1037
1536
  ] }, i)),
1038
- /* @__PURE__ */ jsxs4("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
1537
+ /* @__PURE__ */ jsxs6("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
1039
1538
  (trace.totalMs / 1e3).toFixed(1),
1040
1539
  "s",
1041
1540
  cost ? ` \xB7 ${cost}` : ""
@@ -1043,43 +1542,43 @@ function FlowWaterfall({ trace }) {
1043
1542
  ] });
1044
1543
  }
1045
1544
  function MissionActivityLane({ activity, startedAt, nowMs }) {
1046
- const [expanded, setExpanded] = useState4(false);
1545
+ const [expanded, setExpanded] = useState7(false);
1047
1546
  if (activity.length === 0) return null;
1048
- return /* @__PURE__ */ jsxs4("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
1547
+ return /* @__PURE__ */ jsxs6("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
1049
1548
  activity.map((run) => {
1050
1549
  const tone = activityTone(run.status);
1051
1550
  const cost = formatActivityCost(run.costUsd);
1052
1551
  const duration = formatActivityDuration(run.durationMs);
1053
- return /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
1054
- /* @__PURE__ */ jsx5(StatusDot, { tone }),
1055
- /* @__PURE__ */ jsxs4("span", { className: "min-w-0 flex-1 truncate", children: [
1056
- /* @__PURE__ */ jsx5("span", { className: "font-medium", children: run.tool }),
1057
- /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
1552
+ return /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
1553
+ /* @__PURE__ */ jsx7(StatusDot, { tone }),
1554
+ /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
1555
+ /* @__PURE__ */ jsx7("span", { className: "font-medium", children: run.tool }),
1556
+ /* @__PURE__ */ jsxs6("span", { className: "text-muted-foreground", children: [
1058
1557
  " \u2014 ",
1059
1558
  run.detail
1060
1559
  ] })
1061
1560
  ] }),
1062
- tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx5("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 ") }),
1063
- /* @__PURE__ */ jsxs4("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
1064
- tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx5("span", { children: run.status }),
1065
- cost && /* @__PURE__ */ jsx5("span", { children: cost }),
1066
- duration && /* @__PURE__ */ jsx5("span", { children: duration })
1561
+ tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx7("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 ") }),
1562
+ /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
1563
+ tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx7("span", { children: run.status }),
1564
+ cost && /* @__PURE__ */ jsx7("span", { children: cost }),
1565
+ duration && /* @__PURE__ */ jsx7("span", { children: duration })
1067
1566
  ] })
1068
1567
  ] }, run.taskId);
1069
1568
  }),
1070
- /* @__PURE__ */ jsxs4(
1569
+ /* @__PURE__ */ jsxs6(
1071
1570
  "button",
1072
1571
  {
1073
1572
  type: "button",
1074
1573
  onClick: () => setExpanded((v) => !v),
1075
1574
  className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
1076
1575
  children: [
1077
- /* @__PURE__ */ jsx5(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
1576
+ /* @__PURE__ */ jsx7(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
1078
1577
  "timeline"
1079
1578
  ]
1080
1579
  }
1081
1580
  ),
1082
- expanded && /* @__PURE__ */ jsx5("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx5(
1581
+ expanded && /* @__PURE__ */ jsx7("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx7(
1083
1582
  FlowWaterfall,
1084
1583
  {
1085
1584
  trace: stepActivityFlowTrace(activity, {
@@ -1094,45 +1593,45 @@ function ActivityRow({
1094
1593
  record,
1095
1594
  renderMissionRef
1096
1595
  }) {
1097
- const [open, setOpen] = useState4(false);
1596
+ const [open, setOpen] = useState7(false);
1098
1597
  const tone = activityTone(record.status);
1099
1598
  const cost = formatActivityCost(record.costUsd);
1100
1599
  const duration = formatActivityDuration(record.durationMs);
1101
- return /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-border/60 bg-card", children: [
1102
- /* @__PURE__ */ jsxs4("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm", children: [
1103
- /* @__PURE__ */ jsx5(StatusDot, { tone }),
1104
- /* @__PURE__ */ jsxs4("span", { className: "min-w-0 flex-1 truncate", children: [
1105
- /* @__PURE__ */ jsx5("span", { className: "font-medium", children: record.tool }),
1106
- /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
1600
+ return /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border/60 bg-card", children: [
1601
+ /* @__PURE__ */ jsxs6("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm", children: [
1602
+ /* @__PURE__ */ jsx7(StatusDot, { tone }),
1603
+ /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
1604
+ /* @__PURE__ */ jsx7("span", { className: "font-medium", children: record.tool }),
1605
+ /* @__PURE__ */ jsxs6("span", { className: "text-muted-foreground", children: [
1107
1606
  " \u2014 ",
1108
1607
  record.detail
1109
1608
  ] })
1110
1609
  ] }),
1111
- tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx5("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 ") }),
1112
- /* @__PURE__ */ jsx5(
1610
+ tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx7("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 ") }),
1611
+ /* @__PURE__ */ jsx7(
1113
1612
  "span",
1114
1613
  {
1115
1614
  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-muted/60 text-muted-foreground"}`,
1116
1615
  children: record.status
1117
1616
  }
1118
1617
  ),
1119
- cost && /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
1120
- /* @__PURE__ */ jsx5(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
1618
+ cost && /* @__PURE__ */ jsx7("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
1619
+ /* @__PURE__ */ jsx7(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
1121
1620
  ] }),
1122
- open && /* @__PURE__ */ jsxs4("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
1123
- record.durationMs !== void 0 && /* @__PURE__ */ jsx5("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx5(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
1124
- /* @__PURE__ */ jsxs4("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
1125
- /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "task" }),
1126
- /* @__PURE__ */ jsx5("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
1127
- /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "started" }),
1128
- /* @__PURE__ */ jsx5("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
1129
- duration && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1130
- /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "duration" }),
1131
- /* @__PURE__ */ jsx5("dd", { className: "text-muted-foreground", children: duration })
1621
+ open && /* @__PURE__ */ jsxs6("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
1622
+ record.durationMs !== void 0 && /* @__PURE__ */ jsx7("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx7(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
1623
+ /* @__PURE__ */ jsxs6("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
1624
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "task" }),
1625
+ /* @__PURE__ */ jsx7("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
1626
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "started" }),
1627
+ /* @__PURE__ */ jsx7("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
1628
+ duration && /* @__PURE__ */ jsxs6(Fragment4, { children: [
1629
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "duration" }),
1630
+ /* @__PURE__ */ jsx7("dd", { className: "text-muted-foreground", children: duration })
1132
1631
  ] }),
1133
- record.traceId && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1134
- /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "trace" }),
1135
- /* @__PURE__ */ jsx5("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx5(TraceIdCopy, { traceId: record.traceId }) })
1632
+ record.traceId && /* @__PURE__ */ jsxs6(Fragment4, { children: [
1633
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "trace" }),
1634
+ /* @__PURE__ */ jsx7("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx7(TraceIdCopy, { traceId: record.traceId }) })
1136
1635
  ] })
1137
1636
  ] }),
1138
1637
  record.missionRef && renderMissionRef?.(record.missionRef, record)
@@ -1140,11 +1639,11 @@ function ActivityRow({
1140
1639
  ] });
1141
1640
  }
1142
1641
  function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent activity", emptyLabel = "No agent runs yet." }) {
1143
- const [rows, setRows] = useState4([]);
1144
- const [cursor, setCursor] = useState4(void 0);
1145
- const [loading, setLoading] = useState4(false);
1146
- const [error, setError] = useState4(null);
1147
- const load = useCallback2(
1642
+ const [rows, setRows] = useState7([]);
1643
+ const [cursor, setCursor] = useState7(void 0);
1644
+ const [loading, setLoading] = useState7(false);
1645
+ const [error, setError] = useState7(null);
1646
+ const load = useCallback3(
1148
1647
  async (from) => {
1149
1648
  setLoading(true);
1150
1649
  setError(null);
@@ -1163,10 +1662,10 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1163
1662
  useEffect4(() => {
1164
1663
  void load();
1165
1664
  }, [load]);
1166
- return /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1167
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1168
- /* @__PURE__ */ jsx5("h2", { className: "flex-1 text-sm font-semibold", children: title }),
1169
- /* @__PURE__ */ jsx5(
1665
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
1666
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
1667
+ /* @__PURE__ */ jsx7("h2", { className: "flex-1 text-sm font-semibold", children: title }),
1668
+ /* @__PURE__ */ jsx7(
1170
1669
  "button",
1171
1670
  {
1172
1671
  type: "button",
@@ -1174,14 +1673,14 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1174
1673
  disabled: loading,
1175
1674
  "aria-label": "Refresh",
1176
1675
  className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground disabled:opacity-50",
1177
- children: /* @__PURE__ */ jsx5(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
1676
+ children: /* @__PURE__ */ jsx7(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
1178
1677
  }
1179
1678
  )
1180
1679
  ] }),
1181
- error && /* @__PURE__ */ jsx5("p", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error }),
1182
- !error && rows.length === 0 && !loading && /* @__PURE__ */ jsx5("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
1183
- /* @__PURE__ */ jsx5("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx5(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
1184
- cursor && /* @__PURE__ */ jsx5(
1680
+ error && /* @__PURE__ */ jsx7("p", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error }),
1681
+ !error && rows.length === 0 && !loading && /* @__PURE__ */ jsx7("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
1682
+ /* @__PURE__ */ jsx7("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx7(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
1683
+ cursor && /* @__PURE__ */ jsx7(
1185
1684
  "button",
1186
1685
  {
1187
1686
  type: "button",
@@ -1195,9 +1694,9 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1195
1694
  }
1196
1695
 
1197
1696
  // src/web-react/seat-paywall.tsx
1198
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1199
- function CheckGlyph() {
1200
- return /* @__PURE__ */ jsx6(
1697
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1698
+ function CheckGlyph3() {
1699
+ return /* @__PURE__ */ jsx8(
1201
1700
  "svg",
1202
1701
  {
1203
1702
  className: "h-4 w-4 shrink-0 text-primary",
@@ -1208,14 +1707,14 @@ function CheckGlyph() {
1208
1707
  strokeLinecap: "round",
1209
1708
  strokeLinejoin: "round",
1210
1709
  "aria-hidden": true,
1211
- children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" })
1710
+ children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
1212
1711
  }
1213
1712
  );
1214
1713
  }
1215
1714
  function Benefit({ children }) {
1216
- return /* @__PURE__ */ jsxs5("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
1217
- /* @__PURE__ */ jsx6("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx6(CheckGlyph, {}) }),
1218
- /* @__PURE__ */ jsx6("span", { children })
1715
+ return /* @__PURE__ */ jsxs7("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
1716
+ /* @__PURE__ */ jsx8("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx8(CheckGlyph3, {}) }),
1717
+ /* @__PURE__ */ jsx8("span", { children })
1219
1718
  ] });
1220
1719
  }
1221
1720
  function SeatPaywall({
@@ -1229,30 +1728,30 @@ function SeatPaywall({
1229
1728
  footnote
1230
1729
  }) {
1231
1730
  const { pending, run } = usePending();
1232
- return /* @__PURE__ */ jsx6("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs5("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
1233
- /* @__PURE__ */ jsx6("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
1234
- /* @__PURE__ */ jsxs5("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
1731
+ return /* @__PURE__ */ jsx8("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs7("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
1732
+ /* @__PURE__ */ jsx8("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
1733
+ /* @__PURE__ */ jsxs7("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
1235
1734
  "Unlock ",
1236
1735
  product
1237
1736
  ] }),
1238
- tagline && /* @__PURE__ */ jsx6("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
1239
- /* @__PURE__ */ jsxs5("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
1240
- /* @__PURE__ */ jsxs5("span", { className: "text-3xl font-semibold text-foreground", children: [
1737
+ tagline && /* @__PURE__ */ jsx8("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
1738
+ /* @__PURE__ */ jsxs7("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
1739
+ /* @__PURE__ */ jsxs7("span", { className: "text-3xl font-semibold text-foreground", children: [
1241
1740
  "$",
1242
1741
  priceUsd
1243
1742
  ] }),
1244
- /* @__PURE__ */ jsx6("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1743
+ /* @__PURE__ */ jsx8("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1245
1744
  ] }),
1246
- /* @__PURE__ */ jsxs5("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1745
+ /* @__PURE__ */ jsxs7("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1247
1746
  "Includes $",
1248
1747
  includedUsageUsd,
1249
1748
  "/mo of AI usage"
1250
1749
  ] }),
1251
- /* @__PURE__ */ jsx6("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
1750
+ /* @__PURE__ */ jsx8("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
1252
1751
  `Full access to ${product}`,
1253
1752
  `$${includedUsageUsd}/mo of AI usage included, every month`
1254
- ]).map((benefit, i) => /* @__PURE__ */ jsx6(Benefit, { children: benefit }, i)) }),
1255
- /* @__PURE__ */ jsx6(
1753
+ ]).map((benefit, i) => /* @__PURE__ */ jsx8(Benefit, { children: benefit }, i)) }),
1754
+ /* @__PURE__ */ jsx8(
1256
1755
  "button",
1257
1756
  {
1258
1757
  type: "button",
@@ -1262,13 +1761,13 @@ function SeatPaywall({
1262
1761
  children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
1263
1762
  }
1264
1763
  ),
1265
- footnote && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
1764
+ footnote && /* @__PURE__ */ jsx8("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
1266
1765
  ] }) });
1267
1766
  }
1268
1767
 
1269
1768
  // src/web-react/agent-session-controls.tsx
1270
- import { useMemo as useMemo2, useState as useState5 } from "react";
1271
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1769
+ import { useMemo as useMemo5, useState as useState8 } from "react";
1770
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1272
1771
  var HARNESS_LABELS = {
1273
1772
  opencode: "OpenCode (any model)",
1274
1773
  "claude-code": "Claude Code (Anthropic)",
@@ -1288,12 +1787,12 @@ function harnessLabel(h) {
1288
1787
  return HARNESS_LABELS[h] ?? h;
1289
1788
  }
1290
1789
  function ChevronDown2({ className }) {
1291
- 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: "m6 9 6 6 6-6" }) });
1790
+ return /* @__PURE__ */ jsx9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx9("path", { d: "m6 9 6 6 6-6" }) });
1292
1791
  }
1293
1792
  function GearGlyph({ className }) {
1294
- return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1295
- /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
1296
- /* @__PURE__ */ jsx7("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
1793
+ return /* @__PURE__ */ jsxs8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1794
+ /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "3" }),
1795
+ /* @__PURE__ */ jsx9("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
1297
1796
  ] });
1298
1797
  }
1299
1798
  var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
@@ -1302,11 +1801,11 @@ function HarnessPicker({
1302
1801
  onChange,
1303
1802
  available
1304
1803
  }) {
1305
- const [open, setOpen] = useState5(false);
1804
+ const [open, setOpen] = useState8(false);
1306
1805
  const { containerRef, triggerProps } = usePopover(open, setOpen);
1307
1806
  const options = available ?? Object.keys(HARNESS_LABELS);
1308
- return /* @__PURE__ */ jsxs6("div", { ref: containerRef, className: "relative inline-flex", children: [
1309
- /* @__PURE__ */ jsxs6(
1807
+ return /* @__PURE__ */ jsxs8("div", { ref: containerRef, className: "relative inline-flex", children: [
1808
+ /* @__PURE__ */ jsxs8(
1310
1809
  "button",
1311
1810
  {
1312
1811
  type: "button",
@@ -1315,12 +1814,12 @@ function HarnessPicker({
1315
1814
  title: "Agent backend",
1316
1815
  className: `inline-flex w-full items-center justify-between gap-1.5 rounded-lg border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 ${FOCUS_RING}`,
1317
1816
  children: [
1318
- /* @__PURE__ */ jsx7("span", { className: "truncate", children: harnessLabel(value) }),
1319
- /* @__PURE__ */ jsx7(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1817
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: harnessLabel(value) }),
1818
+ /* @__PURE__ */ jsx9(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1320
1819
  ]
1321
1820
  }
1322
1821
  ),
1323
- open && /* @__PURE__ */ jsx7("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[220px] overflow-y-auto rounded-xl border border-border bg-card p-1 shadow-lg", children: options.map((h) => /* @__PURE__ */ jsx7(
1822
+ open && /* @__PURE__ */ jsx9("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[220px] overflow-y-auto rounded-xl border border-border bg-card p-1 shadow-lg", children: options.map((h) => /* @__PURE__ */ jsx9(
1324
1823
  "button",
1325
1824
  {
1326
1825
  type: "button",
@@ -1339,7 +1838,7 @@ function HarnessPicker({
1339
1838
  }
1340
1839
  function useCoherentHandlers(props) {
1341
1840
  const { model, models, harness, onModelChange, onHarnessChange } = props;
1342
- const canonicalIds = useMemo2(() => models.map((m) => m.id), [models]);
1841
+ const canonicalIds = useMemo5(() => models.map((m) => m.id), [models]);
1343
1842
  const onModel = (next) => {
1344
1843
  onModelChange(next);
1345
1844
  const nextHarness = snapHarnessToModel(harness, next);
@@ -1367,11 +1866,11 @@ function AgentSessionControls(props) {
1367
1866
  className
1368
1867
  } = props;
1369
1868
  const { onModel, onHarness } = useCoherentHandlers(props);
1370
- const [open, setOpen] = useState5(false);
1869
+ const [open, setOpen] = useState8(false);
1371
1870
  const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
1372
1871
  const selectedModel = models.find((m) => m.id === model);
1373
1872
  const showEffort = selectedModel?.supportsReasoning ?? true;
1374
- const modelPicker = /* @__PURE__ */ jsx7(
1873
+ const modelPicker = /* @__PURE__ */ jsx9(
1375
1874
  ModelPicker,
1376
1875
  {
1377
1876
  value: model,
@@ -1382,17 +1881,17 @@ function AgentSessionControls(props) {
1382
1881
  }
1383
1882
  );
1384
1883
  if (layout === "inline") {
1385
- return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1884
+ return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1386
1885
  modelPicker,
1387
- showHarness && /* @__PURE__ */ jsx7(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1388
- showEffort && /* @__PURE__ */ jsx7(EffortPicker, { value: effort, onChange: onEffortChange })
1886
+ showHarness && /* @__PURE__ */ jsx9(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1887
+ showEffort && /* @__PURE__ */ jsx9(EffortPicker, { value: effort, onChange: onEffortChange })
1389
1888
  ] });
1390
1889
  }
1391
1890
  const hasAdvanced = showHarness || showEffort;
1392
- return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1891
+ return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1393
1892
  modelPicker,
1394
- hasAdvanced && /* @__PURE__ */ jsxs6("div", { ref: popoverRef, className: "relative inline-flex", children: [
1395
- /* @__PURE__ */ jsx7(
1893
+ hasAdvanced && /* @__PURE__ */ jsxs8("div", { ref: popoverRef, className: "relative inline-flex", children: [
1894
+ /* @__PURE__ */ jsx9(
1396
1895
  "button",
1397
1896
  {
1398
1897
  type: "button",
@@ -1401,19 +1900,19 @@ function AgentSessionControls(props) {
1401
1900
  title: "Model settings \u2014 pick the agent backend and how hard it thinks",
1402
1901
  className: `flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[state=open]:bg-muted ${FOCUS_RING}`,
1403
1902
  "data-state": open ? "open" : "closed",
1404
- children: /* @__PURE__ */ jsx7(GearGlyph, { className: "h-4 w-4" })
1903
+ children: /* @__PURE__ */ jsx9(GearGlyph, { className: "h-4 w-4" })
1405
1904
  }
1406
1905
  ),
1407
- open && /* @__PURE__ */ jsxs6("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
1408
- showHarness && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1409
- /* @__PURE__ */ jsx7("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1410
- /* @__PURE__ */ jsx7(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1411
- /* @__PURE__ */ jsx7("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
1906
+ open && /* @__PURE__ */ jsxs8("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
1907
+ showHarness && /* @__PURE__ */ jsxs8("div", { className: "space-y-1.5", children: [
1908
+ /* @__PURE__ */ jsx9("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1909
+ /* @__PURE__ */ jsx9(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1910
+ /* @__PURE__ */ jsx9("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
1412
1911
  ] }),
1413
- showEffort && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1414
- /* @__PURE__ */ jsx7("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
1415
- /* @__PURE__ */ jsx7(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
1416
- /* @__PURE__ */ jsx7("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
1912
+ showEffort && /* @__PURE__ */ jsxs8("div", { className: "space-y-1.5", children: [
1913
+ /* @__PURE__ */ jsx9("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
1914
+ /* @__PURE__ */ jsx9(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
1915
+ /* @__PURE__ */ jsx9("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
1417
1916
  ] })
1418
1917
  ] })
1419
1918
  ] })
@@ -1421,7 +1920,7 @@ function AgentSessionControls(props) {
1421
1920
  }
1422
1921
 
1423
1922
  // src/web-react/index.tsx
1424
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1923
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1425
1924
  function formatModelCost(msg, models) {
1426
1925
  if (msg.promptTokens == null && msg.completionTokens == null) return null;
1427
1926
  const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
@@ -1435,41 +1934,41 @@ function formatTokensPerSecond(msg) {
1435
1934
  return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
1436
1935
  }
1437
1936
  function RunDrillIn({ run, onClose }) {
1438
- return /* @__PURE__ */ jsxs7("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
1439
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1440
- /* @__PURE__ */ jsx8(
1937
+ return /* @__PURE__ */ jsxs9("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
1938
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1939
+ /* @__PURE__ */ jsx10(
1441
1940
  "span",
1442
1941
  {
1443
1942
  className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
1444
1943
  }
1445
1944
  ),
1446
- /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1447
- /* @__PURE__ */ jsx8("p", { className: "truncate text-sm font-semibold", children: run.title }),
1448
- /* @__PURE__ */ jsx8("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1945
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
1946
+ /* @__PURE__ */ jsx10("p", { className: "truncate text-sm font-semibold", children: run.title }),
1947
+ /* @__PURE__ */ jsx10("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1449
1948
  ] }),
1450
- /* @__PURE__ */ jsx8(
1949
+ /* @__PURE__ */ jsx10(
1451
1950
  "button",
1452
1951
  {
1453
1952
  type: "button",
1454
1953
  onClick: onClose,
1455
1954
  "aria-label": "Close",
1456
1955
  className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
1457
- children: /* @__PURE__ */ jsx8("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "M18 6 6 18M6 6l12 12" }) })
1956
+ children: /* @__PURE__ */ jsx10("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx10("path", { d: "M18 6 6 18M6 6l12 12" }) })
1458
1957
  }
1459
1958
  )
1460
1959
  ] }),
1461
- /* @__PURE__ */ jsxs7("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1462
- run.steps.length === 0 && /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1463
- run.steps.map((step, i) => /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1464
- /* @__PURE__ */ jsxs7("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1465
- /* @__PURE__ */ jsx8("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1466
- /* @__PURE__ */ jsx8("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1467
- /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
1960
+ /* @__PURE__ */ jsxs9("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1961
+ run.steps.length === 0 && /* @__PURE__ */ jsx10("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1962
+ run.steps.map((step, i) => /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1963
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1964
+ /* @__PURE__ */ jsx10("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1965
+ /* @__PURE__ */ jsx10("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1966
+ /* @__PURE__ */ jsx10("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
1468
1967
  ] }),
1469
- step.detail && /* @__PURE__ */ jsx8("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 })
1968
+ step.detail && /* @__PURE__ */ jsx10("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 })
1470
1969
  ] }, i))
1471
1970
  ] }),
1472
- /* @__PURE__ */ jsx8("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." })
1971
+ /* @__PURE__ */ jsx10("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." })
1473
1972
  ] });
1474
1973
  }
1475
1974
  function pendingApprovalOf(call) {
@@ -1483,20 +1982,20 @@ function ChatEmptyState({
1483
1982
  subline = "Describe the outcome you want. The agent works through it step by step, and pauses for your approval before anything irreversible.",
1484
1983
  doors
1485
1984
  }) {
1486
- return /* @__PURE__ */ jsxs7("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
1487
- /* @__PURE__ */ jsx8("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__ */ jsx8(BrandMark, { size: 32, className: "shrink-0" }) }),
1488
- /* @__PURE__ */ jsx8("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
1489
- /* @__PURE__ */ jsx8("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
1490
- subline && /* @__PURE__ */ jsx8("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
1491
- doors && doors.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs7(
1985
+ return /* @__PURE__ */ jsxs9("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
1986
+ /* @__PURE__ */ jsx10("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__ */ jsx10(BrandMark, { size: 32, className: "shrink-0" }) }),
1987
+ /* @__PURE__ */ jsx10("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
1988
+ /* @__PURE__ */ jsx10("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
1989
+ subline && /* @__PURE__ */ jsx10("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
1990
+ doors && doors.length > 0 && /* @__PURE__ */ jsx10("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs9(
1492
1991
  "button",
1493
1992
  {
1494
1993
  type: "button",
1495
1994
  onClick: door.onSelect,
1496
1995
  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/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1497
1996
  children: [
1498
- /* @__PURE__ */ jsx8("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
1499
- door.description && /* @__PURE__ */ jsx8("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
1997
+ /* @__PURE__ */ jsx10("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
1998
+ door.description && /* @__PURE__ */ jsx10("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
1500
1999
  ]
1501
2000
  },
1502
2001
  i
@@ -1505,26 +2004,26 @@ function ChatEmptyState({
1505
2004
  }
1506
2005
  function ToolGlyph({ name, className }) {
1507
2006
  if (name.startsWith("sandbox_")) {
1508
- return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1509
- /* @__PURE__ */ jsx8("polyline", { points: "4 17 10 11 4 5" }),
1510
- /* @__PURE__ */ jsx8("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
2007
+ return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
2008
+ /* @__PURE__ */ jsx10("polyline", { points: "4 17 10 11 4 5" }),
2009
+ /* @__PURE__ */ jsx10("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
1511
2010
  ] });
1512
2011
  }
1513
2012
  if (name === "submit_proposal") {
1514
- return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1515
- /* @__PURE__ */ jsx8("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1516
- /* @__PURE__ */ jsx8("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
2013
+ return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
2014
+ /* @__PURE__ */ jsx10("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2015
+ /* @__PURE__ */ jsx10("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
1517
2016
  ] });
1518
2017
  }
1519
2018
  if (name === "schedule_followup") {
1520
- return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
1521
- /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "9" }),
1522
- /* @__PURE__ */ jsx8("path", { d: "M12 7v5l3 3" })
2019
+ return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
2020
+ /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "9" }),
2021
+ /* @__PURE__ */ jsx10("path", { d: "M12 7v5l3 3" })
1523
2022
  ] });
1524
2023
  }
1525
- return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1526
- /* @__PURE__ */ jsx8("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
1527
- /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "4" })
2024
+ return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
2025
+ /* @__PURE__ */ jsx10("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
2026
+ /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "4" })
1528
2027
  ] });
1529
2028
  }
1530
2029
  function toolOutcomeOf(call) {
@@ -1591,36 +2090,36 @@ function truncate(v, max = 240) {
1591
2090
  function KvRows({ data }) {
1592
2091
  const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
1593
2092
  if (!entries.length) return null;
1594
- return /* @__PURE__ */ jsx8("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs7("div", { className: "contents", children: [
1595
- /* @__PURE__ */ jsx8("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
1596
- /* @__PURE__ */ jsx8("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
2093
+ return /* @__PURE__ */ jsx10("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs9("div", { className: "contents", children: [
2094
+ /* @__PURE__ */ jsx10("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
2095
+ /* @__PURE__ */ jsx10("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
1597
2096
  ] }, k)) });
1598
2097
  }
1599
2098
  function ShellDetail({ call }) {
1600
2099
  const outcome = toolOutcomeOf(call);
1601
2100
  const r = outcome?.result ?? {};
1602
- return /* @__PURE__ */ jsxs7("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
1603
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
1604
- /* @__PURE__ */ jsx8("span", { className: "select-none text-zinc-500", children: "$" }),
1605
- /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
1606
- r.exitCode != null && /* @__PURE__ */ jsxs7("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
2101
+ return /* @__PURE__ */ jsxs9("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
2102
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
2103
+ /* @__PURE__ */ jsx10("span", { className: "select-none text-zinc-500", children: "$" }),
2104
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
2105
+ r.exitCode != null && /* @__PURE__ */ jsxs9("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
1607
2106
  "exit ",
1608
2107
  r.exitCode
1609
2108
  ] })
1610
2109
  ] }),
1611
- /* @__PURE__ */ jsx8("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap px-3 pb-2.5 pt-1.5 text-zinc-300", children: outcome?.ok === false ? outcome.message ?? "failed" : [r.stdout, r.stderr].filter(Boolean).join("\n") || "(no output)" })
2110
+ /* @__PURE__ */ jsx10("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap px-3 pb-2.5 pt-1.5 text-zinc-300", children: outcome?.ok === false ? outcome.message ?? "failed" : [r.stdout, r.stderr].filter(Boolean).join("\n") || "(no output)" })
1612
2111
  ] });
1613
2112
  }
1614
2113
  function DefaultToolDetail({ call }) {
1615
2114
  const outcome = toolOutcomeOf(call);
1616
- return /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
1617
- call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs7("div", { children: [
1618
- /* @__PURE__ */ jsx8("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
1619
- /* @__PURE__ */ jsx8(KvRows, { data: call.args })
2115
+ return /* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
2116
+ call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs9("div", { children: [
2117
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
2118
+ /* @__PURE__ */ jsx10(KvRows, { data: call.args })
1620
2119
  ] }),
1621
- outcome && /* @__PURE__ */ jsxs7("div", { children: [
1622
- /* @__PURE__ */ jsx8("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
1623
- outcome.ok === false ? /* @__PURE__ */ jsx8("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx8(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx8("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
2120
+ outcome && /* @__PURE__ */ jsxs9("div", { children: [
2121
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
2122
+ outcome.ok === false ? /* @__PURE__ */ jsx10("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx10(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx10("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
1624
2123
  ] })
1625
2124
  ] });
1626
2125
  }
@@ -1631,23 +2130,23 @@ function ProposalCard({
1631
2130
  approval,
1632
2131
  renderers
1633
2132
  }) {
1634
- const [expanded, setExpanded] = useState6(false);
2133
+ const [expanded, setExpanded] = useState9(false);
1635
2134
  const { summary, meta } = proposalPreview(call);
1636
2135
  const custom = renderers?.[call.name]?.(call, message);
1637
2136
  const { pending: deciding, run: decide } = usePending();
1638
- return /* @__PURE__ */ jsxs7("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: [
1639
- /* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
1640
- /* @__PURE__ */ jsx8("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__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
1641
- /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1642
- /* @__PURE__ */ jsx8("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
1643
- /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
1644
- summary && /* @__PURE__ */ jsx8("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
1645
- meta.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
2137
+ return /* @__PURE__ */ jsxs9("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: [
2138
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
2139
+ /* @__PURE__ */ jsx10("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__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
2140
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
2141
+ /* @__PURE__ */ jsx10("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
2142
+ /* @__PURE__ */ jsx10("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
2143
+ summary && /* @__PURE__ */ jsx10("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
2144
+ meta.length > 0 && /* @__PURE__ */ jsx10("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx10("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
1646
2145
  ] })
1647
2146
  ] }),
1648
- /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
1649
- approval ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
1650
- /* @__PURE__ */ jsx8(
2147
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
2148
+ approval ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
2149
+ /* @__PURE__ */ jsx10(
1651
2150
  "button",
1652
2151
  {
1653
2152
  type: "button",
@@ -1657,7 +2156,7 @@ function ProposalCard({
1657
2156
  children: "Approve & run"
1658
2157
  }
1659
2158
  ),
1660
- /* @__PURE__ */ jsx8(
2159
+ /* @__PURE__ */ jsx10(
1661
2160
  "button",
1662
2161
  {
1663
2162
  type: "button",
@@ -1667,8 +2166,8 @@ function ProposalCard({
1667
2166
  children: "Reject"
1668
2167
  }
1669
2168
  )
1670
- ] }) : /* @__PURE__ */ jsx8("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
1671
- /* @__PURE__ */ jsxs7(
2169
+ ] }) : /* @__PURE__ */ jsx10("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
2170
+ /* @__PURE__ */ jsxs9(
1672
2171
  "button",
1673
2172
  {
1674
2173
  type: "button",
@@ -1677,23 +2176,23 @@ function ProposalCard({
1677
2176
  className: "ml-auto inline-flex items-center gap-1 rounded text-[12px] font-medium text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1678
2177
  children: [
1679
2178
  expanded ? "Hide details" : "View details",
1680
- /* @__PURE__ */ jsx8(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
2179
+ /* @__PURE__ */ jsx10(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
1681
2180
  ]
1682
2181
  }
1683
2182
  )
1684
2183
  ] }),
1685
- expanded && /* @__PURE__ */ jsx8("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx8(DefaultToolDetail, { call }) })
2184
+ expanded && /* @__PURE__ */ jsx10("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx10(DefaultToolDetail, { call }) })
1686
2185
  ] });
1687
2186
  }
1688
2187
  function FollowupCard({ call }) {
1689
2188
  const a = call.args ?? {};
1690
2189
  const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
1691
- return /* @__PURE__ */ jsxs7("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
1692
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1693
- /* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
1694
- /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
2190
+ return /* @__PURE__ */ jsxs9("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
2191
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
2192
+ /* @__PURE__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
2193
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
1695
2194
  ] }),
1696
- when && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
2195
+ when && /* @__PURE__ */ jsx10("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
1697
2196
  ] });
1698
2197
  }
1699
2198
  function ToolCallCard({
@@ -1703,13 +2202,13 @@ function ToolCallCard({
1703
2202
  onOpenRun,
1704
2203
  renderers
1705
2204
  }) {
1706
- const [expanded, setExpanded] = useState6(false);
2205
+ const [expanded, setExpanded] = useState9(false);
1707
2206
  const pending = call.status === "done" ? pendingApprovalOf(call) : null;
1708
2207
  const kind = blockKindOf(call);
1709
2208
  const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
1710
2209
  const custom = renderers?.[call.name]?.(call, message);
1711
2210
  if (pending) {
1712
- return /* @__PURE__ */ jsx8(
2211
+ return /* @__PURE__ */ jsx10(
1713
2212
  ProposalCard,
1714
2213
  {
1715
2214
  call,
@@ -1721,16 +2220,16 @@ function ToolCallCard({
1721
2220
  );
1722
2221
  }
1723
2222
  if (kind === "followup" && !failed) {
1724
- return /* @__PURE__ */ jsx8(FollowupCard, { call });
2223
+ return /* @__PURE__ */ jsx10(FollowupCard, { call });
1725
2224
  }
1726
2225
  const isCommand = kind === "command";
1727
- return /* @__PURE__ */ jsxs7(
2226
+ return /* @__PURE__ */ jsxs9(
1728
2227
  "div",
1729
2228
  {
1730
2229
  className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${failed ? "border-destructive/40 bg-destructive/5" : "border-border/60 bg-muted/20"}`,
1731
2230
  children: [
1732
- /* @__PURE__ */ jsxs7("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
1733
- /* @__PURE__ */ jsxs7(
2231
+ /* @__PURE__ */ jsxs9("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
2232
+ /* @__PURE__ */ jsxs9(
1734
2233
  "button",
1735
2234
  {
1736
2235
  type: "button",
@@ -1738,14 +2237,14 @@ function ToolCallCard({
1738
2237
  "aria-expanded": expanded,
1739
2238
  className: "flex min-w-0 flex-1 items-center gap-2 rounded text-left focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1740
2239
  children: [
1741
- /* @__PURE__ */ jsx8(
2240
+ /* @__PURE__ */ jsx10(
1742
2241
  "span",
1743
2242
  {
1744
2243
  className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : failed ? "bg-destructive" : "bg-success"}`
1745
2244
  }
1746
2245
  ),
1747
- /* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1748
- /* @__PURE__ */ jsx8(
2246
+ /* @__PURE__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
2247
+ /* @__PURE__ */ jsx10(
1749
2248
  "span",
1750
2249
  {
1751
2250
  className: `min-w-0 flex-1 truncate ${isCommand ? "font-mono text-[12px] tracking-tight text-foreground/90" : "font-medium"}`,
@@ -1755,8 +2254,8 @@ function ToolCallCard({
1755
2254
  ]
1756
2255
  }
1757
2256
  ),
1758
- /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
1759
- /* @__PURE__ */ jsx8(
2257
+ /* @__PURE__ */ jsx10("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
2258
+ /* @__PURE__ */ jsx10(
1760
2259
  "button",
1761
2260
  {
1762
2261
  type: "button",
@@ -1764,13 +2263,13 @@ function ToolCallCard({
1764
2263
  "aria-label": expanded ? "Collapse details" : "Expand details",
1765
2264
  "aria-expanded": expanded,
1766
2265
  className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1767
- children: /* @__PURE__ */ jsx8(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
2266
+ children: /* @__PURE__ */ jsx10(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
1768
2267
  }
1769
2268
  )
1770
2269
  ] }),
1771
- expanded && /* @__PURE__ */ jsxs7("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
1772
- custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx8(ShellDetail, { call }) : /* @__PURE__ */ jsx8(DefaultToolDetail, { call })),
1773
- onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx8(
2270
+ expanded && /* @__PURE__ */ jsxs9("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
2271
+ custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx10(ShellDetail, { call }) : /* @__PURE__ */ jsx10(DefaultToolDetail, { call })),
2272
+ onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx10(
1774
2273
  "button",
1775
2274
  {
1776
2275
  type: "button",
@@ -1785,7 +2284,7 @@ function ToolCallCard({
1785
2284
  );
1786
2285
  }
1787
2286
  function StreamingCaret() {
1788
- return /* @__PURE__ */ jsx8(
2287
+ return /* @__PURE__ */ jsx10(
1789
2288
  "span",
1790
2289
  {
1791
2290
  className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70",
@@ -1800,11 +2299,11 @@ function SegmentText({
1800
2299
  renderBody
1801
2300
  }) {
1802
2301
  const text = useSmoothText(content, streaming);
1803
- const body = useMemo3(() => renderBody(text), [renderBody, text]);
2302
+ const body = useMemo6(() => renderBody(text), [renderBody, text]);
1804
2303
  if (!content.trim() && !showCaret) return null;
1805
- return /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
2304
+ return /* @__PURE__ */ jsxs9("div", { className: "text-base leading-[1.75]", children: [
1806
2305
  body,
1807
- showCaret && /* @__PURE__ */ jsx8(StreamingCaret, {})
2306
+ showCaret && /* @__PURE__ */ jsx10(StreamingCaret, {})
1808
2307
  ] });
1809
2308
  }
1810
2309
  var COLLAPSE_TOOL_RUN_AT = 3;
@@ -1827,7 +2326,7 @@ function SegmentedBody({
1827
2326
  const leftoverToolCalls = (msg.toolCalls ?? []).filter(
1828
2327
  (tc) => !segmentToolIds.has(tc.id)
1829
2328
  );
1830
- const renderToolCard = (call) => /* @__PURE__ */ jsx8(
2329
+ const renderToolCard = (call) => /* @__PURE__ */ jsx10(
1831
2330
  ToolCallCard,
1832
2331
  {
1833
2332
  call,
@@ -1850,9 +2349,9 @@ function SegmentedBody({
1850
2349
  else groups.push({ kind: "tools", index: i, calls: [seg.call] });
1851
2350
  }
1852
2351
  }
1853
- return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
2352
+ return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2", children: [
1854
2353
  groups.map(
1855
- (g) => g.kind === "text" ? /* @__PURE__ */ jsx8(
2354
+ (g) => g.kind === "text" ? /* @__PURE__ */ jsx10(
1856
2355
  SegmentText,
1857
2356
  {
1858
2357
  content: g.content,
@@ -1861,24 +2360,24 @@ function SegmentedBody({
1861
2360
  renderBody
1862
2361
  },
1863
2362
  `text-${g.index}`
1864
- ) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */ jsxs7(
2363
+ ) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */ jsxs9(
1865
2364
  "details",
1866
2365
  {
1867
2366
  className: "rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2",
1868
2367
  children: [
1869
- /* @__PURE__ */ jsxs7("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: [
2368
+ /* @__PURE__ */ jsxs9("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: [
1870
2369
  "Worked through ",
1871
2370
  g.calls.length,
1872
2371
  " steps"
1873
2372
  ] }),
1874
- /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-col gap-2", children: g.calls.map(renderToolCard) })
2373
+ /* @__PURE__ */ jsx10("div", { className: "mt-2 flex flex-col gap-2", children: g.calls.map(renderToolCard) })
1875
2374
  ]
1876
2375
  },
1877
2376
  `tools-${g.index}`
1878
- ) : /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-2", children: g.calls.map(renderToolCard) }, `tools-${g.index}`)
2377
+ ) : /* @__PURE__ */ jsx10("div", { className: "flex flex-col gap-2", children: g.calls.map(renderToolCard) }, `tools-${g.index}`)
1879
2378
  ),
1880
2379
  leftoverToolCalls.map(renderToolCard),
1881
- streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx8(StreamingCaret, {})
2380
+ streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx10(StreamingCaret, {})
1882
2381
  ] });
1883
2382
  }
1884
2383
  function AssistantMessageImpl({
@@ -1894,12 +2393,12 @@ function AssistantMessageImpl({
1894
2393
  }) {
1895
2394
  const content = useSmoothText(msg.content, streaming);
1896
2395
  const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
1897
- const body = useMemo3(() => renderBody(content), [renderBody, content]);
2396
+ const body = useMemo6(() => renderBody(content), [renderBody, content]);
1898
2397
  const segments = msg.segments;
1899
2398
  const hasAnswerText = content !== "" || (segments?.some((s) => s.kind === "text" && s.content.trim() !== "") ?? false);
1900
- const reasoningScrollRef = useRef4(null);
1901
- const thinkStartRef = useRef4(null);
1902
- const thinkMsRef = useRef4(null);
2399
+ const reasoningScrollRef = useRef6(null);
2400
+ const thinkStartRef = useRef6(null);
2401
+ const thinkMsRef = useRef6(null);
1903
2402
  if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
1904
2403
  thinkStartRef.current = performance.now();
1905
2404
  }
@@ -1913,21 +2412,21 @@ function AssistantMessageImpl({
1913
2412
  const thinkingSeconds = useThinkingSeconds(
1914
2413
  streaming && !!reasoning && !hasAnswerText
1915
2414
  );
1916
- return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1917
- /* @__PURE__ */ jsxs7("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
1918
- /* @__PURE__ */ jsx8("span", { className: "font-semibold uppercase", children: agentLabel }),
1919
- msg.modelUsed && /* @__PURE__ */ jsx8("span", { className: "font-mono normal-case", children: msg.modelUsed }),
1920
- formatTokensPerSecond(msg) && /* @__PURE__ */ jsx8("span", { children: formatTokensPerSecond(msg) }),
1921
- formatModelCost(msg, models) && /* @__PURE__ */ jsx8("span", { children: formatModelCost(msg, models) })
2415
+ return /* @__PURE__ */ jsxs9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
2416
+ /* @__PURE__ */ jsxs9("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
2417
+ /* @__PURE__ */ jsx10("span", { className: "font-semibold uppercase", children: agentLabel }),
2418
+ msg.modelUsed && /* @__PURE__ */ jsx10("span", { className: "font-mono normal-case", children: msg.modelUsed }),
2419
+ formatTokensPerSecond(msg) && /* @__PURE__ */ jsx10("span", { children: formatTokensPerSecond(msg) }),
2420
+ formatModelCost(msg, models) && /* @__PURE__ */ jsx10("span", { children: formatModelCost(msg, models) })
1922
2421
  ] }),
1923
- reasoning && /* @__PURE__ */ jsxs7("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
1924
- /* @__PURE__ */ jsx8("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs7("span", { className: "animate-pulse", children: [
2422
+ reasoning && /* @__PURE__ */ jsxs9("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
2423
+ /* @__PURE__ */ jsx10("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs9("span", { className: "animate-pulse", children: [
1925
2424
  "Thinking",
1926
2425
  thinkingSeconds >= 3 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
1927
2426
  ] }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
1928
- /* @__PURE__ */ jsx8("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
2427
+ /* @__PURE__ */ jsx10("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
1929
2428
  ] }),
1930
- segments && segments.length > 0 ? /* @__PURE__ */ jsx8(
2429
+ segments && segments.length > 0 ? /* @__PURE__ */ jsx10(
1931
2430
  SegmentedBody,
1932
2431
  {
1933
2432
  segments,
@@ -1938,12 +2437,12 @@ function AssistantMessageImpl({
1938
2437
  onToolCallClick,
1939
2438
  toolRenderers
1940
2439
  }
1941
- ) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
1942
- /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
2440
+ ) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
2441
+ /* @__PURE__ */ jsxs9("div", { className: "text-base leading-[1.75]", children: [
1943
2442
  body,
1944
- streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx8(StreamingCaret, {})
2443
+ streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx10(StreamingCaret, {})
1945
2444
  ] }),
1946
- msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx8(
2445
+ msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx10("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx10(
1947
2446
  ToolCallCard,
1948
2447
  {
1949
2448
  call: tc,
@@ -1960,7 +2459,7 @@ function AssistantMessageImpl({
1960
2459
  }
1961
2460
  var AssistantMessage = memo(AssistantMessageImpl);
1962
2461
  function useThinkingSeconds(active) {
1963
- const [seconds, setSeconds] = useState6(0);
2462
+ const [seconds, setSeconds] = useState9(0);
1964
2463
  useEffect5(() => {
1965
2464
  if (!active) return;
1966
2465
  setSeconds(0);
@@ -1971,23 +2470,23 @@ function useThinkingSeconds(active) {
1971
2470
  }
1972
2471
  function ThinkingRow({ agentLabel }) {
1973
2472
  const seconds = useThinkingSeconds(true);
1974
- return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1975
- /* @__PURE__ */ jsx8("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
1976
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
1977
- /* @__PURE__ */ jsx8("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
2473
+ return /* @__PURE__ */ jsxs9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
2474
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
2475
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
2476
+ /* @__PURE__ */ jsx10("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx10("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
1978
2477
  "Thinking",
1979
2478
  seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
1980
2479
  ] })
1981
2480
  ] });
1982
2481
  }
1983
2482
  function StreamErrorRow({ message, onRetry }) {
1984
- return /* @__PURE__ */ jsx8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
1985
- /* @__PURE__ */ jsxs7("svg", { className: "mt-0.5 h-4 w-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1986
- /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "9" }),
1987
- /* @__PURE__ */ jsx8("path", { d: "M12 8v4m0 4h.01" })
2483
+ return /* @__PURE__ */ jsx10("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs9("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
2484
+ /* @__PURE__ */ jsxs9("svg", { className: "mt-0.5 h-4 w-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
2485
+ /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "9" }),
2486
+ /* @__PURE__ */ jsx10("path", { d: "M12 8v4m0 4h.01" })
1988
2487
  ] }),
1989
- /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 break-words", children: message }),
1990
- onRetry && /* @__PURE__ */ jsx8(
2488
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 break-words", children: message }),
2489
+ onRetry && /* @__PURE__ */ jsx10(
1991
2490
  "button",
1992
2491
  {
1993
2492
  type: "button",
@@ -2015,25 +2514,25 @@ function ChatMessages({
2015
2514
  emptyState,
2016
2515
  header
2017
2516
  }) {
2018
- const renderBody = useMemo3(
2019
- () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-wrap", children: content })),
2517
+ const renderBody = useMemo6(
2518
+ () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx10("p", { className: "whitespace-pre-wrap", children: content })),
2020
2519
  [renderMarkdown]
2021
2520
  );
2022
2521
  const lastIsUser = messages[messages.length - 1]?.role === "user";
2023
2522
  if (messages.length === 0 && !loading && !error) {
2024
- const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx8(ChatEmptyState, { ...emptyState });
2025
- return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2523
+ const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx10(ChatEmptyState, { ...emptyState });
2524
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2026
2525
  header,
2027
2526
  empty
2028
2527
  ] });
2029
2528
  }
2030
- return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2529
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2031
2530
  header,
2032
2531
  messages.map(
2033
- (msg) => msg.role === "user" ? /* @__PURE__ */ jsx8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { className: "ml-auto w-fit max-w-[85%]", children: [
2034
- /* @__PURE__ */ jsx8("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
2035
- /* @__PURE__ */ jsx8("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-wrap", children: msg.content }) })
2036
- ] }) }, msg.id) : /* @__PURE__ */ jsx8(
2532
+ (msg) => msg.role === "user" ? /* @__PURE__ */ jsx10("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs9("div", { className: "ml-auto w-fit max-w-[85%]", children: [
2533
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
2534
+ /* @__PURE__ */ jsx10("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx10("p", { className: "whitespace-pre-wrap", children: msg.content }) })
2535
+ ] }) }, msg.id) : /* @__PURE__ */ jsx10(
2037
2536
  AssistantMessage,
2038
2537
  {
2039
2538
  msg,
@@ -2049,8 +2548,8 @@ function ChatMessages({
2049
2548
  msg.id
2050
2549
  )
2051
2550
  ),
2052
- loading && lastIsUser && /* @__PURE__ */ jsx8(ThinkingRow, { agentLabel }),
2053
- error && !loading && /* @__PURE__ */ jsx8(StreamErrorRow, { message: error, onRetry })
2551
+ loading && lastIsUser && /* @__PURE__ */ jsx10(ThinkingRow, { agentLabel }),
2552
+ error && !loading && /* @__PURE__ */ jsx10(StreamErrorRow, { message: error, onRetry })
2054
2553
  ] });
2055
2554
  }
2056
2555
 
@@ -2063,31 +2562,32 @@ export {
2063
2562
  ModelPicker,
2064
2563
  DEFAULT_EFFORT_LEVELS,
2065
2564
  EffortPicker,
2066
- INTERACTION_EVENT,
2067
- INTERACTION_CANCEL_EVENT,
2068
- INTERACTION_RESOLVED_EVENT,
2069
- isRenderableInteractionKind,
2070
- isSafeInteractionFieldKey,
2071
- isTerminalInteractionStatus,
2072
- canTransitionInteractionStatus,
2073
- cancelStatusFor,
2074
- questionInteractionContentSignature,
2075
- dedupeQuestionInteractionsByContent,
2076
- parseInteractionRequest,
2077
- parseInteractionCancel,
2078
- fieldAcceptsFreeText,
2079
- composerAnswerDeliveries,
2080
- composerAnswerData,
2081
- interactionPartKey,
2082
- noticePartKey,
2083
- noticePart,
2084
- interactionFromWireRequest,
2085
- interactionToPersistedPart,
2086
- persistedPartToInteraction,
2087
2565
  dispatchChatStreamLine,
2088
2566
  consumeChatStream,
2089
2567
  streamChatTurn,
2090
2568
  ChatComposer,
2569
+ interactionStatusLabels,
2570
+ interactionTerminalNotes,
2571
+ fieldAnswer,
2572
+ buildAnswerData,
2573
+ isLateAnswerableStatus,
2574
+ hasSecretField,
2575
+ lateAnswerMessage,
2576
+ INTERACTION_SUBMIT_TIMEOUT_MS,
2577
+ INTERACTION_SUBMIT_TIMEOUT_MESSAGE,
2578
+ responseErrorMessage,
2579
+ createInteractionAnswerSubmitter,
2580
+ InteractionBadge,
2581
+ InteractionActionButton,
2582
+ QuestionOptionList,
2583
+ InteractionQuestionCard,
2584
+ InteractionPlanCard,
2585
+ upsertChatInteraction,
2586
+ cancelChatInteraction,
2587
+ resolveChatInteraction,
2588
+ terminalizePendingChatInteractions,
2589
+ restoreChatInteractions,
2590
+ useChatInteractions,
2091
2591
  activityTone,
2092
2592
  formatActivityCost,
2093
2593
  formatActivityDuration,
@@ -2106,4 +2606,4 @@ export {
2106
2606
  useThinkingSeconds,
2107
2607
  ChatMessages
2108
2608
  };
2109
- //# sourceMappingURL=chunk-VMY4TKMN.js.map
2609
+ //# sourceMappingURL=chunk-FCQP75JT.js.map