leerness 1.9.185 β†’ 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,112 @@
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
+
3
110
  ## 1.9.185 β€” 2026-05-21
4
111
 
5
112
  **πŸ”§ DEP0190 μžμ‹ process μ „νŒŒ fix + REPL stream 친절 진단 + Hermes UX 뢄석 보고 (μ‚¬μš©μž λͺ…μ‹œ).**
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.185-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v130-15%2F15-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-115-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-46_rounds-success)]() [![dep-child](https://img.shields.io/badge/DEP0190-λΆ€λͺ¨%2Bμžμ‹_μ „νŒŒ-success)]() [![repl-diag](https://img.shields.io/badge/REPL_μ‹€νŒ¨-친절_진단_μ•ˆλ‚΄-success)]() [![hermes-ux](https://img.shields.io/badge/Hermes_UX-뢄석_μ™„λ£Œ-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-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.185 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.186 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ πŸ”§ DEP0190 μžμ‹ μ „νŒŒΒ·REPL 친절 진단·Hermes UX 뢄석 β•‘
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.185';
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 처리).
@@ -10953,7 +10953,16 @@ async function _cliChatStream(root, provider, promptText, opts) {
10953
10953
  return { ok: false, error: `${provider} λΉ„ν™œμ„± (${status.status}) β€” .env μ—μ„œ ${agent.envFlag}=1 ν•„μš”`, provider };
10954
10954
  }
10955
10955
  let cmd, args;
10956
- 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
+ }
10957
10966
  else if (provider === 'codex') { cmd = 'codex'; args = ['exec', '--skip-git-repo-check', promptText]; }
10958
10967
  else if (provider === 'gemini') { cmd = 'gemini'; args = ['-p', promptText]; }
10959
10968
  else if (provider === 'copilot') { cmd = 'gh'; args = ['copilot', 'suggest', promptText]; }
@@ -11015,10 +11024,15 @@ async function _cliChatStream(root, provider, promptText, opts) {
11015
11024
  process.stdout.write(dim(`\n ── ${provider} stream ──\n`));
11016
11025
  let child;
11017
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 μ•ˆμ—μ„œλ§Œ μ‚¬μš©.
11018
11032
  child = cp.spawn(cmd, args, {
11019
11033
  cwd: process.cwd(),
11020
11034
  env: _scrubEnv({}),
11021
- shell: false,
11035
+ shell: true,
11022
11036
  stdio: ['ignore', 'pipe', 'pipe']
11023
11037
  });
11024
11038
  } catch (e) {
@@ -11070,7 +11084,8 @@ async function _cliChatStream(root, provider, promptText, opts) {
11070
11084
 
11071
11085
  child.stdout.on('data', chunk => {
11072
11086
  lastActivity = Date.now();
11073
- if (provider === 'claude') {
11087
+ // 1.9.186: claude default λŠ” plain --print β†’ JSON 라인 νŒŒμ‹± X. useStreamJson μ‹œμ—λ§Œ stream-json 처리.
11088
+ if (provider === 'claude' && useStreamJson) {
11074
11089
  handleClaudeStream(chunk);
11075
11090
  } else {
11076
11091
  stopSpinner();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.185",
3
+ "version": "1.9.186",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",