✨ feat(vscode): 提交代码按钮实时显示进度并预检 git 身份
- spawnClaude 新增 onProgress 回调,给了回调就改走 stream-json 逐行输出,按行解析出工具调用 / 回复文本 - 新增 claudeProgress 把每行 NDJSON 压成可读进度短语 - 提交前先读 git user.name / user.email,缺失直接提示,不再让 claude 白跑 - 运行期间用带转圈的 toast 滚动显示进度,完成后带上 claude 的结果摘要 Claude-Session: https://claude.ai/code/session_01HTMgwaE3woqM5yvsHiuSAa
This commit is contained in:
1 parent
443a8e472a
commit
73a0c46f9f
6 files changed
+322
-25
No files matched your search
@@ -8,9 +8,11 @@ import { resolveProfilePath } from '../../cc/profiles'
|
||||
import { spawnClaude } from '../../cc/spawnClaude'
|
||||
import { findEnvFiles, lockEnvFiles, unlockEnvFiles } from '../../files/envLock'
|
||||
import { checkBranchSync, runBranchSync } from '../../git/branchSync'
|
||||
import { missingGitIdentityKeys, readGitIdentity } from '../../git/identity'
|
||||
import { logger } from '../../logging/logger'
|
||||
import { getEffectiveCommitProfilePath, getSettings } from '../../settings/store'
|
||||
import { makeNonce } from '../KanbanPanel'
|
||||
import { dismiss, toast } from './handoffFlow'
|
||||
|
||||
/**
|
||||
* Minimal structural typing for the bits of the built-in `vscode.git`
|
||||
@@ -86,43 +88,65 @@ export async function handleCommitRun(panel: KanbanWebviewPanel): Promise<void>
|
||||
return
|
||||
}
|
||||
|
||||
// 身份缺失时 git commit 必然失败,提前拦下,别让 claude 白跑十几分钟
|
||||
const missingIdentity = missingGitIdentityKeys(await readGitIdentity(workspaceRoot))
|
||||
if (missingIdentity.length > 0) {
|
||||
toast(
|
||||
panel,
|
||||
'error',
|
||||
`git 未配置 ${missingIdentity.join(' 和 ')},无法提交。请先执行:git config --global user.name "你的名字" && git config --global user.email "你的邮箱"`,
|
||||
{ dismissOnTimer: 15000 },
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
panel.commitRunning = true
|
||||
panel.postMessage({ type: 'commit/state', running: true })
|
||||
|
||||
// 同一个 id 反复发 toast 会原地替换,正好用来滚动显示实时进度
|
||||
const progressToastId = toast(panel, 'info', '提交中:正在启动 claude…', {
|
||||
spinner: true,
|
||||
dismissOnTimer: 31 * 60 * 1000,
|
||||
})
|
||||
|
||||
try {
|
||||
// claude -p 提交流程可能跑得比较久(要 git add / 编 commit message / git
|
||||
// commit),所以给一个比较宽松的超时(30 min)。
|
||||
await spawnClaude({
|
||||
const { resultText } = await spawnClaude({
|
||||
prompt: '提交下代码',
|
||||
cwd: workspaceRoot,
|
||||
profilePath: resolution.profilePath,
|
||||
timeoutMs: 30 * 60 * 1000,
|
||||
bare: true,
|
||||
onProgress: (label) => {
|
||||
toast(panel, 'info', `提交中:${label}`, {
|
||||
id: progressToastId,
|
||||
spinner: true,
|
||||
dismissOnTimer: 31 * 60 * 1000,
|
||||
})
|
||||
},
|
||||
})
|
||||
panel.postMessage({
|
||||
type: 'toast/show',
|
||||
id: makeNonce(),
|
||||
level: 'success',
|
||||
message: '提交完成',
|
||||
dismissOnTimer: 5000,
|
||||
})
|
||||
toast(panel, 'success', formatCommitDone(resultText), { dismissOnTimer: 5000 })
|
||||
}
|
||||
catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err)
|
||||
panel.postMessage({
|
||||
type: 'toast/show',
|
||||
id: makeNonce(),
|
||||
level: 'error',
|
||||
message: `提交失败: ${msg}`,
|
||||
dismissOnTimer: 8000,
|
||||
})
|
||||
toast(panel, 'error', `提交失败: ${msg}`, { dismissOnTimer: 8000 })
|
||||
}
|
||||
finally {
|
||||
dismiss(panel, progressToastId)
|
||||
panel.commitRunning = false
|
||||
panel.postMessage({ type: 'commit/state', running: false })
|
||||
}
|
||||
}
|
||||
|
||||
function formatCommitDone(resultText: string): string {
|
||||
const firstLine = resultText.split('\n').map(l => l.trim()).find(l => l.length > 0) ?? ''
|
||||
if (!firstLine)
|
||||
return '提交完成'
|
||||
const summary = firstLine.length > 100 ? `${firstLine.slice(0, 100)}…` : firstLine
|
||||
return `提交完成:${summary}`
|
||||
}
|
||||
|
||||
export async function handleBranchSyncCheck(panel: KanbanWebviewPanel): Promise<void> {
|
||||
const workspaceRoot = workspace.workspaceFolders?.[0]?.uri.fsPath
|
||||
const s = getSettings(panel.context)
|
||||
|
||||
Reference in new issue
Block a user