@dsh-workbench/core 0.2.1 → 0.2.3

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/client.js CHANGED
@@ -561,6 +561,7 @@ window.__ModuleLoader__.load({
561
561
  //#endregion
562
562
  //#region ../shared/dist/config/constants.js
563
563
  var PLUGIN_ID = "@dsh-workbench/core";
564
+ var RELEASE_SIBLINGS = ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
564
565
  var API_PREFIX = "/workbench/api";
565
566
  var PREFS_PREFIX = `${API_PREFIX}/prefs`;
566
567
  var EVENTS_PATH = "/workbench/events";
@@ -1242,6 +1243,8 @@ window.__ModuleLoader__.load({
1242
1243
  "project.search.label": "Search workspaces",
1243
1244
  "project.search.placeholder": "Search workspaces (folder / name / path)",
1244
1245
  "project.search.empty": "No workspace matches “{query}”.",
1246
+ "project.group.workspaces": "Workspaces",
1247
+ "project.group.workshop": "Workshop",
1245
1248
  "project.rename.row": "Rename “{name}”",
1246
1249
  "project.rename.current": "Give this workspace a display name…",
1247
1250
  "project.rename.title": "Give “{name}” a display name",
@@ -1416,6 +1419,7 @@ window.__ModuleLoader__.load({
1416
1419
  "panels.market.add.failureIntegrity": "The downloaded package failed its integrity check",
1417
1420
  "panels.market.add.failureTimeout": "The install timed out",
1418
1421
  "panels.market.add.failurePnpmMissing": "pnpm was not found, cannot install",
1422
+ "panels.market.add.failureInstalled": "It is already in this profile: this dsh runs with hot reload, which refuses to install over the same package (remove it first) — and removing it failed too",
1419
1423
  "panels.market.add.failureGeneric": "Something went wrong during install — see the install details",
1420
1424
  "panels.market.add.approveTitle": "Your approval is needed for install scripts",
1421
1425
  "panels.market.add.approveCaution": "Only allow packages you trust: install scripts run on this machine with your permissions.",
@@ -1587,6 +1591,8 @@ window.__ModuleLoader__.load({
1587
1591
  "project.search.label": "搜索工作区",
1588
1592
  "project.search.placeholder": "搜索工作区(目录名 / 中文名 / 路径)",
1589
1593
  "project.search.empty": "没有匹配「{query}」的工作区。",
1594
+ "project.group.workspaces": "工作区",
1595
+ "project.group.workshop": "工坊",
1590
1596
  "project.rename.row": "改「{name}」的中文名",
1591
1597
  "project.rename.current": "改当前工作区的中文名…",
1592
1598
  "project.rename.title": "给「{name}」配一个中文名",
@@ -1761,6 +1767,7 @@ window.__ModuleLoader__.load({
1761
1767
  "panels.market.add.failureIntegrity": "下载的安装包校验失败",
1762
1768
  "panels.market.add.failureTimeout": "安装超时",
1763
1769
  "panels.market.add.failurePnpmMissing": "没有找到 pnpm,无法安装",
1770
+ "panels.market.add.failureInstalled": "它已经在这份 profile 里了:这一版 dsh 开着热更新,同一个包不许就地覆盖装(得先卸载再装),而这次也没能把它卸下来",
1764
1771
  "panels.market.add.failureGeneric": "安装过程中出错,原因见安装详情",
1765
1772
  "panels.market.add.approveTitle": "需要你允许安装脚本",
1766
1773
  "panels.market.add.approveCaution": "只允许你信得过的包:安装脚本会以你的权限在这台机器上运行。",
@@ -2298,6 +2305,7 @@ window.__ModuleLoader__.load({
2298
2305
  PREFS_PREFIX: () => PREFS_PREFIX,
2299
2306
  PROBE_TTL_MS: () => PROBE_TTL_MS,
2300
2307
  PROVISION_PREFIX: () => PROVISION_PREFIX,
2308
+ RELEASE_SIBLINGS: () => RELEASE_SIBLINGS,
2301
2309
  RIGHTBAR_FULLSCREEN_WIDTH: () => 768,
2302
2310
  Row: () => Row,
2303
2311
  Rows: () => Rows,
@@ -4690,6 +4698,7 @@ window.__ModuleLoader__.load({
4690
4698
  integrity: "panels.market.add.failureIntegrity",
4691
4699
  timeout: "panels.market.add.failureTimeout",
4692
4700
  "pnpm-missing": "panels.market.add.failurePnpmMissing",
4701
+ "already-installed": "panels.market.add.failureInstalled",
4693
4702
  "operation-error": "panels.market.add.failureGeneric",
4694
4703
  "incompatible-version": "panels.market.add.failureGeneric",
4695
4704
  "not-bundle": "panels.market.add.failureGeneric",
@@ -6252,8 +6261,12 @@ window.__ModuleLoader__.load({
6252
6261
  //#endregion
6253
6262
  //#region src/shared/api/diy.ts
6254
6263
  var DIY_PRESET_ID = "workbench-diy";
6264
+ var WORKSHOP_RELATIVE = "workbench/diy";
6255
6265
  var WORKSHOP_TITLE = "工作台DIY";
6256
6266
  var WORKSHOP_PAST_TITLES = ["DIY 工坊", "工作台自带 · DIY 模块住这儿"];
6267
+ function isWorkshopPath(path) {
6268
+ return path.replace(/\\/g, "/").replace(/\/+$/, "").endsWith(`/${WORKSHOP_RELATIVE}`);
6269
+ }
6257
6270
  //#endregion
6258
6271
  //#region src/app/units/index.ts
6259
6272
  var CLIENT_UNITS = [];
@@ -8781,6 +8794,29 @@ window.__ModuleLoader__.load({
8781
8794
  }));
8782
8795
  }
8783
8796
  //#endregion
8797
+ //#region src/app/layouts/sidebar/workspace-groups.ts
8798
+ function workspaceSections(items, headings) {
8799
+ const workspaces = [];
8800
+ const workshop = [];
8801
+ for (const item of items) if (isWorkshopPath(item.path)) workshop.push(item);
8802
+ else workspaces.push(item);
8803
+ const sections = [];
8804
+ if (workspaces.length > 0) sections.push({
8805
+ id: "workspaces",
8806
+ heading: workshop.length > 0 ? headings.workspaces : null,
8807
+ items: workspaces
8808
+ });
8809
+ if (workshop.length > 0) sections.push({
8810
+ id: "workshop",
8811
+ heading: headings.workshop,
8812
+ items: workshop
8813
+ });
8814
+ return sections;
8815
+ }
8816
+ function flattenSections(sections) {
8817
+ return sections.flatMap((section) => section.items);
8818
+ }
8819
+ //#endregion
8784
8820
  //#region src/app/layouts/sidebar/WorkspaceRowAction.tsx
8785
8821
  function WorkspaceRowAction({ workspace, t, onEdit }) {
8786
8822
  return /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
@@ -8828,8 +8864,8 @@ window.__ModuleLoader__.load({
8828
8864
  //#endregion
8829
8865
  //#region src/app/layouts/sidebar/workspace-items.tsx
8830
8866
  function workspaceMenuItems(options) {
8831
- const { results, currentId, hoverId, t, onHover, onEdit } = options;
8832
- return results.map((workspace) => ({
8867
+ const { sections, currentId, hoverId, t, onHover, onEdit } = options;
8868
+ const rowOf = (workspace) => ({
8833
8869
  id: workspace.workspaceId,
8834
8870
  icon: /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenRegular, { size: 16 }),
8835
8871
  label: /* @__PURE__ */ h(WorkspaceRowLabel, {
@@ -8842,7 +8878,12 @@ window.__ModuleLoader__.load({
8842
8878
  onEdit: () => onEdit(workspace)
8843
8879
  }) : void 0
8844
8880
  })
8845
- }));
8881
+ });
8882
+ return sections.flatMap((section) => [...section.heading === null ? [] : [{
8883
+ type: "label",
8884
+ id: section.id,
8885
+ text: section.heading
8886
+ }], ...section.items.map(rowOf)]);
8846
8887
  }
8847
8888
  //#endregion
8848
8889
  //#region src/app/layouts/sidebar/ProjectSwitcher.tsx
@@ -8862,7 +8903,12 @@ window.__ModuleLoader__.load({
8862
8903
  const wasOpenRef = useRef(false);
8863
8904
  const currentId = current?.workspaceId ?? null;
8864
8905
  const results = useMemo(() => matchWorkspaces(items, query), [items, query]);
8865
- const cursorId = cursor === null || results.length === 0 ? null : results[Math.min(cursor, results.length - 1)]?.workspaceId ?? null;
8906
+ const sections = useMemo(() => workspaceSections(results, {
8907
+ workspaces: t("project.group.workspaces"),
8908
+ workshop: t("project.group.workshop")
8909
+ }), [results, t]);
8910
+ const ordered = useMemo(() => flattenSections(sections), [sections]);
8911
+ const cursorId = cursor === null || ordered.length === 0 ? null : ordered[Math.min(cursor, ordered.length - 1)]?.workspaceId ?? null;
8866
8912
  useEffect(() => {
8867
8913
  if (open) {
8868
8914
  wasOpenRef.current = true;
@@ -8885,11 +8931,11 @@ window.__ModuleLoader__.load({
8885
8931
  setCursor(null);
8886
8932
  },
8887
8933
  onCursor: (step) => {
8888
- if (results.length === 0) return;
8889
- setCursor((at) => at === null ? step === 1 ? 0 : results.length - 1 : (at + step + results.length) % results.length);
8934
+ if (ordered.length === 0) return;
8935
+ setCursor((at) => at === null ? step === 1 ? 0 : ordered.length - 1 : (at + step + ordered.length) % ordered.length);
8890
8936
  },
8891
8937
  onSubmit: () => {
8892
- const pick = results[Math.min(cursor ?? 0, results.length - 1)];
8938
+ const pick = ordered[Math.min(cursor ?? 0, ordered.length - 1)];
8893
8939
  if (pick === void 0) return;
8894
8940
  close();
8895
8941
  onPick(pick.workspaceId);
@@ -8919,7 +8965,7 @@ window.__ModuleLoader__.load({
8919
8965
  id: "empty",
8920
8966
  text: t("project.search.empty", { query: query.trim() })
8921
8967
  }] : [], ...workspaceMenuItems({
8922
- results,
8968
+ sections,
8923
8969
  currentId,
8924
8970
  hoverId,
8925
8971
  t,
@@ -9640,7 +9686,7 @@ window.__ModuleLoader__.load({
9640
9686
  disposeDictionary?.();
9641
9687
  };
9642
9688
  }, "dsh-workbench: dictionaries");
9643
- const workshopWorkspace = () => ctx.workspaces.list.getSnapshot().items.find((item) => item.path.endsWith("/workbench/diy"));
9689
+ const workshopWorkspace = () => ctx.workspaces.list.getSnapshot().items.find((item) => isWorkshopPath(item.path));
9644
9690
  const openDiySession = (workspaceId, fallback) => {
9645
9691
  const remoteCreate = sessionCreateOf(ctx.remote);
9646
9692
  try {
@@ -554,6 +554,7 @@ function readDeclaration(subject, raw) {
554
554
  //#endregion
555
555
  //#region ../shared/dist/config/constants.js
556
556
  var PLUGIN_ID = "@dsh-workbench/core";
557
+ var RELEASE_SIBLINGS = ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
557
558
  var API_PREFIX = "/workbench/api";
558
559
  var PREFS_PREFIX = `${API_PREFIX}/prefs`;
559
560
  var EVENTS_PATH = "/workbench/events";
@@ -1235,6 +1236,8 @@ var en = {
1235
1236
  "project.search.label": "Search workspaces",
1236
1237
  "project.search.placeholder": "Search workspaces (folder / name / path)",
1237
1238
  "project.search.empty": "No workspace matches “{query}”.",
1239
+ "project.group.workspaces": "Workspaces",
1240
+ "project.group.workshop": "Workshop",
1238
1241
  "project.rename.row": "Rename “{name}”",
1239
1242
  "project.rename.current": "Give this workspace a display name…",
1240
1243
  "project.rename.title": "Give “{name}” a display name",
@@ -1409,6 +1412,7 @@ var en = {
1409
1412
  "panels.market.add.failureIntegrity": "The downloaded package failed its integrity check",
1410
1413
  "panels.market.add.failureTimeout": "The install timed out",
1411
1414
  "panels.market.add.failurePnpmMissing": "pnpm was not found, cannot install",
1415
+ "panels.market.add.failureInstalled": "It is already in this profile: this dsh runs with hot reload, which refuses to install over the same package (remove it first) — and removing it failed too",
1412
1416
  "panels.market.add.failureGeneric": "Something went wrong during install — see the install details",
1413
1417
  "panels.market.add.approveTitle": "Your approval is needed for install scripts",
1414
1418
  "panels.market.add.approveCaution": "Only allow packages you trust: install scripts run on this machine with your permissions.",
@@ -1580,6 +1584,8 @@ var zh = {
1580
1584
  "project.search.label": "搜索工作区",
1581
1585
  "project.search.placeholder": "搜索工作区(目录名 / 中文名 / 路径)",
1582
1586
  "project.search.empty": "没有匹配「{query}」的工作区。",
1587
+ "project.group.workspaces": "工作区",
1588
+ "project.group.workshop": "工坊",
1583
1589
  "project.rename.row": "改「{name}」的中文名",
1584
1590
  "project.rename.current": "改当前工作区的中文名…",
1585
1591
  "project.rename.title": "给「{name}」配一个中文名",
@@ -1754,6 +1760,7 @@ var zh = {
1754
1760
  "panels.market.add.failureIntegrity": "下载的安装包校验失败",
1755
1761
  "panels.market.add.failureTimeout": "安装超时",
1756
1762
  "panels.market.add.failurePnpmMissing": "没有找到 pnpm,无法安装",
1763
+ "panels.market.add.failureInstalled": "它已经在这份 profile 里了:这一版 dsh 开着热更新,同一个包不许就地覆盖装(得先卸载再装),而这次也没能把它卸下来",
1757
1764
  "panels.market.add.failureGeneric": "安装过程中出错,原因见安装详情",
1758
1765
  "panels.market.add.approveTitle": "需要你允许安装脚本",
1759
1766
  "panels.market.add.approveCaution": "只允许你信得过的包:安装脚本会以你的权限在这台机器上运行。",
@@ -2291,6 +2298,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2291
2298
  PREFS_PREFIX: () => PREFS_PREFIX,
2292
2299
  PROBE_TTL_MS: () => PROBE_TTL_MS,
2293
2300
  PROVISION_PREFIX: () => PROVISION_PREFIX,
2301
+ RELEASE_SIBLINGS: () => RELEASE_SIBLINGS,
2294
2302
  RIGHTBAR_FULLSCREEN_WIDTH: () => 768,
2295
2303
  Row: () => Row,
2296
2304
  Rows: () => Rows,
@@ -4683,6 +4691,7 @@ var FAILURE_KEYS = {
4683
4691
  integrity: "panels.market.add.failureIntegrity",
4684
4692
  timeout: "panels.market.add.failureTimeout",
4685
4693
  "pnpm-missing": "panels.market.add.failurePnpmMissing",
4694
+ "already-installed": "panels.market.add.failureInstalled",
4686
4695
  "operation-error": "panels.market.add.failureGeneric",
4687
4696
  "incompatible-version": "panels.market.add.failureGeneric",
4688
4697
  "not-bundle": "panels.market.add.failureGeneric",
@@ -6245,8 +6254,12 @@ function registerMarketPanel(ctx, units) {
6245
6254
  //#endregion
6246
6255
  //#region src/shared/api/diy.ts
6247
6256
  var DIY_PRESET_ID = "workbench-diy";
6257
+ var WORKSHOP_RELATIVE = "workbench/diy";
6248
6258
  var WORKSHOP_TITLE = "工作台DIY";
6249
6259
  var WORKSHOP_PAST_TITLES = ["DIY 工坊", "工作台自带 · DIY 模块住这儿"];
6260
+ function isWorkshopPath(path) {
6261
+ return path.replace(/\\/g, "/").replace(/\/+$/, "").endsWith(`/${WORKSHOP_RELATIVE}`);
6262
+ }
6250
6263
  //#endregion
6251
6264
  //#region src/app/units/index.ts
6252
6265
  var CLIENT_UNITS = [];
@@ -8774,6 +8787,29 @@ function WorkspaceSearchField({ t, query, onQuery, onCursor, onSubmit }) {
8774
8787
  }));
8775
8788
  }
8776
8789
  //#endregion
8790
+ //#region src/app/layouts/sidebar/workspace-groups.ts
8791
+ function workspaceSections(items, headings) {
8792
+ const workspaces = [];
8793
+ const workshop = [];
8794
+ for (const item of items) if (isWorkshopPath(item.path)) workshop.push(item);
8795
+ else workspaces.push(item);
8796
+ const sections = [];
8797
+ if (workspaces.length > 0) sections.push({
8798
+ id: "workspaces",
8799
+ heading: workshop.length > 0 ? headings.workspaces : null,
8800
+ items: workspaces
8801
+ });
8802
+ if (workshop.length > 0) sections.push({
8803
+ id: "workshop",
8804
+ heading: headings.workshop,
8805
+ items: workshop
8806
+ });
8807
+ return sections;
8808
+ }
8809
+ function flattenSections(sections) {
8810
+ return sections.flatMap((section) => section.items);
8811
+ }
8812
+ //#endregion
8777
8813
  //#region src/app/layouts/sidebar/WorkspaceRowAction.tsx
8778
8814
  function WorkspaceRowAction({ workspace, t, onEdit }) {
8779
8815
  return /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.Button, {
@@ -8821,8 +8857,8 @@ function WorkspaceRowLabel({ workspace, current, action, onHover }) {
8821
8857
  //#endregion
8822
8858
  //#region src/app/layouts/sidebar/workspace-items.tsx
8823
8859
  function workspaceMenuItems(options) {
8824
- const { results, currentId, hoverId, t, onHover, onEdit } = options;
8825
- return results.map((workspace) => ({
8860
+ const { sections, currentId, hoverId, t, onHover, onEdit } = options;
8861
+ const rowOf = (workspace) => ({
8826
8862
  id: workspace.workspaceId,
8827
8863
  icon: /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenRegular, { size: 16 }),
8828
8864
  label: /* @__PURE__ */ h(WorkspaceRowLabel, {
@@ -8835,7 +8871,12 @@ function workspaceMenuItems(options) {
8835
8871
  onEdit: () => onEdit(workspace)
8836
8872
  }) : void 0
8837
8873
  })
8838
- }));
8874
+ });
8875
+ return sections.flatMap((section) => [...section.heading === null ? [] : [{
8876
+ type: "label",
8877
+ id: section.id,
8878
+ text: section.heading
8879
+ }], ...section.items.map(rowOf)]);
8839
8880
  }
8840
8881
  //#endregion
8841
8882
  //#region src/app/layouts/sidebar/ProjectSwitcher.tsx
@@ -8855,7 +8896,12 @@ function ProjectSwitcher({ items, current, onPick, onAdd, onRename, t }) {
8855
8896
  const wasOpenRef = useRef(false);
8856
8897
  const currentId = current?.workspaceId ?? null;
8857
8898
  const results = useMemo(() => matchWorkspaces(items, query), [items, query]);
8858
- const cursorId = cursor === null || results.length === 0 ? null : results[Math.min(cursor, results.length - 1)]?.workspaceId ?? null;
8899
+ const sections = useMemo(() => workspaceSections(results, {
8900
+ workspaces: t("project.group.workspaces"),
8901
+ workshop: t("project.group.workshop")
8902
+ }), [results, t]);
8903
+ const ordered = useMemo(() => flattenSections(sections), [sections]);
8904
+ const cursorId = cursor === null || ordered.length === 0 ? null : ordered[Math.min(cursor, ordered.length - 1)]?.workspaceId ?? null;
8859
8905
  useEffect(() => {
8860
8906
  if (open) {
8861
8907
  wasOpenRef.current = true;
@@ -8878,11 +8924,11 @@ function ProjectSwitcher({ items, current, onPick, onAdd, onRename, t }) {
8878
8924
  setCursor(null);
8879
8925
  },
8880
8926
  onCursor: (step) => {
8881
- if (results.length === 0) return;
8882
- setCursor((at) => at === null ? step === 1 ? 0 : results.length - 1 : (at + step + results.length) % results.length);
8927
+ if (ordered.length === 0) return;
8928
+ setCursor((at) => at === null ? step === 1 ? 0 : ordered.length - 1 : (at + step + ordered.length) % ordered.length);
8883
8929
  },
8884
8930
  onSubmit: () => {
8885
- const pick = results[Math.min(cursor ?? 0, results.length - 1)];
8931
+ const pick = ordered[Math.min(cursor ?? 0, ordered.length - 1)];
8886
8932
  if (pick === void 0) return;
8887
8933
  close();
8888
8934
  onPick(pick.workspaceId);
@@ -8912,7 +8958,7 @@ function ProjectSwitcher({ items, current, onPick, onAdd, onRename, t }) {
8912
8958
  id: "empty",
8913
8959
  text: t("project.search.empty", { query: query.trim() })
8914
8960
  }] : [], ...workspaceMenuItems({
8915
- results,
8961
+ sections,
8916
8962
  currentId,
8917
8963
  hoverId,
8918
8964
  t,
@@ -9633,7 +9679,7 @@ function mount(ctx) {
9633
9679
  disposeDictionary?.();
9634
9680
  };
9635
9681
  }, "dsh-workbench: dictionaries");
9636
- const workshopWorkspace = () => ctx.workspaces.list.getSnapshot().items.find((item) => item.path.endsWith("/workbench/diy"));
9682
+ const workshopWorkspace = () => ctx.workspaces.list.getSnapshot().items.find((item) => isWorkshopPath(item.path));
9637
9683
  const openDiySession = (workspaceId, fallback) => {
9638
9684
  const remoteCreate = sessionCreateOf(ctx.remote);
9639
9685
  try {
@@ -557,6 +557,7 @@ function readDeclaration(subject, raw) {
557
557
  //#endregion
558
558
  //#region ../shared/dist/config/constants.js
559
559
  var PLUGIN_ID = "@dsh-workbench/core";
560
+ var RELEASE_SIBLINGS = ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
560
561
  var API_PREFIX = "/workbench/api";
561
562
  var PREFS_PREFIX = `${API_PREFIX}/prefs`;
562
563
  var EVENTS_PATH = "/workbench/events";
@@ -1238,6 +1239,8 @@ var en = {
1238
1239
  "project.search.label": "Search workspaces",
1239
1240
  "project.search.placeholder": "Search workspaces (folder / name / path)",
1240
1241
  "project.search.empty": "No workspace matches “{query}”.",
1242
+ "project.group.workspaces": "Workspaces",
1243
+ "project.group.workshop": "Workshop",
1241
1244
  "project.rename.row": "Rename “{name}”",
1242
1245
  "project.rename.current": "Give this workspace a display name…",
1243
1246
  "project.rename.title": "Give “{name}” a display name",
@@ -1412,6 +1415,7 @@ var en = {
1412
1415
  "panels.market.add.failureIntegrity": "The downloaded package failed its integrity check",
1413
1416
  "panels.market.add.failureTimeout": "The install timed out",
1414
1417
  "panels.market.add.failurePnpmMissing": "pnpm was not found, cannot install",
1418
+ "panels.market.add.failureInstalled": "It is already in this profile: this dsh runs with hot reload, which refuses to install over the same package (remove it first) — and removing it failed too",
1415
1419
  "panels.market.add.failureGeneric": "Something went wrong during install — see the install details",
1416
1420
  "panels.market.add.approveTitle": "Your approval is needed for install scripts",
1417
1421
  "panels.market.add.approveCaution": "Only allow packages you trust: install scripts run on this machine with your permissions.",
@@ -1583,6 +1587,8 @@ var zh = {
1583
1587
  "project.search.label": "搜索工作区",
1584
1588
  "project.search.placeholder": "搜索工作区(目录名 / 中文名 / 路径)",
1585
1589
  "project.search.empty": "没有匹配「{query}」的工作区。",
1590
+ "project.group.workspaces": "工作区",
1591
+ "project.group.workshop": "工坊",
1586
1592
  "project.rename.row": "改「{name}」的中文名",
1587
1593
  "project.rename.current": "改当前工作区的中文名…",
1588
1594
  "project.rename.title": "给「{name}」配一个中文名",
@@ -1757,6 +1763,7 @@ var zh = {
1757
1763
  "panels.market.add.failureIntegrity": "下载的安装包校验失败",
1758
1764
  "panels.market.add.failureTimeout": "安装超时",
1759
1765
  "panels.market.add.failurePnpmMissing": "没有找到 pnpm,无法安装",
1766
+ "panels.market.add.failureInstalled": "它已经在这份 profile 里了:这一版 dsh 开着热更新,同一个包不许就地覆盖装(得先卸载再装),而这次也没能把它卸下来",
1760
1767
  "panels.market.add.failureGeneric": "安装过程中出错,原因见安装详情",
1761
1768
  "panels.market.add.approveTitle": "需要你允许安装脚本",
1762
1769
  "panels.market.add.approveCaution": "只允许你信得过的包:安装脚本会以你的权限在这台机器上运行。",
@@ -2294,6 +2301,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2294
2301
  PREFS_PREFIX: () => PREFS_PREFIX,
2295
2302
  PROBE_TTL_MS: () => PROBE_TTL_MS,
2296
2303
  PROVISION_PREFIX: () => PROVISION_PREFIX,
2304
+ RELEASE_SIBLINGS: () => RELEASE_SIBLINGS,
2297
2305
  RIGHTBAR_FULLSCREEN_WIDTH: () => 768,
2298
2306
  Row: () => Row,
2299
2307
  Rows: () => Rows,
@@ -4686,6 +4694,7 @@ var FAILURE_KEYS = {
4686
4694
  integrity: "panels.market.add.failureIntegrity",
4687
4695
  timeout: "panels.market.add.failureTimeout",
4688
4696
  "pnpm-missing": "panels.market.add.failurePnpmMissing",
4697
+ "already-installed": "panels.market.add.failureInstalled",
4689
4698
  "operation-error": "panels.market.add.failureGeneric",
4690
4699
  "incompatible-version": "panels.market.add.failureGeneric",
4691
4700
  "not-bundle": "panels.market.add.failureGeneric",
@@ -6248,8 +6257,12 @@ function registerMarketPanel(ctx, units) {
6248
6257
  //#endregion
6249
6258
  //#region src/shared/api/diy.ts
6250
6259
  var DIY_PRESET_ID = "workbench-diy";
6260
+ var WORKSHOP_RELATIVE = "workbench/diy";
6251
6261
  var WORKSHOP_TITLE = "工作台DIY";
6252
6262
  var WORKSHOP_PAST_TITLES = ["DIY 工坊", "工作台自带 · DIY 模块住这儿"];
6263
+ function isWorkshopPath(path) {
6264
+ return path.replace(/\\/g, "/").replace(/\/+$/, "").endsWith(`/${WORKSHOP_RELATIVE}`);
6265
+ }
6253
6266
  //#endregion
6254
6267
  //#region src/app/units/index.ts
6255
6268
  var CLIENT_UNITS = [];
@@ -8777,6 +8790,29 @@ function WorkspaceSearchField({ t, query, onQuery, onCursor, onSubmit }) {
8777
8790
  }));
8778
8791
  }
8779
8792
  //#endregion
8793
+ //#region src/app/layouts/sidebar/workspace-groups.ts
8794
+ function workspaceSections(items, headings) {
8795
+ const workspaces = [];
8796
+ const workshop = [];
8797
+ for (const item of items) if (isWorkshopPath(item.path)) workshop.push(item);
8798
+ else workspaces.push(item);
8799
+ const sections = [];
8800
+ if (workspaces.length > 0) sections.push({
8801
+ id: "workspaces",
8802
+ heading: workshop.length > 0 ? headings.workspaces : null,
8803
+ items: workspaces
8804
+ });
8805
+ if (workshop.length > 0) sections.push({
8806
+ id: "workshop",
8807
+ heading: headings.workshop,
8808
+ items: workshop
8809
+ });
8810
+ return sections;
8811
+ }
8812
+ function flattenSections(sections) {
8813
+ return sections.flatMap((section) => section.items);
8814
+ }
8815
+ //#endregion
8780
8816
  //#region src/app/layouts/sidebar/WorkspaceRowAction.tsx
8781
8817
  function WorkspaceRowAction({ workspace, t, onEdit }) {
8782
8818
  return /* @__PURE__ */ h(Button, {
@@ -8824,8 +8860,8 @@ function WorkspaceRowLabel({ workspace, current, action, onHover }) {
8824
8860
  //#endregion
8825
8861
  //#region src/app/layouts/sidebar/workspace-items.tsx
8826
8862
  function workspaceMenuItems(options) {
8827
- const { results, currentId, hoverId, t, onHover, onEdit } = options;
8828
- return results.map((workspace) => ({
8863
+ const { sections, currentId, hoverId, t, onHover, onEdit } = options;
8864
+ const rowOf = (workspace) => ({
8829
8865
  id: workspace.workspaceId,
8830
8866
  icon: /* @__PURE__ */ h(IconFolderOpenRegular, { size: 16 }),
8831
8867
  label: /* @__PURE__ */ h(WorkspaceRowLabel, {
@@ -8838,7 +8874,12 @@ function workspaceMenuItems(options) {
8838
8874
  onEdit: () => onEdit(workspace)
8839
8875
  }) : void 0
8840
8876
  })
8841
- }));
8877
+ });
8878
+ return sections.flatMap((section) => [...section.heading === null ? [] : [{
8879
+ type: "label",
8880
+ id: section.id,
8881
+ text: section.heading
8882
+ }], ...section.items.map(rowOf)]);
8842
8883
  }
8843
8884
  //#endregion
8844
8885
  //#region src/app/layouts/sidebar/ProjectSwitcher.tsx
@@ -8858,7 +8899,12 @@ function ProjectSwitcher({ items, current, onPick, onAdd, onRename, t }) {
8858
8899
  const wasOpenRef = useRef(false);
8859
8900
  const currentId = current?.workspaceId ?? null;
8860
8901
  const results = useMemo(() => matchWorkspaces(items, query), [items, query]);
8861
- const cursorId = cursor === null || results.length === 0 ? null : results[Math.min(cursor, results.length - 1)]?.workspaceId ?? null;
8902
+ const sections = useMemo(() => workspaceSections(results, {
8903
+ workspaces: t("project.group.workspaces"),
8904
+ workshop: t("project.group.workshop")
8905
+ }), [results, t]);
8906
+ const ordered = useMemo(() => flattenSections(sections), [sections]);
8907
+ const cursorId = cursor === null || ordered.length === 0 ? null : ordered[Math.min(cursor, ordered.length - 1)]?.workspaceId ?? null;
8862
8908
  useEffect(() => {
8863
8909
  if (open) {
8864
8910
  wasOpenRef.current = true;
@@ -8881,11 +8927,11 @@ function ProjectSwitcher({ items, current, onPick, onAdd, onRename, t }) {
8881
8927
  setCursor(null);
8882
8928
  },
8883
8929
  onCursor: (step) => {
8884
- if (results.length === 0) return;
8885
- setCursor((at) => at === null ? step === 1 ? 0 : results.length - 1 : (at + step + results.length) % results.length);
8930
+ if (ordered.length === 0) return;
8931
+ setCursor((at) => at === null ? step === 1 ? 0 : ordered.length - 1 : (at + step + ordered.length) % ordered.length);
8886
8932
  },
8887
8933
  onSubmit: () => {
8888
- const pick = results[Math.min(cursor ?? 0, results.length - 1)];
8934
+ const pick = ordered[Math.min(cursor ?? 0, ordered.length - 1)];
8889
8935
  if (pick === void 0) return;
8890
8936
  close();
8891
8937
  onPick(pick.workspaceId);
@@ -8915,7 +8961,7 @@ function ProjectSwitcher({ items, current, onPick, onAdd, onRename, t }) {
8915
8961
  id: "empty",
8916
8962
  text: t("project.search.empty", { query: query.trim() })
8917
8963
  }] : [], ...workspaceMenuItems({
8918
- results,
8964
+ sections,
8919
8965
  currentId,
8920
8966
  hoverId,
8921
8967
  t,
@@ -9636,7 +9682,7 @@ function mount(ctx) {
9636
9682
  disposeDictionary?.();
9637
9683
  };
9638
9684
  }, "dsh-workbench: dictionaries");
9639
- const workshopWorkspace = () => ctx.workspaces.list.getSnapshot().items.find((item) => item.path.endsWith("/workbench/diy"));
9685
+ const workshopWorkspace = () => ctx.workspaces.list.getSnapshot().items.find((item) => isWorkshopPath(item.path));
9640
9686
  const openDiySession = (workspaceId, fallback) => {
9641
9687
  const remoteCreate = sessionCreateOf(ctx.remote);
9642
9688
  try {