leerness 1.9.88 → 1.9.90
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 +48 -0
- package/README.md +4 -2
- package/bin/harness.js +47 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.90 — 2026-05-20
|
|
4
|
+
|
|
5
|
+
**`leerness skill search <capability>` 새 명령** — capability 배열 부분 일치 검색.
|
|
6
|
+
|
|
7
|
+
### Added — `leerness skill search`
|
|
8
|
+
- `leerness skill search "<capability>"` — capability 키워드로 skill 검색.
|
|
9
|
+
- substring + case-insensitive 매칭.
|
|
10
|
+
- `--json`: 구조화 출력 (`{ query, total, matches[] }`).
|
|
11
|
+
- skill match (jaccard 점수 매칭)과 다름:
|
|
12
|
+
- `skill match`: 자연어 task → 점수 기반 추천
|
|
13
|
+
- `skill search`: capability 필드에 정확히 키워드 포함된 skill만
|
|
14
|
+
- 예:
|
|
15
|
+
```
|
|
16
|
+
leerness skill search "API" → commerce-api
|
|
17
|
+
leerness skill search "검증" → firebase, ai-verified-skill-publisher
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Use Case
|
|
21
|
+
- "내가 이 능력을 가진 skill을 찾고 싶다" 명확한 의도에 사용.
|
|
22
|
+
- skill match가 너무 광범위할 때 capability로 좁히기.
|
|
23
|
+
|
|
24
|
+
### Verified
|
|
25
|
+
- stress-v36 — search 명령 + 부분 일치 + --json + 누적 회귀.
|
|
26
|
+
- e2e 219/219 PASS 유지.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1.9.89 — 2026-05-20
|
|
31
|
+
|
|
32
|
+
**자율 모드 19 라운드 종합 검증 + 마무리** (1.9.70 ~ 1.9.88).
|
|
33
|
+
|
|
34
|
+
### Verified — stress-v35 24/24 PASS
|
|
35
|
+
- 19 라운드 모든 핵심 기능 (R70~R88) 개별 검증
|
|
36
|
+
- MCP server 18 도구 노출 확인
|
|
37
|
+
- 성능 종합 측정:
|
|
38
|
+
- handoff (전체 통합) **692ms** / health **689ms** / audit 345ms / drift check 383ms
|
|
39
|
+
- 누적에도 회귀 없음 (절대 임계 모두 통과)
|
|
40
|
+
|
|
41
|
+
### Internal — 종합 보고서
|
|
42
|
+
- `_reports/AUTONOMOUS_ROUNDS_1.9.70-1.9.88.md` (비공개, 사용자 검토용)
|
|
43
|
+
- 19 라운드 그룹화: 보안 라인 / MCP 도구 / 학습·회고 / handoff 5단 통합
|
|
44
|
+
- 디버그 기록 6건 (모두 진단 + 수정 후 PASS)
|
|
45
|
+
|
|
46
|
+
### e2e
|
|
47
|
+
- **219/219 PASS** 유지
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
3
51
|
## 1.9.88 — 2026-05-20
|
|
4
52
|
|
|
5
53
|
**`handoff`에 brainstorm 자동 hits 노출** (1.9.72 brainstorm 통합).
|
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.90 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.90** — **`leerness skill search <capability>` 새 명령** — capability 배열 부분 일치 검색 (skill match와 다른 정확 매칭). `--json` 옵션.
|
|
437
|
+
- **1.9.89** — **자율 모드 19 라운드 종합 검증** — stress-v35 24/24 PASS + handoff 692ms / health 689ms (회귀 없음). 자율 모드 (1.9.70~88) 안정 완료.
|
|
436
438
|
- **1.9.88** — **`handoff`에 brainstorm 자동 hits 노출** — 현재 task 키워드로 자동 호출 → decisions / lessons / task-log fail / skill 미리보기 1줄씩 (1.9.72 brainstorm 통합).
|
|
437
439
|
- **1.9.87** — **`session-workflow.md` 템플릿 갱신** — 1.9.69~86 누적 신규 기능 안내 추가 (handoff history hit / 보안 요약 / CRITICAL / 헤드라인 / health / drift --auto-fix 보안 / MCP 18 도구). init 가이드 정확성 보장.
|
|
438
440
|
- **1.9.86** — **MCP server 18번째 도구 `leerness_health`** — 1.9.85 health 종합 헬스 체크를 외부 AI에 노출. drift + 보안 + skill + MCP + tasks 한 호출.
|
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.90';
|
|
10
10
|
const MARK = '<!-- leerness:managed -->';
|
|
11
11
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
12
12
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -3433,7 +3433,7 @@ function _banner(opts = {}) {
|
|
|
3433
3433
|
lines.push('');
|
|
3434
3434
|
for (const ln of lines) log(ln);
|
|
3435
3435
|
if (opts.quickStart) {
|
|
3436
|
-
log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.
|
|
3436
|
+
log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.90+ 워크플로)')));
|
|
3437
3437
|
log(' ' + C.green('npx leerness@latest init .') + C.dim(' # 신규 프로젝트 + 외부 AI CLI 설정'));
|
|
3438
3438
|
log(' ' + C.green('npx leerness handoff .') + C.dim(' # 컨텍스트 + lessons + 매칭 skill + 이전 history hit (1.9.69)'));
|
|
3439
3439
|
log(' ' + C.green('npx leerness skill match "<query>"') + C.dim(' # 매칭 skill + rolling history 자동 누적 (1.9.68)'));
|
|
@@ -7245,6 +7245,49 @@ function _cosine(a, b) {
|
|
|
7245
7245
|
return (na && nb) ? dot / (Math.sqrt(na) * Math.sqrt(nb)) : 0;
|
|
7246
7246
|
}
|
|
7247
7247
|
|
|
7248
|
+
// 1.9.90: leerness skill search <capability> — capability 배열에서 부분 일치 검색
|
|
7249
|
+
// skill match (jaccard)와 다름: capability 필드 정확 매칭 (substring + case-insensitive)
|
|
7250
|
+
function skillSearchCmd(root, capabilityQuery) {
|
|
7251
|
+
root = absRoot(root || process.cwd());
|
|
7252
|
+
if (!capabilityQuery) { fail('사용법: leerness skill search "<capability keyword>" [--json]'); return process.exit(1); }
|
|
7253
|
+
const all = listAllSkills(root);
|
|
7254
|
+
const q = capabilityQuery.toLowerCase();
|
|
7255
|
+
const matches = [];
|
|
7256
|
+
for (const [id, v] of Object.entries(all)) {
|
|
7257
|
+
const caps = v.capabilities || [];
|
|
7258
|
+
const matched = caps.filter(c => String(c).toLowerCase().includes(q));
|
|
7259
|
+
if (matched.length) {
|
|
7260
|
+
matches.push({
|
|
7261
|
+
id,
|
|
7262
|
+
displayNameKo: v.displayNameKo || id,
|
|
7263
|
+
source: v._source,
|
|
7264
|
+
matchedCapabilities: matched,
|
|
7265
|
+
allCapabilities: caps.length,
|
|
7266
|
+
usageCount: v.usage?.count || 0
|
|
7267
|
+
});
|
|
7268
|
+
}
|
|
7269
|
+
}
|
|
7270
|
+
if (has('--json')) {
|
|
7271
|
+
log(JSON.stringify({ query: capabilityQuery, total: matches.length, matches }, null, 2));
|
|
7272
|
+
return;
|
|
7273
|
+
}
|
|
7274
|
+
log(`# leerness skill search (1.9.90)`);
|
|
7275
|
+
log(`query (capability): "${capabilityQuery}"`);
|
|
7276
|
+
log(`전체 ${Object.keys(all).length}개 skill 중 매칭 ${matches.length}건`);
|
|
7277
|
+
log('');
|
|
7278
|
+
if (!matches.length) {
|
|
7279
|
+
log(' (해당 능력 없음 — 다른 키워드 시도 또는 \`leerness skill discover\`로 확장)');
|
|
7280
|
+
return;
|
|
7281
|
+
}
|
|
7282
|
+
log(`| ID | 한글명 | 매칭 능력 | 사용 |`);
|
|
7283
|
+
log(`|---|---|---|---:|`);
|
|
7284
|
+
for (const m of matches) {
|
|
7285
|
+
log(`| ${m.id} | ${m.displayNameKo} | ${m.matchedCapabilities.slice(0, 2).join(' / ')}${m.matchedCapabilities.length > 2 ? ' …' : ''} | ${m.usageCount}회 |`);
|
|
7286
|
+
}
|
|
7287
|
+
log('');
|
|
7288
|
+
log(`💡 상세: \`leerness skill info <id>\` · 사용 시작: \`leerness skill use <id>\``);
|
|
7289
|
+
}
|
|
7290
|
+
|
|
7248
7291
|
async function skillMatchCmd(root, query) {
|
|
7249
7292
|
root = absRoot(root || process.cwd());
|
|
7250
7293
|
if (!query) { fail('사용법: leerness skill match "<task or keywords>" [--embedding]'); return process.exit(1); }
|
|
@@ -8089,6 +8132,8 @@ async function main() {
|
|
|
8089
8132
|
if (cmd === 'skill' && args[1] === 'export') return skillExportCmd(absRoot(arg('--path', process.cwd())), args[2]);
|
|
8090
8133
|
if (cmd === 'skill' && args[1] === 'export-all') return skillExportAllCmd(absRoot(arg('--path', process.cwd())));
|
|
8091
8134
|
if (cmd === 'skill' && args[1] === 'match') return skillMatchCmd(absRoot(arg('--path', process.cwd())), args.slice(2).filter(x => !x.startsWith('-')).join(' '));
|
|
8135
|
+
// 1.9.90: leerness skill search <capability> — capability 키워드로 검색 (substring 정확 일치)
|
|
8136
|
+
if (cmd === 'skill' && args[1] === 'search') return skillSearchCmd(absRoot(arg('--path', process.cwd())), args.slice(2).filter(x => !x.startsWith('-')).join(' '));
|
|
8092
8137
|
if (cmd === 'benchmark') return benchmarkCmd(absRoot(args[1] || arg('--path', process.cwd())));
|
|
8093
8138
|
if (cmd === 'skill' && args[1] === 'publish') return skillPublishCmd(absRoot(arg('--path', process.cwd())));
|
|
8094
8139
|
if (cmd === 'skill' && args[1] === 'suggest') return skillSuggestCmd(absRoot(arg('--path', process.cwd())));
|