feat(arch): get_architecture single-call overview — closes #19#28
Merged
Conversation
added 4 commits
June 28, 2026 06:09
New engine module orchestrating existing engines (framework_detect, entrypoints_engine, apimap_engine, graph_model) into a single compact codebase overview payload. Addresses issue #19. Public API: - get_architecture(workspace, lite=False) -> dict Pipeline: - _compute_languages: three-tier resolution (fresh scan_result's files_scanned -> .codelens/summary.json -> cheap stat-only extension walk). Scan buckets collapsed to canonical names (js_backend + js_frontend -> javascript). - _compute_frameworks: wraps framework_detect.detect_frameworks. - _compute_entry_points: wraps entrypoints_engine.map_entrypoints, dedupes by file path, prioritises main/handler/cli types (top 10). - _compute_packages: scans src/, app/, lib/, packages/, server/, internal/ for immediate subdirs that contain source files (top 20). - _compute_routes: wraps apimap_engine.map_api_routes, normalises to {method, path, handler} (top 20). - _compute_hotspots: single SQL round-trip against graph_edges JOIN graph_nodes GROUP BY file ORDER BY count DESC LIMIT 5. Killer feature of the new graph model: files ranked by total incoming CALLS edges. - _compute_total_symbols: graph_stats(db_path).nodes. Caching: - First call writes .codelens/architecture_cache.json with timestamp. - Subsequent calls return the cache as long as .codelens/codelens.db mtime hasn't advanced (i.e. scan hasn't been re-run). - Lite and full payloads have different shapes -- the cache won't serve the wrong shape even when the db is unchanged. Auto-scan: - If .codelens/codelens.db doesn't exist or graph tables are empty when architecture is called, the engine runs cmd_scan first. This makes the tool self-sufficient for the issue #19 use-case ('agent starts on an unfamiliar codebase'). Payload shape: - Architecture-specific fields nested inside a 'stats' dict so they survive the MCP _normalize_to_ai formatter (which preserves stats as-is but drops unknown top-level keys). CLI consumers see the same shape. Adrs field is an empty list placeholder (ADR feature is issue #16, Phase 3).
CLI command (scripts/commands/architecture.py):
- Auto-registered via commands/__init__.py (no manual registration needed).
- Flags: --lite (omit routes/packages/hotspots for <1k token orientation),
--no-cache (force rebuild by removing architecture_cache.json).
- Wraps architecture_engine.get_architecture(workspace, lite=lite).
MCP tool (added to _TOOL_DEFINITIONS in scripts/mcp_server.py):
- Tool name: codelens_architecture
- Schema: {workspace: string} required; {format: string, lite: boolean}
optional.
- Description documents the issue #19 use-case and the --lite flag for
<1k token orientation mode.
- Result cached in .codelens/architecture_cache.json and invalidated on
re-scan.
The MCP _execute_command path runs _normalize_to_ai on every command
result. The architecture_engine nests all architecture fields inside a
'stats' dict so they survive normalization intact -- agents calling
codelens_architecture get the full overview, not just an empty
{stats:{}, items:[]} shell.
No other changes to mcp_server.py -- only the architecture entry is
added to _TOOL_DEFINITIONS, in line with the parallel-worker file
ownership agreement (2-a owns the compact-format changes).
24 test cases across 7 test classes covering all eight spec verification points from issue #19: TestArchitectureBasic (2 tests): - test_returns_ok_status: architecture returns status=ok on scanned clean_app. - test_auto_scans_on_fresh_workspace: auto-scan populates db + graph on a workspace with no .codelens/ directory. TestArchitectureFields (9 tests): - test_payload_has_all_required_fields: every issue #19 field present in stats (languages, frameworks, entry_points, packages, routes, hotspots, total_symbols, adrs). - Per-field type/shape checks (dict of counts, list of paths, list of {method,path,handler} dicts, etc). - test_adrs_is_empty_list_placeholder: confirms ADR placeholder shape. - test_total_symbols_is_int: confirms graph_stats().nodes is used. TestArchitectureLiteMode (2 tests): - test_lite_omits_routes_packages_hotspots: lite mode shape. - test_lite_keeps_core_fields: languages/frameworks/entry_points/ total_symbols still present in lite mode. TestArchitectureHotspots (3 tests): - test_hotspots_sorted_by_dependents_desc: parses '(N dependents)' and verifies descending sort. - test_hotspots_match_graph_query: independent SQL query returns the same file set as the engine (proves the graph model is the source). - test_hotspots_are_distinct_files: no duplicate file paths (group-by-file SQL contract). TestArchitectureCaching (4 tests): - test_cache_file_created_on_first_call: .codelens/architecture_cache.json appears after first call. - test_cache_reused_on_second_call: second call returns cached=True and the cache file mtime is unchanged. - test_cache_invalidated_after_rescan: re-running cmd_scan makes the next architecture call rebuild (cached=False). - test_lite_and_full_caches_not_shared: requesting lite after full (or vice versa) rebuilds because the payload shapes differ. TestArchitectureMCPTool (2 tests): - test_mcp_tool_listed: codelens_architecture is in _TOOL_DEFINITIONS with workspace (required) and lite (optional) parameters. - test_mcp_tool_returns_full_architecture_via_stats: end-to-end MCP tools/call returns the full architecture data inside stats (verifies the stats-nesting workaround for _normalize_to_ai). TestArchitectureTokenBudget (2 tests): - test_lite_payload_under_4000_bytes: raw --lite engine payload stays under 4000 bytes (~1k tokens). - test_lite_mcp_response_under_4000_bytes: MCP-normalised --lite response stays under 4000 bytes. All 24 tests pass. Uses two fixtures: scanned_clean_app (full scan done before architecture call) and fresh_clean_app (no scan -- tests auto-scan path).
README.md: - Add 'architecture' to the 'Architecture & Understanding (P1)' command table with description and flag hints (--lite, --no-cache). SKILL-QUICK.md: - Add 'architecture [--lite] [--no-cache]' to the Navigation category (10 -> 11 commands). - Update the trigger map entry for 'project overview' from 'summary or handbook' to 'architecture --lite (single call, <1k tokens) or summary / handbook (deeper)'. CHANGELOG.md: - Add new '### get_architecture -- single-call codebase overview (issue #19)' section under [8.2.0] Unreleased. - Document the new architecture_engine.py module, CLI command, MCP tool, and test suite. - Document design decisions (stats-nesting, adrs placeholder, auto-scan, file-level hotspots). - Include token budget verification measurements from clean_app fixture. references/agent-integration.md: - Update the Codebase Understanding intent-to-tool map: 'How does this app work?' now starts with 'architecture --lite' before drilling into entrypoints/api-map/state-map/outline. - Add new entries: 'Give me a codebase overview' -> architecture --lite, 'What files have the most dependents?' -> architecture (hotspots field uses the graph model). - Add 'overview, orient, unfamiliar, codebase summary, what is this project' to the keyword detection matrix mapping to architecture --lite. Only additive changes to shared docs -- no rewrites of existing content, in line with the parallel-worker file ownership agreement.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Implements issue #19 —
get_architecturesingle-call codebase overview for AI agents.Orientation on an unfamiliar codebase previously required 4-6 chained commands (scan → list → detect → entrypoints → api-map → read entry files), burning 10-20k tokens before any real work started. This PR collapses that into a single
architectureCLI command +codelens_architectureMCP tool returning a compact overview: languages, frameworks, entry points, packages, top routes, graph hotspots, total symbol count, and anadrsplaceholder (ADR feature is issue #16, Phase 3).Files Touched
Created:
scripts/architecture_engine.py(677 lines) — engine module orchestrating framework_detect, entrypoints_engine, apimap_engine, and the graph_model hotspots query. Includes caching layer with scan-mtime invalidation.scripts/commands/architecture.py(52 lines) — CLI command auto-registered viacommands/__init__.py. Flags:--lite,--no-cache.tests/test_architecture.py(533 lines) — 24 test cases across 7 test classes.Modified (additive only — coordinated with parallel workers 2-a and 2-c):
scripts/mcp_server.py— addedarchitectureentry to_TOOL_DEFINITIONSonly (no other changes; 2-a owns compact-format changes in this file).README.md— addedarchitectureto the Architecture & Understanding command table.SKILL-QUICK.md— addedarchitecture [--lite] [--no-cache]to Navigation category (10 → 11); updated trigger map entry for "project overview".CHANGELOG.md— added new### get_architecturesection under[8.2.0]Unreleased.references/agent-integration.md— addedarchitectureto intent-to-tool map + keyword detection matrix.Test Results
All 24 architecture tests pass. Breakdown:
Broader suite (no regressions):
The 4 failures are pre-existing in
test_hybrid_engine.py(confidence-field assertions onmain, not caused by this PR — verified in worklog Task 1).Token Size Measurement
Measured on the
clean_appfixture (7 python files + 1 js file, 31 graph nodes, 97 edges):--literaw engine payload--liteMCP-normalised responseAll well under the 1k-token target from the issue spec.
Verification:
architectureworks on clean_app fixtureVerification: hotspots use the graph model
The
_compute_hotspotsfunction issues a single SQL round-trip:On
clean_appthis returns:The test
test_hotspots_match_graph_queryindependently re-runs this SQL and verifies the file set matches. This is the killer feature of the new graph model (PR #24, issue #8): file-level blast-radius surfaced in one call.Design Decisions Beyond BOS Spec
Architecture-specific fields nested inside
stats— The MCP_normalize_to_aiformatter preservesstatsas-is but drops unknown top-level keys. To deliver the full architecture data through MCP without modifying the shared formatter (which would collide with parallel worker 2-a's compact-format changes), all architecture fields are nested insidestats. CLI consumers see the same shape. Documented in CHANGELOG andarchitecture_engine.get_architecturedocstring.File-level hotspots (not per-symbol) — The SQL query groups by
gn.file, notge.target_id, so each hotspot is a distinct file with its total blast radius (sum of incoming CALLS edges across all symbols in that file). Matches the issue spec example"src/models/user.py (47 dependents)"more closely than per-symbol rows would.Three-tier language resolution — When
architectureauto-scans, the scan_result'sfiles_scannedis used directly (no re-walk). When scan was done externally (e.g. via CLI),.codelens/summary.jsonis read. If neither is available, a cheap stat-only extension-counting walk is used as a last-resort fallback (no file parsing, justos.walk+os.path.splitext). This honours the BOS spec "reuse existing logic, don't re-walk files" while remaining robust to all entry points.Auto-scan on fresh workspace — If
.codelens/codelens.dbdoesn't exist or graph tables are empty whenarchitectureis called, the engine runscmd_scanfirst. This makes the tool self-sufficient for the issue [FEATURE]get_architecture— single-call codebase overview for agents #19 use-case ("agent starts on an unfamiliar codebase").Cache shape isolation — Lite and full payloads have different shapes (lite omits routes/packages/hotspots). The cache won't serve the wrong shape even when the db mtime is unchanged — requesting
--liteafter--full(or vice versa) forces a rebuild.Commits
4 incremental commits:
feat(arch): add architecture_engine.py with overview aggregationfeat(cmd): add architecture command + codelens_architecture MCP tooltest(arch): add architecture command + caching testsdocs(arch): update README, SKILL-QUICK, CHANGELOG, agent-integrationCloses #19.