miii-agent 0.1.0 → 0.1.1
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.
- package/README.md +139 -53
- package/dist/cli.js +42 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,123 @@
|
|
|
1
1
|
# miii
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Your code never leaves your machine. No API keys. No cloud. No bullshit.
|
|
4
4
|
|
|
5
|
-
miii
|
|
5
|
+
**miii** is a local-first AI coding agent that lives in your terminal. Powered by [Ollama](https://ollama.com), it reads your code, writes features, runs tests, and fixes bugs — entirely on your hardware, at native speed.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/miii-agent)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Demo
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Why miii?
|
|
20
|
+
|
|
21
|
+
Most AI coding tools are wrappers around cloud APIs. They're slow, expensive, and send your private code to someone else's server.
|
|
22
|
+
|
|
23
|
+
miii is different:
|
|
24
|
+
|
|
25
|
+
- **Local-first** — Powered by Ollama. Your code stays on your disk, period.
|
|
26
|
+
- **Zero ceremony** — No API keys. No billing. No accounts. Just `miii`.
|
|
27
|
+
- **Actually agentic** — miii doesn't just chat. It decomposes problems, calls tools, and verifies results like an engineer would.
|
|
28
|
+
- **Fast** — No network round-trips. Response time is limited by your GPU, not a CDN.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
### Prerequisites
|
|
35
|
+
|
|
36
|
+
- **Node.js** ≥ 18
|
|
37
|
+
- **Ollama** running locally — [install here](https://ollama.com/download)
|
|
38
|
+
- A coding model pulled locally:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
ollama pull qwen2.5-coder:14b
|
|
42
|
+
# or any model you prefer
|
|
43
|
+
ollama pull deepseek-coder-v2
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Install miii
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install -g miii-agent
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Launch
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
miii
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
That's it.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
Once inside the TUI, just type naturally:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
> refactor the auth module to use async/await
|
|
68
|
+
> @src/server.ts add rate limiting to all POST routes
|
|
69
|
+
> why are my tests failing in utils/parser.ts
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Keyboard Shortcuts
|
|
73
|
+
|
|
74
|
+
| Key | Action |
|
|
75
|
+
|-----|--------|
|
|
76
|
+
| `Enter` | Send prompt |
|
|
77
|
+
| `@filename` | Attach file to context |
|
|
78
|
+
| `/models` | Switch active Ollama model |
|
|
79
|
+
| `/clear` | Reset conversation history |
|
|
80
|
+
| `Esc` | Stop current generation or tool run |
|
|
81
|
+
| `Ctrl+C` | Quit |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
Settings live in `~/.miii/config.json` and are created on first run.
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"model": "qwen2.5-coder:14b",
|
|
92
|
+
"ollamaHost": "http://localhost:11434",
|
|
93
|
+
"effort": "medium"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
| Field | Description | Values |
|
|
98
|
+
|-------|-------------|--------|
|
|
99
|
+
| `model` | Default Ollama model | any `ollama list` model |
|
|
100
|
+
| `ollamaHost` | Ollama API endpoint | URL string |
|
|
101
|
+
| `effort` | Controls temperature & limits | `low` \| `medium` \| `high` |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Capabilities
|
|
106
|
+
|
|
107
|
+
miii ships with a built-in tool suite the agent can invoke autonomously:
|
|
108
|
+
|
|
109
|
+
| Tool | What it does |
|
|
110
|
+
|------|-------------|
|
|
111
|
+
| `read_file` | Read any file in your workspace |
|
|
112
|
+
| `write_file` | Create new files |
|
|
113
|
+
| `edit_file` | Precise string-level edits (no rewrites) |
|
|
114
|
+
| `glob` | Pattern-match files across the project |
|
|
115
|
+
| `grep` | Regex search across files |
|
|
116
|
+
| `run_bash` | Execute shell commands |
|
|
117
|
+
|
|
118
|
+
Every sensitive operation is gated by a permission system — you approve what the agent can touch.
|
|
119
|
+
|
|
120
|
+
---
|
|
6
121
|
|
|
7
122
|
## Architecture
|
|
8
123
|
|
|
@@ -49,65 +164,36 @@ graph TD
|
|
|
49
164
|
App -.->|"reads"| Config
|
|
50
165
|
```
|
|
51
166
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Most AI agents are wrappers around cloud APIs. They are slow, expensive, and a privacy nightmare. miii is different:
|
|
55
|
-
|
|
56
|
-
1. Local-First: Powered by Ollama. Your code stays on your disk.
|
|
57
|
-
2. Zero Ceremony: No API keys. No billing. Just run miii and start coding.
|
|
58
|
-
3. Engineering Mindset: miii doesn't just "chat". It treats every request as a bug, feature, or fix. It decomposes problems, executes tools, and verifies results.
|
|
59
|
-
|
|
60
|
-
## Project Status
|
|
61
|
-
|
|
62
|
-
This project is currently an MVP designed to demonstrate and refine basic AI coding skills. I am refurbishing older implementations and experimenting with the agent loop. Feel free to fork, modify, or do whatever you want with this codebase.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
## Capabilities
|
|
66
|
-
|
|
67
|
-
miii is equipped with a suite of tools to interact with your workspace:
|
|
68
|
-
|
|
69
|
-
- File System: read_file, write_file, edit_file (precise string replacement).
|
|
70
|
-
- Discovery: glob (pattern matching), grep (regex search).
|
|
71
|
-
- Execution: run_bash (shell command execution).
|
|
72
|
-
|
|
73
|
-
Every sensitive operation is gated by a permission system. You decide what the agent can touch.
|
|
167
|
+
---
|
|
74
168
|
|
|
75
|
-
##
|
|
76
|
-
|
|
77
|
-
### 1. Prerequisites
|
|
78
|
-
- Node.js 18+
|
|
79
|
-
- Ollama (running locally via ollama serve)
|
|
80
|
-
- A coder model (e.g., ollama pull qwen2.5-coder:14b)
|
|
169
|
+
## Development
|
|
81
170
|
|
|
82
|
-
|
|
83
|
-
|
|
171
|
+
```bash
|
|
172
|
+
git clone https://github.com/maruakshay/miii-cli.git
|
|
173
|
+
cd miii-cli
|
|
174
|
+
npm install
|
|
175
|
+
npm run dev
|
|
176
|
+
```
|
|
84
177
|
|
|
85
|
-
|
|
86
|
-
|
|
178
|
+
```bash
|
|
179
|
+
npm run build # production build
|
|
180
|
+
npm run start # run built output
|
|
181
|
+
```
|
|
87
182
|
|
|
88
|
-
|
|
183
|
+
---
|
|
89
184
|
|
|
90
|
-
|
|
91
|
-
- @file: Inline a file's content into the context.
|
|
92
|
-
- /models: Switch your active Ollama model.
|
|
93
|
-
- /clear: Reset conversation history.
|
|
94
|
-
- Esc: Stop the current generation or tool execution.
|
|
95
|
-
- Ctrl+C: Quit.
|
|
185
|
+
## Project Status
|
|
96
186
|
|
|
97
|
-
|
|
187
|
+
MVP. Core agent loop works. Actively refining tool execution, streaming, and the permission model. PRs welcome — fork it, break it, improve it.
|
|
98
188
|
|
|
99
|
-
|
|
100
|
-
- model: Your default LLM.
|
|
101
|
-
- ollamaHost: Your Ollama API endpoint.
|
|
102
|
-
- effort: Tuning for temperature and limits (low | medium | high).
|
|
189
|
+
---
|
|
103
190
|
|
|
191
|
+
## License
|
|
104
192
|
|
|
105
|
-
|
|
193
|
+
MIT © [maruakshay](https://github.com/maruakshay)
|
|
106
194
|
|
|
107
|
-
|
|
108
|
-
cd miii-cli
|
|
109
|
-
npm install
|
|
110
|
-
npm run dev
|
|
195
|
+
---
|
|
111
196
|
|
|
112
|
-
|
|
113
|
-
|
|
197
|
+
<p align="center">
|
|
198
|
+
Built for engineers who'd rather own their tools than rent them.
|
|
199
|
+
</p>
|
package/dist/cli.js
CHANGED
|
@@ -1726,6 +1726,41 @@ function useKeyboard(opts) {
|
|
|
1726
1726
|
});
|
|
1727
1727
|
}
|
|
1728
1728
|
|
|
1729
|
+
// src/updateCheck.ts
|
|
1730
|
+
import { createRequire } from "module";
|
|
1731
|
+
var require2 = createRequire(import.meta.url);
|
|
1732
|
+
var PKG_NAME = "miii-agent";
|
|
1733
|
+
function currentVersion() {
|
|
1734
|
+
try {
|
|
1735
|
+
return require2("../package.json").version;
|
|
1736
|
+
} catch {
|
|
1737
|
+
return "";
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
function newerVersion(current, latest) {
|
|
1741
|
+
const parse = (v) => v.replace(/^v/, "").split(".").map(Number);
|
|
1742
|
+
const [ca, cb, cc] = parse(current);
|
|
1743
|
+
const [la, lb, lc] = parse(latest);
|
|
1744
|
+
if (la !== ca) return la > ca;
|
|
1745
|
+
if (lb !== cb) return lb > cb;
|
|
1746
|
+
return lc > cc;
|
|
1747
|
+
}
|
|
1748
|
+
async function checkForUpdate() {
|
|
1749
|
+
try {
|
|
1750
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG_NAME}/latest`, {
|
|
1751
|
+
signal: AbortSignal.timeout(3e3)
|
|
1752
|
+
});
|
|
1753
|
+
if (!res.ok) return null;
|
|
1754
|
+
const data = await res.json();
|
|
1755
|
+
const latest = data.version;
|
|
1756
|
+
const current = currentVersion();
|
|
1757
|
+
if (current && newerVersion(current, latest)) return latest;
|
|
1758
|
+
return null;
|
|
1759
|
+
} catch {
|
|
1760
|
+
return null;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1729
1764
|
// src/ui/App.tsx
|
|
1730
1765
|
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1731
1766
|
function App() {
|
|
@@ -1737,10 +1772,16 @@ function App() {
|
|
|
1737
1772
|
const [activeCtx, setActiveCtx] = useState4(null);
|
|
1738
1773
|
const [state, setState] = useState4("loading");
|
|
1739
1774
|
const [cursor, setCursor] = useState4(0);
|
|
1775
|
+
const [updateAvailable, setUpdateAvailable] = useState4(null);
|
|
1740
1776
|
const [input, setInput] = useState4("");
|
|
1741
1777
|
const [paletteCursor, setPaletteCursor] = useState4(0);
|
|
1742
1778
|
const [filePickerCursor, setFilePickerCursor] = useState4(0);
|
|
1743
1779
|
const agent = useAgentRunner(cfg.model, activeCtx);
|
|
1780
|
+
useEffect3(() => {
|
|
1781
|
+
checkForUpdate().then((v) => {
|
|
1782
|
+
if (v) setUpdateAvailable(v);
|
|
1783
|
+
});
|
|
1784
|
+
}, []);
|
|
1744
1785
|
useEffect3(() => {
|
|
1745
1786
|
listModels().then((m) => {
|
|
1746
1787
|
setModels(m);
|
|
@@ -1801,6 +1842,7 @@ function App() {
|
|
|
1801
1842
|
})();
|
|
1802
1843
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, children: [
|
|
1803
1844
|
/* @__PURE__ */ jsx9(WelcomeBlock, { model: cfg.model, activeCtx, effort, cwd, error: agent.error }),
|
|
1845
|
+
updateAvailable && /* @__PURE__ */ jsx9(Box9, { marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: `\u2191 update available: v${updateAvailable} \u2014 run: npm i -g miii-agent` }) }),
|
|
1804
1846
|
state === "loading" && !agent.error && /* @__PURE__ */ jsx9(Box9, { marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "connecting to ollama\u2026" }) }),
|
|
1805
1847
|
agent.error && state !== "ready" && /* @__PURE__ */ jsx9(
|
|
1806
1848
|
ChatView,
|