leerness 1.9.193 β†’ 1.9.194

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,58 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.194 β€” 2026-05-21
4
+
5
+ **🎯 EμΆ• (κ²ŒμœΌλ¦„ λ°©μ§€) 보강 β€” handoff λ‹€μŒ 단계 μžλ™ μ œμ•ˆ + 24h+ 무진척 lazy 감지.**
6
+
7
+ 자율 λͺ¨λ“œ 124 λΌμš΄λ“œ. 1.9.192 CμΆ• / 1.9.193 BμΆ• 보강에 이어 **EμΆ• (9/10 β†’ λͺ©ν‘œ 9.5/10)** 보강.
8
+
9
+ ### μ‚¬μš©μž μ˜λ„ μ •λ ¬ (1.9.191 verbatim)
10
+ > *"κ²ŒμœΌλ¦„ λ°©μ§€λ“±λ“± 졜고의 도ꡬ"*
11
+
12
+ ### 1. handoff λ‹€μŒ 단계 μžλ™ μ œμ•ˆ (EμΆ• 핡심)
13
+ - ν˜„μž¬ in-progress task description + Memory Surface (decisions/lessons/plan) μ‘°ν•© β†’ λ‹€μŒ 단계 1-3개 μ œμ•ˆ
14
+ - μ‚¬μš©μž/AI κ°€ "Next Exact Step" 을 직접 μ±„μš°μ§€ μ•Šμ•„λ„ μ¦‰μ‹œ λ…ΈμΆœ
15
+ - **7개 νœ΄λ¦¬μŠ€ν‹±**:
16
+ 1. lessons.md μ‹€νŒ¨ λ§€μΉ­ β†’ νšŒν”Ό μ „λž΅ 적용 (`leerness lessons --auto`)
17
+ 2. plan.md milestone λ§€μΉ­ β†’ milestone 검증 (`leerness plan list`)
18
+ 3. decisions.md κ²°μ • λ§€μΉ­ β†’ 영ν–₯ 확인 (`leerness decision list`)
19
+ 4. review-evidence.md λΆ€μž¬ β†’ e2e μ‹€ν–‰ (`node ./scripts/e2e.js`)
20
+ 5. 24h+ 정체 β†’ task status κ°±μ‹  (`leerness task update`)
21
+ 6. 버전 변동 task β†’ CHANGELOG/README κ°±μ‹  확인 (`leerness whats-new`)
22
+ 7. stress test λˆ„λ½ β†’ μƒˆ stress μž‘μ„± ꢌμž₯
23
+ - 끄기: `--no-next-actions` λ˜λŠ” `LEERNESS_NO_NEXT_ACTIONS=1`
24
+
25
+ ### 2. 24h+ 무 μ§„μ²™ lazy 감지
26
+ - progress-tracker.md mtime β‰₯ 24h β†’ `## ⚠ μ§„μ²™ 정체 감지` μžλ™ 좜λ ₯
27
+ - ν˜„μž¬ in-progress task ID + request μš”μ•½ ν‘œμ‹œ
28
+ - ꢌμž₯ λͺ…λ Ή: `leerness task update <id> --status` / `leerness lazy detect --json`
29
+ - 끄기: `--no-lazy-warn` λ˜λŠ” `LEERNESS_NO_LAZY_WARN=1`
30
+
31
+ ### 3. λˆ„μ  νšŒκ·€ (1.9.188~193) β€” λͺ¨λ‘ μœ μ§€
32
+ - [1.9.193] agents multi consensus β†’ lessons.md μžλ™
33
+ - [1.9.192] _loadOfficialSkillCache + 24h μΊμ‹œ
34
+ - [1.9.191] ꡬ쑰 μ΅œμ ν™” λ³΄κ³ μ„œ 88/100
35
+ - [1.9.190] _selectOne/_selectMany Ctrl+C μ¦‰μ‹œ μ’…λ£Œ
36
+ - [1.9.189] _showSlashCommandList + Tab cycle ν•œ 쀄 κ°±μ‹ 
37
+ - [1.9.188] stdin prompt 전달
38
+
39
+ ### 4. stress-v139 β€” 15/15 PASS
40
+ - EμΆ• 보강 (6: ν•¨μˆ˜ + μ„Ήμ…˜ + μž„μ‹œ μ›Œν¬μŠ€νŽ˜μ΄μŠ€ 톡합) + μ„±λŠ₯ (2) + λˆ„μ  νšŒκ·€ (7)
41
+ - μž„μ‹œ μ›Œν¬μŠ€νŽ˜μ΄μŠ€ mtime 25h κ°•μ œ β†’ ⚠ μ§„μ²™ 정체 감지 βœ“
42
+ - μ„±λŠ₯: --version cold start avg **479 ms** Β· MCP 54 도ꡬ **416 ms**
43
+
44
+ ### 5. 5μΆ• 맀트릭슀 변동
45
+ | μΆ• | 1.9.193 | 1.9.194 | Ξ” |
46
+ |---|---|---|---|
47
+ | E. κ²ŒμœΌλ¦„ λ°©μ§€ | 9/10 | **9.5/10** | +0.5 (λ‹€μŒ 단계 μžλ™ μ œμ•ˆ + lazy 감지) |
48
+ | μ’…ν•© | 45.5/50 (91%) | **46/50 (92%)** | +1% |
49
+
50
+ ### 6. μžλ™ release 흐름
51
+ - main μžλ™ push **56 λΌμš΄λ“œ 연속** (1.9.140~194)
52
+ - npm publish μžλ™ (1.9.178~)
53
+
54
+ ---
55
+
3
56
  ## 1.9.193 β€” 2026-05-21
4
57
 
5
58
  **πŸ€– BμΆ• (λ©€ν‹° Sub-Agent μ˜€μΌ€μŠ€νŠΈλΌ) 보강 β€” agents multi consensus κ²°κ³Ό μžλ™ lessons.md μ €μž₯ + μΊμ‹œ 7일 stale hint.**
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.193-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v138-16%2F16-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-123-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-55_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-91%2F100_(5μΆ•)-brightgreen)]() [![multi-agent](https://img.shields.io/badge/multi--agent-consensus_lessons_μžλ™-success)]() [![perf](https://img.shields.io/badge/cold_start-396ms-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.194-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v139-15%2F15-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-124-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-56_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-92%2F100_(5μΆ•)-brightgreen)]() [![next-actions](https://img.shields.io/badge/handoff-next_actions_μžλ™-success)]() [![perf](https://img.shields.io/badge/cold_start-479ms-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.193 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.194 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ πŸ€– multi-agent consensus lessons μžλ™ Β· 91/100 Β· 123 λΌμš΄λ“œ β•‘
17
+ β•‘ 🎯 handoff next-actions μžλ™ μ œμ•ˆ Β· 92/100 Β· 124 λΌμš΄λ“œ β•‘
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.193';
10
+ const VERSION = '1.9.194';
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 처리).
@@ -1662,6 +1662,112 @@ async function skillAutoCacheCmd(root, sub) {
1662
1662
  if (c.expired) log(` β†’ κ°±μ‹ : leerness skill auto-cache refresh`);
1663
1663
  }
1664
1664
 
1665
+ // 1.9.194: EμΆ• (κ²ŒμœΌλ¦„ λ°©μ§€) β€” handoff μ—μ„œ λ‹€μŒ 단계 1-3개 μžλ™ μ œμ•ˆ
1666
+ // ν˜„μž¬ in-progress task description + Memory Surface (decisions/lessons/plan) μ‘°ν•© β†’
1667
+ // "λ‹€μŒ λ‹¨κ³„λ‘œ 무엇을 ν• μ§€" μΆ”λ‘  (μ‚¬μš©μž/AI 직접 μž…λ ₯ 없이 μ¦‰μ‹œ λ…ΈμΆœ)
1668
+ // μ•Œκ³ λ¦¬μ¦˜:
1669
+ // 1) lessons.md 에 keyword λ§€μΉ­ + μ‹€νŒ¨/λ‘€λ°± ν‚€μ›Œλ“œ β†’ "νšŒν”Ό μ „λž΅ 적용"
1670
+ // 2) plan.md 에 keyword λ§€μΉ­ + M-XXXX β†’ "κ³„νš milestone 검증"
1671
+ // 3) decisions.md 에 keyword λ§€μΉ­ β†’ "κ²°μ • N 영ν–₯ 확인"
1672
+ // 4) review-evidence.md λΆ€μž¬ β†’ "verify-code λ˜λŠ” e2e μ‹€ν–‰"
1673
+ // 5) progress-tracker.md 24h+ 정체 β†’ "task status κ°±μ‹ "
1674
+ // 6) CHANGELOG 보강 λΆ€μž¬ β†’ "버전 λ³€κ²½ μ‹œ CHANGELOG κ°±μ‹ "
1675
+ // 7) stress-vXXX λˆ„λ½ β†’ "stress test μž‘μ„±"
1676
+ // 1.9.116 brainstorm νšŒμˆ˜μ™€ λ‹€λ₯Έ 점: brainstorm 은 "κ΄€λ ¨ hits 회수" / next-actions λŠ” "λ‹€μŒ μ‹€ν–‰ λͺ…λ Ή μ œμ•ˆ"
1677
+ function _suggestNextActions(root, latestRow, keyword) {
1678
+ const actions = [];
1679
+ const taskText = String(latestRow.request || '').toLowerCase();
1680
+ const fuzzyRe = keyword ? new RegExp(escapeRegex(keyword.slice(0, Math.max(4, Math.floor(keyword.length * 0.7)))), 'i') : null;
1681
+
1682
+ // 1) lessons.md μ‹€νŒ¨ λ§€μΉ­ β†’ νšŒν”Ό μ „λž΅
1683
+ try {
1684
+ if (fuzzyRe && exists(lessonsPath(root))) {
1685
+ const lt = read(lessonsPath(root));
1686
+ const blocks = lt.split(/\n### /);
1687
+ const hits = blocks.filter(b => fuzzyRe.test(b) && /(μ‹€νŒ¨|fail|λ‘€λ°±|버그|incomplete)/i.test(b));
1688
+ if (hits.length > 0) {
1689
+ actions.push({ icon: 'πŸ›‘', title: `κ³Όκ±° μ‹€νŒ¨ νšŒν”Ό β€” lessons.md 에 "${keyword}" κ΄€λ ¨ ${hits.length}건`, command: `leerness lessons --auto --path .` });
1690
+ }
1691
+ }
1692
+ } catch {}
1693
+
1694
+ // 2) plan.md milestone λ§€μΉ­ β†’ milestone 검증
1695
+ try {
1696
+ if (fuzzyRe && exists(planPath(root))) {
1697
+ const pt = read(planPath(root));
1698
+ const milestones = (pt.match(/^### (M-\d{4})\..*$/gm) || []).filter(l => fuzzyRe.test(l));
1699
+ if (milestones.length > 0) {
1700
+ const m = milestones[0].match(/M-\d{4}/);
1701
+ if (m) actions.push({ icon: '🎯', title: `plan.md milestone ${m[0]} 검증 β€” "${keyword}" κ΄€λ ¨`, command: `leerness plan list --filter "${keyword}"` });
1702
+ }
1703
+ }
1704
+ } catch {}
1705
+
1706
+ // 3) decisions.md κ²°μ • λ§€μΉ­
1707
+ try {
1708
+ if (fuzzyRe && exists(decisionsPath(root))) {
1709
+ const dt = read(decisionsPath(root));
1710
+ const blocks = _extractDecisionBlocks(dt);
1711
+ const hits = blocks.filter(b => fuzzyRe.test(b));
1712
+ if (hits.length > 0) {
1713
+ actions.push({ icon: 'πŸ’­', title: `decisions.md "${keyword}" κ΄€λ ¨ κ²°μ • ${hits.length}건 영ν–₯ 확인`, command: `leerness decision list --filter "${keyword}"` });
1714
+ }
1715
+ }
1716
+ } catch {}
1717
+
1718
+ // 4) review-evidence.md λΆ€μž¬ β†’ e2e
1719
+ try {
1720
+ if (!exists(evidencePath(root)) || fs.statSync(evidencePath(root)).size < 100) {
1721
+ actions.push({ icon: 'πŸ§ͺ', title: `review-evidence.md λΉ„μ–΄μžˆμŒ β€” e2e λ˜λŠ” verify-code μ‹€ν–‰`, command: `node ./scripts/e2e.js` });
1722
+ }
1723
+ } catch {}
1724
+
1725
+ // 5) 24h+ 정체 β†’ task status κ°±μ‹  (handoff lazy-warn κ³Ό λ³„κ°œ β€” λ‹€μŒ 단계 λͺ…λ Ή)
1726
+ try {
1727
+ const pp = progressPath(root);
1728
+ if (exists(pp)) {
1729
+ const ageHours = Math.floor((Date.now() - fs.statSync(pp).mtimeMs) / 3600000);
1730
+ if (ageHours >= 24 && latestRow.id) {
1731
+ actions.push({ icon: 'πŸ”„', title: `progress-tracker ${ageHours}h 정체 β€” task ${latestRow.id} status κ°±μ‹ `, command: `leerness task update ${latestRow.id} --status completed` });
1732
+ }
1733
+ }
1734
+ } catch {}
1735
+
1736
+ // 6) CHANGELOG / README 버전 일치 확인 (1.9.X bump ν›„ 자주 λˆ„λ½λ˜λŠ” 단계)
1737
+ try {
1738
+ if (/(\d\.\d\.\d+)/.test(taskText) || /(bump|version|release)/i.test(taskText)) {
1739
+ actions.push({ icon: 'πŸ“', title: `버전 변동 task β€” CHANGELOG.md / README.md κ°±μ‹  확인`, command: `node ./bin/harness.js whats-new .` });
1740
+ }
1741
+ } catch {}
1742
+
1743
+ // 7) stress test λˆ„λ½ (자율 λΌμš΄λ“œ 자주 λˆ„λ½)
1744
+ try {
1745
+ const stressDir = path.resolve(root, '..', '_apps', 'leerness-stress', 'bin');
1746
+ if (exists(stressDir)) {
1747
+ const files = fs.readdirSync(stressDir).filter(f => /^stress-v\d+\.js$/.test(f));
1748
+ if (files.length > 0) {
1749
+ const versions = files.map(f => Number(f.match(/v(\d+)/)[1])).sort((a, b) => b - a);
1750
+ const latest = versions[0];
1751
+ // ν˜„μž¬ λΌμš΄λ“œ = 1.9.X μ—μ„œ stress-v(X-55) 정도? λ‹¨μˆœνžˆ μ΅œμ‹  stress κ°€ 7일+ 였래되면 ꢌμž₯
1752
+ const latestFile = path.join(stressDir, `stress-v${latest}.js`);
1753
+ const ageHours = Math.floor((Date.now() - fs.statSync(latestFile).mtimeMs) / 3600000);
1754
+ if (ageHours >= 24 && /(bump|version|보강|μΆ”κ°€|κΈ°λŠ₯)/.test(taskText)) {
1755
+ actions.push({ icon: '🧬', title: `stress-v${latest} λ§ˆμ§€λ§‰ κ°±μ‹  ${ageHours}h μ „ β€” μƒˆ stress test μž‘μ„± ꢌμž₯`, command: `node _apps/leerness-stress/bin/stress-v${latest+1}.js` });
1756
+ }
1757
+ }
1758
+ }
1759
+ } catch {}
1760
+
1761
+ // 쀑볡 제거 (icon+title κΈ°μ€€) + top 3
1762
+ const seen = new Set();
1763
+ return actions.filter(a => {
1764
+ const key = a.icon + a.title.slice(0, 30);
1765
+ if (seen.has(key)) return false;
1766
+ seen.add(key);
1767
+ return true;
1768
+ }).slice(0, 3);
1769
+ }
1770
+
1665
1771
  // 1.9.182: handoff μ»¨ν…μŠ€νŠΈ (ν˜„μž¬ in-progress task) μ—μ„œ μžλ™ query μΆ”μΆœ
1666
1772
  function _autoInstallQueryFromHandoff(root) {
1667
1773
  try {
@@ -3557,6 +3663,51 @@ function handoff(root) {
3557
3663
  }
3558
3664
  } catch {}
3559
3665
  }
3666
+ // 1.9.194: EμΆ• (κ²ŒμœΌλ¦„ λ°©μ§€) 보강 β€” handoff λ‹€μŒ 단계 1-3개 μžλ™ μ œμ•ˆ
3667
+ // ν˜„μž¬ in-progress task description + Memory Surface (decisions/lessons/plan) μ‘°ν•© β†’
3668
+ // "λ‹€μŒ λ‹¨κ³„λ‘œ 무엇을 ν• μ§€" 3개λ₯Ό μ¦‰μ‹œ μ œμ•ˆ (μ‚¬μš©μžκ°€ 직접 μ±„μš°μ§€ μ•Šμ•„λ„ AIμ—κ²Œ λ…ΈμΆœλ¨)
3669
+ // skill installed 여뢀와 무관 β€” keyword 만 있으면 λ™μž‘ (κ²ŒμœΌλ¦„ λ°©μ§€λŠ” λͺ¨λ“  μ›Œν¬μŠ€νŽ˜μ΄μŠ€ ν•„μˆ˜)
3670
+ // 끄기: --no-next-actions λ˜λŠ” LEERNESS_NO_NEXT_ACTIONS=1
3671
+ if (!has('--no-next-actions') && !has('--quiet') && process.env.LEERNESS_NO_NEXT_ACTIONS !== '1') {
3672
+ try {
3673
+ const actions = _suggestNextActions(root, latestRow, keyword);
3674
+ if (actions.length > 0) {
3675
+ const isTty = process.stdout && process.stdout.isTTY;
3676
+ const grn = s => isTty ? `\x1b[32m${s}\x1b[0m` : s;
3677
+ const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3678
+ log(grn(`## 🎯 λ‹€μŒ 단계 μžλ™ μ œμ•ˆ (1.9.194 EμΆ• β€” κ²ŒμœΌλ¦„ λ°©μ§€) β€” ν‚€μ›Œλ“œ "${keyword}"`));
3679
+ for (const a of actions) {
3680
+ log(dim(` ${a.icon} ${a.title}`));
3681
+ if (a.command) log(dim(` \`${a.command}\``));
3682
+ }
3683
+ log(dim(` β†’ 직접 μž…λ ₯: leerness next-action add "<text>"`));
3684
+ log('');
3685
+ }
3686
+ } catch {}
3687
+ }
3688
+ // 1.9.194: 24h+ 무 μ§„μ²™ lazy 감지 β€” progress-tracker mtime 기반
3689
+ // ν˜„μž¬ in-progress task κ°€ 24h 이상 변동 μ—†μœΌλ©΄ "lazy μ˜μ‹¬" hint
3690
+ // 끄기: --no-lazy-warn λ˜λŠ” LEERNESS_NO_LAZY_WARN=1
3691
+ if (!has('--no-lazy-warn') && !has('--quiet') && process.env.LEERNESS_NO_LAZY_WARN !== '1') {
3692
+ try {
3693
+ const pp = progressPath(root);
3694
+ if (exists(pp)) {
3695
+ const ageMs = Date.now() - fs.statSync(pp).mtimeMs;
3696
+ const ageHours = Math.floor(ageMs / 3600000);
3697
+ if (ageHours >= 24) {
3698
+ const isTty = process.stdout && process.stdout.isTTY;
3699
+ const yel = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
3700
+ const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3701
+ const ageLabel = ageHours < 48 ? `${ageHours}h` : `${Math.floor(ageHours/24)}d`;
3702
+ log(yel(`## ⚠ μ§„μ²™ 정체 감지 (1.9.194 EμΆ•) β€” progress-tracker λ§ˆμ§€λ§‰ 변동 ${ageLabel} μ „`));
3703
+ log(dim(` ν˜„μž¬ in-progress task: ${latestRow.id} ${(latestRow.request || '').slice(0, 60)}`));
3704
+ log(dim(` β†’ λ³€κ²½: leerness task update ${latestRow.id} --status in-progress λ˜λŠ” --status completed`));
3705
+ log(dim(` β†’ 회고: leerness lazy detect --json`));
3706
+ log('');
3707
+ }
3708
+ }
3709
+ } catch {}
3710
+ }
3560
3711
  }
3561
3712
  }
3562
3713
  } catch {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.193",
3
+ "version": "1.9.194",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",