mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-23 00:43:14 +00:00
* feat: add per-workspace indexing opt-in and stop/cancel control - Add codeIndexWorkspaceEnabled flag in workspaceState (default: false) - Thread AbortController/AbortSignal through orchestrator → scanner - Add Stop Indexing button and Stopping state to UI - Fix handleSettingsChange() to abort active scan when disabling toggle - Add translations for all 18 locales * fix: correct abort handling in indexing scanner and orchestrator - Re-throw AbortError in scanner's file processing catch block to prevent abort signals from being silently swallowed as file errors - Reorder stopWatcher() before setSystemState() in orchestrator abort catch path to ensure watcher cleanup before state transition - Update scanner test to assert AbortError propagation on mid-scan abort * fix: optimize workspace check ordering, translate new i18n keys, fix abort handling - Move workspace-enabled check before _recreateServices() in initialize() to avoid creating Qdrant/embedder connections for disabled workspaces - Translate new i18n keys (indexingStopped, indexingStoppedPartial, stopping, stopIndexingButton, stoppingButton, workspaceToggleLabel, workspaceDisabledMessage) in all 17 non-English locales - Re-throw AbortError in scanner catch block to prevent silent swallowing - Reorder stopWatcher() before setSystemState() in orchestrator abort path - Update scanner test to assert AbortError propagation on mid-scan abort - Fix recoverFromError test for workspace-enabled check ordering * fix: per-folder enablement key, abort-safe dispose and back-pressure, translate i18n Addresses 0xMink review feedback: - Store workspace enablement keyed by folder path to support multi-root workspaces (codeIndexWorkspaceEnabled:<path> instead of single boolean) - Add test proving folder A enabled does not enable folder B - dispose() now calls stopIndexing() to abort orphaned scans on folder removal - Scanner back-pressure loop checks abort signal to avoid spin-waiting - Move workspace-enabled check before _recreateServices() in initialize() - Translate new i18n keys in all 17 non-English locales - Fix abort handling in orchestrator and scanner catch blocks * fix: flush debounced cache writes on abort to preserve indexing progress * feat: add global auto-enable default for backward-compatible workspace indexing * fix: stop/start indexer when auto-enable default changes effective state * fix: URI-keyed enablement, throw AbortError in back-pressure, stopWatcher on early-return * fix: iterate all managers when auto-enable default changes in multi-root workspaces --------- Co-authored-by: James Mtendamema <jmtendamema@geologicai.com>
119 lines
4.1 KiB
TypeScript
119 lines
4.1 KiB
TypeScript
import * as vscode from "vscode"
|
|
|
|
export type IndexingState = "Standby" | "Indexing" | "Indexed" | "Error" | "Stopping"
|
|
|
|
export class CodeIndexStateManager {
|
|
private _systemStatus: IndexingState = "Standby"
|
|
private _statusMessage: string = ""
|
|
private _processedItems: number = 0
|
|
private _totalItems: number = 0
|
|
private _currentItemUnit: string = "blocks"
|
|
private _progressEmitter = new vscode.EventEmitter<ReturnType<typeof this.getCurrentStatus>>()
|
|
|
|
// --- Public API ---
|
|
|
|
public readonly onProgressUpdate = this._progressEmitter.event
|
|
|
|
public get state(): IndexingState {
|
|
return this._systemStatus
|
|
}
|
|
|
|
public getCurrentStatus() {
|
|
return {
|
|
systemStatus: this._systemStatus,
|
|
message: this._statusMessage,
|
|
processedItems: this._processedItems,
|
|
totalItems: this._totalItems,
|
|
currentItemUnit: this._currentItemUnit,
|
|
}
|
|
}
|
|
|
|
// --- State Management ---
|
|
|
|
public setSystemState(newState: IndexingState, message?: string): void {
|
|
const stateChanged =
|
|
newState !== this._systemStatus || (message !== undefined && message !== this._statusMessage)
|
|
|
|
if (stateChanged) {
|
|
this._systemStatus = newState
|
|
if (message !== undefined) {
|
|
this._statusMessage = message
|
|
}
|
|
|
|
// Reset progress counters if moving to a non-indexing state or starting fresh
|
|
if (newState !== "Indexing") {
|
|
this._processedItems = 0
|
|
this._totalItems = 0
|
|
this._currentItemUnit = "blocks" // Reset to default unit
|
|
// Optionally clear the message or set a default for non-indexing states
|
|
if (newState === "Standby" && message === undefined) this._statusMessage = "Ready."
|
|
if (newState === "Indexed" && message === undefined) this._statusMessage = "Index up-to-date."
|
|
if (newState === "Error" && message === undefined) this._statusMessage = "An error occurred."
|
|
}
|
|
|
|
this._progressEmitter.fire(this.getCurrentStatus())
|
|
}
|
|
}
|
|
|
|
public reportBlockIndexingProgress(processedItems: number, totalItems: number): void {
|
|
const progressChanged = processedItems !== this._processedItems || totalItems !== this._totalItems
|
|
|
|
// Don't override Stopping state with progress updates
|
|
if (this._systemStatus === "Stopping") return
|
|
// Update if progress changes OR if the system wasn't already in 'Indexing' state
|
|
if (progressChanged || this._systemStatus !== "Indexing") {
|
|
this._processedItems = processedItems
|
|
this._totalItems = totalItems
|
|
this._currentItemUnit = "blocks"
|
|
|
|
const message = `Indexed ${this._processedItems} / ${this._totalItems} ${this._currentItemUnit} found`
|
|
const oldStatus = this._systemStatus
|
|
const oldMessage = this._statusMessage
|
|
|
|
this._systemStatus = "Indexing" // Ensure state is Indexing
|
|
this._statusMessage = message
|
|
|
|
// Only fire update if status, message or progress actually changed
|
|
if (oldStatus !== this._systemStatus || oldMessage !== this._statusMessage || progressChanged) {
|
|
this._progressEmitter.fire(this.getCurrentStatus())
|
|
}
|
|
}
|
|
}
|
|
|
|
public reportFileQueueProgress(processedFiles: number, totalFiles: number, currentFileBasename?: string): void {
|
|
const progressChanged = processedFiles !== this._processedItems || totalFiles !== this._totalItems
|
|
|
|
// Don't override Stopping state with progress updates
|
|
if (this._systemStatus === "Stopping") return
|
|
if (progressChanged || this._systemStatus !== "Indexing") {
|
|
this._processedItems = processedFiles
|
|
this._totalItems = totalFiles
|
|
this._currentItemUnit = "files"
|
|
this._systemStatus = "Indexing"
|
|
|
|
let message: string
|
|
if (totalFiles > 0 && processedFiles < totalFiles) {
|
|
message = `Processing ${processedFiles} / ${totalFiles} ${this._currentItemUnit}. Current: ${
|
|
currentFileBasename || "..."
|
|
}`
|
|
} else if (totalFiles > 0 && processedFiles === totalFiles) {
|
|
message = `Finished processing ${totalFiles} ${this._currentItemUnit} from queue.`
|
|
} else {
|
|
message = `File queue processed.`
|
|
}
|
|
|
|
const oldStatus = this._systemStatus
|
|
const oldMessage = this._statusMessage
|
|
|
|
this._statusMessage = message
|
|
|
|
if (oldStatus !== this._systemStatus || oldMessage !== this._statusMessage || progressChanged) {
|
|
this._progressEmitter.fire(this.getCurrentStatus())
|
|
}
|
|
}
|
|
}
|
|
|
|
public dispose(): void {
|
|
this._progressEmitter.dispose()
|
|
}
|
|
}
|