research-copilot 0.2.17 → 0.2.21
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/README.md +7 -1
- package/app/out/main/index.mjs +2842 -188
- package/app/out/preload/index.js +2 -0
- package/app/out/renderer/assets/{MilkdownMarkdownEditor-tTNRIB2K.css → MilkdownMarkdownEditor-BW0Pt28W.css} +103 -15
- package/app/out/renderer/assets/{MilkdownMarkdownEditor-CuTa5j4S.js → MilkdownMarkdownEditor-OhCrq3X0.js} +99 -52
- package/app/out/renderer/assets/{arc-BAWS3N-F.js → arc-DLr0RP8F.js} +1 -1
- package/app/out/renderer/assets/{blockDiagram-c4efeb88-BHadwPqY.js → blockDiagram-c4efeb88-XhKChw2n.js} +8 -8
- package/app/out/renderer/assets/{c4Diagram-c83219d4-B3kOxRad.js → c4Diagram-c83219d4-DDoJmoIQ.js} +3 -3
- package/app/out/renderer/assets/{channel-Bll9CBqI.js → channel-CJCgJSqV.js} +1 -1
- package/app/out/renderer/assets/{classDiagram-beda092f-Dv7owGyx.js → classDiagram-beda092f-CAmimZpz.js} +6 -6
- package/app/out/renderer/assets/{classDiagram-v2-2358418a-cWrqk5tQ.js → classDiagram-v2-2358418a-Bma4E_Eg.js} +10 -10
- package/app/out/renderer/assets/{clone-D-DQ4nnY.js → clone-C338dmoI.js} +1 -1
- package/app/out/renderer/assets/{createText-1719965b-ciE8YuqI.js → createText-1719965b-_up4NJqB.js} +2 -2
- package/app/out/renderer/assets/{edges-96097737-DycnAYk_.js → edges-96097737-Bpp6hVLn.js} +3 -3
- package/app/out/renderer/assets/{erDiagram-0228fc6a-Sv78YNMY.js → erDiagram-0228fc6a-bjTh_7ap.js} +5 -5
- package/app/out/renderer/assets/{flowDb-c6c81e3f-BiOarg9b.js → flowDb-c6c81e3f-BjVV4DVk.js} +1 -1
- package/app/out/renderer/assets/{flowDiagram-50d868cf-19J80nxU.js → flowDiagram-50d868cf-gmeaaZ6z.js} +12 -12
- package/app/out/renderer/assets/{flowDiagram-v2-4f6560a1-c-kGsubV.js → flowDiagram-v2-4f6560a1-nem5zs2M.js} +12 -12
- package/app/out/renderer/assets/{flowchart-elk-definition-6af322e1-DRrYbiSC.js → flowchart-elk-definition-6af322e1-DPaGAYRw.js} +6 -6
- package/app/out/renderer/assets/{ganttDiagram-a2739b55-BadmpvMy.js → ganttDiagram-a2739b55-CnAti19E.js} +3 -3
- package/app/out/renderer/assets/{gitGraphDiagram-82fe8481-BdVoj60Q.js → gitGraphDiagram-82fe8481-DQWHD3SJ.js} +2 -2
- package/app/out/renderer/assets/{graph-jZhookGR.js → graph-DKiKgH8m.js} +1 -1
- package/app/out/renderer/assets/{index-B8fh500_.js → index-4s-c5d65.js} +3 -3
- package/app/out/renderer/assets/{index-5325376f-CbxmatXv.js → index-5325376f-G-0aO-2i.js} +6 -6
- package/app/out/renderer/assets/{index-CAlpJ3-o.js → index-9q_P5ULR.js} +4 -4
- package/app/out/renderer/assets/{index-cavFRVgM.js → index-B1A3JxQj.js} +3 -3
- package/app/out/renderer/assets/{index-B9kkJj3J.js → index-BBUrmGmY.js} +6 -6
- package/app/out/renderer/assets/{index-CMGDsC_t.js → index-BQho5LH-.js} +6 -6
- package/app/out/renderer/assets/{index-CirXkIv2.js → index-BUVlmsgO.js} +3 -3
- package/app/out/renderer/assets/{index-BWCwSkxb.js → index-BzEthrJ4.js} +3 -3
- package/app/out/renderer/assets/{index-B2UUF9y9.js → index-C1YzkB4z.js} +1289 -419
- package/app/out/renderer/assets/{index-D-ZMmLhv.js → index-CGo665vD.js} +3 -3
- package/app/out/renderer/assets/{index-DQwFQR1s.js → index-CPZaxR35.js} +3 -3
- package/app/out/renderer/assets/{index-DOUTte7i.js → index-CSyD1mbL.js} +3 -3
- package/app/out/renderer/assets/{index-BUcSHPha.js → index-Cf7vlFSn.js} +3 -3
- package/app/out/renderer/assets/{index-CZX0435B.js → index-CluH1o2q.js} +6 -6
- package/app/out/renderer/assets/{index-lAZsmnj1.css → index-CogwQwDN.css} +185 -32
- package/app/out/renderer/assets/{index-DEO9Jh2Y.js → index-Cw1n3klA.js} +5 -5
- package/app/out/renderer/assets/{index-BBUnWjLe.js → index-DFzvntIw.js} +3 -3
- package/app/out/renderer/assets/{index-g91Iwgxa.js → index-DHzyAhWM.js} +4 -4
- package/app/out/renderer/assets/{index-47oNNEnx.js → index-DhliHfCM.js} +6 -6
- package/app/out/renderer/assets/{index-DF_C6DjR.js → index-DkVFbCxC.js} +3 -3
- package/app/out/renderer/assets/{index-HCRA2-Q6.js → index-DpZJP5MT.js} +6 -6
- package/app/out/renderer/assets/{index-BXpNbFhG.js → index-Gfd_DiMG.js} +3 -3
- package/app/out/renderer/assets/{index-B110aKST.js → index-jOvNAYyP.js} +3 -3
- package/app/out/renderer/assets/{index-BTE0dEKO.js → index-rrJkk8KV.js} +6 -6
- package/app/out/renderer/assets/{index-DO5LsHlM.js → index-vfSerSmF.js} +1 -1
- package/app/out/renderer/assets/{infoDiagram-8eee0895-DpVt3Scv.js → infoDiagram-8eee0895-BCnBkXXS.js} +2 -2
- package/app/out/renderer/assets/{journeyDiagram-c64418c1-RYKX5mcV.js → journeyDiagram-c64418c1-Bq2wSX3k.js} +4 -4
- package/app/out/renderer/assets/{layout-BsbNXXgR.js → layout-BvkumzoT.js} +2 -2
- package/app/out/renderer/assets/{line-OzQTpJsh.js → line-eU4el-G4.js} +1 -1
- package/app/out/renderer/assets/{linear-DO5pdnqi.js → linear-DlBjMBEa.js} +1 -1
- package/app/out/renderer/assets/{mindmap-definition-8da855dc-D3zWs3h1.js → mindmap-definition-8da855dc-CzLBu7ao.js} +3 -3
- package/app/out/renderer/assets/{pieDiagram-a8764435-DDoNhSgQ.js → pieDiagram-a8764435--olrXFr_.js} +3 -3
- package/app/out/renderer/assets/{quadrantDiagram-1e28029f-ZO85SsRM.js → quadrantDiagram-1e28029f-BnpnBBgc.js} +3 -3
- package/app/out/renderer/assets/{requirementDiagram-08caed73-C-vKE6g8.js → requirementDiagram-08caed73-6O9WS7hn.js} +5 -5
- package/app/out/renderer/assets/{sankeyDiagram-a04cb91d-Cbqb2K-X.js → sankeyDiagram-a04cb91d-D-iJnK91.js} +2 -2
- package/app/out/renderer/assets/{sequenceDiagram-c5b8d532-BK4uvpEA.js → sequenceDiagram-c5b8d532-DBlK15cV.js} +3 -3
- package/app/out/renderer/assets/{stateDiagram-1ecb1508-DXa_YqNi.js → stateDiagram-1ecb1508-DKXKPYuk.js} +6 -6
- package/app/out/renderer/assets/{stateDiagram-v2-c2b004d7-Dm203Z8l.js → stateDiagram-v2-c2b004d7-DY288Eo5.js} +10 -10
- package/app/out/renderer/assets/{styles-b4e223ce-BV4b1eAh.js → styles-b4e223ce-CRJ_xgJ-.js} +1 -1
- package/app/out/renderer/assets/{styles-ca3715f6-CKhYSe7r.js → styles-ca3715f6-Bp_k5KLD.js} +1 -1
- package/app/out/renderer/assets/{styles-d45a18b0-DTCMfE-4.js → styles-d45a18b0-DLA8Gg6D.js} +4 -4
- package/app/out/renderer/assets/{svgDrawCommon-b86b1483-DK4i-dfJ.js → svgDrawCommon-b86b1483-Dm5CK2gQ.js} +1 -1
- package/app/out/renderer/assets/{timeline-definition-faaaa080-CE2LmuDH.js → timeline-definition-faaaa080-D-m9BHUg.js} +3 -3
- package/app/out/renderer/assets/{xychartDiagram-f5964ef8-Bd8KT9X9.js → xychartDiagram-f5964ef8-Drn4Rqev.js} +5 -5
- package/app/out/renderer/index.html +2 -2
- package/lib/skills/builtin/academic-marp-slides/SKILL.md +933 -0
- package/lib/skills/builtin/research-grants/SKILL.md +15 -11
- package/lib/skills/builtin/scholar-evaluation/SKILL.md +12 -11
- package/lib/skills/builtin/scientific-schematics/SKILL.md +463 -560
- package/lib/skills/builtin/teaching-marp-slides/SKILL.md +1218 -0
- package/package.json +1 -1
- package/scripts/audit-diagram-prompts.mjs +67 -0
- package/scripts/test-skill-routing.mjs +238 -0
- package/lib/skills/builtin/marp-slides/SKILL.md +0 -642
- package/lib/skills/builtin/scientific-schematics/references/QUICK_REFERENCE.md +0 -182
- package/lib/skills/builtin/scientific-schematics/references/README.md +0 -292
- package/lib/skills/builtin/scientific-schematics/scripts/__pycache__/generate_schematic.cpython-312.pyc +0 -0
- package/lib/skills/builtin/scientific-schematics/scripts/__pycache__/generate_schematic_ai.cpython-312.pyc +0 -0
- package/lib/skills/builtin/scientific-schematics/scripts/example_usage.sh +0 -85
- package/lib/skills/builtin/scientific-schematics/scripts/generate_schematic.py +0 -141
- package/lib/skills/builtin/scientific-schematics/scripts/generate_schematic_ai.py +0 -910
|
@@ -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-OhCrq3X0.js","./MilkdownMarkdownEditor-BW0Pt28W.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;
|
|
@@ -12704,6 +12704,26 @@ const CircleDot = createLucideIcon("CircleDot", [
|
|
|
12704
12704
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
12705
12705
|
["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }]
|
|
12706
12706
|
]);
|
|
12707
|
+
/**
|
|
12708
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12709
|
+
*
|
|
12710
|
+
* This source code is licensed under the ISC license.
|
|
12711
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12712
|
+
*/
|
|
12713
|
+
const ClipboardPaste = createLucideIcon("ClipboardPaste", [
|
|
12714
|
+
[
|
|
12715
|
+
"path",
|
|
12716
|
+
{ d: "M15 2H9a1 1 0 0 0-1 1v2c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V3c0-.6-.4-1-1-1Z", key: "1pp7kr" }
|
|
12717
|
+
],
|
|
12718
|
+
[
|
|
12719
|
+
"path",
|
|
12720
|
+
{
|
|
12721
|
+
d: "M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2M16 4h2a2 2 0 0 1 2 2v2M11 14h10",
|
|
12722
|
+
key: "2ik1ml"
|
|
12723
|
+
}
|
|
12724
|
+
],
|
|
12725
|
+
["path", { d: "m17 10 4 4-4 4", key: "vp2hj1" }]
|
|
12726
|
+
]);
|
|
12707
12727
|
/**
|
|
12708
12728
|
* @license lucide-react v0.469.0 - ISC
|
|
12709
12729
|
*
|
|
@@ -12754,6 +12774,17 @@ const Database = createLucideIcon("Database", [
|
|
|
12754
12774
|
["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
|
|
12755
12775
|
["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
|
|
12756
12776
|
]);
|
|
12777
|
+
/**
|
|
12778
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12779
|
+
*
|
|
12780
|
+
* This source code is licensed under the ISC license.
|
|
12781
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12782
|
+
*/
|
|
12783
|
+
const Ellipsis = createLucideIcon("Ellipsis", [
|
|
12784
|
+
["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
|
|
12785
|
+
["circle", { cx: "19", cy: "12", r: "1", key: "1wjl8i" }],
|
|
12786
|
+
["circle", { cx: "5", cy: "12", r: "1", key: "1pcz8c" }]
|
|
12787
|
+
]);
|
|
12757
12788
|
/**
|
|
12758
12789
|
* @license lucide-react v0.469.0 - ISC
|
|
12759
12790
|
*
|
|
@@ -12950,6 +12981,29 @@ const Globe = createLucideIcon("Globe", [
|
|
|
12950
12981
|
["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
|
|
12951
12982
|
["path", { d: "M2 12h20", key: "9i4pu4" }]
|
|
12952
12983
|
]);
|
|
12984
|
+
/**
|
|
12985
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12986
|
+
*
|
|
12987
|
+
* This source code is licensed under the ISC license.
|
|
12988
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12989
|
+
*/
|
|
12990
|
+
const Hash = createLucideIcon("Hash", [
|
|
12991
|
+
["line", { x1: "4", x2: "20", y1: "9", y2: "9", key: "4lhtct" }],
|
|
12992
|
+
["line", { x1: "4", x2: "20", y1: "15", y2: "15", key: "vyu0kd" }],
|
|
12993
|
+
["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }],
|
|
12994
|
+
["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }]
|
|
12995
|
+
]);
|
|
12996
|
+
/**
|
|
12997
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12998
|
+
*
|
|
12999
|
+
* This source code is licensed under the ISC license.
|
|
13000
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
13001
|
+
*/
|
|
13002
|
+
const Image = createLucideIcon("Image", [
|
|
13003
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
13004
|
+
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
13005
|
+
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
13006
|
+
]);
|
|
12953
13007
|
/**
|
|
12954
13008
|
* @license lucide-react v0.469.0 - ISC
|
|
12955
13009
|
*
|
|
@@ -12989,6 +13043,17 @@ const Lightbulb = createLucideIcon("Lightbulb", [
|
|
|
12989
13043
|
["path", { d: "M9 18h6", key: "x1upvd" }],
|
|
12990
13044
|
["path", { d: "M10 22h4", key: "ceow96" }]
|
|
12991
13045
|
]);
|
|
13046
|
+
/**
|
|
13047
|
+
* @license lucide-react v0.469.0 - ISC
|
|
13048
|
+
*
|
|
13049
|
+
* This source code is licensed under the ISC license.
|
|
13050
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
13051
|
+
*/
|
|
13052
|
+
const Link2 = createLucideIcon("Link2", [
|
|
13053
|
+
["path", { d: "M9 17H7A5 5 0 0 1 7 7h2", key: "8i5ue5" }],
|
|
13054
|
+
["path", { d: "M15 7h2a5 5 0 1 1 0 10h-2", key: "1b9ql8" }],
|
|
13055
|
+
["line", { x1: "8", x2: "16", y1: "12", y2: "12", key: "1jonct" }]
|
|
13056
|
+
]);
|
|
12992
13057
|
/**
|
|
12993
13058
|
* @license lucide-react v0.469.0 - ISC
|
|
12994
13059
|
*
|
|
@@ -13104,6 +13169,17 @@ const Plus = createLucideIcon("Plus", [
|
|
|
13104
13169
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
13105
13170
|
["path", { d: "M12 5v14", key: "s699le" }]
|
|
13106
13171
|
]);
|
|
13172
|
+
/**
|
|
13173
|
+
* @license lucide-react v0.469.0 - ISC
|
|
13174
|
+
*
|
|
13175
|
+
* This source code is licensed under the ISC license.
|
|
13176
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
13177
|
+
*/
|
|
13178
|
+
const Presentation = createLucideIcon("Presentation", [
|
|
13179
|
+
["path", { d: "M2 3h20", key: "91anmk" }],
|
|
13180
|
+
["path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3", key: "2k9sn8" }],
|
|
13181
|
+
["path", { d: "m7 21 5-5 5 5", key: "bip4we" }]
|
|
13182
|
+
]);
|
|
13107
13183
|
/**
|
|
13108
13184
|
* @license lucide-react v0.469.0 - ISC
|
|
13109
13185
|
*
|
|
@@ -13419,7 +13495,7 @@ const KEY_FIELDS = [
|
|
|
13419
13495
|
name: "OPENAI_API_KEY",
|
|
13420
13496
|
label: "OpenAI",
|
|
13421
13497
|
placeholder: "sk-...",
|
|
13422
|
-
hint: "Powers GPT / o-series models. Get a key at platform.openai.com",
|
|
13498
|
+
hint: "Powers GPT / o-series models AND publication-quality diagram generation (gpt-image-2 + PNG-anchored SVG transcription). Without this key, diagrams fall back to a chat-model-only path with reduced quality. Get a key at platform.openai.com",
|
|
13423
13499
|
url: "https://platform.openai.com/api-keys",
|
|
13424
13500
|
required: true
|
|
13425
13501
|
},
|
|
@@ -13932,6 +14008,42 @@ function formatRelativeTime(isoString) {
|
|
|
13932
14008
|
if (hours < 24) return `${hours} hour${hours > 1 ? "s" : ""} ago`;
|
|
13933
14009
|
return new Date(isoString).toLocaleDateString();
|
|
13934
14010
|
}
|
|
14011
|
+
function DiagramSettings({ reviewProvider, onChangeReviewProvider }) {
|
|
14012
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
|
|
14013
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
14014
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-xs font-semibold t-text mb-1.5", children: "Generation Provider" }),
|
|
14015
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[11px] t-text-muted", children: [
|
|
14016
|
+
"Diagram images are generated via OpenAI ",
|
|
14017
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "font-mono", children: "gpt-image-2" }),
|
|
14018
|
+
" and require ",
|
|
14019
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "font-mono", children: "OPENAI_API_KEY" }),
|
|
14020
|
+
". Claude cannot generate images, so this is fixed for now."
|
|
14021
|
+
] })
|
|
14022
|
+
] }),
|
|
14023
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
14024
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-xs font-semibold t-text mb-1.5", children: "Review Provider" }),
|
|
14025
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] t-text-muted mb-2.5", children: "Which model evaluates each draft and decides whether to accept, edit, or regenerate." }),
|
|
14026
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
14027
|
+
SegmentedControl,
|
|
14028
|
+
{
|
|
14029
|
+
options: [
|
|
14030
|
+
{ label: "Auto", value: "auto" },
|
|
14031
|
+
{ label: "OpenAI", value: "openai" },
|
|
14032
|
+
{ label: "Anthropic", value: "anthropic" }
|
|
14033
|
+
],
|
|
14034
|
+
value: reviewProvider,
|
|
14035
|
+
onChange: onChangeReviewProvider
|
|
14036
|
+
}
|
|
14037
|
+
),
|
|
14038
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[10px] t-text-muted mt-1.5", children: [
|
|
14039
|
+
reviewProvider === "auto" && "Prefer heterogeneous review (Anthropic when available, so the generator does not grade its own family).",
|
|
14040
|
+
reviewProvider === "openai" && "GPT-4o vision with JSON-schema output. Requires OPENAI_API_KEY.",
|
|
14041
|
+
reviewProvider === "anthropic" && "Claude Opus vision with tool-use constrained output. Requires ANTHROPIC_API_KEY."
|
|
14042
|
+
] }),
|
|
14043
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] t-text-muted mt-2 leading-relaxed", children: "Score thresholds are calibrated per reviewer and are not directly comparable across providers. An 8.0 from OpenAI and an 8.0 from Claude represent similar quality targets, but the underlying numbers are not interchangeable." })
|
|
14044
|
+
] })
|
|
14045
|
+
] });
|
|
14046
|
+
}
|
|
13935
14047
|
const DEFAULT_SETTINGS = {
|
|
13936
14048
|
research: {
|
|
13937
14049
|
researchIntensity: "medium",
|
|
@@ -13944,6 +14056,9 @@ const DEFAULT_SETTINGS = {
|
|
|
13944
14056
|
wikiAgent: {
|
|
13945
14057
|
model: "none",
|
|
13946
14058
|
speed: "medium"
|
|
14059
|
+
},
|
|
14060
|
+
diagram: {
|
|
14061
|
+
reviewProvider: "auto"
|
|
13947
14062
|
}
|
|
13948
14063
|
};
|
|
13949
14064
|
const api$e = window.api;
|
|
@@ -13951,7 +14066,8 @@ const TABS = [
|
|
|
13951
14066
|
{ id: "api-keys", label: "API Keys", icon: Key },
|
|
13952
14067
|
{ id: "research", label: "Research", icon: BookOpen },
|
|
13953
14068
|
{ id: "data-analysis", label: "Data Analysis", icon: ChartNoAxesColumn },
|
|
13954
|
-
{ id: "paper-wiki", label: "Paper Wiki", icon: BookMarked }
|
|
14069
|
+
{ id: "paper-wiki", label: "Paper Wiki", icon: BookMarked },
|
|
14070
|
+
{ id: "diagram", label: "Diagrams", icon: Image }
|
|
13955
14071
|
];
|
|
13956
14072
|
const FOCUSABLE_SELECTOR = [
|
|
13957
14073
|
"button:not([disabled])",
|
|
@@ -14043,6 +14159,7 @@ function SettingsModal({ open, onClose, initialTab }) {
|
|
|
14043
14159
|
if (patch2.research) next.research = { ...prev.research, ...patch2.research };
|
|
14044
14160
|
if (patch2.dataAnalysis) next.dataAnalysis = { ...prev.dataAnalysis, ...patch2.dataAnalysis };
|
|
14045
14161
|
if (patch2.wikiAgent) next.wikiAgent = { ...prev.wikiAgent, ...patch2.wikiAgent };
|
|
14162
|
+
if (patch2.diagram) next.diagram = { ...prev.diagram, ...patch2.diagram };
|
|
14046
14163
|
return next;
|
|
14047
14164
|
});
|
|
14048
14165
|
setDirty(true);
|
|
@@ -14126,7 +14243,7 @@ function SettingsModal({ open, onClose, initialTab }) {
|
|
|
14126
14243
|
)
|
|
14127
14244
|
] }),
|
|
14128
14245
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto px-6 pb-4", children: [
|
|
14129
|
-
activeTab === "api-keys" && /* @__PURE__ */ jsxRuntimeExports.jsx(ApiKeysSettings, {}),
|
|
14246
|
+
activeTab === "api-keys" && /* @__PURE__ */ jsxRuntimeExports.jsx(ApiKeysSettings, { showSaveButton: true }),
|
|
14130
14247
|
activeTab === "research" && loaded && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
14131
14248
|
ResearchSettings,
|
|
14132
14249
|
{
|
|
@@ -14153,6 +14270,13 @@ function SettingsModal({ open, onClose, initialTab }) {
|
|
|
14153
14270
|
onChangeModel: (v3) => updateSettings({ wikiAgent: { ...settings.wikiAgent, model: v3 } }),
|
|
14154
14271
|
onChangeSpeed: (v3) => updateSettings({ wikiAgent: { ...settings.wikiAgent, speed: v3 } })
|
|
14155
14272
|
}
|
|
14273
|
+
),
|
|
14274
|
+
activeTab === "diagram" && loaded && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
14275
|
+
DiagramSettings,
|
|
14276
|
+
{
|
|
14277
|
+
reviewProvider: settings.diagram?.reviewProvider ?? "auto",
|
|
14278
|
+
onChangeReviewProvider: (v3) => updateSettings({ diagram: { reviewProvider: v3 } })
|
|
14279
|
+
}
|
|
14156
14280
|
)
|
|
14157
14281
|
] }),
|
|
14158
14282
|
activeTab !== "api-keys" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-6 py-2.5 border-t t-border-subtle", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] t-text-muted", children: "Settings are saved automatically. Changes to research and analysis settings take effect for new agent sessions. Existing sessions require an app restart." }) })
|
|
@@ -14235,6 +14359,21 @@ function bootTheme() {
|
|
|
14235
14359
|
applyThemeClass(theme);
|
|
14236
14360
|
return theme;
|
|
14237
14361
|
}
|
|
14362
|
+
const DRAWER_WIDTH_MIN = 360;
|
|
14363
|
+
const DRAWER_WIDTH_MAX = 720;
|
|
14364
|
+
const DRAWER_WIDTH_DEFAULT = 540;
|
|
14365
|
+
const clampDrawerWidth = (px) => Math.max(DRAWER_WIDTH_MIN, Math.min(DRAWER_WIDTH_MAX, Math.round(px)));
|
|
14366
|
+
const LEFT_WIDTH_MIN = 260;
|
|
14367
|
+
const LEFT_WIDTH_MAX = 480;
|
|
14368
|
+
const LEFT_WIDTH_DEFAULT = 320;
|
|
14369
|
+
const LEFT_WIDTH_KEY = "ui.leftSidebarWidth";
|
|
14370
|
+
const clampLeftWidth = (px) => Math.max(LEFT_WIDTH_MIN, Math.min(LEFT_WIDTH_MAX, Math.round(px)));
|
|
14371
|
+
const readLeftWidth = () => {
|
|
14372
|
+
if (typeof window === "undefined") return LEFT_WIDTH_DEFAULT;
|
|
14373
|
+
const raw = window.localStorage?.getItem(LEFT_WIDTH_KEY);
|
|
14374
|
+
const n = raw ? Number.parseInt(raw, 10) : NaN;
|
|
14375
|
+
return Number.isFinite(n) ? clampLeftWidth(n) : LEFT_WIDTH_DEFAULT;
|
|
14376
|
+
};
|
|
14238
14377
|
const useUIStore = create$1((set) => ({
|
|
14239
14378
|
// Theme hydrates from localStorage (or OS preference) at module init so
|
|
14240
14379
|
// the zustand state matches the <html> class applied by bootTheme() in
|
|
@@ -14253,6 +14392,8 @@ const useUIStore = create$1((set) => ({
|
|
|
14253
14392
|
previewEntity: null,
|
|
14254
14393
|
previewSourceTab: null,
|
|
14255
14394
|
previewEditorFocused: false,
|
|
14395
|
+
drawerWidth: DRAWER_WIDTH_DEFAULT,
|
|
14396
|
+
leftSidebarWidth: readLeftWidth(),
|
|
14256
14397
|
literatureFilter: {
|
|
14257
14398
|
search: "",
|
|
14258
14399
|
subTopic: null,
|
|
@@ -14348,13 +14489,33 @@ const useUIStore = create$1((set) => ({
|
|
|
14348
14489
|
previewEntity: null,
|
|
14349
14490
|
previewSourceTab: null,
|
|
14350
14491
|
previewEditorFocused: false,
|
|
14492
|
+
drawerWidth: DRAWER_WIDTH_DEFAULT,
|
|
14493
|
+
leftSidebarWidth: readLeftWidth(),
|
|
14351
14494
|
literatureFilter: { search: "", subTopic: null, sortBy: "year", sortDir: "desc", minScore: 0, source: null, round: null },
|
|
14352
14495
|
wikiReaderSlug: null,
|
|
14353
14496
|
wikiReaderHistory: []
|
|
14354
14497
|
}),
|
|
14355
|
-
|
|
14356
|
-
|
|
14357
|
-
|
|
14498
|
+
// Opening a preview routes the user to chat view — the drawer is mounted
|
|
14499
|
+
// inside the chat-body host, so it only renders there. Researchers expect
|
|
14500
|
+
// clicking a file to show them the file; forcing the view switch is the
|
|
14501
|
+
// honest implementation of that expectation.
|
|
14502
|
+
openPreview: (entity) => set((s15) => ({
|
|
14503
|
+
previewEntity: entity,
|
|
14504
|
+
previewSourceTab: s15.leftTab,
|
|
14505
|
+
previewEditorFocused: false,
|
|
14506
|
+
centerView: "chat"
|
|
14507
|
+
})),
|
|
14508
|
+
closePreview: () => set({ previewEntity: null, previewSourceTab: null, previewEditorFocused: false }),
|
|
14509
|
+
setPreviewEditorFocused: (previewEditorFocused) => set({ previewEditorFocused }),
|
|
14510
|
+
setDrawerWidth: (drawerWidth) => set({ drawerWidth: clampDrawerWidth(drawerWidth) }),
|
|
14511
|
+
setLeftSidebarWidth: (width) => {
|
|
14512
|
+
const clamped = clampLeftWidth(width);
|
|
14513
|
+
set({ leftSidebarWidth: clamped });
|
|
14514
|
+
try {
|
|
14515
|
+
window.localStorage?.setItem(LEFT_WIDTH_KEY, String(clamped));
|
|
14516
|
+
} catch {
|
|
14517
|
+
}
|
|
14518
|
+
}
|
|
14358
14519
|
}));
|
|
14359
14520
|
async function hydratePreferences() {
|
|
14360
14521
|
const api2 = window.api;
|
|
@@ -27548,7 +27709,6 @@ const TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
27548
27709
|
"ts",
|
|
27549
27710
|
"js",
|
|
27550
27711
|
"css",
|
|
27551
|
-
"html",
|
|
27552
27712
|
"yml",
|
|
27553
27713
|
"yaml",
|
|
27554
27714
|
"toml",
|
|
@@ -27578,6 +27738,8 @@ function WorkspaceTree() {
|
|
|
27578
27738
|
const { projectPath } = useSessionStore();
|
|
27579
27739
|
const openPreview = useUIStore((s15) => s15.openPreview);
|
|
27580
27740
|
const previewEntity = useUIStore((s15) => s15.previewEntity);
|
|
27741
|
+
const leftTab = useUIStore((s15) => s15.leftTab);
|
|
27742
|
+
const centerView = useUIStore((s15) => s15.centerView);
|
|
27581
27743
|
const data = useEntityStore((s15) => s15.data);
|
|
27582
27744
|
const refreshEntities = useEntityStore((s15) => s15.refreshAll);
|
|
27583
27745
|
const [query, setQuery] = reactExports.useState("");
|
|
@@ -27599,6 +27761,7 @@ function WorkspaceTree() {
|
|
|
27599
27761
|
const [dropTargetPath, setDropTargetPath] = reactExports.useState(null);
|
|
27600
27762
|
const [confirmTrashPath, setConfirmTrashPath] = reactExports.useState(null);
|
|
27601
27763
|
const [contextMenu, setContextMenu] = reactExports.useState(null);
|
|
27764
|
+
const [clipboardNode, setClipboardNode] = reactExports.useState(null);
|
|
27602
27765
|
const [renaming, setRenaming] = reactExports.useState(null);
|
|
27603
27766
|
const [renameValue, setRenameValue] = reactExports.useState("");
|
|
27604
27767
|
const [creating, setCreating] = reactExports.useState(null);
|
|
@@ -27613,6 +27776,9 @@ function WorkspaceTree() {
|
|
|
27613
27776
|
window.addEventListener("click", handleClick);
|
|
27614
27777
|
return () => window.removeEventListener("click", handleClick);
|
|
27615
27778
|
}, [contextMenu]);
|
|
27779
|
+
reactExports.useEffect(() => {
|
|
27780
|
+
setContextMenu(null);
|
|
27781
|
+
}, [leftTab, centerView]);
|
|
27616
27782
|
reactExports.useEffect(() => {
|
|
27617
27783
|
if (renaming && renameInputRef.current) {
|
|
27618
27784
|
renameInputRef.current.focus();
|
|
@@ -27795,6 +27961,35 @@ function WorkspaceTree() {
|
|
|
27795
27961
|
if (node2.type === "directory") return node2.relativePath;
|
|
27796
27962
|
return node2.relativePath.includes("/") ? node2.relativePath.slice(0, node2.relativePath.lastIndexOf("/")) : "";
|
|
27797
27963
|
}, []);
|
|
27964
|
+
const handleRevealInFinder = reactExports.useCallback((node2) => {
|
|
27965
|
+
void api$9.revealInFinder(node2.path);
|
|
27966
|
+
setContextMenu(null);
|
|
27967
|
+
}, []);
|
|
27968
|
+
const handleOpenInDefaultApp = reactExports.useCallback((node2) => {
|
|
27969
|
+
void api$9.openFile(node2.path);
|
|
27970
|
+
setContextMenu(null);
|
|
27971
|
+
}, []);
|
|
27972
|
+
const handleCopyFile = reactExports.useCallback((node2) => {
|
|
27973
|
+
setClipboardNode(node2);
|
|
27974
|
+
setContextMenu(null);
|
|
27975
|
+
}, []);
|
|
27976
|
+
const handlePasteFile = reactExports.useCallback(async (targetNode) => {
|
|
27977
|
+
if (!clipboardNode) return;
|
|
27978
|
+
const destDir = targetNode.type === "directory" ? targetNode.relativePath : getParentDir(targetNode);
|
|
27979
|
+
setContextMenu(null);
|
|
27980
|
+
const result = await api$9.copyItem(clipboardNode.relativePath, destDir);
|
|
27981
|
+
if (result.success) {
|
|
27982
|
+
await loadChildren(destDir);
|
|
27983
|
+
}
|
|
27984
|
+
}, [clipboardNode, getParentDir, loadChildren]);
|
|
27985
|
+
const handleCopyPath = reactExports.useCallback((node2) => {
|
|
27986
|
+
void navigator.clipboard.writeText(node2.path);
|
|
27987
|
+
setContextMenu(null);
|
|
27988
|
+
}, []);
|
|
27989
|
+
const handleCopyRelativePath = reactExports.useCallback((node2) => {
|
|
27990
|
+
void navigator.clipboard.writeText(node2.relativePath);
|
|
27991
|
+
setContextMenu(null);
|
|
27992
|
+
}, []);
|
|
27798
27993
|
const handleNewFile = reactExports.useCallback((parentRelPath) => {
|
|
27799
27994
|
setCreating({ parentDir: parentRelPath, type: "file" });
|
|
27800
27995
|
setCreateValue("");
|
|
@@ -28057,7 +28252,7 @@ function WorkspaceTree() {
|
|
|
28057
28252
|
onClick: (e) => e.stopPropagation(),
|
|
28058
28253
|
className: "flex-1 bg-transparent outline-none t-focus-ring border-b border-[var(--color-accent-soft)] text-xs t-text"
|
|
28059
28254
|
}
|
|
28060
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate flex-1", children: node2.name }),
|
|
28255
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate flex-1", title: node2.name, children: node2.name }),
|
|
28061
28256
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "hidden group-hover:flex items-center gap-0.5", children: [
|
|
28062
28257
|
node2.type === "file" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
28063
28258
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -28168,6 +28363,7 @@ function WorkspaceTree() {
|
|
|
28168
28363
|
{
|
|
28169
28364
|
ref: viewportRef,
|
|
28170
28365
|
className: `flex-1 min-h-0 overflow-y-auto px-1 py-1 ${dropTargetPath === "__root__" ? "ring-2 ring-inset ring-[var(--color-accent)]/60 bg-[var(--color-accent)]/5" : ""}`,
|
|
28366
|
+
style: { overflowAnchor: "none" },
|
|
28171
28367
|
onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
|
|
28172
28368
|
onDragOver: handleViewportDragOver,
|
|
28173
28369
|
onDragLeave: handleViewportDragLeave,
|
|
@@ -28181,16 +28377,16 @@ function WorkspaceTree() {
|
|
|
28181
28377
|
'".'
|
|
28182
28378
|
] }) : !query.trim() && rootNodes.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "px-2 py-2 text-xs t-text-muted", children: "No visible files in workspace root." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
28183
28379
|
creating && creating.parentDir === "" && renderCreateInput(0),
|
|
28184
|
-
|
|
28380
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { height: `${topSpacerHeight}px` } }),
|
|
28185
28381
|
visibleRows.map((row) => renderVisibleRow(row)),
|
|
28186
|
-
|
|
28382
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { height: `${bottomSpacerHeight}px` } })
|
|
28187
28383
|
] })
|
|
28188
28384
|
}
|
|
28189
28385
|
),
|
|
28190
28386
|
contextMenu && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28191
28387
|
"div",
|
|
28192
28388
|
{
|
|
28193
|
-
className: "fixed z-50 min-w-[
|
|
28389
|
+
className: "fixed z-50 min-w-[180px] rounded-lg border t-border t-bg-surface shadow-xl py-1",
|
|
28194
28390
|
style: { left: contextMenu.x, top: contextMenu.y },
|
|
28195
28391
|
onClick: (e) => e.stopPropagation(),
|
|
28196
28392
|
children: [
|
|
@@ -28208,6 +28404,75 @@ function WorkspaceTree() {
|
|
|
28208
28404
|
]
|
|
28209
28405
|
}
|
|
28210
28406
|
),
|
|
28407
|
+
contextMenu.node.type === "file" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28408
|
+
"button",
|
|
28409
|
+
{
|
|
28410
|
+
className: "w-full text-left px-3 py-1.5 text-xs t-text-secondary hover:t-bg-hover flex items-center gap-2",
|
|
28411
|
+
onClick: () => handleOpenInDefaultApp(contextMenu.node),
|
|
28412
|
+
children: [
|
|
28413
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { size: 11 }),
|
|
28414
|
+
" Open in Default App"
|
|
28415
|
+
]
|
|
28416
|
+
}
|
|
28417
|
+
),
|
|
28418
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28419
|
+
"button",
|
|
28420
|
+
{
|
|
28421
|
+
className: "w-full text-left px-3 py-1.5 text-xs t-text-secondary hover:t-bg-hover flex items-center gap-2",
|
|
28422
|
+
onClick: () => handleRevealInFinder(contextMenu.node),
|
|
28423
|
+
children: [
|
|
28424
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { size: 11 }),
|
|
28425
|
+
" Reveal in Finder"
|
|
28426
|
+
]
|
|
28427
|
+
}
|
|
28428
|
+
),
|
|
28429
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t t-border my-1" }),
|
|
28430
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28431
|
+
"button",
|
|
28432
|
+
{
|
|
28433
|
+
className: "w-full text-left px-3 py-1.5 text-xs t-text-secondary hover:t-bg-hover flex items-center gap-2",
|
|
28434
|
+
onClick: () => handleCopyFile(contextMenu.node),
|
|
28435
|
+
children: [
|
|
28436
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 11 }),
|
|
28437
|
+
" Copy"
|
|
28438
|
+
]
|
|
28439
|
+
}
|
|
28440
|
+
),
|
|
28441
|
+
clipboardNode && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28442
|
+
"button",
|
|
28443
|
+
{
|
|
28444
|
+
className: "w-full text-left px-3 py-1.5 text-xs t-text-secondary hover:t-bg-hover flex items-center gap-2",
|
|
28445
|
+
onClick: () => void handlePasteFile(contextMenu.node),
|
|
28446
|
+
children: [
|
|
28447
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardPaste, { size: 11 }),
|
|
28448
|
+
" Paste"
|
|
28449
|
+
]
|
|
28450
|
+
}
|
|
28451
|
+
),
|
|
28452
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t t-border my-1" }),
|
|
28453
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28454
|
+
"button",
|
|
28455
|
+
{
|
|
28456
|
+
className: "w-full text-left px-3 py-1.5 text-xs t-text-secondary hover:t-bg-hover flex items-center gap-2",
|
|
28457
|
+
onClick: () => handleCopyPath(contextMenu.node),
|
|
28458
|
+
children: [
|
|
28459
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Hash, { size: 11 }),
|
|
28460
|
+
" Copy Path"
|
|
28461
|
+
]
|
|
28462
|
+
}
|
|
28463
|
+
),
|
|
28464
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28465
|
+
"button",
|
|
28466
|
+
{
|
|
28467
|
+
className: "w-full text-left px-3 py-1.5 text-xs t-text-secondary hover:t-bg-hover flex items-center gap-2",
|
|
28468
|
+
onClick: () => handleCopyRelativePath(contextMenu.node),
|
|
28469
|
+
children: [
|
|
28470
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Link2, { size: 11 }),
|
|
28471
|
+
" Copy Relative Path"
|
|
28472
|
+
]
|
|
28473
|
+
}
|
|
28474
|
+
),
|
|
28475
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t t-border my-1" }),
|
|
28211
28476
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28212
28477
|
"button",
|
|
28213
28478
|
{
|
|
@@ -28318,7 +28583,7 @@ const useSkillStore = create$1((set, get) => ({
|
|
|
28318
28583
|
return result;
|
|
28319
28584
|
}
|
|
28320
28585
|
}));
|
|
28321
|
-
const remarkPlugins$
|
|
28586
|
+
const remarkPlugins$4 = [remarkGfm];
|
|
28322
28587
|
function HoverPreview({
|
|
28323
28588
|
entity,
|
|
28324
28589
|
anchorRect,
|
|
@@ -28360,7 +28625,7 @@ function HoverPreview({
|
|
|
28360
28625
|
}
|
|
28361
28626
|
) })
|
|
28362
28627
|
] }),
|
|
28363
|
-
content2 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose text-xs", style: { color: "var(--color-text-secondary)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$
|
|
28628
|
+
content2 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose text-xs", style: { color: "var(--color-text-secondary)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$4, children: content2.length > 600 ? content2.slice(0, 600) + "..." : content2 }) }) })
|
|
28364
28629
|
]
|
|
28365
28630
|
}
|
|
28366
28631
|
);
|
|
@@ -28447,7 +28712,7 @@ const EntityRow = React$2.memo(function EntityRow2({ entity }) {
|
|
|
28447
28712
|
}
|
|
28448
28713
|
),
|
|
28449
28714
|
isEnriching ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 10, className: "shrink-0 t-text-accent-soft animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-1 h-1 rounded-full shrink-0 t-bg-elevated" }),
|
|
28450
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs t-text truncate", children: entity.title })
|
|
28715
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs t-text truncate", title: entity.title, children: entity.title })
|
|
28451
28716
|
]
|
|
28452
28717
|
}
|
|
28453
28718
|
),
|
|
@@ -28508,10 +28773,18 @@ function DataTreeView({ items }) {
|
|
|
28508
28773
|
}
|
|
28509
28774
|
),
|
|
28510
28775
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FlaskConical, { size: 13, className: "shrink-0 t-text-accent" }),
|
|
28511
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28512
|
-
"
|
|
28513
|
-
|
|
28514
|
-
|
|
28776
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28777
|
+
"span",
|
|
28778
|
+
{
|
|
28779
|
+
className: "text-xs t-text truncate",
|
|
28780
|
+
title: `Analysis: ${label}`,
|
|
28781
|
+
onClick: () => openPreview(children[0]),
|
|
28782
|
+
children: [
|
|
28783
|
+
"Analysis: ",
|
|
28784
|
+
label
|
|
28785
|
+
]
|
|
28786
|
+
}
|
|
28787
|
+
)
|
|
28515
28788
|
] }),
|
|
28516
28789
|
isOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-4", children: children.map((e) => /* @__PURE__ */ jsxRuntimeExports.jsx(EntityRow, { entity: e }, e.id)) })
|
|
28517
28790
|
] }, runId);
|
|
@@ -28720,7 +28993,7 @@ function SkillsContent() {
|
|
|
28720
28993
|
),
|
|
28721
28994
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
28722
28995
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
28723
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text font-medium truncate", children: skill.name }),
|
|
28996
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text font-medium truncate", title: skill.name, children: skill.name }),
|
|
28724
28997
|
skill.source !== "builtin" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 px-1 py-px text-[9px] rounded t-bg-elevated t-text-muted", children: skill.source })
|
|
28725
28998
|
] }),
|
|
28726
28999
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] t-text-muted leading-tight line-clamp-2 mt-0.5", children: skill.description }),
|
|
@@ -28761,21 +29034,6 @@ function EntityTabs() {
|
|
|
28761
29034
|
const notes = useEntityStore((s15) => s15.notes);
|
|
28762
29035
|
const data = useEntityStore((s15) => s15.data);
|
|
28763
29036
|
const refreshAll = useEntityStore((s15) => s15.refreshAll);
|
|
28764
|
-
reactExports.useEffect(() => {
|
|
28765
|
-
refreshAll();
|
|
28766
|
-
}, []);
|
|
28767
|
-
const renderContent = () => {
|
|
28768
|
-
switch (leftTab) {
|
|
28769
|
-
case "library":
|
|
28770
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(LibraryContent, { notes, data, refreshAll });
|
|
28771
|
-
case "files":
|
|
28772
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(WorkspaceTree, {});
|
|
28773
|
-
case "skills":
|
|
28774
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(SkillsContent, {});
|
|
28775
|
-
default:
|
|
28776
|
-
return null;
|
|
28777
|
-
}
|
|
28778
|
-
};
|
|
28779
29037
|
const handleTabKeyDown = (e) => {
|
|
28780
29038
|
const tabKeys = tabs.map((t) => t.key);
|
|
28781
29039
|
const idx = tabKeys.indexOf(leftTab);
|
|
@@ -28809,16 +29067,44 @@ function EntityTabs() {
|
|
|
28809
29067
|
},
|
|
28810
29068
|
key
|
|
28811
29069
|
)) }),
|
|
28812
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
28813
|
-
|
|
28814
|
-
|
|
28815
|
-
|
|
28816
|
-
|
|
28817
|
-
|
|
28818
|
-
|
|
28819
|
-
|
|
28820
|
-
|
|
28821
|
-
|
|
29070
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-h-0 overflow-hidden", children: [
|
|
29071
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29072
|
+
"div",
|
|
29073
|
+
{
|
|
29074
|
+
role: "tabpanel",
|
|
29075
|
+
id: "tabpanel-library",
|
|
29076
|
+
"aria-labelledby": "tab-library",
|
|
29077
|
+
className: `h-full flex flex-col min-h-0 ${leftTab === "library" ? "" : "hidden"}`,
|
|
29078
|
+
"aria-hidden": leftTab !== "library",
|
|
29079
|
+
inert: leftTab !== "library",
|
|
29080
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(LibraryContent, { notes, data, refreshAll })
|
|
29081
|
+
}
|
|
29082
|
+
),
|
|
29083
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29084
|
+
"div",
|
|
29085
|
+
{
|
|
29086
|
+
role: "tabpanel",
|
|
29087
|
+
id: "tabpanel-files",
|
|
29088
|
+
"aria-labelledby": "tab-files",
|
|
29089
|
+
className: `h-full flex flex-col min-h-0 ${leftTab === "files" ? "" : "hidden"}`,
|
|
29090
|
+
"aria-hidden": leftTab !== "files",
|
|
29091
|
+
inert: leftTab !== "files",
|
|
29092
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(WorkspaceTree, {})
|
|
29093
|
+
}
|
|
29094
|
+
),
|
|
29095
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29096
|
+
"div",
|
|
29097
|
+
{
|
|
29098
|
+
role: "tabpanel",
|
|
29099
|
+
id: "tabpanel-skills",
|
|
29100
|
+
"aria-labelledby": "tab-skills",
|
|
29101
|
+
className: `h-full flex flex-col min-h-0 ${leftTab === "skills" ? "" : "hidden"}`,
|
|
29102
|
+
"aria-hidden": leftTab !== "skills",
|
|
29103
|
+
inert: leftTab !== "skills",
|
|
29104
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(SkillsContent, {})
|
|
29105
|
+
}
|
|
29106
|
+
)
|
|
29107
|
+
] })
|
|
28822
29108
|
] });
|
|
28823
29109
|
}
|
|
28824
29110
|
const api$8 = window.api;
|
|
@@ -28899,7 +29185,7 @@ function GapAlerts({ papers }) {
|
|
|
28899
29185
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] t-text-muted uppercase tracking-wider font-medium", children: "Coverage Gaps" }),
|
|
28900
29186
|
gaps.map((topic) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 px-1", children: [
|
|
28901
29187
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-amber-400 shrink-0" }),
|
|
28902
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] t-text-secondary truncate", children: topic })
|
|
29188
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] t-text-secondary truncate", title: topic, children: topic })
|
|
28903
29189
|
] }, topic))
|
|
28904
29190
|
] });
|
|
28905
29191
|
}
|
|
@@ -29167,6 +29453,7 @@ function UserProfile() {
|
|
|
29167
29453
|
"button",
|
|
29168
29454
|
{
|
|
29169
29455
|
onClick: handlePickFolder,
|
|
29456
|
+
title: displayPath,
|
|
29170
29457
|
className: "no-drag flex items-center gap-2 w-full text-left text-sm t-text-secondary hover:t-text transition-colors",
|
|
29171
29458
|
children: [
|
|
29172
29459
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { size: 16, className: "shrink-0" }),
|
|
@@ -29711,12 +29998,13 @@ function ReasoningToggle() {
|
|
|
29711
29998
|
}
|
|
29712
29999
|
);
|
|
29713
30000
|
}
|
|
29714
|
-
function ToolbarButton({ onClick, tooltip, children }) {
|
|
30001
|
+
function ToolbarButton({ onClick, tooltip, children, ariaExpanded }) {
|
|
29715
30002
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
29716
30003
|
"button",
|
|
29717
30004
|
{
|
|
29718
30005
|
onClick,
|
|
29719
30006
|
"aria-label": tooltip,
|
|
30007
|
+
"aria-expanded": ariaExpanded,
|
|
29720
30008
|
className: "no-drag group relative p-2.5 rounded-lg t-text-muted t-bg-hover transition-colors",
|
|
29721
30009
|
children: [
|
|
29722
30010
|
children,
|
|
@@ -29733,10 +30021,99 @@ function ToolbarButton({ onClick, tooltip, children }) {
|
|
|
29733
30021
|
}
|
|
29734
30022
|
);
|
|
29735
30023
|
}
|
|
30024
|
+
function OverflowMenu({
|
|
30025
|
+
theme,
|
|
30026
|
+
onToggleTheme,
|
|
30027
|
+
onResetContext,
|
|
30028
|
+
onToggleTerminal
|
|
30029
|
+
}) {
|
|
30030
|
+
const [open, setOpen] = React$2.useState(false);
|
|
30031
|
+
const ref = reactExports.useRef(null);
|
|
30032
|
+
reactExports.useEffect(() => {
|
|
30033
|
+
if (!open) return;
|
|
30034
|
+
const handler = (e) => {
|
|
30035
|
+
if (!ref.current?.contains(e.target)) setOpen(false);
|
|
30036
|
+
};
|
|
30037
|
+
const escHandler = (e) => {
|
|
30038
|
+
if (e.key === "Escape") setOpen(false);
|
|
30039
|
+
};
|
|
30040
|
+
document.addEventListener("mousedown", handler);
|
|
30041
|
+
document.addEventListener("keydown", escHandler);
|
|
30042
|
+
return () => {
|
|
30043
|
+
document.removeEventListener("mousedown", handler);
|
|
30044
|
+
document.removeEventListener("keydown", escHandler);
|
|
30045
|
+
};
|
|
30046
|
+
}, [open]);
|
|
30047
|
+
const run = (fn2) => () => {
|
|
30048
|
+
fn2();
|
|
30049
|
+
setOpen(false);
|
|
30050
|
+
};
|
|
30051
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref, className: "relative", children: [
|
|
30052
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30053
|
+
ToolbarButton,
|
|
30054
|
+
{
|
|
30055
|
+
onClick: () => setOpen((v3) => !v3),
|
|
30056
|
+
tooltip: "More",
|
|
30057
|
+
ariaExpanded: open,
|
|
30058
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Ellipsis, { size: 16 })
|
|
30059
|
+
}
|
|
30060
|
+
),
|
|
30061
|
+
open && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30062
|
+
"div",
|
|
30063
|
+
{
|
|
30064
|
+
role: "menu",
|
|
30065
|
+
className: "absolute right-0 top-full mt-1 min-w-[180px] rounded-lg border t-border t-bg-surface shadow-xl z-50 py-1",
|
|
30066
|
+
children: [
|
|
30067
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30068
|
+
"button",
|
|
30069
|
+
{
|
|
30070
|
+
role: "menuitem",
|
|
30071
|
+
onClick: run(onResetContext),
|
|
30072
|
+
className: "w-full flex items-center gap-2 px-3 py-1.5 text-xs t-text t-bg-hover transition-colors",
|
|
30073
|
+
children: [
|
|
30074
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 14, className: "t-text-muted" }),
|
|
30075
|
+
"Reset AI context"
|
|
30076
|
+
]
|
|
30077
|
+
}
|
|
30078
|
+
),
|
|
30079
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30080
|
+
"button",
|
|
30081
|
+
{
|
|
30082
|
+
role: "menuitem",
|
|
30083
|
+
onClick: run(onToggleTheme),
|
|
30084
|
+
className: "w-full flex items-center gap-2 px-3 py-1.5 text-xs t-text t-bg-hover transition-colors",
|
|
30085
|
+
children: [
|
|
30086
|
+
theme === "dark" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Sun, { size: 14, className: "t-text-muted" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Moon, { size: 14, className: "t-text-muted" }),
|
|
30087
|
+
theme === "dark" ? "Light mode" : "Dark mode"
|
|
30088
|
+
]
|
|
30089
|
+
}
|
|
30090
|
+
),
|
|
30091
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30092
|
+
"button",
|
|
30093
|
+
{
|
|
30094
|
+
role: "menuitem",
|
|
30095
|
+
onClick: run(onToggleTerminal),
|
|
30096
|
+
className: "w-full flex items-center justify-between gap-2 px-3 py-1.5 text-xs t-text t-bg-hover transition-colors",
|
|
30097
|
+
children: [
|
|
30098
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-2", children: [
|
|
30099
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { size: 14, className: "t-text-muted" }),
|
|
30100
|
+
"Terminal"
|
|
30101
|
+
] }),
|
|
30102
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "t-text-muted font-mono text-[10px]", children: "⌘`" })
|
|
30103
|
+
]
|
|
30104
|
+
}
|
|
30105
|
+
)
|
|
30106
|
+
]
|
|
30107
|
+
}
|
|
30108
|
+
)
|
|
30109
|
+
] });
|
|
30110
|
+
}
|
|
29736
30111
|
function LeftSidebar({ onOpenSettings }) {
|
|
29737
30112
|
const theme = useUIStore((s15) => s15.theme);
|
|
29738
30113
|
const toggleTheme = useUIStore((s15) => s15.toggleTheme);
|
|
29739
30114
|
const centerView = useUIStore((s15) => s15.centerView);
|
|
30115
|
+
const leftSidebarWidth = useUIStore((s15) => s15.leftSidebarWidth);
|
|
30116
|
+
const setLeftSidebarWidth = useUIStore((s15) => s15.setLeftSidebarWidth);
|
|
29740
30117
|
const noContextShownRef = reactExports.useRef(false);
|
|
29741
30118
|
const handleResetContext = reactExports.useCallback(async () => {
|
|
29742
30119
|
const messages = useChatStore.getState().messages;
|
|
@@ -29760,49 +30137,84 @@ function LeftSidebar({ onOpenSettings }) {
|
|
|
29760
30137
|
useChatStore.getState().insertContextReset();
|
|
29761
30138
|
noContextShownRef.current = false;
|
|
29762
30139
|
}, []);
|
|
29763
|
-
|
|
29764
|
-
|
|
29765
|
-
|
|
29766
|
-
|
|
29767
|
-
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
|
|
29773
|
-
|
|
29774
|
-
|
|
29775
|
-
|
|
29776
|
-
|
|
29777
|
-
|
|
29778
|
-
|
|
29779
|
-
|
|
29780
|
-
|
|
29781
|
-
|
|
29782
|
-
|
|
29783
|
-
|
|
29784
|
-
|
|
29785
|
-
|
|
29786
|
-
|
|
29787
|
-
|
|
29788
|
-
|
|
29789
|
-
|
|
29790
|
-
|
|
29791
|
-
|
|
29792
|
-
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
29797
|
-
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
29804
|
-
|
|
29805
|
-
|
|
30140
|
+
const dragStateRef = reactExports.useRef(null);
|
|
30141
|
+
const handleEdgeMouseDown = reactExports.useCallback((e) => {
|
|
30142
|
+
dragStateRef.current = { startX: e.clientX, startWidth: leftSidebarWidth };
|
|
30143
|
+
document.body.style.cursor = "ew-resize";
|
|
30144
|
+
e.preventDefault();
|
|
30145
|
+
}, [leftSidebarWidth]);
|
|
30146
|
+
reactExports.useEffect(() => {
|
|
30147
|
+
const onMove = (e) => {
|
|
30148
|
+
if (!dragStateRef.current) return;
|
|
30149
|
+
const dx = e.clientX - dragStateRef.current.startX;
|
|
30150
|
+
setLeftSidebarWidth(dragStateRef.current.startWidth + dx);
|
|
30151
|
+
};
|
|
30152
|
+
const onUp = () => {
|
|
30153
|
+
if (dragStateRef.current) document.body.style.cursor = "";
|
|
30154
|
+
dragStateRef.current = null;
|
|
30155
|
+
};
|
|
30156
|
+
window.addEventListener("mousemove", onMove);
|
|
30157
|
+
window.addEventListener("mouseup", onUp);
|
|
30158
|
+
return () => {
|
|
30159
|
+
window.removeEventListener("mousemove", onMove);
|
|
30160
|
+
window.removeEventListener("mouseup", onUp);
|
|
30161
|
+
};
|
|
30162
|
+
}, [setLeftSidebarWidth]);
|
|
30163
|
+
const handleEdgeDoubleClick = reactExports.useCallback(() => {
|
|
30164
|
+
setLeftSidebarWidth(320);
|
|
30165
|
+
}, [setLeftSidebarWidth]);
|
|
30166
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30167
|
+
"aside",
|
|
30168
|
+
{
|
|
30169
|
+
className: "relative flex flex-col border-r t-border t-bg-base pt-10 shrink-0",
|
|
30170
|
+
style: { width: `${leftSidebarWidth}px` },
|
|
30171
|
+
children: [
|
|
30172
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { "aria-label": "Sidebar tools", className: "px-4 pb-3 flex items-center justify-between gap-2", children: [
|
|
30173
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ModelSelector, {}),
|
|
30174
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
30175
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ReasoningToggle, {}),
|
|
30176
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30177
|
+
OverflowMenu,
|
|
30178
|
+
{
|
|
30179
|
+
theme,
|
|
30180
|
+
onToggleTheme: toggleTheme,
|
|
30181
|
+
onResetContext: handleResetContext,
|
|
30182
|
+
onToggleTerminal: () => useUIStore.getState().toggleTerminal()
|
|
30183
|
+
}
|
|
30184
|
+
)
|
|
30185
|
+
] })
|
|
30186
|
+
] }),
|
|
30187
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: (() => {
|
|
30188
|
+
const computeEnabled2 = !!window.api?.isComputeEnabled?.();
|
|
30189
|
+
const showLit = centerView === "literature";
|
|
30190
|
+
const showCompute = centerView === "compute" && computeEnabled2;
|
|
30191
|
+
const showEntity = !showLit && !showCompute;
|
|
30192
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
30193
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `h-full ${showLit ? "" : "hidden"}`, "aria-hidden": !showLit, inert: !showLit, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LiteratureSidebar, {}) }),
|
|
30194
|
+
computeEnabled2 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `h-full ${showCompute ? "" : "hidden"}`, "aria-hidden": !showCompute, inert: !showCompute, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ComputeSidebar, {}) }),
|
|
30195
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `h-full ${showEntity ? "" : "hidden"}`, "aria-hidden": !showEntity, inert: !showEntity, children: /* @__PURE__ */ jsxRuntimeExports.jsx(EntityTabs, {}) })
|
|
30196
|
+
] });
|
|
30197
|
+
})() }),
|
|
30198
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t t-border p-4 flex items-center justify-between", children: [
|
|
30199
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(UserProfile, {}),
|
|
30200
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarButton, { onClick: onOpenSettings, tooltip: "Settings ⌘,", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { size: 16 }) })
|
|
30201
|
+
] }),
|
|
30202
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30203
|
+
"div",
|
|
30204
|
+
{
|
|
30205
|
+
role: "separator",
|
|
30206
|
+
"aria-orientation": "vertical",
|
|
30207
|
+
"aria-label": "Resize sidebar (drag to resize, double-click to reset)",
|
|
30208
|
+
tabIndex: -1,
|
|
30209
|
+
className: "absolute right-0 top-0 bottom-0 w-[6px] cursor-ew-resize group z-[6]",
|
|
30210
|
+
style: { marginRight: -3 },
|
|
30211
|
+
onMouseDown: handleEdgeMouseDown,
|
|
30212
|
+
onDoubleClick: handleEdgeDoubleClick,
|
|
30213
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute right-[3px] top-1/2 -translate-y-1/2 w-[2px] h-9 rounded bg-transparent group-hover:t-bg-accent transition-colors" })
|
|
30214
|
+
}
|
|
30215
|
+
)
|
|
30216
|
+
]
|
|
30217
|
+
}
|
|
29806
30218
|
);
|
|
29807
30219
|
}
|
|
29808
30220
|
const STARTERS = [
|
|
@@ -30502,8 +30914,53 @@ function ToolUseStream({ events: propEvents }) {
|
|
|
30502
30914
|
running.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 mt-1", children: running.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(ToolUseCard, { event }, event.id)) })
|
|
30503
30915
|
] });
|
|
30504
30916
|
}
|
|
30917
|
+
function ImageLightbox({ src, onClose }) {
|
|
30918
|
+
reactExports.useEffect(() => {
|
|
30919
|
+
const onKey = (e) => {
|
|
30920
|
+
if (e.key === "Escape") onClose();
|
|
30921
|
+
};
|
|
30922
|
+
document.addEventListener("keydown", onKey);
|
|
30923
|
+
const prevOverflow = document.body.style.overflow;
|
|
30924
|
+
document.body.style.overflow = "hidden";
|
|
30925
|
+
return () => {
|
|
30926
|
+
document.removeEventListener("keydown", onKey);
|
|
30927
|
+
document.body.style.overflow = prevOverflow;
|
|
30928
|
+
};
|
|
30929
|
+
}, [onClose]);
|
|
30930
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30931
|
+
"div",
|
|
30932
|
+
{
|
|
30933
|
+
role: "dialog",
|
|
30934
|
+
"aria-modal": "true",
|
|
30935
|
+
"aria-label": "Image preview",
|
|
30936
|
+
onClick: onClose,
|
|
30937
|
+
className: "fixed inset-0 z-[100] flex items-center justify-center p-8",
|
|
30938
|
+
style: { background: "rgba(0,0,0,0.82)" },
|
|
30939
|
+
children: [
|
|
30940
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30941
|
+
"img",
|
|
30942
|
+
{
|
|
30943
|
+
src,
|
|
30944
|
+
alt: "",
|
|
30945
|
+
onClick: (e) => e.stopPropagation(),
|
|
30946
|
+
className: "max-w-full max-h-full object-contain rounded-lg shadow-2xl"
|
|
30947
|
+
}
|
|
30948
|
+
),
|
|
30949
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30950
|
+
"button",
|
|
30951
|
+
{
|
|
30952
|
+
onClick: onClose,
|
|
30953
|
+
"aria-label": "Close preview",
|
|
30954
|
+
className: "absolute top-4 right-4 p-2 rounded-full text-white/80 hover:text-white hover:bg-white/10 transition-colors",
|
|
30955
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { size: 22 })
|
|
30956
|
+
}
|
|
30957
|
+
)
|
|
30958
|
+
]
|
|
30959
|
+
}
|
|
30960
|
+
);
|
|
30961
|
+
}
|
|
30505
30962
|
const api$7 = window.api;
|
|
30506
|
-
const remarkPlugins$
|
|
30963
|
+
const remarkPlugins$3 = [remarkGfm];
|
|
30507
30964
|
function formatMessageTime(ts2) {
|
|
30508
30965
|
const d = new Date(ts2);
|
|
30509
30966
|
const now2 = /* @__PURE__ */ new Date();
|
|
@@ -30663,59 +31120,63 @@ const MessageBubble = React$2.memo(function MessageBubble2({ msg, isSaved }) {
|
|
|
30663
31120
|
}
|
|
30664
31121
|
};
|
|
30665
31122
|
const [copied, setCopied] = reactExports.useState(false);
|
|
31123
|
+
const [lightboxSrc, setLightboxSrc] = reactExports.useState(null);
|
|
30666
31124
|
const handleCopy = async () => {
|
|
30667
31125
|
await navigator.clipboard.writeText(msg.content);
|
|
30668
31126
|
setCopied(true);
|
|
30669
31127
|
setTimeout(() => setCopied(false), 1500);
|
|
30670
31128
|
};
|
|
30671
|
-
return /* @__PURE__ */ jsxRuntimeExports.
|
|
30672
|
-
|
|
30673
|
-
|
|
30674
|
-
|
|
30675
|
-
|
|
30676
|
-
|
|
30677
|
-
|
|
30678
|
-
|
|
30679
|
-
|
|
30680
|
-
|
|
30681
|
-
"
|
|
30682
|
-
|
|
30683
|
-
src,
|
|
30684
|
-
alt: "",
|
|
30685
|
-
loading: "lazy",
|
|
30686
|
-
className: `rounded-lg border t-border cursor-pointer hover:opacity-90 transition-opacity ${isUser ? "max-h-48" : "max-h-80"}`,
|
|
30687
|
-
onClick: () => window.open(src, "_blank")
|
|
30688
|
-
},
|
|
30689
|
-
i
|
|
30690
|
-
)) }),
|
|
30691
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose", style: { color: "var(--color-text)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$2, children: msg.content }) }),
|
|
30692
|
-
msg.timestamp > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-1.5 text-[10px] t-text-muted select-none ${isUser ? "text-right" : "text-left"}`, children: formatMessageTime(msg.timestamp) }),
|
|
30693
|
-
!isUser && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute -right-8 top-2 flex flex-col gap-1.5", children: [
|
|
30694
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30695
|
-
"button",
|
|
30696
|
-
{
|
|
30697
|
-
onClick: handleSaveNote,
|
|
30698
|
-
disabled: saveState !== "idle",
|
|
30699
|
-
className: `transition-opacity ${saveState === "saved" ? "opacity-100 t-text-success" : saveState === "saving" ? "opacity-100 t-text-muted" : "opacity-0 group-hover:opacity-100 t-text-muted hover:t-text-accent-soft"}`,
|
|
30700
|
-
title: saveState === "saved" ? "Saved as note" : "Save entire message as note",
|
|
30701
|
-
"aria-label": saveState === "saved" ? "Message saved as note" : "Save entire message as note",
|
|
30702
|
-
children: saveState === "saving" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin" }) : saveState === "saved" ? /* @__PURE__ */ jsxRuntimeExports.jsx(BookmarkCheck, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Bookmark, { size: 14 })
|
|
30703
|
-
}
|
|
30704
|
-
),
|
|
30705
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30706
|
-
"button",
|
|
31129
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex ${isUser ? "justify-end" : "justify-start"} group`, children: [
|
|
31130
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
31131
|
+
"div",
|
|
31132
|
+
{
|
|
31133
|
+
className: `relative max-w-[90%] rounded-2xl px-4 py-3 text-sm t-text ${!isUser ? "assistant-bubble" : ""}${!isUser && isSaved ? " border-l-2 border-[var(--color-status-success)]" : ""}`,
|
|
31134
|
+
style: {
|
|
31135
|
+
background: isUser ? "var(--color-bubble-user)" : "var(--color-bubble-assistant)"
|
|
31136
|
+
},
|
|
31137
|
+
"data-msg-id": msg.id,
|
|
31138
|
+
children: [
|
|
31139
|
+
msg.images && msg.images.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2 mb-2 flex-wrap", children: msg.images.map((src, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31140
|
+
"img",
|
|
30707
31141
|
{
|
|
30708
|
-
|
|
30709
|
-
|
|
30710
|
-
|
|
30711
|
-
|
|
30712
|
-
|
|
30713
|
-
}
|
|
30714
|
-
|
|
30715
|
-
|
|
30716
|
-
|
|
30717
|
-
|
|
30718
|
-
|
|
31142
|
+
src,
|
|
31143
|
+
alt: "",
|
|
31144
|
+
loading: "lazy",
|
|
31145
|
+
className: `rounded-lg border t-border cursor-pointer hover:opacity-90 transition-opacity ${isUser ? "max-h-48" : "max-h-80"}`,
|
|
31146
|
+
onClick: () => setLightboxSrc(src)
|
|
31147
|
+
},
|
|
31148
|
+
i
|
|
31149
|
+
)) }),
|
|
31150
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose", style: { color: "var(--color-text)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$3, children: msg.content }) }),
|
|
31151
|
+
msg.timestamp > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-1.5 text-[10px] t-text-muted select-none ${isUser ? "text-right" : "text-left"}`, children: formatMessageTime(msg.timestamp) }),
|
|
31152
|
+
!isUser && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute -right-8 top-2 flex flex-col gap-1.5", children: [
|
|
31153
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31154
|
+
"button",
|
|
31155
|
+
{
|
|
31156
|
+
onClick: handleSaveNote,
|
|
31157
|
+
disabled: saveState !== "idle",
|
|
31158
|
+
className: `transition-opacity ${saveState === "saved" ? "opacity-100 t-text-success" : saveState === "saving" ? "opacity-100 t-text-muted" : "opacity-0 group-hover:opacity-100 t-text-muted hover:t-text-accent-soft"}`,
|
|
31159
|
+
title: saveState === "saved" ? "Saved as note" : "Save entire message as note",
|
|
31160
|
+
"aria-label": saveState === "saved" ? "Message saved as note" : "Save entire message as note",
|
|
31161
|
+
children: saveState === "saving" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin" }) : saveState === "saved" ? /* @__PURE__ */ jsxRuntimeExports.jsx(BookmarkCheck, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Bookmark, { size: 14 })
|
|
31162
|
+
}
|
|
31163
|
+
),
|
|
31164
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31165
|
+
"button",
|
|
31166
|
+
{
|
|
31167
|
+
onClick: handleCopy,
|
|
31168
|
+
className: `transition-opacity ${copied ? "opacity-100 t-text-success" : "opacity-0 group-hover:opacity-100 t-text-muted hover:t-text-accent-soft"}`,
|
|
31169
|
+
title: copied ? "Copied!" : "Copy message",
|
|
31170
|
+
"aria-label": copied ? "Message copied" : "Copy message to clipboard",
|
|
31171
|
+
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 14 })
|
|
31172
|
+
}
|
|
31173
|
+
)
|
|
31174
|
+
] })
|
|
31175
|
+
]
|
|
31176
|
+
}
|
|
31177
|
+
),
|
|
31178
|
+
lightboxSrc && /* @__PURE__ */ jsxRuntimeExports.jsx(ImageLightbox, { src: lightboxSrc, onClose: () => setLightboxSrc(null) })
|
|
31179
|
+
] });
|
|
30719
31180
|
});
|
|
30720
31181
|
function ThinkingIndicator() {
|
|
30721
31182
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -30740,7 +31201,7 @@ function StreamingBubble() {
|
|
|
30740
31201
|
className: "max-w-[90%] rounded-2xl px-4 py-3 text-sm t-text assistant-bubble",
|
|
30741
31202
|
style: { background: "var(--color-bubble-assistant)" },
|
|
30742
31203
|
children: [
|
|
30743
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose", style: { color: "var(--color-text)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$
|
|
31204
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose", style: { color: "var(--color-text)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$3, children: text2 }) }),
|
|
30744
31205
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-block w-1.5 h-4 t-bg-accent-soft animate-pulse ml-0.5 align-text-bottom" })
|
|
30745
31206
|
]
|
|
30746
31207
|
}
|
|
@@ -31349,6 +31810,7 @@ function ChatInput() {
|
|
|
31349
31810
|
const [pendingImages, setPendingImages] = reactExports.useState([]);
|
|
31350
31811
|
const [pendingFiles, setPendingFiles] = reactExports.useState([]);
|
|
31351
31812
|
const [isDragOver, setIsDragOver] = reactExports.useState(false);
|
|
31813
|
+
const [lightboxSrc, setLightboxSrc] = reactExports.useState(null);
|
|
31352
31814
|
const textareaRef = reactExports.useRef(null);
|
|
31353
31815
|
const fileInputRef = reactExports.useRef(null);
|
|
31354
31816
|
const send = useChatStore((s15) => s15.send);
|
|
@@ -31366,23 +31828,17 @@ function ChatInput() {
|
|
|
31366
31828
|
const addImageFiles = reactExports.useCallback((files) => {
|
|
31367
31829
|
const imageFiles = files.filter((f) => ACCEPTED_IMAGE_TYPES.includes(f.type));
|
|
31368
31830
|
if (imageFiles.length === 0) return;
|
|
31369
|
-
|
|
31370
|
-
const
|
|
31371
|
-
|
|
31372
|
-
|
|
31373
|
-
|
|
31374
|
-
|
|
31375
|
-
|
|
31376
|
-
|
|
31377
|
-
|
|
31378
|
-
|
|
31379
|
-
|
|
31380
|
-
return [...p, { base64, mimeType: file.type, dataUrl }];
|
|
31381
|
-
});
|
|
31382
|
-
};
|
|
31383
|
-
reader.readAsDataURL(file);
|
|
31384
|
-
});
|
|
31385
|
-
return prev;
|
|
31831
|
+
imageFiles.forEach((file) => {
|
|
31832
|
+
const reader = new FileReader();
|
|
31833
|
+
reader.onload = () => {
|
|
31834
|
+
const dataUrl = reader.result;
|
|
31835
|
+
const base64 = dataUrl.split(",")[1];
|
|
31836
|
+
setPendingImages((p) => {
|
|
31837
|
+
if (p.length >= MAX_IMAGES) return p;
|
|
31838
|
+
return [...p, { base64, mimeType: file.type, dataUrl }];
|
|
31839
|
+
});
|
|
31840
|
+
};
|
|
31841
|
+
reader.readAsDataURL(file);
|
|
31386
31842
|
});
|
|
31387
31843
|
}, []);
|
|
31388
31844
|
const isDocFile = reactExports.useCallback((file) => {
|
|
@@ -31744,6 +32200,7 @@ ${s15.openQuestions.map((q2) => `- ${q2}`).join("\n")}`;
|
|
|
31744
32200
|
}
|
|
31745
32201
|
}, [text2]);
|
|
31746
32202
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
|
|
32203
|
+
lightboxSrc && /* @__PURE__ */ jsxRuntimeExports.jsx(ImageLightbox, { src: lightboxSrc, onClose: () => setLightboxSrc(null) }),
|
|
31747
32204
|
showMention && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31748
32205
|
MentionPopover,
|
|
31749
32206
|
{
|
|
@@ -31790,13 +32247,17 @@ ${s15.openQuestions.map((q2) => `- ${q2}`).join("\n")}`;
|
|
|
31790
32247
|
{
|
|
31791
32248
|
src: img.dataUrl,
|
|
31792
32249
|
alt: "",
|
|
31793
|
-
|
|
32250
|
+
onClick: () => setLightboxSrc(img.dataUrl),
|
|
32251
|
+
className: "h-16 w-16 object-cover rounded-lg border t-border cursor-pointer hover:opacity-90 transition-opacity"
|
|
31794
32252
|
}
|
|
31795
32253
|
),
|
|
31796
32254
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31797
32255
|
"button",
|
|
31798
32256
|
{
|
|
31799
|
-
onClick: () =>
|
|
32257
|
+
onClick: (e) => {
|
|
32258
|
+
e.stopPropagation();
|
|
32259
|
+
setPendingImages((prev) => prev.filter((_2, j2) => j2 !== i));
|
|
32260
|
+
},
|
|
31800
32261
|
className: "absolute -top-1.5 -right-1.5 w-4 h-4 rounded-full t-bg-error text-white text-[10px]\n leading-none flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity",
|
|
31801
32262
|
"aria-label": "Remove image",
|
|
31802
32263
|
children: "×"
|
|
@@ -31879,7 +32340,7 @@ ${s15.openQuestions.map((q2) => `- ${q2}`).join("\n")}`;
|
|
|
31879
32340
|
] });
|
|
31880
32341
|
}
|
|
31881
32342
|
const api$4 = window.api;
|
|
31882
|
-
const remarkPlugins$
|
|
32343
|
+
const remarkPlugins$2 = [remarkGfm];
|
|
31883
32344
|
function PaperFallback({ paper }) {
|
|
31884
32345
|
const authors = paper.authors || [];
|
|
31885
32346
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
|
|
@@ -32014,7 +32475,7 @@ ${body.trim()}
|
|
|
32014
32475
|
}
|
|
32015
32476
|
)
|
|
32016
32477
|
] }),
|
|
32017
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto px-4 py-3", onClick: handleLinkClick, children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text-muted animate-pulse", children: "Loading..." }) : isPaperFallback && fallbackPaper ? /* @__PURE__ */ jsxRuntimeExports.jsx(PaperFallback, { paper: fallbackPaper }) : processedContent ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose text-sm", style: { color: "var(--color-text)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$
|
|
32478
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto px-4 py-3", onClick: handleLinkClick, children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text-muted animate-pulse", children: "Loading..." }) : isPaperFallback && fallbackPaper ? /* @__PURE__ */ jsxRuntimeExports.jsx(PaperFallback, { paper: fallbackPaper }) : processedContent ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "md-prose text-sm", style: { color: "var(--color-text)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { remarkPlugins: remarkPlugins$2, children: processedContent }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text-muted", children: "No wiki page found for this slug." }) })
|
|
32018
32479
|
] });
|
|
32019
32480
|
}
|
|
32020
32481
|
function normalize(raw) {
|
|
@@ -32146,14 +32607,13 @@ function SortHeader({
|
|
|
32146
32607
|
}
|
|
32147
32608
|
);
|
|
32148
32609
|
}
|
|
32149
|
-
|
|
32150
|
-
|
|
32610
|
+
const PaperRow = React$2.memo(function PaperRow2({
|
|
32611
|
+
row,
|
|
32151
32612
|
expanded,
|
|
32152
|
-
onToggle,
|
|
32153
|
-
wikiSlug,
|
|
32154
32613
|
isActive,
|
|
32155
|
-
|
|
32614
|
+
onToggle
|
|
32156
32615
|
}) {
|
|
32616
|
+
const { paper, source, wikiSlug } = row;
|
|
32157
32617
|
const setWikiSlug = useUIStore((s15) => s15.setWikiReaderSlug);
|
|
32158
32618
|
const authors = paper.authors || [];
|
|
32159
32619
|
const authorStr = authors.length <= 3 ? authors.join(", ") : `${authors.slice(0, 2).join(", ")} et al.`;
|
|
@@ -32164,7 +32624,7 @@ function PaperRow({
|
|
|
32164
32624
|
"div",
|
|
32165
32625
|
{
|
|
32166
32626
|
className: `flex items-center gap-3 px-3 py-2 transition-colors cursor-pointer ${isActive ? "bg-[var(--color-accent-soft)]/10" : "hover:bg-[var(--color-accent-soft)]/5"}`,
|
|
32167
|
-
onClick: onToggle,
|
|
32627
|
+
onClick: () => onToggle(row),
|
|
32168
32628
|
children: [
|
|
32169
32629
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "shrink-0 t-text-muted", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 14 }) }),
|
|
32170
32630
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
@@ -32245,7 +32705,7 @@ function PaperRow({
|
|
|
32245
32705
|
] })
|
|
32246
32706
|
] })
|
|
32247
32707
|
] });
|
|
32248
|
-
}
|
|
32708
|
+
});
|
|
32249
32709
|
function WikiStatusPill() {
|
|
32250
32710
|
const [status, setStatus] = reactExports.useState(null);
|
|
32251
32711
|
reactExports.useEffect(() => {
|
|
@@ -32424,6 +32884,14 @@ function LiteratureView() {
|
|
|
32424
32884
|
const wikiReaderSlug = useUIStore((s15) => s15.wikiReaderSlug);
|
|
32425
32885
|
const setWikiSlug = useUIStore((s15) => s15.setWikiReaderSlug);
|
|
32426
32886
|
const [expandedKey, setExpandedKey] = reactExports.useState(null);
|
|
32887
|
+
const handleRowToggle = reactExports.useCallback((row) => {
|
|
32888
|
+
setExpandedKey((prev) => prev === row.key ? null : row.key);
|
|
32889
|
+
if (row.source === "wiki") {
|
|
32890
|
+
setWikiSlug(row.wikiSlug);
|
|
32891
|
+
} else {
|
|
32892
|
+
setWikiSlug(row.wikiSlug || `paper:${row.paper.id}`);
|
|
32893
|
+
}
|
|
32894
|
+
}, [setWikiSlug]);
|
|
32427
32895
|
const [wikiSlugs, setWikiSlugs] = reactExports.useState({});
|
|
32428
32896
|
const [wikiMeta, setWikiMeta] = reactExports.useState([]);
|
|
32429
32897
|
reactExports.useEffect(() => {
|
|
@@ -32615,19 +33083,10 @@ function LiteratureView() {
|
|
|
32615
33083
|
] }) : filteredRows.map((row) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32616
33084
|
PaperRow,
|
|
32617
33085
|
{
|
|
32618
|
-
|
|
32619
|
-
source: row.source,
|
|
33086
|
+
row,
|
|
32620
33087
|
expanded: expandedKey === row.key,
|
|
32621
33088
|
isActive: activeRowKey === row.key,
|
|
32622
|
-
onToggle:
|
|
32623
|
-
setExpandedKey(expandedKey === row.key ? null : row.key);
|
|
32624
|
-
if (row.source === "wiki") {
|
|
32625
|
-
setWikiSlug(row.wikiSlug);
|
|
32626
|
-
} else {
|
|
32627
|
-
setWikiSlug(row.wikiSlug || `paper:${row.paper.id}`);
|
|
32628
|
-
}
|
|
32629
|
-
},
|
|
32630
|
-
wikiSlug: row.wikiSlug
|
|
33089
|
+
onToggle: handleRowToggle
|
|
32631
33090
|
},
|
|
32632
33091
|
row.key
|
|
32633
33092
|
)) })
|
|
@@ -32986,95 +33445,135 @@ function ComputeView() {
|
|
|
32986
33445
|
!isEmpty && /* @__PURE__ */ jsxRuntimeExports.jsx(CoverageBar, { runs: allRuns })
|
|
32987
33446
|
] });
|
|
32988
33447
|
}
|
|
32989
|
-
|
|
32990
|
-
|
|
32991
|
-
|
|
32992
|
-
|
|
32993
|
-
|
|
32994
|
-
|
|
32995
|
-
|
|
32996
|
-
|
|
32997
|
-
|
|
32998
|
-
|
|
32999
|
-
|
|
33000
|
-
|
|
33001
|
-
|
|
33002
|
-
|
|
33003
|
-
|
|
33004
|
-
|
|
33005
|
-
|
|
33006
|
-
|
|
33007
|
-
|
|
33008
|
-
|
|
33009
|
-
|
|
33010
|
-
|
|
33011
|
-
|
|
33012
|
-
|
|
33013
|
-
|
|
33014
|
-
|
|
33015
|
-
|
|
33016
|
-
|
|
33017
|
-
|
|
33018
|
-
|
|
33019
|
-
|
|
33020
|
-
|
|
33021
|
-
|
|
33022
|
-
|
|
33023
|
-
|
|
33024
|
-
|
|
33025
|
-
|
|
33026
|
-
|
|
33027
|
-
|
|
33028
|
-
|
|
33029
|
-
|
|
33030
|
-
|
|
33031
|
-
|
|
33032
|
-
className: `inline-flex items-center px-1 py-0 rounded border text-[9.5px] font-mono leading-[1.4] transition-colors ${isActive ? "t-border-accent-soft t-text-accent-soft bg-transparent" : "t-border-subtle t-bg-elevated t-text-muted group-hover:t-text-secondary"}`,
|
|
33033
|
-
children: shortcut
|
|
33034
|
-
}
|
|
33035
|
-
),
|
|
33036
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33037
|
-
"span",
|
|
33038
|
-
{
|
|
33039
|
-
"aria-hidden": true,
|
|
33040
|
-
className: `pointer-events-none absolute left-0 right-0 -bottom-px h-[2px] transition-colors ${isActive ? "t-bg-accent" : "bg-transparent"}`
|
|
33041
|
-
}
|
|
33042
|
-
)
|
|
33043
|
-
]
|
|
33044
|
-
},
|
|
33045
|
-
key
|
|
33046
|
-
);
|
|
33047
|
-
})
|
|
33048
|
-
}
|
|
33049
|
-
)
|
|
33050
|
-
);
|
|
33051
|
-
}
|
|
33052
|
-
function CenterPanel() {
|
|
33053
|
-
const centerView = useUIStore((s15) => s15.centerView);
|
|
33054
|
-
const isIdle = useUIStore((s15) => s15.isIdle);
|
|
33055
|
-
const messages = useChatStore((s15) => s15.messages);
|
|
33056
|
-
const showHero = isIdle && messages.length === 0;
|
|
33057
|
-
if (centerView === "literature") {
|
|
33058
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { id: "main-content", className: "flex-1 flex flex-col min-w-0", children: [
|
|
33059
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewSwitcher, {}),
|
|
33060
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(LiteratureView, {})
|
|
33061
|
-
] });
|
|
33448
|
+
function resolveMarkdownImageUrl(src, baseDir) {
|
|
33449
|
+
if (!src) return "";
|
|
33450
|
+
if (/^(?:https?:|data:|blob:|workspace-asset:|file:)/i.test(src)) return src;
|
|
33451
|
+
let absPath = null;
|
|
33452
|
+
if (src.startsWith("/")) {
|
|
33453
|
+
absPath = src;
|
|
33454
|
+
} else if (baseDir) {
|
|
33455
|
+
try {
|
|
33456
|
+
const normalizedBase = baseDir.endsWith("/") ? baseDir : baseDir + "/";
|
|
33457
|
+
const resolved = new URL(src, `file://${normalizedBase}`);
|
|
33458
|
+
absPath = decodeURIComponent(resolved.pathname);
|
|
33459
|
+
} catch {
|
|
33460
|
+
absPath = null;
|
|
33461
|
+
}
|
|
33462
|
+
}
|
|
33463
|
+
if (!absPath) return src;
|
|
33464
|
+
return `workspace-asset://asset${encodeURI(absPath)}`;
|
|
33465
|
+
}
|
|
33466
|
+
function dirnameOf(filePath) {
|
|
33467
|
+
if (!filePath) return void 0;
|
|
33468
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
33469
|
+
const idx = normalized.lastIndexOf("/");
|
|
33470
|
+
if (idx < 0) return void 0;
|
|
33471
|
+
return normalized.slice(0, idx);
|
|
33472
|
+
}
|
|
33473
|
+
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
33474
|
+
function splitFrontmatter(markdown) {
|
|
33475
|
+
if (!markdown) return { frontmatterBlock: null, body: markdown ?? "" };
|
|
33476
|
+
const match = markdown.match(FRONTMATTER_RE);
|
|
33477
|
+
if (!match) return { frontmatterBlock: null, body: markdown };
|
|
33478
|
+
return { frontmatterBlock: match[0], body: markdown.slice(match[0].length) };
|
|
33479
|
+
}
|
|
33480
|
+
function parseFrontmatterPairs(block) {
|
|
33481
|
+
const out = {};
|
|
33482
|
+
if (!block) return out;
|
|
33483
|
+
const inner = block.match(FRONTMATTER_RE)?.[1] ?? "";
|
|
33484
|
+
for (const rawLine of inner.split("\n")) {
|
|
33485
|
+
const line = rawLine.trim();
|
|
33486
|
+
if (!line || line.startsWith("#")) continue;
|
|
33487
|
+
const colonIdx = line.indexOf(":");
|
|
33488
|
+
if (colonIdx < 0) continue;
|
|
33489
|
+
const key = line.slice(0, colonIdx).trim();
|
|
33490
|
+
if (key) out[key] = line.slice(colonIdx + 1).trim();
|
|
33062
33491
|
}
|
|
33063
|
-
|
|
33064
|
-
|
|
33065
|
-
|
|
33066
|
-
|
|
33067
|
-
|
|
33492
|
+
return out;
|
|
33493
|
+
}
|
|
33494
|
+
function isMarpFrontmatter(block) {
|
|
33495
|
+
const pairs = parseFrontmatterPairs(block);
|
|
33496
|
+
return /^(?:true|yes|on)$/i.test(pairs.marp || "");
|
|
33497
|
+
}
|
|
33498
|
+
const THEMATIC_BREAK_RE = /^[ \t]{0,3}(?:-{3,}|\*{3,}|_{3,})[ \t]*\r?$/m;
|
|
33499
|
+
function splitSlides(body) {
|
|
33500
|
+
return body.split(THEMATIC_BREAK_RE).map((chunk) => chunk.trim()).filter((chunk) => chunk.length > 0);
|
|
33501
|
+
}
|
|
33502
|
+
const remarkPlugins$1 = [remarkGfm];
|
|
33503
|
+
function MarpSlideView({ slides, baseDir }) {
|
|
33504
|
+
if (slides.length === 0) {
|
|
33505
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text-muted", children: "No slides detected. Switch to source view to inspect the markdown." });
|
|
33068
33506
|
}
|
|
33069
|
-
return /* @__PURE__ */ jsxRuntimeExports.
|
|
33070
|
-
|
|
33071
|
-
|
|
33072
|
-
|
|
33073
|
-
|
|
33507
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-4", children: slides.map((slide, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
33508
|
+
"article",
|
|
33509
|
+
{
|
|
33510
|
+
className: "relative t-bg-surface border t-border rounded-lg shadow-sm overflow-hidden",
|
|
33511
|
+
style: { aspectRatio: "16 / 9", minHeight: 200 },
|
|
33512
|
+
"aria-label": `Slide ${index2 + 1} of ${slides.length}`,
|
|
33513
|
+
children: [
|
|
33514
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute top-2 right-3 text-[10px] font-mono tabular-nums t-text-muted z-10", children: [
|
|
33515
|
+
index2 + 1,
|
|
33516
|
+
" / ",
|
|
33517
|
+
slides.length
|
|
33518
|
+
] }),
|
|
33519
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33520
|
+
"div",
|
|
33521
|
+
{
|
|
33522
|
+
className: "md-prose h-full overflow-auto px-6 py-5",
|
|
33523
|
+
style: { color: "var(--color-text)", fontSize: "14px", lineHeight: 1.5 },
|
|
33524
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33525
|
+
Markdown,
|
|
33526
|
+
{
|
|
33527
|
+
remarkPlugins: remarkPlugins$1,
|
|
33528
|
+
components: {
|
|
33529
|
+
img: ({ src, alt, ...rest }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33530
|
+
"img",
|
|
33531
|
+
{
|
|
33532
|
+
src: resolveMarkdownImageUrl(src, baseDir),
|
|
33533
|
+
alt,
|
|
33534
|
+
...rest
|
|
33535
|
+
}
|
|
33536
|
+
)
|
|
33537
|
+
},
|
|
33538
|
+
children: slide
|
|
33539
|
+
}
|
|
33540
|
+
)
|
|
33541
|
+
}
|
|
33542
|
+
)
|
|
33543
|
+
]
|
|
33544
|
+
},
|
|
33545
|
+
index2
|
|
33546
|
+
)) });
|
|
33074
33547
|
}
|
|
33075
33548
|
const remarkPlugins = [remarkGfm];
|
|
33549
|
+
const NAVIGABLE_FILE_EXTS = /* @__PURE__ */ new Set([
|
|
33550
|
+
"md",
|
|
33551
|
+
"txt",
|
|
33552
|
+
"json",
|
|
33553
|
+
"ts",
|
|
33554
|
+
"js",
|
|
33555
|
+
"css",
|
|
33556
|
+
"yml",
|
|
33557
|
+
"yaml",
|
|
33558
|
+
"toml",
|
|
33559
|
+
"env",
|
|
33560
|
+
"sh",
|
|
33561
|
+
"py",
|
|
33562
|
+
"cfg",
|
|
33563
|
+
"ini",
|
|
33564
|
+
"log",
|
|
33565
|
+
"csv",
|
|
33566
|
+
"xml",
|
|
33567
|
+
"rst",
|
|
33568
|
+
"jsx",
|
|
33569
|
+
"tsx",
|
|
33570
|
+
"mjs",
|
|
33571
|
+
"cjs",
|
|
33572
|
+
"markdown",
|
|
33573
|
+
"gitignore"
|
|
33574
|
+
]);
|
|
33076
33575
|
const LazyMilkdownMarkdownEditor = reactExports.lazy(async () => {
|
|
33077
|
-
const mod = await __vitePreload(() => import("./MilkdownMarkdownEditor-
|
|
33576
|
+
const mod = await __vitePreload(() => import("./MilkdownMarkdownEditor-OhCrq3X0.js").then((n) => n.bL), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
|
|
33078
33577
|
return { default: mod.MilkdownMarkdownEditor };
|
|
33079
33578
|
});
|
|
33080
33579
|
const typeIcons = {
|
|
@@ -33185,6 +33684,9 @@ function CsvPreview({ content: content2, separator }) {
|
|
|
33185
33684
|
] })
|
|
33186
33685
|
] });
|
|
33187
33686
|
}
|
|
33687
|
+
function normalizePathSep(p) {
|
|
33688
|
+
return p.replace(/\\/g, "/");
|
|
33689
|
+
}
|
|
33188
33690
|
function usePreviewNavigation() {
|
|
33189
33691
|
const previewSourceTab = useUIStore((s15) => s15.previewSourceTab);
|
|
33190
33692
|
const previewEntity = useUIStore((s15) => s15.previewEntity);
|
|
@@ -33192,6 +33694,71 @@ function usePreviewNavigation() {
|
|
|
33192
33694
|
const notes = useEntityStore((s15) => s15.notes);
|
|
33193
33695
|
const papers = useEntityStore((s15) => s15.papers);
|
|
33194
33696
|
const data = useEntityStore((s15) => s15.data);
|
|
33697
|
+
const projectPath = useSessionStore((s15) => s15.projectPath);
|
|
33698
|
+
const [fileSiblings, setFileSiblings] = reactExports.useState([]);
|
|
33699
|
+
const currentFilePath = previewSourceTab === "files" ? previewEntity?.filePath : void 0;
|
|
33700
|
+
reactExports.useEffect(() => {
|
|
33701
|
+
if (!currentFilePath || !projectPath) {
|
|
33702
|
+
setFileSiblings([]);
|
|
33703
|
+
return;
|
|
33704
|
+
}
|
|
33705
|
+
const absFile = normalizePathSep(currentFilePath);
|
|
33706
|
+
const absProj = normalizePathSep(projectPath);
|
|
33707
|
+
let relParent;
|
|
33708
|
+
if (absFile === absProj) {
|
|
33709
|
+
relParent = "";
|
|
33710
|
+
} else if (absFile.startsWith(absProj + "/")) {
|
|
33711
|
+
const rel = absFile.slice(absProj.length + 1);
|
|
33712
|
+
relParent = rel.includes("/") ? rel.slice(0, rel.lastIndexOf("/")) : "";
|
|
33713
|
+
} else {
|
|
33714
|
+
setFileSiblings([]);
|
|
33715
|
+
return;
|
|
33716
|
+
}
|
|
33717
|
+
let cancelled = false;
|
|
33718
|
+
const api2 = window.api;
|
|
33719
|
+
Promise.resolve(api2.listTree({ relativePath: relParent, showIgnored: true, limit: 2e3 })).then((nodes) => {
|
|
33720
|
+
if (cancelled || !Array.isArray(nodes)) return;
|
|
33721
|
+
const siblings = [];
|
|
33722
|
+
for (const n of nodes) {
|
|
33723
|
+
if (n.type !== "file") continue;
|
|
33724
|
+
const ext = (n.name.split(".").pop() || "").toLowerCase();
|
|
33725
|
+
if (!NAVIGABLE_FILE_EXTS.has(ext)) continue;
|
|
33726
|
+
siblings.push({ name: n.name, path: n.path, modifiedAt: n.modifiedAt || Date.now() });
|
|
33727
|
+
}
|
|
33728
|
+
setFileSiblings(siblings);
|
|
33729
|
+
}).catch(() => {
|
|
33730
|
+
if (!cancelled) setFileSiblings([]);
|
|
33731
|
+
});
|
|
33732
|
+
return () => {
|
|
33733
|
+
cancelled = true;
|
|
33734
|
+
};
|
|
33735
|
+
}, [currentFilePath, projectPath]);
|
|
33736
|
+
const entityForFilePath = reactExports.useCallback((filePath, displayName, modifiedAt) => {
|
|
33737
|
+
const norm = normalizePathSep(filePath);
|
|
33738
|
+
const existing = data.find((item) => normalizePathSep(item.filePath || "") === norm);
|
|
33739
|
+
if (existing) {
|
|
33740
|
+
return {
|
|
33741
|
+
...existing,
|
|
33742
|
+
type: "data",
|
|
33743
|
+
title: existing.title || existing.name || displayName,
|
|
33744
|
+
filePath
|
|
33745
|
+
};
|
|
33746
|
+
}
|
|
33747
|
+
const iso = new Date(modifiedAt || Date.now()).toISOString();
|
|
33748
|
+
return {
|
|
33749
|
+
id: filePath,
|
|
33750
|
+
type: "data",
|
|
33751
|
+
title: displayName,
|
|
33752
|
+
filePath,
|
|
33753
|
+
tags: [],
|
|
33754
|
+
createdAt: iso,
|
|
33755
|
+
updatedAt: iso
|
|
33756
|
+
};
|
|
33757
|
+
}, [data]);
|
|
33758
|
+
const fileSiblingEntities = reactExports.useMemo(
|
|
33759
|
+
() => fileSiblings.map((s15) => entityForFilePath(s15.path, s15.name, s15.modifiedAt)),
|
|
33760
|
+
[fileSiblings, entityForFilePath]
|
|
33761
|
+
);
|
|
33195
33762
|
const list2 = (() => {
|
|
33196
33763
|
switch (previewSourceTab) {
|
|
33197
33764
|
case "library":
|
|
@@ -33199,11 +33766,19 @@ function usePreviewNavigation() {
|
|
|
33199
33766
|
case "papers":
|
|
33200
33767
|
return papers;
|
|
33201
33768
|
case "files":
|
|
33769
|
+
return fileSiblingEntities;
|
|
33202
33770
|
default:
|
|
33203
33771
|
return [];
|
|
33204
33772
|
}
|
|
33205
33773
|
})();
|
|
33206
|
-
const currentIndex =
|
|
33774
|
+
const currentIndex = (() => {
|
|
33775
|
+
if (!previewEntity) return -1;
|
|
33776
|
+
if (previewSourceTab === "files" && previewEntity.filePath) {
|
|
33777
|
+
const target = normalizePathSep(previewEntity.filePath);
|
|
33778
|
+
return list2.findIndex((item) => normalizePathSep(item.filePath || "") === target);
|
|
33779
|
+
}
|
|
33780
|
+
return list2.findIndex((item) => item.id === previewEntity.id);
|
|
33781
|
+
})();
|
|
33207
33782
|
const total = list2.length;
|
|
33208
33783
|
const canNavigate = total > 1 && currentIndex >= 0;
|
|
33209
33784
|
const goNext = reactExports.useCallback(() => {
|
|
@@ -33222,12 +33797,35 @@ function EntityPreviewPanel() {
|
|
|
33222
33797
|
const rawEntity = useUIStore((s15) => s15.previewEntity);
|
|
33223
33798
|
const closePreview = useUIStore((s15) => s15.closePreview);
|
|
33224
33799
|
const setPreviewEditorFocused = useUIStore((s15) => s15.setPreviewEditorFocused);
|
|
33225
|
-
const
|
|
33800
|
+
const drawerWidth = useUIStore((s15) => s15.drawerWidth);
|
|
33801
|
+
const setDrawerWidth = useUIStore((s15) => s15.setDrawerWidth);
|
|
33226
33802
|
const refreshAll = useEntityStore((s15) => s15.refreshAll);
|
|
33227
33803
|
const previewEditorFocused = useUIStore((s15) => s15.previewEditorFocused);
|
|
33228
33804
|
const nav = usePreviewNavigation();
|
|
33805
|
+
const dragStateRef = reactExports.useRef(null);
|
|
33806
|
+
const handleEdgeMouseDown = reactExports.useCallback((e) => {
|
|
33807
|
+
dragStateRef.current = { startX: e.clientX, startWidth: drawerWidth };
|
|
33808
|
+
document.body.style.cursor = "ew-resize";
|
|
33809
|
+
e.preventDefault();
|
|
33810
|
+
}, [drawerWidth]);
|
|
33811
|
+
reactExports.useEffect(() => {
|
|
33812
|
+
const onMove = (e) => {
|
|
33813
|
+
if (!dragStateRef.current) return;
|
|
33814
|
+
const dx = dragStateRef.current.startX - e.clientX;
|
|
33815
|
+
setDrawerWidth(dragStateRef.current.startWidth + dx);
|
|
33816
|
+
};
|
|
33817
|
+
const onUp = () => {
|
|
33818
|
+
if (dragStateRef.current) document.body.style.cursor = "";
|
|
33819
|
+
dragStateRef.current = null;
|
|
33820
|
+
};
|
|
33821
|
+
window.addEventListener("mousemove", onMove);
|
|
33822
|
+
window.addEventListener("mouseup", onUp);
|
|
33823
|
+
return () => {
|
|
33824
|
+
window.removeEventListener("mousemove", onMove);
|
|
33825
|
+
window.removeEventListener("mouseup", onUp);
|
|
33826
|
+
};
|
|
33827
|
+
}, [setDrawerWidth]);
|
|
33229
33828
|
const entity = rawEntity ? { ...rawEntity } : null;
|
|
33230
|
-
const [confirmDelete, setConfirmDelete] = reactExports.useState(false);
|
|
33231
33829
|
const [draftMarkdown, setDraftMarkdown] = reactExports.useState("");
|
|
33232
33830
|
const [baselineMarkdown, setBaselineMarkdown] = reactExports.useState("");
|
|
33233
33831
|
const [editorSeedMarkdown, setEditorSeedMarkdown] = reactExports.useState("");
|
|
@@ -33237,6 +33835,7 @@ function EntityPreviewPanel() {
|
|
|
33237
33835
|
const [fileType, setFileType] = reactExports.useState(null);
|
|
33238
33836
|
const [loading, setLoading] = reactExports.useState(false);
|
|
33239
33837
|
const [externalMarkdown, setExternalMarkdown] = reactExports.useState(void 0);
|
|
33838
|
+
const [viewModeOverride, setViewModeOverride] = reactExports.useState(null);
|
|
33240
33839
|
const resolvedAbsPathRef = reactExports.useRef(null);
|
|
33241
33840
|
const baselineRef = reactExports.useRef("");
|
|
33242
33841
|
const getArtifactMarkdownContent = (artifactLike) => {
|
|
@@ -33259,6 +33858,7 @@ function EntityPreviewPanel() {
|
|
|
33259
33858
|
setSaveError(null);
|
|
33260
33859
|
setSaveSuccess(null);
|
|
33261
33860
|
setPreviewEditorFocused(false);
|
|
33861
|
+
setViewModeOverride(null);
|
|
33262
33862
|
}, [entity?.id]);
|
|
33263
33863
|
reactExports.useEffect(() => {
|
|
33264
33864
|
setFileContent(null);
|
|
@@ -33299,6 +33899,11 @@ function EntityPreviewPanel() {
|
|
|
33299
33899
|
reactExports.useEffect(() => {
|
|
33300
33900
|
baselineRef.current = baselineMarkdown;
|
|
33301
33901
|
}, [baselineMarkdown]);
|
|
33902
|
+
const scrollContentRef = reactExports.useRef(null);
|
|
33903
|
+
const modeScrollRef = reactExports.useRef({ source: 0, slides: 0 });
|
|
33904
|
+
reactExports.useEffect(() => {
|
|
33905
|
+
modeScrollRef.current = { source: 0, slides: 0 };
|
|
33906
|
+
}, [entity?.id]);
|
|
33302
33907
|
reactExports.useEffect(() => {
|
|
33303
33908
|
if (!entity?.filePath) return;
|
|
33304
33909
|
const ext = getExtension(entity.filePath);
|
|
@@ -33343,7 +33948,48 @@ function EntityPreviewPanel() {
|
|
|
33343
33948
|
const isInlineEditable = !entity.filePath;
|
|
33344
33949
|
const isEditable = isInlineEditable || isFileMarkdown;
|
|
33345
33950
|
const isDirty = isEditable && normalizeMarkdown(draftMarkdown) !== normalizeMarkdown(baselineMarkdown);
|
|
33346
|
-
const
|
|
33951
|
+
const { frontmatterBlock, body: baselineBody } = reactExports.useMemo(
|
|
33952
|
+
() => splitFrontmatter(baselineMarkdown),
|
|
33953
|
+
[baselineMarkdown]
|
|
33954
|
+
);
|
|
33955
|
+
const isMarpFile = reactExports.useMemo(() => isMarpFrontmatter(frontmatterBlock), [frontmatterBlock]);
|
|
33956
|
+
const draftBody = reactExports.useMemo(() => {
|
|
33957
|
+
if (!frontmatterBlock) return draftMarkdown;
|
|
33958
|
+
return draftMarkdown.startsWith(frontmatterBlock) ? draftMarkdown.slice(frontmatterBlock.length) : splitFrontmatter(draftMarkdown).body;
|
|
33959
|
+
}, [draftMarkdown, frontmatterBlock]);
|
|
33960
|
+
const editorSeedBody = reactExports.useMemo(() => splitFrontmatter(editorSeedMarkdown).body, [editorSeedMarkdown]);
|
|
33961
|
+
const externalBody = reactExports.useMemo(() => {
|
|
33962
|
+
if (externalMarkdown === void 0) return void 0;
|
|
33963
|
+
return splitFrontmatter(externalMarkdown).body;
|
|
33964
|
+
}, [externalMarkdown]);
|
|
33965
|
+
const slides = reactExports.useMemo(
|
|
33966
|
+
() => isMarpFile ? splitSlides(draftBody) : [],
|
|
33967
|
+
[isMarpFile, draftBody]
|
|
33968
|
+
);
|
|
33969
|
+
const effectiveViewMode = viewModeOverride ?? (isMarpFile ? "slides" : "source");
|
|
33970
|
+
const showSlideView = isMarpFile && effectiveViewMode === "slides";
|
|
33971
|
+
reactExports.useEffect(() => {
|
|
33972
|
+
const el2 = scrollContentRef.current;
|
|
33973
|
+
if (!el2) return;
|
|
33974
|
+
const onScroll = () => {
|
|
33975
|
+
modeScrollRef.current[effectiveViewMode] = el2.scrollTop;
|
|
33976
|
+
};
|
|
33977
|
+
el2.addEventListener("scroll", onScroll, { passive: true });
|
|
33978
|
+
return () => el2.removeEventListener("scroll", onScroll);
|
|
33979
|
+
}, [effectiveViewMode]);
|
|
33980
|
+
reactExports.useEffect(() => {
|
|
33981
|
+
const target = modeScrollRef.current[effectiveViewMode] ?? 0;
|
|
33982
|
+
const apply = () => {
|
|
33983
|
+
if (scrollContentRef.current) scrollContentRef.current.scrollTop = target;
|
|
33984
|
+
};
|
|
33985
|
+
const raf = requestAnimationFrame(apply);
|
|
33986
|
+
const retry = window.setTimeout(apply, 200);
|
|
33987
|
+
return () => {
|
|
33988
|
+
cancelAnimationFrame(raf);
|
|
33989
|
+
window.clearTimeout(retry);
|
|
33990
|
+
};
|
|
33991
|
+
}, [effectiveViewMode, entity?.id]);
|
|
33992
|
+
const seedFp = buildFingerprint(editorSeedBody);
|
|
33347
33993
|
const editorKey = `${entity.id}:${entity.filePath ?? "inline"}:${seedFp.length}:${seedFp.codeFenceCount}:${seedFp.mermaidFenceCount}:${seedFp.mathBlockCount}:${seedFp.imageCount}`;
|
|
33348
33994
|
const handleNavNext = reactExports.useCallback(() => {
|
|
33349
33995
|
if (!nav.canNavigate) return;
|
|
@@ -33376,15 +34022,6 @@ function EntityPreviewPanel() {
|
|
|
33376
34022
|
window.addEventListener("keydown", handler);
|
|
33377
34023
|
return () => window.removeEventListener("keydown", handler);
|
|
33378
34024
|
}, [nav.canNavigate, previewEditorFocused, handleNavPrev, handleNavNext]);
|
|
33379
|
-
const handleDelete2 = async () => {
|
|
33380
|
-
if (!confirmDelete) {
|
|
33381
|
-
setConfirmDelete(true);
|
|
33382
|
-
setTimeout(() => setConfirmDelete(false), 2e3);
|
|
33383
|
-
return;
|
|
33384
|
-
}
|
|
33385
|
-
await deleteEntity(entity.id);
|
|
33386
|
-
closePreview();
|
|
33387
|
-
};
|
|
33388
34025
|
const handleSave = async () => {
|
|
33389
34026
|
if (!isEditable || !isDirty) return;
|
|
33390
34027
|
const nextMarkdown = draftMarkdown;
|
|
@@ -33465,10 +34102,11 @@ Save anyway?`
|
|
|
33465
34102
|
LazyMilkdownMarkdownEditor,
|
|
33466
34103
|
{
|
|
33467
34104
|
editorId: editorKey,
|
|
33468
|
-
initialMarkdown:
|
|
33469
|
-
externalMarkdown,
|
|
34105
|
+
initialMarkdown: baselineBody,
|
|
34106
|
+
externalMarkdown: externalBody,
|
|
34107
|
+
baseDir: dirnameOf(entity.filePath),
|
|
33470
34108
|
onChange: (markdown) => {
|
|
33471
|
-
setDraftMarkdown(markdown);
|
|
34109
|
+
setDraftMarkdown((frontmatterBlock ?? "") + markdown);
|
|
33472
34110
|
if (saveError) setSaveError(null);
|
|
33473
34111
|
},
|
|
33474
34112
|
onFocusChange: setPreviewEditorFocused,
|
|
@@ -33511,6 +34149,9 @@ Save anyway?`
|
|
|
33511
34149
|
const ext = getExtension(entity.filePath);
|
|
33512
34150
|
const isMarkdown = ext === "md" || ext === "markdown";
|
|
33513
34151
|
if (isMarkdown) {
|
|
34152
|
+
if (showSlideView) {
|
|
34153
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(MarpSlideView, { slides, baseDir: dirnameOf(entity.filePath) });
|
|
34154
|
+
}
|
|
33514
34155
|
return renderMarkdownEditor();
|
|
33515
34156
|
}
|
|
33516
34157
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs whitespace-pre-wrap break-words t-text font-mono leading-relaxed", children: fileContent });
|
|
@@ -33518,142 +34159,368 @@ Save anyway?`
|
|
|
33518
34159
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs t-text-muted", children: entity.filePath });
|
|
33519
34160
|
}
|
|
33520
34161
|
if (isInlineEditable) {
|
|
34162
|
+
if (showSlideView) {
|
|
34163
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(MarpSlideView, { slides, baseDir: dirnameOf(entity.filePath) });
|
|
34164
|
+
}
|
|
33521
34165
|
return renderMarkdownEditor();
|
|
33522
34166
|
}
|
|
33523
34167
|
const content2 = entity.content || entity.abstract || entity.valueText || "No content available.";
|
|
33524
|
-
|
|
33525
|
-
|
|
33526
|
-
|
|
33527
|
-
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
|
|
33532
|
-
|
|
33533
|
-
|
|
33534
|
-
|
|
33535
|
-
|
|
33536
|
-
|
|
33537
|
-
title: "Previous item (Alt+Up)",
|
|
33538
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { size: 14 })
|
|
33539
|
-
}
|
|
33540
|
-
),
|
|
33541
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] t-text-muted tabular-nums min-w-[2.5rem] text-center", children: [
|
|
33542
|
-
nav.currentIndex + 1,
|
|
33543
|
-
" / ",
|
|
33544
|
-
nav.total
|
|
33545
|
-
] }),
|
|
33546
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33547
|
-
"button",
|
|
34168
|
+
const mdBaseDir = dirnameOf(entity.filePath);
|
|
34169
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34170
|
+
"div",
|
|
34171
|
+
{
|
|
34172
|
+
className: "md-prose",
|
|
34173
|
+
style: {
|
|
34174
|
+
color: "var(--color-text)",
|
|
34175
|
+
fontFamily: READING_FONT,
|
|
34176
|
+
fontSize: "14px",
|
|
34177
|
+
lineHeight: 1.55
|
|
34178
|
+
},
|
|
34179
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34180
|
+
Markdown,
|
|
33548
34181
|
{
|
|
33549
|
-
|
|
33550
|
-
|
|
33551
|
-
|
|
33552
|
-
|
|
34182
|
+
remarkPlugins,
|
|
34183
|
+
components: {
|
|
34184
|
+
// Rewrite relative / absolute disk paths to workspace-asset://
|
|
34185
|
+
// URLs so images actually load. Remote URLs pass through.
|
|
34186
|
+
img: ({ src, alt, ...rest }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34187
|
+
"img",
|
|
34188
|
+
{
|
|
34189
|
+
src: resolveMarkdownImageUrl(src, mdBaseDir),
|
|
34190
|
+
alt,
|
|
34191
|
+
...rest
|
|
34192
|
+
}
|
|
34193
|
+
)
|
|
34194
|
+
},
|
|
34195
|
+
children: typeof content2 === "string" ? content2 : JSON.stringify(content2, null, 2)
|
|
33553
34196
|
}
|
|
33554
34197
|
)
|
|
33555
|
-
|
|
33556
|
-
|
|
33557
|
-
|
|
33558
|
-
|
|
33559
|
-
|
|
33560
|
-
|
|
33561
|
-
|
|
33562
|
-
|
|
33563
|
-
|
|
33564
|
-
|
|
33565
|
-
|
|
33566
|
-
|
|
33567
|
-
|
|
33568
|
-
"button",
|
|
33569
|
-
{
|
|
33570
|
-
onClick: handleDelete2,
|
|
33571
|
-
className: `p-1 rounded transition-colors ${confirmDelete ? "t-text-error" : "t-text-muted t-bg-hover"}`,
|
|
33572
|
-
title: confirmDelete ? "Click again to confirm delete" : "Delete",
|
|
33573
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { size: 14 })
|
|
33574
|
-
}
|
|
33575
|
-
),
|
|
34198
|
+
}
|
|
34199
|
+
);
|
|
34200
|
+
};
|
|
34201
|
+
const drawerBoxShadow = "inset 3px 0 0 0 var(--color-accent), -12px 0 32px -14px rgba(0,0,0,0.18)";
|
|
34202
|
+
const crumb = entity.filePath ? `files · ${(getExtension(entity.filePath) || "file").toLowerCase()}` : `library · ${entity.type}`;
|
|
34203
|
+
const READING_FONT = '"Iowan Old Style", "Charter", "Sitka Text", Georgia, serif';
|
|
34204
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
34205
|
+
"div",
|
|
34206
|
+
{
|
|
34207
|
+
className: "absolute top-0 right-0 bottom-0 flex flex-col t-bg-base min-w-0 z-[5] pt-10 transition-[width,box-shadow] duration-500 ease-[cubic-bezier(0.32,0.72,0.24,1)]",
|
|
34208
|
+
style: { width: drawerWidth, boxShadow: drawerBoxShadow },
|
|
34209
|
+
"aria-label": `Preview: ${entity.title}`,
|
|
34210
|
+
children: [
|
|
33576
34211
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33577
|
-
"
|
|
34212
|
+
"div",
|
|
33578
34213
|
{
|
|
33579
|
-
|
|
33580
|
-
|
|
33581
|
-
|
|
33582
|
-
|
|
34214
|
+
className: "absolute left-0 top-0 bottom-0 w-[6px] cursor-ew-resize group z-[6]",
|
|
34215
|
+
style: { marginLeft: -3 },
|
|
34216
|
+
onMouseDown: handleEdgeMouseDown,
|
|
34217
|
+
title: "Drag to resize",
|
|
34218
|
+
"aria-hidden": "true",
|
|
34219
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-[3px] top-1/2 -translate-y-1/2 w-[2px] h-9 rounded bg-transparent group-hover:t-bg-accent transition-colors" })
|
|
33583
34220
|
}
|
|
33584
|
-
)
|
|
33585
|
-
|
|
33586
|
-
|
|
33587
|
-
|
|
33588
|
-
|
|
33589
|
-
|
|
33590
|
-
|
|
33591
|
-
|
|
33592
|
-
|
|
33593
|
-
|
|
33594
|
-
|
|
33595
|
-
|
|
33596
|
-
|
|
33597
|
-
|
|
33598
|
-
|
|
33599
|
-
|
|
33600
|
-
|
|
33601
|
-
|
|
33602
|
-
|
|
33603
|
-
|
|
33604
|
-
|
|
33605
|
-
|
|
33606
|
-
|
|
33607
|
-
|
|
33608
|
-
|
|
33609
|
-
|
|
33610
|
-
|
|
33611
|
-
|
|
33612
|
-
|
|
33613
|
-
|
|
33614
|
-
|
|
33615
|
-
|
|
33616
|
-
|
|
33617
|
-
|
|
33618
|
-
|
|
33619
|
-
|
|
33620
|
-
|
|
33621
|
-
|
|
33622
|
-
|
|
33623
|
-
|
|
33624
|
-
|
|
33625
|
-
|
|
33626
|
-
|
|
33627
|
-
|
|
33628
|
-
|
|
33629
|
-
|
|
33630
|
-
|
|
33631
|
-
|
|
33632
|
-
|
|
33633
|
-
|
|
33634
|
-
|
|
33635
|
-
|
|
33636
|
-
|
|
33637
|
-
|
|
33638
|
-
|
|
33639
|
-
|
|
33640
|
-
|
|
33641
|
-
|
|
33642
|
-
|
|
33643
|
-
|
|
33644
|
-
|
|
33645
|
-
|
|
33646
|
-
|
|
33647
|
-
|
|
33648
|
-
|
|
33649
|
-
|
|
33650
|
-
|
|
33651
|
-
|
|
33652
|
-
|
|
33653
|
-
|
|
33654
|
-
|
|
33655
|
-
|
|
33656
|
-
|
|
34221
|
+
),
|
|
34222
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("header", { className: "px-5 pt-3.5 pb-3 border-b t-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
34223
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
34224
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] font-mono uppercase tracking-[0.14em] t-text-muted mb-1.5 flex items-center gap-2 flex-wrap", children: [
|
|
34225
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: crumb }),
|
|
34226
|
+
isEditable && isDirty && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "normal-case tracking-normal px-1.5 py-0.5 rounded-full bg-[var(--color-status-warning)]/15 t-text-warning", children: "Unsaved" })
|
|
34227
|
+
] }),
|
|
34228
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
34229
|
+
typeIcons[entity.type] || null,
|
|
34230
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34231
|
+
"h2",
|
|
34232
|
+
{
|
|
34233
|
+
className: "min-w-0 truncate t-text",
|
|
34234
|
+
style: {
|
|
34235
|
+
fontFamily: READING_FONT,
|
|
34236
|
+
fontSize: "17px",
|
|
34237
|
+
lineHeight: 1.2,
|
|
34238
|
+
fontWeight: 500,
|
|
34239
|
+
letterSpacing: "-0.012em"
|
|
34240
|
+
},
|
|
34241
|
+
children: entity.title
|
|
34242
|
+
}
|
|
34243
|
+
)
|
|
34244
|
+
] })
|
|
34245
|
+
] }),
|
|
34246
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 flex-shrink-0 pt-1", children: [
|
|
34247
|
+
nav.canNavigate && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0.5 mr-1", children: [
|
|
34248
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34249
|
+
"button",
|
|
34250
|
+
{
|
|
34251
|
+
onClick: handleNavPrev,
|
|
34252
|
+
className: "p-1 rounded t-text-muted t-bg-hover transition-colors",
|
|
34253
|
+
title: "Previous item (Alt+Up)",
|
|
34254
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { size: 14 })
|
|
34255
|
+
}
|
|
34256
|
+
),
|
|
34257
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] t-text-muted tabular-nums min-w-[2.5rem] text-center", children: [
|
|
34258
|
+
nav.currentIndex + 1,
|
|
34259
|
+
" / ",
|
|
34260
|
+
nav.total
|
|
34261
|
+
] }),
|
|
34262
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34263
|
+
"button",
|
|
34264
|
+
{
|
|
34265
|
+
onClick: handleNavNext,
|
|
34266
|
+
className: "p-1 rounded t-text-muted t-bg-hover transition-colors",
|
|
34267
|
+
title: "Next item (Alt+Down)",
|
|
34268
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { size: 14 })
|
|
34269
|
+
}
|
|
34270
|
+
)
|
|
34271
|
+
] }),
|
|
34272
|
+
isEditable && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34273
|
+
"button",
|
|
34274
|
+
{
|
|
34275
|
+
onClick: () => void handleSave(),
|
|
34276
|
+
disabled: !isDirty,
|
|
34277
|
+
className: `p-1 rounded transition-colors ${isDirty ? "t-text-accent-soft hover:t-text-accent" : "t-text-muted opacity-50"}`,
|
|
34278
|
+
title: isDirty ? "Save markdown (Cmd/Ctrl+S)" : "No changes to save",
|
|
34279
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { size: 14 })
|
|
34280
|
+
}
|
|
34281
|
+
),
|
|
34282
|
+
isMarpFile && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34283
|
+
"button",
|
|
34284
|
+
{
|
|
34285
|
+
onClick: () => setViewModeOverride(showSlideView ? "source" : "slides"),
|
|
34286
|
+
className: "p-1 rounded t-text-muted t-bg-hover transition-colors",
|
|
34287
|
+
title: showSlideView ? "Edit source" : "View as slides",
|
|
34288
|
+
"aria-pressed": showSlideView,
|
|
34289
|
+
children: showSlideView ? /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Presentation, { size: 14 })
|
|
34290
|
+
}
|
|
34291
|
+
),
|
|
34292
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34293
|
+
"button",
|
|
34294
|
+
{
|
|
34295
|
+
onClick: handleClosePreview,
|
|
34296
|
+
className: "p-1 rounded t-text-muted t-bg-hover transition-colors",
|
|
34297
|
+
title: "Close preview (Esc)",
|
|
34298
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { size: 14 })
|
|
34299
|
+
}
|
|
34300
|
+
)
|
|
34301
|
+
] })
|
|
34302
|
+
] }) }),
|
|
34303
|
+
entity.type === "paper" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-2 border-b t-border text-xs t-text-secondary space-y-1", children: [
|
|
34304
|
+
entity.authors?.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34305
|
+
"Authors: ",
|
|
34306
|
+
entity.authors.join(", ")
|
|
34307
|
+
] }),
|
|
34308
|
+
entity.year && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34309
|
+
"Year: ",
|
|
34310
|
+
entity.year
|
|
34311
|
+
] }),
|
|
34312
|
+
entity.venue && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34313
|
+
"Venue: ",
|
|
34314
|
+
entity.venue
|
|
34315
|
+
] }),
|
|
34316
|
+
entity.doi && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34317
|
+
"DOI: ",
|
|
34318
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: `https://doi.org/${entity.doi}`, target: "_blank", rel: "noreferrer", className: "t-text-accent-soft hover:underline", children: entity.doi })
|
|
34319
|
+
] }),
|
|
34320
|
+
entity.citationCount != null && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34321
|
+
"Citations: ",
|
|
34322
|
+
entity.citationCount
|
|
34323
|
+
] }),
|
|
34324
|
+
entity.url && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34325
|
+
"URL: ",
|
|
34326
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: entity.url, target: "_blank", rel: "noreferrer", className: "t-text-accent-soft hover:underline break-all", children: entity.url })
|
|
34327
|
+
] }),
|
|
34328
|
+
entity.pdfUrl && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34329
|
+
"PDF: ",
|
|
34330
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: entity.pdfUrl, target: "_blank", rel: "noreferrer", className: "t-text-accent-soft hover:underline break-all", children: entity.pdfUrl })
|
|
34331
|
+
] }),
|
|
34332
|
+
entity.citeKey && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34333
|
+
"Cite key: ",
|
|
34334
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "t-bg-surface px-1 rounded", children: entity.citeKey })
|
|
34335
|
+
] }),
|
|
34336
|
+
entity.externalSource && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34337
|
+
"Source: ",
|
|
34338
|
+
entity.externalSource
|
|
34339
|
+
] }),
|
|
34340
|
+
entity.relevanceScore != null && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34341
|
+
"Relevance: ",
|
|
34342
|
+
entity.relevanceScore,
|
|
34343
|
+
"/10"
|
|
34344
|
+
] }),
|
|
34345
|
+
entity.enrichmentSource && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34346
|
+
"Enriched via: ",
|
|
34347
|
+
entity.enrichmentSource
|
|
34348
|
+
] }),
|
|
34349
|
+
entity.enrichedAt && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34350
|
+
"Enriched at: ",
|
|
34351
|
+
new Date(entity.enrichedAt).toLocaleDateString()
|
|
34352
|
+
] }),
|
|
34353
|
+
entity.tags?.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "flex items-center gap-1 flex-wrap", children: [
|
|
34354
|
+
"Tags: ",
|
|
34355
|
+
entity.tags.map((t) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-block t-bg-surface px-1.5 py-0.5 rounded", children: t }, t))
|
|
34356
|
+
] }),
|
|
34357
|
+
entity.bibtex && /* @__PURE__ */ jsxRuntimeExports.jsxs("details", { className: "mt-1", children: [
|
|
34358
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("summary", { className: "cursor-pointer hover:t-text-accent-soft", children: "BibTeX" }),
|
|
34359
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "mt-1 p-2 t-bg-surface rounded text-[11px] font-mono whitespace-pre-wrap break-all", children: entity.bibtex })
|
|
34360
|
+
] })
|
|
34361
|
+
] }),
|
|
34362
|
+
entity.type === "data" && entity.schema && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-2 border-b t-border text-xs t-text-secondary", children: [
|
|
34363
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34364
|
+
"File: ",
|
|
34365
|
+
entity.name
|
|
34366
|
+
] }),
|
|
34367
|
+
entity.schema.rowCount != null && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
34368
|
+
"Rows: ",
|
|
34369
|
+
entity.schema.rowCount
|
|
34370
|
+
] })
|
|
34371
|
+
] }),
|
|
34372
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: scrollContentRef, className: "flex-1 overflow-y-auto px-5 py-5 min-h-0", children: renderContent() }),
|
|
34373
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("footer", { className: "shrink-0 px-5 py-2.5 border-t t-border flex items-center justify-between gap-3 text-[10px] font-mono uppercase tracking-[0.12em] t-text-muted", children: [
|
|
34374
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-2 min-w-0 truncate", children: [
|
|
34375
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34376
|
+
"span",
|
|
34377
|
+
{
|
|
34378
|
+
className: "inline-block w-[7px] h-[7px] rounded-full t-bg-accent animate-pulse shrink-0",
|
|
34379
|
+
"aria-hidden": "true"
|
|
34380
|
+
}
|
|
34381
|
+
),
|
|
34382
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: "Bound to chat" })
|
|
34383
|
+
] }),
|
|
34384
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate shrink-0", children: "Drag edge · Esc to close" })
|
|
34385
|
+
] })
|
|
34386
|
+
]
|
|
34387
|
+
}
|
|
34388
|
+
);
|
|
34389
|
+
}
|
|
34390
|
+
const api$2 = window.api;
|
|
34391
|
+
const computeEnabled = api$2?.isComputeEnabled?.() ?? false;
|
|
34392
|
+
const viewTabs = [
|
|
34393
|
+
{ key: "chat", label: "Chat", icon: MessageSquare, shortcut: "⌘1" },
|
|
34394
|
+
{ key: "literature", label: "Literature", icon: BookOpen, shortcut: "⌘2" },
|
|
34395
|
+
...computeEnabled ? [{ key: "compute", label: "Compute", icon: Cpu, shortcut: "⌘3" }] : []
|
|
34396
|
+
];
|
|
34397
|
+
function ViewSwitcher() {
|
|
34398
|
+
const centerView = useUIStore((s15) => s15.centerView);
|
|
34399
|
+
const setCenterView = useUIStore((s15) => s15.setCenterView);
|
|
34400
|
+
const paperCount = useEntityStore((s15) => s15.papers.length);
|
|
34401
|
+
const activeComputeRuns = useActiveRunCount();
|
|
34402
|
+
return (
|
|
34403
|
+
// Bottom hairline gives the nav a real anchor — without it, the tabs
|
|
34404
|
+
// float in a gray area between the drag region and the content.
|
|
34405
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34406
|
+
"nav",
|
|
34407
|
+
{
|
|
34408
|
+
"aria-label": "View switcher",
|
|
34409
|
+
className: "flex items-stretch gap-1 px-4 pt-10 border-b t-border",
|
|
34410
|
+
children: viewTabs.map(({ key, label, icon: Icon2, shortcut }) => {
|
|
34411
|
+
const isActive = centerView === key;
|
|
34412
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
34413
|
+
"button",
|
|
34414
|
+
{
|
|
34415
|
+
onClick: () => setCenterView(key),
|
|
34416
|
+
"aria-current": isActive ? "page" : void 0,
|
|
34417
|
+
title: `${label} (${shortcut})`,
|
|
34418
|
+
className: `no-drag relative group flex items-center gap-2 px-3 pt-1.5 pb-2 text-[13px] font-medium transition-colors ${isActive ? "t-text" : "t-text-muted hover:t-text-secondary"}`,
|
|
34419
|
+
children: [
|
|
34420
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { size: 14, className: isActive ? "t-text-accent" : "" }),
|
|
34421
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: label }),
|
|
34422
|
+
key === "literature" && paperCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34423
|
+
"span",
|
|
34424
|
+
{
|
|
34425
|
+
className: `px-1.5 py-px text-[10px] rounded-full tabular-nums ${isActive ? "t-bg-accent/15 t-text-accent" : "t-bg-elevated t-text-muted"}`,
|
|
34426
|
+
children: paperCount
|
|
34427
|
+
}
|
|
34428
|
+
),
|
|
34429
|
+
key === "compute" && activeComputeRuns > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-1.5 py-px text-[10px] rounded-full tabular-nums t-bg-accent/15 t-text-accent", children: activeComputeRuns }),
|
|
34430
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34431
|
+
"kbd",
|
|
34432
|
+
{
|
|
34433
|
+
className: `inline-flex items-center px-1 py-0 rounded border text-[9.5px] font-mono leading-[1.4] transition-colors ${isActive ? "t-border-accent-soft t-text-accent-soft bg-transparent" : "t-border-subtle t-bg-elevated t-text-muted group-hover:t-text-secondary"}`,
|
|
34434
|
+
children: shortcut
|
|
34435
|
+
}
|
|
34436
|
+
),
|
|
34437
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34438
|
+
"span",
|
|
34439
|
+
{
|
|
34440
|
+
"aria-hidden": true,
|
|
34441
|
+
className: `pointer-events-none absolute left-0 right-0 -bottom-px h-[2px] transition-colors ${isActive ? "t-bg-accent" : "bg-transparent"}`
|
|
34442
|
+
}
|
|
34443
|
+
)
|
|
34444
|
+
]
|
|
34445
|
+
},
|
|
34446
|
+
key
|
|
34447
|
+
);
|
|
34448
|
+
})
|
|
34449
|
+
}
|
|
34450
|
+
)
|
|
34451
|
+
);
|
|
34452
|
+
}
|
|
34453
|
+
function CenterPanel() {
|
|
34454
|
+
const centerView = useUIStore((s15) => s15.centerView);
|
|
34455
|
+
const isIdle = useUIStore((s15) => s15.isIdle);
|
|
34456
|
+
const messages = useChatStore((s15) => s15.messages);
|
|
34457
|
+
const previewEntity = useUIStore((s15) => s15.previewEntity);
|
|
34458
|
+
const drawerWidth = useUIStore((s15) => s15.drawerWidth);
|
|
34459
|
+
const showHero = isIdle && messages.length === 0;
|
|
34460
|
+
const drawerOpen = !!previewEntity;
|
|
34461
|
+
const rightGutter = drawerOpen ? drawerWidth : 0;
|
|
34462
|
+
const columnShiftStyle = { paddingRight: `${rightGutter}px` };
|
|
34463
|
+
const columnShiftClass = "transition-[padding] duration-500 ease-[cubic-bezier(0.32,0.72,0.24,1)]";
|
|
34464
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
34465
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
34466
|
+
"main",
|
|
34467
|
+
{
|
|
34468
|
+
id: centerView === "chat" ? "main-content" : void 0,
|
|
34469
|
+
hidden: centerView !== "chat",
|
|
34470
|
+
className: "flex-1 flex flex-col min-w-0 relative overflow-hidden",
|
|
34471
|
+
children: [
|
|
34472
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: columnShiftClass, style: columnShiftStyle, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ViewSwitcher, {}) }),
|
|
34473
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: showHero ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34474
|
+
"div",
|
|
34475
|
+
{
|
|
34476
|
+
className: `h-full flex items-center justify-center ${columnShiftClass}`,
|
|
34477
|
+
style: columnShiftStyle,
|
|
34478
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(HeroIdle, {})
|
|
34479
|
+
}
|
|
34480
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34481
|
+
"div",
|
|
34482
|
+
{
|
|
34483
|
+
className: `h-full pl-6 pt-4 pb-2 ${columnShiftClass}`,
|
|
34484
|
+
style: { paddingRight: `${24 + rightGutter}px` },
|
|
34485
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto h-full", style: { maxWidth: "64rem" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChatMessages, {}) })
|
|
34486
|
+
}
|
|
34487
|
+
) }),
|
|
34488
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34489
|
+
"div",
|
|
34490
|
+
{
|
|
34491
|
+
className: `pl-6 pb-5 ${columnShiftClass}`,
|
|
34492
|
+
style: { paddingRight: `${24 + rightGutter}px` },
|
|
34493
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto", style: { maxWidth: "64rem" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChatInput, {}) })
|
|
34494
|
+
}
|
|
34495
|
+
),
|
|
34496
|
+
drawerOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(EntityPreviewPanel, {})
|
|
34497
|
+
]
|
|
34498
|
+
}
|
|
34499
|
+
),
|
|
34500
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
34501
|
+
"main",
|
|
34502
|
+
{
|
|
34503
|
+
id: centerView === "literature" ? "main-content" : void 0,
|
|
34504
|
+
hidden: centerView !== "literature",
|
|
34505
|
+
className: "flex-1 flex flex-col min-w-0",
|
|
34506
|
+
children: [
|
|
34507
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewSwitcher, {}),
|
|
34508
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LiteratureView, {})
|
|
34509
|
+
]
|
|
34510
|
+
}
|
|
34511
|
+
),
|
|
34512
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
34513
|
+
"main",
|
|
34514
|
+
{
|
|
34515
|
+
id: centerView === "compute" ? "main-content" : void 0,
|
|
34516
|
+
hidden: centerView !== "compute",
|
|
34517
|
+
className: "flex-1 flex flex-col min-w-0",
|
|
34518
|
+
children: [
|
|
34519
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewSwitcher, {}),
|
|
34520
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ComputeView, {})
|
|
34521
|
+
]
|
|
34522
|
+
}
|
|
34523
|
+
)
|
|
33657
34524
|
] });
|
|
33658
34525
|
}
|
|
33659
34526
|
function formatCost(cost) {
|
|
@@ -42748,7 +43615,6 @@ function TipsBlock() {
|
|
|
42748
43615
|
function FolderGate({ onOpenSettings }) {
|
|
42749
43616
|
const pickFolder = useSessionStore((s15) => s15.pickFolder);
|
|
42750
43617
|
const openPath = useSessionStore((s15) => s15.openPath);
|
|
42751
|
-
const refreshEntities = useEntityStore((s15) => s15.refreshAll);
|
|
42752
43618
|
const [recents, setRecents] = reactExports.useState([]);
|
|
42753
43619
|
const [projectStats, setProjectStats] = reactExports.useState({});
|
|
42754
43620
|
const [activeIndex, setActiveIndex] = reactExports.useState(0);
|
|
@@ -42784,22 +43650,20 @@ function FolderGate({ onOpenSettings }) {
|
|
|
42784
43650
|
if (opening) return;
|
|
42785
43651
|
setOpening(true);
|
|
42786
43652
|
try {
|
|
42787
|
-
|
|
42788
|
-
if (ok2) await refreshEntities();
|
|
43653
|
+
await openPath(path2);
|
|
42789
43654
|
} finally {
|
|
42790
43655
|
setOpening(false);
|
|
42791
43656
|
}
|
|
42792
|
-
}, [openPath,
|
|
43657
|
+
}, [openPath, opening]);
|
|
42793
43658
|
const handlePickNew = reactExports.useCallback(async () => {
|
|
42794
43659
|
if (opening) return;
|
|
42795
43660
|
setOpening(true);
|
|
42796
43661
|
try {
|
|
42797
|
-
|
|
42798
|
-
if (ok2) await refreshEntities();
|
|
43662
|
+
await pickFolder();
|
|
42799
43663
|
} finally {
|
|
42800
43664
|
setOpening(false);
|
|
42801
43665
|
}
|
|
42802
|
-
}, [pickFolder,
|
|
43666
|
+
}, [pickFolder, opening]);
|
|
42803
43667
|
const handleRemove = reactExports.useCallback(async (path2) => {
|
|
42804
43668
|
await api.removeRecentProject?.(path2);
|
|
42805
43669
|
setRecents((prev) => {
|
|
@@ -43065,10 +43929,17 @@ function App() {
|
|
|
43065
43929
|
const unsubSkillLoaded = api.onSkillLoaded((skillName) => {
|
|
43066
43930
|
useActivityStore.getState().addSkill(skillName);
|
|
43067
43931
|
});
|
|
43932
|
+
let entityRefreshTimer = null;
|
|
43933
|
+
const scheduleEntityRefresh = () => {
|
|
43934
|
+
if (entityRefreshTimer) clearTimeout(entityRefreshTimer);
|
|
43935
|
+
entityRefreshTimer = setTimeout(() => {
|
|
43936
|
+
entityRefreshTimer = null;
|
|
43937
|
+
refreshEntities();
|
|
43938
|
+
}, 300);
|
|
43939
|
+
};
|
|
43068
43940
|
const unsub1 = api.onStreamChunk((chunk) => appendChunk(chunk));
|
|
43069
43941
|
const unsub2 = api.onAgentDone((result) => {
|
|
43070
43942
|
finalize(result);
|
|
43071
|
-
refreshEntities();
|
|
43072
43943
|
const text2 = result.response || "";
|
|
43073
43944
|
const projectRoot = useSessionStore.getState().projectPath;
|
|
43074
43945
|
const filePathRegex = /(?:^|\s)((?:[\w.-]+\/)+[\w.-]+\.\w+|(?:\/[\w.-]+)+\.\w+)/gm;
|
|
@@ -43096,7 +43967,7 @@ function App() {
|
|
|
43096
43967
|
useUIStore.getState().addWorkingFile(path2);
|
|
43097
43968
|
});
|
|
43098
43969
|
const unsub6 = api.onEntityCreated(() => {
|
|
43099
|
-
|
|
43970
|
+
scheduleEntityRefresh();
|
|
43100
43971
|
});
|
|
43101
43972
|
if (api?.isComputeEnabled?.()) {
|
|
43102
43973
|
api.probeComputeEnvironment?.().catch(() => {
|
|
@@ -43112,6 +43983,7 @@ function App() {
|
|
|
43112
43983
|
useComputeStore.getState().setEnvironment(event);
|
|
43113
43984
|
});
|
|
43114
43985
|
return () => {
|
|
43986
|
+
if (entityRefreshTimer) clearTimeout(entityRefreshTimer);
|
|
43115
43987
|
unsub1();
|
|
43116
43988
|
unsub2();
|
|
43117
43989
|
unsub3();
|
|
@@ -43212,12 +44084,9 @@ function App() {
|
|
|
43212
44084
|
/* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "#main-content", className: "skip-link", children: "Skip to content" }),
|
|
43213
44085
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "drag-region fixed top-0 left-0 right-0 h-8 z-50" }),
|
|
43214
44086
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 min-h-0", children: [
|
|
43215
|
-
!leftCollapsed && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
44087
|
+
!leftCollapsed && /* @__PURE__ */ jsxRuntimeExports.jsx(LeftSidebar, { onOpenSettings: () => setSettingsOpen(true) }),
|
|
43216
44088
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col min-w-0 min-h-0", children: [
|
|
43217
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
43218
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CenterPanel, {}),
|
|
43219
|
-
previewEntity && /* @__PURE__ */ jsxRuntimeExports.jsx(EntityPreviewPanel, {})
|
|
43220
|
-
] }),
|
|
44089
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `flex min-h-0 ${terminalVisible ? "flex-[2]" : "flex-1"}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(CenterPanel, {}) }),
|
|
43221
44090
|
terminalAlive && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
43222
44091
|
"div",
|
|
43223
44092
|
{
|
|
@@ -43262,6 +44131,7 @@ export {
|
|
|
43262
44131
|
patternInScope as p,
|
|
43263
44132
|
jsxRuntimeExports as q,
|
|
43264
44133
|
reactExports as r,
|
|
44134
|
+
resolveMarkdownImageUrl as s,
|
|
43265
44135
|
unified as u,
|
|
43266
44136
|
visit as v
|
|
43267
44137
|
};
|