✨ feat(vscode): 头脑风暴会话可清除,悬停提示改窄改紧凑

工单记着的头脑风暴会话 id 此前没有清除入口,续聊只能 resume 旧会话,
把几个版本前的提示词和它当时报的错一起带回来。会话 id 行新增清除按钮,
确认后把 state JSON 的 sessionId 置空,下次续聊新开会话;会话文件不动,
手上有 id 仍可 claude --resume 找回。

悬停气泡此前贴着视口右边测量尺寸:fixed 元素的可用宽度是「视口宽 - left」,
贴边测会被挤窄、行数变多,按那个高度定位就浮高一截。改成先在左上角量再落位,
字号行高收紧,提示文案压成一行。顺带修掉「重置为待办」的错误说明——它会停
会话、删 worktree 和未合并 PR,不是原样保留。

Claude-Session: https://claude.ai/code/session_01REdhpbaNyqWASF2HWsnTFv
This commit is contained in:
cruldra committed 2026-09-13 09:21:53 +08:00
1 parent 9fadcac12b
commit 5bfd759822
11 files changed
+124 -23

No files matched your search

+4
View File
@@ -538,6 +538,10 @@ export class KanbanWebviewPanel {
void issues.handleUpdateBrainstormProfilePath(this, msg.issueNumber, msg.brainstormProfilePath)
return
}
if (msg.type === 'issue/clear-brainstorm-session') {
void issues.handleClearBrainstormSession(this, msg.issueNumber)
return
}
if (msg.type === 'issue/update-test-profile-path') {
void issues.handleUpdateTestProfilePath(this, msg.issueNumber, msg.testProfilePath)
return
+71
View File
@@ -1976,6 +1976,77 @@ export async function handleUpdateProfilePath(panel: KanbanWebviewPanel, issueNu
}
}
/**
* 清掉工单记的头脑风暴会话 id,下次点 ▶ 续聊就新开一个会话。
*
* 用处:旧会话的历史被 `claude --resume` 原样带回来(里面可能还留着几个版本
* 之前的提示词和它报的错),想从干净的上下文重新聊需求时用。会话文件本身不动,
* 手上有 id 仍可用 `claude --resume <id>` 找回。
*/
export async function handleClearBrainstormSession(panel: KanbanWebviewPanel, issueNumber: number): Promise<void> {
let previousValue: string | undefined
try {
const existingState = await panel.readIssueState(issueNumber)
previousValue = typeof existingState.sessionId === 'string' ? existingState.sessionId : undefined
}
catch {
previousValue = undefined
}
if (!previousValue) {
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'info',
message: `工单 #${issueNumber} 本来就没有头脑风暴会话`,
dismissOnTimer: 4000,
})
return
}
const choice = await window.showWarningMessage(
`确定清除工单 #${issueNumber} 的头脑风暴会话 id(${previousValue})?下次续聊会新开一个会话,旧会话记录还在,可用 claude --resume 找回。`,
{ modal: true },
'清除',
)
if (choice !== '清除')
return
try {
await panel.mergeIssueState(issueNumber, { sessionId: '' })
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({
level: 'error',
source: 'panel',
message: `清除 sessionId 失败 (issue #${issueNumber})`,
details: message,
})
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'error',
message: `清除工单 #${issueNumber} 头脑风暴会话失败: ${message}`,
dismissOnTimer: 6000,
})
return
}
panel.postMessage({
type: 'issue/patch',
issueNumber,
patch: { sessionId: null },
})
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'success',
message: `工单 #${issueNumber} 头脑风暴会话已清除,下次续聊将新开会话`,
dismissOnTimer: 5000,
})
}
/**
* Persist a per-issue `brainstormProfilePath` override into the issue's state
* JSON. Brainstorm start/resume use this profile (see resolveBrainstormProfilePath);
+1
View File
@@ -213,6 +213,7 @@ export type WebviewToExtension
| { type: 'issue/update-auto-review', issueNumber: number, value: boolean }
| { type: 'issue/update-profile-path', issueNumber: number, profilePath: string }
| { type: 'issue/update-brainstorm-profile-path', issueNumber: number, brainstormProfilePath: string }
| { type: 'issue/clear-brainstorm-session', issueNumber: number }
| { type: 'issue/update-test-profile-path', issueNumber: number, testProfilePath: string }
| { type: 'logs/fetch' }
| { type: 'logs/clear' }
+1
View File
@@ -26,6 +26,7 @@ export const OWNER_ONLY_MESSAGE_TYPES: ReadonlySet<string> = new Set([
'issue/update-auto-review',
'issue/update-profile-path',
'issue/update-brainstorm-profile-path',
'issue/clear-brainstorm-session',
'issue/update-test-profile-path',
'dependency/set',
'dependency/clear',