leerness 1.9.271 → 1.9.272
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 +24 -0
- package/README.md +36 -6
- package/SECURITY.md +56 -0
- package/bin/harness.js +61 -2
- package/package.json +3 -2
- package/scripts/e2e.js +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.272 — 2026-06-03 — 공개 신뢰도·투명성 강화 (GPT-5.5 외부 리뷰 반영)
|
|
4
|
+
|
|
5
|
+
**🔒 외부 평가(GPT-5.5 직접 실행/검사, 7/10)에서 지적된 공개 패키지 신뢰도·투명성 항목을 반영.**
|
|
6
|
+
|
|
7
|
+
### 배경
|
|
8
|
+
GPT-5.5 가 패키지를 직접 받아 실행·검사한 외부 리뷰: 기능은 실용적이나 (1) README 배지 버전 불일치, (2) `.claude` hook 자동 설치 명시성 부족, (3) 권한이 큰 CLI(child_process/git/외부CLI/automation)인데 표면 비공개, (4) CI 공개 부재로 e2e 신뢰도, (5) 잦은 릴리스·단일 대형 파일·e2e 5분 초과를 지적. 실행 가능한 신뢰도 항목을 이번 라운드에 반영하고 나머지는 백로그(UR-0025~0027)에 기록.
|
|
9
|
+
|
|
10
|
+
### 구현
|
|
11
|
+
1. **`leerness capabilities` (alias `security-surface`) 신규 명령** — 권한 표면 6영역(filesystem/network/childProcess/externalAgents/automationBridges/claudeHook) + risk/opt-out + ⚠ 주의 명령 7종 공개. `--json` 기계 판독. (GPT #3 반영)
|
|
12
|
+
2. **`SECURITY.md` 신규** (npm `files` 포함) — 동일 표면 + 설계원칙(0-dep/no-postinstall/백업/무동의 호출금지) + 권장 도입 방식. (GPT #3)
|
|
13
|
+
3. **`.claude` hook 투명성** — 설치 시 "무엇을/왜/끄는 법(`--no-auto-update`, 파일 경로)" 명시 안내. (GPT #2/#4)
|
|
14
|
+
4. **README 버전 배지 불일치 영구 방지** — `prepack` 에 `readme sync` 추가 → 매 publish 시 배지가 현재 버전/e2e 결과와 자동 일치. ASCII 배너 버전 숫자 제거(drift-proof). (GPT #1 근본 해결)
|
|
15
|
+
5. **GitHub Actions CI** — `.github/workflows/ci.yml` (ubuntu+windows × node 18/20/22, selftest+e2e). 공개 CI 로 e2e 배지 신뢰도. (GPT #4)
|
|
16
|
+
6. **README 보안·투명성 섹션** (한/영) + selftest 24→25 + e2e 219→220.
|
|
17
|
+
|
|
18
|
+
### 백로그 기록 (GPT 장기 항목)
|
|
19
|
+
- UR-0025: `bin/harness.js` 단일 대형 파일 모듈 분리 (점진적·비파괴).
|
|
20
|
+
- UR-0026: 릴리스 채널 (npm dist-tag latest/next 안정·실험 구분).
|
|
21
|
+
- UR-0027: `npm test` 5분 초과 → `test:fast` 서브셋 분리 + CI 전체.
|
|
22
|
+
|
|
23
|
+
### 검증
|
|
24
|
+
- **selftest 25/25 PASS** · **E2E 220/220 PASS** (회귀 0).
|
|
25
|
+
- `capabilities --json` 6영역/주의명령/원칙 + alias 확인 · 배지 자동 동기화(1.9.272 / e2e 220) 확인.
|
|
26
|
+
|
|
3
27
|
## 1.9.271 — 2026-06-02 — README 한/영 이중 사용자 친화 재작성 (가독성) + e2e 배지 카운트 정확화
|
|
4
28
|
|
|
5
29
|
**📖 README 를 한국어/영어 이중 버전으로 가독성 좋게 재작성 (사용자 명시).**
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **AI 코딩 에이전트의 거짓 완료·중복·망각·충돌을 막아주는 검수·기억·협업 CLI 하네스.**
|
|
4
4
|
> **A CLI harness that stops AI coding agents from faking completion, duplicating work, forgetting context, and colliding.**
|
|
5
5
|
|
|
6
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []()
|
|
7
7
|
|
|
8
8
|
```
|
|
9
9
|
╔══════════════════════════════════════════════════════════════╗
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
║ ██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║ ║
|
|
14
14
|
║ ███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║ ║
|
|
15
15
|
║ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝ ║
|
|
16
|
-
║
|
|
16
|
+
║ AI Agent Reliability Harness (버전: 상단 배지 참조) ║
|
|
17
17
|
║ verify · remember · orchestrate · audit · drift · roles ║
|
|
18
18
|
╚══════════════════════════════════════════════════════════════╝
|
|
19
19
|
```
|
|
@@ -175,6 +175,21 @@ A. 네. 모든 명령이 exit code + `--json` + `--yes` 비대화형을 지원
|
|
|
175
175
|
|
|
176
176
|
---
|
|
177
177
|
|
|
178
|
+
## 🔒 보안·투명성
|
|
179
|
+
|
|
180
|
+
leerness 는 권한이 큰 CLI 하네스입니다(child_process · git · 외부 CLI · 자동화 브리지 · hook 설치). **할 수 있는 전부와 끄는 법**을 공개합니다.
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
leerness capabilities # 권한 표면 + opt-out + 주의 명령 (--json 지원)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
- **런타임 의존성 0** · **postinstall 없음** · **변경 전 자동 백업** · **동의 없는 외부 호출 금지**
|
|
187
|
+
- `init` 시 `.claude/settings.local.json` 에 SessionStart hook(`update --check`)이 설치됩니다 → 끄기: `leerness init . --no-auto-update`
|
|
188
|
+
- 회사/운영 코드에서는 먼저 한 프로젝트에서 `init` 후 `git diff` 로 검토하고 커밋하세요.
|
|
189
|
+
- 자세히: [SECURITY.md](SECURITY.md)
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
178
193
|
<a id="english"></a>
|
|
179
194
|
|
|
180
195
|
# 🇬🇧 English
|
|
@@ -328,6 +343,21 @@ A. Yes. Every command supports exit codes, `--json`, and non-interactive `--yes`
|
|
|
328
343
|
|
|
329
344
|
---
|
|
330
345
|
|
|
346
|
+
## 🔒 Security & transparency
|
|
347
|
+
|
|
348
|
+
leerness is a powerful CLI harness (child_process, git, external CLIs, automation bridges, hook install). It discloses **everything it can do and how to turn each off**.
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
leerness capabilities # capability surface + opt-out + cautious commands (--json supported)
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
- **Zero runtime deps** · **no postinstall** · **auto-backup before changes** · **never auto-calls external services without consent**
|
|
355
|
+
- `init` installs a SessionStart hook (`update --check`) in `.claude/settings.local.json` → disable with `leerness init . --no-auto-update`
|
|
356
|
+
- For company/production code, trial `init` in one project, review with `git diff`, then commit.
|
|
357
|
+
- Details: [SECURITY.md](SECURITY.md)
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
331
361
|
## 🔧 Environment variables / 환경변수
|
|
332
362
|
|
|
333
363
|
| Variable | Effect |
|
|
@@ -367,7 +397,7 @@ MIT — © leerness contributors
|
|
|
367
397
|
<!-- leerness:project-readme:start -->
|
|
368
398
|
## Leerness Project Harness
|
|
369
399
|
|
|
370
|
-
이 프로젝트는 Leerness v1.9.
|
|
400
|
+
이 프로젝트는 Leerness v1.9.272 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
|
|
371
401
|
|
|
372
402
|
### Core Commands
|
|
373
403
|
|
|
@@ -409,7 +439,7 @@ leerness memory restore decision <date|title>
|
|
|
409
439
|
|
|
410
440
|
### MCP server (외부 AI 통합)
|
|
411
441
|
|
|
412
|
-
Leerness v1.9.
|
|
442
|
+
Leerness v1.9.272는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **42개 도구**를 노출:
|
|
413
443
|
|
|
414
444
|
```jsonc
|
|
415
445
|
// 카테고리별
|
|
@@ -430,7 +460,7 @@ Leerness v1.9.271는 stdio JSON-RPC MCP server를 내장합니다 — Claude Cod
|
|
|
430
460
|
`<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
|
|
431
461
|
1) 다음 라운드 후보 선정 → 2) 코드 변경 → 3) stress-v* 신규 작성 + 누적 회귀 → 4) e2e 219/219 → 5) npm pack + git tag + GitHub release → 6) main 자동 push (1.9.140+) → 7) session close → 8) 다음 라운드 예약.
|
|
432
462
|
|
|
433
|
-
현재 누적: **70 라운드 (1.9.40 → 1.9.
|
|
463
|
+
현재 누적: **70 라운드 (1.9.40 → 1.9.272)** · 매 라운드 GitHub release/태그 생성 · _reports/는 비공개 보존.
|
|
434
464
|
|
|
435
465
|
### 성능 가이드 (1.9.140 측정)
|
|
436
466
|
|
|
@@ -468,6 +498,6 @@ leerness release pack --close --auto-main-push
|
|
|
468
498
|
- `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
|
|
469
499
|
- `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
|
|
470
500
|
|
|
471
|
-
Last synced by Leerness v1.9.
|
|
501
|
+
Last synced by Leerness v1.9.272: 2026-06-03
|
|
472
502
|
<!-- leerness:project-readme:end -->
|
|
473
503
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Security & Transparency / 보안·투명성
|
|
2
|
+
|
|
3
|
+
> `leerness capabilities` 로 언제든 아래 표면을 CLI 에서 확인할 수 있습니다 (`--json` 지원).
|
|
4
|
+
> Run `leerness capabilities` anytime to view this surface from the CLI (`--json` supported).
|
|
5
|
+
|
|
6
|
+
leerness 는 **권한이 큰 CLI 하네스**입니다 (child_process · git · 외부 AI CLI · 자동화 브리지 · hook 설치). 신뢰를 위해 **할 수 있는 전부와 각 항목의 끄는 법(opt-out)** 을 공개합니다.
|
|
7
|
+
|
|
8
|
+
leerness is a **powerful CLI harness** (child_process, git, external AI CLIs, automation bridges, hook install). For trust, we disclose **everything it can do and how to opt out of each**.
|
|
9
|
+
|
|
10
|
+
## 설계 원칙 / Design principles
|
|
11
|
+
|
|
12
|
+
- **런타임 의존성 0** — `npm audit` 취약점 0. / Zero runtime dependencies.
|
|
13
|
+
- **postinstall 없음** — 설치만으로 코드가 실행되지 않음. / No postinstall scripts.
|
|
14
|
+
- **변경 전 자동 백업** — 모든 메타파일 변경 전 `.harness/archive/` 에 백업. / Auto-backup before any change.
|
|
15
|
+
- **동의 없는 자동 호출 금지** — 사용자 동의 없이 외부 LLM/API/CLI 를 자동 호출하지 않음. / Never auto-calls external LLMs/APIs/CLIs without consent.
|
|
16
|
+
|
|
17
|
+
## 권한 표면 / Capability surface
|
|
18
|
+
|
|
19
|
+
| 영역 / Area | 위험 / Risk | 설명 / What | opt-out |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| filesystem | 🟢 low | `.harness/` 메타파일 생성·갱신, 변경 전 백업. 소스코드 직접 수정 안 함. | 핵심 동작 (백업으로 보호) |
|
|
22
|
+
| network | 🟢 low | `update --check` 의 npm 최신 버전 비교만. 외부 URL 자동 fetch 안 함. | `LEERNESS_OFFLINE=1` |
|
|
23
|
+
| childProcess | 🟡 medium | git(명시 명령 시), `npm test`(verify-code), 외부 CLI `--version` 감지. | verify 계열 한정 · 외부 CLI 는 opt-in |
|
|
24
|
+
| externalAgents | 🟡 medium | `agents dispatch/multi` — 기본은 명령 텍스트만 생성, `multi --execute` 시 실제 spawn. | `LEERNESS_ENABLE_*` 미설정 시 비활성 (기본 off) |
|
|
25
|
+
| automationBridges | 🔴 high | `web`(playwright)/`pc`(robotjs)/`lsp`(typescript) — opt-in 의존성. `pc` 는 마우스/키보드 제어. | 의존성 미설치 시 비활성 (기본 off) |
|
|
26
|
+
| claudeHook | 🟢 low | `init` 시 `.claude/settings.local.json` 에 SessionStart hook(`update --check`) 설치. | `leerness init . --no-auto-update` |
|
|
27
|
+
|
|
28
|
+
## ⚠ 주의해서 쓸 명령 / Use with caution
|
|
29
|
+
|
|
30
|
+
회사·운영 코드에서는 아래 명령을 먼저 검토하세요. / Review these before using on company/production code.
|
|
31
|
+
|
|
32
|
+
| 명령 / Command | 동작 / Action |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `init` | `.harness/` 50+ 파일 + `.claude` hook 생성 (변경 전 백업) |
|
|
35
|
+
| `update --yes` | 자동 마이그레이션 — 메타파일 갱신 |
|
|
36
|
+
| `agents multi --execute` | 외부 AI CLI 실제 spawn (병렬) |
|
|
37
|
+
| `release publish` / `sync-main` | git push + npm publish + GitHub release |
|
|
38
|
+
| `pc <click|type>` | 마우스/키보드 제어 (robotjs, full 권한) |
|
|
39
|
+
| `web <...>` | 헤드리스 브라우저 자동화 (playwright) |
|
|
40
|
+
| `setup-agents` | 외부 CLI 활성화 + 자동 설치 시도 |
|
|
41
|
+
|
|
42
|
+
## 권장 도입 방식 / Recommended adoption
|
|
43
|
+
|
|
44
|
+
전역 자동 적용보다, 먼저 한 프로젝트에서 확인 후 커밋하세요.
|
|
45
|
+
Prefer per-project trial over global auto-adoption.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx leerness@latest init . --yes --language ko # 또는 --language en
|
|
49
|
+
git diff && git status # 생성 파일 검토 후 커밋
|
|
50
|
+
leerness capabilities # 권한 표면 확인
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 취약점 보고 / Reporting
|
|
54
|
+
|
|
55
|
+
보안 이슈는 공개 이슈 대신 비공개로 알려주세요 / Report security issues privately (not public issues):
|
|
56
|
+
https://github.com/gugu9999gu/leerness/issues (보안 라벨 / security label)
|
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.
|
|
10
|
+
const VERSION = '1.9.272';
|
|
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 처리).
|
|
@@ -2950,6 +2950,7 @@ function _selfTestCases() {
|
|
|
2950
2950
|
{ name: '_detectSystemLang: LC_ALL 우선 + LANGUAGE 폴백 (1.9.269)', run: () => _detectSystemLang({ LC_ALL: 'ko_KR.UTF-8', LANG: 'en_US.UTF-8' }) === 'ko' && _detectSystemLang({ LANGUAGE: 'en_GB' }) === 'en' },
|
|
2951
2951
|
{ name: 'ROLE_CATALOG + _normalizeRole: 7종 + 한국어 별칭 (1.9.270)', run: () => { const keys = Object.keys(ROLE_CATALOG); return keys.length === 7 && keys.includes('coder') && keys.includes('reviewer') && _normalizeRole('코딩') === 'coder' && _normalizeRole('검수자') === 'reviewer' && _normalizeRole('지휘관') === 'commander'; } },
|
|
2952
2952
|
{ name: '_pickModel: top/code/fast 등급 선택 (1.9.270)', run: () => { return _pickModel('codex', 'code') === 'gpt-5-codex' && _pickModel('claude', 'top') === 'claude-opus-4-7' && /haiku/.test(_pickModel('claude', 'fast')); } },
|
|
2953
|
+
{ name: 'CAPABILITY_SURFACE: 6 영역 + risk/optOut + 주의명령 (1.9.272)', run: () => { const ks = Object.keys(CAPABILITY_SURFACE); return ks.length === 6 && ks.includes('automationBridges') && Object.values(CAPABILITY_SURFACE).every(v => ['low','medium','high'].includes(v.risk) && v.optOut && v.desc) && POWERFUL_COMMANDS.length >= 5; } },
|
|
2953
2954
|
{ name: 'VERSION 형식 (x.y.z)', run: () => /^\d+\.\d+\.\d+$/.test(VERSION) }
|
|
2954
2955
|
];
|
|
2955
2956
|
}
|
|
@@ -3606,6 +3607,7 @@ function commandsCmd(root) {
|
|
|
3606
3607
|
{ cmd: 'route <task-type>', desc: '작업 유형 분류 (11종)' },
|
|
3607
3608
|
{ cmd: 'agents list|check|quota|dispatch|multi', desc: '외부 AI CLI 오케스트레이션 (dispatch --role 모델 라우팅 1.9.270)' },
|
|
3608
3609
|
{ cmd: 'roles list|set|unset|catalog|suggest|verify', desc: '모델별 역할 부여 (코딩/검수/지휘/디자인/디버그/설계/분배) — 1.9.270' },
|
|
3610
|
+
{ cmd: 'capabilities [--json]', desc: '권한·보안 표면 공개 (무엇을 하는지 + opt-out + 주의 명령) — 1.9.272' },
|
|
3609
3611
|
{ cmd: 'slash-commands [agent] [--json --record --detect --refresh]', desc: 'CLI 에이전트 슬래시 명령 레지스트리 + --help probe 자동 갱신 (1.9.265~267, UR-0021)' },
|
|
3610
3612
|
{ cmd: 'review-request "<request>"', desc: '사용자 요청 사전 검토 (1.9.176)' },
|
|
3611
3613
|
{ cmd: 'review <file> --persona <ids>', desc: '페르소나 리뷰 (1.9.29)' },
|
|
@@ -15258,6 +15260,9 @@ function autoUpdateInstall(root) {
|
|
|
15258
15260
|
ok('auto-update SessionStart hook installed (.claude/settings.local.json)');
|
|
15259
15261
|
if (removedLegacy) ok(`legacy hook 제거: ${removedLegacy}건 (leerness-plus → leerness 통합)`);
|
|
15260
15262
|
ok('/update slash command added');
|
|
15263
|
+
// 1.9.272 (GPT-5.5 외부 리뷰 반영): hook 설치 투명성 — 무엇을/왜/어떻게 끄는지 명시.
|
|
15264
|
+
log(` ⓘ 이 hook 은 Claude Code 세션 시작 시 \`leerness update --check\` 를 1회 실행합니다 (네트워크: npm 최신 버전 비교, 자동 설치는 안 함).`);
|
|
15265
|
+
log(` ⓘ 제거: ${rel(root, settingsFile)} 의 hooks.SessionStart 항목 삭제 · 설치 시 끄기: leerness init . --no-auto-update`);
|
|
15261
15266
|
}
|
|
15262
15267
|
|
|
15263
15268
|
// 1.9.151: ViewWork hook 제거 (사용자 명시 — leerness와 무관한 외부 도구)
|
|
@@ -17893,6 +17898,56 @@ function rolesCmd(root, sub, ...args) {
|
|
|
17893
17898
|
log(`\n 사용: leerness agents dispatch "<task>" --role <role> · 검증: leerness roles verify`);
|
|
17894
17899
|
}
|
|
17895
17900
|
|
|
17901
|
+
// ===== 1.9.272: Capability / Security Surface 공개 (GPT-5.5 외부 리뷰 반영) =====
|
|
17902
|
+
// leerness 는 권한이 큰 CLI 하네스(child_process/git/외부 CLI/automation 브리지/hook 설치)이므로,
|
|
17903
|
+
// 무엇을 할 수 있고 어떻게 끄는지를 명시적으로 공개해 신뢰도를 높인다. SECURITY.md 와 동일 출처.
|
|
17904
|
+
const CAPABILITY_SURFACE = {
|
|
17905
|
+
filesystem: { risk: 'low', desc: '.harness/ 메타파일 생성·갱신, 변경 전 .harness/archive/ 자동 백업. 소스코드는 직접 수정 안 함.', optOut: '핵심 동작 (백업으로 보호)' },
|
|
17906
|
+
network: { risk: 'low', desc: 'npm 최신 버전 비교(update --check)만. 그 외 외부 URL 자동 fetch 안 함.', optOut: 'LEERNESS_OFFLINE=1' },
|
|
17907
|
+
childProcess: { risk: 'medium', desc: 'git(명시 명령 시 status/commit/push), npm test(verify-code), 외부 CLI --version 감지. 셸 spawn.', optOut: 'verify 계열 한정 · 외부 CLI 는 opt-in' },
|
|
17908
|
+
externalAgents: { risk: 'medium', desc: 'agents dispatch/multi — 외부 AI CLI(claude/codex/agy/grok/copilot) 호출. 기본은 명령 텍스트만 생성, multi --execute 시 실제 spawn.', optOut: 'LEERNESS_ENABLE_* 미설정 시 비활성 (기본 off)' },
|
|
17909
|
+
automationBridges: { risk: 'high', desc: 'web(playwright)/pc(robotjs)/lsp(typescript) 브리지 — opt-in 의존성. pc 는 마우스/키보드 제어(full 권한).', optOut: '의존성 미설치 시 비활성 (기본 off, 명시 설치 필요)' },
|
|
17910
|
+
claudeHook: { risk: 'low', desc: 'init 시 .claude/settings.local.json 에 SessionStart hook(update --check) 설치.', optOut: 'leerness init . --no-auto-update' }
|
|
17911
|
+
};
|
|
17912
|
+
const POWERFUL_COMMANDS = [
|
|
17913
|
+
{ cmd: 'init', note: '.harness/ 50+ 파일 + .claude hook 생성 (변경 전 백업)' },
|
|
17914
|
+
{ cmd: 'update --yes', note: '자동 마이그레이션 — 메타파일 갱신' },
|
|
17915
|
+
{ cmd: 'agents multi --execute', note: '외부 AI CLI 실제 spawn (병렬 실행)' },
|
|
17916
|
+
{ cmd: 'release publish / sync-main', note: 'git push + npm publish + GitHub release' },
|
|
17917
|
+
{ cmd: 'pc <click|type|...>', note: '마우스/키보드 제어 (robotjs, full 권한)' },
|
|
17918
|
+
{ cmd: 'web <...>', note: '헤드리스 브라우저 자동화 (playwright)' },
|
|
17919
|
+
{ cmd: 'setup-agents', note: '외부 CLI 활성화 + 자동 설치 시도' }
|
|
17920
|
+
];
|
|
17921
|
+
function capabilitiesCmd(root, opts = {}) {
|
|
17922
|
+
if (opts.json) {
|
|
17923
|
+
log(JSON.stringify({ version: VERSION, surface: CAPABILITY_SURFACE, powerfulCommands: POWERFUL_COMMANDS,
|
|
17924
|
+
principles: ['0 런타임 의존성', 'postinstall 없음', '사용자 동의 없이 외부 LLM/API/CLI 자동 호출 안 함', '변경 전 자동 백업'] }, null, 2));
|
|
17925
|
+
return;
|
|
17926
|
+
}
|
|
17927
|
+
const isTty = process.stdout && process.stdout.isTTY;
|
|
17928
|
+
const cy = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
|
|
17929
|
+
const dm = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
17930
|
+
const riskMark = r => r === 'high' ? '🔴 high' : r === 'medium' ? '🟡 medium' : '🟢 low';
|
|
17931
|
+
log(cy(`# leerness capabilities (1.9.272) — 권한·보안 표면 공개`));
|
|
17932
|
+
log(dm(` leerness 는 권한이 큰 CLI 하네스입니다. 아래가 할 수 있는 전부이며, 각 항목의 opt-out 을 함께 표기합니다.`));
|
|
17933
|
+
log('');
|
|
17934
|
+
log(`## 원칙`);
|
|
17935
|
+
log(` ✓ 런타임 의존성 0 · postinstall 없음 · 변경 전 자동 백업`);
|
|
17936
|
+
log(` ✓ 사용자 동의 없이 외부 LLM/API/CLI 를 자동 호출하지 않음`);
|
|
17937
|
+
log('');
|
|
17938
|
+
log(`## 권한 표면`);
|
|
17939
|
+
for (const [k, v] of Object.entries(CAPABILITY_SURFACE)) {
|
|
17940
|
+
log(` ${riskMark(v.risk)} ${cy(k)}`);
|
|
17941
|
+
log(` ${v.desc}`);
|
|
17942
|
+
log(dm(` opt-out: ${v.optOut}`));
|
|
17943
|
+
}
|
|
17944
|
+
log('');
|
|
17945
|
+
log(`## ⚠ 주의해서 쓸 명령 (회사/운영 코드)`);
|
|
17946
|
+
for (const c of POWERFUL_COMMANDS) log(` • ${c.cmd.padEnd(22)} ${dm(c.note)}`);
|
|
17947
|
+
log('');
|
|
17948
|
+
log(dm(` 전체 정책: SECURITY.md · 기계 판독: leerness capabilities --json`));
|
|
17949
|
+
}
|
|
17950
|
+
|
|
17896
17951
|
// 1.9.149+1.9.153: REPL 모드 — leerness 자율 AI 에이전트 (multi-provider 세션)
|
|
17897
17952
|
async function _agentRepl(root, opts) {
|
|
17898
17953
|
// 1.9.153: .env 자동 로드 (REPL 진입 직전) — install 직후 LEERNESS_ENABLE_* 즉시 반영
|
|
@@ -20816,6 +20871,8 @@ async function main() {
|
|
|
20816
20871
|
}
|
|
20817
20872
|
// 1.9.270: leerness roles <list|set|unset|catalog|suggest|verify> — 모델별 역할 부여 (사용자 명시)
|
|
20818
20873
|
if (cmd === 'roles' || cmd === 'role') return rolesCmd(arg('--path', process.cwd()), args[1], ...args.slice(2));
|
|
20874
|
+
// 1.9.272: leerness capabilities — 권한/보안 표면 공개 (GPT-5.5 외부 리뷰 반영)
|
|
20875
|
+
if (cmd === 'capabilities' || cmd === 'security-surface') return capabilitiesCmd(arg('--path', process.cwd()), { json: has('--json') });
|
|
20819
20876
|
// 1.9.245: API skill cache — 공식 문서·관련링크 자동 정리 (사용자 명시 UR-0015)
|
|
20820
20877
|
if (cmd === 'api-skill') return apiSkillCmd(arg('--path', process.cwd()), args[1] || 'help');
|
|
20821
20878
|
// 1.9.208: leerness constraints <list|check|add> — 플랫폼/API 제약 사전 체크 (사용자 명시)
|
|
@@ -20988,5 +21045,7 @@ module.exports = {
|
|
|
20988
21045
|
// 1.9.269: 시스템(OS) 언어 감지 (UR-0022) + 언어 판별 — 단위 테스트
|
|
20989
21046
|
_detectSystemLang, detectLanguageValue,
|
|
20990
21047
|
// 1.9.270: agent roles — 모델별 역할 부여 (사용자 명시) — 단위 테스트
|
|
20991
|
-
ROLE_CATALOG, _normalizeRole, _pickModel, _rolesFile, _loadRoles, _saveRoles, _resolveRole, _suggestRoles, rolesCmd, _dispatchCommand
|
|
21048
|
+
ROLE_CATALOG, _normalizeRole, _pickModel, _rolesFile, _loadRoles, _saveRoles, _resolveRole, _suggestRoles, rolesCmd, _dispatchCommand,
|
|
21049
|
+
// 1.9.272: 권한/보안 표면 공개 (GPT-5.5 리뷰) — 단위 테스트
|
|
21050
|
+
CAPABILITY_SURFACE, POWERFUL_COMMANDS, capabilitiesCmd
|
|
20992
21051
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.272",
|
|
4
4
|
"description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|
|
@@ -42,12 +42,13 @@
|
|
|
42
42
|
"docs",
|
|
43
43
|
"README.md",
|
|
44
44
|
"CHANGELOG.md",
|
|
45
|
+
"SECURITY.md",
|
|
45
46
|
"LICENSE"
|
|
46
47
|
],
|
|
47
48
|
"scripts": {
|
|
48
49
|
"test": "node ./bin/harness.js --version && node ./bin/harness.js selftest && node ./scripts/e2e.js",
|
|
49
50
|
"test:smoke": "node ./scripts/e2e.js",
|
|
50
|
-
"prepack": "node ./bin/harness.js --version"
|
|
51
|
+
"prepack": "node ./bin/harness.js readme sync . && node ./bin/harness.js --version"
|
|
51
52
|
},
|
|
52
53
|
"publishConfig": {
|
|
53
54
|
"access": "public"
|
package/scripts/e2e.js
CHANGED
|
@@ -2748,5 +2748,23 @@ total++;
|
|
|
2748
2748
|
if (!ok) { failed++; console.log((rRoute.stdout || '').slice(0, 400)); }
|
|
2749
2749
|
}
|
|
2750
2750
|
|
|
2751
|
+
// 1.9.272 회귀: capabilities — 권한/보안 표면 공개 (GPT-5.5 리뷰 반영)
|
|
2752
|
+
total++;
|
|
2753
|
+
{
|
|
2754
|
+
const rJson = cp.spawnSync(process.execPath, [CLI, 'capabilities', '--json'], { encoding: 'utf8', timeout: 15000 });
|
|
2755
|
+
let jsonOk = false;
|
|
2756
|
+
try {
|
|
2757
|
+
const j = JSON.parse(rJson.stdout);
|
|
2758
|
+
jsonOk = j.surface && Object.keys(j.surface).length === 6 && j.surface.automationBridges
|
|
2759
|
+
&& j.surface.automationBridges.risk === 'high' && Array.isArray(j.powerfulCommands) && j.powerfulCommands.length >= 5
|
|
2760
|
+
&& Array.isArray(j.principles);
|
|
2761
|
+
} catch {}
|
|
2762
|
+
const rTxt = cp.spawnSync(process.execPath, [CLI, 'security-surface'], { encoding: 'utf8', timeout: 15000 });
|
|
2763
|
+
const txtOk = rTxt.status === 0 && /권한·보안 표면/.test(rTxt.stdout) && /opt-out/.test(rTxt.stdout);
|
|
2764
|
+
const ok = jsonOk && txtOk;
|
|
2765
|
+
console.log(ok ? '✓ B(1.9.272) capabilities: 6 영역 surface + 주의명령 + alias(security-surface)' : `✗ capabilities 실패 (json=${jsonOk} txt=${txtOk})`);
|
|
2766
|
+
if (!ok) { failed++; console.log((rJson.stdout || '').slice(0, 300)); }
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2751
2769
|
console.log(`\nE2E result: ${total - failed}/${total} passed`);
|
|
2752
2770
|
if (failed > 0) process.exit(1);
|