@ai-matrx/coding-sessions 0.1.83 → 0.1.85
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.
- package/CHANGELOG.md +12 -0
- package/dist/engine/index.cjs +521 -112
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +4 -1
- package/dist/engine/index.d.ts +4 -1
- package/dist/engine/index.js +521 -112
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/worker.js +2 -2
- package/dist/engine/worker.js.map +1 -1
- package/dist/{index-DQ0teQvw.d.cts → index-DEPwyr2j.d.cts} +130 -0
- package/dist/{index-DQ0teQvw.d.ts → index-DEPwyr2j.d.ts} +130 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -1
- package/dist/index.d.ts +87 -1
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +666 -408
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +87 -7
- package/dist/react/index.d.ts +87 -7
- package/dist/react/index.js +674 -403
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +588 -127
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +4 -1
- package/dist/server/index.d.ts +4 -1
- package/dist/server/index.js +587 -126
- package/dist/server/index.js.map +1 -1
- package/dist/ui/assets/index-DSWoryQZ.js +72 -0
- package/dist/ui/assets/index-Gp2bMDtx.css +2 -0
- package/dist/ui/index.html +2 -2
- package/package.json +4 -2
- package/dist/ui/assets/index-C-_1qjy9.css +0 -2
- package/dist/ui/assets/index-CmFgFvLa.js +0 -69
package/dist/react/index.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
import {
|
|
5
5
|
useCallback as useCallback2,
|
|
6
6
|
useContext as useContext3,
|
|
7
|
-
useEffect as
|
|
8
|
-
useMemo as
|
|
9
|
-
useRef as
|
|
10
|
-
useState as
|
|
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,7 +16,7 @@ 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
|
|
19
|
+
Button as Button3,
|
|
20
20
|
Dialog,
|
|
21
21
|
DropdownMenu as DropdownMenu2,
|
|
22
22
|
DropdownMenuContent as DropdownMenuContent2,
|
|
@@ -26,9 +26,9 @@ import {
|
|
|
26
26
|
DialogFooter,
|
|
27
27
|
DialogHeader,
|
|
28
28
|
DialogTitle,
|
|
29
|
-
Input,
|
|
30
|
-
Textarea,
|
|
31
|
-
cn as
|
|
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
|
-
|
|
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
|
-
"
|
|
496
|
+
"svg",
|
|
495
497
|
{
|
|
496
498
|
className: `cs-provider-mark cs-provider-mark--${provider}`,
|
|
497
|
-
|
|
499
|
+
width: size,
|
|
500
|
+
height: size,
|
|
501
|
+
viewBox: "0 0 24 24",
|
|
502
|
+
fill: "currentColor",
|
|
498
503
|
"aria-hidden": "true",
|
|
499
|
-
|
|
504
|
+
"data-provider-mark": provider,
|
|
505
|
+
children: /* @__PURE__ */ jsx("path", { d: provider === "claude" ? CLAUDE_MARK : OPENAI_MARK })
|
|
500
506
|
}
|
|
501
507
|
);
|
|
502
508
|
}
|
|
@@ -893,10 +899,230 @@ function ModelPicker(props) {
|
|
|
893
899
|
] });
|
|
894
900
|
}
|
|
895
901
|
|
|
896
|
-
// src/react/
|
|
897
|
-
import {
|
|
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,
|
|
912
|
+
Input,
|
|
913
|
+
Select,
|
|
914
|
+
SelectContent,
|
|
915
|
+
SelectItem,
|
|
916
|
+
SelectTrigger,
|
|
917
|
+
SelectValue,
|
|
918
|
+
Textarea,
|
|
919
|
+
TooltipProvider,
|
|
920
|
+
cn as cn3
|
|
921
|
+
} from "@ai-matrx/design-system";
|
|
922
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
923
|
+
var SIGNED_OUT_AGENTS = "Sign in to AI Matrx to use your agents";
|
|
924
|
+
var LATEST = "latest";
|
|
925
|
+
function bridgedClient(transport) {
|
|
926
|
+
const call = (request) => {
|
|
927
|
+
const run = () => transport.call("agentCatalogRpc", request).then((result) => ({
|
|
928
|
+
data: result.data,
|
|
929
|
+
error: result.error ? {
|
|
930
|
+
message: result.error.message,
|
|
931
|
+
...result.error.code ? { code: result.error.code } : {},
|
|
932
|
+
details: result.error.details ?? null,
|
|
933
|
+
hint: result.error.hint ?? null
|
|
934
|
+
} : null,
|
|
935
|
+
count: result.count ?? null
|
|
936
|
+
}));
|
|
937
|
+
return {
|
|
938
|
+
then: (onOk, onErr) => run().then(onOk, onErr),
|
|
939
|
+
range: (from, to) => call({ ...request, range: [from, to] }),
|
|
940
|
+
order: (column, options) => call({ ...request, order: { column, ascending: options?.ascending !== false } })
|
|
941
|
+
};
|
|
942
|
+
};
|
|
943
|
+
return {
|
|
944
|
+
rpc: (fn, args, options) => call({ fn, ...args ? { args } : {}, ...options?.count ? { count: options.count } : {} })
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
function useAgentAccess(transport, open) {
|
|
948
|
+
const [access, setAccess] = useState4(null);
|
|
949
|
+
useEffect2(() => {
|
|
950
|
+
if (!open) return;
|
|
951
|
+
let alive = true;
|
|
952
|
+
transport.call("agentAccess").then((next) => alive && setAccess(next)).catch(() => alive && setAccess({ signedIn: false, userId: null, organizationId: null, configured: false }));
|
|
953
|
+
return () => {
|
|
954
|
+
alive = false;
|
|
955
|
+
};
|
|
956
|
+
}, [transport, open]);
|
|
957
|
+
return access;
|
|
958
|
+
}
|
|
959
|
+
function useCatalog(transport, userId, onError) {
|
|
960
|
+
const report = useRef(onError);
|
|
961
|
+
report.current = onError;
|
|
962
|
+
return useMemo2(() => {
|
|
963
|
+
if (!userId) return null;
|
|
964
|
+
return createAgentCatalog({
|
|
965
|
+
client: bridgedClient(transport),
|
|
966
|
+
identity: { requireUserId: () => userId, getUserId: () => userId },
|
|
967
|
+
catalogId: `coding-sessions:${userId}`,
|
|
968
|
+
// A failed catalogue read shows at the field, never only in the console.
|
|
969
|
+
errorSink: (event) => {
|
|
970
|
+
console.error(`[coding-sessions] agent catalogue: ${event.code}: ${event.message}`);
|
|
971
|
+
if (event.code === "list_read_failed") report.current("Couldn't load your agents. Reopen to retry.");
|
|
972
|
+
}
|
|
973
|
+
});
|
|
974
|
+
}, [transport, userId]);
|
|
975
|
+
}
|
|
976
|
+
function asRunInputVariables(defs) {
|
|
977
|
+
return defs.flatMap((def) => typeof def.name === "string" ? [def] : []);
|
|
978
|
+
}
|
|
979
|
+
function AgentField(props) {
|
|
980
|
+
const access = useAgentAccess(props.transport, props.open);
|
|
981
|
+
const [details, setDetails] = useState4(null);
|
|
982
|
+
const [problem, setProblem] = useState4(null);
|
|
983
|
+
const catalog = useCatalog(props.transport, access?.signedIn ? access.userId : null, setProblem);
|
|
984
|
+
const agentId = props.value?.agentId ?? null;
|
|
985
|
+
useEffect2(() => {
|
|
986
|
+
setDetails(null);
|
|
987
|
+
setProblem(null);
|
|
988
|
+
if (!agentId) return;
|
|
989
|
+
let alive = true;
|
|
990
|
+
props.transport.call("agentDetails", agentId).then((next) => alive && setDetails(next)).catch((error) => alive && setProblem(error instanceof Error ? error.message : String(error)));
|
|
991
|
+
return () => {
|
|
992
|
+
alive = false;
|
|
993
|
+
};
|
|
994
|
+
}, [agentId, props.transport]);
|
|
995
|
+
const { onDetails } = props;
|
|
996
|
+
useEffect2(() => {
|
|
997
|
+
onDetails?.(details);
|
|
998
|
+
}, [details, onDetails]);
|
|
999
|
+
const inputs = useMemo2(() => deriveRunInputs(asRunInputVariables(details?.variables ?? []), humanizeContextKey), [details]);
|
|
1000
|
+
if (access === null) return /* @__PURE__ */ jsx5("div", { className: "cs-skeleton h-9 rounded-lg" });
|
|
1001
|
+
if (!access.signedIn || !catalog) {
|
|
1002
|
+
return /* @__PURE__ */ jsx5("p", { className: "text-[12.5px] text-muted-foreground", children: SIGNED_OUT_AGENTS });
|
|
1003
|
+
}
|
|
1004
|
+
const setVariable = (name, value) => {
|
|
1005
|
+
if (!props.value) return;
|
|
1006
|
+
props.onChange({ ...props.value, variables: { ...props.value.variables ?? {}, [name]: value } });
|
|
1007
|
+
};
|
|
1008
|
+
return /* @__PURE__ */ jsxs5("div", { className: "space-y-3", children: [
|
|
1009
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
|
|
1010
|
+
/* @__PURE__ */ jsx5(TooltipProvider, { children: /* @__PURE__ */ jsx5(AgentCatalogProvider, { catalog, children: /* @__PURE__ */ jsx5(
|
|
1011
|
+
AgentListDropdown,
|
|
1012
|
+
{
|
|
1013
|
+
consumerId: "coding-sessions-new-session",
|
|
1014
|
+
activeAgentId: agentId,
|
|
1015
|
+
label: details?.name ?? (agentId ? "Loading\u2026" : "None"),
|
|
1016
|
+
onSelect: (id) => props.onChange({ agentId: id, versionId: null, variables: {} })
|
|
1017
|
+
}
|
|
1018
|
+
) }) }),
|
|
1019
|
+
agentId ? /* @__PURE__ */ jsx5(Button, { type: "button", size: "sm", variant: "ghost", onClick: () => props.onChange(null), children: "Remove" }) : null
|
|
1020
|
+
] }),
|
|
1021
|
+
problem ? /* @__PURE__ */ jsx5("p", { className: "text-[12px] text-destructive", children: problem }) : null,
|
|
1022
|
+
details && props.value ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1023
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
|
|
1024
|
+
/* @__PURE__ */ jsx5("span", { className: "w-[72px] shrink-0 text-[12px] text-muted-foreground", children: "Version" }),
|
|
1025
|
+
/* @__PURE__ */ jsxs5(
|
|
1026
|
+
Select,
|
|
1027
|
+
{
|
|
1028
|
+
value: props.value.versionId ?? LATEST,
|
|
1029
|
+
onValueChange: (next) => props.value && props.onChange({ ...props.value, versionId: next === LATEST ? null : next }),
|
|
1030
|
+
children: [
|
|
1031
|
+
/* @__PURE__ */ jsx5(SelectTrigger, { className: "h-8 w-[200px] text-[12.5px]", "aria-label": "Agent version", children: /* @__PURE__ */ jsx5(SelectValue, {}) }),
|
|
1032
|
+
/* @__PURE__ */ jsxs5(SelectContent, { children: [
|
|
1033
|
+
/* @__PURE__ */ jsx5(SelectItem, { value: LATEST, children: details.latestVersionNumber !== null ? `Latest (v${details.latestVersionNumber})` : "Latest" }),
|
|
1034
|
+
details.versions.map((v) => /* @__PURE__ */ jsxs5(SelectItem, { value: v.id, children: [
|
|
1035
|
+
"v",
|
|
1036
|
+
v.versionNumber
|
|
1037
|
+
] }, v.id))
|
|
1038
|
+
] })
|
|
1039
|
+
]
|
|
1040
|
+
}
|
|
1041
|
+
)
|
|
1042
|
+
] }),
|
|
1043
|
+
inputs.map((input) => {
|
|
1044
|
+
const raw = props.value?.variables?.[input.name];
|
|
1045
|
+
const value = typeof raw === "string" ? raw : "";
|
|
1046
|
+
const id = `cs-agent-var-${input.name}`;
|
|
1047
|
+
const invalid = props.missing === input.name;
|
|
1048
|
+
return /* @__PURE__ */ jsxs5("div", { className: "space-y-1", children: [
|
|
1049
|
+
/* @__PURE__ */ jsxs5("label", { htmlFor: id, className: "text-[12px] font-medium", children: [
|
|
1050
|
+
input.label,
|
|
1051
|
+
input.required ? /* @__PURE__ */ jsx5("span", { className: "text-muted-foreground", children: " \xB7 required" }) : null
|
|
1052
|
+
] }),
|
|
1053
|
+
input.options && input.options.length > 0 ? /* @__PURE__ */ jsxs5(Select, { value, onValueChange: (next) => setVariable(input.name, next), children: [
|
|
1054
|
+
/* @__PURE__ */ jsx5(SelectTrigger, { id, className: "h-8 text-[12.5px]", "aria-invalid": invalid || void 0, children: /* @__PURE__ */ jsx5(SelectValue, { placeholder: "Choose\u2026" }) }),
|
|
1055
|
+
/* @__PURE__ */ jsx5(SelectContent, { children: input.options.map((option) => /* @__PURE__ */ jsx5(SelectItem, { value: option, children: option }, option)) })
|
|
1056
|
+
] }) : input.variable.customComponent?.type === "textarea" ? /* @__PURE__ */ jsx5(
|
|
1057
|
+
Textarea,
|
|
1058
|
+
{
|
|
1059
|
+
id,
|
|
1060
|
+
rows: 2,
|
|
1061
|
+
value,
|
|
1062
|
+
onChange: (e) => setVariable(input.name, e.target.value),
|
|
1063
|
+
placeholder: input.hint ?? "",
|
|
1064
|
+
"aria-invalid": invalid || void 0
|
|
1065
|
+
}
|
|
1066
|
+
) : /* @__PURE__ */ jsx5(
|
|
1067
|
+
Input,
|
|
1068
|
+
{
|
|
1069
|
+
id,
|
|
1070
|
+
value,
|
|
1071
|
+
onChange: (e) => setVariable(input.name, e.target.value),
|
|
1072
|
+
placeholder: input.hint ?? "",
|
|
1073
|
+
"aria-invalid": invalid || void 0
|
|
1074
|
+
}
|
|
1075
|
+
),
|
|
1076
|
+
invalid ? /* @__PURE__ */ jsx5("p", { className: "text-[12px] text-destructive", children: "Fill this in to use the agent" }) : null
|
|
1077
|
+
] }, input.name);
|
|
1078
|
+
})
|
|
1079
|
+
] }) : null
|
|
1080
|
+
] });
|
|
1081
|
+
}
|
|
1082
|
+
function missingRequiredVariable(details, selection) {
|
|
1083
|
+
if (!details || !selection) return null;
|
|
1084
|
+
for (const input of deriveRunInputs(asRunInputVariables(details.variables), humanizeContextKey)) {
|
|
1085
|
+
if (!input.required) continue;
|
|
1086
|
+
const value = selection.variables?.[input.name];
|
|
1087
|
+
if (typeof value !== "string" || !value.trim()) return input.name;
|
|
1088
|
+
}
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
var PART_LABEL = {
|
|
1092
|
+
instructions: "Instructions",
|
|
1093
|
+
skills: "Skills",
|
|
1094
|
+
tools: "Tools"
|
|
1095
|
+
};
|
|
1096
|
+
function AgentChip({ agent }) {
|
|
1097
|
+
const parts = agent.loaded.map(
|
|
1098
|
+
(part) => part.part === "instructions" ? `${PART_LABEL.instructions} ${part.loaded === 1 ? "\u2713" : "\u2014"}` : `${PART_LABEL[part.part]} ${part.loaded}/${part.total}`
|
|
1099
|
+
);
|
|
1100
|
+
const missing = agent.unavailable.slice(0, 6).map((u) => `${u.name}: ${u.reason}`);
|
|
1101
|
+
const more = agent.unavailable.length > 6 ? [`+${agent.unavailable.length - 6} more`] : [];
|
|
1102
|
+
const complete = agent.loaded.every((part) => part.loaded === part.total);
|
|
1103
|
+
return /* @__PURE__ */ jsxs5(
|
|
1104
|
+
"span",
|
|
1105
|
+
{
|
|
1106
|
+
className: cn3("cs-agent-chip", !complete && "cs-agent-chip--partial"),
|
|
1107
|
+
title: missing.length ? [...missing, ...more].join("\n") : "Everything loaded",
|
|
1108
|
+
"data-testid": "cs-agent-chip",
|
|
1109
|
+
children: [
|
|
1110
|
+
/* @__PURE__ */ jsxs5("span", { className: "font-medium text-foreground", children: [
|
|
1111
|
+
agent.name,
|
|
1112
|
+
agent.versionNumber !== null ? ` v${agent.versionNumber}` : ""
|
|
1113
|
+
] }),
|
|
1114
|
+
" ",
|
|
1115
|
+
"\xB7 ",
|
|
1116
|
+
parts.join(" \xB7 ")
|
|
1117
|
+
]
|
|
1118
|
+
}
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// src/react/sidebar.tsx
|
|
1123
|
+
import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState5 } from "react";
|
|
1124
|
+
import {
|
|
1125
|
+
Button as Button2,
|
|
900
1126
|
ContextMenu,
|
|
901
1127
|
ContextMenuContent,
|
|
902
1128
|
ContextMenuTrigger,
|
|
@@ -908,9 +1134,9 @@ import {
|
|
|
908
1134
|
DropdownMenuRadioItem,
|
|
909
1135
|
DropdownMenuSeparator as DropdownMenuSeparator2,
|
|
910
1136
|
DropdownMenuTrigger,
|
|
911
|
-
cn as
|
|
1137
|
+
cn as cn4
|
|
912
1138
|
} from "@ai-matrx/design-system";
|
|
913
|
-
import { Fragment as
|
|
1139
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
914
1140
|
function readLocal(key, allowed, fallback) {
|
|
915
1141
|
try {
|
|
916
1142
|
const value = localStorage.getItem(key);
|
|
@@ -926,23 +1152,23 @@ function writeLocal(key, value) {
|
|
|
926
1152
|
}
|
|
927
1153
|
}
|
|
928
1154
|
function SectionLabel({ children, action }) {
|
|
929
|
-
return /* @__PURE__ */
|
|
930
|
-
/* @__PURE__ */
|
|
1155
|
+
return /* @__PURE__ */ jsxs6("div", { "data-cs-section-label": true, className: "flex h-8 items-center justify-between px-3 pt-3", children: [
|
|
1156
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[12px] font-medium text-muted-foreground", children }),
|
|
931
1157
|
action
|
|
932
1158
|
] });
|
|
933
1159
|
}
|
|
934
1160
|
function GroupLabel({ children }) {
|
|
935
|
-
return /* @__PURE__ */
|
|
1161
|
+
return /* @__PURE__ */ jsx6("div", { className: "truncate px-4 pb-0.5 pt-2.5 text-[12px] font-medium text-muted-foreground", children });
|
|
936
1162
|
}
|
|
937
1163
|
function RenameInput(props) {
|
|
938
|
-
const [value, setValue] =
|
|
939
|
-
const done =
|
|
1164
|
+
const [value, setValue] = useState5(props.initial);
|
|
1165
|
+
const done = useRef2(false);
|
|
940
1166
|
const finish = (title) => {
|
|
941
1167
|
if (done.current) return;
|
|
942
1168
|
done.current = true;
|
|
943
1169
|
props.onDone(title);
|
|
944
1170
|
};
|
|
945
|
-
return /* @__PURE__ */
|
|
1171
|
+
return /* @__PURE__ */ jsx6(
|
|
946
1172
|
"input",
|
|
947
1173
|
{
|
|
948
1174
|
autoFocus: true,
|
|
@@ -959,11 +1185,16 @@ function RenameInput(props) {
|
|
|
959
1185
|
}
|
|
960
1186
|
);
|
|
961
1187
|
}
|
|
1188
|
+
function entryTarget(entry) {
|
|
1189
|
+
if (entry.kind === "session" && entry.session) return `#s/${entry.session.id}`;
|
|
1190
|
+
if (entry.providerSessionId) return `#d/${entry.provider}/${entry.providerSessionId}`;
|
|
1191
|
+
return "";
|
|
1192
|
+
}
|
|
962
1193
|
function Row(props) {
|
|
963
1194
|
const client = useCodingSessionsClient();
|
|
964
1195
|
const show = useToastShow();
|
|
965
|
-
const [renaming, setRenaming] =
|
|
966
|
-
const [menuOpen, setMenuOpen] =
|
|
1196
|
+
const [renaming, setRenaming] = useState5(false);
|
|
1197
|
+
const [menuOpen, setMenuOpen] = useState5(false);
|
|
967
1198
|
const { entry } = props;
|
|
968
1199
|
const rename = (title) => {
|
|
969
1200
|
setRenaming(false);
|
|
@@ -973,14 +1204,20 @@ function Row(props) {
|
|
|
973
1204
|
(error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`)
|
|
974
1205
|
);
|
|
975
1206
|
};
|
|
976
|
-
return /* @__PURE__ */
|
|
977
|
-
/* @__PURE__ */
|
|
1207
|
+
return /* @__PURE__ */ jsxs6(ContextMenu, { children: [
|
|
1208
|
+
/* @__PURE__ */ jsx6(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
|
|
978
1209
|
"div",
|
|
979
1210
|
{
|
|
980
|
-
className:
|
|
1211
|
+
className: cn4("cs-row group", props.active && "cs-row--active", menuOpen && "cs-row--menu"),
|
|
981
1212
|
"data-hidden": entry.hidden || void 0,
|
|
1213
|
+
"data-cs-row": entry.key,
|
|
1214
|
+
"data-cs-target": entryTarget(entry),
|
|
1215
|
+
"data-cs-provider": entry.provider,
|
|
1216
|
+
"data-cs-title": entry.title,
|
|
1217
|
+
"data-cs-live": props.live ? "true" : void 0,
|
|
1218
|
+
"data-cs-active": props.active ? "true" : void 0,
|
|
982
1219
|
children: [
|
|
983
|
-
/* @__PURE__ */
|
|
1220
|
+
/* @__PURE__ */ jsx6(
|
|
984
1221
|
"button",
|
|
985
1222
|
{
|
|
986
1223
|
type: "button",
|
|
@@ -992,39 +1229,39 @@ function Row(props) {
|
|
|
992
1229
|
(${entry.originalTitle})` : entry.title
|
|
993
1230
|
}
|
|
994
1231
|
),
|
|
995
|
-
/* @__PURE__ */
|
|
996
|
-
/* @__PURE__ */
|
|
997
|
-
renaming ? /* @__PURE__ */
|
|
998
|
-
/* @__PURE__ */
|
|
999
|
-
entry.pinned ? /* @__PURE__ */
|
|
1232
|
+
/* @__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 }) }),
|
|
1233
|
+
/* @__PURE__ */ jsxs6("span", { className: "cs-row__body", children: [
|
|
1234
|
+
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: [
|
|
1235
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 truncate text-[13px] font-medium leading-5", children: entry.title }),
|
|
1236
|
+
entry.pinned ? /* @__PURE__ */ jsx6(PinIcon, { size: 11, className: "shrink-0 text-muted-foreground", "aria-label": "Pinned" }) : null
|
|
1000
1237
|
] }),
|
|
1001
|
-
/* @__PURE__ */
|
|
1002
|
-
props.snippet ? /* @__PURE__ */
|
|
1238
|
+
/* @__PURE__ */ jsx6("span", { className: "block truncate text-[11.5px] leading-4 text-muted-foreground", children: props.meta }),
|
|
1239
|
+
props.snippet ? /* @__PURE__ */ jsx6("span", { className: "cs-row__snippet", children: props.snippet }) : null
|
|
1003
1240
|
] }),
|
|
1004
|
-
renaming ? null : /* @__PURE__ */
|
|
1241
|
+
renaming ? null : /* @__PURE__ */ jsxs6("span", { className: "cs-row__actions", children: [
|
|
1005
1242
|
props.takeover,
|
|
1006
|
-
/* @__PURE__ */
|
|
1007
|
-
/* @__PURE__ */
|
|
1008
|
-
/* @__PURE__ */
|
|
1243
|
+
/* @__PURE__ */ jsxs6(DropdownMenu, { open: menuOpen, onOpenChange: setMenuOpen, children: [
|
|
1244
|
+
/* @__PURE__ */ jsx6(DropdownMenuTrigger, { 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 }) }) }),
|
|
1245
|
+
/* @__PURE__ */ jsx6(DropdownMenuContent, { align: "start", className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx6(ChatMenuItems, { entry, variant: "dropdown", onRename: () => setRenaming(true) }) })
|
|
1009
1246
|
] })
|
|
1010
1247
|
] })
|
|
1011
1248
|
]
|
|
1012
1249
|
}
|
|
1013
1250
|
) }),
|
|
1014
|
-
/* @__PURE__ */
|
|
1251
|
+
/* @__PURE__ */ jsx6(ContextMenuContent, { className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx6(ChatMenuItems, { entry, variant: "context", onRename: () => setRenaming(true) }) })
|
|
1015
1252
|
] });
|
|
1016
1253
|
}
|
|
1017
1254
|
function SidebarSkeleton() {
|
|
1018
|
-
return /* @__PURE__ */
|
|
1255
|
+
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
1256
|
}
|
|
1020
1257
|
function Highlight({ text, query }) {
|
|
1021
1258
|
const q = query.trim().toLowerCase();
|
|
1022
1259
|
if (!q) return text;
|
|
1023
1260
|
const at = text.toLowerCase().indexOf(q);
|
|
1024
1261
|
if (at < 0) return text;
|
|
1025
|
-
return /* @__PURE__ */
|
|
1262
|
+
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1026
1263
|
text.slice(0, at),
|
|
1027
|
-
/* @__PURE__ */
|
|
1264
|
+
/* @__PURE__ */ jsx6("mark", { className: "cs-mark", children: text.slice(at, at + q.length) }),
|
|
1028
1265
|
text.slice(at + q.length)
|
|
1029
1266
|
] });
|
|
1030
1267
|
}
|
|
@@ -1039,8 +1276,8 @@ var EMPTY_SEARCH = {
|
|
|
1039
1276
|
};
|
|
1040
1277
|
function useContentSearch(query) {
|
|
1041
1278
|
const client = useCodingSessionsClient();
|
|
1042
|
-
const [state, setState] =
|
|
1043
|
-
const latest =
|
|
1279
|
+
const [state, setState] = useState5(EMPTY_SEARCH);
|
|
1280
|
+
const latest = useRef2(query);
|
|
1044
1281
|
latest.current = query;
|
|
1045
1282
|
const run = useCallback(
|
|
1046
1283
|
async (q, cursor, append) => {
|
|
@@ -1064,7 +1301,7 @@ function useContentSearch(query) {
|
|
|
1064
1301
|
},
|
|
1065
1302
|
[client]
|
|
1066
1303
|
);
|
|
1067
|
-
|
|
1304
|
+
useEffect3(() => {
|
|
1068
1305
|
const q = query.trim();
|
|
1069
1306
|
if (q.length < 2) {
|
|
1070
1307
|
setState(EMPTY_SEARCH);
|
|
@@ -1093,19 +1330,19 @@ function Sidebar(props) {
|
|
|
1093
1330
|
const client = useCodingSessionsClient();
|
|
1094
1331
|
const state = useCodingSessionsState();
|
|
1095
1332
|
const now = useMinuteClock();
|
|
1096
|
-
const [query, setQuery] =
|
|
1333
|
+
const [query, setQuery] = useState5("");
|
|
1097
1334
|
const [search, searchMore] = useContentSearch(query);
|
|
1098
|
-
const [groupMode, setGroupMode] =
|
|
1099
|
-
const [showHidden, setShowHidden] =
|
|
1100
|
-
const [takingOver, setTakingOver] =
|
|
1101
|
-
const [takeoverError, setTakeoverError] =
|
|
1335
|
+
const [groupMode, setGroupMode] = useState5(() => readLocal("coding-sessions.group", ["date", "folder"], "date"));
|
|
1336
|
+
const [showHidden, setShowHidden] = useState5(false);
|
|
1337
|
+
const [takingOver, setTakingOver] = useState5(null);
|
|
1338
|
+
const [takeoverError, setTakeoverError] = useState5(null);
|
|
1102
1339
|
const prefs = state.preferences;
|
|
1103
1340
|
const sessions = state.sessions.data;
|
|
1104
1341
|
const isLive = (id) => {
|
|
1105
1342
|
const run = state.runs[id];
|
|
1106
1343
|
return run !== void 0 && !isTerminalRunStatus(run.status);
|
|
1107
1344
|
};
|
|
1108
|
-
const { ours, others, hiddenCount } =
|
|
1345
|
+
const { ours, others, hiddenCount } = useMemo3(() => {
|
|
1109
1346
|
const oursList = sessions.map((s) => sessionEntry(s, prefs));
|
|
1110
1347
|
const known = new Set(sessions.map((s) => s.providerSessionId).filter(Boolean));
|
|
1111
1348
|
const othersList = state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => discoveredEntry(d, prefs));
|
|
@@ -1145,8 +1382,8 @@ function Sidebar(props) {
|
|
|
1145
1382
|
let meta;
|
|
1146
1383
|
if (live) meta = `${PROVIDER_LABEL[entry.provider]} is working\u2026`;
|
|
1147
1384
|
else if (d?.activeElsewhere)
|
|
1148
|
-
meta = /* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1385
|
+
meta = /* @__PURE__ */ jsxs6("span", { className: "cs-live-elsewhere", children: [
|
|
1386
|
+
/* @__PURE__ */ jsx6("span", { className: "cs-live-dot", "aria-hidden": "true" }),
|
|
1150
1387
|
"Running in ",
|
|
1151
1388
|
PROVIDER_LABEL[entry.provider]
|
|
1152
1389
|
] });
|
|
@@ -1155,8 +1392,8 @@ function Sidebar(props) {
|
|
|
1155
1392
|
const where = entry.cwd ? prettyPath2(entry.cwd) : "unknown folder";
|
|
1156
1393
|
meta = `${status}${entry.kind === "discovered" ? `${PROVIDER_LABEL[entry.provider]} \xB7 ` : ""}${groupMode === "folder" && !extra ? "" : `${where} \xB7 `}${relativeTime(entry.updatedAt, now)}`;
|
|
1157
1394
|
}
|
|
1158
|
-
return /* @__PURE__ */
|
|
1159
|
-
/* @__PURE__ */
|
|
1395
|
+
return /* @__PURE__ */ jsxs6("div", { children: [
|
|
1396
|
+
/* @__PURE__ */ jsx6(
|
|
1160
1397
|
Row,
|
|
1161
1398
|
{
|
|
1162
1399
|
entry,
|
|
@@ -1165,7 +1402,7 @@ function Sidebar(props) {
|
|
|
1165
1402
|
live,
|
|
1166
1403
|
meta,
|
|
1167
1404
|
snippet: extra?.snippet,
|
|
1168
|
-
takeover: d?.cwd ? /* @__PURE__ */
|
|
1405
|
+
takeover: d?.cwd ? /* @__PURE__ */ jsxs6(
|
|
1169
1406
|
"button",
|
|
1170
1407
|
{
|
|
1171
1408
|
type: "button",
|
|
@@ -1174,18 +1411,18 @@ function Sidebar(props) {
|
|
|
1174
1411
|
title: d.activeElsewhere ? d.activeElsewhere.message : "Continue this chat here",
|
|
1175
1412
|
disabled: takingOver === d.providerSessionId,
|
|
1176
1413
|
children: [
|
|
1177
|
-
takingOver === d.providerSessionId ? /* @__PURE__ */
|
|
1414
|
+
takingOver === d.providerSessionId ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 11 }) : null,
|
|
1178
1415
|
"Take over"
|
|
1179
1416
|
]
|
|
1180
1417
|
}
|
|
1181
1418
|
) : null
|
|
1182
1419
|
}
|
|
1183
1420
|
),
|
|
1184
|
-
takeoverError && d && takeoverError.id === d.providerSessionId ? /* @__PURE__ */
|
|
1421
|
+
takeoverError && d && takeoverError.id === d.providerSessionId ? /* @__PURE__ */ jsx6("p", { className: "mx-4 mb-1 text-[11.5px] text-destructive", children: takeoverError.message }) : null
|
|
1185
1422
|
] }, entry.key);
|
|
1186
1423
|
};
|
|
1187
|
-
const renderGroups = (entries) => groupEntries(entries, groupMode, now).map((group) => /* @__PURE__ */
|
|
1188
|
-
/* @__PURE__ */
|
|
1424
|
+
const renderGroups = (entries) => groupEntries(entries, groupMode, now).map((group) => /* @__PURE__ */ jsxs6("div", { role: "group", "aria-label": group.label, children: [
|
|
1425
|
+
/* @__PURE__ */ jsx6(GroupLabel, { children: group.label }),
|
|
1189
1426
|
group.entries.map((e) => renderEntry(e))
|
|
1190
1427
|
] }, group.label));
|
|
1191
1428
|
const searching = query.trim().length > 0;
|
|
@@ -1202,60 +1439,60 @@ function Sidebar(props) {
|
|
|
1202
1439
|
props.onFound(hitToDiscovered(hit));
|
|
1203
1440
|
props.select({ kind: "discovered", provider: hit.provider, id: hit.providerSessionId });
|
|
1204
1441
|
};
|
|
1205
|
-
const searchBody = /* @__PURE__ */
|
|
1206
|
-
/* @__PURE__ */
|
|
1207
|
-
titleMatches.length === 0 ? /* @__PURE__ */
|
|
1208
|
-
/* @__PURE__ */
|
|
1209
|
-
query.trim().length < 2 ? /* @__PURE__ */
|
|
1442
|
+
const searchBody = /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1443
|
+
/* @__PURE__ */ jsx6(SectionLabel, { children: "Chats" }),
|
|
1444
|
+
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 })),
|
|
1445
|
+
/* @__PURE__ */ jsx6(SectionLabel, { children: "In conversations" }),
|
|
1446
|
+
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
1447
|
contentHits.map((hit) => {
|
|
1211
1448
|
const known = allByKey.get(chatKey(hit.provider, hit.providerSessionId));
|
|
1212
1449
|
const entry = known ?? discoveredEntry(hitToDiscovered(hit), prefs);
|
|
1213
|
-
return /* @__PURE__ */
|
|
1450
|
+
return /* @__PURE__ */ jsx6("div", { onClickCapture: known ? void 0 : () => props.onFound(hitToDiscovered(hit)), children: renderEntry(entry, {
|
|
1214
1451
|
query,
|
|
1215
|
-
snippet: hit.snippet ? /* @__PURE__ */
|
|
1452
|
+
snippet: hit.snippet ? /* @__PURE__ */ jsx6(Highlight, { text: hit.snippet, query }) : void 0
|
|
1216
1453
|
}) }, `hit:${entry.key}`);
|
|
1217
1454
|
}),
|
|
1218
|
-
/* @__PURE__ */
|
|
1455
|
+
/* @__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
1456
|
"Search stopped: ",
|
|
1220
1457
|
search.error
|
|
1221
|
-
] }) : search.loading ? /* @__PURE__ */
|
|
1222
|
-
/* @__PURE__ */
|
|
1458
|
+
] }) : search.loading ? /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
1459
|
+
/* @__PURE__ */ jsx6(SpinnerIcon, { size: 12 }),
|
|
1223
1460
|
" Searching your chats\u2026"
|
|
1224
|
-
] }) : search.query ? /* @__PURE__ */
|
|
1461
|
+
] }) : search.query ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1225
1462
|
contentHits.length === 0 && search.hits.length === 0 ? "Nothing found. " : null,
|
|
1226
1463
|
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__ */
|
|
1464
|
+
search.nextCursor !== null ? /* @__PURE__ */ jsx6("button", { type: "button", className: "cs-link ml-1", onClick: searchMore, children: "Search older chats" }) : null
|
|
1228
1465
|
] }) : null })
|
|
1229
1466
|
] })
|
|
1230
1467
|
] });
|
|
1231
|
-
const listBody = /* @__PURE__ */
|
|
1232
|
-
pinned.length > 0 ? /* @__PURE__ */
|
|
1233
|
-
/* @__PURE__ */
|
|
1468
|
+
const listBody = /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1469
|
+
pinned.length > 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1470
|
+
/* @__PURE__ */ jsx6(SectionLabel, { children: "Pinned" }),
|
|
1234
1471
|
pinned.map((e) => renderEntry(e))
|
|
1235
1472
|
] }) : null,
|
|
1236
|
-
running.length > 0 ? /* @__PURE__ */
|
|
1237
|
-
/* @__PURE__ */
|
|
1473
|
+
running.length > 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1474
|
+
/* @__PURE__ */ jsx6(SectionLabel, { children: "Running" }),
|
|
1238
1475
|
running.map((e) => renderEntry(e))
|
|
1239
1476
|
] }) : null,
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
state.sessions.loading && state.sessions.loadedAt === null ? /* @__PURE__ */
|
|
1242
|
-
/* @__PURE__ */
|
|
1477
|
+
/* @__PURE__ */ jsx6(SectionLabel, { children: "Recent" }),
|
|
1478
|
+
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)),
|
|
1479
|
+
/* @__PURE__ */ jsx6(
|
|
1243
1480
|
SectionLabel,
|
|
1244
1481
|
{
|
|
1245
|
-
action: /* @__PURE__ */
|
|
1246
|
-
/* @__PURE__ */
|
|
1247
|
-
/* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1249
|
-
/* @__PURE__ */
|
|
1250
|
-
/* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1482
|
+
action: /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-0.5", children: [
|
|
1483
|
+
/* @__PURE__ */ jsxs6(DropdownMenu, { children: [
|
|
1484
|
+
/* @__PURE__ */ jsx6(DropdownMenuTrigger, { 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" }) }),
|
|
1485
|
+
/* @__PURE__ */ jsxs6(DropdownMenuContent, { align: "end", className: "w-52", children: [
|
|
1486
|
+
/* @__PURE__ */ jsx6(DropdownMenuLabel, { children: "Group your other chats" }),
|
|
1487
|
+
/* @__PURE__ */ jsxs6(DropdownMenuRadioGroup, { value: groupMode, onValueChange: (v) => setMode(v), children: [
|
|
1488
|
+
/* @__PURE__ */ jsx6(DropdownMenuRadioItem, { value: "date", children: "By date" }),
|
|
1489
|
+
/* @__PURE__ */ jsx6(DropdownMenuRadioItem, { value: "folder", children: "By folder" })
|
|
1253
1490
|
] }),
|
|
1254
|
-
/* @__PURE__ */
|
|
1255
|
-
/* @__PURE__ */
|
|
1491
|
+
/* @__PURE__ */ jsx6(DropdownMenuSeparator2, {}),
|
|
1492
|
+
/* @__PURE__ */ jsx6(DropdownMenuItem2, { onSelect: () => setShowHidden((v) => !v), children: showHidden ? "Leave hidden chats out" : `Show hidden chats${hiddenCount ? ` (${hiddenCount})` : ""}` })
|
|
1256
1493
|
] })
|
|
1257
1494
|
] }),
|
|
1258
|
-
/* @__PURE__ */
|
|
1495
|
+
/* @__PURE__ */ jsx6(
|
|
1259
1496
|
"button",
|
|
1260
1497
|
{
|
|
1261
1498
|
type: "button",
|
|
@@ -1263,17 +1500,17 @@ function Sidebar(props) {
|
|
|
1263
1500
|
onClick: () => void client.refreshDiscovered(),
|
|
1264
1501
|
"aria-label": "Look again for your other chats",
|
|
1265
1502
|
title: "Look again",
|
|
1266
|
-
children: state.discovered.loading ? /* @__PURE__ */
|
|
1503
|
+
children: state.discovered.loading ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx6(RefreshIcon, { size: 13 })
|
|
1267
1504
|
}
|
|
1268
1505
|
)
|
|
1269
1506
|
] }),
|
|
1270
1507
|
children: "Your other chats"
|
|
1271
1508
|
}
|
|
1272
1509
|
),
|
|
1273
|
-
state.discovered.loading && state.discovered.loadedAt === null ? /* @__PURE__ */
|
|
1510
|
+
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
1511
|
renderGroups(otherList),
|
|
1275
|
-
state.discovered.data.length >= state.discoveredLimit ? /* @__PURE__ */
|
|
1276
|
-
|
|
1512
|
+
state.discovered.data.length >= state.discoveredLimit ? /* @__PURE__ */ jsx6("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxs6(
|
|
1513
|
+
Button2,
|
|
1277
1514
|
{
|
|
1278
1515
|
variant: "ghost",
|
|
1279
1516
|
size: "sm",
|
|
@@ -1281,32 +1518,32 @@ function Sidebar(props) {
|
|
|
1281
1518
|
onClick: () => void client.showMoreDiscovered(),
|
|
1282
1519
|
disabled: state.discovered.loading,
|
|
1283
1520
|
children: [
|
|
1284
|
-
state.discovered.loading ? /* @__PURE__ */
|
|
1521
|
+
state.discovered.loading ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 13 }) : null,
|
|
1285
1522
|
"Show older chats"
|
|
1286
1523
|
]
|
|
1287
1524
|
}
|
|
1288
1525
|
) }) : null
|
|
1289
1526
|
] }),
|
|
1290
|
-
showHidden ? null : hiddenCount > 0 ? /* @__PURE__ */
|
|
1527
|
+
showHidden ? null : hiddenCount > 0 ? /* @__PURE__ */ jsxs6("button", { type: "button", className: "cs-link mx-4 mt-3 text-[11.5px]", onClick: () => setShowHidden(true), children: [
|
|
1291
1528
|
hiddenCount,
|
|
1292
1529
|
" hidden ",
|
|
1293
1530
|
hiddenCount === 1 ? "chat" : "chats",
|
|
1294
1531
|
" \u2014 show"
|
|
1295
1532
|
] }) : null
|
|
1296
1533
|
] });
|
|
1297
|
-
return /* @__PURE__ */
|
|
1534
|
+
return /* @__PURE__ */ jsxs6(
|
|
1298
1535
|
"aside",
|
|
1299
1536
|
{
|
|
1300
|
-
className: "cs-sidebar flex h-full shrink-0 flex-col border-r border-border bg-
|
|
1537
|
+
className: "cs-sidebar flex h-full shrink-0 flex-col border-r border-border bg-sidebar-background",
|
|
1301
1538
|
style: { width: props.width },
|
|
1302
1539
|
"aria-label": "Sessions",
|
|
1303
1540
|
children: [
|
|
1304
|
-
/* @__PURE__ */
|
|
1305
|
-
/* @__PURE__ */
|
|
1306
|
-
/* @__PURE__ */
|
|
1307
|
-
/* @__PURE__ */
|
|
1541
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2 px-4 pb-2 pt-3.5", children: [
|
|
1542
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1543
|
+
/* @__PURE__ */ jsx6("span", { className: "cs-app-mark", "aria-hidden": "true" }),
|
|
1544
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate text-[14px] font-semibold tracking-[-0.01em]", children: "Coding sessions" })
|
|
1308
1545
|
] }),
|
|
1309
|
-
/* @__PURE__ */
|
|
1546
|
+
/* @__PURE__ */ jsx6(
|
|
1310
1547
|
"button",
|
|
1311
1548
|
{
|
|
1312
1549
|
type: "button",
|
|
@@ -1314,19 +1551,19 @@ function Sidebar(props) {
|
|
|
1314
1551
|
onClick: props.onCollapse,
|
|
1315
1552
|
"aria-label": "Hide the sidebar (\u2318B)",
|
|
1316
1553
|
title: "Hide sidebar \u2318B",
|
|
1317
|
-
children: /* @__PURE__ */
|
|
1554
|
+
children: /* @__PURE__ */ jsx6(SidebarIcon, { size: 15 })
|
|
1318
1555
|
}
|
|
1319
1556
|
)
|
|
1320
1557
|
] }),
|
|
1321
|
-
/* @__PURE__ */
|
|
1322
|
-
/* @__PURE__ */
|
|
1323
|
-
/* @__PURE__ */
|
|
1558
|
+
/* @__PURE__ */ jsxs6("div", { className: "space-y-1.5 px-3 pb-1", children: [
|
|
1559
|
+
/* @__PURE__ */ jsxs6(Button2, { className: "w-full justify-start gap-2", variant: "outline", size: "sm", onClick: props.onNew, children: [
|
|
1560
|
+
/* @__PURE__ */ jsx6(PlusIcon, { size: 15 }),
|
|
1324
1561
|
"New session",
|
|
1325
|
-
/* @__PURE__ */
|
|
1562
|
+
/* @__PURE__ */ jsx6("kbd", { className: "cs-kbd ml-auto", children: "\u2325\u2318N" })
|
|
1326
1563
|
] }),
|
|
1327
|
-
/* @__PURE__ */
|
|
1328
|
-
/* @__PURE__ */
|
|
1329
|
-
/* @__PURE__ */
|
|
1564
|
+
/* @__PURE__ */ jsxs6("div", { className: "cs-search", children: [
|
|
1565
|
+
/* @__PURE__ */ jsx6(SearchIcon, { size: 14, className: "cs-search__icon" }),
|
|
1566
|
+
/* @__PURE__ */ jsx6(
|
|
1330
1567
|
"input",
|
|
1331
1568
|
{
|
|
1332
1569
|
ref: props.searchRef,
|
|
@@ -1352,10 +1589,10 @@ function Sidebar(props) {
|
|
|
1352
1589
|
className: "cs-search__input"
|
|
1353
1590
|
}
|
|
1354
1591
|
),
|
|
1355
|
-
query ? /* @__PURE__ */
|
|
1592
|
+
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
1593
|
] })
|
|
1357
1594
|
] }),
|
|
1358
|
-
/* @__PURE__ */
|
|
1595
|
+
/* @__PURE__ */ jsx6("nav", { className: "min-h-0 flex-1 overflow-y-auto pb-3", children: searching ? searchBody : listBody }),
|
|
1359
1596
|
props.footer
|
|
1360
1597
|
]
|
|
1361
1598
|
}
|
|
@@ -1948,13 +2185,13 @@ function firstInvalidField(errors) {
|
|
|
1948
2185
|
}
|
|
1949
2186
|
|
|
1950
2187
|
// src/react/app.tsx
|
|
1951
|
-
import { Fragment as
|
|
2188
|
+
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1952
2189
|
function CodingSessionsProvider({ transport, children }) {
|
|
1953
|
-
const [client] =
|
|
1954
|
-
|
|
2190
|
+
const [client] = useState6(() => new CodingSessionsClient(transport));
|
|
2191
|
+
useEffect4(() => {
|
|
1955
2192
|
if (transport.status().state === "open") void client.refreshAll();
|
|
1956
2193
|
}, [client, transport]);
|
|
1957
|
-
return /* @__PURE__ */
|
|
2194
|
+
return /* @__PURE__ */ jsx7(CodingSessionsContext.Provider, { value: client, children });
|
|
1958
2195
|
}
|
|
1959
2196
|
function readHash() {
|
|
1960
2197
|
if (typeof location === "undefined") return { kind: "none" };
|
|
@@ -1977,8 +2214,8 @@ function readTheme() {
|
|
|
1977
2214
|
}
|
|
1978
2215
|
}
|
|
1979
2216
|
function useTheme() {
|
|
1980
|
-
const [choice, setChoice] =
|
|
1981
|
-
|
|
2217
|
+
const [choice, setChoice] = useState6(readTheme);
|
|
2218
|
+
useEffect4(() => {
|
|
1982
2219
|
const media = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-color-scheme: dark)") : null;
|
|
1983
2220
|
const apply = () => {
|
|
1984
2221
|
const dark = choice === "dark" || choice === "system" && media?.matches === true;
|
|
@@ -2008,8 +2245,8 @@ var RUN_LABEL = {
|
|
|
2008
2245
|
function RunPill({ run }) {
|
|
2009
2246
|
if (!run) return null;
|
|
2010
2247
|
const live = !isTerminalRunStatus(run.status);
|
|
2011
|
-
return /* @__PURE__ */
|
|
2012
|
-
live ? /* @__PURE__ */
|
|
2248
|
+
return /* @__PURE__ */ jsxs7("span", { className: cn5("cs-pill", `cs-pill--${run.status}`), children: [
|
|
2249
|
+
live ? /* @__PURE__ */ jsx7("span", { className: "cs-pill__dot", "aria-hidden": "true" }) : null,
|
|
2013
2250
|
RUN_LABEL[run.status]
|
|
2014
2251
|
] });
|
|
2015
2252
|
}
|
|
@@ -2017,17 +2254,17 @@ function ConnectionBanner() {
|
|
|
2017
2254
|
const { connection } = useCodingSessionsState();
|
|
2018
2255
|
if (connection.state === "open") return null;
|
|
2019
2256
|
const closed = connection.state === "closed";
|
|
2020
|
-
return /* @__PURE__ */
|
|
2257
|
+
return /* @__PURE__ */ jsxs7(
|
|
2021
2258
|
"div",
|
|
2022
2259
|
{
|
|
2023
2260
|
role: "status",
|
|
2024
|
-
className:
|
|
2261
|
+
className: cn5(
|
|
2025
2262
|
"flex items-center gap-2 border-b px-4 py-2 text-[13px]",
|
|
2026
2263
|
closed ? "border-destructive/30 bg-destructive/10 text-destructive" : "border-border bg-muted/60 text-muted-foreground"
|
|
2027
2264
|
),
|
|
2028
2265
|
children: [
|
|
2029
|
-
closed ? /* @__PURE__ */
|
|
2030
|
-
/* @__PURE__ */
|
|
2266
|
+
closed ? /* @__PURE__ */ jsx7(AlertIcon, { size: 15 }) : /* @__PURE__ */ jsx7(SpinnerIcon, { size: 14 }),
|
|
2267
|
+
/* @__PURE__ */ jsx7("span", { children: closed ? connection.reason : "Connecting to the coding sessions host\u2026" })
|
|
2031
2268
|
]
|
|
2032
2269
|
}
|
|
2033
2270
|
);
|
|
@@ -2037,22 +2274,22 @@ function ProvidersFooter(props) {
|
|
|
2037
2274
|
const client = useCodingSessionsClient();
|
|
2038
2275
|
const next = { system: "light", light: "dark", dark: "system" };
|
|
2039
2276
|
const themeLabel = { system: "Match system", light: "Light", dark: "Dark" };
|
|
2040
|
-
return /* @__PURE__ */
|
|
2041
|
-
/* @__PURE__ */
|
|
2277
|
+
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: [
|
|
2278
|
+
/* @__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
2279
|
"span",
|
|
2043
2280
|
{
|
|
2044
|
-
className:
|
|
2281
|
+
className: cn5("cs-provider-chip", p.ready ? "" : "cs-provider-chip--problem"),
|
|
2045
2282
|
title: p.problem ? `${p.problem} ${p.fix ?? ""}` : [binaryWords(p) ?? p.label, p.plan, newerWords(p)].filter(Boolean).join(" \xB7 "),
|
|
2046
2283
|
children: [
|
|
2047
|
-
/* @__PURE__ */
|
|
2284
|
+
/* @__PURE__ */ jsx7(ProviderMark, { provider: p.provider, size: 13 }),
|
|
2048
2285
|
p.label,
|
|
2049
|
-
p.lastProblem ? /* @__PURE__ */
|
|
2050
|
-
p.ready ? /* @__PURE__ */
|
|
2286
|
+
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,
|
|
2287
|
+
p.ready ? /* @__PURE__ */ jsx7(CheckIcon, { size: 12 }) : /* @__PURE__ */ jsx7(AlertIcon, { size: 12 })
|
|
2051
2288
|
]
|
|
2052
2289
|
},
|
|
2053
2290
|
p.provider
|
|
2054
2291
|
)) }),
|
|
2055
|
-
/* @__PURE__ */
|
|
2292
|
+
/* @__PURE__ */ jsx7(
|
|
2056
2293
|
"button",
|
|
2057
2294
|
{
|
|
2058
2295
|
type: "button",
|
|
@@ -2060,11 +2297,11 @@ function ProvidersFooter(props) {
|
|
|
2060
2297
|
onClick: () => void client.refreshProviders(),
|
|
2061
2298
|
"aria-label": "Check Claude Code and Codex again",
|
|
2062
2299
|
title: "Check again",
|
|
2063
|
-
children: state.providers.loading ? /* @__PURE__ */
|
|
2300
|
+
children: state.providers.loading ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx7(RefreshIcon, { size: 13 })
|
|
2064
2301
|
}
|
|
2065
2302
|
),
|
|
2066
2303
|
props.extra,
|
|
2067
|
-
/* @__PURE__ */
|
|
2304
|
+
/* @__PURE__ */ jsx7(
|
|
2068
2305
|
"button",
|
|
2069
2306
|
{
|
|
2070
2307
|
type: "button",
|
|
@@ -2072,14 +2309,14 @@ function ProvidersFooter(props) {
|
|
|
2072
2309
|
onClick: () => props.setTheme(next[props.theme]),
|
|
2073
2310
|
"aria-label": `Theme: ${themeLabel[props.theme]}. Switch to ${themeLabel[next[props.theme]]}.`,
|
|
2074
2311
|
title: `Theme: ${themeLabel[props.theme]}`,
|
|
2075
|
-
children: props.theme === "system" ? /* @__PURE__ */
|
|
2312
|
+
children: props.theme === "system" ? /* @__PURE__ */ jsx7(MonitorIcon, { size: 14 }) : props.theme === "light" ? /* @__PURE__ */ jsx7(SunIcon, { size: 14 }) : /* @__PURE__ */ jsx7(MoonIcon, { size: 14 })
|
|
2076
2313
|
}
|
|
2077
2314
|
)
|
|
2078
2315
|
] }) });
|
|
2079
2316
|
}
|
|
2080
2317
|
function useNotifier() {
|
|
2081
2318
|
const show = useContext3(ToastContext);
|
|
2082
|
-
return
|
|
2319
|
+
return useMemo4(
|
|
2083
2320
|
() => ({
|
|
2084
2321
|
notify(event) {
|
|
2085
2322
|
show(event.message);
|
|
@@ -2090,8 +2327,8 @@ function useNotifier() {
|
|
|
2090
2327
|
}
|
|
2091
2328
|
function useLiveElsewhere(provider, providerSessionId, initial = null) {
|
|
2092
2329
|
const client = useCodingSessionsClient();
|
|
2093
|
-
const [state, setState] =
|
|
2094
|
-
|
|
2330
|
+
const [state, setState] = useState6(initial);
|
|
2331
|
+
useEffect4(() => {
|
|
2095
2332
|
if (!provider || !providerSessionId) {
|
|
2096
2333
|
setState(null);
|
|
2097
2334
|
return;
|
|
@@ -2111,8 +2348,8 @@ function useLiveElsewhere(provider, providerSessionId, initial = null) {
|
|
|
2111
2348
|
}
|
|
2112
2349
|
function useSessionUsage(sessionId, lastRunKey) {
|
|
2113
2350
|
const client = useCodingSessionsClient();
|
|
2114
|
-
const [usage, setUsage] =
|
|
2115
|
-
|
|
2351
|
+
const [usage, setUsage] = useState6(null);
|
|
2352
|
+
useEffect4(() => {
|
|
2116
2353
|
let cancelled = false;
|
|
2117
2354
|
void client.transport.call("listRuns", sessionId).then((runs) => {
|
|
2118
2355
|
if (cancelled) return;
|
|
@@ -2133,18 +2370,18 @@ function useSessionUsage(sessionId, lastRunKey) {
|
|
|
2133
2370
|
return usage;
|
|
2134
2371
|
}
|
|
2135
2372
|
function HeaderMenu(props) {
|
|
2136
|
-
return /* @__PURE__ */
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2373
|
+
return /* @__PURE__ */ jsxs7(DropdownMenu2, { children: [
|
|
2374
|
+
/* @__PURE__ */ jsx7(DropdownMenuTrigger2, { 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 }) }) }),
|
|
2375
|
+
/* @__PURE__ */ jsx7(DropdownMenuContent2, { align: "end", className: "w-64", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ jsx7(ChatMenuItems, { entry: props.entry, variant: "dropdown", onRename: props.onRename }) })
|
|
2139
2376
|
] });
|
|
2140
2377
|
}
|
|
2141
2378
|
function HeaderTitle(props) {
|
|
2142
2379
|
const client = useCodingSessionsClient();
|
|
2143
2380
|
const show = useContext3(ToastContext);
|
|
2144
|
-
const [value, setValue] =
|
|
2145
|
-
|
|
2146
|
-
const inputRef =
|
|
2147
|
-
|
|
2381
|
+
const [value, setValue] = useState6(props.entry.title);
|
|
2382
|
+
useEffect4(() => setValue(props.entry.title), [props.entry.title, props.renaming]);
|
|
2383
|
+
const inputRef = useRef3(null);
|
|
2384
|
+
useEffect4(() => {
|
|
2148
2385
|
if (!props.renaming) return;
|
|
2149
2386
|
const timer = setTimeout(() => {
|
|
2150
2387
|
const input = inputRef.current;
|
|
@@ -2156,7 +2393,7 @@ function HeaderTitle(props) {
|
|
|
2156
2393
|
return () => clearTimeout(timer);
|
|
2157
2394
|
}, [props.renaming]);
|
|
2158
2395
|
if (!props.renaming) {
|
|
2159
|
-
return /* @__PURE__ */
|
|
2396
|
+
return /* @__PURE__ */ jsx7(
|
|
2160
2397
|
"h1",
|
|
2161
2398
|
{
|
|
2162
2399
|
className: "truncate text-[15px] font-semibold leading-5 tracking-[-0.01em]",
|
|
@@ -2173,7 +2410,7 @@ function HeaderTitle(props) {
|
|
|
2173
2410
|
const next = title === "" || title === props.entry.originalTitle ? null : title;
|
|
2174
2411
|
client.setPreference(props.entry.key, { title: next }).catch((error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`));
|
|
2175
2412
|
};
|
|
2176
|
-
return /* @__PURE__ */
|
|
2413
|
+
return /* @__PURE__ */ jsx7(
|
|
2177
2414
|
"input",
|
|
2178
2415
|
{
|
|
2179
2416
|
ref: inputRef,
|
|
@@ -2192,9 +2429,9 @@ function HeaderTitle(props) {
|
|
|
2192
2429
|
);
|
|
2193
2430
|
}
|
|
2194
2431
|
function LongChatNote(props) {
|
|
2195
|
-
return /* @__PURE__ */
|
|
2432
|
+
return /* @__PURE__ */ jsxs7("p", { className: "mx-auto mt-3 flex items-center gap-2 text-[12px] text-muted-foreground", children: [
|
|
2196
2433
|
"This chat is very long \u2014 showing its most recent part.",
|
|
2197
|
-
/* @__PURE__ */
|
|
2434
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "cs-link", onClick: props.onEarlier, disabled: props.loading, children: props.loading ? "Reading\u2026" : "Show earlier" })
|
|
2198
2435
|
] });
|
|
2199
2436
|
}
|
|
2200
2437
|
function binaryWords(p) {
|
|
@@ -2216,8 +2453,8 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2216
2453
|
const blocked = provider && (!provider.installed || !provider.loggedIn) ? provider : null;
|
|
2217
2454
|
const limited = !blocked && provider?.lastProblem ? provider : null;
|
|
2218
2455
|
const modelRefused = run?.status === "failed" && isModelUnavailable(run.error);
|
|
2219
|
-
const [stopping, setStopping] =
|
|
2220
|
-
const [renaming, setRenaming] =
|
|
2456
|
+
const [stopping, setStopping] = useState6(false);
|
|
2457
|
+
const [renaming, setRenaming] = useState6(false);
|
|
2221
2458
|
const elsewhere = useLiveElsewhere(
|
|
2222
2459
|
session.origin === "takeover" && !live ? session.provider : null,
|
|
2223
2460
|
session.providerSessionId
|
|
@@ -2226,7 +2463,7 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2226
2463
|
const messages = transcript.thread.getSnapshot().messages;
|
|
2227
2464
|
const files = useChangedFiles(messages);
|
|
2228
2465
|
const usage = useSessionUsage(session.id, `${run?.runId ?? ""}:${run?.status ?? ""}`);
|
|
2229
|
-
|
|
2466
|
+
useEffect4(() => {
|
|
2230
2467
|
if (!live) setStopping(false);
|
|
2231
2468
|
}, [live]);
|
|
2232
2469
|
const stop = async () => {
|
|
@@ -2239,16 +2476,16 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2239
2476
|
};
|
|
2240
2477
|
const usageWords = usage ? `${formatCount(usage.tokens, { style: "compact" })} tokens${usage.cost !== null ? ` \xB7 ${formatUsd(usage.cost)}` : ""}` : null;
|
|
2241
2478
|
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__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */
|
|
2245
|
-
/* @__PURE__ */
|
|
2246
|
-
/* @__PURE__ */
|
|
2247
|
-
/* @__PURE__ */
|
|
2248
|
-
/* @__PURE__ */
|
|
2249
|
-
/* @__PURE__ */
|
|
2250
|
-
/* @__PURE__ */
|
|
2251
|
-
/* @__PURE__ */
|
|
2479
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1", children: [
|
|
2480
|
+
/* @__PURE__ */ jsxs7("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
|
|
2481
|
+
/* @__PURE__ */ jsxs7("header", { className: "flex flex-wrap items-center gap-2 border-b border-border px-5 pt-2.5 pb-2.5", children: [
|
|
2482
|
+
/* @__PURE__ */ jsx7(ProviderMark, { provider: session.provider, size: 22 }),
|
|
2483
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1 overflow-hidden", children: [
|
|
2484
|
+
/* @__PURE__ */ jsx7(HeaderTitle, { entry, renaming, setRenaming }),
|
|
2485
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 items-center gap-1 text-[12px] leading-5 text-muted-foreground", children: [
|
|
2486
|
+
/* @__PURE__ */ jsx7("span", { className: "shrink-0", children: PROVIDER_LABEL[session.provider] }),
|
|
2487
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
2488
|
+
/* @__PURE__ */ jsx7(
|
|
2252
2489
|
ModelPicker,
|
|
2253
2490
|
{
|
|
2254
2491
|
status: provider,
|
|
@@ -2256,69 +2493,70 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2256
2493
|
onChange: setOptions
|
|
2257
2494
|
}
|
|
2258
2495
|
),
|
|
2259
|
-
/* @__PURE__ */
|
|
2260
|
-
/* @__PURE__ */
|
|
2261
|
-
/* @__PURE__ */
|
|
2262
|
-
usageWords ? /* @__PURE__ */
|
|
2496
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
2497
|
+
/* @__PURE__ */ jsx7(FolderIcon, { size: 12, className: "shrink-0" }),
|
|
2498
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-[4rem] truncate", title: session.cwd, children: prettyPath2(session.cwd) }),
|
|
2499
|
+
usageWords ? /* @__PURE__ */ jsxs7("span", { className: "shrink-0", title: usageTitle, children: [
|
|
2263
2500
|
"\xB7 ",
|
|
2264
2501
|
usageWords
|
|
2265
2502
|
] }) : null
|
|
2266
2503
|
] })
|
|
2267
2504
|
] }),
|
|
2268
|
-
/* @__PURE__ */
|
|
2505
|
+
session.agent ? /* @__PURE__ */ jsx7(AgentChip, { agent: session.agent }) : null,
|
|
2506
|
+
/* @__PURE__ */ jsxs7(
|
|
2269
2507
|
"button",
|
|
2270
2508
|
{
|
|
2271
2509
|
type: "button",
|
|
2272
|
-
className:
|
|
2510
|
+
className: cn5("cs-chip-button", changesOpen && "cs-chip-button--on"),
|
|
2273
2511
|
onClick: () => setChangesOpen(!changesOpen),
|
|
2274
2512
|
"aria-pressed": changesOpen,
|
|
2275
2513
|
title: "Files this chat changed",
|
|
2276
2514
|
children: [
|
|
2277
|
-
/* @__PURE__ */
|
|
2515
|
+
/* @__PURE__ */ jsx7(FileIcon, { size: 13 }),
|
|
2278
2516
|
files.length > 0 ? `${files.length} ${files.length === 1 ? "file" : "files"} changed` : "Changes"
|
|
2279
2517
|
]
|
|
2280
2518
|
}
|
|
2281
2519
|
),
|
|
2282
|
-
/* @__PURE__ */
|
|
2283
|
-
live ? /* @__PURE__ */
|
|
2284
|
-
stopping ? /* @__PURE__ */
|
|
2520
|
+
/* @__PURE__ */ jsx7(RunPill, { run }),
|
|
2521
|
+
live ? /* @__PURE__ */ jsxs7(Button3, { variant: "outline", size: "sm", onClick: () => void stop(), disabled: stopping, className: "gap-1.5", title: "Stop Esc", children: [
|
|
2522
|
+
stopping ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx7(StopIcon, { size: 13 }),
|
|
2285
2523
|
stopping ? "Stopping\u2026" : "Stop"
|
|
2286
2524
|
] }) : null,
|
|
2287
|
-
/* @__PURE__ */
|
|
2525
|
+
/* @__PURE__ */ jsx7(HeaderMenu, { entry, onRename: () => setRenaming(true) })
|
|
2288
2526
|
] }),
|
|
2289
|
-
/* @__PURE__ */
|
|
2290
|
-
/* @__PURE__ */
|
|
2291
|
-
/* @__PURE__ */
|
|
2527
|
+
/* @__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: [
|
|
2528
|
+
/* @__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: [
|
|
2529
|
+
/* @__PURE__ */ jsx7(SpinnerIcon, { size: 15 }),
|
|
2292
2530
|
" Loading the conversation\u2026"
|
|
2293
|
-
] }) : /* @__PURE__ */
|
|
2294
|
-
transcript.state.unavailable ? /* @__PURE__ */
|
|
2295
|
-
transcript.state.truncated ? /* @__PURE__ */
|
|
2531
|
+
] }) : /* @__PURE__ */ jsxs7("div", { className: "flex h-full flex-col", children: [
|
|
2532
|
+
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,
|
|
2533
|
+
transcript.state.truncated ? /* @__PURE__ */ jsx7(
|
|
2296
2534
|
LongChatNote,
|
|
2297
2535
|
{
|
|
2298
2536
|
loading: transcript.state.loadingEarlier === true,
|
|
2299
2537
|
onEarlier: () => void transcript.loadEarlier()
|
|
2300
2538
|
}
|
|
2301
2539
|
) : null,
|
|
2302
|
-
messages.length === 0 && !live ? /* @__PURE__ */
|
|
2540
|
+
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
2541
|
] }) }),
|
|
2304
|
-
/* @__PURE__ */
|
|
2305
|
-
limited ? /* @__PURE__ */
|
|
2306
|
-
/* @__PURE__ */
|
|
2307
|
-
/* @__PURE__ */
|
|
2542
|
+
/* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-[820px] px-4 pb-4", children: [
|
|
2543
|
+
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: [
|
|
2544
|
+
/* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2545
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2308
2546
|
limited.problem,
|
|
2309
2547
|
" ",
|
|
2310
2548
|
limited.fix
|
|
2311
2549
|
] })
|
|
2312
2550
|
] }) : null,
|
|
2313
|
-
modelRefused && !blocked ? /* @__PURE__ */
|
|
2551
|
+
modelRefused && !blocked ? /* @__PURE__ */ jsxs7(
|
|
2314
2552
|
"div",
|
|
2315
2553
|
{
|
|
2316
2554
|
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
2555
|
role: "alert",
|
|
2318
2556
|
children: [
|
|
2319
|
-
/* @__PURE__ */
|
|
2320
|
-
/* @__PURE__ */
|
|
2321
|
-
/* @__PURE__ */
|
|
2557
|
+
/* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "shrink-0 text-warning" }),
|
|
2558
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", title: run?.error ?? void 0, children: MODEL_UNAVAILABLE_LABEL }),
|
|
2559
|
+
/* @__PURE__ */ jsx7(
|
|
2322
2560
|
ModelPicker,
|
|
2323
2561
|
{
|
|
2324
2562
|
status: provider,
|
|
@@ -2329,31 +2567,31 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2329
2567
|
]
|
|
2330
2568
|
}
|
|
2331
2569
|
) : null,
|
|
2332
|
-
blocked ? /* @__PURE__ */
|
|
2333
|
-
/* @__PURE__ */
|
|
2334
|
-
/* @__PURE__ */
|
|
2570
|
+
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: [
|
|
2571
|
+
/* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2572
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2335
2573
|
blocked.problem,
|
|
2336
2574
|
" ",
|
|
2337
2575
|
blocked.fix
|
|
2338
2576
|
] })
|
|
2339
2577
|
] }) : null,
|
|
2340
|
-
/* @__PURE__ */
|
|
2341
|
-
/* @__PURE__ */
|
|
2342
|
-
/* @__PURE__ */
|
|
2343
|
-
/* @__PURE__ */
|
|
2578
|
+
/* @__PURE__ */ jsx7("div", { className: "cs-activity", role: "status", "aria-live": "polite", "data-idle": live ? void 0 : true, children: live ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
2579
|
+
/* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }),
|
|
2580
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate", children: run?.status === "starting" ? `Starting ${PROVIDER_LABEL[session.provider]}\u2026` : transcript.activity ?? "Thinking\u2026" }),
|
|
2581
|
+
/* @__PURE__ */ jsx7("span", { className: "ml-auto shrink-0 text-[11px] opacity-70", children: "Esc to stop" })
|
|
2344
2582
|
] }) : null }),
|
|
2345
|
-
elsewhere ? /* @__PURE__ */
|
|
2346
|
-
/* @__PURE__ */
|
|
2347
|
-
/* @__PURE__ */
|
|
2583
|
+
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: [
|
|
2584
|
+
/* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2585
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2348
2586
|
elsewhere.message,
|
|
2349
2587
|
" A message sent here would put a second agent on the same chat."
|
|
2350
2588
|
] })
|
|
2351
2589
|
] }) : null,
|
|
2352
|
-
session.queued.length > 0 ? /* @__PURE__ */
|
|
2353
|
-
/* @__PURE__ */
|
|
2354
|
-
/* @__PURE__ */
|
|
2590
|
+
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: [
|
|
2591
|
+
/* @__PURE__ */ jsx7("span", { className: "cs-queued__label", children: "Queued \xB7 sends when this run finishes" }),
|
|
2592
|
+
/* @__PURE__ */ jsx7("span", { className: "cs-queued__text", children: text })
|
|
2355
2593
|
] }, `${index}-${text.slice(0, 16)}`)) }) : null,
|
|
2356
|
-
/* @__PURE__ */
|
|
2594
|
+
/* @__PURE__ */ jsx7(
|
|
2357
2595
|
ChatComposer,
|
|
2358
2596
|
{
|
|
2359
2597
|
placeholder: `Message ${PROVIDER_LABEL[session.provider]}\u2026`,
|
|
@@ -2364,14 +2602,14 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2364
2602
|
] })
|
|
2365
2603
|
] }) })
|
|
2366
2604
|
] }),
|
|
2367
|
-
changesOpen ? /* @__PURE__ */
|
|
2605
|
+
changesOpen ? /* @__PURE__ */ jsx7(ChangesPanel, { files, cwd: session.cwd, truncated: transcript.state.truncated, onClose: () => setChangesOpen(false) }) : null
|
|
2368
2606
|
] });
|
|
2369
2607
|
}
|
|
2370
2608
|
function usePreviewThread(id, onSend) {
|
|
2371
|
-
const ref =
|
|
2372
|
-
const send =
|
|
2609
|
+
const ref = useRef3({ messages: [], listeners: /* @__PURE__ */ new Set() });
|
|
2610
|
+
const send = useRef3(onSend);
|
|
2373
2611
|
send.current = onSend;
|
|
2374
|
-
const thread =
|
|
2612
|
+
const thread = useMemo4(
|
|
2375
2613
|
() => createExternalThreadSource2({
|
|
2376
2614
|
getSnapshot: () => ({ messages: ref.current.messages, status: "idle", conversationId: id }),
|
|
2377
2615
|
subscribe: (listener) => {
|
|
@@ -2396,13 +2634,13 @@ function DiscoveredView(props) {
|
|
|
2396
2634
|
const state = useCodingSessionsState();
|
|
2397
2635
|
const show = useContext3(ToastContext);
|
|
2398
2636
|
const now = useMinuteClock();
|
|
2399
|
-
const [preview, setPreview] =
|
|
2400
|
-
const [busy, setBusy] =
|
|
2401
|
-
const [error, setError] =
|
|
2402
|
-
const [confirming, setConfirming] =
|
|
2403
|
-
const [renaming, setRenaming] =
|
|
2404
|
-
const [maxBytes, setMaxBytes] =
|
|
2405
|
-
const [readingEarlier, setReadingEarlier] =
|
|
2637
|
+
const [preview, setPreview] = useState6({ loading: true, messages: [], unavailable: null, truncated: false });
|
|
2638
|
+
const [busy, setBusy] = useState6(false);
|
|
2639
|
+
const [error, setError] = useState6(null);
|
|
2640
|
+
const [confirming, setConfirming] = useState6(false);
|
|
2641
|
+
const [renaming, setRenaming] = useState6(false);
|
|
2642
|
+
const [maxBytes, setMaxBytes] = useState6(void 0);
|
|
2643
|
+
const [readingEarlier, setReadingEarlier] = useState6(false);
|
|
2406
2644
|
const elsewhere = useLiveElsewhere(props.provider, props.id, props.session?.activeElsewhere ?? null);
|
|
2407
2645
|
const files = useChangedFiles(preview.messages);
|
|
2408
2646
|
const d = props.session;
|
|
@@ -2412,7 +2650,7 @@ function DiscoveredView(props) {
|
|
|
2412
2650
|
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
2651
|
)
|
|
2414
2652
|
);
|
|
2415
|
-
|
|
2653
|
+
useEffect4(() => {
|
|
2416
2654
|
let cancelled = false;
|
|
2417
2655
|
const read = (first) => client.readPreview(props.provider, props.id, maxBytes).then((next) => {
|
|
2418
2656
|
if (cancelled) return;
|
|
@@ -2451,26 +2689,26 @@ function DiscoveredView(props) {
|
|
|
2451
2689
|
setBusy(false);
|
|
2452
2690
|
}
|
|
2453
2691
|
};
|
|
2454
|
-
return /* @__PURE__ */
|
|
2455
|
-
/* @__PURE__ */
|
|
2456
|
-
/* @__PURE__ */
|
|
2457
|
-
/* @__PURE__ */
|
|
2458
|
-
/* @__PURE__ */
|
|
2459
|
-
/* @__PURE__ */
|
|
2460
|
-
/* @__PURE__ */
|
|
2461
|
-
/* @__PURE__ */
|
|
2462
|
-
d?.cwd ? /* @__PURE__ */
|
|
2463
|
-
/* @__PURE__ */
|
|
2464
|
-
/* @__PURE__ */
|
|
2465
|
-
/* @__PURE__ */
|
|
2692
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1", children: [
|
|
2693
|
+
/* @__PURE__ */ jsxs7("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
|
|
2694
|
+
/* @__PURE__ */ jsxs7("header", { className: "flex flex-wrap items-center gap-2 border-b border-border px-5 pt-2.5 pb-2.5", children: [
|
|
2695
|
+
/* @__PURE__ */ jsx7(ProviderMark, { provider: props.provider, size: 22 }),
|
|
2696
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
2697
|
+
/* @__PURE__ */ jsx7(HeaderTitle, { entry, renaming, setRenaming }),
|
|
2698
|
+
/* @__PURE__ */ jsxs7("p", { className: "flex items-center gap-1.5 truncate text-[12px] leading-4 text-muted-foreground", children: [
|
|
2699
|
+
/* @__PURE__ */ jsx7("span", { children: PROVIDER_LABEL[props.provider] }),
|
|
2700
|
+
d?.cwd ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
2701
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
2702
|
+
/* @__PURE__ */ jsx7(FolderIcon, { size: 12 }),
|
|
2703
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate", title: d.cwd, children: prettyPath2(d.cwd) })
|
|
2466
2704
|
] }) : null,
|
|
2467
|
-
d ? /* @__PURE__ */
|
|
2705
|
+
d ? /* @__PURE__ */ jsxs7("span", { children: [
|
|
2468
2706
|
"\xB7 last active ",
|
|
2469
2707
|
relativeTime(d.updatedAt, now)
|
|
2470
2708
|
] }) : null
|
|
2471
2709
|
] })
|
|
2472
2710
|
] }),
|
|
2473
|
-
files.length > 0 ? /* @__PURE__ */
|
|
2711
|
+
files.length > 0 ? /* @__PURE__ */ jsxs7(
|
|
2474
2712
|
"button",
|
|
2475
2713
|
{
|
|
2476
2714
|
type: "button",
|
|
@@ -2479,13 +2717,13 @@ function DiscoveredView(props) {
|
|
|
2479
2717
|
"aria-pressed": props.changesOpen,
|
|
2480
2718
|
title: "Files this chat changed",
|
|
2481
2719
|
children: [
|
|
2482
|
-
/* @__PURE__ */
|
|
2720
|
+
/* @__PURE__ */ jsx7(FileIcon, { size: 13 }),
|
|
2483
2721
|
`${files.length} ${files.length === 1 ? "file" : "files"} changed`
|
|
2484
2722
|
]
|
|
2485
2723
|
}
|
|
2486
2724
|
) : null,
|
|
2487
|
-
d?.cwd ? /* @__PURE__ */
|
|
2488
|
-
|
|
2725
|
+
d?.cwd ? /* @__PURE__ */ jsxs7(
|
|
2726
|
+
Button3,
|
|
2489
2727
|
{
|
|
2490
2728
|
size: "sm",
|
|
2491
2729
|
variant: elsewhere ? "outline" : "default",
|
|
@@ -2494,44 +2732,44 @@ function DiscoveredView(props) {
|
|
|
2494
2732
|
className: "gap-1.5",
|
|
2495
2733
|
title: elsewhere ? elsewhere.message : void 0,
|
|
2496
2734
|
children: [
|
|
2497
|
-
busy ? /* @__PURE__ */
|
|
2735
|
+
busy ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : elsewhere ? /* @__PURE__ */ jsx7(AlertIcon, { size: 14, className: "text-warning" }) : /* @__PURE__ */ jsx7(HandoffIcon, { size: 14 }),
|
|
2498
2736
|
elsewhere ? "Take over anyway\u2026" : "Take over"
|
|
2499
2737
|
]
|
|
2500
2738
|
}
|
|
2501
2739
|
) : null,
|
|
2502
|
-
d ? /* @__PURE__ */
|
|
2740
|
+
d ? /* @__PURE__ */ jsx7(HeaderMenu, { entry, onRename: () => setRenaming(true) }) : null
|
|
2503
2741
|
] }),
|
|
2504
|
-
elsewhere ? /* @__PURE__ */
|
|
2505
|
-
/* @__PURE__ */
|
|
2506
|
-
/* @__PURE__ */
|
|
2507
|
-
/* @__PURE__ */
|
|
2742
|
+
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: [
|
|
2743
|
+
/* @__PURE__ */ jsx7(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2744
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2745
|
+
/* @__PURE__ */ jsx7("span", { className: "font-medium", children: elsewhere.message }),
|
|
2508
2746
|
" 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
2747
|
] })
|
|
2510
2748
|
] }) : null,
|
|
2511
|
-
/* @__PURE__ */
|
|
2512
|
-
/* @__PURE__ */
|
|
2513
|
-
/* @__PURE__ */
|
|
2749
|
+
/* @__PURE__ */ jsx7(Dialog, { open: confirming, onOpenChange: setConfirming, children: /* @__PURE__ */ jsxs7(DialogContent, { className: "max-w-[460px]", children: [
|
|
2750
|
+
/* @__PURE__ */ jsxs7(DialogHeader, { children: [
|
|
2751
|
+
/* @__PURE__ */ jsxs7(DialogTitle, { children: [
|
|
2514
2752
|
"This chat is running right now in ",
|
|
2515
2753
|
PROVIDER_LABEL[props.provider]
|
|
2516
2754
|
] }),
|
|
2517
|
-
/* @__PURE__ */
|
|
2755
|
+
/* @__PURE__ */ jsxs7(DialogDescription, { children: [
|
|
2518
2756
|
elsewhere?.message,
|
|
2519
2757
|
" If you take it over, two agents will work in the same conversation at once and may overwrite each other's changes."
|
|
2520
2758
|
] })
|
|
2521
2759
|
] }),
|
|
2522
|
-
/* @__PURE__ */
|
|
2523
|
-
/* @__PURE__ */
|
|
2524
|
-
/* @__PURE__ */
|
|
2760
|
+
/* @__PURE__ */ jsxs7(DialogFooter, { children: [
|
|
2761
|
+
/* @__PURE__ */ jsx7(Button3, { variant: "ghost", onClick: () => setConfirming(false), children: "Cancel" }),
|
|
2762
|
+
/* @__PURE__ */ jsx7(Button3, { variant: "destructive", onClick: () => void takeover(), children: "Take over anyway" })
|
|
2525
2763
|
] })
|
|
2526
2764
|
] }) }),
|
|
2527
|
-
error ? /* @__PURE__ */
|
|
2528
|
-
d && !d.cwd ? /* @__PURE__ */
|
|
2529
|
-
/* @__PURE__ */
|
|
2530
|
-
preview.loading ? /* @__PURE__ */
|
|
2531
|
-
/* @__PURE__ */
|
|
2765
|
+
error ? /* @__PURE__ */ jsx7("p", { className: "border-b border-destructive/30 bg-destructive/10 px-5 py-2 text-[13px] text-destructive", children: error }) : null,
|
|
2766
|
+
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,
|
|
2767
|
+
/* @__PURE__ */ jsxs7("div", { className: "mx-chat flex min-h-0 flex-1 flex-col", children: [
|
|
2768
|
+
preview.loading ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
|
|
2769
|
+
/* @__PURE__ */ jsx7(SpinnerIcon, { size: 15 }),
|
|
2532
2770
|
" Reading this chat\u2026"
|
|
2533
|
-
] }) : preview.unavailable ? /* @__PURE__ */
|
|
2534
|
-
preview.truncated ? /* @__PURE__ */
|
|
2771
|
+
] }) : 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: [
|
|
2772
|
+
preview.truncated ? /* @__PURE__ */ jsx7(
|
|
2535
2773
|
LongChatNote,
|
|
2536
2774
|
{
|
|
2537
2775
|
loading: readingEarlier,
|
|
@@ -2541,14 +2779,14 @@ function DiscoveredView(props) {
|
|
|
2541
2779
|
}
|
|
2542
2780
|
}
|
|
2543
2781
|
) : null,
|
|
2544
|
-
/* @__PURE__ */
|
|
2782
|
+
/* @__PURE__ */ jsx7(ChatMessageList, { className: "min-h-0 flex-1", label: "Chat preview" })
|
|
2545
2783
|
] }),
|
|
2546
|
-
d?.cwd ? /* @__PURE__ */
|
|
2784
|
+
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
2785
|
"This chat was started in ",
|
|
2548
2786
|
PROVIDER_LABEL[props.provider],
|
|
2549
2787
|
".",
|
|
2550
2788
|
" ",
|
|
2551
|
-
/* @__PURE__ */
|
|
2789
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "font-medium text-foreground underline-offset-4 hover:underline", onClick: requestTakeover, children: "Take it over" }),
|
|
2552
2790
|
" ",
|
|
2553
2791
|
"to continue it here \u2014 it stays in your ",
|
|
2554
2792
|
PROVIDER_LABEL[props.provider],
|
|
@@ -2556,70 +2794,73 @@ function DiscoveredView(props) {
|
|
|
2556
2794
|
] }) : null
|
|
2557
2795
|
] })
|
|
2558
2796
|
] }),
|
|
2559
|
-
props.changesOpen && files.length > 0 ? /* @__PURE__ */
|
|
2797
|
+
props.changesOpen && files.length > 0 ? /* @__PURE__ */ jsx7(ChangesPanel, { files, cwd: d?.cwd ?? null, truncated: preview.truncated, onClose: () => props.setChangesOpen(false) }) : null
|
|
2560
2798
|
] });
|
|
2561
2799
|
}
|
|
2562
2800
|
function ProviderCard(props) {
|
|
2563
2801
|
const ready = props.status.ready;
|
|
2564
|
-
return /* @__PURE__ */
|
|
2802
|
+
return /* @__PURE__ */ jsxs7(
|
|
2565
2803
|
"button",
|
|
2566
2804
|
{
|
|
2567
2805
|
type: "button",
|
|
2568
2806
|
onClick: props.onSelect,
|
|
2569
2807
|
"aria-pressed": props.selected,
|
|
2570
|
-
className:
|
|
2808
|
+
className: cn5(
|
|
2571
2809
|
"flex flex-1 flex-col gap-1.5 rounded-xl border px-3.5 py-3 text-left transition-colors",
|
|
2572
2810
|
props.selected ? "border-primary bg-primary/5 ring-1 ring-primary" : "border-border hover:bg-accent/50"
|
|
2573
2811
|
),
|
|
2574
2812
|
children: [
|
|
2575
|
-
/* @__PURE__ */
|
|
2576
|
-
/* @__PURE__ */
|
|
2577
|
-
/* @__PURE__ */
|
|
2813
|
+
/* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2", children: [
|
|
2814
|
+
/* @__PURE__ */ jsx7(ProviderMark, { provider: props.status.provider, size: 18 }),
|
|
2815
|
+
/* @__PURE__ */ jsx7("span", { className: "text-[13.5px] font-semibold", children: props.status.label })
|
|
2578
2816
|
] }),
|
|
2579
|
-
ready ? /* @__PURE__ */
|
|
2580
|
-
/* @__PURE__ */
|
|
2817
|
+
ready ? /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-1 text-[12px] text-success", children: [
|
|
2818
|
+
/* @__PURE__ */ jsx7(CheckIcon, { size: 13 }),
|
|
2581
2819
|
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__ */
|
|
2583
|
-
/* @__PURE__ */
|
|
2820
|
+
] }) : /* @__PURE__ */ jsxs7("span", { className: "flex items-start gap-1 text-[12px] leading-4 text-warning", children: [
|
|
2821
|
+
/* @__PURE__ */ jsx7(AlertIcon, { size: 13, className: "mt-px shrink-0" }),
|
|
2584
2822
|
props.status.problem
|
|
2585
2823
|
] }),
|
|
2586
|
-
props.status.quota.filter((w) => w.usedPercent !== null).length > 0 ? /* @__PURE__ */
|
|
2824
|
+
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
2825
|
]
|
|
2588
2826
|
}
|
|
2589
2827
|
);
|
|
2590
2828
|
}
|
|
2591
2829
|
function FieldError({ id, children }) {
|
|
2592
|
-
return /* @__PURE__ */
|
|
2593
|
-
/* @__PURE__ */
|
|
2594
|
-
/* @__PURE__ */
|
|
2830
|
+
return /* @__PURE__ */ jsxs7("p", { id, role: "alert", className: "flex items-start gap-1.5 text-[12.5px] leading-5 text-destructive", children: [
|
|
2831
|
+
/* @__PURE__ */ jsx7(AlertIcon, { size: 14, className: "mt-0.5 shrink-0" }),
|
|
2832
|
+
/* @__PURE__ */ jsx7("span", { children })
|
|
2595
2833
|
] });
|
|
2596
2834
|
}
|
|
2597
2835
|
function NewSessionDialog(props) {
|
|
2598
2836
|
const client = useCodingSessionsClient();
|
|
2599
2837
|
const state = useCodingSessionsState();
|
|
2600
2838
|
const now = useMinuteClock();
|
|
2601
|
-
const [provider, setProvider] =
|
|
2602
|
-
const [folder, setFolder] =
|
|
2603
|
-
const [choice, setChoice] =
|
|
2604
|
-
const [prompt, setPrompt] =
|
|
2605
|
-
const [errors, setErrors] =
|
|
2606
|
-
const [problem, setProblem] =
|
|
2607
|
-
const [starting, setStarting] =
|
|
2608
|
-
const [creating, setCreating] =
|
|
2609
|
-
const
|
|
2610
|
-
const
|
|
2611
|
-
const
|
|
2612
|
-
|
|
2839
|
+
const [provider, setProvider] = useState6("claude");
|
|
2840
|
+
const [folder, setFolder] = useState6("");
|
|
2841
|
+
const [choice, setChoice] = useState6({ model: null, effort: null });
|
|
2842
|
+
const [prompt, setPrompt] = useState6("");
|
|
2843
|
+
const [errors, setErrors] = useState6({});
|
|
2844
|
+
const [problem, setProblem] = useState6(null);
|
|
2845
|
+
const [starting, setStarting] = useState6(false);
|
|
2846
|
+
const [creating, setCreating] = useState6(false);
|
|
2847
|
+
const [agent, setAgent] = useState6(null);
|
|
2848
|
+
const [agentDetails, setAgentDetails] = useState6(null);
|
|
2849
|
+
const [agentMissing, setAgentMissing] = useState6(null);
|
|
2850
|
+
const promptRef = useRef3(null);
|
|
2851
|
+
const folderRef = useRef3(null);
|
|
2852
|
+
const agentRef = useRef3(null);
|
|
2853
|
+
useEffect4(() => {
|
|
2613
2854
|
if (!props.open) return;
|
|
2614
2855
|
setProblem(null);
|
|
2615
2856
|
setErrors({});
|
|
2616
2857
|
void client.refreshProviders();
|
|
2617
2858
|
void client.refreshFolders();
|
|
2618
2859
|
}, [props.open, client]);
|
|
2619
|
-
|
|
2860
|
+
useEffect4(() => {
|
|
2620
2861
|
if (!folder && state.folders.data[0]?.exists) setFolder(state.folders.data[0].path);
|
|
2621
2862
|
}, [state.folders.data, folder]);
|
|
2622
|
-
|
|
2863
|
+
useEffect4(() => {
|
|
2623
2864
|
const ready = state.providers.data.filter((p) => p.ready);
|
|
2624
2865
|
const current = state.providers.data.find((p) => p.provider === provider);
|
|
2625
2866
|
if (current && !current.ready && ready[0]) setProvider(ready[0].provider);
|
|
@@ -2645,9 +2886,22 @@ function NewSessionDialog(props) {
|
|
|
2645
2886
|
focusField(first);
|
|
2646
2887
|
return;
|
|
2647
2888
|
}
|
|
2889
|
+
const missing = missingRequiredVariable(agentDetails, agent);
|
|
2890
|
+
setAgentMissing(missing);
|
|
2891
|
+
if (missing) {
|
|
2892
|
+
document.getElementById(`cs-agent-var-${missing}`)?.focus();
|
|
2893
|
+
return;
|
|
2894
|
+
}
|
|
2648
2895
|
setStarting(true);
|
|
2649
2896
|
try {
|
|
2650
|
-
const result = await client.start({
|
|
2897
|
+
const result = await client.start({
|
|
2898
|
+
provider,
|
|
2899
|
+
cwd: folder.trim(),
|
|
2900
|
+
prompt,
|
|
2901
|
+
model: choice.model,
|
|
2902
|
+
effort: choice.effort,
|
|
2903
|
+
...agent ? { agent } : {}
|
|
2904
|
+
});
|
|
2651
2905
|
setPrompt("");
|
|
2652
2906
|
props.onStarted(result.session.id);
|
|
2653
2907
|
} catch (error) {
|
|
@@ -2683,16 +2937,16 @@ function NewSessionDialog(props) {
|
|
|
2683
2937
|
if (field === "folder") delete next.createFolder;
|
|
2684
2938
|
return next;
|
|
2685
2939
|
});
|
|
2686
|
-
return /* @__PURE__ */
|
|
2687
|
-
/* @__PURE__ */
|
|
2688
|
-
/* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2940
|
+
return /* @__PURE__ */ jsx7(Dialog, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ jsxs7(DialogContent, { className: "max-w-[560px]", children: [
|
|
2941
|
+
/* @__PURE__ */ jsxs7(DialogHeader, { children: [
|
|
2942
|
+
/* @__PURE__ */ jsx7(DialogTitle, { children: "New coding session" }),
|
|
2943
|
+
/* @__PURE__ */ jsxs7(DialogDescription, { children: [
|
|
2690
2944
|
"Runs on your own ",
|
|
2691
2945
|
provider === "claude" ? "Claude" : "ChatGPT",
|
|
2692
2946
|
" sign-in, in a folder on this computer."
|
|
2693
2947
|
] })
|
|
2694
2948
|
] }),
|
|
2695
|
-
/* @__PURE__ */
|
|
2949
|
+
/* @__PURE__ */ jsxs7(
|
|
2696
2950
|
"form",
|
|
2697
2951
|
{
|
|
2698
2952
|
noValidate: true,
|
|
@@ -2702,13 +2956,13 @@ function NewSessionDialog(props) {
|
|
|
2702
2956
|
},
|
|
2703
2957
|
className: "flex min-h-0 flex-col",
|
|
2704
2958
|
children: [
|
|
2705
|
-
/* @__PURE__ */
|
|
2706
|
-
/* @__PURE__ */
|
|
2707
|
-
/* @__PURE__ */
|
|
2708
|
-
state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2710
|
-
/* @__PURE__ */
|
|
2711
|
-
] }) : state.providers.error ? /* @__PURE__ */
|
|
2959
|
+
/* @__PURE__ */ jsxs7("div", { className: "cs-dialog-body space-y-5 py-1 pr-1", children: [
|
|
2960
|
+
/* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", ref: agentRef, children: [
|
|
2961
|
+
/* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Agent" }),
|
|
2962
|
+
state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ jsxs7("div", { className: "flex gap-2", children: [
|
|
2963
|
+
/* @__PURE__ */ jsx7("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" }),
|
|
2964
|
+
/* @__PURE__ */ jsx7("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" })
|
|
2965
|
+
] }) : 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
2966
|
ProviderCard,
|
|
2713
2967
|
{
|
|
2714
2968
|
status: p,
|
|
@@ -2721,14 +2975,31 @@ function NewSessionDialog(props) {
|
|
|
2721
2975
|
},
|
|
2722
2976
|
p.provider
|
|
2723
2977
|
)) }),
|
|
2724
|
-
errors.agent ? /* @__PURE__ */
|
|
2978
|
+
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
2979
|
selected.fix,
|
|
2726
2980
|
selected.installed && selected.loggedIn ? " You can still try \u2014 the run will say if it's still blocked." : ""
|
|
2727
2981
|
] }) : null
|
|
2728
2982
|
] }),
|
|
2729
|
-
/* @__PURE__ */
|
|
2730
|
-
/* @__PURE__ */
|
|
2731
|
-
|
|
2983
|
+
/* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
|
|
2984
|
+
/* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "AI Matrx agent" }),
|
|
2985
|
+
/* @__PURE__ */ jsx7(
|
|
2986
|
+
AgentField,
|
|
2987
|
+
{
|
|
2988
|
+
transport: client.transport,
|
|
2989
|
+
open: props.open,
|
|
2990
|
+
value: agent,
|
|
2991
|
+
onChange: (next) => {
|
|
2992
|
+
setAgent(next);
|
|
2993
|
+
setAgentMissing(null);
|
|
2994
|
+
},
|
|
2995
|
+
missing: agentMissing,
|
|
2996
|
+
onDetails: setAgentDetails
|
|
2997
|
+
}
|
|
2998
|
+
)
|
|
2999
|
+
] }),
|
|
3000
|
+
/* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
|
|
3001
|
+
/* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Folder" }),
|
|
3002
|
+
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
3003
|
"button",
|
|
2733
3004
|
{
|
|
2734
3005
|
type: "button",
|
|
@@ -2738,21 +3009,21 @@ function NewSessionDialog(props) {
|
|
|
2738
3009
|
},
|
|
2739
3010
|
disabled: !f.exists,
|
|
2740
3011
|
title: f.exists ? f.path : `${f.path} no longer exists`,
|
|
2741
|
-
className:
|
|
3012
|
+
className: cn5(
|
|
2742
3013
|
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[12.5px]",
|
|
2743
3014
|
folder === f.path ? "bg-accent text-accent-foreground" : "hover:bg-accent/50",
|
|
2744
3015
|
!f.exists && "opacity-50"
|
|
2745
3016
|
),
|
|
2746
3017
|
children: [
|
|
2747
|
-
/* @__PURE__ */
|
|
2748
|
-
/* @__PURE__ */
|
|
2749
|
-
/* @__PURE__ */
|
|
3018
|
+
/* @__PURE__ */ jsx7(FolderIcon, { size: 14, className: "shrink-0 text-muted-foreground" }),
|
|
3019
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", children: prettyPath2(f.path) }),
|
|
3020
|
+
/* @__PURE__ */ jsx7("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: f.exists ? relativeTime(f.lastUsedAt, now) : "missing" })
|
|
2750
3021
|
]
|
|
2751
3022
|
},
|
|
2752
3023
|
f.path
|
|
2753
|
-
)) }) : state.folders.loading ? /* @__PURE__ */
|
|
2754
|
-
/* @__PURE__ */
|
|
2755
|
-
|
|
3024
|
+
)) }) : state.folders.loading ? /* @__PURE__ */ jsx7("div", { className: "cs-skeleton h-10 rounded-lg" }) : null,
|
|
3025
|
+
/* @__PURE__ */ jsx7(
|
|
3026
|
+
Input2,
|
|
2756
3027
|
{
|
|
2757
3028
|
ref: folderRef,
|
|
2758
3029
|
value: folder,
|
|
@@ -2767,18 +3038,18 @@ function NewSessionDialog(props) {
|
|
|
2767
3038
|
spellCheck: false
|
|
2768
3039
|
}
|
|
2769
3040
|
),
|
|
2770
|
-
errors.folder ? /* @__PURE__ */
|
|
2771
|
-
/* @__PURE__ */
|
|
2772
|
-
errors.createFolder ? /* @__PURE__ */
|
|
2773
|
-
creating ? /* @__PURE__ */
|
|
3041
|
+
errors.folder ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1", children: [
|
|
3042
|
+
/* @__PURE__ */ jsx7(FieldError, { id: "cs-err-folder", children: errors.folder }),
|
|
3043
|
+
errors.createFolder ? /* @__PURE__ */ jsxs7(Button3, { type: "button", size: "sm", variant: "outline", onClick: () => void createFolder(), disabled: creating, className: "gap-1.5", children: [
|
|
3044
|
+
creating ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ jsx7(FolderIcon, { size: 13 }),
|
|
2774
3045
|
"Create this folder"
|
|
2775
3046
|
] }) : null
|
|
2776
3047
|
] }) : null
|
|
2777
3048
|
] }),
|
|
2778
|
-
/* @__PURE__ */
|
|
2779
|
-
/* @__PURE__ */
|
|
2780
|
-
/* @__PURE__ */
|
|
2781
|
-
|
|
3049
|
+
/* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
|
|
3050
|
+
/* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "What should it do?" }),
|
|
3051
|
+
/* @__PURE__ */ jsx7(
|
|
3052
|
+
Textarea2,
|
|
2782
3053
|
{
|
|
2783
3054
|
ref: promptRef,
|
|
2784
3055
|
value: prompt,
|
|
@@ -2799,25 +3070,25 @@ function NewSessionDialog(props) {
|
|
|
2799
3070
|
"aria-describedby": errors.prompt ? "cs-err-prompt" : void 0
|
|
2800
3071
|
}
|
|
2801
3072
|
),
|
|
2802
|
-
errors.prompt ? /* @__PURE__ */
|
|
3073
|
+
errors.prompt ? /* @__PURE__ */ jsx7(FieldError, { id: "cs-err-prompt", children: errors.prompt }) : null
|
|
2803
3074
|
] }),
|
|
2804
|
-
/* @__PURE__ */
|
|
2805
|
-
/* @__PURE__ */
|
|
2806
|
-
/* @__PURE__ */
|
|
2807
|
-
/* @__PURE__ */
|
|
3075
|
+
/* @__PURE__ */ jsxs7("fieldset", { className: "space-y-2", children: [
|
|
3076
|
+
/* @__PURE__ */ jsx7("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Model and thinking effort" }),
|
|
3077
|
+
/* @__PURE__ */ jsx7(ModelPicker, { status: selected, value: choice, onChange: setChoice, appearance: "field" }),
|
|
3078
|
+
/* @__PURE__ */ jsxs7("p", { className: "text-[11.5px] leading-4 text-muted-foreground", children: [
|
|
2808
3079
|
"Default is ",
|
|
2809
3080
|
defaultModelWords(selected),
|
|
2810
3081
|
". You can change it later from the chat's header."
|
|
2811
3082
|
] })
|
|
2812
3083
|
] }),
|
|
2813
|
-
problem ? /* @__PURE__ */
|
|
3084
|
+
problem ? /* @__PURE__ */ jsx7(FieldError, { id: "cs-err-start", children: problem }) : null
|
|
2814
3085
|
] }),
|
|
2815
|
-
/* @__PURE__ */
|
|
2816
|
-
/* @__PURE__ */
|
|
2817
|
-
/* @__PURE__ */
|
|
2818
|
-
starting ? /* @__PURE__ */
|
|
3086
|
+
/* @__PURE__ */ jsxs7(DialogFooter, { className: "pt-4", children: [
|
|
3087
|
+
/* @__PURE__ */ jsx7(Button3, { type: "button", variant: "ghost", onClick: () => props.onOpenChange(false), children: "Cancel" }),
|
|
3088
|
+
/* @__PURE__ */ jsxs7(Button3, { type: "submit", disabled: starting, className: "gap-1.5", children: [
|
|
3089
|
+
starting ? /* @__PURE__ */ jsx7(SpinnerIcon, { size: 14 }) : null,
|
|
2819
3090
|
starting ? "Starting\u2026" : "Start session",
|
|
2820
|
-
!starting ? /* @__PURE__ */
|
|
3091
|
+
!starting ? /* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2318\u21B5" }) : null
|
|
2821
3092
|
] })
|
|
2822
3093
|
] })
|
|
2823
3094
|
]
|
|
@@ -2827,34 +3098,34 @@ function NewSessionDialog(props) {
|
|
|
2827
3098
|
}
|
|
2828
3099
|
function Home({ onNew }) {
|
|
2829
3100
|
const state = useCodingSessionsState();
|
|
2830
|
-
return /* @__PURE__ */
|
|
2831
|
-
/* @__PURE__ */
|
|
2832
|
-
/* @__PURE__ */
|
|
2833
|
-
/* @__PURE__ */
|
|
2834
|
-
/* @__PURE__ */
|
|
2835
|
-
/* @__PURE__ */
|
|
3101
|
+
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: [
|
|
3102
|
+
/* @__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 }) }),
|
|
3103
|
+
/* @__PURE__ */ jsx7("h1", { className: "text-[15px] font-semibold leading-5 tracking-[-0.01em]", children: "Drive Claude Code and Codex from here" }),
|
|
3104
|
+
/* @__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." }),
|
|
3105
|
+
/* @__PURE__ */ jsxs7(Button3, { className: "mt-5 gap-1.5", onClick: onNew, children: [
|
|
3106
|
+
/* @__PURE__ */ jsx7(PlusIcon, { size: 15 }),
|
|
2836
3107
|
"New session"
|
|
2837
3108
|
] }),
|
|
2838
|
-
/* @__PURE__ */
|
|
2839
|
-
/* @__PURE__ */
|
|
3109
|
+
/* @__PURE__ */ jsxs7("p", { className: "mt-3 text-[12px] text-muted-foreground", children: [
|
|
3110
|
+
/* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2325\u2318N" }),
|
|
2840
3111
|
" new session \xB7 ",
|
|
2841
|
-
/* @__PURE__ */
|
|
3112
|
+
/* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2318K" }),
|
|
2842
3113
|
" search your chats \xB7",
|
|
2843
3114
|
" ",
|
|
2844
|
-
/* @__PURE__ */
|
|
3115
|
+
/* @__PURE__ */ jsx7("kbd", { className: "cs-kbd", children: "\u2318/" }),
|
|
2845
3116
|
" all shortcuts"
|
|
2846
3117
|
] }),
|
|
2847
|
-
/* @__PURE__ */
|
|
2848
|
-
/* @__PURE__ */
|
|
2849
|
-
/* @__PURE__ */
|
|
2850
|
-
/* @__PURE__ */
|
|
2851
|
-
p.ready ? /* @__PURE__ */
|
|
3118
|
+
/* @__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: [
|
|
3119
|
+
/* @__PURE__ */ jsx7(ProviderMark, { provider: p.provider, size: 16 }),
|
|
3120
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1 text-[12.5px] leading-5", children: [
|
|
3121
|
+
/* @__PURE__ */ jsx7("span", { className: "font-medium", children: p.label }),
|
|
3122
|
+
p.ready ? /* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
|
|
2852
3123
|
" ",
|
|
2853
3124
|
"\u2014 ready",
|
|
2854
3125
|
p.plan ? ` on your ${p.plan} plan` : "",
|
|
2855
3126
|
p.billing === "api" ? " (API key, billed per use)" : ""
|
|
2856
3127
|
] }) : null,
|
|
2857
|
-
p.installed && p.version ? /* @__PURE__ */
|
|
3128
|
+
p.installed && p.version ? /* @__PURE__ */ jsxs7(
|
|
2858
3129
|
"span",
|
|
2859
3130
|
{
|
|
2860
3131
|
className: "block text-[11.5px] text-muted-foreground",
|
|
@@ -2865,20 +3136,20 @@ function Home({ onNew }) {
|
|
|
2865
3136
|
]
|
|
2866
3137
|
}
|
|
2867
3138
|
) : null,
|
|
2868
|
-
p.ready ? null : /* @__PURE__ */
|
|
3139
|
+
p.ready ? null : /* @__PURE__ */ jsxs7("span", { className: "block text-muted-foreground", children: [
|
|
2869
3140
|
p.problem,
|
|
2870
3141
|
" ",
|
|
2871
3142
|
p.fix
|
|
2872
3143
|
] })
|
|
2873
3144
|
] }),
|
|
2874
|
-
p.ready ? /* @__PURE__ */
|
|
3145
|
+
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
3146
|
] }, p.provider)) })
|
|
2876
3147
|
] }) });
|
|
2877
3148
|
}
|
|
2878
3149
|
function useToast() {
|
|
2879
|
-
const [text, setText] =
|
|
2880
|
-
const timer =
|
|
2881
|
-
|
|
3150
|
+
const [text, setText] = useState6(null);
|
|
3151
|
+
const timer = useRef3(null);
|
|
3152
|
+
useEffect4(() => () => {
|
|
2882
3153
|
if (timer.current) clearTimeout(timer.current);
|
|
2883
3154
|
}, []);
|
|
2884
3155
|
const show = useCallback2((next) => {
|
|
@@ -2890,7 +3161,7 @@ function useToast() {
|
|
|
2890
3161
|
}
|
|
2891
3162
|
function Toast({ text }) {
|
|
2892
3163
|
if (!text) return null;
|
|
2893
|
-
return /* @__PURE__ */
|
|
3164
|
+
return /* @__PURE__ */ jsx7("div", { role: "status", className: "cs-toast", children: text });
|
|
2894
3165
|
}
|
|
2895
3166
|
var SIDEBAR_DEFAULT = 300;
|
|
2896
3167
|
var SIDEBAR_MIN = 220;
|
|
@@ -2899,7 +3170,7 @@ function clampWidth(n) {
|
|
|
2899
3170
|
return Math.round(Math.min(SIDEBAR_MAX, Math.max(SIDEBAR_MIN, n)));
|
|
2900
3171
|
}
|
|
2901
3172
|
function useSidebarLayout() {
|
|
2902
|
-
const [width, setWidthState] =
|
|
3173
|
+
const [width, setWidthState] = useState6(() => {
|
|
2903
3174
|
try {
|
|
2904
3175
|
const n = Number(localStorage.getItem("coding-sessions.sidebar-width"));
|
|
2905
3176
|
return Number.isFinite(n) && n > 0 ? clampWidth(n) : SIDEBAR_DEFAULT;
|
|
@@ -2907,7 +3178,7 @@ function useSidebarLayout() {
|
|
|
2907
3178
|
return SIDEBAR_DEFAULT;
|
|
2908
3179
|
}
|
|
2909
3180
|
});
|
|
2910
|
-
const [collapsed, setCollapsedState] =
|
|
3181
|
+
const [collapsed, setCollapsedState] = useState6(() => {
|
|
2911
3182
|
try {
|
|
2912
3183
|
return localStorage.getItem("coding-sessions.sidebar-collapsed") === "1";
|
|
2913
3184
|
} catch {
|
|
@@ -2932,8 +3203,8 @@ function useSidebarLayout() {
|
|
|
2932
3203
|
return { width, setWidth, collapsed, setCollapsed };
|
|
2933
3204
|
}
|
|
2934
3205
|
function Resizer(props) {
|
|
2935
|
-
const [dragging, setDragging] =
|
|
2936
|
-
return /* @__PURE__ */
|
|
3206
|
+
const [dragging, setDragging] = useState6(false);
|
|
3207
|
+
return /* @__PURE__ */ jsx7("div", { className: cn5("cs-resizer", dragging && "cs-resizer--dragging"), children: /* @__PURE__ */ jsx7(
|
|
2937
3208
|
"button",
|
|
2938
3209
|
{
|
|
2939
3210
|
type: "button",
|
|
@@ -2981,24 +3252,24 @@ var SHORTCUTS = [
|
|
|
2981
3252
|
{ keys: "\u2318/", what: "These shortcuts" }
|
|
2982
3253
|
];
|
|
2983
3254
|
function ShortcutsDialog(props) {
|
|
2984
|
-
return /* @__PURE__ */
|
|
2985
|
-
/* @__PURE__ */
|
|
2986
|
-
/* @__PURE__ */
|
|
2987
|
-
/* @__PURE__ */
|
|
3255
|
+
return /* @__PURE__ */ jsx7(Dialog, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ jsxs7(DialogContent, { className: "max-w-[420px]", children: [
|
|
3256
|
+
/* @__PURE__ */ jsxs7(DialogHeader, { children: [
|
|
3257
|
+
/* @__PURE__ */ jsx7(DialogTitle, { children: "Keyboard shortcuts" }),
|
|
3258
|
+
/* @__PURE__ */ jsx7(DialogDescription, { children: "Ctrl works in place of \u2318 on Windows and Linux." })
|
|
2988
3259
|
] }),
|
|
2989
|
-
/* @__PURE__ */
|
|
2990
|
-
/* @__PURE__ */
|
|
2991
|
-
/* @__PURE__ */
|
|
3260
|
+
/* @__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: [
|
|
3261
|
+
/* @__PURE__ */ jsx7("dt", { className: "text-muted-foreground", children: s.what }),
|
|
3262
|
+
/* @__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
3263
|
] }, s.keys)) })
|
|
2993
3264
|
] }) });
|
|
2994
3265
|
}
|
|
2995
3266
|
var BASE_TITLE = "Coding sessions";
|
|
2996
3267
|
function useRunFinishedNotices(openSessionId, show) {
|
|
2997
3268
|
const client = useCodingSessionsClient();
|
|
2998
|
-
const unseen =
|
|
2999
|
-
const openRef =
|
|
3269
|
+
const unseen = useRef3(0);
|
|
3270
|
+
const openRef = useRef3(openSessionId);
|
|
3000
3271
|
openRef.current = openSessionId;
|
|
3001
|
-
|
|
3272
|
+
useEffect4(() => {
|
|
3002
3273
|
const reset = () => {
|
|
3003
3274
|
if (document.visibilityState === "visible") {
|
|
3004
3275
|
unseen.current = 0;
|
|
@@ -3033,9 +3304,9 @@ function useRunFinishedNotices(openSessionId, show) {
|
|
|
3033
3304
|
}
|
|
3034
3305
|
function NotifyToggle() {
|
|
3035
3306
|
const supported = typeof Notification !== "undefined";
|
|
3036
|
-
const [permission, setPermission] =
|
|
3307
|
+
const [permission, setPermission] = useState6(supported ? Notification.permission : "denied");
|
|
3037
3308
|
if (!supported || permission === "granted") return null;
|
|
3038
|
-
return /* @__PURE__ */
|
|
3309
|
+
return /* @__PURE__ */ jsx7(
|
|
3039
3310
|
"button",
|
|
3040
3311
|
{
|
|
3041
3312
|
type: "button",
|
|
@@ -3044,7 +3315,7 @@ function NotifyToggle() {
|
|
|
3044
3315
|
"aria-label": permission === "denied" ? "Notifications are blocked for this page in your browser's site settings" : "Notify me when a run finishes",
|
|
3045
3316
|
title: permission === "denied" ? "Notifications are blocked in your browser's site settings" : "Notify me when a run finishes",
|
|
3046
3317
|
disabled: permission === "denied",
|
|
3047
|
-
children: /* @__PURE__ */
|
|
3318
|
+
children: /* @__PURE__ */ jsx7(BellIcon, { size: 14 })
|
|
3048
3319
|
}
|
|
3049
3320
|
);
|
|
3050
3321
|
}
|
|
@@ -3056,20 +3327,20 @@ function isTyping(target) {
|
|
|
3056
3327
|
function Shell() {
|
|
3057
3328
|
const client = useCodingSessionsClient();
|
|
3058
3329
|
const state = useCodingSessionsState();
|
|
3059
|
-
const [selection, setSelection] =
|
|
3060
|
-
const [newOpen, setNewOpen] =
|
|
3061
|
-
const [shortcutsOpen, setShortcutsOpen] =
|
|
3062
|
-
const [changesOpen, setChangesOpen] =
|
|
3063
|
-
const [found, setFound] =
|
|
3330
|
+
const [selection, setSelection] = useState6(readHash);
|
|
3331
|
+
const [newOpen, setNewOpen] = useState6(false);
|
|
3332
|
+
const [shortcutsOpen, setShortcutsOpen] = useState6(false);
|
|
3333
|
+
const [changesOpen, setChangesOpen] = useState6(false);
|
|
3334
|
+
const [found, setFound] = useState6({});
|
|
3064
3335
|
const [theme, setTheme] = useTheme();
|
|
3065
3336
|
const [toast, showToast] = useToast();
|
|
3066
3337
|
const layout = useSidebarLayout();
|
|
3067
|
-
const searchRef =
|
|
3338
|
+
const searchRef = useRef3(null);
|
|
3068
3339
|
const select = useCallback2((next) => {
|
|
3069
3340
|
setSelection(next);
|
|
3070
3341
|
writeHash(next);
|
|
3071
3342
|
}, []);
|
|
3072
|
-
|
|
3343
|
+
useEffect4(() => {
|
|
3073
3344
|
const onHash = () => setSelection(readHash());
|
|
3074
3345
|
window.addEventListener("hashchange", onHash);
|
|
3075
3346
|
return () => window.removeEventListener("hashchange", onHash);
|
|
@@ -3079,14 +3350,14 @@ function Shell() {
|
|
|
3079
3350
|
const discovered = selection.kind === "discovered" ? state.discovered.data.find((d) => d.providerSessionId === selection.id) ?? found[`${selection.provider}:${selection.id}`] ?? null : null;
|
|
3080
3351
|
const run = session ? state.runs[session.id] : void 0;
|
|
3081
3352
|
const live = run !== void 0 && !isTerminalRunStatus(run.status);
|
|
3082
|
-
const order =
|
|
3353
|
+
const order = useMemo4(() => {
|
|
3083
3354
|
const known = new Set(state.sessions.data.map((s) => s.providerSessionId).filter(Boolean));
|
|
3084
3355
|
return [
|
|
3085
3356
|
...state.sessions.data.map((s) => ({ kind: "session", id: s.id })),
|
|
3086
3357
|
...state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => ({ kind: "discovered", provider: d.provider, id: d.providerSessionId }))
|
|
3087
3358
|
];
|
|
3088
3359
|
}, [state.sessions.data, state.discovered.data]);
|
|
3089
|
-
|
|
3360
|
+
useEffect4(() => {
|
|
3090
3361
|
const onKey = (e) => {
|
|
3091
3362
|
const mod = e.metaKey || e.ctrlKey;
|
|
3092
3363
|
const key = e.key.toLowerCase();
|
|
@@ -3142,12 +3413,12 @@ function Shell() {
|
|
|
3142
3413
|
}, [client, layout, live, run, order, selection, select, showToast]);
|
|
3143
3414
|
let main;
|
|
3144
3415
|
if (selection.kind === "session") {
|
|
3145
|
-
main = session ? /* @__PURE__ */
|
|
3146
|
-
/* @__PURE__ */
|
|
3416
|
+
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: [
|
|
3417
|
+
/* @__PURE__ */ jsx7(SpinnerIcon, { size: 15 }),
|
|
3147
3418
|
" Loading\u2026"
|
|
3148
|
-
] }) : /* @__PURE__ */
|
|
3419
|
+
] }) : /* @__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
3420
|
} else if (selection.kind === "discovered") {
|
|
3150
|
-
main = /* @__PURE__ */
|
|
3421
|
+
main = /* @__PURE__ */ jsx7(
|
|
3151
3422
|
DiscoveredView,
|
|
3152
3423
|
{
|
|
3153
3424
|
session: discovered,
|
|
@@ -3160,13 +3431,13 @@ function Shell() {
|
|
|
3160
3431
|
`${selection.provider}:${selection.id}`
|
|
3161
3432
|
);
|
|
3162
3433
|
} else {
|
|
3163
|
-
main = /* @__PURE__ */
|
|
3434
|
+
main = /* @__PURE__ */ jsx7(Home, { onNew: () => setNewOpen(true) });
|
|
3164
3435
|
}
|
|
3165
|
-
return /* @__PURE__ */
|
|
3166
|
-
/* @__PURE__ */
|
|
3167
|
-
/* @__PURE__ */
|
|
3168
|
-
layout.collapsed ? /* @__PURE__ */
|
|
3169
|
-
/* @__PURE__ */
|
|
3436
|
+
return /* @__PURE__ */ jsx7(ToastContext.Provider, { value: showToast, children: /* @__PURE__ */ jsxs7("div", { className: "cs-app flex h-full flex-col bg-background text-foreground", children: [
|
|
3437
|
+
/* @__PURE__ */ jsx7(ConnectionBanner, {}),
|
|
3438
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-h-0 flex-1", children: [
|
|
3439
|
+
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: [
|
|
3440
|
+
/* @__PURE__ */ jsx7(
|
|
3170
3441
|
"button",
|
|
3171
3442
|
{
|
|
3172
3443
|
type: "button",
|
|
@@ -3174,10 +3445,10 @@ function Shell() {
|
|
|
3174
3445
|
onClick: () => layout.setCollapsed(false),
|
|
3175
3446
|
"aria-label": "Show the sidebar (\u2318B)",
|
|
3176
3447
|
title: "Show sidebar \u2318B",
|
|
3177
|
-
children: /* @__PURE__ */
|
|
3448
|
+
children: /* @__PURE__ */ jsx7(SidebarIcon, { size: 15 })
|
|
3178
3449
|
}
|
|
3179
3450
|
),
|
|
3180
|
-
/* @__PURE__ */
|
|
3451
|
+
/* @__PURE__ */ jsx7(
|
|
3181
3452
|
"button",
|
|
3182
3453
|
{
|
|
3183
3454
|
type: "button",
|
|
@@ -3185,11 +3456,11 @@ function Shell() {
|
|
|
3185
3456
|
onClick: () => setNewOpen(true),
|
|
3186
3457
|
"aria-label": "New session",
|
|
3187
3458
|
title: "New session \u2325\u2318N",
|
|
3188
|
-
children: /* @__PURE__ */
|
|
3459
|
+
children: /* @__PURE__ */ jsx7(PlusIcon, { size: 15 })
|
|
3189
3460
|
}
|
|
3190
3461
|
)
|
|
3191
|
-
] }) : /* @__PURE__ */
|
|
3192
|
-
/* @__PURE__ */
|
|
3462
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
3463
|
+
/* @__PURE__ */ jsx7(
|
|
3193
3464
|
Sidebar,
|
|
3194
3465
|
{
|
|
3195
3466
|
selection,
|
|
@@ -3199,14 +3470,14 @@ function Shell() {
|
|
|
3199
3470
|
width: layout.width,
|
|
3200
3471
|
searchRef,
|
|
3201
3472
|
onFound: (d) => setFound((f) => ({ ...f, [`${d.provider}:${d.providerSessionId}`]: d })),
|
|
3202
|
-
footer: /* @__PURE__ */
|
|
3473
|
+
footer: /* @__PURE__ */ jsx7(
|
|
3203
3474
|
ProvidersFooter,
|
|
3204
3475
|
{
|
|
3205
3476
|
theme,
|
|
3206
3477
|
setTheme,
|
|
3207
|
-
extra: /* @__PURE__ */
|
|
3208
|
-
/* @__PURE__ */
|
|
3209
|
-
/* @__PURE__ */
|
|
3478
|
+
extra: /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
3479
|
+
/* @__PURE__ */ jsx7(NotifyToggle, {}),
|
|
3480
|
+
/* @__PURE__ */ jsx7(
|
|
3210
3481
|
"button",
|
|
3211
3482
|
{
|
|
3212
3483
|
type: "button",
|
|
@@ -3214,7 +3485,7 @@ function Shell() {
|
|
|
3214
3485
|
onClick: () => setShortcutsOpen(true),
|
|
3215
3486
|
"aria-label": "Keyboard shortcuts (\u2318/)",
|
|
3216
3487
|
title: "Keyboard shortcuts \u2318/",
|
|
3217
|
-
children: /* @__PURE__ */
|
|
3488
|
+
children: /* @__PURE__ */ jsx7(KeyboardIcon, { size: 14 })
|
|
3218
3489
|
}
|
|
3219
3490
|
)
|
|
3220
3491
|
] })
|
|
@@ -3222,11 +3493,11 @@ function Shell() {
|
|
|
3222
3493
|
)
|
|
3223
3494
|
}
|
|
3224
3495
|
),
|
|
3225
|
-
/* @__PURE__ */
|
|
3496
|
+
/* @__PURE__ */ jsx7(Resizer, { width: layout.width, setWidth: layout.setWidth })
|
|
3226
3497
|
] }),
|
|
3227
|
-
/* @__PURE__ */
|
|
3498
|
+
/* @__PURE__ */ jsx7("main", { className: "flex min-w-0 flex-1", children: main })
|
|
3228
3499
|
] }),
|
|
3229
|
-
/* @__PURE__ */
|
|
3500
|
+
/* @__PURE__ */ jsx7(
|
|
3230
3501
|
NewSessionDialog,
|
|
3231
3502
|
{
|
|
3232
3503
|
open: newOpen,
|
|
@@ -3237,12 +3508,12 @@ function Shell() {
|
|
|
3237
3508
|
}
|
|
3238
3509
|
}
|
|
3239
3510
|
),
|
|
3240
|
-
/* @__PURE__ */
|
|
3241
|
-
/* @__PURE__ */
|
|
3511
|
+
/* @__PURE__ */ jsx7(ShortcutsDialog, { open: shortcutsOpen, onOpenChange: setShortcutsOpen }),
|
|
3512
|
+
/* @__PURE__ */ jsx7(Toast, { text: toast })
|
|
3242
3513
|
] }) });
|
|
3243
3514
|
}
|
|
3244
3515
|
function CodingSessionsApp({ transport }) {
|
|
3245
|
-
return /* @__PURE__ */
|
|
3516
|
+
return /* @__PURE__ */ jsx7(CodingSessionsProvider, { transport, children: /* @__PURE__ */ jsx7(Shell, {}) });
|
|
3246
3517
|
}
|
|
3247
3518
|
export {
|
|
3248
3519
|
CodingSessionsApp,
|