deel-local-cli 1.17.6 → 1.17.7
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 +37 -3
- package/README.md +39 -3
- package/package.json +1 -1
- package/src/tools/verify.js +20 -21
- package/src/tools//355/231/225/354/235/270/353/262/225.js +127 -0
package/README.ko.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/test.yml)
|
|
22
22
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/codeql.yml)
|
|
23
|
-
[](docs/ko/develop.md)
|
|
24
24
|
|
|
25
25
|
[](https://www.npmjs.com/package/deel-local-cli?activeTab=dependencies)
|
|
26
26
|
[](package.json)
|
|
@@ -53,6 +53,39 @@
|
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
+
### 그래서 뭐가 다른데 — 나란히 세워 재 봤습니다
|
|
57
|
+
|
|
58
|
+
같은 프로젝트, 같은 일, 같은 모델(AWS Bedrock · Claude Opus 5). 양쪽 다 공동
|
|
59
|
+
편집기의 **데이터 손실 결함을 찾아 고치게** 했습니다.
|
|
60
|
+
|
|
61
|
+
| | Claude CLI | deel |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| 관측 비용 | $7.90 | **$6.57** · -16.8% |
|
|
64
|
+
| 소요 시간 | 38분 00초 | **36분 59초** · -2.7% |
|
|
65
|
+
| 종합 상대지수 | 97.9% | 98.5% |
|
|
66
|
+
| 곁들인 것 | `claude-token-saver` (별도 npm) | **없음 — 자체 기능만** |
|
|
67
|
+
|
|
68
|
+
한 줄로 줄이면: **품질은 사실상 동급인데, 절감 패키지를 안 붙이고도 더 쌌습니다.**
|
|
69
|
+
|
|
70
|
+
<picture>
|
|
71
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jysvai/deel-local-cli/main/docs/assets/benchmark-dark.svg">
|
|
72
|
+
<img alt="Claude CLI 와 deel 벤치마크 — 항목별 상대지수" src="https://raw.githubusercontent.com/jysvai/deel-local-cli/main/docs/assets/benchmark-light.svg" width="900">
|
|
73
|
+
</picture>
|
|
74
|
+
|
|
75
|
+
두 실행은 같은 버그를 두 번 찾은 게 아닙니다. **서로 다른 실패 경로**를 하나씩
|
|
76
|
+
없앴습니다 — 한쪽은 한글 조합 중 기준값이 오염되는 길, 한쪽은 `await` 사이에
|
|
77
|
+
입력이 덮이는 경쟁 상태(TOCTOU). 둘 다 고치기 전에 재현했고, 최소 수정 뒤
|
|
78
|
+
회귀 검증까지 갔습니다.
|
|
79
|
+
|
|
80
|
+
> **이 자료로 말할 수 없는 것도 적어 둡니다.** 표본이 2회입니다. Claude 쪽에는
|
|
81
|
+
> 외부 절감 패키지가 붙어 있어서 **엔진 자체의 효율 차이라고 단정할 수 없습니다.**
|
|
82
|
+
> 그리고 **전체 회귀 범위는 Claude 가 넓었습니다** — 우리가 진 항목이고, 그것이
|
|
83
|
+
> 1.17.7 에서 `Verify` 를 고치게 만들었습니다(확인 방법을 하나가 아니라 전부 찾습니다).
|
|
84
|
+
|
|
85
|
+
→ [전체 기록과 방법론](docs/ko/benchmark.md) · [원본 PDF](pdf/cli_benchmark_anonymized_v4.pdf)
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
56
89
|
## 목차
|
|
57
90
|
|
|
58
91
|
- [왜 만들었나](#왜-만들었나)
|
|
@@ -268,7 +301,7 @@ deel --offline
|
|
|
268
301
|
무엇이 어디로 갈 수 있는지는 켤 때 화면 맨 위에 늘 적혀 있습니다.
|
|
269
302
|
|
|
270
303
|
```
|
|
271
|
-
deel 1.17.
|
|
304
|
+
deel 1.17.7 ⌂ 이 안
|
|
272
305
|
보냄 이 컴퓨터 안 127.0.0.1:11434 ← 여기 말고는 어디로도 안 갑니다
|
|
273
306
|
```
|
|
274
307
|
|
|
@@ -1185,7 +1218,7 @@ deel stats # 이 폴더에서 실제로 무엇을 했나 (.de
|
|
|
1185
1218
|
## 개발
|
|
1186
1219
|
|
|
1187
1220
|
```bash
|
|
1188
|
-
npm test 전체 검증 (8,
|
|
1221
|
+
npm test 전체 검증 (8,032항목 — 몇몇은 터미널에 따라 갈립니다)
|
|
1189
1222
|
npm run coverage 검사가 소스의 어디를 밟았는지
|
|
1190
1223
|
npm run verify 반입·통신 검증만
|
|
1191
1224
|
npm run bench 편집 성공률 측정
|
|
@@ -1254,6 +1287,7 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
|
|
|
1254
1287
|
|
|
1255
1288
|
| 판 | 무엇이 바뀌었나 |
|
|
1256
1289
|
|---|---|
|
|
1290
|
+
| [1.17.7](docs/ko/releases/1.17.md#1177) | 나란히 세워 재 봤고, 진 항목을 고쳤습니다 |
|
|
1257
1291
|
| [1.17.6](docs/ko/releases/1.17.md#1176) | 살아 있다는 신호만 오고 내용이 안 오면, 여태 영원히 기다렸습니다 |
|
|
1258
1292
|
| [1.17.5](docs/ko/releases/1.17.md#1175) | 한 턴 안에서 단계가 일을 따라갑니다 — 그리고 읽기 도구 넷이 여태 줄을 서 있었습니다 |
|
|
1259
1293
|
| [1.17.4](docs/ko/releases/1.17.md#1174) | 같은 요청을 한 번 더 보내던 자리들 — 그리고 배운 것이 스스로를 봉인하던 자리 |
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Vendor APIs connect too — **only when you say so**
|
|
|
20
20
|
|
|
21
21
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/test.yml)
|
|
22
22
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/codeql.yml)
|
|
23
|
-
[](docs/en/develop.md)
|
|
24
24
|
|
|
25
25
|
[](https://www.npmjs.com/package/deel-local-cli?activeTab=dependencies)
|
|
26
26
|
[](package.json)
|
|
@@ -60,6 +60,41 @@ summary are what deel actually printed.
|
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
63
|
+
### So what is actually different — we put them side by side
|
|
64
|
+
|
|
65
|
+
Same project, same job, same model (Claude Opus 5 via AWS Bedrock). Both were asked to
|
|
66
|
+
**find and fix a data-loss defect** in a collaborative editor.
|
|
67
|
+
|
|
68
|
+
| | Claude CLI | deel |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| Observed cost | $7.90 | **$6.57** · -16.8% |
|
|
71
|
+
| Wall time | 38m 00s | **36m 59s** · -2.7% |
|
|
72
|
+
| Composite index | 97.9% | 98.5% |
|
|
73
|
+
| Extras | `claude-token-saver` (separate npm) | **none — built-in only** |
|
|
74
|
+
|
|
75
|
+
In one line: **quality came out effectively equal, and it cost less without bolting on
|
|
76
|
+
a savings package.**
|
|
77
|
+
|
|
78
|
+
<picture>
|
|
79
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jysvai/deel-local-cli/main/docs/assets/benchmark-dark.svg">
|
|
80
|
+
<img alt="Claude CLI and deel benchmark — relative index by dimension" src="https://raw.githubusercontent.com/jysvai/deel-local-cli/main/docs/assets/benchmark-light.svg" width="900">
|
|
81
|
+
</picture>
|
|
82
|
+
|
|
83
|
+
The two runs did not find the same bug twice. Each removed **a different failure
|
|
84
|
+
path** — one where the base value is corrupted mid-IME-composition, one a TOCTOU race
|
|
85
|
+
where input is overwritten across an `await`. Both reproduced the defect before fixing
|
|
86
|
+
it, and carried the minimal fix through regression verification.
|
|
87
|
+
|
|
88
|
+
> **What this data cannot say, stated plainly.** The sample is two runs. The Claude
|
|
89
|
+
> side had an external savings package attached, so **the gap cannot be attributed to
|
|
90
|
+
> engine efficiency.** And **Claude covered more regression scope** — that is the row
|
|
91
|
+
> we lost, and it is what made 1.17.7 fix `Verify` to find every way a project checks
|
|
92
|
+
> itself, not just one.
|
|
93
|
+
|
|
94
|
+
→ [Full record and methodology](docs/en/benchmark.md) · [source PDF](pdf/cli_benchmark_anonymized_v4.pdf)
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
63
98
|
## 60 seconds
|
|
64
99
|
|
|
65
100
|
```bash
|
|
@@ -339,7 +374,7 @@ deel --offline
|
|
|
339
374
|
The destination is printed at the top of every session:
|
|
340
375
|
|
|
341
376
|
```
|
|
342
|
-
deel 1.17.
|
|
377
|
+
deel 1.17.7 ⌂ inside
|
|
343
378
|
Sends to this machine 127.0.0.1:11434 ← nowhere else
|
|
344
379
|
```
|
|
345
380
|
|
|
@@ -1258,7 +1293,7 @@ Stored in `~/.deel/config.json`. A `.deel/config.json` in the project folder tak
|
|
|
1258
1293
|
## Development
|
|
1259
1294
|
|
|
1260
1295
|
```bash
|
|
1261
|
-
npm test Full suite (8,
|
|
1296
|
+
npm test Full suite (8,032 checks; a few are TTY-dependent)
|
|
1262
1297
|
npm run coverage Which lines the tests actually execute
|
|
1263
1298
|
npm run verify Import + network checks only
|
|
1264
1299
|
npm run bench Edit success rate
|
|
@@ -1313,6 +1348,7 @@ so one run tells you everything.
|
|
|
1313
1348
|
|
|
1314
1349
|
| Version | What changed |
|
|
1315
1350
|
|---|---|
|
|
1351
|
+
| [1.17.7](docs/en/releases/1.17.md#1177) | We measured it side by side, and fixed the row we lost |
|
|
1316
1352
|
| [1.17.6](docs/en/releases/1.17.md#1176) | Only keep-alive and no content used to mean waiting forever |
|
|
1317
1353
|
| [1.17.5](docs/en/releases/1.17.md#1175) | The phase now follows the work inside a turn — and four read tools had been queueing up |
|
|
1318
1354
|
| [1.17.4](docs/en/releases/1.17.md#1174) | The places that sent the same request twice — and where what it learned sealed itself in |
|
package/package.json
CHANGED
package/src/tools/verify.js
CHANGED
|
@@ -30,9 +30,10 @@
|
|
|
30
30
|
*/
|
|
31
31
|
import { existsSync, statSync, readFileSync } from 'node:fs';
|
|
32
32
|
import { execFile } from 'node:child_process';
|
|
33
|
-
import { extname, dirname,
|
|
33
|
+
import { extname, dirname, resolve } from 'node:path';
|
|
34
34
|
import { walk, SKIP_DIRS, 내부살림 } from './fsutil.js';
|
|
35
35
|
import { 건너뜀말 } from './ignore.js';
|
|
36
|
+
import { 확인법들 } from './확인법.js';
|
|
36
37
|
import { decode, looksBinary } from './encoding.js';
|
|
37
38
|
import { checkCommand } from '../safety/guard.js';
|
|
38
39
|
import { 말 } from '../i18n/index.js';
|
|
@@ -315,10 +316,24 @@ export const VERIFY_TOOL = {
|
|
|
315
316
|
* 검사가 걸려 있기 때문이다. 이 도구가 몰래 돌리면 strict 모드에서
|
|
316
317
|
* "물어보고 실행한다" 는 약속이 이 자리에서만 깨진다.
|
|
317
318
|
*/
|
|
318
|
-
const
|
|
319
|
-
if (
|
|
319
|
+
const 확인들 = 확인법들(뿌리);
|
|
320
|
+
if (확인들.length) {
|
|
320
321
|
줄.push('');
|
|
321
|
-
|
|
322
|
+
if (확인들.length === 1) {
|
|
323
|
+
줄.push(`이 프로젝트에는 ${확인들[0].명령} 가 있습니다. 진짜로 도는지 보려면 Bash 로 돌려라.`);
|
|
324
|
+
} else {
|
|
325
|
+
/*
|
|
326
|
+
* **하나만 알려 주면 하나만 돈다.**
|
|
327
|
+
*
|
|
328
|
+
* 벤치마크에서 진 자리가 여기다 — 검사가 셋인 프로젝트에서 우리는
|
|
329
|
+
* 하나만 알려 줬고, 그래서 하나만 돌았고, 회귀 범위가 좁았다.
|
|
330
|
+
* 고른 하나가 아니라 **찾은 전부**를 준다. 무엇을 돌릴지는 모델이
|
|
331
|
+
* 정하되, 있는 줄도 몰라서 못 도는 일은 없어야 한다.
|
|
332
|
+
*/
|
|
333
|
+
줄.push(`이 프로젝트의 확인 방법은 ${확인들.length}가지입니다. 고친 곳과 닿는 것은 **전부** Bash 로 돌려라 —`);
|
|
334
|
+
for (const { 명령, 어디서 } of 확인들) 줄.push(` ${명령} (${어디서})`);
|
|
335
|
+
줄.push('하나만 돌리고 "회귀 검증했다" 고 말하지 마라. 안 돌린 것은 안 돌렸다고 적어라.');
|
|
336
|
+
}
|
|
322
337
|
}
|
|
323
338
|
|
|
324
339
|
const 다됐나 = !탈난것.length;
|
|
@@ -339,20 +354,4 @@ export const VERIFY_TOOL = {
|
|
|
339
354
|
},
|
|
340
355
|
};
|
|
341
356
|
|
|
342
|
-
|
|
343
|
-
* 이 프로젝트가 스스로 정해 둔 확인 방법.
|
|
344
|
-
*
|
|
345
|
-
* package.json 에 test 가 있으면 그것이 답이다. 없는 것을 지어내지는 않는다 —
|
|
346
|
-
* 없으면 null 이고, 그러면 파일별 확인만 한 것이 전부다.
|
|
347
|
-
* 돌리지는 않는다. 알려 주기만 한다 (위 머리말 참고).
|
|
348
|
-
*/
|
|
349
|
-
function 프로젝트확인법(뿌리) {
|
|
350
|
-
const pkg = join(뿌리, 'package.json');
|
|
351
|
-
if (!existsSync(pkg)) return null;
|
|
352
|
-
try {
|
|
353
|
-
const j = JSON.parse(readFileSync(pkg, 'utf8'));
|
|
354
|
-
if (j.scripts?.test) return 'npm test';
|
|
355
|
-
if (j.scripts?.build) return 'npm run build';
|
|
356
|
-
} catch { /* 망가진 package.json 은 아래 파일 확인에서 잡힌다 */ }
|
|
357
|
-
return null;
|
|
358
|
-
}
|
|
357
|
+
// 확인 방법 찾기는 tools/확인법.js 로 옮겼다 — 찾을 자리가 늘어 파일이 무거워졌다.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 이 프로젝트가 스스로 정해 둔 **확인 방법들**을 찾는다.
|
|
3
|
+
*
|
|
4
|
+
* ── 왜 따로 나왔나 ─────────────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* 벤치마크에서 진 자리다(`docs/ko/benchmark.md`).
|
|
7
|
+
*
|
|
8
|
+
* 같은 프로젝트에 같은 일을 시킨 비교에서, 품질은 거의 동급이었는데 **전체
|
|
9
|
+
* 회귀 범위**만 우리가 낮았다(85% 대 100%). 까닭은 단순했다 — 그 프로젝트의
|
|
10
|
+
* 검사는 `scripts/` 밑의 독립 실행 파일 셋이었는데, 우리는 `package.json` 의
|
|
11
|
+
* `test` 하나만 보고 있었다. 못 본 검사는 안 돌고, 안 돈 검사는 회귀를 못 잡는다.
|
|
12
|
+
*
|
|
13
|
+
* 고칠 자리가 「더 열심히 하라」 가 아니라 **「무엇이 있는지 알려 주기」** 였다.
|
|
14
|
+
* 시킴말에 "확인해라" 는 이미 있었다. 확인할 **길**의 목록이 없었을 뿐이다.
|
|
15
|
+
*
|
|
16
|
+
* ── 여기서도 안 돌린다 ──────────────────────────────────────────────────
|
|
17
|
+
*
|
|
18
|
+
* 찾기만 하고 **실행은 안 한다.** 검사 스크립트는 무슨 짓이든 할 수 있어서,
|
|
19
|
+
* 그걸 돌리는 길은 Bash 하나여야 한다 — 승인 관문과 안전 검사가 거기에만
|
|
20
|
+
* 걸려 있다. 이 파일이 몰래 돌리면 strict 모드의 약속이 여기서만 깨진다.
|
|
21
|
+
*
|
|
22
|
+
* ── 없는 것은 지어내지 않는다 ───────────────────────────────────────────
|
|
23
|
+
*
|
|
24
|
+
* 있을 법한 이름을 추측해서 채우지 않는다. **파일이나 스크립트로 실재하는
|
|
25
|
+
* 것만** 담는다. 없는 명령을 알려 주면 모델이 그걸 부르고, 실패를 받고, 또
|
|
26
|
+
* 부른다 — 걸음만 태우고 사람은 왜 헤매는지 모른다.
|
|
27
|
+
*/
|
|
28
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
29
|
+
import { join } from 'node:path';
|
|
30
|
+
|
|
31
|
+
/** 한 판에 몇 개까지 알려 줄까. 스무 개를 늘어놓으면 그건 목록이 아니라 소음이다. */
|
|
32
|
+
export const 최대 = 8;
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
* package.json 의 스크립트 가운데 **확인에 해당하는 것**.
|
|
36
|
+
*
|
|
37
|
+
* `test` 만 보던 것을 넓힌다. 요즘 저장소는 확인을 여러 칸에 나눠 둔다 —
|
|
38
|
+
* 형 검사와 린트와 e2e 가 따로 있고, 그 중 하나만 돌리면 나머지는 안 돈다.
|
|
39
|
+
*
|
|
40
|
+
* `build` 는 확인이 아니지만 **깨지면 아무것도 안 되는 것**이라 맨 뒤에 붙인다.
|
|
41
|
+
*/
|
|
42
|
+
const 확인스크립트 = /^(test|tests|check|checks|lint|typecheck|types?|verify|qa|e2e|spec|coverage)(:|$)/i;
|
|
43
|
+
const 뒤에붙일것 = /^build(:|$)/i;
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* 독립 실행 검사 파일이 사는 자리와 이름.
|
|
47
|
+
*
|
|
48
|
+
* `package.json` 에 안 걸리는 검사가 여기 산다. 벤치마크에서 놓친 것이 정확히
|
|
49
|
+
* 이 모양이었다 — `scripts/qa-collaboration.js` 처럼 npm 스크립트로 등록되지
|
|
50
|
+
* 않은 채 `node` 로 직접 도는 파일들.
|
|
51
|
+
*/
|
|
52
|
+
const 볼폴더 = ['scripts', 'script', 'test', 'tests', 'qa', 'tools', 'bin'];
|
|
53
|
+
const 검사파일 = /^(qa|test|tests|check|verify|e2e|spec|bench)[-_.].+\.(m?js|cjs|ts|py|sh)$/i;
|
|
54
|
+
const 부르는법 = { '.js': 'node', '.mjs': 'node', '.cjs': 'node', '.ts': 'node', '.py': 'python', '.sh': 'sh' };
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
* 다른 생태계의 관례.
|
|
58
|
+
*
|
|
59
|
+
* 자리(표식 파일)가 실재할 때만 담는다. Makefile 은 `test:` 칸이 진짜로
|
|
60
|
+
* 있을 때만 — 없는데 `make test` 를 알려 주면 그건 지어낸 것이다.
|
|
61
|
+
*/
|
|
62
|
+
function 생태계(뿌리, 담기) {
|
|
63
|
+
const 있나 = (f) => existsSync(join(뿌리, f));
|
|
64
|
+
if (있나('Cargo.toml')) 담기('cargo test', 'Cargo.toml');
|
|
65
|
+
if (있나('go.mod')) 담기('go test ./...', 'go.mod');
|
|
66
|
+
if (있나('pytest.ini') || 있나('tox.ini')) 담기('pytest', 'pytest 설정');
|
|
67
|
+
else if ((있나('pyproject.toml') || 있나('setup.cfg')) && (있나('tests') || 있나('test'))) 담기('pytest', 'pyproject + tests/');
|
|
68
|
+
if (있나('go.work')) 담기('go test ./...', 'go.work');
|
|
69
|
+
for (const 이름 of ['Makefile', 'makefile']) {
|
|
70
|
+
if (!있나(이름)) continue;
|
|
71
|
+
try {
|
|
72
|
+
// 진짜로 `test:` 칸이 있을 때만. 있을 법하다고 넣지 않는다.
|
|
73
|
+
if (/^\.?test\s*:/m.test(readFileSync(join(뿌리, 이름), 'utf8'))) 담기('make test', 이름);
|
|
74
|
+
} catch { /* 못 읽으면 없는 것으로 둔다 */ }
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 확인 방법들을 찾아 돌려준다.
|
|
81
|
+
*
|
|
82
|
+
* @param {string} 뿌리 프로젝트 뿌리 경로
|
|
83
|
+
* @returns {{명령: string, 어디서: string}[]} 실재하는 것만. 없으면 빈 배열.
|
|
84
|
+
*/
|
|
85
|
+
export function 확인법들(뿌리) {
|
|
86
|
+
const 나온것 = [];
|
|
87
|
+
const 본명령 = new Set();
|
|
88
|
+
const 담기 = (명령, 어디서) => {
|
|
89
|
+
if (본명령.has(명령) || 나온것.length >= 최대) return;
|
|
90
|
+
본명령.add(명령);
|
|
91
|
+
나온것.push({ 명령, 어디서 });
|
|
92
|
+
};
|
|
93
|
+
const 나중에 = [];
|
|
94
|
+
|
|
95
|
+
const pkg = join(뿌리, 'package.json');
|
|
96
|
+
if (existsSync(pkg)) {
|
|
97
|
+
try {
|
|
98
|
+
const j = JSON.parse(readFileSync(pkg, 'utf8'));
|
|
99
|
+
for (const 이름 of Object.keys(j.scripts ?? {})) {
|
|
100
|
+
// `npm test` 는 관례가 있고 나머지는 `npm run` 을 붙여야 돈다.
|
|
101
|
+
const 명령 = 이름 === 'test' ? 'npm test' : `npm run ${이름}`;
|
|
102
|
+
if (확인스크립트.test(이름)) 담기(명령, 'package.json');
|
|
103
|
+
else if (뒤에붙일것.test(이름)) 나중에.push([명령, 'package.json']);
|
|
104
|
+
}
|
|
105
|
+
} catch { /* 망가진 package.json 은 파일별 확인에서 잡힌다 */ }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (const 폴더 of 볼폴더) {
|
|
109
|
+
const 곳 = join(뿌리, 폴더);
|
|
110
|
+
let 목록;
|
|
111
|
+
try {
|
|
112
|
+
if (!statSync(곳).isDirectory()) continue;
|
|
113
|
+
목록 = readdirSync(곳);
|
|
114
|
+
} catch { continue; }
|
|
115
|
+
for (const 이름 of 목록.sort()) {
|
|
116
|
+
if (!검사파일.test(이름)) continue;
|
|
117
|
+
const 끝 = 이름.slice(이름.lastIndexOf('.')).toLowerCase();
|
|
118
|
+
const 앞 = 부르는법[끝];
|
|
119
|
+
if (!앞) continue;
|
|
120
|
+
담기(`${앞} ${폴더}/${이름}`, `${폴더}/`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
생태계(뿌리, 담기);
|
|
125
|
+
for (const [명령, 어디서] of 나중에) 담기(명령, 어디서);
|
|
126
|
+
return 나온것;
|
|
127
|
+
}
|