leerness 1.9.81 → 1.9.83
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 +38 -0
- package/README.md +4 -2
- package/bin/harness.js +29 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.83 — 2026-05-20
|
|
4
|
+
|
|
5
|
+
**MCP server 16번째 도구 `leerness_skill_match` 추가** (1.9.45/50/68 skill match 외부 노출).
|
|
6
|
+
|
|
7
|
+
### Added — MCP 16번째 도구
|
|
8
|
+
- `leerness_skill_match` — 사용자 task 키워드에 매칭되는 설치된 skill 추천.
|
|
9
|
+
- inputSchema: `{ query: string (required), path: string, useEmbedding: boolean }`
|
|
10
|
+
- 응답: `skill match --json` 결과 (query / total / matched / top[].id/name/description/score)
|
|
11
|
+
- 1.9.68 rolling history 자동 누적 (`.harness/skill-suggestions.md`)
|
|
12
|
+
- 1.9.79 skill suggest 알고리즘에 자동 누적된 query 반영 가능
|
|
13
|
+
- MCP server 도구 카운트: **15 → 16**.
|
|
14
|
+
|
|
15
|
+
### Verified
|
|
16
|
+
- stress-v29 — MCP 16 도구 + skill_match 호출 + rolling history 누적 + 누적 회귀.
|
|
17
|
+
- e2e 219/219 PASS 유지.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1.9.82 — 2026-05-20
|
|
22
|
+
|
|
23
|
+
**`drift check --auto-fix` 에 보안 회복 통합** (1.9.78 + 1.9.75 audit --fix 결합).
|
|
24
|
+
|
|
25
|
+
### Added — drift --auto-fix 보안 자동 회복
|
|
26
|
+
- 1.9.39 `drift check --auto-fix` 확장:
|
|
27
|
+
- 기존: critical level 시 `session close` 자동 실행.
|
|
28
|
+
- **신규 (1.9.82)**: 보안 신호 (1.9.78) 발견 시 **우선 `audit --fix` 자동 실행** → `.gitignore` + `.env.example` 동기화 → 재검사.
|
|
29
|
+
- 호출 순서:
|
|
30
|
+
1. drift 신호 평가 (5개)
|
|
31
|
+
2. 보안 신호 fired → `audit --fix` 자동 실행 + 재귀 재검사
|
|
32
|
+
3. (보안 없는 critical) → `session close` 자동 실행 + 재귀 재검사
|
|
33
|
+
- AI 에이전트가 `drift check --auto-fix` 한 번으로 보안 + 세션 마감 둘 다 자동 회복.
|
|
34
|
+
|
|
35
|
+
### Verified
|
|
36
|
+
- stress-v28 — drift --auto-fix 보안 회복 / 재검사 후 안정화 / 누적 회귀.
|
|
37
|
+
- e2e 219/219 PASS 유지.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
3
41
|
## 1.9.81 — 2026-05-20
|
|
4
42
|
|
|
5
43
|
**`handoff` "통합 헤드라인" 한 줄 요약** (drift + 보안 + skill + MCP).
|
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,7 +12,7 @@
|
|
|
12
12
|
║ ██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║ ║
|
|
13
13
|
║ ███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║ ║
|
|
14
14
|
║ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝ ║
|
|
15
|
-
║ v1.9.
|
|
15
|
+
║ v1.9.83 AI Agent Reliability Harness ║
|
|
16
16
|
║ verify · remember · orchestrate · audit · prevent drift ║
|
|
17
17
|
╚══════════════════════════════════════════════════════════════╝
|
|
18
18
|
```
|
|
@@ -433,6 +433,8 @@ npm test # = node ./scripts/e2e.js
|
|
|
433
433
|
|
|
434
434
|
## 변경 이력 (최근)
|
|
435
435
|
|
|
436
|
+
- **1.9.83** — **MCP server 16번째 도구 `leerness_skill_match`** — 1.9.45/50/68 skill match를 외부 AI에 노출. rolling history 자동 누적.
|
|
437
|
+
- **1.9.82** — **`drift check --auto-fix` 보안 회복 통합** — 1.9.78 보안 신호 발견 시 `audit --fix` 자동 실행 → `.gitignore` + `.env.example` 동기화 후 재검사. 보안 + 세션 마감 한 번에 자동 회복.
|
|
436
438
|
- **1.9.81** — **`handoff` 통합 헤드라인** — drift level + 보안 상태 + MCP 활동 + skill query + 설치 skill 수를 한 줄로 압축. AI가 세션 시작 즉시 워크스페이스 상태 인지.
|
|
437
439
|
- **1.9.80** — **handoff 보안 critical 자동 회복** — `.env` 가 `.gitignore` 에 없으면 🚨 CRITICAL 경고 + `LEERNESS_AUTO_SECURITY_FIX=1` 시 `audit --fix` 자동 실행.
|
|
438
440
|
- **1.9.79** — **`leerness skill suggest` 알고리즘 강화** — 1.9.68 rolling history 빈도 (×2 가중) 추가. 반복 검색된 키워드를 신규 skill 후보로 자동 식별 (Hermes-style 학습).
|
package/bin/harness.js
CHANGED
|
@@ -6,7 +6,7 @@ const path = require('path');
|
|
|
6
6
|
const cp = require('child_process');
|
|
7
7
|
const readline = require('readline');
|
|
8
8
|
|
|
9
|
-
const VERSION = '1.9.
|
|
9
|
+
const VERSION = '1.9.83';
|
|
10
10
|
const MARK = '<!-- leerness:managed -->';
|
|
11
11
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
12
12
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -3384,7 +3384,7 @@ function _banner(opts = {}) {
|
|
|
3384
3384
|
lines.push('');
|
|
3385
3385
|
for (const ln of lines) log(ln);
|
|
3386
3386
|
if (opts.quickStart) {
|
|
3387
|
-
log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.
|
|
3387
|
+
log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.83+ 워크플로)')));
|
|
3388
3388
|
log(' ' + C.green('npx leerness@latest init .') + C.dim(' # 신규 프로젝트 + 외부 AI CLI 설정'));
|
|
3389
3389
|
log(' ' + C.green('npx leerness handoff .') + C.dim(' # 컨텍스트 + lessons + 매칭 skill + 이전 history hit (1.9.69)'));
|
|
3390
3390
|
log(' ' + C.green('npx leerness skill match "<query>"') + C.dim(' # 매칭 skill + rolling history 자동 누적 (1.9.68)'));
|
|
@@ -3393,7 +3393,7 @@ function _banner(opts = {}) {
|
|
|
3393
3393
|
log(' ' + C.green('npx leerness session close .') + C.dim(' # 마감 + 다음 라운드 추천 (default)'));
|
|
3394
3394
|
log('');
|
|
3395
3395
|
log(C.bold(C.cyan(' 🤖 메인 에이전트 (Claude/Cursor/Copilot)용')));
|
|
3396
|
-
log(' ' + C.green('npx leerness mcp serve') + C.dim(' # MCP 서버 —
|
|
3396
|
+
log(' ' + C.green('npx leerness mcp serve') + C.dim(' # MCP 서버 — 16 도구 (skill_match 포함, 1.9.83)'));
|
|
3397
3397
|
log(' ' + C.green('npx leerness agents bench "<task>"') + C.dim(' # 3 CLI 동시 비교'));
|
|
3398
3398
|
log('');
|
|
3399
3399
|
}
|
|
@@ -6452,8 +6452,30 @@ function driftCheckCmd(root, opts = {}) {
|
|
|
6452
6452
|
}
|
|
6453
6453
|
} catch {}
|
|
6454
6454
|
// 1.9.39: --auto-fix — critical 시 session close 자동 실행
|
|
6455
|
+
// 1.9.82: --auto-fix가 보안 신호도 자동 회복 (audit --fix 호출)
|
|
6455
6456
|
const autoFix = has('--auto-fix');
|
|
6456
|
-
|
|
6457
|
+
// 1.9.82: 보안 신호가 fired에 있으면 우선 audit --fix 호출
|
|
6458
|
+
const hasSecurityFired = fired.some(f => /보안 위험 \(1\.9\.78\)/.test(f.label));
|
|
6459
|
+
if (autoFix && hasSecurityFired) {
|
|
6460
|
+
log('');
|
|
6461
|
+
log(`🔒 --auto-fix 활성 (1.9.82) — 보안 신호 회복: audit --fix 자동 실행 중...`);
|
|
6462
|
+
try {
|
|
6463
|
+
const r = cp.spawnSync(process.execPath, [__filename, 'audit', root, '--fix'],
|
|
6464
|
+
{ encoding: 'utf8', timeout: 30000, env: { ...process.env, LEERNESS_NO_PROMPT: '1', LEERNESS_NO_DRIFT_CHECK: '1' } });
|
|
6465
|
+
if (r.status === 0) {
|
|
6466
|
+
log(`✓ audit --fix 완료 — .gitignore + .env.example 동기화`);
|
|
6467
|
+
// 재검사 (보안 신호 회복 확인)
|
|
6468
|
+
log('');
|
|
6469
|
+
log(`재검사 중...`);
|
|
6470
|
+
return driftCheckCmd(root); // 재귀 1회 (auto-fix 없이)
|
|
6471
|
+
} else {
|
|
6472
|
+
log(`⚠ audit --fix 실패 (exit ${r.status}) — 수동 \`leerness audit --fix\` 권장`);
|
|
6473
|
+
}
|
|
6474
|
+
} catch (e) {
|
|
6475
|
+
log(`⚠ auto-fix 보안 회복 오류: ${e.message}`);
|
|
6476
|
+
}
|
|
6477
|
+
}
|
|
6478
|
+
if (autoFix && level === '🔴 critical' && !hasSecurityFired) {
|
|
6457
6479
|
log('');
|
|
6458
6480
|
log(`🔧 --auto-fix 활성 — session close 자동 실행 중...`);
|
|
6459
6481
|
try {
|
|
@@ -7313,7 +7335,8 @@ function mcpServeCmd(root) {
|
|
|
7313
7335
|
{ name: 'leerness_lessons', description: '1.9.7/54 — 과거 결정·실수 자동 회수 (--auto: 현재 task 키워드 자동 추출)', inputSchema: { type: 'object', properties: { path: { type: 'string' }, query: { type: 'string' }, auto: { type: 'boolean' }, limit: { type: 'number' } } } },
|
|
7314
7336
|
{ name: 'leerness_task_export', description: '1.9.60/66 — leerness task → Claude Code TodoWrite 호환 JSON (외부 AI 양방향 sync)', inputSchema: { type: 'object', properties: { path: { type: 'string' }, to: { type: 'string' } } } },
|
|
7315
7337
|
{ name: 'leerness_env_check', description: '1.9.71/73 — .env vs .env.example 동기화 검사 (보안: 키만, 값 미노출). exit 1 if 누락 키 있음', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
|
|
7316
|
-
{ name: 'leerness_brainstorm', description: '1.9.16/72/77 — 누적 컨텍스트(decisions+skills+tasks+rules+evidence+lessons+skillHistory+taskLogFails) 자원 회수. 외부 AI가 새 작업 시작 전 호출', inputSchema: { type: 'object', properties: { topic: { type: 'string' }, path: { type: 'string' }, allApps: { type: 'boolean' } }, required: ['topic'] } }
|
|
7338
|
+
{ name: 'leerness_brainstorm', description: '1.9.16/72/77 — 누적 컨텍스트(decisions+skills+tasks+rules+evidence+lessons+skillHistory+taskLogFails) 자원 회수. 외부 AI가 새 작업 시작 전 호출', inputSchema: { type: 'object', properties: { topic: { type: 'string' }, path: { type: 'string' }, allApps: { type: 'boolean' } }, required: ['topic'] } },
|
|
7339
|
+
{ name: 'leerness_skill_match', description: '1.9.45/50/83 — 사용자 task 키워드에 매칭되는 설치된 skill 추천 (jaccard 또는 embedding). 1.9.68 rolling history 자동 누적', inputSchema: { type: 'object', properties: { query: { type: 'string' }, path: { type: 'string' }, useEmbedding: { type: 'boolean' } }, required: ['query'] } }
|
|
7317
7340
|
];
|
|
7318
7341
|
|
|
7319
7342
|
function send(obj) {
|
|
@@ -7360,6 +7383,7 @@ function mcpServeCmd(root) {
|
|
|
7360
7383
|
case 'leerness_task_export': cliArgs = ['task', 'export', '--path', targetPath, ...(args.to ? ['--to', args.to] : ['--json'])]; break;
|
|
7361
7384
|
case 'leerness_env_check': cliArgs = ['env', 'check', targetPath, '--json']; break;
|
|
7362
7385
|
case 'leerness_brainstorm': cliArgs = ['brainstorm', args.topic || '', '--path', targetPath, '--json', ...(args.allApps ? ['--all-apps'] : [])]; break;
|
|
7386
|
+
case 'leerness_skill_match': cliArgs = ['skill', 'match', args.query || '', '--path', targetPath, '--json', ...(args.useEmbedding ? ['--embedding'] : [])]; break;
|
|
7363
7387
|
default:
|
|
7364
7388
|
return send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Unknown tool: ${name}` } });
|
|
7365
7389
|
}
|