@tienne/gestalt 0.12.2 → 0.13.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 +34 -428
- package/README.ko.md +51 -1
- package/README.md +51 -1
- package/dist/package.json +5 -1
- package/dist/schemas/gestalt.schema.json +41 -3
- package/dist/skills/interview/SKILL.md +18 -1
- package/dist/src/agent/passthrough-generator.d.ts.map +1 -1
- package/dist/src/agent/passthrough-generator.js +3 -1
- package/dist/src/agent/passthrough-generator.js.map +1 -1
- package/dist/src/agent/role-agent-registry.d.ts.map +1 -1
- package/dist/src/agent/role-agent-registry.js.map +1 -1
- package/dist/src/agent/role-match-engine.d.ts.map +1 -1
- package/dist/src/agent/role-match-engine.js.map +1 -1
- package/dist/src/cli/commands/graph-visualize.d.ts.map +1 -1
- package/dist/src/cli/commands/graph-visualize.js +3 -1
- package/dist/src/cli/commands/graph-visualize.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/interview.d.ts.map +1 -1
- package/dist/src/cli/commands/interview.js +2 -2
- package/dist/src/cli/commands/interview.js.map +1 -1
- package/dist/src/cli/commands/spec.d.ts.map +1 -1
- package/dist/src/cli/commands/spec.js +2 -2
- package/dist/src/cli/commands/spec.js.map +1 -1
- package/dist/src/cli/commands/status.d.ts.map +1 -1
- package/dist/src/cli/commands/status.js.map +1 -1
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/code-graph/engine.d.ts.map +1 -1
- package/dist/src/code-graph/engine.js +16 -13
- package/dist/src/code-graph/engine.js.map +1 -1
- package/dist/src/code-graph/plugins/go.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/go.js +28 -4
- package/dist/src/code-graph/plugins/go.js.map +1 -1
- package/dist/src/code-graph/plugins/java.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/java.js +63 -11
- package/dist/src/code-graph/plugins/java.js.map +1 -1
- package/dist/src/code-graph/plugins/kotlin.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/kotlin.js +50 -7
- package/dist/src/code-graph/plugins/kotlin.js.map +1 -1
- package/dist/src/code-graph/plugins/objc.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/objc.js +70 -12
- package/dist/src/code-graph/plugins/objc.js.map +1 -1
- package/dist/src/code-graph/plugins/python.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/python.js +28 -4
- package/dist/src/code-graph/plugins/python.js.map +1 -1
- package/dist/src/code-graph/plugins/rust.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/rust.js +72 -12
- package/dist/src/code-graph/plugins/rust.js.map +1 -1
- package/dist/src/code-graph/plugins/swift.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/swift.js +62 -8
- package/dist/src/code-graph/plugins/swift.js.map +1 -1
- package/dist/src/code-graph/plugins/typescript.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/typescript.js +2 -2
- package/dist/src/code-graph/plugins/typescript.js.map +1 -1
- package/dist/src/code-graph/providers/local-embedding.js +1 -1
- package/dist/src/code-graph/providers/local-embedding.js.map +1 -1
- package/dist/src/code-graph/storage.d.ts.map +1 -1
- package/dist/src/code-graph/storage.js +1 -3
- package/dist/src/code-graph/storage.js.map +1 -1
- package/dist/src/core/config.d.ts +138 -1
- package/dist/src/core/config.d.ts.map +1 -1
- package/dist/src/core/config.js +36 -3
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/constants.d.ts.map +1 -1
- package/dist/src/core/constants.js +6 -6
- package/dist/src/core/constants.js.map +1 -1
- package/dist/src/core/result.d.ts.map +1 -1
- package/dist/src/core/result.js.map +1 -1
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/execute/audit-engine.d.ts.map +1 -1
- package/dist/src/execute/audit-engine.js +1 -3
- package/dist/src/execute/audit-engine.js.map +1 -1
- package/dist/src/execute/dag-validator.d.ts.map +1 -1
- package/dist/src/execute/dag-validator.js.map +1 -1
- package/dist/src/execute/parallel-groups.d.ts.map +1 -1
- package/dist/src/execute/parallel-groups.js.map +1 -1
- package/dist/src/execute/passthrough-engine.d.ts.map +1 -1
- package/dist/src/execute/passthrough-engine.js +34 -14
- package/dist/src/execute/passthrough-engine.js.map +1 -1
- package/dist/src/execute/prompts.d.ts.map +1 -1
- package/dist/src/execute/prompts.js +2 -4
- package/dist/src/execute/prompts.js.map +1 -1
- package/dist/src/execute/repository.d.ts.map +1 -1
- package/dist/src/execute/repository.js.map +1 -1
- package/dist/src/execute/session.d.ts.map +1 -1
- package/dist/src/execute/session.js +2 -1
- package/dist/src/execute/session.js.map +1 -1
- package/dist/src/execute/termination-detector.d.ts.map +1 -1
- package/dist/src/execute/termination-detector.js +3 -2
- package/dist/src/execute/termination-detector.js.map +1 -1
- package/dist/src/gestalt/analyzer.d.ts.map +1 -1
- package/dist/src/gestalt/analyzer.js +1 -2
- package/dist/src/gestalt/analyzer.js.map +1 -1
- package/dist/src/gestalt/principles.d.ts.map +1 -1
- package/dist/src/gestalt/principles.js +1 -3
- package/dist/src/gestalt/principles.js.map +1 -1
- package/dist/src/interview/engine.d.ts.map +1 -1
- package/dist/src/interview/engine.js +4 -1
- package/dist/src/interview/engine.js.map +1 -1
- package/dist/src/interview/mini-interview-engine.d.ts.map +1 -1
- package/dist/src/interview/mini-interview-engine.js +1 -3
- package/dist/src/interview/mini-interview-engine.js.map +1 -1
- package/dist/src/interview/passthrough-engine.d.ts.map +1 -1
- package/dist/src/interview/passthrough-engine.js +7 -3
- package/dist/src/interview/passthrough-engine.js.map +1 -1
- package/dist/src/interview/repository.d.ts.map +1 -1
- package/dist/src/interview/repository.js.map +1 -1
- package/dist/src/interview/resolution.js +1 -3
- package/dist/src/interview/resolution.js.map +1 -1
- package/dist/src/interview/session.d.ts.map +1 -1
- package/dist/src/interview/session.js.map +1 -1
- package/dist/src/llm/adapter.d.ts.map +1 -1
- package/dist/src/llm/adapter.js.map +1 -1
- package/dist/src/llm/factory.d.ts +24 -0
- package/dist/src/llm/factory.d.ts.map +1 -0
- package/dist/src/llm/factory.js +75 -0
- package/dist/src/llm/factory.js.map +1 -0
- package/dist/src/llm/openai-adapter.d.ts +1 -1
- package/dist/src/llm/openai-adapter.d.ts.map +1 -1
- package/dist/src/llm/openai-adapter.js +2 -2
- package/dist/src/llm/openai-adapter.js.map +1 -1
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +224 -88
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +289 -109
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/mcp/tools/benchmark-passthrough.js +1 -1
- package/dist/src/mcp/tools/benchmark-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/create-agent-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/create-agent-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute-passthrough.js +39 -25
- package/dist/src/mcp/tools/execute-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/graph-visualize-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/graph-visualize-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.js +7 -3
- package/dist/src/mcp/tools/interview-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/interview.d.ts.map +1 -1
- package/dist/src/mcp/tools/interview.js +4 -2
- package/dist/src/mcp/tools/interview.js.map +1 -1
- package/dist/src/mcp/tools/review-passthrough.js +1 -1
- package/dist/src/mcp/tools/review-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/spec-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/spec.d.ts.map +1 -1
- package/dist/src/mcp/tools/spec.js.map +1 -1
- package/dist/src/mcp/tools/status.d.ts.map +1 -1
- package/dist/src/mcp/tools/status.js +1 -1
- package/dist/src/mcp/tools/status.js.map +1 -1
- package/dist/src/memory/memory-context-injector.d.ts.map +1 -1
- package/dist/src/memory/memory-context-injector.js +2 -6
- package/dist/src/memory/memory-context-injector.js.map +1 -1
- package/dist/src/memory/user-profile-store.d.ts.map +1 -1
- package/dist/src/memory/user-profile-store.js +1 -4
- package/dist/src/memory/user-profile-store.js.map +1 -1
- package/dist/src/recording/agg-converter.d.ts.map +1 -1
- package/dist/src/recording/agg-converter.js.map +1 -1
- package/dist/src/recording/agg-installer.d.ts.map +1 -1
- package/dist/src/recording/agg-installer.js.map +1 -1
- package/dist/src/recording/asciinema-installer.d.ts.map +1 -1
- package/dist/src/recording/asciinema-installer.js.map +1 -1
- package/dist/src/recording/asciinema-recorder.d.ts.map +1 -1
- package/dist/src/recording/asciinema-recorder.js.map +1 -1
- package/dist/src/recording/cast-generator.d.ts.map +1 -1
- package/dist/src/recording/cast-generator.js +38 -13
- package/dist/src/recording/cast-generator.js.map +1 -1
- package/dist/src/recording/filename-generator.d.ts.map +1 -1
- package/dist/src/recording/filename-generator.js +2 -2
- package/dist/src/recording/filename-generator.js.map +1 -1
- package/dist/src/recording/recording-orchestrator.d.ts.map +1 -1
- package/dist/src/recording/recording-orchestrator.js.map +1 -1
- package/dist/src/registry/base-registry.d.ts.map +1 -1
- package/dist/src/registry/base-registry.js.map +1 -1
- package/dist/src/resilience/lateral.d.ts.map +1 -1
- package/dist/src/resilience/lateral.js +6 -1
- package/dist/src/resilience/lateral.js.map +1 -1
- package/dist/src/resilience/prompts.d.ts.map +1 -1
- package/dist/src/resilience/prompts.js.map +1 -1
- package/dist/src/review/agent-matcher.d.ts.map +1 -1
- package/dist/src/review/agent-matcher.js.map +1 -1
- package/dist/src/review/context-collector.d.ts.map +1 -1
- package/dist/src/review/context-collector.js.map +1 -1
- package/dist/src/review/passthrough-engine.d.ts.map +1 -1
- package/dist/src/review/passthrough-engine.js +1 -3
- package/dist/src/review/passthrough-engine.js.map +1 -1
- package/dist/src/review/report-generator.d.ts.map +1 -1
- package/dist/src/review/report-generator.js.map +1 -1
- package/dist/src/scripts/postinstall.js +3 -1
- package/dist/src/scripts/postinstall.js.map +1 -1
- package/dist/src/spec/generator.d.ts.map +1 -1
- package/dist/src/spec/generator.js.map +1 -1
- package/dist/src/spec/passthrough-generator.d.ts.map +1 -1
- package/dist/src/spec/passthrough-generator.js.map +1 -1
- package/dist/src/spec/schema.js +1 -1
- package/dist/src/spec/schema.js.map +1 -1
- package/dist/src/spec/text-based-spec-generator.d.ts.map +1 -1
- package/dist/src/spec/text-based-spec-generator.js +3 -1
- package/dist/src/spec/text-based-spec-generator.js.map +1 -1
- package/dist/src/tui/hooks/event-store-reader.d.ts.map +1 -1
- package/dist/src/tui/hooks/event-store-reader.js +1 -3
- package/dist/src/tui/hooks/event-store-reader.js.map +1 -1
- package/dist/src/tui/hooks/useEventStorePoller.d.ts.map +1 -1
- package/dist/src/tui/hooks/useEventStorePoller.js +1 -3
- package/dist/src/tui/hooks/useEventStorePoller.js.map +1 -1
- package/package.json +5 -1
- package/schemas/gestalt.schema.json +41 -3
- package/skills/interview/SKILL.md +18 -1
package/CLAUDE.md
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
## Architecture
|
|
8
8
|
- **Interview Engine**: 게슈탈트 원리 기반 Q&A로 해상도 점수를 0.8 이상으로 높임
|
|
9
9
|
- **Spec Generator**: 완료된 인터뷰에서 구조화된 프로젝트 스펙(Spec) 생성
|
|
10
|
-
- **Execute Engine**:
|
|
10
|
+
- **Execute Engine**: Spec→ExecutionPlan 변환 (Figure-Ground→Closure→Proximity→Continuity)
|
|
11
11
|
- **Resilience Engine**: Stagnation 감지 → Lateral Thinking Personas → Human Escalation
|
|
12
|
-
- **MCP Server**: stdio transport
|
|
13
|
-
- **Skill System**: SKILL.md 기반 확장, chokidar hot-reload
|
|
14
|
-
- **Code Knowledge Graph**:
|
|
12
|
+
- **MCP Server**: stdio transport, API 키 없으면 Passthrough 모드 자동 활성화
|
|
13
|
+
- **Skill System**: SKILL.md 기반 확장, chokidar hot-reload
|
|
14
|
+
- **Code Knowledge Graph**: 정적 분석 → 의존성 그래프 → Blast-Radius 영향 파일 추출
|
|
15
15
|
- **Event Store**: better-sqlite3 WAL 모드 이벤트 소싱
|
|
16
16
|
|
|
17
17
|
## Tech Stack
|
|
@@ -20,441 +20,47 @@ Dependencies: @anthropic-ai/sdk, @modelcontextprotocol/sdk, better-sqlite3, zod,
|
|
|
20
20
|
|
|
21
21
|
## Key Commands
|
|
22
22
|
```bash
|
|
23
|
-
pnpm test #
|
|
24
|
-
pnpm run serve #
|
|
25
|
-
pnpm tsx bin/gestalt.ts interview "topic"
|
|
26
|
-
pnpm tsx bin/gestalt.ts spec <session-id>
|
|
27
|
-
pnpm tsx bin/gestalt.ts status
|
|
28
|
-
pnpm tsx bin/gestalt.ts
|
|
29
|
-
pnpm tsx bin/gestalt.ts init # One-step onboarding: gestalt.json + code graph + post-commit hook
|
|
30
|
-
pnpm tsx bin/gestalt.ts init --skip-graph # Skip code graph build
|
|
31
|
-
pnpm tsx bin/gestalt.ts init --skip-hook # Skip post-commit hook installation
|
|
23
|
+
pnpm test # 전체 테스트
|
|
24
|
+
pnpm run serve # MCP 서버 시작
|
|
25
|
+
pnpm tsx bin/gestalt.ts interview "topic"
|
|
26
|
+
pnpm tsx bin/gestalt.ts spec <session-id>
|
|
27
|
+
pnpm tsx bin/gestalt.ts status
|
|
28
|
+
pnpm tsx bin/gestalt.ts init # gestalt.json + code graph + post-commit hook
|
|
32
29
|
```
|
|
33
30
|
|
|
34
|
-
## Configuration
|
|
35
|
-
|
|
36
|
-
설정값은 다음 우선순위로 merge된다 (높→낮):
|
|
37
|
-
1. `loadConfig(overrides)` — 코드에서 직접 전달
|
|
38
|
-
2. Shell 환경변수 (`export GESTALT_*`)
|
|
39
|
-
3. `.env` 파일 (dotenv)
|
|
40
|
-
4. `gestalt.json` 파일
|
|
41
|
-
5. 기본값
|
|
42
|
-
|
|
43
|
-
### gestalt.json
|
|
44
|
-
`gestalt setup` 명령어로 생성. JSON Schema로 IDE 자동완성 지원.
|
|
45
|
-
|
|
46
|
-
```json
|
|
47
|
-
{
|
|
48
|
-
"$schema": "./node_modules/@tienne/gestalt/schemas/gestalt.schema.json",
|
|
49
|
-
"llm": { "apiKey": "", "model": "claude-sonnet-4-20250514" },
|
|
50
|
-
"interview": { "resolutionThreshold": 0.8, "maxRounds": 10 },
|
|
51
|
-
"execute": { "driftThreshold": 0.3, "successThreshold": 0.85, "goalAlignmentThreshold": 0.80 },
|
|
52
|
-
"dbPath": ".gestalt/gestalt.db",
|
|
53
|
-
"logLevel": "info"
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### GestaltConfig 구조 (nested)
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
interface GestaltConfig {
|
|
61
|
-
llm: { apiKey: string; model: string };
|
|
62
|
-
interview: { resolutionThreshold: number; maxRounds: number };
|
|
63
|
-
execute: { driftThreshold: number; successThreshold: number; goalAlignmentThreshold: number };
|
|
64
|
-
notifications: boolean;
|
|
65
|
-
dbPath: string;
|
|
66
|
-
skillsDir: string;
|
|
67
|
-
agentsDir: string;
|
|
68
|
-
logLevel: 'debug' | 'info' | 'warn' | 'error';
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 환경변수 매핑
|
|
73
|
-
|
|
74
|
-
| 환경변수 | Config 경로 | 기본값 |
|
|
75
|
-
|----------|-------------|--------|
|
|
76
|
-
| `ANTHROPIC_API_KEY` | `llm.apiKey` | `""` |
|
|
77
|
-
| `GESTALT_MODEL` | `llm.model` | `"claude-sonnet-4-20250514"` |
|
|
78
|
-
| `GESTALT_RESOLUTION_THRESHOLD` | `interview.resolutionThreshold` | `0.8` |
|
|
79
|
-
| `GESTALT_MAX_ROUNDS` | `interview.maxRounds` | `10` |
|
|
80
|
-
| `GESTALT_DRIFT_THRESHOLD` | `execute.driftThreshold` | `0.3` |
|
|
81
|
-
| `GESTALT_EVOLVE_SUCCESS_THRESHOLD` | `execute.successThreshold` | `0.85` |
|
|
82
|
-
| `GESTALT_EVOLVE_GOAL_ALIGNMENT_THRESHOLD` | `execute.goalAlignmentThreshold` | `0.80` |
|
|
83
|
-
| `GESTALT_NOTIFICATIONS` | `notifications` | `false` |
|
|
84
|
-
| `GESTALT_DB_PATH` | `dbPath` | `"~/.gestalt/events.db"` |
|
|
85
|
-
| `GESTALT_SKILLS_DIR` | `skillsDir` | `"skills"` |
|
|
86
|
-
| `GESTALT_AGENTS_DIR` | `agentsDir` | `"agents"` |
|
|
87
|
-
| `GESTALT_LOG_LEVEL` | `logLevel` | `"info"` |
|
|
88
|
-
|
|
89
|
-
잘못된 설정값은 경고를 출력하고 기본값으로 fallback한다 (에러를 throw하지 않음).
|
|
90
|
-
|
|
91
31
|
## MCP Tools
|
|
92
32
|
- `ges_interview`: action=[start|respond|score|complete]
|
|
93
|
-
- `ges_generate_spec`: sessionId
|
|
94
|
-
- `ges_execute`: action=[start|plan_step|plan_complete|execute_start|execute_task|evaluate|status|evolve_fix|evolve|evolve_patch|evolve_re_execute|evolve_lateral|evolve_lateral_result|role_match|role_consensus]
|
|
95
|
-
- `ges_create_agent`: action=[start|submit]
|
|
96
|
-
- `ges_code_graph`: action=[build|blast_radius|query|stats|db_exists]
|
|
33
|
+
- `ges_generate_spec`: sessionId?, text?, force?, spec?
|
|
34
|
+
- `ges_execute`: action=[start|plan_step|plan_complete|execute_start|execute_task|evaluate|status|evolve_fix|evolve|evolve_patch|evolve_re_execute|evolve_lateral|evolve_lateral_result|role_match|role_consensus|review_start|review_submit|review_consensus|review_fix]
|
|
35
|
+
- `ges_create_agent`: action=[start|submit]
|
|
36
|
+
- `ges_code_graph`: action=[build|blast_radius|diff_radius|query|stats|db_exists]
|
|
97
37
|
- `ges_status`: sessionId?
|
|
98
38
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
### 설치 방법
|
|
104
|
-
|
|
105
|
-
**Claude Plugin (Recommended)**
|
|
106
|
-
```bash
|
|
107
|
-
# 1. 마켓플레이스 등록 (최초 1회)
|
|
108
|
-
/plugin marketplace add tienne/gestalt
|
|
109
|
-
|
|
110
|
-
# 2. 플러그인 설치
|
|
111
|
-
/plugin install gestalt@gestalt
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**MCP 직접 설정** (claude_desktop_config.json / settings.json)
|
|
115
|
-
```json
|
|
116
|
-
{
|
|
117
|
-
"mcpServers": {
|
|
118
|
-
"gestalt": {
|
|
119
|
-
"command": "npx",
|
|
120
|
-
"args": ["-y", "@tienne/gestalt"]
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
> `env`에 `ANTHROPIC_API_KEY`를 넣지 않으면 passthrough 모드로 동작.
|
|
126
|
-
|
|
127
|
-
### Interview → Spec 전체 플로우
|
|
128
|
-
|
|
129
|
-
**Step 1: 인터뷰 시작**
|
|
130
|
-
```
|
|
131
|
-
ges_interview({ action: "start", topic: "사용자 인증 시스템" })
|
|
132
|
-
```
|
|
133
|
-
→ `gestaltContext` 반환 (systemPrompt, questionPrompt, currentPrinciple, phase 등)
|
|
134
|
-
|
|
135
|
-
**Step 2: 질문 생성 (caller 수행)**
|
|
136
|
-
`gestaltContext.systemPrompt` + `gestaltContext.questionPrompt`를 사용해 질문을 생성한다.
|
|
137
|
-
|
|
138
|
-
**Step 3: 사용자 응답 수집 후 전달**
|
|
139
|
-
```
|
|
140
|
-
ges_interview({
|
|
141
|
-
action: "respond",
|
|
142
|
-
sessionId: "<sessionId>",
|
|
143
|
-
response: "사용자 답변",
|
|
144
|
-
generatedQuestion: "caller가 생성한 질문",
|
|
145
|
-
resolutionScore: { // 선택사항
|
|
146
|
-
goalClarity: 0.7,
|
|
147
|
-
constraintClarity: 0.5,
|
|
148
|
-
successCriteria: 0.4,
|
|
149
|
-
priorityClarity: 0.6
|
|
150
|
-
}
|
|
151
|
-
})
|
|
152
|
-
```
|
|
153
|
-
→ 다음 `gestaltContext` + `resolutionScore` 반환. `resolutionScore.isReady === true`가 될 때까지 반복.
|
|
154
|
-
|
|
155
|
-
**Step 4: 스코어링 (선택)**
|
|
156
|
-
respond 시 resolutionScore를 안 보냈다면 별도로 요청 가능:
|
|
157
|
-
```
|
|
158
|
-
ges_interview({ action: "score", sessionId: "<id>" })
|
|
159
|
-
→ scoringPrompt 반환 → caller가 점수 산출 →
|
|
160
|
-
ges_interview({ action: "score", sessionId: "<id>", resolutionScore: {...} })
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**Step 5: 인터뷰 완료**
|
|
164
|
-
```
|
|
165
|
-
ges_interview({ action: "complete", sessionId: "<id>" })
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
**Step 6: Spec 생성 (2단계)**
|
|
169
|
-
|
|
170
|
-
두 가지 입력 경로 중 하나를 선택한다.
|
|
171
|
-
|
|
172
|
-
```
|
|
173
|
-
// Text-based 경로 (인터뷰 불필요)
|
|
174
|
-
ges_generate_spec({ text: "..." })
|
|
175
|
-
→ specContext (systemPrompt, specPrompt) 반환
|
|
176
|
-
|
|
177
|
-
ges_generate_spec({ text: "...", spec: {...} })
|
|
178
|
-
→ Zod 검증 후 최종 Spec 반환 + .gestalt/memory.json 자동 업데이트
|
|
179
|
-
|
|
180
|
-
// Interview 기반 경로 (6a: specContext 요청)
|
|
181
|
-
ges_generate_spec({ sessionId: "<id>" })
|
|
182
|
-
→ specContext (systemPrompt, specPrompt, allRounds) 반환
|
|
183
|
-
|
|
184
|
-
// 6b: caller가 spec JSON 생성 후 제출
|
|
185
|
-
ges_generate_spec({
|
|
186
|
-
sessionId: "<id>",
|
|
187
|
-
spec: {
|
|
188
|
-
goal: "...",
|
|
189
|
-
constraints: ["..."],
|
|
190
|
-
acceptanceCriteria: ["..."],
|
|
191
|
-
ontologySchema: { entities: [...], relations: [...] },
|
|
192
|
-
gestaltAnalysis: [{ principle: "closure", finding: "...", confidence: 0.9 }]
|
|
193
|
-
}
|
|
194
|
-
})
|
|
195
|
-
→ Zod 검증 후 최종 Spec 반환
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Spec → Execute 플로우
|
|
199
|
-
|
|
200
|
-
**Step 1: 실행 계획 세션 시작**
|
|
201
|
-
```
|
|
202
|
-
ges_execute({ action: "start", spec: { ...completeSpecObject } })
|
|
203
|
-
```
|
|
204
|
-
→ `executeContext` 반환 (systemPrompt, planningPrompt, currentPrinciple 등)
|
|
205
|
-
|
|
206
|
-
**Step 2~5: 4단계 계획 수립 (caller가 각 단계 결과를 생성)**
|
|
207
|
-
```
|
|
208
|
-
// Figure-Ground → Closure → Proximity → Continuity 순서로 진행
|
|
209
|
-
ges_execute({
|
|
210
|
-
action: "plan_step",
|
|
211
|
-
sessionId: "<id>",
|
|
212
|
-
stepResult: { principle: "figure_ground", classifiedACs: [...] }
|
|
213
|
-
})
|
|
214
|
-
→ 다음 단계 executeContext 반환. isLastStep === true가 될 때까지 반복.
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
**Step 6: 실행 계획 조립**
|
|
218
|
-
```
|
|
219
|
-
ges_execute({ action: "plan_complete", sessionId: "<id>" })
|
|
220
|
-
→ ExecutionPlan (classifiedACs, atomicTasks, taskGroups, dagValidation) 반환
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Execute → Evaluate → Evolution 플로우
|
|
224
|
-
|
|
225
|
-
**Execution Phase**: execute_start → execute_task (반복) → evaluate (3-Call: structural → contextual)
|
|
226
|
-
|
|
227
|
-
**Evolution Loop** (Evaluate 점수가 threshold 미달 시):
|
|
228
|
-
|
|
229
|
-
**Flow A: Structural Fix** (structural 실패 시)
|
|
230
|
-
```
|
|
231
|
-
// 1. Fix context 요청
|
|
232
|
-
ges_execute({ action: "evolve_fix", sessionId: "<id>" })
|
|
233
|
-
→ fixContext 반환
|
|
234
|
-
|
|
235
|
-
// 2. Fix tasks 제출
|
|
236
|
-
ges_execute({ action: "evolve_fix", sessionId: "<id>", fixTasks: [...] })
|
|
237
|
-
→ 상태 복원, evaluate 재실행 가능
|
|
238
|
-
|
|
239
|
-
// 3. Re-evaluate
|
|
240
|
-
ges_execute({ action: "evaluate", sessionId: "<id>" })
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
**Flow B: Contextual Evolution** (structural 통과, contextual 점수 미달 시)
|
|
244
|
-
```
|
|
245
|
-
// 1. Evolution context 요청
|
|
246
|
-
ges_execute({ action: "evolve", sessionId: "<id>" })
|
|
247
|
-
→ evolveContext 반환 (또는 terminateReason으로 종료)
|
|
248
|
-
|
|
249
|
-
// 2. Spec patch 제출
|
|
250
|
-
ges_execute({ action: "evolve_patch", sessionId: "<id>", specPatch: {...} })
|
|
251
|
-
→ impactedTaskIds + reExecuteContext 반환
|
|
252
|
-
|
|
253
|
-
// 3. Impacted tasks 재실행 (반복)
|
|
254
|
-
ges_execute({ action: "evolve_re_execute", sessionId: "<id>", reExecuteTaskResult: {...} })
|
|
255
|
-
→ allTasksCompleted === true가 될 때까지 반복
|
|
256
|
-
|
|
257
|
-
// 4. Re-evaluate
|
|
258
|
-
ges_execute({ action: "evaluate", sessionId: "<id>" })
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**Spec Patch 범위**: L1(AC)+L2(constraints) 자유, L3(ontology) 추가/변경만, L4(goal) 금지
|
|
262
|
-
**종료 조건**: success(≥0.85, ≥0.80), stagnation, oscillation, hard_cap(3+3), caller, human_escalation
|
|
263
|
-
**Caller 종료**: `ges_execute({ action: "evolve", sessionId: "<id>", terminateReason: "caller" })`
|
|
264
|
-
|
|
265
|
-
**Flow C: Lateral Thinking** (evolution stagnation/oscillation/hard_cap 감지 시 자동 분기)
|
|
266
|
-
|
|
267
|
-
evolve 호출 시 non-success termination이 감지되면 즉시 종료하는 대신 lateral thinking persona로 자동 분기한다.
|
|
268
|
-
|
|
269
|
-
```
|
|
270
|
-
// 1. evolve 호출 → lateralContext 자동 반환 (stagnation 시)
|
|
271
|
-
ges_execute({ action: "evolve", sessionId: "<id>" })
|
|
272
|
-
→ { status: "lateral_thinking", lateralContext: { persona, pattern, systemPrompt, lateralPrompt, ... } }
|
|
273
|
-
|
|
274
|
-
// 2. Lateral result 제출 (caller가 persona 관점으로 specPatch 생성)
|
|
275
|
-
ges_execute({
|
|
276
|
-
action: "evolve_lateral_result",
|
|
277
|
-
sessionId: "<id>",
|
|
278
|
-
lateralResult: {
|
|
279
|
-
persona: "multistability",
|
|
280
|
-
specPatch: { acceptanceCriteria: [...], constraints: [...] },
|
|
281
|
-
description: "관점 전환으로 요구사항 재구성"
|
|
282
|
-
}
|
|
283
|
-
})
|
|
284
|
-
→ impactedTaskIds + reExecuteContext 반환
|
|
285
|
-
|
|
286
|
-
// 3. Impacted tasks 재실행 (기존 action 재사용)
|
|
287
|
-
ges_execute({ action: "evolve_re_execute", sessionId: "<id>", reExecuteTaskResult: {...} })
|
|
288
|
-
→ 반복...
|
|
289
|
-
|
|
290
|
-
// 4. Re-evaluate
|
|
291
|
-
ges_execute({ action: "evaluate", sessionId: "<id>" })
|
|
292
|
-
|
|
293
|
-
// 5. 다음 persona 요청 (점수 미달 시)
|
|
294
|
-
ges_execute({ action: "evolve_lateral", sessionId: "<id>" })
|
|
295
|
-
→ 다음 lateralContext (or humanEscalation if 4개 persona 소진)
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
**Stagnation Pattern → Persona 매핑**:
|
|
299
|
-
| Pattern | Persona | 전략 |
|
|
300
|
-
|---|---|---|
|
|
301
|
-
| spinning (hard_cap) | Multistability | 다른 각도로 보기 |
|
|
302
|
-
| oscillation | Simplicity | 단순하게 줄이기 |
|
|
303
|
-
| no_drift (delta≈0) | Reification | 빠진 조각 채우기 |
|
|
304
|
-
| diminishing_returns (delta↓) | Invariance | 성공 패턴 복제하기 |
|
|
305
|
-
|
|
306
|
-
**Human Escalation**: 4개 persona 모두 소진 시 `humanEscalation` 반환 (triedPersonas, bestScore, suggestions 포함). session은 `status: 'failed'`, `terminationReason: 'human_escalation'`으로 종료.
|
|
307
|
-
|
|
308
|
-
### Interview → Agent 생성 플로우
|
|
309
|
-
|
|
310
|
-
`ges_interview`로 요구사항을 수집한 뒤, `ges_create_agent`로 커스텀 Role Agent AGENT.md 파일을 자동 생성한다.
|
|
311
|
-
|
|
312
|
-
**Step 1: Agent Context 요청**
|
|
313
|
-
```
|
|
314
|
-
ges_create_agent({ action: "start", sessionId: "<완료된 인터뷰 sessionId>" })
|
|
315
|
-
```
|
|
316
|
-
→ `agentContext` 반환 (systemPrompt, creationPrompt, existingAgents, agentMdSchema)
|
|
317
|
-
|
|
318
|
-
**Step 2: AGENT.md 생성 및 제출**
|
|
319
|
-
```
|
|
320
|
-
ges_create_agent({
|
|
321
|
-
action: "submit",
|
|
322
|
-
sessionId: "<id>",
|
|
323
|
-
agentContent: "---\nname: security-expert\ntier: standard\npipeline: execute\nrole: true\ndomain: [\"oauth\", \"jwt\"]\ndescription: \"보안 전문가\"\n---\n\nSystem prompt...",
|
|
324
|
-
cwd: "/path/to/project" // 선택, 기본값 process.cwd()
|
|
325
|
-
})
|
|
326
|
-
```
|
|
327
|
-
→ agents/{name}/AGENT.md 파일 생성, parseAgentMd() 검증, AGENT_CREATED 이벤트 기록
|
|
328
|
-
|
|
329
|
-
**규칙**:
|
|
330
|
-
- 인터뷰 세션이 `completed` 상태여야 함
|
|
331
|
-
- `role: true` 필수 (Role Agent 전용)
|
|
332
|
-
- 동일 이름 에이전트 존재 시 override + 안내 메시지
|
|
333
|
-
|
|
334
|
-
### Role Agent System 플로우
|
|
335
|
-
|
|
336
|
-
태스크 실행 시 관련 Role Agent를 자동 매칭하여 다중 관점 합의를 수행한다.
|
|
337
|
-
|
|
338
|
-
**Step 1: Role Match (2-Call)**
|
|
339
|
-
```
|
|
340
|
-
// Call 1: 매칭 컨텍스트 요청
|
|
341
|
-
ges_execute({ action: "role_match", sessionId: "<id>" })
|
|
342
|
-
→ matchContext 반환
|
|
343
|
-
|
|
344
|
-
// Call 2: 매칭 결과 제출
|
|
345
|
-
ges_execute({ action: "role_match", sessionId: "<id>", matchResult: [...] })
|
|
346
|
-
→ perspectivePrompts 반환
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
**Step 2: Role Consensus (2-Call)**
|
|
350
|
-
```
|
|
351
|
-
// Call 1: 각 에이전트 관점 제출
|
|
352
|
-
ges_execute({ action: "role_consensus", sessionId: "<id>", perspectives: [...] })
|
|
353
|
-
→ synthesisContext 반환
|
|
354
|
-
|
|
355
|
-
// Call 2: 합성된 합의 제출
|
|
356
|
-
ges_execute({ action: "role_consensus", sessionId: "<id>", consensus: {...} })
|
|
357
|
-
→ roleGuidance 반환 → execute_task 수행 시 참조
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
### 핵심 규칙
|
|
361
|
-
- `action: "respond"` 시 `generatedQuestion` **필수**, `resolutionScore` 선택
|
|
362
|
-
- resolutionScore 차원: `goalClarity`, `constraintClarity`, `successCriteria`, `priorityClarity` (필수), `contextClarity` (선택)
|
|
363
|
-
- Spec의 `gestaltAnalysis[].principle`은 enum: `closure | proximity | similarity | figure_ground | continuity`
|
|
364
|
-
- `ontologySchema.entities[]`: `{ name, description, attributes[] }`
|
|
365
|
-
- `ontologySchema.relations[]`: `{ from, to, type }`
|
|
366
|
-
- text-based 경로: `sessionId` 불필요, 생성된 spec의 `interviewSessionId`는 `"text-input"`으로 설정
|
|
39
|
+
상세 플로우 → [`docs/mcp-reference.md`](./docs/mcp-reference.md)
|
|
40
|
+
설정 레퍼런스 → [`docs/configuration.md`](./docs/configuration.md)
|
|
41
|
+
코드 그래프 → [`docs/code-graph.md`](./docs/code-graph.md)
|
|
367
42
|
|
|
368
43
|
## Project Structure
|
|
369
|
-
- `src/core/` — types, errors, Result monad, config, constants
|
|
370
|
-
- `src/gestalt/` — 게슈탈트 원리 엔진 (핵심 차별점)
|
|
371
|
-
- `src/interview/` — InterviewEngine, ResolutionScorer, SessionManager
|
|
372
|
-
- `src/spec/` — SpecGenerator, SpecExtractor
|
|
373
|
-
- `src/execute/` — ExecuteEngine, DAG Validator, ExecuteSessionManager
|
|
374
|
-
- `src/resilience/` — Stagnation Detector, Lateral Thinking Personas, Human Escalation
|
|
375
|
-
- `src/code-graph/` — CodeGraphEngine, CodeGraphStore, BlastRadius, 언어 플러그인 8개
|
|
376
|
-
- `src/skills/` — SkillRegistry, parser
|
|
377
|
-
- `src/agent/` — AgentRegistry, FiguralRouter, multi-provider LLM, RoleAgentRegistry, PassthroughAgentGenerator
|
|
378
|
-
- `src/registry/` — BaseRegistry 추상 클래스
|
|
379
|
-
- `src/mcp/` — MCP 서버 + 툴 핸들러
|
|
380
|
-
- `src/events/` — EventStore (SQLite)
|
|
381
|
-
- `src/llm/` — Anthropic SDK adapter
|
|
382
|
-
- `src/cli/` — commander 기반 CLI (interview, spec, status, setup)
|
|
383
|
-
- `schemas/` — JSON Schema (gestalt.schema.json)
|
|
384
|
-
- `role-agents/` — 내장 Role Agent 정의 (architect, frontend-developer 등 8개)
|
|
385
|
-
- `skills/` — 외부 스킬 정의 (`build-graph`, `blast-radius`)
|
|
386
|
-
|
|
387
|
-
## Code Knowledge Graph
|
|
388
|
-
|
|
389
|
-
코드베이스를 정적 분석해 의존성 그래프를 빌드하고, 변경 영향 파일을 빠르게 추려 AI 컨텍스트를 절약한다.
|
|
390
|
-
|
|
391
|
-
### ges_code_graph MCP 툴
|
|
392
|
-
|
|
393
44
|
```
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
ges_code_graph({ action: "query", repoRoot: "<경로>", pattern: "callers_of"|"callees_of"|"tests_for"|"imports_of", target: "<노드명>" })
|
|
408
|
-
→ { nodes, edges }
|
|
409
|
-
|
|
410
|
-
// 그래프 통계
|
|
411
|
-
ges_code_graph({ action: "stats", repoRoot: "<경로>" })
|
|
412
|
-
→ { totalFiles, totalNodes, totalEdges, lastBuiltAt, dbSizeBytes }
|
|
413
|
-
|
|
414
|
-
// DB 존재 여부 확인
|
|
415
|
-
ges_code_graph({ action: "db_exists", repoRoot: "<경로>" })
|
|
416
|
-
→ { exists: boolean }
|
|
45
|
+
src/core/ — types, errors, Result monad, config, constants
|
|
46
|
+
src/gestalt/ — 게슈탈트 원리 엔진
|
|
47
|
+
src/interview/ — InterviewEngine, ResolutionScorer
|
|
48
|
+
src/spec/ — SpecGenerator, SpecExtractor
|
|
49
|
+
src/execute/ — ExecuteEngine, DAG Validator
|
|
50
|
+
src/resilience/ — Stagnation Detector, Lateral Thinking Personas
|
|
51
|
+
src/code-graph/ — CodeGraphEngine, BlastRadius, 언어 플러그인 8개
|
|
52
|
+
src/agent/ — AgentRegistry, FiguralRouter, RoleAgentRegistry
|
|
53
|
+
src/mcp/ — MCP 서버 + 툴 핸들러
|
|
54
|
+
src/events/ — EventStore (SQLite)
|
|
55
|
+
src/cli/ — commander 기반 CLI
|
|
56
|
+
role-agents/ — 내장 Role Agent 8개
|
|
57
|
+
skills/ — build-graph, blast-radius, diff-radius
|
|
417
58
|
```
|
|
418
59
|
|
|
419
|
-
저장소: `.gestalt/code-graph.db` (WAL SQLite, EventStore DB와 별도)
|
|
420
|
-
|
|
421
|
-
### 자동 컨텍스트 주입 (Execute 파이프라인 통합)
|
|
422
|
-
|
|
423
|
-
`ges_execute { action: "start", spec: {...}, codeGraphRepoRoot: "/path" }` 호출 시 활성화.
|
|
424
|
-
|
|
425
|
-
태스크 실행 시 `buildNextTaskContext()`가 자동으로:
|
|
426
|
-
1. 태스크 title + description에서 키워드를 추출 (`extractKeywords()`)
|
|
427
|
-
2. `codeGraphEngine.searchByKeywords()`로 관련 파일 최대 10개 검색
|
|
428
|
-
3. `execute_task` 응답의 `suggestedFiles` 필드로 반환
|
|
429
|
-
|
|
430
|
-
Claude Code가 `suggestedFiles`를 받으면 해당 파일을 먼저 Read한 뒤 태스크를 수행한다 (`EXECUTE_EXECUTION_SYSTEM_PROMPT` 지시).
|
|
431
|
-
|
|
432
|
-
code-graph.db가 없거나 검색 실패 시 `suggestedFiles`는 undefined — 기존 동작 그대로 유지 (graceful fallback).
|
|
433
|
-
|
|
434
|
-
### 스킬
|
|
435
|
-
|
|
436
|
-
| 스킬 | 파일 | 설명 |
|
|
437
|
-
|------|------|------|
|
|
438
|
-
| `/build-graph` | `skills/build-graph/SKILL.md` | 코드 그래프 빌드 및 증분 갱신 |
|
|
439
|
-
| `/blast-radius` | `skills/blast-radius/SKILL.md` (v1.1.0) | 영향범위 분석 (커밋 기준), 23개 트리거 |
|
|
440
|
-
| `/diff-radius` | `skills/diff-radius/SKILL.md` (v1.0.0) | 영향범위 분석 (미커밋 기준), staged/unstaged/all 지원 |
|
|
441
|
-
|
|
442
|
-
blast-radius 스킬은 "영향범위", "어디까지 영향받아", "사이드 이펙트", "리팩토링" 등 자연스러운 한국어 표현으로 자동 발동한다. CLAUDE.md나 훅과 달리 호출 시에만 토큰이 발생한다.
|
|
443
|
-
|
|
444
|
-
### 언어 플러그인 (8개)
|
|
445
|
-
|
|
446
|
-
TypeScript/JavaScript, Python, Go, Java, Kotlin, Rust, Swift, Objective-C
|
|
447
|
-
|
|
448
|
-
각 플러그인: `{ language, extensions[], parse(filePath) → {nodes, edges} }`
|
|
449
|
-
TypeScript 플러그인은 TypeScript Compiler API 사용 (Tree-sitter 불필요).
|
|
450
|
-
|
|
451
|
-
### 주의사항
|
|
452
|
-
- `glob` 패키지 미사용 → `readdirSync({ recursive: true })`로 파일 수집, `Dirent.parentPath` 활용
|
|
453
|
-
- `noUncheckedIndexedAccess` 환경 → 배열 인덱스·regex 캡처그룹에 `!` 단언 필수
|
|
454
|
-
|
|
455
60
|
## Conventions
|
|
456
|
-
- MCP 서버에서 `console.log`
|
|
61
|
+
- MCP 서버에서 `console.log` 금지 → `log()` stderr 유틸 사용
|
|
62
|
+
- `noUncheckedIndexedAccess` 환경 → 배열 인덱스·regex 캡처그룹에 `!` 단언 필수
|
|
63
|
+
- `glob` 패키지 미사용 → `readdirSync({ recursive: true })` + `Dirent.parentPath`
|
|
457
64
|
- LLM 호출: temperature 0.3, JSON 응답 파싱 + fallback
|
|
458
65
|
- 해상도 점수 ≥ 0.8 = 요구사항 충분히 명확
|
|
459
|
-
-
|
|
460
|
-
- 테스트: 각 test에서 고유 DB 경로 사용 (병렬 테스트 안전)
|
|
66
|
+
- 테스트 DB: `.gestalt-test/xxx-${randomUUID()}.db` 고유 경로 (병렬 안전)
|
package/README.ko.md
CHANGED
|
@@ -140,7 +140,7 @@ Spec과 실행 결과는 레포 루트의 `.gestalt/memory.json`에 자동으로
|
|
|
140
140
|
|
|
141
141
|
| 항목 | 내용 |
|
|
142
142
|
|------|------|
|
|
143
|
-
| **MCP 도구** | `ges_interview`, `ges_generate_spec`, `ges_execute`, `ges_create_agent`, `ges_agent`, `ges_status` |
|
|
143
|
+
| **MCP 도구** | `ges_interview`, `ges_generate_spec`, `ges_execute`, `ges_create_agent`, `ges_agent`, `ges_status`, `ges_code_graph`, `ges_graph_visualize`, `ges_benchmark` |
|
|
144
144
|
| **슬래시 커맨드** | `/interview`, `/spec`, `/execute`, `/agent` |
|
|
145
145
|
| **에이전트** | Gestalt 파이프라인 에이전트 5개 + Role 에이전트 9개 + Review 에이전트 3개 |
|
|
146
146
|
| **CLAUDE.md** | 프로젝트 컨텍스트 및 MCP 사용 가이드 자동 추가 |
|
|
@@ -542,6 +542,44 @@ npx @tienne/gestalt setup
|
|
|
542
542
|
|
|
543
543
|
잘못된 값은 경고를 출력하고 기본값을 사용해요.
|
|
544
544
|
|
|
545
|
+
### 멀티 프로바이더 설정 (LLM Tier)
|
|
546
|
+
|
|
547
|
+
작업 복잡도에 따라 서로 다른 LLM 프로바이더를 tier별로 지정할 수 있어요.
|
|
548
|
+
|
|
549
|
+
| Tier | 용도 | 예시 |
|
|
550
|
+
|------|------|------|
|
|
551
|
+
| **frugal** | 가벼운 작업 — 점수 산정, 분류, 짧은 응답 | `llama3.2`, `haiku` |
|
|
552
|
+
| **standard** | 일반 작업 — 인터뷰, 스펙 생성, 코드 실행 | `claude-sonnet-4-20250514` |
|
|
553
|
+
| **frontier** | 고난도 추론 — 아키텍처 설계, 코드 리뷰, 진화 루프 | `claude-opus-4-20250514` |
|
|
554
|
+
|
|
555
|
+
Anthropic(standard/frontier)과 Ollama(frugal)를 혼합하는 예시예요:
|
|
556
|
+
|
|
557
|
+
```json
|
|
558
|
+
{
|
|
559
|
+
"$schema": "./node_modules/@tienne/gestalt/schemas/gestalt.schema.json",
|
|
560
|
+
"llm": {
|
|
561
|
+
"apiKey": "",
|
|
562
|
+
"model": "claude-sonnet-4-20250514",
|
|
563
|
+
"frugal": {
|
|
564
|
+
"provider": "openai",
|
|
565
|
+
"baseURL": "http://localhost:11434/v1",
|
|
566
|
+
"apiKey": "ollama",
|
|
567
|
+
"model": "llama3.2"
|
|
568
|
+
},
|
|
569
|
+
"standard": {
|
|
570
|
+
"provider": "anthropic",
|
|
571
|
+
"model": "claude-sonnet-4-20250514"
|
|
572
|
+
},
|
|
573
|
+
"frontier": {
|
|
574
|
+
"provider": "anthropic",
|
|
575
|
+
"model": "claude-opus-4-20250514"
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
> tier를 설정하지 않으면 `llm.apiKey` + `llm.model` 조합으로 모든 tier에 Anthropic을 사용해요. 기존 설정과 완전히 호환돼요.
|
|
582
|
+
|
|
545
583
|
### 환경변수
|
|
546
584
|
|
|
547
585
|
| 변수 | Config 경로 | 기본값 | 설명 |
|
|
@@ -557,6 +595,18 @@ npx @tienne/gestalt setup
|
|
|
557
595
|
| `GESTALT_SKILLS_DIR` | `skillsDir` | `skills` | 커스텀 스킬 디렉토리 |
|
|
558
596
|
| `GESTALT_AGENTS_DIR` | `agentsDir` | `agents` | 커스텀 에이전트 디렉토리 |
|
|
559
597
|
| `GESTALT_LOG_LEVEL` | `logLevel` | `info` | 로그 레벨 (`debug`/`info`/`warn`/`error`) |
|
|
598
|
+
| `GESTALT_LLM_FRUGAL_PROVIDER` | `llm.frugal.provider` | — | frugal tier 프로바이더 (`anthropic`/`openai`) |
|
|
599
|
+
| `GESTALT_LLM_FRUGAL_API_KEY` | `llm.frugal.apiKey` | — | frugal tier API 키 |
|
|
600
|
+
| `GESTALT_LLM_FRUGAL_BASE_URL` | `llm.frugal.baseURL` | — | frugal tier API 엔드포인트 (Ollama 등) |
|
|
601
|
+
| `GESTALT_LLM_FRUGAL_MODEL` | `llm.frugal.model` | — | frugal tier 모델 |
|
|
602
|
+
| `GESTALT_LLM_STANDARD_PROVIDER` | `llm.standard.provider` | — | standard tier 프로바이더 |
|
|
603
|
+
| `GESTALT_LLM_STANDARD_API_KEY` | `llm.standard.apiKey` | — | standard tier API 키 |
|
|
604
|
+
| `GESTALT_LLM_STANDARD_BASE_URL` | `llm.standard.baseURL` | — | standard tier API 엔드포인트 |
|
|
605
|
+
| `GESTALT_LLM_STANDARD_MODEL` | `llm.standard.model` | — | standard tier 모델 |
|
|
606
|
+
| `GESTALT_LLM_FRONTIER_PROVIDER` | `llm.frontier.provider` | — | frontier tier 프로바이더 |
|
|
607
|
+
| `GESTALT_LLM_FRONTIER_API_KEY` | `llm.frontier.apiKey` | — | frontier tier API 키 |
|
|
608
|
+
| `GESTALT_LLM_FRONTIER_BASE_URL` | `llm.frontier.baseURL` | — | frontier tier API 엔드포인트 |
|
|
609
|
+
| `GESTALT_LLM_FRONTIER_MODEL` | `llm.frontier.model` | — | frontier tier 모델 |
|
|
560
610
|
|
|
561
611
|
---
|
|
562
612
|
|
package/README.md
CHANGED
|
@@ -130,7 +130,7 @@ What you get out of the box:
|
|
|
130
130
|
|
|
131
131
|
| Item | Details |
|
|
132
132
|
|------|---------|
|
|
133
|
-
| **MCP Tools** | `ges_interview`, `ges_generate_spec`, `ges_execute`, `ges_create_agent`, `ges_agent`, `ges_status` |
|
|
133
|
+
| **MCP Tools** | `ges_interview`, `ges_generate_spec`, `ges_execute`, `ges_create_agent`, `ges_agent`, `ges_status`, `ges_code_graph`, `ges_graph_visualize`, `ges_benchmark` |
|
|
134
134
|
| **Slash Commands** | `/interview`, `/spec`, `/execute`, `/agent` |
|
|
135
135
|
| **Agents** | 5 Gestalt pipeline agents + 9 Role agents + 3 Review agents |
|
|
136
136
|
| **CLAUDE.md** | Project context and MCP usage guide auto-injected |
|
|
@@ -528,6 +528,44 @@ npx @tienne/gestalt setup
|
|
|
528
528
|
|
|
529
529
|
**Config priority** (highest → lowest): code overrides → shell env vars → `.env` → `gestalt.json` → built-in defaults
|
|
530
530
|
|
|
531
|
+
### Multi-Provider Configuration (LLM Tiers)
|
|
532
|
+
|
|
533
|
+
Gestalt supports routing LLM calls by task complexity across three tiers: **frugal**, **standard**, and **frontier**.
|
|
534
|
+
|
|
535
|
+
| Tier | Purpose | Example models |
|
|
536
|
+
|------|---------|---------------|
|
|
537
|
+
| **frugal** | Lightweight tasks — scoring, classification, short responses | `llama3.2`, `claude-haiku` |
|
|
538
|
+
| **standard** | General tasks — interviews, spec generation, execution | `claude-sonnet-4-20250514` |
|
|
539
|
+
| **frontier** | High-complexity reasoning — architecture, code review, evolution loop | `claude-opus-4-20250514` |
|
|
540
|
+
|
|
541
|
+
Mix providers freely. The example below uses Anthropic for standard/frontier and a local Ollama model for frugal tasks:
|
|
542
|
+
|
|
543
|
+
```json
|
|
544
|
+
{
|
|
545
|
+
"$schema": "./node_modules/@tienne/gestalt/schemas/gestalt.schema.json",
|
|
546
|
+
"llm": {
|
|
547
|
+
"apiKey": "",
|
|
548
|
+
"model": "claude-sonnet-4-20250514",
|
|
549
|
+
"frugal": {
|
|
550
|
+
"provider": "openai",
|
|
551
|
+
"baseURL": "http://localhost:11434/v1",
|
|
552
|
+
"apiKey": "ollama",
|
|
553
|
+
"model": "llama3.2"
|
|
554
|
+
},
|
|
555
|
+
"standard": {
|
|
556
|
+
"provider": "anthropic",
|
|
557
|
+
"model": "claude-sonnet-4-20250514"
|
|
558
|
+
},
|
|
559
|
+
"frontier": {
|
|
560
|
+
"provider": "anthropic",
|
|
561
|
+
"model": "claude-opus-4-20250514"
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
> If no tiers are configured, all tiers fall back to the top-level `llm.apiKey` + `llm.model` with the Anthropic adapter — fully backward-compatible.
|
|
568
|
+
|
|
531
569
|
Invalid values emit a warning and fall back to defaults.
|
|
532
570
|
|
|
533
571
|
### Environment Variables
|
|
@@ -545,6 +583,18 @@ Invalid values emit a warning and fall back to defaults.
|
|
|
545
583
|
| `GESTALT_SKILLS_DIR` | `skillsDir` | `skills` | Custom skills directory |
|
|
546
584
|
| `GESTALT_AGENTS_DIR` | `agentsDir` | `agents` | Custom agents directory |
|
|
547
585
|
| `GESTALT_LOG_LEVEL` | `logLevel` | `info` | Log level (`debug`/`info`/`warn`/`error`) |
|
|
586
|
+
| `GESTALT_LLM_FRUGAL_PROVIDER` | `llm.frugal.provider` | `anthropic` | Frugal tier provider |
|
|
587
|
+
| `GESTALT_LLM_FRUGAL_API_KEY` | `llm.frugal.apiKey` | `""` | Frugal tier API key |
|
|
588
|
+
| `GESTALT_LLM_FRUGAL_BASE_URL` | `llm.frugal.baseURL` | `""` | Frugal tier base URL (e.g. Ollama) |
|
|
589
|
+
| `GESTALT_LLM_FRUGAL_MODEL` | `llm.frugal.model` | — | Frugal tier model |
|
|
590
|
+
| `GESTALT_LLM_STANDARD_PROVIDER` | `llm.standard.provider` | `anthropic` | Standard tier provider |
|
|
591
|
+
| `GESTALT_LLM_STANDARD_API_KEY` | `llm.standard.apiKey` | `""` | Standard tier API key |
|
|
592
|
+
| `GESTALT_LLM_STANDARD_BASE_URL` | `llm.standard.baseURL` | `""` | Standard tier base URL |
|
|
593
|
+
| `GESTALT_LLM_STANDARD_MODEL` | `llm.standard.model` | — | Standard tier model |
|
|
594
|
+
| `GESTALT_LLM_FRONTIER_PROVIDER` | `llm.frontier.provider` | `anthropic` | Frontier tier provider |
|
|
595
|
+
| `GESTALT_LLM_FRONTIER_API_KEY` | `llm.frontier.apiKey` | `""` | Frontier tier API key |
|
|
596
|
+
| `GESTALT_LLM_FRONTIER_BASE_URL` | `llm.frontier.baseURL` | `""` | Frontier tier base URL |
|
|
597
|
+
| `GESTALT_LLM_FRONTIER_MODEL` | `llm.frontier.model` | — | Frontier tier model |
|
|
548
598
|
|
|
549
599
|
---
|
|
550
600
|
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tienne/gestalt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
"serve": "tsx bin/gestalt.ts serve",
|
|
32
32
|
"bench": "tsx benchmarks/run.ts",
|
|
33
33
|
"lint": "tsc --noEmit",
|
|
34
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
35
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
34
36
|
"version:sync": "tsx scripts/sync-version.ts",
|
|
35
37
|
"postversion": "pnpm run version:sync"
|
|
36
38
|
},
|
|
@@ -58,6 +60,8 @@
|
|
|
58
60
|
"@types/better-sqlite3": "^7.6.13",
|
|
59
61
|
"@types/node": "^22.13.10",
|
|
60
62
|
"@types/node-notifier": "^8.0.5",
|
|
63
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
64
|
+
"prettier": "^3.8.1",
|
|
61
65
|
"tsx": "^4.19.3",
|
|
62
66
|
"typescript": "^5.8.2",
|
|
63
67
|
"vitest": "^3.0.9"
|