@ai-matrx/coding-sessions 0.1.81 → 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 +24 -0
- package/dist/engine/index.cjs +724 -139
- 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 +717 -132
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/worker.js +14 -2
- package/dist/engine/worker.js.map +1 -1
- package/dist/{index-RYOb-YZT.d.cts → index-DEPwyr2j.d.cts} +148 -0
- package/dist/{index-RYOb-YZT.d.ts → index-DEPwyr2j.d.ts} +148 -0
- package/dist/index.cjs +21 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +105 -1
- package/dist/index.d.ts +105 -1
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +722 -410
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +105 -7
- package/dist/react/index.d.ts +105 -7
- package/dist/react/index.js +730 -405
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +792 -155
- 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 +783 -146
- 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-B3Ic2ziA.js +0 -69
- package/dist/ui/assets/index-BAkpc01s.css +0 -2
package/dist/react/index.cjs
CHANGED
|
@@ -34,10 +34,10 @@ __export(react_exports, {
|
|
|
34
34
|
module.exports = __toCommonJS(react_exports);
|
|
35
35
|
|
|
36
36
|
// src/react/app.tsx
|
|
37
|
-
var
|
|
38
|
-
var
|
|
37
|
+
var import_react8 = require("react");
|
|
38
|
+
var import_react9 = require("@ai-matrx/chat/react");
|
|
39
39
|
var import_external_store2 = require("@ai-matrx/chat/external-store");
|
|
40
|
-
var
|
|
40
|
+
var import_design_system6 = require("@ai-matrx/design-system");
|
|
41
41
|
var import_format3 = require("@ai-matrx/kit/format");
|
|
42
42
|
|
|
43
43
|
// src/types.ts
|
|
@@ -60,6 +60,21 @@ function formatUntil(until) {
|
|
|
60
60
|
if (Number.isNaN(ms)) return until;
|
|
61
61
|
return new Date(ms).toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
62
62
|
}
|
|
63
|
+
var MODEL_UNAVAILABLE = [
|
|
64
|
+
/model is not supported when using codex/i,
|
|
65
|
+
/\bmodel[\s:'"`][^.\n]{0,80}\b(?:not supported|does not exist|not available|not found)\b/i,
|
|
66
|
+
/\bmodel_not_found\b/i,
|
|
67
|
+
/issue with the selected model/i,
|
|
68
|
+
/may not exist or you may not have access to it/i
|
|
69
|
+
];
|
|
70
|
+
var MODEL_UNAVAILABLE_LABEL = "Model not available on this account";
|
|
71
|
+
function isModelUnavailable(text) {
|
|
72
|
+
const trimmed = (text ?? "").trim();
|
|
73
|
+
return trimmed !== "" && MODEL_UNAVAILABLE.some((re) => re.test(trimmed));
|
|
74
|
+
}
|
|
75
|
+
function runErrorLabel(text) {
|
|
76
|
+
return isModelUnavailable(text) ? MODEL_UNAVAILABLE_LABEL : text;
|
|
77
|
+
}
|
|
63
78
|
|
|
64
79
|
// src/tool-labels.ts
|
|
65
80
|
var BUILTIN = {
|
|
@@ -471,14 +486,20 @@ var SpinnerIcon = ({ size = 16, className }) => /* @__PURE__ */ (0, import_jsx_r
|
|
|
471
486
|
]
|
|
472
487
|
}
|
|
473
488
|
);
|
|
474
|
-
|
|
489
|
+
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";
|
|
490
|
+
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";
|
|
491
|
+
function ProviderMark({ provider, size = 16 }) {
|
|
475
492
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
476
|
-
"
|
|
493
|
+
"svg",
|
|
477
494
|
{
|
|
478
495
|
className: `cs-provider-mark cs-provider-mark--${provider}`,
|
|
479
|
-
|
|
496
|
+
width: size,
|
|
497
|
+
height: size,
|
|
498
|
+
viewBox: "0 0 24 24",
|
|
499
|
+
fill: "currentColor",
|
|
480
500
|
"aria-hidden": "true",
|
|
481
|
-
|
|
501
|
+
"data-provider-mark": provider,
|
|
502
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: provider === "claude" ? CLAUDE_MARK : OPENAI_MARK })
|
|
482
503
|
}
|
|
483
504
|
);
|
|
484
505
|
}
|
|
@@ -875,10 +896,217 @@ function ModelPicker(props) {
|
|
|
875
896
|
] });
|
|
876
897
|
}
|
|
877
898
|
|
|
878
|
-
// src/react/
|
|
899
|
+
// src/react/agent-field.tsx
|
|
879
900
|
var import_react5 = require("react");
|
|
901
|
+
var import_agents = require("@ai-matrx/agents");
|
|
902
|
+
var import_catalog = require("@ai-matrx/agents/catalog");
|
|
903
|
+
var import_react6 = require("@ai-matrx/agents/catalog/react");
|
|
904
|
+
var import_context = require("@ai-matrx/agents/context");
|
|
880
905
|
var import_design_system4 = require("@ai-matrx/design-system");
|
|
881
906
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
907
|
+
var SIGNED_OUT_AGENTS = "Sign in to AI Matrx to use your agents";
|
|
908
|
+
var LATEST = "latest";
|
|
909
|
+
function bridgedClient(transport) {
|
|
910
|
+
const call = (request) => {
|
|
911
|
+
const run = () => transport.call("agentCatalogRpc", request).then((result) => ({
|
|
912
|
+
data: result.data,
|
|
913
|
+
error: result.error ? {
|
|
914
|
+
message: result.error.message,
|
|
915
|
+
...result.error.code ? { code: result.error.code } : {},
|
|
916
|
+
details: result.error.details ?? null,
|
|
917
|
+
hint: result.error.hint ?? null
|
|
918
|
+
} : null,
|
|
919
|
+
count: result.count ?? null
|
|
920
|
+
}));
|
|
921
|
+
return {
|
|
922
|
+
then: (onOk, onErr) => run().then(onOk, onErr),
|
|
923
|
+
range: (from, to) => call({ ...request, range: [from, to] }),
|
|
924
|
+
order: (column, options) => call({ ...request, order: { column, ascending: options?.ascending !== false } })
|
|
925
|
+
};
|
|
926
|
+
};
|
|
927
|
+
return {
|
|
928
|
+
rpc: (fn, args, options) => call({ fn, ...args ? { args } : {}, ...options?.count ? { count: options.count } : {} })
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
function useAgentAccess(transport, open) {
|
|
932
|
+
const [access, setAccess] = (0, import_react5.useState)(null);
|
|
933
|
+
(0, import_react5.useEffect)(() => {
|
|
934
|
+
if (!open) return;
|
|
935
|
+
let alive = true;
|
|
936
|
+
transport.call("agentAccess").then((next) => alive && setAccess(next)).catch(() => alive && setAccess({ signedIn: false, userId: null, organizationId: null, configured: false }));
|
|
937
|
+
return () => {
|
|
938
|
+
alive = false;
|
|
939
|
+
};
|
|
940
|
+
}, [transport, open]);
|
|
941
|
+
return access;
|
|
942
|
+
}
|
|
943
|
+
function useCatalog(transport, userId, onError) {
|
|
944
|
+
const report = (0, import_react5.useRef)(onError);
|
|
945
|
+
report.current = onError;
|
|
946
|
+
return (0, import_react5.useMemo)(() => {
|
|
947
|
+
if (!userId) return null;
|
|
948
|
+
return (0, import_catalog.createAgentCatalog)({
|
|
949
|
+
client: bridgedClient(transport),
|
|
950
|
+
identity: { requireUserId: () => userId, getUserId: () => userId },
|
|
951
|
+
catalogId: `coding-sessions:${userId}`,
|
|
952
|
+
// A failed catalogue read shows at the field, never only in the console.
|
|
953
|
+
errorSink: (event) => {
|
|
954
|
+
console.error(`[coding-sessions] agent catalogue: ${event.code}: ${event.message}`);
|
|
955
|
+
if (event.code === "list_read_failed") report.current("Couldn't load your agents. Reopen to retry.");
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
}, [transport, userId]);
|
|
959
|
+
}
|
|
960
|
+
function asRunInputVariables(defs) {
|
|
961
|
+
return defs.flatMap((def) => typeof def.name === "string" ? [def] : []);
|
|
962
|
+
}
|
|
963
|
+
function AgentField(props) {
|
|
964
|
+
const access = useAgentAccess(props.transport, props.open);
|
|
965
|
+
const [details, setDetails] = (0, import_react5.useState)(null);
|
|
966
|
+
const [problem, setProblem] = (0, import_react5.useState)(null);
|
|
967
|
+
const catalog = useCatalog(props.transport, access?.signedIn ? access.userId : null, setProblem);
|
|
968
|
+
const agentId = props.value?.agentId ?? null;
|
|
969
|
+
(0, import_react5.useEffect)(() => {
|
|
970
|
+
setDetails(null);
|
|
971
|
+
setProblem(null);
|
|
972
|
+
if (!agentId) return;
|
|
973
|
+
let alive = true;
|
|
974
|
+
props.transport.call("agentDetails", agentId).then((next) => alive && setDetails(next)).catch((error) => alive && setProblem(error instanceof Error ? error.message : String(error)));
|
|
975
|
+
return () => {
|
|
976
|
+
alive = false;
|
|
977
|
+
};
|
|
978
|
+
}, [agentId, props.transport]);
|
|
979
|
+
const { onDetails } = props;
|
|
980
|
+
(0, import_react5.useEffect)(() => {
|
|
981
|
+
onDetails?.(details);
|
|
982
|
+
}, [details, onDetails]);
|
|
983
|
+
const inputs = (0, import_react5.useMemo)(() => (0, import_agents.deriveRunInputs)(asRunInputVariables(details?.variables ?? []), import_context.humanizeContextKey), [details]);
|
|
984
|
+
if (access === null) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cs-skeleton h-9 rounded-lg" });
|
|
985
|
+
if (!access.signedIn || !catalog) {
|
|
986
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[12.5px] text-muted-foreground", children: SIGNED_OUT_AGENTS });
|
|
987
|
+
}
|
|
988
|
+
const setVariable = (name, value) => {
|
|
989
|
+
if (!props.value) return;
|
|
990
|
+
props.onChange({ ...props.value, variables: { ...props.value.variables ?? {}, [name]: value } });
|
|
991
|
+
};
|
|
992
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "space-y-3", children: [
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react6.AgentCatalogProvider, { catalog, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
995
|
+
import_react6.AgentListDropdown,
|
|
996
|
+
{
|
|
997
|
+
consumerId: "coding-sessions-new-session",
|
|
998
|
+
activeAgentId: agentId,
|
|
999
|
+
label: details?.name ?? (agentId ? "Loading\u2026" : "None"),
|
|
1000
|
+
onSelect: (id) => props.onChange({ agentId: id, versionId: null, variables: {} })
|
|
1001
|
+
}
|
|
1002
|
+
) }) }),
|
|
1003
|
+
agentId ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.Button, { type: "button", size: "sm", variant: "ghost", onClick: () => props.onChange(null), children: "Remove" }) : null
|
|
1004
|
+
] }),
|
|
1005
|
+
problem ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[12px] text-destructive", children: problem }) : null,
|
|
1006
|
+
details && props.value ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1007
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1008
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-[72px] shrink-0 text-[12px] text-muted-foreground", children: "Version" }),
|
|
1009
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1010
|
+
import_design_system4.Select,
|
|
1011
|
+
{
|
|
1012
|
+
value: props.value.versionId ?? LATEST,
|
|
1013
|
+
onValueChange: (next) => props.value && props.onChange({ ...props.value, versionId: next === LATEST ? null : next }),
|
|
1014
|
+
children: [
|
|
1015
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.SelectTrigger, { className: "h-8 w-[200px] text-[12.5px]", "aria-label": "Agent version", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.SelectValue, {}) }),
|
|
1016
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system4.SelectContent, { children: [
|
|
1017
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.SelectItem, { value: LATEST, children: details.latestVersionNumber !== null ? `Latest (v${details.latestVersionNumber})` : "Latest" }),
|
|
1018
|
+
details.versions.map((v) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system4.SelectItem, { value: v.id, children: [
|
|
1019
|
+
"v",
|
|
1020
|
+
v.versionNumber
|
|
1021
|
+
] }, v.id))
|
|
1022
|
+
] })
|
|
1023
|
+
]
|
|
1024
|
+
}
|
|
1025
|
+
)
|
|
1026
|
+
] }),
|
|
1027
|
+
inputs.map((input) => {
|
|
1028
|
+
const raw = props.value?.variables?.[input.name];
|
|
1029
|
+
const value = typeof raw === "string" ? raw : "";
|
|
1030
|
+
const id = `cs-agent-var-${input.name}`;
|
|
1031
|
+
const invalid = props.missing === input.name;
|
|
1032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "space-y-1", children: [
|
|
1033
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { htmlFor: id, className: "text-[12px] font-medium", children: [
|
|
1034
|
+
input.label,
|
|
1035
|
+
input.required ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-muted-foreground", children: " \xB7 required" }) : null
|
|
1036
|
+
] }),
|
|
1037
|
+
input.options && input.options.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system4.Select, { value, onValueChange: (next) => setVariable(input.name, next), children: [
|
|
1038
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.SelectTrigger, { id, className: "h-8 text-[12.5px]", "aria-invalid": invalid || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.SelectValue, { placeholder: "Choose\u2026" }) }),
|
|
1039
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.SelectContent, { children: input.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.SelectItem, { value: option, children: option }, option)) })
|
|
1040
|
+
] }) : input.variable.customComponent?.type === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1041
|
+
import_design_system4.Textarea,
|
|
1042
|
+
{
|
|
1043
|
+
id,
|
|
1044
|
+
rows: 2,
|
|
1045
|
+
value,
|
|
1046
|
+
onChange: (e) => setVariable(input.name, e.target.value),
|
|
1047
|
+
placeholder: input.hint ?? "",
|
|
1048
|
+
"aria-invalid": invalid || void 0
|
|
1049
|
+
}
|
|
1050
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1051
|
+
import_design_system4.Input,
|
|
1052
|
+
{
|
|
1053
|
+
id,
|
|
1054
|
+
value,
|
|
1055
|
+
onChange: (e) => setVariable(input.name, e.target.value),
|
|
1056
|
+
placeholder: input.hint ?? "",
|
|
1057
|
+
"aria-invalid": invalid || void 0
|
|
1058
|
+
}
|
|
1059
|
+
),
|
|
1060
|
+
invalid ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[12px] text-destructive", children: "Fill this in to use the agent" }) : null
|
|
1061
|
+
] }, input.name);
|
|
1062
|
+
})
|
|
1063
|
+
] }) : null
|
|
1064
|
+
] });
|
|
1065
|
+
}
|
|
1066
|
+
function missingRequiredVariable(details, selection) {
|
|
1067
|
+
if (!details || !selection) return null;
|
|
1068
|
+
for (const input of (0, import_agents.deriveRunInputs)(asRunInputVariables(details.variables), import_context.humanizeContextKey)) {
|
|
1069
|
+
if (!input.required) continue;
|
|
1070
|
+
const value = selection.variables?.[input.name];
|
|
1071
|
+
if (typeof value !== "string" || !value.trim()) return input.name;
|
|
1072
|
+
}
|
|
1073
|
+
return null;
|
|
1074
|
+
}
|
|
1075
|
+
var PART_LABEL = {
|
|
1076
|
+
instructions: "Instructions",
|
|
1077
|
+
skills: "Skills",
|
|
1078
|
+
tools: "Tools"
|
|
1079
|
+
};
|
|
1080
|
+
function AgentChip({ agent }) {
|
|
1081
|
+
const parts = agent.loaded.map(
|
|
1082
|
+
(part) => part.part === "instructions" ? `${PART_LABEL.instructions} ${part.loaded === 1 ? "\u2713" : "\u2014"}` : `${PART_LABEL[part.part]} ${part.loaded}/${part.total}`
|
|
1083
|
+
);
|
|
1084
|
+
const missing = agent.unavailable.slice(0, 6).map((u) => `${u.name}: ${u.reason}`);
|
|
1085
|
+
const more = agent.unavailable.length > 6 ? [`+${agent.unavailable.length - 6} more`] : [];
|
|
1086
|
+
const complete = agent.loaded.every((part) => part.loaded === part.total);
|
|
1087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1088
|
+
"span",
|
|
1089
|
+
{
|
|
1090
|
+
className: (0, import_design_system4.cn)("cs-agent-chip", !complete && "cs-agent-chip--partial"),
|
|
1091
|
+
title: missing.length ? [...missing, ...more].join("\n") : "Everything loaded",
|
|
1092
|
+
"data-testid": "cs-agent-chip",
|
|
1093
|
+
children: [
|
|
1094
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "font-medium text-foreground", children: [
|
|
1095
|
+
agent.name,
|
|
1096
|
+
agent.versionNumber !== null ? ` v${agent.versionNumber}` : ""
|
|
1097
|
+
] }),
|
|
1098
|
+
" ",
|
|
1099
|
+
"\xB7 ",
|
|
1100
|
+
parts.join(" \xB7 ")
|
|
1101
|
+
]
|
|
1102
|
+
}
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// src/react/sidebar.tsx
|
|
1107
|
+
var import_react7 = require("react");
|
|
1108
|
+
var import_design_system5 = require("@ai-matrx/design-system");
|
|
1109
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
882
1110
|
function readLocal(key, allowed, fallback) {
|
|
883
1111
|
try {
|
|
884
1112
|
const value = localStorage.getItem(key);
|
|
@@ -894,23 +1122,23 @@ function writeLocal(key, value) {
|
|
|
894
1122
|
}
|
|
895
1123
|
}
|
|
896
1124
|
function SectionLabel({ children, action }) {
|
|
897
|
-
return /* @__PURE__ */ (0,
|
|
898
|
-
/* @__PURE__ */ (0,
|
|
1125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-cs-section-label": true, className: "flex h-8 items-center justify-between px-3 pt-3", children: [
|
|
1126
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[12px] font-medium text-muted-foreground", children }),
|
|
899
1127
|
action
|
|
900
1128
|
] });
|
|
901
1129
|
}
|
|
902
1130
|
function GroupLabel({ children }) {
|
|
903
|
-
return /* @__PURE__ */ (0,
|
|
1131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "truncate px-4 pb-0.5 pt-2.5 text-[12px] font-medium text-muted-foreground", children });
|
|
904
1132
|
}
|
|
905
1133
|
function RenameInput(props) {
|
|
906
|
-
const [value, setValue] = (0,
|
|
907
|
-
const done = (0,
|
|
1134
|
+
const [value, setValue] = (0, import_react7.useState)(props.initial);
|
|
1135
|
+
const done = (0, import_react7.useRef)(false);
|
|
908
1136
|
const finish = (title) => {
|
|
909
1137
|
if (done.current) return;
|
|
910
1138
|
done.current = true;
|
|
911
1139
|
props.onDone(title);
|
|
912
1140
|
};
|
|
913
|
-
return /* @__PURE__ */ (0,
|
|
1141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
914
1142
|
"input",
|
|
915
1143
|
{
|
|
916
1144
|
autoFocus: true,
|
|
@@ -927,11 +1155,16 @@ function RenameInput(props) {
|
|
|
927
1155
|
}
|
|
928
1156
|
);
|
|
929
1157
|
}
|
|
1158
|
+
function entryTarget(entry) {
|
|
1159
|
+
if (entry.kind === "session" && entry.session) return `#s/${entry.session.id}`;
|
|
1160
|
+
if (entry.providerSessionId) return `#d/${entry.provider}/${entry.providerSessionId}`;
|
|
1161
|
+
return "";
|
|
1162
|
+
}
|
|
930
1163
|
function Row(props) {
|
|
931
1164
|
const client = useCodingSessionsClient();
|
|
932
1165
|
const show = useToastShow();
|
|
933
|
-
const [renaming, setRenaming] = (0,
|
|
934
|
-
const [menuOpen, setMenuOpen] = (0,
|
|
1166
|
+
const [renaming, setRenaming] = (0, import_react7.useState)(false);
|
|
1167
|
+
const [menuOpen, setMenuOpen] = (0, import_react7.useState)(false);
|
|
935
1168
|
const { entry } = props;
|
|
936
1169
|
const rename = (title) => {
|
|
937
1170
|
setRenaming(false);
|
|
@@ -941,14 +1174,20 @@ function Row(props) {
|
|
|
941
1174
|
(error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`)
|
|
942
1175
|
);
|
|
943
1176
|
};
|
|
944
|
-
return /* @__PURE__ */ (0,
|
|
945
|
-
/* @__PURE__ */ (0,
|
|
1177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system5.ContextMenu, { children: [
|
|
1178
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
946
1179
|
"div",
|
|
947
1180
|
{
|
|
948
|
-
className: (0,
|
|
1181
|
+
className: (0, import_design_system5.cn)("cs-row group", props.active && "cs-row--active", menuOpen && "cs-row--menu"),
|
|
949
1182
|
"data-hidden": entry.hidden || void 0,
|
|
1183
|
+
"data-cs-row": entry.key,
|
|
1184
|
+
"data-cs-target": entryTarget(entry),
|
|
1185
|
+
"data-cs-provider": entry.provider,
|
|
1186
|
+
"data-cs-title": entry.title,
|
|
1187
|
+
"data-cs-live": props.live ? "true" : void 0,
|
|
1188
|
+
"data-cs-active": props.active ? "true" : void 0,
|
|
950
1189
|
children: [
|
|
951
|
-
/* @__PURE__ */ (0,
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
952
1191
|
"button",
|
|
953
1192
|
{
|
|
954
1193
|
type: "button",
|
|
@@ -960,39 +1199,39 @@ function Row(props) {
|
|
|
960
1199
|
(${entry.originalTitle})` : entry.title
|
|
961
1200
|
}
|
|
962
1201
|
),
|
|
963
|
-
/* @__PURE__ */ (0,
|
|
964
|
-
/* @__PURE__ */ (0,
|
|
965
|
-
renaming ? /* @__PURE__ */ (0,
|
|
966
|
-
/* @__PURE__ */ (0,
|
|
967
|
-
entry.pinned ? /* @__PURE__ */ (0,
|
|
1202
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pointer-events-none mt-0.5 shrink-0", children: props.live ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SpinnerIcon, { size: 16, className: "text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProviderMark, { provider: entry.provider, size: 16 }) }),
|
|
1203
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "cs-row__body", children: [
|
|
1204
|
+
renaming ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "pointer-events-auto relative z-10 block", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RenameInput, { initial: entry.title, onDone: rename }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex items-center gap-1", children: [
|
|
1205
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "min-w-0 truncate text-[13px] font-medium leading-5", children: entry.title }),
|
|
1206
|
+
entry.pinned ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PinIcon, { size: 11, className: "shrink-0 text-muted-foreground", "aria-label": "Pinned" }) : null
|
|
968
1207
|
] }),
|
|
969
|
-
/* @__PURE__ */ (0,
|
|
970
|
-
props.snippet ? /* @__PURE__ */ (0,
|
|
1208
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "block truncate text-[11.5px] leading-4 text-muted-foreground", children: props.meta }),
|
|
1209
|
+
props.snippet ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "cs-row__snippet", children: props.snippet }) : null
|
|
971
1210
|
] }),
|
|
972
|
-
renaming ? null : /* @__PURE__ */ (0,
|
|
1211
|
+
renaming ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "cs-row__actions", children: [
|
|
973
1212
|
props.takeover,
|
|
974
|
-
/* @__PURE__ */ (0,
|
|
975
|
-
/* @__PURE__ */ (0,
|
|
976
|
-
/* @__PURE__ */ (0,
|
|
1213
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system5.DropdownMenu, { open: menuOpen, onOpenChange: setMenuOpen, children: [
|
|
1214
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "cs-icon-button", "aria-label": `More for ${entry.title}`, title: "More", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MoreIcon, { size: 15 }) }) }),
|
|
1215
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuContent, { align: "start", className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatMenuItems, { entry, variant: "dropdown", onRename: () => setRenaming(true) }) })
|
|
977
1216
|
] })
|
|
978
1217
|
] })
|
|
979
1218
|
]
|
|
980
1219
|
}
|
|
981
1220
|
) }),
|
|
982
|
-
/* @__PURE__ */ (0,
|
|
1221
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.ContextMenuContent, { className: "w-60", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatMenuItems, { entry, variant: "context", onRename: () => setRenaming(true) }) })
|
|
983
1222
|
] });
|
|
984
1223
|
}
|
|
985
1224
|
function SidebarSkeleton() {
|
|
986
|
-
return /* @__PURE__ */ (0,
|
|
1225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "space-y-1.5 px-3 py-2", "aria-hidden": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cs-skeleton h-9 rounded-lg" }, i)) });
|
|
987
1226
|
}
|
|
988
1227
|
function Highlight({ text, query }) {
|
|
989
1228
|
const q = query.trim().toLowerCase();
|
|
990
1229
|
if (!q) return text;
|
|
991
1230
|
const at = text.toLowerCase().indexOf(q);
|
|
992
1231
|
if (at < 0) return text;
|
|
993
|
-
return /* @__PURE__ */ (0,
|
|
1232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
994
1233
|
text.slice(0, at),
|
|
995
|
-
/* @__PURE__ */ (0,
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("mark", { className: "cs-mark", children: text.slice(at, at + q.length) }),
|
|
996
1235
|
text.slice(at + q.length)
|
|
997
1236
|
] });
|
|
998
1237
|
}
|
|
@@ -1007,10 +1246,10 @@ var EMPTY_SEARCH = {
|
|
|
1007
1246
|
};
|
|
1008
1247
|
function useContentSearch(query) {
|
|
1009
1248
|
const client = useCodingSessionsClient();
|
|
1010
|
-
const [state, setState] = (0,
|
|
1011
|
-
const latest = (0,
|
|
1249
|
+
const [state, setState] = (0, import_react7.useState)(EMPTY_SEARCH);
|
|
1250
|
+
const latest = (0, import_react7.useRef)(query);
|
|
1012
1251
|
latest.current = query;
|
|
1013
|
-
const run = (0,
|
|
1252
|
+
const run = (0, import_react7.useCallback)(
|
|
1014
1253
|
async (q, cursor, append) => {
|
|
1015
1254
|
setState((s) => ({ ...append ? s : EMPTY_SEARCH, query: q, loading: true, error: null }));
|
|
1016
1255
|
try {
|
|
@@ -1032,7 +1271,7 @@ function useContentSearch(query) {
|
|
|
1032
1271
|
},
|
|
1033
1272
|
[client]
|
|
1034
1273
|
);
|
|
1035
|
-
(0,
|
|
1274
|
+
(0, import_react7.useEffect)(() => {
|
|
1036
1275
|
const q = query.trim();
|
|
1037
1276
|
if (q.length < 2) {
|
|
1038
1277
|
setState(EMPTY_SEARCH);
|
|
@@ -1041,7 +1280,7 @@ function useContentSearch(query) {
|
|
|
1041
1280
|
const timer = setTimeout(() => void run(q, 0, false), 350);
|
|
1042
1281
|
return () => clearTimeout(timer);
|
|
1043
1282
|
}, [query, run]);
|
|
1044
|
-
const more = (0,
|
|
1283
|
+
const more = (0, import_react7.useCallback)(() => {
|
|
1045
1284
|
if (state.nextCursor !== null && !state.loading) void run(state.query, state.nextCursor, true);
|
|
1046
1285
|
}, [run, state.nextCursor, state.loading, state.query]);
|
|
1047
1286
|
return [state, more];
|
|
@@ -1061,19 +1300,19 @@ function Sidebar(props) {
|
|
|
1061
1300
|
const client = useCodingSessionsClient();
|
|
1062
1301
|
const state = useCodingSessionsState();
|
|
1063
1302
|
const now = useMinuteClock();
|
|
1064
|
-
const [query, setQuery] = (0,
|
|
1303
|
+
const [query, setQuery] = (0, import_react7.useState)("");
|
|
1065
1304
|
const [search, searchMore] = useContentSearch(query);
|
|
1066
|
-
const [groupMode, setGroupMode] = (0,
|
|
1067
|
-
const [showHidden, setShowHidden] = (0,
|
|
1068
|
-
const [takingOver, setTakingOver] = (0,
|
|
1069
|
-
const [takeoverError, setTakeoverError] = (0,
|
|
1305
|
+
const [groupMode, setGroupMode] = (0, import_react7.useState)(() => readLocal("coding-sessions.group", ["date", "folder"], "date"));
|
|
1306
|
+
const [showHidden, setShowHidden] = (0, import_react7.useState)(false);
|
|
1307
|
+
const [takingOver, setTakingOver] = (0, import_react7.useState)(null);
|
|
1308
|
+
const [takeoverError, setTakeoverError] = (0, import_react7.useState)(null);
|
|
1070
1309
|
const prefs = state.preferences;
|
|
1071
1310
|
const sessions = state.sessions.data;
|
|
1072
1311
|
const isLive = (id) => {
|
|
1073
1312
|
const run = state.runs[id];
|
|
1074
1313
|
return run !== void 0 && !isTerminalRunStatus(run.status);
|
|
1075
1314
|
};
|
|
1076
|
-
const { ours, others, hiddenCount } = (0,
|
|
1315
|
+
const { ours, others, hiddenCount } = (0, import_react7.useMemo)(() => {
|
|
1077
1316
|
const oursList = sessions.map((s) => sessionEntry(s, prefs));
|
|
1078
1317
|
const known = new Set(sessions.map((s) => s.providerSessionId).filter(Boolean));
|
|
1079
1318
|
const othersList = state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => discoveredEntry(d, prefs));
|
|
@@ -1113,8 +1352,8 @@ function Sidebar(props) {
|
|
|
1113
1352
|
let meta;
|
|
1114
1353
|
if (live) meta = `${PROVIDER_LABEL[entry.provider]} is working\u2026`;
|
|
1115
1354
|
else if (d?.activeElsewhere)
|
|
1116
|
-
meta = /* @__PURE__ */ (0,
|
|
1117
|
-
/* @__PURE__ */ (0,
|
|
1355
|
+
meta = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "cs-live-elsewhere", children: [
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "cs-live-dot", "aria-hidden": "true" }),
|
|
1118
1357
|
"Running in ",
|
|
1119
1358
|
PROVIDER_LABEL[entry.provider]
|
|
1120
1359
|
] });
|
|
@@ -1123,8 +1362,8 @@ function Sidebar(props) {
|
|
|
1123
1362
|
const where = entry.cwd ? prettyPath2(entry.cwd) : "unknown folder";
|
|
1124
1363
|
meta = `${status}${entry.kind === "discovered" ? `${PROVIDER_LABEL[entry.provider]} \xB7 ` : ""}${groupMode === "folder" && !extra ? "" : `${where} \xB7 `}${relativeTime(entry.updatedAt, now)}`;
|
|
1125
1364
|
}
|
|
1126
|
-
return /* @__PURE__ */ (0,
|
|
1127
|
-
/* @__PURE__ */ (0,
|
|
1365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1128
1367
|
Row,
|
|
1129
1368
|
{
|
|
1130
1369
|
entry,
|
|
@@ -1133,7 +1372,7 @@ function Sidebar(props) {
|
|
|
1133
1372
|
live,
|
|
1134
1373
|
meta,
|
|
1135
1374
|
snippet: extra?.snippet,
|
|
1136
|
-
takeover: d?.cwd ? /* @__PURE__ */ (0,
|
|
1375
|
+
takeover: d?.cwd ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1137
1376
|
"button",
|
|
1138
1377
|
{
|
|
1139
1378
|
type: "button",
|
|
@@ -1142,18 +1381,18 @@ function Sidebar(props) {
|
|
|
1142
1381
|
title: d.activeElsewhere ? d.activeElsewhere.message : "Continue this chat here",
|
|
1143
1382
|
disabled: takingOver === d.providerSessionId,
|
|
1144
1383
|
children: [
|
|
1145
|
-
takingOver === d.providerSessionId ? /* @__PURE__ */ (0,
|
|
1384
|
+
takingOver === d.providerSessionId ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SpinnerIcon, { size: 11 }) : null,
|
|
1146
1385
|
"Take over"
|
|
1147
1386
|
]
|
|
1148
1387
|
}
|
|
1149
1388
|
) : null
|
|
1150
1389
|
}
|
|
1151
1390
|
),
|
|
1152
|
-
takeoverError && d && takeoverError.id === d.providerSessionId ? /* @__PURE__ */ (0,
|
|
1391
|
+
takeoverError && d && takeoverError.id === d.providerSessionId ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mx-4 mb-1 text-[11.5px] text-destructive", children: takeoverError.message }) : null
|
|
1153
1392
|
] }, entry.key);
|
|
1154
1393
|
};
|
|
1155
|
-
const renderGroups = (entries) => groupEntries(entries, groupMode, now).map((group) => /* @__PURE__ */ (0,
|
|
1156
|
-
/* @__PURE__ */ (0,
|
|
1394
|
+
const renderGroups = (entries) => groupEntries(entries, groupMode, now).map((group) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "group", "aria-label": group.label, children: [
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GroupLabel, { children: group.label }),
|
|
1157
1396
|
group.entries.map((e) => renderEntry(e))
|
|
1158
1397
|
] }, group.label));
|
|
1159
1398
|
const searching = query.trim().length > 0;
|
|
@@ -1170,60 +1409,60 @@ function Sidebar(props) {
|
|
|
1170
1409
|
props.onFound(hitToDiscovered(hit));
|
|
1171
1410
|
props.select({ kind: "discovered", provider: hit.provider, id: hit.providerSessionId });
|
|
1172
1411
|
};
|
|
1173
|
-
const searchBody = /* @__PURE__ */ (0,
|
|
1174
|
-
/* @__PURE__ */ (0,
|
|
1175
|
-
titleMatches.length === 0 ? /* @__PURE__ */ (0,
|
|
1176
|
-
/* @__PURE__ */ (0,
|
|
1177
|
-
query.trim().length < 2 ? /* @__PURE__ */ (0,
|
|
1412
|
+
const searchBody = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1413
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Chats" }),
|
|
1414
|
+
titleMatches.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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 })),
|
|
1415
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "In conversations" }),
|
|
1416
|
+
query.trim().length < 2 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "px-4 py-1 text-[12px] text-muted-foreground", children: "Type at least two letters to search what was said." }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1178
1417
|
contentHits.map((hit) => {
|
|
1179
1418
|
const known = allByKey.get(chatKey(hit.provider, hit.providerSessionId));
|
|
1180
1419
|
const entry = known ?? discoveredEntry(hitToDiscovered(hit), prefs);
|
|
1181
|
-
return /* @__PURE__ */ (0,
|
|
1420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { onClickCapture: known ? void 0 : () => props.onFound(hitToDiscovered(hit)), children: renderEntry(entry, {
|
|
1182
1421
|
query,
|
|
1183
|
-
snippet: hit.snippet ? /* @__PURE__ */ (0,
|
|
1422
|
+
snippet: hit.snippet ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Highlight, { text: hit.snippet, query }) : void 0
|
|
1184
1423
|
}) }, `hit:${entry.key}`);
|
|
1185
1424
|
}),
|
|
1186
|
-
/* @__PURE__ */ (0,
|
|
1425
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "px-4 py-2 text-[11.5px] leading-4 text-muted-foreground", role: "status", "aria-live": "polite", children: search.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "text-destructive", children: [
|
|
1187
1426
|
"Search stopped: ",
|
|
1188
1427
|
search.error
|
|
1189
|
-
] }) : search.loading ? /* @__PURE__ */ (0,
|
|
1190
|
-
/* @__PURE__ */ (0,
|
|
1428
|
+
] }) : search.loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
1429
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SpinnerIcon, { size: 12 }),
|
|
1191
1430
|
" Searching your chats\u2026"
|
|
1192
|
-
] }) : search.query ? /* @__PURE__ */ (0,
|
|
1431
|
+
] }) : search.query ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1193
1432
|
contentHits.length === 0 && search.hits.length === 0 ? "Nothing found. " : null,
|
|
1194
1433
|
search.nextCursor === null ? `Searched all ${search.total.toLocaleString()} chats on this computer.` : `Searched the ${search.scanned.toLocaleString()} most recent of ${search.total.toLocaleString()} chats.`,
|
|
1195
|
-
search.nextCursor !== null ? /* @__PURE__ */ (0,
|
|
1434
|
+
search.nextCursor !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "cs-link ml-1", onClick: searchMore, children: "Search older chats" }) : null
|
|
1196
1435
|
] }) : null })
|
|
1197
1436
|
] })
|
|
1198
1437
|
] });
|
|
1199
|
-
const listBody = /* @__PURE__ */ (0,
|
|
1200
|
-
pinned.length > 0 ? /* @__PURE__ */ (0,
|
|
1201
|
-
/* @__PURE__ */ (0,
|
|
1438
|
+
const listBody = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1439
|
+
pinned.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Pinned" }),
|
|
1202
1441
|
pinned.map((e) => renderEntry(e))
|
|
1203
1442
|
] }) : null,
|
|
1204
|
-
running.length > 0 ? /* @__PURE__ */ (0,
|
|
1205
|
-
/* @__PURE__ */ (0,
|
|
1443
|
+
running.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1444
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Running" }),
|
|
1206
1445
|
running.map((e) => renderEntry(e))
|
|
1207
1446
|
] }) : null,
|
|
1208
|
-
/* @__PURE__ */ (0,
|
|
1209
|
-
state.sessions.loading && state.sessions.loadedAt === null ? /* @__PURE__ */ (0,
|
|
1210
|
-
/* @__PURE__ */ (0,
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Recent" }),
|
|
1448
|
+
state.sessions.loading && state.sessions.loadedAt === null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SidebarSkeleton, {}) : state.sessions.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.sessions.error }) : recent.length === 0 ? running.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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)),
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1211
1450
|
SectionLabel,
|
|
1212
1451
|
{
|
|
1213
|
-
action: /* @__PURE__ */ (0,
|
|
1214
|
-
/* @__PURE__ */ (0,
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1217
|
-
/* @__PURE__ */ (0,
|
|
1218
|
-
/* @__PURE__ */ (0,
|
|
1219
|
-
/* @__PURE__ */ (0,
|
|
1220
|
-
/* @__PURE__ */ (0,
|
|
1452
|
+
action: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex items-center gap-0.5", children: [
|
|
1453
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system5.DropdownMenu, { children: [
|
|
1454
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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" }) }),
|
|
1455
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system5.DropdownMenuContent, { align: "end", className: "w-52", children: [
|
|
1456
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuLabel, { children: "Group your other chats" }),
|
|
1457
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system5.DropdownMenuRadioGroup, { value: groupMode, onValueChange: (v) => setMode(v), children: [
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuRadioItem, { value: "date", children: "By date" }),
|
|
1459
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuRadioItem, { value: "folder", children: "By folder" })
|
|
1221
1460
|
] }),
|
|
1222
|
-
/* @__PURE__ */ (0,
|
|
1223
|
-
/* @__PURE__ */ (0,
|
|
1461
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuSeparator, {}),
|
|
1462
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system5.DropdownMenuItem, { onSelect: () => setShowHidden((v) => !v), children: showHidden ? "Leave hidden chats out" : `Show hidden chats${hiddenCount ? ` (${hiddenCount})` : ""}` })
|
|
1224
1463
|
] })
|
|
1225
1464
|
] }),
|
|
1226
|
-
/* @__PURE__ */ (0,
|
|
1465
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1227
1466
|
"button",
|
|
1228
1467
|
{
|
|
1229
1468
|
type: "button",
|
|
@@ -1231,17 +1470,17 @@ function Sidebar(props) {
|
|
|
1231
1470
|
onClick: () => void client.refreshDiscovered(),
|
|
1232
1471
|
"aria-label": "Look again for your other chats",
|
|
1233
1472
|
title: "Look again",
|
|
1234
|
-
children: state.discovered.loading ? /* @__PURE__ */ (0,
|
|
1473
|
+
children: state.discovered.loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RefreshIcon, { size: 13 })
|
|
1235
1474
|
}
|
|
1236
1475
|
)
|
|
1237
1476
|
] }),
|
|
1238
1477
|
children: "Your other chats"
|
|
1239
1478
|
}
|
|
1240
1479
|
),
|
|
1241
|
-
state.discovered.loading && state.discovered.loadedAt === null ? /* @__PURE__ */ (0,
|
|
1480
|
+
state.discovered.loading && state.discovered.loadedAt === null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SidebarSkeleton, {}) : state.discovered.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.discovered.error }) : otherList.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1242
1481
|
renderGroups(otherList),
|
|
1243
|
-
state.discovered.data.length >= state.discoveredLimit ? /* @__PURE__ */ (0,
|
|
1244
|
-
|
|
1482
|
+
state.discovered.data.length >= state.discoveredLimit ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "px-3 pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1483
|
+
import_design_system5.Button,
|
|
1245
1484
|
{
|
|
1246
1485
|
variant: "ghost",
|
|
1247
1486
|
size: "sm",
|
|
@@ -1249,32 +1488,32 @@ function Sidebar(props) {
|
|
|
1249
1488
|
onClick: () => void client.showMoreDiscovered(),
|
|
1250
1489
|
disabled: state.discovered.loading,
|
|
1251
1490
|
children: [
|
|
1252
|
-
state.discovered.loading ? /* @__PURE__ */ (0,
|
|
1491
|
+
state.discovered.loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SpinnerIcon, { size: 13 }) : null,
|
|
1253
1492
|
"Show older chats"
|
|
1254
1493
|
]
|
|
1255
1494
|
}
|
|
1256
1495
|
) }) : null
|
|
1257
1496
|
] }),
|
|
1258
|
-
showHidden ? null : hiddenCount > 0 ? /* @__PURE__ */ (0,
|
|
1497
|
+
showHidden ? null : hiddenCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "cs-link mx-4 mt-3 text-[11.5px]", onClick: () => setShowHidden(true), children: [
|
|
1259
1498
|
hiddenCount,
|
|
1260
1499
|
" hidden ",
|
|
1261
1500
|
hiddenCount === 1 ? "chat" : "chats",
|
|
1262
1501
|
" \u2014 show"
|
|
1263
1502
|
] }) : null
|
|
1264
1503
|
] });
|
|
1265
|
-
return /* @__PURE__ */ (0,
|
|
1504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1266
1505
|
"aside",
|
|
1267
1506
|
{
|
|
1268
|
-
className: "cs-sidebar flex h-full shrink-0 flex-col border-r border-border bg-
|
|
1507
|
+
className: "cs-sidebar flex h-full shrink-0 flex-col border-r border-border bg-sidebar-background",
|
|
1269
1508
|
style: { width: props.width },
|
|
1270
1509
|
"aria-label": "Sessions",
|
|
1271
1510
|
children: [
|
|
1272
|
-
/* @__PURE__ */ (0,
|
|
1273
|
-
/* @__PURE__ */ (0,
|
|
1274
|
-
/* @__PURE__ */ (0,
|
|
1275
|
-
/* @__PURE__ */ (0,
|
|
1511
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between gap-2 px-4 pb-2 pt-3.5", children: [
|
|
1512
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1513
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "cs-app-mark", "aria-hidden": "true" }),
|
|
1514
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate text-[14px] font-semibold tracking-[-0.01em]", children: "Coding sessions" })
|
|
1276
1515
|
] }),
|
|
1277
|
-
/* @__PURE__ */ (0,
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1278
1517
|
"button",
|
|
1279
1518
|
{
|
|
1280
1519
|
type: "button",
|
|
@@ -1282,19 +1521,19 @@ function Sidebar(props) {
|
|
|
1282
1521
|
onClick: props.onCollapse,
|
|
1283
1522
|
"aria-label": "Hide the sidebar (\u2318B)",
|
|
1284
1523
|
title: "Hide sidebar \u2318B",
|
|
1285
|
-
children: /* @__PURE__ */ (0,
|
|
1524
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SidebarIcon, { size: 15 })
|
|
1286
1525
|
}
|
|
1287
1526
|
)
|
|
1288
1527
|
] }),
|
|
1289
|
-
/* @__PURE__ */ (0,
|
|
1290
|
-
/* @__PURE__ */ (0,
|
|
1291
|
-
/* @__PURE__ */ (0,
|
|
1528
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-1.5 px-3 pb-1", children: [
|
|
1529
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system5.Button, { className: "w-full justify-start gap-2", variant: "outline", size: "sm", onClick: props.onNew, children: [
|
|
1530
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PlusIcon, { size: 15 }),
|
|
1292
1531
|
"New session",
|
|
1293
|
-
/* @__PURE__ */ (0,
|
|
1532
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { className: "cs-kbd ml-auto", children: "\u2325\u2318N" })
|
|
1294
1533
|
] }),
|
|
1295
|
-
/* @__PURE__ */ (0,
|
|
1296
|
-
/* @__PURE__ */ (0,
|
|
1297
|
-
/* @__PURE__ */ (0,
|
|
1534
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cs-search", children: [
|
|
1535
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SearchIcon, { size: 14, className: "cs-search__icon" }),
|
|
1536
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1298
1537
|
"input",
|
|
1299
1538
|
{
|
|
1300
1539
|
ref: props.searchRef,
|
|
@@ -1320,10 +1559,10 @@ function Sidebar(props) {
|
|
|
1320
1559
|
className: "cs-search__input"
|
|
1321
1560
|
}
|
|
1322
1561
|
),
|
|
1323
|
-
query ? /* @__PURE__ */ (0,
|
|
1562
|
+
query ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "cs-icon-button cs-search__clear", onClick: () => setQuery(""), "aria-label": "Clear search", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseIcon, { size: 13 }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { className: "cs-search__kbd", children: "\u2318K" })
|
|
1324
1563
|
] })
|
|
1325
1564
|
] }),
|
|
1326
|
-
/* @__PURE__ */ (0,
|
|
1565
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("nav", { className: "min-h-0 flex-1 overflow-y-auto pb-3", children: searching ? searchBody : listBody }),
|
|
1327
1566
|
props.footer
|
|
1328
1567
|
]
|
|
1329
1568
|
}
|
|
@@ -1488,14 +1727,15 @@ function createTranscriptBuilder() {
|
|
|
1488
1727
|
}));
|
|
1489
1728
|
return;
|
|
1490
1729
|
case "error": {
|
|
1491
|
-
const
|
|
1730
|
+
const text = runErrorLabel(item.text);
|
|
1731
|
+
const said = current?.message.parts.some((p) => p.type === "error" && p.message.trim() === text.trim());
|
|
1492
1732
|
if (said) return;
|
|
1493
1733
|
upsertPart(item.id, () => ({
|
|
1494
1734
|
type: "error",
|
|
1495
1735
|
errorType: "provider",
|
|
1496
1736
|
code: null,
|
|
1497
|
-
message:
|
|
1498
|
-
userMessage:
|
|
1737
|
+
message: text,
|
|
1738
|
+
userMessage: text,
|
|
1499
1739
|
recoverable: true,
|
|
1500
1740
|
remedy: null
|
|
1501
1741
|
}));
|
|
@@ -1913,13 +2153,13 @@ function firstInvalidField(errors) {
|
|
|
1913
2153
|
}
|
|
1914
2154
|
|
|
1915
2155
|
// src/react/app.tsx
|
|
1916
|
-
var
|
|
2156
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1917
2157
|
function CodingSessionsProvider({ transport, children }) {
|
|
1918
|
-
const [client] = (0,
|
|
1919
|
-
(0,
|
|
2158
|
+
const [client] = (0, import_react8.useState)(() => new CodingSessionsClient(transport));
|
|
2159
|
+
(0, import_react8.useEffect)(() => {
|
|
1920
2160
|
if (transport.status().state === "open") void client.refreshAll();
|
|
1921
2161
|
}, [client, transport]);
|
|
1922
|
-
return /* @__PURE__ */ (0,
|
|
2162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CodingSessionsContext.Provider, { value: client, children });
|
|
1923
2163
|
}
|
|
1924
2164
|
function readHash() {
|
|
1925
2165
|
if (typeof location === "undefined") return { kind: "none" };
|
|
@@ -1942,8 +2182,8 @@ function readTheme() {
|
|
|
1942
2182
|
}
|
|
1943
2183
|
}
|
|
1944
2184
|
function useTheme() {
|
|
1945
|
-
const [choice, setChoice] = (0,
|
|
1946
|
-
(0,
|
|
2185
|
+
const [choice, setChoice] = (0, import_react8.useState)(readTheme);
|
|
2186
|
+
(0, import_react8.useEffect)(() => {
|
|
1947
2187
|
const media = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-color-scheme: dark)") : null;
|
|
1948
2188
|
const apply = () => {
|
|
1949
2189
|
const dark = choice === "dark" || choice === "system" && media?.matches === true;
|
|
@@ -1954,7 +2194,7 @@ function useTheme() {
|
|
|
1954
2194
|
media?.addEventListener("change", apply);
|
|
1955
2195
|
return () => media?.removeEventListener("change", apply);
|
|
1956
2196
|
}, [choice]);
|
|
1957
|
-
const set = (0,
|
|
2197
|
+
const set = (0, import_react8.useCallback)((next) => {
|
|
1958
2198
|
setChoice(next);
|
|
1959
2199
|
try {
|
|
1960
2200
|
localStorage.setItem("coding-sessions.theme", next);
|
|
@@ -1973,8 +2213,8 @@ var RUN_LABEL = {
|
|
|
1973
2213
|
function RunPill({ run }) {
|
|
1974
2214
|
if (!run) return null;
|
|
1975
2215
|
const live = !isTerminalRunStatus(run.status);
|
|
1976
|
-
return /* @__PURE__ */ (0,
|
|
1977
|
-
live ? /* @__PURE__ */ (0,
|
|
2216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: (0, import_design_system6.cn)("cs-pill", `cs-pill--${run.status}`), children: [
|
|
2217
|
+
live ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "cs-pill__dot", "aria-hidden": "true" }) : null,
|
|
1978
2218
|
RUN_LABEL[run.status]
|
|
1979
2219
|
] });
|
|
1980
2220
|
}
|
|
@@ -1982,17 +2222,17 @@ function ConnectionBanner() {
|
|
|
1982
2222
|
const { connection } = useCodingSessionsState();
|
|
1983
2223
|
if (connection.state === "open") return null;
|
|
1984
2224
|
const closed = connection.state === "closed";
|
|
1985
|
-
return /* @__PURE__ */ (0,
|
|
2225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1986
2226
|
"div",
|
|
1987
2227
|
{
|
|
1988
2228
|
role: "status",
|
|
1989
|
-
className: (0,
|
|
2229
|
+
className: (0, import_design_system6.cn)(
|
|
1990
2230
|
"flex items-center gap-2 border-b px-4 py-2 text-[13px]",
|
|
1991
2231
|
closed ? "border-destructive/30 bg-destructive/10 text-destructive" : "border-border bg-muted/60 text-muted-foreground"
|
|
1992
2232
|
),
|
|
1993
2233
|
children: [
|
|
1994
|
-
closed ? /* @__PURE__ */ (0,
|
|
1995
|
-
/* @__PURE__ */ (0,
|
|
2234
|
+
closed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 15 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 14 }),
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: closed ? connection.reason : "Connecting to the coding sessions host\u2026" })
|
|
1996
2236
|
]
|
|
1997
2237
|
}
|
|
1998
2238
|
);
|
|
@@ -2002,22 +2242,22 @@ function ProvidersFooter(props) {
|
|
|
2002
2242
|
const client = useCodingSessionsClient();
|
|
2003
2243
|
const next = { system: "light", light: "dark", dark: "system" };
|
|
2004
2244
|
const themeLabel = { system: "Match system", light: "Light", dark: "Dark" };
|
|
2005
|
-
return /* @__PURE__ */ (0,
|
|
2006
|
-
/* @__PURE__ */ (0,
|
|
2245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "border-t border-border px-3 py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2246
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-[11.5px] text-muted-foreground", children: "Checking Claude Code and Codex\u2026" }) : state.providers.data.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2007
2247
|
"span",
|
|
2008
2248
|
{
|
|
2009
|
-
className: (0,
|
|
2010
|
-
title: p.problem ? `${p.problem} ${p.fix ?? ""}` :
|
|
2249
|
+
className: (0, import_design_system6.cn)("cs-provider-chip", p.ready ? "" : "cs-provider-chip--problem"),
|
|
2250
|
+
title: p.problem ? `${p.problem} ${p.fix ?? ""}` : [binaryWords(p) ?? p.label, p.plan, newerWords(p)].filter(Boolean).join(" \xB7 "),
|
|
2011
2251
|
children: [
|
|
2012
|
-
/* @__PURE__ */ (0,
|
|
2252
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProviderMark, { provider: p.provider, size: 13 }),
|
|
2013
2253
|
p.label,
|
|
2014
|
-
p.lastProblem ? /* @__PURE__ */ (0,
|
|
2015
|
-
p.ready ? /* @__PURE__ */ (0,
|
|
2254
|
+
p.lastProblem ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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,
|
|
2255
|
+
p.ready ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 12 })
|
|
2016
2256
|
]
|
|
2017
2257
|
},
|
|
2018
2258
|
p.provider
|
|
2019
2259
|
)) }),
|
|
2020
|
-
/* @__PURE__ */ (0,
|
|
2260
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2021
2261
|
"button",
|
|
2022
2262
|
{
|
|
2023
2263
|
type: "button",
|
|
@@ -2025,11 +2265,11 @@ function ProvidersFooter(props) {
|
|
|
2025
2265
|
onClick: () => void client.refreshProviders(),
|
|
2026
2266
|
"aria-label": "Check Claude Code and Codex again",
|
|
2027
2267
|
title: "Check again",
|
|
2028
|
-
children: state.providers.loading ? /* @__PURE__ */ (0,
|
|
2268
|
+
children: state.providers.loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshIcon, { size: 13 })
|
|
2029
2269
|
}
|
|
2030
2270
|
),
|
|
2031
2271
|
props.extra,
|
|
2032
|
-
/* @__PURE__ */ (0,
|
|
2272
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2033
2273
|
"button",
|
|
2034
2274
|
{
|
|
2035
2275
|
type: "button",
|
|
@@ -2037,14 +2277,14 @@ function ProvidersFooter(props) {
|
|
|
2037
2277
|
onClick: () => props.setTheme(next[props.theme]),
|
|
2038
2278
|
"aria-label": `Theme: ${themeLabel[props.theme]}. Switch to ${themeLabel[next[props.theme]]}.`,
|
|
2039
2279
|
title: `Theme: ${themeLabel[props.theme]}`,
|
|
2040
|
-
children: props.theme === "system" ? /* @__PURE__ */ (0,
|
|
2280
|
+
children: props.theme === "system" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MonitorIcon, { size: 14 }) : props.theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SunIcon, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoonIcon, { size: 14 })
|
|
2041
2281
|
}
|
|
2042
2282
|
)
|
|
2043
2283
|
] }) });
|
|
2044
2284
|
}
|
|
2045
2285
|
function useNotifier() {
|
|
2046
|
-
const show = (0,
|
|
2047
|
-
return (0,
|
|
2286
|
+
const show = (0, import_react8.useContext)(ToastContext);
|
|
2287
|
+
return (0, import_react8.useMemo)(
|
|
2048
2288
|
() => ({
|
|
2049
2289
|
notify(event) {
|
|
2050
2290
|
show(event.message);
|
|
@@ -2055,8 +2295,8 @@ function useNotifier() {
|
|
|
2055
2295
|
}
|
|
2056
2296
|
function useLiveElsewhere(provider, providerSessionId, initial = null) {
|
|
2057
2297
|
const client = useCodingSessionsClient();
|
|
2058
|
-
const [state, setState] = (0,
|
|
2059
|
-
(0,
|
|
2298
|
+
const [state, setState] = (0, import_react8.useState)(initial);
|
|
2299
|
+
(0, import_react8.useEffect)(() => {
|
|
2060
2300
|
if (!provider || !providerSessionId) {
|
|
2061
2301
|
setState(null);
|
|
2062
2302
|
return;
|
|
@@ -2076,8 +2316,8 @@ function useLiveElsewhere(provider, providerSessionId, initial = null) {
|
|
|
2076
2316
|
}
|
|
2077
2317
|
function useSessionUsage(sessionId, lastRunKey) {
|
|
2078
2318
|
const client = useCodingSessionsClient();
|
|
2079
|
-
const [usage, setUsage] = (0,
|
|
2080
|
-
(0,
|
|
2319
|
+
const [usage, setUsage] = (0, import_react8.useState)(null);
|
|
2320
|
+
(0, import_react8.useEffect)(() => {
|
|
2081
2321
|
let cancelled = false;
|
|
2082
2322
|
void client.transport.call("listRuns", sessionId).then((runs) => {
|
|
2083
2323
|
if (cancelled) return;
|
|
@@ -2098,18 +2338,18 @@ function useSessionUsage(sessionId, lastRunKey) {
|
|
|
2098
2338
|
return usage;
|
|
2099
2339
|
}
|
|
2100
2340
|
function HeaderMenu(props) {
|
|
2101
|
-
return /* @__PURE__ */ (0,
|
|
2102
|
-
/* @__PURE__ */ (0,
|
|
2103
|
-
/* @__PURE__ */ (0,
|
|
2341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DropdownMenu, { children: [
|
|
2342
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "cs-icon-button", "aria-label": "More for this chat", title: "More", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, { size: 16 }) }) }),
|
|
2343
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.DropdownMenuContent, { align: "end", className: "w-64", onCloseAutoFocus: (e) => e.preventDefault(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChatMenuItems, { entry: props.entry, variant: "dropdown", onRename: props.onRename }) })
|
|
2104
2344
|
] });
|
|
2105
2345
|
}
|
|
2106
2346
|
function HeaderTitle(props) {
|
|
2107
2347
|
const client = useCodingSessionsClient();
|
|
2108
|
-
const show = (0,
|
|
2109
|
-
const [value, setValue] = (0,
|
|
2110
|
-
(0,
|
|
2111
|
-
const inputRef = (0,
|
|
2112
|
-
(0,
|
|
2348
|
+
const show = (0, import_react8.useContext)(ToastContext);
|
|
2349
|
+
const [value, setValue] = (0, import_react8.useState)(props.entry.title);
|
|
2350
|
+
(0, import_react8.useEffect)(() => setValue(props.entry.title), [props.entry.title, props.renaming]);
|
|
2351
|
+
const inputRef = (0, import_react8.useRef)(null);
|
|
2352
|
+
(0, import_react8.useEffect)(() => {
|
|
2113
2353
|
if (!props.renaming) return;
|
|
2114
2354
|
const timer = setTimeout(() => {
|
|
2115
2355
|
const input = inputRef.current;
|
|
@@ -2121,7 +2361,7 @@ function HeaderTitle(props) {
|
|
|
2121
2361
|
return () => clearTimeout(timer);
|
|
2122
2362
|
}, [props.renaming]);
|
|
2123
2363
|
if (!props.renaming) {
|
|
2124
|
-
return /* @__PURE__ */ (0,
|
|
2364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2125
2365
|
"h1",
|
|
2126
2366
|
{
|
|
2127
2367
|
className: "truncate text-[15px] font-semibold leading-5 tracking-[-0.01em]",
|
|
@@ -2138,7 +2378,7 @@ function HeaderTitle(props) {
|
|
|
2138
2378
|
const next = title === "" || title === props.entry.originalTitle ? null : title;
|
|
2139
2379
|
client.setPreference(props.entry.key, { title: next }).catch((error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`));
|
|
2140
2380
|
};
|
|
2141
|
-
return /* @__PURE__ */ (0,
|
|
2381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2142
2382
|
"input",
|
|
2143
2383
|
{
|
|
2144
2384
|
ref: inputRef,
|
|
@@ -2157,15 +2397,22 @@ function HeaderTitle(props) {
|
|
|
2157
2397
|
);
|
|
2158
2398
|
}
|
|
2159
2399
|
function LongChatNote(props) {
|
|
2160
|
-
return /* @__PURE__ */ (0,
|
|
2400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "mx-auto mt-3 flex items-center gap-2 text-[12px] text-muted-foreground", children: [
|
|
2161
2401
|
"This chat is very long \u2014 showing its most recent part.",
|
|
2162
|
-
/* @__PURE__ */ (0,
|
|
2402
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "cs-link", onClick: props.onEarlier, disabled: props.loading, children: props.loading ? "Reading\u2026" : "Show earlier" })
|
|
2163
2403
|
] });
|
|
2164
2404
|
}
|
|
2405
|
+
function binaryWords(p) {
|
|
2406
|
+
if (!p.version) return null;
|
|
2407
|
+
return `${p.label} ${p.version}${p.binary ? ` \xB7 ${p.binary.sourceLabel}` : ""}`;
|
|
2408
|
+
}
|
|
2409
|
+
function newerWords(p) {
|
|
2410
|
+
return p.binary?.newer ? `Newer: ${p.binary.newer.version} ${p.binary.newer.sourceLabel}` : null;
|
|
2411
|
+
}
|
|
2165
2412
|
function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
2166
2413
|
const client = useCodingSessionsClient();
|
|
2167
2414
|
const state = useCodingSessionsState();
|
|
2168
|
-
const show = (0,
|
|
2415
|
+
const show = (0, import_react8.useContext)(ToastContext);
|
|
2169
2416
|
const transcript = useSessionTranscript(session.id);
|
|
2170
2417
|
const run = state.runs[session.id];
|
|
2171
2418
|
const live = run !== void 0 && !isTerminalRunStatus(run.status);
|
|
@@ -2173,8 +2420,9 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2173
2420
|
const provider = state.providers.data.find((p) => p.provider === session.provider) ?? null;
|
|
2174
2421
|
const blocked = provider && (!provider.installed || !provider.loggedIn) ? provider : null;
|
|
2175
2422
|
const limited = !blocked && provider?.lastProblem ? provider : null;
|
|
2176
|
-
const
|
|
2177
|
-
const [
|
|
2423
|
+
const modelRefused = run?.status === "failed" && isModelUnavailable(run.error);
|
|
2424
|
+
const [stopping, setStopping] = (0, import_react8.useState)(false);
|
|
2425
|
+
const [renaming, setRenaming] = (0, import_react8.useState)(false);
|
|
2178
2426
|
const elsewhere = useLiveElsewhere(
|
|
2179
2427
|
session.origin === "takeover" && !live ? session.provider : null,
|
|
2180
2428
|
session.providerSessionId
|
|
@@ -2183,7 +2431,7 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2183
2431
|
const messages = transcript.thread.getSnapshot().messages;
|
|
2184
2432
|
const files = useChangedFiles(messages);
|
|
2185
2433
|
const usage = useSessionUsage(session.id, `${run?.runId ?? ""}:${run?.status ?? ""}`);
|
|
2186
|
-
(0,
|
|
2434
|
+
(0, import_react8.useEffect)(() => {
|
|
2187
2435
|
if (!live) setStopping(false);
|
|
2188
2436
|
}, [live]);
|
|
2189
2437
|
const stop = async () => {
|
|
@@ -2196,16 +2444,16 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2196
2444
|
};
|
|
2197
2445
|
const usageWords = usage ? `${(0, import_format3.formatCount)(usage.tokens, { style: "compact" })} tokens${usage.cost !== null ? ` \xB7 ${(0, import_format3.formatUsd)(usage.cost)}` : ""}` : null;
|
|
2198
2446
|
const usageTitle = usage ? `${(0, import_format3.formatCount)(usage.tokens)} tokens over ${usage.runs} ${usage.runs === 1 ? "message" : "messages"} sent from here.` + (usage.cost !== null ? usage.billing === "subscription" ? ` ${(0, import_format3.formatUsd)(usage.cost)} is what this would cost at API prices \u2014 it's covered by your ${provider?.plan ?? ""} plan.`.replace(" ", " ") : ` Billed ${(0, import_format3.formatUsd)(usage.cost)} to your API key.` : "") : "";
|
|
2199
|
-
return /* @__PURE__ */ (0,
|
|
2200
|
-
/* @__PURE__ */ (0,
|
|
2201
|
-
/* @__PURE__ */ (0,
|
|
2202
|
-
/* @__PURE__ */ (0,
|
|
2203
|
-
/* @__PURE__ */ (0,
|
|
2204
|
-
/* @__PURE__ */ (0,
|
|
2205
|
-
/* @__PURE__ */ (0,
|
|
2206
|
-
/* @__PURE__ */ (0,
|
|
2207
|
-
/* @__PURE__ */ (0,
|
|
2208
|
-
/* @__PURE__ */ (0,
|
|
2447
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 flex-1", children: [
|
|
2448
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
|
|
2449
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { className: "flex flex-wrap items-center gap-2 border-b border-border px-5 pt-2.5 pb-2.5", children: [
|
|
2450
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProviderMark, { provider: session.provider, size: 22 }),
|
|
2451
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "min-w-0 flex-1 overflow-hidden", children: [
|
|
2452
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderTitle, { entry, renaming, setRenaming }),
|
|
2453
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 items-center gap-1 text-[12px] leading-5 text-muted-foreground", children: [
|
|
2454
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "shrink-0", children: PROVIDER_LABEL[session.provider] }),
|
|
2455
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
2456
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2209
2457
|
ModelPicker,
|
|
2210
2458
|
{
|
|
2211
2459
|
status: provider,
|
|
@@ -2213,86 +2461,106 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2213
2461
|
onChange: setOptions
|
|
2214
2462
|
}
|
|
2215
2463
|
),
|
|
2216
|
-
/* @__PURE__ */ (0,
|
|
2217
|
-
/* @__PURE__ */ (0,
|
|
2218
|
-
/* @__PURE__ */ (0,
|
|
2219
|
-
usageWords ? /* @__PURE__ */ (0,
|
|
2464
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
2465
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FolderIcon, { size: 12, className: "shrink-0" }),
|
|
2466
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "min-w-[4rem] truncate", title: session.cwd, children: prettyPath2(session.cwd) }),
|
|
2467
|
+
usageWords ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "shrink-0", title: usageTitle, children: [
|
|
2220
2468
|
"\xB7 ",
|
|
2221
2469
|
usageWords
|
|
2222
2470
|
] }) : null
|
|
2223
2471
|
] })
|
|
2224
2472
|
] }),
|
|
2225
|
-
/* @__PURE__ */ (0,
|
|
2473
|
+
session.agent ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AgentChip, { agent: session.agent }) : null,
|
|
2474
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2226
2475
|
"button",
|
|
2227
2476
|
{
|
|
2228
2477
|
type: "button",
|
|
2229
|
-
className: (0,
|
|
2478
|
+
className: (0, import_design_system6.cn)("cs-chip-button", changesOpen && "cs-chip-button--on"),
|
|
2230
2479
|
onClick: () => setChangesOpen(!changesOpen),
|
|
2231
2480
|
"aria-pressed": changesOpen,
|
|
2232
2481
|
title: "Files this chat changed",
|
|
2233
2482
|
children: [
|
|
2234
|
-
/* @__PURE__ */ (0,
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FileIcon, { size: 13 }),
|
|
2235
2484
|
files.length > 0 ? `${files.length} ${files.length === 1 ? "file" : "files"} changed` : "Changes"
|
|
2236
2485
|
]
|
|
2237
2486
|
}
|
|
2238
2487
|
),
|
|
2239
|
-
/* @__PURE__ */ (0,
|
|
2240
|
-
live ? /* @__PURE__ */ (0,
|
|
2241
|
-
stopping ? /* @__PURE__ */ (0,
|
|
2488
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RunPill, { run }),
|
|
2489
|
+
live ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.Button, { variant: "outline", size: "sm", onClick: () => void stop(), disabled: stopping, className: "gap-1.5", title: "Stop Esc", children: [
|
|
2490
|
+
stopping ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StopIcon, { size: 13 }),
|
|
2242
2491
|
stopping ? "Stopping\u2026" : "Stop"
|
|
2243
2492
|
] }) : null,
|
|
2244
|
-
/* @__PURE__ */ (0,
|
|
2493
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderMenu, { entry, onRename: () => setRenaming(true) })
|
|
2245
2494
|
] }),
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2247
|
-
/* @__PURE__ */ (0,
|
|
2248
|
-
/* @__PURE__ */ (0,
|
|
2495
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mx-chat flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react9.ChatProvider, { thread: transcript.thread, ports: { notifier, toolLabel: friendlyToolName }, children: [
|
|
2496
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "min-h-0 flex-1 overflow-hidden", children: transcript.state.loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex h-full items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
|
|
2497
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 15 }),
|
|
2249
2498
|
" Loading the conversation\u2026"
|
|
2250
|
-
] }) : /* @__PURE__ */ (0,
|
|
2251
|
-
transcript.state.unavailable ? /* @__PURE__ */ (0,
|
|
2252
|
-
transcript.state.truncated ? /* @__PURE__ */ (0,
|
|
2499
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex h-full flex-col", children: [
|
|
2500
|
+
transcript.state.unavailable ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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,
|
|
2501
|
+
transcript.state.truncated ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2253
2502
|
LongChatNote,
|
|
2254
2503
|
{
|
|
2255
2504
|
loading: transcript.state.loadingEarlier === true,
|
|
2256
2505
|
onEarlier: () => void transcript.loadEarlier()
|
|
2257
2506
|
}
|
|
2258
2507
|
) : null,
|
|
2259
|
-
messages.length === 0 && !live ? /* @__PURE__ */ (0,
|
|
2508
|
+
messages.length === 0 && !live ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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__ */ (0, import_jsx_runtime7.jsx)(import_react9.ChatMessageList, { className: "min-h-0 flex-1", label: `Conversation: ${entry.title}` })
|
|
2260
2509
|
] }) }),
|
|
2261
|
-
/* @__PURE__ */ (0,
|
|
2262
|
-
limited ? /* @__PURE__ */ (0,
|
|
2263
|
-
/* @__PURE__ */ (0,
|
|
2264
|
-
/* @__PURE__ */ (0,
|
|
2510
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mx-auto w-full max-w-[820px] px-4 pb-4", children: [
|
|
2511
|
+
limited ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("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: [
|
|
2512
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2513
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
2265
2514
|
limited.problem,
|
|
2266
2515
|
" ",
|
|
2267
2516
|
limited.fix
|
|
2268
2517
|
] })
|
|
2269
2518
|
] }) : null,
|
|
2270
|
-
blocked ? /* @__PURE__ */ (0,
|
|
2271
|
-
|
|
2272
|
-
|
|
2519
|
+
modelRefused && !blocked ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2520
|
+
"div",
|
|
2521
|
+
{
|
|
2522
|
+
className: "mb-2 flex items-center gap-2 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-[12.5px]",
|
|
2523
|
+
role: "alert",
|
|
2524
|
+
children: [
|
|
2525
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 15, className: "shrink-0 text-warning" }),
|
|
2526
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "min-w-0 flex-1 truncate", title: run?.error ?? void 0, children: MODEL_UNAVAILABLE_LABEL }),
|
|
2527
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2528
|
+
ModelPicker,
|
|
2529
|
+
{
|
|
2530
|
+
status: provider,
|
|
2531
|
+
value: { model: session.model, effort: session.effort ?? null },
|
|
2532
|
+
onChange: setOptions
|
|
2533
|
+
}
|
|
2534
|
+
)
|
|
2535
|
+
]
|
|
2536
|
+
}
|
|
2537
|
+
) : null,
|
|
2538
|
+
blocked ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("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: [
|
|
2539
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2540
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
2273
2541
|
blocked.problem,
|
|
2274
2542
|
" ",
|
|
2275
2543
|
blocked.fix
|
|
2276
2544
|
] })
|
|
2277
2545
|
] }) : null,
|
|
2278
|
-
/* @__PURE__ */ (0,
|
|
2279
|
-
/* @__PURE__ */ (0,
|
|
2280
|
-
/* @__PURE__ */ (0,
|
|
2281
|
-
/* @__PURE__ */ (0,
|
|
2546
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "cs-activity", role: "status", "aria-live": "polite", "data-idle": live ? void 0 : true, children: live ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
2547
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 13 }),
|
|
2548
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate", children: run?.status === "starting" ? `Starting ${PROVIDER_LABEL[session.provider]}\u2026` : transcript.activity ?? "Thinking\u2026" }),
|
|
2549
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ml-auto shrink-0 text-[11px] opacity-70", children: "Esc to stop" })
|
|
2282
2550
|
] }) : null }),
|
|
2283
|
-
elsewhere ? /* @__PURE__ */ (0,
|
|
2284
|
-
/* @__PURE__ */ (0,
|
|
2285
|
-
/* @__PURE__ */ (0,
|
|
2551
|
+
elsewhere ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("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: [
|
|
2552
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2553
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
2286
2554
|
elsewhere.message,
|
|
2287
2555
|
" A message sent here would put a second agent on the same chat."
|
|
2288
2556
|
] })
|
|
2289
2557
|
] }) : null,
|
|
2290
|
-
session.queued.length > 0 ? /* @__PURE__ */ (0,
|
|
2291
|
-
/* @__PURE__ */ (0,
|
|
2292
|
-
/* @__PURE__ */ (0,
|
|
2558
|
+
session.queued.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { className: "mb-2 space-y-1.5", "aria-label": "Queued messages", children: session.queued.map((text, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("li", { className: "cs-queued", children: [
|
|
2559
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "cs-queued__label", children: "Queued \xB7 sends when this run finishes" }),
|
|
2560
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "cs-queued__text", children: text })
|
|
2293
2561
|
] }, `${index}-${text.slice(0, 16)}`)) }) : null,
|
|
2294
|
-
/* @__PURE__ */ (0,
|
|
2295
|
-
|
|
2562
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2563
|
+
import_react9.ChatComposer,
|
|
2296
2564
|
{
|
|
2297
2565
|
placeholder: `Message ${PROVIDER_LABEL[session.provider]}\u2026`,
|
|
2298
2566
|
autoFocus: true,
|
|
@@ -2302,14 +2570,14 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2302
2570
|
] })
|
|
2303
2571
|
] }) })
|
|
2304
2572
|
] }),
|
|
2305
|
-
changesOpen ? /* @__PURE__ */ (0,
|
|
2573
|
+
changesOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChangesPanel, { files, cwd: session.cwd, truncated: transcript.state.truncated, onClose: () => setChangesOpen(false) }) : null
|
|
2306
2574
|
] });
|
|
2307
2575
|
}
|
|
2308
2576
|
function usePreviewThread(id, onSend) {
|
|
2309
|
-
const ref = (0,
|
|
2310
|
-
const send = (0,
|
|
2577
|
+
const ref = (0, import_react8.useRef)({ messages: [], listeners: /* @__PURE__ */ new Set() });
|
|
2578
|
+
const send = (0, import_react8.useRef)(onSend);
|
|
2311
2579
|
send.current = onSend;
|
|
2312
|
-
const thread = (0,
|
|
2580
|
+
const thread = (0, import_react8.useMemo)(
|
|
2313
2581
|
() => (0, import_external_store2.createExternalThreadSource)({
|
|
2314
2582
|
getSnapshot: () => ({ messages: ref.current.messages, status: "idle", conversationId: id }),
|
|
2315
2583
|
subscribe: (listener) => {
|
|
@@ -2323,7 +2591,7 @@ function usePreviewThread(id, onSend) {
|
|
|
2323
2591
|
}),
|
|
2324
2592
|
[id]
|
|
2325
2593
|
);
|
|
2326
|
-
const set = (0,
|
|
2594
|
+
const set = (0, import_react8.useCallback)((messages) => {
|
|
2327
2595
|
ref.current.messages = messages;
|
|
2328
2596
|
for (const listener of ref.current.listeners) listener();
|
|
2329
2597
|
}, []);
|
|
@@ -2332,15 +2600,15 @@ function usePreviewThread(id, onSend) {
|
|
|
2332
2600
|
function DiscoveredView(props) {
|
|
2333
2601
|
const client = useCodingSessionsClient();
|
|
2334
2602
|
const state = useCodingSessionsState();
|
|
2335
|
-
const show = (0,
|
|
2603
|
+
const show = (0, import_react8.useContext)(ToastContext);
|
|
2336
2604
|
const now = useMinuteClock();
|
|
2337
|
-
const [preview, setPreview] = (0,
|
|
2338
|
-
const [busy, setBusy] = (0,
|
|
2339
|
-
const [error, setError] = (0,
|
|
2340
|
-
const [confirming, setConfirming] = (0,
|
|
2341
|
-
const [renaming, setRenaming] = (0,
|
|
2342
|
-
const [maxBytes, setMaxBytes] = (0,
|
|
2343
|
-
const [readingEarlier, setReadingEarlier] = (0,
|
|
2605
|
+
const [preview, setPreview] = (0, import_react8.useState)({ loading: true, messages: [], unavailable: null, truncated: false });
|
|
2606
|
+
const [busy, setBusy] = (0, import_react8.useState)(false);
|
|
2607
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
2608
|
+
const [confirming, setConfirming] = (0, import_react8.useState)(false);
|
|
2609
|
+
const [renaming, setRenaming] = (0, import_react8.useState)(false);
|
|
2610
|
+
const [maxBytes, setMaxBytes] = (0, import_react8.useState)(void 0);
|
|
2611
|
+
const [readingEarlier, setReadingEarlier] = (0, import_react8.useState)(false);
|
|
2344
2612
|
const elsewhere = useLiveElsewhere(props.provider, props.id, props.session?.activeElsewhere ?? null);
|
|
2345
2613
|
const files = useChangedFiles(preview.messages);
|
|
2346
2614
|
const d = props.session;
|
|
@@ -2350,7 +2618,7 @@ function DiscoveredView(props) {
|
|
|
2350
2618
|
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."
|
|
2351
2619
|
)
|
|
2352
2620
|
);
|
|
2353
|
-
(0,
|
|
2621
|
+
(0, import_react8.useEffect)(() => {
|
|
2354
2622
|
let cancelled = false;
|
|
2355
2623
|
const read = (first) => client.readPreview(props.provider, props.id, maxBytes).then((next) => {
|
|
2356
2624
|
if (cancelled) return;
|
|
@@ -2389,26 +2657,26 @@ function DiscoveredView(props) {
|
|
|
2389
2657
|
setBusy(false);
|
|
2390
2658
|
}
|
|
2391
2659
|
};
|
|
2392
|
-
return /* @__PURE__ */ (0,
|
|
2393
|
-
/* @__PURE__ */ (0,
|
|
2394
|
-
/* @__PURE__ */ (0,
|
|
2395
|
-
/* @__PURE__ */ (0,
|
|
2396
|
-
/* @__PURE__ */ (0,
|
|
2397
|
-
/* @__PURE__ */ (0,
|
|
2398
|
-
/* @__PURE__ */ (0,
|
|
2399
|
-
/* @__PURE__ */ (0,
|
|
2400
|
-
d?.cwd ? /* @__PURE__ */ (0,
|
|
2401
|
-
/* @__PURE__ */ (0,
|
|
2402
|
-
/* @__PURE__ */ (0,
|
|
2403
|
-
/* @__PURE__ */ (0,
|
|
2660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 flex-1", children: [
|
|
2661
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "flex min-w-0 flex-1 flex-col", "aria-label": entry.title, children: [
|
|
2662
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { className: "flex flex-wrap items-center gap-2 border-b border-border px-5 pt-2.5 pb-2.5", children: [
|
|
2663
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProviderMark, { provider: props.provider, size: 22 }),
|
|
2664
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
2665
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderTitle, { entry, renaming, setRenaming }),
|
|
2666
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "flex items-center gap-1.5 truncate text-[12px] leading-4 text-muted-foreground", children: [
|
|
2667
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: PROVIDER_LABEL[props.provider] }),
|
|
2668
|
+
d?.cwd ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
2669
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
2670
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FolderIcon, { size: 12 }),
|
|
2671
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate", title: d.cwd, children: prettyPath2(d.cwd) })
|
|
2404
2672
|
] }) : null,
|
|
2405
|
-
d ? /* @__PURE__ */ (0,
|
|
2673
|
+
d ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
2406
2674
|
"\xB7 last active ",
|
|
2407
2675
|
relativeTime(d.updatedAt, now)
|
|
2408
2676
|
] }) : null
|
|
2409
2677
|
] })
|
|
2410
2678
|
] }),
|
|
2411
|
-
files.length > 0 ? /* @__PURE__ */ (0,
|
|
2679
|
+
files.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2412
2680
|
"button",
|
|
2413
2681
|
{
|
|
2414
2682
|
type: "button",
|
|
@@ -2417,13 +2685,13 @@ function DiscoveredView(props) {
|
|
|
2417
2685
|
"aria-pressed": props.changesOpen,
|
|
2418
2686
|
title: "Files this chat changed",
|
|
2419
2687
|
children: [
|
|
2420
|
-
/* @__PURE__ */ (0,
|
|
2688
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FileIcon, { size: 13 }),
|
|
2421
2689
|
`${files.length} ${files.length === 1 ? "file" : "files"} changed`
|
|
2422
2690
|
]
|
|
2423
2691
|
}
|
|
2424
2692
|
) : null,
|
|
2425
|
-
d?.cwd ? /* @__PURE__ */ (0,
|
|
2426
|
-
|
|
2693
|
+
d?.cwd ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2694
|
+
import_design_system6.Button,
|
|
2427
2695
|
{
|
|
2428
2696
|
size: "sm",
|
|
2429
2697
|
variant: elsewhere ? "outline" : "default",
|
|
@@ -2432,44 +2700,44 @@ function DiscoveredView(props) {
|
|
|
2432
2700
|
className: "gap-1.5",
|
|
2433
2701
|
title: elsewhere ? elsewhere.message : void 0,
|
|
2434
2702
|
children: [
|
|
2435
|
-
busy ? /* @__PURE__ */ (0,
|
|
2703
|
+
busy ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 13 }) : elsewhere ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 14, className: "text-warning" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HandoffIcon, { size: 14 }),
|
|
2436
2704
|
elsewhere ? "Take over anyway\u2026" : "Take over"
|
|
2437
2705
|
]
|
|
2438
2706
|
}
|
|
2439
2707
|
) : null,
|
|
2440
|
-
d ? /* @__PURE__ */ (0,
|
|
2708
|
+
d ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderMenu, { entry, onRename: () => setRenaming(true) }) : null
|
|
2441
2709
|
] }),
|
|
2442
|
-
elsewhere ? /* @__PURE__ */ (0,
|
|
2443
|
-
/* @__PURE__ */ (0,
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
2445
|
-
/* @__PURE__ */ (0,
|
|
2710
|
+
elsewhere ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("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: [
|
|
2711
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 15, className: "mt-0.5 shrink-0 text-warning" }),
|
|
2712
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
2713
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "font-medium", children: elsewhere.message }),
|
|
2446
2714
|
" 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."
|
|
2447
2715
|
] })
|
|
2448
2716
|
] }) : null,
|
|
2449
|
-
/* @__PURE__ */ (0,
|
|
2450
|
-
/* @__PURE__ */ (0,
|
|
2451
|
-
/* @__PURE__ */ (0,
|
|
2717
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.Dialog, { open: confirming, onOpenChange: setConfirming, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogContent, { className: "max-w-[460px]", children: [
|
|
2718
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogHeader, { children: [
|
|
2719
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogTitle, { children: [
|
|
2452
2720
|
"This chat is running right now in ",
|
|
2453
2721
|
PROVIDER_LABEL[props.provider]
|
|
2454
2722
|
] }),
|
|
2455
|
-
/* @__PURE__ */ (0,
|
|
2723
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogDescription, { children: [
|
|
2456
2724
|
elsewhere?.message,
|
|
2457
2725
|
" If you take it over, two agents will work in the same conversation at once and may overwrite each other's changes."
|
|
2458
2726
|
] })
|
|
2459
2727
|
] }),
|
|
2460
|
-
/* @__PURE__ */ (0,
|
|
2461
|
-
/* @__PURE__ */ (0,
|
|
2462
|
-
/* @__PURE__ */ (0,
|
|
2728
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogFooter, { children: [
|
|
2729
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.Button, { variant: "ghost", onClick: () => setConfirming(false), children: "Cancel" }),
|
|
2730
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.Button, { variant: "destructive", onClick: () => void takeover(), children: "Take over anyway" })
|
|
2463
2731
|
] })
|
|
2464
2732
|
] }) }),
|
|
2465
|
-
error ? /* @__PURE__ */ (0,
|
|
2466
|
-
d && !d.cwd ? /* @__PURE__ */ (0,
|
|
2467
|
-
/* @__PURE__ */ (0,
|
|
2468
|
-
preview.loading ? /* @__PURE__ */ (0,
|
|
2469
|
-
/* @__PURE__ */ (0,
|
|
2733
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "border-b border-destructive/30 bg-destructive/10 px-5 py-2 text-[13px] text-destructive", children: error }) : null,
|
|
2734
|
+
d && !d.cwd ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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,
|
|
2735
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mx-chat flex min-h-0 flex-1 flex-col", children: [
|
|
2736
|
+
preview.loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
|
|
2737
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 15 }),
|
|
2470
2738
|
" Reading this chat\u2026"
|
|
2471
|
-
] }) : preview.unavailable ? /* @__PURE__ */ (0,
|
|
2472
|
-
preview.truncated ? /* @__PURE__ */ (0,
|
|
2739
|
+
] }) : preview.unavailable ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex flex-1 items-center justify-center px-6 text-center text-[13px] text-muted-foreground", children: preview.unavailable }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react9.ChatProvider, { thread, ports: { notifier, toolLabel: friendlyToolName }, children: [
|
|
2740
|
+
preview.truncated ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2473
2741
|
LongChatNote,
|
|
2474
2742
|
{
|
|
2475
2743
|
loading: readingEarlier,
|
|
@@ -2479,14 +2747,14 @@ function DiscoveredView(props) {
|
|
|
2479
2747
|
}
|
|
2480
2748
|
}
|
|
2481
2749
|
) : null,
|
|
2482
|
-
/* @__PURE__ */ (0,
|
|
2750
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react9.ChatMessageList, { className: "min-h-0 flex-1", label: "Chat preview" })
|
|
2483
2751
|
] }),
|
|
2484
|
-
d?.cwd ? /* @__PURE__ */ (0,
|
|
2752
|
+
d?.cwd ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "border-t border-border bg-muted/30 px-5 py-3 text-center text-[13px] text-muted-foreground", children: [
|
|
2485
2753
|
"This chat was started in ",
|
|
2486
2754
|
PROVIDER_LABEL[props.provider],
|
|
2487
2755
|
".",
|
|
2488
2756
|
" ",
|
|
2489
|
-
/* @__PURE__ */ (0,
|
|
2757
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "font-medium text-foreground underline-offset-4 hover:underline", onClick: requestTakeover, children: "Take it over" }),
|
|
2490
2758
|
" ",
|
|
2491
2759
|
"to continue it here \u2014 it stays in your ",
|
|
2492
2760
|
PROVIDER_LABEL[props.provider],
|
|
@@ -2494,70 +2762,73 @@ function DiscoveredView(props) {
|
|
|
2494
2762
|
] }) : null
|
|
2495
2763
|
] })
|
|
2496
2764
|
] }),
|
|
2497
|
-
props.changesOpen && files.length > 0 ? /* @__PURE__ */ (0,
|
|
2765
|
+
props.changesOpen && files.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChangesPanel, { files, cwd: d?.cwd ?? null, truncated: preview.truncated, onClose: () => props.setChangesOpen(false) }) : null
|
|
2498
2766
|
] });
|
|
2499
2767
|
}
|
|
2500
2768
|
function ProviderCard(props) {
|
|
2501
2769
|
const ready = props.status.ready;
|
|
2502
|
-
return /* @__PURE__ */ (0,
|
|
2770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2503
2771
|
"button",
|
|
2504
2772
|
{
|
|
2505
2773
|
type: "button",
|
|
2506
2774
|
onClick: props.onSelect,
|
|
2507
2775
|
"aria-pressed": props.selected,
|
|
2508
|
-
className: (0,
|
|
2776
|
+
className: (0, import_design_system6.cn)(
|
|
2509
2777
|
"flex flex-1 flex-col gap-1.5 rounded-xl border px-3.5 py-3 text-left transition-colors",
|
|
2510
2778
|
props.selected ? "border-primary bg-primary/5 ring-1 ring-primary" : "border-border hover:bg-accent/50"
|
|
2511
2779
|
),
|
|
2512
2780
|
children: [
|
|
2513
|
-
/* @__PURE__ */ (0,
|
|
2514
|
-
/* @__PURE__ */ (0,
|
|
2515
|
-
/* @__PURE__ */ (0,
|
|
2781
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
2782
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProviderMark, { provider: props.status.provider, size: 18 }),
|
|
2783
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-[13.5px] font-semibold", children: props.status.label })
|
|
2516
2784
|
] }),
|
|
2517
|
-
ready ? /* @__PURE__ */ (0,
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
2785
|
+
ready ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex items-center gap-1 text-[12px] text-success", children: [
|
|
2786
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, { size: 13 }),
|
|
2519
2787
|
props.status.billing === "subscription" ? `Signed in${props.status.plan ? ` \xB7 ${props.status.plan} plan` : ""}` : "Signed in with an API key (billed per use)"
|
|
2520
|
-
] }) : /* @__PURE__ */ (0,
|
|
2521
|
-
/* @__PURE__ */ (0,
|
|
2788
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex items-start gap-1 text-[12px] leading-4 text-warning", children: [
|
|
2789
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 13, className: "mt-px shrink-0" }),
|
|
2522
2790
|
props.status.problem
|
|
2523
2791
|
] }),
|
|
2524
|
-
props.status.quota.filter((w) => w.usedPercent !== null).length > 0 ? /* @__PURE__ */ (0,
|
|
2792
|
+
props.status.quota.filter((w) => w.usedPercent !== null).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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
|
|
2525
2793
|
]
|
|
2526
2794
|
}
|
|
2527
2795
|
);
|
|
2528
2796
|
}
|
|
2529
2797
|
function FieldError({ id, children }) {
|
|
2530
|
-
return /* @__PURE__ */ (0,
|
|
2531
|
-
/* @__PURE__ */ (0,
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { id, role: "alert", className: "flex items-start gap-1.5 text-[12.5px] leading-5 text-destructive", children: [
|
|
2799
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 14, className: "mt-0.5 shrink-0" }),
|
|
2800
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children })
|
|
2533
2801
|
] });
|
|
2534
2802
|
}
|
|
2535
2803
|
function NewSessionDialog(props) {
|
|
2536
2804
|
const client = useCodingSessionsClient();
|
|
2537
2805
|
const state = useCodingSessionsState();
|
|
2538
2806
|
const now = useMinuteClock();
|
|
2539
|
-
const [provider, setProvider] = (0,
|
|
2540
|
-
const [folder, setFolder] = (0,
|
|
2541
|
-
const [choice, setChoice] = (0,
|
|
2542
|
-
const [prompt, setPrompt] = (0,
|
|
2543
|
-
const [errors, setErrors] = (0,
|
|
2544
|
-
const [problem, setProblem] = (0,
|
|
2545
|
-
const [starting, setStarting] = (0,
|
|
2546
|
-
const [creating, setCreating] = (0,
|
|
2547
|
-
const
|
|
2548
|
-
const
|
|
2549
|
-
const
|
|
2550
|
-
(0,
|
|
2807
|
+
const [provider, setProvider] = (0, import_react8.useState)("claude");
|
|
2808
|
+
const [folder, setFolder] = (0, import_react8.useState)("");
|
|
2809
|
+
const [choice, setChoice] = (0, import_react8.useState)({ model: null, effort: null });
|
|
2810
|
+
const [prompt, setPrompt] = (0, import_react8.useState)("");
|
|
2811
|
+
const [errors, setErrors] = (0, import_react8.useState)({});
|
|
2812
|
+
const [problem, setProblem] = (0, import_react8.useState)(null);
|
|
2813
|
+
const [starting, setStarting] = (0, import_react8.useState)(false);
|
|
2814
|
+
const [creating, setCreating] = (0, import_react8.useState)(false);
|
|
2815
|
+
const [agent, setAgent] = (0, import_react8.useState)(null);
|
|
2816
|
+
const [agentDetails, setAgentDetails] = (0, import_react8.useState)(null);
|
|
2817
|
+
const [agentMissing, setAgentMissing] = (0, import_react8.useState)(null);
|
|
2818
|
+
const promptRef = (0, import_react8.useRef)(null);
|
|
2819
|
+
const folderRef = (0, import_react8.useRef)(null);
|
|
2820
|
+
const agentRef = (0, import_react8.useRef)(null);
|
|
2821
|
+
(0, import_react8.useEffect)(() => {
|
|
2551
2822
|
if (!props.open) return;
|
|
2552
2823
|
setProblem(null);
|
|
2553
2824
|
setErrors({});
|
|
2554
2825
|
void client.refreshProviders();
|
|
2555
2826
|
void client.refreshFolders();
|
|
2556
2827
|
}, [props.open, client]);
|
|
2557
|
-
(0,
|
|
2828
|
+
(0, import_react8.useEffect)(() => {
|
|
2558
2829
|
if (!folder && state.folders.data[0]?.exists) setFolder(state.folders.data[0].path);
|
|
2559
2830
|
}, [state.folders.data, folder]);
|
|
2560
|
-
(0,
|
|
2831
|
+
(0, import_react8.useEffect)(() => {
|
|
2561
2832
|
const ready = state.providers.data.filter((p) => p.ready);
|
|
2562
2833
|
const current = state.providers.data.find((p) => p.provider === provider);
|
|
2563
2834
|
if (current && !current.ready && ready[0]) setProvider(ready[0].provider);
|
|
@@ -2583,9 +2854,22 @@ function NewSessionDialog(props) {
|
|
|
2583
2854
|
focusField(first);
|
|
2584
2855
|
return;
|
|
2585
2856
|
}
|
|
2857
|
+
const missing = missingRequiredVariable(agentDetails, agent);
|
|
2858
|
+
setAgentMissing(missing);
|
|
2859
|
+
if (missing) {
|
|
2860
|
+
document.getElementById(`cs-agent-var-${missing}`)?.focus();
|
|
2861
|
+
return;
|
|
2862
|
+
}
|
|
2586
2863
|
setStarting(true);
|
|
2587
2864
|
try {
|
|
2588
|
-
const result = await client.start({
|
|
2865
|
+
const result = await client.start({
|
|
2866
|
+
provider,
|
|
2867
|
+
cwd: folder.trim(),
|
|
2868
|
+
prompt,
|
|
2869
|
+
model: choice.model,
|
|
2870
|
+
effort: choice.effort,
|
|
2871
|
+
...agent ? { agent } : {}
|
|
2872
|
+
});
|
|
2589
2873
|
setPrompt("");
|
|
2590
2874
|
props.onStarted(result.session.id);
|
|
2591
2875
|
} catch (error) {
|
|
@@ -2621,16 +2905,16 @@ function NewSessionDialog(props) {
|
|
|
2621
2905
|
if (field === "folder") delete next.createFolder;
|
|
2622
2906
|
return next;
|
|
2623
2907
|
});
|
|
2624
|
-
return /* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2626
|
-
/* @__PURE__ */ (0,
|
|
2627
|
-
/* @__PURE__ */ (0,
|
|
2908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.Dialog, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogContent, { className: "max-w-[560px]", children: [
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogHeader, { children: [
|
|
2910
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.DialogTitle, { children: "New coding session" }),
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogDescription, { children: [
|
|
2628
2912
|
"Runs on your own ",
|
|
2629
2913
|
provider === "claude" ? "Claude" : "ChatGPT",
|
|
2630
2914
|
" sign-in, in a folder on this computer."
|
|
2631
2915
|
] })
|
|
2632
2916
|
] }),
|
|
2633
|
-
/* @__PURE__ */ (0,
|
|
2917
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2634
2918
|
"form",
|
|
2635
2919
|
{
|
|
2636
2920
|
noValidate: true,
|
|
@@ -2640,13 +2924,13 @@ function NewSessionDialog(props) {
|
|
|
2640
2924
|
},
|
|
2641
2925
|
className: "flex min-h-0 flex-col",
|
|
2642
2926
|
children: [
|
|
2643
|
-
/* @__PURE__ */ (0,
|
|
2644
|
-
/* @__PURE__ */ (0,
|
|
2645
|
-
/* @__PURE__ */ (0,
|
|
2646
|
-
state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ (0,
|
|
2647
|
-
/* @__PURE__ */ (0,
|
|
2648
|
-
/* @__PURE__ */ (0,
|
|
2649
|
-
] }) : state.providers.error ? /* @__PURE__ */ (0,
|
|
2927
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "cs-dialog-body space-y-5 py-1 pr-1", children: [
|
|
2928
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("fieldset", { className: "space-y-2", ref: agentRef, children: [
|
|
2929
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Agent" }),
|
|
2930
|
+
state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex gap-2", children: [
|
|
2931
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" }),
|
|
2932
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "cs-skeleton h-[68px] flex-1 rounded-xl" })
|
|
2933
|
+
] }) : state.providers.error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-[12.5px] text-destructive", children: state.providers.error }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex gap-2", children: state.providers.data.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2650
2934
|
ProviderCard,
|
|
2651
2935
|
{
|
|
2652
2936
|
status: p,
|
|
@@ -2659,14 +2943,31 @@ function NewSessionDialog(props) {
|
|
|
2659
2943
|
},
|
|
2660
2944
|
p.provider
|
|
2661
2945
|
)) }),
|
|
2662
|
-
errors.agent ? /* @__PURE__ */ (0,
|
|
2946
|
+
errors.agent ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldError, { id: "cs-err-agent", children: errors.agent }) : selected && !selected.ready && selected.fix ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "text-[12px] leading-4 text-muted-foreground", children: [
|
|
2663
2947
|
selected.fix,
|
|
2664
2948
|
selected.installed && selected.loggedIn ? " You can still try \u2014 the run will say if it's still blocked." : ""
|
|
2665
2949
|
] }) : null
|
|
2666
2950
|
] }),
|
|
2667
|
-
/* @__PURE__ */ (0,
|
|
2668
|
-
/* @__PURE__ */ (0,
|
|
2669
|
-
|
|
2951
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("fieldset", { className: "space-y-2", children: [
|
|
2952
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("legend", { className: "mb-2 text-[12.5px] font-medium", children: "AI Matrx agent" }),
|
|
2953
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2954
|
+
AgentField,
|
|
2955
|
+
{
|
|
2956
|
+
transport: client.transport,
|
|
2957
|
+
open: props.open,
|
|
2958
|
+
value: agent,
|
|
2959
|
+
onChange: (next) => {
|
|
2960
|
+
setAgent(next);
|
|
2961
|
+
setAgentMissing(null);
|
|
2962
|
+
},
|
|
2963
|
+
missing: agentMissing,
|
|
2964
|
+
onDetails: setAgentDetails
|
|
2965
|
+
}
|
|
2966
|
+
)
|
|
2967
|
+
] }),
|
|
2968
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("fieldset", { className: "space-y-2", children: [
|
|
2969
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Folder" }),
|
|
2970
|
+
state.folders.data.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2670
2971
|
"button",
|
|
2671
2972
|
{
|
|
2672
2973
|
type: "button",
|
|
@@ -2676,21 +2977,21 @@ function NewSessionDialog(props) {
|
|
|
2676
2977
|
},
|
|
2677
2978
|
disabled: !f.exists,
|
|
2678
2979
|
title: f.exists ? f.path : `${f.path} no longer exists`,
|
|
2679
|
-
className: (0,
|
|
2980
|
+
className: (0, import_design_system6.cn)(
|
|
2680
2981
|
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[12.5px]",
|
|
2681
2982
|
folder === f.path ? "bg-accent text-accent-foreground" : "hover:bg-accent/50",
|
|
2682
2983
|
!f.exists && "opacity-50"
|
|
2683
2984
|
),
|
|
2684
2985
|
children: [
|
|
2685
|
-
/* @__PURE__ */ (0,
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2687
|
-
/* @__PURE__ */ (0,
|
|
2986
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FolderIcon, { size: 14, className: "shrink-0 text-muted-foreground" }),
|
|
2987
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "min-w-0 flex-1 truncate", children: prettyPath2(f.path) }),
|
|
2988
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: f.exists ? relativeTime(f.lastUsedAt, now) : "missing" })
|
|
2688
2989
|
]
|
|
2689
2990
|
},
|
|
2690
2991
|
f.path
|
|
2691
|
-
)) }) : state.folders.loading ? /* @__PURE__ */ (0,
|
|
2692
|
-
/* @__PURE__ */ (0,
|
|
2693
|
-
|
|
2992
|
+
)) }) : state.folders.loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "cs-skeleton h-10 rounded-lg" }) : null,
|
|
2993
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2994
|
+
import_design_system6.Input,
|
|
2694
2995
|
{
|
|
2695
2996
|
ref: folderRef,
|
|
2696
2997
|
value: folder,
|
|
@@ -2705,18 +3006,18 @@ function NewSessionDialog(props) {
|
|
|
2705
3006
|
spellCheck: false
|
|
2706
3007
|
}
|
|
2707
3008
|
),
|
|
2708
|
-
errors.folder ? /* @__PURE__ */ (0,
|
|
2709
|
-
/* @__PURE__ */ (0,
|
|
2710
|
-
errors.createFolder ? /* @__PURE__ */ (0,
|
|
2711
|
-
creating ? /* @__PURE__ */ (0,
|
|
3009
|
+
errors.folder ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1", children: [
|
|
3010
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldError, { id: "cs-err-folder", children: errors.folder }),
|
|
3011
|
+
errors.createFolder ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.Button, { type: "button", size: "sm", variant: "outline", onClick: () => void createFolder(), disabled: creating, className: "gap-1.5", children: [
|
|
3012
|
+
creating ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FolderIcon, { size: 13 }),
|
|
2712
3013
|
"Create this folder"
|
|
2713
3014
|
] }) : null
|
|
2714
3015
|
] }) : null
|
|
2715
3016
|
] }),
|
|
2716
|
-
/* @__PURE__ */ (0,
|
|
2717
|
-
/* @__PURE__ */ (0,
|
|
2718
|
-
/* @__PURE__ */ (0,
|
|
2719
|
-
|
|
3017
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("fieldset", { className: "space-y-2", children: [
|
|
3018
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("legend", { className: "mb-2 text-[12.5px] font-medium", children: "What should it do?" }),
|
|
3019
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3020
|
+
import_design_system6.Textarea,
|
|
2720
3021
|
{
|
|
2721
3022
|
ref: promptRef,
|
|
2722
3023
|
value: prompt,
|
|
@@ -2737,25 +3038,25 @@ function NewSessionDialog(props) {
|
|
|
2737
3038
|
"aria-describedby": errors.prompt ? "cs-err-prompt" : void 0
|
|
2738
3039
|
}
|
|
2739
3040
|
),
|
|
2740
|
-
errors.prompt ? /* @__PURE__ */ (0,
|
|
3041
|
+
errors.prompt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldError, { id: "cs-err-prompt", children: errors.prompt }) : null
|
|
2741
3042
|
] }),
|
|
2742
|
-
/* @__PURE__ */ (0,
|
|
2743
|
-
/* @__PURE__ */ (0,
|
|
2744
|
-
/* @__PURE__ */ (0,
|
|
2745
|
-
/* @__PURE__ */ (0,
|
|
3043
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("fieldset", { className: "space-y-2", children: [
|
|
3044
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("legend", { className: "mb-2 text-[12.5px] font-medium", children: "Model and thinking effort" }),
|
|
3045
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ModelPicker, { status: selected, value: choice, onChange: setChoice, appearance: "field" }),
|
|
3046
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "text-[11.5px] leading-4 text-muted-foreground", children: [
|
|
2746
3047
|
"Default is ",
|
|
2747
3048
|
defaultModelWords(selected),
|
|
2748
3049
|
". You can change it later from the chat's header."
|
|
2749
3050
|
] })
|
|
2750
3051
|
] }),
|
|
2751
|
-
problem ? /* @__PURE__ */ (0,
|
|
3052
|
+
problem ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldError, { id: "cs-err-start", children: problem }) : null
|
|
2752
3053
|
] }),
|
|
2753
|
-
/* @__PURE__ */ (0,
|
|
2754
|
-
/* @__PURE__ */ (0,
|
|
2755
|
-
/* @__PURE__ */ (0,
|
|
2756
|
-
starting ? /* @__PURE__ */ (0,
|
|
3054
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogFooter, { className: "pt-4", children: [
|
|
3055
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.Button, { type: "button", variant: "ghost", onClick: () => props.onOpenChange(false), children: "Cancel" }),
|
|
3056
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.Button, { type: "submit", disabled: starting, className: "gap-1.5", children: [
|
|
3057
|
+
starting ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 14 }) : null,
|
|
2757
3058
|
starting ? "Starting\u2026" : "Start session",
|
|
2758
|
-
!starting ? /* @__PURE__ */ (0,
|
|
3059
|
+
!starting ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "cs-kbd", children: "\u2318\u21B5" }) : null
|
|
2759
3060
|
] })
|
|
2760
3061
|
] })
|
|
2761
3062
|
]
|
|
@@ -2765,50 +3066,61 @@ function NewSessionDialog(props) {
|
|
|
2765
3066
|
}
|
|
2766
3067
|
function Home({ onNew }) {
|
|
2767
3068
|
const state = useCodingSessionsState();
|
|
2768
|
-
return /* @__PURE__ */ (0,
|
|
2769
|
-
/* @__PURE__ */ (0,
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
2771
|
-
/* @__PURE__ */ (0,
|
|
2772
|
-
/* @__PURE__ */ (0,
|
|
2773
|
-
/* @__PURE__ */ (0,
|
|
3069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("section", { className: "flex flex-1 items-center justify-center px-6", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "w-full max-w-[460px] text-center", children: [
|
|
3070
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mx-auto mb-4 flex h-11 w-11 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChatBubbleIcon, { size: 22 }) }),
|
|
3071
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { className: "text-[15px] font-semibold leading-5 tracking-[-0.01em]", children: "Drive Claude Code and Codex from here" }),
|
|
3072
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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." }),
|
|
3073
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.Button, { className: "mt-5 gap-1.5", onClick: onNew, children: [
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PlusIcon, { size: 15 }),
|
|
2774
3075
|
"New session"
|
|
2775
3076
|
] }),
|
|
2776
|
-
/* @__PURE__ */ (0,
|
|
2777
|
-
/* @__PURE__ */ (0,
|
|
3077
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "mt-3 text-[12px] text-muted-foreground", children: [
|
|
3078
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "cs-kbd", children: "\u2325\u2318N" }),
|
|
2778
3079
|
" new session \xB7 ",
|
|
2779
|
-
/* @__PURE__ */ (0,
|
|
3080
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "cs-kbd", children: "\u2318K" }),
|
|
2780
3081
|
" search your chats \xB7",
|
|
2781
3082
|
" ",
|
|
2782
|
-
/* @__PURE__ */ (0,
|
|
3083
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "cs-kbd", children: "\u2318/" }),
|
|
2783
3084
|
" all shortcuts"
|
|
2784
3085
|
] }),
|
|
2785
|
-
/* @__PURE__ */ (0,
|
|
2786
|
-
/* @__PURE__ */ (0,
|
|
2787
|
-
/* @__PURE__ */ (0,
|
|
2788
|
-
/* @__PURE__ */ (0,
|
|
2789
|
-
p.ready ? /* @__PURE__ */ (0,
|
|
3086
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-[220px] items-start gap-2.5 rounded-lg border border-border px-3 py-2.5", children: [
|
|
3087
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProviderMark, { provider: p.provider, size: 16 }),
|
|
3088
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "min-w-0 flex-1 text-[12.5px] leading-5", children: [
|
|
3089
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "font-medium", children: p.label }),
|
|
3090
|
+
p.ready ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
2790
3091
|
" ",
|
|
2791
3092
|
"\u2014 ready",
|
|
2792
3093
|
p.plan ? ` on your ${p.plan} plan` : "",
|
|
2793
|
-
p.billing === "api" ? " (API key, billed per use)" : ""
|
|
2794
|
-
|
|
2795
|
-
|
|
3094
|
+
p.billing === "api" ? " (API key, billed per use)" : ""
|
|
3095
|
+
] }) : null,
|
|
3096
|
+
p.installed && p.version ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3097
|
+
"span",
|
|
3098
|
+
{
|
|
3099
|
+
className: "block text-[11.5px] text-muted-foreground",
|
|
3100
|
+
title: newerWords(p) ?? p.binary?.path ?? void 0,
|
|
3101
|
+
children: [
|
|
3102
|
+
binaryWords(p),
|
|
3103
|
+
p.binary?.newer ? ` \xB7 ${p.binary.newer.version} available` : ""
|
|
3104
|
+
]
|
|
3105
|
+
}
|
|
3106
|
+
) : null,
|
|
3107
|
+
p.ready ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "block text-muted-foreground", children: [
|
|
2796
3108
|
p.problem,
|
|
2797
3109
|
" ",
|
|
2798
3110
|
p.fix
|
|
2799
3111
|
] })
|
|
2800
3112
|
] }),
|
|
2801
|
-
p.ready ? /* @__PURE__ */ (0,
|
|
3113
|
+
p.ready ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, { size: 15, className: "mt-0.5 text-success" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlertIcon, { size: 15, className: "mt-0.5 text-warning" })
|
|
2802
3114
|
] }, p.provider)) })
|
|
2803
3115
|
] }) });
|
|
2804
3116
|
}
|
|
2805
3117
|
function useToast() {
|
|
2806
|
-
const [text, setText] = (0,
|
|
2807
|
-
const timer = (0,
|
|
2808
|
-
(0,
|
|
3118
|
+
const [text, setText] = (0, import_react8.useState)(null);
|
|
3119
|
+
const timer = (0, import_react8.useRef)(null);
|
|
3120
|
+
(0, import_react8.useEffect)(() => () => {
|
|
2809
3121
|
if (timer.current) clearTimeout(timer.current);
|
|
2810
3122
|
}, []);
|
|
2811
|
-
const show = (0,
|
|
3123
|
+
const show = (0, import_react8.useCallback)((next) => {
|
|
2812
3124
|
setText(next);
|
|
2813
3125
|
if (timer.current) clearTimeout(timer.current);
|
|
2814
3126
|
timer.current = setTimeout(() => setText(null), 6e3);
|
|
@@ -2817,7 +3129,7 @@ function useToast() {
|
|
|
2817
3129
|
}
|
|
2818
3130
|
function Toast({ text }) {
|
|
2819
3131
|
if (!text) return null;
|
|
2820
|
-
return /* @__PURE__ */ (0,
|
|
3132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { role: "status", className: "cs-toast", children: text });
|
|
2821
3133
|
}
|
|
2822
3134
|
var SIDEBAR_DEFAULT = 300;
|
|
2823
3135
|
var SIDEBAR_MIN = 220;
|
|
@@ -2826,7 +3138,7 @@ function clampWidth(n) {
|
|
|
2826
3138
|
return Math.round(Math.min(SIDEBAR_MAX, Math.max(SIDEBAR_MIN, n)));
|
|
2827
3139
|
}
|
|
2828
3140
|
function useSidebarLayout() {
|
|
2829
|
-
const [width, setWidthState] = (0,
|
|
3141
|
+
const [width, setWidthState] = (0, import_react8.useState)(() => {
|
|
2830
3142
|
try {
|
|
2831
3143
|
const n = Number(localStorage.getItem("coding-sessions.sidebar-width"));
|
|
2832
3144
|
return Number.isFinite(n) && n > 0 ? clampWidth(n) : SIDEBAR_DEFAULT;
|
|
@@ -2834,14 +3146,14 @@ function useSidebarLayout() {
|
|
|
2834
3146
|
return SIDEBAR_DEFAULT;
|
|
2835
3147
|
}
|
|
2836
3148
|
});
|
|
2837
|
-
const [collapsed, setCollapsedState] = (0,
|
|
3149
|
+
const [collapsed, setCollapsedState] = (0, import_react8.useState)(() => {
|
|
2838
3150
|
try {
|
|
2839
3151
|
return localStorage.getItem("coding-sessions.sidebar-collapsed") === "1";
|
|
2840
3152
|
} catch {
|
|
2841
3153
|
return false;
|
|
2842
3154
|
}
|
|
2843
3155
|
});
|
|
2844
|
-
const setWidth = (0,
|
|
3156
|
+
const setWidth = (0, import_react8.useCallback)((n) => {
|
|
2845
3157
|
const next = clampWidth(n);
|
|
2846
3158
|
setWidthState(next);
|
|
2847
3159
|
try {
|
|
@@ -2849,7 +3161,7 @@ function useSidebarLayout() {
|
|
|
2849
3161
|
} catch {
|
|
2850
3162
|
}
|
|
2851
3163
|
}, []);
|
|
2852
|
-
const setCollapsed = (0,
|
|
3164
|
+
const setCollapsed = (0, import_react8.useCallback)((v) => {
|
|
2853
3165
|
setCollapsedState(v);
|
|
2854
3166
|
try {
|
|
2855
3167
|
localStorage.setItem("coding-sessions.sidebar-collapsed", v ? "1" : "0");
|
|
@@ -2859,8 +3171,8 @@ function useSidebarLayout() {
|
|
|
2859
3171
|
return { width, setWidth, collapsed, setCollapsed };
|
|
2860
3172
|
}
|
|
2861
3173
|
function Resizer(props) {
|
|
2862
|
-
const [dragging, setDragging] = (0,
|
|
2863
|
-
return /* @__PURE__ */ (0,
|
|
3174
|
+
const [dragging, setDragging] = (0, import_react8.useState)(false);
|
|
3175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: (0, import_design_system6.cn)("cs-resizer", dragging && "cs-resizer--dragging"), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2864
3176
|
"button",
|
|
2865
3177
|
{
|
|
2866
3178
|
type: "button",
|
|
@@ -2908,24 +3220,24 @@ var SHORTCUTS = [
|
|
|
2908
3220
|
{ keys: "\u2318/", what: "These shortcuts" }
|
|
2909
3221
|
];
|
|
2910
3222
|
function ShortcutsDialog(props) {
|
|
2911
|
-
return /* @__PURE__ */ (0,
|
|
2912
|
-
/* @__PURE__ */ (0,
|
|
2913
|
-
/* @__PURE__ */ (0,
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
3223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.Dialog, { open: props.open, onOpenChange: props.onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogContent, { className: "max-w-[420px]", children: [
|
|
3224
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogHeader, { children: [
|
|
3225
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.DialogTitle, { children: "Keyboard shortcuts" }),
|
|
3226
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system6.DialogDescription, { children: "Ctrl works in place of \u2318 on Windows and Linux." })
|
|
2915
3227
|
] }),
|
|
2916
|
-
/* @__PURE__ */ (0,
|
|
2917
|
-
/* @__PURE__ */ (0,
|
|
2918
|
-
/* @__PURE__ */ (0,
|
|
3228
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("dl", { className: "divide-y divide-border text-[13px]", children: SHORTCUTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center justify-between gap-4 py-2", children: [
|
|
3229
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("dt", { className: "text-muted-foreground", children: s.what }),
|
|
3230
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "rounded border border-border px-1.5 py-0.5 font-sans text-[12px]", children: s.keys }) })
|
|
2919
3231
|
] }, s.keys)) })
|
|
2920
3232
|
] }) });
|
|
2921
3233
|
}
|
|
2922
3234
|
var BASE_TITLE = "Coding sessions";
|
|
2923
3235
|
function useRunFinishedNotices(openSessionId, show) {
|
|
2924
3236
|
const client = useCodingSessionsClient();
|
|
2925
|
-
const unseen = (0,
|
|
2926
|
-
const openRef = (0,
|
|
3237
|
+
const unseen = (0, import_react8.useRef)(0);
|
|
3238
|
+
const openRef = (0, import_react8.useRef)(openSessionId);
|
|
2927
3239
|
openRef.current = openSessionId;
|
|
2928
|
-
(0,
|
|
3240
|
+
(0, import_react8.useEffect)(() => {
|
|
2929
3241
|
const reset = () => {
|
|
2930
3242
|
if (document.visibilityState === "visible") {
|
|
2931
3243
|
unseen.current = 0;
|
|
@@ -2941,7 +3253,7 @@ function useRunFinishedNotices(openSessionId, show) {
|
|
|
2941
3253
|
unseen.current += 1;
|
|
2942
3254
|
document.title = `(${unseen.current}) ${BASE_TITLE}`;
|
|
2943
3255
|
if (typeof Notification !== "undefined" && Notification.permission === "granted") {
|
|
2944
|
-
const note = new Notification(sentence, run.error ? { tag: run.runId, body: run.error } : { tag: run.runId });
|
|
3256
|
+
const note = new Notification(sentence, run.error ? { tag: run.runId, body: runErrorLabel(run.error) } : { tag: run.runId });
|
|
2945
3257
|
note.onclick = () => {
|
|
2946
3258
|
window.focus();
|
|
2947
3259
|
location.hash = `#s/${run.sessionId}`;
|
|
@@ -2960,9 +3272,9 @@ function useRunFinishedNotices(openSessionId, show) {
|
|
|
2960
3272
|
}
|
|
2961
3273
|
function NotifyToggle() {
|
|
2962
3274
|
const supported = typeof Notification !== "undefined";
|
|
2963
|
-
const [permission, setPermission] = (0,
|
|
3275
|
+
const [permission, setPermission] = (0, import_react8.useState)(supported ? Notification.permission : "denied");
|
|
2964
3276
|
if (!supported || permission === "granted") return null;
|
|
2965
|
-
return /* @__PURE__ */ (0,
|
|
3277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2966
3278
|
"button",
|
|
2967
3279
|
{
|
|
2968
3280
|
type: "button",
|
|
@@ -2971,7 +3283,7 @@ function NotifyToggle() {
|
|
|
2971
3283
|
"aria-label": permission === "denied" ? "Notifications are blocked for this page in your browser's site settings" : "Notify me when a run finishes",
|
|
2972
3284
|
title: permission === "denied" ? "Notifications are blocked in your browser's site settings" : "Notify me when a run finishes",
|
|
2973
3285
|
disabled: permission === "denied",
|
|
2974
|
-
children: /* @__PURE__ */ (0,
|
|
3286
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BellIcon, { size: 14 })
|
|
2975
3287
|
}
|
|
2976
3288
|
);
|
|
2977
3289
|
}
|
|
@@ -2983,20 +3295,20 @@ function isTyping(target) {
|
|
|
2983
3295
|
function Shell() {
|
|
2984
3296
|
const client = useCodingSessionsClient();
|
|
2985
3297
|
const state = useCodingSessionsState();
|
|
2986
|
-
const [selection, setSelection] = (0,
|
|
2987
|
-
const [newOpen, setNewOpen] = (0,
|
|
2988
|
-
const [shortcutsOpen, setShortcutsOpen] = (0,
|
|
2989
|
-
const [changesOpen, setChangesOpen] = (0,
|
|
2990
|
-
const [found, setFound] = (0,
|
|
3298
|
+
const [selection, setSelection] = (0, import_react8.useState)(readHash);
|
|
3299
|
+
const [newOpen, setNewOpen] = (0, import_react8.useState)(false);
|
|
3300
|
+
const [shortcutsOpen, setShortcutsOpen] = (0, import_react8.useState)(false);
|
|
3301
|
+
const [changesOpen, setChangesOpen] = (0, import_react8.useState)(false);
|
|
3302
|
+
const [found, setFound] = (0, import_react8.useState)({});
|
|
2991
3303
|
const [theme, setTheme] = useTheme();
|
|
2992
3304
|
const [toast, showToast] = useToast();
|
|
2993
3305
|
const layout = useSidebarLayout();
|
|
2994
|
-
const searchRef = (0,
|
|
2995
|
-
const select = (0,
|
|
3306
|
+
const searchRef = (0, import_react8.useRef)(null);
|
|
3307
|
+
const select = (0, import_react8.useCallback)((next) => {
|
|
2996
3308
|
setSelection(next);
|
|
2997
3309
|
writeHash(next);
|
|
2998
3310
|
}, []);
|
|
2999
|
-
(0,
|
|
3311
|
+
(0, import_react8.useEffect)(() => {
|
|
3000
3312
|
const onHash = () => setSelection(readHash());
|
|
3001
3313
|
window.addEventListener("hashchange", onHash);
|
|
3002
3314
|
return () => window.removeEventListener("hashchange", onHash);
|
|
@@ -3006,14 +3318,14 @@ function Shell() {
|
|
|
3006
3318
|
const discovered = selection.kind === "discovered" ? state.discovered.data.find((d) => d.providerSessionId === selection.id) ?? found[`${selection.provider}:${selection.id}`] ?? null : null;
|
|
3007
3319
|
const run = session ? state.runs[session.id] : void 0;
|
|
3008
3320
|
const live = run !== void 0 && !isTerminalRunStatus(run.status);
|
|
3009
|
-
const order = (0,
|
|
3321
|
+
const order = (0, import_react8.useMemo)(() => {
|
|
3010
3322
|
const known = new Set(state.sessions.data.map((s) => s.providerSessionId).filter(Boolean));
|
|
3011
3323
|
return [
|
|
3012
3324
|
...state.sessions.data.map((s) => ({ kind: "session", id: s.id })),
|
|
3013
3325
|
...state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => ({ kind: "discovered", provider: d.provider, id: d.providerSessionId }))
|
|
3014
3326
|
];
|
|
3015
3327
|
}, [state.sessions.data, state.discovered.data]);
|
|
3016
|
-
(0,
|
|
3328
|
+
(0, import_react8.useEffect)(() => {
|
|
3017
3329
|
const onKey = (e) => {
|
|
3018
3330
|
const mod = e.metaKey || e.ctrlKey;
|
|
3019
3331
|
const key = e.key.toLowerCase();
|
|
@@ -3069,12 +3381,12 @@ function Shell() {
|
|
|
3069
3381
|
}, [client, layout, live, run, order, selection, select, showToast]);
|
|
3070
3382
|
let main;
|
|
3071
3383
|
if (selection.kind === "session") {
|
|
3072
|
-
main = session ? /* @__PURE__ */ (0,
|
|
3073
|
-
/* @__PURE__ */ (0,
|
|
3384
|
+
main = session ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SessionView, { session, changesOpen, setChangesOpen }, session.id) : state.sessions.loadedAt === null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground", children: [
|
|
3385
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpinnerIcon, { size: 15 }),
|
|
3074
3386
|
" Loading\u2026"
|
|
3075
|
-
] }) : /* @__PURE__ */ (0,
|
|
3387
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex flex-1 items-center justify-center text-[13px] text-muted-foreground", children: "That session is not in the list anymore." });
|
|
3076
3388
|
} else if (selection.kind === "discovered") {
|
|
3077
|
-
main = /* @__PURE__ */ (0,
|
|
3389
|
+
main = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3078
3390
|
DiscoveredView,
|
|
3079
3391
|
{
|
|
3080
3392
|
session: discovered,
|
|
@@ -3087,13 +3399,13 @@ function Shell() {
|
|
|
3087
3399
|
`${selection.provider}:${selection.id}`
|
|
3088
3400
|
);
|
|
3089
3401
|
} else {
|
|
3090
|
-
main = /* @__PURE__ */ (0,
|
|
3402
|
+
main = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Home, { onNew: () => setNewOpen(true) });
|
|
3091
3403
|
}
|
|
3092
|
-
return /* @__PURE__ */ (0,
|
|
3093
|
-
/* @__PURE__ */ (0,
|
|
3094
|
-
/* @__PURE__ */ (0,
|
|
3095
|
-
layout.collapsed ? /* @__PURE__ */ (0,
|
|
3096
|
-
/* @__PURE__ */ (0,
|
|
3404
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToastContext.Provider, { value: showToast, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "cs-app flex h-full flex-col bg-background text-foreground", children: [
|
|
3405
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConnectionBanner, {}),
|
|
3406
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-h-0 flex-1", children: [
|
|
3407
|
+
layout.collapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col items-center gap-1 border-r border-border bg-muted/30 px-1.5 py-3", children: [
|
|
3408
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3097
3409
|
"button",
|
|
3098
3410
|
{
|
|
3099
3411
|
type: "button",
|
|
@@ -3101,10 +3413,10 @@ function Shell() {
|
|
|
3101
3413
|
onClick: () => layout.setCollapsed(false),
|
|
3102
3414
|
"aria-label": "Show the sidebar (\u2318B)",
|
|
3103
3415
|
title: "Show sidebar \u2318B",
|
|
3104
|
-
children: /* @__PURE__ */ (0,
|
|
3416
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarIcon, { size: 15 })
|
|
3105
3417
|
}
|
|
3106
3418
|
),
|
|
3107
|
-
/* @__PURE__ */ (0,
|
|
3419
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3108
3420
|
"button",
|
|
3109
3421
|
{
|
|
3110
3422
|
type: "button",
|
|
@@ -3112,11 +3424,11 @@ function Shell() {
|
|
|
3112
3424
|
onClick: () => setNewOpen(true),
|
|
3113
3425
|
"aria-label": "New session",
|
|
3114
3426
|
title: "New session \u2325\u2318N",
|
|
3115
|
-
children: /* @__PURE__ */ (0,
|
|
3427
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PlusIcon, { size: 15 })
|
|
3116
3428
|
}
|
|
3117
3429
|
)
|
|
3118
|
-
] }) : /* @__PURE__ */ (0,
|
|
3119
|
-
/* @__PURE__ */ (0,
|
|
3430
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
3431
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3120
3432
|
Sidebar,
|
|
3121
3433
|
{
|
|
3122
3434
|
selection,
|
|
@@ -3126,14 +3438,14 @@ function Shell() {
|
|
|
3126
3438
|
width: layout.width,
|
|
3127
3439
|
searchRef,
|
|
3128
3440
|
onFound: (d) => setFound((f) => ({ ...f, [`${d.provider}:${d.providerSessionId}`]: d })),
|
|
3129
|
-
footer: /* @__PURE__ */ (0,
|
|
3441
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3130
3442
|
ProvidersFooter,
|
|
3131
3443
|
{
|
|
3132
3444
|
theme,
|
|
3133
3445
|
setTheme,
|
|
3134
|
-
extra: /* @__PURE__ */ (0,
|
|
3135
|
-
/* @__PURE__ */ (0,
|
|
3136
|
-
/* @__PURE__ */ (0,
|
|
3446
|
+
extra: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
3447
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NotifyToggle, {}),
|
|
3448
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3137
3449
|
"button",
|
|
3138
3450
|
{
|
|
3139
3451
|
type: "button",
|
|
@@ -3141,7 +3453,7 @@ function Shell() {
|
|
|
3141
3453
|
onClick: () => setShortcutsOpen(true),
|
|
3142
3454
|
"aria-label": "Keyboard shortcuts (\u2318/)",
|
|
3143
3455
|
title: "Keyboard shortcuts \u2318/",
|
|
3144
|
-
children: /* @__PURE__ */ (0,
|
|
3456
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(KeyboardIcon, { size: 14 })
|
|
3145
3457
|
}
|
|
3146
3458
|
)
|
|
3147
3459
|
] })
|
|
@@ -3149,11 +3461,11 @@ function Shell() {
|
|
|
3149
3461
|
)
|
|
3150
3462
|
}
|
|
3151
3463
|
),
|
|
3152
|
-
/* @__PURE__ */ (0,
|
|
3464
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Resizer, { width: layout.width, setWidth: layout.setWidth })
|
|
3153
3465
|
] }),
|
|
3154
|
-
/* @__PURE__ */ (0,
|
|
3466
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("main", { className: "flex min-w-0 flex-1", children: main })
|
|
3155
3467
|
] }),
|
|
3156
|
-
/* @__PURE__ */ (0,
|
|
3468
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3157
3469
|
NewSessionDialog,
|
|
3158
3470
|
{
|
|
3159
3471
|
open: newOpen,
|
|
@@ -3164,11 +3476,11 @@ function Shell() {
|
|
|
3164
3476
|
}
|
|
3165
3477
|
}
|
|
3166
3478
|
),
|
|
3167
|
-
/* @__PURE__ */ (0,
|
|
3168
|
-
/* @__PURE__ */ (0,
|
|
3479
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ShortcutsDialog, { open: shortcutsOpen, onOpenChange: setShortcutsOpen }),
|
|
3480
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Toast, { text: toast })
|
|
3169
3481
|
] }) });
|
|
3170
3482
|
}
|
|
3171
3483
|
function CodingSessionsApp({ transport }) {
|
|
3172
|
-
return /* @__PURE__ */ (0,
|
|
3484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CodingSessionsProvider, { transport, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Shell, {}) });
|
|
3173
3485
|
}
|
|
3174
3486
|
//# sourceMappingURL=index.cjs.map
|