mlx-code 0.0.7__tar.gz → 0.0.8__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.
- {mlx_code-0.0.7 → mlx_code-0.0.8}/PKG-INFO +88 -142
- {mlx_code-0.0.7 → mlx_code-0.0.8}/README.md +84 -141
- mlx_code-0.0.8/mlx_code/ledger.py +192 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code/log.py +4 -7
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code/main.py +83 -75
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code/pie.py +173 -62
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code.egg-info/PKG-INFO +88 -142
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code.egg-info/SOURCES.txt +1 -0
- mlx_code-0.0.8/mlx_code.egg-info/requires.txt +7 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/setup.py +5 -2
- mlx_code-0.0.7/mlx_code.egg-info/requires.txt +0 -4
- {mlx_code-0.0.7 → mlx_code-0.0.8}/LICENSE +0 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code/__init__.py +0 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code/symgraph.py +0 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code.egg-info/dependency_links.txt +0 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code.egg-info/entry_points.txt +0 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/mlx_code.egg-info/top_level.txt +0 -0
- {mlx_code-0.0.7 → mlx_code-0.0.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mlx-code
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.8
|
|
4
4
|
Summary: Coding Agent for Mac
|
|
5
5
|
Home-page: https://github.com/JosefAlbers/mlx-code
|
|
6
6
|
Author: J Joe
|
|
@@ -13,6 +13,9 @@ Requires-Dist: mlx-lm>=0.31.3
|
|
|
13
13
|
Requires-Dist: numpy
|
|
14
14
|
Requires-Dist: httpx
|
|
15
15
|
Requires-Dist: pydantic
|
|
16
|
+
Requires-Dist: GitPython
|
|
17
|
+
Requires-Dist: tree-sitter>=0.23.0
|
|
18
|
+
Requires-Dist: tree-sitter-python
|
|
16
19
|
Dynamic: author
|
|
17
20
|
Dynamic: author-email
|
|
18
21
|
Dynamic: description
|
|
@@ -34,7 +37,7 @@ Modern coding agents are like luxury apartments: impressive and shiny, but you d
|
|
|
34
37
|
|
|
35
38
|
I wanted a [backyard shed](https://poyo.co/note/20260202T150723/) for myself. Something I understand end to end, can break on purpose, and fix without filing a support ticket.
|
|
36
39
|
|
|
37
|
-
mlx-code is that shed. It’s deliberately minimal, extremely transparent, and designed around one core idea:
|
|
40
|
+
`mlx-code` is that shed. It’s deliberately minimal, extremely transparent, and designed around one core idea: [feedback loop](https://www.robert-glaser.de/what-if-iteration-is-all-we-need/) is the thing that matters, not the interface around it. The tighter and faster you can close the loop between intent and output, the better the work gets. Everything else is ceremony.
|
|
38
41
|
|
|
39
42
|
So the terminal stays the interface. Text in, text out. No full-screen TUI fighting your terminal emulator, no proprietary context format, no behavior that shifts between versions.
|
|
40
43
|
|
|
@@ -42,27 +45,36 @@ So the terminal stays the interface. Text in, text out. No full-screen TUI fight
|
|
|
42
45
|
|
|
43
46
|
## How It Works
|
|
44
47
|
|
|
45
|
-
mlx-code has two lightweight, loosely coupled pieces:
|
|
48
|
+
`mlx-code` has two lightweight, loosely coupled pieces:
|
|
46
49
|
|
|
47
|
-
- **main.py
|
|
48
|
-
- **pie.py**
|
|
50
|
+
- [**main.py**](https://github.com/JosefAlbers/mlx-code/blob/main/mlx_code/main.py): LLM server for Apple Silicon. It loads quantized models and exposes a standard OpenAI-compatible completions endpoint.
|
|
51
|
+
- [**pie.py**](https://github.com/JosefAlbers/mlx-code/blob/main/mlx_code/pie.py): Agentic harness based on Mario Zechner's awesome [pi](https://github.com/badlogic/pi-mono)).
|
|
52
|
+
- [**ledger.py**](https://github.com/JosefAlbers/mlx-code/blob/main/mlx_code/ledger.py): Git worktree manager that creates isolated branches and working directories for every agent (and sub‑agen) runs.
|
|
49
53
|
|
|
50
54
|
The CLI is intentionally boring and familiar:
|
|
51
55
|
|
|
52
|
-
- `mc
|
|
53
|
-
- `me
|
|
54
|
-
- `md
|
|
56
|
+
- `mc`: Local agent (LLM server ± harness)
|
|
57
|
+
- `me`: Harness. Connects to any compatible API (Claude, DeepSeek, Gemini, OpenAI, or local `mc`)
|
|
58
|
+
- `md`: Log viewer
|
|
55
59
|
|
|
56
|
-
Agentic work lives on a spectrum from tight, synchronous co-driving to loose, asynchronous delegation
|
|
60
|
+
Agentic work lives on a spectrum from tight, synchronous co-driving to loose, asynchronous delegation. The right tool for both ends is a loop that closes quickly, not a UI that abstracts it away.
|
|
61
|
+
|
|
62
|
+
Text streams compose. They pipe. They chain. They work the same way they did thirty years ago and will work thirty years from now.
|
|
63
|
+
|
|
64
|
+
That's the [constraint](https://jordanlord.co.uk/blog/3-constraints/) that shapes the whole tool.
|
|
57
65
|
|
|
58
66
|
## Features
|
|
59
67
|
|
|
60
|
-
- **
|
|
61
|
-
- **
|
|
62
|
-
- **
|
|
63
|
-
- **
|
|
68
|
+
- **Local or remote execution**: Run models locally via MLX or connect to Claude, Gemini, Codex, DeepSeek, or any OpenAI‑compatible endpoint.
|
|
69
|
+
- **Git worktree isolation**: Every agent run (and every sub‑agent) lives in its own git worktree and branch. Changes are automatically snapshotted (`commit_worktree`), and you can `cleanup_worktree` when done. This makes experimentation safe and fully reversible.
|
|
70
|
+
- **Autonomous sub‑agents**: Spawn isolated agents in fresh git worktrees. Each sub‑agent has its own conversation, tool set, and working directory. They can be used for parallel exploration, refactoring, or deep research without polluting the main context.
|
|
71
|
+
- **Symbol‑aware source inspection (`ReadTree`)**: Uses tree‑sitter to outline code or fetch exact definitions/calls for a symbol. Drastically reduces token usage compared to reading full files.
|
|
72
|
+
- **Built‑in tools**: Read, Write, Edit, Bash, Grep, Find, Ls, ReadTree, GetSkill, and Agent.
|
|
73
|
+
- **Prompt caching**: KV cache is saved to disk and reused across requests automatically.
|
|
74
|
+
- **REPL with `/commands`**: `/clear`, `/history`, `/tools`, `/branch`, `/abort`, `/help`.
|
|
75
|
+
- **TUI log viewer (`md`)**: Explore structured JSON logs with filtering by level, file, function, etc. Mark entries to export.
|
|
64
76
|
|
|
65
|
-
|
|
77
|
+
## Quick Start
|
|
66
78
|
|
|
67
79
|
Install via pip and launch the agent immediately:
|
|
68
80
|
|
|
@@ -73,37 +85,37 @@ mc
|
|
|
73
85
|
|
|
74
86
|
## Command Line Interfaces
|
|
75
87
|
|
|
76
|
-
### `mc
|
|
88
|
+
### `mc`: Local agent (LLM server ± harness)
|
|
77
89
|
|
|
78
90
|
```bash
|
|
79
|
-
#
|
|
91
|
+
# Start local MLX server and launch the default pie harness (Default)
|
|
80
92
|
mc
|
|
81
93
|
|
|
82
|
-
|
|
83
|
-
# Choose a different harness
|
|
94
|
+
# Choose a different harness (claude, gemini, codex, deepseek, pie)
|
|
84
95
|
mc --leash gemini
|
|
85
96
|
mc --leash codex
|
|
86
97
|
mc --leash claude
|
|
87
|
-
mc --leash pie
|
|
88
|
-
|
|
89
|
-
# Use a local model
|
|
90
|
-
mc --model mlx-community/Qwen3.5-4B-OptiQ-4bit
|
|
91
|
-
mc --leash none # server only, no harness
|
|
92
98
|
|
|
93
|
-
#
|
|
94
|
-
mc --
|
|
99
|
+
# Server only, no harness
|
|
100
|
+
mc --leash none
|
|
95
101
|
|
|
96
|
-
# Limit
|
|
102
|
+
# Limit allowed tools
|
|
97
103
|
mc --tools Ls ReadTree Edit
|
|
98
104
|
|
|
105
|
+
# Use a custom system prompt
|
|
106
|
+
mc --system "You are a helpful Python expert."
|
|
107
|
+
|
|
108
|
+
# Load skills from a directory
|
|
109
|
+
mc --skill ./my-skills
|
|
110
|
+
|
|
99
111
|
# Shell piping and chaining
|
|
100
112
|
echo "explain symgraph.py" | mc -d | cat - PLAN.md | mc
|
|
101
113
|
```
|
|
102
114
|
|
|
103
|
-
### `me
|
|
115
|
+
### `me`: Harness (connects to API)
|
|
104
116
|
|
|
105
117
|
```bash
|
|
106
|
-
#
|
|
118
|
+
# Connect to local server at 127.0.0.1:8000 (Default)
|
|
107
119
|
me
|
|
108
120
|
|
|
109
121
|
# Use a remote provider
|
|
@@ -112,33 +124,36 @@ me --api claude
|
|
|
112
124
|
me --api gemini
|
|
113
125
|
me --api codex
|
|
114
126
|
|
|
115
|
-
#
|
|
116
|
-
me --api deepseek --model deepseek-
|
|
127
|
+
# Specify model
|
|
128
|
+
me --api deepseek --model deepseek-v4-pro
|
|
117
129
|
|
|
118
|
-
# Point
|
|
130
|
+
# Point to a custom LLM API endpoint
|
|
119
131
|
me --url http://localhost:9000
|
|
132
|
+
|
|
133
|
+
# Load skills from a directory
|
|
134
|
+
me --skill ./my-skills
|
|
120
135
|
```
|
|
121
136
|
|
|
122
|
-
### `md
|
|
137
|
+
### `md`: TUI log viewer
|
|
123
138
|
|
|
124
139
|
View and filter structured JSON logs from any session.
|
|
125
140
|
|
|
126
141
|
```bash
|
|
127
142
|
md
|
|
128
|
-
md --filter lvl:10;file:main,pie
|
|
129
|
-
md --out picks
|
|
143
|
+
md --filter "lvl:10;file:main,pie" # show DEBUG logs from main.py and pie.py
|
|
144
|
+
md --out picks.json # write marked entries to a file
|
|
130
145
|
```
|
|
131
146
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
- `
|
|
135
|
-
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
147
|
+
Inside the TUI:
|
|
148
|
+
- `j/k` or ↑/↓ – navigate
|
|
149
|
+
- `o` – open detailed view for current entry
|
|
150
|
+
- `*` – highlight related entries (same file/function)
|
|
151
|
+
- `;` – set a live filter
|
|
152
|
+
- `h/l` – switch between request‑grouped tabs
|
|
153
|
+
- `v` – mark/unmark entry for export
|
|
154
|
+
- `q` – quit (marked entries printed or saved with `--out`)
|
|
140
155
|
|
|
141
|
-
<details><summary
|
|
156
|
+
<details><summary>Click to expand</summary><pre>
|
|
142
157
|
|
|
143
158
|
~/tmp> mc
|
|
144
159
|
|
|
@@ -173,102 +188,6 @@ Apache License 2.0 — see LICENSE for details.
|
|
|
173
188
|
≫
|
|
174
189
|
Bye!
|
|
175
190
|
|
|
176
|
-
~/tmp> gg **/*.py
|
|
177
|
-
|
|
178
|
-
staging: mlx_code/__init__.py
|
|
179
|
-
exists
|
|
180
|
-
staging: mlx_code/log.py
|
|
181
|
-
exists
|
|
182
|
-
staging: mlx_code/main.py
|
|
183
|
-
exists
|
|
184
|
-
staging: mlx_code/pie.py
|
|
185
|
-
exists
|
|
186
|
-
staging: mlx_code/symgraph.py
|
|
187
|
-
exists
|
|
188
|
-
staging: setup.py
|
|
189
|
-
exists
|
|
190
|
-
|
|
191
|
-
Diff preview:
|
|
192
|
-
mlx_code/__init__.py | 4 +
|
|
193
|
-
mlx_code/log.py | 771 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
194
|
-
mlx_code/main.py | 1597 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
195
|
-
mlx_code/pie.py | 1994 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
196
|
-
mlx_code/symgraph.py | 483 +++++++++++++++++++++++++++++++++++
|
|
197
|
-
setup.py | 18 ++
|
|
198
|
-
6 files changed, 4867 insertions(+)
|
|
199
|
-
|
|
200
|
-
Show per-file diffs? [s=skip]: y
|
|
201
|
-
|
|
202
|
-
--- mlx_code/__init__.py ---
|
|
203
|
-
@@ -0,0 +1,4 @@
|
|
204
|
-
+from .main import serve, run
|
|
205
|
-
+from .pie import harness
|
|
206
|
-
+
|
|
207
|
-
+__all__ = ["serve", "run", "harness"]
|
|
208
|
-
--- mlx_code/log.py ---
|
|
209
|
-
... ( 772 lines total, truncated)
|
|
210
|
-
+ if args.out:
|
|
211
|
-
+ with open(args.out, "w", encoding="utf-8") as f:
|
|
212
|
-
+ for idx in sorted(marked):
|
|
213
|
-
+ f.write(json.dumps(logs[idx]) + "\n")
|
|
214
|
-
+ else:
|
|
215
|
-
+ for idx in sorted(marked):
|
|
216
|
-
+ print(json.dumps(logs[idx]))
|
|
217
|
-
+
|
|
218
|
-
+if __name__ == "__main__":
|
|
219
|
-
+ main()
|
|
220
|
-
--- mlx_code/main.py ---
|
|
221
|
-
... ( 1598 lines total, truncated)
|
|
222
|
-
+ model=args.model,
|
|
223
|
-
+ system=system,
|
|
224
|
-
+ tools=args.tools,
|
|
225
|
-
+ skill=args.skill,
|
|
226
|
-
+ leash_args=leash_args,
|
|
227
|
-
+ )
|
|
228
|
-
+
|
|
229
|
-
+if __name__ == "__main__":
|
|
230
|
-
+ main()
|
|
231
|
-
+# }}}ser
|
|
232
|
-
--- mlx_code/pie.py ---
|
|
233
|
-
... ( 1995 lines total, truncated)
|
|
234
|
-
+ cwd=args.cwd,
|
|
235
|
-
+ model=model,
|
|
236
|
-
+ base_url=url,
|
|
237
|
-
+ tools=tools,
|
|
238
|
-
+ sdir=args.skill,
|
|
239
|
-
+ api_key=api_key
|
|
240
|
-
+ )
|
|
241
|
-
+
|
|
242
|
-
+if __name__ == "__main__":
|
|
243
|
-
+ main()
|
|
244
|
-
--- mlx_code/symgraph.py ---
|
|
245
|
-
... ( 485 lines total, truncated)
|
|
246
|
-
+ B,H=search_symbols(A.symbols,C,lang_ext=E,include_references=not A.no_references,include_context=A.context,warn_skipped=A.warn_skipped);G=_C
|
|
247
|
-
+ for(I,J)in H.items():
|
|
248
|
-
+ if J is Capability.NONE:_warn(f"'{I}': no matching identifiers found (grammar may be unsupported for this file type)");G=_E
|
|
249
|
-
+ if A.kinds:B=[B for B in B if B.kind in A.kinds]
|
|
250
|
-
+ if A.json:print(json.dumps([A.as_dict()for A in B],indent=2))
|
|
251
|
-
+ else:print_usages(B,F)
|
|
252
|
-
+ if G and not B:return 2
|
|
253
|
-
+ return 0
|
|
254
|
-
+if __name__=='__main__':sys.exit(main())
|
|
255
|
-
|
|
256
|
-
--- setup.py ---
|
|
257
|
-
... ( 19 lines total, truncated)
|
|
258
|
-
+ version="0.0.7",
|
|
259
|
-
+ readme="README.md",
|
|
260
|
-
+ description="Coding Agent for Mac",
|
|
261
|
-
+ long_description=open("README.md").read(),
|
|
262
|
-
+ long_description_content_type="text/markdown",
|
|
263
|
-
+ python_requires=">=3.12.8",
|
|
264
|
-
+ install_requires=["mlx-lm>=0.31.3", "numpy", "httpx", "pydantic"],
|
|
265
|
-
+ packages=find_packages(),
|
|
266
|
-
+ entry_points={"console_scripts": ["mc=mlx_code.main:main", "md=mlx_code.log:main", "me=mlx_code.pie:main"]},
|
|
267
|
-
+)
|
|
268
|
-
|
|
269
|
-
read> v0.0.7
|
|
270
|
-
Saved snapshot d2ab186ee5c02f0589552ffac658c4f4a284b36c
|
|
271
|
-
|
|
272
191
|
~/tmp> mc
|
|
273
192
|
|
|
274
193
|
pie REPL • type /help for commands, Ctrl-D or 'exit' to quit.
|
|
@@ -476,7 +395,7 @@ Apache License 2.0 — see LICENSE for details.
|
|
|
476
395
|
|
|
477
396
|
The tool is particularly useful for developers who need precise, language-aware code navigation and search capabilities without relying on IDE-specific features.
|
|
478
397
|
|
|
479
|
-
~/tmp>
|
|
398
|
+
~/tmp> md -o test
|
|
480
399
|
|
|
481
400
|
┌─ logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐┌─ detail ──────────────────────────────────────────────────────────────────────────┐
|
|
482
401
|
│ TIME LVL FILE FUNC MESSAGE …││ time : 2026-05-09T17:35:17.021887+00:00 │
|
|
@@ -606,6 +525,33 @@ Apache License 2.0 — see LICENSE for details.
|
|
|
606
525
|
|
|
607
526
|
**Bottom line:** `ReadTree` is a sharp tool for context efficiency — it can slash input size dramatically for tasks like code explanation, and the smaller context window often allows the model to think faster and more focused.
|
|
608
527
|
|
|
609
|
-
~/tmp[1 jobs]> hx --capture
|
|
610
|
-
|
|
611
528
|
</pre></details><br>
|
|
529
|
+
|
|
530
|
+
## Tools Overview
|
|
531
|
+
|
|
532
|
+
| Tool | Description |
|
|
533
|
+
|-------------|-------------|
|
|
534
|
+
| `Read` | Read a file (supports offset/limit for large files). |
|
|
535
|
+
| `Write` | Create or overwrite a file. |
|
|
536
|
+
| `Edit` | Replace a unique string in a file. |
|
|
537
|
+
| `Bash` | Run a shell command (timeout, stdout+stderr). |
|
|
538
|
+
| `Grep` | Search file contents with regex, respects `.gitignore`. |
|
|
539
|
+
| `Find` | Find files/directories by name pattern. |
|
|
540
|
+
| `Ls` | List directory contents (respects `.gitignore`). |
|
|
541
|
+
| `ReadTree` | Outline a file/directory or fetch exact bodies of definitions/calls. Uses tree‑sitter and works for many languages (Python, JS/TS, Go, Rust, Java, C/C++, C#, Ruby, etc.). |
|
|
542
|
+
| `GetSkill` | Retrieve full instructions for a named skill (from `--skill` directory). |
|
|
543
|
+
| `Agent` | Spawn an autonomous sub‑agent in an isolated git worktree. For parallel tasks, deep research, or safe experimentation. |
|
|
544
|
+
|
|
545
|
+
## Skills
|
|
546
|
+
|
|
547
|
+
Skills are directories containing a `SKILL.md` file with frontmatter (`name:` and `description:`). Place them in a directory and pass `--skill <dir>`. The agent will list available skills and can load their full instructions via `GetSkill`. This keeps the system prompt lean while allowing on‑demand detailed guidance.
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
## Credits
|
|
551
|
+
|
|
552
|
+
- `main.py`: Built on [mlx](https://github.com/ml-explore/mlx) and [mlx-lm](https://github.com/ml-explore/mlx-lm) by Apple.
|
|
553
|
+
- `pie.py`: Adapted from [pi](https://github.com/badlogic/pi-mono) by Mario Zechner (MIT License).
|
|
554
|
+
|
|
555
|
+
## Licence
|
|
556
|
+
|
|
557
|
+
Apache License 2.0 — see LICENSE for details.
|
|
@@ -8,7 +8,7 @@ Modern coding agents are like luxury apartments: impressive and shiny, but you d
|
|
|
8
8
|
|
|
9
9
|
I wanted a [backyard shed](https://poyo.co/note/20260202T150723/) for myself. Something I understand end to end, can break on purpose, and fix without filing a support ticket.
|
|
10
10
|
|
|
11
|
-
mlx-code is that shed. It’s deliberately minimal, extremely transparent, and designed around one core idea:
|
|
11
|
+
`mlx-code` is that shed. It’s deliberately minimal, extremely transparent, and designed around one core idea: [feedback loop](https://www.robert-glaser.de/what-if-iteration-is-all-we-need/) is the thing that matters, not the interface around it. The tighter and faster you can close the loop between intent and output, the better the work gets. Everything else is ceremony.
|
|
12
12
|
|
|
13
13
|
So the terminal stays the interface. Text in, text out. No full-screen TUI fighting your terminal emulator, no proprietary context format, no behavior that shifts between versions.
|
|
14
14
|
|
|
@@ -16,27 +16,36 @@ So the terminal stays the interface. Text in, text out. No full-screen TUI fight
|
|
|
16
16
|
|
|
17
17
|
## How It Works
|
|
18
18
|
|
|
19
|
-
mlx-code has two lightweight, loosely coupled pieces:
|
|
19
|
+
`mlx-code` has two lightweight, loosely coupled pieces:
|
|
20
20
|
|
|
21
|
-
- **main.py
|
|
22
|
-
- **pie.py**
|
|
21
|
+
- [**main.py**](https://github.com/JosefAlbers/mlx-code/blob/main/mlx_code/main.py): LLM server for Apple Silicon. It loads quantized models and exposes a standard OpenAI-compatible completions endpoint.
|
|
22
|
+
- [**pie.py**](https://github.com/JosefAlbers/mlx-code/blob/main/mlx_code/pie.py): Agentic harness based on Mario Zechner's awesome [pi](https://github.com/badlogic/pi-mono)).
|
|
23
|
+
- [**ledger.py**](https://github.com/JosefAlbers/mlx-code/blob/main/mlx_code/ledger.py): Git worktree manager that creates isolated branches and working directories for every agent (and sub‑agen) runs.
|
|
23
24
|
|
|
24
25
|
The CLI is intentionally boring and familiar:
|
|
25
26
|
|
|
26
|
-
- `mc
|
|
27
|
-
- `me
|
|
28
|
-
- `md
|
|
27
|
+
- `mc`: Local agent (LLM server ± harness)
|
|
28
|
+
- `me`: Harness. Connects to any compatible API (Claude, DeepSeek, Gemini, OpenAI, or local `mc`)
|
|
29
|
+
- `md`: Log viewer
|
|
29
30
|
|
|
30
|
-
Agentic work lives on a spectrum from tight, synchronous co-driving to loose, asynchronous delegation
|
|
31
|
+
Agentic work lives on a spectrum from tight, synchronous co-driving to loose, asynchronous delegation. The right tool for both ends is a loop that closes quickly, not a UI that abstracts it away.
|
|
32
|
+
|
|
33
|
+
Text streams compose. They pipe. They chain. They work the same way they did thirty years ago and will work thirty years from now.
|
|
34
|
+
|
|
35
|
+
That's the [constraint](https://jordanlord.co.uk/blog/3-constraints/) that shapes the whole tool.
|
|
31
36
|
|
|
32
37
|
## Features
|
|
33
38
|
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
39
|
+
- **Local or remote execution**: Run models locally via MLX or connect to Claude, Gemini, Codex, DeepSeek, or any OpenAI‑compatible endpoint.
|
|
40
|
+
- **Git worktree isolation**: Every agent run (and every sub‑agent) lives in its own git worktree and branch. Changes are automatically snapshotted (`commit_worktree`), and you can `cleanup_worktree` when done. This makes experimentation safe and fully reversible.
|
|
41
|
+
- **Autonomous sub‑agents**: Spawn isolated agents in fresh git worktrees. Each sub‑agent has its own conversation, tool set, and working directory. They can be used for parallel exploration, refactoring, or deep research without polluting the main context.
|
|
42
|
+
- **Symbol‑aware source inspection (`ReadTree`)**: Uses tree‑sitter to outline code or fetch exact definitions/calls for a symbol. Drastically reduces token usage compared to reading full files.
|
|
43
|
+
- **Built‑in tools**: Read, Write, Edit, Bash, Grep, Find, Ls, ReadTree, GetSkill, and Agent.
|
|
44
|
+
- **Prompt caching**: KV cache is saved to disk and reused across requests automatically.
|
|
45
|
+
- **REPL with `/commands`**: `/clear`, `/history`, `/tools`, `/branch`, `/abort`, `/help`.
|
|
46
|
+
- **TUI log viewer (`md`)**: Explore structured JSON logs with filtering by level, file, function, etc. Mark entries to export.
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
## Quick Start
|
|
40
49
|
|
|
41
50
|
Install via pip and launch the agent immediately:
|
|
42
51
|
|
|
@@ -47,37 +56,37 @@ mc
|
|
|
47
56
|
|
|
48
57
|
## Command Line Interfaces
|
|
49
58
|
|
|
50
|
-
### `mc
|
|
59
|
+
### `mc`: Local agent (LLM server ± harness)
|
|
51
60
|
|
|
52
61
|
```bash
|
|
53
|
-
#
|
|
62
|
+
# Start local MLX server and launch the default pie harness (Default)
|
|
54
63
|
mc
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
# Choose a different harness
|
|
65
|
+
# Choose a different harness (claude, gemini, codex, deepseek, pie)
|
|
58
66
|
mc --leash gemini
|
|
59
67
|
mc --leash codex
|
|
60
68
|
mc --leash claude
|
|
61
|
-
mc --leash pie
|
|
62
|
-
|
|
63
|
-
# Use a local model
|
|
64
|
-
mc --model mlx-community/Qwen3.5-4B-OptiQ-4bit
|
|
65
|
-
mc --leash none # server only, no harness
|
|
66
69
|
|
|
67
|
-
#
|
|
68
|
-
mc --
|
|
70
|
+
# Server only, no harness
|
|
71
|
+
mc --leash none
|
|
69
72
|
|
|
70
|
-
# Limit
|
|
73
|
+
# Limit allowed tools
|
|
71
74
|
mc --tools Ls ReadTree Edit
|
|
72
75
|
|
|
76
|
+
# Use a custom system prompt
|
|
77
|
+
mc --system "You are a helpful Python expert."
|
|
78
|
+
|
|
79
|
+
# Load skills from a directory
|
|
80
|
+
mc --skill ./my-skills
|
|
81
|
+
|
|
73
82
|
# Shell piping and chaining
|
|
74
83
|
echo "explain symgraph.py" | mc -d | cat - PLAN.md | mc
|
|
75
84
|
```
|
|
76
85
|
|
|
77
|
-
### `me
|
|
86
|
+
### `me`: Harness (connects to API)
|
|
78
87
|
|
|
79
88
|
```bash
|
|
80
|
-
#
|
|
89
|
+
# Connect to local server at 127.0.0.1:8000 (Default)
|
|
81
90
|
me
|
|
82
91
|
|
|
83
92
|
# Use a remote provider
|
|
@@ -86,33 +95,36 @@ me --api claude
|
|
|
86
95
|
me --api gemini
|
|
87
96
|
me --api codex
|
|
88
97
|
|
|
89
|
-
#
|
|
90
|
-
me --api deepseek --model deepseek-
|
|
98
|
+
# Specify model
|
|
99
|
+
me --api deepseek --model deepseek-v4-pro
|
|
91
100
|
|
|
92
|
-
# Point
|
|
101
|
+
# Point to a custom LLM API endpoint
|
|
93
102
|
me --url http://localhost:9000
|
|
103
|
+
|
|
104
|
+
# Load skills from a directory
|
|
105
|
+
me --skill ./my-skills
|
|
94
106
|
```
|
|
95
107
|
|
|
96
|
-
### `md
|
|
108
|
+
### `md`: TUI log viewer
|
|
97
109
|
|
|
98
110
|
View and filter structured JSON logs from any session.
|
|
99
111
|
|
|
100
112
|
```bash
|
|
101
113
|
md
|
|
102
|
-
md --filter lvl:10;file:main,pie
|
|
103
|
-
md --out picks
|
|
114
|
+
md --filter "lvl:10;file:main,pie" # show DEBUG logs from main.py and pie.py
|
|
115
|
+
md --out picks.json # write marked entries to a file
|
|
104
116
|
```
|
|
105
117
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- `
|
|
109
|
-
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
Inside the TUI:
|
|
119
|
+
- `j/k` or ↑/↓ – navigate
|
|
120
|
+
- `o` – open detailed view for current entry
|
|
121
|
+
- `*` – highlight related entries (same file/function)
|
|
122
|
+
- `;` – set a live filter
|
|
123
|
+
- `h/l` – switch between request‑grouped tabs
|
|
124
|
+
- `v` – mark/unmark entry for export
|
|
125
|
+
- `q` – quit (marked entries printed or saved with `--out`)
|
|
114
126
|
|
|
115
|
-
<details><summary
|
|
127
|
+
<details><summary>Click to expand</summary><pre>
|
|
116
128
|
|
|
117
129
|
~/tmp> mc
|
|
118
130
|
|
|
@@ -147,102 +159,6 @@ Apache License 2.0 — see LICENSE for details.
|
|
|
147
159
|
≫
|
|
148
160
|
Bye!
|
|
149
161
|
|
|
150
|
-
~/tmp> gg **/*.py
|
|
151
|
-
|
|
152
|
-
staging: mlx_code/__init__.py
|
|
153
|
-
exists
|
|
154
|
-
staging: mlx_code/log.py
|
|
155
|
-
exists
|
|
156
|
-
staging: mlx_code/main.py
|
|
157
|
-
exists
|
|
158
|
-
staging: mlx_code/pie.py
|
|
159
|
-
exists
|
|
160
|
-
staging: mlx_code/symgraph.py
|
|
161
|
-
exists
|
|
162
|
-
staging: setup.py
|
|
163
|
-
exists
|
|
164
|
-
|
|
165
|
-
Diff preview:
|
|
166
|
-
mlx_code/__init__.py | 4 +
|
|
167
|
-
mlx_code/log.py | 771 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
168
|
-
mlx_code/main.py | 1597 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
169
|
-
mlx_code/pie.py | 1994 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
170
|
-
mlx_code/symgraph.py | 483 +++++++++++++++++++++++++++++++++++
|
|
171
|
-
setup.py | 18 ++
|
|
172
|
-
6 files changed, 4867 insertions(+)
|
|
173
|
-
|
|
174
|
-
Show per-file diffs? [s=skip]: y
|
|
175
|
-
|
|
176
|
-
--- mlx_code/__init__.py ---
|
|
177
|
-
@@ -0,0 +1,4 @@
|
|
178
|
-
+from .main import serve, run
|
|
179
|
-
+from .pie import harness
|
|
180
|
-
+
|
|
181
|
-
+__all__ = ["serve", "run", "harness"]
|
|
182
|
-
--- mlx_code/log.py ---
|
|
183
|
-
... ( 772 lines total, truncated)
|
|
184
|
-
+ if args.out:
|
|
185
|
-
+ with open(args.out, "w", encoding="utf-8") as f:
|
|
186
|
-
+ for idx in sorted(marked):
|
|
187
|
-
+ f.write(json.dumps(logs[idx]) + "\n")
|
|
188
|
-
+ else:
|
|
189
|
-
+ for idx in sorted(marked):
|
|
190
|
-
+ print(json.dumps(logs[idx]))
|
|
191
|
-
+
|
|
192
|
-
+if __name__ == "__main__":
|
|
193
|
-
+ main()
|
|
194
|
-
--- mlx_code/main.py ---
|
|
195
|
-
... ( 1598 lines total, truncated)
|
|
196
|
-
+ model=args.model,
|
|
197
|
-
+ system=system,
|
|
198
|
-
+ tools=args.tools,
|
|
199
|
-
+ skill=args.skill,
|
|
200
|
-
+ leash_args=leash_args,
|
|
201
|
-
+ )
|
|
202
|
-
+
|
|
203
|
-
+if __name__ == "__main__":
|
|
204
|
-
+ main()
|
|
205
|
-
+# }}}ser
|
|
206
|
-
--- mlx_code/pie.py ---
|
|
207
|
-
... ( 1995 lines total, truncated)
|
|
208
|
-
+ cwd=args.cwd,
|
|
209
|
-
+ model=model,
|
|
210
|
-
+ base_url=url,
|
|
211
|
-
+ tools=tools,
|
|
212
|
-
+ sdir=args.skill,
|
|
213
|
-
+ api_key=api_key
|
|
214
|
-
+ )
|
|
215
|
-
+
|
|
216
|
-
+if __name__ == "__main__":
|
|
217
|
-
+ main()
|
|
218
|
-
--- mlx_code/symgraph.py ---
|
|
219
|
-
... ( 485 lines total, truncated)
|
|
220
|
-
+ B,H=search_symbols(A.symbols,C,lang_ext=E,include_references=not A.no_references,include_context=A.context,warn_skipped=A.warn_skipped);G=_C
|
|
221
|
-
+ for(I,J)in H.items():
|
|
222
|
-
+ if J is Capability.NONE:_warn(f"'{I}': no matching identifiers found (grammar may be unsupported for this file type)");G=_E
|
|
223
|
-
+ if A.kinds:B=[B for B in B if B.kind in A.kinds]
|
|
224
|
-
+ if A.json:print(json.dumps([A.as_dict()for A in B],indent=2))
|
|
225
|
-
+ else:print_usages(B,F)
|
|
226
|
-
+ if G and not B:return 2
|
|
227
|
-
+ return 0
|
|
228
|
-
+if __name__=='__main__':sys.exit(main())
|
|
229
|
-
|
|
230
|
-
--- setup.py ---
|
|
231
|
-
... ( 19 lines total, truncated)
|
|
232
|
-
+ version="0.0.7",
|
|
233
|
-
+ readme="README.md",
|
|
234
|
-
+ description="Coding Agent for Mac",
|
|
235
|
-
+ long_description=open("README.md").read(),
|
|
236
|
-
+ long_description_content_type="text/markdown",
|
|
237
|
-
+ python_requires=">=3.12.8",
|
|
238
|
-
+ install_requires=["mlx-lm>=0.31.3", "numpy", "httpx", "pydantic"],
|
|
239
|
-
+ packages=find_packages(),
|
|
240
|
-
+ entry_points={"console_scripts": ["mc=mlx_code.main:main", "md=mlx_code.log:main", "me=mlx_code.pie:main"]},
|
|
241
|
-
+)
|
|
242
|
-
|
|
243
|
-
read> v0.0.7
|
|
244
|
-
Saved snapshot d2ab186ee5c02f0589552ffac658c4f4a284b36c
|
|
245
|
-
|
|
246
162
|
~/tmp> mc
|
|
247
163
|
|
|
248
164
|
pie REPL • type /help for commands, Ctrl-D or 'exit' to quit.
|
|
@@ -450,7 +366,7 @@ Apache License 2.0 — see LICENSE for details.
|
|
|
450
366
|
|
|
451
367
|
The tool is particularly useful for developers who need precise, language-aware code navigation and search capabilities without relying on IDE-specific features.
|
|
452
368
|
|
|
453
|
-
~/tmp>
|
|
369
|
+
~/tmp> md -o test
|
|
454
370
|
|
|
455
371
|
┌─ logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐┌─ detail ──────────────────────────────────────────────────────────────────────────┐
|
|
456
372
|
│ TIME LVL FILE FUNC MESSAGE …││ time : 2026-05-09T17:35:17.021887+00:00 │
|
|
@@ -580,6 +496,33 @@ Apache License 2.0 — see LICENSE for details.
|
|
|
580
496
|
|
|
581
497
|
**Bottom line:** `ReadTree` is a sharp tool for context efficiency — it can slash input size dramatically for tasks like code explanation, and the smaller context window often allows the model to think faster and more focused.
|
|
582
498
|
|
|
583
|
-
~/tmp[1 jobs]> hx --capture
|
|
584
|
-
|
|
585
499
|
</pre></details><br>
|
|
500
|
+
|
|
501
|
+
## Tools Overview
|
|
502
|
+
|
|
503
|
+
| Tool | Description |
|
|
504
|
+
|-------------|-------------|
|
|
505
|
+
| `Read` | Read a file (supports offset/limit for large files). |
|
|
506
|
+
| `Write` | Create or overwrite a file. |
|
|
507
|
+
| `Edit` | Replace a unique string in a file. |
|
|
508
|
+
| `Bash` | Run a shell command (timeout, stdout+stderr). |
|
|
509
|
+
| `Grep` | Search file contents with regex, respects `.gitignore`. |
|
|
510
|
+
| `Find` | Find files/directories by name pattern. |
|
|
511
|
+
| `Ls` | List directory contents (respects `.gitignore`). |
|
|
512
|
+
| `ReadTree` | Outline a file/directory or fetch exact bodies of definitions/calls. Uses tree‑sitter and works for many languages (Python, JS/TS, Go, Rust, Java, C/C++, C#, Ruby, etc.). |
|
|
513
|
+
| `GetSkill` | Retrieve full instructions for a named skill (from `--skill` directory). |
|
|
514
|
+
| `Agent` | Spawn an autonomous sub‑agent in an isolated git worktree. For parallel tasks, deep research, or safe experimentation. |
|
|
515
|
+
|
|
516
|
+
## Skills
|
|
517
|
+
|
|
518
|
+
Skills are directories containing a `SKILL.md` file with frontmatter (`name:` and `description:`). Place them in a directory and pass `--skill <dir>`. The agent will list available skills and can load their full instructions via `GetSkill`. This keeps the system prompt lean while allowing on‑demand detailed guidance.
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
## Credits
|
|
522
|
+
|
|
523
|
+
- `main.py`: Built on [mlx](https://github.com/ml-explore/mlx) and [mlx-lm](https://github.com/ml-explore/mlx-lm) by Apple.
|
|
524
|
+
- `pie.py`: Adapted from [pi](https://github.com/badlogic/pi-mono) by Mario Zechner (MIT License).
|
|
525
|
+
|
|
526
|
+
## Licence
|
|
527
|
+
|
|
528
|
+
Apache License 2.0 — see LICENSE for details.
|