@sokeai/cli 1.0.13 → 1.0.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sokeai/cli",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "授客AI官方CLI工具 - 支持AI Agent Skills",
5
5
  "bin": {
6
6
  "soke-cli": "scripts/run.js"
@@ -262,52 +262,33 @@ function ensureSymlink(targetPath, sourcePath) {
262
262
  }
263
263
 
264
264
  async function maybeAssistGuiPath() {
265
- if (!isLikelyInteractiveInstall()) return;
266
-
267
- const shimPath = detectSokeCliShimPath();
268
- if (!shimPath) return;
269
-
270
- const targets = getPreferredLinkTargetPaths();
271
- if (targets.length === 0) return;
272
-
273
- let selectedTarget = null;
274
- for (const t of targets) {
275
- const dir = path.dirname(t);
276
- if (fs.existsSync(dir)) {
277
- selectedTarget = t;
278
- break;
279
- }
280
- }
281
- if (!selectedTarget) selectedTarget = targets[0];
282
-
283
- const dir = path.dirname(selectedTarget);
284
- let dirWritable = false;
285
- try {
286
- fs.accessSync(dir, fs.constants.W_OK);
287
- dirWritable = true;
288
- } catch (_) {}
289
-
290
- const question = dirWritable
291
- ? `检测到你可能在 sokeclaw(GUI)里遇到 “command not found: soke-cli”。是否创建链接 ${selectedTarget} 指向 ${shimPath} 以便 GUI 可直接找到?(y/N) `
292
- : `检测到你可能在 sokeclaw(GUI)里遇到 “command not found: soke-cli”。是否输出一条需要 sudo 的命令来创建链接 ${selectedTarget} 指向 ${shimPath}?(y/N) `;
293
-
294
- const ok = await promptYesNo(question);
295
- if (!ok) return;
296
-
297
- if (dirWritable) {
298
- const res = ensureSymlink(selectedTarget, shimPath);
299
- if (res.ok) {
300
- console.log(`已配置:${selectedTarget} -> ${shimPath}`);
301
- } else if (res.reason === 'exists_non_symlink') {
302
- console.log(`跳过:${selectedTarget} 已存在且不是软链接。`);
303
- } else {
304
- console.log(`创建软链接失败:${res.reason}`);
265
+ const platform = os.platform();
266
+ const binDir = path.join(__dirname, '..', 'bin');
267
+ const binaryName = platform === 'win32' ? 'soke-cli.exe' : 'soke-cli';
268
+ const binaryPath = path.join(binDir, binaryName);
269
+
270
+ if (!fs.existsSync(binaryPath)) return Promise.resolve();
271
+
272
+ // 我们不再弹窗询问,而是直接以静默模式尝试执行 setup-gui-env
273
+ // 这会尝试创建软链,如果没权限,它会默默失败(不会报错打断安装)
274
+ // 用户如果后面遇到 command not found,仍可以手动执行 soke-cli setup-gui-env
275
+ return new Promise((resolve) => {
276
+ try {
277
+ const runJsPath = path.join(__dirname, 'run.js');
278
+ const { spawn } = require('child_process');
279
+ const child = spawn(process.execPath, [runJsPath, 'setup-gui-env', '--silent'], {
280
+ stdio: 'ignore', // 静默执行,不污染 npm install 输出
281
+ detached: true
282
+ });
283
+ child.on('error', () => resolve());
284
+ child.on('exit', () => resolve());
285
+
286
+ // 避免卡住
287
+ setTimeout(() => resolve(), 3000);
288
+ } catch (e) {
289
+ resolve();
305
290
  }
306
- return;
307
- }
308
-
309
- console.log(`请执行以下命令完成配置(需要 sudo):`);
310
- console.log(`sudo ln -sf "${shimPath}" "${selectedTarget}"`);
291
+ });
311
292
  }
312
293
 
313
294
  // 平台映射
package/scripts/run.js CHANGED
@@ -13,18 +13,7 @@ if (process.argv[2] === 'setup-gui-env') {
13
13
  const cliDir = path.dirname(process.argv[1]);
14
14
 
15
15
  let targetPath = '';
16
- if (process.platform === 'darwin') {
17
- // 提取现有的系统 PATH
18
- const sysPath = execSync('sysctl -n getenv PATH 2>/dev/null || echo ""', { encoding: 'utf8' }).trim();
19
- const currentPath = process.env.PATH || '';
20
-
21
- // 合并并去重 PATH
22
- const pathSet = new Set([nodeDir, cliDir, ...currentPath.split(':'), ...sysPath.split(':')].filter(Boolean));
23
- targetPath = Array.from(pathSet).join(':');
24
-
25
- console.log(`注入的 PATH: ${targetPath.substring(0, 100)}...`);
26
- // launchctl setenv 在新版 macOS 中如果不在 login context 下可能提示 Not privileged,
27
- // 我们改用软链到 GUI 默认 PATH /usr/local/bin 的方式来解决(如果不可写则提示 sudo)
16
+ if (process.platform === 'darwin' || process.platform === 'linux') {
28
17
  const binSource = path.join(nodeDir, 'soke-cli');
29
18
  const binTarget = '/usr/local/bin/soke-cli';
30
19
 
@@ -41,14 +30,18 @@ if (process.argv[2] === 'setup-gui-env') {
41
30
  console.log(`请手动在终端执行以下命令(可能需要输入密码):`);
42
31
  console.log(`\n sudo ln -sf "${binSource}" "${binTarget}"\n`);
43
32
 
44
- // 如果这里没法创建,sokeclaw 可能还是找不到,提示一下
45
- console.log(`执行上述命令后,再重新打开 SokeClaw 即可。`);
46
- process.exit(0);
33
+ if (process.argv[3] !== '--silent') {
34
+ console.log(`执行上述命令后,再重新打开客户端即可。`);
35
+ }
47
36
  }
48
37
  } else {
49
38
  console.log(`⚠️ 未找到源文件: ${binSource}`);
50
39
  }
51
40
 
41
+ if (process.argv[3] === '--silent') {
42
+ process.exit(0);
43
+ }
44
+
52
45
  console.log('尝试重启 SokeClaw / WorkClaw...');
53
46
  try { execSync('killall SokeClaw 2>/dev/null'); } catch(e) {}
54
47
  try { execSync('killall WorkClaw 2>/dev/null'); } catch(e) {}
@@ -57,24 +50,40 @@ if (process.argv[2] === 'setup-gui-env') {
57
50
  // 等待进程退出
58
51
  setTimeout(() => {
59
52
  let launched = false;
60
- if (fs.existsSync('/Applications/SokeClaw.app')) {
61
- execSync('open "/Applications/SokeClaw.app"');
62
- launched = true;
63
- } else if (fs.existsSync('/Applications/WorkClaw.app')) {
64
- execSync('open "/Applications/WorkClaw.app"');
65
- launched = true;
53
+ if (process.platform === 'darwin') {
54
+ if (fs.existsSync('/Applications/SokeClaw.app')) {
55
+ execSync('open "/Applications/SokeClaw.app"');
56
+ launched = true;
57
+ } else if (fs.existsSync('/Applications/WorkClaw.app')) {
58
+ execSync('open "/Applications/WorkClaw.app"');
59
+ launched = true;
60
+ }
66
61
  }
67
62
 
68
63
  if (launched) {
69
64
  console.log('\n✅ 修复完成!SokeClaw 已重启。现在你应该可以在里面使用 /skill soke-exam 了。');
70
65
  } else {
71
- console.log('\n✅ 环境变量已注入,但未找到 SokeClaw 应用。请手动从“启动台(Launchpad)”或“访达(Finder)”重新打开它。');
66
+ console.log('\n✅ 环境变量已注入,但未自动重启应用。请手动从“启动台(Launchpad)”或“访达(Finder)”重新打开它。');
72
67
  }
73
68
  process.exit(0);
74
69
  }, 1500);
75
70
  return; // 异步等待中
71
+ } else if (process.platform === 'win32') {
72
+ console.log('检测到当前为 Windows 系统。');
73
+
74
+ if (process.argv[3] === '--silent') {
75
+ process.exit(0);
76
+ }
77
+
78
+ console.log('正在尝试重启 SokeClaw / WorkClaw...');
79
+ try { execSync('taskkill /F /IM SokeClaw.exe 2>nul'); } catch(e) {}
80
+ try { execSync('taskkill /F /IM WorkClaw.exe 2>nul'); } catch(e) {}
81
+ try { execSync('taskkill /F /IM Electron.exe 2>nul'); } catch(e) {}
82
+
83
+ console.log('\n✅ Windows 环境下的全局包通常已在 PATH 中。客户端已被关闭,请手动重新打开它即可生效。');
84
+ process.exit(0);
76
85
  } else {
77
- console.log('\n⚠️ 目前 setup-gui-env 仅支持 macOS 平台。Windows/Linux 用户请手动将 Node/npm bin 目录加入系统环境变量。');
86
+ console.log('\n⚠️ 目前 setup-gui-env 主要支持 macOS/Linux/Windows。');
78
87
  process.exit(0);
79
88
  }
80
89
  } catch (error) {