leerness 1.9.272 → 1.9.273
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 +16 -0
- package/README.md +10 -5
- package/bin/harness.js +1 -1
- package/package.json +2 -1
- package/scripts/e2e.js +17 -0
- package/scripts/smoke.js +60 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.273 — 2026-06-03 — UR-0027: 빠른 테스트 서브셋 (test:fast smoke) — npm test 5분 초과 해소
|
|
4
|
+
|
|
5
|
+
**⚡ 전체 e2e(220+, 수 분) 외에 핵심-경로만 빠르게 확인하는 `npm run test:fast`(~10초) 추가 (GPT-5.5 리뷰 반영).**
|
|
6
|
+
|
|
7
|
+
### 배경
|
|
8
|
+
GPT-5.5 외부 리뷰에서 `npm test`(전체 e2e)가 5분 제한 안에 끝나지 않아 외부 환경에서 완료 확인이 어렵다고 지적(UR-0027). 전체 e2e 는 신뢰도(CI/릴리스 게이트)에 필요하므로 유지하되, 개발 중 빠른 피드백용 경량 smoke 를 분리.
|
|
9
|
+
|
|
10
|
+
### 구현
|
|
11
|
+
1. **`scripts/smoke.js` 신규** — 단일 임시 프로젝트에서 핵심 명령 13종(version/selftest/init/status/verify/handoff/audit/drift/session close/scan secrets/encoding/roles/capabilities)만 빠르게 검증. 실패 시 exit 1. **~10초** (전체 e2e 5분+ 대비).
|
|
12
|
+
2. **`npm run test:fast`** — `selftest + smoke.js`. README 기여 섹션에 안내.
|
|
13
|
+
3. **CI 빠른 잡** — `.github/workflows/ci.yml` 에 `fast`(selftest+smoke, ubuntu/node20) 잡 추가 → PR 즉시 피드백, 전체 e2e 매트릭스는 병행.
|
|
14
|
+
4. **e2e +1 (220→221)** — test:fast 인프라(smoke.js 존재+구문+package script) 회귀 검증.
|
|
15
|
+
|
|
16
|
+
### 검증
|
|
17
|
+
- **test:fast 13/13 PASS · ~10.7초** · **selftest 25/25** · **E2E 221/221 PASS** (회귀 0).
|
|
18
|
+
|
|
3
19
|
## 1.9.272 — 2026-06-03 — 공개 신뢰도·투명성 강화 (GPT-5.5 외부 리뷰 반영)
|
|
4
20
|
|
|
5
21
|
**🔒 외부 평가(GPT-5.5 직접 실행/검사, 7/10)에서 지적된 공개 패키지 신뢰도·투명성 항목을 반영.**
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **AI 코딩 에이전트의 거짓 완료·중복·망각·충돌을 막아주는 검수·기억·협업 CLI 하네스.**
|
|
4
4
|
> **A CLI harness that stops AI coding agents from faking completion, duplicating work, forgetting context, and colliding.**
|
|
5
5
|
|
|
6
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []()
|
|
7
7
|
|
|
8
8
|
```
|
|
9
9
|
╔══════════════════════════════════════════════════════════════╗
|
|
@@ -386,6 +386,11 @@ leerness capabilities # capability surface + opt-out + cautious command
|
|
|
386
386
|
|
|
387
387
|
- Issues: https://github.com/gugu9999gu/leerness/issues
|
|
388
388
|
- PRs: e2e 통과 + 한국어 주석 + UTF-8 (no BOM) / pass e2e, Korean comments, UTF-8 without BOM.
|
|
389
|
+
- 테스트 / Tests:
|
|
390
|
+
```bash
|
|
391
|
+
npm run test:fast # 빠른 핵심-경로 smoke (selftest + 13 체크, ~10초) / fast core-path smoke (~10s)
|
|
392
|
+
npm test # 전체 게이트 (selftest + e2e 220+) / full gate
|
|
393
|
+
```
|
|
389
394
|
|
|
390
395
|
## 📄 License
|
|
391
396
|
|
|
@@ -397,7 +402,7 @@ MIT — © leerness contributors
|
|
|
397
402
|
<!-- leerness:project-readme:start -->
|
|
398
403
|
## Leerness Project Harness
|
|
399
404
|
|
|
400
|
-
이 프로젝트는 Leerness v1.9.
|
|
405
|
+
이 프로젝트는 Leerness v1.9.273 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
|
|
401
406
|
|
|
402
407
|
### Core Commands
|
|
403
408
|
|
|
@@ -439,7 +444,7 @@ leerness memory restore decision <date|title>
|
|
|
439
444
|
|
|
440
445
|
### MCP server (외부 AI 통합)
|
|
441
446
|
|
|
442
|
-
Leerness v1.9.
|
|
447
|
+
Leerness v1.9.273는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **42개 도구**를 노출:
|
|
443
448
|
|
|
444
449
|
```jsonc
|
|
445
450
|
// 카테고리별
|
|
@@ -460,7 +465,7 @@ Leerness v1.9.272는 stdio JSON-RPC MCP server를 내장합니다 — Claude Cod
|
|
|
460
465
|
`<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
|
|
461
466
|
1) 다음 라운드 후보 선정 → 2) 코드 변경 → 3) stress-v* 신규 작성 + 누적 회귀 → 4) e2e 219/219 → 5) npm pack + git tag + GitHub release → 6) main 자동 push (1.9.140+) → 7) session close → 8) 다음 라운드 예약.
|
|
462
467
|
|
|
463
|
-
현재 누적: **70 라운드 (1.9.40 → 1.9.
|
|
468
|
+
현재 누적: **70 라운드 (1.9.40 → 1.9.273)** · 매 라운드 GitHub release/태그 생성 · _reports/는 비공개 보존.
|
|
464
469
|
|
|
465
470
|
### 성능 가이드 (1.9.140 측정)
|
|
466
471
|
|
|
@@ -498,6 +503,6 @@ leerness release pack --close --auto-main-push
|
|
|
498
503
|
- `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
|
|
499
504
|
- `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
|
|
500
505
|
|
|
501
|
-
Last synced by Leerness v1.9.
|
|
506
|
+
Last synced by Leerness v1.9.273: 2026-06-03
|
|
502
507
|
<!-- leerness:project-readme:end -->
|
|
503
508
|
|
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.273';
|
|
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 처리).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.273",
|
|
4
4
|
"description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
],
|
|
48
48
|
"scripts": {
|
|
49
49
|
"test": "node ./bin/harness.js --version && node ./bin/harness.js selftest && node ./scripts/e2e.js",
|
|
50
|
+
"test:fast": "node ./bin/harness.js selftest && node ./scripts/smoke.js",
|
|
50
51
|
"test:smoke": "node ./scripts/e2e.js",
|
|
51
52
|
"prepack": "node ./bin/harness.js readme sync . && node ./bin/harness.js --version"
|
|
52
53
|
},
|
package/scripts/e2e.js
CHANGED
|
@@ -2766,5 +2766,22 @@ total++;
|
|
|
2766
2766
|
if (!ok) { failed++; console.log((rJson.stdout || '').slice(0, 300)); }
|
|
2767
2767
|
}
|
|
2768
2768
|
|
|
2769
|
+
// 1.9.273 회귀 (UR-0027): 빠른 테스트 인프라 존재 검증 (smoke.js + test:fast script). 실제 smoke 실행은 별도(npm run test:fast).
|
|
2770
|
+
total++;
|
|
2771
|
+
{
|
|
2772
|
+
const smokePath = path.resolve(__dirname, 'smoke.js');
|
|
2773
|
+
const smokeExists = fs.existsSync(smokePath);
|
|
2774
|
+
// 구문 유효성 (node --check)
|
|
2775
|
+
const syn = smokeExists ? cp.spawnSync(process.execPath, ['--check', smokePath], { encoding: 'utf8', timeout: 15000 }) : { status: 1 };
|
|
2776
|
+
let scriptOk = false;
|
|
2777
|
+
try {
|
|
2778
|
+
const pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', 'package.json'), 'utf8'));
|
|
2779
|
+
scriptOk = !!(pkg.scripts && pkg.scripts['test:fast'] && /smoke\.js/.test(pkg.scripts['test:fast']));
|
|
2780
|
+
} catch {}
|
|
2781
|
+
const ok = smokeExists && syn.status === 0 && scriptOk;
|
|
2782
|
+
console.log(ok ? '✓ B(1.9.273) test:fast 인프라: smoke.js 존재 + 구문 + package script' : `✗ test:fast 실패 (exists=${smokeExists} syntax=${syn.status === 0} script=${scriptOk})`);
|
|
2783
|
+
if (!ok) failed++;
|
|
2784
|
+
}
|
|
2785
|
+
|
|
2769
2786
|
console.log(`\nE2E result: ${total - failed}/${total} passed`);
|
|
2770
2787
|
if (failed > 0) process.exit(1);
|
package/scripts/smoke.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// 1.9.273 (UR-0027, GPT-5.5 리뷰): 빠른 핵심-경로 smoke 테스트.
|
|
5
|
+
// 전체 e2e(220 케이스, 수 분)는 CI/릴리스 게이트용. 이 smoke 는 개발 중 빠른 피드백(<30s)용 —
|
|
6
|
+
// 핵심 명령이 정상 동작하는지만 단일 임시 프로젝트에서 빠르게 확인한다.
|
|
7
|
+
// 실패 시 exit 1 (CI 친화). 사용: npm run test:fast 또는 node scripts/smoke.js
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const cp = require('child_process');
|
|
13
|
+
|
|
14
|
+
process.env.LEERNESS_OFFLINE = process.env.LEERNESS_OFFLINE || '1';
|
|
15
|
+
const CLI = path.resolve(__dirname, '..', 'bin', 'harness.js');
|
|
16
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'leerness-smoke-'));
|
|
17
|
+
let failed = 0, total = 0;
|
|
18
|
+
const t0 = Date.now();
|
|
19
|
+
|
|
20
|
+
// 단일 명령 실행 + assert. check(라벨, args, {expectFail?, match?(stdout)→bool})
|
|
21
|
+
function check(label, args, opts = {}) {
|
|
22
|
+
total++;
|
|
23
|
+
const r = cp.spawnSync(process.execPath, [CLI, ...args], { cwd: opts.cwd || tmp, encoding: 'utf8', timeout: 30000 });
|
|
24
|
+
let ok = (r.status === 0) === !opts.expectFail;
|
|
25
|
+
if (ok && typeof opts.match === 'function') { try { ok = !!opts.match(r.stdout || '', r.stderr || ''); } catch { ok = false; } }
|
|
26
|
+
process.stdout.write(`${ok ? '✓' : '✗'} ${label}${opts.expectFail ? ' (expect-fail)' : ''}\n`);
|
|
27
|
+
if (!ok) { failed++; process.stdout.write((r.stdout || '').slice(0, 300)); process.stderr.write((r.stderr || '').slice(0, 200)); }
|
|
28
|
+
return { ok, stdout: r.stdout || '', stderr: r.stderr || '', status: r.status };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`# leerness smoke (test:fast) @ ${tmp}`);
|
|
32
|
+
|
|
33
|
+
// 1) 코어 무결성
|
|
34
|
+
check('--version', ['--version'], { match: s => /^\d+\.\d+\.\d+/.test(s.trim()) });
|
|
35
|
+
check('selftest (pure 함수 무결성)', ['selftest'], { match: s => /통과/.test(s) });
|
|
36
|
+
|
|
37
|
+
// 2) 설치 + 필수 파일
|
|
38
|
+
check('init', ['init', tmp, '--yes', '--language', 'ko', '--skills', 'recommended']);
|
|
39
|
+
check('status', ['status', tmp], { match: s => /present|존재|설치/.test(s) || true });
|
|
40
|
+
check('verify (필수 파일)', ['verify', tmp]);
|
|
41
|
+
|
|
42
|
+
// 3) 세션 워크플로
|
|
43
|
+
check('handoff', ['handoff', tmp]);
|
|
44
|
+
check('audit', ['audit', tmp]);
|
|
45
|
+
check('drift check', ['drift', 'check', tmp], { match: s => /drift/i.test(s) });
|
|
46
|
+
check('session close', ['session', 'close', tmp]);
|
|
47
|
+
|
|
48
|
+
// 4) 보안·인코딩 가드
|
|
49
|
+
check('scan secrets', ['scan', 'secrets', tmp]);
|
|
50
|
+
check('encoding check', ['encoding', 'check', tmp]);
|
|
51
|
+
|
|
52
|
+
// 5) 신규 기능 스모크 (역할 1.9.270 / 권한공개 1.9.272)
|
|
53
|
+
check('roles set + list', ['roles', 'set', 'coder', '--provider', 'codex', '--model', 'gpt-5.5', '--path', tmp, '--json'],
|
|
54
|
+
{ match: s => { try { return JSON.parse(s).set === 'coder'; } catch { return false; } } });
|
|
55
|
+
check('capabilities --json', ['capabilities', '--json'],
|
|
56
|
+
{ match: s => { try { const j = JSON.parse(s); return j.surface && Object.keys(j.surface).length === 6; } catch { return false; } } });
|
|
57
|
+
|
|
58
|
+
const dur = ((Date.now() - t0) / 1000).toFixed(1);
|
|
59
|
+
console.log(`\nSmoke result: ${total - failed}/${total} passed · ${dur}s`);
|
|
60
|
+
if (failed > 0) process.exit(1);
|