leerness 1.9.293 → 1.9.294
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 +22 -0
- package/README.md +5 -5
- package/bin/harness.js +4 -97
- package/lib/role-catalog.js +103 -0
- package/package.json +1 -1
- package/scripts/e2e.js +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.294 — 2026-06-04 — UR-0025 (3단계): 역할/모델 카탈로그 → lib/role-catalog.js 모듈 분리
|
|
4
|
+
|
|
5
|
+
**🧩 모놀리스 분리 3단계 — 역할/모델 레지스트리(4개 카탈로그)를 비파괴 데이터 모듈로 분리. 1.9.274(pure-utils)/1.9.291(agent-registry) 패턴 계승.**
|
|
6
|
+
|
|
7
|
+
### 배경
|
|
8
|
+
GPT-5.5 + Codex 두 리뷰 공통 지적인 단일 대형 `bin/harness.js`(#1 유지보수 이슈)를 점진 분리 중. 1단계(pure-utils 14함수)·2단계(agent-registry)에 이어 3단계로 역할/모델 데이터 카탈로그를 분리.
|
|
9
|
+
|
|
10
|
+
### 구현 (UR-0025 3단계)
|
|
11
|
+
1. **`lib/role-catalog.js` 신설** — 4개 순수 데이터 카탈로그 이동(96줄):
|
|
12
|
+
- `_PROVIDER_MODEL_CATALOG`(provider×모델 10종, REPL Tab cycle)
|
|
13
|
+
- `_AGENT_ROLE_PROMPTS`(planner/reviewer/actor 역할 프롬프트)
|
|
14
|
+
- `ROLE_CATALOG`(7종 역할: commander/reviewer/coder/architect/designer/debugger/dispatcher)
|
|
15
|
+
- `_ROLE_ALIASES`(한국어 별칭 21종)
|
|
16
|
+
2. **비파괴 require-based 분리** — `_normalizeRole`/`_pickModel`/REPL 소비처는 동일 바인딩 사용. 런타임 변형 0(모두 읽기 전용 검증).
|
|
17
|
+
3. **harness.js 21700→21606줄** (94줄 감소). 누적: pure-utils(163)+agent-registry(147)+role-catalog(103) 3 모듈.
|
|
18
|
+
4. selftest 41→42 (4개 카탈로그 동일참조 단일출처 + 인라인 제거 검증) · e2e 238→239 (모듈 standalone + harness 인라인 제거 + `roles list` 동작 회귀).
|
|
19
|
+
|
|
20
|
+
### 검증
|
|
21
|
+
- **selftest 42/42 PASS** · **E2E 239/239 PASS** (회귀 0).
|
|
22
|
+
- 기존 selftest(ROLE_CATALOG 7종 + _normalizeRole 한국어별칭 + _pickModel top/code/fast)가 추출 정합성 즉시 검증.
|
|
23
|
+
- `roles list --json` 정상 동작 확인(모듈 분리 후 회귀 없음).
|
|
24
|
+
|
|
3
25
|
## 1.9.293 — 2026-06-04 — idempotency auto-fix + progress-tracker 복제 버그 근본 수정 🐛
|
|
4
26
|
|
|
5
27
|
**🔁 idempotency 위반(task/요청 중복)을 자동 회복하는 `--auto-fix` 신설 + 중복이 매 세션 누적되던 근본 버그(헤더 유실 시 전체 복제) 수정. 라이브 프로젝트 progress-tracker.md 69행→6행 복구.**
|
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
|
╔══════════════════════════════════════════════════════════════╗
|
|
@@ -471,7 +471,7 @@ MIT — © leerness contributors
|
|
|
471
471
|
<!-- leerness:project-readme:start -->
|
|
472
472
|
## Leerness Project Harness
|
|
473
473
|
|
|
474
|
-
이 프로젝트는 Leerness v1.9.
|
|
474
|
+
이 프로젝트는 Leerness v1.9.294 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
|
|
475
475
|
|
|
476
476
|
### Core Commands
|
|
477
477
|
|
|
@@ -513,7 +513,7 @@ leerness memory restore decision <date|title>
|
|
|
513
513
|
|
|
514
514
|
### MCP server (외부 AI 통합)
|
|
515
515
|
|
|
516
|
-
Leerness v1.9.
|
|
516
|
+
Leerness v1.9.294는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **80개 도구**를 노출:
|
|
517
517
|
|
|
518
518
|
```jsonc
|
|
519
519
|
// 카테고리별
|
|
@@ -534,7 +534,7 @@ Leerness v1.9.293는 stdio JSON-RPC MCP server를 내장합니다 — Claude Cod
|
|
|
534
534
|
`<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
|
|
535
535
|
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) 다음 라운드 예약.
|
|
536
536
|
|
|
537
|
-
현재 누적: **70 라운드 (1.9.40 → 1.9.
|
|
537
|
+
현재 누적: **70 라운드 (1.9.40 → 1.9.294)** · 매 라운드 GitHub release/태그 생성 · _reports/는 비공개 보존.
|
|
538
538
|
|
|
539
539
|
### 성능 가이드 (1.9.140 측정)
|
|
540
540
|
|
|
@@ -572,6 +572,6 @@ leerness release pack --close --auto-main-push
|
|
|
572
572
|
- `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
|
|
573
573
|
- `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
|
|
574
574
|
|
|
575
|
-
Last synced by Leerness v1.9.
|
|
575
|
+
Last synced by Leerness v1.9.294: 2026-06-04
|
|
576
576
|
<!-- leerness:project-readme:end -->
|
|
577
577
|
|
package/bin/harness.js
CHANGED
|
@@ -10,7 +10,7 @@ const readline = require('readline');
|
|
|
10
10
|
const { _isSecretKey, compareVer, parseHarnessVersion, _classifyCJK, _riskLabel, _detectSystemLang, _parseSlashFromHelp,
|
|
11
11
|
PERMISSION_TIERS, _tierRank, _requiredTier, _policyAllows, _resolveNpmTag, _mcpJsonContent, _newRunRecord } = require('../lib/pure-utils');
|
|
12
12
|
|
|
13
|
-
const VERSION = '1.9.
|
|
13
|
+
const VERSION = '1.9.294';
|
|
14
14
|
|
|
15
15
|
// 1.9.290 (UR-0037, Codex gpt-5.5 #4 수렴): CLI 전용 부작용은 require 시 실행하지 않는다.
|
|
16
16
|
// 이전: warning listener 제거 / NODE_OPTIONS 변경 / chcp IIFE 가 top-level 즉시 실행 → require('harness') 시 호스트 프로세스 오염.
|
|
@@ -3000,6 +3000,7 @@ function _selfTestCases() {
|
|
|
3000
3000
|
{ name: 'lib/agent-registry: EXTERNAL_AGENTS/AGENT_SLASH_COMMANDS 모듈 단일출처 분리 (UR-0025 1.9.291)', run: () => { const m = require('../lib/agent-registry'); return m.EXTERNAL_AGENTS === EXTERNAL_AGENTS && m.AGENT_SLASH_COMMANDS === AGENT_SLASH_COMMANDS && m.EXTERNAL_AGENTS.length === 10 && Object.keys(m.AGENT_SLASH_COMMANDS).length === 9 && !/const EXTERNAL_AGENTS = \[/.test(read(__filename)); } },
|
|
3001
3001
|
{ name: 'get_project_context: MCP 시맨틱 verb 등록 + CLI context 디스패치 (UR-0031 1.9.292)', run: () => { const src = read(__filename); const mcpDef = /name: 'leerness_get_project_context'/.test(src); const mcpCase = /case 'leerness_get_project_context':[\s\S]*?cliArgs = \['context'/.test(src); const cliDisp = /if \(cmd === 'context'\)\s+return contextCmd/.test(src); return typeof contextCmd === 'function' && mcpDef && mcpCase && cliDisp && _mcpToolCount() >= 80; } },
|
|
3002
3002
|
{ name: '_canonicalProgressHeader + idempotency auto-fix (근본 복제버그 fix 1.9.293)', run: () => { const h = _canonicalProgressHeader(); const headerOk = /leernessRole: progress-tracker/.test(h) && /\| ID \| Status \| Request \|/.test(h) && /\|---\|/.test(h); const src = read(__filename); const fnOk = typeof _autoFixIdempotency === 'function'; const noWholeTextFallback = /if \(idx < 0\) return _canonicalProgressHeader\(\);/.test(src); const driftWired = /_autoFixIdempotency\(root\)/.test(src) && /idempotency 중복/.test(src); return headerOk && fnOk && noWholeTextFallback && driftWired; } },
|
|
3003
|
+
{ name: 'lib/role-catalog: ROLE/PROVIDER/ALIASES/PROMPTS 모듈 단일출처 분리 (UR-0025 1.9.294)', run: () => { const m = require('../lib/role-catalog'); return m.ROLE_CATALOG === ROLE_CATALOG && m._PROVIDER_MODEL_CATALOG === _PROVIDER_MODEL_CATALOG && m._ROLE_ALIASES === _ROLE_ALIASES && m._AGENT_ROLE_PROMPTS === _AGENT_ROLE_PROMPTS && Object.keys(m.ROLE_CATALOG).length === 7 && Object.keys(m._PROVIDER_MODEL_CATALOG).length === 10 && !/const ROLE_CATALOG = \{/.test(read(__filename)); } },
|
|
3003
3004
|
{ name: 'VERSION 형식 (x.y.z)', run: () => /^\d+\.\d+\.\d+$/.test(VERSION) }
|
|
3004
3005
|
];
|
|
3005
3006
|
}
|
|
@@ -17812,102 +17813,8 @@ function runsShowCmd(root, id) {
|
|
|
17812
17813
|
if (!exists(fp)) return fail(`run 없음: ${id}`);
|
|
17813
17814
|
log(read(fp));
|
|
17814
17815
|
}
|
|
17815
|
-
// 1.9.
|
|
17816
|
-
|
|
17817
|
-
// 각 provider 의 최신 실제 모델 ID 를 반영. Tab/Shift+Tab 키로 cycle.
|
|
17818
|
-
const _PROVIDER_MODEL_CATALOG = {
|
|
17819
|
-
claude: [
|
|
17820
|
-
{ id: 'claude-opus-4-7', note: '최신 1M context (Anthropic Opus 4.7)' },
|
|
17821
|
-
{ id: 'claude-opus-4-5', note: '안정 Opus 4.5' },
|
|
17822
|
-
{ id: 'claude-sonnet-4-7', note: '균형형 — Sonnet 4.7 (속도/품질)' },
|
|
17823
|
-
{ id: 'claude-sonnet-4-5', note: 'Sonnet 4.5 안정' },
|
|
17824
|
-
{ id: 'claude-haiku-4-5', note: '빠름 — Haiku 4.5' }
|
|
17825
|
-
],
|
|
17826
|
-
codex: [
|
|
17827
|
-
{ id: 'gpt-5.5', note: 'OpenAI 최신 추론 모델' },
|
|
17828
|
-
{ id: 'gpt-5.4', note: 'OpenAI 안정 (이전 세대)' },
|
|
17829
|
-
{ id: 'gpt-5', note: 'OpenAI gpt-5 (base)' },
|
|
17830
|
-
{ id: 'gpt-5-codex', note: '코드 특화 (Codex)' },
|
|
17831
|
-
{ id: 'o4-mini', note: '빠른 reasoning' }
|
|
17832
|
-
],
|
|
17833
|
-
agy: [
|
|
17834
|
-
{ id: 'antigravity-pro', note: 'Antigravity 최고급 (1M+ context)' },
|
|
17835
|
-
{ id: 'antigravity-flash', note: '빠른 응답' },
|
|
17836
|
-
{ id: 'antigravity-experimental', note: '실험적 (사용 가능 시)' }
|
|
17837
|
-
],
|
|
17838
|
-
grok: [
|
|
17839
|
-
{ id: 'grok-beta', note: 'xAI 최신 (1.9.268 provider 승격)' },
|
|
17840
|
-
{ id: 'grok-2', note: 'xAI Grok 2' },
|
|
17841
|
-
{ id: 'grok-2-mini', note: '빠른 응답' }
|
|
17842
|
-
],
|
|
17843
|
-
// 1.9.277: 신규 provider 4종 모델 (provider-agnostic 인 도구는 default + 설정 안내)
|
|
17844
|
-
opencode: [
|
|
17845
|
-
{ id: 'default', note: 'opencode 설정 모델 (opencode auth/models 로 provider별 지정)' },
|
|
17846
|
-
{ id: 'anthropic/claude-sonnet', note: 'Anthropic 경유' },
|
|
17847
|
-
{ id: 'openai/gpt-5', note: 'OpenAI 경유' }
|
|
17848
|
-
],
|
|
17849
|
-
qwen: [
|
|
17850
|
-
{ id: 'qwen3-coder-plus', note: '코드 특화 최신' },
|
|
17851
|
-
{ id: 'qwen-max', note: '최고 성능' },
|
|
17852
|
-
{ id: 'qwen-plus', note: '균형' },
|
|
17853
|
-
{ id: 'qwen-turbo', note: '빠름' }
|
|
17854
|
-
],
|
|
17855
|
-
aider: [
|
|
17856
|
-
{ id: 'sonnet', note: 'Anthropic Sonnet (aider --model)' },
|
|
17857
|
-
{ id: 'gpt-5', note: 'OpenAI' },
|
|
17858
|
-
{ id: 'deepseek', note: 'DeepSeek (가성비)' },
|
|
17859
|
-
{ id: 'o1-mini', note: '빠른 reasoning' }
|
|
17860
|
-
],
|
|
17861
|
-
goose: [
|
|
17862
|
-
{ id: 'default', note: 'goose configure 로 설정한 provider/model' },
|
|
17863
|
-
{ id: 'claude-sonnet', note: 'Anthropic 경유' },
|
|
17864
|
-
{ id: 'gpt-5', note: 'OpenAI 경유' }
|
|
17865
|
-
],
|
|
17866
|
-
copilot: [
|
|
17867
|
-
{ id: 'default', note: 'gh copilot 기본 (모델 선택 불가)' }
|
|
17868
|
-
],
|
|
17869
|
-
ollama: [
|
|
17870
|
-
{ id: 'llama3', note: 'Meta — :models 로 실시간 조회 권장' },
|
|
17871
|
-
{ id: 'qwen2.5-coder', note: 'Alibaba — 코드 특화' },
|
|
17872
|
-
{ id: 'gpt-oss', note: 'OpenAI 오픈소스' },
|
|
17873
|
-
{ id: 'deepseek-coder-v2', note: 'DeepSeek 코드 모델' }
|
|
17874
|
-
]
|
|
17875
|
-
};
|
|
17876
|
-
|
|
17877
|
-
// 1.9.170: provider cycle 순서 (Tab) — 빌트인 6종(1.9.268 grok 추가). user provider는 동적으로 뒤에 추가.
|
|
17878
|
-
const _PROVIDER_CYCLE_ORDER = ['ollama', 'claude', 'codex', 'agy', 'grok', 'opencode', 'qwen', 'aider', 'goose', 'copilot'];
|
|
17879
|
-
|
|
17880
|
-
// 1.9.148: planner/reviewer/actor 역할 시스템 프롬프트 (Gemini 권고 — 자기-승인 편향 방지)
|
|
17881
|
-
const _AGENT_ROLE_PROMPTS = {
|
|
17882
|
-
planner: '역할: planner. task를 step 3-6개로 분해, 각 step의 입출력/검증 방법 명시. 코드 작성 금지, 계획만.',
|
|
17883
|
-
reviewer: '역할: reviewer. planner 의 계획 또는 actor 의 결과를 비판적으로 검토. 누락된 검증, 잠재 cascade, 오류 가능성 지적. 동의/수정 결론 명시.',
|
|
17884
|
-
actor: '역할: actor. 계획에 따라 정확한 명령/코드만 실행. evidence(파일 경로 + 테스트 결과) 함께 기록. 새 계획 생성 금지.'
|
|
17885
|
-
};
|
|
17886
|
-
// ===== 1.9.270: Agent Roles — 모델별 역할 부여 (사용자 명시) =====
|
|
17887
|
-
// 여러 AI 에이전트 활성 시 역할(코딩/검수/지휘/디자인/디버그/설계/분배)을 provider+model 에 매핑.
|
|
17888
|
-
// 사용자 설정: .harness/agent-roles.json { schemaVersion, roles: { <role>: { provider, model, persona } } }
|
|
17889
|
-
// dispatch --role <role> → 역할 기반 provider+model 라우팅. roles suggest → 활성 에이전트 기반 최적 배치 판단.
|
|
17890
|
-
// 방향성 판단(사용자 요청): 모델별 강점이 분명하고(추론/코드/멀티모달) 작업이 분해 가능할 때, 역할 특화는
|
|
17891
|
-
// 품질·정확도를 올림 — 강추론 모델의 독립 검수는 자기승인 편향을 차단, 코드 특화 모델은 구현 정확도↑.
|
|
17892
|
-
// 단 조율 오버헤드 < 이득이어야 하므로 opt-in + verify(비활성 provider 배정 경고)로 오설정을 방지.
|
|
17893
|
-
const ROLE_CATALOG = {
|
|
17894
|
-
commander: { ko: '지휘관', desc: '전체 계획 수립·작업 분해·최종 의사결정', prefer: ['claude', 'codex', 'grok'], modelKind: 'top', why: '최강 추론 모델이 전체 맥락을 쥐고 분해/결정 → 일관성↑' },
|
|
17895
|
-
reviewer: { ko: '검수자', desc: '구현 결과 비판적 검수·버그/누락 적발', prefer: ['claude', 'codex', 'grok'], modelKind: 'top', why: '독립 강추론 모델의 적대적 검수가 자기승인 편향 차단 → 정확도↑' },
|
|
17896
|
-
coder: { ko: '코딩 담당', desc: '구현·패치·리팩터', prefer: ['codex', 'agy', 'claude', 'grok'], modelKind: 'code', why: '코드 특화 모델이 구현 정확도/속도↑' },
|
|
17897
|
-
architect: { ko: '설계 담당', desc: '아키텍처·데이터 모델·인터페이스 설계', prefer: ['codex', 'claude'], modelKind: 'top', why: '깊은 코드 추론 모델이 설계 트레이드오프 분석' },
|
|
17898
|
-
designer: { ko: '디자인 담당', desc: 'UI/UX·시각 디자인·레이아웃', prefer: ['agy', 'claude', 'grok'], modelKind: 'top', why: '멀티모달/시각 역량 모델이 디자인 산출물↑' },
|
|
17899
|
-
debugger: { ko: '디버그 담당', desc: '버그 진단·근본원인·재현', prefer: ['codex', 'claude', 'grok'], modelKind: 'top', why: '깊은 추론 모델의 가설-검증이 디버깅 효율↑' },
|
|
17900
|
-
dispatcher: { ko: '하위 분배 담당', desc: '서브에이전트 업무 분배·병렬 조율', prefer: ['claude', 'grok', 'codex'], modelKind: 'fast', why: '빠른 응답 모델이 분배 오버헤드↓' }
|
|
17901
|
-
};
|
|
17902
|
-
const _ROLE_ALIASES = {
|
|
17903
|
-
'코딩': 'coder', '코더': 'coder', '코딩담당': 'coder',
|
|
17904
|
-
'검수': 'reviewer', '검수자': 'reviewer', '리뷰': 'reviewer', '리뷰어': 'reviewer',
|
|
17905
|
-
'지휘': 'commander', '지휘관': 'commander', '사령관': 'commander',
|
|
17906
|
-
'디자인': 'designer', '디자인담당': 'designer',
|
|
17907
|
-
'디버그': 'debugger', '디버거': 'debugger', '디버깅': 'debugger',
|
|
17908
|
-
'설계': 'architect', '설계담당': 'architect', '아키텍트': 'architect',
|
|
17909
|
-
'분배': 'dispatcher', '분배담당': 'dispatcher', '오케스트레이터': 'dispatcher'
|
|
17910
|
-
};
|
|
17816
|
+
// 1.9.294 (UR-0025 3단계): 역할/모델 카탈로그(_PROVIDER_MODEL_CATALOG + _AGENT_ROLE_PROMPTS + ROLE_CATALOG + _ROLE_ALIASES) 데이터 모듈 분리 (비파괴, require-based).
|
|
17817
|
+
const { _PROVIDER_MODEL_CATALOG, _AGENT_ROLE_PROMPTS, ROLE_CATALOG, _ROLE_ALIASES } = require('../lib/role-catalog');
|
|
17911
17818
|
function _normalizeRole(name) {
|
|
17912
17819
|
const raw = String(name || '').trim();
|
|
17913
17820
|
if (_ROLE_ALIASES[raw]) return _ROLE_ALIASES[raw];
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// lib/role-catalog.js — 역할/모델 레지스트리 (순수 데이터, 부작용 0)
|
|
2
|
+
// 1.9.294 (UR-0025 3단계): bin/harness.js 에서 비파괴 분리. selftest(ROLE_CATALOG 7종 + _normalizeRole + _pickModel)가 동작 검증.
|
|
3
|
+
// 런타임 변형 없음 — _normalizeRole/_pickModel/_AGENT_ROLE_PROMPTS 소비처 모두 읽기 전용.
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
// 1.9.155: provider 별 추천 모델 카탈로그 — REPL :models 명령에서 노출 (실제 가용성은 사용자 CLI 가 결정)
|
|
7
|
+
// 1.9.170: provider × 실제 모델 catalog 확장 (Tab cycle 지원 — 사용자 명시 요청)
|
|
8
|
+
// 각 provider 의 최신 실제 모델 ID 를 반영. Tab/Shift+Tab 키로 cycle.
|
|
9
|
+
const _PROVIDER_MODEL_CATALOG = {
|
|
10
|
+
claude: [
|
|
11
|
+
{ id: 'claude-opus-4-7', note: '최신 1M context (Anthropic Opus 4.7)' },
|
|
12
|
+
{ id: 'claude-opus-4-5', note: '안정 Opus 4.5' },
|
|
13
|
+
{ id: 'claude-sonnet-4-7', note: '균형형 — Sonnet 4.7 (속도/품질)' },
|
|
14
|
+
{ id: 'claude-sonnet-4-5', note: 'Sonnet 4.5 안정' },
|
|
15
|
+
{ id: 'claude-haiku-4-5', note: '빠름 — Haiku 4.5' }
|
|
16
|
+
],
|
|
17
|
+
codex: [
|
|
18
|
+
{ id: 'gpt-5.5', note: 'OpenAI 최신 추론 모델' },
|
|
19
|
+
{ id: 'gpt-5.4', note: 'OpenAI 안정 (이전 세대)' },
|
|
20
|
+
{ id: 'gpt-5', note: 'OpenAI gpt-5 (base)' },
|
|
21
|
+
{ id: 'gpt-5-codex', note: '코드 특화 (Codex)' },
|
|
22
|
+
{ id: 'o4-mini', note: '빠른 reasoning' }
|
|
23
|
+
],
|
|
24
|
+
agy: [
|
|
25
|
+
{ id: 'antigravity-pro', note: 'Antigravity 최고급 (1M+ context)' },
|
|
26
|
+
{ id: 'antigravity-flash', note: '빠른 응답' },
|
|
27
|
+
{ id: 'antigravity-experimental', note: '실험적 (사용 가능 시)' }
|
|
28
|
+
],
|
|
29
|
+
grok: [
|
|
30
|
+
{ id: 'grok-beta', note: 'xAI 최신 (1.9.268 provider 승격)' },
|
|
31
|
+
{ id: 'grok-2', note: 'xAI Grok 2' },
|
|
32
|
+
{ id: 'grok-2-mini', note: '빠른 응답' }
|
|
33
|
+
],
|
|
34
|
+
// 1.9.277: 신규 provider 4종 모델 (provider-agnostic 인 도구는 default + 설정 안내)
|
|
35
|
+
opencode: [
|
|
36
|
+
{ id: 'default', note: 'opencode 설정 모델 (opencode auth/models 로 provider별 지정)' },
|
|
37
|
+
{ id: 'anthropic/claude-sonnet', note: 'Anthropic 경유' },
|
|
38
|
+
{ id: 'openai/gpt-5', note: 'OpenAI 경유' }
|
|
39
|
+
],
|
|
40
|
+
qwen: [
|
|
41
|
+
{ id: 'qwen3-coder-plus', note: '코드 특화 최신' },
|
|
42
|
+
{ id: 'qwen-max', note: '최고 성능' },
|
|
43
|
+
{ id: 'qwen-plus', note: '균형' },
|
|
44
|
+
{ id: 'qwen-turbo', note: '빠름' }
|
|
45
|
+
],
|
|
46
|
+
aider: [
|
|
47
|
+
{ id: 'sonnet', note: 'Anthropic Sonnet (aider --model)' },
|
|
48
|
+
{ id: 'gpt-5', note: 'OpenAI' },
|
|
49
|
+
{ id: 'deepseek', note: 'DeepSeek (가성비)' },
|
|
50
|
+
{ id: 'o1-mini', note: '빠른 reasoning' }
|
|
51
|
+
],
|
|
52
|
+
goose: [
|
|
53
|
+
{ id: 'default', note: 'goose configure 로 설정한 provider/model' },
|
|
54
|
+
{ id: 'claude-sonnet', note: 'Anthropic 경유' },
|
|
55
|
+
{ id: 'gpt-5', note: 'OpenAI 경유' }
|
|
56
|
+
],
|
|
57
|
+
copilot: [
|
|
58
|
+
{ id: 'default', note: 'gh copilot 기본 (모델 선택 불가)' }
|
|
59
|
+
],
|
|
60
|
+
ollama: [
|
|
61
|
+
{ id: 'llama3', note: 'Meta — :models 로 실시간 조회 권장' },
|
|
62
|
+
{ id: 'qwen2.5-coder', note: 'Alibaba — 코드 특화' },
|
|
63
|
+
{ id: 'gpt-oss', note: 'OpenAI 오픈소스' },
|
|
64
|
+
{ id: 'deepseek-coder-v2', note: 'DeepSeek 코드 모델' }
|
|
65
|
+
]
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// 1.9.170: provider cycle 순서 (Tab) — 빌트인 6종(1.9.268 grok 추가). user provider는 동적으로 뒤에 추가.
|
|
69
|
+
const _PROVIDER_CYCLE_ORDER = ['ollama', 'claude', 'codex', 'agy', 'grok', 'opencode', 'qwen', 'aider', 'goose', 'copilot'];
|
|
70
|
+
|
|
71
|
+
// 1.9.148: planner/reviewer/actor 역할 시스템 프롬프트 (Gemini 권고 — 자기-승인 편향 방지)
|
|
72
|
+
const _AGENT_ROLE_PROMPTS = {
|
|
73
|
+
planner: '역할: planner. task를 step 3-6개로 분해, 각 step의 입출력/검증 방법 명시. 코드 작성 금지, 계획만.',
|
|
74
|
+
reviewer: '역할: reviewer. planner 의 계획 또는 actor 의 결과를 비판적으로 검토. 누락된 검증, 잠재 cascade, 오류 가능성 지적. 동의/수정 결론 명시.',
|
|
75
|
+
actor: '역할: actor. 계획에 따라 정확한 명령/코드만 실행. evidence(파일 경로 + 테스트 결과) 함께 기록. 새 계획 생성 금지.'
|
|
76
|
+
};
|
|
77
|
+
// ===== 1.9.270: Agent Roles — 모델별 역할 부여 (사용자 명시) =====
|
|
78
|
+
// 여러 AI 에이전트 활성 시 역할(코딩/검수/지휘/디자인/디버그/설계/분배)을 provider+model 에 매핑.
|
|
79
|
+
// 사용자 설정: .harness/agent-roles.json { schemaVersion, roles: { <role>: { provider, model, persona } } }
|
|
80
|
+
// dispatch --role <role> → 역할 기반 provider+model 라우팅. roles suggest → 활성 에이전트 기반 최적 배치 판단.
|
|
81
|
+
// 방향성 판단(사용자 요청): 모델별 강점이 분명하고(추론/코드/멀티모달) 작업이 분해 가능할 때, 역할 특화는
|
|
82
|
+
// 품질·정확도를 올림 — 강추론 모델의 독립 검수는 자기승인 편향을 차단, 코드 특화 모델은 구현 정확도↑.
|
|
83
|
+
// 단 조율 오버헤드 < 이득이어야 하므로 opt-in + verify(비활성 provider 배정 경고)로 오설정을 방지.
|
|
84
|
+
const ROLE_CATALOG = {
|
|
85
|
+
commander: { ko: '지휘관', desc: '전체 계획 수립·작업 분해·최종 의사결정', prefer: ['claude', 'codex', 'grok'], modelKind: 'top', why: '최강 추론 모델이 전체 맥락을 쥐고 분해/결정 → 일관성↑' },
|
|
86
|
+
reviewer: { ko: '검수자', desc: '구현 결과 비판적 검수·버그/누락 적발', prefer: ['claude', 'codex', 'grok'], modelKind: 'top', why: '독립 강추론 모델의 적대적 검수가 자기승인 편향 차단 → 정확도↑' },
|
|
87
|
+
coder: { ko: '코딩 담당', desc: '구현·패치·리팩터', prefer: ['codex', 'agy', 'claude', 'grok'], modelKind: 'code', why: '코드 특화 모델이 구현 정확도/속도↑' },
|
|
88
|
+
architect: { ko: '설계 담당', desc: '아키텍처·데이터 모델·인터페이스 설계', prefer: ['codex', 'claude'], modelKind: 'top', why: '깊은 코드 추론 모델이 설계 트레이드오프 분석' },
|
|
89
|
+
designer: { ko: '디자인 담당', desc: 'UI/UX·시각 디자인·레이아웃', prefer: ['agy', 'claude', 'grok'], modelKind: 'top', why: '멀티모달/시각 역량 모델이 디자인 산출물↑' },
|
|
90
|
+
debugger: { ko: '디버그 담당', desc: '버그 진단·근본원인·재현', prefer: ['codex', 'claude', 'grok'], modelKind: 'top', why: '깊은 추론 모델의 가설-검증이 디버깅 효율↑' },
|
|
91
|
+
dispatcher: { ko: '하위 분배 담당', desc: '서브에이전트 업무 분배·병렬 조율', prefer: ['claude', 'grok', 'codex'], modelKind: 'fast', why: '빠른 응답 모델이 분배 오버헤드↓' }
|
|
92
|
+
};
|
|
93
|
+
const _ROLE_ALIASES = {
|
|
94
|
+
'코딩': 'coder', '코더': 'coder', '코딩담당': 'coder',
|
|
95
|
+
'검수': 'reviewer', '검수자': 'reviewer', '리뷰': 'reviewer', '리뷰어': 'reviewer',
|
|
96
|
+
'지휘': 'commander', '지휘관': 'commander', '사령관': 'commander',
|
|
97
|
+
'디자인': 'designer', '디자인담당': 'designer',
|
|
98
|
+
'디버그': 'debugger', '디버거': 'debugger', '디버깅': 'debugger',
|
|
99
|
+
'설계': 'architect', '설계담당': 'architect', '아키텍트': 'architect',
|
|
100
|
+
'분배': 'dispatcher', '분배담당': 'dispatcher', '오케스트레이터': 'dispatcher'
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
module.exports = { _PROVIDER_MODEL_CATALOG, _AGENT_ROLE_PROMPTS, ROLE_CATALOG, _ROLE_ALIASES };
|
package/package.json
CHANGED
package/scripts/e2e.js
CHANGED
|
@@ -3181,5 +3181,26 @@ total++;
|
|
|
3181
3181
|
if (!ok) failed++;
|
|
3182
3182
|
}
|
|
3183
3183
|
|
|
3184
|
+
// 1.9.294 회귀 (UR-0025 3단계): lib/role-catalog.js 모듈 분리 — 단일출처 + 부작용 0
|
|
3185
|
+
total++;
|
|
3186
|
+
{
|
|
3187
|
+
let ok = false;
|
|
3188
|
+
try {
|
|
3189
|
+
const reg = require(path.resolve(__dirname, '..', 'lib', 'role-catalog.js'));
|
|
3190
|
+
const dataOk = reg.ROLE_CATALOG && Object.keys(reg.ROLE_CATALOG).length === 7 &&
|
|
3191
|
+
reg._PROVIDER_MODEL_CATALOG && Object.keys(reg._PROVIDER_MODEL_CATALOG).length === 10 &&
|
|
3192
|
+
reg._ROLE_ALIASES && Object.keys(reg._ROLE_ALIASES).length >= 14 &&
|
|
3193
|
+
reg._AGENT_ROLE_PROMPTS && reg._AGENT_ROLE_PROMPTS.actor;
|
|
3194
|
+
const harnessSrc = fs.readFileSync(path.resolve(__dirname, '..', 'bin', 'harness.js'), 'utf8');
|
|
3195
|
+
const movedOut = !/const ROLE_CATALOG = \{/.test(harnessSrc) && /require\('\.\.\/lib\/role-catalog'\)/.test(harnessSrc);
|
|
3196
|
+
// roles 명령이 여전히 동작 (모듈 require 후) — 회귀 방지
|
|
3197
|
+
const rr = cp.spawnSync(process.execPath, [CLI, 'roles', 'list', '--path', tmp, '--json'], { cwd: tmp, encoding: 'utf8', timeout: 20000 });
|
|
3198
|
+
const rolesOk = rr.status === 0;
|
|
3199
|
+
ok = dataOk && movedOut && rolesOk;
|
|
3200
|
+
} catch {}
|
|
3201
|
+
console.log(ok ? '✓ B(1.9.294) lib/role-catalog 모듈 분리: 단일출처 + 인라인 제거 + roles 동작 (UR-0025)' : '✗ role-catalog 모듈 분리 실패');
|
|
3202
|
+
if (!ok) failed++;
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3184
3205
|
console.log(`\nE2E result: ${total - failed}/${total} passed · ${((Date.now() - _e2eStart) / 1000).toFixed(0)}s`);
|
|
3185
3206
|
if (failed > 0) process.exit(1);
|