leerness 1.9.22 → 1.9.24
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 +63 -0
- package/README.md +283 -74
- package/bin/harness.js +128 -2
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.24 — 2026-05-14
|
|
4
|
+
|
|
5
|
+
**`leerness deps <capability>` — depends-on 그래프 역방향 추적 + 자동 회귀 sweep**.
|
|
6
|
+
|
|
7
|
+
오래된 작업 재진행 시 / 핵심 모듈 변경 시 영향받는 모듈을 자동 식별 + 해당 프로젝트의 `npm test`를 일괄 실행.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`leerness deps <capability>`**: 워크스페이스 모든 `reuse-map.md`의 depends-on 엣지를 역방향 추적해 해당 capability를 의존하는 모든 capability와 프로젝트를 식별. 1-hop(직접 의존) + 2-hop(전이 의존) 모두 표시.
|
|
12
|
+
- **`leerness deps <capability> --run-tests`**: 영향받는 N개 프로젝트의 `npm test`를 자동 일괄 실행. 회귀 발견 시 어느 프로젝트인지 즉시 보고 + `exit 1`. CI 통합용 `--json`.
|
|
13
|
+
- 실측: `leerness deps Character --all-apps --run-tests` 실행 시 rpg-core의 `Character` capability에 의존하는 **6 프로젝트(8 capability) 자동 식별 + 6/6 npm test 자동 일괄 실행**.
|
|
14
|
+
|
|
15
|
+
### Why
|
|
16
|
+
오래된 작업을 재진행하거나 핵심 모듈을 변경할 때, 영향받는 다른 프로젝트를 수동으로 grep하던 패턴을 1 명령으로 자동화. depends-on 그래프(1.9.18부터 수집)가 활용됨.
|
|
17
|
+
|
|
18
|
+
### Migration
|
|
19
|
+
```bash
|
|
20
|
+
npx leerness@latest update . --yes
|
|
21
|
+
# 사용 예
|
|
22
|
+
leerness deps Character --all-apps --run-tests
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 1.9.23 — 2026-05-14
|
|
26
|
+
|
|
27
|
+
**Install 사용성 개선 — `preferGlobal` + `main` 필드 + README 상단 Install 섹션**.
|
|
28
|
+
|
|
29
|
+
npmjs.com 페이지가 자동 표시하는 `npm i leerness`만 따라 했을 때 `leerness` 명령이 PATH에 없어 실패하던 문제를 안내로 보완.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- `package.json` — `preferGlobal: true` (npm이 사용자에게 전역 설치 권장 메시지 출력) + `main: "bin/harness.js"` (라이브러리 import도 가능)
|
|
33
|
+
- `README.md` — 최상단에 **⚙️ 설치 (Install)** 섹션 추가. 3가지 옵션 명시:
|
|
34
|
+
1. `npx leerness@latest ...` (추천, 설치 불필요)
|
|
35
|
+
2. `npm i -g leerness` (전역 설치)
|
|
36
|
+
3. `npm i --save-dev leerness` + `npx leerness ...`
|
|
37
|
+
|
|
38
|
+
## 1.9.22 — 2026-05-14
|
|
39
|
+
|
|
40
|
+
**Ollama 로컬 LLM 통합 (opt-in 전용) — handoff --compact + orchestrate --agents N + llm-bench record**.
|
|
41
|
+
|
|
42
|
+
LLM 벤치마크에서 확인된 4가지 개선점 통합. **opt-in 정책 엄수**: 사용자가 leerness 적용 프로젝트에서 로컬 LLM 사용을 원치 않을 수 있어 자동 활성화 금지.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **`leerness handoff --compact`** (후보 1): 4KB 출력을 ~500자 1-3줄로 압축. LLM 시스템 프롬프트 주입용. 핵심: 진행률 + 프로젝트 1줄씩 + 핵심 규칙 1줄.
|
|
47
|
+
- **`leerness orchestrate "<목표>" --agents N`** (후보 3, 사용자 정책 명시):
|
|
48
|
+
- **Opt-in 전용**: `LEERNESS_OLLAMA_BASE_URL` 환경변수 감지 시에만 활성화. 미설정 시 명령 거부 + 한국어 안내. **LLM 자동 호출 절대 금지**.
|
|
49
|
+
- `.env` 파일 자동 로드 (간단 파서).
|
|
50
|
+
- `--agents N` 가변 (1~256). 사용자 요구 "10/20개 등 늘어날 수 있음" 반영.
|
|
51
|
+
- `--model` 선택, `--retry-on-fail K`(후보 2 통합), Promise.all 병렬.
|
|
52
|
+
- 실측: 10 agent에서 5.5× 병렬 효과.
|
|
53
|
+
- `.harness/orchestrate-log.md` 자동 누적.
|
|
54
|
+
- **`leerness llm-bench record`** (후보 4): `.harness/llm-bench-history.md`에 표 누적.
|
|
55
|
+
- **`.env.example`**: `LEERNESS_OLLAMA_BASE_URL=` + `LEERNESS_OLLAMA_MODEL=` + opt-in 정책 한국어 주석.
|
|
56
|
+
|
|
57
|
+
### Policy (사용자 명시)
|
|
58
|
+
- ❌ 환경변수 없이 LLM 자동 호출 금지
|
|
59
|
+
- ✅ 환경변수 감지 시에만 활성화 (사용자 동의 표명으로 간주)
|
|
60
|
+
- ✅ sub-agent 수는 사용자가 결정 (`--agents` 가변)
|
|
61
|
+
|
|
62
|
+
## 1.9.21 — 2026-05-14
|
|
63
|
+
|
|
64
|
+
**verify-claim 도메인 확장 hot fix** — `.cfg`/`.ini`/`.env`/`.toml`/`.lock`/`.conf`/`.properties` 추가.
|
|
65
|
+
|
|
3
66
|
## 1.9.20 — 2026-05-14
|
|
4
67
|
|
|
5
68
|
**verify-claim 정확도 + 도메인 확장 — Godot/jest/mocha 지원, verify-code --bench**.
|
package/README.md
CHANGED
|
@@ -1,123 +1,332 @@
|
|
|
1
1
|
# Leerness
|
|
2
2
|
|
|
3
|
-
> 한국어 우선 AI 개발 하네스.
|
|
3
|
+
> 한국어 우선 AI 개발 하네스. 멀티 에이전트 오케스트레이션 · 자동 검수 · 워크스페이스 가시성 · Ollama opt-in 통합.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/leerness) []() []() []()
|
|
6
|
+
|
|
7
|
+
## ⚙️ 설치 (Install)
|
|
8
|
+
|
|
9
|
+
> ⚠️ **leerness는 CLI 도구입니다.** `npm i leerness`로 로컬 설치만 하면 `leerness` 명령이 PATH에 없어 실패할 수 있습니다. 아래 셋 중 하나를 사용하세요:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# ✅ 1) 추천 — 설치 없이 즉시 실행 (npx 자동 캐시)
|
|
13
|
+
npx leerness@latest init . --language ko --skills recommended
|
|
14
|
+
|
|
15
|
+
# ✅ 2) 전역 설치 (한 번 설치 후 어디서나 leerness 명령)
|
|
16
|
+
npm i -g leerness
|
|
17
|
+
leerness --version
|
|
18
|
+
|
|
19
|
+
# ✅ 3) 로컬 dev dependency + npx로 실행
|
|
20
|
+
npm i --save-dev leerness
|
|
21
|
+
npx leerness handoff .
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> npmjs.com 페이지에 표시되는 `npm i leerness`는 라이브러리 import용입니다. CLI 명령(`leerness ...`)을 직접 호출하려면 위 3가지 중 하나가 필요합니다.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
**leerness가 해결하는 것**
|
|
29
|
+
- AI 에이전트가 거짓으로 "완료"를 보고하는 문제 → `verify-claim --run-tests`로 자동 검증
|
|
30
|
+
- 같은 함수를 다른 프로젝트에 중복 생성 → `reuse-map --all-apps --strict-elements`로 자동 감지
|
|
31
|
+
- 다음 세션이 컨텍스트를 잃는 문제 → handoff/current-state 3채널 자동 생성
|
|
32
|
+
- 멀티 에이전트 분담 시 누가 뭘 했는지 안 보임 → `handoff --all-apps --since 1h`
|
|
33
|
+
- LLM 컨텍스트 비용 → `--compact` 모드로 4KB → 500자
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🚀 60초 시작
|
|
6
38
|
|
|
7
39
|
```bash
|
|
8
|
-
# 신규 프로젝트
|
|
9
|
-
npx leerness init . --language ko --skills recommended
|
|
40
|
+
# 1) 신규 프로젝트 (npx 사용 — 설치 불필요)
|
|
41
|
+
npx leerness@latest init . --language ko --skills recommended
|
|
10
42
|
|
|
11
|
-
# 기존 leerness
|
|
43
|
+
# 2) 기존 leerness 프로젝트 자동 업그레이드
|
|
12
44
|
npx leerness@latest update . --yes
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
npx leerness
|
|
45
|
+
|
|
46
|
+
# 3) 매일 사용
|
|
47
|
+
npx leerness handoff . # 컨텍스트 적재
|
|
48
|
+
npx leerness audit . # 일관성 감사
|
|
49
|
+
npx leerness verify-claim T-0001 --run-tests # evidence 자동 검증
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 📊 적용 효과 (검증된 점수)
|
|
55
|
+
|
|
56
|
+
벤치마크 시뮬 결과 (`leerness-bench`로 측정):
|
|
57
|
+
|
|
58
|
+
| 카테고리 | leerness | vanilla | 차이 |
|
|
59
|
+
|---|---:|---:|---:|
|
|
60
|
+
| 멀티에이전트 효율 | 100/100 | 3/100 | **+97** |
|
|
61
|
+
| 검수 자동화 (1.5s vs 90s) | 98/100 | 0/100 | **+98** |
|
|
62
|
+
| 재사용 인식 (86 cap + 22 deps) | 100/100 | 0/100 | **+100** |
|
|
63
|
+
| 워크스페이스 가시성 (1 vs 64 명령) | 98/100 | 0/100 | **+98** |
|
|
64
|
+
| 버그 자동 감지 (158 신호) | 100/100 | 0/100 | **+100** |
|
|
65
|
+
| 컨텍스트 유지 (3채널) | 100/100 | 0/100 | **+100** |
|
|
66
|
+
| **종합** | **503/600** | **3/600** | **+500 (151×)** |
|
|
67
|
+
|
|
68
|
+
로컬 LLM 실측 (Ollama deepseek-coder-v2:16b):
|
|
69
|
+
- **HumanEval pass@1**: leerness 적용 **100%** vs 미적용 0%
|
|
70
|
+
- **SWE-bench style 정확도**: 87.5% vs 62.5%
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 📚 핵심 명령
|
|
75
|
+
|
|
76
|
+
### 작업 흐름
|
|
77
|
+
```bash
|
|
78
|
+
leerness handoff . # 세션 시작 — 컨텍스트 자동 적재
|
|
79
|
+
leerness handoff --all-apps --since 1h # 워크스페이스 + 최근 변경
|
|
80
|
+
leerness handoff --compact # LLM 프롬프트용 1줄 요약
|
|
81
|
+
leerness session close . # 세션 종료 — handoff 자동 작성
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 자동 검수 (핵심 기능)
|
|
85
|
+
```bash
|
|
86
|
+
leerness verify-claim T-0001 --run-tests # progress-tracker evidence 자동 검증 + npm test
|
|
87
|
+
leerness verify-code . --bench # test + lint + bench 일괄 실행
|
|
88
|
+
leerness audit . # 일관성/계획↔진행 감사
|
|
89
|
+
leerness lazy detect . # 거짓 완료 자동 감지
|
|
90
|
+
leerness gate . # verify + audit + scan + encoding + lazy 일괄
|
|
16
91
|
```
|
|
17
92
|
|
|
18
|
-
|
|
93
|
+
### 워크스페이스 (멀티 프로젝트)
|
|
94
|
+
```bash
|
|
95
|
+
leerness retro --all-apps # 전 프로젝트 회고
|
|
96
|
+
leerness reuse-map --all-apps # 중복 capability 자동 감지
|
|
97
|
+
leerness reuse-map --all-apps --strict-elements # 함수명 fuzzy 중복
|
|
98
|
+
leerness handoff --all-apps --since 24h # 최근 변경 워크스페이스 뷰
|
|
99
|
+
leerness brainstorm "키워드" --all-apps # 누적 데이터 검색
|
|
100
|
+
leerness insights --all-apps # 통계 + 안정성 평가
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 멀티 에이전트 (1.9.22, opt-in)
|
|
104
|
+
```bash
|
|
105
|
+
# 환경변수 설정 후 활성화 (자동 실행 절대 금지)
|
|
106
|
+
echo "LEERNESS_OLLAMA_BASE_URL=http://localhost:11434" >> .env
|
|
107
|
+
leerness orchestrate "<목표>" --agents 10 --model qwen2.5:7b-instruct
|
|
108
|
+
```
|
|
19
109
|
|
|
20
|
-
|
|
110
|
+
### 데이터 위생
|
|
111
|
+
```bash
|
|
112
|
+
leerness scan secrets . # AWS/GitHub/OpenAI/Anthropic/Google/Slack/PEM/하드코딩 패스워드
|
|
113
|
+
leerness encoding check . # BOM/UTF-16/한글 라운드트립
|
|
114
|
+
```
|
|
21
115
|
|
|
116
|
+
### 버전 관리
|
|
22
117
|
```bash
|
|
23
|
-
leerness
|
|
24
|
-
leerness
|
|
25
|
-
leerness
|
|
26
|
-
leerness audit . # 디자인/재사용/계획↔진행 정렬 감사
|
|
27
|
-
leerness check . # pre-action 체크
|
|
28
|
-
leerness scan secrets . # AWS/GitHub/OpenAI/Anthropic/Google/Slack/PEM/하드코딩 password 패턴
|
|
29
|
-
leerness encoding check . # UTF-8/BOM/UTF-16 BOM/NUL/.bat의 chcp 65001/한글 라운드트립
|
|
30
|
-
leerness lazy detect . # 증거 없는 done, 빈 handoff, 추적 없는 TODO/FIXME 자동 감지
|
|
31
|
-
leerness memory search "키" # decisions/log/handoff/plan/progress 즉시 grep
|
|
32
|
-
leerness session close . # 세션 종료 + handoff/current-state 자동 작성
|
|
33
|
-
leerness update --check # 24h 캐시 자동 버전 감지
|
|
34
|
-
leerness update --yes # 새 버전 자동 마이그레이션 + verify/audit
|
|
118
|
+
leerness update --check # 24h 캐시로 새 버전 감지
|
|
119
|
+
leerness update --yes # 자동 마이그레이션 + 검증
|
|
120
|
+
leerness update --from <tgz> # 오프라인/사내 미러
|
|
35
121
|
```
|
|
36
122
|
|
|
37
|
-
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 🤖 멀티 에이전트 오케스트레이션 (1.9.22)
|
|
126
|
+
|
|
127
|
+
### Opt-in 정책 ⚠
|
|
128
|
+
**LLM 호출은 사용자 명시적 동의 후에만 활성화**. 환경변수 미설정 시 명령 거부:
|
|
38
129
|
|
|
39
|
-
|
|
130
|
+
```bash
|
|
131
|
+
$ leerness orchestrate "test"
|
|
132
|
+
✗ LEERNESS_OLLAMA_BASE_URL 미설정 — orchestrate는 opt-in입니다.
|
|
133
|
+
정책 (1.9.22): 환경변수 없으면 LLM 호출 자동 시작 금지.
|
|
134
|
+
```
|
|
40
135
|
|
|
41
|
-
|
|
136
|
+
### 활성화
|
|
137
|
+
`.env` 파일에:
|
|
138
|
+
```bash
|
|
139
|
+
LEERNESS_OLLAMA_BASE_URL=http://localhost:11434
|
|
140
|
+
LEERNESS_OLLAMA_MODEL=qwen2.5:7b-instruct # 선택
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 가변 sub-agent 수
|
|
144
|
+
```bash
|
|
145
|
+
leerness orchestrate "함수 작성" --agents 3 # 작은 작업
|
|
146
|
+
leerness orchestrate "복잡한 기능" --agents 20 # 큰 작업
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
실측 병렬 효과:
|
|
150
|
+
- 3 agent: 1.9× / 5 agent: 3.2× / 10 agent: 5.5×
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 🔄 자동 버전 감지/업데이트
|
|
155
|
+
|
|
156
|
+
`init`/`migrate` 시 `.claude/settings.local.json`의 SessionStart hook에 `update --check` 자동 등록. 24시간 캐시(`.harness/cache/update-check.json`)로 npm 호출 폭주 방지.
|
|
42
157
|
|
|
43
158
|
| 명령 | 동작 |
|
|
44
159
|
|---|---|
|
|
45
|
-
| `leerness update --check` |
|
|
46
|
-
| `leerness update --yes` |
|
|
47
|
-
| `leerness update --from <tarball>` | 로컬
|
|
48
|
-
| `LEERNESS_OFFLINE=1`
|
|
160
|
+
| `leerness update --check` | `.harness/HARNESS_VERSION` ↔ `npm view leerness version` 비교 |
|
|
161
|
+
| `leerness update --yes` | 백업 → 마이그레이션 → `verify`/`audit` → `task-log`/`review-evidence` 누적 |
|
|
162
|
+
| `leerness update --from <tarball>` | 로컬 파일/오프라인/사내 미러 |
|
|
163
|
+
| `LEERNESS_OFFLINE=1` | npm 호출 건너뜀 |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 🛡 비파괴 마이그레이션 정책
|
|
49
168
|
|
|
50
|
-
|
|
169
|
+
- 모든 변경 전 `.harness/archive/leerness-<version>-<timestamp>/` 자동 백업
|
|
170
|
+
- 사용자 메모리 (`plan`, `progress`, `decisions`, `task-log`, `architecture`, `reuse-map` 등) **항상 보존**
|
|
171
|
+
- 관리 인스트럭션 (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/leerness.mdc`, `.github/copilot-instructions.md`)은 새 템플릿으로 머지하되 이전 내용을 `<!-- leerness:migration-preserved -->` 블록 안에 보존
|
|
172
|
+
- `.env.example` / `.gitignore` / `.gitattributes`는 라인 단위 머지
|
|
173
|
+
- 결과 보고: `.harness/migration-report.md`
|
|
51
174
|
|
|
52
|
-
|
|
53
|
-
- 사용자 메모리(plan / progress / current-state / decisions / task-log / architecture / context-map / feature-contracts / reuse-map / design-system 등) 기본 보존.
|
|
54
|
-
- 관리되는 인스트럭션(AGENTS.md, CLAUDE.md, .cursor/rules/leerness.mdc, .github/copilot-instructions.md)은 새 템플릿으로 머지하되 이전 내용을 `<!-- leerness:migration-preserved -->` 블록으로 보존.
|
|
55
|
-
- `.env.example`, `.gitignore`, `.gitattributes`는 라인 단위 머지.
|
|
56
|
-
- 결과 보고서: `.harness/migration-report.md`.
|
|
175
|
+
---
|
|
57
176
|
|
|
58
|
-
## 디렉토리 구조
|
|
177
|
+
## 📁 디렉토리 구조
|
|
59
178
|
|
|
60
179
|
```
|
|
61
180
|
.harness/
|
|
62
|
-
├── plan.md
|
|
63
|
-
├── decisions.md
|
|
64
|
-
├── guideline.md
|
|
65
|
-
├── architecture.md
|
|
66
|
-
├── design-system.md
|
|
67
|
-
├── anti-lazy-work-policy.md
|
|
68
|
-
├──
|
|
69
|
-
├──
|
|
70
|
-
├──
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
└── templates/{end-of-session-report.md, decision.md, task-row.md}
|
|
181
|
+
├── plan.md · progress-tracker.md · current-state.md · session-handoff.md
|
|
182
|
+
├── decisions.md · task-log.md · review-evidence.md
|
|
183
|
+
├── guideline.md · writeback-policy.md · context-routing.md
|
|
184
|
+
├── architecture.md · context-map.md · feature-contracts.md
|
|
185
|
+
├── design-system.md · consistency-policy.md · reuse-map.md
|
|
186
|
+
├── anti-lazy-work-policy.md · secret-policy.md · encoding-policy.md
|
|
187
|
+
├── protected-files.md · guardrails.md · language-policy.md
|
|
188
|
+
├── orchestrate-log.md (1.9.22+) · llm-bench-history.md (1.9.22+)
|
|
189
|
+
├── skill-index.md · skills/<id>/
|
|
190
|
+
└── templates/
|
|
191
|
+
|
|
74
192
|
.claude/
|
|
75
|
-
├── commands/
|
|
76
|
-
├── skills/leerness.md
|
|
77
|
-
└── settings.local.json (SessionStart + Stop hooks)
|
|
193
|
+
├── commands/ · skills/leerness.md · settings.local.json
|
|
78
194
|
.cursor/rules/leerness.mdc
|
|
79
195
|
.github/copilot-instructions.md
|
|
80
|
-
AGENTS.md
|
|
196
|
+
AGENTS.md · CLAUDE.md
|
|
81
197
|
```
|
|
82
198
|
|
|
83
|
-
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 🧪 자동 검수 도구 매트릭스
|
|
84
202
|
|
|
85
|
-
|
|
203
|
+
| 도구 | 검출 | 1.9.x 추가 |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `verify-claim T-XXX` | evidence의 파일 존재 + 테스트 카운트 ≥ 주장 | 1.9.18 |
|
|
206
|
+
| `verify-claim --run-tests` | + 실제 `npm test` 실행 + pass 파싱 (jest/mocha/한국어) | 1.9.19/20 |
|
|
207
|
+
| `reuse-map --strict-elements` | 함수명 동일 / capability 이름 다른 잠재 중복 | 1.9.18 |
|
|
208
|
+
| `handoff --since 24h` | 최근 변경된 T-row 자동 강조 | 1.9.18 |
|
|
209
|
+
| `verify-code --bench` | `scripts.bench` 자동 실행 + evidence 누적 | 1.9.20 |
|
|
210
|
+
| `lazy detect` | 증거 없는 done, 빈 handoff, 추적 없는 TODO | 1.9.7 |
|
|
211
|
+
| `orchestrate --agents N` | 다중 LLM 동시 호출 (opt-in) | 1.9.22 |
|
|
212
|
+
| `handoff --compact` | LLM 시스템 프롬프트용 압축 출력 | 1.9.22 |
|
|
86
213
|
|
|
87
|
-
|
|
88
|
-
2. 빈 핸드오프 금지
|
|
89
|
-
3. 부분 구현 자기보고 (`incomplete` 표기 + Next Exact Step 1줄)
|
|
90
|
-
4. 검증 기록 누적 (`review-evidence.md`)
|
|
91
|
-
5. 새 TODO/FIXME → progress-tracker에 동일 ID로 추적
|
|
92
|
-
6. 자동 감지: 증거 없는 done, 추적 없는 TODO, blocker 방치, 검증 흔적 부재
|
|
214
|
+
---
|
|
93
215
|
|
|
94
|
-
##
|
|
216
|
+
## 🧰 Anti-Lazy Work Policy
|
|
95
217
|
|
|
96
|
-
-
|
|
97
|
-
- `encoding check`: BOM, UTF-16 BOM, NUL, .bat의 chcp 65001 누락, 한글 텍스트의 UTF-8 라운드트립.
|
|
218
|
+
`anti-lazy-work-policy.md`의 6개 규칙 + `lazy detect`/`verify-claim` 자동 점검:
|
|
98
219
|
|
|
99
|
-
|
|
220
|
+
1. **증거 없는 완료 금지** — `evidence` 컬럼이 비었거나 plan-link만이면 경고
|
|
221
|
+
2. **빈 핸드오프 금지** — Completed/In Progress/Next Exact Step 모두 비어 있으면 `insufficient`
|
|
222
|
+
3. **부분 구현 자기보고** — `incomplete` 표기 + Next Exact Step 1줄
|
|
223
|
+
4. **검증 기록 누적** — `review-evidence.md`에 typecheck/lint/test 결과
|
|
224
|
+
5. **TODO 추적** — 새 TODO/FIXME → progress-tracker 동일 ID
|
|
225
|
+
6. **자동 감지** — 거짓 완료/추적 없는 TODO/blocker 방치/검증 흔적 부재
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 🤝 Claude Code 통합
|
|
100
230
|
|
|
101
231
|
설치 시 자동 등록:
|
|
102
|
-
- `.claude/commands/handoff
|
|
232
|
+
- `.claude/commands/{handoff, session-close, audit, lazy-detect, update}.md`
|
|
103
233
|
- `.claude/skills/leerness.md` — Claude Code 스킬 정의
|
|
104
|
-
- `.claude/settings.local.json` — SessionStart (`update --check`)
|
|
234
|
+
- `.claude/settings.local.json` — SessionStart hook (`update --check`)
|
|
235
|
+
- `.cursor/rules/leerness.mdc` — Cursor
|
|
236
|
+
- `.github/copilot-instructions.md` — Copilot
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 📦 스킬 라이브러리
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
leerness skill list
|
|
244
|
+
leerness skill info <id>
|
|
245
|
+
leerness skill add <id>
|
|
246
|
+
leerness skill learn <id> --doc <url> --command "..." --capability "..."
|
|
247
|
+
leerness skill optimize <id> --before "..." --after "..."
|
|
248
|
+
leerness skill consolidate
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
기본 카탈로그: `feature-implementation`, `ai-verified-skill-publisher`, `open-meteo`, `static-site-builder`, `project-roadmap-generator`, `office`, `commerce-api`, `crawling`, `firebase`, `ads-analytics`, `appstore-review`.
|
|
105
252
|
|
|
106
|
-
|
|
253
|
+
---
|
|
107
254
|
|
|
108
|
-
|
|
255
|
+
## 🌐 환경변수
|
|
256
|
+
|
|
257
|
+
| 변수 | 효과 |
|
|
258
|
+
|---|---|
|
|
259
|
+
| `LEERNESS_OFFLINE=1` | npm 호출 스킵 (오프라인) |
|
|
260
|
+
| `LEERNESS_NPM_TOKEN` | release publish용 (있을 때) |
|
|
261
|
+
| `LEERNESS_GITHUB_TOKEN` | gh release용 (있을 때) |
|
|
262
|
+
| **`LEERNESS_OLLAMA_BASE_URL`** | **1.9.22 — orchestrate opt-in 활성화** |
|
|
263
|
+
| `LEERNESS_OLLAMA_MODEL` | 기본 모델 (orchestrate `--model`로 override) |
|
|
109
264
|
|
|
110
|
-
|
|
265
|
+
---
|
|
111
266
|
|
|
112
|
-
##
|
|
267
|
+
## 🔧 자연어 트리거 → 명령 자동 매핑
|
|
268
|
+
|
|
269
|
+
| 사용자 발화 | 자동 실행 |
|
|
270
|
+
|---|---|
|
|
271
|
+
| "회고해줘 / 돌아보자" | `leerness retro` |
|
|
272
|
+
| "최근 N일 회고" | `leerness retro --days N` |
|
|
273
|
+
| "통계 / 누적 지표" | `leerness insights` |
|
|
274
|
+
| "X 관련 자료 / X 시작 전 검토" | `leerness brainstorm "X"` |
|
|
275
|
+
| "매 X마다 Y를 해줘" | `leerness rule add "Y" --trigger every-X` |
|
|
276
|
+
|
|
277
|
+
`AGENTS.md`에 자동 등록 — Claude Code/Cursor가 이를 보고 자연어를 명령으로 변환.
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## ❓ FAQ
|
|
282
|
+
|
|
283
|
+
**Q. leerness가 내 코드를 변경하나요?**
|
|
284
|
+
A. 사용자 메모리(plan/progress/decisions/architecture/reuse-map 등)는 **항상 보존**. 관리 인스트럭션(AGENTS.md/CLAUDE.md 등)은 머지 + 이전 내용을 preserved 블록으로 보존. 모든 변경 전 `.harness/archive/`에 자동 백업.
|
|
285
|
+
|
|
286
|
+
**Q. 로컬 LLM을 사용하지 않고 싶어요.**
|
|
287
|
+
A. 기본 동작입니다. `LEERNESS_OLLAMA_BASE_URL` 환경변수를 설정하지 않으면 LLM 호출 절대 발생 안 함. `orchestrate` 명령만 거부됩니다 (다른 명령은 LLM 없이 동작).
|
|
288
|
+
|
|
289
|
+
**Q. CI에서 사용 가능?**
|
|
290
|
+
A. 네. `--json` 옵션 (retro/insights/brainstorm/handoff/reuse-map/verify-claim) + `exit code`로 통합. `verify-claim T-XXX --run-tests --json | jq '.verdict.runTests'`.
|
|
291
|
+
|
|
292
|
+
**Q. 다른 워크스페이스 모드 명령은?**
|
|
293
|
+
A. `--all-apps`는 현재 디렉토리 + `_apps/*` (또는 부모의 `_apps/*`)의 모든 leerness 프로젝트를 발견. `--include p1,p2`로 명시도 가능.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 🧪 E2E
|
|
113
298
|
|
|
114
299
|
```bash
|
|
115
|
-
npm test
|
|
116
|
-
# = node ./scripts/e2e.js
|
|
300
|
+
npm test # = node ./scripts/e2e.js
|
|
117
301
|
```
|
|
118
302
|
|
|
119
|
-
|
|
303
|
+
**131/131 시나리오** 통과 (1.9.7~1.9.22 회귀 + 신규 검증).
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## 📜 변경 이력 (최근)
|
|
308
|
+
|
|
309
|
+
- **1.9.22** — Ollama opt-in 통합 (`orchestrate --agents N`), `handoff --compact`, `llm-bench record`
|
|
310
|
+
- **1.9.21** — `.cfg`/`.ini`/`.env`/`.toml`/`.lock` 메타 파일 verify-claim regex 확장
|
|
311
|
+
- **1.9.20** — Godot/jest/mocha 지원, `verify-code --bench`, file regex 도메인 폴더 자동 인식
|
|
312
|
+
- **1.9.19** — `verify-claim --run-tests` 동적 검증, `--strict-elements` same-file vs diff-file 구분
|
|
313
|
+
- **1.9.18** — `--since`, `--strict-elements`, `depends-on` 그래프, `verify-claim`
|
|
314
|
+
- **1.9.17** — `handoff/reuse-map --all-apps` 워크스페이스 모드
|
|
315
|
+
- **1.9.16** — `retro/insights/brainstorm --json` export
|
|
316
|
+
- **1.9.15** — `retro --all-apps` 워크스페이스 회고
|
|
317
|
+
- ... (전체 CHANGELOG.md 참조)
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 🤝 기여
|
|
322
|
+
|
|
323
|
+
- **이슈**: https://github.com/gugu9999gu/leerness/issues
|
|
324
|
+
- **PR**: e2e 통과 + 한국어 주석 + UTF-8 BOM 없음
|
|
325
|
+
|
|
326
|
+
---
|
|
120
327
|
|
|
121
328
|
## 라이선스
|
|
122
329
|
|
|
123
|
-
MIT
|
|
330
|
+
MIT — © leerness contributors
|
|
331
|
+
|
|
332
|
+
> **AI 에이전트를 잘 다루는 도구가 되도록 설계되었습니다.** 사용자 동의 없이 자동으로 외부 LLM/API를 호출하지 않습니다.
|
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.
|
|
9
|
+
const VERSION = '1.9.24';
|
|
10
10
|
const MARK = '<!-- leerness:managed -->';
|
|
11
11
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
12
12
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -1861,6 +1861,131 @@ async function orchestrateCmd(root, goalParts) {
|
|
|
1861
1861
|
log(`📜 누적 기록: .harness/orchestrate-log.md`);
|
|
1862
1862
|
}
|
|
1863
1863
|
|
|
1864
|
+
// 1.9.24: leerness deps <capability> — depends-on 그래프 역방향 추적 + 자동 회귀 sweep
|
|
1865
|
+
// 사용 예: leerness deps Character
|
|
1866
|
+
// → rpg-core/Character를 의존하는 모든 capability 식별 (rpg-net/Session, rpg-data/* 등)
|
|
1867
|
+
// → 영향받은 프로젝트의 npm test 자동 일괄 실행
|
|
1868
|
+
// → 회귀 발생 시 어느 프로젝트인지 즉시 보고
|
|
1869
|
+
function depsImpactCmd(root, targetCapability) {
|
|
1870
|
+
root = absRoot(root || process.cwd());
|
|
1871
|
+
if (!targetCapability) { fail('impact <capability> 필요. 예: leerness impact Character'); return process.exit(1); }
|
|
1872
|
+
const paths = _collectWorkspacePaths(root);
|
|
1873
|
+
if (!paths.length) {
|
|
1874
|
+
// --all-apps 자동
|
|
1875
|
+
process.argv.push('--all-apps');
|
|
1876
|
+
}
|
|
1877
|
+
const allPaths = _collectWorkspacePaths(root);
|
|
1878
|
+
if (!allPaths.length) return fail('워크스페이스 프로젝트 없음. _apps/* 또는 --include 사용.');
|
|
1879
|
+
|
|
1880
|
+
// 1) 모든 reuse-map에서 entries + depends-on 엣지 수집
|
|
1881
|
+
const allEntries = []; // { project, entry }
|
|
1882
|
+
const allEdges = []; // { fromProject, fromCap, toCap }
|
|
1883
|
+
for (const p of allPaths) {
|
|
1884
|
+
const entries = _readReuseMap(p);
|
|
1885
|
+
for (const e of entries) {
|
|
1886
|
+
allEntries.push({ project: path.basename(p), projectPath: p, entry: e });
|
|
1887
|
+
for (const dep of e.dependsOn) {
|
|
1888
|
+
allEdges.push({ fromProject: path.basename(p), fromCap: e.capability, toCap: dep });
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
// 2) targetCapability를 의존하는 capability 식별 (역방향)
|
|
1894
|
+
const target = String(targetCapability);
|
|
1895
|
+
const targetLower = target.toLowerCase();
|
|
1896
|
+
const directImpact = allEdges.filter(e => e.toCap.toLowerCase() === targetLower);
|
|
1897
|
+
const impactedProjects = new Set(directImpact.map(e => e.fromProject));
|
|
1898
|
+
|
|
1899
|
+
// 2단계 전이: 영향받은 capability를 또 의존하는 것들 (2-hop)
|
|
1900
|
+
const transitiveImpact = [];
|
|
1901
|
+
for (const e1 of directImpact) {
|
|
1902
|
+
for (const e2 of allEdges) {
|
|
1903
|
+
if (e2.toCap.toLowerCase() === e1.fromCap.toLowerCase()) {
|
|
1904
|
+
transitiveImpact.push({ via: e1.fromCap, ...e2 });
|
|
1905
|
+
impactedProjects.add(e2.fromProject);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
// target capability 자체가 어디 등록됐는지
|
|
1911
|
+
const definedAt = allEntries.filter(e => e.entry.capability.toLowerCase() === targetLower);
|
|
1912
|
+
|
|
1913
|
+
if (has('--json')) {
|
|
1914
|
+
log(JSON.stringify({
|
|
1915
|
+
target,
|
|
1916
|
+
definedAt: definedAt.map(d => ({ project: d.project, element: d.entry.element })),
|
|
1917
|
+
directImpact,
|
|
1918
|
+
transitiveImpact,
|
|
1919
|
+
impactedProjects: Array.from(impactedProjects)
|
|
1920
|
+
}, null, 2));
|
|
1921
|
+
return;
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
log(`# leerness impact "${target}" (1.9.24)`);
|
|
1925
|
+
log('');
|
|
1926
|
+
log(`## 정의 위치`);
|
|
1927
|
+
if (!definedAt.length) {
|
|
1928
|
+
log(` ⚠ "${target}" capability가 reuse-map에 등록되지 않음 — 영향 추적 불가`);
|
|
1929
|
+
return process.exit(1);
|
|
1930
|
+
}
|
|
1931
|
+
for (const d of definedAt) log(` - ${d.project}: ${d.entry.element}`);
|
|
1932
|
+
|
|
1933
|
+
log('');
|
|
1934
|
+
log(`## 직접 의존 (1-hop, ${directImpact.length}건)`);
|
|
1935
|
+
if (!directImpact.length) log(` (없음) — 단독 capability. 변경 안전.`);
|
|
1936
|
+
for (const e of directImpact) log(` - ${e.fromProject}/${e.fromCap}`);
|
|
1937
|
+
|
|
1938
|
+
if (transitiveImpact.length) {
|
|
1939
|
+
log('');
|
|
1940
|
+
log(`## 전이 의존 (2-hop, ${transitiveImpact.length}건)`);
|
|
1941
|
+
for (const e of transitiveImpact) log(` - ${e.fromProject}/${e.fromCap} (경유: ${e.via})`);
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
log('');
|
|
1945
|
+
log(`## 영향받는 프로젝트 (${impactedProjects.size}개)`);
|
|
1946
|
+
for (const p of impactedProjects) log(` - ${p}`);
|
|
1947
|
+
|
|
1948
|
+
// 3) --run-tests 옵션이면 영향받은 프로젝트의 npm test 일괄 실행
|
|
1949
|
+
if (has('--run-tests')) {
|
|
1950
|
+
log('');
|
|
1951
|
+
log(`## 🚦 자동 회귀 sweep (--run-tests)`);
|
|
1952
|
+
const results = [];
|
|
1953
|
+
for (const projName of impactedProjects) {
|
|
1954
|
+
const projPath = allPaths.find(p => path.basename(p) === projName);
|
|
1955
|
+
if (!projPath) continue;
|
|
1956
|
+
const pkgPath = path.join(projPath, 'package.json');
|
|
1957
|
+
if (!exists(pkgPath)) { log(` ⚠ ${projName}: package.json 없음 — skip`); continue; }
|
|
1958
|
+
let pkg = null;
|
|
1959
|
+
try { pkg = JSON.parse(read(pkgPath)); } catch {}
|
|
1960
|
+
if (!pkg?.scripts?.test) { log(` ⚠ ${projName}: scripts.test 없음 — skip`); continue; }
|
|
1961
|
+
const t0 = Date.now();
|
|
1962
|
+
const r = cp.spawnSync('npm test', [], { cwd: projPath, encoding: 'utf8', shell: true, timeout: 5 * 60 * 1000 });
|
|
1963
|
+
const elapsed = Date.now() - t0;
|
|
1964
|
+
const out = (r.stdout || '') + (r.stderr || '');
|
|
1965
|
+
const m = out.match(/(\d+)\s*\/\s*(\d+)\s*(?:passed|통과|pass|passing)/i);
|
|
1966
|
+
const passed = r.status === 0;
|
|
1967
|
+
results.push({ project: projName, passed, exit: r.status, elapsed, parsed: m ? { num: parseInt(m[1], 10), denom: parseInt(m[2], 10) } : null });
|
|
1968
|
+
const tag = passed ? '✓' : '✗';
|
|
1969
|
+
const ratio = m ? ` (${m[1]}/${m[2]})` : '';
|
|
1970
|
+
log(` ${tag} ${projName}: exit=${r.status}${ratio} ${elapsed}ms`);
|
|
1971
|
+
}
|
|
1972
|
+
log('');
|
|
1973
|
+
const pass = results.filter(r => r.passed).length;
|
|
1974
|
+
const fail = results.length - pass;
|
|
1975
|
+
log(`## 종합`);
|
|
1976
|
+
log(` - 영향받는 프로젝트 ${impactedProjects.size}개 중 ${pass}개 통과, ${fail}개 실패`);
|
|
1977
|
+
if (fail > 0) {
|
|
1978
|
+
log(` ⚠ ${target} 변경이 ${fail}개 프로젝트에 회귀 발생 가능 — 해당 프로젝트 testing 우선`);
|
|
1979
|
+
return process.exit(1);
|
|
1980
|
+
} else {
|
|
1981
|
+
log(` ✓ 모든 영향받는 프로젝트 회귀 없음 — ${target} 변경 안전`);
|
|
1982
|
+
}
|
|
1983
|
+
} else {
|
|
1984
|
+
log('');
|
|
1985
|
+
log(` 💡 \`--run-tests\` 옵션으로 영향받는 ${impactedProjects.size}개 프로젝트 npm test 자동 일괄 실행 가능`);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1864
1989
|
// 1.9.22 후보 4: llm-bench record + retro 통합
|
|
1865
1990
|
function llmBenchRecordCmd(root) {
|
|
1866
1991
|
root = absRoot(root || process.cwd());
|
|
@@ -3877,7 +4002,7 @@ function viewworkInstall(root) {
|
|
|
3877
4002
|
}
|
|
3878
4003
|
|
|
3879
4004
|
function help() {
|
|
3880
|
-
log(`Leerness v${VERSION}\n\nUsage:\n leerness init [path] [--language auto|ko|en] [--skills recommended|all|a,b]\n leerness migrate [path] [--dry-run] [--force]\n leerness update [path] [--check|--yes|--force|--from <tarball>]\n leerness auto-update install [path]\n leerness status [path]\n leerness verify [path]\n leerness debug [path]\n leerness audit [path]\n leerness check [path]\n leerness scan secrets [path]\n leerness encoding check [path]\n leerness lazy detect [path]\n leerness memory search "query" [--limit 5]\n leerness handoff [path] [--all-apps] [--include p1,p2] [--since 24h|3d] [--compact] [--json] # 1.9.17-22 워크스페이스 (--compact: LLM 시스템 프롬프트용 1줄 요약)\n leerness orchestrate "<목표>" [--agents N] [--model qwen2.5:7b-instruct] [--retry-on-fail K] # 1.9.22 Ollama opt-in (LEERNESS_OLLAMA_BASE_URL 필요)\n leerness llm-bench record --score N --model X [--label L] [--tokens T] # 1.9.22 LLM 벤치 히스토리 누적\n leerness reuse-map [path] [--all-apps] [--include p1,p2] [--strict-elements] [--json] # 1.9.18 중복/잠재중복/depends-on\n leerness verify-claim <T-ID> [--path .] [--run-tests] [--json] # 1.9.18-20 evidence 자동 검증 (1.9.20: scenes/scripts 등 도메인 폴더 + jest/mocha 파싱)\n leerness verify-code [path] [--build] [--bench] # 1.9.20 --bench: scripts.bench 추가 실행 + evidence 누적\n leerness session close [path]\n leerness viewwork install [path]\n leerness viewwork emit [path] [--action a] [--note n] [--agent x] [--tool t]\n leerness route <task-type>\n leerness self check [path]\n leerness readme sync [path]\n leerness consistency check [path]\n leerness consistency merge-design-guide [path]\n leerness plan show|init|add|drop|progress|sync [args]\n leerness task list|add|update|drop|fix-evidence|relink [args]\n leerness skill list|info <name>\n leerness skill learn <id> --doc <url> --command "..." --capability "..." [--note ...]\n leerness skill use <id> [--note ...]\n leerness skill optimize <id> --before "..." --after "..." [--note ...]\n leerness skill remove <id>\n leerness skill consolidate [--threshold 0.3]\n leerness gate [path] # verify+audit+scan+encoding+lazy
|
|
4005
|
+
log(`Leerness v${VERSION}\n\nUsage:\n leerness init [path] [--language auto|ko|en] [--skills recommended|all|a,b]\n leerness migrate [path] [--dry-run] [--force]\n leerness update [path] [--check|--yes|--force|--from <tarball>]\n leerness auto-update install [path]\n leerness status [path]\n leerness verify [path]\n leerness debug [path]\n leerness audit [path]\n leerness check [path]\n leerness scan secrets [path]\n leerness encoding check [path]\n leerness lazy detect [path]\n leerness memory search "query" [--limit 5]\n leerness handoff [path] [--all-apps] [--include p1,p2] [--since 24h|3d] [--compact] [--json] # 1.9.17-22 워크스페이스 (--compact: LLM 시스템 프롬프트용 1줄 요약)\n leerness orchestrate "<목표>" [--agents N] [--model qwen2.5:7b-instruct] [--retry-on-fail K] # 1.9.22 Ollama opt-in (LEERNESS_OLLAMA_BASE_URL 필요)\n leerness llm-bench record --score N --model X [--label L] [--tokens T] # 1.9.22 LLM 벤치 히스토리 누적\n leerness deps <capability> [--run-tests] [--json] # 1.9.24 depends-on 역방향 추적 + 자동 회귀 sweep\n leerness reuse-map [path] [--all-apps] [--include p1,p2] [--strict-elements] [--json] # 1.9.18 중복/잠재중복/depends-on\n leerness verify-claim <T-ID> [--path .] [--run-tests] [--json] # 1.9.18-20 evidence 자동 검증 (1.9.20: scenes/scripts 등 도메인 폴더 + jest/mocha 파싱)\n leerness verify-code [path] [--build] [--bench] # 1.9.20 --bench: scripts.bench 추가 실행 + evidence 누적\n leerness session close [path]\n leerness viewwork install [path]\n leerness viewwork emit [path] [--action a] [--note n] [--agent x] [--tool t]\n leerness route <task-type>\n leerness self check [path]\n leerness readme sync [path]\n leerness consistency check [path]\n leerness consistency merge-design-guide [path]\n leerness plan show|init|add|drop|progress|sync [args]\n leerness task list|add|update|drop|fix-evidence|relink [args]\n leerness skill list|info <name>\n leerness skill learn <id> --doc <url> --command "..." --capability "..." [--note ...]\n leerness skill use <id> [--note ...]\n leerness skill optimize <id> --before "..." --after "..." [--note ...]\n leerness skill remove <id>\n leerness skill consolidate [--threshold 0.3]\n leerness gate [path] # verify+audit+scan+encoding+lazy
|
|
3881
4006
|
leerness retro [path] [--days 7] [--all-apps] [--include p1,p2] [--json] # 회고 (1.9.13~1.9.16)
|
|
3882
4007
|
leerness insights [path] [--all-apps] [--include p1,p2] [--json] # 누적 통계 (1.9.13~1.9.16)
|
|
3883
4008
|
leerness brainstorm "<주제>" [--all-apps] [--include p1,p2] [--json] # 브레인스토밍 (1.9.13~1.9.16)
|
|
@@ -3915,6 +4040,7 @@ async function main() {
|
|
|
3915
4040
|
if (cmd === 'verify-claim') return verifyClaimCmd(arg('--path', process.cwd()), args[1]);
|
|
3916
4041
|
if (cmd === 'orchestrate') return await orchestrateCmd(arg('--path', process.cwd()), args.slice(1).filter(x => !x.startsWith('-')));
|
|
3917
4042
|
if (cmd === 'llm-bench' && args[1] === 'record') return llmBenchRecordCmd(arg('--path', process.cwd()));
|
|
4043
|
+
if (cmd === 'deps') return depsImpactCmd(arg('--path', process.cwd()), args[1]);
|
|
3918
4044
|
if (cmd === 'session' && args[1] === 'close') { const r = sessionClose(args[2] || process.cwd()); viewworkEmit(args[2] || process.cwd(), { action: 'task', tool: 'session-close', note: 'session close' }); return r; }
|
|
3919
4045
|
if (cmd === 'viewwork' && args[1] === 'install') return viewworkInstall(args[2] || process.cwd());
|
|
3920
4046
|
if (cmd === 'viewwork' && args[1] === 'emit') return viewworkEmit(args[2] || process.cwd(), { action: arg('--action','task'), note: arg('--note',''), agent: arg('--agent','leerness'), tool: arg('--tool','leerness-cli') });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.24",
|
|
4
4
|
"description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"author": "leerness contributors",
|
|
30
30
|
"type": "commonjs",
|
|
31
|
+
"main": "bin/harness.js",
|
|
32
|
+
"preferGlobal": true,
|
|
31
33
|
"engines": {
|
|
32
34
|
"node": ">=18"
|
|
33
35
|
},
|