@tienne/gestalt 0.1.0
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/CLAUDE.md +203 -0
- package/README.md +60 -0
- package/agents/closure-completer/AGENT.md +32 -0
- package/agents/continuity-judge/AGENT.md +40 -0
- package/agents/ground-mapper/AGENT.md +31 -0
- package/agents/proximity-worker/AGENT.md +33 -0
- package/agents/similarity-crystallizer/AGENT.md +34 -0
- package/dist/agents/closure-completer/AGENT.md +32 -0
- package/dist/agents/continuity-judge/AGENT.md +40 -0
- package/dist/agents/ground-mapper/AGENT.md +31 -0
- package/dist/agents/proximity-worker/AGENT.md +33 -0
- package/dist/agents/similarity-crystallizer/AGENT.md +34 -0
- package/dist/bin/gestalt.d.ts +3 -0
- package/dist/bin/gestalt.d.ts.map +1 -0
- package/dist/bin/gestalt.js +5 -0
- package/dist/bin/gestalt.js.map +1 -0
- package/dist/skills/execute/SKILL.md +84 -0
- package/dist/skills/interview/SKILL.md +82 -0
- package/dist/skills/seed/SKILL.md +92 -0
- package/dist/skills/spec/SKILL.md +92 -0
- package/dist/src/agent/figural-router.d.ts +48 -0
- package/dist/src/agent/figural-router.d.ts.map +1 -0
- package/dist/src/agent/figural-router.js +55 -0
- package/dist/src/agent/figural-router.js.map +1 -0
- package/dist/src/agent/parser.d.ts +3 -0
- package/dist/src/agent/parser.d.ts.map +1 -0
- package/dist/src/agent/parser.js +32 -0
- package/dist/src/agent/parser.js.map +1 -0
- package/dist/src/agent/prompt-resolver.d.ts +17 -0
- package/dist/src/agent/prompt-resolver.d.ts.map +1 -0
- package/dist/src/agent/prompt-resolver.js +31 -0
- package/dist/src/agent/prompt-resolver.js.map +1 -0
- package/dist/src/agent/registry.d.ts +9 -0
- package/dist/src/agent/registry.d.ts.map +1 -0
- package/dist/src/agent/registry.js +22 -0
- package/dist/src/agent/registry.js.map +1 -0
- package/dist/src/cli/commands/interview.d.ts +2 -0
- package/dist/src/cli/commands/interview.d.ts.map +1 -0
- package/dist/src/cli/commands/interview.js +67 -0
- package/dist/src/cli/commands/interview.js.map +1 -0
- package/dist/src/cli/commands/seed.d.ts +4 -0
- package/dist/src/cli/commands/seed.d.ts.map +1 -0
- package/dist/src/cli/commands/seed.js +34 -0
- package/dist/src/cli/commands/seed.js.map +1 -0
- package/dist/src/cli/commands/serve.d.ts +2 -0
- package/dist/src/cli/commands/serve.d.ts.map +1 -0
- package/dist/src/cli/commands/serve.js +5 -0
- package/dist/src/cli/commands/serve.js.map +1 -0
- package/dist/src/cli/commands/spec.d.ts +4 -0
- package/dist/src/cli/commands/spec.d.ts.map +1 -0
- package/dist/src/cli/commands/spec.js +34 -0
- package/dist/src/cli/commands/spec.js.map +1 -0
- package/dist/src/cli/commands/status.d.ts +2 -0
- package/dist/src/cli/commands/status.d.ts.map +1 -0
- package/dist/src/cli/commands/status.js +66 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/index.d.ts +3 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +39 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/core/config.d.ts +36 -0
- package/dist/src/core/config.d.ts.map +1 -0
- package/dist/src/core/config.js +65 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/constants.d.ts +34 -0
- package/dist/src/core/constants.d.ts.map +1 -0
- package/dist/src/core/constants.js +68 -0
- package/dist/src/core/constants.js.map +1 -0
- package/dist/src/core/errors.d.ts +50 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +99 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/log.d.ts +5 -0
- package/dist/src/core/log.d.ts.map +1 -0
- package/dist/src/core/log.js +7 -0
- package/dist/src/core/log.js.map +1 -0
- package/dist/src/core/result.d.ts +20 -0
- package/dist/src/core/result.d.ts.map +1 -0
- package/dist/src/core/result.js +43 -0
- package/dist/src/core/result.js.map +1 -0
- package/dist/src/core/types.d.ts +289 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +15 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/events/store.d.ts +22 -0
- package/dist/src/events/store.d.ts.map +1 -0
- package/dist/src/events/store.js +130 -0
- package/dist/src/events/store.js.map +1 -0
- package/dist/src/events/types.d.ts +33 -0
- package/dist/src/events/types.d.ts.map +1 -0
- package/dist/src/events/types.js +35 -0
- package/dist/src/events/types.js.map +1 -0
- package/dist/src/execute/dag-validator.d.ts +7 -0
- package/dist/src/execute/dag-validator.d.ts.map +1 -0
- package/dist/src/execute/dag-validator.js +141 -0
- package/dist/src/execute/dag-validator.js.map +1 -0
- package/dist/src/execute/drift-detector.d.ts +11 -0
- package/dist/src/execute/drift-detector.d.ts.map +1 -0
- package/dist/src/execute/drift-detector.js +111 -0
- package/dist/src/execute/drift-detector.js.map +1 -0
- package/dist/src/execute/impact-identifier.d.ts +12 -0
- package/dist/src/execute/impact-identifier.d.ts.map +1 -0
- package/dist/src/execute/impact-identifier.js +60 -0
- package/dist/src/execute/impact-identifier.js.map +1 -0
- package/dist/src/execute/passthrough-engine.d.ts +181 -0
- package/dist/src/execute/passthrough-engine.d.ts.map +1 -0
- package/dist/src/execute/passthrough-engine.js +795 -0
- package/dist/src/execute/passthrough-engine.js.map +1 -0
- package/dist/src/execute/prompts.d.ts +19 -0
- package/dist/src/execute/prompts.d.ts.map +1 -0
- package/dist/src/execute/prompts.js +505 -0
- package/dist/src/execute/prompts.js.map +1 -0
- package/dist/src/execute/repository.d.ts +30 -0
- package/dist/src/execute/repository.d.ts.map +1 -0
- package/dist/src/execute/repository.js +248 -0
- package/dist/src/execute/repository.js.map +1 -0
- package/dist/src/execute/session.d.ts +34 -0
- package/dist/src/execute/session.d.ts.map +1 -0
- package/dist/src/execute/session.js +273 -0
- package/dist/src/execute/session.js.map +1 -0
- package/dist/src/execute/spec-patch-applier.d.ts +13 -0
- package/dist/src/execute/spec-patch-applier.d.ts.map +1 -0
- package/dist/src/execute/spec-patch-applier.js +83 -0
- package/dist/src/execute/spec-patch-applier.js.map +1 -0
- package/dist/src/execute/spec-patch-validator.d.ts +20 -0
- package/dist/src/execute/spec-patch-validator.d.ts.map +1 -0
- package/dist/src/execute/spec-patch-validator.js +60 -0
- package/dist/src/execute/spec-patch-validator.js.map +1 -0
- package/dist/src/execute/termination-detector.d.ts +20 -0
- package/dist/src/execute/termination-detector.d.ts.map +1 -0
- package/dist/src/execute/termination-detector.js +77 -0
- package/dist/src/execute/termination-detector.js.map +1 -0
- package/dist/src/gestalt/analyzer.d.ts +18 -0
- package/dist/src/gestalt/analyzer.d.ts.map +1 -0
- package/dist/src/gestalt/analyzer.js +59 -0
- package/dist/src/gestalt/analyzer.js.map +1 -0
- package/dist/src/gestalt/principles.d.ts +21 -0
- package/dist/src/gestalt/principles.d.ts.map +1 -0
- package/dist/src/gestalt/principles.js +66 -0
- package/dist/src/gestalt/principles.js.map +1 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +22 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interview/ambiguity.d.ts +8 -0
- package/dist/src/interview/ambiguity.d.ts.map +1 -0
- package/dist/src/interview/ambiguity.js +69 -0
- package/dist/src/interview/ambiguity.js.map +1 -0
- package/dist/src/interview/brownfield.d.ts +7 -0
- package/dist/src/interview/brownfield.d.ts.map +1 -0
- package/dist/src/interview/brownfield.js +28 -0
- package/dist/src/interview/brownfield.js.map +1 -0
- package/dist/src/interview/engine.d.ts +31 -0
- package/dist/src/interview/engine.d.ts.map +1 -0
- package/dist/src/interview/engine.js +110 -0
- package/dist/src/interview/engine.js.map +1 -0
- package/dist/src/interview/passthrough-engine.d.ts +52 -0
- package/dist/src/interview/passthrough-engine.d.ts.map +1 -0
- package/dist/src/interview/passthrough-engine.js +174 -0
- package/dist/src/interview/passthrough-engine.js.map +1 -0
- package/dist/src/interview/questions.d.ts +12 -0
- package/dist/src/interview/questions.d.ts.map +1 -0
- package/dist/src/interview/questions.js +54 -0
- package/dist/src/interview/questions.js.map +1 -0
- package/dist/src/interview/repository.d.ts +25 -0
- package/dist/src/interview/repository.d.ts.map +1 -0
- package/dist/src/interview/repository.js +102 -0
- package/dist/src/interview/repository.js.map +1 -0
- package/dist/src/interview/session.d.ts +22 -0
- package/dist/src/interview/session.d.ts.map +1 -0
- package/dist/src/interview/session.js +120 -0
- package/dist/src/interview/session.js.map +1 -0
- package/dist/src/llm/adapter.d.ts +8 -0
- package/dist/src/llm/adapter.d.ts.map +1 -0
- package/dist/src/llm/adapter.js +42 -0
- package/dist/src/llm/adapter.js.map +1 -0
- package/dist/src/llm/openai-adapter.d.ts +8 -0
- package/dist/src/llm/openai-adapter.d.ts.map +1 -0
- package/dist/src/llm/openai-adapter.js +45 -0
- package/dist/src/llm/openai-adapter.js.map +1 -0
- package/dist/src/llm/prompts.d.ts +15 -0
- package/dist/src/llm/prompts.d.ts.map +1 -0
- package/dist/src/llm/prompts.js +83 -0
- package/dist/src/llm/prompts.js.map +1 -0
- package/dist/src/llm/types.d.ts +21 -0
- package/dist/src/llm/types.d.ts.map +1 -0
- package/dist/src/llm/types.js +2 -0
- package/dist/src/llm/types.js.map +1 -0
- package/dist/src/mcp/schemas.d.ts +799 -0
- package/dist/src/mcp/schemas.d.ts.map +1 -0
- package/dist/src/mcp/schemas.js +151 -0
- package/dist/src/mcp/schemas.js.map +1 -0
- package/dist/src/mcp/server.d.ts +13 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +255 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools/execute-passthrough.d.ts +4 -0
- package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/execute-passthrough.js +349 -0
- package/dist/src/mcp/tools/execute-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/index.d.ts +4 -0
- package/dist/src/mcp/tools/index.d.ts.map +1 -0
- package/dist/src/mcp/tools/index.js +4 -0
- package/dist/src/mcp/tools/index.js.map +1 -0
- package/dist/src/mcp/tools/interview-passthrough.d.ts +4 -0
- package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/interview-passthrough.js +96 -0
- package/dist/src/mcp/tools/interview-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/interview.d.ts +4 -0
- package/dist/src/mcp/tools/interview.d.ts.map +1 -0
- package/dist/src/mcp/tools/interview.js +85 -0
- package/dist/src/mcp/tools/interview.js.map +1 -0
- package/dist/src/mcp/tools/seed-passthrough.d.ts +5 -0
- package/dist/src/mcp/tools/seed-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/seed-passthrough.js +29 -0
- package/dist/src/mcp/tools/seed-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/seed.d.ts +5 -0
- package/dist/src/mcp/tools/seed.d.ts.map +1 -0
- package/dist/src/mcp/tools/seed.js +19 -0
- package/dist/src/mcp/tools/seed.js.map +1 -0
- package/dist/src/mcp/tools/spec-passthrough.d.ts +5 -0
- package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/spec-passthrough.js +29 -0
- package/dist/src/mcp/tools/spec-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/spec.d.ts +5 -0
- package/dist/src/mcp/tools/spec.d.ts.map +1 -0
- package/dist/src/mcp/tools/spec.js +19 -0
- package/dist/src/mcp/tools/spec.js.map +1 -0
- package/dist/src/mcp/tools/status.d.ts +4 -0
- package/dist/src/mcp/tools/status.d.ts.map +1 -0
- package/dist/src/mcp/tools/status.js +45 -0
- package/dist/src/mcp/tools/status.js.map +1 -0
- package/dist/src/registry/base-registry.d.ts +26 -0
- package/dist/src/registry/base-registry.d.ts.map +1 -0
- package/dist/src/registry/base-registry.js +82 -0
- package/dist/src/registry/base-registry.js.map +1 -0
- package/dist/src/seed/extractor.d.ts +15 -0
- package/dist/src/seed/extractor.d.ts.map +1 -0
- package/dist/src/seed/extractor.js +88 -0
- package/dist/src/seed/extractor.js.map +1 -0
- package/dist/src/seed/generator.d.ts +12 -0
- package/dist/src/seed/generator.d.ts.map +1 -0
- package/dist/src/seed/generator.js +66 -0
- package/dist/src/seed/generator.js.map +1 -0
- package/dist/src/seed/passthrough-generator.d.ts +31 -0
- package/dist/src/seed/passthrough-generator.d.ts.map +1 -0
- package/dist/src/seed/passthrough-generator.js +80 -0
- package/dist/src/seed/passthrough-generator.js.map +1 -0
- package/dist/src/seed/schema.d.ts +145 -0
- package/dist/src/seed/schema.d.ts.map +1 -0
- package/dist/src/seed/schema.js +37 -0
- package/dist/src/seed/schema.js.map +1 -0
- package/dist/src/skills/executor.d.ts +14 -0
- package/dist/src/skills/executor.d.ts.map +1 -0
- package/dist/src/skills/executor.js +17 -0
- package/dist/src/skills/executor.js.map +1 -0
- package/dist/src/skills/parser.d.ts +3 -0
- package/dist/src/skills/parser.d.ts.map +1 -0
- package/dist/src/skills/parser.js +37 -0
- package/dist/src/skills/parser.js.map +1 -0
- package/dist/src/skills/registry.d.ts +8 -0
- package/dist/src/skills/registry.d.ts.map +1 -0
- package/dist/src/skills/registry.js +19 -0
- package/dist/src/skills/registry.js.map +1 -0
- package/dist/src/skills/types.d.ts +19 -0
- package/dist/src/skills/types.d.ts.map +1 -0
- package/dist/src/skills/types.js +2 -0
- package/dist/src/skills/types.js.map +1 -0
- package/dist/src/spec/extractor.d.ts +15 -0
- package/dist/src/spec/extractor.d.ts.map +1 -0
- package/dist/src/spec/extractor.js +88 -0
- package/dist/src/spec/extractor.js.map +1 -0
- package/dist/src/spec/generator.d.ts +12 -0
- package/dist/src/spec/generator.d.ts.map +1 -0
- package/dist/src/spec/generator.js +66 -0
- package/dist/src/spec/generator.js.map +1 -0
- package/dist/src/spec/passthrough-generator.d.ts +34 -0
- package/dist/src/spec/passthrough-generator.d.ts.map +1 -0
- package/dist/src/spec/passthrough-generator.js +86 -0
- package/dist/src/spec/passthrough-generator.js.map +1 -0
- package/dist/src/spec/schema.d.ts +145 -0
- package/dist/src/spec/schema.d.ts.map +1 -0
- package/dist/src/spec/schema.js +37 -0
- package/dist/src/spec/schema.js.map +1 -0
- package/package.json +53 -0
- package/skills/execute/SKILL.md +84 -0
- package/skills/interview/SKILL.md +82 -0
- package/skills/spec/SKILL.md +92 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: execute
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "Gestalt-driven execution planner that transforms a Spec into a validated ExecutionPlan"
|
|
5
|
+
triggers:
|
|
6
|
+
- "execute"
|
|
7
|
+
- "plan execution"
|
|
8
|
+
- "create execution plan"
|
|
9
|
+
inputs:
|
|
10
|
+
spec:
|
|
11
|
+
type: object
|
|
12
|
+
required: true
|
|
13
|
+
description: "A validated Spec specification from the spec generation step"
|
|
14
|
+
outputs:
|
|
15
|
+
- executionPlan
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Execute Skill
|
|
19
|
+
|
|
20
|
+
This skill transforms a validated Spec specification into a concrete, dependency-aware Execution Plan by applying Gestalt psychology principles as a structured planning framework.
|
|
21
|
+
|
|
22
|
+
## Process
|
|
23
|
+
|
|
24
|
+
1. **Figure-Ground** (Step 1): Classify acceptance criteria as essential (figure) or supplementary (ground), assign priority levels
|
|
25
|
+
2. **Closure** (Step 2): Decompose ACs into atomic tasks, identify implicit sub-tasks not explicitly stated
|
|
26
|
+
3. **Proximity** (Step 3): Group related atomic tasks into logical task groups by domain
|
|
27
|
+
4. **Continuity** (Step 4): Validate the dependency DAG — ensure no cycles, no conflicts, clear execution order
|
|
28
|
+
|
|
29
|
+
## Passthrough Mode
|
|
30
|
+
|
|
31
|
+
API 키 없이 MCP 서버 실행 시 자동 활성화. LLM 작업을 caller가 직접 수행한다.
|
|
32
|
+
|
|
33
|
+
### Action별 사용법
|
|
34
|
+
|
|
35
|
+
**`start`** — 실행 계획 세션 시작
|
|
36
|
+
```json
|
|
37
|
+
{ "action": "start", "spec": { ... } }
|
|
38
|
+
```
|
|
39
|
+
→ `{ status, sessionId, specId, executeContext, message }`
|
|
40
|
+
|
|
41
|
+
**`plan_step`** — 각 계획 단계 결과 제출
|
|
42
|
+
```json
|
|
43
|
+
{ "action": "plan_step", "sessionId": "...", "stepResult": { "principle": "figure_ground", "classifiedACs": [...] } }
|
|
44
|
+
```
|
|
45
|
+
→ `{ status, sessionId, stepsCompleted, isLastStep, executeContext?, message }`
|
|
46
|
+
|
|
47
|
+
**`plan_complete`** — 최종 실행 계획 조립
|
|
48
|
+
```json
|
|
49
|
+
{ "action": "plan_complete", "sessionId": "..." }
|
|
50
|
+
```
|
|
51
|
+
→ `{ status, sessionId, executionPlan, message }`
|
|
52
|
+
|
|
53
|
+
**`status`** — 세션 상태 확인
|
|
54
|
+
```json
|
|
55
|
+
{ "action": "status", "sessionId": "..." }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### ExecuteContext 필드
|
|
59
|
+
|
|
60
|
+
| 필드 | 타입 | 설명 |
|
|
61
|
+
|------|------|------|
|
|
62
|
+
| `systemPrompt` | string | 실행 계획 시스템 프롬프트 |
|
|
63
|
+
| `planningPrompt` | string | 현재 단계의 계획 프롬프트 |
|
|
64
|
+
| `currentPrinciple` | string | 현재 적용 중인 게슈탈트 원리 |
|
|
65
|
+
| `principleStrategy` | string | 해당 원리의 전략 설명 |
|
|
66
|
+
| `phase` | string | 현재 단계 (`planning`) |
|
|
67
|
+
| `stepNumber` | number | 현재 스텝 번호 (1-4) |
|
|
68
|
+
| `totalSteps` | number | 전체 스텝 수 (4) |
|
|
69
|
+
| `spec` | Spec | 원본 Spec 스펙 |
|
|
70
|
+
| `previousSteps` | array | 이전 단계 결과들 |
|
|
71
|
+
|
|
72
|
+
### Planning Principle 순서
|
|
73
|
+
|
|
74
|
+
1. `figure_ground` → ClassifiedAC 배열
|
|
75
|
+
2. `closure` → AtomicTask 배열
|
|
76
|
+
3. `proximity` → TaskGroup 배열
|
|
77
|
+
4. `continuity` → DAGValidation 객체
|
|
78
|
+
|
|
79
|
+
### 검증 규칙
|
|
80
|
+
|
|
81
|
+
- 순서가 강제됨: figure_ground → closure → proximity → continuity
|
|
82
|
+
- 각 단계 결과는 이전 단계 데이터와 교차 검증됨
|
|
83
|
+
- Continuity 단계에서는 서버 측 DAG 검증이 추가로 수행됨
|
|
84
|
+
- 모든 AC가 분류되어야 하고, 모든 Task가 그룹에 포함되어야 함
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: interview
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "Gestalt-driven interview to clarify project requirements"
|
|
5
|
+
triggers:
|
|
6
|
+
- "interview"
|
|
7
|
+
- "clarify requirements"
|
|
8
|
+
- "start interview"
|
|
9
|
+
inputs:
|
|
10
|
+
topic:
|
|
11
|
+
type: string
|
|
12
|
+
required: true
|
|
13
|
+
description: "The topic or feature to interview about"
|
|
14
|
+
cwd:
|
|
15
|
+
type: string
|
|
16
|
+
required: false
|
|
17
|
+
description: "Working directory for brownfield detection"
|
|
18
|
+
outputs:
|
|
19
|
+
- session
|
|
20
|
+
- ambiguityScore
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Interview Skill
|
|
24
|
+
|
|
25
|
+
This skill conducts a Gestalt psychology-driven interview to transform vague requirements into clear specifications.
|
|
26
|
+
|
|
27
|
+
## Process
|
|
28
|
+
|
|
29
|
+
1. **Start**: Create a session, detect project type (greenfield/brownfield), ask the first question
|
|
30
|
+
2. **Iterate**: Ask questions guided by Gestalt principles (Closure → Proximity → Similarity → Figure-Ground)
|
|
31
|
+
3. **Score**: Continuously assess ambiguity across multiple dimensions
|
|
32
|
+
4. **Complete**: When ambiguity score ≤ 0.2, the interview is ready for spec generation
|
|
33
|
+
|
|
34
|
+
## Gestalt Principles Applied
|
|
35
|
+
|
|
36
|
+
- **Closure**: Fill missing requirements
|
|
37
|
+
- **Proximity**: Group related features
|
|
38
|
+
- **Similarity**: Identify patterns
|
|
39
|
+
- **Figure-Ground**: Separate MVP from nice-to-have
|
|
40
|
+
- **Continuity**: Detect contradictions
|
|
41
|
+
|
|
42
|
+
## Passthrough Mode
|
|
43
|
+
|
|
44
|
+
API 키 없이 MCP 서버 실행 시 자동 활성화. LLM 작업을 caller가 직접 수행한다.
|
|
45
|
+
|
|
46
|
+
### 추가 Input 파라미터
|
|
47
|
+
|
|
48
|
+
| 파라미터 | 타입 | 필수 | 설명 |
|
|
49
|
+
|---------|------|------|------|
|
|
50
|
+
| `generatedQuestion` | string | respond 시 필수 | caller가 생성한 질문 텍스트 |
|
|
51
|
+
| `ambiguityScore` | object | 선택 | caller가 산출한 모호성 점수 |
|
|
52
|
+
| `ambiguityScore.goalClarity` | number (0-1) | 필수* | 목표 명확도 |
|
|
53
|
+
| `ambiguityScore.constraintClarity` | number (0-1) | 필수* | 제약조건 명확도 |
|
|
54
|
+
| `ambiguityScore.successCriteria` | number (0-1) | 필수* | 성공 기준 명확도 |
|
|
55
|
+
| `ambiguityScore.priorityClarity` | number (0-1) | 필수* | 우선순위 명확도 |
|
|
56
|
+
| `ambiguityScore.contextClarity` | number (0-1) | 선택 | 컨텍스트 명확도 |
|
|
57
|
+
| `ambiguityScore.contradictions` | string[] | 선택 | 발견된 모순 목록 |
|
|
58
|
+
|
|
59
|
+
\* ambiguityScore 객체를 제공할 경우 필수
|
|
60
|
+
|
|
61
|
+
### Action별 응답 구조 (Passthrough)
|
|
62
|
+
|
|
63
|
+
**`start`** → `{ status, sessionId, projectType, detectedFiles, gestaltContext, roundNumber, message }`
|
|
64
|
+
|
|
65
|
+
**`respond`** → `{ status, sessionId, roundNumber, gestaltContext, ambiguityScore, message }`
|
|
66
|
+
|
|
67
|
+
**`score`** (점수 미제공 시) → `{ status, ambiguityScore, scoringPrompt, message }`
|
|
68
|
+
**`score`** (점수 제공 시) → `{ status, ambiguityScore }`
|
|
69
|
+
|
|
70
|
+
**`complete`** → `{ status, sessionId, totalRounds, finalAmbiguityScore, message }`
|
|
71
|
+
|
|
72
|
+
### GestaltContext 필드
|
|
73
|
+
|
|
74
|
+
| 필드 | 타입 | 설명 |
|
|
75
|
+
|------|------|------|
|
|
76
|
+
| `systemPrompt` | string | 인터뷰어 시스템 프롬프트 |
|
|
77
|
+
| `currentPrinciple` | GestaltPrinciple | 현재 적용 중인 게슈탈트 원리 |
|
|
78
|
+
| `principleStrategy` | string | 해당 원리의 질문 전략 설명 |
|
|
79
|
+
| `phase` | string | 현재 인터뷰 단계 라벨 |
|
|
80
|
+
| `questionPrompt` | string | 다음 질문 생성용 프롬프트 |
|
|
81
|
+
| `scoringPrompt` | string? | 모호성 점수 산출용 프롬프트 (respond 후에만 포함) |
|
|
82
|
+
| `roundNumber` | number | 현재 라운드 번호 |
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: seed
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "Generate a Seed specification from a completed interview"
|
|
5
|
+
triggers:
|
|
6
|
+
- "generate seed"
|
|
7
|
+
- "create spec"
|
|
8
|
+
- "build seed"
|
|
9
|
+
inputs:
|
|
10
|
+
sessionId:
|
|
11
|
+
type: string
|
|
12
|
+
required: true
|
|
13
|
+
description: "The interview session ID to generate a seed from"
|
|
14
|
+
force:
|
|
15
|
+
type: boolean
|
|
16
|
+
required: false
|
|
17
|
+
description: "Force generation even if ambiguity threshold is not met"
|
|
18
|
+
outputs:
|
|
19
|
+
- seed
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Seed Generation Skill
|
|
23
|
+
|
|
24
|
+
This skill transforms completed interview data into a structured project specification (Seed).
|
|
25
|
+
|
|
26
|
+
## Output Structure
|
|
27
|
+
|
|
28
|
+
- **Goal**: Clear project objective
|
|
29
|
+
- **Constraints**: Technical and business constraints
|
|
30
|
+
- **Acceptance Criteria**: Measurable success conditions
|
|
31
|
+
- **Ontology Schema**: Entity-relationship model
|
|
32
|
+
- **Gestalt Analysis**: Findings from each principle applied
|
|
33
|
+
|
|
34
|
+
## Requirements
|
|
35
|
+
|
|
36
|
+
- Interview session must be in `completed` status
|
|
37
|
+
- Ambiguity score must be ≤ 0.2 (unless `force` is true)
|
|
38
|
+
|
|
39
|
+
## Passthrough Mode
|
|
40
|
+
|
|
41
|
+
API 키 없이 MCP 서버 실행 시 자동 활성화. Seed 생성을 caller가 직접 수행한다.
|
|
42
|
+
|
|
43
|
+
### 추가 Input 파라미터
|
|
44
|
+
|
|
45
|
+
| 파라미터 | 타입 | 필수 | 설명 |
|
|
46
|
+
|---------|------|------|------|
|
|
47
|
+
| `seed` | object | 2단계에서 필수 | caller가 생성한 Seed JSON |
|
|
48
|
+
| `seed.goal` | string | 필수 | 프로젝트 목표 |
|
|
49
|
+
| `seed.constraints` | string[] | 필수 | 기술/비즈니스 제약조건 |
|
|
50
|
+
| `seed.acceptanceCriteria` | string[] | 필수 | 수용 기준 |
|
|
51
|
+
| `seed.ontologySchema` | object | 필수 | 엔티티-관계 모델 |
|
|
52
|
+
| `seed.gestaltAnalysis` | array | 필수 | 게슈탈트 분석 결과 |
|
|
53
|
+
|
|
54
|
+
### 2단계 플로우
|
|
55
|
+
|
|
56
|
+
**1단계: SeedContext 요청**
|
|
57
|
+
```
|
|
58
|
+
ges_generate_seed({ sessionId: "<id>" })
|
|
59
|
+
```
|
|
60
|
+
→ `{ status: "prompt", seedContext, message }` 반환
|
|
61
|
+
|
|
62
|
+
SeedContext 필드:
|
|
63
|
+
- `systemPrompt`: Seed 생성용 시스템 프롬프트
|
|
64
|
+
- `seedPrompt`: 인터뷰 내용 기반 Seed 생성 프롬프트
|
|
65
|
+
- `allRounds[]`: `{ roundNumber, question, response, gestaltFocus }`
|
|
66
|
+
|
|
67
|
+
**2단계: Seed 제출 및 검증**
|
|
68
|
+
```
|
|
69
|
+
ges_generate_seed({
|
|
70
|
+
sessionId: "<id>",
|
|
71
|
+
seed: {
|
|
72
|
+
goal: "명확한 프로젝트 목표",
|
|
73
|
+
constraints: ["TypeScript 사용", "REST API"],
|
|
74
|
+
acceptanceCriteria: ["응답 시간 200ms 이하"],
|
|
75
|
+
ontologySchema: {
|
|
76
|
+
entities: [{ name: "User", description: "...", attributes: ["id", "email"] }],
|
|
77
|
+
relations: [{ from: "User", to: "Order", type: "has_many" }]
|
|
78
|
+
},
|
|
79
|
+
gestaltAnalysis: [
|
|
80
|
+
{ principle: "closure", finding: "인증 요구사항 완전히 파악됨", confidence: 0.9 }
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
→ `{ status: "generated", seed }` (metadata 자동 생성 포함) 또는 `{ error }` 반환
|
|
86
|
+
|
|
87
|
+
### Seed 검증 스키마 (Zod)
|
|
88
|
+
|
|
89
|
+
- `gestaltAnalysis[].principle`: `closure | proximity | similarity | figure_ground | continuity`
|
|
90
|
+
- `gestaltAnalysis[].confidence`: 0.0 ~ 1.0
|
|
91
|
+
- `ontologySchema.entities[]`: `{ name: string(min 1), description: string, attributes: string[] }`
|
|
92
|
+
- `ontologySchema.relations[]`: `{ from: string(min 1), to: string(min 1), type: string(min 1) }`
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "Generate a Spec specification from a completed interview"
|
|
5
|
+
triggers:
|
|
6
|
+
- "generate spec"
|
|
7
|
+
- "create spec"
|
|
8
|
+
- "build spec"
|
|
9
|
+
inputs:
|
|
10
|
+
sessionId:
|
|
11
|
+
type: string
|
|
12
|
+
required: true
|
|
13
|
+
description: "The interview session ID to generate a spec from"
|
|
14
|
+
force:
|
|
15
|
+
type: boolean
|
|
16
|
+
required: false
|
|
17
|
+
description: "Force generation even if ambiguity threshold is not met"
|
|
18
|
+
outputs:
|
|
19
|
+
- spec
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Spec Generation Skill
|
|
23
|
+
|
|
24
|
+
This skill transforms completed interview data into a structured project specification (Spec).
|
|
25
|
+
|
|
26
|
+
## Output Structure
|
|
27
|
+
|
|
28
|
+
- **Goal**: Clear project objective
|
|
29
|
+
- **Constraints**: Technical and business constraints
|
|
30
|
+
- **Acceptance Criteria**: Measurable success conditions
|
|
31
|
+
- **Ontology Schema**: Entity-relationship model
|
|
32
|
+
- **Gestalt Analysis**: Findings from each principle applied
|
|
33
|
+
|
|
34
|
+
## Requirements
|
|
35
|
+
|
|
36
|
+
- Interview session must be in `completed` status
|
|
37
|
+
- Ambiguity score must be ≤ 0.2 (unless `force` is true)
|
|
38
|
+
|
|
39
|
+
## Passthrough Mode
|
|
40
|
+
|
|
41
|
+
API 키 없이 MCP 서버 실행 시 자동 활성화. Spec 생성을 caller가 직접 수행한다.
|
|
42
|
+
|
|
43
|
+
### 추가 Input 파라미터
|
|
44
|
+
|
|
45
|
+
| 파라미터 | 타입 | 필수 | 설명 |
|
|
46
|
+
|---------|------|------|------|
|
|
47
|
+
| `spec` | object | 2단계에서 필수 | caller가 생성한 Spec JSON |
|
|
48
|
+
| `spec.goal` | string | 필수 | 프로젝트 목표 |
|
|
49
|
+
| `spec.constraints` | string[] | 필수 | 기술/비즈니스 제약조건 |
|
|
50
|
+
| `spec.acceptanceCriteria` | string[] | 필수 | 수용 기준 |
|
|
51
|
+
| `spec.ontologySchema` | object | 필수 | 엔티티-관계 모델 |
|
|
52
|
+
| `spec.gestaltAnalysis` | array | 필수 | 게슈탈트 분석 결과 |
|
|
53
|
+
|
|
54
|
+
### 2단계 플로우
|
|
55
|
+
|
|
56
|
+
**1단계: SpecContext 요청**
|
|
57
|
+
```
|
|
58
|
+
ges_generate_spec({ sessionId: "<id>" })
|
|
59
|
+
```
|
|
60
|
+
→ `{ status: "prompt", specContext, message }` 반환
|
|
61
|
+
|
|
62
|
+
SpecContext 필드:
|
|
63
|
+
- `systemPrompt`: Spec 생성용 시스템 프롬프트
|
|
64
|
+
- `specPrompt`: 인터뷰 내용 기반 Spec 생성 프롬프트
|
|
65
|
+
- `allRounds[]`: `{ roundNumber, question, response, gestaltFocus }`
|
|
66
|
+
|
|
67
|
+
**2단계: Spec 제출 및 검증**
|
|
68
|
+
```
|
|
69
|
+
ges_generate_spec({
|
|
70
|
+
sessionId: "<id>",
|
|
71
|
+
spec: {
|
|
72
|
+
goal: "명확한 프로젝트 목표",
|
|
73
|
+
constraints: ["TypeScript 사용", "REST API"],
|
|
74
|
+
acceptanceCriteria: ["응답 시간 200ms 이하"],
|
|
75
|
+
ontologySchema: {
|
|
76
|
+
entities: [{ name: "User", description: "...", attributes: ["id", "email"] }],
|
|
77
|
+
relations: [{ from: "User", to: "Order", type: "has_many" }]
|
|
78
|
+
},
|
|
79
|
+
gestaltAnalysis: [
|
|
80
|
+
{ principle: "closure", finding: "인증 요구사항 완전히 파악됨", confidence: 0.9 }
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
→ `{ status: "generated", spec }` (metadata 자동 생성 포함) 또는 `{ error }` 반환
|
|
86
|
+
|
|
87
|
+
### Spec 검증 스키마 (Zod)
|
|
88
|
+
|
|
89
|
+
- `gestaltAnalysis[].principle`: `closure | proximity | similarity | figure_ground | continuity`
|
|
90
|
+
- `gestaltAnalysis[].confidence`: 0.0 ~ 1.0
|
|
91
|
+
- `ontologySchema.entities[]`: `{ name: string(min 1), description: string, attributes: string[] }`
|
|
92
|
+
- `ontologySchema.relations[]`: `{ from: string(min 1), to: string(min 1), type: string(min 1) }`
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AgentDefinition, AgentTier, LLMProvider } from '../core/types.js';
|
|
2
|
+
import type { LLMAdapter } from '../llm/types.js';
|
|
3
|
+
export interface ProviderConfig {
|
|
4
|
+
provider: LLMProvider;
|
|
5
|
+
model: string;
|
|
6
|
+
adapter: LLMAdapter;
|
|
7
|
+
}
|
|
8
|
+
export interface TierMapping {
|
|
9
|
+
frugal: ProviderConfig;
|
|
10
|
+
standard: ProviderConfig;
|
|
11
|
+
frontier: ProviderConfig;
|
|
12
|
+
}
|
|
13
|
+
export interface RouterOptions {
|
|
14
|
+
tierMapping: TierMapping;
|
|
15
|
+
defaultTier?: AgentTier;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* FiguralRouter: Gestalt Figure-Ground 원리 기반 모델 선택 라우터
|
|
19
|
+
*
|
|
20
|
+
* 3-level 우선순위:
|
|
21
|
+
* 1. Runtime override (호출 시 직접 지정)
|
|
22
|
+
* 2. AGENT.md tier (에이전트 정의의 tier 필드)
|
|
23
|
+
* 3. Default tier (라우터 기본값, 'standard')
|
|
24
|
+
*/
|
|
25
|
+
export declare class FiguralRouter {
|
|
26
|
+
private tierMapping;
|
|
27
|
+
private defaultTier;
|
|
28
|
+
constructor(options: RouterOptions);
|
|
29
|
+
/**
|
|
30
|
+
* 에이전트에 적합한 LLM adapter를 반환한다.
|
|
31
|
+
* @param agent - 에이전트 정의 (AGENT.md에서 파싱)
|
|
32
|
+
* @param tierOverride - 런타임에서 tier를 강제 지정할 때 사용
|
|
33
|
+
*/
|
|
34
|
+
route(agent: AgentDefinition, tierOverride?: AgentTier): LLMAdapter;
|
|
35
|
+
/**
|
|
36
|
+
* 에이전트에 적합한 모델명을 반환한다.
|
|
37
|
+
*/
|
|
38
|
+
resolveModel(agent: AgentDefinition, tierOverride?: AgentTier): string;
|
|
39
|
+
/**
|
|
40
|
+
* 에이전트의 tier를 결정한다.
|
|
41
|
+
*/
|
|
42
|
+
private resolveTier;
|
|
43
|
+
/**
|
|
44
|
+
* 등록된 tier 매핑 정보를 반환한다.
|
|
45
|
+
*/
|
|
46
|
+
getTierMapping(): Readonly<TierMapping>;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=figural-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figural-router.d.ts","sourceRoot":"","sources":["../../../src/agent/figural-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,WAAW,CAAY;gBAEnB,OAAO,EAAE,aAAa;IAKlC;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU;IAWnE;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM;IAWtE;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,cAAc,IAAI,QAAQ,CAAC,WAAW,CAAC;CAGxC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { LLMError } from '../core/errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* FiguralRouter: Gestalt Figure-Ground 원리 기반 모델 선택 라우터
|
|
4
|
+
*
|
|
5
|
+
* 3-level 우선순위:
|
|
6
|
+
* 1. Runtime override (호출 시 직접 지정)
|
|
7
|
+
* 2. AGENT.md tier (에이전트 정의의 tier 필드)
|
|
8
|
+
* 3. Default tier (라우터 기본값, 'standard')
|
|
9
|
+
*/
|
|
10
|
+
export class FiguralRouter {
|
|
11
|
+
tierMapping;
|
|
12
|
+
defaultTier;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.tierMapping = options.tierMapping;
|
|
15
|
+
this.defaultTier = options.defaultTier ?? 'standard';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 에이전트에 적합한 LLM adapter를 반환한다.
|
|
19
|
+
* @param agent - 에이전트 정의 (AGENT.md에서 파싱)
|
|
20
|
+
* @param tierOverride - 런타임에서 tier를 강제 지정할 때 사용
|
|
21
|
+
*/
|
|
22
|
+
route(agent, tierOverride) {
|
|
23
|
+
const tier = tierOverride ?? this.resolveTier(agent);
|
|
24
|
+
const config = this.tierMapping[tier];
|
|
25
|
+
if (!config) {
|
|
26
|
+
throw new LLMError(`No provider configured for tier: ${tier}`);
|
|
27
|
+
}
|
|
28
|
+
return config.adapter;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 에이전트에 적합한 모델명을 반환한다.
|
|
32
|
+
*/
|
|
33
|
+
resolveModel(agent, tierOverride) {
|
|
34
|
+
// 1st priority: AGENT.md의 model 필드 (특정 모델 고정)
|
|
35
|
+
if (agent.frontmatter.model) {
|
|
36
|
+
return agent.frontmatter.model;
|
|
37
|
+
}
|
|
38
|
+
// 2nd priority: tier 기반 매핑
|
|
39
|
+
const tier = tierOverride ?? this.resolveTier(agent);
|
|
40
|
+
return this.tierMapping[tier].model;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 에이전트의 tier를 결정한다.
|
|
44
|
+
*/
|
|
45
|
+
resolveTier(agent) {
|
|
46
|
+
return agent.frontmatter.tier ?? this.defaultTier;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 등록된 tier 매핑 정보를 반환한다.
|
|
50
|
+
*/
|
|
51
|
+
getTierMapping() {
|
|
52
|
+
return this.tierMapping;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=figural-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figural-router.js","sourceRoot":"","sources":["../../../src/agent/figural-router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAmB7C;;;;;;;GAOG;AACH,MAAM,OAAO,aAAa;IAChB,WAAW,CAAc;IACzB,WAAW,CAAY;IAE/B,YAAY,OAAsB;QAChC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,UAAU,CAAC;IACvD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAsB,EAAE,YAAwB;QACpD,MAAM,IAAI,GAAG,YAAY,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,KAAsB,EAAE,YAAwB;QAC3D,8CAA8C;QAC9C,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC;QACjC,CAAC;QAED,2BAA2B;QAC3B,MAAM,IAAI,GAAG,YAAY,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;IACtC,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,KAAsB;QACxC,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/agent/parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,kBAAkB,CAAC;AAW1E,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAuB/E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import matter from 'gray-matter';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { SkillParseError } from '../core/errors.js';
|
|
4
|
+
const agentFrontmatterSchema = z.object({
|
|
5
|
+
name: z.string().min(1),
|
|
6
|
+
model: z.string().optional(),
|
|
7
|
+
tier: z.enum(['frugal', 'standard', 'frontier']),
|
|
8
|
+
pipeline: z.enum(['interview', 'spec', 'execute', 'evaluate']),
|
|
9
|
+
escalateTo: z.string().optional(),
|
|
10
|
+
description: z.string().min(1),
|
|
11
|
+
});
|
|
12
|
+
export function parseAgentMd(content, filePath) {
|
|
13
|
+
try {
|
|
14
|
+
const { data, content: body } = matter(content);
|
|
15
|
+
const result = agentFrontmatterSchema.safeParse(data);
|
|
16
|
+
if (!result.success) {
|
|
17
|
+
const issues = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`);
|
|
18
|
+
throw new SkillParseError(`Invalid AGENT.md frontmatter in ${filePath}:\n${issues.join('\n')}`);
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
frontmatter: result.data,
|
|
22
|
+
systemPrompt: body.trim(),
|
|
23
|
+
filePath,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
if (e instanceof SkillParseError)
|
|
28
|
+
throw e;
|
|
29
|
+
throw new SkillParseError(`Failed to parse AGENT.md at ${filePath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/agent/parser.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAChD,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC9D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,QAAgB;IAC5D,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAEtD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACnF,MAAM,IAAI,eAAe,CACvB,mCAAmC,QAAQ,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrE,CAAC;QACJ,CAAC;QAED,OAAO;YACL,WAAW,EAAE,MAAM,CAAC,IAAwB;YAC5C,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE;YACzB,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,eAAe;YAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,IAAI,eAAe,CACvB,+BAA+B,QAAQ,KAAK,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACzF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AgentPipeline } from '../core/types.js';
|
|
2
|
+
import type { AgentRegistry } from './registry.js';
|
|
3
|
+
/**
|
|
4
|
+
* Pipeline에 매칭되는 에이전트들의 systemPrompt를 결합하여 반환한다.
|
|
5
|
+
* AgentRegistry가 없거나 매칭 에이전트가 없으면 undefined를 반환한다.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveAgentPrompt(registry: AgentRegistry | undefined, pipeline: AgentPipeline): string | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* 기본 systemPrompt에 에이전트 persona를 결합한다.
|
|
10
|
+
* 에이전트가 없으면 기본 systemPrompt를 그대로 반환한다.
|
|
11
|
+
*/
|
|
12
|
+
export declare function mergeSystemPrompt(basePrompt: string, registry: AgentRegistry | undefined, pipeline: AgentPipeline): string;
|
|
13
|
+
/**
|
|
14
|
+
* Pipeline에 매칭되는 에이전트 이름 목록을 반환한다.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getActiveAgentNames(registry: AgentRegistry | undefined, pipeline: AgentPipeline): string[];
|
|
17
|
+
//# sourceMappingURL=prompt-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-resolver.d.ts","sourceRoot":"","sources":["../../../src/agent/prompt-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,QAAQ,EAAE,aAAa,GACtB,MAAM,GAAG,SAAS,CAKpB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,QAAQ,EAAE,aAAa,GACtB,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,QAAQ,EAAE,aAAa,GACtB,MAAM,EAAE,CAGV"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline에 매칭되는 에이전트들의 systemPrompt를 결합하여 반환한다.
|
|
3
|
+
* AgentRegistry가 없거나 매칭 에이전트가 없으면 undefined를 반환한다.
|
|
4
|
+
*/
|
|
5
|
+
export function resolveAgentPrompt(registry, pipeline) {
|
|
6
|
+
if (!registry)
|
|
7
|
+
return undefined;
|
|
8
|
+
const agents = registry.getByPipeline(pipeline);
|
|
9
|
+
if (agents.length === 0)
|
|
10
|
+
return undefined;
|
|
11
|
+
return agents.map((a) => a.systemPrompt).join('\n\n---\n\n');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 기본 systemPrompt에 에이전트 persona를 결합한다.
|
|
15
|
+
* 에이전트가 없으면 기본 systemPrompt를 그대로 반환한다.
|
|
16
|
+
*/
|
|
17
|
+
export function mergeSystemPrompt(basePrompt, registry, pipeline) {
|
|
18
|
+
const agentPrompt = resolveAgentPrompt(registry, pipeline);
|
|
19
|
+
if (!agentPrompt)
|
|
20
|
+
return basePrompt;
|
|
21
|
+
return `${basePrompt}\n\n## Agent Persona\n\n${agentPrompt}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Pipeline에 매칭되는 에이전트 이름 목록을 반환한다.
|
|
25
|
+
*/
|
|
26
|
+
export function getActiveAgentNames(registry, pipeline) {
|
|
27
|
+
if (!registry)
|
|
28
|
+
return [];
|
|
29
|
+
return registry.getByPipeline(pipeline).map((a) => a.frontmatter.name);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=prompt-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-resolver.js","sourceRoot":"","sources":["../../../src/agent/prompt-resolver.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAmC,EACnC,QAAuB;IAEvB,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,QAAmC,EACnC,QAAuB;IAEvB,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW;QAAE,OAAO,UAAU,CAAC;IACpC,OAAO,GAAG,UAAU,2BAA2B,WAAW,EAAE,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAmC,EACnC,QAAuB;IAEvB,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,OAAO,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseRegistry } from '../registry/base-registry.js';
|
|
2
|
+
import type { AgentDefinition, AgentPipeline } from '../core/types.js';
|
|
3
|
+
export declare class AgentRegistry extends BaseRegistry<AgentDefinition> {
|
|
4
|
+
constructor(agentsDir?: string);
|
|
5
|
+
protected parse(content: string, filePath: string): AgentDefinition;
|
|
6
|
+
protected getName(item: AgentDefinition): string;
|
|
7
|
+
getByPipeline(pipeline: AgentPipeline): AgentDefinition[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/agent/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIvE,qBAAa,aAAc,SAAQ,YAAY,CAAC,eAAe,CAAC;gBAClD,SAAS,CAAC,EAAE,MAAM;IAQ9B,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe;IAInE,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM;IAIhD,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,eAAe,EAAE;CAG1D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseRegistry } from '../registry/base-registry.js';
|
|
2
|
+
import { parseAgentMd } from './parser.js';
|
|
3
|
+
const AGENTS_DIR = 'agents';
|
|
4
|
+
export class AgentRegistry extends BaseRegistry {
|
|
5
|
+
constructor(agentsDir) {
|
|
6
|
+
super({
|
|
7
|
+
dir: agentsDir ?? AGENTS_DIR,
|
|
8
|
+
filename: 'AGENT.md',
|
|
9
|
+
label: 'agent',
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
parse(content, filePath) {
|
|
13
|
+
return parseAgentMd(content, filePath);
|
|
14
|
+
}
|
|
15
|
+
getName(item) {
|
|
16
|
+
return item.frontmatter.name;
|
|
17
|
+
}
|
|
18
|
+
getByPipeline(pipeline) {
|
|
19
|
+
return this.getAll().filter((a) => a.frontmatter.pipeline === pipeline);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/agent/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,UAAU,GAAG,QAAQ,CAAC;AAE5B,MAAM,OAAO,aAAc,SAAQ,YAA6B;IAC9D,YAAY,SAAkB;QAC5B,KAAK,CAAC;YACJ,GAAG,EAAE,SAAS,IAAI,UAAU;YAC5B,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;IACL,CAAC;IAES,KAAK,CAAC,OAAe,EAAE,QAAgB;QAC/C,OAAO,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAES,OAAO,CAAC,IAAqB;QACrC,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,aAAa,CAAC,QAAuB;QACnC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IAC1E,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interview.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interview.ts"],"names":[],"mappings":"AAMA,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EnE"}
|