@tienne/gestalt 0.7.0 → 0.9.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 (105) hide show
  1. package/CLAUDE.md +14 -3
  2. package/README.ko.md +154 -30
  3. package/README.md +134 -15
  4. package/dist/package.json +1 -1
  5. package/dist/role-agents/technical-writer/AGENT.md +39 -3
  6. package/dist/skills/execute/SKILL.md +66 -1
  7. package/dist/skills/interview/SKILL.md +36 -1
  8. package/dist/skills/spec/SKILL.md +33 -1
  9. package/dist/src/core/types.d.ts +85 -0
  10. package/dist/src/core/types.d.ts.map +1 -1
  11. package/dist/src/execute/audit-engine.d.ts +20 -0
  12. package/dist/src/execute/audit-engine.d.ts.map +1 -0
  13. package/dist/src/execute/audit-engine.js +49 -0
  14. package/dist/src/execute/audit-engine.js.map +1 -0
  15. package/dist/src/execute/parallel-groups.d.ts +9 -0
  16. package/dist/src/execute/parallel-groups.d.ts.map +1 -0
  17. package/dist/src/execute/parallel-groups.js +39 -0
  18. package/dist/src/execute/parallel-groups.js.map +1 -0
  19. package/dist/src/execute/passthrough-engine.d.ts +2 -0
  20. package/dist/src/execute/passthrough-engine.d.ts.map +1 -1
  21. package/dist/src/execute/passthrough-engine.js +6 -0
  22. package/dist/src/execute/passthrough-engine.js.map +1 -1
  23. package/dist/src/execute/repository.d.ts.map +1 -1
  24. package/dist/src/execute/repository.js +3 -0
  25. package/dist/src/execute/repository.js.map +1 -1
  26. package/dist/src/execute/rule-writer.d.ts +15 -0
  27. package/dist/src/execute/rule-writer.d.ts.map +1 -0
  28. package/dist/src/execute/rule-writer.js +57 -0
  29. package/dist/src/execute/rule-writer.js.map +1 -0
  30. package/dist/src/execute/session.d.ts +3 -1
  31. package/dist/src/execute/session.d.ts.map +1 -1
  32. package/dist/src/execute/session.js +31 -0
  33. package/dist/src/execute/session.js.map +1 -1
  34. package/dist/src/interview/context-compressor.d.ts +17 -0
  35. package/dist/src/interview/context-compressor.d.ts.map +1 -0
  36. package/dist/src/interview/context-compressor.js +40 -0
  37. package/dist/src/interview/context-compressor.js.map +1 -0
  38. package/dist/src/interview/mini-interview-engine.d.ts +33 -0
  39. package/dist/src/interview/mini-interview-engine.d.ts.map +1 -0
  40. package/dist/src/interview/mini-interview-engine.js +103 -0
  41. package/dist/src/interview/mini-interview-engine.js.map +1 -0
  42. package/dist/src/interview/passthrough-engine.d.ts +7 -0
  43. package/dist/src/interview/passthrough-engine.d.ts.map +1 -1
  44. package/dist/src/interview/passthrough-engine.js +15 -1
  45. package/dist/src/interview/passthrough-engine.js.map +1 -1
  46. package/dist/src/interview/session.d.ts +2 -1
  47. package/dist/src/interview/session.d.ts.map +1 -1
  48. package/dist/src/interview/session.js +5 -0
  49. package/dist/src/interview/session.js.map +1 -1
  50. package/dist/src/mcp/schemas.d.ts +78 -9
  51. package/dist/src/mcp/schemas.d.ts.map +1 -1
  52. package/dist/src/mcp/schemas.js +25 -2
  53. package/dist/src/mcp/schemas.js.map +1 -1
  54. package/dist/src/mcp/server.d.ts.map +1 -1
  55. package/dist/src/mcp/server.js +5 -2
  56. package/dist/src/mcp/server.js.map +1 -1
  57. package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -1
  58. package/dist/src/mcp/tools/execute-passthrough.js +260 -4
  59. package/dist/src/mcp/tools/execute-passthrough.js.map +1 -1
  60. package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -1
  61. package/dist/src/mcp/tools/interview-passthrough.js +45 -2
  62. package/dist/src/mcp/tools/interview-passthrough.js.map +1 -1
  63. package/dist/src/mcp/tools/interview.d.ts.map +1 -1
  64. package/dist/src/mcp/tools/interview.js +8 -0
  65. package/dist/src/mcp/tools/interview.js.map +1 -1
  66. package/dist/src/mcp/tools/review-passthrough.d.ts.map +1 -1
  67. package/dist/src/mcp/tools/review-passthrough.js +14 -0
  68. package/dist/src/mcp/tools/review-passthrough.js.map +1 -1
  69. package/dist/src/mcp/tools/spec-passthrough.d.ts +2 -1
  70. package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -1
  71. package/dist/src/mcp/tools/spec-passthrough.js +54 -3
  72. package/dist/src/mcp/tools/spec-passthrough.js.map +1 -1
  73. package/dist/src/mcp/tools/spec.d.ts.map +1 -1
  74. package/dist/src/mcp/tools/spec.js +2 -0
  75. package/dist/src/mcp/tools/spec.js.map +1 -1
  76. package/dist/src/memory/memory-context-injector.d.ts +26 -0
  77. package/dist/src/memory/memory-context-injector.d.ts.map +1 -0
  78. package/dist/src/memory/memory-context-injector.js +67 -0
  79. package/dist/src/memory/memory-context-injector.js.map +1 -0
  80. package/dist/src/memory/project-memory-store.d.ts +14 -0
  81. package/dist/src/memory/project-memory-store.d.ts.map +1 -0
  82. package/dist/src/memory/project-memory-store.js +105 -0
  83. package/dist/src/memory/project-memory-store.js.map +1 -0
  84. package/dist/src/memory/user-profile-store.d.ts +13 -0
  85. package/dist/src/memory/user-profile-store.d.ts.map +1 -0
  86. package/dist/src/memory/user-profile-store.js +89 -0
  87. package/dist/src/memory/user-profile-store.js.map +1 -0
  88. package/dist/src/spec/passthrough-generator.d.ts +2 -0
  89. package/dist/src/spec/passthrough-generator.d.ts.map +1 -1
  90. package/dist/src/spec/passthrough-generator.js +34 -0
  91. package/dist/src/spec/passthrough-generator.js.map +1 -1
  92. package/dist/src/spec/templates.d.ts +12 -0
  93. package/dist/src/spec/templates.d.ts.map +1 -0
  94. package/dist/src/spec/templates.js +103 -0
  95. package/dist/src/spec/templates.js.map +1 -0
  96. package/dist/src/spec/text-based-spec-generator.d.ts +15 -0
  97. package/dist/src/spec/text-based-spec-generator.d.ts.map +1 -0
  98. package/dist/src/spec/text-based-spec-generator.js +63 -0
  99. package/dist/src/spec/text-based-spec-generator.js.map +1 -0
  100. package/package.json +1 -1
  101. package/role-agents/technical-writer/AGENT.md +39 -3
  102. package/skills/execute/SKILL.md +66 -1
  103. package/skills/interview/SKILL.md +36 -1
  104. package/skills/spec/SKILL.md +33 -1
  105. package/README.backup.md +0 -442
@@ -0,0 +1,89 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ const PROFILE_DIR = '.gestalt';
5
+ const PROFILE_FILENAME = 'profile.json';
6
+ function getProfilePath() {
7
+ return join(homedir(), PROFILE_DIR, PROFILE_FILENAME);
8
+ }
9
+ function createEmptyProfile() {
10
+ const now = new Date().toISOString();
11
+ return {
12
+ crossRepoPatterns: [],
13
+ personalPreferences: {},
14
+ createdAt: now,
15
+ updatedAt: now,
16
+ };
17
+ }
18
+ export class UserProfileStore {
19
+ profilePath;
20
+ constructor(profilePath) {
21
+ this.profilePath = profilePath ?? getProfilePath();
22
+ }
23
+ read() {
24
+ if (!existsSync(this.profilePath)) {
25
+ return createEmptyProfile();
26
+ }
27
+ try {
28
+ const raw = readFileSync(this.profilePath, 'utf-8');
29
+ return JSON.parse(raw);
30
+ }
31
+ catch {
32
+ return createEmptyProfile();
33
+ }
34
+ }
35
+ write(profile) {
36
+ const dir = dirname(this.profilePath);
37
+ if (!existsSync(dir)) {
38
+ mkdirSync(dir, { recursive: true });
39
+ }
40
+ profile.updatedAt = new Date().toISOString();
41
+ writeFileSync(this.profilePath, JSON.stringify(profile, null, 2), 'utf-8');
42
+ }
43
+ setPreference(key, value) {
44
+ const profile = this.read();
45
+ profile.personalPreferences[key] = value;
46
+ this.write(profile);
47
+ return profile;
48
+ }
49
+ addCrossRepoPattern(pattern) {
50
+ const profile = this.read();
51
+ if (!profile.crossRepoPatterns.includes(pattern)) {
52
+ profile.crossRepoPatterns.push(pattern);
53
+ }
54
+ this.write(profile);
55
+ return profile;
56
+ }
57
+ setPreferredModel(model) {
58
+ const profile = this.read();
59
+ profile.preferredModel = model;
60
+ this.write(profile);
61
+ return profile;
62
+ }
63
+ setUserId(userId) {
64
+ const profile = this.read();
65
+ profile.userId = userId;
66
+ this.write(profile);
67
+ return profile;
68
+ }
69
+ merge(partial) {
70
+ const profile = this.read();
71
+ const merged = {
72
+ ...profile,
73
+ ...partial,
74
+ crossRepoPatterns: [
75
+ ...new Set([
76
+ ...profile.crossRepoPatterns,
77
+ ...(partial.crossRepoPatterns ?? []),
78
+ ]),
79
+ ],
80
+ personalPreferences: {
81
+ ...profile.personalPreferences,
82
+ ...(partial.personalPreferences ?? {}),
83
+ },
84
+ };
85
+ this.write(merged);
86
+ return merged;
87
+ }
88
+ }
89
+ //# sourceMappingURL=user-profile-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-profile-store.js","sourceRoot":"","sources":["../../../src/memory/user-profile-store.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { AmbiguityThresholdError, SpecGenerationError } from '../core/errors.js'
3
3
  import { type Result } from '../core/result.js';
4
4
  import { EventStore } from '../events/store.js';
5
5
  import type { AgentRegistry } from '../agent/registry.js';
6
+ export declare const TEXT_INPUT_SESSION_ID = "text-input";
6
7
  export interface SpecContext {
7
8
  systemPrompt: string;
8
9
  specPrompt: string;
@@ -30,5 +31,6 @@ export declare class PassthroughSpecGenerator {
30
31
  constructor(eventStore: EventStore, agentRegistry?: AgentRegistry);
31
32
  buildSpecContext(session: InterviewSession): SpecContext;
32
33
  validateAndStore(session: InterviewSession, externalSpec: ExternalSpec, force?: boolean): Result<Spec, SpecGenerationError | AmbiguityThresholdError>;
34
+ validateAndStoreFromText(externalSpec: ExternalSpec): Result<Spec, SpecGenerationError>;
33
35
  }
34
36
  //# sourceMappingURL=passthrough-generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"passthrough-generator.d.ts","sourceRoot":"","sources":["../../../src/spec/passthrough-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAkB,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/F,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAAC,SAAS,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAC9D,eAAe,EAAE,OAAO,EAAE,CAAC;CAC5B;AAID,qBAAa,wBAAwB;IAGvB,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAElB,UAAU,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,aAAa;IAIzE,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW;IA4BxD,gBAAgB,CACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,YAAY,EAC1B,KAAK,UAAQ,GACZ,MAAM,CAAC,IAAI,EAAE,mBAAmB,GAAG,uBAAuB,CAAC;CA6D/D"}
1
+ {"version":3,"file":"passthrough-generator.d.ts","sourceRoot":"","sources":["../../../src/spec/passthrough-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAkB,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAIlD,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/F,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAAC,SAAS,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAC9D,eAAe,EAAE,OAAO,EAAE,CAAC;CAC5B;AAID,qBAAa,wBAAwB;IAGvB,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAElB,UAAU,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,aAAa;IAIzE,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW;IA4BxD,gBAAgB,CACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,YAAY,EAC1B,KAAK,UAAQ,GACZ,MAAM,CAAC,IAAI,EAAE,mBAAmB,GAAG,uBAAuB,CAAC;IA8D9D,wBAAwB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,EAAE,mBAAmB,CAAC;CAgDxF"}
@@ -6,6 +6,7 @@ import { specSchema } from './schema.js';
6
6
  import { EventType } from '../events/types.js';
7
7
  import { INTERVIEW_SYSTEM_PROMPT, buildSpecPrompt } from '../llm/prompts.js';
8
8
  import { mergeSystemPrompt, getActiveAgentNames } from '../agent/prompt-resolver.js';
9
+ export const TEXT_INPUT_SESSION_ID = 'text-input';
9
10
  // ─── Generator ──────────────────────────────────────────────────
10
11
  export class PassthroughSpecGenerator {
11
12
  eventStore;
@@ -82,5 +83,38 @@ export class PassthroughSpecGenerator {
82
83
  return err(new SpecGenerationError(`Failed to validate spec: ${e instanceof Error ? e.message : String(e)}`));
83
84
  }
84
85
  }
86
+ validateAndStoreFromText(externalSpec) {
87
+ try {
88
+ const spec = {
89
+ version: '1.0.0',
90
+ goal: externalSpec.goal,
91
+ constraints: externalSpec.constraints,
92
+ acceptanceCriteria: externalSpec.acceptanceCriteria,
93
+ ontologySchema: externalSpec.ontologySchema,
94
+ gestaltAnalysis: externalSpec.gestaltAnalysis,
95
+ metadata: {
96
+ specId: randomUUID(),
97
+ interviewSessionId: TEXT_INPUT_SESSION_ID,
98
+ ambiguityScore: 0,
99
+ generatedAt: new Date().toISOString(),
100
+ },
101
+ };
102
+ const validation = specSchema.safeParse(spec);
103
+ if (!validation.success) {
104
+ return err(new SpecGenerationError(`Spec validation failed: ${validation.error.message}`));
105
+ }
106
+ this.eventStore.append('spec', spec.metadata.specId, EventType.SPEC_GENERATED, {
107
+ sessionId: TEXT_INPUT_SESSION_ID,
108
+ goal: spec.goal,
109
+ constraintCount: spec.constraints.length,
110
+ criteriaCount: spec.acceptanceCriteria.length,
111
+ source: 'text',
112
+ });
113
+ return ok(spec);
114
+ }
115
+ catch (e) {
116
+ return err(new SpecGenerationError(`Failed to validate spec: ${e instanceof Error ? e.message : String(e)}`));
117
+ }
118
+ }
85
119
  }
86
120
  //# sourceMappingURL=passthrough-generator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"passthrough-generator.js","sourceRoot":"","sources":["../../../src/spec/passthrough-generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"passthrough-generator.js","sourceRoot":"","sources":["../../../src/spec/passthrough-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { SpecTemplate } from '../core/types.js';
2
+ export declare class SpecTemplateRegistry {
3
+ get(id: string): SpecTemplate | undefined;
4
+ list(): SpecTemplate[];
5
+ has(id: string): boolean;
6
+ /**
7
+ * 템플릿을 기반으로 specPrompt를 위한 추가 컨텍스트 문자열 생성.
8
+ * TextBasedSpecGenerator.buildSpecContext()에서 주입된다.
9
+ */
10
+ buildTemplateContext(id: string): string | null;
11
+ }
12
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/spec/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA4ErD,qBAAa,oBAAoB;IAC/B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIzC,IAAI,IAAI,YAAY,EAAE;IAItB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAoBhD"}
@@ -0,0 +1,103 @@
1
+ // ─── Built-in Templates ──────────────────────────────────────────
2
+ const REST_API_TEMPLATE = {
3
+ id: 'rest-api',
4
+ name: 'REST API Backend',
5
+ description: 'RESTful API 백엔드 서비스 — 인증, CRUD, 에러 핸들링 포함',
6
+ baseConstraints: [
7
+ 'RESTful API 설계 원칙 준수 (HTTP 메서드, 상태 코드)',
8
+ 'JWT 기반 인증/인가',
9
+ '입력 유효성 검사 및 에러 응답 표준화',
10
+ 'API 버전 관리 (/api/v1/...)',
11
+ '환경변수 기반 설정 관리 (비밀값 하드코딩 금지)',
12
+ ],
13
+ baseAcceptanceCriteria: [
14
+ 'GET /health 엔드포인트가 200 OK와 서버 상태를 반환한다',
15
+ 'POST /auth/login은 유효한 자격증명으로 JWT 토큰을 반환한다',
16
+ '인증이 필요한 엔드포인트는 유효하지 않은 토큰으로 401을 반환한다',
17
+ '잘못된 요청에 대해 표준 에러 형식(code, message)을 반환한다',
18
+ '모든 엔드포인트에 요청/응답 로깅이 동작한다',
19
+ ],
20
+ baseOntologyEntities: ['User', 'AuthToken', 'Resource', 'ApiResponse'],
21
+ };
22
+ const REACT_DASHBOARD_TEMPLATE = {
23
+ id: 'react-dashboard',
24
+ name: 'React Dashboard',
25
+ description: 'React 기반 관리자 대시보드 — 차트, 테이블, 필터링 포함',
26
+ baseConstraints: [
27
+ 'React 18+ 함수형 컴포넌트 + TypeScript',
28
+ '상태 관리: 서버 상태는 React Query, 클라이언트 상태는 Zustand 또는 Context',
29
+ '반응형 레이아웃 (모바일/태블릿/데스크탑)',
30
+ '접근성 (WCAG 2.1 AA) 준수',
31
+ '컴포넌트 단위 Storybook 문서화',
32
+ ],
33
+ baseAcceptanceCriteria: [
34
+ '대시보드 메인 페이지가 핵심 KPI 카드를 표시한다',
35
+ '차트/그래프가 데이터 로딩 중 스켈레톤 UI를 보여준다',
36
+ '테이블에 정렬, 필터링, 페이지네이션이 동작한다',
37
+ '필터 조건이 URL 쿼리 파라미터에 반영되어 공유 가능하다',
38
+ '다크 모드 전환이 즉시 적용된다',
39
+ ],
40
+ baseOntologyEntities: ['Dashboard', 'Chart', 'DataTable', 'Filter', 'UserPreference'],
41
+ };
42
+ const CLI_TOOL_TEMPLATE = {
43
+ id: 'cli-tool',
44
+ name: 'CLI Tool',
45
+ description: 'Node.js CLI 도구 — 명령어, 옵션, 대화형 프롬프트 포함',
46
+ baseConstraints: [
47
+ 'Node.js 20+ ESM 모듈',
48
+ 'commander.js 기반 명령어 파싱',
49
+ '대화형 프롬프트: @inquirer/prompts',
50
+ 'JSON/YAML 설정 파일 지원 (cosmiconfig 또는 동등한 라이브러리)',
51
+ '0-exit-code: 성공, 1-exit-code: 실패 (UNIX 표준)',
52
+ 'stdout: 결과 데이터만, stderr: 로그/에러',
53
+ ],
54
+ baseAcceptanceCriteria: [
55
+ '`tool --help`가 모든 명령어와 옵션을 출력한다',
56
+ '`tool --version`이 package.json 버전을 출력한다',
57
+ '잘못된 옵션 사용 시 명확한 에러 메시지와 exit code 1을 반환한다',
58
+ '`--quiet` 플래그로 진행 메시지를 숨기고 결과만 출력한다',
59
+ '설정 파일이 없을 때 기본값으로 동작한다',
60
+ ],
61
+ baseOntologyEntities: ['Command', 'Option', 'Config', 'Output'],
62
+ };
63
+ // ─── Registry ────────────────────────────────────────────────────
64
+ const TEMPLATES = new Map([
65
+ [REST_API_TEMPLATE.id, REST_API_TEMPLATE],
66
+ [REACT_DASHBOARD_TEMPLATE.id, REACT_DASHBOARD_TEMPLATE],
67
+ [CLI_TOOL_TEMPLATE.id, CLI_TOOL_TEMPLATE],
68
+ ]);
69
+ export class SpecTemplateRegistry {
70
+ get(id) {
71
+ return TEMPLATES.get(id);
72
+ }
73
+ list() {
74
+ return [...TEMPLATES.values()];
75
+ }
76
+ has(id) {
77
+ return TEMPLATES.has(id);
78
+ }
79
+ /**
80
+ * 템플릿을 기반으로 specPrompt를 위한 추가 컨텍스트 문자열 생성.
81
+ * TextBasedSpecGenerator.buildSpecContext()에서 주입된다.
82
+ */
83
+ buildTemplateContext(id) {
84
+ const template = this.get(id);
85
+ if (!template)
86
+ return null;
87
+ const lines = [
88
+ `## Template: ${template.name}`,
89
+ `${template.description}`,
90
+ '',
91
+ '### Template Base Constraints (merge into spec constraints)',
92
+ ...template.baseConstraints.map((c) => `- ${c}`),
93
+ '',
94
+ '### Template Base Acceptance Criteria (merge into spec ACs)',
95
+ ...template.baseAcceptanceCriteria.map((ac) => `- ${ac}`),
96
+ '',
97
+ '### Suggested Ontology Entities',
98
+ ...template.baseOntologyEntities.map((e) => `- ${e}`),
99
+ ];
100
+ return lines.join('\n');
101
+ }
102
+ }
103
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/spec/templates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { AgentRegistry } from '../agent/registry.js';
2
+ import type { ProjectMemory } from '../core/types.js';
3
+ export interface TextSpecContext {
4
+ systemPrompt: string;
5
+ specPrompt: string;
6
+ memoryContext?: string;
7
+ templateId?: string;
8
+ }
9
+ export declare class TextBasedSpecGenerator {
10
+ private agentRegistry?;
11
+ private templateRegistry;
12
+ constructor(agentRegistry?: AgentRegistry);
13
+ buildSpecContext(text: string, memory?: ProjectMemory, templateId?: string): TextSpecContext;
14
+ }
15
+ //# sourceMappingURL=text-based-spec-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-based-spec-generator.d.ts","sourceRoot":"","sources":["../../../src/spec/text-based-spec-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA+CD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,gBAAgB,CAAuB;gBAEnC,aAAa,CAAC,EAAE,aAAa;IAKzC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,eAAe;CAc7F"}
@@ -0,0 +1,63 @@
1
+ import { INTERVIEW_SYSTEM_PROMPT } from '../llm/prompts.js';
2
+ import { mergeSystemPrompt } from '../agent/prompt-resolver.js';
3
+ import { SpecTemplateRegistry } from './templates.js';
4
+ function buildMemorySection(memory) {
5
+ if (memory.specHistory.length === 0 && memory.architectureDecisions.length === 0) {
6
+ return '';
7
+ }
8
+ const lines = ['## Prior Project Context (from .gestalt/memory.json)'];
9
+ if (memory.specHistory.length > 0) {
10
+ lines.push('\n### Previous Specs');
11
+ for (const entry of memory.specHistory.slice(-5)) {
12
+ lines.push(`- [${entry.createdAt.slice(0, 10)}] ${entry.goal} (specId: ${entry.specId})`);
13
+ }
14
+ }
15
+ if (memory.architectureDecisions.length > 0) {
16
+ lines.push('\n### Architecture Decisions');
17
+ for (const decision of memory.architectureDecisions) {
18
+ lines.push(`- ${decision}`);
19
+ }
20
+ }
21
+ return lines.join('\n');
22
+ }
23
+ function buildTextSpecPrompt(text, memoryContext, templateContext) {
24
+ return `Generate a complete project specification (Spec) from the following description.
25
+ ${memoryContext ? `\n${memoryContext}\n` : ''}${templateContext ? `\n${templateContext}\n` : ''}
26
+ ## Description
27
+ ${text}
28
+
29
+ Respond with ONLY a JSON object:
30
+ {
31
+ "goal": "Clear, concise project goal",
32
+ "constraints": ["constraint 1", "constraint 2"],
33
+ "acceptanceCriteria": ["criterion 1", "criterion 2"],
34
+ "ontologySchema": {
35
+ "entities": [{"name": "EntityName", "description": "what it is", "attributes": ["attr1"]}],
36
+ "relations": [{"from": "Entity1", "to": "Entity2", "type": "relationship_type"}]
37
+ },
38
+ "gestaltAnalysis": [
39
+ {"principle": "closure|proximity|similarity|figure_ground|continuity", "finding": "what was inferred", "confidence": 0.0-1.0}
40
+ ]
41
+ }`;
42
+ }
43
+ export class TextBasedSpecGenerator {
44
+ agentRegistry;
45
+ templateRegistry;
46
+ constructor(agentRegistry) {
47
+ this.agentRegistry = agentRegistry;
48
+ this.templateRegistry = new SpecTemplateRegistry();
49
+ }
50
+ buildSpecContext(text, memory, templateId) {
51
+ const systemPrompt = mergeSystemPrompt(INTERVIEW_SYSTEM_PROMPT, this.agentRegistry, 'spec');
52
+ const memoryContext = memory ? buildMemorySection(memory) : undefined;
53
+ const templateContext = templateId ? this.templateRegistry.buildTemplateContext(templateId) ?? undefined : undefined;
54
+ const specPrompt = buildTextSpecPrompt(text, memoryContext || undefined, templateContext);
55
+ return {
56
+ systemPrompt,
57
+ specPrompt,
58
+ memoryContext: memoryContext || undefined,
59
+ templateId: templateId || undefined,
60
+ };
61
+ }
62
+ }
63
+ //# sourceMappingURL=text-based-spec-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-based-spec-generator.js","sourceRoot":"","sources":["../../../src/spec/text-based-spec-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAStD,SAAS,kBAAkB,CAAC,MAAqB;IAC/C,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,qBAAqB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,CAAC,sDAAsD,CAAC,CAAC;IAEjF,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,aAAa,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY,EAAE,aAAsB,EAAE,eAAwB;IACzF,OAAO;EACP,aAAa,CAAC,CAAC,CAAC,KAAK,aAAa,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,KAAK,eAAe,IAAI,CAAC,CAAC,CAAC,EAAE;;EAE7F,IAAI;;;;;;;;;;;;;;EAcJ,CAAC;AACH,CAAC;AAED,MAAM,OAAO,sBAAsB;IACzB,aAAa,CAAiB;IAC9B,gBAAgB,CAAuB;IAE/C,YAAY,aAA6B;QACvC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAG,IAAI,oBAAoB,EAAE,CAAC;IACrD,CAAC;IAED,gBAAgB,CAAC,IAAY,EAAE,MAAsB,EAAE,UAAmB;QACxE,MAAM,YAAY,GAAG,iBAAiB,CAAC,uBAAuB,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAE5F,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACrH,MAAM,UAAU,GAAG,mBAAmB,CAAC,IAAI,EAAE,aAAa,IAAI,SAAS,EAAE,eAAe,CAAC,CAAC;QAE1F,OAAO;YACL,YAAY;YACZ,UAAU;YACV,aAAa,EAAE,aAAa,IAAI,SAAS;YACzC,UAAU,EAAE,UAAU,IAAI,SAAS;SACpC,CAAC;IACJ,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tienne/gestalt",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -32,8 +32,20 @@ When writing Korean developer documentation, follow these conventions observed i
32
32
  **Formatting Patterns**
33
33
  - Bold key terms on first use: **소모성 아이템**, **비소모성 아이템**
34
34
  - Use bullet lists for features, options, and constraints — keep each item concise
35
+ - Use numbered lists when sequence matters — installation steps, API call order, migration procedures
36
+ — Don't: bullet a 3-step setup where step 2 depends on step 1
37
+ — Do: number any list where "do these in order" is part of the instruction
35
38
  - Separate distinct concepts with `---` horizontal rules
36
- - End conceptual sections with a "참고해 주세요" callout for edge cases or policy notes
39
+ - Use callout blocks to signal importance choose the type based on consequence:
40
+ - 💡 **Tip**: better approach, shortcut, optional improvement
41
+ - 📝 **Note / 참고**: extra context, exception cases, policy notes — use at the end of conceptual sections
42
+ - ⚠️ **Warning / 주의**: incorrect usage causes problems (wrong output, wasted time)
43
+ - 🔴 **Danger / 경고**: data loss, security risk, service outage — reader must not skip this
44
+ — Don't use Note for Danger: "참고로 이 명령어는 데이터를 삭제해요" understates the risk
45
+ - Write descriptive link text — destination should be clear from the link text alone
46
+ — Don't: "자세한 내용은 [여기](...)를 참고하세요."
47
+ — Do: "자세한 내용은 [설치 가이드](...)를 참고하세요."
48
+ — Don't: "See [this](url)." → Do: "See [API authentication guide](url)."
37
49
 
38
50
  **Content Principles**
39
51
  - Lead with business value or user benefit, follow with technical detail
@@ -46,6 +58,26 @@ When writing Korean developer documentation, follow these conventions observed i
46
58
  - Avoid listing terms inline in introductions if they are covered in a dedicated section below — redundant inline lists interrupt flow without adding value
47
59
 
48
60
  **Korean Sentence Writing**
61
+
62
+ **핵심 원칙: 영어로 생각하고 번역하지 말 것**
63
+ 한국어로 직접 작성한다. "dependency-based execution planning"을 머릿속에서 먼저 영어로 구성한 뒤 번역하면 번역체가 된다.
64
+
65
+ - ❌ 의존성 기반 실행 계획 수립 → ✅ 의존성에 따라 실행 순서를 정해요
66
+ - ❌ 스태그네이션 감지 메커니즘이 트리거됩니다 → ✅ 답보 상태를 감지하면 자동으로 분기해요
67
+ - ❌ 스포닝 → ✅ 하위 에이전트 생성
68
+ - ❌ 소급 검토 컨텍스트 → ✅ 회고 컨텍스트
69
+ - ❌ 임의 태스크에 적용 가능합니다 → ✅ 모든 태스크에 적용할 수 있어요
70
+ - ❌ 단락(short-circuit) 처리 → ✅ 조기 종료 처리
71
+ - ❌ 수익 체감 패턴 → ✅ 효과 감소 패턴
72
+
73
+ **기술 용어 3단계 처리**
74
+
75
+ | 단계 | 사용 기준 | 예시 |
76
+ |------|-----------|------|
77
+ | 영어 그대로 | 한국 개발자들이 영어로 통용하는 용어 | API, CLI, JSON, Git, PR, LLM, DAG |
78
+ | 한국어 + 영어 병기 (첫 등장) | 덜 일반적인 전문 용어의 첫 사용 | 이벤트 소싱(Event Sourcing), 단락 회로 실행(Short-circuit Evaluation) |
79
+ | 한국어만 | 자연스러운 한국어 표현이 있는 경우 | 버전 관리 (버저닝 ❌), 배포 (디플로이먼트 ❌) |
80
+
49
81
  - Reader is the subject: write so the developer is the actor — use active constructions
50
82
  — Don't: "설정이 완료되어야 합니다." → Do: "설정을 완료하세요."
51
83
  — Don't: "이 라이브러리는 초기화를 수행해요." → Do: "이 명령어로 초기화하세요."
@@ -206,7 +238,11 @@ When writing documentation, produce:
206
238
  - Callout blocks for important notes, warnings, or tips
207
239
 
208
240
  When reviewing existing documentation, provide:
209
- - Specific issues by section (clarity / structure / completeness / consistency)
210
- - Rewrite suggestions for unclear passages
241
+ - Issues classified by severity:
242
+ - **Blocker**: reader can misunderstand, follow wrong steps, or miss a critical risk — must fix before publish
243
+ - **Fix**: clarity, consistency, or structural problem — fix when possible
244
+ - **Suggest**: improvement idea — optional, at author's discretion
245
+ - Specific location (section name or quoted passage) for each issue
246
+ - Rewrite suggestions for all Blocker and Fix items
211
247
  - Missing content checklist
212
248
  - Overall readability assessment
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: execute
3
- version: "1.1.0"
3
+ version: "1.2.0"
4
4
  description: "Gestalt-driven execution planner that transforms a Spec into a validated ExecutionPlan"
5
5
  triggers:
6
6
  - "execute"
@@ -350,3 +350,68 @@ role_match/role_consensus로 얻은 `roleGuidance`를 참조해 태스크를 수
350
350
  | `hard_cap` | structural 3회 + contextual 3회 실패 |
351
351
  | `caller` | `{ action: "evolve", terminateReason: "caller" }` |
352
352
  | `human_escalation` | 4개 lateral persona 소진 |
353
+
354
+ ---
355
+
356
+ ## 공통 진행 패널
357
+
358
+ Execute 파이프라인 실행 중 Claude Code Task 패널에 실시간 상태를 표시한다. 패널 업데이트는 best-effort — 실패가 태스크 실행 흐름을 중단시켜서는 안 된다.
359
+
360
+ ### Planning 단계 시작 시 (`start` 응답 수신 후)
361
+
362
+ `TaskCreate`로 실행 패널을 생성하고, 반환된 taskId를 세션 동안 보관한다.
363
+
364
+ ```
365
+ subject: "Gestalt Execute: {spec.goal 앞 40자}"
366
+ description: "Planning 중 | 단계 1/4 | figure_ground"
367
+ activeForm: "실행 계획 수립 중"
368
+ ```
369
+
370
+ ### Planning 각 단계 후 (`plan_step` 응답 수신 시마다)
371
+
372
+ `TaskUpdate`로 현재 Planning 단계를 업데이트한다.
373
+
374
+ ```
375
+ description: "Planning 중 | 단계 {stepsCompleted}/4 | {currentPrinciple}"
376
+ ```
377
+
378
+ ### Execution 시작 후 (`execute_start` 응답 수신 후)
379
+
380
+ Planning 패널 태스크를 완료하고, 새 Execution 패널 태스크를 생성한다.
381
+
382
+ ```
383
+ subject: "Gestalt Execute: {spec.goal 앞 40자}"
384
+ description: "0/{totalTasks} 완료 | 현재: 시작 대기 중 | 실패: 0개 | 그룹 0/{parallelGroupCount}"
385
+ activeForm: "태스크 실행 중"
386
+ ```
387
+
388
+ `plan_complete` 응답의 `planSummary.totalTasks`와 `planSummary.parallelGroupCount`를 활용한다.
389
+
390
+ ### 각 태스크 완료 후 (`execute_task` 응답 수신 시마다)
391
+
392
+ `TaskUpdate`로 진행 상황을 업데이트한다.
393
+
394
+ ```
395
+ description: "{completedCount}/{totalTasks} 완료 | 현재: {nextTask.title or '완료'} | 실패: {failedCount}개 | 그룹 {groupIndex}/{totalGroups}"
396
+ ```
397
+
398
+ - `completedCount`: 지금까지 제출한 taskResult 수
399
+ - `nextTask`: 응답의 `nextTaskId`로 다음 태스크 이름 추론
400
+ - `failedCount`: status가 `failed`인 taskResult 수
401
+ - `groupIndex/totalGroups`: `plan_complete` 응답의 `parallelGroups` 기준
402
+
403
+ `allTasksCompleted === true` 이면 description에 "전체 완료" 표시 후 `TaskUpdate`로 status를 completed로 변경한다.
404
+
405
+ ### 평가/진화 단계
406
+
407
+ - `evaluate` 시작: description에 "평가 중 — structural 검사" 추가
408
+ - structural 통과: "평가 중 — contextual 검사" 로 업데이트
409
+ - 평가 완료(success): `TaskUpdate({ status: "completed", description: "완료 | score: {overallScore} | alignment: {goalAlignment}" })`
410
+ - Evolve 진입: description에 "개선 중 (generation {N})" 추가
411
+
412
+ ### 오류/에스컬레이션 시
413
+
414
+ ```
415
+ status: "completed"
416
+ description: "종료: {terminationReason} | 최고 점수: {bestScore}"
417
+ ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: interview
3
- version: "1.0.0"
3
+ version: "1.1.0"
4
4
  description: "Gestalt-driven interview to clarify project requirements"
5
5
  triggers:
6
6
  - "interview"
@@ -80,3 +80,38 @@ API 키 없이 MCP 서버 실행 시 자동 활성화. LLM 작업을 caller가
80
80
  | `questionPrompt` | string | 다음 질문 생성용 프롬프트 |
81
81
  | `scoringPrompt` | string? | 모호성 점수 산출용 프롬프트 (respond 후에만 포함) |
82
82
  | `roundNumber` | number | 현재 라운드 번호 |
83
+
84
+ ---
85
+
86
+ ## 공통 진행 패널
87
+
88
+ 인터뷰 진행 중 Claude Code Task 패널에 실시간 상태를 표시한다. 패널 업데이트는 best-effort — 업데이트 실패가 인터뷰 흐름을 중단시켜서는 안 된다.
89
+
90
+ ### 시작 시 (`start` 응답 수신 직후)
91
+
92
+ `TaskCreate`를 호출해 진행 패널을 생성하고, 반환된 taskId를 세션 동안 보관한다.
93
+
94
+ ```
95
+ subject: "Gestalt 인터뷰: {topic}"
96
+ description: "라운드 1/{maxRounds} | 원리: {currentPrinciple} | 모호성: 측정 전"
97
+ activeForm: "인터뷰 진행 중"
98
+ ```
99
+
100
+ ### 각 라운드 후 (`respond` 응답 수신 시마다)
101
+
102
+ `TaskUpdate`로 description을 최신 상태로 갱신한다. 모호성 점수는 추이 형식으로 표시한다.
103
+
104
+ ```
105
+ description: "라운드 {roundNumber}/{maxRounds} | 원리: {currentPrinciple} | 모호성: {score1} → {score2} → {latestScore}"
106
+ ```
107
+
108
+ ambiguityScore.isReady === true 이면 description에 "✓ 준비 완료" 표시를 추가한다.
109
+
110
+ ### 완료 시 (`complete` 응답 수신 후)
111
+
112
+ `TaskUpdate`로 status를 completed로 변경한다.
113
+
114
+ ```
115
+ status: "completed"
116
+ description: "총 {totalRounds}라운드 완료 | 최종 모호성: {finalAmbiguityScore}"
117
+ ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spec
3
- version: "1.0.0"
3
+ version: "1.1.0"
4
4
  description: "Generate a Spec specification from a completed interview"
5
5
  triggers:
6
6
  - "generate spec"
@@ -90,3 +90,35 @@ ges_generate_spec({
90
90
  - `gestaltAnalysis[].confidence`: 0.0 ~ 1.0
91
91
  - `ontologySchema.entities[]`: `{ name: string(min 1), description: string, attributes: string[] }`
92
92
  - `ontologySchema.relations[]`: `{ from: string(min 1), to: string(min 1), type: string(min 1) }`
93
+
94
+ ---
95
+
96
+ ## 공통 진행 패널
97
+
98
+ Spec 생성 중 Claude Code Task 패널에 상태를 표시한다. best-effort — 패널 실패가 Spec 생성을 막아서는 안 된다.
99
+
100
+ ### 시작 시 (1단계 `ges_generate_spec` 호출 전)
101
+
102
+ `TaskCreate`로 패널을 생성한다.
103
+
104
+ ```
105
+ subject: "Spec 생성 중"
106
+ description: "인터뷰 세션 {sessionId} 기반 Spec 구성 중..."
107
+ activeForm: "Spec 생성 중"
108
+ ```
109
+
110
+ ### 완료 시 (2단계 `ges_generate_spec` 응답 수신 후)
111
+
112
+ `TaskUpdate`로 status를 completed로 변경한다.
113
+
114
+ ```
115
+ status: "completed"
116
+ description: "Spec 생성 완료 | specId: {spec.metadata.specId}"
117
+ ```
118
+
119
+ 실패 시(error 반환):
120
+
121
+ ```
122
+ status: "completed"
123
+ description: "Spec 생성 실패: {error}"
124
+ ```