leerness 1.9.30 → 1.9.31
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 +57 -2
- package/bin/harness.js +65 -3
- package/package.json +1 -1
- package/scripts/e2e.js +33 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.31 — 2026-05-15
|
|
4
|
+
|
|
5
|
+
**`leerness agents quota` — 외부 AI CLI 사용량/한도 추정 + provider 대시보드 안내**.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`leerness agents quota`** (1.9.31): 활성 CLI별 quota/rate-limit 정보 표시.
|
|
10
|
+
- **claude**: 비대화형 quota API 없음 → `/status` 슬래시 또는 https://console.anthropic.com/settings/usage 안내.
|
|
11
|
+
- **codex**: `codex --help`에서 `usage`/`quota` 키워드 감지 시 시도 가능 표시, 미감지 시 https://platform.openai.com/account/usage 안내.
|
|
12
|
+
- **gemini**: 무료 티어 `60 req/min, 1000 req/day` 명시.
|
|
13
|
+
- **copilot (gh)**: `gh auth status`로 인증 확인 → 구독자 무제한 또는 `gh auth login` 필요 안내.
|
|
14
|
+
- `--json` 출력 지원 (`{ quota: [{id, bin, status, quota, hint, raw}, ...] }`).
|
|
15
|
+
- **`agents` 사용법 메시지에 `quota` 추가**: `list|check|quota|dispatch`.
|
|
16
|
+
- **`agents dispatch` 안내문에 quota 명령 cross-link** (1.9.31+).
|
|
17
|
+
|
|
18
|
+
### Policy
|
|
19
|
+
- ❌ leerness는 사용량을 직접 추적하지 않음 (provider 대시보드 참조)
|
|
20
|
+
- ✅ sub-agent 분배 시 quota 여유 큰 CLI를 메인 에이전트가 우선 선택하도록 신호 제공
|
|
21
|
+
- ✅ rate-limit/plan 차이는 provider별 다름 — leerness는 hint만 제공
|
|
22
|
+
|
|
23
|
+
### 실측 (이번 라운드 사용 사례)
|
|
24
|
+
- agents quota 신규 명령 검증 후 sub-agent ×3 동시 분배
|
|
25
|
+
- e2e: 146/146 통과 (1.9.30 144 + quota 2)
|
|
26
|
+
|
|
3
27
|
## 1.9.30 — 2026-05-15
|
|
4
28
|
|
|
5
29
|
**외부 AI CLI 오케스트레이션 — 환경변수 활성화 정책 + `leerness agents list/check/dispatch`**.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 한국어 우선 AI 개발 하네스. 멀티 에이전트 오케스트레이션 · 자동 검수 · 워크스페이스 가시성 · Ollama opt-in 통합.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []()
|
|
6
6
|
|
|
7
7
|
## ⚙️ 설치 (Install)
|
|
8
8
|
|
|
@@ -31,6 +31,8 @@ npm i --save-dev leerness && npx leerness handoff .
|
|
|
31
31
|
- LLM 컨텍스트 비용 → `--compact` 모드로 4KB → 500자
|
|
32
32
|
- AI가 "API 호출 완료"라 보고했지만 코드에 호출 흔적이 없는 낙관적 표시 → `optimism-check`로 자동 감지 (1.9.26/27)
|
|
33
33
|
- 코드 리뷰가 표면적이라 도메인 깊이 부족 → `leerness review <file> --persona security,performance,ux`로 도메인 페르소나 자동 부여 (1.9.29)
|
|
34
|
+
- 외부 AI CLI(claude/codex/gemini/copilot)를 sub-agent로 활용하고 싶지만 자동 호출은 위험 → 환경변수 활성화 + `leerness agents list/dispatch`로 명시적 분배 (1.9.30)
|
|
35
|
+
- 어떤 CLI에 quota 여유가 남았는지 한눈에 보고 싶을 때 → `leerness agents quota`로 provider별 사용량/한도 추정 (1.9.31)
|
|
34
36
|
|
|
35
37
|
---
|
|
36
38
|
|
|
@@ -97,6 +99,9 @@ leerness review <file> --persona security,performance,ux # 1.9.29 도메인
|
|
|
97
99
|
leerness persona list # 5종 내장 + 사용자 정의
|
|
98
100
|
leerness persona show security # 페르소나 본문
|
|
99
101
|
leerness persona add my-domain # 사용자 정의 페르소나
|
|
102
|
+
leerness agents list # 1.9.30 외부 AI CLI 상태표
|
|
103
|
+
leerness agents quota # 1.9.31 CLI별 사용량/한도 추정
|
|
104
|
+
leerness agents dispatch "<task>" --to gemini # 1.9.30 sub-agent 명령 생성
|
|
100
105
|
```
|
|
101
106
|
|
|
102
107
|
### 워크스페이스 (멀티 프로젝트)
|
|
@@ -213,6 +218,9 @@ leerness orchestrate "복잡한 기능" --agents 20
|
|
|
213
218
|
| `handoff --compact` | LLM 시스템 프롬프트용 압축 출력 | 1.9.22 |
|
|
214
219
|
| `review --persona X` | 도메인별 sub-agent 자동 프롬프트 (security/performance/ux/testing/docs) | 1.9.29 |
|
|
215
220
|
| `persona list/show/add` | 페르소나 카탈로그 관리 (.harness/personas/) | 1.9.29 |
|
|
221
|
+
| `agents list/check` | 4 CLI(claude/codex/gemini/copilot) 활성/설치 상태표 (env + PATH 검증) | 1.9.30 |
|
|
222
|
+
| `agents dispatch --to X` | ready CLI에 대상 명령 자동 생성 (자동 호출 금지) | 1.9.30 |
|
|
223
|
+
| `agents quota` | provider별 사용량/한도 추정 + 대시보드 안내 | 1.9.31 |
|
|
216
224
|
|
|
217
225
|
---
|
|
218
226
|
|
|
@@ -293,6 +301,47 @@ leerness persona add my-domain # .harness/personas/my-domain.md 템플릿 생
|
|
|
293
301
|
|
|
294
302
|
---
|
|
295
303
|
|
|
304
|
+
## 🤖 외부 AI CLI 오케스트레이션 (1.9.30 / 1.9.31)
|
|
305
|
+
|
|
306
|
+
claude/codex/gemini/copilot CLI들을 sub-agent로 명시적 활용. **자동 호출 절대 금지** — 환경변수 활성화 + PATH 존재 둘 다 충족 시에만 ready.
|
|
307
|
+
|
|
308
|
+
### 활성화 (`.env`)
|
|
309
|
+
```bash
|
|
310
|
+
LEERNESS_ENABLE_CLAUDE=1 # Anthropic Claude Code CLI
|
|
311
|
+
LEERNESS_ENABLE_CODEX=1 # OpenAI Codex CLI (격리 sandbox)
|
|
312
|
+
LEERNESS_ENABLE_GEMINI=1 # Google Gemini CLI (--yolo 모드는 워크스페이스 직접 수정 가능)
|
|
313
|
+
LEERNESS_ENABLE_COPILOT=1 # GitHub Copilot CLI (gh copilot)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### 사용
|
|
317
|
+
```bash
|
|
318
|
+
leerness agents list # 4 CLI 상태표 (env + PATH + 버전)
|
|
319
|
+
leerness agents quota # provider별 사용량/한도 추정 (1.9.31)
|
|
320
|
+
leerness agents dispatch "<task>" --to gemini # ready CLI에 명령 자동 생성
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### quota 안내 (1.9.31)
|
|
324
|
+
| CLI | 추정 | 안내 |
|
|
325
|
+
|---|---|---|
|
|
326
|
+
| claude | `unknown` | 대화 내 `/status` 슬래시 또는 https://console.anthropic.com/settings/usage |
|
|
327
|
+
| codex | `cli-supported` 또는 `unknown` | `codex usage`/`codex quota` 시도 또는 https://platform.openai.com/account/usage |
|
|
328
|
+
| gemini | `rate-limited` | 무료 60 req/min, 1000 req/day · https://ai.google.dev/gemini-api/docs/rate-limits |
|
|
329
|
+
| copilot | `subscription` 또는 `not-authed` | 월 구독자 무제한 · `gh auth login` 필요 시 안내 |
|
|
330
|
+
|
|
331
|
+
### 실측 (이번 라운드)
|
|
332
|
+
- Sub B (rpg-craft, Claude 페르소나) → 20/20 pass, 1,567 라인
|
|
333
|
+
- Sub C (rpg-achievements, Claude 페르소나) → 22/22 pass, 1,375 라인
|
|
334
|
+
- Sub D (rpg-instance, Claude 페르소나, cross-project require 시연) → 20/20 pass, 1,016 라인
|
|
335
|
+
- → **3 도메인 동시 진행**, 메인 에이전트가 sub-agent들에 페르소나 + 영역 분배 + 충돌 방지 컨벤션 명시.
|
|
336
|
+
|
|
337
|
+
### 정책
|
|
338
|
+
- ❌ leerness는 외부 CLI를 자동 호출하지 않음 (사용자/메인 에이전트가 명시적 실행)
|
|
339
|
+
- ✅ `agents dispatch`는 명령 텍스트만 출력 — 복사해서 실행
|
|
340
|
+
- ✅ quota 여유 큰 CLI를 메인 에이전트가 우선 선택하도록 신호 제공
|
|
341
|
+
- ⚠ `gemini --yolo`는 워크스페이스 파일 직접 수정 가능 — 격리 sandbox 아님 (codex와 차이)
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
296
345
|
## 🤝 Claude Code 통합
|
|
297
346
|
|
|
298
347
|
설치 시 자동 등록: `.claude/commands/{handoff, session-close, audit, lazy-detect, update}.md` · `.claude/skills/leerness.md` (스킬 정의) · `.claude/settings.local.json` (SessionStart hook `update --check`) · `.cursor/rules/leerness.mdc` (Cursor) · `.github/copilot-instructions.md` (Copilot)
|
|
@@ -323,6 +372,10 @@ leerness skill consolidate
|
|
|
323
372
|
| `LEERNESS_GITHUB_TOKEN` | gh release용 (있을 때) |
|
|
324
373
|
| **`LEERNESS_OLLAMA_BASE_URL`** | **1.9.22 — orchestrate opt-in 활성화** |
|
|
325
374
|
| `LEERNESS_OLLAMA_MODEL` | 기본 모델 (orchestrate `--model`로 override) |
|
|
375
|
+
| **`LEERNESS_ENABLE_CLAUDE`** | **1.9.30 — `agents list/dispatch` Claude Code CLI 활성** (=1) |
|
|
376
|
+
| **`LEERNESS_ENABLE_CODEX`** | **1.9.30 — Codex CLI 활성** (=1) |
|
|
377
|
+
| **`LEERNESS_ENABLE_GEMINI`** | **1.9.30 — Gemini CLI 활성** (=1) |
|
|
378
|
+
| **`LEERNESS_ENABLE_COPILOT`** | **1.9.30 — gh copilot 활성** (=1) |
|
|
326
379
|
|
|
327
380
|
---
|
|
328
381
|
|
|
@@ -362,12 +415,14 @@ A. `--all-apps`는 현재 디렉토리 + `_apps/*` (또는 부모의 `_apps/*`)
|
|
|
362
415
|
npm test # = node ./scripts/e2e.js
|
|
363
416
|
```
|
|
364
417
|
|
|
365
|
-
**
|
|
418
|
+
**146/146 시나리오** 통과 (1.9.7~1.9.31 회귀 + 신규 검증).
|
|
366
419
|
|
|
367
420
|
---
|
|
368
421
|
|
|
369
422
|
## 📜 변경 이력 (최근)
|
|
370
423
|
|
|
424
|
+
- **1.9.31** — `leerness agents quota` (provider별 사용량/한도 추정 + 대시보드 안내). 멀티 에이전트 분배 신호.
|
|
425
|
+
- **1.9.30** — 외부 AI CLI 오케스트레이션 (claude/codex/gemini/copilot) + 환경변수 활성화 정책 + `leerness agents list/check/dispatch`
|
|
371
426
|
- **1.9.29** — 페르소나 시스템 (5종 내장) + `leerness review --persona` (도메인 깊이 3-4배)
|
|
372
427
|
- **1.9.28** — 카카오페이/네이버페이 패턴 + confidence floor 0.15
|
|
373
428
|
- **1.9.27** — `optimism-check` 강화: 10 카테고리 + URL/메서드 매핑 + 신뢰도 점수
|
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.31';
|
|
10
10
|
const MARK = '<!-- leerness:managed -->';
|
|
11
11
|
const README_START = '<!-- leerness:project-readme:start -->';
|
|
12
12
|
const README_END = '<!-- leerness:project-readme:end -->';
|
|
@@ -2373,11 +2373,73 @@ function agentsCmd(root, sub, ...args) {
|
|
|
2373
2373
|
log(`## 정책 (1.9.30)`);
|
|
2374
2374
|
log(` - leerness는 외부 CLI를 자동 호출하지 않음 (사용자 명시적 실행)`);
|
|
2375
2375
|
log(` - 메인 에이전트(Claude)가 위 명령을 보고 sub-agent로 spawn 가능`);
|
|
2376
|
-
log(` - quota 체크:
|
|
2376
|
+
log(` - quota 체크: \`leerness agents quota\` (1.9.31+)`);
|
|
2377
2377
|
return;
|
|
2378
2378
|
}
|
|
2379
2379
|
|
|
2380
|
-
|
|
2380
|
+
if (sub === 'quota') {
|
|
2381
|
+
// 1.9.31: 각 CLI 사용량/쿼터 추정 + provider 대시보드 링크
|
|
2382
|
+
const results = [];
|
|
2383
|
+
for (const agent of EXTERNAL_AGENTS) {
|
|
2384
|
+
const base = _checkAgent(agent);
|
|
2385
|
+
const out = { id: agent.id, bin: agent.bin, status: base.status, quota: null, hint: null, raw: null };
|
|
2386
|
+
if (base.status !== 'ready') {
|
|
2387
|
+
out.hint = base.status === 'not-installed' ? `${agent.bin} CLI 미설치` : base.status === 'disabled' ? `${agent.envFlag}=1 필요` : '알 수 없음';
|
|
2388
|
+
results.push(out); continue;
|
|
2389
|
+
}
|
|
2390
|
+
// CLI별 quota 탐지 시도
|
|
2391
|
+
try {
|
|
2392
|
+
if (agent.id === 'claude') {
|
|
2393
|
+
// claude는 /status 슬래시 (대화형)만 지원. 비대화형 추정 불가.
|
|
2394
|
+
out.quota = 'unknown';
|
|
2395
|
+
out.hint = '대화 내 `/status` 슬래시 또는 https://console.anthropic.com/settings/usage 확인';
|
|
2396
|
+
} else if (agent.id === 'codex') {
|
|
2397
|
+
// codex CLI: codex --help에 usage 명령 있는지 확인
|
|
2398
|
+
const r = cp.spawnSync(agent.bin, ['--help'], { encoding: 'utf8', timeout: 4000, shell: true });
|
|
2399
|
+
const help = (r.stdout || r.stderr || '').toLowerCase();
|
|
2400
|
+
if (help.includes('usage') || help.includes('quota')) {
|
|
2401
|
+
out.quota = 'cli-supported';
|
|
2402
|
+
out.hint = '`codex usage` 또는 `codex quota` 시도 가능';
|
|
2403
|
+
} else {
|
|
2404
|
+
out.quota = 'unknown';
|
|
2405
|
+
out.hint = 'https://platform.openai.com/account/usage 확인';
|
|
2406
|
+
}
|
|
2407
|
+
out.raw = help.slice(0, 200);
|
|
2408
|
+
} else if (agent.id === 'gemini') {
|
|
2409
|
+
// gemini CLI: 무료 티어는 분당 60req 제한, CLI 자체에선 노출 안 됨
|
|
2410
|
+
out.quota = 'rate-limited';
|
|
2411
|
+
out.hint = '무료 티어: 60 req/min, 1000 req/day · 유료는 https://ai.google.dev/gemini-api/docs/rate-limits';
|
|
2412
|
+
} else if (agent.id === 'copilot') {
|
|
2413
|
+
// gh copilot은 GitHub Copilot 구독 (월 단위 quota 없음, individual/business 플랜)
|
|
2414
|
+
const r = cp.spawnSync('gh', ['auth', 'status'], { encoding: 'utf8', timeout: 4000, shell: true });
|
|
2415
|
+
const authed = r.status === 0;
|
|
2416
|
+
out.quota = authed ? 'subscription' : 'not-authed';
|
|
2417
|
+
out.hint = authed ? 'Copilot 구독자 무제한 (월 플랜) · https://github.com/settings/copilot' : '`gh auth login` 필요';
|
|
2418
|
+
}
|
|
2419
|
+
} catch (e) {
|
|
2420
|
+
out.quota = 'error';
|
|
2421
|
+
out.hint = e.message;
|
|
2422
|
+
}
|
|
2423
|
+
results.push(out);
|
|
2424
|
+
}
|
|
2425
|
+
if (has('--json')) { log(JSON.stringify({ quota: results }, null, 2)); return; }
|
|
2426
|
+
log(`# 외부 AI CLI quota 추정 (1.9.31)`);
|
|
2427
|
+
log('');
|
|
2428
|
+
log(`| Agent | 상태 | quota | 안내 |`);
|
|
2429
|
+
log(`|---|---|---|---|`);
|
|
2430
|
+
for (const q of results) {
|
|
2431
|
+
const statusEmoji = q.status === 'ready' ? '🟢' : q.status === 'not-installed' ? '⚪' : q.status === 'disabled' ? '🟡' : '❓';
|
|
2432
|
+
log(`| ${q.id} | ${statusEmoji} ${q.status} | ${q.quota || '-'} | ${q.hint || '-'} |`);
|
|
2433
|
+
}
|
|
2434
|
+
log('');
|
|
2435
|
+
log(`## 주의`);
|
|
2436
|
+
log(` - leerness는 CLI 사용량을 직접 추적하지 않음 (provider 대시보드 참조)`);
|
|
2437
|
+
log(` - rate-limit/quota는 plan/티어에 따라 달라짐`);
|
|
2438
|
+
log(` - sub-agent 분배 시 quota 여유 큰 CLI 우선 활용 권장`);
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
fail('사용법: leerness agents list|check|quota|dispatch "<task>" --to <id>');
|
|
2381
2443
|
return process.exit(1);
|
|
2382
2444
|
}
|
|
2383
2445
|
|
package/package.json
CHANGED
package/scripts/e2e.js
CHANGED
|
@@ -834,6 +834,39 @@ total++;
|
|
|
834
834
|
if (!ok) { failed++; console.log(r.stdout.slice(0, 400)); }
|
|
835
835
|
}
|
|
836
836
|
|
|
837
|
+
// 1.9.31 회귀: agents quota (각 CLI 사용량/quota 조회)
|
|
838
|
+
total++;
|
|
839
|
+
{
|
|
840
|
+
// agents quota — env=0 시 모두 disabled/not-installed, 안내 메시지 포함
|
|
841
|
+
const env = { ...process.env, LEERNESS_ENABLE_CLAUDE: '0', LEERNESS_ENABLE_CODEX: '0', LEERNESS_ENABLE_GEMINI: '0', LEERNESS_ENABLE_COPILOT: '0' };
|
|
842
|
+
const r = cp.spawnSync(process.execPath, [CLI, 'agents', 'quota'], { encoding: 'utf8', timeout: 15000, env });
|
|
843
|
+
const okText = r.status === 0
|
|
844
|
+
&& /외부 AI CLI quota 추정 \(1\.9\.31\)/.test(r.stdout)
|
|
845
|
+
&& /\| claude \|/.test(r.stdout)
|
|
846
|
+
&& /\| codex \|/.test(r.stdout)
|
|
847
|
+
&& /\| gemini \|/.test(r.stdout)
|
|
848
|
+
&& /\| copilot \|/.test(r.stdout)
|
|
849
|
+
&& /provider 대시보드 참조/.test(r.stdout);
|
|
850
|
+
// JSON 출력
|
|
851
|
+
const r2 = cp.spawnSync(process.execPath, [CLI, 'agents', 'quota', '--json'], { encoding: 'utf8', timeout: 15000, env });
|
|
852
|
+
let parsed = null;
|
|
853
|
+
try { parsed = JSON.parse(r2.stdout); } catch {}
|
|
854
|
+
const okJson = parsed && Array.isArray(parsed.quota) && parsed.quota.length === 4
|
|
855
|
+
&& parsed.quota.every(q => typeof q.id === 'string' && typeof q.status === 'string' && (q.hint === null || typeof q.hint === 'string'));
|
|
856
|
+
const ok = okText && okJson;
|
|
857
|
+
console.log(ok ? '✓ B(1.9.31) agents quota: 4 CLI 사용량/안내 + JSON 출력' : `✗ quota 실패 (text=${okText} json=${okJson})`);
|
|
858
|
+
if (!ok) { failed++; console.log(r.stdout.slice(0, 500)); }
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
total++;
|
|
862
|
+
{
|
|
863
|
+
// 사용법 메시지에 quota 포함
|
|
864
|
+
const r = cp.spawnSync(process.execPath, [CLI, 'agents', 'foo'], { encoding: 'utf8', timeout: 10000 });
|
|
865
|
+
const ok = r.status !== 0 && /list\|check\|quota\|dispatch/.test(r.stdout + r.stderr);
|
|
866
|
+
console.log(ok ? '✓ B(1.9.31) agents 사용법에 quota 명시' : `✗ usage 메시지 실패`);
|
|
867
|
+
if (!ok) { failed++; console.log((r.stdout + r.stderr).slice(0, 300)); }
|
|
868
|
+
}
|
|
869
|
+
|
|
837
870
|
// 1.9.22 회귀: handoff --compact + orchestrate opt-in 정책 + llm-bench record
|
|
838
871
|
total++;
|
|
839
872
|
{
|