Skip to content

Commit db6af72

Browse files
author
Eric Wheeler
committed
feat: task history scan/rebuild with advanced UI tools
Implement a comprehensive task history management system with UI tools for scanning, diagnosing, and repairing history issues: - Add new HistoryScanResults and HistoryRebuildOptions interfaces - Refactor reindexHistoryItems into modular components: - scanTaskHistory: Identifies valid, orphaned, and missing tasks - rebuildIndexes: Rebuilds indexes with configurable options - reconstructTask: Recovers orphaned tasks from UI messages - Create new HistoryIndexTools UI component with: - Task history scanning capabilities - Configurable rebuild options (merge/replace modes) - Task preview and inspection tools - Real-time operation logging - Improve error handling and provide detailed logging - Update message handlers and type definitions - Add comprehensive translations for the new UI This change helps users diagnose and fix task history inconsistencies between global state and filesystem, preventing "lost" tasks and improving history reliability. Signed-off-by: Eric Wheeler <[email protected]> fix: prevent ReDoS vulnerability in log message regex Replace non-greedy wildcard pattern (.*?) with a more specific character class [^\]]* to avoid potential catastrophic backtracking on malicious input. This addresses a security vulnerability where the regex could run slow on strings starting with '[]' and containing many repetitions of '\t'. Signed-off-by: Eric Wheeler <[email protected]> fix: replace regex with string indexes in logMessage Replace regex pattern with string index operations in logMessage function to avoid potential ReDoS (Regular Expression Denial of Service) vulnerabilities. The change uses indexOf and substring instead of regex matching, which is more efficient and safer for processing log messages with tags. Signed-off-by: Eric Wheeler <[email protected]> refactor: implement mutual exclusion for history operations Created a mutex pattern to ensure history operations are mutually exclusive. This prevents concurrent execution of reindexHistoryItems and search operations, maintaining data consistency during indexing. Extracted common mutex logic into a reusable _withMutex helper function. Signed-off-by: Eric Wheeler <[email protected]> feat: add bidirectional sync with legacy globalState Adds capability to synchronize tasks between the new file-based history system and legacy VSCode globalState storage: - Renamed mergeGlobal to mergeFromGlobal for clarity - Added new mergeToGlobal option to update globalState with file index data - Added tracking of tasks that exist only in file indexes via tasksOnlyInTaskHistoryIndexes - Added developer UI controls in advanced section for managing globalState sync - Updated tests and documentation to reflect new bidirectional capabilities This feature enables backward compatibility testing with older versions of Roo Code by ensuring tasks created in the new storage format are also available in the legacy format. Signed-off-by: Eric Wheeler <[email protected]> refactor: make rebuildIndexes private by renaming to _rebuildIndexes This change makes the rebuildIndexes function private by adding an underscore prefix to its name, following the project's convention for private functions. All references to this function have been updated accordingly in both the implementation and test files. Signed-off-by: Eric Wheeler <[email protected]>
1 parent f86d351 commit db6af72

File tree

12 files changed

+1700
-5
lines changed

12 files changed

+1700
-5
lines changed

packages/types/src/history.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,97 @@ export interface HistorySearchOptions {
7272
sortOption?: HistorySortOption
7373
dateRange?: { fromTs?: number; toTs?: number }
7474
}
75+
76+
/**
77+
* Represents the results of a scan of the task history on disk and in global state.
78+
* This is a read-only data structure used to report the state of the history to the UI.
79+
*/
80+
export interface HistoryScanResults {
81+
/**
82+
* The number of valid tasks found during the scan.
83+
* This is equivalent to tasks.valid.size.
84+
*/
85+
validCount: number
86+
87+
tasks: {
88+
/**
89+
* Tasks with a valid `history_item.json` file.
90+
* Key: Task ID, Value: The corresponding HistoryItem.
91+
*/
92+
valid: Map<string, HistoryItem>
93+
94+
/**
95+
* Tasks found in the legacy globalState array but not on the filesystem.
96+
* Key: Task ID, Value: The corresponding HistoryItem from globalState.
97+
*/
98+
tasksOnlyInGlobalState: Map<string, HistoryItem>
99+
100+
/**
101+
* Tasks found in the <state>/taskHistory/ indexes but not in the globalState array.
102+
* Key: Task ID, Value: The corresponding HistoryItem from file indexes.
103+
*/
104+
tasksOnlyInTaskHistoryIndexes: Map<string, HistoryItem>
105+
106+
/**
107+
* Tasks found on the filesystem that are not in the index, but
108+
* successfully reconstructed in-memory from history_item.json or ui_messages.json
109+
* Key: Task ID, Value: The reconstructed HistoryItem.
110+
*/
111+
orphans: Map<string, HistoryItem>
112+
113+
/**
114+
* Task IDs for which in-memory reconstruction from UI messages failed.
115+
* Value: The Task ID.
116+
*/
117+
failedReconstructions: Set<string>
118+
}
119+
}
120+
121+
/**
122+
* Options for rebuilding history indexes.
123+
*/
124+
export interface HistoryRebuildOptions {
125+
/**
126+
* The rebuild mode (not applicable when doing a scan):
127+
* - "replace": Creates fresh indexes, replacing existing ones
128+
* - "merge": Only indexes missing/changed history items, preserving existing data
129+
*/
130+
mode: "replace" | "merge"
131+
132+
/**
133+
* Whether to merge items from globalState.
134+
* When true, moves globalState tasks to the rebuild process.
135+
*/
136+
mergeFromGlobal?: boolean
137+
138+
/**
139+
* Whether to merge rebuilt items to globalState.
140+
* When true, updates context.globalState with the rebuilt history items.
141+
*/
142+
mergeToGlobal?: boolean
143+
144+
/**
145+
* Whether to scan for orphan history_item.json files during the rebuild process.
146+
* When true, use file system scanning to find all files
147+
* When false (default), use getHistoryItemsForSearch() because it is faster to use the index
148+
*/
149+
scanHistoryFiles?: boolean
150+
151+
/**
152+
* Whether to attempt reconstructing orphaned tasks.
153+
* When true, writes orphaned items to disk.
154+
*/
155+
reconstructOrphans?: boolean
156+
157+
/**
158+
* Array to collect log messages during the operation.
159+
* If provided, all operation logs will be added to this array.
160+
*/
161+
logs?: string[]
162+
163+
/**
164+
* Whether to skip the verification scan after rebuilding.
165+
* When true, skips the verification step to improve performance.
166+
*/
167+
noVerify?: boolean
168+
}

0 commit comments

Comments
 (0)