@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.
Files changed (210) hide show
  1. package/CLAUDE.md +34 -428
  2. package/README.ko.md +51 -1
  3. package/README.md +51 -1
  4. package/dist/package.json +5 -1
  5. package/dist/schemas/gestalt.schema.json +41 -3
  6. package/dist/skills/interview/SKILL.md +18 -1
  7. package/dist/src/agent/passthrough-generator.d.ts.map +1 -1
  8. package/dist/src/agent/passthrough-generator.js +3 -1
  9. package/dist/src/agent/passthrough-generator.js.map +1 -1
  10. package/dist/src/agent/role-agent-registry.d.ts.map +1 -1
  11. package/dist/src/agent/role-agent-registry.js.map +1 -1
  12. package/dist/src/agent/role-match-engine.d.ts.map +1 -1
  13. package/dist/src/agent/role-match-engine.js.map +1 -1
  14. package/dist/src/cli/commands/graph-visualize.d.ts.map +1 -1
  15. package/dist/src/cli/commands/graph-visualize.js +3 -1
  16. package/dist/src/cli/commands/graph-visualize.js.map +1 -1
  17. package/dist/src/cli/commands/init.d.ts.map +1 -1
  18. package/dist/src/cli/commands/init.js.map +1 -1
  19. package/dist/src/cli/commands/interview.d.ts.map +1 -1
  20. package/dist/src/cli/commands/interview.js +2 -2
  21. package/dist/src/cli/commands/interview.js.map +1 -1
  22. package/dist/src/cli/commands/spec.d.ts.map +1 -1
  23. package/dist/src/cli/commands/spec.js +2 -2
  24. package/dist/src/cli/commands/spec.js.map +1 -1
  25. package/dist/src/cli/commands/status.d.ts.map +1 -1
  26. package/dist/src/cli/commands/status.js.map +1 -1
  27. package/dist/src/cli/index.d.ts.map +1 -1
  28. package/dist/src/cli/index.js.map +1 -1
  29. package/dist/src/code-graph/engine.d.ts.map +1 -1
  30. package/dist/src/code-graph/engine.js +16 -13
  31. package/dist/src/code-graph/engine.js.map +1 -1
  32. package/dist/src/code-graph/plugins/go.d.ts.map +1 -1
  33. package/dist/src/code-graph/plugins/go.js +28 -4
  34. package/dist/src/code-graph/plugins/go.js.map +1 -1
  35. package/dist/src/code-graph/plugins/java.d.ts.map +1 -1
  36. package/dist/src/code-graph/plugins/java.js +63 -11
  37. package/dist/src/code-graph/plugins/java.js.map +1 -1
  38. package/dist/src/code-graph/plugins/kotlin.d.ts.map +1 -1
  39. package/dist/src/code-graph/plugins/kotlin.js +50 -7
  40. package/dist/src/code-graph/plugins/kotlin.js.map +1 -1
  41. package/dist/src/code-graph/plugins/objc.d.ts.map +1 -1
  42. package/dist/src/code-graph/plugins/objc.js +70 -12
  43. package/dist/src/code-graph/plugins/objc.js.map +1 -1
  44. package/dist/src/code-graph/plugins/python.d.ts.map +1 -1
  45. package/dist/src/code-graph/plugins/python.js +28 -4
  46. package/dist/src/code-graph/plugins/python.js.map +1 -1
  47. package/dist/src/code-graph/plugins/rust.d.ts.map +1 -1
  48. package/dist/src/code-graph/plugins/rust.js +72 -12
  49. package/dist/src/code-graph/plugins/rust.js.map +1 -1
  50. package/dist/src/code-graph/plugins/swift.d.ts.map +1 -1
  51. package/dist/src/code-graph/plugins/swift.js +62 -8
  52. package/dist/src/code-graph/plugins/swift.js.map +1 -1
  53. package/dist/src/code-graph/plugins/typescript.d.ts.map +1 -1
  54. package/dist/src/code-graph/plugins/typescript.js +2 -2
  55. package/dist/src/code-graph/plugins/typescript.js.map +1 -1
  56. package/dist/src/code-graph/providers/local-embedding.js +1 -1
  57. package/dist/src/code-graph/providers/local-embedding.js.map +1 -1
  58. package/dist/src/code-graph/storage.d.ts.map +1 -1
  59. package/dist/src/code-graph/storage.js +1 -3
  60. package/dist/src/code-graph/storage.js.map +1 -1
  61. package/dist/src/core/config.d.ts +138 -1
  62. package/dist/src/core/config.d.ts.map +1 -1
  63. package/dist/src/core/config.js +36 -3
  64. package/dist/src/core/config.js.map +1 -1
  65. package/dist/src/core/constants.d.ts.map +1 -1
  66. package/dist/src/core/constants.js +6 -6
  67. package/dist/src/core/constants.js.map +1 -1
  68. package/dist/src/core/result.d.ts.map +1 -1
  69. package/dist/src/core/result.js.map +1 -1
  70. package/dist/src/core/types.d.ts.map +1 -1
  71. package/dist/src/execute/audit-engine.d.ts.map +1 -1
  72. package/dist/src/execute/audit-engine.js +1 -3
  73. package/dist/src/execute/audit-engine.js.map +1 -1
  74. package/dist/src/execute/dag-validator.d.ts.map +1 -1
  75. package/dist/src/execute/dag-validator.js.map +1 -1
  76. package/dist/src/execute/parallel-groups.d.ts.map +1 -1
  77. package/dist/src/execute/parallel-groups.js.map +1 -1
  78. package/dist/src/execute/passthrough-engine.d.ts.map +1 -1
  79. package/dist/src/execute/passthrough-engine.js +34 -14
  80. package/dist/src/execute/passthrough-engine.js.map +1 -1
  81. package/dist/src/execute/prompts.d.ts.map +1 -1
  82. package/dist/src/execute/prompts.js +2 -4
  83. package/dist/src/execute/prompts.js.map +1 -1
  84. package/dist/src/execute/repository.d.ts.map +1 -1
  85. package/dist/src/execute/repository.js.map +1 -1
  86. package/dist/src/execute/session.d.ts.map +1 -1
  87. package/dist/src/execute/session.js +2 -1
  88. package/dist/src/execute/session.js.map +1 -1
  89. package/dist/src/execute/termination-detector.d.ts.map +1 -1
  90. package/dist/src/execute/termination-detector.js +3 -2
  91. package/dist/src/execute/termination-detector.js.map +1 -1
  92. package/dist/src/gestalt/analyzer.d.ts.map +1 -1
  93. package/dist/src/gestalt/analyzer.js +1 -2
  94. package/dist/src/gestalt/analyzer.js.map +1 -1
  95. package/dist/src/gestalt/principles.d.ts.map +1 -1
  96. package/dist/src/gestalt/principles.js +1 -3
  97. package/dist/src/gestalt/principles.js.map +1 -1
  98. package/dist/src/interview/engine.d.ts.map +1 -1
  99. package/dist/src/interview/engine.js +4 -1
  100. package/dist/src/interview/engine.js.map +1 -1
  101. package/dist/src/interview/mini-interview-engine.d.ts.map +1 -1
  102. package/dist/src/interview/mini-interview-engine.js +1 -3
  103. package/dist/src/interview/mini-interview-engine.js.map +1 -1
  104. package/dist/src/interview/passthrough-engine.d.ts.map +1 -1
  105. package/dist/src/interview/passthrough-engine.js +7 -3
  106. package/dist/src/interview/passthrough-engine.js.map +1 -1
  107. package/dist/src/interview/repository.d.ts.map +1 -1
  108. package/dist/src/interview/repository.js.map +1 -1
  109. package/dist/src/interview/resolution.js +1 -3
  110. package/dist/src/interview/resolution.js.map +1 -1
  111. package/dist/src/interview/session.d.ts.map +1 -1
  112. package/dist/src/interview/session.js.map +1 -1
  113. package/dist/src/llm/adapter.d.ts.map +1 -1
  114. package/dist/src/llm/adapter.js.map +1 -1
  115. package/dist/src/llm/factory.d.ts +24 -0
  116. package/dist/src/llm/factory.d.ts.map +1 -0
  117. package/dist/src/llm/factory.js +75 -0
  118. package/dist/src/llm/factory.js.map +1 -0
  119. package/dist/src/llm/openai-adapter.d.ts +1 -1
  120. package/dist/src/llm/openai-adapter.d.ts.map +1 -1
  121. package/dist/src/llm/openai-adapter.js +2 -2
  122. package/dist/src/llm/openai-adapter.js.map +1 -1
  123. package/dist/src/mcp/schemas.d.ts.map +1 -1
  124. package/dist/src/mcp/schemas.js +224 -88
  125. package/dist/src/mcp/schemas.js.map +1 -1
  126. package/dist/src/mcp/server.d.ts.map +1 -1
  127. package/dist/src/mcp/server.js +289 -109
  128. package/dist/src/mcp/server.js.map +1 -1
  129. package/dist/src/mcp/tools/benchmark-passthrough.js +1 -1
  130. package/dist/src/mcp/tools/benchmark-passthrough.js.map +1 -1
  131. package/dist/src/mcp/tools/create-agent-passthrough.d.ts.map +1 -1
  132. package/dist/src/mcp/tools/create-agent-passthrough.js.map +1 -1
  133. package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -1
  134. package/dist/src/mcp/tools/execute-passthrough.js +39 -25
  135. package/dist/src/mcp/tools/execute-passthrough.js.map +1 -1
  136. package/dist/src/mcp/tools/graph-visualize-passthrough.d.ts.map +1 -1
  137. package/dist/src/mcp/tools/graph-visualize-passthrough.js.map +1 -1
  138. package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -1
  139. package/dist/src/mcp/tools/interview-passthrough.js +7 -3
  140. package/dist/src/mcp/tools/interview-passthrough.js.map +1 -1
  141. package/dist/src/mcp/tools/interview.d.ts.map +1 -1
  142. package/dist/src/mcp/tools/interview.js +4 -2
  143. package/dist/src/mcp/tools/interview.js.map +1 -1
  144. package/dist/src/mcp/tools/review-passthrough.js +1 -1
  145. package/dist/src/mcp/tools/review-passthrough.js.map +1 -1
  146. package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -1
  147. package/dist/src/mcp/tools/spec-passthrough.js.map +1 -1
  148. package/dist/src/mcp/tools/spec.d.ts.map +1 -1
  149. package/dist/src/mcp/tools/spec.js.map +1 -1
  150. package/dist/src/mcp/tools/status.d.ts.map +1 -1
  151. package/dist/src/mcp/tools/status.js +1 -1
  152. package/dist/src/mcp/tools/status.js.map +1 -1
  153. package/dist/src/memory/memory-context-injector.d.ts.map +1 -1
  154. package/dist/src/memory/memory-context-injector.js +2 -6
  155. package/dist/src/memory/memory-context-injector.js.map +1 -1
  156. package/dist/src/memory/user-profile-store.d.ts.map +1 -1
  157. package/dist/src/memory/user-profile-store.js +1 -4
  158. package/dist/src/memory/user-profile-store.js.map +1 -1
  159. package/dist/src/recording/agg-converter.d.ts.map +1 -1
  160. package/dist/src/recording/agg-converter.js.map +1 -1
  161. package/dist/src/recording/agg-installer.d.ts.map +1 -1
  162. package/dist/src/recording/agg-installer.js.map +1 -1
  163. package/dist/src/recording/asciinema-installer.d.ts.map +1 -1
  164. package/dist/src/recording/asciinema-installer.js.map +1 -1
  165. package/dist/src/recording/asciinema-recorder.d.ts.map +1 -1
  166. package/dist/src/recording/asciinema-recorder.js.map +1 -1
  167. package/dist/src/recording/cast-generator.d.ts.map +1 -1
  168. package/dist/src/recording/cast-generator.js +38 -13
  169. package/dist/src/recording/cast-generator.js.map +1 -1
  170. package/dist/src/recording/filename-generator.d.ts.map +1 -1
  171. package/dist/src/recording/filename-generator.js +2 -2
  172. package/dist/src/recording/filename-generator.js.map +1 -1
  173. package/dist/src/recording/recording-orchestrator.d.ts.map +1 -1
  174. package/dist/src/recording/recording-orchestrator.js.map +1 -1
  175. package/dist/src/registry/base-registry.d.ts.map +1 -1
  176. package/dist/src/registry/base-registry.js.map +1 -1
  177. package/dist/src/resilience/lateral.d.ts.map +1 -1
  178. package/dist/src/resilience/lateral.js +6 -1
  179. package/dist/src/resilience/lateral.js.map +1 -1
  180. package/dist/src/resilience/prompts.d.ts.map +1 -1
  181. package/dist/src/resilience/prompts.js.map +1 -1
  182. package/dist/src/review/agent-matcher.d.ts.map +1 -1
  183. package/dist/src/review/agent-matcher.js.map +1 -1
  184. package/dist/src/review/context-collector.d.ts.map +1 -1
  185. package/dist/src/review/context-collector.js.map +1 -1
  186. package/dist/src/review/passthrough-engine.d.ts.map +1 -1
  187. package/dist/src/review/passthrough-engine.js +1 -3
  188. package/dist/src/review/passthrough-engine.js.map +1 -1
  189. package/dist/src/review/report-generator.d.ts.map +1 -1
  190. package/dist/src/review/report-generator.js.map +1 -1
  191. package/dist/src/scripts/postinstall.js +3 -1
  192. package/dist/src/scripts/postinstall.js.map +1 -1
  193. package/dist/src/spec/generator.d.ts.map +1 -1
  194. package/dist/src/spec/generator.js.map +1 -1
  195. package/dist/src/spec/passthrough-generator.d.ts.map +1 -1
  196. package/dist/src/spec/passthrough-generator.js.map +1 -1
  197. package/dist/src/spec/schema.js +1 -1
  198. package/dist/src/spec/schema.js.map +1 -1
  199. package/dist/src/spec/text-based-spec-generator.d.ts.map +1 -1
  200. package/dist/src/spec/text-based-spec-generator.js +3 -1
  201. package/dist/src/spec/text-based-spec-generator.js.map +1 -1
  202. package/dist/src/tui/hooks/event-store-reader.d.ts.map +1 -1
  203. package/dist/src/tui/hooks/event-store-reader.js +1 -3
  204. package/dist/src/tui/hooks/event-store-reader.js.map +1 -1
  205. package/dist/src/tui/hooks/useEventStorePoller.d.ts.map +1 -1
  206. package/dist/src/tui/hooks/useEventStorePoller.js +1 -3
  207. package/dist/src/tui/hooks/useEventStorePoller.js.map +1 -1
  208. package/package.json +5 -1
  209. package/schemas/gestalt.schema.json +41 -3
  210. 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**: 게슈탈트 5원리를 실행 전략으로 사용, Spec→ExecutionPlan 변환 (Figure-Ground→Closure→Proximity→Continuity)
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 Claude Code AI 에이전트와 통합
13
- - **Skill System**: SKILL.md 기반 확장, chokidar hot-reload 지원. 각 스킬(`/interview`, `/spec`, `/execute`)은 실행 중 Claude Code Task 패널에 진행 상태를 `TaskCreate`/`TaskUpdate`로 실시간 표시 (공통 진행 패널)
14
- - **Code Knowledge Graph**: 코드베이스 정적 분석 → 의존성 그래프화 → Blast-Radius 영향 파일 추림. Execute 파이프라인 태스크 실행 시 `suggestedFiles`로 자동 컨텍스트 주입해 불필요한 파일 읽기를 줄임
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 # Run all tests (vitest)
24
- pnpm run serve # Start MCP server
25
- pnpm tsx bin/gestalt.ts interview "topic" # Interactive interview
26
- pnpm tsx bin/gestalt.ts spec <session-id> # Generate spec
27
- pnpm tsx bin/gestalt.ts status # Check sessions
28
- pnpm tsx bin/gestalt.ts setup # Generate gestalt.json config
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? (optional), text? (optional), force?, spec? (passthrough)
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] — 인터뷰 기반 커스텀 Role Agent 생성
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
- ## MCP Passthrough Mode
100
-
101
- API 키(`ANTHROPIC_API_KEY`) 없이 MCP 서버 실행 시 자동 활성화. LLM 호출을 서버가 하지 않고, caller(Claude Code 등)에게 위임한다.
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
- // 그래프 빌드 (최초 또는 full rebuild)
395
- ges_code_graph({ action: "build", repoRoot: "<절대경로>" })
396
- { nodesBuilt, edgesBuilt, timeTakenMs, installedHook }
397
-
398
- // Blast-Radius 분석 (커밋 기준 영향범위)
399
- ges_code_graph({ action: "blast_radius", repoRoot: "<경로>", base?: "HEAD~1", changedFiles?: [...], maxDepth?: 2 })
400
- { changedFiles, impactedFiles, riskScore, summary }
401
-
402
- // Diff-Radius 분석 (미커밋 변경 기준 영향범위)
403
- ges_code_graph({ action: "diff_radius", repoRoot: "<경로>", diffMode?: "staged"|"unstaged"|"all", maxDepth?: 2 })
404
- { changedFiles, impactedFiles, riskScore, summary }
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` 사용 금지 → stderr(`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
- - Spec 생성 실패 최대 3회 재시도
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.12.2",
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"