research-copilot 0.2.1 → 0.2.2
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/app/out/main/index.mjs +2519 -201
- package/app/out/preload/index.js +21 -0
- package/app/out/renderer/assets/{MilkdownMarkdownEditor-D7GYpVZn.js → MilkdownMarkdownEditor-jaF-aGPn.js} +50 -50
- package/app/out/renderer/assets/{arc-Kp4J_Jd7.js → arc-C1kBmvvR.js} +1 -1
- package/app/out/renderer/assets/{blockDiagram-c4efeb88-DkMSdn8j.js → blockDiagram-c4efeb88-Do93X2rs.js} +8 -8
- package/app/out/renderer/assets/{c4Diagram-c83219d4-DqAGxrYw.js → c4Diagram-c83219d4-DgxxcZWC.js} +3 -3
- package/app/out/renderer/assets/{channel-S4GQrISQ.js → channel-Co_M0Svj.js} +1 -1
- package/app/out/renderer/assets/{classDiagram-beda092f-B7AsTCEg.js → classDiagram-beda092f-CQlHgE6H.js} +6 -6
- package/app/out/renderer/assets/{classDiagram-v2-2358418a-B4oFy-In.js → classDiagram-v2-2358418a-CkGG3aI2.js} +10 -10
- package/app/out/renderer/assets/{clone-Dv1e6zYr.js → clone-C18Y6dgC.js} +1 -1
- package/app/out/renderer/assets/{createText-1719965b-HBXHvWlI.js → createText-1719965b-DGRc6nys.js} +2 -2
- package/app/out/renderer/assets/{edges-96097737-B6X5lcC0.js → edges-96097737-BXvJ4fAK.js} +3 -3
- package/app/out/renderer/assets/{erDiagram-0228fc6a-BmBmTBlH.js → erDiagram-0228fc6a-CXjPp0pt.js} +5 -5
- package/app/out/renderer/assets/{flowDb-c6c81e3f-CObz36ob.js → flowDb-c6c81e3f-CNhpbtw_.js} +1 -1
- package/app/out/renderer/assets/{flowDiagram-50d868cf-C2hFHxwF.js → flowDiagram-50d868cf-KZ_BUCPA.js} +12 -12
- package/app/out/renderer/assets/{flowDiagram-v2-4f6560a1-DEe8EygW.js → flowDiagram-v2-4f6560a1-IMv50KZP.js} +12 -12
- package/app/out/renderer/assets/{flowchart-elk-definition-6af322e1-CgTtfYKk.js → flowchart-elk-definition-6af322e1-BFwFiPvq.js} +6 -6
- package/app/out/renderer/assets/{ganttDiagram-a2739b55-C5Pq4zEy.js → ganttDiagram-a2739b55-D0-ehN-T.js} +3 -3
- package/app/out/renderer/assets/{gitGraphDiagram-82fe8481-oLp0f8Ll.js → gitGraphDiagram-82fe8481-DUyIR0Dv.js} +2 -2
- package/app/out/renderer/assets/{graph-51iZ6wgR.js → graph-DnTq2_3F.js} +1 -1
- package/app/out/renderer/assets/{index-5325376f-yLvOW-Os.js → index-5325376f-CBwuFbRF.js} +6 -6
- package/app/out/renderer/assets/{index-DppxBL77.js → index-7hDGClrI.js} +3 -3
- package/app/out/renderer/assets/{index-Du-Z3sl4.js → index-BB-a1ajC.js} +1295 -487
- package/app/out/renderer/assets/{index-shoMWskw.js → index-BHcU72Rm.js} +3 -3
- package/app/out/renderer/assets/{index-y1Od1ed6.js → index-BQ7qz1CD.js} +3 -3
- package/app/out/renderer/assets/{index-UajPJYNV.js → index-BVYoMX5H.js} +3 -3
- package/app/out/renderer/assets/{index-_Z53hJps.js → index-BpKrXGYD.js} +3 -3
- package/app/out/renderer/assets/{index-32eUzqVW.js → index-C1oXjI4L.js} +3 -3
- package/app/out/renderer/assets/{index-CmpSV9Ld.js → index-CKXwBmK7.js} +5 -5
- package/app/out/renderer/assets/{index-ohN9yRWw.js → index-COZSDrEw.js} +6 -6
- package/app/out/renderer/assets/{index-L4DJn7cw.css → index-CT1HtzVp.css} +157 -10
- package/app/out/renderer/assets/{index-BfWWn8B_.js → index-CjffvluT.js} +6 -6
- package/app/out/renderer/assets/{index-D_Y7v6pE.js → index-D6jljsup.js} +3 -3
- package/app/out/renderer/assets/{index-B9a4DKM-.js → index-D6r8msaQ.js} +3 -3
- package/app/out/renderer/assets/{index-_iFRQTkA.js → index-DWU4ia28.js} +6 -6
- package/app/out/renderer/assets/{index-DjqJjt6u.js → index-DZbrRR7w.js} +6 -6
- package/app/out/renderer/assets/{index-CTmGCKqa.js → index-Diy30-34.js} +4 -4
- package/app/out/renderer/assets/{index-BMsuFGn6.js → index-DuhageEr.js} +3 -3
- package/app/out/renderer/assets/{index-BQA_Kvr6.js → index-ESFHcvWy.js} +3 -3
- package/app/out/renderer/assets/{index-FGsCVYSr.js → index-JT8OCsRP.js} +1 -1
- package/app/out/renderer/assets/{index-Cn2e13ja.js → index-bMe3RSkw.js} +6 -6
- package/app/out/renderer/assets/{index-Bscx_5dF.js → index-gH-w4EHk.js} +3 -3
- package/app/out/renderer/assets/{index-AuZa-hTj.js → index-h_fNksib.js} +3 -3
- package/app/out/renderer/assets/{index-BSd80-j9.js → index-u0FZRZON.js} +4 -4
- package/app/out/renderer/assets/{index-CAOQIqEc.js → index-yanwpi6t.js} +6 -6
- package/app/out/renderer/assets/{infoDiagram-8eee0895-Cm0Hm5ZX.js → infoDiagram-8eee0895-Qra4japr.js} +2 -2
- package/app/out/renderer/assets/{journeyDiagram-c64418c1-A2Gw9bVu.js → journeyDiagram-c64418c1-BTN9SgOL.js} +4 -4
- package/app/out/renderer/assets/{layout-C5N2nTfF.js → layout-DGrHHJdN.js} +2 -2
- package/app/out/renderer/assets/{line-Dn6BEQAK.js → line-DXtxdS2B.js} +1 -1
- package/app/out/renderer/assets/{linear-8wk0rPUX.js → linear-CexrSQK6.js} +1 -1
- package/app/out/renderer/assets/{mindmap-definition-8da855dc-BVy6ISnb.js → mindmap-definition-8da855dc-pvG2hzEB.js} +3 -3
- package/app/out/renderer/assets/{pieDiagram-a8764435-B9_axIHE.js → pieDiagram-a8764435-D_neFVMq.js} +3 -3
- package/app/out/renderer/assets/{quadrantDiagram-1e28029f-B1kmkDFg.js → quadrantDiagram-1e28029f-C47W3UMp.js} +3 -3
- package/app/out/renderer/assets/{requirementDiagram-08caed73-C_bNWUtT.js → requirementDiagram-08caed73-DW4Bo_fu.js} +5 -5
- package/app/out/renderer/assets/{sankeyDiagram-a04cb91d-CD2h1LiI.js → sankeyDiagram-a04cb91d-D_3PD7JI.js} +2 -2
- package/app/out/renderer/assets/{sequenceDiagram-c5b8d532-B6d6cuqi.js → sequenceDiagram-c5b8d532-BW6nGtuQ.js} +3 -3
- package/app/out/renderer/assets/{stateDiagram-1ecb1508-CkuNj_3H.js → stateDiagram-1ecb1508-CDgBJ3-T.js} +6 -6
- package/app/out/renderer/assets/{stateDiagram-v2-c2b004d7-CevZ3tno.js → stateDiagram-v2-c2b004d7-CBw5TtXo.js} +10 -10
- package/app/out/renderer/assets/{styles-b4e223ce-DAe5WQrg.js → styles-b4e223ce-DeeiEsuW.js} +1 -1
- package/app/out/renderer/assets/{styles-ca3715f6-BDSX88bY.js → styles-ca3715f6-CMpiebrG.js} +1 -1
- package/app/out/renderer/assets/{styles-d45a18b0-SE9h7les.js → styles-d45a18b0-CZe9hU7H.js} +4 -4
- package/app/out/renderer/assets/{svgDrawCommon-b86b1483-D1mpNbDQ.js → svgDrawCommon-b86b1483-CmJZfZzJ.js} +1 -1
- package/app/out/renderer/assets/{timeline-definition-faaaa080-7Ha-nm4M.js → timeline-definition-faaaa080-Beo2kiiz.js} +3 -3
- package/app/out/renderer/assets/{xychartDiagram-f5964ef8-DLy7iyZW.js → xychartDiagram-f5964ef8-DYmo7moz.js} +5 -5
- package/app/out/renderer/index.html +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./MilkdownMarkdownEditor-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./MilkdownMarkdownEditor-jaF-aGPn.js","./MilkdownMarkdownEditor-tTNRIB2K.css"])))=>i.map(i=>d[i]);
|
|
2
2
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
3
3
|
function getDefaultExportFromCjs(x) {
|
|
4
4
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
@@ -12702,23 +12702,6 @@ const Database = createLucideIcon("Database", [
|
|
|
12702
12702
|
["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
|
|
12703
12703
|
["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
|
|
12704
12704
|
]);
|
|
12705
|
-
/**
|
|
12706
|
-
* @license lucide-react v0.469.0 - ISC
|
|
12707
|
-
*
|
|
12708
|
-
* This source code is licensed under the ISC license.
|
|
12709
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
12710
|
-
*/
|
|
12711
|
-
const Eraser = createLucideIcon("Eraser", [
|
|
12712
|
-
[
|
|
12713
|
-
"path",
|
|
12714
|
-
{
|
|
12715
|
-
d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21",
|
|
12716
|
-
key: "182aya"
|
|
12717
|
-
}
|
|
12718
|
-
],
|
|
12719
|
-
["path", { d: "M22 21H7", key: "t4ddhn" }],
|
|
12720
|
-
["path", { d: "m5 11 9 9", key: "1mo9qw" }]
|
|
12721
|
-
]);
|
|
12722
12705
|
/**
|
|
12723
12706
|
* @license lucide-react v0.469.0 - ISC
|
|
12724
12707
|
*
|
|
@@ -12915,6 +12898,17 @@ const Globe = createLucideIcon("Globe", [
|
|
|
12915
12898
|
["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
|
|
12916
12899
|
["path", { d: "M2 12h20", key: "9i4pu4" }]
|
|
12917
12900
|
]);
|
|
12901
|
+
/**
|
|
12902
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12903
|
+
*
|
|
12904
|
+
* This source code is licensed under the ISC license.
|
|
12905
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12906
|
+
*/
|
|
12907
|
+
const Info$1 = createLucideIcon("Info", [
|
|
12908
|
+
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
12909
|
+
["path", { d: "M12 16v-4", key: "1dtifu" }],
|
|
12910
|
+
["path", { d: "M12 8h.01", key: "e9boi3" }]
|
|
12911
|
+
]);
|
|
12918
12912
|
/**
|
|
12919
12913
|
* @license lucide-react v0.469.0 - ISC
|
|
12920
12914
|
*
|
|
@@ -12952,6 +12946,28 @@ const Lightbulb = createLucideIcon("Lightbulb", [
|
|
|
12952
12946
|
const LoaderCircle = createLucideIcon("LoaderCircle", [
|
|
12953
12947
|
["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]
|
|
12954
12948
|
]);
|
|
12949
|
+
/**
|
|
12950
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12951
|
+
*
|
|
12952
|
+
* This source code is licensed under the ISC license.
|
|
12953
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12954
|
+
*/
|
|
12955
|
+
const LogIn = createLucideIcon("LogIn", [
|
|
12956
|
+
["path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4", key: "u53s6r" }],
|
|
12957
|
+
["polyline", { points: "10 17 15 12 10 7", key: "1ail0h" }],
|
|
12958
|
+
["line", { x1: "15", x2: "3", y1: "12", y2: "12", key: "v6grx8" }]
|
|
12959
|
+
]);
|
|
12960
|
+
/**
|
|
12961
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12962
|
+
*
|
|
12963
|
+
* This source code is licensed under the ISC license.
|
|
12964
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12965
|
+
*/
|
|
12966
|
+
const LogOut = createLucideIcon("LogOut", [
|
|
12967
|
+
["path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4", key: "1uf3rs" }],
|
|
12968
|
+
["polyline", { points: "16 17 21 12 16 7", key: "1gabdz" }],
|
|
12969
|
+
["line", { x1: "21", x2: "9", y1: "12", y2: "12", key: "1uyos4" }]
|
|
12970
|
+
]);
|
|
12955
12971
|
/**
|
|
12956
12972
|
* @license lucide-react v0.469.0 - ISC
|
|
12957
12973
|
*
|
|
@@ -12961,6 +12977,17 @@ const LoaderCircle = createLucideIcon("LoaderCircle", [
|
|
|
12961
12977
|
const MessageSquare = createLucideIcon("MessageSquare", [
|
|
12962
12978
|
["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z", key: "1lielz" }]
|
|
12963
12979
|
]);
|
|
12980
|
+
/**
|
|
12981
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12982
|
+
*
|
|
12983
|
+
* This source code is licensed under the ISC license.
|
|
12984
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12985
|
+
*/
|
|
12986
|
+
const Monitor = createLucideIcon("Monitor", [
|
|
12987
|
+
["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2", key: "48i651" }],
|
|
12988
|
+
["line", { x1: "8", x2: "16", y1: "21", y2: "21", key: "1svkeh" }],
|
|
12989
|
+
["line", { x1: "12", x2: "12", y1: "17", y2: "21", key: "vw1qmm" }]
|
|
12990
|
+
]);
|
|
12964
12991
|
/**
|
|
12965
12992
|
* @license lucide-react v0.469.0 - ISC
|
|
12966
12993
|
*
|
|
@@ -13254,7 +13281,7 @@ const Zap = createLucideIcon("Zap", [
|
|
|
13254
13281
|
}
|
|
13255
13282
|
]
|
|
13256
13283
|
]);
|
|
13257
|
-
const api$
|
|
13284
|
+
const api$b = window.api;
|
|
13258
13285
|
const KEY_FIELDS = [
|
|
13259
13286
|
{
|
|
13260
13287
|
name: "ANTHROPIC_API_KEY",
|
|
@@ -13295,21 +13322,40 @@ function ApiKeySetup({ onComplete }) {
|
|
|
13295
13322
|
const [visible, setVisible] = reactExports.useState({});
|
|
13296
13323
|
const [saving, setSaving] = reactExports.useState(false);
|
|
13297
13324
|
const [error, setError] = reactExports.useState(null);
|
|
13325
|
+
const [codexStatus, setCodexStatus] = reactExports.useState(null);
|
|
13326
|
+
const [codexLoggingIn, setCodexLoggingIn] = reactExports.useState(false);
|
|
13298
13327
|
reactExports.useEffect(() => {
|
|
13299
|
-
api$
|
|
13328
|
+
api$b.getApiKeyStatus().then((s15) => setStatus(s15));
|
|
13329
|
+
api$b.getOpenAICodexStatus?.().then((s15) => setCodexStatus(s15)).catch(() => {
|
|
13330
|
+
});
|
|
13300
13331
|
}, []);
|
|
13301
|
-
const
|
|
13332
|
+
const handleCodexLogin = async () => {
|
|
13333
|
+
setCodexLoggingIn(true);
|
|
13334
|
+
try {
|
|
13335
|
+
const result = await api$b.openaiCodexLogin?.();
|
|
13336
|
+
if (result?.success) {
|
|
13337
|
+
setCodexStatus({ isLoggedIn: true });
|
|
13338
|
+
} else {
|
|
13339
|
+
setError(result?.error || "ChatGPT sign-in failed");
|
|
13340
|
+
}
|
|
13341
|
+
} catch (err) {
|
|
13342
|
+
setError(err.message || "ChatGPT sign-in failed");
|
|
13343
|
+
} finally {
|
|
13344
|
+
setCodexLoggingIn(false);
|
|
13345
|
+
}
|
|
13346
|
+
};
|
|
13347
|
+
const hasAnyLlmKey = status.ANTHROPIC_API_KEY || status.OPENAI_API_KEY || codexStatus?.isLoggedIn || !!(values.ANTHROPIC_API_KEY || "").trim() || !!(values.OPENAI_API_KEY || "").trim();
|
|
13302
13348
|
const handleSave = async () => {
|
|
13303
13349
|
const entries = Object.entries(values).filter(([, v3]) => v3.trim());
|
|
13304
|
-
if (entries.length === 0 && !status.ANTHROPIC_API_KEY && !status.OPENAI_API_KEY) {
|
|
13305
|
-
setError("Please enter at least one API key
|
|
13350
|
+
if (entries.length === 0 && !status.ANTHROPIC_API_KEY && !status.OPENAI_API_KEY && !codexStatus?.isLoggedIn) {
|
|
13351
|
+
setError("Please enter at least one API key or sign in with ChatGPT to continue.");
|
|
13306
13352
|
return;
|
|
13307
13353
|
}
|
|
13308
13354
|
setSaving(true);
|
|
13309
13355
|
setError(null);
|
|
13310
13356
|
try {
|
|
13311
13357
|
for (const [key, val] of entries) {
|
|
13312
|
-
await api$
|
|
13358
|
+
await api$b.saveApiKey(key, val);
|
|
13313
13359
|
}
|
|
13314
13360
|
onComplete();
|
|
13315
13361
|
} catch (err) {
|
|
@@ -13325,11 +13371,7 @@ function ApiKeySetup({ onComplete }) {
|
|
|
13325
13371
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative mx-auto mb-6 w-fit", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13326
13372
|
"div",
|
|
13327
13373
|
{
|
|
13328
|
-
className: "w-14 h-14 rounded-2xl flex items-center justify-center",
|
|
13329
|
-
style: {
|
|
13330
|
-
background: "linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-2) 100%)",
|
|
13331
|
-
boxShadow: "0 8px 32px var(--color-accent-2-muted)"
|
|
13332
|
-
},
|
|
13374
|
+
className: "w-14 h-14 rounded-2xl flex items-center justify-center t-gradient-accent t-gradient-accent-shadow-lg",
|
|
13333
13375
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Key, { className: "text-white", size: 22 })
|
|
13334
13376
|
}
|
|
13335
13377
|
) }),
|
|
@@ -13380,7 +13422,8 @@ function ApiKeySetup({ onComplete }) {
|
|
|
13380
13422
|
className: "w-full text-xs px-2.5 py-1.5 rounded-md border t-border t-bg-base t-text font-mono pr-8\n focus:outline-none focus:ring-1 focus:ring-[var(--color-accent)]",
|
|
13381
13423
|
placeholder: alreadySet ? "•••••••• (already set — leave blank to keep)" : field.placeholder,
|
|
13382
13424
|
value: values[field.name] || "",
|
|
13383
|
-
onChange: (e) => setValues((prev) => ({ ...prev, [field.name]: e.target.value }))
|
|
13425
|
+
onChange: (e) => setValues((prev) => ({ ...prev, [field.name]: e.target.value })),
|
|
13426
|
+
"aria-label": `${field.label} API key`
|
|
13384
13427
|
}
|
|
13385
13428
|
),
|
|
13386
13429
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -13397,10 +13440,33 @@ function ApiKeySetup({ onComplete }) {
|
|
|
13397
13440
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] t-text-muted mt-1", children: field.hint })
|
|
13398
13441
|
] }, field.name);
|
|
13399
13442
|
}) }),
|
|
13400
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
13401
|
-
|
|
13443
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border t-border t-bg-surface/50 p-3", children: [
|
|
13444
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between mb-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium t-text flex items-center gap-1.5", children: [
|
|
13445
|
+
"ChatGPT Subscription",
|
|
13446
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] t-text-muted", children: "(alternative to OpenAI API key)" }),
|
|
13447
|
+
codexStatus?.isLoggedIn && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-0.5 text-[10px] text-green-500", children: [
|
|
13448
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 10 }),
|
|
13449
|
+
" signed in"
|
|
13450
|
+
] })
|
|
13451
|
+
] }) }),
|
|
13452
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13453
|
+
"button",
|
|
13454
|
+
{
|
|
13455
|
+
onClick: handleCodexLogin,
|
|
13456
|
+
disabled: codexLoggingIn || codexStatus?.isLoggedIn,
|
|
13457
|
+
className: "flex items-center gap-1.5 px-3 py-1.5 rounded-md border t-border text-xs t-text-secondary hover:t-text t-bg-hover disabled:opacity-50",
|
|
13458
|
+
children: [
|
|
13459
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LogIn, { size: 12 }),
|
|
13460
|
+
codexLoggingIn ? "Signing in..." : codexStatus?.isLoggedIn ? "Already signed in" : "Sign in with ChatGPT"
|
|
13461
|
+
]
|
|
13462
|
+
}
|
|
13463
|
+
),
|
|
13464
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] t-text-muted mt-1", children: "Use your ChatGPT Plus/Pro subscription instead of an API key. No per-token billing." })
|
|
13465
|
+
] }),
|
|
13466
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] t-text-muted mb-1", children: "* You need at least one of Anthropic or OpenAI (API key or ChatGPT subscription)." }),
|
|
13467
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-400 mb-3", role: "alert", children: error }),
|
|
13402
13468
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
13403
|
-
(status.ANTHROPIC_API_KEY || status.OPENAI_API_KEY) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13469
|
+
(status.ANTHROPIC_API_KEY || status.OPENAI_API_KEY || codexStatus?.isLoggedIn) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13404
13470
|
"button",
|
|
13405
13471
|
{
|
|
13406
13472
|
onClick: onComplete,
|
|
@@ -13414,11 +13480,7 @@ function ApiKeySetup({ onComplete }) {
|
|
|
13414
13480
|
{
|
|
13415
13481
|
onClick: handleSave,
|
|
13416
13482
|
disabled: saving,
|
|
13417
|
-
className: "px-5 py-2 rounded-lg text-white text-sm font-medium hover:opacity-90 transition-all duration-200 disabled:opacity-50",
|
|
13418
|
-
style: {
|
|
13419
|
-
background: "linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-2) 100%)",
|
|
13420
|
-
boxShadow: "0 4px 16px var(--color-accent-2-muted)"
|
|
13421
|
-
},
|
|
13483
|
+
className: "px-5 py-2 rounded-lg text-white text-sm font-medium hover:opacity-90 transition-all duration-200 disabled:opacity-50 t-gradient-accent t-gradient-accent-shadow",
|
|
13422
13484
|
children: saving ? "Saving..." : hasAnyLlmKey ? "Save & Continue" : "Save & Continue"
|
|
13423
13485
|
}
|
|
13424
13486
|
)
|
|
@@ -13465,11 +13527,44 @@ const createImpl = (createState2) => {
|
|
|
13465
13527
|
return useBoundStore;
|
|
13466
13528
|
};
|
|
13467
13529
|
const create$1 = (createState2) => createState2 ? createImpl(createState2) : createImpl;
|
|
13530
|
+
const REASONING_MODELS = [
|
|
13531
|
+
"openai:gpt-5.4",
|
|
13532
|
+
"openai:gpt-5.4-mini",
|
|
13533
|
+
"openai:gpt-5.4-nano",
|
|
13534
|
+
"openai-codex:gpt-5.4",
|
|
13535
|
+
"openai-codex:gpt-5.4-mini",
|
|
13536
|
+
"openai-codex:gpt-5.4-nano",
|
|
13537
|
+
"anthropic:claude-opus-4-6"
|
|
13538
|
+
];
|
|
13539
|
+
const SUPPORTED_MODELS = [
|
|
13540
|
+
// OpenAI (API key)
|
|
13541
|
+
{ id: "openai:gpt-5.4", label: "GPT-5.4", provider: "OpenAI" },
|
|
13542
|
+
{ id: "openai:gpt-5.4-mini", label: "GPT-5.4 Mini", provider: "OpenAI" },
|
|
13543
|
+
{ id: "openai:gpt-5.4-nano", label: "GPT-5.4 Nano", provider: "OpenAI" },
|
|
13544
|
+
{ id: "openai:gpt-4o", label: "GPT-4o", provider: "OpenAI" },
|
|
13545
|
+
// ChatGPT Subscription (OAuth)
|
|
13546
|
+
{ id: "openai-codex:gpt-5.4", label: "GPT-5.4", provider: "ChatGPT Subscription" },
|
|
13547
|
+
{ id: "openai-codex:gpt-5.4-mini", label: "GPT-5.4 Mini", provider: "ChatGPT Subscription" },
|
|
13548
|
+
{ id: "openai-codex:gpt-5.4-pro", label: "GPT-5.4 Pro", provider: "ChatGPT Subscription" },
|
|
13549
|
+
// Anthropic (API key)
|
|
13550
|
+
{ id: "anthropic:claude-opus-4-6", label: "Claude Opus 4.6", provider: "Anthropic" },
|
|
13551
|
+
{ id: "anthropic:claude-opus-4-5-20251101", label: "Claude Opus 4.5", provider: "Anthropic" },
|
|
13552
|
+
{ id: "anthropic:claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5", provider: "Anthropic" },
|
|
13553
|
+
{ id: "anthropic:claude-haiku-4-5-20251001", label: "Claude Haiku 4.5", provider: "Anthropic" }
|
|
13554
|
+
];
|
|
13555
|
+
const DEFAULT_MODEL = "openai:gpt-5.4";
|
|
13556
|
+
function parseModelKey(key) {
|
|
13557
|
+
const i = key.indexOf(":");
|
|
13558
|
+
if (i > 0) return { provider: key.slice(0, i), modelId: key.slice(i + 1) };
|
|
13559
|
+
if (key.startsWith("claude-")) return { provider: "anthropic", modelId: key };
|
|
13560
|
+
if (key.startsWith("gemini-")) return { provider: "google", modelId: key };
|
|
13561
|
+
return { provider: "openai", modelId: key };
|
|
13562
|
+
}
|
|
13468
13563
|
const useUIStore = create$1((set) => ({
|
|
13469
13564
|
theme: "light",
|
|
13470
13565
|
leftTab: "files",
|
|
13471
13566
|
centerView: "chat",
|
|
13472
|
-
selectedModel:
|
|
13567
|
+
selectedModel: DEFAULT_MODEL,
|
|
13473
13568
|
isIdle: true,
|
|
13474
13569
|
rightSidebarCollapsed: false,
|
|
13475
13570
|
leftSidebarCollapsed: false,
|
|
@@ -13575,16 +13670,321 @@ async function hydratePreferences() {
|
|
|
13575
13670
|
const prefs = await api2?.loadPreferences?.();
|
|
13576
13671
|
if (!prefs) return;
|
|
13577
13672
|
const updates = {};
|
|
13578
|
-
if (prefs.selectedModel)
|
|
13673
|
+
if (prefs.selectedModel) {
|
|
13674
|
+
const m = prefs.selectedModel;
|
|
13675
|
+
if (!m.includes(":")) {
|
|
13676
|
+
const { provider, modelId } = parseModelKey(m);
|
|
13677
|
+
updates.selectedModel = `${provider}:${modelId}`;
|
|
13678
|
+
} else {
|
|
13679
|
+
updates.selectedModel = m;
|
|
13680
|
+
}
|
|
13681
|
+
}
|
|
13579
13682
|
if (prefs.reasoningEffort) updates.reasoningEffort = prefs.reasoningEffort;
|
|
13580
13683
|
if (prefs.theme) updates.theme = prefs.theme;
|
|
13581
13684
|
if (Object.keys(updates).length > 0) useUIStore.setState(updates);
|
|
13582
13685
|
}
|
|
13583
13686
|
const uiStore = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
13584
13687
|
__proto__: null,
|
|
13688
|
+
REASONING_MODELS,
|
|
13689
|
+
SUPPORTED_MODELS,
|
|
13585
13690
|
hydratePreferences,
|
|
13586
13691
|
useUIStore
|
|
13587
13692
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
13693
|
+
const scriptRel = function detectScriptRel() {
|
|
13694
|
+
const relList = typeof document !== "undefined" && document.createElement("link").relList;
|
|
13695
|
+
return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload";
|
|
13696
|
+
}();
|
|
13697
|
+
const assetsURL = function(dep, importerUrl) {
|
|
13698
|
+
return new URL(dep, importerUrl).href;
|
|
13699
|
+
};
|
|
13700
|
+
const seen = {};
|
|
13701
|
+
const __vitePreload = function preload2(baseModule, deps, importerUrl) {
|
|
13702
|
+
let promise = Promise.resolve();
|
|
13703
|
+
if (deps && deps.length > 0) {
|
|
13704
|
+
const links = document.getElementsByTagName("link");
|
|
13705
|
+
const cspNonceMeta = document.querySelector(
|
|
13706
|
+
"meta[property=csp-nonce]"
|
|
13707
|
+
);
|
|
13708
|
+
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
13709
|
+
promise = Promise.allSettled(
|
|
13710
|
+
deps.map((dep) => {
|
|
13711
|
+
dep = assetsURL(dep, importerUrl);
|
|
13712
|
+
if (dep in seen) return;
|
|
13713
|
+
seen[dep] = true;
|
|
13714
|
+
const isCss = dep.endsWith(".css");
|
|
13715
|
+
const cssSelector = isCss ? '[rel="stylesheet"]' : "";
|
|
13716
|
+
const isBaseRelative = !!importerUrl;
|
|
13717
|
+
if (isBaseRelative) {
|
|
13718
|
+
for (let i = links.length - 1; i >= 0; i--) {
|
|
13719
|
+
const link22 = links[i];
|
|
13720
|
+
if (link22.href === dep && (!isCss || link22.rel === "stylesheet")) {
|
|
13721
|
+
return;
|
|
13722
|
+
}
|
|
13723
|
+
}
|
|
13724
|
+
} else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
|
|
13725
|
+
return;
|
|
13726
|
+
}
|
|
13727
|
+
const link2 = document.createElement("link");
|
|
13728
|
+
link2.rel = isCss ? "stylesheet" : scriptRel;
|
|
13729
|
+
if (!isCss) {
|
|
13730
|
+
link2.as = "script";
|
|
13731
|
+
}
|
|
13732
|
+
link2.crossOrigin = "";
|
|
13733
|
+
link2.href = dep;
|
|
13734
|
+
if (cspNonce) {
|
|
13735
|
+
link2.setAttribute("nonce", cspNonce);
|
|
13736
|
+
}
|
|
13737
|
+
document.head.appendChild(link2);
|
|
13738
|
+
if (isCss) {
|
|
13739
|
+
return new Promise((res, rej) => {
|
|
13740
|
+
link2.addEventListener("load", res);
|
|
13741
|
+
link2.addEventListener(
|
|
13742
|
+
"error",
|
|
13743
|
+
() => rej(new Error(`Unable to preload CSS for ${dep}`))
|
|
13744
|
+
);
|
|
13745
|
+
});
|
|
13746
|
+
}
|
|
13747
|
+
})
|
|
13748
|
+
);
|
|
13749
|
+
}
|
|
13750
|
+
function handlePreloadError(err) {
|
|
13751
|
+
const e = new Event("vite:preloadError", {
|
|
13752
|
+
cancelable: true
|
|
13753
|
+
});
|
|
13754
|
+
e.payload = err;
|
|
13755
|
+
window.dispatchEvent(e);
|
|
13756
|
+
if (!e.defaultPrevented) {
|
|
13757
|
+
throw err;
|
|
13758
|
+
}
|
|
13759
|
+
}
|
|
13760
|
+
return promise.then((res) => {
|
|
13761
|
+
for (const item of res || []) {
|
|
13762
|
+
if (item.status !== "rejected") continue;
|
|
13763
|
+
handlePreloadError(item.reason);
|
|
13764
|
+
}
|
|
13765
|
+
return baseModule().catch(handlePreloadError);
|
|
13766
|
+
});
|
|
13767
|
+
};
|
|
13768
|
+
function extractProgress(tool, data) {
|
|
13769
|
+
if (!data?.partialResult) return void 0;
|
|
13770
|
+
const text2 = data.partialResult?.content?.[0]?.text;
|
|
13771
|
+
if (typeof text2 === "string" && text2.length > 0) {
|
|
13772
|
+
const lines = text2.split("\n").filter(Boolean);
|
|
13773
|
+
const maxLines = tool === "bash" ? 5 : 3;
|
|
13774
|
+
return lines.slice(-maxLines).join("\n");
|
|
13775
|
+
}
|
|
13776
|
+
return void 0;
|
|
13777
|
+
}
|
|
13778
|
+
const useToolEventsStore = create$1((set, get) => ({
|
|
13779
|
+
currentRunEvents: [],
|
|
13780
|
+
onToolCall: (event) => {
|
|
13781
|
+
const toolCallId = event.toolCallId || `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
13782
|
+
const newEvent = {
|
|
13783
|
+
id: toolCallId,
|
|
13784
|
+
toolCallId,
|
|
13785
|
+
tool: event.tool,
|
|
13786
|
+
status: "running",
|
|
13787
|
+
summary: event.summary,
|
|
13788
|
+
detail: event.detail,
|
|
13789
|
+
startedAt: Date.now()
|
|
13790
|
+
};
|
|
13791
|
+
set((state) => ({
|
|
13792
|
+
currentRunEvents: [...state.currentRunEvents, newEvent]
|
|
13793
|
+
}));
|
|
13794
|
+
},
|
|
13795
|
+
onToolResult: (event) => {
|
|
13796
|
+
set((state) => {
|
|
13797
|
+
const events = [...state.currentRunEvents];
|
|
13798
|
+
const idx = event.toolCallId ? events.findLastIndex((e) => e.toolCallId === event.toolCallId && e.status === "running") : events.findLastIndex((e) => e.tool === event.tool && e.status === "running");
|
|
13799
|
+
if (idx !== -1) {
|
|
13800
|
+
events[idx] = {
|
|
13801
|
+
...events[idx],
|
|
13802
|
+
status: event.success !== false ? "success" : "error",
|
|
13803
|
+
resultSummary: event.summary,
|
|
13804
|
+
resultDetail: event.resultDetail,
|
|
13805
|
+
durationMs: event.durationMs,
|
|
13806
|
+
completedAt: Date.now()
|
|
13807
|
+
};
|
|
13808
|
+
}
|
|
13809
|
+
return { currentRunEvents: events };
|
|
13810
|
+
});
|
|
13811
|
+
},
|
|
13812
|
+
onToolProgress: (event) => {
|
|
13813
|
+
if (event.phase === "end") return;
|
|
13814
|
+
set((state) => {
|
|
13815
|
+
const events = [...state.currentRunEvents];
|
|
13816
|
+
const idx = events.findLastIndex((e) => e.toolCallId === event.toolCallId);
|
|
13817
|
+
if (idx !== -1) {
|
|
13818
|
+
const progress = extractProgress(event.tool, event.data) ?? events[idx].progress;
|
|
13819
|
+
events[idx] = { ...events[idx], progress };
|
|
13820
|
+
}
|
|
13821
|
+
return { currentRunEvents: events };
|
|
13822
|
+
});
|
|
13823
|
+
},
|
|
13824
|
+
snapshot: () => [...get().currentRunEvents],
|
|
13825
|
+
clearRun: () => set({ currentRunEvents: [] })
|
|
13826
|
+
}));
|
|
13827
|
+
const PAGE_SIZE = 20;
|
|
13828
|
+
const api$a = window.api;
|
|
13829
|
+
let _sessionId = "";
|
|
13830
|
+
const useChatStore = create$1((set, get) => ({
|
|
13831
|
+
messages: [],
|
|
13832
|
+
streamingText: "",
|
|
13833
|
+
isStreaming: false,
|
|
13834
|
+
savedMessageIds: /* @__PURE__ */ new Set(),
|
|
13835
|
+
turnToolEvents: /* @__PURE__ */ new Map(),
|
|
13836
|
+
draftText: "",
|
|
13837
|
+
setDraftText: (text2) => set({ draftText: text2 }),
|
|
13838
|
+
hasMore: false,
|
|
13839
|
+
isLoadingHistory: false,
|
|
13840
|
+
_offset: 0,
|
|
13841
|
+
scrollToMessageId: null,
|
|
13842
|
+
send: async (text2, images) => {
|
|
13843
|
+
const userMsg = {
|
|
13844
|
+
id: crypto.randomUUID(),
|
|
13845
|
+
role: "user",
|
|
13846
|
+
content: text2,
|
|
13847
|
+
images: images?.map((i) => `data:${i.mimeType};base64,${i.base64}`),
|
|
13848
|
+
timestamp: Date.now()
|
|
13849
|
+
};
|
|
13850
|
+
set((s15) => ({
|
|
13851
|
+
messages: [...s15.messages, userMsg],
|
|
13852
|
+
streamingText: "",
|
|
13853
|
+
isStreaming: true
|
|
13854
|
+
}));
|
|
13855
|
+
if (_sessionId) {
|
|
13856
|
+
api$a.saveMessage(_sessionId, userMsg).catch(() => {
|
|
13857
|
+
});
|
|
13858
|
+
}
|
|
13859
|
+
const { useUsageStore: useUsageStore2 } = await __vitePreload(async () => {
|
|
13860
|
+
const { useUsageStore: useUsageStore3 } = await Promise.resolve().then(() => usageStore);
|
|
13861
|
+
return { useUsageStore: useUsageStore3 };
|
|
13862
|
+
}, true ? void 0 : void 0, import.meta.url);
|
|
13863
|
+
useUsageStore2.getState().resetRun();
|
|
13864
|
+
try {
|
|
13865
|
+
const { useUIStore: useUIStore2 } = await __vitePreload(async () => {
|
|
13866
|
+
const { useUIStore: useUIStore3 } = await Promise.resolve().then(() => uiStore);
|
|
13867
|
+
return { useUIStore: useUIStore3 };
|
|
13868
|
+
}, true ? void 0 : void 0, import.meta.url);
|
|
13869
|
+
const model = useUIStore2.getState().selectedModel;
|
|
13870
|
+
await api$a.sendMessage(text2, void 0, model, images);
|
|
13871
|
+
} catch {
|
|
13872
|
+
}
|
|
13873
|
+
},
|
|
13874
|
+
stop: async () => {
|
|
13875
|
+
await api$a.stopAgent();
|
|
13876
|
+
},
|
|
13877
|
+
appendChunk: (chunk) => {
|
|
13878
|
+
set((s15) => ({ streamingText: s15.streamingText + chunk }));
|
|
13879
|
+
},
|
|
13880
|
+
finalize: (result) => {
|
|
13881
|
+
const content2 = result.response || result.error || "No response";
|
|
13882
|
+
const assistantMsg = {
|
|
13883
|
+
id: crypto.randomUUID(),
|
|
13884
|
+
role: "assistant",
|
|
13885
|
+
content: content2,
|
|
13886
|
+
images: result.images?.map((i) => `data:${i.mimeType};base64,${i.base64}`),
|
|
13887
|
+
timestamp: Date.now()
|
|
13888
|
+
};
|
|
13889
|
+
const toolEventsSnapshot = useToolEventsStore.getState().snapshot();
|
|
13890
|
+
useToolEventsStore.getState().clearRun();
|
|
13891
|
+
set((s15) => {
|
|
13892
|
+
const nextToolEvents = new Map(s15.turnToolEvents);
|
|
13893
|
+
if (toolEventsSnapshot.length > 0) {
|
|
13894
|
+
nextToolEvents.set(assistantMsg.id, toolEventsSnapshot);
|
|
13895
|
+
}
|
|
13896
|
+
return {
|
|
13897
|
+
messages: [...s15.messages, assistantMsg],
|
|
13898
|
+
streamingText: "",
|
|
13899
|
+
isStreaming: false,
|
|
13900
|
+
turnToolEvents: nextToolEvents
|
|
13901
|
+
};
|
|
13902
|
+
});
|
|
13903
|
+
if (_sessionId) {
|
|
13904
|
+
api$a.saveMessage(_sessionId, assistantMsg).catch(() => {
|
|
13905
|
+
});
|
|
13906
|
+
}
|
|
13907
|
+
},
|
|
13908
|
+
clear: () => {
|
|
13909
|
+
_sessionId = "";
|
|
13910
|
+
return set({
|
|
13911
|
+
messages: [],
|
|
13912
|
+
streamingText: "",
|
|
13913
|
+
isStreaming: false,
|
|
13914
|
+
savedMessageIds: /* @__PURE__ */ new Set(),
|
|
13915
|
+
turnToolEvents: /* @__PURE__ */ new Map(),
|
|
13916
|
+
draftText: "",
|
|
13917
|
+
hasMore: false,
|
|
13918
|
+
isLoadingHistory: false,
|
|
13919
|
+
_offset: 0,
|
|
13920
|
+
scrollToMessageId: null
|
|
13921
|
+
});
|
|
13922
|
+
},
|
|
13923
|
+
markSaved: (messageId) => {
|
|
13924
|
+
set((s15) => {
|
|
13925
|
+
const next = new Set(s15.savedMessageIds);
|
|
13926
|
+
next.add(messageId);
|
|
13927
|
+
return { savedMessageIds: next };
|
|
13928
|
+
});
|
|
13929
|
+
if (_sessionId) {
|
|
13930
|
+
api$a.markMessageSaved(_sessionId, messageId).catch(() => {
|
|
13931
|
+
});
|
|
13932
|
+
}
|
|
13933
|
+
},
|
|
13934
|
+
insertContextReset: () => {
|
|
13935
|
+
const divider = {
|
|
13936
|
+
id: `ctx-reset-${Date.now()}`,
|
|
13937
|
+
role: "system",
|
|
13938
|
+
content: "AI context has been reset — chat history is preserved.",
|
|
13939
|
+
timestamp: Date.now()
|
|
13940
|
+
};
|
|
13941
|
+
set((s15) => ({ messages: [...s15.messages, divider] }));
|
|
13942
|
+
},
|
|
13943
|
+
loadInitial: async (sessionId) => {
|
|
13944
|
+
_sessionId = sessionId;
|
|
13945
|
+
try {
|
|
13946
|
+
const [count, messages, savedIds] = await Promise.all([
|
|
13947
|
+
api$a.getMessageCount(sessionId),
|
|
13948
|
+
api$a.loadMessages(sessionId, 0, PAGE_SIZE),
|
|
13949
|
+
api$a.loadSavedMessageIds(sessionId)
|
|
13950
|
+
]);
|
|
13951
|
+
set({
|
|
13952
|
+
messages,
|
|
13953
|
+
hasMore: count > PAGE_SIZE,
|
|
13954
|
+
_offset: PAGE_SIZE,
|
|
13955
|
+
savedMessageIds: new Set(savedIds || [])
|
|
13956
|
+
});
|
|
13957
|
+
} catch {
|
|
13958
|
+
}
|
|
13959
|
+
},
|
|
13960
|
+
loadHistory: async () => {
|
|
13961
|
+
const { hasMore, isLoadingHistory, _offset } = get();
|
|
13962
|
+
if (!hasMore || isLoadingHistory || !_sessionId) return;
|
|
13963
|
+
set({ isLoadingHistory: true });
|
|
13964
|
+
try {
|
|
13965
|
+
const [count, older] = await Promise.all([
|
|
13966
|
+
api$a.getMessageCount(_sessionId),
|
|
13967
|
+
api$a.loadMessages(_sessionId, _offset, PAGE_SIZE)
|
|
13968
|
+
]);
|
|
13969
|
+
if (older.length > 0) {
|
|
13970
|
+
set((s15) => ({
|
|
13971
|
+
messages: [...older, ...s15.messages],
|
|
13972
|
+
_offset: s15._offset + older.length,
|
|
13973
|
+
hasMore: s15._offset + older.length < count,
|
|
13974
|
+
isLoadingHistory: false
|
|
13975
|
+
}));
|
|
13976
|
+
} else {
|
|
13977
|
+
set({ hasMore: false, isLoadingHistory: false });
|
|
13978
|
+
}
|
|
13979
|
+
} catch {
|
|
13980
|
+
set({ isLoadingHistory: false });
|
|
13981
|
+
}
|
|
13982
|
+
},
|
|
13983
|
+
requestScrollTo: (messageId) => {
|
|
13984
|
+
set({ scrollToMessageId: messageId });
|
|
13985
|
+
setTimeout(() => set({ scrollToMessageId: null }), 100);
|
|
13986
|
+
}
|
|
13987
|
+
}));
|
|
13588
13988
|
function ok$1() {
|
|
13589
13989
|
}
|
|
13590
13990
|
function unreachable() {
|
|
@@ -26187,292 +26587,6 @@ const useEntityStore = create$1((set, get) => ({
|
|
|
26187
26587
|
await get().refreshAll();
|
|
26188
26588
|
}
|
|
26189
26589
|
}));
|
|
26190
|
-
const scriptRel = function detectScriptRel() {
|
|
26191
|
-
const relList = typeof document !== "undefined" && document.createElement("link").relList;
|
|
26192
|
-
return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload";
|
|
26193
|
-
}();
|
|
26194
|
-
const assetsURL = function(dep, importerUrl) {
|
|
26195
|
-
return new URL(dep, importerUrl).href;
|
|
26196
|
-
};
|
|
26197
|
-
const seen = {};
|
|
26198
|
-
const __vitePreload = function preload2(baseModule, deps, importerUrl) {
|
|
26199
|
-
let promise = Promise.resolve();
|
|
26200
|
-
if (deps && deps.length > 0) {
|
|
26201
|
-
const links = document.getElementsByTagName("link");
|
|
26202
|
-
const cspNonceMeta = document.querySelector(
|
|
26203
|
-
"meta[property=csp-nonce]"
|
|
26204
|
-
);
|
|
26205
|
-
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
26206
|
-
promise = Promise.allSettled(
|
|
26207
|
-
deps.map((dep) => {
|
|
26208
|
-
dep = assetsURL(dep, importerUrl);
|
|
26209
|
-
if (dep in seen) return;
|
|
26210
|
-
seen[dep] = true;
|
|
26211
|
-
const isCss = dep.endsWith(".css");
|
|
26212
|
-
const cssSelector = isCss ? '[rel="stylesheet"]' : "";
|
|
26213
|
-
const isBaseRelative = !!importerUrl;
|
|
26214
|
-
if (isBaseRelative) {
|
|
26215
|
-
for (let i = links.length - 1; i >= 0; i--) {
|
|
26216
|
-
const link22 = links[i];
|
|
26217
|
-
if (link22.href === dep && (!isCss || link22.rel === "stylesheet")) {
|
|
26218
|
-
return;
|
|
26219
|
-
}
|
|
26220
|
-
}
|
|
26221
|
-
} else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
|
|
26222
|
-
return;
|
|
26223
|
-
}
|
|
26224
|
-
const link2 = document.createElement("link");
|
|
26225
|
-
link2.rel = isCss ? "stylesheet" : scriptRel;
|
|
26226
|
-
if (!isCss) {
|
|
26227
|
-
link2.as = "script";
|
|
26228
|
-
}
|
|
26229
|
-
link2.crossOrigin = "";
|
|
26230
|
-
link2.href = dep;
|
|
26231
|
-
if (cspNonce) {
|
|
26232
|
-
link2.setAttribute("nonce", cspNonce);
|
|
26233
|
-
}
|
|
26234
|
-
document.head.appendChild(link2);
|
|
26235
|
-
if (isCss) {
|
|
26236
|
-
return new Promise((res, rej) => {
|
|
26237
|
-
link2.addEventListener("load", res);
|
|
26238
|
-
link2.addEventListener(
|
|
26239
|
-
"error",
|
|
26240
|
-
() => rej(new Error(`Unable to preload CSS for ${dep}`))
|
|
26241
|
-
);
|
|
26242
|
-
});
|
|
26243
|
-
}
|
|
26244
|
-
})
|
|
26245
|
-
);
|
|
26246
|
-
}
|
|
26247
|
-
function handlePreloadError(err) {
|
|
26248
|
-
const e = new Event("vite:preloadError", {
|
|
26249
|
-
cancelable: true
|
|
26250
|
-
});
|
|
26251
|
-
e.payload = err;
|
|
26252
|
-
window.dispatchEvent(e);
|
|
26253
|
-
if (!e.defaultPrevented) {
|
|
26254
|
-
throw err;
|
|
26255
|
-
}
|
|
26256
|
-
}
|
|
26257
|
-
return promise.then((res) => {
|
|
26258
|
-
for (const item of res || []) {
|
|
26259
|
-
if (item.status !== "rejected") continue;
|
|
26260
|
-
handlePreloadError(item.reason);
|
|
26261
|
-
}
|
|
26262
|
-
return baseModule().catch(handlePreloadError);
|
|
26263
|
-
});
|
|
26264
|
-
};
|
|
26265
|
-
function extractProgress(tool, data) {
|
|
26266
|
-
if (!data?.partialResult) return void 0;
|
|
26267
|
-
const text2 = data.partialResult?.content?.[0]?.text;
|
|
26268
|
-
if (typeof text2 === "string" && text2.length > 0) {
|
|
26269
|
-
const lines = text2.split("\n").filter(Boolean);
|
|
26270
|
-
const maxLines = tool === "bash" ? 5 : 3;
|
|
26271
|
-
return lines.slice(-maxLines).join("\n");
|
|
26272
|
-
}
|
|
26273
|
-
return void 0;
|
|
26274
|
-
}
|
|
26275
|
-
const useToolEventsStore = create$1((set, get) => ({
|
|
26276
|
-
currentRunEvents: [],
|
|
26277
|
-
onToolCall: (event) => {
|
|
26278
|
-
const toolCallId = event.toolCallId || `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
26279
|
-
const newEvent = {
|
|
26280
|
-
id: toolCallId,
|
|
26281
|
-
toolCallId,
|
|
26282
|
-
tool: event.tool,
|
|
26283
|
-
status: "running",
|
|
26284
|
-
summary: event.summary,
|
|
26285
|
-
detail: event.detail,
|
|
26286
|
-
startedAt: Date.now()
|
|
26287
|
-
};
|
|
26288
|
-
set((state) => ({
|
|
26289
|
-
currentRunEvents: [...state.currentRunEvents, newEvent]
|
|
26290
|
-
}));
|
|
26291
|
-
},
|
|
26292
|
-
onToolResult: (event) => {
|
|
26293
|
-
set((state) => {
|
|
26294
|
-
const events = [...state.currentRunEvents];
|
|
26295
|
-
const idx = event.toolCallId ? events.findLastIndex((e) => e.toolCallId === event.toolCallId && e.status === "running") : events.findLastIndex((e) => e.tool === event.tool && e.status === "running");
|
|
26296
|
-
if (idx !== -1) {
|
|
26297
|
-
events[idx] = {
|
|
26298
|
-
...events[idx],
|
|
26299
|
-
status: event.success !== false ? "success" : "error",
|
|
26300
|
-
resultSummary: event.summary,
|
|
26301
|
-
resultDetail: event.resultDetail,
|
|
26302
|
-
durationMs: event.durationMs,
|
|
26303
|
-
completedAt: Date.now()
|
|
26304
|
-
};
|
|
26305
|
-
}
|
|
26306
|
-
return { currentRunEvents: events };
|
|
26307
|
-
});
|
|
26308
|
-
},
|
|
26309
|
-
onToolProgress: (event) => {
|
|
26310
|
-
if (event.phase === "end") return;
|
|
26311
|
-
set((state) => {
|
|
26312
|
-
const events = [...state.currentRunEvents];
|
|
26313
|
-
const idx = events.findLastIndex((e) => e.toolCallId === event.toolCallId);
|
|
26314
|
-
if (idx !== -1) {
|
|
26315
|
-
const progress = extractProgress(event.tool, event.data) ?? events[idx].progress;
|
|
26316
|
-
events[idx] = { ...events[idx], progress };
|
|
26317
|
-
}
|
|
26318
|
-
return { currentRunEvents: events };
|
|
26319
|
-
});
|
|
26320
|
-
},
|
|
26321
|
-
snapshot: () => [...get().currentRunEvents],
|
|
26322
|
-
clearRun: () => set({ currentRunEvents: [] })
|
|
26323
|
-
}));
|
|
26324
|
-
const PAGE_SIZE = 20;
|
|
26325
|
-
const api$8 = window.api;
|
|
26326
|
-
let _sessionId = "";
|
|
26327
|
-
const useChatStore = create$1((set, get) => ({
|
|
26328
|
-
messages: [],
|
|
26329
|
-
streamingText: "",
|
|
26330
|
-
isStreaming: false,
|
|
26331
|
-
savedMessageIds: /* @__PURE__ */ new Set(),
|
|
26332
|
-
turnToolEvents: /* @__PURE__ */ new Map(),
|
|
26333
|
-
draftText: "",
|
|
26334
|
-
setDraftText: (text2) => set({ draftText: text2 }),
|
|
26335
|
-
hasMore: false,
|
|
26336
|
-
isLoadingHistory: false,
|
|
26337
|
-
_offset: 0,
|
|
26338
|
-
scrollToMessageId: null,
|
|
26339
|
-
send: async (text2, images) => {
|
|
26340
|
-
const userMsg = {
|
|
26341
|
-
id: crypto.randomUUID(),
|
|
26342
|
-
role: "user",
|
|
26343
|
-
content: text2,
|
|
26344
|
-
images: images?.map((i) => `data:${i.mimeType};base64,${i.base64}`),
|
|
26345
|
-
timestamp: Date.now()
|
|
26346
|
-
};
|
|
26347
|
-
set((s15) => ({
|
|
26348
|
-
messages: [...s15.messages, userMsg],
|
|
26349
|
-
streamingText: "",
|
|
26350
|
-
isStreaming: true
|
|
26351
|
-
}));
|
|
26352
|
-
if (_sessionId) {
|
|
26353
|
-
api$8.saveMessage(_sessionId, userMsg).catch(() => {
|
|
26354
|
-
});
|
|
26355
|
-
}
|
|
26356
|
-
const { useUsageStore: useUsageStore2 } = await __vitePreload(async () => {
|
|
26357
|
-
const { useUsageStore: useUsageStore3 } = await Promise.resolve().then(() => usageStore);
|
|
26358
|
-
return { useUsageStore: useUsageStore3 };
|
|
26359
|
-
}, true ? void 0 : void 0, import.meta.url);
|
|
26360
|
-
useUsageStore2.getState().resetRun();
|
|
26361
|
-
try {
|
|
26362
|
-
const { useUIStore: useUIStore2 } = await __vitePreload(async () => {
|
|
26363
|
-
const { useUIStore: useUIStore3 } = await Promise.resolve().then(() => uiStore);
|
|
26364
|
-
return { useUIStore: useUIStore3 };
|
|
26365
|
-
}, true ? void 0 : void 0, import.meta.url);
|
|
26366
|
-
const model = useUIStore2.getState().selectedModel;
|
|
26367
|
-
await api$8.sendMessage(text2, void 0, model, images);
|
|
26368
|
-
} catch {
|
|
26369
|
-
}
|
|
26370
|
-
},
|
|
26371
|
-
stop: async () => {
|
|
26372
|
-
await api$8.stopAgent();
|
|
26373
|
-
},
|
|
26374
|
-
appendChunk: (chunk) => {
|
|
26375
|
-
set((s15) => ({ streamingText: s15.streamingText + chunk }));
|
|
26376
|
-
},
|
|
26377
|
-
finalize: (result) => {
|
|
26378
|
-
const content2 = result.response || result.error || "No response";
|
|
26379
|
-
const assistantMsg = {
|
|
26380
|
-
id: crypto.randomUUID(),
|
|
26381
|
-
role: "assistant",
|
|
26382
|
-
content: content2,
|
|
26383
|
-
images: result.images?.map((i) => `data:${i.mimeType};base64,${i.base64}`),
|
|
26384
|
-
timestamp: Date.now()
|
|
26385
|
-
};
|
|
26386
|
-
const toolEventsSnapshot = useToolEventsStore.getState().snapshot();
|
|
26387
|
-
useToolEventsStore.getState().clearRun();
|
|
26388
|
-
set((s15) => {
|
|
26389
|
-
const nextToolEvents = new Map(s15.turnToolEvents);
|
|
26390
|
-
if (toolEventsSnapshot.length > 0) {
|
|
26391
|
-
nextToolEvents.set(assistantMsg.id, toolEventsSnapshot);
|
|
26392
|
-
}
|
|
26393
|
-
return {
|
|
26394
|
-
messages: [...s15.messages, assistantMsg],
|
|
26395
|
-
streamingText: "",
|
|
26396
|
-
isStreaming: false,
|
|
26397
|
-
turnToolEvents: nextToolEvents
|
|
26398
|
-
};
|
|
26399
|
-
});
|
|
26400
|
-
if (_sessionId) {
|
|
26401
|
-
api$8.saveMessage(_sessionId, assistantMsg).catch(() => {
|
|
26402
|
-
});
|
|
26403
|
-
}
|
|
26404
|
-
},
|
|
26405
|
-
clear: () => {
|
|
26406
|
-
_sessionId = "";
|
|
26407
|
-
return set({
|
|
26408
|
-
messages: [],
|
|
26409
|
-
streamingText: "",
|
|
26410
|
-
isStreaming: false,
|
|
26411
|
-
savedMessageIds: /* @__PURE__ */ new Set(),
|
|
26412
|
-
turnToolEvents: /* @__PURE__ */ new Map(),
|
|
26413
|
-
draftText: "",
|
|
26414
|
-
hasMore: false,
|
|
26415
|
-
isLoadingHistory: false,
|
|
26416
|
-
_offset: 0,
|
|
26417
|
-
scrollToMessageId: null
|
|
26418
|
-
});
|
|
26419
|
-
},
|
|
26420
|
-
markSaved: (messageId) => {
|
|
26421
|
-
set((s15) => {
|
|
26422
|
-
const next = new Set(s15.savedMessageIds);
|
|
26423
|
-
next.add(messageId);
|
|
26424
|
-
return { savedMessageIds: next };
|
|
26425
|
-
});
|
|
26426
|
-
if (_sessionId) {
|
|
26427
|
-
api$8.markMessageSaved(_sessionId, messageId).catch(() => {
|
|
26428
|
-
});
|
|
26429
|
-
}
|
|
26430
|
-
},
|
|
26431
|
-
loadInitial: async (sessionId) => {
|
|
26432
|
-
_sessionId = sessionId;
|
|
26433
|
-
try {
|
|
26434
|
-
const [count, messages, savedIds] = await Promise.all([
|
|
26435
|
-
api$8.getMessageCount(sessionId),
|
|
26436
|
-
api$8.loadMessages(sessionId, 0, PAGE_SIZE),
|
|
26437
|
-
api$8.loadSavedMessageIds(sessionId)
|
|
26438
|
-
]);
|
|
26439
|
-
set({
|
|
26440
|
-
messages,
|
|
26441
|
-
hasMore: count > PAGE_SIZE,
|
|
26442
|
-
_offset: PAGE_SIZE,
|
|
26443
|
-
savedMessageIds: new Set(savedIds || [])
|
|
26444
|
-
});
|
|
26445
|
-
} catch {
|
|
26446
|
-
}
|
|
26447
|
-
},
|
|
26448
|
-
loadHistory: async () => {
|
|
26449
|
-
const { hasMore, isLoadingHistory, _offset } = get();
|
|
26450
|
-
if (!hasMore || isLoadingHistory || !_sessionId) return;
|
|
26451
|
-
set({ isLoadingHistory: true });
|
|
26452
|
-
try {
|
|
26453
|
-
const [count, older] = await Promise.all([
|
|
26454
|
-
api$8.getMessageCount(_sessionId),
|
|
26455
|
-
api$8.loadMessages(_sessionId, _offset, PAGE_SIZE)
|
|
26456
|
-
]);
|
|
26457
|
-
if (older.length > 0) {
|
|
26458
|
-
set((s15) => ({
|
|
26459
|
-
messages: [...older, ...s15.messages],
|
|
26460
|
-
_offset: s15._offset + older.length,
|
|
26461
|
-
hasMore: s15._offset + older.length < count,
|
|
26462
|
-
isLoadingHistory: false
|
|
26463
|
-
}));
|
|
26464
|
-
} else {
|
|
26465
|
-
set({ hasMore: false, isLoadingHistory: false });
|
|
26466
|
-
}
|
|
26467
|
-
} catch {
|
|
26468
|
-
set({ isLoadingHistory: false });
|
|
26469
|
-
}
|
|
26470
|
-
},
|
|
26471
|
-
requestScrollTo: (messageId) => {
|
|
26472
|
-
set({ scrollToMessageId: messageId });
|
|
26473
|
-
setTimeout(() => set({ scrollToMessageId: null }), 100);
|
|
26474
|
-
}
|
|
26475
|
-
}));
|
|
26476
26590
|
const useProgressStore = create$1((set) => ({
|
|
26477
26591
|
items: [],
|
|
26478
26592
|
upsertItem: (item) => set((state) => {
|
|
@@ -26525,10 +26639,10 @@ function findLastIndex(arr, pred) {
|
|
|
26525
26639
|
}
|
|
26526
26640
|
return -1;
|
|
26527
26641
|
}
|
|
26528
|
-
const api$
|
|
26642
|
+
const api$8 = window.api;
|
|
26529
26643
|
async function loadFromFramework() {
|
|
26530
26644
|
try {
|
|
26531
|
-
const data = await api$
|
|
26645
|
+
const data = await api$8?.getUsageTotals?.();
|
|
26532
26646
|
return data ?? null;
|
|
26533
26647
|
} catch (e) {
|
|
26534
26648
|
console.warn("[usage-store] Failed to load persisted totals:", e);
|
|
@@ -26644,7 +26758,7 @@ const useUsageStore = create$1((set, get) => {
|
|
|
26644
26758
|
},
|
|
26645
26759
|
// Reset all-time totals (user-initiated)
|
|
26646
26760
|
resetAllTime: () => {
|
|
26647
|
-
api$
|
|
26761
|
+
api$8?.resetUsageTotals?.().catch?.(() => {
|
|
26648
26762
|
});
|
|
26649
26763
|
set({
|
|
26650
26764
|
runPromptTokens: 0,
|
|
@@ -26675,13 +26789,13 @@ const usageStore = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
26675
26789
|
__proto__: null,
|
|
26676
26790
|
useUsageStore
|
|
26677
26791
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
26678
|
-
const api$
|
|
26792
|
+
const api$7 = window.api;
|
|
26679
26793
|
const useSessionStore = create$1((set) => ({
|
|
26680
26794
|
sessionId: "",
|
|
26681
26795
|
projectPath: "",
|
|
26682
26796
|
hasProject: false,
|
|
26683
26797
|
init: async () => {
|
|
26684
|
-
const session = await api$
|
|
26798
|
+
const session = await api$7.getCurrentSession();
|
|
26685
26799
|
set({
|
|
26686
26800
|
sessionId: session.sessionId,
|
|
26687
26801
|
projectPath: session.projectPath,
|
|
@@ -26692,7 +26806,7 @@ const useSessionStore = create$1((set) => ({
|
|
|
26692
26806
|
}
|
|
26693
26807
|
},
|
|
26694
26808
|
pickFolder: async () => {
|
|
26695
|
-
const result = await api$
|
|
26809
|
+
const result = await api$7.pickFolder();
|
|
26696
26810
|
if (result) {
|
|
26697
26811
|
useChatStore.getState().clear();
|
|
26698
26812
|
useProgressStore.getState().clear();
|
|
@@ -26713,7 +26827,7 @@ const useSessionStore = create$1((set) => ({
|
|
|
26713
26827
|
return false;
|
|
26714
26828
|
},
|
|
26715
26829
|
closeProject: async () => {
|
|
26716
|
-
await api$
|
|
26830
|
+
await api$7.closeProject();
|
|
26717
26831
|
useChatStore.getState().clear();
|
|
26718
26832
|
useProgressStore.getState().clear();
|
|
26719
26833
|
useActivityStore.getState().clear();
|
|
@@ -26723,7 +26837,7 @@ const useSessionStore = create$1((set) => ({
|
|
|
26723
26837
|
set({ sessionId: "", projectPath: "", hasProject: false });
|
|
26724
26838
|
}
|
|
26725
26839
|
}));
|
|
26726
|
-
const api$
|
|
26840
|
+
const api$6 = window.api;
|
|
26727
26841
|
const ROW_HEIGHT = 28;
|
|
26728
26842
|
const OVERSCAN_ROWS = 10;
|
|
26729
26843
|
const MAX_DROP_FILE_SIZE = 100 * 1024 * 1024;
|
|
@@ -26822,7 +26936,7 @@ function WorkspaceTree() {
|
|
|
26822
26936
|
const parentKey = toKey(relativePath);
|
|
26823
26937
|
setParentLoading(parentKey, true);
|
|
26824
26938
|
try {
|
|
26825
|
-
const children = await api$
|
|
26939
|
+
const children = await api$6.listTree({
|
|
26826
26940
|
relativePath,
|
|
26827
26941
|
showIgnored,
|
|
26828
26942
|
limit: 2e3
|
|
@@ -26847,8 +26961,8 @@ function WorkspaceTree() {
|
|
|
26847
26961
|
void Promise.all(dirs.map((dir) => loadChildren(dir)));
|
|
26848
26962
|
}, 500);
|
|
26849
26963
|
};
|
|
26850
|
-
const unsubFileCreated = api$
|
|
26851
|
-
const unsubAgentDone = api$
|
|
26964
|
+
const unsubFileCreated = api$6.onFileCreated(scheduleRefresh);
|
|
26965
|
+
const unsubAgentDone = api$6.onAgentDone(scheduleRefresh);
|
|
26852
26966
|
return () => {
|
|
26853
26967
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
26854
26968
|
unsubFileCreated();
|
|
@@ -26888,7 +27002,7 @@ function WorkspaceTree() {
|
|
|
26888
27002
|
}
|
|
26889
27003
|
setSearching(true);
|
|
26890
27004
|
try {
|
|
26891
|
-
const results = await api$
|
|
27005
|
+
const results = await api$6.searchTree(query.trim(), { showIgnored, maxResults: 4e3 });
|
|
26892
27006
|
setSearchResults(results);
|
|
26893
27007
|
} finally {
|
|
26894
27008
|
setSearching(false);
|
|
@@ -26932,7 +27046,7 @@ function WorkspaceTree() {
|
|
|
26932
27046
|
if (node2.type !== "file") return;
|
|
26933
27047
|
const ext = (node2.name.split(".").pop() || "").toLowerCase();
|
|
26934
27048
|
if (!TEXT_EXTENSIONS.has(ext)) {
|
|
26935
|
-
api$
|
|
27049
|
+
api$6.openFile(node2.path);
|
|
26936
27050
|
return;
|
|
26937
27051
|
}
|
|
26938
27052
|
const normalizedNodePath = normalizePath(node2.path);
|
|
@@ -26957,14 +27071,14 @@ function WorkspaceTree() {
|
|
|
26957
27071
|
});
|
|
26958
27072
|
}, [data, openPreview]);
|
|
26959
27073
|
const createArtifact = reactExports.useCallback(async (node2) => {
|
|
26960
|
-
await api$
|
|
27074
|
+
await api$6.createArtifactFromFile(node2.path);
|
|
26961
27075
|
await refreshEntities();
|
|
26962
27076
|
}, [refreshEntities]);
|
|
26963
27077
|
const handleTrashClick = reactExports.useCallback(async (node2) => {
|
|
26964
27078
|
if (confirmTrashPath === node2.relativePath) {
|
|
26965
27079
|
if (confirmTimerRef.current) clearTimeout(confirmTimerRef.current);
|
|
26966
27080
|
setConfirmTrashPath(null);
|
|
26967
|
-
const result = await api$
|
|
27081
|
+
const result = await api$6.trashFile(node2.path);
|
|
26968
27082
|
if (result.success) {
|
|
26969
27083
|
const parentRelPath = node2.relativePath.includes("/") ? node2.relativePath.slice(0, node2.relativePath.lastIndexOf("/")) : "";
|
|
26970
27084
|
await loadChildren(parentRelPath);
|
|
@@ -27013,7 +27127,7 @@ function WorkspaceTree() {
|
|
|
27013
27127
|
return;
|
|
27014
27128
|
}
|
|
27015
27129
|
const relPath = creating.parentDir ? `${creating.parentDir}/${createValue.trim()}` : createValue.trim();
|
|
27016
|
-
const result = creating.type === "file" ? await api$
|
|
27130
|
+
const result = creating.type === "file" ? await api$6.createFile(relPath) : await api$6.createDir(relPath);
|
|
27017
27131
|
if (result.success) {
|
|
27018
27132
|
await loadChildren(creating.parentDir);
|
|
27019
27133
|
}
|
|
@@ -27040,7 +27154,7 @@ function WorkspaceTree() {
|
|
|
27040
27154
|
const parentDir = renaming.includes("/") ? renaming.slice(0, renaming.lastIndexOf("/")) : "";
|
|
27041
27155
|
const newRelPath = parentDir ? `${parentDir}/${renameValue.trim()}` : renameValue.trim();
|
|
27042
27156
|
if (newRelPath !== renaming) {
|
|
27043
|
-
await api$
|
|
27157
|
+
await api$6.renameFile(renaming, newRelPath);
|
|
27044
27158
|
await loadChildren(parentDir);
|
|
27045
27159
|
}
|
|
27046
27160
|
setRenaming(null);
|
|
@@ -27082,7 +27196,7 @@ function WorkspaceTree() {
|
|
|
27082
27196
|
const base64 = btoa(
|
|
27083
27197
|
new Uint8Array(buffer).reduce((data2, byte) => data2 + String.fromCharCode(byte), "")
|
|
27084
27198
|
);
|
|
27085
|
-
await api$
|
|
27199
|
+
await api$6.dropToDir(file.name, base64, targetRelPath);
|
|
27086
27200
|
}
|
|
27087
27201
|
await loadChildren(targetRelPath);
|
|
27088
27202
|
}, [getDropDir, loadChildren]);
|
|
@@ -27108,7 +27222,7 @@ function WorkspaceTree() {
|
|
|
27108
27222
|
const base64 = btoa(
|
|
27109
27223
|
new Uint8Array(buffer).reduce((data2, byte) => data2 + String.fromCharCode(byte), "")
|
|
27110
27224
|
);
|
|
27111
|
-
await api$
|
|
27225
|
+
await api$6.dropToDir(file.name, base64, "");
|
|
27112
27226
|
}
|
|
27113
27227
|
await loadChildren("");
|
|
27114
27228
|
}, [loadChildren]);
|
|
@@ -27170,7 +27284,7 @@ function WorkspaceTree() {
|
|
|
27170
27284
|
"div",
|
|
27171
27285
|
{
|
|
27172
27286
|
className: "flex items-center gap-1 rounded px-1.5 h-7 text-xs bg-[var(--color-accent)]/10",
|
|
27173
|
-
style: { paddingLeft: `${depth *
|
|
27287
|
+
style: { paddingLeft: `${depth * 1.1 + 0.4}em` },
|
|
27174
27288
|
children: [
|
|
27175
27289
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-3 shrink-0" }),
|
|
27176
27290
|
creating.type === "directory" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { size: 12, className: "shrink-0 t-text-warning" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(File, { size: 12, className: "shrink-0 t-text-muted" }),
|
|
@@ -27197,7 +27311,7 @@ function WorkspaceTree() {
|
|
|
27197
27311
|
"div",
|
|
27198
27312
|
{
|
|
27199
27313
|
className: "flex items-center gap-1 text-xs t-text-muted h-7",
|
|
27200
|
-
style: { paddingLeft: `${row.depth *
|
|
27314
|
+
style: { paddingLeft: `${row.depth * 1.1 + 2}em` },
|
|
27201
27315
|
children: [
|
|
27202
27316
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 11, className: "animate-spin" }),
|
|
27203
27317
|
"Loading..."
|
|
@@ -27330,6 +27444,7 @@ function WorkspaceTree() {
|
|
|
27330
27444
|
value: query,
|
|
27331
27445
|
onChange: (e) => setQuery(e.target.value),
|
|
27332
27446
|
placeholder: "Filter files...",
|
|
27447
|
+
"aria-label": "Filter files",
|
|
27333
27448
|
className: "w-full bg-transparent text-xs outline-none t-focus-ring t-text"
|
|
27334
27449
|
}
|
|
27335
27450
|
)
|
|
@@ -27843,6 +27958,7 @@ function SkillsContent() {
|
|
|
27843
27958
|
onClick: () => fileInputRef.current?.click(),
|
|
27844
27959
|
className: "no-drag flex items-center gap-1 px-1.5 py-0.5 text-[10px] t-text-muted hover:t-text-accent-soft transition-colors rounded t-bg-hover",
|
|
27845
27960
|
title: "Upload skill (.zip)",
|
|
27961
|
+
"aria-label": "Install skill from zip file",
|
|
27846
27962
|
children: [
|
|
27847
27963
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CloudUpload, { size: 11 }),
|
|
27848
27964
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Install" })
|
|
@@ -27870,6 +27986,7 @@ function SkillsContent() {
|
|
|
27870
27986
|
value: searchQuery,
|
|
27871
27987
|
onChange: (e) => setSearchQuery(e.target.value),
|
|
27872
27988
|
placeholder: "Search skills or tags...",
|
|
27989
|
+
"aria-label": "Search skills",
|
|
27873
27990
|
className: "w-full pl-6 pr-2 py-1 text-[11px] rounded border t-border t-bg-surface t-text focus:outline-none focus:border-[var(--color-accent-soft)]"
|
|
27874
27991
|
}
|
|
27875
27992
|
)
|
|
@@ -27957,13 +28074,30 @@ function EntityTabs() {
|
|
|
27957
28074
|
return null;
|
|
27958
28075
|
}
|
|
27959
28076
|
};
|
|
28077
|
+
const handleTabKeyDown = (e) => {
|
|
28078
|
+
const tabKeys = tabs.map((t) => t.key);
|
|
28079
|
+
const idx = tabKeys.indexOf(leftTab);
|
|
28080
|
+
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
28081
|
+
e.preventDefault();
|
|
28082
|
+
const next = tabKeys[(idx + 1) % tabKeys.length];
|
|
28083
|
+
setLeftTab(next);
|
|
28084
|
+
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
28085
|
+
e.preventDefault();
|
|
28086
|
+
const prev = tabKeys[(idx - 1 + tabKeys.length) % tabKeys.length];
|
|
28087
|
+
setLeftTab(prev);
|
|
28088
|
+
}
|
|
28089
|
+
};
|
|
27960
28090
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col min-h-0", children: [
|
|
27961
28091
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex border-b t-border px-1", role: "tablist", "aria-label": "Content categories", children: tabs.map(({ key, label, icon: Icon2 }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
27962
28092
|
"button",
|
|
27963
28093
|
{
|
|
27964
28094
|
role: "tab",
|
|
28095
|
+
id: `tab-${key}`,
|
|
27965
28096
|
"aria-selected": leftTab === key,
|
|
28097
|
+
"aria-controls": `tabpanel-${key}`,
|
|
28098
|
+
tabIndex: leftTab === key ? 0 : -1,
|
|
27966
28099
|
onClick: () => setLeftTab(key),
|
|
28100
|
+
onKeyDown: handleTabKeyDown,
|
|
27967
28101
|
className: `no-drag flex items-center gap-1 px-2 py-2 text-[11px] font-medium border-b-2 transition-colors ${leftTab === key ? "border-[var(--color-accent-soft)] t-text-accent" : "border-transparent t-text-muted hover:t-text-secondary"}`,
|
|
27968
28102
|
title: label,
|
|
27969
28103
|
children: [
|
|
@@ -27973,7 +28107,16 @@ function EntityTabs() {
|
|
|
27973
28107
|
},
|
|
27974
28108
|
key
|
|
27975
28109
|
)) }),
|
|
27976
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28111
|
+
"div",
|
|
28112
|
+
{
|
|
28113
|
+
role: "tabpanel",
|
|
28114
|
+
id: `tabpanel-${leftTab}`,
|
|
28115
|
+
"aria-labelledby": `tab-${leftTab}`,
|
|
28116
|
+
className: "flex-1 min-h-0 overflow-hidden flex flex-col",
|
|
28117
|
+
children: renderContent()
|
|
28118
|
+
}
|
|
28119
|
+
)
|
|
27977
28120
|
] });
|
|
27978
28121
|
}
|
|
27979
28122
|
function QuickAction({
|
|
@@ -28158,6 +28301,166 @@ function LiteratureSidebar() {
|
|
|
28158
28301
|
] })
|
|
28159
28302
|
] });
|
|
28160
28303
|
}
|
|
28304
|
+
const useComputeStore = create$1((set) => ({
|
|
28305
|
+
runs: /* @__PURE__ */ new Map(),
|
|
28306
|
+
environment: null,
|
|
28307
|
+
updateRun: (runId, data) => set((state) => {
|
|
28308
|
+
const next = new Map(state.runs);
|
|
28309
|
+
const existing = next.get(runId);
|
|
28310
|
+
if (existing) {
|
|
28311
|
+
next.set(runId, { ...existing, ...data });
|
|
28312
|
+
} else {
|
|
28313
|
+
next.set(runId, {
|
|
28314
|
+
runId,
|
|
28315
|
+
status: "running",
|
|
28316
|
+
currentPhase: "full",
|
|
28317
|
+
command: "",
|
|
28318
|
+
sandbox: "process",
|
|
28319
|
+
weight: "heavy",
|
|
28320
|
+
elapsedSeconds: 0,
|
|
28321
|
+
outputBytes: 0,
|
|
28322
|
+
outputLines: 0,
|
|
28323
|
+
stalled: false,
|
|
28324
|
+
outputTail: "",
|
|
28325
|
+
...data
|
|
28326
|
+
});
|
|
28327
|
+
}
|
|
28328
|
+
return { runs: next };
|
|
28329
|
+
}),
|
|
28330
|
+
removeRun: (runId) => set((state) => {
|
|
28331
|
+
const next = new Map(state.runs);
|
|
28332
|
+
next.delete(runId);
|
|
28333
|
+
return { runs: next };
|
|
28334
|
+
}),
|
|
28335
|
+
setEnvironment: (env2) => set({ environment: env2 }),
|
|
28336
|
+
reset: () => set({ runs: /* @__PURE__ */ new Map(), environment: null })
|
|
28337
|
+
}));
|
|
28338
|
+
function useActiveRuns() {
|
|
28339
|
+
const runs = useComputeStore((s15) => s15.runs);
|
|
28340
|
+
return Array.from(runs.values()).filter(
|
|
28341
|
+
(r) => r.status === "running" || r.status === "stalled"
|
|
28342
|
+
);
|
|
28343
|
+
}
|
|
28344
|
+
function useRecentRuns() {
|
|
28345
|
+
const runs = useComputeStore((s15) => s15.runs);
|
|
28346
|
+
return Array.from(runs.values()).filter((r) => r.status !== "running" && r.status !== "stalled").sort((a, b2) => {
|
|
28347
|
+
const aTime = a.startedAt ? new Date(a.startedAt).getTime() : 0;
|
|
28348
|
+
const bTime = b2.startedAt ? new Date(b2.startedAt).getTime() : 0;
|
|
28349
|
+
return bTime - aTime;
|
|
28350
|
+
}).slice(0, 20);
|
|
28351
|
+
}
|
|
28352
|
+
function useActiveRunCount() {
|
|
28353
|
+
const runs = useComputeStore((s15) => s15.runs);
|
|
28354
|
+
let count = 0;
|
|
28355
|
+
for (const r of runs.values()) {
|
|
28356
|
+
if (r.status === "running" || r.status === "stalled") count++;
|
|
28357
|
+
}
|
|
28358
|
+
return count;
|
|
28359
|
+
}
|
|
28360
|
+
function ResourceBar({ label, percent }) {
|
|
28361
|
+
const clamped = Math.min(100, Math.max(0, percent));
|
|
28362
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
28363
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] t-text-muted w-11 text-right shrink-0", children: label }),
|
|
28364
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 h-1 rounded-full t-bg-elevated overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28365
|
+
"div",
|
|
28366
|
+
{
|
|
28367
|
+
className: `h-full rounded-full transition-all duration-700 ${clamped > 85 ? "" : "t-gradient-accent-h"}`,
|
|
28368
|
+
style: {
|
|
28369
|
+
width: `${clamped}%`,
|
|
28370
|
+
...clamped > 85 ? { background: "var(--color-text-muted)", opacity: 0.6 } : { opacity: 0.5 }
|
|
28371
|
+
}
|
|
28372
|
+
}
|
|
28373
|
+
) }),
|
|
28374
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] t-text-muted tabular-nums w-7 shrink-0", children: [
|
|
28375
|
+
clamped,
|
|
28376
|
+
"%"
|
|
28377
|
+
] })
|
|
28378
|
+
] });
|
|
28379
|
+
}
|
|
28380
|
+
function SandboxExplanation({ environment }) {
|
|
28381
|
+
const [expanded, setExpanded] = reactExports.useState(false);
|
|
28382
|
+
const isDocker = environment.sandbox === "docker";
|
|
28383
|
+
const isMac = environment.os === "darwin";
|
|
28384
|
+
const hasMLX = environment.mlxAvailable;
|
|
28385
|
+
let explanation;
|
|
28386
|
+
if (isDocker && isMac) {
|
|
28387
|
+
explanation = "Docker available. Note: Docker on macOS lacks GPU passthrough. Switch to Process sandbox for MLX/Metal GPU access if needed.";
|
|
28388
|
+
} else if (isDocker) {
|
|
28389
|
+
explanation = "Docker available. Runs execute in isolated containers with resource limits.";
|
|
28390
|
+
} else if (isMac && hasMLX) {
|
|
28391
|
+
explanation = "Process sandbox uses Python virtual environments with process-group isolation. Direct MLX/Metal GPU access for ML training.";
|
|
28392
|
+
} else if (isMac) {
|
|
28393
|
+
explanation = "Process sandbox uses Python virtual environments. Install Docker for stronger container-based isolation.";
|
|
28394
|
+
} else {
|
|
28395
|
+
explanation = "Process sandbox uses Python virtual environments with process-group isolation.";
|
|
28396
|
+
}
|
|
28397
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 pt-2 border-t t-border-subtle", children: [
|
|
28398
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28399
|
+
"button",
|
|
28400
|
+
{
|
|
28401
|
+
onClick: () => setExpanded(!expanded),
|
|
28402
|
+
className: "flex items-center gap-1 text-[10px] t-text-muted hover:t-text-secondary transition-colors w-full text-left",
|
|
28403
|
+
children: [
|
|
28404
|
+
expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 10 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 10 }),
|
|
28405
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
28406
|
+
"Sandbox: ",
|
|
28407
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-secondary", children: isDocker ? "Docker" : "Process (venv)" })
|
|
28408
|
+
] })
|
|
28409
|
+
]
|
|
28410
|
+
}
|
|
28411
|
+
),
|
|
28412
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 ml-3.5 text-[10px] t-text-muted leading-relaxed", children: explanation })
|
|
28413
|
+
] });
|
|
28414
|
+
}
|
|
28415
|
+
function ComputeSidebar() {
|
|
28416
|
+
const environment = useComputeStore((s15) => s15.environment);
|
|
28417
|
+
const activeCount = useActiveRunCount();
|
|
28418
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col min-h-0", children: [
|
|
28419
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-2 pt-2 pb-2", children: [
|
|
28420
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] t-text-accent-soft uppercase tracking-wider px-3 pb-1.5 font-medium", children: "Compute Target" }),
|
|
28421
|
+
environment ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-2.5 rounded-lg t-bg-surface border t-border-subtle", children: [
|
|
28422
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
28423
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `w-1.5 h-1.5 rounded-full shrink-0 ${activeCount > 0 ? "bg-[var(--color-accent)]" : "bg-[var(--color-text-muted)]"}`, style: { opacity: activeCount > 0 ? 1 : 0.5 } }),
|
|
28424
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs t-text font-medium", children: "Local Machine" })
|
|
28425
|
+
] }),
|
|
28426
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] t-text-muted leading-relaxed space-y-0.5", children: [
|
|
28427
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
28428
|
+
environment.gpu || `${environment.os} ${environment.arch}`,
|
|
28429
|
+
" · ",
|
|
28430
|
+
Math.round(environment.totalMemoryMb / 1024),
|
|
28431
|
+
" GB"
|
|
28432
|
+
] }),
|
|
28433
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
|
|
28434
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Python" }),
|
|
28435
|
+
environment.mlxAvailable && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-1 py-px rounded text-[9px] bg-[var(--color-accent-soft)]/10 t-text-accent", children: "MLX" }),
|
|
28436
|
+
environment.sandbox === "docker" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-1 py-px rounded text-[9px] t-bg-elevated t-text-muted", children: "Docker" })
|
|
28437
|
+
] })
|
|
28438
|
+
] }),
|
|
28439
|
+
(environment.freeMemoryMb !== void 0 || environment.freeDiskMb !== void 0) && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2.5 space-y-1.5", children: environment.freeMemoryMb !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28440
|
+
ResourceBar,
|
|
28441
|
+
{
|
|
28442
|
+
label: "Memory",
|
|
28443
|
+
percent: Math.round((1 - environment.freeMemoryMb / environment.totalMemoryMb) * 100)
|
|
28444
|
+
}
|
|
28445
|
+
) }),
|
|
28446
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SandboxExplanation, { environment }),
|
|
28447
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 pt-2 border-t t-border-subtle text-[10px] t-text-muted", children: activeCount > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
28448
|
+
activeCount,
|
|
28449
|
+
" running"
|
|
28450
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Ready" }) })
|
|
28451
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-4 rounded-lg t-bg-surface border t-border-subtle", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 t-text-muted", children: [
|
|
28452
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Monitor, { size: 14, className: "opacity-40" }),
|
|
28453
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px]", children: "Detecting environment..." })
|
|
28454
|
+
] }) }),
|
|
28455
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1.5 px-3 py-2 rounded-lg border border-dashed t-border-subtle cursor-default", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] t-text-muted opacity-60", children: "+ Add remote target" }) })
|
|
28456
|
+
] }),
|
|
28457
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-3 border-t t-border" }),
|
|
28458
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto px-3 py-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 text-[10px] t-text-muted leading-relaxed", children: [
|
|
28459
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Info$1, { size: 12, className: "shrink-0 mt-0.5 opacity-40" }),
|
|
28460
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Ask the agent to run scripts, train models, or process data. Code executes in a sandboxed environment with progress tracking and failure analysis." })
|
|
28461
|
+
] }) })
|
|
28462
|
+
] });
|
|
28463
|
+
}
|
|
28161
28464
|
function UserProfile() {
|
|
28162
28465
|
const projectPath = useSessionStore((s15) => s15.projectPath);
|
|
28163
28466
|
const pickFolder = useSessionStore((s15) => s15.pickFolder);
|
|
@@ -28181,25 +28484,6 @@ function UserProfile() {
|
|
|
28181
28484
|
}
|
|
28182
28485
|
);
|
|
28183
28486
|
}
|
|
28184
|
-
const REASONING_MODELS = [
|
|
28185
|
-
"gpt-5.4",
|
|
28186
|
-
"gpt-5.4-mini",
|
|
28187
|
-
"gpt-5.4-nano",
|
|
28188
|
-
"claude-opus-4-6"
|
|
28189
|
-
];
|
|
28190
|
-
const SUPPORTED_MODELS = [
|
|
28191
|
-
// GPT
|
|
28192
|
-
{ id: "gpt-5.4", label: "GPT-5.4", provider: "OpenAI" },
|
|
28193
|
-
{ id: "gpt-5.4-mini", label: "GPT-5.4 Mini", provider: "OpenAI" },
|
|
28194
|
-
{ id: "gpt-5.4-nano", label: "GPT-5.4 Nano", provider: "OpenAI" },
|
|
28195
|
-
{ id: "gpt-4o", label: "GPT-4o", provider: "OpenAI" },
|
|
28196
|
-
// Anthropic Claude 4.6
|
|
28197
|
-
{ id: "claude-opus-4-6", label: "Claude Opus 4.6", provider: "Anthropic" },
|
|
28198
|
-
// Anthropic Claude 4.5
|
|
28199
|
-
{ id: "claude-opus-4-5-20251101", label: "Claude Opus 4.5", provider: "Anthropic" },
|
|
28200
|
-
{ id: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5", provider: "Anthropic" },
|
|
28201
|
-
{ id: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5", provider: "Anthropic" }
|
|
28202
|
-
];
|
|
28203
28487
|
const providers = [...new Set(SUPPORTED_MODELS.map((m) => m.provider))];
|
|
28204
28488
|
const groupedModels = {};
|
|
28205
28489
|
for (const p of providers) {
|
|
@@ -28208,6 +28492,8 @@ for (const p of providers) {
|
|
|
28208
28492
|
function ModelSelector$1({ selectedModel, onSelectModel }) {
|
|
28209
28493
|
const [open, setOpen] = reactExports.useState(false);
|
|
28210
28494
|
const [anthropicStatus, setAnthropicStatus] = reactExports.useState(null);
|
|
28495
|
+
const [codexStatus, setCodexStatus] = reactExports.useState(null);
|
|
28496
|
+
const [codexLoggingIn, setCodexLoggingIn] = reactExports.useState(false);
|
|
28211
28497
|
const [showAnthropicDialog, setShowAnthropicDialog] = reactExports.useState(false);
|
|
28212
28498
|
const [showOpenAIDialog, setShowOpenAIDialog] = reactExports.useState(false);
|
|
28213
28499
|
const ref = reactExports.useRef(null);
|
|
@@ -28221,6 +28507,14 @@ function ModelSelector$1({ selectedModel, onSelectModel }) {
|
|
|
28221
28507
|
setAnthropicStatus(null);
|
|
28222
28508
|
}
|
|
28223
28509
|
}, [api2]);
|
|
28510
|
+
const refreshCodexStatus = reactExports.useCallback(async () => {
|
|
28511
|
+
try {
|
|
28512
|
+
const status = await api2?.getOpenAICodexStatus?.();
|
|
28513
|
+
setCodexStatus(status ?? null);
|
|
28514
|
+
} catch {
|
|
28515
|
+
setCodexStatus(null);
|
|
28516
|
+
}
|
|
28517
|
+
}, [api2]);
|
|
28224
28518
|
reactExports.useEffect(() => {
|
|
28225
28519
|
if (!open) return;
|
|
28226
28520
|
const handler = (e) => {
|
|
@@ -28241,13 +28535,47 @@ function ModelSelector$1({ selectedModel, onSelectModel }) {
|
|
|
28241
28535
|
}, [open]);
|
|
28242
28536
|
reactExports.useEffect(() => {
|
|
28243
28537
|
refreshAnthropicStatus();
|
|
28538
|
+
refreshCodexStatus();
|
|
28244
28539
|
const unsub = api2?.onAnthropicAuthStatus?.((status) => setAnthropicStatus(status));
|
|
28245
28540
|
return () => {
|
|
28246
28541
|
if (typeof unsub === "function") unsub();
|
|
28247
28542
|
};
|
|
28248
|
-
}, [api2, refreshAnthropicStatus]);
|
|
28543
|
+
}, [api2, refreshAnthropicStatus, refreshCodexStatus]);
|
|
28544
|
+
const handleCodexLogin = async () => {
|
|
28545
|
+
setCodexLoggingIn(true);
|
|
28546
|
+
try {
|
|
28547
|
+
const result = await api2?.openaiCodexLogin?.();
|
|
28548
|
+
if (result?.success) {
|
|
28549
|
+
await refreshCodexStatus();
|
|
28550
|
+
} else {
|
|
28551
|
+
console.error("[ModelSelector] Codex login failed:", result?.error);
|
|
28552
|
+
}
|
|
28553
|
+
} catch (err) {
|
|
28554
|
+
console.error("[ModelSelector] Codex login error:", err);
|
|
28555
|
+
} finally {
|
|
28556
|
+
setCodexLoggingIn(false);
|
|
28557
|
+
}
|
|
28558
|
+
};
|
|
28559
|
+
const handleCodexLogout = async () => {
|
|
28560
|
+
await api2?.openaiCodexLogout?.();
|
|
28561
|
+
await refreshCodexStatus();
|
|
28562
|
+
};
|
|
28249
28563
|
const handleModelSelect = async (model) => {
|
|
28250
|
-
|
|
28564
|
+
const { provider } = parseModelKey(model.id);
|
|
28565
|
+
if (provider === "openai-codex") {
|
|
28566
|
+
if (!codexStatus?.isLoggedIn) {
|
|
28567
|
+
await handleCodexLogin();
|
|
28568
|
+
const status = await api2?.getOpenAICodexStatus?.();
|
|
28569
|
+
if (!status?.isLoggedIn) {
|
|
28570
|
+
setOpen(false);
|
|
28571
|
+
return;
|
|
28572
|
+
}
|
|
28573
|
+
}
|
|
28574
|
+
onSelectModel(model.id);
|
|
28575
|
+
setOpen(false);
|
|
28576
|
+
return;
|
|
28577
|
+
}
|
|
28578
|
+
if (provider === "openai") {
|
|
28251
28579
|
const status = await api2?.getOpenAIAuthStatus?.();
|
|
28252
28580
|
if (!status?.hasApiKey) {
|
|
28253
28581
|
setShowOpenAIDialog(true);
|
|
@@ -28255,7 +28583,7 @@ function ModelSelector$1({ selectedModel, onSelectModel }) {
|
|
|
28255
28583
|
return;
|
|
28256
28584
|
}
|
|
28257
28585
|
}
|
|
28258
|
-
if (
|
|
28586
|
+
if (provider === "anthropic") {
|
|
28259
28587
|
const status = await api2?.getAnthropicAuthStatus?.();
|
|
28260
28588
|
if (!status?.hasApiKeyFallback) {
|
|
28261
28589
|
setShowAnthropicDialog(true);
|
|
@@ -28267,18 +28595,27 @@ function ModelSelector$1({ selectedModel, onSelectModel }) {
|
|
|
28267
28595
|
setOpen(false);
|
|
28268
28596
|
refreshAnthropicStatus();
|
|
28269
28597
|
};
|
|
28270
|
-
const
|
|
28598
|
+
const { provider: currentProvider } = current ? parseModelKey(current.id) : { provider: "" };
|
|
28599
|
+
const authBadge = currentProvider === "anthropic" ? anthropicStatus?.authMode === "api-key" ? "api" : "auth" : currentProvider === "openai-codex" ? "sub" : currentProvider === "openai" ? "api" : null;
|
|
28271
28600
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref, className: "relative", children: [
|
|
28272
28601
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28273
28602
|
"button",
|
|
28274
28603
|
{
|
|
28275
28604
|
onClick: () => setOpen(!open),
|
|
28276
|
-
className: "no-drag flex items-center gap-1.5 px-2 py-1.5 rounded-lg t-text-secondary text-xs font-medium t-bg-hover transition-colors",
|
|
28277
|
-
title: "Select model",
|
|
28605
|
+
className: "no-drag group relative flex items-center gap-1.5 px-2 py-1.5 rounded-lg t-text-secondary text-xs font-medium t-bg-hover transition-colors",
|
|
28278
28606
|
"aria-label": "Select model",
|
|
28279
28607
|
"aria-haspopup": "listbox",
|
|
28280
28608
|
"aria-expanded": open,
|
|
28281
28609
|
children: [
|
|
28610
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28611
|
+
"span",
|
|
28612
|
+
{
|
|
28613
|
+
role: "tooltip",
|
|
28614
|
+
className: "pointer-events-none absolute left-1/2 -translate-x-1/2 top-full mt-1 px-2 py-0.5 rounded text-[10px] t-bg-elevated t-text-secondary border t-border shadow-lg whitespace-nowrap opacity-0 group-hover:opacity-100 z-50",
|
|
28615
|
+
style: { transition: "opacity 0.15s ease", transitionDelay: "0.2s" },
|
|
28616
|
+
children: "Select model"
|
|
28617
|
+
}
|
|
28618
|
+
),
|
|
28282
28619
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Cpu, { size: 14 }),
|
|
28283
28620
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate max-w-[100px]", children: current?.label || selectedModel }),
|
|
28284
28621
|
authBadge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] px-1 rounded border t-border t-text-muted uppercase", children: authBadge }),
|
|
@@ -28288,7 +28625,39 @@ function ModelSelector$1({ selectedModel, onSelectModel }) {
|
|
|
28288
28625
|
),
|
|
28289
28626
|
open && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-full left-0 mt-1 w-64 max-h-80 overflow-y-auto rounded-xl border t-border t-bg-surface shadow-xl z-50", role: "listbox", "aria-label": "Available models", children: providers.map((provider) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
28290
28627
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider t-text-muted sticky top-0 t-bg-surface", children: provider }),
|
|
28291
|
-
|
|
28628
|
+
provider === "ChatGPT Subscription" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 pb-1 flex items-center justify-between", children: [
|
|
28629
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] t-text-muted", children: codexStatus?.isLoggedIn ? "Signed in" : "OAuth required" }),
|
|
28630
|
+
codexStatus?.isLoggedIn ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28631
|
+
"button",
|
|
28632
|
+
{
|
|
28633
|
+
onClick: (e) => {
|
|
28634
|
+
e.stopPropagation();
|
|
28635
|
+
handleCodexLogout();
|
|
28636
|
+
},
|
|
28637
|
+
className: "text-[10px] t-text-muted hover:t-text flex items-center gap-0.5",
|
|
28638
|
+
children: [
|
|
28639
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LogOut, { size: 10 }),
|
|
28640
|
+
" Sign out"
|
|
28641
|
+
]
|
|
28642
|
+
}
|
|
28643
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28644
|
+
"button",
|
|
28645
|
+
{
|
|
28646
|
+
onClick: (e) => {
|
|
28647
|
+
e.stopPropagation();
|
|
28648
|
+
handleCodexLogin();
|
|
28649
|
+
},
|
|
28650
|
+
disabled: codexLoggingIn,
|
|
28651
|
+
className: "text-[10px] t-text-accent flex items-center gap-0.5 hover:opacity-80 disabled:opacity-50",
|
|
28652
|
+
children: [
|
|
28653
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LogIn, { size: 10 }),
|
|
28654
|
+
" ",
|
|
28655
|
+
codexLoggingIn ? "Signing in..." : "Sign in"
|
|
28656
|
+
]
|
|
28657
|
+
}
|
|
28658
|
+
)
|
|
28659
|
+
] }),
|
|
28660
|
+
(provider === "OpenAI" || provider === "Anthropic") && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 pb-1 text-[11px] t-text-muted", children: "API Key" }),
|
|
28292
28661
|
groupedModels[provider].map((model) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28293
28662
|
"button",
|
|
28294
28663
|
{
|
|
@@ -28342,7 +28711,39 @@ function ApiKeyDialog({
|
|
|
28342
28711
|
const [saving, setSaving] = reactExports.useState(false);
|
|
28343
28712
|
const [error, setError] = reactExports.useState(null);
|
|
28344
28713
|
const [showKey, setShowKey] = reactExports.useState(false);
|
|
28714
|
+
const dialogRef = reactExports.useRef(null);
|
|
28345
28715
|
const api2 = window.api;
|
|
28716
|
+
reactExports.useEffect(() => {
|
|
28717
|
+
const dialog = dialogRef.current;
|
|
28718
|
+
if (!dialog) return;
|
|
28719
|
+
const focusable = dialog.querySelectorAll(
|
|
28720
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
28721
|
+
);
|
|
28722
|
+
if (focusable.length === 0) return;
|
|
28723
|
+
const first = focusable[0];
|
|
28724
|
+
const last = focusable[focusable.length - 1];
|
|
28725
|
+
first.focus();
|
|
28726
|
+
const handler = (e) => {
|
|
28727
|
+
if (e.key === "Escape") {
|
|
28728
|
+
onClose();
|
|
28729
|
+
return;
|
|
28730
|
+
}
|
|
28731
|
+
if (e.key !== "Tab") return;
|
|
28732
|
+
if (e.shiftKey) {
|
|
28733
|
+
if (document.activeElement === first) {
|
|
28734
|
+
e.preventDefault();
|
|
28735
|
+
last.focus();
|
|
28736
|
+
}
|
|
28737
|
+
} else {
|
|
28738
|
+
if (document.activeElement === last) {
|
|
28739
|
+
e.preventDefault();
|
|
28740
|
+
first.focus();
|
|
28741
|
+
}
|
|
28742
|
+
}
|
|
28743
|
+
};
|
|
28744
|
+
dialog.addEventListener("keydown", handler);
|
|
28745
|
+
return () => dialog.removeEventListener("keydown", handler);
|
|
28746
|
+
}, []);
|
|
28346
28747
|
const handleSave = async () => {
|
|
28347
28748
|
const trimmed = value.trim();
|
|
28348
28749
|
if (!trimmed) {
|
|
@@ -28360,7 +28761,7 @@ function ApiKeyDialog({
|
|
|
28360
28761
|
setSaving(false);
|
|
28361
28762
|
}
|
|
28362
28763
|
};
|
|
28363
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-[90] flex items-center justify-center bg-black/40 p-4", role: "dialog", "aria-modal": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full max-w-md rounded-xl border t-border t-bg-surface shadow-2xl p-4 space-y-3", children: [
|
|
28764
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-[90] flex items-center justify-center bg-black/40 p-4", role: "dialog", "aria-modal": "true", "aria-label": `${provider} API Key Required`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: dialogRef, className: "w-full max-w-md rounded-xl border t-border t-bg-surface shadow-2xl p-4 space-y-3", children: [
|
|
28364
28765
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
28365
28766
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm font-semibold t-text", children: [
|
|
28366
28767
|
provider,
|
|
@@ -28386,6 +28787,7 @@ function ApiKeyDialog({
|
|
|
28386
28787
|
onKeyDown: (e) => {
|
|
28387
28788
|
if (e.key === "Enter") handleSave();
|
|
28388
28789
|
},
|
|
28790
|
+
"aria-label": `${provider} API key`,
|
|
28389
28791
|
autoFocus: true
|
|
28390
28792
|
}
|
|
28391
28793
|
),
|
|
@@ -28405,7 +28807,7 @@ function ApiKeyDialog({
|
|
|
28405
28807
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "px-1 rounded t-bg-surface", children: "~/.research-copilot/config.json" }),
|
|
28406
28808
|
". No restart needed."
|
|
28407
28809
|
] }),
|
|
28408
|
-
error && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-400", children: error }),
|
|
28810
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-400", role: "alert", children: error }),
|
|
28409
28811
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
28410
28812
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28411
28813
|
"button",
|
|
@@ -28452,13 +28854,27 @@ const COLORS = {
|
|
|
28452
28854
|
};
|
|
28453
28855
|
function ReasoningToggle$1({ selectedModel, reasoningEffort, onChangeEffort }) {
|
|
28454
28856
|
if (!REASONING_MODELS.includes(selectedModel)) return null;
|
|
28455
|
-
return /* @__PURE__ */ jsxRuntimeExports.
|
|
28857
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28456
28858
|
"button",
|
|
28457
28859
|
{
|
|
28458
28860
|
onClick: () => onChangeEffort(CYCLE[reasoningEffort]),
|
|
28459
|
-
className: "no-drag p-
|
|
28460
|
-
|
|
28461
|
-
children:
|
|
28861
|
+
className: "no-drag group relative p-2.5 rounded-lg t-bg-hover transition-colors",
|
|
28862
|
+
"aria-label": `Reasoning effort: ${reasoningEffort}`,
|
|
28863
|
+
children: [
|
|
28864
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Lightbulb, { size: 16, className: COLORS[reasoningEffort] }),
|
|
28865
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28866
|
+
"span",
|
|
28867
|
+
{
|
|
28868
|
+
role: "tooltip",
|
|
28869
|
+
className: "pointer-events-none absolute left-1/2 -translate-x-1/2 top-full mt-1 px-2 py-0.5 rounded text-[10px] t-bg-elevated t-text-secondary border t-border shadow-lg whitespace-nowrap opacity-0 group-hover:opacity-100 z-50",
|
|
28870
|
+
style: { transition: "opacity 0.15s ease", transitionDelay: "0.2s" },
|
|
28871
|
+
children: [
|
|
28872
|
+
"Reasoning: ",
|
|
28873
|
+
reasoningEffort
|
|
28874
|
+
]
|
|
28875
|
+
}
|
|
28876
|
+
)
|
|
28877
|
+
]
|
|
28462
28878
|
}
|
|
28463
28879
|
);
|
|
28464
28880
|
}
|
|
@@ -28475,45 +28891,87 @@ function ReasoningToggle() {
|
|
|
28475
28891
|
}
|
|
28476
28892
|
);
|
|
28477
28893
|
}
|
|
28894
|
+
function ToolbarButton({ onClick, tooltip, children }) {
|
|
28895
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28896
|
+
"button",
|
|
28897
|
+
{
|
|
28898
|
+
onClick,
|
|
28899
|
+
"aria-label": tooltip,
|
|
28900
|
+
className: "no-drag group relative p-2.5 rounded-lg t-text-muted t-bg-hover transition-colors",
|
|
28901
|
+
children: [
|
|
28902
|
+
children,
|
|
28903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28904
|
+
"span",
|
|
28905
|
+
{
|
|
28906
|
+
role: "tooltip",
|
|
28907
|
+
className: "pointer-events-none absolute left-1/2 -translate-x-1/2 top-full mt-1 px-2 py-0.5 rounded text-[10px] t-bg-elevated t-text-secondary border t-border shadow-lg whitespace-nowrap opacity-0 group-hover:opacity-100 z-50",
|
|
28908
|
+
style: { transition: "opacity 0.15s ease", transitionDelay: "0.2s" },
|
|
28909
|
+
children: tooltip
|
|
28910
|
+
}
|
|
28911
|
+
)
|
|
28912
|
+
]
|
|
28913
|
+
}
|
|
28914
|
+
);
|
|
28915
|
+
}
|
|
28478
28916
|
function LeftSidebar() {
|
|
28479
28917
|
const theme = useUIStore((s15) => s15.theme);
|
|
28480
28918
|
const toggleTheme = useUIStore((s15) => s15.toggleTheme);
|
|
28481
28919
|
const centerView = useUIStore((s15) => s15.centerView);
|
|
28920
|
+
const noContextShownRef = reactExports.useRef(false);
|
|
28921
|
+
const handleResetContext = reactExports.useCallback(async () => {
|
|
28922
|
+
const messages = useChatStore.getState().messages;
|
|
28923
|
+
const hasContext = messages.some((m) => m.role === "user" || m.role === "assistant");
|
|
28924
|
+
if (!hasContext) {
|
|
28925
|
+
if (!noContextShownRef.current) {
|
|
28926
|
+
noContextShownRef.current = true;
|
|
28927
|
+
useChatStore.getState().insertContextReset();
|
|
28928
|
+
useChatStore.setState((s15) => {
|
|
28929
|
+
const msgs = [...s15.messages];
|
|
28930
|
+
const last = msgs[msgs.length - 1];
|
|
28931
|
+
if (last?.role === "system") {
|
|
28932
|
+
msgs[msgs.length - 1] = { ...last, content: "No context to reset yet." };
|
|
28933
|
+
}
|
|
28934
|
+
return { messages: msgs };
|
|
28935
|
+
});
|
|
28936
|
+
}
|
|
28937
|
+
return;
|
|
28938
|
+
}
|
|
28939
|
+
await window.api.clearSessionMemory();
|
|
28940
|
+
useChatStore.getState().insertContextReset();
|
|
28941
|
+
noContextShownRef.current = false;
|
|
28942
|
+
}, []);
|
|
28482
28943
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: "w-80 flex flex-col border-r t-border t-bg-base pt-10", children: [
|
|
28483
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
28944
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { "aria-label": "Sidebar tools", className: "px-4 pb-3 flex items-center justify-between", children: [
|
|
28484
28945
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ModelSelector, {}),
|
|
28485
28946
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
28486
28947
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ReasoningToggle, {}),
|
|
28487
28948
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28488
|
-
|
|
28949
|
+
ToolbarButton,
|
|
28489
28950
|
{
|
|
28490
|
-
onClick:
|
|
28491
|
-
|
|
28492
|
-
|
|
28493
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Eraser, { size: 16 })
|
|
28951
|
+
onClick: handleResetContext,
|
|
28952
|
+
tooltip: "Reset AI context",
|
|
28953
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 16 })
|
|
28494
28954
|
}
|
|
28495
28955
|
),
|
|
28496
28956
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28497
|
-
|
|
28957
|
+
ToolbarButton,
|
|
28498
28958
|
{
|
|
28499
28959
|
onClick: toggleTheme,
|
|
28500
|
-
|
|
28501
|
-
title: `Switch to ${theme === "dark" ? "light" : "dark"} mode`,
|
|
28960
|
+
tooltip: `${theme === "dark" ? "Light" : "Dark"} mode`,
|
|
28502
28961
|
children: theme === "dark" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Sun, { size: 16 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Moon, { size: 16 })
|
|
28503
28962
|
}
|
|
28504
28963
|
),
|
|
28505
28964
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28506
|
-
|
|
28965
|
+
ToolbarButton,
|
|
28507
28966
|
{
|
|
28508
28967
|
onClick: () => useUIStore.getState().toggleTerminal(),
|
|
28509
|
-
|
|
28510
|
-
title: "Toggle terminal (⌘`)",
|
|
28968
|
+
tooltip: "Terminal ⌘`",
|
|
28511
28969
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { size: 16 })
|
|
28512
28970
|
}
|
|
28513
28971
|
)
|
|
28514
28972
|
] })
|
|
28515
28973
|
] }),
|
|
28516
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: centerView === "literature" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LiteratureSidebar, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(EntityTabs, {}) }),
|
|
28974
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: centerView === "literature" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LiteratureSidebar, {}) : centerView === "compute" && window.api?.isComputeEnabled?.() ? /* @__PURE__ */ jsxRuntimeExports.jsx(ComputeSidebar, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(EntityTabs, {}) }),
|
|
28517
28975
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t t-border p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(UserProfile, {}) })
|
|
28518
28976
|
] });
|
|
28519
28977
|
}
|
|
@@ -28524,17 +28982,11 @@ const suggestions = [
|
|
|
28524
28982
|
{ icon: Sparkles, label: "Brainstorm ideas", prompt: "Help me brainstorm ideas for " }
|
|
28525
28983
|
];
|
|
28526
28984
|
function HeroIdle() {
|
|
28985
|
+
const setDraftText = useChatStore((s15) => s15.setDraftText);
|
|
28527
28986
|
const handleSuggestion = (prompt) => {
|
|
28987
|
+
setDraftText(prompt);
|
|
28528
28988
|
const input = document.querySelector("[data-chat-input]");
|
|
28529
|
-
|
|
28530
|
-
const nativeSetter = Object.getOwnPropertyDescriptor(
|
|
28531
|
-
window.HTMLTextAreaElement.prototype,
|
|
28532
|
-
"value"
|
|
28533
|
-
)?.set;
|
|
28534
|
-
nativeSetter?.call(input, prompt);
|
|
28535
|
-
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
28536
|
-
input.focus();
|
|
28537
|
-
}
|
|
28989
|
+
input?.focus();
|
|
28538
28990
|
};
|
|
28539
28991
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-10 w-full max-w-lg px-8", children: [
|
|
28540
28992
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center space-y-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -28936,7 +29388,7 @@ function StatusIcon({ status, size = 13 }) {
|
|
|
28936
29388
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size, className: "t-text-error" });
|
|
28937
29389
|
}
|
|
28938
29390
|
}
|
|
28939
|
-
function formatDuration(ms2) {
|
|
29391
|
+
function formatDuration$1(ms2) {
|
|
28940
29392
|
if (ms2 < 1e3) return `${ms2}ms`;
|
|
28941
29393
|
if (ms2 < 6e4) return `${(ms2 / 1e3).toFixed(1)}s`;
|
|
28942
29394
|
return `${(ms2 / 6e4).toFixed(1)}m`;
|
|
@@ -28944,10 +29396,10 @@ function formatDuration(ms2) {
|
|
|
28944
29396
|
function ElapsedTimer({ startedAt }) {
|
|
28945
29397
|
const [elapsed, setElapsed] = reactExports.useState(Date.now() - startedAt);
|
|
28946
29398
|
reactExports.useEffect(() => {
|
|
28947
|
-
const interval = setInterval(() => setElapsed(Date.now() - startedAt),
|
|
29399
|
+
const interval = setInterval(() => setElapsed(Date.now() - startedAt), 500);
|
|
28948
29400
|
return () => clearInterval(interval);
|
|
28949
29401
|
}, [startedAt]);
|
|
28950
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] t-text-muted tabular-nums", children: formatDuration(elapsed) });
|
|
29402
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] t-text-muted tabular-nums", children: formatDuration$1(elapsed) });
|
|
28951
29403
|
}
|
|
28952
29404
|
const CompactToolLine = React$2.memo(function CompactToolLine2({ event }) {
|
|
28953
29405
|
const [expanded, setExpanded] = reactExports.useState(false);
|
|
@@ -28967,7 +29419,7 @@ const CompactToolLine = React$2.memo(function CompactToolLine2({ event }) {
|
|
|
28967
29419
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium t-text-secondary shrink-0", children: name2 }),
|
|
28968
29420
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-muted select-none", children: "·" }),
|
|
28969
29421
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-muted truncate flex-1 text-left", children: displaySummary }),
|
|
28970
|
-
event.durationMs != null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] t-text-muted tabular-nums shrink-0", children: formatDuration(event.durationMs) }),
|
|
29422
|
+
event.durationMs != null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] t-text-muted tabular-nums shrink-0", children: formatDuration$1(event.durationMs) }),
|
|
28971
29423
|
hasExpandable && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28972
29424
|
"span",
|
|
28973
29425
|
{
|
|
@@ -29183,7 +29635,7 @@ function ToolUseStream({ events: propEvents }) {
|
|
|
29183
29635
|
running.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 mt-1", children: running.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(ToolUseCard, { event }, event.id)) })
|
|
29184
29636
|
] });
|
|
29185
29637
|
}
|
|
29186
|
-
const api$
|
|
29638
|
+
const api$5 = window.api;
|
|
29187
29639
|
const remarkPlugins$1 = [remarkGfm];
|
|
29188
29640
|
function SelectionBookmark() {
|
|
29189
29641
|
const refreshAll = useEntityStore((s15) => s15.refreshAll);
|
|
@@ -29244,7 +29696,7 @@ function SelectionBookmark() {
|
|
|
29244
29696
|
try {
|
|
29245
29697
|
const first = selectedText.split(/[.!?\n]/)[0].trim();
|
|
29246
29698
|
const title = first.length > 60 ? first.slice(0, 57) + "…" : first || "Untitled selection";
|
|
29247
|
-
const created = await api$
|
|
29699
|
+
const created = await api$5.artifactCreate({
|
|
29248
29700
|
type: "note",
|
|
29249
29701
|
title,
|
|
29250
29702
|
content: selectedText,
|
|
@@ -29276,7 +29728,7 @@ function SelectionBookmark() {
|
|
|
29276
29728
|
{
|
|
29277
29729
|
ref: tooltipRef,
|
|
29278
29730
|
onMouseDown: handleSave,
|
|
29279
|
-
className: "fixed z-
|
|
29731
|
+
className: "fixed z-50 flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs font-medium shadow-lg border t-border transition-colors",
|
|
29280
29732
|
style: {
|
|
29281
29733
|
left: pos.x,
|
|
29282
29734
|
top: pos.y,
|
|
@@ -29309,7 +29761,7 @@ const MessageBubble = React$2.memo(function MessageBubble2({ msg, isSaved }) {
|
|
|
29309
29761
|
try {
|
|
29310
29762
|
const first = msg.content.replace(/^#+\s*/, "").split(/[.!?\n]/)[0].trim();
|
|
29311
29763
|
const title = first.length > 60 ? first.slice(0, 57) + "…" : first || "Untitled note";
|
|
29312
|
-
const created = await api$
|
|
29764
|
+
const created = await api$5.artifactCreate({
|
|
29313
29765
|
type: "note",
|
|
29314
29766
|
title,
|
|
29315
29767
|
content: msg.content,
|
|
@@ -29343,6 +29795,7 @@ const MessageBubble = React$2.memo(function MessageBubble2({ msg, isSaved }) {
|
|
|
29343
29795
|
{
|
|
29344
29796
|
src,
|
|
29345
29797
|
alt: "",
|
|
29798
|
+
loading: "lazy",
|
|
29346
29799
|
className: `rounded-lg border t-border cursor-pointer hover:opacity-90 transition-opacity ${isUser ? "max-h-48" : "max-h-80"}`,
|
|
29347
29800
|
onClick: () => window.open(src, "_blank")
|
|
29348
29801
|
},
|
|
@@ -29365,10 +29818,10 @@ const MessageBubble = React$2.memo(function MessageBubble2({ msg, isSaved }) {
|
|
|
29365
29818
|
) });
|
|
29366
29819
|
});
|
|
29367
29820
|
function ThinkingIndicator() {
|
|
29368
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1.5 mt-3 ml-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex gap-[3px] items-center", children: [
|
|
29369
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-[5px] h-[5px] rounded-full t-bg-accent-soft animate-bounce
|
|
29370
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-[5px] h-[5px] rounded-full t-bg-accent-soft animate-bounce
|
|
29371
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-[5px] h-[5px] rounded-full t-bg-accent-soft animate-bounce
|
|
29821
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1.5 mt-3 ml-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex gap-[3px] items-center", "aria-label": "Thinking", children: [
|
|
29822
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-[5px] h-[5px] rounded-full t-bg-accent-soft animate-bounce animation-delay-0" }),
|
|
29823
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-[5px] h-[5px] rounded-full t-bg-accent-soft animate-bounce animation-delay-150" }),
|
|
29824
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-[5px] h-[5px] rounded-full t-bg-accent-soft animate-bounce animation-delay-300" })
|
|
29372
29825
|
] }) });
|
|
29373
29826
|
}
|
|
29374
29827
|
function StreamingBubble() {
|
|
@@ -29454,6 +29907,13 @@ function ChatMessages() {
|
|
|
29454
29907
|
children: [
|
|
29455
29908
|
isLoadingHistory && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 16, className: "animate-spin t-text-muted" }) }),
|
|
29456
29909
|
messages.map((msg, i) => {
|
|
29910
|
+
if (msg.role === "system") {
|
|
29911
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 my-5 px-2", children: [
|
|
29912
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 h-px t-bg-elevated" }),
|
|
29913
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] t-text-muted shrink-0", children: msg.content }),
|
|
29914
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 h-px t-bg-elevated" })
|
|
29915
|
+
] }, msg.id);
|
|
29916
|
+
}
|
|
29457
29917
|
const prev = messages[i - 1];
|
|
29458
29918
|
const gap = prev && prev.role !== msg.role ? "mt-5" : "mt-3";
|
|
29459
29919
|
const toolEvents = msg.role === "assistant" ? turnToolEvents.get(msg.id) : void 0;
|
|
@@ -29482,7 +29942,7 @@ function ChatMessages() {
|
|
|
29482
29942
|
)
|
|
29483
29943
|
] });
|
|
29484
29944
|
}
|
|
29485
|
-
const api$
|
|
29945
|
+
const api$4 = window.api;
|
|
29486
29946
|
const typeIcons$1 = {
|
|
29487
29947
|
note: /* @__PURE__ */ jsxRuntimeExports.jsx(StickyNote, { size: 13, className: "t-text-warning" }),
|
|
29488
29948
|
paper: /* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { size: 13, className: "t-text-info" }),
|
|
@@ -29531,7 +29991,7 @@ function MentionPopover({ query, onSelect, onClose }) {
|
|
|
29531
29991
|
setLoading(true);
|
|
29532
29992
|
clearTimeout(debounceRef.current);
|
|
29533
29993
|
debounceRef.current = setTimeout(() => {
|
|
29534
|
-
api$
|
|
29994
|
+
api$4.getCandidates(query).then((result) => {
|
|
29535
29995
|
if (stale) return;
|
|
29536
29996
|
setCandidates(result || []);
|
|
29537
29997
|
setSelectedIdx(0);
|
|
@@ -29577,8 +30037,8 @@ function MentionPopover({ query, onSelect, onClose }) {
|
|
|
29577
30037
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
29578
30038
|
"div",
|
|
29579
30039
|
{
|
|
29580
|
-
className: "absolute z-50 w-[32rem] max-h-80 overflow-y-auto rounded-xl border t-border t-bg-surface shadow-xl",
|
|
29581
|
-
style: { bottom: "100%", left:
|
|
30040
|
+
className: "absolute z-50 w-[32rem] max-w-[calc(100vw-2rem)] max-h-80 overflow-y-auto rounded-xl border t-border t-bg-surface shadow-xl",
|
|
30041
|
+
style: { bottom: "100%", left: 0, marginBottom: 8 },
|
|
29582
30042
|
children: [
|
|
29583
30043
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-1.5 border-b t-border flex items-center gap-2 text-xs t-text-secondary", children: [
|
|
29584
30044
|
/* @__PURE__ */ jsxRuntimeExports.jsx(AtSign, { size: 11 }),
|
|
@@ -29671,7 +30131,7 @@ function CommandPopover({ query, commands, onSelect, onClose }) {
|
|
|
29671
30131
|
"div",
|
|
29672
30132
|
{
|
|
29673
30133
|
className: "absolute z-50 w-72 rounded-xl border t-border t-bg-surface shadow-xl",
|
|
29674
|
-
style: { bottom: "100%", left:
|
|
30134
|
+
style: { bottom: "100%", left: 0, marginBottom: 8 },
|
|
29675
30135
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-3 text-xs t-text-muted", children: [
|
|
29676
30136
|
'No matching commands for "/',
|
|
29677
30137
|
query,
|
|
@@ -29684,7 +30144,7 @@ function CommandPopover({ query, commands, onSelect, onClose }) {
|
|
|
29684
30144
|
"div",
|
|
29685
30145
|
{
|
|
29686
30146
|
className: "absolute z-50 w-80 max-h-64 overflow-y-auto rounded-xl border t-border t-bg-surface shadow-xl",
|
|
29687
|
-
style: { bottom: "100%", left:
|
|
30147
|
+
style: { bottom: "100%", left: 0, marginBottom: 8 },
|
|
29688
30148
|
children: [
|
|
29689
30149
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-2 border-b t-border flex items-center gap-2 text-xs t-text-secondary", children: [
|
|
29690
30150
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { size: 12 }),
|
|
@@ -29724,7 +30184,7 @@ const SLASH_COMMANDS = [
|
|
|
29724
30184
|
{ name: "/delete", description: "Delete an entity", args: "<id>" },
|
|
29725
30185
|
{ name: "/help", description: "Show available commands" }
|
|
29726
30186
|
];
|
|
29727
|
-
const api$
|
|
30187
|
+
const api$3 = window.api;
|
|
29728
30188
|
const ACCEPTED_IMAGE_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
|
|
29729
30189
|
const MAX_IMAGES = 5;
|
|
29730
30190
|
const ACCEPTED_DOC_EXTENSIONS = [".pdf", ".csv", ".md", ".txt", ".json", ".xml", ".html", ".docx"];
|
|
@@ -29845,7 +30305,7 @@ function ChatInput() {
|
|
|
29845
30305
|
const dataUrl = reader.result;
|
|
29846
30306
|
const base64 = dataUrl.split(",")[1];
|
|
29847
30307
|
try {
|
|
29848
|
-
const result = await api$
|
|
30308
|
+
const result = await api$3.convertFileToText(file.name, base64);
|
|
29849
30309
|
if (result?.success && result.content) {
|
|
29850
30310
|
setPendingFiles((p) => p.map(
|
|
29851
30311
|
(f) => f.name === file.name ? { ...f, content: result.content, loading: false } : f
|
|
@@ -29962,19 +30422,19 @@ ${fileBlocks}`;
|
|
|
29962
30422
|
try {
|
|
29963
30423
|
switch (cmd) {
|
|
29964
30424
|
case "/notes": {
|
|
29965
|
-
const notes = await api$
|
|
30425
|
+
const notes = await api$3.listNotes();
|
|
29966
30426
|
result = notes?.length ? `**Notes (${notes.length}):**
|
|
29967
30427
|
` + notes.map((n) => `- ${n.title} \`${n.id.slice(0, 8)}\``).join("\n") : "No notes yet.";
|
|
29968
30428
|
break;
|
|
29969
30429
|
}
|
|
29970
30430
|
case "/papers": {
|
|
29971
|
-
const papers = await api$
|
|
30431
|
+
const papers = await api$3.listLiterature();
|
|
29972
30432
|
result = papers?.length ? `**Papers (${papers.length}):**
|
|
29973
30433
|
` + papers.map((p) => `- ${p.title} \`${p.citeKey}\``).join("\n") : "No papers yet.";
|
|
29974
30434
|
break;
|
|
29975
30435
|
}
|
|
29976
30436
|
case "/data": {
|
|
29977
|
-
const data = await api$
|
|
30437
|
+
const data = await api$3.listData();
|
|
29978
30438
|
result = data?.length ? `**Data (${data.length}):**
|
|
29979
30439
|
` + data.map((d) => `- ${d.name} \`${d.id.slice(0, 8)}\``).join("\n") : "No data attachments yet.";
|
|
29980
30440
|
break;
|
|
@@ -29984,7 +30444,7 @@ ${fileBlocks}`;
|
|
|
29984
30444
|
result = "Usage: `/search <query>`";
|
|
29985
30445
|
break;
|
|
29986
30446
|
}
|
|
29987
|
-
const results = await api$
|
|
30447
|
+
const results = await api$3.search(rest);
|
|
29988
30448
|
result = results?.length ? `**Search results for "${rest}":**
|
|
29989
30449
|
` + results.map((r) => `- [${r.type}] ${r.title} \`${r.id.slice(0, 8)}\``).join("\n") : `No results for "${rest}".`;
|
|
29990
30450
|
break;
|
|
@@ -29994,7 +30454,7 @@ ${fileBlocks}`;
|
|
|
29994
30454
|
result = "Usage: `/note <title>`";
|
|
29995
30455
|
break;
|
|
29996
30456
|
}
|
|
29997
|
-
const r = await api$
|
|
30457
|
+
const r = await api$3.artifactCreate({ type: "note", title: rest, content: "" });
|
|
29998
30458
|
result = r?.success ? `Note saved: **${rest}**` : `Failed: ${r?.error || "unknown error"}`;
|
|
29999
30459
|
refreshEntities();
|
|
30000
30460
|
break;
|
|
@@ -30017,7 +30477,7 @@ ${fileBlocks}`;
|
|
|
30017
30477
|
const bibtex = flags.bibtex || `@article{${citeKey},
|
|
30018
30478
|
title = {${cleaned}}
|
|
30019
30479
|
}`;
|
|
30020
|
-
const r = await api$
|
|
30480
|
+
const r = await api$3.artifactCreate({
|
|
30021
30481
|
type: "paper",
|
|
30022
30482
|
title: cleaned,
|
|
30023
30483
|
authors,
|
|
@@ -30044,7 +30504,7 @@ ${fileBlocks}`;
|
|
|
30044
30504
|
result = "Usage: `/save-data <name> --path <file>`";
|
|
30045
30505
|
break;
|
|
30046
30506
|
}
|
|
30047
|
-
const r = await api$
|
|
30507
|
+
const r = await api$3.artifactCreate({
|
|
30048
30508
|
type: "data",
|
|
30049
30509
|
title: cleaned,
|
|
30050
30510
|
filePath: flags.path,
|
|
@@ -30055,7 +30515,7 @@ ${fileBlocks}`;
|
|
|
30055
30515
|
break;
|
|
30056
30516
|
}
|
|
30057
30517
|
case "/summary": {
|
|
30058
|
-
const summaryResult = await api$
|
|
30518
|
+
const summaryResult = await api$3.sessionSummaryGet();
|
|
30059
30519
|
if (!summaryResult?.success || !summaryResult?.summary) {
|
|
30060
30520
|
result = "No session summary available yet.";
|
|
30061
30521
|
break;
|
|
@@ -30082,7 +30542,7 @@ ${s15.openQuestions.map((q2) => `- ${q2}`).join("\n")}`;
|
|
|
30082
30542
|
result = "Usage: `/delete <id>`";
|
|
30083
30543
|
break;
|
|
30084
30544
|
}
|
|
30085
|
-
const r = await api$
|
|
30545
|
+
const r = await api$3.deleteEntity(rest);
|
|
30086
30546
|
result = r?.success ? `Deleted \`${rest}\`` : `Failed: ${r?.error || "not found"}`;
|
|
30087
30547
|
refreshEntities();
|
|
30088
30548
|
break;
|
|
@@ -30270,6 +30730,7 @@ ${s15.openQuestions.map((q2) => `- ${q2}`).join("\n")}`;
|
|
|
30270
30730
|
onKeyDown: handleKeyDown,
|
|
30271
30731
|
onPaste: handlePaste,
|
|
30272
30732
|
placeholder: "Ask anything, attach files, or type /commands...",
|
|
30733
|
+
"aria-label": "Chat message input",
|
|
30273
30734
|
rows: 1,
|
|
30274
30735
|
className: "flex-1 bg-transparent text-sm t-text placeholder:t-text-muted resize-none outline-none"
|
|
30275
30736
|
}
|
|
@@ -30461,7 +30922,7 @@ function PaperRow({
|
|
|
30461
30922
|
] })
|
|
30462
30923
|
] });
|
|
30463
30924
|
}
|
|
30464
|
-
function CoverageBar({ papers }) {
|
|
30925
|
+
function CoverageBar$1({ papers }) {
|
|
30465
30926
|
const topicCounts = reactExports.useMemo(() => {
|
|
30466
30927
|
const counts = /* @__PURE__ */ new Map();
|
|
30467
30928
|
for (const p of papers) {
|
|
@@ -30493,16 +30954,15 @@ function CoverageBar({ papers }) {
|
|
|
30493
30954
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 max-w-48", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1.5 rounded-full t-bg-elevated overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30494
30955
|
"div",
|
|
30495
30956
|
{
|
|
30496
|
-
className: "h-full rounded-full",
|
|
30957
|
+
className: "h-full rounded-full t-gradient-accent-h",
|
|
30497
30958
|
style: {
|
|
30498
|
-
width: `${Math.min(100, highRelevance / Math.max(papers.length, 1) * 100)}
|
|
30499
|
-
background: "linear-gradient(90deg, var(--color-accent), var(--color-accent-2))"
|
|
30959
|
+
width: `${Math.min(100, highRelevance / Math.max(papers.length, 1) * 100)}%`
|
|
30500
30960
|
}
|
|
30501
30961
|
}
|
|
30502
30962
|
) }) })
|
|
30503
30963
|
] });
|
|
30504
30964
|
}
|
|
30505
|
-
function FilterBar() {
|
|
30965
|
+
function FilterBar$1() {
|
|
30506
30966
|
const filter = useUIStore((s15) => s15.literatureFilter);
|
|
30507
30967
|
const setFilter = useUIStore((s15) => s15.setLiteratureFilter);
|
|
30508
30968
|
const [showFilters, setShowFilters] = reactExports.useState(false);
|
|
@@ -30638,7 +31098,7 @@ function LiteratureView() {
|
|
|
30638
31098
|
}, [papers, filter]);
|
|
30639
31099
|
const hasTopics = papers.some((p) => p.subTopic);
|
|
30640
31100
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col min-h-0", children: [
|
|
30641
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(FilterBar, {}),
|
|
31101
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FilterBar$1, {}),
|
|
30642
31102
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex min-h-0", children: [
|
|
30643
31103
|
hasTopics && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30644
31104
|
TopicTree,
|
|
@@ -30713,18 +31173,360 @@ function LiteratureView() {
|
|
|
30713
31173
|
)) })
|
|
30714
31174
|
] })
|
|
30715
31175
|
] }),
|
|
30716
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CoverageBar, { papers: filtered })
|
|
31176
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CoverageBar$1, { papers: filtered })
|
|
31177
|
+
] });
|
|
31178
|
+
}
|
|
31179
|
+
function formatDuration(seconds) {
|
|
31180
|
+
if (!seconds || seconds < 0) return "--";
|
|
31181
|
+
if (seconds < 60) return `${Math.round(seconds)}s`;
|
|
31182
|
+
if (seconds < 3600) {
|
|
31183
|
+
const m2 = Math.floor(seconds / 60);
|
|
31184
|
+
const s15 = Math.round(seconds % 60);
|
|
31185
|
+
return s15 > 0 ? `${m2}m ${s15}s` : `${m2}m`;
|
|
31186
|
+
}
|
|
31187
|
+
const h2 = Math.floor(seconds / 3600);
|
|
31188
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
31189
|
+
return `${h2}h ${m}m`;
|
|
31190
|
+
}
|
|
31191
|
+
function formatBytes(bytes) {
|
|
31192
|
+
if (!bytes || bytes < 0) return "--";
|
|
31193
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
31194
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
31195
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
31196
|
+
}
|
|
31197
|
+
function timeAgo(iso) {
|
|
31198
|
+
const diff = Date.now() - new Date(iso).getTime();
|
|
31199
|
+
if (diff < 6e4) return "just now";
|
|
31200
|
+
if (diff < 36e5) return `${Math.floor(diff / 6e4)}m ago`;
|
|
31201
|
+
if (diff < 864e5) return `${Math.floor(diff / 36e5)}h ago`;
|
|
31202
|
+
return `${Math.floor(diff / 864e5)}d ago`;
|
|
31203
|
+
}
|
|
31204
|
+
const STATUS_LABELS = {
|
|
31205
|
+
running: "Running",
|
|
31206
|
+
stalled: "Stalled",
|
|
31207
|
+
completed: "Completed",
|
|
31208
|
+
failed: "Failed",
|
|
31209
|
+
timed_out: "Timed out",
|
|
31210
|
+
cancelled: "Cancelled"
|
|
31211
|
+
};
|
|
31212
|
+
function StatusDot({ status }) {
|
|
31213
|
+
const isActive = status === "running";
|
|
31214
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `inline-block w-1.5 h-1.5 rounded-full shrink-0 ${isActive ? "bg-[var(--color-accent)]" : "t-bg-elevated"}`, style: isActive ? {} : { opacity: 0.8 } });
|
|
31215
|
+
}
|
|
31216
|
+
function ProgressBar({ percentage }) {
|
|
31217
|
+
const value = Math.min(100, Math.max(0, percentage || 0));
|
|
31218
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1 rounded-full t-bg-elevated overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31219
|
+
"div",
|
|
31220
|
+
{
|
|
31221
|
+
className: "h-full rounded-full transition-all duration-700 t-gradient-accent-h",
|
|
31222
|
+
style: { width: `${value}%` }
|
|
31223
|
+
}
|
|
31224
|
+
) });
|
|
31225
|
+
}
|
|
31226
|
+
function RunRow({
|
|
31227
|
+
run,
|
|
31228
|
+
expanded,
|
|
31229
|
+
onToggle
|
|
31230
|
+
}) {
|
|
31231
|
+
const isActive = run.status === "running" || run.status === "stalled";
|
|
31232
|
+
const hasProgress = run.progress?.percentage !== void 0;
|
|
31233
|
+
const setCenterView = useUIStore((s15) => s15.setCenterView);
|
|
31234
|
+
const sendToChat = (text2) => {
|
|
31235
|
+
setCenterView("chat");
|
|
31236
|
+
setTimeout(() => {
|
|
31237
|
+
const inputEl = document.querySelector("[data-chat-input]");
|
|
31238
|
+
if (inputEl) {
|
|
31239
|
+
inputEl.value = text2;
|
|
31240
|
+
inputEl.focus();
|
|
31241
|
+
inputEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
31242
|
+
}
|
|
31243
|
+
}, 100);
|
|
31244
|
+
};
|
|
31245
|
+
const hasMetrics = run.progress?.metrics && Object.keys(run.progress.metrics).length > 0;
|
|
31246
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b t-border last:border-b-0", children: [
|
|
31247
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
31248
|
+
"div",
|
|
31249
|
+
{
|
|
31250
|
+
className: "flex items-center gap-3 px-3 py-2 hover:bg-[var(--color-accent-soft)]/5 transition-colors cursor-pointer",
|
|
31251
|
+
onClick: onToggle,
|
|
31252
|
+
children: [
|
|
31253
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "shrink-0 t-text-muted", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 14 }) }),
|
|
31254
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(StatusDot, { status: run.status }),
|
|
31255
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
31256
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[13px] t-text font-medium truncate leading-tight font-mono", children: run.command }),
|
|
31257
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[11px] t-text-muted truncate mt-0.5", children: [
|
|
31258
|
+
run.runId,
|
|
31259
|
+
run.status !== "running" && run.status !== "stalled" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
31260
|
+
" · ",
|
|
31261
|
+
STATUS_LABELS[run.status] ?? run.status
|
|
31262
|
+
] }),
|
|
31263
|
+
run.stalled && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
31264
|
+
" · ",
|
|
31265
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-accent-soft", children: "stalled — no output for a while" })
|
|
31266
|
+
] }),
|
|
31267
|
+
run.failure && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
31268
|
+
" · ",
|
|
31269
|
+
run.failure.code
|
|
31270
|
+
] }),
|
|
31271
|
+
run.parentRunId && /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: " · retry" })
|
|
31272
|
+
] })
|
|
31273
|
+
] }),
|
|
31274
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 text-[11px] t-text-muted tabular-nums w-14 text-right", children: formatDuration(run.elapsedSeconds) }),
|
|
31275
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 text-[11px] t-text-muted w-14 text-right", children: isActive ? run.currentPhase : run.startedAt ? timeAgo(run.startedAt) : "--" })
|
|
31276
|
+
]
|
|
31277
|
+
}
|
|
31278
|
+
),
|
|
31279
|
+
isActive && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-10 pb-1.5", children: [
|
|
31280
|
+
hasProgress ? /* @__PURE__ */ jsxRuntimeExports.jsx(ProgressBar, { percentage: run.progress.percentage }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1 rounded-full t-bg-elevated overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full w-1/3 rounded-full animate-pulse t-gradient-accent-h opacity-30" }) }),
|
|
31281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mt-1 text-[10px] t-text-muted", children: [
|
|
31282
|
+
hasProgress && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31283
|
+
run.progress.percentage,
|
|
31284
|
+
"%"
|
|
31285
|
+
] }),
|
|
31286
|
+
run.progress?.currentStep !== void 0 && run.progress?.totalSteps !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31287
|
+
"Step ",
|
|
31288
|
+
run.progress.currentStep,
|
|
31289
|
+
"/",
|
|
31290
|
+
run.progress.totalSteps
|
|
31291
|
+
] }),
|
|
31292
|
+
run.progress?.phase && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: run.progress.phase }),
|
|
31293
|
+
run.progress?.etaSeconds !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31294
|
+
"ETA ",
|
|
31295
|
+
formatDuration(run.progress.etaSeconds)
|
|
31296
|
+
] }),
|
|
31297
|
+
run.startedAt && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31298
|
+
"started ",
|
|
31299
|
+
timeAgo(run.startedAt)
|
|
31300
|
+
] }),
|
|
31301
|
+
run.outputLines > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31302
|
+
run.outputLines,
|
|
31303
|
+
" lines"
|
|
31304
|
+
] })
|
|
31305
|
+
] }),
|
|
31306
|
+
hasMetrics && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5", children: Object.entries(run.progress.metrics).map(([key, val]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-1.5 py-0.5 text-[10px] rounded t-bg-elevated t-text-secondary font-mono", children: [
|
|
31307
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-muted", children: key }),
|
|
31308
|
+
" ",
|
|
31309
|
+
typeof val === "number" ? val < 0.01 ? val.toExponential(2) : val.toFixed(4) : val
|
|
31310
|
+
] }, key)) })
|
|
31311
|
+
] }),
|
|
31312
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-10 pb-3 space-y-2", children: [
|
|
31313
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
|
|
31314
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-1.5 py-0.5 text-[10px] rounded t-bg-elevated t-text-muted", children: run.sandbox }),
|
|
31315
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-1.5 py-0.5 text-[10px] rounded t-bg-elevated t-text-muted", children: run.weight }),
|
|
31316
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-1.5 py-0.5 text-[10px] rounded t-bg-elevated t-text-muted", children: [
|
|
31317
|
+
formatBytes(run.outputBytes),
|
|
31318
|
+
" · ",
|
|
31319
|
+
run.outputLines,
|
|
31320
|
+
" lines"
|
|
31321
|
+
] }),
|
|
31322
|
+
run.exitCode !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-1.5 py-0.5 text-[10px] rounded t-bg-elevated t-text-muted", children: [
|
|
31323
|
+
"exit ",
|
|
31324
|
+
run.exitCode
|
|
31325
|
+
] }),
|
|
31326
|
+
run.startedAt && !isActive && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-1.5 py-0.5 text-[10px] rounded t-bg-elevated t-text-muted", children: [
|
|
31327
|
+
"started ",
|
|
31328
|
+
timeAgo(run.startedAt)
|
|
31329
|
+
] })
|
|
31330
|
+
] }),
|
|
31331
|
+
!isActive && hasMetrics && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1.5", children: Object.entries(run.progress.metrics).map(([key, val]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-1.5 py-0.5 text-[10px] rounded t-bg-elevated t-text-secondary font-mono", children: [
|
|
31332
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-muted", children: key }),
|
|
31333
|
+
" ",
|
|
31334
|
+
typeof val === "number" ? val < 0.01 ? val.toExponential(2) : val.toFixed(4) : val
|
|
31335
|
+
] }, key)) }),
|
|
31336
|
+
run.failure && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs t-text-secondary leading-relaxed", children: [
|
|
31337
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-medium", children: [
|
|
31338
|
+
run.failure.code,
|
|
31339
|
+
": ",
|
|
31340
|
+
run.failure.message
|
|
31341
|
+
] }),
|
|
31342
|
+
run.failure.suggestions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "mt-1 space-y-0.5", children: run.failure.suggestions.map((s15, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "flex items-start gap-1.5 t-text-muted", children: [
|
|
31343
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 mt-1.5 w-1 h-1 rounded-full t-bg-elevated" }),
|
|
31344
|
+
s15
|
|
31345
|
+
] }, i)) })
|
|
31346
|
+
] }),
|
|
31347
|
+
run.parentRunId && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] t-text-muted", children: [
|
|
31348
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 10 }),
|
|
31349
|
+
"Retry of ",
|
|
31350
|
+
run.parentRunId
|
|
31351
|
+
] }),
|
|
31352
|
+
run.outputTail && /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "p-2 rounded t-bg-elevated text-[10px] t-text-secondary font-mono overflow-x-auto max-h-40 overflow-y-auto whitespace-pre-wrap leading-relaxed", children: run.outputTail.slice(-2048) }),
|
|
31353
|
+
run.failure?.retryable && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31354
|
+
"button",
|
|
31355
|
+
{
|
|
31356
|
+
onClick: (e) => {
|
|
31357
|
+
e.stopPropagation();
|
|
31358
|
+
sendToChat(`Compute run ${run.runId} failed with ${run.failure.code}. Please review the error and fix the code, then retry.`);
|
|
31359
|
+
},
|
|
31360
|
+
className: "text-[10px] t-text-accent hover:underline",
|
|
31361
|
+
children: "Fix & retry in chat"
|
|
31362
|
+
}
|
|
31363
|
+
)
|
|
31364
|
+
] })
|
|
31365
|
+
] });
|
|
31366
|
+
}
|
|
31367
|
+
function FilterBar({
|
|
31368
|
+
search: search2,
|
|
31369
|
+
onSearchChange
|
|
31370
|
+
}) {
|
|
31371
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 py-2 border-b t-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
|
|
31372
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Search, { size: 13, className: "absolute left-2.5 top-1/2 -translate-y-1/2 t-text-muted" }),
|
|
31373
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31374
|
+
"input",
|
|
31375
|
+
{
|
|
31376
|
+
type: "text",
|
|
31377
|
+
value: search2,
|
|
31378
|
+
onChange: (e) => onSearchChange(e.target.value),
|
|
31379
|
+
placeholder: "Search runs by command or ID...",
|
|
31380
|
+
className: "w-full pl-8 pr-3 py-1.5 text-xs rounded-lg border t-border t-bg-surface t-text focus:outline-none focus:border-[var(--color-accent-soft)]"
|
|
31381
|
+
}
|
|
31382
|
+
),
|
|
31383
|
+
search2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31384
|
+
"button",
|
|
31385
|
+
{
|
|
31386
|
+
onClick: () => onSearchChange(""),
|
|
31387
|
+
className: "absolute right-2 top-1/2 -translate-y-1/2 t-text-muted hover:t-text",
|
|
31388
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { size: 12 })
|
|
31389
|
+
}
|
|
31390
|
+
)
|
|
31391
|
+
] }) });
|
|
31392
|
+
}
|
|
31393
|
+
function CoverageBar({ runs }) {
|
|
31394
|
+
const completed = runs.filter((r) => r.status === "completed").length;
|
|
31395
|
+
const failed = runs.filter((r) => ["failed", "timed_out"].includes(r.status)).length;
|
|
31396
|
+
const total = runs.length;
|
|
31397
|
+
const successRate = total > 0 ? completed / total : 0;
|
|
31398
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4 px-4 py-2 border-t t-border t-bg-surface text-[11px] t-text-muted", children: [
|
|
31399
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31400
|
+
total,
|
|
31401
|
+
" runs"
|
|
31402
|
+
] }),
|
|
31403
|
+
completed > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31404
|
+
completed,
|
|
31405
|
+
" completed"
|
|
31406
|
+
] }),
|
|
31407
|
+
failed > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31408
|
+
failed,
|
|
31409
|
+
" failed"
|
|
31410
|
+
] }),
|
|
31411
|
+
total > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
31412
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 max-w-48", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1.5 rounded-full t-bg-elevated overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31413
|
+
"div",
|
|
31414
|
+
{
|
|
31415
|
+
className: "h-full rounded-full t-gradient-accent-h",
|
|
31416
|
+
style: { width: `${successRate * 100}%` }
|
|
31417
|
+
}
|
|
31418
|
+
) }) }),
|
|
31419
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
31420
|
+
Math.round(successRate * 100),
|
|
31421
|
+
"% success"
|
|
31422
|
+
] })
|
|
31423
|
+
] })
|
|
31424
|
+
] });
|
|
31425
|
+
}
|
|
31426
|
+
function EmptyState() {
|
|
31427
|
+
const environment = useComputeStore((s15) => s15.environment);
|
|
31428
|
+
const setCenterView = useUIStore((s15) => s15.setCenterView);
|
|
31429
|
+
const goToChat = (text2) => {
|
|
31430
|
+
setCenterView("chat");
|
|
31431
|
+
setTimeout(() => {
|
|
31432
|
+
const inputEl = document.querySelector("[data-chat-input]");
|
|
31433
|
+
if (inputEl) {
|
|
31434
|
+
inputEl.value = text2;
|
|
31435
|
+
inputEl.focus();
|
|
31436
|
+
inputEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
31437
|
+
}
|
|
31438
|
+
}, 100);
|
|
31439
|
+
};
|
|
31440
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center px-8", children: [
|
|
31441
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Cpu, { size: 32, className: "t-text-muted mb-3 opacity-30" }),
|
|
31442
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm t-text font-medium mb-1", children: "Your compute environment is ready" }),
|
|
31443
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text-muted max-w-sm leading-relaxed mb-4", children: "Ask the agent to run scripts, train models, or process data. Code executes in a sandboxed environment with progress tracking and failure analysis." }),
|
|
31444
|
+
environment && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-2.5 rounded-lg t-bg-elevated text-[11px] t-text-secondary mb-5", children: [
|
|
31445
|
+
environment.gpu || `${environment.os} ${environment.arch}`,
|
|
31446
|
+
" · ",
|
|
31447
|
+
Math.round(environment.totalMemoryMb / 1024),
|
|
31448
|
+
" GB",
|
|
31449
|
+
environment.mlxAvailable && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
31450
|
+
" · ",
|
|
31451
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-accent", children: "MLX" })
|
|
31452
|
+
] }),
|
|
31453
|
+
environment.sandbox === "docker" && /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: " · Docker" })
|
|
31454
|
+
] }),
|
|
31455
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1.5 w-full max-w-sm", children: [
|
|
31456
|
+
"Train a model on my dataset",
|
|
31457
|
+
"Run my analysis script",
|
|
31458
|
+
"Process and clean this data"
|
|
31459
|
+
].map((prompt) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
31460
|
+
"button",
|
|
31461
|
+
{
|
|
31462
|
+
onClick: () => goToChat(prompt),
|
|
31463
|
+
className: "w-full flex items-center justify-between px-3 py-2 rounded-lg border t-border-subtle hover:bg-[var(--color-accent-soft)]/5 transition-colors text-left",
|
|
31464
|
+
children: [
|
|
31465
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs t-text-secondary", children: [
|
|
31466
|
+
'"',
|
|
31467
|
+
prompt,
|
|
31468
|
+
'"'
|
|
31469
|
+
] }),
|
|
31470
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 12, className: "t-text-muted" })
|
|
31471
|
+
]
|
|
31472
|
+
},
|
|
31473
|
+
prompt
|
|
31474
|
+
)) })
|
|
31475
|
+
] });
|
|
31476
|
+
}
|
|
31477
|
+
function ComputeView() {
|
|
31478
|
+
const activeRuns = useActiveRuns();
|
|
31479
|
+
const recentRuns = useRecentRuns();
|
|
31480
|
+
const [expandedId, setExpandedId] = reactExports.useState(null);
|
|
31481
|
+
const [search2, setSearch] = reactExports.useState("");
|
|
31482
|
+
const allRuns = reactExports.useMemo(() => [...activeRuns, ...recentRuns], [activeRuns, recentRuns]);
|
|
31483
|
+
const filtered = reactExports.useMemo(() => {
|
|
31484
|
+
if (!search2.trim()) return allRuns;
|
|
31485
|
+
const q2 = search2.toLowerCase();
|
|
31486
|
+
return allRuns.filter(
|
|
31487
|
+
(r) => r.command.toLowerCase().includes(q2) || r.runId.toLowerCase().includes(q2)
|
|
31488
|
+
);
|
|
31489
|
+
}, [allRuns, search2]);
|
|
31490
|
+
const isEmpty = allRuns.length === 0;
|
|
31491
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col min-h-0", children: [
|
|
31492
|
+
!isEmpty && /* @__PURE__ */ jsxRuntimeExports.jsx(FilterBar, { search: search2, onSearchChange: setSearch }),
|
|
31493
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: isEmpty ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyState, {}) : filtered.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center px-8", children: [
|
|
31494
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Cpu, { size: 32, className: "t-text-muted mb-3 opacity-40" }),
|
|
31495
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm t-text-muted", children: "No runs match your search." })
|
|
31496
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
31497
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 px-3 py-1.5 border-b t-border t-bg-surface", children: [
|
|
31498
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5" }),
|
|
31499
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-1.5" }),
|
|
31500
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 text-[10px] uppercase tracking-wider font-medium t-text-muted", children: "Command" }),
|
|
31501
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-14 text-right text-[10px] uppercase tracking-wider font-medium t-text-muted", children: "Duration" }),
|
|
31502
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-14 text-right text-[10px] uppercase tracking-wider font-medium t-text-muted", children: "Phase" })
|
|
31503
|
+
] }),
|
|
31504
|
+
filtered.map((run) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31505
|
+
RunRow,
|
|
31506
|
+
{
|
|
31507
|
+
run,
|
|
31508
|
+
expanded: expandedId === run.runId,
|
|
31509
|
+
onToggle: () => setExpandedId(expandedId === run.runId ? null : run.runId)
|
|
31510
|
+
},
|
|
31511
|
+
run.runId
|
|
31512
|
+
))
|
|
31513
|
+
] }) }),
|
|
31514
|
+
!isEmpty && /* @__PURE__ */ jsxRuntimeExports.jsx(CoverageBar, { runs: allRuns })
|
|
30717
31515
|
] });
|
|
30718
31516
|
}
|
|
31517
|
+
const api$2 = window.api;
|
|
31518
|
+
const computeEnabled = api$2?.isComputeEnabled?.() ?? false;
|
|
30719
31519
|
const viewTabs = [
|
|
30720
31520
|
{ key: "chat", label: "Chat", icon: MessageSquare, shortcut: "⌘1" },
|
|
30721
|
-
{ key: "literature", label: "Literature", icon: BookOpen, shortcut: "⌘2" }
|
|
31521
|
+
{ key: "literature", label: "Literature", icon: BookOpen, shortcut: "⌘2" },
|
|
31522
|
+
...computeEnabled ? [{ key: "compute", label: "Compute", icon: Cpu, shortcut: "⌘3" }] : []
|
|
30722
31523
|
];
|
|
30723
31524
|
function ViewSwitcher() {
|
|
30724
31525
|
const centerView = useUIStore((s15) => s15.centerView);
|
|
30725
31526
|
const setCenterView = useUIStore((s15) => s15.setCenterView);
|
|
30726
31527
|
const paperCount = useEntityStore((s15) => s15.papers.length);
|
|
30727
|
-
|
|
31528
|
+
const activeComputeRuns = useActiveRunCount();
|
|
31529
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("nav", { "aria-label": "View switcher", className: "flex items-center gap-0.5 px-4 pt-10 pb-1", children: viewTabs.map(({ key, label, icon: Icon2, shortcut }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30728
31530
|
"button",
|
|
30729
31531
|
{
|
|
30730
31532
|
onClick: () => setCenterView(key),
|
|
@@ -30733,7 +31535,9 @@ function ViewSwitcher() {
|
|
|
30733
31535
|
children: [
|
|
30734
31536
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { size: 13 }),
|
|
30735
31537
|
label,
|
|
30736
|
-
key === "literature" && paperCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-0.5 px-1 py-px text-[9px] rounded-full t-bg-elevated t-text-muted tabular-nums", children: paperCount })
|
|
31538
|
+
key === "literature" && paperCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-0.5 px-1 py-px text-[9px] rounded-full t-bg-elevated t-text-muted tabular-nums", children: paperCount }),
|
|
31539
|
+
key === "compute" && activeComputeRuns > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-0.5 px-1 py-px text-[9px] rounded-full bg-[var(--color-accent-soft)]/10 t-text-accent tabular-nums", children: activeComputeRuns }),
|
|
31540
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] t-text-muted opacity-40 ml-0.5", children: shortcut })
|
|
30737
31541
|
]
|
|
30738
31542
|
},
|
|
30739
31543
|
key
|
|
@@ -30745,12 +31549,18 @@ function CenterPanel() {
|
|
|
30745
31549
|
const messages = useChatStore((s15) => s15.messages);
|
|
30746
31550
|
const showHero = isIdle && messages.length === 0;
|
|
30747
31551
|
if (centerView === "literature") {
|
|
30748
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { className: "flex-1 flex flex-col min-w-0", children: [
|
|
31552
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { id: "main-content", className: "flex-1 flex flex-col min-w-0", children: [
|
|
30749
31553
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewSwitcher, {}),
|
|
30750
31554
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LiteratureView, {})
|
|
30751
31555
|
] });
|
|
30752
31556
|
}
|
|
30753
|
-
|
|
31557
|
+
if (centerView === "compute") {
|
|
31558
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { id: "main-content", className: "flex-1 flex flex-col min-w-0", children: [
|
|
31559
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewSwitcher, {}),
|
|
31560
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ComputeView, {})
|
|
31561
|
+
] });
|
|
31562
|
+
}
|
|
31563
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { id: "main-content", className: "flex-1 flex flex-col min-w-0", children: [
|
|
30754
31564
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewSwitcher, {}),
|
|
30755
31565
|
showHero ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(HeroIdle, {}) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 px-6 pt-4 pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto h-full", style: { maxWidth: "48rem" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChatMessages, {}) }) }),
|
|
30756
31566
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-6 pb-5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto", style: { maxWidth: "48rem" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChatInput, {}) }) })
|
|
@@ -30758,7 +31568,7 @@ function CenterPanel() {
|
|
|
30758
31568
|
}
|
|
30759
31569
|
const remarkPlugins = [remarkGfm];
|
|
30760
31570
|
const LazyMilkdownMarkdownEditor = reactExports.lazy(async () => {
|
|
30761
|
-
const mod = await __vitePreload(() => import("./MilkdownMarkdownEditor-
|
|
31571
|
+
const mod = await __vitePreload(() => import("./MilkdownMarkdownEditor-jaF-aGPn.js").then((n) => n.bL), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
|
|
30762
31572
|
return { default: mod.MilkdownMarkdownEditor };
|
|
30763
31573
|
});
|
|
30764
31574
|
const typeIcons = {
|
|
@@ -31383,7 +32193,7 @@ function StatusBar() {
|
|
|
31383
32193
|
const hasSkills = activeSkills.length > 0;
|
|
31384
32194
|
const hasRunUsage = runTokens > 0;
|
|
31385
32195
|
const hasProjectUsage = allTimeTokens > 0;
|
|
31386
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-7 flex items-center px-4 gap-5 border-t t-border t-bg-surface text-[11px] t-text-
|
|
32196
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-7 flex items-center px-4 gap-5 border-t t-border t-bg-surface text-[11px] t-text-secondary select-none shrink-0", children: [
|
|
31387
32197
|
hasSkills && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 overflow-hidden", children: activeSkills.map((name2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 px-1.5 py-0.5 rounded t-bg-accent/10 t-text-accent whitespace-nowrap", children: [
|
|
31388
32198
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px]", children: "⚡" }),
|
|
31389
32199
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: name2 })
|
|
@@ -40007,22 +40817,17 @@ function TerminalPanel() {
|
|
|
40007
40817
|
};
|
|
40008
40818
|
reactExports.useEffect(() => {
|
|
40009
40819
|
if (!termRef.current) return;
|
|
40010
|
-
const
|
|
40820
|
+
const cs2 = getComputedStyle(document.documentElement);
|
|
40011
40821
|
const term = new Dl({
|
|
40012
40822
|
fontSize: 13,
|
|
40013
40823
|
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
|
40014
40824
|
cursorBlink: true,
|
|
40015
40825
|
allowProposedApi: true,
|
|
40016
|
-
theme:
|
|
40017
|
-
background: "
|
|
40018
|
-
foreground: "
|
|
40019
|
-
cursor: "
|
|
40020
|
-
selectionBackground: "
|
|
40021
|
-
} : {
|
|
40022
|
-
background: "#fafafa",
|
|
40023
|
-
foreground: "#1a1a1a",
|
|
40024
|
-
cursor: "#1a1a1a",
|
|
40025
|
-
selectionBackground: "#c0d0e0"
|
|
40826
|
+
theme: {
|
|
40827
|
+
background: cs2.getPropertyValue("--color-bg-base").trim(),
|
|
40828
|
+
foreground: cs2.getPropertyValue("--color-text").trim(),
|
|
40829
|
+
cursor: cs2.getPropertyValue("--color-text").trim(),
|
|
40830
|
+
selectionBackground: cs2.getPropertyValue("--color-bg-elevated").trim()
|
|
40026
40831
|
}
|
|
40027
40832
|
});
|
|
40028
40833
|
const fit = new o();
|
|
@@ -40079,17 +40884,12 @@ function TerminalPanel() {
|
|
|
40079
40884
|
reactExports.useEffect(() => {
|
|
40080
40885
|
const term = xtermRef.current;
|
|
40081
40886
|
if (!term) return;
|
|
40082
|
-
const
|
|
40083
|
-
term.options.theme =
|
|
40084
|
-
background: "
|
|
40085
|
-
foreground: "
|
|
40086
|
-
cursor: "
|
|
40087
|
-
selectionBackground: "
|
|
40088
|
-
} : {
|
|
40089
|
-
background: "#fafafa",
|
|
40090
|
-
foreground: "#1a1a1a",
|
|
40091
|
-
cursor: "#1a1a1a",
|
|
40092
|
-
selectionBackground: "#c0d0e0"
|
|
40887
|
+
const cs2 = getComputedStyle(document.documentElement);
|
|
40888
|
+
term.options.theme = {
|
|
40889
|
+
background: cs2.getPropertyValue("--color-bg-base").trim(),
|
|
40890
|
+
foreground: cs2.getPropertyValue("--color-text").trim(),
|
|
40891
|
+
cursor: cs2.getPropertyValue("--color-text").trim(),
|
|
40892
|
+
selectionBackground: cs2.getPropertyValue("--color-bg-elevated").trim()
|
|
40093
40893
|
};
|
|
40094
40894
|
}, [theme]);
|
|
40095
40895
|
reactExports.useEffect(() => {
|
|
@@ -40116,8 +40916,9 @@ function TerminalPanel() {
|
|
|
40116
40916
|
"button",
|
|
40117
40917
|
{
|
|
40118
40918
|
onClick: handleRestart,
|
|
40119
|
-
className: "p-
|
|
40919
|
+
className: "p-1 rounded t-text-muted hover:t-text-secondary t-bg-hover",
|
|
40120
40920
|
title: "Restart terminal",
|
|
40921
|
+
"aria-label": "Restart terminal",
|
|
40121
40922
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 12 })
|
|
40122
40923
|
}
|
|
40123
40924
|
),
|
|
@@ -40125,8 +40926,9 @@ function TerminalPanel() {
|
|
|
40125
40926
|
"button",
|
|
40126
40927
|
{
|
|
40127
40928
|
onClick: handleClose,
|
|
40128
|
-
className: "p-
|
|
40929
|
+
className: "p-1 rounded t-text-muted hover:t-text-secondary t-bg-hover",
|
|
40129
40930
|
title: "Close terminal",
|
|
40931
|
+
"aria-label": "Close terminal",
|
|
40130
40932
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { size: 12 })
|
|
40131
40933
|
}
|
|
40132
40934
|
)
|
|
@@ -40227,19 +41029,14 @@ function FolderGate({ onOpenSettings }) {
|
|
|
40227
41029
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
40228
41030
|
"div",
|
|
40229
41031
|
{
|
|
40230
|
-
className: "w-14 h-14 rounded-2xl flex items-center justify-center",
|
|
40231
|
-
style: {
|
|
40232
|
-
background: "linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-2) 100%)",
|
|
40233
|
-
boxShadow: "0 8px 32px var(--color-accent-2-muted)"
|
|
40234
|
-
},
|
|
41032
|
+
className: "w-14 h-14 rounded-2xl flex items-center justify-center t-gradient-accent t-gradient-accent-shadow-lg",
|
|
40235
41033
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-white text-xl font-bold tracking-tight", children: "P" })
|
|
40236
41034
|
}
|
|
40237
41035
|
),
|
|
40238
41036
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
40239
41037
|
"div",
|
|
40240
41038
|
{
|
|
40241
|
-
className: "absolute -inset-2 rounded-3xl opacity-15 blur-xl -z-10"
|
|
40242
|
-
style: { background: "linear-gradient(135deg, var(--color-accent), var(--color-accent-2))" }
|
|
41039
|
+
className: "absolute -inset-2 rounded-3xl opacity-15 blur-xl -z-10 t-gradient-accent"
|
|
40243
41040
|
}
|
|
40244
41041
|
)
|
|
40245
41042
|
] }),
|
|
@@ -40260,11 +41057,7 @@ function FolderGate({ onOpenSettings }) {
|
|
|
40260
41057
|
"button",
|
|
40261
41058
|
{
|
|
40262
41059
|
onClick: handlePick,
|
|
40263
|
-
className: "inline-flex items-center gap-2 px-5 py-2.5 rounded-lg text-white text-sm font-medium\n hover:opacity-90 transition-all duration-200",
|
|
40264
|
-
style: {
|
|
40265
|
-
background: "linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-2) 100%)",
|
|
40266
|
-
boxShadow: "0 4px 16px var(--color-accent-2-muted)"
|
|
40267
|
-
},
|
|
41060
|
+
className: "inline-flex items-center gap-2 px-5 py-2.5 rounded-lg text-white text-sm font-medium\n hover:opacity-90 transition-all duration-200 t-gradient-accent t-gradient-accent-shadow",
|
|
40268
41061
|
children: [
|
|
40269
41062
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { size: 16 }),
|
|
40270
41063
|
"Open Project Folder"
|
|
@@ -40423,6 +41216,19 @@ function App() {
|
|
|
40423
41216
|
const unsub6 = api.onEntityCreated(() => {
|
|
40424
41217
|
refreshEntities();
|
|
40425
41218
|
});
|
|
41219
|
+
if (api?.isComputeEnabled?.()) {
|
|
41220
|
+
api.probeComputeEnvironment?.().catch(() => {
|
|
41221
|
+
});
|
|
41222
|
+
}
|
|
41223
|
+
const unsubComputeUpdate = api.onComputeRunUpdate((event) => {
|
|
41224
|
+
useComputeStore.getState().updateRun(event.runId, event);
|
|
41225
|
+
});
|
|
41226
|
+
const unsubComputeComplete = api.onComputeRunComplete((event) => {
|
|
41227
|
+
useComputeStore.getState().updateRun(event.runId, event);
|
|
41228
|
+
});
|
|
41229
|
+
const unsubComputeEnv = api.onComputeEnvironment((event) => {
|
|
41230
|
+
useComputeStore.getState().setEnvironment(event);
|
|
41231
|
+
});
|
|
40426
41232
|
return () => {
|
|
40427
41233
|
unsub1();
|
|
40428
41234
|
unsub2();
|
|
@@ -40435,6 +41241,9 @@ function App() {
|
|
|
40435
41241
|
unsubToolProgress();
|
|
40436
41242
|
unsubSkillLoaded();
|
|
40437
41243
|
unsubUsage();
|
|
41244
|
+
unsubComputeUpdate();
|
|
41245
|
+
unsubComputeComplete();
|
|
41246
|
+
unsubComputeEnv();
|
|
40438
41247
|
};
|
|
40439
41248
|
}, [hasProject]);
|
|
40440
41249
|
reactExports.useEffect(() => {
|
|
@@ -40446,12 +41255,6 @@ function App() {
|
|
|
40446
41255
|
reactExports.useEffect(() => {
|
|
40447
41256
|
const handler = (e) => {
|
|
40448
41257
|
if (previewEditorFocused) return;
|
|
40449
|
-
if ((e.metaKey || e.ctrlKey) && e.key === "n") {
|
|
40450
|
-
e.preventDefault();
|
|
40451
|
-
useChatStore.getState().clear();
|
|
40452
|
-
useUIStore.getState().setIdle(true);
|
|
40453
|
-
useUIStore.getState().closePreview();
|
|
40454
|
-
}
|
|
40455
41258
|
if ((e.metaKey || e.ctrlKey) && e.key === "1") {
|
|
40456
41259
|
e.preventDefault();
|
|
40457
41260
|
useUIStore.getState().setCenterView("chat");
|
|
@@ -40460,6 +41263,10 @@ function App() {
|
|
|
40460
41263
|
e.preventDefault();
|
|
40461
41264
|
useUIStore.getState().setCenterView("literature");
|
|
40462
41265
|
}
|
|
41266
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "3" && api?.isComputeEnabled?.()) {
|
|
41267
|
+
e.preventDefault();
|
|
41268
|
+
useUIStore.getState().setCenterView("compute");
|
|
41269
|
+
}
|
|
40463
41270
|
if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === "K") {
|
|
40464
41271
|
e.preventDefault();
|
|
40465
41272
|
if (useChatStore.getState().isStreaming) {
|
|
@@ -40491,6 +41298,7 @@ function App() {
|
|
|
40491
41298
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(FolderGate, { onOpenSettings: () => setShowApiKeySetup(true) });
|
|
40492
41299
|
}
|
|
40493
41300
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-screen w-screen t-bg-base t-text", children: [
|
|
41301
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "#main-content", className: "skip-link", children: "Skip to content" }),
|
|
40494
41302
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "drag-region fixed top-0 left-0 right-0 h-8 z-50" }),
|
|
40495
41303
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 min-h-0", children: [
|
|
40496
41304
|
!leftCollapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: previewEntity ? "hidden" : "contents", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LeftSidebar, {}) }),
|