


























@@ -3,7 +3,7 @@ import fs from "node:fs/promises";
33import os from "node:os";
44import path from "node:path";
55import { promisify } from "node:util";
6-import { afterEach, describe, expect, it } from "vitest";
6+import { afterEach, describe, expect, it, vi } from "vitest";
77import { prepareAcpxCodexAuthConfig } from "./codex-auth-bridge.js";
88import { resolveAcpxPluginConfig } from "./config.js";
99@@ -66,6 +66,7 @@ function expectClaudeWrapperCommand(command: string | undefined, wrapperPath: st
6666}
67676868afterEach(async () => {
69+vi.restoreAllMocks();
6970restoreEnv("CODEX_HOME");
7071restoreEnv("OPENCLAW_AGENT_DIR");
7172restoreEnv("PI_CODING_AGENT_DIR");
@@ -114,6 +115,31 @@ describe("prepareAcpxCodexAuthConfig", () => {
114115).rejects.toMatchObject({ code: "ENOENT" });
115116});
116117118+it("keeps generated wrappers usable when chmod is rejected by the state filesystem", async () => {
119+const root = await makeTempDir();
120+const stateDir = path.join(root, "state");
121+const generatedCodex = generatedCodexPaths(stateDir);
122+const generatedClaude = generatedClaudePaths(stateDir);
123+const chmodError = Object.assign(new Error("operation not permitted"), { code: "EPERM" });
124+const chmodSpy = vi.spyOn(fs, "chmod").mockRejectedValue(chmodError);
125+const pluginConfig = resolveAcpxPluginConfig({
126+rawConfig: {},
127+workspaceDir: root,
128+});
129+130+const resolved = await prepareAcpxCodexAuthConfig({
131+ pluginConfig,
132+ stateDir,
133+});
134+135+expect(chmodSpy).toHaveBeenCalledWith(generatedCodex.wrapperPath, 0o755);
136+expect(chmodSpy).toHaveBeenCalledWith(generatedClaude.wrapperPath, 0o755);
137+expectCodexWrapperCommand(resolved.agents.codex, generatedCodex.wrapperPath);
138+expectClaudeWrapperCommand(resolved.agents.claude, generatedClaude.wrapperPath);
139+await expect(fs.access(generatedCodex.wrapperPath)).resolves.toBeUndefined();
140+await expect(fs.access(generatedClaude.wrapperPath)).resolves.toBeUndefined();
141+});
142+117143it("falls back to the current Codex ACP package range when the local adapter is unavailable", async () => {
118144const root = await makeTempDir();
119145const stateDir = path.join(root, "state");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。