@foxden-app/foxclaw 0.5.69 → 0.5.71
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 +18 -0
- package/dist/controller/controller.js +1 -0
- package/dist/main.js +18 -0
- package/dist/types.d.ts +3 -0
- package/dist/update.d.ts +1 -0
- package/dist/update.js +14 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
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.71 - 2026-07-11
|
|
6
|
+
|
|
7
|
+
### 中文
|
|
8
|
+
- 自更新找不到当前 pnpm 可执行文件时,不再通过 `pnpm@latest` 跨 major 安装:`global/5` 旧布局固定使用 pnpm 10,`global/v11` 布局固定使用 pnpm 11,避免同一次升级同时产生两套全局目录和 CLI 入口。
|
|
9
|
+
- 保留 pnpm 10 与 pnpm 11 两种全局 root 解析,确保安装后的自检和服务重启使用与当前 FoxClaw 安装布局一致的新入口。
|
|
10
|
+
|
|
11
|
+
### English
|
|
12
|
+
- Self-update no longer crosses pnpm major versions through `pnpm@latest` when the current pnpm executable is unavailable. The legacy `global/5` layout uses pnpm 10, while `global/v11` uses pnpm 11, preventing one update from creating duplicate global trees and CLI entry points.
|
|
13
|
+
- Kept global-root resolution for both pnpm 10 and pnpm 11 so post-install checks and service restart use the new entry point from the same layout as the current FoxClaw installation.
|
|
14
|
+
|
|
15
|
+
## 0.5.70 - 2026-07-11
|
|
16
|
+
|
|
17
|
+
### 中文
|
|
18
|
+
- `foxclaw status` 现在显示实际生效的 Codex home。单 bot 显示一条 `Codex home` 路径;多 bot 模式会按 bot 列出共享默认 runtime 和各隔离 runtime 的 home,`foxclaw status --json` 也会保留这些路径。
|
|
19
|
+
|
|
20
|
+
### English
|
|
21
|
+
- `foxclaw status` now shows the effective Codex home. Single-bot mode prints one `Codex home` path, while multi-bot mode lists the shared default runtime and every isolated runtime by bot. The same paths are retained in `foxclaw status --json`.
|
|
22
|
+
|
|
5
23
|
## 0.5.69 - 2026-07-11
|
|
6
24
|
|
|
7
25
|
### 中文
|
|
@@ -291,6 +291,7 @@ export class BridgeSessionCore {
|
|
|
291
291
|
running: true,
|
|
292
292
|
connected: this.app.isConnected(),
|
|
293
293
|
userAgent: this.app.getUserAgent(),
|
|
294
|
+
codexHome: this.config.codexHome ?? path.join(os.homedir(), '.codex'),
|
|
294
295
|
codexAppServer: this.app.getServerStatus(),
|
|
295
296
|
botUsername: this.botUsername,
|
|
296
297
|
currentBindings: this.store.countBindings(),
|
package/dist/main.js
CHANGED
|
@@ -470,6 +470,20 @@ function formatRuntimeStatusSummary(status) {
|
|
|
470
470
|
if (status.userAgent) {
|
|
471
471
|
lines.push(`Codex: ${status.userAgent}`);
|
|
472
472
|
}
|
|
473
|
+
const botHomes = (status.bots ?? [])
|
|
474
|
+
.flatMap(bot => bot.codexHome ? [{ label: bot.username ? `@${bot.username}` : bot.id, home: bot.codexHome }] : []);
|
|
475
|
+
if (botHomes.length > 1) {
|
|
476
|
+
lines.push('Codex homes:');
|
|
477
|
+
for (const { label, home } of botHomes) {
|
|
478
|
+
lines.push(` ${label}: ${home}`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else if (botHomes.length === 1) {
|
|
482
|
+
lines.push(`Codex home: ${botHomes[0].home}`);
|
|
483
|
+
}
|
|
484
|
+
else if (status.codexHome) {
|
|
485
|
+
lines.push(`Codex home: ${status.codexHome}`);
|
|
486
|
+
}
|
|
473
487
|
if (status.codexAppServer) {
|
|
474
488
|
lines.push(`App server: ${status.codexAppServer.running ? 'running' : 'stopped'}${status.codexAppServer.pid ? ` pid=${status.codexAppServer.pid}` : ''}${status.codexAppServer.port ? ` port=${status.codexAppServer.port}` : ''}`);
|
|
475
489
|
}
|
|
@@ -654,6 +668,7 @@ async function runServeCli() {
|
|
|
654
668
|
&& statuses.every((status) => status.connected)
|
|
655
669
|
&& (!weixinStatus || weixinStatus.connected),
|
|
656
670
|
userAgent: first?.userAgent ?? null,
|
|
671
|
+
codexHome: first?.codexHome ?? null,
|
|
657
672
|
...(first?.codexAppServer ? { codexAppServer: first.codexAppServer } : {}),
|
|
658
673
|
botUsername: first?.botUsername ?? null,
|
|
659
674
|
currentBindings: store.countBindings(),
|
|
@@ -673,6 +688,7 @@ async function runServeCli() {
|
|
|
673
688
|
connected: running && Boolean(statuses[index]?.connected),
|
|
674
689
|
activeTurns: running ? (statuses[index]?.activeTurns ?? 0) : 0,
|
|
675
690
|
runtimeKind: runtime.sharedDefaultRuntime ? 'default' : 'isolated',
|
|
691
|
+
codexHome: statuses[index]?.codexHome ?? runtime.home,
|
|
676
692
|
...(statuses[index]?.codexAppServer ? { codexAppServer: statuses[index].codexAppServer } : {}),
|
|
677
693
|
})),
|
|
678
694
|
...(weixinStatus ? {
|
|
@@ -749,6 +765,7 @@ async function runServeCli() {
|
|
|
749
765
|
activeTurns: status.activeTurns,
|
|
750
766
|
runtimeKind: runtime.sharedDefaultRuntime ? 'default' : 'isolated',
|
|
751
767
|
currentAuth: await runtime.core.getCurrentAuthLabel().catch(() => null),
|
|
768
|
+
codexHome: status.codexHome ?? runtime.home,
|
|
752
769
|
...(status.codexAppServer ? { codexAppServer: status.codexAppServer } : {}),
|
|
753
770
|
};
|
|
754
771
|
})),
|
|
@@ -1039,6 +1056,7 @@ async function runServeCli() {
|
|
|
1039
1056
|
running: false,
|
|
1040
1057
|
connected: false,
|
|
1041
1058
|
userAgent: app.getUserAgent(),
|
|
1059
|
+
codexHome: singleCodexHome,
|
|
1042
1060
|
codexAppServer: app.getServerStatus(),
|
|
1043
1061
|
botUsername: bot.username,
|
|
1044
1062
|
currentBindings: 0,
|
package/dist/types.d.ts
CHANGED
|
@@ -374,6 +374,8 @@ export interface RuntimeStatus {
|
|
|
374
374
|
running: boolean;
|
|
375
375
|
connected: boolean;
|
|
376
376
|
userAgent: string | null;
|
|
377
|
+
/** Effective Codex home used by this runtime, including the implicit ~/.codex default. */
|
|
378
|
+
codexHome?: string | null;
|
|
377
379
|
codexAppServer?: {
|
|
378
380
|
pid: number | null;
|
|
379
381
|
port: number | null;
|
|
@@ -400,6 +402,7 @@ export interface RuntimeStatus {
|
|
|
400
402
|
activeTurns: number;
|
|
401
403
|
runtimeKind?: 'default' | 'isolated';
|
|
402
404
|
currentAuth?: string | null;
|
|
405
|
+
codexHome?: string | null;
|
|
403
406
|
codexAppServer?: RuntimeStatus['codexAppServer'];
|
|
404
407
|
}>;
|
|
405
408
|
weixinRuntime?: {
|
package/dist/update.d.ts
CHANGED
|
@@ -65,6 +65,7 @@ export interface PendingClusterUpdateBroadcast {
|
|
|
65
65
|
}
|
|
66
66
|
export declare function selfUpdateStatusPath(statusPath: string): string;
|
|
67
67
|
export declare function inferPnpmHomeFromEntryPoint(entryPoint: string): string | null;
|
|
68
|
+
export declare function inferPnpmFallbackPackageFromEntryPoint(entryPoint: string): string;
|
|
68
69
|
export declare function resolveSelfUpdateInstaller(entryPoint: string, nodePath?: string, exists?: (target: string) => boolean, env?: NodeJS.ProcessEnv): SelfUpdateInstaller;
|
|
69
70
|
export declare function resolveCodexUpdateInstaller(codexCliBin: string, nodePath?: string, exists?: (target: string) => boolean, env?: NodeJS.ProcessEnv, realpath?: (target: string) => string, readText?: (target: string) => string): SelfUpdateInstaller | null;
|
|
70
71
|
export declare function readSelfUpdateStatus(statusFile: string): SelfUpdateStatus | null;
|
package/dist/update.js
CHANGED
|
@@ -18,6 +18,17 @@ export function inferPnpmHomeFromEntryPoint(entryPoint) {
|
|
|
18
18
|
}
|
|
19
19
|
return normalizedEntryPoint.slice(0, globalIndex);
|
|
20
20
|
}
|
|
21
|
+
export function inferPnpmFallbackPackageFromEntryPoint(entryPoint) {
|
|
22
|
+
const normalizedEntryPoint = entryPoint.replace(/\\/g, '/');
|
|
23
|
+
const versionedLayout = normalizedEntryPoint.match(/\/global\/v(\d+)(?:\/|$)/);
|
|
24
|
+
if (versionedLayout?.[1]) {
|
|
25
|
+
return `pnpm@${versionedLayout[1]}`;
|
|
26
|
+
}
|
|
27
|
+
if (/\/global\/\d+(?:\/|$)/.test(normalizedEntryPoint)) {
|
|
28
|
+
return 'pnpm@10';
|
|
29
|
+
}
|
|
30
|
+
return 'pnpm@latest';
|
|
31
|
+
}
|
|
21
32
|
export function resolveSelfUpdateInstaller(entryPoint, nodePath = process.execPath, exists = fs.existsSync, env = process.env) {
|
|
22
33
|
const pnpmHome = inferPnpmHomeFromEntryPoint(entryPoint);
|
|
23
34
|
if (pnpmHome) {
|
|
@@ -41,11 +52,12 @@ export function resolveSelfUpdateInstaller(entryPoint, nodePath = process.execPa
|
|
|
41
52
|
const npmCommandName = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
42
53
|
const npmCommand = executableCandidates(npmCommandName, nodePath, env)
|
|
43
54
|
.find((candidate) => exists(candidate)) ?? npmCommandName;
|
|
55
|
+
const fallbackPackage = inferPnpmFallbackPackageFromEntryPoint(entryPoint);
|
|
44
56
|
return {
|
|
45
57
|
manager: 'pnpm',
|
|
46
58
|
command: npmCommand,
|
|
47
|
-
installArgs: ['exec', '--yes',
|
|
48
|
-
rootArgs: ['exec', '--yes',
|
|
59
|
+
installArgs: ['exec', '--yes', `--package=${fallbackPackage}`, '--', 'pnpm', 'add', '--global', PACKAGE_SPEC],
|
|
60
|
+
rootArgs: ['exec', '--yes', `--package=${fallbackPackage}`, '--', 'pnpm', 'root', '--global'],
|
|
49
61
|
pnpmHome,
|
|
50
62
|
};
|
|
51
63
|
}
|