@foxden-app/foxclaw 0.5.46 → 0.5.47
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 +12 -0
- package/dist/auth/mirror.d.ts +1 -0
- package/dist/auth/mirror.js +10 -0
- package/dist/main.js +15 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
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.5.47 - 2026-06-20
|
|
6
|
+
|
|
7
|
+
### 中文
|
|
8
|
+
- 修复远端 auth 候选已成功导入后,`/auth` 面板仍保留旧的 `needs_repair`/禁用状态,导致候选显示问号且无法切换的问题。
|
|
9
|
+
- 远端导入成功现在会恢复该候选的全局状态和各 Telegram runtime 覆盖状态为 active/enabled,确保“确认可用后文件和 UI 状态一致”。
|
|
10
|
+
- 增加 mirror 远端导入 hook 回归测试,避免后续同步链路再次只更新 auth 文件、不恢复健康标记。
|
|
11
|
+
|
|
12
|
+
### English
|
|
13
|
+
- Fixed `/auth` keeping stale `needs_repair`/disabled state after a remote auth candidate was successfully imported, which left the candidate shown with a question mark and blocked switching.
|
|
14
|
+
- Successful remote imports now restore the candidate's global state and each Telegram runtime override to active/enabled, keeping the UI state aligned with validated auth files.
|
|
15
|
+
- Added a regression test for the mirror remote-import hook so future sync changes do not update auth files without clearing health markers.
|
|
16
|
+
|
|
5
17
|
## 0.5.46 - 2026-06-20
|
|
6
18
|
|
|
7
19
|
### 中文
|
package/dist/auth/mirror.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ export interface AuthMirrorSyncAllResult {
|
|
|
61
61
|
}
|
|
62
62
|
export interface AuthMirrorHooks {
|
|
63
63
|
onSynced?: (event: AuthMirrorSyncedEvent) => Promise<void> | void;
|
|
64
|
+
onRemoteImported?: (event: AuthMirrorSyncedEvent) => Promise<void> | void;
|
|
64
65
|
}
|
|
65
66
|
export type AuthMirrorNotification = {
|
|
66
67
|
kind: 'local_synced';
|
package/dist/auth/mirror.js
CHANGED
|
@@ -304,6 +304,16 @@ export class AuthCandidateMirror {
|
|
|
304
304
|
sourceLabel,
|
|
305
305
|
};
|
|
306
306
|
await Promise.allSettled(this.runtimes.map((target) => target.notify?.(notification)));
|
|
307
|
+
await this.hooks.onRemoteImported?.({
|
|
308
|
+
status: this.lastStatus,
|
|
309
|
+
record: {
|
|
310
|
+
raw,
|
|
311
|
+
...metadata,
|
|
312
|
+
candidateName,
|
|
313
|
+
sourceRuntimeId: `remote:${source.nodeId}`,
|
|
314
|
+
sourceLabel,
|
|
315
|
+
},
|
|
316
|
+
});
|
|
307
317
|
return {
|
|
308
318
|
ok: true,
|
|
309
319
|
imported: true,
|
package/dist/main.js
CHANGED
|
@@ -410,6 +410,7 @@ async function runServeCli() {
|
|
|
410
410
|
seeds.push({ id, home, authDir, sharedDefaultRuntime, config: runtimeConfig, bot, app });
|
|
411
411
|
}
|
|
412
412
|
let authSync = null;
|
|
413
|
+
const authRuntimeIds = seeds.map((runtime) => runtime.id);
|
|
413
414
|
const mirror = new AuthCandidateMirror(canonicalAuthDir, seeds.map((runtime) => ({
|
|
414
415
|
id: runtime.id,
|
|
415
416
|
label: runtime.bot.username ? `@${runtime.bot.username}` : runtime.id,
|
|
@@ -423,6 +424,9 @@ async function runServeCli() {
|
|
|
423
424
|
onSynced: async (event) => {
|
|
424
425
|
await authSync?.publishCandidate(event.record.candidateName);
|
|
425
426
|
},
|
|
427
|
+
onRemoteImported: (event) => {
|
|
428
|
+
restoreImportedAuthCandidateState(store, event.record.candidateName, authRuntimeIds);
|
|
429
|
+
},
|
|
426
430
|
});
|
|
427
431
|
await mirror.initialize();
|
|
428
432
|
activeAuthMirror = mirror;
|
|
@@ -757,6 +761,9 @@ async function runServeCli() {
|
|
|
757
761
|
onSynced: async (event) => {
|
|
758
762
|
await singleAuthSync?.publishCandidate(event.record.candidateName);
|
|
759
763
|
},
|
|
764
|
+
onRemoteImported: (event) => {
|
|
765
|
+
restoreImportedAuthCandidateState(store, event.record.candidateName, ['default']);
|
|
766
|
+
},
|
|
760
767
|
});
|
|
761
768
|
await singleMirror.initialize();
|
|
762
769
|
activeAuthMirror = singleMirror;
|
|
@@ -863,6 +870,14 @@ async function runServeCli() {
|
|
|
863
870
|
throw error;
|
|
864
871
|
}
|
|
865
872
|
}
|
|
873
|
+
function restoreImportedAuthCandidateState(store, candidateName, runtimeIds) {
|
|
874
|
+
store.setCodexAuthCandidateState(candidateName, 'active');
|
|
875
|
+
store.setCodexAuthCandidateDisabled(candidateName, false);
|
|
876
|
+
for (const runtimeId of runtimeIds) {
|
|
877
|
+
store.setCodexAuthCandidateState(candidateName, 'active', runtimeId);
|
|
878
|
+
store.setCodexAuthCandidateDisabled(candidateName, false, runtimeId);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
866
881
|
function createAuthMirrorNotifier(store, botId, bot, aggregator, options = {}) {
|
|
867
882
|
return async (event) => {
|
|
868
883
|
if (options.suppressBackgroundNotifications?.())
|