🐛 fix(vscode): 工单先建好也补上头脑风暴会话

This commit is contained in:
cruldra committed 2026-09-28 19:10:37 +08:00
1 parent af8dfcc474
commit 7d70783b32
2 files changed
+39 -6

No files matched your search

+31 -6
View File
@@ -33,6 +33,7 @@ import {
} from '../../gitea/api' } from '../../gitea/api'
import { isValidSpxFilePath, loadIssues } from '../../gitea/issueLoader' import { isValidSpxFilePath, loadIssues } from '../../gitea/issueLoader'
import { mergeStateJsonComment } from '../../gitea/stateJson' import { mergeStateJsonComment } from '../../gitea/stateJson'
import { mergeLocalIssueState } from '../../issues/localState'
import { logger } from '../../logging/logger' import { logger } from '../../logging/logger'
import { getEffectivePrDiffSummaryProfilePath, getSettings } from '../../settings/store' import { getEffectivePrDiffSummaryProfilePath, getSettings } from '../../settings/store'
import { webhookCoordinator } from '../../webhook/coordinator' import { webhookCoordinator } from '../../webhook/coordinator'
@@ -42,6 +43,7 @@ import { evaluateLockedReason } from '../issueLock'
import { cleanupFeatureBranch } from './branchCleanup' import { cleanupFeatureBranch } from './branchCleanup'
import { clearSessionConfirmText, clearSessionDoneText, SESSION_KINDS } from './sessionKinds' import { clearSessionConfirmText, clearSessionDoneText, SESSION_KINDS } from './sessionKinds'
import * as sessions from './sessions' import * as sessions from './sessions'
import { issueNumberForNewIssueTerminal } from './terminals'
import { canResetToTodo, todoResetStateExtra, todoResetUiPatch } from './todoReset' import { canResetToTodo, todoResetStateExtra, todoResetUiPatch } from './todoReset'
export async function handleColumnChange(panel: KanbanWebviewPanel, issueNumber: number, toColumn: IssueColumn): Promise<void> { export async function handleColumnChange(panel: KanbanWebviewPanel, issueNumber: number, toColumn: IssueColumn): Promise<void> {
@@ -1529,12 +1531,9 @@ export async function handleIssueCreate(
dismissOnTimer: 4000, dismissOnTimer: 4000,
}) })
// Background: fill in sessionId once the jsonl materializes. If the // 工单往往比会话文件先出现。webhook 把 pending 取走时 sessionId 还空,
// matching webhook fires before this resolves, the pending entry has // 这里在文件落地后补写本机会话 id。
// already been deleted and we silently no-op — the state JSON just watchPromise.then(async (sid) => {
// lacks sessionId in that (rare) race case, and the user can resume
// from a later session id via the terminal.
watchPromise.then((sid) => {
if (!sid) { if (!sid) {
logger.add({ logger.add({
level: 'warn', level: 'warn',
@@ -1551,7 +1550,33 @@ export async function handleIssueCreate(
source: 'panel', source: 'panel',
message: `已捕获新建工单会话 ${sid} nonce=${shortNonce}`, message: `已捕获新建工单会话 ${sid} nonce=${shortNonce}`,
}) })
return
} }
const issueNumber = issueNumberForNewIssueTerminal(panel, terminal)
if (issueNumber === undefined) {
logger.add({
level: 'warn',
source: 'panel',
message: `新建工单会话 ${sid} 已捕获,但 nonce=${shortNonce} 还没对上工单`,
})
return
}
try {
const state = await panel.readIssueState(issueNumber)
if (typeof state.sessionId === 'string' && state.sessionId.length > 0)
return
}
catch {
// 本机状态还没有,照写
}
await mergeLocalIssueState(panel.context, 'gitea', issueNumber, { sessionId: sid })
panel.terminals.set(sid, terminal)
panel.postMessage({ type: 'issue/patch', issueNumber, patch: { sessionId: sid } })
logger.add({
level: 'info',
source: 'panel',
message: `补写工单 #${issueNumber} 头脑风暴会话 ${sid}`,
})
}).catch((err) => { }).catch((err) => {
console.warn('[superpowers] new-issue session watch failed:', err) console.warn('[superpowers] new-issue session watch failed:', err)
}) })
+8
View File
@@ -405,3 +405,11 @@ export function linkPendingTerminalToIssue(panel: KanbanWebviewPanel, nonce: str
panel.terminals.set(pending.sessionId, pending.terminal) panel.terminals.set(pending.sessionId, pending.terminal)
trackSessionTerminal(panel, pending.terminal, issueNumber, 'brainstorm') trackSessionTerminal(panel, pending.terminal, issueNumber, 'brainstorm')
} }
export function issueNumberForNewIssueTerminal(panel: KanbanWebviewPanel, terminal: Terminal): number | undefined {
for (const [issueNumber, linked] of panel.newIssueTerminals) {
if (linked === terminal)
return issueNumber
}
return undefined
}