leerness 1.9.173 β†’ 1.9.175

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,125 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.175 β€” 2026-05-21
4
+
5
+ **πŸŒ‰ REPL Bridge Slash 3μ’… β€” `:web` / `:pc` / `:lsp` μ¦‰μ‹œ 호좜.**
6
+
7
+ 자율 λͺ¨λ“œ 105 λΌμš΄λ“œ. 1.9.165~167 Bridge 3쒅이 1.9.168 MCP둜 μ™ΈλΆ€ AI 직접 호좜 κ°€λŠ₯. **1.9.175: REPL μ•ˆμ—μ„œλ„ 직접 호좜 κ°€λŠ₯** β€” μ‚¬μš©μž + AI κ°€ 같은 REPL μ„Έμ…˜μ—μ„œ μ½”λ“œ 뢄석/μ›Ή/PC μžλ™ν™” μ¦‰μ‹œ μ‚¬μš©.
8
+
9
+ ### μ‚¬μš© μ˜ˆμ‹œ
10
+ ```
11
+ agent[claude/actor/β–Ά]> :lsp symbols src/api.ts
12
+ β†’ leerness lsp symbols src/api.ts
13
+ # leerness lsp symbols (1.9.173 λ‹€κ΅­μ–΄)
14
+ file: src/api.ts Β· lang: javascript
15
+ mode: typescript-compiler Β· 24 symbols Β· 12ms
16
+ 3:function parseRequest
17
+ 8:class User
18
+ ...
19
+ βœ“ :lsp symbols μ™„λ£Œ (132ms)
20
+
21
+ agent[claude/actor/β–Ά]> :web screenshot https://example.com --out shot.png
22
+ β†’ leerness web screenshot https://example.com --out shot.png
23
+ βœ“ screenshot saved: shot.png Β· 1842ms
24
+ βœ“ :web screenshot μ™„λ£Œ (2014ms)
25
+
26
+ agent[claude/actor/β–Ά]> :pc click 800 400
27
+ ⚠ :pc click 은 permissions=full ν•„μš” (ν˜„μž¬: basic)
28
+ :permissions full 둜 μ¦‰μ‹œ λ³€κ²½ κ°€λŠ₯ (1.9.174)
29
+
30
+ agent[claude/actor/β–Ά]> :permissions full
31
+ βœ“ κΆŒν•œ λͺ¨λ“œ λ³€κ²½: full
32
+ agent[claude/actor/β–Ά]> :pc click 800 400
33
+ βœ“ click (800, 400) β€” 23ms
34
+ βœ“ :pc click μ™„λ£Œ (35ms)
35
+ ```
36
+
37
+ ### 톡합 흐름 β€” μ‚¬μš©μž λͺ…μ‹œ 4 λΌμš΄λ“œ λˆ„μ 
38
+ | λΌμš΄λ“œ | κ°•ν™” |
39
+ |---|---|
40
+ | 1.9.170 | Tab/Shift+Tab cycle + μ‹€μ‹œκ°„ 슀트리밍 |
41
+ | 1.9.172 | 슀트리밍 spinner + tool_use + diff 색깔 |
42
+ | 1.9.174 | install κΆŒν•œ prompt 제거 + REPL `:permissions` λ³€κ²½ |
43
+ | **1.9.175** | **REPL `:web` / `:pc` / `:lsp` slash 3μ’… μ¦‰μ‹œ 호좜** |
44
+
45
+ β†’ **REPL μ•ˆμ—μ„œ leerness 의 λͺ¨λ“  capability μ‚¬μš© κ°€λŠ₯** (AI λŒ€ν™” + μ½”λ“œ 뢄석 + μ›Ή + PC + κΆŒν•œ λ³€κ²½, ν•œ μ„Έμ…˜).
46
+
47
+ ### μœ„ν—˜ sub 사전 κΆŒν•œ 검사
48
+ `:pc click/type/screenshot` μ‹œ `permissions !== 'full'` 이면 μ¦‰μ‹œ κ²½κ³  + λ³€κ²½ μ•ˆλ‚΄ (1.9.174 `:permissions full` 연동).
49
+
50
+ ### κ΅¬ν˜„
51
+ - `op === 'web' || op === 'pc' || op === 'lsp'` ν•Έλ“€λŸ¬ μΆ”κ°€ (Memory slash λΆ„κΈ° 직전)
52
+ - `subParts = rest.length ? rest : ['check']` (인자 μ—†μœΌλ©΄ check κΈ°λ³Έ)
53
+ - `runCommandSafe(process.execPath, [__filename, ...cliArgs, '--path', root], ...)` 톡합 호좜
54
+ - observability: `kind: 'agent_repl_slash'`, `label: 'repl-<op>'`
55
+ - stdout 50쀄 κΉŒμ§€ ν‘œμ‹œ (Memory slash 30쀄보닀 ν™•μž₯ β€” symbol/diff 좜λ ₯ μš©λ„)
56
+
57
+ ### Verified
58
+ - e2e 217/217 baseline μœ μ§€
59
+ - stress-v120: **17/17** (slash ν•Έλ“€λŸ¬ 4 + :pc κΆŒν•œ 사전 검사 2 + :help/ν™˜μ˜ 5 + λˆ„μ  νšŒκ·€ 6)
60
+ - VERSION = 1.9.175 / autonomous-rounds = 105 / main μžλ™ push 36 λΌμš΄λ“œ 연속
61
+
62
+ ---
63
+
64
+ ## 1.9.174 β€” 2026-05-21
65
+
66
+ **πŸ” μ‚¬μš©μž λͺ…μ‹œ β€” install κΆŒν•œ prompt 제거 + REPL `:permissions` μ¦‰μ‹œ λ³€κ²½.**
67
+
68
+ 자율 λͺ¨λ“œ 104 λΌμš΄λ“œ. μ‚¬μš©μž λͺ…μ‹œ: *"κΆŒν•œ μ„€μ • 문항은 μ œκ±°ν•˜κ³  REPL λͺ¨λ“œμ—μ„œ κ°„νŽΈν•˜κ²Œ κΆŒν•œ λ³€κ²½ν•  수 μžˆλ„λ‘"*.
69
+
70
+ ### 1. Install κΆŒν•œ prompt 제거
71
+ 이전 (1.9.146): install μ‹œ 3-tier κΆŒν•œ λͺ¨λ“œ 선택 prompt (basic/extended/full).
72
+ **문제**: μ‚¬μš©μž κ²½ν—˜ λ³΅μž‘λ„ 증가 + 잘λͺ»λœ 선택 (full) μ‹œ μœ„ν—˜.
73
+
74
+ **1.9.174**:
75
+ - install μ‹œ κΆŒν•œ **항상 `basic` μžλ™ 적용** (μ•ˆμ „ default).
76
+ - prompt μ½”λ“œ (resolveInstallOptions μ•ˆ κΆŒν•œ λͺ¨λ“œ _selectOne 블둝) μ™„μ „ 제거.
77
+ - μ•ˆλ‚΄ 라인: `Agent κΆŒν•œ λͺ¨λ“œ: basic (1.9.174 β€” REPLμ—μ„œ :permissions extended|full 둜 μ¦‰μ‹œ λ³€κ²½ κ°€λŠ₯)`.
78
+
79
+ ### 2. REPL `:permissions` μ¦‰μ‹œ λ³€κ²½ κ°€λŠ₯
80
+ 이전 (1.9.146~1.9.173): `:permissions` 메타 λͺ…령은 list 만 (쑰회).
81
+
82
+ **1.9.174**:
83
+ ```
84
+ agent[claude/actor/β–Ά]> :permissions
85
+ πŸ” ν˜„μž¬ κΆŒν•œ λͺ¨λ“œ: basic
86
+
87
+ λ³€κ²½:
88
+ :permissions basic β€” μ•ˆμ „ (.harness 만 μ“°κΈ°, ꢌμž₯)
89
+ :permissions extended β€” ν”„λ‘œμ νŠΈ 폴더 + shell allowlist
90
+ :permissions full β€” ⚠ 전체 (마우슀/ν‚€λ³΄λ“œ/μ›Ή, IDE 톡합 μ‹œλ§Œ)
91
+
92
+ μ„ΈλΆ€ κΆŒν•œ (mouse/keyboard/browser/admin):
93
+ mouse: βœ— κ±°λΆ€
94
+ keyboard: βœ— κ±°λΆ€
95
+ browser: βœ— κ±°λΆ€
96
+ admin: βœ— κ±°λΆ€
97
+
98
+ agent[claude/actor/β–Ά]> :permissions extended
99
+ βœ“ κΆŒν•œ λͺ¨λ“œ λ³€κ²½: extended (μ¦‰μ‹œ 적용 β€” λ‹€μŒ λͺ…λ ΉλΆ€ν„°)
100
+
101
+ agent[claude/actor/β–Ά]> :permissions full
102
+ βœ“ κΆŒν•œ λͺ¨λ“œ λ³€κ²½: full (μ¦‰μ‹œ 적용 β€” λ‹€μŒ λͺ…λ ΉλΆ€ν„°)
103
+ ⚠ full λͺ¨λ“œ β€” 마우슀/ν‚€λ³΄λ“œ/μ›Ή/κ΄€λ¦¬μž 전체 ν—ˆμš©. IDE 톡합 μ™Έ ν™˜κ²½μ—μ„œλŠ” μœ„ν—˜.
104
+ ```
105
+
106
+ - 인자 μ—†μŒ β†’ ν˜„μž¬ λͺ¨λ“œ + μ„ΈλΆ€ κΆŒν•œ (mouse/keyboard/browser/admin) ν‘œμ‹œ + λ³€κ²½ μ˜΅μ…˜ μ•ˆλ‚΄
107
+ - `:permissions basic|extended|full` β†’ μ¦‰μ‹œ λ³€κ²½ (`permissionsSetCmd` 호좜)
108
+ - `:perm` alias μΆ”κ°€ (단좕)
109
+ - `full` λͺ¨λ“œ λ³€κ²½ μ‹œ ⚠ λͺ…μ‹œμ  κ²½κ³ 
110
+ - 잘λͺ»λœ λͺ¨λ“œ β†’ μΉœμ ˆν•œ μ•ˆλ‚΄ (`잘λͺ»λœ λͺ¨λ“œ: xyz (basic | extended | full)`)
111
+
112
+ ### ν˜Έν™˜μ„±
113
+ - CLI λͺ…λ Ή `leerness permissions list|set` κ·ΈλŒ€λ‘œ μœ μ§€ (1.9.146 ν˜Έν™˜).
114
+ - κΈ°μ‘΄ `.harness/agent-permissions.json` ν˜•μ‹ κ·ΈλŒ€λ‘œ (mode + 4-tier μ„ΈλΆ€).
115
+
116
+ ### Verified
117
+ - e2e 217/217 baseline μœ μ§€
118
+ - stress-v119: **20/20** (install 제거 5 + REPL :permissions 7 + CLI ν˜Έν™˜ 2 + λˆ„μ  νšŒκ·€ 6)
119
+ - VERSION = 1.9.174 / autonomous-rounds = 104 / main μžλ™ push 35 λΌμš΄λ“œ 연속
120
+
121
+ ---
122
+
3
123
  ## 1.9.173 β€” 2026-05-21
4
124
 
5
125
  **🌐 LSP μ–΄λŒ‘ν„° λ‹€κ΅­μ–΄ ν™•μž₯ β€” JavaScript + Python + Go + Rust + Java (5개 μ–Έμ–΄ regex fallback).**
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.173-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v118-15%2F15-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-53-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-103-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-34_rounds-success)]() [![lsp-multi](https://img.shields.io/badge/LSP_λ‹€κ΅­μ–΄-JS%2FPython%2FGo%2FRust%2FJava-success)]() [![stream-ux](https://img.shields.io/badge/슀트리밍-spinner%2Btool__use%2Bdiff_색깔-success)]() [![mcp-bridge](https://img.shields.io/badge/MCP_bridge-web%2Fpc%2Flsp_λ…ΈμΆœ-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.175-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v120-17%2F17-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-53-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-105-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-36_rounds-success)]() [![repl-slash](https://img.shields.io/badge/REPL_slash-:web%2F:pc%2F:lsp_μ¦‰μ‹œ_호좜-success)]() [![repl-perm](https://img.shields.io/badge/REPL_:permissions-μ¦‰μ‹œ_λ³€κ²½-success)]() [![lsp-multi](https://img.shields.io/badge/LSP_λ‹€κ΅­μ–΄-JS%2FPython%2FGo%2FRust%2FJava-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.173 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.175 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ 🌐 LSP λ‹€κ΅­μ–΄ 5μ’… (JS/Python/Go/Rust/Java regex fallback) β•‘
17
+ β•‘ πŸŒ‰ REPL :web/:pc/:lsp slash β€” Bridge 3μ’… μ¦‰μ‹œ 호좜 β•‘
18
18
  β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
19
19
  ```
20
20
 
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.173';
9
+ const VERSION = '1.9.175';
10
10
  const MARK = '<!-- leerness:managed -->';
11
11
  const README_START = '<!-- leerness:project-readme:start -->';
12
12
  const README_END = '<!-- leerness:project-readme:end -->';
@@ -739,25 +739,11 @@ async function resolveInstallOptions(root, opts = {}) {
739
739
  }
740
740
  }
741
741
  }
742
- // 1.9.146: κΆŒν•œ λͺ¨λ“œ (μ‚¬μš©μž λͺ…μ‹œ μš”μ²­ #5 β€” agent IDE λͺ¨λ“œ 사전 prompt)
743
- let permissionMode = null;
744
- if (shouldAsk && !opts._skipPermissionsPrompt) {
745
- if (useInteractive) {
746
- const pOpt = await _selectOne('agent κΆŒν•œ λͺ¨λ“œ (leerness agent μ‚¬μš© μ‹œ 적용)', [
747
- { label: 'basic (μ•ˆμ „) β€” 읽기/μ“°κΈ° .harness/ 만', description: 'ꢌμž₯ β€” νŒŒμΌμ‹œμŠ€ν…œ/λ„€νŠΈμ›Œν¬ κ±°λΆ€, .harness μ•ˆλ§Œ μ“°κΈ°', id: 'basic' },
748
- { label: 'extended β€” ν”„λ‘œμ νŠΈ 폴더 + shell allowlist', description: 'ν”„λ‘œμ νŠΈ 폴더 read/write, 사전 μ •μ˜λœ λͺ…λ Ήλ§Œ exec', id: 'extended' },
749
- { label: 'full β€” 전체 (마우슀/ν‚€λ³΄λ“œ/μ›Ή/κ΄€λ¦¬μž) ⚠ μœ„ν—˜', description: '⚠ IDE 톡합 μ‹œμ—λ§Œ ꢌμž₯ β€” λͺ¨λ“  PC μž‘μ—… κ°€λŠ₯', id: 'full' }
750
- ], { defaultIndex: 0 });
751
- permissionMode = pOpt ? pOpt.id : 'basic';
752
- } else {
753
- log('\nagent κΆŒν•œ λͺ¨λ“œ (leerness agent λͺ…λ Ή μ‚¬μš© μ‹œ):');
754
- log('1) basic (μ•ˆμ „) β€” .harness/ 만');
755
- log('2) extended β€” ν”„λ‘œμ νŠΈ 폴더 + shell allowlist');
756
- log('3) full ⚠ β€” 마우슀/ν‚€λ³΄λ“œ/μ›Ή/κ΄€λ¦¬μž 전체 (IDE 톡합 μ‹œμ—λ§Œ)');
757
- const a = await ask('선택 [1]: ');
758
- permissionMode = a === '2' ? 'extended' : a === '3' ? 'full' : 'basic';
759
- }
760
- }
742
+ // 1.9.174: κΆŒν•œ prompt 제거 (μ‚¬μš©μž λͺ…μ‹œ) β€” install μ‹œ 항상 basic μžλ™ 적용.
743
+ // REPL μ•ˆμ—μ„œ `:permissions <basic|extended|full>` 둜 μ¦‰μ‹œ λ³€κ²½ κ°€λŠ₯ (REPL UX κ°•ν™”).
744
+ // 이전 1.9.146 의 3-tier 선택 prompt λŠ” μ‚¬μš©μž κ²½ν—˜ λ³΅μž‘λ„ 증가 + 잘λͺ»λœ 선택 (full) μ‹œ μœ„ν—˜ β†’
745
+ // μ•ˆμ „ν•œ κΈ°λ³Έ (basic) μžλ™ μ‹œμž‘ + REPL μ§„μž… μ‹œμ μ— ν•„μš” μ‹œ λ³€κ²½ν•˜λŠ” 흐름이 더 μ•ˆμ „ν•˜κ³  κ°„νŽΈ.
746
+ const permissionMode = 'basic';
761
747
  // 1.9.151: λͺ¨λ“  λ¬Έν•­ μ’…λ£Œ ν›„ β€” REPL λͺ¨λ“œ μ¦‰μ‹œ ν™œμ„±ν™” μ—¬λΆ€ (μ‚¬μš©μž λͺ…μ‹œ μš”μ²­)
762
748
  // μ„ νƒλœ μ—μ΄μ „νŠΈκ°€ μžˆμ„ λ•Œλ§Œ ν‘œμ‹œ. μ„€μΉ˜ μ™„λ£Œ ν›„ install() κ°€ 처리.
763
749
  let startRepl = false;
@@ -807,7 +793,7 @@ async function install(root, opts = {}) {
807
793
  log(`Agents ν™œμ„±ν™”: ${list}`);
808
794
  }
809
795
  if (resolved.startRepl) log(`REPL μžλ™ μ‹œμž‘: 예 (μ„€μΉ˜ μ™„λ£Œ ν›„ \`leerness agent\` μ§„μž…)`);
810
- if (resolved.permissionMode) log(`Agent κΆŒν•œ λͺ¨λ“œ: ${resolved.permissionMode}`);
796
+ if (resolved.permissionMode) log(`Agent κΆŒν•œ λͺ¨λ“œ: ${resolved.permissionMode} (1.9.174 β€” REPLμ—μ„œ \`:permissions extended|full\` 둜 μ¦‰μ‹œ λ³€κ²½ κ°€λŠ₯)`);
811
797
  // 1.9.10: μŠ€ν‚¬ μΉ΄νƒˆλ‘œκ·Έ 좜처 μ•ˆλ‚΄
812
798
  if (SKILLPACK_SOURCE === 'builtin') log(`Skill catalog source: builtin (leerness-skillpack λ―Έμ„€μΉ˜ β€” \`npm i leerness-skillpack\`둜 ν™•μž₯ κ°€λŠ₯)`);
813
799
  else log(`Skill catalog source: ${SKILLPACK_SOURCE} (leerness-skillpack${SKILLPACK_META ? ` v${SKILLPACK_META.version}` : ''})`);
@@ -11019,6 +11005,8 @@ async function _agentRepl(root, opts) {
11019
11005
  log(C.dim(' Slash λͺ…λ Ή (1.9.150): :verify | :audit | :handoff | :health'));
11020
11006
  log(C.dim(' Memory Slash (1.9.161): :lessons | :brainstorm <topic> | :tasks | :plan'));
11021
11007
  log(C.dim(' πŸ†• 1.9.170 β€” Tab=provider cycle, Shift+Tab=model cycle, :stream on|off (μ‹€μ‹œκ°„ 좜λ ₯)'));
11008
+ log(C.dim(' πŸ†• 1.9.174 β€” :permissions [basic|extended|full] 둜 μ¦‰μ‹œ κΆŒν•œ λ³€κ²½ (default: basic μ•ˆμ „)'));
11009
+ log(C.dim(' πŸ†• 1.9.175 β€” :web / :pc / :lsp 으둜 Bridge 3μ’… REPL μ•ˆμ—μ„œ μ¦‰μ‹œ 호좜 (μ½”λ“œ 뢄석/μ›Ή/PC)'));
11022
11010
  log(C.dim(` ν˜„μž¬ β€” provider=${state.provider} model=${state.model || '(κΈ°λ³Έ)'} role=${state.role} permissions=${_readPermissions(root).mode}`));
11023
11011
  // 1.9.155: REPL μ§„μž… μ‹œ handoff μ»¨ν…μŠ€νŠΈ μžλ™ λ…ΈμΆœ (UX κ°œμ„  β€” μ‚¬μš©μžκ°€ 맀번 :handoff μ•ˆ 해도 μ»¨ν…μŠ€νŠΈ 인지)
11024
11012
  try {
@@ -11123,7 +11111,8 @@ async function _agentRepl(root, opts) {
11123
11111
  log(' :reset β€” history μ΄ˆκΈ°ν™”');
11124
11112
  log(' :history β€” λŒ€ν™” history ν‘œμ‹œ');
11125
11113
  log(' :save β€” μ„Έμ…˜ μ¦‰μ‹œ μ €μž₯');
11126
- log(' :permissions β€” ν˜„μž¬ κΆŒν•œ λͺ¨λ“œ ν‘œμ‹œ');
11114
+ log(' :permissions [mode] β€” πŸ†• 1.9.174 ν˜„μž¬ λͺ¨λ“œ ν‘œμ‹œ / λ˜λŠ” μ¦‰μ‹œ λ³€κ²½ (basic/extended/full)');
11115
+ log(' :perm [mode] β€” :permissions 단좕 alias');
11127
11116
  log(' :quit / :exit / :q β€” μ’…λ£Œ (μžλ™ μ €μž₯)');
11128
11117
  log(C.bold('\n πŸ†• 1.9.170 ν‚€λ³΄λ“œ 단좕킀:'));
11129
11118
  log(' Tab β€” λ‹€μŒ provider 둜 cycle (ollama β†’ claude β†’ codex β†’ gemini β†’ copilot)');
@@ -11138,6 +11127,17 @@ async function _agentRepl(root, opts) {
11138
11127
  log(' :brainstorm <topic> β€” leerness brainstorm "topic" (κ΄€λ ¨ μ»¨ν…μŠ€νŠΈ 회수)');
11139
11128
  log(' :tasks β€” leerness task list (ν˜„μž¬ task μƒνƒœ)');
11140
11129
  log(' :plan β€” leerness plan show (ν˜„μž¬ milestone)');
11130
+ log(C.bold('\n πŸ†• Bridge Slash (1.9.175) β€” REPL μ•ˆμ—μ„œ μ¦‰μ‹œ Bridge 호좜:'));
11131
+ log(' :web check β€” playwright μ„€μΉ˜ 확인 (opt-in)');
11132
+ log(' :web screenshot <url> [--out f.png] β€” URL β†’ PNG');
11133
+ log(' :web extract <url> --selector "css" β€” DOM ν…μŠ€νŠΈ μΆ”μΆœ');
11134
+ log(' :pc check β€” robotjs/nut-tree μ„€μΉ˜ 확인 (⚠ full κΆŒν•œ)');
11135
+ log(' :pc click <x> <y> β€” μ’Œν‘œ 클릭');
11136
+ log(' :pc type "<text>" β€” ν‚€λ³΄λ“œ μž…λ ₯');
11137
+ log(' :pc screenshot --out shot.png β€” PC ν™”λ©΄ 캑처');
11138
+ log(' :lsp check β€” typescript μ„€μΉ˜ + λ‹€κ΅­μ–΄ fallback');
11139
+ log(' :lsp symbols <file> β€” 심볼 μΆ”μΆœ (JS/TS/Py/Go/Rust/Java)');
11140
+ log(' :lsp references <name> [--in <dir>] β€” 심볼 μ°Έμ‘° 검색');
11141
11141
  return false;
11142
11142
  }
11143
11143
  if (op === 'model') {
@@ -11231,7 +11231,42 @@ async function _agentRepl(root, opts) {
11231
11231
  return false;
11232
11232
  }
11233
11233
  if (op === 'save') { saveSession(); log(C.dim(` β†’ ${rel(root, sessionPath())}`)); return false; }
11234
- if (op === 'permissions') { permissionsListCmd(root); return false; }
11234
+ if (op === 'permissions' || op === 'perm') {
11235
+ // 1.9.174: REPLμ—μ„œ κΆŒν•œ λ³€κ²½ κ°€λŠ₯ (μ‚¬μš©μž λͺ…μ‹œ μš”μ²­).
11236
+ // :permissions β€” ν˜„μž¬ λͺ¨λ“œ ν‘œμ‹œ + λ³€κ²½ μ˜΅μ…˜ μ•ˆλ‚΄
11237
+ // :permissions basic β€” κΆŒν•œ λͺ¨λ“œ μ¦‰μ‹œ λ³€κ²½
11238
+ const target = (rest[0] || '').toLowerCase();
11239
+ if (!target) {
11240
+ const p = _readPermissions(root);
11241
+ log('');
11242
+ log(C.bold(` πŸ” ν˜„μž¬ κΆŒν•œ λͺ¨λ“œ: ${C.cy(p.mode || 'basic')}`));
11243
+ log('');
11244
+ log(C.dim(' λ³€κ²½:'));
11245
+ log(` ${C.green(':permissions basic')} β€” μ•ˆμ „ (.harness 만 μ“°κΈ°, ꢌμž₯)`);
11246
+ log(` ${C.yel(':permissions extended')} β€” ν”„λ‘œμ νŠΈ 폴더 + shell allowlist`);
11247
+ log(` ${C.mag(':permissions full')} β€” ⚠ 전체 (마우슀/ν‚€λ³΄λ“œ/μ›Ή, IDE 톡합 μ‹œλ§Œ)`);
11248
+ log('');
11249
+ log(C.dim(' μ„ΈλΆ€ κΆŒν•œ (mouse/keyboard/browser/admin):'));
11250
+ Object.entries(p).filter(([k]) => k !== 'mode' && typeof p[k] === 'boolean').forEach(([k, v]) => {
11251
+ log(` ${k}: ${v ? C.green('βœ“ ν—ˆμš©') : C.dim('βœ— κ±°λΆ€')}`);
11252
+ });
11253
+ return false;
11254
+ }
11255
+ if (!['basic', 'extended', 'full'].includes(target)) {
11256
+ log(C.yel(` ⚠ 잘λͺ»λœ λͺ¨λ“œ: ${target} (basic | extended | full)`));
11257
+ return false;
11258
+ }
11259
+ try {
11260
+ permissionsSetCmd(root, target);
11261
+ log(C.green(` βœ“ κΆŒν•œ λͺ¨λ“œ λ³€κ²½: ${target} (μ¦‰μ‹œ 적용 β€” λ‹€μŒ λͺ…λ ΉλΆ€ν„°)`));
11262
+ if (target === 'full') {
11263
+ log(C.yel(' ⚠ full λͺ¨λ“œ β€” 마우슀/ν‚€λ³΄λ“œ/μ›Ή/κ΄€λ¦¬μž 전체 ν—ˆμš©. IDE 톡합 μ™Έ ν™˜κ²½μ—μ„œλŠ” μœ„ν—˜.'));
11264
+ }
11265
+ } catch (e) {
11266
+ log(C.yel(` ⚠ κΆŒν•œ λ³€κ²½ μ‹€νŒ¨: ${e.message}`));
11267
+ }
11268
+ return false;
11269
+ }
11235
11270
  if (op === 'status') {
11236
11271
  // 1.9.155: REPL μ•ˆμ—μ„œ ν˜„μž¬ μ„Έμ…˜ μƒνƒœ μžμ„Ένžˆ (provider/model/role/permissions/history/runs)
11237
11272
  log(C.bold('\n πŸ“Š REPL μ„Έμ…˜ μƒνƒœ (1.9.155)'));
@@ -11249,6 +11284,39 @@ async function _agentRepl(root, opts) {
11249
11284
  log('');
11250
11285
  return false;
11251
11286
  }
11287
+ // 1.9.175: Bridge 3μ’… slash β€” :web / :pc / :lsp (REPL μ•ˆμ—μ„œ μ¦‰μ‹œ Bridge 호좜)
11288
+ // μ‚¬μš© 예:
11289
+ // :web check β€” playwright μ„€μΉ˜ 확인
11290
+ // :web screenshot https://example.com β€” URL β†’ PNG
11291
+ // :pc check β€” robotjs μ„€μΉ˜ 확인
11292
+ // :pc click 800 400 β€” μ’Œν‘œ 클릭 (full κΆŒν•œ ν•„μš”)
11293
+ // :lsp symbols src/api.ts β€” 파일 심볼 μΆ”μΆœ
11294
+ // :lsp references myFunc --in src β€” 심볼 μ°Έμ‘° 검색
11295
+ if (op === 'web' || op === 'pc' || op === 'lsp') {
11296
+ const subParts = rest.length ? rest : ['check']; // 인자 μ—†μœΌλ©΄ check κΈ°λ³Έ
11297
+ const cliArgs = [op, ...subParts];
11298
+ // permissions 사전 μ•ˆλ‚΄ (full λͺ¨λ“œ ν•„μš”ν•œ sub 만)
11299
+ if (op === 'pc' && ['click', 'type', 'screenshot'].includes(subParts[0])) {
11300
+ const p = _readPermissions(root);
11301
+ if (p.mode !== 'full') {
11302
+ log(C.yel(` ⚠ :pc ${subParts[0]} 은 permissions=full ν•„μš” (ν˜„μž¬: ${p.mode})`));
11303
+ log(C.dim(` :permissions full 둜 μ¦‰μ‹œ λ³€κ²½ κ°€λŠ₯ (1.9.174)`));
11304
+ return false;
11305
+ }
11306
+ }
11307
+ log(C.dim(` β†’ leerness ${cliArgs.join(' ')}`));
11308
+ const t0 = Date.now();
11309
+ const r = runCommandSafe(process.execPath, [__filename, ...cliArgs, '--path', root], {
11310
+ cwd: root, root, timeout: 60000, kind: 'agent_repl_slash', label: `repl-${op}`,
11311
+ env: { LEERNESS_NO_BANNER: '1', LEERNESS_NO_PROMPT: '1', LEERNESS_NO_DRIFT_CHECK: '1' }
11312
+ });
11313
+ const dt = Date.now() - t0;
11314
+ if (r.stdout) log(r.stdout.trim().split('\n').slice(0, 50).join('\n'));
11315
+ if (r.status === 0) log(C.green(` βœ“ :${op} ${subParts[0] || ''} μ™„λ£Œ (${dt}ms)`));
11316
+ else log(C.yel(` ⚠ :${op} μ‹€νŒ¨ (exit ${r.status}, ${dt}ms)`));
11317
+ return false;
11318
+ }
11319
+
11252
11320
  // 1.9.150: leerness λ‚΄λΆ€ λͺ…λ Ή slash-commands β€” :verify / :audit / :handoff / :health
11253
11321
  // 1.9.161: Memory Surface 쑰회 slash μΆ”κ°€ β€” :lessons / :brainstorm / :tasks / :plan
11254
11322
  if (op === 'verify' || op === 'audit' || op === 'handoff' || op === 'health'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.173",
3
+ "version": "1.9.175",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",