Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
223 commits
Select commit Hold shift + click to select a range
b4a22b7
feat(fs): Enhance API for incremental build, add tracking readers/wri…
RandomByte Nov 18, 2025
792efc1
feat(server): Use incremental build in server
RandomByte Nov 18, 2025
853f1e1
feat(builder): Adapt tasks for incremental build
RandomByte Nov 18, 2025
c8401ee
refactor(project): Align getReader API internals with ComponentProjects
RandomByte Nov 18, 2025
55721f6
refactor(project): Refactor specification-internal workspace handling
RandomByte Nov 18, 2025
088e951
refactor(project): Implement basic incremental build functionality
RandomByte Nov 18, 2025
f44467e
refactor(cli): Use cache in ui5 build
RandomByte Nov 18, 2025
b4f23e4
refactor(project): Use cacache
RandomByte Nov 24, 2025
cad641b
refactor(project): Add cache manager
RandomByte Nov 28, 2025
8bc18af
refactor(fs): Refactor Resource internals
RandomByte Nov 27, 2025
3900158
refactor(fs): Provide createBuffer factory in FileSystem adapter
RandomByte Dec 1, 2025
3ab54c8
refactor(project): Refactor cache classes
RandomByte Dec 1, 2025
aa5b455
refactor(fs): Add Proxy reader
RandomByte Dec 4, 2025
0760f92
refactor(project): API refactoring
RandomByte Dec 8, 2025
928349e
refactor(builder): Rename task param 'buildCache' to 'cacheUtil'
RandomByte Dec 10, 2025
cc73715
refactor(project): Cleanup
RandomByte Dec 10, 2025
1426e4e
refactor(project): Move resource comparison to util
RandomByte Dec 12, 2025
9d551f8
refactor(project): Refactor stage handling
RandomByte Dec 16, 2025
6b55826
refactor(project): Fix cache handling
RandomByte Dec 16, 2025
4dafac3
refactor(fs): Remove contentAccess mutex timeout from Resource
RandomByte Dec 16, 2025
864d82b
refactor(project): Cleanup obsolete code/comments
RandomByte Dec 16, 2025
173a30b
refactor(server): Cleanup obsolete code
RandomByte Dec 16, 2025
0f4a4d8
refactor(project): Rename watch handler events
RandomByte Dec 16, 2025
63b4c9a
refactor: Fix linting issues
matz3 Dec 17, 2025
a723fc3
test(fs): Adjust getIntegrity tests
matz3 Dec 17, 2025
7e46650
refactor: Integrity handling
matz3 Dec 17, 2025
a2472fc
test(fs): Adjust getIntegrity tests again
matz3 Dec 17, 2025
97ac058
refactor: Consider npm-shrinkwrap.json
matz3 Dec 17, 2025
b727c9b
refactor: Rename Tracker => MonitoredReader
RandomByte Dec 17, 2025
6f44cc6
refactor(project): Use workspace version in stage name
RandomByte Dec 17, 2025
e0d300a
refactor(project): Fix stage writer order
RandomByte Dec 17, 2025
35a562f
refactor(fs): Add Switch reader
RandomByte Dec 17, 2025
cfefec8
refactor(project): Cleanup WatchHandler debounce
RandomByte Dec 17, 2025
5d76e8d
refactor(project): Fix outdated API call
RandomByte Dec 17, 2025
f0575f2
refactor(project): Fix build signature calculation
RandomByte Dec 17, 2025
265260a
refactor(fs): Pass integrity to cloned resource
RandomByte Dec 17, 2025
47f6e70
refactor(project): Fix pattern matching and resource comparison
RandomByte Dec 17, 2025
b88a431
refactor(project): Import/overwrite stages from cache after saving
RandomByte Dec 18, 2025
0cea7a8
test(builder): Sort files/folders
matz3 Dec 19, 2025
41acad8
refactor(builder): Prevent duplicate entries on app build from cache
matz3 Dec 19, 2025
8431c71
refactor(fs): Refactor MonitorReader API
RandomByte Dec 23, 2025
c362551
refactor(fs): Always calculate integrity on clone
RandomByte Dec 24, 2025
8fb7fce
refactor(fs): Add getter to WriterCollection
RandomByte Dec 29, 2025
7c12ffe
refactor(builder): Remove cache handling from tasks
RandomByte Dec 24, 2025
b3b4955
refactor(builder): Add env variable for disabling workers
RandomByte Dec 30, 2025
ec0b7b9
refactor(project): Track resource changes using hash trees
RandomByte Dec 23, 2025
9c41d85
refactor(project): Compress cache using gzip
RandomByte Jan 2, 2026
21ee135
refactor(fs): Ensure writer collection uses unique readers
RandomByte Jan 2, 2026
4eea387
refactor(fs): Remove write tracking from MonitoredReaderWriter
RandomByte Jan 2, 2026
3374394
refactor(project): Identify written resources using stage writer
RandomByte Jan 2, 2026
22bd2a0
refactor(project): Add basic differential update functionality
RandomByte Jan 2, 2026
13a6921
refactor(builder): Re-add cache handling in tasks
RandomByte Jan 7, 2026
f508b04
refactor(project): Cleanup HashTree implementation
RandomByte Jan 7, 2026
ade0088
refactor(project): Make WatchHandler wait for build to finish before …
RandomByte Jan 7, 2026
c67b953
refactor(project): Use cleanup hooks in update builds
RandomByte Jan 7, 2026
ff270f2
refactor(logger): Log skipped projects/tasks info in grey color
RandomByte Jan 7, 2026
bda0354
refactor(project): Fix cache update mechanism
RandomByte Jan 7, 2026
751034c
refactor(project): WatchHandler emit error event
RandomByte Jan 7, 2026
a0b451c
refactor(server): Exit process on rebuild error
RandomByte Jan 7, 2026
7454a51
refactor(project): Fix delta indices
RandomByte Jan 7, 2026
91dbc60
refactor(logger): Support differential update task logging
RandomByte Jan 8, 2026
e1b57e2
refactor(project): Provide differential update flag to logger
RandomByte Jan 8, 2026
a113712
refactor(server): Log error stack on build error
RandomByte Jan 8, 2026
286e542
refactor(project): Add chokidar
RandomByte Jan 8, 2026
1e386a5
refactor(project): Limit build signature to project name and config
RandomByte Jan 8, 2026
f559ee4
refactor(project): Improve ResourceRequestGraph handling
RandomByte Jan 8, 2026
dfbdcc4
refactor(server): Remove obsolete code from serveResources middleware
matz3 Jan 8, 2026
7f4fd3f
refactor(project): Add env variable to skip cache update
RandomByte Jan 9, 2026
27c1135
refactor(project): Fix hash tree updates
RandomByte Jan 9, 2026
887e503
refactor(project): Remove unused 'cacheDir' param
matz3 Jan 9, 2026
78169a7
fix(project): Prevent projects from being always invalidated
matz3 Jan 9, 2026
b9a60ce
fix(project): Prevent exception when not building in watch mode
matz3 Jan 12, 2026
a749800
refactor(project): Only store new or modified cache entries
RandomByte Jan 9, 2026
beb2ca9
refactor(project): Refactor project cache validation
RandomByte Jan 11, 2026
b663eaa
refactor(project): Extract project build into own method
matz3 Jan 13, 2026
8a1aa26
fix(project): Clear cleanup task queue
matz3 Jan 13, 2026
10553fb
test(project): Add ProjectBuilder integration test
matz3 Jan 13, 2026
dbe3163
test(project): Add failing ProjectBuilder test case
matz3 Jan 13, 2026
f5fedcb
test(project): Enhance ProjectBuilder test assertions
matz3 Jan 13, 2026
02c3665
test(project): Add library test case for ProjectBuilder
matz3 Jan 13, 2026
2831deb
test(project): Build dependencies in application test of ProjectBuilder
matz3 Jan 13, 2026
6df1a07
test(project): Refactor ProjectBuilder test code
matz3 Jan 14, 2026
5aedd28
refactor(project): Refactor task resource request tracking
RandomByte Jan 14, 2026
086c1d1
test(project): Add theme-library test and update assertions for fixed…
matz3 Jan 14, 2026
34ce53b
test(project): Use graph.build for ProjectBuilder test
matz3 Jan 15, 2026
e8178da
test(project): Add custom task to ProjectBuilder test
matz3 Jan 15, 2026
1cc12e5
fix(project): Fix custom task execution
matz3 Jan 15, 2026
85d1b11
fix(project): Prevent writing cache when project build was skipped
matz3 Jan 16, 2026
8772c4e
refactor(project): Create dedicated SharedHashTree class
RandomByte Jan 15, 2026
9606b2c
refactor(project): Re-implement differential task build
RandomByte Jan 15, 2026
c279a7d
refactor(project): Fix HashTree tests
RandomByte Jan 16, 2026
00fa023
refactor(project): Fix handling cache handling of removed resources
RandomByte Jan 16, 2026
d01f66d
test(project): Add cases for theme.library.e with seperate less files
maxreichmann Jan 20, 2026
9bc3a68
refactor(project): Update graph traversal
RandomByte Jan 20, 2026
168d413
refactor(project): Add BuildServer and BuildReader
RandomByte Jan 16, 2026
b8061d5
refactor(project): Refactor project result cache
RandomByte Jan 20, 2026
1410621
refactor(server): Integrate BuildServer
RandomByte Jan 20, 2026
92861ec
refactor(project): Small build task cache restructuring, cleanup
RandomByte Jan 20, 2026
68125a3
refactor(project): JSDoc cleanup
RandomByte Jan 20, 2026
f75bebe
refactor(project): ProjectBuilder cleanup
RandomByte Jan 20, 2026
6548850
refactor(builder): Small stringReplacer cleanup
RandomByte Jan 20, 2026
637e6ff
revert(fs): Add Switch reader
RandomByte Jan 20, 2026
3350ca1
refactor(project): Add perf logging, cleanups
RandomByte Jan 20, 2026
a9ce605
refactor(project): Add cache write perf logging
RandomByte Jan 20, 2026
82892e7
refactor(project): Improve stage change handling
RandomByte Jan 21, 2026
9f2bed9
refactor(project): Implement queue system in BuildServer
matz3 Jan 21, 2026
27071cb
refactor(server): Add error callback and handle in CLI
RandomByte Jan 21, 2026
a23ba1f
refactor(project): ProjectBuilder to provide callback on project built
RandomByte Jan 21, 2026
8ff3e3c
refactor(project): Do not always include root project in build
RandomByte Jan 21, 2026
dca95b5
refactor(project): Refactor BuildServer init, add tests
RandomByte Jan 21, 2026
8861549
refactor(project): Minor ProjectBuildCache and ProjectBuildContext re…
RandomByte Jan 23, 2026
9c36909
refactor(project): Handle abort signal in ProjectBuilder et al.
RandomByte Jan 23, 2026
a279db4
refactor(project): Refactor BuildServer queue
RandomByte Jan 23, 2026
c8dc196
refactor(project): Fix cache invalidation tracking
RandomByte Jan 23, 2026
1f2bbb9
refactor(project): Fix stage restore
RandomByte Jan 26, 2026
c6e34ea
refactor(project): Add cache support for custom tasks
RandomByte Jan 26, 2026
5b426c2
test(project): Add file deletion case for theme.library.e
maxreichmann Jan 26, 2026
44c252a
fix(builder): Filter out non-JS resources in minify task
matz3 Jan 26, 2026
d9f4f89
test(project): Add test case for minify task fix
matz3 Jan 26, 2026
e15313f
test(project): Add ResourceRequestManager tests
RandomByte Jan 26, 2026
c46a285
refactor(project): Fix derived trees unexpected upsert in parents
RandomByte Jan 26, 2026
42a393b
test(project): Adjust test cases for .library changes
matz3 Jan 26, 2026
70c06c3
fix: Ensure dot-file matching with micromatch
matz3 Jan 26, 2026
9579961
test(project): Add test case for ui5.yaml changes
matz3 Jan 26, 2026
84f9f2c
fix(project): Handle BuildServer race condition when changing files
matz3 Jan 26, 2026
bf6fb97
test(project): Remove test.serial.only
matz3 Jan 26, 2026
cc8d8a1
deps: Fix depcheck issues
matz3 Jan 26, 2026
8673f76
test(project): Update ProjectBuildCache and TaskBuildCache tests
RandomByte Jan 26, 2026
443cb99
test(project): Update ProjectBuilder tests and JSDoc
RandomByte Jan 26, 2026
fac2209
test(project): Update TaskRunner tests
RandomByte Jan 26, 2026
9b6a63c
test(project): Update various tests
RandomByte Jan 26, 2026
a64759a
test(project): Add missing comma
matz3 Jan 27, 2026
44f04f2
refactor(project): Improve abort signal handling
RandomByte Jan 27, 2026
27bf81e
refactor(project): Fix additional tests
RandomByte Jan 27, 2026
1c3b431
refactor(project): Move dependency indice init into PBC
RandomByte Jan 27, 2026
52fa057
fix(project): Improve BuildServer stability on resource changes
matz3 Jan 27, 2026
4c1f228
test(project): Add case for BuildServer which requests application an…
maxreichmann Jan 27, 2026
0ac8598
test(project): Add cases
maxreichmann Jan 28, 2026
13f2340
test(project): Add cases for project type "module" (ProjectBuilder)
maxreichmann Jan 29, 2026
0b84b28
refactor(project): ProjectBuildCache state handling
RandomByte Jan 28, 2026
f825f8b
test(project): Update node_modules deps to be aligned with actual fix…
maxreichmann Feb 4, 2026
ff60953
test(project): Add "library" dependencies to "module" fixture
maxreichmann Feb 5, 2026
5b79006
test(project): Update ProjectBuildContext tests
matz3 Feb 9, 2026
d56ec31
Revert "test(project): Update node_modules deps to be aligned with ac…
maxreichmann Feb 10, 2026
e3de6c6
refactor(project): Rename task param 'supportsDifferentialUpdates' =>…
RandomByte Feb 10, 2026
016dec2
test(project): Extend FixtureTester (ProjectBuilder) to work with non…
maxreichmann Feb 10, 2026
723f220
test(project): Add cases for ui5.yaml path mapping (Modules)
maxreichmann Feb 10, 2026
0e0f98c
test(project): Add race condition test
RandomByte Feb 10, 2026
212a13a
test(project): Add modify file case for modules
maxreichmann Feb 11, 2026
a5291e6
test(project): Add case for multiple custom tasks (tag handling)
maxreichmann Feb 16, 2026
43e7e7a
fix(project): Fix build manifest access
matz3 Feb 18, 2026
bdae0d6
test(project): Fix multiple-task tests (Address review)
maxreichmann Feb 18, 2026
90c0a53
test(project): Re-Add eslint rule (removed by accident)
maxreichmann Feb 18, 2026
6c0e0c3
refactor(fs): Add MonitoredResourceTagCollection
RandomByte Feb 23, 2026
e0890e4
refactor(project): Add basic handling for resource tags
RandomByte Feb 23, 2026
59e4ed5
test(project): Add another multiple-task / tag handling case
maxreichmann Feb 25, 2026
6ef07ac
test(project): Add case for dependency content changes
maxreichmann Feb 26, 2026
627d423
test(project): Clean-up temporary comments
maxreichmann Feb 27, 2026
f9b97cd
test(project): Add case for JSDoc builds (Standard Tasks)
maxreichmann Mar 5, 2026
0031e04
test(project): Address review of @RandomByte
maxreichmann Mar 5, 2026
dbe8dbf
refactor(project): Enhance build cache logging for signatures
RandomByte Mar 5, 2026
e4a8f7c
test(project): Add basic library build test for BuildServer
RandomByte Mar 5, 2026
2c6e830
test(project): Add cases for custom preload configs (for application,…
maxreichmann Mar 5, 2026
cc2c7fe
refactor(project): Adapt tests after refactoring of resource tag hand…
RandomByte Mar 6, 2026
a359945
refactor(fs): Fix resource integrity for resources without content
RandomByte Mar 6, 2026
ae00c61
test(logger): Fix tests
RandomByte Mar 6, 2026
f6eee00
test(project): Add case for self-contained builds (Standard Tasks)
maxreichmann Mar 6, 2026
0bb8c40
refactor(project): Fix incorrect stage signature when using delta sta…
RandomByte Mar 9, 2026
76ff6d6
test(project): Add cases for custom bundling builds
maxreichmann Mar 9, 2026
74a20c3
test(project): Add cases for file deletion (TC4)
d3xter666 Mar 10, 2026
5bf929e
test(project): Refactor "custom tasks 2" case
maxreichmann Mar 10, 2026
42d29ca
test(project): Add tests for various dependency relations
maxreichmann Mar 10, 2026
e3af462
test(project): Add cases for race condition (add/remove file)
d3xter666 Mar 16, 2026
f89dbb7
refactor(project): Cleanup cache state handling
RandomByte Mar 11, 2026
29d8919
feat(project): Incorporate resource tags into hash tree leaf node hashes
RandomByte Mar 10, 2026
913100b
refactor(fs): Add ResourceTagCollection#getAllTagsForResource method
RandomByte Mar 11, 2026
0a297a2
refactor(project): Add test for cross-project resource tag handling
RandomByte Mar 12, 2026
9ff89ec
refactor(fs): Expose getTags method on resource
RandomByte Mar 12, 2026
691b8b4
refactor(project): Fix tag handling, align test
RandomByte Mar 13, 2026
4afc584
refactor(project): Improve build abort handling, ease race-condition …
RandomByte Mar 16, 2026
1e7f376
refactor(project): Cleanup comment
RandomByte Mar 16, 2026
eecf9a8
test(project): Add case for --include-dependency (Cover build with on…
maxreichmann Mar 16, 2026
5d96e18
test(project): Check if sap-ui-version.json contains correct content
d3xter666 Mar 18, 2026
4f7cd30
test(project): Add case for removing a dependency
maxreichmann Mar 19, 2026
ed0dac7
refactor(project): Validate source files after build finishes
RandomByte Mar 19, 2026
cc7982b
refactor(project): Store source files in CAS
RandomByte Mar 19, 2026
bdfce5d
refactor(project): Use stored source files in ProjectResources
RandomByte Mar 19, 2026
f57ca5c
test(project): Add tests for cross project source file modifications
RandomByte Mar 19, 2026
ff08fb0
test(internal): Add new "e2e-tests" dir to internal/
maxreichmann Mar 27, 2026
052bc00
test: E2E-tests: Fix child process security
maxreichmann Apr 1, 2026
c8094fd
test: E2E-tests: Cover scenario for "ui5-task-zipper"
maxreichmann Apr 2, 2026
2064e84
test: E2E-tests: Cover scenario for "ui5-tooling-modules"
maxreichmann Apr 2, 2026
c940d16
test: E2E-tests: Cover scenario for "ui5-tooling-stringreplace" (Curr…
maxreichmann Apr 2, 2026
96cb64d
test: E2E-tests: Adjust readme
maxreichmann Apr 2, 2026
ea12cb5
test: Remove E2E-test
maxreichmann Apr 8, 2026
9e618ab
perf(project): Parallelize I/O in HashTree.upsertResources and TreeRe…
RandomByte Apr 16, 2026
6c10ed8
perf(project): Parallelize I/O in ResourceRequestManager
RandomByte Apr 17, 2026
43cb20b
perf(project): Skip redundant metadata checks for shared tree nodes
RandomByte Apr 17, 2026
368b0dc
perf(project): Prefetch stage cache lookups for next task
RandomByte Apr 17, 2026
2e787f7
perf(project): Add performance instrumentation to build cache
RandomByte Apr 17, 2026
2a8fa55
perf(project): Add orchestration-level timing instrumentation
RandomByte Apr 17, 2026
1e3311d
perf(project): Parallelize source index initialization across projects
RandomByte Apr 17, 2026
937b62e
perf(project): Defer cacache I/O in cached stage proxy readers
RandomByte Apr 17, 2026
6ff5e00
perf(project): Skip redundant dependency index updates for tasks with…
RandomByte Apr 17, 2026
ffbbd3b
docs: Add skills
RandomByte Apr 16, 2026
128a125
perf(project): Skip redundant CAS lookups for unchanged resources dur…
RandomByte Apr 20, 2026
ae987bd
perf(project): Suppress redundant change propagation on initial stage…
RandomByte Apr 20, 2026
718ba88
perf(project): Skip dependency index refresh when no changes were pro…
RandomByte Apr 20, 2026
2ce79d8
perf(project): Add instrumentation for allTasksCompleted, recordTaskR…
RandomByte Apr 22, 2026
f7ce9cc
perf(project): Pre-populate known CAS integrities from cached source …
RandomByte Apr 22, 2026
954bff4
perf(project): Reuse previous frozen source metadata for unchanged files
RandomByte Apr 22, 2026
4928143
refactor(server): Skip bundling by default
RandomByte Apr 22, 2026
90d98be
test(project): Add tests for dependency index refresh skip optimization
RandomByte Apr 22, 2026
6423a59
docs(fs): Add skill for @ui5/fs package
RandomByte Apr 23, 2026
4b97c8c
perf(project): Replace cacache with custom CAS for faster dist writes
RandomByte Apr 23, 2026
2febb1e
docs(project): Update incremental build skill
RandomByte Apr 23, 2026
393e485
perf(fs): Add CAS-aware fast path in FileSystem._write()
RandomByte Apr 23, 2026
3d3b74d
test(project): Add tests for delta cacheInfo path in recordTaskResult
RandomByte Apr 24, 2026
ceca57c
perf(project): Replace file-based metadata cache with SQLite storage
RandomByte Apr 27, 2026
d3a65e4
perf(project): Replace file-based CAS with SQLite BLOB storage
RandomByte Apr 27, 2026
04a6eb1
perf(project): Add batch transaction support to MetadataStorage
RandomByte Apr 27, 2026
ecc717d
refactor(project): Merge CAS and metadata into unified BuildCacheStorage
RandomByte Apr 28, 2026
0c087f8
feat: Introduce --cache option for ui5 build & ui5 serve
maxreichmann Apr 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .claude/skills/incremental-build/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
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

1. **Always read the source file before modifying it.** The Component Map in `architecture.md` tells you where each piece lives.
2. **Understand the cache flow direction.** Changes propagate: source change -> index update -> signature change -> cache miss -> task re-execution.
3. **Be careful with tag side effects.** `getTags()` is not a pure read -- it triggers lazy tag application. Avoid calling it in unexpected contexts.
4. **Respect abort signals.** Any long-running operation should check `signal?.throwIfAborted()` periodically.
5. **Test with incremental rebuilds.** A single build passing is not enough; the interesting bugs appear on the second and third builds after file changes.
6. **Watch for stale stage readers after abort.** If a build is aborted, stage writers may contain partial results that shadow source files.
7. **Signature stability matters.** Any change to how hashes are computed (e.g., adding new fields to hash input) invalidates all existing caches.
8. **SharedHashTree operations must go through TreeRegistry.** Never mutate a SharedHashTree directly; always schedule via the registry and flush.

## Known Constraints

- `StageCache` (in-memory) has no `clear()` method -- stage entries persist for the lifetime of the `ProjectBuildCache` instance
- `ProjectBuildContext` instances (including their caches) are reused across sequential builds of the same project within a session
- `resource.getTags()` has side effects: it triggers `#applyCachedResourceTags()` and creates `MonitoredResourceTagCollection` instances, which modify tag collection state. This means calling `getTags()` during hash tree operations (e.g., in `TreeRegistry.flush()`) can affect the stage pipeline state.
- `updateProjectIndices` uses `project.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()` and `getVirtualPath()` are NOT consistent with `getSourceReader()` for all project types. Module has no `getVirtualPath()` (base class throws). ThemeLibrary's `getSourcePaths()` returns only `[src/]` and `getVirtualPath()` only maps `src/`, but `_getReader()` also includes `test/` when `_testPathExists`. Any optimization that replaces `sourceReader.byGlob()` with direct filesystem enumeration via `getSourcePaths()` + `getVirtualPath()` must handle these mismatches.
369 changes: 369 additions & 0 deletions .claude/skills/incremental-build/architecture.md

Large diffs are not rendered by default.

377 changes: 377 additions & 0 deletions .claude/skills/incremental-build/performance-investigation.md

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions .claude/skills/ui5-fs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: ui5-fs
description: >
Work on the @ui5/fs package: the virtual file system abstraction layer providing
Resource, Adapters (FileSystem, Memory), Reader Collections (ReaderCollection,
ReaderCollectionPrioritized, DuplexCollection, WriterCollection), specialized readers
(Filter, Link, Proxy), resource tagging, monitoring, and the resourceFactory API.
when_to_use: >
TRIGGER when: the user asks about or wants to modify code related to @ui5/fs,
the virtual file system, resources, adapters, reader collections, writer collections,
DuplexCollection, resourceFactory, ResourceTagCollection, MonitoredReader, fsInterface,
ResourceFacade, or any file within packages/fs/.
DO NOT TRIGGER when: the user is working on builder tasks/processors, CLI commands,
server middleware, or project graph resolution that does not touch the FS layer.
user-invocable: true
---

# @ui5/fs Skill

You are working on the `@ui5/fs` package — the virtual file system abstraction layer for UI5 CLI. Read `architecture.md` in this skill directory for the full architecture reference, including the class hierarchy, API surface, adapter internals, and collection patterns.

## Package Location

Source: `packages/fs/lib/`
Tests: `packages/fs/test/lib/`
Fixtures: `packages/fs/test/fixtures/`

## Guidelines for Working on This Code

1. **Always read the source file before modifying it.** The Component Map in `architecture.md` tells you where each piece lives.
2. **Understand the content type state machine.** Resources have internal content types (BUFFER, STREAM, FACTORY, DRAINED_STREAM, IN_TRANSFORMATION) with strict transitions. Never bypass `modifyStream()` for content transformations — it handles mutex locking and state management.
3. **Respect the mutex.** Resource content access is protected by `async-mutex`. Concurrent `getBuffer()` / `getString()` calls are safe, but `modifyStream()` acquires an exclusive lock. Never hold a reference to content across an `await` that could trigger a transformation.
4. **Virtual paths are POSIX-absolute.** All virtual paths must be absolute POSIX paths (start with `/`). Base paths must end with `/`. Adapters normalize patterns relative to their `virBasePath`.
5. **Content parameters are mutually exclusive.** When creating a Resource, only one of `buffer`, `string`, `stream`, `createStream`, or `createBuffer` can be provided. The `createBuffer`/`createStream` factories enable lazy loading.
6. **byGlob randomizes result order.** `AbstractReader.byGlob()` intentionally shuffles results to prevent consumers from relying on ordering. Do not assume or depend on glob result order.
7. **Clone semantics matter.** Resources are cloned on retrieval from adapters. `resource.clone()` creates an independent copy including content. When modifying resources from collections, understand whether you're working on the original or a clone.
8. **ResourceFacade is immutable.** `ResourceFacade.setPath()` throws. The facade wraps a resource with a different virtual path (used by Link reader). Use `getOriginalPath()` to get the underlying path.
9. **Tag format is strict.** Tags follow the pattern `"namespace:Name"` — namespace is lowercase alphanumeric, name is PascalCase. Tags are validated on set. Use `ResourceTagCollection` or `MonitoredResourceTagCollection` for tag operations.
10. **Test with both FileSystem and Memory adapters.** Behavior can differ between adapters (e.g., FileSystem uses `globby` while Memory uses `micromatch`; FileSystem has lazy content loading via factories, Memory clones on read).

## Known Constraints

- `Resource.getStream()` is deprecated — use `getStreamAsync()` or `getBuffer()` / `getString()` instead. The deprecation warning is only logged once per process.
- `Resource.getStatInfo()` is deprecated — use `getLastModified()`, `getSize()`, `getInode()` instead.
- FileSystem adapter's `write()` uses `fs.copyFile` for unmodified resources (optimization). It also detects same-source-same-target writes and skips them, but switches to buffer-based writes if the content was modified (to avoid stream read-during-write conflicts).
- Memory adapter auto-creates virtual directory entries in its hierarchy on `write()`.
- `WriterCollection` matches the **longest prefix** (greedy match) when routing writes to writers.
- `DuplexCollection` uses an internal `ReaderCollectionPrioritized` with the writer first, so written resources shadow the reader's resources.
- `fsInterface` provides a Node.js `fs`-compatible wrapper but only implements `readFile`, `stat`, and `readdir`. `mkdir` is a no-op.
- `Resource.getIntegrity()` computes SHA-256 via `ssri` — this triggers full content loading if not already loaded.
- Monitored readers/writers (`MonitoredReader`, `MonitoredReaderWriter`) prevent reads/writes after being sealed. They track all access patterns for build caching analysis.

## Running Tests

```bash
# All tests
npm run unit --workspace=@ui5/fs

# Single file
cd packages/fs && npx ava test/lib/Resource.js

# Verbose with logging
npm run unit-verbose --workspace=@ui5/fs

# Coverage
npm run coverage --workspace=@ui5/fs
```
Loading