leerness 1.9.175 → 1.9.176
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 +61 -0
- package/README.md +3 -3
- package/bin/harness.js +307 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.176 — 2026-05-21
|
|
4
|
+
|
|
5
|
+
**⚠ 사용자 명시: `leerness review-request` — 사용자 요구를 무조건 구현 전 사전 검토.**
|
|
6
|
+
|
|
7
|
+
사용자 명시: *"leerness가 적용된 프로젝트는 사용자의 요구를 무조건적으로 구현하기 전에, 충돌이 발생할 수 있는 부분이나 제작하고자 하는 기능 등을 구현하거나 설계할 때 더 효율적인 단계가 있는지 검토해보고 제시할 수도 있도록 설계"*.
|
|
8
|
+
|
|
9
|
+
### `leerness review-request "<request>"` — 9개 신호 분석
|
|
10
|
+
| 신호 | 데이터 소스 |
|
|
11
|
+
|---|---|
|
|
12
|
+
| **estimatedType** | route 키워드 매핑 (feature/bugfix/refactor/research/planning/release/consistency) |
|
|
13
|
+
| **conflicts** | lessons 실패 패턴 + 진행 중 task + taskLogFails |
|
|
14
|
+
| **reuseCandidates** | skills 매칭 + reuse-map 키워드 검색 |
|
|
15
|
+
| **lessonsRecall** | 과거 decisions + 관련 lessons |
|
|
16
|
+
| **planConflicts** | 진행 중 milestone (plan.md) |
|
|
17
|
+
| **featureConflicts** | feature_graph.md 영역 겹침 |
|
|
18
|
+
| **recommendedSteps** | 작업 유형별 3-4단계 권장 흐름 |
|
|
19
|
+
| **efficiencyHints** | 재사용/sub-agent/skill 활용 제안 |
|
|
20
|
+
| **proceed** | true (안전) / false (사용자 확인 필요) |
|
|
21
|
+
|
|
22
|
+
### 사용 예
|
|
23
|
+
```bash
|
|
24
|
+
$ leerness review-request "OAuth 로그인 구현해줘"
|
|
25
|
+
# leerness review-request (1.9.176 사전 검토)
|
|
26
|
+
요청: "OAuth 로그인 구현해줘"
|
|
27
|
+
추정 작업 유형: feature
|
|
28
|
+
|
|
29
|
+
## 💡 효율 제안
|
|
30
|
+
👥 leerness agents recommend feature — 작업 유형별 sub-agent 매핑 활용 가능
|
|
31
|
+
|
|
32
|
+
## 📍 권장 단계 (feature)
|
|
33
|
+
1) leerness reuse find "<핵심 capability>" — 중복 구현 사전 차단
|
|
34
|
+
2) leerness plan add "<milestone>" — 진행 추적
|
|
35
|
+
3) leerness contract verify SPEC.md src/<mod>.js — 사양 ↔ 구현 일치 검증
|
|
36
|
+
4) verify-claim --run-tests 로 evidence 의무화
|
|
37
|
+
|
|
38
|
+
## ▶ 진행 권장: ✓ 진행 안전
|
|
39
|
+
사유: 안전 — 충돌 신호 < 3 + plan 충돌 0
|
|
40
|
+
분석 소요: 938ms
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 통합 — 3 진입점
|
|
44
|
+
- **CLI**: `leerness review-request "<request>"` (또는 단축 `review-req`)
|
|
45
|
+
- **REPL**: `:review "<request>"` slash (1.9.175 흐름 연장)
|
|
46
|
+
- **MCP**: `leerness_review_request` (외부 AI 직접 호출 — **54번째 도구**)
|
|
47
|
+
|
|
48
|
+
### AGENTS.md / CLAUDE.md 강제 안내
|
|
49
|
+
```markdown
|
|
50
|
+
## ⚠ 사용자 요청 사전 검토 의무 (1.9.176 — 사용자 명시)
|
|
51
|
+
**사용자가 "X 구현해줘 / X 만들어줘 / X 추가해줘" 같은 요청을 줬을 때 무조건 즉시 구현하지 말 것.**
|
|
52
|
+
먼저 `leerness review-request "<요청>"` 호출 → 분석 결과 표시 → 사용자 확인 후 구현.
|
|
53
|
+
"그냥 바로 해줘 / review 건너뛰어줘" 명시 옵트아웃 시에만 review 생략.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Verified
|
|
57
|
+
- e2e 217/217 baseline 유지
|
|
58
|
+
- stress-v121: **23/23** (함수 정의 4 + router/help 2 + 실 동작 6 + REPL/MCP 3 + metadata 2 + 누적 회귀 6)
|
|
59
|
+
- 작업 유형 추정 정확도: feature/bugfix/refactor/research 4종 100% 매칭
|
|
60
|
+
- VERSION = 1.9.176 · MCP **54 도구** · autonomous-rounds = 106 · main 자동 push 37 라운드 연속
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
3
64
|
## 1.9.175 — 2026-05-21
|
|
4
65
|
|
|
5
66
|
**🌉 REPL Bridge Slash 3종 — `:web` / `:pc` / `:lsp` 즉시 호출.**
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **AI 코딩 에이전트의 거짓 완료·중복·망각·충돌을 막아주는 검수·기억·협업 CLI 하네스.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []() []() []() []() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
╔══════════════════════════════════════════════════════════════╗
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
║ ██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║ ║
|
|
13
13
|
║ ███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║ ║
|
|
14
14
|
║ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝ ║
|
|
15
|
-
║ v1.9.
|
|
15
|
+
║ v1.9.176 AI Agent Reliability Harness + Sandbox ║
|
|
16
16
|
║ verify · remember · orchestrate · audit · sandbox · drift ║
|
|
17
|
-
║
|
|
17
|
+
║ ⚠ review-request — 무조건 구현 전 충돌/효율 사전 검토 ║
|
|
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.
|
|
9
|
+
const VERSION = '1.9.176';
|
|
10
10
|
const MARK = '<!-- leerness:managed -->';
|
|
11
11
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
12
12
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -9845,7 +9845,8 @@ function mcpServeCmd(root) {
|
|
|
9845
9845
|
{ name: 'leerness_provider_remove', description: '1.9.159 — Provider Registry 에서 사용자 정의 provider 제거. 인자: { id (required), path? }. 빌트인 5종 id 는 제거 불가 (override 만 제거 가능). 🎉 MCP 50 도구 마일스톤 — Provider Registry CRUD MCP 완성 (list/add/remove)', inputSchema: { type: 'object', properties: { id: { type: 'string' }, path: { type: 'string' } }, required: ['id'] } },
|
|
9846
9846
|
{ name: 'leerness_web', description: '1.9.168 — Web Bridge (1.9.165 playwright opt-in). sub: check (설치 + permissions.browser 확인) | screenshot (URL → PNG) | extract (URL + CSS selector → DOM 텍스트). 외부 AI가 leerness 의 웹 자동화 능력을 직접 호출. playwright 미설치 시 친절 안내 (graceful). 인자: { sub (required), url?, out?, selector?, path? }', inputSchema: { type: 'object', properties: { sub: { type: 'string', enum: ['check', 'screenshot', 'extract'] }, url: { type: 'string' }, out: { type: 'string' }, selector: { type: 'string' }, path: { type: 'string' } }, required: ['sub'] } },
|
|
9847
9847
|
{ name: 'leerness_pc', description: '1.9.168 — PC Bridge (1.9.166 robotjs/nut-tree opt-in). sub: check (설치 + permissions.mouse/keyboard) | click (x,y) | type (text) | screenshot (out). ⚠ full permissions 권장 (mouse/keyboard 접근). 외부 AI가 데스크탑 자동화 능력을 직접 호출. 인자: { sub (required), x?, y?, text?, out?, path? }', inputSchema: { type: 'object', properties: { sub: { type: 'string', enum: ['check', 'click', 'type', 'screenshot'] }, x: { type: 'number' }, y: { type: 'number' }, text: { type: 'string' }, out: { type: 'string' }, path: { type: 'string' } }, required: ['sub'] } },
|
|
9848
|
-
{ name: 'leerness_lsp', description: '1.9.168 — LSP Bridge (1.9.167 typescript opt-in + regex fallback). sub: check (설치 여부) | symbols (file → function/class/interface/type/enum 목록) | references (name + in 디렉토리 → 호출 위치). 외부 AI가 코드 인텔리전스를 직접 호출 (의존성 0 fallback 동작). 🎉 MCP 53 도구 마일스톤. 인자: { sub (required), file?, name?, in?, path? }', inputSchema: { type: 'object', properties: { sub: { type: 'string', enum: ['check', 'symbols', 'references'] }, file: { type: 'string' }, name: { type: 'string' }, in: { type: 'string' }, path: { type: 'string' } }, required: ['sub'] } }
|
|
9848
|
+
{ name: 'leerness_lsp', description: '1.9.168 — LSP Bridge (1.9.167 typescript opt-in + regex fallback). sub: check (설치 여부) | symbols (file → function/class/interface/type/enum 목록) | references (name + in 디렉토리 → 호출 위치). 외부 AI가 코드 인텔리전스를 직접 호출 (의존성 0 fallback 동작). 🎉 MCP 53 도구 마일스톤. 인자: { sub (required), file?, name?, in?, path? }', inputSchema: { type: 'object', properties: { sub: { type: 'string', enum: ['check', 'symbols', 'references'] }, file: { type: 'string' }, name: { type: 'string' }, in: { type: 'string' }, path: { type: 'string' } }, required: ['sub'] } },
|
|
9849
|
+
{ name: 'leerness_review_request', description: '1.9.176 — 사용자 요청 사전 검토 (사용자 명시 요청). AI 에이전트가 사용자 요구를 **무조건 구현 전**에 호출. 분석: 1) estimatedType (route 추정), 2) conflicts (lesson 실패/진행중 task), 3) reuseCandidates (skill/reuse-map 매칭), 4) lessonsRecall (과거 결정), 5) planConflicts (진행중 milestone), 6) featureConflicts (feature graph 영역 겹침), 7) recommendedSteps (작업 유형별 3-5 단계), 8) efficiencyHints, 9) proceed (true/false). 사용자 결정 도움. 인자: { request (required), path? }', inputSchema: { type: 'object', properties: { request: { type: 'string' }, path: { type: 'string' } }, required: ['request'] } }
|
|
9849
9850
|
];
|
|
9850
9851
|
|
|
9851
9852
|
function send(obj) {
|
|
@@ -9973,6 +9974,10 @@ function mcpServeCmd(root) {
|
|
|
9973
9974
|
if (args.name) cliArgs.splice(2, 0, String(args.name));
|
|
9974
9975
|
if (args.in) cliArgs.push('--in', String(args.in));
|
|
9975
9976
|
break;
|
|
9977
|
+
case 'leerness_review_request':
|
|
9978
|
+
// 1.9.176: 사용자 요청 사전 검토 (사용자 명시 요청)
|
|
9979
|
+
cliArgs = ['review-request', String(args.request || ''), '--path', targetPath, '--json'];
|
|
9980
|
+
break;
|
|
9976
9981
|
default:
|
|
9977
9982
|
return send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Unknown tool: ${name}` } });
|
|
9978
9983
|
}
|
|
@@ -11007,6 +11012,7 @@ async function _agentRepl(root, opts) {
|
|
|
11007
11012
|
log(C.dim(' 🆕 1.9.170 — Tab=provider cycle, Shift+Tab=model cycle, :stream on|off (실시간 출력)'));
|
|
11008
11013
|
log(C.dim(' 🆕 1.9.174 — :permissions [basic|extended|full] 로 즉시 권한 변경 (default: basic 안전)'));
|
|
11009
11014
|
log(C.dim(' 🆕 1.9.175 — :web / :pc / :lsp 으로 Bridge 3종 REPL 안에서 즉시 호출 (코드 분석/웹/PC)'));
|
|
11015
|
+
log(C.dim(' 🆕 1.9.176 — :review "<요청>" 으로 사용자 요청 사전 검토 (충돌/재사용/효율/권장 단계)'));
|
|
11010
11016
|
log(C.dim(` 현재 — provider=${state.provider} model=${state.model || '(기본)'} role=${state.role} permissions=${_readPermissions(root).mode}`));
|
|
11011
11017
|
// 1.9.155: REPL 진입 시 handoff 컨텍스트 자동 노출 (UX 개선 — 사용자가 매번 :handoff 안 해도 컨텍스트 인지)
|
|
11012
11018
|
try {
|
|
@@ -11127,6 +11133,8 @@ async function _agentRepl(root, opts) {
|
|
|
11127
11133
|
log(' :brainstorm <topic> — leerness brainstorm "topic" (관련 컨텍스트 회수)');
|
|
11128
11134
|
log(' :tasks — leerness task list (현재 task 상태)');
|
|
11129
11135
|
log(' :plan — leerness plan show (현재 milestone)');
|
|
11136
|
+
log(C.bold('\n 🆕 Review Slash (1.9.176) — 사용자 요청 사전 검토:'));
|
|
11137
|
+
log(' :review "<request>" — 충돌/재사용/효율/권장 단계 분석 후 구현 권장');
|
|
11130
11138
|
log(C.bold('\n 🆕 Bridge Slash (1.9.175) — REPL 안에서 즉시 Bridge 호출:'));
|
|
11131
11139
|
log(' :web check — playwright 설치 확인 (opt-in)');
|
|
11132
11140
|
log(' :web screenshot <url> [--out f.png] — URL → PNG');
|
|
@@ -11317,6 +11325,27 @@ async function _agentRepl(root, opts) {
|
|
|
11317
11325
|
return false;
|
|
11318
11326
|
}
|
|
11319
11327
|
|
|
11328
|
+
// 1.9.176: :review <request> — 사용자 요청 사전 검토 slash (사용자 명시)
|
|
11329
|
+
// "이거 구현해줘" 같은 요청을 받으면 AI 가 먼저 :review 호출 → 충돌/재사용/효율 분석.
|
|
11330
|
+
if (op === 'review') {
|
|
11331
|
+
const reqText = rest.join(' ').trim();
|
|
11332
|
+
if (!reqText) {
|
|
11333
|
+
log(C.yel(` ⚠ :review 는 요청 텍스트 필요 — 예: :review "OAuth 로그인 추가"`));
|
|
11334
|
+
return false;
|
|
11335
|
+
}
|
|
11336
|
+
log(C.dim(` → leerness review-request "${reqText.slice(0, 60)}${reqText.length > 60 ? '…' : ''}"`));
|
|
11337
|
+
const t0 = Date.now();
|
|
11338
|
+
const r = runCommandSafe(process.execPath, [__filename, 'review-request', reqText, '--path', root], {
|
|
11339
|
+
cwd: root, root, timeout: 30000, kind: 'agent_repl_slash', label: 'repl-review',
|
|
11340
|
+
env: { LEERNESS_NO_BANNER: '1', LEERNESS_NO_PROMPT: '1', LEERNESS_NO_DRIFT_CHECK: '1' }
|
|
11341
|
+
});
|
|
11342
|
+
const dt = Date.now() - t0;
|
|
11343
|
+
if (r.stdout) log(r.stdout.trim().split('\n').slice(0, 60).join('\n'));
|
|
11344
|
+
if (r.status === 0) log(C.green(` ✓ :review 완료 (${dt}ms)`));
|
|
11345
|
+
else log(C.yel(` ⚠ :review 실패 (exit ${r.status}, ${dt}ms)`));
|
|
11346
|
+
return false;
|
|
11347
|
+
}
|
|
11348
|
+
|
|
11320
11349
|
// 1.9.150: leerness 내부 명령 slash-commands — :verify / :audit / :handoff / :health
|
|
11321
11350
|
// 1.9.161: Memory Surface 조회 slash 추가 — :lessons / :brainstorm / :tasks / :plan
|
|
11322
11351
|
if (op === 'verify' || op === 'audit' || op === 'handoff' || op === 'health'
|
|
@@ -12825,6 +12854,274 @@ function lspCmd(root, sub, ...args) {
|
|
|
12825
12854
|
fail(`알 수 없는 sub: ${sub} (check / symbols / references)`);
|
|
12826
12855
|
}
|
|
12827
12856
|
|
|
12857
|
+
// 1.9.176: 사용자 요청 사전 검토 (사용자 명시 요청)
|
|
12858
|
+
// AI 에이전트가 사용자 요구를 **무조건 구현하기 전**에 먼저:
|
|
12859
|
+
// 1) 충돌 위험 (같은 키워드의 과거 실패/lessons)
|
|
12860
|
+
// 2) 기존 자원 재사용 후보 (reuse-map / skills)
|
|
12861
|
+
// 3) 더 효율적인 단계 제안 (route + plan)
|
|
12862
|
+
// 4) 권장 단계 리스트 (작업 유형별)
|
|
12863
|
+
// 를 분석하여 사용자에게 제시. 사용자 결정 후 구현 진행.
|
|
12864
|
+
//
|
|
12865
|
+
// 사용 예:
|
|
12866
|
+
// leerness review-request "OAuth 로그인 구현해줘"
|
|
12867
|
+
// leerness review-request "..." --json # MCP/외부 AI 통합
|
|
12868
|
+
//
|
|
12869
|
+
// REPL: :review <request> (1.9.175 slash 패턴)
|
|
12870
|
+
// MCP : leerness_review_request (외부 AI 직접 호출)
|
|
12871
|
+
function reviewRequestCmd(root, request) {
|
|
12872
|
+
root = absRoot(root || process.cwd());
|
|
12873
|
+
if (!request || !String(request).trim()) {
|
|
12874
|
+
return fail('leerness review-request "<request>" — 사용자 요청 텍스트 필요');
|
|
12875
|
+
}
|
|
12876
|
+
const t0 = Date.now();
|
|
12877
|
+
const text = String(request).trim();
|
|
12878
|
+
|
|
12879
|
+
// 1) 작업 유형 추정 (route 기반 키워드 매핑)
|
|
12880
|
+
const lower = text.toLowerCase();
|
|
12881
|
+
const routeKw = {
|
|
12882
|
+
bugfix: ['버그', '오류', '에러', '수정', '고쳐', '실패', 'fix', 'bug', 'error'],
|
|
12883
|
+
refactor: ['리팩토', '재구성', '정리', '개선', 'refactor', 'cleanup'],
|
|
12884
|
+
feature: ['추가', '구현', '만들', '새', '기능', 'add', 'implement', 'feature', 'create', 'new'],
|
|
12885
|
+
research: ['조사', '분석', '비교', '검토', '연구', 'research', 'analyze', 'compare', 'investigate'],
|
|
12886
|
+
planning: ['계획', '설계', '로드맵', 'plan', 'design', 'architecture', 'roadmap'],
|
|
12887
|
+
release: ['배포', '릴리즈', '버전', 'release', 'deploy', 'publish'],
|
|
12888
|
+
consistency: ['일관성', '통합', '동기화', '맞춰', 'consistency', 'sync', 'align']
|
|
12889
|
+
};
|
|
12890
|
+
let estimatedType = 'feature'; // default
|
|
12891
|
+
let maxScore = 0;
|
|
12892
|
+
for (const [type, kws] of Object.entries(routeKw)) {
|
|
12893
|
+
const score = kws.filter(k => lower.includes(k)).length;
|
|
12894
|
+
if (score > maxScore) { maxScore = score; estimatedType = type; }
|
|
12895
|
+
}
|
|
12896
|
+
|
|
12897
|
+
// 2) 기존 자원 회수 — brainstorm spawn (모든 surface 통합 회수)
|
|
12898
|
+
const conflictHints = []; // ⚠ 같은 키워드 + 실패/오류 패턴
|
|
12899
|
+
const reuseCandidates = []; // 🔁 기존 skill / reuse-map / decision 후보
|
|
12900
|
+
const lessonsRecall = []; // 🧠 과거 lesson
|
|
12901
|
+
const planConflicts = []; // 📋 진행 중 milestone과 충돌 가능
|
|
12902
|
+
|
|
12903
|
+
// brainstorm 호출 (1.9.13~) — JSON 결과 회수
|
|
12904
|
+
try {
|
|
12905
|
+
const r = cp.spawnSync(process.execPath, [__filename, 'brainstorm', text, '--path', root, '--json'], {
|
|
12906
|
+
encoding: 'utf8', timeout: 12000,
|
|
12907
|
+
env: { ...process.env, LEERNESS_NO_BANNER: '1', LEERNESS_NO_PROMPT: '1', LEERNESS_NO_DRIFT_CHECK: '1' }
|
|
12908
|
+
});
|
|
12909
|
+
if (r.stdout) {
|
|
12910
|
+
const j = JSON.parse(r.stdout);
|
|
12911
|
+
const hits = j.hits || {};
|
|
12912
|
+
// decisions — 과거 결정 후보
|
|
12913
|
+
(hits.decisions || []).slice(0, 5).forEach(d => {
|
|
12914
|
+
lessonsRecall.push({ kind: 'decision', title: d.title, line: d.line, preview: (d.preview || '').slice(0, 100) });
|
|
12915
|
+
});
|
|
12916
|
+
// lessons — 과거 교훈 (특히 실패 키워드)
|
|
12917
|
+
(hits.lessons || []).slice(0, 5).forEach(l => {
|
|
12918
|
+
const preview = (l.text || l.preview || '').slice(0, 100);
|
|
12919
|
+
const isFailure = /실패|오류|에러|fail|error|bug|문제|warning/i.test(preview);
|
|
12920
|
+
if (isFailure) {
|
|
12921
|
+
conflictHints.push({ kind: 'lesson-failure', preview, tags: l.tags });
|
|
12922
|
+
} else {
|
|
12923
|
+
lessonsRecall.push({ kind: 'lesson', preview, tags: l.tags });
|
|
12924
|
+
}
|
|
12925
|
+
});
|
|
12926
|
+
// skills — 기존 skill 후보
|
|
12927
|
+
(hits.skills || []).slice(0, 3).forEach(s => {
|
|
12928
|
+
reuseCandidates.push({ kind: 'skill', id: s.id, displayNameKo: s.displayNameKo, capabilities: s.capabilities });
|
|
12929
|
+
});
|
|
12930
|
+
// tasks — 진행 중 task 충돌
|
|
12931
|
+
(hits.tasks || []).slice(0, 3).forEach(tsk => {
|
|
12932
|
+
if (tsk.status && /in-progress|진행/.test(String(tsk.status))) {
|
|
12933
|
+
conflictHints.push({ kind: 'task-in-progress', id: tsk.id, title: tsk.title });
|
|
12934
|
+
}
|
|
12935
|
+
});
|
|
12936
|
+
// plan milestones — 진행 중 milestone
|
|
12937
|
+
(hits.planMilestones || []).slice(0, 3).forEach(m => {
|
|
12938
|
+
if (m.status && /in-progress|진행/.test(String(m.status))) {
|
|
12939
|
+
planConflicts.push({ kind: 'milestone-in-progress', id: m.id, title: m.title });
|
|
12940
|
+
}
|
|
12941
|
+
});
|
|
12942
|
+
// taskLogFails — 과거 같은 키워드 실패 흔적
|
|
12943
|
+
(hits.taskLogFails || []).slice(0, 3).forEach(f => {
|
|
12944
|
+
conflictHints.push({ kind: 'task-log-failure', preview: (f.preview || f.text || '').slice(0, 100) });
|
|
12945
|
+
});
|
|
12946
|
+
}
|
|
12947
|
+
} catch {}
|
|
12948
|
+
|
|
12949
|
+
// 3) reuse-map 매칭 — 기존 capability 등록 후보
|
|
12950
|
+
try {
|
|
12951
|
+
const reusePath = path.join(root, '.harness/reuse-map.md');
|
|
12952
|
+
if (exists(reusePath)) {
|
|
12953
|
+
const reuseLines = read(reusePath).split('\n');
|
|
12954
|
+
const tokens = lower.split(/\s+/).filter(t => t.length >= 3);
|
|
12955
|
+
for (const line of reuseLines) {
|
|
12956
|
+
if (!/^\| /.test(line)) continue; // 테이블 row만
|
|
12957
|
+
const ll = line.toLowerCase();
|
|
12958
|
+
const matched = tokens.filter(t => ll.includes(t)).length;
|
|
12959
|
+
if (matched > 0) {
|
|
12960
|
+
const cols = line.split('|').map(s => s.trim());
|
|
12961
|
+
if (cols[1]) {
|
|
12962
|
+
reuseCandidates.push({ kind: 'reuse-map', capability: cols[1], where: cols[2] || '', note: cols[3] || '' });
|
|
12963
|
+
}
|
|
12964
|
+
}
|
|
12965
|
+
}
|
|
12966
|
+
}
|
|
12967
|
+
} catch {}
|
|
12968
|
+
|
|
12969
|
+
// 4) feature_graph — 같은 영역 변경 가능성
|
|
12970
|
+
const featureConflicts = [];
|
|
12971
|
+
try {
|
|
12972
|
+
const fgPath = path.join(root, '.harness/feature_graph.md');
|
|
12973
|
+
if (exists(fgPath)) {
|
|
12974
|
+
const fg = read(fgPath);
|
|
12975
|
+
const tokens = lower.split(/\s+/).filter(t => t.length >= 4);
|
|
12976
|
+
// F-XXXX 노드 라인 추출
|
|
12977
|
+
const nodeBlocks = fg.split(/\n### /);
|
|
12978
|
+
for (const blk of nodeBlocks.slice(1)) {
|
|
12979
|
+
const bl = blk.toLowerCase();
|
|
12980
|
+
const matched = tokens.filter(t => bl.includes(t)).length;
|
|
12981
|
+
if (matched > 0) {
|
|
12982
|
+
const titleMatch = blk.match(/^([^\n]+)/);
|
|
12983
|
+
const idMatch = blk.match(/F-\d+/);
|
|
12984
|
+
if (titleMatch && idMatch) {
|
|
12985
|
+
featureConflicts.push({ kind: 'feature', id: idMatch[0], title: titleMatch[1].trim() });
|
|
12986
|
+
}
|
|
12987
|
+
}
|
|
12988
|
+
}
|
|
12989
|
+
}
|
|
12990
|
+
} catch {}
|
|
12991
|
+
|
|
12992
|
+
// 5) 권장 단계 (작업 유형별)
|
|
12993
|
+
const recommendedSteps = {
|
|
12994
|
+
feature: [
|
|
12995
|
+
'1) leerness reuse find "<핵심 capability>" — 중복 구현 사전 차단',
|
|
12996
|
+
'2) leerness plan add "<milestone>" — 진행 추적',
|
|
12997
|
+
'3) leerness contract verify SPEC.md src/<mod>.js — 사양 ↔ 구현 일치 검증',
|
|
12998
|
+
'4) verify-claim --run-tests 로 evidence 의무화'
|
|
12999
|
+
],
|
|
13000
|
+
bugfix: [
|
|
13001
|
+
'1) leerness brainstorm "<버그 키워드>" — 과거 같은 영역 lesson 회수',
|
|
13002
|
+
'2) leerness verify-claim T-XXX --strict-claims — 낙관적 표시 사전 감지',
|
|
13003
|
+
'3) verify-code --run-tests — 재현 + fix 검증',
|
|
13004
|
+
'4) leerness lesson save "<root cause>" — 같은 실수 재발 차단'
|
|
13005
|
+
],
|
|
13006
|
+
refactor: [
|
|
13007
|
+
'1) leerness reuse-map — 영향 범위 파악',
|
|
13008
|
+
'2) leerness impact <file> — 강한/약한 참조 분리',
|
|
13009
|
+
'3) leerness contract verify — 외부 인터페이스 보존 확인',
|
|
13010
|
+
'4) verify-code --run-tests + 회귀 테스트'
|
|
13011
|
+
],
|
|
13012
|
+
research: [
|
|
13013
|
+
'1) leerness brainstorm "<주제>" — 누적 컨텍스트 회수',
|
|
13014
|
+
'2) leerness lessons --query "<주제>" — 과거 같은 영역 결정',
|
|
13015
|
+
'3) leerness review <file> --persona research — 깊이 검토',
|
|
13016
|
+
'4) leerness decision add "<결론>" — 회수 가능하게 영구화'
|
|
13017
|
+
],
|
|
13018
|
+
planning: [
|
|
13019
|
+
'1) leerness plan add "<milestone>" — 분해 시작',
|
|
13020
|
+
'2) leerness reuse-map — 기존 자원 인벤토리',
|
|
13021
|
+
'3) leerness agents recommend planning — sub-agent 분배',
|
|
13022
|
+
'4) leerness session close — 결정 영구화'
|
|
13023
|
+
],
|
|
13024
|
+
release: [
|
|
13025
|
+
'1) leerness health — production-ready 확인',
|
|
13026
|
+
'2) leerness audit + verify-code — 보안 + 검수',
|
|
13027
|
+
'3) leerness release bump + note + publish'
|
|
13028
|
+
],
|
|
13029
|
+
consistency: [
|
|
13030
|
+
'1) leerness audit — design/reuse/handoff 일관성 검사',
|
|
13031
|
+
'2) leerness consistency check — 잠재 일관성 위반',
|
|
13032
|
+
'3) leerness drift check --auto-fix — 자동 회복'
|
|
13033
|
+
]
|
|
13034
|
+
}[estimatedType] || [];
|
|
13035
|
+
|
|
13036
|
+
// 6) 효율 제안 (적용 가능한 sub-agent + skill)
|
|
13037
|
+
const efficiencyHints = [];
|
|
13038
|
+
if (reuseCandidates.length > 0) {
|
|
13039
|
+
efficiencyHints.push(`🔁 기존 자원 ${reuseCandidates.length}건 발견 — 신규 구현 전 재사용 검토 권장`);
|
|
13040
|
+
}
|
|
13041
|
+
if (conflictHints.length > 0) {
|
|
13042
|
+
efficiencyHints.push(`⚠ 충돌 신호 ${conflictHints.length}건 — 과거 실패 lesson / 진행 중 task 확인 필요`);
|
|
13043
|
+
}
|
|
13044
|
+
if (planConflicts.length > 0) {
|
|
13045
|
+
efficiencyHints.push(`📋 진행 중 milestone ${planConflicts.length}건과 영역 겹침 가능 — plan 정렬 권장`);
|
|
13046
|
+
}
|
|
13047
|
+
if (featureConflicts.length > 0) {
|
|
13048
|
+
efficiencyHints.push(`🕸 Feature Graph ${featureConflicts.length}건 영역 겹침 — 의존성 사전 확인`);
|
|
13049
|
+
}
|
|
13050
|
+
// 다중 에이전트 분배 추천
|
|
13051
|
+
if (estimatedType === 'feature' || estimatedType === 'planning') {
|
|
13052
|
+
efficiencyHints.push(`👥 leerness agents recommend ${estimatedType} — 작업 유형별 sub-agent 매핑 활용 가능`);
|
|
13053
|
+
}
|
|
13054
|
+
if (efficiencyHints.length === 0) {
|
|
13055
|
+
efficiencyHints.push('✨ 충돌 신호 없음 — 즉시 진행 안전');
|
|
13056
|
+
}
|
|
13057
|
+
|
|
13058
|
+
// 7) proceed 권장 (충돌 critical 시 false)
|
|
13059
|
+
const proceed = conflictHints.length < 3 && planConflicts.length === 0;
|
|
13060
|
+
|
|
13061
|
+
const dt = Date.now() - t0;
|
|
13062
|
+
const out = {
|
|
13063
|
+
request: text,
|
|
13064
|
+
estimatedType,
|
|
13065
|
+
conflicts: conflictHints,
|
|
13066
|
+
reuseCandidates,
|
|
13067
|
+
lessonsRecall,
|
|
13068
|
+
planConflicts,
|
|
13069
|
+
featureConflicts,
|
|
13070
|
+
recommendedSteps,
|
|
13071
|
+
efficiencyHints,
|
|
13072
|
+
proceed,
|
|
13073
|
+
proceedReason: proceed ? '안전 — 충돌 신호 < 3 + plan 충돌 0' : '⚠ 충돌 critical — 사용자 확인 후 진행',
|
|
13074
|
+
durationMs: dt
|
|
13075
|
+
};
|
|
13076
|
+
|
|
13077
|
+
try { _recordRun(root, { kind: 'review_request', estimatedType, conflicts: conflictHints.length, reuse: reuseCandidates.length, durationMs: dt, ok: true }); } catch {}
|
|
13078
|
+
|
|
13079
|
+
if (has('--json')) {
|
|
13080
|
+
log(JSON.stringify(out, null, 2));
|
|
13081
|
+
return;
|
|
13082
|
+
}
|
|
13083
|
+
|
|
13084
|
+
log(`# leerness review-request (1.9.176 사전 검토)`);
|
|
13085
|
+
log(`요청: "${text.slice(0, 200)}${text.length > 200 ? '…' : ''}"`);
|
|
13086
|
+
log(`추정 작업 유형: ${estimatedType}`);
|
|
13087
|
+
log('');
|
|
13088
|
+
if (conflictHints.length) {
|
|
13089
|
+
log(`## ⚠ 충돌 신호 (${conflictHints.length})`);
|
|
13090
|
+
conflictHints.slice(0, 5).forEach(c => log(` - [${c.kind}] ${c.title || c.id || ''} ${c.preview || ''}`.trim()));
|
|
13091
|
+
log('');
|
|
13092
|
+
}
|
|
13093
|
+
if (reuseCandidates.length) {
|
|
13094
|
+
log(`## 🔁 재사용 후보 (${reuseCandidates.length}) — 신규 구현 전 검토`);
|
|
13095
|
+
reuseCandidates.slice(0, 5).forEach(r => {
|
|
13096
|
+
if (r.kind === 'skill') log(` - [skill] ${r.id}${r.displayNameKo ? ' · ' + r.displayNameKo : ''}`);
|
|
13097
|
+
else if (r.kind === 'reuse-map') log(` - [reuse] ${r.capability} @ ${r.where}`);
|
|
13098
|
+
});
|
|
13099
|
+
log('');
|
|
13100
|
+
}
|
|
13101
|
+
if (lessonsRecall.length) {
|
|
13102
|
+
log(`## 🧠 과거 컨텍스트 (${lessonsRecall.length}) — 관련 결정/교훈`);
|
|
13103
|
+
lessonsRecall.slice(0, 3).forEach(l => log(` - [${l.kind}] ${l.title || l.preview}`));
|
|
13104
|
+
log('');
|
|
13105
|
+
}
|
|
13106
|
+
if (planConflicts.length || featureConflicts.length) {
|
|
13107
|
+
log(`## 📋 진행 중 영역 (${planConflicts.length + featureConflicts.length})`);
|
|
13108
|
+
planConflicts.forEach(m => log(` - [milestone] ${m.id}: ${m.title}`));
|
|
13109
|
+
featureConflicts.slice(0, 5).forEach(f => log(` - [feature] ${f.id}: ${f.title}`));
|
|
13110
|
+
log('');
|
|
13111
|
+
}
|
|
13112
|
+
log(`## 💡 효율 제안`);
|
|
13113
|
+
efficiencyHints.forEach(h => log(` ${h}`));
|
|
13114
|
+
log('');
|
|
13115
|
+
if (recommendedSteps.length) {
|
|
13116
|
+
log(`## 📍 권장 단계 (${estimatedType})`);
|
|
13117
|
+
recommendedSteps.forEach(s => log(` ${s}`));
|
|
13118
|
+
log('');
|
|
13119
|
+
}
|
|
13120
|
+
log(`## ▶ 진행 권장: ${proceed ? '✓ 진행 안전' : '⚠ 사용자 확인 필요'}`);
|
|
13121
|
+
log(` 사유: ${out.proceedReason}`);
|
|
13122
|
+
log(` 분석 소요: ${dt}ms`);
|
|
13123
|
+
}
|
|
13124
|
+
|
|
12828
13125
|
// 1.9.164: leerness which — 진단 도구 (구버전 충돌 / npx 캐시 / PATH 충돌 해결)
|
|
12829
13126
|
// 사용자가 "최신 버전 작동 안 함" 의심 시: 실제 실행 중인 leerness 의 경로 / 버전 / npm 캐시 / PATH 후보 표시.
|
|
12830
13127
|
function whichCmd() {
|
|
@@ -12906,7 +13203,7 @@ function whichCmd() {
|
|
|
12906
13203
|
}
|
|
12907
13204
|
|
|
12908
13205
|
function help() {
|
|
12909
|
-
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 memory search "키" [--include-code] # 1.9.25 소스 코드 본문도 검색 (모순 감지 핵심)\n leerness brainstorm "주제" [--include-code] # 1.9.25 코드 본문 hits 포함\n leerness register-pending "<요청>" [--agent X] [--note Y] # 1.9.25 다중 세션 in-progress 즉시 등록\n leerness optimism-check <T-ID> [--json] # 1.9.26/27 낙관적 표시 감지 (1.9.27: 10 카테고리 + URL/메서드 매핑 + 신뢰도 점수)\n leerness persona list|show <id>|add <id> # 1.9.29 페르소나 카탈로그 (보안/성능/UX/testing/docs 5종 내장)\n leerness review <file> --persona <id1,id2,...> # 1.9.29 도메인 페르소나 리뷰 프롬프트 자동 생성\n leerness agents list|check|quota # 1.9.30/31 외부 AI CLI 가용성 + quota 추정 (claude/codex/gemini/copilot)\n leerness agents dispatch "<task>" --to <id> # 1.9.30 활성 CLI 대상 실행 명령 생성 (실 호출 X, 사용자 실행)\n leerness agents multi "<task>" [--only c1,c2] [--write] [--execute] [--timeout 60] # 1.9.152/156 활성 N개 일괄 dispatch (--execute: 실 spawn + consensus)\n leerness provider list|add|remove [args] # 1.9.157 Provider Registry — 사용자 정의 CLI provider 동적 추가 (OpenRouter/Bedrock 흡수)\n leerness agents dispatch "<task>" --multi # 1.9.152 multi 모드 alias (또는 --to all)\n leerness setup-agents [path] [--yes|--no-setup-agents] # 1.9.32 sub-agent CLI 인터랙티브 설정 (.env + 미설치 자동 설치)\n leerness init [path] [--no-stale-check] # 1.9.33 npx 캐시 함정 — 옛 버전 자동 경고 (끄려면 --no-stale-check)\n leerness which [--json] # 1.9.164 진단: 현재 실행 경로/버전 + npm 캐시 + PATH 후보 (구버전 충돌 해결)\n leerness web check|screenshot|extract <url> [--out file.png] [--selector "css"] # 1.9.165 playwright bridge (opt-in: npm i -g playwright + permissions.browser)\n leerness pc check|click|type|screenshot [--x N --y N] [--text "s"] [--out f.png] # 1.9.166 robotjs/nut-tree bridge (opt-in: npm i -g robotjs + permissions.mouse/keyboard, ⚠ full 모드 권장)\n leerness lsp check|symbols|references <file/name> [--in dir] [--json] # 1.9.167 LSP 어댑터 MVP (typescript opt-in + regex fallback, 코드 인텔리전스)\n leerness contract verify <spec.md> <impl.js> [--json] # 1.9.35 명세 ↔ 구현 일치 검사 (함수/필드)\n leerness reuse autodetect [path] [--apply] [--json] # 1.9.35 src/*.js의 module.exports → reuse-map 후보 등록\n leerness audit [path] [--fix] # 1.9.35 --fix: session-handoff/current-state 자동 갱신\n leerness verify-claim <T-ID> ... [--strict-claims] # 1.9.26 verify-claim에 낙관적 표시 자동 검사 통합\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 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
|
|
13206
|
+
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 memory search "키" [--include-code] # 1.9.25 소스 코드 본문도 검색 (모순 감지 핵심)\n leerness brainstorm "주제" [--include-code] # 1.9.25 코드 본문 hits 포함\n leerness register-pending "<요청>" [--agent X] [--note Y] # 1.9.25 다중 세션 in-progress 즉시 등록\n leerness optimism-check <T-ID> [--json] # 1.9.26/27 낙관적 표시 감지 (1.9.27: 10 카테고리 + URL/메서드 매핑 + 신뢰도 점수)\n leerness persona list|show <id>|add <id> # 1.9.29 페르소나 카탈로그 (보안/성능/UX/testing/docs 5종 내장)\n leerness review <file> --persona <id1,id2,...> # 1.9.29 도메인 페르소나 리뷰 프롬프트 자동 생성\n leerness agents list|check|quota # 1.9.30/31 외부 AI CLI 가용성 + quota 추정 (claude/codex/gemini/copilot)\n leerness agents dispatch "<task>" --to <id> # 1.9.30 활성 CLI 대상 실행 명령 생성 (실 호출 X, 사용자 실행)\n leerness agents multi "<task>" [--only c1,c2] [--write] [--execute] [--timeout 60] # 1.9.152/156 활성 N개 일괄 dispatch (--execute: 실 spawn + consensus)\n leerness provider list|add|remove [args] # 1.9.157 Provider Registry — 사용자 정의 CLI provider 동적 추가 (OpenRouter/Bedrock 흡수)\n leerness agents dispatch "<task>" --multi # 1.9.152 multi 모드 alias (또는 --to all)\n leerness setup-agents [path] [--yes|--no-setup-agents] # 1.9.32 sub-agent CLI 인터랙티브 설정 (.env + 미설치 자동 설치)\n leerness init [path] [--no-stale-check] # 1.9.33 npx 캐시 함정 — 옛 버전 자동 경고 (끄려면 --no-stale-check)\n leerness which [--json] # 1.9.164 진단: 현재 실행 경로/버전 + npm 캐시 + PATH 후보 (구버전 충돌 해결)\n leerness web check|screenshot|extract <url> [--out file.png] [--selector "css"] # 1.9.165 playwright bridge (opt-in: npm i -g playwright + permissions.browser)\n leerness pc check|click|type|screenshot [--x N --y N] [--text "s"] [--out f.png] # 1.9.166 robotjs/nut-tree bridge (opt-in: npm i -g robotjs + permissions.mouse/keyboard, ⚠ full 모드 권장)\n leerness lsp check|symbols|references <file/name> [--in dir] [--json] # 1.9.167 LSP 어댑터 MVP (typescript opt-in + regex fallback, 코드 인텔리전스)\n leerness review-request "<request>" [--json] # 1.9.176 사용자 요청 사전 검토 (충돌/재사용/효율/권장 단계 — 사용자 명시)\n leerness contract verify <spec.md> <impl.js> [--json] # 1.9.35 명세 ↔ 구현 일치 검사 (함수/필드)\n leerness reuse autodetect [path] [--apply] [--json] # 1.9.35 src/*.js의 module.exports → reuse-map 후보 등록\n leerness audit [path] [--fix] # 1.9.35 --fix: session-handoff/current-state 자동 갱신\n leerness verify-claim <T-ID> ... [--strict-claims] # 1.9.26 verify-claim에 낙관적 표시 자동 검사 통합\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 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
|
|
12910
13207
|
leerness retro [path] [--days 7] [--all-apps] [--include p1,p2] [--json] # 회고 (1.9.13~1.9.16)
|
|
12911
13208
|
leerness insights [path] [--all-apps] [--include p1,p2] [--json] # 누적 통계 (1.9.13~1.9.16)
|
|
12912
13209
|
leerness brainstorm "<주제>" [--all-apps] [--include p1,p2] [--json] # 브레인스토밍 (1.9.13~1.9.16)
|
|
@@ -12988,6 +13285,13 @@ async function main() {
|
|
|
12988
13285
|
if (cmd === 'pc') return pcCmd(arg('--path', process.cwd()), args[1], ...args.slice(2));
|
|
12989
13286
|
|
|
12990
13287
|
if (cmd === 'lsp') return lspCmd(arg('--path', process.cwd()), args[1], ...args.slice(2));
|
|
13288
|
+
|
|
13289
|
+
// 1.9.176: leerness review-request "<request>" — 사용자 요청 사전 검토 (사용자 명시)
|
|
13290
|
+
// AI 에이전트가 무조건 구현 전에 충돌/재사용/효율/권장 단계 분석.
|
|
13291
|
+
if (cmd === 'review-request' || cmd === 'review-req') {
|
|
13292
|
+
const reqText = args.slice(1).filter(x => !x.startsWith('-')).join(' ');
|
|
13293
|
+
return reviewRequestCmd(arg('--path', process.cwd()), reqText);
|
|
13294
|
+
}
|
|
12991
13295
|
if (cmd === 'contract' && args[1] === 'verify') return contractVerifyCmd(args[2], args[3]);
|
|
12992
13296
|
if (cmd === 'drift' && (args[1] === 'check' || !args[1])) return driftCheckCmd(args[2] || arg('--path', process.cwd()));
|
|
12993
13297
|
if (cmd === 'usage' && (args[1] === 'stats' || !args[1])) return usageStatsCmd(args[2] || arg('--path', process.cwd()));
|