@rethinkingstudio/clawpilot 1.0.9 → 1.0.11

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,137 @@
1
+ const en = {
2
+ // pair
3
+ "pair.alreadyRegistered": (id) => `Gateway already registered (id=${id}). Refreshing access code…`,
4
+ "pair.invalidCredentials": "Invalid credentials (401). The server doesn't recognize this gateway.\nRun `clawpilot reset` to clear config and re-register.",
5
+ "pair.refreshFailed": (status, body) => `Failed to refresh access code: ${status} ${body}`,
6
+ "pair.registering": "Registering with relay server…",
7
+ "pair.registrationFailed": (status, body) => `Registration failed: ${status} ${body}`,
8
+ "pair.registered": (id) => `Registered! Gateway ID: ${id}`,
9
+ "pair.scanQR": "\nScan this QR code with the Clawai iOS app:\n",
10
+ "pair.accessCode": (code) => `\nAccess code (one-time use): ${code}`,
11
+ "pair.installingService": "\nInstalling/updating relay background service…",
12
+ // run
13
+ "run.starting": "Starting ClawAI relay client…",
14
+ "run.gatewayId": (id) => ` Gateway ID: ${id}`,
15
+ "run.relayServer": (url) => ` Relay Server: ${url}`,
16
+ "run.gatewayUrl": (url) => ` Gateway URL: ${url}`,
17
+ "run.connected": "Relay connected.",
18
+ "run.disconnected": "Relay disconnected. Reconnecting…",
19
+ "run.retry": (attempt, delay) => `Retry attempt ${attempt}, waiting ${delay}ms…`,
20
+ // install
21
+ "install.serviceStarted": (label) => `Service installed and started: ${label}`,
22
+ "install.loadFailed": "Failed to load launchd service:",
23
+ "install.plistWritten": (path) => `Plist written to: ${path}`,
24
+ "install.loadManually": (path) => `Run manually: launchctl load -w "${path}"`,
25
+ "install.restarting": "Restarting relay service…",
26
+ "install.serviceStopped": (label) => `Service stopped: ${label}`,
27
+ "install.removePlistFailed": "Failed to remove plist:",
28
+ "install.plistRemoved": (path) => `Plist removed: ${path}`,
29
+ "install.stopped": (label) => `Stopped: ${label}`,
30
+ "install.stoppedAndRemoved": "Relay client stopped and removed from launchd.",
31
+ "install.noService": "No running relay service found.",
32
+ "install.configRemoved": (path) => `Config removed: ${path}`,
33
+ "install.removeConfigFailed": "Failed to remove config:",
34
+ "install.noConfig": "No config file found.",
35
+ "install.resetComplete": "\nReset complete. Run `clawpilot pair` to re-register.",
36
+ // status
37
+ "status.title": "── ClawPilot Relay Client Status ──\n",
38
+ "status.notPaired": "Config: ✗ Not paired — run 'clawpilot pair' first",
39
+ "status.paired": "Config: ✓ Paired",
40
+ "status.displayName": (name) => ` Display name : ${name}`,
41
+ "status.gatewayId": (id) => ` Gateway ID : ${id}`,
42
+ "status.relayServer": (url) => ` Relay server : ${url}`,
43
+ "status.configCorrupted": "Config: ✗ File exists but is corrupted",
44
+ "status.gateway": (url) => `\nGateway: ${url}`,
45
+ "status.serviceNotInstalled": "\nService: ✗ Not installed — run 'clawpilot install'",
46
+ "status.serviceRunning": "\nService: ✓ Running (launchd)",
47
+ "status.serviceLog": (path) => ` Log : ${path}`,
48
+ "status.serviceNotRunning": "\nService: ⚠ Installed but not running",
49
+ "status.servicePlist": (path) => ` Plist : ${path}`,
50
+ "status.serviceStart": (label) => ` Start : launchctl start ${label}`,
51
+ // set-token
52
+ "setToken.noPairing": "No pairing config found. Run 'clawpilot pair' first.",
53
+ "setToken.whereToFind": "\nWhere to find your Gateway Token:",
54
+ "setToken.option1": " Option 1 — OpenClaw desktop app: Settings → Advanced → Gateway Token",
55
+ "setToken.option2": " Option 2 — Terminal:",
56
+ "setToken.option2cmd": " cat ~/.openclaw/openclaw.json | grep -A2 'auth'",
57
+ "setToken.option3": " Option 3 — If set via environment variable: echo $OPENCLAW_GATEWAY_TOKEN\n",
58
+ "setToken.prompt": "Gateway Token (leave blank to clear): ",
59
+ "setToken.saved": "\nToken saved to ~/.clawai/config.json.",
60
+ "setToken.cleared": "\nToken cleared from ~/.clawai/config.json.",
61
+ "setToken.restart": "Run 'clawpilot restart' to apply the change.\n",
62
+ };
63
+ const zh = {
64
+ // pair
65
+ "pair.alreadyRegistered": (id) => `网关已注册 (id=${id}),正在刷新访问码…`,
66
+ "pair.invalidCredentials": "凭证无效 (401),服务器无法识别此网关。\n请运行 `clawpilot reset` 清除配置后重新注册。",
67
+ "pair.refreshFailed": (status, body) => `刷新访问码失败:${status} ${body}`,
68
+ "pair.registering": "正在向中继服务器注册…",
69
+ "pair.registrationFailed": (status, body) => `注册失败:${status} ${body}`,
70
+ "pair.registered": (id) => `注册成功!网关 ID:${id}`,
71
+ "pair.scanQR": "\n请用 Clawai iOS 应用扫描此二维码:\n",
72
+ "pair.accessCode": (code) => `\n访问码(一次性使用):${code}`,
73
+ "pair.installingService": "\n正在安装/更新中继后台服务…",
74
+ // run
75
+ "run.starting": "正在启动 ClawAI 中继客户端…",
76
+ "run.gatewayId": (id) => ` 网关 ID: ${id}`,
77
+ "run.relayServer": (url) => ` 中继服务器:${url}`,
78
+ "run.gatewayUrl": (url) => ` 网关地址: ${url}`,
79
+ "run.connected": "中继已连接。",
80
+ "run.disconnected": "中继已断开,正在重连…",
81
+ "run.retry": (attempt, delay) => `第 ${attempt} 次重试,等待 ${delay}ms…`,
82
+ // install
83
+ "install.serviceStarted": (label) => `服务已安装并启动:${label}`,
84
+ "install.loadFailed": "加载 launchd 服务失败:",
85
+ "install.plistWritten": (path) => `Plist 已写入:${path}`,
86
+ "install.loadManually": (path) => `请手动运行:launchctl load -w "${path}"`,
87
+ "install.restarting": "正在重启中继服务…",
88
+ "install.serviceStopped": (label) => `服务已停止:${label}`,
89
+ "install.removePlistFailed": "删除 Plist 失败:",
90
+ "install.plistRemoved": (path) => `Plist 已删除:${path}`,
91
+ "install.stopped": (label) => `已停止:${label}`,
92
+ "install.stoppedAndRemoved": "中继客户端已停止并从 launchd 移除。",
93
+ "install.noService": "未找到正在运行的中继服务。",
94
+ "install.configRemoved": (path) => `配置文件已删除:${path}`,
95
+ "install.removeConfigFailed": "删除配置文件失败:",
96
+ "install.noConfig": "未找到配置文件。",
97
+ "install.resetComplete": "\n重置完成。请运行 `clawpilot pair` 重新注册。",
98
+ // status
99
+ "status.title": "── ClawPilot 中继客户端状态 ──\n",
100
+ "status.notPaired": "配置:✗ 未配对 — 请先运行 'clawpilot pair'",
101
+ "status.paired": "配置:✓ 已配对",
102
+ "status.displayName": (name) => ` 显示名称:${name}`,
103
+ "status.gatewayId": (id) => ` 网关 ID: ${id}`,
104
+ "status.relayServer": (url) => ` 中继服务器:${url}`,
105
+ "status.configCorrupted": "配置:✗ 文件存在但已损坏",
106
+ "status.gateway": (url) => `\n网关地址:${url}`,
107
+ "status.serviceNotInstalled": "\n服务:✗ 未安装 — 请运行 'clawpilot install'",
108
+ "status.serviceRunning": "\n服务:✓ 运行中 (launchd)",
109
+ "status.serviceLog": (path) => ` 日志:${path}`,
110
+ "status.serviceNotRunning": "\n服务:⚠ 已安装但未运行",
111
+ "status.servicePlist": (path) => ` Plist:${path}`,
112
+ "status.serviceStart": (label) => ` 启动命令:launchctl start ${label}`,
113
+ // set-token
114
+ "setToken.noPairing": "未找到配对配置,请先运行 'clawpilot pair'。",
115
+ "setToken.whereToFind": "\n如何查找 Gateway Token:",
116
+ "setToken.option1": " 方式一 — OpenClaw 桌面应用:设置 → 高级 → Gateway Token",
117
+ "setToken.option2": " 方式二 — 终端:",
118
+ "setToken.option2cmd": " cat ~/.openclaw/openclaw.json | grep -A2 'auth'",
119
+ "setToken.option3": " 方式三 — 若通过环境变量设置:echo $OPENCLAW_GATEWAY_TOKEN\n",
120
+ "setToken.prompt": "Gateway Token(留空则清除):",
121
+ "setToken.saved": "\nToken 已保存到 ~/.clawai/config.json。",
122
+ "setToken.cleared": "\nToken 已从 ~/.clawai/config.json 清除。",
123
+ "setToken.restart": "请运行 'clawpilot restart' 使修改生效。\n",
124
+ };
125
+ function detectLocale() {
126
+ const lang = process.env.LANG ?? process.env.LC_ALL ?? process.env.LANGUAGE ?? "";
127
+ return lang.toLowerCase().startsWith("zh") ? "zh" : "en";
128
+ }
129
+ const locale = detectLocale();
130
+ const msgs = locale === "zh" ? zh : en;
131
+ export function t(key, ...args) {
132
+ const val = msgs[key] ?? en[key] ?? key;
133
+ if (typeof val === "function")
134
+ return val(...args);
135
+ return val;
136
+ }
137
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/i18n/index.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.9";
7
+ import { setTokenCommand } from "./commands/set-token.js";
8
+ const version = "1.0.11";
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rethinkingstudio/clawpilot",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "ClawAI relay client for Mac mini",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,6 +2,7 @@ import { writeFileSync, mkdirSync, existsSync, unlinkSync } from "fs";
2
2
  import { join } from "path";
3
3
  import { homedir } from "os";
4
4
  import { execSync } from "child_process";
5
+ import { t } from "../i18n/index.js";
5
6
 
6
7
  const PLIST_LABEL = "com.rethinkingstudio.clawpilot";
7
8
  const PLIST_LABEL_OLD = "com.rethinkingstudio.clawai"; // legacy, cleaned up by stop
@@ -59,32 +60,32 @@ ${argsXml}
59
60
 
60
61
  try {
61
62
  execSync(`launchctl load -w "${PLIST_PATH}"`, { stdio: "inherit" });
62
- console.log(`Service installed and started: ${PLIST_LABEL}`);
63
+ console.log(t("install.serviceStarted", PLIST_LABEL));
63
64
  } catch (err) {
64
- console.error("Failed to load launchd service:", err);
65
- console.log(`Plist written to: ${PLIST_PATH}`);
66
- console.log(`Run manually: launchctl load -w "${PLIST_PATH}"`);
65
+ console.error(t("install.loadFailed"), err);
66
+ console.log(t("install.plistWritten", PLIST_PATH));
67
+ console.log(t("install.loadManually", PLIST_PATH));
67
68
  }
68
69
  }
69
70
 
70
71
  export function restartCommand(): void {
71
- console.log("Restarting relay service…");
72
+ console.log(t("install.restarting"));
72
73
  installCommand();
73
74
  }
74
75
 
75
76
  export function uninstallCommand(): void {
76
77
  try {
77
78
  execSync(`launchctl unload -w "${PLIST_PATH}"`, { stdio: "inherit" });
78
- console.log(`Service stopped: ${PLIST_LABEL}`);
79
+ console.log(t("install.serviceStopped", PLIST_LABEL));
79
80
  } catch {
80
81
  // May fail if not loaded
81
82
  }
82
83
 
83
84
  try {
84
85
  execSync(`rm -f "${PLIST_PATH}"`, { stdio: "inherit" });
85
- console.log(`Plist removed: ${PLIST_PATH}`);
86
+ console.log(t("install.plistRemoved", PLIST_PATH));
86
87
  } catch (err) {
87
- console.error("Failed to remove plist:", err);
88
+ console.error(t("install.removePlistFailed"), err);
88
89
  }
89
90
  }
90
91
 
@@ -95,7 +96,7 @@ export function stopCommand(): void {
95
96
  // Stop + remove new label
96
97
  try {
97
98
  execSync(`launchctl unload -w "${PLIST_PATH}"`, { stdio: "pipe" });
98
- console.log(`Stopped: ${PLIST_LABEL}`);
99
+ console.log(t("install.stopped", PLIST_LABEL));
99
100
  stopped = true;
100
101
  } catch {
101
102
  // Not loaded — that's fine
@@ -107,7 +108,7 @@ export function stopCommand(): void {
107
108
  // Stop + remove legacy clawai label
108
109
  try {
109
110
  execSync(`launchctl unload -w "${PLIST_PATH_OLD}"`, { stdio: "pipe" });
110
- console.log(`Stopped: ${PLIST_LABEL_OLD}`);
111
+ console.log(t("install.stopped", PLIST_LABEL_OLD));
111
112
  stopped = true;
112
113
  } catch {
113
114
  // Not loaded — that's fine
@@ -117,9 +118,9 @@ export function stopCommand(): void {
117
118
  } catch { /* ignore */ }
118
119
 
119
120
  if (stopped) {
120
- console.log("Relay client stopped and removed from launchd.");
121
+ console.log(t("install.stoppedAndRemoved"));
121
122
  } else {
122
- console.log("No running relay service found.");
123
+ console.log(t("install.noService"));
123
124
  }
124
125
  }
125
126
 
@@ -133,13 +134,13 @@ export function resetCommand(): void {
133
134
  if (existsSync(configPath)) {
134
135
  try {
135
136
  unlinkSync(configPath);
136
- console.log(`Config removed: ${configPath}`);
137
+ console.log(t("install.configRemoved", configPath));
137
138
  } catch (err) {
138
- console.error("Failed to remove config:", err);
139
+ console.error(t("install.removeConfigFailed"), err);
139
140
  }
140
141
  } else {
141
- console.log("No config file found.");
142
+ console.log(t("install.noConfig"));
142
143
  }
143
144
 
144
- console.log("\nReset complete. Run `clawpilot pair` to re-register.");
145
+ console.log(t("install.resetComplete"));
145
146
  }
@@ -1,4 +1,4 @@
1
- import { readdirSync, statSync, copyFileSync, existsSync } from "fs";
1
+ import { readdirSync, statSync, copyFileSync, existsSync, readFileSync } from "fs";
2
2
  import { join } from "path";
3
3
  import { homedir } from "os";
4
4
  import { execSync } from "child_process";
@@ -20,6 +20,14 @@ export function handleLocalCommand(method: string): LocalResult | null {
20
20
  return restoreConfig();
21
21
  case "clawpilot.watchskill":
22
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();
23
31
  default:
24
32
  return null;
25
33
  }
@@ -69,3 +77,96 @@ function watchSkill(): LocalResult {
69
77
  return { ok: false, error: String(err) };
70
78
  }
71
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
+ }
@@ -11,6 +11,7 @@ function getDisplayName(): string {
11
11
  import { configExists, readConfig, writeConfig } from "../config/config.js";
12
12
  import { installCommand } from "./install.js";
13
13
  import qrcodeTerminal from "qrcode-terminal";
14
+ import { t } from "../i18n/index.js";
14
15
 
15
16
  const DEFAULT_RELAY_SERVER = "https://clawpilot.codeaddict.cn";
16
17
 
@@ -34,7 +35,7 @@ export async function pairCommand(opts: PairOptions): Promise<void> {
34
35
  relaySecret = config.relaySecret;
35
36
  displayName = opts.name ?? config.displayName;
36
37
 
37
- console.log(`Gateway already registered (id=${gatewayId}). Refreshing access code…`);
38
+ console.log(t("pair.alreadyRegistered", gatewayId));
38
39
 
39
40
  const res = await fetch(`${httpBase}/api/relay/accesscode`, {
40
41
  method: "POST",
@@ -45,11 +46,9 @@ export async function pairCommand(opts: PairOptions): Promise<void> {
45
46
  if (!res.ok) {
46
47
  const body = await res.text();
47
48
  if (res.status === 401) {
48
- throw new Error(
49
- `Invalid credentials (401). The server doesn't recognize this gateway.\nRun \`clawpilot reset\` to clear config and re-register.`
50
- );
49
+ throw new Error(t("pair.invalidCredentials"));
51
50
  }
52
- throw new Error(`Failed to refresh access code: ${res.status} ${body}`);
51
+ throw new Error(t("pair.refreshFailed", String(res.status), body));
53
52
  }
54
53
 
55
54
  const data = (await res.json()) as { accessCode: string };
@@ -58,7 +57,7 @@ export async function pairCommand(opts: PairOptions): Promise<void> {
58
57
  writeConfig({ ...config, relayServerUrl, displayName });
59
58
  } else {
60
59
  displayName = opts.name ?? getDisplayName();
61
- console.log("Registering with relay server…");
60
+ console.log(t("pair.registering"));
62
61
 
63
62
  const res = await fetch(`${httpBase}/api/relay/register`, {
64
63
  method: "POST",
@@ -68,7 +67,7 @@ export async function pairCommand(opts: PairOptions): Promise<void> {
68
67
 
69
68
  if (!res.ok) {
70
69
  const body = await res.text();
71
- throw new Error(`Registration failed: ${res.status} ${body}`);
70
+ throw new Error(t("pair.registrationFailed", String(res.status), body));
72
71
  }
73
72
 
74
73
  const data = (await res.json()) as {
@@ -83,7 +82,7 @@ export async function pairCommand(opts: PairOptions): Promise<void> {
83
82
 
84
83
  writeConfig({ relayServerUrl, gatewayId, relaySecret, displayName });
85
84
 
86
- console.log(`Registered! Gateway ID: ${gatewayId}`);
85
+ console.log(t("pair.registered", gatewayId));
87
86
  }
88
87
 
89
88
  const qrPayload = JSON.stringify({
@@ -94,10 +93,10 @@ export async function pairCommand(opts: PairOptions): Promise<void> {
94
93
  displayName,
95
94
  });
96
95
 
97
- console.log("\nScan this QR code with the Clawai iOS app:\n");
96
+ console.log(t("pair.scanQR"));
98
97
  qrcodeTerminal.generate(qrPayload, { small: true });
99
- console.log("\nAccess code (one-time use):", accessCode);
98
+ console.log(t("pair.accessCode", accessCode));
100
99
 
101
- console.log("\nInstalling/updating relay background service…");
100
+ console.log(t("pair.installingService"));
102
101
  installCommand();
103
102
  }
@@ -1,16 +1,17 @@
1
1
  import { readConfig, readGatewayUrl, readGatewayAuth } from "../config/config.js";
2
2
  import { runRelayManager } from "../relay/relay-manager.js";
3
3
  import { withReconnect } from "../relay/reconnect.js";
4
+ import { t } from "../i18n/index.js";
4
5
 
5
6
  export async function runCommand(): Promise<void> {
6
7
  const config = readConfig();
7
8
  const gatewayUrl = readGatewayUrl();
8
9
  const gatewayAuth = readGatewayAuth(config);
9
10
 
10
- console.log(`Starting ClawAI relay client…`);
11
- console.log(` Gateway ID: ${config.gatewayId}`);
12
- console.log(` Relay Server: ${config.relayServerUrl}`);
13
- console.log(` Gateway URL: ${gatewayUrl}`);
11
+ console.log(t("run.starting"));
12
+ console.log(t("run.gatewayId", config.gatewayId));
13
+ console.log(t("run.relayServer", config.relayServerUrl));
14
+ console.log(t("run.gatewayUrl", gatewayUrl));
14
15
 
15
16
  await withReconnect(
16
17
  () =>
@@ -21,12 +22,12 @@ export async function runCommand(): Promise<void> {
21
22
  gatewayUrl,
22
23
  gatewayToken: gatewayAuth.token,
23
24
  gatewayPassword: gatewayAuth.password,
24
- onConnected: () => console.log("Relay connected."),
25
- onDisconnected: () => console.log("Relay disconnected. Reconnecting…"),
25
+ onConnected: () => console.log(t("run.connected")),
26
+ onDisconnected: () => console.log(t("run.disconnected")),
26
27
  }),
27
28
  {
28
29
  onRetry: (attempt, delayMs) => {
29
- console.log(`Retry attempt ${attempt}, waiting ${delayMs}ms…`);
30
+ console.log(t("run.retry", String(attempt), String(delayMs)));
30
31
  },
31
32
  }
32
33
  );
@@ -0,0 +1,45 @@
1
+ import readline from "readline";
2
+ import { readConfig, writeConfig } from "../config/config.js";
3
+ import { t } from "../i18n/index.js";
4
+
5
+ export async function setTokenCommand(): Promise<void> {
6
+ // Require pairing to be done first
7
+ let config;
8
+ try {
9
+ config = readConfig();
10
+ } catch {
11
+ console.error(t("setToken.noPairing"));
12
+ process.exit(1);
13
+ }
14
+
15
+ // Tell the user where to find the token
16
+ console.log(t("setToken.whereToFind"));
17
+ console.log(t("setToken.option1"));
18
+ console.log(t("setToken.option2"));
19
+ console.log(t("setToken.option2cmd"));
20
+ console.log(t("setToken.option3"));
21
+
22
+ // Prompt for the token
23
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
24
+ const token = await new Promise<string>((resolve) => {
25
+ rl.question(t("setToken.prompt"), (answer) => {
26
+ rl.close();
27
+ resolve(answer.trim());
28
+ });
29
+ });
30
+
31
+ // Save
32
+ if (token) {
33
+ config.gatewayToken = token;
34
+ delete config.gatewayPassword;
35
+ writeConfig(config);
36
+ console.log(t("setToken.saved"));
37
+ } else {
38
+ delete config.gatewayToken;
39
+ delete config.gatewayPassword;
40
+ writeConfig(config);
41
+ console.log(t("setToken.cleared"));
42
+ }
43
+
44
+ console.log(t("setToken.restart"));
45
+ }
@@ -3,6 +3,7 @@ import { join } from "path";
3
3
  import { homedir } from "os";
4
4
  import { execSync } from "child_process";
5
5
  import { configExists, readConfig, readGatewayUrl } from "../config/config.js";
6
+ import { t } from "../i18n/index.js";
6
7
 
7
8
  const PLIST_LABEL = "com.rethinkingstudio.clawpilot";
8
9
  const PLIST_PATH = join(homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
@@ -18,40 +19,40 @@ function isServiceRunning(): boolean {
18
19
  }
19
20
 
20
21
  export function statusCommand(): void {
21
- console.log("── ClawPilot Relay Client Status ──\n");
22
+ console.log(t("status.title"));
22
23
 
23
24
  // Pairing config
24
25
  if (!configExists()) {
25
- console.log("Config: ✗ Not paired — run 'clawpilot pair' first");
26
+ console.log(t("status.notPaired"));
26
27
  } else {
27
28
  try {
28
29
  const config = readConfig();
29
- console.log("Config: ✓ Paired");
30
- console.log(` Display name : ${config.displayName}`);
31
- console.log(` Gateway ID : ${config.gatewayId}`);
32
- console.log(` Relay server : ${config.relayServerUrl}`);
30
+ console.log(t("status.paired"));
31
+ console.log(t("status.displayName", config.displayName));
32
+ console.log(t("status.gatewayId", config.gatewayId));
33
+ console.log(t("status.relayServer", config.relayServerUrl));
33
34
  } catch {
34
- console.log("Config: ✗ File exists but is corrupted");
35
+ console.log(t("status.configCorrupted"));
35
36
  }
36
37
  }
37
38
 
38
39
  // Local gateway
39
40
  const gatewayUrl = readGatewayUrl();
40
- console.log(`\nGateway: ${gatewayUrl}`);
41
+ console.log(t("status.gateway", gatewayUrl));
41
42
 
42
43
  // launchd service
43
44
  const plistExists = existsSync(PLIST_PATH);
44
45
  const running = isServiceRunning();
45
46
 
46
47
  if (!plistExists) {
47
- console.log("\nService: ✗ Not installed — run 'clawpilot install'");
48
+ console.log(t("status.serviceNotInstalled"));
48
49
  } else if (running) {
49
- console.log("\nService: ✓ Running (launchd)");
50
- console.log(` Log : ${LOG_PATH}`);
50
+ console.log(t("status.serviceRunning"));
51
+ console.log(t("status.serviceLog", LOG_PATH));
51
52
  } else {
52
- console.log("\nService: ⚠ Installed but not running");
53
- console.log(` Plist : ${PLIST_PATH}`);
54
- console.log(" Start : launchctl start " + PLIST_LABEL);
53
+ console.log(t("status.serviceNotRunning"));
54
+ console.log(t("status.servicePlist", PLIST_PATH));
55
+ console.log(t("status.serviceStart", PLIST_LABEL));
55
56
  }
56
57
 
57
58
  console.log("");