mdx-code 0.1.0__py3-none-any.whl
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.
- mdx_code-0.1.0.dist-info/METADATA +316 -0
- mdx_code-0.1.0.dist-info/RECORD +21 -0
- mdx_code-0.1.0.dist-info/WHEEL +5 -0
- mdx_code-0.1.0.dist-info/entry_points.txt +2 -0
- mdx_code-0.1.0.dist-info/licenses/LICENSE +21 -0
- mdx_code-0.1.0.dist-info/top_level.txt +1 -0
- mdxcode/__init__.py +11 -0
- mdxcode/cli.py +269 -0
- mdxcode/core/__init__.py +26 -0
- mdxcode/core/agent_loop.py +308 -0
- mdxcode/core/context_loader.py +209 -0
- mdxcode/core/session.py +80 -0
- mdxcode/governance/__init__.py +26 -0
- mdxcode/governance/audit.py +200 -0
- mdxcode/governance/permissions.py +299 -0
- mdxcode/governance/security_agent.py +363 -0
- mdxcode/models/__init__.py +28 -0
- mdxcode/models/auth.py +232 -0
- mdxcode/models/router.py +202 -0
- mdxcode/tools/__init__.py +18 -0
- mdxcode/tools/registry.py +417 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mdx-code
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-Native Engineering Companion. Built for builders. Designed for regulated environments.
|
|
5
|
+
Author: MD
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dhotherm/mdx-code
|
|
8
|
+
Project-URL: Documentation, https://github.com/dhotherm/mdx-code#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/dhotherm/mdx-code
|
|
10
|
+
Project-URL: Issues, https://github.com/dhotherm/mdx-code/issues
|
|
11
|
+
Keywords: ai,llm,claude,developer-tools,agents,agentic-ai,code-assistant
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: anthropic>=0.40.0
|
|
28
|
+
Requires-Dist: httpx>=0.27.0
|
|
29
|
+
Requires-Dist: pydantic>=2.0.0
|
|
30
|
+
Requires-Dist: typer>=0.12.0
|
|
31
|
+
Requires-Dist: rich>=13.0.0
|
|
32
|
+
Requires-Dist: pyyaml>=6.0
|
|
33
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
37
|
+
Requires-Dist: black>=24.0.0; extra == "dev"
|
|
38
|
+
Requires-Dist: mypy>=1.8.0; extra == "dev"
|
|
39
|
+
Provides-Extra: openai
|
|
40
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
41
|
+
Provides-Extra: bedrock
|
|
42
|
+
Requires-Dist: boto3>=1.34.0; extra == "bedrock"
|
|
43
|
+
Provides-Extra: all
|
|
44
|
+
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
45
|
+
Requires-Dist: boto3>=1.34.0; extra == "all"
|
|
46
|
+
Requires-Dist: google-cloud-aiplatform>=1.0.0; extra == "all"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# MDx Code
|
|
50
|
+
|
|
51
|
+
**AI-Native Engineering Companion**
|
|
52
|
+
|
|
53
|
+
Built for builders. Designed for regulated environments.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## The Story
|
|
58
|
+
|
|
59
|
+
I've been thinking about AI-powered development tools for over a year. Then I read an article that broke down Claude Code from first principles and realized something: the core architecture is embarrassingly simple.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
while task_not_complete:
|
|
63
|
+
response = ask_llm(conversation)
|
|
64
|
+
if response.wants_tool:
|
|
65
|
+
result = execute_tool(response.tool)
|
|
66
|
+
conversation.append(result)
|
|
67
|
+
if response.done:
|
|
68
|
+
break
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
That's it. AI thinks → acts → observes → repeats.
|
|
72
|
+
|
|
73
|
+
Everything else is just tooling and governance wrapped around this loop.
|
|
74
|
+
|
|
75
|
+
So I built my own. Not because Claude Code isn't good... it's excellent. But because I needed something that:
|
|
76
|
+
|
|
77
|
+
- **Works in regulated environments** → Financial services, healthcare, government
|
|
78
|
+
- **Owns the orchestration layer** → Swap models without rewriting everything
|
|
79
|
+
- **Respects governance rules** → Audit trails, permission controls, compliance profiles
|
|
80
|
+
- **Learns over time** → The security agent gets smarter with use
|
|
81
|
+
|
|
82
|
+
MDx Code is that tool.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Quick Start
|
|
87
|
+
|
|
88
|
+
**Option 1: Install directly from GitHub (recommended)**
|
|
89
|
+
```bash
|
|
90
|
+
pip install git+https://github.com/dhotherm/mdx-code.git
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Option 2: Clone and install locally**
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/dhotherm/mdx-code.git
|
|
96
|
+
cd mdx-code
|
|
97
|
+
pip install -e .
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Then authenticate and run:**
|
|
101
|
+
```bash
|
|
102
|
+
# Authenticate with Claude
|
|
103
|
+
mdxcode auth claude
|
|
104
|
+
|
|
105
|
+
# Initialize in your project
|
|
106
|
+
cd your-project
|
|
107
|
+
mdxcode init
|
|
108
|
+
|
|
109
|
+
# Run it
|
|
110
|
+
mdxcode main "Fix the bug in auth.py"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## What It Does
|
|
116
|
+
|
|
117
|
+
**Give it a task. Watch it work.**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
mdxcode "Add input validation to the user registration endpoint"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
MDx Code will:
|
|
124
|
+
1. Read your MDXCODE.md for project context
|
|
125
|
+
2. Find the relevant files
|
|
126
|
+
3. Understand the existing patterns
|
|
127
|
+
4. Make changes incrementally
|
|
128
|
+
5. Run tests to verify
|
|
129
|
+
6. Log everything for audit
|
|
130
|
+
|
|
131
|
+
**Scan for vulnerabilities:**
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
mdxcode security scan
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Auto-fix issues:**
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
mdxcode security fix --auto-fix
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## MDXCODE.md
|
|
146
|
+
|
|
147
|
+
Every project gets a context file. This is how MDx Code understands your project before touching anything.
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
# MDXCODE.md
|
|
151
|
+
|
|
152
|
+
## Project
|
|
153
|
+
- **Name:** Claims Processing API
|
|
154
|
+
- **Domain:** Health
|
|
155
|
+
- **Team:** Health Platform
|
|
156
|
+
|
|
157
|
+
## Conventions
|
|
158
|
+
- All endpoints require JWT auth
|
|
159
|
+
- Use Pydantic for request/response models
|
|
160
|
+
- Event sourcing for state changes
|
|
161
|
+
|
|
162
|
+
## Compliance
|
|
163
|
+
- PHI fields use SL-encrypt utility
|
|
164
|
+
- Never log PHI in plain text
|
|
165
|
+
|
|
166
|
+
## Guardrails
|
|
167
|
+
- ❌ Never commit directly to main
|
|
168
|
+
- ❌ Never modify production configs
|
|
169
|
+
- ⚠️ Schema changes require approval
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Different domains, different rules. The context file captures all of that.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Regulatory Profiles
|
|
177
|
+
|
|
178
|
+
MDx Code ships with profiles for regulated industries:
|
|
179
|
+
|
|
180
|
+
| Profile | Description |
|
|
181
|
+
|---------|-------------|
|
|
182
|
+
| `standard` | Default. Sensible permissions for most projects. |
|
|
183
|
+
| `financial_services` | Stricter controls for OSFI/SOX compliance. |
|
|
184
|
+
| `healthcare` | HIPAA-aware. Extra protection for PHI. |
|
|
185
|
+
| `government` | Maximum restrictions. Minimal auto-approval. |
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
mdxcode "Update the API" --profile financial_services
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Multi-Model Support
|
|
194
|
+
|
|
195
|
+
Own the orchestration. Swap the models.
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
mdxcode "Fix the bug" --model claude # Default
|
|
199
|
+
mdxcode "Fix the bug" --model gpt # OpenAI
|
|
200
|
+
mdxcode "Fix the bug" --model bedrock # AWS Bedrock
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Today it's Claude. Tomorrow it could be anything. Your choice.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Security Agent
|
|
208
|
+
|
|
209
|
+
Not just a linter. An AI that understands context.
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Scan for vulnerabilities
|
|
213
|
+
mdxcode security scan
|
|
214
|
+
|
|
215
|
+
# Scan specific path
|
|
216
|
+
mdxcode security scan --path src/
|
|
217
|
+
|
|
218
|
+
# Auto-fix what can be fixed
|
|
219
|
+
mdxcode security fix --auto-fix
|
|
220
|
+
|
|
221
|
+
# Teach it new patterns
|
|
222
|
+
mdxcode security learn
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The knowledge base grows as you use it. Every fix teaches it something new.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Audit Trail
|
|
230
|
+
|
|
231
|
+
Every action. Every decision. Logged.
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
~/.mdxcode/audit/2026-01-09_abc123.jsonl
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"timestamp": "2026-01-09T14:32:15Z",
|
|
240
|
+
"event": "tool_use",
|
|
241
|
+
"tool": "write_file",
|
|
242
|
+
"input": {"path": "src/api.py", "content": "..."},
|
|
243
|
+
"approved_by": "user",
|
|
244
|
+
"session_id": "abc123"
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Essential for compliance. Essential for trust.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Project Structure
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
mdx-code/
|
|
256
|
+
├── mdxcode.py # CLI entry point
|
|
257
|
+
├── core/
|
|
258
|
+
│ ├── agent_loop.py # The heart of it
|
|
259
|
+
│ ├── context_loader.py
|
|
260
|
+
│ └── session.py
|
|
261
|
+
├── tools/
|
|
262
|
+
│ └── registry.py # read, write, edit, bash, grep, glob
|
|
263
|
+
├── models/
|
|
264
|
+
│ ├── router.py # Multi-model support
|
|
265
|
+
│ └── auth.py # Credential management
|
|
266
|
+
├── governance/
|
|
267
|
+
│ ├── permissions.py # What's allowed
|
|
268
|
+
│ ├── audit.py # Logging everything
|
|
269
|
+
│ └── security_agent.py
|
|
270
|
+
├── knowledge/
|
|
271
|
+
│ └── vulnerabilities/
|
|
272
|
+
└── examples/
|
|
273
|
+
└── demo_project/
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Philosophy
|
|
279
|
+
|
|
280
|
+
**Own the orchestration layer.**
|
|
281
|
+
|
|
282
|
+
Models will come and go. Vendors will compete on capability and cost. But the orchestration... the context engineering, the governance, the institutional knowledge... that's yours.
|
|
283
|
+
|
|
284
|
+
**Built for regulated environments.**
|
|
285
|
+
|
|
286
|
+
This isn't a toy. It's designed for environments where compliance matters, where audit trails are required, where "move fast and break things" gets you fired.
|
|
287
|
+
|
|
288
|
+
**Learn over time.**
|
|
289
|
+
|
|
290
|
+
The security agent grows smarter. The patterns library expands. Every project teaches it something new.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Contributing
|
|
295
|
+
|
|
296
|
+
Found a bug? Want to add a feature? PRs welcome.
|
|
297
|
+
|
|
298
|
+
The code is intentionally readable. If you can't understand it in an afternoon, I've failed.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT. Use it. Modify it. Build on it.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Author
|
|
309
|
+
|
|
310
|
+
Built by MD.
|
|
311
|
+
|
|
312
|
+
Not because I had to. Because I couldn't stop thinking about it.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
*"The future of software development is agents that can actually do things. Now we know how they work."*
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
mdx_code-0.1.0.dist-info/licenses/LICENSE,sha256=pp9j0Bt7MSztJrKcWtA2iSgzaq5dKjAcHLIMRzhpQfE,1059
|
|
2
|
+
mdxcode/__init__.py,sha256=KAV8lCmAOOGD0nb97qPES5Q-6mVVAzfBE5wZMhy4TlA,207
|
|
3
|
+
mdxcode/cli.py,sha256=83FYSWJH0LeWU7oAHpyRO1wFnDMRJYa7Ck2pZhWMmjI,9180
|
|
4
|
+
mdxcode/core/__init__.py,sha256=J8fXKYUK_t38aUkrCMxpIhULwN_d4tIsxYkWS50AR6k,569
|
|
5
|
+
mdxcode/core/agent_loop.py,sha256=4CsuSPVqITgSNFeu4f1fXqzSGGlLHTeAXiqrtyyqZ3o,11124
|
|
6
|
+
mdxcode/core/context_loader.py,sha256=JZFUh54fR_fG6k-irlM3_XY9tUvmlkzXsrpJR1Co98k,6210
|
|
7
|
+
mdxcode/core/session.py,sha256=T4KoJ0Lp7kuB8jOjR9YR_Ol7nhc6jKUSduFody0D6ws,2649
|
|
8
|
+
mdxcode/governance/__init__.py,sha256=N7NsrVq5KjxCarbQdSx9VNcMbhBMjqbk3EYwUCiTcCY,853
|
|
9
|
+
mdxcode/governance/audit.py,sha256=FVpJQW8pzfTMNhnyu6VR7epRpSCjmxG8b7aLxUVOyBQ,5925
|
|
10
|
+
mdxcode/governance/permissions.py,sha256=kMTMovUZhh8CCFNVc72UXNY9_f8nwYe_Xabog1Nk2TM,9621
|
|
11
|
+
mdxcode/governance/security_agent.py,sha256=IPq0FR0FafeDvOTv0Q23jY01T2JcjmN5ar5nuZPLx7M,13496
|
|
12
|
+
mdxcode/models/__init__.py,sha256=QJFphYKPDBaQe72ae7aO_CHNaarVbG4uh66jktjCQDk,667
|
|
13
|
+
mdxcode/models/auth.py,sha256=BLiI2MPjWsd2uhlpK07YZK0B_xW3_R0bmJ-b2VzV0vk,7421
|
|
14
|
+
mdxcode/models/router.py,sha256=gW9wk5lBTd0ynUWI8pdXzs31IsPmIOU2R_2qHJGBijI,5925
|
|
15
|
+
mdxcode/tools/__init__.py,sha256=R9ZhVo5QRSG7doLBtmaJdxEmEg0Vo0FY8u5CRgorPis,384
|
|
16
|
+
mdxcode/tools/registry.py,sha256=lzXh83VSc6KybpDT7cEhK2j-P_ew7F8e82_zZfONHSA,13546
|
|
17
|
+
mdx_code-0.1.0.dist-info/METADATA,sha256=vLalCddIQdShxmgN5X1-SYzdPPKMfEyFUMFB2Lxyn8E,7897
|
|
18
|
+
mdx_code-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
mdx_code-0.1.0.dist-info/entry_points.txt,sha256=dtFrZaULL68n911H7enEuP1wnUn_YWvsrYt6Ir9x0vw,40
|
|
20
|
+
mdx_code-0.1.0.dist-info/top_level.txt,sha256=VcIBQaqm0bIrugT9-6e_en1y2nMATWmkF_KC_50_fPc,8
|
|
21
|
+
mdx_code-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MD
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mdxcode
|
mdxcode/__init__.py
ADDED
mdxcode/cli.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
MDx Code - AI-Native Engineering Companion
|
|
4
|
+
|
|
5
|
+
Built for builders. Designed for regulated environments.
|
|
6
|
+
Own the orchestration. Swap the models. Keep the governance.
|
|
7
|
+
|
|
8
|
+
This is what happens when you realize Claude Code's architecture
|
|
9
|
+
is embarrassingly simple... and decide to build your own.
|
|
10
|
+
|
|
11
|
+
Author: MD
|
|
12
|
+
License: MIT
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import asyncio
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
import typer
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
from rich.panel import Panel
|
|
22
|
+
from rich.text import Text
|
|
23
|
+
|
|
24
|
+
from mdxcode.core.agent_loop import AgentLoop
|
|
25
|
+
from mdxcode.core.context_loader import load_mdxcode_context
|
|
26
|
+
from mdxcode.core.session import Session
|
|
27
|
+
from mdxcode.governance.audit import AuditLogger
|
|
28
|
+
from mdxcode.models.router import ModelRouter
|
|
29
|
+
|
|
30
|
+
# The CLI app
|
|
31
|
+
app = typer.Typer(
|
|
32
|
+
name="mdxcode",
|
|
33
|
+
help="AI-Native Engineering Companion. Built for builders.",
|
|
34
|
+
add_completion=False,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
console = Console()
|
|
38
|
+
|
|
39
|
+
# Version
|
|
40
|
+
__version__ = "0.1.0"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def version_callback(value: bool):
|
|
44
|
+
"""Show version and exit."""
|
|
45
|
+
if value:
|
|
46
|
+
console.print(f"[bold cyan]MDx Code[/bold cyan] v{__version__}")
|
|
47
|
+
raise typer.Exit()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# ASCII art banner - MDx CODE with style
|
|
51
|
+
BANNER_ART = """
|
|
52
|
+
[bold cyan]
|
|
53
|
+
███╗ ███╗[/bold cyan][cyan]██████╗[/cyan] [dim cyan]x[/dim cyan] [bold white]██████╗ ██████╗ ██████╗ ███████╗[/bold white]
|
|
54
|
+
[bold cyan] ████╗ ████║[/bold cyan][cyan]██╔══██╗[/cyan] [bold white]██╔════╝██╔═══██╗██╔══██╗██╔════╝[/bold white]
|
|
55
|
+
[bold cyan] ██╔████╔██║[/bold cyan][cyan]██║ ██║[/cyan] [bold white]██║ ██║ ██║██║ ██║█████╗[/bold white]
|
|
56
|
+
[bold cyan] ██║╚██╔╝██║[/bold cyan][cyan]██║ ██║[/cyan] [bold white]██║ ██║ ██║██║ ██║██╔══╝[/bold white]
|
|
57
|
+
[bold cyan] ██║ ╚═╝ ██║[/bold cyan][cyan]██████╔╝[/cyan] [bold white]╚██████╗╚██████╔╝██████╔╝███████╗[/bold white]
|
|
58
|
+
[bold cyan] ╚═╝ ╚═╝[/bold cyan][cyan]╚═════╝[/cyan] [bold white]╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝[/bold white]
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def show_banner():
|
|
63
|
+
"""Show the MDx Code banner. First impressions matter."""
|
|
64
|
+
from rich.markup import escape
|
|
65
|
+
|
|
66
|
+
console.print(BANNER_ART)
|
|
67
|
+
console.print(f" [dim]v{__version__}[/dim] [italic]Built for builders. Designed for regulated environments.[/italic]\n")
|
|
68
|
+
console.print(" [bold green]Yoooooo! Let's ship some code.[/bold green] 🚀\n")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@app.callback(invoke_without_command=True)
|
|
72
|
+
def app_callback(
|
|
73
|
+
ctx: typer.Context,
|
|
74
|
+
version: bool = typer.Option(False, "--version", "-V", help="Show version and exit.", callback=version_callback, is_eager=True),
|
|
75
|
+
):
|
|
76
|
+
"""MDx Code - AI-Native Engineering Companion."""
|
|
77
|
+
if ctx.invoked_subcommand is None:
|
|
78
|
+
show_banner()
|
|
79
|
+
console.print("Run [bold]mdxcode --help[/bold] for usage.\n")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@app.command()
|
|
83
|
+
def main(
|
|
84
|
+
task: str = typer.Argument(None, help="What do you want to work on?"),
|
|
85
|
+
model: str = typer.Option("claude", "--model", "-m", help="Model to use: claude, gpt, bedrock"),
|
|
86
|
+
profile: str = typer.Option("standard", "--profile", "-p", help="Regulatory profile: standard, financial_services, healthcare"),
|
|
87
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output"),
|
|
88
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Show what would happen without executing"),
|
|
89
|
+
):
|
|
90
|
+
"""
|
|
91
|
+
Run MDx Code on a task.
|
|
92
|
+
|
|
93
|
+
Examples:
|
|
94
|
+
mdxcode "Fix the bug in auth.py"
|
|
95
|
+
mdxcode "Add tests for the claims module" --model gpt
|
|
96
|
+
mdxcode "Scan for security vulnerabilities" --profile financial_services
|
|
97
|
+
"""
|
|
98
|
+
show_banner()
|
|
99
|
+
|
|
100
|
+
# Load project context if MDXCODE.md exists
|
|
101
|
+
context = load_mdxcode_context()
|
|
102
|
+
if context:
|
|
103
|
+
console.print(f"[dim]Loaded context from MDXCODE.md[/dim]")
|
|
104
|
+
if context.project_name:
|
|
105
|
+
console.print(f"[dim]Project: {context.project_name} ({context.domain})[/dim]")
|
|
106
|
+
|
|
107
|
+
# If no task provided, enter interactive mode
|
|
108
|
+
if not task:
|
|
109
|
+
console.print("\n[cyan]No task provided. Entering interactive mode...[/cyan]\n")
|
|
110
|
+
task = console.input("[bold]What do you want to work on?[/bold] → ")
|
|
111
|
+
if not task.strip():
|
|
112
|
+
console.print("[dim]Nothing to do. Exiting.[/dim]")
|
|
113
|
+
raise typer.Exit()
|
|
114
|
+
|
|
115
|
+
# Initialize the session
|
|
116
|
+
session = Session(
|
|
117
|
+
model=model,
|
|
118
|
+
profile=profile,
|
|
119
|
+
context=context,
|
|
120
|
+
verbose=verbose,
|
|
121
|
+
dry_run=dry_run,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Initialize audit logging
|
|
125
|
+
audit = AuditLogger(session)
|
|
126
|
+
audit.log_session_start(task)
|
|
127
|
+
|
|
128
|
+
# Initialize model router
|
|
129
|
+
router = ModelRouter(model)
|
|
130
|
+
|
|
131
|
+
# Initialize and run the agent loop
|
|
132
|
+
# This is where the magic happens.
|
|
133
|
+
# AI thinks → acts → observes → repeats.
|
|
134
|
+
agent = AgentLoop(
|
|
135
|
+
session=session,
|
|
136
|
+
router=router,
|
|
137
|
+
audit=audit,
|
|
138
|
+
console=console,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
asyncio.run(agent.run(task))
|
|
143
|
+
except KeyboardInterrupt:
|
|
144
|
+
console.print("\n[yellow]Interrupted. Saving session state...[/yellow]")
|
|
145
|
+
audit.log_session_end("interrupted")
|
|
146
|
+
except Exception as e:
|
|
147
|
+
console.print(f"\n[red]Error: {e}[/red]")
|
|
148
|
+
audit.log_session_end("error", str(e))
|
|
149
|
+
raise typer.Exit(1)
|
|
150
|
+
else:
|
|
151
|
+
audit.log_session_end("success")
|
|
152
|
+
|
|
153
|
+
console.print("\n[dim]Session complete. Audit log saved.[/dim]")
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@app.command()
|
|
157
|
+
def auth(
|
|
158
|
+
provider: str = typer.Argument(..., help="Provider to authenticate: claude, openai, bedrock"),
|
|
159
|
+
):
|
|
160
|
+
"""
|
|
161
|
+
Authenticate with an LLM provider.
|
|
162
|
+
|
|
163
|
+
Examples:
|
|
164
|
+
mdxcode auth claude
|
|
165
|
+
mdxcode auth openai
|
|
166
|
+
"""
|
|
167
|
+
from mdxcode.models.auth import authenticate
|
|
168
|
+
|
|
169
|
+
show_banner()
|
|
170
|
+
console.print(f"\n[cyan]Authenticating with {provider}...[/cyan]\n")
|
|
171
|
+
|
|
172
|
+
success = asyncio.run(authenticate(provider, console))
|
|
173
|
+
|
|
174
|
+
if success:
|
|
175
|
+
console.print(f"\n[green]✓ Authenticated with {provider}[/green]")
|
|
176
|
+
else:
|
|
177
|
+
console.print(f"\n[red]✗ Authentication failed[/red]")
|
|
178
|
+
raise typer.Exit(1)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@app.command()
|
|
182
|
+
def security(
|
|
183
|
+
action: str = typer.Argument("scan", help="Action: scan, fix, learn"),
|
|
184
|
+
path: str = typer.Option(".", "--path", "-p", help="Path to scan"),
|
|
185
|
+
auto_fix: bool = typer.Option(False, "--auto-fix", help="Automatically apply fixes"),
|
|
186
|
+
):
|
|
187
|
+
"""
|
|
188
|
+
Security agent for vulnerability scanning and remediation.
|
|
189
|
+
|
|
190
|
+
Examples:
|
|
191
|
+
mdxcode security scan
|
|
192
|
+
mdxcode security scan --path src/
|
|
193
|
+
mdxcode security fix --auto-fix
|
|
194
|
+
"""
|
|
195
|
+
from mdxcode.governance.security_agent import SecurityAgent
|
|
196
|
+
|
|
197
|
+
show_banner()
|
|
198
|
+
console.print(f"\n[cyan]MDx Code Security Agent[/cyan]\n")
|
|
199
|
+
|
|
200
|
+
agent = SecurityAgent(console)
|
|
201
|
+
|
|
202
|
+
if action == "scan":
|
|
203
|
+
asyncio.run(agent.scan(path))
|
|
204
|
+
elif action == "fix":
|
|
205
|
+
asyncio.run(agent.fix(path, auto_fix=auto_fix))
|
|
206
|
+
elif action == "learn":
|
|
207
|
+
asyncio.run(agent.learn())
|
|
208
|
+
else:
|
|
209
|
+
console.print(f"[red]Unknown action: {action}[/red]")
|
|
210
|
+
raise typer.Exit(1)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
@app.command()
|
|
214
|
+
def init():
|
|
215
|
+
"""
|
|
216
|
+
Initialize MDx Code in the current directory.
|
|
217
|
+
|
|
218
|
+
Creates a starter MDXCODE.md file with sensible defaults.
|
|
219
|
+
"""
|
|
220
|
+
show_banner()
|
|
221
|
+
|
|
222
|
+
mdxcode_path = Path("MDXCODE.md")
|
|
223
|
+
|
|
224
|
+
if mdxcode_path.exists():
|
|
225
|
+
console.print("[yellow]MDXCODE.md already exists. Skipping.[/yellow]")
|
|
226
|
+
raise typer.Exit()
|
|
227
|
+
|
|
228
|
+
from mdxcode.core.context_loader import create_starter_mdxcode
|
|
229
|
+
|
|
230
|
+
create_starter_mdxcode(mdxcode_path)
|
|
231
|
+
console.print("[green]✓ Created MDXCODE.md[/green]")
|
|
232
|
+
console.print("[dim]Edit this file to customize MDx Code for your project.[/dim]")
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@app.command()
|
|
236
|
+
def status():
|
|
237
|
+
"""
|
|
238
|
+
Show current MDx Code status and configuration.
|
|
239
|
+
"""
|
|
240
|
+
show_banner()
|
|
241
|
+
|
|
242
|
+
from mdxcode.core.context_loader import load_mdxcode_context
|
|
243
|
+
from mdxcode.models.auth import get_authenticated_providers
|
|
244
|
+
|
|
245
|
+
context = load_mdxcode_context()
|
|
246
|
+
providers = get_authenticated_providers()
|
|
247
|
+
|
|
248
|
+
console.print("\n[bold]Configuration[/bold]")
|
|
249
|
+
console.print(f" MDXCODE.md: {'[green]Found[/green]' if context else '[yellow]Not found[/yellow]'}")
|
|
250
|
+
if context:
|
|
251
|
+
console.print(f" Project: {context.project_name or 'Not set'}")
|
|
252
|
+
console.print(f" Domain: {context.domain or 'Not set'}")
|
|
253
|
+
console.print(f" Profile: {context.regulatory_profile or 'standard'}")
|
|
254
|
+
|
|
255
|
+
console.print("\n[bold]Authenticated Providers[/bold]")
|
|
256
|
+
if providers:
|
|
257
|
+
for provider in providers:
|
|
258
|
+
console.print(f" [green]✓[/green] {provider}")
|
|
259
|
+
else:
|
|
260
|
+
console.print(" [yellow]None. Run 'mdxcode auth <provider>' to authenticate.[/yellow]")
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def run():
|
|
264
|
+
"""Entry point for the CLI."""
|
|
265
|
+
app()
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
if __name__ == "__main__":
|
|
269
|
+
run()
|
mdxcode/core/__init__.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MDx Code Core
|
|
3
|
+
|
|
4
|
+
The fundamental building blocks:
|
|
5
|
+
- Agent Loop: The while loop that powers everything
|
|
6
|
+
- Session: State management for a single run
|
|
7
|
+
- Context Loader: Reading MDXCODE.md files
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from mdxcode.core.agent_loop import AgentLoop
|
|
11
|
+
from mdxcode.core.session import Session
|
|
12
|
+
from mdxcode.core.context_loader import (
|
|
13
|
+
MDXCodeContext,
|
|
14
|
+
load_mdxcode_context,
|
|
15
|
+
parse_mdxcode,
|
|
16
|
+
create_starter_mdxcode,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"AgentLoop",
|
|
21
|
+
"Session",
|
|
22
|
+
"MDXCodeContext",
|
|
23
|
+
"load_mdxcode_context",
|
|
24
|
+
"parse_mdxcode",
|
|
25
|
+
"create_starter_mdxcode",
|
|
26
|
+
]
|