shizai-agent-mcp 0.5.4 → 0.7.29

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
@@ -1,37 +1,39 @@
1
1
  # shizai-agent-mcp
2
2
 
3
- 实在 Agent 本地 MCP 的轻量 npm/npx 安装器。它只安装和注册 Shizai MCP,浏览器识别与控制复用实在 Agent 客户端自带的 Chrome 扩展和 DeepCapture。
3
+ 实在 Agent 本地 MCP 的轻量 npm/npx 安装器。默认安装 MCP、准备独立浏览器扩展文件并注册本地连接程序。
4
4
 
5
5
  ## 使用
6
6
 
7
7
  ```powershell
8
- npx -y shizai-agent-mcp@latest install
9
- npx -y shizai-agent-mcp@latest register codex
8
+ npx -y shizai-agent-mcp@latest install
9
+ npx -y shizai-agent-mcp@latest status
10
10
  ```
11
11
 
12
12
  也可以注册 Cursor 或 Claude Desktop:
13
13
 
14
14
  ```powershell
15
- npx -y shizai-agent-mcp@latest register cursor
16
- npx -y shizai-agent-mcp@latest register claude
15
+ npx -y shizai-agent-mcp@latest register cursor
16
+ npx -y shizai-agent-mcp@latest register claude
17
17
  ```
18
18
 
19
19
  常用命令:
20
20
 
21
21
  ```powershell
22
- npx -y shizai-agent-mcp@latest status
23
- npx -y shizai-agent-mcp@latest path
24
- npx -y shizai-agent-mcp@latest uninstall
22
+ npx -y shizai-agent-mcp@latest status
23
+ npx -y shizai-agent-mcp@latest path
24
+ npx -y shizai-agent-mcp@latest uninstall
25
25
  ```
26
26
 
27
- 当前 npm launcher 版本为 `0.5.4`,默认下载最新的 `v0.7.27` Windows x64 资产:
28
- `shizai-agent-v0.7.27-windows-x64.zip`。npm 包不附带浏览器自动化依赖,也不要求用户安装额外扩展。
27
+ 从 `0.7.29` 起 npm 安装器与 MCP 采用同一版本号,默认下载对应的 Windows x64 发布包。
28
+ 安装前校验实际构建产生的工具清单、扩展文件和所有载荷哈希,缺件或版本不符直接失败。
29
+ 首次使用仍须在 `chrome://extensions` 或 `edge://extensions` 中加载返回的扩展目录;
30
+ 浏览器是否真正连接以 `shizai_browser_status` 为准。可用 `--without-browser-extension` 跳过本地连接程序注册。
29
31
 
30
32
  `install` 覆盖文件后会自动注册 Codex MCP;需要跳过配置写入时使用
31
33
  `install --skip-register`,之后可单独运行 `register codex`。
32
34
 
33
35
  发布 Release 时必须同时上传同名 `.sha256` 文件。安装器先校验、解压到同盘暂存目录,
34
- 再原子替换现有版本;失败会恢复旧安装。测试企业内网镜像时可设置
36
+ 再替换现有版本;注册成功后才清理旧安装。升级保留扩展连接密钥和端口。测试企业内网镜像时可设置
35
37
  `SHIZAI_AGENT_RELEASE_BASE_URL`,测试其他版本可设置 `SHIZAI_AGENT_VERSION`。
36
38
  仅临时调试未签名镜像时可显式设置 `SHIZAI_AGENT_ALLOW_UNVERIFIED=1`。
37
39
 
@@ -9,7 +9,7 @@ const { execFileSync, spawn } = require('node:child_process');
9
9
 
10
10
  const SERVER = 'shizai-agent';
11
11
  const REPO = process.env.SHIZAI_AGENT_REPO || 'yimoxzy/shizai-agent';
12
- const DEFAULT_VERSION = process.env.SHIZAI_AGENT_VERSION || '0.7.27';
12
+ const DEFAULT_VERSION = process.env.SHIZAI_AGENT_VERSION || require('../package.json').version;
13
13
  const installRoot = process.env.SHIZAI_AGENT_HOME || path.join(
14
14
  process.env.LOCALAPPDATA || path.join(os.homedir(), '.local'), 'Programs', 'ShizaiAgent'
15
15
  );
@@ -17,7 +17,7 @@ const installRoot = process.env.SHIZAI_AGENT_HOME || path.join(
17
17
  function fail(message) { console.error(`shizai-agent-mcp: ${message}`); process.exitCode = 1; }
18
18
  function json(value) { console.log(JSON.stringify(value, null, 2)); }
19
19
  function help() {
20
- console.log(`Shizai Agent MCP installer\n\nUsage:\n shizai-agent-mcp install [--version VERSION]\n shizai-agent-mcp register <codex|cursor|claude>\n shizai-agent-mcp status\n shizai-agent-mcp path\n shizai-agent-mcp uninstall\n\nEnvironment:\n SHIZAI_AGENT_VERSION Release version (default: ${DEFAULT_VERSION})\n SHIZAI_AGENT_HOME Installation directory\n SHIZAI_AGENT_REPO GitHub repository owner/name\n SHIZAI_AGENT_RELEASE_BASE_URL Override release asset base URL\n`);
20
+ console.log(`Shizai Agent MCP installer\n\nUsage:\n shizai-agent-mcp install [--version VERSION] [--without-browser-extension]\n shizai-agent-mcp register <codex|cursor|claude|browser>\n shizai-agent-mcp status\n shizai-agent-mcp path\n shizai-agent-mcp uninstall\n\nBrowser extension files and native host registration are prepared by default.\nLoad the extension in Chrome/Edge once; --without-browser-extension skips host setup.\n\nEnvironment:\n SHIZAI_AGENT_VERSION Release version (default: ${DEFAULT_VERSION})\n SHIZAI_AGENT_HOME Installation directory\n SHIZAI_AGENT_REPO GitHub repository owner/name\n SHIZAI_AGENT_RELEASE_BASE_URL Override release asset base URL\n`);
21
21
  }
22
22
  function binaryPath() { return path.join(installRoot, 'shizai-agent-mcp.exe'); }
23
23
  function validateInstallRoot() {
@@ -26,11 +26,21 @@ function validateInstallRoot() {
26
26
  if (resolved === parsed.root || resolved === path.resolve(os.homedir())) {
27
27
  throw new Error(`拒绝使用过宽的安装目录:${resolved}`);
28
28
  }
29
+ if (fs.existsSync(resolved) && fs.readdirSync(resolved).length && !fs.existsSync(path.join(resolved, 'shizai-agent-mcp.exe'))) {
30
+ throw new Error('拒绝替换非 Shizai Agent 安装目录');
31
+ }
29
32
  return resolved;
30
33
  }
31
34
  function psQuote(value) { return `'${String(value).replaceAll("'", "''")}'`; }
35
+ function powerShellOptions() {
36
+ // A host running PowerShell 7 can pass its module search path through Node.
37
+ // Windows PowerShell must resolve its own built-in modules first.
38
+ const builtin = path.join(process.env.SystemRoot || 'C:\\Windows', 'System32', 'WindowsPowerShell', 'v1.0', 'Modules');
39
+ return { encoding: 'utf8', windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'],
40
+ env: { ...process.env, PSModulePath: [builtin, process.env.PSModulePath].filter(Boolean).join(path.delimiter) } };
41
+ }
32
42
  function runPowerShell(script, args = []) {
33
- return execFileSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', script, ...args], { encoding: 'utf8' });
43
+ return execFileSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', script, ...args], powerShellOptions());
34
44
  }
35
45
  function sleepSync(milliseconds) {
36
46
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
@@ -53,7 +63,8 @@ function stopInstalledProcesses(destination) {
53
63
  if (process.platform !== 'win32') return [];
54
64
  const executables = [
55
65
  path.join(destination, 'shizai-agent-mcp.exe'),
56
- path.join(destination, 'shizai-agent.exe')
66
+ path.join(destination, 'shizai-agent.exe'),
67
+ path.join(destination, 'shizai-agent-browser-host.exe')
57
68
  ];
58
69
  const targetList = executables.map(psQuote).join(', ');
59
70
  const script = String.raw`
@@ -112,22 +123,22 @@ function verifySha256(file, expected) {
112
123
  const actual = crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex').toLowerCase();
113
124
  if (actual !== expected.toLowerCase()) throw new Error(`SHA256 校验失败:期望 ${expected},实际 ${actual}`);
114
125
  }
115
- function download(url, destination, options = {}) {
116
- const progress = options.progress !== false;
117
- const curl = process.env.SHIZAI_AGENT_CURL || 'curl.exe';
118
- const args = ['--fail', '--location', '--silent', '--show-error'];
119
- if (progress) args.push('--progress-bar');
120
- args.push('--output', destination, url);
121
- try {
122
- execFileSync(curl, args, { stdio: ['ignore', 'ignore', 'inherit'] });
123
- if (progress) process.stderr.write('\n');
124
- return;
125
- } catch (error) {
126
- if (error?.code !== 'ENOENT') throw error;
127
- }
128
- const script = `Invoke-WebRequest -UseBasicParsing -Uri ${psQuote(url)} -OutFile ${psQuote(destination)} -ProgressAction SilentlyContinue`;
129
- runPowerShell(script);
130
- }
126
+ function download(url, destination, options = {}) {
127
+ const progress = options.progress !== false;
128
+ const curl = process.env.SHIZAI_AGENT_CURL || 'curl.exe';
129
+ const args = ['--fail', '--location', '--silent', '--show-error'];
130
+ if (progress) args.push('--progress-bar');
131
+ args.push('--output', destination, url);
132
+ try {
133
+ execFileSync(curl, args, { stdio: ['ignore', 'ignore', 'inherit'] });
134
+ if (progress) process.stderr.write('\n');
135
+ return;
136
+ } catch (error) {
137
+ if (error?.code !== 'ENOENT') throw error;
138
+ }
139
+ const script = `$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -UseBasicParsing -Uri ${psQuote(url)} -OutFile ${psQuote(destination)}`;
140
+ runPowerShell(script);
141
+ }
131
142
  function install(version, options = {}) {
132
143
  const destination = validateInstallRoot();
133
144
  const asset = assetName(version);
@@ -140,11 +151,12 @@ function install(version, options = {}) {
140
151
  const stage = path.join(parent, `.shizai-agent-stage-${nonce}`);
141
152
  const backup = path.join(parent, `.shizai-agent-backup-${nonce}`);
142
153
  let verified = false;
154
+ let committed = false;
143
155
  const stoppedProcesses = new Set();
144
156
  try {
145
- download(url, archive, { progress: true });
146
- try {
147
- download(`${url}.sha256`, checksum, { progress: false });
157
+ download(url, archive, { progress: true });
158
+ try {
159
+ download(`${url}.sha256`, checksum, { progress: false });
148
160
  const text = fs.readFileSync(checksum, 'utf8');
149
161
  const expected = (text.match(/[a-f0-9]{64}/i) || [])[0];
150
162
  if (!expected) throw new Error('校验文件中没有 SHA-256');
@@ -166,10 +178,17 @@ function install(version, options = {}) {
166
178
  if (!nested) throw new Error('发布包中未找到 shizai-agent-mcp.exe');
167
179
  source = nested;
168
180
  }
169
- fs.writeFileSync(path.join(source, 'version.json'), JSON.stringify({ version, asset, installedAt: new Date().toISOString() }, null, 2));
170
- cleanupInstallArtifacts(parent, [stage, backup]);
181
+ const verification = verifyPackage(source, version);
182
+ fs.writeFileSync(path.join(source, 'version.json'), JSON.stringify({
183
+ version, asset, installedAt: new Date().toISOString(),
184
+ manifest_sha256: verification.manifest_sha256, tools: verification.tools
185
+ }, null, 2));
186
+ const oldBridge = path.join(destination, 'browser-bridge.json');
187
+ if (fs.existsSync(oldBridge)) fs.copyFileSync(oldBridge, path.join(source, 'browser-bridge.json'));
171
188
  for (const processId of stopInstalledProcesses(destination)) stoppedProcesses.add(processId);
172
189
  let previousMoved = false;
190
+ const result = { installed: true, version, directory: destination, command: binaryPath(), verified,
191
+ tools: verification.tools, browser_extension_version: verification.extension_version };
173
192
  try {
174
193
  if (fs.existsSync(destination)) {
175
194
  fs.renameSync(destination, backup);
@@ -177,51 +196,69 @@ function install(version, options = {}) {
177
196
  for (const processId of stopInstalledProcesses(destination)) stoppedProcesses.add(processId);
178
197
  }
179
198
  fs.renameSync(source, destination);
199
+ if (!options.skipRegister) result.registration = registerCodex(true);
200
+ if (options.withBrowserExtension !== false) result.browser_extension = registerBrowser(true);
201
+ committed = true;
180
202
  } catch (error) {
181
- if (!fs.existsSync(destination) && previousMoved && fs.existsSync(backup)) {
203
+ if (previousMoved && fs.existsSync(backup)) {
204
+ for (const processId of stopInstalledProcesses(destination)) stoppedProcesses.add(processId);
205
+ // Keep the old installation recoverable until registration also succeeds.
206
+ const failedInstall = path.join(parent, `.shizai-agent-failed-${nonce}`);
207
+ if (fs.existsSync(destination)) fs.renameSync(destination, failedInstall);
182
208
  fs.renameSync(backup, destination);
209
+ removeDirectoryWithRetries(failedInstall);
183
210
  }
184
211
  throw error;
185
212
  }
186
- if (previousMoved) {
187
- try {
188
- removeDirectoryWithRetries(backup);
189
- } catch (error) {
190
- for (const processId of stopInstalledProcesses(destination)) stoppedProcesses.add(processId);
191
- try {
192
- removeDirectoryWithRetries(backup);
193
- } catch (retryError) {
194
- const failedInstall = path.join(temp, 'failed-install');
195
- fs.renameSync(destination, failedInstall);
196
- fs.renameSync(backup, destination);
197
- removeDirectoryWithRetries(failedInstall);
198
- throw new Error(`旧版本清理失败,已恢复原安装:${retryError.message}`);
199
- }
200
- }
213
+ result.stopped_processes = [...stoppedProcesses].sort((left, right) => left - right);
214
+ console.log(`安装成功:Shizai Agent MCP v${version}`);
215
+ if (result.registration?.registered) console.log('Codex MCP 已注册');
216
+ if (result.browser_extension?.registered) {
217
+ console.log(`浏览器扩展文件已准备:${result.browser_extension.extension_path}`);
218
+ console.log('首次使用:在 chrome://extensions 或 edge://extensions 加载该目录;连接状态以 shizai_browser_status 为准。');
201
219
  }
202
- cleanupInstallArtifacts(parent, [stage, backup]);
203
- const result = { installed: true, version, directory: destination, command: binaryPath(), verified, stopped_processes: [...stoppedProcesses].sort((left, right) => left - right) };
204
- if (!options.skipRegister) result.registration = registerCodex(true);
205
- console.log(`安装成功:Shizai Agent MCP v${version}`);
206
- if (result.registration?.registered) console.log('Codex MCP 已注册');
207
- return result;
220
+ return result;
208
221
  } finally {
209
222
  removeDirectoryWithRetries(temp);
210
223
  removeDirectoryWithRetries(stage);
211
- if (fs.existsSync(backup) && fs.existsSync(destination)) removeDirectoryWithRetries(backup);
224
+ if (committed && fs.existsSync(backup)) removeDirectoryWithRetries(backup);
212
225
  }
213
226
  }
227
+ function verifyPackage(root, version) {
228
+ const script = path.join(root, 'scripts', 'verify-package.ps1');
229
+ if (!fs.existsSync(script)) throw new Error('发布包缺少完整性校验器,请使用新版发布包');
230
+ const output = execFileSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass',
231
+ '-File', script, '-PackageRoot', root, '-Version', version],
232
+ powerShellOptions()).replace(/^\uFEFF/, '').trim();
233
+ return JSON.parse(output);
234
+ }
235
+ function installationStatus() {
236
+ const metadataFile = path.join(installRoot, 'version.json');
237
+ const metadata = fs.existsSync(metadataFile) ? JSON.parse(fs.readFileSync(metadataFile, 'utf8').replace(/^\uFEFF/, '')) : {};
238
+ let verification;
239
+ try { verification = verifyPackage(installRoot, metadata.version || DEFAULT_VERSION); }
240
+ catch (_) { verification = { verified: false, reason: '安装文件缺失、损坏或来自未校验的旧发布包,请重新安装最新版' }; }
241
+ return { installed: fs.existsSync(binaryPath()), version: metadata.version || null, installer_version: require('../package.json').version,
242
+ directory: installRoot, command: binaryPath(), verification,
243
+ browser_extension_files_present: fs.existsSync(path.join(installRoot, 'browser-extension', 'manifest.json')),
244
+ native_host_present: fs.existsSync(path.join(installRoot, 'shizai-agent-browser-host.exe')),
245
+ browser_config_present: fs.existsSync(path.join(installRoot, 'browser-bridge.json')),
246
+ browser_extension_loaded: null, browser_extension_path: path.join(installRoot, 'browser-extension') };
247
+ }
214
248
  function replaceTomlSection(content, section, replacement) {
215
- const header = `[${section}]`;
216
249
  const lines = String(content || '').split(/\r?\n/);
217
250
  const kept = [];
218
251
  let skipping = false;
219
252
  for (const line of lines) {
220
- if (line.trim() === header) {
221
- skipping = true;
222
- continue;
253
+ const match = line.trim().match(/^\[([^\]]+)\]$/);
254
+ if (match) {
255
+ const table = match[1];
256
+ if (table === section || table.startsWith(`${section}.`)) {
257
+ skipping = true;
258
+ continue;
259
+ }
260
+ skipping = false;
223
261
  }
224
- if (skipping && /^\s*\[.*\]\s*$/.test(line)) skipping = false;
225
262
  if (!skipping) kept.push(line);
226
263
  }
227
264
  const next = kept.join('\n').trimEnd();
@@ -233,10 +270,27 @@ function registerCodex(silent = false) {
233
270
  fs.mkdirSync(path.dirname(config), { recursive: true });
234
271
  const old = fs.existsSync(config) ? fs.readFileSync(config, 'utf8') : '';
235
272
  if (old) fs.copyFileSync(config, `${config}.shizai-agent.bak`);
236
- const section = `[mcp_servers.${SERVER}]\ncommand = ${tomlString(binaryPath())}\nargs = []\nstartup_timeout_sec = 30\ntool_timeout_sec = 120`;
273
+ // Keep this local stdio server on Codex's direct tool path. Some custom
274
+ // Responses providers do not support Codex's deferred tool-search payload.
275
+ const section = `[mcp_servers.${SERVER}]\ncommand = ${tomlString(binaryPath())}\nargs = []\nenabled = true\nstartup_timeout_sec = 30\ntool_timeout_sec = 120\nomit_tools_from = [\"deferred\"]\n\n[mcp_servers.${SERVER}.env]\nSHIZAI_MCP_TOOL_PROFILE = \"rpa-authoring\"`;
237
276
  const next = replaceTomlSection(old, `mcp_servers.${SERVER}`, section);
238
277
  fs.writeFileSync(config, next, 'utf8');
239
- const result = { registered: true, client: 'codex', config, command: binaryPath() };
278
+ const persisted = fs.readFileSync(config, 'utf8');
279
+ const verified = persisted.includes(`[mcp_servers.${SERVER}]`) &&
280
+ persisted.includes(`[mcp_servers.${SERVER}.env]`) &&
281
+ persisted.includes(`command = ${tomlString(binaryPath())}`) &&
282
+ persisted.includes('enabled = true') &&
283
+ persisted.includes('SHIZAI_MCP_TOOL_PROFILE = "rpa-authoring"');
284
+ if (!verified) throw new Error('Codex MCP 配置写入后校验失败');
285
+ const result = {
286
+ registered: true,
287
+ verified,
288
+ client: 'codex',
289
+ config,
290
+ command: binaryPath(),
291
+ tool_profile: 'rpa-authoring',
292
+ restart_required: true
293
+ };
240
294
  if (!silent) json(result);
241
295
  return result;
242
296
  }
@@ -254,9 +308,37 @@ function registerJsonClient(client) {
254
308
  fs.writeFileSync(file, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
255
309
  json({ registered: true, client, config: file, command: binaryPath() });
256
310
  }
311
+ function registerBrowser(silent = false) {
312
+ const script = path.join(installRoot, 'scripts', 'register-browser.ps1');
313
+ if (!fs.existsSync(script)) throw new Error('发布包中缺少 register-browser.ps1');
314
+ const output = execFileSync('powershell.exe', [
315
+ '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass',
316
+ '-File', script, '-InstallDir', installRoot
317
+ ], powerShellOptions()).replace(/^\uFEFF/, '').trim();
318
+ const result = JSON.parse(output);
319
+ if (!silent) json(result);
320
+ return result;
321
+ }
322
+ function unregisterBrowser() {
323
+ const script = path.join(installRoot, 'scripts', 'unregister-browser.ps1');
324
+ if (!fs.existsSync(script)) return null;
325
+ const output = execFileSync('powershell.exe', [
326
+ '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass',
327
+ '-File', script, '-InstallDir', installRoot
328
+ ], powerShellOptions()).replace(/^\uFEFF/, '').trim();
329
+ return output ? JSON.parse(output) : null;
330
+ }
257
331
  function launch() {
258
- if (!fs.existsSync(binaryPath())) install(DEFAULT_VERSION);
332
+ // stdout is the MCP protocol, so setup/progress must never be printed here.
333
+ // Upgrades also must not stop other running MCP sessions during a new launch.
334
+ const metadataFile = path.join(installRoot, 'version.json');
335
+ const metadata = fs.existsSync(metadataFile) ? JSON.parse(fs.readFileSync(metadataFile, 'utf8').replace(/^\uFEFF/, '')) : {};
336
+ if (!fs.existsSync(binaryPath()) || metadata.version !== DEFAULT_VERSION) {
337
+ throw new Error(`请先运行 npx -y shizai-agent-mcp@${DEFAULT_VERSION} install,再启动 MCP`);
338
+ }
339
+ verifyPackage(installRoot, DEFAULT_VERSION);
259
340
  const child = spawn(binaryPath(), process.argv.slice(2), { stdio: 'inherit', windowsHide: true });
341
+ child.on('error', error => fail(error.message));
260
342
  child.on('exit', code => { process.exitCode = code ?? 0; });
261
343
  }
262
344
  function main() {
@@ -268,22 +350,27 @@ function main() {
268
350
  const index = args.indexOf('--version');
269
351
  const version = index >= 0 ? args[index + 1] : args.find(value => !value.startsWith('-'));
270
352
  if (index >= 0 && !version) throw new Error('--version 后需要版本号');
271
- return install(version || DEFAULT_VERSION, { skipRegister: args.includes('--skip-register') });
353
+ return install(version || DEFAULT_VERSION, {
354
+ skipRegister: args.includes('--skip-register'),
355
+ withBrowserExtension: !args.includes('--without-browser-extension')
356
+ });
272
357
  }
273
358
  if (command === 'register') {
274
359
  if (!fs.existsSync(binaryPath())) throw new Error('尚未安装,请先运行 install');
275
360
  if (target === 'codex') return registerCodex();
276
361
  if (target === 'cursor' || target === 'claude') return registerJsonClient(target);
277
- throw new Error('请指定 codex、cursor 或 claude');
362
+ if (target === 'browser') return registerBrowser();
363
+ throw new Error('请指定 codex、cursor、claude 或 browser');
278
364
  }
279
- if (command === 'status') return json({ installed: fs.existsSync(binaryPath()), directory: installRoot, command: binaryPath(), versionFile: path.join(installRoot, 'version.json') });
365
+ if (command === 'status') return json(installationStatus());
280
366
  if (command === 'path') return console.log(binaryPath());
281
367
  if (command === 'uninstall') {
282
368
  const destination = validateInstallRoot();
283
369
  const stoppedProcesses = stopInstalledProcesses(destination);
370
+ const browser = unregisterBrowser();
284
371
  removeDirectoryWithRetries(destination);
285
372
  if (fs.existsSync(path.dirname(destination))) cleanupInstallArtifacts(path.dirname(destination));
286
- return json({ uninstalled: true, directory: destination, stopped_processes: stoppedProcesses });
373
+ return json({ uninstalled: true, directory: destination, stopped_processes: stoppedProcesses, browser });
287
374
  }
288
375
  throw new Error(`未知命令:${command}`);
289
376
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shizai-agent-mcp",
3
- "version": "0.5.4",
3
+ "version": "0.7.29",
4
4
  "description": "Installer and launcher for the Shizai Agent local MCP server",
5
5
  "bin": {
6
6
  "shizai-agent-mcp": "bin/shizai-agent-mcp.js"