@dsh-workbench/core 1.0.0-beta.1 → 1.0.1

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.
@@ -964,69 +964,6 @@ function wroteNow(result) {
964
964
  function unitFactScope(unit) {
965
965
  return `${unit}*`;
966
966
  }
967
- //#endregion
968
- //#region ../shared/dist/host/shell-text.js
969
- /**
970
- * 按目标平台把一个值裹成 shell 字面量:POSIX 用单引号,win32 用双引号(cmd 与 PowerShell 都认)。
971
- * @param value - 任意值;不是字符串的先 `String()`。
972
- * @param platform - 目标平台,默认当前 `process.platform`。
973
- * @returns 可安全拼进该平台 shell 命令的一段文本;含空格 / 元字符的值不会被当成语法。
974
- */
975
- function quoteShellArgFor(value, platform = process.platform) {
976
- const text = String(value);
977
- if (platform === "win32") return `"${text.replace(/"/g, "\\\"")}"`;
978
- return `'${text.replace(/'/g, `'\\''`)}'`;
979
- }
980
- /**
981
- * 按当前平台把值裹成 shell 字面量;跨平台代码要固定平台时用 `quoteShellArgFor`。
982
- * @param value - 任意值;不是字符串的先 `String()`。
983
- * @returns 可安全拼进当前平台 shell 命令的一段文本。
984
- */
985
- function quoteShellArg(value) {
986
- return quoteShellArgFor(value, process.platform);
987
- }
988
- /**
989
- * 取一段文本的末尾若干行(如命令输出),顺带去掉首尾空白。
990
- * @param text - 原文;`null` / `undefined` 当空串。
991
- * @param lines - 最多留几行,默认 6;0 给全篇、负数从开头砍掉那么多行(都是 `slice` 语义),调用方传正数。
992
- * @returns 末尾若干行、去首尾空行后的文本;原文行数不够就全给,空输入给空串。
993
- */
994
- function tailLines(text, lines = 6) {
995
- return String(text ?? "").trim().split("\n").slice(-lines).join("\n");
996
- }
997
- //#endregion
998
- //#region ../shared/dist/host/shell.js
999
- var DEFAULT_MAX_BYTES$2 = 8388608;
1000
- async function runShell(shell, command, options = {}) {
1001
- const { workdir, timeoutMs = GIT_TIMEOUT_MS, signal } = options;
1002
- const spec = shell.resolve({
1003
- command,
1004
- ...workdir === void 0 ? {} : { workdir },
1005
- timeoutMs,
1006
- onExpiry: "kill",
1007
- stdoutMaxBytes: DEFAULT_MAX_BYTES$2,
1008
- ...signal === void 0 ? {} : { signal }
1009
- });
1010
- const result = await (await shell.execute(spec)).result();
1011
- return {
1012
- exitCode: result.exitCode,
1013
- timedOut: result.timedOut === true,
1014
- aborted: result.aborted === true,
1015
- stdout: result.stdout.text,
1016
- stderr: result.stderr.text,
1017
- truncated: result.stdout.truncated || result.stderr.truncated
1018
- };
1019
- }
1020
- function backgroundPrefix() {
1021
- return [quoteShellArg("env"), quoteShellArg("OPENCLI_WINDOW=background")];
1022
- }
1023
- function backgroundLine(command, argv) {
1024
- return [
1025
- ...backgroundPrefix(),
1026
- quoteShellArg(command),
1027
- ...argv.map(quoteShellArg)
1028
- ].join(" ");
1029
- }
1030
967
  /**
1031
968
  * 上报文本字段的截断长度(2000 字符;workspace / reason / message 共用)。
1032
969
  */
@@ -2385,6 +2322,69 @@ function createWorkspaceStore(options) {
2385
2322
  };
2386
2323
  }
2387
2324
  //#endregion
2325
+ //#region ../shared/dist/host/shell-text.js
2326
+ /**
2327
+ * 按目标平台把一个值裹成 shell 字面量:POSIX 用单引号,win32 用双引号(cmd 与 PowerShell 都认)。
2328
+ * @param value - 任意值;不是字符串的先 `String()`。
2329
+ * @param platform - 目标平台,默认当前 `process.platform`。
2330
+ * @returns 可安全拼进该平台 shell 命令的一段文本;含空格 / 元字符的值不会被当成语法。
2331
+ */
2332
+ function quoteShellArgFor(value, platform = process.platform) {
2333
+ const text = String(value);
2334
+ if (platform === "win32") return `"${text.replace(/"/g, "\\\"")}"`;
2335
+ return `'${text.replace(/'/g, `'\\''`)}'`;
2336
+ }
2337
+ /**
2338
+ * 按当前平台把值裹成 shell 字面量;跨平台代码要固定平台时用 `quoteShellArgFor`。
2339
+ * @param value - 任意值;不是字符串的先 `String()`。
2340
+ * @returns 可安全拼进当前平台 shell 命令的一段文本。
2341
+ */
2342
+ function quoteShellArg(value) {
2343
+ return quoteShellArgFor(value, process.platform);
2344
+ }
2345
+ /**
2346
+ * 取一段文本的末尾若干行(如命令输出),顺带去掉首尾空白。
2347
+ * @param text - 原文;`null` / `undefined` 当空串。
2348
+ * @param lines - 最多留几行,默认 6;0 给全篇、负数从开头砍掉那么多行(都是 `slice` 语义),调用方传正数。
2349
+ * @returns 末尾若干行、去首尾空行后的文本;原文行数不够就全给,空输入给空串。
2350
+ */
2351
+ function tailLines(text, lines = 6) {
2352
+ return String(text ?? "").trim().split("\n").slice(-lines).join("\n");
2353
+ }
2354
+ //#endregion
2355
+ //#region ../shared/dist/host/shell.js
2356
+ var DEFAULT_MAX_BYTES$2 = 8388608;
2357
+ async function runShell(shell, command, options = {}) {
2358
+ const { workdir, timeoutMs = GIT_TIMEOUT_MS, signal } = options;
2359
+ const spec = shell.resolve({
2360
+ command,
2361
+ ...workdir === void 0 ? {} : { workdir },
2362
+ timeoutMs,
2363
+ onExpiry: "kill",
2364
+ stdoutMaxBytes: DEFAULT_MAX_BYTES$2,
2365
+ ...signal === void 0 ? {} : { signal }
2366
+ });
2367
+ const result = await (await shell.execute(spec)).result();
2368
+ return {
2369
+ exitCode: result.exitCode,
2370
+ timedOut: result.timedOut === true,
2371
+ aborted: result.aborted === true,
2372
+ stdout: result.stdout.text,
2373
+ stderr: result.stderr.text,
2374
+ truncated: result.stdout.truncated || result.stderr.truncated
2375
+ };
2376
+ }
2377
+ function backgroundPrefix() {
2378
+ return [quoteShellArg("env"), quoteShellArg("OPENCLI_WINDOW=background")];
2379
+ }
2380
+ function backgroundLine(command, argv) {
2381
+ return [
2382
+ ...backgroundPrefix(),
2383
+ quoteShellArg(command),
2384
+ ...argv.map(quoteShellArg)
2385
+ ].join(" ");
2386
+ }
2387
+ //#endregion
2388
2388
  //#region ../shared/dist/host/paths.js
2389
2389
  function isolatedRoot() {
2390
2390
  return `${workbenchRoot()}/opencli`;
@@ -5738,10 +5738,11 @@ function stopVerdict(call, runs) {
5738
5738
  function publishVerdict(call, preview) {
5739
5739
  const raw = argsOf$1(call);
5740
5740
  if (raw["verify"] === true || raw["target"] === "local") return { kind: "allow" };
5741
+ const refresh = raw["refresh"] === true;
5741
5742
  const unit = textOf$3(raw, "unit");
5742
5743
  const found = unit === "" ? null : preview?.(unit) ?? null;
5743
5744
  const asked = textOf$3(raw, "target");
5744
- const target = asked === "" ? found?.market === void 0 ? found?.registry === void 0 ? "tarball" : "team" : "market" : asked;
5745
+ const target = refresh ? "market" : asked === "" ? found?.market === void 0 ? found?.registry === void 0 ? "tarball" : "team" : "market" : asked;
5745
5746
  const label = unit === "" ? "工作台模块" : `工作台模块 [${unit}]`;
5746
5747
  const labelEn = unit === "" ? "the workbench module" : `the workbench module [${unit}]`;
5747
5748
  const copies = {
@@ -5771,7 +5772,9 @@ function publishVerdict(call, preview) {
5771
5772
  }
5772
5773
  };
5773
5774
  const copy = copies[target] ?? copies["team"];
5774
- return askOf(`${DIY_PUBLISH_TOOL} ${found === null ? target : target === "market" && found.market !== void 0 ? `${found.name}@${found.version} → market (${found.market.url})` : `${found.name}@${found.version} → ${target}${found.registry === void 0 ? "" : ` (${found.registry})`}`}`, pair(copy.zh, copy.en), pair(copy.zh, copy.en));
5775
+ const targetLabel = found === null ? target : target === "market" && found.market !== void 0 ? `${found.name}@${found.version} → market (${found.market.url})` : `${found.name}@${found.version} → ${target}${found.registry === void 0 ? "" : ` (${found.registry})`}`;
5776
+ const question = refresh ? pair(`只刷新${label}在市集里的元数据(标题 / 作者 / 说明),不升版本、不重发产物,允许吗?`, `Only refresh ${labelEn}'s market metadata (title, author, description); no version bump, no artifacts. Allow?`) : pair(copy.zh, copy.en);
5777
+ return askOf(`${DIY_PUBLISH_TOOL} ${targetLabel}${refresh ? "(元数据)" : ""}`, question, question);
5775
5778
  }
5776
5779
  var panelsApproval = (call) => {
5777
5780
  if (call.name === "workbench_long_tasks_stop") return stopVerdict(call, void 0);
@@ -6792,10 +6795,10 @@ var OUTPUT$2 = {
6792
6795
  },
6793
6796
  unit: { type: "string" },
6794
6797
  path: { type: "string" },
6795
- install: {
6798
+ install: { oneOf: [{
6796
6799
  type: "object",
6797
6800
  additionalProperties: true
6798
- },
6801
+ }, { type: "string" }] },
6799
6802
  alreadyInstalled: { type: "boolean" },
6800
6803
  panel: {
6801
6804
  type: "object",
@@ -8873,6 +8876,10 @@ function renderStatus(root, lines, options = {}) {
8873
8876
  });
8874
8877
  return `${notice === void 0 ? `工作区:${root}` : `工作区:${root}\n${notice}`}\n${block.join("\n")}`;
8875
8878
  }
8879
+ function publishStatusOf(preview) {
8880
+ if (preview === null) return "";
8881
+ return [preview.market === void 0 ? preview.registry === void 0 ? "发布出口:安装包(这个环境没配可写市场索引源,模块也没声明 publishConfig.registry)" : `发布出口:团队源 ${preview.registry}(package.json 的 publishConfig.registry)` : `发布出口:市场索引 ${preview.market.url}${preview.market.ref === void 0 ? "" : `(${preview.market.ref})`}—— 不填 target 时默认发这里;这一版会发 ${preview.market.nextVersion ?? preview.version}`, preview.changelog === void 0 ? void 0 : preview.changelog.missing ? `发布前置:CHANGELOG 还差 ${preview.changelog.version} 这一版 —— 先 workbench_diy_changelog(unit=…)` : `发布前置:CHANGELOG 里已有 ${preview.changelog.version}`].filter((one) => one !== void 0).join("\n");
8882
+ }
8876
8883
  function renderList(root, modules, shape = "bare") {
8877
8884
  if (modules.length === 0) return [
8878
8885
  `这个工作区里没有模块源码(${root})—— ${shape === "workspace" ? "它声明了 workspace,但里面的包没有一个报 dsh.workbench.unit" : shape === "package" ? "它是一个包(有 package.json),但没声明 dsh.workbench.unit,也没声明 workspace" : "它没有 package.json(空项目 / 一堆散文件都算这一档)"};这条会话也还没装过任何模块。`,
@@ -8887,7 +8894,7 @@ function renderList(root, modules, shape = "bare") {
8887
8894
  //#endregion
8888
8895
  //#region src/modules/panels/model/diy-tools.ts
8889
8896
  var PUBLISH_TIMEOUT_MS = 18e5;
8890
- function registerDiyTools(ctx, market, panels, debug) {
8897
+ function registerDiyTools(ctx, market, panels, debug, previewOf = () => null) {
8891
8898
  const supply = supplyPortOf(ctx);
8892
8899
  const tools = ctx.get("tools");
8893
8900
  if (tools === void 0) {
@@ -8928,10 +8935,13 @@ function registerDiyTools(ctx, market, panels, debug) {
8928
8935
  installed: one.installed
8929
8936
  })
8930
8937
  }));
8938
+ const preview = wanted === "" ? null : previewOf(wanted);
8939
+ const text = [renderStatus(root, rows), publishStatusOf(preview)].filter((one) => one !== "").join("\n");
8931
8940
  return plainJson({
8932
8941
  workspace: root,
8933
8942
  status: rows,
8934
- text: renderStatus(root, rows)
8943
+ ...preview === null ? {} : { publish: preview },
8944
+ text
8935
8945
  });
8936
8946
  }
8937
8947
  };
@@ -9125,7 +9135,7 @@ function registerDiyTools(ctx, market, panels, debug) {
9125
9135
  };
9126
9136
  const publishTool = {
9127
9137
  name: DIY_PUBLISH_TOOL,
9128
- description: "用户说“发布”后才用:把这一格发到团队源/公网 npm/安装包/git/市场索引。先跑全门禁(验收没打完不发),发完给安装命令。",
9138
+ description: "用户说“发布”后才用:把这一格发到 target 指定的出口(不填按环境默认)。",
9129
9139
  parameters: {
9130
9140
  type: "object",
9131
9141
  properties: {
@@ -9160,6 +9170,10 @@ function registerDiyTools(ctx, market, panels, debug) {
9160
9170
  license: {
9161
9171
  type: "string",
9162
9172
  description: "公开发布用的许可证(MIT / Apache-2.0 / 仓库已有 LICENSE)。"
9173
+ },
9174
+ refresh: {
9175
+ type: "boolean",
9176
+ description: "只刷市集元数据(标题/作者/说明),不升版本、不重发产物。"
9163
9177
  }
9164
9178
  },
9165
9179
  required: ["unit"],
@@ -9191,6 +9205,7 @@ function registerDiyTools(ctx, market, panels, debug) {
9191
9205
  if (target !== "") argv.push("--target", target);
9192
9206
  if (version !== "") argv.push("--version", version);
9193
9207
  if (license !== "") argv.push("--license", license);
9208
+ if (asRecord$1(raw)["refresh"] === true) argv.push("--refresh");
9194
9209
  const result = await runShell(shell, argv.map((one) => quoteShellArg(one)).join(" "), {
9195
9210
  workdir: root,
9196
9211
  timeoutMs: PUBLISH_TIMEOUT_MS
@@ -9231,7 +9246,7 @@ function registerDiyTools(ctx, market, panels, debug) {
9231
9246
  `已核过 ${name}@${released}`,
9232
9247
  `安装:${install}`,
9233
9248
  "没有重新发布。"
9234
- ].join("\n") : targetOfPayload === "tarball" ? [
9249
+ ].join("\n") : payload["refresh"] === true ? [payload["refreshed"] === true ? `已刷新 ${name} 的市集元数据(版本 ${released} 不变)` : `${name} 的市集元数据本来就是这样,没动`, `市场索引:${asText(asRecord$1(payload["market"])["url"])}`].join("\n") : targetOfPayload === "tarball" ? [
9235
9250
  `安装包在 ${file}`,
9236
9251
  `本机装:${install}`,
9237
9252
  "文件可以从对话里带走,发给同事。"
@@ -9362,14 +9377,26 @@ function publishPreviewOf(root, unit, options = {}) {
9362
9377
  const registry = typeof publishConfig === "object" && publishConfig !== null ? publishConfig["registry"] : void 0;
9363
9378
  const market = marketOf(found.unit, found.dir, name, version);
9364
9379
  const target = targetVersionOf(version, (options.version ?? "").trim(), market);
9380
+ const author = authorOf(record);
9365
9381
  return {
9366
9382
  name,
9367
9383
  version,
9384
+ ...author === "" ? {} : { author },
9368
9385
  ...typeof registry === "string" && registry !== "" ? { registry } : {},
9369
9386
  ...market === void 0 ? {} : { market },
9370
9387
  changelog: changelogOf(found.dir, target)
9371
9388
  };
9372
9389
  }
9390
+ function authorOf(manifest) {
9391
+ const author = manifest["author"];
9392
+ if (typeof author === "string") return author.trim();
9393
+ if (author === null || typeof author !== "object") return "";
9394
+ const record = author;
9395
+ const name = typeof record["name"] === "string" ? record["name"].trim() : "";
9396
+ if (name === "") return "";
9397
+ const email = typeof record["email"] === "string" ? record["email"].trim() : "";
9398
+ return email === "" ? name : `${name} <${email}>`;
9399
+ }
9373
9400
  function targetVersionOf(version, asked, market) {
9374
9401
  if (asked === "") return market?.nextVersion ?? version;
9375
9402
  if (/^(major|minor|patch)$/.test(asked)) return bumped(version, asked) ?? version;
@@ -12851,11 +12878,18 @@ function createMarketDocReader(options) {
12851
12878
  const directory = (git.path ?? "").replace(/^\/+|\/+$/g, "");
12852
12879
  const file = directory === "" ? FILES[kind] : `${directory}/${FILES[kind]}`;
12853
12880
  const repo = join(options.root, "market-index", marketSourceKey(source), "repo.git");
12881
+ const show = () => runShell(shell, `git -C ${quoteShellArg(repo)} show ${git.commit}:${quoteShellArg(file)}`, { timeoutMs });
12882
+ const hasCommit = async () => {
12883
+ return (await runShell(shell, `git -C ${quoteShellArg(repo)} cat-file -e ${quoteShellArg(`${git.commit}^{commit}`)}`, { timeoutMs })).exitCode === 0;
12884
+ };
12854
12885
  try {
12855
- const result = await runShell(shell, `git -C ${quoteShellArg(repo)} show ${git.commit}:${quoteShellArg(file)}`, { timeoutMs });
12886
+ let result = await show();
12887
+ if (result.exitCode !== 0 && !await hasCommit()) {
12888
+ if ((await runShell(shell, `git -C ${quoteShellArg(repo)} fetch --depth 1 origin ${git.commit}`, { timeoutMs })).exitCode === 0) result = await show();
12889
+ }
12856
12890
  if (result.exitCode !== 0) {
12857
12891
  const text = result.stderr.trim();
12858
- return remember(key, missingText(text) ? fail(kind, target.version, "missing") : fail(kind, target.version, "unavailable", text));
12892
+ return missingText(text) ? fail(kind, target.version, "missing") : fail(kind, target.version, "unavailable", text);
12859
12893
  }
12860
12894
  return remember(key, {
12861
12895
  ok: true,
@@ -14353,7 +14387,7 @@ var OWNED = [{
14353
14387
  registerTools: () => [
14354
14388
  ...registerPanelTools(ctx, panels, values),
14355
14389
  ...registerMarketTools(ctx, market),
14356
- ...registerDiyTools(ctx, market, panels, debug),
14390
+ ...registerDiyTools(ctx, market, panels, debug, (unit) => publishPreviewOf(workshopPathOf(ctx), unit)),
14357
14391
  ...registerRecordTools(ctx, record),
14358
14392
  ...registerLongTaskTools(ctx, longTaskRuns)
14359
14393
  ],
@@ -14,7 +14,6 @@ export interface SharedRow {
14
14
  readonly installed?: string;
15
15
  readonly latest?: string;
16
16
  };
17
- readonly detail?: string;
18
17
  }
19
18
  export declare function sharedActions(row: SharedRow): MarketRowAction[];
20
19
  export declare function sharedRows(manifests: readonly UnitManifest[], capabilities: CapabilityMap | null): SharedRow[];
@@ -1,11 +1,9 @@
1
1
  import type { Translate } from '@dsh-workbench/shared';
2
2
  import type { ConfigSyncRow } from '../../../kernel/contract/config-sync';
3
- export declare function SourceRows({ t, rows, picked, profile, assetOverwrites, onToggle, onToggleAsset, }: {
3
+ export declare function SourceRows({ t, rows, picked, profile, onToggle, }: {
4
4
  readonly t: Translate;
5
5
  readonly rows: readonly ConfigSyncRow[];
6
6
  readonly picked: readonly string[];
7
7
  readonly profile: string;
8
- readonly assetOverwrites: readonly string[];
9
8
  readonly onToggle: (key: string, next: boolean) => void;
10
- readonly onToggleAsset: (key: string, next: boolean) => void;
11
9
  }): JSX.Element;
@@ -1,2 +1,2 @@
1
1
  export { CONFIG_SYNC_ROUTE, CONFIG_SYNC_RESOURCE } from '@dsh-workbench/shared/contract/protocol/config-sync';
2
- export type { ConfigSyncState, ConfigSyncAssetState, ConfigSyncAssetFile, ConfigSyncAsset, ConfigSyncRow, ConfigSyncProfile, ConfigSyncSnapshot, ConfigSyncApplied, ConfigSyncRequest } from '@dsh-workbench/shared/contract/protocol/config-sync';
2
+ export type { ConfigSyncState, ConfigSyncRow, ConfigSyncProfile, ConfigSyncSnapshot, ConfigSyncApplied, ConfigSyncRequest } from '@dsh-workbench/shared/contract/protocol/config-sync';
@@ -24,8 +24,13 @@ export declare const OUTPUT_SCHEMA: {
24
24
  type: string;
25
25
  };
26
26
  install: {
27
- type: string;
28
- additionalProperties: boolean;
27
+ oneOf: ({
28
+ type: string;
29
+ additionalProperties: boolean;
30
+ } | {
31
+ type: string;
32
+ additionalProperties?: undefined;
33
+ })[];
29
34
  };
30
35
  alreadyInstalled: {
31
36
  type: string;
@@ -61,8 +66,13 @@ export declare const OUTPUT: {
61
66
  type: string;
62
67
  };
63
68
  install: {
64
- type: string;
65
- additionalProperties: boolean;
69
+ oneOf: ({
70
+ type: string;
71
+ additionalProperties: boolean;
72
+ } | {
73
+ type: string;
74
+ additionalProperties?: undefined;
75
+ })[];
66
76
  };
67
77
  alreadyInstalled: {
68
78
  type: string;
@@ -1,4 +1,5 @@
1
1
  import type { PanelUnitReport } from '@dsh-workbench/shared/host';
2
+ import type { PublishPreview } from '@dsh-workbench/shared/contract/protocol/market-index';
2
3
  import { type DiyModule, type SyncState, type Toolchain, type WorkspaceShape } from '../../../shared/api/host/diy-modules';
3
4
  export declare const SYNC_STALE_MINUTES = 15;
4
5
  export declare const SYNC_STALE_MS: number;
@@ -70,4 +71,5 @@ export declare function statusOf(options: {
70
71
  export declare function renderStatus(root: string, lines: readonly ModuleStatus[], options?: {
71
72
  readonly shellVersion?: string;
72
73
  }): string;
74
+ export declare function publishStatusOf(preview: PublishPreview | null): string;
73
75
  export declare function renderList(root: string, modules: readonly DiyModule[], shape?: WorkspaceShape): string;
@@ -1,6 +1,7 @@
1
1
  import type { DshHostContext } from '@dsh-workbench/shared';
2
2
  import type { DebugStore } from '@dsh-workbench/shared/host';
3
+ import type { PublishPreview } from '@dsh-workbench/shared/contract/protocol/market-index';
3
4
  import type { MarketService } from './market';
4
5
  import type { PanelsService } from './service';
5
6
  export declare const PUBLISH_TIMEOUT_MS: number;
6
- export declare function registerDiyTools(ctx: DshHostContext, market: MarketService, panels: PanelsService, debug: DebugStore): Array<() => void>;
7
+ export declare function registerDiyTools(ctx: DshHostContext, market: MarketService, panels: PanelsService, debug: DebugStore, previewOf?: (unit: string) => PublishPreview | null): Array<() => void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/core",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.1",
4
4
  "description": "个人工作台:Agent 工作台(左栏 + 常驻对话 + 自研右侧数据面板)。",
5
5
  "type": "module",
6
6
  "icon": "./icon.svg",
@@ -36,6 +36,8 @@
36
36
  "preset",
37
37
  "scripts/create-workbench.mjs",
38
38
  "scripts/clone-profile.mjs",
39
+ "scripts/patch-blocks.mjs",
40
+ "scripts/share-data-root.mjs",
39
41
  "scripts/seed-profile.sh",
40
42
  "scripts/seed-workshop.sh",
41
43
  "README.md"
@@ -98,8 +100,8 @@
98
100
  "proper-lockfile": "^4.1.2",
99
101
  "which": "^7.0.0",
100
102
  "write-file-atomic": "^8.0.0",
101
- "@dsh-workbench/shared": "1.0.0-beta.1",
102
- "@dsh-workbench/adapters-default": "1.0.0-beta.1"
103
+ "@dsh-workbench/shared": "1.0.1",
104
+ "@dsh-workbench/adapters-default": "1.0.1"
103
105
  },
104
106
  "license": "MIT",
105
107
  "repository": {
@@ -1,4 +1,7 @@
1
- # 工作台运行时的**可写根**声明 —— 由启动器每次启动叠加(`--patch`)。
1
+ # 工作台运行时的**可写根**声明。两个入口共用同一行:
2
+ # 1. 启动器每次启动用 `--patch` 叠一层(对新旧 profile 都生效);
3
+ # 2. `scripts/share-data-root.mjs` 把这一行补进 profile 的 cordis.patch.yml,
4
+ # 给不带启动器的 `dsh <profile>` 兜底(只抄这一行,不抄注释)。
2
5
  #
3
6
  # 为什么必须有它:工作台自己要跑命令(启动体检自动装 opencli、模块市场装/升插件、
4
7
  # 查源上有没有新版),而这些命令走 dsh 的**执行缝**,执行缝带**文件沙箱**。
@@ -9,14 +12,13 @@
9
12
  # 症状:自动安装死在第一步,界面只能退化成"让用户去终端抄一条命令" ——
10
13
  # 终端没有沙箱,抄过去反而能跑,于是这个缺口一直看不出来。
11
14
  #
12
- # 指到 `$DSH_HOME/workbench` 之后,沙箱放行的是**同一棵树**:
15
+ # 指到运行时根之后,沙箱放行的是**同一棵树**:
13
16
  # 隔离运行时的工具链 + npm 缓存(opencli-runtime.ts)、
14
17
  # 模块专属文件夹(ADR-0011 的 workspaces/)、模块市场的 plugins-npm。
15
18
  # 也就是 ADR-0011 说的"启动器给插件声明的可写根"。
16
19
  #
17
- # 为什么用 `--patch` 叠加、而不是写进 profile 的 cordis.patch.yml:
18
- # profile 可能是**早就建好**的(交接出去的机器尤其如此),没人会回头重跑
19
- # seed-profile.sh —— 叠加层每次启动都生效,对新旧 profile 一视同仁。
20
+ # 会话 / 项目 / 附件**不在这里**:它们跟 `dsh web` / Desktop 共用 `$DSH_HOME`,
21
+ # 不再由工作台按 profile 隔离(见 ADR-0085)。
20
22
  #
21
23
  # mode 与 base 出厂值**一致**(只重述,不改变语义):patch 的 config 是**整体替换**、
22
24
  # 不深合并,所以两个字段都得写全,否则 workspaceRoot 会被替换掉 mode 丢失。