From 6d6888343d4304cd0c56530362f295b90df85dca Mon Sep 17 00:00:00 2001 From: xiao Date: Fri, 19 Jun 2026 21:35:24 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20/cwd=20=E5=88=87=E6=8D=A2=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E7=9B=AE=E5=BD=95=E5=89=8D=E6=A0=A1=E9=AA=8C=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E5=AD=98=E5=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /cwd 原来直接把参数写入 session、不做任何校验,输错路径后下次对话 claude 会在不存在的 cwd 里 spawn 失败,错误很隐晦、难排查。 - 展开 ~、把相对路径解析为绝对路径(基于当前工作目录) - 校验目标存在且确实是目录,否则提示并拒绝切换 - 存储解析后的绝对路径,与 /send 的校验风格保持一致 --- src/commands/handlers.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/commands/handlers.ts b/src/commands/handlers.ts index 25586df..edde38f 100644 --- a/src/commands/handlers.ts +++ b/src/commands/handlers.ts @@ -67,8 +67,17 @@ export function handleCwd(ctx: CommandContext, args: string): CommandResult { if (!args) { return { reply: `当前工作目录: ${ctx.session.workingDirectory}\n用法: /cwd <路径>`, handled: true }; } - ctx.updateSession({ workingDirectory: args }); - return { reply: `✅ 工作目录已切换为: ${args}`, handled: true }; + // 展开 ~ 并解析为绝对路径(相对路径基于当前工作目录),切换前校验目录确实存在 + const expanded = args.replace(/^~/, homedir()); + const resolved = expanded.startsWith('/') ? expanded : resolve(ctx.session.workingDirectory, expanded); + if (!existsSync(resolved)) { + return { reply: `目录不存在: ${resolved}\n请检查路径后重试。`, handled: true }; + } + if (!statSync(resolved).isDirectory()) { + return { reply: `这不是一个目录: ${resolved}`, handled: true }; + } + ctx.updateSession({ workingDirectory: resolved }); + return { reply: `✅ 工作目录已切换为: ${resolved}`, handled: true }; } export function handleModel(ctx: CommandContext, args: string): CommandResult { From 0cd9dfce09317222248b120357485c5c9544b3ad Mon Sep 17 00:00:00 2001 From: xiao Date: Fri, 19 Jun 2026 21:54:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20/cwd=20=E5=AE=B9=E9=94=99=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E9=A6=96=E5=B0=BE=E7=9A=84=E5=BC=95=E5=8F=B7/?= =?UTF-8?q?=E5=8F=8D=E5=BC=95=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 手机输入法或 markdown 代码格式常给路径自动加上反引号或引号(如 \`/path\`、'/path'),导致路径开头不是 / 被当成相对路径拼接、校验失败。 切换前先剥离首尾的反引号/单双引号/空格。 --- src/commands/handlers.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/commands/handlers.ts b/src/commands/handlers.ts index edde38f..f8834ee 100644 --- a/src/commands/handlers.ts +++ b/src/commands/handlers.ts @@ -64,11 +64,13 @@ export function handleClear(ctx: CommandContext): CommandResult { } export function handleCwd(ctx: CommandContext, args: string): CommandResult { - if (!args) { + // 清理首尾的反引号/引号/空格:手机输入法或 markdown 代码格式常给路径自动加上这些 + const cleaned = args.trim().replace(/^[`'"\s]+|[`'"\s]+$/g, ''); + if (!cleaned) { return { reply: `当前工作目录: ${ctx.session.workingDirectory}\n用法: /cwd <路径>`, handled: true }; } // 展开 ~ 并解析为绝对路径(相对路径基于当前工作目录),切换前校验目录确实存在 - const expanded = args.replace(/^~/, homedir()); + const expanded = cleaned.replace(/^~/, homedir()); const resolved = expanded.startsWith('/') ? expanded : resolve(ctx.session.workingDirectory, expanded); if (!existsSync(resolved)) { return { reply: `目录不存在: ${resolved}\n请检查路径后重试。`, handled: true };