deel-local-cli 1.4.0 → 1.4.2

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
@@ -1,12 +1,31 @@
1
1
  <div align="center">
2
2
 
3
- # deel
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/hero-ko-dark.svg">
5
+ <img alt="deel — 이 컴퓨터 안에서만" src="docs/assets/hero-ko-light.svg" width="620">
6
+ </picture>
4
7
 
5
- **로컬 모델과 사내 게이트웨이만으로 도는 코딩 에이전트 CLI**
8
+ ### 로컬 모델과 사내 게이트웨이만으로 도는 코딩 에이전트 CLI
6
9
 
7
10
  의존성 0개 · Node 20+ · 소스가 나가는 자리는 딱 한 곳
8
11
 
9
- [English](README.en.md) · [사내 반입 안내](#사내-반입) · [문제 해결](#문제-해결)
12
+ <br>
13
+
14
+ [![npm](https://img.shields.io/npm/v/deel-local-cli?logo=npm&logoColor=white&label=npm&color=cb3837)](https://www.npmjs.com/package/deel-local-cli)
15
+ [![downloads](https://img.shields.io/npm/dt/deel-local-cli?label=downloads&color=1a7f37)](https://www.npmjs.com/package/deel-local-cli)
16
+ [![node](https://img.shields.io/node/v/deel-local-cli?logo=nodedotjs&logoColor=white&label=node&color=5FA04E)](https://nodejs.org)
17
+ [![license](https://img.shields.io/npm/l/deel-local-cli?label=license&color=0969da)](LICENSE)
18
+
19
+ [![Node.js CI](https://img.shields.io/github/actions/workflow/status/jysvai/deel-local-cli/test.yml?branch=main&logo=github&logoColor=white&label=Node.js%20CI)](https://github.com/jysvai/deel-local-cli/actions/workflows/test.yml)
20
+ [![CodeQL](https://img.shields.io/github/actions/workflow/status/jysvai/deel-local-cli/codeql.yml?branch=main&logo=github&logoColor=white&label=CodeQL)](https://github.com/jysvai/deel-local-cli/actions/workflows/codeql.yml)
21
+ [![tests](https://img.shields.io/badge/tests-3%2C498%20passing-1a7f37?logo=checkmarx&logoColor=white)](docs/ko/develop.md)
22
+
23
+ [![dependencies](https://img.shields.io/badge/dependencies-0-1a7f37)](https://www.npmjs.com/package/deel-local-cli?activeTab=dependencies)
24
+ [![ESM](https://img.shields.io/badge/ESM-Node%2020%2B-5FA04E?logo=javascript&logoColor=white)](package.json)
25
+ [![network](https://img.shields.io/badge/network-127.0.0.1%20only-1a7f37?logo=wireguard&logoColor=white)](#데이터가-나가는-길)
26
+ [![telemetry](https://img.shields.io/badge/telemetry-none-1a7f37?logo=ghostery&logoColor=white)](#데이터가-나가는-길)
27
+
28
+ **[English](README.en.md)** · [사내 반입 안내](#사내-반입) · [문제 해결](#문제-해결) · [자세한 문서](docs/ko/)
10
29
 
11
30
  </div>
12
31
 
@@ -69,7 +88,19 @@
69
88
  - [개발](#개발)
70
89
  - [릴리스 노트](#릴리스-노트)
71
90
 
72
- 절은 요약만 두었습니다. **▸ 자세히** 를 누르면 그 안의 이야기가 펼쳐집니다.
91
+ 여기는 **요약**입니다. 절마다 붙은 링크를 따라가면 그 안의 이야기가 나옵니다.
92
+
93
+ | 자세한 문서 | 무엇이 있나 |
94
+ |---|---|
95
+ | [모델 다루기](docs/ko/models.md) | 급과 창 크기 · 국산 모델 이름표 · 켤 때 프로젝트 읽기 |
96
+ | [화면과 조작](docs/ko/interface.md) | 입력칸 · 작업 모드 · 쉬움과 개발자 · 무엇을 묻고 무엇을 그냥 하나 |
97
+ | [도구 자세히](docs/ko/tools.md) | `Outline` · `Verify` · `Task` · `Jobs` · `Append` · `Def`/`Refs` · 편집 매칭 |
98
+ | [한글 문서와 엑셀](docs/ko/documents.md) | hwpx·docx·pptx · 인코딩 · 엑셀 → CSV |
99
+ | [늘려 쓰기](docs/ko/extend.md) | 스킬 · 플러그인 · MCP · ACP |
100
+ | [속도와 씀씀이](docs/ko/tuning.md) | 단계별 추론 강도 · 프리픽스 캐시 · 컨텍스트 길이 |
101
+ | [안전망과 사내 반입](docs/ko/safety.md) | 되돌리기 · 작업 범위 · 감사기록 · 심사 서류 |
102
+ | [설정](docs/ko/config.md) · [개발](docs/ko/develop.md) | 환경변수 · 실행 옵션 · 검사 돌리기 · 폴더 구조 |
103
+ | [릴리스 노트](docs/ko/releases.md) | [1.4.2](docs/ko/releases.md#142) · [1.4.1](docs/ko/releases.md#141) · [1.4.0](docs/ko/releases.md#140) · [1.3.0](docs/ko/releases.md#130) · [1.2.0](docs/ko/releases.md#120) |
73
104
 
74
105
  ---
75
106
 
@@ -218,152 +249,9 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
218
249
 
219
250
  등록한 뒤에는 대화 중 `/model` 로 갈아탑니다. **대화 내용은 그대로 이어집니다.**
220
251
 
221
- <details>
222
- <summary><b>자세히</b> — 걸린 모델에 맞춰 스스로 바뀝니다 · 작은 창에서는 고정 몫을 줄입니다 · 켤 때 이 폴더가 무슨 프로젝트인지 읽습니다</summary>
223
-
224
- ### 걸린 모델에 맞춰 스스로 바뀝니다
225
-
226
- 여러 모델을 왔다 갔다 쓰면, 어느 한 모델에 맞춰 박아 둔 숫자는 나머지 전부에서
227
- 틀립니다. 그래서 **아무 숫자도 안 박아 뒀습니다.**
228
-
229
- 축이 둘입니다. 헷갈리기 쉬워서 명령도 따로 뒀습니다.
230
-
231
- | | 무엇을 재나 | 명령 |
232
- |---|---|---|
233
- | **창 크기** | 얼마나 담나 | `/ctx` |
234
- | **모델 급** | 얼마나 알아서 하나 | `/grade` |
235
-
236
- 둘은 같이 안 갑니다. 창이 128k 인 3B 모델이 있고, 창이 32k 인 아주 좋은 모델도
237
- 있습니다. 하나로 다루면 하나는 붙들려 있고 하나는 놓쳐집니다.
238
-
239
- **창 크기에서 뽑는 것** (`src/agent/budget.js`):
240
-
241
- | | 8k | 32k | 131k | 655k |
242
- |---|---|---|---|---|
243
- | 한 턴 걸음 수 (코드) | 16 | 48 | 192 | 200 |
244
- | `Read` 줄 수 | 200 | 384 | 1,536 | 4,000 |
245
- | `Glob` 개수 | 50 | 192 | 768 | 1,000 |
246
- | `Outline` 줄 수 | 120 | 480 | 1,920 | 2,500 |
247
- | `WebFetch` 글자 수 | 4,000 | 12,800 | 51,200 | 120,000 |
248
- | 하위 작업 요약 | 400자 | 1,600자 | 4,000자 | 4,000자 |
249
-
250
- **모델 급에서 뽑는 것** (`src/agent/grade.js`):
251
-
252
- | | 작음 | 보통 | 큼 |
253
- |---|---|---|---|
254
- | 한 번에 만들 파일 | 3개 | 6개 | 12개 |
255
- | 나눠 쓰기 기준 | 200줄 | 400줄 | 800줄 |
256
- | 절차를 못 박나 | 예 | 예 | **아니오 — 목표만 준다** |
257
- | 확인을 시키나 | 예 | 예 | **예** (급과 상관없다) |
258
-
259
- 급은 이렇게 정해집니다.
260
-
261
- 1. **이름으로 첫 어림.** `qwen2.5-coder-7b` → 작음, `llama-3.3-70b` → 큼.
262
- 판 번호(`2.5`)나 양자화 표시(`q4_k_m`)를 크기로 오해하지 않습니다.
263
- 이름을 못 읽으면 **보통**입니다 — 작음이 아닙니다. 사내 게이트웨이가 딱 그
264
- 자리인데, 거기 붙는 모델은 대개 크기 때문입니다. 작다고 잡으면 좋은 모델을
265
- 붙들어 매게 됩니다.
266
- 2. **실제로 본 것으로 고쳐 잡음.** 인자 잘림 · 빈 답 · 편집 실패 · 되풀이를 셉니다.
267
- 70B 라고 적혀 있어도 걸음마다 잘리면 **작음**으로 내리고, 7B 라도 열 걸음을
268
- 사고 없이 돌면 한 단 **올립니다.** 이름은 짐작이고, 겪은 것이 사실입니다.
269
- 3. **사람이 정하면 그것이 이깁니다.** `/grade 큼` · 되돌리려면 `/grade auto`.
270
-
271
- ```
272
- 모델 급 작음 (짐작)
273
- 이름에 7B 라고 적혀 있습니다
274
-
275
- 이 급에서 쓰는 값
276
- 한 번에 만들 파일 3개
277
- 나눠 쓰기 기준 200줄
278
- 절차를 못 박나 예
279
- 하위 작업 권함 아니오
280
-
281
- 이번 대화에서 실제로 본 것 (12걸음)
282
- 인자 잘림 0 · 빈 답 0 · 편집 실패 1 · 되풀이 0 · 도구 성공 14
283
- ```
284
-
285
- 상태줄에는 `◈ 작음?` 처럼 뜹니다. 물음표는 **아직 짐작** 이라는 뜻입니다 —
286
- 알아낸 사실과 같은 낯으로 내밀지 않습니다.
287
-
288
- 급이 바꾸는 것은 **얼마나 붙들어 주나** 뿐입니다. 작업 범위 · 승인 방식 ·
289
- 되돌리기 · 감사기록은 모든 급에서 똑같습니다. "좋은 모델이니 확인 안 해도 된다"
290
- 같은 것도 없습니다 — 그건 잘하는 모델이 잘못 만들었을 때 아무도 모르게 만듭니다.
291
-
292
- ### 작은 창에서는 고정 몫을 줄입니다
293
-
294
- 시스템 프롬프트와 도구 정의는 **매 요청에 통째로 다시 나갑니다.** 대화를 접어도
295
- (`/compact`) 이건 안 줄어듭니다. 이 몫이 창의 절반을 넘으면 아무리 잘 접어도
296
- 남는 자리가 없고, 사람 눈에는 "모델이 갑자기 멍청해졌다" 로 보입니다.
297
-
298
- 도구를 셋(`Outline` · `Verify` · `Task`) 늘리면서 8k 기준 **49%** 까지 갔습니다.
299
- 도구를 뺄까 하다가 **안 뺐습니다** — 빼면 작은 모델만 할 수 있는 일이 달라져서,
300
- "환경마다 다르게 동작" 하게 됩니다. 대신 창에 맞춰 줄였습니다.
301
-
302
- | | 8k | 16k | 32k 이상 |
303
- |---|---|---|---|
304
- | 기본 규칙 | 짧은 판 | 짧은 판 | 원래 판 |
305
- | 모드 설명 | 짧은 판 | 짧은 판 | 원래 판 |
306
- | 도구 설명 | 90자까지 | 140자까지 | 220자 / 통째로 |
307
- | 뻔한 인자 설명 | 뺌 | 남김 | 남김 |
308
- | 배열 안쪽 인자 설명 | 뺌 | 뺌 | 남김 |
309
- | **고정 몫** | **2,712토큰 (33%)** | 3,290 (21%) | 4,745 (131k 기준 4%) |
310
-
311
- 여기에 **폴더 지문**이 8k 에서 80토큰쯤 더 붙습니다(바로 아래). 그건 폴더마다
312
- 달라지는 값이라 위 표에는 안 넣었습니다.
313
-
314
- **도구 이름과 인자는 그대로 남습니다.** 할 수 있는 일은 어느 창에서나 똑같고,
315
- 없어지는 것은 '왜 이걸 쓰는지' 하는 설득뿐입니다. 큰 창에서는 그 설득이 실제로
316
- 값을 하기 때문에 그대로 둡니다 — `Outline` 을 `Read` 앞에 부르게 만드는 것이
317
- 바로 그 두 문장입니다.
318
-
319
- 이 값은 검사로 못 박혀 있습니다(`test/compact.test.js`). 프롬프트를 늘리면
320
- 거기가 먼저 빨개집니다.
321
-
322
- ### 켤 때 이 폴더가 무슨 프로젝트인지 읽습니다
323
-
324
- 남의 코드가 있는 폴더에서 켜면 모델은 아무것도 모르는 채로 시작했습니다.
325
- 그래서 매번 같은 세 걸음을 다시 밟습니다 — 위쪽을 훑고, `package.json` 을 읽고,
326
- 검사를 어떻게 돌리는지 찾습니다. **로컬 모델은 한 걸음이 20~40초라, 일을
327
- 시작하기도 전에 2분이 갑니다.**
328
-
329
- 더 나쁜 쪽도 있습니다. 그 세 걸음을 **안 밟고** 그냥 시작하는 경우입니다.
330
- 그러면 이 프로젝트가 이미 쓰는 것을 모른 채 제 관례로 파일을 만듭니다 —
331
- npm 프로젝트에 `requirements.txt` 를 만들어 놓는 식입니다.
332
-
333
- 그 세 걸음의 답은 켤 때 이미 다 알 수 있는 것이라, 한 번 읽어 프롬프트에 넣습니다.
334
-
335
- ```
336
- --- 이 폴더 ---
337
- node 프로젝트 (deel-local-cli) · git main
338
- 돌릴 수 있는 것: npm start · npm test · npm run bench · npm run chat · npm run check ·
339
- npm run coverage · npm run demo · npm run diagnose
340
- 위쪽: bin/ src/ test/ LICENSE README.en.md README.md package.json report.txt
341
- 위쪽 한 겹만 본 것이다. 안을 알아야 하면 Outline 을 불러라.
342
- ```
343
-
344
- (deel 자신의 폴더에서 켠 것입니다. 실제로는 한 줄로 나갑니다.)
345
-
346
- **이름을 지어내지 않습니다.** 돌릴 수 있는 명령은 `package.json` 의 `scripts` 에
347
- 적힌 것만 그대로 옮깁니다. 없는 명령을 알려 주면 모델이 그걸 부르고, 실패하고,
348
- 다시 찾느라 아껴 준 걸음을 도로 씁니다.
349
-
350
- **마지막 한 줄이 중요합니다.** 여기 적힌 것은 위쪽 한 겹과 `package.json` 뿐이고
351
- 하위 폴더 안은 아무것도 안 봤습니다. 그 사실을 안 적으면 모델은 이걸 프로젝트
352
- 전체 지도로 여기고 `Outline` 을 안 부릅니다 — 그러면 이 토막이 오히려 손해가 됩니다.
353
-
354
- | 안 하는 것 | 왜 |
355
- |---|---|
356
- | `git` 을 띄우지 않음 | `.git/HEAD` 를 그냥 읽습니다. 큰 저장소에서 켜는 순간 몇 초가 멈춥니다 |
357
- | 폴더를 훑지 않음 | 위쪽 **한 겹**만. 하위까지 내려가면 느려지고, 넣을 양은 어차피 한 줄입니다 |
358
- | 매 턴 다시 읽지 않음 | 켤 때 한 번입니다. 대화 도중에 프롬프트가 바뀌면 무엇 때문에 답이 달라졌는지 알 길이 없어집니다 |
359
-
360
- 창 크기에 맞춥니다 — 8k 에서는 위쪽 10개·명령 4개까지, 큰 창에서는 24개·8개까지.
361
- 좁은 창에서 하나만 남긴다면 그건 **명령**입니다. 위쪽 생김새는 `Glob` 한 번이면
362
- 다시 알 수 있지만, "`npm test` 로 검사를 돌린다" 는 `package.json` 을 열어야 압니다.
363
-
364
- 파일 600개짜리 폴더에서 7ms 입니다(`test/project.test.js`).
365
-
366
- </details>
252
+ > **자세히** — 걸린 모델에 맞춰 스스로 바뀝니다 · 국산 모델은 겪기 전에 압니다 · 작은 창에서는 고정 몫을 줄입니다 · 켤 때 이 폴더가 무슨 프로젝트인지 읽습니다
253
+ >
254
+ > **[모델 다루기 읽기 →](docs/ko/models.md#로컬-모델-여러-개-쓰기)**
367
255
 
368
256
  ---
369
257
 
@@ -377,6 +265,7 @@ node 프로젝트 (deel-local-cli) · git main
377
265
  | `/bell [on|off]` | 다 됐을 때·물어볼 때 종소리와 창 제목 |
378
266
  | `/lang [ko|en]` | 화면 말 — 영어권 사람이 쓸 때. 모델이 읽는 글도 같이 따라간다(영어 쪽이 1,400토큰 덜 먹는다). 코드는 그대로 |
379
267
  | `/consult <프로필> <질문>` | 다른 모델에게 한 번 물어보기 — 지금 쓰는 것은 안 바꿈 |
268
+ | `/export` | 이 대화를 **보고서 한 장**(HTML)으로 — 시킨 것·바뀐 것·확인한 것. 폐쇄망에서 여는 자기완결 파일 |
380
269
  | `/lsp [on\|off]` | 언어 서버 — 무엇이 깔려 있고 `Def`·`Refs` 를 쓸 수 있는지. `off` 는 고친 뒤 진단만 끔 |
381
270
  | `/context` | 무엇이 컨텍스트를 먹고 있는지 |
382
271
  | `/ctx [auto\|숫자\|자세히]` | 컨텍스트 **길이** — 모델에 맞춰 다시 재거나 직접 지정 |
@@ -429,69 +318,9 @@ node 프로젝트 (deel-local-cli) · git main
429
318
 
430
319
  한글 조합·붙여넣기·`Ctrl+A/E`·백스페이스는 전부 그대로 됩니다.
431
320
 
432
- <details>
433
- <summary><b>자세히</b> — @파일 로 바로 붙이기 · 도중에 멈추기</summary>
434
-
435
- ### `@파일` 로 바로 붙이기
436
-
437
- 말 속에 `@` 뒤로 경로를 쓰면 그 파일을 말과 함께 바로 보냅니다.
438
-
439
- ```
440
- ❯ @src/a.js 이거 왜 느려?
441
- ◧ 붙임 src/a.js
442
- ```
443
-
444
- 모델이 `Read` 를 스스로 부르는 **왕복 한 번이 없어집니다.** 로컬 모델은 도구 호출이
445
- 약해서 그 한 번이 자주 헛돕니다 — 엉뚱한 경로를 부르거나, 아예 안 부르고 지어냅니다.
446
- 사람은 이미 어느 파일인지 아는데 모델더러 찾아보라고 시킬 이유가 없습니다.
447
-
448
- 어려운 것은 붙이는 일이 아니라 **아닌 것을 파일로 오해하지 않기** 입니다.
449
- `@` 로 시작하는 것은 세상에 널렸습니다.
450
-
451
- | 이렇게 쓰면 | 어떻게 되나 |
452
- |---|---|
453
- | `@src/a.js` | 붙습니다 — 실제로 있는 경로일 때만 |
454
- | `hong@example.com` | 지목으로 안 봅니다. `@` 앞에 글자가 붙어 있으면 주소입니다 |
455
- | `@media` · `@dataclass` · `@scope/pkg` | 그대로 둡니다 — 그런 경로가 없으니까 |
456
- | `@src/` 처럼 폴더 | 안에 든 것을 목록으로 붙입니다 |
457
- | `@"보고서 초안.txt"` | 띄어쓰기가 든 이름은 따옴표로 묶습니다 |
458
- | 작업 범위 밖 | 안 붙이고, 왜 안 붙였는지 화면에 알립니다 |
459
- | CP949 사내 문서 | 무엇으로 쓰였는지 알아보고 제대로 붙입니다 |
460
-
461
- 규칙은 하나입니다 — **실제로 있는 경로일 때만 붙입니다.** 없으면 아무 말 없이
462
- 글자 그대로 둡니다. 지목이 아니었을 테니 조용한 편이 맞습니다.
463
-
464
- 붙이는 양은 컨텍스트 길이의 **25%**(많아야 20,000토큰)까지입니다. 그보다 크면 앞부분만 붙이는데,
465
- 이때는 **'읽은 것' 으로 치지 않습니다.** 잘린 파일을 읽은 것으로 쳐 두면 모델이
466
- 안 본 자리를 그냥 고쳐 버립니다. 통째로 붙은 파일만 `Read` 를 건너뜁니다.
467
-
468
- 붙인 것은 화면에 반드시 알립니다. 사람이 안 보낸 글이 대화에 들어가 있는데
469
- 그걸 모르면, 컨텍스트가 왜 줄었는지도 알 수 없습니다.
470
-
471
- ### 도중에 멈추기
472
-
473
- 모델이 엉뚱한 길로 가는 게 보이면 **Ctrl+C** 로 그 자리에서 끊습니다.
474
-
475
- ```
476
- ❯ 전체 테스트 다시 짜줘
477
- ◧ Read test/smoke.js
478
- ◧ Read test/loop.test.js
479
- ^C
480
- ⚠ 중단했습니다 (2단계까지)
481
-
482
- ❯ ▊
483
- ```
484
-
485
- 끊어도 대화는 성한 채로 남습니다 — 모델이 부르겠다고 한 도구가 있으면 그 자리에
486
- `중단했습니다` 결과를 채워 짝을 맞춥니다. 짝이 깨진 대화는 다음 요청에서 게이트웨이가
487
- 400 으로 거절하기 때문에, 이걸 안 하면 세션 하나가 통째로 못 쓰게 됩니다.
488
- 돌던 도구는 끝까지 돌고, **아직 시작 안 한 것은 실행되지 않습니다.**
489
-
490
- 빈 줄에서 한 번 더 Ctrl+C 를 누르면 프로그램이 끝납니다.
491
-
492
- 발견된 스킬의 명령은 `/<플러그인>:<이름>` 으로 부르고 `$ARGUMENTS` 가 치환됩니다.
493
-
494
- </details>
321
+ > **자세히** — @파일 로 바로 붙이기 · 도중에 멈추기
322
+ >
323
+ > **[화면과 조작 읽기 →](docs/ko/interface.md#대화-중-명령)**
495
324
 
496
325
  ---
497
326
 
@@ -521,52 +350,9 @@ node 프로젝트 (deel-local-cli) · git main
521
350
  `/think` 나 `/mode` 를 직접 고른 적이 있으면 그 선택이 우선합니다.
522
351
  모드가 사람이 고른 값을 덮어쓰지 않습니다.
523
352
 
524
- <details>
525
- <summary><b>자세히</b> — 저절로 옮겨 가기 (종합 모드)</summary>
526
-
527
- ### 저절로 옮겨 가기 (종합 모드)
528
-
529
- 처음에는 **종합** 으로 시작합니다. 무슨 일이 올지 모르는 상태입니다.
530
- 한마디를 받을 때마다 그 말을 보고 알맞은 모드로 옮겨 간 다음 일합니다.
531
-
532
- ```
533
- ❯ 로그인이 왜 안 되지?
534
-
535
- ◉ 디버그 (debug) 말 속에 '왜 안 되', '왜 안' 가 있어서
536
- 다르면 /code 처럼 직접 고르세요. 그때부터는 안 바뀝니다.
537
- ```
538
-
539
- 옮겨 가면 그 모드의 **절차·도구·추론 설정이 전부** 따라옵니다.
540
- "디버그 모드입니다" 라고 이름만 붙는 게 아니라, 실제로 증상→재현→가설→증거 순서를
541
- 밟게 하고, 계획 모드에서는 `Write`·`Edit` 를 아예 안 줍니다.
542
-
543
- | 이런 말이면 | 이 모드로 |
544
- |---|---|
545
- | 왜 안 돼 · 에러 · 실패 · 죽어요 · 원인 | ◉ 디버그 |
546
- | 계획 · 순서 · 로드맵 · 먼저 잡자 | ☰ 계획 |
547
- | 설계 · 구조를 어떻게 · 아키텍처 · 어떻게 나눌까 | ◈ 설계 |
548
- | 뭐야? · 설명해줘 · 어떻게 동작해 · 차이가 뭐야 | ◇ 묻기 |
549
- | 전체 · 전부 · 하나씩 · 끝까지 · 통일 | ❋ 총괄 |
550
- | 고쳐줘 · 만들어줘 · 구현해줘 · 지워줘 | ◆ 코드 |
551
-
552
- **애매하면 안 옮깁니다.** "음", "ㅇㅇ", "계속해줘", "아까 그거" 같은 말에는
553
- 종합 그대로 있습니다. 1등과 2등이 비슷할 때도 안 옮깁니다 —
554
- 잘못 옮겨서 읽기 전용 모드에 갇히면 사용자는 *왜* 막혔는지 모른 채 막힙니다.
555
- 그래서 읽기 전용 모드(계획·설계·묻기)는 문턱을 더 높게 뒀습니다.
556
- "설명해주고 고쳐줘" 는 묻기가 아니라 코드로 갑니다.
557
-
558
- 옮겨 간 것은 **그 한마디에만** 붙습니다. 다음 말은 다시 처음부터 고릅니다.
559
- 상태줄에 `~` 가 붙으면 저절로 옮겨 간 것이고, 없으면 직접 고르신 것입니다.
560
-
561
- ```
562
- ◎ 종합 ← 대기 중
563
- ~◉ 디버그 ← 이번 한마디만 저절로
564
- ◉ 디버그 ← /debug 로 직접 고름. 저절로 안 바뀝니다
565
- ```
566
-
567
- 직접 고르면 그때부터 **고정** 됩니다. 다시 맡기려면 `/auto` 또는 `/work 종합`.
568
-
569
- </details>
353
+ > **자세히** — 저절로 옮겨 가기 (종합 모드)
354
+ >
355
+ > **[화면과 조작 읽기 →](docs/ko/interface.md#작업-모드)**
570
356
 
571
357
  ---
572
358
 
@@ -589,199 +375,9 @@ node 프로젝트 (deel-local-cli) · git main
589
375
  - **초보라고 승인을 덜 받지 않습니다.** 되돌리기·작업 범위·위험 명령 차단은 두 수준이 같습니다.
590
376
  초보일수록 되돌릴 수 있어야 합니다.
591
377
 
592
- <details>
593
- <summary><b>자세히</b> — 입력칸 · 명령은 다 안 쳐도 됩니다 · 일하는 중에는 상자가 그대로 있습니다 · 왼쪽 그림도 같이 움직입니다 외 1개</summary>
594
-
595
- ### 입력칸
596
-
597
- 터미널에서 그냥 켜면 **대화는 위로 흘러가고, 맨 아래에 입력 상자가 붙습니다.**
598
- 상자만 우리가 지우고 다시 그립니다 — 위쪽 대화는 손대지 않습니다.
599
-
600
- ```
601
- ❊ Grep(console.log)
602
- └ 3개 파일 · 11건
603
- ◈ Edit(src/runner.js)
604
- └ 1군데 +3-1
605
- - 12 console.log('시작', 이름)
606
- + 12 logger.info({ 단계: '시작', 이름 })
607
-
608
- ▌ 로그 호출을 logger 형식으로 통일했습니다. runner.js 한 군데입니다.
609
-
610
- ── 4.2초 · 도구 3회 · ↑3,900 ↓180
611
-
612
- ▏myproject · qwen2.5-coder:7b ▏ ▰▰▱▱▱▱▱▱ 22% ▏ ◎ 종합 · ◇ medium · ⏵⏵ 자동
613
- ╭─────────────────────────────────────────────────────────────────────────────╮
614
- │ ❯ 집계 함수도 줄여줘 │
615
- ╰─────────────────────────────────────────────────────────────────────────────╯
616
- ```
617
-
618
- 터미널 스크롤·복사·`Ctrl+F` 찾기가 **그대로 됩니다.** 대화를 우리 칸에 가둬 두지
619
- 않기 때문입니다. 긴 글을 치면 상자가 알아서 여러 줄로 늘어납니다.
620
-
621
- **저절로 꺼지는 자리가 있습니다.** 파이프·리다이렉트로 넘길 때, `CI` 가 켜져 있을 때,
622
- `TERM=dumb` 일 때, 창이 40칸보다 좁을 때는 묻지 않고 상자를 안 그립니다.
623
- `deel … | tee 기록.txt` 가 제어문자 덩어리가 되면 안 되기 때문입니다.
624
- `--tui` 를 줘도 파이프면 안 켭니다. `--no-tui` 로 언제든 끌 수 있습니다.
625
-
626
- 줄 편집은 전부 Node 의 readline 이 그대로 맡습니다 — 한글 조합, 붙여넣기,
627
- 위아래 이력, Ctrl+A/E, 백스페이스. 우리는 readline 이 들고 있는 글을 상자 안에
628
- **그리기만** 합니다. 직접 키를 받아 줄 편집을 짜기 시작하면 한글 입력기부터 깨집니다.
629
-
630
- > **한 번 틀렸던 길** — 처음에는 터미널을 통째로 빌려(vim 처럼 딴 화면) 대화 칸·
631
- > 파일 칸·할 일 칸을 나눠 그렸습니다. 보기에는 그럴듯했는데 **슬래시 명령이 전부
632
- > 먹통**이 됐습니다. `commands.js` 를 비롯한 여섯 모듈이 화면 객체를 안 거치고
633
- > 터미널에 바로 쓰는데, 매번 화면을 통째로 다시 그리니 그 글이 찍히자마자 덮여
634
- > 사라졌던 것입니다. 명령이 안 도는 게 아니라 **결과가 안 보이는** 것이라 더
635
- > 나빴습니다. 고치려면 터미널에 쓰는 자리를 전부 화면 객체로 꿰야 하는데, 지금
636
- > 여섯 곳이고 앞으로 늘 것이며, 하나라도 빠뜨리면 같은 증상이 조용히 돌아옵니다.
637
- > 그래서 반대로 갔습니다 — 대화는 그냥 흘려보내고 상자만 관리합니다.
638
- > ([`test/box.test.js`](test/box.test.js) 가 터미널인 척하는 자식을 띄워
639
- > 이 결함이 다시 안 나가는지 봅니다.)
640
-
641
- ---
642
-
643
- ### 명령은 다 안 쳐도 됩니다
644
-
645
- 명령이 서른 개가 넘습니다. 다 외우고 있는 사람은 만든 사람뿐이고, 그마저도
646
- `/mem…` 까지 치고 "이게 memory 였나 memo 였나" 하고 멈춥니다. 그때 할 수 있는
647
- 것이 `/help` 를 쳐서 서른 줄을 받아 눈으로 훑는 것뿐이면, 그건 명령이 아니라
648
- 시험입니다.
649
-
650
- 그래서 **치는 도중에 보여 줍니다.**
651
-
652
- ```
653
- ╭─────────────────────────────────────────────────────────────────────────────╮
654
- │ ❯ /mo │
655
- ╰─────────────────────────────────────────────────────────────────────────────╯
656
- › /model [이름|list|models] 연결·모델 바꾸기 (이름 일부 · list · models)
657
- /mode <모드> 승인 정책 — 얼마나 물어보나
658
- /memory [지우기 <번호>|…] 대화가 끝나도 남는 기억 — 보기·지우기
659
- ```
660
-
661
- `Tab` 을 누르면 채워집니다. 하나만 맞으면 끝까지, 여럿이면 **다 같이 가진
662
- 앞부분까지만** 채웁니다(`/mo` + Tab → `/mode`). 하나를 골라 박아 넣지 않는
663
- 것은, 사람이 원한 것이 아닐 때 지우는 수고가 더 들기 때문입니다. 인자를 받는
664
- 명령이면 빈칸까지 붙여 바로 이어 칠 수 있게 합니다.
665
-
666
- 앞에서 맞는 것을 먼저 보여 주고, **가운데 맞는 것도 뒤에 붙입니다** — 오타는
667
- 앞글자에서 제일 많이 나므로, `/emo` 라고 잘못 쳐도 `/memory` 가 나옵니다.
668
- 빈칸을 치는 순간(`/mode auto`) 목록은 접힙니다. 명령이 이미 정해졌기 때문입니다.
669
-
670
- 목록은 **상자 아래**에 붙습니다. 안에 넣으면 치던 글이 밀려 올라가서 무엇을
671
- 치고 있었는지가 안 보입니다.
672
-
673
- > 위아래 화살표로 고르게 하지 않습니다. 그러면 **지난 입력 이력**(위 화살표)을
674
- > 뺏어야 하는데, 그건 훨씬 자주 쓰는 기능입니다. 여기서 필요한 것은 고르는
675
- > 것이 아니라 **알아보는 것**이고, 알아보고 나면 Tab 한 번이면 됩니다.
676
- >
677
- > `쉬움` 수준에서 감춰 둔 명령도 앞글자를 치면 나옵니다. 감춘 것은 '못 쓰는
678
- > 것' 이 아닙니다 — `/recall` 을 아는 사람이 수준 설정 때문에 "그런 명령
679
- > 없다" 는 화면을 보면 안 됩니다.
680
-
681
- ---
682
-
683
- ### 일하는 중에는 상자가 그대로 있습니다
684
-
685
- 로컬 모델은 느립니다. 한 걸음에 수십 초가 걸리는데 그 동안 화면 아래가 텅 비면
686
- **멈춘 줄 알고 Ctrl+C 를 누르게 됩니다** — 다 되어 가던 일이 그렇게 날아갑니다.
687
- 그래서 테두리는 그대로 두고 안엣것만 바꿉니다.
688
-
689
- ```
690
- ◧ Read(집계.py)
691
- └ 6줄
692
-
693
- ▏myproject · qwen2.5-coder:7b ▏ ▰▱▱▱▱▱▱▱▱▱ 2% ▏ ◎ 종합 · ◇ medium · ⏵⏵ 자동 ▏ ↑3.8k ↓180
694
- ╭─────────────────────────────────────────────────────────────────────────────╮
695
- │ ⠹ 파일 들여다보는 중… 12초 · 생각 1,240자 · Ctrl+C 중단 │
696
- ╰─────────────────────────────────────────────────────────────────────────────╯
697
- ```
698
-
699
- 문구는 **지금 진짜로 하는 일**을 따라갑니다. 재미로 넣은 것이 아닙니다 —
700
- 아무 말이나 돌려 대면 두 번째부터 아무도 안 읽고, 그때부터는 화면이 조용한 것과
701
- 같아집니다. 한 턴을 돌리면 이렇게 지나갑니다:
702
-
703
- ```
704
- 머리 굴리는 중 → 파일 들여다보는 중 → 코드 짜는 중 → 답 쓰는 중
705
- ```
706
-
707
- | 하는 일 | 문구 |
708
- |---|---|
709
- | 생각 | 머리 굴리는 중 · 어떻게 할지 궁리하는 중 · 수 읽는 중 · 따져 보는 중 |
710
- | `Read` `Grep` `Glob` | 파일 들여다보는 중 · 코드 훑는 중 · 어디 있나 뒤지는 중 · 단서 찾는 중 |
711
- | `Write` `Edit` `Append` | 코드 짜는 중 · 고쳐 넣는 중 · 손보는 중 · 한 줄씩 옮기는 중 |
712
- | `Bash` | 명령 돌리는 중 · 터미널 두드리는 중 · 결과 기다리는 중 |
713
- | `WebFetch` | 문서 찾아보는 중 · 읽어 오는 중 |
714
- | 답하는 중 | 답 쓰는 중 · 정리해서 말하는 중 |
715
- | **45초가 넘으면** | 아직 하는 중 · 조금만 더 · 생각보다 오래 걸리는 중 |
716
-
717
- ### 왼쪽 그림도 같이 움직입니다
718
-
719
- 문구 옆에서 도는 것은 돌림표가 아니라 **지금 하는 일을 그린 작은 그림**입니다.
720
-
721
- | 하는 일 | 한 바퀴 | 그림 |
722
- |---|---|---|
723
- | 생각 | `⠀⠶⠀` `⠰⣿⠆` `⢾⣿⡷` `⠰⣿⠆` | 부풀었다 줄어든다 |
724
- | 읽기 | `⠉⠉⠉` `⠒⠒⠒` `⠤⠤⠤` `⣀⣀⣀` | 훑는 줄이 내려간다 |
725
- | 쓰기 | `⡼⠭⠧` `⠼⡯⠧` `⠼⠿⡧` `⠼⡭⠧` | **노트북이 자판을 두드린다** |
726
- | 명령 | `⠉⠀⠀` `⠉⠈⠀` `⠛⠊⠀` `⠿⠮⠄` | 결과가 한 줄씩 쌓인다 |
727
- | 답 | `⠉⠀⠀` `⠛⠉⠀` `⠿⠛⠉` `⣿⠿⠛` | 글이 차오른다 |
728
- | 웹 | `⣀⣀⣀` `⣤⣀⣀` `⣶⣤⣀` `⣿⣶⣤` | 신호 막대가 자란다 |
729
- | 접기 | `⣿⣿⣿` `⣶⣶⣶` `⣤⣤⣤` `⣀⣀⣀` | 눌려서 한 줄로 모인다 |
730
- | 45초 넘으면 | `⠶⠀⠀` `⠰⠆⠀` `⠀⠶⠀` `⠀⠰⠆` | 왔다 갔다 — '기다리는 중' |
731
-
732
- 점자만 씁니다. 점자 한 칸은 **가로 2 · 세로 4 점**이라 세 칸이면 6×4 격자가 되고,
733
- 어느 터미널에서나 정확히 한 칸입니다. 이모지나 `●` `▪` 는 동아시아 로캘에서 두 칸으로
734
- 잡히는 것이 섞여 있어 90ms마다 테두리가 어긋납니다.
735
-
736
- 그림이 안 나오거나 화면 읽기 프로그램을 쓰신다면 `DEEL_NO_MOTION=1` 로 끄면
737
- 예전처럼 한 칸짜리 돌림표만 돕니다.
738
-
739
- 같은 갈래 안에서도 4초마다 다른 문구로 넘어갑니다. 같은 글자가 30초 동안 그대로
740
- 있으면 그것도 멈춘 것처럼 보이기 때문입니다. 오른쪽에는 **걸린 시간**과, 모델이
741
- 추론 중이면 **지금까지 생각한 글자 수**가 같이 뜹니다 — 진짜로 늘어나는 숫자가
742
- 하나 있어야 '살아 있다' 가 표시가 아니라 사실이 됩니다.
743
-
744
- ### 무엇을 물어보고 무엇을 그냥 할지
745
-
746
- 내 파일이 **물어보고 바뀌는지, 안 물어보고 바뀌는지**는 흘깃 봐서 바로 알아야
747
- 하는 한 가지입니다. 상태줄 오른쪽에 늘 떠 있습니다.
748
-
749
- | 표시 | 명령 | 무엇을 물어보나 |
750
- |---|---|---|
751
- | `⏵⏵ 자동 승인` | `/mode auto` | 안 묻고 고칩니다. 되돌리기(`/undo`)가 안전망입니다 |
752
- | `⏵ 위험만 확인` | `/mode confirm` | 되돌릴 수 없는 명령만 물어봅니다. 파일은 안 묻고 고칩니다 |
753
- | `⏸ 모두 확인` | `/mode strict` | 파일을 고치거나 명령을 돌리기 전에 매번 물어봅니다 |
754
-
755
- `/mode` 만 치면 셋을 나란히 보여 주고 지금 것에 ● 를 찍습니다.
756
- 켤 때 머리말에도 사람 말로 한 줄 나옵니다 — 한 번 읽고 나면 그 다음부터는
757
- 글자만 봐도 압니다.
758
-
759
- **`Shift+Tab` 으로 치지 않고 바꿉니다.** 누를 때마다 차례로 돌고, 무엇에서
760
- 무엇으로 갔는지 한 줄이 남습니다. 치던 글은 그대로 있습니다.
761
-
762
- ```
763
- ⏵ 위험만 확인 되돌릴 수 없는 명령만 물어봅니다. 파일은 안 묻고 고칩니다
764
- 자동 승인 → 위험만 확인 · Shift+Tab 으로 계속 바꿉니다
765
- ```
766
-
767
- 차례는 **느슨한 쪽 → 조이는 쪽**입니다(자동 → 위험만 → 모두 → 자동). 잘못
768
- 눌러도 더 물어보게 될 뿐, 한 번에 '안 묻고 고침' 으로 떨어지지 않습니다.
769
-
770
- > 이 자리는 원래 작업 모드(`종합`·`코드`…)가 쓰고 있었습니다. 바꾼 이유는
771
- > **누가 더 자주 손대느냐**입니다. 작업 모드는 요청을 보고 저절로 옮겨 가지만,
772
- > 승인 방식은 "이번 건은 좀 봐야겠다" 싶을 때 일하는 도중에 바꾸고 싶어집니다.
773
- > 작업 모드는 `Ctrl+O` 로 옮겼고 `/work` 도 그대로 됩니다.
774
-
775
- > 전에는 `auto` 라는 영문 한 낱말이었습니다. 옆에 `종합`·`medium·절약` 이 나란히
776
- > 있으니 셋 다 그냥 '모드' 로 보였고, 그중 하나가 **묻지 않고 파일을 고친다**는
777
- > 뜻이라는 것은 화면 어디에도 없었습니다.
378
+ > **자세히** — 입력칸 · 명령은 다 안 쳐도 됩니다 · 일하는 중에는 상자가 그대로 있습니다 · 왼쪽 그림도 같이 움직입니다 외 1개
778
379
  >
779
- > 자리가 모자랄 무엇을 접는지도 그래서 바꿨습니다. 사내 게이트웨이 모델 이름은
780
- > `databricks-gpt-5-6-luna` 처럼 스물세 칸을 그냥 먹는데, 그것 하나 때문에 승인
781
- > 방식이 화면에서 통째로 사라지고 있었습니다. 지금은 **모델 이름을 먼저 줄입니다** —
782
- > 무엇으로 도는지는 이미 알지만, 내 파일이 안 물어보고 바뀌는지는 지금 봐야 압니다.
783
-
784
- </details>
380
+ > **[화면과 조작 읽기 →](docs/ko/interface.md#쉬움--개발자)**
785
381
 
786
382
  ---
787
383
 
@@ -791,7 +387,7 @@ node 프로젝트 (deel-local-cli) · git main
791
387
 
792
388
  | 도구 | 하는 일 |
793
389
  |---|---|
794
- | `Read` | 파일 읽기 (줄 번호 · `offset`/`limit` 지원 · **엑셀은 CSV 바꿔서**) |
390
+ | `Read` | 파일 읽기 (줄 번호 · `offset`/`limit` 지원 · **엑셀은 CSV 로, hwpx·docx·pptx 는 글로 바꿔서**) |
795
391
  | `Write` | 파일 쓰기·덮어쓰기 (**여러 개는 `files` 배열로 한 번에**) |
796
392
  | `Append` | 파일 끝에 이어 붙이기 — **큰 파일을 나눠 쓰는 자리** |
797
393
  | `Edit` | 정확한 문자열 바꾸기 (`replace_all` · **여러 군데는 `edits` 배열로 한 번에**) |
@@ -816,911 +412,153 @@ Claude Code 에 없는 것은 일곱입니다 — `Append` · `Recall` · `Remem
816
412
  (`test/loop.test.js`). 뒤의 넷은 그 값을 치르고도 넣을 만해서 넣은 것들이라,
817
413
  아래에 왜인지를 적어 뒀습니다.
818
414
 
819
- <details>
820
- <summary><b>자세히</b> — Outline · Verify · Task · Def · Refs · 끝나지 않는 명령은 뒤에서 외 9개</summary>
821
-
822
- ### 프로젝트 모양을 싸게 봅니다 — `Outline`
415
+ > **자세히** — Outline · Verify · Task · Def · Refs · 끝나지 않는 명령은 뒤에서 외 9개
416
+ >
417
+ > **[도구 자세히 읽기 →](docs/ko/tools.md#도구)**
823
418
 
824
- 전에는 남의 코드를 이해하는 길이 둘뿐이었습니다. `Glob` 은 경로만 주고,
825
- `Read` 는 파일을 통째로 읽어 창을 채웁니다. **가운데가 비어 있었습니다.**
419
+ ---
826
420
 
827
- 그래서 모델은 "무엇이 어디 있는지" 를 모른 채로 고치기 시작하고, 이미 있는
828
- 함수를 엉뚱한 파일에 또 만들었습니다. 못 본 것이지 모르는 게 아니었습니다.
421
+ ## 한글 문서와 엑셀
829
422
 
830
- ```
831
- ❉ Outline(src/ui) 12개 파일 · 122곳
423
+ **CP949 로 저장된 파일은 CP949 로 되돌려 씁니다.** 인코딩을 바꾸지 않습니다.
424
+ 엑셀(`.xlsx`) CSV 로, 한글·워드·파워포인트(`.hwpx`/`.docx`/`.pptx`)는 글로
425
+ 바꿔서 읽습니다 — 전부 읽기 전용입니다.
832
426
 
833
- src/ui/screen.js (304줄)
834
- 46 fn 상자쓸까
835
- 65 class LineScreen
836
- 92 method 줄
837
- 198 class BoxScreen
838
- ```
427
+ > **자세히** — 인코딩 · 엑셀 · hwpx/docx/pptx
428
+ >
429
+ > **[한글 문서와 엑셀 읽기 →](docs/ko/documents.md#한글-문서와-엑셀)**
839
430
 
840
- 이 폴더를 `Read` 로 통째로 읽으면 **25,612토큰**, `Outline` 은 **857토큰** 입니다
841
- — 30배입니다. 8k 모델도 프로젝트 전체 모양을 볼 수 있습니다.
431
+ ---
842
432
 
843
- js/ts · py · java/kotlin · go · rust · c# · md · html · css · sh · json 을 읽습니다.
844
- 파서 없이 정규식으로 뽑습니다(의존성 0개라서). 그래서 **못 읽는 것은 못 읽는다고
845
- 말합니다** — 조용히 빼면 모델은 그 파일이 없는 줄 알고, 있는 설정을 다시 만듭니다.
433
+ ## 만든 웹을 자리에서 띄웁니다
846
434
 
847
435
  ```
848
- 여기 있지만 뼈대는 못 뽑은 것 (필요하면 Read 로 직접 읽어라):
849
- [YAML 설정 — 뼈대 없음] 설정.yml
850
- ```
851
-
852
- ### 만든 것을 확인합니다 — `Verify`
853
-
854
- 턴 끝에 이렇게 떴습니다.
436
+ /preview
855
437
 
856
- ```
857
- index.html · 410줄 · 18.2KB
438
+ ▶ 띄웠습니다 http://127.0.0.1:56801/
439
+ 보여 주는 .
440
+ 파일을 고치면 화면이 저절로 새로 뜹니다.
441
+ 이 컴퓨터에서만 열립니다(127.0.0.1). 다른 PC 에서는 안 보입니다.
442
+ 끄려면 /preview off · deel 을 끝내면 같이 꺼집니다.
858
443
  ```
859
444
 
860
- 이건 파일이 **있다**는 증명이지 **된다**는 증명이 아닙니다. `<div>` 닫아
861
- 놨어도, `src="app.js"` 가 없는 파일을 가리켜도, JS 에 괄호가 하나 모자라도
862
- 똑같이 초록으로 떴습니다.
445
+ 브라우저가 같이 열립니다. `/preview 폴더` 자리를 정하고, `/preview off` 로 끕니다.
863
446
 
864
- 돌려 있는 것은 돌려 보고(`node --check` · `py_compile`), 돌리는 것은
865
- 읽어서 봅니다(HTML 태그 · 빠진 참조 · CSS 중괄호 · JSON).
447
+ **파일을 눌러 여는 (`file://`)과 다릅니다.** `file://` 에서는 아래가 전부
448
+ 막힙니다 그런데 오류는 콘솔에만 나오고 화면은 그냥 희어서, 만든 사람은 제 코드를
449
+ 의심하며 시간을 씁니다. 진짜 HTTP 서버라 다 돕니다:
866
450
 
867
- ```
868
- ⏺ Verify 탈 1개 · 확인 3개
869
- ```
451
+ | | `file://` | `/preview` |
452
+ |---|---|---|
453
+ | `<script type="module">` · `import` | 막힘 (CORS) | **됨** |
454
+ | `fetch('./자료.json')` | 막힘 | **됨** |
455
+ | `new Worker(...)` | 막힘 | **됨** |
456
+ | `WebAssembly.compileStreaming` | 막힘 (형식) | **됨** |
457
+ | 텍스처·`getImageData` | 캔버스 오염 | **됨** |
458
+ | `.glb` / `.gltf` (Three.js) | 형식 없음 → 조용히 안 그려짐 | **됨** |
870
459
 
871
- 그리고 제일 중요한 **확인 것은 못 했다고 말합니다.**
460
+ 실제 크롬에서 일곱 가지를 돌려 **7/7** 확인했습니다.
872
461
 
873
- ```
874
- 확인 것 2개 (**됐다고 말하면된다**):
875
- ? 문서.hwp 바이너리 돌려 없습니다
876
- ```
462
+ 라우터를 쓰는 앱(React Router 등)은 안쪽 주소에서 새로고침해도 첫 장이 나옵니다.
463
+ 다만 확장자가 있는 요청(`app.js`)에는 절대그럽니다 — 없는 스크립트에 HTML 을
464
+ 돌려주면 `Unexpected token '<'` 죽는데, 그게 진짜 원인(파일 이름 오타)을 가립니다.
877
465
 
878
- 검사·빌드 같은 임의 명령은 여기서 **안 돌립니다.** 그 길은 `Bash` 하나여야 합니다
879
- — 승인 관문과 안전 검사가 거기에만 걸려 있어서, 여기서 몰래 돌리면 엄격 모드의
880
- 약속이 이 자리에서만 깨집니다. 대신 "이 프로젝트엔 `npm test` 가 있다" 고
881
- 알려만 줍니다.
466
+ ### 열어 주는 만큼만 엽니다
882
467
 
883
- ### 일은 떼어서 따로 돌립니다 `Task`
468
+ 서버를 띄운다는 것은 디스크를 남에게 열어 주는 일입니다.
884
469
 
885
- 파일 여덟 개짜리 일을 창에서 하면 여덟 파일 내용이 전부 그 창에 쌓입니다.
886
- 32k 모델이면 서너 개째에 창이 차고, 차면 앞엣말이 접혀 나갑니다. 그때부터 모델은
887
- 자기가 무엇을 만들던 중이었는지 잊습니다 **오류는 뜨고 결과만 이상해집니다.**
888
- "대시보드 만들어줘" 계획표 장으로 끝나던 일의 뿌리가 이것이었습니다.
470
+ - **`127.0.0.1` 에만** 묶습니다. `0.0.0.0` 아예 씁니다 같은 사무실 망에서
471
+ 아무나 소스를 읽게 됩니다.
472
+ - 포트는 **0**(커널이 것을 줍니다). 고정 포트는 남이 쓰던 것을 뺏습니다.
473
+ - 경로는 작업 범위 밖으로 나갑니다. `../` · `%2e%2e` · 두 번 인코딩 · 절대 경로 ·
474
+ 널바이트 · 심볼릭 링크 — 여덟 가지를 검사로 막아 뒀습니다.
475
+ - **주기만 합니다.** `POST` · `PUT` · `DELETE` 는 405 로 거절합니다.
476
+ - `deel` 을 끝내면 같이 꺼집니다.
889
477
 
890
- `Task` 는 그 덩이를 **새 대화**에서 돌리고, 부모에게는 요약 한 덩이만 돌려줍니다.
478
+ ## 스킬·플러그인
891
479
 
892
- ```
893
- ⌥ 하위 작업 화면 뼈대 만들기 따로 떨어진 대화 · 최대 8걸음
894
- │ ◆ Write(index.html 외 1개) 2개 · 24줄
895
- ✓ 하위 작업 화면 뼈대 만들기 끝냄 · 파일 2개 · 2걸음
896
- ```
480
+ **남의 스킬은 품고 다니지 않습니다.** 켜질 때 그 PC 를 훑어 있는 것을 그대로 씁니다.
897
481
 
898
- 같은 파일 넷을 만들 **한 창에 제일 많이 쌓인 양** (시스템 프롬프트 제외):
482
+ **다만 일하는 방법 일곱 가지는 품고 다닙니다.** 사내에서 새로 받은 PC 에는
483
+ `~/.claude/skills` 도 플러그인도 없습니다. 거기서는 방법론이 0개라 모델이 매번
484
+ 제 나름대로 했고, 시킨 것만 겨우 하고 끝나는 얄팍한 결과가 거기서 나왔습니다.
899
485
 
900
- | | 쌓인 |
486
+ | 스킬 | 언제 |
901
487
  |---|---|
902
- | 통째로 | 4,181자 |
903
- | `Task` 쪼개서 | **2,113자** |
904
-
905
- 파일이 늘수록 왼쪽은 계속 커지고 오른쪽은 그대로입니다.
906
-
907
- **울타리는 그대로 걸립니다.** 하위 작업도 같은 작업 폴더 안에서만 돌고, 같은
908
- 승인 방식을 따르고, `/undo` 번에 부모 것과 **같이** 되돌아가고, 감사기록에
909
- 그대로 남습니다. 읽기만 하는 모드(설계·계획·묻기)에서 하위가 파일을 고치는 길은
910
- 없습니다 — 모드 쪽과 도구 목록 쪽에서 두 겹으로 막았습니다. 깊이는 2단까지입니다.
911
-
912
- ### 끝나지 않는 명령은 뒤에서 — `Bash` 의 `background` 와 `Jobs`
488
+ | `깊이있게-만들기` | 고도화·보고용·선포용 — 최소치만 내고 끝내지 않게 |
489
+ | `끝까지-하기` | 시킨 것이 여러 조각일 때. 빼먹은 것은 말하게 |
490
+ | `차근차근-디버깅` | 재현 → 좁히기 → 원인 → 고치기 → 증명 |
491
+ | `검사-먼저` | 고치기 전에 실패하는 검사부터 |
492
+ | `찔러보기` | 되는지 모를 때 시간 정해 작게 찔러 보고 버리기 |
493
+ | `코드-줄이기` | 동작은 그대로 두고 읽기 쉽게 |
494
+ | `스스로-검토` | 됐다고 말하기 전에. 것까지 말하게 |
913
495
 
914
- `Bash` 명령이 **끝나야** 결과를 줍니다. 그래서 끝나지 않는 것을 돌렸습니다
915
- `npm run dev`, `python -m http.server`, `vite`, `npm run watch` 전부 그렇습니다.
916
- 전에는 이걸 시키면 120초를 기다렸다가 시간 초과로 죽였고, 화면에는 이 한 줄만
917
- 남았습니다.
496
+ 목록으로 나가는 몫은 354토큰입니다(8k 창의 4%). 본문은 `Skill` 부를 때만 나갑니다.
497
+ 같은 이름을 직접 만들면 그쪽이 이깁니다 품고 다니는 것이 제일 낮은 자리입니다.
918
498
 
919
499
  ```
920
- ▶ Bash(npm run dev)
921
- └ 시간 초과로 중단됨 (120000ms) 2분 0.0초
500
+ 품고 다님 (패키지 안) ← 제일 낮은 자리
501
+ 프로젝트 ./.deel/skills ./.claude/skills ./.deel/commands ./.claude/commands
502
+ 사용자 ~/.deel/skills ~/.claude/skills ~/.claude/commands
503
+ 플러그인 ~/.claude/plugins/** ~/.deel/plugins/**
922
504
  ```
923
505
 
924
- 모델은 서버를 띄운 것으로 알고 포기하거나, 나쁘게는 `timeout` 늘려서
925
- 다시 부릅니다 — 그러면 그 턴이 통째로 멈춥니다. **만든 것을 띄워서 확인하는
926
- 길이 아예 없었습니다.** `Verify` 가 "문법은 맞다" 까지 봐 주지만, 진짜로 뜨는지는
927
- 띄워 봐야 압니다.
928
-
929
- ```
930
- ▶ Bash(npm run dev)
931
- └ 1번으로 띄움
506
+ Claude Code 같은 형식(`SKILL.md` + YAML 앞머리, `commands/*.md`, `$ARGUMENTS`)읽습니다.
932
507
 
933
- Edit(src/App.jsx)
934
- └ 1군데
508
+ > **자세히** — 3단계로 나눠 올립니다 · 플러그인 받아 오기 · 안 넣은 것
509
+ >
510
+ > **[늘려 쓰기 읽기 →](docs/ko/extend.md#스킬플러그인)**
935
511
 
936
- ◐ Jobs(1번)
937
- └ 도는중 · 24초
512
+ ---
938
513
 
939
- Jobs(1번 · 끝내기)
940
- └ 끝냄 · 41초
941
- ```
514
+ ## 추론 강도
942
515
 
943
- 띄우고 **바로 돌아옵니다.** 출력은 쌓아 두고 `Jobs` 읽어 갑니다 모델은
944
- 주소와 오류를 자리에서 보고, 고치고, 다시 읽습니다.
516
+ 에이전트 번의 대답은 모델을 여러 부릅니다. **부를 때마다 필요한 생각의 양이 다릅니다.**
517
+ 전부 세게 두면 느리고, 전부 얕게 두면 엉뚱한 길로 갑니다.
945
518
 
946
- **안 것을 떴다고 하지 않습니다.** 띄운 직후 잠깐 지켜보고, 사이에 죽으면
947
- 실패로 못 박습니다. 제일 흔한 실패가 '포트가 이미 물려 있음' 인데, 그걸
948
- "띄웠습니다" 로 넘기면 모델은 다음 단계로 가고 사람은 뜨지도 않은 서버를
949
- 새로고침하며 찾아다닙니다.
519
+ 기본은 **한 줄**입니다. 알고 싶은 것은 '지금 얼마나 생각하나' 이지 단계표가 아닙니다.
950
520
 
951
521
  ```
952
- Bash(npm run dev)
953
- └ 띄우자마자 끝났습니다 (종료코드 1).
954
- ```
522
+ $ /think
955
523
 
956
- 모델에게는 아래 나온 말까지 그대로 갑니다
957
- `Error: listen EADDRINUSE: address already in use :::5173`.
958
- 대개 답은 그 몇 줄에 다 있습니다.
524
+ 추론 강도 medium (첫 판단 medium · 이어가기 low · 막혔을 때 high)
525
+ 세게 /think high 더 빠르게 /think low
526
+ ```
959
527
 
960
- | 지키는 | 내용 |
528
+ | 배분 | 성격 |
961
529
  |---|---|
962
- | 안전 검사 | `Bash` **똑같이** 거칩니다. 여기가 뒷문이 되면 됩니다 |
963
- | 거두기 | deel 끝나면 전부 죽입니다 **손자까지**, 몇 개를 껐는지 말하고 |
964
- | 들고 있는 | 256KB. 넘으면 앞을 버리고 뒤를 남기며, **버렸다고 적습니다** |
965
- | 한 번에 건네는 양 | 4,000자. 위엣것과 **다른 값이어야 합니다** |
966
- | 끝낼 때 | 죽는 순간 뱉은 말을 기다렸다 거둡니다. 그리고 **정말 죽은 뒤에** 돌아옵니다 |
967
- | 인자 이름 | 한글·영문 둘 다 받습니다 (`번호`/`job`, `끝내기`/`stop`). 못 알아들으면 **못 알아들었다고 말합니다** |
968
- | 개수 | 도는 것 8개까지. 끝난 것은 최근 8개만 남기고, 지웠으면 **지웠다고 적습니다** |
969
-
970
- 두 상한이 왜 다른 값이냐면 — 같게 두면 watch 하나가 넘칠 때마다 `Jobs` 읽기
971
- 한 번이 256KB 를 창에 쏟습니다. 8k 모델이면 그 한 번으로 창이 끝납니다.
972
-
973
- **끝낼 때 곧장 파이프를 끊지 않습니다.** 죽이라고 말한 그 순간 파이프에는 아직
974
- 안 읽힌 것이 남아 있고, 하필 **죽기 직전에 나온 몇 줄이 제일 중요합니다** —
975
- 서버가 뻗으면서 남긴 스택 트레이스가 거기 있습니다. `마지막 출력:` 이라고
976
- 적어 놓고 정작 마지막을 안 주면 안 적느니만 못합니다. 그리고 **정말 죽은
977
- 것을 확인한 뒤에** 목록에서 지웁니다. 안 죽은 채로 지우면 그놈을 다시는
978
- 가리킬 수 없게 되는데, 그게 바로 이 기능이 없애려던 상태입니다.
979
-
980
- 끝난 일감은 바로 안 지웁니다 — 마지막 출력을 읽으라고 남겨 두는 것입니다.
981
- 다만 최근 여덟만 남깁니다. 안 그러면 짧은 명령 서른 개에 항목 서른 개가 쌓이고,
982
- 하나가 최대 256KB 를 들고 있어 몇 MB 가 됩니다.
983
-
984
- **인자 이름은 한글·영문을 둘 다 받습니다.** 모델은 한글 인자 이름을 자주 영어로
985
- 바꿔 보냅니다 — 추정이 아니라 이 저장소가 겪은 일입니다(`Task` 는 이미
986
- `목적`/`purpose` 를 둘 다 받습니다). `Jobs` 에는 그게 없어서 이런 일이 있었습니다.
530
+ | `even` (균일) | 모든 단계 같은 강도 예측 가능한 대신 느림 |
531
+ | `save` (절약, 기본) | 판단만 세게, 이어가기는 얕게 |
532
+ | `deep` (깊게) | 단계 칸씩 위로 어려운 일에만 |
987
533
 
988
- ```
989
- Jobs({job: 1, stop: true}) → 목록이 돌아온다. 서버는 그대로 돈다
990
- ```
534
+ 배분은 `/think 배분 절약` 로 정합니다. **강도와 배분은 다른 축이라 명령을 갈랐습니다** —
535
+ 전에는 `/think high` `/think save` 같은 이름으로 다른 것을 정해서,
536
+ 화면을 봐도 지금 무엇이 무엇인지 읽히지 않았습니다.
991
537
 
992
- 모델은 **끄라고 시켰고 성공처럼 보이는 답을 받았는데** 포트는 계속 물려 있습니다.
993
- 그래서 둘 다 받고, 하나도 못 알아들었으면 목록으로 얼버무리지 않고 무엇을
994
- 받는지 말해 줍니다. 이름 고르기는 **한 군데에만** 둡니다 — 화면 이름표도 같은
995
- 것을 봅니다. 두 벌이 되면 도구는 제대로 도는데 화면만 빈 괄호가 됩니다.
538
+ 단계표는 `/think 자세히` 뺐습니다(개발자 수준 기본).
996
539
 
997
- **손자까지 죽이는 것이 이 기능에서 제일 조용히 어긋나는 자리입니다.**
998
- `npm run dev` 는 npm → node → vite 로 내려가고, 포트를 무는 것은 맨 아래입니다.
999
- 윈도우는 `taskkill /t` 가 나무를 훑어 주지만 유닉스에는 그런 게 없어서,
1000
- **띄울 때 무리(process group)를 만들어 둡니다** — 나중에는 손자를 가리킬
1001
- 방법이 아예 없습니다. 이걸 빠뜨리면 "3개를 껐습니다" 라고 말해 놓고 서버는
1002
- 그대로 도는 상태가 됩니다.
540
+ ```
541
+ $ /think 자세히
1003
542
 
1004
- 거두기가 기능에서 제일 조용히 다치는 자리입니다. 거두면 사람이 안 띄운
1005
- 프로세스가 계속 돕니다. 다음에 켜서 dev 서버를 띄우면 "포트가 이미 쓰이는 중" 이
1006
- 뜨는데, **무엇이 물고 있는지 알 길이 없습니다.** 그래서 `test/jobs.test.js` 가
1007
- 자국 파일로 진짜 죽었는지까지 확인합니다.
543
+ 추론 강도 medium (첫 판단 medium · 이어가기 low · 막혔을 high)
544
+ 배분 절약 첫 판단만 세게, 이어가기는 얕게 대개 이게 낫습니다
1008
545
 
1009
- `deel run` (한 번에 끝내는 모드)도 같습니다. 배치가 이걸 빠뜨리면 제일 크게
1010
- 다칩니다 잡이 끝났다고 표시된 뒤에도 서버가 돌고, 다음 잡이 같은 포트를
1011
- 잡으려다 실패합니다. 원인은 로그 어디에도 안 남습니다.
546
+ 단계 강도 출력상한 언제
547
+ 판단 · medium 15,549 무엇을 할지 정하는 자리
548
+ 이어가기 ↓ low 13,605 도구 결과를 읽고 다음
549
+ 막혔을 때 ↑ high 16,384 직전 도구가 오류를 냄
1012
550
 
1013
- ### 번에 여러 `Write` `files`, `Edit` 의 `edits`
551
+ 출력 상한은 16,384 (모르는 값이라 기본값) 안에서 나눕니다 /out
552
+ 컨텍스트 40,960 · 지금 찬 양 2,087
553
+ ```
1014
554
 
1015
- 로컬 모델은 왕복 번이 20~40초입니다. 파일 다섯 개를 만들면서 `Write`
1016
- 다섯 부르면 그것만으로 2~3분입니다. 그래서 배열로 번에 보냅니다.
1017
-
1018
- ```
1019
- ◈ Edit(src/app.js 외 2군데)
1020
- └ 2개 파일 · 3군데
1021
- ✓ src/app.js · 2군데
1022
- ✓ src/style.css · 1군데
1023
- ```
1024
-
1025
- **고치는 쪽이 값이 더 큽니다.** 파일을 새로 만드는 일은 한 번이지만, 고치는 일은
1026
- 계속 있습니다. 여섯 군데짜리 손질에 왕복이 여섯 번이면 몇 분이 그냥 갑니다.
1027
-
1028
- | | 지키는 것 |
1029
- |---|---|
1030
- | 차례로 적용 | 같은 파일을 두 번 고치는 것이 흔합니다. 매번 다시 읽어 뒤엣것이 앞엣것의 결과를 봅니다 |
1031
- | 하나가 실패해도 | 나머지는 갑니다. 첫 실패에서 멈추면 왕복을 줄이려던 것이 도로 늡니다 |
1032
- | 실패했을 때 | "실패한 것만 다시 보내세요 — **파일을 다시 `Read` 해서**" 라고 알려 줍니다 |
1033
- | 되돌리기 | 그대로 **한 턴**입니다. 같은 파일을 여섯 군데 고쳐도 `/undo` 한 번 |
1034
- | 한 개일 때 | 결과 모양이 한 글자도 안 바뀝니다 |
1035
-
1036
- `2개 파일 · 3군데` 처럼 파일 수와 군데 수를 갈라 적습니다. 한 파일을 여섯 군데
1037
- 고치는 것이 보통이라 '3개 파일' 이라고 적으면 거짓이 되고, 사람이 화면에서 세는
1038
- 것과 말이 어긋나기 시작하면 그때부터는 화면을 안 믿게 됩니다.
1039
-
1040
- ### 지난 대화를 찾고, 정한 것을 기억합니다
1041
-
1042
- deel 은 대화를 `.deel/sessions/*.jsonl` 로 꼬박꼬박 남깁니다. 그런데 목록을 보는 것
1043
- 말고는 할 수 있는 게 없었습니다 — **기록이 있는데 못 찾으면 없는 것과 같습니다.**
1044
-
1045
- ```
1046
- $ /recall 인코딩을 어떻게
1047
-
1048
- 2026-08-01 10:15 모델 20260801-101500
1049
- CP949 인코딩 문제입니다. 읽을 때 인코딩을 재서 그대로 되돌려 쓰도록…
1050
- 2026-08-20 14:45 나 20260820-144500
1051
- 저번 인코딩 규칙 그대로 적용해줘
1052
-
1053
- 2건 중 2건 · 대화 3개를 뒤졌습니다
1054
- ```
1055
-
1056
- 조사를 붙여 쳐도 찾습니다(`인코딩을` → `인코딩`). 형태소 분석기를 붙일 수는 없으니
1057
- (의존성 0) 조사처럼 보이는 꼬리를 떼어 **둘 다** 찾습니다. 색인은 안 만듭니다 —
1058
- 색인은 반드시 낡고, **낡은 색인은 없는 것보다 나쁩니다**("못 찾았습니다" 가
1059
- "없습니다" 로 읽힙니다). 대신 얼마나 뒤졌고 무엇을 못 뒤졌는지 반드시 말합니다.
1060
-
1061
- `Recall` 은 **도구로도** 줍니다. 사람만 쓰는 명령으로 두면 "저번에 정한 대로 해줘" 에
1062
- 모델이 할 수 있는 게 되묻는 것뿐입니다.
1063
-
1064
- **기억(`/memory`)은 다른 물건입니다.** 지난 대화 찾기는 *찾아야* 나오고, 기억은
1065
- *처음부터 들어가 있습니다.* 매번 다시 설명할 수 없는 것이 여기 옵니다.
1066
-
1067
- ```
1068
- $ /memory
1069
-
1070
- 1 사내 문서는 CP949 로 읽고 CP949 로 되돌려 쓴다
1071
- 2 검증할 때 7080 포트는 쓰지 않는다 — 앱 기본 포트라 진짜 data/ 를 덮는다
1072
-
1073
- 2줄 · 약 30토큰이 매 요청마다 함께 나갑니다
1074
- 파일 .deel/memory.md — 직접 고치셔도 됩니다
1075
- ```
1076
-
1077
- `.deel/memory.md` 는 **사람이 열어 고치는 글**입니다. 데이터베이스가 아닙니다.
1078
- 이게 중요합니다 — 모델이 잘못 적은 줄은 매 요청마다 실려 나가면서 계속 틀리게
1079
- 만듭니다. **틀린 기억은 없느니만 못합니다.** 그래서 `/memory 지우기 2` 로 지웁니다.
1080
-
1081
- 매 요청에 나가는 물건이라 자리를 지킵니다: 한 줄 400자 · 60줄 · 전체 6,000자.
1082
- 넘으면 오래된 것부터 빼고 뺐다고 말합니다. `/context` 에도 줄 수와 토큰이 뜹니다.
1083
-
1084
- ### 또 하게 될 절차는 스킬로 남깁니다
1085
-
1086
- 여러 걸음이 걸리는 일을 끝냈고 또 하게 될 일이면, 모델이 그 절차를
1087
- `.deel/skills/<이름>/SKILL.md` 로 적어 둡니다. 다음에 켤 때 스킬 목록에 떠서 바로
1088
- 쓸 수 있고, 쓰다가 틀린 데를 찾으면 그 파일을 고칩니다.
1089
-
1090
- 새 도구가 필요 없습니다 — 이미 있는 `Write` 로 쓰고, 이미 있는 스킬 훑기가 읽습니다.
1091
-
1092
-
1093
-
1094
- ### 큰 파일은 나눠 씁니다 — `Append`
1095
-
1096
- 출력 상한이 4k 인 모델도 2,000줄 파일을 여덟 번에 나눠 쓸 수 있어야 합니다.
1097
- `Edit` 으로 잇는 방법은 실제로 안 됩니다 — HTML 은 `</div>` 같은 앵커가 반복돼
1098
- "여러 군데에서 발견됐습니다" 로 막히고, 앵커를 길게 잡으면 그 토큰이 본문에서 빠집니다.
1099
-
1100
- 처음 만들 때는 `Write`, 이어 붙일 때는 `Append` 입니다. 인코딩은 `Write` 와 같게
1101
- 따라갑니다(사내 문서의 CP949, `.csv` 의 BOM 을 그대로 지킵니다).
1102
- 되돌리기 스냅샷은 **첫 `Append` 때 한 번만** 남습니다 — 여덟 번 이어 붙였다고
1103
- 이력에 여덟 벌이 쌓이면 되돌릴 자리를 찾을 수 없기 때문입니다.
1104
-
1105
- ```
1106
- ⏺ Write(dashboard.html)
1107
- └ ⚠ 잘린 데까지만 썼습니다 — 632줄
1108
- ↻ 대답이 상한에서 잘렸습니다 — 상한을 9,984 → 16,384 로 올려 다시 부릅니다
1109
- ⏺ Append(dashboard.html)
1110
- └ +567줄 · 전체 1,199줄
1111
-
1112
- ✓ dashboard.html · 1,199줄 · 97.7KB
1113
- ```
1114
-
1115
- 마지막 줄이 중요합니다. 파일이 없는데 모델이 "만들었습니다" 라고 하면
1116
- 그대로 믿게 됩니다. **턴이 끝날 때 실제 파일을 재서 알려 줍니다.**
1117
-
1118
- ### 할 일 목록
1119
-
1120
- 여러 단계가 걸리는 일에서 모델이 순서를 잃지 않게 하는 장치입니다.
1121
- 모델이 목록을 고칠 때마다 화면에 그대로 그려집니다.
1122
-
1123
- ```
1124
- ☰ 할 일 1/3 완료 ← 방금 1개
1125
-
1126
- ✓ 로그 형식 통일
1127
- ▶ 테스트 고치기
1128
- ☐ 문서 갱신
1129
- ```
1130
-
1131
- `진행 중` 은 한 번에 하나만 둘 수 있습니다. 둘 이상을 진행 중으로 두려고 하면
1132
- 거절합니다 — 여러 개를 동시에 붙잡으면 무엇 하나도 안 끝나기 때문입니다.
1133
-
1134
- ### 읽기만 하는 도구는 한꺼번에
1135
-
1136
- 모델이 `Read` 세 개를 한 번에 부르면 세 개를 **동시에** 돌립니다.
1137
- 파일 다섯 개를 훑는 데 걸리던 시간이 한 개 읽는 시간으로 줄어듭니다.
1138
-
1139
- ```
1140
- ◧ Read src/a.js ◧ Read src/b.js ◧ Read src/c.js 함께
1141
- ```
1142
-
1143
- 같이 도는 것은 `Read` · `Glob` · `Grep` · `Skill` · `WebFetch` 뿐입니다.
1144
- `Write` · `Edit` · `Bash` 는 언제나 하나씩 차례로 돕니다 — 같은 파일을 두 갈래로
1145
- 고치면 되돌리기 스냅샷의 순서가 엉키고, `Bash` 는 무슨 짓을 할지 알 수 없습니다.
1146
- 결과는 동시에 끝나도 **모델이 부른 순서 그대로** 돌려줍니다. 순서가 뒤섞이면
1147
- 모델이 어느 결과가 어느 호출의 것인지 헷갈립니다.
1148
-
1149
- ### 편집이 조금 틀려도 찾아냅니다
1150
-
1151
- 모델은 공백·들여쓰기·줄바꿈을 자주 틀립니다. 단계적으로 완화해 찾되,
1152
- **모호하면 무조건 거부합니다** — 엉뚱한 곳을 조용히 고치는 것이 못 찾는 것보다 훨씬 나쁩니다.
1153
-
1154
- ```
1155
- 정확히 일치 → 줄 끝 공백·CRLF 무시 → 들여쓰기 무시 → 모든 공백 무시
1156
- ```
1157
-
1158
- `npm run bench` 로 잰 결과입니다.
1159
-
1160
- | | 성공률 | 엉뚱한 곳을 고침 |
1161
- |---|---|---|
1162
- | 정확히 일치만 | 20% | 0건 |
1163
- | 지금 (단계별 완화) | **100%** | **0건** |
1164
-
1165
- 못 찾으면 파일에서 가장 비슷한 줄을 짚어 줍니다.
1166
-
1167
- ```
1168
- 찾지 못했습니다.
1169
- 파일의 2번 줄이 가장 비슷합니다:
1170
- console.log("실행 시작: " + id);
1171
- 이 줄을 그대로 옮겨 담아 다시 시도하세요.
1172
- ```
1173
-
1174
- ### 고친 자리를 그 자리에서 보여줍니다
1175
-
1176
- `auto` 모드는 안 물어보고 고칩니다. 그게 이 도구의 속도인데, 화면에 `3군데` 만
1177
- 남으면 사람은 무엇이 바뀐지 모른 채 넘어갑니다. 되돌리기가 안전망이어도
1178
- **뭐가 바뀐지 모르면 되돌릴지 말지조차 못 정합니다.**
1179
- 그래서 `Edit`·`Write` 뒤에는 바뀐 줄을 그대로 붙여 보여줍니다.
1180
-
1181
- ```
1182
- ◈ Edit(src/runner.js)
1183
- └ 1군데 +1 −2
1184
-
1185
- 11 const id = job.id;
1186
- - console.log("실행 시작: " + id);
1187
- - console.log(" 옵션 " + JSON.stringify(opts));
1188
- + 12 logger.info('실행 시작', { id, opts });
1189
- 13 return run(job);
1190
- ```
1191
-
1192
- 요약 옆의 `+1 −2` 는 늘고 준 줄 수입니다.
1193
-
1194
- - **없어진 줄에는 번호를 안 답니다.** 지금 파일에 없는 줄이니까요. 옛 번호를
1195
- 달았더니 바로 위 곁줄의 새 번호와 같은 숫자가 나란히 찍혔습니다 — 서로 다른
1196
- 파일의 번호가 한 열에 섞여 보입니다. 실제로 8번이 두 번 찍히는 화면이 나왔습니다.
1197
- - 줄 끝 표시(CRLF/LF)만 바뀌었으면 그렇다고 따로 말해 줍니다. 안 그러면 눈에
1198
- 똑같은 줄이 전부 바뀐 것으로 나와서 진짜 바뀐 곳을 못 찾습니다.
1199
- - 큰 파일은 앞뒤로 같은 부분을 먼저 잘라내고 견줍니다. 그러고도 크면 자세히 맞추기를
1200
- 포기하고 '이만큼이 통째로 바뀌었다' 로 물러섭니다 — 느린 것보다 대충이라도
1201
- 빨리 보이는 편이 낫습니다.
1202
-
1203
- 몇 줄까지 펼칠지는 수준마다 다릅니다. 처음 켠 사람에게 40줄을 쏟으면 아무것도 안 읽습니다.
1204
-
1205
- | | 쉬움 | 개발자 |
1206
- |---|---|---|
1207
- | 도구 뒤에 펼치는 줄 | 14줄 | 40줄 |
1208
- | `/diff <파일>` | 60줄 | 200줄 |
1209
-
1210
- ### `/diff` — 이번 대화에서 바뀐 것
1211
-
1212
- 도구 뒤에 지나간 화면은 스크롤에 묻힙니다. `/diff` 는 이번 대화에서 손댄 파일을
1213
- 한 장에 모읍니다.
1214
-
1215
- ```
1216
- $ /diff
1217
-
1218
- ── 이번 대화에서 바뀐 파일 ──────────────────────────────────
1219
- src/runner.js +12 −7 3번
1220
- src/logger.js +40 −0
1221
- ──────────────────────────────────────────────────────────
1222
- 2개 파일 +52 −7
1223
-
1224
- 한 파일을 자세히 보려면 /diff <파일>, 되돌리려면 /undo
1225
- ```
1226
-
1227
- `/diff <파일>` 은 **이번 대화를 시작하기 전과 지금**을 견줍니다. 세 번 고쳤어도
1228
- 사람이 알고 싶은 것은 '내가 시키기 전과 지금이 뭐가 다른가' 이지 마지막 한 번이
1229
- 아니기 때문입니다. 그 처음 모습은 되돌리기 이력의 가장 오래된 스냅샷에서 꺼냅니다.
1230
-
1231
- `/diff` 는 **쉬움 수준의 명령 목록에도 들어 있습니다.** `auto` 가 안 물어보고
1232
- 고치는 이상, 초보일수록 '무엇이 바뀌었나' 를 볼 통로가 필요합니다.
1233
-
1234
- ### 언어 서버가 있으면 뜻까지 봅니다 — `Def` · `Refs`
1235
-
1236
- `Grep` 은 **글자**를 찾고 언어 서버는 **뜻**을 압니다. `run` 을 `Grep` 으로 찾으면
1237
- 주석에 든 run, 남의 라이브러리의 run, 문자열 안의 run 이 다 같이 나옵니다. 그중
1238
- 진짜 그 함수를 부르는 자리가 몇 개인지는 사람이 하나씩 열어 봐야 압니다. 모델은
1239
- 그 값을 못 치르니 앞의 몇 개만 보고 고치고, **놓친 자리는 돌려 본 뒤에야** 나옵니다.
1240
-
1241
- ```
1242
- ⏺ Refs(셈하기)
1243
- 셈하기 — 쓰는 자리 3곳 · 파일 2개
1244
-
1245
- src/쓰는곳.py (2)
1246
- 4: return 셈하기(1, 2)
1247
- 9: return 셈하기(x, x)
1248
- src/또다른곳.py (1)
1249
- 2: 값 = 셈하기(9, 9)
1250
- ```
1251
-
1252
- `Grep` 은 그대로 남습니다. 오히려 이름을 통째로 바꿀 때는 `Grep` 쪽이 필요합니다 —
1253
- 언어 서버는 주석·설정·문서를 안 봅니다. 그래서 이 둘은 **더해 주는 것**이지
1254
- 갈아 끼우는 것이 아닙니다.
1255
-
1256
- 자리(줄·칸) 대신 **이름**을 받습니다. LSP 는 "이 파일 이 줄 이 칸" 을 묻는 규약인데
1257
- 모델은 칸 번호를 모릅니다. 알려면 파일을 먼저 `Read` 해야 하고, 그러면 이 도구를
1258
- 쓰는 값이 통째로 사라집니다. 그래서 `workspace/symbol` 로 자리를 먼저 찾고 그
1259
- 자리로 다시 묻습니다. 같은 이름이 여러 곳이면 **그 목록을 그대로 보여 줍니다** —
1260
- 하나를 골라 주고 아닌 척하지 않습니다.
1261
-
1262
- ### 고친 직후에 그 파일이 성한지 봅니다
1263
-
1264
- `Verify` 도 그대로 남습니다. 하는 일이 다릅니다.
1265
-
1266
- | | 언제 | 무엇을 |
1267
- |---|---|---|
1268
- | `Verify` | 일 다 끝내고 한 번 | **문법** (`node --check` · `py_compile`) |
1269
- | 고친 뒤 진단 | 고친 직후 그 파일만 | **뜻** (없는 이름 · 안 맞는 타입 · 빠진 인자) |
1270
-
1271
- 문법은 맞는데 틀린 것들이 있습니다. `node --check` 는 다 통과시킵니다.
1272
-
1273
- ```
1274
- ⏺ Write(pkg/bad.py)
1275
- 3줄
1276
- 언어 서버 — pkg/bad.py: 오류 2개
1277
- 1줄 오류: Type "Literal['글자']" is not assignable to declared type "int"
1278
- 2줄 오류: "없는이름" is not defined
1279
- ```
1280
-
1281
- 지금까지는 이런 것이 **돌려 본 뒤에야** 나왔고, 돌려 보는 것은 사용자 승인을
1282
- 거치는 일이라 몇 걸음 뒤였습니다. 그 사이에 모델은 그 파일을 끝낸 것으로 치고
1283
- 다음 파일로 갑니다. 나중에 오류가 나오면 어디서부터 잘못됐는지를 되짚어야 하는데,
1284
- 되짚는 값이 고치는 값보다 큽니다.
1285
-
1286
- 성할 때는 **아무 말도 안 합니다.** 고칠 때마다 "오류 0개" 를 한 줄씩 붙이면 창이
1287
- 그만큼 찹니다. 그리고 진단을 못 받은 것과 오류가 없는 것은 다릅니다 — 못 받았으면
1288
- 아무 말도 안 합니다. 없는 말을 지어내지 않습니다.
1289
-
1290
- ### 아무것도 깔지 않습니다
1291
-
1292
- **이 프로그램은 언어 서버를 깔아 주지 않습니다.** PATH 를 훑어보고, 있으면 쓰고
1293
- 없으면 `Grep`·`Outline` 으로 갑니다. 사내에 미승인 SW 를 못 들이는 자리가 이
1294
- 프로그램이 존재하는 이유라, 도구가 `npm i -g` 를 제 마음대로 부르면 안 됩니다.
1295
-
1296
- 없으면 `Def`·`Refs` 는 **모델 목록에 아예 안 나옵니다.** 오프라인일 때 웹 도구를
1297
- 숨기는 것과 같습니다 — 못 쓰는 도구를 세워 두면 모델은 그걸 부르고, "없습니다" 를
1298
- 받고, 또 부릅니다. 그 왕복이 도구 설명으로 나가는 자리보다 비쌉니다.
1299
-
1300
- 무엇이 있는지는 `/lsp` 로 봅니다.
1301
-
1302
- ```
1303
- $ /lsp
1304
-
1305
- ◈ 이 PC 에 있는 언어 서버 2개
1306
- ✓ ts typescript-language-server
1307
- ✓ py pyright-langserver
1308
-
1309
- 이 폴더의 언어: py · 12개 파일
1310
- 도구: Def · Refs
1311
- 고친 뒤 진단: 켜짐
1312
- 고친 뒤 진단 켜고 끄기: /lsp on · /lsp off
1313
- ```
1314
-
1315
- `ts` · `py` · `go` · `rs` · `java` · `cs` · `cpp` · `rb` · `php` · `lua` 를 찾습니다.
1316
- 없으면 깔 명령을 **글자로만** 보여 줍니다. 칠지 말지는 사람이 정합니다.
1317
-
1318
- <details>
1319
- <summary>붙이면서 진짜 서버(pyright)에게 배운 것 넷</summary>
1320
-
1321
- 흉내 서버로만 시험했으면 전부 초록이었을 것들입니다.
1322
-
1323
- - **서버는 주소를 우리와 다르게 적습니다.** 우리는 `file:///C:/…`, pyright 은
1324
- `file:///c%3A/…` — 드라이브 글자를 소문자로 쓰고 콜론을 퍼센트로 감쌉니다.
1325
- 글자로 견주면 영영 안 맞습니다. 진단은 제대로 오는데 표에서 못 찾아 '안 왔다' 가
1326
- 되고, **아무 말도 안 하는 것이 '성하다' 는 뜻이라** 틀린 것을 성하다고 말하게
1327
- 됩니다. 그래서 주소가 아니라 경로로 견줍니다.
1328
- - **막 켠 서버는 빈손으로 답합니다.** 없어서가 아니라 아직 프로젝트를 다 못
1329
- 훑어서입니다. 켠 지 0.2초에 물었더니 없다고 했고 0.5초 뒤엔 나왔습니다. 이걸
1330
- '없다' 로 잘라 말하면 모델은 그 말을 믿고 이미 있는 것을 새로 만듭니다. 켠 지
1331
- 얼마 안 됐을 때만 몇 번 더 물어봅니다.
1332
- - **윈도우에서 npm 이 깐 것은 이름이 둘입니다.** 확장자 없는 sh 스크립트와 `.cmd`.
1333
- 앞엣것을 먼저 찾으면 파일은 분명히 있으니 '깔려 있다' 고 나오는데, 띄우면
1334
- 윈도우가 못 돌립니다. 있다고 해 놓고 안 되는, 제일 알아채기 어려운 꼴입니다.
1335
- - **`cmd /s /c` 는 바깥 따옴표 한 쌍을 떼어 냅니다.** 한 쌍만 두르면 명령이 통째로
1336
- 깨지는데, 겉에서 보이는 것은 "언어 서버가 없습니다" 뿐입니다.
1337
-
1338
- </details>
1339
-
1340
- </details>
1341
-
1342
- ---
1343
-
1344
- ## 한글 문서와 엑셀
1345
-
1346
- **CP949 로 저장된 파일은 CP949 로 되돌려 씁니다.** 인코딩을 바꾸지 않습니다.
1347
- 엑셀(`.xlsx`)은 CSV 로 바꿔서 읽습니다 — 읽기 전용입니다.
1348
-
1349
- <details>
1350
- <summary><b>자세히</b> — 인코딩 · 엑셀</summary>
1351
-
1352
- ### 인코딩 — 읽은 그대로 되돌려 씁니다
1353
-
1354
- 사내 문서는 UTF-8 이 아닌 경우가 흔합니다. 윈도우 메모장이 오래 쓰던 완성형
1355
- (한국 CP949, 일본 CP932, 중국 GBK…) 으로 저장된 파일이 그대로 남아 있습니다.
1356
- 그걸 UTF-8 로 읽으면 통째로 깨집니다. `한글` → `�ѱ�`
1357
-
1358
- 더 위험한 건 쓸 때입니다. 깨진 채로 읽고 UTF-8 로 저장하면 원본이 상합니다.
1359
- 그래서 규칙이 하나입니다 — **읽은 인코딩으로 되돌려 씁니다.**
1360
-
1361
- 무엇으로 읽었는지는 **컴퓨터 설정이 아니라 파일 내용**을 보고 정합니다.
1362
- 후보마다 엄격하게 해독해 보고, 나온 글이 그 인코딩으로 쓴 진짜 글처럼
1363
- 보이는지 점수를 매깁니다. 그래서 우분투에서도, 미국 윈도우에서도, 한국
1364
- 윈도우에서도 같은 CP949 문서가 같게 읽힙니다.
1365
-
1366
- ```
1367
- › Read 품의서.txt
1368
- └ 4줄 · CP949
1369
- ```
1370
-
1371
- 그 인코딩에 **없는 글자**를 넣으려 하면 저장하지 않고 멈춥니다.
1372
-
1373
- ```
1374
- › Edit 품의서.txt 비고 → 비고 🚀
1375
- └ 이 파일은 CP949 로 되어 있는데, 그 인코딩에 없는 글자를 넣으려 합니다: 🚀
1376
- ```
1377
-
1378
- 조용히 물음표로 바꿔 저장하는 것보다 안 쓰는 편이 낫기 때문입니다.
1379
- 새로 만드는 파일은 UTF-8 입니다.
1380
-
1381
- 명령 출력도 마찬가지입니다. 윈도우 명령창은 UTF-8 이 아니라, `Bash` 결과를
1382
- utf8 로 받으면 한글이 깨집니다. 바이트로 받아서 풉니다.
1383
-
1384
- **되돌리기 스냅샷도 바이트로 담습니다.** 예전에는 UTF-8 글자로 적었습니다.
1385
- 그러면 CP949 파일을 되돌릴 때 `가나다`(`b0a1 b3aa b4d9`) 가 U+FFFD 여섯 개로
1386
- 돌아옵니다 — **안전망이 원본 바이트를 없애 버리는 것입니다.** 지금은 UTF-8 로
1387
- 되짚어 봐서 바이트가 그대로 살아나지 않는 파일만 base64 로 담고, 되돌릴 때
1388
- 바이트 그대로 씁니다.
1389
-
1390
- ### 엑셀 — CSV 로 바꿔서 읽습니다
1391
-
1392
- 엑셀 파일은 글이 아니라 압축 꾸러미라, 보통은 "바이너리 파일입니다" 로 끝납니다.
1393
- 사람이 손으로 CSV 로 내보내 붙여넣어야 했습니다. `Read` 가 알아서 합니다.
1394
-
1395
- ```
1396
- › Read 결재문서.xlsx
1397
- └ 시트 3개 · 128줄 · 직접 풀었습니다
1398
- ```
1399
-
1400
- - **의존성 0개** 그대로입니다. xlsx 는 사실 zip 이고 그 안은 XML 이라, Node 내장 `zlib` 만으로 풉니다.
1401
- - 시트가 여럿이면 전부 줍니다. 숨긴 시트도 줍니다 (숨김이라고 표시해서).
1402
- - 날짜는 숫자가 아니라 날짜로 보여줍니다. 서식을 읽어 판단합니다.
1403
- - 수식은 식이 아니라 **계산된 값**으로 줍니다. `#REF!` 같은 오류값은 지우지 않습니다.
1404
-
1405
- **암호가 걸린 파일과 옛 `.xls`** 는 엑셀에게 맡깁니다. 그것만은 직접 풀 수 없습니다.
1406
- 이때 암호를 물어봅니다.
1407
-
1408
- 암호는 **아무 데도 남지 않습니다.**
1409
-
1410
- - 설정 파일에 안 씁니다
1411
- - 세션 기록에 안 씁니다
1412
- - 감사기록에 안 씁니다
1413
- - 명령줄 인자로 안 넘깁니다 (작업 관리자에서 남의 명령줄이 보입니다)
1414
-
1415
- 나가는 길은 자식 프로세스의 표준입력 하나뿐이고, 그 사실을 검사로 못 박아 뒀습니다.
1416
- 쓰고 나면 임시로 뽑은 내용까지 지웁니다.
1417
-
1418
- > **엑셀 파일은 읽기만 됩니다.** `Edit`·`Write` 로 고치려 하면 막습니다.
1419
- > 서식·수식·차트가 든 파일을 CSV 로 왕복시키면 반드시 뭔가 잃기 때문입니다.
1420
- > 잃는 걸 알면서 쓰느니 안 쓰는 편이 낫습니다.
1421
-
1422
- </details>
1423
-
1424
- ---
1425
-
1426
- ## 만든 웹을 그 자리에서 띄웁니다
1427
-
1428
- ```
1429
- ❯ /preview
1430
-
1431
- ▶ 띄웠습니다 http://127.0.0.1:56801/
1432
- 보여 주는 것 .
1433
- 파일을 고치면 화면이 저절로 새로 뜹니다.
1434
- 이 컴퓨터에서만 열립니다(127.0.0.1). 다른 PC 에서는 안 보입니다.
1435
- 끄려면 /preview off · deel 을 끝내면 같이 꺼집니다.
1436
- ```
1437
-
1438
- 브라우저가 같이 열립니다. `/preview 폴더` 로 자리를 정하고, `/preview off` 로 끕니다.
1439
-
1440
- **파일을 두 번 눌러 여는 것(`file://`)과 다릅니다.** `file://` 에서는 아래가 전부
1441
- 막힙니다 — 그런데 오류는 콘솔에만 나오고 화면은 그냥 희어서, 만든 사람은 제 코드를
1442
- 의심하며 시간을 씁니다. 진짜 HTTP 서버라 다 돕니다:
1443
-
1444
- | | `file://` | `/preview` |
1445
- |---|---|---|
1446
- | `<script type="module">` · `import` | 막힘 (CORS) | **됨** |
1447
- | `fetch('./자료.json')` | 막힘 | **됨** |
1448
- | `new Worker(...)` | 막힘 | **됨** |
1449
- | `WebAssembly.compileStreaming` | 막힘 (형식) | **됨** |
1450
- | 텍스처·`getImageData` | 캔버스 오염 | **됨** |
1451
- | `.glb` / `.gltf` (Three.js) | 형식 없음 → 조용히 안 그려짐 | **됨** |
1452
-
1453
- 실제 크롬에서 이 일곱 가지를 돌려 **7/7** 을 확인했습니다.
1454
-
1455
- 라우터를 쓰는 앱(React Router 등)은 안쪽 주소에서 새로고침해도 첫 장이 나옵니다.
1456
- 다만 확장자가 있는 요청(`app.js`)에는 절대 안 그럽니다 — 없는 스크립트에 HTML 을
1457
- 돌려주면 `Unexpected token '<'` 로 죽는데, 그게 진짜 원인(파일 이름 오타)을 가립니다.
1458
-
1459
- ### 열어 주는 만큼만 엽니다
1460
-
1461
- 서버를 띄운다는 것은 내 디스크를 남에게 열어 주는 일입니다.
1462
-
1463
- - **`127.0.0.1` 에만** 묶습니다. `0.0.0.0` 은 아예 못 씁니다 — 같은 사무실 망에서
1464
- 아무나 내 소스를 읽게 됩니다.
1465
- - 포트는 **0**(커널이 빈 것을 줍니다). 고정 포트는 남이 쓰던 것을 뺏습니다.
1466
- - 경로는 작업 범위 밖으로 못 나갑니다. `../` · `%2e%2e` · 두 번 인코딩 · 절대 경로 ·
1467
- 널바이트 · 심볼릭 링크 — 여덟 가지를 검사로 막아 뒀습니다.
1468
- - **주기만 합니다.** `POST` · `PUT` · `DELETE` 는 405 로 거절합니다.
1469
- - `deel` 을 끝내면 같이 꺼집니다.
1470
-
1471
- ## 스킬·플러그인
1472
-
1473
- **남의 스킬은 품고 다니지 않습니다.** 켜질 때 그 PC 를 훑어 있는 것을 그대로 씁니다.
1474
-
1475
- **다만 일하는 방법 일곱 가지는 품고 다닙니다.** 사내에서 새로 받은 PC 에는
1476
- `~/.claude/skills` 도 플러그인도 없습니다. 거기서는 방법론이 0개라 모델이 매번
1477
- 제 나름대로 했고, 시킨 것만 겨우 하고 끝나는 얄팍한 결과가 거기서 나왔습니다.
1478
-
1479
- | 스킬 | 언제 |
1480
- |---|---|
1481
- | `깊이있게-만들기` | 고도화·보고용·선포용 — 최소치만 내고 끝내지 않게 |
1482
- | `끝까지-하기` | 시킨 것이 여러 조각일 때. 빼먹은 것은 말하게 |
1483
- | `차근차근-디버깅` | 재현 → 좁히기 → 원인 → 고치기 → 증명 |
1484
- | `검사-먼저` | 고치기 전에 실패하는 검사부터 |
1485
- | `찔러보기` | 되는지 모를 때 시간 정해 작게 찔러 보고 버리기 |
1486
- | `코드-줄이기` | 동작은 그대로 두고 읽기 쉽게 |
1487
- | `스스로-검토` | 다 됐다고 말하기 전에. 못 잰 것까지 말하게 |
1488
-
1489
- 목록으로 늘 나가는 몫은 354토큰입니다(8k 창의 4%). 본문은 `Skill` 로 부를 때만 나갑니다.
1490
- 같은 이름을 직접 만들면 그쪽이 이깁니다 — 품고 다니는 것이 제일 낮은 자리입니다.
1491
-
1492
- ```
1493
- 품고 다님 (패키지 안) ← 제일 낮은 자리
1494
- 프로젝트 ./.deel/skills ./.claude/skills ./.deel/commands ./.claude/commands
1495
- 사용자 ~/.deel/skills ~/.claude/skills ~/.claude/commands
1496
- 플러그인 ~/.claude/plugins/** ~/.deel/plugins/**
1497
- ```
1498
-
1499
- Claude Code 와 같은 형식(`SKILL.md` + YAML 앞머리, `commands/*.md`, `$ARGUMENTS`)을 읽습니다.
1500
-
1501
- <details>
1502
- <summary><b>자세히</b> — 3단계로 나눠 올립니다 · 플러그인 받아 오기 · 안 넣은 것</summary>
1503
-
1504
- ### 3단계로 나눠 올립니다
1505
-
1506
- 전부 올리면 컨텍스트가 죽습니다.
1507
-
1508
- | 단계 | 무엇을 | 비용 |
1509
- |---|---|---|
1510
- | 1 | 이름 + 설명 한 줄만 프롬프트에 | 40개 기준 약 1,800토큰 |
1511
- | 2 | 모델이 `Skill` 도구로 고른 것의 본문만 | 필요할 때 1개씩 |
1512
- | 3 | 본문이 가리키는 파일은 `Read` 로 | 그때 또 |
1513
-
1514
- ### 플러그인 받아 오기
1515
-
1516
- ```bash
1517
- # 온라인 기기에서
1518
- deel # 대화 시작 후
1519
- /plugin install affaan-m/ECC # git 이 있으면 clone, 없으면 tarball
1520
- /plugin pack 반입.zip # 실행 스크립트를 빼고 묶기
1521
-
1522
- # 오프라인 기기에서 — 압축만 풀면 됩니다
1523
- unzip 반입.zip -d ~/.deel/plugins/
1524
- ```
1525
-
1526
- `/plugin pack` 은 `.js` `.sh` `.ps1` `.py` 같은 **실행 스크립트를 빼고** 담고,
1527
- 안에 라이선스 표가 적힌 `사용안내.txt` 를 같이 넣습니다 — 그대로 반입 심사에 낼 수 있습니다.
1528
-
1529
- ### 안 넣은 것
1530
-
1531
- | | 이유 |
1532
- |---|---|
1533
- | hooks | 실행 스크립트라 반입 심사에 걸리고, 자율 실행에 사고 경로를 늘립니다 |
1534
- | 서브에이전트 | 모델 호출이 배로 늘어 게이트웨이 할당량을 먹습니다 |
1535
- | MCP | 별도 프로토콜이라 그 자체로 하나의 프로젝트입니다 |
1536
-
1537
- </details>
1538
-
1539
- ---
1540
-
1541
- ## 추론 강도
1542
-
1543
- 에이전트 한 번의 대답은 모델을 여러 번 부릅니다. **부를 때마다 필요한 생각의 양이 다릅니다.**
1544
- 전부 세게 두면 느리고, 전부 얕게 두면 엉뚱한 길로 갑니다.
1545
-
1546
- 기본은 **한 줄**입니다. 알고 싶은 것은 '지금 얼마나 생각하나' 이지 단계표가 아닙니다.
1547
-
1548
- ```
1549
- $ /think
1550
-
1551
- 추론 강도 medium (첫 판단 medium · 이어가기 low · 막혔을 때 high)
1552
- 더 세게 /think high 더 빠르게 /think low
1553
- ```
1554
-
1555
- | 배분 | 성격 |
1556
- |---|---|
1557
- | `even` (균일) | 모든 단계 같은 강도 — 예측 가능한 대신 느림 |
1558
- | `save` (절약, 기본) | 첫 판단만 세게, 이어가기는 얕게 |
1559
- | `deep` (깊게) | 전 단계 한 칸씩 위로 — 어려운 일에만 |
1560
-
1561
- 배분은 `/think 배분 절약` 로 정합니다. **강도와 배분은 다른 축이라 명령을 갈랐습니다** —
1562
- 전에는 `/think high` 와 `/think save` 가 같은 이름으로 다른 것을 정해서,
1563
- 화면을 봐도 지금 무엇이 무엇인지 읽히지 않았습니다.
1564
-
1565
- 단계표는 `/think 자세히` 로 뺐습니다(개발자 수준 기본).
1566
-
1567
- ```
1568
- $ /think 자세히
1569
-
1570
- 추론 강도 medium (첫 판단 medium · 이어가기 low · 막혔을 때 high)
1571
- 배분 절약 첫 판단만 세게, 이어가기는 얕게 — 대개 이게 낫습니다
1572
-
1573
- 단계 강도 출력상한 언제
1574
- 첫 판단 · medium 15,549 무엇을 할지 정하는 자리
1575
- 이어가기 ↓ low 13,605 도구 결과를 읽고 다음 한 수
1576
- 막혔을 때 ↑ high 16,384 직전 도구가 오류를 냄
1577
-
1578
- 출력 상한은 16,384 (모르는 값이라 기본값) 안에서 나눕니다 — /out
1579
- 컨텍스트 40,960 · 지금 찬 양 2,087
1580
- ```
1581
-
1582
- 마지막에서 두 번째 줄이 있는 이유: **세 값이 다 같을 때 그게 고장인지 아닌지**
1583
- 이 한 줄로 갈립니다. 아는 상한이 낮으면 셋이 같아지는 것이 맞습니다.
1584
- 한동안 이 표는 세 줄이 늘 `16,384` 였고, 그건 표가 뜻이 없다는 뜻이었습니다.
1585
-
1586
- <details>
1587
- <summary><b>자세히</b> — 컨텍스트 길이는 모델에서 긁어옵니다 · /out · 잘린 도구 호출</summary>
1588
-
1589
- ### 컨텍스트 길이는 모델에서 긁어옵니다
1590
-
1591
- 이 숫자 하나가 프로그램 전체 크기를 정합니다. 한 번에 읽힐 수 있는 파일 수,
1592
- 대화가 접히는 시점, 한 번에 쓸 수 있는 답 길이가 **전부 여기서 나옵니다.**
1593
-
1594
- 그래서 켤 때마다 서버에 물어봅니다. 저장된 값을 그대로 믿지 않습니다 —
1595
- 같은 이름의 모델이라도 서버에서 몇 k 로 올렸는지가 그때그때 다르고,
1596
- 그 차이는 화면에 안 뜨면 알 길이 없습니다. **그냥 조용히 작아집니다.**
1597
-
1598
- ```
1599
- │ 모델 qwen3-coder (640k 토큰) │
1600
- ╰─────────────────────────────────────────────────────────╯
1601
- ✓ 컨텍스트를 32,768 → 655,360 로 맞췄습니다 (LM Studio에서 읽음)
1602
- ```
1603
-
1604
- 서버마다 이 숫자를 다른 이름, 다른 자리에 둡니다. 한 군데만 보지 않습니다.
1605
-
1606
- | 서버 | 어디서 읽나 |
1607
- |---|---|
1608
- | LM Studio | `/api/v0/models` — `max_context_length` · `loaded_context_length` |
1609
- | llama.cpp | `/props` — `n_ctx` |
1610
- | vLLM | `/v1/models` — `max_model_len` |
1611
- | Ollama | `/api/show` — `<모델>.context_length` |
1612
- | 그 밖의 OpenAI 호환 | `/v1/models/<모델>` — `context_window` · `context_length` · `max_input_tokens` · `max_position_embeddings` (깊이 박혀 있어도 찾습니다) |
1613
-
1614
- **모델 최대와 올려 둔 길이를 구분합니다.** LM Studio 는 655,360 까지 되는 모델을
1615
- 8,192 로 올려 둘 수 있습니다. 그 상태에서 최대치를 믿고 보내면 서버가 거절합니다.
1616
- 그래서 **실제로 쓸 값은 올려 둔 길이**로 잡고, 최대치는 따로 알려 줍니다.
1617
-
1618
- ```
1619
- ⚠ 이 모델은 655,360 까지 됩니다 — 서버에서 더 올린 뒤 /ctx auto
1620
- ```
1621
-
1622
- | 명령 | 하는 일 |
1623
- |---|---|
1624
- | `/ctx` | 지금 값과 남은 자리 |
1625
- | `/ctx auto` | 서버에 다시 물어 모델에 맞춤 |
1626
- | `/ctx 655360` | 직접 지정 (`640k` · `128k` · `1m` 도 됩니다) |
1627
- | `/ctx 자세히` | 어디를 두드려서 어떤 값을 얻었는지 — 안 가져와질 때 원인을 봅니다 |
1628
- | `deel --ctx 655360` | 켤 때부터 이 값으로 (긁어오기를 건너뜁니다) |
1629
-
1630
- `/ctx` 는 **얼마나 담나**를 정합니다. **얼마나 알아서 하나**는 `/grade` 입니다 —
1631
- 다른 축이고, 위의 「걸린 모델에 맞춰 스스로 바뀝니다」 에 같이 적어 뒀습니다.
1632
-
1633
- **`k` 는 1024 입니다.** 컨텍스트 길이는 전부 2의 거듭제곱이라 그래야 아귀가 맞습니다 —
1634
- 655,360 은 `655k` 가 아니라 `640k`, 131,072 는 `131k` 가 아니라 `128k` 입니다.
1635
- 화면에 뜨는 표기와 `/ctx` 가 받는 단위가 같아서, 보이는 대로 쳐도 같은 값이 됩니다.
1636
-
1637
- ### 한 번에 받을 답 길이 — `/out`
1638
-
1639
- 컨텍스트(담아 둘 수 있는 양)와 **출력 상한**(한 번에 낼 수 있는 양)은 다른 숫자입니다.
1640
- 그 둘을 하나로 알면 큰 파일이 왜 안 만들어지는지 영영 알 수 없습니다 —
1641
- 컨텍스트는 넉넉한데 답이 잘리기 때문입니다.
1642
-
1643
- | 명령 | 하는 일 |
1644
- |---|---|
1645
- | `/out` | 지금 상한과 그 값이 **어디서 왔는지**(직접 정함 / 서버에서 알아냄 / 기본값) |
1646
- | `/out 32k` | 직접 지정 (`k` 는 1024). 프로필에 남아 다음에 켤 때도 그대로입니다 |
1647
- | `/out auto` | 직접 정한 값을 지우고 알아낸 값·기본값으로 |
1648
- | `deel --max-tokens 65536` | 켤 때부터 이 값으로 |
1649
-
1650
- 옛 이름 `/ctx out 32k` 도 그대로 받습니다.
1651
-
1652
- **상한은 고정 숫자가 아닙니다.** 모델 컨텍스트와 지금 찬 양에서 매번 계산합니다 —
1653
- 남은 자리의 몇 %를 이 단계에 내줄지가 배분입니다.
1654
-
1655
- | 모델 | 첫 판단 | 이어가기 | 막혔을 때 | 잘린 뒤 다시 |
1656
- |---|---|---|---|---|
1657
- | 2k 로컬 | 819 | 716 | 921 | 1,638 |
1658
- | 8k 로컬 | 3,276 | 2,867 | 3,686 | 6,553 |
1659
- | 40k (qwen3) | 16,384 | 14,336 | 16,384 | 16,384 |
1660
- | 128k 게이트웨이 | 16,384 | 16,384 | 16,384 | 16,384 |
1661
- | 128k 인데 80% 참 | 10,485 | 9,174 | 11,796 | 16,384 |
1662
- | 640k 에 `/out 65536` | 65,536 | 65,536 | 65,536 | 65,536 |
1663
-
1664
- 컨텍스트가 차오르면 상한도 같이 줄어듭니다. 4k 모델에 4096 을 주면 입력 자리가 안 남기 때문입니다.
1665
-
1666
- 마지막 줄이 요점입니다. **아는 값이 있으면 16,384 는 비켜섭니다.**
1667
- 한동안은 안 그랬습니다 — `Math.min(cap, max ?? 16384, 16384)` 의 세 번째 인자가
1668
- 무조건 다시 조여서, 적어 둔 값은 **낮출 수만 있고 올릴 수 없었습니다.**
1669
- 그런데 주석도 README 도 안내도 셋 다 "올릴 수 있다" 고 말했습니다.
1670
- 문서에 적힌 탈출구가 막혀 있는 것이 가장 나쁩니다.
1671
-
1672
- 아끼다 대답이 잘리면 **상한을 풀어 자동으로 다시 부릅니다.** 이때 추론 강도도 한 칸
1673
- 내립니다 — 생각 토큰이 같은 예산을 먼저 까먹기 때문에, 강도를 낮춰야 본문 자리가 실제로 늡니다.
1674
- 잘린 채로 넘어가면 도구 호출이 반토막 나서 조용히 실패합니다.
1675
-
1676
- **서버가 거절하면 그 문장에서 배웁니다.**
1677
-
1678
- ```
1679
- This model's maximum context length is 8192 tokens, however you requested 41003
1680
- ```
1681
-
1682
- 이 숫자를 뽑아 즉시 맞추고 다시 부릅니다. 사용자는 실패를 안 봅니다.
1683
- 규격을 몰라도 되므로 **처음 보는 서버에서도 통합니다.**
1684
-
1685
- ### 잘린 도구 호출
1686
-
1687
- 실제로 있었던 일입니다. 사용자가 대시보드를 만들어 달라고 했고, 모델은 HTML 문서를
1688
- 통째로 `Write` 의 인자에 넣으려다 출력 한도에 걸렸습니다. 인자 JSON 이 중간에서
1689
- 끊긴 채로 도착했습니다.
1690
-
1691
- 예전 코드는 그 읽히지 않는 JSON 을 조용히 `{_raw: "..."}` 로 바꿔 도구에 넘겼습니다.
1692
- 도구는 `경로가 비었습니다` 라고 답했습니다 — **진짜 원인과 아무 상관 없는 말입니다.**
1693
- 모델은 경로를 안 빠뜨렸으니 고칠 게 없다고 보고 똑같이 다시 시도했고, 또 잘렸습니다.
1694
-
1695
- ```
1696
- ◆ Write(dashboard.html)
1697
- └ 경로가 비었습니다 ← 아홉 번 똑같이
1698
-
1699
- ── 71초 · 도구 13회 · 컨텍스트가 차서 대화를 접음 · 파일은 안 생김
1700
- ```
1701
-
1702
- 조용히 삼킨 값 하나가 그 전부를 만들었습니다. 지금은 이렇게 합니다.
1703
-
1704
- | | 지금 |
1705
- |---|---|
1706
- | 안 읽히는 인자 | 삼키지 않고 **잘렸다고 표시**합니다. 도구에 넘기지 않습니다 |
1707
- | 모델에게 | 무슨 일이 났는지 그대로 말하고, 통째로 다시 보내지 말고 **뼈대만 먼저 만든 뒤 `Edit` 으로 나눠 이어 붙이라**고 알려 줍니다 |
1708
- | 잘린 내용 | 대화에 다시 넣지 않습니다 — 반쪽인 데다 컨텍스트만 먹습니다 |
1709
- | 잘림 판정 | 게이트웨이가 `finish_reason: "stop"` 이라고 해도 **인자가 깨진 것 자체를 잘린 증거로 봅니다.** 모델은 반쪽짜리 JSON 을 일부러 만들지 않습니다 |
1710
- | 같은 실패 3번 | 그 턴을 멈추고, 나눠서 시켜 보라고 말합니다 |
1711
-
1712
- ```
1713
- ⊘ 같은 자리에서 헛돌고 있어 멈췄습니다.
1714
- 같은 도구 호출이 계속 잘립니다
1715
- 한 번에 만들 내용이 모델의 출력 한도보다 큽니다. 나눠서 시켜 보세요 —
1716
- 예: "뼈대만 먼저 만들어줘" → "표 부분 추가해줘" → "그래프 추가해줘"
1717
- ```
1718
-
1719
- **걸음 수 상한(`maxSteps`)으로는 이걸 못 막습니다.** 그건 '잘 되고 있는 긴 작업' 과
1720
- '헛도는 작업' 을 구분하지 못합니다. 여기서 세는 것은 걸음 수가 아니라
1721
- **같은 도구가 같은 이유로 실패한 횟수**입니다.
555
+ 마지막에서 번째 줄이 있는 이유: **세 값이 같을 그게 고장인지 아닌지**
556
+ 줄로 갈립니다. 아는 상한이 낮으면 셋이 같아지는 것이 맞습니다.
557
+ 한동안 이 표는 세 줄이 늘 `16,384` 였고, 그건 표가 뜻이 없다는 뜻이었습니다.
1722
558
 
1723
- </details>
559
+ > **자세히** — 컨텍스트 길이는 모델에서 긁어옵니다 · /out · 잘린 도구 호출
560
+ >
561
+ > **[속도와 씀씀이 읽기 →](docs/ko/tuning.md#추론-강도)**
1724
562
 
1725
563
  ---
1726
564
 
@@ -1790,29 +628,9 @@ deel 은 그걸 **코드를 안 고치고** 도구로 씁니다.
1790
628
  JSON-RPC 2.0 을 주고받는 것이 전부라, `child_process` 와 `JSON` 이면 됩니다. SDK 가
1791
629
  필요 없습니다.
1792
630
 
1793
- <details>
1794
- <summary><b>자세히</b> — 다만 이건 남의 프로그램입니다</summary>
1795
-
1796
- ### 다만 이건 남의 프로그램입니다
1797
-
1798
- 이 프로젝트가 존재하는 이유가 '미승인 SW 반입 금지' 인데, MCP 를 아무렇게나 켜면
1799
- 그 선을 우리 손으로 무너뜨리는 셈입니다. 그래서:
1800
-
1801
- | | |
1802
- |---|---|
1803
- | **기본은 꺼져 있음** | `.deel/mcp.json` 에 직접 적어야만 뜹니다 |
1804
- | **`--offline` 이면 안 띄움** | 자식 프로세스가 어디로 나가는지 우리는 못 막습니다. **막을 수 없는 것을 막았다고 말하지 않습니다** |
1805
- | **작업 범위 밖** | MCP 서버는 우리 울타리를 안 지킵니다. `/mcp` 화면이 그렇다고 말합니다 |
1806
- | **감사기록에 남음** | 무엇을 띄웠고 무엇을 불렀는지 `.deel/audit.jsonl` 에 |
1807
- | **열쇠를 안 넘김** | 우리 환경변수를 통째로 안 넘깁니다 — `DEEL_*` 의 게이트웨이 열쇠가 남의 프로세스로 가면 어디로 가는지 알 수 없습니다 |
1808
- | **읽기 전용 모드엔 안 줌** | 이름이 '검색' 이어도 파일을 쓸 수 있습니다. 계획·설계 모드에서 '모르는 것' 을 쥐여 주면 그 약속이 약속이 아니게 됩니다 |
1809
- | **한 서버에 24개까지** | 스키마가 매 요청에 실립니다. 넘으면 자르고 **잘랐다고 말합니다** |
1810
-
1811
- 서버 하나가 죽거나·답이 없거나·헛소리를 해도 나머지는 그대로 씁니다. 안 뜬 것은
1812
- 조용히 빠지지 않고 머리말에 이유가 뜹니다 — 조용히 빠지면 "왜 그 도구가 없지" 를
1813
- 영영 알 수 없습니다.
1814
-
1815
- </details>
631
+ > **자세히** — 다만 이건 남의 프로그램입니다
632
+ >
633
+ > **[늘려 쓰기 읽기 →](docs/ko/extend.md#밖에서-도구-붙이기-mcp)**
1816
634
 
1817
635
  ---
1818
636
 
@@ -1845,30 +663,9 @@ deel acp
1845
663
  **의존성은 그대로 0 입니다.** MCP 와 같은 이유입니다 — 줄 단위 JSON-RPC 2.0 이
1846
664
  전부라 SDK 가 필요 없습니다.
1847
665
 
1848
- <details>
1849
- <summary><b>자세히</b> — 조용히 깨지는 자리들</summary>
1850
-
1851
- 이 프로토콜은 깨질 때 조용히 깨집니다. 에디터는 "에이전트가 응답하지 않습니다"
1852
- 만 띄우고, 왜 그런지는 어디에도 안 남습니다. 그래서 다음 자리들을 검사로 못
1853
- 박아 두었습니다 (`test/acp.test.js` — 진짜 프로세스를 띄우고 진짜 파이프로 잽니다).
1854
-
1855
- | 자리 | 왜 |
1856
- |---|---|
1857
- | **표준출력에는 ACP 말고 아무것도** | 규격이 `MUST NOT` 이라 적은 것입니다. deel 안에는 화면에 적는 자리가 수십 군데인데, 그 중 하나만 이 모드에서 불려도 관이 깨집니다. 부르는 자리를 하나씩 막는 대신 **통로 자체를 바꿔 끼웠습니다** — 앞으로 새로 쓰는 코드까지 저절로 안전합니다. 적힌 글은 버리지 않고 표준오류로 보냅니다 |
1858
- | **한글이 덩이 경계에 걸칠 때** | 파이프는 글자가 아니라 바이트로 끊깁니다. 덩이마다 따로 디코딩하면 `안녕` 이 `안<?>하` 가 되는데 **JSON 은 그대로 파싱되므로 오류도 안 납니다.** 글자만 조용히 뭉개집니다 |
1859
- | **`id` 가 0 인 요청** | ACP 클라이언트는 0번부터 셉니다. `if (msg.id)` 로 보면 첫 `initialize` 를 알림으로 오해하고 답을 안 보냅니다 — 붙자마자 멈춥니다 |
1860
- | **취소가 도중에 닿는가** | 취소는 늘 무언가가 돌고 있는 중에 옵니다. 들어온 줄을 하나씩 기다렸다 처리하면 취소는 **영영 안 닿습니다** |
1861
- | **승인을 못 물어봤을 때** | 여기서 '그냥 실행' 을 고르고 싶어집니다 — 안 그러면 승인 창을 아직 안 만든 클라이언트에서 아무것도 안 도니까. 그런데 그건 "물어볼 수 없으면 마음대로 한다" 는 뜻입니다. **안 합니다** |
1862
-
1863
- **아직 안 하는 것도 적어 둡니다.**
1864
-
1865
- | | |
1866
- |---|---|
1867
- | `session/load` | 지난 대화 되살리기. 오간 말을 전부 다시 흘려야 하는데, 반쯤 만들어 두면 에디터가 빈 대화를 열고 사용자는 기록이 날아간 줄 압니다. **`loadSession: false` 라고 분명히 말합니다** |
1868
- | 그림·소리 붙임 | 로컬 모델 대부분이 못 읽습니다. 조용히 버리지 않고 "못 읽습니다" 라고 적어 모델에게 넘깁니다 |
1869
- | 에디터가 넘긴 MCP 서버 | 띄우지 않습니다. 그러면 **에디터 설정에 적힌 프로세스를 deel 이 대신 띄우는** 셈이 됩니다. 반입 심사에서 제일 먼저 묻는 것이 "이 도구가 무엇을 띄우는가" 인데, 그 답이 '에디터가 시키는 대로' 가 되면 안 됩니다. `.deel/mcp.json` 에 사람이 직접 적은 것만 띄웁니다 |
1870
-
1871
- </details>
666
+ > **자세히** — 조용히 깨지는 자리들
667
+ >
668
+ > **[늘려 쓰기 읽기 →](docs/ko/extend.md#에디터-안에서-쓰기-acp)**
1872
669
 
1873
670
  ---
1874
671
 
@@ -1945,76 +742,9 @@ AWS 키 · Google 키 · JWT · 주소에 박힌 열쇠 · `Authorization` 계
1945
742
  32MB 를 넘으면 **최근 50턴만 남기고** 오래된 것을 버립니다. 방금 한 일은 언제나
1946
743
  되돌릴 수 있고, 지금 이력이 얼마나 되는지는 `/status` 에서 봅니다.
1947
744
 
1948
- <details>
1949
- <summary><b>자세히</b> — Bash 로 사라진 것도 되돌아갑니다 · 안 읽는 자리</summary>
1950
-
1951
- ### `Bash` 로 사라진 것도 되돌아갑니다
1952
-
1953
- 안전망이 `Write` · `Edit` 만 지키고 있었습니다. 그런데 모델은 파일을 옮길 때
1954
- 당연히 `Bash` 를 씁니다 — `mv 옛것.js 새것.js`, `rm 임시.txt`. 그 순간 파일이
1955
- 사라지는데 `/undo` 는 아무것도 못 했습니다. 절반짜리 안전망이었습니다.
1956
-
1957
- 이제 파일을 바꾸는 명령이면 손대기 전 내용을 떠 두고, **무엇을 떠 뒀는지
1958
- 그 자리에서 적습니다.**
1959
-
1960
- ```
1961
- ▶ Bash(mv src/old.js src/new.js)
1962
- └ 성공
1963
- ↩ src/old.js 는 떠 뒀습니다 — /undo 로 되돌아갑니다
1964
- ```
1965
-
1966
- `mv` 나 `rm` 은 화면에 '성공' 한 줄만 남습니다. 그 줄만 보면 되돌릴 수 있는지
1967
- 없는지 알 길이 없어서, 사람은 되돌릴 수 있는 줄 알고 넘어가거나 반대로 못
1968
- 되돌리는 줄 알고 겁을 냅니다. 그래서 사실을 적습니다.
1969
-
1970
- **못 뜨는 것이 있다는 사실을 숨기지 않습니다.** 셸이 풀어 주는 와일드카드
1971
- (`rm *.tmp`), 스크립트 안에서 지우는 것, 폴더 통째는 여기서 안 보입니다.
1972
- 그럴 때는 위의 `↩` 줄이 아예 안 나옵니다 — **'전부 되돌아간다' 고 말하지
1973
- 않습니다.** 거짓 안심을 주면 사람은 확인 없이 넘어갑니다.
1974
-
1975
- 떠 두는 쪽은 막는 쪽보다 **넓게** 잡습니다. 울타리(`checkPaths`)는 슬래시가 든
1976
- 낱말만 경로로 보는데 — 안 걸린 것을 막아 버리면 멀쩡한 명령이 막히니까요 —
1977
- `del 지울것.txt` 처럼 슬래시 없는 이름이 실제로 제일 흔합니다. 여기는 막는 자리가
1978
- 아니라 읽는 자리라 넓게 훑고, 실제로 그 자리에 파일이 있을 때만 뜹니다.
1979
- 헛다리를 짚어도 손해가 없습니다. 한 번에 24개까지입니다.
1980
-
1981
- ### 안 읽는 자리
1982
-
1983
- 폴더를 훑다 보면 프로젝트 파일이 아닌 것이 걸려 나옵니다. 다른 코딩 도구가 제 살림을
1984
- 넣어 둔 자리입니다 — 지난 대화, 명령 이력, 캐시, 그리고 열쇠.
1985
- 이 작업과 아무 상관이 없는데 목록에 나오면 모델이 그것부터 읽습니다.
1986
-
1987
- ```
1988
- ◧ Read(~/.deel/audit.jsonl) 77줄
1989
- ◧ Read(~/.claude/history.jsonl) 35줄
1990
- ```
1991
-
1992
- 감사기록은 **이 프로그램이 방금 무엇을 했는지** 적어 둔 것입니다. 그걸 다시 읽어
1993
- 대화에 넣으면 모델이 제 그림자를 좇습니다. 시킨 일과는 상관없이 컨텍스트만 찹니다.
1994
-
1995
- 설정 파일은 더 나쁩니다. `.deel/config.json` 에는 게이트웨이 **열쇠(API 키)** 가
1996
- 들어 있습니다. 읽는 순간 그 열쇠가 대화에 실려 모델로 나가고, 디스크의 세션 기록에도
1997
- 남습니다. 열쇠를 그 열쇠의 주인에게 보내는 셈입니다.
1998
-
1999
- | 안 읽는 것 | 왜 |
2000
- |---|---|
2001
- | `.deel/config.json` | 게이트웨이 열쇠가 들어 있음 |
2002
- | `.deel/audit.jsonl` · `.deel/sessions` · `.deel/history` | deel 자신의 기록. 제 그림자를 좇게 됨 |
2003
- | `.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` | 남의 도구 살림 |
2004
- | `.aider.chat.history.md` 처럼 폴더가 아니라 파일로 흘리는 것 | 같은 이유 |
2005
-
2006
- 읽기만이 아니라 **쓰기도 막습니다.** 읽기만 막아 두면 남의 도구 설정을 덮어쓸 수 있고,
2007
- `.deel/config.json` 을 덮어쓰면 연결이 통째로 날아갑니다.
2008
-
2009
- **막는 것이지 숨기는 것이 아닙니다** — 왜 안 되는지 그대로 말해 줍니다.
2010
- 새 도구는 계속 나옵니다. 목록에 없는 이름이 보이면 **한 줄 더하면 됩니다.**
2011
-
2012
- 그 목록은 **소스의 한 곳에만 둡니다.** 훑는 쪽(`SKIP_DIRS`)과 읽기 막는 쪽이
2013
- 같은 것을 봅니다. 전에는 따로 적어 놨는데, 그러면 한쪽에만 새 이름을 넣는 날이
2014
- 반드시 옵니다 — 훑을 때는 안 걸리는데 이름을 대면 읽히는, 설명하기 어려운
2015
- 상태가 됩니다.
2016
-
2017
- </details>
745
+ > **자세히** — Bash 로 사라진 것도 되돌아갑니다 · 안 읽는 자리
746
+ >
747
+ > **[안전망과 사내 반입 읽기 →](docs/ko/safety.md#안전망)**
2018
748
 
2019
749
  ---
2020
750
 
@@ -2060,33 +790,9 @@ deel sbom --only sbom # SBOM 한 장만
2060
790
  것을 발견하면 나머지도 안 믿습니다. 감사기록 사양만은 손으로 적혀 있어서,
2061
791
  그것이 진짜 기록과 어긋나지 않는지를 검사가 매번 대조합니다.
2062
792
 
2063
- <details>
2064
- <summary><b>자세히</b> — 사내 게이트웨이 진단</summary>
2065
-
2066
- ### 사내 게이트웨이 진단
2067
-
2068
- 압축을 푼 폴더에서:
2069
-
2070
- ```bash
2071
- node bin/deel.js diagnose --url <게이트웨이주소> --key <키> --model <모델> --out report.txt
2072
- ```
2073
-
2074
- `report.txt` 하나만 가져오시면 됩니다. 색 없는 평문입니다.
2075
-
2076
- | 검사 | 왜 보는가 |
2077
- |---|---|
2078
- | 기본 대화 | 주소·키·모델 이름이 맞는지 |
2079
- | 시스템 메시지 | 규칙(`DEEL.md`)과 스킬이 먹는지 |
2080
- | 스트리밍 | 화면이 한 글자씩 흐를 수 있는지 |
2081
- | **도구 호출** | **파일을 읽고 고칠 수 있는지 — 가장 중요** |
2082
- | **도구 결과 되돌리기** | **여러 턴이 이어지는지 — 에이전트 루프의 전제** |
2083
- | 구조적 출력 | 편집 형식을 스키마로 강제할 수 있는지 |
2084
- | 추론 강도 조절 | `/think` 가 모델 층에서 먹는지 |
2085
- | 컨텍스트 길이 | 파일을 몇 개까지 한 번에 읽힐 수 있는지 |
2086
-
2087
- 판정은 **준비됨 · 제한적 · 막힘 · 연결실패** 넷 중 하나로 나옵니다.
2088
-
2089
- </details>
793
+ > **자세히** — 사내 게이트웨이 진단
794
+ >
795
+ > **[안전망과 사내 반입 읽기 →](docs/ko/safety.md#사내-반입)**
2090
796
 
2091
797
  ---
2092
798
 
@@ -2094,56 +800,9 @@ node bin/deel.js diagnose --url <게이트웨이주소> --key <키> --model <모
2094
800
 
2095
801
  `~/.deel/config.json` 에 저장됩니다. 프로젝트 폴더에 `.deel/config.json` 이 있으면 그쪽이 우선입니다.
2096
802
 
2097
- <details>
2098
- <summary><b>자세히</b> — 붙는 서버 · 환경변수 · 실행 옵션 · 프로젝트 규칙</summary>
2099
-
2100
- ### 붙는 서버
2101
-
2102
- 주소만 넣으면 규격을 알아서 찾습니다.
2103
-
2104
- | | 주소 예 |
2105
- |---|---|
2106
- | 사내 AI 게이트웨이 (OpenAI 호환) | `https://ai-gw.example.corp/v1` |
2107
- | Ollama | `http://localhost:11434` |
2108
- | LM Studio | `http://localhost:1234/v1` |
2109
- | llama.cpp · vLLM · LiteLLM | `http://호스트:포트/v1` |
2110
-
2111
- 인증도 자동으로 맞춥니다 — `Authorization: Bearer` → `x-api-key` → `api-key`(Azure 계열) → 인증 없음.
2112
-
2113
- ### 환경변수
2114
-
2115
- | 변수 | 쓰임 |
2116
- |---|---|
2117
- | `DEEL_API_KEY` | 키를 파일에 안 남기고 싶을 때 (파일보다 우선) |
2118
- | `DEEL_KEY_<프로필ID>` | 프로필별 키 |
2119
- | `NODE_EXTRA_CA_CERTS` | 사내 인증서를 쓰는 게이트웨이 |
2120
- | `HTTPS_PROXY` | 프록시를 거쳐야 할 때 |
2121
- | `DEEL_DEBUG=1` | 자세한 오류 |
2122
- | `NO_COLOR` | 색 끄기 |
2123
-
2124
- ### 실행 옵션
2125
-
2126
- ```bash
2127
- deel --root <폴더> 작업 범위. 기본은 지금 폴더
2128
- deel --mode <모드> auto(기본) / confirm / strict
2129
- deel --work <모드> auto(기본·종합) / code / plan / architect / debug / ask / orchestrator
2130
- deel --level <수준> 쉬움 / 개발자
2131
- deel --ctx <길이> 컨텍스트 길이 직접 지정 (655360 · 640k · 128k)
2132
- deel --max-tokens <길이> 한 번에 받을 답 길이 상한 (32k) — /out 과 같은 값
2133
- deel --think <강도> off / low / medium(기본) / high / max
2134
- deel --effort <배분> even / save(기본) / deep
2135
- deel --offline 이 컴퓨터 밖으로 아무것도 안 보냄
2136
- deel --continue 가장 최근 대화 이어하기
2137
- deel --resume <id> 골라서 이어하기
2138
- deel --no-tui 입력 상자를 끄고 줄 화면으로 (아래 참고)
2139
- ```
2140
-
2141
- ### 프로젝트 규칙
2142
-
2143
- 작업 폴더에 `DEEL.md` · `CLAUDE.md` · `AGENTS.md` 중 하나가 있으면 읽어서 규칙으로 씁니다.
2144
- `/init` 으로 틀을 만들 수 있습니다.
2145
-
2146
- </details>
803
+ > **자세히** — 붙는 서버 · 환경변수 · 실행 옵션 · 프로젝트 규칙
804
+ >
805
+ > **[설정 읽기 →](docs/ko/config.md#설정)**
2147
806
 
2148
807
  ---
2149
808
 
@@ -2223,438 +882,23 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
2223
882
  | `no-bundle` | 12 | 배포 묶음에 남의 것이 안 섞였는가 · 검사 파일 위생 |
2224
883
  | `edit-bench` | 20건 | 편집 성공률 |
2225
884
 
2226
- <details>
2227
- <summary><b>자세히</b> — 어디를 밟았는지 · 폴더 구조</summary>
2228
-
2229
- ### 어디를 밟았는지
2230
-
2231
- ```bash
2232
- npm run coverage 전체 요약
2233
- node test/coverage.mjs --file src/repl.js 한 파일 자세히
2234
- node test/coverage.mjs --json 기계가 읽을 형태로
2235
- ```
2236
-
2237
- 의존성이 0개라 c8·nyc 를 못 씁니다. 대신 Node 에 원래 들어 있는
2238
- `NODE_V8_COVERAGE` 를 읽습니다 — 새로 반입 심사할 것이 하나도 안 늡니다.
2239
- 자식 프로세스까지 잡히므로 `deel` 을 띄워 보는 `cli` 검사도 그대로 집계됩니다.
2240
-
2241
- 지금 **전체 92%** (7,646줄 중 7,056줄). 일부러 못 채운 곳이 셋 있습니다.
2242
-
2243
- | 파일 | 지금 | 왜 못 채우나 |
2244
- |---|---|---|
2245
- | `tools/excel.js` | 67% | 암호 걸린 엑셀을 여는 길. 이 PC 에 엑셀이 깔려 있고 암호 걸린 진짜 파일이 있어야 합니다. 흉내 내면 '되는 것처럼 보이는' 검사가 됩니다 |
2246
- | `repl.js` | 77% | 사람이 키를 누르는 길 — Shift+Tab, Ctrl+C, 암호 입력, 붙여넣기. 가짜 터미널(pty)이 있어야 밟히는데 그건 의존성입니다. 대신 화면에 나가는 **글**은 값으로 재 봅니다(`ui`·`tui` 검사) |
2247
- | `plugins/manage.js` | 79% | GitHub 에서 내려받는 길. **검사가 바깥으로 안 나간다**는 약속이 먼저입니다. 폴더에서 설치하는 길은 검사합니다 |
2248
-
2249
- ### 폴더 구조
2250
-
2251
- ```
2252
- bin/deel.js 진입점
2253
- src/
2254
- repl.js 대화 화면 — 사람이 마주하는 자리
2255
- oneshot.js 한 번 돌리고 끝내기 (-p)
2256
- commands.js / 명령 35종
2257
- setup.js 처음 켤 때 연결 잡기
2258
- config.js 설정 읽고 쓰기
2259
-
2260
- ui/ansi.js 색 · 한글 폭 계산
2261
- ui/screen.js 화면 고르기 (줄 화면 / 상자 화면)
2262
- ui/inputbox.js 맨 아래 입력 상자 — 덮어 그리기·커서 자리
2263
- ui/status.js 상태줄 — 모델·컨텍스트·모드·승인
2264
- ui/working.js 일하는 중 문구 — 지금 하는 일을 따라간다
2265
- ui/motion.js 문구 옆에서 도는 점자 그림
2266
- ui/approve.js 승인 방식 표시 (자동/위험만/모두)
2267
- ui/diff.js 고친 자리를 그 자리에서 보여 주기
2268
- ui/wrap.js 색을 지키며 폭에 맞춰 접기
2269
- ui/level.js 쉬움 · 개발자
2270
-
2271
- agent/loop.js 에이전트 루프
2272
- agent/session.js 대화 상태 + 컨텍스트 셈
2273
- agent/modes.js 작업 모드 (종합·코드·계획·설계·디버그·묻기·총괄)
2274
- agent/route.js 말을 보고 알맞은 모드 고르기
2275
- agent/effort.js 단계별 추론 강도 배분
2276
- agent/budget.js 창 크기에 맞춘 몫 — 읽을 줄·설명 길이·걸음 수
2277
- agent/project.js 이 폴더가 무슨 프로젝트인지 읽기
2278
- agent/compact.js 요약 압축
2279
- agent/store.js 대화 저장·이어하기
2280
- agent/recall.js 지난 대화 찾기 (색인 없이, 예산 안에서)
2281
- agent/memory.js 대화가 끝나도 남는 것
2282
- agent/mention.js `@파일` 붙이기
2283
-
2284
- backend/http.js HTTP 한 겹 (바깥으로 나가는 유일한 문)
2285
- backend/detect.js 규격·인증 자동 판별
2286
- backend/adapter.js OpenAI/Ollama 차이 흡수 + 스트리밍 파서
2287
- backend/ctxsize.js 컨텍스트 길이를 모델에서 긁어오기
2288
- backend/probe.js 진단 검사 8종
2289
- backend/scan.js 로컬 서버 훑기
2290
- backend/mcp.js 밖에서 도구 붙이기 (MCP, stdio)
2291
-
2292
- tools/index.js 도구 17종
2293
- tools/edit-match.js 단계별 완화 편집 매칭
2294
- tools/outline.js 파일 모양만 싸게 보기
2295
- tools/verify.js 만든 것 확인
2296
- tools/task.js 큰 일을 떼어 따로 돌리기
2297
- tools/jobs.js 뒤에서 도는 명령
2298
- tools/todo.js 할 일 목록
2299
- tools/webfetch.js 웹 읽기 (읽기 전용)
2300
- tools/encoding.js 읽은 인코딩 그대로 되돌려 쓰기
2301
- tools/xlsx.js 엑셀 → CSV (직접 구현)
2302
- tools/lsp.js Def · Refs — 언어 서버에게 묻기
2303
-
2304
- lsp/rpc.js LSP 말틀 (Content-Length + JSON-RPC, 직접 구현)
2305
- lsp/servers.js 깔린 언어 서버 찾기 (안 깔아 준다)
2306
- lsp/client.js 서버 하나 띄워 놓고 주고받기 · 시한 · 정리
2307
- lsp/diag.js 고친 직후 그 파일이 성한지
2308
-
2309
- preview/serve.js 만든 웹 띄우기 (127.0.0.1 에만)
2310
- skills/discover.js 그 PC 의 스킬·명령·플러그인 찾기
2311
- plugins/manage.js 플러그인 설치·삭제·묶기
2312
- pack/zip.js ZIP 쓰기 (직접 구현, 한글 이름 보존)
2313
- pack/tar.js TAR 읽기 (직접 구현)
2314
- pack/selfpack.js 반입 심사서 + 소스 묶기
2315
-
2316
- safety/network.js 나가는 자리 자물쇠
2317
- safety/guard.js 작업 범위 + 위험 명령 차단
2318
- safety/undo.js 스냅샷·되돌리기
2319
- safety/audit.js 무엇을 언제 했는지 남기기
2320
- test/ 검증 (배포 묶음에서 뺀다)
2321
- ```
2322
-
2323
- </details>
885
+ > **자세히** — 어디를 밟았는지 · 폴더 구조
886
+ >
887
+ > **[개발 읽기 →](docs/ko/develop.md#개발)**
2324
888
 
2325
889
  ---
2326
890
 
2327
891
  ## 릴리스 노트
2328
892
 
2329
- <details>
2330
- <summary><b>▸ 1.4.0 — deel 이 제 얼굴을 갖고, 영어로도 말하고, 뜻까지 본다</b> · 일곱 자리가 어떻게 바뀌었나</summary>
2331
-
2332
- <br>
2333
-
2334
- | | 전 | 후 |
2335
- |---|---|---|
2336
- | `/undo` | 파일만 되돌렸다 — 대화는 그 일이 있었다고 믿는 채로 | **대화까지** 같이 되감는다 |
2337
- | 몇 분 걸리는 턴 | 화면만 보고 앉아 있어야 했다 | 종소리와 창 제목 — 다른 창에 가 있어도 안다 |
2338
- | 켤 때 · 상태줄 | 어느 CLI 나 같아 보였다 | 글자가 자라는 시작 모션, 경계를 말하는 상태줄 |
2339
- | 영어권 사람 | 화면이 온통 못 읽는 말이었다 | `/lang en` — 화면도 **모델이 읽는 글도** 영어로 |
2340
- | 한 세션의 모델 | 하나 | 덩이마다 다른 모델 — 잔일은 작은 모델에게 |
2341
- | 이름 찾기 | `Grep` 뿐 — 주석·문자열까지 섞여 나왔다 | `Def`·`Refs` — 언어 서버가 있으면 **뜻**으로 |
2342
- | 고친 파일 | 돌려 봐야 성한지 알았다 | 고친 **직후에** 그 파일만 본다 |
2343
-
2344
- <br>
2345
-
2346
- #### 1. `/undo` 가 대화까지 되감습니다
2347
-
2348
- 파일만 되돌리면 대화는 그 일이 있었던 채로 남습니다. 모델은 방금 고쳤다고 믿고
2349
- 다음 걸음을 그 위에 쌓습니다 — 화면에는 아무 일도 안 일어납니다. 이제 되돌린
2350
- 만큼 오간 말도 같이 접습니다. 접다가 도구 호출 짝이 깨지면 서버가 400을 내므로,
2351
- `repairToolPairs` 를 그대로 태워 짝을 맞춥니다.
2352
-
2353
- #### 2. 다 됐을 때 알려 줍니다 — `/bell`
2354
-
2355
- 로컬 모델은 한 턴이 몇 분씩 갑니다. 종소리와 창 제목으로 알립니다. 종은
2356
- `` 이지만 **파이프로는 한 글자도 안 흘립니다** — TTY 가 아니면 아무 데도
2357
- 안 씁니다. 창 제목은 ST 로 끝냅니다. BEL 로 끝내면 제목을 갱신할 때마다 종이
2358
- 울립니다.
2359
-
2360
- #### 3. deel 만의 화면
2361
-
2362
- 켤 때 `deel` 에서 `deel-local` 로 글자가 자랍니다. 상태줄은 지금 어느 경계에
2363
- 있는지를 한 글자로 말합니다(`⌂` 이 폴더 · `↗` 밖 · `?` 모름). 애니메이션은
2364
- 점자와 괘선만 씁니다 — 이모지와 도형은 East Asian Ambiguous 라 폭이 자리마다
2365
- 달라서, 한 칸씩 밀린 화면이 됩니다.
2366
-
2367
- #### 4·5. 영어권에서도, 그리고 모델이 읽는 글까지
2368
-
2369
- `/lang en` 이면 화면 말이 영어로 갑니다. 안 옮긴 마디는 빈칸 대신 한국어를 그대로
2370
- 내고, `/lang` 이 몇 개가 남았는지 정직하게 셉니다.
2371
-
2372
- 그런데 화면만 바꾸면 모델은 계속 한국어로 답합니다 — 규칙 안에 그렇게 적혀
2373
- 있어서입니다. 그래서 모델이 읽는 글(뼈대 규칙·모드 지시문·도구 설명 열여섯 개)도
2374
- 같이 갑니다. 덤이 하나 붙습니다: 한글은 글자당 약 1토큰이고 영문은 약 3.6자당
2375
- 1토큰이라, 32k 창 고정 몫이 **4,910 → 3,446 토큰**으로 줄었습니다.
2376
-
2377
- 도구 이름과 인자 이름은 **안 옮깁니다.** 그건 식별자입니다.
2378
-
2379
- #### 6. 한 세션 안에서 여러 모델 — `Task` 의 `모델`
2380
-
2381
- 8GB 램에서도 큰 모델과 작은 모델을 같이 씁니다. 잔일(형식 맞추기·되풀이 편집·
2382
- 짧은 요약)은 작은 모델에게 떼어 주고 판단이 필요한 것만 직접 합니다. 하위가
2383
- 쓰는 자리는 `allowTemporarily` 로 열고 **`finally` 에서 반드시 닫습니다** —
2384
- 끝나고 나면 열린 자리가 정확히 하나로 돌아옵니다.
2385
-
2386
- #### 7. 언어 서버 — `Def` · `Refs` · 고친 뒤 진단
2387
-
2388
- 위 "언어 서버가 있으면 뜻까지 봅니다" 를 보세요. **아무것도 깔지 않습니다.**
2389
-
2390
- </details>
2391
-
2392
- <details>
2393
- <summary><b>▸ 1.3.0 — 말 대신 증거, 터미널 대신 에디터</b> · 여섯 자리가 어떻게 바뀌었나</summary>
2394
-
2395
- <br>
2396
-
2397
- | | 전 | 후 |
2398
- |---|---|---|
2399
- | 꼭 지켜야 할 말 | 접히거나 요약되면 **사라졌다** | 프롬프트 밖에 두어 손이 못 닿는다 |
2400
- | 이 모델의 버릇 | 프롬프트에 "이렇게 해라" 고 **부탁**했다 | 하네스 설정을 바꾼다 — 모델 협조가 필요 없다 |
2401
- | 끝맺음 | "다 됐습니다" | 무엇을 바꿨고 무엇이 그걸 증명하나. **안 된 것도** |
2402
- | 쓰는 자리 | 터미널을 하나 더 | 에디터 안에서 (Zed · JetBrains · Neovim · Emacs) |
2403
- | 심사 서류 | 사람이 읽는 글 한 장 | SBOM · 통신 목록 · 감사 사양 — **스캐너에 그대로** |
2404
- | 열쇠 | `env` 한 번이면 대화에도 디스크에도 남았다 | 들어가는 한 자리에서 가린다. 파일은 **일부러** 안 가린다 |
2405
-
2406
- <br>
2407
-
2408
- #### 1. 꼭 지켜야 할 말이 접히면서 사라지던 것 — `/pin`
2409
-
2410
- 긴 대화에서는 자리를 비우려고 앞선 말을 접거나 요약합니다. 그런데 2026년 재기로는
2411
- **요약이 안전 제약을 50% 밖에 안 남깁니다.** "이 파일은 절대 건드리지 마세요" 가
2412
- 그 50% 에 안 들면, 모델은 그 말을 들은 적이 없는 상태가 됩니다. 화면에는 아무 일도
2413
- 안 일어납니다.
2414
-
2415
- 못 박은 말은 **오간 말 쪽에 안 둡니다.** 시스템 프롬프트 끝에 붙입니다 — 접기도
2416
- 요약도 오간 말만 만지므로, 구조적으로 손이 닿지 않습니다. 조심해서 안 지우는 것이
2417
- 아니라 **지울 수가 없습니다.**
2418
-
2419
- ```
2420
- /pin src/legacy 폴더는 건드리지 마세요
2421
-
2422
- ✓ 못 박았습니다 — 지금 2개 (78 토큰)
2423
- ```
2424
-
2425
- 12개 · 240 토큰까지입니다. 넘으면 넘었다고 말하고 최근 것부터 싣습니다 — 조용히
2426
- 빠뜨리면 못 박은 뜻이 없어집니다.
2427
-
2428
- #### 2. 겪어 본 버릇이 말로만 남던 것 — `/model 카드`
2429
-
2430
- deel 은 이미 모델의 버릇을 지켜보고 있었습니다. 그런데 지켜보기만 하고 **프롬프트에
2431
- 적는 것**이 전부였습니다 — "인자를 자주 잘라 먹었으니 Append 를 써라" 하고. 작은
2432
- 모델은 그 말을 잘 안 듣습니다. 그게 작은 모델입니다.
2433
-
2434
- 이제 겪은 것이 **하네스 설정**으로 바뀝니다. 모델에게 부탁하는 대신 deel 이 제
2435
- 행동을 바꿉니다.
2436
-
2437
- | 겪은 것 | 바뀌는 것 |
2438
- |---|---|
2439
- | 인자가 자주 잘린다 (15% 넘게) | 처음부터 상한을 높여 부릅니다 — 한 번 버리고 다시 부르지 않게 |
2440
- | 같은 것을 되풀이한다 | 세 번까지 봐 주던 것을 두 번에서 끊습니다 |
2441
- | 편집이 자주 빗나간다 | 빗나갔을 때 보여 주는 앞뒤 줄을 늘립니다 |
2442
-
2443
- 12걸음을 걸어 보기 전에는 **아무것도 안 바꿉니다.** 우연히 한 번 잘린 것 때문에
2444
- 멀쩡한 모델을 붙들어 매면 안 배우느니만 못합니다.
2445
-
2446
- #### 3. "다 됐습니다" 대신 검토할 수 있는 것 — `/evidence`
2447
-
2448
- 2026년 조사로는 개발자의 **96%가 AI 가 쓴 코드를 온전히 믿지 않는데, 매번 확인하는
2449
- 사람은 48%** 입니다. 38%는 "사람 코드보다 리뷰가 더 힘들다"고 답했습니다.
2450
-
2451
- 왜 더 힘든가. 사람이 낸 코드는 "왜 이렇게 했나" 를 물으면 답이 옵니다. 에이전트가
2452
- 낸 코드는 **"끝났습니다" 한 줄**과 함께 옵니다. 그 한 줄은 검토할 수가 없습니다.
2453
-
2454
- ```
2455
- /evidence
2456
-
2457
- 바꾼 것 3개 파일 · +142 −38
2458
- 돌린 것 5개 (실패 1)
2459
- 증명 안 된 것 1개
2460
-
2461
- ✗ src/worker.js — 마지막으로 돌린 `npm test` 가 실패했습니다 —
2462
- 그 앞이 통과했어도 지금 상태를 증명하지 못합니다.
2463
- ```
2464
-
2465
- 바꾼 것을 늘어놓는 일은 `/diff` 도 합니다. 여기서만 하는 것은 **증명 안 된 것을
2466
- 증명 안 됐다고 말하는 것**입니다. 셋을 거릅니다 —
2467
-
2468
- - 고쳐 놓고 아무것도 안 돌렸으면 아무것도 증명되지 않았습니다
2469
- - 검사가 빨간데 돌리기는 했다고 초록으로 치면 **빨간 검사를 증거로 내미는** 셈입니다
2470
- - 고치기 **전에** 돌린 검사는 고친 것을 증명하지 못합니다 — "아까 돌렸으니 됐다" 가
2471
- 제일 흔한 자기기만입니다
2472
-
2473
- 빌드가 통과하고 그 **뒤에** 검사가 깨졌으면, 앞의 초록은 증거가 아닙니다. 마지막에
2474
- 돌린 것이 빨간데 확인됐을 리가 없습니다.
2475
-
2476
- `/evidence 파일이름` 이면 `.deel/증거/` 아래에 마크다운으로 남깁니다. 화면은
2477
- 스크롤로 사라지고, 검토는 나중에 다른 사람이 합니다.
2478
-
2479
- #### 4. 터미널을 하나 더 띄우게 하던 것 — `deel acp`
2480
-
2481
- 개발자는 하루 종일 IDE 안에 있습니다. 창을 옮겨 다녀야 하는 도구는 두 주쯤 뒤에
2482
- 안 씁니다. 반입 심사를 통과한 판이 아무도 안 쓰는 판이 되는 것이 제일 아까운
2483
- 결말입니다.
2484
-
2485
- **ACP**(Agent Client Protocol)를 지킵니다. 에디터 설정에 `deel acp` 한 줄이면
2486
- Zed · JetBrains · Neovim · Emacs 가 **저쪽을 한 줄도 안 고치고** 붙습니다.
2487
-
2488
- 붙이는 일은 관을 잇는 것이 아니라 **에디터가 무엇을 보여 줄 수 있게 하는가** 입니다.
2489
- 갈래·자리·상태는 안 줘도 규격에 안 걸려서, 대충 붙인 구현은 죄다 안 줍니다 —
2490
- 그러면 도구가 전부 똑같은 회색 점이고, 고친 파일을 눌러도 안 열립니다.
2491
-
2492
- 승인 창도 그대로 나갑니다. deel 의 안전망이 에디터 제 창으로 뜨고, "앞으로 묻지
2493
- 않기" 도 그 세션 동안 기억합니다. 못 물어보는 클라이언트에서는 **실행하지 않습니다** —
2494
- "물어볼 수 없으면 마음대로 한다" 가 되면 안 됩니다.
2495
-
2496
- **의존성은 그대로 0 입니다.** 줄 단위 JSON-RPC 2.0 이 전부라 SDK 가 필요 없습니다.
2497
-
2498
- #### 5. 심사 서류가 사람만 읽을 수 있던 것 — `deel sbom`
2499
-
2500
- 2026년 4월 20일 전자금융감독규정 시행세칙 개정으로 금융권 망분리 예외가
2501
- 열렸습니다. 그 문 앞에서 요구되는 서류는 사람이 읽는 글이 아닙니다 — 보안팀은
2502
- SBOM 을 **스캐너에 먹여** 취약점 목록을 뽑고, 운영팀은 감사 사양을 보고 SIEM
2503
- 수집 규칙을 짭니다.
2504
-
2505
- 이제 `deel pack` 이 세 장을 냅니다.
2506
-
2507
- | | |
893
+ | 판 | 무엇이 바뀌었나 |
2508
894
  |---|---|
2509
- | `반입심사서.txt` | 전과 같은, 사람이 읽는 |
2510
- | `sbom.cdx.json` | CycloneDX 1.5. 파일마다 부품 하나에 SHA-256. **의존성은 배열로 명시** 적어 낸 것과 없는 것은 다릅니다 |
2511
- | `심사명세.json` | 통신 목록(갈래마다 언제·어디로·무엇이·막는법·소스 자리) · 감사기록 사양 · 파일 해시 |
2512
-
2513
- 소스를 훑어 만듭니다. 감사 사양만은 손으로 적혀 있어서, **그것이 진짜
2514
- 기록과 어긋나지 않는지를 검사가 매번 대조합니다** — 어긋난 심사 서류는 없느니만
2515
- 못하고, 담당자가 한 번 틀린 것을 발견하면 나머지도 안 믿습니다.
2516
-
2517
- #### 6. `env` 한 번이면 열쇠가 대화에도 디스크에도 남던 것
2518
-
2519
- 사람이 열쇠를 붙여 넣는 일은 드뭅니다. 새는 자리는 거의 항상 명령 출력입니다 —
2520
- `env` · `git remote -v` · `curl -v` · 검사 실패 로그. 그 글은 모델에게 실려 가고,
2521
- **동시에** `.deel/sessions/*.jsonl` 로 디스크에 적힙니다. 한 번 새면 여러 벌이
2522
- 됩니다.
2523
-
2524
- 도구 결과가 대화로 들어가는 **한 자리**에서 가립니다. 사설키 블록 · OpenAI ·
2525
- Anthropic · GitHub · Slack · AWS · Google · JWT · 주소에 박힌 열쇠 ·
2526
- `Authorization` 계열 헤더 · 이름이 `…KEY`/`…TOKEN`/`…SECRET`/`…PASSWORD` 인
2527
- 환경변수. 설정에 든 게이트웨이 열쇠는 모양과 상관없이 지웁니다 — 그건 짐작이
2528
- 아니라 아는 값이니까요.
2529
-
2530
- **파일 내용은 일부러 안 가립니다.** `.env` 를 가리면 모델이 가려진 글을 보고
2531
- 되돌려 써서, 진짜 열쇠가 있던 자리에 표가 적힙니다 — 비밀을 지키려다 사람의
2532
- 열쇠를 우리 손으로 지우는 셈입니다. 그래서 파일 쪽은 가리는 대신 알립니다.
2533
-
2534
- <br>
2535
-
2536
- 검사 2,578 → **2,860개** · 54/54 파일. 지난 판들은 [태그](https://github.com/jysvai/deel-local-cli/tags)에서 봅니다.
2537
-
2538
- </details>
2539
-
2540
- <details>
2541
- <summary><b>▸ 1.2.0 — 대화가 끊기지 않게</b> · 여섯 자리가 어떻게 바뀌었나</summary>
2542
-
2543
- <br>
2544
-
2545
- | | 전 | 후 |
2546
- |---|---|---|
2547
- | 이어받기 | 도구를 부르다 끊긴 대화는 **다시 안 열렸다** | 짝 안 맞는 호출을 걷어내고 연다 |
2548
- | 토큰 셈 | 어림잡은 채로 끝까지 갔다 | 서버 실제값에 맞춰 간다 |
2549
- | 자리 비우기 | 49턴이면 요약이 왔다 | **102턴**까지 간다 |
2550
- | 곁가지 | 본줄기 컨텍스트에 그대로 쌓였다 | 딴 갈래에서 |
2551
- | 어제 알아낸 것 | 끄면 사라졌다 | 다음에 켤 때 넘어온다 |
2552
- | 답 화면 | `**굵게**` 가 글자로 보였다 | 그려진다 |
2553
-
2554
- <br>
2555
-
2556
- #### 1. 도구를 부르다 끊긴 대화가 다시 안 열리던 것
2557
-
2558
- 도구를 부르던 중에 창을 닫거나 <kbd>Ctrl</kbd>+<kbd>C</kbd> 로 끊으면, 적어 둔 대화에 **부름은 있고 결과가 없는 자리**가 남습니다. 다음에 `--resume` 으로 열면 서버가 그 짝을 문제 삼아 400 을 돌려줍니다 — 대화는 멀쩡히 적혀 있는데 이어서 갈 수가 없었습니다.
2559
-
2560
- 이제 열기 전에 짝을 맞춰 봅니다. 결과 없는 부름은 버리고, 부모 없는 결과도 버리고, **모델이 한 말은 남깁니다.**
2561
-
2562
- ```
2563
- $ deel --resume 20260826-140217
2564
-
2565
- ✓ 20260826-140217 — 메시지 48개를 이어 받았습니다.
2566
- 중단된 도구 호출 2개를 걷어냈습니다 — 그때 하던 일은 다시 시켜 주세요.
2567
- ```
2568
-
2569
- #### 2. 남은 자리를 잘못 알던 것
2570
-
2571
- 토큰 수는 글자 수로 어림잡습니다. 그런데 한국어·코드·JSON 이 섞이면 그 어림이 실제와 어긋나서, 자리가 남았는데 일찍 접거나 없는데 안 접어 서버가 거절했습니다.
2572
-
2573
- 이제 서버가 답마다 알려 주는 **실제값과 견줘 배수를 고쳐 갑니다.** `/context` 맨 아래에 한 줄로 뜹니다.
2574
-
2575
- ```
2576
- 서버가 알려 준 실제값에 맞춰 +12% 보정했습니다 (7번 재봄).
2577
- ```
2578
-
2579
- 이 배수는 모델별로 남아서 **다음에 켤 때 그 값으로 시작합니다.** 처음부터 다시 재지 않습니다.
2580
-
2581
- #### 3. 요약이 너무 일찍 오던 것
2582
-
2583
- 창의 80% 가 차면 앞 대화를 요약으로 접습니다. 요약은 **되돌릴 수 없고**, 판단의 근거였던 파일 내용이 통째로 사라집니다.
2584
-
2585
- 그 전에 한 단계를 넣었습니다. 55% 에서 **오래된 도구 결과만** 먼저 접습니다 — 최근 4개는 안 건드립니다. 모델이 한 말과 사람이 한 말도 하나도 안 건드립니다.
2586
-
2587
- ```
2588
- ◲ 오래된 도구 결과 6개를 접었습니다 (2,148 토큰을 비움)
2589
- ```
2590
-
2591
- 접힌 자리에는 무엇이었는지가 남습니다.
2592
-
2593
- ```
2594
- (접힘) Read(src/runner.js) — 61줄. 자리를 비우려고 내용을 접었습니다. 필요하면 다시 읽으세요.
2595
- ```
2596
-
2597
- 같은 대화를 흘려보내며 재 봤습니다 — 요약이 오는 시점이 **49턴 → 102턴, 2.1배** 늦춰집니다.
2598
-
2599
- #### 4. 곁가지가 본줄기를 더럽히던 것
2600
-
2601
- "이것만 잠깐 봐 줘" 한 마디가 본줄기 컨텍스트에 그대로 쌓입니다. 확인이 끝나도 그 말은 안 없어집니다.
2602
-
2603
- ```
2604
- /thread new 로그확인
2605
- ⑂ 로그확인 갈래로 왔습니다. 빈 대화입니다
2606
- 본줄기로 돌아가려면 /thread 1
2607
- ```
2608
-
2609
- `fork` 로 갈라 나오면 여기까지 오간 말을 물려받습니다. 갈래끼리 **나뉘는 것은 오간 말·토큰·할 일**이고, **같이 쓰는 것은 연결·되돌리기·감사기록**입니다 — 갈래에서 고친 파일도 `/undo` 로 그대로 되돌아갑니다. 갈래가 둘 이상일 때만 상태줄에 `⑂` 가 뜹니다.
2610
-
2611
- #### 5. 어제 알아낸 것이 오늘 또 사라지던 것
2612
-
2613
- `pnpm` 이 이 PC 에 없다는 걸 알아내도 끄면 사라졌습니다. 내일 또 부르고, 또 실패하고, 또 우회합니다.
2614
-
2615
- ```
2616
- /learned
2617
- ── 겪어 본 것 ──────────────────────────────────────
2618
-
2619
- 이 폴더에서 돌려 본 명령
2620
- ✓ npm test 됨 12 · 안 됨 0
2621
- ✗ pnpm 됨 0 · 안 됨 3
2622
-
2623
- 이 모델에 대해 qwen2.5-coder:7b
2624
- 같이 걸어 본 걸음 86
2625
- 인자가 잘림 14 (16%)
2626
- 토큰 추정 보정 ×1.12
2627
-
2628
- 이 중 프롬프트에 실리는 것
2629
- - 여기서 되는 명령: `npm test`
2630
- - 이 PC 에서 안 되는 명령(다시 부르지 마라): `pnpm`
2631
- ```
2632
-
2633
- **학습이 아닙니다.** 모델을 고치지도, 대화를 쌓아 두지도 않습니다 — 그러면 컨텍스트만 먹습니다. 세어 두기만 하고, **두 번 이상 겪은 것만**, 다 합쳐 **220토큰 안에서** 넘깁니다. 한 번 겪은 것은 우연일 수 있고, 우연을 사실처럼 적으면 모델이 되는 길을 두고 우회합니다.
2634
-
2635
- 되는 명령은 폴더(`.deel/배운것.json`)에, 모델 버릇은 설정 폴더에 따로 둡니다. 그래서 **폴더를 옮겨도 모델에 대해 알아낸 것은 따라옵니다.** `/learned 지우기` 로 언제든 비웁니다.
2636
-
2637
- #### 6. 답이 글자 그대로 보이던 것
2638
-
2639
- 모델은 마크다운으로 말하는데 화면은 그걸 몰라서, 별표와 백틱과 우물정자가 글에 섞여 나왔습니다. 무엇이 제목이고 무엇이 코드인지 사람이 머릿속에서 다시 읽어야 했습니다.
2640
-
2641
- ```
2642
- 전 후
2643
- ▌ ## 고친 것 ▌ ▍ 고친 것
2644
- ▌ **src/runner.js** 의 `console.log` ▌ src/runner.js 의 console.log
2645
- ▌ - [ ] 남은 것: `src/worker.js` ▌ ☐ 남은 것: src/worker.js
2646
- ▌ ```js ▌ ┌──────────────── js
2647
- ▌ log.info('시작', { id }) ▌ │ log.info('시작', { id })
2648
- ▌ |---|---| ▌ ┼────────┼─────────┼
2649
- ```
2650
-
2651
- 답은 토막토막 흘러오므로 **줄이 끝나야** 그릴 수 있습니다. 그런데 문단 하나가 통째로 한 줄이면 몇 초 동안 화면이 멈춘 것처럼 보입니다 — 그래서 한 줄이 화면 폭을 넘게 길어지면 거기까지를 **날것 그대로 흘려보냅니다.** 모양보다 '살아 있다' 가 먼저입니다.
2652
-
2653
- <br>
2654
-
2655
- 검사 2,532 → **2,578개** · 48/48 파일. 지난 판들은 [태그](https://github.com/jysvai/deel-local-cli/tags)에서 봅니다.
895
+ | **[1.4.2](docs/ko/releases.md#142)** | 1.4.1 보안 수정 전에 나갔다 — 그걸 바로잡는 판 |
896
+ | [1.4.1](docs/ko/releases.md#141) | 기능 없이, 실제로 찾은 것만 고친다윈도우 abort·ReDoS·XSS |
897
+ | [1.4.0](docs/ko/releases.md#140) | deel 얼굴을 갖고, 영어로도 말하고, 뜻까지 본다 열한 자리 |
898
+ | [1.3.0](docs/ko/releases.md#130) | 말 대신 증거, 터미널 대신 에디터 — 여섯 자리 |
899
+ | [1.2.0](docs/ko/releases.md#120) | 대화가 끊기지 않게 여섯 자리 |
2656
900
 
2657
- </details>
901
+ 무엇이 왜 바뀌었는지는 **[릴리스 노트](docs/ko/releases.md)** 에 있습니다.
2658
902
 
2659
903
  ---
2660
904