claude-codex-wechat 0.1.46 → 0.1.48

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/README.md CHANGED
@@ -88,13 +88,13 @@ claude-codex-wechat doctor
88
88
  }
89
89
  ```
90
90
 
91
- 如需接入自建的公网中转服务(relay-server),在同一份配置里加上:
91
+ 默认配置只保留 relay 地址;`authToken` 会在首次启动时自动生成并写回 `config.json`。
92
+
93
+ 如需改为接入自建的公网中转服务(relay-server),在同一份配置里覆盖 relay 地址,并把 `authToken` 换成该 relay 接受的真实 token:
92
94
 
93
95
  ```json
94
96
  {
95
97
  "tunnel": {
96
- "provider": "relay",
97
- "enabled": true,
98
98
  "relay": {
99
99
  "serverUrl": "wss://your-relay-host/agent",
100
100
  "authToken": "replace-with-relay-auth-token"
@@ -16,11 +16,8 @@
16
16
  }
17
17
  },
18
18
  "tunnel": {
19
- "provider": "relay",
20
- "enabled": false,
21
19
  "relay": {
22
- "serverUrl": "wss://wechat.style520.com/agent",
23
- "authToken": "replace-with-relay-auth-token"
20
+ "serverUrl": "wss://wechat.style520.com/agent"
24
21
  }
25
22
  }
26
23
  }
@@ -497,7 +497,7 @@ var FileWeixinStateStore = class {
497
497
  };
498
498
 
499
499
  // src/providers/claude-code/nativeSessions.ts
500
- import { appendFile, mkdir as mkdir2, readdir as readdir2, readFile as readFile2, stat as stat2, writeFile } from "node:fs/promises";
500
+ import { appendFile, mkdir as mkdir2, readdir as readdir2, readFile as readFile2, stat as stat2, unlink as unlink2, writeFile } from "node:fs/promises";
501
501
  import { homedir as homedir2 } from "node:os";
502
502
  import { basename as basename2, dirname as dirname2, join as join3 } from "node:path";
503
503
 
@@ -528,6 +528,19 @@ function parseSessionBridgeName(value) {
528
528
  function resolveClaudeConfigDir(env = process.env) {
529
529
  return join3(env.HOME || homedir2(), ".claude");
530
530
  }
531
+ async function prepareClaudeSessionForResume(input) {
532
+ const env = input.env ?? process.env;
533
+ const index = await readClaudeRuntimeSessionIndex(env);
534
+ const record = index.get(input.sessionId.trim());
535
+ if (!record || record.kind !== "bg") return { ok: true, adoptedBackground: false };
536
+ if (record.status && record.status !== "idle") {
537
+ return { ok: false, reason: "background_session_running" };
538
+ }
539
+ if (record.path) {
540
+ await unlink2(record.path).catch(() => void 0);
541
+ }
542
+ return { ok: true, adoptedBackground: true };
543
+ }
531
544
  async function listRecoverableClaudeSessions(env = process.env) {
532
545
  const projectsDir = join3(resolveClaudeConfigDir(env), "projects");
533
546
  const historyIndex = await readClaudeHistoryIndex(env);
@@ -685,6 +698,30 @@ async function readClaudeSessionMetadata(filePath) {
685
698
  }
686
699
  return { aiTitle, lastPrompt, sessionName, cwd };
687
700
  }
701
+ async function readClaudeRuntimeSessionIndex(env) {
702
+ const sessionsDir = join3(resolveClaudeConfigDir(env), "sessions");
703
+ const index = /* @__PURE__ */ new Map();
704
+ try {
705
+ const entries = await readdir2(sessionsDir, { withFileTypes: true });
706
+ for (const entry of entries) {
707
+ if (!entry.isFile() || entry.isSymbolicLink() || !String(entry.name).endsWith(".json")) continue;
708
+ const path = join3(sessionsDir, String(entry.name));
709
+ try {
710
+ const raw = await readFile2(path, "utf8");
711
+ const record = JSON.parse(raw);
712
+ const sessionId = typeof record.sessionId === "string" ? record.sessionId.trim() : "";
713
+ if (!sessionId) continue;
714
+ const kind = typeof record.kind === "string" ? record.kind.trim() : void 0;
715
+ const status = typeof record.status === "string" ? record.status.trim() : void 0;
716
+ index.set(sessionId, { kind, status, path });
717
+ } catch {
718
+ }
719
+ }
720
+ } catch {
721
+ return index;
722
+ }
723
+ return index;
724
+ }
688
725
  async function readClaudeHistoryIndex(env) {
689
726
  const historyPath = join3(resolveClaudeConfigDir(env), "history.jsonl");
690
727
  const index = /* @__PURE__ */ new Map();
@@ -1373,6 +1410,12 @@ function registerChannelAdminRoutes(input) {
1373
1410
  if (!input.conversation) {
1374
1411
  return reply.code(500).send({ ok: false, error: "current_conversation_store_unavailable" });
1375
1412
  }
1413
+ if (request.body.providerId === "claude-code") {
1414
+ const prepared = await prepareClaudeSessionForResume({ sessionId: request.body.providerSessionId });
1415
+ if (!prepared.ok) {
1416
+ return reply.code(409).send({ ok: false, error: "claude_background_session_still_running" });
1417
+ }
1418
+ }
1376
1419
  const recoverableCandidate = provider.listRecoverableSessions ? (await provider.listRecoverableSessions()).find((candidate) => candidate.id === request.body.providerSessionId) : void 0;
1377
1420
  const attached = await attachProviderSessionToBridge({
1378
1421
  conversationStore: input.conversation,
@@ -1387,6 +1430,19 @@ function registerChannelAdminRoutes(input) {
1387
1430
  resumeTitle: recoverableCandidate?.resumeTitle
1388
1431
  });
1389
1432
  input.events?.emit({ type: "channel.current-session-changed" });
1433
+ try {
1434
+ const providerLabel = attached.providerId === "codex" ? "Codex" : "Claude";
1435
+ const lines = [`### \u5DF2\u63A5\u5165 ${providerLabel} \u4F1A\u8BDD`];
1436
+ if (attached.providerSessionId) lines.push(`- \`sessionId\`: \`${attached.providerSessionId}\``);
1437
+ lines.push(`- \`cwd\`: \`${attached.cwd}\``);
1438
+ await input.channel?.sendMessage({
1439
+ chatId: request.body.chatId ?? user.platformUserId,
1440
+ kind: "status",
1441
+ text: lines.join("\n")
1442
+ });
1443
+ } catch (err) {
1444
+ input.app.log.warn({ err }, "sessions_attach_notify_failed");
1445
+ }
1390
1446
  return {
1391
1447
  ok: true,
1392
1448
  session: {
@@ -5640,7 +5696,6 @@ async function startDaemon(options) {
5640
5696
  defaultProvider: config.bridge?.defaultProvider ?? "claude-code",
5641
5697
  defaultWorkspace: config.bridge?.defaultWorkspace ?? process.cwd(),
5642
5698
  tunnel: {
5643
- enabled: true,
5644
5699
  ...config.tunnel?.relay ? { relay: config.tunnel.relay } : {}
5645
5700
  }
5646
5701
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-codex-wechat",
3
- "version": "0.1.46",
3
+ "version": "0.1.48",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.5.0",