leerness 1.9.156 β 1.9.158
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 +88 -0
- package/README.md +2 -2
- package/bin/harness.js +133 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.158 β 2026-05-20
|
|
4
|
+
|
|
5
|
+
**π MCP 48λ²μ§Έ λꡬ `leerness_provider_list` β Provider Registry μΈλΆ AI λ
ΈμΆ λ§μΌμ€ν€.**
|
|
6
|
+
|
|
7
|
+
μμ¨ λͺ¨λ 88 λΌμ΄λ. 1.9.157 Provider Registry CLI μ μμ°μ€λ¬μ΄ νμ β MCP λ
ΈμΆ.
|
|
8
|
+
|
|
9
|
+
### Added β MCP `leerness_provider_list` (48λ²μ§Έ λꡬ)
|
|
10
|
+
- μΈλΆ AI (Claude / Codex / Gemini λ±) κ° MCP ν΅ν΄ λ±λ‘λ provider μ 체 νμ κ°λ₯
|
|
11
|
+
- μλ΅ JSON: `{ total, builtin, user, providers: [{ id, bin, envFlag, source, desc }] }`
|
|
12
|
+
- λΉνΈμΈ 5μ’
(claude/codex/gemini/copilot/ollama) + `.harness/providers.json` μ¬μ©μ μ μ ν΅ν©
|
|
13
|
+
- μΈλΆ AI νμ© μ¬λ‘:
|
|
14
|
+
- λ©μΈ μμ΄μ νΈκ° sub-agent λΆλ°° μ μ¬μ© κ°λ₯ν provider νμΈ
|
|
15
|
+
- OpenRouter/Bedrock λ± λ±λ‘λμ΄ μμΌλ©΄ μλ λ°κ²¬
|
|
16
|
+
- sub-agent κ° "λ΄κ° μ¬μ© κ°λ₯ν λκ΅¬κ° λ¬΄μμΈμ§" μκΈ°-μ κ²
|
|
17
|
+
|
|
18
|
+
### MCP λꡬ μΉ΄μ΄νΈ μ§ν
|
|
19
|
+
- 1.9.43 β 1.9.84 (READ 5μ’
μμ±): 17 λꡬ
|
|
20
|
+
- 1.9.85 β 1.9.110 (health + Memory CRUD): 30 λꡬ λ§μΌμ€ν€
|
|
21
|
+
- 1.9.112 β 1.9.119 (Memory READ 5μ’
): 35 λꡬ
|
|
22
|
+
- 1.9.128 (DELETE/RESTORE 5μ’
): 40 λꡬ λ§μΌμ€ν€
|
|
23
|
+
- 1.9.142 (Feature Graph): 45 λꡬ
|
|
24
|
+
- 1.9.145 (env detect): 47 λꡬ
|
|
25
|
+
- **1.9.158: 48 λꡬ π**
|
|
26
|
+
|
|
27
|
+
### Pending β 1.9.158 κΆκ³ λ€μ ν보
|
|
28
|
+
- **1.9.159** β `leerness_provider_add` MCP λꡬ (49λ²μ§Έ) β μΈλΆ AI κ° μκ° νμ₯ κ°λ₯
|
|
29
|
+
- **1.9.160** β `provider sync` (OpenRouter llms.txt μλ λκΈ°ν)
|
|
30
|
+
- **1.9.161** β LSP μ΄λν° MVP
|
|
31
|
+
|
|
32
|
+
### Verified
|
|
33
|
+
- e2e 217/217 β
|
|
34
|
+
- stress-v103: 12/12 (MCP tools/list 48κ° 3μ’
+ tools/call μ€νΈμΆ 2μ’
+ λμ νκ· 7μ’
) π **MCP 48 λꡬ λ§μΌμ€ν€**
|
|
35
|
+
- VERSION = 1.9.158 / autonomous-rounds = 88
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 1.9.157 β 2026-05-20
|
|
40
|
+
|
|
41
|
+
**Provider Registry CLI MVP β μ¬μ©μ μ μ provider λμ μΆκ° (μ κ² λ³΄κ³ μ κΆκ³ #3 β Provider Registry MCPμ CLI λ¨κ³).**
|
|
42
|
+
|
|
43
|
+
μμ¨ λͺ¨λ 87 λΌμ΄λ. 1.9.155 μ κ² λ³΄κ³ μκ° λ°κ²¬ν "λͺ¨λΈ/νλ‘λ°μ΄λ ν 5μ’
vs 200+" gap 보κ°μ 첫 λ¨κ³.
|
|
44
|
+
|
|
45
|
+
### Added β `leerness provider list|add|remove` μ κ· λͺ
λ Ή
|
|
46
|
+
- λΉνΈμΈ 5μ’
(claude/codex/gemini/copilot/ollama) + **μ¬μ©μ μ μ provider λμ μΆκ°**
|
|
47
|
+
- `.harness/providers.json` β μ¬μ©μ μ μ μ μ₯ (schemaVersion 1)
|
|
48
|
+
- `_allProviders(root)` β λΉνΈμΈ + μ¬μ©μ μ μ merge
|
|
49
|
+
- κ°μ id μ user override μ μ© β λΉνΈμΈ μ€μ λ³κ²½ κ°λ₯
|
|
50
|
+
- λΉνΈμΈμ μλ user-only provider μΆκ°
|
|
51
|
+
|
|
52
|
+
### CLI
|
|
53
|
+
```bash
|
|
54
|
+
leerness provider list # λΉνΈμΈ + μ¬μ©μ μ μ ν΅ν© νμ
|
|
55
|
+
leerness provider list --json # ꡬ쑰ν μΆλ ₯ (total/builtin/user/providers)
|
|
56
|
+
leerness provider add openrouter --bin openrouter-cli --desc "OpenRouter aggregator"
|
|
57
|
+
leerness provider add bedrock --bin aws-bedrock-cli --env-flag LEERNESS_ENABLE_BEDROCK
|
|
58
|
+
leerness provider remove openrouter # μ¬μ©μ μ μλ§ μ κ±° κ°λ₯ (λΉνΈμΈ κ±°λΆ)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Changed β `agents list/check` Provider Registry ν΅ν©
|
|
62
|
+
- ν μΆλ ₯μ `source` μ»¬λΌ μΆκ° (builtin / user / user(override))
|
|
63
|
+
- JSON μλ΅μ `source` νλ μΆκ°
|
|
64
|
+
- νμ± μμ λ "1.9.157: λΉνΈμΈ μΈ CLI μΆκ°" hint νμ
|
|
65
|
+
- ν€λ `(1.9.30)` μ μ§ β κΈ°μ‘΄ e2e regex νΈν
|
|
66
|
+
|
|
67
|
+
### Use Cases
|
|
68
|
+
- **OpenRouter 200+ λͺ¨λΈ ν‘μ**: `provider add openrouter --bin openrouter-cli` ν `LEERNESS_ENABLE_OPENROUTER=1` μ€μ
|
|
69
|
+
- **AWS Bedrock ν΅ν©**: `provider add bedrock --bin aws-bedrock-cli`
|
|
70
|
+
- **Groq / Hugging Face / μ체 LLM CLI**: λͺ¨λ λμΌ ν¨ν΄
|
|
71
|
+
- **μλ λ°κ²¬**: 1.9.158 μμ OpenRouter llms.txt μλ λκΈ°ν μμ
|
|
72
|
+
|
|
73
|
+
### Verified β 5λ₯λ ₯ λ§€νΈλ¦μ€ κ°±μ
|
|
74
|
+
| μμ | 1.9.156 | 1.9.157 |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| Provider ν | 5μ’
κ³ μ | **무μ ν (λμ λ±λ‘)** |
|
|
77
|
+
| μ’
ν© μμ±λ | 60% | **62%** |
|
|
78
|
+
|
|
79
|
+
### Pending β λ³΄κ³ μ κΆκ³ λ¨μ ν보
|
|
80
|
+
- **1.9.158** β `leerness provider sync` (OpenRouter llms.txt μλ λκΈ°ν) + MCP `leerness_provider_list` (48λ²μ§Έ λꡬ)
|
|
81
|
+
- **1.9.159** β LSP μ΄λν° MVP (TypeScript LSP)
|
|
82
|
+
- **1.9.160** β playwright/computer-use bridge (`permissions.browser/mouse` μ€ λμ)
|
|
83
|
+
|
|
84
|
+
### Verified
|
|
85
|
+
- e2e 217/217 β
|
|
86
|
+
- stress-v102: 19/19 (Provider Registry ν¨μ 3μ’
+ list 2μ’
+ add/remove 6μ’
+ agents ν΅ν© 2μ’
+ λμ νκ· 6μ’
)
|
|
87
|
+
- VERSION = 1.9.157 / autonomous-rounds = 87
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
3
91
|
## 1.9.156 β 2026-05-20
|
|
4
92
|
|
|
5
93
|
**`agents multi --execute` μ€μ spawn + consensus ν΅ν© (1.9.155 μ κ² λ³΄κ³ μ λ°κ²¬ gap #1 보κ°).**
|
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) []() []() []() []() []() []() []() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
β βββ ββββββ ββββββ ββββββββββββββββββββββββ ββββββββ β
|
|
13
13
|
β βββββββββββββββββββββββββββ ββββββ ββββββββββββββββββββββ β
|
|
14
14
|
β βββββββββββββββββββββββββββ ββββββ βββββββββββββββββββββ β
|
|
15
|
-
β v1.9.
|
|
15
|
+
β v1.9.158 AI Agent Reliability Harness + Sandbox β
|
|
16
16
|
β verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β
|
|
17
17
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
18
18
|
```
|
package/bin/harness.js
CHANGED
|
@@ -6,7 +6,7 @@ const path = require('path');
|
|
|
6
6
|
const cp = require('child_process');
|
|
7
7
|
const readline = require('readline');
|
|
8
8
|
|
|
9
|
-
const VERSION = '1.9.
|
|
9
|
+
const VERSION = '1.9.158';
|
|
10
10
|
const MARK = '<!-- leerness:managed -->';
|
|
11
11
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
12
12
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -4584,6 +4584,119 @@ const EXTERNAL_AGENTS = [
|
|
|
4584
4584
|
installCmd: 'curl -fsSL https://ollama.com/install.sh | sh (λλ https://ollama.com/download)', installHint: 'ollama serve μ€ν + ollama pull <model>' }
|
|
4585
4585
|
];
|
|
4586
4586
|
|
|
4587
|
+
// 1.9.157: Provider Registry β μ¬μ©μ μ μ provider λμ μΆκ° (.harness/providers.json)
|
|
4588
|
+
// λΉνΈμΈ 5μ’
(EXTERNAL_AGENTS) + μ¬μ©μ μ μλ₯Ό merge. OpenRouter / Bedrock / Groq λ± μ CLI μ¦μ ν‘μ κ°λ₯.
|
|
4589
|
+
// νμΌ νμ: { "schemaVersion": 1, "providers": [{ id, bin, envFlag, versionArgs, desc, installHint }] }
|
|
4590
|
+
function _providersFile(root) { return path.join(absRoot(root), '.harness', 'providers.json'); }
|
|
4591
|
+
function _readUserProviders(root) {
|
|
4592
|
+
const p = _providersFile(root);
|
|
4593
|
+
if (!exists(p)) return [];
|
|
4594
|
+
try {
|
|
4595
|
+
const j = JSON.parse(read(p));
|
|
4596
|
+
return Array.isArray(j.providers) ? j.providers : [];
|
|
4597
|
+
} catch { return []; }
|
|
4598
|
+
}
|
|
4599
|
+
function _writeUserProviders(root, providers) {
|
|
4600
|
+
const p = _providersFile(root);
|
|
4601
|
+
mkdirp(path.dirname(p));
|
|
4602
|
+
writeUtf8(p, JSON.stringify({ schemaVersion: 1, providers }, null, 2) + '\n');
|
|
4603
|
+
}
|
|
4604
|
+
// λΉνΈμΈ + μ¬μ©μ μ μ merge β κ°μ id κ° μμΌλ©΄ user κ° λΉνΈμΈ override
|
|
4605
|
+
function _allProviders(root) {
|
|
4606
|
+
try {
|
|
4607
|
+
const userList = _readUserProviders(root);
|
|
4608
|
+
const builtinIds = new Set(EXTERNAL_AGENTS.map(a => a.id));
|
|
4609
|
+
const userOverrides = new Map();
|
|
4610
|
+
for (const u of userList) {
|
|
4611
|
+
if (!u || !u.id) continue;
|
|
4612
|
+
// μ μν β λλ½ νλλ λΉνΈμΈμμ fallback
|
|
4613
|
+
userOverrides.set(u.id, {
|
|
4614
|
+
id: u.id,
|
|
4615
|
+
bin: u.bin || u.id,
|
|
4616
|
+
envFlag: u.envFlag || `LEERNESS_ENABLE_${String(u.id).toUpperCase()}`,
|
|
4617
|
+
versionArgs: Array.isArray(u.versionArgs) ? u.versionArgs : ['--version'],
|
|
4618
|
+
desc: u.desc || `(user) ${u.id}`,
|
|
4619
|
+
installHint: u.installHint || '',
|
|
4620
|
+
installCmd: u.installCmd || ''
|
|
4621
|
+
});
|
|
4622
|
+
}
|
|
4623
|
+
// λΉνΈμΈ λ¨Όμ , user override μ μ©
|
|
4624
|
+
const merged = EXTERNAL_AGENTS.map(a => userOverrides.has(a.id) ? userOverrides.get(a.id) : a);
|
|
4625
|
+
// λΉνΈμΈμ μλ user-only μΆκ°
|
|
4626
|
+
for (const u of userOverrides.values()) {
|
|
4627
|
+
if (!builtinIds.has(u.id)) merged.push(u);
|
|
4628
|
+
}
|
|
4629
|
+
return merged;
|
|
4630
|
+
} catch { return EXTERNAL_AGENTS.slice(); }
|
|
4631
|
+
}
|
|
4632
|
+
function providerCmd(root, sub, ...args) {
|
|
4633
|
+
root = absRoot(root || process.cwd());
|
|
4634
|
+
_loadEnvFile(root);
|
|
4635
|
+
if (!sub || sub === 'list') {
|
|
4636
|
+
const all = _allProviders(root);
|
|
4637
|
+
const userList = _readUserProviders(root);
|
|
4638
|
+
const userIds = new Set(userList.map(u => u.id));
|
|
4639
|
+
if (has('--json')) {
|
|
4640
|
+
log(JSON.stringify({
|
|
4641
|
+
total: all.length,
|
|
4642
|
+
builtin: EXTERNAL_AGENTS.length,
|
|
4643
|
+
user: userList.length,
|
|
4644
|
+
providers: all.map(p => ({ id: p.id, bin: p.bin, envFlag: p.envFlag, source: userIds.has(p.id) ? 'user' : 'builtin', desc: p.desc }))
|
|
4645
|
+
}, null, 2));
|
|
4646
|
+
return;
|
|
4647
|
+
}
|
|
4648
|
+
log(`# leerness provider list (1.9.157)`);
|
|
4649
|
+
log(`μ΄ ${all.length}κ° (λΉνΈμΈ ${EXTERNAL_AGENTS.length} + μ¬μ©μ ${userList.length})`);
|
|
4650
|
+
log('');
|
|
4651
|
+
log(`| id | source | bin | envFlag |`);
|
|
4652
|
+
log(`|---|---|---|---|`);
|
|
4653
|
+
for (const p of all) {
|
|
4654
|
+
const src = userIds.has(p.id) ? (EXTERNAL_AGENTS.some(b => b.id === p.id) ? 'user(override)' : 'user') : 'builtin';
|
|
4655
|
+
log(`| ${p.id} | ${src} | ${p.bin} | ${p.envFlag} |`);
|
|
4656
|
+
}
|
|
4657
|
+
if (!userList.length) {
|
|
4658
|
+
log('');
|
|
4659
|
+
log(`π‘ μ¬μ©μ μ μ provider μΆκ°: leerness provider add <id> --bin <cmd> [--env-flag F] [--version-args ARGS] [--desc D]`);
|
|
4660
|
+
}
|
|
4661
|
+
return;
|
|
4662
|
+
}
|
|
4663
|
+
if (sub === 'add') {
|
|
4664
|
+
const id = (args[0] || arg('--id', '')).trim();
|
|
4665
|
+
if (!id) return fail('provider add <id> νμ (μ: openrouter)');
|
|
4666
|
+
if (!/^[a-z][a-z0-9_-]*$/i.test(id)) return fail(`μλͺ»λ id: ${id} (μλ¬Έμ/μ«μ/_- λ§ νμ©)`);
|
|
4667
|
+
const bin = arg('--bin', id);
|
|
4668
|
+
const envFlag = arg('--env-flag', `LEERNESS_ENABLE_${id.toUpperCase()}`);
|
|
4669
|
+
const versionArgs = (arg('--version-args', '--version') || '--version').split(/\s+/).filter(Boolean);
|
|
4670
|
+
const desc = arg('--desc', `(user) ${id}`);
|
|
4671
|
+
const installHint = arg('--install-hint', '');
|
|
4672
|
+
const userList = _readUserProviders(root);
|
|
4673
|
+
// μ€λ³΅ id μ²λ¦¬: λΉνΈμΈ override λλ user κ°±μ
|
|
4674
|
+
const existingIdx = userList.findIndex(u => u.id === id);
|
|
4675
|
+
const entry = { id, bin, envFlag, versionArgs, desc, installHint };
|
|
4676
|
+
if (existingIdx >= 0) userList[existingIdx] = entry;
|
|
4677
|
+
else userList.push(entry);
|
|
4678
|
+
_writeUserProviders(root, userList);
|
|
4679
|
+
ok(`provider λ±λ‘: ${id} (bin=${bin}, envFlag=${envFlag})`);
|
|
4680
|
+
log(` β νμ±ν: .envμ ${envFlag}=1 μ€μ ν \`leerness agents list\` λ‘ νμΈ`);
|
|
4681
|
+
return;
|
|
4682
|
+
}
|
|
4683
|
+
if (sub === 'remove') {
|
|
4684
|
+
const id = (args[0] || arg('--id', '')).trim();
|
|
4685
|
+
if (!id) return fail('provider remove <id> νμ');
|
|
4686
|
+
if (EXTERNAL_AGENTS.some(b => b.id === id) && !_readUserProviders(root).some(u => u.id === id)) {
|
|
4687
|
+
return fail(`${id} λ λΉνΈμΈ β μ κ±° λΆκ° (override λ§ μ κ±° κ°λ₯)`);
|
|
4688
|
+
}
|
|
4689
|
+
const userList = _readUserProviders(root);
|
|
4690
|
+
const before = userList.length;
|
|
4691
|
+
const filtered = userList.filter(u => u.id !== id);
|
|
4692
|
+
if (filtered.length === before) return fail(`μ¬μ©μ μ μ provider ${id} μμ`);
|
|
4693
|
+
_writeUserProviders(root, filtered);
|
|
4694
|
+
ok(`provider μ κ±°: ${id}`);
|
|
4695
|
+
return;
|
|
4696
|
+
}
|
|
4697
|
+
fail(`μ μ μλ sub: ${sub} (list / add / remove)`);
|
|
4698
|
+
}
|
|
4699
|
+
|
|
4587
4700
|
// 1.9.36: μμ
ν€μλ λΆμμΌλ‘ μ΅μ CLI μΆμ²
|
|
4588
4701
|
// \bλ ASCII word boundaryλ§ μΈμ β νκΈ ν€μλλ λ¨μ substring κ²μ¬ μ¬μ©.
|
|
4589
4702
|
function _recommendAgent(task) {
|
|
@@ -5119,17 +5232,20 @@ function agentsCmd(root, sub, ...args) {
|
|
|
5119
5232
|
_loadEnvFile(path.join(root, '..'));
|
|
5120
5233
|
|
|
5121
5234
|
if (!sub || sub === 'list') {
|
|
5122
|
-
|
|
5235
|
+
// 1.9.157: Provider Registry ν΅ν© β λΉνΈμΈ 5μ’
+ μ¬μ©μ μ μ provider ν¬ν¨
|
|
5236
|
+
const providers = _allProviders(root);
|
|
5237
|
+
const userIds = new Set(_readUserProviders(root).map(u => u.id));
|
|
5238
|
+
const checks = providers.map(a => ({ ...(_checkAgent(a)), source: userIds.has(a.id) ? 'user' : 'builtin' }));
|
|
5123
5239
|
if (has('--json')) { log(JSON.stringify({ agents: checks }, null, 2)); return; }
|
|
5124
5240
|
log(`# μΈλΆ AI CLI μ€μΌμ€νΈλ μ΄μ
(1.9.30)`);
|
|
5125
5241
|
log('');
|
|
5126
|
-
log(`| Agent | env (${'env=1 νμ±'}) | μ€μΉ | λ²μ | μν |`);
|
|
5127
|
-
log(
|
|
5242
|
+
log(`| Agent | source | env (${'env=1 νμ±'}) | μ€μΉ | λ²μ | μν |`);
|
|
5243
|
+
log(`|---|---|---|---|---|---|`);
|
|
5128
5244
|
for (const c of checks) {
|
|
5129
5245
|
const envMark = c.enabled ? 'β' : 'β';
|
|
5130
5246
|
const instMark = c.installed ? 'β' : 'β';
|
|
5131
5247
|
const statusEmoji = c.status === 'ready' ? 'π’ ready' : c.status === 'not-installed' ? 'βͺ λ―Έμ€μΉ' : c.status === 'disabled' ? 'π‘ λΉνμ±' : 'β';
|
|
5132
|
-
log(`| ${c.id} | ${envMark} ${c.envFlag} | ${instMark} | ${c.version || '-'} | ${statusEmoji} |`);
|
|
5248
|
+
log(`| ${c.id} | ${c.source} | ${envMark} ${c.envFlag} | ${instMark} | ${c.version || '-'} | ${statusEmoji} |`);
|
|
5133
5249
|
}
|
|
5134
5250
|
const ready = checks.filter(c => c.status === 'ready');
|
|
5135
5251
|
log('');
|
|
@@ -5140,6 +5256,7 @@ function agentsCmd(root, sub, ...args) {
|
|
|
5140
5256
|
log(` 1) CLI μ€μΉ (μ: \`npm i -g @openai/codex-cli\`, \`npm i -g @google/gemini-cli\`)`);
|
|
5141
5257
|
log(` 2) .env λλ νκ²½λ³μ: LEERNESS_ENABLE_CODEX=1, LEERNESS_ENABLE_GEMINI=1`);
|
|
5142
5258
|
log(` 3) \`leerness agents check\`λ‘ μ¬νμΈ`);
|
|
5259
|
+
log(` π‘ 1.9.157: λΉνΈμΈ μΈ CLI μΆκ°: \`leerness provider add <id> --bin <cmd>\``);
|
|
5143
5260
|
} else {
|
|
5144
5261
|
log('');
|
|
5145
5262
|
log(`π‘ λ©μΈ μμ΄μ νΈκ° sub-agent λΆλ°° μ μ ${ready.length}κ° CLI νμ© κ°λ₯:`);
|
|
@@ -5150,7 +5267,10 @@ function agentsCmd(root, sub, ...args) {
|
|
|
5150
5267
|
|
|
5151
5268
|
if (sub === 'check') {
|
|
5152
5269
|
// listμ alias, λ¨ λͺ
μμ μ¬νμΈ (JSON μΆλ ₯ κΈ°λ³Έ)
|
|
5153
|
-
|
|
5270
|
+
// 1.9.157: Provider Registry ν΅ν©
|
|
5271
|
+
const providers = _allProviders(root);
|
|
5272
|
+
const userIds = new Set(_readUserProviders(root).map(u => u.id));
|
|
5273
|
+
const checks = providers.map(a => ({ ...(_checkAgent(a)), source: userIds.has(a.id) ? 'user' : 'builtin' }));
|
|
5154
5274
|
if (has('--json')) { log(JSON.stringify({ agents: checks, ready: checks.filter(c => c.status === 'ready').map(c => c.id) }, null, 2)); return; }
|
|
5155
5275
|
return agentsCmd(root, 'list'); // λΉ-JSONμ listμ λμΌ
|
|
5156
5276
|
}
|
|
@@ -9621,7 +9741,8 @@ function mcpServeCmd(root) {
|
|
|
9621
9741
|
{ name: 'leerness_feature_list', description: '1.9.141 β μ 체 Feature Graph λ
Έλ + μ£μ§ JSON. μΈλΆ AIκ° μμ€ν
λ΄ κΈ°λ₯ μμ‘΄μ±μ ν λ²μ νμ', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
|
|
9622
9742
|
{ name: 'leerness_feature_add', description: '1.9.142 β Feature Graph μ μ λ
Έλ μΆκ° (μΈλΆ AIκ° μ½λ μμ± μ€ μ§μ feature λ±λ‘). μΈμ: { title (required), dependsOn?, affects?, coChangesWith?, files?, path? }. μλ F-XXXX ID λΆμ¬. CRUD μμ±μ κΈ°μ¬', inputSchema: { type: 'object', properties: { title: { type: 'string' }, dependsOn: { type: 'string' }, affects: { type: 'string' }, coChangesWith: { type: 'string' }, files: { type: 'string' }, path: { type: 'string' } }, required: ['title'] } },
|
|
9623
9743
|
{ name: 'leerness_feature_link', description: '1.9.142 β κΈ°μ‘΄ feature λ
Έλμ μμ‘΄/μν₯/곡λ³κ²½ μ£μ§ μΆκ°. μΈμ: { id (required, F-XXXX), dependsOn?, affects?, coChangesWith?, path? }. μΈλΆ AIκ° μ½λ λ³κ²½ λμ€ λ°κ²¬ν μΈκ³Όκ΄κ³λ₯Ό μ¦μ κ·Έλνμ λ°μ', inputSchema: { type: 'object', properties: { id: { type: 'string' }, dependsOn: { type: 'string' }, affects: { type: 'string' }, coChangesWith: { type: 'string' }, path: { type: 'string' } }, required: ['id'] } },
|
|
9624
|
-
{ name: 'leerness_env_detect', description: '1.9.145 β μ€ν νκ²½ μλ κ°μ§ + λ³λ μΆμ JSON ({ snapshot: { os, hardware, locale, shell, node, tools, scriptDependencies }, diff: { firstCapture, changes, missing }, persisted }). "Xμ(λ) λ΄λΆ λλ μΈλΆ λͺ
λ Ή... μλλλ€" μ¬μ λ°©μ§: package.json scripts μμ‘΄ λκ΅¬κ° PATHμ μλμ§ κ²μ¦ + λ¨Έμ /Node/λꡬ λ³κ²½ κ°μ§. μ λκ²½λ‘ λ§μ€νΉ (보μ). μΈμ: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
|
|
9744
|
+
{ name: 'leerness_env_detect', description: '1.9.145 β μ€ν νκ²½ μλ κ°μ§ + λ³λ μΆμ JSON ({ snapshot: { os, hardware, locale, shell, node, tools, scriptDependencies }, diff: { firstCapture, changes, missing }, persisted }). "Xμ(λ) λ΄λΆ λλ μΈλΆ λͺ
λ Ή... μλλλ€" μ¬μ λ°©μ§: package.json scripts μμ‘΄ λκ΅¬κ° PATHμ μλμ§ κ²μ¦ + λ¨Έμ /Node/λꡬ λ³κ²½ κ°μ§. μ λκ²½λ‘ λ§μ€νΉ (보μ). μΈμ: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
|
|
9745
|
+
{ name: 'leerness_provider_list', description: '1.9.157/158 β Provider Registry μ‘°ν JSON ({ total, builtin, user, providers: [{ id, bin, envFlag, source, desc }] }). λΉνΈμΈ 5μ’
(claude/codex/gemini/copilot/ollama) + .harness/providers.json μ¬μ©μ μ μ ν΅ν©. μΈλΆ AIκ° sub-agent λΆλ°° κ°λ₯ν provider μ 체 νμ (OpenRouter/Bedrock λ± λ±λ‘λμ΄ μμΌλ©΄ κ°μ΄ λ
ΈμΆ). π MCP 48 λꡬ λ§μΌμ€ν€', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
|
|
9625
9746
|
];
|
|
9626
9747
|
|
|
9627
9748
|
function send(obj) {
|
|
@@ -9714,6 +9835,8 @@ function mcpServeCmd(root) {
|
|
|
9714
9835
|
break;
|
|
9715
9836
|
// 1.9.145: μ€ν νκ²½ μλ κ°μ§
|
|
9716
9837
|
case 'leerness_env_detect': cliArgs = ['env', 'detect', targetPath, '--json']; break;
|
|
9838
|
+
// 1.9.158: Provider Registry β μΈλΆ AI κ° λ±λ‘λ provider νμ
|
|
9839
|
+
case 'leerness_provider_list': cliArgs = ['provider', 'list', '--path', targetPath, '--json']; break;
|
|
9717
9840
|
default:
|
|
9718
9841
|
return send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Unknown tool: ${name}` } });
|
|
9719
9842
|
}
|
|
@@ -11572,7 +11695,7 @@ function reuseAutodetectCmd(root) {
|
|
|
11572
11695
|
}
|
|
11573
11696
|
|
|
11574
11697
|
function help() {
|
|
11575
|
-
log(`Leerness v${VERSION}\n\nUsage:\n leerness init [path] [--language auto|ko|en] [--skills recommended|all|a,b]\n leerness migrate [path] [--dry-run] [--force]\n leerness update [path] [--check|--yes|--force|--from <tarball>]\n leerness auto-update install [path]\n leerness status [path]\n leerness verify [path]\n leerness debug [path]\n leerness audit [path]\n leerness check [path]\n leerness scan secrets [path]\n leerness encoding check [path]\n leerness lazy detect [path]\n leerness memory search "query" [--limit 5]\n leerness handoff [path] [--all-apps] [--include p1,p2] [--since 24h|3d] [--compact] [--json] # 1.9.17-22 μν¬μ€νμ΄μ€ (--compact: LLM μμ€ν
ν둬ννΈμ© 1μ€ μμ½)\n leerness orchestrate "<λͺ©ν>" [--agents N] [--model qwen2.5:7b-instruct] [--retry-on-fail K] # 1.9.22 Ollama opt-in (LEERNESS_OLLAMA_BASE_URL νμ)\n leerness llm-bench record --score N --model X [--label L] [--tokens T] # 1.9.22 LLM λ²€μΉ νμ€ν 리 λμ \n leerness deps <capability> [--run-tests] [--json] # 1.9.24 depends-on μλ°©ν₯ μΆμ + μλ νκ· sweep\n leerness memory search "ν€" [--include-code] # 1.9.25 μμ€ μ½λ λ³Έλ¬Έλ κ²μ (λͺ¨μ κ°μ§ ν΅μ¬)\n leerness brainstorm "μ£Όμ " [--include-code] # 1.9.25 μ½λ λ³Έλ¬Έ hits ν¬ν¨\n leerness register-pending "<μμ²>" [--agent X] [--note Y] # 1.9.25 λ€μ€ μΈμ
in-progress μ¦μ λ±λ‘\n leerness optimism-check <T-ID> [--json] # 1.9.26/27 λκ΄μ νμ κ°μ§ (1.9.27: 10 μΉ΄ν
κ³ λ¦¬ + URL/λ©μλ λ§€ν + μ λ’°λ μ μ)\n leerness persona list|show <id>|add <id> # 1.9.29 νλ₯΄μλ μΉ΄νλ‘κ·Έ (보μ/μ±λ₯/UX/testing/docs 5μ’
λ΄μ₯)\n leerness review <file> --persona <id1,id2,...> # 1.9.29 λλ©μΈ νλ₯΄μλ 리뷰 ν둬ννΈ μλ μμ±\n leerness agents list|check|quota # 1.9.30/31 μΈλΆ AI CLI κ°μ©μ± + quota μΆμ (claude/codex/gemini/copilot)\n leerness agents dispatch "<task>" --to <id> # 1.9.30 νμ± CLI λμ μ€ν λͺ
λ Ή μμ± (μ€ νΈμΆ X, μ¬μ©μ μ€ν)\n leerness agents multi "<task>" [--only c1,c2] [--write] [--execute] [--timeout 60] # 1.9.152/156 νμ± Nκ° μΌκ΄ dispatch (--execute: μ€ spawn + consensus)\n leerness agents dispatch "<task>" --multi # 1.9.152 multi λͺ¨λ alias (λλ --to all)\n leerness setup-agents [path] [--yes|--no-setup-agents] # 1.9.32 sub-agent CLI μΈν°λν°λΈ μ€μ (.env + λ―Έμ€μΉ μλ μ€μΉ)\n leerness init [path] [--no-stale-check] # 1.9.33 npx μΊμ ν¨μ β μ λ²μ μλ κ²½κ³ (λλ €λ©΄ --no-stale-check)\n leerness contract verify <spec.md> <impl.js> [--json] # 1.9.35 λͺ
μΈ β ꡬν μΌμΉ κ²μ¬ (ν¨μ/νλ)\n leerness reuse autodetect [path] [--apply] [--json] # 1.9.35 src/*.jsμ module.exports β reuse-map ν보 λ±λ‘\n leerness audit [path] [--fix] # 1.9.35 --fix: session-handoff/current-state μλ κ°±μ \n leerness verify-claim <T-ID> ... [--strict-claims] # 1.9.26 verify-claimμ λκ΄μ νμ μλ κ²μ¬ ν΅ν©\n leerness reuse-map [path] [--all-apps] [--include p1,p2] [--strict-elements] [--json] # 1.9.18 μ€λ³΅/μ μ¬μ€λ³΅/depends-on\n leerness verify-claim <T-ID> [--path .] [--run-tests] [--json] # 1.9.18-20 evidence μλ κ²μ¦ (1.9.20: scenes/scripts λ± λλ©μΈ ν΄λ + jest/mocha νμ±)\n leerness verify-code [path] [--build] [--bench] # 1.9.20 --bench: scripts.bench μΆκ° μ€ν + evidence λμ \n leerness session close [path]\n leerness route <task-type>\n leerness self check [path]\n leerness readme sync [path]\n leerness consistency check [path]\n leerness consistency merge-design-guide [path]\n leerness plan show|init|add|drop|progress|sync [args]\n leerness task list|add|update|drop|fix-evidence|relink [args]\n leerness skill list|info <name>\n leerness skill learn <id> --doc <url> --command "..." --capability "..." [--note ...]\n leerness skill use <id> [--note ...]\n leerness skill optimize <id> --before "..." --after "..." [--note ...]\n leerness skill remove <id>\n leerness skill consolidate [--threshold 0.3]\n leerness gate [path] # verify+audit+scan+encoding+lazy
|
|
11698
|
+
log(`Leerness v${VERSION}\n\nUsage:\n leerness init [path] [--language auto|ko|en] [--skills recommended|all|a,b]\n leerness migrate [path] [--dry-run] [--force]\n leerness update [path] [--check|--yes|--force|--from <tarball>]\n leerness auto-update install [path]\n leerness status [path]\n leerness verify [path]\n leerness debug [path]\n leerness audit [path]\n leerness check [path]\n leerness scan secrets [path]\n leerness encoding check [path]\n leerness lazy detect [path]\n leerness memory search "query" [--limit 5]\n leerness handoff [path] [--all-apps] [--include p1,p2] [--since 24h|3d] [--compact] [--json] # 1.9.17-22 μν¬μ€νμ΄μ€ (--compact: LLM μμ€ν
ν둬ννΈμ© 1μ€ μμ½)\n leerness orchestrate "<λͺ©ν>" [--agents N] [--model qwen2.5:7b-instruct] [--retry-on-fail K] # 1.9.22 Ollama opt-in (LEERNESS_OLLAMA_BASE_URL νμ)\n leerness llm-bench record --score N --model X [--label L] [--tokens T] # 1.9.22 LLM λ²€μΉ νμ€ν 리 λμ \n leerness deps <capability> [--run-tests] [--json] # 1.9.24 depends-on μλ°©ν₯ μΆμ + μλ νκ· sweep\n leerness memory search "ν€" [--include-code] # 1.9.25 μμ€ μ½λ λ³Έλ¬Έλ κ²μ (λͺ¨μ κ°μ§ ν΅μ¬)\n leerness brainstorm "μ£Όμ " [--include-code] # 1.9.25 μ½λ λ³Έλ¬Έ hits ν¬ν¨\n leerness register-pending "<μμ²>" [--agent X] [--note Y] # 1.9.25 λ€μ€ μΈμ
in-progress μ¦μ λ±λ‘\n leerness optimism-check <T-ID> [--json] # 1.9.26/27 λκ΄μ νμ κ°μ§ (1.9.27: 10 μΉ΄ν
κ³ λ¦¬ + URL/λ©μλ λ§€ν + μ λ’°λ μ μ)\n leerness persona list|show <id>|add <id> # 1.9.29 νλ₯΄μλ μΉ΄νλ‘κ·Έ (보μ/μ±λ₯/UX/testing/docs 5μ’
λ΄μ₯)\n leerness review <file> --persona <id1,id2,...> # 1.9.29 λλ©μΈ νλ₯΄μλ 리뷰 ν둬ννΈ μλ μμ±\n leerness agents list|check|quota # 1.9.30/31 μΈλΆ AI CLI κ°μ©μ± + quota μΆμ (claude/codex/gemini/copilot)\n leerness agents dispatch "<task>" --to <id> # 1.9.30 νμ± CLI λμ μ€ν λͺ
λ Ή μμ± (μ€ νΈμΆ X, μ¬μ©μ μ€ν)\n leerness agents multi "<task>" [--only c1,c2] [--write] [--execute] [--timeout 60] # 1.9.152/156 νμ± Nκ° μΌκ΄ dispatch (--execute: μ€ spawn + consensus)\n leerness provider list|add|remove [args] # 1.9.157 Provider Registry β μ¬μ©μ μ μ CLI provider λμ μΆκ° (OpenRouter/Bedrock ν‘μ)\n leerness agents dispatch "<task>" --multi # 1.9.152 multi λͺ¨λ alias (λλ --to all)\n leerness setup-agents [path] [--yes|--no-setup-agents] # 1.9.32 sub-agent CLI μΈν°λν°λΈ μ€μ (.env + λ―Έμ€μΉ μλ μ€μΉ)\n leerness init [path] [--no-stale-check] # 1.9.33 npx μΊμ ν¨μ β μ λ²μ μλ κ²½κ³ (λλ €λ©΄ --no-stale-check)\n leerness contract verify <spec.md> <impl.js> [--json] # 1.9.35 λͺ
μΈ β ꡬν μΌμΉ κ²μ¬ (ν¨μ/νλ)\n leerness reuse autodetect [path] [--apply] [--json] # 1.9.35 src/*.jsμ module.exports β reuse-map ν보 λ±λ‘\n leerness audit [path] [--fix] # 1.9.35 --fix: session-handoff/current-state μλ κ°±μ \n leerness verify-claim <T-ID> ... [--strict-claims] # 1.9.26 verify-claimμ λκ΄μ νμ μλ κ²μ¬ ν΅ν©\n leerness reuse-map [path] [--all-apps] [--include p1,p2] [--strict-elements] [--json] # 1.9.18 μ€λ³΅/μ μ¬μ€λ³΅/depends-on\n leerness verify-claim <T-ID> [--path .] [--run-tests] [--json] # 1.9.18-20 evidence μλ κ²μ¦ (1.9.20: scenes/scripts λ± λλ©μΈ ν΄λ + jest/mocha νμ±)\n leerness verify-code [path] [--build] [--bench] # 1.9.20 --bench: scripts.bench μΆκ° μ€ν + evidence λμ \n leerness session close [path]\n leerness route <task-type>\n leerness self check [path]\n leerness readme sync [path]\n leerness consistency check [path]\n leerness consistency merge-design-guide [path]\n leerness plan show|init|add|drop|progress|sync [args]\n leerness task list|add|update|drop|fix-evidence|relink [args]\n leerness skill list|info <name>\n leerness skill learn <id> --doc <url> --command "..." --capability "..." [--note ...]\n leerness skill use <id> [--note ...]\n leerness skill optimize <id> --before "..." --after "..." [--note ...]\n leerness skill remove <id>\n leerness skill consolidate [--threshold 0.3]\n leerness gate [path] # verify+audit+scan+encoding+lazy
|
|
11576
11699
|
leerness retro [path] [--days 7] [--all-apps] [--include p1,p2] [--json] # νκ³ (1.9.13~1.9.16)
|
|
11577
11700
|
leerness insights [path] [--all-apps] [--include p1,p2] [--json] # λμ ν΅κ³ (1.9.13~1.9.16)
|
|
11578
11701
|
leerness brainstorm "<μ£Όμ >" [--all-apps] [--include p1,p2] [--json] # λΈλ μΈμ€ν λ° (1.9.13~1.9.16)
|
|
@@ -11644,6 +11767,8 @@ async function main() {
|
|
|
11644
11767
|
if (cmd === 'persona') return personaCmd(arg('--path', process.cwd()), args[1], args[2]);
|
|
11645
11768
|
if (cmd === 'review') return reviewCmd(arg('--path', process.cwd()), args[1]);
|
|
11646
11769
|
if (cmd === 'agents') return agentsCmd(arg('--path', process.cwd()), args[1], ...args.slice(2));
|
|
11770
|
+
// 1.9.157: Provider Registry β μ¬μ©μ μ μ provider λμ μΆκ°
|
|
11771
|
+
if (cmd === 'provider') return providerCmd(arg('--path', process.cwd()), args[1], ...args.slice(2));
|
|
11647
11772
|
if (cmd === 'contract' && args[1] === 'verify') return contractVerifyCmd(args[2], args[3]);
|
|
11648
11773
|
if (cmd === 'drift' && (args[1] === 'check' || !args[1])) return driftCheckCmd(args[2] || arg('--path', process.cwd()));
|
|
11649
11774
|
if (cmd === 'usage' && (args[1] === 'stats' || !args[1])) return usageStatsCmd(args[2] || arg('--path', process.cwd()));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.158",
|
|
4
4
|
"description": "Leerness: λΉνκ΄΄ λ§μ΄κ·Έλ μ΄μ
, μλ λ²μ κ°μ§Β·μ
λ°μ΄νΈ, κ³ν/μ§ν/νΈλμ€ν μλν, κ²μΌλ¦Β·μν¬λ¦ΏΒ·μΈμ½λ© μλ κ°λ, Claude Code μ¬λμ ν΅ν©μ κ°μΆ νκ΅μ΄ μ°μ AI κ°λ° νλ€μ€.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|