leerness 1.9.180 β 1.9.182
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 +166 -0
- package/README.md +3 -3
- package/bin/harness.js +239 -55
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,171 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.182 β 2026-05-21
|
|
4
|
+
|
|
5
|
+
**π 곡μ μ‘°μ§ μ€ν¬ catalog μλ νμ β vercel-labs/agent-skills + anthropics/skills μ§μ ν΅ν© (μ¬μ©μ λͺ
μ).**
|
|
6
|
+
|
|
7
|
+
μμ¨ λͺ¨λ 112 λΌμ΄λ. μ¬μ©μ λͺ
μ: *"곡μ μ‘°μ§μ μ€ν¬ λͺ¨μμ νμν΄μ λ€μ΄λ‘λ λ°μμ μ€ν¬μ μ¬μ©νλμ§ νμΈ (vercel-labs/agent-skills, anthropics/skills) + μ§κΈ μ€κ³νλ λ°©ν₯μ΄ μ¬λ°λ₯Έμ§ νλ¨λ λκ° ν΄μ€"*.
|
|
8
|
+
|
|
9
|
+
### ν΅μ¬ μΆκ°
|
|
10
|
+
|
|
11
|
+
#### 1. `SKILL_CATALOG_PRESETS` β λ΄μ₯ 곡μ catalog
|
|
12
|
+
```js
|
|
13
|
+
const SKILL_CATALOG_PRESETS = {
|
|
14
|
+
'vercel': { owner: 'vercel-labs', repo: 'agent-skills', branch: 'main', path: 'skills' },
|
|
15
|
+
'anthropic': { owner: 'anthropics', repo: 'skills', branch: 'main', path: 'skills' }
|
|
16
|
+
};
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
#### 2. `_fetchGitHubSkills(owner, repo, branch, dirPath)` β GitHub Contents API μ§μ νΈμΆ
|
|
20
|
+
- rate limit: 60 req/hr (LEERNESS_GITHUB_TOKEN μ 5000 req/hr)
|
|
21
|
+
- μλ΅μ νμ€ entry νμμΌλ‘ λ³ν (name, url, description, source, homepage)
|
|
22
|
+
- raw.githubusercontent.com URL μλ ꡬμ±
|
|
23
|
+
|
|
24
|
+
#### 3. `leerness skill discover` νμ₯
|
|
25
|
+
```bash
|
|
26
|
+
$ leerness skill discover --preset anthropic
|
|
27
|
+
# leerness skill discover (1.9.182 β GitHub presets)
|
|
28
|
+
targets: anthropics/skills#main:skills
|
|
29
|
+
fetching anthropics/skills...
|
|
30
|
+
β anthropics/skills: 17κ° skill λ°κ²¬
|
|
31
|
+
μ 체 17건 (μ 체 νμ β λ§€μΉ μμ)
|
|
32
|
+
|
|
33
|
+
| name | source | url |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| algorithmic-art | github:anthropics/skills | https://raw.githubusercontent.com/anthropics/skills/main/skills/algorithmic-art/SKILL.md |
|
|
36
|
+
| mcp-builder | github:anthropics/skills | https://raw.githubusercontent.com/anthropics/skills/main/skills/mcp-builder/SKILL.md |
|
|
37
|
+
| ...
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
μ κ· μ΅μ
:
|
|
41
|
+
- `--preset <name>` β λ΄μ₯ catalog (vercel, anthropic)
|
|
42
|
+
- `--all-presets` β λͺ¨λ preset λμ νμ
|
|
43
|
+
- `--github owner/repo[#branch][:path]` β μ§μ GitHub repo μ§μ
|
|
44
|
+
|
|
45
|
+
#### 4. `leerness skill auto-install` β μ κ· λͺ
λ Ή (μ¬μ©μ λͺ
μ ν΅μ¬)
|
|
46
|
+
```bash
|
|
47
|
+
$ leerness skill auto-install --query "mcp"
|
|
48
|
+
# leerness skill auto-install (1.9.182)
|
|
49
|
+
presets: vercel, anthropic
|
|
50
|
+
query: mcp
|
|
51
|
+
mode: π‘ dry-run (LEERNESS_SKILL_AUTO_INSTALL=1 λλ --yes νμ)
|
|
52
|
+
fetching anthropics/skills...
|
|
53
|
+
β anthropics/skills: 17κ° skill
|
|
54
|
+
λ§€μΉ 1/17건 (query: mcp)
|
|
55
|
+
| mcp-builder | github:anthropics/skills | https://raw.githubusercontent.com/anthropics/skills/main/skills/mcp-builder/SKILL.md |
|
|
56
|
+
|
|
57
|
+
π‘ μλ install νμ±ν: .env μ LEERNESS_SKILL_AUTO_INSTALL=1 λλ leerness skill auto-install --yes
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- handoff 컨ν
μ€νΈμμ μλ query μΆμΆ (μ§ν task ν€μλ)
|
|
61
|
+
- LEERNESS_SKILL_AUTO_INSTALL=1 μ μ€μ λ€μ΄λ‘λ (보μ opt-in)
|
|
62
|
+
- λ―Έμ€μ μ dry-run (μΆμ²λ§)
|
|
63
|
+
|
|
64
|
+
#### 5. .env.example 보κ°
|
|
65
|
+
```
|
|
66
|
+
LEERNESS_SKILL_AUTO_INSTALL=0
|
|
67
|
+
LEERNESS_SKILL_AUTO_PRESETS=vercel,anthropic
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### μ€ κ²μ¦ (live GitHub API)
|
|
71
|
+
- **anthropics/skills 17κ° skill μλ λ°κ²¬**:
|
|
72
|
+
algorithmic-art, brand-guidelines, canvas-design, claude-api, doc-coauthoring, **docx**, frontend-design, internal-comms, **mcp-builder**, **pdf**, **pptx**, skill-creator, slack-gif-creator, theme-factory, web-artifacts-builder, **webapp-testing**, **xlsx**
|
|
73
|
+
- **mcp-builder μ€ λ€μ΄λ‘λ + μ€μΉ μ±κ³΅**:
|
|
74
|
+
`leerness-stress/.harness/skills/mcp-builder/SKILL.md` λ€μ΄λ‘λ κ²μ¦
|
|
75
|
+
description: "Guide for creating high-quality MCP (Model Context Protocol) servers..."
|
|
76
|
+
|
|
77
|
+
### λ°©ν₯μ± νκ° λ³΄κ³ μ (μ¬μ©μ λͺ
μ)
|
|
78
|
+
μ¬μ©μ μμ²: *"μ§κΈ μ€κ³νλ λ°©ν₯μ΄ μ¬λ°λ₯Έ λ°©ν₯μΈμ§ νλ¨λ λκ° ν΄μ€"*. λ³΄κ³ μ: `_reports/direction-1.9.182.md` (λΉκ³΅κ°).
|
|
79
|
+
|
|
80
|
+
**κ²°λ‘ **:
|
|
81
|
+
| νκ° νλͺ© | μ μ |
|
|
82
|
+
|---|---|
|
|
83
|
+
| μμ¨μ± (auto loop Β· review Β· install) | 8.5/10 |
|
|
84
|
+
| μ±μ₯μ± (learn Β· suggest Β· skill catalog) | 8/10 |
|
|
85
|
+
| μμ μ± (sandbox Β· permissions Β· env opt-in) | 9/10 |
|
|
86
|
+
| λ²μ©μ± (multi-provider Β· MCP Β· bridges) | 8/10 |
|
|
87
|
+
| κ²μ¦ κ°λ₯μ± (verify-claim Β· stress Β· e2e) | 9.5/10 |
|
|
88
|
+
|
|
89
|
+
**μ’
ν©**: 86/100. **μ¬λ°λ₯Έ λ°©ν₯**. μ½μ μ *μ€ν¬ μ μ© ν νκ³ λΆμ¬ + μΈλΆ μ€ν¬ μ λ’°μ± κ²μ¦* β 1.9.183~190 λ§μΌμ€ν€.
|
|
90
|
+
|
|
91
|
+
### Verified
|
|
92
|
+
- stress-v127: **16/16** (preset 4 + .env λΌμ°ν
2 + μ€ GitHub fetch 3 + VERSION+λμ νκ· 7)
|
|
93
|
+
- e2e 217/217 baseline μ μ§
|
|
94
|
+
- VERSION = 1.9.182 Β· autonomous-rounds = 112 Β· main μλ push 43 λΌμ΄λ μ°μ
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 1.9.181 β 2026-05-21
|
|
99
|
+
|
|
100
|
+
**πͺ REPL μ§μ
νλ¦ μ 리 β μ¬μ©μ λͺ
μ 4μ’
+ μ§μ ꡬλ μ€ νΈμΆ κ²μ¦.**
|
|
101
|
+
|
|
102
|
+
μμ¨ λͺ¨λ 111 λΌμ΄λ. μ¬μ©μ μ§μ ꡬλ ν
μ€νΈ κ²°κ³Ό λ³΄κ³ (μ€ν¬λ¦°μ· 첨λΆ):
|
|
103
|
+
1. *"1.9.149 Hermes/OpenClaw μ€νμΌ λ±μ 문ꡬλ μ κ±°"* β μ€μΉ μλ£ λ©μμ§ λ¨μν
|
|
104
|
+
2. *"μ΄ λ¨κ³μμ Ollama μ μΈν λͺ¨λΈμ μ ννλλ° REPL μ§μ
μ Ollama μ°μ νΈμΆ"* β installβREPL provider μλ μ ν
|
|
105
|
+
3. *"νλ‘λ°μ΄λ μ ν μ ν λ¨κ³ μμ΄ λ°λ‘ μ±ν
λͺ¨λλ‘ μ§μ
"* β μ§μ
prompt μ κ±°
|
|
106
|
+
4. *"REPLμ μ§μ ꡬλν΄μ λͺ
λ Ή μ
λ ₯ν΄λ³΄κ³ κ°λ°/μΉ/PC/μΆλ‘ /μ§λ¬Έ-λ΅λ³ λμ ν
μ€νΈ"* β agents multi --execute μ€ νΈμΆ κ²μ¦
|
|
107
|
+
|
|
108
|
+
### Fix #1 β 문ꡬ λ¨μν
|
|
109
|
+
```diff
|
|
110
|
+
- log('π μ€μΉ μλ£ β REPL agent λͺ¨λλ₯Ό μμν©λλ€ (1.9.149 Hermes/OpenClaw μ€νμΌ)...');
|
|
111
|
+
+ log('π μ€μΉ μλ£ β REPL agent λͺ¨λλ₯Ό μμν©λλ€...');
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Fix #2 β installβREPL provider νλμ½λ© μ κ±°
|
|
115
|
+
```diff
|
|
116
|
+
- await _agentRepl(root, { provider: 'ollama', role: 'actor' }); // 1.9.151 β 무쑰건 ollama
|
|
117
|
+
+ await _agentRepl(root, { role: 'actor' }); // provider λ―Έμ§μ β auto-select λμ (1.9.181 fix)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Fix #3 β λΉ-Ollama μ°μ μλ μ ν (Ollama μ°μ νΈμΆ X)
|
|
121
|
+
```js
|
|
122
|
+
const ready = EXTERNAL_AGENTS.map(a => ({ def: a, status: _checkAgent(a) }))
|
|
123
|
+
.filter(x => x.status.status === 'ready');
|
|
124
|
+
const nonOllama = ready.filter(x => x.def.id !== 'ollama');
|
|
125
|
+
if (nonOllama.length >= 1) {
|
|
126
|
+
// λΉ-Ollama νμ± β 첫 λ²μ§Έ μλ (μ¬μ©μ λͺ
μ: Ollama μ°μ νΈμΆ X)
|
|
127
|
+
initialProvider = nonOllama[0].def.id;
|
|
128
|
+
_autoPickNote = nonOllama.length === 1
|
|
129
|
+
? `${initialProvider} μλ μ ν (νμ± CLI 1κ°)`
|
|
130
|
+
: `${initialProvider} μλ μ ν (νμ± CLI ${nonOllama.length}κ° Β· TabμΌλ‘ μ ν)`;
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Fix #4 β provider μ ν prompt λ¨κ³ μ κ±° (μλ μ ν)
|
|
135
|
+
μ΄μ :
|
|
136
|
+
```
|
|
137
|
+
β Ollama λ―Έκ°λ λλ λͺ¨λΈ μμ
|
|
138
|
+
π‘ νμ± μΈλΆ CLI 4κ° λ°κ²¬ β provider μ ν κ°λ₯:
|
|
139
|
+
1) claude (v2.1.145)
|
|
140
|
+
2) codex (vcodex-cli 0.132.0)
|
|
141
|
+
...
|
|
142
|
+
provider μ ν (λ²νΈ / Enter=ollama κ³μ): _
|
|
143
|
+
```
|
|
144
|
+
μ§κΈ:
|
|
145
|
+
```
|
|
146
|
+
βΈ Provider: claude μλ μ ν (νμ± CLI 4κ° Β· TabμΌλ‘ μ ν)
|
|
147
|
+
[μ±ν
λͺ¨λ μ¦μ μ§μ
]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### μ§μ ꡬλ μ€ νΈμΆ κ²μ¦ (μ¬μ©μ λͺ
μ 4λ²μ§Έ μμ²)
|
|
151
|
+
```bash
|
|
152
|
+
$ leerness agents multi "1+1=? μ«μλ§ λ΅ν΄μ£ΌμΈμ." --only claude,gemini --execute --timeout 30
|
|
153
|
+
β claude Β· 4810ms Β· 1 ν ν°
|
|
154
|
+
β gemini Β· 1266ms Β· exit=null
|
|
155
|
+
best: claude Β· score=0.600
|
|
156
|
+
--- μ²μ 600μ ---
|
|
157
|
+
2
|
|
158
|
+
```
|
|
159
|
+
**claude μΆλ‘ μλ΅ μ μ**. geminiλ λ³λ νκ²½ μ΄μ (--yolo κΆν λλ quota β 1.9.182μμ μΆκ° λλ²κ·Έ ν보).
|
|
160
|
+
|
|
161
|
+
### Verified
|
|
162
|
+
- stress-v126: **18/18** (μ¬μ©μ λͺ
μ 4 + μλ μ ν λμ 4 + μ§μ ꡬλ 2 + VERSION+λμ νκ· 8)
|
|
163
|
+
- e2e 217/217 baseline μ μ§
|
|
164
|
+
- claude μ€ νΈμΆ 4810ms Β· μλ΅ "2" β REPL agentμ ν΅μ¬ λ₯λ ₯ (μ€ λͺ¨λΈ νΈμΆ + μΆλ‘ + μλ΅ μμ ) λμ νμΈ
|
|
165
|
+
- VERSION = 1.9.181 Β· autonomous-rounds = 111 Β· main μλ push 42 λΌμ΄λ μ°μ
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
3
169
|
## 1.9.180 β 2026-05-21
|
|
4
170
|
|
|
5
171
|
**π§ REPL Tab cycle ν΅μ¬ fix + μ±ν
μμ separator β μ¬μ©μ λͺ
μ (μ§μ ꡬλ ν
μ€νΈ κ²°κ³Ό).**
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **AI μ½λ© μμ΄μ νΈμ κ±°μ§ μλ£Β·μ€λ³΅Β·λ§κ°Β·μΆ©λμ λ§μμ£Όλ κ²μΒ·κΈ°μ΅Β·νμ
CLI νλ€μ€.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []() []() [-success)]() [-brightgreen)]() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
β βββ ββββββ ββββββ ββββββββββββββββββββββββ ββββββββ β
|
|
13
13
|
β βββββββββββββββββββββββββββ ββββββ ββββββββββββββββββββββ β
|
|
14
14
|
β βββββββββββββββββββββββββββ ββββββ βββββββββββββββββββββ β
|
|
15
|
-
β v1.9.
|
|
15
|
+
β v1.9.182 AI Agent Reliability Harness + Sandbox β
|
|
16
16
|
β verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β
|
|
17
|
-
β
|
|
17
|
+
β π 곡μ catalog μλ νμ (vercel/anthropic) Β· μκ° μ±μ₯ν β
|
|
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.
|
|
10
|
+
const VERSION = '1.9.182';
|
|
11
11
|
const MARK = '<!-- leerness:managed -->';
|
|
12
12
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
13
13
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -872,7 +872,11 @@ async function install(root, opts = {}) {
|
|
|
872
872
|
'# μμ URL: https://agentskills.io/llms.txt',
|
|
873
873
|
'LEERNESS_SKILL_DISCOVER_URL=',
|
|
874
874
|
'# (μ ν) μ¬μ©μ μμ² λΆμ μ μλ λ§€μΉ μ€ν¬ μΆμ². 1=νμ±, 0/λ―Έμ€μ =λΉνμ±.',
|
|
875
|
-
'LEERNESS_SKILL_AUTO_DISCOVER=0'
|
|
875
|
+
'LEERNESS_SKILL_AUTO_DISCOVER=0',
|
|
876
|
+
'# 1.9.182 β handoff μ 곡μ catalog (vercel-labs, anthropics) μλ νμ + λ§€μΉ μ μλ install. 1=νμ± (opt-in 보μ).',
|
|
877
|
+
'LEERNESS_SKILL_AUTO_INSTALL=0',
|
|
878
|
+
'# 1.9.182 β handoff μλ νμ λμ preset (μ½€λ§ κ΅¬λΆ). μ: vercel,anthropic',
|
|
879
|
+
'LEERNESS_SKILL_AUTO_PRESETS=vercel,anthropic'
|
|
876
880
|
];
|
|
877
881
|
mergeLinesFile(path.join(root, '.env.example'), envLines);
|
|
878
882
|
// 1.9.153: .env μ§μ μμ±/λ§μ΄κ·Έλ μ΄μ
(μ¬μ©μ λͺ
μ μμ²). 보μ = λΉ κ°λ§ β μ¬μ©μκ° μ§μ ν ν° μ±μ.
|
|
@@ -934,12 +938,13 @@ async function install(root, opts = {}) {
|
|
|
934
938
|
// resolveInstallOptions (1.9.146) κ° μ΄λ―Έ λͺ¨λ prompt λͺ¨μ μμΉμ ν΅ν©λ 4μ§μ λ€ prompt μμ.
|
|
935
939
|
// λ³λ setupAgents λͺ
λ Ήμ μ¬μ©μκ° λͺ
μμ μΌλ‘ `leerness setup-agents` νΈμΆ μμλ§.
|
|
936
940
|
// 1.9.151: μ€μΉ μλ£ μ§ν β startRepl μ ν μ REPL agent λͺ¨λ μ¦μ μ§μ
(μ¬μ©μ λͺ
μ μμ²)
|
|
941
|
+
// 1.9.181: 문ꡬ λ¨μν + provider νλμ½λ© μ κ±° (μ¬μ©μ λͺ
μ β install μ νν CLIλ₯Ό REPLμ΄ μλ μ ν)
|
|
937
942
|
if (resolved.startRepl && !opts.migration && process.stdin.isTTY && process.env.LEERNESS_NO_PROMPT !== '1') {
|
|
938
943
|
log('');
|
|
939
|
-
log('π μ€μΉ μλ£ β REPL agent λͺ¨λλ₯Ό
|
|
944
|
+
log('π μ€μΉ μλ£ β REPL agent λͺ¨λλ₯Ό μμν©λλ€...');
|
|
940
945
|
log('');
|
|
941
946
|
try {
|
|
942
|
-
await _agentRepl(root, {
|
|
947
|
+
await _agentRepl(root, { role: 'actor' }); // provider λ―Έμ§μ β _agentRepl μ auto-select λμ (1.9.181 fix)
|
|
943
948
|
} catch (e) { warn('REPL μ§μ
μ€ν¨: ' + e.message); }
|
|
944
949
|
}
|
|
945
950
|
}
|
|
@@ -1321,15 +1326,135 @@ function _parseSkillCatalog(body, sourceUrl) {
|
|
|
1321
1326
|
return entries;
|
|
1322
1327
|
}
|
|
1323
1328
|
|
|
1324
|
-
//
|
|
1329
|
+
// 1.9.182: 곡μ μ‘°μ§ μ€ν¬ catalog presets β μ¬μ©μ λͺ
μ (vercel-labs, anthropics κ°μ 1st-party μλ νμ).
|
|
1330
|
+
// κ° entry: GitHub repoμ skills/ λλ ν 리μ SKILL.md λ€μ΄ μλ νμ€ κ΅¬μ‘°.
|
|
1331
|
+
// sync: leerness skill discover --preset <name> Β· --all-presets Β· --github <owner/repo>[#branch]
|
|
1332
|
+
const SKILL_CATALOG_PRESETS = {
|
|
1333
|
+
'vercel': { owner: 'vercel-labs', repo: 'agent-skills', branch: 'main', path: 'skills',
|
|
1334
|
+
homepage: 'https://github.com/vercel-labs/agent-skills' },
|
|
1335
|
+
'anthropic': { owner: 'anthropics', repo: 'skills', branch: 'main', path: 'skills',
|
|
1336
|
+
homepage: 'https://github.com/anthropics/skills' }
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
// 1.9.182: GitHub repo μ skills/ λλ ν 리 μλ νμ.
|
|
1340
|
+
// GitHub Contents API (no auth 60req/hr, .env GITHUB_TOKEN μ 5000req/hr) μ¬μ©.
|
|
1341
|
+
// μλ΅μ νμ€ entry νμμΌλ‘ λ³ν: { name, url, description, format: 'github', source }
|
|
1342
|
+
async function _fetchGitHubSkills(owner, repo, branch, dirPath) {
|
|
1343
|
+
branch = branch || 'main'; dirPath = dirPath || 'skills';
|
|
1344
|
+
const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${dirPath}?ref=${branch}`;
|
|
1345
|
+
const token = process.env.LEERNESS_GITHUB_TOKEN || process.env.GITHUB_TOKEN || '';
|
|
1346
|
+
const headers = token ? { Authorization: `Bearer ${token}` } : {};
|
|
1347
|
+
// _httpFetch κ° headersλ₯Ό μ§μνμ§ μμΌλ©΄ raw https μ¬μ©
|
|
1348
|
+
let body, status;
|
|
1349
|
+
try {
|
|
1350
|
+
const https = require('https');
|
|
1351
|
+
const u = new URL(apiUrl);
|
|
1352
|
+
body = await new Promise((resolve, reject) => {
|
|
1353
|
+
const req = https.get({
|
|
1354
|
+
hostname: u.hostname, path: u.pathname + u.search,
|
|
1355
|
+
headers: { 'User-Agent': `leerness/${VERSION}`, ...headers }
|
|
1356
|
+
}, res => {
|
|
1357
|
+
status = res.statusCode;
|
|
1358
|
+
const chunks = [];
|
|
1359
|
+
res.on('data', c => chunks.push(c));
|
|
1360
|
+
res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
1361
|
+
});
|
|
1362
|
+
req.on('error', reject);
|
|
1363
|
+
req.setTimeout(10000, () => { req.destroy(new Error('timeout')); });
|
|
1364
|
+
});
|
|
1365
|
+
} catch (e) { return { ok: false, error: e.message, skills: [] }; }
|
|
1366
|
+
if (status !== 200) return { ok: false, error: `HTTP ${status}`, skills: [] };
|
|
1367
|
+
let items; try { items = JSON.parse(body); } catch { return { ok: false, error: 'invalid JSON', skills: [] }; }
|
|
1368
|
+
if (!Array.isArray(items)) return { ok: false, error: 'not array', skills: [] };
|
|
1369
|
+
const skills = items
|
|
1370
|
+
.filter(i => i && i.type === 'dir')
|
|
1371
|
+
.map(i => ({
|
|
1372
|
+
name: i.name,
|
|
1373
|
+
url: `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${i.path}/SKILL.md`,
|
|
1374
|
+
description: '',
|
|
1375
|
+
format: 'github',
|
|
1376
|
+
source: `github:${owner}/${repo}`,
|
|
1377
|
+
homepage: i.html_url
|
|
1378
|
+
}));
|
|
1379
|
+
return { ok: true, skills };
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
// skill discover β agentskills.io / GitHub repo / 곡μ preset μΉ΄νλ‘κ·Έ μΈλ±μ€μμ λ§€μΉ μΆμ²
|
|
1325
1383
|
async function skillDiscoverCmd(root) {
|
|
1326
|
-
|
|
1384
|
+
// 1.9.182: --preset / --all-presets / --github μΆκ° (μ¬μ©μ λͺ
μ β vercel-labs/agent-skills, anthropics/skills λ±)
|
|
1385
|
+
const preset = arg('--preset', null);
|
|
1386
|
+
const allPresets = has('--all-presets');
|
|
1387
|
+
const github = arg('--github', null); // μ: vercel-labs/agent-skills λλ owner/repo#branch:path
|
|
1327
1388
|
const query = arg('--query', null);
|
|
1389
|
+
|
|
1390
|
+
// preset / --all-presets / --github μ²λ¦¬ β λ¨μΌ source URLκ³Ό λ³κ° νλ¦
|
|
1391
|
+
if (preset || allPresets || github) {
|
|
1392
|
+
const targets = [];
|
|
1393
|
+
if (allPresets) for (const k of Object.keys(SKILL_CATALOG_PRESETS)) targets.push({ key: k, ...SKILL_CATALOG_PRESETS[k] });
|
|
1394
|
+
else if (preset) {
|
|
1395
|
+
const p = SKILL_CATALOG_PRESETS[preset];
|
|
1396
|
+
if (!p) { fail(`μ μ μλ preset: ${preset} (μ¬μ© κ°λ₯: ${Object.keys(SKILL_CATALOG_PRESETS).join(', ')})`); return process.exit(1); }
|
|
1397
|
+
targets.push({ key: preset, ...p });
|
|
1398
|
+
}
|
|
1399
|
+
if (github) {
|
|
1400
|
+
// owner/repo λλ owner/repo#branch λλ owner/repo#branch:path
|
|
1401
|
+
const m = github.match(/^([^/]+)\/([^#:]+)(?:#([^:]+))?(?::(.+))?$/);
|
|
1402
|
+
if (!m) { fail(`--github νμ μ€λ₯ (μ: vercel-labs/agent-skills λλ owner/repo#main:skills)`); return process.exit(1); }
|
|
1403
|
+
targets.push({ key: 'custom', owner: m[1], repo: m[2], branch: m[3] || 'main', path: m[4] || 'skills', homepage: `https://github.com/${m[1]}/${m[2]}` });
|
|
1404
|
+
}
|
|
1405
|
+
log(`# leerness skill discover (1.9.182 β GitHub presets)`);
|
|
1406
|
+
if (query) log(`query: ${query}`);
|
|
1407
|
+
log(`targets: ${targets.map(t => `${t.owner}/${t.repo}#${t.branch}:${t.path}`).join(', ')}`);
|
|
1408
|
+
log('');
|
|
1409
|
+
const allEntries = [];
|
|
1410
|
+
for (const t of targets) {
|
|
1411
|
+
log(` fetching ${t.owner}/${t.repo}...`);
|
|
1412
|
+
const r = await _fetchGitHubSkills(t.owner, t.repo, t.branch, t.path);
|
|
1413
|
+
if (!r.ok) {
|
|
1414
|
+
log(` β ${t.owner}/${t.repo}: ${r.error}`);
|
|
1415
|
+
continue;
|
|
1416
|
+
}
|
|
1417
|
+
log(` β ${t.owner}/${t.repo}: ${r.skills.length}κ° skill λ°κ²¬`);
|
|
1418
|
+
for (const s of r.skills) allEntries.push(s);
|
|
1419
|
+
}
|
|
1420
|
+
log('');
|
|
1421
|
+
if (has('--json')) { log(JSON.stringify({ presets: targets.map(t => t.key), query, entries: allEntries }, null, 2)); return; }
|
|
1422
|
+
if (!allEntries.length) {
|
|
1423
|
+
log(' (μ€ν¬ 0건 β preset/path/branch νμΈ λλ rate limit κ°λ₯)');
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1426
|
+
let matched = allEntries;
|
|
1427
|
+
if (query) {
|
|
1428
|
+
const q = query.toLowerCase();
|
|
1429
|
+
matched = allEntries.filter(e => e.name.toLowerCase().includes(q) || (e.description || '').toLowerCase().includes(q));
|
|
1430
|
+
log(`λ§€μΉ ${matched.length}/${allEntries.length}건 (query: ${query})`);
|
|
1431
|
+
} else {
|
|
1432
|
+
log(`μ 체 ${allEntries.length}건 (μ 체 νμ β λ§€μΉ μμ)`);
|
|
1433
|
+
}
|
|
1434
|
+
log('');
|
|
1435
|
+
log('| name | source | url |');
|
|
1436
|
+
log('|---|---|---|');
|
|
1437
|
+
for (const e of matched.slice(0, 40)) {
|
|
1438
|
+
log(`| ${e.name} | ${e.source} | ${e.url} |`);
|
|
1439
|
+
}
|
|
1440
|
+
log('');
|
|
1441
|
+
log(`π‘ μ€μΉ: leerness skill install <url> Β· μλ install (env opt-in): LEERNESS_SKILL_AUTO_INSTALL=1`);
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
// κΈ°μ‘΄ λ¨μΌ URL νλ¦ (1.9.42)
|
|
1446
|
+
const url = arg('--source', null) || process.env.LEERNESS_SKILL_DISCOVER_URL || null;
|
|
1328
1447
|
if (!url) {
|
|
1329
1448
|
fail([
|
|
1330
1449
|
'LEERNESS_SKILL_DISCOVER_URL νκ²½λ³μ λλ --source URL νμ.',
|
|
1450
|
+
'',
|
|
1451
|
+
'λλ (1.9.182 μ κ·) β 곡μ μ‘°μ§ catalog presets:',
|
|
1452
|
+
' leerness skill discover --preset vercel # vercel-labs/agent-skills',
|
|
1453
|
+
' leerness skill discover --preset anthropic # anthropics/skills',
|
|
1454
|
+
' leerness skill discover --all-presets # λͺ¨λ preset λμ νμ',
|
|
1455
|
+
' leerness skill discover --github owner/repo # μ§μ GitHub repo μ§μ ',
|
|
1456
|
+
'',
|
|
1331
1457
|
'μ: leerness skill discover --source https://agentskills.io/llms.txt',
|
|
1332
|
-
'λλ .envμ LEERNESS_SKILL_DISCOVER_URL=...',
|
|
1333
1458
|
'',
|
|
1334
1459
|
'(μ μ±
: leernessλ μ¬μ©μ λμ μμ΄ μΈλΆ URLμ fetchνμ§ μμ β 1.9.42 opt-in)'
|
|
1335
1460
|
].join('\n'));
|
|
@@ -1371,6 +1496,78 @@ async function skillDiscoverCmd(root) {
|
|
|
1371
1496
|
log(`π‘ μ€μΉ: leerness skill install <url>`);
|
|
1372
1497
|
}
|
|
1373
1498
|
|
|
1499
|
+
// 1.9.182: skill auto-install β 곡μ organization catalog μλ νμ β skill match β μλ install.
|
|
1500
|
+
// μ¬μ©μ λͺ
μ: "μ€ν¬μ μ¬μ©νκ±°λ μ μ©ν΄λλ©΄ μ’μ λΆλΆλ€μ μμμ μΉμμ 곡μ μ‘°μ§μ μ€ν¬ λͺ¨μμ νμν΄μ λ€μ΄λ‘λ λ°μμ μ¬μ©"
|
|
1501
|
+
// μ μ±
: LEERNESS_SKILL_AUTO_INSTALL=1 μΌ λλ§ μ€μ install (보μ opt-in). λ―Έμ€μ μ dry-run (μΆμ²λ§).
|
|
1502
|
+
async function skillAutoInstallCmd(root) {
|
|
1503
|
+
root = absRoot(root);
|
|
1504
|
+
const presets = (process.env.LEERNESS_SKILL_AUTO_PRESETS || arg('--presets', 'vercel,anthropic') || '').split(',').map(s => s.trim()).filter(Boolean);
|
|
1505
|
+
const autoInstall = process.env.LEERNESS_SKILL_AUTO_INSTALL === '1' || has('--yes');
|
|
1506
|
+
const query = arg('--query', null) || _autoInstallQueryFromHandoff(root);
|
|
1507
|
+
const maxInstall = Number(arg('--max', '3'));
|
|
1508
|
+
log(`# leerness skill auto-install (1.9.182)`);
|
|
1509
|
+
log(`presets: ${presets.join(', ') || '(none)'}`);
|
|
1510
|
+
log(`query: ${query || '(auto β handoff 컨ν
μ€νΈ)'}`);
|
|
1511
|
+
log(`mode: ${autoInstall ? 'π’ μλ install' : 'π‘ dry-run (LEERNESS_SKILL_AUTO_INSTALL=1 λλ --yes νμ)'}`);
|
|
1512
|
+
log('');
|
|
1513
|
+
const allEntries = [];
|
|
1514
|
+
for (const key of presets) {
|
|
1515
|
+
const p = SKILL_CATALOG_PRESETS[key];
|
|
1516
|
+
if (!p) { log(` β μ μ μλ preset: ${key}`); continue; }
|
|
1517
|
+
log(` fetching ${p.owner}/${p.repo}...`);
|
|
1518
|
+
const r = await _fetchGitHubSkills(p.owner, p.repo, p.branch, p.path);
|
|
1519
|
+
if (!r.ok) { log(` β ${p.owner}/${p.repo}: ${r.error}`); continue; }
|
|
1520
|
+
log(` β ${p.owner}/${p.repo}: ${r.skills.length}κ° skill`);
|
|
1521
|
+
for (const s of r.skills) allEntries.push(s);
|
|
1522
|
+
}
|
|
1523
|
+
log('');
|
|
1524
|
+
// query λ§€μΉ (substring) β query μμΌλ©΄ λͺ¨λ νλͺ©
|
|
1525
|
+
let matched = allEntries;
|
|
1526
|
+
if (query) {
|
|
1527
|
+
const q = String(query).toLowerCase();
|
|
1528
|
+
matched = allEntries.filter(e => e.name.toLowerCase().includes(q) || (e.description || '').toLowerCase().includes(q));
|
|
1529
|
+
log(`λ§€μΉ ${matched.length}/${allEntries.length}건 (query: ${query})`);
|
|
1530
|
+
} else {
|
|
1531
|
+
log(`μ 체 ${allEntries.length}건 (λͺ¨λ νλͺ©)`);
|
|
1532
|
+
}
|
|
1533
|
+
if (!matched.length) { log(' (λ§€μΉ 0건 β query λ³κ²½ λλ --presets μΆκ°)'); return; }
|
|
1534
|
+
log('');
|
|
1535
|
+
log('| name | source | url |');
|
|
1536
|
+
log('|---|---|---|');
|
|
1537
|
+
for (const e of matched.slice(0, maxInstall)) {
|
|
1538
|
+
log(`| ${e.name} | ${e.source} | ${e.url} |`);
|
|
1539
|
+
}
|
|
1540
|
+
log('');
|
|
1541
|
+
if (!autoInstall) {
|
|
1542
|
+
log(`π‘ μλ install νμ±ν: .env μ LEERNESS_SKILL_AUTO_INSTALL=1 λλ \`leerness skill auto-install --yes\``);
|
|
1543
|
+
log(` νμ¬ ${Math.min(maxInstall, matched.length)}κ±΄μ΄ install λμ (μ€μ λ€μ΄λ‘λ X β dry-run)`);
|
|
1544
|
+
return;
|
|
1545
|
+
}
|
|
1546
|
+
log(`π₯ μλ install μμ β μ΅λ ${maxInstall}건`);
|
|
1547
|
+
let installed = 0, failed = 0;
|
|
1548
|
+
for (const e of matched.slice(0, maxInstall)) {
|
|
1549
|
+
try {
|
|
1550
|
+
await skillInstallCmd(root, e.url);
|
|
1551
|
+
installed++;
|
|
1552
|
+
} catch (err) {
|
|
1553
|
+
log(` β ${e.name} install μ€ν¨: ${err.message}`);
|
|
1554
|
+
failed++;
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
log('');
|
|
1558
|
+
log(`β auto-install μλ£: ${installed}건 μ€μΉ / ${failed}건 μ€ν¨ / ${matched.length - installed - failed}건 skip`);
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
// 1.9.182: handoff 컨ν
μ€νΈ (νμ¬ in-progress task) μμ μλ query μΆμΆ
|
|
1562
|
+
function _autoInstallQueryFromHandoff(root) {
|
|
1563
|
+
try {
|
|
1564
|
+
const rows = readProgressRows(root);
|
|
1565
|
+
const active = rows.find(r => r.status === '[μ§ν]' || r.status === '[in-progress]' || r.status === 'in_progress');
|
|
1566
|
+
if (active) return (active.request || '').split(/\s+/).slice(0, 3).join(' ');
|
|
1567
|
+
} catch {}
|
|
1568
|
+
return null;
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1374
1571
|
// skill export <id> β κΈ°μ‘΄ μ체 skillμ agentskills.io νμ€ SKILL.mdλ‘ export
|
|
1375
1572
|
function skillExportCmd(root, id) {
|
|
1376
1573
|
if (!id) { fail('μ¬μ©λ²: leerness skill export <id>'); return process.exit(1); }
|
|
@@ -11066,23 +11263,28 @@ async function _agentRepl(root, opts) {
|
|
|
11066
11263
|
bold: s => `\x1b[1m${s}\x1b[0m`, green: s => `\x1b[32m${s}\x1b[0m`,
|
|
11067
11264
|
yel: s => `\x1b[33m${s}\x1b[0m`, mag: s => `\x1b[35m${s}\x1b[0m`
|
|
11068
11265
|
} : { cy:s=>s, dim:s=>s, bold:s=>s, green:s=>s, yel:s=>s, mag:s=>s };
|
|
11069
|
-
// 1.9.
|
|
11266
|
+
// 1.9.181 fix: provider μλ μ ν β prompt λ¨κ³ μ κ±°νκ³ μ¦μ μ±ν
λͺ¨λ μ§μ
(μ¬μ©μ λͺ
μ).
|
|
11267
|
+
// μ μ±
: λΉ-Ollama νμ± CLI μ°μ β Ollama β fallback. 볡μ νμ± μ prompt μμ΄ μ²« λΉ-Ollama μλ μ ν.
|
|
11268
|
+
// μ¬μ©μ μλ: "νλ‘λ°μ΄λ μ ν μ ν λ¨κ³μμ΄ λ°λ‘ μ±ν
λͺ¨λλ‘ μ§μ
ν΄λ λ κ±°κ°μ" + "Ollamaλ₯Ό μ°μ νΈμΆ X".
|
|
11269
|
+
// Tab μΌλ‘ μΈμ λ cycle κ°λ₯νλ―λ‘ μλ μ νν΄λ μ¬μ©μκ° μ¦μ μ ν κ°λ₯.
|
|
11070
11270
|
let initialProvider = opts.provider;
|
|
11271
|
+
let _autoPickNote = '';
|
|
11071
11272
|
if (!initialProvider) {
|
|
11072
11273
|
const ready = EXTERNAL_AGENTS.map(a => ({ def: a, status: _checkAgent(a) }))
|
|
11073
11274
|
.filter(x => x.status.status === 'ready');
|
|
11074
|
-
|
|
11075
|
-
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11082
|
-
|
|
11083
|
-
|
|
11275
|
+
const nonOllama = ready.filter(x => x.def.id !== 'ollama');
|
|
11276
|
+
if (nonOllama.length >= 1) {
|
|
11277
|
+
// λΉ-Ollama νμ± β 첫 λ²μ§Έ μλ (μ¬μ©μ λͺ
μ: Ollama μ°μ νΈμΆ X)
|
|
11278
|
+
initialProvider = nonOllama[0].def.id;
|
|
11279
|
+
_autoPickNote = nonOllama.length === 1
|
|
11280
|
+
? `${initialProvider} μλ μ ν (νμ± CLI 1κ°)`
|
|
11281
|
+
: `${initialProvider} μλ μ ν (νμ± CLI ${nonOllama.length}κ° Β· TabμΌλ‘ μ ν)`;
|
|
11282
|
+
} else if (ready.length === 1) {
|
|
11283
|
+
initialProvider = ready[0].def.id; // ollama λ¨λ
|
|
11284
|
+
_autoPickNote = `${initialProvider} μλ μ ν`;
|
|
11084
11285
|
} else {
|
|
11085
|
-
initialProvider = 'ollama'; // νμ± 0κ° β fallback
|
|
11286
|
+
initialProvider = 'ollama'; // νμ± 0κ° β fallback
|
|
11287
|
+
_autoPickNote = 'fallback ollama (νμ± CLI μμ β .env μμ LEERNESS_ENABLE_* νμ±ν κΆμ₯)';
|
|
11086
11288
|
}
|
|
11087
11289
|
}
|
|
11088
11290
|
// μΈμ
state
|
|
@@ -11116,47 +11318,27 @@ async function _agentRepl(root, opts) {
|
|
|
11116
11318
|
log('');
|
|
11117
11319
|
log(C.dim(` βΈ Welcome back Β· ${wsName} (${rel(process.cwd(), absRoot(root))})`));
|
|
11118
11320
|
log(C.dim(` βΈ Session: ${state.sessionId}`));
|
|
11321
|
+
if (_autoPickNote) log(C.dim(` βΈ Provider: ${_autoPickNote}`));
|
|
11119
11322
|
log('');
|
|
11120
|
-
//
|
|
11323
|
+
// 1.9.181 fix: provider μ§μ
μμ prompt λ¨κ³ μ κ±° β μλ μ νλ§ μν (μ¬μ©μ λͺ
μ β λ°λ‘ μ±ν
λͺ¨λ μ§μ
).
|
|
11121
11324
|
if (state.provider === 'ollama' && !state.model) {
|
|
11122
|
-
|
|
11325
|
+
// Ollama μ¬μ© κ°λ₯ β 첫 λͺ¨λΈ μλ μ ν (μ¬μ©μ prompt μμ)
|
|
11123
11326
|
const r = await _ollamaListModels();
|
|
11124
11327
|
if (r.ok && r.models.length) {
|
|
11125
|
-
|
|
11126
|
-
|
|
11127
|
-
const choice = await new Promise(res => rl.question(C.cy('\n λͺ¨λΈ λ²νΈ μ ν (Enter=1): '), res));
|
|
11128
|
-
const idx = parseInt(choice, 10) - 1;
|
|
11129
|
-
state.model = (idx >= 0 && idx < r.models.length) ? r.models[idx] : r.models[0];
|
|
11130
|
-
log(C.green(` β λͺ¨λΈ μ ν: ${state.model}`));
|
|
11328
|
+
state.model = process.env.LEERNESS_OLLAMA_MODEL || r.models[0];
|
|
11329
|
+
log(C.dim(` βΈ Model: ${state.model} (Ollama ${r.models.length}κ° catalog Β· Shift+TabμΌλ‘ λ³κ²½)`));
|
|
11131
11330
|
} else {
|
|
11132
|
-
|
|
11133
|
-
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
readyCli.forEach((x, i) => log(` ${i + 1}) ${x.def.id} (v${x.status.version || '?'})`));
|
|
11142
|
-
const choice = await new Promise(res => rl.question(C.cy('\n provider μ ν (λ²νΈ / Enter=ollama κ³μ): '), res));
|
|
11143
|
-
const idx = parseInt(choice, 10) - 1;
|
|
11144
|
-
if (idx >= 0 && idx < readyCli.length) {
|
|
11145
|
-
state.provider = readyCli[idx].def.id;
|
|
11146
|
-
state.model = null; // μ provider κΈ°λ³Έ λͺ¨λΈ μ¬μ©
|
|
11147
|
-
log(C.green(` β provider μ ν: ${state.provider} (λ©μμ§ μ
λ ₯ μ¦μ μ¬μ©)`));
|
|
11148
|
-
} else {
|
|
11149
|
-
state.model = process.env.LEERNESS_OLLAMA_MODEL || 'llama3';
|
|
11150
|
-
log(C.dim(` ollama fallback: ${state.model} β μΆν :provider <μ΄λ¦> μΌλ‘ μ ν κ°λ₯`));
|
|
11151
|
-
}
|
|
11152
|
-
} else {
|
|
11153
|
-
log(C.dim(` ollama serve + ollama pull <model> / λλ .env μμ LEERNESS_ENABLE_CLAUDE=1 λ± νμ±ν`));
|
|
11154
|
-
state.model = process.env.LEERNESS_OLLAMA_MODEL || 'llama3';
|
|
11155
|
-
log(C.dim(` fallback: ${state.model} (μ€ νΈμΆ μ€ν¨ μ :provider λ©λ΄ λλ :quit)`));
|
|
11156
|
-
}
|
|
11157
|
-
} catch {
|
|
11331
|
+
// Ollama λ―Έκ°λ β λΉ-Ollama νμ± CLI κ° μμΌλ©΄ μλ μ ν, μμΌλ©΄ fallback ollama (warn)
|
|
11332
|
+
const readyCli = EXTERNAL_AGENTS.filter(a => a.id !== 'ollama')
|
|
11333
|
+
.map(a => ({ def: a, status: _checkAgent(a) }))
|
|
11334
|
+
.filter(x => x.status.status === 'ready');
|
|
11335
|
+
if (readyCli.length) {
|
|
11336
|
+
state.provider = readyCli[0].def.id;
|
|
11337
|
+
state.model = null;
|
|
11338
|
+
log(C.green(` βΈ Ollama λ―Έκ°λ β ${state.provider} μλ μ ν (TabμΌλ‘ λ€λ₯Έ provider μ ν κ°λ₯)`));
|
|
11339
|
+
} else {
|
|
11158
11340
|
state.model = process.env.LEERNESS_OLLAMA_MODEL || 'llama3';
|
|
11159
|
-
log(C.
|
|
11341
|
+
log(C.yel(` β Ollama λ―Έκ°λ + νμ± CLI μμ β fallback ${state.model} (μ€ νΈμΆ μ€ν¨ μ :quit λλ :provider)`));
|
|
11160
11342
|
}
|
|
11161
11343
|
}
|
|
11162
11344
|
}
|
|
@@ -11658,7 +11840,7 @@ async function _agentRepl(root, opts) {
|
|
|
11658
11840
|
async function agentCmd(root, taskArg) {
|
|
11659
11841
|
root = absRoot(root || process.cwd());
|
|
11660
11842
|
const task = (taskArg || arg('--task', '') || '').trim();
|
|
11661
|
-
// 1.9.149: REPL μ§μ
β μΈμ μκ±°λ --interactive λͺ
μ (
|
|
11843
|
+
// 1.9.149+1.9.181: REPL μ§μ
β μΈμ μκ±°λ --interactive λͺ
μ (provider μλ μ ν)
|
|
11662
11844
|
if (!task || has('--interactive') || has('--repl')) {
|
|
11663
11845
|
if (process.stdin.isTTY && !has('--no-repl') && process.env.LEERNESS_NO_PROMPT !== '1') {
|
|
11664
11846
|
const t0 = Date.now();
|
|
@@ -13554,6 +13736,8 @@ async function main() {
|
|
|
13554
13736
|
if (cmd === 'benchmark') return benchmarkCmd(absRoot(args[1] || arg('--path', process.cwd())));
|
|
13555
13737
|
if (cmd === 'skill' && args[1] === 'publish') return skillPublishCmd(absRoot(arg('--path', process.cwd())));
|
|
13556
13738
|
if (cmd === 'skill' && args[1] === 'suggest') return skillSuggestCmd(absRoot(arg('--path', process.cwd())));
|
|
13739
|
+
// 1.9.182: leerness skill auto-install β 곡μ catalog μλ νμ + skill match λ§€μΉ μ μλ install (μ¬μ©μ λͺ
μ)
|
|
13740
|
+
if (cmd === 'skill' && args[1] === 'auto-install') return await skillAutoInstallCmd(absRoot(arg('--path', process.cwd())));
|
|
13557
13741
|
if (cmd === 'mcp' && args[1] === 'serve') return mcpServeCmd(absRoot(arg('--path', process.cwd())));
|
|
13558
13742
|
if (cmd === 'gate') return gate(args[1] || process.cwd());
|
|
13559
13743
|
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.
|
|
3
|
+
"version": "1.9.182",
|
|
4
4
|
"description": "Leerness: λΉνκ΄΄ λ§μ΄κ·Έλ μ΄μ
, μλ λ²μ κ°μ§Β·μ
λ°μ΄νΈ, κ³ν/μ§ν/νΈλμ€ν μλν, κ²μΌλ¦Β·μν¬λ¦ΏΒ·μΈμ½λ© μλ κ°λ, Claude Code μ¬λμ ν΅ν©μ κ°μΆ νκ΅μ΄ μ°μ AI κ°λ° νλ€μ€.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|