leerness 1.9.181 β 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 +95 -0
- package/README.md +3 -3
- package/bin/harness.js +203 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
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
|
+
|
|
3
98
|
## 1.9.181 β 2026-05-21
|
|
4
99
|
|
|
5
100
|
**πͺ REPL μ§μ
νλ¦ μ 리 β μ¬μ©μ λͺ
μ 4μ’
+ μ§μ ꡬλ μ€ νΈμΆ κ²μ¦.**
|
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 μ§μ μμ±/λ§μ΄κ·Έλ μ΄μ
(μ¬μ©μ λͺ
μ μμ²). 보μ = λΉ κ°λ§ β μ¬μ©μκ° μ§μ ν ν° μ±μ.
|
|
@@ -1322,15 +1326,135 @@ function _parseSkillCatalog(body, sourceUrl) {
|
|
|
1322
1326
|
return entries;
|
|
1323
1327
|
}
|
|
1324
1328
|
|
|
1325
|
-
//
|
|
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 μΉ΄νλ‘κ·Έ μΈλ±μ€μμ λ§€μΉ μΆμ²
|
|
1326
1383
|
async function skillDiscoverCmd(root) {
|
|
1327
|
-
|
|
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
|
|
1328
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;
|
|
1329
1447
|
if (!url) {
|
|
1330
1448
|
fail([
|
|
1331
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
|
+
'',
|
|
1332
1457
|
'μ: leerness skill discover --source https://agentskills.io/llms.txt',
|
|
1333
|
-
'λλ .envμ LEERNESS_SKILL_DISCOVER_URL=...',
|
|
1334
1458
|
'',
|
|
1335
1459
|
'(μ μ±
: leernessλ μ¬μ©μ λμ μμ΄ μΈλΆ URLμ fetchνμ§ μμ β 1.9.42 opt-in)'
|
|
1336
1460
|
].join('\n'));
|
|
@@ -1372,6 +1496,78 @@ async function skillDiscoverCmd(root) {
|
|
|
1372
1496
|
log(`π‘ μ€μΉ: leerness skill install <url>`);
|
|
1373
1497
|
}
|
|
1374
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
|
+
|
|
1375
1571
|
// skill export <id> β κΈ°μ‘΄ μ체 skillμ agentskills.io νμ€ SKILL.mdλ‘ export
|
|
1376
1572
|
function skillExportCmd(root, id) {
|
|
1377
1573
|
if (!id) { fail('μ¬μ©λ²: leerness skill export <id>'); return process.exit(1); }
|
|
@@ -13540,6 +13736,8 @@ async function main() {
|
|
|
13540
13736
|
if (cmd === 'benchmark') return benchmarkCmd(absRoot(args[1] || arg('--path', process.cwd())));
|
|
13541
13737
|
if (cmd === 'skill' && args[1] === 'publish') return skillPublishCmd(absRoot(arg('--path', process.cwd())));
|
|
13542
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())));
|
|
13543
13741
|
if (cmd === 'mcp' && args[1] === 'serve') return mcpServeCmd(absRoot(arg('--path', process.cwd())));
|
|
13544
13742
|
if (cmd === 'gate') return gate(args[1] || process.cwd());
|
|
13545
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",
|