@okclaw-build/cli 1.0.0-beta.3 → 1.0.0-beta.30
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/dist/commands/check.js +22 -6
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/edit.d.ts +2 -7
- package/dist/commands/edit.js +28 -15
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/feed.d.ts +0 -9
- package/dist/commands/feed.js +80 -103
- package/dist/commands/feed.js.map +1 -1
- package/dist/commands/install.js +57 -9
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/service.js +65 -12
- package/dist/commands/service.js.map +1 -1
- package/dist/commands/show.d.ts +13 -0
- package/dist/commands/show.js +49 -0
- package/dist/commands/show.js.map +1 -0
- package/dist/commands/skill.d.ts +1 -0
- package/dist/commands/skill.js +114 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +46 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/index.js +88 -5
- package/dist/index.js.map +1 -1
- package/dist/installers/base.d.ts +1 -0
- package/dist/installers/channel.d.ts +16 -1
- package/dist/installers/channel.js +121 -8
- package/dist/installers/channel.js.map +1 -1
- package/dist/installers/openclaw.d.ts +1 -0
- package/dist/installers/openclaw.js +72 -10
- package/dist/installers/openclaw.js.map +1 -1
- package/dist/installers/openviking-purge.d.ts +52 -0
- package/dist/installers/openviking-purge.js +380 -0
- package/dist/installers/openviking-purge.js.map +1 -0
- package/dist/installers/openviking.js +1 -2
- package/dist/installers/openviking.js.map +1 -1
- package/dist/installers/skill.d.ts +1 -0
- package/dist/installers/skill.js +11 -1
- package/dist/installers/skill.js.map +1 -1
- package/dist/output/mode.d.ts +11 -0
- package/dist/output/mode.js +27 -0
- package/dist/output/mode.js.map +1 -0
- package/dist/output/ndjson.d.ts +57 -0
- package/dist/output/ndjson.js +136 -0
- package/dist/output/ndjson.js.map +1 -0
- package/dist/utils/constants.d.ts +0 -2
- package/dist/utils/constants.js +1 -4
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/deps.d.ts +0 -5
- package/dist/utils/deps.js +1 -88
- package/dist/utils/deps.js.map +1 -1
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.js +31 -4
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mirror.js +7 -0
- package/dist/utils/mirror.js.map +1 -1
- package/dist/utils/openclaw-config-cli.d.ts +19 -0
- package/dist/utils/openclaw-config-cli.js +81 -0
- package/dist/utils/openclaw-config-cli.js.map +1 -0
- package/dist/utils/shell.d.ts +12 -2
- package/dist/utils/shell.js +66 -3
- package/dist/utils/shell.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { appendFileSync } from 'node:fs';
|
|
2
|
+
import { getNdjsonPath, getOpId, isNdjson } from './mode.js';
|
|
3
|
+
const defaultWriter = (line) => {
|
|
4
|
+
const path = getNdjsonPath();
|
|
5
|
+
if (path) {
|
|
6
|
+
appendFileSync(path, line);
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
process.stdout.write(line);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* 单 op 的事件发射器。在 text 模式下所有方法都是 no-op;ndjson 模式才写出。
|
|
14
|
+
*
|
|
15
|
+
* 约定:
|
|
16
|
+
* - seq 单调递增,同一 emitter 实例内唯一
|
|
17
|
+
* - end() 只能发一次,重复调用忽略
|
|
18
|
+
* - 非正常退出(exception/signal)由 registerExitHandlers 兜底补 end
|
|
19
|
+
*/
|
|
20
|
+
export class NdjsonEmitter {
|
|
21
|
+
seq = 0;
|
|
22
|
+
op;
|
|
23
|
+
writer;
|
|
24
|
+
ended = false;
|
|
25
|
+
constructor(op, writer = defaultWriter) {
|
|
26
|
+
this.op = op;
|
|
27
|
+
this.writer = writer;
|
|
28
|
+
}
|
|
29
|
+
start(msg = '', fields) {
|
|
30
|
+
this.emit('start', 'info', { msg, fields });
|
|
31
|
+
}
|
|
32
|
+
stepStart(step, msg, fields) {
|
|
33
|
+
this.emit('step_start', 'info', { step, msg, fields });
|
|
34
|
+
}
|
|
35
|
+
progress(step, progress, msg, fields) {
|
|
36
|
+
const clamped = Number.isFinite(progress) ? Math.max(0, Math.min(1, progress)) : undefined;
|
|
37
|
+
this.emit('progress', 'info', { step, progress: clamped, msg, fields });
|
|
38
|
+
}
|
|
39
|
+
stepDone(step, msg, fields) {
|
|
40
|
+
this.emit('step_done', 'info', { step, msg, fields });
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 通用日志事件。走独立 phase="log"(bug#7 修:之前借用 phase="progress" 会
|
|
44
|
+
* 污染"取 max(progress) 作为当前进度"的聚合逻辑)。用 level 区分严重度。
|
|
45
|
+
*/
|
|
46
|
+
log(level, msg, fields) {
|
|
47
|
+
this.emit('log', level, { msg, fields });
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 终态事件;必发。ok=false 时 fields 里加 errorCode(可选)。
|
|
51
|
+
* end 事件的 fields 可承载 op-specific 返回值(如 FILE_READ 的 content)。
|
|
52
|
+
*/
|
|
53
|
+
end(ok, exitCode, code, fields) {
|
|
54
|
+
if (this.ended)
|
|
55
|
+
return;
|
|
56
|
+
this.ended = true;
|
|
57
|
+
const mergedFields = { ok, exitCode, ...(fields ?? {}) };
|
|
58
|
+
this.emit('end', ok ? 'info' : 'error', {
|
|
59
|
+
msg: ok ? 'success' : 'failed',
|
|
60
|
+
fields: mergedFields,
|
|
61
|
+
code,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
hasEnded() {
|
|
65
|
+
return this.ended;
|
|
66
|
+
}
|
|
67
|
+
emit(phase, level, partial) {
|
|
68
|
+
if (!isNdjson())
|
|
69
|
+
return;
|
|
70
|
+
const opId = getOpId();
|
|
71
|
+
const userFields = { ...(partial.fields ?? {}) };
|
|
72
|
+
if (opId !== undefined && userFields.opId === undefined) {
|
|
73
|
+
userFields.opId = opId;
|
|
74
|
+
}
|
|
75
|
+
const event = {
|
|
76
|
+
ts: new Date().toISOString(),
|
|
77
|
+
seq: ++this.seq,
|
|
78
|
+
op: this.op,
|
|
79
|
+
phase,
|
|
80
|
+
level,
|
|
81
|
+
};
|
|
82
|
+
if (partial.step !== undefined)
|
|
83
|
+
event.step = partial.step;
|
|
84
|
+
if (partial.progress !== undefined)
|
|
85
|
+
event.progress = partial.progress;
|
|
86
|
+
if (partial.msg !== undefined && partial.msg !== '')
|
|
87
|
+
event.msg = partial.msg;
|
|
88
|
+
if (Object.keys(userFields).length > 0)
|
|
89
|
+
event.fields = userFields;
|
|
90
|
+
if (partial.code !== undefined)
|
|
91
|
+
event.code = partial.code;
|
|
92
|
+
this.writer(JSON.stringify(event) + '\n');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// bug#4 修:顶层 main().catch 里也要能拿到活 emitter 发 end 兜底。
|
|
96
|
+
// registerExitHandlers 时把 emitter 挂到 module 级,exposé getActiveEmitter 给 index.ts。
|
|
97
|
+
let activeEmitter = null;
|
|
98
|
+
export function getActiveEmitter() {
|
|
99
|
+
return activeEmitter;
|
|
100
|
+
}
|
|
101
|
+
export function clearActiveEmitter() {
|
|
102
|
+
activeEmitter = null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 注册进程兜底,确保 ndjson 模式下 end 事件必发(plan P1 风险:忘 flush → os-api 卡死)。
|
|
106
|
+
* 只在 ndjson 模式生效。
|
|
107
|
+
*/
|
|
108
|
+
export function registerExitHandlers(emitter) {
|
|
109
|
+
if (!isNdjson())
|
|
110
|
+
return;
|
|
111
|
+
activeEmitter = emitter;
|
|
112
|
+
const finalize = (exitCode, code) => {
|
|
113
|
+
if (!emitter.hasEnded()) {
|
|
114
|
+
emitter.end(false, exitCode, code);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
process.on('uncaughtException', (err) => {
|
|
118
|
+
finalize(1, 'E_UNCAUGHT');
|
|
119
|
+
process.stderr.write(String(err?.stack ?? err) + '\n');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
});
|
|
122
|
+
process.on('unhandledRejection', (reason) => {
|
|
123
|
+
finalize(1, 'E_UNHANDLED_REJECTION');
|
|
124
|
+
process.stderr.write(String(reason) + '\n');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
});
|
|
127
|
+
process.on('SIGTERM', () => {
|
|
128
|
+
finalize(143, 'E_SIGTERM');
|
|
129
|
+
process.exit(143);
|
|
130
|
+
});
|
|
131
|
+
process.on('SIGINT', () => {
|
|
132
|
+
finalize(130, 'E_SIGINT');
|
|
133
|
+
process.exit(130);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=ndjson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ndjson.js","sourceRoot":"","sources":["../../src/output/ndjson.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,6 @@ export declare const OPENVIKING_PORT = 1933;
|
|
|
11
11
|
export declare const NODE_MIN_MAJOR = 22;
|
|
12
12
|
export declare const NODE_MIN_MINOR = 16;
|
|
13
13
|
export declare const NODE_INSTALL_VERSION = "22.16.0";
|
|
14
|
-
export declare const PYTHON_MIN_MAJOR = 3;
|
|
15
|
-
export declare const PYTHON_MIN_MINOR = 11;
|
|
16
14
|
export declare const NPM_REGISTRY = "https://registry.npmmirror.com";
|
|
17
15
|
export declare const PIP_INDEX_URL = "https://pypi.tuna.tsinghua.edu.cn/simple";
|
|
18
16
|
export declare const PIP_TRUSTED_HOST = "pypi.tuna.tsinghua.edu.cn";
|
package/dist/utils/constants.js
CHANGED
|
@@ -9,13 +9,10 @@ export const OPENVIKING_HOME = '/root/.openviking';
|
|
|
9
9
|
export const OPENVIKING_CONF = `${OPENVIKING_HOME}/ov.conf`;
|
|
10
10
|
export const OPENVIKING_ENV = `${OPENCLAW_HOME}/openviking.env`;
|
|
11
11
|
export const OPENVIKING_PORT = 1933;
|
|
12
|
-
// Version requirements — slightly above official
|
|
13
|
-
// Official: Node >= 22.14, Python >= 3.10
|
|
12
|
+
// Version requirements — slightly above official minimum (Node >= 22.14)
|
|
14
13
|
export const NODE_MIN_MAJOR = 22;
|
|
15
14
|
export const NODE_MIN_MINOR = 16;
|
|
16
15
|
export const NODE_INSTALL_VERSION = '22.16.0';
|
|
17
|
-
export const PYTHON_MIN_MAJOR = 3;
|
|
18
|
-
export const PYTHON_MIN_MINOR = 11;
|
|
19
16
|
// China mirrors
|
|
20
17
|
export const NPM_REGISTRY = 'https://registry.npmmirror.com';
|
|
21
18
|
export const PIP_INDEX_URL = 'https://pypi.tuna.tsinghua.edu.cn/simple';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,WAAW,SAAS,CAAC;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,WAAW,SAAS,CAAC;AACzD,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,WAAW,MAAM,CAAC;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,aAAa,YAAY,CAAC;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,eAAe,UAAU,CAAC;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,aAAa,iBAAiB,CAAC;AAChE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,WAAW,SAAS,CAAC;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,WAAW,SAAS,CAAC;AACzD,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,WAAW,MAAM,CAAC;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,aAAa,YAAY,CAAC;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,eAAe,UAAU,CAAC;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,aAAa,iBAAiB,CAAC;AAChE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAE9C,gBAAgB;AAChB,MAAM,CAAC,MAAM,YAAY,GAAG,gCAAgC,CAAC;AAC7D,MAAM,CAAC,MAAM,aAAa,GAAG,0CAA0C,CAAC;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAC5D,MAAM,CAAC,MAAM,WAAW,GAAG,oCAAoC,CAAC;AAEhE,wEAAwE;AACxE,MAAM,CAAC,MAAM,WAAW,GAAG,6BAA6B,CAAC;AACzD,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAEhE,gDAAgD;AAChD,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;AAC1F,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,mBAAmB,EAAE,WAAW,EAAE,oBAAoB;IACtD,mBAAmB,EAAE,eAAe,EAAE,iBAAiB;IACvD,8BAA8B,EAAE,sBAAsB;IACtD,eAAe;CAChB,CAAC;AAEF,8BAA8B;AAC9B,MAAM,CAAC,MAAM,oBAAoB,GAA2B;IAC1D,QAAQ,EAAE,iBAAiB;IAC3B,MAAM,EAAE,iCAAiC;IACzC,iDAAiD;IACjD,mEAAmE;CACpE,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC"}
|
package/dist/utils/deps.d.ts
CHANGED
|
@@ -3,11 +3,6 @@
|
|
|
3
3
|
* Installs nvm first if not present, then installs Node.js through nvm.
|
|
4
4
|
*/
|
|
5
5
|
export declare function ensureNodeVersion(): Promise<void>;
|
|
6
|
-
/**
|
|
7
|
-
* Ensure Python >= PYTHON_MIN_MAJOR.PYTHON_MIN_MINOR is installed.
|
|
8
|
-
* Auto-installs via system package manager if missing or too old.
|
|
9
|
-
*/
|
|
10
|
-
export declare function ensurePython(): Promise<void>;
|
|
11
6
|
/**
|
|
12
7
|
* Ensure a command exists on PATH.
|
|
13
8
|
*/
|
package/dist/utils/deps.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { shell, shellCapture, commandExists } from './shell.js';
|
|
2
2
|
import { info, warn } from './logger.js';
|
|
3
|
-
import { NODE_MIN_MAJOR, NODE_MIN_MINOR, NODE_INSTALL_VERSION, NODE_MIRROR,
|
|
3
|
+
import { NODE_MIN_MAJOR, NODE_MIN_MINOR, NODE_INSTALL_VERSION, NODE_MIRROR, } from './constants.js';
|
|
4
4
|
/**
|
|
5
5
|
* Ensure Node.js >= NODE_MIN_MAJOR.NODE_MIN_MINOR is installed via nvm.
|
|
6
6
|
* Installs nvm first if not present, then installs Node.js through nvm.
|
|
@@ -55,79 +55,6 @@ async function installNodejs() {
|
|
|
55
55
|
throw new Error('Node.js installation failed: node command not found');
|
|
56
56
|
info(`Node.js ${verify.stdout.trim()} installed via nvm ✓`);
|
|
57
57
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Ensure Python >= PYTHON_MIN_MAJOR.PYTHON_MIN_MINOR is installed.
|
|
60
|
-
* Auto-installs via system package manager if missing or too old.
|
|
61
|
-
*/
|
|
62
|
-
export async function ensurePython() {
|
|
63
|
-
const required = `${PYTHON_MIN_MAJOR}.${PYTHON_MIN_MINOR}`;
|
|
64
|
-
const result = await shellCapture('python3 --version');
|
|
65
|
-
if (result.code === 0) {
|
|
66
|
-
const match = result.stdout.match(/(\d+)\.(\d+)\.?(\d+)?/);
|
|
67
|
-
if (match) {
|
|
68
|
-
const version = `${match[1]}.${match[2]}`;
|
|
69
|
-
if (versionGe(version, required)) {
|
|
70
|
-
info(`Python ${result.stdout.trim()} >= ${required} ✓`);
|
|
71
|
-
await ensurePip();
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
warn(`Python ${version} < ${required}, upgrading...`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
info('Python3 not found, installing...');
|
|
79
|
-
}
|
|
80
|
-
await installPython();
|
|
81
|
-
await ensurePip();
|
|
82
|
-
}
|
|
83
|
-
async function installPython() {
|
|
84
|
-
const required = `${PYTHON_MIN_MAJOR}.${PYTHON_MIN_MINOR}`;
|
|
85
|
-
info(`Installing Python >= ${required}...`);
|
|
86
|
-
if (await commandExists('apt-get')) {
|
|
87
|
-
// Try deadsnakes PPA for newer Python on older Ubuntu
|
|
88
|
-
await shell('apt-get update -qq').catch(() => { });
|
|
89
|
-
await shell('apt-get install -y -qq python3 python3-pip python3-venv python3-dev').catch(async () => {
|
|
90
|
-
info('Trying deadsnakes PPA...');
|
|
91
|
-
await shell('apt-get install -y -qq software-properties-common').catch(() => { });
|
|
92
|
-
await shell('add-apt-repository -y ppa:deadsnakes/ppa').catch(() => { });
|
|
93
|
-
await shell('apt-get update -qq');
|
|
94
|
-
await shell('apt-get install -y -qq python3 python3-pip python3-venv python3-dev');
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
else if (await commandExists('dnf')) {
|
|
98
|
-
await shell('dnf install -y python3 python3-pip python3-devel');
|
|
99
|
-
}
|
|
100
|
-
else if (await commandExists('yum')) {
|
|
101
|
-
await shell('yum install -y python3 python3-pip python3-devel');
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
throw new Error(`Cannot install Python: no supported package manager. Install Python >= ${required} manually.`);
|
|
105
|
-
}
|
|
106
|
-
// Verify
|
|
107
|
-
const verify = await shellCapture('python3 --version');
|
|
108
|
-
if (verify.code !== 0)
|
|
109
|
-
throw new Error('Python installation failed');
|
|
110
|
-
const match = verify.stdout.match(/(\d+)\.(\d+)/);
|
|
111
|
-
if (match && !versionGe(`${match[1]}.${match[2]}`, required)) {
|
|
112
|
-
throw new Error(`Installed Python ${match[1]}.${match[2]} still below ${required}. Install manually.`);
|
|
113
|
-
}
|
|
114
|
-
info(`Python ${verify.stdout.trim()} installed ✓`);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Ensure pip is available.
|
|
118
|
-
*/
|
|
119
|
-
async function ensurePip() {
|
|
120
|
-
const result = await shellCapture('python3 -m pip --version');
|
|
121
|
-
if (result.code === 0)
|
|
122
|
-
return;
|
|
123
|
-
info('pip not found, installing...');
|
|
124
|
-
await shell('curl -fsSL https://bootstrap.pypa.io/get-pip.py | python3').catch(async () => {
|
|
125
|
-
await installSystemPackages(['python3-pip']);
|
|
126
|
-
});
|
|
127
|
-
const verify = await shellCapture('python3 -m pip --version');
|
|
128
|
-
if (verify.code !== 0)
|
|
129
|
-
throw new Error('Failed to install pip');
|
|
130
|
-
}
|
|
131
58
|
/**
|
|
132
59
|
* Ensure a command exists on PATH.
|
|
133
60
|
*/
|
|
@@ -147,20 +74,6 @@ export async function checkDiskSpace(requiredMb) {
|
|
|
147
74
|
}
|
|
148
75
|
}
|
|
149
76
|
// ---- helpers ----
|
|
150
|
-
async function installSystemPackages(packages) {
|
|
151
|
-
if (await commandExists('apt-get')) {
|
|
152
|
-
await shell(`apt-get update -qq && apt-get install -y -qq ${packages.join(' ')}`);
|
|
153
|
-
}
|
|
154
|
-
else if (await commandExists('dnf')) {
|
|
155
|
-
await shell(`dnf install -y ${packages.join(' ')}`);
|
|
156
|
-
}
|
|
157
|
-
else if (await commandExists('yum')) {
|
|
158
|
-
await shell(`yum install -y ${packages.join(' ')}`);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
throw new Error(`Cannot install packages: no supported package manager`);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
77
|
function versionGe(a, b) {
|
|
165
78
|
const pa = a.split('.').map(Number);
|
|
166
79
|
const pb = b.split('.').map(Number);
|
package/dist/utils/deps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/utils/deps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/utils/deps.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 人类可读 log。
|
|
3
|
+
*
|
|
4
|
+
* ndjson 模式下:所有业务级 log(info / warn / success / error)静默。
|
|
5
|
+
* - info/warn/success 本就无关紧要,静默避免污染 stdout 结构化流
|
|
6
|
+
* - error 也静默(bug#5 修):业务错误必须通过 emitter.end(false, code, { error: msg }) 承载,
|
|
7
|
+
* 与 design 契约对齐(stderr 仅给真正的崩溃栈,由 registerExitHandlers 的 uncaughtException 打印)
|
|
8
|
+
*
|
|
9
|
+
* 调用方注意:ndjson 模式下调 error(msg) 不会让用户看见消息,务必把 msg 塞进 emitter.end 的 fields。
|
|
10
|
+
*/
|
|
1
11
|
export declare function info(msg: string): void;
|
|
2
12
|
export declare function warn(msg: string): void;
|
|
3
13
|
export declare function error(msg: string): void;
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { isNdjson } from '../output/mode.js';
|
|
2
|
+
/**
|
|
3
|
+
* 人类可读 log。
|
|
4
|
+
*
|
|
5
|
+
* ndjson 模式下:所有业务级 log(info / warn / success / error)静默。
|
|
6
|
+
* - info/warn/success 本就无关紧要,静默避免污染 stdout 结构化流
|
|
7
|
+
* - error 也静默(bug#5 修):业务错误必须通过 emitter.end(false, code, { error: msg }) 承载,
|
|
8
|
+
* 与 design 契约对齐(stderr 仅给真正的崩溃栈,由 registerExitHandlers 的 uncaughtException 打印)
|
|
9
|
+
*
|
|
10
|
+
* 调用方注意:ndjson 模式下调 error(msg) 不会让用户看见消息,务必把 msg 塞进 emitter.end 的 fields。
|
|
11
|
+
*/
|
|
12
|
+
export function info(msg) {
|
|
13
|
+
if (isNdjson())
|
|
14
|
+
return;
|
|
15
|
+
console.log(`[okclaw] ${msg}`);
|
|
16
|
+
}
|
|
17
|
+
export function warn(msg) {
|
|
18
|
+
if (isNdjson())
|
|
19
|
+
return;
|
|
20
|
+
console.log(`[okclaw] WARN: ${msg}`);
|
|
21
|
+
}
|
|
22
|
+
export function error(msg) {
|
|
23
|
+
if (isNdjson())
|
|
24
|
+
return;
|
|
25
|
+
console.error(`[okclaw] ERROR: ${msg}`);
|
|
26
|
+
}
|
|
27
|
+
export function success(msg) {
|
|
28
|
+
if (isNdjson())
|
|
29
|
+
return;
|
|
30
|
+
console.log(`[okclaw] ✓ ${msg}`);
|
|
31
|
+
}
|
|
5
32
|
//# sourceMappingURL=logger.js.map
|
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,IAAI,CAAC,GAAW,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C;;;;;;;;;GASG;AAEH,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,IAAI,QAAQ,EAAE;QAAE,OAAO;IACvB,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,IAAI,QAAQ,EAAE;QAAE,OAAO;IACvB,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,QAAQ,EAAE;QAAE,OAAO;IACvB,OAAO,CAAC,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,QAAQ,EAAE;QAAE,OAAO;IACvB,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/utils/mirror.js
CHANGED
|
@@ -4,6 +4,13 @@ import { NPM_REGISTRY, PIP_INDEX_URL, PIP_TRUSTED_HOST } from './constants.js';
|
|
|
4
4
|
export async function configureMirrors() {
|
|
5
5
|
info('Configuring China mirrors...');
|
|
6
6
|
await shell(`npm config set registry ${NPM_REGISTRY}`).catch(() => { });
|
|
7
|
+
// 部分 npm 包(如 openclaw 依赖的 libsignal-node)用 git+ssh://git@github.com/...
|
|
8
|
+
// 引用 GitHub 仓库。云主机 root 账户默认没有 GitHub SSH key 会拉取失败。
|
|
9
|
+
// 这里把 ssh://git@github.com/ 和 git@github.com: 都重写成 https://github.com/(匿名可读)。
|
|
10
|
+
// 注意: 同一个 URL name 下要写多个 insteadOf 必须用 --add,否则第二次 set 会覆盖第一次。
|
|
11
|
+
await shell(`git config --global --unset-all url."https://github.com/".insteadOf 2>/dev/null || true`).catch(() => { });
|
|
12
|
+
await shell(`git config --global --add url."https://github.com/".insteadOf ssh://git@github.com/`).catch(() => { });
|
|
13
|
+
await shell(`git config --global --add url."https://github.com/".insteadOf git@github.com:`).catch(() => { });
|
|
7
14
|
// Use /root/.pip — not ~/
|
|
8
15
|
await shell(`mkdir -p /root/.pip && cat > /root/.pip/pip.conf << 'EOF'
|
|
9
16
|
[global]
|
package/dist/utils/mirror.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/utils/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE/E,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAErC,MAAM,KAAK,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEvE,0BAA0B;IAC1B,MAAM,KAAK,CAAC;;cAEA,aAAa;iBACV,gBAAgB;IAC7B,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEpB,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAC9B,CAAC"}
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/utils/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE/E,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAErC,MAAM,KAAK,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEvE,wEAAwE;IACxE,qDAAqD;IACrD,8EAA8E;IAC9E,+DAA+D;IAC/D,MAAM,KAAK,CACT,yFAAyF,CAC1F,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClB,MAAM,KAAK,CACT,qFAAqF,CACtF,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClB,MAAM,KAAK,CACT,+EAA+E,CAChF,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAElB,0BAA0B;IAC1B,MAAM,KAAK,CAAC;;cAEA,aAAa;iBACV,gBAAgB;IAC7B,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEpB,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class OpenclawConfigCliError extends Error {
|
|
2
|
+
readonly cmd: string;
|
|
3
|
+
readonly exitCode: number;
|
|
4
|
+
readonly stdout: string;
|
|
5
|
+
readonly stderr: string;
|
|
6
|
+
constructor(cmd: string, exitCode: number, stdout: string, stderr: string);
|
|
7
|
+
}
|
|
8
|
+
export interface CliRunner {
|
|
9
|
+
run(args: string[]): {
|
|
10
|
+
exitCode: number;
|
|
11
|
+
stdout: string;
|
|
12
|
+
stderr: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export declare const defaultCliRunner: CliRunner;
|
|
16
|
+
export declare function configGet(path: string, runner?: CliRunner): unknown | undefined;
|
|
17
|
+
export declare function configSet(path: string, valueJson: string, runner?: CliRunner): void;
|
|
18
|
+
export declare function configUnset(path: string, runner?: CliRunner): void;
|
|
19
|
+
export declare function configValidate(runner?: CliRunner): boolean;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
export class OpenclawConfigCliError extends Error {
|
|
3
|
+
cmd;
|
|
4
|
+
exitCode;
|
|
5
|
+
stdout;
|
|
6
|
+
stderr;
|
|
7
|
+
constructor(cmd, exitCode, stdout, stderr) {
|
|
8
|
+
super(`openclaw ${cmd} failed (exit ${exitCode}): ${stderr || stdout}`);
|
|
9
|
+
this.cmd = cmd;
|
|
10
|
+
this.exitCode = exitCode;
|
|
11
|
+
this.stdout = stdout;
|
|
12
|
+
this.stderr = stderr;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function stringifyOutput(value) {
|
|
16
|
+
if (typeof value === 'string')
|
|
17
|
+
return value;
|
|
18
|
+
if (Buffer.isBuffer(value))
|
|
19
|
+
return value.toString('utf8');
|
|
20
|
+
return '';
|
|
21
|
+
}
|
|
22
|
+
export const defaultCliRunner = {
|
|
23
|
+
run(args) {
|
|
24
|
+
try {
|
|
25
|
+
const stdout = execFileSync('openclaw', args, {
|
|
26
|
+
encoding: 'utf8',
|
|
27
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
28
|
+
});
|
|
29
|
+
return { exitCode: 0, stdout, stderr: '' };
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
const error = err;
|
|
33
|
+
return {
|
|
34
|
+
exitCode: typeof error.status === 'number' ? error.status : 127,
|
|
35
|
+
stdout: stringifyOutput(error.stdout),
|
|
36
|
+
stderr: stringifyOutput(error.stderr || error.message),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
function runOrThrow(args, runner = defaultCliRunner) {
|
|
42
|
+
const result = runner.run(args);
|
|
43
|
+
if (result.exitCode !== 0) {
|
|
44
|
+
throw new OpenclawConfigCliError(args.join(' '), result.exitCode, result.stdout, result.stderr);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
function isNotFoundOutput(output) {
|
|
49
|
+
return /Config\s+path\s+not\s+found/i.test(output);
|
|
50
|
+
}
|
|
51
|
+
export function configGet(path, runner = defaultCliRunner) {
|
|
52
|
+
const args = ['config', 'get', path];
|
|
53
|
+
const result = runner.run(args);
|
|
54
|
+
if (result.exitCode !== 0) {
|
|
55
|
+
if (isNotFoundOutput(`${result.stderr}\n${result.stdout}`))
|
|
56
|
+
return undefined;
|
|
57
|
+
throw new OpenclawConfigCliError(args.join(' '), result.exitCode, result.stdout, result.stderr);
|
|
58
|
+
}
|
|
59
|
+
const stdout = result.stdout.trim();
|
|
60
|
+
if (!stdout)
|
|
61
|
+
return undefined;
|
|
62
|
+
try {
|
|
63
|
+
return JSON.parse(stdout);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// openclaw config get prints scalar string values as raw text without JSON
|
|
67
|
+
// quoting (e.g. `openviking` rather than `"openviking"`). number / bool / null
|
|
68
|
+
// are valid JSON literals so they parse above; only unquoted strings reach here.
|
|
69
|
+
return stdout;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function configSet(path, valueJson, runner = defaultCliRunner) {
|
|
73
|
+
runOrThrow(['config', 'set', path, valueJson, '--strict-json'], runner);
|
|
74
|
+
}
|
|
75
|
+
export function configUnset(path, runner = defaultCliRunner) {
|
|
76
|
+
runOrThrow(['config', 'unset', path], runner);
|
|
77
|
+
}
|
|
78
|
+
export function configValidate(runner = defaultCliRunner) {
|
|
79
|
+
return runner.run(['config', 'validate']).exitCode === 0;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=openclaw-config-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-config-cli.js","sourceRoot":"","sources":["../../src/utils/openclaw-config-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/shell.d.ts
CHANGED
|
@@ -8,8 +8,18 @@ export interface ShellResult {
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function ensureRoot(): void;
|
|
10
10
|
/**
|
|
11
|
-
* Run a shell command
|
|
12
|
-
*
|
|
11
|
+
* Run a shell command and wait for exit.
|
|
12
|
+
*
|
|
13
|
+
* text 模式:stdio:inherit,子进程输出直通父进程 TTY(本地交互体验不变)。
|
|
14
|
+
*
|
|
15
|
+
* ndjson 模式:捕获 stdout/stderr 并按行合成 phase="log" 事件(stdout→level=info,
|
|
16
|
+
* stderr→level=warn),通过 {@link getActiveEmitter} 拿到当前 op 的 emitter 发出。
|
|
17
|
+
* 这样像 `npm install` 这种几分钟才回一行 ndjson 的长操作,其实时进度也能通过
|
|
18
|
+
* 事件流推给 os-api / 前端,用户不会看到 UI 卡死 10 分钟。
|
|
19
|
+
*
|
|
20
|
+
* 透传是"尽力而为":emitter 缺失(理论上只有本地脚本直接 import shell() 且没走
|
|
21
|
+
* 正常 command 入口才会发生)时静默吞,不影响命令本身执行。
|
|
22
|
+
*
|
|
13
23
|
* Throws on non-zero exit.
|
|
14
24
|
*/
|
|
15
25
|
export declare function shell(cmd: string): Promise<void>;
|
package/dist/utils/shell.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { spawn, execFileSync } from 'node:child_process';
|
|
2
2
|
import { error as logError, info } from './logger.js';
|
|
3
|
+
import { isNdjson } from '../output/mode.js';
|
|
4
|
+
import { getActiveEmitter } from '../output/ndjson.js';
|
|
3
5
|
/**
|
|
4
6
|
* Ensure running as root. If not, re-exec with sudo and exit.
|
|
5
7
|
*/
|
|
@@ -23,16 +25,31 @@ export function ensureRoot() {
|
|
|
23
25
|
// Prefix to source nvm before every shell command so node/npm are on PATH
|
|
24
26
|
const NVM_INIT = 'export HOME=/root; export NVM_DIR=/root/.nvm; [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"; ';
|
|
25
27
|
/**
|
|
26
|
-
* Run a shell command
|
|
27
|
-
*
|
|
28
|
+
* Run a shell command and wait for exit.
|
|
29
|
+
*
|
|
30
|
+
* text 模式:stdio:inherit,子进程输出直通父进程 TTY(本地交互体验不变)。
|
|
31
|
+
*
|
|
32
|
+
* ndjson 模式:捕获 stdout/stderr 并按行合成 phase="log" 事件(stdout→level=info,
|
|
33
|
+
* stderr→level=warn),通过 {@link getActiveEmitter} 拿到当前 op 的 emitter 发出。
|
|
34
|
+
* 这样像 `npm install` 这种几分钟才回一行 ndjson 的长操作,其实时进度也能通过
|
|
35
|
+
* 事件流推给 os-api / 前端,用户不会看到 UI 卡死 10 分钟。
|
|
36
|
+
*
|
|
37
|
+
* 透传是"尽力而为":emitter 缺失(理论上只有本地脚本直接 import shell() 且没走
|
|
38
|
+
* 正常 command 入口才会发生)时静默吞,不影响命令本身执行。
|
|
39
|
+
*
|
|
28
40
|
* Throws on non-zero exit.
|
|
29
41
|
*/
|
|
30
42
|
export function shell(cmd) {
|
|
31
43
|
return new Promise((resolve, reject) => {
|
|
44
|
+
const ndjson = isNdjson();
|
|
32
45
|
const child = spawn('bash', ['-c', NVM_INIT + cmd], {
|
|
33
|
-
stdio: 'inherit',
|
|
46
|
+
stdio: ndjson ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
34
47
|
env: { ...process.env, HOME: '/root' },
|
|
35
48
|
});
|
|
49
|
+
if (ndjson) {
|
|
50
|
+
forwardStreamAsLogEvents(child, 'stdout', 'info');
|
|
51
|
+
forwardStreamAsLogEvents(child, 'stderr', 'warn');
|
|
52
|
+
}
|
|
36
53
|
child.on('error', reject);
|
|
37
54
|
child.on('close', (code) => {
|
|
38
55
|
if (code === 0)
|
|
@@ -42,6 +59,52 @@ export function shell(cmd) {
|
|
|
42
59
|
});
|
|
43
60
|
});
|
|
44
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* 把子进程的一个输出流按换行切分,每行合成一条 phase="log" ndjson 事件。
|
|
64
|
+
*
|
|
65
|
+
* 实现细节:
|
|
66
|
+
* - 跨 chunk 续行:`buf` 累积未看到 \n 的尾巴,下次 data 再拼
|
|
67
|
+
* - 空行丢弃(避免 npm 输出里的空白行污染事件流)
|
|
68
|
+
* - \r 尾字符剥掉(Windows / 终端控制字符常见)
|
|
69
|
+
* - close 时 flush 尾 buf,防止最后一行没 \n 漏掉
|
|
70
|
+
* - emitter 为空时整段 no-op,绝不抛异常——shell() 的主路径不能因日志透传失败而失败
|
|
71
|
+
*/
|
|
72
|
+
function forwardStreamAsLogEvents(child, streamName, level) {
|
|
73
|
+
const stream = child[streamName];
|
|
74
|
+
if (!stream)
|
|
75
|
+
return;
|
|
76
|
+
let buf = '';
|
|
77
|
+
stream.setEncoding('utf8');
|
|
78
|
+
stream.on('data', (chunk) => {
|
|
79
|
+
buf += chunk;
|
|
80
|
+
let idx = buf.indexOf('\n');
|
|
81
|
+
while (idx >= 0) {
|
|
82
|
+
emitLogLine(buf.slice(0, idx), level);
|
|
83
|
+
buf = buf.slice(idx + 1);
|
|
84
|
+
idx = buf.indexOf('\n');
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
stream.on('close', () => {
|
|
88
|
+
if (buf.length > 0) {
|
|
89
|
+
emitLogLine(buf, level);
|
|
90
|
+
buf = '';
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function emitLogLine(line, level) {
|
|
95
|
+
const cleaned = line.endsWith('\r') ? line.slice(0, -1) : line;
|
|
96
|
+
if (cleaned.length === 0)
|
|
97
|
+
return;
|
|
98
|
+
const emitter = getActiveEmitter();
|
|
99
|
+
if (!emitter)
|
|
100
|
+
return;
|
|
101
|
+
try {
|
|
102
|
+
emitter.log(level, cleaned);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// log 事件透传失败不能影响命令本身执行;这里静默
|
|
106
|
+
}
|
|
107
|
+
}
|
|
45
108
|
/**
|
|
46
109
|
* Run a shell command with retries.
|
|
47
110
|
*/
|