leerness 1.9.235 β†’ 1.9.237

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,78 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.237 β€” 2026-05-24
4
+
5
+ **πŸ—‘ session close --auto-cleanup-branches + handoff body 50+ branches κ²½κ³ .**
6
+
7
+ ### 1. `session close --auto-cleanup-branches` μ˜΅μ…˜ (1.9.224 νŒ¨ν„΄ ν™•μž₯)
8
+ - 50+ release/* merged branches μ‹œ μžλ™ 정리 (keep 10)
9
+ - μ•ˆμ „: 1.9.235 κ°€λ“œ (merged 만, ν˜„μž¬ branch 보호)
10
+ - `--auto-apply-delivered` (1.9.224) 와 λ™μΌν•œ 자율 λͺ¨λ“œ νŒ¨ν„΄
11
+
12
+ ### 2. handoff body 50+ branches κ²½κ³  μžλ™ λ…ΈμΆœ
13
+ - `## πŸ—‘ release/* branches λˆ„μ  N개 (50+) (1.9.237)` λ³Έλ¬Έ μ„Ήμ…˜ μžλ™
14
+ - 3 κ°€μ§€ 정리 μ˜΅μ…˜ μžλ™ μ•ˆλ‚΄:
15
+ - μˆ˜λ™: `leerness release cleanup --apply --keep 10`
16
+ - 마감 μžλ™: `session close --auto-cleanup-branches`
17
+ - drift μžλ™: `drift check --auto-fix` (1.9.236)
18
+ - AI/μ‚¬μš©μž λˆ„μ  폐기물 κ°€μ‹œν™”
19
+
20
+ ### 3. release cleanup μƒνƒœκ³„ μ™„μ„± (3 λΌμš΄λ“œ λˆ„μ )
21
+ | λΌμš΄λ“œ | κΈ°λŠ₯ |
22
+ |---|---|
23
+ | 1.9.235 | CLI μ‹ μ„€ (μˆ˜λ™) |
24
+ | 1.9.236 | MCP 66 + drift --auto-fix 톡합 |
25
+ | **1.9.237** | **session close μžλ™ + handoff body κ²½κ³ ** ⭐ |
26
+
27
+ ### 4. λˆ„μ  νšŒκ·€ (1.9.207~236) β€” λͺ¨λ‘ μœ μ§€
28
+
29
+ ### 5. stress-v182 β€” 15/15 PASS
30
+ - 1.9.237 (5): VERSION + flag μ½”λ“œ + session close μ•ˆλ‚΄ + handoff body κ²½κ³  + 격리 no-warning
31
+ - μ„±λŠ₯ (2): cold_start avg 387ms / handoff 4706ms
32
+ - λˆ„μ  νšŒκ·€ (8): 1.9.207~236
33
+
34
+ ### 6. μžλ™ release (99 λΌμš΄λ“œ main-push streak Β· 60 λΌμš΄λ“œ npm publish streak πŸŽ‰)
35
+
36
+ πŸŽ‰ **60 λΌμš΄λ“œ npm publish streak 달성** + 1 λΌμš΄λ“œ ν›„ **R100 main-push streak 도달**
37
+
38
+ ---
39
+
40
+ ## 1.9.236 β€” 2026-05-24
41
+
42
+ **πŸ”Œ MCP 66번째 도ꡬ (release_cleanup) + drift check --auto-fix 톡합 (50+ branches μžλ™ 정리).**
43
+
44
+ ### 1. MCP 66번째 도ꡬ β€” `leerness_release_cleanup`
45
+ - 1.9.235 release cleanup CLI λ₯Ό μ™ΈλΆ€ AI 에 λ…ΈμΆœ
46
+ - 인자: `{ path?, apply? (default false), keep? (default 5) }`
47
+ - 응닡: `{ apply, keep, total, merged, unmerged, deleteCount, toDelete[], recent[], unmergedSample[] }`
48
+ - MCP 65 β†’ **66** (+1)
49
+
50
+ ### 2. `drift check --auto-fix` release cleanup 톡합 (1.9.82/225 νŒ¨ν„΄ ν™•μž₯)
51
+ - merged `release/*` branches 50개 초과 μ‹œ μžλ™ 정리
52
+ - μ•ˆμ „: keep 10 (졜근 10개 μœ μ§€), merged 만 μ‚­μ œ (unmerged 보호)
53
+ - 1.9.82 audit --fix β†’ 1.9.225 delivered β†’ 1.9.236 release cleanup (3 λΌμš΄λ“œ λˆ„μ )
54
+
55
+ ### 3. drift 회볡 μ‹œμŠ€ν…œ ν™•μž₯ 맀트릭슀 (4 μžλ™ 회볡 톡합)
56
+ | λΌμš΄λ“œ | μ‹ ν˜Έ | μžλ™ 회볡 |
57
+ |---|---|---|
58
+ | 1.9.39 | critical | session close μžλ™ |
59
+ | 1.9.82 | λ³΄μ•ˆ | audit --fix |
60
+ | 1.9.225 | delivered | requests μžλ™ μ™„λ£Œ |
61
+ | **1.9.236** | **release-branch** | **release cleanup --keep 10** ⭐ |
62
+
63
+ ### 4. λˆ„μ  νšŒκ·€ (1.9.207~235) β€” λͺ¨λ‘ μœ μ§€
64
+
65
+ ### 5. stress-v181 β€” 15/15 PASS
66
+ - 1.9.236 (5): VERSION + MCP 66 등둝 + μ‹€ 호좜 + keep νŒŒλΌλ―Έν„° + drift 톡합 μ½”λ“œ
67
+ - μ„±λŠ₯ (2): cold_start avg 389ms / MCP 66 tools/list 363ms
68
+ - λˆ„μ  νšŒκ·€ (8): 1.9.207~235
69
+
70
+ ### 6. μžλ™ release (98 λΌμš΄λ“œ main-push streak Β· 59 λΌμš΄λ“œ npm publish streak)
71
+
72
+ πŸ”Œ **drift μžλ™ 회볡 4 톡합** β€” leerness κ°€ 슀슀둜 λˆ„μ  폐기물 정리
73
+
74
+ ---
75
+
3
76
  ## 1.9.235 β€” 2026-05-23
4
77
 
5
78
  **πŸ—‘ leerness release cleanup CLI β€” local release/* branches 정리 + --keep BUG fix.**
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.235-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v180-16%2F16-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-65-brightgreen)]() [![cli](https://img.shields.io/badge/CLI_commands-52-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-191-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-97_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![cleanup](https://img.shields.io/badge/πŸ—‘_release-cleanup_CLI-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-353ms-success)]() [![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.237-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v182-15%2F15-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-66-brightgreen)]() [![cli](https://img.shields.io/badge/CLI_commands-52-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-193-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-99_rounds-success)]() [![npm-streak](https://img.shields.io/badge/πŸŽ‰_npm--publish-60_streak-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![cleanup](https://img.shields.io/badge/πŸ—‘_release--cleanup-3_λΌμš΄λ“œ_μ™„μ„±-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-387ms-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
6
6
 
7
7
  ```
8
8
  ╔══════════════════════════════════════════════════════════════╗
@@ -12,9 +12,9 @@
12
12
  β•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β•šβ•β•β•β•β–ˆβ–ˆβ•‘ β•‘
13
13
  β•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β•‘
14
14
  β•‘ β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β• β•‘
15
- β•‘ v1.9.235 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.237 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ πŸ—‘ release cleanup Β· 191 branches λˆ„μ  정리 + BUG fix β•‘
17
+ β•‘ πŸŽ‰ 60 npm publish streak Β· release cleanup 3 λΌμš΄λ“œ μ™„μ„± β•‘
18
18
  β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
19
19
  ```
20
20
 
package/bin/harness.js CHANGED
@@ -7,7 +7,7 @@ const cp = require('child_process');
7
7
  const os = require('os'); // 1.9.178: _publishToNpm μ—μ„œ os.tmpdir() μ‚¬μš© (μ „μ—­ import)
8
8
  const readline = require('readline');
9
9
 
10
- const VERSION = '1.9.235';
10
+ const VERSION = '1.9.237';
11
11
 
12
12
  // 1.9.184: DEP0190 (child_process shell: true) deprecation warning μ–΅μ œ (μ‚¬μš©μž λͺ…μ‹œ).
13
13
  // leerness λŠ” cross-platform PATH resolution 을 μœ„ν•΄ shell: true λ₯Ό μ˜λ„μ μœΌλ‘œ μ‚¬μš© (claude.cmd / ollama.cmd λ“± Windows .cmd 처리).
@@ -6573,6 +6573,25 @@ function handoff(root) {
6573
6573
  }
6574
6574
  } catch {}
6575
6575
 
6576
+ // 1.9.237: handoff λ³Έλ¬Έ release/* λˆ„μ  κ²½κ³  β€” 50+ branches merged μ‹œ μžλ™ μ•ˆλ‚΄
6577
+ // 1.9.220 λΉ„μ •μƒμ’…λ£Œ release-branch-pending μ‹ ν˜Έμ˜ λ³Έλ¬Έ 보강 (handoff ν—€λ“œλΌμΈμ€ β€˜πŸ”Œ λΉ„μ •μƒμ’…λ£Œβ€™ 만 ν‘œμ‹œ)
6578
+ try {
6579
+ const branchR = cp.spawnSync('git', ['branch', '--merged', 'main', '--list', 'release/*'], { cwd: root, encoding: 'utf8' });
6580
+ if (branchR.status === 0) {
6581
+ const mergedCnt = (branchR.stdout || '').split('\n').filter(l => l.trim() && /release\/\d+\.\d+\.\d+/.test(l)).length;
6582
+ if (mergedCnt > 50) {
6583
+ const isTty = process.stdout && process.stdout.isTTY;
6584
+ const yl5 = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
6585
+ const dm5 = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
6586
+ log('');
6587
+ log(yl5(`## πŸ—‘ release/* branches λˆ„μ  ${mergedCnt}개 (50+) (1.9.237)`));
6588
+ log(dm5(` β†’ μˆ˜λ™ 정리: leerness release cleanup --apply --keep 10`));
6589
+ log(dm5(` β†’ 마감 μ‹œ μžλ™: session close --auto-cleanup-branches`));
6590
+ log(dm5(` β†’ drift μžλ™ 회볡: drift check --auto-fix (1.9.236, 50+ μ‹œ)`));
6591
+ }
6592
+ }
6593
+ } catch {}
6594
+
6576
6595
  // 1.9.224: handoff λ³Έλ¬Έ μžλ™ λ…ΈμΆœ β€” delivered νŒ¨ν„΄ 후보 β‰₯ 1건 μ‹œ (1.9.223 ν™•μž₯)
6577
6596
  // "Round X.Y.Z β€” κ΅¬ν˜„ μ™„λ£Œ" νŒ¨ν„΄μ΄ λˆ„μ λ˜λ©΄ λ³Έλ¬Έ μ„Ήμ…˜μœΌλ‘œ μžλ™ μ•ˆλ‚΄ (ν—€λ“œλΌμΈλ§ŒμœΌλ‘œλŠ” λ†“μΉ˜κΈ° 쉬움)
6578
6597
  // 1.9.225: LEERNESS_AUTO_APPLY_DELIVERED=1 env ν™œμ„± μ‹œ handoff 첫 ν˜ΈμΆœμ—μ„œ μžλ™ 적용 (자율 λͺ¨λ“œμš© opt-in)
@@ -10507,6 +10526,40 @@ function sessionClose(root, opts = {}) {
10507
10526
  log(grn(` βœ“ λ©±λ“±μ„± 검사 톡과 β€” verified ${idemp.summary.verifiedAreas} μ˜μ—­`));
10508
10527
  }
10509
10528
  } catch {}
10529
+ // 1.9.237: session close --auto-cleanup-branches β€” 50+ release/* branches μ‹œ μžλ™ 정리
10530
+ // 1.9.224 νŒ¨ν„΄ (--auto-apply-delivered) ν™•μž₯ β€” 마감 μ‹œ 운영 λˆ„μ  폐기물 μžλ™ 정리
10531
+ // μ•ˆμ „: keep 10, merged 만, ν˜„μž¬ branch 보호
10532
+ try {
10533
+ const branchR = cp.spawnSync('git', ['branch', '--merged', 'main', '--list', 'release/*'], { cwd: root, encoding: 'utf8' });
10534
+ if (branchR.status === 0) {
10535
+ const merged = (branchR.stdout || '').split('\n')
10536
+ .map(l => l.replace(/^\*?\s+/, '').trim())
10537
+ .filter(l => l && /^release\/\d+\.\d+\.\d+$/.test(l));
10538
+ if (merged.length > 50) {
10539
+ if (has('--auto-cleanup-branches')) {
10540
+ merged.sort((a, b) => {
10541
+ const va = a.replace('release/', '').split('.').map(n => parseInt(n, 10) || 0);
10542
+ const vb = b.replace('release/', '').split('.').map(n => parseInt(n, 10) || 0);
10543
+ for (let i = 0; i < 3; i++) if (va[i] !== vb[i]) return vb[i] - va[i];
10544
+ return 0;
10545
+ });
10546
+ const curR = cp.spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: root, encoding: 'utf8' });
10547
+ const cur = (curR.stdout || '').trim();
10548
+ const toDelete = merged.slice(10).filter(b => b !== cur);
10549
+ let okCnt = 0;
10550
+ for (const b of toDelete) {
10551
+ const r = cp.spawnSync('git', ['branch', '-d', b], { cwd: root, encoding: 'utf8' });
10552
+ if (r.status === 0) okCnt++;
10553
+ }
10554
+ log(grn(` βœ“ release 정리 ${okCnt}/${toDelete.length}건 (--auto-cleanup-branches 1.9.237, keep 10)`));
10555
+ } else {
10556
+ log(yel(` πŸ—‘ release/* merged ${merged.length}개 (50+) β€” cleanup κ°€λŠ₯ (1.9.235)`));
10557
+ log(dim(` β†’ leerness release cleanup --apply --keep 10 (μˆ˜λ™)`));
10558
+ log(dim(` β†’ λ˜λŠ” session close --auto-cleanup-branches (1.9.237 μžλ™)`));
10559
+ }
10560
+ }
10561
+ }
10562
+ } catch {}
10510
10563
  // 1.9.232: 마감 μ‹œ pulse ν•œ 쀄 μžλ™ λ…ΈμΆœ β€” λ‹€μŒ λΌμš΄λ“œ μ§„μž… μ‹œ μ¦‰μ‹œ μƒνƒœ 인지
10511
10564
  try {
10512
10565
  const rh = _computeRoundHistory(root);
@@ -13480,6 +13533,42 @@ function driftCheckCmd(root, opts = {}) {
13480
13533
  log(`⚠ delivered auto-apply 였λ₯˜ (1.9.225): ${e.message}`);
13481
13534
  }
13482
13535
  }
13536
+ // 1.9.236: drift check --auto-fix 에 release cleanup 톡합 (1.9.235 회수)
13537
+ // λˆ„μ λœ 50개+ release/* branches β†’ abnormal-shutdown release-branch-pending μ‹ ν˜Έ 가쀑
13538
+ // μ•ˆμ „: keep 10 (졜근 10개 μœ μ§€), merged 만 μ‚­μ œ (1.9.235 μ•ˆμ „ κ°€λ“œ)
13539
+ // μž„κ³„: 50개 초과 μ‹œλ§Œ μžλ™ 정리 (μ†ŒλŸ‰ λˆ„μ μ€ 정상 운영)
13540
+ if (autoFix) {
13541
+ try {
13542
+ const branchR = cp.spawnSync('git', ['branch', '--merged', 'main', '--list', 'release/*'], { cwd: root, encoding: 'utf8' });
13543
+ if (branchR.status === 0) {
13544
+ const merged = (branchR.stdout || '').split('\n')
13545
+ .map(l => l.replace(/^\*?\s+/, '').trim())
13546
+ .filter(l => l && /^release\/\d+\.\d+\.\d+$/.test(l));
13547
+ if (merged.length > 50) {
13548
+ log('');
13549
+ log(`πŸ—‘ --auto-fix ν™œμ„± (1.9.236) β€” release/* merged ${merged.length}개 (50+) μžλ™ 정리 (keep 10)...`);
13550
+ // μ •λ ¬ (semver desc)
13551
+ merged.sort((a, b) => {
13552
+ const va = a.replace('release/', '').split('.').map(n => parseInt(n, 10) || 0);
13553
+ const vb = b.replace('release/', '').split('.').map(n => parseInt(n, 10) || 0);
13554
+ for (let i = 0; i < 3; i++) if (va[i] !== vb[i]) return vb[i] - va[i];
13555
+ return 0;
13556
+ });
13557
+ const currentBranchR = cp.spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: root, encoding: 'utf8' });
13558
+ const currentBranch = (currentBranchR.stdout || '').trim();
13559
+ const toDelete = merged.slice(10).filter(b => b !== currentBranch);
13560
+ let ok = 0;
13561
+ for (const b of toDelete) {
13562
+ const r = cp.spawnSync('git', ['branch', '-d', b], { cwd: root, encoding: 'utf8' });
13563
+ if (r.status === 0) ok++;
13564
+ }
13565
+ log(`βœ“ release cleanup μžλ™ μ™„λ£Œ ${ok}/${toDelete.length}건 (keep 10)`);
13566
+ }
13567
+ }
13568
+ } catch (e) {
13569
+ log(`⚠ release cleanup auto-fix 였λ₯˜ (1.9.236): ${e.message}`);
13570
+ }
13571
+ }
13483
13572
  if (autoFix && level === 'πŸ”΄ critical' && !hasSecurityFired) {
13484
13573
  log('');
13485
13574
  log(`πŸ”§ --auto-fix ν™œμ„± β€” session close μžλ™ μ‹€ν–‰ 쀑...`);
@@ -14468,7 +14557,8 @@ function mcpServeCmd(root) {
14468
14557
  { name: 'leerness_round_history', description: '1.9.226 β€” 자율 λΌμš΄λ“œ 톡계. git tag v1.9.X 기반 λˆ„μ  λΌμš΄λ“œ 카운트 + λ‹€μŒ λ§ˆμΌμŠ€ν†€ (50/75/100/125/150/175/200/250/300/400/500) + 평균 rounds/day. 응닡: { currentVersion, roundCount, baselineVersion, latestTags[], nextMilestone, roundsToNextMilestone, firstTagAt, latestTagAt, daysActive, avgRoundsPerDay }. μ™ΈλΆ€ AIκ°€ "이 ν”„λ‘œμ νŠΈλŠ” μ–Όλ§ˆλ‚˜ 진행됐고 λ‹€μŒ λ§ˆμΌμŠ€ν†€κΉŒμ§€ λͺ‡ λΌμš΄λ“œ λ‚¨μ•˜λ‚˜?"λ₯Ό 회수. 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
14469
14558
  { name: 'leerness_milestones', description: '1.9.229 (1.9.226 ν™•μž₯) β€” 도달 λ§ˆμΌμŠ€ν†€ + λ‹€μŒ ETA. git tag 순차 λΆ„μ„μœΌλ‘œ 25/50/75/100/125/150/175/200/250/300/400/500 λ§ˆμΌμŠ€ν†€ 도달 일자 + λ‹€μŒ λ§ˆμΌμŠ€ν†€ ETA (ν˜„μž¬ 속도 κΈ°μ€€) 계산. 응닡: { totalRounds, reached: [{milestone, version, reachedAt, daysFromBaseline}], next: {milestone, roundsRemaining, etaDays, etaDate}, baselineAt, avgRoundsPerDay }. μ™ΈλΆ€ AIκ°€ "μ§€κΈˆκΉŒμ§€ μ–΄λ–€ λ§ˆμΌμŠ€ν†€μ„ μ–Έμ œ λ‹¬μ„±ν–ˆκ³  λ‹€μŒ λ§ˆμΌμŠ€ν†€ μ˜ˆμƒ 도달일은?"을 회수. 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
14470
14559
  { name: 'leerness_pulse', description: '1.9.231 β€” ν•œ 쀄 μ’…ν•© μš”μ•½ (10 핡심 μ§€ν‘œ). 응닡: { version, roundCount, mcpTools, memorySurface, security, health, driftScore, nextMilestone, etaDays, abnormalShutdown }. μ™ΈλΆ€ AIκ°€ "leerness μƒνƒœ ν•œ λˆˆμ— 보기"λ₯Ό κ°€λ²Όμš΄ 단일 호좜둜 회수. handoff 보닀 5λ°° 빠름 (drift/health 계산 skip). 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
14471
- { name: 'leerness_commands', description: '1.9.233 β€” μΉ΄ν…Œκ³ λ¦¬ν™”λœ 전체 CLI λͺ…λ Ή λͺ©λ‘ (9 μΉ΄ν…Œκ³ λ¦¬). 응닡: { version, totalCommands, categories: { status, task, memory, audit, workflow, release, skill, bridge, config } }. μ™ΈλΆ€ AIκ°€ "leerness κ°€ μ œκ³΅ν•˜λŠ” λͺ…령이 뭐가 μžˆλ‚˜"λ₯Ό 직접 회수. 맀뉴얼/도움말 동적 생성. 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
14560
+ { name: 'leerness_commands', description: '1.9.233 β€” μΉ΄ν…Œκ³ λ¦¬ν™”λœ 전체 CLI λͺ…λ Ή λͺ©λ‘ (9 μΉ΄ν…Œκ³ λ¦¬). 응닡: { version, totalCommands, categories: { status, task, memory, audit, workflow, release, skill, bridge, config } }. μ™ΈλΆ€ AIκ°€ "leerness κ°€ μ œκ³΅ν•˜λŠ” λͺ…령이 뭐가 μžˆλ‚˜"λ₯Ό 직접 회수. 맀뉴얼/도움말 동적 생성. 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
14561
+ { name: 'leerness_release_cleanup', description: '1.9.236 (1.9.235 μžλ™ 회수) β€” local release/* branches 정리. main 에 merge된 κ²ƒλ§Œ 후보 (unmerged 보호, ν˜„μž¬ branch 보호). 응닡: { apply, keep, total, merged, unmerged, deleteCount, toDelete[], recent[], unmergedSample[] }. μ™ΈλΆ€ AIκ°€ "운영 λˆ„μ  release branches 정리 κ°€λŠ₯?"을 회수. κΈ°λ³Έ dry-run, apply: true μ‹œμ—λ§Œ μ‹€ μ‚­μ œ. 인자: { path?, apply? (default false), keep? (default 5) }', inputSchema: { type: 'object', properties: { path: { type: 'string' }, apply: { type: 'boolean' }, keep: { type: 'number' } } } }
14472
14562
  ];
14473
14563
 
14474
14564
  function send(obj) {
@@ -14645,6 +14735,12 @@ function mcpServeCmd(root) {
14645
14735
  // 1.9.233: μΉ΄ν…Œκ³ λ¦¬ν™”λœ 전체 CLI λͺ…λ Ή λͺ©λ‘
14646
14736
  cliArgs = ['commands', '--json'];
14647
14737
  break;
14738
+ case 'leerness_release_cleanup':
14739
+ // 1.9.236 (1.9.235): local release/* branches 정리
14740
+ cliArgs = ['release', 'cleanup', '--json'];
14741
+ if (args.apply === true) cliArgs.push('--apply');
14742
+ if (typeof args.keep === 'number') cliArgs.push('--keep', String(args.keep));
14743
+ break;
14648
14744
  default:
14649
14745
  return send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Unknown tool: ${name}` } });
14650
14746
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.235",
3
+ "version": "1.9.237",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",