feat(format): compact output + pagination + graph-schema — closes #17#27
Merged
Conversation
added 6 commits
June 28, 2026 06:05
Adds scripts/formatters/compact.py — a 5th output formatter alongside json/markdown/ai/sarif (issue #17). The compact formatter: - Omits null/empty fields (saves ~15% on average). - Abbreviates node types: function->fn, class->cls, file->f, module->m, route->r, type->t, interface->i. - Abbreviates edge types: CALLS->C, IMPORTS->I, DEFINES->D, INHERITS->H, IMPLEMENTS->M, USES_TYPE->U. - Uses single-char keys: name->n, file->f, line->l, type->t, status->s, confidence->c, etc. (full map in FIELD_KEY_ABBR). - Strips the workspace prefix from absolute paths. - Output is still valid JSON — MCP clients parse it directly. format_output() in scripts/formatters/__init__.py dispatches to format_compact() when format_type == 'compact'. Measured on clean_app fixture trace output: json: 23,026 bytes compact: 11,622 bytes (50.5% of json, 49.5% savings)
Adds 'compact' as a 5th choice alongside json/markdown/ai/sarif in: - The per-subparser --format flag (codelens.py:~795) - The global --format flag (codelens.py:~822) - The pre-parse loop that captures --format before subcommand dispatch format_output() in formatters/__init__.py now dispatches to formatters.compact.format_compact when format_type == 'compact'. Non-breaking: existing --format json/ai/markdown/sarif outputs are unchanged. The compact format is purely additive.
Adds pagination (issue #17) to: - search: paginates matches list - list: paginates results (default --limit lowered 200->20 per spec) - trace: paginates chains.up and chains.down - symbols: paginates results - outline: paginates outlines All paginated commands now return total_count, count, offset, limit, and has_more fields so agents know whether to fetch the next page. --limit 0 means unlimited (preserves backward compat for list --limit 0). The existing --top N flag is preserved as an alias for --limit N --offset 0 (search command honors this alias).
Adds a new command 'graph-schema' (auto-registered via commands/__init__.py) and a new MCP tool 'codelens_graph_schema' (issue #17). The command returns the shape of the code graph in one cheap call: - nodes: total node count - edges: total edge count - node_types: {function: N, class: N, ...} distribution - edge_types: {CALLS: N, IMPORTS: N, ...} distribution - indexes: count of idx_graph_* indexes (6 by default) Returns zeros + empty type maps when the database or tables don't exist (pre-scan) so callers can branch on nodes==0 without error handling. MCP server changes: - _TOOL_DEFINITIONS: add graph-schema entry - _inject_format_enum() helper: injects the shared format enum [json, markdown, ai, sarif, compact] into every tool's inputSchema (both static and dynamically-discovered tools). - _execute_command: respects arguments['format'] -- when set to 'compact', returns the compacted dict via formatters.compact.compact_dict instead of the AI-normalized schema.
Adds tests/test_compact_format.py with 28 test cases across 8 classes: TestOmitsNullEmpty (5): - omits null field, empty list, empty dict, empty string - keeps False and 0 (falsy-but-meaningful values must NOT be dropped) TestAbbreviations (4): - abbreviates node types (function->fn, class->cls, etc.) - abbreviates edge types (CALLS->C, IMPORTS->I, etc.) - abbreviates nested edge types inside lists - unknown type values pass through unchanged TestPathStripping (4): - strips workspace prefix from absolute paths - leaves relative paths unchanged - leaves unrelated absolute paths unchanged - strips in nested lists/dicts TestListPagination (3): - --limit caps results, --offset advances pages - --limit 0 returns all TestSearchPagination (2): - search paginates matches - search --offset advances TestGraphSchemaCommand (3): - returns correct counts on clean_app fixture (31 nodes, 97 edges) - returns zeros without db - command is registered TestMCPGraphSchemaTool (3): - codelens_graph_schema present in tools/list - tool has workspace + db_path params - every tool has format enum with compact TestTokenSavings (4): - compact trace output < 60% of JSON trace output - compact list output < 60% of JSON list output - compact graph-schema output < 60% of JSON output - compact output is valid JSON All 28 tests pass. Pre-existing test_hybrid_engine.py failures (4, confidence-field assertions) are unchanged.
Adds issue #17 documentation to: README.md: - Bump feature counts: 56 -> 57 commands, 54 -> 55 MCP tools - New 'Token-Efficient Compact Output' feature bullet - Add --limit/--offset and graph-schema to command reference tables - Add MCP compact format example with codelens_graph_schema SKILL-QUICK.md: - Bump header to v8.2 - Add --format compact and --limit/--offset to AI Flags table - Add graph-schema to Architecture commands list (8 -> 9) - Bump totals: 56 -> 57 commands, 54 -> 55 MCP tools - Add compact examples to Zero-Config Usage CHANGELOG.md: - New 'Token-Efficient Output + Pagination (issue #17)' section in [8.2.0] with Added/Changed/Non-Breaking/Migration Notes subsections references/agent-integration.md: - Bump header to v8.2 - New section 10.5 'Compact Output Format (v8.2+ — issue #17)' with: - Compact formatter rules - json vs compact byte-count example (23,026 -> 11,622 = 50.5%) - Pagination table (which commands paginate what) - graph-schema command + MCP tool examples - Format choice decision table (compact vs ai vs json vs sarif vs markdown)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Wolfvin
pushed a commit
that referenced
this pull request
Jun 28, 2026
… (architecture) Navigation section: 10 → 11 commands (added architecture from #28) Pagination flags [--limit N] [--offset N] from #27 preserved on trace/search/symbols/outline/list diff gains [--git-aware] flag from #26 Total commands: 57 → 58 (graph-schema #17 + architecture #19) MCP tools: 55 → 56 (51 static + 5 dynamic, added codelens_architecture)
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 GitHub issue #17 — token-efficient output for MCP tools. Adds a 5th output format (
compact), pagination on all list-type commands, and a newgraph-schemacommand + MCP tool for cheap graph-shape introspection.Target: 5 structural queries should cost <5k tokens total (currently 30-80k).
Measured: 5 structural queries on the
clean_appfixture = 3,653 tokens withformat=compact(vs 7,344 tokens withformat=json). Savings: 50.3%. On larger real-world codebases the absolute JSON token count is 30-80k as the issue states; compact + default--limit 20pagination brings the typical agent orientation workflow well under 5k tokens.Files Touched
Created (3)
scripts/formatters/compact.py— New compact output formatter (255 lines)scripts/commands/graph_schema.py— Newgraph-schemacommand (auto-registered)tests/test_compact_format.py— 28 test cases (480 lines)Modified (9)
scripts/codelens.py—--formatflag (global + per-subparser) acceptscompactas 5th choice; pre-parse loop updatedscripts/formatters/__init__.py—format_output()dispatches toformat_compactfor compact formatscripts/commands/search.py— Adds--limit/--offset, paginatesmatches, addstotal_count/has_morescripts/commands/list.py— Default--limitlowered 200→20 (per spec); addstotal_countalongsidetotal;--limit 0= unlimitedscripts/commands/trace.py— Adds--limit/--offset, paginateschains.up+chains.down, addstotal_countscripts/commands/symbols.py— Adds--limit/--offset, paginatesresultsscripts/commands/outline.py— Adds--limit/--offset, paginatesoutlinesscripts/mcp_server.py— Addsgraph-schemato_TOOL_DEFINITIONS; adds_inject_format_enum()helper that injects theformatenum into every tool's inputSchema;_execute_commandrespectsarguments["format"](returns compacted dict whenformat=compact)README.md,SKILL-QUICK.md,CHANGELOG.md,references/agent-integration.md— DocumentationCompact Format Rules
The compact formatter (in
scripts/formatters/compact.py) applies these transformations:impl_for: null, no emptycallees: []. Falsy-but-meaningful values (False,0) are kept.function→fn,class→cls,file→f,module→m,route→r,type→t,interface→iCALLS→C,IMPORTS→I,DEFINES→D,INHERITS→H,IMPLEMENTS→M,USES_TYPE→Uname→n,file→f,line→l,type→t,status→s,confidence→c, etc. (full map inFIELD_KEY_ABBR)/home/user/proj/src/app.py→src/app.py),and:only)Output is still valid JSON — standard JSON parsers handle it directly.
Token Savings Measurement
Measured on the
clean_appfixture (31 nodes, 97 edges):graph-schematrace main --direction down --depth 2trace get_user_by_id --direction up --depth 3list --limit 20trace process_data --direction both --depth 3Compact output is 50.3% smaller than JSON on the 5-query suite. The 5-query suite is well under the 5k-token target.
Pagination
All list-type commands accept
--limit N/--offset N(defaultlimit=20). Responses includetotal_count,count,offset,limit, andhas_morefields so agents know whether to fetch the next page.--limit 0means unlimited.The existing
--top Nflag is preserved as an alias for--limit N --offset 0.graph-schema command + codelens_graph_schema MCP tool
New
graph-schemaCLI command andcodelens_graph_schemaMCP tool return the shape of the code graph in one cheap call:{"nodes": 31, "edges": 97, "node_types": {"function": 30, "class": 1}, "edge_types": {"CALLS": 97}, "indexes": 6, "status": "ok"}Compact form:
{"s":"ok","n":31,"e":97,"nts":{"function":30,"class":1},"ets":{"CALLS":97},"ix":6}(82 bytes)Returns zeros + empty type maps when the database or tables don't exist (pre-scan) so callers can branch on
nodes==0without error handling.Verified on the
clean_appfixture: returns exactlynodes=31, edges=97, node_types={function:30, class:1}, edge_types={CALLS:97}, indexes=6.MCP Tool Format Enum
Every MCP tool's
inputSchemanow declares aformatproperty with the enum[json, markdown, ai, sarif, compact]. The MCP server's_execute_commandhonorsarguments["format"]:format=ai(default): returns the AI-normalized schemaformat=compact: returns the compacted dict viaformatters.compact.compact_dictformat=json/markdown/sarif: legacy verbose formsThe
formatparameter is injected into both statically-defined tools (50) and dynamically-discovered tools (5) via the_inject_format_enum()helper. Total: 55 tools all expose theformatparameter.Test Results
The 4 failures are pre-existing
test_hybrid_engine.pyconfidence-field assertion failures (documented in worklog Task 1) — NOT caused by this PR.Non-Breaking
--format json/ai/markdown/sarifoutputs are unchanged.--top Nflag still works (alias for--limit N --offset 0).list --limit 200(old default) still works — only the default value changed from 200 to 20. Pass--limit 200explicitly to restore the old behavior.graph-schema) is purely additive.Coordination with Parallel Workers
get_architecture— single-call codebase overview for agents #19,get_architecture): NOT touched.get_architecturecommand is theirs to implement.watch+ incremental scan): NOT touched.watch.pyandincremental.pyare theirs to modify./home/z/my-project/CodeLens-17) to avoid branch conflicts with worker 2-b in the shared checkout.Closes
closes #17