leerness 1.9.191 โ†’ 1.9.193

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,126 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.193 โ€” 2026-05-21
4
+
5
+ **๐Ÿค– B์ถ• (๋ฉ€ํ‹ฐ Sub-Agent ์˜ค์ผ€์ŠคํŠธ๋ผ) ๋ณด๊ฐ• โ€” agents multi consensus ๊ฒฐ๊ณผ ์ž๋™ lessons.md ์ €์žฅ + ์บ์‹œ 7์ผ stale hint.**
6
+
7
+ ์ž์œจ ๋ชจ๋“œ 123 ๋ผ์šด๋“œ. 1.9.192 C์ถ• ๋ณด๊ฐ•์— ์ด์–ด, 5์ถ• ๋งคํŠธ๋ฆญ์Šค์—์„œ ๋‘ ๋ฒˆ์งธ๋กœ ์ ์ˆ˜๊ฐ€ ๋‚ฎ์•˜๋˜ **B์ถ• (8.5/10 โ†’ ๋ชฉํ‘œ 9/10)** ๋ณด๊ฐ•.
8
+
9
+ ### ์‚ฌ์šฉ์ž ์˜๋„ ์ •๋ ฌ (1.9.191 verbatim)
10
+ > *"๋ฉ€ํ‹ฐ ์„œ๋ธŒ ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ผ ... ์ตœ๊ณ ์˜ ๋„๊ตฌ"*
11
+
12
+ ### 1. agents multi --execute โ†’ lessons.md ์ž๋™ ์ €์žฅ (B์ถ• ํ•ต์‹ฌ)
13
+ - ๋งค `agents multi --execute` ํ˜ธ์ถœ ์‹œ consensus best agent + score ๊ฐ€ `.harness/lessons.md`์— ๊ธฐ๋ก
14
+ - ๊ฐ™์€ keyword ์žฌ๋ฐœ ์‹œ handoff lessons auto-recall (1.9.56)๊ฐ€ ์ž๋™ ๋งค์นญ โ†’ ๊ณผ๊ฑฐ best agent ์šฐ์„  ์‹œ๋„
15
+ - ๋„๊ธฐ: `LEERNESS_NO_MULTIAGENT_LESSON=1`
16
+
17
+ **lesson ๋ธ”๋ก ํฌ๋งท:**
18
+ ```markdown
19
+ ### 2026-05-21 multi-agent consensus โ€” best=claude (1.9.193)
20
+ - task: ...
21
+ - agents: claude, codex, gemini (3/3 success)
22
+ - best agent: claude, score=0.873
23
+ - others: codex=0.71, gemini=0.65
24
+ - lesson: ๊ฐ™์€ keyword ์žฌ๋ฐœ ์‹œ claude ์šฐ์„  ์‹œ๋„ (multi-signal consensus ์ž…์ฆ)
25
+ ```
26
+
27
+ ### 2. skill auto-cache age 7์ผ stale ๊ฐ•์กฐ (1.9.192 ํ›„์†)
28
+ - handoff body์—์„œ ์บ์‹œ age โ‰ฅ 7์ผ (veryStale) ์‹œ `โš  7์ผ+` ํ‘œ์‹œ
29
+ - ๊ฐฑ์‹  ๊ถŒ์žฅ hint: `1.9.193 7์ผ+ stale` ๋˜๋Š” `24h+ expired` ๋ช…์‹œ
30
+ - ์‚ฌ์šฉ์ž๊ฐ€ "์˜ค๋ž˜๋œ catalog ์ž„์„ ์ธ์ง€" โ†’ ์ž๋™ ๊ฒŒ์œผ๋ฆ„ ๋ฐฉ์ง€
31
+
32
+ ### 3. ๋ˆ„์  ํšŒ๊ท€ (1.9.187~192) โ€” ๋ชจ๋‘ ์œ ์ง€
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 ์ „๋‹ฌ (useStdinForPrompt)
38
+ - [1.9.187] _loadLeernessConfig (.harness/leerness-config.json)
39
+
40
+ ### 4. stress-v138 โ€” 16/16 PASS
41
+ - consensus auto-lessons (3) + cache age hint (2) + 1.9.192 ์ž”์กด (2)
42
+ - ์„ฑ๋Šฅ: --version cold start avg **396 ms** (376/382/430) ยท MCP 54 ๋„๊ตฌ **369 ms**
43
+ - ๋ˆ„์  ํšŒ๊ท€ 1.9.187~192 (7)
44
+
45
+ ### 5. 5์ถ• ๋งคํŠธ๋ฆญ์Šค ๋ณ€๋™
46
+ | ์ถ• | 1.9.192 | 1.9.193 | ฮ” |
47
+ |---|---|---|---|
48
+ | B. ๋ฉ€ํ‹ฐ Sub-Agent ์˜ค์ผ€์ŠคํŠธ๋ผ | 8.5/10 | **9/10** | +0.5 (consensus ์ž๋™ lessons โ†’ ํ•™์Šต ์‚ฌ์ดํด ์™„์„ฑ) |
49
+ | C. ๊ณต์‹ ํ‘œ์ค€ ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ | 9/10 | 9/10 | (์œ ์ง€) |
50
+ | ์ข…ํ•ฉ | 45/50 (90%) | **45.5/50 (91%)** | +1% |
51
+
52
+ ### 6. ์ž๋™ release ํ๋ฆ„
53
+ - main ์ž๋™ push **55 ๋ผ์šด๋“œ ์—ฐ์†** (1.9.140~193)
54
+ - npm publish ์ž๋™ (1.9.178~)
55
+
56
+ ---
57
+
58
+ ## 1.9.192 โ€” 2026-05-21
59
+
60
+ **๐ŸŒ C์ถ• (๊ณต์‹ ํ‘œ์ค€ ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ) ๋ณด๊ฐ• โ€” handoff์— ๊ณต์‹ organization catalog ์ž๋™ ๋…ธ์ถœ + 24h ์บ์‹œ.**
61
+
62
+ ์ž์œจ ๋ชจ๋“œ 122 ๋ผ์šด๋“œ. 1.9.191 5์ถ• ๋งคํŠธ๋ฆญ์Šค์—์„œ ๊ฐ€์žฅ ์ ์ˆ˜๊ฐ€ ๋‚ฎ์•˜๋˜ **C์ถ• (8/10 โ†’ ๋ชฉํ‘œ 9/10)** ๋ณด๊ฐ•.
63
+
64
+ ### ์‚ฌ์šฉ์ž ์˜๋„ (1.9.191 verbatim)
65
+ > *"๊ณต์‹ ํ‘œ์ค€ํ™”๋œ ์Šคํ‚ฌ์„ ์ ์žฌ์ ์†Œ๋กœ ์ž๋™ ํ™œ์šฉ ... ์ตœ๊ณ ์˜ ๋„๊ตฌ๋กœ ๊ฐœ๋ฐœํ•˜๋Š”๊ฒŒ ๋ชฉํ‘œ"*
66
+
67
+ ### 1. ๊ณต์‹ organization skill catalog 24h ์บ์‹œ (์‹ ๊ทœ)
68
+ - ํŒŒ์ผ: `.harness/skill-auto-cache.json` (๋น„์‹œํฌ๋ฆฟ โ€” ์ฒดํฌ์ธ ๊ฐ€๋Šฅ)
69
+ - TTL 24h โ†’ `_OFFICIAL_SKILL_CACHE_TTL_MS` ์ƒ์ˆ˜
70
+ - presets: `vercel-labs/agent-skills` + `anthropics/skills`
71
+ - ํ•จ์ˆ˜: `_loadOfficialSkillCache` / `_writeOfficialSkillCache` / `_refreshOfficialSkillCache` / `_matchOfficialSkillsFromCache`
72
+
73
+ ### 2. handoff ์ž๋™ ๋…ธ์ถœ (์‚ฌ์šฉ์ž ์˜๋„ ์ •๋ ฌ)
74
+ **ํ—ค๋“œ๋ผ์ธ 10๋ฒˆ์งธ ์š”์†Œ** (1.9.81/93/113/152/162/192):
75
+ ```
76
+ ๐Ÿ“Š ํ—ค๋“œ๋ผ์ธ ...ยท ๐ŸŒ official 25/25 (0hโœ“)
77
+ ```
78
+ - `official {๋งค์นญ์ˆ˜}/{์ „์ฒด์ˆ˜} ({์บ์‹œ๋‚˜์ด}{๋งŒ๋ฃŒ์—ฌ๋ถ€})`
79
+ - ์บ์‹œ ๋งŒ๋ฃŒ (24h+) ์‹œ `โš ` ํ‘œ์‹œ
80
+
81
+ **body ์„น์…˜** โ€” in-progress task keyword ๊ธฐ๋ฐ˜ ๋งค์นญ top 3:
82
+ ```
83
+ ## ๐ŸŒ ๊ณต์‹ organization ์Šคํ‚ฌ ์ž๋™ ๋งค์นญ (1.9.192) โ€” ํ‚ค์›Œ๋“œ "..."
84
+ vercel-labs/anthropics ๋“ฑ catalog ์บ์‹œ 0h โœ“ ยท 3/25๊ฑด ๋งค์นญ
85
+ โ€ข [vercel] skill-name โ€” description ...
86
+ โ€ข [anthropic] another-skill โ€” ...
87
+ โ†’ ์„ค์น˜: leerness skill auto-install --yes
88
+ ```
89
+
90
+ ๋„๊ธฐ: `--no-official-skills` ๋˜๋Š” `LEERNESS_NO_OFFICIAL_SKILLS=1`.
91
+
92
+ ### 3. CLI: `leerness skill auto-cache <sub>`
93
+ - `status` (default) โ€” ์บ์‹œ ๋‚˜์ด / ๋งŒ๋ฃŒ / preset / entry ์ˆ˜ + ์ƒ˜ํ”Œ 3๊ฑด
94
+ - `refresh` โ€” vercel-labs + anthropics ๋™๊ธฐํ™” (์‹ค์ธก 25 entries / 612ms)
95
+ - `clear` โ€” ์บ์‹œ ์‚ญ์ œ
96
+
97
+ ### 4. ๋ˆ„์  ํšŒ๊ท€ (1.9.186~191)
98
+ | ๋ฒ„์ „ | ํ•ต์‹ฌ ๊ฒ€์ฆ ํ•ญ๋ชฉ | ์œ ์ง€ |
99
+ |---|---|---|
100
+ | 1.9.191 | ๊ตฌ์กฐ ์ตœ์ ํ™” ๋ณด๊ณ ์„œ 88/100 | โœ“ |
101
+ | 1.9.190 | _selectOne/_selectMany Ctrl+C ์ฆ‰์‹œ ์ข…๋ฃŒ | โœ“ |
102
+ | 1.9.189 | _showSlashCommandList + Tab cycle ํ•œ ์ค„ ๊ฐฑ์‹  | โœ“ |
103
+ | 1.9.188 | stdin prompt ์ „๋‹ฌ (useStdinForPrompt) | โœ“ |
104
+ | 1.9.187 | _loadLeernessConfig (.harness/leerness-config.json) | โœ“ |
105
+ | 1.9.186 | _cliChatStream shell:true (Windows .cmd) | โœ“ |
106
+
107
+ ### 5. stress-v137 โ€” 17/17 PASS
108
+ - ๋ณด๊ณ ์„œ + ํ•จ์ˆ˜ + ํ—ค๋“œ๋ผ์ธ + body + CLI + ํ—ค๋“œ๋ผ์ธ ๋…ธ์ถœ (8)
109
+ - ์„ฑ๋Šฅ hot path: --version cold start avg **398 ms** (3 samples: 417/395/381) ยท MCP 54 ๋„๊ตฌ **387 ms** (2)
110
+ - ๋ˆ„์  ํšŒ๊ท€ 1.9.186~191 (7)
111
+
112
+ ### 6. 5์ถ• ๋งคํŠธ๋ฆญ์Šค ๋ณ€๋™ (๋ชฉํ‘œ)
113
+ | ์ถ• | 1.9.191 | 1.9.192 | ฮ” |
114
+ |---|---|---|---|
115
+ | C. ๊ณต์‹ ํ‘œ์ค€ ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ | 8/10 | **9/10** | +1 (handoff ์ž๋™ ๋…ธ์ถœ + 24h ์บ์‹œ) |
116
+ | ์ข…ํ•ฉ | 44/50 (88%) | **45/50 (90%)** | +2% |
117
+
118
+ ### 7. ์ž๋™ release ํ๋ฆ„ ์œ ์ง€
119
+ - main ์ž๋™ push **54 ๋ผ์šด๋“œ** ์—ฐ์† (1.9.140~192)
120
+ - npm publish ์ž๋™ (1.9.178~)
121
+
122
+ ---
123
+
3
124
  ## 1.9.191 โ€” 2026-05-21
4
125
 
5
126
  **๐Ÿ“Š ๊ตฌ์กฐ ์ตœ์ ํ™” ์‹ค ์ธก์ • + ๋ชฉ์  ๋งคํŠธ๋ฆญ์Šค 88/100 + ScheduleWakeup ์•ˆ์ •ํ™” (์‚ฌ์šฉ์ž ๋ช…์‹œ 3์ข…).**
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.191-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v136-12%2F12-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-121-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-52_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/๋ชฉ์ _๋งคํŠธ๋ฆญ์Šค-88%2F100_(5์ถ•)-brightgreen)]() [![perf](https://img.shields.io/badge/cold_start-339ms-success)]() [![lines](https://img.shields.io/badge/14K_lines-346_ํ•จ์ˆ˜-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.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)]()
6
6
 
7
7
  ```
8
8
  โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
@@ -12,9 +12,9 @@
12
12
  โ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ• โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘ โ•‘
13
13
  โ•‘ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘ โ•‘
14
14
  โ•‘ โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ• โ•šโ•โ•โ•šโ•โ• โ•šโ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ• โ•‘
15
- โ•‘ v1.9.191 AI Agent Reliability Harness + Sandbox โ•‘
15
+ โ•‘ v1.9.193 AI Agent Reliability Harness + Sandbox โ•‘
16
16
  โ•‘ verify ยท remember ยท orchestrate ยท audit ยท sandbox ยท drift โ•‘
17
- โ•‘ ๐Ÿ“Š ๋ชฉ์  ๋งคํŠธ๋ฆญ์Šค 88/100 (5์ถ•) ยท 52 ๋ผ์šด๋“œ ยท 121 autonomous โ•‘
17
+ โ•‘ ๐Ÿค– multi-agent consensus lessons ์ž๋™ ยท 91/100 ยท 123 ๋ผ์šด๋“œ โ•‘
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.191';
10
+ const VERSION = '1.9.193';
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 ์ฒ˜๋ฆฌ).
@@ -1618,6 +1618,50 @@ async function skillAutoInstallCmd(root) {
1618
1618
  log(`โœ“ auto-install ์™„๋ฃŒ: ${installed}๊ฑด ์„ค์น˜ / ${failed}๊ฑด ์‹คํŒจ / ${matched.length - installed - failed}๊ฑด skip`);
1619
1619
  }
1620
1620
 
1621
+ // 1.9.192: skill auto-cache CLI โ€” refresh|status|clear (C์ถ• ๋ณด๊ฐ• ์‚ฌ์šฉ์ž ๋ช…์‹œ)
1622
+ async function skillAutoCacheCmd(root, sub) {
1623
+ root = absRoot(root);
1624
+ const fp = _officialSkillCachePath(root);
1625
+ if (sub === 'refresh') {
1626
+ log(`# leerness skill auto-cache refresh (1.9.192)`);
1627
+ log(` presets: ${Object.keys(SKILL_CATALOG_PRESETS).join(', ')}`);
1628
+ log(` fetching...`);
1629
+ const t0 = Date.now();
1630
+ const entries = await _refreshOfficialSkillCache(root);
1631
+ const dt = Date.now() - t0;
1632
+ if (entries.length > 0) {
1633
+ log(`โœ“ ์บ์‹œ ๊ฐฑ์‹  ์™„๋ฃŒ: ${entries.length}๊ฐœ entry / ${dt}ms`);
1634
+ log(` โ†’ ${rel(root, fp)}`);
1635
+ } else {
1636
+ log(`โš  ์บ์‹œ ๊ฐฑ์‹  ์‹คํŒจ (network/offline?) โ€” 0 entries`);
1637
+ }
1638
+ return;
1639
+ }
1640
+ if (sub === 'clear') {
1641
+ if (exists(fp)) { fs.unlinkSync(fp); log(`โœ“ ์บ์‹œ ์‚ญ์ œ: ${rel(root, fp)}`); }
1642
+ else log(`(์บ์‹œ ์—†์Œ)`);
1643
+ return;
1644
+ }
1645
+ // status (default)
1646
+ log(`# leerness skill auto-cache status (1.9.192)`);
1647
+ const c = _loadOfficialSkillCache(root);
1648
+ if (!c) {
1649
+ log(` โš  ์บ์‹œ ์—†์Œ โ€” \`leerness skill auto-cache refresh\` ๋กœ ์ƒ์„ฑ`);
1650
+ return;
1651
+ }
1652
+ const ageH = Math.floor(c.ageMs / 3600000);
1653
+ log(` ํŒŒ์ผ: ${rel(root, fp)}`);
1654
+ log(` ์ƒ์„ฑ: ${c.at} (${ageH}h ago)${c.expired ? ' โš  ๋งŒ๋ฃŒ (24h+)' : ' โœ“'}`);
1655
+ log(` presets: ${(c.presets || []).join(', ')}`);
1656
+ log(` entries: ${c.entries.length}๊ฑด`);
1657
+ log('');
1658
+ log(` ์ƒ˜ํ”Œ 3๊ฑด:`);
1659
+ for (const e of c.entries.slice(0, 3)) {
1660
+ log(` โ€ข [${e.preset || e.source || '?'}] ${e.name} โ€” ${(e.description || '').slice(0, 60)}`);
1661
+ }
1662
+ if (c.expired) log(` โ†’ ๊ฐฑ์‹ : leerness skill auto-cache refresh`);
1663
+ }
1664
+
1621
1665
  // 1.9.182: handoff ์ปจํ…์ŠคํŠธ (ํ˜„์žฌ in-progress task) ์—์„œ ์ž๋™ query ์ถ”์ถœ
1622
1666
  function _autoInstallQueryFromHandoff(root) {
1623
1667
  try {
@@ -1628,6 +1672,67 @@ function _autoInstallQueryFromHandoff(root) {
1628
1672
  return null;
1629
1673
  }
1630
1674
 
1675
+ // 1.9.192: ๊ณต์‹ organization skill catalog 24h ์บ์‹œ โ€” C์ถ• (๊ณต์‹ ํ‘œ์ค€ ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ) ๋ณด๊ฐ•
1676
+ // ์‚ฌ์šฉ์ž ๋ช…์‹œ (1.9.191): "๊ณต์‹ ํ‘œ์ค€ํ™”๋œ ์Šคํ‚ฌ์„ ์ ์žฌ์ ์†Œ๋กœ ์ž๋™ ํ™œ์šฉ ... ๊ฒŒ์œผ๋ฆ„ ๋ฐฉ์ง€๋“ฑ๋“ฑ ์ตœ๊ณ ์˜ ๋„๊ตฌ"
1677
+ // handoff ๋งˆ๋‹ค GitHub Contents API ํ˜ธ์ถœํ•˜์ง€ ์•Š๋„๋ก 24h TTL โ†’ offline / rate-limit ํšŒํ”ผ
1678
+ // ์บ์‹œ ์œ„์น˜: .harness/skill-auto-cache.json (์ฒดํฌ์ธ ๊ฐ€๋Šฅ โ€” ๋น„์‹œํฌ๋ฆฟ)
1679
+ const _OFFICIAL_SKILL_CACHE_TTL_MS = 24 * 3600 * 1000;
1680
+ function _officialSkillCachePath(root) { return path.join(root, '.harness', 'skill-auto-cache.json'); }
1681
+ function _loadOfficialSkillCache(root) {
1682
+ try {
1683
+ const fp = _officialSkillCachePath(root);
1684
+ if (!exists(fp)) return null;
1685
+ const j = JSON.parse(read(fp));
1686
+ if (!j.at || !Array.isArray(j.entries)) return null;
1687
+ const ageMs = Date.now() - new Date(j.at).getTime();
1688
+ return { ...j, ageMs, expired: ageMs > _OFFICIAL_SKILL_CACHE_TTL_MS };
1689
+ } catch { return null; }
1690
+ }
1691
+ function _writeOfficialSkillCache(root, entries, presets) {
1692
+ try {
1693
+ mkdirp(path.join(root, '.harness'));
1694
+ writeUtf8(_officialSkillCachePath(root), JSON.stringify({ at: new Date().toISOString(), presets, entries }, null, 2));
1695
+ return true;
1696
+ } catch { return false; }
1697
+ }
1698
+ async function _refreshOfficialSkillCache(root) {
1699
+ const presets = Object.keys(SKILL_CATALOG_PRESETS);
1700
+ const allEntries = [];
1701
+ for (const key of presets) {
1702
+ const p = SKILL_CATALOG_PRESETS[key];
1703
+ if (!p) continue;
1704
+ try {
1705
+ const r = await _fetchGitHubSkills(p.owner, p.repo, p.branch, p.path);
1706
+ if (r.ok) {
1707
+ for (const s of r.skills) allEntries.push({ ...s, preset: key });
1708
+ }
1709
+ } catch {}
1710
+ }
1711
+ if (allEntries.length > 0) _writeOfficialSkillCache(root, allEntries, presets);
1712
+ return allEntries;
1713
+ }
1714
+ // query (in-progress task keyword) ์™€ ๋งค์นญ๋˜๋Š” entries ์ถ”์ถœ
1715
+ function _matchOfficialSkillsFromCache(root, query, max) {
1716
+ max = max || 3;
1717
+ const cache = _loadOfficialSkillCache(root);
1718
+ if (!cache || !cache.entries || cache.entries.length === 0) return { entries: [], total: 0, ageHours: null, expired: false, cacheTotal: 0 };
1719
+ const q = String(query || '').toLowerCase().split(/\s+/).filter(Boolean);
1720
+ let matched = cache.entries;
1721
+ if (q.length > 0) {
1722
+ matched = cache.entries.filter(e => {
1723
+ const hay = ((e.name || '') + ' ' + (e.description || '')).toLowerCase();
1724
+ return q.some(token => token.length >= 2 && hay.includes(token));
1725
+ });
1726
+ }
1727
+ return {
1728
+ entries: matched.slice(0, max),
1729
+ total: matched.length,
1730
+ ageHours: Math.floor(cache.ageMs / 3600000),
1731
+ expired: cache.expired,
1732
+ cacheTotal: cache.entries.length
1733
+ };
1734
+ }
1735
+
1631
1736
  // skill export <id> โ€” ๊ธฐ์กด ์ž์ฒด skill์„ agentskills.io ํ‘œ์ค€ SKILL.md๋กœ export
1632
1737
  function skillExportCmd(root, id) {
1633
1738
  if (!id) { fail('์‚ฌ์šฉ๋ฒ•: leerness skill export <id>'); return process.exit(1); }
@@ -3265,10 +3370,21 @@ function handoff(root) {
3265
3370
  if (slashCount > 0) parts.push(`๐Ÿช„ slash 24h ${slashCount}ํšŒ`);
3266
3371
  }
3267
3372
  } catch {}
3373
+ // 10) 1.9.192: ๊ณต์‹ organization skill catalog ์บ์‹œ ๋งค์นญ (C์ถ• ๋ณด๊ฐ• โ€” ์‚ฌ์šฉ์ž ๋ช…์‹œ)
3374
+ // handoff ๋งˆ๋‹ค GitHub API ํ˜ธ์ถœ X (24h TTL ์บ์‹œ) โ†’ in-progress task keyword ์™€ ๋งค์นญ๋˜๋Š” ๊ณต์‹ ์Šคํ‚ฌ ์ˆ˜ ๋…ธ์ถœ
3375
+ try {
3376
+ const q = _autoInstallQueryFromHandoff(root);
3377
+ const m = _matchOfficialSkillsFromCache(root, q, 3);
3378
+ if (m.cacheTotal > 0) {
3379
+ const ageStr = m.ageHours != null ? (m.ageHours < 24 ? `${m.ageHours}h` : `${Math.floor(m.ageHours/24)}d`) : '?';
3380
+ const status = m.expired ? 'โš ' : 'โœ“';
3381
+ parts.push(`๐ŸŒ official ${m.total}/${m.cacheTotal} (${ageStr}${status})`);
3382
+ }
3383
+ } catch {}
3268
3384
  if (parts.length) {
3269
3385
  const isTty = process.stdout && process.stdout.isTTY;
3270
3386
  const cy = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
3271
- log(cy(`๐Ÿ“Š ํ—ค๋“œ๋ผ์ธ (1.9.81/93/113/152/162): ${parts.join(' ยท ')}`));
3387
+ log(cy(`๐Ÿ“Š ํ—ค๋“œ๋ผ์ธ (1.9.81/93/113/152/162/192): ${parts.join(' ยท ')}`));
3272
3388
  }
3273
3389
  } catch {}
3274
3390
  }
@@ -3405,6 +3521,39 @@ function handoff(root) {
3405
3521
  }
3406
3522
  } catch {}
3407
3523
  }
3524
+ // 1.9.192: ๊ณต์‹ organization skill catalog ์ž๋™ ๋งค์นญ (C์ถ• ๋ณด๊ฐ• โ€” ์‚ฌ์šฉ์ž ์˜๋„)
3525
+ // "๊ณต์‹ ํ‘œ์ค€ํ™”๋œ ์Šคํ‚ฌ์„ ์ ์žฌ์ ์†Œ๋กœ ์ž๋™ ํ™œ์šฉ ... ์ตœ๊ณ ์˜ ๋„๊ตฌ" โ€” handoff ์‹œ keyword ๊ธฐ๋ฐ˜ ์ž๋™ ์ถ”์ฒœ
3526
+ // ์บ์‹œ (.harness/skill-auto-cache.json, 24h TTL) ์‚ฌ์šฉ โ†’ GitHub API ๋ถ€๋‹ด X
3527
+ // 1.9.193: cache age > 7์ผ โ†’ ์ž๋™ refresh ๊ถŒ์žฅ hint ๊ฐ•ํ™”
3528
+ // ๋„๊ธฐ: --no-official-skills ๋˜๋Š” LEERNESS_NO_OFFICIAL_SKILLS=1
3529
+ if (!has('--no-official-skills') && !has('--quiet') && process.env.LEERNESS_NO_OFFICIAL_SKILLS !== '1') {
3530
+ try {
3531
+ const ofm = _matchOfficialSkillsFromCache(root, latestRow.request, 3);
3532
+ if (ofm.entries.length > 0) {
3533
+ const isTty = process.stdout && process.stdout.isTTY;
3534
+ const cyan = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
3535
+ const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3536
+ const yel = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
3537
+ const cacheAge = ofm.ageHours != null ? (ofm.ageHours < 24 ? `${ofm.ageHours}h` : `${Math.floor(ofm.ageHours/24)}d`) : '?';
3538
+ // 1.9.193: cache age 7์ผ ์ด์ƒ์ด๋ฉด ๊ฐ•์กฐ ํ‘œ์‹œ (week stale)
3539
+ const veryStale = ofm.ageHours != null && ofm.ageHours >= 24 * 7;
3540
+ log(cyan(`## ๐ŸŒ ๊ณต์‹ organization ์Šคํ‚ฌ ์ž๋™ ๋งค์นญ (1.9.192/193) โ€” ํ‚ค์›Œ๋“œ "${keyword}"`));
3541
+ const ageLabel = veryStale ? yel(`${cacheAge} โš  7์ผ+`) : (ofm.expired ? yel(`${cacheAge} โš  ๋งŒ๋ฃŒ`) : `${cacheAge} โœ“`);
3542
+ log(dim(` vercel-labs/anthropics ๋“ฑ catalog ์บ์‹œ ${ageLabel} ยท ${ofm.total}/${ofm.cacheTotal}๊ฑด ๋งค์นญ`));
3543
+ for (const e of ofm.entries) {
3544
+ log(dim(` โ€ข [${e.preset || e.source || '?'}] ${e.name} โ€” ${(e.description || '').slice(0, 70)}`));
3545
+ }
3546
+ log(dim(` โ†’ ์„ค์น˜: leerness skill auto-install --yes`));
3547
+ if (ofm.expired || veryStale) log(yel(` โ†’ ๊ฐฑ์‹  ๊ถŒ์žฅ: leerness skill auto-cache refresh (1.9.193 ${veryStale ? '7์ผ+ stale' : '24h+ expired'})`));
3548
+ log('');
3549
+ } else if (ofm.cacheTotal === 0) {
3550
+ // ์บ์‹œ ์—†์Œ โ€” ์ฒซ ์‚ฌ์šฉ ์•ˆ๋‚ด
3551
+ const isTty = process.stdout && process.stdout.isTTY;
3552
+ const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3553
+ log(dim(` ๐Ÿ’ก ๊ณต์‹ ์Šคํ‚ฌ catalog ์บ์‹œ ์—†์Œ โ€” \`leerness skill auto-cache refresh\` ๋กœ vercel-labs/anthropics ์บ์‹œ ์ƒ์„ฑ (1.9.192)`));
3554
+ }
3555
+ } catch {}
3556
+ }
3408
3557
  }
3409
3558
  } catch {}
3410
3559
  }
@@ -5903,6 +6052,21 @@ function agentsCmd(root, sub, ...args) {
5903
6052
  const block = `\n## ${today()} agents multi --execute (1.9.156)\n- task: ${task.slice(0, 200)}\n- agents: ${ready.map(x => x.def.id).join(', ')}\n- success: ${ok.length}/${ready.length}\n- best: ${best.agent} (score=${best.score.toFixed(3)})\n`;
5904
6053
  append(tlp, block);
5905
6054
  } catch {}
6055
+ // 1.9.193: B์ถ• (๋ฉ€ํ‹ฐ Sub-Agent ์˜ค์ผ€์ŠคํŠธ๋ผ) ๋ณด๊ฐ• โ€” consensus ๊ฒฐ๊ณผ๋ฅผ lessons.md ์— ์ž๋™ ๊ธฐ๋ก
6056
+ // ๊ฐ™์€ task ์žฌ์‹œ๋„ ์‹œ ๊ณผ๊ฑฐ best agent + score ๊ฐ€ handoff lessons auto-recall ์—์„œ ๋งค์นญ
6057
+ // ๋„๊ธฐ: LEERNESS_NO_MULTIAGENT_LESSON=1
6058
+ if (process.env.LEERNESS_NO_MULTIAGENT_LESSON !== '1') {
6059
+ try {
6060
+ const lp = lessonsPath(root);
6061
+ const lessonBlock = `\n### ${today()} multi-agent consensus โ€” best=${best.agent} (1.9.193)\n`
6062
+ + `- task: ${task.slice(0, 200)}\n`
6063
+ + `- agents: ${ready.map(x => x.def.id).join(', ')} (${ok.length}/${ready.length} success)\n`
6064
+ + `- best agent: ${best.agent}, score=${best.score.toFixed(3)}\n`
6065
+ + (scored.length > 1 ? `- others: ${scored.slice(1, 4).map(s => `${s.agent}=${s.score.toFixed(2)}`).join(', ')}\n` : '')
6066
+ + `- lesson: ๊ฐ™์€ keyword ์žฌ๋ฐœ ์‹œ ${best.agent} ์šฐ์„  ์‹œ๋„ (multi-signal consensus ์ž…์ฆ)\n`;
6067
+ append(lp, lessonBlock);
6068
+ } catch {}
6069
+ }
5906
6070
  }
5907
6071
  if (failures.length && !best) {
5908
6072
  process.exitCode = 1;
@@ -14105,6 +14269,8 @@ async function main() {
14105
14269
  if (cmd === 'skill' && args[1] === 'suggest') return skillSuggestCmd(absRoot(arg('--path', process.cwd())));
14106
14270
  // 1.9.182: leerness skill auto-install โ€” ๊ณต์‹ catalog ์ž๋™ ํƒ์ƒ‰ + skill match ๋งค์นญ ์‹œ ์ž๋™ install (์‚ฌ์šฉ์ž ๋ช…์‹œ)
14107
14271
  if (cmd === 'skill' && args[1] === 'auto-install') return await skillAutoInstallCmd(absRoot(arg('--path', process.cwd())));
14272
+ // 1.9.192: skill auto-cache โ€” ๊ณต์‹ organization catalog 24h ์บ์‹œ ๊ด€๋ฆฌ (C์ถ• ๋ณด๊ฐ•)
14273
+ if (cmd === 'skill' && args[1] === 'auto-cache') return await skillAutoCacheCmd(absRoot(arg('--path', process.cwd())), args[2] || 'status');
14108
14274
  if (cmd === 'mcp' && args[1] === 'serve') return mcpServeCmd(absRoot(arg('--path', process.cwd())));
14109
14275
  if (cmd === 'gate') return gate(args[1] || process.cwd());
14110
14276
  if (cmd === 'verify-code') return verifyCodeCmd(args[1] || process.cwd());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.191",
3
+ "version": "1.9.193",
4
4
  "description": "Leerness: ๋น„ํŒŒ๊ดด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜, ์ž๋™ ๋ฒ„์ „ ๊ฐ์ง€ยท์—…๋ฐ์ดํŠธ, ๊ณ„ํš/์ง„ํ–‰/ํ•ธ๋“œ์˜คํ”„ ์ž๋™ํ™”, ๊ฒŒ์œผ๋ฆ„ยท์‹œํฌ๋ฆฟยท์ธ์ฝ”๋”ฉ ์ž๋™ ๊ฐ€๋“œ, Claude Code ์Šฌ๋ž˜์‹œ ํ†ตํ•ฉ์„ ๊ฐ–์ถ˜ ํ•œ๊ตญ์–ด ์šฐ์„  AI ๊ฐœ๋ฐœ ํ•˜๋„ค์Šค.",
5
5
  "keywords": [
6
6
  "leerness",