@foxden-app/foxclaw 0.4.11 → 0.4.12
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/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/README_EN.md +1 -1
- package/dist/controller/controller.js +13 -3
- package/docs/user-manual.md +6 -6
- package/docs/zh/user-manual.md +6 -6
- package/package.json +1 -1
- package/skills/foxclaw/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable FoxClaw changes are listed here. Each release note is bilingual so GitHub Releases and the npm package are useful to both Chinese and English readers.
|
|
4
4
|
|
|
5
|
+
## 0.4.12 - 2026-06-02
|
|
6
|
+
|
|
7
|
+
### 中文
|
|
8
|
+
- `/auth` 面板顶部、候选列表和切换按钮省略标准候选名中重复的 `auth.json_` 前缀,让额度与账号标识在窄屏 Telegram 客户端中更容易完整显示。
|
|
9
|
+
- 磁盘文件名、文件名搜索、候选编号、切换和镜像同步行为保持不变;非标准候选名仍原样展示。
|
|
10
|
+
|
|
11
|
+
### English
|
|
12
|
+
- Omitted the repeated `auth.json_` prefix from the `/auth` panel header, candidate rows, and switch buttons so quota and account labels fit better in narrow Telegram clients.
|
|
13
|
+
- Kept filenames on disk, filename search, candidate numbering, switching, and mirroring unchanged. Non-standard candidate names still render verbatim.
|
|
14
|
+
|
|
5
15
|
## 0.4.11 - 2026-06-02
|
|
6
16
|
|
|
7
17
|
### 中文
|
package/README.md
CHANGED
|
@@ -128,7 +128,7 @@ FoxClaw 的一大特色是自动多账号切换。当一个账号触发用量限
|
|
|
128
128
|
3. 用 `/auth` 查看所有候选账号状态。
|
|
129
129
|
4. 用 `/auth enable <n>` / `/auth disable <n>` 控制哪些账号参与自动轮换。
|
|
130
130
|
|
|
131
|
-
候选较多时,`/auth` 每页显示 8 个账号,并提供翻页、`全部 / 已启用 / 需关注` 筛选。也可以用 `/auth list <关键词>` 搜索文件名,或用 `/auth page <页码>` 直接跳页。额度窗口按 Codex 实际返回值展示,例如 `5h:20|7d:25` 或单月窗口 `30d:97
|
|
131
|
+
候选较多时,`/auth` 每页显示 8 个账号,并提供翻页、`全部 / 已启用 / 需关注` 筛选。也可以用 `/auth list <关键词>` 搜索文件名,或用 `/auth page <页码>` 直接跳页。额度窗口按 Codex 实际返回值展示,例如 `5h:20|7d:25` 或单月窗口 `30d:97`。面板会省略候选名中重复的 `auth.json_` 前缀,磁盘文件名保持不变。
|
|
132
132
|
|
|
133
133
|
当 Codex 报告用量限制错误时,FoxClaw 会自动:
|
|
134
134
|
- 切换到下一个未失败的候选账号
|
package/README_EN.md
CHANGED
|
@@ -128,7 +128,7 @@ Setup:
|
|
|
128
128
|
3. Use `/auth` to view all candidate account statuses.
|
|
129
129
|
4. Use `/auth enable <n>` / `/auth disable <n>` to control which accounts participate in auto-rotation.
|
|
130
130
|
|
|
131
|
-
For larger inventories, `/auth` shows 8 candidates per page with paging and `All / Enabled / Attention` filters. Use `/auth list <keyword>` to search filenames or `/auth page <n>` to jump directly. Quota windows use the values reported by Codex, for example `5h:20|7d:25` or a single monthly window such as `30d:97`.
|
|
131
|
+
For larger inventories, `/auth` shows 8 candidates per page with paging and `All / Enabled / Attention` filters. Use `/auth list <keyword>` to search filenames or `/auth page <n>` to jump directly. Quota windows use the values reported by Codex, for example `5h:20|7d:25` or a single monthly window such as `30d:97`. The panel omits the repeated `auth.json_` prefix from candidate labels without renaming files on disk.
|
|
132
132
|
|
|
133
133
|
When Codex reports a usage-limit error, FoxClaw automatically:
|
|
134
134
|
- Switches to the next non-failed candidate account
|
|
@@ -7785,7 +7785,11 @@ function renderAuthListMessage(locale, state, botLabel = null, includeWeixinCopy
|
|
|
7785
7785
|
if (botLabel) {
|
|
7786
7786
|
lines.push(t(locale, 'auth_bot', { value: botLabel }));
|
|
7787
7787
|
}
|
|
7788
|
-
lines.push(t(locale, 'auth_current', {
|
|
7788
|
+
lines.push(t(locale, 'auth_current', {
|
|
7789
|
+
value: state.currentLabel
|
|
7790
|
+
? formatCodexAuthCandidateDisplayName(state.currentLabel)
|
|
7791
|
+
: t(locale, 'none'),
|
|
7792
|
+
}), t(locale, 'auth_dir', { value: state.authDir }));
|
|
7789
7793
|
if (state.candidates.length === 0) {
|
|
7790
7794
|
lines.push(t(locale, 'auth_no_candidates'));
|
|
7791
7795
|
if (includeWeixinCopyPaste) {
|
|
@@ -7817,7 +7821,7 @@ function renderAuthListMessage(locale, state, botLabel = null, includeWeixinCopy
|
|
|
7817
7821
|
}
|
|
7818
7822
|
page.visible.forEach(({ candidate, index }) => {
|
|
7819
7823
|
const marker = candidate.isCurrent ? ' *' : '';
|
|
7820
|
-
lines.push(`${index + 1}. ${formatAuthQuotaPrefix(locale, candidate.quota)}|${candidate.name}${marker} ${formatCodexAuthCandidateStatus(locale, candidate)}`);
|
|
7824
|
+
lines.push(`${index + 1}. ${formatAuthQuotaPrefix(locale, candidate.quota)}|${formatCodexAuthCandidateDisplayName(candidate.name)}${marker} ${formatCodexAuthCandidateStatus(locale, candidate)}`);
|
|
7821
7825
|
});
|
|
7822
7826
|
if (includeWeixinCopyPaste) {
|
|
7823
7827
|
lines.push('', t(locale, 'weixin_copy_paste_divider'), t(locale, 'weixin_copy_auth_title'), ...page.visible.map(({ index }) => `/auth use ${index + 1}`), ...page.visible.map(({ candidate, index }) => candidate.disabled
|
|
@@ -7830,7 +7834,7 @@ function authChoiceKeyboard(locale, record) {
|
|
|
7830
7834
|
const page = codexAuthListPage(record.candidates, record);
|
|
7831
7835
|
const rows = page.visible.map(({ candidate, index }) => [
|
|
7832
7836
|
{
|
|
7833
|
-
text: clipButtonText(`${candidate.isCurrent ? '✅ ' : '🔐 '}${formatAuthQuotaPrefix(locale, candidate.quota)}|${candidate.name}${candidate.disabled ? ' · off' : ''}`),
|
|
7837
|
+
text: clipButtonText(`${candidate.isCurrent ? '✅ ' : '🔐 '}${formatAuthQuotaPrefix(locale, candidate.quota)}|${formatCodexAuthCandidateDisplayName(candidate.name)}${candidate.disabled ? ' · off' : ''}`),
|
|
7834
7838
|
callback_data: `auth:${record.localId}:${index}`,
|
|
7835
7839
|
},
|
|
7836
7840
|
{
|
|
@@ -7863,6 +7867,12 @@ function authChoiceKeyboard(locale, record) {
|
|
|
7863
7867
|
rows.push([{ text: t(locale, 'button_auth_reload'), callback_data: `auth:${record.localId}:reload` }]);
|
|
7864
7868
|
return rows;
|
|
7865
7869
|
}
|
|
7870
|
+
function formatCodexAuthCandidateDisplayName(name) {
|
|
7871
|
+
const prefix = 'auth.json_';
|
|
7872
|
+
return name.length > prefix.length && name.startsWith(prefix)
|
|
7873
|
+
? name.slice(prefix.length)
|
|
7874
|
+
: name;
|
|
7875
|
+
}
|
|
7866
7876
|
function authFilterButton(locale, record, filter) {
|
|
7867
7877
|
const label = t(locale, `button_auth_filter_${filter}`);
|
|
7868
7878
|
return {
|
package/docs/user-manual.md
CHANGED
|
@@ -389,7 +389,7 @@ If the login is cancelled or fails, FoxClaw tries to restore the previous auth t
|
|
|
389
389
|
|
|
390
390
|
### 6.3 The `/auth` Panel
|
|
391
391
|
|
|
392
|
-
`/auth` lists candidate accounts, the current account, and the auth directory. It also provides buttons for switching, disabling, login, and reload. In multi-bot mode the panel names the `@botname` runtime being managed, because private chats, groups, and topics on one bot share that bot's current auth. The panel shows 8 candidates per page and supports paging, `All / Enabled / Attention` filters, and `/auth list <keyword>` filename search for large local inventories. `/auth use <n>` always uses the full-list candidate number, independent of panel paging.
|
|
392
|
+
`/auth` lists candidate accounts, the current account, and the auth directory. It also provides buttons for switching, disabling, login, and reload. In multi-bot mode the panel names the `@botname` runtime being managed, because private chats, groups, and topics on one bot share that bot's current auth. The panel shows 8 candidates per page and supports paging, `All / Enabled / Attention` filters, and `/auth list <keyword>` filename search for large local inventories. Panel text and buttons omit the repeated `auth.json_` prefix from standard candidate filenames, so `auth.json_personal` on disk renders as `personal`; files are not renamed, and search and commands still operate on the original candidates. `/auth use <n>` always uses the full-list candidate number, independent of panel paging.
|
|
393
393
|
|
|
394
394
|
Each filename is prefixed with observed `window:remaining-percent` values. For example, a Plus account may show `5h:20|7d:25`, while an account with one monthly window may show `30d:97`. The current auth quota is refreshed when the panel opens; other candidates are not switched merely to query quota. When multiple bot runtimes have recently used the same ChatGPT account, FoxClaw combines their cached quota snapshots by verified account ID, so one bot's `/auth` panel can show quota information learned by another bot without mixing different accounts.
|
|
395
395
|
|
|
@@ -397,15 +397,15 @@ Approximation:
|
|
|
397
397
|
|
|
398
398
|
```text
|
|
399
399
|
Codex auth
|
|
400
|
-
Current:
|
|
400
|
+
Current: personal
|
|
401
401
|
Auth dir: /home/alice/.codex
|
|
402
402
|
Candidates: 2
|
|
403
403
|
Quota remaining: window:percent|auth
|
|
404
|
-
1. 5h:20|7d:25|
|
|
405
|
-
2. --|
|
|
404
|
+
1. 5h:20|7d:25|personal * [Plus · ready · refreshed 2h ago]
|
|
405
|
+
2. --|team [quota unknown]
|
|
406
406
|
|
|
407
|
-
[✅ 5h:20|7d:25|
|
|
408
|
-
[🔐 --|
|
|
407
|
+
[✅ 5h:20|7d:25|personal] [✅]
|
|
408
|
+
[🔐 --|team] [✅]
|
|
409
409
|
[☑️ All] [Enabled] [Attention]
|
|
410
410
|
[🛡️ Access] [🔑 Login]
|
|
411
411
|
[🔄 Reload auth]
|
package/docs/zh/user-manual.md
CHANGED
|
@@ -389,7 +389,7 @@ cp -L ~/.codex/auth.json ~/.codex/auth.json_personal
|
|
|
389
389
|
|
|
390
390
|
### 6.3 `/auth` 面板
|
|
391
391
|
|
|
392
|
-
`/auth` 会列出候选账号、当前账号和 auth 目录,并提供按钮切换、禁用、登录和重载。多 bot 模式中,面板顶部还会显示当前正在管理的 `@botname`,因为该 bot 内的私聊、群聊和话题共享同一个当前 auth。面板每页显示 8 个候选,支持翻页、`全部 / 已启用 / 需关注` 筛选和 `/auth list <关键词>`
|
|
392
|
+
`/auth` 会列出候选账号、当前账号和 auth 目录,并提供按钮切换、禁用、登录和重载。多 bot 模式中,面板顶部还会显示当前正在管理的 `@botname`,因为该 bot 内的私聊、群聊和话题共享同一个当前 auth。面板每页显示 8 个候选,支持翻页、`全部 / 已启用 / 需关注` 筛选和 `/auth list <关键词>` 文件名搜索,适合管理较大的本地候选清单。面板文本和按钮会省略标准候选文件名中重复的 `auth.json_` 前缀,例如磁盘上的 `auth.json_personal` 显示为 `personal`;文件本身不会重命名,搜索和命令仍按原候选工作。命令 `/auth use <n>` 的编号始终对应完整候选列表,不会因为分页变化。
|
|
393
393
|
|
|
394
394
|
每个候选名前的 `窗口:剩余百分比` 来自最近一次观察到的真实额度窗口,例如 Plus 账号可能显示 `5h:20|7d:25`,只有一个月度窗口的账号可能显示 `30d:97`。当前 auth 会在打开面板时刷新额度;其他候选不会为了查询额度被自动切换。如果多个 bot runtime 最近使用过同一个 ChatGPT 账号,FoxClaw 会按已验证的账号 ID 合并它们缓存到的额度快照,因此一个 bot 的 `/auth` 面板可以显示另一个 bot 掌握到的额度信息,同时不会把不同账号混在一起。
|
|
395
395
|
|
|
@@ -397,15 +397,15 @@ cp -L ~/.codex/auth.json ~/.codex/auth.json_personal
|
|
|
397
397
|
|
|
398
398
|
```text
|
|
399
399
|
Codex auth
|
|
400
|
-
Current:
|
|
400
|
+
Current: personal
|
|
401
401
|
Auth dir: /home/alice/.codex
|
|
402
402
|
Candidates: 2
|
|
403
403
|
额度剩余:窗口:百分比|auth
|
|
404
|
-
1. 5h:20|7d:25|
|
|
405
|
-
2. --|
|
|
404
|
+
1. 5h:20|7d:25|personal * [Plus · 正常 · 刷新于 2小时前]
|
|
405
|
+
2. --|team [额度未知]
|
|
406
406
|
|
|
407
|
-
[✅ 5h:20|7d:25|
|
|
408
|
-
[🔐 --|
|
|
407
|
+
[✅ 5h:20|7d:25|personal] [✅]
|
|
408
|
+
[🔐 --|team] [✅]
|
|
409
409
|
[☑️ 全部] [已启用] [需关注]
|
|
410
410
|
[🛡️ Access] [🔑 设备登录]
|
|
411
411
|
[🔄 Reload auth]
|
package/package.json
CHANGED
package/skills/foxclaw/SKILL.md
CHANGED
|
@@ -67,7 +67,7 @@ Telegram behavior:
|
|
|
67
67
|
- when `TG_BOT_TOKENS` contains multiple bots, one FoxClaw service starts independent Codex app-servers and auth selections per bot
|
|
68
68
|
- isolated Telegram runtimes use independent `CODEX_HOME` directories and file-backed credentials; they do not share Codex sessions
|
|
69
69
|
- refreshed ChatGPT candidates are mirrored only after online usage-endpoint validation; before auth switch or reload, a runtime restores any newer same-account credential found in another Codex home
|
|
70
|
-
- `/auth` paginates large candidate inventories at 8 rows per page, supports all/enabled/attention filters and filename search,
|
|
70
|
+
- `/auth` paginates large candidate inventories at 8 rows per page, supports all/enabled/attention filters and filename search, renders the actual observed quota windows rather than assuming every account has 5-hour and 7-day windows, and omits the repeated `auth.json_` prefix from panel labels without renaming files
|
|
71
71
|
- treat the `/auth` `not recently refreshed` state as a maintenance hint only: OpenAI does not publish a fixed ChatGPT refresh-token lifetime or replay grace period, and FoxClaw must not add routine bulk keepalive refreshes
|
|
72
72
|
- `/auth refresh all` remains a command-only maintenance action, not a panel button; it requires explicit token-rotation risk confirmation, then force-refreshes every ChatGPT candidate through Codex `account/read refreshToken=true`, validates usage, mirrors successful candidates, and restores the original current auth while every runtime is globally idle
|
|
73
73
|
- if `TG_BOT_TOKEN` is also set to one exact token from `TG_BOT_TOKENS`, that bot uses the default/shared-terminal runtime instead of an isolated Telegram home
|