@foxden-app/foxclaw 0.3.5 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,7 @@ FoxClaw(狸爪)的目标很直接:让你用手机控制本机的 Codex,
40
40
  - Git、Node、`.env` 都玩得转?直接往下看快速设置。
41
41
  - 卡住了?看 [故障排查](./docs/zh/troubleshooting.md)。
42
42
 
43
- 最低要求:一个 Telegram bot token、你的 Telegram 数字用户 ID、Node.js 24、一份已登录的 `codex` CLI。首次安装大约 10–20 分钟。
43
+ 最低要求:一个 Telegram bot token、你的 Telegram 数字用户 ID、Node.js 24+、一份已登录的 `codex` CLI。首次安装大约 10–20 分钟。
44
44
 
45
45
  **30 秒体验**:启动 FoxClaw 后,给你的 Telegram 机器人发一句 `List files in DEFAULT_CWD`。Codex 会在本地检查那个目录,然后把结果发回 Telegram。
46
46
 
@@ -70,7 +70,7 @@ foxclaw doctor
70
70
  foxclaw start
71
71
  ```
72
72
 
73
- `foxclaw init` 会创建 `~/.foxclaw/.env`,并在终端里提示填写 Telegram bot token、Telegram 数字用户 ID 和默认工作目录。任何一项都可以直接回车跳过,之后再用 `$EDITOR ~/.foxclaw/.env` 手动修改。
73
+ `foxclaw init` 会创建 `~/.foxclaw/.env`,并在终端里提示填写 Telegram bot token、Telegram 数字用户 ID 和默认工作目录。如果当前 shell 里有 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 等代理变量,也会询问是否写入 FoxClaw 配置,避免服务启动后 Codex 走不到同一条网络。任何一项都可以直接回车跳过,之后再用 `$EDITOR ~/.foxclaw/.env` 手动修改。
74
74
 
75
75
  跑 `doctor` 或 `start` 之前先把 `.env` 填好。私聊模式最小配置:
76
76
 
package/README_EN.md CHANGED
@@ -40,7 +40,7 @@ FoxClaw is more than message forwarding. It provides Telegram panels for Codex w
40
40
  - Already comfortable with Git, Node, and `.env` files? Use the quick setup below.
41
41
  - Something failed? Check [Troubleshooting](./docs/troubleshooting.md).
42
42
 
43
- The minimum install needs only a Telegram bot token, your numeric Telegram user id, Node.js 24, and a logged-in `codex` CLI. A first install usually takes 10–20 minutes.
43
+ The minimum install needs only a Telegram bot token, your numeric Telegram user id, Node.js 24+, and a logged-in `codex` CLI. A first install usually takes 10–20 minutes.
44
44
 
45
45
  **30-second demo**: after FoxClaw is running, send `List files in DEFAULT_CWD` to your Telegram bot. FoxClaw asks local Codex to inspect that folder on your computer and sends the answer back to Telegram.
46
46
 
@@ -70,7 +70,7 @@ foxclaw doctor
70
70
  foxclaw start
71
71
  ```
72
72
 
73
- `foxclaw init` creates `~/.foxclaw/.env` and prompts for the Telegram bot token, your numeric Telegram user id, and the default workspace. Press Enter on any field to skip it and edit later with `$EDITOR ~/.foxclaw/.env`.
73
+ `foxclaw init` creates `~/.foxclaw/.env` and prompts for the Telegram bot token, your numeric Telegram user id, and the default workspace. If the current shell has proxy variables such as `HTTP_PROXY`, `HTTPS_PROXY`, or `ALL_PROXY`, it also asks whether to save them into the FoxClaw config so the service uses the same network path as your working Codex CLI. Press Enter on any field to skip it and edit later with `$EDITOR ~/.foxclaw/.env`.
74
74
 
75
75
  Fill `.env` before running `doctor` or `start`. Minimum private-chat config:
76
76
 
package/dist/main.js CHANGED
@@ -12,6 +12,16 @@ const command = process.argv[2] || 'serve';
12
12
  loadEnv();
13
13
  const packageRoot = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
14
14
  const entryPoint = fileURLToPath(import.meta.url);
15
+ const PROXY_ENV_KEYS = [
16
+ 'HTTP_PROXY',
17
+ 'HTTPS_PROXY',
18
+ 'ALL_PROXY',
19
+ 'NO_PROXY',
20
+ 'http_proxy',
21
+ 'https_proxy',
22
+ 'all_proxy',
23
+ 'no_proxy',
24
+ ];
15
25
  async function main() {
16
26
  if (command === 'init') {
17
27
  await initConfig();
@@ -160,6 +170,7 @@ async function initConfig() {
160
170
  console.log(`Created ${envPath}`);
161
171
  }
162
172
  if (!canPromptForInit()) {
173
+ printProxyEnvHint(envPath);
163
174
  console.log(`Edit it manually, then run: foxclaw doctor`);
164
175
  return;
165
176
  }
@@ -174,6 +185,7 @@ async function configureEnvInteractively(envPath, existed) {
174
185
  if (existed) {
175
186
  const updateExisting = (await rl.question('Update Telegram/workspace setup fields now? [y/N]: ')).trim().toLowerCase();
176
187
  if (updateExisting !== 'y' && updateExisting !== 'yes') {
188
+ await maybeSaveProxyEnvFromShell(rl, envPath);
177
189
  console.log(`Edit it manually, then run: foxclaw doctor`);
178
190
  return;
179
191
  }
@@ -184,6 +196,7 @@ async function configureEnvInteractively(envPath, existed) {
184
196
  const updates = {};
185
197
  const skipped = [];
186
198
  const warnings = [];
199
+ Object.assign(updates, await maybeSaveProxyEnvFromShell(rl, envPath));
187
200
  const token = sanitizeEnvInput(await rl.question('Telegram bot token (TG_BOT_TOKEN): '));
188
201
  if (token) {
189
202
  updates.TG_BOT_TOKEN = token;
@@ -307,6 +320,64 @@ function writeEnvUpdates(envPath, updates) {
307
320
  }
308
321
  fs.writeFileSync(envPath, text);
309
322
  }
323
+ async function maybeSaveProxyEnvFromShell(rl, envPath) {
324
+ const proxyUpdates = detectMissingProxyEnv(envPath);
325
+ const keys = Object.keys(proxyUpdates);
326
+ if (keys.length === 0) {
327
+ return {};
328
+ }
329
+ console.log(`Detected proxy env in this shell: ${keys.join(', ')}`);
330
+ const answer = (await rl.question('Save these proxy settings to FoxClaw .env for service use? [Y/n]: ')).trim().toLowerCase();
331
+ if (answer === 'n' || answer === 'no') {
332
+ console.log(`Skipped proxy env. Add it to ${envPath} if ChatGPT access needs a proxy.`);
333
+ return {};
334
+ }
335
+ writeEnvUpdates(envPath, proxyUpdates);
336
+ console.log(`Saved ${keys.join(', ')} to ${envPath}`);
337
+ return proxyUpdates;
338
+ }
339
+ function printProxyEnvHint(envPath) {
340
+ const proxyUpdates = detectMissingProxyEnv(envPath);
341
+ const keys = Object.keys(proxyUpdates);
342
+ if (keys.length === 0) {
343
+ return;
344
+ }
345
+ console.log(`[WARN] Proxy env detected in this shell but missing from ${envPath}: ${keys.join(', ')}`);
346
+ console.log(`[WARN] Add those proxy variables to ${envPath} if ChatGPT/Codex needs a proxy.`);
347
+ }
348
+ function detectMissingProxyEnv(envPath) {
349
+ const existing = readEnvFileKeys(envPath);
350
+ const existingCanonical = new Set(Array.from(existing, canonicalProxyEnvKey));
351
+ const updates = {};
352
+ for (const key of PROXY_ENV_KEYS) {
353
+ const value = process.env[key]?.trim();
354
+ if (!value || existing.has(key) || existingCanonical.has(canonicalProxyEnvKey(key))) {
355
+ continue;
356
+ }
357
+ updates[key] = value;
358
+ }
359
+ return updates;
360
+ }
361
+ function canonicalProxyEnvKey(key) {
362
+ return key.toUpperCase();
363
+ }
364
+ function readEnvFileKeys(envPath) {
365
+ const keys = new Set();
366
+ let text = '';
367
+ try {
368
+ text = fs.readFileSync(envPath, 'utf8');
369
+ }
370
+ catch {
371
+ return keys;
372
+ }
373
+ for (const line of text.split(/\r?\n/)) {
374
+ const match = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/);
375
+ if (match?.[1]) {
376
+ keys.add(match[1]);
377
+ }
378
+ }
379
+ return keys;
380
+ }
310
381
  function formatEnvValue(value) {
311
382
  const cleaned = value.replace(/[\r\n]/g, '').trim();
312
383
  if (!/[\s#"\\]/.test(cleaned))
@@ -376,8 +447,52 @@ function runDoctorChecks() {
376
447
  console.log(`[FAIL] default cwd missing: ${cwd}`);
377
448
  passed = false;
378
449
  }
450
+ warnIfProxyEnvMissingFromLoadedEnv();
451
+ warnIfInstalledServiceNodeLooksWrong();
379
452
  return passed;
380
453
  }
454
+ function warnIfProxyEnvMissingFromLoadedEnv() {
455
+ const envPath = serviceEnvPath();
456
+ const proxyUpdates = detectMissingProxyEnv(envPath);
457
+ const keys = Object.keys(proxyUpdates);
458
+ if (keys.length === 0) {
459
+ return;
460
+ }
461
+ console.log(`[WARN] proxy env is present in this shell but missing from ${envPath}: ${keys.join(', ')}`);
462
+ console.log(`[WARN] systemd/launchd services do not inherit your shell; add those variables to the FoxClaw env file if Codex needs a proxy.`);
463
+ }
464
+ function warnIfInstalledServiceNodeLooksWrong() {
465
+ if (process.platform !== 'linux') {
466
+ return;
467
+ }
468
+ const unitPath = path.join(process.env.XDG_CONFIG_HOME || path.join(process.env.HOME || '', '.config'), 'systemd', 'user', 'foxclaw.service');
469
+ let text = '';
470
+ try {
471
+ text = fs.readFileSync(unitPath, 'utf8');
472
+ }
473
+ catch {
474
+ return;
475
+ }
476
+ const execStart = text.match(/^ExecStart=(.+)$/m)?.[1]?.trim();
477
+ const nodePath = execStart ? systemdUnescape(execStart.split(/\s+/)[0] ?? '') : '';
478
+ if (!nodePath) {
479
+ return;
480
+ }
481
+ if (!fs.existsSync(nodePath)) {
482
+ console.log(`[WARN] installed service node is missing: ${nodePath}`);
483
+ console.log('[WARN] Run foxclaw start from a Node 24 shell to refresh the service unit.');
484
+ return;
485
+ }
486
+ const result = spawnSync(nodePath, ['-p', 'process.versions.node'], { encoding: 'utf8' });
487
+ const version = result.status === 0 ? result.stdout.trim() : '';
488
+ const major = Number.parseInt(version.split('.')[0] ?? '', 10);
489
+ if (Number.isFinite(major) && major >= 24) {
490
+ console.log(`[OK] service node >= 24: ${nodePath}`);
491
+ return;
492
+ }
493
+ console.log(`[WARN] installed service node is older than 24: ${nodePath}${version ? ` (${version})` : ''}`);
494
+ console.log('[WARN] Run foxclaw start from a Node 24 shell to refresh the service unit.');
495
+ }
381
496
  function installSystemd() {
382
497
  if (!hasCommand('systemctl')) {
383
498
  console.error('systemctl not found (need systemd)');
@@ -543,6 +658,9 @@ function spawnChecked(commandName, args) {
543
658
  function systemdEscape(value) {
544
659
  return value.replace(/\\/g, '\\\\').replace(/ /g, '\\x20');
545
660
  }
661
+ function systemdUnescape(value) {
662
+ return value.replace(/\\x20/g, ' ').replace(/\\\\/g, '\\');
663
+ }
546
664
  function xmlEscape(value) {
547
665
  return value
548
666
  .replace(/&/g, '&')
@@ -39,7 +39,7 @@ DEFAULT_CWD=<paste absolute working directory here>
39
39
 
40
40
  Tasks:
41
41
  1. Inspect the machine first. If a FoxClaw service already exists, report it before changing services.
42
- 2. Ensure Node.js 24+ is available. If not, install or activate Node 24 with nvm.
42
+ 2. Ensure Node.js 24+ is available. If not, install or activate Node 24+ by any suitable method; nvm is only one common option.
43
43
  3. Ensure the Codex CLI exists and is logged in. If login is required, stop and tell me exactly what I need to do.
44
44
  4. Install or update FoxClaw with npm install -g @foxden-app/foxclaw@latest.
45
45
  5. Run foxclaw init, then write ~/.foxclaw/.env. Never print or commit the bot token.
@@ -25,17 +25,17 @@ You need:
25
25
 
26
26
  Use private chat first. Group and topic setup can wait until the bot replies reliably.
27
27
 
28
- ## 2. Install Node.js 24
28
+ ## 2. Install Node.js 24+
29
29
 
30
- FoxClaw needs Node.js 24 because it uses the built-in SQLite runtime.
30
+ FoxClaw needs Node.js 24+ because it uses the built-in SQLite runtime. It does not require nvm; you can use nvm, fnm, asdf, mise, Volta, Homebrew, or your system package manager.
31
31
 
32
- If you already have Node 24, this should print `v24...`:
32
+ If you already have Node 24+, this should print `v24...` or newer:
33
33
 
34
34
  ```bash
35
35
  node -v
36
36
  ```
37
37
 
38
- If not, install Node 24 with `nvm`:
38
+ If not, nvm is a good default for first-time users. Example:
39
39
 
40
40
  ```bash
41
41
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
@@ -47,7 +47,7 @@ node -v
47
47
  npm -v
48
48
  ```
49
49
 
50
- If `node -v` still shows an old version, close the terminal, open a new one, and run:
50
+ If you use nvm and `node -v` still shows an old version, close the terminal, open a new one, and run:
51
51
 
52
52
  ```bash
53
53
  nvm use 24
@@ -18,7 +18,7 @@ journalctl --user -u foxclaw.service -f
18
18
 
19
19
  | Symptom | Meaning | Fix |
20
20
  | --- | --- | --- |
21
- | `[FAIL] node >= 24` | Your current shell is using an older Node.js. | Run `nvm install 24 && nvm use 24`, then rerun `foxclaw doctor`. If the service uses old Node, reinstall it from a Node 24 shell with `foxclaw start`. |
21
+ | `[FAIL] node >= 24` | Your current shell is using an older Node.js. | Install or activate Node.js 24+ by any method, then rerun `foxclaw doctor`. If the service uses old Node, reinstall it from a Node 24+ shell with `foxclaw start`. |
22
22
  | `[FAIL] codex cli available` | The `codex` command is not in PATH. | Install Codex CLI or fix PATH, then confirm `codex --version` works. |
23
23
  | `[FAIL] telegram bot token configured` | `TG_BOT_TOKEN` is missing from `.env`. | Copy the token from `@BotFather` into `.env`. |
24
24
  | `[FAIL] telegram allowed user configured` | `TG_ALLOWED_USER_ID` is missing from `.env`. | Get your numeric id from `@userinfobot` and add it to `.env`. |
@@ -26,7 +26,7 @@ journalctl --user -u foxclaw.service -f
26
26
 
27
27
  ## Node Or npm Is Missing
28
28
 
29
- If you see `node: command not found` or `npm: command not found`, install Node.js 24 with `nvm`:
29
+ If you see `node: command not found` or `npm: command not found`, install Node.js 24+ using your preferred tool, such as nvm, fnm, asdf, mise, Volta, Homebrew, or your system package manager. This is an nvm example:
30
30
 
31
31
  ```bash
32
32
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
@@ -38,7 +38,7 @@ node -v
38
38
  npm -v
39
39
  ```
40
40
 
41
- If it still fails, close the terminal, open a new one, and run:
41
+ If you use nvm and it still fails, close the terminal, open a new one, and run:
42
42
 
43
43
  ```bash
44
44
  nvm use 24
@@ -48,7 +48,7 @@ nvm use 24
48
48
 
49
49
  If `npm install -g @openai/codex` fails with `EACCES`, `EPERM`, or `permission denied`, your global npm directory is not writable by your user.
50
50
 
51
- Recommended fix: use Node through `nvm`, then install again:
51
+ Recommended fix: use a user-level Node.js 24+ install, then install again. This is an nvm example:
52
52
 
53
53
  ```bash
54
54
  nvm install 24
@@ -56,7 +56,7 @@ nvm use 24
56
56
  npm install -g @openai/codex
57
57
  ```
58
58
 
59
- Avoid `sudo npm install -g ...` unless you already understand how your Node installation is managed. Mixing `sudo`, system Node, and `nvm` is a common source of broken PATHs.
59
+ Avoid `sudo npm install -g ...` unless you already understand how your Node installation is managed. Mixing `sudo`, system Node, and user-level Node managers is a common source of broken PATHs.
60
60
 
61
61
  If `codex` installs but FoxClaw still cannot find it, locate the binary:
62
62
 
@@ -192,6 +192,8 @@ A common cause is that your shell or project `.env` has proxy variables, while t
192
192
  systemctl --user cat foxclaw.service
193
193
  ```
194
194
 
195
+ `foxclaw init` detects proxy environment variables in the current shell and asks whether to save them into the FoxClaw `.env`. If you skipped that step, `foxclaw doctor` warns when it sees proxy variables in the shell but not in the FoxClaw env file.
196
+
195
197
  Make sure the file referenced by `Environment=FOXCLAW_ENV=...` contains your proxy variables, for example:
196
198
 
197
199
  ```dotenv
@@ -209,7 +211,9 @@ foxclaw restart
209
211
 
210
212
  ## Service Starts With The Wrong Node Version
211
213
 
212
- The systemd installer captures the `node` binary from your current PATH. If you installed the service from a shell using Node 22 or older, reinstall it from a Node 24 shell:
214
+ The systemd installer records the absolute path of the Node process that is currently running FoxClaw. It does not rely on systemd loading `nvm.sh` or any other shell init script. Whether you use nvm, fnm, asdf, mise, Volta, Homebrew, or system Node, run `foxclaw start` from a Node 24+ shell and the service will keep using that Node 24+ path.
215
+
216
+ If you installed the service from a shell using Node 22 or older, reinstall it from a Node 24+ shell. Example for nvm users:
213
217
 
214
218
  ```bash
215
219
  nvm use 24
@@ -217,7 +221,7 @@ foxclaw start
217
221
  systemctl --user status foxclaw.service
218
222
  ```
219
223
 
220
- The status output should show a Node 24 path in `ExecStart`.
224
+ The status output should show a Node 24+ path in `ExecStart`. `foxclaw doctor` also checks the installed service Node path and warns if it is missing or older than 24.
221
225
 
222
226
  ## Does It Run After Reboot?
223
227
 
@@ -16,15 +16,15 @@ Your code, shell access, Codex auth, and runtime state stay on the host machine.
16
16
 
17
17
  ## 1. Full Setup
18
18
 
19
- ### 1.1 Install Node.js 24
19
+ ### 1.1 Install Node.js 24+
20
20
 
21
- FoxClaw requires Node.js 24. Check first:
21
+ FoxClaw requires Node.js 24+ and does not require nvm. Check first:
22
22
 
23
23
  ```bash
24
24
  node -v
25
25
  ```
26
26
 
27
- If this is not `v24...`, install Node 24 with `nvm`:
27
+ If this is not `v24...` or newer, install Node 24+ with nvm, fnm, asdf, mise, Volta, Homebrew, or your system package manager. This is an nvm example:
28
28
 
29
29
  ```bash
30
30
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
@@ -100,7 +100,7 @@ Both install the same published npm package. Use one global package manager cons
100
100
 
101
101
  ### 1.6 Fill In The Config
102
102
 
103
- `foxclaw init` creates the default config file at `~/.foxclaw/.env` and prompts for the Telegram bot token, your numeric Telegram user id, and the default workspace. Press Enter on any field to skip it, then edit manually if needed:
103
+ `foxclaw init` creates the default config file at `~/.foxclaw/.env` and prompts for the Telegram bot token, your numeric Telegram user id, and the default workspace. If the current shell has proxy variables such as `HTTP_PROXY`, `HTTPS_PROXY`, or `ALL_PROXY`, it also asks whether to save them into the FoxClaw config so the service-side Codex app-server uses the same network. Press Enter on any field to skip it, then edit manually if needed:
104
104
 
105
105
  ```bash
106
106
  $EDITOR ~/.foxclaw/.env
@@ -38,7 +38,7 @@ DEFAULT_CWD=<把绝对工作目录粘贴在这里>
38
38
 
39
39
  任务:
40
40
  1. 先检查机器环境。如果已经存在 FoxClaw 服务,先报告再改服务。
41
- 2. 确保 Node.js 24+ 可用;如果没有,请用 nvm 安装或切到 Node 24
41
+ 2. 确保 Node.js 24+ 可用;如果没有,请用任意合适方式安装或切到 Node 24+,nvm 只是常见选择。
42
42
  3. 确保 Codex CLI 存在并且已经登录。如果需要登录,停下来告诉我具体要执行什么。
43
43
  4. 用 npm install -g @foxden-app/foxclaw@latest 安装或升级 FoxClaw。
44
44
  5. 运行 foxclaw init,然后写入 ~/.foxclaw/.env。不要打印或提交 bot token。
@@ -5,7 +5,7 @@
5
5
  ## 适合什么时候用
6
6
 
7
7
  - 你想让 Codex 通过 SSH 帮另一台 Mac 安装 FoxClaw。
8
- - 你希望 agent 先检查环境,再决定如何安装 Node.js 24Codex CLI 和 FoxClaw。
8
+ - 你希望 agent 先检查环境,再决定如何安装 Node.js 24+、Codex CLI 和 FoxClaw。
9
9
  - 你不想手动复制每一步安装命令,但愿意提供 Telegram bot token、用户 ID 和默认工作目录。
10
10
 
11
11
  ## 基本流程
@@ -23,17 +23,17 @@ FoxClaw 跑在你的电脑上。手机发消息给 Telegram bot,bot 把消息
23
23
  - 一个 Codex 可以工作的目录,例如 `~/Projects` 或 `~/Desktop`
24
24
  - 第一次安装大约 10-20 分钟
25
25
 
26
- ## 2. 安装 Node.js 24
26
+ ## 2. 安装 Node.js 24+
27
27
 
28
- FoxClaw 需要 Node.js 24,因为它使用 Node 内置 SQLite 运行时。
28
+ FoxClaw 需要 Node.js 24+,因为它使用 Node 内置 SQLite 运行时。不强依赖 nvm;你可以用 nvm、fnm、asdf、mise、Volta、Homebrew 或系统包管理器安装。
29
29
 
30
- 如果已经安装 Node 24,这条命令会输出 `v24...`:
30
+ 如果已经安装 Node 24+,这条命令会输出 `v24...` 或更高版本:
31
31
 
32
32
  ```bash
33
33
  node -v
34
34
  ```
35
35
 
36
- 如果不是 Node 24,推荐用 `nvm` 安装:
36
+ 如果不是 Node 24+,推荐普通用户用 `nvm` 安装,示例:
37
37
 
38
38
  ```bash
39
39
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
@@ -45,7 +45,7 @@ node -v
45
45
  npm -v
46
46
  ```
47
47
 
48
- 如果 `node -v` 仍然显示旧版本,关闭终端,重新打开后运行:
48
+ 如果使用 nvm 后 `node -v` 仍然显示旧版本,关闭终端,重新打开后运行:
49
49
 
50
50
  ```bash
51
51
  nvm use 24
@@ -18,7 +18,7 @@ journalctl --user -u foxclaw.service -f
18
18
 
19
19
  | 现象 | 含义 | 处理方式 |
20
20
  | --- | --- | --- |
21
- | `[FAIL] node >= 24` | 当前 shell 使用的是旧版 Node.js。 | 运行 `nvm install 24 && nvm use 24`,再重新执行 `foxclaw doctor`。如果服务仍用旧 Node,从 Node 24 的 shell 里重新执行 `foxclaw start`。 |
21
+ | `[FAIL] node >= 24` | 当前 shell 使用的是旧版 Node.js。 | 先用任意方式安装或切换到 Node.js 24+,再重新执行 `foxclaw doctor`。如果服务仍用旧 Node,从 Node 24+ 的 shell 里重新执行 `foxclaw start`。 |
22
22
  | `[FAIL] codex cli available` | `codex` 命令不在 PATH 里。 | 安装 Codex CLI 或修正 PATH,再确认 `codex --version` 可用。 |
23
23
  | `[FAIL] telegram bot token configured` | `.env` 里缺少 `TG_BOT_TOKEN`。 | 从 `@BotFather` 复制 token,填入 `.env`。 |
24
24
  | `[FAIL] telegram allowed user configured` | `.env` 里缺少 `TG_ALLOWED_USER_ID`。 | 从 `@userinfobot` 获取数字 ID,填入 `.env`。 |
@@ -26,7 +26,7 @@ journalctl --user -u foxclaw.service -f
26
26
 
27
27
  ## Node 或 npm 不存在
28
28
 
29
- 如果看到 `node: command not found` 或 `npm: command not found`,用 `nvm` 安装 Node.js 24
29
+ 如果看到 `node: command not found` 或 `npm: command not found`,先用你习惯的方式安装 Node.js 24+,例如 nvm、fnm、asdf、mise、Volta、Homebrew 或系统包管理器。下面是 nvm 示例:
30
30
 
31
31
  ```bash
32
32
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
@@ -38,7 +38,7 @@ node -v
38
38
  npm -v
39
39
  ```
40
40
 
41
- 如果仍然失败,关闭终端,重新打开后运行:
41
+ 如果使用 nvm 后仍然失败,关闭终端,重新打开后运行:
42
42
 
43
43
  ```bash
44
44
  nvm use 24
@@ -48,7 +48,7 @@ nvm use 24
48
48
 
49
49
  如果 `npm install -g @openai/codex` 或 `npm install -g @foxden-app/foxclaw` 报 `EACCES`、`EPERM`、`permission denied`,说明当前全局 npm 目录不可写。
50
50
 
51
- 推荐处理方式是通过 `nvm` 使用用户级 Node,然后重新安装:
51
+ 推荐处理方式是使用一个用户级 Node.js 24+,然后重新安装。下面是 nvm 示例:
52
52
 
53
53
  ```bash
54
54
  nvm install 24
@@ -57,7 +57,7 @@ npm install -g @openai/codex
57
57
  npm install -g @foxden-app/foxclaw
58
58
  ```
59
59
 
60
- 除非你很清楚本机 Node 的安装方式,否则不要直接混用 `sudo npm install -g ...`。`sudo`、系统 Node `nvm` 混在一起,常见结果是 PATH 断掉或服务启动时找不到命令。
60
+ 除非你很清楚本机 Node 的安装方式,否则不要直接混用 `sudo npm install -g ...`。`sudo`、系统 Node 和用户级 Node 管理器混在一起,常见结果是 PATH 断掉或服务启动时找不到命令。
61
61
 
62
62
  如果 `codex` 已安装但 FoxClaw 找不到它,先定位二进制:
63
63
 
@@ -193,6 +193,8 @@ tail -f ~/.foxclaw/logs/service.log
193
193
  systemctl --user cat foxclaw.service
194
194
  ```
195
195
 
196
+ `foxclaw init` 会检测当前 shell 里的代理环境变量,并询问是否保存到 FoxClaw `.env`。如果你跳过了这一步,`foxclaw doctor` 会在发现“shell 有代理,但 FoxClaw env 没有代理”时给出 `[WARN]`。
197
+
196
198
  确认 `Environment=FOXCLAW_ENV=...` 指向的文件里有你的代理配置,例如:
197
199
 
198
200
  ```dotenv
@@ -210,7 +212,9 @@ foxclaw restart
210
212
 
211
213
  ## 服务用了错误的 Node 版本
212
214
 
213
- systemd 安装脚本会记录当时 PATH 里的 `node`。如果你从 Node 22 或更旧版本的 shell 里安装过服务,请从 Node 24 的 shell 重新安装:
215
+ systemd 安装脚本会记录当时正在运行的 Node 绝对路径,不依赖 systemd 去加载 `nvm.sh` 或其它 shell 初始化脚本。无论你用 nvm、fnm、asdf、mise、Volta、Homebrew 还是系统 Node,原则都是:从 Node 24+ 的 shell 里执行 `foxclaw start`,服务之后就固定使用这个 Node 24+ 路径。
216
+
217
+ 如果你从 Node 22 或更旧版本的 shell 里安装过服务,请从 Node 24+ 的 shell 重新安装。nvm 用户示例:
214
218
 
215
219
  ```bash
216
220
  nvm use 24
@@ -218,7 +222,7 @@ foxclaw start
218
222
  systemctl --user status foxclaw.service
219
223
  ```
220
224
 
221
- 状态输出里应该能看到 Node 24 的路径。
225
+ 状态输出里应该能看到 Node 24+ 的路径。`foxclaw doctor` 也会检查已安装服务里的 Node 路径,如果发现路径不存在或版本低于 24,会提示重新运行 `foxclaw start`。
222
226
 
223
227
  ## 重启后是否会自动运行
224
228
 
@@ -16,15 +16,15 @@ FoxClaw 把本机 Codex 包成一个可从手机控制的服务。Telegram 或
16
16
 
17
17
  ## 1. 完整安装流程
18
18
 
19
- ### 1.1 安装 Node.js 24
19
+ ### 1.1 安装 Node.js 24+
20
20
 
21
- FoxClaw 需要 Node.js 24。先检查:
21
+ FoxClaw 需要 Node.js 24+,不强依赖 nvm。先检查:
22
22
 
23
23
  ```bash
24
24
  node -v
25
25
  ```
26
26
 
27
- 如果不是 `v24...`,推荐用 `nvm`:
27
+ 如果不是 `v24...` 或更高版本,可以用 nvm、fnm、asdf、mise、Volta、Homebrew 或系统包管理器安装 Node 24+。下面是 nvm 示例:
28
28
 
29
29
  ```bash
30
30
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
@@ -100,7 +100,7 @@ foxclaw init
100
100
 
101
101
  ### 1.6 填写配置
102
102
 
103
- `foxclaw init` 会创建默认配置文件 `~/.foxclaw/.env`,并提示填写 Telegram bot token、Telegram 数字用户 ID 和默认工作目录。任何一项都可以直接回车跳过,之后再手动编辑:
103
+ `foxclaw init` 会创建默认配置文件 `~/.foxclaw/.env`,并提示填写 Telegram bot token、Telegram 数字用户 ID 和默认工作目录。如果当前 shell 里有 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 等代理变量,它也会询问是否写入 FoxClaw 配置,让服务里的 Codex app-server 使用同样的网络。任何一项都可以直接回车跳过,之后再手动编辑:
104
104
 
105
105
  ```bash
106
106
  $EDITOR ~/.foxclaw/.env
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foxden-app/foxclaw",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Foxden local execution claw for controlling Codex from trusted chat interfaces.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",