From 95b488dfa6234ba93f6ea90980ab0509814ae6f4 Mon Sep 17 00:00:00 2001 From: unclee Date: Thu, 5 Mar 2026 03:00:39 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20clone=5Fremote=20=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E5=86=B3=E7=AD=96=E5=AE=9E=E9=99=85=E6=89=A7=E8=A1=8C=E4=BB=93?= =?UTF-8?q?=E5=BA=93=E5=85=8B=E9=9A=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clone_remote 决策返回时,thread-context.ts 仅取 decision.workdir (对 clone_remote 为 undefined)回退到默认目录 /root/dev/, 从未调用 setupWorkspace 执行实际克隆。 修复: 检测到 clone_remote + repo_url 时,调用 setupWorkspace 通过 bare cache 克隆到隔离工作区,与 use_existing 的隔离逻辑对齐。 Co-Authored-By: Claude Opus 4.6 --- src/feishu/thread-context.ts | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/feishu/thread-context.ts b/src/feishu/thread-context.ts index 11e3baf8..35fc902c 100644 --- a/src/feishu/thread-context.ts +++ b/src/feishu/thread-context.ts @@ -5,6 +5,7 @@ import { logger } from '../utils/logger.js'; import { sessionManager } from '../session/manager.js'; import { routeWorkspace } from '../claude/router.js'; import { isAutoWorkspacePath, ensureIsolatedWorkspace } from '../workspace/isolation.js'; +import { setupWorkspace } from '../workspace/manager.js'; import { isOwner } from '../utils/security.js'; import { consumePreApproved } from './approval.js'; import { ensureThread } from './thread-utils.js'; @@ -154,13 +155,20 @@ export async function resolveThreadContext(params: ResolveParams): Promise Date: Thu, 5 Mar 2026 12:58:00 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E6=8F=90=E5=8F=96=20resolveWorkdir?= =?UTF-8?q?=20=E6=B6=88=E9=99=A4=E9=87=8D=E5=A4=8D=E7=9A=84=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=8C=BA=E5=88=9B=E5=BB=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit address PR review feedback — 将 clone_remote / use_existing 的工作区 创建逻辑提取为共享 resolveWorkdir 函数,消除两处路由路径中的重复代码。 Co-Authored-By: Claude Opus 4.6 --- src/feishu/thread-context.ts | 49 +++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/feishu/thread-context.ts b/src/feishu/thread-context.ts index 35fc902c..cb910af3 100644 --- a/src/feishu/thread-context.ts +++ b/src/feishu/thread-context.ts @@ -3,7 +3,7 @@ import { basename } from 'node:path'; import { config } from '../config.js'; import { logger } from '../utils/logger.js'; import { sessionManager } from '../session/manager.js'; -import { routeWorkspace } from '../claude/router.js'; +import { routeWorkspace, type RoutingDecision } from '../claude/router.js'; import { isAutoWorkspacePath, ensureIsolatedWorkspace } from '../workspace/isolation.js'; import { setupWorkspace } from '../workspace/manager.js'; import { isOwner } from '../utils/security.js'; @@ -57,6 +57,25 @@ export interface ResolveParams { pipelineMode?: boolean; } +/** + * 根据路由决策创建或隔离工作区 + * + * clone_remote: 通过 setupWorkspace 从 bare cache 克隆到隔离工作区 + * use_existing / use_default: 通过 ensureIsolatedWorkspace 隔离本地仓库 + */ +function resolveWorkdir( + decision: RoutingDecision, + isolationMode: 'readonly' | 'writable', +): { workingDir: string; warning?: string } { + if (decision.decision === 'clone_remote' && decision.repo_url) { + const result = setupWorkspace({ repoUrl: decision.repo_url, mode: isolationMode }); + return { workingDir: result.workspacePath, warning: result.warning }; + } + const workingDir = decision.workdir || config.claude.defaultWorkDir; + const isolated = ensureIsolatedWorkspace(workingDir, isolationMode); + return { workingDir: isolated.workingDir, warning: isolated.warning }; +} + /** * 解析话题上下文(thread + 路由 + 工作区隔离 + greeting) * @@ -158,17 +177,9 @@ export async function resolveThreadContext(params: ResolveParams): Promise Date: Thu, 5 Mar 2026 13:01:47 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E4=BC=A0=E9=80=92=20decision.branch?= =?UTF-8?q?=20=E5=88=B0=20setupWorkspace=20sourceBranch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit address PR review feedback — clone_remote 时将路由决策的 branch 字段传递给 setupWorkspace,支持指定分支克隆。 Co-Authored-By: Claude Opus 4.6 --- src/feishu/thread-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/feishu/thread-context.ts b/src/feishu/thread-context.ts index cb910af3..318d4718 100644 --- a/src/feishu/thread-context.ts +++ b/src/feishu/thread-context.ts @@ -68,7 +68,7 @@ function resolveWorkdir( isolationMode: 'readonly' | 'writable', ): { workingDir: string; warning?: string } { if (decision.decision === 'clone_remote' && decision.repo_url) { - const result = setupWorkspace({ repoUrl: decision.repo_url, mode: isolationMode }); + const result = setupWorkspace({ repoUrl: decision.repo_url, mode: isolationMode, sourceBranch: decision.branch }); return { workingDir: result.workspacePath, warning: result.warning }; } const workingDir = decision.workdir || config.claude.defaultWorkDir;