dsh-code-server-app 0.3.43 → 0.3.45

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.
@@ -9,8 +9,10 @@
9
9
  // + src/browser),不含 code-server 的 out/node 与它的 136 个依赖(那层由 lib/launcher.mjs 取代);
10
10
  // ② @<scope>/dshcs-<名字>[-<platform>-<arch>]@<版本> 需要构建的原生包(node-pty / @vscode/sqlite3 /
11
11
  // kerberos / koffi / ssh2 / …),依赖链上命中它们的包也一并重打包(含 optionalDependencies);
12
- // ③ @<scope>/dsh-code-server-runtime-<platform>-<arch>@<插件版本> 平台聚合包:用 npm: 别名把 ② 装回
13
- // 原始名字,VS Code 的 require/import 无需改动;插件按 os/cpu 声明 ①(常规)+ ③(可选)依赖。
12
+ // ③ 插件依赖表 + lib/vendored.json —— **0.3.45 起不再有平台聚合包**:平台无关的重打包包写进插件
13
+ // `dependencies`(真名),平台专属的写进 `optionalDependencies`(真名 + 包自带 os/cpu,每目标一份);
14
+ // 原始名字(node-pty / @vscode/sqlite3 …)由 lib/native.js 在运行时按 lib/vendored.json 补 junction。
15
+ // 为什么弃用「平台聚合包 + npm: 别名」:见 docs/desktop-first-install-root-cause.md。
14
16
  //
15
17
  // 用法:node scripts/vendor-repacks.mjs [--from <已完整安装的 code-server 树>]
16
18
  // [--target win32-arm64,win32-x64] [--scope @jinsiyu] [--pack]
@@ -395,63 +397,15 @@ function hostMapFromProfile() {
395
397
  return best;
396
398
  }
397
399
 
398
- /** --reuse:从现有 repack/build + 聚合包清单还原「重打包集」,不重新分析源树。
399
- * @returns {{repack: Map<string,{pkg:{version:string},platformSpecific:boolean}>, declare:{name:string,version:string}[], reusedItems:{dir:string,file:string}[]}} */
400
- function reuseExisting(targets, hostKey) {
400
+ /** --reuse:从现有 repack/build + 重打包表还原「重打包集」,不重新分析源树。
401
+ * @returns {{modules:{alias:string,package:string,version:string,platform:boolean}[],
402
+ * declare:{name:string,version:string}[], reusedItems:{dir:string,file:string}[]}} */
403
+ function reuseExisting(targets) {
401
404
  const buildRoot = join(OUT, 'build');
402
405
  if (!existsSync(buildRoot)) throw new Error('--reuse 需要 repack/build 已存在(先跑一次完整流程)');
403
- const byTarget = new Map();
404
- for (const target of targets) {
405
- const agg = readJson(join(OUT, 'aggregator', target, 'package.json'));
406
- if (agg === null) continue;
407
- const map = new Map();
408
- for (const [orig, spec] of Object.entries(agg.dependencies ?? {})) {
409
- // 旧的聚合包清单里可能仍带 argon2(已随 code-server 服务层移除)
410
- if (orig === 'argon2') continue;
411
- const hit = /^npm:(.+)@([^@]+)$/.exec(spec);
412
- if (hit === null) throw new Error(`无法解析聚合包依赖 ${orig}: ${spec}`);
413
- map.set(orig, { pkgName: hit[1], version: hit[2] });
414
- }
415
- byTarget.set(target, map);
416
- }
417
- if (byTarget.size === 0) {
418
- const base = hostMapFromProfile();
419
- if (base === null) {
420
- throw new Error('--reuse 需要 repack/aggregator/*/package.json 或一个已安装的 profile 用于还原映射');
421
- }
422
- byTarget.set(hostKey, base);
423
- } else {
424
- // 与已安装 profile 的别名取并集:聚合包清单可能在上一次失败的重建里丢过条目
425
- const hostTarget = byTarget.has(hostKey) ? hostKey : targets[0];
426
- const base = hostMapFromProfile();
427
- if (base !== null) {
428
- const merged = new Map(byTarget.get(hostTarget));
429
- let added = 0;
430
- for (const [orig, info] of base) {
431
- if (!merged.has(orig)) { merged.set(orig, info); added += 1; }
432
- }
433
- if (added > 0) console.log(`[repack] --reuse:聚合包清单缺 ${added} 个条目 → 已用 profile 别名补齐`);
434
- byTarget.set(hostTarget, merged);
435
- }
436
- }
437
- const known = byTarget.get(hostKey) ?? byTarget.get(targets[0]);
438
- // 其余目标:按后缀替换推导(平台专属包名只在结尾的 -<platform>-<arch> 上不同)
439
- const knownTarget = byTarget.has(hostKey) ? hostKey : targets[0];
440
- for (const target of targets) {
441
- if (byTarget.has(target)) continue;
442
- const map = new Map();
443
- for (const [orig, info] of known) {
444
- const pkgName = info.pkgName.endsWith(`-${knownTarget}`)
445
- ? `${info.pkgName.slice(0, -knownTarget.length)}${target}`
446
- : info.pkgName;
447
- map.set(orig, { pkgName, version: info.version });
448
- }
449
- byTarget.set(target, map);
450
- }
451
- const hostSet = byTarget.get(knownTarget);
452
- const repack = new Map();
453
- for (const [orig, info] of hostSet) {
454
- repack.set(orig, { pkg: { version: info.version }, platformSpecific: info.pkgName.endsWith(`-${knownTarget}`) });
406
+ const modules = readModules(targets);
407
+ if (modules.length === 0) {
408
+ throw new Error('--reuse 需要 lib/vendored.json、repack/aggregator/*/package.json 或一个已安装的 profile 用于还原重打包表');
455
409
  }
456
410
  // 已有原生包目录 → plan 项;顺带清掉将被重建的树目录(旧 code-server / argon2 目录一并清理)
457
411
  const reusedItems = [];
@@ -464,50 +418,125 @@ function reuseExisting(targets, hostKey) {
464
418
  if (m === null) continue;
465
419
  reusedItems.push({ dir: join(buildRoot, ent), file: tgzName(m.name, m.version) });
466
420
  }
467
- // 纯 JS 直装集:插件现有 dependencies 里非 @jinsiyu 的项
421
+ // 纯 JS 直装集:插件现有 dependencies 里既不是树包、也不是重打包子包的项
422
+ const vendoredNames = new Set(modules.map((m) => m.package));
468
423
  const pluginPkg = readJson(join(pkgRoot, 'package.json'));
469
424
  const declare = Object.entries(pluginPkg.dependencies ?? {})
470
- .filter(([name]) => !/^@jinsiyu\//.test(name))
425
+ .filter(([name]) => !vendoredNames.has(name) && !/\/(?:dshcs-vscode-server|dshcs-code-server)$/.test(name))
471
426
  .map(([name, version]) => ({ name, version }));
472
427
  rmSync(join(OUT, 'aggregator'), { recursive: true, force: true });
473
- console.log(`[repack] --reuse:复用 ${reusedItems.length} 个已打包目录、${repack.size} 个重打包条目、${declare.length} 个纯 JS 直装依赖`);
474
- return { repack, declare, reusedItems };
428
+ console.log(`[repack] --reuse:复用 ${reusedItems.length} 个已打包目录、${modules.length} 个重打包条目、${declare.length} 个纯 JS 直装依赖`);
429
+ return { modules, declare, reusedItems };
430
+ }
431
+
432
+ /** 重打包子包的平台后缀(平台专属包才有),如 `@<scope>/dshcs-kerberos-win32-arm64`。 */
433
+ const PLATFORM_SUFFIX = /-(win32|darwin|linux)-(arm64|x64)$/;
434
+
435
+ /** 由「原名 + 真包名 + 版本」得到重打包条目(平台专属的存**基名**,运行时按目标拼后缀)。 */
436
+ function moduleEntry(alias, pkgName, version) {
437
+ const hit = PLATFORM_SUFFIX.exec(pkgName);
438
+ return hit === null
439
+ ? { alias, package: pkgName, version, platform: false }
440
+ : { alias, package: pkgName.slice(0, -hit[0].length), version, platform: true };
441
+ }
442
+
443
+ /** 读「原名 → 重打包子包」表:优先 lib/vendored.json(0.3.45 起),
444
+ * 否则从平台聚合包清单(0.3.44 及更早)或已安装 profile 迁移,再否则返回空表。 */
445
+ function readModules(targets) {
446
+ const vendoredFile = join(pkgRoot, 'lib', 'vendored.json');
447
+ const doc = readJson(vendoredFile);
448
+ if (doc !== null && Array.isArray(doc.modules) && doc.modules.length > 0) {
449
+ const modules = doc.modules
450
+ .filter((m) => m !== null && typeof m === 'object' && typeof m.alias === 'string' && typeof m.package === 'string')
451
+ .map((m) => ({
452
+ alias: m.alias,
453
+ package: m.package,
454
+ version: typeof m.version === 'string' ? m.version : null,
455
+ platform: m.platform === true,
456
+ }))
457
+ .sort((a, b) => a.alias.localeCompare(b.alias));
458
+ if (modules.length > 0) {
459
+ console.log(`[repack] 读 lib/vendored.json:${modules.length} 个重打包条目`);
460
+ return modules;
461
+ }
462
+ }
463
+ // 迁移:旧的聚合包清单(每个目标一份,dependencies 里是 npm: 别名)
464
+ let source = null;
465
+ for (const target of targets) {
466
+ const agg = readJson(join(OUT, 'aggregator', target, 'package.json'));
467
+ if (agg === null) continue;
468
+ const map = new Map();
469
+ for (const [orig, spec] of Object.entries(agg.dependencies ?? {})) {
470
+ // 旧的聚合包清单里可能仍带 argon2(已随 code-server 服务层移除)
471
+ if (orig === 'argon2') continue;
472
+ const hit = /^npm:(.+)@([^@]+)$/.exec(spec);
473
+ if (hit === null) throw new Error(`无法解析聚合包依赖 ${orig}: ${spec}`);
474
+ map.set(orig, { pkgName: hit[1], version: hit[2] });
475
+ }
476
+ if (map.size > 0) { source = { label: `repack/aggregator/${target}`, map }; break; }
477
+ }
478
+ // 与已安装 profile 的别名取并集:聚合包清单可能在上一次失败的重建里丢过条目
479
+ const base = hostMapFromProfile();
480
+ if (source === null && base === null) return [];
481
+ const merged = new Map(source !== null ? source.map : []);
482
+ if (base !== null) {
483
+ let added = 0;
484
+ for (const [orig, info] of base) {
485
+ if (!merged.has(orig)) { merged.set(orig, info); added += 1; }
486
+ }
487
+ if (added > 0) console.log(`[repack] 重打包表缺 ${added} 个条目 → 已用 profile 别名补齐`);
488
+ }
489
+ const modules = [...merged]
490
+ .map(([alias, info]) => moduleEntry(alias, info.pkgName, info.version))
491
+ .sort((a, b) => a.alias.localeCompare(b.alias));
492
+ console.log(`[repack] 迁移 ${modules.length} 个重打包条目(${source !== null ? source.label : 'profile 别名'})→ 将写入 lib/vendored.json`);
493
+ return modules;
475
494
  }
476
495
 
477
496
  function main() {
478
497
  const hostKey = `${process.platform}-${process.arch}`;
479
498
  const targets = TARGETS.length > 0 ? TARGETS : [hostKey];
480
- const pluginVersion = readJson(join(pkgRoot, 'package.json'))?.version ?? '0.0.0';
481
499
 
482
- let repack;
500
+ let repack = null;
501
+ let modules;
483
502
  let declare;
484
503
  let reusedItems = [];
485
504
  let autoSourceTree = null;
486
505
  if (REUSE) {
487
- ({ repack, declare, reusedItems } = reuseExisting(targets, hostKey));
506
+ ({ modules, declare, reusedItems } = reuseExisting(targets));
488
507
  } else {
489
508
  const autoSource = FROM === null;
490
509
  const sourceTree = autoSource ? prepareSourceTree() : FROM;
491
510
  if (autoSource) autoSourceTree = sourceTree;
492
511
  ({ repack, declare } = analyze(sourceTree));
512
+ modules = [...repack]
513
+ .map(([name, r]) => ({
514
+ alias: name,
515
+ package: `${SCOPE}/dshcs-${flat(name)}`,
516
+ version: r.pkg.version,
517
+ platform: r.platformSpecific,
518
+ }))
519
+ .sort((a, b) => a.alias.localeCompare(b.alias));
493
520
  rmSync(OUT, { recursive: true, force: true });
494
521
  }
495
- console.log(`\n重打包集(${repack.size}):`);
496
- for (const [name, r] of [...repack].sort()) {
497
- console.log(` ${name}@${r.pkg.version} ${r.platformSpecific ? '[平台专属]' : '[全平台]'}`);
522
+ console.log(`\n重打包集(${modules.length}):`);
523
+ for (const m of modules) {
524
+ console.log(` ${m.alias}@${m.version} → ${m.package}${m.platform ? `-<平台>` : ''} ${m.platform ? '[平台专属]' : '[全平台]'}`);
498
525
  }
499
526
  console.log(`\n直装集(${declare.length}): ${declare.map((d) => d.name).join(', ')}\n`);
500
527
 
501
528
  mkdirSync(join(OUT, 'build'), { recursive: true });
502
529
 
503
- // 每个目标的包名映射
530
+ // 每个目标的包名映射:平台专属的按目标拼后缀,平台无关的到处同名
504
531
  const byTarget = new Map();
505
532
  for (const target of targets) {
506
- const suffix = `-${target}`;
507
- const map = new Map(); // 原包名 -> { pkgName, version }
508
- for (const [name, r] of repack) {
509
- const pkgName = `${SCOPE}/dshcs-${flat(name)}${r.platformSpecific ? suffix : ''}`;
510
- map.set(name, { pkgName, version: r.pkg.version, platformSpecific: r.platformSpecific });
533
+ const map = new Map(); // 原包名 -> { pkgName, version, platformSpecific }
534
+ for (const m of modules) {
535
+ map.set(m.alias, {
536
+ pkgName: `${m.package}${m.platform ? `-${target}` : ''}`,
537
+ version: m.version,
538
+ platformSpecific: m.platform,
539
+ });
511
540
  }
512
541
  byTarget.set(target, map);
513
542
  }
@@ -599,45 +628,45 @@ function main() {
599
628
  }
600
629
  if (crossTree !== null) rmSync(crossTree, { recursive: true, force: true });
601
630
  }
602
- // 3) 聚合包(每平台一个):dependencies 用 npm: 别名把重打包包装回原名
603
- for (const target of targets) {
604
- const map = byTarget.get(target);
605
- const aggName = `${SCOPE}/dsh-code-server-runtime-${target}`;
606
- const aggDir = join(OUT, 'aggregator', target);
607
- mkdirSync(aggDir, { recursive: true });
608
- const deps = {};
609
- for (const [name] of repack) deps[name] = `npm:${map.get(name).pkgName}@${map.get(name).version}`;
610
- writeFileSync(join(aggDir, 'package.json'), JSON.stringify({
611
- name: aggName,
612
- version: pluginVersion,
613
- description: `Prebuilt native modules for the VS Code server tree on ${target} `
614
- + '(node-pty, @vscode/sqlite3, kerberos, @vscode/spdlog, …), '
615
- + 'so that installing the VS Code inner dependencies needs no build approval or C++ toolchain.',
616
- os: [target.split('-')[0]],
617
- cpu: [target.split('-')[1]],
618
- dependencies: deps,
619
- license: 'MIT',
620
- repository: readJson(join(pkgRoot, 'package.json'))?.repository ?? undefined,
621
- }, null, 2) + '\n', 'utf8');
622
- plan.push({ dir: aggDir, file: tgzName(aggName, pluginVersion), aggregator: true, target });
623
- }
631
+ // 3) 重打包表(lib/vendored.json,随插件发布):运行时用它把真名子包补成原始名字
632
+ const vendoredDoc = {
633
+ schemaVersion: 1,
634
+ generatedBy: 'scripts/vendor-repacks.mjs',
635
+ scope: SCOPE,
636
+ targets,
637
+ modules: modules.map((m) => {
638
+ const entry = { alias: m.alias, package: m.package, version: m.version };
639
+ if (m.platform) entry.platform = true;
640
+ return entry;
641
+ }),
642
+ };
643
+ writeFileSync(join(pkgRoot, 'lib', 'vendored.json'), `${JSON.stringify(vendoredDoc, null, 2)}\n`, 'utf8');
644
+ const independent = modules.filter((m) => !m.platform);
645
+ const specific = modules.filter((m) => m.platform);
646
+ console.log(`[repack] 重打包表 → lib/vendored.json(${modules.length} 个:全平台 ${independent.length} / 平台专属 ${specific.length})`);
624
647
 
625
648
  writeFileSync(join(OUT, 'pack-plan.json'), JSON.stringify(plan, null, 2) + '\n', 'utf8');
626
649
  console.log(`[repack] 生成 ${plan.length} 个待打包目录 → repack/ (计划:repack/pack-plan.json)`);
627
650
 
628
- // 4) 改写插件 package.json 的依赖:纯 JS 直装集 + VS Code 树包(平台无关);
629
- // 平台专属的(原生包)通过聚合包按 os/cpu 自动选。
651
+ // 4) 改写插件 package.json 的依赖:树 + 纯 JS 直装集 + **全平台**重打包包写 dependencies(真名);
652
+ // 平台专属的重打包包按目标写 optionalDependencies(真名 + 包自带 os/cpu,包管理器按架构自动选)。
653
+ // 这样每个包在依赖图里都是「根项目的直接依赖」,不依赖 pnpm 对可选子树别名的处理
654
+ // (见 docs/desktop-first-install-root-cause.md)。
630
655
  const pkgFile = join(pkgRoot, 'package.json');
631
656
  const pluginPkg = readJson(pkgFile);
632
657
  pluginPkg.dependencies = Object.fromEntries([
633
658
  [vscodePkg.name, vscodePkg.version],
634
659
  ...declare.map((d) => [d.name, d.version]),
660
+ ...independent.map((m) => [m.package, m.version]),
635
661
  ].sort(([a], [b]) => a.localeCompare(b)));
636
662
  pluginPkg.optionalDependencies = Object.fromEntries(targets
637
- .map((t) => [`${SCOPE}/dsh-code-server-runtime-${t}`, `^${pluginVersion}`]));
663
+ .flatMap((t) => specific.map((m) => [`${m.package}-${t}`, m.version]))
664
+ .sort(([a], [b]) => a.localeCompare(b)));
638
665
  writeFileSync(pkgFile, JSON.stringify(pluginPkg, null, 2) + '\n', 'utf8');
639
- console.log(`[repack] 已写入 package.json:dependencies ${pluginPkg.dependencies ? Object.keys(pluginPkg.dependencies).length : 0} 个`
640
- + `(VS Code 树 + 纯 JS),optionalDependencies ${targets.length} 个平台聚合包`);
666
+ console.log(`[repack] 已写入 package.json:dependencies ${Object.keys(pluginPkg.dependencies).length} 个`
667
+ + `(VS Code 树 + 纯 JS + ${independent.length} 个全平台重打包包),`
668
+ + `optionalDependencies ${Object.keys(pluginPkg.optionalDependencies).length} 个`
669
+ + `(${specific.length} 个平台专属重打包包 × ${targets.length} 个目标)`);
641
670
 
642
671
  // 5) 可选:直接打包
643
672
  if (DO_PACK) {
@@ -3,7 +3,7 @@
3
3
  "vscodeVersion": "1.137.0",
4
4
  "productPath": "stable-b11dabdaca0d3369986975be285db92c8795cea5",
5
5
  "layout": "vscode-only",
6
- "preparedAt": "2026-09-13T13:18:20.385Z",
6
+ "preparedAt": "2026-09-13T13:24:33.857Z",
7
7
  "source": "registry",
8
8
  "node": "v24.21.0",
9
9
  "platform": "win32",