From 63fd6568e4d148e9933100a7caef2c9377625821 Mon Sep 17 00:00:00 2001 From: Sasa Junuzovic <44276455+microsasa@users.noreply.github.com> Date: Thu, 9 Apr 2026 03:54:30 -0700 Subject: [PATCH 1/2] docs: add _fs_utils.py to architecture Components table and enforce completeness - Add _fs_utils.py row to the ### Components table in architecture.md - Add test_components_table_lists_all_modules to test_docs.py that enumerates all src/copilot_usage/*.py modules and asserts each one appears in the Components table Closes #881 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/copilot_usage/docs/architecture.md | 1 + tests/test_docs.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/copilot_usage/docs/architecture.md b/src/copilot_usage/docs/architecture.md index 689586a1..d495dee0 100644 --- a/src/copilot_usage/docs/architecture.md +++ b/src/copilot_usage/docs/architecture.md @@ -39,6 +39,7 @@ Monorepo containing Python CLI utilities that share tooling, CI, and common depe | `report.py` | Rich-formatted terminal output — summary tables (with Model Calls and User Msgs columns), live view, premium request breakdown. Shows raw counts and `~`-prefixed premium cost estimates for live/active sessions; historical post-shutdown views display exact API-provided numbers. | | `render_detail.py` | Session detail rendering — extracted from report.py. Displays event timeline, per-event metadata, and session-level aggregates. | | `_formatting.py` | Shared formatting utilities — `format_duration()` and `format_tokens()` with doctest-verified examples. Used by report.py and render_detail.py. | +| `_fs_utils.py` | Shared filesystem/caching utilities — `lru_insert` (LRU eviction for module-level `OrderedDict` caches) and `safe_file_identity` (returns `(mtime_ns, size)` for robust cache-invalidation; returns `None` on any `OSError`). Used by `parser.py` and `vscode_parser.py`. | | `pricing.py` | Model pricing registry — multiplier lookup, tier categorization. Multipliers are used for `~`-prefixed cost estimates in live/active views (`render_live_sessions`, `render_cost_view`); historical post-shutdown views use exact API-provided numbers exclusively. | | `logging_config.py` | Loguru setup — stderr warnings only, no file output. Uses a `_PatcherRecord` TypedDict to type-check the emoji-injection patcher without importing the unresolvable `loguru.Record` type at runtime. Called once from CLI entry point. | | `vscode_parser.py` | VS Code Copilot Chat log parser — discovers log files per platform (macOS/Windows/Linux), parses `ccreq:` lines with regex, aggregates into `VSCodeLogSummary`. | diff --git a/tests/test_docs.py b/tests/test_docs.py index f15bf17b..e2f4c6f2 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -145,6 +145,21 @@ def test_since_last_shutdown_documents_premium_cost_estimate() -> None: ) +def test_components_table_lists_all_modules() -> None: + """Every .py module in src/copilot_usage/ (excluding __init__.py and the + docs/ subdirectory) must appear in the ### Components table in + architecture.md.""" + pkg_dir = Path(__file__).parents[1] / "src" / "copilot_usage" + on_disk = {p.name for p in pkg_dir.glob("*.py") if p.name != "__init__.py"} + # Extract backtick-quoted module names from table rows. + in_table = set(re.findall(r"^\|\s*`([^`]+\.py)`\s*\|", _ARCH_MD, re.MULTILINE)) + missing = on_disk - in_table + assert not missing, ( + f"Modules missing from the ### Components table in " + f"architecture.md: {sorted(missing)}" + ) + + def test_architecture_detect_resume_lists_all_indicators() -> None: """The _detect_resume() description in architecture.md must mention the three true resume indicators and the separately-tracked turn_start event.""" From 7fb99866e1d2dabd061cc164475841245d08d732 Mon Sep 17 00:00:00 2001 From: Sasa Junuzovic <44276455+microsasa@users.noreply.github.com> Date: Thu, 9 Apr 2026 04:02:22 -0700 Subject: [PATCH 2/2] fix: address review comments Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/test_docs.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/test_docs.py b/tests/test_docs.py index e2f4c6f2..41379ca8 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -151,8 +151,19 @@ def test_components_table_lists_all_modules() -> None: architecture.md.""" pkg_dir = Path(__file__).parents[1] / "src" / "copilot_usage" on_disk = {p.name for p in pkg_dir.glob("*.py") if p.name != "__init__.py"} - # Extract backtick-quoted module names from table rows. - in_table = set(re.findall(r"^\|\s*`([^`]+\.py)`\s*\|", _ARCH_MD, re.MULTILINE)) + components_section_match = re.search( + r"^###\s+Components\b.*?(?=^#{1,6}\s+|\Z)", + _ARCH_MD, + re.MULTILINE | re.DOTALL, + ) + assert components_section_match, ( + "Could not find the '### Components' section in architecture.md" + ) + components_section = components_section_match.group(0) + # Extract backtick-quoted module names from rows in the Components table only. + in_table = set( + re.findall(r"^\|\s*`([^`]+\.py)`\s*\|", components_section, re.MULTILINE) + ) missing = on_disk - in_table assert not missing, ( f"Modules missing from the ### Components table in "