@ai-matrx/coding-sessions 0.1.83 → 0.1.86

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.
@@ -4,10 +4,10 @@
4
4
  import {
5
5
  useCallback as useCallback2,
6
6
  useContext as useContext3,
7
- useEffect as useEffect3,
8
- useMemo as useMemo3,
9
- useRef as useRef2,
10
- useState as useState5
7
+ useEffect as useEffect4,
8
+ useMemo as useMemo4,
9
+ useRef as useRef3,
10
+ useState as useState6
11
11
  } from "react";
12
12
  import {
13
13
  ChatComposer,
@@ -16,19 +16,19 @@ import {
16
16
  } from "@ai-matrx/chat/react";
17
17
  import { createExternalThreadSource as createExternalThreadSource2 } from "@ai-matrx/chat/external-store";
18
18
  import {
19
- Button as Button2,
20
- Dialog,
21
- DropdownMenu as DropdownMenu2,
22
- DropdownMenuContent as DropdownMenuContent2,
23
- DropdownMenuTrigger as DropdownMenuTrigger2,
24
- DialogContent,
19
+ Button as Button3,
20
+ Dialog as Dialog2,
21
+ DropdownMenu as DropdownMenu3,
22
+ DropdownMenuContent as DropdownMenuContent3,
23
+ DropdownMenuTrigger as DropdownMenuTrigger3,
24
+ DialogContent as DialogContent2,
25
25
  DialogDescription,
26
- DialogFooter,
27
- DialogHeader,
28
- DialogTitle,
29
- Input,
30
- Textarea,
31
- cn as cn4
26
+ DialogFooter as DialogFooter2,
27
+ DialogHeader as DialogHeader2,
28
+ DialogTitle as DialogTitle2,
29
+ Input as Input2,
30
+ Textarea as Textarea2,
31
+ cn as cn5
32
32
  } from "@ai-matrx/design-system";
33
33
  import { formatCount, formatUsd } from "@ai-matrx/kit/format";
34
34
 
@@ -489,14 +489,20 @@ var SpinnerIcon = ({ size = 16, className }) => /* @__PURE__ */ jsxs(
489
489
  ]
490
490
  }
491
491
  );
492
- function ProviderMark({ provider, size = 18 }) {
492
+ var CLAUDE_MARK = "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z";
493
+ var OPENAI_MARK = "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z";
494
+ function ProviderMark({ provider, size = 16 }) {
493
495
  return /* @__PURE__ */ jsx(
494
- "span",
496
+ "svg",
495
497
  {
496
498
  className: `cs-provider-mark cs-provider-mark--${provider}`,
497
- style: { width: size, height: size, fontSize: Math.round(size * 0.58) },
499
+ width: size,
500
+ height: size,
501
+ viewBox: "0 0 24 24",
502
+ fill: "currentColor",
498
503
  "aria-hidden": "true",
499
- children: provider === "claude" ? "C" : "X"
504
+ "data-provider-mark": provider,
505
+ children: /* @__PURE__ */ jsx("path", { d: provider === "claude" ? CLAUDE_MARK : OPENAI_MARK })
500
506
  }
501
507
  );
502
508
  }
@@ -893,24 +899,392 @@ function ModelPicker(props) {
893
899
  ] });
894
900
  }
895
901
 
896
- // src/react/sidebar.tsx
897
- import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState4 } from "react";
902
+ // src/react/agent-field.tsx
903
+ import { useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState4 } from "react";
904
+ import { deriveRunInputs } from "@ai-matrx/agents";
905
+ import {
906
+ createAgentCatalog
907
+ } from "@ai-matrx/agents/catalog";
908
+ import { AgentCatalogProvider, AgentListDropdown } from "@ai-matrx/agents/catalog/react";
909
+ import { humanizeContextKey } from "@ai-matrx/agents/context";
898
910
  import {
899
911
  Button,
900
- ContextMenu,
901
- ContextMenuContent,
902
- ContextMenuTrigger,
912
+ Dialog,
913
+ DialogContent,
914
+ DialogFooter,
915
+ DialogHeader,
916
+ DialogTitle,
903
917
  DropdownMenu,
904
918
  DropdownMenuContent,
905
919
  DropdownMenuItem as DropdownMenuItem2,
906
920
  DropdownMenuLabel,
907
- DropdownMenuRadioGroup,
908
- DropdownMenuRadioItem,
909
921
  DropdownMenuSeparator as DropdownMenuSeparator2,
910
922
  DropdownMenuTrigger,
923
+ Input,
924
+ Select,
925
+ SelectContent,
926
+ SelectItem,
927
+ SelectTrigger,
928
+ SelectValue,
929
+ Textarea,
930
+ TooltipProvider,
911
931
  cn as cn3
912
932
  } from "@ai-matrx/design-system";
913
933
  import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
934
+ var SIGNED_OUT_AGENTS = "Sign in to AI Matrx to use your agents";
935
+ var LATEST = "latest";
936
+ function bridgedClient(transport) {
937
+ const call = (request) => {
938
+ const run = () => transport.call("agentCatalogRpc", request).then((result) => ({
939
+ data: result.data,
940
+ error: result.error ? {
941
+ message: result.error.message,
942
+ ...result.error.code ? { code: result.error.code } : {},
943
+ details: result.error.details ?? null,
944
+ hint: result.error.hint ?? null
945
+ } : null,
946
+ count: result.count ?? null
947
+ }));
948
+ return {
949
+ then: (onOk, onErr) => run().then(onOk, onErr),
950
+ range: (from, to) => call({ ...request, range: [from, to] }),
951
+ order: (column, options) => call({ ...request, order: { column, ascending: options?.ascending !== false } })
952
+ };
953
+ };
954
+ return {
955
+ rpc: (fn, args, options) => call({ fn, ...args ? { args } : {}, ...options?.count ? { count: options.count } : {} })
956
+ };
957
+ }
958
+ function useAgentAccess(transport, open) {
959
+ const [access, setAccess] = useState4(null);
960
+ useEffect2(() => {
961
+ if (!open) return;
962
+ let alive = true;
963
+ transport.call("agentAccess").then((next) => alive && setAccess(next)).catch(() => alive && setAccess({ signedIn: false, userId: null, organizationId: null, configured: false }));
964
+ return () => {
965
+ alive = false;
966
+ };
967
+ }, [transport, open]);
968
+ return access;
969
+ }
970
+ function useCatalog(transport, userId, onError) {
971
+ const report = useRef(onError);
972
+ report.current = onError;
973
+ return useMemo2(() => {
974
+ if (!userId) return null;
975
+ return createAgentCatalog({
976
+ client: bridgedClient(transport),
977
+ identity: { requireUserId: () => userId, getUserId: () => userId },
978
+ catalogId: `coding-sessions:${userId}`,
979
+ // A failed catalogue read shows at the field, never only in the console.
980
+ errorSink: (event) => {
981
+ console.error(`[coding-sessions] agent catalogue: ${event.code}: ${event.message}`);
982
+ if (event.code === "list_read_failed") report.current("Couldn't load your agents. Reopen to retry.");
983
+ }
984
+ });
985
+ }, [transport, userId]);
986
+ }
987
+ function asRunInputVariables(defs) {
988
+ return defs.flatMap((def) => typeof def.name === "string" ? [def] : []);
989
+ }
990
+ function AgentField(props) {
991
+ const access = useAgentAccess(props.transport, props.open);
992
+ const [details, setDetails] = useState4(null);
993
+ const [problem, setProblem] = useState4(null);
994
+ const catalog = useCatalog(props.transport, access?.signedIn ? access.userId : null, setProblem);
995
+ const agentId = props.value?.agentId ?? null;
996
+ useEffect2(() => {
997
+ setDetails(null);
998
+ setProblem(null);
999
+ if (!agentId) return;
1000
+ let alive = true;
1001
+ props.transport.call("agentDetails", agentId).then((next) => alive && setDetails(next)).catch((error) => alive && setProblem(error instanceof Error ? error.message : String(error)));
1002
+ return () => {
1003
+ alive = false;
1004
+ };
1005
+ }, [agentId, props.transport]);
1006
+ const { onDetails } = props;
1007
+ useEffect2(() => {
1008
+ onDetails?.(details);
1009
+ }, [details, onDetails]);
1010
+ const inputs = useMemo2(() => deriveRunInputs(asRunInputVariables(details?.variables ?? []), humanizeContextKey), [details]);
1011
+ if (access === null) return /* @__PURE__ */ jsx5("div", { className: "cs-skeleton h-9 rounded-lg" });
1012
+ if (!access.signedIn || !catalog) {
1013
+ return /* @__PURE__ */ jsx5("p", { className: "text-[12.5px] text-muted-foreground", children: SIGNED_OUT_AGENTS });
1014
+ }
1015
+ const setVariable = (name, value) => {
1016
+ if (!props.value) return;
1017
+ props.onChange({ ...props.value, variables: { ...props.value.variables ?? {}, [name]: value } });
1018
+ };
1019
+ return /* @__PURE__ */ jsxs5("div", { className: "space-y-3", children: [
1020
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1021
+ /* @__PURE__ */ jsx5(TooltipProvider, { children: /* @__PURE__ */ jsx5(AgentCatalogProvider, { catalog, children: /* @__PURE__ */ jsx5(
1022
+ AgentListDropdown,
1023
+ {
1024
+ consumerId: "coding-sessions-new-session",
1025
+ activeAgentId: agentId,
1026
+ label: details?.name ?? (agentId ? "Loading\u2026" : "None"),
1027
+ onSelect: (id) => props.onChange({ agentId: id, versionId: null, variables: {} })
1028
+ }
1029
+ ) }) }),
1030
+ agentId ? /* @__PURE__ */ jsx5(Button, { type: "button", size: "sm", variant: "ghost", onClick: () => props.onChange(null), children: "Remove" }) : null
1031
+ ] }),
1032
+ problem ? /* @__PURE__ */ jsx5("p", { className: "text-[12px] text-destructive", children: problem }) : null,
1033
+ details && props.value ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1034
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1035
+ /* @__PURE__ */ jsx5("span", { className: "w-[72px] shrink-0 text-[12px] text-muted-foreground", children: "Version" }),
1036
+ /* @__PURE__ */ jsxs5(
1037
+ Select,
1038
+ {
1039
+ value: props.value.versionId ?? LATEST,
1040
+ onValueChange: (next) => props.value && props.onChange({ ...props.value, versionId: next === LATEST ? null : next }),
1041
+ children: [
1042
+ /* @__PURE__ */ jsx5(SelectTrigger, { className: "h-8 w-[200px] text-[12.5px]", "aria-label": "Agent version", children: /* @__PURE__ */ jsx5(SelectValue, {}) }),
1043
+ /* @__PURE__ */ jsxs5(SelectContent, { children: [
1044
+ /* @__PURE__ */ jsx5(SelectItem, { value: LATEST, children: details.latestVersionNumber !== null ? `Latest (v${details.latestVersionNumber})` : "Latest" }),
1045
+ details.versions.map((v) => /* @__PURE__ */ jsxs5(SelectItem, { value: v.id, children: [
1046
+ "v",
1047
+ v.versionNumber
1048
+ ] }, v.id))
1049
+ ] })
1050
+ ]
1051
+ }
1052
+ )
1053
+ ] }),
1054
+ inputs.map((input) => {
1055
+ const raw = props.value?.variables?.[input.name];
1056
+ const value = typeof raw === "string" ? raw : "";
1057
+ const id = `cs-agent-var-${input.name}`;
1058
+ const invalid = props.missing === input.name;
1059
+ return /* @__PURE__ */ jsxs5("div", { className: "space-y-1", children: [
1060
+ /* @__PURE__ */ jsxs5("label", { htmlFor: id, className: "text-[12px] font-medium", children: [
1061
+ input.label,
1062
+ input.required ? /* @__PURE__ */ jsx5("span", { className: "text-muted-foreground", children: " \xB7 required" }) : null
1063
+ ] }),
1064
+ input.options && input.options.length > 0 ? /* @__PURE__ */ jsxs5(Select, { value, onValueChange: (next) => setVariable(input.name, next), children: [
1065
+ /* @__PURE__ */ jsx5(SelectTrigger, { id, className: "h-8 text-[12.5px]", "aria-invalid": invalid || void 0, children: /* @__PURE__ */ jsx5(SelectValue, { placeholder: "Choose\u2026" }) }),
1066
+ /* @__PURE__ */ jsx5(SelectContent, { children: input.options.map((option) => /* @__PURE__ */ jsx5(SelectItem, { value: option, children: option }, option)) })
1067
+ ] }) : input.variable.customComponent?.type === "textarea" ? /* @__PURE__ */ jsx5(
1068
+ Textarea,
1069
+ {
1070
+ id,
1071
+ rows: 2,
1072
+ value,
1073
+ onChange: (e) => setVariable(input.name, e.target.value),
1074
+ placeholder: input.hint ?? "",
1075
+ "aria-invalid": invalid || void 0
1076
+ }
1077
+ ) : /* @__PURE__ */ jsx5(
1078
+ Input,
1079
+ {
1080
+ id,
1081
+ value,
1082
+ onChange: (e) => setVariable(input.name, e.target.value),
1083
+ placeholder: input.hint ?? "",
1084
+ "aria-invalid": invalid || void 0
1085
+ }
1086
+ ),
1087
+ invalid ? /* @__PURE__ */ jsx5("p", { className: "text-[12px] text-destructive", children: "Fill this in to use the agent" }) : null
1088
+ ] }, input.name);
1089
+ })
1090
+ ] }) : null
1091
+ ] });
1092
+ }
1093
+ function missingRequiredVariable(details, selection) {
1094
+ if (!details || !selection) return null;
1095
+ for (const input of deriveRunInputs(asRunInputVariables(details.variables), humanizeContextKey)) {
1096
+ if (!input.required) continue;
1097
+ const value = selection.variables?.[input.name];
1098
+ if (typeof value !== "string" || !value.trim()) return input.name;
1099
+ }
1100
+ return null;
1101
+ }
1102
+ var PART_LABEL = {
1103
+ instructions: "Instructions",
1104
+ skills: "Skills",
1105
+ tools: "Tools"
1106
+ };
1107
+ function agentChipText(agent) {
1108
+ const parts = agent.loaded.map(
1109
+ (part) => part.part === "instructions" ? `${PART_LABEL.instructions} ${part.loaded === 1 ? "\u2713" : "\u2014"}` : `${PART_LABEL[part.part]} ${part.loaded}/${part.total}`
1110
+ );
1111
+ return `${agent.name}${agent.versionNumber !== null ? ` v${agent.versionNumber}` : ""} \xB7 ${parts.join(" \xB7 ")}`;
1112
+ }
1113
+ function AgentMenu(props) {
1114
+ const { agent } = props;
1115
+ const show = useToastShow();
1116
+ const [open, setOpen] = useState4(false);
1117
+ const [choosing, setChoosing] = useState4(false);
1118
+ const [latest, setLatest] = useState4(null);
1119
+ const [access, setAccess] = useState4(null);
1120
+ useEffect2(() => {
1121
+ if (!open) return;
1122
+ let alive = true;
1123
+ void props.transport.call("agentAccess").then((next) => alive && setAccess(next)).catch(() => void 0);
1124
+ if (agent) {
1125
+ props.transport.call("agentDetails", agent.agentId).then((d) => {
1126
+ if (alive && d.latestVersionId && d.latestVersionNumber !== null) setLatest({ id: d.latestVersionId, number: d.latestVersionNumber });
1127
+ }).catch(() => void 0);
1128
+ }
1129
+ return () => {
1130
+ alive = false;
1131
+ };
1132
+ }, [open, agent, props.transport]);
1133
+ const apply = async (selection, done) => {
1134
+ try {
1135
+ await props.transport.call("setAgent", props.sessionId, selection);
1136
+ show(done);
1137
+ props.onChange();
1138
+ } catch (error) {
1139
+ show(`That didn't change: ${error instanceof Error ? error.message : String(error)}`);
1140
+ }
1141
+ };
1142
+ const behind = agent && latest && agent.versionNumber !== null && latest.number > agent.versionNumber ? latest : null;
1143
+ const complete = agent ? agent.loaded.every((part) => part.loaded === part.total) : true;
1144
+ const signedIn = access?.signedIn ?? false;
1145
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
1146
+ /* @__PURE__ */ jsxs5(DropdownMenu, { open, onOpenChange: setOpen, children: [
1147
+ /* @__PURE__ */ jsx5(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
1148
+ "button",
1149
+ {
1150
+ type: "button",
1151
+ className: cn3("cs-agent-chip", agent ? "cs-agent-chip--set" : "cs-agent-chip--none", !complete && "cs-agent-chip--partial"),
1152
+ "data-testid": "cs-agent-chip",
1153
+ "aria-label": agent ? `AI Matrx agent: ${agent.name}` : "Add an AI Matrx agent",
1154
+ children: [
1155
+ agent ? agentChipText(agent) : "No agent",
1156
+ behind ? /* @__PURE__ */ jsx5("span", { className: "cs-agent-chip-dot", "aria-label": "Update available" }) : null,
1157
+ /* @__PURE__ */ jsx5(ChevronDownIcon, { size: 12, className: "ml-1 inline shrink-0" })
1158
+ ]
1159
+ }
1160
+ ) }),
1161
+ /* @__PURE__ */ jsxs5(DropdownMenuContent, { align: "end", className: "w-[320px]", children: [
1162
+ agent ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1163
+ /* @__PURE__ */ jsxs5(DropdownMenuLabel, { className: "truncate", children: [
1164
+ agent.name,
1165
+ agent.versionNumber !== null ? ` \xB7 v${agent.versionNumber}` : ""
1166
+ ] }),
1167
+ /* @__PURE__ */ jsxs5("div", { className: "cs-agent-parts", children: [
1168
+ agent.blockDue ? /* @__PURE__ */ jsx5("p", { className: "text-[12px] text-muted-foreground", children: "Sent with your next message" }) : null,
1169
+ /* @__PURE__ */ jsx5(AgentPartList, { title: "Skills", items: agent.skills ?? [] }),
1170
+ /* @__PURE__ */ jsx5(AgentPartList, { title: "Tools", items: agent.tools ?? [] }),
1171
+ agent.unavailable.length > 0 ? /* @__PURE__ */ jsx5(
1172
+ AgentPartList,
1173
+ {
1174
+ title: "Not loaded",
1175
+ items: agent.unavailable.map((u) => `${u.name} \u2014 ${u.reason}`)
1176
+ }
1177
+ ) : null
1178
+ ] }),
1179
+ /* @__PURE__ */ jsx5(DropdownMenuSeparator2, {})
1180
+ ] }) : null,
1181
+ signedIn ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1182
+ behind && agent ? /* @__PURE__ */ jsxs5(
1183
+ DropdownMenuItem2,
1184
+ {
1185
+ onSelect: () => void apply(
1186
+ { agentId: agent.agentId, versionId: behind.id, variables: agent.variables ?? {} },
1187
+ `The next message uses ${agent.name} v${behind.number}.`
1188
+ ),
1189
+ children: [
1190
+ "Update to v",
1191
+ behind.number
1192
+ ]
1193
+ }
1194
+ ) : null,
1195
+ /* @__PURE__ */ jsx5(DropdownMenuItem2, { onSelect: () => setChoosing(true), children: agent ? "Change agent\u2026" : "Choose agent\u2026" }),
1196
+ agent ? /* @__PURE__ */ jsx5(DropdownMenuItem2, { onSelect: () => void apply(null, "The next message runs without an agent."), children: "Remove agent" }) : null
1197
+ ] }) : access ? /* @__PURE__ */ jsx5("p", { className: "px-2 py-1.5 text-[12px] text-muted-foreground", children: SIGNED_OUT_AGENTS }) : null
1198
+ ] })
1199
+ ] }),
1200
+ /* @__PURE__ */ jsx5(
1201
+ ChooseAgentDialog,
1202
+ {
1203
+ transport: props.transport,
1204
+ open: choosing,
1205
+ onOpenChange: setChoosing,
1206
+ title: agent ? "Change agent" : "Choose an agent",
1207
+ action: "Use this agent",
1208
+ onConfirm: (selection) => apply(selection, "The next message uses the new agent.")
1209
+ }
1210
+ )
1211
+ ] });
1212
+ }
1213
+ function AgentPartList({ title, items }) {
1214
+ return /* @__PURE__ */ jsxs5("div", { children: [
1215
+ /* @__PURE__ */ jsxs5("p", { className: "text-[11.5px] font-medium text-muted-foreground", children: [
1216
+ title,
1217
+ " \xB7 ",
1218
+ items.length
1219
+ ] }),
1220
+ items.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "cs-agent-part-list", children: items.map((item) => /* @__PURE__ */ jsx5("li", { className: "truncate", title: item, children: item }, item)) }) : null
1221
+ ] });
1222
+ }
1223
+ function ChooseAgentDialog(props) {
1224
+ const [value, setValue] = useState4(null);
1225
+ const [details, setDetails] = useState4(null);
1226
+ const [missing, setMissing] = useState4(null);
1227
+ const [busy, setBusy] = useState4(false);
1228
+ useEffect2(() => {
1229
+ if (props.open) {
1230
+ setValue(null);
1231
+ setMissing(null);
1232
+ }
1233
+ }, [props.open]);
1234
+ const confirm = async () => {
1235
+ if (!value) return;
1236
+ const gap = missingRequiredVariable(details, value);
1237
+ setMissing(gap);
1238
+ if (gap) return;
1239
+ setBusy(true);
1240
+ try {
1241
+ await props.onConfirm(value);
1242
+ props.onOpenChange(false);
1243
+ } finally {
1244
+ setBusy(false);
1245
+ }
1246
+ };
1247
+ return /* @__PURE__ */ jsx5(Dialog, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ jsxs5(DialogContent, { className: "max-w-[480px]", children: [
1248
+ /* @__PURE__ */ jsx5(DialogHeader, { children: /* @__PURE__ */ jsx5(DialogTitle, { children: props.title }) }),
1249
+ /* @__PURE__ */ jsx5(
1250
+ AgentField,
1251
+ {
1252
+ transport: props.transport,
1253
+ open: props.open,
1254
+ value,
1255
+ onChange: (next) => {
1256
+ setValue(next);
1257
+ setMissing(null);
1258
+ },
1259
+ missing,
1260
+ onDetails: setDetails
1261
+ }
1262
+ ),
1263
+ /* @__PURE__ */ jsxs5(DialogFooter, { children: [
1264
+ /* @__PURE__ */ jsx5(Button, { type: "button", variant: "ghost", onClick: () => props.onOpenChange(false), children: "Cancel" }),
1265
+ /* @__PURE__ */ jsx5(Button, { type: "button", disabled: !value || busy, onClick: () => void confirm(), children: props.action })
1266
+ ] })
1267
+ ] }) });
1268
+ }
1269
+
1270
+ // src/react/sidebar.tsx
1271
+ import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState5 } from "react";
1272
+ import {
1273
+ Button as Button2,
1274
+ ContextMenu,
1275
+ ContextMenuContent,
1276
+ ContextMenuTrigger,
1277
+ DropdownMenu as DropdownMenu2,
1278
+ DropdownMenuContent as DropdownMenuContent2,
1279
+ DropdownMenuItem as DropdownMenuItem3,
1280
+ DropdownMenuLabel as DropdownMenuLabel2,
1281
+ DropdownMenuRadioGroup,
1282
+ DropdownMenuRadioItem,
1283
+ DropdownMenuSeparator as DropdownMenuSeparator3,
1284
+ DropdownMenuTrigger as DropdownMenuTrigger2,
1285
+ cn as cn4
1286
+ } from "@ai-matrx/design-system";
1287
+ import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
914
1288
  function readLocal(key, allowed, fallback) {
915
1289
  try {
916
1290
  const value = localStorage.getItem(key);
@@ -926,23 +1300,23 @@ function writeLocal(key, value) {
926
1300
  }
927
1301
  }
928
1302
  function SectionLabel({ children, action }) {
929
- return /* @__PURE__ */ jsxs5("div", { className: "flex h-8 items-center justify-between px-3 pt-3", children: [
930
- /* @__PURE__ */ jsx5("span", { className: "text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground", children }),
1303
+ return /* @__PURE__ */ jsxs6("div", { "data-cs-section-label": true, className: "flex h-8 items-center justify-between px-3 pt-3", children: [
1304
+ /* @__PURE__ */ jsx6("span", { className: "text-[12px] font-medium text-muted-foreground", children }),
931
1305
  action
932
1306
  ] });
933
1307
  }
934
1308
  function GroupLabel({ children }) {
935
- return /* @__PURE__ */ jsx5("div", { className: "truncate px-4 pb-0.5 pt-2.5 text-[11px] font-medium text-muted-foreground/80", children });
1309
+ return /* @__PURE__ */ jsx6("div", { className: "truncate px-4 pb-0.5 pt-2.5 text-[12px] font-medium text-muted-foreground", children });
936
1310
  }
937
1311
  function RenameInput(props) {
938
- const [value, setValue] = useState4(props.initial);
939
- const done = useRef(false);
1312
+ const [value, setValue] = useState5(props.initial);
1313
+ const done = useRef2(false);
940
1314
  const finish = (title) => {
941
1315
  if (done.current) return;
942
1316
  done.current = true;
943
1317
  props.onDone(title);
944
1318
  };
945
- return /* @__PURE__ */ jsx5(
1319
+ return /* @__PURE__ */ jsx6(
946
1320
  "input",
947
1321
  {
948
1322
  autoFocus: true,
@@ -959,11 +1333,16 @@ function RenameInput(props) {
959
1333
  }
960
1334
  );
961
1335
  }
1336
+ function entryTarget(entry) {
1337
+ if (entry.kind === "session" && entry.session) return `#s/${entry.session.id}`;
1338
+ if (entry.providerSessionId) return `#d/${entry.provider}/${entry.providerSessionId}`;
1339
+ return "";
1340
+ }
962
1341
  function Row(props) {
963
1342
  const client = useCodingSessionsClient();
964
1343
  const show = useToastShow();
965
- const [renaming, setRenaming] = useState4(false);
966
- const [menuOpen, setMenuOpen] = useState4(false);
1344
+ const [renaming, setRenaming] = useState5(false);
1345
+ const [menuOpen, setMenuOpen] = useState5(false);
967
1346
  const { entry } = props;
968
1347
  const rename = (title) => {
969
1348
  setRenaming(false);
@@ -973,14 +1352,20 @@ function Row(props) {
973
1352
  (error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`)
974
1353
  );
975
1354
  };
976
- return /* @__PURE__ */ jsxs5(ContextMenu, { children: [
977
- /* @__PURE__ */ jsx5(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
1355
+ return /* @__PURE__ */ jsxs6(ContextMenu, { children: [
1356
+ /* @__PURE__ */ jsx6(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
978
1357
  "div",
979
1358
  {
980
- className: cn3("cs-row group", props.active && "cs-row--active", menuOpen && "cs-row--menu"),
1359
+ className: cn4("cs-row group", props.active && "cs-row--active", menuOpen && "cs-row--menu"),
981
1360
  "data-hidden": entry.hidden || void 0,
1361
+ "data-cs-row": entry.key,
1362
+ "data-cs-target": entryTarget(entry),
1363
+ "data-cs-provider": entry.provider,
1364
+ "data-cs-title": entry.title,
1365
+ "data-cs-live": props.live ? "true" : void 0,
1366
+ "data-cs-active": props.active ? "true" : void 0,
982
1367
  children: [
983
- /* @__PURE__ */ jsx5(
1368
+ /* @__PURE__ */ jsx6(
984
1369
  "button",
985
1370
  {
986
1371
  type: "button",
@@ -992,39 +1377,39 @@ function Row(props) {
992
1377
  (${entry.originalTitle})` : entry.title
993
1378
  }
994
1379
  ),
995
- /* @__PURE__ */ jsx5("span", { className: "pointer-events-none mt-0.5 shrink-0", children: props.live ? /* @__PURE__ */ jsx5(SpinnerIcon, { size: 16, className: "text-primary" }) : /* @__PURE__ */ jsx5(ProviderMark, { provider: entry.provider, size: 16 }) }),
996
- /* @__PURE__ */ jsxs5("span", { className: "cs-row__body", children: [
997
- renaming ? /* @__PURE__ */ jsx5("span", { className: "pointer-events-auto relative z-10 block", children: /* @__PURE__ */ jsx5(RenameInput, { initial: entry.title, onDone: rename }) }) : /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-1", children: [
998
- /* @__PURE__ */ jsx5("span", { className: "min-w-0 truncate text-[13px] font-medium leading-5", children: entry.title }),
999
- entry.pinned ? /* @__PURE__ */ jsx5(PinIcon, { size: 11, className: "shrink-0 text-muted-foreground", "aria-label": "Pinned" }) : null
1380
+ /* @__PURE__ */ jsx6("span", { className: "pointer-events-none mt-0.5 shrink-0", children: props.live ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 16, className: "text-primary" }) : /* @__PURE__ */ jsx6(ProviderMark, { provider: entry.provider, size: 16 }) }),
1381
+ /* @__PURE__ */ jsxs6("span", { className: "cs-row__body", children: [
1382
+ renaming ? /* @__PURE__ */ jsx6("span", { className: "pointer-events-auto relative z-10 block", children: /* @__PURE__ */ jsx6(RenameInput, { initial: entry.title, onDone: rename }) }) : /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-1", children: [
1383
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 truncate text-[13px] font-medium leading-5", children: entry.title }),
1384
+ entry.pinned ? /* @__PURE__ */ jsx6(PinIcon, { size: 11, className: "shrink-0 text-muted-foreground", "aria-label": "Pinned" }) : null
1000
1385
  ] }),
1001
- /* @__PURE__ */ jsx5("span", { className: "block truncate text-[11.5px] leading-4 text-muted-foreground", children: props.meta }),
1002
- props.snippet ? /* @__PURE__ */ jsx5("span", { className: "cs-row__snippet", children: props.snippet }) : null
1386
+ /* @__PURE__ */ jsx6("span", { className: "block truncate text-[11.5px] leading-4 text-muted-foreground", children: props.meta }),
1387
+ props.snippet ? /* @__PURE__ */ jsx6("span", { className: "cs-row__snippet", children: props.snippet }) : null
1003
1388
  ] }),
1004
- renaming ? null : /* @__PURE__ */ jsxs5("span", { className: "cs-row__actions", children: [
1389
+ renaming ? null : /* @__PURE__ */ jsxs6("span", { className: "cs-row__actions", children: [
1005
1390
  props.takeover,
1006
- /* @__PURE__ */ jsxs5(DropdownMenu, { open: menuOpen, onOpenChange: setMenuOpen, children: [
1007
- /* @__PURE__ */ jsx5(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx5("button", { type: "button", className: "cs-icon-button", "aria-label": `More for ${entry.title}`, title: "More", children: /* @__PURE__ */ jsx5(MoreIcon, { size: 15 }) }) }),
1008
- /* @__PURE__ */ jsx5(DropdownMenuContent, { align: "start", className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx5(ChatMenuItems, { entry, variant: "dropdown", onRename: () => setRenaming(true) }) })
1391
+ /* @__PURE__ */ jsxs6(DropdownMenu2, { open: menuOpen, onOpenChange: setMenuOpen, children: [
1392
+ /* @__PURE__ */ jsx6(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsx6("button", { type: "button", className: "cs-icon-button", "aria-label": `More for ${entry.title}`, title: "More", children: /* @__PURE__ */ jsx6(MoreIcon, { size: 15 }) }) }),
1393
+ /* @__PURE__ */ jsx6(DropdownMenuContent2, { align: "start", className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx6(ChatMenuItems, { entry, variant: "dropdown", onRename: () => setRenaming(true) }) })
1009
1394
  ] })
1010
1395
  ] })
1011
1396
  ]
1012
1397
  }
1013
1398
  ) }),
1014
- /* @__PURE__ */ jsx5(ContextMenuContent, { className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx5(ChatMenuItems, { entry, variant: "context", onRename: () => setRenaming(true) }) })
1399
+ /* @__PURE__ */ jsx6(ContextMenuContent, { className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx6(ChatMenuItems, { entry, variant: "context", onRename: () => setRenaming(true) }) })
1015
1400
  ] });
1016
1401
  }
1017
1402
  function SidebarSkeleton() {
1018
- return /* @__PURE__ */ jsx5("div", { className: "space-y-1.5 px-3 py-2", "aria-hidden": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx5("div", { className: "cs-skeleton h-9 rounded-lg" }, i)) });
1403
+ return /* @__PURE__ */ jsx6("div", { className: "space-y-1.5 px-3 py-2", "aria-hidden": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx6("div", { className: "cs-skeleton h-9 rounded-lg" }, i)) });
1019
1404
  }
1020
1405
  function Highlight({ text, query }) {
1021
1406
  const q = query.trim().toLowerCase();
1022
1407
  if (!q) return text;
1023
1408
  const at = text.toLowerCase().indexOf(q);
1024
1409
  if (at < 0) return text;
1025
- return /* @__PURE__ */ jsxs5(Fragment3, { children: [
1410
+ return /* @__PURE__ */ jsxs6(Fragment4, { children: [
1026
1411
  text.slice(0, at),
1027
- /* @__PURE__ */ jsx5("mark", { className: "cs-mark", children: text.slice(at, at + q.length) }),
1412
+ /* @__PURE__ */ jsx6("mark", { className: "cs-mark", children: text.slice(at, at + q.length) }),
1028
1413
  text.slice(at + q.length)
1029
1414
  ] });
1030
1415
  }
@@ -1039,8 +1424,8 @@ var EMPTY_SEARCH = {
1039
1424
  };
1040
1425
  function useContentSearch(query) {
1041
1426
  const client = useCodingSessionsClient();
1042
- const [state, setState] = useState4(EMPTY_SEARCH);
1043
- const latest = useRef(query);
1427
+ const [state, setState] = useState5(EMPTY_SEARCH);
1428
+ const latest = useRef2(query);
1044
1429
  latest.current = query;
1045
1430
  const run = useCallback(
1046
1431
  async (q, cursor, append) => {
@@ -1064,7 +1449,7 @@ function useContentSearch(query) {
1064
1449
  },
1065
1450
  [client]
1066
1451
  );
1067
- useEffect2(() => {
1452
+ useEffect3(() => {
1068
1453
  const q = query.trim();
1069
1454
  if (q.length < 2) {
1070
1455
  setState(EMPTY_SEARCH);
@@ -1093,19 +1478,19 @@ function Sidebar(props) {
1093
1478
  const client = useCodingSessionsClient();
1094
1479
  const state = useCodingSessionsState();
1095
1480
  const now = useMinuteClock();
1096
- const [query, setQuery] = useState4("");
1481
+ const [query, setQuery] = useState5("");
1097
1482
  const [search, searchMore] = useContentSearch(query);
1098
- const [groupMode, setGroupMode] = useState4(() => readLocal("coding-sessions.group", ["date", "folder"], "date"));
1099
- const [showHidden, setShowHidden] = useState4(false);
1100
- const [takingOver, setTakingOver] = useState4(null);
1101
- const [takeoverError, setTakeoverError] = useState4(null);
1483
+ const [groupMode, setGroupMode] = useState5(() => readLocal("coding-sessions.group", ["date", "folder"], "date"));
1484
+ const [showHidden, setShowHidden] = useState5(false);
1485
+ const [takingOver, setTakingOver] = useState5(null);
1486
+ const [takeoverError, setTakeoverError] = useState5(null);
1102
1487
  const prefs = state.preferences;
1103
1488
  const sessions = state.sessions.data;
1104
1489
  const isLive = (id) => {
1105
1490
  const run = state.runs[id];
1106
1491
  return run !== void 0 && !isTerminalRunStatus(run.status);
1107
1492
  };
1108
- const { ours, others, hiddenCount } = useMemo2(() => {
1493
+ const { ours, others, hiddenCount } = useMemo3(() => {
1109
1494
  const oursList = sessions.map((s) => sessionEntry(s, prefs));
1110
1495
  const known = new Set(sessions.map((s) => s.providerSessionId).filter(Boolean));
1111
1496
  const othersList = state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => discoveredEntry(d, prefs));
@@ -1145,8 +1530,8 @@ function Sidebar(props) {
1145
1530
  let meta;
1146
1531
  if (live) meta = `${PROVIDER_LABEL[entry.provider]} is working\u2026`;
1147
1532
  else if (d?.activeElsewhere)
1148
- meta = /* @__PURE__ */ jsxs5("span", { className: "cs-live-elsewhere", children: [
1149
- /* @__PURE__ */ jsx5("span", { className: "cs-live-dot", "aria-hidden": "true" }),
1533
+ meta = /* @__PURE__ */ jsxs6("span", { className: "cs-live-elsewhere", children: [
1534
+ /* @__PURE__ */ jsx6("span", { className: "cs-live-dot", "aria-hidden": "true" }),
1150
1535
  "Running in ",
1151
1536
  PROVIDER_LABEL[entry.provider]
1152
1537
  ] });
@@ -1155,8 +1540,8 @@ function Sidebar(props) {
1155
1540
  const where = entry.cwd ? prettyPath2(entry.cwd) : "unknown folder";
1156
1541
  meta = `${status}${entry.kind === "discovered" ? `${PROVIDER_LABEL[entry.provider]} \xB7 ` : ""}${groupMode === "folder" && !extra ? "" : `${where} \xB7 `}${relativeTime(entry.updatedAt, now)}`;
1157
1542
  }
1158
- return /* @__PURE__ */ jsxs5("div", { children: [
1159
- /* @__PURE__ */ jsx5(
1543
+ return /* @__PURE__ */ jsxs6("div", { children: [
1544
+ /* @__PURE__ */ jsx6(
1160
1545
  Row,
1161
1546
  {
1162
1547
  entry,
@@ -1165,7 +1550,7 @@ function Sidebar(props) {
1165
1550
  live,
1166
1551
  meta,
1167
1552
  snippet: extra?.snippet,
1168
- takeover: d?.cwd ? /* @__PURE__ */ jsxs5(
1553
+ takeover: d?.cwd ? /* @__PURE__ */ jsxs6(
1169
1554
  "button",
1170
1555
  {
1171
1556
  type: "button",
@@ -1174,18 +1559,18 @@ function Sidebar(props) {
1174
1559
  title: d.activeElsewhere ? d.activeElsewhere.message : "Continue this chat here",
1175
1560
  disabled: takingOver === d.providerSessionId,
1176
1561
  children: [
1177
- takingOver === d.providerSessionId ? /* @__PURE__ */ jsx5(SpinnerIcon, { size: 11 }) : null,
1562
+ takingOver === d.providerSessionId ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 11 }) : null,
1178
1563
  "Take over"
1179
1564
  ]
1180
1565
  }
1181
1566
  ) : null
1182
1567
  }
1183
1568
  ),
1184
- takeoverError && d && takeoverError.id === d.providerSessionId ? /* @__PURE__ */ jsx5("p", { className: "mx-4 mb-1 text-[11.5px] text-destructive", children: takeoverError.message }) : null
1569
+ takeoverError && d && takeoverError.id === d.providerSessionId ? /* @__PURE__ */ jsx6("p", { className: "mx-4 mb-1 text-[11.5px] text-destructive", children: takeoverError.message }) : null
1185
1570
  ] }, entry.key);
1186
1571
  };
1187
- const renderGroups = (entries) => groupEntries(entries, groupMode, now).map((group) => /* @__PURE__ */ jsxs5("div", { role: "group", "aria-label": group.label, children: [
1188
- /* @__PURE__ */ jsx5(GroupLabel, { children: group.label }),
1572
+ const renderGroups = (entries) => groupEntries(entries, groupMode, now).map((group) => /* @__PURE__ */ jsxs6("div", { role: "group", "aria-label": group.label, children: [
1573
+ /* @__PURE__ */ jsx6(GroupLabel, { children: group.label }),
1189
1574
  group.entries.map((e) => renderEntry(e))
1190
1575
  ] }, group.label));
1191
1576
  const searching = query.trim().length > 0;
@@ -1202,60 +1587,60 @@ function Sidebar(props) {
1202
1587
  props.onFound(hitToDiscovered(hit));
1203
1588
  props.select({ kind: "discovered", provider: hit.provider, id: hit.providerSessionId });
1204
1589
  };
1205
- const searchBody = /* @__PURE__ */ jsxs5(Fragment3, { children: [
1206
- /* @__PURE__ */ jsx5(SectionLabel, { children: "Chats" }),
1207
- titleMatches.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "px-4 py-1 text-[12px] text-muted-foreground", children: "No listed chat has that in its name or folder." }) : titleMatches.map((e) => renderEntry(e, { query })),
1208
- /* @__PURE__ */ jsx5(SectionLabel, { children: "In conversations" }),
1209
- query.trim().length < 2 ? /* @__PURE__ */ jsx5("p", { className: "px-4 py-1 text-[12px] text-muted-foreground", children: "Type at least two letters to search what was said." }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
1590
+ const searchBody = /* @__PURE__ */ jsxs6(Fragment4, { children: [
1591
+ /* @__PURE__ */ jsx6(SectionLabel, { children: "Chats" }),
1592
+ titleMatches.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] text-muted-foreground", children: "No listed chat has that in its name or folder." }) : titleMatches.map((e) => renderEntry(e, { query })),
1593
+ /* @__PURE__ */ jsx6(SectionLabel, { children: "In conversations" }),
1594
+ query.trim().length < 2 ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] text-muted-foreground", children: "Type at least two letters to search what was said." }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
1210
1595
  contentHits.map((hit) => {
1211
1596
  const known = allByKey.get(chatKey(hit.provider, hit.providerSessionId));
1212
1597
  const entry = known ?? discoveredEntry(hitToDiscovered(hit), prefs);
1213
- return /* @__PURE__ */ jsx5("div", { onClickCapture: known ? void 0 : () => props.onFound(hitToDiscovered(hit)), children: renderEntry(entry, {
1598
+ return /* @__PURE__ */ jsx6("div", { onClickCapture: known ? void 0 : () => props.onFound(hitToDiscovered(hit)), children: renderEntry(entry, {
1214
1599
  query,
1215
- snippet: hit.snippet ? /* @__PURE__ */ jsx5(Highlight, { text: hit.snippet, query }) : void 0
1600
+ snippet: hit.snippet ? /* @__PURE__ */ jsx6(Highlight, { text: hit.snippet, query }) : void 0
1216
1601
  }) }, `hit:${entry.key}`);
1217
1602
  }),
1218
- /* @__PURE__ */ jsx5("div", { className: "px-4 py-2 text-[11.5px] leading-4 text-muted-foreground", role: "status", "aria-live": "polite", children: search.error ? /* @__PURE__ */ jsxs5("span", { className: "text-destructive", children: [
1603
+ /* @__PURE__ */ jsx6("div", { className: "px-4 py-2 text-[11.5px] leading-4 text-muted-foreground", role: "status", "aria-live": "polite", children: search.error ? /* @__PURE__ */ jsxs6("span", { className: "text-destructive", children: [
1219
1604
  "Search stopped: ",
1220
1605
  search.error
1221
- ] }) : search.loading ? /* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1.5", children: [
1222
- /* @__PURE__ */ jsx5(SpinnerIcon, { size: 12 }),
1606
+ ] }) : search.loading ? /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-1.5", children: [
1607
+ /* @__PURE__ */ jsx6(SpinnerIcon, { size: 12 }),
1223
1608
  " Searching your chats\u2026"
1224
- ] }) : search.query ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1609
+ ] }) : search.query ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
1225
1610
  contentHits.length === 0 && search.hits.length === 0 ? "Nothing found. " : null,
1226
1611
  search.nextCursor === null ? `Searched all ${search.total.toLocaleString()} chats on this computer.` : `Searched the ${search.scanned.toLocaleString()} most recent of ${search.total.toLocaleString()} chats.`,
1227
- search.nextCursor !== null ? /* @__PURE__ */ jsx5("button", { type: "button", className: "cs-link ml-1", onClick: searchMore, children: "Search older chats" }) : null
1612
+ search.nextCursor !== null ? /* @__PURE__ */ jsx6("button", { type: "button", className: "cs-link ml-1", onClick: searchMore, children: "Search older chats" }) : null
1228
1613
  ] }) : null })
1229
1614
  ] })
1230
1615
  ] });
1231
- const listBody = /* @__PURE__ */ jsxs5(Fragment3, { children: [
1232
- pinned.length > 0 ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1233
- /* @__PURE__ */ jsx5(SectionLabel, { children: "Pinned" }),
1616
+ const listBody = /* @__PURE__ */ jsxs6(Fragment4, { children: [
1617
+ pinned.length > 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
1618
+ /* @__PURE__ */ jsx6(SectionLabel, { children: "Pinned" }),
1234
1619
  pinned.map((e) => renderEntry(e))
1235
1620
  ] }) : null,
1236
- running.length > 0 ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1237
- /* @__PURE__ */ jsx5(SectionLabel, { children: "Running" }),
1621
+ running.length > 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
1622
+ /* @__PURE__ */ jsx6(SectionLabel, { children: "Running" }),
1238
1623
  running.map((e) => renderEntry(e))
1239
1624
  ] }) : null,
1240
- /* @__PURE__ */ jsx5(SectionLabel, { children: "Recent" }),
1241
- state.sessions.loading && state.sessions.loadedAt === null ? /* @__PURE__ */ jsx5(SidebarSkeleton, {}) : state.sessions.error ? /* @__PURE__ */ jsx5("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.sessions.error }) : recent.length === 0 ? running.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "px-4 py-1 text-[12px] leading-5 text-muted-foreground", children: "Sessions you start or take over here will appear here." }) : null : recent.map((e) => renderEntry(e)),
1242
- /* @__PURE__ */ jsx5(
1625
+ /* @__PURE__ */ jsx6(SectionLabel, { children: "Recent" }),
1626
+ state.sessions.loading && state.sessions.loadedAt === null ? /* @__PURE__ */ jsx6(SidebarSkeleton, {}) : state.sessions.error ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.sessions.error }) : recent.length === 0 ? running.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] leading-5 text-muted-foreground", children: "Sessions you start or take over here will appear here." }) : null : recent.map((e) => renderEntry(e)),
1627
+ /* @__PURE__ */ jsx6(
1243
1628
  SectionLabel,
1244
1629
  {
1245
- action: /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-0.5", children: [
1246
- /* @__PURE__ */ jsxs5(DropdownMenu, { children: [
1247
- /* @__PURE__ */ jsx5(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx5("button", { type: "button", className: "cs-icon-button cs-icon-button--text", "aria-label": "How to list your other chats", children: groupMode === "date" ? "By date" : "By folder" }) }),
1248
- /* @__PURE__ */ jsxs5(DropdownMenuContent, { align: "end", className: "w-52", children: [
1249
- /* @__PURE__ */ jsx5(DropdownMenuLabel, { children: "Group your other chats" }),
1250
- /* @__PURE__ */ jsxs5(DropdownMenuRadioGroup, { value: groupMode, onValueChange: (v) => setMode(v), children: [
1251
- /* @__PURE__ */ jsx5(DropdownMenuRadioItem, { value: "date", children: "By date" }),
1252
- /* @__PURE__ */ jsx5(DropdownMenuRadioItem, { value: "folder", children: "By folder" })
1630
+ action: /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-0.5", children: [
1631
+ /* @__PURE__ */ jsxs6(DropdownMenu2, { children: [
1632
+ /* @__PURE__ */ jsx6(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsx6("button", { type: "button", className: "cs-icon-button cs-icon-button--text", "aria-label": "How to list your other chats", children: groupMode === "date" ? "By date" : "By folder" }) }),
1633
+ /* @__PURE__ */ jsxs6(DropdownMenuContent2, { align: "end", className: "w-52", children: [
1634
+ /* @__PURE__ */ jsx6(DropdownMenuLabel2, { children: "Group your other chats" }),
1635
+ /* @__PURE__ */ jsxs6(DropdownMenuRadioGroup, { value: groupMode, onValueChange: (v) => setMode(v), children: [
1636
+ /* @__PURE__ */ jsx6(DropdownMenuRadioItem, { value: "date", children: "By date" }),
1637
+ /* @__PURE__ */ jsx6(DropdownMenuRadioItem, { value: "folder", children: "By folder" })
1253
1638
  ] }),
1254
- /* @__PURE__ */ jsx5(DropdownMenuSeparator2, {}),
1255
- /* @__PURE__ */ jsx5(DropdownMenuItem2, { onSelect: () => setShowHidden((v) => !v), children: showHidden ? "Leave hidden chats out" : `Show hidden chats${hiddenCount ? ` (${hiddenCount})` : ""}` })
1639
+ /* @__PURE__ */ jsx6(DropdownMenuSeparator3, {}),
1640
+ /* @__PURE__ */ jsx6(DropdownMenuItem3, { onSelect: () => setShowHidden((v) => !v), children: showHidden ? "Leave hidden chats out" : `Show hidden chats${hiddenCount ? ` (${hiddenCount})` : ""}` })
1256
1641
  ] })
1257
1642
  ] }),
1258
- /* @__PURE__ */ jsx5(
1643
+ /* @__PURE__ */ jsx6(
1259
1644
  "button",
1260
1645
  {
1261
1646
  type: "button",
@@ -1263,17 +1648,17 @@ function Sidebar(props) {
1263
1648
  onClick: () => void client.refreshDiscovered(),
1264
1649
  "aria-label": "Look again for your other chats",
1265
1650
  title: "Look again",
1266
- children: state.discovered.loading ? /* @__PURE__ */ jsx5(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx5(RefreshIcon, { size: 13 })
1651
+ children: state.discovered.loading ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx6(RefreshIcon, { size: 13 })
1267
1652
  }
1268
1653
  )
1269
1654
  ] }),
1270
1655
  children: "Your other chats"
1271
1656
  }
1272
1657
  ),
1273
- state.discovered.loading && state.discovered.loadedAt === null ? /* @__PURE__ */ jsx5(SidebarSkeleton, {}) : state.discovered.error ? /* @__PURE__ */ jsx5("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.discovered.error }) : otherList.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "px-4 py-1 text-[12px] leading-5 text-muted-foreground", children: others.length > 0 ? "Every chat found here is pinned or hidden." : "No other Claude Code or Codex chats were found on this computer." }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
1658
+ state.discovered.loading && state.discovered.loadedAt === null ? /* @__PURE__ */ jsx6(SidebarSkeleton, {}) : state.discovered.error ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.discovered.error }) : otherList.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] leading-5 text-muted-foreground", children: others.length > 0 ? "Every chat found here is pinned or hidden." : "No other Claude Code or Codex chats were found on this computer." }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
1274
1659
  renderGroups(otherList),
1275
- state.discovered.data.length >= state.discoveredLimit ? /* @__PURE__ */ jsx5("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxs5(
1276
- Button,
1660
+ state.discovered.data.length >= state.discoveredLimit ? /* @__PURE__ */ jsx6("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxs6(
1661
+ Button2,
1277
1662
  {
1278
1663
  variant: "ghost",
1279
1664
  size: "sm",
@@ -1281,32 +1666,32 @@ function Sidebar(props) {
1281
1666
  onClick: () => void client.showMoreDiscovered(),
1282
1667
  disabled: state.discovered.loading,
1283
1668
  children: [
1284
- state.discovered.loading ? /* @__PURE__ */ jsx5(SpinnerIcon, { size: 13 }) : null,
1669
+ state.discovered.loading ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : null,
1285
1670
  "Show older chats"
1286
1671
  ]
1287
1672
  }
1288
1673
  ) }) : null
1289
1674
  ] }),
1290
- showHidden ? null : hiddenCount > 0 ? /* @__PURE__ */ jsxs5("button", { type: "button", className: "cs-link mx-4 mt-3 text-[11.5px]", onClick: () => setShowHidden(true), children: [
1675
+ showHidden ? null : hiddenCount > 0 ? /* @__PURE__ */ jsxs6("button", { type: "button", className: "cs-link mx-4 mt-3 text-[11.5px]", onClick: () => setShowHidden(true), children: [
1291
1676
  hiddenCount,
1292
1677
  " hidden ",
1293
1678
  hiddenCount === 1 ? "chat" : "chats",
1294
1679
  " \u2014 show"
1295
1680
  ] }) : null
1296
1681
  ] });
1297
- return /* @__PURE__ */ jsxs5(
1682
+ return /* @__PURE__ */ jsxs6(
1298
1683
  "aside",
1299
1684
  {
1300
- className: "cs-sidebar flex h-full shrink-0 flex-col border-r border-border bg-muted/30",
1685
+ className: "cs-sidebar flex h-full shrink-0 flex-col border-r border-border bg-sidebar-background",
1301
1686
  style: { width: props.width },
1302
1687
  "aria-label": "Sessions",
1303
1688
  children: [
1304
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-2 px-4 pb-2 pt-3.5", children: [
1305
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2", children: [
1306
- /* @__PURE__ */ jsx5("span", { className: "cs-app-mark", "aria-hidden": "true" }),
1307
- /* @__PURE__ */ jsx5("span", { className: "truncate text-[14px] font-semibold tracking-[-0.01em]", children: "Coding sessions" })
1689
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2 px-4 pb-2 pt-3.5", children: [
1690
+ /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 items-center gap-2", children: [
1691
+ /* @__PURE__ */ jsx6("span", { className: "cs-app-mark", "aria-hidden": "true" }),
1692
+ /* @__PURE__ */ jsx6("span", { className: "truncate text-[14px] font-semibold tracking-[-0.01em]", children: "Coding sessions" })
1308
1693
  ] }),
1309
- /* @__PURE__ */ jsx5(
1694
+ /* @__PURE__ */ jsx6(
1310
1695
  "button",
1311
1696
  {
1312
1697
  type: "button",
@@ -1314,19 +1699,19 @@ function Sidebar(props) {
1314
1699
  onClick: props.onCollapse,
1315
1700
  "aria-label": "Hide the sidebar (\u2318B)",
1316
1701
  title: "Hide sidebar \u2318B",
1317
- children: /* @__PURE__ */ jsx5(SidebarIcon, { size: 15 })
1702
+ children: /* @__PURE__ */ jsx6(SidebarIcon, { size: 15 })
1318
1703
  }
1319
1704
  )
1320
1705
  ] }),
1321
- /* @__PURE__ */ jsxs5("div", { className: "space-y-1.5 px-3 pb-1", children: [
1322
- /* @__PURE__ */ jsxs5(Button, { className: "w-full justify-start gap-2", variant: "outline", size: "sm", onClick: props.onNew, children: [
1323
- /* @__PURE__ */ jsx5(PlusIcon, { size: 15 }),
1706
+ /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5 px-3 pb-1", children: [
1707
+ /* @__PURE__ */ jsxs6(Button2, { className: "w-full justify-start gap-2", variant: "outline", size: "sm", onClick: props.onNew, children: [
1708
+ /* @__PURE__ */ jsx6(PlusIcon, { size: 15 }),
1324
1709
  "New session",
1325
- /* @__PURE__ */ jsx5("kbd", { className: "cs-kbd ml-auto", children: "\u2325\u2318N" })
1710
+ /* @__PURE__ */ jsx6("kbd", { className: "cs-kbd ml-auto", children: "\u2325\u2318N" })
1326
1711
  ] }),
1327
- /* @__PURE__ */ jsxs5("div", { className: "cs-search", children: [
1328
- /* @__PURE__ */ jsx5(SearchIcon, { size: 14, className: "cs-search__icon" }),
1329
- /* @__PURE__ */ jsx5(
1712
+ /* @__PURE__ */ jsxs6("div", { className: "cs-search", children: [
1713
+ /* @__PURE__ */ jsx6(SearchIcon, { size: 14, className: "cs-search__icon" }),
1714
+ /* @__PURE__ */ jsx6(
1330
1715
  "input",
1331
1716
  {
1332
1717
  ref: props.searchRef,
@@ -1352,10 +1737,10 @@ function Sidebar(props) {
1352
1737
  className: "cs-search__input"
1353
1738
  }
1354
1739
  ),
1355
- query ? /* @__PURE__ */ jsx5("button", { type: "button", className: "cs-icon-button cs-search__clear", onClick: () => setQuery(""), "aria-label": "Clear search", children: /* @__PURE__ */ jsx5(CloseIcon, { size: 13 }) }) : /* @__PURE__ */ jsx5("kbd", { className: "cs-search__kbd", children: "\u2318K" })
1740
+ query ? /* @__PURE__ */ jsx6("button", { type: "button", className: "cs-icon-button cs-search__clear", onClick: () => setQuery(""), "aria-label": "Clear search", children: /* @__PURE__ */ jsx6(CloseIcon, { size: 13 }) }) : /* @__PURE__ */ jsx6("kbd", { className: "cs-search__kbd", children: "\u2318K" })
1356
1741
  ] })
1357
1742
  ] }),
1358
- /* @__PURE__ */ jsx5("nav", { className: "min-h-0 flex-1 overflow-y-auto pb-3", children: searching ? searchBody : listBody }),
1743
+ /* @__PURE__ */ jsx6("nav", { className: "min-h-0 flex-1 overflow-y-auto pb-3", children: searching ? searchBody : listBody }),
1359
1744
  props.footer
1360
1745
  ]
1361
1746
  }
@@ -1901,12 +2286,13 @@ var CodingSessionsClient = class {
1901
2286
  start(input) {
1902
2287
  return this.transport.call("start", input);
1903
2288
  }
1904
- takeover(session) {
2289
+ takeover(session, agent) {
1905
2290
  return this.transport.call("takeover", {
1906
2291
  provider: session.provider,
1907
2292
  providerSessionId: session.providerSessionId,
1908
2293
  cwd: session.cwd ?? "",
1909
- title: session.title
2294
+ title: session.title,
2295
+ ...agent ? { agent } : {}
1910
2296
  });
1911
2297
  }
1912
2298
  send(sessionId, prompt) {
@@ -1948,13 +2334,13 @@ function firstInvalidField(errors) {
1948
2334
  }
1949
2335
 
1950
2336
  // src/react/app.tsx
1951
- import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2337
+ import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1952
2338
  function CodingSessionsProvider({ transport, children }) {
1953
- const [client] = useState5(() => new CodingSessionsClient(transport));
1954
- useEffect3(() => {
2339
+ const [client] = useState6(() => new CodingSessionsClient(transport));
2340
+ useEffect4(() => {
1955
2341
  if (transport.status().state === "open") void client.refreshAll();
1956
2342
  }, [client, transport]);
1957
- return /* @__PURE__ */ jsx6(CodingSessionsContext.Provider, { value: client, children });
2343
+ return /* @__PURE__ */ jsx7(CodingSessionsContext.Provider, { value: client, children });
1958
2344
  }
1959
2345
  function readHash() {
1960
2346
  if (typeof location === "undefined") return { kind: "none" };
@@ -1977,8 +2363,8 @@ function readTheme() {
1977
2363
  }
1978
2364
  }
1979
2365
  function useTheme() {
1980
- const [choice, setChoice] = useState5(readTheme);
1981
- useEffect3(() => {
2366
+ const [choice, setChoice] = useState6(readTheme);
2367
+ useEffect4(() => {
1982
2368
  const media = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-color-scheme: dark)") : null;
1983
2369
  const apply = () => {
1984
2370
  const dark = choice === "dark" || choice === "system" && media?.matches === true;
@@ -2008,8 +2394,8 @@ var RUN_LABEL = {
2008
2394
  function RunPill({ run }) {
2009
2395
  if (!run) return null;
2010
2396
  const live = !isTerminalRunStatus(run.status);
2011
- return /* @__PURE__ */ jsxs6("span", { className: cn4("cs-pill", `cs-pill--${run.status}`), children: [
2012
- live ? /* @__PURE__ */ jsx6("span", { className: "cs-pill__dot", "aria-hidden": "true" }) : null,
2397
+ return /* @__PURE__ */ jsxs7("span", { className: cn5("cs-pill", `cs-pill--${run.status}`), children: [
2398
+ live ? /* @__PURE__ */ jsx7("span", { className: "cs-pill__dot", "aria-hidden": "true" }) : null,
2013
2399
  RUN_LABEL[run.status]
2014
2400
  ] });
2015
2401
  }
@@ -2017,17 +2403,17 @@ function ConnectionBanner() {
2017
2403
  const { connection } = useCodingSessionsState();
2018
2404
  if (connection.state === "open") return null;
2019
2405
  const closed = connection.state === "closed";
2020
- return /* @__PURE__ */ jsxs6(
2406
+ return /* @__PURE__ */ jsxs7(
2021
2407
  "div",
2022
2408
  {
2023
2409
  role: "status",
2024
- className: cn4(
2410
+ className: cn5(
2025
2411
  "flex items-center gap-2 border-b px-4 py-2 text-[13px]",
2026
2412
  closed ? "border-destructive/30 bg-destructive/10 text-destructive" : "border-border bg-muted/60 text-muted-foreground"
2027
2413
  ),
2028
2414
  children: [
2029
- closed ? /* @__PURE__ */ jsx6(AlertIcon, { size: 15 }) : /* @__PURE__ */ jsx6(SpinnerIcon, { size: 14 }),
2030
- /* @__PURE__ */ jsx6("span", { children: closed ? connection.reason : "Connecting to the coding sessions host\u2026" })
2415
+ closed ? /* @__PURE__ */ jsx7(AlertIcon, { size: 15 }) : /* @__PURE__ */ jsx7(SpinnerIcon, { size: 14 }),
2416
+ /* @__PURE__ */ jsx7("span", { children: closed ? connection.reason : "Connecting to the coding sessions host\u2026" })
2031
2417
  ]
2032
2418
  }
2033
2419
  );
@@ -2037,22 +2423,22 @@ function ProvidersFooter(props) {
2037
2423
  const client = useCodingSessionsClient();
2038
2424
  const next = { system: "light", light: "dark", dark: "system" };
2039
2425
  const themeLabel = { system: "Match system", light: "Light", dark: "Dark" };
2040
- return /* @__PURE__ */ jsx6("div", { className: "border-t border-border px-3 py-2.5", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1.5", children: [
2041
- /* @__PURE__ */ jsx6("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ jsx6("span", { className: "text-[11.5px] text-muted-foreground", children: "Checking Claude Code and Codex\u2026" }) : state.providers.data.map((p) => /* @__PURE__ */ jsxs6(
2426
+ return /* @__PURE__ */ jsx7("div", { className: "border-t border-border px-3 py-2.5", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5", children: [
2427
+ /* @__PURE__ */ jsx7("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ jsx7("span", { className: "text-[11.5px] text-muted-foreground", children: "Checking Claude Code and Codex\u2026" }) : state.providers.data.map((p) => /* @__PURE__ */ jsxs7(
2042
2428
  "span",
2043
2429
  {
2044
- className: cn4("cs-provider-chip", p.ready ? "" : "cs-provider-chip--problem"),
2430
+ className: cn5("cs-provider-chip", p.ready ? "" : "cs-provider-chip--problem"),
2045
2431
  title: p.problem ? `${p.problem} ${p.fix ?? ""}` : [binaryWords(p) ?? p.label, p.plan, newerWords(p)].filter(Boolean).join(" \xB7 "),
2046
2432
  children: [
2047
- /* @__PURE__ */ jsx6(ProviderMark, { provider: p.provider, size: 13 }),
2433
+ /* @__PURE__ */ jsx7(ProviderMark, { provider: p.provider, size: 13 }),
2048
2434
  p.label,
2049
- p.lastProblem ? /* @__PURE__ */ jsx6("span", { className: "cs-provider-chip__note", children: p.lastProblem.kind === "signed-out" ? "\xB7 sign in again" : `\xB7 limit${formatUntil(p.lastProblem.until) ? ` until ${formatUntil(p.lastProblem.until)}` : ""}` }) : null,
2050
- p.ready ? /* @__PURE__ */ jsx6(CheckIcon, { size: 12 }) : /* @__PURE__ */ jsx6(AlertIcon, { size: 12 })
2435
+ p.lastProblem ? /* @__PURE__ */ jsx7("span", { className: "cs-provider-chip__note", children: p.lastProblem.kind === "signed-out" ? "\xB7 sign in again" : `\xB7 limit${formatUntil(p.lastProblem.until) ? ` until ${formatUntil(p.lastProblem.until)}` : ""}` }) : null,
2436
+ p.ready ? /* @__PURE__ */ jsx7(CheckIcon, { size: 12 }) : /* @__PURE__ */ jsx7(AlertIcon, { size: 12 })
2051
2437
  ]
2052
2438
  },
2053
2439
  p.provider
2054
2440
  )) }),
2055
- /* @__PURE__ */ jsx6(
2441
+ /* @__PURE__ */ jsx7(
2056
2442
  "button",
2057
2443
  {
2058
2444
  type: "button",
@@ -2060,11 +2446,11 @@ function ProvidersFooter(props) {
2060
2446
  onClick: () => void client.refreshProviders(),
2061
2447
  "aria-label": "Check Claude Code and Codex again",
2062
2448
  title: "Check again",
2063
- children: state.providers.loading ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx6(RefreshIcon, { size: 13 })
2449
+ children: state.providers.loading ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx7(RefreshIcon, { size: 13 })
2064
2450
  }
2065
2451
  ),
2066
2452
  props.extra,
2067
- /* @__PURE__ */ jsx6(
2453
+ /* @__PURE__ */ jsx7(
2068
2454
  "button",
2069
2455
  {
2070
2456
  type: "button",
@@ -2072,14 +2458,14 @@ function ProvidersFooter(props) {
2072
2458
  onClick: () => props.setTheme(next[props.theme]),
2073
2459
  "aria-label": `Theme: ${themeLabel[props.theme]}. Switch to ${themeLabel[next[props.theme]]}.`,
2074
2460
  title: `Theme: ${themeLabel[props.theme]}`,
2075
- children: props.theme === "system" ? /* @__PURE__ */ jsx6(MonitorIcon, { size: 14 }) : props.theme === "light" ? /* @__PURE__ */ jsx6(SunIcon, { size: 14 }) : /* @__PURE__ */ jsx6(MoonIcon, { size: 14 })
2461
+ children: props.theme === "system" ? /* @__PURE__ */ jsx7(MonitorIcon, { size: 14 }) : props.theme === "light" ? /* @__PURE__ */ jsx7(SunIcon, { size: 14 }) : /* @__PURE__ */ jsx7(MoonIcon, { size: 14 })
2076
2462
  }
2077
2463
  )
2078
2464
  ] }) });
2079
2465
  }
2080
2466
  function useNotifier() {
2081
2467
  const show = useContext3(ToastContext);
2082
- return useMemo3(
2468
+ return useMemo4(
2083
2469
  () => ({
2084
2470
  notify(event) {
2085
2471
  show(event.message);
@@ -2090,8 +2476,8 @@ function useNotifier() {
2090
2476
  }
2091
2477
  function useLiveElsewhere(provider, providerSessionId, initial = null) {
2092
2478
  const client = useCodingSessionsClient();
2093
- const [state, setState] = useState5(initial);
2094
- useEffect3(() => {
2479
+ const [state, setState] = useState6(initial);
2480
+ useEffect4(() => {
2095
2481
  if (!provider || !providerSessionId) {
2096
2482
  setState(null);
2097
2483
  return;
@@ -2111,8 +2497,8 @@ function useLiveElsewhere(provider, providerSessionId, initial = null) {
2111
2497
  }
2112
2498
  function useSessionUsage(sessionId, lastRunKey) {
2113
2499
  const client = useCodingSessionsClient();
2114
- const [usage, setUsage] = useState5(null);
2115
- useEffect3(() => {
2500
+ const [usage, setUsage] = useState6(null);
2501
+ useEffect4(() => {
2116
2502
  let cancelled = false;
2117
2503
  void client.transport.call("listRuns", sessionId).then((runs) => {
2118
2504
  if (cancelled) return;
@@ -2133,18 +2519,18 @@ function useSessionUsage(sessionId, lastRunKey) {
2133
2519
  return usage;
2134
2520
  }
2135
2521
  function HeaderMenu(props) {
2136
- return /* @__PURE__ */ jsxs6(DropdownMenu2, { children: [
2137
- /* @__PURE__ */ jsx6(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsx6("button", { type: "button", className: "cs-icon-button", "aria-label": "More for this chat", title: "More", children: /* @__PURE__ */ jsx6(MoreIcon, { size: 16 }) }) }),
2138
- /* @__PURE__ */ jsx6(DropdownMenuContent2, { align: "end", className: "w-64", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx6(ChatMenuItems, { entry: props.entry, variant: "dropdown", onRename: props.onRename }) })
2522
+ return /* @__PURE__ */ jsxs7(DropdownMenu3, { children: [
2523
+ /* @__PURE__ */ jsx7(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx7("button", { type: "button", className: "cs-icon-button", "aria-label": "More for this chat", title: "More", children: /* @__PURE__ */ jsx7(MoreIcon, { size: 16 }) }) }),
2524
+ /* @__PURE__ */ jsx7(DropdownMenuContent3, { align: "end", className: "w-64", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx7(ChatMenuItems, { entry: props.entry, variant: "dropdown", onRename: props.onRename }) })
2139
2525
  ] });
2140
2526
  }
2141
2527
  function HeaderTitle(props) {
2142
2528
  const client = useCodingSessionsClient();
2143
2529
  const show = useContext3(ToastContext);
2144
- const [value, setValue] = useState5(props.entry.title);
2145
- useEffect3(() => setValue(props.entry.title), [props.entry.title, props.renaming]);
2146
- const inputRef = useRef2(null);
2147
- useEffect3(() => {
2530
+ const [value, setValue] = useState6(props.entry.title);
2531
+ useEffect4(() => setValue(props.entry.title), [props.entry.title, props.renaming]);
2532
+ const inputRef = useRef3(null);
2533
+ useEffect4(() => {
2148
2534
  if (!props.renaming) return;
2149
2535
  const timer = setTimeout(() => {
2150
2536
  const input = inputRef.current;
@@ -2156,7 +2542,7 @@ function HeaderTitle(props) {
2156
2542
  return () => clearTimeout(timer);
2157
2543
  }, [props.renaming]);
2158
2544
  if (!props.renaming) {
2159
- return /* @__PURE__ */ jsx6(
2545
+ return /* @__PURE__ */ jsx7(
2160
2546
  "h1",
2161
2547
  {
2162
2548
  className: "truncate text-[15px] font-semibold leading-5 tracking-[-0.01em]",
@@ -2173,7 +2559,7 @@ function HeaderTitle(props) {
2173
2559
  const next = title === "" || title === props.entry.originalTitle ? null : title;
2174
2560
  client.setPreference(props.entry.key, { title: next }).catch((error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`));
2175
2561
  };
2176
- return /* @__PURE__ */ jsx6(
2562
+ return /* @__PURE__ */ jsx7(
2177
2563
  "input",
2178
2564
  {
2179
2565
  ref: inputRef,
@@ -2192,9 +2578,9 @@ function HeaderTitle(props) {
2192
2578
  );
2193
2579
  }
2194
2580
  function LongChatNote(props) {
2195
- return /* @__PURE__ */ jsxs6("p", { className: "mx-auto mt-3 flex items-center gap-2 text-[12px] text-muted-foreground", children: [
2581
+ return /* @__PURE__ */ jsxs7("p", { className: "mx-auto mt-3 flex items-center gap-2 text-[12px] text-muted-foreground", children: [
2196
2582
  "This chat is very long \u2014 showing its most recent part.",
2197
- /* @__PURE__ */ jsx6("button", { type: "button", className: "cs-link", onClick: props.onEarlier, disabled: props.loading, children: props.loading ? "Reading\u2026" : "Show earlier" })
2583
+ /* @__PURE__ */ jsx7("button", { type: "button", className: "cs-link", onClick: props.onEarlier, disabled: props.loading, children: props.loading ? "Reading\u2026" : "Show earlier" })
2198
2584
  ] });
2199
2585
  }
2200
2586
  function binaryWords(p) {
@@ -2216,8 +2602,8 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
2216
2602
  const blocked = provider && (!provider.installed || !provider.loggedIn) ? provider : null;
2217
2603
  const limited = !blocked && provider?.lastProblem ? provider : null;
2218
2604
  const modelRefused = run?.status === "failed" && isModelUnavailable(run.error);
2219
- const [stopping, setStopping] = useState5(false);
2220
- const [renaming, setRenaming] = useState5(false);
2605
+ const [stopping, setStopping] = useState6(false);
2606
+ const [renaming, setRenaming] = useState6(false);
2221
2607
  const elsewhere = useLiveElsewhere(
2222
2608
  session.origin === "takeover" && !live ? session.provider : null,
2223
2609
  session.providerSessionId
@@ -2226,7 +2612,7 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
2226
2612
  const messages = transcript.thread.getSnapshot().messages;
2227
2613
  const files = useChangedFiles(messages);
2228
2614
  const usage = useSessionUsage(session.id, `${run?.runId ?? ""}:${run?.status ?? ""}`);
2229
- useEffect3(() => {
2615
+ useEffect4(() => {
2230
2616
  if (!live) setStopping(false);
2231
2617
  }, [live]);
2232
2618
  const stop = async () => {
@@ -2239,16 +2625,16 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
2239
2625
  };
2240
2626
  const usageWords = usage ? `${formatCount(usage.tokens, { style: "compact" })} tokens${usage.cost !== null ? ` \xB7 ${formatUsd(usage.cost)}` : ""}` : null;
2241
2627
  const usageTitle = usage ? `${formatCount(usage.tokens)} tokens over ${usage.runs} ${usage.runs === 1 ? "message" : "messages"} sent from here.` + (usage.cost !== null ? usage.billing === "subscription" ? ` ${formatUsd(usage.cost)} is what this would cost at API prices \u2014 it's covered by your ${provider?.plan ?? ""} plan.`.replace(" ", " ") : ` Billed ${formatUsd(usage.cost)} to your API key.` : "") : "";
2242
- return /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 flex-1", children: [
2243
- /* @__PURE__ */ jsxs6("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
2244
- /* @__PURE__ */ jsxs6("header", { className: "flex items-center gap-3 border-b border-border px-5 py-2.5", children: [
2245
- /* @__PURE__ */ jsx6(ProviderMark, { provider: session.provider, size: 22 }),
2246
- /* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
2247
- /* @__PURE__ */ jsx6(HeaderTitle, { entry, renaming, setRenaming }),
2248
- /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 items-center gap-1 text-[12px] leading-5 text-muted-foreground", children: [
2249
- /* @__PURE__ */ jsx6("span", { className: "shrink-0", children: PROVIDER_LABEL[session.provider] }),
2250
- /* @__PURE__ */ jsx6("span", { "aria-hidden": "true", children: "\xB7" }),
2251
- /* @__PURE__ */ jsx6(
2628
+ return /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1", children: [
2629
+ /* @__PURE__ */ jsxs7("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
2630
+ /* @__PURE__ */ jsxs7("header", { className: "flex flex-wrap items-center gap-2 border-b border-border px-5 pt-2.5 pb-2.5", children: [
2631
+ /* @__PURE__ */ jsx7(ProviderMark, { provider: session.provider, size: 22 }),
2632
+ /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1 overflow-hidden", children: [
2633
+ /* @__PURE__ */ jsx7(HeaderTitle, { entry, renaming, setRenaming }),
2634
+ /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 items-center gap-1 text-[12px] leading-5 text-muted-foreground", children: [
2635
+ /* @__PURE__ */ jsx7("span", { className: "shrink-0", children: PROVIDER_LABEL[session.provider] }),
2636
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xB7" }),
2637
+ /* @__PURE__ */ jsx7(
2252
2638
  ModelPicker,
2253
2639
  {
2254
2640
  status: provider,
@@ -2256,69 +2642,70 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
2256
2642
  onChange: setOptions
2257
2643
  }
2258
2644
  ),
2259
- /* @__PURE__ */ jsx6("span", { "aria-hidden": "true", children: "\xB7" }),
2260
- /* @__PURE__ */ jsx6(FolderIcon, { size: 12, className: "shrink-0" }),
2261
- /* @__PURE__ */ jsx6("span", { className: "min-w-[4rem] truncate", title: session.cwd, children: prettyPath2(session.cwd) }),
2262
- usageWords ? /* @__PURE__ */ jsxs6("span", { className: "shrink-0", title: usageTitle, children: [
2645
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xB7" }),
2646
+ /* @__PURE__ */ jsx7(FolderIcon, { size: 12, className: "shrink-0" }),
2647
+ /* @__PURE__ */ jsx7("span", { className: "min-w-[4rem] truncate", title: session.cwd, children: prettyPath2(session.cwd) }),
2648
+ usageWords ? /* @__PURE__ */ jsxs7("span", { className: "shrink-0", title: usageTitle, children: [
2263
2649
  "\xB7 ",
2264
2650
  usageWords
2265
2651
  ] }) : null
2266
2652
  ] })
2267
2653
  ] }),
2268
- /* @__PURE__ */ jsxs6(
2654
+ /* @__PURE__ */ jsx7(AgentMenu, { transport: client.transport, sessionId: session.id, agent: session.agent ?? null, onChange: () => void 0 }),
2655
+ /* @__PURE__ */ jsxs7(
2269
2656
  "button",
2270
2657
  {
2271
2658
  type: "button",
2272
- className: cn4("cs-chip-button", changesOpen && "cs-chip-button--on"),
2659
+ className: cn5("cs-chip-button", changesOpen && "cs-chip-button--on"),
2273
2660
  onClick: () => setChangesOpen(!changesOpen),
2274
2661
  "aria-pressed": changesOpen,
2275
2662
  title: "Files this chat changed",
2276
2663
  children: [
2277
- /* @__PURE__ */ jsx6(FileIcon, { size: 13 }),
2664
+ /* @__PURE__ */ jsx7(FileIcon, { size: 13 }),
2278
2665
  files.length > 0 ? `${files.length} ${files.length === 1 ? "file" : "files"} changed` : "Changes"
2279
2666
  ]
2280
2667
  }
2281
2668
  ),
2282
- /* @__PURE__ */ jsx6(RunPill, { run }),
2283
- live ? /* @__PURE__ */ jsxs6(Button2, { variant: "outline", size: "sm", onClick: () => void stop(), disabled: stopping, className: "gap-1.5", title: "Stop Esc", children: [
2284
- stopping ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx6(StopIcon, { size: 13 }),
2669
+ /* @__PURE__ */ jsx7(RunPill, { run }),
2670
+ live ? /* @__PURE__ */ jsxs7(Button3, { variant: "outline", size: "sm", onClick: () => void stop(), disabled: stopping, className: "gap-1.5", title: "Stop Esc", children: [
2671
+ stopping ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx7(StopIcon, { size: 13 }),
2285
2672
  stopping ? "Stopping\u2026" : "Stop"
2286
2673
  ] }) : null,
2287
- /* @__PURE__ */ jsx6(HeaderMenu, { entry, onRename: () => setRenaming(true) })
2674
+ /* @__PURE__ */ jsx7(HeaderMenu, { entry, onRename: () => setRenaming(true) })
2288
2675
  ] }),
2289
- /* @__PURE__ */ jsx6("div", { className: "mx-chat flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ jsxs6(ChatProvider, { thread: transcript.thread, ports: { notifier, toolLabel: friendlyToolName }, children: [
2290
- /* @__PURE__ */ jsx6("div", { className: "min-h-0 flex-1 overflow-hidden", children: transcript.state.loading ? /* @__PURE__ */ jsxs6("div", { className: "flex h-full items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
2291
- /* @__PURE__ */ jsx6(SpinnerIcon, { size: 15 }),
2676
+ /* @__PURE__ */ jsx7("div", { className: "mx-chat flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ jsxs7(ChatProvider, { thread: transcript.thread, ports: { notifier, toolLabel: friendlyToolName }, children: [
2677
+ /* @__PURE__ */ jsx7("div", { className: "min-h-0 flex-1 overflow-hidden", children: transcript.state.loading ? /* @__PURE__ */ jsxs7("div", { className: "flex h-full items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
2678
+ /* @__PURE__ */ jsx7(SpinnerIcon, { size: 15 }),
2292
2679
  " Loading the conversation\u2026"
2293
- ] }) : /* @__PURE__ */ jsxs6("div", { className: "flex h-full flex-col", children: [
2294
- transcript.state.unavailable ? /* @__PURE__ */ jsx6("p", { className: "mx-auto mt-4 max-w-[720px] rounded-lg border border-border bg-muted/50 px-4 py-2.5 text-[13px] text-muted-foreground", children: transcript.state.unavailable }) : null,
2295
- transcript.state.truncated ? /* @__PURE__ */ jsx6(
2680
+ ] }) : /* @__PURE__ */ jsxs7("div", { className: "flex h-full flex-col", children: [
2681
+ transcript.state.unavailable ? /* @__PURE__ */ jsx7("p", { className: "mx-auto mt-4 max-w-[720px] rounded-lg border border-border bg-muted/50 px-4 py-2.5 text-[13px] text-muted-foreground", children: transcript.state.unavailable }) : null,
2682
+ transcript.state.truncated ? /* @__PURE__ */ jsx7(
2296
2683
  LongChatNote,
2297
2684
  {
2298
2685
  loading: transcript.state.loadingEarlier === true,
2299
2686
  onEarlier: () => void transcript.loadEarlier()
2300
2687
  }
2301
2688
  ) : null,
2302
- messages.length === 0 && !live ? /* @__PURE__ */ jsx6("div", { className: "flex flex-1 items-center justify-center text-[13px] text-muted-foreground", children: session.origin === "takeover" ? "You've taken over this chat. Send a message to continue it." : "Nothing here yet." }) : /* @__PURE__ */ jsx6(ChatMessageList, { className: "min-h-0 flex-1", label: `Conversation: ${entry.title}` })
2689
+ messages.length === 0 && !live ? /* @__PURE__ */ jsx7("div", { className: "flex flex-1 items-center justify-center text-[13px] text-muted-foreground", children: session.origin === "takeover" ? "You've taken over this chat. Send a message to continue it." : "Nothing here yet." }) : /* @__PURE__ */ jsx7(ChatMessageList, { className: "min-h-0 flex-1", label: `Conversation: ${entry.title}` })
2303
2690
  ] }) }),
2304
- /* @__PURE__ */ jsxs6("div", { className: "mx-auto w-full max-w-[820px] px-4 pb-4", children: [
2305
- limited ? /* @__PURE__ */ jsxs6("div", { className: "mb-2 flex items-start gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]", children: [
2306
- /* @__PURE__ */ jsx6(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2307
- /* @__PURE__ */ jsxs6("span", { children: [
2691
+ /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-[820px] px-4 pb-4", children: [
2692
+ limited ? /* @__PURE__ */ jsxs7("div", { className: "mb-2 flex items-start gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]", children: [
2693
+ /* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2694
+ /* @__PURE__ */ jsxs7("span", { children: [
2308
2695
  limited.problem,
2309
2696
  " ",
2310
2697
  limited.fix
2311
2698
  ] })
2312
2699
  ] }) : null,
2313
- modelRefused && !blocked ? /* @__PURE__ */ jsxs6(
2700
+ modelRefused && !blocked ? /* @__PURE__ */ jsxs7(
2314
2701
  "div",
2315
2702
  {
2316
2703
  className: "mb-2 flex items-center gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]",
2317
2704
  role: "alert",
2318
2705
  children: [
2319
- /* @__PURE__ */ jsx6(AlertIcon, { size: 15, className: "shrink-0 text-warning" }),
2320
- /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate", title: run?.error ?? void 0, children: MODEL_UNAVAILABLE_LABEL }),
2321
- /* @__PURE__ */ jsx6(
2706
+ /* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "shrink-0 text-warning" }),
2707
+ /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", title: run?.error ?? void 0, children: MODEL_UNAVAILABLE_LABEL }),
2708
+ /* @__PURE__ */ jsx7(
2322
2709
  ModelPicker,
2323
2710
  {
2324
2711
  status: provider,
@@ -2329,31 +2716,31 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
2329
2716
  ]
2330
2717
  }
2331
2718
  ) : null,
2332
- blocked ? /* @__PURE__ */ jsxs6("div", { className: "mb-2 flex items-start gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]", children: [
2333
- /* @__PURE__ */ jsx6(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2334
- /* @__PURE__ */ jsxs6("span", { children: [
2719
+ blocked ? /* @__PURE__ */ jsxs7("div", { className: "mb-2 flex items-start gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]", children: [
2720
+ /* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2721
+ /* @__PURE__ */ jsxs7("span", { children: [
2335
2722
  blocked.problem,
2336
2723
  " ",
2337
2724
  blocked.fix
2338
2725
  ] })
2339
2726
  ] }) : null,
2340
- /* @__PURE__ */ jsx6("div", { className: "cs-activity", role: "status", "aria-live": "polite", "data-idle": live ? void 0 : true, children: live ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
2341
- /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }),
2342
- /* @__PURE__ */ jsx6("span", { className: "truncate", children: run?.status === "starting" ? `Starting ${PROVIDER_LABEL[session.provider]}\u2026` : transcript.activity ?? "Thinking\u2026" }),
2343
- /* @__PURE__ */ jsx6("span", { className: "ml-auto shrink-0 text-[11px] opacity-70", children: "Esc to stop" })
2727
+ /* @__PURE__ */ jsx7("div", { className: "cs-activity", role: "status", "aria-live": "polite", "data-idle": live ? void 0 : true, children: live ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
2728
+ /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }),
2729
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: run?.status === "starting" ? `Starting ${PROVIDER_LABEL[session.provider]}\u2026` : transcript.activity ?? "Thinking\u2026" }),
2730
+ /* @__PURE__ */ jsx7("span", { className: "ml-auto shrink-0 text-[11px] opacity-70", children: "Esc to stop" })
2344
2731
  ] }) : null }),
2345
- elsewhere ? /* @__PURE__ */ jsxs6("div", { className: "mb-2 flex items-start gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]", children: [
2346
- /* @__PURE__ */ jsx6(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2347
- /* @__PURE__ */ jsxs6("span", { children: [
2732
+ elsewhere ? /* @__PURE__ */ jsxs7("div", { className: "mb-2 flex items-start gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]", children: [
2733
+ /* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2734
+ /* @__PURE__ */ jsxs7("span", { children: [
2348
2735
  elsewhere.message,
2349
2736
  " A message sent here would put a second agent on the same chat."
2350
2737
  ] })
2351
2738
  ] }) : null,
2352
- session.queued.length > 0 ? /* @__PURE__ */ jsx6("ul", { className: "mb-2 space-y-1.5", "aria-label": "Queued messages", children: session.queued.map((text, index) => /* @__PURE__ */ jsxs6("li", { className: "cs-queued", children: [
2353
- /* @__PURE__ */ jsx6("span", { className: "cs-queued__label", children: "Queued \xB7 sends when this run finishes" }),
2354
- /* @__PURE__ */ jsx6("span", { className: "cs-queued__text", children: text })
2739
+ session.queued.length > 0 ? /* @__PURE__ */ jsx7("ul", { className: "mb-2 space-y-1.5", "aria-label": "Queued messages", children: session.queued.map((text, index) => /* @__PURE__ */ jsxs7("li", { className: "cs-queued", children: [
2740
+ /* @__PURE__ */ jsx7("span", { className: "cs-queued__label", children: "Queued \xB7 sends when this run finishes" }),
2741
+ /* @__PURE__ */ jsx7("span", { className: "cs-queued__text", children: text })
2355
2742
  ] }, `${index}-${text.slice(0, 16)}`)) }) : null,
2356
- /* @__PURE__ */ jsx6(
2743
+ /* @__PURE__ */ jsx7(
2357
2744
  ChatComposer,
2358
2745
  {
2359
2746
  placeholder: `Message ${PROVIDER_LABEL[session.provider]}\u2026`,
@@ -2364,14 +2751,14 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
2364
2751
  ] })
2365
2752
  ] }) })
2366
2753
  ] }),
2367
- changesOpen ? /* @__PURE__ */ jsx6(ChangesPanel, { files, cwd: session.cwd, truncated: transcript.state.truncated, onClose: () => setChangesOpen(false) }) : null
2754
+ changesOpen ? /* @__PURE__ */ jsx7(ChangesPanel, { files, cwd: session.cwd, truncated: transcript.state.truncated, onClose: () => setChangesOpen(false) }) : null
2368
2755
  ] });
2369
2756
  }
2370
2757
  function usePreviewThread(id, onSend) {
2371
- const ref = useRef2({ messages: [], listeners: /* @__PURE__ */ new Set() });
2372
- const send = useRef2(onSend);
2758
+ const ref = useRef3({ messages: [], listeners: /* @__PURE__ */ new Set() });
2759
+ const send = useRef3(onSend);
2373
2760
  send.current = onSend;
2374
- const thread = useMemo3(
2761
+ const thread = useMemo4(
2375
2762
  () => createExternalThreadSource2({
2376
2763
  getSnapshot: () => ({ messages: ref.current.messages, status: "idle", conversationId: id }),
2377
2764
  subscribe: (listener) => {
@@ -2396,13 +2783,13 @@ function DiscoveredView(props) {
2396
2783
  const state = useCodingSessionsState();
2397
2784
  const show = useContext3(ToastContext);
2398
2785
  const now = useMinuteClock();
2399
- const [preview, setPreview] = useState5({ loading: true, messages: [], unavailable: null, truncated: false });
2400
- const [busy, setBusy] = useState5(false);
2401
- const [error, setError] = useState5(null);
2402
- const [confirming, setConfirming] = useState5(false);
2403
- const [renaming, setRenaming] = useState5(false);
2404
- const [maxBytes, setMaxBytes] = useState5(void 0);
2405
- const [readingEarlier, setReadingEarlier] = useState5(false);
2786
+ const [preview, setPreview] = useState6({ loading: true, messages: [], unavailable: null, truncated: false });
2787
+ const [busy, setBusy] = useState6(false);
2788
+ const [error, setError] = useState6(null);
2789
+ const [confirming, setConfirming] = useState6(false);
2790
+ const [renaming, setRenaming] = useState6(false);
2791
+ const [maxBytes, setMaxBytes] = useState6(void 0);
2792
+ const [readingEarlier, setReadingEarlier] = useState6(false);
2406
2793
  const elsewhere = useLiveElsewhere(props.provider, props.id, props.session?.activeElsewhere ?? null);
2407
2794
  const files = useChangedFiles(preview.messages);
2408
2795
  const d = props.session;
@@ -2412,7 +2799,7 @@ function DiscoveredView(props) {
2412
2799
  d?.cwd ? `This chat is read-only until you take it over. Press Take over to continue it here.` : "This chat is read-only here: it doesn't record its folder, so it can't be continued."
2413
2800
  )
2414
2801
  );
2415
- useEffect3(() => {
2802
+ useEffect4(() => {
2416
2803
  let cancelled = false;
2417
2804
  const read = (first) => client.readPreview(props.provider, props.id, maxBytes).then((next) => {
2418
2805
  if (cancelled) return;
@@ -2437,13 +2824,14 @@ function DiscoveredView(props) {
2437
2824
  if (elsewhere) setConfirming(true);
2438
2825
  else void takeover();
2439
2826
  };
2440
- const takeover = async () => {
2827
+ const [choosingAgent, setChoosingAgent] = useState6(false);
2828
+ const takeover = async (agent) => {
2441
2829
  if (!d) return;
2442
2830
  setConfirming(false);
2443
2831
  setBusy(true);
2444
2832
  setError(null);
2445
2833
  try {
2446
- const taken = await client.takeover(d);
2834
+ const taken = await client.takeover(d, agent);
2447
2835
  props.onTakenOver(taken.id);
2448
2836
  } catch (e) {
2449
2837
  setError(e instanceof Error ? e.message : String(e));
@@ -2451,26 +2839,26 @@ function DiscoveredView(props) {
2451
2839
  setBusy(false);
2452
2840
  }
2453
2841
  };
2454
- return /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 flex-1", children: [
2455
- /* @__PURE__ */ jsxs6("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
2456
- /* @__PURE__ */ jsxs6("header", { className: "flex items-center gap-3 border-b border-border px-5 py-3", children: [
2457
- /* @__PURE__ */ jsx6(ProviderMark, { provider: props.provider, size: 22 }),
2458
- /* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
2459
- /* @__PURE__ */ jsx6(HeaderTitle, { entry, renaming, setRenaming }),
2460
- /* @__PURE__ */ jsxs6("p", { className: "flex items-center gap-1.5 truncate text-[12px] leading-4 text-muted-foreground", children: [
2461
- /* @__PURE__ */ jsx6("span", { children: PROVIDER_LABEL[props.provider] }),
2462
- d?.cwd ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
2463
- /* @__PURE__ */ jsx6("span", { "aria-hidden": "true", children: "\xB7" }),
2464
- /* @__PURE__ */ jsx6(FolderIcon, { size: 12 }),
2465
- /* @__PURE__ */ jsx6("span", { className: "truncate", title: d.cwd, children: prettyPath2(d.cwd) })
2842
+ return /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1", children: [
2843
+ /* @__PURE__ */ jsxs7("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
2844
+ /* @__PURE__ */ jsxs7("header", { className: "flex flex-wrap items-center gap-2 border-b border-border px-5 pt-2.5 pb-2.5", children: [
2845
+ /* @__PURE__ */ jsx7(ProviderMark, { provider: props.provider, size: 22 }),
2846
+ /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
2847
+ /* @__PURE__ */ jsx7(HeaderTitle, { entry, renaming, setRenaming }),
2848
+ /* @__PURE__ */ jsxs7("p", { className: "flex items-center gap-1.5 truncate text-[12px] leading-4 text-muted-foreground", children: [
2849
+ /* @__PURE__ */ jsx7("span", { children: PROVIDER_LABEL[props.provider] }),
2850
+ d?.cwd ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
2851
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xB7" }),
2852
+ /* @__PURE__ */ jsx7(FolderIcon, { size: 12 }),
2853
+ /* @__PURE__ */ jsx7("span", { className: "truncate", title: d.cwd, children: prettyPath2(d.cwd) })
2466
2854
  ] }) : null,
2467
- d ? /* @__PURE__ */ jsxs6("span", { children: [
2855
+ d ? /* @__PURE__ */ jsxs7("span", { children: [
2468
2856
  "\xB7 last active ",
2469
2857
  relativeTime(d.updatedAt, now)
2470
2858
  ] }) : null
2471
2859
  ] })
2472
2860
  ] }),
2473
- files.length > 0 ? /* @__PURE__ */ jsxs6(
2861
+ files.length > 0 ? /* @__PURE__ */ jsxs7(
2474
2862
  "button",
2475
2863
  {
2476
2864
  type: "button",
@@ -2479,13 +2867,13 @@ function DiscoveredView(props) {
2479
2867
  "aria-pressed": props.changesOpen,
2480
2868
  title: "Files this chat changed",
2481
2869
  children: [
2482
- /* @__PURE__ */ jsx6(FileIcon, { size: 13 }),
2870
+ /* @__PURE__ */ jsx7(FileIcon, { size: 13 }),
2483
2871
  `${files.length} ${files.length === 1 ? "file" : "files"} changed`
2484
2872
  ]
2485
2873
  }
2486
2874
  ) : null,
2487
- d?.cwd ? /* @__PURE__ */ jsxs6(
2488
- Button2,
2875
+ d?.cwd ? /* @__PURE__ */ jsxs7(
2876
+ Button3,
2489
2877
  {
2490
2878
  size: "sm",
2491
2879
  variant: elsewhere ? "outline" : "default",
@@ -2494,44 +2882,56 @@ function DiscoveredView(props) {
2494
2882
  className: "gap-1.5",
2495
2883
  title: elsewhere ? elsewhere.message : void 0,
2496
2884
  children: [
2497
- busy ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : elsewhere ? /* @__PURE__ */ jsx6(AlertIcon, { size: 14, className: "text-warning" }) : /* @__PURE__ */ jsx6(HandoffIcon, { size: 14 }),
2885
+ busy ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : elsewhere ? /* @__PURE__ */ jsx7(AlertIcon, { size: 14, className: "text-warning" }) : /* @__PURE__ */ jsx7(HandoffIcon, { size: 14 }),
2498
2886
  elsewhere ? "Take over anyway\u2026" : "Take over"
2499
2887
  ]
2500
2888
  }
2501
2889
  ) : null,
2502
- d ? /* @__PURE__ */ jsx6(HeaderMenu, { entry, onRename: () => setRenaming(true) }) : null
2890
+ d?.cwd && !elsewhere ? /* @__PURE__ */ jsx7(Button3, { size: "sm", variant: "outline", onClick: () => setChoosingAgent(true), disabled: busy, children: "Continue with agent\u2026" }) : null,
2891
+ /* @__PURE__ */ jsx7(
2892
+ ChooseAgentDialog,
2893
+ {
2894
+ transport: client.transport,
2895
+ open: choosingAgent,
2896
+ onOpenChange: setChoosingAgent,
2897
+ title: "Continue with an agent",
2898
+ action: "Take over with this agent",
2899
+ onConfirm: (agent) => takeover(agent)
2900
+ }
2901
+ ),
2902
+ d ? /* @__PURE__ */ jsx7(HeaderMenu, { entry, onRename: () => setRenaming(true) }) : null
2503
2903
  ] }),
2504
- elsewhere ? /* @__PURE__ */ jsxs6("div", { role: "status", className: "flex items-start gap-2 border-b border-warning/40 bg-warning/10 px-5 py-2.5 text-[13px]", children: [
2505
- /* @__PURE__ */ jsx6(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2506
- /* @__PURE__ */ jsxs6("span", { children: [
2507
- /* @__PURE__ */ jsx6("span", { className: "font-medium", children: elsewhere.message }),
2904
+ elsewhere ? /* @__PURE__ */ jsxs7("div", { role: "status", className: "flex items-start gap-2 border-b border-warning/40 bg-warning/10 px-5 py-2.5 text-[13px]", children: [
2905
+ /* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
2906
+ /* @__PURE__ */ jsxs7("span", { children: [
2907
+ /* @__PURE__ */ jsx7("span", { className: "font-medium", children: elsewhere.message }),
2508
2908
  " Taking it over now would put two agents on the same chat, and they could overwrite each other's work. Finish or stop it there first if you can. This preview follows it as it runs."
2509
2909
  ] })
2510
2910
  ] }) : null,
2511
- /* @__PURE__ */ jsx6(Dialog, { open: confirming, onOpenChange: setConfirming, children: /* @__PURE__ */ jsxs6(DialogContent, { className: "max-w-[460px]", children: [
2512
- /* @__PURE__ */ jsxs6(DialogHeader, { children: [
2513
- /* @__PURE__ */ jsxs6(DialogTitle, { children: [
2911
+ /* @__PURE__ */ jsx7(Dialog2, { open: confirming, onOpenChange: setConfirming, children: /* @__PURE__ */ jsxs7(DialogContent2, { className: "max-w-[460px]", children: [
2912
+ /* @__PURE__ */ jsxs7(DialogHeader2, { children: [
2913
+ /* @__PURE__ */ jsxs7(DialogTitle2, { children: [
2514
2914
  "This chat is running right now in ",
2515
2915
  PROVIDER_LABEL[props.provider]
2516
2916
  ] }),
2517
- /* @__PURE__ */ jsxs6(DialogDescription, { children: [
2917
+ /* @__PURE__ */ jsxs7(DialogDescription, { children: [
2518
2918
  elsewhere?.message,
2519
2919
  " If you take it over, two agents will work in the same conversation at once and may overwrite each other's changes."
2520
2920
  ] })
2521
2921
  ] }),
2522
- /* @__PURE__ */ jsxs6(DialogFooter, { children: [
2523
- /* @__PURE__ */ jsx6(Button2, { variant: "ghost", onClick: () => setConfirming(false), children: "Cancel" }),
2524
- /* @__PURE__ */ jsx6(Button2, { variant: "destructive", onClick: () => void takeover(), children: "Take over anyway" })
2922
+ /* @__PURE__ */ jsxs7(DialogFooter2, { children: [
2923
+ /* @__PURE__ */ jsx7(Button3, { variant: "ghost", onClick: () => setConfirming(false), children: "Cancel" }),
2924
+ /* @__PURE__ */ jsx7(Button3, { variant: "destructive", onClick: () => void takeover(), children: "Take over anyway" })
2525
2925
  ] })
2526
2926
  ] }) }),
2527
- error ? /* @__PURE__ */ jsx6("p", { className: "border-b border-destructive/30 bg-destructive/10 px-5 py-2 text-[13px] text-destructive", children: error }) : null,
2528
- d && !d.cwd ? /* @__PURE__ */ jsx6("p", { className: "border-b border-border bg-muted/50 px-5 py-2 text-[13px] text-muted-foreground", children: "This chat doesn't record which folder it ran in, so it can't be continued from here." }) : null,
2529
- /* @__PURE__ */ jsxs6("div", { className: "mx-chat flex min-h-0 flex-1 flex-col", children: [
2530
- preview.loading ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
2531
- /* @__PURE__ */ jsx6(SpinnerIcon, { size: 15 }),
2927
+ error ? /* @__PURE__ */ jsx7("p", { className: "border-b border-destructive/30 bg-destructive/10 px-5 py-2 text-[13px] text-destructive", children: error }) : null,
2928
+ d && !d.cwd ? /* @__PURE__ */ jsx7("p", { className: "border-b border-border bg-muted/50 px-5 py-2 text-[13px] text-muted-foreground", children: "This chat doesn't record which folder it ran in, so it can't be continued from here." }) : null,
2929
+ /* @__PURE__ */ jsxs7("div", { className: "mx-chat flex min-h-0 flex-1 flex-col", children: [
2930
+ preview.loading ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
2931
+ /* @__PURE__ */ jsx7(SpinnerIcon, { size: 15 }),
2532
2932
  " Reading this chat\u2026"
2533
- ] }) : preview.unavailable ? /* @__PURE__ */ jsx6("div", { className: "flex flex-1 items-center justify-center px-6 text-center text-[13px] text-muted-foreground", children: preview.unavailable }) : /* @__PURE__ */ jsxs6(ChatProvider, { thread, ports: { notifier, toolLabel: friendlyToolName }, children: [
2534
- preview.truncated ? /* @__PURE__ */ jsx6(
2933
+ ] }) : preview.unavailable ? /* @__PURE__ */ jsx7("div", { className: "flex flex-1 items-center justify-center px-6 text-center text-[13px] text-muted-foreground", children: preview.unavailable }) : /* @__PURE__ */ jsxs7(ChatProvider, { thread, ports: { notifier, toolLabel: friendlyToolName }, children: [
2934
+ preview.truncated ? /* @__PURE__ */ jsx7(
2535
2935
  LongChatNote,
2536
2936
  {
2537
2937
  loading: readingEarlier,
@@ -2541,14 +2941,14 @@ function DiscoveredView(props) {
2541
2941
  }
2542
2942
  }
2543
2943
  ) : null,
2544
- /* @__PURE__ */ jsx6(ChatMessageList, { className: "min-h-0 flex-1", label: "Chat preview" })
2944
+ /* @__PURE__ */ jsx7(ChatMessageList, { className: "min-h-0 flex-1", label: "Chat preview" })
2545
2945
  ] }),
2546
- d?.cwd ? /* @__PURE__ */ jsxs6("div", { className: "border-t border-border bg-muted/30 px-5 py-3 text-center text-[13px] text-muted-foreground", children: [
2946
+ d?.cwd ? /* @__PURE__ */ jsxs7("div", { className: "border-t border-border bg-muted/30 px-5 py-3 text-center text-[13px] text-muted-foreground", children: [
2547
2947
  "This chat was started in ",
2548
2948
  PROVIDER_LABEL[props.provider],
2549
2949
  ".",
2550
2950
  " ",
2551
- /* @__PURE__ */ jsx6("button", { type: "button", className: "font-medium text-foreground underline-offset-4 hover:underline", onClick: requestTakeover, children: "Take it over" }),
2951
+ /* @__PURE__ */ jsx7("button", { type: "button", className: "font-medium text-foreground underline-offset-4 hover:underline", onClick: requestTakeover, children: "Take it over" }),
2552
2952
  " ",
2553
2953
  "to continue it here \u2014 it stays in your ",
2554
2954
  PROVIDER_LABEL[props.provider],
@@ -2556,70 +2956,73 @@ function DiscoveredView(props) {
2556
2956
  ] }) : null
2557
2957
  ] })
2558
2958
  ] }),
2559
- props.changesOpen && files.length > 0 ? /* @__PURE__ */ jsx6(ChangesPanel, { files, cwd: d?.cwd ?? null, truncated: preview.truncated, onClose: () => props.setChangesOpen(false) }) : null
2959
+ props.changesOpen && files.length > 0 ? /* @__PURE__ */ jsx7(ChangesPanel, { files, cwd: d?.cwd ?? null, truncated: preview.truncated, onClose: () => props.setChangesOpen(false) }) : null
2560
2960
  ] });
2561
2961
  }
2562
2962
  function ProviderCard(props) {
2563
2963
  const ready = props.status.ready;
2564
- return /* @__PURE__ */ jsxs6(
2964
+ return /* @__PURE__ */ jsxs7(
2565
2965
  "button",
2566
2966
  {
2567
2967
  type: "button",
2568
2968
  onClick: props.onSelect,
2569
2969
  "aria-pressed": props.selected,
2570
- className: cn4(
2970
+ className: cn5(
2571
2971
  "flex flex-1 flex-col gap-1.5 rounded-xl border px-3.5 py-3 text-left transition-colors",
2572
2972
  props.selected ? "border-primary bg-primary/5 ring-1 ring-primary" : "border-border hover:bg-accent/50"
2573
2973
  ),
2574
2974
  children: [
2575
- /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-2", children: [
2576
- /* @__PURE__ */ jsx6(ProviderMark, { provider: props.status.provider, size: 18 }),
2577
- /* @__PURE__ */ jsx6("span", { className: "text-[13.5px] font-semibold", children: props.status.label })
2975
+ /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2", children: [
2976
+ /* @__PURE__ */ jsx7(ProviderMark, { provider: props.status.provider, size: 18 }),
2977
+ /* @__PURE__ */ jsx7("span", { className: "text-[13.5px] font-semibold", children: props.status.label })
2578
2978
  ] }),
2579
- ready ? /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-1 text-[12px] text-success", children: [
2580
- /* @__PURE__ */ jsx6(CheckIcon, { size: 13 }),
2979
+ ready ? /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-1 text-[12px] text-success", children: [
2980
+ /* @__PURE__ */ jsx7(CheckIcon, { size: 13 }),
2581
2981
  props.status.billing === "subscription" ? `Signed in${props.status.plan ? ` \xB7 ${props.status.plan} plan` : ""}` : "Signed in with an API key (billed per use)"
2582
- ] }) : /* @__PURE__ */ jsxs6("span", { className: "flex items-start gap-1 text-[12px] leading-4 text-warning", children: [
2583
- /* @__PURE__ */ jsx6(AlertIcon, { size: 13, className: "mt-px shrink-0" }),
2982
+ ] }) : /* @__PURE__ */ jsxs7("span", { className: "flex items-start gap-1 text-[12px] leading-4 text-warning", children: [
2983
+ /* @__PURE__ */ jsx7(AlertIcon, { size: 13, className: "mt-px shrink-0" }),
2584
2984
  props.status.problem
2585
2985
  ] }),
2586
- props.status.quota.filter((w) => w.usedPercent !== null).length > 0 ? /* @__PURE__ */ jsx6("span", { className: "text-[11.5px] leading-4 text-muted-foreground", children: props.status.quota.filter((w) => w.usedPercent !== null).map((w) => `${w.label}: ${w.usedPercent}% used`).join(" \xB7 ") }) : null
2986
+ props.status.quota.filter((w) => w.usedPercent !== null).length > 0 ? /* @__PURE__ */ jsx7("span", { className: "text-[11.5px] leading-4 text-muted-foreground", children: props.status.quota.filter((w) => w.usedPercent !== null).map((w) => `${w.label}: ${w.usedPercent}% used`).join(" \xB7 ") }) : null
2587
2987
  ]
2588
2988
  }
2589
2989
  );
2590
2990
  }
2591
2991
  function FieldError({ id, children }) {
2592
- return /* @__PURE__ */ jsxs6("p", { id, role: "alert", className: "flex items-start gap-1.5 text-[12.5px] leading-5 text-destructive", children: [
2593
- /* @__PURE__ */ jsx6(AlertIcon, { size: 14, className: "mt-0.5 shrink-0" }),
2594
- /* @__PURE__ */ jsx6("span", { children })
2992
+ return /* @__PURE__ */ jsxs7("p", { id, role: "alert", className: "flex items-start gap-1.5 text-[12.5px] leading-5 text-destructive", children: [
2993
+ /* @__PURE__ */ jsx7(AlertIcon, { size: 14, className: "mt-0.5 shrink-0" }),
2994
+ /* @__PURE__ */ jsx7("span", { children })
2595
2995
  ] });
2596
2996
  }
2597
2997
  function NewSessionDialog(props) {
2598
2998
  const client = useCodingSessionsClient();
2599
2999
  const state = useCodingSessionsState();
2600
3000
  const now = useMinuteClock();
2601
- const [provider, setProvider] = useState5("claude");
2602
- const [folder, setFolder] = useState5("");
2603
- const [choice, setChoice] = useState5({ model: null, effort: null });
2604
- const [prompt, setPrompt] = useState5("");
2605
- const [errors, setErrors] = useState5({});
2606
- const [problem, setProblem] = useState5(null);
2607
- const [starting, setStarting] = useState5(false);
2608
- const [creating, setCreating] = useState5(false);
2609
- const promptRef = useRef2(null);
2610
- const folderRef = useRef2(null);
2611
- const agentRef = useRef2(null);
2612
- useEffect3(() => {
3001
+ const [provider, setProvider] = useState6("claude");
3002
+ const [folder, setFolder] = useState6("");
3003
+ const [choice, setChoice] = useState6({ model: null, effort: null });
3004
+ const [prompt, setPrompt] = useState6("");
3005
+ const [errors, setErrors] = useState6({});
3006
+ const [problem, setProblem] = useState6(null);
3007
+ const [starting, setStarting] = useState6(false);
3008
+ const [creating, setCreating] = useState6(false);
3009
+ const [agent, setAgent] = useState6(null);
3010
+ const [agentDetails, setAgentDetails] = useState6(null);
3011
+ const [agentMissing, setAgentMissing] = useState6(null);
3012
+ const promptRef = useRef3(null);
3013
+ const folderRef = useRef3(null);
3014
+ const agentRef = useRef3(null);
3015
+ useEffect4(() => {
2613
3016
  if (!props.open) return;
2614
3017
  setProblem(null);
2615
3018
  setErrors({});
2616
3019
  void client.refreshProviders();
2617
3020
  void client.refreshFolders();
2618
3021
  }, [props.open, client]);
2619
- useEffect3(() => {
3022
+ useEffect4(() => {
2620
3023
  if (!folder && state.folders.data[0]?.exists) setFolder(state.folders.data[0].path);
2621
3024
  }, [state.folders.data, folder]);
2622
- useEffect3(() => {
3025
+ useEffect4(() => {
2623
3026
  const ready = state.providers.data.filter((p) => p.ready);
2624
3027
  const current = state.providers.data.find((p) => p.provider === provider);
2625
3028
  if (current && !current.ready && ready[0]) setProvider(ready[0].provider);
@@ -2645,9 +3048,22 @@ function NewSessionDialog(props) {
2645
3048
  focusField(first);
2646
3049
  return;
2647
3050
  }
3051
+ const missing = missingRequiredVariable(agentDetails, agent);
3052
+ setAgentMissing(missing);
3053
+ if (missing) {
3054
+ document.getElementById(`cs-agent-var-${missing}`)?.focus();
3055
+ return;
3056
+ }
2648
3057
  setStarting(true);
2649
3058
  try {
2650
- const result = await client.start({ provider, cwd: folder.trim(), prompt, model: choice.model, effort: choice.effort });
3059
+ const result = await client.start({
3060
+ provider,
3061
+ cwd: folder.trim(),
3062
+ prompt,
3063
+ model: choice.model,
3064
+ effort: choice.effort,
3065
+ ...agent ? { agent } : {}
3066
+ });
2651
3067
  setPrompt("");
2652
3068
  props.onStarted(result.session.id);
2653
3069
  } catch (error) {
@@ -2683,16 +3099,16 @@ function NewSessionDialog(props) {
2683
3099
  if (field === "folder") delete next.createFolder;
2684
3100
  return next;
2685
3101
  });
2686
- return /* @__PURE__ */ jsx6(Dialog, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ jsxs6(DialogContent, { className: "max-w-[560px]", children: [
2687
- /* @__PURE__ */ jsxs6(DialogHeader, { children: [
2688
- /* @__PURE__ */ jsx6(DialogTitle, { children: "New coding session" }),
2689
- /* @__PURE__ */ jsxs6(DialogDescription, { children: [
3102
+ return /* @__PURE__ */ jsx7(Dialog2, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ jsxs7(DialogContent2, { className: "max-w-[560px]", children: [
3103
+ /* @__PURE__ */ jsxs7(DialogHeader2, { children: [
3104
+ /* @__PURE__ */ jsx7(DialogTitle2, { children: "New coding session" }),
3105
+ /* @__PURE__ */ jsxs7(DialogDescription, { children: [
2690
3106
  "Runs on your own ",
2691
3107
  provider === "claude" ? "Claude" : "ChatGPT",
2692
3108
  " sign-in, in a folder on this computer."
2693
3109
  ] })
2694
3110
  ] }),
2695
- /* @__PURE__ */ jsxs6(
3111
+ /* @__PURE__ */ jsxs7(
2696
3112
  "form",
2697
3113
  {
2698
3114
  noValidate: true,
@@ -2702,13 +3118,13 @@ function NewSessionDialog(props) {
2702
3118
  },
2703
3119
  className: "flex min-h-0 flex-col",
2704
3120
  children: [
2705
- /* @__PURE__ */ jsxs6("div", { className: "cs-dialog-body space-y-5 py-1 pr-1", children: [
2706
- /* @__PURE__ */ jsxs6("fieldset", { className: "space-y-2", ref: agentRef, children: [
2707
- /* @__PURE__ */ jsx6("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Agent" }),
2708
- state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ jsxs6("div", { className: "flex gap-2", children: [
2709
- /* @__PURE__ */ jsx6("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" }),
2710
- /* @__PURE__ */ jsx6("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" })
2711
- ] }) : state.providers.error ? /* @__PURE__ */ jsx6("p", { className: "text-[12.5px] text-destructive", children: state.providers.error }) : /* @__PURE__ */ jsx6("div", { className: "flex gap-2", children: state.providers.data.map((p) => /* @__PURE__ */ jsx6(
3121
+ /* @__PURE__ */ jsxs7("div", { className: "cs-dialog-body space-y-5 py-1 pr-1", children: [
3122
+ /* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", ref: agentRef, children: [
3123
+ /* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Agent" }),
3124
+ state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ jsxs7("div", { className: "flex gap-2", children: [
3125
+ /* @__PURE__ */ jsx7("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" }),
3126
+ /* @__PURE__ */ jsx7("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" })
3127
+ ] }) : state.providers.error ? /* @__PURE__ */ jsx7("p", { className: "text-[12.5px] text-destructive", children: state.providers.error }) : /* @__PURE__ */ jsx7("div", { className: "flex gap-2", children: state.providers.data.map((p) => /* @__PURE__ */ jsx7(
2712
3128
  ProviderCard,
2713
3129
  {
2714
3130
  status: p,
@@ -2721,14 +3137,31 @@ function NewSessionDialog(props) {
2721
3137
  },
2722
3138
  p.provider
2723
3139
  )) }),
2724
- errors.agent ? /* @__PURE__ */ jsx6(FieldError, { id: "cs-err-agent", children: errors.agent }) : selected && !selected.ready && selected.fix ? /* @__PURE__ */ jsxs6("p", { className: "text-[12px] leading-4 text-muted-foreground", children: [
3140
+ errors.agent ? /* @__PURE__ */ jsx7(FieldError, { id: "cs-err-agent", children: errors.agent }) : selected && !selected.ready && selected.fix ? /* @__PURE__ */ jsxs7("p", { className: "text-[12px] leading-4 text-muted-foreground", children: [
2725
3141
  selected.fix,
2726
3142
  selected.installed && selected.loggedIn ? " You can still try \u2014 the run will say if it's still blocked." : ""
2727
3143
  ] }) : null
2728
3144
  ] }),
2729
- /* @__PURE__ */ jsxs6("fieldset", { className: "space-y-2", children: [
2730
- /* @__PURE__ */ jsx6("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Folder" }),
2731
- state.folders.data.length > 0 ? /* @__PURE__ */ jsx6("div", { className: "max-h-[132px] space-y-0.5 overflow-y-auto rounded-lg border border-border p-1", children: state.folders.data.map((f) => /* @__PURE__ */ jsxs6(
3145
+ /* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
3146
+ /* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "AI Matrx agent" }),
3147
+ /* @__PURE__ */ jsx7(
3148
+ AgentField,
3149
+ {
3150
+ transport: client.transport,
3151
+ open: props.open,
3152
+ value: agent,
3153
+ onChange: (next) => {
3154
+ setAgent(next);
3155
+ setAgentMissing(null);
3156
+ },
3157
+ missing: agentMissing,
3158
+ onDetails: setAgentDetails
3159
+ }
3160
+ )
3161
+ ] }),
3162
+ /* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
3163
+ /* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Folder" }),
3164
+ state.folders.data.length > 0 ? /* @__PURE__ */ jsx7("div", { className: "max-h-[132px] space-y-0.5 overflow-y-auto rounded-lg border border-border p-1", children: state.folders.data.map((f) => /* @__PURE__ */ jsxs7(
2732
3165
  "button",
2733
3166
  {
2734
3167
  type: "button",
@@ -2738,21 +3171,21 @@ function NewSessionDialog(props) {
2738
3171
  },
2739
3172
  disabled: !f.exists,
2740
3173
  title: f.exists ? f.path : `${f.path} no longer exists`,
2741
- className: cn4(
3174
+ className: cn5(
2742
3175
  "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[12.5px]",
2743
3176
  folder === f.path ? "bg-accent text-accent-foreground" : "hover:bg-accent/50",
2744
3177
  !f.exists && "opacity-50"
2745
3178
  ),
2746
3179
  children: [
2747
- /* @__PURE__ */ jsx6(FolderIcon, { size: 14, className: "shrink-0 text-muted-foreground" }),
2748
- /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate", children: prettyPath2(f.path) }),
2749
- /* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: f.exists ? relativeTime(f.lastUsedAt, now) : "missing" })
3180
+ /* @__PURE__ */ jsx7(FolderIcon, { size: 14, className: "shrink-0 text-muted-foreground" }),
3181
+ /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", children: prettyPath2(f.path) }),
3182
+ /* @__PURE__ */ jsx7("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: f.exists ? relativeTime(f.lastUsedAt, now) : "missing" })
2750
3183
  ]
2751
3184
  },
2752
3185
  f.path
2753
- )) }) : state.folders.loading ? /* @__PURE__ */ jsx6("div", { className: "cs-skeleton h-10 rounded-lg" }) : null,
2754
- /* @__PURE__ */ jsx6(
2755
- Input,
3186
+ )) }) : state.folders.loading ? /* @__PURE__ */ jsx7("div", { className: "cs-skeleton h-10 rounded-lg" }) : null,
3187
+ /* @__PURE__ */ jsx7(
3188
+ Input2,
2756
3189
  {
2757
3190
  ref: folderRef,
2758
3191
  value: folder,
@@ -2767,18 +3200,18 @@ function NewSessionDialog(props) {
2767
3200
  spellCheck: false
2768
3201
  }
2769
3202
  ),
2770
- errors.folder ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1", children: [
2771
- /* @__PURE__ */ jsx6(FieldError, { id: "cs-err-folder", children: errors.folder }),
2772
- errors.createFolder ? /* @__PURE__ */ jsxs6(Button2, { type: "button", size: "sm", variant: "outline", onClick: () => void createFolder(), disabled: creating, className: "gap-1.5", children: [
2773
- creating ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx6(FolderIcon, { size: 13 }),
3203
+ errors.folder ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1", children: [
3204
+ /* @__PURE__ */ jsx7(FieldError, { id: "cs-err-folder", children: errors.folder }),
3205
+ errors.createFolder ? /* @__PURE__ */ jsxs7(Button3, { type: "button", size: "sm", variant: "outline", onClick: () => void createFolder(), disabled: creating, className: "gap-1.5", children: [
3206
+ creating ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx7(FolderIcon, { size: 13 }),
2774
3207
  "Create this folder"
2775
3208
  ] }) : null
2776
3209
  ] }) : null
2777
3210
  ] }),
2778
- /* @__PURE__ */ jsxs6("fieldset", { className: "space-y-2", children: [
2779
- /* @__PURE__ */ jsx6("legend", { className: "mb-2 text-[12.5px] font-medium", children: "What should it do?" }),
2780
- /* @__PURE__ */ jsx6(
2781
- Textarea,
3211
+ /* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
3212
+ /* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "What should it do?" }),
3213
+ /* @__PURE__ */ jsx7(
3214
+ Textarea2,
2782
3215
  {
2783
3216
  ref: promptRef,
2784
3217
  value: prompt,
@@ -2799,25 +3232,25 @@ function NewSessionDialog(props) {
2799
3232
  "aria-describedby": errors.prompt ? "cs-err-prompt" : void 0
2800
3233
  }
2801
3234
  ),
2802
- errors.prompt ? /* @__PURE__ */ jsx6(FieldError, { id: "cs-err-prompt", children: errors.prompt }) : null
3235
+ errors.prompt ? /* @__PURE__ */ jsx7(FieldError, { id: "cs-err-prompt", children: errors.prompt }) : null
2803
3236
  ] }),
2804
- /* @__PURE__ */ jsxs6("fieldset", { className: "space-y-2", children: [
2805
- /* @__PURE__ */ jsx6("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Model and thinking effort" }),
2806
- /* @__PURE__ */ jsx6(ModelPicker, { status: selected, value: choice, onChange: setChoice, appearance: "field" }),
2807
- /* @__PURE__ */ jsxs6("p", { className: "text-[11.5px] leading-4 text-muted-foreground", children: [
3237
+ /* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
3238
+ /* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Model and thinking effort" }),
3239
+ /* @__PURE__ */ jsx7(ModelPicker, { status: selected, value: choice, onChange: setChoice, appearance: "field" }),
3240
+ /* @__PURE__ */ jsxs7("p", { className: "text-[11.5px] leading-4 text-muted-foreground", children: [
2808
3241
  "Default is ",
2809
3242
  defaultModelWords(selected),
2810
3243
  ". You can change it later from the chat's header."
2811
3244
  ] })
2812
3245
  ] }),
2813
- problem ? /* @__PURE__ */ jsx6(FieldError, { id: "cs-err-start", children: problem }) : null
3246
+ problem ? /* @__PURE__ */ jsx7(FieldError, { id: "cs-err-start", children: problem }) : null
2814
3247
  ] }),
2815
- /* @__PURE__ */ jsxs6(DialogFooter, { className: "pt-4", children: [
2816
- /* @__PURE__ */ jsx6(Button2, { type: "button", variant: "ghost", onClick: () => props.onOpenChange(false), children: "Cancel" }),
2817
- /* @__PURE__ */ jsxs6(Button2, { type: "submit", disabled: starting, className: "gap-1.5", children: [
2818
- starting ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 14 }) : null,
3248
+ /* @__PURE__ */ jsxs7(DialogFooter2, { className: "pt-4", children: [
3249
+ /* @__PURE__ */ jsx7(Button3, { type: "button", variant: "ghost", onClick: () => props.onOpenChange(false), children: "Cancel" }),
3250
+ /* @__PURE__ */ jsxs7(Button3, { type: "submit", disabled: starting, className: "gap-1.5", children: [
3251
+ starting ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 14 }) : null,
2819
3252
  starting ? "Starting\u2026" : "Start session",
2820
- !starting ? /* @__PURE__ */ jsx6("kbd", { className: "cs-kbd", children: "\u2318\u21B5" }) : null
3253
+ !starting ? /* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2318\u21B5" }) : null
2821
3254
  ] })
2822
3255
  ] })
2823
3256
  ]
@@ -2827,34 +3260,34 @@ function NewSessionDialog(props) {
2827
3260
  }
2828
3261
  function Home({ onNew }) {
2829
3262
  const state = useCodingSessionsState();
2830
- return /* @__PURE__ */ jsx6("section", { className: "flex flex-1 items-center justify-center px-6", children: /* @__PURE__ */ jsxs6("div", { className: "w-full max-w-[460px] text-center", children: [
2831
- /* @__PURE__ */ jsx6("span", { className: "mx-auto mb-4 flex h-11 w-11 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx6(ChatBubbleIcon, { size: 22 }) }),
2832
- /* @__PURE__ */ jsx6("h1", { className: "text-[19px] font-semibold tracking-[-0.015em]", children: "Drive Claude Code and Codex from here" }),
2833
- /* @__PURE__ */ jsx6("p", { className: "mx-auto mt-2 max-w-[400px] text-[13.5px] leading-6 text-muted-foreground", children: "Start a session in any folder, or pick up a chat you began somewhere else. Everything runs on your own subscriptions \u2014 no API keys." }),
2834
- /* @__PURE__ */ jsxs6(Button2, { className: "mt-5 gap-1.5", onClick: onNew, children: [
2835
- /* @__PURE__ */ jsx6(PlusIcon, { size: 15 }),
3263
+ return /* @__PURE__ */ jsx7("section", { className: "flex flex-1 items-center justify-center px-6", children: /* @__PURE__ */ jsxs7("div", { className: "w-full max-w-[460px] text-center", children: [
3264
+ /* @__PURE__ */ jsx7("span", { className: "mx-auto mb-4 flex h-11 w-11 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx7(ChatBubbleIcon, { size: 22 }) }),
3265
+ /* @__PURE__ */ jsx7("h1", { className: "text-[15px] font-semibold leading-5 tracking-[-0.01em]", children: "Drive Claude Code and Codex from here" }),
3266
+ /* @__PURE__ */ jsx7("p", { className: "mx-auto mt-2 max-w-[400px] text-[13.5px] leading-6 text-muted-foreground", children: "Start a session in any folder, or pick up a chat you began somewhere else. Everything runs on your own subscriptions \u2014 no API keys." }),
3267
+ /* @__PURE__ */ jsxs7(Button3, { className: "mt-5 gap-1.5", onClick: onNew, children: [
3268
+ /* @__PURE__ */ jsx7(PlusIcon, { size: 15 }),
2836
3269
  "New session"
2837
3270
  ] }),
2838
- /* @__PURE__ */ jsxs6("p", { className: "mt-3 text-[12px] text-muted-foreground", children: [
2839
- /* @__PURE__ */ jsx6("kbd", { className: "cs-kbd", children: "\u2325\u2318N" }),
3271
+ /* @__PURE__ */ jsxs7("p", { className: "mt-3 text-[12px] text-muted-foreground", children: [
3272
+ /* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2325\u2318N" }),
2840
3273
  " new session \xB7 ",
2841
- /* @__PURE__ */ jsx6("kbd", { className: "cs-kbd", children: "\u2318K" }),
3274
+ /* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2318K" }),
2842
3275
  " search your chats \xB7",
2843
3276
  " ",
2844
- /* @__PURE__ */ jsx6("kbd", { className: "cs-kbd", children: "\u2318/" }),
3277
+ /* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2318/" }),
2845
3278
  " all shortcuts"
2846
3279
  ] }),
2847
- /* @__PURE__ */ jsx6("div", { className: "mt-6 space-y-1.5 text-left", children: state.providers.data.map((p) => /* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-2.5 rounded-lg border border-border px-3 py-2.5", children: [
2848
- /* @__PURE__ */ jsx6(ProviderMark, { provider: p.provider, size: 18 }),
2849
- /* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1 text-[12.5px] leading-5", children: [
2850
- /* @__PURE__ */ jsx6("span", { className: "font-medium", children: p.label }),
2851
- p.ready ? /* @__PURE__ */ jsxs6("span", { className: "text-muted-foreground", children: [
3280
+ /* @__PURE__ */ jsx7("div", { className: "mt-6 grid grid-cols-[repeat(auto-fit,minmax(220px,1fr))] gap-1.5 text-left", children: state.providers.data.map((p) => /* @__PURE__ */ jsxs7("div", { className: "flex min-w-[220px] items-start gap-2.5 rounded-lg border border-border px-3 py-2.5", children: [
3281
+ /* @__PURE__ */ jsx7(ProviderMark, { provider: p.provider, size: 16 }),
3282
+ /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1 text-[12.5px] leading-5", children: [
3283
+ /* @__PURE__ */ jsx7("span", { className: "font-medium", children: p.label }),
3284
+ p.ready ? /* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
2852
3285
  " ",
2853
3286
  "\u2014 ready",
2854
3287
  p.plan ? ` on your ${p.plan} plan` : "",
2855
3288
  p.billing === "api" ? " (API key, billed per use)" : ""
2856
3289
  ] }) : null,
2857
- p.installed && p.version ? /* @__PURE__ */ jsxs6(
3290
+ p.installed && p.version ? /* @__PURE__ */ jsxs7(
2858
3291
  "span",
2859
3292
  {
2860
3293
  className: "block text-[11.5px] text-muted-foreground",
@@ -2865,20 +3298,20 @@ function Home({ onNew }) {
2865
3298
  ]
2866
3299
  }
2867
3300
  ) : null,
2868
- p.ready ? null : /* @__PURE__ */ jsxs6("span", { className: "block text-muted-foreground", children: [
3301
+ p.ready ? null : /* @__PURE__ */ jsxs7("span", { className: "block text-muted-foreground", children: [
2869
3302
  p.problem,
2870
3303
  " ",
2871
3304
  p.fix
2872
3305
  ] })
2873
3306
  ] }),
2874
- p.ready ? /* @__PURE__ */ jsx6(CheckIcon, { size: 15, className: "mt-0.5 text-success" }) : /* @__PURE__ */ jsx6(AlertIcon, { size: 15, className: "mt-0.5 text-warning" })
3307
+ p.ready ? /* @__PURE__ */ jsx7(CheckIcon, { size: 15, className: "mt-0.5 text-success" }) : /* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 text-warning" })
2875
3308
  ] }, p.provider)) })
2876
3309
  ] }) });
2877
3310
  }
2878
3311
  function useToast() {
2879
- const [text, setText] = useState5(null);
2880
- const timer = useRef2(null);
2881
- useEffect3(() => () => {
3312
+ const [text, setText] = useState6(null);
3313
+ const timer = useRef3(null);
3314
+ useEffect4(() => () => {
2882
3315
  if (timer.current) clearTimeout(timer.current);
2883
3316
  }, []);
2884
3317
  const show = useCallback2((next) => {
@@ -2890,7 +3323,7 @@ function useToast() {
2890
3323
  }
2891
3324
  function Toast({ text }) {
2892
3325
  if (!text) return null;
2893
- return /* @__PURE__ */ jsx6("div", { role: "status", className: "cs-toast", children: text });
3326
+ return /* @__PURE__ */ jsx7("div", { role: "status", className: "cs-toast", children: text });
2894
3327
  }
2895
3328
  var SIDEBAR_DEFAULT = 300;
2896
3329
  var SIDEBAR_MIN = 220;
@@ -2899,7 +3332,7 @@ function clampWidth(n) {
2899
3332
  return Math.round(Math.min(SIDEBAR_MAX, Math.max(SIDEBAR_MIN, n)));
2900
3333
  }
2901
3334
  function useSidebarLayout() {
2902
- const [width, setWidthState] = useState5(() => {
3335
+ const [width, setWidthState] = useState6(() => {
2903
3336
  try {
2904
3337
  const n = Number(localStorage.getItem("coding-sessions.sidebar-width"));
2905
3338
  return Number.isFinite(n) && n > 0 ? clampWidth(n) : SIDEBAR_DEFAULT;
@@ -2907,7 +3340,7 @@ function useSidebarLayout() {
2907
3340
  return SIDEBAR_DEFAULT;
2908
3341
  }
2909
3342
  });
2910
- const [collapsed, setCollapsedState] = useState5(() => {
3343
+ const [collapsed, setCollapsedState] = useState6(() => {
2911
3344
  try {
2912
3345
  return localStorage.getItem("coding-sessions.sidebar-collapsed") === "1";
2913
3346
  } catch {
@@ -2932,8 +3365,8 @@ function useSidebarLayout() {
2932
3365
  return { width, setWidth, collapsed, setCollapsed };
2933
3366
  }
2934
3367
  function Resizer(props) {
2935
- const [dragging, setDragging] = useState5(false);
2936
- return /* @__PURE__ */ jsx6("div", { className: cn4("cs-resizer", dragging && "cs-resizer--dragging"), children: /* @__PURE__ */ jsx6(
3368
+ const [dragging, setDragging] = useState6(false);
3369
+ return /* @__PURE__ */ jsx7("div", { className: cn5("cs-resizer", dragging && "cs-resizer--dragging"), children: /* @__PURE__ */ jsx7(
2937
3370
  "button",
2938
3371
  {
2939
3372
  type: "button",
@@ -2981,24 +3414,24 @@ var SHORTCUTS = [
2981
3414
  { keys: "\u2318/", what: "These shortcuts" }
2982
3415
  ];
2983
3416
  function ShortcutsDialog(props) {
2984
- return /* @__PURE__ */ jsx6(Dialog, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ jsxs6(DialogContent, { className: "max-w-[420px]", children: [
2985
- /* @__PURE__ */ jsxs6(DialogHeader, { children: [
2986
- /* @__PURE__ */ jsx6(DialogTitle, { children: "Keyboard shortcuts" }),
2987
- /* @__PURE__ */ jsx6(DialogDescription, { children: "Ctrl works in place of \u2318 on Windows and Linux." })
3417
+ return /* @__PURE__ */ jsx7(Dialog2, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ jsxs7(DialogContent2, { className: "max-w-[420px]", children: [
3418
+ /* @__PURE__ */ jsxs7(DialogHeader2, { children: [
3419
+ /* @__PURE__ */ jsx7(DialogTitle2, { children: "Keyboard shortcuts" }),
3420
+ /* @__PURE__ */ jsx7(DialogDescription, { children: "Ctrl works in place of \u2318 on Windows and Linux." })
2988
3421
  ] }),
2989
- /* @__PURE__ */ jsx6("dl", { className: "divide-y divide-border text-[13px]", children: SHORTCUTS.map((s) => /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-4 py-2", children: [
2990
- /* @__PURE__ */ jsx6("dt", { className: "text-muted-foreground", children: s.what }),
2991
- /* @__PURE__ */ jsx6("dd", { children: /* @__PURE__ */ jsx6("kbd", { className: "rounded border border-border px-1.5 py-0.5 font-sans text-[12px]", children: s.keys }) })
3422
+ /* @__PURE__ */ jsx7("dl", { className: "divide-y divide-border text-[13px]", children: SHORTCUTS.map((s) => /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-4 py-2", children: [
3423
+ /* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground", children: s.what }),
3424
+ /* @__PURE__ */ jsx7("dd", { children: /* @__PURE__ */ jsx7("kbd", { className: "rounded border border-border px-1.5 py-0.5 font-sans text-[12px]", children: s.keys }) })
2992
3425
  ] }, s.keys)) })
2993
3426
  ] }) });
2994
3427
  }
2995
3428
  var BASE_TITLE = "Coding sessions";
2996
3429
  function useRunFinishedNotices(openSessionId, show) {
2997
3430
  const client = useCodingSessionsClient();
2998
- const unseen = useRef2(0);
2999
- const openRef = useRef2(openSessionId);
3431
+ const unseen = useRef3(0);
3432
+ const openRef = useRef3(openSessionId);
3000
3433
  openRef.current = openSessionId;
3001
- useEffect3(() => {
3434
+ useEffect4(() => {
3002
3435
  const reset = () => {
3003
3436
  if (document.visibilityState === "visible") {
3004
3437
  unseen.current = 0;
@@ -3033,9 +3466,9 @@ function useRunFinishedNotices(openSessionId, show) {
3033
3466
  }
3034
3467
  function NotifyToggle() {
3035
3468
  const supported = typeof Notification !== "undefined";
3036
- const [permission, setPermission] = useState5(supported ? Notification.permission : "denied");
3469
+ const [permission, setPermission] = useState6(supported ? Notification.permission : "denied");
3037
3470
  if (!supported || permission === "granted") return null;
3038
- return /* @__PURE__ */ jsx6(
3471
+ return /* @__PURE__ */ jsx7(
3039
3472
  "button",
3040
3473
  {
3041
3474
  type: "button",
@@ -3044,7 +3477,7 @@ function NotifyToggle() {
3044
3477
  "aria-label": permission === "denied" ? "Notifications are blocked for this page in your browser's site settings" : "Notify me when a run finishes",
3045
3478
  title: permission === "denied" ? "Notifications are blocked in your browser's site settings" : "Notify me when a run finishes",
3046
3479
  disabled: permission === "denied",
3047
- children: /* @__PURE__ */ jsx6(BellIcon, { size: 14 })
3480
+ children: /* @__PURE__ */ jsx7(BellIcon, { size: 14 })
3048
3481
  }
3049
3482
  );
3050
3483
  }
@@ -3056,20 +3489,20 @@ function isTyping(target) {
3056
3489
  function Shell() {
3057
3490
  const client = useCodingSessionsClient();
3058
3491
  const state = useCodingSessionsState();
3059
- const [selection, setSelection] = useState5(readHash);
3060
- const [newOpen, setNewOpen] = useState5(false);
3061
- const [shortcutsOpen, setShortcutsOpen] = useState5(false);
3062
- const [changesOpen, setChangesOpen] = useState5(false);
3063
- const [found, setFound] = useState5({});
3492
+ const [selection, setSelection] = useState6(readHash);
3493
+ const [newOpen, setNewOpen] = useState6(false);
3494
+ const [shortcutsOpen, setShortcutsOpen] = useState6(false);
3495
+ const [changesOpen, setChangesOpen] = useState6(false);
3496
+ const [found, setFound] = useState6({});
3064
3497
  const [theme, setTheme] = useTheme();
3065
3498
  const [toast, showToast] = useToast();
3066
3499
  const layout = useSidebarLayout();
3067
- const searchRef = useRef2(null);
3500
+ const searchRef = useRef3(null);
3068
3501
  const select = useCallback2((next) => {
3069
3502
  setSelection(next);
3070
3503
  writeHash(next);
3071
3504
  }, []);
3072
- useEffect3(() => {
3505
+ useEffect4(() => {
3073
3506
  const onHash = () => setSelection(readHash());
3074
3507
  window.addEventListener("hashchange", onHash);
3075
3508
  return () => window.removeEventListener("hashchange", onHash);
@@ -3079,14 +3512,14 @@ function Shell() {
3079
3512
  const discovered = selection.kind === "discovered" ? state.discovered.data.find((d) => d.providerSessionId === selection.id) ?? found[`${selection.provider}:${selection.id}`] ?? null : null;
3080
3513
  const run = session ? state.runs[session.id] : void 0;
3081
3514
  const live = run !== void 0 && !isTerminalRunStatus(run.status);
3082
- const order = useMemo3(() => {
3515
+ const order = useMemo4(() => {
3083
3516
  const known = new Set(state.sessions.data.map((s) => s.providerSessionId).filter(Boolean));
3084
3517
  return [
3085
3518
  ...state.sessions.data.map((s) => ({ kind: "session", id: s.id })),
3086
3519
  ...state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => ({ kind: "discovered", provider: d.provider, id: d.providerSessionId }))
3087
3520
  ];
3088
3521
  }, [state.sessions.data, state.discovered.data]);
3089
- useEffect3(() => {
3522
+ useEffect4(() => {
3090
3523
  const onKey = (e) => {
3091
3524
  const mod = e.metaKey || e.ctrlKey;
3092
3525
  const key = e.key.toLowerCase();
@@ -3142,12 +3575,12 @@ function Shell() {
3142
3575
  }, [client, layout, live, run, order, selection, select, showToast]);
3143
3576
  let main;
3144
3577
  if (selection.kind === "session") {
3145
- main = session ? /* @__PURE__ */ jsx6(SessionView, { session, changesOpen, setChangesOpen }, session.id) : state.sessions.loadedAt === null ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
3146
- /* @__PURE__ */ jsx6(SpinnerIcon, { size: 15 }),
3578
+ main = session ? /* @__PURE__ */ jsx7(SessionView, { session, changesOpen, setChangesOpen }, session.id) : state.sessions.loadedAt === null ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
3579
+ /* @__PURE__ */ jsx7(SpinnerIcon, { size: 15 }),
3147
3580
  " Loading\u2026"
3148
- ] }) : /* @__PURE__ */ jsx6("div", { className: "flex flex-1 items-center justify-center text-[13px] text-muted-foreground", children: "That session is not in the list anymore." });
3581
+ ] }) : /* @__PURE__ */ jsx7("div", { className: "flex flex-1 items-center justify-center text-[13px] text-muted-foreground", children: "That session is not in the list anymore." });
3149
3582
  } else if (selection.kind === "discovered") {
3150
- main = /* @__PURE__ */ jsx6(
3583
+ main = /* @__PURE__ */ jsx7(
3151
3584
  DiscoveredView,
3152
3585
  {
3153
3586
  session: discovered,
@@ -3160,13 +3593,13 @@ function Shell() {
3160
3593
  `${selection.provider}:${selection.id}`
3161
3594
  );
3162
3595
  } else {
3163
- main = /* @__PURE__ */ jsx6(Home, { onNew: () => setNewOpen(true) });
3596
+ main = /* @__PURE__ */ jsx7(Home, { onNew: () => setNewOpen(true) });
3164
3597
  }
3165
- return /* @__PURE__ */ jsx6(ToastContext.Provider, { value: showToast, children: /* @__PURE__ */ jsxs6("div", { className: "cs-app flex h-full flex-col bg-background text-foreground", children: [
3166
- /* @__PURE__ */ jsx6(ConnectionBanner, {}),
3167
- /* @__PURE__ */ jsxs6("div", { className: "flex min-h-0 flex-1", children: [
3168
- layout.collapsed ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center gap-1 border-r border-border bg-muted/30 px-1.5 py-3", children: [
3169
- /* @__PURE__ */ jsx6(
3598
+ return /* @__PURE__ */ jsx7(ToastContext.Provider, { value: showToast, children: /* @__PURE__ */ jsxs7("div", { className: "cs-app flex h-full flex-col bg-background text-foreground", children: [
3599
+ /* @__PURE__ */ jsx7(ConnectionBanner, {}),
3600
+ /* @__PURE__ */ jsxs7("div", { className: "flex min-h-0 flex-1", children: [
3601
+ layout.collapsed ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-center gap-1 border-r border-border bg-muted/30 px-1.5 py-3", children: [
3602
+ /* @__PURE__ */ jsx7(
3170
3603
  "button",
3171
3604
  {
3172
3605
  type: "button",
@@ -3174,10 +3607,10 @@ function Shell() {
3174
3607
  onClick: () => layout.setCollapsed(false),
3175
3608
  "aria-label": "Show the sidebar (\u2318B)",
3176
3609
  title: "Show sidebar \u2318B",
3177
- children: /* @__PURE__ */ jsx6(SidebarIcon, { size: 15 })
3610
+ children: /* @__PURE__ */ jsx7(SidebarIcon, { size: 15 })
3178
3611
  }
3179
3612
  ),
3180
- /* @__PURE__ */ jsx6(
3613
+ /* @__PURE__ */ jsx7(
3181
3614
  "button",
3182
3615
  {
3183
3616
  type: "button",
@@ -3185,11 +3618,11 @@ function Shell() {
3185
3618
  onClick: () => setNewOpen(true),
3186
3619
  "aria-label": "New session",
3187
3620
  title: "New session \u2325\u2318N",
3188
- children: /* @__PURE__ */ jsx6(PlusIcon, { size: 15 })
3621
+ children: /* @__PURE__ */ jsx7(PlusIcon, { size: 15 })
3189
3622
  }
3190
3623
  )
3191
- ] }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
3192
- /* @__PURE__ */ jsx6(
3624
+ ] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
3625
+ /* @__PURE__ */ jsx7(
3193
3626
  Sidebar,
3194
3627
  {
3195
3628
  selection,
@@ -3199,14 +3632,14 @@ function Shell() {
3199
3632
  width: layout.width,
3200
3633
  searchRef,
3201
3634
  onFound: (d) => setFound((f) => ({ ...f, [`${d.provider}:${d.providerSessionId}`]: d })),
3202
- footer: /* @__PURE__ */ jsx6(
3635
+ footer: /* @__PURE__ */ jsx7(
3203
3636
  ProvidersFooter,
3204
3637
  {
3205
3638
  theme,
3206
3639
  setTheme,
3207
- extra: /* @__PURE__ */ jsxs6(Fragment4, { children: [
3208
- /* @__PURE__ */ jsx6(NotifyToggle, {}),
3209
- /* @__PURE__ */ jsx6(
3640
+ extra: /* @__PURE__ */ jsxs7(Fragment5, { children: [
3641
+ /* @__PURE__ */ jsx7(NotifyToggle, {}),
3642
+ /* @__PURE__ */ jsx7(
3210
3643
  "button",
3211
3644
  {
3212
3645
  type: "button",
@@ -3214,7 +3647,7 @@ function Shell() {
3214
3647
  onClick: () => setShortcutsOpen(true),
3215
3648
  "aria-label": "Keyboard shortcuts (\u2318/)",
3216
3649
  title: "Keyboard shortcuts \u2318/",
3217
- children: /* @__PURE__ */ jsx6(KeyboardIcon, { size: 14 })
3650
+ children: /* @__PURE__ */ jsx7(KeyboardIcon, { size: 14 })
3218
3651
  }
3219
3652
  )
3220
3653
  ] })
@@ -3222,11 +3655,11 @@ function Shell() {
3222
3655
  )
3223
3656
  }
3224
3657
  ),
3225
- /* @__PURE__ */ jsx6(Resizer, { width: layout.width, setWidth: layout.setWidth })
3658
+ /* @__PURE__ */ jsx7(Resizer, { width: layout.width, setWidth: layout.setWidth })
3226
3659
  ] }),
3227
- /* @__PURE__ */ jsx6("main", { className: "flex min-w-0 flex-1", children: main })
3660
+ /* @__PURE__ */ jsx7("main", { className: "flex min-w-0 flex-1", children: main })
3228
3661
  ] }),
3229
- /* @__PURE__ */ jsx6(
3662
+ /* @__PURE__ */ jsx7(
3230
3663
  NewSessionDialog,
3231
3664
  {
3232
3665
  open: newOpen,
@@ -3237,12 +3670,12 @@ function Shell() {
3237
3670
  }
3238
3671
  }
3239
3672
  ),
3240
- /* @__PURE__ */ jsx6(ShortcutsDialog, { open: shortcutsOpen, onOpenChange: setShortcutsOpen }),
3241
- /* @__PURE__ */ jsx6(Toast, { text: toast })
3673
+ /* @__PURE__ */ jsx7(ShortcutsDialog, { open: shortcutsOpen, onOpenChange: setShortcutsOpen }),
3674
+ /* @__PURE__ */ jsx7(Toast, { text: toast })
3242
3675
  ] }) });
3243
3676
  }
3244
3677
  function CodingSessionsApp({ transport }) {
3245
- return /* @__PURE__ */ jsx6(CodingSessionsProvider, { transport, children: /* @__PURE__ */ jsx6(Shell, {}) });
3678
+ return /* @__PURE__ */ jsx7(CodingSessionsProvider, { transport, children: /* @__PURE__ */ jsx7(Shell, {}) });
3246
3679
  }
3247
3680
  export {
3248
3681
  CodingSessionsApp,