leerness 1.9.201 β†’ 1.9.202

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,49 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.202 β€” 2026-05-22
4
+
5
+ **🌐 CμΆ• (곡식 ν‘œμ€€ μŠ€ν‚¬ μžλ™ ν™œμš©) 9.0/10 β†’ 9.5/10 보강 β€” matched skill μ„€μΉ˜ μƒνƒœ ν‘œμ‹œ + leerness skill install-top.**
6
+
7
+ 자율 λͺ¨λ“œ 132 λΌμš΄λ“œ. 100% 맀트릭슀 도전 β€” CμΆ• λ§ˆμ§€λ§‰ 0.5 보강 (97 β†’ 97.5).
8
+
9
+ ### 1. install 이λ ₯ 기둝 + μ„€μΉ˜ μƒνƒœ ν‘œμ‹œ
10
+ - `.harness/skill-installed-log.json` (λΉ„μ‹œν¬λ¦Ώ, 체크인 κ°€λŠ₯)
11
+ - ν•¨μˆ˜: `_loadSkillInstalledLog` / `_appendSkillInstalledLog` / `_isSkillInstalled`
12
+ - handoff matched entry 에 `βœ“ μ„€μΉ˜λ¨` λ˜λŠ” `πŸ†•` νƒœκ·Έ μžλ™ ν‘œμ‹œ
13
+
14
+ ### 2. `leerness skill install-top` μ‹ κ·œ CLI
15
+ - handoff μ»¨ν…μŠ€νŠΈ (in-progress task) 의 keyword 둜 official skill λ§€μΉ­
16
+ - top 1 (이미 μ„€μΉ˜λœ 것 μžλ™ skip) μ¦‰μ‹œ download + install
17
+ - μ„€μΉ˜ ν›„ μžλ™ 이λ ₯ 기둝 β†’ 쀑볡 install λ°©μ§€
18
+ - `--force`: 이미 μ„€μΉ˜λœ 것 κ°•μ œ μž¬μ„€μΉ˜
19
+
20
+ ### 3. handoff body 톡합
21
+ ```
22
+ ## 🌐 곡식 organization μŠ€ν‚¬ μžλ™ λ§€μΉ­ (1.9.192/193) β€” ν‚€μ›Œλ“œ "X"
23
+ βœ“ μ„€μΉ˜λ¨ [vercel] skill-A β€” ...
24
+ πŸ†• [anthropic] skill-B β€” ...
25
+ β†’ 1개 μ¦‰μ‹œ: leerness skill install-top (1.9.202)
26
+ β†’ 전체 μ„€μΉ˜: leerness skill auto-install --yes
27
+ ```
28
+
29
+ ### 4. λˆ„μ  νšŒκ·€ (1.9.196~201) β€” λͺ¨λ‘ μœ μ§€
30
+
31
+ ### 5. stress-v147 β€” 15/15 PASS
32
+ - μ„€μΉ˜ 이λ ₯ (6) + μ„±λŠ₯ (2) + λˆ„μ  νšŒκ·€ (7)
33
+ - μ„±λŠ₯: --version cold start avg **457 ms** Β· MCP 54 도ꡬ **468 ms**
34
+
35
+ ### 6. 5μΆ• 맀트릭슀
36
+ | μΆ• | 1.9.201 | 1.9.202 | μƒνƒœ |
37
+ |---|---|---|---|
38
+ | C. 곡식 ν‘œμ€€ μŠ€ν‚¬ μžλ™ ν™œμš© | 9.0 | **9.5** | +0.5 (μ„€μΉ˜ μƒνƒœ + install-top) |
39
+ | **μ’…ν•©** | 48.5/50 (97%) | **49/50 (98%)** | **+1%** |
40
+
41
+ ### 7. μžλ™ release
42
+ - main μžλ™ push **64 λΌμš΄λ“œ 연속** (1.9.140~202)
43
+ - npm publish μžλ™ (1.9.178~)
44
+
45
+ ---
46
+
3
47
  ## 1.9.201 β€” 2026-05-22
4
48
 
5
49
  **🎯 EμΆ• (κ²ŒμœΌλ¦„ λ°©μ§€) 9.5/10 β†’ 10/10 보강 β€” next-action queue + leerness next-action take λͺ…λ Ή.**
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.201-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v146-16%2F16-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-131-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-63_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-97%2F100_(5μΆ•)-brightgreen)]() [![next-action](https://img.shields.io/badge/next--action-1step_μžλ™_task_add-success)]() [![perf](https://img.shields.io/badge/cold_start-436ms-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.202-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v147-15%2F15-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-132-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-64_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-98%2F100_(5μΆ•)-brightgreen)]() [![skill-install-top](https://img.shields.io/badge/skill-install--top_μ¦‰μ‹œ-success)]() [![perf](https://img.shields.io/badge/cold_start-457ms-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.201 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.202 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ 🎯 next-action 1step Β· 맀트릭슀 97/100 Β· AΒ·DΒ·E 10/10 β•‘
17
+ β•‘ 🌐 skill install-top + μ„€μΉ˜ μƒνƒœ Β· 맀트릭슀 98/100 Β· AΒ·DΒ·E 10/10 β•‘
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.201';
10
+ const VERSION = '1.9.202';
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 처리).
@@ -1556,6 +1556,77 @@ async function skillDiscoverCmd(root) {
1556
1556
  log(`πŸ’‘ μ„€μΉ˜: leerness skill install <url>`);
1557
1557
  }
1558
1558
 
1559
+ // 1.9.202: CμΆ• (곡식 ν‘œμ€€ μŠ€ν‚¬ μžλ™ ν™œμš©) 9.0β†’9.5 보강 β€” install 이λ ₯ 기둝 + μ„€μΉ˜ μƒνƒœ ν‘œμ‹œ
1560
+ // 1.9.192 official catalog λ§€μΉ­ μ‹œ "이미 μ„€μΉ˜λ¨" / "μ‹ κ·œ" ꡬ뢄 β†’ 쀑볡 install λ°©μ§€ + μ‚¬μš©μž 인지 도움
1561
+ // 파일: .harness/skill-installed-log.json (λΉ„μ‹œν¬λ¦Ώ)
1562
+ function _skillInstalledLogPath(root) { return path.join(root, '.harness', 'skill-installed-log.json'); }
1563
+ function _loadSkillInstalledLog(root) {
1564
+ try {
1565
+ const fp = _skillInstalledLogPath(root);
1566
+ if (!exists(fp)) return { installed: [] };
1567
+ const j = JSON.parse(read(fp));
1568
+ return { installed: Array.isArray(j.installed) ? j.installed : [] };
1569
+ } catch { return { installed: [] }; }
1570
+ }
1571
+ function _appendSkillInstalledLog(root, entry) {
1572
+ try {
1573
+ const state = _loadSkillInstalledLog(root);
1574
+ const e = { name: entry.name, source: entry.source || entry.preset || '?', url: entry.url || '', at: new Date().toISOString() };
1575
+ // 쀑볡 (같은 name + source) 제거 ν›„ append
1576
+ state.installed = state.installed.filter(x => !(x.name === e.name && x.source === e.source));
1577
+ state.installed.push(e);
1578
+ mkdirp(path.join(root, '.harness'));
1579
+ writeUtf8(_skillInstalledLogPath(root), JSON.stringify({ installed: state.installed }, null, 2));
1580
+ return true;
1581
+ } catch { return false; }
1582
+ }
1583
+ function _isSkillInstalled(root, entry) {
1584
+ try {
1585
+ const state = _loadSkillInstalledLog(root);
1586
+ const src = entry.source || entry.preset || '?';
1587
+ return state.installed.some(x => x.name === entry.name && x.source === src);
1588
+ } catch { return false; }
1589
+ }
1590
+
1591
+ // 1.9.202: leerness skill install-top β€” handoff matched 의 top 1 entry λ₯Ό μ¦‰μ‹œ install
1592
+ async function skillInstallTopCmd(root) {
1593
+ root = absRoot(root);
1594
+ // handoff context 의 keyword μΆ”μΆœ
1595
+ const rows = readProgressRows(root);
1596
+ const active = rows.find(r => r.status === 'in-progress' || r.status === '[μ§„ν–‰]') || rows[rows.length - 1];
1597
+ if (!active || !active.request) { fail('in-progress task μ—†μŒ β€” leerness handoff . λ¨Όμ €'); return process.exit(1); }
1598
+ const m = _matchOfficialSkillsFromCache(root, active.request, 3);
1599
+ if (m.entries.length === 0) {
1600
+ fail(`맀칭된 official skill μ—†μŒ (keyword: "${(active.request || '').slice(0, 40)}", cache total: ${m.cacheTotal || 0})`);
1601
+ return process.exit(1);
1602
+ }
1603
+ // 이미 μ„€μΉ˜λœ 것 skip
1604
+ const candidates = m.entries.filter(e => !_isSkillInstalled(root, e));
1605
+ if (candidates.length === 0) {
1606
+ log(`βœ“ λͺ¨λ“  맀칭된 skill 이미 μ„€μΉ˜λ¨ (1.9.202 log κΈ°μ€€):`);
1607
+ for (const e of m.entries) log(` β€’ ${e.name} (${e.preset || e.source}) β€” 이미 μ„€μΉ˜`);
1608
+ log(` β†’ leerness skill install-top --force 둜 μž¬μ„€μΉ˜`);
1609
+ return;
1610
+ }
1611
+ const top = has('--force') ? m.entries[0] : candidates[0];
1612
+ log(`# leerness skill install-top (1.9.202 CμΆ• 보강)`);
1613
+ log(` task: ${(active.request || '').slice(0, 80)}`);
1614
+ log(` λ§€μΉ­: ${m.total}/${m.cacheTotal}건 Β· top 1 β†’ ${top.name} (${top.preset || top.source})`);
1615
+ log(` URL: ${top.url || '(none)'}`);
1616
+ log('');
1617
+ if (!top.url) { fail(`top entry url λΆ€μž¬ β€” install λΆˆκ°€`); return process.exit(1); }
1618
+ try {
1619
+ log(`πŸ“₯ install μ‹œμž‘...`);
1620
+ await skillInstallCmd(root, top.url);
1621
+ _appendSkillInstalledLog(root, top);
1622
+ log('');
1623
+ log(`βœ“ μ„€μΉ˜ + 이λ ₯ 기둝 μ™„λ£Œ (.harness/skill-installed-log.json)`);
1624
+ } catch (e) {
1625
+ fail(`install μ‹€νŒ¨: ${e.message}`);
1626
+ return process.exit(1);
1627
+ }
1628
+ }
1629
+
1559
1630
  // 1.9.182: skill auto-install β€” 곡식 organization catalog μžλ™ 탐색 β†’ skill match β†’ μžλ™ install.
1560
1631
  // μ‚¬μš©μž λͺ…μ‹œ: "μŠ€ν‚¬μ„ μ‚¬μš©ν•˜κ±°λ‚˜ μ μš©ν•΄λ‘λ©΄ 쒋을 뢀뢄듀을 μ•Œμ•„μ„œ μ›Ήμ—μ„œ 곡식 쑰직의 μŠ€ν‚¬ λͺ¨μŒμ„ νƒμƒ‰ν•΄μ„œ λ‹€μš΄λ‘œλ“œ λ°›μ•„μ„œ μ‚¬μš©"
1561
1632
  // μ •μ±…: LEERNESS_SKILL_AUTO_INSTALL=1 일 λ•Œλ§Œ μ‹€μ œ install (λ³΄μ•ˆ opt-in). λ―Έμ„€μ • μ‹œ dry-run (μΆ”μ²œλ§Œ).
@@ -3835,10 +3906,14 @@ function handoff(root) {
3835
3906
  log(cyan(`## 🌐 곡식 organization μŠ€ν‚¬ μžλ™ λ§€μΉ­ (1.9.192/193) β€” ν‚€μ›Œλ“œ "${keyword}"`));
3836
3907
  const ageLabel = veryStale ? yel(`${cacheAge} ⚠ 7일+`) : (ofm.expired ? yel(`${cacheAge} ⚠ 만료`) : `${cacheAge} βœ“`);
3837
3908
  log(dim(` vercel-labs/anthropics λ“± catalog μΊμ‹œ ${ageLabel} Β· ${ofm.total}/${ofm.cacheTotal}건 λ§€μΉ­`));
3909
+ // 1.9.202: 각 entry 의 μ„€μΉ˜ μƒνƒœ ν‘œμ‹œ (installed/new)
3838
3910
  for (const e of ofm.entries) {
3839
- log(dim(` β€’ [${e.preset || e.source || '?'}] ${e.name} β€” ${(e.description || '').slice(0, 70)}`));
3911
+ const installed = _isSkillInstalled(root, e);
3912
+ const tag = installed ? 'βœ“ μ„€μΉ˜λ¨' : 'πŸ†•';
3913
+ log(dim(` ${tag} [${e.preset || e.source || '?'}] ${e.name} β€” ${(e.description || '').slice(0, 65)}`));
3840
3914
  }
3841
- log(dim(` β†’ μ„€μΉ˜: leerness skill auto-install --yes`));
3915
+ log(dim(` β†’ 1개 μ¦‰μ‹œ: leerness skill install-top (1.9.202)`));
3916
+ log(dim(` β†’ 전체 μ„€μΉ˜: leerness skill auto-install --yes`));
3842
3917
  if (ofm.expired || veryStale) log(yel(` β†’ κ°±μ‹  ꢌμž₯: leerness skill auto-cache refresh (1.9.193 ${veryStale ? '7일+ stale' : '24h+ expired'})`));
3843
3918
  log('');
3844
3919
  } else if (ofm.cacheTotal === 0) {
@@ -14875,6 +14950,8 @@ async function main() {
14875
14950
  if (cmd === 'skill' && args[1] === 'suggest') return skillSuggestCmd(absRoot(arg('--path', process.cwd())));
14876
14951
  // 1.9.182: leerness skill auto-install β€” 곡식 catalog μžλ™ 탐색 + skill match λ§€μΉ­ μ‹œ μžλ™ install (μ‚¬μš©μž λͺ…μ‹œ)
14877
14952
  if (cmd === 'skill' && args[1] === 'auto-install') return await skillAutoInstallCmd(absRoot(arg('--path', process.cwd())));
14953
+ // 1.9.202: leerness skill install-top β€” handoff matched top 1 μ¦‰μ‹œ install (CμΆ• 9β†’9.5 보강)
14954
+ if (cmd === 'skill' && args[1] === 'install-top') return await skillInstallTopCmd(absRoot(arg('--path', process.cwd())));
14878
14955
  // 1.9.192: skill auto-cache β€” 곡식 organization catalog 24h μΊμ‹œ 관리 (CμΆ• 보강)
14879
14956
  if (cmd === 'skill' && args[1] === 'auto-cache') return await skillAutoCacheCmd(absRoot(arg('--path', process.cwd())), args[2] || 'status');
14880
14957
  if (cmd === 'mcp' && args[1] === 'serve') return mcpServeCmd(absRoot(arg('--path', process.cwd())));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.201",
3
+ "version": "1.9.202",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",