🐛 fix(vscode): 完成列归档会话改为整包搬迁并清理重复 sid

Claude-Session: https://claude.ai/code/session_011cEyL6k351U2BzX1Qmygph
This commit is contained in:
2026-08-26 16:33:54 +08:00
parent e066c26583
commit 6d3720d424
+12 -29
View File
@@ -11,6 +11,7 @@ import { getToken } from '../../auth/secrets'
import { buildCcCommand } from '../../cc/ccCommand'
import { getDefaultProfilePath, getPrDiffSummaryProfilePath } from '../../cc/profiles'
import { getBrainstormPrompt } from '../../cc/prompts'
import { claudeProjectsRoot, installClaudeSession } from '../../cc/sessionBundle'
import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher'
import { spawnClaude } from '../../cc/spawnClaude'
import { gitFetch, resolveFeatureBranch } from '../../git/branchSync'
@@ -390,47 +391,29 @@ export async function handleColumnChange(panel: KanbanWebviewPanel, issueNumber:
issueNumber,
})
// Before removing the worktree, copy the impl- and test-session jsonl into
// the workspace-root projects dir so `claude --resume` can still find them
// after the worktree (and its projects dir) are gone.
// 删 worktree 前把实施/测试会话整包(jsonl + 子目录)搬到主仓库 projects 目录,
// 并清掉 worktree 侧副本:新版 claude 遇到重复 sid 会拒绝 resume。
if ((implementSessionId || testSessionId) && worktreePath) {
try {
const worktreeAbs = resolveWorktreePath(worktreePath, workspaceRoot)
const srcProjectsDir = projectsDirFor(worktreeAbs)
const dstProjectsDir = projectsDirFor(workspaceRoot)
const sessionIds = [implementSessionId, testSessionId].filter(
(id): id is string => typeof id === 'string' && id.length > 0,
)
for (const sessionId of sessionIds) {
const srcJsonl = path.join(srcProjectsDir, `${sessionId}.jsonl`)
const dstJsonl = path.join(dstProjectsDir, `${sessionId}.jsonl`)
if (fs.existsSync(srcJsonl)) {
if (!fs.existsSync(dstProjectsDir))
fs.mkdirSync(dstProjectsDir, { recursive: true })
if (!fs.existsSync(dstJsonl)) {
fs.copyFileSync(srcJsonl, dstJsonl)
logger.add({
level: 'info',
source: 'panel',
message: `已复制 cc session jsonl 到主 workspace projects 目录 (issue #${issueNumber})`,
details: `${srcJsonl}${dstJsonl}`,
})
}
}
}
for (const sid of [implementSessionId, testSessionId]) {
if (typeof sid !== 'string' || sid.length === 0)
continue
try {
await installClaudeSession({ sid, srcDir: srcProjectsDir, dstProjectsDir, projectsRoot: claudeProjectsRoot() })
logger.add({ level: 'info', source: 'panel', message: `cc 会话 ${sid} 已搬到主仓库 projects 目录 (issue #${issueNumber})` })
}
catch (err) {
// Non-fatal — worktree cleanup still proceeds. User can manually copy
// the jsonl later if needed.
const message = err instanceof Error ? err.message : String(err)
logger.add({
level: 'warn',
source: 'panel',
message: `复制 cc session jsonl 失败 (issue #${issueNumber})worktree 清理仍继续`,
details: message,
message: `搬迁 cc 会话 ${sid} 失败 (issue #${issueNumber})worktree 清理仍继续`,
details: err instanceof Error ? err.message : String(err),
})
}
}
}
// 5. Best-effort cleanup of the worktree. Failures are non-fatal — the
// state JSON already records done, user can manually clean later.