Repository navigation
refactor(task-graph): read tasks through a lazily loaded graph - #943
Merged
Merged
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
fspy benchmarklinuxmacoswindows |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 424f37e. Configure here.
Tasks now live in `LazyGraph`, a generic graph that loads one package's tasks the first time any of them is read and resolves a task's `dependsOn` the first time it's read. `IndexedTaskGraph` exposes only reads (`task`, `tasks`, `depends_on`, `query_tasks`, ...) built on it, so the planner, the task selector and the session no longer see petgraph or call a load step: the `TaskGraphLoader` trait and `Session::ensure_task_graph_loaded` are gone, and `Session::task_graph` returns the graph. `IndexedTaskGraph::load` still reads every config and resolves every `dependsOn` up front, so errors and output are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…her packages' The root package loads before the rest, so when its tasks set cache fields at the top level, `load` returned that error before visiting the other packages, and the error listed only the root's tasks. Pass it to `load_all`, which adds the other packages' tasks, as before this stack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wan9chi
force-pushed
the
claude/lazy-loading-task-graph-6fbaee
branch
from
November 5, 2026 12:43
619ae94 to
8584d82
Compare
wan9chi
added a commit
that referenced
this pull request
Nov 5, 2026
…asks (#944) ## Motivation `vp run` loads every package's `vite.config.*` before it plans, so a run in one package waits for all of them, and a broken config in any package fails every run in the workspace. With every task read going through the lazy graph (#943), configs can load only when a run reaches their tasks. ## Changes - `IndexedTaskGraph::load` no longer loads every task and resolves every `dependsOn` up front. It loads the package list and the root config; another package's config loads when a run first reads its tasks, through the task query, a `dependsOn` or a nested `vp run`. - Checks that covered the whole workspace now run when a package's config loads: `cache` or `enablePrePostScripts` outside the root config, a task named like a `package.json` script, a `dependsOn` naming a missing task, and cache settings at the top level of a task. That last error used to list every such task in the workspace; it now lists the loading package's, as the snapshot of `top_level_cache_fields_workspace_error` shows. - `vp run` without a task lists every task, so it still loads every config. E2E fixture `unreached_package_config`: `packages/broken` sets `cache`, which only the root config may set, or, in the second case, has a `vite-task.json` that isn't valid JSON. The first commit records today's output: every run fails with that package's error, including `vt run -t build` in `packages/app`, which only runs `@test/app` and `@test/lib`. In the second, that run succeeds, while `vt run -r build` and a `dependsOn` on `@test/broken#build` still fail. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes when config validation runs and which errors surface, which could hide issues until a package is first reached in a run. > > **Overview** > **`vp run` no longer loads every package's `vite.config.*` up front.** `IndexedTaskGraph::load` now loads the package list and workspace root config only; each other package's config loads the first time a run reads that package's tasks (task selection, `-r`, `dependsOn`, or listing all tasks). > > Runs scoped to one package **ignore broken or invalid configs in packages the graph never touches**, so startup is faster and unrelated packages can't block the run. When a run **does** reach a package, config errors (invalid JSON, `cache` outside the root, misplaced cache fields, etc.) still fail at load time as before. **`vp run` without a task** still enumerates every task, so it still loads every config. > > Workspace-wide aggregation of top-level cache field errors is removed: those messages now list only tasks from the package being loaded. E2E fixture **`unreached_package_config`** documents the new behavior, and the changelog is updated. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3a205d0. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
wan9chi
added a commit
to voidzero-dev/vite-plus
that referenced
this pull request
Nov 5, 2026
Point the vite-task git dependencies at 650d697, which loads a package's `vite.config.*` only when a run reaches its tasks (voidzero-dev/vite-task#943, #944), so the preview workflow produces a build to measure against the 0b37399 baseline. This exists only to generate a preview build and is not meant to be merged. `Session::ensure_task_graph_loaded` is now `Session::task_graph`, which takes `&self`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Motivation
vp runloads every package'svite.config.*before it plans anything, even when the run touches one package. To load configs only when a run needs them (#944), every reader of the task graph has to go through methods that can load what they read. Today the planner, the task selector and the session read petgraph nodes and edges directly, and callload_task_graph()first so that everything is loaded.This PR moves every reader onto such methods without changing what loads: everything still loads up front.
Changes
vt_graph::lazy_graph::LazyGraph: a generic graph that loads a partition's nodes the first time any of them is read, and resolves a node's edges the first time they're read. Resolving edges can read nodes, loading their partitions, but not other nodes' edges, so adependsOncycle across packages can't make two loads wait on each other. Nodes live in an append-onlyelsa::FrozenMap, so reads return plain references.TaskLoaderholds the per-package code that was inIndexedTaskGraph::load: config loading, its checks, anddependsOnresolution. The root config loads with the package list, since its settings apply to the whole workspace.IndexedTaskGraphexposes only reads:task,tasks,depends_on,query_tasks,get_script_hookandlist_tasks. Tasks are keyed byTaskId(package index and task name) instead of petgraph node indices, and a query returns aBTreeMapof the tasks it selected.TaskGraphLoader,Session::ensure_task_graph_loaded,TaskNodeIndexand the petgraphTaskGraphtype are removed, andSession::task_graph()returns the graph. vite-plus'sbench/benches/workspace_load.rscallsensure_task_graph_loaded, which becomestask_graph().IndexedTaskGraph::loadstill reads every config and resolves everydependsOn, through the same reads, so output and errors don't change and no snapshot changes. One difference: when several packages have config errors, the first one reported can differ. Before, every config was read and checked before any task was created; now each package's config and tasks load together, the root's first, then the others in package order. The error that lists tasks setting cache fields at the top level still covers every package; plan fixturetop_level_cache_fields_workspace_errorchecks that with the root and a package.LazyGraphhas unit tests for what each read loads, a cycle across partitions, a retry after a failed load, and duplicate edges.🤖 Generated with Claude Code
Note
Medium Risk
Touches core task-graph loading, querying, and planning with widespread async API changes, though behavior is intended to stay the same aside from multi-error ordering.
Overview
Refactors the workspace task graph so all reads go through async APIs built on a new
LazyGraph, instead of a fully builtpetgraphandTaskGraphLoader.LazyGraphloads graph partitions on first access (nodes per package, edges on firstdependsOnread), with stable node refs viaelsa::FrozenMap.TaskLoaderholds the per-package config/script loading and dependency resolution that used to live inIndexedTaskGraph::load.IndexedTaskGraphis now keyed byTaskId(notTaskNodeIndex). Callers usetask,tasks,depends_on,query_tasks,list_tasks, andget_script_hook. Query results are aBTreeMapofQueriedTaskinstead of a petgraph of indices.Session caches the graph in
tokio::sync::OnceCell(**task_graph()** replacesensure_task_graph_loaded).vt_plantakes a loadedIndexedTaskGraphdirectly and plans fromTaskNodereferences.IndexedTaskGraph::loadstill runsload_allso every package anddependsOnis validated up front (same outcomes; which config error surfaces first can change when several packages fail).TopLevelCacheFieldsCollector::absorbaggregates misplaced cache fields across packages; a new plan snapshot fixture covers root + package errors together.Reviewed by Cursor Bugbot for commit 8584d82. Bugbot is set up for automated code reviews on this repo. Configure here.