deel-local-cli 0.5.0 → 0.8.0
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.en.md +526 -135
- package/README.md +652 -149
- package/bin/deel.js +67 -1
- package/package.json +4 -3
- package/src/agent/compact.js +138 -0
- package/src/agent/effort.js +139 -0
- package/src/agent/loop.js +186 -60
- package/src/agent/modes.js +153 -0
- package/src/agent/session.js +14 -3
- package/src/agent/sessionui.js +59 -0
- package/src/agent/store.js +193 -0
- package/src/backend/adapter.js +12 -2
- package/src/backend/http.js +21 -3
- package/src/backend/scan.js +162 -0
- package/src/backend/scanui.js +147 -0
- package/src/commands.js +307 -17
- package/src/config.js +19 -6
- package/src/pack/selfpack.js +248 -0
- package/src/pack/tar.js +69 -0
- package/src/pack/zip.js +217 -0
- package/src/plugins/manage.js +272 -0
- package/src/repl.js +230 -38
- package/src/safety/network.js +95 -0
- package/src/safety/undo.js +46 -1
- package/src/setup.js +4 -0
- package/src/tools/encoding.js +333 -0
- package/src/tools/excel-com.js +254 -0
- package/src/tools/excel.js +118 -0
- package/src/tools/fsutil.js +47 -4
- package/src/tools/index.js +128 -14
- package/src/tools/todo.js +92 -0
- package/src/tools/webfetch.js +110 -0
- package/src/tools/xlsx.js +319 -0
- package/src/ui/ansi.js +78 -4
- package/src/ui/level.js +104 -0
- package/src/ui/prompt.js +34 -0
- package/src/ui/status.js +151 -0
package/README.en.md
CHANGED
|
@@ -1,246 +1,637 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
**Zero dependencies** — nothing but Node's own standard library.
|
|
3
|
+
# deel
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
**A coding-agent CLI that runs on local models and private gateways only**
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
Zero dependencies · Node 20+ · Exactly one place your source can go
|
|
8
|
+
|
|
9
|
+
[한국어](README.md) · [Corporate review](#corporate-review-package) · [Troubleshooting](#troubleshooting)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
</div>
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
software requires review. `dependencies` is empty and stays empty — that fact is
|
|
14
|
-
the argument you hand to a security team.
|
|
13
|
+
---
|
|
15
14
|
|
|
16
15
|
```
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
╭──────────────────────────────────────────────────────────────╮
|
|
17
|
+
│ deel OpenAI-compatible │
|
|
18
|
+
│ │
|
|
19
|
+
│ Model qwen2.5-coder:7b (40k tokens) │
|
|
20
|
+
│ Sends to this machine 127.0.0.1:11434 ← nowhere else │
|
|
21
|
+
│ Link streaming · tools · reasoning control │
|
|
22
|
+
│ Folder C:\work\myproject │
|
|
23
|
+
│ This PC 337 skills · 127 commands · 42 plugins │
|
|
24
|
+
╰──────────────────────────────────────────────────────────────╯
|
|
25
|
+
|
|
26
|
+
▏myproject ▏qwen2.5-coder:7b ▏▰▰▱▱▱▱▱▱▱▱ 22% 28k/128k ▏◇ medium·save ▏auto
|
|
27
|
+
❯ unify the logging style
|
|
28
|
+
|
|
29
|
+
❊ Grep(console.log)
|
|
30
|
+
└ 1 file · 1 hit
|
|
31
|
+
◧ Read(src/runner.js)
|
|
32
|
+
└ 5 lines
|
|
33
|
+
◈ Edit(src/runner.js)
|
|
34
|
+
└ 1 spot
|
|
35
|
+
|
|
36
|
+
Unified log calls to the logger format. One change in runner.js.
|
|
37
|
+
|
|
38
|
+
── 4.2s · 3 tools · ↑3,900 ↓180
|
|
19
39
|
```
|
|
20
40
|
|
|
21
|
-
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Contents
|
|
44
|
+
|
|
45
|
+
- [Why this exists](#why-this-exists)
|
|
46
|
+
- [Quick start](#quick-start)
|
|
47
|
+
- [Where your data can go](#where-your-data-can-go)
|
|
48
|
+
- [Multiple local runtimes](#multiple-local-runtimes)
|
|
49
|
+
- [Slash commands](#slash-commands)
|
|
50
|
+
- [Tools](#tools)
|
|
51
|
+
- [Skills and plugins](#skills-and-plugins)
|
|
52
|
+
- [Reasoning effort](#reasoning-effort)
|
|
53
|
+
- [Auto-compaction](#auto-compaction)
|
|
54
|
+
- [Resuming a conversation](#resuming-a-conversation)
|
|
55
|
+
- [Safety](#safety)
|
|
56
|
+
- [Corporate review package](#corporate-review-package)
|
|
57
|
+
- [Configuration](#configuration)
|
|
58
|
+
- [Troubleshooting](#troubleshooting)
|
|
59
|
+
- [Development](#development)
|
|
22
60
|
|
|
23
61
|
---
|
|
24
62
|
|
|
25
|
-
##
|
|
63
|
+
## Why this exists
|
|
64
|
+
|
|
65
|
+
When a corporate security policy blocks **unapproved software**, most coding-agent tools are
|
|
66
|
+
unusable: hundreds of transitive dependencies, scripts that run at install time, and no
|
|
67
|
+
one-line answer to "where does it send my code?"
|
|
68
|
+
|
|
69
|
+
deel is built to pass that review.
|
|
70
|
+
|
|
71
|
+
| | deel |
|
|
72
|
+
|---|---|
|
|
73
|
+
| External dependencies | **0** — Node built-ins only |
|
|
74
|
+
| Install scripts | **none** — unzip and run |
|
|
75
|
+
| Where source can go | **one address** — the one you configured |
|
|
76
|
+
| Requirement | Node 20+ |
|
|
77
|
+
|
|
78
|
+
Verify it yourself:
|
|
26
79
|
|
|
27
80
|
```bash
|
|
28
|
-
npm
|
|
29
|
-
|
|
30
|
-
|
|
81
|
+
npm view deel-local-cli dependencies # {}
|
|
82
|
+
npm view deel-local-cli scripts # no install/postinstall
|
|
83
|
+
deel audit # full review sheet
|
|
31
84
|
```
|
|
32
85
|
|
|
33
|
-
For an air-gapped machine, copy the folder across and run `node bin/deel.js`
|
|
34
|
-
directly. Nothing is installed on the target machine.
|
|
35
|
-
|
|
36
86
|
---
|
|
37
87
|
|
|
38
|
-
##
|
|
88
|
+
## Quick start
|
|
89
|
+
|
|
90
|
+
### Install
|
|
39
91
|
|
|
40
92
|
```bash
|
|
41
|
-
deel
|
|
93
|
+
npm install -g deel-local-cli
|
|
42
94
|
```
|
|
43
95
|
|
|
44
|
-
|
|
45
|
-
it found, and saves the profile to `~/.deel/config.json`.
|
|
96
|
+
Or skip installing entirely — there is no `npm install` step:
|
|
46
97
|
|
|
47
|
-
|
|
98
|
+
```bash
|
|
99
|
+
git clone https://github.com/jysvai/deel-local-cli
|
|
100
|
+
node deel-local-cli/bin/deel.js
|
|
101
|
+
```
|
|
48
102
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
103
|
+
> **Note** — do not run `npm install` in your home directory. A `node_modules` there makes every
|
|
104
|
+
> later npm command scan it and report warnings about unrelated packages. Use `-g` or `npx`.
|
|
105
|
+
|
|
106
|
+
### Point it at a model
|
|
107
|
+
|
|
108
|
+
Scan this machine and pick one:
|
|
55
109
|
|
|
56
|
-
|
|
57
|
-
|
|
110
|
+
```bash
|
|
111
|
+
deel scan --pick
|
|
112
|
+
```
|
|
58
113
|
|
|
59
|
-
|
|
114
|
+
Or enter an address directly (use this for a corporate gateway):
|
|
60
115
|
|
|
61
116
|
```bash
|
|
62
|
-
|
|
63
|
-
deel diagnose --url https://ai-gw.example.corp/v1 --model sec-llm-01
|
|
117
|
+
deel setup
|
|
64
118
|
```
|
|
65
119
|
|
|
66
|
-
|
|
67
|
-
|
|
120
|
+
### Start
|
|
121
|
+
|
|
122
|
+
Run `deel` in the folder you want to work in. **That folder becomes the scope — files outside it
|
|
123
|
+
cannot be read or written.**
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
cd C:\work\myproject
|
|
127
|
+
deel
|
|
128
|
+
```
|
|
68
129
|
|
|
69
130
|
---
|
|
70
131
|
|
|
71
|
-
##
|
|
132
|
+
## Where your data can go
|
|
133
|
+
|
|
134
|
+
A coding agent ships your whole source to a model. **The address is everything.**
|
|
135
|
+
Rather than promising in prose, the code enforces it: `src/safety/network.js` checks every request
|
|
136
|
+
and never builds one for an address that is not on the allow-list.
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
[A] Model gateway ────── the only path your source travels
|
|
140
|
+
One address, set in `setup`. Switching models closes the previous one.
|
|
72
141
|
|
|
73
|
-
|
|
142
|
+
[B] Web read (WebFetch) ─ receive-only
|
|
143
|
+
GET only, zero-byte body. Private/loopback addresses refused. Every visit logged.
|
|
144
|
+
|
|
145
|
+
[C] Plugin fetch ─────── open only while /plugin install runs
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Pass `--offline` and **both B and C are closed** — traffic stays on this machine.
|
|
74
149
|
|
|
75
150
|
```bash
|
|
76
|
-
deel
|
|
151
|
+
deel --offline
|
|
77
152
|
```
|
|
78
153
|
|
|
79
|
-
|
|
80
|
-
|---|---|
|
|
81
|
-
| Basic chat | URL, key and model name are right |
|
|
82
|
-
| System message | Whether rules and skills take effect |
|
|
83
|
-
| Streaming | Whether output can arrive token by token |
|
|
84
|
-
| **Tool calling** | **Whether files can be read and edited — the critical one** |
|
|
85
|
-
| **Tool result round-trip** | **Whether multi-turn works — the agent loop depends on it** |
|
|
86
|
-
| Structured output | Whether edit formats can be schema-enforced |
|
|
87
|
-
| Reasoning effort | Whether `/think` reaches the model |
|
|
88
|
-
| Context length | How many files fit at once |
|
|
154
|
+
The destination is printed at the top of every session:
|
|
89
155
|
|
|
90
|
-
|
|
91
|
-
|
|
156
|
+
```
|
|
157
|
+
Sends to this machine 127.0.0.1:11434 ← nowhere else
|
|
158
|
+
```
|
|
92
159
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
160
|
+
Nothing is collected or transmitted. No telemetry, no usage stats, no crash reporting.
|
|
161
|
+
Conversation history, undo snapshots and config live only in `.deel/` inside your working folder.
|
|
162
|
+
|
|
163
|
+
> Verified by 55 checks in `npm test` (network + web), including bringing up a real server and
|
|
164
|
+
> confirming that **not a single request reaches it** when it is not allow-listed.
|
|
96
165
|
|
|
97
166
|
---
|
|
98
167
|
|
|
99
|
-
##
|
|
168
|
+
## Multiple local runtimes
|
|
100
169
|
|
|
101
|
-
|
|
102
|
-
|
|
170
|
+
People rarely run just one. `deel scan` knocks on 13 known ports concurrently and identifies
|
|
171
|
+
each runtime from its **response**, not its port number — Ollama by `/api/version`,
|
|
172
|
+
LM Studio by `/api/v0/models`, llama.cpp by `/props`. Unrecognised ones are marked as a guess.
|
|
103
173
|
|
|
104
174
|
```
|
|
105
|
-
|
|
106
|
-
skills: 337 · commands: 127 (42 plugins)
|
|
175
|
+
$ deel scan
|
|
107
176
|
|
|
108
|
-
|
|
177
|
+
✓ found 3
|
|
109
178
|
|
|
110
|
-
|
|
111
|
-
|
|
179
|
+
◆ Ollama 127.0.0.1:11434 Ollama API 36ms
|
|
180
|
+
· qwen2.5-coder:7b 7B · 4.4GB
|
|
181
|
+
· llama3.2:1b 1B · 1.2GB
|
|
182
|
+
◆ LM Studio 127.0.0.1:1234 OpenAI-compat 7ms
|
|
183
|
+
· devstral-small-2507
|
|
184
|
+
◆ llama.cpp 127.0.0.1:8080 OpenAI-compat 7ms
|
|
185
|
+
· gemma-3-4b-it
|
|
112
186
|
|
|
113
|
-
|
|
114
|
-
|
|
187
|
+
Recommended Ollama · qwen2.5-coder:7b
|
|
188
|
+
```
|
|
115
189
|
|
|
116
|
-
|
|
117
|
-
|
|
190
|
+
| Command | What it does |
|
|
191
|
+
|---|---|
|
|
192
|
+
| `deel scan` | Show what is running |
|
|
193
|
+
| `deel scan --pick` | Choose one from the list |
|
|
194
|
+
| `deel scan --save` | Register everything found |
|
|
195
|
+
| `deel scan --ports 9000,9100` | Extra ports to probe |
|
|
196
|
+
| `deel scan --host <addr>` | Defaults to `127.0.0.1` |
|
|
118
197
|
|
|
119
|
-
|
|
198
|
+
Switch with `/model` mid-conversation — **the conversation carries over.**
|
|
120
199
|
|
|
121
|
-
|
|
122
|
-
```
|
|
200
|
+
---
|
|
123
201
|
|
|
124
|
-
|
|
202
|
+
## Slash commands
|
|
125
203
|
|
|
126
|
-
Names follow
|
|
204
|
+
Names follow Claude Code / Codex conventions.
|
|
127
205
|
|
|
128
|
-
| Command | |
|
|
206
|
+
| Command | What it does |
|
|
129
207
|
|---|---|
|
|
130
|
-
| `/help` | list
|
|
131
|
-
| `/context` |
|
|
132
|
-
| `/compact`
|
|
133
|
-
| `/
|
|
134
|
-
| `/
|
|
135
|
-
| `/
|
|
136
|
-
| `/
|
|
137
|
-
| `/
|
|
138
|
-
| `/
|
|
139
|
-
| `/
|
|
208
|
+
| `/help` | Command list |
|
|
209
|
+
| `/context` | What is consuming the context window |
|
|
210
|
+
| `/compact` | Summarise and fold older turns |
|
|
211
|
+
| `/clear` | Clear the conversation (keeps link and rules) |
|
|
212
|
+
| `/model` | Switch connection / model |
|
|
213
|
+
| `/think <level\|profile>` | `off·low·medium·high·max` or `even·save·deep` |
|
|
214
|
+
| `/mode <mode>` | `auto` · `confirm` · `strict` |
|
|
215
|
+
| `/undo [turns]` | Revert file changes |
|
|
216
|
+
| `/tools` | Available tools |
|
|
217
|
+
| `/skills [query\|all\|off]` | Browse, search, load skills |
|
|
218
|
+
| `/plugin [install\|remove\|pack]` | Manage plugins |
|
|
219
|
+
| `/cost` | Session usage |
|
|
220
|
+
| `/status` | Connection status |
|
|
221
|
+
| `/scan [save]` | Sweep this machine for local model servers (`save` registers them) |
|
|
222
|
+
| `/sessions` | Past conversations in this folder |
|
|
223
|
+
| `/init` | Create a `DEEL.md` rules file |
|
|
224
|
+
| `/exit` | Quit |
|
|
225
|
+
|
|
226
|
+
Discovered plugin commands are invoked as `/<plugin>:<name>`, with `$ARGUMENTS` substituted.
|
|
227
|
+
|
|
228
|
+
`/scan` and `/sessions` work without leaving the session. If you just started another local
|
|
229
|
+
server or loaded a different model, `/scan save` then `/model` switches over without losing
|
|
230
|
+
the conversation.
|
|
231
|
+
|
|
232
|
+
### Interrupting
|
|
233
|
+
|
|
234
|
+
Press **Ctrl+C** to stop the model mid-answer when it is heading the wrong way.
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
❯ rewrite the whole test suite
|
|
238
|
+
◧ Read test/smoke.js
|
|
239
|
+
◧ Read test/loop.test.js
|
|
240
|
+
^C
|
|
241
|
+
⚠ Stopped (after step 2)
|
|
140
242
|
|
|
141
|
-
|
|
243
|
+
❯ ▊
|
|
244
|
+
```
|
|
142
245
|
|
|
143
|
-
|
|
144
|
-
|
|
246
|
+
The conversation stays valid. If the model had announced tool calls, each unanswered one is
|
|
247
|
+
filled with a `stopped by user` result so the call/result pairing holds — a conversation with
|
|
248
|
+
broken pairing is rejected with HTTP 400 on the next request, which would waste the whole
|
|
249
|
+
session. Tools already running finish; **tools not yet started never run.**
|
|
145
250
|
|
|
146
|
-
|
|
251
|
+
Pressing Ctrl+C again on an empty line quits.
|
|
147
252
|
|
|
148
253
|
---
|
|
149
254
|
|
|
150
|
-
##
|
|
255
|
+
## Tools
|
|
256
|
+
|
|
257
|
+
Names and arguments match Claude Code, so skills written for that convention work unchanged.
|
|
258
|
+
|
|
259
|
+
| Tool | What it does |
|
|
260
|
+
|---|---|
|
|
261
|
+
| `Read` | Read a file (line numbers, `offset`/`limit`) |
|
|
262
|
+
| `Write` | Write / overwrite a file |
|
|
263
|
+
| `Edit` | Replace an exact string (`replace_all` supported) |
|
|
264
|
+
| `Glob` | Find files by name pattern |
|
|
265
|
+
| `Grep` | Regex search file contents |
|
|
266
|
+
| `Bash` | Run a command |
|
|
267
|
+
| `Skill` | Expand a skill body (shown to the model only when skills exist) |
|
|
268
|
+
| `WebFetch` | Read a web page (read-only; hidden under `--offline`) |
|
|
269
|
+
| `TodoWrite` | Checklist — breaks long work into steps and shows progress |
|
|
270
|
+
|
|
271
|
+
### Checklists
|
|
151
272
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
because silently editing the wrong place is far worse than not finding it.
|
|
273
|
+
Keeps the model from losing its place on multi-step work. The list is redrawn whenever the
|
|
274
|
+
model updates it.
|
|
155
275
|
|
|
156
276
|
```
|
|
157
|
-
|
|
277
|
+
☰ Todo 1/3 done ← just finished 1
|
|
278
|
+
|
|
279
|
+
✓ unify log format
|
|
280
|
+
▶ fix the tests
|
|
281
|
+
☐ update the docs
|
|
158
282
|
```
|
|
159
283
|
|
|
160
|
-
|
|
284
|
+
Only one item may be **in progress** at a time; setting two is refused. Holding several at
|
|
285
|
+
once is how nothing gets finished.
|
|
286
|
+
|
|
287
|
+
### Read-only tools run together
|
|
288
|
+
|
|
289
|
+
When the model asks for three `Read` calls at once, all three run **concurrently** — sweeping
|
|
290
|
+
five files costs about what reading one costs.
|
|
161
291
|
|
|
162
292
|
```
|
|
163
|
-
|
|
164
|
-
should-refuse 5/5 (100%) · wrong-place edits: 0
|
|
293
|
+
◧ Read src/a.js ◧ Read src/b.js ◧ Read src/c.js together
|
|
165
294
|
```
|
|
166
295
|
|
|
167
|
-
|
|
296
|
+
Only `Read`, `Glob`, `Grep`, `Skill` and `WebFetch` are eligible. `Write`, `Edit` and `Bash`
|
|
297
|
+
always run one at a time — two concurrent writes to one file scramble the undo snapshot
|
|
298
|
+
order, and `Bash` can do anything. Results come back **in the order the model asked for
|
|
299
|
+
them**, even when they finish out of order; shuffled results confuse the model about which
|
|
300
|
+
result belongs to which call.
|
|
301
|
+
|
|
302
|
+
### Edits survive small mistakes
|
|
303
|
+
|
|
304
|
+
Models routinely get whitespace, indentation and line endings wrong. deel relaxes matching in
|
|
305
|
+
stages but **refuses outright when the match is ambiguous** — silently editing the wrong place is
|
|
306
|
+
far worse than not finding it.
|
|
168
307
|
|
|
169
308
|
```
|
|
170
|
-
|
|
171
|
-
Line 2 of the file is closest:
|
|
172
|
-
console.log("start: " + id);
|
|
173
|
-
Copy that line verbatim and try again.
|
|
309
|
+
exact → ignore trailing space / CRLF → ignore indentation → ignore all whitespace
|
|
174
310
|
```
|
|
175
311
|
|
|
312
|
+
Measured with `npm run bench`:
|
|
313
|
+
|
|
314
|
+
| | Success | Wrong place edited |
|
|
315
|
+
|---|---|---|
|
|
316
|
+
| Exact match only | 20% | 0 |
|
|
317
|
+
| Staged relaxation | **100%** | **0** |
|
|
318
|
+
|
|
319
|
+
On failure it points at the closest line in the file.
|
|
320
|
+
|
|
176
321
|
---
|
|
177
322
|
|
|
178
|
-
## Skills and
|
|
323
|
+
## Skills and plugins
|
|
179
324
|
|
|
180
|
-
|
|
325
|
+
**deel does not carry skills with it.** On startup it scans the machine it is running on and uses
|
|
326
|
+
whatever is there. On a clean PC: zero. On a PC with skills installed: those skills.
|
|
181
327
|
|
|
182
328
|
```
|
|
183
329
|
project ./.deel/skills ./.claude/skills ./.deel/commands ./.claude/commands
|
|
184
330
|
user ~/.deel/skills ~/.claude/skills ~/.claude/commands
|
|
185
|
-
plugins ~/.claude/plugins/**
|
|
331
|
+
plugins ~/.claude/plugins/** ~/.deel/plugins/**
|
|
186
332
|
```
|
|
187
333
|
|
|
188
|
-
|
|
189
|
-
`commands/*.md` with `$ARGUMENTS` substitution.
|
|
334
|
+
Reads the Claude Code format: `SKILL.md` with YAML front matter, `commands/*.md`, `$ARGUMENTS`.
|
|
190
335
|
|
|
191
336
|
### Loaded in three stages
|
|
192
337
|
|
|
193
|
-
|
|
338
|
+
Loading everything would blow the context window.
|
|
194
339
|
|
|
195
340
|
| Stage | What | Cost |
|
|
196
341
|
|---|---|---|
|
|
197
|
-
| 1 |
|
|
198
|
-
| 2 |
|
|
199
|
-
| 3 |
|
|
342
|
+
| 1 | Name + one-line description in the prompt | ~1,800 tokens for 40 skills |
|
|
343
|
+
| 2 | Body of the one the model picks via `Skill` | one at a time |
|
|
344
|
+
| 3 | Files that body references, via `Read` | on demand |
|
|
345
|
+
|
|
346
|
+
### Fetching plugins
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
# on a connected machine
|
|
350
|
+
/plugin install affaan-m/ECC # git clone, or tarball when git is absent
|
|
351
|
+
/plugin pack import.zip # bundle, excluding executable scripts
|
|
352
|
+
|
|
353
|
+
# on the air-gapped machine — just unzip
|
|
354
|
+
unzip import.zip -d ~/.deel/plugins/
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
`/plugin pack` omits `.js` `.sh` `.ps1` `.py` and friends, and includes a plain-text manifest
|
|
358
|
+
with a licence table — ready to hand to a security reviewer.
|
|
359
|
+
|
|
360
|
+
### Deliberately not included
|
|
361
|
+
|
|
362
|
+
| | Why |
|
|
363
|
+
|---|---|
|
|
364
|
+
| hooks | Executable scripts — fails import review, widens the blast radius of autonomy |
|
|
365
|
+
| sub-agents | Doubles model calls against a gateway quota |
|
|
366
|
+
| MCP | A separate protocol; a project of its own |
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Reasoning effort
|
|
371
|
+
|
|
372
|
+
One answer means several model calls, and **each needs a different amount of thinking.**
|
|
373
|
+
All-high is slow; all-low wanders off.
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
$ /think
|
|
377
|
+
|
|
378
|
+
Base medium Profile save Hard on the first decision, light while continuing
|
|
379
|
+
|
|
380
|
+
Stage Effort Cap When
|
|
381
|
+
first call · medium 4,096 deciding what to do
|
|
382
|
+
continuing ↓ low 2,048 reading a tool result, picking the next step
|
|
383
|
+
stuck ↑ high 4,096 the previous tool errored
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
| Profile | Character |
|
|
387
|
+
|---|---|
|
|
388
|
+
| `even` | Same effort everywhere — predictable, slower |
|
|
389
|
+
| `save` (default) | Hard on the first decision only |
|
|
390
|
+
| `deep` | Everything one notch up — for hard work |
|
|
391
|
+
|
|
392
|
+
**Caps are not fixed numbers.** They are computed from the model's context window and how
|
|
393
|
+
much of it is currently used — the profile decides what share of the remaining room a stage gets.
|
|
394
|
+
|
|
395
|
+
| Model | First call | Continuing | Stuck |
|
|
396
|
+
|---|---|---|---|
|
|
397
|
+
| 2k local | 554 | 512 | 554 |
|
|
398
|
+
| 8k local | 2,007 | 1,003 | 2,007 |
|
|
399
|
+
| 40k (qwen3) | 11,688 | 5,844 | 11,688 |
|
|
400
|
+
| 128k gateway | 16,384 | 16,384 | 16,384 |
|
|
401
|
+
| 128k, 80% full | 7,680 | 3,840 | 7,680 |
|
|
402
|
+
|
|
403
|
+
Caps shrink as the context fills. Handing a 4k model a 4,096-token cap would leave no room for input.
|
|
404
|
+
Raise the ceiling with `maxTokens` in the profile if you need more.
|
|
405
|
+
|
|
406
|
+
If a saved cap truncates a reply, **that step alone is retried with the cap lifted.**
|
|
407
|
+
A truncated reply means a half-written tool call, which fails silently.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Auto-compaction
|
|
412
|
+
|
|
413
|
+
At 80% context, older turns are **summarised and folded** so work continues.
|
|
414
|
+
Plain truncation makes the model forget: it re-reads files and re-fixes what it already fixed.
|
|
415
|
+
|
|
416
|
+
```
|
|
417
|
+
◱ Folded 44 turns into a summary — 10,399 → 3,170 tokens (70% smaller)
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
The summary keeps goal / done / learned / decided / remaining. The cut point is chosen so a
|
|
421
|
+
**tool call is never separated from its result** — splitting them makes the server return 400.
|
|
422
|
+
If the summary request fails, it falls back to plain trimming rather than stopping.
|
|
423
|
+
|
|
424
|
+
`/compact` folds on demand.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Resuming a conversation
|
|
429
|
+
|
|
430
|
+
Close the terminal by accident, or reboot, and the conversation is still there.
|
|
431
|
+
Messages are written to `.deel/sessions/` **as each one completes**, so a crash
|
|
432
|
+
loses at most the message in flight.
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
$ deel sessions
|
|
436
|
+
|
|
437
|
+
── conversations in this folder ────────────────────────────────
|
|
438
|
+
● 20260824-090200 just now 1 turn devstral-small-2507
|
|
439
|
+
fix the failing test
|
|
440
|
+
· 20260824-084500 2h ago 2 turns qwen2.5-coder:7b
|
|
441
|
+
switch src/a.js logging to the logger
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
| Command | What it does |
|
|
445
|
+
|---|---|
|
|
446
|
+
| `deel --continue` | Resume the most recent conversation in this folder |
|
|
447
|
+
| `deel --resume <id>` | Resume a specific one |
|
|
448
|
+
| `deel sessions` | List what is stored |
|
|
449
|
+
| `deel sessions --rm <id>` | Delete one |
|
|
450
|
+
|
|
451
|
+
The format is `jsonl` — one message per line — so a power cut costs only the last line.
|
|
452
|
+
Resumed history keeps tool calls paired with their results, so work continues immediately.
|
|
453
|
+
Conversations older than 30 days and outside the most recent 30 are pruned automatically.
|
|
454
|
+
|
|
455
|
+
Everything lives in `.deel/sessions/` inside the working folder, and `.gitignore`
|
|
456
|
+
covers `.deel/` so it never reaches a repository.
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Safety
|
|
461
|
+
|
|
462
|
+
Instead of approval prompts, the design makes things **reversible**. The default `auto` mode
|
|
463
|
+
does not ask.
|
|
464
|
+
|
|
465
|
+
| Mechanism | Detail |
|
|
466
|
+
|---|---|
|
|
467
|
+
| **Undo** | Snapshot before every write. `/undo` restores per turn |
|
|
468
|
+
| **Scope** | Outside the starting folder is refused, even if the model insists |
|
|
469
|
+
| **Blocked commands** | Only irreversible ones (disk format, recursive delete, `--force` push) |
|
|
470
|
+
| **No re-run** | A mutating command is never retried after failure |
|
|
471
|
+
| **Interrupt** | Ctrl+C stops mid-answer and leaves the conversation valid |
|
|
472
|
+
| **Audit log** | Everything recorded in `.deel/audit.jsonl` |
|
|
473
|
+
|
|
474
|
+
| Mode | Asks when |
|
|
475
|
+
|---|---|
|
|
476
|
+
| `auto` (default) | Never — undo is the safety net |
|
|
477
|
+
| `confirm` | Irreversible commands only |
|
|
478
|
+
| `strict` | All file changes and commands |
|
|
479
|
+
|
|
480
|
+
Undo history stores whole file contents, so repeated edits to large files add up. Past 32MB
|
|
481
|
+
it keeps the **most recent 50 turns** and drops the rest. What you just did is always
|
|
482
|
+
undoable; `/status` shows how large the history currently is.
|
|
200
483
|
|
|
201
|
-
|
|
202
|
-
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Corporate review package
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
deel pack --out deel-import.zip
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
```
|
|
493
|
+
✓ deel-import.zip
|
|
494
|
+
39 files · 100.2KB
|
|
495
|
+
|
|
496
|
+
Dependencies 0
|
|
497
|
+
Install scripts none
|
|
498
|
+
External imports 0
|
|
499
|
+
Network calls 3 sites (configured address only)
|
|
500
|
+
Ports opened none
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
The bundled review sheet contains:
|
|
504
|
+
|
|
505
|
+
- Dependency list and every external `import` in the source
|
|
506
|
+
- Presence of `preinstall` / `install` / `postinstall` / `prepare`
|
|
507
|
+
- **Every network and process-spawn call site found by scanning the source** (file:line)
|
|
508
|
+
- The three outbound lanes, explained
|
|
509
|
+
- SHA-256 per file (verify with `certutil -hashfile`)
|
|
203
510
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
511
|
+
It is generated by scanning the source, not written by hand — hand-written sheets drift from reality.
|
|
512
|
+
Use `deel audit` to read it without building a zip.
|
|
513
|
+
|
|
514
|
+
### Diagnosing a corporate gateway
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
node bin/deel.js diagnose --url <gateway> --key <key> --model <model> --out report.txt
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Hand over `report.txt` alone — plain text, no colour codes.
|
|
521
|
+
|
|
522
|
+
| Check | Why it matters |
|
|
523
|
+
|---|---|
|
|
524
|
+
| Basic chat | Address, key and model name are right |
|
|
525
|
+
| System message | Rules (`DEEL.md`) and skills take effect |
|
|
526
|
+
| Streaming | Output can flow token by token |
|
|
527
|
+
| **Tool calls** | **Whether it can read and edit files — the critical one** |
|
|
528
|
+
| **Tool results** | **Whether multi-turn works — the premise of the agent loop** |
|
|
529
|
+
| Structured output | Edit format can be enforced by schema |
|
|
530
|
+
| Reasoning control | Whether `/think` works at the model layer |
|
|
531
|
+
| Context length | How many files can be read at once |
|
|
532
|
+
|
|
533
|
+
Verdict is one of **ready · limited · blocked · unreachable**.
|
|
207
534
|
|
|
208
535
|
---
|
|
209
536
|
|
|
210
|
-
##
|
|
537
|
+
## Configuration
|
|
538
|
+
|
|
539
|
+
Stored in `~/.deel/config.json`. A `.deel/config.json` in the project folder takes precedence.
|
|
211
540
|
|
|
212
|
-
|
|
213
|
-
The safety net is that everything is **reversible**, not that everything is gated.
|
|
541
|
+
### Supported servers
|
|
214
542
|
|
|
215
|
-
| | |
|
|
543
|
+
| | Example address |
|
|
216
544
|
|---|---|
|
|
217
|
-
|
|
|
218
|
-
|
|
|
219
|
-
|
|
|
220
|
-
|
|
|
221
|
-
|
|
545
|
+
| Corporate AI gateway (OpenAI-compatible) | `https://ai-gw.example.corp/v1` |
|
|
546
|
+
| Ollama | `http://localhost:11434` |
|
|
547
|
+
| LM Studio | `http://localhost:1234/v1` |
|
|
548
|
+
| llama.cpp · vLLM · LiteLLM | `http://host:port/v1` |
|
|
549
|
+
|
|
550
|
+
Auth style is detected automatically: `Authorization: Bearer` → `x-api-key` → `api-key` (Azure) → none.
|
|
551
|
+
|
|
552
|
+
### Environment variables
|
|
553
|
+
|
|
554
|
+
| Variable | Use |
|
|
555
|
+
|---|---|
|
|
556
|
+
| `DEEL_API_KEY` | Keep the key out of the config file (takes precedence) |
|
|
557
|
+
| `DEEL_KEY_<PROFILE_ID>` | Per-profile key |
|
|
558
|
+
| `NODE_EXTRA_CA_CERTS` | Corporate TLS certificate |
|
|
559
|
+
| `HTTPS_PROXY` | Behind a proxy |
|
|
560
|
+
| `DEEL_DEBUG=1` | Verbose errors |
|
|
561
|
+
| `NO_COLOR` | Disable colour |
|
|
562
|
+
|
|
563
|
+
### Flags
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
deel --root <folder> Working scope. Defaults to the current folder
|
|
567
|
+
deel --mode <mode> auto (default) / confirm / strict
|
|
568
|
+
deel --think <level> off / low / medium (default) / high / max
|
|
569
|
+
deel --effort <profile> even / save (default) / deep
|
|
570
|
+
deel --offline Nothing leaves this machine
|
|
571
|
+
deel --continue Resume the most recent conversation
|
|
572
|
+
deel --resume <id> Resume a specific one
|
|
573
|
+
```
|
|
222
574
|
|
|
223
|
-
|
|
224
|
-
|
|
575
|
+
### Project rules
|
|
576
|
+
|
|
577
|
+
If the working folder has `DEEL.md`, `CLAUDE.md` or `AGENTS.md`, it is loaded as project rules.
|
|
578
|
+
`/init` scaffolds one.
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
## Troubleshooting
|
|
583
|
+
|
|
584
|
+
| Symptom | Check |
|
|
585
|
+
|---|---|
|
|
586
|
+
| `address not found` | Typo, DNS, VPN / intranet connectivity |
|
|
587
|
+
| `connection refused` | Server is down or the port differs |
|
|
588
|
+
| certificate error | `set NODE_EXTRA_CA_CERTS=C:\path\corp-ca.pem` |
|
|
589
|
+
| behind a proxy | `set HTTPS_PROXY=http://proxy:port` |
|
|
590
|
+
| 401 / 403 | Wrong key or auth header style (four are tried automatically) |
|
|
591
|
+
| `address not permitted` | The lock did its job — pick a connection with `/model` |
|
|
592
|
+
| Tool calls don't work | Run `deel diagnose`. Small models (1B–3B) often can't |
|
|
593
|
+
| Empty replies | A heavy-reasoning model — try `/think low` |
|
|
594
|
+
| `deel scan` finds nothing | Server is off or on another port — use `--ports` |
|
|
225
595
|
|
|
226
596
|
---
|
|
227
597
|
|
|
228
598
|
## Development
|
|
229
599
|
|
|
230
600
|
```bash
|
|
231
|
-
npm
|
|
232
|
-
npm
|
|
233
|
-
npm run
|
|
234
|
-
npm run
|
|
601
|
+
npm test Full suite (254 checks)
|
|
602
|
+
npm run verify Import + network checks only
|
|
603
|
+
npm run bench Edit success rate
|
|
604
|
+
npm run demo See what the UI actually looks like
|
|
605
|
+
npm run check Syntax check every file
|
|
235
606
|
```
|
|
236
607
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
608
|
+
Tests run against a **fake gateway**, so the loop, streaming, tool execution, undo and compaction
|
|
609
|
+
are verified deterministically without any model. ZIP output is cross-checked with the real
|
|
610
|
+
`unzip`; the TAR reader is fed archives produced by the real `tar`.
|
|
611
|
+
|
|
612
|
+
`npm test` runs each file separately and reports **per-file exit codes**, because the exit code
|
|
613
|
+
— not the pass marks on screen — is what CI reads, and the two can disagree: a file can pass
|
|
614
|
+
every check and still die on the way out, leaving the screen green and the exit code 1. That
|
|
615
|
+
happened once on Windows and cost a lot of time. The runner does not stop at the first failure,
|
|
616
|
+
so one run tells you everything.
|
|
617
|
+
|
|
618
|
+
| Suite | Checks | Covers |
|
|
619
|
+
|---|---|---|
|
|
620
|
+
| `smoke` | 20 | Tools, scope, undo, audit log |
|
|
621
|
+
| `loop` | 16 | Agent loop, streaming, tool calls |
|
|
622
|
+
| `network` | 30 | Nothing escapes the configured address |
|
|
623
|
+
| `web` | 25 | Web reads stay read-only |
|
|
624
|
+
| `abort` | 16 | Ctrl+C leaves the conversation valid |
|
|
625
|
+
| `parallel` | 23 | Read-only tools run together; checklists |
|
|
626
|
+
| `compact` | 21 | Summary folding, pairing intact, graceful fallback |
|
|
627
|
+
| `store` | 34 | Session persistence, resume, crash recovery |
|
|
628
|
+
| `scan` | 19 | Distinguishing multiple runtimes |
|
|
629
|
+
| `plugins` | 38 | Plugin fetch/pack, ZIP/TAR |
|
|
630
|
+
| `no-bundle` | 12 | Nothing foreign in the published package; test-file hygiene |
|
|
631
|
+
| `edit-bench` | 20 cases | Edit success rate |
|
|
241
632
|
|
|
242
633
|
---
|
|
243
634
|
|
|
244
|
-
##
|
|
635
|
+
## Licence
|
|
245
636
|
|
|
246
|
-
MIT
|
|
637
|
+
[MIT](LICENSE)
|