deel-local-cli 1.15.0 → 1.15.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.ko.md CHANGED
@@ -14,13 +14,13 @@
14
14
  <br>
15
15
 
16
16
  [![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)
17
- [![downloads](https://img.shields.io/npm/dt/deel-local-cli?label=downloads&color=1a7f37)](https://www.npmjs.com/package/deel-local-cli)
17
+ [![downloads](https://img.shields.io/npm/dm/deel-local-cli?label=downloads&color=1a7f37)](https://www.npmjs.com/package/deel-local-cli)
18
18
  [![node](https://img.shields.io/node/v/deel-local-cli?logo=nodedotjs&logoColor=white&label=node&color=5FA04E)](https://nodejs.org)
19
19
  [![license](https://img.shields.io/npm/l/deel-local-cli?label=license&color=0969da)](LICENSE)
20
20
 
21
21
  [![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)
22
22
  [![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)
23
- [![tests](https://img.shields.io/badge/tests-7%2C095%20passing-1a7f37?logo=checkmarx&logoColor=white)](docs/ko/develop.md)
23
+ [![tests](https://img.shields.io/badge/tests-7%2C152%20passing-1a7f37?logo=checkmarx&logoColor=white)](docs/ko/develop.md)
24
24
 
25
25
  [![dependencies](https://img.shields.io/badge/dependencies-0-1a7f37)](https://www.npmjs.com/package/deel-local-cli?activeTab=dependencies)
26
26
  [![ESM](https://img.shields.io/badge/ESM-Node%2020%2B-5FA04E?logo=javascript&logoColor=white)](package.json)
@@ -267,7 +267,7 @@ deel --offline
267
267
  무엇이 어디로 갈 수 있는지는 켤 때 화면 맨 위에 늘 적혀 있습니다.
268
268
 
269
269
  ```
270
- deel 1.15.0 ⌂ 이 안
270
+ deel 1.15.1 ⌂ 이 안
271
271
  보냄 이 컴퓨터 안 127.0.0.1:11434 ← 여기 말고는 어디로도 안 갑니다
272
272
  ```
273
273
 
@@ -1087,7 +1087,7 @@ deel sbom --only sbom # SBOM 한 장만
1087
1087
  ## 개발
1088
1088
 
1089
1089
  ```bash
1090
- npm test 전체 검증 (7,144항목 — 몇몇은 터미널에 따라 갈립니다)
1090
+ npm test 전체 검증 (7,152항목 — 몇몇은 터미널에 따라 갈립니다)
1091
1091
  npm run coverage 검사가 소스의 어디를 밟았는지
1092
1092
  npm run verify 반입·통신 검증만
1093
1093
  npm run bench 편집 성공률 측정
@@ -1144,7 +1144,7 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
1144
1144
  | `exitcode` · `doorparity` | 7 · 7 | 화면에 적은 종료코드 표가 진짜인가 · 문 **네 개**가 같은 것을 주는가 |
1145
1145
  | `no-bundle` | 21 | 배포 묶음에 남의 것이 안 섞였는가 · 검사 파일 위생 |
1146
1146
  | `edit-bench` | 20건 | 편집 성공률 |
1147
- | `mutate` | 어긋 10개 | **검사가 정말 지키는가** — 지켜야 할 줄을 일부러 어긋내고 빨개지는지 본다 |
1147
+ | `mutate` | 어긋 11개 | **검사가 정말 지키는가** — 지켜야 할 줄을 일부러 어긋내고 빨개지는지 본다 |
1148
1148
 
1149
1149
  > **자세히** — 어디를 밟았는지 · 폴더 구조
1150
1150
  >
@@ -1156,6 +1156,7 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
1156
1156
 
1157
1157
  | 판 | 무엇이 바뀌었나 |
1158
1158
  |---|---|
1159
+ | **[1.15.1](docs/ko/releases/1.15.md#1151)** | 에디터에 우리가 어떻게 인증받는지 말합니다 — ACP 레지스트리 등재 조건 |
1159
1160
  | **[1.15.0](docs/ko/releases/1.15.md#1150)** | 같은 것을 두 번 하지 않습니다 — 프리픽스 캐시를 깨던 조용히 비싼 아홉 자리 |
1160
1161
  | **[1.14.0](docs/ko/releases/1.14.md#1140)** | 적어 둔 것이 참인지 기계가 대신 봅니다 — 초록불과 「깨면 잡힌다」 는 다릅니다 |
1161
1162
  | [1.13.1](docs/ko/releases/1.13.md#1131) | 올라간 물건이 소스와 달랐습니다 — 148개 중 47개가 CRLF 로 나갔습니다 |
package/README.md CHANGED
@@ -14,13 +14,13 @@ Vendor APIs connect too — **only when you say so**
14
14
  <br>
15
15
 
16
16
  [![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)
17
- [![downloads](https://img.shields.io/npm/dt/deel-local-cli?label=downloads&color=1a7f37)](https://www.npmjs.com/package/deel-local-cli)
17
+ [![downloads](https://img.shields.io/npm/dm/deel-local-cli?label=downloads&color=1a7f37)](https://www.npmjs.com/package/deel-local-cli)
18
18
  [![node](https://img.shields.io/node/v/deel-local-cli?logo=nodedotjs&logoColor=white&label=node&color=5FA04E)](https://nodejs.org)
19
19
  [![license](https://img.shields.io/npm/l/deel-local-cli?label=license&color=0969da)](LICENSE)
20
20
 
21
21
  [![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)
22
22
  [![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)
23
- [![tests](https://img.shields.io/badge/tests-7%2C095%20passing-1a7f37?logo=checkmarx&logoColor=white)](docs/en/develop.md)
23
+ [![tests](https://img.shields.io/badge/tests-7%2C152%20passing-1a7f37?logo=checkmarx&logoColor=white)](docs/en/develop.md)
24
24
 
25
25
  [![dependencies](https://img.shields.io/badge/dependencies-0-1a7f37)](https://www.npmjs.com/package/deel-local-cli?activeTab=dependencies)
26
26
  [![ESM](https://img.shields.io/badge/ESM-Node%2020%2B-5FA04E?logo=javascript&logoColor=white)](package.json)
@@ -338,7 +338,7 @@ deel --offline
338
338
  The destination is printed at the top of every session:
339
339
 
340
340
  ```
341
- deel 1.15.0 ⌂ inside
341
+ deel 1.15.1 ⌂ inside
342
342
  Sends to this machine 127.0.0.1:11434 ← nowhere else
343
343
  ```
344
344
 
@@ -1158,7 +1158,7 @@ Stored in `~/.deel/config.json`. A `.deel/config.json` in the project folder tak
1158
1158
  ## Development
1159
1159
 
1160
1160
  ```bash
1161
- npm test Full suite (7,144 checks; a few are TTY-dependent)
1161
+ npm test Full suite (7,152 checks; a few are TTY-dependent)
1162
1162
  npm run coverage Which lines the tests actually execute
1163
1163
  npm run verify Import + network checks only
1164
1164
  npm run bench Edit success rate
@@ -1201,7 +1201,7 @@ so one run tells you everything.
1201
1201
  | `exitcode` · `doorparity` | 7 · 7 | The printed exit-code table is real · all **four** doors hand out the same thing |
1202
1202
  | `no-bundle` | 21 | Nothing foreign in the published package; test-file hygiene |
1203
1203
  | `edit-bench` | 20 cases | Edit success rate |
1204
- | `mutate` | 10 mutants | **Whether the tests actually guard** — break the line on purpose, check it turns red |
1204
+ | `mutate` | 11 mutants | **Whether the tests actually guard** — break the line on purpose, check it turns red |
1205
1205
 
1206
1206
  > **More** — Coverage · Layout
1207
1207
  >
@@ -1213,6 +1213,7 @@ so one run tells you everything.
1213
1213
 
1214
1214
  | Version | What changed |
1215
1215
  |---|---|
1216
+ | **[1.15.1](docs/en/releases/1.15.md#1151)** | Telling the editor how we get authenticated — ACP Registry listing requirement |
1216
1217
  | **[1.15.0](docs/en/releases/1.15.md#1150)** | Stop doing the same thing twice — nine quietly expensive places that broke the prefix cache |
1217
1218
  | **[1.14.0](docs/en/releases/1.14.md#1140)** | A machine now checks that what we wrote down is true — green does not mean guarded |
1218
1219
  | [1.13.1](docs/en/releases/1.13.md#1131) | What shipped was not what the source said — 47 of 148 files went out with CRLF line endings |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deel-local-cli",
3
- "version": "1.15.0",
3
+ "version": "1.15.1",
4
4
  "description": "A coding-agent CLI that runs on local models and private gateways. Zero dependencies, Node 20+.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,6 +33,16 @@ export const 오류번호 = {
33
33
  모르는방법: -32601,
34
34
  잘못된인자: -32602,
35
35
  안쪽오류: -32603,
36
+ /*
37
+ * 인증이 있어야 한다.
38
+ *
39
+ * 다른 번호와 달리 이건 JSON-RPC 가 아니라 **ACP 가 정한 번호**다
40
+ * (규격의 ErrorCode::AuthRequired). 에디터는 이 번호를 봐야 initialize
41
+ * 때 받아 둔 authMethods 를 꺼내 「인증」 단추를 그린다. 잘못된인자로
42
+ * 답하면 그냥 빨간 글씨가 뜨고, 사람은 이게 설정 문제인지 버그인지
43
+ * 모른다 — 할 수 있는 안내를 안 한 셈이다.
44
+ */
45
+ 인증필요: -32000,
36
46
  };
37
47
 
38
48
  /**
@@ -228,3 +238,16 @@ export function 잘못된인자오류(무엇) {
228
238
  e.code = 오류번호.잘못된인자;
229
239
  return e;
230
240
  }
241
+
242
+ /**
243
+ * 아직 인증(연결 설정)이 안 됐다고 답하게 하는 오류.
244
+ *
245
+ * 글은 그대로 사람에게 보인다. 그러니 **무엇을 하면 되는지**까지 적는다 —
246
+ * 번호만 맞고 글이 「인증이 필요합니다」 면 어디서 무엇을 해야 하는지 여전히
247
+ * 모른다.
248
+ */
249
+ export function 인증필요오류(무엇) {
250
+ const e = new Error(무엇);
251
+ e.code = 오류번호.인증필요;
252
+ return e;
253
+ }
package/src/acp/serve.js CHANGED
@@ -54,7 +54,7 @@ import { 못박기 } from '../agent/pins.js';
54
54
  import { route } from '../agent/route.js';
55
55
  import { ORDER as 모드순서, get as getWork, normalize as 모드정리 } from '../agent/modes.js';
56
56
  import { 모두끝내기 as 일감모두끝내기 } from '../tools/jobs.js';
57
- import { 연결, 줄나누기, 모르는방법오류, 잘못된인자오류 } from './jsonrpc.js';
57
+ import { 연결, 줄나누기, 모르는방법오류, 잘못된인자오류, 인증필요오류 } from './jsonrpc.js';
58
58
  import { 도구시작, 도구끝남, 도구이름표, 도구갈래, 도구자리, 멈춘까닭, 프롬프트글, 되살린것 } from './map.js';
59
59
 
60
60
  /** 우리가 말하는 규격 판. 정수 하나이고, 깨지는 변경에서만 올라간다. */
@@ -87,6 +87,35 @@ export async function acp(opts = {}) {
87
87
  const 내보내기 = 표준출력잠그기();
88
88
  const 로그 = (s) => { try { process.stderr.write(`[acp] ${s}\n`); } catch { /* 여기서 또 터지면 할 게 없다 */ } };
89
89
 
90
+ /*
91
+ * ── 우리가 어떻게 인증받는지 ────────────────────────────────────────────
92
+ *
93
+ * ACP 의 `initialize` 응답에는 authMethods 자리가 있다. 여기를 비워 두면
94
+ * 에디터는 「이 에이전트는 인증이 필요 없다」 로 읽는다. 그런데 deel 은
95
+ * 연결 정보가 없으면 아무 일도 못 한다.
96
+ *
97
+ * 그래서 처음 붙인 사람은 이렇게 됐다 — 에디터에서 deel 을 고르고, 대화를
98
+ * 열고, 「저장된 연결이 없습니다」 를 받는다. 화면만 봐서는 이게 인증
99
+ * 문제인지 버그인지 모른다.
100
+ *
101
+ * 규격에는 그 자리가 있다. **Terminal Auth** — 「터미널에서 이 인자로 나를
102
+ * 다시 띄우면 설정이 끝난다」 고 말하는 방법이다. 그리고 deel 은 그 명령이
103
+ * 이미 있다: `deel setup`. 없는 것을 만드는 게 아니라 **있는 것을 말하는**
104
+ * 일이었다.
105
+ *
106
+ * args 가 진짜 도는 명령인지는 검사가 지킨다(test/acp.test.js 의 5-11).
107
+ * 여기가 틀리면 에디터가 사람에게 없는 명령을 치라고 시킨다.
108
+ */
109
+ const 인증방법들 = [
110
+ {
111
+ id: 'terminal-setup',
112
+ name: 'Run `deel setup` in a terminal',
113
+ description: '로컬 런타임(Ollama · LM Studio · llama.cpp)을 고르거나 게이트웨이 주소와 열쇠를 넣습니다.',
114
+ type: 'terminal',
115
+ args: ['setup'],
116
+ },
117
+ ];
118
+
90
119
  /** 세션 하나. 에디터의 탭 하나에 해당한다. */
91
120
  const 방들 = new Map();
92
121
 
@@ -127,7 +156,16 @@ export async function acp(opts = {}) {
127
156
  const cfg = load();
128
157
  const prof = activeProfile(cfg);
129
158
  if (!prof) {
130
- throw 잘못된인자오류('저장된 연결이 없습니다. 터미널에서 `deel setup` 을 먼저 실행하세요.');
159
+ /*
160
+ * 잘못된인자가 아니라 **인증필요**다.
161
+ *
162
+ * 사람이 인자를 잘못 준 것이 아니라 아직 설정을 안 한 것이다. 그 둘은
163
+ * 에디터에서 하는 일이 다르다 — 인증필요(-32000)를 받으면 위 initialize
164
+ * 에서 받아 둔 authMethods 를 꺼내 「터미널에서 설정하기」 를 띄우고,
165
+ * 잘못된인자면 그냥 빨간 글씨만 뜬다. 고칠 방법이 있는데 안 알려 주는
166
+ * 것이 제일 나쁘다.
167
+ */
168
+ throw 인증필요오류('저장된 연결이 없습니다. 터미널에서 `deel setup` 을 먼저 실행하세요.');
131
169
  }
132
170
 
133
171
  /*
@@ -729,13 +767,32 @@ export async function acp(opts = {}) {
729
767
  mcpCapabilities: { http: false, sse: false },
730
768
  },
731
769
  agentInfo: { name: 'deel', title: 'deel (로컬 모델 코딩 에이전트)', version: 판번호() },
732
- authMethods: [], // 연결 설정은 `deel setup` 이 맡는다
770
+ authMethods: 인증방법들,
733
771
  };
734
772
  }
735
773
 
736
- case 'authenticate':
737
- // 인증 방법을 하나도 안 걸었으니 여기 올 일이 없다. 와도 조용히 넘긴다.
774
+ /*
775
+ * 에디터가 「인증」 눌렀다.
776
+ *
777
+ * 우리 인증은 터미널에서 도는 것이라(위 인증방법들 머리말), 여기서
778
+ * 우리가 할 일은 없다 — 에디터가 우리를 `deel setup` 으로 다시 띄우고,
779
+ * 사람이 거기서 마치고, 그 다음에 이 프로세스가 다시 연결된다.
780
+ *
781
+ * 그래도 **끝났는지는 확인해 준다.** 사람이 설정을 안 마치고 창을
782
+ * 닫았는데 여기서 성공이라고 답하면, 에디터는 인증이 끝난 줄 알고 대화를
783
+ * 열고, 그 다음 한마디에서야 같은 오류가 난다. 한 번 더 돌아가는 셈이다.
784
+ */
785
+ case 'authenticate': {
786
+ const 골라온것 = String(인자?.methodId ?? '');
787
+ if (골라온것 && !인증방법들.some((m) => m.id === 골라온것)) {
788
+ throw 잘못된인자오류(`모르는 인증 방법입니다: ${골라온것}`);
789
+ }
790
+ if (!activeProfile(load())) {
791
+ throw 인증필요오류('아직 설정이 안 끝났습니다. 터미널에서 `deel setup` 을 마치고 다시 시도하세요.');
792
+ }
793
+ 로그('설정이 확인됐습니다.');
738
794
  return {};
795
+ }
739
796
 
740
797
  case 'session/new': {
741
798
  const 방 = await 방만들기(인자);