@foxden-app/foxclaw 0.2.1 → 0.2.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.
@@ -3,7 +3,9 @@ import fs from 'node:fs';
3
3
  import net from 'node:net';
4
4
  import path from 'node:path';
5
5
  import { spawn } from 'node:child_process';
6
+ import { fileURLToPath } from 'node:url';
6
7
  import { buildThreadDeepLink, openUrl } from './deeplink.js';
8
+ const CLIENT_VERSION = readPackageVersion();
7
9
  export class CodexAppClient extends EventEmitter {
8
10
  codexCliBin;
9
11
  launchCommand;
@@ -593,7 +595,7 @@ export class CodexAppClient extends EventEmitter {
593
595
  clientInfo: {
594
596
  name: 'foxclaw',
595
597
  title: 'FoxClaw',
596
- version: '0.2.0',
598
+ version: CLIENT_VERSION,
597
599
  },
598
600
  capabilities: {
599
601
  experimentalApi: true,
@@ -770,6 +772,16 @@ export class CodexAppClient extends EventEmitter {
770
772
  this.clearServerState();
771
773
  }
772
774
  }
775
+ function readPackageVersion() {
776
+ try {
777
+ const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'package.json');
778
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
779
+ return typeof pkg.version === 'string' && pkg.version.trim() ? pkg.version : '0.0.0';
780
+ }
781
+ catch {
782
+ return '0.0.0';
783
+ }
784
+ }
773
785
  async function reservePort() {
774
786
  return new Promise((resolve, reject) => {
775
787
  const server = net.createServer();
package/dist/main.js CHANGED
@@ -5,19 +5,6 @@ import process from 'node:process';
5
5
  import { spawnSync } from 'node:child_process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { APP_HOME, DEFAULT_ENV_PATH, DEFAULT_LOG_PATH, DEFAULT_STATUS_PATH, loadConfig, loadEnv, } from './config.js';
8
- import { BridgeMessagingRouter } from './channels/bridge_messaging_router.js';
9
- import { TelegramMessagingPort } from './channels/telegram/telegram_messaging_port.js';
10
- import { WeixinChannelAdapter } from './channels/weixin/weixin_channel_adapter.js';
11
- import { WeixinMessagingPort } from './channels/weixin/weixin_messaging_port.js';
12
- import { attachIlinkRuntimeFromBridgeLogger } from './channels/weixin/ilink/runtime_attach.js';
13
- import { startWeixinLoginWithQr, waitForWeixinLogin } from './channels/weixin/ilink/login_qr.js';
14
- import { accountFilePath, loadWeixinAccount, saveWeixinAccount } from './channels/weixin/account_store.js';
15
- import { Logger } from './logger.js';
16
- import { BridgeStore } from './store/database.js';
17
- import { TelegramGateway } from './telegram/gateway.js';
18
- import { CodexAppClient } from './codex_app/client.js';
19
- import { BridgeSessionCore } from './controller/controller.js';
20
- import { TelegramChannelAdapter } from './channels/telegram/telegram_channel_adapter.js';
21
8
  import { acquireProcessLock, LockHeldError } from './lock.js';
22
9
  import { readRuntimeStatus, writeRuntimeStatus } from './runtime.js';
23
10
  const command = process.argv[2] || 'serve';
@@ -30,6 +17,7 @@ async function main() {
30
17
  return;
31
18
  }
32
19
  if (command === 'install-systemd') {
20
+ requireNode24(command);
33
21
  installSystemd();
34
22
  return;
35
23
  }
@@ -38,6 +26,7 @@ async function main() {
38
26
  return;
39
27
  }
40
28
  if (command === 'install-launchd') {
29
+ requireNode24(command);
41
30
  installLaunchd();
42
31
  return;
43
32
  }
@@ -91,9 +80,28 @@ async function main() {
91
80
  process.exit(failed ? 1 : 0);
92
81
  }
93
82
  if (command === 'weixin-login') {
83
+ requireNode24(command);
94
84
  await runWeixinLoginCli();
95
85
  return;
96
86
  }
87
+ requireNode24(command);
88
+ await runServeCli();
89
+ }
90
+ async function runServeCli() {
91
+ const [{ BridgeMessagingRouter }, { TelegramMessagingPort }, { WeixinChannelAdapter }, { WeixinMessagingPort }, { attachIlinkRuntimeFromBridgeLogger }, { loadWeixinAccount }, { Logger }, { BridgeStore }, { TelegramGateway }, { CodexAppClient }, { BridgeSessionCore }, { TelegramChannelAdapter },] = await Promise.all([
92
+ import('./channels/bridge_messaging_router.js'),
93
+ import('./channels/telegram/telegram_messaging_port.js'),
94
+ import('./channels/weixin/weixin_channel_adapter.js'),
95
+ import('./channels/weixin/weixin_messaging_port.js'),
96
+ import('./channels/weixin/ilink/runtime_attach.js'),
97
+ import('./channels/weixin/account_store.js'),
98
+ import('./logger.js'),
99
+ import('./store/database.js'),
100
+ import('./telegram/gateway.js'),
101
+ import('./codex_app/client.js'),
102
+ import('./controller/controller.js'),
103
+ import('./channels/telegram/telegram_channel_adapter.js'),
104
+ ]);
97
105
  const config = loadConfig();
98
106
  const logger = new Logger(config.logLevel, config.logPath);
99
107
  attachIlinkRuntimeFromBridgeLogger(logger, config.wxIlinkRouteTag);
@@ -322,6 +330,12 @@ function xmlEscape(value) {
322
330
  .replace(/'/g, ''');
323
331
  }
324
332
  async function runWeixinLoginCli() {
333
+ const [{ attachIlinkRuntimeFromBridgeLogger }, { startWeixinLoginWithQr, waitForWeixinLogin }, { accountFilePath, saveWeixinAccount }, { Logger },] = await Promise.all([
334
+ import('./channels/weixin/ilink/runtime_attach.js'),
335
+ import('./channels/weixin/ilink/login_qr.js'),
336
+ import('./channels/weixin/account_store.js'),
337
+ import('./logger.js'),
338
+ ]);
325
339
  const logPath = process.env.LOG_PATH || DEFAULT_LOG_PATH;
326
340
  const level = process.env.LOG_LEVEL === 'debug' || process.env.LOG_LEVEL === 'warn' || process.env.LOG_LEVEL === 'error'
327
341
  ? process.env.LOG_LEVEL
@@ -410,6 +424,15 @@ function hasConfiguredCodexBin(binPath) {
410
424
  return false;
411
425
  }
412
426
  }
427
+ function requireNode24(commandName) {
428
+ if (Number(process.versions.node.split('.')[0]) >= 24)
429
+ return;
430
+ console.error(`FoxClaw ${commandName} requires Node.js 24+. Current Node.js is ${process.version}.`);
431
+ console.error('Install or activate Node 24, then reinstall/re-run FoxClaw:');
432
+ console.error(' nvm install 24 && nvm use 24');
433
+ console.error(' npm install -g @foxden-app/foxclaw@latest');
434
+ process.exit(1);
435
+ }
413
436
  function serializeError(error) {
414
437
  if (error instanceof Error) {
415
438
  return { message: error.message, stack: error.stack };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "name": "@foxden-app/foxclaw",
3
- "version": "0.2.1",
2
+ "name": "@foxden-app/foxclaw",
3
+ "version": "0.2.3",
4
4
  "description": "Foxden local execution claw for controlling Codex from trusted chat interfaces.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -8,13 +8,13 @@
8
8
  "foxclaw": "dist/main.js"
9
9
  },
10
10
  "files": [
11
- "dist",
12
- "docs",
13
- "scripts",
11
+ "dist",
12
+ "docs",
13
+ "scripts",
14
14
  "skills",
15
15
  ".env.example",
16
- "README.md",
17
- "README_EN.md",
16
+ "README.md",
17
+ "README_EN.md",
18
18
  "LICENSE"
19
19
  ],
20
20
  "private": false,
@@ -32,23 +32,23 @@
32
32
  "engines": {
33
33
  "node": ">=24"
34
34
  },
35
- "scripts": {
36
- "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
37
- "build": "npm run clean && tsc -p tsconfig.build.json",
38
- "dev": "tsx src/main.ts serve",
39
- "serve": "node dist/main.js serve",
35
+ "scripts": {
36
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
37
+ "build": "npm run clean && tsc -p tsconfig.build.json",
38
+ "dev": "tsx src/main.ts serve",
39
+ "serve": "node dist/main.js serve",
40
40
  "weixin-login": "node dist/main.js weixin-login",
41
41
  "status": "node dist/main.js status",
42
42
  "doctor": "node dist/main.js doctor",
43
- "init": "node dist/main.js init",
44
- "install-systemd": "node dist/main.js install-systemd",
45
- "uninstall-systemd": "node dist/main.js uninstall-systemd",
46
- "install-launchd": "node dist/main.js install-launchd",
43
+ "init": "node dist/main.js init",
44
+ "install-systemd": "node dist/main.js install-systemd",
45
+ "uninstall-systemd": "node dist/main.js uninstall-systemd",
46
+ "install-launchd": "node dist/main.js install-launchd",
47
47
  "typecheck": "tsc --noEmit",
48
48
  "lint": "eslint .",
49
- "test": "node --test --import tsx \"src/**/*.test.ts\"",
50
- "prepack": "npm run build"
51
- },
49
+ "test": "node --test --import tsx \"src/**/*.test.ts\"",
50
+ "prepack": "npm run build"
51
+ },
52
52
  "dependencies": {
53
53
  "dotenv": "^16.6.1",
54
54
  "qrcode-terminal": "^0.12.0"