@rethinkingstudio/clawpilot 1.0.13 → 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,68 +1,63 @@
|
|
|
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
7
|
// ---------------------------------------------------------------------------
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
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).
|
|
11
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
|
+
};
|
|
12
32
|
function resolveOpenclawBin() {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
console.log(`[clawpilot] openclaw found at ${p} (via ${shell})`);
|
|
19
|
-
return p;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
catch { /* try next */ }
|
|
23
|
-
}
|
|
24
|
-
// Common install locations as final fallback
|
|
25
|
-
for (const p of [
|
|
26
|
-
"/opt/homebrew/bin/openclaw",
|
|
27
|
-
"/usr/local/bin/openclaw",
|
|
28
|
-
join(homedir(), ".local/bin/openclaw"),
|
|
29
|
-
]) {
|
|
30
|
-
if (existsSync(p)) {
|
|
31
|
-
console.log(`[clawpilot] openclaw found at ${p} (fallback)`);
|
|
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}`);
|
|
32
38
|
return p;
|
|
33
39
|
}
|
|
34
40
|
}
|
|
35
|
-
|
|
41
|
+
catch { /* fall through */ }
|
|
42
|
+
console.warn("[clawpilot] could not resolve openclaw path, using bare name");
|
|
36
43
|
return "openclaw";
|
|
37
44
|
}
|
|
38
45
|
const OPENCLAW_BIN = resolveOpenclawBin();
|
|
39
46
|
// ---------------------------------------------------------------------------
|
|
40
|
-
/**
|
|
41
|
-
* Handles clawpilot-specific commands locally, without forwarding to the gateway.
|
|
42
|
-
* Returns null if the method is not a local command (caller should forward to gateway).
|
|
43
|
-
*/
|
|
44
47
|
export function handleLocalCommand(method) {
|
|
45
48
|
switch (method) {
|
|
46
|
-
case "clawpilot.restore.config":
|
|
47
|
-
|
|
48
|
-
case "clawpilot.
|
|
49
|
-
|
|
50
|
-
case "clawpilot.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return readLogs();
|
|
54
|
-
case "clawpilot.gateway.restart":
|
|
55
|
-
return restartGateway();
|
|
56
|
-
case "clawpilot.update":
|
|
57
|
-
return updateOpenclaw();
|
|
58
|
-
default:
|
|
59
|
-
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;
|
|
60
56
|
}
|
|
61
57
|
}
|
|
62
58
|
// ---------------------------------------------------------------------------
|
|
63
59
|
// Helpers
|
|
64
60
|
// ---------------------------------------------------------------------------
|
|
65
|
-
/** Extracts combined stdout+stderr from an execSync error. */
|
|
66
61
|
function execErrorOutput(err) {
|
|
67
62
|
const e = err;
|
|
68
63
|
const out = e.stdout?.toString() ?? "";
|
|
@@ -71,16 +66,13 @@ function execErrorOutput(err) {
|
|
|
71
66
|
return `${out}\n${errStr}`;
|
|
72
67
|
return out || errStr;
|
|
73
68
|
}
|
|
74
|
-
/** Run openclaw with the resolved
|
|
69
|
+
/** Run openclaw with the resolved path and the enriched subprocess environment. */
|
|
75
70
|
function openclaw(args) {
|
|
76
|
-
return execSync(`"${OPENCLAW_BIN}" ${args}`, { stdio: "pipe" });
|
|
71
|
+
return execSync(`"${OPENCLAW_BIN}" ${args}`, { stdio: "pipe", env: SUBPROCESS_ENV });
|
|
77
72
|
}
|
|
78
73
|
// ---------------------------------------------------------------------------
|
|
79
74
|
// Command implementations
|
|
80
75
|
// ---------------------------------------------------------------------------
|
|
81
|
-
/**
|
|
82
|
-
* Finds the most recent openclaw.json.bak* file and copies it over openclaw.json.
|
|
83
|
-
*/
|
|
84
76
|
function restoreConfig() {
|
|
85
77
|
try {
|
|
86
78
|
if (!existsSync(OPENCLAW_DIR)) {
|
|
@@ -105,9 +97,6 @@ function restoreConfig() {
|
|
|
105
97
|
return { ok: false, error: String(err) };
|
|
106
98
|
}
|
|
107
99
|
}
|
|
108
|
-
/**
|
|
109
|
-
* Enables real-time skill file watching via openclaw CLI.
|
|
110
|
-
*/
|
|
111
100
|
function watchSkill() {
|
|
112
101
|
try {
|
|
113
102
|
openclaw("config set skills.load.watch true");
|
|
@@ -118,9 +107,6 @@ function watchSkill() {
|
|
|
118
107
|
return { ok: false, error: String(err) };
|
|
119
108
|
}
|
|
120
109
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Runs openclaw doctor to check system health.
|
|
123
|
-
*/
|
|
124
110
|
function runDoctor() {
|
|
125
111
|
try {
|
|
126
112
|
const output = openclaw("doctor").toString();
|
|
@@ -129,14 +115,9 @@ function runDoctor() {
|
|
|
129
115
|
}
|
|
130
116
|
catch (err) {
|
|
131
117
|
const output = execErrorOutput(err);
|
|
132
|
-
return output
|
|
133
|
-
? { ok: true, payload: { output } }
|
|
134
|
-
: { ok: false, error: String(err) };
|
|
118
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
135
119
|
}
|
|
136
120
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Reads the last 100 lines from log files in ~/.openclaw/logs/ or ~/.openclaw/*.log.
|
|
139
|
-
*/
|
|
140
121
|
function readLogs() {
|
|
141
122
|
try {
|
|
142
123
|
const logsDir = join(OPENCLAW_DIR, "logs");
|
|
@@ -159,17 +140,13 @@ function readLogs() {
|
|
|
159
140
|
const latest = logFilesWithMtime[0].path;
|
|
160
141
|
const allLines = readFileSync(latest, "utf-8").split("\n");
|
|
161
142
|
const last100 = allLines.slice(-100).join("\n");
|
|
162
|
-
const output = `[${latest}]\n${last100}`;
|
|
163
143
|
console.log(`[clawpilot] logs read from ${latest}`);
|
|
164
|
-
return { ok: true, payload: { output } };
|
|
144
|
+
return { ok: true, payload: { output: `[${latest}]\n${last100}` } };
|
|
165
145
|
}
|
|
166
146
|
catch (err) {
|
|
167
147
|
return { ok: false, error: String(err) };
|
|
168
148
|
}
|
|
169
149
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Restarts the openclaw gateway process.
|
|
172
|
-
*/
|
|
173
150
|
function restartGateway() {
|
|
174
151
|
try {
|
|
175
152
|
const output = openclaw("gateway restart").toString();
|
|
@@ -178,14 +155,9 @@ function restartGateway() {
|
|
|
178
155
|
}
|
|
179
156
|
catch (err) {
|
|
180
157
|
const output = execErrorOutput(err);
|
|
181
|
-
return output
|
|
182
|
-
? { ok: true, payload: { output } }
|
|
183
|
-
: { ok: false, error: String(err) };
|
|
158
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
184
159
|
}
|
|
185
160
|
}
|
|
186
|
-
/**
|
|
187
|
-
* Updates openclaw to the latest version.
|
|
188
|
-
*/
|
|
189
161
|
function updateOpenclaw() {
|
|
190
162
|
try {
|
|
191
163
|
const output = openclaw("update").toString();
|
|
@@ -194,9 +166,7 @@ function updateOpenclaw() {
|
|
|
194
166
|
}
|
|
195
167
|
catch (err) {
|
|
196
168
|
const output = execErrorOutput(err);
|
|
197
|
-
return output
|
|
198
|
-
? { ok: true, payload: { output } }
|
|
199
|
-
: { ok: false, error: String(err) };
|
|
169
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
200
170
|
}
|
|
201
171
|
}
|
|
202
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
|
|
|
@@ -11,34 +11,43 @@ export type LocalResult =
|
|
|
11
11
|
| { ok: false; error: string };
|
|
12
12
|
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
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).
|
|
17
24
|
// ---------------------------------------------------------------------------
|
|
18
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
|
+
|
|
19
41
|
function resolveOpenclawBin(): string {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
console.log(`[clawpilot] openclaw found at ${p} (via ${shell})`);
|
|
26
|
-
return p;
|
|
27
|
-
}
|
|
28
|
-
} catch { /* try next */ }
|
|
29
|
-
}
|
|
30
|
-
// Common install locations as final fallback
|
|
31
|
-
for (const p of [
|
|
32
|
-
"/opt/homebrew/bin/openclaw",
|
|
33
|
-
"/usr/local/bin/openclaw",
|
|
34
|
-
join(homedir(), ".local/bin/openclaw"),
|
|
35
|
-
]) {
|
|
36
|
-
if (existsSync(p)) {
|
|
37
|
-
console.log(`[clawpilot] openclaw found at ${p} (fallback)`);
|
|
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}`);
|
|
38
47
|
return p;
|
|
39
48
|
}
|
|
40
|
-
}
|
|
41
|
-
console.warn("[clawpilot] could not resolve openclaw path, using bare
|
|
49
|
+
} catch { /* fall through */ }
|
|
50
|
+
console.warn("[clawpilot] could not resolve openclaw path, using bare name");
|
|
42
51
|
return "openclaw";
|
|
43
52
|
}
|
|
44
53
|
|
|
@@ -46,26 +55,15 @@ const OPENCLAW_BIN = resolveOpenclawBin();
|
|
|
46
55
|
|
|
47
56
|
// ---------------------------------------------------------------------------
|
|
48
57
|
|
|
49
|
-
/**
|
|
50
|
-
* Handles clawpilot-specific commands locally, without forwarding to the gateway.
|
|
51
|
-
* Returns null if the method is not a local command (caller should forward to gateway).
|
|
52
|
-
*/
|
|
53
58
|
export function handleLocalCommand(method: string): LocalResult | null {
|
|
54
59
|
switch (method) {
|
|
55
|
-
case "clawpilot.restore.config":
|
|
56
|
-
return
|
|
57
|
-
case "clawpilot.
|
|
58
|
-
|
|
59
|
-
case "clawpilot.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return readLogs();
|
|
63
|
-
case "clawpilot.gateway.restart":
|
|
64
|
-
return restartGateway();
|
|
65
|
-
case "clawpilot.update":
|
|
66
|
-
return updateOpenclaw();
|
|
67
|
-
default:
|
|
68
|
-
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;
|
|
69
67
|
}
|
|
70
68
|
}
|
|
71
69
|
|
|
@@ -73,7 +71,6 @@ export function handleLocalCommand(method: string): LocalResult | null {
|
|
|
73
71
|
// Helpers
|
|
74
72
|
// ---------------------------------------------------------------------------
|
|
75
73
|
|
|
76
|
-
/** Extracts combined stdout+stderr from an execSync error. */
|
|
77
74
|
function execErrorOutput(err: unknown): string {
|
|
78
75
|
const e = err as { stdout?: Buffer | string; stderr?: Buffer | string };
|
|
79
76
|
const out = e.stdout?.toString() ?? "";
|
|
@@ -82,24 +79,20 @@ function execErrorOutput(err: unknown): string {
|
|
|
82
79
|
return out || errStr;
|
|
83
80
|
}
|
|
84
81
|
|
|
85
|
-
/** Run openclaw with the resolved
|
|
82
|
+
/** Run openclaw with the resolved path and the enriched subprocess environment. */
|
|
86
83
|
function openclaw(args: string): Buffer {
|
|
87
|
-
return execSync(`"${OPENCLAW_BIN}" ${args}`, { stdio: "pipe" });
|
|
84
|
+
return execSync(`"${OPENCLAW_BIN}" ${args}`, { stdio: "pipe", env: SUBPROCESS_ENV });
|
|
88
85
|
}
|
|
89
86
|
|
|
90
87
|
// ---------------------------------------------------------------------------
|
|
91
88
|
// Command implementations
|
|
92
89
|
// ---------------------------------------------------------------------------
|
|
93
90
|
|
|
94
|
-
/**
|
|
95
|
-
* Finds the most recent openclaw.json.bak* file and copies it over openclaw.json.
|
|
96
|
-
*/
|
|
97
91
|
function restoreConfig(): LocalResult {
|
|
98
92
|
try {
|
|
99
93
|
if (!existsSync(OPENCLAW_DIR)) {
|
|
100
94
|
return { ok: false, error: `openclaw config dir not found: ${OPENCLAW_DIR}` };
|
|
101
95
|
}
|
|
102
|
-
|
|
103
96
|
const bakFiles = readdirSync(OPENCLAW_DIR)
|
|
104
97
|
.filter(name => name.startsWith("openclaw.json.bak"))
|
|
105
98
|
.map(name => {
|
|
@@ -111,10 +104,8 @@ function restoreConfig(): LocalResult {
|
|
|
111
104
|
if (bakFiles.length === 0) {
|
|
112
105
|
return { ok: false, error: "No backup files found in ~/.openclaw/" };
|
|
113
106
|
}
|
|
114
|
-
|
|
115
107
|
const latest = bakFiles[0];
|
|
116
108
|
copyFileSync(latest.path, OPENCLAW_CONFIG);
|
|
117
|
-
|
|
118
109
|
console.log(`[clawpilot] Config restored from ${latest.name}`);
|
|
119
110
|
return { ok: true, payload: { restoredFrom: latest.name } };
|
|
120
111
|
} catch (err) {
|
|
@@ -122,9 +113,6 @@ function restoreConfig(): LocalResult {
|
|
|
122
113
|
}
|
|
123
114
|
}
|
|
124
115
|
|
|
125
|
-
/**
|
|
126
|
-
* Enables real-time skill file watching via openclaw CLI.
|
|
127
|
-
*/
|
|
128
116
|
function watchSkill(): LocalResult {
|
|
129
117
|
try {
|
|
130
118
|
openclaw("config set skills.load.watch true");
|
|
@@ -135,9 +123,6 @@ function watchSkill(): LocalResult {
|
|
|
135
123
|
}
|
|
136
124
|
}
|
|
137
125
|
|
|
138
|
-
/**
|
|
139
|
-
* Runs openclaw doctor to check system health.
|
|
140
|
-
*/
|
|
141
126
|
function runDoctor(): LocalResult {
|
|
142
127
|
try {
|
|
143
128
|
const output = openclaw("doctor").toString();
|
|
@@ -145,15 +130,10 @@ function runDoctor(): LocalResult {
|
|
|
145
130
|
return { ok: true, payload: { output } };
|
|
146
131
|
} catch (err) {
|
|
147
132
|
const output = execErrorOutput(err);
|
|
148
|
-
return output
|
|
149
|
-
? { ok: true, payload: { output } }
|
|
150
|
-
: { ok: false, error: String(err) };
|
|
133
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
151
134
|
}
|
|
152
135
|
}
|
|
153
136
|
|
|
154
|
-
/**
|
|
155
|
-
* Reads the last 100 lines from log files in ~/.openclaw/logs/ or ~/.openclaw/*.log.
|
|
156
|
-
*/
|
|
157
137
|
function readLogs(): LocalResult {
|
|
158
138
|
try {
|
|
159
139
|
const logsDir = join(OPENCLAW_DIR, "logs");
|
|
@@ -178,18 +158,14 @@ function readLogs(): LocalResult {
|
|
|
178
158
|
const latest = logFilesWithMtime[0].path;
|
|
179
159
|
const allLines = readFileSync(latest, "utf-8").split("\n");
|
|
180
160
|
const last100 = allLines.slice(-100).join("\n");
|
|
181
|
-
const output = `[${latest}]\n${last100}`;
|
|
182
161
|
|
|
183
162
|
console.log(`[clawpilot] logs read from ${latest}`);
|
|
184
|
-
return { ok: true, payload: { output } };
|
|
163
|
+
return { ok: true, payload: { output: `[${latest}]\n${last100}` } };
|
|
185
164
|
} catch (err) {
|
|
186
165
|
return { ok: false, error: String(err) };
|
|
187
166
|
}
|
|
188
167
|
}
|
|
189
168
|
|
|
190
|
-
/**
|
|
191
|
-
* Restarts the openclaw gateway process.
|
|
192
|
-
*/
|
|
193
169
|
function restartGateway(): LocalResult {
|
|
194
170
|
try {
|
|
195
171
|
const output = openclaw("gateway restart").toString();
|
|
@@ -197,15 +173,10 @@ function restartGateway(): LocalResult {
|
|
|
197
173
|
return { ok: true, payload: { output: output || "Gateway restarted successfully." } };
|
|
198
174
|
} catch (err) {
|
|
199
175
|
const output = execErrorOutput(err);
|
|
200
|
-
return output
|
|
201
|
-
? { ok: true, payload: { output } }
|
|
202
|
-
: { ok: false, error: String(err) };
|
|
176
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
203
177
|
}
|
|
204
178
|
}
|
|
205
179
|
|
|
206
|
-
/**
|
|
207
|
-
* Updates openclaw to the latest version.
|
|
208
|
-
*/
|
|
209
180
|
function updateOpenclaw(): LocalResult {
|
|
210
181
|
try {
|
|
211
182
|
const output = openclaw("update").toString();
|
|
@@ -213,8 +184,6 @@ function updateOpenclaw(): LocalResult {
|
|
|
213
184
|
return { ok: true, payload: { output: output || "openclaw updated successfully." } };
|
|
214
185
|
} catch (err) {
|
|
215
186
|
const output = execErrorOutput(err);
|
|
216
|
-
return output
|
|
217
|
-
? { ok: true, payload: { output } }
|
|
218
|
-
: { ok: false, error: String(err) };
|
|
187
|
+
return output ? { ok: true, payload: { output } } : { ok: false, error: String(err) };
|
|
219
188
|
}
|
|
220
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
|
|