## Summary
- **Extract `Indexer` class** — owns all index state (ProjectIndex,
MergedIndex shards, OpenFileIndex) and query methods (definition,
references, call/type hierarchy, workspace symbol search)
- **Extract `Compiler` class** — owns document state, PCH/PCM cache,
compile argument resolution, header context, `ensure_compiled`, and
worker forwarding
- **MasterServer is now a pure LSP handler registration layer** (~700
lines, down from ~3200)
- **`MergedIndexShard`** wraps `index::MergedIndex` with a lazily-cached
PositionMapper; `OpenFileIndex` gains matching
`find_occurrence()`/`find_relations()` APIs — callers get pre-converted
LSP ranges directly
- **Indexer returns typed values** (`vector<Location>`,
`vector<CallHierarchyIncomingCall>`, etc.) instead of pre-serialized
JSON, fixing the references handler from JSON string surgery to simple
vector concatenation
- **Fix**: duplicate `workspace/symbol` loop in the original code
## Test plan
- [x] 465 unit tests pass
- [x] 113 integration tests pass
- [x] 2/2 smoke tests pass
- [x] `clang-format` applied
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Server-side C++ compilation orchestration (module & precompiled header
builds) with LSP-integrated document handling.
* **Improvements**
* Deterministic, persistent, dependency-aware caching to avoid redundant
rebuilds and speed up incremental work.
* Better cross-file indexing and navigation, improved diagnostics and
more reliable include/import-aware completions.
* **Tests**
* Unit tests updated to the unified worker query/build request shapes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
PCH and PCM artifacts are now cached to disk at
`.clice/cache/{pch/,pcm/}` with content-addressed filenames, so they
survive server restarts. Dependency metadata is persisted in
`cache.json` (using eventide serde) with a shared path table for
deduplication.
### Key changes
- **protocol.h**: `output_path` field on `BuildPCHParams` /
`BuildPCMParams` so master specifies where workers write
- **stateless_worker.cpp**: Atomic write via `.tmp` + `fs::rename`;
`CompilationUnit` destroyed before rename to flush the file to disk;
fallback to temp file when `output_path` is empty (unit tests)
- **master_server.h**: `PCMState` struct, `pcm_states` map,
`load_cache()` / `save_cache()` / `cleanup_cache()` methods
- **master_server.cpp**: Cache lifecycle — load from `cache.json` on
startup, save after each PCH/PCM build and on exit; deterministic path
computation (`xxh3` preamble hash for PCH, module name + source path
hash for PCM); stale files (>7 days) cleaned on startup; `cache.json`
uses shared path table to avoid redundant storage of header paths across
entries
- **filesystem.h**: `fs::rename()` helper; `ThreadSafeFS` broadened to
match `.pch` extension instead of `preamble-` prefix
- **tests**: 11 new integration tests covering PCH/PCM persistence,
cross-session reuse, staleness detection, shared preamble dedup, and
restart survival; unit tests updated with `output_path`
### Naming scheme
- **PCH**: `.clice/cache/pch/<016x(xxh3(preamble))>.pch`
- **PCM**:
`.clice/cache/pcm/<module_name>-<016x(xxh3(source_path))>.pcm`
## Test plan
- [x] Unit tests — 448 passed
- [x] Integration tests — 92 passed (including 11 new persistent cache
tests)
- [x] Smoke tests — 1 passed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
- **CMake-based CDB generation for module tests**: Replace hand-written
compile_commands.json with CMakeLists.txt (CMake 3.28 `FILE_SET
CXX_MODULES`) in all 26 `tests/data/modules/*/` directories. CDB is
generated on-the-fly via `cmake -G Ninja` during test setup.
- **`@pytest.mark.workspace()` decorator**: Introduce a marker + fixture
pattern so tests declare their workspace via decorator and receive a
resolved `workspace` path. The fixture auto-generates CDB when a
CMakeLists.txt is present.
- **`CliceClient` helper methods**: Add `initialize()`, `open()`,
`wait_diagnostics()`, and `open_and_wait()` to reduce boilerplate across
all test files.
- **Use `asyncio_mode = "auto"`**: Switch from `@pytest_asyncio.fixture`
+ `@pytest.mark.asyncio` to `@pytest.fixture` + auto mode for proper
Pylance type inference on fixtures.
- **Test cleanup**: Remove redundant section separators and docstrings,
delete `tests/pyproject.toml` (config moved to `pytest.ini`).
- **Format task**: Add `.cppm` to `format-cpp` glob pattern.
- **CI fix**: Disable `CMAKE_CXX_SCAN_FOR_MODULES` and prefer pixi
clang++ to fix macOS CI where CMake rejects module scanning.
## Test plan
- [x] All 26 module test directories have CMakeLists.txt with FILE_SET
CXX_MODULES
- [x] generate_cdb() produces valid compile_commands.json with module
flags
- [x] Integration tests pass locally
- [ ] CI passes on all platforms (Linux, macOS, Windows)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Unified fixtures and client workflow: new init/open/wait helpers,
workspace marker support, bounded diagnostics waiting, CMake-based
compilation-database generation, and directory-backed temp-file
workflows; enabled asyncio test mode.
* **Chores**
* Added many C++20 module test projects and test data; removed prior
test pyproject in favor of pytest config; updated formatter to include
.cppm files.
* **Style**
* Reformatted many module/source implementations to consistent
multi-line function bodies.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
Initial integration of `CompileGraph` (#375) into `MasterServer`,
enabling basic end-to-end C++20 module support: on-demand PCM building,
dependency-ordered compilation, cascade invalidation on save, and
diagnostic integration.
This is a **first-pass implementation** — the core pipeline works, but
there are known areas for follow-up:
- PCM files go to system temp dir instead of `.clice/cache/`; no disk
cleanup on invalidation
- `run_build_drain` scans imports itself rather than delegating fully to
CompileGraph
- No incremental/partial rebuild (full PCM rebuild on any change)
- Cycle detection is tested at unit level but integration-level coverage
is minimal
## Changes
### Module dependency compilation (`master_server.cpp`)
Before sending a file to the stateful worker, `run_build_drain` now:
1. Scans imports via `scan_precise()` to discover module dependencies
2. Compiles each dep through `compile_graph->compile()`, which
recursively builds transitive PCMs
3. Handles implementation units — `module M;` implicitly needs the
interface PCM
4. Passes all built PCMs to the stateful worker, excluding the file's
own PCM
5. Skips compile on dep failure and resets `build_running` /
`drain_scheduled`
6. Re-lookups iterators after `co_await` to avoid use-after-invalidation
### Cascade invalidation (`didSave` / `didClose`)
- `didSave`: calls `compile_graph->update()` to mark transitive
dependents dirty, removes stale PCM paths, schedules rebuilds for open
dirtied files
- `didClose`: cancels in-flight compilations for the closed file
### Other fixes in this PR
- Debounce timers switched to `shared_ptr` to prevent use-after-free
when `didClose` destroys the timer mid-wait
- `fill_compile_args` returns `bool`; callers handle empty CDB
gracefully
- Adapt all `PositionMapper` call sites to the new `optional` return API
from eventide
## Test plan
- [x] 25 C++ unit tests for CompileGraph (cycles, partial failure,
cancel, update, empty graph)
- [x] 24 C++ integration tests with real clang PCM compilation
- [x] 3 worker-level module tests (BuildPCM, PCM-dependent compile,
multi-module)
- [x] 26 Python LSP integration tests (single module through circular
deps, hover, error diagnostics)
- [x] 371 unit tests + 54 integration tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>