deel-local-cli 0.9.0 → 1.0.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 CHANGED
@@ -24,7 +24,7 @@
24
24
  ╰──────────────────────────────────────────────────────────────╯
25
25
  /help 명령 목록 /think 추론 강도 Ctrl+C 중단·끝내기
26
26
 
27
- ▏myproject qwen2.5-coder:7b ▏▰▰▱▱▱▱▱▱▱▱ 22% 28k/128k ▏◇ medium·절약 auto
27
+ ▏myproject · qwen2.5-coder:7b ▰▰▱▱▱▱▱▱▱▱ 22% 28k/128k ◎ 종합 · ◇ medium·절약 · auto
28
28
  ❯ 로그 형식 통일해줘
29
29
 
30
30
  ❊ Grep(console.log)
@@ -34,7 +34,7 @@
34
34
  ◈ Edit(src/runner.js)
35
35
  └ 1군데
36
36
 
37
- 로그 호출을 logger 형식으로 통일했습니다. runner.js 한 군데를 고쳤습니다.
37
+ 로그 호출을 logger 형식으로 통일했습니다. runner.js 한 군데를 고쳤습니다.
38
38
 
39
39
  ── 4.2초 · 도구 3회 · ↑3,900 ↓180
40
40
  ```
@@ -56,6 +56,7 @@
56
56
  - [추론 강도](#추론-강도)
57
57
  - [자동 압축](#자동-압축)
58
58
  - [대화 이어하기](#대화-이어하기)
59
+ - [밖에서 도구 붙이기 (MCP)](#밖에서-도구-붙이기-mcp)
59
60
  - [안전망](#안전망)
60
61
  - [사내 반입](#사내-반입)
61
62
  - [설정](#설정)
@@ -219,17 +220,21 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
219
220
  |---|---|
220
221
  | `/help` | 명령 목록 |
221
222
  | `/context` | 무엇이 컨텍스트를 먹고 있는지 |
222
- | `/ctx [auto\|숫자]` | 컨텍스트 **길이** — 모델에 맞춰 다시 재거나 직접 지정 |
223
+ | `/ctx [auto\|숫자\|자세히]` | 컨텍스트 **길이** — 모델에 맞춰 다시 재거나 직접 지정 |
224
+ | `/out [숫자\|auto]` | 한 번에 받을 **답 길이** 상한 — 큰 파일이 잘리면 여기를 올립니다 |
223
225
  | `/compact` | 앞선 대화를 요약해서 접기 |
224
226
  | `/clear` | 대화 비우기 (연결·규칙은 유지) |
225
227
  | `/model` | 연결·모델 바꾸기 |
226
- | `/think <강도\|배분>` | 추론 강도 (`off·low·medium·high·max`) 또는 배분 (`even·save·deep`) |
228
+ | `/think <강도>` | 추론 강도 (`off·low·medium·high·max`) |
229
+ | `/think 배분 <배분>` | 단계별 배분 (`균일·절약·깊게`) |
230
+ | `/think 자세히` | 단계표 — 어느 단계를 어떤 강도·상한으로 도는지 |
227
231
  | `/mode <모드>` | 승인 정책 — 얼마나 물어보나 (`auto` · `confirm` · `strict`) |
228
232
  | `/work [모드]` | 작업 모드 — 무슨 일을 하는 중인가 |
229
233
  | `/auto` | 다시 맡기기 — 말을 보고 알맞은 모드로 저절로 옮겨 갑니다 |
230
234
  | `/code` `/plan` `/architect` `/debug` `/ask` `/orchestrator` | 작업 모드 바로 바꾸기 (그때부터 고정) |
231
235
  | `/level [수준]` | 화면에 무엇을 내놓을지 (`쉬움` · `개발자`) |
232
236
  | `/undo [턴수]` | 파일 변경 되돌리기 |
237
+ | `/diff [파일]` | 이번 대화에서 바뀐 파일 · 바뀐 자리 보기 |
233
238
  | `/tools` | 쓸 수 있는 도구 |
234
239
  | `/skills [검색어\|all\|off]` | 스킬 보기·검색·골라 올리기 |
235
240
  | `/plugin [install\|remove\|pack]` | 플러그인 관리 |
@@ -237,12 +242,51 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
237
242
  | `/status` | 연결 상태 |
238
243
  | `/scan [save]` | 이 PC 에 떠 있는 로컬 모델 서버 훑기 (`save` 면 바로 등록) |
239
244
  | `/sessions` | 이 폴더의 지난 대화 목록 |
245
+ | `/recall <말>` | 지난 대화에서 **내용으로** 찾기 |
246
+ | `/memory` | 대화가 끝나도 남는 기억 — 보기·적기·지우기 |
247
+ | `/mcp` | 밖에서 붙인 도구(MCP) 서버 보기 |
240
248
  | `/init` | `DEEL.md` 규칙 파일 만들기 |
241
249
  | `/exit` | 끝내기 |
242
250
 
243
251
  `/scan` 과 `/sessions` 는 나가지 않고도 씁니다. 로컬 서버를 새로 켰거나 모델을
244
252
  바꿔 올렸을 때 `/scan save` → `/model` 두 번이면 대화를 이어둔 채로 갈아탑니다.
245
253
 
254
+ ### `@파일` 로 바로 붙이기
255
+
256
+ 말 속에 `@` 뒤로 경로를 쓰면 그 파일을 말과 함께 바로 보냅니다.
257
+
258
+ ```
259
+ ❯ @src/a.js 이거 왜 느려?
260
+ ◧ 붙임 src/a.js
261
+ ```
262
+
263
+ 모델이 `Read` 를 스스로 부르는 **왕복 한 번이 없어집니다.** 로컬 모델은 도구 호출이
264
+ 약해서 그 한 번이 자주 헛돕니다 — 엉뚱한 경로를 부르거나, 아예 안 부르고 지어냅니다.
265
+ 사람은 이미 어느 파일인지 아는데 모델더러 찾아보라고 시킬 이유가 없습니다.
266
+
267
+ 어려운 것은 붙이는 일이 아니라 **아닌 것을 파일로 오해하지 않기** 입니다.
268
+ `@` 로 시작하는 것은 세상에 널렸습니다.
269
+
270
+ | 이렇게 쓰면 | 어떻게 되나 |
271
+ |---|---|
272
+ | `@src/a.js` | 붙습니다 — 실제로 있는 경로일 때만 |
273
+ | `hong@example.com` | 지목으로 안 봅니다. `@` 앞에 글자가 붙어 있으면 주소입니다 |
274
+ | `@media` · `@dataclass` · `@scope/pkg` | 그대로 둡니다 — 그런 경로가 없으니까 |
275
+ | `@src/` 처럼 폴더 | 안에 든 것을 목록으로 붙입니다 |
276
+ | `@"보고서 초안.txt"` | 띄어쓰기가 든 이름은 따옴표로 묶습니다 |
277
+ | 작업 범위 밖 | 안 붙이고, 왜 안 붙였는지 화면에 알립니다 |
278
+ | CP949 사내 문서 | 무엇으로 쓰였는지 알아보고 제대로 붙입니다 |
279
+
280
+ 규칙은 하나입니다 — **실제로 있는 경로일 때만 붙입니다.** 없으면 아무 말 없이
281
+ 글자 그대로 둡니다. 지목이 아니었을 테니 조용한 편이 맞습니다.
282
+
283
+ 붙이는 양은 컨텍스트 길이의 **25%**(많아야 20,000토큰)까지입니다. 그보다 크면 앞부분만 붙이는데,
284
+ 이때는 **'읽은 것' 으로 치지 않습니다.** 잘린 파일을 읽은 것으로 쳐 두면 모델이
285
+ 안 본 자리를 그냥 고쳐 버립니다. 통째로 붙은 파일만 `Read` 를 건너뜁니다.
286
+
287
+ 붙인 것은 화면에 반드시 알립니다. 사람이 안 보낸 글이 대화에 들어가 있는데
288
+ 그걸 모르면, 컨텍스트가 왜 줄었는지도 알 수 없습니다.
289
+
246
290
  ### 도중에 멈추기
247
291
 
248
292
  모델이 엉뚱한 길로 가는 게 보이면 **Ctrl+C** 로 그 자리에서 끊습니다.
@@ -357,6 +401,52 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
357
401
  - **초보라고 승인을 덜 받지 않습니다.** 되돌리기·작업 범위·위험 명령 차단은 두 수준이 같습니다.
358
402
  초보일수록 되돌릴 수 있어야 합니다.
359
403
 
404
+ ### 입력칸
405
+
406
+ 터미널에서 그냥 켜면 **대화는 위로 흘러가고, 맨 아래에 입력 상자가 붙습니다.**
407
+ 상자만 우리가 지우고 다시 그립니다 — 위쪽 대화는 손대지 않습니다.
408
+
409
+ ```
410
+ ❊ Grep(console.log)
411
+ └ 3개 파일 · 11건
412
+ ◈ Edit(src/runner.js)
413
+ └ 1군데 +3-1
414
+ - 12 console.log('시작', 이름)
415
+ + 12 logger.info({ 단계: '시작', 이름 })
416
+
417
+ ▌ 로그 호출을 logger 형식으로 통일했습니다. runner.js 한 군데입니다.
418
+
419
+ ── 4.2초 · 도구 3회 · ↑3,900 ↓180
420
+
421
+ ▏myproject · qwen2.5-coder:7b ▏ ▰▰▱▱▱▱▱▱ 22% ▏ ◎ 종합 · ◇ medium · auto
422
+ ╭─────────────────────────────────────────────────────────────────────────────╮
423
+ │ ❯ 집계 함수도 줄여줘 │
424
+ ╰─────────────────────────────────────────────────────────────────────────────╯
425
+ ```
426
+
427
+ 터미널 스크롤·복사·`Ctrl+F` 찾기가 **그대로 됩니다.** 대화를 우리 칸에 가둬 두지
428
+ 않기 때문입니다. 긴 글을 치면 상자가 알아서 여러 줄로 늘어납니다.
429
+
430
+ **저절로 꺼지는 자리가 있습니다.** 파이프·리다이렉트로 넘길 때, `CI` 가 켜져 있을 때,
431
+ `TERM=dumb` 일 때, 창이 40칸보다 좁을 때는 묻지 않고 상자를 안 그립니다.
432
+ `deel … | tee 기록.txt` 가 제어문자 덩어리가 되면 안 되기 때문입니다.
433
+ `--tui` 를 줘도 파이프면 안 켭니다. `--no-tui` 로 언제든 끌 수 있습니다.
434
+
435
+ 줄 편집은 전부 Node 의 readline 이 그대로 맡습니다 — 한글 조합, 붙여넣기,
436
+ 위아래 이력, Ctrl+A/E, 백스페이스. 우리는 readline 이 들고 있는 글을 상자 안에
437
+ **그리기만** 합니다. 직접 키를 받아 줄 편집을 짜기 시작하면 한글 입력기부터 깨집니다.
438
+
439
+ > **한 번 틀렸던 길** — 처음에는 터미널을 통째로 빌려(vim 처럼 딴 화면) 대화 칸·
440
+ > 파일 칸·할 일 칸을 나눠 그렸습니다. 보기에는 그럴듯했는데 **슬래시 명령이 전부
441
+ > 먹통**이 됐습니다. `commands.js` 를 비롯한 여섯 모듈이 화면 객체를 안 거치고
442
+ > 터미널에 바로 쓰는데, 매번 화면을 통째로 다시 그리니 그 글이 찍히자마자 덮여
443
+ > 사라졌던 것입니다. 명령이 안 도는 게 아니라 **결과가 안 보이는** 것이라 더
444
+ > 나빴습니다. 고치려면 터미널에 쓰는 자리를 전부 화면 객체로 꿰야 하는데, 지금
445
+ > 여섯 곳이고 앞으로 늘 것이며, 하나라도 빠뜨리면 같은 증상이 조용히 돌아옵니다.
446
+ > 그래서 반대로 갔습니다 — 대화는 그냥 흘려보내고 상자만 관리합니다.
447
+ > ([`test/box.test.js`](test/box.test.js) 가 터미널인 척하는 자식을 띄워
448
+ > 이 결함이 다시 안 나가는지 봅니다.)
449
+
360
450
  ---
361
451
 
362
452
  ## 도구
@@ -367,14 +457,99 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
367
457
  |---|---|
368
458
  | `Read` | 파일 읽기 (줄 번호 · `offset`/`limit` 지원 · **엑셀은 CSV 로 바꿔서**) |
369
459
  | `Write` | 파일 쓰기·덮어쓰기 |
460
+ | `Append` | 파일 끝에 이어 붙이기 — **큰 파일을 나눠 쓰는 자리** |
370
461
  | `Edit` | 정확한 문자열 바꾸기 (`replace_all` 지원) |
371
462
  | `Glob` | 이름 패턴으로 파일 찾기 |
372
463
  | `Grep` | 내용 정규식 검색 |
373
464
  | `Bash` | 명령 실행 |
374
465
  | `Skill` | 스킬 본문 펼쳐 읽기 (스킬이 있을 때만 모델에게 보임) |
375
466
  | `WebFetch` | 웹 페이지 읽기 (읽기 전용 · `--offline` 이면 숨김) |
467
+ | `Recall` | **지난 대화**에서 찾기 — "저번에 그거" 를 모델이 스스로 뒤진다 |
468
+ | `Remember` | 대화가 끝나도 남길 것 한 줄 — 다음에 켤 때 처음부터 안다 |
376
469
  | `TodoWrite` | 할 일 목록 — 긴 일을 쪼개서 어디까지 했는지 화면에 띄움 |
377
470
 
471
+ Claude Code 에 없는 것은 **셋뿐**입니다 — `Append` · `Recall` · `Remember`.
472
+ 도구 하나가 스키마로 150토큰쯤 먹고 그게 **매 요청마다** 나가므로, 늘릴 때마다
473
+ 검사에서 한 번 멈추게 해 뒀습니다(`test/loop.test.js`).
474
+
475
+ ### 지난 대화를 찾고, 정한 것을 기억합니다
476
+
477
+ deel 은 대화를 `.deel/sessions/*.jsonl` 로 꼬박꼬박 남깁니다. 그런데 목록을 보는 것
478
+ 말고는 할 수 있는 게 없었습니다 — **기록이 있는데 못 찾으면 없는 것과 같습니다.**
479
+
480
+ ```
481
+ $ /recall 인코딩을 어떻게
482
+
483
+ 2026-08-01 10:15 모델 20260801-101500
484
+ CP949 인코딩 문제입니다. 읽을 때 인코딩을 재서 그대로 되돌려 쓰도록…
485
+ 2026-08-20 14:45 나 20260820-144500
486
+ 저번 인코딩 규칙 그대로 적용해줘
487
+
488
+ 2건 중 2건 · 대화 3개를 뒤졌습니다
489
+ ```
490
+
491
+ 조사를 붙여 쳐도 찾습니다(`인코딩을` → `인코딩`). 형태소 분석기를 붙일 수는 없으니
492
+ (의존성 0) 조사처럼 보이는 꼬리를 떼어 **둘 다** 찾습니다. 색인은 안 만듭니다 —
493
+ 색인은 반드시 낡고, **낡은 색인은 없는 것보다 나쁩니다**("못 찾았습니다" 가
494
+ "없습니다" 로 읽힙니다). 대신 얼마나 뒤졌고 무엇을 못 뒤졌는지 반드시 말합니다.
495
+
496
+ `Recall` 은 **도구로도** 줍니다. 사람만 쓰는 명령으로 두면 "저번에 정한 대로 해줘" 에
497
+ 모델이 할 수 있는 게 되묻는 것뿐입니다.
498
+
499
+ **기억(`/memory`)은 다른 물건입니다.** 지난 대화 찾기는 *찾아야* 나오고, 기억은
500
+ *처음부터 들어가 있습니다.* 매번 다시 설명할 수 없는 것이 여기 옵니다.
501
+
502
+ ```
503
+ $ /memory
504
+
505
+ 1 사내 문서는 CP949 로 읽고 CP949 로 되돌려 쓴다
506
+ 2 검증할 때 7080 포트는 쓰지 않는다 — 앱 기본 포트라 진짜 data/ 를 덮는다
507
+
508
+ 2줄 · 약 30토큰이 매 요청마다 함께 나갑니다
509
+ 파일 .deel/memory.md — 직접 고치셔도 됩니다
510
+ ```
511
+
512
+ `.deel/memory.md` 는 **사람이 열어 고치는 글**입니다. 데이터베이스가 아닙니다.
513
+ 이게 중요합니다 — 모델이 잘못 적은 줄은 매 요청마다 실려 나가면서 계속 틀리게
514
+ 만듭니다. **틀린 기억은 없느니만 못합니다.** 그래서 `/memory 지우기 2` 로 지웁니다.
515
+
516
+ 매 요청에 나가는 물건이라 자리를 지킵니다: 한 줄 400자 · 60줄 · 전체 6,000자.
517
+ 넘으면 오래된 것부터 빼고 뺐다고 말합니다. `/context` 에도 줄 수와 토큰이 뜹니다.
518
+
519
+ ### 또 하게 될 절차는 스킬로 남깁니다
520
+
521
+ 여러 걸음이 걸리는 일을 끝냈고 또 하게 될 일이면, 모델이 그 절차를
522
+ `.deel/skills/<이름>/SKILL.md` 로 적어 둡니다. 다음에 켤 때 스킬 목록에 떠서 바로
523
+ 쓸 수 있고, 쓰다가 틀린 데를 찾으면 그 파일을 고칩니다.
524
+
525
+ 새 도구가 필요 없습니다 — 이미 있는 `Write` 로 쓰고, 이미 있는 스킬 훑기가 읽습니다.
526
+
527
+
528
+
529
+ ### 큰 파일은 나눠 씁니다 — `Append`
530
+
531
+ 출력 상한이 4k 인 모델도 2,000줄 파일을 여덟 번에 나눠 쓸 수 있어야 합니다.
532
+ `Edit` 으로 잇는 방법은 실제로 안 됩니다 — HTML 은 `</div>` 같은 앵커가 반복돼
533
+ "여러 군데에서 발견됐습니다" 로 막히고, 앵커를 길게 잡으면 그 토큰이 본문에서 빠집니다.
534
+
535
+ 처음 만들 때는 `Write`, 이어 붙일 때는 `Append` 입니다. 인코딩은 `Write` 와 같게
536
+ 따라갑니다(사내 문서의 CP949, `.csv` 의 BOM 을 그대로 지킵니다).
537
+ 되돌리기 스냅샷은 **첫 `Append` 때 한 번만** 남습니다 — 여덟 번 이어 붙였다고
538
+ 이력에 여덟 벌이 쌓이면 되돌릴 자리를 찾을 수 없기 때문입니다.
539
+
540
+ ```
541
+ ⏺ Write(dashboard.html)
542
+ └ ⚠ 잘린 데까지만 썼습니다 — 632줄
543
+ ↻ 대답이 상한에서 잘렸습니다 — 상한을 9,984 → 16,384 로 올려 다시 부릅니다
544
+ ⏺ Append(dashboard.html)
545
+ └ +567줄 · 전체 1,199줄
546
+
547
+ ✓ dashboard.html · 1,199줄 · 97.7KB
548
+ ```
549
+
550
+ 마지막 줄이 중요합니다. 파일이 없는데 모델이 "만들었습니다" 라고 하면
551
+ 그대로 믿게 됩니다. **턴이 끝날 때 실제 파일을 재서 알려 줍니다.**
552
+
378
553
  ### 할 일 목록
379
554
 
380
555
  여러 단계가 걸리는 일에서 모델이 순서를 잃지 않게 하는 장치입니다.
@@ -431,6 +606,66 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
431
606
  이 줄을 그대로 옮겨 담아 다시 시도하세요.
432
607
  ```
433
608
 
609
+ ### 고친 자리를 그 자리에서 보여줍니다
610
+
611
+ `auto` 모드는 안 물어보고 고칩니다. 그게 이 도구의 속도인데, 화면에 `3군데` 만
612
+ 남으면 사람은 무엇이 바뀐지 모른 채 넘어갑니다. 되돌리기가 안전망이어도
613
+ **뭐가 바뀐지 모르면 되돌릴지 말지조차 못 정합니다.**
614
+ 그래서 `Edit`·`Write` 뒤에는 바뀐 줄을 그대로 붙여 보여줍니다.
615
+
616
+ ```
617
+ ◈ Edit(src/runner.js)
618
+ └ 1군데 +1 −2
619
+
620
+ 11 const id = job.id;
621
+ - console.log("실행 시작: " + id);
622
+ - console.log(" 옵션 " + JSON.stringify(opts));
623
+ + 12 logger.info('실행 시작', { id, opts });
624
+ 13 return run(job);
625
+ ```
626
+
627
+ 요약 옆의 `+1 −2` 는 늘고 준 줄 수입니다.
628
+
629
+ - **없어진 줄에는 번호를 안 답니다.** 지금 파일에 없는 줄이니까요. 옛 번호를
630
+ 달았더니 바로 위 곁줄의 새 번호와 같은 숫자가 나란히 찍혔습니다 — 서로 다른
631
+ 파일의 번호가 한 열에 섞여 보입니다. 실제로 8번이 두 번 찍히는 화면이 나왔습니다.
632
+ - 줄 끝 표시(CRLF/LF)만 바뀌었으면 그렇다고 따로 말해 줍니다. 안 그러면 눈에
633
+ 똑같은 줄이 전부 바뀐 것으로 나와서 진짜 바뀐 곳을 못 찾습니다.
634
+ - 큰 파일은 앞뒤로 같은 부분을 먼저 잘라내고 견줍니다. 그러고도 크면 자세히 맞추기를
635
+ 포기하고 '이만큼이 통째로 바뀌었다' 로 물러섭니다 — 느린 것보다 대충이라도
636
+ 빨리 보이는 편이 낫습니다.
637
+
638
+ 몇 줄까지 펼칠지는 수준마다 다릅니다. 처음 켠 사람에게 40줄을 쏟으면 아무것도 안 읽습니다.
639
+
640
+ | | 쉬움 | 개발자 |
641
+ |---|---|---|
642
+ | 도구 뒤에 펼치는 줄 | 14줄 | 40줄 |
643
+ | `/diff <파일>` | 60줄 | 200줄 |
644
+
645
+ ### `/diff` — 이번 대화에서 바뀐 것
646
+
647
+ 도구 뒤에 지나간 화면은 스크롤에 묻힙니다. `/diff` 는 이번 대화에서 손댄 파일을
648
+ 한 장에 모읍니다.
649
+
650
+ ```
651
+ $ /diff
652
+
653
+ ── 이번 대화에서 바뀐 파일 ──────────────────────────────────
654
+ src/runner.js +12 −7 3번
655
+ src/logger.js +40 −0
656
+ ──────────────────────────────────────────────────────────
657
+ 2개 파일 +52 −7
658
+
659
+ 한 파일을 자세히 보려면 /diff <파일>, 되돌리려면 /undo
660
+ ```
661
+
662
+ `/diff <파일>` 은 **이번 대화를 시작하기 전과 지금**을 견줍니다. 세 번 고쳤어도
663
+ 사람이 알고 싶은 것은 '내가 시키기 전과 지금이 뭐가 다른가' 이지 마지막 한 번이
664
+ 아니기 때문입니다. 그 처음 모습은 되돌리기 이력의 가장 오래된 스냅샷에서 꺼냅니다.
665
+
666
+ `/diff` 는 **쉬움 수준의 명령 목록에도 들어 있습니다.** `auto` 가 안 물어보고
667
+ 고치는 이상, 초보일수록 '무엇이 바뀌었나' 를 볼 통로가 필요합니다.
668
+
434
669
  ---
435
670
 
436
671
  ## 한글 문서와 엑셀
@@ -467,6 +702,12 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
467
702
  명령 출력도 마찬가지입니다. 윈도우 명령창은 UTF-8 이 아니라, `Bash` 결과를
468
703
  utf8 로 받으면 한글이 깨집니다. 바이트로 받아서 풉니다.
469
704
 
705
+ **되돌리기 스냅샷도 바이트로 담습니다.** 예전에는 UTF-8 글자로 적었습니다.
706
+ 그러면 CP949 파일을 되돌릴 때 `가나다`(`b0a1 b3aa b4d9`) 가 U+FFFD 여섯 개로
707
+ 돌아옵니다 — **안전망이 원본 바이트를 없애 버리는 것입니다.** 지금은 UTF-8 로
708
+ 되짚어 봐서 바이트가 그대로 살아나지 않는 파일만 base64 로 담고, 되돌릴 때
709
+ 바이트 그대로 씁니다.
710
+
470
711
  ### 엑셀 — CSV 로 바꿔서 읽습니다
471
712
 
472
713
  엑셀 파일은 글이 아니라 압축 꾸러미라, 보통은 "바이너리 파일입니다" 로 끝납니다.
@@ -554,16 +795,13 @@ unzip 반입.zip -d ~/.deel/plugins/
554
795
  에이전트 한 번의 대답은 모델을 여러 번 부릅니다. **부를 때마다 필요한 생각의 양이 다릅니다.**
555
796
  전부 세게 두면 느리고, 전부 얕게 두면 엉뚱한 길로 갑니다.
556
797
 
798
+ 기본은 **한 줄**입니다. 알고 싶은 것은 '지금 얼마나 생각하나' 이지 단계표가 아닙니다.
799
+
557
800
  ```
558
801
  $ /think
559
802
 
560
- ── 추론 강도 ─────────────────────────────────────────────────────
561
- 기준 medium 배분 절약 판단만 세게, 이어가기는 얕게
562
-
563
- 단계 강도 출력상한 언제
564
- 첫 판단 · medium 4,096 무엇을 할지 정하는 자리
565
- 이어가기 ↓ low 2,048 도구 결과를 읽고 다음 한 수
566
- 막혔을 때 ↑ high 4,096 직전 도구가 오류를 냄
803
+ 추론 강도 medium (첫 판단 medium · 이어가기 low · 막혔을 때 high)
804
+ 세게 /think high 빠르게 /think low
567
805
  ```
568
806
 
569
807
  | 배분 | 성격 |
@@ -572,6 +810,31 @@ $ /think
572
810
  | `save` (절약, 기본) | 첫 판단만 세게, 이어가기는 얕게 |
573
811
  | `deep` (깊게) | 전 단계 한 칸씩 위로 — 어려운 일에만 |
574
812
 
813
+ 배분은 `/think 배분 절약` 로 정합니다. **강도와 배분은 다른 축이라 명령을 갈랐습니다** —
814
+ 전에는 `/think high` 와 `/think save` 가 같은 이름으로 다른 것을 정해서,
815
+ 화면을 봐도 지금 무엇이 무엇인지 읽히지 않았습니다.
816
+
817
+ 단계표는 `/think 자세히` 로 뺐습니다(개발자 수준 기본).
818
+
819
+ ```
820
+ $ /think 자세히
821
+
822
+ 추론 강도 medium (첫 판단 medium · 이어가기 low · 막혔을 때 high)
823
+ 배분 절약 첫 판단만 세게, 이어가기는 얕게 — 대개 이게 낫습니다
824
+
825
+ 단계 강도 출력상한 언제
826
+ 첫 판단 · medium 15,549 무엇을 할지 정하는 자리
827
+ 이어가기 ↓ low 13,605 도구 결과를 읽고 다음 한 수
828
+ 막혔을 때 ↑ high 16,384 직전 도구가 오류를 냄
829
+
830
+ 출력 상한은 16,384 (모르는 값이라 기본값) 안에서 나눕니다 — /out
831
+ 컨텍스트 40,960 · 지금 찬 양 2,087
832
+ ```
833
+
834
+ 마지막에서 두 번째 줄이 있는 이유: **세 값이 다 같을 때 그게 고장인지 아닌지**
835
+ 이 한 줄로 갈립니다. 아는 상한이 낮으면 셋이 같아지는 것이 맞습니다.
836
+ 한동안 이 표는 세 줄이 늘 `16,384` 였고, 그건 표가 뜻이 없다는 뜻이었습니다.
837
+
575
838
  ### 컨텍스트 길이는 모델에서 긁어옵니다
576
839
 
577
840
  이 숫자 하나가 프로그램 전체 크기를 정합니다. 한 번에 읽힐 수 있는 파일 수,
@@ -610,29 +873,98 @@ $ /think
610
873
  | `/ctx` | 지금 값과 남은 자리 |
611
874
  | `/ctx auto` | 서버에 다시 물어 모델에 맞춤 |
612
875
  | `/ctx 655360` | 직접 지정 (`640k` · `128k` · `1m` 도 됩니다) |
613
- | `/ctx out 32k` | 번에 받을 **답 길이** 상한 컨텍스트와 다른 |
876
+ | `/ctx 자세히` | 어디를 두드려서 어떤 값을 얻었는지 가져와질 원인을 봅니다 |
614
877
  | `deel --ctx 655360` | 켤 때부터 이 값으로 (긁어오기를 건너뜁니다) |
615
878
 
616
879
  **`k` 는 1024 입니다.** 컨텍스트 길이는 전부 2의 거듭제곱이라 그래야 아귀가 맞습니다 —
617
880
  655,360 은 `655k` 가 아니라 `640k`, 131,072 는 `131k` 가 아니라 `128k` 입니다.
618
881
  화면에 뜨는 표기와 `/ctx` 가 받는 단위가 같아서, 보이는 대로 쳐도 같은 값이 됩니다.
619
882
 
620
- **출력 상한은 고정 숫자가 아닙니다.** 모델 컨텍스트와 지금 찬 양에서 매번 계산합니다 —
883
+ ### 번에 받을 길이 `/out`
884
+
885
+ 컨텍스트(담아 둘 수 있는 양)와 **출력 상한**(한 번에 낼 수 있는 양)은 다른 숫자입니다.
886
+ 그 둘을 하나로 알면 큰 파일이 왜 안 만들어지는지 영영 알 수 없습니다 —
887
+ 컨텍스트는 넉넉한데 답이 잘리기 때문입니다.
888
+
889
+ | 명령 | 하는 일 |
890
+ |---|---|
891
+ | `/out` | 지금 상한과 그 값이 **어디서 왔는지**(직접 정함 / 서버에서 알아냄 / 기본값) |
892
+ | `/out 32k` | 직접 지정 (`k` 는 1024). 프로필에 남아 다음에 켤 때도 그대로입니다 |
893
+ | `/out auto` | 직접 정한 값을 지우고 알아낸 값·기본값으로 |
894
+ | `deel --max-tokens 65536` | 켤 때부터 이 값으로 |
895
+
896
+ 옛 이름 `/ctx out 32k` 도 그대로 받습니다.
897
+
898
+ **상한은 고정 숫자가 아닙니다.** 모델 컨텍스트와 지금 찬 양에서 매번 계산합니다 —
621
899
  남은 자리의 몇 %를 이 단계에 내줄지가 배분입니다.
622
900
 
623
- | 모델 | 첫 판단 | 이어가기 | 막혔을 때 |
624
- |---|---|---|---|
625
- | 2k 로컬 | 554 | 512 | 554 |
626
- | 8k 로컬 | 2,007 | 1,003 | 2,007 |
627
- | 40k (qwen3) | 11,688 | 5,844 | 11,688 |
628
- | 128k 게이트웨이 | 16,384 | 16,384 | 16,384 |
629
- | 128k 인데 80% 참 | 7,680 | 3,840 | 7,680 |
901
+ | 모델 | 첫 판단 | 이어가기 | 막혔을 때 | 잘린 뒤 다시 |
902
+ |---|---|---|---|---|
903
+ | 2k 로컬 | 819 | 716 | 921 | 1,638 |
904
+ | 8k 로컬 | 3,276 | 2,867 | 3,686 | 6,553 |
905
+ | 40k (qwen3) | 16,384 | 14,336 | 16,384 | 16,384 |
906
+ | 128k 게이트웨이 | 16,384 | 16,384 | 16,384 | 16,384 |
907
+ | 128k 인데 80% 참 | 10,485 | 9,174 | 11,796 | 16,384 |
908
+ | 640k 에 `/out 65536` | 65,536 | 65,536 | 65,536 | 65,536 |
630
909
 
631
910
  컨텍스트가 차오르면 상한도 같이 줄어듭니다. 4k 모델에 4096 을 주면 입력 자리가 안 남기 때문입니다.
632
- 더 필요하면 프로필에 `maxTokens` 를 적어 올릴 수 있습니다.
633
911
 
634
- 아끼다 대답이 잘리면 **그 단계만 상한을 풀어 자동으로 다시 부릅니다.**
635
- 잘린 채로 넘어가면 도구 호출이 반토막 나서 조용히 실패하기 때문입니다.
912
+ 마지막 줄이 요점입니다. **아는 값이 있으면 16,384 비켜섭니다.**
913
+ 한동안은 그랬습니다 `Math.min(cap, max ?? 16384, 16384)` 의 세 번째 인자가
914
+ 무조건 다시 조여서, 적어 둔 값은 **낮출 수만 있고 올릴 수 없었습니다.**
915
+ 그런데 주석도 README 도 안내도 셋 다 "올릴 수 있다" 고 말했습니다.
916
+ 문서에 적힌 탈출구가 막혀 있는 것이 가장 나쁩니다.
917
+
918
+ 아끼다 대답이 잘리면 **상한을 풀어 자동으로 다시 부릅니다.** 이때 추론 강도도 한 칸
919
+ 내립니다 — 생각 토큰이 같은 예산을 먼저 까먹기 때문에, 강도를 낮춰야 본문 자리가 실제로 늡니다.
920
+ 잘린 채로 넘어가면 도구 호출이 반토막 나서 조용히 실패합니다.
921
+
922
+ **서버가 거절하면 그 문장에서 배웁니다.**
923
+
924
+ ```
925
+ This model's maximum context length is 8192 tokens, however you requested 41003
926
+ ```
927
+
928
+ 이 숫자를 뽑아 즉시 맞추고 다시 부릅니다. 사용자는 실패를 안 봅니다.
929
+ 규격을 몰라도 되므로 **처음 보는 서버에서도 통합니다.**
930
+
931
+ ### 잘린 도구 호출
932
+
933
+ 실제로 있었던 일입니다. 사용자가 대시보드를 만들어 달라고 했고, 모델은 HTML 문서를
934
+ 통째로 `Write` 의 인자에 넣으려다 출력 한도에 걸렸습니다. 인자 JSON 이 중간에서
935
+ 끊긴 채로 도착했습니다.
936
+
937
+ 예전 코드는 그 읽히지 않는 JSON 을 조용히 `{_raw: "..."}` 로 바꿔 도구에 넘겼습니다.
938
+ 도구는 `경로가 비었습니다` 라고 답했습니다 — **진짜 원인과 아무 상관 없는 말입니다.**
939
+ 모델은 경로를 안 빠뜨렸으니 고칠 게 없다고 보고 똑같이 다시 시도했고, 또 잘렸습니다.
940
+
941
+ ```
942
+ ◆ Write(dashboard.html)
943
+ └ 경로가 비었습니다 ← 아홉 번 똑같이
944
+
945
+ ── 71초 · 도구 13회 · 컨텍스트가 차서 대화를 접음 · 파일은 안 생김
946
+ ```
947
+
948
+ 조용히 삼킨 값 하나가 그 전부를 만들었습니다. 지금은 이렇게 합니다.
949
+
950
+ | | 지금 |
951
+ |---|---|
952
+ | 안 읽히는 인자 | 삼키지 않고 **잘렸다고 표시**합니다. 도구에 넘기지 않습니다 |
953
+ | 모델에게 | 무슨 일이 났는지 그대로 말하고, 통째로 다시 보내지 말고 **뼈대만 먼저 만든 뒤 `Edit` 으로 나눠 이어 붙이라**고 알려 줍니다 |
954
+ | 잘린 내용 | 대화에 다시 넣지 않습니다 — 반쪽인 데다 컨텍스트만 먹습니다 |
955
+ | 잘림 판정 | 게이트웨이가 `finish_reason: "stop"` 이라고 해도 **인자가 깨진 것 자체를 잘린 증거로 봅니다.** 모델은 반쪽짜리 JSON 을 일부러 만들지 않습니다 |
956
+ | 같은 실패 3번 | 그 턴을 멈추고, 나눠서 시켜 보라고 말합니다 |
957
+
958
+ ```
959
+ ⊘ 같은 자리에서 헛돌고 있어 멈췄습니다.
960
+ 같은 도구 호출이 계속 잘립니다
961
+ 한 번에 만들 내용이 모델의 출력 한도보다 큽니다. 나눠서 시켜 보세요 —
962
+ 예: "뼈대만 먼저 만들어줘" → "표 부분 추가해줘" → "그래프 추가해줘"
963
+ ```
964
+
965
+ **걸음 수 상한(`maxSteps`)으로는 이걸 못 막습니다.** 그건 '잘 되고 있는 긴 작업' 과
966
+ '헛도는 작업' 을 구분하지 못합니다. 여기서 세는 것은 걸음 수가 아니라
967
+ **같은 도구가 같은 이유로 실패한 횟수**입니다.
636
968
 
637
969
  ---
638
970
 
@@ -685,6 +1017,44 @@ $ deel sessions
685
1017
 
686
1018
  ---
687
1019
 
1020
+ ## 밖에서 도구 붙이기 (MCP)
1021
+
1022
+ 사내 위키 검색기, 이슈 트래커, DB 조회기 같은 것을 각 팀이 MCP 서버로 만들어 두면
1023
+ deel 은 그걸 **코드를 안 고치고** 도구로 씁니다.
1024
+
1025
+ `.deel/mcp.json` 에 적습니다. Claude Code 설정을 그대로 복사해 붙일 수 있습니다:
1026
+
1027
+ ```json
1028
+ { "mcpServers": { "사내위키": { "command": "node", "args": ["wiki-mcp.js"] } } }
1029
+ ```
1030
+
1031
+ 모델에게는 `mcp__사내위키__검색` 이라는 이름으로 보입니다. `/mcp` 로 무엇이 붙었는지 봅니다.
1032
+
1033
+ **의존성은 그대로 0 입니다.** stdio 규격은 자식 프로세스의 stdin/stdout 에 줄 단위
1034
+ JSON-RPC 2.0 을 주고받는 것이 전부라, `child_process` 와 `JSON` 이면 됩니다. SDK 가
1035
+ 필요 없습니다.
1036
+
1037
+ ### 다만 이건 남의 프로그램입니다
1038
+
1039
+ 이 프로젝트가 존재하는 이유가 '미승인 SW 반입 금지' 인데, MCP 를 아무렇게나 켜면
1040
+ 그 선을 우리 손으로 무너뜨리는 셈입니다. 그래서:
1041
+
1042
+ | | |
1043
+ |---|---|
1044
+ | **기본은 꺼져 있음** | `.deel/mcp.json` 에 직접 적어야만 뜹니다 |
1045
+ | **`--offline` 이면 안 띄움** | 자식 프로세스가 어디로 나가는지 우리는 못 막습니다. **막을 수 없는 것을 막았다고 말하지 않습니다** |
1046
+ | **작업 범위 밖** | MCP 서버는 우리 울타리를 안 지킵니다. `/mcp` 화면이 그렇다고 말합니다 |
1047
+ | **감사기록에 남음** | 무엇을 띄웠고 무엇을 불렀는지 `.deel/audit.jsonl` 에 |
1048
+ | **열쇠를 안 넘김** | 우리 환경변수를 통째로 안 넘깁니다 — `DEEL_*` 의 게이트웨이 열쇠가 남의 프로세스로 가면 어디로 가는지 알 수 없습니다 |
1049
+ | **읽기 전용 모드엔 안 줌** | 이름이 '검색' 이어도 파일을 쓸 수 있습니다. 계획·설계 모드에서 '모르는 것' 을 쥐여 주면 그 약속이 약속이 아니게 됩니다 |
1050
+ | **한 서버에 24개까지** | 스키마가 매 요청에 실립니다. 넘으면 자르고 **잘랐다고 말합니다** |
1051
+
1052
+ 서버 하나가 죽거나·답이 없거나·헛소리를 해도 나머지는 그대로 씁니다. 안 뜬 것은
1053
+ 조용히 빠지지 않고 머리말에 이유가 뜹니다 — 조용히 빠지면 "왜 그 도구가 없지" 를
1054
+ 영영 알 수 없습니다.
1055
+
1056
+ ---
1057
+
688
1058
  ## 안전망
689
1059
 
690
1060
  승인 프롬프트 대신 **되돌릴 수 있게** 만들었습니다. 기본 모드 `auto` 는 묻지 않고 알아서 합니다.
@@ -692,10 +1062,13 @@ $ deel sessions
692
1062
  | 장치 | 내용 |
693
1063
  |---|---|
694
1064
  | **되돌리기** | 파일을 고치기 전 항상 스냅샷. `/undo` 로 턴 단위 복구 |
1065
+ | **바뀐 자리 보기** | 고칠 때마다 바뀐 줄을 화면에. 이번 대화 전체는 `/diff` |
695
1066
  | **작업 범위** | 시작한 폴더 밖은 모델이 시켜도 거부 |
696
1067
  | **위험 명령 차단** | 되돌릴 수 없는 것만 (디스크 포맷, 재귀 삭제, `--force` 푸시 등) |
697
1068
  | **재실행 금지** | 변경성 명령은 실패해도 다시 실행하지 않음 — 두 번 돌면 사고 |
698
1069
  | **중단** | Ctrl+C 로 도중에 끊어도 대화가 성한 채로 남음 |
1070
+ | **헛돌기 차단** | 같은 도구가 같은 이유로 3번 실패하면 그 턴을 멈추고 왜인지 말함 |
1071
+ | **안 읽는 자리** | 남의 도구 살림과 deel 자신의 기록·설정(열쇠)은 거절 |
699
1072
  | **감사 로그** | `.deel/audit.jsonl` 에 전부 기록 |
700
1073
 
701
1074
  | 모드 | 언제 물어보나 |
@@ -708,6 +1081,42 @@ $ deel sessions
708
1081
  32MB 를 넘으면 **최근 50턴만 남기고** 오래된 것을 버립니다. 방금 한 일은 언제나
709
1082
  되돌릴 수 있고, 지금 이력이 얼마나 되는지는 `/status` 에서 봅니다.
710
1083
 
1084
+ ### 안 읽는 자리
1085
+
1086
+ 폴더를 훑다 보면 프로젝트 파일이 아닌 것이 걸려 나옵니다. 다른 코딩 도구가 제 살림을
1087
+ 넣어 둔 자리입니다 — 지난 대화, 명령 이력, 캐시, 그리고 열쇠.
1088
+ 이 작업과 아무 상관이 없는데 목록에 나오면 모델이 그것부터 읽습니다.
1089
+
1090
+ ```
1091
+ ◧ Read(~/.deel/audit.jsonl) 77줄
1092
+ ◧ Read(~/.claude/history.jsonl) 35줄
1093
+ ```
1094
+
1095
+ 감사기록은 **이 프로그램이 방금 무엇을 했는지** 적어 둔 것입니다. 그걸 다시 읽어
1096
+ 대화에 넣으면 모델이 제 그림자를 좇습니다. 시킨 일과는 상관없이 컨텍스트만 찹니다.
1097
+
1098
+ 설정 파일은 더 나쁩니다. `.deel/config.json` 에는 게이트웨이 **열쇠(API 키)** 가
1099
+ 들어 있습니다. 읽는 순간 그 열쇠가 대화에 실려 모델로 나가고, 디스크의 세션 기록에도
1100
+ 남습니다. 열쇠를 그 열쇠의 주인에게 보내는 셈입니다.
1101
+
1102
+ | 안 읽는 것 | 왜 |
1103
+ |---|---|
1104
+ | `.deel/config.json` | 게이트웨이 열쇠가 들어 있음 |
1105
+ | `.deel/audit.jsonl` · `.deel/sessions` · `.deel/history` | deel 자신의 기록. 제 그림자를 좇게 됨 |
1106
+ | `.claude` `.codex` `.cursor` `.gemini` `.aider` `.continue` `.cline` `.roo` `.kilocode` `.windsurf` `.opencode` `.zed` `.trae` `.augment` `.qodo` `.tabnine` `.cody` `.sourcegraph` `.copilot` `.amazonq` `.junie` `.codeium` `.goose` `.crush` `.gptme` `.openhands` `.devin` | 남의 도구 살림 |
1107
+ | `.aider.chat.history.md` 처럼 폴더가 아니라 파일로 흘리는 것 | 같은 이유 |
1108
+
1109
+ 읽기만이 아니라 **쓰기도 막습니다.** 읽기만 막아 두면 남의 도구 설정을 덮어쓸 수 있고,
1110
+ `.deel/config.json` 을 덮어쓰면 연결이 통째로 날아갑니다.
1111
+
1112
+ **막는 것이지 숨기는 것이 아닙니다** — 왜 안 되는지 그대로 말해 줍니다.
1113
+ 새 도구는 계속 나옵니다. 목록에 없는 이름이 보이면 **한 줄 더하면 됩니다.**
1114
+
1115
+ 그 목록은 **소스의 한 곳에만 둡니다.** 훑는 쪽(`SKIP_DIRS`)과 읽기 막는 쪽이
1116
+ 같은 것을 봅니다. 전에는 따로 적어 놨는데, 그러면 한쪽에만 새 이름을 넣는 날이
1117
+ 반드시 옵니다 — 훑을 때는 안 걸리는데 이름을 대면 읽히는, 설명하기 어려운
1118
+ 상태가 됩니다.
1119
+
711
1120
  ---
712
1121
 
713
1122
  ## 사내 반입
@@ -801,11 +1210,14 @@ deel --root <폴더> 작업 범위. 기본은 지금 폴더
801
1210
  deel --mode <모드> auto(기본) / confirm / strict
802
1211
  deel --work <모드> auto(기본·종합) / code / plan / architect / debug / ask / orchestrator
803
1212
  deel --level <수준> 쉬움 / 개발자
1213
+ deel --ctx <길이> 컨텍스트 길이 직접 지정 (655360 · 640k · 128k)
1214
+ deel --max-tokens <길이> 한 번에 받을 답 길이 상한 (32k) — /out 과 같은 값
804
1215
  deel --think <강도> off / low / medium(기본) / high / max
805
1216
  deel --effort <배분> even / save(기본) / deep
806
1217
  deel --offline 이 컴퓨터 밖으로 아무것도 안 보냄
807
1218
  deel --continue 가장 최근 대화 이어하기
808
1219
  deel --resume <id> 골라서 이어하기
1220
+ deel --no-tui 입력 상자를 끄고 줄 화면으로 (아래 참고)
809
1221
  ```
810
1222
 
811
1223
  ### 프로젝트 규칙
@@ -826,7 +1238,9 @@ deel --resume <id> 골라서 이어하기
826
1238
  | 401 / 403 | 키가 틀렸거나 인증 헤더 형식이 다름 (4가지를 자동 시도합니다) |
827
1239
  | `허용되지 않은 주소입니다` | 자물쇠가 막은 것. 정상입니다 — `/model` 로 연결을 고르세요 |
828
1240
  | 도구 호출이 안 먹음 | `deel diagnose` 로 판정을 보세요. 작은 모델(1B~3B)은 자주 못 합니다 |
829
- | 대답이 비어 있음 | 생각을 많이 하는 모델입니다. `/think low` 낮춰 보세요 |
1241
+ | 대답이 비어 있음 | 스트리밍을 무시하는 서버입니다. 번은 저절로 다시 부르고, 그래도 비면 이 대화에서는 스트리밍을 끕니다 |
1242
+ | 큰 파일이 중간에 끊김 | `/out` 으로 지금 상한을 보고 올리세요. 상한을 몰라 16,384 로 서 있을 수 있습니다 |
1243
+ | `HTTP 400` 만 뜸 | 서버가 보낸 문장을 그대로 보여 줍니다. 길이 문제면 숫자를 읽어 저절로 맞춥니다 |
830
1244
  | `deel scan` 이 0곳 | 로컬 서버가 꺼져 있거나 다른 포트 — `--ports` 로 지정 |
831
1245
 
832
1246
  ---
@@ -834,11 +1248,12 @@ deel --resume <id> 골라서 이어하기
834
1248
  ## 개발
835
1249
 
836
1250
  ```bash
837
- npm test 전체 검증 (254항목)
838
- npm run verify 반입·통신 검증만
839
- npm run bench 편집 성공률 측정
840
- npm run demo 화면이 어떻게 보이는지 실제로 돌려 보기
841
- npm run check 전 파일 문법 검사
1251
+ npm test 전체 검증 (1,787항목)
1252
+ npm run coverage 검사가 소스의 어디를 밟았는지
1253
+ npm run verify 반입·통신 검증만
1254
+ npm run bench 편집 성공률 측정
1255
+ npm run demo 화면이 어떻게 보이는지 실제로 돌려 보기
1256
+ npm run check 전 파일 문법 검사
842
1257
  ```
843
1258
 
844
1259
  검증은 **가짜 게이트웨이**를 띄워서 합니다. 실제 모델 없이 규격 그대로
@@ -868,34 +1283,69 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
868
1283
  |---|---|---|
869
1284
  | `smoke` | 20 | 도구·작업범위·되돌리기·감사로그 |
870
1285
  | `loop` | 16 | 에이전트 루프·스트리밍·도구 호출 |
1286
+ | `guard` | 24 | **안 하는 자리** — 거부·모르는 도구·두 번 실행·범위 밖 |
871
1287
  | `network` | 30 | 정해진 자리 밖으로 새지 않는가 |
872
1288
  | `web` | 25 | 웹 읽기가 읽기만 하는가 |
873
1289
  | `abort` | 16 | Ctrl+C 로 끊어도 대화가 성한가 |
874
1290
  | `parallel` | 23 | 읽기만 동시에 도는가 · 할 일 목록 |
1291
+ | `cli` | 75 | **진짜 `deel` 을 띄워** 끝까지 돌려 본다 |
1292
+ | `setup` | 42 | 첫 실행 마법사 (가짜 TTY 로 사람처럼 입력) |
1293
+ | `detect` | 66 | 주소 한 줄로 규격·인증을 짚어내는가 |
1294
+ | `modes` · `route` | 89 · 33 | 작업 모드 · 종합에서 알맞은 모드로 옮겨 가는가 |
1295
+ | `ctxsize` | 43 | 모델에 걸린 컨텍스트 길이를 긁어오는가 |
1296
+ | `commands` · `commands-more` | 128 · 62 | 슬래시 명령 전부 |
1297
+ | `ui` · `ui2` | 60 · 40 | 암호 가림·한글 폭·상태줄·대화 목록·엑셀→글 |
1298
+ | `encoding` · `xlsx` | 68 · 72 | 한글 인코딩 판별 · 엑셀 읽기 |
875
1299
  | `compact` | 21 | 요약 압축·짝 안 깨짐·실패 시 물러섬 |
876
1300
  | `store` | 34 | 대화 저장·이어하기·중간에 죽어도 복구 |
877
- | `scan` | 19 | 여러 런타임을 구분해 찾는가 |
1301
+ | `scan` | 29 | 여러 런타임을 구분해 찾는가 |
878
1302
  | `plugins` | 38 | 플러그인 받기·묶기·ZIP/TAR |
879
1303
  | `no-bundle` | 12 | 배포 묶음에 남의 것이 안 섞였는가 · 검사 파일 위생 |
880
1304
  | `edit-bench` | 20건 | 편집 성공률 |
881
1305
 
1306
+ ### 어디를 밟았는지
1307
+
1308
+ ```bash
1309
+ npm run coverage 전체 요약
1310
+ node test/coverage.mjs --file src/repl.js 한 파일 자세히
1311
+ node test/coverage.mjs --json 기계가 읽을 형태로
1312
+ ```
1313
+
1314
+ 의존성이 0개라 c8·nyc 를 못 씁니다. 대신 Node 에 원래 들어 있는
1315
+ `NODE_V8_COVERAGE` 를 읽습니다 — 새로 반입 심사할 것이 하나도 안 늡니다.
1316
+ 자식 프로세스까지 잡히므로 `deel` 을 띄워 보는 `cli` 검사도 그대로 집계됩니다.
1317
+
1318
+ 지금 **전체 92%** (7,496줄 중 6,911줄). 일부러 못 채운 곳이 셋 있습니다.
1319
+
1320
+ | 파일 | 지금 | 왜 못 채우나 |
1321
+ |---|---|---|
1322
+ | `tools/excel.js` | 67% | 암호 걸린 엑셀을 여는 길. 이 PC 에 엑셀이 깔려 있고 암호 걸린 진짜 파일이 있어야 합니다. 흉내 내면 '되는 것처럼 보이는' 검사가 됩니다 |
1323
+ | `repl.js` | 77% | 사람이 키를 누르는 길 — Shift+Tab, Ctrl+C, 암호 입력, 붙여넣기. 가짜 터미널(pty)이 있어야 밟히는데 그건 의존성입니다. 대신 화면에 나가는 **글**은 값으로 재 봅니다(`ui`·`tui` 검사) |
1324
+ | `plugins/manage.js` | 79% | GitHub 에서 내려받는 길. **검사가 바깥으로 안 나간다**는 약속이 먼저입니다. 폴더에서 설치하는 길은 검사합니다 |
1325
+
882
1326
  ### 폴더 구조
883
1327
 
884
1328
  ```
885
1329
  bin/deel.js 진입점
886
1330
  src/
887
1331
  ui/ 색·한글 폭·상자·상태줄·입력
1332
+ ui/screen.js 화면 고르기 (줄 화면 / 상자 화면)
1333
+ ui/inputbox.js 맨 아래 입력 상자 — 그리기·지우기·커서 자리
1334
+ ui/wrap.js 색을 지키며 폭에 맞춰 접기
888
1335
  agent/loop.js 에이전트 루프
889
1336
  agent/session.js 대화 상태 + 컨텍스트 셈
890
1337
  agent/effort.js 단계별 추론 강도 배분
891
1338
  agent/compact.js 요약 압축
892
1339
  agent/store.js 대화 저장·이어하기
1340
+ agent/recall.js 지난 대화 찾기 (색인 없이, 예산 안에서)
1341
+ agent/memory.js 대화가 끝나도 남는 것
893
1342
  backend/http.js HTTP 한 겹 (바깥으로 나가는 유일한 문)
894
1343
  backend/detect.js 규격·인증 자동 판별
895
1344
  backend/adapter.js OpenAI/Ollama 차이 흡수 + 스트리밍 파서
896
1345
  backend/probe.js 진단 검사 8종
897
1346
  backend/scan.js 로컬 서버 훑기
898
- tools/index.js 도구 9종
1347
+ backend/mcp.js 밖에서 도구 붙이기 (MCP, stdio)
1348
+ tools/index.js 도구 11종
899
1349
  tools/edit-match.js 단계별 완화 편집 매칭
900
1350
  tools/webfetch.js 웹 읽기 (읽기 전용)
901
1351
  tools/todo.js 할 일 목록