leerness 1.9.254 → 1.9.255
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 +33 -0
- package/README.md +3 -3
- package/bin/harness.js +47 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.255 — 2026-05-29 — UR-0019 2단계: PATH 등록 실제 테스트/디버그 + require.main 가드
|
|
4
|
+
|
|
5
|
+
**🧪 사용자 명시 (UR-0019 후속 "테스트 및 디버그 다음라운드 참고"): PATH 자동 등록 실제 동작 검증 + 테스트 인프라.**
|
|
6
|
+
|
|
7
|
+
### 배경
|
|
8
|
+
1.9.254에서 `path-setup` 구현 후, 실제 `--apply` 등록 로직(Unix shell-rc append, Windows PS-script)의 깊은 테스트/디버그가 필요. 단, 실 PATH 변경은 위험 → 단위 테스트 가능하도록 리팩터링.
|
|
9
|
+
|
|
10
|
+
### 구현 (테스트 가능성 + 안전 검증)
|
|
11
|
+
1. **`require.main === module` 가드** (footgun fix):
|
|
12
|
+
- `node harness.js` / `npx leerness` CLI 직접 실행 시에만 `main()` 호출
|
|
13
|
+
- `require('harness.js')` 시 init 부작용 없이 내부 함수 import 가능 → 단위 테스트 활성화
|
|
14
|
+
- 기존 CLI 동작 100% 보존 (e2e 217 검증)
|
|
15
|
+
2. **순수 함수 추출** (테스트/디버그 가능):
|
|
16
|
+
- `_winPathPsScript(bin)` — Windows User PATH 등록 PowerShell 스크립트 생성 (실행과 분리)
|
|
17
|
+
- `_unixPathBlock(bin)` — Unix shell-rc export 블록 생성 (마커 멱등)
|
|
18
|
+
- `_registerPath` — `process.platform` → `diag.platform` (테스트 시 플랫폼 주입 가능)
|
|
19
|
+
3. **8종 헬퍼 module.exports** (test 인프라)
|
|
20
|
+
|
|
21
|
+
### 실제 테스트/디버그 결과 (stress-v200, 실 PATH 미변경)
|
|
22
|
+
- **Unix shell-rc 실제 등록**: temp 파일에 1차 등록(shell-rc) → 2차 멱등(already, export 1줄만) → 마커 존재 → 기존 rc 내용 보존(append-only) ✓
|
|
23
|
+
- **Windows PS-script**: User scope SetEnvironmentVariable / setx 미사용(truncation 회피) / -notcontains 멱등 가드 / bin JSON 이스케이프 ✓
|
|
24
|
+
- **edge**: globalBin null → ok=false / shellRc null → ok=false / _dirInPath trailing-slash 정규화 ✓
|
|
25
|
+
|
|
26
|
+
### stress-v200 — **27/27 PASS · 100%**
|
|
27
|
+
- 테스트 인프라 (4): require.main 가드 + 8종 export + CLI 동작
|
|
28
|
+
- Unix 실제 등록 (5) + Windows PS (4) + edge (5) + 성능/누적 회귀 (9)
|
|
29
|
+
|
|
30
|
+
### 자동 release (117 main-push streak · 78 npm publish streak · R211)
|
|
31
|
+
|
|
32
|
+
🧪 **PATH 등록 실증 + 테스트 인프라** — require.main 가드로 내부 함수 단위 테스트 가능 (이후 라운드 회귀 강화 기반).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
3
36
|
## 1.9.254 — 2026-05-29 — UR-0019 leerness CLI PATH 자동 등록
|
|
4
37
|
|
|
5
38
|
**🔗 사용자 명시 (UR-0019): "leerness 설치 시 leerness CLI가 PATH를 자동으로 등록될 수 있게 구현". (테스트/디버그는 다음 라운드 참고)**
|
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.255 AI Agent Reliability Harness + Sandbox ║
|
|
16
16
|
║ verify · remember · orchestrate · audit · sandbox · drift ║
|
|
17
|
-
║
|
|
17
|
+
║ 🧪 PATH 등록 실증 + require.main 가드 (UR-0019 · R211) ║
|
|
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.255';
|
|
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 처리).
|
|
@@ -2775,24 +2775,39 @@ function _pathDiagnose() {
|
|
|
2775
2775
|
return { globalBin, inPath, resolvable, platform: process.platform, shellRc };
|
|
2776
2776
|
}
|
|
2777
2777
|
|
|
2778
|
+
// 1.9.255 (UR-0019 2단계): Windows User PATH 등록용 PowerShell 스크립트 생성 (순수 함수 — 테스트/디버그 가능)
|
|
2779
|
+
// setx 의 1024자 truncation 회피 위해 [Environment]::SetEnvironmentVariable User scope 사용.
|
|
2780
|
+
// 멱등: 현재 User PATH 에 이미 있으면 EXISTS, 없으면 append 후 ADDED. 시스템 PATH 불변 (관리자 권한 불요).
|
|
2781
|
+
function _winPathPsScript(bin) {
|
|
2782
|
+
return [
|
|
2783
|
+
"$b = " + JSON.stringify(bin) + ";",
|
|
2784
|
+
"$u = [Environment]::GetEnvironmentVariable('PATH','User'); if (-not $u) { $u = '' }",
|
|
2785
|
+
"$parts = $u.Split(';') | Where-Object { $_ -ne '' }",
|
|
2786
|
+
"if ($parts -notcontains $b) {",
|
|
2787
|
+
" $nu = if ($u -eq '') { $b } else { $u.TrimEnd(';') + ';' + $b }",
|
|
2788
|
+
" [Environment]::SetEnvironmentVariable('PATH', $nu, 'User')",
|
|
2789
|
+
" Write-Output 'ADDED'",
|
|
2790
|
+
"} else { Write-Output 'EXISTS' }"
|
|
2791
|
+
].join(' ');
|
|
2792
|
+
}
|
|
2793
|
+
|
|
2794
|
+
// 1.9.255 (UR-0019 2단계): Unix shell rc 등록 블록 마커 (순수 — 테스트/디버그 가능, 멱등 키)
|
|
2795
|
+
const _UNIX_PATH_MARKER = '# >>> leerness PATH (managed) >>>';
|
|
2796
|
+
const _UNIX_PATH_END = '# <<< leerness PATH <<<';
|
|
2797
|
+
function _unixPathBlock(bin) {
|
|
2798
|
+
return `\n${_UNIX_PATH_MARKER}\nexport PATH="$PATH:${bin}"\n${_UNIX_PATH_END}\n`;
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2778
2801
|
// PATH 에 globalBin 등록 (플랫폼별 안전 방법). 반환: { ok, method, detail }
|
|
2802
|
+
// 1.9.255: process.platform → diag.platform 으로 변경 (테스트 가능 — diag.platform 은 실사용 시 process.platform 과 동일).
|
|
2779
2803
|
function _registerPath(diag) {
|
|
2780
2804
|
const bin = diag.globalBin;
|
|
2781
2805
|
if (!bin) return { ok: false, method: 'none', detail: 'npm global bin 경로를 찾을 수 없음' };
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
//
|
|
2806
|
+
const platform = diag.platform || process.platform;
|
|
2807
|
+
if (platform === 'win32') {
|
|
2808
|
+
// Windows: PowerShell [Environment]::SetEnvironmentVariable User scope (멱등, 관리자 권한 불요)
|
|
2785
2809
|
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(' ');
|
|
2810
|
+
const ps = _winPathPsScript(bin);
|
|
2796
2811
|
const r = cp.spawnSync('powershell', ['-NoProfile', '-Command', ps], { encoding: 'utf8', timeout: 10000 });
|
|
2797
2812
|
const out = (r.stdout || '').trim();
|
|
2798
2813
|
if (r.status === 0 && /ADDED/.test(out)) return { ok: true, method: 'powershell-user-path', detail: `User PATH 에 추가됨 (새 터미널부터 적용): ${bin}` };
|
|
@@ -2803,13 +2818,11 @@ function _registerPath(diag) {
|
|
|
2803
2818
|
// Unix: shell rc 파일에 export 블록 append (멱등 — 마커로 중복 차단)
|
|
2804
2819
|
try {
|
|
2805
2820
|
const rc = diag.shellRc;
|
|
2806
|
-
|
|
2807
|
-
const END = '# <<< leerness PATH <<<';
|
|
2821
|
+
if (!rc) return { ok: false, method: 'shell-rc', detail: 'shell rc 경로 미확인' };
|
|
2808
2822
|
let cur = '';
|
|
2809
2823
|
try { cur = fs.readFileSync(rc, 'utf8'); } catch {}
|
|
2810
|
-
if (cur.includes(
|
|
2811
|
-
|
|
2812
|
-
fs.appendFileSync(rc, block, 'utf8');
|
|
2824
|
+
if (cur.includes(_UNIX_PATH_MARKER)) return { ok: true, method: 'already', detail: `${rc} 에 이미 등록됨` };
|
|
2825
|
+
fs.appendFileSync(rc, _unixPathBlock(bin), 'utf8');
|
|
2813
2826
|
return { ok: true, method: 'shell-rc', detail: `${rc} 에 추가됨 (source 또는 새 터미널부터 적용): ${bin}` };
|
|
2814
2827
|
} catch (e) { return { ok: false, method: 'shell-rc', detail: `예외: ${e.message}` }; }
|
|
2815
2828
|
}
|
|
@@ -20024,6 +20037,18 @@ async function main() {
|
|
|
20024
20037
|
}
|
|
20025
20038
|
|
|
20026
20039
|
// 1.9.4 B: main 종료 후 exitCode를 명시적으로 process.exit으로 강제 (셸/wrapper 차 무시).
|
|
20027
|
-
main()
|
|
20028
|
-
|
|
20029
|
-
|
|
20040
|
+
// 1.9.255 (UR-0019 2단계): require.main 가드 — `require('harness.js')` 시 main() 미실행 (init 부작용 차단 + 내부 함수 단위 테스트 가능).
|
|
20041
|
+
// CLI 직접 실행 (node harness.js / npx leerness) 시에만 main() 호출. 기존 동작 100% 보존.
|
|
20042
|
+
if (require.main === module) {
|
|
20043
|
+
main()
|
|
20044
|
+
.then(() => { if (process.exitCode && process.exitCode !== 0) process.exit(process.exitCode); })
|
|
20045
|
+
.catch(err => { fail(err && err.message ? err.message : String(err)); process.exit(1); });
|
|
20046
|
+
}
|
|
20047
|
+
|
|
20048
|
+
// 1.9.255: 테스트/디버그용 내부 함수 export (require.main 가드 덕분에 require 시 CLI 미실행).
|
|
20049
|
+
// PATH 등록 (UR-0019) 검증 + 향후 단위 테스트 확장에 사용.
|
|
20050
|
+
module.exports = {
|
|
20051
|
+
VERSION,
|
|
20052
|
+
_npmGlobalBin, _dirInPath, _leernessResolvable, _pathDiagnose, _registerPath,
|
|
20053
|
+
_winPathPsScript, _unixPathBlock, pathSetupCmd
|
|
20054
|
+
};
|