leerness 1.9.220 β†’ 1.9.222

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,74 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.222 β€” 2026-05-22
4
+
5
+ **πŸ›‘ session-resume --auto-fix μ•ˆμ „ 회볡 + handoff λ³Έλ¬Έ 비정상 μ’…λ£Œ μžλ™ λ…ΈμΆœ.**
6
+
7
+ ### 1. `leerness session-resume --auto-fix` β€” μ•ˆμ „ν•œ μžλ™ 회볡
8
+ - 1.9.220 detect / 1.9.221 MCP / 1.9.222 **auto-fix**
9
+ - `wakeup-missed` μ‹ ν˜Έ 감지 μ‹œ β†’ 30λΆ„+ μ§€λ‚œ pending wakeup μžλ™ `superseded`
10
+ - `state.supersededReason: 'auto-fix-1.9.222-abnormal-shutdown'`
11
+ - μ‚¬μš©μž/AIκ°€ μˆ˜λ™ 정리할 ν•„μš” 없이 λ‹€μŒ wakeup이 정상 λ™μž‘
12
+ - `--auto-fix` μ˜΅μ…˜μ΄ μ—†μœΌλ©΄ κΈ°μ‘΄ λ™μž‘ κ·ΈλŒ€λ‘œ (κ°μ§€λ§Œ, λ³€κ²½ X)
13
+
14
+ ### 2. handoff λ³Έλ¬Έ μžλ™ λ…ΈμΆœ β€” 비정상 μ’…λ£Œ μ„Ήμ…˜
15
+ - 1.9.220 ν—€λ“œλΌμΈ (`πŸ”Œ λΉ„μ •μƒμ’…λ£Œ <severity>`) + 1.9.222 **λ³Έλ¬Έ**
16
+ - `severity: high` β†’ `## 🚨 비정상 μ’…λ£Œ 감지 (1.9.220, severity: high)` λ³Έλ¬Έ μ„Ήμ…˜ μžλ™
17
+ - `severity: medium` β†’ `## ⚠ 비정상 μ’…λ£Œ 감지` λ³Έλ¬Έ μ„Ήμ…˜ μžλ™
18
+ - λ³Έλ¬Έ 좜λ ₯ μœ„μΉ˜: pre-wake-audit μ„Ήμ…˜ λ‹€μŒ, ν™œμ„± λ£° 이전
19
+ - top 3 μ‹ ν˜Έ + 재개 κ°€μ΄λ“œ + auto-fix κ°€μ΄λ“œ ν•œ λ²ˆμ— λ…ΈμΆœ
20
+
21
+ ### 3. CLAUDE.md / AGENTS.md 1.9.214~221 운영 κ°•ν™” 8 λΌμš΄λ“œ 톡합
22
+ - drift 차단을 μœ„ν•œ `## 운영 κ°•ν™” 8 λΌμš΄λ“œ (1.9.214~221)` μ„Ήμ…˜ λˆ„μ 
23
+ - 9 λΌμš΄λ“œ (drift 차단 / handoff ν—€λ“œλΌμΈ / MCP 5μ’… / session close / handoff JSON 4 톡합 / 80 λΌμš΄λ“œ / 비정상 μ’…λ£Œ / MCP 60 / auto-fix) λͺ¨λ‘ 단일 μ‹œμ•Ό λ…ΈμΆœ
24
+
25
+ ### 4. λˆ„μ  νšŒκ·€ (1.9.207~221) β€” λͺ¨λ‘ μœ μ§€
26
+
27
+ ### 5. stress-v167 β€” 14/14 PASS
28
+ - 1.9.222 (6): VERSION + auto-fix (격리) + auto-fix λ―Έμ§€μ • μ‹œ λ™μž‘ + handoff λ³Έλ¬Έ λ…ΈμΆœ + handoff 정상 μ‹œ λ―Έλ…ΈμΆœ + CLAUDE 8 λΌμš΄λ“œ μ„Ήμ…˜
29
+ - μ„±λŠ₯ (2): cold_start avg 408ms / MCP 60 도ꡬ 413ms
30
+ - λˆ„μ  νšŒκ·€ (6): 1.9.207~221
31
+
32
+ ### 6. μžλ™ release (84 λΌμš΄λ“œ main-push streak Β· 45 λΌμš΄λ“œ npm publish streak)
33
+
34
+ πŸ›‘ **비정상 μ’…λ£Œ μ‹œμŠ€ν…œ μ™„μ„±**: 1.9.220 detect β†’ 1.9.221 MCP β†’ 1.9.222 **auto-fix** + **λ³Έλ¬Έ μžλ™ λ…ΈμΆœ** (3 λΌμš΄λ“œ λˆ„μ )
35
+
36
+ ---
37
+
38
+ ## 1.9.221 β€” 2026-05-22
39
+
40
+ **πŸŽ‰ MCP 60 도ꡬ λ§ˆμΌμŠ€ν†€ + abnormalShutdown JSON 톡합 (handoff/session close).**
41
+
42
+ ### 1. MCP 60번째 도ꡬ β€” `leerness_session_resume`
43
+ - 1.9.220 비정상 μ’…λ£Œ 감지 μ‹œμŠ€ν…œμ„ μ™ΈλΆ€ AI에 λ…ΈμΆœ
44
+ - 인자: `{ path? }`
45
+ - 응닡: `{ abnormalShutdown, severity, signals[], resumeGuide[] }`
46
+ - 5μ‹ ν˜Έ 뢄석 (last-handoff/wakeup-missed/in-progress-stale/auto-resume-plan/release-branch)
47
+
48
+ ### 2. handoff --json `abnormalShutdown` ν•„λ“œ μΆ”κ°€
49
+ - `{ detected, severity, signalCount, signals[], resumeGuide[] }`
50
+ - μ™ΈλΆ€ λͺ¨λ‹ˆν„°λ§ 도ꡬ / CI κ°€ 비정상 μ’…λ£Œ μžλ™ 감지
51
+ - 1.9.218 톡합 νŒ¨ν„΄ ν™•μž₯ (handoff JSON 4μ’… ν•„λ“œ μ™„μ„±: userRequests/preWake/idempotency/abnormalShutdown)
52
+
53
+ ### 3. session close --json 동일 톡합
54
+ - 마감 μ‹œ λ‹€μŒ λΌμš΄λ“œ μ§„μž… μ‹œ 재개 κ°€μ΄λ“œ μžλ™ 회수
55
+ - CI 마감 ν›„ 비정상 μ’…λ£Œ detect κ°€λŠ₯
56
+
57
+ ### 4. λˆ„μ  νšŒκ·€ (1.9.207~220) β€” λͺ¨λ‘ μœ μ§€
58
+
59
+ ### 5. stress-v166 β€” 16/16 PASS
60
+ - 1.9.221 (4): VERSION + MCP 60 + session_resume 등둝 + μ‹€ 호좜 (high severity 응닡)
61
+ - abnormalShutdown JSON 톡합 (3): handoff/session close + wakeup miss μ‹œλ‚˜λ¦¬μ˜€
62
+ - μ„±λŠ₯ (2): cold_start 374ms / MCP 60 도ꡬ 385ms
63
+ - λˆ„μ  νšŒκ·€ (7): 1.9.207~220
64
+
65
+ ### 6. μžλ™ release (83 λΌμš΄λ“œ main-push streak Β· 44 λΌμš΄λ“œ npm publish streak)
66
+
67
+ πŸŽ‰ **MCP 60 도ꡬ 도달** (53 β†’ 60, +7: 1.9.168 +3 / 1.9.216 +5 / 1.9.221 +1)
68
+ πŸŽ‰ **handoff/session close JSON 4 톡합 ν•„λ“œ μ™„μ„±** (userRequests/preWake/idempotency/abnormalShutdown)
69
+
70
+ ---
71
+
3
72
  ## 1.9.220 β€” 2026-05-22
4
73
 
5
74
  **πŸ”Œ 비정상 μ’…λ£Œ ν›„ 자율 재개 μ‹œμŠ€ν…œ (μ‚¬μš©μž λͺ…μ‹œ).**
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.220-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v165-18%2F18-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-59-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-150-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-82_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![resilience](https://img.shields.io/badge/session_resume-5μ‹ ν˜Έ_μžλ™κ°μ§€-success)]() [![perf](https://img.shields.io/badge/cold_start-461ms-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-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.222-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v167-14%2F14-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-60_πŸŽ‰-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-152-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-84_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![auto-fix](https://img.shields.io/badge/πŸ›‘_session--resume-auto--fix-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-408ms-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-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.220 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.222 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ πŸ”Œ 비정상 μ’…λ£Œ β†’ 자율 재개 5μ‹ ν˜Έ μžλ™ 감지 (μ‚¬μš©μž λͺ…μ‹œ) β•‘
17
+ β•‘ πŸ›‘ session-resume --auto-fix Β· handoff λ³Έλ¬Έ 비정상 μ’…λ£Œ μžλ™ β•‘
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.220';
10
+ const VERSION = '1.9.222';
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 처리).
@@ -3055,6 +3055,7 @@ function requestsCmd(root, sub, ...rest) {
3055
3055
  }
3056
3056
 
3057
3057
  // 1.9.220: leerness session-resume β€” 비정상 μ’…λ£Œ 감지 + 자율 재개 κ°€μ΄λ“œ (μ‚¬μš©μž λͺ…μ‹œ)
3058
+ // 1.9.222: --auto-fix μ˜΅μ…˜ μΆ”κ°€ β€” μ•ˆμ „ν•œ μžλ™ 회볡 (wakeup supersede)
3058
3059
  function sessionResumeCmd(root) {
3059
3060
  root = absRoot(root);
3060
3061
  const isTty = process.stdout && process.stdout.isTTY;
@@ -3065,6 +3066,45 @@ function sessionResumeCmd(root) {
3065
3066
  const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3066
3067
 
3067
3068
  const result = _detectAbnormalShutdown(root);
3069
+
3070
+ // 1.9.222: --auto-fix β€” μ•ˆμ „ν•œ μ‹ ν˜Έλ³„ μžλ™ 회볡
3071
+ const autoFix = has('--auto-fix');
3072
+ if (autoFix && result.abnormalShutdown) {
3073
+ result.autoFixed = [];
3074
+ // 1) wakeup-missed β†’ 였래된 pending wakeup supersede (μ•ˆμ „: λ‹¨μˆœ μƒνƒœ λ³€κ²½)
3075
+ if (result.signals.some(s => s.kind === 'wakeup-missed')) {
3076
+ try {
3077
+ const state = _loadActiveWakeups(root);
3078
+ let fixed = 0;
3079
+ state.wakeups = state.wakeups.map(w => {
3080
+ if (w.status === 'pending') {
3081
+ const expectedMs = new Date(w.expectedFireAt).getTime();
3082
+ const deltaMin = Math.floor((Date.now() - expectedMs) / 60000);
3083
+ if (deltaMin > 30) {
3084
+ w.status = 'superseded';
3085
+ w.supersededReason = 'auto-fix-1.9.222-abnormal-shutdown';
3086
+ w.supersededAt = new Date().toISOString();
3087
+ fixed++;
3088
+ }
3089
+ }
3090
+ return w;
3091
+ });
3092
+ if (fixed > 0) {
3093
+ _writeActiveWakeups(root, state.wakeups);
3094
+ result.autoFixed.push({ kind: 'wakeup-missed', action: 'superseded', count: fixed });
3095
+ }
3096
+ } catch {}
3097
+ }
3098
+ // 2) auto-resume-plan-unused β†’ 60min+ λ―Έμ‚¬μš©μ€ μ•ˆλ‚΄λ§Œ (μžλ™ μ‚­μ œ X, μ‚¬μš©μžκ°€ κ²€ν† ν•΄μ•Ό 함)
3099
+ if (result.signals.some(s => s.kind === 'auto-resume-plan-unused')) {
3100
+ result.autoFixed.push({ kind: 'auto-resume-plan-unused', action: 'guidance-only', detail: 'leerness resume 으둜 적용 κ²€ν† ' });
3101
+ }
3102
+ // 3) in-progress-stale β†’ drop 결정은 μ‚¬μš©μž μ˜μ—­ (μžλ™ X)
3103
+ if (result.signals.some(s => s.kind === 'in-progress-stale')) {
3104
+ result.autoFixed.push({ kind: 'in-progress-stale', action: 'guidance-only', detail: 'leerness task list --status in-progress ν›„ μ‚¬μš©μž κ²°μ • ν•„μš”' });
3105
+ }
3106
+ }
3107
+
3068
3108
  if (has('--json')) { log(JSON.stringify(result, null, 2)); return; }
3069
3109
  log(cyan(`# leerness session-resume (1.9.220) β€” 비정상 μ’…λ£Œ 감지 + 자율 재개`));
3070
3110
  log(` detected at: ${result.detectedAt}`);
@@ -3093,6 +3133,18 @@ function sessionResumeCmd(root) {
3093
3133
  for (const g of result.resumeGuide) {
3094
3134
  log(` ${g}`);
3095
3135
  }
3136
+ // 1.9.222: --auto-fix κ²°κ³Ό λ…ΈμΆœ
3137
+ if (result.autoFixed && result.autoFixed.length > 0) {
3138
+ log('');
3139
+ log(grn(`## πŸ”§ auto-fix κ²°κ³Ό (${result.autoFixed.length})`));
3140
+ for (const af of result.autoFixed) {
3141
+ const icon = af.action === 'superseded' ? 'βœ“' : 'β„Ή';
3142
+ log(` ${icon} [${af.kind}] ${af.action}${af.count ? ` (count: ${af.count})` : ''}`);
3143
+ if (af.detail) log(dim(` ${af.detail}`));
3144
+ }
3145
+ } else if (autoFix) {
3146
+ log(dim(` (auto-fix 적용 λŒ€μƒ μ—†μŒ)`));
3147
+ }
3096
3148
  }
3097
3149
 
3098
3150
  // 1.9.208: leerness constraints <list|check|add> β€” ν”Œλž«νΌ/API μ œμ•½ 사전 체크 CLI (μ‚¬μš©μž λͺ…μ‹œ)
@@ -5697,6 +5749,17 @@ function handoff(root) {
5697
5749
  overall: idemp.summary.overall
5698
5750
  };
5699
5751
  } catch {}
5752
+ // 1.9.221: abnormalShutdown μžλ™ 감지 (1.9.220 톡합)
5753
+ try {
5754
+ const ad = _detectAbnormalShutdown(root);
5755
+ result.abnormalShutdown = {
5756
+ detected: ad.abnormalShutdown,
5757
+ severity: ad.severity,
5758
+ signalCount: ad.signals.length,
5759
+ signals: ad.signals.map(s => ({ kind: s.kind, severity: s.severity, detail: s.detail })),
5760
+ resumeGuide: ad.resumeGuide
5761
+ };
5762
+ } catch {}
5700
5763
  log(JSON.stringify(result, null, 2));
5701
5764
  return;
5702
5765
  }
@@ -5945,6 +6008,30 @@ function handoff(root) {
5945
6008
  }
5946
6009
  }
5947
6010
  } catch {}
6011
+
6012
+ // 1.9.222: 비정상 μ’…λ£Œ 감지 λ³Έλ¬Έ μžλ™ λ…ΈμΆœ (handoff 직후 β€” κ°€μž₯ λ¨Όμ € 봐야 함)
6013
+ // high/medium severity μ‹œ μ¦‰μ‹œ λ…ΈμΆœ, low/none 은 λ¬΄μ‹œ
6014
+ try {
6015
+ const ad = _detectAbnormalShutdown(root);
6016
+ if (ad.abnormalShutdown && (ad.severity === 'high' || ad.severity === 'medium')) {
6017
+ const isTty = process.stdout && process.stdout.isTTY;
6018
+ const cy3 = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
6019
+ const rd3 = s => isTty ? `\x1b[31m${s}\x1b[0m` : s;
6020
+ const yl3 = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
6021
+ const dm3 = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
6022
+ log('');
6023
+ const sevIcon = ad.severity === 'high' ? '🚨' : '⚠';
6024
+ const sevColor = ad.severity === 'high' ? rd3 : yl3;
6025
+ log(sevColor(`## ${sevIcon} 비정상 μ’…λ£Œ 감지 (1.9.220, severity: ${ad.severity})`));
6026
+ ad.signals.slice(0, 3).forEach(s => {
6027
+ const ic = s.severity === 'high' ? '🚨' : (s.severity === 'medium' ? '⚠' : 'β„Ή');
6028
+ log(` ${ic} [${s.kind}] ${s.detail}`);
6029
+ });
6030
+ log(dm3(` β†’ 재개 κ°€μ΄λ“œ: leerness session-resume`));
6031
+ log(dm3(` β†’ μžλ™ 회볡: leerness session-resume --auto-fix (1.9.222)`));
6032
+ }
6033
+ } catch {}
6034
+
5948
6035
  // 1.9.8: active rules μžλ™ λ…ΈμΆœ (λ§€ μ„Έμ…˜ μ‹œμž‘ μ‹œ AIμ—κ²Œ λ³΄μž„)
5949
6036
  const activeRules = readRules(root).filter(r => r.status === 'active');
5950
6037
  if (activeRules.length) {
@@ -9723,6 +9810,17 @@ function sessionClose(root, opts = {}) {
9723
9810
  overall: idemp.summary.overall
9724
9811
  };
9725
9812
  } catch {}
9813
+ try {
9814
+ // 1.9.221: abnormalShutdown μžλ™ 감지 (1.9.220 톡합) β€” session close μ‹œ λ‹€μŒ 재개 κ°€μ΄λ“œ 회수
9815
+ const ad = _detectAbnormalShutdown(root);
9816
+ jsonResult.abnormalShutdown = {
9817
+ detected: ad.abnormalShutdown,
9818
+ severity: ad.severity,
9819
+ signalCount: ad.signals.length,
9820
+ signals: ad.signals.map(s => ({ kind: s.kind, severity: s.severity, detail: s.detail })),
9821
+ resumeGuide: ad.resumeGuide
9822
+ };
9823
+ } catch {}
9726
9824
 
9727
9825
  process.stdout.write(JSON.stringify(jsonResult, null, 2) + '\n');
9728
9826
  } else {
@@ -13598,7 +13696,8 @@ function mcpServeCmd(root) {
13598
13696
  { name: 'leerness_constraints_check', description: '1.9.216 (1.9.208 μ‚¬μš©μž λͺ…μ‹œ) β€” ν”Œλž«νΌ/API μ œμ•½ 사전 체크. μ‚¬μš©μž μš”μ²­ ν…μŠ€νŠΈμ—μ„œ ν”Œλž«νΌ alias λ§€μΉ­ (stripe/openai/anthropic/github/discord/twitter 6μ’… + μ‚¬μš©μž μ •μ˜) β†’ 각 ν”Œλž«νΌμ˜ rate-limit / idempotency / auth / cost μ œμ•½ λ…ΈμΆœ. μ™ΈλΆ€ AIκ°€ "이 κΈ°λŠ₯ κ΅¬ν˜„ μ „ μ–΄λ–€ κ·œμ •μ„ 봐야 ν•˜λ‚˜?"λ₯Ό 직접 회수. 인자: { request (required), path? }', inputSchema: { type: 'object', properties: { request: { type: 'string' }, path: { type: 'string' } }, required: ['request'] } },
13599
13697
  { name: 'leerness_pre_wake_audit', description: '1.9.216 (1.9.209 μ‚¬μš©μž λͺ…μ‹œ) β€” sleep μ „ sub-agent audit. 6 μ˜μ—­ 점검: missing-user-requests / stale-in-progress / drift-handoff-stale / wakeup-missed / next-action-pending / auto-resume-plan. μ™ΈλΆ€ AIκ°€ "κΉ¨μ–΄λ‚˜κΈ° μ „ 점검할 λΆ€λΆ„"을 회수. 응닡: { auditedAt, findings: {critical, warning, info}, summary }. 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
13600
13698
  { name: 'leerness_intent_classify', description: '1.9.216 (1.9.213 μ‚¬μš©μž λͺ…μ‹œ) β€” μ‚¬μš©μž μ˜λ„ νŒŒμ•… + scope expansion 게이트. 응닡: { intent: precise|broad|default, signals, domain, explicitMentions, expansionCandidates, mode: dry-run }. 3원칙 μ•ˆμ „: (1) Always-Off Opt-In, (2) Dry-run κΈ°λ³Έ (μ‹€ν–‰ X), (3) λͺ…μ‹œ vs μΆ”λ‘  뢄리 라벨링. 5 도메인 (game/web/api/cli/data). μ™ΈλΆ€ AIκ°€ "이 μš”μ²­μ€ μ •ν™•νžˆ κ·Έκ²ƒλ§Œ / 포괄적 / 기본인가?"λ₯Ό 회수. 인자: { request (required), path? }', inputSchema: { type: 'object', properties: { request: { type: 'string' }, path: { type: 'string' } }, required: ['request'] } },
13601
- { name: 'leerness_idempotency_audit', description: '1.9.216 (1.9.212 μ‚¬μš©μž λͺ…μ‹œ) β€” λ©±λ“±μ„± μœ„λ°˜ 탐지. 4μ˜μ—­ 점검: rule-duplicate (medium) / task-duplicate-request (medium) / user-request-duplicate (low) / wakeup-duplicate (high). 응닡: { violations[], verified[], summary: {totalViolations, high/medium/low, overall} }. μ™ΈλΆ€ AIκ°€ "μ›Œν¬μŠ€νŽ˜μ΄μŠ€μ— 쀑볡/좩돌이 μžˆλ‚˜?"λ₯Ό 회수. πŸŽ‰ MCP 58 도ꡬ λ§ˆμΌμŠ€ν†€ (50β†’58). 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
13699
+ { name: 'leerness_idempotency_audit', description: '1.9.216 (1.9.212 μ‚¬μš©μž λͺ…μ‹œ) β€” λ©±λ“±μ„± μœ„λ°˜ 탐지. 4μ˜μ—­ 점검: rule-duplicate (medium) / task-duplicate-request (medium) / user-request-duplicate (low) / wakeup-duplicate (high). 응닡: { violations[], verified[], summary: {totalViolations, high/medium/low, overall} }. μ™ΈλΆ€ AIκ°€ "μ›Œν¬μŠ€νŽ˜μ΄μŠ€μ— 쀑볡/좩돌이 μžˆλ‚˜?"λ₯Ό 회수. πŸŽ‰ MCP 58 도ꡬ λ§ˆμΌμŠ€ν†€ (50β†’58). 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
13700
+ { name: 'leerness_session_resume', description: '1.9.221 (1.9.220 μ‚¬μš©μž λͺ…μ‹œ) β€” 비정상 μ’…λ£Œ 감지 + 자율 재개. 5μ‹ ν˜Έ 뢄석: last-handoff-stale / wakeup-missed / in-progress-stale / auto-resume-plan-unused / release-branch-pending. 응닡: { abnormalShutdown, severity (none/low/medium/high), signals[], resumeGuide[] }. μ™ΈλΆ€ AIκ°€ "μ ˆμ „/μ‹œμŠ€ν…œμ’…λ£Œ/μ„Έμ…˜μ’…λ£Œ ν›„ leerness μƒνƒœκ°€ 정상인가? μ–΄λ–»κ²Œ 재개?"λ₯Ό 회수. πŸŽ‰ MCP 60 도ꡬ λ§ˆμΌμŠ€ν†€ (53β†’60, +7 in 1.9.168/216/221). 인자: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
13602
13701
  ];
13603
13702
 
13604
13703
  function send(obj) {
@@ -13750,6 +13849,10 @@ function mcpServeCmd(root) {
13750
13849
  // 1.9.216 (1.9.212): λ©±λ“±μ„± 감사 (rule/task/user-requests/wakeups 4μ˜μ—­)
13751
13850
  cliArgs = ['idempotency', 'audit', '--path', targetPath, '--json'];
13752
13851
  break;
13852
+ case 'leerness_session_resume':
13853
+ // 1.9.221 (1.9.220): 비정상 μ’…λ£Œ 감지 + 자율 재개
13854
+ cliArgs = ['session-resume', '--path', targetPath, '--json'];
13855
+ break;
13753
13856
  default:
13754
13857
  return send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Unknown tool: ${name}` } });
13755
13858
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.220",
3
+ "version": "1.9.222",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",