


























@@ -8,6 +8,7 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js";
88import { runEmbeddedAgent, type EmbeddedAgentRunResult } from "../embedded-agent.js";
99import { FailoverError } from "../failover-error.js";
1010import { persistCliTurnTranscript, runAgentAttempt } from "./attempt-execution.js";
11+import { resolveClaudeCliProjectDirForWorkspace } from "./claude-cli-project-dir.js";
11121213const runCliAgentMock = vi.hoisted(() => vi.fn());
1314const runEmbeddedAgentMock = vi.hoisted(() => vi.fn());
@@ -179,6 +180,7 @@ describe("CLI attempt execution", () => {
179180sessionStore: Record<string, SessionEntry>;
180181body: string;
181182runId: string;
183+cwd?: string;
182184}) {
183185await runAgentAttempt({
184186providerOverride: "claude-cli",
@@ -191,6 +193,7 @@ describe("CLI attempt execution", () => {
191193sessionAgentId: "main",
192194sessionFile: path.join(tmpDir, "session.jsonl"),
193195workspaceDir: tmpDir,
196+cwd: params.cwd,
194197body: params.body,
195198isFallbackRetry: false,
196199resolvedThinkLevel: "medium",
@@ -213,7 +216,10 @@ describe("CLI attempt execution", () => {
213216214217async function writeClaudeCliAssistantTranscript(cliSessionId: string) {
215218const homeDir = path.join(tmpDir, `home-${cliSessionId}`);
216-const projectsDir = path.join(homeDir, ".claude", "projects", "demo-workspace");
219+const projectsDir = resolveClaudeCliProjectDirForWorkspace({
220+workspaceDir: tmpDir,
221+ homeDir,
222+});
217223process.env.HOME = homeDir;
218224await fs.mkdir(projectsDir, { recursive: true });
219225await fs.writeFile(
@@ -247,7 +253,10 @@ describe("CLI attempt execution", () => {
247253it("clears stale Claude CLI session IDs before retrying after session expiration", async () => {
248254const sessionKey = "agent:main:subagent:cli-expired";
249255const homeDir = path.join(tmpDir, "home");
250-const projectsDir = path.join(homeDir, ".claude", "projects", "demo-workspace");
256+const projectsDir = resolveClaudeCliProjectDirForWorkspace({
257+workspaceDir: tmpDir,
258+ homeDir,
259+});
251260process.env.HOME = homeDir;
252261await fs.mkdir(projectsDir, { recursive: true });
253262await fs.writeFile(
@@ -437,7 +446,10 @@ describe("CLI attempt execution", () => {
437446const sessionKey = "agent:main:direct:claude-transcript-present";
438447const cliSessionId = "existing-claude-session";
439448const homeDir = path.join(tmpDir, "home");
440-const projectsDir = path.join(homeDir, ".claude", "projects", "demo-workspace");
449+const projectsDir = resolveClaudeCliProjectDirForWorkspace({
450+workspaceDir: tmpDir,
451+ homeDir,
452+});
441453process.env.HOME = homeDir;
442454await fs.mkdir(projectsDir, { recursive: true });
443455await fs.writeFile(
@@ -485,6 +497,48 @@ describe("CLI attempt execution", () => {
485497expect(sessionStore[sessionKey]?.claudeCliSessionId).toBe(cliSessionId);
486498});
487499500+it("checks Claude CLI transcript content under the process cwd", async () => {
501+const sessionKey = "agent:main:direct:claude-transcript-cwd-present";
502+const cliSessionId = "existing-claude-cwd-session";
503+const homeDir = path.join(tmpDir, "home");
504+const cwd = path.join(tmpDir, "task");
505+const projectsDir = resolveClaudeCliProjectDirForWorkspace({
506+workspaceDir: cwd,
507+ homeDir,
508+});
509+process.env.HOME = homeDir;
510+await fs.mkdir(projectsDir, { recursive: true });
511+await fs.writeFile(
512+path.join(projectsDir, `${cliSessionId}.jsonl`),
513+`${JSON.stringify({
514+ type: "assistant",
515+ message: {
516+ role: "assistant",
517+ content: [{ type: "text", text: "previous reply" }],
518+ },
519+ })}\n`,
520+"utf-8",
521+);
522+const sessionEntry = makeClaudeCliSessionEntry("openclaw-session-cwd", cliSessionId);
523+const sessionStore: Record<string, SessionEntry> = { [sessionKey]: sessionEntry };
524+await fs.writeFile(storePath, JSON.stringify(sessionStore, null, 2), "utf-8");
525+runCliAgentMock.mockResolvedValueOnce(makeCliResult("resumed cli response"));
526+527+await runClaudeCliAttempt({
528+ sessionKey,
529+ sessionEntry,
530+ sessionStore,
531+body: "continue from task cwd",
532+runId: "run-cli-transcript-cwd-present",
533+ cwd,
534+});
535+536+expect(runCliAgentMock).toHaveBeenCalledTimes(1);
537+expect(firstRunCliAgentArg().cliSessionId).toBe(cliSessionId);
538+expect(firstRunCliAgentArg().cwd).toBe(cwd);
539+expect(sessionStore[sessionKey]?.cliSessionIds?.["claude-cli"]).toBe(cliSessionId);
540+});
541+488542it("passes session-bound OpenAI Codex auth profile to codex-cli aliases", async () => {
489543const sessionKey = "agent:main:direct:codex-cli-auth-alias";
490544const sessionEntry: SessionEntry = {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。