feat: halstead metrics, maintainability index, and docs update#142
feat: halstead metrics, maintainability index, and docs update#142carlos-alm wants to merge 5 commits intomainfrom
Conversation
Add formal code health metrics per function: Halstead volume, difficulty,
effort, bugs estimate, LOC/SLOC, and the industry-standard Maintainability
Index (MI) normalized to 0-100 (Microsoft convention). MI below 20 flags
functions needing refactoring attention.
- DB migration v9: 14 new columns on function_complexity table
- HALSTEAD_RULES registry for JS/TS/TSX operator/operand classification
- computeHalsteadMetrics(), computeLOCMetrics(), computeMaintainabilityIndex()
- complexity command: MI column in default view, --health flag for full
Halstead view, --sort mi|volume|effort|bugs|loc options
- stats/context/explain commands surface MI per function
- MCP tool schema updated with new sort values and health property
- Config: maintainabilityIndex threshold { warn: 20, fail: null }
- 29 new tests (18 unit + 11 integration)
Impact: 16 functions changed, 30 affected
Impact: 16 functions changed, 30 affected
…sults Add offset/limit pagination to data functions so MCP clients get bounded results with metadata to request more, and CLI consumers can process results incrementally via NDJSON. - New src/paginate.js with paginate(), paginateResult(), MCP_DEFAULTS, MCP_MAX_LIMIT utilities - Pagination support in listFunctionsData, queryNameData, whereData, rolesData, listEntryPointsData - Export limiting for DOT/Mermaid (truncation comments) and JSON (edge pagination) - MCP tool schemas updated with limit/offset props and sensible defaults (e.g. list_functions: 100, query_function: 50) - CLI --limit, --offset, --ndjson flags on query, where, roles, flow - Programmatic API exports from index.js - 33 new integration tests covering all pagination scenarios Impact: 19 functions changed, 18 affected
The --above-threshold filter for maintainabilityIndex now requires MI > 0, consistent with the exceeds array logic that already guards against uncomputed rows from pre-migration databases. Impact: 1 functions changed, 4 affected Impact: 1 functions changed, 1 affected
Replace loose `!= null` checks with `typeof === 'number' && Number.isFinite()`
to prevent `Number("")`, `Number(null)`, and `Number(true)` from silently
coercing into valid SQL values. Add integration test verifying exceeds
arrays and summary.aboveWarn are correctly computed.
Addresses Greptile review feedback on #136.
Impact: 2 functions changed, 3 affected
Update README, CLAUDE.md, BACKLOG, titan-paradigm, recommended-practices, and CLI/MCP examples to reflect today's merged PRs: complexity metrics (#130/#139), Louvain community detection (#133/#134), and manifesto rule engine (#138). Updates MCP tool count from 21 to 24 (25 in multi-repo), marks backlog items 6/11/21/22 as done, and adds real CLI output examples.
Greptile SummaryThis PR adds comprehensive code health metrics and pagination to codegraph. The implementation is solid with thorough test coverage and consistent integration across all components. Major additions:
Documentation updates:
Note: Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
Start[codegraph build] --> Parse[Parse source files with tree-sitter]
Parse --> Compute[Compute complexity metrics]
Compute --> Halstead[Calculate Halstead metrics<br/>n1, n2, N1, N2, volume, difficulty, effort, bugs]
Compute --> LOC[Calculate LOC metrics<br/>loc, sloc, comment lines]
Halstead --> MI[Calculate Maintainability Index<br/>MI = f volume, cyclomatic, sloc, comments]
LOC --> MI
MI --> Store[Store in function_complexity table<br/>Migration 9: adds Halstead & MI columns]
Store --> Query[Query-time: codegraph complexity]
Query --> Paginate[Apply pagination<br/>limit, offset, hasMore]
Paginate --> Filter[Apply filters<br/>--above-threshold, --sort, --file]
Filter --> Format{Output format?}
Format -->|--health| Health[Display Halstead view<br/>Volume, Difficulty, Effort, Bugs, MI]
Format -->|default| Default[Display cognitive, cyclomatic, nesting, MI]
Format -->|--json| JSON[Return JSON with _pagination metadata]
Store --> MCP[MCP Server: complexity tool]
MCP --> MCPPaginate[Apply MCP defaults<br/>limit: 20, max: 1000]
MCPPaginate --> MCPOut[Return paginated results to AI agent]
Store --> OtherQueries[Other query functions<br/>queryName, where, listFunctions, etc.]
OtherQueries --> PaginateAll[Consistent pagination via paginateResult]
PaginateAll --> Export[Export: DOT, Mermaid, JSON<br/>Edge limiting with truncation notices]
Last reviewed commit: d5a322a |
| * @returns {{ items: any[], pagination?: { total: number, offset: number, limit: number, hasMore: boolean, returned: number } }} | ||
| */ | ||
| export function paginate(items, { limit, offset } = {}) { | ||
| if (limit === undefined && limit !== 0) { |
There was a problem hiding this comment.
logic error: && limit !== 0 should be removed or the operator should be ||
The condition currently checks if limit is undefined AND not zero, but when limit is undefined, the second check is always true and redundant. Based on the docstring ("When limit is undefined the input is returned unchanged"), this should just be:
| if (limit === undefined && limit !== 0) { | |
| if (limit === undefined) { |
or to handle null as well:
| if (limit === undefined && limit !== 0) { | |
| if (limit == null) { |
| * @returns {object} - Result with paginated field + `_pagination` (if active) | ||
| */ | ||
| export function paginateResult(result, field, { limit, offset } = {}) { | ||
| if (limit === undefined && limit !== 0) { |
There was a problem hiding this comment.
same logic error as line 31: && limit !== 0 is redundant and confusing
| if (limit === undefined && limit !== 0) { | |
| if (limit === undefined) { |
|
Addressed Greptile feedback: removed redundant |
Summary
codegraph complexitywith Halstead volume, difficulty, effort, estimated bugs, and MI per function. New--healthflag for full Halstead view,--sort mito rank by worst MI. Stored infunction_complexityDB tablepaginate.jshelpers for context-friendly output across CLI and MCPTest plan
npm testpassescodegraph complexity -Tshows cognitive, cyclomatic, nesting, MI columnscodegraph complexity --health -Tshows Halstead columns (volume, diff, effort, bugs, LOC, SLOC)codegraph complexity --sort mi -Tsorts ascending by MIcodegraph complexity --above-threshold -Tfilters to flagged functions only