dsh-code-server-app 0.3.46 → 0.3.49

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/lib/native.js CHANGED
@@ -16,6 +16,9 @@
16
16
  // 实测证据与复现命令见 docs/desktop-first-install-root-cause.md。
17
17
  //
18
18
  // 「原名 → 真包」的表由打包期写进 lib/vendored.json(随包发布),本模块运行时只读它。
19
+ // 平台专属条目还带一个 `targets` 白名单(打包期由 scripts/repack-platforms.json 推导):
20
+ // 只属于别的平台的模块(如 Linux 上的 @vscode/windows-registry)**不进本平台的清单** ——
21
+ // 它对应的 `-linux-x64` 子包永远不会存在,报成「缺包」只会误导环境检测卡片。
19
22
  //
20
23
  // 本模块只做四件事:
21
24
  // 1. 读 lib/vendored.json → 本平台期望可解析的「原名 → 真包」表;
@@ -36,6 +39,17 @@ export function platformKey(platform = process.platform, arch = process.arch) {
36
39
  return `${platform}-${arch}`;
37
40
  }
38
41
 
42
+ /** 某个条目是否适用于给定平台。
43
+ * 平台无关的模块哪儿都适用;平台专属的看它的每模块 `targets` 白名单
44
+ * ——例如 `@vscode/windows-registry` 只在 win32-* 里有子包,在 Linux 上压根不该去找
45
+ * `@jinsiyu/dshcs-vscode-windows-registry-linux-x64`(那名字永远不会存在)。
46
+ * `targets` 缺席 = 全部目标(兼容 0.3.47 及更早写出的旧表)。 */
47
+ export function vendoredAppliesTo(entry, platform = process.platform, arch = process.arch) {
48
+ if (entry.platform !== true) return true;
49
+ const targets = Array.isArray(entry.targets) ? entry.targets : null;
50
+ return targets === null || targets.includes(platformKey(platform, arch));
51
+ }
52
+
39
53
  /** 读重打包表。
40
54
  * @returns {{scope:string, targets:string[], modules:{alias:string,package:string,version?:string,platform?:boolean}[]}} */
41
55
  export function readVendoredTable() {
@@ -62,9 +76,12 @@ export function vendoredPackageName(entry, platform = process.platform, arch = p
62
76
  }
63
77
 
64
78
  /** 本平台期望装在依赖图里的重打包子包(原名 + 真名),按原名排序。
79
+ * **不含**只属于其它平台的模块(见 vendoredAppliesTo):它们的子包永远不会存在,
80
+ * 报成「缺包」只会误导环境检测卡片。
65
81
  * @returns {{alias:string, packageName:string, version:string|null, platform:boolean}[]} */
66
82
  export function vendoredEntries(platform = process.platform, arch = process.arch) {
67
83
  return readVendoredTable().modules
84
+ .filter((m) => vendoredAppliesTo(m, platform, arch))
68
85
  .map((m) => ({
69
86
  alias: m.alias,
70
87
  packageName: vendoredPackageName(m, platform, arch),
@@ -74,6 +91,14 @@ export function vendoredEntries(platform = process.platform, arch = process.arch
74
91
  .sort((a, b) => a.alias.localeCompare(b.alias));
75
92
  }
76
93
 
94
+ /** 本平台不适用的重打包模块(别名),给环境检测卡片用一句话解释「为什么这些不在清单里」。 */
95
+ export function vendoredNotApplicable(platform = process.platform, arch = process.arch) {
96
+ return readVendoredTable().modules
97
+ .filter((m) => !vendoredAppliesTo(m, platform, arch))
98
+ .map((m) => m.alias)
99
+ .sort((a, b) => a.localeCompare(b));
100
+ }
101
+
77
102
  /** 解析原生模块时的锚点目录:
78
103
  * ① code-server 运行根(树自带 node_modules);
79
104
  * ② 插件包根 —— 重打包子包挂在插件依赖上(profile 根或插件自己的 node_modules),
@@ -266,7 +291,7 @@ export function ensureRuntimeLayout() {
266
291
 
267
292
  /** 本平台预编译原生包的状态汇总(环境检测卡片用)。
268
293
  * @returns {{name:string, source:'package'|null, version:string|null, modules:number, packages:number,
269
- * resolved:number, missing:string[], missingPackages:string[]}} */
294
+ * resolved:number, missing:string[], missingPackages:string[], notApplicable:string[]}} */
270
295
  export function nativeRuntimeStatus(platform = process.platform, arch = process.arch) {
271
296
  const table = readVendoredTable();
272
297
  const entries = vendoredEntries(platform, arch);
@@ -286,5 +311,7 @@ export function nativeRuntimeStatus(platform = process.platform, arch = process.
286
311
  resolved: resolved.length,
287
312
  missing,
288
313
  missingPackages: missingPackages.map((entry) => entry.packageName),
314
+ // 只属于其它平台的模块(如 Linux 上的 windows-*):不计入 modules/missing,单独列出来解释
315
+ notApplicable: vendoredNotApplicable(platform, arch),
289
316
  };
290
317
  }
package/lib/serve-dsh.mjs CHANGED
@@ -1,162 +1,162 @@
1
- /**
2
- * lib/serve-dsh.mjs — 把 VS Code server 挂到 DSH 自身 HTTP 端口上的两段式注册(serve=dsh)。
3
- *
4
- * ctx.webServer.register({ kind: 'prefix', path: '/code-server', handler }) ← HTTP
5
- * ctx.webServer.registerUpgrade({ path: '/code-server/<productPath>', handler }) ← WebSocket(精确匹配)
6
- *
7
- * 两条路径都必须先过 ctx.connection.requestRejection():DSH 的 webServer 本身不做任何校验,
8
- * 防护是逐路由的(Host/Origin fence + 浏览器 cookie 认证),缺了它 IDE 会成为源站上唯一的无认证面。
9
- *
10
- * 转发策略(Phase 0 实测):**剥掉挂载前缀**后转给 launcher 的命名管道 —— VS Code 侧保持根挂载,
11
- * 与今天已验证的配置完全一致;客户端渲染出的资源引用全是相对路径,浏览器按 /code-server/ 解析,
12
- * 因此同一套 prefix 路由就能覆盖 HTML、静态资源、vscode-remote-resource 与 /_static/*。
13
- *
14
- * 已知退化:转发端口(/proxy/:port)的 WebSocket 无法用精确升级路由覆盖(端口号在路径里),
15
- * 需要 DSH 上游提供 prefix upgrade;HTTP 转发端口不受影响。
16
- */
17
-
18
- import { request as httpRequest } from 'node:http';
19
- import { connect } from 'node:net';
20
-
21
- export const MOUNT_PATH = '/code-server';
22
-
23
- /** 前缀匹配(与 DSH webServer 的 prefix 语义一致:命中 p 与 p/<anything>)。 */
24
- function matchesPrefix(pathname, prefix) {
25
- return pathname === prefix || pathname.startsWith(`${prefix}/`);
26
- }
27
-
28
- /** 把 /code-server/xxx 转成上游要的 /xxx(空则 '/'),保留 query。 */
29
- function stripPrefix(url, prefix) {
30
- const rest = url.slice(prefix.length);
31
- return rest === '' ? '/' : rest;
32
- }
33
-
34
- function rejectionOf(connection, req) {
35
- try {
36
- return connection.requestRejection({ headers: req.headers }) ?? undefined;
37
- } catch (error) {
38
- return { error };
39
- }
40
- }
41
-
42
- /** 转发目标的两种形态:命名管道(kind:'pipe')或回环 TCP(kind:'tcp')。
43
- * 注意 http.request 用 socketPath、net.connect 用 path —— 两者键名不同,必须在这里翻译。 */
44
- function httpOptions(target, extra) {
45
- return target.kind === 'pipe'
46
- ? { socketPath: target.pipe, ...extra }
47
- : { host: target.host, port: target.port, ...extra };
48
- }
49
-
50
- function connectTo(target, onConnect) {
51
- return target.kind === 'pipe'
52
- ? connect({ path: target.pipe }, onConnect)
53
- : connect({ host: target.host, port: target.port }, onConnect);
54
- }
55
-
56
- /**
57
- * 注册 IDE 的同源挂载点。
58
- * @param {object} options
59
- * @param {object} options.webServer - DSH webServer 服务(register / registerUpgrade)
60
- * @param {object} options.connection - DSH connection 服务(requestRejection)
61
- * @param {() => ({socketPath: string} | {host: string, port: number} | null)} options.getTarget
62
- * 当前 launcher 的转发目标(命名管道为主;loopback TCP 用于测试/回退)
63
- * @param {string} options.productPath - VS Code 客户端路径(quality-commit)
64
- * @param {string} [options.mount] - 挂载前缀,默认 /code-server
65
- * @param {(msg: string) => void} [options.log]
66
- * @returns {{ disposers: (() => void)[], upgradePath: string }}
67
- */
68
- export function mountOnWebServer({ webServer, connection, getTarget, productPath, mount = MOUNT_PATH, log = () => {} }) {
69
- const upgradePath = `${mount}/${productPath}`;
70
- const disposers = [];
71
-
72
- /** 请求被 fence 拒绝时按 DSH 的约定回 401/403(upgrade 走裸 socket)。 */
73
- function fence(req) {
74
- const rejection = rejectionOf(connection, req);
75
- if (rejection === undefined) return null;
76
- if (typeof rejection === 'object' && rejection.error !== undefined) {
77
- log(`requestRejection 抛错,按 403 处理: ${rejection.error?.message ?? rejection.error}`);
78
- return 403;
79
- }
80
- return rejection;
81
- }
82
-
83
- disposers.push(webServer.register({
84
- kind: 'prefix',
85
- path: mount,
86
- handler: (req, res) => {
87
- try {
88
- const pathname = new URL(req.url ?? '/', 'http://x').pathname;
89
- if (!matchesPrefix(pathname, mount)) { res.writeHead(404); res.end(); return; }
90
- const status = fence(req);
91
- if (status !== null) {
92
- res.writeHead(status, { 'content-type': 'text/plain; charset=utf-8' });
93
- res.end(status === 401 ? 'unauthorized\n' : 'forbidden\n');
94
- return;
95
- }
96
- const target = getTarget();
97
- if (target === null) {
98
- res.writeHead(503, { 'content-type': 'text/plain; charset=utf-8' });
99
- res.end('code-server 未启动\n');
100
- return;
101
- }
102
- const upstream = httpRequest(httpOptions(target, {
103
- method: req.method,
104
- path: stripPrefix(req.url ?? '/', mount),
105
- headers: req.headers,
106
- }), (upstreamRes) => {
107
- res.writeHead(upstreamRes.statusCode ?? 502, upstreamRes.headers);
108
- upstreamRes.pipe(res);
109
- });
110
- upstream.on('error', (error) => {
111
- log(`HTTP 转发失败(${req.method} ${req.url}): ${error.message}`);
112
- if (!res.headersSent) res.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' });
113
- if (!res.writableEnded) res.end('code-server 不可达\n');
114
- });
115
- req.on('aborted', () => upstream.destroy());
116
- req.pipe(upstream);
117
- } catch (error) {
118
- // 路由回调里的异常绝不能冒泡到 DSH 的 webServer(会变成未捕获异常)
119
- log(`HTTP 挂载点异常(${req.method} ${req.url}): ${error && error.stack ? error.stack : error}`);
120
- if (!res.headersSent) res.writeHead(500, { 'content-type': 'text/plain; charset=utf-8' });
121
- if (!res.writableEnded) res.end('code-server 挂载点异常\n');
122
- }
123
- },
124
- }));
125
-
126
- disposers.push(webServer.registerUpgrade({
127
- path: upgradePath,
128
- handler: (req, socket, head) => {
129
- try {
130
- const status = fence(req);
131
- if (status !== null) {
132
- socket.end(`HTTP/1.1 ${status} ${status === 401 ? 'Unauthorized' : 'Forbidden'}\r\nConnection: close\r\n\r\n`);
133
- return;
134
- }
135
- const target = getTarget();
136
- if (target === null) { socket.destroy(); return; }
137
- const upstream = connectTo(target, () => {
138
- const lines = [`GET ${stripPrefix(req.url ?? '/', mount)} HTTP/1.1`];
139
- for (let i = 0; i < req.rawHeaders.length; i += 2) {
140
- lines.push(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}`);
141
- }
142
- upstream.write(`${lines.join('\r\n')}\r\n\r\n`);
143
- if (head !== undefined && head.length > 0) upstream.write(head);
144
- upstream.pipe(socket);
145
- socket.pipe(upstream);
146
- });
147
- upstream.on('error', (error) => { log(`WS 转发失败(${req.url}): ${error.message}`); socket.destroy(); });
148
- socket.on('error', () => upstream.destroy());
149
- socket.on('close', () => upstream.destroy());
150
- } catch (error) {
151
- log(`WS 挂载点异常(${req.url}): ${error && error.stack ? error.stack : error}`);
152
- socket.destroy();
153
- }
154
- },
155
- }));
156
-
157
- log(`已挂载 ${mount}/ (HTTP prefix)+ ${upgradePath} (WS exact)`);
158
- return {
159
- upgradePath,
160
- disposers,
161
- };
162
- }
1
+ /**
2
+ * lib/serve-dsh.mjs — 把 VS Code server 挂到 DSH 自身 HTTP 端口上的两段式注册(serve=dsh)。
3
+ *
4
+ * ctx.webServer.register({ kind: 'prefix', path: '/code-server', handler }) ← HTTP
5
+ * ctx.webServer.registerUpgrade({ path: '/code-server/<productPath>', handler }) ← WebSocket(精确匹配)
6
+ *
7
+ * 两条路径都必须先过 ctx.connection.requestRejection():DSH 的 webServer 本身不做任何校验,
8
+ * 防护是逐路由的(Host/Origin fence + 浏览器 cookie 认证),缺了它 IDE 会成为源站上唯一的无认证面。
9
+ *
10
+ * 转发策略(Phase 0 实测):**剥掉挂载前缀**后转给 launcher 的命名管道 —— VS Code 侧保持根挂载,
11
+ * 与今天已验证的配置完全一致;客户端渲染出的资源引用全是相对路径,浏览器按 /code-server/ 解析,
12
+ * 因此同一套 prefix 路由就能覆盖 HTML、静态资源、vscode-remote-resource 与 /_static/*。
13
+ *
14
+ * 已知退化:转发端口(/proxy/:port)的 WebSocket 无法用精确升级路由覆盖(端口号在路径里),
15
+ * 需要 DSH 上游提供 prefix upgrade;HTTP 转发端口不受影响。
16
+ */
17
+
18
+ import { request as httpRequest } from 'node:http';
19
+ import { connect } from 'node:net';
20
+
21
+ export const MOUNT_PATH = '/code-server';
22
+
23
+ /** 前缀匹配(与 DSH webServer 的 prefix 语义一致:命中 p 与 p/<anything>)。 */
24
+ function matchesPrefix(pathname, prefix) {
25
+ return pathname === prefix || pathname.startsWith(`${prefix}/`);
26
+ }
27
+
28
+ /** 把 /code-server/xxx 转成上游要的 /xxx(空则 '/'),保留 query。 */
29
+ function stripPrefix(url, prefix) {
30
+ const rest = url.slice(prefix.length);
31
+ return rest === '' ? '/' : rest;
32
+ }
33
+
34
+ function rejectionOf(connection, req) {
35
+ try {
36
+ return connection.requestRejection({ headers: req.headers }) ?? undefined;
37
+ } catch (error) {
38
+ return { error };
39
+ }
40
+ }
41
+
42
+ /** 转发目标的两种形态:命名管道(kind:'pipe')或回环 TCP(kind:'tcp')。
43
+ * 注意 http.request 用 socketPath、net.connect 用 path —— 两者键名不同,必须在这里翻译。 */
44
+ function httpOptions(target, extra) {
45
+ return target.kind === 'pipe'
46
+ ? { socketPath: target.pipe, ...extra }
47
+ : { host: target.host, port: target.port, ...extra };
48
+ }
49
+
50
+ function connectTo(target, onConnect) {
51
+ return target.kind === 'pipe'
52
+ ? connect({ path: target.pipe }, onConnect)
53
+ : connect({ host: target.host, port: target.port }, onConnect);
54
+ }
55
+
56
+ /**
57
+ * 注册 IDE 的同源挂载点。
58
+ * @param {object} options
59
+ * @param {object} options.webServer - DSH webServer 服务(register / registerUpgrade)
60
+ * @param {object} options.connection - DSH connection 服务(requestRejection)
61
+ * @param {() => ({socketPath: string} | {host: string, port: number} | null)} options.getTarget
62
+ * 当前 launcher 的转发目标(命名管道为主;loopback TCP 用于测试/回退)
63
+ * @param {string} options.productPath - VS Code 客户端路径(quality-commit)
64
+ * @param {string} [options.mount] - 挂载前缀,默认 /code-server
65
+ * @param {(msg: string) => void} [options.log]
66
+ * @returns {{ disposers: (() => void)[], upgradePath: string }}
67
+ */
68
+ export function mountOnWebServer({ webServer, connection, getTarget, productPath, mount = MOUNT_PATH, log = () => {} }) {
69
+ const upgradePath = `${mount}/${productPath}`;
70
+ const disposers = [];
71
+
72
+ /** 请求被 fence 拒绝时按 DSH 的约定回 401/403(upgrade 走裸 socket)。 */
73
+ function fence(req) {
74
+ const rejection = rejectionOf(connection, req);
75
+ if (rejection === undefined) return null;
76
+ if (typeof rejection === 'object' && rejection.error !== undefined) {
77
+ log(`requestRejection 抛错,按 403 处理: ${rejection.error?.message ?? rejection.error}`);
78
+ return 403;
79
+ }
80
+ return rejection;
81
+ }
82
+
83
+ disposers.push(webServer.register({
84
+ kind: 'prefix',
85
+ path: mount,
86
+ handler: (req, res) => {
87
+ try {
88
+ const pathname = new URL(req.url ?? '/', 'http://x').pathname;
89
+ if (!matchesPrefix(pathname, mount)) { res.writeHead(404); res.end(); return; }
90
+ const status = fence(req);
91
+ if (status !== null) {
92
+ res.writeHead(status, { 'content-type': 'text/plain; charset=utf-8' });
93
+ res.end(status === 401 ? 'unauthorized\n' : 'forbidden\n');
94
+ return;
95
+ }
96
+ const target = getTarget();
97
+ if (target === null) {
98
+ res.writeHead(503, { 'content-type': 'text/plain; charset=utf-8' });
99
+ res.end('code-server 未启动\n');
100
+ return;
101
+ }
102
+ const upstream = httpRequest(httpOptions(target, {
103
+ method: req.method,
104
+ path: stripPrefix(req.url ?? '/', mount),
105
+ headers: req.headers,
106
+ }), (upstreamRes) => {
107
+ res.writeHead(upstreamRes.statusCode ?? 502, upstreamRes.headers);
108
+ upstreamRes.pipe(res);
109
+ });
110
+ upstream.on('error', (error) => {
111
+ log(`HTTP 转发失败(${req.method} ${req.url}): ${error.message}`);
112
+ if (!res.headersSent) res.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' });
113
+ if (!res.writableEnded) res.end('code-server 不可达\n');
114
+ });
115
+ req.on('aborted', () => upstream.destroy());
116
+ req.pipe(upstream);
117
+ } catch (error) {
118
+ // 路由回调里的异常绝不能冒泡到 DSH 的 webServer(会变成未捕获异常)
119
+ log(`HTTP 挂载点异常(${req.method} ${req.url}): ${error && error.stack ? error.stack : error}`);
120
+ if (!res.headersSent) res.writeHead(500, { 'content-type': 'text/plain; charset=utf-8' });
121
+ if (!res.writableEnded) res.end('code-server 挂载点异常\n');
122
+ }
123
+ },
124
+ }));
125
+
126
+ disposers.push(webServer.registerUpgrade({
127
+ path: upgradePath,
128
+ handler: (req, socket, head) => {
129
+ try {
130
+ const status = fence(req);
131
+ if (status !== null) {
132
+ socket.end(`HTTP/1.1 ${status} ${status === 401 ? 'Unauthorized' : 'Forbidden'}\r\nConnection: close\r\n\r\n`);
133
+ return;
134
+ }
135
+ const target = getTarget();
136
+ if (target === null) { socket.destroy(); return; }
137
+ const upstream = connectTo(target, () => {
138
+ const lines = [`GET ${stripPrefix(req.url ?? '/', mount)} HTTP/1.1`];
139
+ for (let i = 0; i < req.rawHeaders.length; i += 2) {
140
+ lines.push(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}`);
141
+ }
142
+ upstream.write(`${lines.join('\r\n')}\r\n\r\n`);
143
+ if (head !== undefined && head.length > 0) upstream.write(head);
144
+ upstream.pipe(socket);
145
+ socket.pipe(upstream);
146
+ });
147
+ upstream.on('error', (error) => { log(`WS 转发失败(${req.url}): ${error.message}`); socket.destroy(); });
148
+ socket.on('error', () => upstream.destroy());
149
+ socket.on('close', () => upstream.destroy());
150
+ } catch (error) {
151
+ log(`WS 挂载点异常(${req.url}): ${error && error.stack ? error.stack : error}`);
152
+ socket.destroy();
153
+ }
154
+ },
155
+ }));
156
+
157
+ log(`已挂载 ${mount}/ (HTTP prefix)+ ${upgradePath} (WS exact)`);
158
+ return {
159
+ upgradePath,
160
+ disposers,
161
+ };
162
+ }
package/lib/vendored.json CHANGED
@@ -3,8 +3,10 @@
3
3
  "generatedBy": "scripts/vendor-repacks.mjs",
4
4
  "scope": "@jinsiyu",
5
5
  "targets": [
6
+ "win32-x64",
6
7
  "win32-arm64",
7
- "win32-x64"
8
+ "linux-x64",
9
+ "linux-arm64"
8
10
  ],
9
11
  "modules": [
10
12
  {
@@ -21,7 +23,13 @@
21
23
  "alias": "@vscode/deviceid",
22
24
  "package": "@jinsiyu/dshcs-vscode-deviceid",
23
25
  "version": "0.1.5",
24
- "platform": true
26
+ "platform": true,
27
+ "targets": [
28
+ "win32-x64",
29
+ "win32-arm64",
30
+ "linux-x64",
31
+ "linux-arm64"
32
+ ]
25
33
  },
26
34
  {
27
35
  "alias": "@vscode/fs-copyfile",
@@ -32,7 +40,13 @@
32
40
  "alias": "@vscode/native-watchdog",
33
41
  "package": "@jinsiyu/dshcs-vscode-native-watchdog",
34
42
  "version": "1.4.6",
35
- "platform": true
43
+ "platform": true,
44
+ "targets": [
45
+ "win32-x64",
46
+ "win32-arm64",
47
+ "linux-x64",
48
+ "linux-arm64"
49
+ ]
36
50
  },
37
51
  {
38
52
  "alias": "@vscode/proxy-agent",
@@ -43,31 +57,55 @@
43
57
  "alias": "@vscode/spdlog",
44
58
  "package": "@jinsiyu/dshcs-vscode-spdlog",
45
59
  "version": "0.15.8",
46
- "platform": true
60
+ "platform": true,
61
+ "targets": [
62
+ "win32-x64",
63
+ "win32-arm64",
64
+ "linux-x64",
65
+ "linux-arm64"
66
+ ]
47
67
  },
48
68
  {
49
69
  "alias": "@vscode/sqlite3",
50
70
  "package": "@jinsiyu/dshcs-vscode-sqlite3",
51
71
  "version": "5.1.12-vscode",
52
- "platform": true
72
+ "platform": true,
73
+ "targets": [
74
+ "win32-x64",
75
+ "win32-arm64",
76
+ "linux-x64",
77
+ "linux-arm64"
78
+ ]
53
79
  },
54
80
  {
55
81
  "alias": "@vscode/windows-ca-certs",
56
82
  "package": "@jinsiyu/dshcs-vscode-windows-ca-certs",
57
83
  "version": "0.3.4",
58
- "platform": true
84
+ "platform": true,
85
+ "targets": [
86
+ "win32-x64",
87
+ "win32-arm64"
88
+ ]
59
89
  },
60
90
  {
61
91
  "alias": "@vscode/windows-process-tree",
62
92
  "package": "@jinsiyu/dshcs-vscode-windows-process-tree",
63
93
  "version": "0.8.0",
64
- "platform": true
94
+ "platform": true,
95
+ "targets": [
96
+ "win32-x64",
97
+ "win32-arm64"
98
+ ]
65
99
  },
66
100
  {
67
101
  "alias": "@vscode/windows-registry",
68
102
  "package": "@jinsiyu/dshcs-vscode-windows-registry",
69
103
  "version": "1.2.0",
70
- "platform": true
104
+ "platform": true,
105
+ "targets": [
106
+ "win32-x64",
107
+ "win32-arm64"
108
+ ]
71
109
  },
72
110
  {
73
111
  "alias": "cpu-features",
@@ -78,7 +116,13 @@
78
116
  "alias": "kerberos",
79
117
  "package": "@jinsiyu/dshcs-kerberos",
80
118
  "version": "2.1.1-dshcs.1",
81
- "platform": true
119
+ "platform": true,
120
+ "targets": [
121
+ "win32-x64",
122
+ "win32-arm64",
123
+ "linux-x64",
124
+ "linux-arm64"
125
+ ]
82
126
  },
83
127
  {
84
128
  "alias": "koffi",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-code-server-app",
3
- "version": "0.3.46",
3
+ "version": "0.3.49",
4
4
  "description": "VS Code (from a code-server release) inside DSH: a right-sidebar tab driven by the plugin's own launcher over the in-process VS Code server (lib/launcher.mjs). Since 0.3.0 the bundle also ships an editor bridge (assets/extensions/dshcs-editor-bridge): a read-only channel between the in-tree VS Code extension host and DSH, giving the agent what only the editor knows (unsaved buffers, language-server diagnostics, the active selection) and letting editor gestures drive the session. Since 0.3.22 the ask panel renders that session's new content with DSH's own Markdown renderer (pinned to the deployed DSH UI version); since 0.3.23 it is a full-width dialog with collapsible thinking rows and can answer approval requests in place — the bridge's only non-read-only route (POST /approve, constrained to pending in-process requests and the outcomes allowed-once/rejected; panel-first for 5 minutes, handed back to the official card the moment the panel closes). The tab claims DSH file addresses (dsh-resource://file/**) by file type (setting claimExtensions), so the product's own produced-file chips, delivered-file previews and inline prose mentions open in the workbench. The IDE is a resident surface moved with Element.moveBefore instead of being remounted, so switching sidebar tabs no longer reloads it. Opening the tab switches the right sidebar to fullscreen by default (setting fullscreenOnOpen). Following a workspace switch is lightweight: the workbench re-navigates with the new ?folder= and the IDE process is not restarted (since 0.2.12). Requires a DSH with the right-sidebar services (sidebarRightTabs/sidebarRight, >= 0.1.5-alpha.1); older DSH versions get a single upgrade notice on the settings page and no other UI. Two serving modes: loopback port (default) or same-origin mount on DSH's own webServer (/code-server, protected by ctx.connection.requestRejection). No code-server Node layer, no argon2, no C++ toolchain.",
5
5
  "homepage": "https://github.com/jinsiyu/dsh-code-server-app",
6
6
  "repository": {
@@ -64,34 +64,14 @@
64
64
  "README.md",
65
65
  "README.en.md"
66
66
  ],
67
- "scripts": {
68
- "vendor:vscode": "node scripts/vendor-vscode-server.mjs",
69
- "vendor:latest": "node scripts/vendor-vscode-server.mjs --force",
70
- "vendor:check": "node scripts/vendor-vscode-server.mjs --check",
71
- "vendor:code-server": "node scripts/vendor-code-server.mjs",
72
- "repack:build": "node scripts/vendor-repacks.mjs",
73
- "publish:repacks": "node scripts/publish-repacks.mjs",
74
- "publish:plugin": "node scripts/publish-plugin.mjs",
75
- "promote": "node scripts/promote.mjs",
76
- "prepack": "node scripts/vendor-vscode-server.mjs && node scripts/build-webview.mjs",
77
- "build:client": "node scripts/build-client.mjs",
78
- "build:webview": "node scripts/build-webview.mjs",
79
- "test:apply": "node scripts/test-plugin-apply.mjs",
80
- "test:launcher-routes": "node scripts/test-launcher-routes.mjs",
81
- "test:fullscreen": "node scripts/test-sidebar-fullscreen.mjs",
82
- "test:claim-types": "node scripts/test-claim-types.mjs",
83
- "test:workspace-switch": "node scripts/test-workspace-switch.mjs",
84
- "test:bridge-routes": "node scripts/test-bridge-routes.mjs",
85
- "test:bridge-extension": "node scripts/test-bridge-extension.mjs",
86
- "test:webview": "node scripts/test-webview-bundle.mjs",
87
- "test:vendored": "node scripts/test-vendored-table.mjs"
88
- },
89
67
  "devDependencies": {
90
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
91
- "@deepseek-ai/dsh-client-ui-theme": "0.1.5-rc.2",
68
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.6-alpha.1",
69
+ "@deepseek-ai/dsh-client-ui-theme": "0.1.6-alpha.1",
70
+ "@deepseek-ai/schemastery": "3.18.2",
92
71
  "@shikijs/langs": "4.3.1",
93
72
  "anser": "2.3.5",
94
73
  "clsx": "2.0.0",
74
+ "diff": "9.0.0",
95
75
  "esbuild": "^0.25.0",
96
76
  "katex": "0.16.47",
97
77
  "mdast-util-from-markdown": "2.0.3",
@@ -162,14 +142,24 @@
162
142
  "zod": "4.4.3"
163
143
  },
164
144
  "optionalDependencies": {
145
+ "@jinsiyu/dshcs-kerberos-linux-arm64": "2.1.1-dshcs.1",
146
+ "@jinsiyu/dshcs-kerberos-linux-x64": "2.1.1-dshcs.1",
165
147
  "@jinsiyu/dshcs-kerberos-win32-arm64": "2.1.1-dshcs.1",
166
148
  "@jinsiyu/dshcs-kerberos-win32-x64": "2.1.1-dshcs.1",
149
+ "@jinsiyu/dshcs-vscode-deviceid-linux-arm64": "0.1.5",
150
+ "@jinsiyu/dshcs-vscode-deviceid-linux-x64": "0.1.5",
167
151
  "@jinsiyu/dshcs-vscode-deviceid-win32-arm64": "0.1.5",
168
152
  "@jinsiyu/dshcs-vscode-deviceid-win32-x64": "0.1.5",
153
+ "@jinsiyu/dshcs-vscode-native-watchdog-linux-arm64": "1.4.6",
154
+ "@jinsiyu/dshcs-vscode-native-watchdog-linux-x64": "1.4.6",
169
155
  "@jinsiyu/dshcs-vscode-native-watchdog-win32-arm64": "1.4.6",
170
156
  "@jinsiyu/dshcs-vscode-native-watchdog-win32-x64": "1.4.6",
157
+ "@jinsiyu/dshcs-vscode-spdlog-linux-arm64": "0.15.8",
158
+ "@jinsiyu/dshcs-vscode-spdlog-linux-x64": "0.15.8",
171
159
  "@jinsiyu/dshcs-vscode-spdlog-win32-arm64": "0.15.8",
172
160
  "@jinsiyu/dshcs-vscode-spdlog-win32-x64": "0.15.8",
161
+ "@jinsiyu/dshcs-vscode-sqlite3-linux-arm64": "5.1.12-vscode",
162
+ "@jinsiyu/dshcs-vscode-sqlite3-linux-x64": "5.1.12-vscode",
173
163
  "@jinsiyu/dshcs-vscode-sqlite3-win32-arm64": "5.1.12-vscode",
174
164
  "@jinsiyu/dshcs-vscode-sqlite3-win32-x64": "5.1.12-vscode",
175
165
  "@jinsiyu/dshcs-vscode-windows-ca-certs-win32-arm64": "0.3.4",
@@ -178,5 +168,32 @@
178
168
  "@jinsiyu/dshcs-vscode-windows-process-tree-win32-x64": "0.8.0",
179
169
  "@jinsiyu/dshcs-vscode-windows-registry-win32-arm64": "1.2.0",
180
170
  "@jinsiyu/dshcs-vscode-windows-registry-win32-x64": "1.2.0"
171
+ },
172
+ "scripts": {
173
+ "test": "node scripts/run-all-tests.mjs",
174
+ "test:all": "node scripts/run-all-tests.mjs",
175
+ "test:installed": "node scripts/test-installed.mjs",
176
+ "vendor:vscode": "node scripts/vendor-vscode-server.mjs",
177
+ "vendor:latest": "node scripts/vendor-vscode-server.mjs --force",
178
+ "vendor:check": "node scripts/vendor-vscode-server.mjs --check",
179
+ "vendor:code-server": "node scripts/vendor-code-server.mjs",
180
+ "repack:build": "node scripts/vendor-repacks.mjs",
181
+ "publish:repacks": "node scripts/publish-repacks.mjs",
182
+ "publish:plugin": "node scripts/publish-plugin.mjs",
183
+ "promote": "node scripts/promote.mjs",
184
+ "build:client": "node scripts/build-client.mjs",
185
+ "build:webview": "node scripts/build-webview.mjs",
186
+ "test:apply": "node scripts/test-plugin-apply.mjs",
187
+ "test:launcher-routes": "node scripts/test-launcher-routes.mjs",
188
+ "test:fullscreen": "node scripts/test-sidebar-fullscreen.mjs",
189
+ "test:claim-types": "node scripts/test-claim-types.mjs",
190
+ "test:workspace-switch": "node scripts/test-workspace-switch.mjs",
191
+ "test:workspace-cwd": "node scripts/test-workspace-cwd.mjs",
192
+ "test:client-cwd": "node scripts/test-client-bundle-cwd.mjs",
193
+ "test:dsh-resolve": "node scripts/test-dsh-resolve.mjs",
194
+ "test:bridge-routes": "node scripts/test-bridge-routes.mjs",
195
+ "test:bridge-extension": "node scripts/test-bridge-extension.mjs",
196
+ "test:webview": "node scripts/test-webview-bundle.mjs",
197
+ "test:vendored": "node scripts/test-vendored-table.mjs"
181
198
  }
182
- }
199
+ }