@dsh-electron/dsh-plugin-multi-root-workspace 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.en.md +89 -0
  2. package/CHANGELOG.md +89 -0
  3. package/README.en.md +96 -20
  4. package/README.md +97 -19
  5. package/cordis.patch.yml +22 -1
  6. package/lib/client.js +234 -71
  7. package/lib/client.js.map +1 -1
  8. package/lib/{command-BSkrYOAf.js → command-DyOWujPo.js} +24 -61
  9. package/lib/command.js +2 -2
  10. package/lib/compat-CRdv0vPw.js +272 -0
  11. package/lib/compat.js +2 -0
  12. package/lib/{fs-D7UoCb7T.js → fs-D_Sw3o5z.js} +7 -3
  13. package/lib/fs.js +1 -1
  14. package/lib/index.js +8 -6
  15. package/lib/instructions-Cn1Jj5Xi.js +703 -0
  16. package/lib/instructions.js +2 -0
  17. package/lib/registry-DySMbjgW.js +793 -0
  18. package/lib/registry-lease-win32-dy8TQMD9.js +93 -0
  19. package/lib/registry.js +2 -466
  20. package/lib/{sandbox-BhuMTDgH.js → sandbox-D8Fw95FM.js} +51 -4
  21. package/lib/sandbox.js +1 -1
  22. package/lib/scope.js +1 -1
  23. package/lib/types/client/locales.d.ts +6 -0
  24. package/lib/types/client/panel-client.d.ts +0 -2
  25. package/lib/types/command.d.ts +17 -0
  26. package/lib/types/compat/agent-instructions.d.ts +138 -0
  27. package/lib/types/compat/client-icons.d.ts +40 -0
  28. package/lib/types/compat/client-session.d.ts +32 -0
  29. package/lib/types/compat/dsh-version.d.ts +119 -0
  30. package/lib/types/compat/llm-message.d.ts +72 -0
  31. package/lib/types/compat/sandbox-confine.d.ts +58 -0
  32. package/lib/types/compat/tool-result.d.ts +29 -0
  33. package/lib/types/compat.d.ts +85 -0
  34. package/lib/types/contract.d.ts +6 -8
  35. package/lib/types/index.d.ts +19 -5
  36. package/lib/types/instructions.d.ts +125 -0
  37. package/lib/types/registry-lease-win32.d.ts +29 -0
  38. package/lib/types/registry-lease.d.ts +62 -0
  39. package/lib/types/registry.d.ts +130 -19
  40. package/lib/types/roots.d.ts +1 -1
  41. package/lib/types/sandbox.d.ts +22 -2
  42. package/package.json +60 -13
  43. package/lib/{roots-DyT2jgEP.js → roots-DasWEBJk.js} +1 -1
package/lib/client.js CHANGED
@@ -4,9 +4,96 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ //#region \0rolldown/runtime.js
8
+ var __create = Object.create;
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __getOwnPropNames = Object.getOwnPropertyNames;
12
+ var __getProtoOf = Object.getPrototypeOf;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
16
+ key = keys[i];
17
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
18
+ get: ((k) => from[k]).bind(null, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
25
+ value: mod,
26
+ enumerable: true
27
+ }) : target, mod));
28
+ //#endregion
7
29
  let react = require("react");
8
30
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
31
+ _deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
9
32
  let react_jsx_runtime = require("react/jsx-runtime");
33
+ //#region src/compat/client-session.ts
34
+ /**
35
+ * The session the composed client is showing, when it can name one.
36
+ * @param sessions - the client `sessions` service, or whatever this
37
+ * composition provided under that name. Absence is a supported state.
38
+ * @returns the session id, or `undefined` when no main view holds one.
39
+ */
40
+ function currentSessionIdOf(sessions) {
41
+ const snapshot = listSnapshotOf(sessions);
42
+ if (snapshot === void 0) return void 0;
43
+ const current = snapshot.current;
44
+ if (typeof current === "string" && current !== "") return current;
45
+ return mainViewSessionId(snapshot.byId);
46
+ }
47
+ /**
48
+ * The list snapshot, when the service actually exposes one.
49
+ *
50
+ * `getSnapshot` is invoked as a method so a real store can read `this`.
51
+ * Extracting the function and calling it unbound drops that binding and
52
+ * yields `undefined` even when a session is selected.
53
+ */
54
+ function listSnapshotOf(sessions) {
55
+ if (sessions === null || typeof sessions !== "object") return void 0;
56
+ const list = sessions.list;
57
+ if (list === null || typeof list !== "object") return void 0;
58
+ const holder = list;
59
+ if (typeof holder.getSnapshot !== "function") return void 0;
60
+ let snapshot;
61
+ try {
62
+ snapshot = holder.getSnapshot();
63
+ } catch {
64
+ return;
65
+ }
66
+ if (snapshot === null || typeof snapshot !== "object") return void 0;
67
+ return snapshot;
68
+ }
69
+ /**
70
+ * The first catalog row retained by the main view.
71
+ *
72
+ * Enumeration order is the catalog's insertion order, which is the order
73
+ * upstream's own main-binding projection scans. A row counts only while
74
+ * `retainedBy.mainView` is a positive number: zero, a missing source, and a
75
+ * non-numeric value are not a selection.
76
+ * @param byId - the catalog map, or anything else the snapshot happened to carry.
77
+ * @returns that row's session id.
78
+ */
79
+ function mainViewSessionId(byId) {
80
+ if (byId === null || typeof byId !== "object") return void 0;
81
+ for (const [key, row] of Object.entries(byId)) {
82
+ if (!isMainViewRow(row)) continue;
83
+ const id = row.id;
84
+ if (typeof id === "string" && id !== "") return id;
85
+ if (key !== "") return key;
86
+ }
87
+ }
88
+ /** Whether one catalog value is a row the main view currently retains. */
89
+ function isMainViewRow(row) {
90
+ if (row === null || typeof row !== "object") return false;
91
+ const retainedBy = row.retainedBy;
92
+ if (retainedBy === null || typeof retainedBy !== "object") return false;
93
+ const count = retainedBy.mainView;
94
+ return typeof count === "number" && count > 0;
95
+ }
96
+ //#endregion
10
97
  //#region node_modules/.pnpm/zod@4.6.2/node_modules/zod/v4/core/util.js
11
98
  function getEnumValues(entries) {
12
99
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
@@ -5139,8 +5226,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5139
5226
  /** The absolute logical channel both halves speak over. */
5140
5227
  const PANEL_CHANNEL = "/multi-root-workspace";
5141
5228
  object({
5142
- primaryRoot: string().optional(),
5143
- sessionId: string().optional(),
5229
+ sessionId: string().min(1),
5144
5230
  entry: object({
5145
5231
  ordinal: number().int().positive(),
5146
5232
  id: string(),
@@ -5283,6 +5369,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5283
5369
  "panel.additional": "附属工作目录",
5284
5370
  "panel.empty": "还没有附属工作目录。",
5285
5371
  "panel.emptyHint": "添加后,Agent 可在同一会话中读写该目录;macOS/Linux 的受限 bash 同步生效,Windows 当前仅覆盖 fs 写路径。",
5372
+ "panel.noSession": "当前没有活动会话",
5286
5373
  "panel.loading": "正在读取…",
5287
5374
  "panel.retry": "重试",
5288
5375
  "panel.close": "关闭",
@@ -5316,9 +5403,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5316
5403
  "error.not-found": "没有找到对应的登记项。",
5317
5404
  "error.invalid-ref": "请求缺少必要的标识。",
5318
5405
  "error.storage-unavailable": "根目录登记的存储不可用,请检查 $DSH_HOME/storages 下的文件。",
5406
+ "error.registry-contended": "根目录登记正由另一个 DSH 进程占用;本进程不会授予附加根。关闭另一个进程后点重试。",
5319
5407
  "error.reveal-unavailable": "无法打开系统的文件管理器;登记项不受影响,路径仍可复制。",
5320
5408
  "error.unavailable": "无法连接到 dsh 主进程。",
5321
5409
  "error.copy-failed": "无法写入剪贴板,请检查浏览器的剪贴板权限。",
5410
+ "error.session-not-found": "找不到该会话;请先打开一个工作区会话。",
5322
5411
  "error.fallback": "操作失败。"
5323
5412
  };
5324
5413
  /** English copy, pinned to the Chinese key set. */
@@ -5332,6 +5421,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5332
5421
  "panel.additional": "Secondary working directories",
5333
5422
  "panel.empty": "No secondary working directories yet.",
5334
5423
  "panel.emptyHint": "Once added, the agent can use the folder in this session; confined bash follows on macOS/Linux, while Windows currently covers fs writes only.",
5424
+ "panel.noSession": "No active session",
5335
5425
  "panel.loading": "Loading…",
5336
5426
  "panel.retry": "Retry",
5337
5427
  "panel.close": "Close",
@@ -5365,9 +5455,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5365
5455
  "error.not-found": "No registration matches that reference.",
5366
5456
  "error.invalid-ref": "The request is missing a required identity.",
5367
5457
  "error.storage-unavailable": "The root registry store is unavailable; check the files under $DSH_HOME/storages.",
5458
+ "error.registry-contended": "The root registry is owned by another DSH process; this process grants no additional roots. Close the other process, then retry.",
5368
5459
  "error.reveal-unavailable": "Could not open the system file manager; the registration is untouched, and the path can still be copied.",
5369
5460
  "error.unavailable": "Could not reach the dsh host process.",
5370
5461
  "error.copy-failed": "Could not write to the clipboard; check the browser's clipboard permission.",
5462
+ "error.session-not-found": "That session is not active; open a workspace session first.",
5371
5463
  "error.fallback": "The operation failed."
5372
5464
  };
5373
5465
  //#endregion
@@ -5429,11 +5521,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5429
5521
  if (!parsed.ok) throw new PanelError("panel/bad-response", parsed.message);
5430
5522
  return parsed.value;
5431
5523
  }
5432
- /** The current session id, when the composed client can name one. */
5433
- function currentSessionIdOf(sessions) {
5434
- const current = sessions?.list?.getSnapshot?.().current;
5435
- return typeof current === "string" && current !== "" ? current : void 0;
5436
- }
5437
5524
  //#endregion
5438
5525
  //#region src/client/styles.ts
5439
5526
  /**
@@ -5810,6 +5897,43 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5810
5897
  width: 32px;
5811
5898
  }
5812
5899
  `;
5900
+ //#endregion
5901
+ //#region src/compat/client-icons.ts
5902
+ /**
5903
+ * The installed icon module, addressed by export name.
5904
+ *
5905
+ * Named imports cannot spell both releases: each name is absent from the
5906
+ * other release's declaration, so the compiler is told once, here.
5907
+ */
5908
+ const installed = _deepseek_ai_dsh_client_ui_primitives;
5909
+ /**
5910
+ * Pick the first export name this release actually provides.
5911
+ * @param module - the icon module to read.
5912
+ * @param names - candidate export names, preferred first.
5913
+ * @returns the component.
5914
+ * @throws {Error} when none of the names is exported. That is a compatibility
5915
+ * break to adapt here, not a missing optional peer.
5916
+ */
5917
+ function selectIcon(module, names) {
5918
+ for (const name of names) {
5919
+ const found = module[name];
5920
+ if (found !== void 0) return found;
5921
+ }
5922
+ throw new Error(`multi-root workspace: @deepseek-ai/dsh-client-ui-primitives exports none of ${names.join(", ")}; the workspace-folders panel cannot render its icons. Adapt src/compat/client-icons.ts to the installed release.`);
5923
+ }
5924
+ /** Resolved once, against the installed module. */
5925
+ function icon(pixelName, regularName) {
5926
+ return selectIcon(installed, [pixelName, regularName]);
5927
+ }
5928
+ const IconChevronDown = icon("IconChevronDownOutline14", "IconChevronDownOutlineRegular");
5929
+ const IconChevronUp = icon("IconChevronUpOutline14", "IconChevronUpOutlineRegular");
5930
+ const IconCopy = icon("IconCopyOutline16", "IconCopyOutlineRegular");
5931
+ const IconEdit = icon("IconEditOutline16", "IconEditOutlineRegular");
5932
+ const IconEllipsis = icon("IconEllipsisOutline16", "IconEllipsisOutlineRegular");
5933
+ const IconFolderClose = icon("IconFolderClose16", "IconFolderCloseRegular");
5934
+ const IconFolderOpen = icon("IconFolderOpenOutline16", "IconFolderOpenOutlineRegular");
5935
+ const IconPlus = icon("IconPlusOutline16", "IconPlusOutlineRegular");
5936
+ const IconTrash = icon("IconTrashOutline16", "IconTrashOutlineRegular");
5813
5937
  //#endregion
5814
5938
  //#region src/client/WorkspaceFoldersAction.tsx
5815
5939
  /**
@@ -5918,7 +6042,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5918
6042
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5919
6043
  className: "mrfw-triggerIcon",
5920
6044
  "aria-hidden": "true",
5921
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderClose16, { size: rail ? 18 : 16 })
6045
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFolderClose, { size: rail ? 18 : 16 })
5922
6046
  }), rail ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5923
6047
  className: "mrfw-triggerLabel",
5924
6048
  children: props.t("action.label")
@@ -5956,7 +6080,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5956
6080
  const [state, setState] = (0, react.useState)({
5957
6081
  view: void 0,
5958
6082
  error: void 0,
5959
- busy: false
6083
+ busy: false,
6084
+ noSession: false
5960
6085
  });
5961
6086
  const [manualPath, setManualPath] = (0, react.useState)("");
5962
6087
  const [aliasFor, setAliasFor] = (0, react.useState)(void 0);
@@ -5972,7 +6097,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5972
6097
  }, []);
5973
6098
  const requestBase = (0, react.useCallback)(() => {
5974
6099
  const current = props.sessionId?.();
5975
- return current === void 0 ? {} : { sessionId: current };
6100
+ return current === void 0 || current === "" ? void 0 : { sessionId: current };
5976
6101
  }, [props.sessionId]);
5977
6102
  (0, react.useEffect)(() => {
5978
6103
  dialogRef.current?.focus();
@@ -6008,29 +6133,43 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6008
6133
  setState({
6009
6134
  view: void 0,
6010
6135
  error: new PanelError("unavailable", "no connection"),
6011
- busy: false
6136
+ busy: false,
6137
+ noSession: false
6138
+ });
6139
+ return;
6140
+ }
6141
+ const base = requestBase();
6142
+ if (base === void 0) {
6143
+ setState({
6144
+ view: void 0,
6145
+ error: void 0,
6146
+ busy: false,
6147
+ noSession: true
6012
6148
  });
6013
6149
  return;
6014
6150
  }
6015
6151
  const epoch = ++requestEpoch.current;
6016
6152
  setState((previous) => ({
6017
6153
  ...previous,
6018
- busy: true
6154
+ busy: true,
6155
+ noSession: false
6019
6156
  }));
6020
6157
  try {
6021
- const view = await panel.call("list", requestBase());
6158
+ const view = await panel.call("list", base);
6022
6159
  if (!mounted.current || epoch !== requestEpoch.current) return;
6023
6160
  setState({
6024
6161
  view,
6025
6162
  error: void 0,
6026
- busy: false
6163
+ busy: false,
6164
+ noSession: false
6027
6165
  });
6028
6166
  } catch (error) {
6029
6167
  if (!mounted.current || epoch !== requestEpoch.current) return;
6030
6168
  setState({
6031
6169
  view: void 0,
6032
6170
  error: asPanelError(error),
6033
- busy: false
6171
+ busy: false,
6172
+ noSession: false
6034
6173
  });
6035
6174
  }
6036
6175
  }, [panel, requestBase]);
@@ -6044,21 +6183,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6044
6183
  */
6045
6184
  const mutate = (0, react.useCallback)(async (endpoint, payload) => {
6046
6185
  if (panel === void 0) return false;
6186
+ const base = requestBase();
6187
+ if (base === void 0) {
6188
+ setState({
6189
+ view: void 0,
6190
+ error: void 0,
6191
+ busy: false,
6192
+ noSession: true
6193
+ });
6194
+ return false;
6195
+ }
6047
6196
  const epoch = ++requestEpoch.current;
6048
6197
  setState((previous) => ({
6049
6198
  ...previous,
6050
- busy: true
6199
+ busy: true,
6200
+ noSession: false
6051
6201
  }));
6052
6202
  try {
6053
6203
  const view = await panel.call(endpoint, {
6054
- ...requestBase(),
6204
+ ...base,
6055
6205
  ...payload
6056
6206
  });
6057
6207
  if (!mounted.current || epoch !== requestEpoch.current) return false;
6058
6208
  setState({
6059
6209
  view,
6060
6210
  error: void 0,
6061
- busy: false
6211
+ busy: false,
6212
+ noSession: false
6062
6213
  });
6063
6214
  return true;
6064
6215
  } catch (error) {
@@ -6105,14 +6256,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6105
6256
  /** Reveal one root: the answer is the revealed path, not a new view. */
6106
6257
  const reveal = (0, react.useCallback)(async (root) => {
6107
6258
  if (panel === void 0) return;
6259
+ const base = requestBase();
6260
+ if (base === void 0) {
6261
+ setState({
6262
+ view: void 0,
6263
+ error: void 0,
6264
+ busy: false,
6265
+ noSession: true
6266
+ });
6267
+ return;
6268
+ }
6108
6269
  const epoch = ++requestEpoch.current;
6109
6270
  setState((previous) => ({
6110
6271
  ...previous,
6111
- busy: true
6272
+ busy: true,
6273
+ noSession: false
6112
6274
  }));
6113
6275
  try {
6114
6276
  await panel.call("reveal", {
6115
- ...requestBase(),
6277
+ ...base,
6116
6278
  entry: entryOf(root)
6117
6279
  });
6118
6280
  if (!mounted.current || epoch !== requestEpoch.current) return;
@@ -6189,7 +6351,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6189
6351
  })]
6190
6352
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6191
6353
  className: "mrfw-body",
6192
- children: [
6354
+ children: [state.noSession ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6355
+ className: "mrfw-note",
6356
+ children: t("panel.noSession")
6357
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
6193
6358
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6194
6359
  className: "mrfw-description",
6195
6360
  children: t("panel.subtitle")
@@ -6275,7 +6440,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6275
6440
  onClick: () => {
6276
6441
  copyPath(root);
6277
6442
  },
6278
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16, {}),
6443
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopy, {}),
6279
6444
  label: copiedId === key ? t("panel.copied") : t("panel.copyPath")
6280
6445
  }),
6281
6446
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
@@ -6283,7 +6448,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6283
6448
  onClick: () => {
6284
6449
  reveal(root);
6285
6450
  },
6286
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenOutline16, {}),
6451
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFolderOpen, {}),
6287
6452
  label: t("panel.reveal")
6288
6453
  }),
6289
6454
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
@@ -6291,7 +6456,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6291
6456
  onClick: () => {
6292
6457
  move(root, roots[index - 1]);
6293
6458
  },
6294
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutline14, {}),
6459
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronUp, {}),
6295
6460
  label: t("panel.moveUp")
6296
6461
  }),
6297
6462
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
@@ -6299,7 +6464,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6299
6464
  onClick: () => {
6300
6465
  move(root, roots[index + 2]);
6301
6466
  },
6302
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {}),
6467
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronDown, {}),
6303
6468
  label: t("panel.moveDown")
6304
6469
  }),
6305
6470
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
@@ -6310,11 +6475,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6310
6475
  items: [{
6311
6476
  id: "rename",
6312
6477
  label: t("panel.rename"),
6313
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {})
6478
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconEdit, {})
6314
6479
  }, {
6315
6480
  id: "remove",
6316
6481
  label: t("panel.remove"),
6317
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}),
6482
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconTrash, {}),
6318
6483
  danger: true,
6319
6484
  disabled: state.busy
6320
6485
  }],
@@ -6334,7 +6499,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6334
6499
  onClick: () => {
6335
6500
  setMenuFor((current) => current === key ? void 0 : key);
6336
6501
  },
6337
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, {}),
6502
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconEllipsis, {}),
6338
6503
  label: t("panel.more")
6339
6504
  })
6340
6505
  }),
@@ -6373,49 +6538,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6373
6538
  }, key);
6374
6539
  })
6375
6540
  ]
6376
- }),
6377
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6378
- className: "mrfw-actions",
6379
- children: [
6380
- props.pickDirectory === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
6381
- variant: "outline",
6382
- disabled: state.busy,
6383
- onClick: () => {
6384
- addViaPicker();
6385
- },
6386
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, {}),
6387
- label: t("panel.add")
6388
- }),
6389
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6390
- className: "mrfw-input",
6391
- value: manualPath,
6392
- placeholder: t("panel.addManual"),
6393
- onChange: (event) => {
6394
- setManualPath(event.target.value);
6395
- },
6396
- onKeyDown: (event) => {
6397
- if (event.key === "Enter") addManualPath();
6398
- }
6399
- }),
6400
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Action, {
6401
- onClick: () => {
6402
- addManualPath();
6403
- },
6404
- disabled: state.busy || manualPath.trim() === "",
6405
- variant: "primary",
6406
- children: t("panel.addConfirm")
6407
- }),
6408
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Action, {
6409
- onClick: () => {
6410
- refresh();
6411
- },
6412
- disabled: state.busy,
6413
- variant: "outline",
6414
- children: t("panel.retry")
6415
- })
6416
- ]
6417
6541
  })
6418
- ]
6542
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6543
+ className: "mrfw-actions",
6544
+ children: [
6545
+ state.noSession || props.pickDirectory === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
6546
+ variant: "outline",
6547
+ disabled: state.busy,
6548
+ onClick: () => {
6549
+ addViaPicker();
6550
+ },
6551
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconPlus, {}),
6552
+ label: t("panel.add")
6553
+ }),
6554
+ state.noSession ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6555
+ className: "mrfw-input",
6556
+ value: manualPath,
6557
+ placeholder: t("panel.addManual"),
6558
+ onChange: (event) => {
6559
+ setManualPath(event.target.value);
6560
+ },
6561
+ onKeyDown: (event) => {
6562
+ if (event.key === "Enter") addManualPath();
6563
+ }
6564
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Action, {
6565
+ onClick: () => {
6566
+ addManualPath();
6567
+ },
6568
+ disabled: state.busy || manualPath.trim() === "",
6569
+ variant: "primary",
6570
+ children: t("panel.addConfirm")
6571
+ })] }),
6572
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Action, {
6573
+ onClick: () => {
6574
+ refresh();
6575
+ },
6576
+ disabled: state.busy,
6577
+ variant: "outline",
6578
+ children: t("panel.retry")
6579
+ })
6580
+ ]
6581
+ })]
6419
6582
  })]
6420
6583
  })]
6421
6584
  });
@@ -6493,7 +6656,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6493
6656
  * and the workspace UI service are composed by the surface, not by this
6494
6657
  * plugin, and neither is a dependency it may assume (the footer action exists
6495
6658
  * on surfaces where they do not). Absence is a supported state — the panel then
6496
- * offers a manual path field and lets the host resolve the workspace root.
6659
+ * shows "No active session" and does not ask the host to guess a workspace root.
6497
6660
  * @param ctx - the client context.
6498
6661
  * @param name - the service key to read.
6499
6662
  * @returns the service, or `undefined` when this composition has none.