deel-local-cli 1.0.2 → 1.1.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.
Files changed (37) hide show
  1. package/README.en.md +381 -7
  2. package/README.md +493 -9
  3. package/bin/deel.js +266 -234
  4. package/package.json +4 -3
  5. package/src/agent/budget.js +167 -0
  6. package/src/agent/grade.js +207 -0
  7. package/src/agent/loop.js +778 -574
  8. package/src/agent/modes.js +109 -28
  9. package/src/agent/project.js +171 -0
  10. package/src/agent/route.js +55 -3
  11. package/src/agent/session.js +131 -12
  12. package/src/backend/http.js +41 -4
  13. package/src/backend/learn.js +46 -4
  14. package/src/commands.js +178 -3
  15. package/src/oneshot.js +390 -327
  16. package/src/preview/serve.js +326 -0
  17. package/src/repl.js +1184 -887
  18. package/src/safety/audit.js +3 -1
  19. package/src/skills/builtin//352/262/200/354/202/254-/353/250/274/354/240/200/SKILL.md +64 -0
  20. package/src/skills/builtin//352/271/212/354/235/264/354/236/210/352/262/214-/353/247/214/353/223/244/352/270/260/SKILL.md +78 -0
  21. package/src/skills/builtin//353/201/235/352/271/214/354/247/200-/355/225/230/352/270/260/SKILL.md +65 -0
  22. package/src/skills/builtin//354/212/244/354/212/244/353/241/234-/352/262/200/355/206/240/SKILL.md +74 -0
  23. package/src/skills/builtin//354/260/224/353/237/254/353/263/264/352/270/260/SKILL.md +59 -0
  24. package/src/skills/builtin//354/260/250/352/267/274/354/260/250/352/267/274-/353/224/224/353/262/204/352/271/205/SKILL.md +73 -0
  25. package/src/skills/builtin//354/275/224/353/223/234-/354/244/204/354/235/264/352/270/260/SKILL.md +66 -0
  26. package/src/skills/discover.js +17 -2
  27. package/src/tools/index.js +500 -107
  28. package/src/tools/jobs.js +670 -0
  29. package/src/tools/outline.js +331 -0
  30. package/src/tools/task.js +153 -0
  31. package/src/tools/verify.js +306 -0
  32. package/src/tools/webfetch.js +152 -16
  33. package/src/ui/inputbox.js +102 -7
  34. package/src/ui/motion.js +212 -0
  35. package/src/ui/screen.js +51 -3
  36. package/src/ui/status.js +69 -4
  37. package/src/ui/working.js +8 -1
@@ -20,7 +20,9 @@ export class Audit {
20
20
  tool(name, args, result) {
21
21
  return this.write('tool', {
22
22
  tool: name,
23
- target: args?.file_path ?? args?.path ?? args?.pattern ?? args?.command ?? null,
23
+ // 목적 하위 작업(Task)이 쓰는 이름이다. 이게 없으면 감사기록에
24
+ // '하위 작업을 돌렸다' 만 남고 **무엇을** 돌렸는지가 안 남는다.
25
+ target: args?.file_path ?? args?.path ?? args?.pattern ?? args?.command ?? args?.목적 ?? null,
24
26
  ok: !result?.error,
25
27
  note: result?.error ?? result?.summary ?? null,
26
28
  });
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: 검사-먼저
3
+ description: 고치기 전에 실패하는 검사부터 만들기. 결함·새 기능에 쓴다
4
+ ---
5
+
6
+ # 검사 먼저
7
+
8
+ ## 왜 있나
9
+
10
+ "고쳤습니다" 는 증명이 아니다. 무엇이 어떻게 틀렸는지를 **먼저 못 박아
11
+ 두지 않으면**, 고친 뒤에 통과하는 것이 원래부터 통과하던 것인지 알 수 없다.
12
+
13
+ 실제로 겪는 순서는 이렇다. 검사를 안 만들고 고친다 → 통과한다 → 사실은
14
+ 그 자리를 한 번도 안 밟는 검사였다 → 결함이 그대로 나간다.
15
+
16
+ ## 순서
17
+
18
+ ### 1. 빨강 — 실패하는 것을 먼저 만든다
19
+
20
+ - 지금 코드로 **반드시 실패해야 한다.** 통과하면 그 검사는 아무것도 안 잰다
21
+ - 실패하는 것을 눈으로 확인한다. 이 단계를 건너뛰면 아무 의미가 없다
22
+ - 이름은 무엇이 잘못됐는지 말해야 한다.
23
+ `'끝내기가 돌아왔으면 이미 죽어 있다'` 가 `'jobs test 3'` 보다 낫다
24
+
25
+ ### 2. 초록 — 통과할 만큼만 고친다
26
+
27
+ - 통과에 필요한 것만. 김에 다른 것까지 손보지 않는다
28
+ - 통과하면 멈춘다
29
+
30
+ ### 3. 다시 본다
31
+
32
+ - 전체 검사를 돌린다. 다른 것이 깨졌으면 아직 안 끝난 것이다
33
+ - 검사가 우연히 통과하는 것은 아닌지 본다 — **일부러 코드를 되돌려 보고
34
+ 다시 실패하는지** 확인하면 확실하다
35
+
36
+ ## 무엇을 재야 하나
37
+
38
+ **말이 아니라 결과물을 잰다.**
39
+
40
+ - ✗ 화면에 "만들었습니다" 가 떴다
41
+ - ✓ 파일이 실제로 생겼고 내용이 맞다
42
+
43
+ - ✗ 함수가 오류를 안 던졌다
44
+ - ✓ 프로세스가 정말 죽었다 (커 가던 표시 파일이 더 이상 안 자란다)
45
+
46
+ ### 안 되어야 하는 것도 같은 무게로 잰다
47
+
48
+ 되는 것만 재면 절반이다. 승인 창이 **떠야 할 때** 뜨는 것만 재고 **안 떠야
49
+ 할 때** 안 뜨는 것을 안 재면, 아무 때나 뜨는 것을 못 잡는다.
50
+
51
+ ## 검사가 못 미더울 때
52
+
53
+ - 검사가 바깥 도구(tar·unzip·python)에 기대면, 그게 없는 자리에서 조용히
54
+ 건너뛰어진다. **건너뛴 것을 반드시 화면에 남긴다**
55
+ - 서버를 띄우는 검사는 **포트 0**(커널이 빈 포트를 준다)으로 띄운다.
56
+ 고정 포트는 남의 것을 뺏는다
57
+ - 임시 폴더는 매번 새로 만들고 끝나면 지운다. 진짜 설정 폴더를 안 건드린다
58
+
59
+ ## 하지 말 것
60
+
61
+ - 고친 뒤에 검사 만들기 — 그 검사는 십중팔구 그냥 통과한다
62
+ - 실패를 안 보고 넘어가기
63
+ - 검사를 통과시키려고 검사를 고치기 (원인을 봐야 한다)
64
+ - 재기 어렵다고 안 재기 — 못 재면 **못 잰다고 적어 둔다**
@@ -0,0 +1,78 @@
1
+ ---
2
+ name: 깊이있게-만들기
3
+ description: 만들라는 요청에 최소치만 내지 않기. 고도화·제대로·보고용·선포용에 쓴다
4
+ ---
5
+
6
+ # 깊이있게 만들기
7
+
8
+ ## 언제 쓰나
9
+
10
+ 무엇을 **만들어** 달라는 요청인데, 다음 중 하나라도 걸리면 이걸 쓴다.
11
+
12
+ - "고도화", "제대로", "잘", "본격적으로", "정식으로"
13
+ - 보는 사람이 있다 — 선포용, 보고용, 발표용, 제출용, 대외용
14
+ - 만들 것의 개수를 안 정해 줬다 ("자료들", "내용들", "문서 묶음")
15
+
16
+ ## 왜 있나
17
+
18
+ 시킨 것의 **최소치**만 내고 끝내는 일이 잦다. "AX 비전 선포 자료 만들어줘"
19
+ 에 파일 세 개를 만들고 멈추는 식이다. 문법으로는 틀린 게 없다. 그런데
20
+ 그걸 받아서 실제로 선포를 할 수는 없다.
21
+
22
+ 받는 사람이 **그걸 그대로 쓸 수 있는가**가 기준이다. 더 채워야 한다면
23
+ 아직 안 끝난 것이다.
24
+
25
+ ## 어떻게
26
+
27
+ ### 1. 요청의 무게부터 잰다
28
+
29
+ 무게는 낱말이 아니라 **쓰임**에서 나온다.
30
+
31
+ | 쓰임 | 무게 | 대략 |
32
+ |---|---|---|
33
+ | 나 혼자 보려고 | 가벼움 | 파일 1~2개, 뼈대만 |
34
+ | 팀 안에서 돌려 볼 것 | 보통 | 3~6개, 읽는 순서 + 각 문서가 자립 |
35
+ | 밖에 나가거나 위로 올라갈 것 | 무거움 | 6개 이상, 요약본 · 근거 · 실행안 · 반론 대비까지 |
36
+
37
+ 애매하면 **한 단계 무겁게** 잡는다. 넘치는 것은 지우면 되지만, 모자라면
38
+ 사람이 처음부터 다시 시켜야 한다.
39
+
40
+ ### 2. 무엇이 빠졌는지 먼저 센다
41
+
42
+ 만들기 전에 이 목록을 훑는다. 무거운 일일수록 아래쪽까지 내려간다.
43
+
44
+ - **한 장 요약** — 바쁜 사람이 이것만 봐도 되는가
45
+ - **왜 지금인가** — 배경·현황·안 하면 생기는 일
46
+ - **무엇을** — 목표를 확인 가능한 문장으로. "개선한다" 는 목표가 아니다
47
+ - **어떻게** — 단계와 시기. 단계마다 끝났는지 알 방법
48
+ - **누가** — 역할·책임. 이름 자리가 비어도 자리는 만들어 둔다
49
+ - **얼마나** — 사람·돈·기간. 모르면 "확인 필요" 라고 적는다
50
+ - **어떻게 잴 것인가** — 지표와 목표치
51
+ - **무엇이 걸리는가** — 위험·반대 의견과 그에 대한 답
52
+ - **읽는 순서** — 문서가 셋을 넘으면 README 가 있어야 한다
53
+
54
+ ### 3. 각 문서가 혼자 서게 만든다
55
+
56
+ 문서 하나를 떼어 내도 그것만으로 말이 되어야 한다. 제목, 한 줄 요약,
57
+ 본문, 그리고 다음에 볼 것. **표와 목록으로 끝내지 않는다** — 표는 근거를
58
+ 못 담는다. 표 밑에 왜 그런지 한두 줄을 붙인다.
59
+
60
+ ### 4. 모르는 것은 지어내지 않는다
61
+
62
+ 숫자·날짜·조직 이름·예산은 확인이 필요한 것들이다. 지어내면 그 문서는
63
+ 쓸 수 없게 된다. `> 확인 필요: …` 로 눈에 띄게 남긴다. 빈 자리는 흠이
64
+ 아니지만 틀린 값은 흠이다.
65
+
66
+ ### 5. 끝내기 전에 되묻는다
67
+
68
+ - 받는 사람이 이걸 그대로 쓸 수 있나
69
+ - 표만 있고 근거가 없는 자리는 없나
70
+ - 지어낸 숫자는 없나
71
+ - 셋 이상인데 읽는 순서가 없지는 않나
72
+
73
+ ## 하지 말 것
74
+
75
+ - 개수를 안 정해 줬다고 최소로 만들기
76
+ - 목차만 만들고 본문을 비워 두기
77
+ - 길이로 때우기 — 같은 말을 늘려 쓰는 것은 깊이가 아니다
78
+ - 사람이 준 자료를 안 읽고 일반론으로 채우기
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: 끝까지-하기
3
+ description: 시킨 것이 여러 조각일 때 쉬운 것만 하고 멈추지 않기. 빼먹은 것은 말한다
4
+ ---
5
+
6
+ # 끝까지 하기
7
+
8
+ ## 왜 있나
9
+
10
+ 한 번에 여러 가지를 시키면 앞의 한둘만 하고 "다 했습니다" 로 끝나는 일이
11
+ 잦다. 나머지는 조용히 사라진다. 사람은 다 된 줄 알고 넘어갔다가 나중에
12
+ 발견한다 — 그때는 이미 그걸 믿고 다음 일을 시작한 뒤다.
13
+
14
+ **빼먹는 것 자체보다, 빼먹은 줄 모르게 하는 것이 나쁘다.**
15
+
16
+ ## 어떻게
17
+
18
+ ### 1. 조각부터 다 센다
19
+
20
+ 시작하기 전에 요청을 조각으로 끊는다. '그리고', '또', '~도', 쉼표,
21
+ 줄바꿈이 경계다. 중간에 끼워 넣은 말도 조각이다.
22
+
23
+ 셋을 넘으면 **TodoWrite 로 적는다.** 머리로 들고 있으면 반드시 샌다.
24
+
25
+ ### 2. 순서를 정한다
26
+
27
+ - 남의 답을 기다려야 하는 것부터 던져 놓는다
28
+ - 서로 안 엮인 것은 한 번에 처리한다
29
+ - 막힐 것 같은 것을 **뒤로 미루지 않는다.** 미루면 시간이 없어 못 하게 되고,
30
+ 그게 정확히 조용히 빠지는 자리다
31
+
32
+ ### 3. 하나씩 끝내고 표시한다
33
+
34
+ - 끝난 것은 바로 done 으로 바꾼다
35
+ - 다음으로 넘어가기 전에 **그 조각이 정말 끝났는지** 본다. 절반쯤 해 놓고
36
+ 넘어간 것이 나중에 다 됐다고 세어진다
37
+
38
+ ### 4. 막히면 나머지를 먼저 끝낸다
39
+
40
+ 한 조각이 막혔다고 전부 멈추지 않는다.
41
+
42
+ - 그것에 안 엮인 나머지를 **전부** 끝낸다
43
+ - 막힌 것은 무엇이 왜 막혔는지 적는다
44
+ - 범위를 줄이는 것은 사람이 정할 일이다. 혼자 줄이고 다 했다고 하지 않는다
45
+
46
+ ### 5. 끝에 반드시 셈을 맞춘다
47
+
48
+ 원래 요청을 다시 읽고 조각과 하나씩 맞춰 본다.
49
+
50
+ 시킨 것 5개 · 끝낸 것 4개 · 못 한 것 1개 (왜: …)
51
+
52
+ 숫자가 안 맞으면 아직 안 끝난 것이다.
53
+
54
+ ## 말할 때
55
+
56
+ - 다 했으면 짧게 "다 했다" 고 한다
57
+ - 못 한 것이 있으면 **먼저** 말한다. 잘된 것 뒤에 붙이면 안 읽힌다
58
+ - 나중에 하겠다는 것도 안 한 것이다. 그렇게 적는다
59
+
60
+ ## 하지 말 것
61
+
62
+ - 쉬운 것만 하고 "다 했습니다"
63
+ - 조각을 세지 않고 시작하기
64
+ - 막혔다고 통째로 멈추기
65
+ - 조용히 범위 줄이기 — 줄였으면 줄였다고 말한다
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: 스스로-검토
3
+ description: 다 됐다고 말하기 전에 스스로 훑고 못 잰 것까지 말하기. 끝냈을 때·커밋 전에 쓴다
4
+ ---
5
+
6
+ # 스스로 검토
7
+
8
+ ## 왜 있나
9
+
10
+ "다 됐습니다" 는 제일 하기 쉬운 말이고, 제일 자주 틀리는 말이다.
11
+ 사람이 그 말을 믿고 넘어간 뒤에 깨진 것을 발견하면, 그 다음부터는
12
+ 아무 말도 못 믿게 된다.
13
+
14
+ **검토는 잘한 것을 확인하는 자리가 아니라 안 한 것을 찾는 자리다.**
15
+
16
+ ## 훑는 차례
17
+
18
+ ### 1. 시킨 것을 다 했나
19
+
20
+ - 요청을 다시 읽는다. 조각이 여럿이면 하나씩 짚는다
21
+ - 조용히 줄인 것은 없나. 줄였으면 **줄였다고 말한다** — 그건 사람이 정할 일이다
22
+ - 못 한 것이 있으면 무엇을 왜 못 했는지 적는다
23
+
24
+ ### 2. 돌려 봤나
25
+
26
+ - 화면·숫자로 확인했나, 아니면 될 것 같아서 말하는 건가
27
+ - 검사가 있으면 돌렸나. **전체**를 돌렸나
28
+ - 고친 자리를 실제로 밟는 검사인가
29
+
30
+ ### 3. 안 되어야 하는 것도 봤나
31
+
32
+ 되는 길만 보면 절반이다.
33
+
34
+ - 빈 값·없는 파일·권한 없음·끊긴 연결
35
+ - 한글·공백 든 경로·CRLF
36
+ - 다른 셸(PowerShell·cmd)·다른 OS 에서도 같은가
37
+
38
+ ### 4. 조용히 실패하는 자리는 없나
39
+
40
+ - 삼킨 오류(`catch {}`)
41
+ - 못 찾으면 기본값으로 넘어가는 자리 — 그게 맞는 기본값인가
42
+ - 조건 때문에 통째로 건너뛰어지는 검사
43
+
44
+ ### 5. 남은 것을 치웠나
45
+
46
+ - 임시 파일·디버그 출력·주석 처리한 코드
47
+ - 띄운 프로세스·열린 포트·안 지운 임시 폴더
48
+
49
+ ### 6. 왜 그랬는지 적었나
50
+
51
+ 겪어서 알게 된 것은 코드에 안 남는다. 다음 사람(과 다음의 나)이 그걸
52
+ 모르면 같은 데서 또 넘어진다. 주석이나 커밋 본문에 남긴다.
53
+
54
+ ## 무엇을 못 쟀는지 말한다
55
+
56
+ 이게 제일 중요하다. **못 잰 것을 안 말하면 사람은 다 쟀다고 읽는다.**
57
+
58
+ - "로컬 모델로는 못 재 봤습니다. 가짜 게이트웨이로만 확인했습니다"
59
+ - "unzip 이 없는 자리에서는 11건을 못 쟀습니다"
60
+ - "인식률은 잴 방법이 없어 그 이유로 결정하지 않았습니다"
61
+
62
+ ## 어떻게 말하나
63
+
64
+ - 됐으면 됐다고 짧게. 에두르지 않는다
65
+ - 안 됐으면 **출력을 붙여** 말한다. "검사가 실패합니다" 만으로는 부족하다
66
+ - 지어낸 숫자를 쓰지 않는다. 안 잰 것은 "안 쟀다" 고 한다
67
+ - 잘못을 길게 뉘우치지 않는다. 무엇이 틀렸고 어떻게 했는지만 적는다
68
+
69
+ ## 하지 말 것
70
+
71
+ - 안 돌려 보고 "될 겁니다"
72
+ - 요청의 일부를 조용히 빼고 "다 했습니다"
73
+ - 실패한 검사를 안 보이는 곳에 두기
74
+ - 못 잰 것을 잰 것처럼 말하기
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: 찔러보기
3
+ description: 되는지 모를 때 시간 정해 작게 찔러 답만 얻고 버리기. 헤매지 않으려고 쓴다
4
+ ---
5
+
6
+ # 찔러보기 (spike)
7
+
8
+ ## 언제 쓰나
9
+
10
+ - 이 방법이 되는지 안 되는지를 모른다
11
+ - 남의 규격·API 가 실제로 무엇을 돌려주는지 모른다
12
+ - 둘 중 어느 쪽이 나은지 재 보지 않고는 못 정하겠다
13
+
14
+ **모르는 채로 본 코드를 짜기 시작하면 안 된다.** 절반쯤 짓고 나서 안 된다는
15
+ 것을 알게 되고, 그때는 되돌리기도 아깝다.
16
+
17
+ ## 어떻게
18
+
19
+ ### 1. 물음을 하나로 좁힌다
20
+
21
+ 답이 **예/아니오** 나 **숫자 하나**로 나와야 한다.
22
+
23
+ - ✗ "이 방식이 괜찮을까"
24
+ - ✓ "이 프록시가 401 을 줄 때 본문에 사람이 읽을 문장이 들어 있나"
25
+ - ✓ "파일 600개짜리 폴더를 훑는 데 몇 ms 걸리나"
26
+
27
+ ### 2. 시간을 먼저 정한다
28
+
29
+ 15분, 30분, 한 시간. 정하고 시작한다. 넘기면 **멈추고 무엇까지 알아냈는지
30
+ 말한다.** 끝이 없는 찌르기는 찌르기가 아니라 헤매는 것이다.
31
+
32
+ ### 3. 제일 더러운 방법으로 짠다
33
+
34
+ - 임시 폴더에 짠다. 본 코드에 안 섞는다
35
+ - 오류 처리·이름·구조 다 신경 안 쓴다
36
+ - 화면에 답만 찍히면 된다
37
+
38
+ ### 4. 답을 적고 **버린다**
39
+
40
+ 찔러 본 코드는 지운다. 남기는 것은 **알아낸 사실 한 줄**이다.
41
+
42
+ "unzip 은 Git Bash PATH 에만 있다. cmd 에는 없고, npm 은 cmd 로 돈다."
43
+ "폴더 600개 훑기 7ms — 켤 때마다 해도 된다."
44
+ "이 모델은 content 가 비고 전부 thinking 으로 간다. 상한이 낮으면 본문이 안 나온다."
45
+
46
+ 그 한 줄이 본 코드의 주석이 되고 결정의 근거가 된다.
47
+
48
+ ## 왜 버리나
49
+
50
+ 찔러 본 코드는 **답을 얻으려고** 짠 것이지 오래 쓰려고 짠 게 아니다.
51
+ 그대로 두면 오류 처리도 없고 이름도 엉망인 것이 본 코드가 된다.
52
+ "어차피 도니까" 로 남긴 것이 나중에 제일 오래 남는다.
53
+
54
+ ## 하지 말 것
55
+
56
+ - 시간을 안 정하고 시작하기
57
+ - 찌르다가 슬그머니 본 구현으로 넘어가기
58
+ - 답을 안 적고 코드만 남기기 — 코드는 무엇을 알아냈는지 말해 주지 않는다
59
+ - 사내망·운영 서버에 대고 찌르기. 가짜를 세워서 찌른다
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: 차근차근-디버깅
3
+ description: 재현→좁히기→원인→고치기→증명. 짐작으로 손대지 않기. 고장·재발에 쓴다
4
+ ---
5
+
6
+ # 차근차근 디버깅
7
+
8
+ ## 왜 있나
9
+
10
+ 안 되는 것을 보면 바로 고치고 싶어진다. 그래서 짐작으로 한 줄 바꾸고
11
+ "이제 될 겁니다" 라고 말하게 된다. 그게 맞을 때도 있는데, **틀렸을 때
12
+ 그걸 알 방법이 없다.** 그리고 틀린 채로 넘어간 것은 반드시 다시 돌아온다.
13
+
14
+ ## 순서
15
+
16
+ ### 1. 재현한다 — 이걸 건너뛰지 않는다
17
+
18
+ 고칠 수 있는 것은 **볼 수 있는 것**뿐이다.
19
+
20
+ - 무엇을 하면 터지는가를 명령 한 줄로 만든다
21
+ - 매번 터지는가, 가끔인가. 가끔이면 몇 번에 한 번인가
22
+ - 못 재현하면 거기서 멈추고 **무엇이 더 필요한지 말한다.** 재현 못 한 채
23
+ 고치는 것은 고치는 게 아니라 바꾸는 것이다
24
+
25
+ ### 2. 좁힌다 — 반씩 자른다
26
+
27
+ 원인을 짐작하지 말고 **범위를 자른다.**
28
+
29
+ - 언제부터 됐나 / 안 됐나 (되던 시점이 있으면 그 사이가 범위다)
30
+ - 되는 입력과 안 되는 입력의 차이는 정확히 무엇인가
31
+ - 절반을 빼면 여전히 터지나
32
+ - 다른 자리(다른 셸·다른 PC·다른 폴더)에서도 터지나
33
+
34
+ 세 번 좁혔는데 범위가 안 줄면 좁히는 방향이 틀린 것이다. 처음으로 돌아간다.
35
+
36
+ ### 3. 원인을 말로 만든다
37
+
38
+ **"A 일 때 B 가 C 를 하므로 D 가 된다"** 꼴로 한 문장이 나와야 한다.
39
+ 안 나오면 아직 원인을 모르는 것이다. 이때 고치면 증상만 덮게 된다.
40
+
41
+ "아마 인코딩 문제일 것" 은 원인이 아니다.
42
+ "파일이 CP949 로 저장돼 있는데 utf8 로 읽어서 앞 두 글자가 깨진다" 가 원인이다.
43
+
44
+ ### 4. 고치기 전에 실패를 못 박는다
45
+
46
+ **터지는 것을 먼저 검사로 만든다.** 지금 실패해야 맞다.
47
+
48
+ - 실패하는 것을 확인한 뒤에 고친다
49
+ - 안 만들면 "고쳤다" 를 증명할 방법이 없고, 다음에 같은 게 돌아와도 모른다
50
+ - 검사를 만들기 어려운 자리면, 최소한 재현 명령과 그 출력을 남긴다
51
+
52
+ ### 5. 고치고 증명한다
53
+
54
+ - 아까 실패하던 것이 통과하는가
55
+ - **다른 것이 안 깨졌는가** — 전체 검사를 돌린다
56
+ - 원인을 지웠는가, 증상을 덮었는가. 덮었으면 그렇다고 말한다
57
+
58
+ ## 겪은 것에서 나온 규칙
59
+
60
+ - **문법이 맞는다고 맞는 게 아니다.** 셸이 `${...}` 를 먹어서 만들어진
61
+ `error: + '…'` 는 `node --check` 를 통과한다. 검사가 잡았다.
62
+ - **같은 코드가 셸에 따라 다르게 돈다.** Git Bash 의 PATH 에만 있는 도구에
63
+ 기댄 검사가 npm(cmd) 에서만 실패했다. "간헐적" 으로 보이면 **무엇이
64
+ 다른지**부터 본다 — 대개 간헐적이 아니다.
65
+ - **조용히 건너뛴 것이 실패보다 나쁘다.** 실패는 눈에 띄지만 건너뛴 것은
66
+ 통과처럼 보인다.
67
+
68
+ ## 하지 말 것
69
+
70
+ - 재현 없이 고치기
71
+ - 한 번에 여러 군데 고치기 — 뭐가 들었는지 알 수 없게 된다
72
+ - 원인을 모른 채 `try/catch` 로 덮기
73
+ - "이제 될 겁니다" — 돌려 보고 말한다
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: 코드-줄이기
3
+ description: 동작은 그대로 두고 읽기 쉽게 줄이기. 정리해달라는 말에 쓴다
4
+ ---
5
+
6
+ # 코드 줄이기
7
+
8
+ ## 규칙 하나
9
+
10
+ **동작을 바꾸지 않는다.** 줄이기와 고치기를 같이 하면, 뭔가 깨졌을 때
11
+ 줄여서 깨진 건지 고치다 깨진 건지 알 수 없다. 둘을 섞지 않는다.
12
+
13
+ 시작하기 전에 검사가 초록인지 본다. 빨강에서 시작하면 줄이는 게 아니라
14
+ 그냥 헤매는 것이다.
15
+
16
+ ## 무엇을 줄이나 — 값이 큰 순서
17
+
18
+ ### 1. 같은 것이 세 군데 이상
19
+
20
+ 두 군데는 놔둔다. 세 번째가 나타나면 묶는다. **두 번에 묶으면** 나중에
21
+ 셋이 서로 다른 방향으로 갈라질 때 억지로 한 틀에 우겨넣게 된다.
22
+
23
+ ### 2. 이름이 하는 일과 다른 것
24
+
25
+ `process()`, `data`, `handle2()`. 이름만 바꿔도 읽는 속도가 달라진다.
26
+ 이름을 못 짓겠으면 그 함수가 두 가지 일을 하고 있는 것이다.
27
+
28
+ ### 3. 세 겹 넘는 중첩
29
+
30
+ - 일찍 돌려보낸다 (`if (없으면) return`)
31
+ - 안쪽 덩어리를 이름 있는 함수로 뺀다
32
+
33
+ ### 4. 죽은 것
34
+
35
+ 안 쓰는 함수·변수·주석 처리된 코드. **지운다.** "나중에 쓸까 봐" 는 이유가
36
+ 못 된다 — 되돌리기가 있다.
37
+
38
+ ### 5. 주석이 코드를 되풀이하는 것
39
+
40
+ ```js
41
+ // i 를 1 늘린다
42
+ i += 1;
43
+ ```
44
+ 지운다. **왜 그렇게 했는지**만 남긴다. 무엇을 하는지는 코드가 말한다.
45
+
46
+ ## 무엇을 안 줄이나
47
+
48
+ - **왜 그런지 적어 둔 주석.** 이건 코드에 안 남는 정보다. 제일 먼저 지워지고
49
+ 제일 아깝다
50
+ - 겪어서 붙은 예외 처리. `// 윈도우 GNU tar 는 'C:\' 를 원격 호스트로 오해한다`
51
+ 같은 것. 이유가 안 적혀 있으면 지우기 전에 왜 있는지부터 찾는다
52
+ - 검사 코드 — 조금 지저분해도 괜찮다. 검사는 읽히는 것보다 **잡는 것**이 일이다
53
+ - 이미 잘 도는 남의 코드
54
+
55
+ ## 끝내기 전에
56
+
57
+ - 검사가 여전히 전부 초록인가
58
+ - 지운 것 중에 **왜 있었는지 모르는 채로** 지운 게 있나. 있으면 되돌린다
59
+ - 줄인 만큼 읽기 쉬워졌나. 짧아지기만 하고 더 어려워졌으면 되돌린다
60
+
61
+ ## 하지 말 것
62
+
63
+ - 줄이면서 기능 고치기
64
+ - 검사가 빨강인 채로 시작하기
65
+ - 한 번에 여러 파일 갈아엎기 — 무엇이 깨졌는지 못 찾는다
66
+ - 짧게 만들려고 한 줄에 우겨넣기. 짧은 것과 읽기 쉬운 것은 다르다
@@ -1,10 +1,20 @@
1
1
  // 스킬·슬래시명령 찾기.
2
- // deel 는 스킬을 품고 다니지 않는다 — 켜질 때 그 PC 를 훑어 있는 것을 쓴다.
3
- // Claude Code 와 같은 형식을 읽으므로, 그쪽으로 쓰인 것이 그대로 먹는다.
2
+ // deel 는 그 PC 를 훑어 있는 것을 쓴다. Claude Code 와 같은 형식을 읽으므로,
3
+ // 그쪽으로 쓰인 것이 그대로 먹는다.
4
+ //
5
+ // **다만 일하는 방법 몇 가지는 품고 다닌다(builtin/).**
6
+ // 전에는 하나도 안 품었다. 그런데 사내에서 새로 받은 PC 에는 ~/.claude/skills 도
7
+ // 플러그인도 없다 — 거기서는 방법론이 0개였고, 모델은 매번 제 나름대로 했다.
8
+ // 시킨 것만 겨우 하고 끝나는 얄팍한 결과가 거기서 나온다.
9
+ // 품고 다니는 것은 **가장 낮은 자리**에 둔다. 같은 이름을 사용자가 만들면 그쪽이 이긴다.
4
10
  import { readdirSync, readFileSync, existsSync, statSync } from 'node:fs';
5
11
  import { join, basename, dirname } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
6
13
  import { homedir } from 'node:os';
7
14
 
15
+ // 이 파일 옆의 builtin/ — 패키지에 같이 실려 나간다(package.json files: src).
16
+ export const 내장자리 = join(dirname(fileURLToPath(import.meta.url)), 'builtin');
17
+
8
18
  // --- YAML 앞머리 읽기 (name, description 만 쓰므로 최소만 구현) -------------
9
19
  export function frontmatter(text) {
10
20
  if (!text.startsWith('---')) return { data: {}, body: text };
@@ -156,6 +166,11 @@ export function discover(root, opts = {}) {
156
166
  const commands = [];
157
167
  const plugins = [];
158
168
 
169
+ // 0) 품고 다니는 것 — 제일 먼저 넣어 제일 낮은 자리를 준다.
170
+ // dedupe 는 나중에 온 것이 이기므로, 사용자·프로젝트가 같은 이름을 만들면 그쪽이 이긴다.
171
+ // 끄고 싶으면 opts.내장 = false (검사에서 이 여섯을 세지 않으려고 쓴다).
172
+ if (opts.내장 !== false) skillsIn(내장자리, 'builtin', null, skills, caps.skills);
173
+
159
174
  // 1) 플러그인
160
175
  // 같은 플러그인이 cache/ 와 marketplaces/ 양쪽에 있을 수 있다.
161
176
  // 이름이 같으면 알맹이가 더 많은 쪽 하나만 쓴다.