leerness 1.9.129 β†’ 1.9.130

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,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.130 β€” 2026-05-20 πŸŽ‰ **60 λΌμš΄λ“œ 자율 λͺ¨λ“œ λ§ˆμΌμŠ€ν†€**
4
+
5
+ **JSON 4μ’… 톡합에 `memorySurface.archive` ν•„λ“œ μΆ”κ°€** + 60 λΌμš΄λ“œ 자율 λˆ„μ  λ³΄κ³ μ„œ.
6
+
7
+ ### Added β€” archive ν•„λ“œ (JSON 4μ’…)
8
+ - `handoff --json` / `memory status --json` / `session close --json` / `health --json` λͺ¨λ‘ `memorySurface.archive: { decisions, lessons, plan, total }` λ…ΈμΆœ
9
+ - `memory status` ν…μŠ€νŠΈ λͺ¨λ“œ: `πŸ—‘ Archive: D1/L1/P0 (2건)` 라인 μΆ”κ°€
10
+ - μ™ΈλΆ€ AI κ°€ ν•œ JSON 호좜둜 λͺ¨λ“  λ©”λͺ¨λ¦¬ μƒνƒœ (active + archive) λ™μ‹œ 회수
11
+
12
+ ### 60 λΌμš΄λ“œ λ§ˆμΌμŠ€ν†€
13
+ - λΌμš΄λ“œ: 60 (1.9.70 β†’ 1.9.130)
14
+ - MCP 도ꡬ: 11 β†’ **40 πŸŽ‰** (1.9.128 λ§ˆμΌμŠ€ν†€)
15
+ - --json λͺ…λ Ή: 6 β†’ **19**
16
+ - handoff μžλ™ 회수: 1 β†’ **7**
17
+ - Memory Surface: WRITE 5 + READ 5 + DELETE 5 + RESTORE 3 + Archive 3
18
+ - stress μ‹œλ‚˜λ¦¬μ˜€: v16 β†’ v74 (58 μΆ”κ°€)
19
+ - e2e: μ•ˆμ • 219/219
20
+
21
+ 상세: `_reports/AUTONOMOUS_ROUNDS_60_MILESTONE.md` (λΉ„κ³΅κ°œ)
22
+
3
23
  ## 1.9.129 β€” 2026-05-20
4
24
 
5
25
  **handoff 7번째 μžλ™ 회수 β€” πŸ—‘ 졜근 24h archive μ•Œλ¦Ό** β€” DELETE 5μ’… archive ν™œλ™μ„ λ§€ μ„Έμ…˜ μ‹œμž‘ μ‹œ μžλ™ λ…ΈμΆœ.
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.129-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-59-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.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)]()
6
6
 
7
7
  ```
8
8
  ╔══════════════════════════════════════════════════════════════╗
@@ -12,7 +12,7 @@
12
12
  β•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β•šβ•β•β•β•β–ˆβ–ˆβ•‘ β•‘
13
13
  β•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β•‘
14
14
  β•‘ β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β• β•‘
15
- β•‘ v1.9.129 AI Agent Reliability Harness β•‘
15
+ β•‘ v1.9.130 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.129';
9
+ const VERSION = '1.9.130';
10
10
  const MARK = '<!-- leerness:managed -->';
11
11
  const README_START = '<!-- leerness:project-readme:start -->';
12
12
  const README_END = '<!-- leerness:project-readme:end -->';
@@ -330,6 +330,7 @@ leerness audit . --fix # λˆ„λ½ 메타 μžλ™ 보강
330
330
  - 1.9.127+ \`leerness memory archive list [--surface decisions|lessons|plan] [--json]\` + MCP **39 도ꡬ** (\`leerness_memory_archive_list\`) β€” DELETE 5μ’… archive 톡합 쑰회 (볡원 후보 회수).
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
+ - 1.9.130+ πŸŽ‰ **60 λΌμš΄λ“œ 자율 λͺ¨λ“œ λ§ˆμΌμŠ€ν†€** β€” JSON 4μ’… (handoff/memory status/session close/health) \`memorySurface.archive\` ν•„λ“œ 톡합. MCP 40 / handoff auto-recovery 7 / DELETE-RESTORE cycle μ™„μ„±.
333
334
 
334
335
  ---
335
336
 
@@ -1425,6 +1426,19 @@ function memoryStatusCmd(root, opts = {}) {
1425
1426
  const lm = exists(lessonsPath(root)) ? read(lessonsPath(root)) : '';
1426
1427
  const lessonHeaders = lm.match(/^### \d{4}-\d{2}-\d{2}[^\n]*/gm) || [];
1427
1428
  const lessonsLatest = lessonHeaders.length ? (lm.split('\n').filter(l => /- Lesson:/.test(l)).pop() || '').replace(/^- Lesson:\s*/, '').slice(0, 100) : null;
1429
+ // 1.9.130: DELETE 5μ’… archive entry counts
1430
+ const archiveCounts = { decisions: 0, lessons: 0, plan: 0, total: 0 };
1431
+ try {
1432
+ const hd = path.join(root, '.harness');
1433
+ for (const [key, file] of [['decisions', 'decisions.archive.md'], ['lessons', 'lessons.archive.md'], ['plan', 'plan.archive.md']]) {
1434
+ const fp = path.join(hd, file);
1435
+ if (exists(fp)) {
1436
+ const entries = _parseArchiveBlocks(read(fp));
1437
+ archiveCounts[key] = entries.length;
1438
+ archiveCounts.total += entries.length;
1439
+ }
1440
+ }
1441
+ } catch {}
1428
1442
 
1429
1443
  const payload = {
1430
1444
  version: VERSION,
@@ -1434,6 +1448,7 @@ function memoryStatusCmd(root, opts = {}) {
1434
1448
  rules: { active: rulesActive, paused: rulesPaused, total: rules.length },
1435
1449
  plan: { milestones, inProgress: planInProgress },
1436
1450
  lessons: { count: lessonHeaders.length, latest: lessonsLatest },
1451
+ archive: archiveCounts, // 1.9.130
1437
1452
  summary: `T${tasksInProgress}/D${decisionHeaders.length}/R${rulesActive}/P${milestones}/L${lessonHeaders.length}`,
1438
1453
  };
1439
1454
  if (jsonMode) {
@@ -1450,6 +1465,7 @@ function memoryStatusCmd(root, opts = {}) {
1450
1465
  log(`πŸ—Ί Plan: ${milestones} milestones (${planInProgress} in-progress)`);
1451
1466
  log(`πŸ’‘ Lessons: ${lessonHeaders.length} entries`);
1452
1467
  if (lessonsLatest) log(` - 졜근: ${lessonsLatest}`);
1468
+ if (archiveCounts.total > 0) log(`πŸ—‘ Archive: D${archiveCounts.decisions}/L${archiveCounts.lessons}/P${archiveCounts.plan} (${archiveCounts.total}건)`);
1453
1469
  log(`\nπŸ“Š Summary: ${payload.summary}`);
1454
1470
  }
1455
1471
 
@@ -2484,12 +2500,26 @@ function handoff(root) {
2484
2500
  const milestones = (planText.match(/^### M-\d{4}\./gm) || []).length;
2485
2501
  const lm = exists(lessonsPath(root)) ? read(lessonsPath(root)) : '';
2486
2502
  const lessonsCount = (lm.match(/^### \d{4}-\d{2}-\d{2}[^\n]*/gm) || []).length;
2503
+ // 1.9.130: archive 카운트 톡합
2504
+ const archiveCountsH = { decisions: 0, lessons: 0, plan: 0, total: 0 };
2505
+ try {
2506
+ const hdH = path.join(root, '.harness');
2507
+ for (const [key, file] of [['decisions', 'decisions.archive.md'], ['lessons', 'lessons.archive.md'], ['plan', 'plan.archive.md']]) {
2508
+ const fpH = path.join(hdH, file);
2509
+ if (exists(fpH)) {
2510
+ const entries = _parseArchiveBlocks(read(fpH));
2511
+ archiveCountsH[key] = entries.length;
2512
+ archiveCountsH.total += entries.length;
2513
+ }
2514
+ }
2515
+ } catch {}
2487
2516
  result.memorySurface = {
2488
2517
  tasks: { inProgress: tasksInProgress, total: rows.length, byStatus: tasksByStatus },
2489
2518
  decisions: { count: decisionsCount },
2490
2519
  rules: { active: rulesActive, total: rules.length },
2491
2520
  plan: { milestones },
2492
2521
  lessons: { count: lessonsCount },
2522
+ archive: archiveCountsH, // 1.9.130
2493
2523
  summary: `T${tasksInProgress}/D${decisionsCount}/R${rulesActive}/P${milestones}/L${lessonsCount}`,
2494
2524
  };
2495
2525
  } catch {}
@@ -4238,7 +4268,7 @@ function _banner(opts = {}) {
4238
4268
  lines.push('');
4239
4269
  for (const ln of lines) log(ln);
4240
4270
  if (opts.quickStart) {
4241
- log(C.bold(C.cyan(' ✨ λΉ λ₯Έ μ‹œμž‘ (1.9.129+ handoff 7 μžλ™ 회수 πŸ—‘ archive μ•Œλ¦Ό β€” 59 λΌμš΄λ“œ 자율 λˆ„μ )')));
4271
+ log(C.bold(C.cyan(' ✨ λΉ λ₯Έ μ‹œμž‘ (1.9.130+ πŸŽ‰ 60 λΌμš΄λ“œ λ§ˆμΌμŠ€ν†€ archive ν•„λ“œ 톡합 β€” 60 λΌμš΄λ“œ 자율 λˆ„μ )')));
4242
4272
  log(' ' + C.green('npx leerness@latest init .') + C.dim(' # μ‹ κ·œ ν”„λ‘œμ νŠΈ + μ™ΈλΆ€ AI CLI μ„€μ •'));
4243
4273
  log(' ' + C.green('npx leerness handoff .') + C.dim(' # μ»¨ν…μŠ€νŠΈ + lessons + λ§€μΉ­ skill + history hit + brainstorm hits + ν—€λ“œλΌμΈ'));
4244
4274
  log(' ' + C.green('npx leerness handoff . --quiet') + C.dim(' # μžλ™ν™”/CI λͺ¨λ“œ (1.9.99) β€” μžλ™ 회수 라인 λΉ„ν™œμ„±'));
@@ -5160,12 +5190,26 @@ function sessionClose(root, opts = {}) {
5160
5190
  const milestones0 = (planText0.match(/^### M-\d{4}\./gm) || []).length;
5161
5191
  const lm0 = exists(lessonsPath(root)) ? read(lessonsPath(root)) : '';
5162
5192
  const lessonsCount0 = (lm0.match(/^### \d{4}-\d{2}-\d{2}[^\n]*/gm) || []).length;
5193
+ // 1.9.130: archive 카운트 톡합
5194
+ const archiveCountsS = { decisions: 0, lessons: 0, plan: 0, total: 0 };
5195
+ try {
5196
+ const hdS = path.join(root, '.harness');
5197
+ for (const [key, file] of [['decisions', 'decisions.archive.md'], ['lessons', 'lessons.archive.md'], ['plan', 'plan.archive.md']]) {
5198
+ const fpS = path.join(hdS, file);
5199
+ if (exists(fpS)) {
5200
+ const entries = _parseArchiveBlocks(read(fpS));
5201
+ archiveCountsS[key] = entries.length;
5202
+ archiveCountsS.total += entries.length;
5203
+ }
5204
+ }
5205
+ } catch {}
5163
5206
  jsonResult.memorySurface = {
5164
5207
  tasks: { inProgress: tasksInProgress0, total: rows0.length, byStatus: tasksByStatus0 },
5165
5208
  decisions: { count: decisionsCount0 },
5166
5209
  rules: { active: rulesActive0, total: rules0.length },
5167
5210
  plan: { milestones: milestones0 },
5168
5211
  lessons: { count: lessonsCount0 },
5212
+ archive: archiveCountsS, // 1.9.130
5169
5213
  summary: `T${tasksInProgress0}/D${decisionsCount0}/R${rulesActive0}/P${milestones0}/L${lessonsCount0}`,
5170
5214
  };
5171
5215
  } catch {}
@@ -8777,6 +8821,22 @@ function healthCmd(root) {
8777
8821
  rules: { active: rulesActive, total: rules.length },
8778
8822
  plan: { milestones },
8779
8823
  lessons: { count: lessonsCount },
8824
+ archive: (() => {
8825
+ // 1.9.130: archive 카운트 톡합
8826
+ const a = { decisions: 0, lessons: 0, plan: 0, total: 0 };
8827
+ try {
8828
+ const hdHe = path.join(root, '.harness');
8829
+ for (const [key, file] of [['decisions', 'decisions.archive.md'], ['lessons', 'lessons.archive.md'], ['plan', 'plan.archive.md']]) {
8830
+ const fpHe = path.join(hdHe, file);
8831
+ if (exists(fpHe)) {
8832
+ const entries = _parseArchiveBlocks(read(fpHe));
8833
+ a[key] = entries.length;
8834
+ a.total += entries.length;
8835
+ }
8836
+ }
8837
+ } catch {}
8838
+ return a;
8839
+ })(),
8780
8840
  summary: `T${tasksInProgress}/D${decisionsCount}/R${rulesActive}/P${milestones}/L${lessonsCount}`,
8781
8841
  };
8782
8842
  } catch { out.memorySurface = { error: 'memorySurface 점검 μ‹€νŒ¨' }; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.129",
3
+ "version": "1.9.130",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",