claw-subagent-service 0.0.13 → 0.0.15
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/cli.js +4 -8
- package/package.json +1 -1
- package/scripts/install-silent.js +4 -8
- package/scripts/post-install.js +29 -13
- package/service/modules/service-manager.js +4 -13
- package/version.json +2 -2
package/cli.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* node cli.js --status # 查看服务状态
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
const { spawn, exec
|
|
15
|
+
const { spawn, exec } = require('child_process');
|
|
16
16
|
const path = require('path');
|
|
17
17
|
const fs = require('fs');
|
|
18
18
|
const os = require('os');
|
|
@@ -58,13 +58,9 @@ function installService() {
|
|
|
58
58
|
|
|
59
59
|
// 先停止并删除旧服务(避免文件锁)
|
|
60
60
|
exec(`net stop "${SERVICE_NAME}" 2>nul & sc delete "${SERVICE_NAME}" 2>nul`, () => {
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
'binPath=', binPath,
|
|
65
|
-
'start=', 'auto',
|
|
66
|
-
'displayname=', 'OpenClaw Guard'
|
|
67
|
-
], { windowsHide: true }, (err2) => {
|
|
61
|
+
// sc.exe 是 cmd 时代的工具,必须用 exec(走 cmd 解析)才能正确传递 binPath
|
|
62
|
+
const createCmd = `sc create "${SERVICE_NAME}" binPath= ${binPath} start= auto displayname= "OpenClaw Guard"`;
|
|
63
|
+
exec(createCmd, { windowsHide: true }, (err2) => {
|
|
68
64
|
if (err2) return console.error(`[CLI] 服务安装失败: ${err2.message}`);
|
|
69
65
|
console.log('[CLI] 服务安装成功');
|
|
70
66
|
exec(`net start "${SERVICE_NAME}"`, (err3) => {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const { exec
|
|
2
|
+
const { exec } = require('child_process');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
|
|
5
5
|
const ROOT = process.argv[2] || process.env.SILENT_SERVICE_DIR || path.join(__dirname, '..');
|
|
@@ -48,13 +48,9 @@ if (platform === 'win32') {
|
|
|
48
48
|
exec(`net stop "${SERVICE_NAME}" 2>nul & sc delete "${SERVICE_NAME}" 2>nul`, () => {
|
|
49
49
|
const binPath = `"${process.execPath}" "${DAEMON_PATH}"`;
|
|
50
50
|
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
'binPath=', binPath,
|
|
55
|
-
'start=', 'auto',
|
|
56
|
-
'displayname=', 'Node.js 静默后台服务'
|
|
57
|
-
], { windowsHide: true }, (err) => {
|
|
51
|
+
// sc.exe 是 cmd 时代的工具,必须用 exec(走 cmd 解析)才能正确传递 binPath
|
|
52
|
+
const createCmd = `sc create "${SERVICE_NAME}" binPath= ${binPath} start= auto displayname= "Node.js 静默后台服务"`;
|
|
53
|
+
exec(createCmd, { windowsHide: true }, (err) => {
|
|
58
54
|
if (err) {
|
|
59
55
|
log(`创建服务失败: ${err.message}`);
|
|
60
56
|
return finish(1, `创建服务失败: ${err.message}`);
|
package/scripts/post-install.js
CHANGED
|
@@ -2,18 +2,32 @@
|
|
|
2
2
|
* npm postinstall 钩子
|
|
3
3
|
* 全局安装完成后自动注册并启动 Windows 服务
|
|
4
4
|
*/
|
|
5
|
-
const { exec,
|
|
5
|
+
const { exec, execSync } = require('child_process');
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const fs = require('fs');
|
|
8
7
|
|
|
9
8
|
const SERVICE_NAME = 'claw-subagent-service';
|
|
10
9
|
const DAEMON_PATH = path.join(__dirname, '..', 'service', 'daemon.js');
|
|
11
10
|
|
|
12
11
|
function isGlobalInstall() {
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
// 方法1: npm 全局安装时会设置此环境变量
|
|
13
|
+
if (process.env.npm_config_global === 'true') {
|
|
14
|
+
console.log('[postinstall] 通过 npm_config_global 检测到全局安装');
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 方法2: 检查包路径是否在全局 node_modules 下(使用 npm root -g,支持 nvm)
|
|
19
|
+
try {
|
|
20
|
+
const globalRoot = execSync('npm root -g', { encoding: 'utf8', timeout: 5000 }).trim();
|
|
21
|
+
const pkgPath = path.join(__dirname, '..');
|
|
22
|
+
const normalizedPkg = path.normalize(pkgPath).toLowerCase();
|
|
23
|
+
const normalizedGlobal = path.normalize(globalRoot).toLowerCase();
|
|
24
|
+
const isGlobal = normalizedPkg.startsWith(normalizedGlobal);
|
|
25
|
+
console.log(`[postinstall] 全局安装检测: pkgPath=${normalizedPkg}, globalRoot=${normalizedGlobal}, result=${isGlobal}`);
|
|
26
|
+
return isGlobal;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.log(`[postinstall] 全局安装检测失败(${e.message}),默认按全局安装处理`);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
17
31
|
}
|
|
18
32
|
|
|
19
33
|
function isWindowsAdmin() {
|
|
@@ -46,13 +60,9 @@ function installAndStartService() {
|
|
|
46
60
|
try { execSync(`net stop "${SERVICE_NAME}" 2>nul`, { stdio: 'ignore', timeout: 10000 }); } catch (e) {}
|
|
47
61
|
try { execSync(`sc delete "${SERVICE_NAME}" 2>nul`, { stdio: 'ignore', timeout: 10000 }); } catch (e) {}
|
|
48
62
|
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
'binPath=', binPath,
|
|
53
|
-
'start=', 'auto',
|
|
54
|
-
'displayname=', 'OpenClaw Guard'
|
|
55
|
-
], { windowsHide: true }, (err) => {
|
|
63
|
+
// sc.exe 是 cmd 时代的工具,必须用 exec(走 cmd 解析)才能正确传递 binPath
|
|
64
|
+
const createCmd = `sc create "${SERVICE_NAME}" binPath= ${binPath} start= auto displayname= "OpenClaw Guard"`;
|
|
65
|
+
exec(createCmd, { windowsHide: true }, (err) => {
|
|
56
66
|
if (err) {
|
|
57
67
|
console.error(`[postinstall] 注册服务失败: ${err.message}`);
|
|
58
68
|
return;
|
|
@@ -76,6 +86,12 @@ function installAndStartService() {
|
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
// 主逻辑
|
|
89
|
+
console.log('[postinstall] 脚本开始执行...');
|
|
90
|
+
console.log(`[postinstall] __dirname=${__dirname}`);
|
|
91
|
+
console.log(`[postinstall] cwd=${process.cwd()}`);
|
|
92
|
+
console.log(`[postinstall] npm_config_global=${process.env.npm_config_global}`);
|
|
93
|
+
console.log(`[postinstall] npm_config_prefix=${process.env.npm_config_prefix}`);
|
|
94
|
+
|
|
79
95
|
if (isGlobalInstall()) {
|
|
80
96
|
console.log('[postinstall] 检测到全局安装,准备自动注册服务...');
|
|
81
97
|
installAndStartService();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 系统服务管理器
|
|
3
3
|
* 支持 Windows/Linux/macOS 系统服务注册
|
|
4
4
|
*/
|
|
5
|
-
const { spawn, exec
|
|
5
|
+
const { spawn, exec } = require('child_process');
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
8
|
|
|
@@ -163,18 +163,9 @@ class ServiceManager {
|
|
|
163
163
|
try { await this.execCommand(`net stop "${this.serviceName}" 2>nul`); } catch (e) {}
|
|
164
164
|
try { await this.execCommand(`sc delete "${this.serviceName}" 2>nul`); } catch (e) {}
|
|
165
165
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
'create', this.serviceName,
|
|
170
|
-
'binPath=', binPath,
|
|
171
|
-
'start=', 'auto',
|
|
172
|
-
'displayname=', this.serviceDesc
|
|
173
|
-
], { windowsHide: true }, (err) => {
|
|
174
|
-
if (err) reject(err);
|
|
175
|
-
else resolve();
|
|
176
|
-
});
|
|
177
|
-
});
|
|
166
|
+
// sc.exe 是 cmd 时代的工具,必须用 exec(走 cmd 解析)才能正确传递 binPath
|
|
167
|
+
const createCmd = `sc create "${this.serviceName}" binPath= ${binPath} start= auto displayname= "${this.serviceDesc}"`;
|
|
168
|
+
await this.execCommand(createCmd);
|
|
178
169
|
this.log?.info('[ServiceManager] Windows 服务注册成功');
|
|
179
170
|
|
|
180
171
|
// 启动服务
|
package/version.json
CHANGED