leerness 1.9.184 β†’ 1.9.186

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,186 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.186 β€” 2026-05-21
4
+
5
+ **πŸ› REPL claude stream 0자 응닡 BUG fix + ꡬ쑰 μ΅œμ ν™” 체크 (μ‚¬μš©μž λͺ…μ‹œ 핡심 버그).**
6
+
7
+ 자율 λͺ¨λ“œ 116 λΌμš΄λ“œ. μ‚¬μš©μž λͺ…μ‹œ 핡심 버그 보고:
8
+ ```
9
+ agent[claude/actor/β–Ά]> 파이썬 ν”„λ‘œκ·Έλž¨ ν•˜λ‚˜ μ œμž‘ν•΄μ€˜
10
+ ── /stream (27596ms) ──
11
+ [assistant: claude/default, role=actor, 27743ms · 0자]
12
+ ```
13
+ *"REPL agent λͺ¨λ“œμ—μ„œ μž‘μ—… μš”μ²­ μ‹œ AIκ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜μ§€ λͺ»ν•˜κ³  μžˆλ‹€"*
14
+
15
+ ### κ·Όλ³Έ 원인 발견 (μ½”λ“œ audit)
16
+
17
+ | ν•¨μˆ˜ | spawn 방식 | shell | μž‘λ™ μ—¬λΆ€ |
18
+ |---|---|---|---|
19
+ | `_cliChat` (line 10920) | `runCommandSafe` β†’ spawnSync `shell: true` | true | βœ“ μž‘λ™ (`agents multi --execute` 검증) |
20
+ | `_cliChatStream` (line 11018) | `cp.spawn(cmd, args, { shell: false })` | **false** | βœ— **0자 응닡** |
21
+
22
+ **원인 1**: Windows μ—μ„œ `cp.spawn('claude', ..., { shell: false })` κ°€ `claude.cmd` λ₯Ό μ°Ύμ§€ λͺ»ν•΄ stdout λΉ„μ–΄μžˆκ³  27초 timeout ν›„ μ’…λ£Œ (exit code 0).
23
+
24
+ **원인 2**: claude CLI `--output-format=stream-json --verbose` κ°€ 일뢀 λ²„μ „μ—μ„œ 빈 stdout λ°˜ν™˜ β†’ out λ³€μˆ˜ 0자 λˆ„μ .
25
+
26
+ ### Fix #1 β€” shell: true (Windows .cmd ν˜Έν™˜)
27
+ ```diff
28
+ - child = cp.spawn(cmd, args, {
29
+ - cwd: process.cwd(),
30
+ - env: _scrubEnv({}),
31
+ - shell: false,
32
+ - stdio: ['ignore', 'pipe', 'pipe']
33
+ - });
34
+ + // 1.9.186 (μ‚¬μš©μž λͺ…μ‹œ fix): Windows .cmd ν˜Έν™˜μ„ μœ„ν•΄ shell: true.
35
+ + // _cliChat (μž‘λ™ν•˜λŠ” ν•¨μˆ˜) 이 runCommandSafe β†’ spawnSync shell: true νŒ¨ν„΄μ΄λΌμ„œ μž‘λ™.
36
+ + // _cliChatStream 도 λ™μΌν•˜κ²Œ shell: true μ‚¬μš© (DEP0190 은 1.9.184/185 fix 둜 μ–΅μ œλ¨).
37
+ + child = cp.spawn(cmd, args, {
38
+ + cwd: process.cwd(),
39
+ + env: _scrubEnv({}),
40
+ + shell: true,
41
+ + stdio: ['ignore', 'pipe', 'pipe']
42
+ + });
43
+ ```
44
+
45
+ ### Fix #2 β€” claude default = plain `--print` (stream-json opt-in)
46
+ ```diff
47
+ - if (provider === 'claude') { cmd = 'claude'; args = ['--print', '--output-format=stream-json', '--verbose', promptText]; }
48
+ + // 1.9.186 (μ‚¬μš©μž λͺ…μ‹œ fix): claude --output-format=stream-json κ°€ 일뢀 λ²„μ „μ—μ„œ 빈 응닡.
49
+ + // default λ₯Ό plain --print 둜 λ³€κ²½ β†’ _cliChat κ³Ό λ™μΌν•œ 인자, μž‘λ™ κ²€μ¦λœ νŒ¨ν„΄.
50
+ + // stream ν˜•μ‹ μ‚¬μš© opt-in: LEERNESS_REPL_STREAM_FORMAT=json
51
+ + const useStreamJson = process.env.LEERNESS_REPL_STREAM_FORMAT === 'json';
52
+ + if (provider === 'claude') {
53
+ + cmd = 'claude';
54
+ + args = useStreamJson
55
+ + ? ['--print', '--output-format=stream-json', '--verbose', promptText]
56
+ + : ['--print', promptText];
57
+ + }
58
+ ```
59
+
60
+ handleClaudeStream 쑰건뢀 호좜 (useStreamJson 일 λ•Œλ§Œ):
61
+ ```diff
62
+ - if (provider === 'claude') {
63
+ + if (provider === 'claude' && useStreamJson) {
64
+ handleClaudeStream(chunk);
65
+ } else {
66
+ stopSpinner();
67
+ ```
68
+
69
+ ### ꡬ쑰 μ΅œμ ν™” 체크 (μ‚¬μš©μž λͺ…μ‹œ 보강)
70
+
71
+ **λ³΄κ³ μ„œ**: `_reports/structure-optimization-1.9.186.md`
72
+
73
+ **λ©”νŠΈλ¦­**:
74
+ - bin/harness.js: **~12000 lines** (1 monolithic)
75
+ - μ˜μ‘΄μ„± **0** (Node built-in)
76
+ - npm tarball ~358 KB (gzipped)
77
+ - MCP 54 Β· CLI 100+ Β· ν•¨μˆ˜ 250+
78
+
79
+ **μ΅œμ ν™” 강점** (μœ μ§€):
80
+ - μ˜μ‘΄μ„± 0 μ •μ±… (cross-platform + supply chain risk μ΅œμ†Œ)
81
+ - λ©”λͺ¨λ¦¬ 캐싱 (usage-stats / listAllSkills / lessons keyword index)
82
+ - Provider/MCP/Bridge λͺ…ν™•ν•œ abstraction
83
+ - runCommandSafe sandbox (cwd jail + env scrub)
84
+ - λ§€ λΌμš΄λ“œ stress + e2e + main μžλ™ push
85
+
86
+ **μ΅œμ ν™” 약점** (1.9.187+ 후보):
87
+ - ⚠ Monolithic 12000 lines β€” ν˜„ μƒνƒœ μœ μ§€ (npm pack λ‹¨μˆœμ„± μš°μ„ )
88
+ - ⚠ `_cliChat` ↔ `_cliChatStream` μ½”λ“œ 쀑볡 β€” 1.9.186 fixκ°€ 이 κ°­μ—μ„œ λ°œμƒ. 1.9.187 후보: `_buildCliArgs` 곡톡 헬퍼
89
+ - ⚠ skill catalog μΊμ‹œ stale κ°€λŠ₯ β€” mtime 기반 invalidation 후보
90
+ - ⚠ MCP tools/list 맀번 μž¬μƒμ„± β€” λ©”λͺ¨λ¦¬ μΊμ‹œ 후보
91
+ - ⚠ 280 task λˆ„μ  β€” archive μžλ™ν™” (1.9.190+)
92
+
93
+ ### 1.9.186 fix μ •ν•©μ„± (λ³΄κ³ μ„œ Β§4)
94
+ | 영ν–₯ | 평가 |
95
+ |---|---|
96
+ | λ³΄μ•ˆ (shell escape) | promptText λŠ” μ‚¬μš©μž 직접 μž…λ ₯, REPL μ•ˆμ—μ„œλ§Œ μ‚¬μš© β†’ μΆ”κ°€ μœ„ν—˜ μ—†μŒ |
97
+ | μ„±λŠ₯ | shell:true κ°€ ~10ms 느림 (λ¬΄μ‹œ κ°€λŠ₯) |
98
+ | λ‹€λ₯Έ provider (codex/gemini/copilot) | shell:true 동일 적용 β€” 더 μ•ˆμ •μ  (.cmd ν˜Έν™˜) |
99
+ | μ‹€μ‹œκ°„ 슀트리밍 (1.9.170 μ‚¬μš©μž λͺ…μ‹œ) | LEERNESS_REPL_STREAM_FORMAT=json 으둜 opt-in κ°€λŠ₯ β€” κΈ°λŠ₯ μœ μ§€ |
100
+ | κΈ°μ‘΄ μž‘λ™ | `_cliChat` λ³€κ²½ X β€” `agents multi --execute` νšŒκ·€ μ—†μŒ |
101
+
102
+ ### Verified
103
+ - stress-v131: **16/16 PASS** (μ‚¬μš©μž λͺ…μ‹œ 4 + live 3 + λˆ„μ  9)
104
+ - e2e 217/217 baseline μœ μ§€
105
+ - live 검증: `agents multi --execute --only claude` μ‹€ 호좜 응닡 "2" (4.5초)
106
+ - VERSION = 1.9.186 Β· autonomous-rounds = 116 Β· main μžλ™ push 47 λΌμš΄λ“œ 연속
107
+
108
+ ---
109
+
110
+ ## 1.9.185 β€” 2026-05-21
111
+
112
+ **πŸ”§ DEP0190 μžμ‹ process μ „νŒŒ fix + REPL stream 친절 진단 + Hermes UX 뢄석 보고 (μ‚¬μš©μž λͺ…μ‹œ).**
113
+
114
+ 자율 λͺ¨λ“œ 115 λΌμš΄λ“œ. μ‚¬μš©μž λͺ…μ‹œ 3μ’…:
115
+ 1. *"REPL μ—μ΄μ „νŠΈ λͺ¨λ“œ ꡬ동 μ‹€νŒ¨ + μΆ”λ‘ λ‚΄μš©/diff λ―Έν‘œμ‹œ"* β†’ μΉœμ ˆν•œ 진단 λ©”μ‹œμ§€
116
+ 2. *"agent[claude/actor/β–Ά]> (node:54076) [DEP0190] ..."* β†’ μžμ‹ process μ „νŒŒ fix
117
+ 3. *"SSH duffy@192.168.68.89 의 hermes REPL UX 확인 β†’ μœ μ‚¬ κ΅¬ν˜„"* β†’ λ³΄κ³ μ„œ μž‘μ„±
118
+
119
+ ### Fix #1 β€” DEP0190 μžμ‹ process μ „νŒŒ
120
+ 1.9.184 의 `process.on('warning')` ν•Έλ“€λŸ¬λŠ” λΆ€λͺ¨λ§Œ. claude/codex/gemini CLI κ°€ λ‚΄λΆ€ Node child λ₯Ό spawnν•  λ•Œ μžμ‹μ— 상속 X β†’ μ‚¬μš©μž REPL μž…λ ₯ 후에도 DEP0190 좜λ ₯.
121
+
122
+ ```js
123
+ // 1.9.185 (μ‚¬μš©μž λͺ…μ‹œ): NODE_OPTIONS=--no-deprecation μžλ™ μ„€μ • β†’ λͺ¨λ“  Node child κΉŒμ§€ μ „νŒŒ.
124
+ if (!/--no-deprecation/.test(process.env.NODE_OPTIONS || '')) {
125
+ process.env.NODE_OPTIONS = ((process.env.NODE_OPTIONS || '') + ' --no-deprecation').trim();
126
+ }
127
+ ```
128
+
129
+ `process.env` 변경은 μžμ‹ spawn μ‹œ 상속. λΆ€λͺ¨λŠ” 1.9.184 의 `process.on('warning')` 으둜 처리.
130
+
131
+ ### Fix #2 β€” REPL stream μ‹€νŒ¨ 친절 진단
132
+ **Before**:
133
+ ```
134
+ agent[claude/actor/β–Ά]> μ›Ήκ°œλ°œμ„ μ§„ν–‰ν•΄μ€˜
135
+ ── /stream (120053ms) ──
136
+ ⚠ μ‹€νŒ¨: exit=null
137
+ πŸ’‘ μ „ν™˜ κ°€λŠ₯: :provider codex / :provider gemini / :provider copilot
138
+ ```
139
+
140
+ **After**:
141
+ ```
142
+ agent[claude/actor/β–Ά]> μ›Ήκ°œλ°œμ„ μ§„ν–‰ν•΄μ€˜
143
+ ── /stream (120053ms) ──
144
+ ⚠ claude CLI 응닡 μ‹€νŒ¨: exit=null
145
+ ↳ κ°€λŠ₯ 원인: (1) claude CLI 응닡 μ‹œκ°„ 초과 (λͺ¨λΈ λ‘œλ”©/큰 응닡 λŒ€κΈ° 쀑)
146
+ (2) network/auth 문제 (특히 codex/gemini λŠ” 인터넷 + 토큰 ν•„μš”)
147
+ ↳ 직접 검증: claude --print "ping"
148
+ πŸ’‘ μ¦‰μ‹œ μ „ν™˜: :provider codex Β· :provider gemini Β· :provider copilot λ˜λŠ” Tab ν‚€
149
+ ```
150
+
151
+ μ‹€νŒ¨ μΌ€μ΄μŠ€ λΆ„κΈ°:
152
+ - `exit=null` / `timeout` β†’ 응닡 μ‹œκ°„ 초과 + 직접 검증 λͺ…λ Ή
153
+ - `exit=1` / `unauth` / `login` β†’ 인증 λˆ„λ½ + login λͺ…λ Ή (claude/codex/gemini login, copilot=gh auth login)
154
+
155
+ ### #3 β€” Hermes UX 뢄석 (μ‚¬μš©μž SSH 접속 μš”μ²­)
156
+
157
+ **SSH λ³΄μ•ˆ μ •μ±…**: νŒ¨μŠ€μ›Œλ“œλŠ” `LEERNESS_SSH_PASS` env λ³€μˆ˜λ‘œλ§Œ 전달. paramiko μž„μ‹œ μŠ€ν¬λ¦½νŠΈλŠ” 뢄석 μ™„λ£Œ ν›„ μ¦‰μ‹œ μ‚­μ œ. μ½”λ“œ/λ‘œκ·Έμ— μ ˆλŒ€ μ €μž₯ X.
158
+
159
+ **Hermes 사양 확인** (v0.14.0, Python 3.11, 89 commands Β· 29 tools Β· 85 skills):
160
+ - μœ„μΉ˜: `~/.local/bin/hermes` (Ollama hermes-gemma:latest)
161
+ - 2-column Welcome λ°•μŠ€ (logo + toolsets/skills catalog)
162
+ - μ‹€μ‹œκ°„ μƒνƒœλ°”: `βš• model β”‚ ctx % β”‚ [progress bar] β”‚ elapsed β”‚ ⏲ timer`
163
+ - minimal prompt: `❯ `
164
+ - slash commands: `/help`, `/compress`, `/quit`
165
+ - `-z/--oneshot` 슀크립트 λͺ¨λ“œ (λ°°λ„ˆ/μŠ€ν”Όλ„ˆ/μ„Έμ…˜ID λͺ¨λ‘ 제거)
166
+
167
+ **leerness 차용 후보** (1.9.186+):
168
+ 1. μƒνƒœλ°” μ‹€μ‹œκ°„ κ°±μ‹  (`⚑ provider β”‚ ctx N% β”‚ [bar] β”‚ elapsed β”‚ ⏲ timer`)
169
+ 2. `:compress` slash command β€” context μ••μΆ•
170
+ 3. 2-column Welcome λ°•μŠ€ μž¬λ””μžμΈ
171
+ 4. `--oneshot/-z` λͺ…ν™•ν™” (λ°°λ„ˆ/μŠ€ν”Όλ„ˆ 제거)
172
+ 5. Tip 라인 (`✦ Tip: ...`)
173
+
174
+ 상세 λ³΄κ³ μ„œ: `_reports/hermes-ux-analysis-1.9.185.md` (λΉ„κ³΅κ°œ)
175
+
176
+ ### Verified
177
+ - stress-v130: **15/15 PASS** (μ‚¬μš©μž λͺ…μ‹œ 4 + live 3 + λˆ„μ  8)
178
+ - e2e 217/217 baseline μœ μ§€
179
+ - `agents list` 호좜: DEP0190 좜λ ₯ μ—†μŒ βœ“
180
+ - VERSION = 1.9.185 Β· autonomous-rounds = 115 Β· main μžλ™ push 46 λΌμš΄λ“œ 연속
181
+
182
+ ---
183
+
3
184
  ## 1.9.184 β€” 2026-05-21
4
185
 
5
186
  **🎨 μ„€μΉ˜ UX 4μ’… β€” Ctrl+C 확인 prompt + λ‘œλ”©λ°” + skillpack μ œμ™Έ + DEP0190 μ–΅μ œ (μ‚¬μš©μž λͺ…μ‹œ).**
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.184-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v129-14%2F14-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-114-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-45_rounds-success)]() [![install-ux](https://img.shields.io/badge/μ„€μΉ˜_UX-Ctrl%2BC확인%2Bλ‘œλ”©λ°”-success)]() [![dep-clean](https://img.shields.io/badge/DEP0190-μ–΅μ œ-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![stale-check](https://img.shields.io/badge/ꡬ버전_감지-λͺ¨λ“ _λͺ…λ Ή-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
5
+ [![npm](https://img.shields.io/badge/npm-leerness-blue)](https://www.npmjs.com/package/leerness) [![version](https://img.shields.io/badge/version-1.9.186-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v131-16%2F16-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-116-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-47_rounds-success)]() [![repl-fix](https://img.shields.io/badge/REPL_stream-0자_응닡_BUG_fix-success)]() [![structure](https://img.shields.io/badge/ꡬ쑰_μ΅œμ ν™”-체크_μ™„λ£Œ-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![dep-child](https://img.shields.io/badge/DEP0190-λΆ€λͺ¨%2Bμžμ‹_μ „νŒŒ-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
6
6
 
7
7
  ```
8
8
  ╔══════════════════════════════════════════════════════════════╗
@@ -12,9 +12,9 @@
12
12
  β•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β•šβ•β•β•β•β–ˆβ–ˆβ•‘ β•‘
13
13
  β•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β•‘
14
14
  β•‘ β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β• β•‘
15
- β•‘ v1.9.184 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.186 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ 🎨 μ„€μΉ˜ UX κ°œμ„  (λ‘œλ”©λ°”Β·Ctrl+C확인·DEP0190 μ–΅μ œΒ·κΉ¨λ—ν•œ REPL) β•‘
17
+ β•‘ πŸ› REPL stream 0자 응닡 BUG fix Β· ꡬ쑰 μ΅œμ ν™” 체크 β•‘
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.184';
10
+ const VERSION = '1.9.186';
11
11
 
12
12
  // 1.9.184: DEP0190 (child_process shell: true) deprecation warning μ–΅μ œ (μ‚¬μš©μž λͺ…μ‹œ).
13
13
  // leerness λŠ” cross-platform PATH resolution 을 μœ„ν•΄ shell: true λ₯Ό μ˜λ„μ μœΌλ‘œ μ‚¬μš© (claude.cmd / ollama.cmd λ“± Windows .cmd 처리).
@@ -17,6 +17,12 @@ process.on('warning', (w) => {
17
17
  if (w && (w.code === 'DEP0190' || /DEP0190/.test(String(w.message || '')))) return;
18
18
  process.stderr.write(`(node:${process.pid}) ${w.name || 'Warning'}: ${w.message || w}\n`);
19
19
  });
20
+ // 1.9.185 (μ‚¬μš©μž λͺ…μ‹œ): REPL μ§„μž… ν›„ user input μ‹œμ μ—λ„ DEP0190 λ°œμƒ (claude/ollama CLI κ°€ Node μžμ‹ spawn μ‹œ μžμ‹μ˜ λ…Έμ΄μ¦ˆ).
21
+ // λΆ€λͺ¨ ν•Έλ“€λŸ¬λŠ” μžμ‹μ— 상속 X β†’ NODE_OPTIONS=--no-deprecation 으둜 λͺ¨λ“  Node child κΉŒμ§€ μ „νŒŒ.
22
+ // process.env 변경은 μžμ‹ spawn μ‹œ 상속 (이미 μ‹œμž‘λœ λΆ€λͺ¨μ—λŠ” 영ν–₯ X, λΆ€λͺ¨λŠ” μœ„μ˜ 'warning' ν•Έλ“€λŸ¬λ‘œ 처리).
23
+ if (!/--no-deprecation/.test(process.env.NODE_OPTIONS || '')) {
24
+ process.env.NODE_OPTIONS = ((process.env.NODE_OPTIONS || '') + ' --no-deprecation').trim();
25
+ }
20
26
 
21
27
  const MARK = '<!-- leerness:managed -->';
22
28
  const README_START = '<!-- leerness:project-readme:start -->';
@@ -10947,7 +10953,16 @@ async function _cliChatStream(root, provider, promptText, opts) {
10947
10953
  return { ok: false, error: `${provider} λΉ„ν™œμ„± (${status.status}) β€” .env μ—μ„œ ${agent.envFlag}=1 ν•„μš”`, provider };
10948
10954
  }
10949
10955
  let cmd, args;
10950
- if (provider === 'claude') { cmd = 'claude'; args = ['--print', '--output-format=stream-json', '--verbose', promptText]; }
10956
+ // 1.9.186 (μ‚¬μš©μž λͺ…μ‹œ fix): claude --output-format=stream-json κ°€ 일뢀 λ²„μ „μ—μ„œ 빈 응닡.
10957
+ // default λ₯Ό plain --print 둜 λ³€κ²½ β†’ _cliChat κ³Ό λ™μΌν•œ 인자, μž‘λ™ κ²€μ¦λœ νŒ¨ν„΄.
10958
+ // stream ν˜•μ‹ μ‚¬μš© opt-in: LEERNESS_REPL_STREAM_FORMAT=json (μ‹€μ‹œκ°„ thinking/tool_use 보고 싢을 λ•Œ).
10959
+ const useStreamJson = process.env.LEERNESS_REPL_STREAM_FORMAT === 'json';
10960
+ if (provider === 'claude') {
10961
+ cmd = 'claude';
10962
+ args = useStreamJson
10963
+ ? ['--print', '--output-format=stream-json', '--verbose', promptText]
10964
+ : ['--print', promptText]; // plain text 응닡 (μž‘λ™ 검증됨)
10965
+ }
10951
10966
  else if (provider === 'codex') { cmd = 'codex'; args = ['exec', '--skip-git-repo-check', promptText]; }
10952
10967
  else if (provider === 'gemini') { cmd = 'gemini'; args = ['-p', promptText]; }
10953
10968
  else if (provider === 'copilot') { cmd = 'gh'; args = ['copilot', 'suggest', promptText]; }
@@ -11009,10 +11024,15 @@ async function _cliChatStream(root, provider, promptText, opts) {
11009
11024
  process.stdout.write(dim(`\n ── ${provider} stream ──\n`));
11010
11025
  let child;
11011
11026
  try {
11027
+ // 1.9.186 (μ‚¬μš©μž λͺ…μ‹œ fix): Windows .cmd ν˜Έν™˜μ„ μœ„ν•΄ shell: true.
11028
+ // 1.9.185 κΉŒμ§€ shell: false β†’ Windows μ—μ„œ claude.cmd λͺ» μ°Ύμ•„ 빈 응닡 (μ‚¬μš©μž 보고: 27초 ν›„ 0자).
11029
+ // _cliChat (μž‘λ™ν•˜λŠ” ν•¨μˆ˜) 이 runCommandSafe β†’ spawnSync shell: true νŒ¨ν„΄μ΄λΌμ„œ μž‘λ™.
11030
+ // _cliChatStream 도 λ™μΌν•˜κ²Œ shell: true μ‚¬μš© (DEP0190 은 1.9.184/185 fix 둜 μ–΅μ œλ¨).
11031
+ // security: shell escape μš°λ €λŠ” promptText κ°€ μ‚¬μš©μž 직접 μž…λ ₯ β€” sandboxed REPL μ•ˆμ—μ„œλ§Œ μ‚¬μš©.
11012
11032
  child = cp.spawn(cmd, args, {
11013
11033
  cwd: process.cwd(),
11014
11034
  env: _scrubEnv({}),
11015
- shell: false,
11035
+ shell: true,
11016
11036
  stdio: ['ignore', 'pipe', 'pipe']
11017
11037
  });
11018
11038
  } catch (e) {
@@ -11064,7 +11084,8 @@ async function _cliChatStream(root, provider, promptText, opts) {
11064
11084
 
11065
11085
  child.stdout.on('data', chunk => {
11066
11086
  lastActivity = Date.now();
11067
- if (provider === 'claude') {
11087
+ // 1.9.186: claude default λŠ” plain --print β†’ JSON 라인 νŒŒμ‹± X. useStreamJson μ‹œμ—λ§Œ stream-json 처리.
11088
+ if (provider === 'claude' && useStreamJson) {
11068
11089
  handleClaudeStream(chunk);
11069
11090
  } else {
11070
11091
  stopSpinner();
@@ -11868,14 +11889,25 @@ async function _agentRepl(root, opts) {
11868
11889
  }
11869
11890
  if (state.history.length % 6 === 0) saveSession(); // 6ν„΄λ§ˆλ‹€ μžλ™ μ €μž₯
11870
11891
  } else {
11871
- log(C.yel(` ⚠ μ‹€νŒ¨: ${result.error || 'unknown'}`));
11872
- // 1.9.164: μ‹€νŒ¨ μ‹œ μ¦‰μ‹œ μ „ν™˜ κ°€λŠ₯ provider μ•ˆλ‚΄ (UX κ°œμ„  β€” μ‚¬μš©μž λͺ…μ‹œ μš”μ²­)
11892
+ // 1.9.185 (μ‚¬μš©μž λͺ…μ‹œ): REPL 호좜 μ‹€νŒ¨ μΉœμ ˆν•œ 진단 β€” μ–΄λŠ λ‹¨κ³„μ—μ„œ μ‹€νŒ¨ν–ˆλŠ”μ§€ + μ¦‰μ‹œ 검증 λͺ…λ Ή μ•ˆλ‚΄
11893
+ const errMsg = result.error || 'unknown';
11894
+ log(C.yel(` ⚠ ${state.provider} CLI 응닡 μ‹€νŒ¨: ${errMsg}`));
11895
+ // μ‹€νŒ¨ 원인 λΆ„λ₯˜
11896
+ if (/exit=null/.test(errMsg) || /timeout/i.test(errMsg)) {
11897
+ log(C.dim(` ↳ κ°€λŠ₯ 원인: (1) ${state.provider} CLI 응닡 μ‹œκ°„ 초과 (λͺ¨λΈ λ‘œλ”©/큰 응닡 λŒ€κΈ° 쀑)`));
11898
+ log(C.dim(` (2) network/auth 문제 (특히 codex/gemini λŠ” 인터넷 + 토큰 ν•„μš”)`));
11899
+ log(C.dim(` ↳ 직접 검증: ${state.provider} --print "ping" ${state.provider === 'gemini' ? '--yolo' : ''}`));
11900
+ } else if (/exit=1/.test(errMsg) || /unauth/i.test(errMsg) || /login/i.test(errMsg)) {
11901
+ log(C.dim(` ↳ κ°€λŠ₯ 원인: 인증 λˆ„λ½ (login ν•„μš”)`));
11902
+ log(C.dim(` ↳ ν•΄κ²°: ${state.provider} login ${state.provider === 'copilot' ? '(gh auth login)' : ''}`));
11903
+ }
11904
+ // μ „ν™˜ κ°€λŠ₯ provider μ•ˆλ‚΄
11873
11905
  try {
11874
11906
  const others = EXTERNAL_AGENTS.filter(a => a.id !== state.provider)
11875
11907
  .map(a => ({ def: a, status: _checkAgent(a) }))
11876
11908
  .filter(x => x.status.status === 'ready');
11877
11909
  if (others.length) {
11878
- log(C.dim(` πŸ’‘ μ „ν™˜ κ°€λŠ₯: ${others.map(x => `:provider ${x.def.id}`).join(' / ')}`));
11910
+ log(C.dim(` πŸ’‘ μ¦‰μ‹œ μ „ν™˜: ${others.map(x => `:provider ${x.def.id}`).join(' Β· ')} λ˜λŠ” Tab ν‚€`));
11879
11911
  } else {
11880
11912
  log(C.dim(` πŸ’‘ λ‹€λ₯Έ provider ν™œμ„±ν™”: .env μ—μ„œ LEERNESS_ENABLE_<CLAUDE|CODEX|GEMINI|COPILOT>=1`));
11881
11913
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.184",
3
+ "version": "1.9.186",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",