maskweaver 0.7.26 → 0.7.28

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.
Files changed (35) hide show
  1. package/assets/agents/squad-operator.md +56 -16
  2. package/assets/commands/weave-craft.md +189 -92
  3. package/assets/commands/weave-design.md +59 -31
  4. package/dist/plugin/index.d.ts.map +1 -1
  5. package/dist/plugin/index.js +73 -14
  6. package/dist/plugin/index.js.map +1 -1
  7. package/dist/plugin/tools/squad.d.ts +1 -0
  8. package/dist/plugin/tools/squad.d.ts.map +1 -1
  9. package/dist/plugin/tools/squad.js +49 -2
  10. package/dist/plugin/tools/squad.js.map +1 -1
  11. package/dist/plugin/tools/weave.js +8 -12
  12. package/dist/plugin/tools/weave.js.map +1 -1
  13. package/dist/shared/config.d.ts +46 -1
  14. package/dist/shared/config.d.ts.map +1 -1
  15. package/dist/shared/config.js +34 -0
  16. package/dist/shared/config.js.map +1 -1
  17. package/dist/shared/model-registry.d.ts +126 -0
  18. package/dist/shared/model-registry.d.ts.map +1 -0
  19. package/dist/shared/model-registry.js +318 -0
  20. package/dist/shared/model-registry.js.map +1 -0
  21. package/dist/weave/bridge.d.ts +61 -0
  22. package/dist/weave/bridge.d.ts.map +1 -0
  23. package/dist/weave/bridge.js +143 -0
  24. package/dist/weave/bridge.js.map +1 -0
  25. package/dist/weave/orchestrator.d.ts +59 -1
  26. package/dist/weave/orchestrator.d.ts.map +1 -1
  27. package/dist/weave/orchestrator.js +228 -0
  28. package/dist/weave/orchestrator.js.map +1 -1
  29. package/dist/weave/stages/execute.d.ts +35 -7
  30. package/dist/weave/stages/execute.d.ts.map +1 -1
  31. package/dist/weave/stages/execute.js +136 -267
  32. package/dist/weave/stages/execute.js.map +1 -1
  33. package/dist/weave/types.d.ts +20 -0
  34. package/dist/weave/types.d.ts.map +1 -1
  35. package/package.json +1 -1
@@ -133,17 +133,56 @@ permission:
133
133
  3. **진행 관리**: task 상태 모니터링 및 업데이트
134
134
  4. **결과 통합**: 워커 결과를 수집하고 가면술사에게 보고
135
135
 
136
- ## 사용 가능한 도구
137
-
138
- ### squad 도구
139
- - `squad({ action: "assign", squadId, description, assignee, priority })` - task 할당
140
- - `squad({ action: "update", squadId, taskId, status })` - 상태 업데이트
141
- - `squad({ action: "complete", squadId, taskId, success, output })` - 완료 처리
142
- - `squad({ action: "status", squadId })` - 현재 상태 조회
143
- - `squad({ action: "watchdog", dryRun: true })` - 건강 체크
144
-
145
- ### Task 도구
146
- - 더미인간 소환 가능 (다른 워커에게 위임)
136
+ ## 사용 가능한 도구
137
+
138
+ ### squad 도구
139
+ - `squad({ action: "assign", squadId, description, assignee, priority })` - task 할당
140
+ - `squad({ action: "update", squadId, taskId, status })` - 상태 업데이트
141
+ - `squad({ action: "complete", squadId, taskId, success, output })` - 완료 처리
142
+ - `squad({ action: "status", squadId })` - 현재 상태 조회
143
+ - `squad({ action: "watchdog", dryRun: true })` - 건강 체크
144
+ - `squad({ action: "models" })` - **모델 풀 상태 조회** (가용 슬롯, 능력, 동시실행 현황)
145
+
146
+ ### Task 도구
147
+ - 더미인간 소환 가능 (다른 워커에게 위임)
148
+
149
+ ## 모델 풀 기반 워커 할당
150
+
151
+ ### 모델 풀 시스템
152
+ 사용자의 AI 구독 모델들은 **풀(pool)**로 관리됩니다. 각 모델은:
153
+ - **동시실행 제한**: `maxConcurrent` 개까지만 동시에 사용 가능
154
+ - **능력 태그**: 모델마다 잘하는 분야가 다름 (coding, architecture, debugging 등)
155
+ - **비용 등급**: low / medium / high
156
+
157
+ ### 작업 할당 전 모델 확인
158
+ 작업 할당 전 반드시 `squad({ action: "models" })`로 가용 모델을 확인하세요:
159
+ ```
160
+ squad({ action: "models" })
161
+ → {
162
+ totalCapacity: 6,
163
+ totalAvailable: 4,
164
+ models: [
165
+ { id: "gemini-flash", agentName: "dummy-gemini-flash", tier: "flash",
166
+ maxConcurrent: 5, activeCount: 1, remainingSlots: 4, capabilities: [...] },
167
+ { id: "claude-opus", agentName: "dummy-claude-opus", tier: "premium",
168
+ maxConcurrent: 1, activeCount: 1, remainingSlots: 0, available: false },
169
+ ]
170
+ }
171
+ ```
172
+
173
+ ### 할당 전략
174
+ 1. **모델 확인**: `squad({ action: "models" })`로 가용 현황 파악
175
+ 2. **작업 매칭**: 작업의 복잡도와 특성에 맞는 모델 선택
176
+ - 단순 작업 (파일 정리, 포매팅) → flash 티어 모델
177
+ - 일반 코딩 → human 티어 모델
178
+ - 복잡한 설계/디버깅 → premium 티어 모델
179
+ 3. **동시실행 고려**: 해당 모델의 `remainingSlots`이 0이면 다른 모델 사용
180
+ 4. **fallback**: 원하는 티어가 꽉 찼으면 비슷한 능력의 다른 모델 사용
181
+
182
+ ### assignee 지정 방식
183
+ `assignee` 필드에 **에이전트 이름**을 사용합니다:
184
+ - 풀 모델: `"dummy-{모델id}"` (예: `"dummy-gemini-flash"`, `"dummy-claude-opus"`)
185
+ - 레거시: `"dummy-flash"`, `"dummy-human"`, `"dummy-premium"`
147
186
 
148
187
  ## 워크플로우
149
188
 
@@ -190,8 +229,9 @@ squad({ action: "plan", squadId })
190
229
  - 실패한 task 및 원인 (있는 경우)
191
230
  - 총 소요 시간
192
231
 
193
- ## 제약사항
194
-
195
- - 한 번에 최대 5개 워커 관리
196
- - task당 최대 5분 타임아웃
197
- - 실패 시 재시도 1회
232
+ ## 제약사항
233
+
234
+ - 한 번에 최대 5개 워커 관리
235
+ - task당 최대 5분 타임아웃
236
+ - 실패 시 재시도 1회
237
+ - **모델별 동시실행 제한 준수** (반드시 `squad({ action: "models" })`로 확인 후 할당)
@@ -50,30 +50,38 @@ AI가 자동으로 검증 루프를 돌리고, 완료되면 유저에게 전달
50
50
 
51
51
  ---
52
52
 
53
- ## 실행 흐름
54
-
55
- ```
56
- 0. LOAD PLAN (활성 플랜 + Phase 정보 로드)
57
-
58
- 1. UNDERSTAND (Phase 요구사항 확인)
59
-
60
- 2. DESIGN (Task 분해 + 설계)
61
-
62
- 3. BUILD + SELF-VERIFY LOOP
63
- ├─ Task에 대해:
64
- │ ├─ 적합한 마스크 자동 선택
65
- │ ├─ 테스트 먼저 (Red)
66
- ├─ 최소 구현 (Green)
67
- ├─ 정리 (Refactor)
68
- └─ AI 자동 검증 → PASS/FAIL
69
- │ ├─ PASS → 다음 Task
70
- │ └─ FAIL 글로벌 지식 검색 → 수정 → 재검증
71
- └─ 5회 초과 → 유저에게 도움 요청
72
-
73
- 4. UPDATE PLAN (Phase 상태 업데이트)
74
-
75
- 5. USER HANDOFF (검증 완료 → 유저 테스트)
76
- ```
53
+ ## 실행 흐름
54
+
55
+ ```
56
+ 0. LOAD PLAN (활성 플랜 + Phase 정보 로드)
57
+
58
+ 1. GENERATE EXECUTION PLAN (자동 분석)
59
+ ├─ 각 Task의 복잡도 판단 (simple/standard/complex)
60
+ ├─ 에이전트 티어 선택 (flash/human/premium)
61
+ ├─ 전문가 마스크 자동 선택
62
+ ├─ 글로벌 지식에서 트러블슈팅 힌트 검색
63
+ └─ 병렬 실행 가능 여부 분석
64
+
65
+ 2. DELEGATE (실행 계획에 따라 작업 위임)
66
+ ├─ simple → dummy-flash (빠르고 저렴)
67
+ ├─ standard → dummy-human (범용)
68
+ └─ complex → dummy-premium (강력한 추론)
69
+
70
+ 3. BUILD + SELF-VERIFY LOOP
71
+ ├─ Task에 대해:
72
+ │ ├─ 적합한 마스크 자동 선택
73
+ │ ├─ 테스트 먼저 (Red)
74
+ │ ├─ 최소 구현 (Green)
75
+ │ ├─ 정리 (Refactor)
76
+ │ └─ AI 자동 검증 → PASS/FAIL
77
+ │ ├─ PASS → 다음 Task
78
+ │ └─ FAIL → 글로벌 지식 검색 → 수정 → 재검증
79
+ └─ 5회 초과 → 유저에게 도움 요청
80
+
81
+ 4. UPDATE PLAN (Phase 상태 업데이트)
82
+
83
+ 5. USER HANDOFF (검증 완료 → 유저 테스트)
84
+ ```
77
85
 
78
86
  ---
79
87
 
@@ -98,9 +106,32 @@ You are the **Mask Weaver**. During execution, your role is to **orchestrate exp
98
106
 
99
107
  ---
100
108
 
101
- ### 1. Task Complexity → Execution Strategy
102
-
103
- #### Handle Directly (Simple Tasks)
109
+ ### 1. Task Complexity → Execution Strategy
110
+
111
+ **The Orchestrator automatically assesses task complexity and selects the agent tier.**
112
+
113
+ When `weave craft P1` is called, the system generates an execution plan like:
114
+
115
+ ```markdown
116
+ ## Phase P1: Emotion Selection UI
117
+
118
+ ### Execution Plan
119
+ | # | Task | Complexity | Agent Tier | Mask |
120
+ |---|-------------------|-----------|------------|---------------|
121
+ | 1 | Update imports | simple | flash | auto |
122
+ | 2 | Build component | standard | human | dan-abramov |
123
+ | 3 | Auth refactoring | complex | premium | martin-fowler |
124
+ ```
125
+
126
+ **Agent Tier Selection Rules:**
127
+
128
+ | Complexity | Agent Tier | Use When |
129
+ |-----------|------------|----------|
130
+ | simple | `dummy-flash` | File renames, import fixes, formatting, config changes, lint fixes |
131
+ | standard | `dummy-human` | Component implementation, API endpoints, tests, validation |
132
+ | complex | `dummy-premium` | Architecture refactoring, debugging, auth, state management, performance |
133
+
134
+ #### Handle Directly (Simple Tasks)
104
135
 
105
136
  ```
106
137
  Examples:
@@ -173,19 +204,22 @@ Mask Weaver:
173
204
 
174
205
  ---
175
206
 
176
- ### 3. Execution Decision Flow
177
-
178
- ```
179
- Analyze Task
180
-
181
- Can you finish in 5 minutes?
182
- ├─ YES → Handle directly
183
- └─ NO → Single focused task?
184
- ├─ YESSummon domain expert
185
- └─ NOMultiple independent tasks?
186
- ├─ YESSquad parallel
187
- └─ NO → Sequential expert delegation
188
- ```
207
+ ### 3. Execution Decision Flow
208
+
209
+ ```
210
+ Execution Plan Generated (automatic)
211
+
212
+ For each task in plan:
213
+
214
+ Check Agent Tier:
215
+ ├─ flash (simple) Handle directly or Task(dummy-flash)
216
+ ├─ human (standard) Task(dummy-human) with mask
217
+ └─ premium (complex) Task(dummy-premium) with mask
218
+
219
+ Multiple independent tasks in same wave?
220
+ ├─ YES → Run in parallel (Squad system)
221
+ └─ NO → Run sequentially
222
+ ```
189
223
 
190
224
  ---
191
225
 
@@ -235,61 +269,124 @@ Stuck on performance issue:
235
269
 
236
270
  ---
237
271
 
238
- ## Step 4: UPDATE PLAN
239
-
240
- Phase 완료 시 플랜 파일을 업데이트합니다:
241
-
242
- ```yaml
243
- # .opencode/weave/plans/{active_plan}.yaml 내 해당 Phase 업데이트:
244
- phases:
245
- - id: "P1"
246
- status: "completed" # pendingin_progress completed
247
- started_at: "2026-02-06T10:30:00"
248
- completed_at: "2026-02-06T13:00:00"
249
- masks_used:
250
- - name: "kent-beck"
251
- tasks: 2
252
- effectiveness: 0.9
253
- - name: "dan-abramov"
254
- tasks: 1
255
- effectiveness: 0.85
256
- retry_count: 1
257
- issues:
258
- - "JSON 직렬화 오류 → useEffect 의존성 추가로 해결"
259
- ```
272
+ ## Step 4: UPDATE PLAN
273
+
274
+ Phase 완료 시 플랜 파일을 업데이트합니다.
275
+
276
+ > ⚠️ **YAML 작성 규칙 (반드시 준수)**
277
+ >
278
+ > 플랜 YAML을 직접 수정할 때, `done_when` 등 문자열 값은 반드시 아래 규칙을 따릅니다:
279
+ >
280
+ > - **짧은 값** (한 줄): double-quote 사용`done_when: "로그인 기능 동작"`
281
+ > - **긴 값** (여러 줄): block scalar(`|`) 사용 → `done_when: |` 후 들여쓰기된 내용
282
+ > - **❌ 절대 금지**: double-quote(`"`)로 시작한 문자열을 다른 줄에서 닫는 것
283
+ >
284
+ > **핵심**: `"` 로 시작했으면 **같은 줄에서** `"` 로 닫기. 줄바꿈이 필요하면 `|` 사용.
285
+
286
+ ```yaml
287
+ # .opencode/weave/plans/{active_plan}.yaml 내 해당 Phase 업데이트:
288
+ phases:
289
+ - id: "P1"
290
+ status: "completed" # pending → in_progress → completed
291
+ done_when: "유저가 감정을 선택할 수 있다" # 짧으면 한 줄 quote
292
+ started_at: "2026-02-06T10:30:00"
293
+ completed_at: "2026-02-06T13:00:00"
294
+ masks_used:
295
+ - name: "kent-beck"
296
+ tasks: 2
297
+ effectiveness: 0.9
298
+ - name: "dan-abramov"
299
+ tasks: 1
300
+ effectiveness: 0.85
301
+ retry_count: 1
302
+ issues:
303
+ - "JSON 직렬화 오류 → useEffect 의존성 추가로 해결"
304
+ ```
260
305
 
261
306
  ---
262
307
 
263
- ## 유저 핸드오프
264
-
265
- 모든 Task 통과 후:
266
-
267
- ```markdown
268
- ## ✅ Phase P1 검증 완료!
269
-
270
- **플랜**: `emotion-diary`
271
-
272
- ### AI 자동 테스트 결과
273
- | 테스트 | 결과 |
274
- |--------|------|
275
- | Build | ✅ 성공 |
276
- | Unit Tests | ✅ 15/15 |
277
- | Lint | 통과 |
278
-
279
- ### 사용된 마스크
280
- - Kent Beck (테스트)
281
- - Dan Abramov (React 컴포넌트)
282
-
283
- ### 접속
284
- http://localhost:5173
285
-
286
- ### 사람만 판단 가능한 것
287
- - [ ] 느낌이 의도대로인가요?
288
- - [ ] 사용성이 좋은가요?
289
- - [ ] 원하던 기능이 맞나요?
290
-
291
- **다음**: `/weave-craft P2` | **상태**: `/weave-status`
292
- ```
308
+ ## 유저 핸드오프
309
+
310
+ 모든 Task 통과 후:
311
+
312
+ ### 1. AI 사전 체험 (Virtual User Test)
313
+
314
+ 코드 검증이 끝나면, **가상의 대상 사용자 페르소나**를 만들어 주관적 항목을 먼저 평가한다.
315
+
316
+ #### 페르소나 생성 기준
317
+
318
+ 플랜의 목적과 대상 사용자를 기반으로 적절한 페르소나를 구성한다:
319
+
320
+ ```yaml
321
+ virtual_user:
322
+ name: "직장인 김지수 (30대)" # 프로젝트 대상에 맞는 가상 인물
323
+ context: "퇴근 후 하루를 정리하며 감정 기록" # 사용 맥락
324
+ goals: "간단하고 빠르게 오늘의 감정을 남기고 싶다"
325
+ tech_level: "일반 사용자" # 기술 수준
326
+ ```
327
+
328
+ #### 평가 항목
329
+
330
+ 페르소나 관점에서 다음을 평가한다:
331
+
332
+ | 항목 | 평가 관점 |
333
+ |------|----------|
334
+ | **느낌/톤** | UI 분위기가 프로젝트 의도와 맞는가? (스크린샷 기반) |
335
+ | **사용 흐름** | 핵심 동작이 직관적으로 완료되는가? (클릭 수, 동선) |
336
+ | **기능 일치** | 플랜에 정의된 기능이 실제로 동작하는가? |
337
+ | **첫인상** | 처음 본 사용자가 헤매지 않을까? |
338
+
339
+ #### 평가 방법
340
+
341
+ - **스크린샷 촬영**: 브라우저로 주요 화면을 캡처하여 시각적으로 확인
342
+ - **동선 시뮬레이션**: 핵심 시나리오를 실제로 클릭하며 체험
343
+ - **플랜 대조**: 원래 요구사항과 구현 결과를 항목별로 비교
344
+
345
+ ### 2. 핸드오프 메시지 형식
346
+
347
+ ```markdown
348
+ ## ✅ Phase P1 검증 완료!
349
+
350
+ **플랜**: `emotion-diary`
351
+
352
+ ### AI 자동 테스트 결과
353
+ | 테스트 | 결과 |
354
+ |--------|------|
355
+ | Build | ✅ 성공 |
356
+ | Unit Tests | ✅ 15/15 |
357
+ | Lint | ✅ 통과 |
358
+
359
+ ### 사용된 마스크
360
+ - Kent Beck (테스트)
361
+ - Dan Abramov (React 컴포넌트)
362
+
363
+ ### 접속
364
+ http://localhost:5173
365
+
366
+ ### AI 사전 체험 결과
367
+
368
+ > 💡 **"직장인 김지수 (30대)"** 관점으로 먼저 사용해봤습니다.
369
+ > 한번 확인해보세요.
370
+
371
+ | 항목 | AI 평가 | 비고 |
372
+ |------|---------|------|
373
+ | 느낌/톤 | ✅ 부드러운 파스텔 톤이 감정 기록 앱에 적합해 보입니다 | 스크린샷 첨부 |
374
+ | 사용 흐름 | ⚠️ 감정 선택 → 저장까지 3탭인데, 2탭이면 더 자연스러울 것 같습니다 | 중간 확인 화면 생략 검토 |
375
+ | 기능 일치 | ✅ 감정 선택 UI가 플랜대로 동작합니다 | - |
376
+ | 첫인상 | ✅ 아이콘만으로 감정이 구분됩니다 | - |
377
+
378
+ > 위 내용은 AI가 가상 사용자로서 판단한 것입니다.
379
+ > 실제 느낌과 다를 수 있으니 직접 확인 부탁드립니다.
380
+
381
+ **다음**: `/weave-craft P2` | **상태**: `/weave-status`
382
+ ```
383
+
384
+ ### 3. 핵심 원칙
385
+
386
+ - **빈 체크박스를 던지지 않는다**: AI가 먼저 체험하고 소견을 제시한다
387
+ - **단정하지 않는다**: "~해 보입니다", "~인 것 같습니다" 톤으로 제안한다
388
+ - **유저 판단을 대체하지 않는다**: 최종 확인은 반드시 유저 몫
389
+ - **구체적 근거를 붙인다**: 스크린샷, 클릭 수, 플랜 대조 등 판단 근거를 함께 제시
293
390
 
294
391
  ---
295
392
 
@@ -190,37 +190,65 @@ Mask Weaver:
190
190
 
191
191
  ---
192
192
 
193
- ### Step 5: APPROVE
194
-
195
- **플랜 파일 생성**: `.opencode/weave/plans/{plan-name}.yaml`
196
-
197
- ```yaml
198
- plan_name: "emotion-diary"
199
- project_name: "감정 일기 앱"
200
- created_at: "2026-02-06"
201
- status: "active" # active | paused | completed | archived
202
-
203
- vision: |
204
- [전체 비전]
205
-
206
- architecture:
207
- frontend: "[...]"
208
- backend: "[...]"
209
- database: "[...]"
210
-
211
- phases:
212
- - id: "P1"
213
- name: "[Phase 이름]"
214
- status: "pending" # pending | in_progress | completed
215
- done_when: "[완료 조건]"
216
- started_at: null
217
- completed_at: null
218
- masks_used: []
219
- checklist:
220
- - "[체크 항목 1]"
221
- - "[체크 항목 2]"
222
- tasks: []
223
- ```
193
+ ### Step 5: APPROVE
194
+
195
+ **플랜 파일 생성**: `.opencode/weave/plans/{plan-name}.yaml`
196
+
197
+ > ⚠️ **YAML 작성 규칙 (반드시 준수)**
198
+ >
199
+ > `done_when`, `vision` 등 **긴 문자열 값**은 반드시 아래 규칙을 따릅니다:
200
+ >
201
+ > | 상황 | 사용할 표기법 | 예시 |
202
+ > |------|-------------|------|
203
+ > | 한 줄로 끝나는 짧은 값 | double-quote (`"`) | `done_when: "로그인 기능 동작"` |
204
+ > | 여러 줄 또는 긴 값 | block scalar (`\|`) | 아래 예시 참고 |
205
+ > | ❌ 절대 금지 | 여러 줄에 걸친 double-quote | `done_when: "1단계...\n2단계..."` |
206
+ >
207
+ > ```yaml
208
+ > # ✅ 올바른 예시 - 짧은 값
209
+ > done_when: "유저가 감정을 선택할 수 있다"
210
+ >
211
+ > # ✅ 올바른 예시 - 긴 값 (block scalar)
212
+ > done_when: |
213
+ > 1. 유저가 감정을 선택할 수 있다
214
+ > 2. 선택한 감정이 저장된다
215
+ > 3. 저장 확인 메시지가 표시된다
216
+ >
217
+ > # ❌ 잘못된 예시 - 닫는 따옴표가 다른 줄에 있음 (YAML 파싱 실패!)
218
+ > done_when: "1. 유저가 감정을 선택할 수 있다
219
+ > 2. 선택한 감정이 저장된다
220
+ > 3. 저장 확인 메시지가 표시된다"
221
+ > ```
222
+ >
223
+ > **핵심 원칙**: `"` 로 시작했으면 **같은 줄에서** `"` 로 닫아야 합니다. 줄바꿈이 필요하면 `|` 를 사용하세요.
224
+
225
+ ```yaml
226
+ plan_name: "emotion-diary"
227
+ project_name: "감정 일기 앱"
228
+ created_at: "2026-02-06"
229
+ status: "active" # active | paused | completed | archived
230
+
231
+ vision: |
232
+ [전체 비전]
233
+
234
+ architecture:
235
+ frontend: "[...]"
236
+ backend: "[...]"
237
+ database: "[...]"
238
+
239
+ phases:
240
+ - id: "P1"
241
+ name: "[Phase 이름]"
242
+ status: "pending" # pending | in_progress | completed
243
+ done_when: "[짧으면 한 줄 double-quote, 길면 | 블록 스칼라 사용]"
244
+ started_at: null
245
+ completed_at: null
246
+ masks_used: []
247
+ checklist:
248
+ - "[체크 항목 1]"
249
+ - "[체크 항목 2]"
250
+ tasks: []
251
+ ```
224
252
 
225
253
  **state.yaml 업데이트**:
226
254
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;EAcE;AAEF,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA2xBxD,eAAO,MAAM,gBAAgB,EAAE,MAoY9B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;EAcE;AAEF,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA2xBxD,eAAO,MAAM,gBAAgB,EAAE,MAmc9B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -872,21 +872,80 @@ export const MaskweaverPlugin = async ({ client, directory }) => {
872
872
  const projectOpencodeDir = path.join(directory, '.opencode');
873
873
  // Load from package assets first, then project .opencode (project overrides package)
874
874
  const loadedAgents = loadAgentAssets(assetsDir, projectOpencodeDir);
875
- // Add variants for dummy-human
876
- if (loadedAgents['dummy-human']) {
877
- if (!loadedAgents['dummy-flash']) {
878
- loadedAgents['dummy-flash'] = {
879
- ...loadedAgents['dummy-human'],
880
- description: 'Dummy-Human (Flash) - Fast and cheap',
881
- model: 'google/gemini-2.0-flash',
882
- };
875
+ // ==========================================================================
876
+ // 8b. Generate agents from model pool (or legacy fallback)
877
+ // ==========================================================================
878
+ {
879
+ const { loadRuntimeConfig, normalizeDummyHumansConfig } = await import('../shared/config.js');
880
+ const { createModelRegistry } = await import('../shared/model-registry.js');
881
+ const runtimeConfig = loadRuntimeConfig(directory);
882
+ if (runtimeConfig.dummyHumans) {
883
+ const pool = normalizeDummyHumansConfig(runtimeConfig.dummyHumans);
884
+ // Initialize the global model registry
885
+ createModelRegistry(pool);
886
+ if (loadedAgents['dummy-human']) {
887
+ // Generate agent variants from pool entries
888
+ for (const entry of pool) {
889
+ const agentName = `dummy-${entry.id}`;
890
+ if (!loadedAgents[agentName]) {
891
+ const tierLabel = entry.tier === 'flash' ? 'Flash' : entry.tier === 'premium' ? 'Premium' : 'Standard';
892
+ const capStr = entry.capabilities.slice(0, 3).join(', ');
893
+ loadedAgents[agentName] = {
894
+ ...loadedAgents['dummy-human'],
895
+ description: `Dummy-Human (${entry.id}) - ${tierLabel}. ${entry.description || capStr}. [max ${entry.maxConcurrent} concurrent]`,
896
+ model: entry.model,
897
+ };
898
+ }
899
+ }
900
+ // Also ensure legacy dummy-flash / dummy-premium aliases exist (for backward compat)
901
+ const flashEntry = pool.find(e => e.tier === 'flash');
902
+ const humanEntry = pool.find(e => e.tier === 'human');
903
+ const premiumEntry = pool.find(e => e.tier === 'premium');
904
+ if (flashEntry && !loadedAgents['dummy-flash']) {
905
+ loadedAgents['dummy-flash'] = loadedAgents[`dummy-${flashEntry.id}`];
906
+ }
907
+ if (humanEntry) {
908
+ // dummy-human already exists as the base agent; just update its model from pool
909
+ loadedAgents['dummy-human'].model = humanEntry.model;
910
+ }
911
+ if (premiumEntry && !loadedAgents['dummy-premium']) {
912
+ loadedAgents['dummy-premium'] = loadedAgents[`dummy-${premiumEntry.id}`];
913
+ }
914
+ // Fallback: if no tier mapping found, use defaults
915
+ if (!loadedAgents['dummy-flash']) {
916
+ loadedAgents['dummy-flash'] = {
917
+ ...loadedAgents['dummy-human'],
918
+ description: 'Dummy-Human (Flash) - Fast and cheap',
919
+ model: 'google/gemini-2.0-flash',
920
+ };
921
+ }
922
+ if (!loadedAgents['dummy-premium']) {
923
+ loadedAgents['dummy-premium'] = {
924
+ ...loadedAgents['dummy-human'],
925
+ description: 'Dummy-Human (Premium) - Powerful and reasoning',
926
+ model: 'google/gemini-2.0-pro-exp-02-05',
927
+ };
928
+ }
929
+ }
883
930
  }
884
- if (!loadedAgents['dummy-premium']) {
885
- loadedAgents['dummy-premium'] = {
886
- ...loadedAgents['dummy-human'],
887
- description: 'Dummy-Human (Premium) - Powerful and reasoning',
888
- model: 'google/gemini-2.0-pro-exp-02-05',
889
- };
931
+ else {
932
+ // No pool config → legacy hardcoded defaults
933
+ if (loadedAgents['dummy-human']) {
934
+ if (!loadedAgents['dummy-flash']) {
935
+ loadedAgents['dummy-flash'] = {
936
+ ...loadedAgents['dummy-human'],
937
+ description: 'Dummy-Human (Flash) - Fast and cheap',
938
+ model: 'google/gemini-2.0-flash',
939
+ };
940
+ }
941
+ if (!loadedAgents['dummy-premium']) {
942
+ loadedAgents['dummy-premium'] = {
943
+ ...loadedAgents['dummy-human'],
944
+ description: 'Dummy-Human (Premium) - Powerful and reasoning',
945
+ model: 'google/gemini-2.0-pro-exp-02-05',
946
+ };
947
+ }
948
+ }
890
949
  }
891
950
  }
892
951
  // Apply config overrides to agents