🐛 fix(vscode): 修好单个会话 tab 从看板点回时不反向选中所属工单
Claude-Session: https://claude.ai/code/session_01FAA5YEyR7fzWj7gYQiLSqy
This commit is contained in:
1 parent
eee0170a63
commit
06fb5ecec2
4 files changed
+157
-77
No files matched your search
@@ -118,7 +118,7 @@ export function findExistingTerminal(panel: KanbanWebviewPanel, expectedName: st
|
||||
* no-op (user has to press Enter to spawn one).
|
||||
*/
|
||||
export function handleSessionFocus(panel: KanbanWebviewPanel, issueNumber: number): void {
|
||||
// 如果这次 session/focus 是 onDidChangeActiveTerminal 反选触发的回路
|
||||
// 如果这次 session/focus 是终端 tab 切换反选触发的回路
|
||||
// (而不是用户主动点卡片切换工单),跳过优先级跳转,否则会把用户刚刚
|
||||
// 点的"审查 tab"弹回到优先级更高的"实施 tab"。
|
||||
const REVERSE_LOOP_WINDOW_MS = 200
|
||||
@@ -135,10 +135,8 @@ export function handleSessionFocus(panel: KanbanWebviewPanel, issueNumber: numbe
|
||||
// side-map is the only way to find it by issueNumber.
|
||||
const newIssueTerm = panel.newIssueTerminals.get(issueNumber)
|
||||
if (newIssueTerm && newIssueTerm.exitStatus === undefined) {
|
||||
if (newIssueTerm !== window.activeTerminal) {
|
||||
panel.programmaticTabReveal = newIssueTerm
|
||||
if (newIssueTerm !== window.activeTerminal)
|
||||
newIssueTerm.show(true)
|
||||
}
|
||||
return
|
||||
}
|
||||
// Priority 1-4: 实施 > 规划 > 审查 > 测试. Match by terminal.name since we know
|
||||
@@ -152,12 +150,10 @@ export function handleSessionFocus(panel: KanbanWebviewPanel, issueNumber: numbe
|
||||
for (const name of namePriority) {
|
||||
const term = findExistingTerminal(panel, name)
|
||||
if (term) {
|
||||
// 已经是 active terminal 就不重复 show(避免无谓的回声事件);
|
||||
// 否则记下程序化 reveal,让随后的 active 变更被吞掉,不回环。
|
||||
if (term !== window.activeTerminal) {
|
||||
panel.programmaticTabReveal = term
|
||||
// preserveFocus 只在分组内切 tab、不激活分组,因此不会被当成
|
||||
// 用户切到终端而反向选中;已是 active terminal 则无需重复 show。
|
||||
if (term !== window.activeTerminal)
|
||||
term.show(true)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -165,27 +161,14 @@ export function handleSessionFocus(panel: KanbanWebviewPanel, issueNumber: numbe
|
||||
}
|
||||
|
||||
/**
|
||||
* 反向选中:用户在 column 2 切换 terminal tab 时,从 terminal.name 解析
|
||||
* issueNumber 并通知 webview 选中对应工单。
|
||||
* 反向选中:用户把焦点切到 column 2 的某个 terminal tab 时,从 terminal.name
|
||||
* 解析 issueNumber 并通知 webview 选中对应工单。去重与回声抑制由调用方的
|
||||
* `FocusedTerminalTracker` 负责,这里每次调用都视为一次真实切换。
|
||||
*
|
||||
* 终端名按 `issue-${N}-(规划|实施|审查)` 命名;`issue-new-${nonce}-...`
|
||||
* 终端名按 `issue-${N}-(规划|实施|审查|测试)` 命名;`issue-new-${nonce}-...`
|
||||
* 是新建工单流程的占位 tab,没有 issue number,跳过。
|
||||
*/
|
||||
export function handleActiveTerminalChanged(panel: KanbanWebviewPanel, terminal: Terminal): void {
|
||||
// Dedupe by reference: OSC title rewrites / shell prompt updates fire
|
||||
// onDidChangeTabs repeatedly for the same terminal. Skip if it's the
|
||||
// same reference we just handled.
|
||||
// 吞掉「我们自己 show() 引发的」active 变更回声:handleSessionFocus 在程序化
|
||||
// show 前把目标终端记到 programmaticTabReveal,这里命中就 return,不反向选中,
|
||||
// 从根上打断 选中→聚焦→选中 的死循环(基于引用,不依赖脆弱的时间窗)。
|
||||
// 每次调用都清空,因此只压制紧随其后的那一次回声,用户真实点 tab 不受影响。
|
||||
const reveal = panel.programmaticTabReveal
|
||||
panel.programmaticTabReveal = undefined
|
||||
if (terminal === reveal)
|
||||
return
|
||||
if (terminal === panel.lastActiveTerminalRef)
|
||||
return
|
||||
panel.lastActiveTerminalRef = terminal
|
||||
// Primary: `issue-${N}-(规划|实施|审查|测试)` — the steady-state naming.
|
||||
const m = terminal.name.match(/^issue-(\d+)-(规划|实施|审查|测试)/)
|
||||
if (m) {
|
||||
|
||||
Reference in new issue
Block a user