leerness 1.9.180 β†’ 1.9.181

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,76 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.181 β€” 2026-05-21
4
+
5
+ **πŸšͺ REPL μ§„μž… 흐름 정리 β€” μ‚¬μš©μž λͺ…μ‹œ 4μ’… + 직접 ꡬ동 μ‹€ 호좜 검증.**
6
+
7
+ 자율 λͺ¨λ“œ 111 λΌμš΄λ“œ. μ‚¬μš©μž 직접 ꡬ동 ν…ŒμŠ€νŠΈ κ²°κ³Ό 보고 (μŠ€ν¬λ¦°μƒ· 첨뢀):
8
+ 1. *"1.9.149 Hermes/OpenClaw μŠ€νƒ€μΌ λ“±μ˜ λ¬Έκ΅¬λŠ” 제거"* β†’ μ„€μΉ˜ μ™„λ£Œ λ©”μ‹œμ§€ λ‹¨μˆœν™”
9
+ 2. *"이 λ‹¨κ³„μ—μ„œ Ollama μ œμ™Έν•œ λͺ¨λΈμ„ μ„ νƒν–ˆλŠ”λ° REPL μ§„μž… μ‹œ Ollama μš°μ„  호좜"* β†’ installβ†’REPL provider μžλ™ 선택
10
+ 3. *"ν”„λ‘œλ°”μ΄λ” μ „ν™˜ 선택 단계 없이 λ°”λ‘œ μ±„νŒ… λͺ¨λ“œλ‘œ μ§„μž…"* β†’ μ§„μž… prompt 제거
11
+ 4. *"REPL을 직접 κ΅¬λ™ν•΄μ„œ λͺ…λ Ή μž…λ ₯해보고 개발/μ›Ή/PC/μΆ”λ‘ /질문-λ‹΅λ³€ λ™μž‘ ν…ŒμŠ€νŠΈ"* β†’ agents multi --execute μ‹€ 호좜 검증
12
+
13
+ ### Fix #1 β€” 문ꡬ λ‹¨μˆœν™”
14
+ ```diff
15
+ - log('πŸš€ μ„€μΉ˜ μ™„λ£Œ β€” REPL agent λͺ¨λ“œλ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€ (1.9.149 Hermes/OpenClaw μŠ€νƒ€μΌ)...');
16
+ + log('πŸš€ μ„€μΉ˜ μ™„λ£Œ β€” REPL agent λͺ¨λ“œλ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€...');
17
+ ```
18
+
19
+ ### Fix #2 β€” installβ†’REPL provider ν•˜λ“œμ½”λ”© 제거
20
+ ```diff
21
+ - await _agentRepl(root, { provider: 'ollama', role: 'actor' }); // 1.9.151 β€” 무쑰건 ollama
22
+ + await _agentRepl(root, { role: 'actor' }); // provider λ―Έμ§€μ • β†’ auto-select λ™μž‘ (1.9.181 fix)
23
+ ```
24
+
25
+ ### Fix #3 β€” λΉ„-Ollama μš°μ„  μžλ™ 선택 (Ollama μš°μ„  호좜 X)
26
+ ```js
27
+ const ready = EXTERNAL_AGENTS.map(a => ({ def: a, status: _checkAgent(a) }))
28
+ .filter(x => x.status.status === 'ready');
29
+ const nonOllama = ready.filter(x => x.def.id !== 'ollama');
30
+ if (nonOllama.length >= 1) {
31
+ // λΉ„-Ollama ν™œμ„± β†’ 첫 번째 μžλ™ (μ‚¬μš©μž λͺ…μ‹œ: Ollama μš°μ„  호좜 X)
32
+ initialProvider = nonOllama[0].def.id;
33
+ _autoPickNote = nonOllama.length === 1
34
+ ? `${initialProvider} μžλ™ 선택 (ν™œμ„± CLI 1개)`
35
+ : `${initialProvider} μžλ™ 선택 (ν™œμ„± CLI ${nonOllama.length}개 Β· Tab으둜 μ „ν™˜)`;
36
+ }
37
+ ```
38
+
39
+ ### Fix #4 β€” provider μ „ν™˜ prompt 단계 제거 (μžλ™ μ „ν™˜)
40
+ 이전:
41
+ ```
42
+ ⚠ Ollama 미가동 λ˜λŠ” λͺ¨λΈ μ—†μŒ
43
+ πŸ’‘ ν™œμ„± μ™ΈλΆ€ CLI 4개 발견 β€” provider μ „ν™˜ κ°€λŠ₯:
44
+ 1) claude (v2.1.145)
45
+ 2) codex (vcodex-cli 0.132.0)
46
+ ...
47
+ provider μ „ν™˜ (번호 / Enter=ollama 계속): _
48
+ ```
49
+ μ§€κΈˆ:
50
+ ```
51
+ β–Έ Provider: claude μžλ™ 선택 (ν™œμ„± CLI 4개 Β· Tab으둜 μ „ν™˜)
52
+ [μ±„νŒ… λͺ¨λ“œ μ¦‰μ‹œ μ§„μž…]
53
+ ```
54
+
55
+ ### 직접 ꡬ동 μ‹€ 호좜 검증 (μ‚¬μš©μž λͺ…μ‹œ 4번째 μš”μ²­)
56
+ ```bash
57
+ $ leerness agents multi "1+1=? 숫자만 λ‹΅ν•΄μ£Όμ„Έμš”." --only claude,gemini --execute --timeout 30
58
+ βœ“ claude Β· 4810ms Β· 1 토큰
59
+ βœ— gemini Β· 1266ms Β· exit=null
60
+ best: claude Β· score=0.600
61
+ --- 처음 600자 ---
62
+ 2
63
+ ```
64
+ **claude μΆ”λ‘  응닡 정상**. geminiλŠ” 별도 ν™˜κ²½ 이슈 (--yolo κΆŒν•œ λ˜λŠ” quota β€” 1.9.182μ—μ„œ μΆ”κ°€ 디버그 후보).
65
+
66
+ ### Verified
67
+ - stress-v126: **18/18** (μ‚¬μš©μž λͺ…μ‹œ 4 + μžλ™ 선택 λ™μž‘ 4 + 직접 ꡬ동 2 + VERSION+λˆ„μ  νšŒκ·€ 8)
68
+ - e2e 217/217 baseline μœ μ§€
69
+ - claude μ‹€ 호좜 4810ms Β· 응닡 "2" β€” REPL agent의 핡심 λŠ₯λ ₯ (μ‹€ λͺ¨λΈ 호좜 + μΆ”λ‘  + 응닡 μˆ˜μ‹ ) λ™μž‘ 확인
70
+ - VERSION = 1.9.181 Β· autonomous-rounds = 111 Β· main μžλ™ push 42 λΌμš΄λ“œ 연속
71
+
72
+ ---
73
+
3
74
  ## 1.9.180 β€” 2026-05-21
4
75
 
5
76
  **πŸ”§ REPL Tab cycle 핡심 fix + μ±„νŒ… μ˜μ—­ separator β€” μ‚¬μš©μž λͺ…μ‹œ (직접 ꡬ동 ν…ŒμŠ€νŠΈ κ²°κ³Ό).**
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.180-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v125-17%2F17-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-110-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-41_rounds-success)]() [![repl-tab](https://img.shields.io/badge/REPL_Tab_cycle-completer_no--op%2BShift_fix-success)]() [![repl-chat](https://img.shields.io/badge/REPL_고정헀더-μ±„νŒ…μ˜μ—­_separator-success)]() [![npm-auto](https://img.shields.io/badge/npm_auto--publish-NPM__TOKEN_톡합-success)]() [![capability](https://img.shields.io/badge/6_capability-72%25_production--ready-brightgreen)]() [![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.181-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v126-18%2F18-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-111-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-42_rounds-success)]() [![repl-flow](https://img.shields.io/badge/REPL_μ§„μž…-provider_μžλ™μ„ νƒ-success)]() [![repl-tested](https://img.shields.io/badge/μ‹€ν˜ΈμΆœ-claude_검증-success)]() [![npm-auto](https://img.shields.io/badge/npm_auto--publish-NPM__TOKEN_톡합-success)]() [![capability](https://img.shields.io/badge/6_capability-72%25_production--ready-brightgreen)]() [![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.180 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.181 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ πŸ”§ REPL Tab cycle fix Β· μ±„νŒ… μ˜μ—­ separator (κ³ μ • 헀더+μ±„νŒ…) β•‘
17
+ β•‘ πŸšͺ REPL μ§„μž… 흐름 정리 (provider μžλ™ 선택 Β· μ‹€ν˜ΈμΆœ 검증) β•‘
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.180';
10
+ const VERSION = '1.9.181';
11
11
  const MARK = '<!-- leerness:managed -->';
12
12
  const README_START = '<!-- leerness:project-readme:start -->';
13
13
  const README_END = '<!-- leerness:project-readme:end -->';
@@ -934,12 +934,13 @@ async function install(root, opts = {}) {
934
934
  // resolveInstallOptions (1.9.146) κ°€ 이미 λͺ¨λ“  prompt λͺ¨μ€ μœ„μΉ˜μ— ν†΅ν•©λœ 4μ§€μ„ λ‹€ prompt 있음.
935
935
  // 별도 setupAgents λͺ…령은 μ‚¬μš©μžκ°€ λͺ…μ‹œμ μœΌλ‘œ `leerness setup-agents` 호좜 μ‹œμ—λ§Œ.
936
936
  // 1.9.151: μ„€μΉ˜ μ™„λ£Œ 직후 β€” startRepl 선택 μ‹œ REPL agent λͺ¨λ“œ μ¦‰μ‹œ μ§„μž… (μ‚¬μš©μž λͺ…μ‹œ μš”μ²­)
937
+ // 1.9.181: 문ꡬ λ‹¨μˆœν™” + provider ν•˜λ“œμ½”λ”© 제거 (μ‚¬μš©μž λͺ…μ‹œ β€” install μ„ νƒν•œ CLIλ₯Ό REPL이 μžλ™ 선택)
937
938
  if (resolved.startRepl && !opts.migration && process.stdin.isTTY && process.env.LEERNESS_NO_PROMPT !== '1') {
938
939
  log('');
939
- log('πŸš€ μ„€μΉ˜ μ™„λ£Œ β€” REPL agent λͺ¨λ“œλ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€ (1.9.149 Hermes/OpenClaw μŠ€νƒ€μΌ)...');
940
+ log('πŸš€ μ„€μΉ˜ μ™„λ£Œ β€” REPL agent λͺ¨λ“œλ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€...');
940
941
  log('');
941
942
  try {
942
- await _agentRepl(root, { provider: 'ollama', role: 'actor' });
943
+ await _agentRepl(root, { role: 'actor' }); // provider λ―Έμ§€μ • β†’ _agentRepl 의 auto-select λ™μž‘ (1.9.181 fix)
943
944
  } catch (e) { warn('REPL μ§„μž… μ‹€νŒ¨: ' + e.message); }
944
945
  }
945
946
  }
@@ -11066,23 +11067,28 @@ async function _agentRepl(root, opts) {
11066
11067
  bold: s => `\x1b[1m${s}\x1b[0m`, green: s => `\x1b[32m${s}\x1b[0m`,
11067
11068
  yel: s => `\x1b[33m${s}\x1b[0m`, mag: s => `\x1b[35m${s}\x1b[0m`
11068
11069
  } : { cy:s=>s, dim:s=>s, bold:s=>s, green:s=>s, yel:s=>s, mag:s=>s };
11069
- // 1.9.153: provider μžλ™ 선택 β€” opts.provider λͺ…μ‹œ μ•ˆ 됨 + ν™œμ„± CLI κ°€ 있으면 μ‚¬μš©μžμ—κ²Œ 선택지 ν‘œμ‹œ
11070
+ // 1.9.181 fix: provider μžλ™ 선택 β€” prompt 단계 μ œκ±°ν•˜κ³  μ¦‰μ‹œ μ±„νŒ… λͺ¨λ“œ μ§„μž… (μ‚¬μš©μž λͺ…μ‹œ).
11071
+ // μ •μ±…: λΉ„-Ollama ν™œμ„± CLI μš°μ„  β†’ Ollama β†’ fallback. 볡수 ν™œμ„± μ‹œ prompt 없이 첫 λΉ„-Ollama μžλ™ 선택.
11072
+ // μ‚¬μš©μž μ˜λ„: "ν”„λ‘œλ°”μ΄λ” μ „ν™˜ 선택 단계없이 λ°”λ‘œ μ±„νŒ… λͺ¨λ“œλ‘œ μ§„μž…ν•΄λ„ 될거같아" + "Ollamaλ₯Ό μš°μ„  호좜 X".
11073
+ // Tab 으둜 μ–Έμ œλ“  cycle κ°€λŠ₯ν•˜λ―€λ‘œ μžλ™ 선택해도 μ‚¬μš©μžκ°€ μ¦‰μ‹œ μ „ν™˜ κ°€λŠ₯.
11070
11074
  let initialProvider = opts.provider;
11075
+ let _autoPickNote = '';
11071
11076
  if (!initialProvider) {
11072
11077
  const ready = EXTERNAL_AGENTS.map(a => ({ def: a, status: _checkAgent(a) }))
11073
11078
  .filter(x => x.status.status === 'ready');
11074
- if (ready.length === 1) {
11075
- initialProvider = ready[0].def.id; // 단일 ν™œμ„± β†’ μžλ™ 선택
11076
- } else if (ready.length > 1 && isTty) {
11077
- // 볡수 ν™œμ„± β†’ μ‚¬μš©μžμ—κ²Œ 선택지 (Ollama μš°μ„ μ΄ μ•„λ‹Œ, ν™œμ„±λœ CLI 쀑 선택)
11078
- console.log('');
11079
- console.log(` μ‚¬μš© κ°€λŠ₯ν•œ CLI μ—μ΄μ „νŠΈ ${ready.length}개:`);
11080
- ready.forEach((x, i) => console.log(` ${i + 1}) ${x.def.id}${x.status.version ? ' (v' + x.status.version + ')' : ''}`));
11081
- const choice = await new Promise(res => rl.question(`\n provider 선택 (Enter=1): `, res));
11082
- const idx = parseInt(choice, 10) - 1;
11083
- initialProvider = (idx >= 0 && idx < ready.length) ? ready[idx].def.id : ready[0].def.id;
11079
+ const nonOllama = ready.filter(x => x.def.id !== 'ollama');
11080
+ if (nonOllama.length >= 1) {
11081
+ // λΉ„-Ollama ν™œμ„± β†’ 첫 번째 μžλ™ (μ‚¬μš©μž λͺ…μ‹œ: Ollama μš°μ„  호좜 X)
11082
+ initialProvider = nonOllama[0].def.id;
11083
+ _autoPickNote = nonOllama.length === 1
11084
+ ? `${initialProvider} μžλ™ 선택 (ν™œμ„± CLI 1개)`
11085
+ : `${initialProvider} μžλ™ 선택 (ν™œμ„± CLI ${nonOllama.length}개 Β· Tab으둜 μ „ν™˜)`;
11086
+ } else if (ready.length === 1) {
11087
+ initialProvider = ready[0].def.id; // ollama 단독
11088
+ _autoPickNote = `${initialProvider} μžλ™ 선택`;
11084
11089
  } else {
11085
- initialProvider = 'ollama'; // ν™œμ„± 0개 β†’ fallback (μ‚¬μš© μ‹œ friendly κ²½κ³ )
11090
+ initialProvider = 'ollama'; // ν™œμ„± 0개 β†’ fallback
11091
+ _autoPickNote = 'fallback ollama (ν™œμ„± CLI μ—†μŒ β€” .env μ—μ„œ LEERNESS_ENABLE_* ν™œμ„±ν™” ꢌμž₯)';
11086
11092
  }
11087
11093
  }
11088
11094
  // μ„Έμ…˜ state
@@ -11116,47 +11122,27 @@ async function _agentRepl(root, opts) {
11116
11122
  log('');
11117
11123
  log(C.dim(` β–Έ Welcome back Β· ${wsName} (${rel(process.cwd(), absRoot(root))})`));
11118
11124
  log(C.dim(` β–Έ Session: ${state.sessionId}`));
11125
+ if (_autoPickNote) log(C.dim(` β–Έ Provider: ${_autoPickNote}`));
11119
11126
  log('');
11120
- // Ollama λͺ¨λΈ μžλ™ 감지 β€” model이 λͺ…μ‹œλ˜μ§€ μ•Šμ•˜μœΌλ©΄ μ‚¬μš©μžμ—κ²Œ 선택지 제곡
11127
+ // 1.9.181 fix: provider μ§„μž… μ‹œμ  prompt 단계 제거 β€” μžλ™ μ „ν™˜λ§Œ μˆ˜ν–‰ (μ‚¬μš©μž λͺ…μ‹œ β€” λ°”λ‘œ μ±„νŒ… λͺ¨λ“œ μ§„μž…).
11121
11128
  if (state.provider === 'ollama' && !state.model) {
11122
- log(C.dim(' Ollama λͺ¨λΈ λͺ©λ‘ 쑰회 쀑...'));
11129
+ // Ollama μ‚¬μš© κ°€λŠ₯ β†’ 첫 λͺ¨λΈ μžλ™ 선택 (μ‚¬μš©μž prompt μ—†μŒ)
11123
11130
  const r = await _ollamaListModels();
11124
11131
  if (r.ok && r.models.length) {
11125
- log(C.green(` μ‚¬μš© κ°€λŠ₯ λͺ¨λΈ ${r.models.length}개:`));
11126
- r.models.slice(0, 8).forEach((m, i) => log(` ${i + 1}) ${m}`));
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}`));
11132
+ state.model = process.env.LEERNESS_OLLAMA_MODEL || r.models[0];
11133
+ log(C.dim(` β–Έ Model: ${state.model} (Ollama ${r.models.length}개 catalog Β· Shift+Tab으둜 λ³€κ²½)`));
11131
11134
  } else {
11132
- log(C.yel(` ⚠ Ollama 미가동 λ˜λŠ” λͺ¨λΈ μ—†μŒ`));
11133
- // 1.9.164: Ollama μ‹€νŒ¨ μ‹œ λ‹€λ₯Έ ν™œμ„± CLI μ¦‰μ‹œ μ œμ•ˆ (UX κ°œμ„  β€” μ‚¬μš©μž λͺ…μ‹œ μš”μ²­)
11134
- try {
11135
- const readyCli = EXTERNAL_AGENTS.filter(a => a.id !== 'ollama')
11136
- .map(a => ({ def: a, status: _checkAgent(a) }))
11137
- .filter(x => x.status.status === 'ready');
11138
- if (readyCli.length) {
11139
- log('');
11140
- log(C.cy(` πŸ’‘ ν™œμ„± μ™ΈλΆ€ CLI ${readyCli.length}개 발견 β€” provider μ „ν™˜ κ°€λŠ₯:`));
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 {
11135
+ // Ollama 미가동 β†’ λΉ„-Ollama ν™œμ„± CLI κ°€ 있으면 μžλ™ μ „ν™˜, μ—†μœΌλ©΄ fallback ollama (warn)
11136
+ const readyCli = EXTERNAL_AGENTS.filter(a => a.id !== 'ollama')
11137
+ .map(a => ({ def: a, status: _checkAgent(a) }))
11138
+ .filter(x => x.status.status === 'ready');
11139
+ if (readyCli.length) {
11140
+ state.provider = readyCli[0].def.id;
11141
+ state.model = null;
11142
+ log(C.green(` β–Έ Ollama 미가동 β†’ ${state.provider} μžλ™ μ „ν™˜ (Tab으둜 λ‹€λ₯Έ provider μ „ν™˜ κ°€λŠ₯)`));
11143
+ } else {
11158
11144
  state.model = process.env.LEERNESS_OLLAMA_MODEL || 'llama3';
11159
- log(C.dim(` fallback: ${state.model}`));
11145
+ log(C.yel(` ⚠ Ollama 미가동 + ν™œμ„± CLI μ—†μŒ β€” fallback ${state.model} (μ‹€ 호좜 μ‹€νŒ¨ μ‹œ :quit λ˜λŠ” :provider)`));
11160
11146
  }
11161
11147
  }
11162
11148
  }
@@ -11658,7 +11644,7 @@ async function _agentRepl(root, opts) {
11658
11644
  async function agentCmd(root, taskArg) {
11659
11645
  root = absRoot(root || process.cwd());
11660
11646
  const task = (taskArg || arg('--task', '') || '').trim();
11661
- // 1.9.149: REPL μ§„μž… β€” 인자 μ—†κ±°λ‚˜ --interactive λͺ…μ‹œ (Hermes/OpenClaw μŠ€νƒ€μΌ)
11647
+ // 1.9.149+1.9.181: REPL μ§„μž… β€” 인자 μ—†κ±°λ‚˜ --interactive λͺ…μ‹œ (provider μžλ™ 선택)
11662
11648
  if (!task || has('--interactive') || has('--repl')) {
11663
11649
  if (process.stdin.isTTY && !has('--no-repl') && process.env.LEERNESS_NO_PROMPT !== '1') {
11664
11650
  const t0 = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.180",
3
+ "version": "1.9.181",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",