mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-19 01:51:21 +08:00
This commit is contained in:
@@ -43,8 +43,6 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
private diffInterval: ReturnType<typeof setInterval> | undefined
|
||||
private diffSessionId: string | undefined
|
||||
private lastDiffHash: string | undefined
|
||||
private validationInterval: ReturnType<typeof setInterval> | undefined
|
||||
private validating = false
|
||||
private statsPoller: WorktreeStatsPoller
|
||||
private cachedDiffTarget: { directory: string; baseBranch: string } | undefined
|
||||
|
||||
@@ -109,7 +107,6 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
|
||||
this.panel.onDidDispose(() => {
|
||||
this.log("Panel disposed")
|
||||
this.stopWorktreeValidation()
|
||||
this.statsPoller.stop()
|
||||
this.stopDiffPolling()
|
||||
this.provider?.dispose()
|
||||
@@ -134,12 +131,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
|
||||
// Validate worktree directories still exist (handles manual deletion)
|
||||
const root = this.getWorkspaceRoot()
|
||||
if (root) {
|
||||
const orphaned = await state.validate(root)
|
||||
for (const s of orphaned) {
|
||||
this.provider?.clearSessionDirectory(s.id)
|
||||
}
|
||||
}
|
||||
if (root) await state.validate(root)
|
||||
|
||||
// Register all worktree sessions with KiloProvider
|
||||
for (const worktree of state.getWorktrees()) {
|
||||
@@ -156,10 +148,6 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
if (state.getSessions().length > 0) {
|
||||
this.provider?.refreshSessions()
|
||||
}
|
||||
|
||||
// Poll for externally deleted worktrees while the panel is open.
|
||||
// Guard against panel being disposed while initializeState() was awaiting.
|
||||
if (this.panel) this.startWorktreeValidation()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -1498,52 +1486,6 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
this.cachedDiffTarget = undefined
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Worktree validation polling
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
private startWorktreeValidation(): void {
|
||||
this.stopWorktreeValidation()
|
||||
this.validationInterval = setInterval(() => {
|
||||
void this.validateWorktrees()
|
||||
}, 10_000)
|
||||
}
|
||||
|
||||
private stopWorktreeValidation(): void {
|
||||
if (this.validationInterval) {
|
||||
clearInterval(this.validationInterval)
|
||||
this.validationInterval = undefined
|
||||
}
|
||||
}
|
||||
|
||||
private async validateWorktrees(): Promise<void> {
|
||||
if (this.validating) return
|
||||
this.validating = true
|
||||
try {
|
||||
const state = this.getStateManager()
|
||||
const root = this.getWorkspaceRoot()
|
||||
if (!state || !root) return
|
||||
|
||||
const orphaned = await state.validate(root)
|
||||
if (orphaned.length === 0) return
|
||||
|
||||
for (const s of orphaned) {
|
||||
this.provider?.clearSessionDirectory(s.id)
|
||||
}
|
||||
|
||||
// Stop diff polling if it targets an orphaned session
|
||||
if (this.diffSessionId && orphaned.some((s) => s.id === this.diffSessionId)) {
|
||||
this.stopDiffPolling()
|
||||
}
|
||||
|
||||
this.pushState()
|
||||
} catch (error) {
|
||||
this.log("Worktree validation failed:", error)
|
||||
} finally {
|
||||
this.validating = false
|
||||
}
|
||||
}
|
||||
|
||||
private postToWebview(message: Record<string, unknown>): void {
|
||||
if (this.panel?.webview) void this.panel.webview.postMessage(message)
|
||||
}
|
||||
@@ -1584,7 +1526,6 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.stopWorktreeValidation()
|
||||
this.stopDiffPolling()
|
||||
this.statsPoller.stop()
|
||||
this.terminalManager.dispose()
|
||||
|
||||
@@ -280,26 +280,23 @@ export class WorktreeStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove worktrees whose directories no longer exist on disk. Returns orphaned sessions. */
|
||||
async validate(root: string): Promise<ManagedSession[]> {
|
||||
const orphaned: ManagedSession[] = []
|
||||
/** Remove worktrees whose directories no longer exist on disk. */
|
||||
async validate(root: string): Promise<void> {
|
||||
let changed = false
|
||||
for (const wt of [...this.worktrees.values()]) {
|
||||
const resolved = path.isAbsolute(wt.path) ? wt.path : path.join(root, wt.path)
|
||||
if (!fs.existsSync(resolved)) {
|
||||
this.log(`Worktree ${wt.id} directory missing (${resolved}), removing`)
|
||||
orphaned.push(...this.removeWorktree(wt.id))
|
||||
this.removeWorktree(wt.id)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
// removeWorktree() already queues a save per call — just wait for completion
|
||||
if (orphaned.length > 0) await this.flush()
|
||||
return orphaned
|
||||
if (changed) await this.save()
|
||||
}
|
||||
|
||||
/** Wait for all in-flight and queued saves to complete without triggering a new one. */
|
||||
/** Wait for any in-flight save to complete without triggering a new one. */
|
||||
async flush(): Promise<void> {
|
||||
while (this.saving || this.pendingSave) {
|
||||
await (this.saving ?? Promise.resolve())
|
||||
}
|
||||
if (this.saving) await this.saving
|
||||
}
|
||||
|
||||
async save(): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user