name: incremental-build description: > Work on the incremental (delta) build system in @ui5/project: build caching, resource indexing, hash trees, stage caching, build server, file watching, task execution caching, and delta builds. when_to_use: > TRIGGER when: the user asks about or wants to modify code related to incremental builds, build caching, resource indexing, hash trees, stage caching, build server, file watching, task execution caching, delta builds, resource tags in build context, or any component listed in the Component Map in architecture.md. DO NOT TRIGGER when: the user is working on unrelated CLI commands, general tooling, or non-build features. user-invocable: true
Incremental Build Skill
You are working on the incremental (delta) build system in @ui5/project. Read architecture.md in this skill directory for the full architecture reference, including the component map, key flows, caching architecture, and data structures. Read performance-investigation.md for guidance on profiling builds, reading perf logs, and known performance peculiarities.
Guidelines for Working on This Code
- Always read the source file before modifying it. The Component Map in
architecture.mdtells you where each piece lives. - Understand the cache flow direction. Changes propagate: source change -> index update -> signature change -> cache miss -> task re-execution.
- Be careful with tag side effects.
getTags()is not a pure read -- it triggers lazy tag application. Avoid calling it in unexpected contexts. - Respect abort signals. Any long-running operation should check
signal?.throwIfAborted()periodically. - Test with incremental rebuilds. A single build passing is not enough; the interesting bugs appear on the second and third builds after file changes.
- Watch for stale stage readers after abort. If a build is aborted, stage writers may contain partial results that shadow source files.
- Signature stability matters. Any change to how hashes are computed (e.g., adding new fields to hash input) invalidates all existing caches.
- SharedHashTree operations must go through TreeRegistry. Never mutate a SharedHashTree directly; always schedule via the registry and flush.
Known Constraints
StageCache(in-memory) has noclear()method -- stage entries persist for the lifetime of theProjectBuildCacheinstanceProjectBuildContextinstances (including their caches) are reused across sequential builds of the same project within a sessionresource.getTags()has side effects: it triggers#applyCachedResourceTags()and createsMonitoredResourceTagCollectioninstances, which modify tag collection state. This means callinggetTags()during hash tree operations (e.g., inTreeRegistry.flush()) can affect the stage pipeline state.updateProjectIndicesusesproject.getReader()(stage pipeline reader) to read resources. After an aborted build, stage writers may contain in-memory resources that shadow updated source content, causing stale reads.getSourcePaths()andgetVirtualPath()are NOT consistent withgetSourceReader()for all project types. Module has nogetVirtualPath()(base class throws). ThemeLibrary'sgetSourcePaths()returns only[src/]andgetVirtualPath()only mapssrc/, but_getReader()also includestest/when_testPathExists. Any optimization that replacessourceReader.byGlob()with direct filesystem enumeration viagetSourcePaths()+getVirtualPath()must handle these mismatches.