⚡ perf(vscode): 开会话去掉多余远程往返,spinner 跟随真实进度
开会话原先要先全量拉工单(含每张工单的评论、依赖、PR)做前置锁检查, 再各读一次 state JSON 给 pre-create 钩子和终端图标,几秒后才 createTerminal。 - 锁检查改用主进程已算好的工单快照,快照里没有该工单才回落全量拉取 - state JSON 一次读两处用,且提前发起与本地准备重叠 - 会话行 spinner 由扩展的 session/tab-settled 消息驱动,不再是固定 1.5s 假动画, 消息丢失时 60s 超时兜底 Claude-Session: https://claude.ai/code/session_01Kgmb1LvrPmFX3NoUDB4zZC
This commit is contained in:
1 parent
b182e0ac5b
commit
70b826123c
12 files changed
+218
-71
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import type { IssueColumn } from '../../gitea/types'
|
||||
import type { LockedReason } from '../issueLock'
|
||||
import type { KanbanWebviewPanel } from '../KanbanPanel'
|
||||
import { Buffer } from 'node:buffer'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
@@ -35,6 +36,7 @@ import { logger } from '../../logging/logger'
|
||||
import { getEffectivePrDiffSummaryProfilePath, getSettings } from '../../settings/store'
|
||||
import { webhookCoordinator } from '../../webhook/coordinator'
|
||||
import { pickRandomIssueColor, themeColorIdToIconUri } from '../issueColor'
|
||||
import { evaluateLockedReason } from '../issueLock'
|
||||
import { makeNonce } from '../KanbanPanel'
|
||||
import { cleanupFeatureBranch } from './branchCleanup'
|
||||
import * as sessions from './sessions'
|
||||
@@ -1572,12 +1574,10 @@ export async function syncCloseGiteaIssue(panel: KanbanWebviewPanel, opts: {
|
||||
}
|
||||
|
||||
/**
|
||||
* Server-side lock check for prerequisite gating. Fetches a fresh issues
|
||||
* snapshot (we don't trust webview state) and reports whether
|
||||
* `issueNumber` is blocked by an unfinished prerequisite. Mirrors the
|
||||
* webview-side `isIssueLocked` predicate: locked iff the issue has a
|
||||
* prerequisite that exists in the current snapshot and is not yet in the
|
||||
* `done` column.
|
||||
* Server-side lock check for prerequisite gating(不信 webview 传来的状态)。
|
||||
* 优先用主进程自己算好的工单快照——开会话是热路径,全量 loadIssues 要拉工单
|
||||
* 列表、每张工单的评论、依赖和 PR,几秒起步;快照没有该工单(面板还没加载
|
||||
* 完)时才退回一次全量拉取。
|
||||
*
|
||||
* Fail-open: any error fetching issues is logged and we return
|
||||
* `{ locked: false }` so a transient Gitea hiccup can't lock the user out
|
||||
@@ -1586,8 +1586,12 @@ export async function syncCloseGiteaIssue(panel: KanbanWebviewPanel, opts: {
|
||||
export async function resolveLockedReason(
|
||||
panel: KanbanWebviewPanel,
|
||||
issueNumber: number,
|
||||
): Promise<{ locked: boolean, prerequisiteNumber?: number, prerequisiteColumn?: string }> {
|
||||
): Promise<LockedReason> {
|
||||
try {
|
||||
const snapshot = panel.snapshotIssues()
|
||||
if (snapshot?.some(i => i.number === issueNumber))
|
||||
return evaluateLockedReason(snapshot, issueNumber)
|
||||
|
||||
const workspaceRoot = workspace.workspaceFolders?.[0]?.uri.fsPath
|
||||
if (!workspaceRoot)
|
||||
return { locked: false }
|
||||
@@ -1604,21 +1608,7 @@ export async function resolveLockedReason(
|
||||
repo: remote.repo,
|
||||
workspaceRoot,
|
||||
})
|
||||
const issue = issues.find(i => i.number === issueNumber)
|
||||
if (!issue)
|
||||
return { locked: false }
|
||||
if (issue.prerequisite === undefined)
|
||||
return { locked: false }
|
||||
const prereq = issues.find(i => i.number === issue.prerequisite)
|
||||
if (!prereq)
|
||||
return { locked: false }
|
||||
if (prereq.column === 'done')
|
||||
return { locked: false }
|
||||
return {
|
||||
locked: true,
|
||||
prerequisiteNumber: prereq.number,
|
||||
prerequisiteColumn: prereq.column,
|
||||
}
|
||||
return evaluateLockedReason(issues, issueNumber)
|
||||
}
|
||||
catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
|
||||
Reference in new issue
Block a user