leerness 1.9.252 → 1.9.254
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/CHANGELOG.md +64 -0
- package/README.md +3 -3
- package/bin/harness.js +171 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.254 — 2026-05-29 — UR-0019 leerness CLI PATH 자동 등록
|
|
4
|
+
|
|
5
|
+
**🔗 사용자 명시 (UR-0019): "leerness 설치 시 leerness CLI가 PATH를 자동으로 등록될 수 있게 구현". (테스트/디버그는 다음 라운드 참고)**
|
|
6
|
+
|
|
7
|
+
### 배경
|
|
8
|
+
`npm i -g leerness` 설치 후 npm global bin 디렉토리가 PATH에 없으면 `leerness` 명령이 동작하지 않음 (특히 Windows nvm/수동 Node 설치 환경). 설치 직후 자동 감지 + 안전 등록.
|
|
9
|
+
|
|
10
|
+
### 구현 (`leerness path-setup [--apply] [--json]` + install 자동 안내)
|
|
11
|
+
1. **진단 헬퍼 5종**:
|
|
12
|
+
- `_npmGlobalBin()` — `npm prefix -g` 기반 global bin 감지 (Windows=prefix, Unix=prefix/bin, fallback=node dir)
|
|
13
|
+
- `_dirInPath(dir)` — 플랫폼별 정규화(대소문자/구분자/trailing slash) 후 PATH 포함 확인
|
|
14
|
+
- `_leernessResolvable()` — `where`/`which` 로 실제 실행 가능 여부
|
|
15
|
+
- `_pathDiagnose()` — globalBin/inPath/resolvable/shellRc 종합
|
|
16
|
+
- `_registerPath(diag)` — 플랫폼별 안전 등록
|
|
17
|
+
2. **플랫폼별 안전 등록**:
|
|
18
|
+
- **Windows**: PowerShell `[Environment]::SetEnvironmentVariable('PATH', ..., 'User')` — User scope (관리자 권한 불요), `setx`의 1024자 truncation 회피, 멱등(중복 시 EXISTS)
|
|
19
|
+
- **Unix**: shell rc(`.zshrc`/`.bashrc`/`.profile`) 에 `export PATH` 블록 append — 마커(`# >>> leerness PATH`)로 멱등
|
|
20
|
+
3. **안전 원칙** (글로벌 룰: 안정성 > 성능, 엄격 처리):
|
|
21
|
+
- **dry-run 기본** — `--apply` 명시해야 실제 등록
|
|
22
|
+
- **멱등** — 이미 등록/PATH 포함 시 "등록 불필요"
|
|
23
|
+
- **append-only** — 기존 PATH 덮어쓰기 절대 없음
|
|
24
|
+
4. **install 완료 자동 안내**: PATH 미등록 감지 시 `🔗 leerness CLI PATH 미등록` + `path-setup --apply` 안내. opt-out `LEERNESS_NO_PATH_CHECK=1`
|
|
25
|
+
5. **env summary 힌트** + `path` 별칭
|
|
26
|
+
|
|
27
|
+
### 다음 라운드 참고 (사용자 명시)
|
|
28
|
+
- 실제 `--apply` 등록 동작 깊은 테스트/디버그 (Windows User PATH 반영 확인, Unix rc source 후 동작)
|
|
29
|
+
- 신규 셸 세션에서 PATH 반영 검증
|
|
30
|
+
|
|
31
|
+
### stress-v199 — **25/25 PASS · 100%**
|
|
32
|
+
- 1.9.254 (12): VERSION + 헬퍼 5종 + dispatch + Windows PS/Unix rc 등록 + dry-run + install 안내 + 실제 실행(진단/json/별칭/정규화) + env 힌트
|
|
33
|
+
- 성능 (1): cold start avg 434ms
|
|
34
|
+
- 누적 회귀 (12): 1.9.207~253
|
|
35
|
+
|
|
36
|
+
### 자동 release (116 main-push streak · 77 npm publish streak · R210)
|
|
37
|
+
|
|
38
|
+
🔗 **설치 후 즉시 사용 가능** — npm global bin PATH 누락 자동 감지 + 안전 등록 (opt-in).
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 1.9.253 — 2026-05-29 — CLAUDE/AGENTS 문서 누적 갱신 (1.9.238~252 drift 차단)
|
|
43
|
+
|
|
44
|
+
**📚 문서 drift 차단: 메타 지침서가 1.9.237에 멈춰 있어 15 라운드(1.9.238~252) 미반영 → 누적 갱신.**
|
|
45
|
+
|
|
46
|
+
### 배경
|
|
47
|
+
CLAUDE.md / AGENTS.md(AI 에이전트 핸드오프 핵심 지침)가 마지막으로 1.9.237까지만 반영. 1.9.238~252의 사용자 명시 백로그 UR-0013~0018 6 요청이 문서에 없어, 새 세션 AI가 최신 기능(py-check, env encoding, api-skill, agy, 인코딩 자동회복)을 인지 못 할 drift 위험. (기존 패턴: 1.9.171/214/238 doc-sync 라운드 계승)
|
|
48
|
+
|
|
49
|
+
### 구현 (문서 전용 — 코드 변경 없음, VERSION bump만)
|
|
50
|
+
1. **CLAUDE.md**: "사용자 명시 백로그 UR-0013~0018 (1.9.239~252)" 섹션 추가
|
|
51
|
+
- UR-0013 py/agent-mode · UR-0014 env encoding · UR-0015 api-skill · UR-0016 REPL UX · UR-0017 agy · UR-0018 인코딩 자동회복(4 라운드 상세)
|
|
52
|
+
- 마일스톤 1.9.237→1.9.252 갱신 (R208 · 114 main-push · 75 npm · JSON 11 필드 · MCP 70 · CLI 57)
|
|
53
|
+
2. **AGENTS.md**: UR-0013~0018 백로그 테이블 + UR-0018 4 라운드 상세 + 5축 매트릭스 유지 표기 + 마일스톤 1.9.252
|
|
54
|
+
3. session-workflow.md는 gitignored 생성 메타파일(6단계 워크플로 템플릿) — 기능 로그 대상 아님, 갱신 제외
|
|
55
|
+
|
|
56
|
+
### stress-v198 — **21/21 PASS · 100%**
|
|
57
|
+
- 1.9.253 (8): VERSION + CLAUDE/AGENTS 백로그·UR-0018·마일스톤·11필드·stale 참조 해소
|
|
58
|
+
- 성능 (1): cold start avg 394ms
|
|
59
|
+
- 누적 회귀 (12): 1.9.207~252
|
|
60
|
+
|
|
61
|
+
### 자동 release (115 main-push streak · 76 npm publish streak · R209)
|
|
62
|
+
|
|
63
|
+
📚 **AI 핸드오프 지침 최신화** — 새 세션 에이전트가 UR-0013~0018 기능을 즉시 인지, drift 0 유지.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
3
67
|
## 1.9.252 — 2026-05-29 — UR-0018 마무리: env DRY 통합 + agent-mode 인코딩 점검
|
|
4
68
|
|
|
5
69
|
**🧹 UR-0018 코드 정리: 1.9.249~251 누적된 인코딩 분기 중복을 단일 헬퍼로 일원화.**
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **AI 코딩 에이전트의 거짓 완료·중복·망각·충돌을 막아주는 검수·기억·협업 CLI 하네스.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []() []() []() []() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
╔══════════════════════════════════════════════════════════════╗
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
║ ██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║ ║
|
|
13
13
|
║ ███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║ ║
|
|
14
14
|
║ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝ ║
|
|
15
|
-
║ v1.9.
|
|
15
|
+
║ v1.9.254 AI Agent Reliability Harness + Sandbox ║
|
|
16
16
|
║ verify · remember · orchestrate · audit · sandbox · drift ║
|
|
17
|
-
║
|
|
17
|
+
║ 🔗 CLI PATH 자동 등록 (path-setup · UR-0019 · R210) ║
|
|
18
18
|
╚══════════════════════════════════════════════════════════════╝
|
|
19
19
|
```
|
|
20
20
|
|
package/bin/harness.js
CHANGED
|
@@ -7,7 +7,7 @@ const cp = require('child_process');
|
|
|
7
7
|
const os = require('os'); // 1.9.178: _publishToNpm 에서 os.tmpdir() 사용 (전역 import)
|
|
8
8
|
const readline = require('readline');
|
|
9
9
|
|
|
10
|
-
const VERSION = '1.9.
|
|
10
|
+
const VERSION = '1.9.254';
|
|
11
11
|
|
|
12
12
|
// 1.9.184: DEP0190 (child_process shell: true) deprecation warning 억제 (사용자 명시).
|
|
13
13
|
// leerness 는 cross-platform PATH resolution 을 위해 shell: true 를 의도적으로 사용 (claude.cmd / ollama.cmd 등 Windows .cmd 처리).
|
|
@@ -1069,6 +1069,19 @@ async function install(root, opts = {}) {
|
|
|
1069
1069
|
}
|
|
1070
1070
|
} catch {}
|
|
1071
1071
|
}
|
|
1072
|
+
// 1.9.254 (UR-0019): init 완료 시 leerness CLI 가 PATH 에서 안 찾아지면 자동 등록 안내 (사용자 명시)
|
|
1073
|
+
// opt-out: LEERNESS_NO_PATH_CHECK=1. 자동 등록은 강제하지 않고 안내만 (--apply 명시 필요).
|
|
1074
|
+
if (!opts.migration && process.env.LEERNESS_NO_PATH_CHECK !== '1') {
|
|
1075
|
+
try {
|
|
1076
|
+
const diag = _pathDiagnose();
|
|
1077
|
+
if (!diag.resolvable && !diag.inPath && diag.globalBin) {
|
|
1078
|
+
log('');
|
|
1079
|
+
log(`\x1b[33m🔗 leerness CLI PATH 미등록 (1.9.254, UR-0019)\x1b[0m`);
|
|
1080
|
+
log(`\x1b[2m npm global bin (${diag.globalBin}) 이 PATH 에 없어 'leerness' 명령이 안 먹힐 수 있음\x1b[0m`);
|
|
1081
|
+
log(`\x1b[36m → 자동 등록: leerness path-setup --apply\x1b[0m`);
|
|
1082
|
+
}
|
|
1083
|
+
} catch {}
|
|
1084
|
+
}
|
|
1072
1085
|
// 1.9.1 P7: 디폴트 M-0001이 plan에 있고 progress에 row가 없으면 자동 추가
|
|
1073
1086
|
try {
|
|
1074
1087
|
const planText = exists(planPath(root)) ? read(planPath(root)) : '';
|
|
@@ -2699,9 +2712,163 @@ function envCmd(root, sub) {
|
|
|
2699
2712
|
}
|
|
2700
2713
|
log('');
|
|
2701
2714
|
log(dm(` → 인코딩 검사: leerness env encoding-check (셸 스크립트 .ps1/.bat 위험 감지)`));
|
|
2715
|
+
log(dm(` → PATH 등록: leerness path-setup (leerness CLI 가 PATH 에서 안 찾아질 때)`));
|
|
2702
2716
|
log(dm(` → JSON 출력: leerness env --json`));
|
|
2703
2717
|
}
|
|
2704
2718
|
|
|
2719
|
+
// 1.9.254: leerness CLI PATH 자동 등록 (사용자 명시 UR-0019)
|
|
2720
|
+
// 배경: `npm i -g leerness` 했는데 npm global bin 이 PATH 에 없으면 `leerness` 명령이 안 먹힘.
|
|
2721
|
+
// 해결: global bin 경로 감지 + PATH 포함 여부 확인 → 미등록 시 플랫폼별 안전 등록 (opt-in --apply).
|
|
2722
|
+
// 안전 원칙 (글로벌 룰: 안정성 > 성능, 엄격 처리): dry-run 기본 / 멱등 / append-only / 덮어쓰기 금지.
|
|
2723
|
+
|
|
2724
|
+
// npm global bin 디렉토리 감지 (npm prefix -g + bin, fallback: process.execPath 기반)
|
|
2725
|
+
function _npmGlobalBin() {
|
|
2726
|
+
// 1) npm prefix -g (가장 정확) — Windows 는 prefix 자체가 bin, Unix 는 prefix/bin
|
|
2727
|
+
try {
|
|
2728
|
+
const r = cp.spawnSync('npm', ['prefix', '-g'], { encoding: 'utf8', shell: true, timeout: 5000 });
|
|
2729
|
+
if (r.status === 0) {
|
|
2730
|
+
const prefix = (r.stdout || '').trim().split(/\r?\n/).pop();
|
|
2731
|
+
if (prefix) return process.platform === 'win32' ? prefix : path.join(prefix, 'bin');
|
|
2732
|
+
}
|
|
2733
|
+
} catch {}
|
|
2734
|
+
// 2) fallback: 현재 실행 중인 node 의 디렉토리 (global bin 이 보통 같은 위치)
|
|
2735
|
+
try { return path.dirname(process.execPath); } catch {}
|
|
2736
|
+
return null;
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
// 주어진 디렉토리가 현재 PATH 에 포함되어 있는지 (대소문자/구분자 정규화)
|
|
2740
|
+
function _dirInPath(dir) {
|
|
2741
|
+
if (!dir) return false;
|
|
2742
|
+
const sep = process.platform === 'win32' ? ';' : ':';
|
|
2743
|
+
const norm = s => {
|
|
2744
|
+
let p = (s || '').trim().replace(/["']/g, '');
|
|
2745
|
+
try { p = path.normalize(p); } catch {}
|
|
2746
|
+
p = p.replace(/[\\/]+$/, '');
|
|
2747
|
+
return process.platform === 'win32' ? p.toLowerCase() : p;
|
|
2748
|
+
};
|
|
2749
|
+
const want = norm(dir);
|
|
2750
|
+
return (process.env.PATH || '').split(sep).map(norm).filter(Boolean).includes(want);
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2753
|
+
// leerness 가 PATH 에서 실행 가능한지 (which/where 사용)
|
|
2754
|
+
function _leernessResolvable() {
|
|
2755
|
+
try {
|
|
2756
|
+
const probe = process.platform === 'win32' ? 'where' : 'which';
|
|
2757
|
+
const r = cp.spawnSync(probe, ['leerness'], { encoding: 'utf8', shell: true, timeout: 5000 });
|
|
2758
|
+
return r.status === 0 && /leerness/i.test((r.stdout || ''));
|
|
2759
|
+
} catch { return false; }
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
// PATH 등록 상태 진단 (반환: { globalBin, inPath, resolvable, platform, shellRc })
|
|
2763
|
+
function _pathDiagnose() {
|
|
2764
|
+
const globalBin = _npmGlobalBin();
|
|
2765
|
+
const inPath = _dirInPath(globalBin);
|
|
2766
|
+
const resolvable = _leernessResolvable();
|
|
2767
|
+
let shellRc = null;
|
|
2768
|
+
if (process.platform !== 'win32') {
|
|
2769
|
+
const home = os.homedir();
|
|
2770
|
+
const shell = process.env.SHELL || '';
|
|
2771
|
+
if (/zsh/.test(shell)) shellRc = path.join(home, '.zshrc');
|
|
2772
|
+
else if (/bash/.test(shell)) shellRc = path.join(home, '.bashrc');
|
|
2773
|
+
else shellRc = path.join(home, '.profile');
|
|
2774
|
+
}
|
|
2775
|
+
return { globalBin, inPath, resolvable, platform: process.platform, shellRc };
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
// PATH 에 globalBin 등록 (플랫폼별 안전 방법). 반환: { ok, method, detail }
|
|
2779
|
+
function _registerPath(diag) {
|
|
2780
|
+
const bin = diag.globalBin;
|
|
2781
|
+
if (!bin) return { ok: false, method: 'none', detail: 'npm global bin 경로를 찾을 수 없음' };
|
|
2782
|
+
if (process.platform === 'win32') {
|
|
2783
|
+
// Windows: PowerShell [Environment]::SetEnvironmentVariable User scope — setx 의 1024자 truncation 회피
|
|
2784
|
+
// 현재 User PATH 를 읽어 중복 없으면 append (멱등). 시스템 PATH 는 건드리지 않음 (관리자 권한 불요).
|
|
2785
|
+
try {
|
|
2786
|
+
const ps = [
|
|
2787
|
+
"$b = " + JSON.stringify(bin) + ";",
|
|
2788
|
+
"$u = [Environment]::GetEnvironmentVariable('PATH','User'); if (-not $u) { $u = '' }",
|
|
2789
|
+
"$parts = $u.Split(';') | Where-Object { $_ -ne '' }",
|
|
2790
|
+
"if ($parts -notcontains $b) {",
|
|
2791
|
+
" $nu = if ($u -eq '') { $b } else { $u.TrimEnd(';') + ';' + $b }",
|
|
2792
|
+
" [Environment]::SetEnvironmentVariable('PATH', $nu, 'User')",
|
|
2793
|
+
" Write-Output 'ADDED'",
|
|
2794
|
+
"} else { Write-Output 'EXISTS' }"
|
|
2795
|
+
].join(' ');
|
|
2796
|
+
const r = cp.spawnSync('powershell', ['-NoProfile', '-Command', ps], { encoding: 'utf8', timeout: 10000 });
|
|
2797
|
+
const out = (r.stdout || '').trim();
|
|
2798
|
+
if (r.status === 0 && /ADDED/.test(out)) return { ok: true, method: 'powershell-user-path', detail: `User PATH 에 추가됨 (새 터미널부터 적용): ${bin}` };
|
|
2799
|
+
if (r.status === 0 && /EXISTS/.test(out)) return { ok: true, method: 'already', detail: `User PATH 에 이미 존재: ${bin}` };
|
|
2800
|
+
return { ok: false, method: 'powershell-user-path', detail: `등록 실패 (exit ${r.status}): ${(r.stderr || out || '').trim().slice(0, 200)}` };
|
|
2801
|
+
} catch (e) { return { ok: false, method: 'powershell-user-path', detail: `예외: ${e.message}` }; }
|
|
2802
|
+
}
|
|
2803
|
+
// Unix: shell rc 파일에 export 블록 append (멱등 — 마커로 중복 차단)
|
|
2804
|
+
try {
|
|
2805
|
+
const rc = diag.shellRc;
|
|
2806
|
+
const MARKER = '# >>> leerness PATH (1.9.254) >>>';
|
|
2807
|
+
const END = '# <<< leerness PATH <<<';
|
|
2808
|
+
let cur = '';
|
|
2809
|
+
try { cur = fs.readFileSync(rc, 'utf8'); } catch {}
|
|
2810
|
+
if (cur.includes(MARKER)) return { ok: true, method: 'already', detail: `${rc} 에 이미 등록됨` };
|
|
2811
|
+
const block = `\n${MARKER}\nexport PATH="$PATH:${bin}"\n${END}\n`;
|
|
2812
|
+
fs.appendFileSync(rc, block, 'utf8');
|
|
2813
|
+
return { ok: true, method: 'shell-rc', detail: `${rc} 에 추가됨 (source 또는 새 터미널부터 적용): ${bin}` };
|
|
2814
|
+
} catch (e) { return { ok: false, method: 'shell-rc', detail: `예외: ${e.message}` }; }
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
function pathSetupCmd(root, opts = {}) {
|
|
2818
|
+
const isTty = process.stdout && process.stdout.isTTY;
|
|
2819
|
+
const cy = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
|
|
2820
|
+
const gr = s => isTty ? `\x1b[32m${s}\x1b[0m` : s;
|
|
2821
|
+
const yl = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
|
|
2822
|
+
const dm = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
2823
|
+
const diag = _pathDiagnose();
|
|
2824
|
+
if (opts.json) {
|
|
2825
|
+
let applied = null;
|
|
2826
|
+
if (opts.apply && !diag.resolvable && !diag.inPath) applied = _registerPath(diag);
|
|
2827
|
+
log(JSON.stringify({ ...diag, applied }, null, 2));
|
|
2828
|
+
return;
|
|
2829
|
+
}
|
|
2830
|
+
log(cy(`# leerness path-setup (1.9.254, UR-0019) — CLI PATH 자동 등록`));
|
|
2831
|
+
log('');
|
|
2832
|
+
log(` npm global bin: ${diag.globalBin ? gr(diag.globalBin) : yl('감지 실패')}`);
|
|
2833
|
+
log(` PATH 포함 여부: ${diag.inPath ? gr('✓ 포함됨') : yl('✗ 미포함')}`);
|
|
2834
|
+
log(` leerness 실행 가능: ${diag.resolvable ? gr('✓ 가능 (which/where 성공)') : yl('✗ 불가')}`);
|
|
2835
|
+
log('');
|
|
2836
|
+
if (diag.resolvable || diag.inPath) {
|
|
2837
|
+
log(gr(` ✓ leerness CLI 가 이미 PATH 에서 정상 동작합니다 — 등록 불필요`));
|
|
2838
|
+
return;
|
|
2839
|
+
}
|
|
2840
|
+
if (!diag.globalBin) {
|
|
2841
|
+
log(yl(` ⚠ npm global bin 경로를 찾을 수 없어 자동 등록 불가`));
|
|
2842
|
+
log(dm(` → 수동: npm prefix -g 로 경로 확인 후 PATH 에 추가`));
|
|
2843
|
+
return;
|
|
2844
|
+
}
|
|
2845
|
+
if (!opts.apply) {
|
|
2846
|
+
// dry-run (기본)
|
|
2847
|
+
log(yl(` ⚠ leerness 가 PATH 에 없습니다 — 'leerness' 명령이 동작하지 않을 수 있음`));
|
|
2848
|
+
log(` ${dm('적용 시 추가될 경로:')} ${diag.globalBin}`);
|
|
2849
|
+
if (diag.platform === 'win32') {
|
|
2850
|
+
log(dm(` 방법: PowerShell [Environment]::SetEnvironmentVariable('PATH', ..., 'User') (관리자 권한 불요)`));
|
|
2851
|
+
} else {
|
|
2852
|
+
log(dm(` 방법: ${diag.shellRc} 에 export PATH 블록 append (멱등)`));
|
|
2853
|
+
}
|
|
2854
|
+
log('');
|
|
2855
|
+
log(cy(` → 자동 등록: leerness path-setup --apply`));
|
|
2856
|
+
return;
|
|
2857
|
+
}
|
|
2858
|
+
// --apply
|
|
2859
|
+
const res = _registerPath(diag);
|
|
2860
|
+
if (res.ok) {
|
|
2861
|
+
log(gr(` ✓ PATH 등록 완료 (${res.method})`));
|
|
2862
|
+
log(` ${res.detail}`);
|
|
2863
|
+
log('');
|
|
2864
|
+
if (diag.platform === 'win32') log(dm(` → 새 터미널을 열면 'leerness' 명령을 바로 쓸 수 있습니다.`));
|
|
2865
|
+
else log(dm(` → source ${diag.shellRc} 또는 새 터미널에서 'leerness' 명령 사용 가능.`));
|
|
2866
|
+
} else {
|
|
2867
|
+
log(yl(` ⚠ 자동 등록 실패 (${res.method}): ${res.detail}`));
|
|
2868
|
+
log(dm(` → 수동 등록: PATH 에 ${diag.globalBin} 추가`));
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2705
2872
|
// 1.9.245: API skill cache — 공식 문서 + 관련 링크 자동 정리 (사용자 명시 UR-0015)
|
|
2706
2873
|
// .harness/api-skills/<id>.md 에 frontmatter + 본문 저장. handoff 자동 매칭.
|
|
2707
2874
|
// Node built-in https (의존성 0), depth=1 same-domain crawl, max 10 links.
|
|
@@ -19713,6 +19880,9 @@ async function main() {
|
|
|
19713
19880
|
// 기존 env check/sync/detect (1.9.71) 와 충돌하지 않음 — summary/encoding 신규 서브
|
|
19714
19881
|
if (cmd === 'env' && (args[1] === 'summary' || args[1] === 'encoding' || args[1] === 'encoding-check'))
|
|
19715
19882
|
return envCmd(arg('--path', process.cwd()), args[1] === 'summary' ? null : 'encoding-check');
|
|
19883
|
+
// 1.9.254: leerness path-setup [--apply] — CLI PATH 자동 등록 (사용자 명시 UR-0019)
|
|
19884
|
+
// npm global bin 경로 감지 + leerness 가 PATH 에서 찾아지는지 확인 → 미등록 시 플랫폼별 등록
|
|
19885
|
+
if (cmd === 'path-setup' || cmd === 'path') return pathSetupCmd(arg('--path', process.cwd()), { apply: has('--apply'), json: has('--json') });
|
|
19716
19886
|
// 1.9.245: API skill cache — 공식 문서·관련링크 자동 정리 (사용자 명시 UR-0015)
|
|
19717
19887
|
if (cmd === 'api-skill') return apiSkillCmd(arg('--path', process.cwd()), args[1] || 'help');
|
|
19718
19888
|
// 1.9.208: leerness constraints <list|check|add> — 플랫폼/API 제약 사전 체크 (사용자 명시)
|