@dsh-enhanced/dsh-rsi-cli 0.1.48 → 0.1.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/README.md CHANGED
@@ -22,7 +22,7 @@ dsh-rsi [全局选项] <命令>
22
22
  | `logs` | 查看各 profile 的受管 `*-host.log` / `*-host.error.log` 尾部(默认末 200 行)。**只读**。 |
23
23
  | `web-url` | 从运行中受管服务的 journal(Linux)或 `*-host.log`(macOS)解析最近一次 `dsh web:` 行,输出带 token 的完整 Web 授权 URL。**只读**,不关闭或绕过 Web 认证;服务未运行时提示先 `dsh-rsi start`。 |
24
24
  | `update` | 升级全局 dsh-rsi 自身;加 `--all` 再把插件集合交给安装器 `--operation upgrade` **原地升级**(保留 patch、凭据、Session、Goal)。 |
25
- | `install` | 安装/修复插件集合:npm 形态下载与本 dsh-rsi 同版本的官方安装器执行,`--local <dir>` 执行 checkout 内安装器;其余参数原样透传。 |
25
+ | `install` | 安装/修复插件集合:默认选择 supervised 自迭代场景;npm 形态下载与本 dsh-rsi 同版本的官方安装器执行,`--local <dir>` 执行 checkout 内安装器。 |
26
26
  | `reinstall` | 先 `purge`(默认先备份、同样的安全门控)再立即 `install`,用于干净重装。 |
27
27
  | `purge` | 彻底卸载:进程静止检查 → 停服注销 → tar.gz 备份 → 删除 profile / DSH home / 生命周期残留 → 清理外部凭据。 |
28
28
  | `version` | 打印版本。 |
@@ -37,14 +37,26 @@ dsh-rsi [全局选项] <命令>
37
37
 
38
38
  ## install / reinstall(薄委托)
39
39
 
40
- `dsh-rsi install` 不复制任何安装逻辑,只做统一入口与引导器版本固定:
40
+ `dsh-rsi install` 为全新 Home 选择 Host,再调用统一安装器:
41
+
42
+ `install` 和 `reinstall` 在未指定 `--scenario`、也未指定 `--mode` 时,向安装器显式传入 `--scenario supervised`;`--dry-run` 会展示这一默认场景。完整 supervised 需要 Linux/systemd user services;macOS 可显式选择 `--scenario core` 等轻量场景。显式 `--lark skip` 或 `--no-service` 不追加完整场景,交由统一安装器保留有限场景;它们不能覆盖用户显式选择的 `supervised`。显式 `--scenario` 或旧式 `--mode` 保持安装器原有语义,例如 `--scenario core` 选择 core,`--mode standard` 保留安装器的自动选择。`update --all` 等升级、卸载、恢复及 `install --help` 不采用此默认值。其余参数仍按原顺序透传。
43
+
44
+ 首次飞书身份授权须由平台的授权流程完成。全新 Home 尚无飞书 Bot 时,`supervised --yes` 或管道等非交互执行会在安装前停止;先在交互式终端运行 `dsh-rsi install` 完成 onboarding。安装器保留已有模型选择,并生成路径、签名身份及有期限的授权与有限预算;仍须有可用模型及隔离构建环境。已有 active/paused Automation 需要另行确认 `--ack-existing-automations`,`--yes` 不代替它。授权尚未就绪时,不能把 supervised 安装称为成功。
41
45
 
42
46
  - **npm 形态(默认)**:下载 `https://raw.githubusercontent.com/22-ai-00/dsh-enhanced/v<本包版本>/scripts/install/install-npm.sh` 到临时目录执行。引导脚本内部会按内嵌 SHA-256 自校验 `common.sh` 等资产,dsh-rsi 不重复 hash 逻辑。**锁定的只是引导脚本与同 tag 的安装器资产,不是插件 cohort 版本**:安装器默认把 `@dsh-enhanced/personal-assistant@latest` 解析为精确版本,再以该版本安装整套 `@dsh-enhanced/*` bundle;要锁定插件版本需透传 `--plugin-version <x.y.z|dist-tag>` 或预设 `DSH_ENHANCED_VERSION`。安装器尾部还会执行 `npm install --global @dsh-enhanced/dsh-rsi-cli@<cohort 版本>`,可能因此把全局 dsh-rsi 升降级到该 cohort 版本。
43
47
  - **local 形态**:`--local <checkout 目录>`,直接执行该目录下 `scripts/install/install-local.sh`,并从该 checkout 的 packages/dsh-rsi-cli 全局安装(本地开发 / 无网救机)。
44
- - 安装器 stdio 与终端直连(交互提示照常),退出码原样透传。
48
+ - 全新、空的 `DSH_HOME` 默认从官方 npm 解析一次 DSH `latest`,当前新安装接受已适配的 `0.2.0-rc.2`(官方 latest,尚非正式稳定版),安装到 `~/.local/share/dsh-enhanced/hosts/<精确版本>`。安装不执行依赖安装脚本;校验 registry integrity、lockfile、实际入口及全部安装文件后,写入 Home 内的私有 `.dsh-rsi-host.json`。不替换全局 DSH。安装器及其生成的常驻服务使用该私有入口,补装 pnpm 后仍保留这个入口的优先级。
49
+ - 重试安装按 Home 绑定读取原精确版本,并核对文件与收据;重试不重新解析 `latest`。受管 Home 的升级入口默认解析官方 `latest`,先核对兼容范围,再通过独立事务迁移 Host;同版本不创建 Host 事务。已有未绑定 Home 保留原 Host。`--dsh-version` 可在首次安装或受管 Home 升级时选择范围内精确版本,不能直接覆盖已有绑定。此路径已在 Linux 验证;macOS/Windows 私有 Host 安装尚未实机验证。直接运行 shell 安装脚本仍使用原有 Host 选择方式。
50
+ - 同一 Home 不支持与旧版或外部安装器并发安装;绑定文件原子发布不等于整个安装流程具有跨程序排他锁。
51
+ - 私有缓存是多个 Home 可共享的安装资源;全量 purge/reinstall 删除 Home 绑定但保留缓存,`--remove-host` 仍只操作全局 npm Host。缓存只含运行程序及收据,不含飞书凭据。
52
+ - 安装器 stdio 与终端直连,退出码原样透传。`--help` / `--dry-run` 不准备私有 Host。
45
53
 
46
54
  ```bash
47
- # npm 形态安装 core 场景(其余安装器参数任意透传)
55
+ # npm 形态在交互式终端安装 supervised 场景
56
+ dsh-rsi install
57
+
58
+ # 已完成飞书 onboarding 后可非交互重试;显式选择 core 也无需飞书
59
+ dsh-rsi install --yes
48
60
  dsh-rsi install --scenario core --yes
49
61
 
50
62
  # local checkout 形态
@@ -53,9 +65,10 @@ dsh-rsi install --local ~/work/github/dsh-enhanced --scenario web
53
65
  # 查看安装器支持的全部参数
54
66
  dsh-rsi install --help
55
67
 
56
- # 干净重装:先备份+purge,再按相同形态重新安装
57
- dsh-rsi reinstall --yes
58
- dsh-rsi reinstall --profile web --yes
68
+ # 干净重装:先备份+purge,再交互式完成新的 supervised onboarding
69
+ dsh-rsi reinstall
70
+ # 若只需轻量场景,可非交互地重装 core
71
+ dsh-rsi reinstall --profile web --scenario core --yes
59
72
  ```
60
73
 
61
74
  `reinstall` 支持的 rsi 侧选项与 `purge` 一致(`--no-backup` / `--keep-keychain` / `--remove-host` / `--profile`);只有既未加 `--yes` 也未加 `--dry-run` 时才需输入 `purge` 确认——`reinstall --dry-run` 全程无交互、无修改:先打印 purge 计划,再以 `--dry-run` 透传演练安装器(`--dry-run` 同时作用于 purge 与安装两个阶段)。重装阶段默认走 npm 形态;local 重装加 `--local <dir>`。
@@ -79,11 +92,17 @@ dsh-rsi update --all --yes
79
92
 
80
93
  `update` 选项:
81
94
 
82
- - `--all`:自身升级成功后,自动确认目标 profile 没有运行中 Host,再把插件集合交给同一目标版本的安装器原地升级。用户无需传 `--confirm-dsh-home-stopped` 或重复声明 `--scenario`;安装器从 effective/composed profile 自动识别场景。
95
+ - `--all`:自身升级成功后,把插件集合交给同一目标版本的安装器原地升级;Linux 受管服务由事务停服并恢复,额外或手工启动的 Host 必须先停止。`0.1.49` 起,在已绑定的 Linux Home 继续执行受管 Host 更新;版本相同则跳过。用户无需传 `--confirm-dsh-home-stopped` 或重复声明 `--scenario`;安装器从 effective/composed profile 自动识别场景。
83
96
  - `--version <v|tag>`:dsh-rsi 自身的目标版本或 dist-tag(默认 `latest`)。只接受精确版本 `x.y.z`(可带预发布后缀)或纯字母 dist-tag;范围表达式如 `>=0.1.0` 会被拒绝。
84
97
  - `--dry-run`:解析出目标版本并打印将执行的命令,不做任何安装。
85
98
  - 其余参数在 `--all` 下原样透传给安装器;`--local <dir>` 走 local 形态。显式 `--scenario` 仍可作为一致性断言,但不再是必填项。
86
99
 
100
+ ### 受管 Host 更新
101
+
102
+ `0.1.49` 起,已绑定 Linux Home 的受管更新分两步:先完成目标与协调器的同批插件升级,使其具备新版状态读取能力;再在 Home 外准备精确 Host 与原生依赖,停止同一 Home 的受管服务,对完整副本迁移、验证并切换。旧 `0.1` Home 到 `0.2` 不支持普通自动升级,须使用安装指南中的显式联合迁移。Host 阶段失败可能保留已成功更新的插件和旧 Host;整个命令不提供跨两个阶段的原子回退。真实跨版本 Host 更新的验收状态见 [RSI 状态](../../docs/rsi-status.md)。
103
+
104
+ Host 事务覆盖同一 Home 的其它 profile,保留原配置、owner、历史记录、密钥、授权期限和已用额度。候选服务须重新通过启动与运行验收;中断重试先恢复已有事务,再规划更新。冻结本地源码/cohort 的升级仍不支持。兼容范围外的新 `latest` 会明确报错,须完成适配后才能更新;不会改用 `next` 或替换全局 Host。
105
+
87
106
  ### 三条语义边界
88
107
 
89
108
  - **自身先行,失败即止**。`--all` 下先升级 dsh-rsi 自身,失败就**不**继续升级 cohort —— 避免用旧版 rsi 的判断去驱动一轮新的 cohort 升级。
@@ -0,0 +1,36 @@
1
+ export interface ManagedHostRuntime {
2
+ version: string;
3
+ root: string;
4
+ dshPath: string;
5
+ binDirectory: string;
6
+ integrity: string;
7
+ receiptDigest: string;
8
+ }
9
+ export interface ManagedHostCommandResult {
10
+ exitCode: number;
11
+ stdout: string;
12
+ stderr: string;
13
+ }
14
+ export interface ManagedHostRuntimePorts {
15
+ /** Injectable npm transport for deterministic fixtures. The dsh executable is always run for real. */
16
+ runNpm?: (args: readonly string[], options: {
17
+ cwd: string;
18
+ signal: AbortSignal;
19
+ timeoutMs: number;
20
+ }) => Promise<ManagedHostCommandResult>;
21
+ }
22
+ export declare function isSupportedReceiptVersion(version: string): boolean;
23
+ export declare function isSupportedCandidateVersion(version: string): boolean;
24
+ /** Read and independently verify a previously prepared exact version without contacting npm. */
25
+ export declare function readManagedHostRuntime(input: {
26
+ root: string;
27
+ version: string;
28
+ signal?: AbortSignal;
29
+ }): Promise<ManagedHostRuntime>;
30
+ /** Resolve once from the official npm registry, then install exact DSH into an owner-private version directory. */
31
+ export declare function prepareManagedHostRuntime(input: {
32
+ root: string;
33
+ selector?: 'latest' | string;
34
+ signal?: AbortSignal;
35
+ }, ports?: ManagedHostRuntimePorts): Promise<ManagedHostRuntime>;
36
+ //# sourceMappingURL=host-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-runtime.d.ts","sourceRoot":"","sources":["../src/host-runtime.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,sGAAsG;IACtG,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAA;CAC1I;AA0BD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGlE;AACD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEpE;AAgQD,gGAAgG;AAChG,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAIxI;AAED,mHAAmH;AACnH,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,EAAE,KAAK,GAAE,uBAA4B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkC7L"}
@@ -0,0 +1,400 @@
1
+ import { randomUUID, createHash } from 'node:crypto';
2
+ import { spawn } from 'node:child_process';
3
+ import { createReadStream } from 'node:fs';
4
+ import { chmod, lstat, mkdir, readFile, readdir, readlink, realpath, rename, rm, stat, writeFile } from 'node:fs/promises';
5
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
6
+ const PACKAGE = '@deepseek-ai/dsh';
7
+ const REGISTRY = 'https://registry.npmjs.org/';
8
+ const MAX_OUTPUT = 1024 * 1024;
9
+ const MAX_RECEIPT = 32 * 1024 * 1024;
10
+ const MAX_ENTRIES = 150_000;
11
+ const NPM_TIMEOUT = 8 * 60_000;
12
+ const LOCK_TIMEOUT = 10 * 60_000;
13
+ function fail(message) { throw new Error(`Managed DSH runtime: ${message}`); }
14
+ function sha256(input) { return createHash('sha256').update(input).digest('hex'); }
15
+ function inside(base, path) {
16
+ const part = relative(base, path);
17
+ return part === '' || (part !== '..' && !part.startsWith(`..${sep}`) && !isAbsolute(part));
18
+ }
19
+ export function isSupportedReceiptVersion(version) {
20
+ const match = /^0\.1\.5(?:-rc\.([0-9]{1,6}))?$/u.exec(version);
21
+ return version === '0.2.0-rc.2' || match !== null && (match[1] === undefined || Number(match[1]) >= 3);
22
+ }
23
+ export function isSupportedCandidateVersion(version) {
24
+ return version === '0.2.0-rc.2';
25
+ }
26
+ function validReceiptVersion(version) {
27
+ if (!isSupportedReceiptVersion(version))
28
+ fail(`unsupported DSH receipt version ${JSON.stringify(version)}`);
29
+ return version;
30
+ }
31
+ function validCandidateVersion(version) {
32
+ if (!isSupportedCandidateVersion(version))
33
+ fail(`unsupported DSH version ${JSON.stringify(version)}; validated candidate is 0.2.0-rc.2`);
34
+ return version;
35
+ }
36
+ function validIntegrity(integrity) {
37
+ if (!/^sha512-[A-Za-z0-9+/]+={0,2}$/u.test(integrity))
38
+ return false;
39
+ const digest = integrity.slice('sha512-'.length);
40
+ return Buffer.from(digest, 'base64').length === 64
41
+ && Buffer.from(digest, 'base64').toString('base64') === digest;
42
+ }
43
+ async function canonicalRoot(root, create) {
44
+ if (!isAbsolute(root) || resolve(root) !== root)
45
+ fail('cache root must be an absolute canonical path');
46
+ if (create)
47
+ await mkdir(root, { recursive: true, mode: 0o700 });
48
+ const info = await lstat(root);
49
+ if (!info.isDirectory() || info.isSymbolicLink())
50
+ fail('cache root is not a real directory');
51
+ if (process.getuid !== undefined && info.uid !== process.getuid())
52
+ fail('cache root is not owned by the current user');
53
+ if ((info.mode & 0o077) !== 0)
54
+ fail('cache root must be private (mode 0700)');
55
+ if (await realpath(root) !== root)
56
+ fail('cache root contains a symlink or a noncanonical path');
57
+ return root;
58
+ }
59
+ async function runBounded(command, args, options) {
60
+ const maxOutput = options.maxOutput ?? MAX_OUTPUT;
61
+ if (options.signal.aborted)
62
+ fail('operation cancelled');
63
+ return await new Promise((resolvePromise, reject) => {
64
+ const child = spawn(command, [...args], { cwd: options.cwd, shell: false, detached: process.platform !== 'win32', stdio: ['ignore', 'pipe', 'pipe'] });
65
+ let stdout = '';
66
+ let stderr = '';
67
+ let ended = false;
68
+ let reason;
69
+ const kill = (why) => {
70
+ if (reason === undefined)
71
+ reason = why;
72
+ if (child.pid !== undefined && process.platform !== 'win32') {
73
+ try {
74
+ process.kill(-child.pid, 'SIGKILL');
75
+ }
76
+ catch {
77
+ child.kill('SIGKILL');
78
+ }
79
+ }
80
+ else
81
+ child.kill('SIGKILL');
82
+ };
83
+ const timer = setTimeout(() => kill(`timed out after ${options.timeoutMs} ms`), options.timeoutMs);
84
+ const aborted = () => kill('cancelled');
85
+ options.signal.addEventListener('abort', aborted, { once: true });
86
+ const append = (which, chunk) => {
87
+ if (reason !== undefined)
88
+ return;
89
+ if (which === 'stdout')
90
+ stdout += chunk.toString('utf8');
91
+ else
92
+ stderr += chunk.toString('utf8');
93
+ if (Buffer.byteLength(stdout) + Buffer.byteLength(stderr) > maxOutput) {
94
+ stdout = stdout.slice(0, maxOutput);
95
+ stderr = stderr.slice(0, maxOutput);
96
+ kill(`output exceeded ${maxOutput} bytes`);
97
+ }
98
+ };
99
+ child.stdout?.on('data', (chunk) => append('stdout', chunk));
100
+ child.stderr?.on('data', (chunk) => append('stderr', chunk));
101
+ const finish = (error, code) => {
102
+ if (ended)
103
+ return;
104
+ ended = true;
105
+ clearTimeout(timer);
106
+ options.signal.removeEventListener('abort', aborted);
107
+ if (error !== undefined)
108
+ reject(error);
109
+ else if (reason !== undefined)
110
+ reject(new Error(`Managed DSH runtime: process ${basename(command)} ${reason}`));
111
+ else
112
+ resolvePromise({ exitCode: code ?? -1, stdout, stderr });
113
+ };
114
+ child.on('error', error => finish(new Error(`Managed DSH runtime: cannot start ${basename(command)} (${error.message})`)));
115
+ child.on('close', code => finish(undefined, code));
116
+ });
117
+ }
118
+ async function npmCommand(args, cwd, signal, ports) {
119
+ const result = await (ports.runNpm ?? ((cmdArgs, opts) => runBounded('npm', cmdArgs, opts)))(args, { cwd, signal, timeoutMs: NPM_TIMEOUT });
120
+ if (result.exitCode !== 0) {
121
+ // npm diagnostics can echo auth configuration. Report a stable error code, never raw output.
122
+ const code = /(?:^|\n)npm (?:ERR!|error) code ([A-Z][A-Z0-9_]*)/u.exec(result.stderr)?.[1];
123
+ fail(`npm ${args[0] ?? 'command'} failed (exit ${result.exitCode}${code === undefined ? '' : `, ${code}`})`);
124
+ }
125
+ if (Buffer.byteLength(result.stdout) + Buffer.byteLength(result.stderr) > MAX_OUTPUT)
126
+ fail('npm output exceeded limit');
127
+ return result;
128
+ }
129
+ async function resolveMetadata(selector, root, signal, ports) {
130
+ if (selector !== 'latest')
131
+ validCandidateVersion(selector);
132
+ const response = await npmCommand(['view', `${PACKAGE}@${selector}`, 'version', 'dist.integrity', 'dist.tarball', '--json', '--prefer-online', `--registry=${REGISTRY}`], root, signal, ports);
133
+ let object;
134
+ try {
135
+ object = JSON.parse(response.stdout);
136
+ }
137
+ catch {
138
+ fail('npm view did not return valid JSON');
139
+ }
140
+ if (object === null || typeof object !== 'object' || Array.isArray(object))
141
+ fail('npm view returned unexpected metadata');
142
+ const data = object;
143
+ const version = data.version;
144
+ const integrity = data['dist.integrity'];
145
+ const tarball = data['dist.tarball'];
146
+ if (typeof version !== 'string' || typeof integrity !== 'string' || typeof tarball !== 'string')
147
+ fail('npm metadata is incomplete');
148
+ validCandidateVersion(version);
149
+ if (selector !== 'latest' && version !== selector)
150
+ fail('npm resolved a different exact version');
151
+ if (!validIntegrity(integrity))
152
+ fail('npm metadata lacks a valid SHA-512 integrity value');
153
+ const expectedTarball = `${REGISTRY}@deepseek-ai/dsh/-/dsh-${version}.tgz`;
154
+ if (tarball !== expectedTarball)
155
+ fail('npm metadata points outside the official DSH tarball');
156
+ return { version, integrity, tarball };
157
+ }
158
+ async function sha256File(path) {
159
+ const hash = createHash('sha256');
160
+ for await (const chunk of createReadStream(path))
161
+ hash.update(chunk);
162
+ return hash.digest('hex');
163
+ }
164
+ async function inventory(runtimeRoot) {
165
+ const entries = [];
166
+ async function walk(directory) {
167
+ for (const name of (await readdir(directory)).sort()) {
168
+ const path = join(directory, name);
169
+ const rel = relative(runtimeRoot, path).split(sep).join('/');
170
+ if (rel === 'receipt.json')
171
+ continue;
172
+ if (entries.length >= MAX_ENTRIES)
173
+ fail('runtime inventory exceeds limit');
174
+ const info = await lstat(path);
175
+ const mode = info.mode & 0o777;
176
+ if (info.isDirectory()) {
177
+ entries.push({ path: rel, type: 'directory', mode });
178
+ await walk(path);
179
+ }
180
+ else if (info.isFile()) {
181
+ entries.push({ path: rel, type: 'file', mode, sha256: await sha256File(path) });
182
+ }
183
+ else if (info.isSymbolicLink()) {
184
+ const link = await readlink(path);
185
+ if (isAbsolute(link) || !inside(runtimeRoot, resolve(dirname(path), link)))
186
+ fail(`symlink escapes runtime: ${rel}`);
187
+ const destination = await realpath(path);
188
+ if (!inside(runtimeRoot, destination))
189
+ fail(`symlink escapes runtime: ${rel}`);
190
+ entries.push({ path: rel, type: 'link', mode, target: link });
191
+ }
192
+ else
193
+ fail(`unsupported runtime file type: ${rel}`);
194
+ }
195
+ }
196
+ await walk(runtimeRoot);
197
+ return entries;
198
+ }
199
+ async function parseJsonFile(path, maxBytes = MAX_RECEIPT) {
200
+ const file = await lstat(path);
201
+ if (!file.isFile() || file.isSymbolicLink() || file.size > maxBytes)
202
+ fail(`invalid ${basename(path)}`);
203
+ let parsed;
204
+ try {
205
+ parsed = JSON.parse(await readFile(path, 'utf8'));
206
+ }
207
+ catch {
208
+ fail(`invalid JSON in ${basename(path)}`);
209
+ }
210
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
211
+ fail(`invalid ${basename(path)}`);
212
+ return parsed;
213
+ }
214
+ async function verifyPackage(runtimeRoot, expected, signal) {
215
+ const lock = await parseJsonFile(join(runtimeRoot, 'package-lock.json'));
216
+ const packages = lock.packages;
217
+ if (packages === null || typeof packages !== 'object' || Array.isArray(packages))
218
+ fail('package-lock lacks packages');
219
+ const lockedRoot = packages[''];
220
+ if (lockedRoot === null || typeof lockedRoot !== 'object' || Array.isArray(lockedRoot))
221
+ fail('package-lock lacks root package');
222
+ const lockedDependencies = lockedRoot.dependencies;
223
+ if (lockedDependencies === null || typeof lockedDependencies !== 'object' || Array.isArray(lockedDependencies)
224
+ || lockedDependencies[PACKAGE] !== expected.version)
225
+ fail('package-lock root does not pin exact DSH version');
226
+ const resolved = packages['node_modules/@deepseek-ai/dsh'];
227
+ if (resolved === null || typeof resolved !== 'object' || Array.isArray(resolved))
228
+ fail('package-lock lacks DSH');
229
+ const entry = resolved;
230
+ if (entry.version !== expected.version || entry.integrity !== expected.integrity || entry.resolved !== expected.tarball)
231
+ fail('package-lock DSH resolution differs from npm metadata');
232
+ const rootManifest = await parseJsonFile(join(runtimeRoot, 'package.json'));
233
+ const dependencies = rootManifest.dependencies;
234
+ if (dependencies === null || typeof dependencies !== 'object' || Array.isArray(dependencies)
235
+ || dependencies[PACKAGE] !== expected.version)
236
+ fail('runtime manifest does not pin exact DSH version');
237
+ const packageRoot = join(runtimeRoot, 'node_modules', '@deepseek-ai', 'dsh');
238
+ const manifest = await parseJsonFile(join(packageRoot, 'package.json'));
239
+ if (manifest.name !== PACKAGE || manifest.version !== expected.version)
240
+ fail('installed DSH package manifest differs from selected version');
241
+ const bin = manifest.bin;
242
+ const binFile = typeof bin === 'object' && bin !== null && !Array.isArray(bin) ? bin.dsh : undefined;
243
+ if (typeof binFile !== 'string' || binFile.length === 0 || isAbsolute(binFile) || !inside(packageRoot, resolve(packageRoot, binFile)))
244
+ fail('installed DSH package has invalid bin metadata');
245
+ const dshPath = join(runtimeRoot, 'node_modules', '.bin', 'dsh');
246
+ const binInfo = await lstat(dshPath);
247
+ if (!binInfo.isSymbolicLink() && !binInfo.isFile())
248
+ fail('installed DSH bin is missing');
249
+ if (await realpath(dshPath) !== await realpath(resolve(packageRoot, binFile)))
250
+ fail('installed DSH bin does not match its manifest');
251
+ if ((await stat(dshPath)).mode & 0o111) {
252
+ const version = await runBounded(dshPath, ['--version'], { cwd: runtimeRoot, signal, timeoutMs: 20_000, maxOutput: 4096 });
253
+ if (version.exitCode !== 0 || version.stdout.trim() !== expected.version)
254
+ fail('installed DSH --version differs from selected version');
255
+ }
256
+ else
257
+ fail('installed DSH bin is not executable');
258
+ return dshPath;
259
+ }
260
+ async function checkReceipt(root, version, signal) {
261
+ const runtimeRoot = join(root, version);
262
+ const info = await lstat(runtimeRoot);
263
+ if (!info.isDirectory() || info.isSymbolicLink())
264
+ fail(`runtime ${version} is not a real directory`);
265
+ if (process.getuid !== undefined && info.uid !== process.getuid())
266
+ fail(`runtime ${version} is not owned by the current user`);
267
+ if ((info.mode & 0o077) !== 0)
268
+ fail(`runtime ${version} is not private`);
269
+ const receiptPath = join(runtimeRoot, 'receipt.json');
270
+ const receipt = await parseJsonFile(receiptPath);
271
+ if (receipt.schemaVersion !== 1 || receipt.version !== version || typeof receipt.integrity !== 'string'
272
+ || typeof receipt.tarball !== 'string' || !Array.isArray(receipt.entries))
273
+ fail('runtime receipt is invalid');
274
+ const expected = { version, integrity: receipt.integrity, tarball: receipt.tarball };
275
+ if (!validIntegrity(expected.integrity)
276
+ || expected.tarball !== `${REGISTRY}@deepseek-ai/dsh/-/dsh-${version}.tgz`)
277
+ fail('runtime receipt metadata is invalid');
278
+ const actual = await inventory(runtimeRoot);
279
+ if (JSON.stringify(actual) !== JSON.stringify(receipt.entries))
280
+ fail(`runtime ${version} file inventory changed`);
281
+ const dshPath = await verifyPackage(runtimeRoot, expected, signal);
282
+ const receiptDigest = sha256(JSON.stringify(receipt));
283
+ return { version, root: runtimeRoot, dshPath, binDirectory: dirname(dshPath), integrity: expected.integrity, receiptDigest };
284
+ }
285
+ async function acquireLock(root, signal) {
286
+ const lock = join(root, '.prepare.lock');
287
+ const token = randomUUID();
288
+ const deadline = Date.now() + LOCK_TIMEOUT;
289
+ for (;;) {
290
+ if (signal.aborted)
291
+ fail('operation cancelled while waiting for runtime lock');
292
+ let created = false;
293
+ try {
294
+ await mkdir(lock, { mode: 0o700 });
295
+ created = true;
296
+ await writeFile(join(lock, 'owner.json'), JSON.stringify({ pid: process.pid, token }), { flag: 'wx', mode: 0o600 });
297
+ return async () => {
298
+ try {
299
+ const owner = JSON.parse(await readFile(join(lock, 'owner.json'), 'utf8'));
300
+ if (owner.token === token)
301
+ await rm(lock, { recursive: true, force: true });
302
+ }
303
+ catch { /* another owner or damaged lock: never remove it */ }
304
+ };
305
+ }
306
+ catch (error) {
307
+ if (created) {
308
+ await rm(lock, { recursive: true, force: true });
309
+ throw error;
310
+ }
311
+ if (error.code !== 'EEXIST')
312
+ throw error;
313
+ const age = Date.now() - (await stat(lock)).mtimeMs;
314
+ if (age > 60_000) {
315
+ try {
316
+ const owner = JSON.parse(await readFile(join(lock, 'owner.json'), 'utf8'));
317
+ if (typeof owner.pid === 'number' && Number.isInteger(owner.pid) && owner.pid > 0) {
318
+ try {
319
+ process.kill(owner.pid, 0);
320
+ }
321
+ catch (err) {
322
+ if (err.code === 'ESRCH') {
323
+ const stale = join(root, `.stale-${randomUUID()}`);
324
+ await rename(lock, stale);
325
+ await rm(stale, { recursive: true, force: true });
326
+ continue;
327
+ }
328
+ }
329
+ }
330
+ }
331
+ catch (error) {
332
+ if (error.code === 'ENOENT') {
333
+ const stale = join(root, `.stale-${randomUUID()}`);
334
+ try {
335
+ await rename(lock, stale);
336
+ await rm(stale, { recursive: true, force: true });
337
+ continue;
338
+ }
339
+ catch { /* another process may have acquired the lock */ }
340
+ }
341
+ }
342
+ }
343
+ if (Date.now() >= deadline)
344
+ fail('timed out waiting for private runtime lock');
345
+ await new Promise((done, reject) => {
346
+ const timer = setTimeout(() => { signal.removeEventListener('abort', abort); done(); }, 100);
347
+ const abort = () => { clearTimeout(timer); reject(new Error('Managed DSH runtime: operation cancelled')); };
348
+ signal.addEventListener('abort', abort, { once: true });
349
+ });
350
+ }
351
+ }
352
+ }
353
+ /** Read and independently verify a previously prepared exact version without contacting npm. */
354
+ export async function readManagedHostRuntime(input) {
355
+ const root = await canonicalRoot(input.root, false);
356
+ const version = validReceiptVersion(input.version);
357
+ return await checkReceipt(root, version, input.signal ?? new AbortController().signal);
358
+ }
359
+ /** Resolve once from the official npm registry, then install exact DSH into an owner-private version directory. */
360
+ export async function prepareManagedHostRuntime(input, ports = {}) {
361
+ const root = await canonicalRoot(input.root, true);
362
+ const signal = input.signal ?? new AbortController().signal;
363
+ const release = await acquireLock(root, signal);
364
+ try {
365
+ const metadata = await resolveMetadata(input.selector ?? 'latest', root, signal, ports);
366
+ const runtimeRoot = join(root, metadata.version);
367
+ try {
368
+ await lstat(runtimeRoot);
369
+ const existing = await checkReceipt(root, metadata.version, signal);
370
+ if (existing.integrity !== metadata.integrity)
371
+ fail('cached runtime integrity differs from current registry metadata');
372
+ return existing;
373
+ }
374
+ catch (error) {
375
+ if (error.code !== 'ENOENT')
376
+ throw error;
377
+ }
378
+ const stage = join(root, `.stage-${metadata.version}-${randomUUID()}`);
379
+ await mkdir(stage, { mode: 0o700 });
380
+ try {
381
+ await writeFile(join(stage, 'package.json'), JSON.stringify({ name: 'dsh-enhanced-managed-host', private: true, version: '0.0.0', dependencies: { [PACKAGE]: metadata.version } }) + '\n', { flag: 'wx', mode: 0o600 });
382
+ await npmCommand(['install', '--prefix', stage, '--ignore-scripts', '--no-audit', '--no-fund', '--package-lock=true', '--save-exact', `--registry=${REGISTRY}`], stage, signal, ports);
383
+ // Check links and package metadata before executing any installed code.
384
+ const entries = await inventory(stage);
385
+ await verifyPackage(stage, metadata, signal);
386
+ const receipt = { schemaVersion: 1, ...metadata, entries };
387
+ await writeFile(join(stage, 'receipt.json'), JSON.stringify(receipt) + '\n', { flag: 'wx', mode: 0o600 });
388
+ await chmod(stage, 0o700);
389
+ await rename(stage, runtimeRoot);
390
+ return await checkReceipt(root, metadata.version, signal);
391
+ }
392
+ finally {
393
+ await rm(stage, { recursive: true, force: true });
394
+ }
395
+ }
396
+ finally {
397
+ await release();
398
+ }
399
+ }
400
+ //# sourceMappingURL=host-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-runtime.js","sourceRoot":"","sources":["../src/host-runtime.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAgC,MAAM,YAAY,CAAA;AAGnE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAA0B,aAAa,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,EAKL,wBAAwB,EAIzB,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACpF,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,WAAW,GACZ,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAgFtC,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,OAAO,CAAA;IACrB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,iCAAiC;IACjC,UAAU,EAAE,OAAO,CAAA;IACnB,wCAAwC;IACxC,GAAG,EAAE,OAAO,CAAA;IACZ,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,qCAAqC;IACrC,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AA+BD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,UAAU,CAwFnG;AAsJD,0DAA0D;AAC1D,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,OAAO,QAAQ,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,UAAU,CAAA;IAC3B,UAAU,CAAC,EAAE,OAAO,aAAa,CAAA;IACjC,WAAW,CAAC,EAAE,OAAO,mBAAmB,CAAA;IACxC,kBAAkB,CAAC,EAAE,OAAO,wBAAwB,CAAA;CACrD;AAED,wBAAsB,IAAI,CACxB,IAAI,GAAE,SAAS,MAAM,EAA0B,EAC/C,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC,MAAM,CAAC,CAwLjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAgC,MAAM,YAAY,CAAA;AAGnE,OAAO,EAA0B,UAAU,EAAE,MAAM,cAAc,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAA0B,aAAa,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,EAKL,wBAAwB,EAIzB,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACpF,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,WAAW,GACZ,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAkFtC,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,OAAO,CAAA;IACrB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,iCAAiC;IACjC,UAAU,EAAE,OAAO,CAAA;IACnB,wCAAwC;IACxC,GAAG,EAAE,OAAO,CAAA;IACZ,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,qCAAqC;IACrC,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AA+BD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,UAAU,CAwFnG;AAsJD,0DAA0D;AAC1D,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,OAAO,QAAQ,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,UAAU,CAAA;IAC3B,UAAU,CAAC,EAAE,OAAO,aAAa,CAAA;IACjC,WAAW,CAAC,EAAE,OAAO,mBAAmB,CAAA;IACxC,kBAAkB,CAAC,EAAE,OAAO,wBAAwB,CAAA;CACrD;AAED,wBAAsB,IAAI,CACxB,IAAI,GAAE,SAAS,MAAM,EAA0B,EAC/C,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC,MAAM,CAAC,CA+LjB"}
package/lib/index.js CHANGED
@@ -3,7 +3,7 @@ import { createInterface } from 'node:readline/promises';
3
3
  import { runPurge, PurgeError } from "./purge.js";
4
4
  import { collectStatus, formatStatus, formatFindings, runDoctor } from "./diagnose.js";
5
5
  import { resolveDshHome } from "./paths.js";
6
- import { runInstall } from "./install.js";
6
+ import { hasPendingHostRecovery, runInstall } from "./install.js";
7
7
  import { findRunningProfiles } from "./run.js";
8
8
  import { formatSelfUpdateReport, runSelfUpdate } from "./update.js";
9
9
  import { formatWebUrlResult, resolveManagedWebUrl } from "./weburl.js";
@@ -53,8 +53,10 @@ install / reinstall:
53
53
  update:
54
54
  不带参数 只升级全局 dsh-rsi 自身(npm install --global @dsh-enhanced/dsh-rsi-cli@latest);
55
55
  若当前仍由旧包 @dsh-enhanced/rsi-cli 安装,会在新包可用后自动卸载旧包。
56
- --all 自身升级成功后,再把插件集合交给官方安装器 --operation upgrade 原地升级
57
- (保留 patch、凭据、Session、Goal 等状态;不同于 reinstall 的先 purge 再装)
56
+ --all 自身升级成功后,先升级插件集合,再将已绑定的私有 Host 更新到最新兼容版本;
57
+ 保留 patch、凭据、Session、Goal 等状态
58
+ --dsh-version <v> --all 时指定兼容的私有 Host 版本;默认 latest(现有未绑定 Home 保持原 Host)
59
+ Host 事务覆盖同一 DSH_HOME 下全部已登记受管 unit,即使 --profile 只升级一个 cohort
58
60
  --version <v|tag> 指定 dsh-rsi 目标版本或 dist-tag(默认 latest)
59
61
  --local <dir> --all 时走 local 形态,用该 checkout 的安装器升级
60
62
  其它参数 --all 时原样透传给安装器;通常无需再写 --scenario 或内部确认参数
@@ -491,6 +493,26 @@ export async function main(argv = process.argv.slice(2), env = process.env, deps
491
493
  process.stdout.write(`${formatSelfUpdateReport(report, args.dryRun)}\n`);
492
494
  if (!args.all)
493
495
  return 0;
496
+ const passthrough = [...args.passthrough];
497
+ if (!passthrough.includes('--operation'))
498
+ passthrough.push('--operation', 'upgrade');
499
+ if (!passthrough.includes('--confirm-dsh-home-stopped')) {
500
+ passthrough.push('--confirm-dsh-home-stopped');
501
+ }
502
+ const releaseVersion = report.installedVersion
503
+ ?? report.resolvedVersion
504
+ ?? (/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(report.selector) ? report.selector : undefined);
505
+ if (releaseVersion === undefined) {
506
+ throw new PurgeError('无法把 dsh-rsi 目标 selector 解析为精确发布版本;为避免 CLI 与安装器版本错配,未开始插件升级。');
507
+ }
508
+ if (!args.dryRun && await hasPendingHostRecovery(args.dshHome)) {
509
+ const recovery = await install({
510
+ ...buildInstallOptions(args), releaseRef: `v${releaseVersion}`, passthrough,
511
+ recoveryOnly: true,
512
+ });
513
+ if (recovery !== 0)
514
+ return recovery;
515
+ }
494
516
  const profiles = args.profile === undefined
495
517
  ? await resolveTargetProfiles(args.dshHome)
496
518
  : [args.profile];
@@ -512,18 +534,6 @@ export async function main(argv = process.argv.slice(2), env = process.env, deps
512
534
  process.stdout.write(managed.pids.length > 0
513
535
  ? '\n插件集合升级:已确认除受管服务外没有其它 Host;生命周期事务将安全停服、升级并恢复。\n'
514
536
  : '\n插件集合升级:已确认目标 profile 无运行中 Host,正在继承现有部署场景并原地升级。\n');
515
- const passthrough = [...args.passthrough];
516
- if (!passthrough.includes('--operation'))
517
- passthrough.push('--operation', 'upgrade');
518
- if (!passthrough.includes('--confirm-dsh-home-stopped')) {
519
- passthrough.push('--confirm-dsh-home-stopped');
520
- }
521
- const releaseVersion = report.installedVersion
522
- ?? report.resolvedVersion
523
- ?? (/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(report.selector) ? report.selector : undefined);
524
- if (releaseVersion === undefined) {
525
- throw new PurgeError('无法把 dsh-rsi 目标 selector 解析为精确发布版本;为避免 CLI 与安装器版本错配,未开始插件升级。');
526
- }
527
537
  return await install({
528
538
  ...buildInstallOptions(args),
529
539
  releaseRef: `v${releaseVersion}`,