leerness 1.9.190 โ†’ 1.9.192

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,135 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.192 โ€” 2026-05-21
4
+
5
+ **๐ŸŒ C์ถ• (๊ณต์‹ ํ‘œ์ค€ ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ) ๋ณด๊ฐ• โ€” handoff์— ๊ณต์‹ organization catalog ์ž๋™ ๋…ธ์ถœ + 24h ์บ์‹œ.**
6
+
7
+ ์ž์œจ ๋ชจ๋“œ 122 ๋ผ์šด๋“œ. 1.9.191 5์ถ• ๋งคํŠธ๋ฆญ์Šค์—์„œ ๊ฐ€์žฅ ์ ์ˆ˜๊ฐ€ ๋‚ฎ์•˜๋˜ **C์ถ• (8/10 โ†’ ๋ชฉํ‘œ 9/10)** ๋ณด๊ฐ•.
8
+
9
+ ### ์‚ฌ์šฉ์ž ์˜๋„ (1.9.191 verbatim)
10
+ > *"๊ณต์‹ ํ‘œ์ค€ํ™”๋œ ์Šคํ‚ฌ์„ ์ ์žฌ์ ์†Œ๋กœ ์ž๋™ ํ™œ์šฉ ... ์ตœ๊ณ ์˜ ๋„๊ตฌ๋กœ ๊ฐœ๋ฐœํ•˜๋Š”๊ฒŒ ๋ชฉํ‘œ"*
11
+
12
+ ### 1. ๊ณต์‹ organization skill catalog 24h ์บ์‹œ (์‹ ๊ทœ)
13
+ - ํŒŒ์ผ: `.harness/skill-auto-cache.json` (๋น„์‹œํฌ๋ฆฟ โ€” ์ฒดํฌ์ธ ๊ฐ€๋Šฅ)
14
+ - TTL 24h โ†’ `_OFFICIAL_SKILL_CACHE_TTL_MS` ์ƒ์ˆ˜
15
+ - presets: `vercel-labs/agent-skills` + `anthropics/skills`
16
+ - ํ•จ์ˆ˜: `_loadOfficialSkillCache` / `_writeOfficialSkillCache` / `_refreshOfficialSkillCache` / `_matchOfficialSkillsFromCache`
17
+
18
+ ### 2. handoff ์ž๋™ ๋…ธ์ถœ (์‚ฌ์šฉ์ž ์˜๋„ ์ •๋ ฌ)
19
+ **ํ—ค๋“œ๋ผ์ธ 10๋ฒˆ์งธ ์š”์†Œ** (1.9.81/93/113/152/162/192):
20
+ ```
21
+ ๐Ÿ“Š ํ—ค๋“œ๋ผ์ธ ...ยท ๐ŸŒ official 25/25 (0hโœ“)
22
+ ```
23
+ - `official {๋งค์นญ์ˆ˜}/{์ „์ฒด์ˆ˜} ({์บ์‹œ๋‚˜์ด}{๋งŒ๋ฃŒ์—ฌ๋ถ€})`
24
+ - ์บ์‹œ ๋งŒ๋ฃŒ (24h+) ์‹œ `โš ` ํ‘œ์‹œ
25
+
26
+ **body ์„น์…˜** โ€” in-progress task keyword ๊ธฐ๋ฐ˜ ๋งค์นญ top 3:
27
+ ```
28
+ ## ๐ŸŒ ๊ณต์‹ organization ์Šคํ‚ฌ ์ž๋™ ๋งค์นญ (1.9.192) โ€” ํ‚ค์›Œ๋“œ "..."
29
+ vercel-labs/anthropics ๋“ฑ catalog ์บ์‹œ 0h โœ“ ยท 3/25๊ฑด ๋งค์นญ
30
+ โ€ข [vercel] skill-name โ€” description ...
31
+ โ€ข [anthropic] another-skill โ€” ...
32
+ โ†’ ์„ค์น˜: leerness skill auto-install --yes
33
+ ```
34
+
35
+ ๋„๊ธฐ: `--no-official-skills` ๋˜๋Š” `LEERNESS_NO_OFFICIAL_SKILLS=1`.
36
+
37
+ ### 3. CLI: `leerness skill auto-cache <sub>`
38
+ - `status` (default) โ€” ์บ์‹œ ๋‚˜์ด / ๋งŒ๋ฃŒ / preset / entry ์ˆ˜ + ์ƒ˜ํ”Œ 3๊ฑด
39
+ - `refresh` โ€” vercel-labs + anthropics ๋™๊ธฐํ™” (์‹ค์ธก 25 entries / 612ms)
40
+ - `clear` โ€” ์บ์‹œ ์‚ญ์ œ
41
+
42
+ ### 4. ๋ˆ„์  ํšŒ๊ท€ (1.9.186~191)
43
+ | ๋ฒ„์ „ | ํ•ต์‹ฌ ๊ฒ€์ฆ ํ•ญ๋ชฉ | ์œ ์ง€ |
44
+ |---|---|---|
45
+ | 1.9.191 | ๊ตฌ์กฐ ์ตœ์ ํ™” ๋ณด๊ณ ์„œ 88/100 | โœ“ |
46
+ | 1.9.190 | _selectOne/_selectMany Ctrl+C ์ฆ‰์‹œ ์ข…๋ฃŒ | โœ“ |
47
+ | 1.9.189 | _showSlashCommandList + Tab cycle ํ•œ ์ค„ ๊ฐฑ์‹  | โœ“ |
48
+ | 1.9.188 | stdin prompt ์ „๋‹ฌ (useStdinForPrompt) | โœ“ |
49
+ | 1.9.187 | _loadLeernessConfig (.harness/leerness-config.json) | โœ“ |
50
+ | 1.9.186 | _cliChatStream shell:true (Windows .cmd) | โœ“ |
51
+
52
+ ### 5. stress-v137 โ€” 17/17 PASS
53
+ - ๋ณด๊ณ ์„œ + ํ•จ์ˆ˜ + ํ—ค๋“œ๋ผ์ธ + body + CLI + ํ—ค๋“œ๋ผ์ธ ๋…ธ์ถœ (8)
54
+ - ์„ฑ๋Šฅ hot path: --version cold start avg **398 ms** (3 samples: 417/395/381) ยท MCP 54 ๋„๊ตฌ **387 ms** (2)
55
+ - ๋ˆ„์  ํšŒ๊ท€ 1.9.186~191 (7)
56
+
57
+ ### 6. 5์ถ• ๋งคํŠธ๋ฆญ์Šค ๋ณ€๋™ (๋ชฉํ‘œ)
58
+ | ์ถ• | 1.9.191 | 1.9.192 | ฮ” |
59
+ |---|---|---|---|
60
+ | C. ๊ณต์‹ ํ‘œ์ค€ ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ | 8/10 | **9/10** | +1 (handoff ์ž๋™ ๋…ธ์ถœ + 24h ์บ์‹œ) |
61
+ | ์ข…ํ•ฉ | 44/50 (88%) | **45/50 (90%)** | +2% |
62
+
63
+ ### 7. ์ž๋™ release ํ๋ฆ„ ์œ ์ง€
64
+ - main ์ž๋™ push **54 ๋ผ์šด๋“œ** ์—ฐ์† (1.9.140~192)
65
+ - npm publish ์ž๋™ (1.9.178~)
66
+
67
+ ---
68
+
69
+ ## 1.9.191 โ€” 2026-05-21
70
+
71
+ **๐Ÿ“Š ๊ตฌ์กฐ ์ตœ์ ํ™” ์‹ค ์ธก์ • + ๋ชฉ์  ๋งคํŠธ๋ฆญ์Šค 88/100 + ScheduleWakeup ์•ˆ์ •ํ™” (์‚ฌ์šฉ์ž ๋ช…์‹œ 3์ข…).**
72
+
73
+ ์ž์œจ ๋ชจ๋“œ 121 ๋ผ์šด๋“œ. ์‚ฌ์šฉ์ž ๋ช…์‹œ:
74
+ 1. *"ScheduleWakeup์˜ ๊ฐ„๊ฒฉ์„ ์ค„์—ฌ์ฃผ๊ณ , ๋ชป์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข…์žˆ๋Š”๊ฑฐ๊ฐ™์•„"*
75
+ 2. *"leerness์˜ ๊ตฌ์กฐ๊ฐ€ ์ตœ์ ํ™” ๋˜์–ด์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธ ๋ฐ ๋””๋ฒ„๊ทธ๋„ ์ง„ํ–‰"*
76
+ 3. *"๋ฒ”์šฉ AI ํ•˜๋„ค์Šค + ๋ฉ€ํ‹ฐ sub-agent ์˜ค์ผ€์ŠคํŠธ๋ผ + ๊ณต์‹ ํ‘œ์ค€ํ™” ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ + ์žฅ๊ธฐ ๋งฅ๋ฝ + ๊ฒŒ์œผ๋ฆ„ ๋ฐฉ์ง€ = ์ตœ๊ณ ์˜ ๋„๊ตฌ"*
77
+
78
+ ### 1. ์‹ค ์ธก์ • ๋ฉ”ํŠธ๋ฆญ (1.9.191 vs 1.9.186)
79
+
80
+ | ํ•ญ๋ชฉ | 1.9.191 | 1.9.186 ๋Œ€๋น„ | ํ‰๊ฐ€ |
81
+ |---|---|---|---|
82
+ | `bin/harness.js` lines | **14,243** | +2,243 (+18.7%) | โš  15K ๊ถŒ์žฅ ์ƒํ•œ ๊ทผ์ ‘ |
83
+ | ํ•จ์ˆ˜ ์ˆ˜ | **346** | +96 | โœ“ |
84
+ | CLI ๋ช…๋ น ๋ผ์šฐํŒ… | **122** | +20 | โœ“ |
85
+ | MCP ๋„๊ตฌ | **54** | ๋™๋“ฑ | โœ“ |
86
+ | npm tarball | **371 KB** | +13 KB | โœ“ |
87
+ | `--version` cold | **339 ms** | -10 ms | โœ“ |
88
+ | `handoff` ์‹ค ์›Œํฌ๋กœ๋“œ | **355 ms** | -50 ms | โœ“ |
89
+
90
+ ### 2. ๋ชฉ์  ๋งคํŠธ๋ฆญ์Šค 5์ถ• ํ‰๊ฐ€ (44/50 = 88%)
91
+
92
+ | ์ถ• | ์ ์ˆ˜ | ํ•ต์‹ฌ capability |
93
+ |---|---|---|
94
+ | A. ๋ฒ”์šฉ AI ํ•˜๋„ค์Šค | **9/10** | 5 provider + ์˜์กด์„ฑ 0 + cross-platform |
95
+ | B. ๋ฉ€ํ‹ฐ Sub-Agent ์˜ค์ผ€์ŠคํŠธ๋ผ | **8.5/10** | `agents multi --execute` + consensus + Tab cycle |
96
+ | C. ๊ณต์‹ ํ‘œ์ค€ ์Šคํ‚ฌ ์ž๋™ ํ™œ์šฉ | **8/10** | vercel/anthropic preset + auto-install (opt-in) |
97
+ | D. ์žฅ๊ธฐ ๋งฅ๋ฝ/๊ณ„ํš ์œ ์ง€ | **9.5/10** | Memory 5์ข… CRUD + handoff 6์ฑ„๋„ + 51 ๋ผ์šด๋“œ main push |
98
+ | E. ๊ฒŒ์œผ๋ฆ„ ๋ฐฉ์ง€ | **9/10** | verify-claim + lazy detect + audit + drift check |
99
+
100
+ **๋‚จ์€ 12%** (1.9.192~200 ๋งˆ์ผ์Šคํ†ค):
101
+ - Tier 1: skill-utility-retro + ์™ธ๋ถ€ SECURITY check
102
+ - Tier 2: `_buildCliArgs` ๊ณตํ†ต ํ—ฌํผ (์ฝ”๋“œ ์ค‘๋ณต ์ œ๊ฑฐ)
103
+ - Tier 3: Universal MCP gateway (์™ธ๋ถ€ MCP ํ†ตํ•ฉ)
104
+ - Tier 4: Continuous learning (lessons โ†’ skill ์ž๋™ ๋ณ€ํ™˜)
105
+
106
+ ### 3. ScheduleWakeup ์•ˆ์ •ํ™” (์‚ฌ์šฉ์ž ๋ช…์‹œ)
107
+
108
+ **๋ชป ์ผ์–ด๋‚˜๋Š” ์ผ€์ด์Šค ์›์ธ ๋ถ„์„**:
109
+ | ์›์ธ | ๋นˆ๋„ | ํšŒํ”ผ |
110
+ |---|---|---|
111
+ | ์‹œ์Šคํ…œ sleep/suspend | ๋†’์Œ | โŒ OS ํ•œ๊ณ„ |
112
+ | ์‚ฌ์šฉ์ž ํ™œ์„ฑ conversation ๊ฐ€๋กœ์ฑ„๊ธฐ | ์ค‘๊ฐ„ | โŒ ์šฐ์„ ์ˆœ์œ„ ์ถฉ๋Œ |
113
+ | wakeup delay ๋„ˆ๋ฌด ๊น€ | ์ค‘๊ฐ„ | โœ“ delay ๋‹จ์ถ• |
114
+
115
+ **Fix**: ์ด ๋ผ์šด๋“œ๋ถ€ํ„ฐ **delay 1500s โ†’ 900s (15๋ถ„)**. ์‚ฌ์šฉ์ž ์„ธ์…˜ ํ™œ์„ฑ ๋™์•ˆ ๋” ๋นˆ๋ฒˆํ•œ ์ž์œจ ์ง„ํ–‰.
116
+
117
+ ### 4. ๊ตฌ์กฐ ์ตœ์ ํ™” ํ›„๋ณด (๋‹ค์Œ ๋ผ์šด๋“œ)
118
+
119
+ - 14K lines monolithic โ†’ ๊ณง 15K ๋„๋‹ฌ โ†’ ๋ชจ๋“ˆ ๋ถ„๋ฆฌ ๊ฒ€ํ†  (Tier 2)
120
+ - skill catalog mtime ๊ธฐ๋ฐ˜ invalidation (์บ์‹œ stale ํšŒํ”ผ)
121
+ - task list 280+๊ฑด โ†’ 50๊ฑด ์ด์ƒ archive ์ž๋™ํ™”
122
+
123
+ ์ƒ์„ธ ๋ณด๊ณ ์„œ: `_reports/structure-optimization-1.9.191.md` (๋น„๊ณต๊ฐœ)
124
+
125
+ ### Verified
126
+ - stress-v136: **12/12 PASS** (๋ณด๊ณ ์„œ 3 + ์„ฑ๋Šฅ 2 + ๋ˆ„์  7)
127
+ - e2e 217/217 baseline ์œ ์ง€
128
+ - `--version` 339ms ยท MCP tools/list 334ms ยท handoff 355ms
129
+ - VERSION = 1.9.191 ยท autonomous-rounds = 121 ยท main ์ž๋™ push 52 ๋ผ์šด๋“œ ์—ฐ์†
130
+
131
+ ---
132
+
3
133
  ## 1.9.190 โ€” 2026-05-21
4
134
 
5
135
  **๐Ÿšจ ์„ค์น˜ ๊ฐ€์ด๋“œ Ctrl+C ๋ฏธ์ž‘๋™ BUG fix (์‚ฌ์šฉ์ž ๋ช…์‹œ โ€” npx ์ง„ํ–‰ ์ฐจ๋‹จ).**
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.190-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v135-13%2F13-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-120-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-51_rounds-success)]() [![ctrl-c](https://img.shields.io/badge/์„ค์น˜_Ctrl%2BC-์ฆ‰์‹œ_์ข…๋ฃŒ_BUG_fix-success)]() [![slash-list](https://img.shields.io/badge/"/"_slash-์ž๋™_๋ช…๋ น_list-success)]() [![cycle-clean](https://img.shields.io/badge/Tab_cycle-ํ•œ_์ค„_๊ฐฑ์‹ -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.192-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v137-17%2F17-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-122-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-54_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/๋ชฉ์ _๋งคํŠธ๋ฆญ์Šค-90%2F100_(5์ถ•)-brightgreen)]() [![official-skills](https://img.shields.io/badge/official_skills-handoff_์ž๋™_๋…ธ์ถœ-success)]() [![perf](https://img.shields.io/badge/cold_start-398ms-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.190 AI Agent Reliability Harness + Sandbox โ•‘
15
+ โ•‘ v1.9.192 AI Agent Reliability Harness + Sandbox โ•‘
16
16
  โ•‘ verify ยท remember ยท orchestrate ยท audit ยท sandbox ยท drift โ•‘
17
- โ•‘ ๐Ÿšจ ์„ค์น˜ Ctrl+C ์ฆ‰์‹œ ์ข…๋ฃŒ BUG fix ยท 51 ๋ผ์šด๋“œ main push โ•‘
17
+ โ•‘ ๐ŸŒ official skills handoff ์ž๋™ ยท ๋งคํŠธ๋ฆญ์Šค 90/100 ยท 122 ๋ผ์šด๋“œ โ•‘
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.190';
10
+ const VERSION = '1.9.192';
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,34 @@ 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
+ // ๋„๊ธฐ: --no-official-skills ๋˜๋Š” LEERNESS_NO_OFFICIAL_SKILLS=1
3528
+ if (!has('--no-official-skills') && !has('--quiet') && process.env.LEERNESS_NO_OFFICIAL_SKILLS !== '1') {
3529
+ try {
3530
+ const ofm = _matchOfficialSkillsFromCache(root, latestRow.request, 3);
3531
+ if (ofm.entries.length > 0) {
3532
+ const isTty = process.stdout && process.stdout.isTTY;
3533
+ const cyan = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
3534
+ const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3535
+ const cacheAge = ofm.ageHours != null ? (ofm.ageHours < 24 ? `${ofm.ageHours}h` : `${Math.floor(ofm.ageHours/24)}d`) : '?';
3536
+ log(cyan(`## ๐ŸŒ ๊ณต์‹ organization ์Šคํ‚ฌ ์ž๋™ ๋งค์นญ (1.9.192) โ€” ํ‚ค์›Œ๋“œ "${keyword}"`));
3537
+ log(dim(` vercel-labs/anthropics ๋“ฑ catalog ์บ์‹œ ${cacheAge}${ofm.expired ? ' โš  ๋งŒ๋ฃŒ' : ''} ยท ${ofm.total}/${ofm.cacheTotal}๊ฑด ๋งค์นญ`));
3538
+ for (const e of ofm.entries) {
3539
+ log(dim(` โ€ข [${e.preset || e.source || '?'}] ${e.name} โ€” ${(e.description || '').slice(0, 70)}`));
3540
+ }
3541
+ log(dim(` โ†’ ์„ค์น˜: leerness skill auto-install --yes`));
3542
+ if (ofm.expired) log(dim(` โ†’ ๊ฐฑ์‹ : leerness skill auto-cache refresh`));
3543
+ log('');
3544
+ } else if (ofm.cacheTotal === 0) {
3545
+ // ์บ์‹œ ์—†์Œ โ€” ์ฒซ ์‚ฌ์šฉ ์•ˆ๋‚ด
3546
+ const isTty = process.stdout && process.stdout.isTTY;
3547
+ const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3548
+ log(dim(` ๐Ÿ’ก ๊ณต์‹ ์Šคํ‚ฌ catalog ์บ์‹œ ์—†์Œ โ€” \`leerness skill auto-cache refresh\` ๋กœ vercel-labs/anthropics ์บ์‹œ ์ƒ์„ฑ (1.9.192)`));
3549
+ }
3550
+ } catch {}
3551
+ }
3408
3552
  }
3409
3553
  } catch {}
3410
3554
  }
@@ -14105,6 +14249,8 @@ async function main() {
14105
14249
  if (cmd === 'skill' && args[1] === 'suggest') return skillSuggestCmd(absRoot(arg('--path', process.cwd())));
14106
14250
  // 1.9.182: leerness skill auto-install โ€” ๊ณต์‹ catalog ์ž๋™ ํƒ์ƒ‰ + skill match ๋งค์นญ ์‹œ ์ž๋™ install (์‚ฌ์šฉ์ž ๋ช…์‹œ)
14107
14251
  if (cmd === 'skill' && args[1] === 'auto-install') return await skillAutoInstallCmd(absRoot(arg('--path', process.cwd())));
14252
+ // 1.9.192: skill auto-cache โ€” ๊ณต์‹ organization catalog 24h ์บ์‹œ ๊ด€๋ฆฌ (C์ถ• ๋ณด๊ฐ•)
14253
+ if (cmd === 'skill' && args[1] === 'auto-cache') return await skillAutoCacheCmd(absRoot(arg('--path', process.cwd())), args[2] || 'status');
14108
14254
  if (cmd === 'mcp' && args[1] === 'serve') return mcpServeCmd(absRoot(arg('--path', process.cwd())));
14109
14255
  if (cmd === 'gate') return gate(args[1] || process.cwd());
14110
14256
  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.190",
3
+ "version": "1.9.192",
4
4
  "description": "Leerness: ๋น„ํŒŒ๊ดด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜, ์ž๋™ ๋ฒ„์ „ ๊ฐ์ง€ยท์—…๋ฐ์ดํŠธ, ๊ณ„ํš/์ง„ํ–‰/ํ•ธ๋“œ์˜คํ”„ ์ž๋™ํ™”, ๊ฒŒ์œผ๋ฆ„ยท์‹œํฌ๋ฆฟยท์ธ์ฝ”๋”ฉ ์ž๋™ ๊ฐ€๋“œ, Claude Code ์Šฌ๋ž˜์‹œ ํ†ตํ•ฉ์„ ๊ฐ–์ถ˜ ํ•œ๊ตญ์–ด ์šฐ์„  AI ๊ฐœ๋ฐœ ํ•˜๋„ค์Šค.",
5
5
  "keywords": [
6
6
  "leerness",