dsh-coding-sidebar 1.0.7 → 1.0.8

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.
Files changed (69) hide show
  1. package/README.md +2 -2
  2. package/lib/client-editor.js +436 -227
  3. package/lib/client-registry.js +627 -7391
  4. package/lib/client-terminal.js +234 -182
  5. package/lib/client.js +634 -7398
  6. package/lib/index.js +367 -67
  7. package/lib/types/agent-pty.d.ts +62 -4
  8. package/lib/types/bundle-route.d.ts +1 -1
  9. package/lib/types/client/EditorHost.d.ts +1 -1
  10. package/lib/types/client/FileTree.d.ts +2 -2
  11. package/lib/types/client/TreePanel.d.ts +1 -1
  12. package/lib/types/client/chunk-loader.d.ts +1 -1
  13. package/lib/types/client/chunks/locale.d.ts +3 -0
  14. package/lib/types/client/conversation-draft.d.ts +85 -4
  15. package/lib/types/client/locales.d.ts +1 -20
  16. package/lib/types/client/selection-popup.d.ts +58 -0
  17. package/lib/types/client/service.d.ts +1 -1
  18. package/lib/types/client/terminal-font.d.ts +25 -2
  19. package/lib/types/context-types.d.ts +3 -1
  20. package/lib/types/index.d.ts +9 -0
  21. package/lib/types/prefs-shared.d.ts +7 -5
  22. package/lib/types/pty-manager.d.ts +53 -0
  23. package/lib/types/wire.d.ts +6 -2
  24. package/package.json +1 -1
  25. package/src/agent-pty.ts +221 -33
  26. package/src/bundle-route.ts +1 -1
  27. package/src/client/EditorHost.tsx +1 -1
  28. package/src/client/FileTree.tsx +4 -4
  29. package/src/client/Sidebar.tsx +41 -22
  30. package/src/client/TerminalView.tsx +13 -0
  31. package/src/client/TextEditor.tsx +27 -45
  32. package/src/client/TreePanel.tsx +16 -1
  33. package/src/client/chunk-loader.ts +1 -1
  34. package/src/client/chunks/locale.tsx +60 -0
  35. package/src/client/conversation-draft.ts +233 -7
  36. package/src/client/index.tsx +19 -8
  37. package/src/client/locales-ar.ts +5 -4
  38. package/src/client/locales-de.ts +5 -4
  39. package/src/client/locales-fr.ts +5 -4
  40. package/src/client/locales-hi.ts +5 -4
  41. package/src/client/locales-id.ts +5 -4
  42. package/src/client/locales-it.ts +5 -4
  43. package/src/client/locales-ja.ts +5 -4
  44. package/src/client/locales-ko.ts +5 -4
  45. package/src/client/locales-nl.ts +5 -4
  46. package/src/client/locales-pl.ts +5 -4
  47. package/src/client/locales-pt.ts +5 -4
  48. package/src/client/locales-ru.ts +5 -4
  49. package/src/client/locales-sv.ts +5 -4
  50. package/src/client/locales-th.ts +5 -4
  51. package/src/client/locales-tr.ts +5 -4
  52. package/src/client/locales-vi.ts +5 -4
  53. package/src/client/locales-zh-HK.ts +5 -4
  54. package/src/client/locales-zh-MO.ts +5 -4
  55. package/src/client/locales-zh-TW.ts +5 -4
  56. package/src/client/locales.ts +17 -51
  57. package/src/client/selection-popup.ts +155 -0
  58. package/src/client/service.ts +1 -1
  59. package/src/client/state.ts +14 -7
  60. package/src/client/terminal-font.ts +34 -3
  61. package/src/context-types.ts +3 -2
  62. package/src/git.ts +17 -1
  63. package/src/index.ts +39 -6
  64. package/src/open-external.ts +3 -4
  65. package/src/prefs-shared.ts +7 -5
  66. package/src/pty-manager.ts +176 -5
  67. package/src/sidechat-routes.ts +13 -1
  68. package/src/tools.ts +24 -6
  69. package/src/wire.ts +3 -0
@@ -43208,19 +43208,126 @@ globalThis.__dshChunks__["editor"] = (require) => {
43208
43208
  //#endregion
43209
43209
  //#region src/client/conversation-draft.ts
43210
43210
  /**
43211
- * Append `text` to the session's composer draft (space-separated, like the
43212
- * @-mentions). Returns false — and logs when the conversation service or
43213
- * the session scope is unavailable.
43211
+ * Splice `text` into `draft` at `caret` (replacing any live selection) with
43212
+ * whitespace-aware joins and report the caret position right after the
43213
+ * inserted text. `caret === null` (position unknown) appends at the end,
43214
+ * exactly like the original behavior.
43215
+ */
43216
+ function spliceInsert(draft, text, caret) {
43217
+ if (caret === null || draft === "") {
43218
+ const next = draft.trim() === "" ? text : `${draft} ${text}`;
43219
+ return {
43220
+ draft: next,
43221
+ caretAfter: next.length
43222
+ };
43223
+ }
43224
+ const prefix = draft.slice(0, caret.start);
43225
+ const suffix = draft.slice(caret.end);
43226
+ if (prefix === "" && suffix === "") return {
43227
+ draft: text,
43228
+ caretAfter: text.length
43229
+ };
43230
+ const left = prefix === "" || /\s$/.test(prefix) ? "" : " ";
43231
+ return {
43232
+ draft: `${prefix}${left}${text}${suffix === "" || /^\s/.test(suffix) ? "" : " "}${suffix}`,
43233
+ caretAfter: prefix.length + left.length + text.length
43234
+ };
43235
+ }
43236
+ /**
43237
+ * Locate the composer `<textarea>` in the conversation column: prefer the
43238
+ * `data-phase`-tagged textarea (the composer's marker), falling back to any
43239
+ * textarea in the column, then to a bare data-phase textarea (older host
43240
+ * layouts without the column attribute). Null in jsdom-less hosts.
43241
+ */
43242
+ function findComposerTextarea() {
43243
+ if (typeof document === "undefined") return null;
43244
+ const column = document.querySelector("#root [data-slot=\"conversation\"]");
43245
+ const find = (scope) => scope.querySelector("textarea[data-phase]") ?? scope.querySelector("textarea");
43246
+ return column !== null ? find(column) : document.querySelector("textarea[data-phase]");
43247
+ }
43248
+ /**
43249
+ * Resolve the composer's live caret from its DOM `<textarea>`. The draft
43250
+ * store has no caret API, so the sidebar reads the composed input's selection
43251
+ * directly; the value-sync check (`el.value === draft`) discards stale or
43252
+ * wrong-composer reads — a caret must never be applied against a draft it
43253
+ * was not measured on.
43254
+ *
43255
+ * Returns null when the composer is missing, disabled/read-only, out of
43256
+ * sync with the store draft, or has no measurable selection (odd hosts
43257
+ * report null selectionStart/End).
43258
+ */
43259
+ function probeComposerCaret(draft) {
43260
+ const el = findComposerTextarea();
43261
+ if (el === null || el.disabled || el.readOnly) return null;
43262
+ if (el.value !== draft) return null;
43263
+ let start = el.selectionStart;
43264
+ let end = el.selectionEnd;
43265
+ if (typeof start !== "number" || typeof end !== "number") return null;
43266
+ if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
43267
+ start = Math.max(0, Math.min(start, draft.length));
43268
+ end = Math.max(start, Math.min(end, draft.length));
43269
+ return {
43270
+ start,
43271
+ end
43272
+ };
43273
+ }
43274
+ /**
43275
+ * Restore the composer caret to `caretIndex` after a programmatic
43276
+ * `setDraft` commit. A controlled textarea update resets the caret (React
43277
+ * commits the value asynchronously and the browser moves the caret to the
43278
+ * start/end), so the placement is scheduled and retried across at most two
43279
+ * animation frames (setTimeout fallback), and only applied when the textarea
43280
+ * still matches `expectedDraft` — a newer edit or a different composer wins
43281
+ * the race untouched. The caret is clamped into the value bounds, mirroring
43282
+ * how browsers clamp type-in positions.
43283
+ */
43284
+ function placeComposerCaretAfterInsert(expectedDraft, caretIndex) {
43285
+ let remaining = 2;
43286
+ let scheduled = false;
43287
+ const schedule = (fn) => {
43288
+ if (scheduled) return;
43289
+ scheduled = true;
43290
+ if (typeof requestAnimationFrame === "function") requestAnimationFrame(fn);
43291
+ else setTimeout(fn, 0);
43292
+ };
43293
+ const place = () => {
43294
+ scheduled = false;
43295
+ if (remaining <= 0) return;
43296
+ remaining -= 1;
43297
+ const el = findComposerTextarea();
43298
+ if (el === null || el.disabled || el.readOnly) return;
43299
+ if (el.value !== expectedDraft) {
43300
+ schedule(place);
43301
+ return;
43302
+ }
43303
+ const clamped = Math.max(0, Math.min(caretIndex, el.value.length));
43304
+ el.setSelectionRange(clamped, clamped);
43305
+ };
43306
+ schedule(place);
43307
+ }
43308
+ /**
43309
+ * Insert `text` into the session's composer draft at the composer's live
43310
+ * caret (see {@link probeComposerCaret}), falling back to appending at the
43311
+ * end when the caret cannot be resolved. Returns false — and logs — when the
43312
+ * conversation service or the session scope is unavailable.
43214
43313
  */
43215
43314
  function appendToDraft(ctx, sessionId, text) {
43216
43315
  try {
43217
43316
  const actx = ctx.sessions.scope(sessionId);
43218
- if (actx === void 0) return false;
43317
+ if (actx === void 0) {
43318
+ console.warn("[dsh-coding-sidebar] draft insert skipped: no session scope", sessionId);
43319
+ return false;
43320
+ }
43219
43321
  const conversation = ctx.get("conversation");
43220
- if (conversation === void 0) return false;
43322
+ if (conversation === void 0) {
43323
+ console.warn("[dsh-coding-sidebar] draft insert skipped: conversation service unavailable");
43324
+ return false;
43325
+ }
43221
43326
  const input = conversation.input.for(actx);
43222
43327
  const draft = input.state.getSnapshot().draft;
43223
- input.setDraft(draft.trim() === "" ? text : `${draft} ${text}`);
43328
+ const { draft: next, caretAfter } = spliceInsert(draft, text, probeComposerCaret(draft));
43329
+ input.setDraft(next);
43330
+ placeComposerCaretAfterInsert(next, caretAfter);
43224
43331
  return true;
43225
43332
  } catch (error) {
43226
43333
  console.warn("[dsh-coding-sidebar] draft insert failed:", error);
@@ -43228,6 +43335,117 @@ globalThis.__dshChunks__["editor"] = (require) => {
43228
43335
  }
43229
43336
  }
43230
43337
  //#endregion
43338
+ //#region src/client/selection-popup.ts
43339
+ /**
43340
+ * The floating "add selection to conversation" popup shared by the text
43341
+ * viewer: a viewport-anchored button portaled to `document.body`, kept alive
43342
+ * across the selection gesture and committed on click.
43343
+ *
43344
+ * Dismissal contract (upstream issue #425): the popup must never outlive its
43345
+ * editor surface. The sidebar keeps every tab MOUNTED — switching tabs only
43346
+ * flips the pane cell to `display:none` and collapsing the panel translates
43347
+ * it off-screen — while the portaled `position:fixed` button stays pinned to
43348
+ * its viewport anchor, ignoring both. The caller already hides on surface
43349
+ * scrolls, selection collapse and content swaps; this hook adds the global
43350
+ * dismissal that covers everything else:
43351
+ *
43352
+ * - any `mousedown` outside the button (tab bar, composer, another pane,
43353
+ * the collapse toggle, …) closes it;
43354
+ * - `Escape` closes it;
43355
+ * - the document going hidden (`visibilitychange`) or the window losing
43356
+ * focus closes it;
43357
+ * - an `IntersectionObserver` on the editor surface closes it as soon as the
43358
+ * surface leaves the viewport — the tab-switch (`display:none`) and
43359
+ * panel-collapse (translated off-screen) paths have no DOM events of their
43360
+ * own, so the geometry signal is the only reliable one.
43361
+ *
43362
+ * The button's own `mousedown` is never treated as an outside click: the
43363
+ * caller preventDefaults it to keep the selection/caret alive until the
43364
+ * click commits (the hook's capture-phase listener runs first and must not
43365
+ * hide for it).
43366
+ */
43367
+ function useSelectionPopup(options) {
43368
+ const onCommitRef = (0, react.useRef)(options.onCommit);
43369
+ const getSurfaceRef = (0, react.useRef)(options.getSurface);
43370
+ onCommitRef.current = options.onCommit;
43371
+ getSurfaceRef.current = options.getSurface;
43372
+ const [popup, setPopup] = (0, react.useState)(null);
43373
+ /** Live mirror for click/event-time reads (no re-render race). */
43374
+ const popupRef = (0, react.useRef)(null);
43375
+ /** The portaled button itself (for the outside-click guard). */
43376
+ const buttonRef = (0, react.useRef)(null);
43377
+ /** The surface visibility observer (created lazily on open). */
43378
+ const observerRef = (0, react.useRef)(null);
43379
+ const show = (insert, left, top) => {
43380
+ const next = {
43381
+ insert,
43382
+ left: Math.min(Math.max(left, 80), window.innerWidth - 80),
43383
+ top
43384
+ };
43385
+ popupRef.current = next;
43386
+ setPopup(next);
43387
+ };
43388
+ const hide = () => {
43389
+ popupRef.current = null;
43390
+ setPopup(null);
43391
+ };
43392
+ const commit = () => {
43393
+ const current = popupRef.current;
43394
+ if (current === null) return;
43395
+ onCommitRef.current(current.insert);
43396
+ hide();
43397
+ };
43398
+ (0, react.useEffect)(() => {
43399
+ const onMouseDown = (event) => {
43400
+ if (popupRef.current === null) return;
43401
+ const button = buttonRef.current;
43402
+ if (button !== null && (button === event.target || button.contains(event.target))) return;
43403
+ hide();
43404
+ };
43405
+ const onKeyDown = (event) => {
43406
+ if (event.key === "Escape" && popupRef.current !== null) hide();
43407
+ };
43408
+ const onVisibilityChange = () => {
43409
+ if (document.hidden && popupRef.current !== null) hide();
43410
+ };
43411
+ const onWindowBlur = () => {
43412
+ if (popupRef.current !== null) hide();
43413
+ };
43414
+ document.addEventListener("mousedown", onMouseDown, true);
43415
+ document.addEventListener("keydown", onKeyDown, true);
43416
+ document.addEventListener("visibilitychange", onVisibilityChange);
43417
+ window.addEventListener("blur", onWindowBlur);
43418
+ return () => {
43419
+ document.removeEventListener("mousedown", onMouseDown, true);
43420
+ document.removeEventListener("keydown", onKeyDown, true);
43421
+ document.removeEventListener("visibilitychange", onVisibilityChange);
43422
+ window.removeEventListener("blur", onWindowBlur);
43423
+ observerRef.current?.disconnect();
43424
+ observerRef.current = null;
43425
+ };
43426
+ }, []);
43427
+ (0, react.useEffect)(() => {
43428
+ if (popup === null) return;
43429
+ observerRef.current?.disconnect();
43430
+ observerRef.current = null;
43431
+ if (typeof IntersectionObserver === "undefined") return;
43432
+ const surface = getSurfaceRef.current();
43433
+ if (surface === null) return;
43434
+ const observer = new IntersectionObserver((entries) => {
43435
+ for (const entry of entries) if (!entry.isIntersecting) hide();
43436
+ }, { threshold: 0 });
43437
+ observerRef.current = observer;
43438
+ observer.observe(surface);
43439
+ }, [popup !== null]);
43440
+ return {
43441
+ popup,
43442
+ buttonRef,
43443
+ show,
43444
+ hide,
43445
+ commit
43446
+ };
43447
+ }
43448
+ //#endregion
43231
43449
  //#region src/client/paths.ts
43232
43450
  /**
43233
43451
  * The path relative to the session's working directory.
@@ -43368,6 +43586,7 @@ globalThis.__dshChunks__["editor"] = (require) => {
43368
43586
  terminalDepsFailed: "终端依赖 node-pty 加载失败",
43369
43587
  terminalDepsHint: "在 DSH 所在环境的终端或 cmd 中执行以下命令修复,然后点重试(node-pty 与 DSH 核心保持同一版本):",
43370
43588
  terminalDepsProfile: "(检测到 profile:{profile})",
43589
+ terminalShellNotFound: "未找到配置的 Shell:{name},请到 设置 → 侧边卡片 → 终端 检查 Shell 路径",
43371
43590
  refresh: "刷新",
43372
43591
  refreshUnsavedConfirm: "文件已在磁盘更新,刷新将丢弃未保存编辑。继续吗?",
43373
43592
  save: "保存",
@@ -43491,10 +43710,10 @@ globalThis.__dshChunks__["editor"] = (require) => {
43491
43710
  settingsConflict: "设置已被其他窗口修改,请重试",
43492
43711
  binaryNoPreview: "此文件类型不支持预览",
43493
43712
  downloadToView: "下载查看",
43494
- settingsSubagentTitle: "检测到子代理时自动展开任务管理页",
43495
- settingsSubagentDesc: "当前会话产生新的子代理时,自动展开侧边栏并打开任务管理页;关闭后需手动打开",
43496
- settingsJobsTitle: "有新后台任务时自动展开后台任务页",
43497
- settingsJobsDesc: "当前会话出现新的后台任务时,自动展开侧边栏并打开后台任务页(每个新任务都会触发);关闭后需手动打开",
43713
+ settingsSubagentTitle: "检测到子代理时自动激活任务管理页",
43714
+ settingsSubagentDesc: "当前会话产生新的子代理时,自动激活任务管理页;宽屏同时展开侧边栏,窄屏不强制展开全屏抽屉;关闭后需手动打开",
43715
+ settingsJobsTitle: "有新后台任务时自动激活后台任务页",
43716
+ settingsJobsDesc: "当前会话出现新的后台任务时,自动激活后台任务页(每个新任务都会触发);宽屏同时展开侧边栏,窄屏不强制展开全屏抽屉;关闭后需手动打开",
43498
43717
  settingsToolsTitle: "为模型注入终端工具",
43499
43718
  settingsToolsDesc: "开启后,模型可通过 terminal_create 等 8 个工具创建并操作侧边栏终端(默认关闭)",
43500
43719
  settingsFontFamilyTitle: "终端字体",
@@ -43703,6 +43922,7 @@ globalThis.__dshChunks__["editor"] = (require) => {
43703
43922
  terminalDepsFailed: "Terminal dependency node-pty failed to load",
43704
43923
  terminalDepsHint: "Run the command below in a terminal or cmd on the DSH machine to repair it, then retry (node-pty stays in sync with the DSH core version):",
43705
43924
  terminalDepsProfile: " (detected profile: {profile})",
43925
+ terminalShellNotFound: "Configured shell not found: {name} — check the shell path under Settings → Side card → Terminal",
43706
43926
  refresh: "Refresh",
43707
43927
  refreshUnsavedConfirm: "The file changed on disk. Refreshing will discard unsaved edits. Continue?",
43708
43928
  save: "Save",
@@ -43826,10 +44046,10 @@ globalThis.__dshChunks__["editor"] = (require) => {
43826
44046
  settingsConflict: "The setting changed in another window — please retry",
43827
44047
  binaryNoPreview: "This file type cannot be previewed",
43828
44048
  downloadToView: "Download to view",
43829
- settingsSubagentTitle: "Auto-open the Tasks page when a subagent appears",
43830
- settingsSubagentDesc: "Expand the side card and open the Tasks page when the current conversation spawns a new subagent; turn off to open it manually",
43831
- settingsJobsTitle: "Auto-open the Jobs page on a new background job",
43832
- settingsJobsDesc: "Expand the side card and open the Jobs page whenever a new background job appears for the current conversation (every new job triggers); turn off to open it manually",
44049
+ settingsSubagentTitle: "Auto-activate the Tasks page when a subagent appears",
44050
+ settingsSubagentDesc: "Activate the Tasks page when the current conversation spawns a new subagent; on wide screens the side card expands with it, narrow screens never force the full-screen drawer; turn off to open it manually",
44051
+ settingsJobsTitle: "Auto-activate the Jobs page on a new background job",
44052
+ settingsJobsDesc: "Activate the Jobs page whenever a new background job appears for the current conversation (every new job triggers); on wide screens the side card expands with it, narrow screens never force the full-screen drawer; turn off to open it manually",
43833
44053
  settingsToolsTitle: "Inject terminal tools for the model",
43834
44054
  settingsToolsDesc: "When enabled, the model can create and drive sidebar terminals through the 8 terminal_* tools (off by default)",
43835
44055
  settingsFontFamilyTitle: "Terminal font family",
@@ -43991,207 +44211,207 @@ globalThis.__dshChunks__["editor"] = (require) => {
43991
44211
  document.head.appendChild(tag);
43992
44212
  }
43993
44213
  var sidebar_module_css_default = {
43994
- "gitDiff": "S5HVoW_gitDiff",
43995
- "editorTreePanelFull": "S5HVoW_editorTreePanelFull",
43996
- "editorTreeDock": "S5HVoW_editorTreeDock",
43997
- "explorerEmpty": "S5HVoW_explorerEmpty",
43998
- "editorCm": "S5HVoW_editorCm",
43999
- "gitDiffHunk": "S5HVoW_gitDiffHunk",
44000
- "gitCommitInput": "S5HVoW_gitCommitInput",
44001
- "producedRow": "S5HVoW_producedRow",
44002
- "toggleButton": "S5HVoW_toggleButton",
44003
- "gitDiffTab": "S5HVoW_gitDiffTab",
44004
- "gitRowSelected": "S5HVoW_gitRowSelected",
44005
- "terminalWrap": "S5HVoW_terminalWrap",
44006
- "editorMain": "S5HVoW_editorMain",
44007
- "gitPlaceholder": "S5HVoW_gitPlaceholder",
44008
44214
  "editorStatus": "S5HVoW_editorStatus",
44009
- "explorerDir": "S5HVoW_explorerDir",
44010
- "editorPathInput": "S5HVoW_editorPathInput",
44011
- "editorTreeToggleActive": "S5HVoW_editorTreeToggleActive",
44012
- "dirtyDot": "S5HVoW_dirtyDot",
44013
- "gitDiffFileChevronExpanded": "S5HVoW_gitDiffFileChevronExpanded",
44215
+ "paneDrop": "S5HVoW_paneDrop",
44216
+ "uploadDropZonePill": "S5HVoW_uploadDropZonePill",
44217
+ "gitLogRow": "S5HVoW_gitLogRow",
44014
44218
  "gitDiffFileOld": "S5HVoW_gitDiffFileOld",
44015
- "gitSectionHeader": "S5HVoW_gitSectionHeader",
44016
- "gitConfirmDesc": "S5HVoW_gitConfirmDesc",
44017
- "panelResizeActive": "S5HVoW_panelResizeActive",
44018
- "gitLogLine1": "S5HVoW_gitLogLine1",
44019
- "tabBar": "S5HVoW_tabBar",
44020
- "splitCol": "S5HVoW_splitCol",
44021
- "editorSearchHint": "S5HVoW_editorSearchHint",
44022
- "tabBoundaryError": "S5HVoW_tabBoundaryError",
44023
- "dropOverlay": "S5HVoW_dropOverlay",
44024
- "tabBarDrop": "S5HVoW_tabBarDrop",
44025
- "explorer": "S5HVoW_explorer",
44026
- "panelHidden": "S5HVoW_panelHidden",
44027
- "uploadDropHero": "S5HVoW_uploadDropHero",
44028
- "browserBlockedTitle": "S5HVoW_browserBlockedTitle",
44029
- "browserBlockedButton": "S5HVoW_browserBlockedButton",
44030
- "uploadOverlayProgress": "S5HVoW_uploadOverlayProgress",
44031
- "terminalRetry": "S5HVoW_terminalRetry",
44032
- "terminalDepsBanner": "S5HVoW_terminalDepsBanner",
44033
- "gitName": "S5HVoW_gitName",
44034
- "uploadDropChatCard": "S5HVoW_uploadDropChatCard",
44035
- "uploadDropZone": "S5HVoW_uploadDropZone",
44036
- "producedLabel": "S5HVoW_producedLabel",
44037
- "uploadDropZoneText": "S5HVoW_uploadDropZoneText",
44038
- "boundaryError": "S5HVoW_boundaryError",
44039
- "panelResize": "S5HVoW_panelResize",
44040
- "dsh-row-in": "S5HVoW_dsh-row-in",
44041
- "explorerRow": "S5HVoW_explorerRow",
44042
- "sandboxStatusOn": "S5HVoW_sandboxStatusOn",
44043
- "gitSection": "S5HVoW_gitSection",
44044
- "openWithLabel": "S5HVoW_openWithLabel",
44045
- "openWithName": "S5HVoW_openWithName",
44046
- "tabTitle": "S5HVoW_tabTitle",
44047
- "floatTitle": "S5HVoW_floatTitle",
44048
- "explorerHidden": "S5HVoW_explorerHidden",
44219
+ "tabList": "S5HVoW_tabList",
44220
+ "editorSearchInput": "S5HVoW_editorSearchInput",
44221
+ "panel": "S5HVoW_panel",
44049
44222
  "explorerRowDropTarget": "S5HVoW_explorerRowDropTarget",
44050
- "browserStart": "S5HVoW_browserStart",
44051
- "toggleCluster": "S5HVoW_toggleCluster",
44052
- "tabClose": "S5HVoW_tabClose",
44053
- "gitWorktreeLabel": "S5HVoW_gitWorktreeLabel",
44223
+ "floatContent": "S5HVoW_floatContent",
44054
44224
  "gitBranchSelect": "S5HVoW_gitBranchSelect",
44055
- "pane": "S5HVoW_pane",
44056
- "openWithPin": "S5HVoW_openWithPin",
44057
- "browser": "S5HVoW_browser",
44058
- "paneTab": "S5HVoW_paneTab",
44059
- "tabActive": "S5HVoW_tabActive",
44060
- "gitEmpty": "S5HVoW_gitEmpty",
44225
+ "sandboxStatus": "S5HVoW_sandboxStatus",
44061
44226
  "dropRight": "S5HVoW_dropRight",
44062
- "paneCard": "S5HVoW_paneCard",
44227
+ "editorStatusError": "S5HVoW_editorStatusError",
44228
+ "gitDiffMetaText": "S5HVoW_gitDiffMetaText",
44229
+ "gitDiffExpand": "S5HVoW_gitDiffExpand",
44230
+ "producedRow": "S5HVoW_producedRow",
44231
+ "explorerRef": "S5HVoW_explorerRef",
44232
+ "uploadDropChatHint": "S5HVoW_uploadDropChatHint",
44233
+ "tabTitle": "S5HVoW_tabTitle",
44234
+ "explorerRowRevealed": "S5HVoW_explorerRowRevealed",
44235
+ "gitHeader": "S5HVoW_gitHeader",
44236
+ "sandboxDot": "S5HVoW_sandboxDot",
44237
+ "dropUp": "S5HVoW_dropUp",
44063
44238
  "uploadOverlayCancel": "S5HVoW_uploadOverlayCancel",
44064
- "gitDiffLine": "S5HVoW_gitDiffLine",
44065
- "terminalRepairCommand": "S5HVoW_terminalRepairCommand",
44066
- "openWithPinActive": "S5HVoW_openWithPinActive",
44067
- "browserBlocked": "S5HVoW_browserBlocked",
44068
- "dsh-toc-flash": "S5HVoW_dsh-toc-flash",
44069
- "uploadDropZonePill": "S5HVoW_uploadDropZonePill",
44070
- "floatDropHintLabel": "S5HVoW_floatDropHintLabel",
44071
- "editorSearchResult": "S5HVoW_editorSearchResult",
44239
+ "editorPlaceholder": "S5HVoW_editorPlaceholder",
44072
44240
  "terminalDepsActions": "S5HVoW_terminalDepsActions",
44073
- "dropLeft": "S5HVoW_dropLeft",
44074
- "uploadOverlayProgressFill": "S5HVoW_uploadOverlayProgressFill",
44075
- "selectionPopup": "S5HVoW_selectionPopup",
44076
- "tab": "S5HVoW_tab",
44077
- "paneTabHidden": "S5HVoW_paneTabHidden",
44078
- "dropDown": "S5HVoW_dropDown",
44079
- "explorerRoot": "S5HVoW_explorerRoot",
44080
- "browserBar": "S5HVoW_browserBar",
44081
- "gitDiffCtx": "S5HVoW_gitDiffCtx",
44241
+ "split": "S5HVoW_split",
44242
+ "explorerName": "S5HVoW_explorerName",
44243
+ "editorTitle": "S5HVoW_editorTitle",
44244
+ "editorTreePanelFull": "S5HVoW_editorTreePanelFull",
44245
+ "tabClose": "S5HVoW_tabClose",
44246
+ "terminalDepsHint": "S5HVoW_terminalDepsHint",
44247
+ "terminalRepairCommand": "S5HVoW_terminalRepairCommand",
44248
+ "gitWorktreeLabel": "S5HVoW_gitWorktreeLabel",
44249
+ "gitBadge": "S5HVoW_gitBadge",
44250
+ "gitDiff": "S5HVoW_gitDiff",
44251
+ "floatClose": "S5HVoW_floatClose",
44252
+ "gitDiffNum": "S5HVoW_gitDiffNum",
44253
+ "iconButton": "S5HVoW_iconButton",
44082
44254
  "gitCommit": "S5HVoW_gitCommit",
44255
+ "producedLabel": "S5HVoW_producedLabel",
44256
+ "editorSearchResult": "S5HVoW_editorSearchResult",
44257
+ "openWithName": "S5HVoW_openWithName",
44258
+ "gitDiffFileChevronExpanded": "S5HVoW_gitDiffFileChevronExpanded",
44259
+ "openWithPinActive": "S5HVoW_openWithPinActive",
44260
+ "editorMain": "S5HVoW_editorMain",
44261
+ "uploadDropChatCard": "S5HVoW_uploadDropChatCard",
44262
+ "workbench": "S5HVoW_workbench",
44263
+ "browserLiveTarget": "S5HVoW_browserLiveTarget",
44264
+ "terminalRetry": "S5HVoW_terminalRetry",
44265
+ "gitLogLine2": "S5HVoW_gitLogLine2",
44266
+ "explorerRow": "S5HVoW_explorerRow",
44267
+ "producedChip": "S5HVoW_producedChip",
44268
+ "editorTreePanel": "S5HVoW_editorTreePanel",
44269
+ "browserInput": "S5HVoW_browserInput",
44270
+ "uploadOverlayProgress": "S5HVoW_uploadOverlayProgress",
44271
+ "editorHeader": "S5HVoW_editorHeader",
44272
+ "browserBlockedActions": "S5HVoW_browserBlockedActions",
44273
+ "floatDropHint": "S5HVoW_floatDropHint",
44274
+ "browserFrame": "S5HVoW_browserFrame",
44083
44275
  "terminalDepsTitle": "S5HVoW_terminalDepsTitle",
44276
+ "gitDiffTabHeader": "S5HVoW_gitDiffTabHeader",
44277
+ "gitDiffFileTag": "S5HVoW_gitDiffFileTag",
44278
+ "gitDiffHunkHeader": "S5HVoW_gitDiffHunkHeader",
44279
+ "gitLogMeta": "S5HVoW_gitLogMeta",
44280
+ "gitLogRef": "S5HVoW_gitLogRef",
44281
+ "producedMore": "S5HVoW_producedMore",
44282
+ "explorerBroken": "S5HVoW_explorerBroken",
44283
+ "paneCard": "S5HVoW_paneCard",
44284
+ "tabBarPlus": "S5HVoW_tabBarPlus",
44285
+ "explorerError": "S5HVoW_explorerError",
44286
+ "panelBody": "S5HVoW_panelBody",
44287
+ "explorerSymlink": "S5HVoW_explorerSymlink",
44288
+ "dropOverlay": "S5HVoW_dropOverlay",
44289
+ "uploadDropZone": "S5HVoW_uploadDropZone",
44290
+ "dirtyDot": "S5HVoW_dirtyDot",
44291
+ "floatDropHintLabel": "S5HVoW_floatDropHintLabel",
44292
+ "uploadOverlay": "S5HVoW_uploadOverlay",
44084
44293
  "terminalDepsCommandRow": "S5HVoW_terminalDepsCommandRow",
44085
- "sandboxDot": "S5HVoW_sandboxDot",
44086
- "divider": "S5HVoW_divider",
44294
+ "git": "S5HVoW_git",
44295
+ "gitRowSelected": "S5HVoW_gitRowSelected",
44296
+ "browserBlockedTitle": "S5HVoW_browserBlockedTitle",
44297
+ "gitDiffCtx": "S5HVoW_gitDiffCtx",
44298
+ "gitDiffDel": "S5HVoW_gitDiffDel",
44087
44299
  "gitLogSubject": "S5HVoW_gitLogSubject",
44088
- "paneEmptyCards": "S5HVoW_paneEmptyCards",
44089
- "gitDiffFileChevron": "S5HVoW_gitDiffFileChevron",
44300
+ "gitDiffTabTitle": "S5HVoW_gitDiffTabTitle",
44301
+ "gitSectionHeader": "S5HVoW_gitSectionHeader",
44302
+ "gitDiffAdd": "S5HVoW_gitDiffAdd",
44303
+ "editorBanner": "S5HVoW_editorBanner",
44304
+ "terminalDepsNote": "S5HVoW_terminalDepsNote",
44305
+ "openWithChevron": "S5HVoW_openWithChevron",
44306
+ "sandboxStatusOn": "S5HVoW_sandboxStatusOn",
44307
+ "gitLogMore": "S5HVoW_gitLogMore",
44308
+ "openWithPin": "S5HVoW_openWithPin",
44309
+ "browserMessage": "S5HVoW_browserMessage",
44310
+ "gitDiffFile": "S5HVoW_gitDiffFile",
44311
+ "browserBar": "S5HVoW_browserBar",
44312
+ "editorCm": "S5HVoW_editorCm",
44313
+ "editorTreeToggleActive": "S5HVoW_editorTreeToggleActive",
44314
+ "sandboxAction": "S5HVoW_sandboxAction",
44315
+ "toggleCluster": "S5HVoW_toggleCluster",
44316
+ "dsh-toc-flash": "S5HVoW_dsh-toc-flash",
44090
44317
  "dividerCol": "S5HVoW_dividerCol",
44091
- "explorerSymlink": "S5HVoW_explorerSymlink",
44318
+ "gitEmpty": "S5HVoW_gitEmpty",
44319
+ "browserLiveCanvas": "S5HVoW_browserLiveCanvas",
44320
+ "pinnedTab": "S5HVoW_pinnedTab",
44321
+ "uploadOverlayTitle": "S5HVoW_uploadOverlayTitle",
44322
+ "browserBlocked": "S5HVoW_browserBlocked",
44092
44323
  "gitRow": "S5HVoW_gitRow",
44093
- "browserInput": "S5HVoW_browserInput",
44094
- "paneDrop": "S5HVoW_paneDrop",
44095
- "dropCenter": "S5HVoW_dropCenter",
44096
- "tabBadge": "S5HVoW_tabBadge",
44097
- "gitDiffTabHeader": "S5HVoW_gitDiffTabHeader",
44098
- "editorBody": "S5HVoW_editorBody",
44099
- "gitDiffFile": "S5HVoW_gitDiffFile",
44100
- "gitDiffMetaText": "S5HVoW_gitDiffMetaText",
44101
- "gitLogHash": "S5HVoW_gitLogHash",
44102
- "gitLogMore": "S5HVoW_gitLogMore",
44324
+ "browserBlockedDesc": "S5HVoW_browserBlockedDesc",
44325
+ "gitRowMain": "S5HVoW_gitRowMain",
44103
44326
  "editor": "S5HVoW_editor",
44104
44327
  "terminalBannerUrl": "S5HVoW_terminalBannerUrl",
44328
+ "explorerHidden": "S5HVoW_explorerHidden",
44329
+ "dividerRow": "S5HVoW_dividerRow",
44330
+ "terminal": "S5HVoW_terminal",
44331
+ "editorError": "S5HVoW_editorError",
44332
+ "gitDiffFilePath": "S5HVoW_gitDiffFilePath",
44333
+ "dropCenter": "S5HVoW_dropCenter",
44334
+ "gitDiffTab": "S5HVoW_gitDiffTab",
44335
+ "gitDiffLine": "S5HVoW_gitDiffLine",
44336
+ "gitCommitInput": "S5HVoW_gitCommitInput",
44337
+ "dropLeft": "S5HVoW_dropLeft",
44338
+ "uploadDropHero": "S5HVoW_uploadDropHero",
44339
+ "browserLive": "S5HVoW_browserLive",
44105
44340
  "browserLiveStatus": "S5HVoW_browserLiveStatus",
44106
- "browserLiveCanvas": "S5HVoW_browserLiveCanvas",
44107
- "editorBanner": "S5HVoW_editorBanner",
44108
- "workbench": "S5HVoW_workbench",
44109
- "gitDiffCode": "S5HVoW_gitDiffCode",
44110
- "producedChip": "S5HVoW_producedChip",
44111
- "floatContent": "S5HVoW_floatContent",
44112
- "floatClose": "S5HVoW_floatClose",
44113
- "explorerBroken": "S5HVoW_explorerBroken",
44114
- "gitLogRow": "S5HVoW_gitLogRow",
44115
- "editorBinary": "S5HVoW_editorBinary",
44116
- "gitHeader": "S5HVoW_gitHeader",
44117
- "editorTreePanel": "S5HVoW_editorTreePanel",
44118
- "gitDiffHunkHeader": "S5HVoW_gitDiffHunkHeader",
44119
- "gitWorktreeRow": "S5HVoW_gitWorktreeRow",
44120
- "terminalDepsHint": "S5HVoW_terminalDepsHint",
44121
- "editorBinaryNotice": "S5HVoW_editorBinaryNotice",
44122
44341
  "splitChild": "S5HVoW_splitChild",
44123
- "browserFrame": "S5HVoW_browserFrame",
44124
- "paneContent": "S5HVoW_paneContent",
44125
- "editorSearchInput": "S5HVoW_editorSearchInput",
44126
- "gitDiffFileTag": "S5HVoW_gitDiffFileTag",
44342
+ "floatWindowDragging": "S5HVoW_floatWindowDragging",
44343
+ "splitRow": "S5HVoW_splitRow",
44344
+ "editorTreeResize": "S5HVoW_editorTreeResize",
44345
+ "gitDiffHunk": "S5HVoW_gitDiffHunk",
44127
44346
  "dividerActive": "S5HVoW_dividerActive",
44128
- "pinnedTab": "S5HVoW_pinnedTab",
44129
- "uploadOverlay": "S5HVoW_uploadOverlay",
44130
- "editorTreeSearch": "S5HVoW_editorTreeSearch",
44131
- "explorerRowRevealed": "S5HVoW_explorerRowRevealed",
44132
- "gitDiffExpand": "S5HVoW_gitDiffExpand",
44133
- "gitDiffHunkSection": "S5HVoW_gitDiffHunkSection",
44347
+ "gitDiffFileChevron": "S5HVoW_gitDiffFileChevron",
44348
+ "boundaryError": "S5HVoW_boundaryError",
44349
+ "explorerEmpty": "S5HVoW_explorerEmpty",
44350
+ "gitDiffCode": "S5HVoW_gitDiffCode",
44351
+ "tabBadge": "S5HVoW_tabBadge",
44352
+ "uploadOverlayStatus": "S5HVoW_uploadOverlayStatus",
44134
44353
  "floatResize": "S5HVoW_floatResize",
44135
- "panelBody": "S5HVoW_panelBody",
44354
+ "gitPlaceholder": "S5HVoW_gitPlaceholder",
44355
+ "gitConfirmDesc": "S5HVoW_gitConfirmDesc",
44356
+ "dsh-row-in": "S5HVoW_dsh-row-in",
44357
+ "floatWindow": "S5HVoW_floatWindow",
44358
+ "browser": "S5HVoW_browser",
44136
44359
  "floatHeader": "S5HVoW_floatHeader",
44137
- "uploadDropChatHint": "S5HVoW_uploadDropChatHint",
44138
- "editorDownloadLink": "S5HVoW_editorDownloadLink",
44139
- "terminalDepsNote": "S5HVoW_terminalDepsNote",
44140
- "git": "S5HVoW_git",
44141
- "terminal": "S5HVoW_terminal",
44142
- "panel": "S5HVoW_panel",
44143
- "sandboxStatus": "S5HVoW_sandboxStatus",
44144
- "iconButton": "S5HVoW_iconButton",
44145
- "gitDiffNum": "S5HVoW_gitDiffNum",
44146
- "gitCommitButton": "S5HVoW_gitCommitButton",
44147
- "gitLogMeta": "S5HVoW_gitLogMeta",
44148
- "dropUp": "S5HVoW_dropUp",
44149
- "uploadOverlayStatus": "S5HVoW_uploadOverlayStatus",
44150
- "gitLogRef": "S5HVoW_gitLogRef",
44151
- "explorerName": "S5HVoW_explorerName",
44152
- "gitDiffMeta": "S5HVoW_gitDiffMeta",
44153
- "browserLiveTarget": "S5HVoW_browserLiveTarget",
44154
- "floatDropHint": "S5HVoW_floatDropHint",
44155
- "floatWindowDragging": "S5HVoW_floatWindowDragging",
44156
- "orphanedType": "S5HVoW_orphanedType",
44157
- "editorTreeResize": "S5HVoW_editorTreeResize",
44158
- "uploadOverlayCard": "S5HVoW_uploadOverlayCard",
44159
- "split": "S5HVoW_split",
44160
- "sandboxStatusOff": "S5HVoW_sandboxStatusOff",
44161
- "browserBlockedDesc": "S5HVoW_browserBlockedDesc",
44162
- "terminalBanner": "S5HVoW_terminalBanner",
44163
- "explorerHeader": "S5HVoW_explorerHeader",
44164
- "splitRow": "S5HVoW_splitRow",
44360
+ "editorTreeDock": "S5HVoW_editorTreeDock",
44361
+ "tabActive": "S5HVoW_tabActive",
44362
+ "splitCol": "S5HVoW_splitCol",
44363
+ "paneEmptyCards": "S5HVoW_paneEmptyCards",
44364
+ "explorerRoot": "S5HVoW_explorerRoot",
44165
44365
  "explorerBody": "S5HVoW_explorerBody",
44166
- "explorerError": "S5HVoW_explorerError",
44167
- "sandboxStatusText": "S5HVoW_sandboxStatusText",
44168
- "tabBarPlus": "S5HVoW_tabBarPlus",
44169
- "editorError": "S5HVoW_editorError",
44170
- "gitLogLine2": "S5HVoW_gitLogLine2",
44171
- "openWithChevron": "S5HVoW_openWithChevron",
44172
- "browserLive": "S5HVoW_browserLive",
44173
- "editorHeader": "S5HVoW_editorHeader",
44174
- "gitDiffTabTitle": "S5HVoW_gitDiffTabTitle",
44175
- "browserMessage": "S5HVoW_browserMessage",
44176
- "editorPlaceholder": "S5HVoW_editorPlaceholder",
44177
- "gitBadge": "S5HVoW_gitBadge",
44178
- "explorerRef": "S5HVoW_explorerRef",
44179
- "editorStatusError": "S5HVoW_editorStatusError",
44180
- "tabList": "S5HVoW_tabList",
44181
- "gitDiffDel": "S5HVoW_gitDiffDel",
44182
- "gitDiffAdd": "S5HVoW_gitDiffAdd",
44366
+ "editorBinaryNotice": "S5HVoW_editorBinaryNotice",
44367
+ "browserBlockedButton": "S5HVoW_browserBlockedButton",
44368
+ "pane": "S5HVoW_pane",
44369
+ "paneContent": "S5HVoW_paneContent",
44370
+ "dropDown": "S5HVoW_dropDown",
44371
+ "terminalDepsBanner": "S5HVoW_terminalDepsBanner",
44372
+ "terminalBanner": "S5HVoW_terminalBanner",
44373
+ "gitWorktreeRow": "S5HVoW_gitWorktreeRow",
44374
+ "gitDiffHunkSection": "S5HVoW_gitDiffHunkSection",
44375
+ "panelResizeActive": "S5HVoW_panelResizeActive",
44376
+ "tabBarDrop": "S5HVoW_tabBarDrop",
44377
+ "explorerDir": "S5HVoW_explorerDir",
44378
+ "editorBinary": "S5HVoW_editorBinary",
44379
+ "explorer": "S5HVoW_explorer",
44380
+ "sandboxStatusOff": "S5HVoW_sandboxStatusOff",
44381
+ "tabBar": "S5HVoW_tabBar",
44183
44382
  "gitError": "S5HVoW_gitError",
44184
- "editorTitle": "S5HVoW_editorTitle",
44185
- "browserBlockedActions": "S5HVoW_browserBlockedActions",
44383
+ "explorerHeader": "S5HVoW_explorerHeader",
44384
+ "editorTreeSearch": "S5HVoW_editorTreeSearch",
44385
+ "openWithLabel": "S5HVoW_openWithLabel",
44186
44386
  "gitLink": "S5HVoW_gitLink",
44187
- "gitDiffFilePath": "S5HVoW_gitDiffFilePath",
44188
- "sandboxAction": "S5HVoW_sandboxAction",
44189
- "producedMore": "S5HVoW_producedMore",
44387
+ "tabBoundaryError": "S5HVoW_tabBoundaryError",
44388
+ "editorSearchHint": "S5HVoW_editorSearchHint",
44389
+ "toggleButton": "S5HVoW_toggleButton",
44390
+ "sandboxStatusText": "S5HVoW_sandboxStatusText",
44391
+ "panelHidden": "S5HVoW_panelHidden",
44392
+ "uploadOverlayProgressFill": "S5HVoW_uploadOverlayProgressFill",
44393
+ "terminalWrap": "S5HVoW_terminalWrap",
44394
+ "gitName": "S5HVoW_gitName",
44395
+ "editorBody": "S5HVoW_editorBody",
44396
+ "gitSection": "S5HVoW_gitSection",
44397
+ "floatTitle": "S5HVoW_floatTitle",
44398
+ "paneTabHidden": "S5HVoW_paneTabHidden",
44399
+ "paneTab": "S5HVoW_paneTab",
44190
44400
  "explorerCopied": "S5HVoW_explorerCopied",
44191
- "uploadOverlayTitle": "S5HVoW_uploadOverlayTitle",
44192
- "gitRowMain": "S5HVoW_gitRowMain",
44193
- "floatWindow": "S5HVoW_floatWindow",
44194
- "dividerRow": "S5HVoW_dividerRow"
44401
+ "divider": "S5HVoW_divider",
44402
+ "tab": "S5HVoW_tab",
44403
+ "uploadDropZoneText": "S5HVoW_uploadDropZoneText",
44404
+ "editorPathInput": "S5HVoW_editorPathInput",
44405
+ "panelResize": "S5HVoW_panelResize",
44406
+ "browserStart": "S5HVoW_browserStart",
44407
+ "selectionPopup": "S5HVoW_selectionPopup",
44408
+ "gitDiffMeta": "S5HVoW_gitDiffMeta",
44409
+ "gitLogHash": "S5HVoW_gitLogHash",
44410
+ "gitLogLine1": "S5HVoW_gitLogLine1",
44411
+ "editorDownloadLink": "S5HVoW_editorDownloadLink",
44412
+ "gitCommitButton": "S5HVoW_gitCommitButton",
44413
+ "uploadOverlayCard": "S5HVoW_uploadOverlayCard",
44414
+ "orphanedType": "S5HVoW_orphanedType"
44195
44415
  };
44196
44416
  //#endregion
44197
44417
  //#region src/client/TextEditor.tsx
@@ -44222,38 +44442,26 @@ globalThis.__dshChunks__["editor"] = (require) => {
44222
44442
  const themeCompRef = (0, react.useRef)(null);
44223
44443
  /** The app's resolved color scheme; the editor re-themes in place on flips. */
44224
44444
  const [dark, setDark] = (0, react.useState)(() => isDarkScheme());
44225
- /** The floating "add to conversation" popup (viewport-anchored; null = hidden). */
44226
- const [popup, setPopup] = (0, react.useState)(null);
44227
- /** Live mirror of the popup state for click-time reads (no re-render race). */
44228
- const popupRef = (0, react.useRef)(null);
44229
- const hidePopup = () => {
44230
- popupRef.current = null;
44231
- setPopup(null);
44232
- };
44233
- /** Anchor the popup above the selection center; clamp inside the viewport. */
44234
- const showPopup = (insert, left, top) => {
44235
- const next = {
44236
- insert,
44237
- left: Math.min(Math.max(left, 80), window.innerWidth - 80),
44238
- top
44239
- };
44240
- popupRef.current = next;
44241
- setPopup(next);
44242
- };
44243
- /** The popup button's click: insert the stored payload into the draft. */
44244
- const commitPopup = () => {
44245
- const current = popupRef.current;
44246
- if (current === null) return;
44247
- appendToDraft(ctx, scope.sessionId, current.insert);
44248
- hidePopup();
44249
- };
44445
+ /**
44446
+ * The floating "add to conversation" popup (viewport-anchored; null =
44447
+ * hidden). The hook owns show/hide/commit plus the global dismissal
44448
+ * listeners (outside mousedown, Escape, hidden tab/window, and the editor
44449
+ * surface leaving the viewport — the tab-switch/panel-collapse paths have
44450
+ * no DOM events of their own) — see selection-popup.ts.
44451
+ */
44452
+ const selectionPopup = useSelectionPopup({
44453
+ onCommit: (insert) => {
44454
+ appendToDraft(ctx, scope.sessionId, insert);
44455
+ },
44456
+ getSurface: () => hostRef.current
44457
+ });
44250
44458
  (0, react.useEffect)(() => subscribeColorScheme(() => {
44251
44459
  setDark(isDarkScheme());
44252
44460
  }), []);
44253
44461
  (0, react.useEffect)(() => {
44254
44462
  setDirty(false);
44255
44463
  setSaveState("idle");
44256
- hidePopup();
44464
+ selectionPopup.hide();
44257
44465
  }, [content]);
44258
44466
  (0, react.useEffect)(() => {
44259
44467
  if (content === void 0) return;
@@ -44291,31 +44499,31 @@ globalThis.__dshChunks__["editor"] = (require) => {
44291
44499
  ]),
44292
44500
  EditorView.updateListener.of((update) => {
44293
44501
  if (update.geometryChanged || update.viewportChanged) {
44294
- hidePopup();
44502
+ selectionPopup.hide();
44295
44503
  return;
44296
44504
  }
44297
44505
  if (!update.view.hasFocus) {
44298
- hidePopup();
44506
+ selectionPopup.hide();
44299
44507
  return;
44300
44508
  }
44301
44509
  if (!(update.selectionSet || update.docChanged || update.focusChanged)) return;
44302
44510
  const sel = update.state.selection.main;
44303
44511
  if (sel.empty) {
44304
- hidePopup();
44512
+ selectionPopup.hide();
44305
44513
  return;
44306
44514
  }
44307
44515
  const text = update.state.sliceDoc(sel.from, sel.to);
44308
44516
  if (text.trim() === "") {
44309
- hidePopup();
44517
+ selectionPopup.hide();
44310
44518
  return;
44311
44519
  }
44312
44520
  const rect = update.view.coordsAtPos(sel.head);
44313
44521
  if (rect === null) {
44314
- hidePopup();
44522
+ selectionPopup.hide();
44315
44523
  return;
44316
44524
  }
44317
44525
  const doc = update.state.doc;
44318
- showPopup(buildSelectionInsert(path, scope.cwd, {
44526
+ selectionPopup.show(buildSelectionInsert(path, scope.cwd, {
44319
44527
  start: doc.lineAt(sel.from).number,
44320
44528
  end: doc.lineAt(sel.to).number
44321
44529
  }, text), rect.left - window.scrollX + (rect.right - rect.left) / 2, rect.top - window.scrollY);
@@ -44403,17 +44611,18 @@ globalThis.__dshChunks__["editor"] = (require) => {
44403
44611
  className: sidebar_module_css_default.editorCm,
44404
44612
  ref: hostRef
44405
44613
  })] }),
44406
- popup !== null && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
44614
+ selectionPopup.popup !== null && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
44407
44615
  type: "button",
44616
+ ref: selectionPopup.buttonRef,
44408
44617
  className: sidebar_module_css_default.selectionPopup,
44409
44618
  style: {
44410
- left: popup.left,
44411
- top: popup.top
44619
+ left: selectionPopup.popup.left,
44620
+ top: selectionPopup.popup.top
44412
44621
  },
44413
44622
  onMouseDown: (event) => {
44414
44623
  event.preventDefault();
44415
44624
  },
44416
- onClick: commitPopup,
44625
+ onClick: selectionPopup.commit,
44417
44626
  children: t("addToConversation")
44418
44627
  }), document.body)
44419
44628
  ] });