openclaw-config-web 1.0.0 → 1.0.1
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/bin/cli.js +24 -5
- package/package.json +10 -4
- package/server.js +36 -6
package/bin/cli.js
CHANGED
|
@@ -3,13 +3,32 @@
|
|
|
3
3
|
const { start } = require('../server');
|
|
4
4
|
|
|
5
5
|
const args = process.argv.slice(2);
|
|
6
|
-
|
|
6
|
+
const options = {};
|
|
7
7
|
|
|
8
8
|
for (let i = 0; i < args.length; i++) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
i
|
|
9
|
+
const arg = args[i];
|
|
10
|
+
if (arg === '-p' || arg === '--port') {
|
|
11
|
+
options.port = parseInt(args[++i], 10);
|
|
12
|
+
if (isNaN(options.port)) {
|
|
13
|
+
console.error('Error: Invalid port number');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
} else if (arg === '-c' || arg === '--config') {
|
|
17
|
+
options.configPath = args[++i];
|
|
18
|
+
} else if (arg === '-h' || arg === '--help') {
|
|
19
|
+
console.log(`
|
|
20
|
+
Usage: openclaw-config-web [options]
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
-p, --port <port> Port to run the server on (default: 3888)
|
|
24
|
+
-c, --config <path> Path to config file
|
|
25
|
+
-h, --help Show this help message
|
|
26
|
+
|
|
27
|
+
Environment variables:
|
|
28
|
+
OPENCLAW_WEB_PORT Port to run the server on
|
|
29
|
+
`);
|
|
30
|
+
process.exit(0);
|
|
12
31
|
}
|
|
13
32
|
}
|
|
14
33
|
|
|
15
|
-
start(
|
|
34
|
+
start(options);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-config-web",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "OpenClaw
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "OpenClaw Model Configuration Web UI",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"openclaw-config-web": "./bin/cli.js"
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"openclaw",
|
|
22
22
|
"config",
|
|
23
23
|
"web-ui",
|
|
24
|
-
"model-management"
|
|
24
|
+
"model-management",
|
|
25
|
+
"cross-platform"
|
|
25
26
|
],
|
|
26
27
|
"license": "MIT",
|
|
27
28
|
"dependencies": {
|
|
@@ -29,5 +30,10 @@
|
|
|
29
30
|
},
|
|
30
31
|
"engines": {
|
|
31
32
|
"node": ">=14.0.0"
|
|
32
|
-
}
|
|
33
|
+
},
|
|
34
|
+
"os": [
|
|
35
|
+
"win32",
|
|
36
|
+
"darwin",
|
|
37
|
+
"linux"
|
|
38
|
+
]
|
|
33
39
|
}
|
package/server.js
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
4
5
|
const { exec } = require('child_process');
|
|
5
6
|
const crypto = require('crypto');
|
|
6
7
|
|
|
8
|
+
const isWindows = process.platform === 'win32';
|
|
9
|
+
const isDarwin = process.platform === 'darwin';
|
|
10
|
+
const isLinux = process.platform === 'linux';
|
|
11
|
+
|
|
12
|
+
function getHomeDir() {
|
|
13
|
+
return os.homedir();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getDefaultConfigPath() {
|
|
17
|
+
return path.join(getHomeDir(), '.openclaw', 'openclaw.json');
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
function createServer(options = {}) {
|
|
8
21
|
const app = express();
|
|
9
22
|
const PORT = options.port || process.env.OPENCLAW_WEB_PORT || 3888;
|
|
10
|
-
const CONFIG_PATH = options.configPath ||
|
|
23
|
+
const CONFIG_PATH = options.configPath || getDefaultConfigPath();
|
|
11
24
|
let csrfToken = crypto.randomBytes(32).toString('hex');
|
|
12
25
|
|
|
13
26
|
function authenticate(req, res, next) {
|
|
@@ -22,6 +35,17 @@ function createServer(options = {}) {
|
|
|
22
35
|
res.json({ success: true, token: csrfToken });
|
|
23
36
|
});
|
|
24
37
|
|
|
38
|
+
app.get('/api/platform', (req, res) => {
|
|
39
|
+
res.json({
|
|
40
|
+
success: true,
|
|
41
|
+
platform: process.platform,
|
|
42
|
+
isWindows,
|
|
43
|
+
isDarwin,
|
|
44
|
+
isLinux,
|
|
45
|
+
hasSystemd: isLinux
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
25
49
|
app.use(express.json());
|
|
26
50
|
|
|
27
51
|
const publicPath = path.join(__dirname, 'public');
|
|
@@ -239,6 +263,9 @@ function createServer(options = {}) {
|
|
|
239
263
|
|
|
240
264
|
function runSystemctl(cmd) {
|
|
241
265
|
return new Promise((resolve, reject) => {
|
|
266
|
+
if (!isLinux) {
|
|
267
|
+
return reject(new Error('systemctl is only available on Linux'));
|
|
268
|
+
}
|
|
242
269
|
exec(`systemctl --user ${cmd} openclaw-gateway 2>&1`, (error, stdout, stderr) => {
|
|
243
270
|
if (error && !stdout.includes('Inactive')) {
|
|
244
271
|
reject(new Error(stdout || stderr || error.message));
|
|
@@ -251,6 +278,9 @@ function createServer(options = {}) {
|
|
|
251
278
|
|
|
252
279
|
function getServiceStatus() {
|
|
253
280
|
return new Promise((resolve) => {
|
|
281
|
+
if (!isLinux) {
|
|
282
|
+
return resolve({ state: 'unsupported', subState: 'systemctl only available on Linux', pid: null });
|
|
283
|
+
}
|
|
254
284
|
exec('systemctl --user show openclaw-gateway --property=ActiveState,SubState,MainPID 2>&1', (error, stdout) => {
|
|
255
285
|
if (error) {
|
|
256
286
|
resolve({ state: 'unknown', subState: 'unknown', pid: null });
|
|
@@ -351,7 +381,8 @@ function createServer(options = {}) {
|
|
|
351
381
|
return res.status(403).json({ success: false, error: 'Command not allowed' });
|
|
352
382
|
}
|
|
353
383
|
|
|
354
|
-
|
|
384
|
+
const openclawCmd = isWindows ? 'openclaw.cmd' : 'openclaw';
|
|
385
|
+
exec(`${openclawCmd} ${command} 2>&1`, { timeout: 30000 }, (error, stdout, stderr) => {
|
|
355
386
|
if (error) {
|
|
356
387
|
res.json({ success: true, output: stderr || error.message });
|
|
357
388
|
} else {
|
|
@@ -366,17 +397,16 @@ function createServer(options = {}) {
|
|
|
366
397
|
function start(options = {}) {
|
|
367
398
|
const { app, PORT } = createServer(options);
|
|
368
399
|
return app.listen(PORT, '0.0.0.0', () => {
|
|
369
|
-
console.log(`OpenClaw
|
|
370
|
-
const os = require('os');
|
|
400
|
+
console.log(`OpenClaw Config Web UI running at: http://localhost:${PORT}`);
|
|
371
401
|
const interfaces = os.networkInterfaces();
|
|
372
402
|
for (const name of Object.keys(interfaces)) {
|
|
373
403
|
for (const iface of interfaces[name]) {
|
|
374
404
|
if (iface.family === 'IPv4' && !iface.internal) {
|
|
375
|
-
console.log(`
|
|
405
|
+
console.log(` Network access: http://${iface.address}:${PORT}`);
|
|
376
406
|
}
|
|
377
407
|
}
|
|
378
408
|
}
|
|
379
409
|
});
|
|
380
410
|
}
|
|
381
411
|
|
|
382
|
-
module.exports = { createServer, start };
|
|
412
|
+
module.exports = { createServer, start, getDefaultConfigPath };
|