@foxden-app/foxclaw 0.5.68 → 0.5.70

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 CHANGED
@@ -2,6 +2,22 @@
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.70 - 2026-07-11
6
+
7
+ ### 中文
8
+ - `foxclaw status` 现在显示实际生效的 Codex home。单 bot 显示一条 `Codex home` 路径;多 bot 模式会按 bot 列出共享默认 runtime 和各隔离 runtime 的 home,`foxclaw status --json` 也会保留这些路径。
9
+
10
+ ### English
11
+ - `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`.
12
+
13
+ ## 0.5.69 - 2026-07-11
14
+
15
+ ### 中文
16
+ - 修复 pnpm 11 的自更新路径解析:`pnpm root -g` 在 pnpm 11 返回全局目录本身(例如 `.../global/v11`),而不是旧版返回的 `node_modules` 目录。FoxClaw 现在同时识别两种布局,升级后可以正确执行自检和服务重启。
17
+
18
+ ### English
19
+ - Fixed self-update path resolution for pnpm 11. `pnpm root -g` now returns the global directory itself (for example `.../global/v11`) rather than the `node_modules` directory returned by earlier pnpm versions. FoxClaw now recognizes both layouts and can correctly run post-update checks and restart the service.
20
+
5
21
  ## 0.5.68 - 2026-07-01
6
22
 
7
23
  ### 中文
@@ -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
@@ -85,5 +85,6 @@ export declare function performSelfUpdate(options: PerformSelfUpdateOptions): Se
85
85
  export declare function readPendingClusterUpdateBroadcast(filePath: string): PendingClusterUpdateBroadcast | null;
86
86
  export declare function writePendingClusterUpdateBroadcast(filePath: string, value: PendingClusterUpdateBroadcast): void;
87
87
  export declare function clearPendingClusterUpdateBroadcast(filePath: string): void;
88
+ export declare function resolveFoxclawEntryPointFromGlobalRoot(globalRoot: string, exists?: (target: string) => boolean): string | null;
88
89
  export declare function extractReleaseNotes(changelog: string, version: string, locale: AppLocale): string[] | null;
89
90
  export {};
package/dist/update.js CHANGED
@@ -472,6 +472,15 @@ function runInherited(command, args, env) {
472
472
  throw new Error(`${command} ${args.join(' ')} exited with status ${result.status ?? 'unknown'}.`);
473
473
  }
474
474
  }
475
+ export function resolveFoxclawEntryPointFromGlobalRoot(globalRoot, exists = fs.existsSync) {
476
+ // pnpm <= 10 prints the global node_modules directory; pnpm >= 11 prints
477
+ // the global directory itself. Accept both documented layouts.
478
+ const candidates = [
479
+ path.join(globalRoot, '@foxden-app', 'foxclaw', 'dist', 'main.js'),
480
+ path.join(globalRoot, 'node_modules', '@foxden-app', 'foxclaw', 'dist', 'main.js'),
481
+ ];
482
+ return candidates.find(candidate => exists(candidate)) ?? null;
483
+ }
475
484
  function resolveUpdatedEntryPoint(installer, env) {
476
485
  const result = spawnSync(installer.command, installer.rootArgs, { encoding: 'utf8', env });
477
486
  if (result.error) {
@@ -484,9 +493,9 @@ function resolveUpdatedEntryPoint(installer, env) {
484
493
  if (!globalRoot) {
485
494
  throw new Error(`Could not locate the updated global package root using ${installer.manager}.`);
486
495
  }
487
- const updatedEntryPoint = path.join(globalRoot, '@foxden-app', 'foxclaw', 'dist', 'main.js');
488
- if (!fs.existsSync(updatedEntryPoint)) {
489
- throw new Error(`Updated FoxClaw entry point was not found at ${updatedEntryPoint}.`);
496
+ const updatedEntryPoint = resolveFoxclawEntryPointFromGlobalRoot(globalRoot);
497
+ if (!updatedEntryPoint) {
498
+ throw new Error(`Updated FoxClaw entry point was not found below ${globalRoot} (checked direct and node_modules layouts).`);
490
499
  }
491
500
  return updatedEntryPoint;
492
501
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foxden-app/foxclaw",
3
- "version": "0.5.68",
3
+ "version": "0.5.70",
4
4
  "description": "Foxden local execution claw for controlling Codex from trusted chat interfaces.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",