Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ semble savings --verbose # also show breakdown by call type

Savings are calculated as follows: for each call, semble records the total character count of the unique files containing returned chunks and the character count of the snippets returned. Estimated tokens saved is `(file chars − snippet chars) / 4` (4 chars per token). This is a conservative estimate: the baseline is reading matched files in full, which is how coding agents often explore unfamiliar code.

Stats are stored in the OS cache folder (`~/Library/Caches/semble/` on macOS, `~/.cache/semble/` on Linux, `%LOCALAPPDATA%\semble\Cache\` on Windows).
By default, stats are stored in the OS cache folder (`~/Library/Caches/semble/` on macOS, `~/.cache/semble/` on Linux, `%LOCALAPPDATA%\semble\Cache\` on Windows). To override this location you can supply an environment variable `SEMBLE_CACHE_LOCATION` which should be the full path to the target cache location e.g. 'd:\caches\storemysemblecachehere'.

</details>

Expand Down
6 changes: 4 additions & 2 deletions src/semble/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ def _linux_cache_dir(name: str) -> Path:


def resolve_cache_folder() -> Path:
"""Resolves a cache folder, respects XDG_CACHE_HOME."""
"""Resolves a cache folder, respects SEMBLE_CACHE_LOCATION (highest precedence), XDG_CACHE_HOME."""
name = "semble"
if sys.platform == "win32":
if semble_cache_location := os.getenv("SEMBLE_CACHE_LOCATION"):
cache_dir = Path(semble_cache_location)
elif sys.platform == "win32":
cache_dir = _windows_cache_dir(name)
elif sys.platform == "darwin":
cache_dir = _macos_cache_dir(name)
Expand Down
9 changes: 9 additions & 0 deletions tests/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ def test_resolve_cache_folder(platform: str, mock_target: str, expected: Path) -
assert result == expected


def test_resolve_cache_folder_semble_cache_location(tmp_path: Path) -> None:
"""SEMBLE_CACHE_LOCATION takes precedence over all platform-specific helpers."""
custom = tmp_path / "custom_cache"
with patch.dict("os.environ", {"SEMBLE_CACHE_LOCATION": str(custom)}):
result = resolve_cache_folder()
assert result == custom
assert custom.exists()


def test_clear_cache(tmp_path: Path) -> None:
"""clear_cache removes the index directory when it exists and is a no-op otherwise."""
index_path = tmp_path / "index"
Expand Down
Loading