suitable-loop 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- suitable_loop-0.1.0/.claude/CLAUDE.md +41 -0
- suitable_loop-0.1.0/.claude/commands/debug-error.md +15 -0
- suitable_loop-0.1.0/.claude/commands/health-check.md +23 -0
- suitable_loop-0.1.0/.claude/commands/impact-check.md +16 -0
- suitable_loop-0.1.0/.claude/commands/onboard.md +16 -0
- suitable_loop-0.1.0/.claude/commands/risk-report.md +12 -0
- suitable_loop-0.1.0/.claude/commands/trace-function.md +17 -0
- suitable_loop-0.1.0/.github/workflows/publish.yml +27 -0
- suitable_loop-0.1.0/.gitignore +7 -0
- suitable_loop-0.1.0/PKG-INFO +12 -0
- suitable_loop-0.1.0/README.md +149 -0
- suitable_loop-0.1.0/pyproject.toml +24 -0
- suitable_loop-0.1.0/suitable_loop/__init__.py +3 -0
- suitable_loop-0.1.0/suitable_loop/__main__.py +5 -0
- suitable_loop-0.1.0/suitable_loop/analyzers/__init__.py +1 -0
- suitable_loop-0.1.0/suitable_loop/analyzers/code_analyzer.py +652 -0
- suitable_loop-0.1.0/suitable_loop/analyzers/git_analyzer.py +510 -0
- suitable_loop-0.1.0/suitable_loop/analyzers/log_analyzer.py +663 -0
- suitable_loop-0.1.0/suitable_loop/config.py +60 -0
- suitable_loop-0.1.0/suitable_loop/db.py +497 -0
- suitable_loop-0.1.0/suitable_loop/graph/__init__.py +1 -0
- suitable_loop-0.1.0/suitable_loop/graph/engine.py +341 -0
- suitable_loop-0.1.0/suitable_loop/models.py +131 -0
- suitable_loop-0.1.0/suitable_loop/server.py +46 -0
- suitable_loop-0.1.0/suitable_loop/tools/__init__.py +1 -0
- suitable_loop-0.1.0/suitable_loop/tools/code_tools.py +104 -0
- suitable_loop-0.1.0/suitable_loop/tools/git_tools.py +52 -0
- suitable_loop-0.1.0/suitable_loop/tools/log_tools.py +53 -0
- suitable_loop-0.1.0/suitable_loop/tools/util_tools.py +49 -0
- suitable_loop-0.1.0/tests/__init__.py +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Suitable Loop
|
|
2
|
+
|
|
3
|
+
This is a local MCP server for production engineering. It indexes Python codebases and exposes analysis tools.
|
|
4
|
+
|
|
5
|
+
## Available slash commands
|
|
6
|
+
|
|
7
|
+
- `/onboard` — Index a codebase and get a full orientation (structure, hotspots, complexity, blast radius)
|
|
8
|
+
- `/risk-report` — Analyze recent commits by risk score, find hotspots, get review recommendations
|
|
9
|
+
- `/impact-check <file>` — Before changing a file, see its blast radius, callers, and what could break
|
|
10
|
+
- `/debug-error <error text or log path>` — Correlate an error/traceback to source code paths
|
|
11
|
+
- `/health-check` — Full codebase health assessment with actionable recommendations
|
|
12
|
+
- `/trace-function <name>` — Map a function's callers, callees, and role in the system
|
|
13
|
+
|
|
14
|
+
## MCP tools reference
|
|
15
|
+
|
|
16
|
+
### Indexing
|
|
17
|
+
- `index_codebase(path, force)` — Parse and index a Python project
|
|
18
|
+
- `reindex(path)` — Incremental re-index (only changed files)
|
|
19
|
+
- `status()` — Server status and entity counts
|
|
20
|
+
|
|
21
|
+
### Code analysis
|
|
22
|
+
- `query_entity(name)` — Look up any function/class/file with relationships
|
|
23
|
+
- `find_callers(function_name)` — Who calls this function?
|
|
24
|
+
- `find_callees(function_name)` — What does this function call?
|
|
25
|
+
- `dependency_tree(file_path, depth)` — Import tree for a file
|
|
26
|
+
- `search_code(query)` — Full-text search across indexed code
|
|
27
|
+
- `complexity_report(top_n)` — Most complex functions
|
|
28
|
+
- `codebase_summary()` — High-level stats
|
|
29
|
+
|
|
30
|
+
### Git analysis
|
|
31
|
+
- `analyze_recent_changes(repo_path, n_commits)` — Score commits by risk
|
|
32
|
+
- `analyze_commit(repo_path, sha)` — Deep-dive a single commit
|
|
33
|
+
- `hotspot_report(repo_path, n_commits)` — Files with high churn x high dependencies
|
|
34
|
+
- `blast_radius(file_path)` — Transitive impact of changing a file
|
|
35
|
+
|
|
36
|
+
### Log analysis
|
|
37
|
+
- `ingest_logs(path)` — Parse log files, extract and group errors
|
|
38
|
+
- `get_error_groups(limit)` — List error groups by frequency
|
|
39
|
+
- `error_detail(error_group_id)` — Full error detail with code links
|
|
40
|
+
- `correlate_error(error_text)` — Map raw error text to code paths
|
|
41
|
+
- `error_timeline(days)` — Error frequency over time
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Help me investigate this error: $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Steps:
|
|
4
|
+
1. Use `correlate_error` with the provided error text to find matching code paths
|
|
5
|
+
2. If a log file path was provided instead, use `ingest_logs` first, then `get_error_groups`
|
|
6
|
+
3. For each relevant error group, use `error_detail` to get full tracebacks and affected functions
|
|
7
|
+
4. Use `query_entity` on the key functions in the stack trace to understand their role
|
|
8
|
+
5. Use `find_callers` on the originating function to see all code paths that lead to it
|
|
9
|
+
|
|
10
|
+
Then give me:
|
|
11
|
+
- Where the error originates (file, function, line)
|
|
12
|
+
- The full call chain leading to the error
|
|
13
|
+
- How many times this error has occurred (if logs were ingested)
|
|
14
|
+
- All code paths that could trigger this error
|
|
15
|
+
- Suggested investigation steps or likely root cause
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Run a full codebase health check using Suitable Loop.
|
|
2
|
+
|
|
3
|
+
Steps:
|
|
4
|
+
1. Use `reindex` on the current project to ensure data is fresh
|
|
5
|
+
2. Use `codebase_summary` for overall stats
|
|
6
|
+
3. Use `complexity_report` (top 15) to find overly complex code
|
|
7
|
+
4. Use `hotspot_report` on this repo (last 100 commits) to find high-risk areas
|
|
8
|
+
5. Use `blast_radius` on the top 5 most-depended-upon files
|
|
9
|
+
6. Use `analyze_recent_changes` (last 20 commits) to check recent risk trends
|
|
10
|
+
|
|
11
|
+
Produce a health report with these sections:
|
|
12
|
+
|
|
13
|
+
**Codebase overview** — size, structure, key metrics
|
|
14
|
+
|
|
15
|
+
**Complexity hotspots** — functions above complexity 15, with recommendations to simplify
|
|
16
|
+
|
|
17
|
+
**Dependency risks** — files with the largest blast radius, coupling concerns
|
|
18
|
+
|
|
19
|
+
**Change hotspots** — files that change too often relative to how many things depend on them
|
|
20
|
+
|
|
21
|
+
**Recent risk trend** — are recent commits getting riskier or safer?
|
|
22
|
+
|
|
23
|
+
**Recommendations** — top 3 actionable items to improve codebase health
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
I'm about to change the file: $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Before I make changes, analyze the impact.
|
|
4
|
+
|
|
5
|
+
Steps:
|
|
6
|
+
1. Use `blast_radius` on the specified file to find all transitively affected files
|
|
7
|
+
2. Use `query_entity` on key functions/classes in the file to understand their relationships
|
|
8
|
+
3. Use `find_callers` on the most important functions to see what depends on them
|
|
9
|
+
4. Use `dependency_tree` on the file to see its import chain
|
|
10
|
+
|
|
11
|
+
Then give me:
|
|
12
|
+
- The blast radius: how many files are affected if this file breaks
|
|
13
|
+
- A list of the affected files, grouped by app/module
|
|
14
|
+
- The key functions in this file and who calls them
|
|
15
|
+
- What this file depends on (its imports)
|
|
16
|
+
- Practical advice: what to test after making changes, what could break, any coupling concerns
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Index this codebase with Suitable Loop and give me a complete orientation.
|
|
2
|
+
|
|
3
|
+
Steps:
|
|
4
|
+
1. Use `index_codebase` to index the current project directory (use force=true if already indexed)
|
|
5
|
+
2. Use `codebase_summary` to get high-level stats
|
|
6
|
+
3. Use `complexity_report` (top 10) to find the most complex code
|
|
7
|
+
4. Use `hotspot_report` on this repo to find high-risk areas
|
|
8
|
+
5. Check `blast_radius` on the top 3 hotspot files
|
|
9
|
+
|
|
10
|
+
Then give me a concise briefing covering:
|
|
11
|
+
- Project size and structure (files, functions, classes)
|
|
12
|
+
- The most connected/central modules
|
|
13
|
+
- The most complex functions (and why they matter)
|
|
14
|
+
- The highest-risk hotspots (high churn + high dependency count)
|
|
15
|
+
- Which files have the largest blast radius
|
|
16
|
+
- Recommendations for where to focus testing and review
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Analyze recent git activity and produce a risk report.
|
|
2
|
+
|
|
3
|
+
Steps:
|
|
4
|
+
1. Use `analyze_recent_changes` on this repo (last 30 commits)
|
|
5
|
+
2. For the top 3 riskiest commits, use `analyze_commit` to get detailed breakdowns
|
|
6
|
+
3. Use `hotspot_report` on this repo to cross-reference with code hotspots
|
|
7
|
+
|
|
8
|
+
Then produce a report covering:
|
|
9
|
+
- Top 5 riskiest commits with their risk scores and key factors (complexity delta, blast radius, churn, lines changed)
|
|
10
|
+
- For each risky commit: what files were touched and why it's risky
|
|
11
|
+
- Current hotspots: files that change frequently AND are heavily depended upon
|
|
12
|
+
- Actionable recommendations: which changes deserve extra review, which areas need better test coverage
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Trace the function: $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Map out everything about this function and its role in the codebase.
|
|
4
|
+
|
|
5
|
+
Steps:
|
|
6
|
+
1. Use `query_entity` to get the function's details (signature, complexity, location)
|
|
7
|
+
2. Use `find_callers` to see everything that calls it
|
|
8
|
+
3. Use `find_callees` to see everything it calls
|
|
9
|
+
4. Use `blast_radius` on the file containing this function
|
|
10
|
+
5. Use `search_code` if the function name is ambiguous to find all matches
|
|
11
|
+
|
|
12
|
+
Then give me:
|
|
13
|
+
- Function signature, location, and complexity score
|
|
14
|
+
- Who calls this function (direct callers) — grouped by module
|
|
15
|
+
- What this function calls (direct callees)
|
|
16
|
+
- The blast radius of its containing file
|
|
17
|
+
- A visual call chain showing how this function fits into the broader system
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: astral-sh/setup-uv@v4
|
|
14
|
+
- run: uv sync --all-extras
|
|
15
|
+
- run: uv run pytest --no-header -q || true
|
|
16
|
+
|
|
17
|
+
publish:
|
|
18
|
+
needs: test
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
environment: pypi
|
|
21
|
+
permissions:
|
|
22
|
+
id-token: write
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: astral-sh/setup-uv@v4
|
|
26
|
+
- run: uv build
|
|
27
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: suitable-loop
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local production engineering platform — semantic code analysis, git risk scoring, and log correlation via MCP
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: gitpython>=3.1
|
|
7
|
+
Requires-Dist: mcp>=1.0.0
|
|
8
|
+
Requires-Dist: networkx>=3.0
|
|
9
|
+
Requires-Dist: radon>=6.0
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
12
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Suitable Loop
|
|
2
|
+
|
|
3
|
+
Local production engineering platform — semantic code analysis, git risk scoring, and log correlation via MCP.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
Suitable Loop indexes your Python codebase and exposes deep analysis through MCP tools that AI assistants can call:
|
|
8
|
+
|
|
9
|
+
- **Code Analysis** — AST-based parsing, function/class extraction, call graph construction, cyclomatic complexity
|
|
10
|
+
- **Git Risk Scoring** — Weighted risk scores per commit (complexity delta × blast radius × churn × size)
|
|
11
|
+
- **Log Correlation** — Parse logs, group errors by signature, map stack frames to indexed code
|
|
12
|
+
- **Dependency Graph** — NetworkX-powered call graphs, import trees, blast radius analysis
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### 1. Add MCP server to your project
|
|
17
|
+
|
|
18
|
+
Create `.mcp.json` in your project root:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"mcpServers": {
|
|
23
|
+
"suitable-loop": {
|
|
24
|
+
"command": "uvx",
|
|
25
|
+
"args": ["--from", "git+https://github.com/suitable-adventures/suitable-loop", "suitable-loop"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
That's it. `uvx` handles cloning, caching, and running automatically — no manual install needed.
|
|
32
|
+
|
|
33
|
+
> **Local development?** Point to a local checkout instead:
|
|
34
|
+
> ```json
|
|
35
|
+
> "args": ["--from", "/path/to/suitable-loop", "suitable-loop"]
|
|
36
|
+
> ```
|
|
37
|
+
|
|
38
|
+
### 2. Install slash commands (optional)
|
|
39
|
+
|
|
40
|
+
Copy the commands into your project for workflow shortcuts:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
mkdir -p .claude/commands
|
|
44
|
+
cp -r /path/to/suitable-loop/.claude/commands/* .claude/commands/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Restart Claude Code and start using it
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
/onboard # Get a full codebase orientation
|
|
51
|
+
/risk-report # Analyze recent commits by risk
|
|
52
|
+
/impact-check models.py # Check blast radius before changing a file
|
|
53
|
+
/debug-error "ConnectionResetError in db/pool.py"
|
|
54
|
+
/health-check # Full codebase health assessment
|
|
55
|
+
/trace-function my_function # Map a function's callers and callees
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Slash Commands
|
|
59
|
+
|
|
60
|
+
| Command | What it does |
|
|
61
|
+
|---------|-------------|
|
|
62
|
+
| `/onboard` | Index the codebase and produce a full orientation: structure, hotspots, complexity, blast radius |
|
|
63
|
+
| `/risk-report` | Score recent commits by risk, find hotspots, recommend where to focus review |
|
|
64
|
+
| `/impact-check <file>` | Before changing a file: blast radius, who calls what, what could break |
|
|
65
|
+
| `/debug-error <error or log path>` | Correlate an error/traceback to source code paths |
|
|
66
|
+
| `/health-check` | Full assessment: complexity, coupling, churn trends, actionable recommendations |
|
|
67
|
+
| `/trace-function <name>` | Map a function's callers, callees, complexity, and role in the system |
|
|
68
|
+
|
|
69
|
+
## MCP Tools
|
|
70
|
+
|
|
71
|
+
### Code Analysis
|
|
72
|
+
| Tool | Description |
|
|
73
|
+
|------|-------------|
|
|
74
|
+
| `index_codebase` | Index a Python project — parse AST, extract entities, build call graph |
|
|
75
|
+
| `query_entity` | Look up a function/class/file by name with all relationships |
|
|
76
|
+
| `find_callers` | Find all functions that call a given function |
|
|
77
|
+
| `find_callees` | Find all functions called by a given function |
|
|
78
|
+
| `dependency_tree` | Get import dependency tree for a file |
|
|
79
|
+
| `search_code` | Full-text search across indexed functions and classes |
|
|
80
|
+
| `complexity_report` | Top N most complex functions |
|
|
81
|
+
| `codebase_summary` | High-level stats and most-connected modules |
|
|
82
|
+
|
|
83
|
+
### Git Analysis
|
|
84
|
+
| Tool | Description |
|
|
85
|
+
|------|-------------|
|
|
86
|
+
| `analyze_recent_changes` | Score recent commits by risk |
|
|
87
|
+
| `analyze_commit` | Deep-dive a single commit |
|
|
88
|
+
| `hotspot_report` | Files with high churn × high dependency count |
|
|
89
|
+
| `blast_radius` | Transitive impact of changing a file |
|
|
90
|
+
|
|
91
|
+
### Log Analysis
|
|
92
|
+
| Tool | Description |
|
|
93
|
+
|------|-------------|
|
|
94
|
+
| `ingest_logs` | Parse log files, extract errors, group by signature |
|
|
95
|
+
| `get_error_groups` | List distinct error groups by frequency |
|
|
96
|
+
| `error_detail` | Full detail on an error group with code links |
|
|
97
|
+
| `correlate_error` | Map raw error text to code paths |
|
|
98
|
+
| `error_timeline` | Error frequency over time |
|
|
99
|
+
|
|
100
|
+
### Utility
|
|
101
|
+
| Tool | Description |
|
|
102
|
+
|------|-------------|
|
|
103
|
+
| `status` | Server status and entity counts |
|
|
104
|
+
| `reindex` | Incremental re-index (only changed files) |
|
|
105
|
+
|
|
106
|
+
## Architecture
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
suitable_loop/
|
|
110
|
+
├── __init__.py # Package root
|
|
111
|
+
├── __main__.py # Entry point (python -m suitable_loop)
|
|
112
|
+
├── server.py # MCP server setup (FastMCP) + main() entry point
|
|
113
|
+
├── config.py # Configuration dataclasses
|
|
114
|
+
├── models.py # Data models (entities, edges)
|
|
115
|
+
├── db.py # SQLite database layer
|
|
116
|
+
├── analyzers/
|
|
117
|
+
│ ├── code_analyzer.py # AST parsing, call resolution
|
|
118
|
+
│ ├── git_analyzer.py # Commit analysis, risk scoring
|
|
119
|
+
│ └── log_analyzer.py # Log parsing, error grouping
|
|
120
|
+
├── graph/
|
|
121
|
+
│ └── engine.py # NetworkX graph engine
|
|
122
|
+
└── tools/
|
|
123
|
+
├── code_tools.py # MCP code analysis tools
|
|
124
|
+
├── git_tools.py # MCP git analysis tools
|
|
125
|
+
├── log_tools.py # MCP log analysis tools
|
|
126
|
+
└── util_tools.py # MCP utility tools
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Configuration
|
|
130
|
+
|
|
131
|
+
Environment variables:
|
|
132
|
+
|
|
133
|
+
| Variable | Default | Description |
|
|
134
|
+
|----------|---------|-------------|
|
|
135
|
+
| `SUITABLE_LOOP_DB_PATH` | `~/.suitable-loop/suitable-loop.db` | SQLite database path |
|
|
136
|
+
| `SUITABLE_LOOP_LOG_LEVEL` | `INFO` | Logging level |
|
|
137
|
+
|
|
138
|
+
Default exclude patterns (files skipped during indexing):
|
|
139
|
+
- `.venv/`, `venv/`, `node_modules/`, `__pycache__/`, `migrations/`, `.git/`
|
|
140
|
+
|
|
141
|
+
## Development
|
|
142
|
+
|
|
143
|
+
For working on Suitable Loop itself:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
cd suitable-loop
|
|
147
|
+
uv venv && uv pip install -e ".[dev]"
|
|
148
|
+
uv run pytest
|
|
149
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "suitable-loop"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Local production engineering platform — semantic code analysis, git risk scoring, and log correlation via MCP"
|
|
5
|
+
requires-python = ">=3.11"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"mcp>=1.0.0",
|
|
8
|
+
"networkx>=3.0",
|
|
9
|
+
"gitpython>=3.1",
|
|
10
|
+
"radon>=6.0",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[project.optional-dependencies]
|
|
14
|
+
dev = [
|
|
15
|
+
"pytest>=8.0",
|
|
16
|
+
"pytest-asyncio>=0.23",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.scripts]
|
|
20
|
+
suitable-loop = "suitable_loop.server:main"
|
|
21
|
+
|
|
22
|
+
[build-system]
|
|
23
|
+
requires = ["hatchling"]
|
|
24
|
+
build-backend = "hatchling.build"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Suitable Loop analysis engines."""
|