wiggum-cli 0.11.2 → 0.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +2 -1
- package/dist/generator/writer.d.ts.map +1 -1
- package/dist/generator/writer.js +39 -1
- package/dist/generator/writer.js.map +1 -1
- package/dist/templates/config/.gitignore.tmpl +9 -0
- package/dist/templates/scripts/feature-loop.sh.tmpl +7 -2
- package/dist/tui/orchestration/interview-orchestrator.d.ts.map +1 -1
- package/dist/tui/orchestration/interview-orchestrator.js +33 -1
- package/dist/tui/orchestration/interview-orchestrator.js.map +1 -1
- package/dist/tui/screens/InterviewScreen.js +1 -1
- package/dist/tui/screens/InterviewScreen.js.map +1 -1
- package/dist/tui/utils/loop-status.d.ts.map +1 -1
- package/dist/tui/utils/loop-status.js +4 -2
- package/dist/tui/utils/loop-status.js.map +1 -1
- package/package.json +1 -1
- package/src/generator/writer.ts +41 -0
- package/src/templates/config/.gitignore.tmpl +9 -0
- package/src/templates/scripts/feature-loop.sh.tmpl +7 -2
- package/src/tui/orchestration/interview-orchestrator.ts +37 -1
- package/src/tui/screens/InterviewScreen.tsx +1 -1
- package/src/tui/utils/loop-status.ts +4 -2
- package/.ralph/TUI-ARCHITECTURE.md +0 -1142
- package/.ralph/TUI-IMPROVEMENT-PROPOSAL.md +0 -756
|
@@ -1,1142 +0,0 @@
|
|
|
1
|
-
# Wiggum CLI - TUI Architecture Specification
|
|
2
|
-
|
|
3
|
-
> Comprehensive documentation of the Terminal User Interface layer for UX review and improvement.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
|
|
9
|
-
1. [Overview](#1-overview)
|
|
10
|
-
2. [Entry Points & Initialization](#2-entry-points--initialization)
|
|
11
|
-
3. [Screen Architecture](#3-screen-architecture)
|
|
12
|
-
4. [Component Library](#4-component-library)
|
|
13
|
-
5. [State Management](#5-state-management)
|
|
14
|
-
6. [Navigation Patterns](#6-navigation-patterns)
|
|
15
|
-
7. [Input Handling](#7-input-handling)
|
|
16
|
-
8. [Theme & Visual System](#8-theme--visual-system)
|
|
17
|
-
9. [User Flows](#9-user-flows)
|
|
18
|
-
10. [Current Issues & Pain Points](#10-current-issues--pain-points)
|
|
19
|
-
11. [Out of Scope](#11-out-of-scope)
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 1. Overview
|
|
24
|
-
|
|
25
|
-
### Technology Stack
|
|
26
|
-
|
|
27
|
-
| Layer | Technology | Purpose |
|
|
28
|
-
|-------|------------|---------|
|
|
29
|
-
| Runtime | Node.js ≥18 | JavaScript execution |
|
|
30
|
-
| UI Framework | Ink 5.x | React for CLI rendering |
|
|
31
|
-
| React | 18.x | Component model |
|
|
32
|
-
| Input | ink-text-input | Text input handling |
|
|
33
|
-
| Entry | Commander.js | CLI argument parsing |
|
|
34
|
-
|
|
35
|
-
### Architecture Pattern
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
39
|
-
│ User Terminal │
|
|
40
|
-
└─────────────────────────────────────────────────────────────┘
|
|
41
|
-
│
|
|
42
|
-
▼
|
|
43
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
44
|
-
│ Entry Point (index.ts) │
|
|
45
|
-
│ • Mode detection (TUI vs CLI) │
|
|
46
|
-
│ • Session state initialization │
|
|
47
|
-
│ • Provider/config loading │
|
|
48
|
-
└─────────────────────────────────────────────────────────────┘
|
|
49
|
-
│
|
|
50
|
-
▼
|
|
51
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
52
|
-
│ App.tsx (Router) │
|
|
53
|
-
│ • Screen navigation state │
|
|
54
|
-
│ • SessionState propagation │
|
|
55
|
-
│ • Completion/exit callbacks │
|
|
56
|
-
└─────────────────────────────────────────────────────────────┘
|
|
57
|
-
│
|
|
58
|
-
┌───────────────────┼───────────────────┐
|
|
59
|
-
▼ ▼ ▼
|
|
60
|
-
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
61
|
-
│ WelcomeScreen │ │ MainShell │ │ InitScreen │
|
|
62
|
-
│ │ │ │ │ │
|
|
63
|
-
│ • ASCII banner │ │ • REPL loop │ │ • Multi-phase │
|
|
64
|
-
│ • Press Enter │ │ • Commands │ │ • Provider │
|
|
65
|
-
└─────────────────┘ │ • Navigation │ │ • AI analysis │
|
|
66
|
-
└─────────────────┘ └─────────────────┘
|
|
67
|
-
│
|
|
68
|
-
▼
|
|
69
|
-
┌─────────────────┐
|
|
70
|
-
│ InterviewScreen │
|
|
71
|
-
│ │
|
|
72
|
-
│ • Spec gen │
|
|
73
|
-
│ • Q&A flow │
|
|
74
|
-
│ • Streaming │
|
|
75
|
-
└─────────────────┘
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 2. Entry Points & Initialization
|
|
81
|
-
|
|
82
|
-
### File: `src/index.ts`
|
|
83
|
-
|
|
84
|
-
### Startup Function
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
startInkTui(initialScreen: AppScreen = 'welcome', interviewFeature?: string)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Initialization Sequence
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
1. Detect project root (cwd)
|
|
94
|
-
│
|
|
95
|
-
▼
|
|
96
|
-
2. Check config exists? ──────────────────┐
|
|
97
|
-
hasConfig(projectRoot) │
|
|
98
|
-
│ │
|
|
99
|
-
┌────┴────┐ │
|
|
100
|
-
│ YES │ NO │
|
|
101
|
-
▼ ▼ │
|
|
102
|
-
3a. Load 3b. Set │
|
|
103
|
-
config initialized=false │
|
|
104
|
-
│ │
|
|
105
|
-
▼ │
|
|
106
|
-
4. Detect available provider ◄────────────┘
|
|
107
|
-
getAvailableProvider()
|
|
108
|
-
(checks env vars: ANTHROPIC_API_KEY,
|
|
109
|
-
OPENAI_API_KEY, OPENROUTER_API_KEY)
|
|
110
|
-
│
|
|
111
|
-
▼
|
|
112
|
-
5. Create SessionState
|
|
113
|
-
{
|
|
114
|
-
projectRoot,
|
|
115
|
-
provider,
|
|
116
|
-
model (defaults based on provider),
|
|
117
|
-
config,
|
|
118
|
-
initialized
|
|
119
|
-
}
|
|
120
|
-
│
|
|
121
|
-
▼
|
|
122
|
-
6. Render App with sessionState
|
|
123
|
-
render(<App sessionState={...} />)
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### SessionState Interface
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
interface SessionState {
|
|
130
|
-
projectRoot: string;
|
|
131
|
-
provider: AIProvider | null; // 'anthropic' | 'openai' | 'openrouter'
|
|
132
|
-
model: string;
|
|
133
|
-
config: RalphConfig | null;
|
|
134
|
-
initialized: boolean;
|
|
135
|
-
scanResult?: ScanResult; // Cached from /init
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Model Defaults by Provider
|
|
140
|
-
|
|
141
|
-
| Provider | Default Model |
|
|
142
|
-
|----------|---------------|
|
|
143
|
-
| anthropic | claude-sonnet-4-20250514 |
|
|
144
|
-
| openai | gpt-4.1 |
|
|
145
|
-
| openrouter | anthropic/claude-sonnet-4 |
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## 3. Screen Architecture
|
|
150
|
-
|
|
151
|
-
### File: `src/tui/screens/`
|
|
152
|
-
|
|
153
|
-
### Screen Registry
|
|
154
|
-
|
|
155
|
-
| Screen | File | Purpose | Entry Condition |
|
|
156
|
-
|--------|------|---------|-----------------|
|
|
157
|
-
| WelcomeScreen | `WelcomeScreen.tsx` | First-run welcome | App startup |
|
|
158
|
-
| MainShell | `MainShell.tsx` | Interactive REPL | After welcome / navigation |
|
|
159
|
-
| InitScreen | `InitScreen.tsx` | Project initialization | `/init` command |
|
|
160
|
-
| InterviewScreen | `InterviewScreen.tsx` | Spec generation | `/new <feature>` command |
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
### 3.1 WelcomeScreen
|
|
165
|
-
|
|
166
|
-
**Purpose**: Branded entry point with status display
|
|
167
|
-
|
|
168
|
-
**Visual Layout**:
|
|
169
|
-
```
|
|
170
|
-
┌────────────────────────────────────────────────────┐
|
|
171
|
-
│ │
|
|
172
|
-
│ ██╗ ██╗██╗ ██████╗ ██████╗ ██╗ ██╗███╗ ███╗│
|
|
173
|
-
│ ██║ ██║██║██╔════╝ ██╔════╝ ██║ ██║████╗ ████║│
|
|
174
|
-
│ ██║ █╗ ██║██║██║ ███╗██║ ███╗██║ ██║██╔████╔██║│
|
|
175
|
-
│ ██║███╗██║██║██║ ██║██║ ██║██║ ██║██║╚██╔╝██║│
|
|
176
|
-
│ ╚███╔███╔╝██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ╚═╝ ██║│
|
|
177
|
-
│ ╚══╝╚══╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝│
|
|
178
|
-
│ │
|
|
179
|
-
│ v0.10.9 │
|
|
180
|
-
│ anthropic/claude-sonnet-4 │ Ready │
|
|
181
|
-
│ │
|
|
182
|
-
│ Press Enter to continue... (blinking) │
|
|
183
|
-
│ │
|
|
184
|
-
│ Tips: /init, /new <feature>, /help │
|
|
185
|
-
│ │
|
|
186
|
-
└────────────────────────────────────────────────────┘
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Props**:
|
|
190
|
-
```typescript
|
|
191
|
-
interface WelcomeScreenProps {
|
|
192
|
-
provider: AIProvider | null;
|
|
193
|
-
model: string;
|
|
194
|
-
version: string;
|
|
195
|
-
isInitialized: boolean;
|
|
196
|
-
onContinue: () => void;
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Behavior**:
|
|
201
|
-
- Blinking "Press Enter..." text (800ms interval)
|
|
202
|
-
- Status shows green "Ready" or orange "Not initialized"
|
|
203
|
-
- Enter key → navigates to MainShell
|
|
204
|
-
|
|
205
|
-
---
|
|
206
|
-
|
|
207
|
-
### 3.2 MainShell
|
|
208
|
-
|
|
209
|
-
**Purpose**: Primary interactive interface (REPL replacement)
|
|
210
|
-
|
|
211
|
-
**Visual Layout**:
|
|
212
|
-
```
|
|
213
|
-
┌────────────────────────────────────────────────────┐
|
|
214
|
-
│ Wiggum Interactive Mode │ Ready │
|
|
215
|
-
│ openai/gpt-5.1 │ Type /help for commands │
|
|
216
|
-
├────────────────────────────────────────────────────┤
|
|
217
|
-
│ │
|
|
218
|
-
│ (message history appears here) │
|
|
219
|
-
│ │
|
|
220
|
-
│ › Feature name required. Usage: /new <feature> │
|
|
221
|
-
│ │
|
|
222
|
-
├────────────────────────────────────────────────────┤
|
|
223
|
-
│ › /new my-feature█ │
|
|
224
|
-
│ ┌──────────────────────────────┐ │
|
|
225
|
-
│ │ /init Initialize project │ │
|
|
226
|
-
│ │ /new Create spec │ ← dropdown │
|
|
227
|
-
│ │ /run Run spec with AI │ │
|
|
228
|
-
│ │ /help Show commands │ │
|
|
229
|
-
│ └──────────────────────────────┘ │
|
|
230
|
-
└────────────────────────────────────────────────────┘
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**Props**:
|
|
234
|
-
```typescript
|
|
235
|
-
interface MainShellProps {
|
|
236
|
-
sessionState: SessionState;
|
|
237
|
-
onNavigate: (target: NavigationTarget, props?: NavigationProps) => void;
|
|
238
|
-
onSessionStateChange?: (state: SessionState) => void;
|
|
239
|
-
}
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
**Available Commands**:
|
|
243
|
-
|
|
244
|
-
| Command | Aliases | Description | Requires Init |
|
|
245
|
-
|---------|---------|-------------|---------------|
|
|
246
|
-
| `/init` | `/i` | Initialize project | No |
|
|
247
|
-
| `/new <name>` | `/n` | Create feature spec | Yes |
|
|
248
|
-
| `/run <name>` | `/r` | Run feature loop | Yes |
|
|
249
|
-
| `/monitor <name>` | `/m` | Monitor running loop | No |
|
|
250
|
-
| `/config` | `/cfg` | Manage settings | No |
|
|
251
|
-
| `/help` | `/h`, `/?` | Show help | No |
|
|
252
|
-
| `/exit` | `/quit`, `/q` | Exit application | No |
|
|
253
|
-
|
|
254
|
-
**Message Types**:
|
|
255
|
-
- User messages: `› content` (blue prefix)
|
|
256
|
-
- Assistant messages: `● content` (yellow prefix)
|
|
257
|
-
- System messages: dimmed text (no prefix)
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
|
|
261
|
-
### 3.3 InitScreen
|
|
262
|
-
|
|
263
|
-
**Purpose**: Multi-phase project initialization wizard
|
|
264
|
-
|
|
265
|
-
**Phases**:
|
|
266
|
-
|
|
267
|
-
| # | Phase | Display Name | User Action |
|
|
268
|
-
|---|-------|--------------|-------------|
|
|
269
|
-
| 1 | scanning | Analyzing project | (automatic) |
|
|
270
|
-
| 2 | provider-select | Select AI provider | Select from list |
|
|
271
|
-
| 2 | key-input | Enter API key | Type masked input |
|
|
272
|
-
| 2 | key-save | Save to .env.local | Yes/No confirm |
|
|
273
|
-
| 3 | model-select | Select AI model | Select from list |
|
|
274
|
-
| 4 | ai-analysis | AI codebase analysis | (automatic, shows tools) |
|
|
275
|
-
| 5 | confirm | Confirm generation | Yes/No confirm |
|
|
276
|
-
| 5 | generating | Creating files | (automatic) |
|
|
277
|
-
| 6 | complete | Done | Press Enter |
|
|
278
|
-
| - | error | Error occurred | Press Escape |
|
|
279
|
-
|
|
280
|
-
**Visual Layout** (ai-analysis phase):
|
|
281
|
-
```
|
|
282
|
-
┌────────────────────────────────────────────────────┐
|
|
283
|
-
│ ━━━ Phase 4 of 5: AI-powered codebase analysis ━━━ │
|
|
284
|
-
├────────────────────────────────────────────────────┤
|
|
285
|
-
│ │
|
|
286
|
-
│ ● Search Code (pattern: "export.*component") │
|
|
287
|
-
│ → 12 matches found │
|
|
288
|
-
│ │
|
|
289
|
-
│ ● Read File (src/index.ts) │
|
|
290
|
-
│ → 156 lines │
|
|
291
|
-
│ │
|
|
292
|
-
│ ◐ List Directory (src/components) │
|
|
293
|
-
│ Running... │
|
|
294
|
-
│ │
|
|
295
|
-
│ ⠋ Analyzing codebase structure... │
|
|
296
|
-
│ │
|
|
297
|
-
└────────────────────────────────────────────────────┘
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
**Props**:
|
|
301
|
-
```typescript
|
|
302
|
-
interface InitScreenProps {
|
|
303
|
-
projectRoot: string;
|
|
304
|
-
sessionState: SessionState;
|
|
305
|
-
onComplete: (newState: SessionState) => void;
|
|
306
|
-
onCancel: () => void;
|
|
307
|
-
}
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**State Hook**: `useInit` (manages all phase transitions)
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
### 3.4 InterviewScreen
|
|
315
|
-
|
|
316
|
-
**Purpose**: Interactive spec generation through AI conversation
|
|
317
|
-
|
|
318
|
-
**Phases**:
|
|
319
|
-
|
|
320
|
-
| # | Phase | Display Name | User Action |
|
|
321
|
-
|---|-------|--------------|-------------|
|
|
322
|
-
| 1 | context | Share references | Enter URLs/files or skip |
|
|
323
|
-
| 2 | goals | Describe feature | Type description |
|
|
324
|
-
| 3 | interview | Clarify requirements | Answer 2-10 questions |
|
|
325
|
-
| 4 | generation | Generating spec | (automatic, streaming) |
|
|
326
|
-
| 5 | complete | Spec ready | Press Enter |
|
|
327
|
-
|
|
328
|
-
**Visual Layout** (interview phase):
|
|
329
|
-
```
|
|
330
|
-
┌────────────────────────────────────────────────────┐
|
|
331
|
-
│ ━━━ Phase 3 of 4: Answer clarifying questions ━━━ │
|
|
332
|
-
├────────────────────────────────────────────────────┤
|
|
333
|
-
│ │
|
|
334
|
-
│ › I want to build a user authentication system │
|
|
335
|
-
│ │
|
|
336
|
-
│ ● Reading codebase to understand structure... │
|
|
337
|
-
│ ◐ search_codebase → 8 matches │
|
|
338
|
-
│ ● read_file (src/app.tsx) → 234 lines │
|
|
339
|
-
│ │
|
|
340
|
-
│ ● What authentication method do you prefer? │
|
|
341
|
-
│ - JWT tokens │
|
|
342
|
-
│ - Session-based │
|
|
343
|
-
│ - OAuth providers │
|
|
344
|
-
│ │
|
|
345
|
-
│ › JWT with refresh tokens█ │
|
|
346
|
-
│ │
|
|
347
|
-
│ (Type "done" or "skip" to generate early) │
|
|
348
|
-
└────────────────────────────────────────────────────┘
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
**Props**:
|
|
352
|
-
```typescript
|
|
353
|
-
interface InterviewScreenProps {
|
|
354
|
-
featureName: string;
|
|
355
|
-
projectRoot: string;
|
|
356
|
-
provider: AIProvider;
|
|
357
|
-
model: string;
|
|
358
|
-
scanResult?: ScanResult;
|
|
359
|
-
onComplete: (spec: string) => void;
|
|
360
|
-
onCancel: () => void;
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
**State Hook**: `useSpecGenerator`
|
|
365
|
-
**Orchestrator**: `InterviewOrchestrator` (bridges TUI ↔ AI)
|
|
366
|
-
|
|
367
|
-
---
|
|
368
|
-
|
|
369
|
-
## 4. Component Library
|
|
370
|
-
|
|
371
|
-
### File: `src/tui/components/`
|
|
372
|
-
|
|
373
|
-
### Component Hierarchy
|
|
374
|
-
|
|
375
|
-
```
|
|
376
|
-
App
|
|
377
|
-
├── WelcomeScreen
|
|
378
|
-
│ └── WiggumBanner
|
|
379
|
-
├── MainShell
|
|
380
|
-
│ ├── MessageList
|
|
381
|
-
│ │ ├── UserMessage
|
|
382
|
-
│ │ ├── AssistantMessage
|
|
383
|
-
│ │ │ ├── ToolCallCard
|
|
384
|
-
│ │ │ └── StreamingText
|
|
385
|
-
│ │ └── SystemMessage
|
|
386
|
-
│ └── ChatInput
|
|
387
|
-
│ └── CommandDropdown
|
|
388
|
-
├── InitScreen
|
|
389
|
-
│ ├── PhaseHeader
|
|
390
|
-
│ ├── Select
|
|
391
|
-
│ ├── PasswordInput
|
|
392
|
-
│ ├── Confirm
|
|
393
|
-
│ ├── ActionList
|
|
394
|
-
│ │ └── ActionOutput
|
|
395
|
-
│ └── WorkingIndicator
|
|
396
|
-
└── InterviewScreen
|
|
397
|
-
├── PhaseHeader
|
|
398
|
-
├── MessageList
|
|
399
|
-
├── WorkingIndicator
|
|
400
|
-
└── ChatInput
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
---
|
|
404
|
-
|
|
405
|
-
### 4.1 Input Components
|
|
406
|
-
|
|
407
|
-
#### ChatInput
|
|
408
|
-
|
|
409
|
-
**Purpose**: Primary text input with command dropdown support
|
|
410
|
-
|
|
411
|
-
**Visual**:
|
|
412
|
-
```
|
|
413
|
-
› Type your message...█
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
**Props**:
|
|
417
|
-
```typescript
|
|
418
|
-
interface ChatInputProps {
|
|
419
|
-
onSubmit: (value: string) => void;
|
|
420
|
-
placeholder?: string;
|
|
421
|
-
disabled?: boolean;
|
|
422
|
-
allowEmpty?: boolean;
|
|
423
|
-
commands?: Command[];
|
|
424
|
-
onCommand?: (command: string) => void;
|
|
425
|
-
}
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
**Behavior**:
|
|
429
|
-
- Shows `›` blue prompt prefix
|
|
430
|
-
- Typing `/` triggers CommandDropdown
|
|
431
|
-
- Space after command hides dropdown
|
|
432
|
-
- Disabled state shows `› [waiting for AI...]`
|
|
433
|
-
|
|
434
|
-
---
|
|
435
|
-
|
|
436
|
-
#### CommandDropdown
|
|
437
|
-
|
|
438
|
-
**Purpose**: Autocomplete for slash commands
|
|
439
|
-
|
|
440
|
-
**Visual**:
|
|
441
|
-
```
|
|
442
|
-
/init Initialize project with CLAUDE.md
|
|
443
|
-
/new Create a new feature specification
|
|
444
|
-
► /run Run a spec file with AI
|
|
445
|
-
/help Show available commands
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
**Props**:
|
|
449
|
-
```typescript
|
|
450
|
-
interface CommandDropdownProps {
|
|
451
|
-
commands: Command[];
|
|
452
|
-
filter: string;
|
|
453
|
-
onSelect: (command: string) => void;
|
|
454
|
-
onCancel: () => void;
|
|
455
|
-
}
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
---
|
|
459
|
-
|
|
460
|
-
#### Select
|
|
461
|
-
|
|
462
|
-
**Purpose**: Arrow-navigable option list
|
|
463
|
-
|
|
464
|
-
**Visual**:
|
|
465
|
-
```
|
|
466
|
-
Select AI provider:
|
|
467
|
-
○ Anthropic (Claude)
|
|
468
|
-
► ● OpenAI (GPT-4)
|
|
469
|
-
○ OpenRouter
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
**Props**:
|
|
473
|
-
```typescript
|
|
474
|
-
interface SelectProps<T> {
|
|
475
|
-
message: string;
|
|
476
|
-
options: SelectOption<T>[];
|
|
477
|
-
onSelect: (value: T) => void;
|
|
478
|
-
onCancel?: () => void;
|
|
479
|
-
initialIndex?: number;
|
|
480
|
-
}
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
**Controls**: ↑/↓, j/k, Enter, Escape
|
|
484
|
-
|
|
485
|
-
---
|
|
486
|
-
|
|
487
|
-
#### PasswordInput
|
|
488
|
-
|
|
489
|
-
**Purpose**: Masked text input for secrets
|
|
490
|
-
|
|
491
|
-
**Visual**:
|
|
492
|
-
```
|
|
493
|
-
Enter your API key:
|
|
494
|
-
› ************************************█
|
|
495
|
-
(Enter to submit, Esc to cancel)
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
**Props**:
|
|
499
|
-
```typescript
|
|
500
|
-
interface PasswordInputProps {
|
|
501
|
-
message: string;
|
|
502
|
-
onSubmit: (value: string) => void;
|
|
503
|
-
onCancel?: () => void;
|
|
504
|
-
mask?: string;
|
|
505
|
-
placeholder?: string;
|
|
506
|
-
}
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
#### Confirm
|
|
512
|
-
|
|
513
|
-
**Purpose**: Yes/No binary choice
|
|
514
|
-
|
|
515
|
-
**Visual**:
|
|
516
|
-
```
|
|
517
|
-
Save API key to .env.local?
|
|
518
|
-
[Yes] No
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
**Props**:
|
|
522
|
-
```typescript
|
|
523
|
-
interface ConfirmProps {
|
|
524
|
-
message: string;
|
|
525
|
-
onConfirm: (value: boolean) => void;
|
|
526
|
-
onCancel?: () => void;
|
|
527
|
-
initialValue?: boolean;
|
|
528
|
-
}
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
**Controls**: ←/→, y/n, Enter, Escape
|
|
532
|
-
|
|
533
|
-
---
|
|
534
|
-
|
|
535
|
-
### 4.2 Display Components
|
|
536
|
-
|
|
537
|
-
#### PhaseHeader
|
|
538
|
-
|
|
539
|
-
**Purpose**: Progress indicator for multi-step flows
|
|
540
|
-
|
|
541
|
-
**Visual**:
|
|
542
|
-
```
|
|
543
|
-
━━━ Phase 3 of 5: AI-powered codebase analysis ━━━
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
**Props**:
|
|
547
|
-
```typescript
|
|
548
|
-
interface PhaseHeaderProps {
|
|
549
|
-
currentPhase: number;
|
|
550
|
-
totalPhases: number;
|
|
551
|
-
phaseName: string;
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
#### MessageList
|
|
558
|
-
|
|
559
|
-
**Purpose**: Conversation history display
|
|
560
|
-
|
|
561
|
-
**Visual**:
|
|
562
|
-
```
|
|
563
|
-
› What should I build? (user - blue)
|
|
564
|
-
|
|
565
|
-
● Let me explore the codebase... (assistant - yellow)
|
|
566
|
-
● search_codebase → 5 matches
|
|
567
|
-
● read_file → 120 lines
|
|
568
|
-
|
|
569
|
-
Project not initialized. (system - dimmed)
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
**Props**:
|
|
573
|
-
```typescript
|
|
574
|
-
interface MessageListProps {
|
|
575
|
-
messages: Message[];
|
|
576
|
-
maxHeight?: number;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
interface Message {
|
|
580
|
-
id: string;
|
|
581
|
-
role: 'user' | 'assistant' | 'system';
|
|
582
|
-
content: string;
|
|
583
|
-
toolCalls?: ToolCall[];
|
|
584
|
-
isStreaming?: boolean;
|
|
585
|
-
}
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
---
|
|
589
|
-
|
|
590
|
-
#### ToolCallCard
|
|
591
|
-
|
|
592
|
-
**Purpose**: Tool execution status display
|
|
593
|
-
|
|
594
|
-
**Visual States**:
|
|
595
|
-
```
|
|
596
|
-
○ Search Code (pattern) (pending - brown)
|
|
597
|
-
◐ Read File (path) (running - yellow)
|
|
598
|
-
● List Directory (path) → 5 items (complete - green)
|
|
599
|
-
● Search Code (pattern) → Error (error - pink)
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
**Props**:
|
|
603
|
-
```typescript
|
|
604
|
-
interface ToolCallCardProps {
|
|
605
|
-
toolName: string;
|
|
606
|
-
status: ToolCallStatus; // 'pending' | 'running' | 'complete' | 'error'
|
|
607
|
-
input: string;
|
|
608
|
-
output?: string;
|
|
609
|
-
error?: string;
|
|
610
|
-
}
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
---
|
|
614
|
-
|
|
615
|
-
#### WorkingIndicator
|
|
616
|
-
|
|
617
|
-
**Purpose**: Loading state with spinner
|
|
618
|
-
|
|
619
|
-
**Visual**:
|
|
620
|
-
```
|
|
621
|
-
⠋ Analyzing codebase structure... (Press Esc to cancel)
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
**Props**:
|
|
625
|
-
```typescript
|
|
626
|
-
interface WorkingIndicatorProps {
|
|
627
|
-
state: {
|
|
628
|
-
isWorking: boolean;
|
|
629
|
-
status: string;
|
|
630
|
-
hint?: string;
|
|
631
|
-
};
|
|
632
|
-
}
|
|
633
|
-
```
|
|
634
|
-
|
|
635
|
-
---
|
|
636
|
-
|
|
637
|
-
#### StreamingText
|
|
638
|
-
|
|
639
|
-
**Purpose**: Real-time text display with cursor
|
|
640
|
-
|
|
641
|
-
**Visual**:
|
|
642
|
-
```
|
|
643
|
-
The authentication system should use JWT tokens for...█
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
**Props**:
|
|
647
|
-
```typescript
|
|
648
|
-
interface StreamingTextProps {
|
|
649
|
-
text: string;
|
|
650
|
-
isStreaming: boolean;
|
|
651
|
-
color?: string;
|
|
652
|
-
showCursor?: boolean;
|
|
653
|
-
}
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
---
|
|
657
|
-
|
|
658
|
-
### 4.3 Branding Components
|
|
659
|
-
|
|
660
|
-
#### WiggumBanner
|
|
661
|
-
|
|
662
|
-
**Purpose**: ASCII art logo
|
|
663
|
-
|
|
664
|
-
**Visual**:
|
|
665
|
-
```
|
|
666
|
-
██╗ ██╗██╗ ██████╗ ██████╗ ██╗ ██╗███╗ ███╗
|
|
667
|
-
██║ ██║██║██╔════╝ ██╔════╝ ██║ ██║████╗ ████║
|
|
668
|
-
██║ █╗ ██║██║██║ ███╗██║ ███╗██║ ██║██╔████╔██║
|
|
669
|
-
██║███╗██║██║██║ ██║██║ ██║██║ ██║██║╚██╔╝██║
|
|
670
|
-
╚███╔███╔╝██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
|
|
671
|
-
╚══╝╚══╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
---
|
|
675
|
-
|
|
676
|
-
## 5. State Management
|
|
677
|
-
|
|
678
|
-
### Patterns
|
|
679
|
-
|
|
680
|
-
| Level | Scope | Mechanism | Persistence |
|
|
681
|
-
|-------|-------|-----------|-------------|
|
|
682
|
-
| Session | Cross-screen | SessionState object | Yes (config files) |
|
|
683
|
-
| Screen | Single screen | useState/hooks | No |
|
|
684
|
-
| Component | Single component | useState | No |
|
|
685
|
-
|
|
686
|
-
### State Hooks
|
|
687
|
-
|
|
688
|
-
#### useInit (`src/tui/hooks/useInit.ts`)
|
|
689
|
-
|
|
690
|
-
**Manages**: InitScreen phases and data
|
|
691
|
-
|
|
692
|
-
**Key State**:
|
|
693
|
-
```typescript
|
|
694
|
-
interface InitState {
|
|
695
|
-
phase: InitPhase;
|
|
696
|
-
projectRoot: string;
|
|
697
|
-
scanResult: ScanResult | null;
|
|
698
|
-
enhancedResult: EnhancedScanResult | null;
|
|
699
|
-
provider: AIProvider | null;
|
|
700
|
-
model: string | null;
|
|
701
|
-
hasApiKey: boolean;
|
|
702
|
-
apiKeyEnteredThisSession: boolean;
|
|
703
|
-
saveKeyToEnv: boolean;
|
|
704
|
-
isWorking: boolean;
|
|
705
|
-
workingStatus: string;
|
|
706
|
-
error: string | null;
|
|
707
|
-
generatedFiles: string[];
|
|
708
|
-
toolCalls: ToolCallDisplay[];
|
|
709
|
-
}
|
|
710
|
-
```
|
|
711
|
-
|
|
712
|
-
**Actions**: `initialize`, `setScanResult`, `selectProvider`, `setApiKey`, `selectModel`, `setEnhancedResult`, `setGenerationComplete`, etc.
|
|
713
|
-
|
|
714
|
-
---
|
|
715
|
-
|
|
716
|
-
#### useSpecGenerator (`src/tui/hooks/useSpecGenerator.ts`)
|
|
717
|
-
|
|
718
|
-
**Manages**: InterviewScreen phases and conversation
|
|
719
|
-
|
|
720
|
-
**Key State**:
|
|
721
|
-
```typescript
|
|
722
|
-
interface SpecGeneratorState {
|
|
723
|
-
phase: 'context' | 'goals' | 'interview' | 'generation' | 'complete';
|
|
724
|
-
messages: Message[];
|
|
725
|
-
isWorking: boolean;
|
|
726
|
-
workingStatus: string;
|
|
727
|
-
currentQuestion: string;
|
|
728
|
-
awaitingInput: boolean;
|
|
729
|
-
generatedSpec: string | null;
|
|
730
|
-
error: string | null;
|
|
731
|
-
questionCount: number;
|
|
732
|
-
references: Array<{ source: string; content: string }>;
|
|
733
|
-
}
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
**Actions**: `initialize`, `addMessage`, `setPhase`, `startToolCall`, `completeToolCall`, `updateStreamingMessage`, etc.
|
|
737
|
-
|
|
738
|
-
---
|
|
739
|
-
|
|
740
|
-
### Orchestrator Pattern
|
|
741
|
-
|
|
742
|
-
**File**: `src/tui/orchestration/interview-orchestrator.ts`
|
|
743
|
-
|
|
744
|
-
**Purpose**: Bridge between TUI state and AI services
|
|
745
|
-
|
|
746
|
-
```
|
|
747
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
748
|
-
│ InterviewOrchestrator │
|
|
749
|
-
├─────────────────────────────────────────────────────────────┤
|
|
750
|
-
│ │
|
|
751
|
-
│ TUI Callbacks AI Services │
|
|
752
|
-
│ ───────────────── ─────────────── │
|
|
753
|
-
│ onMessage() ◄─────► ConversationManager │
|
|
754
|
-
│ onStreamChunk() ◄─────► InterviewTools │
|
|
755
|
-
│ onToolStart() ◄─────► TavilySearchTool │
|
|
756
|
-
│ onToolEnd() ◄─────► Context7Tools │
|
|
757
|
-
│ onPhaseChange() │
|
|
758
|
-
│ onComplete() │
|
|
759
|
-
│ onError() │
|
|
760
|
-
│ onWorkingChange() │
|
|
761
|
-
│ onReady() │
|
|
762
|
-
│ │
|
|
763
|
-
└─────────────────────────────────────────────────────────────┘
|
|
764
|
-
```
|
|
765
|
-
|
|
766
|
-
---
|
|
767
|
-
|
|
768
|
-
## 6. Navigation Patterns
|
|
769
|
-
|
|
770
|
-
### Navigation Targets
|
|
771
|
-
|
|
772
|
-
```typescript
|
|
773
|
-
type NavigationTarget = 'welcome' | 'shell' | 'interview' | 'init';
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
### Navigation Flow Diagram
|
|
777
|
-
|
|
778
|
-
```
|
|
779
|
-
┌──────────────────┐
|
|
780
|
-
│ App Startup │
|
|
781
|
-
└────────┬─────────┘
|
|
782
|
-
│
|
|
783
|
-
▼
|
|
784
|
-
┌──────────────────┐
|
|
785
|
-
┌────────│ WelcomeScreen │
|
|
786
|
-
│ └────────┬─────────┘
|
|
787
|
-
│ │ [Enter]
|
|
788
|
-
│ ▼
|
|
789
|
-
│ ┌──────────────────┐
|
|
790
|
-
│ ┌────│ MainShell │◄─────────────────┐
|
|
791
|
-
│ │ └────────┬─────────┘ │
|
|
792
|
-
│ │ │ │
|
|
793
|
-
│ │ ┌────────┼────────┐ │
|
|
794
|
-
│ │ │ │ │ │
|
|
795
|
-
│ │ [/init] [/new] [/exit] │
|
|
796
|
-
│ │ │ │ │ │
|
|
797
|
-
│ │ ▼ │ ▼ │
|
|
798
|
-
│ │ ┌──────┐ │ ┌────────┐ │
|
|
799
|
-
│ │ │ Init │────┼───►│ Exit() │ │
|
|
800
|
-
│ │ │Screen│ │ └────────┘ │
|
|
801
|
-
│ │ └──┬───┘ │ │
|
|
802
|
-
│ │ │ │ │
|
|
803
|
-
│ │ [complete] │ │
|
|
804
|
-
│ │ │ ▼ │
|
|
805
|
-
│ │ │ ┌──────────┐ │
|
|
806
|
-
│ │ │ │Interview │ │
|
|
807
|
-
│ │ │ │ Screen │─────────────────────┤
|
|
808
|
-
│ │ │ └──────────┘ [complete] │
|
|
809
|
-
│ │ │ │
|
|
810
|
-
│ └────┴────────────────────────────────────┘
|
|
811
|
-
│ [Escape]
|
|
812
|
-
│
|
|
813
|
-
[Deep link: wiggum --new feature]
|
|
814
|
-
```
|
|
815
|
-
|
|
816
|
-
### Navigation Triggers
|
|
817
|
-
|
|
818
|
-
| Trigger | From | To | Condition |
|
|
819
|
-
|---------|------|-----|-----------|
|
|
820
|
-
| Enter | Welcome | Shell | Always |
|
|
821
|
-
| `/init` | Shell | Init | Always |
|
|
822
|
-
| `/new <name>` | Shell | Interview | `initialized=true` |
|
|
823
|
-
| `/exit` | Shell | (exit) | Always |
|
|
824
|
-
| Escape | Init/Interview | Shell | Always |
|
|
825
|
-
| Complete | Init | Shell | Success |
|
|
826
|
-
| Complete | Interview | Shell | Spec saved |
|
|
827
|
-
|
|
828
|
-
---
|
|
829
|
-
|
|
830
|
-
## 7. Input Handling
|
|
831
|
-
|
|
832
|
-
### Input Pipeline
|
|
833
|
-
|
|
834
|
-
```
|
|
835
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
836
|
-
│ Raw Stdin │
|
|
837
|
-
│ (managed by Ink internally) │
|
|
838
|
-
└─────────────────────────────────────────────────────────────┘
|
|
839
|
-
│
|
|
840
|
-
▼
|
|
841
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
842
|
-
│ useInput Hook │
|
|
843
|
-
│ (keyboard events: chars, arrows, special keys) │
|
|
844
|
-
└─────────────────────────────────────────────────────────────┘
|
|
845
|
-
│
|
|
846
|
-
┌───────────────────┼───────────────────┐
|
|
847
|
-
▼ ▼ ▼
|
|
848
|
-
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
849
|
-
│ TextInput │ │ Select │ │ PasswordInput │
|
|
850
|
-
│ (typing) │ │ (navigation) │ │ (masked) │
|
|
851
|
-
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
852
|
-
│
|
|
853
|
-
▼
|
|
854
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
855
|
-
│ Component Handler │
|
|
856
|
-
│ (ChatInput.handleSubmit, Select.handleSelect, etc.) │
|
|
857
|
-
└─────────────────────────────────────────────────────────────┘
|
|
858
|
-
│
|
|
859
|
-
▼
|
|
860
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
861
|
-
│ Screen Handler │
|
|
862
|
-
│ (MainShell.handleSubmit → parseInput → executeCommand) │
|
|
863
|
-
└─────────────────────────────────────────────────────────────┘
|
|
864
|
-
│
|
|
865
|
-
▼
|
|
866
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
867
|
-
│ Business Logic │
|
|
868
|
-
│ (Orchestrator, AI services, file operations) │
|
|
869
|
-
└─────────────────────────────────────────────────────────────┘
|
|
870
|
-
```
|
|
871
|
-
|
|
872
|
-
### Key Bindings
|
|
873
|
-
|
|
874
|
-
| Key | Context | Action |
|
|
875
|
-
|-----|---------|--------|
|
|
876
|
-
| Enter | TextInput | Submit |
|
|
877
|
-
| Enter | Select | Confirm selection |
|
|
878
|
-
| Enter | Welcome | Continue |
|
|
879
|
-
| Escape | Any screen | Cancel/back |
|
|
880
|
-
| Ctrl+C | MainShell | Show "use /exit" hint |
|
|
881
|
-
| ↑/↓ | Select/Dropdown | Navigate options |
|
|
882
|
-
| j/k | Select | Vim navigation |
|
|
883
|
-
| ←/→ | Confirm | Toggle Yes/No |
|
|
884
|
-
| y/n | Confirm | Quick select |
|
|
885
|
-
| Backspace | TextInput | Delete char |
|
|
886
|
-
|
|
887
|
-
### Command Parsing
|
|
888
|
-
|
|
889
|
-
**File**: `src/repl/command-parser.ts`
|
|
890
|
-
|
|
891
|
-
```typescript
|
|
892
|
-
parseInput(value: string): ParsedInput
|
|
893
|
-
|
|
894
|
-
// Returns one of:
|
|
895
|
-
{ type: 'empty' }
|
|
896
|
-
{ type: 'slash-command', command: { name, args, raw } }
|
|
897
|
-
{ type: 'natural-language', text }
|
|
898
|
-
```
|
|
899
|
-
|
|
900
|
-
---
|
|
901
|
-
|
|
902
|
-
## 8. Theme & Visual System
|
|
903
|
-
|
|
904
|
-
### File: `src/tui/theme.ts`
|
|
905
|
-
|
|
906
|
-
### Color Palette (Simpson Theme)
|
|
907
|
-
|
|
908
|
-
| Name | Hex | Usage |
|
|
909
|
-
|------|-----|-------|
|
|
910
|
-
| blue | #2f64d6 | Input prompts (›), user messages |
|
|
911
|
-
| yellow | #f8db27 | Primary accent, headers, assistant messages |
|
|
912
|
-
| brown | #9c5b01 | Secondary, hints, pending states |
|
|
913
|
-
| white | #ffffff | Content text |
|
|
914
|
-
| pink | #ff81c1 | Errors, warnings |
|
|
915
|
-
| green | #4ade80 | Success states |
|
|
916
|
-
| orange | #fb923c | Caution, not initialized |
|
|
917
|
-
|
|
918
|
-
### Status Indicators
|
|
919
|
-
|
|
920
|
-
| Symbol | Name | Usage |
|
|
921
|
-
|--------|------|-------|
|
|
922
|
-
| `○` | pending | Tool not started |
|
|
923
|
-
| `◐` | active | Tool running |
|
|
924
|
-
| `●` | complete | Tool done / bullet |
|
|
925
|
-
| `✓` | success | Phase complete |
|
|
926
|
-
| `✗` | error | Phase failed |
|
|
927
|
-
| `›` | prompt | User input prefix |
|
|
928
|
-
| `█` | cursor | Streaming text cursor |
|
|
929
|
-
|
|
930
|
-
### Box Drawing
|
|
931
|
-
|
|
932
|
-
```typescript
|
|
933
|
-
const box = {
|
|
934
|
-
topLeft: '┌', topRight: '┐',
|
|
935
|
-
bottomLeft: '└', bottomRight: '┘',
|
|
936
|
-
horizontal: '─', vertical: '│',
|
|
937
|
-
}
|
|
938
|
-
```
|
|
939
|
-
|
|
940
|
-
### Phase Header Style
|
|
941
|
-
|
|
942
|
-
```
|
|
943
|
-
━━━ Phase 3 of 5: Phase Name ━━━
|
|
944
|
-
```
|
|
945
|
-
(Uses U+2501 heavy horizontal line)
|
|
946
|
-
|
|
947
|
-
---
|
|
948
|
-
|
|
949
|
-
## 9. User Flows
|
|
950
|
-
|
|
951
|
-
### Flow 1: First-Time Setup
|
|
952
|
-
|
|
953
|
-
```
|
|
954
|
-
1. User runs `wiggum`
|
|
955
|
-
│
|
|
956
|
-
▼
|
|
957
|
-
2. WelcomeScreen displays
|
|
958
|
-
- ASCII banner
|
|
959
|
-
- "Not initialized" status (orange)
|
|
960
|
-
- Tips shown
|
|
961
|
-
│
|
|
962
|
-
▼ [Enter]
|
|
963
|
-
3. MainShell displays
|
|
964
|
-
- Status bar shows provider/model
|
|
965
|
-
│
|
|
966
|
-
▼ [/init]
|
|
967
|
-
4. InitScreen starts
|
|
968
|
-
│
|
|
969
|
-
├─► Phase 1: Scanning (automatic)
|
|
970
|
-
│
|
|
971
|
-
├─► Phase 2: Provider selection
|
|
972
|
-
│ └─► API key entry (if needed)
|
|
973
|
-
│ └─► Save to .env.local confirmation
|
|
974
|
-
│
|
|
975
|
-
├─► Phase 3: Model selection
|
|
976
|
-
│
|
|
977
|
-
├─► Phase 4: AI analysis
|
|
978
|
-
│ └─► Tool calls displayed
|
|
979
|
-
│
|
|
980
|
-
├─► Phase 5: Confirm & generate
|
|
981
|
-
│ └─► Files created
|
|
982
|
-
│
|
|
983
|
-
└─► Complete: Return to MainShell
|
|
984
|
-
│
|
|
985
|
-
▼
|
|
986
|
-
5. MainShell with "Ready" status
|
|
987
|
-
```
|
|
988
|
-
|
|
989
|
-
### Flow 2: Create Feature Spec
|
|
990
|
-
|
|
991
|
-
```
|
|
992
|
-
1. User in MainShell
|
|
993
|
-
│
|
|
994
|
-
▼ [/new my-feature]
|
|
995
|
-
2. InterviewScreen starts
|
|
996
|
-
│
|
|
997
|
-
├─► Phase 1: Context (optional)
|
|
998
|
-
│ └─► User enters URLs/files or skips
|
|
999
|
-
│
|
|
1000
|
-
├─► Phase 2: Goals
|
|
1001
|
-
│ └─► User describes feature
|
|
1002
|
-
│
|
|
1003
|
-
├─► Phase 3: Interview (2-10 questions)
|
|
1004
|
-
│ └─► AI asks questions
|
|
1005
|
-
│ └─► User answers
|
|
1006
|
-
│ └─► Tool calls shown
|
|
1007
|
-
│
|
|
1008
|
-
├─► Phase 4: Generation (streaming)
|
|
1009
|
-
│ └─► Spec text appears incrementally
|
|
1010
|
-
│
|
|
1011
|
-
└─► Phase 5: Complete
|
|
1012
|
-
└─► Spec saved to .ralph/specs/my-feature.md
|
|
1013
|
-
│
|
|
1014
|
-
▼
|
|
1015
|
-
3. Return to MainShell
|
|
1016
|
-
```
|
|
1017
|
-
|
|
1018
|
-
### Flow 3: Quick Commands
|
|
1019
|
-
|
|
1020
|
-
```
|
|
1021
|
-
MainShell
|
|
1022
|
-
│
|
|
1023
|
-
├─► [/help] → Shows command list (inline)
|
|
1024
|
-
│
|
|
1025
|
-
├─► [/config] → "Not implemented" message
|
|
1026
|
-
│
|
|
1027
|
-
├─► [/run feature] → "Not implemented" message
|
|
1028
|
-
│
|
|
1029
|
-
└─► [/exit] → "Goodbye!" → Process exits
|
|
1030
|
-
```
|
|
1031
|
-
|
|
1032
|
-
---
|
|
1033
|
-
|
|
1034
|
-
## 10. Current Issues & Pain Points
|
|
1035
|
-
|
|
1036
|
-
### Known UX Issues
|
|
1037
|
-
|
|
1038
|
-
| Issue | Severity | Location | Description |
|
|
1039
|
-
|-------|----------|----------|-------------|
|
|
1040
|
-
| Stdin conflicts | High | index.ts | Ink/readline mode switching |
|
|
1041
|
-
| Buffered input | Medium | repl-prompts.ts | 100ms delay workaround |
|
|
1042
|
-
| No scroll | Medium | MessageList | Long conversations overflow |
|
|
1043
|
-
| No persistence | Low | MainShell | Messages lost on navigation |
|
|
1044
|
-
| Limited feedback | Medium | Various | No progress bars |
|
|
1045
|
-
|
|
1046
|
-
### Visual Inconsistencies
|
|
1047
|
-
|
|
1048
|
-
| Issue | Location | Description |
|
|
1049
|
-
|-------|----------|-------------|
|
|
1050
|
-
| Mixed prefixes | Various | Sometimes `>`, sometimes `›` |
|
|
1051
|
-
| Color usage | Various | Inconsistent success/error colors |
|
|
1052
|
-
| Spacing | Various | Inconsistent padding/margins |
|
|
1053
|
-
|
|
1054
|
-
### Missing Features
|
|
1055
|
-
|
|
1056
|
-
| Feature | Priority | Notes |
|
|
1057
|
-
|---------|----------|-------|
|
|
1058
|
-
| History | High | Command history (up arrow) |
|
|
1059
|
-
| Autocomplete | Medium | Tab completion for paths |
|
|
1060
|
-
| Resize handling | Medium | Terminal resize events |
|
|
1061
|
-
| Copy/paste | Low | Full clipboard support |
|
|
1062
|
-
| Mouse support | Low | Click to select |
|
|
1063
|
-
|
|
1064
|
-
---
|
|
1065
|
-
|
|
1066
|
-
## 11. Out of Scope
|
|
1067
|
-
|
|
1068
|
-
The following are **not** part of this TUI review:
|
|
1069
|
-
|
|
1070
|
-
### Ralph Loop Layer (AI/Generation)
|
|
1071
|
-
- `src/ai/` - AI providers, prompts, tools
|
|
1072
|
-
- `src/generator/` - File generation, templates
|
|
1073
|
-
- `src/scanner/` - Tech stack detection
|
|
1074
|
-
|
|
1075
|
-
### Configuration Files
|
|
1076
|
-
- `.ralph/claude.md` content/format
|
|
1077
|
-
- `.ralph/specs/*.md` content/format
|
|
1078
|
-
- Template files in `src/templates/`
|
|
1079
|
-
|
|
1080
|
-
### CLI Mode
|
|
1081
|
-
- `src/cli.ts` - Commander.js CLI
|
|
1082
|
-
- Direct command execution (non-TUI)
|
|
1083
|
-
|
|
1084
|
-
---
|
|
1085
|
-
|
|
1086
|
-
## Appendix: File Reference
|
|
1087
|
-
|
|
1088
|
-
### Core TUI Files
|
|
1089
|
-
|
|
1090
|
-
| Path | Purpose |
|
|
1091
|
-
|------|---------|
|
|
1092
|
-
| `src/index.ts` | Entry point, TUI initialization |
|
|
1093
|
-
| `src/tui/app.tsx` | Root component, screen router |
|
|
1094
|
-
| `src/tui/theme.ts` | Colors, symbols, box drawing |
|
|
1095
|
-
|
|
1096
|
-
### Screens
|
|
1097
|
-
|
|
1098
|
-
| Path | Screen |
|
|
1099
|
-
|------|--------|
|
|
1100
|
-
| `src/tui/screens/WelcomeScreen.tsx` | Welcome |
|
|
1101
|
-
| `src/tui/screens/MainShell.tsx` | Shell/REPL |
|
|
1102
|
-
| `src/tui/screens/InitScreen.tsx` | Initialization |
|
|
1103
|
-
| `src/tui/screens/InterviewScreen.tsx` | Spec generation |
|
|
1104
|
-
|
|
1105
|
-
### Components
|
|
1106
|
-
|
|
1107
|
-
| Path | Component |
|
|
1108
|
-
|------|-----------|
|
|
1109
|
-
| `src/tui/components/ChatInput.tsx` | Text input |
|
|
1110
|
-
| `src/tui/components/CommandDropdown.tsx` | Command autocomplete |
|
|
1111
|
-
| `src/tui/components/MessageList.tsx` | Conversation display |
|
|
1112
|
-
| `src/tui/components/ToolCallCard.tsx` | Tool status |
|
|
1113
|
-
| `src/tui/components/PhaseHeader.tsx` | Progress header |
|
|
1114
|
-
| `src/tui/components/WorkingIndicator.tsx` | Loading spinner |
|
|
1115
|
-
| `src/tui/components/Select.tsx` | Option list |
|
|
1116
|
-
| `src/tui/components/PasswordInput.tsx` | Masked input |
|
|
1117
|
-
| `src/tui/components/Confirm.tsx` | Yes/No prompt |
|
|
1118
|
-
| `src/tui/components/WiggumBanner.tsx` | ASCII logo |
|
|
1119
|
-
|
|
1120
|
-
### Hooks
|
|
1121
|
-
|
|
1122
|
-
| Path | Hook |
|
|
1123
|
-
|------|------|
|
|
1124
|
-
| `src/tui/hooks/useInit.ts` | Init state |
|
|
1125
|
-
| `src/tui/hooks/useSpecGenerator.ts` | Interview state |
|
|
1126
|
-
|
|
1127
|
-
### Orchestration
|
|
1128
|
-
|
|
1129
|
-
| Path | Class |
|
|
1130
|
-
|------|-------|
|
|
1131
|
-
| `src/tui/orchestration/interview-orchestrator.ts` | TUI↔AI bridge |
|
|
1132
|
-
|
|
1133
|
-
### Support
|
|
1134
|
-
|
|
1135
|
-
| Path | Purpose |
|
|
1136
|
-
|------|---------|
|
|
1137
|
-
| `src/repl/command-parser.ts` | Command parsing |
|
|
1138
|
-
| `src/repl/session-state.ts` | Session state types |
|
|
1139
|
-
|
|
1140
|
-
---
|
|
1141
|
-
|
|
1142
|
-
*Document generated for UX/TUI review. Last updated: 2026-01-27*
|