@ai-matrx/coding-sessions 0.1.83 → 0.1.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/engine/index.cjs +521 -112
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +4 -1
- package/dist/engine/index.d.ts +4 -1
- package/dist/engine/index.js +521 -112
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/worker.js +2 -2
- package/dist/engine/worker.js.map +1 -1
- package/dist/{index-DQ0teQvw.d.cts → index-DEPwyr2j.d.cts} +130 -0
- package/dist/{index-DQ0teQvw.d.ts → index-DEPwyr2j.d.ts} +130 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -1
- package/dist/index.d.ts +87 -1
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +666 -408
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +87 -7
- package/dist/react/index.d.ts +87 -7
- package/dist/react/index.js +674 -403
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +588 -127
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +4 -1
- package/dist/server/index.d.ts +4 -1
- package/dist/server/index.js +587 -126
- package/dist/server/index.js.map +1 -1
- package/dist/ui/assets/index-DSWoryQZ.js +72 -0
- package/dist/ui/assets/index-Gp2bMDtx.css +2 -0
- package/dist/ui/index.html +2 -2
- package/package.json +4 -2
- package/dist/ui/assets/index-C-_1qjy9.css +0 -2
- package/dist/ui/assets/index-CmFgFvLa.js +0 -69
package/dist/react/index.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
|
|
@@ -486,14 +486,20 @@ var SpinnerIcon = ({ size = 16, className }) => /* @__PURE__ */ (0, import_jsx_r
|
|
|
486
486
|
]
|
|
487
487
|
}
|
|
488
488
|
);
|
|
489
|
-
|
|
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 }) {
|
|
490
492
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
491
|
-
"
|
|
493
|
+
"svg",
|
|
492
494
|
{
|
|
493
495
|
className: `cs-provider-mark cs-provider-mark--${provider}`,
|
|
494
|
-
|
|
496
|
+
width: size,
|
|
497
|
+
height: size,
|
|
498
|
+
viewBox: "0 0 24 24",
|
|
499
|
+
fill: "currentColor",
|
|
495
500
|
"aria-hidden": "true",
|
|
496
|
-
|
|
501
|
+
"data-provider-mark": provider,
|
|
502
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: provider === "claude" ? CLAUDE_MARK : OPENAI_MARK })
|
|
497
503
|
}
|
|
498
504
|
);
|
|
499
505
|
}
|
|
@@ -890,10 +896,217 @@ function ModelPicker(props) {
|
|
|
890
896
|
] });
|
|
891
897
|
}
|
|
892
898
|
|
|
893
|
-
// src/react/
|
|
899
|
+
// src/react/agent-field.tsx
|
|
894
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");
|
|
895
905
|
var import_design_system4 = require("@ai-matrx/design-system");
|
|
896
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");
|
|
897
1110
|
function readLocal(key, allowed, fallback) {
|
|
898
1111
|
try {
|
|
899
1112
|
const value = localStorage.getItem(key);
|
|
@@ -909,23 +1122,23 @@ function writeLocal(key, value) {
|
|
|
909
1122
|
}
|
|
910
1123
|
}
|
|
911
1124
|
function SectionLabel({ children, action }) {
|
|
912
|
-
return /* @__PURE__ */ (0,
|
|
913
|
-
/* @__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 }),
|
|
914
1127
|
action
|
|
915
1128
|
] });
|
|
916
1129
|
}
|
|
917
1130
|
function GroupLabel({ children }) {
|
|
918
|
-
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 });
|
|
919
1132
|
}
|
|
920
1133
|
function RenameInput(props) {
|
|
921
|
-
const [value, setValue] = (0,
|
|
922
|
-
const done = (0,
|
|
1134
|
+
const [value, setValue] = (0, import_react7.useState)(props.initial);
|
|
1135
|
+
const done = (0, import_react7.useRef)(false);
|
|
923
1136
|
const finish = (title) => {
|
|
924
1137
|
if (done.current) return;
|
|
925
1138
|
done.current = true;
|
|
926
1139
|
props.onDone(title);
|
|
927
1140
|
};
|
|
928
|
-
return /* @__PURE__ */ (0,
|
|
1141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
929
1142
|
"input",
|
|
930
1143
|
{
|
|
931
1144
|
autoFocus: true,
|
|
@@ -942,11 +1155,16 @@ function RenameInput(props) {
|
|
|
942
1155
|
}
|
|
943
1156
|
);
|
|
944
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
|
+
}
|
|
945
1163
|
function Row(props) {
|
|
946
1164
|
const client = useCodingSessionsClient();
|
|
947
1165
|
const show = useToastShow();
|
|
948
|
-
const [renaming, setRenaming] = (0,
|
|
949
|
-
const [menuOpen, setMenuOpen] = (0,
|
|
1166
|
+
const [renaming, setRenaming] = (0, import_react7.useState)(false);
|
|
1167
|
+
const [menuOpen, setMenuOpen] = (0, import_react7.useState)(false);
|
|
950
1168
|
const { entry } = props;
|
|
951
1169
|
const rename = (title) => {
|
|
952
1170
|
setRenaming(false);
|
|
@@ -956,14 +1174,20 @@ function Row(props) {
|
|
|
956
1174
|
(error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`)
|
|
957
1175
|
);
|
|
958
1176
|
};
|
|
959
|
-
return /* @__PURE__ */ (0,
|
|
960
|
-
/* @__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)(
|
|
961
1179
|
"div",
|
|
962
1180
|
{
|
|
963
|
-
className: (0,
|
|
1181
|
+
className: (0, import_design_system5.cn)("cs-row group", props.active && "cs-row--active", menuOpen && "cs-row--menu"),
|
|
964
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,
|
|
965
1189
|
children: [
|
|
966
|
-
/* @__PURE__ */ (0,
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
967
1191
|
"button",
|
|
968
1192
|
{
|
|
969
1193
|
type: "button",
|
|
@@ -975,39 +1199,39 @@ function Row(props) {
|
|
|
975
1199
|
(${entry.originalTitle})` : entry.title
|
|
976
1200
|
}
|
|
977
1201
|
),
|
|
978
|
-
/* @__PURE__ */ (0,
|
|
979
|
-
/* @__PURE__ */ (0,
|
|
980
|
-
renaming ? /* @__PURE__ */ (0,
|
|
981
|
-
/* @__PURE__ */ (0,
|
|
982
|
-
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
|
|
983
1207
|
] }),
|
|
984
|
-
/* @__PURE__ */ (0,
|
|
985
|
-
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
|
|
986
1210
|
] }),
|
|
987
|
-
renaming ? null : /* @__PURE__ */ (0,
|
|
1211
|
+
renaming ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "cs-row__actions", children: [
|
|
988
1212
|
props.takeover,
|
|
989
|
-
/* @__PURE__ */ (0,
|
|
990
|
-
/* @__PURE__ */ (0,
|
|
991
|
-
/* @__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) }) })
|
|
992
1216
|
] })
|
|
993
1217
|
] })
|
|
994
1218
|
]
|
|
995
1219
|
}
|
|
996
1220
|
) }),
|
|
997
|
-
/* @__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) }) })
|
|
998
1222
|
] });
|
|
999
1223
|
}
|
|
1000
1224
|
function SidebarSkeleton() {
|
|
1001
|
-
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)) });
|
|
1002
1226
|
}
|
|
1003
1227
|
function Highlight({ text, query }) {
|
|
1004
1228
|
const q = query.trim().toLowerCase();
|
|
1005
1229
|
if (!q) return text;
|
|
1006
1230
|
const at = text.toLowerCase().indexOf(q);
|
|
1007
1231
|
if (at < 0) return text;
|
|
1008
|
-
return /* @__PURE__ */ (0,
|
|
1232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1009
1233
|
text.slice(0, at),
|
|
1010
|
-
/* @__PURE__ */ (0,
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("mark", { className: "cs-mark", children: text.slice(at, at + q.length) }),
|
|
1011
1235
|
text.slice(at + q.length)
|
|
1012
1236
|
] });
|
|
1013
1237
|
}
|
|
@@ -1022,10 +1246,10 @@ var EMPTY_SEARCH = {
|
|
|
1022
1246
|
};
|
|
1023
1247
|
function useContentSearch(query) {
|
|
1024
1248
|
const client = useCodingSessionsClient();
|
|
1025
|
-
const [state, setState] = (0,
|
|
1026
|
-
const latest = (0,
|
|
1249
|
+
const [state, setState] = (0, import_react7.useState)(EMPTY_SEARCH);
|
|
1250
|
+
const latest = (0, import_react7.useRef)(query);
|
|
1027
1251
|
latest.current = query;
|
|
1028
|
-
const run = (0,
|
|
1252
|
+
const run = (0, import_react7.useCallback)(
|
|
1029
1253
|
async (q, cursor, append) => {
|
|
1030
1254
|
setState((s) => ({ ...append ? s : EMPTY_SEARCH, query: q, loading: true, error: null }));
|
|
1031
1255
|
try {
|
|
@@ -1047,7 +1271,7 @@ function useContentSearch(query) {
|
|
|
1047
1271
|
},
|
|
1048
1272
|
[client]
|
|
1049
1273
|
);
|
|
1050
|
-
(0,
|
|
1274
|
+
(0, import_react7.useEffect)(() => {
|
|
1051
1275
|
const q = query.trim();
|
|
1052
1276
|
if (q.length < 2) {
|
|
1053
1277
|
setState(EMPTY_SEARCH);
|
|
@@ -1056,7 +1280,7 @@ function useContentSearch(query) {
|
|
|
1056
1280
|
const timer = setTimeout(() => void run(q, 0, false), 350);
|
|
1057
1281
|
return () => clearTimeout(timer);
|
|
1058
1282
|
}, [query, run]);
|
|
1059
|
-
const more = (0,
|
|
1283
|
+
const more = (0, import_react7.useCallback)(() => {
|
|
1060
1284
|
if (state.nextCursor !== null && !state.loading) void run(state.query, state.nextCursor, true);
|
|
1061
1285
|
}, [run, state.nextCursor, state.loading, state.query]);
|
|
1062
1286
|
return [state, more];
|
|
@@ -1076,19 +1300,19 @@ function Sidebar(props) {
|
|
|
1076
1300
|
const client = useCodingSessionsClient();
|
|
1077
1301
|
const state = useCodingSessionsState();
|
|
1078
1302
|
const now = useMinuteClock();
|
|
1079
|
-
const [query, setQuery] = (0,
|
|
1303
|
+
const [query, setQuery] = (0, import_react7.useState)("");
|
|
1080
1304
|
const [search, searchMore] = useContentSearch(query);
|
|
1081
|
-
const [groupMode, setGroupMode] = (0,
|
|
1082
|
-
const [showHidden, setShowHidden] = (0,
|
|
1083
|
-
const [takingOver, setTakingOver] = (0,
|
|
1084
|
-
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);
|
|
1085
1309
|
const prefs = state.preferences;
|
|
1086
1310
|
const sessions = state.sessions.data;
|
|
1087
1311
|
const isLive = (id) => {
|
|
1088
1312
|
const run = state.runs[id];
|
|
1089
1313
|
return run !== void 0 && !isTerminalRunStatus(run.status);
|
|
1090
1314
|
};
|
|
1091
|
-
const { ours, others, hiddenCount } = (0,
|
|
1315
|
+
const { ours, others, hiddenCount } = (0, import_react7.useMemo)(() => {
|
|
1092
1316
|
const oursList = sessions.map((s) => sessionEntry(s, prefs));
|
|
1093
1317
|
const known = new Set(sessions.map((s) => s.providerSessionId).filter(Boolean));
|
|
1094
1318
|
const othersList = state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => discoveredEntry(d, prefs));
|
|
@@ -1128,8 +1352,8 @@ function Sidebar(props) {
|
|
|
1128
1352
|
let meta;
|
|
1129
1353
|
if (live) meta = `${PROVIDER_LABEL[entry.provider]} is working\u2026`;
|
|
1130
1354
|
else if (d?.activeElsewhere)
|
|
1131
|
-
meta = /* @__PURE__ */ (0,
|
|
1132
|
-
/* @__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" }),
|
|
1133
1357
|
"Running in ",
|
|
1134
1358
|
PROVIDER_LABEL[entry.provider]
|
|
1135
1359
|
] });
|
|
@@ -1138,8 +1362,8 @@ function Sidebar(props) {
|
|
|
1138
1362
|
const where = entry.cwd ? prettyPath2(entry.cwd) : "unknown folder";
|
|
1139
1363
|
meta = `${status}${entry.kind === "discovered" ? `${PROVIDER_LABEL[entry.provider]} \xB7 ` : ""}${groupMode === "folder" && !extra ? "" : `${where} \xB7 `}${relativeTime(entry.updatedAt, now)}`;
|
|
1140
1364
|
}
|
|
1141
|
-
return /* @__PURE__ */ (0,
|
|
1142
|
-
/* @__PURE__ */ (0,
|
|
1365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1143
1367
|
Row,
|
|
1144
1368
|
{
|
|
1145
1369
|
entry,
|
|
@@ -1148,7 +1372,7 @@ function Sidebar(props) {
|
|
|
1148
1372
|
live,
|
|
1149
1373
|
meta,
|
|
1150
1374
|
snippet: extra?.snippet,
|
|
1151
|
-
takeover: d?.cwd ? /* @__PURE__ */ (0,
|
|
1375
|
+
takeover: d?.cwd ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1152
1376
|
"button",
|
|
1153
1377
|
{
|
|
1154
1378
|
type: "button",
|
|
@@ -1157,18 +1381,18 @@ function Sidebar(props) {
|
|
|
1157
1381
|
title: d.activeElsewhere ? d.activeElsewhere.message : "Continue this chat here",
|
|
1158
1382
|
disabled: takingOver === d.providerSessionId,
|
|
1159
1383
|
children: [
|
|
1160
|
-
takingOver === d.providerSessionId ? /* @__PURE__ */ (0,
|
|
1384
|
+
takingOver === d.providerSessionId ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SpinnerIcon, { size: 11 }) : null,
|
|
1161
1385
|
"Take over"
|
|
1162
1386
|
]
|
|
1163
1387
|
}
|
|
1164
1388
|
) : null
|
|
1165
1389
|
}
|
|
1166
1390
|
),
|
|
1167
|
-
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
|
|
1168
1392
|
] }, entry.key);
|
|
1169
1393
|
};
|
|
1170
|
-
const renderGroups = (entries) => groupEntries(entries, groupMode, now).map((group) => /* @__PURE__ */ (0,
|
|
1171
|
-
/* @__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 }),
|
|
1172
1396
|
group.entries.map((e) => renderEntry(e))
|
|
1173
1397
|
] }, group.label));
|
|
1174
1398
|
const searching = query.trim().length > 0;
|
|
@@ -1185,60 +1409,60 @@ function Sidebar(props) {
|
|
|
1185
1409
|
props.onFound(hitToDiscovered(hit));
|
|
1186
1410
|
props.select({ kind: "discovered", provider: hit.provider, id: hit.providerSessionId });
|
|
1187
1411
|
};
|
|
1188
|
-
const searchBody = /* @__PURE__ */ (0,
|
|
1189
|
-
/* @__PURE__ */ (0,
|
|
1190
|
-
titleMatches.length === 0 ? /* @__PURE__ */ (0,
|
|
1191
|
-
/* @__PURE__ */ (0,
|
|
1192
|
-
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: [
|
|
1193
1417
|
contentHits.map((hit) => {
|
|
1194
1418
|
const known = allByKey.get(chatKey(hit.provider, hit.providerSessionId));
|
|
1195
1419
|
const entry = known ?? discoveredEntry(hitToDiscovered(hit), prefs);
|
|
1196
|
-
return /* @__PURE__ */ (0,
|
|
1420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { onClickCapture: known ? void 0 : () => props.onFound(hitToDiscovered(hit)), children: renderEntry(entry, {
|
|
1197
1421
|
query,
|
|
1198
|
-
snippet: hit.snippet ? /* @__PURE__ */ (0,
|
|
1422
|
+
snippet: hit.snippet ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Highlight, { text: hit.snippet, query }) : void 0
|
|
1199
1423
|
}) }, `hit:${entry.key}`);
|
|
1200
1424
|
}),
|
|
1201
|
-
/* @__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: [
|
|
1202
1426
|
"Search stopped: ",
|
|
1203
1427
|
search.error
|
|
1204
|
-
] }) : search.loading ? /* @__PURE__ */ (0,
|
|
1205
|
-
/* @__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 }),
|
|
1206
1430
|
" Searching your chats\u2026"
|
|
1207
|
-
] }) : search.query ? /* @__PURE__ */ (0,
|
|
1431
|
+
] }) : search.query ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1208
1432
|
contentHits.length === 0 && search.hits.length === 0 ? "Nothing found. " : null,
|
|
1209
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.`,
|
|
1210
|
-
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
|
|
1211
1435
|
] }) : null })
|
|
1212
1436
|
] })
|
|
1213
1437
|
] });
|
|
1214
|
-
const listBody = /* @__PURE__ */ (0,
|
|
1215
|
-
pinned.length > 0 ? /* @__PURE__ */ (0,
|
|
1216
|
-
/* @__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" }),
|
|
1217
1441
|
pinned.map((e) => renderEntry(e))
|
|
1218
1442
|
] }) : null,
|
|
1219
|
-
running.length > 0 ? /* @__PURE__ */ (0,
|
|
1220
|
-
/* @__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" }),
|
|
1221
1445
|
running.map((e) => renderEntry(e))
|
|
1222
1446
|
] }) : null,
|
|
1223
|
-
/* @__PURE__ */ (0,
|
|
1224
|
-
state.sessions.loading && state.sessions.loadedAt === null ? /* @__PURE__ */ (0,
|
|
1225
|
-
/* @__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)(
|
|
1226
1450
|
SectionLabel,
|
|
1227
1451
|
{
|
|
1228
|
-
action: /* @__PURE__ */ (0,
|
|
1229
|
-
/* @__PURE__ */ (0,
|
|
1230
|
-
/* @__PURE__ */ (0,
|
|
1231
|
-
/* @__PURE__ */ (0,
|
|
1232
|
-
/* @__PURE__ */ (0,
|
|
1233
|
-
/* @__PURE__ */ (0,
|
|
1234
|
-
/* @__PURE__ */ (0,
|
|
1235
|
-
/* @__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" })
|
|
1236
1460
|
] }),
|
|
1237
|
-
/* @__PURE__ */ (0,
|
|
1238
|
-
/* @__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})` : ""}` })
|
|
1239
1463
|
] })
|
|
1240
1464
|
] }),
|
|
1241
|
-
/* @__PURE__ */ (0,
|
|
1465
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1242
1466
|
"button",
|
|
1243
1467
|
{
|
|
1244
1468
|
type: "button",
|
|
@@ -1246,17 +1470,17 @@ function Sidebar(props) {
|
|
|
1246
1470
|
onClick: () => void client.refreshDiscovered(),
|
|
1247
1471
|
"aria-label": "Look again for your other chats",
|
|
1248
1472
|
title: "Look again",
|
|
1249
|
-
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 })
|
|
1250
1474
|
}
|
|
1251
1475
|
)
|
|
1252
1476
|
] }),
|
|
1253
1477
|
children: "Your other chats"
|
|
1254
1478
|
}
|
|
1255
1479
|
),
|
|
1256
|
-
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: [
|
|
1257
1481
|
renderGroups(otherList),
|
|
1258
|
-
state.discovered.data.length >= state.discoveredLimit ? /* @__PURE__ */ (0,
|
|
1259
|
-
|
|
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,
|
|
1260
1484
|
{
|
|
1261
1485
|
variant: "ghost",
|
|
1262
1486
|
size: "sm",
|
|
@@ -1264,32 +1488,32 @@ function Sidebar(props) {
|
|
|
1264
1488
|
onClick: () => void client.showMoreDiscovered(),
|
|
1265
1489
|
disabled: state.discovered.loading,
|
|
1266
1490
|
children: [
|
|
1267
|
-
state.discovered.loading ? /* @__PURE__ */ (0,
|
|
1491
|
+
state.discovered.loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SpinnerIcon, { size: 13 }) : null,
|
|
1268
1492
|
"Show older chats"
|
|
1269
1493
|
]
|
|
1270
1494
|
}
|
|
1271
1495
|
) }) : null
|
|
1272
1496
|
] }),
|
|
1273
|
-
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: [
|
|
1274
1498
|
hiddenCount,
|
|
1275
1499
|
" hidden ",
|
|
1276
1500
|
hiddenCount === 1 ? "chat" : "chats",
|
|
1277
1501
|
" \u2014 show"
|
|
1278
1502
|
] }) : null
|
|
1279
1503
|
] });
|
|
1280
|
-
return /* @__PURE__ */ (0,
|
|
1504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1281
1505
|
"aside",
|
|
1282
1506
|
{
|
|
1283
|
-
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",
|
|
1284
1508
|
style: { width: props.width },
|
|
1285
1509
|
"aria-label": "Sessions",
|
|
1286
1510
|
children: [
|
|
1287
|
-
/* @__PURE__ */ (0,
|
|
1288
|
-
/* @__PURE__ */ (0,
|
|
1289
|
-
/* @__PURE__ */ (0,
|
|
1290
|
-
/* @__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" })
|
|
1291
1515
|
] }),
|
|
1292
|
-
/* @__PURE__ */ (0,
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1293
1517
|
"button",
|
|
1294
1518
|
{
|
|
1295
1519
|
type: "button",
|
|
@@ -1297,19 +1521,19 @@ function Sidebar(props) {
|
|
|
1297
1521
|
onClick: props.onCollapse,
|
|
1298
1522
|
"aria-label": "Hide the sidebar (\u2318B)",
|
|
1299
1523
|
title: "Hide sidebar \u2318B",
|
|
1300
|
-
children: /* @__PURE__ */ (0,
|
|
1524
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SidebarIcon, { size: 15 })
|
|
1301
1525
|
}
|
|
1302
1526
|
)
|
|
1303
1527
|
] }),
|
|
1304
|
-
/* @__PURE__ */ (0,
|
|
1305
|
-
/* @__PURE__ */ (0,
|
|
1306
|
-
/* @__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 }),
|
|
1307
1531
|
"New session",
|
|
1308
|
-
/* @__PURE__ */ (0,
|
|
1532
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { className: "cs-kbd ml-auto", children: "\u2325\u2318N" })
|
|
1309
1533
|
] }),
|
|
1310
|
-
/* @__PURE__ */ (0,
|
|
1311
|
-
/* @__PURE__ */ (0,
|
|
1312
|
-
/* @__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)(
|
|
1313
1537
|
"input",
|
|
1314
1538
|
{
|
|
1315
1539
|
ref: props.searchRef,
|
|
@@ -1335,10 +1559,10 @@ function Sidebar(props) {
|
|
|
1335
1559
|
className: "cs-search__input"
|
|
1336
1560
|
}
|
|
1337
1561
|
),
|
|
1338
|
-
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" })
|
|
1339
1563
|
] })
|
|
1340
1564
|
] }),
|
|
1341
|
-
/* @__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 }),
|
|
1342
1566
|
props.footer
|
|
1343
1567
|
]
|
|
1344
1568
|
}
|
|
@@ -1929,13 +2153,13 @@ function firstInvalidField(errors) {
|
|
|
1929
2153
|
}
|
|
1930
2154
|
|
|
1931
2155
|
// src/react/app.tsx
|
|
1932
|
-
var
|
|
2156
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1933
2157
|
function CodingSessionsProvider({ transport, children }) {
|
|
1934
|
-
const [client] = (0,
|
|
1935
|
-
(0,
|
|
2158
|
+
const [client] = (0, import_react8.useState)(() => new CodingSessionsClient(transport));
|
|
2159
|
+
(0, import_react8.useEffect)(() => {
|
|
1936
2160
|
if (transport.status().state === "open") void client.refreshAll();
|
|
1937
2161
|
}, [client, transport]);
|
|
1938
|
-
return /* @__PURE__ */ (0,
|
|
2162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CodingSessionsContext.Provider, { value: client, children });
|
|
1939
2163
|
}
|
|
1940
2164
|
function readHash() {
|
|
1941
2165
|
if (typeof location === "undefined") return { kind: "none" };
|
|
@@ -1958,8 +2182,8 @@ function readTheme() {
|
|
|
1958
2182
|
}
|
|
1959
2183
|
}
|
|
1960
2184
|
function useTheme() {
|
|
1961
|
-
const [choice, setChoice] = (0,
|
|
1962
|
-
(0,
|
|
2185
|
+
const [choice, setChoice] = (0, import_react8.useState)(readTheme);
|
|
2186
|
+
(0, import_react8.useEffect)(() => {
|
|
1963
2187
|
const media = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-color-scheme: dark)") : null;
|
|
1964
2188
|
const apply = () => {
|
|
1965
2189
|
const dark = choice === "dark" || choice === "system" && media?.matches === true;
|
|
@@ -1970,7 +2194,7 @@ function useTheme() {
|
|
|
1970
2194
|
media?.addEventListener("change", apply);
|
|
1971
2195
|
return () => media?.removeEventListener("change", apply);
|
|
1972
2196
|
}, [choice]);
|
|
1973
|
-
const set = (0,
|
|
2197
|
+
const set = (0, import_react8.useCallback)((next) => {
|
|
1974
2198
|
setChoice(next);
|
|
1975
2199
|
try {
|
|
1976
2200
|
localStorage.setItem("coding-sessions.theme", next);
|
|
@@ -1989,8 +2213,8 @@ var RUN_LABEL = {
|
|
|
1989
2213
|
function RunPill({ run }) {
|
|
1990
2214
|
if (!run) return null;
|
|
1991
2215
|
const live = !isTerminalRunStatus(run.status);
|
|
1992
|
-
return /* @__PURE__ */ (0,
|
|
1993
|
-
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,
|
|
1994
2218
|
RUN_LABEL[run.status]
|
|
1995
2219
|
] });
|
|
1996
2220
|
}
|
|
@@ -1998,17 +2222,17 @@ function ConnectionBanner() {
|
|
|
1998
2222
|
const { connection } = useCodingSessionsState();
|
|
1999
2223
|
if (connection.state === "open") return null;
|
|
2000
2224
|
const closed = connection.state === "closed";
|
|
2001
|
-
return /* @__PURE__ */ (0,
|
|
2225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2002
2226
|
"div",
|
|
2003
2227
|
{
|
|
2004
2228
|
role: "status",
|
|
2005
|
-
className: (0,
|
|
2229
|
+
className: (0, import_design_system6.cn)(
|
|
2006
2230
|
"flex items-center gap-2 border-b px-4 py-2 text-[13px]",
|
|
2007
2231
|
closed ? "border-destructive/30 bg-destructive/10 text-destructive" : "border-border bg-muted/60 text-muted-foreground"
|
|
2008
2232
|
),
|
|
2009
2233
|
children: [
|
|
2010
|
-
closed ? /* @__PURE__ */ (0,
|
|
2011
|
-
/* @__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" })
|
|
2012
2236
|
]
|
|
2013
2237
|
}
|
|
2014
2238
|
);
|
|
@@ -2018,22 +2242,22 @@ function ProvidersFooter(props) {
|
|
|
2018
2242
|
const client = useCodingSessionsClient();
|
|
2019
2243
|
const next = { system: "light", light: "dark", dark: "system" };
|
|
2020
2244
|
const themeLabel = { system: "Match system", light: "Light", dark: "Dark" };
|
|
2021
|
-
return /* @__PURE__ */ (0,
|
|
2022
|
-
/* @__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)(
|
|
2023
2247
|
"span",
|
|
2024
2248
|
{
|
|
2025
|
-
className: (0,
|
|
2249
|
+
className: (0, import_design_system6.cn)("cs-provider-chip", p.ready ? "" : "cs-provider-chip--problem"),
|
|
2026
2250
|
title: p.problem ? `${p.problem} ${p.fix ?? ""}` : [binaryWords(p) ?? p.label, p.plan, newerWords(p)].filter(Boolean).join(" \xB7 "),
|
|
2027
2251
|
children: [
|
|
2028
|
-
/* @__PURE__ */ (0,
|
|
2252
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProviderMark, { provider: p.provider, size: 13 }),
|
|
2029
2253
|
p.label,
|
|
2030
|
-
p.lastProblem ? /* @__PURE__ */ (0,
|
|
2031
|
-
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 })
|
|
2032
2256
|
]
|
|
2033
2257
|
},
|
|
2034
2258
|
p.provider
|
|
2035
2259
|
)) }),
|
|
2036
|
-
/* @__PURE__ */ (0,
|
|
2260
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2037
2261
|
"button",
|
|
2038
2262
|
{
|
|
2039
2263
|
type: "button",
|
|
@@ -2041,11 +2265,11 @@ function ProvidersFooter(props) {
|
|
|
2041
2265
|
onClick: () => void client.refreshProviders(),
|
|
2042
2266
|
"aria-label": "Check Claude Code and Codex again",
|
|
2043
2267
|
title: "Check again",
|
|
2044
|
-
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 })
|
|
2045
2269
|
}
|
|
2046
2270
|
),
|
|
2047
2271
|
props.extra,
|
|
2048
|
-
/* @__PURE__ */ (0,
|
|
2272
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2049
2273
|
"button",
|
|
2050
2274
|
{
|
|
2051
2275
|
type: "button",
|
|
@@ -2053,14 +2277,14 @@ function ProvidersFooter(props) {
|
|
|
2053
2277
|
onClick: () => props.setTheme(next[props.theme]),
|
|
2054
2278
|
"aria-label": `Theme: ${themeLabel[props.theme]}. Switch to ${themeLabel[next[props.theme]]}.`,
|
|
2055
2279
|
title: `Theme: ${themeLabel[props.theme]}`,
|
|
2056
|
-
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 })
|
|
2057
2281
|
}
|
|
2058
2282
|
)
|
|
2059
2283
|
] }) });
|
|
2060
2284
|
}
|
|
2061
2285
|
function useNotifier() {
|
|
2062
|
-
const show = (0,
|
|
2063
|
-
return (0,
|
|
2286
|
+
const show = (0, import_react8.useContext)(ToastContext);
|
|
2287
|
+
return (0, import_react8.useMemo)(
|
|
2064
2288
|
() => ({
|
|
2065
2289
|
notify(event) {
|
|
2066
2290
|
show(event.message);
|
|
@@ -2071,8 +2295,8 @@ function useNotifier() {
|
|
|
2071
2295
|
}
|
|
2072
2296
|
function useLiveElsewhere(provider, providerSessionId, initial = null) {
|
|
2073
2297
|
const client = useCodingSessionsClient();
|
|
2074
|
-
const [state, setState] = (0,
|
|
2075
|
-
(0,
|
|
2298
|
+
const [state, setState] = (0, import_react8.useState)(initial);
|
|
2299
|
+
(0, import_react8.useEffect)(() => {
|
|
2076
2300
|
if (!provider || !providerSessionId) {
|
|
2077
2301
|
setState(null);
|
|
2078
2302
|
return;
|
|
@@ -2092,8 +2316,8 @@ function useLiveElsewhere(provider, providerSessionId, initial = null) {
|
|
|
2092
2316
|
}
|
|
2093
2317
|
function useSessionUsage(sessionId, lastRunKey) {
|
|
2094
2318
|
const client = useCodingSessionsClient();
|
|
2095
|
-
const [usage, setUsage] = (0,
|
|
2096
|
-
(0,
|
|
2319
|
+
const [usage, setUsage] = (0, import_react8.useState)(null);
|
|
2320
|
+
(0, import_react8.useEffect)(() => {
|
|
2097
2321
|
let cancelled = false;
|
|
2098
2322
|
void client.transport.call("listRuns", sessionId).then((runs) => {
|
|
2099
2323
|
if (cancelled) return;
|
|
@@ -2114,18 +2338,18 @@ function useSessionUsage(sessionId, lastRunKey) {
|
|
|
2114
2338
|
return usage;
|
|
2115
2339
|
}
|
|
2116
2340
|
function HeaderMenu(props) {
|
|
2117
|
-
return /* @__PURE__ */ (0,
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2119
|
-
/* @__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 }) })
|
|
2120
2344
|
] });
|
|
2121
2345
|
}
|
|
2122
2346
|
function HeaderTitle(props) {
|
|
2123
2347
|
const client = useCodingSessionsClient();
|
|
2124
|
-
const show = (0,
|
|
2125
|
-
const [value, setValue] = (0,
|
|
2126
|
-
(0,
|
|
2127
|
-
const inputRef = (0,
|
|
2128
|
-
(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)(() => {
|
|
2129
2353
|
if (!props.renaming) return;
|
|
2130
2354
|
const timer = setTimeout(() => {
|
|
2131
2355
|
const input = inputRef.current;
|
|
@@ -2137,7 +2361,7 @@ function HeaderTitle(props) {
|
|
|
2137
2361
|
return () => clearTimeout(timer);
|
|
2138
2362
|
}, [props.renaming]);
|
|
2139
2363
|
if (!props.renaming) {
|
|
2140
|
-
return /* @__PURE__ */ (0,
|
|
2364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2141
2365
|
"h1",
|
|
2142
2366
|
{
|
|
2143
2367
|
className: "truncate text-[15px] font-semibold leading-5 tracking-[-0.01em]",
|
|
@@ -2154,7 +2378,7 @@ function HeaderTitle(props) {
|
|
|
2154
2378
|
const next = title === "" || title === props.entry.originalTitle ? null : title;
|
|
2155
2379
|
client.setPreference(props.entry.key, { title: next }).catch((error) => show(`The new name didn't save: ${error instanceof Error ? error.message : String(error)}`));
|
|
2156
2380
|
};
|
|
2157
|
-
return /* @__PURE__ */ (0,
|
|
2381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2158
2382
|
"input",
|
|
2159
2383
|
{
|
|
2160
2384
|
ref: inputRef,
|
|
@@ -2173,9 +2397,9 @@ function HeaderTitle(props) {
|
|
|
2173
2397
|
);
|
|
2174
2398
|
}
|
|
2175
2399
|
function LongChatNote(props) {
|
|
2176
|
-
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: [
|
|
2177
2401
|
"This chat is very long \u2014 showing its most recent part.",
|
|
2178
|
-
/* @__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" })
|
|
2179
2403
|
] });
|
|
2180
2404
|
}
|
|
2181
2405
|
function binaryWords(p) {
|
|
@@ -2188,7 +2412,7 @@ function newerWords(p) {
|
|
|
2188
2412
|
function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
2189
2413
|
const client = useCodingSessionsClient();
|
|
2190
2414
|
const state = useCodingSessionsState();
|
|
2191
|
-
const show = (0,
|
|
2415
|
+
const show = (0, import_react8.useContext)(ToastContext);
|
|
2192
2416
|
const transcript = useSessionTranscript(session.id);
|
|
2193
2417
|
const run = state.runs[session.id];
|
|
2194
2418
|
const live = run !== void 0 && !isTerminalRunStatus(run.status);
|
|
@@ -2197,8 +2421,8 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2197
2421
|
const blocked = provider && (!provider.installed || !provider.loggedIn) ? provider : null;
|
|
2198
2422
|
const limited = !blocked && provider?.lastProblem ? provider : null;
|
|
2199
2423
|
const modelRefused = run?.status === "failed" && isModelUnavailable(run.error);
|
|
2200
|
-
const [stopping, setStopping] = (0,
|
|
2201
|
-
const [renaming, setRenaming] = (0,
|
|
2424
|
+
const [stopping, setStopping] = (0, import_react8.useState)(false);
|
|
2425
|
+
const [renaming, setRenaming] = (0, import_react8.useState)(false);
|
|
2202
2426
|
const elsewhere = useLiveElsewhere(
|
|
2203
2427
|
session.origin === "takeover" && !live ? session.provider : null,
|
|
2204
2428
|
session.providerSessionId
|
|
@@ -2207,7 +2431,7 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2207
2431
|
const messages = transcript.thread.getSnapshot().messages;
|
|
2208
2432
|
const files = useChangedFiles(messages);
|
|
2209
2433
|
const usage = useSessionUsage(session.id, `${run?.runId ?? ""}:${run?.status ?? ""}`);
|
|
2210
|
-
(0,
|
|
2434
|
+
(0, import_react8.useEffect)(() => {
|
|
2211
2435
|
if (!live) setStopping(false);
|
|
2212
2436
|
}, [live]);
|
|
2213
2437
|
const stop = async () => {
|
|
@@ -2220,16 +2444,16 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2220
2444
|
};
|
|
2221
2445
|
const usageWords = usage ? `${(0, import_format3.formatCount)(usage.tokens, { style: "compact" })} tokens${usage.cost !== null ? ` \xB7 ${(0, import_format3.formatUsd)(usage.cost)}` : ""}` : null;
|
|
2222
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.` : "") : "";
|
|
2223
|
-
return /* @__PURE__ */ (0,
|
|
2224
|
-
/* @__PURE__ */ (0,
|
|
2225
|
-
/* @__PURE__ */ (0,
|
|
2226
|
-
/* @__PURE__ */ (0,
|
|
2227
|
-
/* @__PURE__ */ (0,
|
|
2228
|
-
/* @__PURE__ */ (0,
|
|
2229
|
-
/* @__PURE__ */ (0,
|
|
2230
|
-
/* @__PURE__ */ (0,
|
|
2231
|
-
/* @__PURE__ */ (0,
|
|
2232
|
-
/* @__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)(
|
|
2233
2457
|
ModelPicker,
|
|
2234
2458
|
{
|
|
2235
2459
|
status: provider,
|
|
@@ -2237,69 +2461,70 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2237
2461
|
onChange: setOptions
|
|
2238
2462
|
}
|
|
2239
2463
|
),
|
|
2240
|
-
/* @__PURE__ */ (0,
|
|
2241
|
-
/* @__PURE__ */ (0,
|
|
2242
|
-
/* @__PURE__ */ (0,
|
|
2243
|
-
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: [
|
|
2244
2468
|
"\xB7 ",
|
|
2245
2469
|
usageWords
|
|
2246
2470
|
] }) : null
|
|
2247
2471
|
] })
|
|
2248
2472
|
] }),
|
|
2249
|
-
/* @__PURE__ */ (0,
|
|
2473
|
+
session.agent ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AgentChip, { agent: session.agent }) : null,
|
|
2474
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2250
2475
|
"button",
|
|
2251
2476
|
{
|
|
2252
2477
|
type: "button",
|
|
2253
|
-
className: (0,
|
|
2478
|
+
className: (0, import_design_system6.cn)("cs-chip-button", changesOpen && "cs-chip-button--on"),
|
|
2254
2479
|
onClick: () => setChangesOpen(!changesOpen),
|
|
2255
2480
|
"aria-pressed": changesOpen,
|
|
2256
2481
|
title: "Files this chat changed",
|
|
2257
2482
|
children: [
|
|
2258
|
-
/* @__PURE__ */ (0,
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FileIcon, { size: 13 }),
|
|
2259
2484
|
files.length > 0 ? `${files.length} ${files.length === 1 ? "file" : "files"} changed` : "Changes"
|
|
2260
2485
|
]
|
|
2261
2486
|
}
|
|
2262
2487
|
),
|
|
2263
|
-
/* @__PURE__ */ (0,
|
|
2264
|
-
live ? /* @__PURE__ */ (0,
|
|
2265
|
-
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 }),
|
|
2266
2491
|
stopping ? "Stopping\u2026" : "Stop"
|
|
2267
2492
|
] }) : null,
|
|
2268
|
-
/* @__PURE__ */ (0,
|
|
2493
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderMenu, { entry, onRename: () => setRenaming(true) })
|
|
2269
2494
|
] }),
|
|
2270
|
-
/* @__PURE__ */ (0,
|
|
2271
|
-
/* @__PURE__ */ (0,
|
|
2272
|
-
/* @__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 }),
|
|
2273
2498
|
" Loading the conversation\u2026"
|
|
2274
|
-
] }) : /* @__PURE__ */ (0,
|
|
2275
|
-
transcript.state.unavailable ? /* @__PURE__ */ (0,
|
|
2276
|
-
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)(
|
|
2277
2502
|
LongChatNote,
|
|
2278
2503
|
{
|
|
2279
2504
|
loading: transcript.state.loadingEarlier === true,
|
|
2280
2505
|
onEarlier: () => void transcript.loadEarlier()
|
|
2281
2506
|
}
|
|
2282
2507
|
) : null,
|
|
2283
|
-
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}` })
|
|
2284
2509
|
] }) }),
|
|
2285
|
-
/* @__PURE__ */ (0,
|
|
2286
|
-
limited ? /* @__PURE__ */ (0,
|
|
2287
|
-
/* @__PURE__ */ (0,
|
|
2288
|
-
/* @__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: [
|
|
2289
2514
|
limited.problem,
|
|
2290
2515
|
" ",
|
|
2291
2516
|
limited.fix
|
|
2292
2517
|
] })
|
|
2293
2518
|
] }) : null,
|
|
2294
|
-
modelRefused && !blocked ? /* @__PURE__ */ (0,
|
|
2519
|
+
modelRefused && !blocked ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2295
2520
|
"div",
|
|
2296
2521
|
{
|
|
2297
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]",
|
|
2298
2523
|
role: "alert",
|
|
2299
2524
|
children: [
|
|
2300
|
-
/* @__PURE__ */ (0,
|
|
2301
|
-
/* @__PURE__ */ (0,
|
|
2302
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
2303
2528
|
ModelPicker,
|
|
2304
2529
|
{
|
|
2305
2530
|
status: provider,
|
|
@@ -2310,32 +2535,32 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2310
2535
|
]
|
|
2311
2536
|
}
|
|
2312
2537
|
) : null,
|
|
2313
|
-
blocked ? /* @__PURE__ */ (0,
|
|
2314
|
-
/* @__PURE__ */ (0,
|
|
2315
|
-
/* @__PURE__ */ (0,
|
|
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: [
|
|
2316
2541
|
blocked.problem,
|
|
2317
2542
|
" ",
|
|
2318
2543
|
blocked.fix
|
|
2319
2544
|
] })
|
|
2320
2545
|
] }) : null,
|
|
2321
|
-
/* @__PURE__ */ (0,
|
|
2322
|
-
/* @__PURE__ */ (0,
|
|
2323
|
-
/* @__PURE__ */ (0,
|
|
2324
|
-
/* @__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" })
|
|
2325
2550
|
] }) : null }),
|
|
2326
|
-
elsewhere ? /* @__PURE__ */ (0,
|
|
2327
|
-
/* @__PURE__ */ (0,
|
|
2328
|
-
/* @__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: [
|
|
2329
2554
|
elsewhere.message,
|
|
2330
2555
|
" A message sent here would put a second agent on the same chat."
|
|
2331
2556
|
] })
|
|
2332
2557
|
] }) : null,
|
|
2333
|
-
session.queued.length > 0 ? /* @__PURE__ */ (0,
|
|
2334
|
-
/* @__PURE__ */ (0,
|
|
2335
|
-
/* @__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 })
|
|
2336
2561
|
] }, `${index}-${text.slice(0, 16)}`)) }) : null,
|
|
2337
|
-
/* @__PURE__ */ (0,
|
|
2338
|
-
|
|
2562
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2563
|
+
import_react9.ChatComposer,
|
|
2339
2564
|
{
|
|
2340
2565
|
placeholder: `Message ${PROVIDER_LABEL[session.provider]}\u2026`,
|
|
2341
2566
|
autoFocus: true,
|
|
@@ -2345,14 +2570,14 @@ function SessionView({ session, changesOpen, setChangesOpen }) {
|
|
|
2345
2570
|
] })
|
|
2346
2571
|
] }) })
|
|
2347
2572
|
] }),
|
|
2348
|
-
changesOpen ? /* @__PURE__ */ (0,
|
|
2573
|
+
changesOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChangesPanel, { files, cwd: session.cwd, truncated: transcript.state.truncated, onClose: () => setChangesOpen(false) }) : null
|
|
2349
2574
|
] });
|
|
2350
2575
|
}
|
|
2351
2576
|
function usePreviewThread(id, onSend) {
|
|
2352
|
-
const ref = (0,
|
|
2353
|
-
const send = (0,
|
|
2577
|
+
const ref = (0, import_react8.useRef)({ messages: [], listeners: /* @__PURE__ */ new Set() });
|
|
2578
|
+
const send = (0, import_react8.useRef)(onSend);
|
|
2354
2579
|
send.current = onSend;
|
|
2355
|
-
const thread = (0,
|
|
2580
|
+
const thread = (0, import_react8.useMemo)(
|
|
2356
2581
|
() => (0, import_external_store2.createExternalThreadSource)({
|
|
2357
2582
|
getSnapshot: () => ({ messages: ref.current.messages, status: "idle", conversationId: id }),
|
|
2358
2583
|
subscribe: (listener) => {
|
|
@@ -2366,7 +2591,7 @@ function usePreviewThread(id, onSend) {
|
|
|
2366
2591
|
}),
|
|
2367
2592
|
[id]
|
|
2368
2593
|
);
|
|
2369
|
-
const set = (0,
|
|
2594
|
+
const set = (0, import_react8.useCallback)((messages) => {
|
|
2370
2595
|
ref.current.messages = messages;
|
|
2371
2596
|
for (const listener of ref.current.listeners) listener();
|
|
2372
2597
|
}, []);
|
|
@@ -2375,15 +2600,15 @@ function usePreviewThread(id, onSend) {
|
|
|
2375
2600
|
function DiscoveredView(props) {
|
|
2376
2601
|
const client = useCodingSessionsClient();
|
|
2377
2602
|
const state = useCodingSessionsState();
|
|
2378
|
-
const show = (0,
|
|
2603
|
+
const show = (0, import_react8.useContext)(ToastContext);
|
|
2379
2604
|
const now = useMinuteClock();
|
|
2380
|
-
const [preview, setPreview] = (0,
|
|
2381
|
-
const [busy, setBusy] = (0,
|
|
2382
|
-
const [error, setError] = (0,
|
|
2383
|
-
const [confirming, setConfirming] = (0,
|
|
2384
|
-
const [renaming, setRenaming] = (0,
|
|
2385
|
-
const [maxBytes, setMaxBytes] = (0,
|
|
2386
|
-
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);
|
|
2387
2612
|
const elsewhere = useLiveElsewhere(props.provider, props.id, props.session?.activeElsewhere ?? null);
|
|
2388
2613
|
const files = useChangedFiles(preview.messages);
|
|
2389
2614
|
const d = props.session;
|
|
@@ -2393,7 +2618,7 @@ function DiscoveredView(props) {
|
|
|
2393
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."
|
|
2394
2619
|
)
|
|
2395
2620
|
);
|
|
2396
|
-
(0,
|
|
2621
|
+
(0, import_react8.useEffect)(() => {
|
|
2397
2622
|
let cancelled = false;
|
|
2398
2623
|
const read = (first) => client.readPreview(props.provider, props.id, maxBytes).then((next) => {
|
|
2399
2624
|
if (cancelled) return;
|
|
@@ -2432,26 +2657,26 @@ function DiscoveredView(props) {
|
|
|
2432
2657
|
setBusy(false);
|
|
2433
2658
|
}
|
|
2434
2659
|
};
|
|
2435
|
-
return /* @__PURE__ */ (0,
|
|
2436
|
-
/* @__PURE__ */ (0,
|
|
2437
|
-
/* @__PURE__ */ (0,
|
|
2438
|
-
/* @__PURE__ */ (0,
|
|
2439
|
-
/* @__PURE__ */ (0,
|
|
2440
|
-
/* @__PURE__ */ (0,
|
|
2441
|
-
/* @__PURE__ */ (0,
|
|
2442
|
-
/* @__PURE__ */ (0,
|
|
2443
|
-
d?.cwd ? /* @__PURE__ */ (0,
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
2445
|
-
/* @__PURE__ */ (0,
|
|
2446
|
-
/* @__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) })
|
|
2447
2672
|
] }) : null,
|
|
2448
|
-
d ? /* @__PURE__ */ (0,
|
|
2673
|
+
d ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
2449
2674
|
"\xB7 last active ",
|
|
2450
2675
|
relativeTime(d.updatedAt, now)
|
|
2451
2676
|
] }) : null
|
|
2452
2677
|
] })
|
|
2453
2678
|
] }),
|
|
2454
|
-
files.length > 0 ? /* @__PURE__ */ (0,
|
|
2679
|
+
files.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2455
2680
|
"button",
|
|
2456
2681
|
{
|
|
2457
2682
|
type: "button",
|
|
@@ -2460,13 +2685,13 @@ function DiscoveredView(props) {
|
|
|
2460
2685
|
"aria-pressed": props.changesOpen,
|
|
2461
2686
|
title: "Files this chat changed",
|
|
2462
2687
|
children: [
|
|
2463
|
-
/* @__PURE__ */ (0,
|
|
2688
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FileIcon, { size: 13 }),
|
|
2464
2689
|
`${files.length} ${files.length === 1 ? "file" : "files"} changed`
|
|
2465
2690
|
]
|
|
2466
2691
|
}
|
|
2467
2692
|
) : null,
|
|
2468
|
-
d?.cwd ? /* @__PURE__ */ (0,
|
|
2469
|
-
|
|
2693
|
+
d?.cwd ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2694
|
+
import_design_system6.Button,
|
|
2470
2695
|
{
|
|
2471
2696
|
size: "sm",
|
|
2472
2697
|
variant: elsewhere ? "outline" : "default",
|
|
@@ -2475,44 +2700,44 @@ function DiscoveredView(props) {
|
|
|
2475
2700
|
className: "gap-1.5",
|
|
2476
2701
|
title: elsewhere ? elsewhere.message : void 0,
|
|
2477
2702
|
children: [
|
|
2478
|
-
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 }),
|
|
2479
2704
|
elsewhere ? "Take over anyway\u2026" : "Take over"
|
|
2480
2705
|
]
|
|
2481
2706
|
}
|
|
2482
2707
|
) : null,
|
|
2483
|
-
d ? /* @__PURE__ */ (0,
|
|
2708
|
+
d ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderMenu, { entry, onRename: () => setRenaming(true) }) : null
|
|
2484
2709
|
] }),
|
|
2485
|
-
elsewhere ? /* @__PURE__ */ (0,
|
|
2486
|
-
/* @__PURE__ */ (0,
|
|
2487
|
-
/* @__PURE__ */ (0,
|
|
2488
|
-
/* @__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 }),
|
|
2489
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."
|
|
2490
2715
|
] })
|
|
2491
2716
|
] }) : null,
|
|
2492
|
-
/* @__PURE__ */ (0,
|
|
2493
|
-
/* @__PURE__ */ (0,
|
|
2494
|
-
/* @__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: [
|
|
2495
2720
|
"This chat is running right now in ",
|
|
2496
2721
|
PROVIDER_LABEL[props.provider]
|
|
2497
2722
|
] }),
|
|
2498
|
-
/* @__PURE__ */ (0,
|
|
2723
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system6.DialogDescription, { children: [
|
|
2499
2724
|
elsewhere?.message,
|
|
2500
2725
|
" If you take it over, two agents will work in the same conversation at once and may overwrite each other's changes."
|
|
2501
2726
|
] })
|
|
2502
2727
|
] }),
|
|
2503
|
-
/* @__PURE__ */ (0,
|
|
2504
|
-
/* @__PURE__ */ (0,
|
|
2505
|
-
/* @__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" })
|
|
2506
2731
|
] })
|
|
2507
2732
|
] }) }),
|
|
2508
|
-
error ? /* @__PURE__ */ (0,
|
|
2509
|
-
d && !d.cwd ? /* @__PURE__ */ (0,
|
|
2510
|
-
/* @__PURE__ */ (0,
|
|
2511
|
-
preview.loading ? /* @__PURE__ */ (0,
|
|
2512
|
-
/* @__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 }),
|
|
2513
2738
|
" Reading this chat\u2026"
|
|
2514
|
-
] }) : preview.unavailable ? /* @__PURE__ */ (0,
|
|
2515
|
-
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)(
|
|
2516
2741
|
LongChatNote,
|
|
2517
2742
|
{
|
|
2518
2743
|
loading: readingEarlier,
|
|
@@ -2522,14 +2747,14 @@ function DiscoveredView(props) {
|
|
|
2522
2747
|
}
|
|
2523
2748
|
}
|
|
2524
2749
|
) : null,
|
|
2525
|
-
/* @__PURE__ */ (0,
|
|
2750
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react9.ChatMessageList, { className: "min-h-0 flex-1", label: "Chat preview" })
|
|
2526
2751
|
] }),
|
|
2527
|
-
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: [
|
|
2528
2753
|
"This chat was started in ",
|
|
2529
2754
|
PROVIDER_LABEL[props.provider],
|
|
2530
2755
|
".",
|
|
2531
2756
|
" ",
|
|
2532
|
-
/* @__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" }),
|
|
2533
2758
|
" ",
|
|
2534
2759
|
"to continue it here \u2014 it stays in your ",
|
|
2535
2760
|
PROVIDER_LABEL[props.provider],
|
|
@@ -2537,70 +2762,73 @@ function DiscoveredView(props) {
|
|
|
2537
2762
|
] }) : null
|
|
2538
2763
|
] })
|
|
2539
2764
|
] }),
|
|
2540
|
-
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
|
|
2541
2766
|
] });
|
|
2542
2767
|
}
|
|
2543
2768
|
function ProviderCard(props) {
|
|
2544
2769
|
const ready = props.status.ready;
|
|
2545
|
-
return /* @__PURE__ */ (0,
|
|
2770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2546
2771
|
"button",
|
|
2547
2772
|
{
|
|
2548
2773
|
type: "button",
|
|
2549
2774
|
onClick: props.onSelect,
|
|
2550
2775
|
"aria-pressed": props.selected,
|
|
2551
|
-
className: (0,
|
|
2776
|
+
className: (0, import_design_system6.cn)(
|
|
2552
2777
|
"flex flex-1 flex-col gap-1.5 rounded-xl border px-3.5 py-3 text-left transition-colors",
|
|
2553
2778
|
props.selected ? "border-primary bg-primary/5 ring-1 ring-primary" : "border-border hover:bg-accent/50"
|
|
2554
2779
|
),
|
|
2555
2780
|
children: [
|
|
2556
|
-
/* @__PURE__ */ (0,
|
|
2557
|
-
/* @__PURE__ */ (0,
|
|
2558
|
-
/* @__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 })
|
|
2559
2784
|
] }),
|
|
2560
|
-
ready ? /* @__PURE__ */ (0,
|
|
2561
|
-
/* @__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 }),
|
|
2562
2787
|
props.status.billing === "subscription" ? `Signed in${props.status.plan ? ` \xB7 ${props.status.plan} plan` : ""}` : "Signed in with an API key (billed per use)"
|
|
2563
|
-
] }) : /* @__PURE__ */ (0,
|
|
2564
|
-
/* @__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" }),
|
|
2565
2790
|
props.status.problem
|
|
2566
2791
|
] }),
|
|
2567
|
-
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
|
|
2568
2793
|
]
|
|
2569
2794
|
}
|
|
2570
2795
|
);
|
|
2571
2796
|
}
|
|
2572
2797
|
function FieldError({ id, children }) {
|
|
2573
|
-
return /* @__PURE__ */ (0,
|
|
2574
|
-
/* @__PURE__ */ (0,
|
|
2575
|
-
/* @__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 })
|
|
2576
2801
|
] });
|
|
2577
2802
|
}
|
|
2578
2803
|
function NewSessionDialog(props) {
|
|
2579
2804
|
const client = useCodingSessionsClient();
|
|
2580
2805
|
const state = useCodingSessionsState();
|
|
2581
2806
|
const now = useMinuteClock();
|
|
2582
|
-
const [provider, setProvider] = (0,
|
|
2583
|
-
const [folder, setFolder] = (0,
|
|
2584
|
-
const [choice, setChoice] = (0,
|
|
2585
|
-
const [prompt, setPrompt] = (0,
|
|
2586
|
-
const [errors, setErrors] = (0,
|
|
2587
|
-
const [problem, setProblem] = (0,
|
|
2588
|
-
const [starting, setStarting] = (0,
|
|
2589
|
-
const [creating, setCreating] = (0,
|
|
2590
|
-
const
|
|
2591
|
-
const
|
|
2592
|
-
const
|
|
2593
|
-
(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)(() => {
|
|
2594
2822
|
if (!props.open) return;
|
|
2595
2823
|
setProblem(null);
|
|
2596
2824
|
setErrors({});
|
|
2597
2825
|
void client.refreshProviders();
|
|
2598
2826
|
void client.refreshFolders();
|
|
2599
2827
|
}, [props.open, client]);
|
|
2600
|
-
(0,
|
|
2828
|
+
(0, import_react8.useEffect)(() => {
|
|
2601
2829
|
if (!folder && state.folders.data[0]?.exists) setFolder(state.folders.data[0].path);
|
|
2602
2830
|
}, [state.folders.data, folder]);
|
|
2603
|
-
(0,
|
|
2831
|
+
(0, import_react8.useEffect)(() => {
|
|
2604
2832
|
const ready = state.providers.data.filter((p) => p.ready);
|
|
2605
2833
|
const current = state.providers.data.find((p) => p.provider === provider);
|
|
2606
2834
|
if (current && !current.ready && ready[0]) setProvider(ready[0].provider);
|
|
@@ -2626,9 +2854,22 @@ function NewSessionDialog(props) {
|
|
|
2626
2854
|
focusField(first);
|
|
2627
2855
|
return;
|
|
2628
2856
|
}
|
|
2857
|
+
const missing = missingRequiredVariable(agentDetails, agent);
|
|
2858
|
+
setAgentMissing(missing);
|
|
2859
|
+
if (missing) {
|
|
2860
|
+
document.getElementById(`cs-agent-var-${missing}`)?.focus();
|
|
2861
|
+
return;
|
|
2862
|
+
}
|
|
2629
2863
|
setStarting(true);
|
|
2630
2864
|
try {
|
|
2631
|
-
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
|
+
});
|
|
2632
2873
|
setPrompt("");
|
|
2633
2874
|
props.onStarted(result.session.id);
|
|
2634
2875
|
} catch (error) {
|
|
@@ -2664,16 +2905,16 @@ function NewSessionDialog(props) {
|
|
|
2664
2905
|
if (field === "folder") delete next.createFolder;
|
|
2665
2906
|
return next;
|
|
2666
2907
|
});
|
|
2667
|
-
return /* @__PURE__ */ (0,
|
|
2668
|
-
/* @__PURE__ */ (0,
|
|
2669
|
-
/* @__PURE__ */ (0,
|
|
2670
|
-
/* @__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: [
|
|
2671
2912
|
"Runs on your own ",
|
|
2672
2913
|
provider === "claude" ? "Claude" : "ChatGPT",
|
|
2673
2914
|
" sign-in, in a folder on this computer."
|
|
2674
2915
|
] })
|
|
2675
2916
|
] }),
|
|
2676
|
-
/* @__PURE__ */ (0,
|
|
2917
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2677
2918
|
"form",
|
|
2678
2919
|
{
|
|
2679
2920
|
noValidate: true,
|
|
@@ -2683,13 +2924,13 @@ function NewSessionDialog(props) {
|
|
|
2683
2924
|
},
|
|
2684
2925
|
className: "flex min-h-0 flex-col",
|
|
2685
2926
|
children: [
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2687
|
-
/* @__PURE__ */ (0,
|
|
2688
|
-
/* @__PURE__ */ (0,
|
|
2689
|
-
state.providers.loading && state.providers.loadedAt === null ? /* @__PURE__ */ (0,
|
|
2690
|
-
/* @__PURE__ */ (0,
|
|
2691
|
-
/* @__PURE__ */ (0,
|
|
2692
|
-
] }) : 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)(
|
|
2693
2934
|
ProviderCard,
|
|
2694
2935
|
{
|
|
2695
2936
|
status: p,
|
|
@@ -2702,14 +2943,31 @@ function NewSessionDialog(props) {
|
|
|
2702
2943
|
},
|
|
2703
2944
|
p.provider
|
|
2704
2945
|
)) }),
|
|
2705
|
-
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: [
|
|
2706
2947
|
selected.fix,
|
|
2707
2948
|
selected.installed && selected.loggedIn ? " You can still try \u2014 the run will say if it's still blocked." : ""
|
|
2708
2949
|
] }) : null
|
|
2709
2950
|
] }),
|
|
2710
|
-
/* @__PURE__ */ (0,
|
|
2711
|
-
/* @__PURE__ */ (0,
|
|
2712
|
-
|
|
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)(
|
|
2713
2971
|
"button",
|
|
2714
2972
|
{
|
|
2715
2973
|
type: "button",
|
|
@@ -2719,21 +2977,21 @@ function NewSessionDialog(props) {
|
|
|
2719
2977
|
},
|
|
2720
2978
|
disabled: !f.exists,
|
|
2721
2979
|
title: f.exists ? f.path : `${f.path} no longer exists`,
|
|
2722
|
-
className: (0,
|
|
2980
|
+
className: (0, import_design_system6.cn)(
|
|
2723
2981
|
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[12.5px]",
|
|
2724
2982
|
folder === f.path ? "bg-accent text-accent-foreground" : "hover:bg-accent/50",
|
|
2725
2983
|
!f.exists && "opacity-50"
|
|
2726
2984
|
),
|
|
2727
2985
|
children: [
|
|
2728
|
-
/* @__PURE__ */ (0,
|
|
2729
|
-
/* @__PURE__ */ (0,
|
|
2730
|
-
/* @__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" })
|
|
2731
2989
|
]
|
|
2732
2990
|
},
|
|
2733
2991
|
f.path
|
|
2734
|
-
)) }) : state.folders.loading ? /* @__PURE__ */ (0,
|
|
2735
|
-
/* @__PURE__ */ (0,
|
|
2736
|
-
|
|
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,
|
|
2737
2995
|
{
|
|
2738
2996
|
ref: folderRef,
|
|
2739
2997
|
value: folder,
|
|
@@ -2748,18 +3006,18 @@ function NewSessionDialog(props) {
|
|
|
2748
3006
|
spellCheck: false
|
|
2749
3007
|
}
|
|
2750
3008
|
),
|
|
2751
|
-
errors.folder ? /* @__PURE__ */ (0,
|
|
2752
|
-
/* @__PURE__ */ (0,
|
|
2753
|
-
errors.createFolder ? /* @__PURE__ */ (0,
|
|
2754
|
-
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 }),
|
|
2755
3013
|
"Create this folder"
|
|
2756
3014
|
] }) : null
|
|
2757
3015
|
] }) : null
|
|
2758
3016
|
] }),
|
|
2759
|
-
/* @__PURE__ */ (0,
|
|
2760
|
-
/* @__PURE__ */ (0,
|
|
2761
|
-
/* @__PURE__ */ (0,
|
|
2762
|
-
|
|
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,
|
|
2763
3021
|
{
|
|
2764
3022
|
ref: promptRef,
|
|
2765
3023
|
value: prompt,
|
|
@@ -2780,25 +3038,25 @@ function NewSessionDialog(props) {
|
|
|
2780
3038
|
"aria-describedby": errors.prompt ? "cs-err-prompt" : void 0
|
|
2781
3039
|
}
|
|
2782
3040
|
),
|
|
2783
|
-
errors.prompt ? /* @__PURE__ */ (0,
|
|
3041
|
+
errors.prompt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldError, { id: "cs-err-prompt", children: errors.prompt }) : null
|
|
2784
3042
|
] }),
|
|
2785
|
-
/* @__PURE__ */ (0,
|
|
2786
|
-
/* @__PURE__ */ (0,
|
|
2787
|
-
/* @__PURE__ */ (0,
|
|
2788
|
-
/* @__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: [
|
|
2789
3047
|
"Default is ",
|
|
2790
3048
|
defaultModelWords(selected),
|
|
2791
3049
|
". You can change it later from the chat's header."
|
|
2792
3050
|
] })
|
|
2793
3051
|
] }),
|
|
2794
|
-
problem ? /* @__PURE__ */ (0,
|
|
3052
|
+
problem ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldError, { id: "cs-err-start", children: problem }) : null
|
|
2795
3053
|
] }),
|
|
2796
|
-
/* @__PURE__ */ (0,
|
|
2797
|
-
/* @__PURE__ */ (0,
|
|
2798
|
-
/* @__PURE__ */ (0,
|
|
2799
|
-
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,
|
|
2800
3058
|
starting ? "Starting\u2026" : "Start session",
|
|
2801
|
-
!starting ? /* @__PURE__ */ (0,
|
|
3059
|
+
!starting ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "cs-kbd", children: "\u2318\u21B5" }) : null
|
|
2802
3060
|
] })
|
|
2803
3061
|
] })
|
|
2804
3062
|
]
|
|
@@ -2808,34 +3066,34 @@ function NewSessionDialog(props) {
|
|
|
2808
3066
|
}
|
|
2809
3067
|
function Home({ onNew }) {
|
|
2810
3068
|
const state = useCodingSessionsState();
|
|
2811
|
-
return /* @__PURE__ */ (0,
|
|
2812
|
-
/* @__PURE__ */ (0,
|
|
2813
|
-
/* @__PURE__ */ (0,
|
|
2814
|
-
/* @__PURE__ */ (0,
|
|
2815
|
-
/* @__PURE__ */ (0,
|
|
2816
|
-
/* @__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 }),
|
|
2817
3075
|
"New session"
|
|
2818
3076
|
] }),
|
|
2819
|
-
/* @__PURE__ */ (0,
|
|
2820
|
-
/* @__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" }),
|
|
2821
3079
|
" new session \xB7 ",
|
|
2822
|
-
/* @__PURE__ */ (0,
|
|
3080
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "cs-kbd", children: "\u2318K" }),
|
|
2823
3081
|
" search your chats \xB7",
|
|
2824
3082
|
" ",
|
|
2825
|
-
/* @__PURE__ */ (0,
|
|
3083
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("kbd", { className: "cs-kbd", children: "\u2318/" }),
|
|
2826
3084
|
" all shortcuts"
|
|
2827
3085
|
] }),
|
|
2828
|
-
/* @__PURE__ */ (0,
|
|
2829
|
-
/* @__PURE__ */ (0,
|
|
2830
|
-
/* @__PURE__ */ (0,
|
|
2831
|
-
/* @__PURE__ */ (0,
|
|
2832
|
-
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: [
|
|
2833
3091
|
" ",
|
|
2834
3092
|
"\u2014 ready",
|
|
2835
3093
|
p.plan ? ` on your ${p.plan} plan` : "",
|
|
2836
3094
|
p.billing === "api" ? " (API key, billed per use)" : ""
|
|
2837
3095
|
] }) : null,
|
|
2838
|
-
p.installed && p.version ? /* @__PURE__ */ (0,
|
|
3096
|
+
p.installed && p.version ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2839
3097
|
"span",
|
|
2840
3098
|
{
|
|
2841
3099
|
className: "block text-[11.5px] text-muted-foreground",
|
|
@@ -2846,23 +3104,23 @@ function Home({ onNew }) {
|
|
|
2846
3104
|
]
|
|
2847
3105
|
}
|
|
2848
3106
|
) : null,
|
|
2849
|
-
p.ready ? null : /* @__PURE__ */ (0,
|
|
3107
|
+
p.ready ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "block text-muted-foreground", children: [
|
|
2850
3108
|
p.problem,
|
|
2851
3109
|
" ",
|
|
2852
3110
|
p.fix
|
|
2853
3111
|
] })
|
|
2854
3112
|
] }),
|
|
2855
|
-
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" })
|
|
2856
3114
|
] }, p.provider)) })
|
|
2857
3115
|
] }) });
|
|
2858
3116
|
}
|
|
2859
3117
|
function useToast() {
|
|
2860
|
-
const [text, setText] = (0,
|
|
2861
|
-
const timer = (0,
|
|
2862
|
-
(0,
|
|
3118
|
+
const [text, setText] = (0, import_react8.useState)(null);
|
|
3119
|
+
const timer = (0, import_react8.useRef)(null);
|
|
3120
|
+
(0, import_react8.useEffect)(() => () => {
|
|
2863
3121
|
if (timer.current) clearTimeout(timer.current);
|
|
2864
3122
|
}, []);
|
|
2865
|
-
const show = (0,
|
|
3123
|
+
const show = (0, import_react8.useCallback)((next) => {
|
|
2866
3124
|
setText(next);
|
|
2867
3125
|
if (timer.current) clearTimeout(timer.current);
|
|
2868
3126
|
timer.current = setTimeout(() => setText(null), 6e3);
|
|
@@ -2871,7 +3129,7 @@ function useToast() {
|
|
|
2871
3129
|
}
|
|
2872
3130
|
function Toast({ text }) {
|
|
2873
3131
|
if (!text) return null;
|
|
2874
|
-
return /* @__PURE__ */ (0,
|
|
3132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { role: "status", className: "cs-toast", children: text });
|
|
2875
3133
|
}
|
|
2876
3134
|
var SIDEBAR_DEFAULT = 300;
|
|
2877
3135
|
var SIDEBAR_MIN = 220;
|
|
@@ -2880,7 +3138,7 @@ function clampWidth(n) {
|
|
|
2880
3138
|
return Math.round(Math.min(SIDEBAR_MAX, Math.max(SIDEBAR_MIN, n)));
|
|
2881
3139
|
}
|
|
2882
3140
|
function useSidebarLayout() {
|
|
2883
|
-
const [width, setWidthState] = (0,
|
|
3141
|
+
const [width, setWidthState] = (0, import_react8.useState)(() => {
|
|
2884
3142
|
try {
|
|
2885
3143
|
const n = Number(localStorage.getItem("coding-sessions.sidebar-width"));
|
|
2886
3144
|
return Number.isFinite(n) && n > 0 ? clampWidth(n) : SIDEBAR_DEFAULT;
|
|
@@ -2888,14 +3146,14 @@ function useSidebarLayout() {
|
|
|
2888
3146
|
return SIDEBAR_DEFAULT;
|
|
2889
3147
|
}
|
|
2890
3148
|
});
|
|
2891
|
-
const [collapsed, setCollapsedState] = (0,
|
|
3149
|
+
const [collapsed, setCollapsedState] = (0, import_react8.useState)(() => {
|
|
2892
3150
|
try {
|
|
2893
3151
|
return localStorage.getItem("coding-sessions.sidebar-collapsed") === "1";
|
|
2894
3152
|
} catch {
|
|
2895
3153
|
return false;
|
|
2896
3154
|
}
|
|
2897
3155
|
});
|
|
2898
|
-
const setWidth = (0,
|
|
3156
|
+
const setWidth = (0, import_react8.useCallback)((n) => {
|
|
2899
3157
|
const next = clampWidth(n);
|
|
2900
3158
|
setWidthState(next);
|
|
2901
3159
|
try {
|
|
@@ -2903,7 +3161,7 @@ function useSidebarLayout() {
|
|
|
2903
3161
|
} catch {
|
|
2904
3162
|
}
|
|
2905
3163
|
}, []);
|
|
2906
|
-
const setCollapsed = (0,
|
|
3164
|
+
const setCollapsed = (0, import_react8.useCallback)((v) => {
|
|
2907
3165
|
setCollapsedState(v);
|
|
2908
3166
|
try {
|
|
2909
3167
|
localStorage.setItem("coding-sessions.sidebar-collapsed", v ? "1" : "0");
|
|
@@ -2913,8 +3171,8 @@ function useSidebarLayout() {
|
|
|
2913
3171
|
return { width, setWidth, collapsed, setCollapsed };
|
|
2914
3172
|
}
|
|
2915
3173
|
function Resizer(props) {
|
|
2916
|
-
const [dragging, setDragging] = (0,
|
|
2917
|
-
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)(
|
|
2918
3176
|
"button",
|
|
2919
3177
|
{
|
|
2920
3178
|
type: "button",
|
|
@@ -2962,24 +3220,24 @@ var SHORTCUTS = [
|
|
|
2962
3220
|
{ keys: "\u2318/", what: "These shortcuts" }
|
|
2963
3221
|
];
|
|
2964
3222
|
function ShortcutsDialog(props) {
|
|
2965
|
-
return /* @__PURE__ */ (0,
|
|
2966
|
-
/* @__PURE__ */ (0,
|
|
2967
|
-
/* @__PURE__ */ (0,
|
|
2968
|
-
/* @__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." })
|
|
2969
3227
|
] }),
|
|
2970
|
-
/* @__PURE__ */ (0,
|
|
2971
|
-
/* @__PURE__ */ (0,
|
|
2972
|
-
/* @__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 }) })
|
|
2973
3231
|
] }, s.keys)) })
|
|
2974
3232
|
] }) });
|
|
2975
3233
|
}
|
|
2976
3234
|
var BASE_TITLE = "Coding sessions";
|
|
2977
3235
|
function useRunFinishedNotices(openSessionId, show) {
|
|
2978
3236
|
const client = useCodingSessionsClient();
|
|
2979
|
-
const unseen = (0,
|
|
2980
|
-
const openRef = (0,
|
|
3237
|
+
const unseen = (0, import_react8.useRef)(0);
|
|
3238
|
+
const openRef = (0, import_react8.useRef)(openSessionId);
|
|
2981
3239
|
openRef.current = openSessionId;
|
|
2982
|
-
(0,
|
|
3240
|
+
(0, import_react8.useEffect)(() => {
|
|
2983
3241
|
const reset = () => {
|
|
2984
3242
|
if (document.visibilityState === "visible") {
|
|
2985
3243
|
unseen.current = 0;
|
|
@@ -3014,9 +3272,9 @@ function useRunFinishedNotices(openSessionId, show) {
|
|
|
3014
3272
|
}
|
|
3015
3273
|
function NotifyToggle() {
|
|
3016
3274
|
const supported = typeof Notification !== "undefined";
|
|
3017
|
-
const [permission, setPermission] = (0,
|
|
3275
|
+
const [permission, setPermission] = (0, import_react8.useState)(supported ? Notification.permission : "denied");
|
|
3018
3276
|
if (!supported || permission === "granted") return null;
|
|
3019
|
-
return /* @__PURE__ */ (0,
|
|
3277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3020
3278
|
"button",
|
|
3021
3279
|
{
|
|
3022
3280
|
type: "button",
|
|
@@ -3025,7 +3283,7 @@ function NotifyToggle() {
|
|
|
3025
3283
|
"aria-label": permission === "denied" ? "Notifications are blocked for this page in your browser's site settings" : "Notify me when a run finishes",
|
|
3026
3284
|
title: permission === "denied" ? "Notifications are blocked in your browser's site settings" : "Notify me when a run finishes",
|
|
3027
3285
|
disabled: permission === "denied",
|
|
3028
|
-
children: /* @__PURE__ */ (0,
|
|
3286
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BellIcon, { size: 14 })
|
|
3029
3287
|
}
|
|
3030
3288
|
);
|
|
3031
3289
|
}
|
|
@@ -3037,20 +3295,20 @@ function isTyping(target) {
|
|
|
3037
3295
|
function Shell() {
|
|
3038
3296
|
const client = useCodingSessionsClient();
|
|
3039
3297
|
const state = useCodingSessionsState();
|
|
3040
|
-
const [selection, setSelection] = (0,
|
|
3041
|
-
const [newOpen, setNewOpen] = (0,
|
|
3042
|
-
const [shortcutsOpen, setShortcutsOpen] = (0,
|
|
3043
|
-
const [changesOpen, setChangesOpen] = (0,
|
|
3044
|
-
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)({});
|
|
3045
3303
|
const [theme, setTheme] = useTheme();
|
|
3046
3304
|
const [toast, showToast] = useToast();
|
|
3047
3305
|
const layout = useSidebarLayout();
|
|
3048
|
-
const searchRef = (0,
|
|
3049
|
-
const select = (0,
|
|
3306
|
+
const searchRef = (0, import_react8.useRef)(null);
|
|
3307
|
+
const select = (0, import_react8.useCallback)((next) => {
|
|
3050
3308
|
setSelection(next);
|
|
3051
3309
|
writeHash(next);
|
|
3052
3310
|
}, []);
|
|
3053
|
-
(0,
|
|
3311
|
+
(0, import_react8.useEffect)(() => {
|
|
3054
3312
|
const onHash = () => setSelection(readHash());
|
|
3055
3313
|
window.addEventListener("hashchange", onHash);
|
|
3056
3314
|
return () => window.removeEventListener("hashchange", onHash);
|
|
@@ -3060,14 +3318,14 @@ function Shell() {
|
|
|
3060
3318
|
const discovered = selection.kind === "discovered" ? state.discovered.data.find((d) => d.providerSessionId === selection.id) ?? found[`${selection.provider}:${selection.id}`] ?? null : null;
|
|
3061
3319
|
const run = session ? state.runs[session.id] : void 0;
|
|
3062
3320
|
const live = run !== void 0 && !isTerminalRunStatus(run.status);
|
|
3063
|
-
const order = (0,
|
|
3321
|
+
const order = (0, import_react8.useMemo)(() => {
|
|
3064
3322
|
const known = new Set(state.sessions.data.map((s) => s.providerSessionId).filter(Boolean));
|
|
3065
3323
|
return [
|
|
3066
3324
|
...state.sessions.data.map((s) => ({ kind: "session", id: s.id })),
|
|
3067
3325
|
...state.discovered.data.filter((d) => !known.has(d.providerSessionId)).map((d) => ({ kind: "discovered", provider: d.provider, id: d.providerSessionId }))
|
|
3068
3326
|
];
|
|
3069
3327
|
}, [state.sessions.data, state.discovered.data]);
|
|
3070
|
-
(0,
|
|
3328
|
+
(0, import_react8.useEffect)(() => {
|
|
3071
3329
|
const onKey = (e) => {
|
|
3072
3330
|
const mod = e.metaKey || e.ctrlKey;
|
|
3073
3331
|
const key = e.key.toLowerCase();
|
|
@@ -3123,12 +3381,12 @@ function Shell() {
|
|
|
3123
3381
|
}, [client, layout, live, run, order, selection, select, showToast]);
|
|
3124
3382
|
let main;
|
|
3125
3383
|
if (selection.kind === "session") {
|
|
3126
|
-
main = session ? /* @__PURE__ */ (0,
|
|
3127
|
-
/* @__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 }),
|
|
3128
3386
|
" Loading\u2026"
|
|
3129
|
-
] }) : /* @__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." });
|
|
3130
3388
|
} else if (selection.kind === "discovered") {
|
|
3131
|
-
main = /* @__PURE__ */ (0,
|
|
3389
|
+
main = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3132
3390
|
DiscoveredView,
|
|
3133
3391
|
{
|
|
3134
3392
|
session: discovered,
|
|
@@ -3141,13 +3399,13 @@ function Shell() {
|
|
|
3141
3399
|
`${selection.provider}:${selection.id}`
|
|
3142
3400
|
);
|
|
3143
3401
|
} else {
|
|
3144
|
-
main = /* @__PURE__ */ (0,
|
|
3402
|
+
main = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Home, { onNew: () => setNewOpen(true) });
|
|
3145
3403
|
}
|
|
3146
|
-
return /* @__PURE__ */ (0,
|
|
3147
|
-
/* @__PURE__ */ (0,
|
|
3148
|
-
/* @__PURE__ */ (0,
|
|
3149
|
-
layout.collapsed ? /* @__PURE__ */ (0,
|
|
3150
|
-
/* @__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)(
|
|
3151
3409
|
"button",
|
|
3152
3410
|
{
|
|
3153
3411
|
type: "button",
|
|
@@ -3155,10 +3413,10 @@ function Shell() {
|
|
|
3155
3413
|
onClick: () => layout.setCollapsed(false),
|
|
3156
3414
|
"aria-label": "Show the sidebar (\u2318B)",
|
|
3157
3415
|
title: "Show sidebar \u2318B",
|
|
3158
|
-
children: /* @__PURE__ */ (0,
|
|
3416
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarIcon, { size: 15 })
|
|
3159
3417
|
}
|
|
3160
3418
|
),
|
|
3161
|
-
/* @__PURE__ */ (0,
|
|
3419
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3162
3420
|
"button",
|
|
3163
3421
|
{
|
|
3164
3422
|
type: "button",
|
|
@@ -3166,11 +3424,11 @@ function Shell() {
|
|
|
3166
3424
|
onClick: () => setNewOpen(true),
|
|
3167
3425
|
"aria-label": "New session",
|
|
3168
3426
|
title: "New session \u2325\u2318N",
|
|
3169
|
-
children: /* @__PURE__ */ (0,
|
|
3427
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PlusIcon, { size: 15 })
|
|
3170
3428
|
}
|
|
3171
3429
|
)
|
|
3172
|
-
] }) : /* @__PURE__ */ (0,
|
|
3173
|
-
/* @__PURE__ */ (0,
|
|
3430
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
3431
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3174
3432
|
Sidebar,
|
|
3175
3433
|
{
|
|
3176
3434
|
selection,
|
|
@@ -3180,14 +3438,14 @@ function Shell() {
|
|
|
3180
3438
|
width: layout.width,
|
|
3181
3439
|
searchRef,
|
|
3182
3440
|
onFound: (d) => setFound((f) => ({ ...f, [`${d.provider}:${d.providerSessionId}`]: d })),
|
|
3183
|
-
footer: /* @__PURE__ */ (0,
|
|
3441
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3184
3442
|
ProvidersFooter,
|
|
3185
3443
|
{
|
|
3186
3444
|
theme,
|
|
3187
3445
|
setTheme,
|
|
3188
|
-
extra: /* @__PURE__ */ (0,
|
|
3189
|
-
/* @__PURE__ */ (0,
|
|
3190
|
-
/* @__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)(
|
|
3191
3449
|
"button",
|
|
3192
3450
|
{
|
|
3193
3451
|
type: "button",
|
|
@@ -3195,7 +3453,7 @@ function Shell() {
|
|
|
3195
3453
|
onClick: () => setShortcutsOpen(true),
|
|
3196
3454
|
"aria-label": "Keyboard shortcuts (\u2318/)",
|
|
3197
3455
|
title: "Keyboard shortcuts \u2318/",
|
|
3198
|
-
children: /* @__PURE__ */ (0,
|
|
3456
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(KeyboardIcon, { size: 14 })
|
|
3199
3457
|
}
|
|
3200
3458
|
)
|
|
3201
3459
|
] })
|
|
@@ -3203,11 +3461,11 @@ function Shell() {
|
|
|
3203
3461
|
)
|
|
3204
3462
|
}
|
|
3205
3463
|
),
|
|
3206
|
-
/* @__PURE__ */ (0,
|
|
3464
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Resizer, { width: layout.width, setWidth: layout.setWidth })
|
|
3207
3465
|
] }),
|
|
3208
|
-
/* @__PURE__ */ (0,
|
|
3466
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("main", { className: "flex min-w-0 flex-1", children: main })
|
|
3209
3467
|
] }),
|
|
3210
|
-
/* @__PURE__ */ (0,
|
|
3468
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3211
3469
|
NewSessionDialog,
|
|
3212
3470
|
{
|
|
3213
3471
|
open: newOpen,
|
|
@@ -3218,11 +3476,11 @@ function Shell() {
|
|
|
3218
3476
|
}
|
|
3219
3477
|
}
|
|
3220
3478
|
),
|
|
3221
|
-
/* @__PURE__ */ (0,
|
|
3222
|
-
/* @__PURE__ */ (0,
|
|
3479
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ShortcutsDialog, { open: shortcutsOpen, onOpenChange: setShortcutsOpen }),
|
|
3480
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Toast, { text: toast })
|
|
3223
3481
|
] }) });
|
|
3224
3482
|
}
|
|
3225
3483
|
function CodingSessionsApp({ transport }) {
|
|
3226
|
-
return /* @__PURE__ */ (0,
|
|
3484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CodingSessionsProvider, { transport, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Shell, {}) });
|
|
3227
3485
|
}
|
|
3228
3486
|
//# sourceMappingURL=index.cjs.map
|