deel-local-cli 0.5.0 → 0.9.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 +738 -132
- package/README.md +742 -147
- package/bin/deel.js +96 -4
- 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 +252 -0
- package/src/agent/route.js +156 -0
- package/src/agent/session.js +28 -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/ctxsize.js +174 -0
- package/src/backend/http.js +44 -3
- package/src/backend/probe.js +15 -14
- package/src/backend/scan.js +256 -0
- package/src/backend/scanui.js +147 -0
- package/src/commands.js +658 -33
- 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 +297 -40
- package/src/report.js +1 -1
- 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 +97 -5
- package/src/ui/level.js +106 -0
- package/src/ui/prompt.js +34 -0
- package/src/ui/status.js +161 -0
package/README.en.md
CHANGED
|
@@ -1,246 +1,852 @@
|
|
|
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
|
+
- [Work modes](#work-modes)
|
|
51
|
+
- [Simple vs developer](#simple-vs-developer)
|
|
52
|
+
- [Tools](#tools)
|
|
53
|
+
- [Korean text and Excel](#korean-text-and-excel)
|
|
54
|
+
- [Skills and plugins](#skills-and-plugins)
|
|
55
|
+
- [Reasoning effort](#reasoning-effort)
|
|
56
|
+
- [Auto-compaction](#auto-compaction)
|
|
57
|
+
- [Resuming a conversation](#resuming-a-conversation)
|
|
58
|
+
- [Safety](#safety)
|
|
59
|
+
- [Corporate review package](#corporate-review-package)
|
|
60
|
+
- [Configuration](#configuration)
|
|
61
|
+
- [Troubleshooting](#troubleshooting)
|
|
62
|
+
- [Development](#development)
|
|
22
63
|
|
|
23
64
|
---
|
|
24
65
|
|
|
25
|
-
##
|
|
66
|
+
## Why this exists
|
|
67
|
+
|
|
68
|
+
When a corporate security policy blocks **unapproved software**, most coding-agent tools are
|
|
69
|
+
unusable: hundreds of transitive dependencies, scripts that run at install time, and no
|
|
70
|
+
one-line answer to "where does it send my code?"
|
|
71
|
+
|
|
72
|
+
deel is built to pass that review.
|
|
73
|
+
|
|
74
|
+
| | deel |
|
|
75
|
+
|---|---|
|
|
76
|
+
| External dependencies | **0** — Node built-ins only |
|
|
77
|
+
| Install scripts | **none** — unzip and run |
|
|
78
|
+
| Where source can go | **one address** — the one you configured |
|
|
79
|
+
| Requirement | Node 20+ |
|
|
80
|
+
|
|
81
|
+
Verify it yourself:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm view deel-local-cli dependencies # {}
|
|
85
|
+
npm view deel-local-cli scripts # no install/postinstall
|
|
86
|
+
deel audit # full review sheet
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Quick start
|
|
92
|
+
|
|
93
|
+
### Install
|
|
26
94
|
|
|
27
95
|
```bash
|
|
28
96
|
npm install -g deel-local-cli
|
|
29
|
-
# or run without installing
|
|
30
|
-
npx deel-local-cli setup
|
|
31
97
|
```
|
|
32
98
|
|
|
33
|
-
|
|
34
|
-
directly. Nothing is installed on the target machine.
|
|
99
|
+
Or skip installing entirely — there is no `npm install` step:
|
|
35
100
|
|
|
36
|
-
|
|
101
|
+
```bash
|
|
102
|
+
git clone https://github.com/jysvai/deel-local-cli
|
|
103
|
+
node deel-local-cli/bin/deel.js
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
> **Note** — do not run `npm install` in your home directory. A `node_modules` there makes every
|
|
107
|
+
> later npm command scan it and report warnings about unrelated packages. Use `-g` or `npx`.
|
|
108
|
+
|
|
109
|
+
### Point it at a model
|
|
110
|
+
|
|
111
|
+
Scan this machine and pick one:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
deel scan --pick
|
|
115
|
+
```
|
|
37
116
|
|
|
38
|
-
|
|
117
|
+
Or enter an address directly (use this for a corporate gateway):
|
|
39
118
|
|
|
40
119
|
```bash
|
|
41
120
|
deel setup
|
|
42
121
|
```
|
|
43
122
|
|
|
44
|
-
|
|
45
|
-
it found, and saves the profile to `~/.deel/config.json`.
|
|
123
|
+
### Start
|
|
46
124
|
|
|
47
|
-
|
|
125
|
+
Run `deel` in the folder you want to work in. **That folder becomes the scope — files outside it
|
|
126
|
+
cannot be read or written.**
|
|
48
127
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
128
|
+
```bash
|
|
129
|
+
cd C:\work\myproject
|
|
130
|
+
deel
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
55
134
|
|
|
56
|
-
|
|
57
|
-
`api-key` (Azure-style), or none.
|
|
135
|
+
## Where your data can go
|
|
58
136
|
|
|
59
|
-
|
|
137
|
+
A coding agent ships your whole source to a model. **The address is everything.**
|
|
138
|
+
Rather than promising in prose, the code enforces it: `src/safety/network.js` checks every request
|
|
139
|
+
and never builds one for an address that is not on the allow-list.
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
[A] Model gateway ────── the only path your source travels
|
|
143
|
+
One address, set in `setup`. Switching models closes the previous one.
|
|
144
|
+
|
|
145
|
+
[B] Web read (WebFetch) ─ receive-only
|
|
146
|
+
GET only, zero-byte body. Private/loopback addresses refused. Every visit logged.
|
|
147
|
+
|
|
148
|
+
[C] Plugin fetch ─────── open only while /plugin install runs
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Pass `--offline` and **both B and C are closed** — traffic stays on this machine.
|
|
60
152
|
|
|
61
153
|
```bash
|
|
62
|
-
|
|
63
|
-
|
|
154
|
+
deel --offline
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The destination is printed at the top of every session:
|
|
158
|
+
|
|
64
159
|
```
|
|
160
|
+
Sends to this machine 127.0.0.1:11434 ← nowhere else
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Nothing is collected or transmitted. No telemetry, no usage stats, no crash reporting.
|
|
164
|
+
Conversation history, undo snapshots and config live only in `.deel/` inside your working folder.
|
|
65
165
|
|
|
66
|
-
|
|
67
|
-
|
|
166
|
+
> Verified by 55 checks in `npm test` (network + web), including bringing up a real server and
|
|
167
|
+
> confirming that **not a single request reaches it** when it is not allow-listed.
|
|
68
168
|
|
|
69
169
|
---
|
|
70
170
|
|
|
71
|
-
##
|
|
171
|
+
## Multiple local runtimes
|
|
72
172
|
|
|
73
|
-
|
|
173
|
+
People rarely run just one. `deel scan` knocks on 13 known ports concurrently and identifies
|
|
174
|
+
each runtime from its **response**, not its port number — Ollama by `/api/version`,
|
|
175
|
+
LM Studio by `/api/v0/models`, llama.cpp by `/props`. Unrecognised ones are marked as a guess.
|
|
74
176
|
|
|
75
|
-
```bash
|
|
76
|
-
deel diagnose --url <base-url> --key <key> --model <model> --out report.txt
|
|
77
177
|
```
|
|
178
|
+
$ deel scan
|
|
78
179
|
|
|
79
|
-
|
|
180
|
+
✓ found 3
|
|
181
|
+
|
|
182
|
+
◆ Ollama 127.0.0.1:11434 Ollama API 36ms
|
|
183
|
+
· qwen2.5-coder:7b 7B · 4.4GB
|
|
184
|
+
· llama3.2:1b 1B · 1.2GB
|
|
185
|
+
◆ LM Studio 127.0.0.1:1234 OpenAI-compat 7ms
|
|
186
|
+
· devstral-small-2507
|
|
187
|
+
◆ llama.cpp 127.0.0.1:8080 OpenAI-compat 7ms
|
|
188
|
+
· gemma-3-4b-it
|
|
189
|
+
|
|
190
|
+
Recommended Ollama · qwen2.5-coder:7b
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
| Command | What it does |
|
|
80
194
|
|---|---|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
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 |
|
|
195
|
+
| `deel scan` | Show what is running |
|
|
196
|
+
| `deel scan --pick` | Choose one from the list |
|
|
197
|
+
| `deel scan --save` | Register everything found |
|
|
198
|
+
| `deel scan --ports 9000,9100` | Extra ports to probe |
|
|
199
|
+
| `deel scan --host <addr>` | Defaults to `127.0.0.1` |
|
|
89
200
|
|
|
90
|
-
|
|
91
|
-
plain-text report you can hand to whoever runs the gateway.
|
|
201
|
+
Switch with `/model` mid-conversation — **the conversation carries over.**
|
|
92
202
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Slash commands
|
|
206
|
+
|
|
207
|
+
Names follow Claude Code / Codex conventions.
|
|
208
|
+
|
|
209
|
+
| Command | What it does |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `/help` | Command list |
|
|
212
|
+
| `/context` | What is consuming the context window |
|
|
213
|
+
| `/ctx [auto\|number]` | Context **length** — re-read it off the model, or set it yourself |
|
|
214
|
+
| `/compact` | Summarise and fold older turns |
|
|
215
|
+
| `/clear` | Clear the conversation (keeps link and rules) |
|
|
216
|
+
| `/model` | Switch connection / model |
|
|
217
|
+
| `/think <level\|profile>` | `off·low·medium·high·max` or `even·save·deep` |
|
|
218
|
+
| `/mode <mode>` | Approval policy — how much it asks (`auto` · `confirm` · `strict`) |
|
|
219
|
+
| `/work [mode]` | Work mode — what kind of work you are doing |
|
|
220
|
+
| `/auto` | Hand the wheel back — it picks the mode from what you type |
|
|
221
|
+
| `/code` `/plan` `/architect` `/debug` `/ask` `/orchestrator` | Switch work mode directly (pins it) |
|
|
222
|
+
| `/level [level]` | How much to show (`쉬움` simple · `개발자` developer) |
|
|
223
|
+
| `/undo [turns]` | Revert file changes |
|
|
224
|
+
| `/tools` | Available tools |
|
|
225
|
+
| `/skills [query\|all\|off]` | Browse, search, load skills |
|
|
226
|
+
| `/plugin [install\|remove\|pack]` | Manage plugins |
|
|
227
|
+
| `/cost` | Session usage |
|
|
228
|
+
| `/status` | Connection status |
|
|
229
|
+
| `/scan [save]` | Sweep this machine for local model servers (`save` registers them) |
|
|
230
|
+
| `/sessions` | Past conversations in this folder |
|
|
231
|
+
| `/init` | Create a `DEEL.md` rules file |
|
|
232
|
+
| `/exit` | Quit |
|
|
233
|
+
|
|
234
|
+
Discovered plugin commands are invoked as `/<plugin>:<name>`, with `$ARGUMENTS` substituted.
|
|
235
|
+
|
|
236
|
+
`/scan` and `/sessions` work without leaving the session. If you just started another local
|
|
237
|
+
server or loaded a different model, `/scan save` then `/model` switches over without losing
|
|
238
|
+
the conversation.
|
|
239
|
+
|
|
240
|
+
### Interrupting
|
|
241
|
+
|
|
242
|
+
Press **Ctrl+C** to stop the model mid-answer when it is heading the wrong way.
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
❯ rewrite the whole test suite
|
|
246
|
+
◧ Read test/smoke.js
|
|
247
|
+
◧ Read test/loop.test.js
|
|
248
|
+
^C
|
|
249
|
+
⚠ Stopped (after step 2)
|
|
250
|
+
|
|
251
|
+
❯ ▊
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
The conversation stays valid. If the model had announced tool calls, each unanswered one is
|
|
255
|
+
filled with a `stopped by user` result so the call/result pairing holds — a conversation with
|
|
256
|
+
broken pairing is rejected with HTTP 400 on the next request, which would waste the whole
|
|
257
|
+
session. Tools already running finish; **tools not yet started never run.**
|
|
258
|
+
|
|
259
|
+
Pressing Ctrl+C again on an empty line quits.
|
|
96
260
|
|
|
97
261
|
---
|
|
98
262
|
|
|
99
|
-
##
|
|
263
|
+
## Work modes
|
|
264
|
+
|
|
265
|
+
What you are working on changes **which tools the model is given and how hard it thinks.**
|
|
266
|
+
Cycle with `Shift+Tab`, or type the name.
|
|
267
|
+
|
|
268
|
+
| Mode | For | Can edit files | Reasoning |
|
|
269
|
+
|---|---|---|---|
|
|
270
|
+
| `/auto` ◎ Auto | **Default.** Reads your message and switches for you | Yes | Normal (`save`) |
|
|
271
|
+
| `/code` ◆ Code | Writing and fixing | Yes | Normal (`save`) |
|
|
272
|
+
| `/plan` ☰ Plan | Planning first | **No** | Deep (`deep`·high) |
|
|
273
|
+
| `/architect` ◈ Architect | Shaping structure | **No** | Deep (`deep`·high) |
|
|
274
|
+
| `/debug` ◉ Debug | Finding causes | Yes | Deep, more steps (32) |
|
|
275
|
+
| `/ask` ◇ Ask | Explaining only | **No** | Shallow (`low`) |
|
|
276
|
+
| `/orchestrator` ❋ Orchestrator | Breaking up large work | Yes | Many steps (40) |
|
|
277
|
+
|
|
278
|
+
In read-only modes, `Write`, `Edit` and `Bash` are **never sent to the model at all.**
|
|
279
|
+
It is not asked politely not to edit — models forget requests. A tool that isn't there can't be used.
|
|
280
|
+
|
|
281
|
+
Don't confuse this with `/mode`. They are separate axes:
|
|
282
|
+
|
|
283
|
+
- `/mode` — **how much it asks you** (auto · confirm · strict)
|
|
284
|
+
- `/work` — **what kind of work you are doing** (the seven above)
|
|
285
|
+
|
|
286
|
+
If you have explicitly set `/think` or `/mode`, your choice wins. A work mode never
|
|
287
|
+
overrides something a person chose.
|
|
288
|
+
|
|
289
|
+
### Switching by itself (Auto mode)
|
|
100
290
|
|
|
101
|
-
|
|
102
|
-
|
|
291
|
+
You start in **Auto**. Nothing has been decided about what kind of work is coming.
|
|
292
|
+
Every turn, deel reads what you typed, picks the mode that fits, and works in it.
|
|
103
293
|
|
|
104
294
|
```
|
|
105
|
-
|
|
106
|
-
skills: 337 · commands: 127 (42 plugins)
|
|
295
|
+
❯ why won't the login go through?
|
|
107
296
|
|
|
108
|
-
|
|
297
|
+
◉ Debug because your message contained "why won't", "won't"
|
|
298
|
+
Not what you wanted? Type /code to pin a mode yourself.
|
|
299
|
+
```
|
|
109
300
|
|
|
110
|
-
|
|
111
|
-
|
|
301
|
+
Switching brings **the whole mode** with it — its working protocol, its tool set, its
|
|
302
|
+
reasoning settings. It isn't a label saying "debug mode": the model is actually walked
|
|
303
|
+
through symptom → reproduce → hypothesis → evidence, and in Plan mode `Write` and `Edit`
|
|
304
|
+
are not handed over at all.
|
|
112
305
|
|
|
113
|
-
|
|
114
|
-
|
|
306
|
+
| When you say | It goes to |
|
|
307
|
+
|---|---|
|
|
308
|
+
| why won't · error · fails · crashes · what's causing | ◉ Debug |
|
|
309
|
+
| plan · roadmap · what order · let's map it out first | ☰ Plan |
|
|
310
|
+
| design · architecture · how should this be structured · how to split | ◈ Architect |
|
|
311
|
+
| what is · explain · how does it work · difference between | ◇ Ask |
|
|
312
|
+
| all of · everything · one by one · to the end · unify | ❋ Orchestrator |
|
|
313
|
+
| fix · add · implement · rename · delete | ◆ Code |
|
|
115
314
|
|
|
116
|
-
|
|
117
|
-
|
|
315
|
+
**When it's close, it doesn't switch.** "ok", "go on", "that thing from earlier" leave you
|
|
316
|
+
in Auto. So does a near-tie between first and second place — a wrong switch into a read-only
|
|
317
|
+
mode leaves you blocked without knowing *why*. Read-only modes (Plan, Architect, Ask)
|
|
318
|
+
therefore carry a higher bar: "explain this and fix it" routes to Code, not Ask.
|
|
118
319
|
|
|
119
|
-
|
|
320
|
+
A switch lasts **one turn only.** The next message is judged fresh.
|
|
321
|
+
A `~` in the status line means it switched by itself; no `~` means you chose it.
|
|
120
322
|
|
|
121
|
-
─ 4.2s · 3 tools · 180 tokens
|
|
122
323
|
```
|
|
324
|
+
◎ Auto ← waiting
|
|
325
|
+
~◉ Debug ← this turn only, chosen for you
|
|
326
|
+
◉ Debug ← you typed /debug. It stays.
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Choosing a mode yourself **pins** it. `/auto` (or `/work auto`) hands the wheel back.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Simple vs developer
|
|
334
|
+
|
|
335
|
+
Twenty commands on first launch means nothing gets chosen. Locking features away means
|
|
336
|
+
hitting a wall later. So only **what is shown** differs.
|
|
337
|
+
|
|
338
|
+
| | Simple (`쉬움`, default) | Developer (`개발자`) |
|
|
339
|
+
|---|---|---|
|
|
340
|
+
| `/help` listing | Common commands only | Everything |
|
|
341
|
+
| Error messages | What to do about it | The original text |
|
|
342
|
+
| Safety | **Identical** | **Identical** |
|
|
343
|
+
|
|
344
|
+
`/level 개발자` is saved to config and persists across sessions.
|
|
345
|
+
|
|
346
|
+
Two things matter here:
|
|
347
|
+
|
|
348
|
+
- **Hidden commands still work.** `/think high` works in simple mode. It just isn't listed.
|
|
349
|
+
- **Beginners do not get fewer safeguards.** Undo, workspace scope and dangerous-command
|
|
350
|
+
blocking are identical. A beginner needs the undo more, not less.
|
|
123
351
|
|
|
124
|
-
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Tools
|
|
125
355
|
|
|
126
|
-
Names
|
|
356
|
+
Names and arguments match Claude Code, so skills written for that convention work unchanged.
|
|
127
357
|
|
|
128
|
-
|
|
|
358
|
+
| Tool | What it does |
|
|
129
359
|
|---|---|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
132
|
-
|
|
|
133
|
-
|
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
|
|
|
139
|
-
|
|
360
|
+
| `Read` | Read a file (line numbers, `offset`/`limit`, **Excel as CSV**) |
|
|
361
|
+
| `Write` | Write / overwrite a file |
|
|
362
|
+
| `Edit` | Replace an exact string (`replace_all` supported) |
|
|
363
|
+
| `Glob` | Find files by name pattern |
|
|
364
|
+
| `Grep` | Regex search file contents |
|
|
365
|
+
| `Bash` | Run a command |
|
|
366
|
+
| `Skill` | Expand a skill body (shown to the model only when skills exist) |
|
|
367
|
+
| `WebFetch` | Read a web page (read-only; hidden under `--offline`) |
|
|
368
|
+
| `TodoWrite` | Checklist — breaks long work into steps and shows progress |
|
|
369
|
+
|
|
370
|
+
### Checklists
|
|
371
|
+
|
|
372
|
+
Keeps the model from losing its place on multi-step work. The list is redrawn whenever the
|
|
373
|
+
model updates it.
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
☰ Todo 1/3 done ← just finished 1
|
|
377
|
+
|
|
378
|
+
✓ unify log format
|
|
379
|
+
▶ fix the tests
|
|
380
|
+
☐ update the docs
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Only one item may be **in progress** at a time; setting two is refused. Holding several at
|
|
384
|
+
once is how nothing gets finished.
|
|
385
|
+
|
|
386
|
+
### Read-only tools run together
|
|
387
|
+
|
|
388
|
+
When the model asks for three `Read` calls at once, all three run **concurrently** — sweeping
|
|
389
|
+
five files costs about what reading one costs.
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
◧ Read src/a.js ◧ Read src/b.js ◧ Read src/c.js together
|
|
393
|
+
```
|
|
140
394
|
|
|
141
|
-
|
|
395
|
+
Only `Read`, `Glob`, `Grep`, `Skill` and `WebFetch` are eligible. `Write`, `Edit` and `Bash`
|
|
396
|
+
always run one at a time — two concurrent writes to one file scramble the undo snapshot
|
|
397
|
+
order, and `Bash` can do anything. Results come back **in the order the model asked for
|
|
398
|
+
them**, even when they finish out of order; shuffled results confuse the model about which
|
|
399
|
+
result belongs to which call.
|
|
142
400
|
|
|
143
|
-
|
|
144
|
-
convention work unchanged.
|
|
401
|
+
### Edits survive small mistakes
|
|
145
402
|
|
|
146
|
-
|
|
403
|
+
Models routinely get whitespace, indentation and line endings wrong. deel relaxes matching in
|
|
404
|
+
stages but **refuses outright when the match is ambiguous** — silently editing the wrong place is
|
|
405
|
+
far worse than not finding it.
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
exact → ignore trailing space / CRLF → ignore indentation → ignore all whitespace
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Measured with `npm run bench`:
|
|
412
|
+
|
|
413
|
+
| | Success | Wrong place edited |
|
|
414
|
+
|---|---|---|
|
|
415
|
+
| Exact match only | 20% | 0 |
|
|
416
|
+
| Staged relaxation | **100%** | **0** |
|
|
417
|
+
|
|
418
|
+
On failure it points at the closest line in the file.
|
|
147
419
|
|
|
148
420
|
---
|
|
149
421
|
|
|
150
|
-
##
|
|
422
|
+
## Korean text and Excel
|
|
151
423
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
424
|
+
### Encoding — written back the way it was read
|
|
425
|
+
|
|
426
|
+
Corporate documents are often not UTF-8. Files saved by old Windows Notepad in a legacy
|
|
427
|
+
codepage (CP949 in Korea, CP932 in Japan, GBK in China) are still around. Reading one as
|
|
428
|
+
UTF-8 garbles it completely: `한글` becomes `�ѱ�`.
|
|
429
|
+
|
|
430
|
+
Writing is the dangerous part. Read it garbled, save it as UTF-8, and the original is gone.
|
|
431
|
+
So there is one rule: **write it back in the encoding it was read in.**
|
|
432
|
+
|
|
433
|
+
Which encoding that is comes from **the file's contents, not the machine's settings.**
|
|
434
|
+
Each candidate is decoded strictly, then scored on whether the result looks like real text
|
|
435
|
+
written in that encoding. So the same CP949 document reads identically on Ubuntu, on a US
|
|
436
|
+
Windows machine, and on a Korean one.
|
|
155
437
|
|
|
156
438
|
```
|
|
157
|
-
|
|
439
|
+
› Read report.txt
|
|
440
|
+
└ 4 lines · CP949
|
|
158
441
|
```
|
|
159
442
|
|
|
160
|
-
|
|
443
|
+
If you try to insert a character that encoding **cannot hold**, it refuses instead of saving.
|
|
161
444
|
|
|
162
445
|
```
|
|
163
|
-
|
|
164
|
-
|
|
446
|
+
› Edit report.txt note → note 🚀
|
|
447
|
+
└ This file is CP949, and you are inserting a character that encoding does not have: 🚀
|
|
165
448
|
```
|
|
166
449
|
|
|
167
|
-
|
|
450
|
+
Silently substituting question marks would be worse than not writing at all.
|
|
451
|
+
Newly created files are UTF-8.
|
|
452
|
+
|
|
453
|
+
Command output is handled the same way. A Windows console is not UTF-8, so taking `Bash`
|
|
454
|
+
output as utf8 garbles non-ASCII text. It is collected as bytes and decoded afterwards.
|
|
455
|
+
|
|
456
|
+
### Excel — read as CSV
|
|
457
|
+
|
|
458
|
+
An Excel file is a compressed archive, not text, so normally you get "this is a binary file"
|
|
459
|
+
and somebody has to export a CSV by hand. `Read` just does it.
|
|
168
460
|
|
|
169
461
|
```
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
console.log("start: " + id);
|
|
173
|
-
Copy that line verbatim and try again.
|
|
462
|
+
› Read report.xlsx
|
|
463
|
+
└ 3 sheets · 128 rows · unpacked directly
|
|
174
464
|
```
|
|
175
465
|
|
|
466
|
+
- **Still zero dependencies.** An xlsx is a zip full of XML, so Node's built-in `zlib` is enough.
|
|
467
|
+
- Every sheet is returned. Hidden sheets too, marked as hidden.
|
|
468
|
+
- Dates come back as dates, not serial numbers — the cell format is read to decide.
|
|
469
|
+
- Formulas come back as **computed values**, and error values like `#REF!` are not dropped.
|
|
470
|
+
|
|
471
|
+
**Password-protected files and legacy `.xls`** are handed to Excel itself; those cannot be
|
|
472
|
+
unpacked directly. You are asked for the password at that point.
|
|
473
|
+
|
|
474
|
+
The password is **not stored anywhere**:
|
|
475
|
+
|
|
476
|
+
- not in the config file
|
|
477
|
+
- not in the session log
|
|
478
|
+
- not in the audit log
|
|
479
|
+
- not as a command-line argument (other people can see your command lines)
|
|
480
|
+
|
|
481
|
+
The only path out is the child process's stdin, and a test asserts that this stays true.
|
|
482
|
+
Extracted intermediate files are deleted after use.
|
|
483
|
+
|
|
484
|
+
> **Excel files are read-only here.** `Edit` and `Write` refuse them, and say why and what
|
|
485
|
+
> to do instead. Round-tripping a file with formatting, formulas and charts through CSV
|
|
486
|
+
> always loses something. Better not to write than to write knowing you'll lose data.
|
|
487
|
+
|
|
176
488
|
---
|
|
177
489
|
|
|
178
|
-
## Skills and
|
|
490
|
+
## Skills and plugins
|
|
179
491
|
|
|
180
|
-
|
|
492
|
+
**deel does not carry skills with it.** On startup it scans the machine it is running on and uses
|
|
493
|
+
whatever is there. On a clean PC: zero. On a PC with skills installed: those skills.
|
|
181
494
|
|
|
182
495
|
```
|
|
183
496
|
project ./.deel/skills ./.claude/skills ./.deel/commands ./.claude/commands
|
|
184
497
|
user ~/.deel/skills ~/.claude/skills ~/.claude/commands
|
|
185
|
-
plugins ~/.claude/plugins/**
|
|
498
|
+
plugins ~/.claude/plugins/** ~/.deel/plugins/**
|
|
186
499
|
```
|
|
187
500
|
|
|
188
|
-
|
|
189
|
-
`commands/*.md` with `$ARGUMENTS` substitution.
|
|
501
|
+
Reads the Claude Code format: `SKILL.md` with YAML front matter, `commands/*.md`, `$ARGUMENTS`.
|
|
190
502
|
|
|
191
503
|
### Loaded in three stages
|
|
192
504
|
|
|
193
|
-
|
|
505
|
+
Loading everything would blow the context window.
|
|
194
506
|
|
|
195
507
|
| Stage | What | Cost |
|
|
196
508
|
|---|---|---|
|
|
197
|
-
| 1 |
|
|
198
|
-
| 2 |
|
|
199
|
-
| 3 |
|
|
509
|
+
| 1 | Name + one-line description in the prompt | ~1,800 tokens for 40 skills |
|
|
510
|
+
| 2 | Body of the one the model picks via `Skill` | one at a time |
|
|
511
|
+
| 3 | Files that body references, via `Read` | on demand |
|
|
512
|
+
|
|
513
|
+
### Fetching plugins
|
|
200
514
|
|
|
201
|
-
|
|
202
|
-
|
|
515
|
+
```bash
|
|
516
|
+
# on a connected machine
|
|
517
|
+
/plugin install affaan-m/ECC # git clone, or tarball when git is absent
|
|
518
|
+
/plugin pack import.zip # bundle, excluding executable scripts
|
|
203
519
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
520
|
+
# on the air-gapped machine — just unzip
|
|
521
|
+
unzip import.zip -d ~/.deel/plugins/
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
`/plugin pack` omits `.js` `.sh` `.ps1` `.py` and friends, and includes a plain-text manifest
|
|
525
|
+
with a licence table — ready to hand to a security reviewer.
|
|
526
|
+
|
|
527
|
+
### Deliberately not included
|
|
528
|
+
|
|
529
|
+
| | Why |
|
|
530
|
+
|---|---|
|
|
531
|
+
| hooks | Executable scripts — fails import review, widens the blast radius of autonomy |
|
|
532
|
+
| sub-agents | Doubles model calls against a gateway quota |
|
|
533
|
+
| MCP | A separate protocol; a project of its own |
|
|
207
534
|
|
|
208
535
|
---
|
|
209
536
|
|
|
210
|
-
##
|
|
537
|
+
## Reasoning effort
|
|
538
|
+
|
|
539
|
+
One answer means several model calls, and **each needs a different amount of thinking.**
|
|
540
|
+
All-high is slow; all-low wanders off.
|
|
541
|
+
|
|
542
|
+
```
|
|
543
|
+
$ /think
|
|
211
544
|
|
|
212
|
-
|
|
213
|
-
The safety net is that everything is **reversible**, not that everything is gated.
|
|
545
|
+
Base medium Profile save Hard on the first decision, light while continuing
|
|
214
546
|
|
|
215
|
-
|
|
547
|
+
Stage Effort Cap When
|
|
548
|
+
first call · medium 4,096 deciding what to do
|
|
549
|
+
continuing ↓ low 2,048 reading a tool result, picking the next step
|
|
550
|
+
stuck ↑ high 4,096 the previous tool errored
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
| Profile | Character |
|
|
554
|
+
|---|---|
|
|
555
|
+
| `even` | Same effort everywhere — predictable, slower |
|
|
556
|
+
| `save` (default) | Hard on the first decision only |
|
|
557
|
+
| `deep` | Everything one notch up — for hard work |
|
|
558
|
+
|
|
559
|
+
### Context length is read off the model
|
|
560
|
+
|
|
561
|
+
This one number sizes the whole program: how many files fit in one read, when the
|
|
562
|
+
conversation gets folded, how long a single reply may be — **all of it comes from here.**
|
|
563
|
+
|
|
564
|
+
So deel asks the server on every launch rather than trusting the saved value. The same
|
|
565
|
+
model name can be loaded at a different length each time, and if that difference never
|
|
566
|
+
reaches the screen there is no way to notice. **It just quietly gets smaller.**
|
|
567
|
+
|
|
568
|
+
```
|
|
569
|
+
│ Model qwen3-coder (640k tokens) │
|
|
570
|
+
╰─────────────────────────────────────────────────────────╯
|
|
571
|
+
✓ Context adjusted 32,768 → 655,360 (read from LM Studio)
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
Every server puts this number under a different name in a different place, so deel checks
|
|
575
|
+
all of them.
|
|
576
|
+
|
|
577
|
+
| Server | Where it reads |
|
|
216
578
|
|---|---|
|
|
217
|
-
|
|
|
218
|
-
|
|
|
219
|
-
|
|
|
220
|
-
|
|
|
221
|
-
|
|
|
579
|
+
| LM Studio | `/api/v0/models` — `max_context_length`, `loaded_context_length` |
|
|
580
|
+
| llama.cpp | `/props` — `n_ctx` |
|
|
581
|
+
| vLLM | `/v1/models` — `max_model_len` |
|
|
582
|
+
| Ollama | `/api/show` — `<model>.context_length` |
|
|
583
|
+
| Other OpenAI-compatible | `/v1/models/<model>` — `context_window`, `context_length`, `max_input_tokens`, `max_position_embeddings` (found even when nested) |
|
|
584
|
+
|
|
585
|
+
**Model maximum and loaded length are not the same thing.** LM Studio will happily load a
|
|
586
|
+
655,360-capable model at 8,192. Trusting the maximum there gets your requests rejected. So
|
|
587
|
+
the **loaded length is what deel uses**, and the maximum is reported separately.
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
⚠ This model goes up to 655,360 — raise it on the server, then /ctx auto
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
| Command | What it does |
|
|
594
|
+
|---|---|
|
|
595
|
+
| `/ctx` | Current length and remaining room |
|
|
596
|
+
| `/ctx auto` | Ask the server again and match the model |
|
|
597
|
+
| `/ctx 655360` | Set it yourself (`640k`, `128k`, `1m` also work) |
|
|
598
|
+
| `/ctx out 32k` | Cap on a **single reply** — a different axis from context |
|
|
599
|
+
| `deel --ctx 655360` | Start at this value (skips the lookup) |
|
|
600
|
+
|
|
601
|
+
**`k` means 1024 here.** Context lengths are all powers of two, so that is the only base
|
|
602
|
+
that lines up: 655,360 is `640k`, not `655k`; 131,072 is `128k`, not `131k`. The display and
|
|
603
|
+
`/ctx` use the same unit, so typing back what you see gives you the same number.
|
|
604
|
+
|
|
605
|
+
**Caps are not fixed numbers.** They are computed from the model's context window and how
|
|
606
|
+
much of it is currently used — the profile decides what share of the remaining room a stage gets.
|
|
607
|
+
|
|
608
|
+
| Model | First call | Continuing | Stuck |
|
|
609
|
+
|---|---|---|---|
|
|
610
|
+
| 2k local | 554 | 512 | 554 |
|
|
611
|
+
| 8k local | 2,007 | 1,003 | 2,007 |
|
|
612
|
+
| 40k (qwen3) | 11,688 | 5,844 | 11,688 |
|
|
613
|
+
| 128k gateway | 16,384 | 16,384 | 16,384 |
|
|
614
|
+
| 128k, 80% full | 7,680 | 3,840 | 7,680 |
|
|
615
|
+
|
|
616
|
+
Caps shrink as the context fills. Handing a 4k model a 4,096-token cap would leave no room for input.
|
|
617
|
+
Raise the ceiling with `maxTokens` in the profile if you need more.
|
|
618
|
+
|
|
619
|
+
If a saved cap truncates a reply, **that step alone is retried with the cap lifted.**
|
|
620
|
+
A truncated reply means a half-written tool call, which fails silently.
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
## Auto-compaction
|
|
625
|
+
|
|
626
|
+
At 80% context, older turns are **summarised and folded** so work continues.
|
|
627
|
+
Plain truncation makes the model forget: it re-reads files and re-fixes what it already fixed.
|
|
628
|
+
|
|
629
|
+
```
|
|
630
|
+
◱ Folded 44 turns into a summary — 10,399 → 3,170 tokens (70% smaller)
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
The summary keeps goal / done / learned / decided / remaining. The cut point is chosen so a
|
|
634
|
+
**tool call is never separated from its result** — splitting them makes the server return 400.
|
|
635
|
+
If the summary request fails, it falls back to plain trimming rather than stopping.
|
|
636
|
+
|
|
637
|
+
`/compact` folds on demand.
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## Resuming a conversation
|
|
642
|
+
|
|
643
|
+
Close the terminal by accident, or reboot, and the conversation is still there.
|
|
644
|
+
Messages are written to `.deel/sessions/` **as each one completes**, so a crash
|
|
645
|
+
loses at most the message in flight.
|
|
646
|
+
|
|
647
|
+
```
|
|
648
|
+
$ deel sessions
|
|
649
|
+
|
|
650
|
+
── conversations in this folder ────────────────────────────────
|
|
651
|
+
● 20260824-090200 just now 1 turn devstral-small-2507
|
|
652
|
+
fix the failing test
|
|
653
|
+
· 20260824-084500 2h ago 2 turns qwen2.5-coder:7b
|
|
654
|
+
switch src/a.js logging to the logger
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
| Command | What it does |
|
|
658
|
+
|---|---|
|
|
659
|
+
| `deel --continue` | Resume the most recent conversation in this folder |
|
|
660
|
+
| `deel --resume <id>` | Resume a specific one |
|
|
661
|
+
| `deel sessions` | List what is stored |
|
|
662
|
+
| `deel sessions --rm <id>` | Delete one |
|
|
663
|
+
|
|
664
|
+
The format is `jsonl` — one message per line — so a power cut costs only the last line.
|
|
665
|
+
Resumed history keeps tool calls paired with their results, so work continues immediately.
|
|
666
|
+
Conversations older than 30 days and outside the most recent 30 are pruned automatically.
|
|
222
667
|
|
|
223
|
-
|
|
224
|
-
|
|
668
|
+
Everything lives in `.deel/sessions/` inside the working folder, and `.gitignore`
|
|
669
|
+
covers `.deel/` so it never reaches a repository.
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
## Safety
|
|
674
|
+
|
|
675
|
+
Instead of approval prompts, the design makes things **reversible**. The default `auto` mode
|
|
676
|
+
does not ask.
|
|
677
|
+
|
|
678
|
+
| Mechanism | Detail |
|
|
679
|
+
|---|---|
|
|
680
|
+
| **Undo** | Snapshot before every write. `/undo` restores per turn |
|
|
681
|
+
| **Scope** | Outside the starting folder is refused, even if the model insists |
|
|
682
|
+
| **Blocked commands** | Only irreversible ones (disk format, recursive delete, `--force` push) |
|
|
683
|
+
| **No re-run** | A mutating command is never retried after failure |
|
|
684
|
+
| **Interrupt** | Ctrl+C stops mid-answer and leaves the conversation valid |
|
|
685
|
+
| **Audit log** | Everything recorded in `.deel/audit.jsonl` |
|
|
686
|
+
|
|
687
|
+
| Mode | Asks when |
|
|
688
|
+
|---|---|
|
|
689
|
+
| `auto` (default) | Never — undo is the safety net |
|
|
690
|
+
| `confirm` | Irreversible commands only |
|
|
691
|
+
| `strict` | All file changes and commands |
|
|
692
|
+
|
|
693
|
+
Undo history stores whole file contents, so repeated edits to large files add up. Past 32MB
|
|
694
|
+
it keeps the **most recent 50 turns** and drops the rest. What you just did is always
|
|
695
|
+
undoable; `/status` shows how large the history currently is.
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
## Corporate review package
|
|
700
|
+
|
|
701
|
+
```bash
|
|
702
|
+
deel pack --out deel-import.zip
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
```
|
|
706
|
+
✓ deel-import.zip
|
|
707
|
+
39 files · 100.2KB
|
|
708
|
+
|
|
709
|
+
Dependencies 0
|
|
710
|
+
Install scripts none
|
|
711
|
+
External imports 0
|
|
712
|
+
Network calls 3 sites (configured address only)
|
|
713
|
+
Ports opened none
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
The bundled review sheet contains:
|
|
717
|
+
|
|
718
|
+
- Dependency list and every external `import` in the source
|
|
719
|
+
- Presence of `preinstall` / `install` / `postinstall` / `prepare`
|
|
720
|
+
- **Every network and process-spawn call site found by scanning the source** (file:line)
|
|
721
|
+
- The three outbound lanes, explained
|
|
722
|
+
- SHA-256 per file (verify with `certutil -hashfile`)
|
|
723
|
+
|
|
724
|
+
It is generated by scanning the source, not written by hand — hand-written sheets drift from reality.
|
|
725
|
+
Use `deel audit` to read it without building a zip.
|
|
726
|
+
|
|
727
|
+
### Diagnosing a corporate gateway
|
|
728
|
+
|
|
729
|
+
```bash
|
|
730
|
+
node bin/deel.js diagnose --url <gateway> --key <key> --model <model> --out report.txt
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
Hand over `report.txt` alone — plain text, no colour codes.
|
|
734
|
+
|
|
735
|
+
| Check | Why it matters |
|
|
736
|
+
|---|---|
|
|
737
|
+
| Basic chat | Address, key and model name are right |
|
|
738
|
+
| System message | Rules (`DEEL.md`) and skills take effect |
|
|
739
|
+
| Streaming | Output can flow token by token |
|
|
740
|
+
| **Tool calls** | **Whether it can read and edit files — the critical one** |
|
|
741
|
+
| **Tool results** | **Whether multi-turn works — the premise of the agent loop** |
|
|
742
|
+
| Structured output | Edit format can be enforced by schema |
|
|
743
|
+
| Reasoning control | Whether `/think` works at the model layer |
|
|
744
|
+
| Context length | How many files can be read at once |
|
|
745
|
+
|
|
746
|
+
Verdict is one of **ready · limited · blocked · unreachable**.
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
750
|
+
## Configuration
|
|
751
|
+
|
|
752
|
+
Stored in `~/.deel/config.json`. A `.deel/config.json` in the project folder takes precedence.
|
|
753
|
+
|
|
754
|
+
### Supported servers
|
|
755
|
+
|
|
756
|
+
| | Example address |
|
|
757
|
+
|---|---|
|
|
758
|
+
| Corporate AI gateway (OpenAI-compatible) | `https://ai-gw.example.corp/v1` |
|
|
759
|
+
| Ollama | `http://localhost:11434` |
|
|
760
|
+
| LM Studio | `http://localhost:1234/v1` |
|
|
761
|
+
| llama.cpp · vLLM · LiteLLM | `http://host:port/v1` |
|
|
762
|
+
|
|
763
|
+
Auth style is detected automatically: `Authorization: Bearer` → `x-api-key` → `api-key` (Azure) → none.
|
|
764
|
+
|
|
765
|
+
### Environment variables
|
|
766
|
+
|
|
767
|
+
| Variable | Use |
|
|
768
|
+
|---|---|
|
|
769
|
+
| `DEEL_API_KEY` | Keep the key out of the config file (takes precedence) |
|
|
770
|
+
| `DEEL_KEY_<PROFILE_ID>` | Per-profile key |
|
|
771
|
+
| `NODE_EXTRA_CA_CERTS` | Corporate TLS certificate |
|
|
772
|
+
| `HTTPS_PROXY` | Behind a proxy |
|
|
773
|
+
| `DEEL_DEBUG=1` | Verbose errors |
|
|
774
|
+
| `NO_COLOR` | Disable colour |
|
|
775
|
+
|
|
776
|
+
### Flags
|
|
777
|
+
|
|
778
|
+
```bash
|
|
779
|
+
deel --root <folder> Working scope. Defaults to the current folder
|
|
780
|
+
deel --mode <mode> auto (default) / confirm / strict
|
|
781
|
+
deel --work <mode> auto (default) / code / plan / architect / debug / ask / orchestrator
|
|
782
|
+
deel --level <level> 쉬움 (simple) / 개발자 (developer)
|
|
783
|
+
deel --think <level> off / low / medium (default) / high / max
|
|
784
|
+
deel --effort <profile> even / save (default) / deep
|
|
785
|
+
deel --offline Nothing leaves this machine
|
|
786
|
+
deel --continue Resume the most recent conversation
|
|
787
|
+
deel --resume <id> Resume a specific one
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
### Project rules
|
|
791
|
+
|
|
792
|
+
If the working folder has `DEEL.md`, `CLAUDE.md` or `AGENTS.md`, it is loaded as project rules.
|
|
793
|
+
`/init` scaffolds one.
|
|
794
|
+
|
|
795
|
+
---
|
|
796
|
+
|
|
797
|
+
## Troubleshooting
|
|
798
|
+
|
|
799
|
+
| Symptom | Check |
|
|
800
|
+
|---|---|
|
|
801
|
+
| `address not found` | Typo, DNS, VPN / intranet connectivity |
|
|
802
|
+
| `connection refused` | Server is down or the port differs |
|
|
803
|
+
| certificate error | `set NODE_EXTRA_CA_CERTS=C:\path\corp-ca.pem` |
|
|
804
|
+
| behind a proxy | `set HTTPS_PROXY=http://proxy:port` |
|
|
805
|
+
| 401 / 403 | Wrong key or auth header style (four are tried automatically) |
|
|
806
|
+
| `address not permitted` | The lock did its job — pick a connection with `/model` |
|
|
807
|
+
| Tool calls don't work | Run `deel diagnose`. Small models (1B–3B) often can't |
|
|
808
|
+
| Empty replies | A heavy-reasoning model — try `/think low` |
|
|
809
|
+
| `deel scan` finds nothing | Server is off or on another port — use `--ports` |
|
|
225
810
|
|
|
226
811
|
---
|
|
227
812
|
|
|
228
813
|
## Development
|
|
229
814
|
|
|
230
815
|
```bash
|
|
231
|
-
npm
|
|
232
|
-
npm
|
|
233
|
-
npm run
|
|
234
|
-
npm run
|
|
816
|
+
npm test Full suite (254 checks)
|
|
817
|
+
npm run verify Import + network checks only
|
|
818
|
+
npm run bench Edit success rate
|
|
819
|
+
npm run demo See what the UI actually looks like
|
|
820
|
+
npm run check Syntax check every file
|
|
235
821
|
```
|
|
236
822
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
823
|
+
Tests run against a **fake gateway**, so the loop, streaming, tool execution, undo and compaction
|
|
824
|
+
are verified deterministically without any model. ZIP output is cross-checked with the real
|
|
825
|
+
`unzip`; the TAR reader is fed archives produced by the real `tar`.
|
|
826
|
+
|
|
827
|
+
`npm test` runs each file separately and reports **per-file exit codes**, because the exit code
|
|
828
|
+
— not the pass marks on screen — is what CI reads, and the two can disagree: a file can pass
|
|
829
|
+
every check and still die on the way out, leaving the screen green and the exit code 1. That
|
|
830
|
+
happened once on Windows and cost a lot of time. The runner does not stop at the first failure,
|
|
831
|
+
so one run tells you everything.
|
|
832
|
+
|
|
833
|
+
| Suite | Checks | Covers |
|
|
834
|
+
|---|---|---|
|
|
835
|
+
| `smoke` | 20 | Tools, scope, undo, audit log |
|
|
836
|
+
| `loop` | 16 | Agent loop, streaming, tool calls |
|
|
837
|
+
| `network` | 30 | Nothing escapes the configured address |
|
|
838
|
+
| `web` | 25 | Web reads stay read-only |
|
|
839
|
+
| `abort` | 16 | Ctrl+C leaves the conversation valid |
|
|
840
|
+
| `parallel` | 23 | Read-only tools run together; checklists |
|
|
841
|
+
| `compact` | 21 | Summary folding, pairing intact, graceful fallback |
|
|
842
|
+
| `store` | 34 | Session persistence, resume, crash recovery |
|
|
843
|
+
| `scan` | 19 | Distinguishing multiple runtimes |
|
|
844
|
+
| `plugins` | 38 | Plugin fetch/pack, ZIP/TAR |
|
|
845
|
+
| `no-bundle` | 12 | Nothing foreign in the published package; test-file hygiene |
|
|
846
|
+
| `edit-bench` | 20 cases | Edit success rate |
|
|
241
847
|
|
|
242
848
|
---
|
|
243
849
|
|
|
244
|
-
##
|
|
850
|
+
## Licence
|
|
245
851
|
|
|
246
|
-
MIT
|
|
852
|
+
[MIT](LICENSE)
|