@foxden-app/foxclaw 0.3.1 → 0.3.3
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 +11 -22
- package/README_EN.md +12 -23
- package/dist/main.js +176 -10
- package/docs/agent-assisted-install.md +1 -24
- package/docs/assets/telegram-preview-en.svg +95 -0
- package/docs/assets/telegram-preview-zh.svg +95 -0
- package/docs/install-for-beginners.md +2 -2
- package/docs/troubleshooting.md +3 -24
- package/docs/user-manual.md +1 -1
- package/docs/zh/agent-assisted-install.md +1 -24
- package/docs/zh/install-for-beginners.md +5 -14
- package/docs/zh/troubleshooting.md +3 -9
- package/docs/zh/user-manual.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,6 +26,12 @@ FoxClaw(狸爪)的目标很直接:让你用手机控制本机的 Codex,
|
|
|
26
26
|
- 🔒 代码、shell、认证、审批、运行数据全部留在本机,不暴露到公网
|
|
27
27
|
- 👤 只允许一个受信任的 Telegram 用户远程操作
|
|
28
28
|
|
|
29
|
+
## 功能预览
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
手机端不是简单转发消息,而是给 Codex 的常用工作流做了 Telegram 面板:`/setup` 调模型、推理强度、Fast tier、权限和 Agent/Plan 模式;`/auth` 管理多个 Codex 登录候选,触发限制时自动轮转;`/threads`、`/watch` 和审批按钮用于切线程、观察进度和处理权限请求。
|
|
34
|
+
|
|
29
35
|
## 从这里开始
|
|
30
36
|
|
|
31
37
|
- 手头有 Codex、OpenClaw、QwenPaw、Hermes、OpenCode、Kimi CLI 之类能跑 shell 的 agent?推荐走 [Agent 辅助安装](./docs/zh/agent-assisted-install.md)。
|
|
@@ -51,7 +57,6 @@ FoxClaw(狸爪)的目标很直接:让你用手机控制本机的 Codex,
|
|
|
51
57
|
```bash
|
|
52
58
|
npm install -g @foxden-app/foxclaw
|
|
53
59
|
foxclaw init
|
|
54
|
-
$EDITOR ~/.foxclaw/.env
|
|
55
60
|
foxclaw doctor
|
|
56
61
|
foxclaw start
|
|
57
62
|
```
|
|
@@ -61,11 +66,12 @@ pnpm 用户:
|
|
|
61
66
|
```bash
|
|
62
67
|
pnpm add -g @foxden-app/foxclaw
|
|
63
68
|
foxclaw init
|
|
64
|
-
$EDITOR ~/.foxclaw/.env
|
|
65
69
|
foxclaw doctor
|
|
66
70
|
foxclaw start
|
|
67
71
|
```
|
|
68
72
|
|
|
73
|
+
`foxclaw init` 会创建 `~/.foxclaw/.env`,并在终端里提示填写 Telegram bot token、Telegram 数字用户 ID 和默认工作目录。任何一项都可以直接回车跳过,之后再用 `$EDITOR ~/.foxclaw/.env` 手动修改。
|
|
74
|
+
|
|
69
75
|
跑 `doctor` 或 `start` 之前先把 `.env` 填好。私聊模式最小配置:
|
|
70
76
|
|
|
71
77
|
```dotenv
|
|
@@ -165,26 +171,9 @@ foxclaw serve
|
|
|
165
171
|
|
|
166
172
|
可通过 `STORE_PATH`、`LOCK_PATH`、`CODEX_APP_SERVER_STATE_PATH`、`CODEX_APP_SERVER_LOG_PATH` 覆盖。
|
|
167
173
|
|
|
168
|
-
##
|
|
169
|
-
|
|
170
|
-
FoxClaw 最初 fork 自 `Gan-Xing/telegram-codex-app-bridge`,继续以 MIT License 分发。
|
|
171
|
-
|
|
172
|
-
升级已有安装:
|
|
173
|
-
|
|
174
|
-
```bash
|
|
175
|
-
systemctl --user disable --now telegram-codex-app-bridge.service 2>/dev/null || true
|
|
176
|
-
test -e ~/.foxclaw || cp -a ~/.telegram-codex-app-bridge ~/.foxclaw
|
|
177
|
-
foxclaw start
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
macOS launchd 用户先卸载旧 plist:
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
launchctl unload ~/Library/LaunchAgents/com.ganxing.telegram-codex-app-bridge.plist 2>/dev/null || true
|
|
184
|
-
foxclaw start
|
|
185
|
-
```
|
|
174
|
+
## 鸣谢
|
|
186
175
|
|
|
187
|
-
|
|
176
|
+
FoxClaw 最初基于 `Gan-Xing/telegram-codex-app-bridge` fork 演进而来,继续以 MIT License 分发。感谢原项目对 Telegram 与 Codex 本地桥接思路的探索。
|
|
188
177
|
|
|
189
178
|
## Telegram 设置
|
|
190
179
|
|
|
@@ -292,7 +281,7 @@ foxclaw weixin-login
|
|
|
292
281
|
|
|
293
282
|
## 故障排查
|
|
294
283
|
|
|
295
|
-
`doctor` 报错、Telegram
|
|
284
|
+
`doctor` 报错、Telegram 没回复、服务日志看不懂、重启行为异常——都看 [故障排查](./docs/zh/troubleshooting.md)。
|
|
296
285
|
|
|
297
286
|
## 运维命令
|
|
298
287
|
|
package/README_EN.md
CHANGED
|
@@ -26,6 +26,12 @@ No public server required. FoxClaw runs on your own computer, talks to `codex ap
|
|
|
26
26
|
- 🔒 Code, shell, auth, approvals, and runtime data stay on your machine — nothing exposed to the public internet
|
|
27
27
|
- 👤 Only one trusted Telegram user can operate the bot
|
|
28
28
|
|
|
29
|
+
## Feature Preview
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
FoxClaw is more than message forwarding. It provides Telegram panels for Codex workflows: `/setup` adjusts model, reasoning, Fast tier, access, and Agent/Plan mode; `/auth` manages multiple Codex auth candidates and rotates them on usage limits; `/threads`, `/watch`, and approval buttons handle thread switching, progress monitoring, and permission requests.
|
|
34
|
+
|
|
29
35
|
## Start Here
|
|
30
36
|
|
|
31
37
|
- Already have a shell-capable agent such as Codex, OpenClaw, QwenPaw, Hermes, OpenCode, or Kimi CLI? Use the [Agent-Assisted Install](./docs/agent-assisted-install.md) first. This is the recommended path.
|
|
@@ -51,7 +57,6 @@ The minimum install needs only a Telegram bot token, your numeric Telegram user
|
|
|
51
57
|
```bash
|
|
52
58
|
npm install -g @foxden-app/foxclaw
|
|
53
59
|
foxclaw init
|
|
54
|
-
$EDITOR ~/.foxclaw/.env
|
|
55
60
|
foxclaw doctor
|
|
56
61
|
foxclaw start
|
|
57
62
|
```
|
|
@@ -61,12 +66,13 @@ pnpm users:
|
|
|
61
66
|
```bash
|
|
62
67
|
pnpm add -g @foxden-app/foxclaw
|
|
63
68
|
foxclaw init
|
|
64
|
-
$EDITOR ~/.foxclaw/.env
|
|
65
69
|
foxclaw doctor
|
|
66
70
|
foxclaw start
|
|
67
71
|
```
|
|
68
72
|
|
|
69
|
-
|
|
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`.
|
|
74
|
+
|
|
75
|
+
Fill `.env` before running `doctor` or `start`. Minimum private-chat config:
|
|
70
76
|
|
|
71
77
|
```dotenv
|
|
72
78
|
TG_BOT_TOKEN=123456:telegram-token
|
|
@@ -165,26 +171,9 @@ Default runtime files are stored under `~/.foxclaw`:
|
|
|
165
171
|
|
|
166
172
|
Override with `STORE_PATH`, `LOCK_PATH`, `CODEX_APP_SERVER_STATE_PATH`, and `CODEX_APP_SERVER_LOG_PATH`.
|
|
167
173
|
|
|
168
|
-
##
|
|
169
|
-
|
|
170
|
-
FoxClaw was originally forked from `Gan-Xing/telegram-codex-app-bridge` and remains distributed under the MIT License.
|
|
171
|
-
|
|
172
|
-
When upgrading an existing local install:
|
|
173
|
-
|
|
174
|
-
```bash
|
|
175
|
-
systemctl --user disable --now telegram-codex-app-bridge.service 2>/dev/null || true
|
|
176
|
-
test -e ~/.foxclaw || cp -a ~/.telegram-codex-app-bridge ~/.foxclaw
|
|
177
|
-
foxclaw start
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
For launchd installs, unload the old plist if present:
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
launchctl unload ~/Library/LaunchAgents/com.ganxing.telegram-codex-app-bridge.plist 2>/dev/null || true
|
|
184
|
-
foxclaw start
|
|
185
|
-
```
|
|
174
|
+
## Acknowledgements
|
|
186
175
|
|
|
187
|
-
|
|
176
|
+
FoxClaw originally evolved from a fork of `Gan-Xing/telegram-codex-app-bridge` and remains distributed under the MIT License. Thanks to that project for exploring the Telegram-to-local-Codex bridge pattern.
|
|
188
177
|
|
|
189
178
|
## Telegram Setup
|
|
190
179
|
|
|
@@ -292,7 +281,7 @@ This repo ships a Codex skill at [`skills/foxclaw`](./skills/foxclaw). Use it wh
|
|
|
292
281
|
|
|
293
282
|
## Troubleshooting
|
|
294
283
|
|
|
295
|
-
See [Troubleshooting](./docs/troubleshooting.md) for `doctor` failures, Telegram no-reply cases, service logs, reboot behavior
|
|
284
|
+
See [Troubleshooting](./docs/troubleshooting.md) for `doctor` failures, Telegram no-reply cases, service logs, and reboot behavior.
|
|
296
285
|
|
|
297
286
|
## Operations
|
|
298
287
|
|
package/dist/main.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import process from 'node:process';
|
|
5
|
+
import { createInterface } from 'node:readline/promises';
|
|
5
6
|
import { spawnSync } from 'node:child_process';
|
|
6
7
|
import { fileURLToPath } from 'node:url';
|
|
7
8
|
import { APP_HOME, DEFAULT_ENV_PATH, DEFAULT_LOG_PATH, DEFAULT_STATUS_PATH, loadConfig, loadEnv, } from './config.js';
|
|
@@ -13,7 +14,7 @@ const packageRoot = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
|
13
14
|
const entryPoint = fileURLToPath(import.meta.url);
|
|
14
15
|
async function main() {
|
|
15
16
|
if (command === 'init') {
|
|
16
|
-
initConfig();
|
|
17
|
+
await initConfig();
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
20
|
if (command === 'install-systemd') {
|
|
@@ -143,17 +144,177 @@ async function runServeCli() {
|
|
|
143
144
|
throw error;
|
|
144
145
|
}
|
|
145
146
|
}
|
|
146
|
-
function initConfig() {
|
|
147
|
+
async function initConfig() {
|
|
147
148
|
const envPath = process.env.FOXCLAW_ENV?.trim() || DEFAULT_ENV_PATH;
|
|
148
149
|
fs.mkdirSync(path.dirname(envPath), { recursive: true });
|
|
149
|
-
|
|
150
|
+
const existed = fs.existsSync(envPath);
|
|
151
|
+
if (existed) {
|
|
150
152
|
console.log(`Config already exists: ${envPath}`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const examplePath = path.join(packageRoot, '.env.example');
|
|
156
|
+
fs.copyFileSync(examplePath, envPath);
|
|
157
|
+
console.log(`Created ${envPath}`);
|
|
158
|
+
}
|
|
159
|
+
if (!canPromptForInit()) {
|
|
160
|
+
console.log(`Edit it manually, then run: foxclaw doctor`);
|
|
151
161
|
return;
|
|
152
162
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
163
|
+
await configureEnvInteractively(envPath, existed);
|
|
164
|
+
}
|
|
165
|
+
function canPromptForInit() {
|
|
166
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY && !process.argv.includes('--no-input') && !process.argv.includes('--skip-prompts'));
|
|
167
|
+
}
|
|
168
|
+
async function configureEnvInteractively(envPath, existed) {
|
|
169
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
170
|
+
try {
|
|
171
|
+
if (existed) {
|
|
172
|
+
const updateExisting = (await rl.question('Update Telegram/workspace setup fields now? [y/N]: ')).trim().toLowerCase();
|
|
173
|
+
if (updateExisting !== 'y' && updateExisting !== 'yes') {
|
|
174
|
+
console.log(`Edit it manually, then run: foxclaw doctor`);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
console.log('Interactive setup. Press Enter to skip any field and edit it later.');
|
|
180
|
+
}
|
|
181
|
+
const updates = {};
|
|
182
|
+
const skipped = [];
|
|
183
|
+
const warnings = [];
|
|
184
|
+
const token = sanitizeEnvInput(await rl.question('Telegram bot token (TG_BOT_TOKEN): '));
|
|
185
|
+
if (token) {
|
|
186
|
+
updates.TG_BOT_TOKEN = token;
|
|
187
|
+
if (!/^\d+:[A-Za-z0-9_-]+$/.test(token)) {
|
|
188
|
+
warnings.push('TG_BOT_TOKEN does not look like a standard Telegram bot token.');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
skipped.push('TG_BOT_TOKEN');
|
|
193
|
+
}
|
|
194
|
+
const userId = sanitizeEnvInput(await rl.question('Telegram numeric user ID (TG_ALLOWED_USER_ID): '));
|
|
195
|
+
if (userId) {
|
|
196
|
+
if (/^\d+$/.test(userId)) {
|
|
197
|
+
updates.TG_ALLOWED_USER_ID = userId;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
skipped.push('TG_ALLOWED_USER_ID');
|
|
201
|
+
warnings.push('TG_ALLOWED_USER_ID must be numeric; use the Id from @userinfobot, not @username.');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
skipped.push('TG_ALLOWED_USER_ID');
|
|
206
|
+
}
|
|
207
|
+
const cwdDefault = defaultInitCwd();
|
|
208
|
+
const cwdPrompt = cwdDefault
|
|
209
|
+
? `Default Codex workspace (DEFAULT_CWD) [${cwdDefault}]: `
|
|
210
|
+
: 'Default Codex workspace (DEFAULT_CWD): ';
|
|
211
|
+
const cwdAnswer = sanitizeEnvInput(await rl.question(cwdPrompt));
|
|
212
|
+
const cwd = cwdAnswer ? normalizeUserPath(cwdAnswer) : cwdDefault;
|
|
213
|
+
if (cwd) {
|
|
214
|
+
updates.DEFAULT_CWD = cwd;
|
|
215
|
+
warnings.push(...validateDefaultCwd(cwd));
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
skipped.push('DEFAULT_CWD');
|
|
219
|
+
}
|
|
220
|
+
const codexBin = resolveCommand('codex');
|
|
221
|
+
if (codexBin) {
|
|
222
|
+
updates.CODEX_CLI_BIN = codexBin;
|
|
223
|
+
}
|
|
224
|
+
const updatedKeys = Object.keys(updates);
|
|
225
|
+
if (updatedKeys.length > 0) {
|
|
226
|
+
writeEnvUpdates(envPath, updates);
|
|
227
|
+
console.log(`Saved ${updatedKeys.join(', ')} to ${envPath}`);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
console.log('No setup fields changed.');
|
|
231
|
+
}
|
|
232
|
+
for (const warning of warnings) {
|
|
233
|
+
console.log(`[WARN] ${warning}`);
|
|
234
|
+
}
|
|
235
|
+
if (skipped.length > 0) {
|
|
236
|
+
console.log(`Skipped ${skipped.join(', ')}. Edit later: ${editorCommand(envPath)}`);
|
|
237
|
+
}
|
|
238
|
+
console.log('Next: foxclaw doctor');
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
rl.close();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function sanitizeEnvInput(value) {
|
|
245
|
+
return value.replace(/[\r\n]/g, '').trim();
|
|
246
|
+
}
|
|
247
|
+
function defaultInitCwd() {
|
|
248
|
+
const cwd = path.resolve(process.cwd());
|
|
249
|
+
if (isUnsafeDefaultCwd(cwd))
|
|
250
|
+
return null;
|
|
251
|
+
try {
|
|
252
|
+
if (fs.statSync(cwd).isDirectory())
|
|
253
|
+
return cwd;
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
function normalizeUserPath(value) {
|
|
261
|
+
const expanded = value === '~' || value.startsWith('~/')
|
|
262
|
+
? path.join(process.env.HOME || '', value.slice(2))
|
|
263
|
+
: value;
|
|
264
|
+
return path.resolve(expanded);
|
|
265
|
+
}
|
|
266
|
+
function validateDefaultCwd(cwd) {
|
|
267
|
+
const warnings = [];
|
|
268
|
+
if (!path.isAbsolute(cwd)) {
|
|
269
|
+
warnings.push('DEFAULT_CWD should be an absolute path.');
|
|
270
|
+
}
|
|
271
|
+
if (isUnsafeDefaultCwd(cwd)) {
|
|
272
|
+
warnings.push('DEFAULT_CWD points at a very broad directory; use a project/workspace folder for the first install.');
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
if (!fs.statSync(cwd).isDirectory()) {
|
|
276
|
+
warnings.push('DEFAULT_CWD exists but is not a directory.');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
warnings.push('DEFAULT_CWD does not exist yet; create it or edit the path before starting.');
|
|
281
|
+
}
|
|
282
|
+
return warnings;
|
|
283
|
+
}
|
|
284
|
+
function isUnsafeDefaultCwd(cwd) {
|
|
285
|
+
const resolved = path.resolve(cwd);
|
|
286
|
+
const home = process.env.HOME ? path.resolve(process.env.HOME) : '';
|
|
287
|
+
return resolved === path.parse(resolved).root || resolved === home || resolved === '/home' || resolved === '/Users';
|
|
288
|
+
}
|
|
289
|
+
function writeEnvUpdates(envPath, updates) {
|
|
290
|
+
let text = fs.readFileSync(envPath, 'utf8');
|
|
291
|
+
const newline = text.includes('\r\n') ? '\r\n' : '\n';
|
|
292
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
293
|
+
const line = `${key}=${formatEnvValue(value)}`;
|
|
294
|
+
const pattern = new RegExp(`^${escapeRegExp(key)}=.*$`, 'm');
|
|
295
|
+
if (pattern.test(text)) {
|
|
296
|
+
text = text.replace(pattern, line);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
if (text && !text.endsWith('\n') && !text.endsWith('\r\n')) {
|
|
300
|
+
text += newline;
|
|
301
|
+
}
|
|
302
|
+
text += `${line}${newline}`;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
fs.writeFileSync(envPath, text);
|
|
306
|
+
}
|
|
307
|
+
function formatEnvValue(value) {
|
|
308
|
+
const cleaned = value.replace(/[\r\n]/g, '').trim();
|
|
309
|
+
if (!/[\s#"\\]/.test(cleaned))
|
|
310
|
+
return cleaned;
|
|
311
|
+
return `"${cleaned.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
312
|
+
}
|
|
313
|
+
function escapeRegExp(value) {
|
|
314
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
315
|
+
}
|
|
316
|
+
function editorCommand(envPath) {
|
|
317
|
+
return `${process.env.EDITOR?.trim() || '$EDITOR'} ${envPath}`;
|
|
157
318
|
}
|
|
158
319
|
function startService(action) {
|
|
159
320
|
if (!runDoctorChecks()) {
|
|
@@ -463,13 +624,18 @@ void main().catch((error) => {
|
|
|
463
624
|
process.exit(1);
|
|
464
625
|
});
|
|
465
626
|
function hasCommand(commandName) {
|
|
627
|
+
return Boolean(resolveCommand(commandName));
|
|
628
|
+
}
|
|
629
|
+
function resolveCommand(commandName) {
|
|
466
630
|
try {
|
|
467
631
|
const which = process.platform === 'win32' ? 'where' : 'which';
|
|
468
|
-
const result = spawnSync(which, [commandName], {
|
|
469
|
-
|
|
632
|
+
const result = spawnSync(which, [commandName], { encoding: 'utf8' });
|
|
633
|
+
if (result.status !== 0)
|
|
634
|
+
return null;
|
|
635
|
+
return result.stdout.split(/\r?\n/).map(line => line.trim()).find(Boolean) ?? null;
|
|
470
636
|
}
|
|
471
637
|
catch {
|
|
472
|
-
return
|
|
638
|
+
return null;
|
|
473
639
|
}
|
|
474
640
|
}
|
|
475
641
|
function hasConfiguredCodexBin(binPath) {
|
|
@@ -38,7 +38,7 @@ TG_ALLOWED_USER_ID=<paste numeric Telegram user id here>
|
|
|
38
38
|
DEFAULT_CWD=<paste absolute working directory here>
|
|
39
39
|
|
|
40
40
|
Tasks:
|
|
41
|
-
1. Inspect the machine first. If a FoxClaw
|
|
41
|
+
1. Inspect the machine first. If a FoxClaw service already exists, report it before changing services.
|
|
42
42
|
2. Ensure Node.js 24+ is available. If not, install or activate Node 24 with nvm.
|
|
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.
|
|
@@ -48,33 +48,10 @@ Tasks:
|
|
|
48
48
|
8. Ask me to send /help and /status to the Telegram bot.
|
|
49
49
|
9. Verify the final state:
|
|
50
50
|
- foxclaw.service is active/enabled on Linux
|
|
51
|
-
- old telegram-codex-app-bridge.service is inactive/disabled if present
|
|
52
51
|
- foxclaw status works
|
|
53
52
|
10. Report the commands used, the final status, and the log command I should use if something stops working. Redact TG_BOT_TOKEN and never print the full token or full .env content.
|
|
54
53
|
```
|
|
55
54
|
|
|
56
|
-
## Migration Prompt For Old Installs
|
|
57
|
-
|
|
58
|
-
Use this when the target computer is still running `telegram-codex-app-bridge`:
|
|
59
|
-
|
|
60
|
-
```text
|
|
61
|
-
Migrate this machine from telegram-codex-app-bridge to FoxClaw.
|
|
62
|
-
|
|
63
|
-
New package:
|
|
64
|
-
@foxden-app/foxclaw
|
|
65
|
-
|
|
66
|
-
Please:
|
|
67
|
-
1. Inspect the current install method, service file, and runtime directory before changing anything.
|
|
68
|
-
2. Stop and disable telegram-codex-app-bridge.service if it exists.
|
|
69
|
-
3. If ~/.foxclaw does not exist and ~/.telegram-codex-app-bridge exists, copy ~/.telegram-codex-app-bridge to ~/.foxclaw.
|
|
70
|
-
4. Install or update FoxClaw with npm install -g @foxden-app/foxclaw@latest.
|
|
71
|
-
5. Run foxclaw init if ~/.foxclaw/.env does not exist, then verify ~/.foxclaw/.env.
|
|
72
|
-
6. Run foxclaw doctor.
|
|
73
|
-
7. Install or restart the FoxClaw service with foxclaw start.
|
|
74
|
-
8. Verify foxclaw.service is active and telegram-codex-app-bridge.service is inactive/disabled.
|
|
75
|
-
9. Report final status and any blockers. Redact TG_BOT_TOKEN and never print the full token or full .env content.
|
|
76
|
-
```
|
|
77
|
-
|
|
78
55
|
## Safety Notes
|
|
79
56
|
|
|
80
57
|
- Do not paste bot tokens into public issue trackers or public chat logs.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1280" height="760" viewBox="0 0 1280 760" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">FoxClaw Telegram feature preview</title>
|
|
3
|
+
<desc id="desc">Telegram-style preview of FoxClaw setup and auth management panels.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
6
|
+
<feDropShadow dx="0" dy="18" stdDeviation="18" flood-color="#152033" flood-opacity="0.16"/>
|
|
7
|
+
</filter>
|
|
8
|
+
<style>
|
|
9
|
+
.label { font: 600 24px Arial, sans-serif; fill: #111827; }
|
|
10
|
+
.body { font: 500 18px Arial, sans-serif; fill: #243244; }
|
|
11
|
+
.muted { font: 500 15px Arial, sans-serif; fill: #607086; }
|
|
12
|
+
.small { font: 600 14px Arial, sans-serif; fill: #42526a; }
|
|
13
|
+
.button { font: 700 15px Arial, sans-serif; fill: #1f6fb2; }
|
|
14
|
+
.top { font: 700 18px Arial, sans-serif; fill: #fff; }
|
|
15
|
+
.mono { font: 600 16px ui-monospace, SFMono-Regular, Menlo, monospace; fill: #334155; }
|
|
16
|
+
</style>
|
|
17
|
+
</defs>
|
|
18
|
+
<rect width="1280" height="760" rx="0" fill="#f3f7fb"/>
|
|
19
|
+
<circle cx="112" cy="102" r="58" fill="#d7edf9"/>
|
|
20
|
+
<circle cx="1185" cy="660" r="74" fill="#e5f4ec"/>
|
|
21
|
+
<text x="80" y="86" class="label">A mobile control panel for Codex</text>
|
|
22
|
+
<text x="80" y="118" class="body">Send tasks, inspect progress, approve actions, switch threads, and rotate auth accounts from Telegram.</text>
|
|
23
|
+
|
|
24
|
+
<g filter="url(#shadow)" transform="translate(96 164)">
|
|
25
|
+
<rect x="0" y="0" width="520" height="492" rx="36" fill="#17212b"/>
|
|
26
|
+
<rect x="18" y="18" width="484" height="456" rx="28" fill="#dcebf5"/>
|
|
27
|
+
<rect x="18" y="18" width="484" height="58" rx="28" fill="#229ed9"/>
|
|
28
|
+
<text x="48" y="55" class="top">FoxClaw Bot · /setup</text>
|
|
29
|
+
<rect x="44" y="104" width="432" height="236" rx="18" fill="#ffffff"/>
|
|
30
|
+
<text x="70" y="142" class="label">Setup · current thread</text>
|
|
31
|
+
<text x="70" y="176" class="body">Model: GPT-5.5</text>
|
|
32
|
+
<text x="70" y="206" class="body">Reasoning: High</text>
|
|
33
|
+
<text x="70" y="236" class="body">Mode: 📝 Plan</text>
|
|
34
|
+
<text x="70" y="266" class="body">Access: Workspace write</text>
|
|
35
|
+
<text x="70" y="296" class="body">Fast tier: ⚡ enabled</text>
|
|
36
|
+
<text x="70" y="326" class="muted">Each chat/thread can keep its own settings.</text>
|
|
37
|
+
<g transform="translate(44 360)">
|
|
38
|
+
<rect x="0" y="0" width="100" height="42" rx="12" fill="#e9f5ff"/>
|
|
39
|
+
<text x="25" y="27" class="button">⚡ Fast</text>
|
|
40
|
+
<rect x="112" y="0" width="96" height="42" rx="12" fill="#e9f5ff"/>
|
|
41
|
+
<text x="137" y="27" class="button">🔒 Read</text>
|
|
42
|
+
<rect x="220" y="0" width="96" height="42" rx="12" fill="#e9f5ff"/>
|
|
43
|
+
<text x="238" y="27" class="button">✍️ Work</text>
|
|
44
|
+
<rect x="328" y="0" width="104" height="42" rx="12" fill="#e9f5ff"/>
|
|
45
|
+
<text x="350" y="27" class="button">🛠️ Full</text>
|
|
46
|
+
<rect x="0" y="54" width="132" height="42" rx="12" fill="#eaf8ef"/>
|
|
47
|
+
<text x="34" y="81" class="button">📝 Plan</text>
|
|
48
|
+
<rect x="144" y="54" width="132" height="42" rx="12" fill="#eef2ff"/>
|
|
49
|
+
<text x="177" y="81" class="button">Agent</text>
|
|
50
|
+
</g>
|
|
51
|
+
</g>
|
|
52
|
+
|
|
53
|
+
<g filter="url(#shadow)" transform="translate(664 164)">
|
|
54
|
+
<rect x="0" y="0" width="520" height="492" rx="36" fill="#17212b"/>
|
|
55
|
+
<rect x="18" y="18" width="484" height="456" rx="28" fill="#dcebf5"/>
|
|
56
|
+
<rect x="18" y="18" width="484" height="58" rx="28" fill="#229ed9"/>
|
|
57
|
+
<text x="48" y="55" class="top">FoxClaw Bot · /auth</text>
|
|
58
|
+
<rect x="44" y="104" width="432" height="258" rx="18" fill="#ffffff"/>
|
|
59
|
+
<text x="70" y="142" class="label">Auth · account rotation</text>
|
|
60
|
+
<text x="70" y="176" class="body">Current: personal · GPT-5.5</text>
|
|
61
|
+
<text x="70" y="206" class="body">Auto-switches and retries on usage limits.</text>
|
|
62
|
+
<g transform="translate(70 232)">
|
|
63
|
+
<rect x="0" y="0" width="376" height="34" rx="10" fill="#f7fafc"/>
|
|
64
|
+
<text x="14" y="23" class="mono">✅ 1 personal</text>
|
|
65
|
+
<text x="256" y="23" class="small">32% used</text>
|
|
66
|
+
<rect x="0" y="44" width="376" height="34" rx="10" fill="#f7fafc"/>
|
|
67
|
+
<text x="14" y="67" class="mono">✅ 2 team</text>
|
|
68
|
+
<text x="280" y="67" class="small">ready</text>
|
|
69
|
+
<rect x="0" y="88" width="376" height="34" rx="10" fill="#f7fafc"/>
|
|
70
|
+
<text x="14" y="111" class="mono">⏸️ 3 trial</text>
|
|
71
|
+
<text x="256" y="111" class="small">disabled</text>
|
|
72
|
+
</g>
|
|
73
|
+
<g transform="translate(44 386)">
|
|
74
|
+
<rect x="0" y="0" width="120" height="42" rx="12" fill="#e9f5ff"/>
|
|
75
|
+
<text x="31" y="27" class="button">✅ enable</text>
|
|
76
|
+
<rect x="132" y="0" width="120" height="42" rx="12" fill="#fff4e6"/>
|
|
77
|
+
<text x="167" y="27" class="button">⏸️ pause</text>
|
|
78
|
+
<rect x="264" y="0" width="168" height="42" rx="12" fill="#eaf8ef"/>
|
|
79
|
+
<text x="309" y="27" class="button">add auth</text>
|
|
80
|
+
</g>
|
|
81
|
+
</g>
|
|
82
|
+
|
|
83
|
+
<g transform="translate(138 686)">
|
|
84
|
+
<rect x="0" y="-30" width="138" height="46" rx="23" fill="#ffffff"/>
|
|
85
|
+
<text x="25" y="0" class="small">send tasks</text>
|
|
86
|
+
<rect x="160" y="-30" width="150" height="46" rx="23" fill="#ffffff"/>
|
|
87
|
+
<text x="186" y="0" class="small">watch progress</text>
|
|
88
|
+
<rect x="332" y="-30" width="150" height="46" rx="23" fill="#ffffff"/>
|
|
89
|
+
<text x="359" y="0" class="small">tap approvals</text>
|
|
90
|
+
<rect x="504" y="-30" width="150" height="46" rx="23" fill="#ffffff"/>
|
|
91
|
+
<text x="533" y="0" class="small">switch threads</text>
|
|
92
|
+
<rect x="676" y="-30" width="176" height="46" rx="23" fill="#ffffff"/>
|
|
93
|
+
<text x="703" y="0" class="small">rotate accounts</text>
|
|
94
|
+
</g>
|
|
95
|
+
</svg>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1280" height="760" viewBox="0 0 1280 760" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">FoxClaw Telegram 功能预览</title>
|
|
3
|
+
<desc id="desc">Telegram 风格的 FoxClaw setup 和 auth 管理面板示意图。</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
6
|
+
<feDropShadow dx="0" dy="18" stdDeviation="18" flood-color="#152033" flood-opacity="0.16"/>
|
|
7
|
+
</filter>
|
|
8
|
+
<style>
|
|
9
|
+
.label { font: 600 24px Arial, "Noto Sans CJK SC", sans-serif; fill: #111827; }
|
|
10
|
+
.body { font: 500 18px Arial, "Noto Sans CJK SC", sans-serif; fill: #243244; }
|
|
11
|
+
.muted { font: 500 15px Arial, "Noto Sans CJK SC", sans-serif; fill: #607086; }
|
|
12
|
+
.small { font: 600 14px Arial, "Noto Sans CJK SC", sans-serif; fill: #42526a; }
|
|
13
|
+
.button { font: 700 15px Arial, "Noto Sans CJK SC", sans-serif; fill: #1f6fb2; }
|
|
14
|
+
.top { font: 700 18px Arial, "Noto Sans CJK SC", sans-serif; fill: #fff; }
|
|
15
|
+
.mono { font: 600 16px ui-monospace, SFMono-Regular, Menlo, monospace; fill: #334155; }
|
|
16
|
+
</style>
|
|
17
|
+
</defs>
|
|
18
|
+
<rect width="1280" height="760" rx="0" fill="#f3f7fb"/>
|
|
19
|
+
<circle cx="112" cy="102" r="58" fill="#d7edf9"/>
|
|
20
|
+
<circle cx="1185" cy="660" r="74" fill="#e5f4ec"/>
|
|
21
|
+
<text x="80" y="86" class="label">手机上的 Codex 控制台</text>
|
|
22
|
+
<text x="80" y="118" class="body">发任务、看进度、点审批、切线程、轮转账号,都在 Telegram 面板里完成。</text>
|
|
23
|
+
|
|
24
|
+
<g filter="url(#shadow)" transform="translate(96 164)">
|
|
25
|
+
<rect x="0" y="0" width="520" height="492" rx="36" fill="#17212b"/>
|
|
26
|
+
<rect x="18" y="18" width="484" height="456" rx="28" fill="#dcebf5"/>
|
|
27
|
+
<rect x="18" y="18" width="484" height="58" rx="28" fill="#229ed9"/>
|
|
28
|
+
<text x="48" y="55" class="top">FoxClaw Bot · /setup</text>
|
|
29
|
+
<rect x="44" y="104" width="432" height="236" rx="18" fill="#ffffff"/>
|
|
30
|
+
<text x="70" y="142" class="label">Setup · 当前线程</text>
|
|
31
|
+
<text x="70" y="176" class="body">模型:GPT-5.5</text>
|
|
32
|
+
<text x="70" y="206" class="body">推理强度:High</text>
|
|
33
|
+
<text x="70" y="236" class="body">模式:📝 Plan</text>
|
|
34
|
+
<text x="70" y="266" class="body">权限:Workspace write</text>
|
|
35
|
+
<text x="70" y="296" class="body">Fast tier:⚡ 开启</text>
|
|
36
|
+
<text x="70" y="326" class="muted">每个聊天/线程都可以独立配置。</text>
|
|
37
|
+
<g transform="translate(44 360)">
|
|
38
|
+
<rect x="0" y="0" width="100" height="42" rx="12" fill="#e9f5ff"/>
|
|
39
|
+
<text x="25" y="27" class="button">⚡ Fast</text>
|
|
40
|
+
<rect x="112" y="0" width="96" height="42" rx="12" fill="#e9f5ff"/>
|
|
41
|
+
<text x="135" y="27" class="button">🔒 只读</text>
|
|
42
|
+
<rect x="220" y="0" width="96" height="42" rx="12" fill="#e9f5ff"/>
|
|
43
|
+
<text x="239" y="27" class="button">✍️ 默认</text>
|
|
44
|
+
<rect x="328" y="0" width="104" height="42" rx="12" fill="#e9f5ff"/>
|
|
45
|
+
<text x="345" y="27" class="button">🛠️ 完全</text>
|
|
46
|
+
<rect x="0" y="54" width="132" height="42" rx="12" fill="#eaf8ef"/>
|
|
47
|
+
<text x="34" y="81" class="button">📝 Plan</text>
|
|
48
|
+
<rect x="144" y="54" width="132" height="42" rx="12" fill="#eef2ff"/>
|
|
49
|
+
<text x="177" y="81" class="button">Agent</text>
|
|
50
|
+
</g>
|
|
51
|
+
</g>
|
|
52
|
+
|
|
53
|
+
<g filter="url(#shadow)" transform="translate(664 164)">
|
|
54
|
+
<rect x="0" y="0" width="520" height="492" rx="36" fill="#17212b"/>
|
|
55
|
+
<rect x="18" y="18" width="484" height="456" rx="28" fill="#dcebf5"/>
|
|
56
|
+
<rect x="18" y="18" width="484" height="58" rx="28" fill="#229ed9"/>
|
|
57
|
+
<text x="48" y="55" class="top">FoxClaw Bot · /auth</text>
|
|
58
|
+
<rect x="44" y="104" width="432" height="258" rx="18" fill="#ffffff"/>
|
|
59
|
+
<text x="70" y="142" class="label">Auth · 多账号轮转</text>
|
|
60
|
+
<text x="70" y="176" class="body">当前:personal · GPT-5.5</text>
|
|
61
|
+
<text x="70" y="206" class="body">限制触发时自动切换并重试。</text>
|
|
62
|
+
<g transform="translate(70 232)">
|
|
63
|
+
<rect x="0" y="0" width="376" height="34" rx="10" fill="#f7fafc"/>
|
|
64
|
+
<text x="14" y="23" class="mono">✅ 1 personal</text>
|
|
65
|
+
<text x="256" y="23" class="small">32% used</text>
|
|
66
|
+
<rect x="0" y="44" width="376" height="34" rx="10" fill="#f7fafc"/>
|
|
67
|
+
<text x="14" y="67" class="mono">✅ 2 team</text>
|
|
68
|
+
<text x="280" y="67" class="small">ready</text>
|
|
69
|
+
<rect x="0" y="88" width="376" height="34" rx="10" fill="#f7fafc"/>
|
|
70
|
+
<text x="14" y="111" class="mono">⏸️ 3 trial</text>
|
|
71
|
+
<text x="256" y="111" class="small">disabled</text>
|
|
72
|
+
</g>
|
|
73
|
+
<g transform="translate(44 386)">
|
|
74
|
+
<rect x="0" y="0" width="120" height="42" rx="12" fill="#e9f5ff"/>
|
|
75
|
+
<text x="31" y="27" class="button">✅ 启用</text>
|
|
76
|
+
<rect x="132" y="0" width="120" height="42" rx="12" fill="#fff4e6"/>
|
|
77
|
+
<text x="163" y="27" class="button">⏸️ 暂停</text>
|
|
78
|
+
<rect x="264" y="0" width="168" height="42" rx="12" fill="#eaf8ef"/>
|
|
79
|
+
<text x="307" y="27" class="button">添加账号</text>
|
|
80
|
+
</g>
|
|
81
|
+
</g>
|
|
82
|
+
|
|
83
|
+
<g transform="translate(158 686)">
|
|
84
|
+
<rect x="0" y="-30" width="138" height="46" rx="23" fill="#ffffff"/>
|
|
85
|
+
<text x="25" y="0" class="small">发任务</text>
|
|
86
|
+
<rect x="160" y="-30" width="138" height="46" rx="23" fill="#ffffff"/>
|
|
87
|
+
<text x="185" y="0" class="small">看进度</text>
|
|
88
|
+
<rect x="320" y="-30" width="138" height="46" rx="23" fill="#ffffff"/>
|
|
89
|
+
<text x="345" y="0" class="small">点审批</text>
|
|
90
|
+
<rect x="480" y="-30" width="138" height="46" rx="23" fill="#ffffff"/>
|
|
91
|
+
<text x="505" y="0" class="small">切线程</text>
|
|
92
|
+
<rect x="640" y="-30" width="168" height="46" rx="23" fill="#ffffff"/>
|
|
93
|
+
<text x="675" y="0" class="small">多账号轮转</text>
|
|
94
|
+
</g>
|
|
95
|
+
</svg>
|
|
@@ -123,7 +123,7 @@ npm install -g @foxden-app/foxclaw
|
|
|
123
123
|
foxclaw init
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
This creates the config file at `~/.foxclaw/.env
|
|
126
|
+
This creates the config file at `~/.foxclaw/.env` and prompts for the Telegram bot token, your numeric Telegram user id, and the default workspace.
|
|
127
127
|
|
|
128
128
|
If you prefer pnpm:
|
|
129
129
|
|
|
@@ -134,7 +134,7 @@ foxclaw init
|
|
|
134
134
|
|
|
135
135
|
## 7. Fill In `.env`
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
If you filled the token, user id, and workspace during `foxclaw init`, go straight to the first check. If you skipped a field or want to change anything, open `.env` in a simple editor:
|
|
138
138
|
|
|
139
139
|
```bash
|
|
140
140
|
nano ~/.foxclaw/.env
|
package/docs/troubleshooting.md
CHANGED
|
@@ -129,20 +129,14 @@ If FoxClaw is still running, it may consume the update before you inspect it.
|
|
|
129
129
|
|
|
130
130
|
If Telegram reports conflicts or the same bot behaves strangely, two processes may be polling the same bot token.
|
|
131
131
|
|
|
132
|
-
Check
|
|
132
|
+
Check the service and any extra foreground processes:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
135
|
systemctl --user is-active foxclaw.service
|
|
136
|
-
|
|
136
|
+
pgrep -af foxclaw
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
Stop the
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
systemctl --user disable --now telegram-codex-app-bridge.service
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Then restart FoxClaw:
|
|
139
|
+
Stop the extra process or service, then restart FoxClaw:
|
|
146
140
|
|
|
147
141
|
```bash
|
|
148
142
|
foxclaw restart
|
|
@@ -219,18 +213,3 @@ macOS launchd starts FoxClaw when you log in after running:
|
|
|
219
213
|
```bash
|
|
220
214
|
foxclaw start
|
|
221
215
|
```
|
|
222
|
-
|
|
223
|
-
## Migrating From The Old Project Name
|
|
224
|
-
|
|
225
|
-
If this machine still runs `telegram-codex-app-bridge`, migrate once:
|
|
226
|
-
|
|
227
|
-
```bash
|
|
228
|
-
systemctl --user disable --now telegram-codex-app-bridge.service 2>/dev/null || true
|
|
229
|
-
test -e ~/.foxclaw || cp -a ~/.telegram-codex-app-bridge ~/.foxclaw
|
|
230
|
-
npm install -g @foxden-app/foxclaw@latest
|
|
231
|
-
foxclaw init
|
|
232
|
-
foxclaw doctor
|
|
233
|
-
foxclaw start
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
If `~/.foxclaw/.env` already exists, `foxclaw init` leaves it untouched.
|
package/docs/user-manual.md
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
104
104
|
|
|
105
105
|
```bash
|
|
106
106
|
$EDITOR ~/.foxclaw/.env
|
|
@@ -37,7 +37,7 @@ TG_ALLOWED_USER_ID=<把 Telegram 数字用户 ID 粘贴在这里>
|
|
|
37
37
|
DEFAULT_CWD=<把绝对工作目录粘贴在这里>
|
|
38
38
|
|
|
39
39
|
任务:
|
|
40
|
-
1. 先检查机器环境。如果已经存在 FoxClaw
|
|
40
|
+
1. 先检查机器环境。如果已经存在 FoxClaw 服务,先报告再改服务。
|
|
41
41
|
2. 确保 Node.js 24+ 可用;如果没有,请用 nvm 安装或切到 Node 24。
|
|
42
42
|
3. 确保 Codex CLI 存在并且已经登录。如果需要登录,停下来告诉我具体要执行什么。
|
|
43
43
|
4. 用 npm install -g @foxden-app/foxclaw@latest 安装或升级 FoxClaw。
|
|
@@ -47,33 +47,10 @@ DEFAULT_CWD=<把绝对工作目录粘贴在这里>
|
|
|
47
47
|
8. 让我在 Telegram bot 里发送 /help 和 /status。
|
|
48
48
|
9. 验证最终状态:
|
|
49
49
|
- Linux 上 foxclaw.service 处于 active/enabled
|
|
50
|
-
- 如果存在旧 telegram-codex-app-bridge.service,它应当 inactive/disabled
|
|
51
50
|
- foxclaw status 可以正常输出
|
|
52
51
|
10. 汇报执行过的命令、最终状态和后续看日志的命令。请隐藏 TG_BOT_TOKEN,不要打印完整 token 或完整 .env。
|
|
53
52
|
```
|
|
54
53
|
|
|
55
|
-
## 旧项目迁移提示词
|
|
56
|
-
|
|
57
|
-
如果目标机器还在跑 `telegram-codex-app-bridge`,用这段:
|
|
58
|
-
|
|
59
|
-
```text
|
|
60
|
-
请把这台机器从 telegram-codex-app-bridge 迁移到 FoxClaw。
|
|
61
|
-
|
|
62
|
-
新发布包:
|
|
63
|
-
@foxden-app/foxclaw
|
|
64
|
-
|
|
65
|
-
请执行:
|
|
66
|
-
1. 修改前先检查现有安装方式、服务文件和运行目录。
|
|
67
|
-
2. 如果存在 telegram-codex-app-bridge.service,停止并禁用它。
|
|
68
|
-
3. 如果 ~/.foxclaw 不存在而 ~/.telegram-codex-app-bridge 存在,把旧目录复制到 ~/.foxclaw。
|
|
69
|
-
4. 用 npm install -g @foxden-app/foxclaw@latest 安装或升级 FoxClaw。
|
|
70
|
-
5. 如果 ~/.foxclaw/.env 不存在,运行 foxclaw init;然后检查配置是否完整。
|
|
71
|
-
6. 运行 foxclaw doctor。
|
|
72
|
-
7. 用 foxclaw start 安装或重启 FoxClaw 服务。
|
|
73
|
-
8. 验证 foxclaw.service 正常运行,旧 telegram-codex-app-bridge.service 已停止或禁用。
|
|
74
|
-
9. 汇报最终状态和阻塞点。请隐藏 TG_BOT_TOKEN,不要打印完整 token 或完整 .env。
|
|
75
|
-
```
|
|
76
|
-
|
|
77
54
|
## 安全注意事项
|
|
78
55
|
|
|
79
56
|
- 不要把 bot token 粘贴到公开 issue、公开聊天或代码仓库。
|
|
@@ -121,7 +121,7 @@ npm install -g @foxden-app/foxclaw
|
|
|
121
121
|
foxclaw init
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
这会创建默认配置文件 `~/.foxclaw/.env
|
|
124
|
+
这会创建默认配置文件 `~/.foxclaw/.env`,并提示你填写 Telegram bot token、Telegram 数字用户 ID 和默认工作目录。
|
|
125
125
|
|
|
126
126
|
如果你用 pnpm:
|
|
127
127
|
|
|
@@ -132,7 +132,7 @@ foxclaw init
|
|
|
132
132
|
|
|
133
133
|
## 7. 填写 `.env`
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
如果刚才在 `foxclaw init` 里已经填好了 token、用户 ID 和工作目录,可以直接进入下一步检查。如果你选择了跳过,或者想改配置,用简单编辑器打开:
|
|
136
136
|
|
|
137
137
|
```bash
|
|
138
138
|
nano ~/.foxclaw/.env
|
|
@@ -279,20 +279,11 @@ npm install -g @foxden-app/foxclaw@latest
|
|
|
279
279
|
foxclaw start
|
|
280
280
|
```
|
|
281
281
|
|
|
282
|
-
|
|
282
|
+
如果 `~/.foxclaw/.env` 已经存在,`foxclaw init` 会先询问是否更新 Telegram 和工作目录相关字段,其它配置保持不变。
|
|
283
283
|
|
|
284
|
-
|
|
284
|
+
## 鸣谢
|
|
285
285
|
|
|
286
|
-
|
|
287
|
-
systemctl --user disable --now telegram-codex-app-bridge.service 2>/dev/null || true
|
|
288
|
-
test -e ~/.foxclaw || cp -a ~/.telegram-codex-app-bridge ~/.foxclaw
|
|
289
|
-
npm install -g @foxden-app/foxclaw@latest
|
|
290
|
-
foxclaw init
|
|
291
|
-
foxclaw doctor
|
|
292
|
-
foxclaw start
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
如果 `~/.foxclaw/.env` 已经存在,`foxclaw init` 不会覆盖它。
|
|
286
|
+
FoxClaw 最初基于 `Gan-Xing/telegram-codex-app-bridge` fork 演进而来。感谢原项目对 Telegram 与 Codex 本地桥接思路的探索。
|
|
296
287
|
|
|
297
288
|
## 下一步
|
|
298
289
|
|
|
@@ -130,20 +130,14 @@ CODEX_CLI_BIN=/absolute/path/to/codex
|
|
|
130
130
|
|
|
131
131
|
如果 Telegram 报 conflict,或者同一个 bot 行为异常,通常是两个进程在轮询同一个 bot token。
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
检查服务和额外的前台进程:
|
|
134
134
|
|
|
135
135
|
```bash
|
|
136
136
|
systemctl --user is-active foxclaw.service
|
|
137
|
-
|
|
137
|
+
pgrep -af foxclaw
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
systemctl --user disable --now telegram-codex-app-bridge.service
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
然后重启 FoxClaw:
|
|
140
|
+
停掉多余进程或服务后,重启 FoxClaw:
|
|
147
141
|
|
|
148
142
|
```bash
|
|
149
143
|
foxclaw restart
|
package/docs/zh/user-manual.md
CHANGED