@tangle-network/agent-app 0.43.24 → 0.43.25

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 (50) 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 +1 -0
  6. package/dist/assistant/index.js +2 -1
  7. package/dist/assistant/index.js.map +1 -1
  8. package/dist/chat-store/index.d.ts +193 -0
  9. package/dist/chat-store/index.js +194 -0
  10. package/dist/chat-store/index.js.map +1 -0
  11. package/dist/chunk-4H77LX3V.js +38 -0
  12. package/dist/chunk-4H77LX3V.js.map +1 -0
  13. package/dist/chunk-4TXDD6P2.js +163 -0
  14. package/dist/chunk-4TXDD6P2.js.map +1 -0
  15. package/dist/chunk-AVBANQ67.js +295 -0
  16. package/dist/chunk-AVBANQ67.js.map +1 -0
  17. package/dist/{chunk-3PK3T4KD.js → chunk-JJGZ54EB.js} +44 -1
  18. package/dist/chunk-JJGZ54EB.js.map +1 -0
  19. package/dist/{chunk-VMY4TKMN.js → chunk-PEPXQTJ3.js} +921 -432
  20. package/dist/chunk-PEPXQTJ3.js.map +1 -0
  21. package/dist/chunk-U7DLCPJ6.js +203 -0
  22. package/dist/chunk-U7DLCPJ6.js.map +1 -0
  23. package/dist/{chunk-SAOAAA3S.js → chunk-UHXQ3KNX.js} +1 -22
  24. package/dist/chunk-UHXQ3KNX.js.map +1 -0
  25. package/dist/contract-DYbTzEDf.d.ts +122 -0
  26. package/dist/index.d.ts +5 -2
  27. package/dist/index.js +170 -88
  28. package/dist/interactions/index.d.ts +141 -0
  29. package/dist/interactions/index.js +59 -0
  30. package/dist/interactions/index.js.map +1 -0
  31. package/dist/parts-BeRnK54I.d.ts +185 -0
  32. package/dist/platform/index.d.ts +2 -270
  33. package/dist/platform/index.js +12 -278
  34. package/dist/platform/index.js.map +1 -1
  35. package/dist/preset-cloudflare/index.d.ts +0 -10
  36. package/dist/preset-cloudflare/index.js +1 -1
  37. package/dist/profile/index.d.ts +33 -2
  38. package/dist/profile/index.js +37 -1
  39. package/dist/profile/index.js.map +1 -1
  40. package/dist/sandbox/index.d.ts +47 -1
  41. package/dist/sandbox/index.js +11 -1
  42. package/dist/sso-Df4wtL8D.d.ts +270 -0
  43. package/dist/teams/index.js +9 -9
  44. package/dist/teams/invitations-api.js +3 -3
  45. package/dist/web-react/index.d.ts +206 -96
  46. package/dist/web-react/index.js +68 -22
  47. package/package.json +20 -1
  48. package/dist/chunk-3PK3T4KD.js.map +0 -1
  49. package/dist/chunk-SAOAAA3S.js.map +0 -1
  50. 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
  }
@@ -914,9 +793,618 @@ function ChatComposer({
914
793
  );
915
794
  }
916
795
 
917
- // src/web-react/mission-activity.tsx
918
- import { useCallback as useCallback2, useEffect as useEffect4, useState as useState4 } from "react";
796
+ // src/web-react/interaction-card-support.ts
797
+ function interactionStatusLabels(labels) {
798
+ return { cancelled: "Withdrawn", expired: "Expired", ...labels };
799
+ }
800
+ function interactionTerminalNotes(noun, extra) {
801
+ return {
802
+ expired: `This ${noun} expired \u2014 send a new message to continue.`,
803
+ cancelled: `The agent withdrew this ${noun}.`,
804
+ ...extra
805
+ };
806
+ }
807
+ function fieldAnswer(field, values) {
808
+ const value = values[field.name] ?? {};
809
+ if (field.type === "select") {
810
+ const custom = field.allowCustom === true ? value.custom?.trim() : void 0;
811
+ const chosen = [...value.selected ?? [], ...custom ? [custom] : []];
812
+ if (field.multi !== true && custom) return [custom];
813
+ return chosen.length > 0 ? chosen : null;
814
+ }
815
+ if (field.type === "number") {
816
+ const parsed = Number(value.text);
817
+ return value.text?.trim() && Number.isFinite(parsed) ? parsed : null;
818
+ }
819
+ if (field.type === "boolean") return value.selected ? value.selected[0] === "true" : null;
820
+ const text = value.text?.trim();
821
+ return text ? text : null;
822
+ }
823
+ function buildAnswerData(fields, values) {
824
+ const data = {};
825
+ for (const field of fields) {
826
+ const answer = fieldAnswer(field, values);
827
+ if (answer === null) {
828
+ if (field.required === false) continue;
829
+ return null;
830
+ }
831
+ data[field.name] = answer;
832
+ }
833
+ return data;
834
+ }
835
+ function isLateAnswerableStatus(status) {
836
+ return status === "expired" || status === "cancelled";
837
+ }
838
+ function hasSecretField(fields) {
839
+ return fields.some((field) => field.type === "secret");
840
+ }
841
+ function optionLabel(field, value) {
842
+ return field.options.find((option) => option.value === value)?.label ?? value;
843
+ }
844
+ function answerText(field, answer) {
845
+ if (field.type === "select" && Array.isArray(answer)) {
846
+ return answer.map((value) => optionLabel(field, value)).join(", ");
847
+ }
848
+ if (field.type === "boolean") return answer === true ? "Yes" : "No";
849
+ if (field.type === "secret") return "[secret omitted]";
850
+ return String(answer);
851
+ }
852
+ function lateAnswerMessage(interaction, data) {
853
+ const title = interaction.title.trim() || "the earlier question";
854
+ const body = interaction.body?.trim();
855
+ const answers = interaction.fields.map((field) => {
856
+ const answer = data[field.name];
857
+ if (answer === void 0) return null;
858
+ return { label: field.label.trim(), text: answerText(field, answer).trim() };
859
+ }).filter((item) => !!item && item.text.length > 0);
860
+ const only = answers.length === 1 ? answers[0] : void 0;
861
+ const answerSummary = only ? only.text : answers.map((item) => `${item.label || "Answer"}: ${item.text}`).join("\n");
862
+ return [
863
+ `Regarding your earlier question: "${title}"`,
864
+ body ? `Context: ${body}` : null,
865
+ `My answer: ${answerSummary}`
866
+ ].filter((line) => !!line).join("\n");
867
+ }
868
+ var INTERACTION_SUBMIT_TIMEOUT_MS = 3e4;
869
+ var INTERACTION_SUBMIT_TIMEOUT_MESSAGE = "Could not reach the agent. Try again.";
870
+ async function responseErrorMessage(res) {
871
+ const text = await res.text().catch(() => "");
872
+ if (text) {
873
+ try {
874
+ const parsed = JSON.parse(text);
875
+ const message = typeof parsed.error === "string" && parsed.error.trim() ? parsed.error : typeof parsed.message === "string" && parsed.message.trim() ? parsed.message : null;
876
+ if (message) return { ...typeof parsed.code === "string" ? { code: parsed.code } : {}, message };
877
+ } catch {
878
+ }
879
+ }
880
+ return { message: `Answer failed (${res.status})` };
881
+ }
882
+ function createInteractionAnswerSubmitter(options) {
883
+ const timeoutMs = options.timeoutMs ?? INTERACTION_SUBMIT_TIMEOUT_MS;
884
+ return async (submission) => {
885
+ const doFetch = options.fetchImpl ?? fetch;
886
+ const url = typeof options.url === "function" ? options.url(submission) : options.url;
887
+ const extra = typeof options.body === "function" ? options.body(submission) : options.body ?? {};
888
+ const controller = new AbortController();
889
+ const timer = setTimeout(() => controller.abort(INTERACTION_SUBMIT_TIMEOUT_MESSAGE), timeoutMs);
890
+ try {
891
+ const res = await doFetch(url, {
892
+ method: "POST",
893
+ headers: { "Content-Type": "application/json" },
894
+ signal: controller.signal,
895
+ body: JSON.stringify({
896
+ ...extra,
897
+ id: submission.id,
898
+ outcome: submission.outcome,
899
+ ...submission.data ? { data: submission.data } : {}
900
+ })
901
+ });
902
+ if (res.ok) return { ok: true };
903
+ const failure = await responseErrorMessage(res);
904
+ return { ok: false, expired: res.status === 410, message: failure.message };
905
+ } catch (err) {
906
+ if (controller.signal.aborted) {
907
+ return { ok: false, expired: false, message: INTERACTION_SUBMIT_TIMEOUT_MESSAGE };
908
+ }
909
+ return { ok: false, expired: false, message: err instanceof Error ? err.message : "Failed to submit the answer" };
910
+ } finally {
911
+ clearTimeout(timer);
912
+ }
913
+ };
914
+ }
915
+
916
+ // src/web-react/interaction-question-card.tsx
917
+ import { useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
919
918
  import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
919
+ function CheckGlyph({ className }) {
920
+ 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" }) });
921
+ }
922
+ var BADGE_VARIANT_CLASSES = {
923
+ outline: "border-border text-foreground",
924
+ default: "border-transparent bg-primary text-primary-foreground",
925
+ destructive: "border-transparent bg-destructive/15 text-destructive"
926
+ };
927
+ function InteractionBadge({ variant, children }) {
928
+ 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 });
929
+ }
930
+ function InteractionActionButton({
931
+ variant = "primary",
932
+ onClick,
933
+ disabled,
934
+ children
935
+ }) {
936
+ 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";
937
+ return /* @__PURE__ */ jsx5(
938
+ "button",
939
+ {
940
+ type: "button",
941
+ onClick,
942
+ disabled,
943
+ 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}`,
944
+ children
945
+ }
946
+ );
947
+ }
948
+ 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";
949
+ function QuestionOptionList({
950
+ groupName,
951
+ idPrefix,
952
+ options,
953
+ multi,
954
+ selectedValues,
955
+ disabled,
956
+ onToggle
957
+ }) {
958
+ return /* @__PURE__ */ jsx5(Fragment3, { children: options.map((option, optionIndex) => {
959
+ const inputId = `${idPrefix}-${optionIndex}`;
960
+ const checked = selectedValues.includes(option.value);
961
+ 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: [
962
+ /* @__PURE__ */ jsx5(
963
+ "input",
964
+ {
965
+ id: inputId,
966
+ type: multi ? "checkbox" : "radio",
967
+ name: groupName,
968
+ value: option.value,
969
+ checked,
970
+ disabled,
971
+ onChange: () => onToggle(option.value),
972
+ "aria-labelledby": `${inputId}-label`,
973
+ "aria-describedby": option.description ? `${inputId}-description` : void 0,
974
+ className: "mt-0.5 h-4 w-4 shrink-0 accent-primary"
975
+ }
976
+ ),
977
+ /* @__PURE__ */ jsxs4("span", { className: "min-w-0", children: [
978
+ /* @__PURE__ */ jsx5("span", { id: `${inputId}-label`, className: "block text-sm font-medium leading-5 text-foreground", children: option.label }),
979
+ option.description && /* @__PURE__ */ jsx5("span", { id: `${inputId}-description`, className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: option.description })
980
+ ] })
981
+ ] }, `${option.value}-${optionIndex}`);
982
+ }) });
983
+ }
984
+ function selectField(field) {
985
+ return field.type === "select" ? field : null;
986
+ }
987
+ function valuesWithSelected(values, field, optionValue) {
988
+ const current = values[field.name]?.selected ?? [];
989
+ let selected = [optionValue];
990
+ if (field.multi === true) {
991
+ selected = current.includes(optionValue) ? current.filter((item) => item !== optionValue) : [...current, optionValue];
992
+ }
993
+ return { ...values, [field.name]: { ...values[field.name], selected } };
994
+ }
995
+ var STATUS_LABELS = interactionStatusLabels({
996
+ pending: "Waiting for your answer",
997
+ answered: "Answered",
998
+ declined: "Declined"
999
+ });
1000
+ var TERMINAL_NOTES = interactionTerminalNotes("question", {
1001
+ expired: "The original run ended. Answer now to send a new message with this context.",
1002
+ cancelled: "The agent withdrew this question. Answer now to send a new message with this context."
1003
+ });
1004
+ function InteractionQuestionCard({
1005
+ interaction,
1006
+ canWrite,
1007
+ submitAnswer,
1008
+ onResolved,
1009
+ onLateAnswer,
1010
+ className
1011
+ }) {
1012
+ const [values, setValues] = useState4({});
1013
+ const [submitting, setSubmitting] = useState4(false);
1014
+ const [localStatus, setLocalStatus] = useState4(null);
1015
+ const [lateAnswerSent, setLateAnswerSent] = useState4(false);
1016
+ const [error, setError] = useState4(null);
1017
+ const submitInFlightRef = useRef4(false);
1018
+ const status = isTerminalInteractionStatus(interaction.status) ? interaction.status : localStatus ?? interaction.status;
1019
+ const answered = status === "answered";
1020
+ const lateAnswerable = isLateAnswerableStatus(status) && onLateAnswer !== void 0;
1021
+ const secretLateAnswerBlocked = lateAnswerable && hasSecretField(interaction.fields);
1022
+ const canLateAnswer = canWrite && lateAnswerable && !lateAnswerSent && !secretLateAnswerBlocked;
1023
+ const disabled = !canWrite || status !== "pending" && !canLateAnswer || submitting;
1024
+ const answerData = useMemo2(() => buildAnswerData(interaction.fields, values), [interaction.fields, values]);
1025
+ const setFieldValue = (name, patch) => {
1026
+ setValues((prev) => ({ ...prev, [name]: { ...prev[name], ...patch } }));
1027
+ };
1028
+ const toggleSelected = (field, optionValue) => {
1029
+ setValues((prev) => valuesWithSelected(prev, field, optionValue));
1030
+ };
1031
+ async function submitLateAnswer() {
1032
+ if (submitInFlightRef.current || !canLateAnswer || !onLateAnswer) return;
1033
+ const data = buildAnswerData(interaction.fields, values);
1034
+ if (!data) return;
1035
+ submitInFlightRef.current = true;
1036
+ setSubmitting(true);
1037
+ setError(null);
1038
+ let accepted;
1039
+ try {
1040
+ accepted = await onLateAnswer(lateAnswerMessage(interaction, data));
1041
+ } catch {
1042
+ accepted = false;
1043
+ } finally {
1044
+ submitInFlightRef.current = false;
1045
+ setSubmitting(false);
1046
+ }
1047
+ if (accepted === false) {
1048
+ setError("The new message was not sent. Try again from this card.");
1049
+ return;
1050
+ }
1051
+ setLateAnswerSent(true);
1052
+ }
1053
+ async function submit() {
1054
+ if (lateAnswerable) {
1055
+ await submitLateAnswer();
1056
+ return;
1057
+ }
1058
+ if (submitInFlightRef.current || disabled || !answerData) return;
1059
+ submitInFlightRef.current = true;
1060
+ setSubmitting(true);
1061
+ setError(null);
1062
+ try {
1063
+ const result = await submitAnswer({ id: interaction.id, outcome: "accepted", data: answerData });
1064
+ if (result.ok) {
1065
+ setLocalStatus("answered");
1066
+ onResolved?.(interaction.id, "answered");
1067
+ return;
1068
+ }
1069
+ if (result.expired) {
1070
+ setLocalStatus("expired");
1071
+ onResolved?.(interaction.id, "expired");
1072
+ return;
1073
+ }
1074
+ setError(result.message);
1075
+ } finally {
1076
+ submitInFlightRef.current = false;
1077
+ setSubmitting(false);
1078
+ }
1079
+ }
1080
+ 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];
1081
+ const showSubmitButton = status === "pending" || canWrite && lateAnswerable && !lateAnswerSent;
1082
+ let submitLabel = "Submit answer";
1083
+ if (lateAnswerable) {
1084
+ submitLabel = submitting ? "Sending\u2026" : "Send as new message";
1085
+ } else if (submitting) {
1086
+ submitLabel = "Submitting\u2026";
1087
+ }
1088
+ return /* @__PURE__ */ jsxs4("div", { className: `rounded-xl border border-border bg-card p-4 shadow-sm ${className ?? ""}`, children: [
1089
+ /* @__PURE__ */ jsxs4("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
1090
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2", children: [
1091
+ /* @__PURE__ */ jsx5(InteractionBadge, { variant: "outline", children: "Question" }),
1092
+ /* @__PURE__ */ jsx5(InteractionBadge, { variant: answered ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS[status] })
1093
+ ] }),
1094
+ /* @__PURE__ */ jsx5("span", { className: "text-xs text-muted-foreground", children: "The agent asked for input" })
1095
+ ] }),
1096
+ 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 }),
1097
+ interaction.body && /* @__PURE__ */ jsx5("p", { className: "mb-3 text-sm leading-5 text-muted-foreground", children: interaction.body }),
1098
+ /* @__PURE__ */ jsx5("div", { className: "space-y-4", children: interaction.fields.map((field) => {
1099
+ const value = values[field.name] ?? {};
1100
+ const select = selectField(field);
1101
+ return /* @__PURE__ */ jsxs4("fieldset", { className: "space-y-2", children: [
1102
+ /* @__PURE__ */ jsx5("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
1103
+ select ? /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1104
+ /* @__PURE__ */ jsx5(
1105
+ QuestionOptionList,
1106
+ {
1107
+ groupName: `${interaction.id}-${field.name}`,
1108
+ idPrefix: `${interaction.id}-${field.name}`,
1109
+ options: select.options,
1110
+ multi: select.multi === true,
1111
+ selectedValues: value.selected ?? [],
1112
+ disabled,
1113
+ onToggle: (optionValue) => toggleSelected(select, optionValue)
1114
+ }
1115
+ ),
1116
+ select.allowCustom === true && /* @__PURE__ */ jsx5(
1117
+ "input",
1118
+ {
1119
+ type: "text",
1120
+ value: value.custom ?? "",
1121
+ disabled,
1122
+ onChange: (event) => setFieldValue(field.name, { custom: event.target.value }),
1123
+ placeholder: "Other \u2014 type your own answer",
1124
+ "aria-label": `Custom answer for ${field.label}`,
1125
+ className: FIELD_INPUT_CLASSES
1126
+ }
1127
+ )
1128
+ ] }) : 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: [
1129
+ /* @__PURE__ */ jsx5(
1130
+ "input",
1131
+ {
1132
+ type: "radio",
1133
+ name: `${interaction.id}-${field.name}`,
1134
+ value: boolValue,
1135
+ checked: (value.selected ?? [])[0] === boolValue,
1136
+ disabled,
1137
+ onChange: () => setFieldValue(field.name, { selected: [boolValue] }),
1138
+ className: "h-4 w-4 accent-primary"
1139
+ }
1140
+ ),
1141
+ boolValue === "true" ? "Yes" : "No"
1142
+ ] }, boolValue)) }) : field.type === "number" ? /* @__PURE__ */ jsx5(
1143
+ "input",
1144
+ {
1145
+ type: "number",
1146
+ value: value.text ?? "",
1147
+ disabled,
1148
+ "aria-label": field.label,
1149
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
1150
+ className: FIELD_INPUT_CLASSES
1151
+ }
1152
+ ) : field.type === "secret" ? /* @__PURE__ */ jsx5(
1153
+ "input",
1154
+ {
1155
+ type: "password",
1156
+ value: value.text ?? "",
1157
+ disabled,
1158
+ "aria-label": field.label,
1159
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
1160
+ placeholder: field.placeholder,
1161
+ className: FIELD_INPUT_CLASSES
1162
+ }
1163
+ ) : /* @__PURE__ */ jsx5(
1164
+ "textarea",
1165
+ {
1166
+ value: value.text ?? "",
1167
+ disabled,
1168
+ "aria-label": field.label,
1169
+ onChange: (event) => setFieldValue(field.name, { text: event.target.value }),
1170
+ rows: 3,
1171
+ placeholder: field.type === "text" ? field.placeholder : void 0,
1172
+ className: FIELD_INPUT_CLASSES
1173
+ }
1174
+ )
1175
+ ] }, field.name);
1176
+ }) }),
1177
+ error && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-xs text-destructive", children: error }),
1178
+ terminalNote && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
1179
+ 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 }) }),
1180
+ 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: [
1181
+ /* @__PURE__ */ jsx5(CheckGlyph, { className: "h-3 w-3" }),
1182
+ "Answered"
1183
+ ] }) }),
1184
+ 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: [
1185
+ /* @__PURE__ */ jsx5(CheckGlyph, { className: "h-3 w-3" }),
1186
+ "Sent as new message"
1187
+ ] }) })
1188
+ ] });
1189
+ }
1190
+
1191
+ // src/web-react/interaction-plan-card.tsx
1192
+ import { useMemo as useMemo3, useRef as useRef5, useState as useState5 } from "react";
1193
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1194
+ function CheckGlyph2({ className }) {
1195
+ 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" }) });
1196
+ }
1197
+ function ChevronDownGlyph({ className }) {
1198
+ 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" }) });
1199
+ }
1200
+ var STATUS_LABELS2 = interactionStatusLabels({
1201
+ pending: "Waiting for your approval",
1202
+ answered: "Approved",
1203
+ declined: "Rejected"
1204
+ });
1205
+ var TERMINAL_NOTES2 = interactionTerminalNotes("plan", {
1206
+ declined: "The agent was asked to revise the plan."
1207
+ });
1208
+ var COLLAPSED_MAX_HEIGHT = 320;
1209
+ function InteractionPlanCard({
1210
+ interaction,
1211
+ canWrite,
1212
+ submitAnswer,
1213
+ onResolved,
1214
+ renderMarkdown,
1215
+ className
1216
+ }) {
1217
+ const [values, setValues] = useState5({});
1218
+ const [expanded, setExpanded] = useState5(false);
1219
+ const [submitting, setSubmitting] = useState5(null);
1220
+ const [localStatus, setLocalStatus] = useState5(null);
1221
+ const [error, setError] = useState5(null);
1222
+ const submitInFlightRef = useRef5(false);
1223
+ const status = isTerminalInteractionStatus(interaction.status) ? interaction.status : localStatus ?? interaction.status;
1224
+ const disabled = !canWrite || status !== "pending" || submitting !== null;
1225
+ const approveData = useMemo3(() => buildAnswerData(interaction.fields, values), [interaction.fields, values]);
1226
+ const rejectData = useMemo3(() => {
1227
+ const data = {};
1228
+ for (const field of interaction.fields) {
1229
+ const answer = fieldAnswer(field, values);
1230
+ if (answer !== null) data[field.name] = answer;
1231
+ }
1232
+ return data;
1233
+ }, [interaction.fields, values]);
1234
+ async function submit(outcome) {
1235
+ const data = outcome === "accepted" ? approveData : rejectData;
1236
+ if (submitInFlightRef.current || disabled || data === null) return;
1237
+ submitInFlightRef.current = true;
1238
+ setSubmitting(outcome === "accepted" ? "approve" : "reject");
1239
+ setError(null);
1240
+ try {
1241
+ const result = await submitAnswer({ id: interaction.id, outcome, data });
1242
+ if (result.ok) {
1243
+ const resolved = outcome === "accepted" ? "answered" : "declined";
1244
+ setLocalStatus(resolved);
1245
+ onResolved?.(interaction.id, resolved);
1246
+ return;
1247
+ }
1248
+ if (result.expired) {
1249
+ setLocalStatus("expired");
1250
+ onResolved?.(interaction.id, "expired");
1251
+ return;
1252
+ }
1253
+ setError(result.message);
1254
+ } finally {
1255
+ submitInFlightRef.current = false;
1256
+ setSubmitting(null);
1257
+ }
1258
+ }
1259
+ const terminalNote = TERMINAL_NOTES2[status];
1260
+ const approved = status === "answered";
1261
+ return /* @__PURE__ */ jsxs5("div", { className: `rounded-xl border border-border bg-card p-4 shadow-sm ${className ?? ""}`, children: [
1262
+ /* @__PURE__ */ jsxs5("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
1263
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2", children: [
1264
+ /* @__PURE__ */ jsx6(InteractionBadge, { variant: "outline", children: "Plan" }),
1265
+ /* @__PURE__ */ jsx6(InteractionBadge, { variant: approved ? "default" : status === "expired" || status === "declined" ? "destructive" : "outline", children: STATUS_LABELS2[status] })
1266
+ ] }),
1267
+ /* @__PURE__ */ jsx6("span", { className: "text-xs text-muted-foreground", children: "The agent proposed a plan" })
1268
+ ] }),
1269
+ interaction.title.trim() && /* @__PURE__ */ jsx6("p", { className: "mb-3 text-sm font-medium leading-5 text-foreground", children: interaction.title }),
1270
+ interaction.body && /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
1271
+ /* @__PURE__ */ jsx6(
1272
+ "div",
1273
+ {
1274
+ className: "overflow-hidden text-sm text-foreground",
1275
+ style: expanded ? void 0 : { maxHeight: COLLAPSED_MAX_HEIGHT },
1276
+ children: renderMarkdown ? renderMarkdown(interaction.body) : /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap leading-5", children: interaction.body })
1277
+ }
1278
+ ),
1279
+ !expanded && /* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-card to-transparent" }),
1280
+ /* @__PURE__ */ jsxs5(
1281
+ "button",
1282
+ {
1283
+ type: "button",
1284
+ onClick: () => setExpanded((prev) => !prev),
1285
+ 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",
1286
+ children: [
1287
+ /* @__PURE__ */ jsx6(ChevronDownGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
1288
+ expanded ? "Collapse plan" : "Show full plan"
1289
+ ]
1290
+ }
1291
+ )
1292
+ ] }),
1293
+ 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: [
1294
+ /* @__PURE__ */ jsx6("p", { className: "text-sm font-medium leading-5 text-foreground", children: field.label }),
1295
+ fieldAcceptsFreeText(field) ? /* @__PURE__ */ jsx6(
1296
+ "textarea",
1297
+ {
1298
+ value: values[field.name]?.text ?? "",
1299
+ disabled,
1300
+ "aria-label": field.label,
1301
+ onChange: (event) => setValues((prev) => ({ ...prev, [field.name]: { ...prev[field.name], text: event.target.value } })),
1302
+ rows: 2,
1303
+ placeholder: field.type === "text" ? field.placeholder ?? "Optional feedback for the agent" : void 0,
1304
+ 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"
1305
+ }
1306
+ ) : /* @__PURE__ */ jsx6(
1307
+ "input",
1308
+ {
1309
+ type: "text",
1310
+ value: values[field.name]?.text ?? "",
1311
+ disabled,
1312
+ "aria-label": field.label,
1313
+ onChange: (event) => setValues((prev) => ({ ...prev, [field.name]: { ...prev[field.name], text: event.target.value } })),
1314
+ 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"
1315
+ }
1316
+ )
1317
+ ] }, field.name)) }),
1318
+ error && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-xs text-destructive", children: error }),
1319
+ terminalNote && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-xs text-muted-foreground", children: terminalNote }),
1320
+ status === "pending" && /* @__PURE__ */ jsxs5("div", { className: "mt-4 flex items-center justify-end gap-2", children: [
1321
+ /* @__PURE__ */ jsx6(InteractionActionButton, { variant: "outline", onClick: () => void submit("declined"), disabled, children: submitting === "reject" ? "Sending\u2026" : "Request changes" }),
1322
+ /* @__PURE__ */ jsx6(InteractionActionButton, { onClick: () => void submit("accepted"), disabled: disabled || approveData === null, children: submitting === "approve" ? "Approving\u2026" : "Approve plan" })
1323
+ ] }),
1324
+ 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: [
1325
+ /* @__PURE__ */ jsx6(CheckGlyph2, { className: "h-3 w-3" }),
1326
+ "Approved"
1327
+ ] }) })
1328
+ ] });
1329
+ }
1330
+
1331
+ // src/web-react/use-chat-interactions.ts
1332
+ import { useCallback as useCallback2, useMemo as useMemo4, useState as useState6 } from "react";
1333
+ function hasPendingContentDuplicate(list, interaction) {
1334
+ if (interaction.status !== "pending") return false;
1335
+ const signature = questionInteractionContentSignature(interaction);
1336
+ if (!signature) return false;
1337
+ return list.some((item) => item.id !== interaction.id && item.status === "pending" && questionInteractionContentSignature(item) === signature);
1338
+ }
1339
+ function upsertChatInteraction(list, interaction) {
1340
+ const index = list.findIndex((item) => item.id === interaction.id);
1341
+ if (index === -1) {
1342
+ if (hasPendingContentDuplicate(list, interaction)) return list;
1343
+ return [...list, interaction];
1344
+ }
1345
+ const existing = list[index];
1346
+ if (!existing || isTerminalInteractionStatus(existing.status)) return list;
1347
+ const next = [...list];
1348
+ next[index] = interaction;
1349
+ return next;
1350
+ }
1351
+ function cancelChatInteraction(list, cancel) {
1352
+ const index = list.findIndex((item) => item.id === cancel.id);
1353
+ const existing = list[index];
1354
+ if (!existing || existing.status !== "pending") return list;
1355
+ const next = [...list];
1356
+ next[index] = {
1357
+ ...existing,
1358
+ status: cancelStatusFor(cancel.reason),
1359
+ ...cancel.reason ? { cancelReason: cancel.reason } : {}
1360
+ };
1361
+ return next;
1362
+ }
1363
+ function resolveChatInteraction(list, id, status) {
1364
+ const index = list.findIndex((item) => item.id === id);
1365
+ const existing = list[index];
1366
+ if (!existing || existing.status !== "pending") return list;
1367
+ const next = [...list];
1368
+ next[index] = { ...existing, status };
1369
+ return next;
1370
+ }
1371
+ function terminalizePendingChatInteractions(list, status) {
1372
+ if (!list.some((item) => item.status === "pending")) return list;
1373
+ return list.map((item) => item.status === "pending" ? { ...item, status } : item);
1374
+ }
1375
+ function restoreChatInteractions(list, outstanding) {
1376
+ const outstandingIds = new Set(outstanding.map((request) => request.id));
1377
+ let next = list.map((item) => item.status === "pending" && !outstandingIds.has(item.id) ? { ...item, status: "answered" } : item);
1378
+ for (const request of outstanding) {
1379
+ next = upsertChatInteraction(next, interactionFromWireRequest(request));
1380
+ }
1381
+ return next;
1382
+ }
1383
+ function useChatInteractions() {
1384
+ const [interactions, setInteractions] = useState6([]);
1385
+ const upsert = useCallback2((interaction) => {
1386
+ setInteractions((prev) => upsertChatInteraction(prev, interaction));
1387
+ }, []);
1388
+ const applyCancel = useCallback2((cancel) => {
1389
+ setInteractions((prev) => cancelChatInteraction(prev, cancel));
1390
+ }, []);
1391
+ const markResolved = useCallback2((id, status) => {
1392
+ setInteractions((prev) => resolveChatInteraction(prev, id, status));
1393
+ }, []);
1394
+ const restore = useCallback2((outstanding) => {
1395
+ setInteractions((prev) => restoreChatInteractions(prev, outstanding));
1396
+ }, []);
1397
+ const terminalizePending = useCallback2((status) => {
1398
+ setInteractions((prev) => terminalizePendingChatInteractions(prev, status));
1399
+ }, []);
1400
+ const reset = useCallback2(() => setInteractions([]), []);
1401
+ const pending = useMemo4(() => interactions.filter((item) => item.status === "pending"), [interactions]);
1402
+ return { interactions, pending, upsert, applyCancel, markResolved, restore, terminalizePending, reset };
1403
+ }
1404
+
1405
+ // src/web-react/mission-activity.tsx
1406
+ import { useCallback as useCallback3, useEffect as useEffect4, useState as useState7 } from "react";
1407
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
920
1408
  var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
921
1409
  var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
922
1410
  var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
@@ -963,20 +1451,20 @@ function waterfallLayout(trace) {
963
1451
  });
964
1452
  }
965
1453
  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" }) });
1454
+ 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
1455
  }
968
1456
  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" }) });
1457
+ 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
1458
  }
971
1459
  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" })
1460
+ return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1461
+ /* @__PURE__ */ jsx7("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
1462
+ /* @__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
1463
  ] });
976
1464
  }
977
1465
  function TraceIdCopy({ traceId }) {
978
- const [copied, setCopied] = useState4(false);
979
- const copy = useCallback2(() => {
1466
+ const [copied, setCopied] = useState7(false);
1467
+ const copy = useCallback3(() => {
980
1468
  void navigator.clipboard?.writeText(traceId).then(
981
1469
  () => {
982
1470
  setCopied(true);
@@ -986,7 +1474,7 @@ function TraceIdCopy({ traceId }) {
986
1474
  }
987
1475
  );
988
1476
  }, [traceId]);
989
- return /* @__PURE__ */ jsxs4(
1477
+ return /* @__PURE__ */ jsxs6(
990
1478
  "button",
991
1479
  {
992
1480
  type: "button",
@@ -995,23 +1483,23 @@ function TraceIdCopy({ traceId }) {
995
1483
  "aria-label": "Copy trace id",
996
1484
  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
1485
  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" })
1486
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: traceId }),
1487
+ /* @__PURE__ */ jsx7(CopyGlyph, { className: "h-3 w-3 shrink-0" }),
1488
+ copied && /* @__PURE__ */ jsx7("span", { className: "shrink-0 not-italic text-success", children: "copied" })
1001
1489
  ]
1002
1490
  }
1003
1491
  );
1004
1492
  }
1005
1493
  function StatusDot({ tone }) {
1006
- return /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center", children: [
1007
- /* @__PURE__ */ jsx5(
1494
+ return /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center", children: [
1495
+ /* @__PURE__ */ jsx7(
1008
1496
  "span",
1009
1497
  {
1010
1498
  "aria-hidden": true,
1011
1499
  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
1500
  }
1013
1501
  ),
1014
- /* @__PURE__ */ jsx5("span", { className: "sr-only", children: tone })
1502
+ /* @__PURE__ */ jsx7("span", { className: "sr-only", children: tone })
1015
1503
  ] });
1016
1504
  }
1017
1505
  var BAR_CLASS = {
@@ -1023,19 +1511,19 @@ function FlowWaterfall({ trace }) {
1023
1511
  const rows = waterfallLayout(trace);
1024
1512
  if (rows.length === 0) return null;
1025
1513
  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(
1514
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
1515
+ rows.map((row, i) => /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
1516
+ /* @__PURE__ */ jsx7("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
1517
+ /* @__PURE__ */ jsx7("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx7(
1030
1518
  "div",
1031
1519
  {
1032
1520
  className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-destructive/80"} ${row.approx ? "opacity-70" : ""}`,
1033
1521
  style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
1034
1522
  }
1035
1523
  ) }),
1036
- /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
1524
+ /* @__PURE__ */ jsx7("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
1037
1525
  ] }, i)),
1038
- /* @__PURE__ */ jsxs4("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
1526
+ /* @__PURE__ */ jsxs6("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
1039
1527
  (trace.totalMs / 1e3).toFixed(1),
1040
1528
  "s",
1041
1529
  cost ? ` \xB7 ${cost}` : ""
@@ -1043,43 +1531,43 @@ function FlowWaterfall({ trace }) {
1043
1531
  ] });
1044
1532
  }
1045
1533
  function MissionActivityLane({ activity, startedAt, nowMs }) {
1046
- const [expanded, setExpanded] = useState4(false);
1534
+ const [expanded, setExpanded] = useState7(false);
1047
1535
  if (activity.length === 0) return null;
1048
- return /* @__PURE__ */ jsxs4("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
1536
+ return /* @__PURE__ */ jsxs6("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
1049
1537
  activity.map((run) => {
1050
1538
  const tone = activityTone(run.status);
1051
1539
  const cost = formatActivityCost(run.costUsd);
1052
1540
  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: [
1541
+ return /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
1542
+ /* @__PURE__ */ jsx7(StatusDot, { tone }),
1543
+ /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
1544
+ /* @__PURE__ */ jsx7("span", { className: "font-medium", children: run.tool }),
1545
+ /* @__PURE__ */ jsxs6("span", { className: "text-muted-foreground", children: [
1058
1546
  " \u2014 ",
1059
1547
  run.detail
1060
1548
  ] })
1061
1549
  ] }),
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 })
1550
+ 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 ") }),
1551
+ /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
1552
+ tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx7("span", { children: run.status }),
1553
+ cost && /* @__PURE__ */ jsx7("span", { children: cost }),
1554
+ duration && /* @__PURE__ */ jsx7("span", { children: duration })
1067
1555
  ] })
1068
1556
  ] }, run.taskId);
1069
1557
  }),
1070
- /* @__PURE__ */ jsxs4(
1558
+ /* @__PURE__ */ jsxs6(
1071
1559
  "button",
1072
1560
  {
1073
1561
  type: "button",
1074
1562
  onClick: () => setExpanded((v) => !v),
1075
1563
  className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
1076
1564
  children: [
1077
- /* @__PURE__ */ jsx5(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
1565
+ /* @__PURE__ */ jsx7(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
1078
1566
  "timeline"
1079
1567
  ]
1080
1568
  }
1081
1569
  ),
1082
- expanded && /* @__PURE__ */ jsx5("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx5(
1570
+ expanded && /* @__PURE__ */ jsx7("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx7(
1083
1571
  FlowWaterfall,
1084
1572
  {
1085
1573
  trace: stepActivityFlowTrace(activity, {
@@ -1094,45 +1582,45 @@ function ActivityRow({
1094
1582
  record,
1095
1583
  renderMissionRef
1096
1584
  }) {
1097
- const [open, setOpen] = useState4(false);
1585
+ const [open, setOpen] = useState7(false);
1098
1586
  const tone = activityTone(record.status);
1099
1587
  const cost = formatActivityCost(record.costUsd);
1100
1588
  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: [
1589
+ return /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border/60 bg-card", children: [
1590
+ /* @__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: [
1591
+ /* @__PURE__ */ jsx7(StatusDot, { tone }),
1592
+ /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
1593
+ /* @__PURE__ */ jsx7("span", { className: "font-medium", children: record.tool }),
1594
+ /* @__PURE__ */ jsxs6("span", { className: "text-muted-foreground", children: [
1107
1595
  " \u2014 ",
1108
1596
  record.detail
1109
1597
  ] })
1110
1598
  ] }),
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(
1599
+ 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 ") }),
1600
+ /* @__PURE__ */ jsx7(
1113
1601
  "span",
1114
1602
  {
1115
1603
  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
1604
  children: record.status
1117
1605
  }
1118
1606
  ),
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" : ""}` })
1607
+ cost && /* @__PURE__ */ jsx7("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
1608
+ /* @__PURE__ */ jsx7(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
1121
1609
  ] }),
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 })
1610
+ open && /* @__PURE__ */ jsxs6("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
1611
+ 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]) }) }),
1612
+ /* @__PURE__ */ jsxs6("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
1613
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "task" }),
1614
+ /* @__PURE__ */ jsx7("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
1615
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "started" }),
1616
+ /* @__PURE__ */ jsx7("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
1617
+ duration && /* @__PURE__ */ jsxs6(Fragment4, { children: [
1618
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "duration" }),
1619
+ /* @__PURE__ */ jsx7("dd", { className: "text-muted-foreground", children: duration })
1132
1620
  ] }),
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 }) })
1621
+ record.traceId && /* @__PURE__ */ jsxs6(Fragment4, { children: [
1622
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground/60", children: "trace" }),
1623
+ /* @__PURE__ */ jsx7("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx7(TraceIdCopy, { traceId: record.traceId }) })
1136
1624
  ] })
1137
1625
  ] }),
1138
1626
  record.missionRef && renderMissionRef?.(record.missionRef, record)
@@ -1140,11 +1628,11 @@ function ActivityRow({
1140
1628
  ] });
1141
1629
  }
1142
1630
  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(
1631
+ const [rows, setRows] = useState7([]);
1632
+ const [cursor, setCursor] = useState7(void 0);
1633
+ const [loading, setLoading] = useState7(false);
1634
+ const [error, setError] = useState7(null);
1635
+ const load = useCallback3(
1148
1636
  async (from) => {
1149
1637
  setLoading(true);
1150
1638
  setError(null);
@@ -1163,10 +1651,10 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1163
1651
  useEffect4(() => {
1164
1652
  void load();
1165
1653
  }, [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(
1654
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
1655
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
1656
+ /* @__PURE__ */ jsx7("h2", { className: "flex-1 text-sm font-semibold", children: title }),
1657
+ /* @__PURE__ */ jsx7(
1170
1658
  "button",
1171
1659
  {
1172
1660
  type: "button",
@@ -1174,14 +1662,14 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1174
1662
  disabled: loading,
1175
1663
  "aria-label": "Refresh",
1176
1664
  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" : ""}` })
1665
+ children: /* @__PURE__ */ jsx7(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
1178
1666
  }
1179
1667
  )
1180
1668
  ] }),
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(
1669
+ 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 }),
1670
+ !error && rows.length === 0 && !loading && /* @__PURE__ */ jsx7("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
1671
+ /* @__PURE__ */ jsx7("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx7(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
1672
+ cursor && /* @__PURE__ */ jsx7(
1185
1673
  "button",
1186
1674
  {
1187
1675
  type: "button",
@@ -1195,9 +1683,9 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1195
1683
  }
1196
1684
 
1197
1685
  // 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(
1686
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1687
+ function CheckGlyph3() {
1688
+ return /* @__PURE__ */ jsx8(
1201
1689
  "svg",
1202
1690
  {
1203
1691
  className: "h-4 w-4 shrink-0 text-primary",
@@ -1208,14 +1696,14 @@ function CheckGlyph() {
1208
1696
  strokeLinecap: "round",
1209
1697
  strokeLinejoin: "round",
1210
1698
  "aria-hidden": true,
1211
- children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" })
1699
+ children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
1212
1700
  }
1213
1701
  );
1214
1702
  }
1215
1703
  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 })
1704
+ return /* @__PURE__ */ jsxs7("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
1705
+ /* @__PURE__ */ jsx8("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx8(CheckGlyph3, {}) }),
1706
+ /* @__PURE__ */ jsx8("span", { children })
1219
1707
  ] });
1220
1708
  }
1221
1709
  function SeatPaywall({
@@ -1229,30 +1717,30 @@ function SeatPaywall({
1229
1717
  footnote
1230
1718
  }) {
1231
1719
  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: [
1720
+ 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: [
1721
+ /* @__PURE__ */ jsx8("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
1722
+ /* @__PURE__ */ jsxs7("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
1235
1723
  "Unlock ",
1236
1724
  product
1237
1725
  ] }),
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: [
1726
+ tagline && /* @__PURE__ */ jsx8("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
1727
+ /* @__PURE__ */ jsxs7("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
1728
+ /* @__PURE__ */ jsxs7("span", { className: "text-3xl font-semibold text-foreground", children: [
1241
1729
  "$",
1242
1730
  priceUsd
1243
1731
  ] }),
1244
- /* @__PURE__ */ jsx6("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1732
+ /* @__PURE__ */ jsx8("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1245
1733
  ] }),
1246
- /* @__PURE__ */ jsxs5("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1734
+ /* @__PURE__ */ jsxs7("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1247
1735
  "Includes $",
1248
1736
  includedUsageUsd,
1249
1737
  "/mo of AI usage"
1250
1738
  ] }),
1251
- /* @__PURE__ */ jsx6("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
1739
+ /* @__PURE__ */ jsx8("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
1252
1740
  `Full access to ${product}`,
1253
1741
  `$${includedUsageUsd}/mo of AI usage included, every month`
1254
- ]).map((benefit, i) => /* @__PURE__ */ jsx6(Benefit, { children: benefit }, i)) }),
1255
- /* @__PURE__ */ jsx6(
1742
+ ]).map((benefit, i) => /* @__PURE__ */ jsx8(Benefit, { children: benefit }, i)) }),
1743
+ /* @__PURE__ */ jsx8(
1256
1744
  "button",
1257
1745
  {
1258
1746
  type: "button",
@@ -1262,13 +1750,13 @@ function SeatPaywall({
1262
1750
  children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
1263
1751
  }
1264
1752
  ),
1265
- footnote && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
1753
+ footnote && /* @__PURE__ */ jsx8("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
1266
1754
  ] }) });
1267
1755
  }
1268
1756
 
1269
1757
  // 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";
1758
+ import { useMemo as useMemo5, useState as useState8 } from "react";
1759
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1272
1760
  var HARNESS_LABELS = {
1273
1761
  opencode: "OpenCode (any model)",
1274
1762
  "claude-code": "Claude Code (Anthropic)",
@@ -1288,12 +1776,12 @@ function harnessLabel(h) {
1288
1776
  return HARNESS_LABELS[h] ?? h;
1289
1777
  }
1290
1778
  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" }) });
1779
+ 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
1780
  }
1293
1781
  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" })
1782
+ return /* @__PURE__ */ jsxs8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1783
+ /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "3" }),
1784
+ /* @__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
1785
  ] });
1298
1786
  }
1299
1787
  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 +1790,11 @@ function HarnessPicker({
1302
1790
  onChange,
1303
1791
  available
1304
1792
  }) {
1305
- const [open, setOpen] = useState5(false);
1793
+ const [open, setOpen] = useState8(false);
1306
1794
  const { containerRef, triggerProps } = usePopover(open, setOpen);
1307
1795
  const options = available ?? Object.keys(HARNESS_LABELS);
1308
- return /* @__PURE__ */ jsxs6("div", { ref: containerRef, className: "relative inline-flex", children: [
1309
- /* @__PURE__ */ jsxs6(
1796
+ return /* @__PURE__ */ jsxs8("div", { ref: containerRef, className: "relative inline-flex", children: [
1797
+ /* @__PURE__ */ jsxs8(
1310
1798
  "button",
1311
1799
  {
1312
1800
  type: "button",
@@ -1315,12 +1803,12 @@ function HarnessPicker({
1315
1803
  title: "Agent backend",
1316
1804
  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
1805
  children: [
1318
- /* @__PURE__ */ jsx7("span", { className: "truncate", children: harnessLabel(value) }),
1319
- /* @__PURE__ */ jsx7(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1806
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: harnessLabel(value) }),
1807
+ /* @__PURE__ */ jsx9(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1320
1808
  ]
1321
1809
  }
1322
1810
  ),
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(
1811
+ 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
1812
  "button",
1325
1813
  {
1326
1814
  type: "button",
@@ -1339,7 +1827,7 @@ function HarnessPicker({
1339
1827
  }
1340
1828
  function useCoherentHandlers(props) {
1341
1829
  const { model, models, harness, onModelChange, onHarnessChange } = props;
1342
- const canonicalIds = useMemo2(() => models.map((m) => m.id), [models]);
1830
+ const canonicalIds = useMemo5(() => models.map((m) => m.id), [models]);
1343
1831
  const onModel = (next) => {
1344
1832
  onModelChange(next);
1345
1833
  const nextHarness = snapHarnessToModel(harness, next);
@@ -1367,11 +1855,11 @@ function AgentSessionControls(props) {
1367
1855
  className
1368
1856
  } = props;
1369
1857
  const { onModel, onHarness } = useCoherentHandlers(props);
1370
- const [open, setOpen] = useState5(false);
1858
+ const [open, setOpen] = useState8(false);
1371
1859
  const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
1372
1860
  const selectedModel = models.find((m) => m.id === model);
1373
1861
  const showEffort = selectedModel?.supportsReasoning ?? true;
1374
- const modelPicker = /* @__PURE__ */ jsx7(
1862
+ const modelPicker = /* @__PURE__ */ jsx9(
1375
1863
  ModelPicker,
1376
1864
  {
1377
1865
  value: model,
@@ -1382,17 +1870,17 @@ function AgentSessionControls(props) {
1382
1870
  }
1383
1871
  );
1384
1872
  if (layout === "inline") {
1385
- return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1873
+ return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1386
1874
  modelPicker,
1387
- showHarness && /* @__PURE__ */ jsx7(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1388
- showEffort && /* @__PURE__ */ jsx7(EffortPicker, { value: effort, onChange: onEffortChange })
1875
+ showHarness && /* @__PURE__ */ jsx9(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1876
+ showEffort && /* @__PURE__ */ jsx9(EffortPicker, { value: effort, onChange: onEffortChange })
1389
1877
  ] });
1390
1878
  }
1391
1879
  const hasAdvanced = showHarness || showEffort;
1392
- return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1880
+ return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1393
1881
  modelPicker,
1394
- hasAdvanced && /* @__PURE__ */ jsxs6("div", { ref: popoverRef, className: "relative inline-flex", children: [
1395
- /* @__PURE__ */ jsx7(
1882
+ hasAdvanced && /* @__PURE__ */ jsxs8("div", { ref: popoverRef, className: "relative inline-flex", children: [
1883
+ /* @__PURE__ */ jsx9(
1396
1884
  "button",
1397
1885
  {
1398
1886
  type: "button",
@@ -1401,19 +1889,19 @@ function AgentSessionControls(props) {
1401
1889
  title: "Model settings \u2014 pick the agent backend and how hard it thinks",
1402
1890
  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
1891
  "data-state": open ? "open" : "closed",
1404
- children: /* @__PURE__ */ jsx7(GearGlyph, { className: "h-4 w-4" })
1892
+ children: /* @__PURE__ */ jsx9(GearGlyph, { className: "h-4 w-4" })
1405
1893
  }
1406
1894
  ),
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." })
1895
+ 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: [
1896
+ showHarness && /* @__PURE__ */ jsxs8("div", { className: "space-y-1.5", children: [
1897
+ /* @__PURE__ */ jsx9("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1898
+ /* @__PURE__ */ jsx9(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1899
+ /* @__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
1900
  ] }),
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." })
1901
+ showEffort && /* @__PURE__ */ jsxs8("div", { className: "space-y-1.5", children: [
1902
+ /* @__PURE__ */ jsx9("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
1903
+ /* @__PURE__ */ jsx9(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
1904
+ /* @__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
1905
  ] })
1418
1906
  ] })
1419
1907
  ] })
@@ -1421,7 +1909,7 @@ function AgentSessionControls(props) {
1421
1909
  }
1422
1910
 
1423
1911
  // src/web-react/index.tsx
1424
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1912
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1425
1913
  function formatModelCost(msg, models) {
1426
1914
  if (msg.promptTokens == null && msg.completionTokens == null) return null;
1427
1915
  const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
@@ -1435,41 +1923,41 @@ function formatTokensPerSecond(msg) {
1435
1923
  return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
1436
1924
  }
1437
1925
  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(
1926
+ 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: [
1927
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1928
+ /* @__PURE__ */ jsx10(
1441
1929
  "span",
1442
1930
  {
1443
1931
  className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
1444
1932
  }
1445
1933
  ),
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 })
1934
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
1935
+ /* @__PURE__ */ jsx10("p", { className: "truncate text-sm font-semibold", children: run.title }),
1936
+ /* @__PURE__ */ jsx10("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1449
1937
  ] }),
1450
- /* @__PURE__ */ jsx8(
1938
+ /* @__PURE__ */ jsx10(
1451
1939
  "button",
1452
1940
  {
1453
1941
  type: "button",
1454
1942
  onClick: onClose,
1455
1943
  "aria-label": "Close",
1456
1944
  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" }) })
1945
+ 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
1946
  }
1459
1947
  )
1460
1948
  ] }),
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() })
1949
+ /* @__PURE__ */ jsxs9("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1950
+ run.steps.length === 0 && /* @__PURE__ */ jsx10("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1951
+ run.steps.map((step, i) => /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1952
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1953
+ /* @__PURE__ */ jsx10("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1954
+ /* @__PURE__ */ jsx10("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1955
+ /* @__PURE__ */ jsx10("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
1468
1956
  ] }),
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 })
1957
+ 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
1958
  ] }, i))
1471
1959
  ] }),
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." })
1960
+ /* @__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
1961
  ] });
1474
1962
  }
1475
1963
  function pendingApprovalOf(call) {
@@ -1483,20 +1971,20 @@ function ChatEmptyState({
1483
1971
  subline = "Describe the outcome you want. The agent works through it step by step, and pauses for your approval before anything irreversible.",
1484
1972
  doors
1485
1973
  }) {
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(
1974
+ 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: [
1975
+ /* @__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" }) }),
1976
+ /* @__PURE__ */ jsx10("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
1977
+ /* @__PURE__ */ jsx10("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
1978
+ subline && /* @__PURE__ */ jsx10("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
1979
+ 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
1980
  "button",
1493
1981
  {
1494
1982
  type: "button",
1495
1983
  onClick: door.onSelect,
1496
1984
  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
1985
  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 })
1986
+ /* @__PURE__ */ jsx10("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
1987
+ door.description && /* @__PURE__ */ jsx10("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
1500
1988
  ]
1501
1989
  },
1502
1990
  i
@@ -1505,26 +1993,26 @@ function ChatEmptyState({
1505
1993
  }
1506
1994
  function ToolGlyph({ name, className }) {
1507
1995
  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" })
1996
+ return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1997
+ /* @__PURE__ */ jsx10("polyline", { points: "4 17 10 11 4 5" }),
1998
+ /* @__PURE__ */ jsx10("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
1511
1999
  ] });
1512
2000
  }
1513
2001
  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" })
2002
+ return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
2003
+ /* @__PURE__ */ jsx10("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2004
+ /* @__PURE__ */ jsx10("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
1517
2005
  ] });
1518
2006
  }
1519
2007
  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" })
2008
+ return /* @__PURE__ */ jsxs9("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
2009
+ /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "9" }),
2010
+ /* @__PURE__ */ jsx10("path", { d: "M12 7v5l3 3" })
1523
2011
  ] });
1524
2012
  }
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" })
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: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
2015
+ /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "4" })
1528
2016
  ] });
1529
2017
  }
1530
2018
  function toolOutcomeOf(call) {
@@ -1591,36 +2079,36 @@ function truncate(v, max = 240) {
1591
2079
  function KvRows({ data }) {
1592
2080
  const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
1593
2081
  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) })
2082
+ 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: [
2083
+ /* @__PURE__ */ jsx10("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
2084
+ /* @__PURE__ */ jsx10("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
1597
2085
  ] }, k)) });
1598
2086
  }
1599
2087
  function ShellDetail({ call }) {
1600
2088
  const outcome = toolOutcomeOf(call);
1601
2089
  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: [
2090
+ return /* @__PURE__ */ jsxs9("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
2091
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
2092
+ /* @__PURE__ */ jsx10("span", { className: "select-none text-zinc-500", children: "$" }),
2093
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
2094
+ r.exitCode != null && /* @__PURE__ */ jsxs9("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
1607
2095
  "exit ",
1608
2096
  r.exitCode
1609
2097
  ] })
1610
2098
  ] }),
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)" })
2099
+ /* @__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
2100
  ] });
1613
2101
  }
1614
2102
  function DefaultToolDetail({ call }) {
1615
2103
  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 })
2104
+ return /* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
2105
+ call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs9("div", { children: [
2106
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
2107
+ /* @__PURE__ */ jsx10(KvRows, { data: call.args })
1620
2108
  ] }),
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) })
2109
+ outcome && /* @__PURE__ */ jsxs9("div", { children: [
2110
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
2111
+ 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
2112
  ] })
1625
2113
  ] });
1626
2114
  }
@@ -1631,23 +2119,23 @@ function ProposalCard({
1631
2119
  approval,
1632
2120
  renderers
1633
2121
  }) {
1634
- const [expanded, setExpanded] = useState6(false);
2122
+ const [expanded, setExpanded] = useState9(false);
1635
2123
  const { summary, meta } = proposalPreview(call);
1636
2124
  const custom = renderers?.[call.name]?.(call, message);
1637
2125
  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)) })
2126
+ 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: [
2127
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
2128
+ /* @__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" }) }),
2129
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
2130
+ /* @__PURE__ */ jsx10("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
2131
+ /* @__PURE__ */ jsx10("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
2132
+ summary && /* @__PURE__ */ jsx10("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
2133
+ 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
2134
  ] })
1647
2135
  ] }),
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(
2136
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
2137
+ approval ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
2138
+ /* @__PURE__ */ jsx10(
1651
2139
  "button",
1652
2140
  {
1653
2141
  type: "button",
@@ -1657,7 +2145,7 @@ function ProposalCard({
1657
2145
  children: "Approve & run"
1658
2146
  }
1659
2147
  ),
1660
- /* @__PURE__ */ jsx8(
2148
+ /* @__PURE__ */ jsx10(
1661
2149
  "button",
1662
2150
  {
1663
2151
  type: "button",
@@ -1667,8 +2155,8 @@ function ProposalCard({
1667
2155
  children: "Reject"
1668
2156
  }
1669
2157
  )
1670
- ] }) : /* @__PURE__ */ jsx8("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
1671
- /* @__PURE__ */ jsxs7(
2158
+ ] }) : /* @__PURE__ */ jsx10("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
2159
+ /* @__PURE__ */ jsxs9(
1672
2160
  "button",
1673
2161
  {
1674
2162
  type: "button",
@@ -1677,23 +2165,23 @@ function ProposalCard({
1677
2165
  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
2166
  children: [
1679
2167
  expanded ? "Hide details" : "View details",
1680
- /* @__PURE__ */ jsx8(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
2168
+ /* @__PURE__ */ jsx10(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
1681
2169
  ]
1682
2170
  }
1683
2171
  )
1684
2172
  ] }),
1685
- expanded && /* @__PURE__ */ jsx8("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx8(DefaultToolDetail, { call }) })
2173
+ expanded && /* @__PURE__ */ jsx10("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx10(DefaultToolDetail, { call }) })
1686
2174
  ] });
1687
2175
  }
1688
2176
  function FollowupCard({ call }) {
1689
2177
  const a = call.args ?? {};
1690
2178
  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) })
2179
+ 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: [
2180
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
2181
+ /* @__PURE__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
2182
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
1695
2183
  ] }),
1696
- when && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
2184
+ when && /* @__PURE__ */ jsx10("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
1697
2185
  ] });
1698
2186
  }
1699
2187
  function ToolCallCard({
@@ -1703,13 +2191,13 @@ function ToolCallCard({
1703
2191
  onOpenRun,
1704
2192
  renderers
1705
2193
  }) {
1706
- const [expanded, setExpanded] = useState6(false);
2194
+ const [expanded, setExpanded] = useState9(false);
1707
2195
  const pending = call.status === "done" ? pendingApprovalOf(call) : null;
1708
2196
  const kind = blockKindOf(call);
1709
2197
  const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
1710
2198
  const custom = renderers?.[call.name]?.(call, message);
1711
2199
  if (pending) {
1712
- return /* @__PURE__ */ jsx8(
2200
+ return /* @__PURE__ */ jsx10(
1713
2201
  ProposalCard,
1714
2202
  {
1715
2203
  call,
@@ -1721,16 +2209,16 @@ function ToolCallCard({
1721
2209
  );
1722
2210
  }
1723
2211
  if (kind === "followup" && !failed) {
1724
- return /* @__PURE__ */ jsx8(FollowupCard, { call });
2212
+ return /* @__PURE__ */ jsx10(FollowupCard, { call });
1725
2213
  }
1726
2214
  const isCommand = kind === "command";
1727
- return /* @__PURE__ */ jsxs7(
2215
+ return /* @__PURE__ */ jsxs9(
1728
2216
  "div",
1729
2217
  {
1730
2218
  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
2219
  children: [
1732
- /* @__PURE__ */ jsxs7("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
1733
- /* @__PURE__ */ jsxs7(
2220
+ /* @__PURE__ */ jsxs9("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
2221
+ /* @__PURE__ */ jsxs9(
1734
2222
  "button",
1735
2223
  {
1736
2224
  type: "button",
@@ -1738,14 +2226,14 @@ function ToolCallCard({
1738
2226
  "aria-expanded": expanded,
1739
2227
  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
2228
  children: [
1741
- /* @__PURE__ */ jsx8(
2229
+ /* @__PURE__ */ jsx10(
1742
2230
  "span",
1743
2231
  {
1744
2232
  className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : failed ? "bg-destructive" : "bg-success"}`
1745
2233
  }
1746
2234
  ),
1747
- /* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1748
- /* @__PURE__ */ jsx8(
2235
+ /* @__PURE__ */ jsx10(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
2236
+ /* @__PURE__ */ jsx10(
1749
2237
  "span",
1750
2238
  {
1751
2239
  className: `min-w-0 flex-1 truncate ${isCommand ? "font-mono text-[12px] tracking-tight text-foreground/90" : "font-medium"}`,
@@ -1755,8 +2243,8 @@ function ToolCallCard({
1755
2243
  ]
1756
2244
  }
1757
2245
  ),
1758
- /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
1759
- /* @__PURE__ */ jsx8(
2246
+ /* @__PURE__ */ jsx10("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
2247
+ /* @__PURE__ */ jsx10(
1760
2248
  "button",
1761
2249
  {
1762
2250
  type: "button",
@@ -1764,13 +2252,13 @@ function ToolCallCard({
1764
2252
  "aria-label": expanded ? "Collapse details" : "Expand details",
1765
2253
  "aria-expanded": expanded,
1766
2254
  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" : ""}` })
2255
+ children: /* @__PURE__ */ jsx10(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
1768
2256
  }
1769
2257
  )
1770
2258
  ] }),
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(
2259
+ expanded && /* @__PURE__ */ jsxs9("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
2260
+ custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx10(ShellDetail, { call }) : /* @__PURE__ */ jsx10(DefaultToolDetail, { call })),
2261
+ onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx10(
1774
2262
  "button",
1775
2263
  {
1776
2264
  type: "button",
@@ -1785,7 +2273,7 @@ function ToolCallCard({
1785
2273
  );
1786
2274
  }
1787
2275
  function StreamingCaret() {
1788
- return /* @__PURE__ */ jsx8(
2276
+ return /* @__PURE__ */ jsx10(
1789
2277
  "span",
1790
2278
  {
1791
2279
  className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70",
@@ -1800,11 +2288,11 @@ function SegmentText({
1800
2288
  renderBody
1801
2289
  }) {
1802
2290
  const text = useSmoothText(content, streaming);
1803
- const body = useMemo3(() => renderBody(text), [renderBody, text]);
2291
+ const body = useMemo6(() => renderBody(text), [renderBody, text]);
1804
2292
  if (!content.trim() && !showCaret) return null;
1805
- return /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
2293
+ return /* @__PURE__ */ jsxs9("div", { className: "text-base leading-[1.75]", children: [
1806
2294
  body,
1807
- showCaret && /* @__PURE__ */ jsx8(StreamingCaret, {})
2295
+ showCaret && /* @__PURE__ */ jsx10(StreamingCaret, {})
1808
2296
  ] });
1809
2297
  }
1810
2298
  var COLLAPSE_TOOL_RUN_AT = 3;
@@ -1827,7 +2315,7 @@ function SegmentedBody({
1827
2315
  const leftoverToolCalls = (msg.toolCalls ?? []).filter(
1828
2316
  (tc) => !segmentToolIds.has(tc.id)
1829
2317
  );
1830
- const renderToolCard = (call) => /* @__PURE__ */ jsx8(
2318
+ const renderToolCard = (call) => /* @__PURE__ */ jsx10(
1831
2319
  ToolCallCard,
1832
2320
  {
1833
2321
  call,
@@ -1850,9 +2338,9 @@ function SegmentedBody({
1850
2338
  else groups.push({ kind: "tools", index: i, calls: [seg.call] });
1851
2339
  }
1852
2340
  }
1853
- return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
2341
+ return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2", children: [
1854
2342
  groups.map(
1855
- (g) => g.kind === "text" ? /* @__PURE__ */ jsx8(
2343
+ (g) => g.kind === "text" ? /* @__PURE__ */ jsx10(
1856
2344
  SegmentText,
1857
2345
  {
1858
2346
  content: g.content,
@@ -1861,24 +2349,24 @@ function SegmentedBody({
1861
2349
  renderBody
1862
2350
  },
1863
2351
  `text-${g.index}`
1864
- ) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */ jsxs7(
2352
+ ) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */ jsxs9(
1865
2353
  "details",
1866
2354
  {
1867
2355
  className: "rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2",
1868
2356
  children: [
1869
- /* @__PURE__ */ jsxs7("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: [
2357
+ /* @__PURE__ */ jsxs9("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: [
1870
2358
  "Worked through ",
1871
2359
  g.calls.length,
1872
2360
  " steps"
1873
2361
  ] }),
1874
- /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-col gap-2", children: g.calls.map(renderToolCard) })
2362
+ /* @__PURE__ */ jsx10("div", { className: "mt-2 flex flex-col gap-2", children: g.calls.map(renderToolCard) })
1875
2363
  ]
1876
2364
  },
1877
2365
  `tools-${g.index}`
1878
- ) : /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-2", children: g.calls.map(renderToolCard) }, `tools-${g.index}`)
2366
+ ) : /* @__PURE__ */ jsx10("div", { className: "flex flex-col gap-2", children: g.calls.map(renderToolCard) }, `tools-${g.index}`)
1879
2367
  ),
1880
2368
  leftoverToolCalls.map(renderToolCard),
1881
- streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx8(StreamingCaret, {})
2369
+ streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx10(StreamingCaret, {})
1882
2370
  ] });
1883
2371
  }
1884
2372
  function AssistantMessageImpl({
@@ -1894,12 +2382,12 @@ function AssistantMessageImpl({
1894
2382
  }) {
1895
2383
  const content = useSmoothText(msg.content, streaming);
1896
2384
  const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
1897
- const body = useMemo3(() => renderBody(content), [renderBody, content]);
2385
+ const body = useMemo6(() => renderBody(content), [renderBody, content]);
1898
2386
  const segments = msg.segments;
1899
2387
  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);
2388
+ const reasoningScrollRef = useRef6(null);
2389
+ const thinkStartRef = useRef6(null);
2390
+ const thinkMsRef = useRef6(null);
1903
2391
  if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
1904
2392
  thinkStartRef.current = performance.now();
1905
2393
  }
@@ -1913,21 +2401,21 @@ function AssistantMessageImpl({
1913
2401
  const thinkingSeconds = useThinkingSeconds(
1914
2402
  streaming && !!reasoning && !hasAnswerText
1915
2403
  );
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) })
2404
+ return /* @__PURE__ */ jsxs9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
2405
+ /* @__PURE__ */ jsxs9("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
2406
+ /* @__PURE__ */ jsx10("span", { className: "font-semibold uppercase", children: agentLabel }),
2407
+ msg.modelUsed && /* @__PURE__ */ jsx10("span", { className: "font-mono normal-case", children: msg.modelUsed }),
2408
+ formatTokensPerSecond(msg) && /* @__PURE__ */ jsx10("span", { children: formatTokensPerSecond(msg) }),
2409
+ formatModelCost(msg, models) && /* @__PURE__ */ jsx10("span", { children: formatModelCost(msg, models) })
1922
2410
  ] }),
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: [
2411
+ 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: [
2412
+ /* @__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
2413
  "Thinking",
1926
2414
  thinkingSeconds >= 3 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
1927
2415
  ] }) : 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 })
2416
+ /* @__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
2417
  ] }),
1930
- segments && segments.length > 0 ? /* @__PURE__ */ jsx8(
2418
+ segments && segments.length > 0 ? /* @__PURE__ */ jsx10(
1931
2419
  SegmentedBody,
1932
2420
  {
1933
2421
  segments,
@@ -1938,12 +2426,12 @@ function AssistantMessageImpl({
1938
2426
  onToolCallClick,
1939
2427
  toolRenderers
1940
2428
  }
1941
- ) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
1942
- /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
2429
+ ) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
2430
+ /* @__PURE__ */ jsxs9("div", { className: "text-base leading-[1.75]", children: [
1943
2431
  body,
1944
- streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx8(StreamingCaret, {})
2432
+ streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx10(StreamingCaret, {})
1945
2433
  ] }),
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(
2434
+ 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
2435
  ToolCallCard,
1948
2436
  {
1949
2437
  call: tc,
@@ -1960,7 +2448,7 @@ function AssistantMessageImpl({
1960
2448
  }
1961
2449
  var AssistantMessage = memo(AssistantMessageImpl);
1962
2450
  function useThinkingSeconds(active) {
1963
- const [seconds, setSeconds] = useState6(0);
2451
+ const [seconds, setSeconds] = useState9(0);
1964
2452
  useEffect5(() => {
1965
2453
  if (!active) return;
1966
2454
  setSeconds(0);
@@ -1971,23 +2459,23 @@ function useThinkingSeconds(active) {
1971
2459
  }
1972
2460
  function ThinkingRow({ agentLabel }) {
1973
2461
  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" }) }),
2462
+ return /* @__PURE__ */ jsxs9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
2463
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
2464
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
2465
+ /* @__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
2466
  "Thinking",
1979
2467
  seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
1980
2468
  ] })
1981
2469
  ] });
1982
2470
  }
1983
2471
  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" })
2472
+ 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: [
2473
+ /* @__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: [
2474
+ /* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "9" }),
2475
+ /* @__PURE__ */ jsx10("path", { d: "M12 8v4m0 4h.01" })
1988
2476
  ] }),
1989
- /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 break-words", children: message }),
1990
- onRetry && /* @__PURE__ */ jsx8(
2477
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1 break-words", children: message }),
2478
+ onRetry && /* @__PURE__ */ jsx10(
1991
2479
  "button",
1992
2480
  {
1993
2481
  type: "button",
@@ -2015,25 +2503,25 @@ function ChatMessages({
2015
2503
  emptyState,
2016
2504
  header
2017
2505
  }) {
2018
- const renderBody = useMemo3(
2019
- () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-wrap", children: content })),
2506
+ const renderBody = useMemo6(
2507
+ () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx10("p", { className: "whitespace-pre-wrap", children: content })),
2020
2508
  [renderMarkdown]
2021
2509
  );
2022
2510
  const lastIsUser = messages[messages.length - 1]?.role === "user";
2023
2511
  if (messages.length === 0 && !loading && !error) {
2024
- const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx8(ChatEmptyState, { ...emptyState });
2025
- return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2512
+ const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx10(ChatEmptyState, { ...emptyState });
2513
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2026
2514
  header,
2027
2515
  empty
2028
2516
  ] });
2029
2517
  }
2030
- return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2518
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2031
2519
  header,
2032
2520
  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(
2521
+ (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: [
2522
+ /* @__PURE__ */ jsx10("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
2523
+ /* @__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 }) })
2524
+ ] }) }, msg.id) : /* @__PURE__ */ jsx10(
2037
2525
  AssistantMessage,
2038
2526
  {
2039
2527
  msg,
@@ -2049,8 +2537,8 @@ function ChatMessages({
2049
2537
  msg.id
2050
2538
  )
2051
2539
  ),
2052
- loading && lastIsUser && /* @__PURE__ */ jsx8(ThinkingRow, { agentLabel }),
2053
- error && !loading && /* @__PURE__ */ jsx8(StreamErrorRow, { message: error, onRetry })
2540
+ loading && lastIsUser && /* @__PURE__ */ jsx10(ThinkingRow, { agentLabel }),
2541
+ error && !loading && /* @__PURE__ */ jsx10(StreamErrorRow, { message: error, onRetry })
2054
2542
  ] });
2055
2543
  }
2056
2544
 
@@ -2063,31 +2551,32 @@ export {
2063
2551
  ModelPicker,
2064
2552
  DEFAULT_EFFORT_LEVELS,
2065
2553
  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
2554
  dispatchChatStreamLine,
2088
2555
  consumeChatStream,
2089
2556
  streamChatTurn,
2090
2557
  ChatComposer,
2558
+ interactionStatusLabels,
2559
+ interactionTerminalNotes,
2560
+ fieldAnswer,
2561
+ buildAnswerData,
2562
+ isLateAnswerableStatus,
2563
+ hasSecretField,
2564
+ lateAnswerMessage,
2565
+ INTERACTION_SUBMIT_TIMEOUT_MS,
2566
+ INTERACTION_SUBMIT_TIMEOUT_MESSAGE,
2567
+ responseErrorMessage,
2568
+ createInteractionAnswerSubmitter,
2569
+ InteractionBadge,
2570
+ InteractionActionButton,
2571
+ QuestionOptionList,
2572
+ InteractionQuestionCard,
2573
+ InteractionPlanCard,
2574
+ upsertChatInteraction,
2575
+ cancelChatInteraction,
2576
+ resolveChatInteraction,
2577
+ terminalizePendingChatInteractions,
2578
+ restoreChatInteractions,
2579
+ useChatInteractions,
2091
2580
  activityTone,
2092
2581
  formatActivityCost,
2093
2582
  formatActivityDuration,
@@ -2106,4 +2595,4 @@ export {
2106
2595
  useThinkingSeconds,
2107
2596
  ChatMessages
2108
2597
  };
2109
- //# sourceMappingURL=chunk-VMY4TKMN.js.map
2598
+ //# sourceMappingURL=chunk-PEPXQTJ3.js.map