@rethinkingstudio/clawpilot 1.0.8 → 1.0.10

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.
@@ -0,0 +1,12 @@
1
+ export type LocalResult = {
2
+ ok: true;
3
+ payload?: unknown;
4
+ } | {
5
+ ok: false;
6
+ error: string;
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
+ export declare function handleLocalCommand(method: string): LocalResult | null;
@@ -0,0 +1,160 @@
1
+ import { readdirSync, statSync, copyFileSync, existsSync, readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ import { execSync } from "child_process";
5
+ const OPENCLAW_DIR = join(homedir(), ".openclaw");
6
+ const OPENCLAW_CONFIG = join(OPENCLAW_DIR, "openclaw.json");
7
+ /**
8
+ * Handles clawpilot-specific commands locally, without forwarding to the gateway.
9
+ * Returns null if the method is not a local command (caller should forward to gateway).
10
+ */
11
+ export function handleLocalCommand(method) {
12
+ switch (method) {
13
+ case "clawpilot.restore.config":
14
+ return restoreConfig();
15
+ case "clawpilot.watchskill":
16
+ return watchSkill();
17
+ case "clawpilot.doctor":
18
+ return runDoctor();
19
+ case "clawpilot.logs":
20
+ return readLogs();
21
+ case "clawpilot.gateway.restart":
22
+ return restartGateway();
23
+ case "clawpilot.update":
24
+ return updateOpenclaw();
25
+ default:
26
+ return null;
27
+ }
28
+ }
29
+ /**
30
+ * Finds the most recent openclaw.json.bak* file and copies it over openclaw.json.
31
+ * The backup files are kept intact so they can be used again if needed.
32
+ */
33
+ function restoreConfig() {
34
+ try {
35
+ if (!existsSync(OPENCLAW_DIR)) {
36
+ return { ok: false, error: `openclaw config dir not found: ${OPENCLAW_DIR}` };
37
+ }
38
+ const bakFiles = readdirSync(OPENCLAW_DIR)
39
+ .filter(name => name.startsWith("openclaw.json.bak"))
40
+ .map(name => {
41
+ const path = join(OPENCLAW_DIR, name);
42
+ return { name, path, mtime: statSync(path).mtimeMs };
43
+ })
44
+ .sort((a, b) => b.mtime - a.mtime);
45
+ if (bakFiles.length === 0) {
46
+ return { ok: false, error: "No backup files found in ~/.openclaw/" };
47
+ }
48
+ const latest = bakFiles[0];
49
+ copyFileSync(latest.path, OPENCLAW_CONFIG);
50
+ console.log(`[clawpilot] Config restored from ${latest.name}`);
51
+ return { ok: true, payload: { restoredFrom: latest.name } };
52
+ }
53
+ catch (err) {
54
+ return { ok: false, error: String(err) };
55
+ }
56
+ }
57
+ /**
58
+ * Enables real-time skill file watching via openclaw CLI.
59
+ */
60
+ function watchSkill() {
61
+ try {
62
+ execSync("openclaw config set skills.load.watch true", { stdio: "pipe" });
63
+ console.log("[clawpilot] skills.load.watch set to true");
64
+ return { ok: true, payload: { message: "skills.load.watch enabled" } };
65
+ }
66
+ catch (err) {
67
+ return { ok: false, error: String(err) };
68
+ }
69
+ }
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 openclaw doctor to check system health.
81
+ */
82
+ function runDoctor() {
83
+ try {
84
+ const output = execSync("openclaw doctor", { stdio: "pipe" }).toString();
85
+ console.log("[clawpilot] doctor completed");
86
+ return { ok: true, payload: { output } };
87
+ }
88
+ catch (err) {
89
+ const output = execErrorOutput(err);
90
+ return output
91
+ ? { ok: true, payload: { output } }
92
+ : { ok: false, error: String(err) };
93
+ }
94
+ }
95
+ /**
96
+ * Reads the last 100 lines from log files in ~/.openclaw/logs/ or ~/.openclaw/*.log.
97
+ */
98
+ function readLogs() {
99
+ try {
100
+ const logsDir = join(OPENCLAW_DIR, "logs");
101
+ let logFiles = [];
102
+ if (existsSync(logsDir)) {
103
+ logFiles = readdirSync(logsDir)
104
+ .filter(f => f.endsWith(".log"))
105
+ .map(f => join(logsDir, f));
106
+ }
107
+ else {
108
+ logFiles = readdirSync(OPENCLAW_DIR)
109
+ .filter(f => f.endsWith(".log"))
110
+ .map(f => join(OPENCLAW_DIR, f));
111
+ }
112
+ if (logFiles.length === 0) {
113
+ return { ok: true, payload: { output: "No log files found." } };
114
+ }
115
+ const logFilesWithMtime = logFiles.map(f => ({ path: f, mtime: statSync(f).mtimeMs }));
116
+ logFilesWithMtime.sort((a, b) => b.mtime - a.mtime);
117
+ const latest = logFilesWithMtime[0].path;
118
+ const allLines = readFileSync(latest, "utf-8").split("\n");
119
+ const last100 = allLines.slice(-100).join("\n");
120
+ const output = `[${latest}]\n${last100}`;
121
+ console.log(`[clawpilot] logs read from ${latest}`);
122
+ return { ok: true, payload: { output } };
123
+ }
124
+ catch (err) {
125
+ return { ok: false, error: String(err) };
126
+ }
127
+ }
128
+ /**
129
+ * Restarts the openclaw gateway process.
130
+ */
131
+ function restartGateway() {
132
+ try {
133
+ const output = execSync("openclaw gateway restart", { stdio: "pipe" }).toString();
134
+ console.log("[clawpilot] gateway restarted");
135
+ return { ok: true, payload: { output: output || "Gateway restarted successfully." } };
136
+ }
137
+ catch (err) {
138
+ const output = execErrorOutput(err);
139
+ return output
140
+ ? { ok: true, payload: { output } }
141
+ : { ok: false, error: String(err) };
142
+ }
143
+ }
144
+ /**
145
+ * Updates openclaw to the latest version.
146
+ */
147
+ function updateOpenclaw() {
148
+ try {
149
+ const output = execSync("openclaw update", { stdio: "pipe" }).toString();
150
+ console.log("[clawpilot] openclaw updated");
151
+ return { ok: true, payload: { output: output || "openclaw updated successfully." } };
152
+ }
153
+ catch (err) {
154
+ const output = execErrorOutput(err);
155
+ return output
156
+ ? { ok: true, payload: { output } }
157
+ : { ok: false, error: String(err) };
158
+ }
159
+ }
160
+ //# sourceMappingURL=local-handlers.js.map
@@ -0,0 +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;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,YAAY,GAAM,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACrD,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;AAM5D;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,0BAA0B;YAC7B,OAAO,aAAa,EAAE,CAAC;QACzB,KAAK,sBAAsB;YACzB,OAAO,UAAU,EAAE,CAAC;QACtB,KAAK,kBAAkB;YACrB,OAAO,SAAS,EAAE,CAAC;QACrB,KAAK,gBAAgB;YACnB,OAAO,QAAQ,EAAE,CAAC;QACpB,KAAK,2BAA2B;YAC9B,OAAO,cAAc,EAAE,CAAC;QAC1B,KAAK,kBAAkB;YACrB,OAAO,cAAc,EAAE,CAAC;QAC1B;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa;IACpB,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,YAAY,EAAE,EAAE,CAAC;QAChF,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,YAAY,CAAC;aACvC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;aACpD,GAAG,CAAC,IAAI,CAAC,EAAE;YACV,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YACtC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAErC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC;QACvE,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC3B,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAE3C,OAAO,CAAC,GAAG,CAAC,oCAAoC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,QAAQ,CAAC,4CAA4C,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,2BAA2B,EAAE,EAAE,CAAC;IACzE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,sGAAsG;AACtG,SAAS,eAAe,CAAC,GAAY;IACnC,MAAM,CAAC,GAAG,GAA6D,CAAC;IACxE,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,IAAI,GAAG,IAAI,MAAM;QAAE,OAAO,GAAG,GAAG,KAAK,MAAM,EAAE,CAAC;IAC9C,OAAO,GAAG,IAAI,MAAM,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,MAAM;YACX,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE;YACnC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ;IACf,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,QAAQ,GAAa,EAAE,CAAC;QAE5B,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC;iBAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;iBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,WAAW,CAAC,YAAY,CAAC;iBACjC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;iBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,EAAE,CAAC;QAClE,CAAC;QAED,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACvF,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,MAAM,MAAM,OAAO,EAAE,CAAC;QAEzC,OAAO,CAAC,GAAG,CAAC,8BAA8B,MAAM,EAAE,CAAC,CAAC;QACpD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,iCAAiC,EAAE,EAAE,CAAC;IACxF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,MAAM;YACX,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE;YACnC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,gCAAgC,EAAE,EAAE,CAAC;IACvF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,MAAM;YACX,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE;YACnC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function setTokenCommand(): Promise<void>;
@@ -0,0 +1,42 @@
1
+ import readline from "readline";
2
+ import { readConfig, writeConfig } from "../config/config.js";
3
+ export async function setTokenCommand() {
4
+ // Require pairing to be done first
5
+ let config;
6
+ try {
7
+ config = readConfig();
8
+ }
9
+ catch {
10
+ console.error("No pairing config found. Run 'clawpilot pair' first.");
11
+ process.exit(1);
12
+ }
13
+ // Tell the user where to find the token
14
+ console.log("\nWhere to find your Gateway Token:");
15
+ console.log(" Option 1 — OpenClaw desktop app: Settings → Advanced → Gateway Token");
16
+ console.log(" Option 2 — Terminal:");
17
+ console.log(" cat ~/.openclaw/openclaw.json | grep -A2 'auth'");
18
+ console.log(" Option 3 — If set via environment variable: echo $OPENCLAW_GATEWAY_TOKEN\n");
19
+ // Prompt for the token
20
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
21
+ const token = await new Promise((resolve) => {
22
+ rl.question("Gateway Token (leave blank to clear): ", (answer) => {
23
+ rl.close();
24
+ resolve(answer.trim());
25
+ });
26
+ });
27
+ // Save
28
+ if (token) {
29
+ config.gatewayToken = token;
30
+ delete config.gatewayPassword;
31
+ writeConfig(config);
32
+ console.log("\nToken saved to ~/.clawai/config.json.");
33
+ }
34
+ else {
35
+ delete config.gatewayToken;
36
+ delete config.gatewayPassword;
37
+ writeConfig(config);
38
+ console.log("\nToken cleared from ~/.clawai/config.json.");
39
+ }
40
+ console.log("Run 'clawpilot restart' to apply the change.\n");
41
+ }
42
+ //# sourceMappingURL=set-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-token.js","sourceRoot":"","sources":["../../src/commands/set-token.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,mCAAmC;IACnC,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wCAAwC;IACxC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAC;IAE5F,uBAAuB;IACvB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QAClD,EAAE,CAAC,QAAQ,CAAC,wCAAwC,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/D,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO;IACP,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC;QAC5B,OAAO,MAAM,CAAC,eAAe,CAAC;QAC9B,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,OAAO,MAAM,CAAC,YAAY,CAAC;QAC3B,OAAO,MAAM,CAAC,eAAe,CAAC;QAC9B,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;AAChE,CAAC"}
@@ -13,8 +13,10 @@ export declare function readConfig(): ClawaiConfig;
13
13
  export declare function writeConfig(config: ClawaiConfig): void;
14
14
  export declare function readGatewayUrl(): string;
15
15
  /**
16
- * Reads the gateway token or password from the clawai config first,
17
- * then falls back to reading directly from the OpenClaw config file.
16
+ * Reads the gateway token or password. Priority order:
17
+ * 1. ~/.clawai/config.json (gatewayToken / gatewayPassword)
18
+ * 2. ~/.openclaw/openclaw.json (gateway.token / gateway.auth.token)
19
+ * 3. Environment variables (OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD)
18
20
  */
19
21
  export declare function readGatewayAuth(cfg: ClawaiConfig): {
20
22
  token?: string;
@@ -30,8 +30,10 @@ export function readGatewayUrl() {
30
30
  }
31
31
  }
32
32
  /**
33
- * Reads the gateway token or password from the clawai config first,
34
- * then falls back to reading directly from the OpenClaw config file.
33
+ * Reads the gateway token or password. Priority order:
34
+ * 1. ~/.clawai/config.json (gatewayToken / gatewayPassword)
35
+ * 2. ~/.openclaw/openclaw.json (gateway.token / gateway.auth.token)
36
+ * 3. Environment variables (OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD)
35
37
  */
36
38
  export function readGatewayAuth(cfg) {
37
39
  if (cfg.gatewayToken || cfg.gatewayPassword) {
@@ -41,13 +43,20 @@ export function readGatewayAuth(cfg) {
41
43
  try {
42
44
  const raw = readFileSync(OPENCLAW_CONFIG_PATH, "utf-8");
43
45
  const json = JSON.parse(raw);
44
- return {
45
- token: json?.gateway?.token ?? json?.gateway?.auth?.token ?? undefined,
46
- password: json?.gateway?.password ?? json?.gateway?.auth?.password ?? undefined,
47
- };
46
+ const token = json?.gateway?.token ?? json?.gateway?.auth?.token ?? undefined;
47
+ const password = json?.gateway?.password ?? json?.gateway?.auth?.password ?? undefined;
48
+ if (token || password)
49
+ return { token, password };
48
50
  }
49
51
  catch {
50
- return {};
52
+ // ignore
51
53
  }
54
+ // Fall back to environment variables (e.g. set via LaunchAgent)
55
+ const envToken = process.env.OPENCLAW_GATEWAY_TOKEN;
56
+ const envPassword = process.env.OPENCLAW_GATEWAY_PASSWORD;
57
+ if (envToken || envPassword) {
58
+ return { token: envToken, password: envPassword };
59
+ }
60
+ return {};
52
61
  }
53
62
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AACpD,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;AAa3E,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,4BAA4B,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAoB;IAC9C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoC,CAAC;QAChE,MAAM,IAAI,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,KAAK,CAAC;QAC1C,OAAO,kBAAkB,IAAI,EAAE,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,sBAAsB,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAiB;IAC/C,IAAI,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;QAC5C,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,YAAY,EAAE,QAAQ,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC;IACpE,CAAC;IACD,mDAAmD;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsG,CAAC;QAClI,OAAO;YACL,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,SAAS;YACtE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,SAAS;SAChF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,7 +4,8 @@ import { pairCommand } from "./commands/pair.js";
4
4
  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
- const version = "1.0.8";
7
+ import { setTokenCommand } from "./commands/set-token.js";
8
+ const version = "1.0.10";
8
9
  const program = new Command();
9
10
  program
10
11
  .name("clawpilot")
@@ -66,6 +67,18 @@ program
66
67
  .action(() => {
67
68
  uninstallCommand();
68
69
  });
70
+ program
71
+ .command("set-token")
72
+ .description("Set the local OpenClaw gateway token (needed when using token auth)")
73
+ .action(async () => {
74
+ try {
75
+ await setTokenCommand();
76
+ }
77
+ catch (err) {
78
+ console.error("Error:", err instanceof Error ? err.message : err);
79
+ process.exit(1);
80
+ }
81
+ });
69
82
  program
70
83
  .command("reset")
71
84
  .description("Clear saved config and stop service — use when switching servers or on auth errors")
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { WebSocket } from "ws";
2
2
  import { OpenClawGatewayClient } from "./gateway-client.js";
3
+ import { handleLocalCommand } from "../commands/local-handlers.js";
3
4
  // ---------------------------------------------------------------------------
4
5
  // Main entry point
5
6
  // ---------------------------------------------------------------------------
@@ -64,6 +65,19 @@ export async function runRelayManager(opts) {
64
65
  return;
65
66
  const requestId = msg.id;
66
67
  console.log(`[relay] cmd received method=${msg.method} id=${requestId ?? "(no-id)"}`);
68
+ // Handle clawpilot.* commands locally without forwarding to the gateway
69
+ const localResult = handleLocalCommand(msg.method);
70
+ if (localResult !== null) {
71
+ if (requestId) {
72
+ if (localResult.ok) {
73
+ send({ type: "res", id: requestId, ok: true, payload: localResult.payload });
74
+ }
75
+ else {
76
+ send({ type: "res", id: requestId, ok: false, error: { message: localResult.error } });
77
+ }
78
+ }
79
+ return;
80
+ }
67
81
  gatewayClient
68
82
  ?.request(msg.method, msg.params)
69
83
  .then((result) => {
@@ -1 +1 @@
1
- {"version":3,"file":"relay-manager.js","sourceRoot":"","sources":["../../src/relay/relay-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relay-manager.js","sourceRoot":"","sources":["../../src/relay/relay-manager.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rethinkingstudio/clawpilot",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "ClawAI relay client for Mac mini",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,172 @@
1
+ import { readdirSync, statSync, copyFileSync, existsSync, readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ import { execSync } from "child_process";
5
+
6
+ const OPENCLAW_DIR = join(homedir(), ".openclaw");
7
+ const OPENCLAW_CONFIG = join(OPENCLAW_DIR, "openclaw.json");
8
+
9
+ export type LocalResult =
10
+ | { ok: true; payload?: unknown }
11
+ | { ok: false; error: string };
12
+
13
+ /**
14
+ * Handles clawpilot-specific commands locally, without forwarding to the gateway.
15
+ * Returns null if the method is not a local command (caller should forward to gateway).
16
+ */
17
+ export function handleLocalCommand(method: string): LocalResult | null {
18
+ switch (method) {
19
+ case "clawpilot.restore.config":
20
+ return restoreConfig();
21
+ case "clawpilot.watchskill":
22
+ return watchSkill();
23
+ case "clawpilot.doctor":
24
+ return runDoctor();
25
+ case "clawpilot.logs":
26
+ return readLogs();
27
+ case "clawpilot.gateway.restart":
28
+ return restartGateway();
29
+ case "clawpilot.update":
30
+ return updateOpenclaw();
31
+ default:
32
+ return null;
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Finds the most recent openclaw.json.bak* file and copies it over openclaw.json.
38
+ * The backup files are kept intact so they can be used again if needed.
39
+ */
40
+ function restoreConfig(): LocalResult {
41
+ try {
42
+ if (!existsSync(OPENCLAW_DIR)) {
43
+ return { ok: false, error: `openclaw config dir not found: ${OPENCLAW_DIR}` };
44
+ }
45
+
46
+ const bakFiles = readdirSync(OPENCLAW_DIR)
47
+ .filter(name => name.startsWith("openclaw.json.bak"))
48
+ .map(name => {
49
+ const path = join(OPENCLAW_DIR, name);
50
+ return { name, path, mtime: statSync(path).mtimeMs };
51
+ })
52
+ .sort((a, b) => b.mtime - a.mtime);
53
+
54
+ if (bakFiles.length === 0) {
55
+ return { ok: false, error: "No backup files found in ~/.openclaw/" };
56
+ }
57
+
58
+ const latest = bakFiles[0];
59
+ copyFileSync(latest.path, OPENCLAW_CONFIG);
60
+
61
+ console.log(`[clawpilot] Config restored from ${latest.name}`);
62
+ return { ok: true, payload: { restoredFrom: latest.name } };
63
+ } catch (err) {
64
+ return { ok: false, error: String(err) };
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Enables real-time skill file watching via openclaw CLI.
70
+ */
71
+ function watchSkill(): LocalResult {
72
+ try {
73
+ execSync("openclaw config set skills.load.watch true", { stdio: "pipe" });
74
+ console.log("[clawpilot] skills.load.watch set to true");
75
+ return { ok: true, payload: { message: "skills.load.watch enabled" } };
76
+ } catch (err) {
77
+ return { ok: false, error: String(err) };
78
+ }
79
+ }
80
+
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 openclaw doctor to check system health.
92
+ */
93
+ function runDoctor(): LocalResult {
94
+ try {
95
+ const output = execSync("openclaw doctor", { stdio: "pipe" }).toString();
96
+ console.log("[clawpilot] doctor completed");
97
+ return { ok: true, payload: { output } };
98
+ } catch (err) {
99
+ const output = execErrorOutput(err);
100
+ return output
101
+ ? { ok: true, payload: { output } }
102
+ : { ok: false, error: String(err) };
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Reads the last 100 lines from log files in ~/.openclaw/logs/ or ~/.openclaw/*.log.
108
+ */
109
+ function readLogs(): LocalResult {
110
+ try {
111
+ const logsDir = join(OPENCLAW_DIR, "logs");
112
+ let logFiles: string[] = [];
113
+
114
+ if (existsSync(logsDir)) {
115
+ logFiles = readdirSync(logsDir)
116
+ .filter(f => f.endsWith(".log"))
117
+ .map(f => join(logsDir, f));
118
+ } else {
119
+ logFiles = readdirSync(OPENCLAW_DIR)
120
+ .filter(f => f.endsWith(".log"))
121
+ .map(f => join(OPENCLAW_DIR, f));
122
+ }
123
+
124
+ if (logFiles.length === 0) {
125
+ return { ok: true, payload: { output: "No log files found." } };
126
+ }
127
+
128
+ const logFilesWithMtime = logFiles.map(f => ({ path: f, mtime: statSync(f).mtimeMs }));
129
+ logFilesWithMtime.sort((a, b) => b.mtime - a.mtime);
130
+ const latest = logFilesWithMtime[0].path;
131
+ const allLines = readFileSync(latest, "utf-8").split("\n");
132
+ const last100 = allLines.slice(-100).join("\n");
133
+ const output = `[${latest}]\n${last100}`;
134
+
135
+ console.log(`[clawpilot] logs read from ${latest}`);
136
+ return { ok: true, payload: { output } };
137
+ } catch (err) {
138
+ return { ok: false, error: String(err) };
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Restarts the openclaw gateway process.
144
+ */
145
+ function restartGateway(): LocalResult {
146
+ try {
147
+ const output = execSync("openclaw gateway restart", { stdio: "pipe" }).toString();
148
+ console.log("[clawpilot] gateway restarted");
149
+ return { ok: true, payload: { output: output || "Gateway restarted successfully." } };
150
+ } catch (err) {
151
+ const output = execErrorOutput(err);
152
+ return output
153
+ ? { ok: true, payload: { output } }
154
+ : { ok: false, error: String(err) };
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Updates openclaw to the latest version.
160
+ */
161
+ function updateOpenclaw(): LocalResult {
162
+ try {
163
+ const output = execSync("openclaw update", { stdio: "pipe" }).toString();
164
+ console.log("[clawpilot] openclaw updated");
165
+ return { ok: true, payload: { output: output || "openclaw updated successfully." } };
166
+ } catch (err) {
167
+ const output = execErrorOutput(err);
168
+ return output
169
+ ? { ok: true, payload: { output } }
170
+ : { ok: false, error: String(err) };
171
+ }
172
+ }
@@ -0,0 +1,44 @@
1
+ import readline from "readline";
2
+ import { readConfig, writeConfig } from "../config/config.js";
3
+
4
+ export async function setTokenCommand(): Promise<void> {
5
+ // Require pairing to be done first
6
+ let config;
7
+ try {
8
+ config = readConfig();
9
+ } catch {
10
+ console.error("No pairing config found. Run 'clawpilot pair' first.");
11
+ process.exit(1);
12
+ }
13
+
14
+ // Tell the user where to find the token
15
+ console.log("\nWhere to find your Gateway Token:");
16
+ console.log(" Option 1 — OpenClaw desktop app: Settings → Advanced → Gateway Token");
17
+ console.log(" Option 2 — Terminal:");
18
+ console.log(" cat ~/.openclaw/openclaw.json | grep -A2 'auth'");
19
+ console.log(" Option 3 — If set via environment variable: echo $OPENCLAW_GATEWAY_TOKEN\n");
20
+
21
+ // Prompt for the token
22
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
23
+ const token = await new Promise<string>((resolve) => {
24
+ rl.question("Gateway Token (leave blank to clear): ", (answer) => {
25
+ rl.close();
26
+ resolve(answer.trim());
27
+ });
28
+ });
29
+
30
+ // Save
31
+ if (token) {
32
+ config.gatewayToken = token;
33
+ delete config.gatewayPassword;
34
+ writeConfig(config);
35
+ console.log("\nToken saved to ~/.clawai/config.json.");
36
+ } else {
37
+ delete config.gatewayToken;
38
+ delete config.gatewayPassword;
39
+ writeConfig(config);
40
+ console.log("\nToken cleared from ~/.clawai/config.json.");
41
+ }
42
+
43
+ console.log("Run 'clawpilot restart' to apply the change.\n");
44
+ }
@@ -46,8 +46,10 @@ export function readGatewayUrl(): string {
46
46
  }
47
47
 
48
48
  /**
49
- * Reads the gateway token or password from the clawai config first,
50
- * then falls back to reading directly from the OpenClaw config file.
49
+ * Reads the gateway token or password. Priority order:
50
+ * 1. ~/.clawai/config.json (gatewayToken / gatewayPassword)
51
+ * 2. ~/.openclaw/openclaw.json (gateway.token / gateway.auth.token)
52
+ * 3. Environment variables (OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD)
51
53
  */
52
54
  export function readGatewayAuth(cfg: ClawaiConfig): { token?: string; password?: string } {
53
55
  if (cfg.gatewayToken || cfg.gatewayPassword) {
@@ -57,11 +59,17 @@ export function readGatewayAuth(cfg: ClawaiConfig): { token?: string; password?:
57
59
  try {
58
60
  const raw = readFileSync(OPENCLAW_CONFIG_PATH, "utf-8");
59
61
  const json = JSON.parse(raw) as { gateway?: { token?: string; password?: string; auth?: { token?: string; password?: string } } };
60
- return {
61
- token: json?.gateway?.token ?? json?.gateway?.auth?.token ?? undefined,
62
- password: json?.gateway?.password ?? json?.gateway?.auth?.password ?? undefined,
63
- };
62
+ const token = json?.gateway?.token ?? json?.gateway?.auth?.token ?? undefined;
63
+ const password = json?.gateway?.password ?? json?.gateway?.auth?.password ?? undefined;
64
+ if (token || password) return { token, password };
64
65
  } catch {
65
- return {};
66
+ // ignore
66
67
  }
68
+ // Fall back to environment variables (e.g. set via LaunchAgent)
69
+ const envToken = process.env.OPENCLAW_GATEWAY_TOKEN;
70
+ const envPassword = process.env.OPENCLAW_GATEWAY_PASSWORD;
71
+ if (envToken || envPassword) {
72
+ return { token: envToken, password: envPassword };
73
+ }
74
+ return {};
67
75
  }
package/src/index.ts CHANGED
@@ -4,8 +4,9 @@ import { pairCommand } from "./commands/pair.js";
4
4
  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
+ import { setTokenCommand } from "./commands/set-token.js";
7
8
 
8
- const version = "1.0.8";
9
+ const version = "1.0.10";
9
10
 
10
11
  const program = new Command();
11
12
 
@@ -75,6 +76,18 @@ program
75
76
  uninstallCommand();
76
77
  });
77
78
 
79
+ program
80
+ .command("set-token")
81
+ .description("Set the local OpenClaw gateway token (needed when using token auth)")
82
+ .action(async () => {
83
+ try {
84
+ await setTokenCommand();
85
+ } catch (err) {
86
+ console.error("Error:", err instanceof Error ? err.message : err);
87
+ process.exit(1);
88
+ }
89
+ });
90
+
78
91
  program
79
92
  .command("reset")
80
93
  .description("Clear saved config and stop service — use when switching servers or on auth errors")
@@ -1,5 +1,6 @@
1
1
  import { WebSocket } from "ws";
2
2
  import { OpenClawGatewayClient } from "./gateway-client.js";
3
+ import { handleLocalCommand } from "../commands/local-handlers.js";
3
4
 
4
5
  // ---------------------------------------------------------------------------
5
6
  // Messages: relay client ↔ relay server
@@ -109,6 +110,20 @@ export async function runRelayManager(opts: RelayManagerOptions): Promise<boolea
109
110
 
110
111
  const requestId = msg.id;
111
112
  console.log(`[relay] cmd received method=${msg.method} id=${requestId ?? "(no-id)"}`);
113
+
114
+ // Handle clawpilot.* commands locally without forwarding to the gateway
115
+ const localResult = handleLocalCommand(msg.method);
116
+ if (localResult !== null) {
117
+ if (requestId) {
118
+ if (localResult.ok) {
119
+ send({ type: "res", id: requestId, ok: true, payload: localResult.payload });
120
+ } else {
121
+ send({ type: "res", id: requestId, ok: false, error: { message: localResult.error } });
122
+ }
123
+ }
124
+ return;
125
+ }
126
+
112
127
  gatewayClient
113
128
  ?.request(msg.method, msg.params)
114
129
  .then((result) => {