@tienne/gestalt 0.14.1 → 0.15.1

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 (97) hide show
  1. package/README.ko.md +19 -32
  2. package/README.md +188 -164
  3. package/dist/package.json +1 -1
  4. package/dist/role-agents/harness-architect/AGENT.md +210 -0
  5. package/dist/role-agents/technical-writer/AGENT.md +46 -0
  6. package/dist/role-agents/technical-writer/references/ai-tell-quick-rules.md +134 -0
  7. package/dist/skills/agent/SKILL.md +2 -0
  8. package/package.json +1 -1
  9. package/role-agents/harness-architect/AGENT.md +210 -0
  10. package/role-agents/technical-writer/AGENT.md +46 -0
  11. package/role-agents/technical-writer/references/ai-tell-quick-rules.md +134 -0
  12. package/skills/agent/SKILL.md +2 -0
  13. package/dist/skills/seed/SKILL.md +0 -92
  14. package/dist/src/cli/commands/seed.d.ts +0 -4
  15. package/dist/src/cli/commands/seed.d.ts.map +0 -1
  16. package/dist/src/cli/commands/seed.js +0 -34
  17. package/dist/src/cli/commands/seed.js.map +0 -1
  18. package/dist/src/interview/ambiguity.d.ts +0 -8
  19. package/dist/src/interview/ambiguity.d.ts.map +0 -1
  20. package/dist/src/interview/ambiguity.js +0 -69
  21. package/dist/src/interview/ambiguity.js.map +0 -1
  22. package/dist/src/mcp/tools/seed-passthrough.d.ts +0 -5
  23. package/dist/src/mcp/tools/seed-passthrough.d.ts.map +0 -1
  24. package/dist/src/mcp/tools/seed-passthrough.js +0 -29
  25. package/dist/src/mcp/tools/seed-passthrough.js.map +0 -1
  26. package/dist/src/mcp/tools/seed.d.ts +0 -5
  27. package/dist/src/mcp/tools/seed.d.ts.map +0 -1
  28. package/dist/src/mcp/tools/seed.js +0 -19
  29. package/dist/src/mcp/tools/seed.js.map +0 -1
  30. package/dist/src/recording/agg-converter.d.ts +0 -25
  31. package/dist/src/recording/agg-converter.d.ts.map +0 -1
  32. package/dist/src/recording/agg-converter.js +0 -80
  33. package/dist/src/recording/agg-converter.js.map +0 -1
  34. package/dist/src/recording/agg-installer.d.ts +0 -6
  35. package/dist/src/recording/agg-installer.d.ts.map +0 -1
  36. package/dist/src/recording/agg-installer.js +0 -50
  37. package/dist/src/recording/agg-installer.js.map +0 -1
  38. package/dist/src/recording/asciinema-installer.d.ts +0 -6
  39. package/dist/src/recording/asciinema-installer.d.ts.map +0 -1
  40. package/dist/src/recording/asciinema-installer.js +0 -50
  41. package/dist/src/recording/asciinema-installer.js.map +0 -1
  42. package/dist/src/recording/asciinema-recorder.d.ts +0 -26
  43. package/dist/src/recording/asciinema-recorder.d.ts.map +0 -1
  44. package/dist/src/recording/asciinema-recorder.js +0 -52
  45. package/dist/src/recording/asciinema-recorder.js.map +0 -1
  46. package/dist/src/recording/cast-generator.d.ts +0 -7
  47. package/dist/src/recording/cast-generator.d.ts.map +0 -1
  48. package/dist/src/recording/cast-generator.js +0 -97
  49. package/dist/src/recording/cast-generator.js.map +0 -1
  50. package/dist/src/recording/filename-generator.d.ts +0 -19
  51. package/dist/src/recording/filename-generator.d.ts.map +0 -1
  52. package/dist/src/recording/filename-generator.js +0 -67
  53. package/dist/src/recording/filename-generator.js.map +0 -1
  54. package/dist/src/recording/gif-generator.d.ts +0 -21
  55. package/dist/src/recording/gif-generator.d.ts.map +0 -1
  56. package/dist/src/recording/gif-generator.js +0 -121
  57. package/dist/src/recording/gif-generator.js.map +0 -1
  58. package/dist/src/recording/recording-dir.d.ts +0 -5
  59. package/dist/src/recording/recording-dir.d.ts.map +0 -1
  60. package/dist/src/recording/recording-dir.js +0 -13
  61. package/dist/src/recording/recording-dir.js.map +0 -1
  62. package/dist/src/recording/recording-orchestrator.d.ts +0 -50
  63. package/dist/src/recording/recording-orchestrator.d.ts.map +0 -1
  64. package/dist/src/recording/recording-orchestrator.js +0 -98
  65. package/dist/src/recording/recording-orchestrator.js.map +0 -1
  66. package/dist/src/recording/resume-detector.d.ts +0 -10
  67. package/dist/src/recording/resume-detector.d.ts.map +0 -1
  68. package/dist/src/recording/resume-detector.js +0 -14
  69. package/dist/src/recording/resume-detector.js.map +0 -1
  70. package/dist/src/recording/segment-merger.d.ts +0 -27
  71. package/dist/src/recording/segment-merger.d.ts.map +0 -1
  72. package/dist/src/recording/segment-merger.js +0 -65
  73. package/dist/src/recording/segment-merger.js.map +0 -1
  74. package/dist/src/recording/terminal-recorder.d.ts +0 -31
  75. package/dist/src/recording/terminal-recorder.d.ts.map +0 -1
  76. package/dist/src/recording/terminal-recorder.js +0 -111
  77. package/dist/src/recording/terminal-recorder.js.map +0 -1
  78. package/dist/src/scripts/postinstall.d.ts +0 -2
  79. package/dist/src/scripts/postinstall.d.ts.map +0 -1
  80. package/dist/src/scripts/postinstall.js +0 -29
  81. package/dist/src/scripts/postinstall.js.map +0 -1
  82. package/dist/src/seed/extractor.d.ts +0 -15
  83. package/dist/src/seed/extractor.d.ts.map +0 -1
  84. package/dist/src/seed/extractor.js +0 -88
  85. package/dist/src/seed/extractor.js.map +0 -1
  86. package/dist/src/seed/generator.d.ts +0 -12
  87. package/dist/src/seed/generator.d.ts.map +0 -1
  88. package/dist/src/seed/generator.js +0 -66
  89. package/dist/src/seed/generator.js.map +0 -1
  90. package/dist/src/seed/passthrough-generator.d.ts +0 -31
  91. package/dist/src/seed/passthrough-generator.d.ts.map +0 -1
  92. package/dist/src/seed/passthrough-generator.js +0 -80
  93. package/dist/src/seed/passthrough-generator.js.map +0 -1
  94. package/dist/src/seed/schema.d.ts +0 -145
  95. package/dist/src/seed/schema.d.ts.map +0 -1
  96. package/dist/src/seed/schema.js +0 -37
  97. package/dist/src/seed/schema.js.map +0 -1
@@ -59,6 +59,11 @@ When writing Korean developer documentation, follow these conventions observed i
59
59
 
60
60
  **Korean Sentence Writing**
61
61
 
62
+ > **AI 티 패턴 룰북**: 아래 원칙은 가장 자주 노출되는 예시다.
63
+ > 전체 패턴(A~J, S1/S2/S3 심각도 × 40+ 서브패턴)은
64
+ > `references/ai-tell-quick-rules.md`를 참조한다.
65
+ > 한국어 산출물 작성 전에 이 파일을 읽고 패턴을 숙지한다.
66
+
62
67
  **핵심 원칙: 영어로 생각하고 번역하지 말 것**
63
68
  한국어로 직접 작성한다. "dependency-based execution planning"을 머릿속에서 먼저 영어로 구성한 뒤 번역하면 번역체가 된다.
64
69
 
@@ -228,6 +233,47 @@ Apply these principles when structuring any document:
228
233
  — Do (Reference): `` `eventSourcing` `boolean` — 이벤트 소싱 활성화 여부. 기본값: `false` ``
229
234
  — Do (Learning/Explanation): "이 서비스는 이벤트 소싱(Event Sourcing)으로 상태를 관리해요. 이벤트 소싱은 상태의 최종 값 대신 변화를 일으킨 모든 이벤트를 기록하는 방식이에요."
230
235
 
236
+ ## Korean Output Self-Review
237
+
238
+ 한국어 문서 작성이 끝나면 제출 전에 아래 절차로 자가 검증한다.
239
+
240
+ ### S1 패턴 잔존 금지 (하나라도 발견 시 즉시 수정)
241
+
242
+ 전체 패턴은 `references/ai-tell-quick-rules.md` 참조. 핵심 S1만 인라인으로:
243
+
244
+ | ID | 패턴 | 처방 |
245
+ |----|------|------|
246
+ | A-1 | "~에 대해(서)" | 목적격 조사로 직결 |
247
+ | A-2 | "~를 통해" 남발 | "~로", "~해서"로 분산 |
248
+ | A-3 | "~에 있어(서)" | "~에서", "~을 볼 때" |
249
+ | A-7 | "가지고 있다" / have+N 직역 | 형용사·동사 환원 |
250
+ | A-8 | 이중 피동 "~되어진다" | 단일 피동 또는 능동 |
251
+ | A-16 | "그/그녀/그들" 대명사 남발 | 영형 생략 또는 명사구 |
252
+ | C-5 | 이모지 남발 (칼럼·리포트) | 전부 삭제 |
253
+ | C-10 | 콜론 부제 헤딩 "X: Y" 반복 | 평서 헤딩으로 |
254
+ | C-11 | 연결어미 뒤 쉼표 (-고, -며, 등 직후) | 쉼표 제거 |
255
+ | D-1 | "결론적으로/따라서/이를 통해" 3회+ | 삭제 또는 1회로 제한 |
256
+ | D-2 | "시사하는 바가 크다" | 삭제 또는 구체 결론으로 |
257
+ | D-3 | "본질적으로/핵심적으로" | 삭제 |
258
+ | D-4 | hype 어휘 3회+ (파격적·획기적·강력한) | 구체 수치·사실로 |
259
+ | D-5 | 의인화 추상 주어 ("기술이 묻는다") | 사람·기관 주어로 |
260
+ | D-6 | 결말 공식 "~할 때다/지금이야말로" | 평서로 닫거나 삭제 |
261
+ | H-1 | 문두 접속사 "또한·따라서·아울러" 5회+ | 대량 제거 |
262
+ | H-3 | 메타 진입 "이는·이 점에서" 3회+ | 본문에 녹이거나 삭제 |
263
+ | I-1 | "~인 것이다/~한 것이다" 결말 | 평서형으로 |
264
+ | J-2 | 따옴표 강조 5회+ | 핵심 1~2개만 유지 |
265
+
266
+ ### 자가 검증 6항 체크리스트
267
+
268
+ 1. **고유명사·수치·날짜·인용** 100% 원문 보존
269
+ 2. **레지스터 보존** — 격식체/평어체 일관 (원고 전체 동일 어미)
270
+ 3. **장르 이탈 없음** — 리포트가 에세이체로, 가이드가 칼럼체로 흐르지 않았는가
271
+ 4. **잔존 S1 패턴 0건** — 위 표 기준
272
+ 5. **임의 추가 없음** — 원문에 없던 비유·수사·사실·예시를 추가하지 않았는가
273
+ 6. **이모지·볼드 남용 없음** — 기술 문서에서 이모지 전부 삭제, 볼드는 최초 등장 핵심 용어에만
274
+
275
+ 위반 항목이 있으면 해당 구간만 수정 후 재검증.
276
+
231
277
  ## Output Format
232
278
 
233
279
  When writing documentation, produce:
@@ -0,0 +1,134 @@
1
+ # Quick Rules — Monolith Fast Path 전용 (v2.0)
2
+
3
+ `humanize-monolith` 에이전트가 한 콜에서 탐지·윤문·자체검증을 끝내기 위해 사용하는 슬림 룰북. 본진 `ai-tell-taxonomy.md`(590줄)에서 S1·S2 핵심 패턴만 추려 처방과 함께 한 줄로 압축했다.
4
+
5
+ **원칙:** 정의 1줄 + 처방 1줄. 예문 생략. 본진 ID와 1:1 매칭.
6
+
7
+ **Do-NOT (탐지·윤문 모두 제외):** 고유명사·제품명·모델명·기관명, 수치·날짜·단위, 큰따옴표 안 직접 인용, 법률 조문, 수학·화학·통계 표기, 영어 약어(LLM·GPU·MCP·API 등 업계 표준).
8
+
9
+ **과윤문 가드:** 변경률 30% 초과 = 경고, 50% 초과 = 강제 중단·롤백.
10
+
11
+ ---
12
+
13
+ ## A. 번역투 (Translation-ese)
14
+
15
+ | ID | 패턴 | 심각도 | 처방 |
16
+ |---|---|---|---|
17
+ | A-1 | "~에 대해(서)" | S1 | 목적격 조사로 직결("X에 대해 논의" → "X를 논의") |
18
+ | A-2 | "~를 통해/통하여" 남발 | S1 | "~로", "~해서", "~함으로써"로 분산 |
19
+ | A-3 | "~에 있어(서)" | S1 | "~에서", "~을 볼 때" |
20
+ | A-4 | "~라는 점에서" 3회+ | S2 | "~서", "~라는 이유로" |
21
+ | A-5 | "~와 관련하여/관련된" | S2 | "~에", "~의" |
22
+ | A-6 | "~에 기반하여/바탕으로" 남발 | S2 | "~로", "~을 보고" |
23
+ | A-7 | "가지고 있다" / have·make·take·give + N 직역 | S1 | 형용사·동사 환원 또는 이중주어("회의를 가지다" → "회의를 했다", "강한 경쟁력을 가지고 있다" → "경쟁력이 강하다") |
24
+ | A-8 | 이중 피동 "~되어진다" | S1 | 능동 또는 단일 피동 ("판단되어진다" → "판단된다") |
25
+ | A-9 | "~에 의해" 피동 | S2 | 행위자를 주어로("AI에 의해 생성" → "AI가 만든") |
26
+ | A-10 | "~할 수 있다" 남발 | S2 | 단언으로("높일 수 있다" → "높인다") |
27
+ | A-11 | "~을 위해" 목적절 남발 | S2 | "~려고", "~위한" |
28
+ | A-15 | 추상 주어 + 만능 동사 / 사역·인지 동사 | S2 | 구체 주어로 환원, 사역은 "X 때문에/덕분에/로 인해" 부사절, 인지 동사(suggest/show/indicate/reveal)는 "~에 따르면 ~이다"·"~으로 ~이 드러났다" 분리 |
29
+ | A-16 | "그/그녀/그것/그들" 단락 ≥3회 영어 대명사 직역 | S1 | 50%+ 영형(생략) 또는 호칭·명사구로 (김도훈 2009) |
30
+ | A-18 | 명사 앞 ≥3어절 관형구·관계절 좌향 수식 | S2 | 문장 분리 또는 후치 동격절("X를 만났는데, 그 X는 …") (박옥수 2018) |
31
+ | A-19 | 이중 조사 "~에서의/~에로의/~으로의/~에의/~으로부터의" | S2 | 절·구로 풀어쓰기. 단순 ~의는 비대상 (김정우 2007) |
32
+
33
+ ## B. 영어 인용·용어 과다
34
+
35
+ | ID | 패턴 | 심각도 | 처방 |
36
+ |---|---|---|---|
37
+ | B-1 | 한글 + 괄호 영어 매번 ("~(Sovereign AI)" 처럼) | S2 | 첫 등장만 병기, 이후 한글만 |
38
+ | B-2 | 영어 어휘 직역 가능한데 그대로 | S2 | 한국어로 옮기되 업계 표준은 유지 |
39
+
40
+ ## C. 구조적 AI 패턴
41
+
42
+ | ID | 패턴 | 심각도 | 처방 |
43
+ |---|---|---|---|
44
+ | C-5 | 이모지 남발 | S1 | 장르 칼럼·리포트면 전부 삭제 |
45
+ | C-7 | "먼저·반면·결국" 3단 공식 | S2 | 접속사 1~2개로 줄이거나 본문에 녹여 제거 |
46
+ | C-8 | "A인가·B인가" 대구 반복 | S2 | 한 번만 살리고 나머지는 평서문으로 |
47
+ | C-9 | 숫자 괄호 인덱싱 "(1)·(2)·(3)" | S2 | 본문에 녹이거나 단순 줄바꿈 |
48
+ | C-10 | 콜론 부제 헤딩 "X: Y" 반복 | S1 | 헤딩 짧게 또는 평서 헤딩으로 |
49
+ | C-11 | 연결어미 뒤 쉼표 (-고/-며/-지만/-며서/-아서/-어서 직후 쉼표) | S1 | 쉼표 제거. 6+회=강한 신호. KatFish 4.84배 분리도 |
50
+
51
+ ## D. AI 특유의 관용구 (Signature Phrases)
52
+
53
+ | ID | 패턴 | 심각도 | 처방 |
54
+ |---|---|---|---|
55
+ | D-1 | 결산 피벗 lexicon "결론적으로/따라서/이를 통해/그러므로/요약하면/정리하면" | S1 | 3회 초과 시 1~2건 다른 종결로 치환, 나머지 삭제 |
56
+ | D-2 | "시사하는 바가 크다/주목할 만하다" | S1 | 삭제 또는 구체 결론으로 |
57
+ | D-3 | "본질적으로/핵심적으로" | S1 | 삭제 |
58
+ | D-4 | hype 어휘(파격적·압도적·강력한·획기적·치명적) 3회+ | S1 | 구체 수치·사실로 환원 |
59
+ | D-5 | 의인화 추상 주어("기술이 묻는다·시대가 부른다") | S1 | 사람·기관 주어로 |
60
+ | D-6 | 결말 공식 "~할 때다/~해야 한다/~지금이야말로" | S1 | 평서로 닫거나 삭제 |
61
+ | D-7 | 변환 공식 "X에서 Y로" 반복 | S2 | 한 번만, 나머지는 일반 서술 |
62
+
63
+ ## E. 리듬·종결어미
64
+
65
+ | ID | 패턴 | 심각도 | 처방 |
66
+ |---|---|---|---|
67
+ | E-1 | 문장 길이 균일(stdev 8 미만) | S2 | 단문 1~2개 / 장문 1개를 각 문단에 의도적 삽입 |
68
+ | E-2 | 동일 종결어미 "~다" 4문장 연속 + 진행형 "~고 있다" 자동 매핑 | S2 | "~었다·~ㄴ다·~는다·~기 마련이다·~ㄹ 것이다" 등 다양화. "~고 있다" 단순 시제 환원 가능 시 환원("읽고 있다" → "읽는다") |
69
+ | E-7 | 청자 경어법 4단계(해라/하게/하오/해요/합쇼) 일관성 손실 (대화·구어 한정) | S2 | 한 단락 내 혼용 금지, 격식 일관 (김혜영 2019, estimated) |
70
+
71
+ ## F. 과도한 수식·중복
72
+
73
+ | ID | 패턴 | 심각도 | 처방 |
74
+ |---|---|---|---|
75
+ | F-4 | 한자어 명사화 -성/-적/-화 + 영어 명사화 -tion/-ment/-ness/-ity 누적 (한 글 12회+) | S2 | 동사·형용사 어근으로 환원("the implementation of the policy" → "정책 시행" 또는 "정책을 시행하기") |
76
+ | F-5 | "~적 N" 추상 체인 ("전략적 함의·실천적 기반") | S2 | 명사+명사 또는 풀어쓰기("전략 함의·실천의 기반") |
77
+
78
+ ## G. Hedging
79
+
80
+ | ID | 패턴 | 심각도 | 처방 |
81
+ |---|---|---|---|
82
+ | G-1 | "~것이다/~할 것이다" 미래 단정 남발 | S2 | 현재형·확정형으로 |
83
+ | G-2 | "~로 보인다/~인 듯하다" 추정 남발 | S2 | 단언 가능한 곳은 단언 |
84
+ | G-3 | 안전 균형 lexicon "양쪽 모두/두 가지 모두/장점도 있지만/신중하게/균형" | S2 | 4회 초과 시 1~2건 화자 입장으로 치환 |
85
+
86
+ ## H. 접속사 남발
87
+
88
+ | ID | 패턴 | 심각도 | 처방 |
89
+ |---|---|---|---|
90
+ | H-1 | 문두 접속사 "또한·따라서·즉·나아가·아울러·게다가·더욱이" 5회+ | S1 | 대량 제거. 문장 자체가 흐름을 잡게 |
91
+ | H-3 | 메타 진입 "이는·이 점에서·이 관점에서·이 말은" 3회+ | S1 | 본문에 녹이거나 삭제 |
92
+ | H-4 | "즉" 남발 | S2 | 1회로 제한 |
93
+
94
+ ## I. 형식명사·의존명사
95
+
96
+ | ID | 패턴 | 심각도 | 처방 |
97
+ |---|---|---|---|
98
+ | I-1 | "~인 것이다/~한 것이다" 결말 | S1 | 평서형으로 |
99
+ | I-2 | "X은 ~라는 점에 있다" | S2 | "X는 ~다" 직설로 |
100
+ | I-3 | "~다는 뜻이다/~다는 의미다" 결말 | S2 | 본문에 풀어 쓰기 |
101
+ | I-4 | 권고형 결말 "~해야 한다·~합니다" 반복 | S2 | 평서·단언으로 |
102
+
103
+ ## J. 시각 장식
104
+
105
+ | ID | 패턴 | 심각도 | 처방 |
106
+ |---|---|---|---|
107
+ | J-1 | 헤딩 마크다운 ** 강조 남발 | S2 | 칼럼·리포트면 거의 다 제거 |
108
+ | J-2 | 따옴표 강조 5회+ | S1 | 핵심 한두 개만 살리고 평어로 |
109
+ | J-3 | 불릿 리스트 (장르가 칼럼·리포트일 때) | S2 | 문단 산문으로 통합 |
110
+
111
+ ---
112
+
113
+ ## 자체검증 체크리스트 (monolith 윤문 후 자가 점검)
114
+
115
+ 윤문 직후 5초 내에 다음을 자체 점검한다. 한 항목이라도 위반이면 해당 edit 롤백.
116
+
117
+ 1. **고유명사·수치·날짜·인용 100% 보존**: 원문 대비 한 글자도 다르지 않은가
118
+ 2. **변경률**: 30% 이하인가 (50% 초과는 작업 중단)
119
+ 3. **장르 이탈 없음**: 칼럼이 에세이·문학으로 변하지 않았는가, 리포트가 블로그체로 떨어지지 않았는가
120
+ 4. **register 보존**: 원문 격식체면 결과도 격식체. 평어체로 떨어뜨리지 않는다
121
+ 5. **잔존 S1 패턴 0건**: D-1~D-7, A-7, A-8, A-16, C-5, C-10, C-11, H-1, I-1, J-2 핵심 S1이 남아있지 않은가
122
+ 6. **인공 표현 자제**: 원문에 없던 비유·수사·문학적 표현을 윤문 과정에서 임의로 추가하지 않았는가
123
+
124
+ 위반 시: edit 롤백 → 다시 윤문 → 재점검. 자체 루프 최대 1회. 이상 미해결이면 결과를 그대로 출력하되 `summary.md`에 "자가검증 미통과 항목 N건" 표기.
125
+
126
+ ## 등급 기준 (자가 채점)
127
+
128
+ - **A**: S1 잔존 0, S2 잔존 2 이하, 변경률 10~25%, 자체검증 6항 모두 통과
129
+ - **B**: S1 잔존 0, S2 잔존 4 이하, 자체검증 5항 이상 통과
130
+ - **C**: S1 잔존 1~2 또는 자체검증 4항 이하 통과 — 사용자에게 strict 모드 권고
131
+ - **D**: S1 잔존 3+ 또는 변경률 50% 초과 — 작업 중단 권고
132
+
133
+ > v2.0 신규/보강은 A-7·A-15·A-16·A-18·A-19·E-2·E-7·F-4 **8건 (A-17 hold)**. 학술 인용 전문은 `references/scholarship.md`. post-editese 3축 metric은 본 룰북 미반영(metric only 트랙). A-17 무정물·추상명사 '-들'은 학술 anchor(전영철 2007·곽은주·진실로 2011) 강하나 외부 회차(2026-05-07 위키 6편)에서 양성 0건 — NMT 원본 출력 회차 후 v2.1에서 동일 ID로 재평가.
134
+
@@ -49,6 +49,7 @@ Invoke any Gestalt Role or Review agent directly, outside the Gestalt pipeline.
49
49
  | Agent | Domain |
50
50
  |-------|--------|
51
51
  | `architect` | System design, scalability, design patterns |
52
+ | `harness-architect` | Claude Code harness design, agent pipeline, skill/command structure |
52
53
  | `backend-developer` | API, database, authentication, server |
53
54
  | `frontend-developer` | UI, React, accessibility |
54
55
  | `designer` | UX/UI, design systems, interaction |
@@ -56,6 +57,7 @@ Invoke any Gestalt Role or Review agent directly, outside the Gestalt pipeline.
56
57
  | `devops-engineer` | CI/CD, infrastructure, monitoring |
57
58
  | `product-planner` | Requirements, roadmap, user stories |
58
59
  | `researcher` | Analysis, benchmarks, best practices |
60
+ | `technical-writer` | Documentation, API docs, README, developer guides |
59
61
 
60
62
  **Review Agents** — code review specialists:
61
63
 
@@ -1,92 +0,0 @@
1
- ---
2
- name: seed
3
- version: "1.0.0"
4
- description: "Generate a Seed specification from a completed interview"
5
- triggers:
6
- - "generate seed"
7
- - "create spec"
8
- - "build seed"
9
- inputs:
10
- sessionId:
11
- type: string
12
- required: true
13
- description: "The interview session ID to generate a seed from"
14
- force:
15
- type: boolean
16
- required: false
17
- description: "Force generation even if ambiguity threshold is not met"
18
- outputs:
19
- - seed
20
- ---
21
-
22
- # Seed Generation Skill
23
-
24
- This skill transforms completed interview data into a structured project specification (Seed).
25
-
26
- ## Output Structure
27
-
28
- - **Goal**: Clear project objective
29
- - **Constraints**: Technical and business constraints
30
- - **Acceptance Criteria**: Measurable success conditions
31
- - **Ontology Schema**: Entity-relationship model
32
- - **Gestalt Analysis**: Findings from each principle applied
33
-
34
- ## Requirements
35
-
36
- - Interview session must be in `completed` status
37
- - Ambiguity score must be ≤ 0.2 (unless `force` is true)
38
-
39
- ## Passthrough Mode
40
-
41
- API 키 없이 MCP 서버 실행 시 자동 활성화. Seed 생성을 caller가 직접 수행한다.
42
-
43
- ### 추가 Input 파라미터
44
-
45
- | 파라미터 | 타입 | 필수 | 설명 |
46
- |---------|------|------|------|
47
- | `seed` | object | 2단계에서 필수 | caller가 생성한 Seed JSON |
48
- | `seed.goal` | string | 필수 | 프로젝트 목표 |
49
- | `seed.constraints` | string[] | 필수 | 기술/비즈니스 제약조건 |
50
- | `seed.acceptanceCriteria` | string[] | 필수 | 수용 기준 |
51
- | `seed.ontologySchema` | object | 필수 | 엔티티-관계 모델 |
52
- | `seed.gestaltAnalysis` | array | 필수 | 게슈탈트 분석 결과 |
53
-
54
- ### 2단계 플로우
55
-
56
- **1단계: SeedContext 요청**
57
- ```
58
- ges_generate_seed({ sessionId: "<id>" })
59
- ```
60
- → `{ status: "prompt", seedContext, message }` 반환
61
-
62
- SeedContext 필드:
63
- - `systemPrompt`: Seed 생성용 시스템 프롬프트
64
- - `seedPrompt`: 인터뷰 내용 기반 Seed 생성 프롬프트
65
- - `allRounds[]`: `{ roundNumber, question, response, gestaltFocus }`
66
-
67
- **2단계: Seed 제출 및 검증**
68
- ```
69
- ges_generate_seed({
70
- sessionId: "<id>",
71
- seed: {
72
- goal: "명확한 프로젝트 목표",
73
- constraints: ["TypeScript 사용", "REST API"],
74
- acceptanceCriteria: ["응답 시간 200ms 이하"],
75
- ontologySchema: {
76
- entities: [{ name: "User", description: "...", attributes: ["id", "email"] }],
77
- relations: [{ from: "User", to: "Order", type: "has_many" }]
78
- },
79
- gestaltAnalysis: [
80
- { principle: "closure", finding: "인증 요구사항 완전히 파악됨", confidence: 0.9 }
81
- ]
82
- }
83
- })
84
- ```
85
- → `{ status: "generated", seed }` (metadata 자동 생성 포함) 또는 `{ error }` 반환
86
-
87
- ### Seed 검증 스키마 (Zod)
88
-
89
- - `gestaltAnalysis[].principle`: `closure | proximity | similarity | figure_ground | continuity`
90
- - `gestaltAnalysis[].confidence`: 0.0 ~ 1.0
91
- - `ontologySchema.entities[]`: `{ name: string(min 1), description: string, attributes: string[] }`
92
- - `ontologySchema.relations[]`: `{ from: string(min 1), to: string(min 1), type: string(min 1) }`
@@ -1,4 +0,0 @@
1
- export declare function seedCommand(sessionId: string, options: {
2
- force?: boolean;
3
- }): Promise<void>;
4
- //# sourceMappingURL=seed.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/seed.ts"],"names":[],"mappings":"AAMA,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BhG"}
@@ -1,34 +0,0 @@
1
- import { loadConfig } from '../../core/config.js';
2
- import { EventStore } from '../../events/store.js';
3
- import { AnthropicAdapter } from '../../llm/adapter.js';
4
- import { InterviewEngine } from '../../interview/engine.js';
5
- import { SeedGenerator } from '../../seed/generator.js';
6
- export async function seedCommand(sessionId, options) {
7
- const config = loadConfig();
8
- if (!config.anthropicApiKey) {
9
- console.error('Error: ANTHROPIC_API_KEY is required for CLI mode. Set it in .env or as environment variable.');
10
- process.exit(1);
11
- }
12
- const eventStore = new EventStore(config.dbPath);
13
- const llm = new AnthropicAdapter(config.anthropicApiKey, config.model);
14
- const engine = new InterviewEngine(llm, eventStore);
15
- const generator = new SeedGenerator(llm, eventStore);
16
- try {
17
- const session = engine.getSession(sessionId);
18
- console.log(`\n🌱 Generating seed for session: ${session.topic}\n`);
19
- const result = await generator.generate(session, options.force ?? false);
20
- if (!result.ok) {
21
- console.error(`Error: ${result.error.message}`);
22
- return;
23
- }
24
- console.log(JSON.stringify(result.value, null, 2));
25
- console.log('\n✅ Seed generated successfully.\n');
26
- }
27
- catch (e) {
28
- console.error(`Error: ${e instanceof Error ? e.message : String(e)}`);
29
- }
30
- finally {
31
- eventStore.close();
32
- }
33
- }
34
- //# sourceMappingURL=seed.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../../src/cli/commands/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB,EAAE,OAA4B;IAC/E,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,+FAA+F,CAAC,CAAC;QAC/G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,qCAAqC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;QAEzE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -1,8 +0,0 @@
1
- import type { AmbiguityScore, InterviewRound, ProjectType } from '../core/types.js';
2
- import type { LLMAdapter } from '../llm/types.js';
3
- export declare class AmbiguityScorer {
4
- private llm;
5
- constructor(llm: LLMAdapter);
6
- score(topic: string, rounds: InterviewRound[], projectType: ProjectType): Promise<AmbiguityScore>;
7
- }
8
- //# sourceMappingURL=ambiguity.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ambiguity.d.ts","sourceRoot":"","sources":["../../../src/interview/ambiguity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,qBAAa,eAAe;IACd,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,UAAU;IAE7B,KAAK,CACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EAAE,EACxB,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,cAAc,CAAC;CA4B3B"}
@@ -1,69 +0,0 @@
1
- import { computeAmbiguityScore } from '../gestalt/analyzer.js';
2
- import { buildAmbiguityPrompt, INTERVIEW_SYSTEM_PROMPT } from '../llm/prompts.js';
3
- export class AmbiguityScorer {
4
- llm;
5
- constructor(llm) {
6
- this.llm = llm;
7
- }
8
- async score(topic, rounds, projectType) {
9
- const answeredRounds = rounds.filter((r) => r.userResponse);
10
- if (answeredRounds.length === 0) {
11
- return {
12
- overall: 1.0,
13
- dimensions: [],
14
- isReady: false,
15
- };
16
- }
17
- const prompt = buildAmbiguityPrompt(topic, answeredRounds.map((r) => ({
18
- question: r.question,
19
- response: r.userResponse,
20
- })), projectType);
21
- const response = await this.llm.chat({
22
- system: INTERVIEW_SYSTEM_PROMPT,
23
- messages: [{ role: 'user', content: prompt }],
24
- temperature: 0.3,
25
- });
26
- const raw = parseAmbiguityResponse(response.content, projectType);
27
- return computeAmbiguityScore(raw, projectType);
28
- }
29
- }
30
- function parseAmbiguityResponse(content, projectType) {
31
- const jsonMatch = content.match(/\{[\s\S]*\}/);
32
- if (!jsonMatch) {
33
- return defaultScores(projectType);
34
- }
35
- try {
36
- const parsed = JSON.parse(jsonMatch[0]);
37
- return {
38
- goalClarity: toNumber(parsed['goalClarity'], 0),
39
- constraintClarity: toNumber(parsed['constraintClarity'], 0),
40
- successCriteria: toNumber(parsed['successCriteria'], 0),
41
- priorityClarity: toNumber(parsed['priorityClarity'], 0),
42
- contextClarity: projectType === 'brownfield'
43
- ? toNumber(parsed['contextClarity'], 0)
44
- : undefined,
45
- contradictions: Array.isArray(parsed['contradictions'])
46
- ? parsed['contradictions']
47
- : [],
48
- };
49
- }
50
- catch {
51
- return defaultScores(projectType);
52
- }
53
- }
54
- function defaultScores(projectType) {
55
- return {
56
- goalClarity: 0,
57
- constraintClarity: 0,
58
- successCriteria: 0,
59
- priorityClarity: 0,
60
- contextClarity: projectType === 'brownfield' ? 0 : undefined,
61
- contradictions: [],
62
- };
63
- }
64
- function toNumber(value, fallback) {
65
- if (typeof value === 'number' && !isNaN(value))
66
- return value;
67
- return fallback;
68
- }
69
- //# sourceMappingURL=ambiguity.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ambiguity.js","sourceRoot":"","sources":["../../../src/interview/ambiguity.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import type { PassthroughEngine } from '../../interview/passthrough-engine.js';
2
- import type { PassthroughSeedGenerator } from '../../seed/passthrough-generator.js';
3
- import type { SeedInput } from '../schemas.js';
4
- export declare function handleSeedPassthrough(engine: PassthroughEngine, generator: PassthroughSeedGenerator, input: SeedInput): string;
5
- //# sourceMappingURL=seed-passthrough.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-passthrough.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/seed-passthrough.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AACpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,wBAAwB,EACnC,KAAK,EAAE,SAAS,GACf,MAAM,CA8BR"}
@@ -1,29 +0,0 @@
1
- export function handleSeedPassthrough(engine, generator, input) {
2
- try {
3
- const session = engine.getSession(input.sessionId);
4
- // If external seed is provided, validate and store it
5
- if (input.seed) {
6
- const result = generator.validateAndStore(session, input.seed, input.force);
7
- if (!result.ok) {
8
- return JSON.stringify({ error: result.error.message }, null, 2);
9
- }
10
- return JSON.stringify({
11
- status: 'generated',
12
- seed: result.value,
13
- }, null, 2);
14
- }
15
- // No seed provided — return the prompt for generation
16
- const context = generator.buildSeedContext(session);
17
- return JSON.stringify({
18
- status: 'prompt',
19
- seedContext: context,
20
- message: 'Use seedContext.seedPrompt with seedContext.systemPrompt to generate the seed JSON, then call this tool again with the seed parameter.',
21
- }, null, 2);
22
- }
23
- catch (e) {
24
- return JSON.stringify({
25
- error: e instanceof Error ? e.message : String(e),
26
- }, null, 2);
27
- }
28
- }
29
- //# sourceMappingURL=seed-passthrough.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed-passthrough.js","sourceRoot":"","sources":["../../../../src/mcp/tools/seed-passthrough.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,qBAAqB,CACnC,MAAyB,EACzB,SAAmC,EACnC,KAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAEnD,sDAAsD;QACtD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAClE,CAAC;YAED,OAAO,IAAI,CAAC,SAAS,CAAC;gBACpB,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,MAAM,CAAC,KAAK;aACnB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACd,CAAC;QAED,sDAAsD;QACtD,MAAM,OAAO,GAAG,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEpD,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,MAAM,EAAE,QAAQ;YAChB,WAAW,EAAE,OAAO;YACpB,OAAO,EAAE,wIAAwI;SAClJ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACd,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;SAClD,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,5 +0,0 @@
1
- import type { InterviewEngine } from '../../interview/engine.js';
2
- import type { SeedGenerator } from '../../seed/generator.js';
3
- import type { SeedInput } from '../schemas.js';
4
- export declare function handleSeed(engine: InterviewEngine, generator: SeedGenerator, input: SeedInput): Promise<string>;
5
- //# sourceMappingURL=seed.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/seed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,wBAAsB,UAAU,CAC9B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
@@ -1,19 +0,0 @@
1
- export async function handleSeed(engine, generator, input) {
2
- try {
3
- const session = engine.getSession(input.sessionId);
4
- const result = await generator.generate(session, input.force);
5
- if (!result.ok) {
6
- return JSON.stringify({ error: result.error.message }, null, 2);
7
- }
8
- return JSON.stringify({
9
- status: 'generated',
10
- seed: result.value,
11
- }, null, 2);
12
- }
13
- catch (e) {
14
- return JSON.stringify({
15
- error: e instanceof Error ? e.message : String(e),
16
- }, null, 2);
17
- }
18
- }
19
- //# sourceMappingURL=seed.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../../src/mcp/tools/seed.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAuB,EACvB,SAAwB,EACxB,KAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAClE,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,MAAM,EAAE,WAAW;YACnB,IAAI,EAAE,MAAM,CAAC,KAAK;SACnB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACd,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;SAClD,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,25 +0,0 @@
1
- export interface ConvertOptions {
2
- /** 변환 완료 후 .cast 파일을 삭제할지 여부 (기본값: true) */
3
- deleteCastAfter?: boolean;
4
- /** 변환 완료 콜백 (파일 경로 출력 등) */
5
- onComplete?: (outputPath: string) => void;
6
- /** 변환 실패 콜백 */
7
- onError?: (err: Error) => void;
8
- }
9
- /**
10
- * AggConverter: agg 바이너리를 사용해 .cast → GIF 변환을 비동기 백그라운드로 수행한다.
11
- * convert()는 즉시 return하며, 변환은 백그라운드에서 진행된다.
12
- */
13
- export declare class AggConverter {
14
- /**
15
- * .cast 파일을 GIF로 변환한다 (백그라운드 비동기).
16
- * 반환값은 변환 완료를 기다리는 Promise이지만, 호출 측에서 await하지 않아도 된다.
17
- */
18
- convertAsync(castPath: string, outputPath: string, options?: ConvertOptions): Promise<string>;
19
- /**
20
- * GIF → MP4 변환 (ffmpeg 사용).
21
- * agg는 gif만 지원하므로 gifPath → mp4Path 변환은 ffmpeg에 위임한다.
22
- */
23
- convertGifToMp4Async(gifPath: string, mp4Path: string, options?: ConvertOptions): Promise<string>;
24
- }
25
- //# sourceMappingURL=agg-converter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agg-converter.d.ts","sourceRoot":"","sources":["../../../src/recording/agg-converter.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4BAA4B;IAC5B,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,eAAe;IACf,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB;;;OAGG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC;IA6ClB;;;OAGG;IACH,oBAAoB,CAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC;CAiCnB"}
@@ -1,80 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import { unlink } from 'node:fs/promises';
3
- import { dirname } from 'node:path';
4
- import { mkdirSync } from 'node:fs';
5
- /**
6
- * AggConverter: agg 바이너리를 사용해 .cast → GIF 변환을 비동기 백그라운드로 수행한다.
7
- * convert()는 즉시 return하며, 변환은 백그라운드에서 진행된다.
8
- */
9
- export class AggConverter {
10
- /**
11
- * .cast 파일을 GIF로 변환한다 (백그라운드 비동기).
12
- * 반환값은 변환 완료를 기다리는 Promise이지만, 호출 측에서 await하지 않아도 된다.
13
- */
14
- convertAsync(castPath, outputPath, options = {}) {
15
- const { deleteCastAfter = true, onComplete, onError } = options;
16
- mkdirSync(dirname(outputPath), { recursive: true });
17
- return new Promise((resolve, reject) => {
18
- const child = spawn('agg', [castPath, outputPath], {
19
- stdio: ['ignore', 'pipe', 'pipe'],
20
- detached: false,
21
- });
22
- child.stderr?.on('data', (data) => {
23
- const msg = data.toString().trim();
24
- if (msg)
25
- process.stderr.write(`[agg] ${msg}\n`);
26
- });
27
- child.on('close', async (code) => {
28
- if (code !== 0) {
29
- const err = new Error(`agg exited with code ${code}. GIF conversion failed for: ${castPath}`);
30
- onError?.(err);
31
- reject(err);
32
- return;
33
- }
34
- if (deleteCastAfter) {
35
- try {
36
- await unlink(castPath);
37
- }
38
- catch {
39
- // 삭제 실패는 무시
40
- }
41
- }
42
- onComplete?.(outputPath);
43
- resolve(outputPath);
44
- });
45
- child.on('error', (err) => {
46
- onError?.(err);
47
- reject(err);
48
- });
49
- });
50
- }
51
- /**
52
- * GIF → MP4 변환 (ffmpeg 사용).
53
- * agg는 gif만 지원하므로 gifPath → mp4Path 변환은 ffmpeg에 위임한다.
54
- */
55
- convertGifToMp4Async(gifPath, mp4Path, options = {}) {
56
- const { onComplete, onError } = options;
57
- mkdirSync(dirname(mp4Path), { recursive: true });
58
- return new Promise((resolve, reject) => {
59
- const child = spawn('ffmpeg', ['-y', '-i', gifPath, '-movflags', 'faststart', '-pix_fmt', 'yuv420p', mp4Path], { stdio: ['ignore', 'pipe', 'pipe'], detached: false });
60
- child.stderr?.on('data', () => {
61
- // ffmpeg는 stderr에 진행상황 출력 — 무시
62
- });
63
- child.on('close', (code) => {
64
- if (code !== 0) {
65
- const err = new Error(`ffmpeg exited with code ${code}. MP4 conversion failed.`);
66
- onError?.(err);
67
- reject(err);
68
- return;
69
- }
70
- onComplete?.(mp4Path);
71
- resolve(mp4Path);
72
- });
73
- child.on('error', (err) => {
74
- onError?.(err);
75
- reject(err);
76
- });
77
- });
78
- }
79
- }
80
- //# sourceMappingURL=agg-converter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agg-converter.js","sourceRoot":"","sources":["../../../src/recording/agg-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAWpC;;;GAGG;AACH,MAAM,OAAO,YAAY;IACvB;;;OAGG;IACH,YAAY,CACV,QAAgB,EAChB,UAAkB,EAClB,UAA0B,EAAE;QAE5B,MAAM,EAAE,eAAe,GAAG,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAEhE,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE;gBACjD,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;gBACjC,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;YAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACxC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,GAAG;oBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBAC/B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACf,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,wBAAwB,IAAI,gCAAgC,QAAQ,EAAE,CACvE,CAAC;oBACF,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;oBACf,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,OAAO;gBACT,CAAC;gBAED,IAAI,eAAe,EAAE,CAAC;oBACpB,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACzB,CAAC;oBAAC,MAAM,CAAC;wBACP,YAAY;oBACd,CAAC;gBACH,CAAC;gBAED,UAAU,EAAE,CAAC,UAAU,CAAC,CAAC;gBACzB,OAAO,CAAC,UAAU,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACxB,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;gBACf,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,oBAAoB,CAClB,OAAe,EACf,OAAe,EACf,UAA0B,EAAE;QAE5B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAExC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CACjB,QAAQ,EACR,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,EAC/E,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CACvD,CAAC;YAEF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;gBAC5B,+BAA+B;YACjC,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACf,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,2BAA2B,IAAI,0BAA0B,CAAC,CAAC;oBACjF,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;oBACf,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,CAAC,OAAO,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACxB,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;gBACf,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}