🐛 fix(vscode): resume 会话用 resolveWorktreePath 避免误判 worktree 已清理
This commit is contained in:
@@ -3,7 +3,27 @@ import { existsSync, mkdtempSync, rmSync } from 'node:fs'
|
|||||||
import * as os from 'node:os'
|
import * as os from 'node:os'
|
||||||
import * as path from 'node:path'
|
import * as path from 'node:path'
|
||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
import { findProcessesUsingWorktree } from './worktree'
|
import { findProcessesUsingWorktree, resolveWorktreePath } from './worktree'
|
||||||
|
|
||||||
|
describe('resolveWorktreePath', () => {
|
||||||
|
const workspaceRoot = '/workspace/project'
|
||||||
|
|
||||||
|
it('绝对路径原样返回', () => {
|
||||||
|
const abs = '/home/user/Sources/worktree/repo/session-foo'
|
||||||
|
expect(resolveWorktreePath(abs, workspaceRoot)).toBe(abs)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('~/... 展开为 home 下路径', () => {
|
||||||
|
const home = os.homedir()
|
||||||
|
expect(resolveWorktreePath('~/Sources/worktree/repo/session-foo', workspaceRoot))
|
||||||
|
.toBe(path.join(home, 'Sources/worktree/repo/session-foo'))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('相对路径拼到 workspaceRoot 下', () => {
|
||||||
|
expect(resolveWorktreePath('.claude/worktrees/abc123', workspaceRoot))
|
||||||
|
.toBe(path.join(workspaceRoot, '.claude/worktrees/abc123'))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// 检测靠扫 /proc,只有 Linux 有;别的平台整组跳过(函数本身也会返回空)。
|
// 检测靠扫 /proc,只有 Linux 有;别的平台整组跳过(函数本身也会返回空)。
|
||||||
describe.runIf(existsSync('/proc'))('findProcessesUsingWorktree', () => {
|
describe.runIf(existsSync('/proc'))('findProcessesUsingWorktree', () => {
|
||||||
|
|||||||
@@ -84,15 +84,16 @@ export async function handleResumeSession(panel: KanbanWebviewPanel, sessionId:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const workspaceRoot = workspace.workspaceFolders?.[0]?.uri.fsPath
|
const workspaceRoot = workspace.workspaceFolders?.[0]?.uri.fsPath
|
||||||
// Implementation sessions live in a worktree; the caller can pass a
|
// Implementation sessions live in a worktree; `relCwd` may be absolute /
|
||||||
// workspace-relative `relCwd` so `--resume` runs from the right place.
|
// `~/...` / workspace-relative — must go through resolveWorktreePath
|
||||||
|
// (path.join(workspaceRoot, abs) would mangle absolute paths).
|
||||||
// If the worktree has since been cleaned up (typical: drop card to
|
// If the worktree has since been cleaned up (typical: drop card to
|
||||||
// "完成" → auto `git worktree remove`), fall back to the workspace
|
// "完成" → auto `git worktree remove`), fall back to the workspace
|
||||||
// root instead of pointing the terminal at a missing directory.
|
// root instead of pointing the terminal at a missing directory.
|
||||||
let effectiveCwd: string | undefined = workspaceRoot
|
let effectiveCwd: string | undefined = workspaceRoot
|
||||||
let cwdFallback = false
|
let cwdFallback = false
|
||||||
if (relCwd && workspaceRoot) {
|
if (relCwd && workspaceRoot) {
|
||||||
const resolved = path.join(workspaceRoot, relCwd)
|
const resolved = resolveWorktreePath(relCwd, workspaceRoot)
|
||||||
if (fs.existsSync(resolved)) {
|
if (fs.existsSync(resolved)) {
|
||||||
effectiveCwd = resolved
|
effectiveCwd = resolved
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user