maskweaver 0.8.3 → 0.8.4
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/README.ko.md +50 -14
- package/README.md +50 -14
- package/dist/plugin/tools/weave.d.ts.map +1 -1
- package/dist/plugin/tools/weave.js +234 -14
- package/dist/plugin/tools/weave.js.map +1 -1
- package/dist/shared/config.d.ts +14 -0
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/shared/config.js +7 -0
- package/dist/shared/config.js.map +1 -1
- package/dist/shared-context/test/squad.test.js +2 -2
- package/dist/shared-context/test/squad.test.js.map +1 -1
- package/dist/shared-context/test/storage.test.js +3 -3
- package/dist/shared-context/test/storage.test.js.map +1 -1
- package/dist/shared-context/test/task.test.js +6 -6
- package/dist/shared-context/test/task.test.js.map +1 -1
- package/dist/weave/gdc.d.ts +59 -0
- package/dist/weave/gdc.d.ts.map +1 -0
- package/dist/weave/gdc.js +221 -0
- package/dist/weave/gdc.js.map +1 -0
- package/dist/weave/stages/research.d.ts +1 -1
- package/dist/weave/stages/research.d.ts.map +1 -1
- package/dist/weave/stages/research.js +225 -5
- package/dist/weave/stages/research.js.map +1 -1
- package/package.json +8 -2
package/README.ko.md
CHANGED
|
@@ -24,9 +24,10 @@
|
|
|
24
24
|
- **전문가 페르소나 (Masks)**: 전설적인 개발자들의 철학을 담은 표준 YAML 프로필.
|
|
25
25
|
- **스마트 위임**: OpenCode에 최적화된 멀티 에이전트 워크플로우.
|
|
26
26
|
- **프로젝트 메모리**: 코드베이스 전체에 대한 하이브리드 의미론적 검색.
|
|
27
|
-
- **🆕 Weave 워크플로우**: AI 자체 검증이 포함된 Phase 기반 개발.
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
- **🆕 Weave 워크플로우**: AI 자체 검증이 포함된 Phase 기반 개발.
|
|
28
|
+
- **🔗 GDC 통합**: Graph-Driven Codebase 지원으로 리서치 품질 향상 및 설계 시점 검증 게이트 추가.
|
|
29
|
+
|
|
30
|
+
---
|
|
30
31
|
|
|
31
32
|
## 왜 Maskweaver인가요?
|
|
32
33
|
|
|
@@ -227,9 +228,43 @@ Weave는 Maskweaver의 핵심 워크플로우입니다. 작업을 테스트 가
|
|
|
227
228
|
| 5️⃣ E2E Tests | 테스트 | **Playwright** |
|
|
228
229
|
| 6️⃣ Screenshot | 시각 | Playwright / 브라우저 캡처 |
|
|
229
230
|
| 7️⃣ API Check | API | `fetch` 헬스 체크 |
|
|
230
|
-
| 8️⃣ A11y | 접근성 | `axe-core` |
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
| 8️⃣ A11y | 접근성 | `axe-core` |
|
|
232
|
+
| 0️⃣ GDC Check | 설계 | `gdc check --machine` |
|
|
233
|
+
|
|
234
|
+
#### GDC 통합 (Graph-Driven Codebase)
|
|
235
|
+
|
|
236
|
+
Weave는 [GDC](https://github.com/ulgerang/gdc)(Graph-Driven Codebase)와 통합되어 리서치 품질을 향상시키고 설계 시점 검증 게이트를 추가합니다:
|
|
237
|
+
|
|
238
|
+
**리서치 강화:**
|
|
239
|
+
- `.gdc` 워크스페이스 자동 감지
|
|
240
|
+
- GDC `stats`, `graph`, `check` 결과를 `tasks/research.md`에 포함
|
|
241
|
+
- 그래프 엣지 기반 의존성 영향 범위(Blast Radius) 분석
|
|
242
|
+
- 기능 키워드와 매칭된 재사용 후보 노드
|
|
243
|
+
- 새 보고서 섹션: `GDC Node Coverage`, `Dependency Blast Radius`, `Existing Spec vs Implementation Drift`, `Candidate Reuse Nodes`
|
|
244
|
+
|
|
245
|
+
**Pre-Verify 게이트:**
|
|
246
|
+
GDC가 감지되면 `weave verify`와 `weave flow`가 자동으로 실행:
|
|
247
|
+
1. `gdc sync --machine` - 스펙과 구현 동기화
|
|
248
|
+
2. `gdc check --machine` - 스펙/구현 일치성 검증
|
|
249
|
+
|
|
250
|
+
GDC check의 블로킹 에러는 검증을 중단시킵니다(`strictVerify` 모드로 설정 가능).
|
|
251
|
+
|
|
252
|
+
**설정** (`maskweaver.config.json`):
|
|
253
|
+
```json
|
|
254
|
+
{
|
|
255
|
+
"gdc": {
|
|
256
|
+
"enabled": "auto",
|
|
257
|
+
"strictVerify": false,
|
|
258
|
+
"autoSyncOnPrepare": true
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
- `enabled`: `true` | `false` | `"auto"` (기본값: `.gdc` 디렉터리 자동 감지)
|
|
264
|
+
- `strictVerify`: `true`면 GDC check 실패 시 검증 차단; `false`면 경고 후 계속 진행
|
|
265
|
+
- `autoSyncOnPrepare`: `weave prepare` 시 `gdc sync` 실행
|
|
266
|
+
|
|
267
|
+
#### 마스크 자동 선택
|
|
233
268
|
|
|
234
269
|
AI가 각 작업에 가장 적합한 전문가를 자동으로 선택합니다:
|
|
235
270
|
|
|
@@ -333,14 +368,15 @@ import { MaskLoader } from 'maskweaver/core';
|
|
|
333
368
|
import { WeaveOrchestrator, GlobalKnowledge } from 'maskweaver/weave';
|
|
334
369
|
```
|
|
335
370
|
|
|
336
|
-
**모듈:**
|
|
337
|
-
- `maskweaver/core` - 가면 로딩, 검증 (YAML/JSON)
|
|
338
|
-
- `maskweaver/memory` - 임베딩 + 벡터 검색 (5개 프로바이더)
|
|
339
|
-
- `maskweaver/context` - 기능 기반 작업 추적
|
|
340
|
-
- `maskweaver/verify` - 교차 가면 코드 리뷰
|
|
341
|
-
- `maskweaver/retrospect` - 세션 효과 분석
|
|
342
|
-
- `maskweaver/weave` - Phase 기반 개발 워크플로우
|
|
343
|
-
- `maskweaver/
|
|
371
|
+
**모듈:**
|
|
372
|
+
- `maskweaver/core` - 가면 로딩, 검증 (YAML/JSON)
|
|
373
|
+
- `maskweaver/memory` - 임베딩 + 벡터 검색 (5개 프로바이더)
|
|
374
|
+
- `maskweaver/context` - 기능 기반 작업 추적
|
|
375
|
+
- `maskweaver/verify` - 교차 가면 코드 리뷰
|
|
376
|
+
- `maskweaver/retrospect` - 세션 효과 분석
|
|
377
|
+
- `maskweaver/weave` - Phase 기반 개발 워크플로우
|
|
378
|
+
- `maskweaver/gdc` - GDC(Graph-Driven Codebase) 통합 유틸리티
|
|
379
|
+
- `maskweaver/plugin` - OpenCode 플러그인 엔트리 포인트
|
|
344
380
|
|
|
345
381
|
---
|
|
346
382
|
|
package/README.md
CHANGED
|
@@ -24,9 +24,10 @@ While it can be used as a standalone library, it works great with OpenCode to ad
|
|
|
24
24
|
- **Expert Personas (Masks)**: Standardized YAML profiles for legendary developers.
|
|
25
25
|
- **Smart Delegation**: Multi-agent workflows optimized for OpenCode.
|
|
26
26
|
- **Project Memory**: Hybrid semantic search for your entire codebase.
|
|
27
|
-
- **🆕 Weave Workflow**: Phase-driven development with AI self-verification.
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
- **🆕 Weave Workflow**: Phase-driven development with AI self-verification.
|
|
28
|
+
- **🔗 GDC Integration**: Graph-Driven Codebase support for enhanced research and design-time verification gates.
|
|
29
|
+
|
|
30
|
+
---
|
|
30
31
|
|
|
31
32
|
## Why Maskweaver?
|
|
32
33
|
|
|
@@ -246,9 +247,43 @@ Before handing off to you, AI runs these verification layers:
|
|
|
246
247
|
| 5️⃣ E2E Tests | Test | **Playwright** |
|
|
247
248
|
| 6️⃣ Screenshot | Visual | Playwright / browser capture |
|
|
248
249
|
| 7️⃣ API Check | API | `fetch` health checks |
|
|
249
|
-
| 8️⃣ A11y | Accessibility | `axe-core` |
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
| 8️⃣ A11y | Accessibility | `axe-core` |
|
|
251
|
+
| 0️⃣ GDC Check | Design | `gdc check --machine` |
|
|
252
|
+
|
|
253
|
+
#### GDC Integration (Graph-Driven Codebase)
|
|
254
|
+
|
|
255
|
+
Weave integrates with [GDC](https://github.com/ulgerang/gdc) (Graph-Driven Codebase) to enhance research quality and add design-time verification gates:
|
|
256
|
+
|
|
257
|
+
**Research Enhancement:**
|
|
258
|
+
- Automatic `.gdc` workspace detection
|
|
259
|
+
- GDC `stats`, `graph`, and `check` results embedded in `tasks/research.md`
|
|
260
|
+
- Dependency blast radius analysis from graph edges
|
|
261
|
+
- Candidate reuse nodes matched against feature keywords
|
|
262
|
+
- New report sections: `GDC Node Coverage`, `Dependency Blast Radius`, `Existing Spec vs Implementation Drift`, `Candidate Reuse Nodes`
|
|
263
|
+
|
|
264
|
+
**Pre-Verify Gate:**
|
|
265
|
+
When GDC is detected, `weave verify` and `weave flow` automatically run:
|
|
266
|
+
1. `gdc sync --machine` - Sync specs with implementation
|
|
267
|
+
2. `gdc check --machine` - Validate spec/implementation alignment
|
|
268
|
+
|
|
269
|
+
Blocking errors from GDC check will halt verification (configurable via `strictVerify` mode).
|
|
270
|
+
|
|
271
|
+
**Configuration** (`maskweaver.config.json`):
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"gdc": {
|
|
275
|
+
"enabled": "auto",
|
|
276
|
+
"strictVerify": false,
|
|
277
|
+
"autoSyncOnPrepare": true
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
- `enabled`: `true` | `false` | `"auto"` (default: auto-detect from `.gdc` directory)
|
|
283
|
+
- `strictVerify`: If `true`, GDC check failures block verification; if `false`, continues with warning
|
|
284
|
+
- `autoSyncOnPrepare`: Run `gdc sync` during `weave prepare`
|
|
285
|
+
|
|
286
|
+
#### Autonomous Mask Selection
|
|
252
287
|
|
|
253
288
|
The AI automatically picks the best expert for each task:
|
|
254
289
|
|
|
@@ -352,14 +387,15 @@ import { MaskLoader } from 'maskweaver/core';
|
|
|
352
387
|
import { WeaveOrchestrator, GlobalKnowledge } from 'maskweaver/weave';
|
|
353
388
|
```
|
|
354
389
|
|
|
355
|
-
**Modules:**
|
|
356
|
-
- `maskweaver/core` - Mask loading, validation (YAML/JSON)
|
|
357
|
-
- `maskweaver/memory` - Embeddings + vector search (5 providers)
|
|
358
|
-
- `maskweaver/context` - Feature-based work tracking
|
|
359
|
-
- `maskweaver/verify` - Cross-mask code review
|
|
360
|
-
- `maskweaver/retrospect` - Session effectiveness analysis
|
|
361
|
-
- `maskweaver/weave` - Phase-driven development workflow
|
|
362
|
-
- `maskweaver/
|
|
390
|
+
**Modules:**
|
|
391
|
+
- `maskweaver/core` - Mask loading, validation (YAML/JSON)
|
|
392
|
+
- `maskweaver/memory` - Embeddings + vector search (5 providers)
|
|
393
|
+
- `maskweaver/context` - Feature-based work tracking
|
|
394
|
+
- `maskweaver/verify` - Cross-mask code review
|
|
395
|
+
- `maskweaver/retrospect` - Session effectiveness analysis
|
|
396
|
+
- `maskweaver/weave` - Phase-driven development workflow
|
|
397
|
+
- `maskweaver/gdc` - GDC (Graph-Driven Codebase) integration utilities
|
|
398
|
+
- `maskweaver/plugin` - OpenCode plugin entry point
|
|
363
399
|
|
|
364
400
|
---
|
|
365
401
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weave.d.ts","sourceRoot":"","sources":["../../../src/plugin/tools/weave.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"weave.d.ts","sourceRoot":"","sources":["../../../src/plugin/tools/weave.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgCxB,wBAAgB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAsFb;QACF,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,GAAG,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,cAAc,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;QAC3L,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;QACjE,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;QAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB,WACQ;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,KAC9B,OAAO,CAAC,MAAM,CAAC;EA4DzB"}
|
|
@@ -23,6 +23,7 @@ import { createWeaveWorktree, listWeaveWorktrees, resolveWeaveWorktree, removeWe
|
|
|
23
23
|
import { ensureGitRepo, stageAllChanges, listStagedFiles, hasStagedChanges, commitStagedChanges } from '../../weave/git.js';
|
|
24
24
|
import { scanFilesForSecrets, loadSecretScanConfig, shouldBlockOnFindings, formatSecretScanReport } from '../../weave/security/secret-scan.js';
|
|
25
25
|
import { searchTroubleshooting, recordTroubleshooting, GlobalKnowledge } from '../../weave/knowledge/global.js';
|
|
26
|
+
import { getEffectiveGdcConfig, runGdcMachineCommand, countGdcCheckIssues, } from '../../weave/gdc.js';
|
|
26
27
|
// ============================================================================
|
|
27
28
|
// Tool Factory
|
|
28
29
|
// ============================================================================
|
|
@@ -292,6 +293,174 @@ function formatRefinePlanResult(title, outcome) {
|
|
|
292
293
|
}
|
|
293
294
|
return lines.join('\n');
|
|
294
295
|
}
|
|
296
|
+
function pickLogTail(text, maxLength = 180) {
|
|
297
|
+
if (!text)
|
|
298
|
+
return '';
|
|
299
|
+
const lines = text.split(/\r?\n/).map(line => line.trim()).filter(Boolean);
|
|
300
|
+
if (lines.length === 0)
|
|
301
|
+
return '';
|
|
302
|
+
return sanitizeLessonText(lines[lines.length - 1], maxLength);
|
|
303
|
+
}
|
|
304
|
+
function formatGdcCommandLine(label, result) {
|
|
305
|
+
const parts = [];
|
|
306
|
+
parts.push(result.exitCode === 0 ? 'PASS' : `FAIL(exit=${result.exitCode})`);
|
|
307
|
+
if (result.timedOut)
|
|
308
|
+
parts.push('timeout');
|
|
309
|
+
if (result.transportError)
|
|
310
|
+
parts.push(sanitizeLessonText(result.transportError, 140));
|
|
311
|
+
if (result.parseError)
|
|
312
|
+
parts.push(`parse=${sanitizeLessonText(result.parseError, 120)}`);
|
|
313
|
+
const detail = pickLogTail(result.stderr || result.stdout);
|
|
314
|
+
if (detail)
|
|
315
|
+
parts.push(`detail=${detail}`);
|
|
316
|
+
return `- ${label}: ${parts.join(' | ')}`;
|
|
317
|
+
}
|
|
318
|
+
async function runGdcVerifyGate(basePath) {
|
|
319
|
+
const gdc = getEffectiveGdcConfig(basePath);
|
|
320
|
+
if (!gdc.enabled) {
|
|
321
|
+
return {
|
|
322
|
+
applied: false,
|
|
323
|
+
passed: true,
|
|
324
|
+
report: '',
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
const lines = [];
|
|
328
|
+
lines.push('### GDC Pre-Verify Gate');
|
|
329
|
+
lines.push('');
|
|
330
|
+
lines.push(`- mode: ${gdc.strictVerify ? 'strict' : 'lenient'}`);
|
|
331
|
+
lines.push(`- binary: \`${gdc.binPath}\``);
|
|
332
|
+
const syncResult = await runGdcMachineCommand({
|
|
333
|
+
basePath,
|
|
334
|
+
command: 'sync',
|
|
335
|
+
config: gdc,
|
|
336
|
+
});
|
|
337
|
+
lines.push(formatGdcCommandLine('sync', syncResult));
|
|
338
|
+
const syncInfraFailure = Boolean(syncResult.transportError)
|
|
339
|
+
|| (syncResult.exitCode !== 0 && syncResult.exitCode !== 2);
|
|
340
|
+
const syncMachineParseFailure = Boolean(syncResult.parseError && syncResult.exitCode === 0);
|
|
341
|
+
if (syncInfraFailure || syncMachineParseFailure) {
|
|
342
|
+
if (gdc.strictVerify) {
|
|
343
|
+
lines.push('');
|
|
344
|
+
lines.push('❌ Strict mode blocks verification when GDC sync cannot be trusted.');
|
|
345
|
+
return {
|
|
346
|
+
applied: true,
|
|
347
|
+
passed: false,
|
|
348
|
+
failedAt: 'GDC Sync',
|
|
349
|
+
report: lines.join('\n'),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
lines.push('');
|
|
353
|
+
lines.push('⚠️ Proceeding without strict GDC sync gate (lenient mode).');
|
|
354
|
+
return {
|
|
355
|
+
applied: true,
|
|
356
|
+
passed: true,
|
|
357
|
+
report: lines.join('\n'),
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const checkResult = await runGdcMachineCommand({
|
|
361
|
+
basePath,
|
|
362
|
+
command: 'check',
|
|
363
|
+
config: gdc,
|
|
364
|
+
});
|
|
365
|
+
lines.push(formatGdcCommandLine('check', checkResult));
|
|
366
|
+
if (checkResult.exitCode === 2) {
|
|
367
|
+
lines.push('');
|
|
368
|
+
lines.push('❌ Blocking GDC check issues detected (exit code 2).');
|
|
369
|
+
return {
|
|
370
|
+
applied: true,
|
|
371
|
+
passed: false,
|
|
372
|
+
failedAt: 'GDC Check',
|
|
373
|
+
report: lines.join('\n'),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
const checkInfraFailure = Boolean(checkResult.transportError)
|
|
377
|
+
|| (checkResult.exitCode !== 0 && checkResult.exitCode !== 2);
|
|
378
|
+
if (checkInfraFailure) {
|
|
379
|
+
if (gdc.strictVerify) {
|
|
380
|
+
lines.push('');
|
|
381
|
+
lines.push('❌ Strict mode blocks verification when GDC check fails to run.');
|
|
382
|
+
return {
|
|
383
|
+
applied: true,
|
|
384
|
+
passed: false,
|
|
385
|
+
failedAt: 'GDC Check',
|
|
386
|
+
report: lines.join('\n'),
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
lines.push('');
|
|
390
|
+
lines.push('⚠️ GDC check execution failed, but lenient mode allows verification to continue.');
|
|
391
|
+
return {
|
|
392
|
+
applied: true,
|
|
393
|
+
passed: true,
|
|
394
|
+
report: lines.join('\n'),
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
const counts = countGdcCheckIssues(checkResult.data);
|
|
398
|
+
lines.push(`- check summary: errors=${counts.errors}, warnings=${counts.warnings}, info=${counts.infos}, issues=${counts.issueCount}`);
|
|
399
|
+
if (counts.errors > 0) {
|
|
400
|
+
lines.push('');
|
|
401
|
+
lines.push('❌ Blocking GDC check errors found. Resolve them before build/test verification.');
|
|
402
|
+
return {
|
|
403
|
+
applied: true,
|
|
404
|
+
passed: false,
|
|
405
|
+
failedAt: 'GDC Check',
|
|
406
|
+
report: lines.join('\n'),
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
if (checkResult.parseError) {
|
|
410
|
+
if (gdc.strictVerify) {
|
|
411
|
+
lines.push('');
|
|
412
|
+
lines.push('❌ Strict mode requires parseable GDC machine output.');
|
|
413
|
+
return {
|
|
414
|
+
applied: true,
|
|
415
|
+
passed: false,
|
|
416
|
+
failedAt: 'GDC Check Parse',
|
|
417
|
+
report: lines.join('\n'),
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
lines.push('');
|
|
421
|
+
lines.push('⚠️ GDC check output could not be parsed; continuing in lenient mode.');
|
|
422
|
+
}
|
|
423
|
+
lines.push('');
|
|
424
|
+
lines.push('✅ GDC gate passed.');
|
|
425
|
+
return {
|
|
426
|
+
applied: true,
|
|
427
|
+
passed: true,
|
|
428
|
+
report: lines.join('\n'),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
async function runGdcPrepareSync(basePath) {
|
|
432
|
+
const gdc = getEffectiveGdcConfig(basePath);
|
|
433
|
+
if (!gdc.enabled || !gdc.autoSyncOnPrepare) {
|
|
434
|
+
return {
|
|
435
|
+
applied: false,
|
|
436
|
+
report: '',
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
const lines = [];
|
|
440
|
+
lines.push('### GDC Prepare Sync');
|
|
441
|
+
lines.push('');
|
|
442
|
+
lines.push(`- binary: \`${gdc.binPath}\``);
|
|
443
|
+
const syncResult = await runGdcMachineCommand({
|
|
444
|
+
basePath,
|
|
445
|
+
command: 'sync',
|
|
446
|
+
config: gdc,
|
|
447
|
+
});
|
|
448
|
+
lines.push(formatGdcCommandLine('sync', syncResult));
|
|
449
|
+
const syncInfraFailure = Boolean(syncResult.transportError)
|
|
450
|
+
|| (syncResult.exitCode !== 0 && syncResult.exitCode !== 2);
|
|
451
|
+
const syncMachineParseFailure = Boolean(syncResult.parseError && syncResult.exitCode === 0);
|
|
452
|
+
lines.push('');
|
|
453
|
+
if (syncInfraFailure || syncMachineParseFailure) {
|
|
454
|
+
lines.push('⚠️ GDC sync failed during prepare; continuing without blocking.');
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
lines.push('✅ GDC sync completed before research/plan generation.');
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
applied: true,
|
|
461
|
+
report: lines.join('\n'),
|
|
462
|
+
};
|
|
463
|
+
}
|
|
295
464
|
async function handleResearch(args, basePath) {
|
|
296
465
|
const { docsPath, projectName } = args;
|
|
297
466
|
if (!docsPath) {
|
|
@@ -521,6 +690,7 @@ async function handlePrepare(args, basePath) {
|
|
|
521
690
|
}
|
|
522
691
|
const resolvedDocsPath = resolveUnderBase(basePath, docsPath);
|
|
523
692
|
const intakeResult = await intake({ docsPath: resolvedDocsPath });
|
|
693
|
+
const gdcPrepareSync = await runGdcPrepareSync(basePath);
|
|
524
694
|
const researchResult = await writeResearchReport({
|
|
525
695
|
docsPath: resolvedDocsPath,
|
|
526
696
|
intake: intakeResult,
|
|
@@ -552,6 +722,10 @@ async function handlePrepare(args, basePath) {
|
|
|
552
722
|
});
|
|
553
723
|
const lines = [];
|
|
554
724
|
lines.push('## ✅ Weave Prepare 완료\n');
|
|
725
|
+
if (gdcPrepareSync.applied && gdcPrepareSync.report) {
|
|
726
|
+
lines.push(gdcPrepareSync.report);
|
|
727
|
+
lines.push('');
|
|
728
|
+
}
|
|
555
729
|
lines.push(researchResult.summary);
|
|
556
730
|
lines.push('');
|
|
557
731
|
lines.push(specResult.summary);
|
|
@@ -683,6 +857,24 @@ async function handleFlow(args, basePath) {
|
|
|
683
857
|
lines.push('');
|
|
684
858
|
lines.push('### 3) Verify');
|
|
685
859
|
lines.push('');
|
|
860
|
+
const reviewLines = [
|
|
861
|
+
`Flow executed for ${resolvedPhaseId}.`,
|
|
862
|
+
`Plan gate: ${planGate.passed ? 'PASS' : 'BYPASS'} (${planGate.nonTrivial ? 'non-trivial' : 'simple'} scope).`,
|
|
863
|
+
];
|
|
864
|
+
const gdcGate = await runGdcVerifyGate(basePath);
|
|
865
|
+
if (gdcGate.applied && gdcGate.report) {
|
|
866
|
+
lines.push(gdcGate.report);
|
|
867
|
+
lines.push('');
|
|
868
|
+
}
|
|
869
|
+
if (!gdcGate.passed) {
|
|
870
|
+
lines.push(`❌ Verification failed at: ${gdcGate.failedAt || 'GDC Gate'}`);
|
|
871
|
+
reviewLines.push(`Flow stopped at GDC gate for ${resolvedPhaseId}: ${gdcGate.failedAt || 'GDC Gate'}.`);
|
|
872
|
+
await syncWorkflowArtifacts(basePath, manager, {
|
|
873
|
+
phaseId: resolvedPhaseId,
|
|
874
|
+
reviewLines,
|
|
875
|
+
});
|
|
876
|
+
return lines.join('\n');
|
|
877
|
+
}
|
|
686
878
|
const verification = await runAIVerification({
|
|
687
879
|
projectType: args.projectType || 'unknown',
|
|
688
880
|
projectPath: basePath,
|
|
@@ -692,12 +884,11 @@ async function handleFlow(args, basePath) {
|
|
|
692
884
|
});
|
|
693
885
|
const verificationReport = generateVerificationReport(verification.results);
|
|
694
886
|
lines.push(verificationReport);
|
|
695
|
-
const reviewLines = [
|
|
696
|
-
`Flow executed for ${resolvedPhaseId}.`,
|
|
697
|
-
`Plan gate: ${planGate.passed ? 'PASS' : 'BYPASS'} (${planGate.nonTrivial ? 'non-trivial' : 'simple'} scope).`,
|
|
698
|
-
];
|
|
699
887
|
reviewLines.push(`Craft prepared execution context for ${resolvedPhaseId}.`);
|
|
700
888
|
reviewLines.push('Phase implementation/verification proceeds outside the legacy auto loop.');
|
|
889
|
+
if (gdcGate.applied) {
|
|
890
|
+
reviewLines.push(`GDC pre-verify gate passed for ${resolvedPhaseId}.`);
|
|
891
|
+
}
|
|
701
892
|
if (!verification.passed) {
|
|
702
893
|
lines.push('');
|
|
703
894
|
lines.push(`❌ Verification failed at: ${verification.failedAt || 'unknown'}`);
|
|
@@ -970,6 +1161,15 @@ async function handleWorktree(args, basePath) {
|
|
|
970
1161
|
async function handleVerify(args, basePath) {
|
|
971
1162
|
const projectType = args.projectType || 'unknown';
|
|
972
1163
|
const mode = args.verifyMode || 'full';
|
|
1164
|
+
const gdcGate = await runGdcVerifyGate(basePath);
|
|
1165
|
+
const sections = [];
|
|
1166
|
+
if (gdcGate.applied && gdcGate.report) {
|
|
1167
|
+
sections.push(gdcGate.report);
|
|
1168
|
+
}
|
|
1169
|
+
if (!gdcGate.passed) {
|
|
1170
|
+
sections.push(`❌ Verification failed at: ${gdcGate.failedAt || 'GDC Gate'}`);
|
|
1171
|
+
return sections.join('\n\n');
|
|
1172
|
+
}
|
|
973
1173
|
const verification = await runAIVerification({
|
|
974
1174
|
projectType,
|
|
975
1175
|
projectPath: basePath,
|
|
@@ -978,26 +1178,27 @@ async function handleVerify(args, basePath) {
|
|
|
978
1178
|
mode,
|
|
979
1179
|
});
|
|
980
1180
|
const report = generateVerificationReport(verification.results);
|
|
1181
|
+
sections.push(report);
|
|
981
1182
|
if (verification.results.length === 0) {
|
|
982
|
-
|
|
983
|
-
report,
|
|
1183
|
+
sections.push([
|
|
984
1184
|
'',
|
|
985
1185
|
'> No verification commands detected for this project.',
|
|
986
1186
|
'> Provide scripts/tools (package.json, go.mod, Cargo.toml, pyproject.toml, *.sln) or pass projectType hint.',
|
|
987
|
-
].join('\n');
|
|
1187
|
+
].join('\n'));
|
|
1188
|
+
return sections.join('\n\n');
|
|
988
1189
|
}
|
|
989
1190
|
if (!verification.passed) {
|
|
990
|
-
|
|
991
|
-
report,
|
|
1191
|
+
sections.push([
|
|
992
1192
|
'',
|
|
993
1193
|
`❌ Verification failed at: ${verification.failedAt || 'unknown'}`,
|
|
994
|
-
].join('\n');
|
|
1194
|
+
].join('\n'));
|
|
1195
|
+
return sections.join('\n\n');
|
|
995
1196
|
}
|
|
996
|
-
|
|
997
|
-
report,
|
|
1197
|
+
sections.push([
|
|
998
1198
|
'',
|
|
999
1199
|
'✅ Verification passed.',
|
|
1000
|
-
].join('\n');
|
|
1200
|
+
].join('\n'));
|
|
1201
|
+
return sections.join('\n\n');
|
|
1001
1202
|
}
|
|
1002
1203
|
async function handleTroubleshoot(args) {
|
|
1003
1204
|
const { error, projectType } = args;
|
|
@@ -1086,6 +1287,24 @@ async function handleApprove(args, basePath) {
|
|
|
1086
1287
|
return message;
|
|
1087
1288
|
};
|
|
1088
1289
|
if (!skipVerify) {
|
|
1290
|
+
const reportSections = [];
|
|
1291
|
+
const gdcGate = await runGdcVerifyGate(basePath);
|
|
1292
|
+
if (gdcGate.applied && gdcGate.report) {
|
|
1293
|
+
reportSections.push(gdcGate.report);
|
|
1294
|
+
}
|
|
1295
|
+
if (!gdcGate.passed) {
|
|
1296
|
+
return finalizeApprove([
|
|
1297
|
+
...reportSections,
|
|
1298
|
+
`❌ Verification failed at: ${gdcGate.failedAt || 'GDC Gate'}`,
|
|
1299
|
+
'',
|
|
1300
|
+
invokedByCraft
|
|
1301
|
+
? 'Fix the failures and rerun `weave craft`.'
|
|
1302
|
+
: 'Fix the failures and re-run `weave craft`.',
|
|
1303
|
+
'You can also run: `weave command=verify`',
|
|
1304
|
+
].filter(Boolean).join('\n\n'), [
|
|
1305
|
+
`Finalization blocked at GDC gate for ${resolvedPhaseId}: ${gdcGate.failedAt || 'GDC Gate'}.`,
|
|
1306
|
+
]);
|
|
1307
|
+
}
|
|
1089
1308
|
const verification = await runAIVerification({
|
|
1090
1309
|
projectType: projectType || 'unknown',
|
|
1091
1310
|
projectPath: basePath,
|
|
@@ -1093,7 +1312,8 @@ async function handleApprove(args, basePath) {
|
|
|
1093
1312
|
enableScreenshots: false,
|
|
1094
1313
|
mode: verifyMode || 'full',
|
|
1095
1314
|
});
|
|
1096
|
-
|
|
1315
|
+
reportSections.push(generateVerificationReport(verification.results));
|
|
1316
|
+
const report = reportSections.join('\n\n');
|
|
1097
1317
|
if (!verification.passed) {
|
|
1098
1318
|
return finalizeApprove([
|
|
1099
1319
|
report,
|