@dsh-workbench/core 0.2.1 → 0.2.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.
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";
@@ -2298,6 +2299,7 @@ window.__ModuleLoader__.load({
2298
2299
  PREFS_PREFIX: () => PREFS_PREFIX,
2299
2300
  PROBE_TTL_MS: () => PROBE_TTL_MS,
2300
2301
  PROVISION_PREFIX: () => PROVISION_PREFIX,
2302
+ RELEASE_SIBLINGS: () => RELEASE_SIBLINGS,
2301
2303
  RIGHTBAR_FULLSCREEN_WIDTH: () => 768,
2302
2304
  Row: () => Row,
2303
2305
  Rows: () => Rows,
@@ -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";
@@ -2291,6 +2292,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2291
2292
  PREFS_PREFIX: () => PREFS_PREFIX,
2292
2293
  PROBE_TTL_MS: () => PROBE_TTL_MS,
2293
2294
  PROVISION_PREFIX: () => PROVISION_PREFIX,
2295
+ RELEASE_SIBLINGS: () => RELEASE_SIBLINGS,
2294
2296
  RIGHTBAR_FULLSCREEN_WIDTH: () => 768,
2295
2297
  Row: () => Row,
2296
2298
  Rows: () => Rows,
@@ -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";
@@ -2294,6 +2295,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
2294
2295
  PREFS_PREFIX: () => PREFS_PREFIX,
2295
2296
  PROBE_TTL_MS: () => PROBE_TTL_MS,
2296
2297
  PROVISION_PREFIX: () => PROVISION_PREFIX,
2298
+ RELEASE_SIBLINGS: () => RELEASE_SIBLINGS,
2297
2299
  RIGHTBAR_FULLSCREEN_WIDTH: () => 768,
2298
2300
  Row: () => Row,
2299
2301
  Rows: () => Rows,
@@ -6,6 +6,7 @@ import { spawn } from "node:child_process";
6
6
  import { fileURLToPath } from "node:url";
7
7
  //#region ../shared/dist/config/constants.js
8
8
  var PLUGIN_ID = "@dsh-workbench/core";
9
+ var RELEASE_SIBLINGS = ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
9
10
  var API_PREFIX = "/workbench/api";
10
11
  var PREFS_PREFIX = `${API_PREFIX}/prefs`;
11
12
  var EVENTS_PATH = "/workbench/events";
@@ -3862,6 +3863,32 @@ async function latestVersion(options) {
3862
3863
  });
3863
3864
  return value;
3864
3865
  }
3866
+ var existsCache = /* @__PURE__ */ new Map();
3867
+ async function versionExists(options) {
3868
+ const { shell, name, version, registry, force = false } = options;
3869
+ const key = `${registry}|${name}@${version}`;
3870
+ const hit = existsCache.get(key);
3871
+ if (!force && hit !== void 0 && (hit.value || Date.now() - hit.at < 6e5)) return hit.value;
3872
+ const result = await runShell(shell, `npm view ${quoteShellArg(`${name}@${version}`)} version --registry ${quoteShellArg(registry)} --cache ${quoteShellArg(npmCacheDir())}`, { timeoutMs: VERSION_CHECK_TIMEOUT_MS }).catch(() => void 0);
3873
+ const value = result?.exitCode === 0 && parseVersion(result.stdout) !== void 0;
3874
+ existsCache.set(key, {
3875
+ at: Date.now(),
3876
+ value
3877
+ });
3878
+ return value;
3879
+ }
3880
+ async function missingReleaseParts(options) {
3881
+ const { shell, registry, version, force = false } = options;
3882
+ const missing = [];
3883
+ for (const name of RELEASE_SIBLINGS) if (!await versionExists({
3884
+ shell,
3885
+ name,
3886
+ version,
3887
+ registry,
3888
+ force
3889
+ })) missing.push(name);
3890
+ return missing;
3891
+ }
3865
3892
  async function probeRelease(options) {
3866
3893
  const { shell, package: pkg, registry, force = false } = options;
3867
3894
  if (pkg === "") return void 0;
@@ -4986,6 +5013,15 @@ function createMarketService(options) {
4986
5013
  registry,
4987
5014
  force: true
4988
5015
  });
5016
+ if (shell !== void 0 && registry !== void 0 && latest !== void 0) {
5017
+ const missing = await missingReleaseParts({
5018
+ shell,
5019
+ registry,
5020
+ version: latest,
5021
+ force: true
5022
+ });
5023
+ if (missing.length > 0) throw new Error(`源上已经有 ${read.pkg}@${latest},但这一份发布还没铺齐:${missing.join("、")} 在这一版上还拉不到。装上会缺依赖,稍等再试 —— 市场页那颗「重新检查」会重新探一次。`);
5024
+ }
4989
5025
  const spec = latest === void 0 ? `${read.pkg}@latest` : `${read.pkg}@${latest}`;
4990
5026
  const outcome = await installDshBundle(routeDeps(requireBundles()), spec, { ...registry === void 0 ? {} : { registry } });
4991
5027
  logger?.info?.(`[dsh-workbench] 已更新工作台 ${read.version} → ${latest ?? "最新版"}`);
@@ -6283,17 +6319,43 @@ function bundleRegistriesHandler(ctx) {
6283
6319
  };
6284
6320
  }
6285
6321
  var refusalLog = /* @__PURE__ */ new Map();
6322
+ var holdLog = /* @__PURE__ */ new Map();
6323
+ async function latestIfReleaseReady(input) {
6324
+ const missing = await missingReleaseParts({
6325
+ shell: input.shell,
6326
+ registry: input.registry,
6327
+ version: input.version,
6328
+ force: input.force
6329
+ });
6330
+ if (missing.length === 0) {
6331
+ holdLog.delete(input.pkg);
6332
+ return input.version;
6333
+ }
6334
+ const line = `${input.version}|${missing.join("、")}`;
6335
+ if (holdLog.get(input.pkg) !== line) {
6336
+ holdLog.set(input.pkg, line);
6337
+ input.logger?.warn?.(`[dsh-workbench] 源上已经有 ${input.pkg}@${input.version},但这一份发布还没铺齐(${missing.join("、")} 在这个版本上还拉不到)—— 先不提示更新;等铺齐或点「重新检查」。`);
6338
+ }
6339
+ }
6286
6340
  async function workbenchVersion(input) {
6287
6341
  const read = readProfilePackage(input.dir, PLUGIN_ID);
6288
6342
  if (read === void 0) return void 0;
6289
6343
  const registry = read.registry ?? input.fallback;
6290
- const queried = read.local === true || input.shell === void 0 || registry === void 0 ? void 0 : await latestVersion({
6291
- shell: input.shell,
6344
+ const shell = input.shell;
6345
+ const queried = read.local === true || shell === void 0 || registry === void 0 ? void 0 : await latestVersion({
6346
+ shell,
6292
6347
  name: read.pkg,
6293
6348
  registry,
6294
6349
  force: input.force
6295
6350
  });
6296
- const latest = queried !== void 0 && isNewerVersion(queried, read.version) ? queried : void 0;
6351
+ const latest = queried === void 0 || shell === void 0 || registry === void 0 || !isNewerVersion(queried, read.version) ? void 0 : await latestIfReleaseReady({
6352
+ pkg: read.pkg,
6353
+ version: queried,
6354
+ registry,
6355
+ shell,
6356
+ force: input.force,
6357
+ logger: input.logger
6358
+ });
6297
6359
  return {
6298
6360
  pkg: read.pkg,
6299
6361
  installed: read.version,
@@ -6345,7 +6407,8 @@ function moduleVersionsHandler(ctx, shell) {
6345
6407
  dir,
6346
6408
  shell,
6347
6409
  fallback,
6348
- force
6410
+ force,
6411
+ logger: ctx.logger
6349
6412
  });
6350
6413
  return {
6351
6414
  ok: true,
@@ -152,6 +152,7 @@ export declare const kit: {
152
152
  IconModules({ size }: apiModule.IconProps): JSX.Element;
153
153
  IconPanelScreen({ size }: apiModule.IconProps): JSX.Element;
154
154
  PLUGIN_ID: "@dsh-workbench/core";
155
+ RELEASE_SIBLINGS: readonly ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
155
156
  API_PREFIX: "/workbench/api";
156
157
  PREFS_PREFIX: "/workbench/api/prefs";
157
158
  EVENTS_PATH: "/workbench/events";
@@ -1009,6 +1010,7 @@ export declare const kit: {
1009
1010
  IconModules({ size }: apiModule.IconProps): JSX.Element;
1010
1011
  IconPanelScreen({ size }: apiModule.IconProps): JSX.Element;
1011
1012
  PLUGIN_ID: "@dsh-workbench/core";
1013
+ RELEASE_SIBLINGS: readonly ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
1012
1014
  API_PREFIX: "/workbench/api";
1013
1015
  PREFS_PREFIX: "/workbench/api/prefs";
1014
1016
  EVENTS_PATH: "/workbench/events";
@@ -1861,6 +1863,7 @@ export declare const kit: {
1861
1863
  IconModules({ size }: apiModule.IconProps): JSX.Element;
1862
1864
  IconPanelScreen({ size }: apiModule.IconProps): JSX.Element;
1863
1865
  PLUGIN_ID: "@dsh-workbench/core";
1866
+ RELEASE_SIBLINGS: readonly ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
1864
1867
  API_PREFIX: "/workbench/api";
1865
1868
  PREFS_PREFIX: "/workbench/api/prefs";
1866
1869
  EVENTS_PATH: "/workbench/events";
@@ -0,0 +1,42 @@
1
+ import type { UnitCapability } from '../../../shared/api/host/probe-units';
2
+ import type { BundleManager } from '../../../shared/api/host/bundle-manager';
3
+ import type { InstalledModule, ProfileModule, ProfilePackage } from '../../../shared/api/host/installed-module';
4
+ import type { PluginSource, UnitManifest } from '@dsh-workbench/shared';
5
+ import { type PluginLedger } from '../model/plugin-ledger';
6
+ export declare function unit(id: string, plugin: string, source?: PluginSource): UnitManifest;
7
+ export declare function libUnit(id: string, libName: string): UnitManifest;
8
+ export declare function cleanupRoots(): void;
9
+ export declare function ledgerWith(entries: readonly {
10
+ pkg: string;
11
+ name?: string;
12
+ registry?: string;
13
+ }[]): PluginLedger;
14
+ export declare function harness(options: {
15
+ manifests: UnitManifest[];
16
+ statuses?: Readonly<Record<string, UnitCapability['status']>>;
17
+ withShell?: boolean;
18
+ bundles?: BundleManager;
19
+ installed?: (pkg: string) => InstalledModule;
20
+ modules?: () => readonly ProfileModule[];
21
+ workbench?: (pkg: string) => ProfilePackage | undefined;
22
+ ledger?: PluginLedger;
23
+ references?: {
24
+ readonly trustworthy: boolean;
25
+ };
26
+ npmLatest?: string;
27
+ npmMissing?: readonly string[];
28
+ }): {
29
+ registered: {
30
+ name: string;
31
+ execute: (args: unknown) => Promise<unknown>;
32
+ }[];
33
+ fake: {
34
+ shell: import("@dsh-workbench/shared").DshShell;
35
+ calls: import("@dsh-workbench/shared/testing").ShellCall[];
36
+ peak: () => number;
37
+ commands: () => string[];
38
+ };
39
+ disposers: (() => void)[];
40
+ };
41
+ export declare function fakeBundles(over?: Partial<BundleManager>): BundleManager;
42
+ export declare function call(h: ReturnType<typeof harness>, args: unknown): Promise<Record<string, unknown>>;
@@ -2,5 +2,6 @@ import type { DshHostContext, DshShell } from '@dsh-workbench/shared';
2
2
  import { type RouteHandler } from '@dsh-workbench/shared/host';
3
3
  export declare function bundleRegistriesHandler(ctx: DshHostContext): RouteHandler;
4
4
  export declare function resetRefusalLog(): void;
5
+ export declare function resetHoldLog(): void;
5
6
  export declare function moduleVersionsHandler(ctx: DshHostContext, shell: DshShell | undefined): RouteHandler;
6
7
  export declare function bundleInspectHandler(ctx: DshHostContext): RouteHandler;
@@ -9,6 +9,12 @@ export declare function latestVersion(options: {
9
9
  registry: string;
10
10
  force?: boolean;
11
11
  }): Promise<string | undefined>;
12
+ export declare function missingReleaseParts(options: {
13
+ shell: DshShell;
14
+ registry: string;
15
+ version: string;
16
+ force?: boolean;
17
+ }): Promise<readonly string[]>;
12
18
  export declare function probeRelease(options: {
13
19
  shell: DshShell;
14
20
  package: string;
package/docs/HANDOFF.md CHANGED
@@ -242,6 +242,10 @@ pnpm release:dry # 同上,但 publish 只 dry-run:零上传,结束
242
242
  落到脚本顶部的 `REGISTRY`(npmjs);本仓现在这 4 个包都发公网,命令一律带 `--access public`。
243
243
  注意 `inspectTarget` **只查 npmjs** —— "这个版本发出去没有"对发内网源的包看不准;
244
244
  - **什么顺序** = pnpm 自己拓扑排序(`shared` → `core` → 用到它们的模块);
245
+ - **市场什么时候说"有新版本"** = 要**整份发布铺齐**才亮:`core` / `shared` / `module-tools` 三包
246
+ 在同一版上都拉得到才算数([ADR-0043](../../../docs/adr/0043-version-prompt-waits-for-the-whole-release.md))。
247
+ 所以中断续跑那段窗口里、或镜像还没同步全时,市场**不会**提示更新 —— 铺齐后等 10 分钟,
248
+ 或让用户点市场页那颗「重新检查」即可(用户主动的时机一路 `force`,不等缓存);
245
249
  - **发什么** = pnpm 按各包 `files` / `.gitignore` 打包;**打包清单没人替你核**(见上一章
246
250
  「只能自己盯」)。要看清单用 `dsh-wb-module publish`:它只 dry-run、打印清单,不发布。
247
251
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/core",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "个人工作台:Agent 工作台外壳(左栏 + 常驻对话 + 自研右侧数据面板)。",
5
5
  "type": "module",
6
6
  "icon": "./icon.svg",
@@ -87,7 +87,7 @@
87
87
  "access": "public"
88
88
  },
89
89
  "dependencies": {
90
- "@dsh-workbench/shared": "0.2.1"
90
+ "@dsh-workbench/shared": "0.2.2"
91
91
  },
92
92
  "scripts": {
93
93
  "build": "node scripts/build.mjs && node scripts/build-types.mjs",