🐛 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
+20 -37
View File
@@ -11,6 +11,7 @@ import { getToken } from '../../auth/secrets'
import { buildCcCommand } from '../../cc/ccCommand' import { buildCcCommand } from '../../cc/ccCommand'
import { getDefaultProfilePath, getPrDiffSummaryProfilePath } from '../../cc/profiles' import { getDefaultProfilePath, getPrDiffSummaryProfilePath } from '../../cc/profiles'
import { getBrainstormPrompt } from '../../cc/prompts' import { getBrainstormPrompt } from '../../cc/prompts'
import { claudeProjectsRoot, installClaudeSession } from '../../cc/sessionBundle'
import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher' import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher'
import { spawnClaude } from '../../cc/spawnClaude' import { spawnClaude } from '../../cc/spawnClaude'
import { gitFetch, resolveFeatureBranch } from '../../git/branchSync' import { gitFetch, resolveFeatureBranch } from '../../git/branchSync'
@@ -390,45 +391,27 @@ export async function handleColumnChange(panel: KanbanWebviewPanel, issueNumber:
issueNumber, issueNumber,
}) })
// Before removing the worktree, copy the impl- and test-session jsonl into // 删 worktree 前把实施/测试会话整包(jsonl + 子目录)搬到主仓库 projects 目录,
// the workspace-root projects dir so `claude --resume` can still find them // 并清掉 worktree 侧副本:新版 claude 遇到重复 sid 会拒绝 resume。
// after the worktree (and its projects dir) are gone.
if ((implementSessionId || testSessionId) && worktreePath) { if ((implementSessionId || testSessionId) && worktreePath) {
try { const worktreeAbs = resolveWorktreePath(worktreePath, workspaceRoot)
const worktreeAbs = resolveWorktreePath(worktreePath, workspaceRoot) const srcProjectsDir = projectsDirFor(worktreeAbs)
const srcProjectsDir = projectsDirFor(worktreeAbs) const dstProjectsDir = projectsDirFor(workspaceRoot)
const dstProjectsDir = projectsDirFor(workspaceRoot) for (const sid of [implementSessionId, testSessionId]) {
const sessionIds = [implementSessionId, testSessionId].filter( if (typeof sid !== 'string' || sid.length === 0)
(id): id is string => typeof id === 'string' && id.length > 0, continue
) try {
for (const sessionId of sessionIds) { await installClaudeSession({ sid, srcDir: srcProjectsDir, dstProjectsDir, projectsRoot: claudeProjectsRoot() })
const srcJsonl = path.join(srcProjectsDir, `${sessionId}.jsonl`) logger.add({ level: 'info', source: 'panel', message: `cc 会话 ${sid} 已搬到主仓库 projects 目录 (issue #${issueNumber})` })
const dstJsonl = path.join(dstProjectsDir, `${sessionId}.jsonl`) }
if (fs.existsSync(srcJsonl)) { catch (err) {
if (!fs.existsSync(dstProjectsDir)) logger.add({
fs.mkdirSync(dstProjectsDir, { recursive: true }) level: 'warn',
if (!fs.existsSync(dstJsonl)) { source: 'panel',
fs.copyFileSync(srcJsonl, dstJsonl) message: `搬迁 cc 会话 ${sid} 失败 (issue #${issueNumber})worktree 清理仍继续`,
logger.add({ details: err instanceof Error ? err.message : String(err),
level: 'info', })
source: 'panel',
message: `已复制 cc session jsonl 到主 workspace projects 目录 (issue #${issueNumber})`,
details: `${srcJsonl}${dstJsonl}`,
})
}
}
} }
}
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,
})
} }
} }