leerness 1.9.136 → 1.9.138
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 +35 -0
- package/README.md +2 -2
- package/bin/harness.js +46 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.138 — 2026-05-20
|
|
4
|
+
|
|
5
|
+
**`leerness memory archive list --query <keyword>` 필터 추가** — archive 항목 키워드 검색.
|
|
6
|
+
|
|
7
|
+
### Added — --query 필터
|
|
8
|
+
- `target` 또는 `originalHeader` 에 키워드 case-insensitive 매칭
|
|
9
|
+
- 정규식 특수문자는 자동 escape
|
|
10
|
+
- 텍스트 모드 헤더에 `— query: "..."` 표시
|
|
11
|
+
- JSON 모드 응답에 `query` 필드 추가
|
|
12
|
+
- 매칭 0건 시 안내 메시지
|
|
13
|
+
|
|
14
|
+
### Updated — MCP leerness_memory_archive_list
|
|
15
|
+
- 신규 인자: `{ query? }` (optional)
|
|
16
|
+
- 외부 AI 가 archive 에서 특정 주제 항목만 회수 가능
|
|
17
|
+
|
|
18
|
+
### 사용 시나리오
|
|
19
|
+
```
|
|
20
|
+
leerness memory archive list --query PostgreSQL --json
|
|
21
|
+
# → decisions/lessons/plan 중 PostgreSQL 매칭만 반환
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 1.9.137 — 2026-05-20
|
|
25
|
+
|
|
26
|
+
**`.harness/session-workflow.md` 템플릿 갱신 — Memory CRUD Quick Reference 추가** — 신규 \`init\` 워크스페이스의 AI 에이전트에 5 surface CRUD 매트릭스 + archive cycle 가이드 제공.
|
|
27
|
+
|
|
28
|
+
### Updated — session-workflow.md
|
|
29
|
+
- Step 6 (세션 마감) 뒤에 **🧠 Memory CRUD Quick Reference** 섹션 추가
|
|
30
|
+
- 5 surface (tasks/decisions/lessons/plan/rules) × CRUD ops 표
|
|
31
|
+
- archive cycle workflow 3 단계 예시
|
|
32
|
+
- DELETE→RESTORE 복구 사용 시나리오
|
|
33
|
+
|
|
34
|
+
### 영향
|
|
35
|
+
- 신규 `leerness init` 워크스페이스: 새 템플릿 적용
|
|
36
|
+
- 기존 워크스페이스: `leerness audit --fix` 으로 갱신 가능
|
|
37
|
+
|
|
3
38
|
## 1.9.136 — 2026-05-20
|
|
4
39
|
|
|
5
40
|
**MCP `leerness_drift_check` JSON 응답 fix** — drift check CLI 는 `--json` 옵션을 지원하지만 MCP 라우팅이 plain 텍스트를 반환하던 버그 fix.
|
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.138 AI Agent Reliability Harness ║
|
|
16
16
|
║ verify · remember · orchestrate · audit · prevent drift ║
|
|
17
17
|
╚══════════════════════════════════════════════════════════════╝
|
|
18
18
|
```
|
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.138';
|
|
10
10
|
const MARK = '<!-- leerness:managed -->';
|
|
11
11
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
12
12
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -286,6 +286,31 @@ leerness skill suggest . # 1.9.53 — 반복 패턴 → 새 skill
|
|
|
286
286
|
leerness drift check . # 4 신호 + 4 레벨 점검
|
|
287
287
|
leerness audit . --fix # 누락 메타 자동 보강
|
|
288
288
|
\`\`\`
|
|
289
|
+
|
|
290
|
+
## 🧠 Memory CRUD Quick Reference (1.9.107~135)
|
|
291
|
+
|
|
292
|
+
5 Memory Surface 모두 CRUD CLI + MCP 노출 완성:
|
|
293
|
+
|
|
294
|
+
| Surface | CREATE | READ | DELETE | RESTORE |
|
|
295
|
+
|---|---|---|---|---|
|
|
296
|
+
| **tasks** | task add | task list --json (1.9.134) | task drop | task update |
|
|
297
|
+
| **decisions** | decision add | decision list --json | decision drop | memory restore decisions |
|
|
298
|
+
| **lessons** | lesson save | lesson list [--tag] | lesson drop | memory restore lessons |
|
|
299
|
+
| **plan** | plan add | plan list --json | plan remove | memory restore plan |
|
|
300
|
+
| **rules** | rule add | rule list --json | rule remove | (rule pause/resume) |
|
|
301
|
+
|
|
302
|
+
\`\`\`bash
|
|
303
|
+
leerness memory status [--json] # 5종 상태 통합 조회 (T/D/R/P/L 카운트)
|
|
304
|
+
leerness memory archive list [--surface s] # DELETE archive 통합 조회 (복원 후보)
|
|
305
|
+
leerness memory restore <surface> <target> # archive → active 복귀 (DELETE→RESTORE cycle, 1.9.128)
|
|
306
|
+
\`\`\`
|
|
307
|
+
|
|
308
|
+
**잘못 저장한 항목 복구**:
|
|
309
|
+
1. \`memory archive list\` — 복원 후보 확인
|
|
310
|
+
2. \`memory restore decisions "PostgreSQL"\` — archive → active
|
|
311
|
+
3. handoff 가 매 세션 자동으로 24h 내 archive 활동 알림 (1.9.129)
|
|
312
|
+
|
|
313
|
+
|
|
289
314
|
- session close가 누락되면 다음 세션 시작 시 drift critical 발생.
|
|
290
315
|
- 자동 회복 옵션: \`drift check --auto-fix\` (critical 시 session close 자동 실행).
|
|
291
316
|
- 1.9.56+ handoff가 매 세션 시작 시 **과거 lessons 자동 재상기** (현재 task 키워드 기준).
|
|
@@ -337,6 +362,8 @@ leerness audit . --fix # 누락 메타 자동 보강
|
|
|
337
362
|
- 1.9.134+ \`leerness task list --json\` + MCP **41 도구** (\`leerness_task_list\`) — progress-tracker.md task 전체 JSON 조회 + \`--status\` 필터. Task surface CRUD MCP 완전 완성 (add/list/update/drop).
|
|
338
363
|
- 1.9.135+ MCP **42 도구** (\`leerness_rule_remove\`) — rules.md 에서 특정 rule 제거 + archive 보존. **5 surface CRUD MCP 완전 완성** (task/decision/lesson/plan/rule 모두 add/list/delete MCP 노출).
|
|
339
364
|
- 1.9.136+ MCP \`leerness_drift_check\` JSON 응답 fix — \`--json\` 플래그 자동 추가하여 외부 AI가 구조화된 drift 신호 회수 (score, level, signals[], healthy).
|
|
365
|
+
- 1.9.137+ \`.harness/session-workflow.md\` 템플릿에 **🧠 Memory CRUD Quick Reference** 섹션 추가 — 5 surface × CRUD 매트릭스 + archive cycle 워크플로 가이드. 신규 \`init\` 워크스페이스 즉시 적용.
|
|
366
|
+
- 1.9.138+ \`leerness memory archive list --query <keyword>\` + MCP \`leerness_memory_archive_list\` query 인자 — archive 항목 키워드 case-insensitive 검색 (target/originalHeader 매칭).
|
|
340
367
|
|
|
341
368
|
---
|
|
342
369
|
|
|
@@ -1521,6 +1548,9 @@ function memoryArchiveListCmd(root, opts = {}) {
|
|
|
1521
1548
|
root = absRoot(root);
|
|
1522
1549
|
const jsonMode = !!opts.json || has('--json');
|
|
1523
1550
|
const surfaceFilter = arg('--surface', '');
|
|
1551
|
+
// 1.9.138: --query 키워드 필터 (target / originalHeader 매칭, case-insensitive)
|
|
1552
|
+
const queryFilter = arg('--query', '');
|
|
1553
|
+
const queryRe = queryFilter ? new RegExp(queryFilter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i') : null;
|
|
1524
1554
|
const hd = path.join(root, '.harness');
|
|
1525
1555
|
const archives = {
|
|
1526
1556
|
decisions: { path: path.join(hd, 'decisions.archive.md'), entries: [] },
|
|
@@ -1530,7 +1560,14 @@ function memoryArchiveListCmd(root, opts = {}) {
|
|
|
1530
1560
|
for (const k of Object.keys(archives)) {
|
|
1531
1561
|
if (surfaceFilter && surfaceFilter !== k) continue;
|
|
1532
1562
|
const a = archives[k];
|
|
1533
|
-
if (exists(a.path))
|
|
1563
|
+
if (exists(a.path)) {
|
|
1564
|
+
let entries = _parseArchiveBlocks(read(a.path));
|
|
1565
|
+
// 1.9.138: --query 필터 적용 (target 또는 originalHeader 매칭)
|
|
1566
|
+
if (queryRe) {
|
|
1567
|
+
entries = entries.filter(e => queryRe.test(e.target || '') || queryRe.test(e.originalHeader || ''));
|
|
1568
|
+
}
|
|
1569
|
+
a.entries = entries;
|
|
1570
|
+
}
|
|
1534
1571
|
}
|
|
1535
1572
|
const totals = {
|
|
1536
1573
|
decisions: archives.decisions.entries.length,
|
|
@@ -1546,12 +1583,14 @@ function memoryArchiveListCmd(root, opts = {}) {
|
|
|
1546
1583
|
plan: archives.plan.entries,
|
|
1547
1584
|
totals
|
|
1548
1585
|
};
|
|
1586
|
+
if (queryFilter) payload.query = queryFilter;
|
|
1587
|
+
if (surfaceFilter) payload.surface = surfaceFilter;
|
|
1549
1588
|
process.stdout.write(JSON.stringify(payload, null, 2) + '\n');
|
|
1550
1589
|
return;
|
|
1551
1590
|
}
|
|
1552
|
-
log('# 🗑 Memory Archive List (1.9.127)\n');
|
|
1591
|
+
log('# 🗑 Memory Archive List (1.9.127)' + (queryFilter ? ` — query: "${queryFilter}"` : '') + '\n');
|
|
1553
1592
|
if (totals.all === 0) {
|
|
1554
|
-
log('(archive 파일 없음 — 아직 제거된 항목 없음)');
|
|
1593
|
+
log(queryFilter ? `(매칭 archive entry 없음 — query: "${queryFilter}")` : '(archive 파일 없음 — 아직 제거된 항목 없음)');
|
|
1555
1594
|
return;
|
|
1556
1595
|
}
|
|
1557
1596
|
if ((!surfaceFilter || surfaceFilter === 'decisions') && archives.decisions.entries.length) {
|
|
@@ -4295,7 +4334,7 @@ function _banner(opts = {}) {
|
|
|
4295
4334
|
lines.push('');
|
|
4296
4335
|
for (const ln of lines) log(ln);
|
|
4297
4336
|
if (opts.quickStart) {
|
|
4298
|
-
log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.
|
|
4337
|
+
log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.138+ archive list --query 필터 — 68 라운드 자율 누적)')));
|
|
4299
4338
|
log(' ' + C.green('npx leerness@latest init .') + C.dim(' # 신규 프로젝트 + 외부 AI CLI 설정'));
|
|
4300
4339
|
log(' ' + C.green('npx leerness handoff .') + C.dim(' # 컨텍스트 + lessons + 매칭 skill + history hit + brainstorm hits + 헤드라인'));
|
|
4301
4340
|
log(' ' + C.green('npx leerness handoff . --quiet') + C.dim(' # 자동화/CI 모드 (1.9.99) — 자동 회수 라인 비활성'));
|
|
@@ -8611,7 +8650,7 @@ function mcpServeCmd(root) {
|
|
|
8611
8650
|
{ name: 'leerness_lesson_drop', description: '1.9.124 — lessons.md 에서 특정 lesson 제거 (target: date YYYY-MM-DD 또는 text substring). 잘못 저장한 lesson 제거. 제거된 블록은 .harness/lessons.archive.md 에 자동 보존 (복구 가능)', inputSchema: { type: 'object', properties: { target: { type: 'string' }, path: { type: 'string' } }, required: ['target'] } },
|
|
8612
8651
|
{ name: 'leerness_decision_drop', description: '1.9.125 — decisions.md 에서 특정 결정 제거 (target: date YYYY-MM-DD 또는 title substring). 제거된 블록은 .harness/decisions.archive.md 에 자동 보존', inputSchema: { type: 'object', properties: { target: { type: 'string' }, path: { type: 'string' } }, required: ['target'] } },
|
|
8613
8652
|
{ name: 'leerness_plan_remove', description: '1.9.126 — plan.md 에서 특정 milestone 블록 (### M-XXXX) 제거 (target: M-XXXX 또는 title substring). 제거된 블록은 .harness/plan.archive.md 에 자동 보존. Memory Surface DELETE 5종 완전 완성', inputSchema: { type: 'object', properties: { target: { type: 'string' }, path: { type: 'string' } }, required: ['target'] } },
|
|
8614
|
-
{ name: 'leerness_memory_archive_list', description: '1.9.127 — DELETE 5종 archive 파일 통합 조회 JSON ({ decisions: [], lessons: [], plan: [], totals: { decisions, lessons, plan, all } }). 외부 AI가 과거에 제거된 항목을 회수/복원 후보로 참조. --surface 필터: decisions|lessons|plan', inputSchema: { type: 'object', properties: { surface: { type: 'string' }, path: { type: 'string' } } } },
|
|
8653
|
+
{ name: 'leerness_memory_archive_list', description: '1.9.127 — DELETE 5종 archive 파일 통합 조회 JSON ({ decisions: [], lessons: [], plan: [], totals: { decisions, lessons, plan, all } }). 외부 AI가 과거에 제거된 항목을 회수/복원 후보로 참조. --surface 필터: decisions|lessons|plan. 1.9.138+ --query 키워드 필터 (target/originalHeader case-insensitive 매칭)', inputSchema: { type: 'object', properties: { surface: { type: 'string' }, query: { type: 'string' }, path: { type: 'string' } } } },
|
|
8615
8654
|
{ name: 'leerness_memory_restore', description: '1.9.128 — archive 의 항목을 active 파일로 복귀 (DELETE→RESTORE cycle). surface: decisions|lessons|plan. target: date YYYY-MM-DD 또는 target substring 매칭. 복원된 블록은 archive 에서 제거됨. 🎉 MCP 40 도구 마일스톤', inputSchema: { type: 'object', properties: { surface: { type: 'string', enum: ['decisions', 'lessons', 'plan'] }, target: { type: 'string' }, path: { type: 'string' } }, required: ['surface', 'target'] } },
|
|
8616
8655
|
{ name: 'leerness_task_list', description: '1.9.134 — progress-tracker.md 전체 task 조회 JSON ({ total, tasks: [{ id, status, request, evidence, nextAction, updated }] }). --status 필터 지원 (planned|in-progress|done 등). 외부 AI가 task 상태 회수', inputSchema: { type: 'object', properties: { path: { type: 'string' }, status: { type: 'string' } } } },
|
|
8617
8656
|
{ name: 'leerness_rule_remove', description: '1.9.135 — rules.md 에서 특정 rule 제거 (id: R-XXXX). 제거된 rule 은 .harness/rules.archive.md 에 자동 보존 (복구 가능). Rule surface CRUD MCP 완성 (add/list/remove)', inputSchema: { type: 'object', properties: { id: { type: 'string' }, path: { type: 'string' } }, required: ['id'] } }
|
|
@@ -8684,7 +8723,7 @@ function mcpServeCmd(root) {
|
|
|
8684
8723
|
case 'leerness_lesson_drop': cliArgs = ['lesson', 'drop', String(args.target || ''), '--path', targetPath]; break;
|
|
8685
8724
|
case 'leerness_decision_drop': cliArgs = ['decision', 'drop', String(args.target || ''), '--path', targetPath]; break;
|
|
8686
8725
|
case 'leerness_plan_remove': cliArgs = ['plan', 'remove', String(args.target || ''), '--path', targetPath]; break;
|
|
8687
|
-
case 'leerness_memory_archive_list': cliArgs = ['memory', 'archive', 'list', '--path', targetPath, '--json', ...(args.surface ? ['--surface', args.surface] : [])]; break;
|
|
8726
|
+
case 'leerness_memory_archive_list': cliArgs = ['memory', 'archive', 'list', '--path', targetPath, '--json', ...(args.surface ? ['--surface', args.surface] : []), ...(args.query ? ['--query', args.query] : [])]; break;
|
|
8688
8727
|
case 'leerness_memory_restore': cliArgs = ['memory', 'restore', String(args.surface || ''), String(args.target || ''), '--path', targetPath]; break;
|
|
8689
8728
|
case 'leerness_task_list': cliArgs = ['task', 'list', '--path', targetPath, '--json', ...(args.status ? ['--status', args.status] : [])]; break;
|
|
8690
8729
|
case 'leerness_rule_remove': cliArgs = ['rule', 'remove', String(args.id || ''), '--path', targetPath]; break;
|