leerness 1.9.130 → 1.9.132

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 CHANGED
@@ -1,5 +1,57 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.132 — 2026-05-20
4
+
5
+ **session close 텍스트 모드에 archive 누적 라인 추가** — 마감 시점 DELETE 활동 가시화 (handoff archive 알림과 symmetric).
6
+
7
+ ### Added
8
+ - `leerness session close` 텍스트 모드에 1줄 archive 요약 추가:
9
+ ```
10
+ 🗑 archive 누적: D1/L1/P0 (2건) — 복원 후보: leerness memory archive list
11
+ ```
12
+ - 진행 요약 (session #N) 라인 바로 아래 출력
13
+ - archive 없으면 라인 비표시
14
+ - handoff 7번째 자동 회수 (1.9.129) 와 symmetric — 시작/마감 양쪽에서 archive 가시성
15
+
16
+ ### Archive 가시성 매트릭스 (1.9.132 시점)
17
+ | 명령 | 텍스트 | JSON |
18
+ |---|---|---|
19
+ | `handoff` | ✓ (1.9.129) | ✓ (1.9.130) |
20
+ | `session close` | **✓ (1.9.132)** | ✓ (1.9.130) |
21
+ | `memory status` | ✓ (1.9.130) | ✓ (1.9.130) |
22
+ | `health` | (N/A) | ✓ (1.9.130) |
23
+ | `memory archive list` | ✓ (1.9.127) | ✓ (1.9.127) |
24
+ | `brainstorm` | ✓ (1.9.131) | ✓ (1.9.131) |
25
+
26
+ ## 1.9.131 — 2026-05-20
27
+
28
+ **brainstorm 회수 범위에 3 archive 파일 통합** — 과거에 제거됐던 ideas 가 새 brainstorm 시 다시 후보로 노출.
29
+
30
+ ### Added — brainstorm + archive 통합
31
+ - `hits.archive: { decisions: [], lessons: [], plan: [] }` 추가
32
+ - 3 archive 파일 (`.harness/decisions.archive.md`, `lessons.archive.md`, `plan.archive.md`) 본문 키워드 매칭
33
+ - entry 구조: `{ date, target, originalHeader, preview, line }`
34
+ - 텍스트 모드: `🗑 archive 후보 (N)` 섹션 + 복원 안내 라인
35
+ - `_brainstormFor` (helper) + `brainstormCmd` (CLI) 양쪽 동일 구현
36
+
37
+ ### 사용 시나리오
38
+ 사용자: `leerness brainstorm "PostgreSQL"`
39
+ → 응답에 과거 archive 후보 포함:
40
+ ```
41
+ 🗑 archive 후보 (2) — 과거에 제거됐던 ideas; 복원 검토 가능 (1.9.131)
42
+ - 🧠 .harness/decisions.archive.md:4 — 2026-05-20 "PostgreSQL"
43
+ - 💡 .harness/lessons.archive.md:4 — 2026-05-20 "PostgreSQL"
44
+ → 복원: leerness memory restore <decisions|lessons|plan> <target>
45
+ ```
46
+
47
+ ### brainstorm 누적 source 진화
48
+ | 라운드 | source |
49
+ |---|---|
50
+ | (기존) | decisions / skills / tasks / rules / evidence / lessons / code |
51
+ | 1.9.72 | skillHistory / taskLogFails |
52
+ | 1.9.116 | lessonsExplicit / planMilestones |
53
+ | **1.9.131** | **archive (decisions/lessons/plan)** |
54
+
3
55
  ## 1.9.130 — 2026-05-20 🎉 **60 라운드 자율 모드 마일스톤**
4
56
 
5
57
  **JSON 4종 통합에 `memorySurface.archive` 필드 추가** + 60 라운드 자율 누적 보고서.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **AI 코딩 에이전트의 거짓 완료·중복·망각·충돌을 막아주는 검수·기억·협업 CLI 하네스.**
4
4
 
5
- [![npm](https://img.shields.io/badge/npm-leerness-blue)](https://www.npmjs.com/package/leerness) [![version](https://img.shields.io/badge/version-1.9.130-green)]() [![tests](https://img.shields.io/badge/e2e-219%2F219-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-40_🎉-blue)]() [![json](https://img.shields.io/badge/--json-19_commands-blueviolet)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-60_🎉-blueviolet)]() [![handoff](https://img.shields.io/badge/handoff--auto--recovery-7-blueviolet)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
5
+ [![npm](https://img.shields.io/badge/npm-leerness-blue)](https://www.npmjs.com/package/leerness) [![version](https://img.shields.io/badge/version-1.9.132-green)]() [![tests](https://img.shields.io/badge/e2e-219%2F219-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-40_🎉-blue)]() [![json](https://img.shields.io/badge/--json-19_commands-blueviolet)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-62-blueviolet)]() [![archive](https://img.shields.io/badge/archive--visibility-6_surfaces-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
6
6
 
7
7
  ```
8
8
  ╔══════════════════════════════════════════════════════════════╗
@@ -12,7 +12,7 @@
12
12
  ║ ██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║ ║
13
13
  ║ ███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║ ║
14
14
  ║ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝ ║
15
- ║ v1.9.130 AI Agent Reliability Harness ║
15
+ ║ v1.9.132 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.130';
9
+ const VERSION = '1.9.132';
10
10
  const MARK = '<!-- leerness:managed -->';
11
11
  const README_START = '<!-- leerness:project-readme:start -->';
12
12
  const README_END = '<!-- leerness:project-readme:end -->';
@@ -331,6 +331,8 @@ leerness audit . --fix # 누락 메타 자동 보강
331
331
  - 1.9.128+ \`leerness memory restore <surface> <target>\` + MCP **40 도구 🎉** (\`leerness_memory_restore\`) — archive → active 복귀 (DELETE→RESTORE cycle 완성). **MCP 40 도구 마일스톤**.
332
332
  - 1.9.129+ handoff **7번째 자동 회수** — \`🗑 최근 24h archive\` (D/L/P 카운트 + 복원 후보 안내). DELETE 활동 자동 인지.
333
333
  - 1.9.130+ 🎉 **60 라운드 자율 모드 마일스톤** — JSON 4종 (handoff/memory status/session close/health) \`memorySurface.archive\` 필드 통합. MCP 40 / handoff auto-recovery 7 / DELETE-RESTORE cycle 완성.
334
+ - 1.9.131+ \`brainstorm\` 회수 범위에 3 archive 파일 (decisions/lessons/plan archive) 통합 — 과거 제거된 ideas 가 새 brainstorm 시 다시 후보로 노출. \`hits.archive\` 필드 + 복원 안내 라인.
335
+ - 1.9.132+ \`session close\` 텍스트 모드에 archive 누적 라인 추가 — 마감 시점 DELETE 활동 가시화 (handoff 7번째 회수와 symmetric). archive 가시성 6 surface 완성.
334
336
 
335
337
  ---
336
338
 
@@ -4268,7 +4270,7 @@ function _banner(opts = {}) {
4268
4270
  lines.push('');
4269
4271
  for (const ln of lines) log(ln);
4270
4272
  if (opts.quickStart) {
4271
- log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.130+ 🎉 60 라운드 마일스톤 archive 필드 통합 60 라운드 자율 누적)')));
4273
+ log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.132+ session close archive 라인62 라운드 자율 누적)')));
4272
4274
  log(' ' + C.green('npx leerness@latest init .') + C.dim(' # 신규 프로젝트 + 외부 AI CLI 설정'));
4273
4275
  log(' ' + C.green('npx leerness handoff .') + C.dim(' # 컨텍스트 + lessons + 매칭 skill + history hit + brainstorm hits + 헤드라인'));
4274
4276
  log(' ' + C.green('npx leerness handoff . --quiet') + C.dim(' # 자동화/CI 모드 (1.9.99) — 자동 회수 라인 비활성'));
@@ -5135,6 +5137,22 @@ function sessionClose(root, opts = {}) {
5135
5137
  const agg = _retroAggregate(root);
5136
5138
  log(`\n## 📈 진행 요약 (session #${sc.count})`);
5137
5139
  log(` ${_retroOneLine(agg)}`);
5140
+ // 1.9.132: archive 활동 1줄 요약 — 마감 시점에 DELETE 활동 가시화 (handoff 7번째 회수와 symmetric)
5141
+ try {
5142
+ const hdSC = path.join(root, '.harness');
5143
+ const arc = { d: 0, l: 0, p: 0, total: 0 };
5144
+ for (const [k, f] of [['d', 'decisions.archive.md'], ['l', 'lessons.archive.md'], ['p', 'plan.archive.md']]) {
5145
+ const fp = path.join(hdSC, f);
5146
+ if (exists(fp)) {
5147
+ const entries = _parseArchiveBlocks(read(fp));
5148
+ arc[k] = entries.length;
5149
+ arc.total += entries.length;
5150
+ }
5151
+ }
5152
+ if (arc.total > 0) {
5153
+ log(` 🗑 archive 누적: D${arc.d}/L${arc.l}/P${arc.p} (${arc.total}건) — 복원 후보: leerness memory archive list`);
5154
+ }
5155
+ } catch {}
5138
5156
  if (sc.count % 5 === 0) {
5139
5157
  log(`\n## 🔄 ${sc.count}세션 마일스톤 — 자동 회고 (5세션마다)`);
5140
5158
  retroCmd(root);
@@ -5713,6 +5731,36 @@ function _brainstormFor(root, topic) {
5713
5731
  }
5714
5732
  }
5715
5733
  }
5734
+ // 1.9.131: 3 archive 파일 (decisions/lessons/plan) hits — DELETE 5종 archive 도 brainstorm 후보로
5735
+ // archived ideas 가 새 brainstorm 시점에 다시 후보로 노출 → "이전에 검토한 건데 다시 볼까?"
5736
+ hits.archive = { decisions: [], lessons: [], plan: [] };
5737
+ const archiveSources_bsFor = [
5738
+ { key: 'decisions', file: 'decisions.archive.md' },
5739
+ { key: 'lessons', file: 'lessons.archive.md' },
5740
+ { key: 'plan', file: 'plan.archive.md' }
5741
+ ];
5742
+ for (const src of archiveSources_bsFor) {
5743
+ const fp = path.join(root, '.harness', src.file);
5744
+ if (!exists(fp)) continue;
5745
+ const txt = read(fp);
5746
+ const blocks = txt.split(/\n(?=## 제거 )/);
5747
+ for (const b of blocks) {
5748
+ const m = b.match(/^## 제거 (\d{4}-\d{2}-\d{2})\s*\(target:\s*"([^"]*)"\)/);
5749
+ if (!m) continue;
5750
+ if (matches(b)) {
5751
+ const headerMatch = b.match(/^### (.+)$/m);
5752
+ const idx = txt.indexOf(b);
5753
+ const lineNo = idx >= 0 ? txt.slice(0, idx).split('\n').length : 0;
5754
+ hits.archive[src.key].push({
5755
+ date: m[1],
5756
+ target: m[2],
5757
+ originalHeader: headerMatch ? headerMatch[1].trim() : null,
5758
+ preview: b.slice(0, 220).replace(/\n+/g, ' '),
5759
+ line: lineNo
5760
+ });
5761
+ }
5762
+ }
5763
+ }
5716
5764
  // 1.9.25: --include-code 옵션 — 소스 본문 검색 추가 (모순 감지 핵심)
5717
5765
  if (has('--include-code')) {
5718
5766
  const codeDirs = ['src', 'tests', 'bin', 'lib'];
@@ -5908,6 +5956,35 @@ function brainstormCmd(root, topic) {
5908
5956
  }
5909
5957
  }
5910
5958
  }
5959
+ // 1.9.131: 3 archive 파일 hits (brainstormCmd 변종) — DELETE 5종 archive 도 brainstorm 후보로
5960
+ if (!hits.archive) hits.archive = { decisions: [], lessons: [], plan: [] };
5961
+ const archiveSources_bsCmd = [
5962
+ { key: 'decisions', file: 'decisions.archive.md' },
5963
+ { key: 'lessons', file: 'lessons.archive.md' },
5964
+ { key: 'plan', file: 'plan.archive.md' }
5965
+ ];
5966
+ for (const src of archiveSources_bsCmd) {
5967
+ const fp = path.join(root, '.harness', src.file);
5968
+ if (!exists(fp)) continue;
5969
+ const txt = read(fp);
5970
+ const blocks = txt.split(/\n(?=## 제거 )/);
5971
+ for (const b of blocks) {
5972
+ const m = b.match(/^## 제거 (\d{4}-\d{2}-\d{2})\s*\(target:\s*"([^"]*)"\)/);
5973
+ if (!m) continue;
5974
+ if (matches(b)) {
5975
+ const headerMatch = b.match(/^### (.+)$/m);
5976
+ const idx = txt.indexOf(b);
5977
+ const lineNo = idx >= 0 ? txt.slice(0, idx).split('\n').length : 0;
5978
+ hits.archive[src.key].push({
5979
+ date: m[1],
5980
+ target: m[2],
5981
+ originalHeader: headerMatch ? headerMatch[1].trim() : null,
5982
+ preview: b.slice(0, 220).replace(/\n+/g, ' '),
5983
+ line: lineNo
5984
+ });
5985
+ }
5986
+ }
5987
+ }
5911
5988
  // 1.9.116: lessons.md + plan.md milestone hits (Memory Surface 5종 완전 통합)
5912
5989
  if (!hits.lessonsExplicit) hits.lessonsExplicit = [];
5913
5990
  if (!hits.planMilestones) hits.planMilestones = [];
@@ -5976,6 +6053,22 @@ function brainstormCmd(root, topic) {
5976
6053
  log(`\n## 📜 task-log 실패 라인 (${hits.taskLogFails.length}) — 1.9.67 인덱스 + brainstorm`);
5977
6054
  hits.taskLogFails.slice(0, 5).forEach(t => log(` - .harness/task-log.md:${t.line || '?'} — ${t.title}`));
5978
6055
  }
6056
+ // 1.9.131: 3 archive 파일 hits — DELETE 5종 archive 도 brainstorm 후보
6057
+ if (hits.archive) {
6058
+ const archiveTotal = (hits.archive.decisions?.length || 0) + (hits.archive.lessons?.length || 0) + (hits.archive.plan?.length || 0);
6059
+ if (archiveTotal > 0) {
6060
+ log(`\n## 🗑 archive 후보 (${archiveTotal}) — 과거에 제거됐던 ideas; 복원 검토 가능 (1.9.131)`);
6061
+ for (const [key, label, emoji] of [['decisions', 'decisions.archive.md', '🧠'], ['lessons', 'lessons.archive.md', '💡'], ['plan', 'plan.archive.md', '🗺']]) {
6062
+ const items = hits.archive[key] || [];
6063
+ if (items.length) {
6064
+ for (const a of items.slice(0, 3)) {
6065
+ log(` - ${emoji} .harness/${label}:${a.line || '?'} — ${a.date} "${a.target}"${a.originalHeader ? ' (orig: ' + a.originalHeader.slice(0, 80) + ')' : ''}`);
6066
+ }
6067
+ }
6068
+ }
6069
+ log(` → 복원: leerness memory restore <decisions|lessons|plan> <target>`);
6070
+ }
6071
+ }
5979
6072
 
5980
6073
  log(`\n## 💡 시작 전 권장 액션`);
5981
6074
  log(` 1. 위 자원을 모두 검토 후 plan add 또는 task add로 새 작업 등록`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.130",
3
+ "version": "1.9.132",
4
4
  "description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
5
5
  "keywords": [
6
6
  "leerness",