@tienne/gestalt 0.17.0 → 0.18.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 (171) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/role-agents/presentation-designer/AGENT.md +211 -0
  3. package/dist/role-agents/presentation-designer/templates/broadside.html +292 -0
  4. package/dist/role-agents/presentation-designer/templates/editorial-forest.html +264 -0
  5. package/dist/role-agents/presentation-designer/templates/emerald-editorial.html +273 -0
  6. package/dist/role-agents/presentation-designer/templates/neo-grid.html +407 -0
  7. package/dist/role-agents/presentation-designer/templates/pin-and-paper.html +225 -0
  8. package/dist/role-agents/presentation-designer/templates/pink-script.html +241 -0
  9. package/dist/role-agents/presentation-designer/templates/sakura-chroma.html +293 -0
  10. package/dist/role-agents/presentation-designer/templates/signal.html +403 -0
  11. package/dist/role-agents/presentation-designer/templates/stencil-tablet.html +211 -0
  12. package/dist/role-agents/presentation-designer/templates/studio.html +379 -0
  13. package/dist/skills/agent/SKILL.md +2 -0
  14. package/dist/skills/seed/SKILL.md +92 -0
  15. package/dist/src/cli/commands/monitor.d.ts +2 -0
  16. package/dist/src/cli/commands/monitor.d.ts.map +1 -0
  17. package/dist/src/cli/commands/monitor.js +13 -0
  18. package/dist/src/cli/commands/monitor.js.map +1 -0
  19. package/dist/src/cli/commands/seed.d.ts +4 -0
  20. package/dist/src/cli/commands/seed.d.ts.map +1 -0
  21. package/dist/src/cli/commands/seed.js +34 -0
  22. package/dist/src/cli/commands/seed.js.map +1 -0
  23. package/dist/src/interview/ambiguity.d.ts +8 -0
  24. package/dist/src/interview/ambiguity.d.ts.map +1 -0
  25. package/dist/src/interview/ambiguity.js +69 -0
  26. package/dist/src/interview/ambiguity.js.map +1 -0
  27. package/dist/src/mcp/tools/seed-passthrough.d.ts +5 -0
  28. package/dist/src/mcp/tools/seed-passthrough.d.ts.map +1 -0
  29. package/dist/src/mcp/tools/seed-passthrough.js +29 -0
  30. package/dist/src/mcp/tools/seed-passthrough.js.map +1 -0
  31. package/dist/src/mcp/tools/seed.d.ts +5 -0
  32. package/dist/src/mcp/tools/seed.d.ts.map +1 -0
  33. package/dist/src/mcp/tools/seed.js +19 -0
  34. package/dist/src/mcp/tools/seed.js.map +1 -0
  35. package/dist/src/recording/agg-converter.d.ts +25 -0
  36. package/dist/src/recording/agg-converter.d.ts.map +1 -0
  37. package/dist/src/recording/agg-converter.js +80 -0
  38. package/dist/src/recording/agg-converter.js.map +1 -0
  39. package/dist/src/recording/agg-installer.d.ts +6 -0
  40. package/dist/src/recording/agg-installer.d.ts.map +1 -0
  41. package/dist/src/recording/agg-installer.js +50 -0
  42. package/dist/src/recording/agg-installer.js.map +1 -0
  43. package/dist/src/recording/asciinema-installer.d.ts +6 -0
  44. package/dist/src/recording/asciinema-installer.d.ts.map +1 -0
  45. package/dist/src/recording/asciinema-installer.js +50 -0
  46. package/dist/src/recording/asciinema-installer.js.map +1 -0
  47. package/dist/src/recording/asciinema-recorder.d.ts +26 -0
  48. package/dist/src/recording/asciinema-recorder.d.ts.map +1 -0
  49. package/dist/src/recording/asciinema-recorder.js +52 -0
  50. package/dist/src/recording/asciinema-recorder.js.map +1 -0
  51. package/dist/src/recording/cast-generator.d.ts +7 -0
  52. package/dist/src/recording/cast-generator.d.ts.map +1 -0
  53. package/dist/src/recording/cast-generator.js +97 -0
  54. package/dist/src/recording/cast-generator.js.map +1 -0
  55. package/dist/src/recording/filename-generator.d.ts +19 -0
  56. package/dist/src/recording/filename-generator.d.ts.map +1 -0
  57. package/dist/src/recording/filename-generator.js +67 -0
  58. package/dist/src/recording/filename-generator.js.map +1 -0
  59. package/dist/src/recording/gif-generator.d.ts +21 -0
  60. package/dist/src/recording/gif-generator.d.ts.map +1 -0
  61. package/dist/src/recording/gif-generator.js +121 -0
  62. package/dist/src/recording/gif-generator.js.map +1 -0
  63. package/dist/src/recording/recording-dir.d.ts +5 -0
  64. package/dist/src/recording/recording-dir.d.ts.map +1 -0
  65. package/dist/src/recording/recording-dir.js +13 -0
  66. package/dist/src/recording/recording-dir.js.map +1 -0
  67. package/dist/src/recording/recording-orchestrator.d.ts +50 -0
  68. package/dist/src/recording/recording-orchestrator.d.ts.map +1 -0
  69. package/dist/src/recording/recording-orchestrator.js +98 -0
  70. package/dist/src/recording/recording-orchestrator.js.map +1 -0
  71. package/dist/src/recording/resume-detector.d.ts +10 -0
  72. package/dist/src/recording/resume-detector.d.ts.map +1 -0
  73. package/dist/src/recording/resume-detector.js +14 -0
  74. package/dist/src/recording/resume-detector.js.map +1 -0
  75. package/dist/src/recording/segment-merger.d.ts +27 -0
  76. package/dist/src/recording/segment-merger.d.ts.map +1 -0
  77. package/dist/src/recording/segment-merger.js +65 -0
  78. package/dist/src/recording/segment-merger.js.map +1 -0
  79. package/dist/src/recording/terminal-recorder.d.ts +31 -0
  80. package/dist/src/recording/terminal-recorder.d.ts.map +1 -0
  81. package/dist/src/recording/terminal-recorder.js +111 -0
  82. package/dist/src/recording/terminal-recorder.js.map +1 -0
  83. package/dist/src/scripts/postinstall.d.ts +2 -0
  84. package/dist/src/scripts/postinstall.d.ts.map +1 -0
  85. package/dist/src/scripts/postinstall.js +29 -0
  86. package/dist/src/scripts/postinstall.js.map +1 -0
  87. package/dist/src/seed/extractor.d.ts +15 -0
  88. package/dist/src/seed/extractor.d.ts.map +1 -0
  89. package/dist/src/seed/extractor.js +88 -0
  90. package/dist/src/seed/extractor.js.map +1 -0
  91. package/dist/src/seed/generator.d.ts +12 -0
  92. package/dist/src/seed/generator.d.ts.map +1 -0
  93. package/dist/src/seed/generator.js +66 -0
  94. package/dist/src/seed/generator.js.map +1 -0
  95. package/dist/src/seed/passthrough-generator.d.ts +31 -0
  96. package/dist/src/seed/passthrough-generator.d.ts.map +1 -0
  97. package/dist/src/seed/passthrough-generator.js +80 -0
  98. package/dist/src/seed/passthrough-generator.js.map +1 -0
  99. package/dist/src/seed/schema.d.ts +145 -0
  100. package/dist/src/seed/schema.d.ts.map +1 -0
  101. package/dist/src/seed/schema.js +37 -0
  102. package/dist/src/seed/schema.js.map +1 -0
  103. package/dist/src/tui/components/TUIApp.d.ts +20 -0
  104. package/dist/src/tui/components/TUIApp.d.ts.map +1 -0
  105. package/dist/src/tui/components/TUIApp.js +84 -0
  106. package/dist/src/tui/components/TUIApp.js.map +1 -0
  107. package/dist/src/tui/hooks/event-store-reader.d.ts +28 -0
  108. package/dist/src/tui/hooks/event-store-reader.d.ts.map +1 -0
  109. package/dist/src/tui/hooks/event-store-reader.js +141 -0
  110. package/dist/src/tui/hooks/event-store-reader.js.map +1 -0
  111. package/dist/src/tui/hooks/useEventStorePoller.d.ts +12 -0
  112. package/dist/src/tui/hooks/useEventStorePoller.d.ts.map +1 -0
  113. package/dist/src/tui/hooks/useEventStorePoller.js +84 -0
  114. package/dist/src/tui/hooks/useEventStorePoller.js.map +1 -0
  115. package/dist/src/tui/screens/DashboardScreen.d.ts +4 -0
  116. package/dist/src/tui/screens/DashboardScreen.d.ts.map +1 -0
  117. package/dist/src/tui/screens/DashboardScreen.js +132 -0
  118. package/dist/src/tui/screens/DashboardScreen.js.map +1 -0
  119. package/dist/src/tui/screens/DebugScreen.d.ts +4 -0
  120. package/dist/src/tui/screens/DebugScreen.d.ts.map +1 -0
  121. package/dist/src/tui/screens/DebugScreen.js +40 -0
  122. package/dist/src/tui/screens/DebugScreen.js.map +1 -0
  123. package/dist/src/tui/screens/EvolutionScreen.d.ts +4 -0
  124. package/dist/src/tui/screens/EvolutionScreen.d.ts.map +1 -0
  125. package/dist/src/tui/screens/EvolutionScreen.js +136 -0
  126. package/dist/src/tui/screens/EvolutionScreen.js.map +1 -0
  127. package/dist/src/tui/screens/HUDPanel.d.ts +4 -0
  128. package/dist/src/tui/screens/HUDPanel.d.ts.map +1 -0
  129. package/dist/src/tui/screens/HUDPanel.js +13 -0
  130. package/dist/src/tui/screens/HUDPanel.js.map +1 -0
  131. package/dist/src/tui/screens/InterviewScreen.d.ts +4 -0
  132. package/dist/src/tui/screens/InterviewScreen.d.ts.map +1 -0
  133. package/dist/src/tui/screens/InterviewScreen.js +103 -0
  134. package/dist/src/tui/screens/InterviewScreen.js.map +1 -0
  135. package/dist/src/tui/screens/LogScreen.d.ts +4 -0
  136. package/dist/src/tui/screens/LogScreen.d.ts.map +1 -0
  137. package/dist/src/tui/screens/LogScreen.js +83 -0
  138. package/dist/src/tui/screens/LogScreen.js.map +1 -0
  139. package/dist/src/tui/screens/SessionListScreen.d.ts +4 -0
  140. package/dist/src/tui/screens/SessionListScreen.d.ts.map +1 -0
  141. package/dist/src/tui/screens/SessionListScreen.js +71 -0
  142. package/dist/src/tui/screens/SessionListScreen.js.map +1 -0
  143. package/dist/src/tui/screens/SpecViewerScreen.d.ts +4 -0
  144. package/dist/src/tui/screens/SpecViewerScreen.d.ts.map +1 -0
  145. package/dist/src/tui/screens/SpecViewerScreen.js +73 -0
  146. package/dist/src/tui/screens/SpecViewerScreen.js.map +1 -0
  147. package/dist/src/tui/widgets/DriftMeter.d.ts +15 -0
  148. package/dist/src/tui/widgets/DriftMeter.d.ts.map +1 -0
  149. package/dist/src/tui/widgets/DriftMeter.js +27 -0
  150. package/dist/src/tui/widgets/DriftMeter.js.map +1 -0
  151. package/dist/src/tui/widgets/GestaltPrincipleBar.d.ts +9 -0
  152. package/dist/src/tui/widgets/GestaltPrincipleBar.d.ts.map +1 -0
  153. package/dist/src/tui/widgets/GestaltPrincipleBar.js +35 -0
  154. package/dist/src/tui/widgets/GestaltPrincipleBar.js.map +1 -0
  155. package/dist/src/tui/widgets/TaskDAGTree.d.ts +15 -0
  156. package/dist/src/tui/widgets/TaskDAGTree.d.ts.map +1 -0
  157. package/dist/src/tui/widgets/TaskDAGTree.js +54 -0
  158. package/dist/src/tui/widgets/TaskDAGTree.js.map +1 -0
  159. package/package.json +1 -1
  160. package/role-agents/presentation-designer/AGENT.md +211 -0
  161. package/role-agents/presentation-designer/templates/broadside.html +292 -0
  162. package/role-agents/presentation-designer/templates/editorial-forest.html +264 -0
  163. package/role-agents/presentation-designer/templates/emerald-editorial.html +273 -0
  164. package/role-agents/presentation-designer/templates/neo-grid.html +407 -0
  165. package/role-agents/presentation-designer/templates/pin-and-paper.html +225 -0
  166. package/role-agents/presentation-designer/templates/pink-script.html +241 -0
  167. package/role-agents/presentation-designer/templates/sakura-chroma.html +293 -0
  168. package/role-agents/presentation-designer/templates/signal.html +403 -0
  169. package/role-agents/presentation-designer/templates/stencil-tablet.html +211 -0
  170. package/role-agents/presentation-designer/templates/studio.html +379 -0
  171. package/skills/agent/SKILL.md +2 -0
@@ -0,0 +1,379 @@
1
+ <!DOCTYPE html>
2
+ <html lang="ko">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Studio — Reveal.js</title>
6
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
7
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
8
+ <link href="https://fonts.googleapis.com/css2?family=Barlow:wght@400;500;700;800;900&family=IBM+Plex+Mono:wght@300;400;500&display=swap" rel="stylesheet" />
9
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.css" />
10
+ <style>
11
+ /* ── DESIGN TOKENS ────────────────────────────────────────────── */
12
+ :root {
13
+ --c-bg: #1c1c1c;
14
+ --c-bg-alt: #242422;
15
+ --c-bg-light: #f5d200;
16
+ --c-bg-light-alt: #f0cc00;
17
+ --c-fg: #f5d200;
18
+ --c-fg-2: rgba(245, 210, 0, 0.58);
19
+ --c-fg-3: rgba(245, 210, 0, 0.32);
20
+ --c-fg-light: #1c1c1c;
21
+ --c-fg-light-2: rgba(28, 28, 28, 0.62);
22
+ --c-fg-light-3: rgba(28, 28, 28, 0.35);
23
+ --c-accent: #f5d200;
24
+ --c-border: #2e2e2c;
25
+ --c-border-light: rgba(28, 28, 28, 0.18);
26
+ --f-display: "Barlow", sans-serif;
27
+ --f-body: "Barlow", sans-serif;
28
+ --f-mono: "IBM Plex Mono", monospace;
29
+ --sz-display: 12vw;
30
+ --sz-h1: 7.5vw;
31
+ --sz-h2: 4.8vw;
32
+ --sz-h3: 2.8vw;
33
+ --sz-lead: 1.6vw;
34
+ --sz-body: 1.15vw;
35
+ --sz-caption: 0.85vw;
36
+ --sz-label: 0.72vw;
37
+ --pad-x: 5vw;
38
+ --pad-y: 5vh;
39
+ --gap-lg: 3.5vh;
40
+ --gap-md: 2vh;
41
+ --gap-sm: 1vh;
42
+ --ease-enter: cubic-bezier(0.16, 1, 0.3, 1);
43
+ }
44
+
45
+ /* ── REVEAL RESET ─────────────────────────────────────────────── */
46
+ .reveal { font-family: var(--f-body); }
47
+ .reveal .slides { text-align: left; }
48
+ .reveal .slides section {
49
+ box-sizing: border-box;
50
+ width: 100%;
51
+ height: 100%;
52
+ padding: var(--pad-y) var(--pad-x);
53
+ display: grid;
54
+ grid-template-rows: auto 1fr auto;
55
+ overflow: hidden;
56
+ top: 0 !important;
57
+ left: 0 !important;
58
+ }
59
+ .reveal h1, .reveal h2, .reveal h3, .reveal h4,
60
+ .reveal p, .reveal ul, .reveal ol { margin: 0; }
61
+ .reveal .slides section.dark { background: var(--c-bg); color: var(--c-fg); }
62
+ .reveal .slides section.light { background: var(--c-bg-light); color: var(--c-fg-light); }
63
+
64
+ /* ── CHROME / FOOTER ──────────────────────────────────────────── */
65
+ .slide-chrome, .slide-foot {
66
+ display: flex;
67
+ justify-content: space-between;
68
+ align-items: center;
69
+ position: relative;
70
+ z-index: 1;
71
+ }
72
+ .dark .slide-chrome { border-bottom: 1px solid var(--c-border); padding-bottom: var(--gap-sm); margin-bottom: var(--gap-md); }
73
+ .dark .slide-foot { border-top: 1px solid var(--c-border); padding-top: var(--gap-sm); margin-top: var(--gap-md); }
74
+ .light .slide-chrome { border-bottom: 1px solid var(--c-border-light); padding-bottom: var(--gap-sm); margin-bottom: var(--gap-md); }
75
+ .light .slide-foot { border-top: 1px solid var(--c-border-light); padding-top: var(--gap-sm); margin-top: var(--gap-md); }
76
+ .slide-body { min-height: 0; }
77
+
78
+ /* ── SLIDE VARIANTS ───────────────────────────────────────────── */
79
+ .slide--cover, .slide--chapter, .slide--quote, .slide--end, .slide--statement {
80
+ display: flex !important;
81
+ flex-direction: column;
82
+ }
83
+ .slide--cover .slide-chrome, .slide--cover .slide-foot,
84
+ .slide--chapter .slide-chrome, .slide--chapter .slide-foot,
85
+ .slide--quote .slide-chrome, .slide--quote .slide-foot,
86
+ .slide--end .slide-chrome, .slide--end .slide-foot,
87
+ .slide--statement .slide-chrome, .slide--statement .slide-foot { display: none; }
88
+
89
+ .slide--cover { justify-content: flex-end; }
90
+ .slide--chapter { justify-content: flex-end; }
91
+ .slide--statement { justify-content: center; }
92
+ .slide--quote { justify-content: center; }
93
+ .slide--end { justify-content: space-between; }
94
+
95
+ .slide--split .slide-body { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-md); align-items: center; }
96
+ .slide--stats .slide-body { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--gap-md); }
97
+ .slide--list .slide-body { display: grid; grid-template-columns: 2fr 3fr; gap: var(--gap-md); }
98
+ .slide--compare .slide-body { display: grid; grid-template-columns: 1fr 1fr; height: 100%; }
99
+
100
+ /* ── TYPOGRAPHY ───────────────────────────────────────────────── */
101
+ .display { font-size: var(--sz-display); font-weight: 900; line-height: 0.9; letter-spacing: -0.02em; text-transform: uppercase; }
102
+ .h1 { font-size: var(--sz-h1); font-weight: 900; line-height: 0.92; letter-spacing: -0.02em; text-transform: uppercase; }
103
+ .h2 { font-size: var(--sz-h2); font-weight: 900; line-height: 0.95; letter-spacing: -0.01em; text-transform: uppercase; }
104
+ .h3 { font-size: var(--sz-h3); font-weight: 700; line-height: 1.1; text-transform: uppercase; }
105
+ .lead { font-size: var(--sz-lead); font-weight: 500; line-height: 1.45; }
106
+ .body { font-size: var(--sz-body); font-weight: 400; line-height: 1.6; }
107
+ .caption { font-size: var(--sz-caption); line-height: 1.5; }
108
+ .label { font-family: var(--f-mono); font-size: var(--sz-label); font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; }
109
+ .kicker { font-family: var(--f-mono); font-size: var(--sz-label); letter-spacing: 0.12em; text-transform: uppercase; color: var(--c-accent); display: block; margin-bottom: var(--gap-sm); }
110
+ .dark .kicker { color: var(--c-accent); }
111
+ .light .kicker { color: var(--c-fg-light-2); }
112
+ .muted { opacity: 0.55; }
113
+ .accent { color: var(--c-accent); }
114
+
115
+ /* ── COMPONENTS ───────────────────────────────────────────────── */
116
+ .rule { width: 36px; height: 2px; background: var(--c-accent); margin: var(--gap-sm) 0; }
117
+ .light .rule { background: var(--c-fg-light); }
118
+
119
+ .img-placeholder {
120
+ background: var(--c-bg-alt);
121
+ width: 100%; height: 100%; min-height: 25vh;
122
+ display: flex; align-items: center; justify-content: center;
123
+ font-family: var(--f-mono); font-size: var(--sz-label); letter-spacing: 0.1em;
124
+ color: var(--c-fg-3);
125
+ }
126
+
127
+ .bullet-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--gap-sm); }
128
+ .bullet-list li { display: flex; gap: 0.75em; font-size: var(--sz-body); line-height: 1.6; }
129
+ .dark .bullet-list li::before { content: "—"; color: var(--c-accent); flex-shrink: 0; }
130
+ .light .bullet-list li::before { content: "—"; color: var(--c-fg-light); flex-shrink: 0; }
131
+
132
+ .stat-val { font-size: 6vw; font-weight: 900; line-height: 1; }
133
+ .stat-unit { font-size: 2.5vw; font-weight: 900; }
134
+
135
+ /* ── BAR CHART ────────────────────────────────────────────────── */
136
+ .bar-chart { display: flex; align-items: flex-end; gap: 1.5vw; height: 22vh; }
137
+ .bar-col { display: flex; flex-direction: column; align-items: center; gap: 0.5vh; flex: 1; }
138
+ .bar-track { flex: 1; width: 100%; display: flex; align-items: flex-end; border-left: 2px solid var(--c-fg-3); }
139
+ .bar-fill { width: 100%; background: var(--c-fg-3); transition: height 0.6s var(--ease-enter); }
140
+ .bar-fill.hi { background: var(--c-accent); }
141
+ .bar-label { font-family: var(--f-mono); font-size: 0.65vw; text-align: center; opacity: 0.6; }
142
+
143
+ /* ── ANIMATIONS ───────────────────────────────────────────────── */
144
+ [data-anim] { opacity: 0; animation-fill-mode: forwards; animation-timing-function: var(--ease-enter); animation-duration: 0.55s; }
145
+ [data-anim][data-delay="0"] { animation-delay: 0s; }
146
+ [data-anim][data-delay="1"] { animation-delay: 0.08s; }
147
+ [data-anim][data-delay="2"] { animation-delay: 0.18s; }
148
+ [data-anim][data-delay="3"] { animation-delay: 0.3s; }
149
+ [data-anim][data-delay="4"] { animation-delay: 0.44s; }
150
+ [data-anim][data-delay="5"] { animation-delay: 0.6s; }
151
+ .reveal .present [data-anim="fade-up"] { animation-name: kFadeUp; }
152
+ .reveal .present [data-anim="fade-in"] { animation-name: kFadeIn; }
153
+ .reveal .present [data-anim="reveal-right"] { animation-name: kRevealRight; opacity: 1; }
154
+ .reveal .present [data-anim="scale-in"] { animation-name: kScaleIn; }
155
+ @keyframes kFadeUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
156
+ @keyframes kFadeIn { from { opacity: 0; } to { opacity: 1; } }
157
+ @keyframes kRevealRight { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
158
+ @keyframes kScaleIn { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }
159
+
160
+ /* ── REVEAL UI OVERRIDES ──────────────────────────────────────── */
161
+ .reveal .controls { color: var(--c-accent); }
162
+ .reveal .progress { color: var(--c-accent); }
163
+ .reveal .slide-number { font-family: var(--f-mono); background: transparent; color: var(--c-fg-3); font-size: 0.6em; }
164
+ </style>
165
+ </head>
166
+ <body style="margin:0;background:#111">
167
+ <div class="reveal">
168
+ <div class="slides">
169
+
170
+ <!-- ════════════════════════════════════════════════
171
+ COVER — image + overlay text
172
+ ════════════════════════════════════════════════ -->
173
+ <section class="dark slide--cover">
174
+ <div style="flex:1;position:relative">
175
+ <div class="img-placeholder">IMAGE</div>
176
+ </div>
177
+ <div class="slide-body" style="padding-top:var(--gap-md)">
178
+ <span class="kicker" data-anim="fade-in" data-delay="0">{{ORGANIZATION}}</span>
179
+ <div class="display" data-anim="fade-up" data-delay="1">{{TITLE}}</div>
180
+ <div class="rule" data-anim="reveal-right" data-delay="2" style="margin-top:1.5vh"></div>
181
+ <div style="display:flex;justify-content:space-between;margin-top:1.5vh" data-anim="fade-in" data-delay="3">
182
+ <span class="label muted">{{DATE}}</span>
183
+ <span class="label muted">{{AUTHOR}}</span>
184
+ </div>
185
+ </div>
186
+ </section>
187
+
188
+ <!-- ════════════════════════════════════════════════
189
+ CHAPTER DIVIDER (light background)
190
+ ════════════════════════════════════════════════ -->
191
+ <section class="light slide--chapter">
192
+ <div class="slide-body" style="display:flex;flex-direction:column;justify-content:flex-end;gap:var(--gap-sm)">
193
+ <span class="kicker" data-anim="fade-in" data-delay="0">01 — ģ„¹ģ…˜ėŖ…</span>
194
+ <div class="h1" data-anim="fade-up" data-delay="1">챕터<br>제목</div>
195
+ <div class="rule" data-anim="reveal-right" data-delay="2"></div>
196
+ <p class="body muted" data-anim="fade-up" data-delay="3">ģ„œėøŒ 설명</p>
197
+ </div>
198
+ </section>
199
+
200
+ <!-- ════════════════════════════════════════════════
201
+ STATS — 3-column (dark)
202
+ ════════════════════════════════════════════════ -->
203
+ <section class="dark">
204
+ <div class="slide-chrome">
205
+ <span class="label muted">{{SECTION_LABEL}}</span>
206
+ <span class="label muted">01 / ģ§€ķ‘œ</span>
207
+ </div>
208
+ <div class="slide-body slide--stats">
209
+ <div style="border-top:1px solid var(--c-border);padding-top:var(--gap-sm)" data-anim="fade-up" data-delay="1">
210
+ <div class="stat-val accent">98<span class="stat-unit">%</span></div>
211
+ <div class="rule"></div>
212
+ <p class="body" style="margin-top:var(--gap-sm)">ģ§€ķ‘œėŖ…</p>
213
+ <p class="caption muted">ģ „źø° ėŒ€ė¹„ +12%p</p>
214
+ </div>
215
+ <div style="border-top:1px solid var(--c-border);padding-top:var(--gap-sm)" data-anim="fade-up" data-delay="2">
216
+ <div class="stat-val accent">2.4<span class="stat-unit">s</span></div>
217
+ <div class="rule"></div>
218
+ <p class="body" style="margin-top:var(--gap-sm)">ģ§€ķ‘œėŖ…</p>
219
+ <p class="caption muted">ėŖ©ķ‘œģ¹˜ 3s 달성</p>
220
+ </div>
221
+ <div style="border-top:1px solid var(--c-border);padding-top:var(--gap-sm)" data-anim="fade-up" data-delay="3">
222
+ <div class="stat-val accent">41</div>
223
+ <div class="rule"></div>
224
+ <p class="body" style="margin-top:var(--gap-sm)">ģ§€ķ‘œėŖ…</p>
225
+ <p class="caption muted">ėˆ„ģ  ģ“ 186개</p>
226
+ </div>
227
+ </div>
228
+ <div class="slide-foot">
229
+ <span class="label muted">{{ORG}} Ā· {{DATE}}</span>
230
+ </div>
231
+ </section>
232
+
233
+ <!-- ════════════════════════════════════════════════
234
+ SPLIT — text + list (light)
235
+ ════════════════════════════════════════════════ -->
236
+ <section class="light">
237
+ <div class="slide-chrome">
238
+ <span class="label" style="color:var(--c-fg-light-2)">{{SECTION_LABEL}}</span>
239
+ <span class="label" style="color:var(--c-fg-light-3)">01 / ė¶„ģ„</span>
240
+ </div>
241
+ <div class="slide-body slide--split">
242
+ <div data-anim="fade-up" data-delay="1">
243
+ <span class="kicker">Topic</span>
244
+ <div class="h2">ģŠ¬ė¼ģ“ė“œ<br>제목</div>
245
+ <div class="rule"></div>
246
+ </div>
247
+ <div data-anim="fade-up" data-delay="2">
248
+ <ul class="bullet-list">
249
+ <li>ķ•­ėŖ© 1 — 설명</li>
250
+ <li>ķ•­ėŖ© 2 — 설명</li>
251
+ <li>ķ•­ėŖ© 3 — 설명</li>
252
+ <li>ķ•­ėŖ© 4 — 설명</li>
253
+ </ul>
254
+ </div>
255
+ </div>
256
+ <div class="slide-foot" style="border-color:var(--c-border-light)">
257
+ <span class="label" style="color:var(--c-fg-light-3)">{{ORG}} Ā· {{DATE}}</span>
258
+ </div>
259
+ </section>
260
+
261
+ <!-- ════════════════════════════════════════════════
262
+ BAR CHART (dark)
263
+ ════════════════════════════════════════════════ -->
264
+ <section class="dark">
265
+ <div class="slide-chrome">
266
+ <span class="label muted">{{SECTION_LABEL}}</span>
267
+ <span class="label muted">01 / ė°ģ“ķ„°</span>
268
+ </div>
269
+ <div class="slide-body" style="display:flex;flex-direction:column;justify-content:flex-end;gap:var(--gap-lg)">
270
+ <div data-anim="fade-up" data-delay="0">
271
+ <span class="kicker">Chart Title</span>
272
+ <div class="h2">ė°ģ“ķ„° 비교</div>
273
+ </div>
274
+ <div class="bar-chart" data-anim="scale-in" data-delay="2">
275
+ <div class="bar-col"><div class="bar-track"><div class="bar-fill" style="height:85%"></div></div><span class="bar-label">ķ•­ėŖ© A</span></div>
276
+ <div class="bar-col"><div class="bar-track"><div class="bar-fill hi" style="height:60%"></div></div><span class="bar-label">ķ•­ėŖ© B</span></div>
277
+ <div class="bar-col"><div class="bar-track"><div class="bar-fill" style="height:48%"></div></div><span class="bar-label">ķ•­ėŖ© C</span></div>
278
+ <div class="bar-col"><div class="bar-track"><div class="bar-fill" style="height:38%"></div></div><span class="bar-label">ķ•­ėŖ© D</span></div>
279
+ </div>
280
+ </div>
281
+ <div class="slide-foot">
282
+ <span class="label muted">{{ORG}} Ā· {{DATE}}</span>
283
+ </div>
284
+ </section>
285
+
286
+ <!-- ════════════════════════════════════════════════
287
+ LIST — heading + bullets (dark)
288
+ ════════════════════════════════════════════════ -->
289
+ <section class="dark">
290
+ <div class="slide-chrome">
291
+ <span class="label muted">{{SECTION_LABEL}}</span>
292
+ <span class="label muted">02 / ź³„ķš</span>
293
+ </div>
294
+ <div class="slide-body slide--list">
295
+ <div data-anim="fade-up" data-delay="1">
296
+ <span class="kicker">{{PERIOD}}</span>
297
+ <div class="h2">ģ£¼ģš”<br>과제</div>
298
+ <div class="rule"></div>
299
+ </div>
300
+ <div data-anim="fade-up" data-delay="2">
301
+ <ul class="bullet-list">
302
+ <li>ķ•  ģ¼ 1</li>
303
+ <li>ķ•  ģ¼ 2</li>
304
+ <li>ķ•  ģ¼ 3</li>
305
+ <li>ķ•  ģ¼ 4</li>
306
+ <li>ķ•  ģ¼ 5</li>
307
+ </ul>
308
+ </div>
309
+ </div>
310
+ <div class="slide-foot">
311
+ <span class="label muted">{{ORG}} Ā· {{DATE}}</span>
312
+ </div>
313
+ </section>
314
+
315
+ <!-- ════════════════════════════════════════════════
316
+ STATEMENT — full-screen (dark)
317
+ ════════════════════════════════════════════════ -->
318
+ <section class="dark slide--statement">
319
+ <div class="slide-body" style="display:flex;flex-direction:column;justify-content:center">
320
+ <div class="display" data-anim="fade-up" data-delay="0">선언문<br>ė˜ėŠ” ķ…Œģ œ</div>
321
+ <div class="rule" data-anim="reveal-right" data-delay="2" style="margin-top:2vh"></div>
322
+ <p class="body muted" data-anim="fade-up" data-delay="3" style="margin-top:var(--gap-sm)">— 출처 / ė§„ė½</p>
323
+ </div>
324
+ </section>
325
+
326
+ <!-- ════════════════════════════════════════════════
327
+ QUOTE (dark)
328
+ ════════════════════════════════════════════════ -->
329
+ <section class="dark slide--quote">
330
+ <div class="slide-body" style="display:flex;flex-direction:column;justify-content:center;gap:var(--gap-md)">
331
+ <div class="rule" data-anim="reveal-right" data-delay="0"></div>
332
+ <div class="h1" data-anim="fade-up" data-delay="1">"ģøģš©ė¬øģ„<br>크게 볓여줄 ė•Œ"</div>
333
+ <p class="label muted" data-anim="fade-in" data-delay="3">— ė°œģ–øģž, ė§„ė½</p>
334
+ </div>
335
+ </section>
336
+
337
+ <!-- ════════════════════════════════════════════════
338
+ END / Q&A (light)
339
+ ════════════════════════════════════════════════ -->
340
+ <section class="light slide--end">
341
+ <div style="padding-top:var(--pad-y)" data-anim="fade-up" data-delay="0">
342
+ <span class="kicker">ź°ģ‚¬ķ•©ė‹ˆė‹¤</span>
343
+ <div class="display">Q&amp;A</div>
344
+ <div class="rule" style="margin-top:2vh"></div>
345
+ </div>
346
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--gap-md);padding-bottom:var(--pad-y)" data-anim="fade-up" data-delay="2">
347
+ <div>
348
+ <p class="label" style="color:var(--c-fg-light-2)">ģ“ė©”ģ¼</p>
349
+ <p class="body">{{EMAIL}}</p>
350
+ </div>
351
+ <div>
352
+ <p class="label" style="color:var(--c-fg-light-2)">ģ†Œģ†</p>
353
+ <p class="body">{{ORG}}</p>
354
+ </div>
355
+ </div>
356
+ </section>
357
+
358
+ </div>
359
+ </div>
360
+ <script src="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.js"></script>
361
+ <script src="https://cdn.jsdelivr.net/npm/reveal.js@5/plugin/notes/notes.js"></script>
362
+ <script>
363
+ Reveal.initialize({
364
+ hash: true,
365
+ width: 1600,
366
+ height: 900,
367
+ margin: 0,
368
+ minScale: 0.1,
369
+ maxScale: 1.5,
370
+ controls: true,
371
+ progress: true,
372
+ slideNumber: 'c/t',
373
+ transition: 'fade',
374
+ backgroundTransition: 'fade',
375
+ plugins: [RevealNotes],
376
+ });
377
+ </script>
378
+ </body>
379
+ </html>
@@ -35,6 +35,7 @@ Invoke any Gestalt Role or Review agent directly, outside the Gestalt pipeline.
35
35
  /agent backend-developer "is this REST API design consistent?"
36
36
  /agent qa-engineer "what edge cases am I missing for this login flow?"
37
37
  /agent frontend-developer "review this React component for accessibility issues"
38
+ /agent presentation-designer "ė¶„źø° 실적 ė°œķ‘œģš© Reveal.js ģŠ¬ė¼ģ“ė“œ 구씰 ģ„¤ź³„ķ•“ģ¤˜"
38
39
 
39
40
  # Run a Review Agent
40
41
  /agent security-reviewer "check this authentication code for vulnerabilities"
@@ -53,6 +54,7 @@ Invoke any Gestalt Role or Review agent directly, outside the Gestalt pipeline.
53
54
  | `backend-developer` | API, database, authentication, server |
54
55
  | `frontend-developer` | UI, React, accessibility |
55
56
  | `designer` | UX/UI, design systems, interaction |
57
+ | `presentation-designer` | Reveal.js slides, storytelling, visual design for decks |
56
58
  | `qa-engineer` | Testing, edge cases, quality |
57
59
  | `devops-engineer` | CI/CD, infrastructure, monitoring |
58
60
  | `product-planner` | Requirements, roadmap, user stories |
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: seed
3
+ version: "1.0.0"
4
+ description: "Generate a Seed specification from a completed interview"
5
+ triggers:
6
+ - "generate seed"
7
+ - "create spec"
8
+ - "build seed"
9
+ inputs:
10
+ sessionId:
11
+ type: string
12
+ required: true
13
+ description: "The interview session ID to generate a seed from"
14
+ force:
15
+ type: boolean
16
+ required: false
17
+ description: "Force generation even if ambiguity threshold is not met"
18
+ outputs:
19
+ - seed
20
+ ---
21
+
22
+ # Seed Generation Skill
23
+
24
+ This skill transforms completed interview data into a structured project specification (Seed).
25
+
26
+ ## Output Structure
27
+
28
+ - **Goal**: Clear project objective
29
+ - **Constraints**: Technical and business constraints
30
+ - **Acceptance Criteria**: Measurable success conditions
31
+ - **Ontology Schema**: Entity-relationship model
32
+ - **Gestalt Analysis**: Findings from each principle applied
33
+
34
+ ## Requirements
35
+
36
+ - Interview session must be in `completed` status
37
+ - Ambiguity score must be ≤ 0.2 (unless `force` is true)
38
+
39
+ ## Passthrough Mode
40
+
41
+ API 키 ģ—†ģ“ MCP ģ„œė²„ 실행 ģ‹œ ģžė™ ķ™œģ„±ķ™”. Seed ģƒģ„±ģ„ callerź°€ 직접 ģˆ˜ķ–‰ķ•œė‹¤.
42
+
43
+ ### 추가 Input ķŒŒė¼ėÆøķ„°
44
+
45
+ | ķŒŒė¼ėÆøķ„° | ķƒ€ģž… | ķ•„ģˆ˜ | 설명 |
46
+ |---------|------|------|------|
47
+ | `seed` | object | 2ė‹Øź³„ģ—ģ„œ ķ•„ģˆ˜ | callerź°€ ģƒģ„±ķ•œ Seed JSON |
48
+ | `seed.goal` | string | ķ•„ģˆ˜ | ķ”„ė”œģ ķŠø ėŖ©ķ‘œ |
49
+ | `seed.constraints` | string[] | ķ•„ģˆ˜ | 기술/ė¹„ģ¦ˆė‹ˆģŠ¤ ģ œģ•½ģ”°ź±“ |
50
+ | `seed.acceptanceCriteria` | string[] | ķ•„ģˆ˜ | 수용 기준 |
51
+ | `seed.ontologySchema` | object | ķ•„ģˆ˜ | 엔티티-꓀계 ėŖØėø |
52
+ | `seed.gestaltAnalysis` | array | ķ•„ģˆ˜ | 게슈탈트 ė¶„ģ„ ź²°ź³¼ |
53
+
54
+ ### 2단계 ķ”Œė”œģš°
55
+
56
+ **1단계: SeedContext ģš”ģ²­**
57
+ ```
58
+ ges_generate_seed({ sessionId: "<id>" })
59
+ ```
60
+ → `{ status: "prompt", seedContext, message }` ė°˜ķ™˜
61
+
62
+ SeedContext ķ•„ė“œ:
63
+ - `systemPrompt`: Seed ģƒģ„±ģš© ģ‹œģŠ¤ķ…œ ķ”„ė”¬ķ”„ķŠø
64
+ - `seedPrompt`: ģøķ„°ė·° ė‚“ģš© 기반 Seed ģƒģ„± ķ”„ė”¬ķ”„ķŠø
65
+ - `allRounds[]`: `{ roundNumber, question, response, gestaltFocus }`
66
+
67
+ **2단계: Seed 제출 ė° ź²€ģ¦**
68
+ ```
69
+ ges_generate_seed({
70
+ sessionId: "<id>",
71
+ seed: {
72
+ goal: "ėŖ…ķ™•ķ•œ ķ”„ė”œģ ķŠø ėŖ©ķ‘œ",
73
+ constraints: ["TypeScript ģ‚¬ģš©", "REST API"],
74
+ acceptanceCriteria: ["ģ‘ė‹µ ģ‹œź°„ 200ms ģ“ķ•˜"],
75
+ ontologySchema: {
76
+ entities: [{ name: "User", description: "...", attributes: ["id", "email"] }],
77
+ relations: [{ from: "User", to: "Order", type: "has_many" }]
78
+ },
79
+ gestaltAnalysis: [
80
+ { principle: "closure", finding: "ģøģ¦ ģš”źµ¬ģ‚¬ķ•­ ģ™„ģ „ķžˆ ķŒŒģ•…ėØ", confidence: 0.9 }
81
+ ]
82
+ }
83
+ })
84
+ ```
85
+ → `{ status: "generated", seed }` (metadata ģžė™ ģƒģ„± ķ¬ķ•Ø) ė˜ėŠ” `{ error }` ė°˜ķ™˜
86
+
87
+ ### Seed ź²€ģ¦ ģŠ¤ķ‚¤ė§ˆ (Zod)
88
+
89
+ - `gestaltAnalysis[].principle`: `closure | proximity | similarity | figure_ground | continuity`
90
+ - `gestaltAnalysis[].confidence`: 0.0 ~ 1.0
91
+ - `ontologySchema.entities[]`: `{ name: string(min 1), description: string, attributes: string[] }`
92
+ - `ontologySchema.relations[]`: `{ from: string(min 1), to: string(min 1), type: string(min 1) }`
@@ -0,0 +1,2 @@
1
+ export declare function monitorCommand(sessionId?: string): Promise<void>;
2
+ //# sourceMappingURL=monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/monitor.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtE"}
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { render } from 'ink';
3
+ import { loadConfig } from '../../core/config.js';
4
+ import { TUIApp } from '../../tui/components/TUIApp.js';
5
+ export async function monitorCommand(sessionId) {
6
+ const config = loadConfig();
7
+ const { waitUntilExit } = render(React.createElement(TUIApp, {
8
+ dbPath: config.dbPath,
9
+ initialSessionId: sessionId,
10
+ }));
11
+ await waitUntilExit();
12
+ }
13
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../../src/cli/commands/monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAkB;IACrD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAC9B,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;QAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,gBAAgB,EAAE,SAAS;KAC5B,CAAC,CACH,CAAC;IAEF,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function seedCommand(sessionId: string, options: {
2
+ force?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,34 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,8 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,69 @@
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