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.
- package/README.en.md +29 -20
- package/README.md +40 -20
- package/assets/extensions/dshcs-editor-bridge/package.json +1 -1
- package/assets/extensions/dshcs-editor-bridge/webview/THIRD-PARTY.md +1 -1
- package/assets/extensions/dshcs-editor-bridge/webview/src/app.jsx +11 -3
- package/assets/extensions/dshcs-editor-bridge/webview/thread.js +14 -14
- package/lib/index.js +15 -23
- package/lib/native.js +111 -83
- package/lib/vendor.js +3 -1
- package/lib/vendored.json +99 -0
- package/package.json +49 -24
- package/scripts/vendor-repacks.mjs +129 -100
- package/vendor/VENDOR.json +1 -1
|
@@ -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
|
-
// ③
|
|
13
|
-
//
|
|
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 {{
|
|
400
|
-
|
|
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
|
|
404
|
-
|
|
405
|
-
|
|
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
|
|
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]) =>
|
|
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} 个已打包目录、${
|
|
474
|
-
return {
|
|
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
|
-
({
|
|
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重打包集(${
|
|
496
|
-
for (const
|
|
497
|
-
console.log(` ${
|
|
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
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
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)
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
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
|
|
629
|
-
//
|
|
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
|
-
.
|
|
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 ${
|
|
640
|
-
+ `(VS Code 树 + 纯 JS
|
|
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) {
|
package/vendor/VENDOR.json
CHANGED
|
@@ -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:
|
|
6
|
+
"preparedAt": "2026-09-13T13:24:33.857Z",
|
|
7
7
|
"source": "registry",
|
|
8
8
|
"node": "v24.21.0",
|
|
9
9
|
"platform": "win32",
|