rol-websocket-channel 1.4.2 → 1.4.9
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/{MQTT-API /346/226/260/345/242/236/346/226/207/344/273/266/345/212/237/350/203/275.md" → MQTT-API 5-6.md } +89 -1
- package/dist/index.js +6 -0
- package/dist/message-handler.js +13 -1
- package/dist/src/admin/cli-manifest.test.js +62 -0
- package/dist/src/admin/methods/artifacts.js +96 -2
- package/dist/src/admin/methods/artifacts.test.js +19 -0
- package/dist/src/admin/methods/index.js +3 -1
- package/dist/src/admin/methods/mem9.js +40 -1
- package/dist/src/admin/methods/mem9.test.js +34 -0
- package/dist/src/admin/methods/system.js +92 -1
- package/index.ts +6 -0
- package/message-handler.ts +15 -1
- package/openclaw.plugin.json +80 -0
- package/package.json +1 -1
- package/src/admin/cli-manifest.test.ts +67 -0
- package/src/admin/methods/artifacts.test.ts +35 -0
- package/src/admin/methods/artifacts.ts +140 -2
- package/src/admin/methods/index.ts +3 -1
- package/src/admin/methods/mem9.test.ts +39 -0
- package/src/admin/methods/mem9.ts +48 -1
- package/src/admin/methods/system.ts +129 -1
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { exec } from 'node:child_process';
|
|
1
|
+
import { exec, execFile } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
|
+
import { JsonRpcException, JSON_RPC_ERRORS } from '../jsonrpc.js';
|
|
5
6
|
import type { JsonValue, MethodHandler, MethodContext } from '../types.js';
|
|
6
7
|
|
|
7
8
|
const execAsync = promisify(exec);
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
const UPDATE_COMMAND_TIMEOUT_MS = 10 * 60 * 1000;
|
|
11
|
+
const UPDATE_COMMAND_MAX_BUFFER = 10 * 1024 * 1024;
|
|
8
12
|
|
|
9
13
|
export const ping: MethodHandler = async (): Promise<JsonValue> => {
|
|
10
14
|
return {
|
|
@@ -74,6 +78,33 @@ export const doctorFix: MethodHandler = async (_params, context: MethodContext):
|
|
|
74
78
|
}
|
|
75
79
|
};
|
|
76
80
|
|
|
81
|
+
export const openclawUpdate: MethodHandler = async (_params, context: MethodContext): Promise<JsonValue> => {
|
|
82
|
+
const result = await runOpenClawCommand(['update'], context, 'openclawUpdate');
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
ok: true,
|
|
86
|
+
action: 'openclawUpdate',
|
|
87
|
+
restartRecommended: true,
|
|
88
|
+
...result
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const pluginSelfUpdate: MethodHandler = async (_params, context: MethodContext): Promise<JsonValue> => {
|
|
93
|
+
const result = await runOpenClawCommand(
|
|
94
|
+
['plugins', 'install', 'clawhub:rol-websocket-channel'],
|
|
95
|
+
context,
|
|
96
|
+
'pluginSelfUpdate'
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
ok: true,
|
|
101
|
+
action: 'pluginSelfUpdate',
|
|
102
|
+
plugin: 'clawhub:rol-websocket-channel',
|
|
103
|
+
restartRecommended: true,
|
|
104
|
+
...result
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
|
|
77
108
|
export const logs: MethodHandler = async (params: any, context: MethodContext): Promise<JsonValue> => {
|
|
78
109
|
try {
|
|
79
110
|
// 根据实际情况可能需要调整,这里默认尝试 project root 或 user home 下的 .openclaw/logs
|
|
@@ -203,3 +234,100 @@ export const logs: MethodHandler = async (params: any, context: MethodContext):
|
|
|
203
234
|
};
|
|
204
235
|
}
|
|
205
236
|
};
|
|
237
|
+
|
|
238
|
+
async function runOpenClawCommand(
|
|
239
|
+
args: string[],
|
|
240
|
+
context: MethodContext,
|
|
241
|
+
action: string
|
|
242
|
+
): Promise<{ command: string; args: string[]; cwd: string; stdout: string; stderr: string }> {
|
|
243
|
+
const command = process.env.OPENCLAW_BIN || 'openclaw';
|
|
244
|
+
const options = buildOpenClawExecOptions(context.openclawRoot, context.openclawRoot);
|
|
245
|
+
const openclawBin = process.env.OPENCLAW_BIN || '';
|
|
246
|
+
const openclawHome = options.env?.OPENCLAW_HOME || '';
|
|
247
|
+
const home = options.env?.HOME || '';
|
|
248
|
+
|
|
249
|
+
console.log(
|
|
250
|
+
`[system] exec start: action=${action}, command=${command}, args=${JSON.stringify(args)}, cwd=${options.cwd}, OPENCLAW_BIN=${openclawBin}, OPENCLAW_HOME=${openclawHome}, HOME=${home}`
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
const { stdout, stderr } = await execFileAsync(command, args, {
|
|
255
|
+
...options,
|
|
256
|
+
timeout: UPDATE_COMMAND_TIMEOUT_MS,
|
|
257
|
+
maxBuffer: UPDATE_COMMAND_MAX_BUFFER
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
console.log(
|
|
261
|
+
`[system] exec success: action=${action}, command=${command}, args=${JSON.stringify(args)}, stdoutLength=${stdout.length}, stderrLength=${stderr.length}`
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
command,
|
|
266
|
+
args,
|
|
267
|
+
cwd: options.cwd,
|
|
268
|
+
stdout,
|
|
269
|
+
stderr
|
|
270
|
+
};
|
|
271
|
+
} catch (err: any) {
|
|
272
|
+
const stdout = typeof err?.stdout === 'string' ? err.stdout : '';
|
|
273
|
+
const stderr = typeof err?.stderr === 'string' ? err.stderr : '';
|
|
274
|
+
console.error(
|
|
275
|
+
`[system] exec failed: action=${action}, command=${command}, args=${JSON.stringify(args)}, cwd=${options.cwd}, OPENCLAW_BIN=${openclawBin}, OPENCLAW_HOME=${openclawHome}, HOME=${home}, stdout=${JSON.stringify(stdout)}, stderr=${JSON.stringify(stderr)}`
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
throw new JsonRpcException(
|
|
279
|
+
JSON_RPC_ERRORS.internalError,
|
|
280
|
+
`OpenClaw system command failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
281
|
+
{
|
|
282
|
+
action,
|
|
283
|
+
command,
|
|
284
|
+
args,
|
|
285
|
+
cwd: options.cwd,
|
|
286
|
+
stdout,
|
|
287
|
+
stderr
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function buildOpenClawExecOptions(
|
|
294
|
+
cwd: string,
|
|
295
|
+
openclawRoot?: string
|
|
296
|
+
): { cwd: string; shell?: boolean; env: NodeJS.ProcessEnv } {
|
|
297
|
+
const env: NodeJS.ProcessEnv = { ...process.env };
|
|
298
|
+
const openclawHome = resolveOpenClawHomeForCli(openclawRoot);
|
|
299
|
+
if (openclawHome) {
|
|
300
|
+
env.OPENCLAW_HOME = openclawHome;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (openclawRoot && path.basename(path.resolve(openclawRoot)) === '.openclaw') {
|
|
304
|
+
const home = path.dirname(path.resolve(openclawRoot));
|
|
305
|
+
env.HOME = home;
|
|
306
|
+
if (process.platform === 'win32') {
|
|
307
|
+
env.USERPROFILE = home;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (process.platform === 'win32') {
|
|
312
|
+
return {
|
|
313
|
+
cwd,
|
|
314
|
+
shell: true,
|
|
315
|
+
env
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return { cwd, env };
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function resolveOpenClawHomeForCli(openclawRoot?: string): string | undefined {
|
|
323
|
+
if (!openclawRoot) {
|
|
324
|
+
return process.env.OPENCLAW_HOME;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const resolvedRoot = path.resolve(openclawRoot);
|
|
328
|
+
if (path.basename(resolvedRoot) === '.openclaw') {
|
|
329
|
+
return path.dirname(resolvedRoot);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return process.env.OPENCLAW_HOME;
|
|
333
|
+
}
|