debtpilot 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.
- debtpilot-0.1.0/PKG-INFO +143 -0
- debtpilot-0.1.0/README.md +113 -0
- debtpilot-0.1.0/debtpilot.egg-info/PKG-INFO +143 -0
- debtpilot-0.1.0/debtpilot.egg-info/SOURCES.txt +23 -0
- debtpilot-0.1.0/debtpilot.egg-info/dependency_links.txt +1 -0
- debtpilot-0.1.0/debtpilot.egg-info/entry_points.txt +2 -0
- debtpilot-0.1.0/debtpilot.egg-info/requires.txt +14 -0
- debtpilot-0.1.0/debtpilot.egg-info/top_level.txt +1 -0
- debtpilot-0.1.0/debtpilot_core/__init__.py +6 -0
- debtpilot-0.1.0/debtpilot_core/ai_advisor.py +206 -0
- debtpilot-0.1.0/debtpilot_core/autostart.py +255 -0
- debtpilot-0.1.0/debtpilot_core/cli.py +682 -0
- debtpilot-0.1.0/debtpilot_core/daemon.py +263 -0
- debtpilot-0.1.0/debtpilot_core/dashboard.py +289 -0
- debtpilot-0.1.0/debtpilot_core/database.py +271 -0
- debtpilot-0.1.0/debtpilot_core/digest.py +227 -0
- debtpilot-0.1.0/debtpilot_core/hooks.py +149 -0
- debtpilot-0.1.0/debtpilot_core/linter.py +153 -0
- debtpilot-0.1.0/debtpilot_core/notifier.py +247 -0
- debtpilot-0.1.0/debtpilot_core/predictor.py +223 -0
- debtpilot-0.1.0/debtpilot_core/reporter.py +210 -0
- debtpilot-0.1.0/debtpilot_core/scanner.py +177 -0
- debtpilot-0.1.0/debtpilot_core/scorer.py +138 -0
- debtpilot-0.1.0/pyproject.toml +53 -0
- debtpilot-0.1.0/setup.cfg +4 -0
debtpilot-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: debtpilot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Track technical debt before it blows up in production
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/YOUR_GITHUB_USERNAME/debtpilot
|
|
7
|
+
Project-URL: Issues, https://github.com/YOUR_GITHUB_USERNAME/debtpilot/issues
|
|
8
|
+
Keywords: technical-debt,code-quality,developer-tools,cli,linting
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: rich>=13.0
|
|
22
|
+
Provides-Extra: daemon
|
|
23
|
+
Requires-Dist: websockets>=12.0; extra == "daemon"
|
|
24
|
+
Requires-Dist: watchdog>=4.0; extra == "daemon"
|
|
25
|
+
Provides-Extra: notify
|
|
26
|
+
Requires-Dist: win10toast>=0.9; platform_system == "Windows" and extra == "notify"
|
|
27
|
+
Requires-Dist: plyer>=2.1; extra == "notify"
|
|
28
|
+
Provides-Extra: full
|
|
29
|
+
Requires-Dist: debtpilot[daemon,notify]; extra == "full"
|
|
30
|
+
|
|
31
|
+
# DebtPilot
|
|
32
|
+
|
|
33
|
+
> Track technical debt before it blows up in production.
|
|
34
|
+
|
|
35
|
+
Every IDE catches syntax errors. DebtPilot does something no IDE can —
|
|
36
|
+
it knows that `payments/stripe.js` has been edited 30 times by 4 different
|
|
37
|
+
developers, has a TODO from 8 months ago, and a complexity score of 24.
|
|
38
|
+
That combination is your next production incident.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
pip install debtpilot
|
|
45
|
+
|
|
46
|
+
Full install (file watcher + live notifications):
|
|
47
|
+
|
|
48
|
+
pip install "debtpilot[full]"
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Quickstart — 4 commands, done
|
|
53
|
+
|
|
54
|
+
1. Scan your project
|
|
55
|
+
debtpilot scan .
|
|
56
|
+
|
|
57
|
+
2. See the report
|
|
58
|
+
debtpilot report
|
|
59
|
+
|
|
60
|
+
3. Block bad commits automatically
|
|
61
|
+
debtpilot hook --install
|
|
62
|
+
|
|
63
|
+
4. Start live background watching
|
|
64
|
+
debtpilot start --dir .
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## What it does
|
|
69
|
+
|
|
70
|
+
| Command | What happens |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `debtpilot scan .` | Scores every file 0-100 for technical debt |
|
|
73
|
+
| `debtpilot report` | Shows top debt files in a ranked table |
|
|
74
|
+
| `debtpilot file <path>` | Deep breakdown of one file |
|
|
75
|
+
| `debtpilot ai <path>` | AI explains exactly what to fix (needs Gemini key) |
|
|
76
|
+
| `debtpilot predict` | Predicts which file will cause your next bug |
|
|
77
|
+
| `debtpilot dashboard` | Generates an HTML dashboard — open in browser |
|
|
78
|
+
| `debtpilot report-pdf` | Generates a print-ready PDF report |
|
|
79
|
+
| `debtpilot alerts` | Shows active danger alerts |
|
|
80
|
+
| `debtpilot todos` | Lists stale TODOs by age |
|
|
81
|
+
| `debtpilot hook --install` | Blocks commits above the debt threshold |
|
|
82
|
+
| `debtpilot start` | Starts live file watcher + WebSocket server |
|
|
83
|
+
| `debtpilot status` | Full health check of your DebtPilot setup |
|
|
84
|
+
| `debtpilot digest --send` | Sends weekly email summary to your team |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Debt Score (0-100)
|
|
89
|
+
|
|
90
|
+
| Grade | Score | Meaning |
|
|
91
|
+
|-------|-------|---------|
|
|
92
|
+
| A | 0-25 | Healthy |
|
|
93
|
+
| B | 26-45 | Watch |
|
|
94
|
+
| C | 46-65 | Concerning |
|
|
95
|
+
| D | 66-80 | Dangerous |
|
|
96
|
+
| F | 81-100 | Critical — fix before next deploy |
|
|
97
|
+
|
|
98
|
+
Score = weighted combination of: git churn (30%) + complexity (25%) +
|
|
99
|
+
lint issues (20%) + stale TODOs (15%) + staleness (10%).
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## AI Fix Suggestions (optional)
|
|
104
|
+
|
|
105
|
+
Get a free Gemini API key at aistudio.google.com then:
|
|
106
|
+
|
|
107
|
+
debtpilot config --gemini-key YOUR_KEY
|
|
108
|
+
debtpilot ai src/payments.py
|
|
109
|
+
|
|
110
|
+
DebtPilot sends the file context to Gemini and gets back exact fix
|
|
111
|
+
suggestions with code examples and effort estimates.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Weekly Email Digest
|
|
116
|
+
|
|
117
|
+
debtpilot config --gmail you@gmail.com --gmail-password YOUR_APP_PASS --recipients team@company.com
|
|
118
|
+
debtpilot digest --send
|
|
119
|
+
|
|
120
|
+
Use a Gmail App Password from: myaccount.google.com/apppasswords
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Auto-start on Windows login
|
|
125
|
+
|
|
126
|
+
debtpilot autostart --install --dir .
|
|
127
|
+
|
|
128
|
+
DebtPilot will start silently in the background every time Windows starts.
|
|
129
|
+
No manual debtpilot start needed.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Requirements
|
|
134
|
+
|
|
135
|
+
- Python 3.10 or higher
|
|
136
|
+
- git in PATH
|
|
137
|
+
- pylint / mypy / eslint — optional, for richer lint scores
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# DebtPilot
|
|
2
|
+
|
|
3
|
+
> Track technical debt before it blows up in production.
|
|
4
|
+
|
|
5
|
+
Every IDE catches syntax errors. DebtPilot does something no IDE can —
|
|
6
|
+
it knows that `payments/stripe.js` has been edited 30 times by 4 different
|
|
7
|
+
developers, has a TODO from 8 months ago, and a complexity score of 24.
|
|
8
|
+
That combination is your next production incident.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
pip install debtpilot
|
|
15
|
+
|
|
16
|
+
Full install (file watcher + live notifications):
|
|
17
|
+
|
|
18
|
+
pip install "debtpilot[full]"
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quickstart — 4 commands, done
|
|
23
|
+
|
|
24
|
+
1. Scan your project
|
|
25
|
+
debtpilot scan .
|
|
26
|
+
|
|
27
|
+
2. See the report
|
|
28
|
+
debtpilot report
|
|
29
|
+
|
|
30
|
+
3. Block bad commits automatically
|
|
31
|
+
debtpilot hook --install
|
|
32
|
+
|
|
33
|
+
4. Start live background watching
|
|
34
|
+
debtpilot start --dir .
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## What it does
|
|
39
|
+
|
|
40
|
+
| Command | What happens |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `debtpilot scan .` | Scores every file 0-100 for technical debt |
|
|
43
|
+
| `debtpilot report` | Shows top debt files in a ranked table |
|
|
44
|
+
| `debtpilot file <path>` | Deep breakdown of one file |
|
|
45
|
+
| `debtpilot ai <path>` | AI explains exactly what to fix (needs Gemini key) |
|
|
46
|
+
| `debtpilot predict` | Predicts which file will cause your next bug |
|
|
47
|
+
| `debtpilot dashboard` | Generates an HTML dashboard — open in browser |
|
|
48
|
+
| `debtpilot report-pdf` | Generates a print-ready PDF report |
|
|
49
|
+
| `debtpilot alerts` | Shows active danger alerts |
|
|
50
|
+
| `debtpilot todos` | Lists stale TODOs by age |
|
|
51
|
+
| `debtpilot hook --install` | Blocks commits above the debt threshold |
|
|
52
|
+
| `debtpilot start` | Starts live file watcher + WebSocket server |
|
|
53
|
+
| `debtpilot status` | Full health check of your DebtPilot setup |
|
|
54
|
+
| `debtpilot digest --send` | Sends weekly email summary to your team |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Debt Score (0-100)
|
|
59
|
+
|
|
60
|
+
| Grade | Score | Meaning |
|
|
61
|
+
|-------|-------|---------|
|
|
62
|
+
| A | 0-25 | Healthy |
|
|
63
|
+
| B | 26-45 | Watch |
|
|
64
|
+
| C | 46-65 | Concerning |
|
|
65
|
+
| D | 66-80 | Dangerous |
|
|
66
|
+
| F | 81-100 | Critical — fix before next deploy |
|
|
67
|
+
|
|
68
|
+
Score = weighted combination of: git churn (30%) + complexity (25%) +
|
|
69
|
+
lint issues (20%) + stale TODOs (15%) + staleness (10%).
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## AI Fix Suggestions (optional)
|
|
74
|
+
|
|
75
|
+
Get a free Gemini API key at aistudio.google.com then:
|
|
76
|
+
|
|
77
|
+
debtpilot config --gemini-key YOUR_KEY
|
|
78
|
+
debtpilot ai src/payments.py
|
|
79
|
+
|
|
80
|
+
DebtPilot sends the file context to Gemini and gets back exact fix
|
|
81
|
+
suggestions with code examples and effort estimates.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Weekly Email Digest
|
|
86
|
+
|
|
87
|
+
debtpilot config --gmail you@gmail.com --gmail-password YOUR_APP_PASS --recipients team@company.com
|
|
88
|
+
debtpilot digest --send
|
|
89
|
+
|
|
90
|
+
Use a Gmail App Password from: myaccount.google.com/apppasswords
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Auto-start on Windows login
|
|
95
|
+
|
|
96
|
+
debtpilot autostart --install --dir .
|
|
97
|
+
|
|
98
|
+
DebtPilot will start silently in the background every time Windows starts.
|
|
99
|
+
No manual debtpilot start needed.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Requirements
|
|
104
|
+
|
|
105
|
+
- Python 3.10 or higher
|
|
106
|
+
- git in PATH
|
|
107
|
+
- pylint / mypy / eslint — optional, for richer lint scores
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
MIT
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: debtpilot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Track technical debt before it blows up in production
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/YOUR_GITHUB_USERNAME/debtpilot
|
|
7
|
+
Project-URL: Issues, https://github.com/YOUR_GITHUB_USERNAME/debtpilot/issues
|
|
8
|
+
Keywords: technical-debt,code-quality,developer-tools,cli,linting
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: rich>=13.0
|
|
22
|
+
Provides-Extra: daemon
|
|
23
|
+
Requires-Dist: websockets>=12.0; extra == "daemon"
|
|
24
|
+
Requires-Dist: watchdog>=4.0; extra == "daemon"
|
|
25
|
+
Provides-Extra: notify
|
|
26
|
+
Requires-Dist: win10toast>=0.9; platform_system == "Windows" and extra == "notify"
|
|
27
|
+
Requires-Dist: plyer>=2.1; extra == "notify"
|
|
28
|
+
Provides-Extra: full
|
|
29
|
+
Requires-Dist: debtpilot[daemon,notify]; extra == "full"
|
|
30
|
+
|
|
31
|
+
# DebtPilot
|
|
32
|
+
|
|
33
|
+
> Track technical debt before it blows up in production.
|
|
34
|
+
|
|
35
|
+
Every IDE catches syntax errors. DebtPilot does something no IDE can —
|
|
36
|
+
it knows that `payments/stripe.js` has been edited 30 times by 4 different
|
|
37
|
+
developers, has a TODO from 8 months ago, and a complexity score of 24.
|
|
38
|
+
That combination is your next production incident.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
pip install debtpilot
|
|
45
|
+
|
|
46
|
+
Full install (file watcher + live notifications):
|
|
47
|
+
|
|
48
|
+
pip install "debtpilot[full]"
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Quickstart — 4 commands, done
|
|
53
|
+
|
|
54
|
+
1. Scan your project
|
|
55
|
+
debtpilot scan .
|
|
56
|
+
|
|
57
|
+
2. See the report
|
|
58
|
+
debtpilot report
|
|
59
|
+
|
|
60
|
+
3. Block bad commits automatically
|
|
61
|
+
debtpilot hook --install
|
|
62
|
+
|
|
63
|
+
4. Start live background watching
|
|
64
|
+
debtpilot start --dir .
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## What it does
|
|
69
|
+
|
|
70
|
+
| Command | What happens |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `debtpilot scan .` | Scores every file 0-100 for technical debt |
|
|
73
|
+
| `debtpilot report` | Shows top debt files in a ranked table |
|
|
74
|
+
| `debtpilot file <path>` | Deep breakdown of one file |
|
|
75
|
+
| `debtpilot ai <path>` | AI explains exactly what to fix (needs Gemini key) |
|
|
76
|
+
| `debtpilot predict` | Predicts which file will cause your next bug |
|
|
77
|
+
| `debtpilot dashboard` | Generates an HTML dashboard — open in browser |
|
|
78
|
+
| `debtpilot report-pdf` | Generates a print-ready PDF report |
|
|
79
|
+
| `debtpilot alerts` | Shows active danger alerts |
|
|
80
|
+
| `debtpilot todos` | Lists stale TODOs by age |
|
|
81
|
+
| `debtpilot hook --install` | Blocks commits above the debt threshold |
|
|
82
|
+
| `debtpilot start` | Starts live file watcher + WebSocket server |
|
|
83
|
+
| `debtpilot status` | Full health check of your DebtPilot setup |
|
|
84
|
+
| `debtpilot digest --send` | Sends weekly email summary to your team |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Debt Score (0-100)
|
|
89
|
+
|
|
90
|
+
| Grade | Score | Meaning |
|
|
91
|
+
|-------|-------|---------|
|
|
92
|
+
| A | 0-25 | Healthy |
|
|
93
|
+
| B | 26-45 | Watch |
|
|
94
|
+
| C | 46-65 | Concerning |
|
|
95
|
+
| D | 66-80 | Dangerous |
|
|
96
|
+
| F | 81-100 | Critical — fix before next deploy |
|
|
97
|
+
|
|
98
|
+
Score = weighted combination of: git churn (30%) + complexity (25%) +
|
|
99
|
+
lint issues (20%) + stale TODOs (15%) + staleness (10%).
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## AI Fix Suggestions (optional)
|
|
104
|
+
|
|
105
|
+
Get a free Gemini API key at aistudio.google.com then:
|
|
106
|
+
|
|
107
|
+
debtpilot config --gemini-key YOUR_KEY
|
|
108
|
+
debtpilot ai src/payments.py
|
|
109
|
+
|
|
110
|
+
DebtPilot sends the file context to Gemini and gets back exact fix
|
|
111
|
+
suggestions with code examples and effort estimates.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Weekly Email Digest
|
|
116
|
+
|
|
117
|
+
debtpilot config --gmail you@gmail.com --gmail-password YOUR_APP_PASS --recipients team@company.com
|
|
118
|
+
debtpilot digest --send
|
|
119
|
+
|
|
120
|
+
Use a Gmail App Password from: myaccount.google.com/apppasswords
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Auto-start on Windows login
|
|
125
|
+
|
|
126
|
+
debtpilot autostart --install --dir .
|
|
127
|
+
|
|
128
|
+
DebtPilot will start silently in the background every time Windows starts.
|
|
129
|
+
No manual debtpilot start needed.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Requirements
|
|
134
|
+
|
|
135
|
+
- Python 3.10 or higher
|
|
136
|
+
- git in PATH
|
|
137
|
+
- pylint / mypy / eslint — optional, for richer lint scores
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
debtpilot.egg-info/PKG-INFO
|
|
4
|
+
debtpilot.egg-info/SOURCES.txt
|
|
5
|
+
debtpilot.egg-info/dependency_links.txt
|
|
6
|
+
debtpilot.egg-info/entry_points.txt
|
|
7
|
+
debtpilot.egg-info/requires.txt
|
|
8
|
+
debtpilot.egg-info/top_level.txt
|
|
9
|
+
debtpilot_core/__init__.py
|
|
10
|
+
debtpilot_core/ai_advisor.py
|
|
11
|
+
debtpilot_core/autostart.py
|
|
12
|
+
debtpilot_core/cli.py
|
|
13
|
+
debtpilot_core/daemon.py
|
|
14
|
+
debtpilot_core/dashboard.py
|
|
15
|
+
debtpilot_core/database.py
|
|
16
|
+
debtpilot_core/digest.py
|
|
17
|
+
debtpilot_core/hooks.py
|
|
18
|
+
debtpilot_core/linter.py
|
|
19
|
+
debtpilot_core/notifier.py
|
|
20
|
+
debtpilot_core/predictor.py
|
|
21
|
+
debtpilot_core/reporter.py
|
|
22
|
+
debtpilot_core/scanner.py
|
|
23
|
+
debtpilot_core/scorer.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
debtpilot_core
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""
|
|
2
|
+
DebtPilot - AI Fix Suggestions using Google Gemini (free API).
|
|
3
|
+
Sends risky code to Gemini and gets back exact fix suggestions.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import json
|
|
8
|
+
import urllib.request
|
|
9
|
+
import urllib.error
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_api_key() -> Optional[str]:
|
|
17
|
+
# First check environment variable
|
|
18
|
+
key = os.environ.get("DEBTPILOT_GEMINI_KEY")
|
|
19
|
+
if key:
|
|
20
|
+
return key
|
|
21
|
+
# Then check config file
|
|
22
|
+
config_path = Path.home() / ".debtpilot" / "config.json"
|
|
23
|
+
if config_path.exists():
|
|
24
|
+
try:
|
|
25
|
+
data = json.loads(config_path.read_text())
|
|
26
|
+
return data.get("gemini_api_key")
|
|
27
|
+
except Exception:
|
|
28
|
+
pass
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def save_api_key(api_key: str) -> None:
|
|
33
|
+
config_dir = Path.home() / ".debtpilot"
|
|
34
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
35
|
+
config_path = config_dir / "config.json"
|
|
36
|
+
data = {}
|
|
37
|
+
if config_path.exists():
|
|
38
|
+
try:
|
|
39
|
+
data = json.loads(config_path.read_text())
|
|
40
|
+
except Exception:
|
|
41
|
+
pass
|
|
42
|
+
data["gemini_api_key"] = api_key
|
|
43
|
+
config_path.write_text(json.dumps(data, indent=2))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _call_gemini(prompt: str, api_key: str) -> str:
|
|
47
|
+
payload = json.dumps({
|
|
48
|
+
"contents": [{"parts": [{"text": prompt}]}],
|
|
49
|
+
"generationConfig": {"temperature": 0.3, "maxOutputTokens": 1500}
|
|
50
|
+
}).encode()
|
|
51
|
+
|
|
52
|
+
req = urllib.request.Request(
|
|
53
|
+
f"{GEMINI_API_URL}?key={api_key}",
|
|
54
|
+
data=payload,
|
|
55
|
+
headers={"Content-Type": "application/json"},
|
|
56
|
+
method="POST",
|
|
57
|
+
)
|
|
58
|
+
try:
|
|
59
|
+
with urllib.request.urlopen(req, timeout=30) as r:
|
|
60
|
+
result = json.loads(r.read())
|
|
61
|
+
return result["candidates"][0]["content"]["parts"][0]["text"]
|
|
62
|
+
except urllib.error.HTTPError as e:
|
|
63
|
+
body = e.read().decode()
|
|
64
|
+
raise RuntimeError(f"Gemini API error {e.code}: {body}")
|
|
65
|
+
except Exception as e:
|
|
66
|
+
raise RuntimeError(f"Failed to call Gemini: {e}")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def analyze_file(
|
|
70
|
+
filepath: str,
|
|
71
|
+
score_data: Dict,
|
|
72
|
+
lint_issues: List[Dict],
|
|
73
|
+
todos: List[Dict],
|
|
74
|
+
complexity: Dict,
|
|
75
|
+
) -> Dict:
|
|
76
|
+
"""
|
|
77
|
+
Send file context to Gemini and get back structured fix suggestions.
|
|
78
|
+
Returns dict with summary, fixes, and priority actions.
|
|
79
|
+
"""
|
|
80
|
+
api_key = get_api_key()
|
|
81
|
+
if not api_key:
|
|
82
|
+
return {
|
|
83
|
+
"error": "No Gemini API key configured. Run: debtpilot config --gemini-key YOUR_KEY",
|
|
84
|
+
"summary": "AI advisor not configured. The rest of DebtPilot works without it.",
|
|
85
|
+
"fixes": [],
|
|
86
|
+
"priority_actions": ["Run: debtpilot config --gemini-key YOUR_KEY to enable AI suggestions"],
|
|
87
|
+
"risk_level": "UNKNOWN",
|
|
88
|
+
"estimated_fix_time": "N/A",
|
|
89
|
+
"ai_available": False,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# Read file content (first 150 lines to stay within token limits)
|
|
93
|
+
try:
|
|
94
|
+
lines = Path(filepath).read_text(encoding="utf-8", errors="ignore").splitlines()
|
|
95
|
+
code_preview = "\n".join(lines[:150])
|
|
96
|
+
total_lines = len(lines)
|
|
97
|
+
except OSError:
|
|
98
|
+
code_preview = "(could not read file)"
|
|
99
|
+
total_lines = 0
|
|
100
|
+
|
|
101
|
+
# Build lint summary
|
|
102
|
+
errors = [i for i in lint_issues if i.get("severity") == "error"][:5]
|
|
103
|
+
warnings = [i for i in lint_issues if i.get("severity") == "warning"][:5]
|
|
104
|
+
lint_summary = "\n".join(
|
|
105
|
+
[f" ERROR L{i['line']}: {i['message']}" for i in errors] +
|
|
106
|
+
[f" WARNING L{i['line']}: {i['message']}" for i in warnings]
|
|
107
|
+
) or " None detected"
|
|
108
|
+
|
|
109
|
+
# Build TODO summary
|
|
110
|
+
todo_summary = "\n".join(
|
|
111
|
+
[f" L{t['line']} ({t.get('age_days', 0)} days old): {t.get('text', '')}" for t in todos[:5]]
|
|
112
|
+
) or " None"
|
|
113
|
+
|
|
114
|
+
# Build complexity summary
|
|
115
|
+
funcs = complexity.get("functions", [])[:5]
|
|
116
|
+
complexity_summary = "\n".join(
|
|
117
|
+
[f" {f['name']}() at L{f['line']}: complexity {f['complexity']}" for f in funcs]
|
|
118
|
+
) or f" avg={complexity.get('avg_complexity', 0)}"
|
|
119
|
+
|
|
120
|
+
prompt = f"""You are a senior software engineer doing a technical debt review.
|
|
121
|
+
|
|
122
|
+
FILE: {filepath}
|
|
123
|
+
TOTAL LINES: {total_lines}
|
|
124
|
+
DEBT SCORE: {score_data.get('total', 0)}/100 (Grade {score_data.get('grade', '?')} — {score_data.get('label', '')})
|
|
125
|
+
|
|
126
|
+
SUB-SCORES:
|
|
127
|
+
Churn (how often edited by many people): {score_data.get('churn_score', 0)}/100
|
|
128
|
+
Complexity (how hard to understand): {score_data.get('complexity_score', 0)}/100
|
|
129
|
+
Lint issues: {score_data.get('lint_score', 0)}/100
|
|
130
|
+
Stale TODOs: {score_data.get('todo_score', 0)}/100
|
|
131
|
+
Staleness: {score_data.get('staleness_score', 0)}/100
|
|
132
|
+
|
|
133
|
+
LINT ISSUES:
|
|
134
|
+
{lint_summary}
|
|
135
|
+
|
|
136
|
+
STALE TODOs:
|
|
137
|
+
{todo_summary}
|
|
138
|
+
|
|
139
|
+
COMPLEX FUNCTIONS:
|
|
140
|
+
{complexity_summary}
|
|
141
|
+
|
|
142
|
+
CODE PREVIEW (first 150 lines):
|
|
143
|
+
{code_preview}
|
|
144
|
+
|
|
145
|
+
Respond ONLY with a valid JSON object in this exact format, no markdown, no explanation outside the JSON:
|
|
146
|
+
{{
|
|
147
|
+
"summary": "2-3 sentence plain English summary of the main problems",
|
|
148
|
+
"risk_level": "LOW or MEDIUM or HIGH or CRITICAL",
|
|
149
|
+
"fixes": [
|
|
150
|
+
{{
|
|
151
|
+
"title": "short title of the fix",
|
|
152
|
+
"problem": "what is wrong and why it matters",
|
|
153
|
+
"solution": "exactly what to do",
|
|
154
|
+
"code_example": "short before/after code snippet if relevant, else empty string",
|
|
155
|
+
"effort": "15min or 1hr or half-day or 1day"
|
|
156
|
+
}}
|
|
157
|
+
],
|
|
158
|
+
"priority_actions": [
|
|
159
|
+
"action 1 — most important thing to do first",
|
|
160
|
+
"action 2",
|
|
161
|
+
"action 3"
|
|
162
|
+
],
|
|
163
|
+
"estimated_fix_time": "total estimated time to resolve all issues"
|
|
164
|
+
}}"""
|
|
165
|
+
|
|
166
|
+
raw = _call_gemini(prompt, api_key)
|
|
167
|
+
|
|
168
|
+
# Strip markdown code fences if present
|
|
169
|
+
raw = raw.strip()
|
|
170
|
+
if raw.startswith("```"):
|
|
171
|
+
raw = raw.split("```")[1]
|
|
172
|
+
if raw.startswith("json"):
|
|
173
|
+
raw = raw[4:]
|
|
174
|
+
raw = raw.strip()
|
|
175
|
+
|
|
176
|
+
try:
|
|
177
|
+
return json.loads(raw)
|
|
178
|
+
except json.JSONDecodeError:
|
|
179
|
+
return {
|
|
180
|
+
"summary": raw[:500],
|
|
181
|
+
"risk_level": "UNKNOWN",
|
|
182
|
+
"fixes": [],
|
|
183
|
+
"priority_actions": [],
|
|
184
|
+
"estimated_fix_time": "unknown",
|
|
185
|
+
"parse_error": True,
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def quick_explain(code_snippet: str, question: str) -> str:
|
|
190
|
+
"""Ask Gemini a quick question about a code snippet."""
|
|
191
|
+
api_key = get_api_key()
|
|
192
|
+
if not api_key:
|
|
193
|
+
return "No Gemini API key configured. Run: debtpilot config --gemini-key YOUR_KEY"
|
|
194
|
+
|
|
195
|
+
prompt = f"""You are a helpful senior developer. Answer concisely.
|
|
196
|
+
|
|
197
|
+
Question: {question}
|
|
198
|
+
|
|
199
|
+
Code:{code_snippet[:1000]}
|
|
200
|
+
|
|
201
|
+
Give a direct, practical answer in 3-5 sentences maximum."""
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
return _call_gemini(prompt, api_key)
|
|
205
|
+
except RuntimeError as e:
|
|
206
|
+
return f"AI error: {e}"
|