@rethinkingstudio/clawpilot 1.0.12 → 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.
|
@@ -5,8 +5,4 @@ export type LocalResult = {
|
|
|
5
5
|
ok: false;
|
|
6
6
|
error: string;
|
|
7
7
|
};
|
|
8
|
-
/**
|
|
9
|
-
* Handles clawpilot-specific commands locally, without forwarding to the gateway.
|
|
10
|
-
* Returns null if the method is not a local command (caller should forward to gateway).
|
|
11
|
-
*/
|
|
12
8
|
export declare function handleLocalCommand(method: string): LocalResult | null;
|
|
@@ -1,35 +1,78 @@
|
|
|
1
1
|
import { readdirSync, statSync, copyFileSync, existsSync, readFileSync } from "fs";
|
|
2
|
-
import { join } from "path";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
5
|
const OPENCLAW_DIR = join(homedir(), ".openclaw");
|
|
6
6
|
const OPENCLAW_CONFIG = join(OPENCLAW_DIR, "openclaw.json");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Subprocess environment
|
|
9
|
+
//
|
|
10
|
+
// launchd services run with a minimal PATH that lacks:
|
|
11
|
+
// - The node binary itself (breaks #!/usr/bin/env node shebangs)
|
|
12
|
+
// - Homebrew / local bins (breaks finding `openclaw`)
|
|
13
|
+
//
|
|
14
|
+
// Fix: build a rich PATH for every subprocess by prepending:
|
|
15
|
+
// 1. dirname(process.execPath) — the dir containing the node binary running
|
|
16
|
+
// this very process. Guarantees #!/usr/bin/env node always resolves.
|
|
17
|
+
// 2. Common package-manager bin dirs (homebrew, /usr/local).
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const NODE_BIN_DIR = dirname(process.execPath);
|
|
20
|
+
const SUBPROCESS_ENV = {
|
|
21
|
+
...process.env,
|
|
22
|
+
HOME: homedir(),
|
|
23
|
+
PATH: [
|
|
24
|
+
NODE_BIN_DIR,
|
|
25
|
+
"/opt/homebrew/bin",
|
|
26
|
+
"/opt/homebrew/sbin",
|
|
27
|
+
"/usr/local/bin",
|
|
28
|
+
"/usr/local/sbin",
|
|
29
|
+
process.env.PATH ?? "/usr/bin:/bin",
|
|
30
|
+
].join(":"),
|
|
31
|
+
};
|
|
32
|
+
function resolveOpenclawBin() {
|
|
33
|
+
try {
|
|
34
|
+
const p = execSync("which openclaw", { stdio: "pipe", env: SUBPROCESS_ENV, timeout: 3000 })
|
|
35
|
+
.toString().trim();
|
|
36
|
+
if (p && existsSync(p)) {
|
|
37
|
+
console.log(`[clawpilot] openclaw resolved: ${p}`);
|
|
38
|
+
return p;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { /* fall through */ }
|
|
42
|
+
console.warn("[clawpilot] could not resolve openclaw path, using bare name");
|
|
43
|
+
return "openclaw";
|
|
44
|
+
}
|
|
45
|
+
const OPENCLAW_BIN = resolveOpenclawBin();
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
11
47
|
export function handleLocalCommand(method) {
|
|
12
48
|
switch (method) {
|
|
13
|
-
case "clawpilot.restore.config":
|
|
14
|
-
|
|
15
|
-
case "clawpilot.
|
|
16
|
-
|
|
17
|
-
case "clawpilot.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return readLogs();
|
|
21
|
-
case "clawpilot.gateway.restart":
|
|
22
|
-
return restartGateway();
|
|
23
|
-
case "clawpilot.update":
|
|
24
|
-
return updateOpenclaw();
|
|
25
|
-
default:
|
|
26
|
-
return null;
|
|
49
|
+
case "clawpilot.restore.config": return restoreConfig();
|
|
50
|
+
case "clawpilot.watchskill": return watchSkill();
|
|
51
|
+
case "clawpilot.doctor": return runDoctor();
|
|
52
|
+
case "clawpilot.logs": return readLogs();
|
|
53
|
+
case "clawpilot.gateway.restart": return restartGateway();
|
|
54
|
+
case "clawpilot.update": return updateOpenclaw();
|
|
55
|
+
default: return null;
|
|
27
56
|
}
|
|
28
57
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Helpers
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
function execErrorOutput(err) {
|
|
62
|
+
const e = err;
|
|
63
|
+
const out = e.stdout?.toString() ?? "";
|
|
64
|
+
const errStr = e.stderr?.toString() ?? "";
|
|
65
|
+
if (out && errStr)
|
|
66
|
+
return `${out}\n${errStr}`;
|
|
67
|
+
return out || errStr;
|
|
68
|
+
}
|
|
69
|
+
/** Run openclaw with the resolved path and the enriched subprocess environment. */
|
|
70
|
+
function openclaw(args) {
|
|
71
|
+
return execSync(`"${OPENCLAW_BIN}" ${args}`, { stdio: "pipe", env: SUBPROCESS_ENV });
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Command implementations
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
33
76
|
function restoreConfig() {
|
|
34
77
|
try {
|
|
35
78
|
if (!existsSync(OPENCLAW_DIR)) {
|
|
@@ -54,12 +97,9 @@ function restoreConfig() {
|
|
|
54
97
|
return { ok: false, error: String(err) };
|
|
55
98
|
}
|
|
56
99
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Enables real-time skill file watching via openclaw CLI.
|
|
59
|
-
*/
|
|
60
100
|
function watchSkill() {
|
|
61
101
|
try {
|
|
62
|
-
|
|
102
|
+
openclaw("config set skills.load.watch true");
|
|
63
103
|
console.log("[clawpilot] skills.load.watch set to true");
|
|
64
104
|
return { ok: true, payload: { message: "skills.load.watch enabled" } };
|
|
65
105
|
}
|
|
@@ -67,41 +107,17 @@ function watchSkill() {
|
|
|
67
107
|
return { ok: false, error: String(err) };
|
|
68
108
|
}
|
|
69
109
|
}
|
|
70
|
-
/** Extracts combined stdout+stderr from an execSync error, with a newline separator if both exist. */
|
|
71
|
-
function execErrorOutput(err) {
|
|
72
|
-
const e = err;
|
|
73
|
-
const out = e.stdout?.toString() ?? "";
|
|
74
|
-
const errStr = e.stderr?.toString() ?? "";
|
|
75
|
-
if (out && errStr)
|
|
76
|
-
return `${out}\n${errStr}`;
|
|
77
|
-
return out || errStr;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Runs a shell command via login bash so that PATH includes homebrew / user-installed bins.
|
|
81
|
-
* The command string must not contain user-controlled input (hardcoded calls only).
|
|
82
|
-
*/
|
|
83
|
-
function loginShell(cmd) {
|
|
84
|
-
return execSync(`/bin/bash -lc '${cmd}'`, { stdio: "pipe" });
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Runs openclaw doctor to check system health.
|
|
88
|
-
*/
|
|
89
110
|
function runDoctor() {
|
|
90
111
|
try {
|
|
91
|
-
const output =
|
|
112
|
+
const output = openclaw("doctor").toString();
|
|
92
113
|
console.log("[clawpilot] doctor completed");
|
|
93
114
|
return { ok: true, payload: { output } };
|
|
94
115
|
}
|
|
95
116
|
catch (err) {
|
|
96
117
|
const output = execErrorOutput(err);
|
|
97
|
-
return output
|
|
98
|
-
? { ok: true, payload: { output } }
|
|
99
|
-
: { ok: false, error: String(err) };
|
|
118
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
100
119
|
}
|
|
101
120
|
}
|
|
102
|
-
/**
|
|
103
|
-
* Reads the last 100 lines from log files in ~/.openclaw/logs/ or ~/.openclaw/*.log.
|
|
104
|
-
*/
|
|
105
121
|
function readLogs() {
|
|
106
122
|
try {
|
|
107
123
|
const logsDir = join(OPENCLAW_DIR, "logs");
|
|
@@ -124,44 +140,33 @@ function readLogs() {
|
|
|
124
140
|
const latest = logFilesWithMtime[0].path;
|
|
125
141
|
const allLines = readFileSync(latest, "utf-8").split("\n");
|
|
126
142
|
const last100 = allLines.slice(-100).join("\n");
|
|
127
|
-
const output = `[${latest}]\n${last100}`;
|
|
128
143
|
console.log(`[clawpilot] logs read from ${latest}`);
|
|
129
|
-
return { ok: true, payload: { output } };
|
|
144
|
+
return { ok: true, payload: { output: `[${latest}]\n${last100}` } };
|
|
130
145
|
}
|
|
131
146
|
catch (err) {
|
|
132
147
|
return { ok: false, error: String(err) };
|
|
133
148
|
}
|
|
134
149
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Restarts the openclaw gateway process.
|
|
137
|
-
*/
|
|
138
150
|
function restartGateway() {
|
|
139
151
|
try {
|
|
140
|
-
const output =
|
|
152
|
+
const output = openclaw("gateway restart").toString();
|
|
141
153
|
console.log("[clawpilot] gateway restarted");
|
|
142
154
|
return { ok: true, payload: { output: output || "Gateway restarted successfully." } };
|
|
143
155
|
}
|
|
144
156
|
catch (err) {
|
|
145
157
|
const output = execErrorOutput(err);
|
|
146
|
-
return output
|
|
147
|
-
? { ok: true, payload: { output } }
|
|
148
|
-
: { ok: false, error: String(err) };
|
|
158
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
149
159
|
}
|
|
150
160
|
}
|
|
151
|
-
/**
|
|
152
|
-
* Updates openclaw to the latest version.
|
|
153
|
-
*/
|
|
154
161
|
function updateOpenclaw() {
|
|
155
162
|
try {
|
|
156
|
-
const output =
|
|
163
|
+
const output = openclaw("update").toString();
|
|
157
164
|
console.log("[clawpilot] openclaw updated");
|
|
158
165
|
return { ok: true, payload: { output: output || "openclaw updated successfully." } };
|
|
159
166
|
}
|
|
160
167
|
catch (err) {
|
|
161
168
|
const output = execErrorOutput(err);
|
|
162
|
-
return output
|
|
163
|
-
? { ok: true, payload: { output } }
|
|
164
|
-
: { ok: false, error: String(err) };
|
|
169
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
165
170
|
}
|
|
166
171
|
}
|
|
167
172
|
//# sourceMappingURL=local-handlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-handlers.js","sourceRoot":"","sources":["../../src/commands/local-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AACnF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"local-handlers.js","sourceRoot":"","sources":["../../src/commands/local-handlers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { runCommand } from "./commands/run.js";
|
|
|
5
5
|
import { installCommand, uninstallCommand, stopCommand, restartCommand, resetCommand } from "./commands/install.js";
|
|
6
6
|
import { statusCommand } from "./commands/status.js";
|
|
7
7
|
import { setTokenCommand } from "./commands/set-token.js";
|
|
8
|
-
const version = "1.0.
|
|
8
|
+
const version = "1.0.14";
|
|
9
9
|
const program = new Command();
|
|
10
10
|
program
|
|
11
11
|
.name("clawpilot")
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readdirSync, statSync, copyFileSync, existsSync, readFileSync } from "fs";
|
|
2
|
-
import { join } from "path";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
5
|
|
|
@@ -10,39 +10,89 @@ export type LocalResult =
|
|
|
10
10
|
| { ok: true; payload?: unknown }
|
|
11
11
|
| { ok: false; error: string };
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Subprocess environment
|
|
15
|
+
//
|
|
16
|
+
// launchd services run with a minimal PATH that lacks:
|
|
17
|
+
// - The node binary itself (breaks #!/usr/bin/env node shebangs)
|
|
18
|
+
// - Homebrew / local bins (breaks finding `openclaw`)
|
|
19
|
+
//
|
|
20
|
+
// Fix: build a rich PATH for every subprocess by prepending:
|
|
21
|
+
// 1. dirname(process.execPath) — the dir containing the node binary running
|
|
22
|
+
// this very process. Guarantees #!/usr/bin/env node always resolves.
|
|
23
|
+
// 2. Common package-manager bin dirs (homebrew, /usr/local).
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
const NODE_BIN_DIR = dirname(process.execPath);
|
|
27
|
+
|
|
28
|
+
const SUBPROCESS_ENV: NodeJS.ProcessEnv = {
|
|
29
|
+
...process.env,
|
|
30
|
+
HOME: homedir(),
|
|
31
|
+
PATH: [
|
|
32
|
+
NODE_BIN_DIR,
|
|
33
|
+
"/opt/homebrew/bin",
|
|
34
|
+
"/opt/homebrew/sbin",
|
|
35
|
+
"/usr/local/bin",
|
|
36
|
+
"/usr/local/sbin",
|
|
37
|
+
process.env.PATH ?? "/usr/bin:/bin",
|
|
38
|
+
].join(":"),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function resolveOpenclawBin(): string {
|
|
42
|
+
try {
|
|
43
|
+
const p = execSync("which openclaw", { stdio: "pipe", env: SUBPROCESS_ENV, timeout: 3000 })
|
|
44
|
+
.toString().trim();
|
|
45
|
+
if (p && existsSync(p)) {
|
|
46
|
+
console.log(`[clawpilot] openclaw resolved: ${p}`);
|
|
47
|
+
return p;
|
|
48
|
+
}
|
|
49
|
+
} catch { /* fall through */ }
|
|
50
|
+
console.warn("[clawpilot] could not resolve openclaw path, using bare name");
|
|
51
|
+
return "openclaw";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const OPENCLAW_BIN = resolveOpenclawBin();
|
|
55
|
+
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
17
58
|
export function handleLocalCommand(method: string): LocalResult | null {
|
|
18
59
|
switch (method) {
|
|
19
|
-
case "clawpilot.restore.config":
|
|
20
|
-
return
|
|
21
|
-
case "clawpilot.
|
|
22
|
-
|
|
23
|
-
case "clawpilot.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return readLogs();
|
|
27
|
-
case "clawpilot.gateway.restart":
|
|
28
|
-
return restartGateway();
|
|
29
|
-
case "clawpilot.update":
|
|
30
|
-
return updateOpenclaw();
|
|
31
|
-
default:
|
|
32
|
-
return null;
|
|
60
|
+
case "clawpilot.restore.config": return restoreConfig();
|
|
61
|
+
case "clawpilot.watchskill": return watchSkill();
|
|
62
|
+
case "clawpilot.doctor": return runDoctor();
|
|
63
|
+
case "clawpilot.logs": return readLogs();
|
|
64
|
+
case "clawpilot.gateway.restart": return restartGateway();
|
|
65
|
+
case "clawpilot.update": return updateOpenclaw();
|
|
66
|
+
default: return null;
|
|
33
67
|
}
|
|
34
68
|
}
|
|
35
69
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Helpers
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
function execErrorOutput(err: unknown): string {
|
|
75
|
+
const e = err as { stdout?: Buffer | string; stderr?: Buffer | string };
|
|
76
|
+
const out = e.stdout?.toString() ?? "";
|
|
77
|
+
const errStr = e.stderr?.toString() ?? "";
|
|
78
|
+
if (out && errStr) return `${out}\n${errStr}`;
|
|
79
|
+
return out || errStr;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Run openclaw with the resolved path and the enriched subprocess environment. */
|
|
83
|
+
function openclaw(args: string): Buffer {
|
|
84
|
+
return execSync(`"${OPENCLAW_BIN}" ${args}`, { stdio: "pipe", env: SUBPROCESS_ENV });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Command implementations
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
40
91
|
function restoreConfig(): LocalResult {
|
|
41
92
|
try {
|
|
42
93
|
if (!existsSync(OPENCLAW_DIR)) {
|
|
43
94
|
return { ok: false, error: `openclaw config dir not found: ${OPENCLAW_DIR}` };
|
|
44
95
|
}
|
|
45
|
-
|
|
46
96
|
const bakFiles = readdirSync(OPENCLAW_DIR)
|
|
47
97
|
.filter(name => name.startsWith("openclaw.json.bak"))
|
|
48
98
|
.map(name => {
|
|
@@ -54,10 +104,8 @@ function restoreConfig(): LocalResult {
|
|
|
54
104
|
if (bakFiles.length === 0) {
|
|
55
105
|
return { ok: false, error: "No backup files found in ~/.openclaw/" };
|
|
56
106
|
}
|
|
57
|
-
|
|
58
107
|
const latest = bakFiles[0];
|
|
59
108
|
copyFileSync(latest.path, OPENCLAW_CONFIG);
|
|
60
|
-
|
|
61
109
|
console.log(`[clawpilot] Config restored from ${latest.name}`);
|
|
62
110
|
return { ok: true, payload: { restoredFrom: latest.name } };
|
|
63
111
|
} catch (err) {
|
|
@@ -65,12 +113,9 @@ function restoreConfig(): LocalResult {
|
|
|
65
113
|
}
|
|
66
114
|
}
|
|
67
115
|
|
|
68
|
-
/**
|
|
69
|
-
* Enables real-time skill file watching via openclaw CLI.
|
|
70
|
-
*/
|
|
71
116
|
function watchSkill(): LocalResult {
|
|
72
117
|
try {
|
|
73
|
-
|
|
118
|
+
openclaw("config set skills.load.watch true");
|
|
74
119
|
console.log("[clawpilot] skills.load.watch set to true");
|
|
75
120
|
return { ok: true, payload: { message: "skills.load.watch enabled" } };
|
|
76
121
|
} catch (err) {
|
|
@@ -78,42 +123,17 @@ function watchSkill(): LocalResult {
|
|
|
78
123
|
}
|
|
79
124
|
}
|
|
80
125
|
|
|
81
|
-
/** Extracts combined stdout+stderr from an execSync error, with a newline separator if both exist. */
|
|
82
|
-
function execErrorOutput(err: unknown): string {
|
|
83
|
-
const e = err as { stdout?: Buffer | string; stderr?: Buffer | string };
|
|
84
|
-
const out = e.stdout?.toString() ?? "";
|
|
85
|
-
const errStr = e.stderr?.toString() ?? "";
|
|
86
|
-
if (out && errStr) return `${out}\n${errStr}`;
|
|
87
|
-
return out || errStr;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Runs a shell command via login bash so that PATH includes homebrew / user-installed bins.
|
|
92
|
-
* The command string must not contain user-controlled input (hardcoded calls only).
|
|
93
|
-
*/
|
|
94
|
-
function loginShell(cmd: string): Buffer {
|
|
95
|
-
return execSync(`/bin/bash -lc '${cmd}'`, { stdio: "pipe" });
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Runs openclaw doctor to check system health.
|
|
100
|
-
*/
|
|
101
126
|
function runDoctor(): LocalResult {
|
|
102
127
|
try {
|
|
103
|
-
const output =
|
|
128
|
+
const output = openclaw("doctor").toString();
|
|
104
129
|
console.log("[clawpilot] doctor completed");
|
|
105
130
|
return { ok: true, payload: { output } };
|
|
106
131
|
} catch (err) {
|
|
107
132
|
const output = execErrorOutput(err);
|
|
108
|
-
return output
|
|
109
|
-
? { ok: true, payload: { output } }
|
|
110
|
-
: { ok: false, error: String(err) };
|
|
133
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
111
134
|
}
|
|
112
135
|
}
|
|
113
136
|
|
|
114
|
-
/**
|
|
115
|
-
* Reads the last 100 lines from log files in ~/.openclaw/logs/ or ~/.openclaw/*.log.
|
|
116
|
-
*/
|
|
117
137
|
function readLogs(): LocalResult {
|
|
118
138
|
try {
|
|
119
139
|
const logsDir = join(OPENCLAW_DIR, "logs");
|
|
@@ -138,43 +158,32 @@ function readLogs(): LocalResult {
|
|
|
138
158
|
const latest = logFilesWithMtime[0].path;
|
|
139
159
|
const allLines = readFileSync(latest, "utf-8").split("\n");
|
|
140
160
|
const last100 = allLines.slice(-100).join("\n");
|
|
141
|
-
const output = `[${latest}]\n${last100}`;
|
|
142
161
|
|
|
143
162
|
console.log(`[clawpilot] logs read from ${latest}`);
|
|
144
|
-
return { ok: true, payload: { output } };
|
|
163
|
+
return { ok: true, payload: { output: `[${latest}]\n${last100}` } };
|
|
145
164
|
} catch (err) {
|
|
146
165
|
return { ok: false, error: String(err) };
|
|
147
166
|
}
|
|
148
167
|
}
|
|
149
168
|
|
|
150
|
-
/**
|
|
151
|
-
* Restarts the openclaw gateway process.
|
|
152
|
-
*/
|
|
153
169
|
function restartGateway(): LocalResult {
|
|
154
170
|
try {
|
|
155
|
-
const output =
|
|
171
|
+
const output = openclaw("gateway restart").toString();
|
|
156
172
|
console.log("[clawpilot] gateway restarted");
|
|
157
173
|
return { ok: true, payload: { output: output || "Gateway restarted successfully." } };
|
|
158
174
|
} catch (err) {
|
|
159
175
|
const output = execErrorOutput(err);
|
|
160
|
-
return output
|
|
161
|
-
? { ok: true, payload: { output } }
|
|
162
|
-
: { ok: false, error: String(err) };
|
|
176
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
163
177
|
}
|
|
164
178
|
}
|
|
165
179
|
|
|
166
|
-
/**
|
|
167
|
-
* Updates openclaw to the latest version.
|
|
168
|
-
*/
|
|
169
180
|
function updateOpenclaw(): LocalResult {
|
|
170
181
|
try {
|
|
171
|
-
const output =
|
|
182
|
+
const output = openclaw("update").toString();
|
|
172
183
|
console.log("[clawpilot] openclaw updated");
|
|
173
184
|
return { ok: true, payload: { output: output || "openclaw updated successfully." } };
|
|
174
185
|
} catch (err) {
|
|
175
186
|
const output = execErrorOutput(err);
|
|
176
|
-
return output
|
|
177
|
-
? { ok: true, payload: { output } }
|
|
178
|
-
: { ok: false, error: String(err) };
|
|
187
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
179
188
|
}
|
|
180
189
|
}
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { installCommand, uninstallCommand, stopCommand, restartCommand, resetCom
|
|
|
6
6
|
import { statusCommand } from "./commands/status.js";
|
|
7
7
|
import { setTokenCommand } from "./commands/set-token.js";
|
|
8
8
|
|
|
9
|
-
const version = "1.0.
|
|
9
|
+
const version = "1.0.14";
|
|
10
10
|
|
|
11
11
|
const program = new Command();
|
|
12
12
|
|