Skip to content

[task-history] Stop rewriting the full task history into VS Code global state - #29

Merged
simurg79 merged 1 commit into
mainfrom
perf/stop-task-history-globalstate-writes
Oct 29, 2026
Merged

simurg79 merged 1 commit into
mainfrom
perf/stop-task-history-globalstate-writes

Conversation

@simurg79

Copy link
Copy Markdown
Owner

What is the problem?

After every task-history change, ClineProvider scheduled a 5-second debounced "write-through" that copied the entire history (taskHistoryStore.getAll()) into globalState["taskHistory"], even though per-task files have been the source of truth since the file-backed store landed. VS Code keeps all of an extension's global state in one value, so each write re-serializes the whole value, routes it through the VS Code main process, and pushes it to every open window's extension host.

With 4,411 tasks that value is about 21 MB. While a task runs, each window logged large extension state detected (extensionId: RooVeterinaryInc.roo-cline, global: true): 21241.95kb every 2-15 seconds. In a 7-minute, per-second CPU capture, all 46 seconds in which the VS Code main-process thread was at least 50% busy fell within 2 seconds of one of these broadcasts; away from broadcasts that thread averaged 2%. Typing lagged in every VS Code window during those stalls.

How does this PR solve the problem?

Ports Zoo-Code-Org/Zoo-Code#1664 (219db1da5, cherry-picked with -x, original author preserved):

  • Removes the debounced write-through and the flush on dispose. Per-task files remain the only place new history is written.
  • Adds getTaskHistoryItem(), which falls back to the legacy globalState copy only until the file-backed store finishes initializing, so a task deleted from the store cannot be restored from the stale legacy copy.
  • Leaves the one-time migration from legacy globalState unchanged.

Conflicts were context-only. This fork's surrounding fields and test mocks were kept, and the src/eslint-suppressions.json hunk was dropped because that file does not exist in this fork.

Out of scope, as upstream: the existing legacy taskHistory value is left in place and is now frozen. VS Code still re-sends it whenever Roo writes another global-state key (mode/profile switches, settings), so clearing it after confirming every entry has a per-task file is a possible follow-up.

How did you test the PR?

cd src
npx vitest run core/webview/__tests__/ClineProvider.taskHistory.spec.ts core/webview/__tests__/ClineProvider.spec.ts core/webview/__tests__/ClineProvider.sticky-mode.spec.ts core/webview/__tests__/ClineProvider.sticky-profile.spec.ts core/task-persistence
npx tsc --noEmit
npx eslint core/webview/ClineProvider.ts core/webview/__tests__/ClineProvider.spec.ts core/webview/__tests__/ClineProvider.sticky-mode.spec.ts core/webview/__tests__/ClineProvider.taskHistory.spec.ts --max-warnings=0
  • Vitest: 8 files, 170 passed, 6 skipped. The skips are pre-existing .skip tests on main.
  • tsc --noEmit and ESLint on the changed files: clean.
  • Commit hook: 10/10 lint tasks passed. Pre-push hook: 10/10 type-check tasks passed.
  • pnpm vsix built successfully; the packaged dist/extension.js no longer contains the write-through. The VSIX was installed locally, but its effect after a window reload has not been measured yet.
Agent notes

Base: 1a6a30a (simurg79/Roo-Code main). RooCodeInc/Roo-Code main has no newer commits and still contains the write-through. Zoo has not yet followed up on clearing the legacy blob.
Separate, unrelated finding: ps-tree spawns wmic.exe, which is absent on current Windows 11 builds, so ExecaTerminalProcess cannot find child PIDs (spawn wmic.exe ENOENT). This PR does not change that.

* perf(webview): stop task history globalState writes

Amp-Thread-ID: https://ampcode.com/threads/T-01a0aa02-b6de-7763-97b8-1650ea4b46da

* fix(history): prevent deleted task fallback

Amp-Thread-ID: https://ampcode.com/threads/T-01a0aac1-c3f8-7220-a896-ac2dafbf72e1

* test(history): seed authoritative store in sticky mode tests

Amp-Thread-ID: https://ampcode.com/threads/T-01a0aafa-4924-751a-9a0b-dce899b72a16

* test(history): complete deleted-task regression fixture

Amp-Thread-ID: https://ampcode.com/threads/T-01a0aafa-4924-751a-9a0b-dce899b72a16

* test(webview): cover file-backed history cutover

* fix: remove legacy task history after successful migration

Amp-Thread-ID: https://ampcode.com/threads/T-01a0be65-3651-76cf-999d-1c931f5de52a

* revert: keep legacy task history blob cleanup out of this PR

Reverts b92f0a365 at the maintainer's request. Clearing the pre-migration
globalState "taskHistory" blob needs its own design for handling old
blobs, so it will be tracked in a separate issue. This PR stays scoped to
stopping new task history writes to globalState.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Port of Zoo-Code-Org/Zoo-Code#1664. Conflicts were resolved by keeping this
fork's surrounding code; the src/eslint-suppressions.json hunk was dropped
because that file does not exist in this fork.
(cherry picked from commit 219db1da59d76c0e4bb4c59b7042f7bd415e2469)

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: edelauna <54631123+edelauna@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simurg79
simurg79 merged commit b32c5cf into main Oct 29, 2026
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants