claude-codex-wechat 0.1.40 → 0.1.44
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 +62 -303
- package/dist/server/cli.js +193 -12
- package/dist/web/assets/{index-Ds7h49vj.js → index-dnbWitlp.js} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
package/dist/server/cli.js
CHANGED
|
@@ -639,6 +639,16 @@ async function hasClaudeHistoryDisplay(input) {
|
|
|
639
639
|
}
|
|
640
640
|
return false;
|
|
641
641
|
}
|
|
642
|
+
async function getClaudeNativeVersion(input) {
|
|
643
|
+
const sessionPath = await findRecoverableClaudeSessionPath(input.sessionId, input.env ?? process.env);
|
|
644
|
+
if (!sessionPath) return null;
|
|
645
|
+
const metadata = await stat2(sessionPath).catch(() => null);
|
|
646
|
+
if (!metadata?.isFile()) return null;
|
|
647
|
+
return {
|
|
648
|
+
fingerprint: `claude:${input.sessionId}:${Math.trunc(metadata.mtimeMs)}:${metadata.size}`,
|
|
649
|
+
observedAt: Date.now()
|
|
650
|
+
};
|
|
651
|
+
}
|
|
642
652
|
async function readClaudeSessionMetadata(filePath) {
|
|
643
653
|
const content = await readFile2(filePath, "utf8");
|
|
644
654
|
let aiTitle;
|
|
@@ -865,6 +875,16 @@ async function findRecoverableCodexSessionPath(sessionId, env = process.env) {
|
|
|
865
875
|
}
|
|
866
876
|
return await walk(root, 0);
|
|
867
877
|
}
|
|
878
|
+
async function getCodexNativeVersion(input) {
|
|
879
|
+
const sessionPath = await findRecoverableCodexSessionPath(input.sessionId, input.env ?? process.env);
|
|
880
|
+
if (!sessionPath) return null;
|
|
881
|
+
const metadata = await stat3(sessionPath).catch(() => null);
|
|
882
|
+
if (!metadata?.isFile()) return null;
|
|
883
|
+
return {
|
|
884
|
+
fingerprint: `codex:${input.sessionId}:${Math.trunc(metadata.mtimeMs)}:${metadata.size}`,
|
|
885
|
+
observedAt: Date.now()
|
|
886
|
+
};
|
|
887
|
+
}
|
|
868
888
|
async function readCodexSessionIndex(env) {
|
|
869
889
|
const indexPath = join4(env.CODEX_HOME || join4(env.HOME || homedir3(), ".codex"), "session_index.jsonl");
|
|
870
890
|
const index = /* @__PURE__ */ new Map();
|
|
@@ -2786,7 +2806,7 @@ function isTemporaryShim(candidate) {
|
|
|
2786
2806
|
const tempDir = tmpdir();
|
|
2787
2807
|
return candidate.startsWith(tempDir);
|
|
2788
2808
|
}
|
|
2789
|
-
async function findExecutable(command) {
|
|
2809
|
+
async function findExecutable(command, pathEnv) {
|
|
2790
2810
|
const extensions = executableExtensions();
|
|
2791
2811
|
if (command.includes("/") || command.includes("\\")) {
|
|
2792
2812
|
for (const ext of extensions) {
|
|
@@ -2794,7 +2814,7 @@ async function findExecutable(command) {
|
|
|
2794
2814
|
}
|
|
2795
2815
|
return void 0;
|
|
2796
2816
|
}
|
|
2797
|
-
const dirs = (
|
|
2817
|
+
const dirs = (pathEnv ?? "").split(delimiter).filter(Boolean);
|
|
2798
2818
|
let fallback;
|
|
2799
2819
|
for (const dir of dirs) {
|
|
2800
2820
|
for (const ext of extensions) {
|
|
@@ -2836,6 +2856,71 @@ function statePath(filename) {
|
|
|
2836
2856
|
return join9(tmpdir(), filename);
|
|
2837
2857
|
}
|
|
2838
2858
|
|
|
2859
|
+
// src/shared/loginShellEnv.ts
|
|
2860
|
+
import { spawnSync } from "node:child_process";
|
|
2861
|
+
import { delimiter as delimiter2 } from "node:path";
|
|
2862
|
+
var DELIMITER = "__CCW_LOGIN_ENV_DELIM_5f3a2b7c__";
|
|
2863
|
+
function parseEnvBlock(block) {
|
|
2864
|
+
const env = {};
|
|
2865
|
+
let currentKey = null;
|
|
2866
|
+
const normalized = block.replace(/\n$/, "");
|
|
2867
|
+
for (const line of normalized.split("\n")) {
|
|
2868
|
+
const match = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/.exec(line);
|
|
2869
|
+
if (match) {
|
|
2870
|
+
currentKey = match[1];
|
|
2871
|
+
env[currentKey] = match[2];
|
|
2872
|
+
} else if (currentKey) {
|
|
2873
|
+
env[currentKey] = `${env[currentKey]}
|
|
2874
|
+
${line}`;
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
return env;
|
|
2878
|
+
}
|
|
2879
|
+
function captureLoginShellEnv(deps = {}) {
|
|
2880
|
+
const platform = deps.platform ?? process.platform;
|
|
2881
|
+
if (platform === "win32") return null;
|
|
2882
|
+
const run = deps.run ?? spawnSync;
|
|
2883
|
+
const shell = deps.shell ?? process.env.SHELL ?? "/bin/zsh";
|
|
2884
|
+
const timeoutMs = deps.timeoutMs ?? 5e3;
|
|
2885
|
+
const command = `printf %s '${DELIMITER}'; env; printf %s '${DELIMITER}'`;
|
|
2886
|
+
try {
|
|
2887
|
+
const result = run(shell, ["-l", "-i", "-c", command], {
|
|
2888
|
+
timeout: timeoutMs,
|
|
2889
|
+
encoding: "utf8",
|
|
2890
|
+
maxBuffer: 8 * 1024 * 1024
|
|
2891
|
+
});
|
|
2892
|
+
const stdout = typeof result.stdout === "string" ? result.stdout : "";
|
|
2893
|
+
const start = stdout.indexOf(DELIMITER);
|
|
2894
|
+
const end = stdout.indexOf(DELIMITER, start + DELIMITER.length);
|
|
2895
|
+
if (start === -1 || end === -1 || end <= start) return null;
|
|
2896
|
+
const block = stdout.slice(start + DELIMITER.length, end);
|
|
2897
|
+
const env = parseEnvBlock(block);
|
|
2898
|
+
if (!env.PATH) return null;
|
|
2899
|
+
return env;
|
|
2900
|
+
} catch {
|
|
2901
|
+
return null;
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
var cache;
|
|
2905
|
+
function resolveLoginShellEnv() {
|
|
2906
|
+
if (cache !== void 0) return cache;
|
|
2907
|
+
cache = captureLoginShellEnv();
|
|
2908
|
+
if (cache === null && process.platform !== "win32") {
|
|
2909
|
+
console.warn(
|
|
2910
|
+
"[claude-codex-wechat] \u7EC8\u7AEF\u73AF\u5883\u590D\u523B\u5931\u8D25\uFF0C\u5DF2\u9000\u56DE process.env\uFF08PATH/\u51ED\u8BC1\u53EF\u80FD\u4E0E\u7EC8\u7AEF\u4E0D\u4E00\u81F4\uFF09\u3002\u82E5 provider \u62A5\u300C\u627E\u4E0D\u5230\u300D\u6216\u300C\u4EE4\u724C\u5DF2\u8FC7\u671F\u300D\uFF0C\u8BF7\u4ECE\u4EA4\u4E92\u7EC8\u7AEF\u91CD\u542F daemon\u3002"
|
|
2911
|
+
);
|
|
2912
|
+
}
|
|
2913
|
+
return cache;
|
|
2914
|
+
}
|
|
2915
|
+
function resolveTerminalSearchPath() {
|
|
2916
|
+
return mergeSearchPath(resolveLoginShellEnv()?.PATH, process.env.PATH);
|
|
2917
|
+
}
|
|
2918
|
+
function mergeSearchPath(primary, fallback) {
|
|
2919
|
+
if (!primary) return fallback;
|
|
2920
|
+
if (!fallback) return primary;
|
|
2921
|
+
return `${primary}${delimiter2}${fallback}`;
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2839
2924
|
// src/providers/claude-code/assistantContent.ts
|
|
2840
2925
|
function extractAssistantBlocks(message) {
|
|
2841
2926
|
if (!message || typeof message !== "object") return [];
|
|
@@ -2950,12 +3035,12 @@ var BRIDGE_APPEND_SYSTEM_PROMPT = [
|
|
|
2950
3035
|
|
|
2951
3036
|
// src/providers/claude-code/claudeCapabilities.ts
|
|
2952
3037
|
import { spawn as spawn2 } from "node:child_process";
|
|
2953
|
-
var
|
|
3038
|
+
var cache2 = /* @__PURE__ */ new Map();
|
|
2954
3039
|
var probeAppendSystemPromptSupport = (command) => {
|
|
2955
|
-
const cached =
|
|
3040
|
+
const cached = cache2.get(command);
|
|
2956
3041
|
if (cached) return cached;
|
|
2957
3042
|
const result = runHelpProbe(command);
|
|
2958
|
-
|
|
3043
|
+
cache2.set(command, result);
|
|
2959
3044
|
return result;
|
|
2960
3045
|
};
|
|
2961
3046
|
function runHelpProbe(command) {
|
|
@@ -3204,7 +3289,7 @@ function parseJsonLine(line) {
|
|
|
3204
3289
|
function defaultClaudeStreamSpawner(call, opts = {}) {
|
|
3205
3290
|
const stderrCapBytes = opts.stderrCapBytes ?? 64 * 1024;
|
|
3206
3291
|
const maxLineBytes = opts.maxLineBytes ?? 10 * 1024 * 1024;
|
|
3207
|
-
const child = spawn3(call.command, call.args, { cwd: expandTilde(call.cwd) ?? call.cwd, stdio: ["pipe", "pipe", "pipe"], shell: useShellForCli() });
|
|
3292
|
+
const child = spawn3(call.command, call.args, { cwd: expandTilde(call.cwd) ?? call.cwd, stdio: ["pipe", "pipe", "pipe"], shell: useShellForCli(), env: resolveLoginShellEnv() ?? process.env });
|
|
3208
3293
|
let stderr = "";
|
|
3209
3294
|
let buffer = "";
|
|
3210
3295
|
const queue = [];
|
|
@@ -3299,6 +3384,12 @@ var ClaudeCodeProvider = class {
|
|
|
3299
3384
|
async listRecoverableSessions() {
|
|
3300
3385
|
return await listRecoverableClaudeSessions();
|
|
3301
3386
|
}
|
|
3387
|
+
async getNativeVersion(input) {
|
|
3388
|
+
return await getClaudeNativeVersion({
|
|
3389
|
+
sessionId: input.providerSessionId,
|
|
3390
|
+
cwd: input.cwd
|
|
3391
|
+
});
|
|
3392
|
+
}
|
|
3302
3393
|
async attachSession(input) {
|
|
3303
3394
|
return await this.options.runner.startSession({
|
|
3304
3395
|
bridgeSessionId: input.bridgeSessionId,
|
|
@@ -3323,7 +3414,8 @@ var CodexAppServerClient = class {
|
|
|
3323
3414
|
this.child = spawn4(command, ["app-server", "--listen", "stdio://"], {
|
|
3324
3415
|
cwd: input.cwd,
|
|
3325
3416
|
stdio: ["pipe", "pipe", "pipe"],
|
|
3326
|
-
shell: useShellForCli()
|
|
3417
|
+
shell: useShellForCli(),
|
|
3418
|
+
env: resolveLoginShellEnv() ?? process.env
|
|
3327
3419
|
});
|
|
3328
3420
|
this.child.stdout.on("data", (chunk) => this.onStdout(String(chunk)));
|
|
3329
3421
|
this.child.stderr.on("data", () => {
|
|
@@ -3784,6 +3876,12 @@ var CodexProvider = class {
|
|
|
3784
3876
|
async listRecoverableSessions() {
|
|
3785
3877
|
return await listRecoverableCodexSessions();
|
|
3786
3878
|
}
|
|
3879
|
+
async getNativeVersion(input) {
|
|
3880
|
+
return await getCodexNativeVersion({
|
|
3881
|
+
sessionId: input.providerSessionId,
|
|
3882
|
+
cwd: input.cwd
|
|
3883
|
+
});
|
|
3884
|
+
}
|
|
3787
3885
|
async attachSession(input) {
|
|
3788
3886
|
return await this.options.runner.startSession({
|
|
3789
3887
|
bridgeSessionId: input.bridgeSessionId,
|
|
@@ -3954,6 +4052,9 @@ function parseBridgeCommand(input) {
|
|
|
3954
4052
|
if (command === "/resume") {
|
|
3955
4053
|
return { kind: "resume_session", ref: first ?? "" };
|
|
3956
4054
|
}
|
|
4055
|
+
if (command === "/reload") {
|
|
4056
|
+
return { kind: "reload_session" };
|
|
4057
|
+
}
|
|
3957
4058
|
if (command === "/new") {
|
|
3958
4059
|
if (!first) return { kind: "new_session", providerId: null, cwd: null };
|
|
3959
4060
|
const colonIndex = first.indexOf(":");
|
|
@@ -3983,7 +4084,8 @@ var BRIDGE_COMMAND_HELP_GROUPS = [
|
|
|
3983
4084
|
{ command: "/new claude|codex", desc: "\u65B0\u5EFA\u6307\u5B9A provider \u4F1A\u8BDD" },
|
|
3984
4085
|
{ command: "/new <\u76EE\u5F55>", desc: "\u5728\u6307\u5B9A\u76EE\u5F55\u6309\u5F53\u524D provider \u65B0\u5EFA\u4F1A\u8BDD" },
|
|
3985
4086
|
{ command: "/new claude:<\u76EE\u5F55>", desc: "\u65B0\u5EFA\u6307\u5B9A provider + \u6307\u5B9A\u76EE\u5F55\u4F1A\u8BDD" },
|
|
3986
|
-
{ command: "/stop", desc: "\u4E2D\u65AD\u5F53\u524D\u6B63\u5728\u751F\u6210\u7684\u56DE\u590D\uFF08\u4F1A\u8BDD\u4FDD\u7559\uFF09" }
|
|
4087
|
+
{ command: "/stop", desc: "\u4E2D\u65AD\u5F53\u524D\u6B63\u5728\u751F\u6210\u7684\u56DE\u590D\uFF08\u4F1A\u8BDD\u4FDD\u7559\uFF09" },
|
|
4088
|
+
{ command: "/reload", desc: "\u5F53\u524D\u4F1A\u8BDD\u5DF2\u88AB\u53E6\u4E00\u7AEF\u7EE7\u7EED\u540E\uFF0C\u91CD\u8F7D\u539F\u751F\u4F1A\u8BDD\u72B6\u6001\u518D\u7EE7\u7EED" }
|
|
3987
4089
|
]
|
|
3988
4090
|
},
|
|
3989
4091
|
{
|
|
@@ -4276,6 +4378,36 @@ var MessageRouter = class _MessageRouter {
|
|
|
4276
4378
|
const provider = this.providers.get(session.providerId);
|
|
4277
4379
|
void Promise.resolve(provider?.stopSession(session.id)).catch(() => void 0);
|
|
4278
4380
|
}
|
|
4381
|
+
async ensureSessionFresh(session, provider) {
|
|
4382
|
+
if (!session.providerSessionId || !provider.getNativeVersion) return { ok: true };
|
|
4383
|
+
const version = await provider.getNativeVersion({
|
|
4384
|
+
providerSessionId: session.providerSessionId,
|
|
4385
|
+
cwd: session.cwd
|
|
4386
|
+
}).catch(() => null);
|
|
4387
|
+
if (!version || !session.lastSeenNativeFingerprint) return { ok: true };
|
|
4388
|
+
if (version.fingerprint === session.lastSeenNativeFingerprint) return { ok: true };
|
|
4389
|
+
this.conversation.update({
|
|
4390
|
+
staleReason: "native_advanced_elsewhere",
|
|
4391
|
+
lastActivityAt: Date.now()
|
|
4392
|
+
}, session.id);
|
|
4393
|
+
return {
|
|
4394
|
+
ok: false,
|
|
4395
|
+
message: "\u8BE5\u4F1A\u8BDD\u5DF2\u5728\u53E6\u4E00\u7AEF\u7EE7\u7EED\uFF0C\u5F53\u524D\u6865\u63A5\u72B6\u6001\u5DF2\u8FC7\u671F\u3002\u8BF7\u5148 /reload \u540E\u518D\u7EE7\u7EED\u3002"
|
|
4396
|
+
};
|
|
4397
|
+
}
|
|
4398
|
+
async refreshNativeFingerprint(session, provider) {
|
|
4399
|
+
if (!session.providerSessionId || !provider.getNativeVersion) return;
|
|
4400
|
+
const version = await provider.getNativeVersion({
|
|
4401
|
+
providerSessionId: session.providerSessionId,
|
|
4402
|
+
cwd: session.cwd
|
|
4403
|
+
}).catch(() => null);
|
|
4404
|
+
if (!version) return;
|
|
4405
|
+
this.conversation.update({
|
|
4406
|
+
lastSeenNativeFingerprint: version.fingerprint,
|
|
4407
|
+
staleReason: void 0,
|
|
4408
|
+
lastActivityAt: Date.now()
|
|
4409
|
+
}, session.id);
|
|
4410
|
+
}
|
|
4279
4411
|
async runChatGeneration(message, user, text, seq) {
|
|
4280
4412
|
const superseded = () => (this.latestMutatingSeq.get(message.chatId) ?? 0) > seq;
|
|
4281
4413
|
if (superseded()) return;
|
|
@@ -4327,6 +4459,11 @@ var MessageRouter = class _MessageRouter {
|
|
|
4327
4459
|
}
|
|
4328
4460
|
await this.persistBridgeMetadata(updated);
|
|
4329
4461
|
}
|
|
4462
|
+
const freshness = await this.ensureSessionFresh(this.conversation.getCurrent() ?? session, provider);
|
|
4463
|
+
if (!freshness.ok) {
|
|
4464
|
+
await this.sendToChat({ chatId: message.chatId, kind: "status", text: freshness.message });
|
|
4465
|
+
return;
|
|
4466
|
+
}
|
|
4330
4467
|
const genId = ++this.generationSeq;
|
|
4331
4468
|
let abortGeneration;
|
|
4332
4469
|
const aborted = new Promise((resolve2) => {
|
|
@@ -4403,6 +4540,10 @@ var MessageRouter = class _MessageRouter {
|
|
|
4403
4540
|
const finalBinding = this.conversation.getCurrent();
|
|
4404
4541
|
if (finalBinding?.id === session.id && finalBinding.providerSessionId) {
|
|
4405
4542
|
await this.persistBridgeMetadata(finalBinding).catch(() => void 0);
|
|
4543
|
+
const refreshedBinding = this.conversation.getCurrent();
|
|
4544
|
+
if (refreshedBinding?.id === session.id && refreshedBinding.providerSessionId) {
|
|
4545
|
+
await this.refreshNativeFingerprint(refreshedBinding, provider).catch(() => void 0);
|
|
4546
|
+
}
|
|
4406
4547
|
}
|
|
4407
4548
|
}
|
|
4408
4549
|
} finally {
|
|
@@ -4438,6 +4579,44 @@ var MessageRouter = class _MessageRouter {
|
|
|
4438
4579
|
await this.sendToChat({ chatId, kind: "status", text: "\u5DF2\u4E2D\u65AD\u5F53\u524D\u751F\u6210\uFF0C\u4F1A\u8BDD\u4FDD\u7559" });
|
|
4439
4580
|
return;
|
|
4440
4581
|
}
|
|
4582
|
+
if (command.kind === "reload_session") {
|
|
4583
|
+
this.pendingChoices.delete(chatId);
|
|
4584
|
+
const current = this.conversation.getCurrent();
|
|
4585
|
+
if (!current) {
|
|
4586
|
+
await this.sendToChat({ chatId, kind: "status", text: "No active session" });
|
|
4587
|
+
return;
|
|
4588
|
+
}
|
|
4589
|
+
if (!current.providerSessionId) {
|
|
4590
|
+
await this.sendToChat({ chatId, kind: "status", text: "\u5F53\u524D\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u539F\u751F provider \u4F1A\u8BDD\u53EF\u91CD\u8F7D" });
|
|
4591
|
+
return;
|
|
4592
|
+
}
|
|
4593
|
+
const provider = this.providers.get(current.providerId);
|
|
4594
|
+
if (!provider?.attachSession) {
|
|
4595
|
+
await this.sendToChat({ chatId, kind: "status", text: `\u5F53\u524D provider\uFF08${current.providerId}\uFF09\u4E0D\u652F\u6301\u4F1A\u8BDD\u91CD\u8F7D` });
|
|
4596
|
+
return;
|
|
4597
|
+
}
|
|
4598
|
+
await this.preemptActiveGeneration(chatId);
|
|
4599
|
+
this.recycleProviderProcess(current);
|
|
4600
|
+
const reattached = await provider.attachSession({
|
|
4601
|
+
candidateId: current.providerSessionId,
|
|
4602
|
+
bridgeSessionId: current.id,
|
|
4603
|
+
cwd: current.cwd
|
|
4604
|
+
});
|
|
4605
|
+
const version = await provider.getNativeVersion?.({
|
|
4606
|
+
providerSessionId: reattached.providerSessionId ?? current.providerSessionId,
|
|
4607
|
+
cwd: current.cwd
|
|
4608
|
+
}).catch(() => null);
|
|
4609
|
+
this.conversation.update({
|
|
4610
|
+
providerSessionId: reattached.providerSessionId ?? current.providerSessionId,
|
|
4611
|
+
status: reattached.status,
|
|
4612
|
+
lastSeenNativeFingerprint: version?.fingerprint,
|
|
4613
|
+
lastReloadedAt: Date.now(),
|
|
4614
|
+
staleReason: void 0,
|
|
4615
|
+
lastActivityAt: Date.now()
|
|
4616
|
+
}, current.id);
|
|
4617
|
+
await this.sendToChat({ chatId, kind: "status", text: "\u5DF2\u91CD\u65B0\u52A0\u8F7D\u5F53\u524D\u4F1A\u8BDD\uFF0C\u53EF\u7EE7\u7EED\u5BF9\u8BDD\u3002" });
|
|
4618
|
+
return;
|
|
4619
|
+
}
|
|
4441
4620
|
if (command.kind === "new_session") {
|
|
4442
4621
|
this.pendingChoices.delete(chatId);
|
|
4443
4622
|
const previousSession = this.conversation.getCurrent();
|
|
@@ -5494,8 +5673,9 @@ function listLanIpv4Addresses() {
|
|
|
5494
5673
|
return Object.values(networkInterfaces()).flat().filter((iface) => Boolean(iface)).filter((iface) => iface.family === "IPv4" && !iface.internal).map((iface) => iface.address);
|
|
5495
5674
|
}
|
|
5496
5675
|
async function resolveProviderCommands(providers) {
|
|
5497
|
-
const
|
|
5498
|
-
const
|
|
5676
|
+
const searchPath = resolveTerminalSearchPath();
|
|
5677
|
+
const claudeCommand = providers?.claude?.command ?? await findExecutable("claude", searchPath);
|
|
5678
|
+
const codexCommand = providers?.codex?.command ?? await findExecutable("codex", searchPath);
|
|
5499
5679
|
if (!claudeCommand && !codexCommand) return void 0;
|
|
5500
5680
|
return {
|
|
5501
5681
|
...claudeCommand ? { claude: { command: claudeCommand } } : {},
|
|
@@ -6063,9 +6243,10 @@ async function cmdDoctor() {
|
|
|
6063
6243
|
console.log("claude-codex-wechat doctor\n");
|
|
6064
6244
|
report("\u914D\u7F6E\u6587\u4EF6", existsSync11(configPath) ? configPath : `\u7F3A\u5931 (${configPath})\uFF0C\u9996\u6B21 start \u65F6\u81EA\u52A8\u521B\u5EFA`);
|
|
6065
6245
|
report("\u524D\u7AEF\u4EA7\u7269", existsSync11(webRoot) ? webRoot : `\u7F3A\u5931 (${webRoot})`);
|
|
6066
|
-
const
|
|
6246
|
+
const searchPath = resolveTerminalSearchPath();
|
|
6247
|
+
const claude = await findExecutable("claude", searchPath);
|
|
6067
6248
|
report("claude \u53EF\u6267\u884C", claude ?? "\u672A\u627E\u5230\uFF0C\u9700\u5148\u5B89\u88C5\u5E76\u767B\u5F55 Claude Code");
|
|
6068
|
-
const codex = await findExecutable("codex");
|
|
6249
|
+
const codex = await findExecutable("codex", searchPath);
|
|
6069
6250
|
report("codex \u53EF\u6267\u884C", codex ?? "\u672A\u627E\u5230\uFF08\u4EC5\u4F7F\u7528 Claude \u65F6\u53EF\u5FFD\u7565\uFF09");
|
|
6070
6251
|
if (existsSync11(configPath)) {
|
|
6071
6252
|
const config = loadBridgeConfig(configPath);
|