Architecture patterns for the Shep AI terminal UI layer.
--flags for CI/scripting bypassA wizard is an async function that orchestrates multiple prompts into a multi-step flow:
// src/presentation/tui/wizards/agent-config.wizard.ts
import { select, confirm, password } from '@inquirer/prompts';
export interface AgentConfigResult {
agentType: string;
authMethod: string;
token?: string;
}
export async function agentConfigWizard(): Promise<AgentConfigResult> {
// Step 1: Select agent
const agentType = await select({ ... });
// Step 2: Select auth method
const authMethod = await select({ ... });
// Step 3: If token, get token
if (authMethod === 'token') {
const token = await password({ ... });
return { agentType, authMethod, token };
}
return { agentType, authMethod };
}
CLI commands detect whether to run interactive or non-interactive mode:
// In command handler
if (options.agent && options.auth) {
// Non-interactive: use flags directly
result = { agentType: options.agent, authMethod: options.auth };
} else {
// Interactive: launch wizard
result = await agentConfigWizard();
}
Reusable prompt configurations are extracted to separate files:
// src/presentation/tui/prompts/agent-select.prompt.ts
import { Separator } from '@inquirer/prompts';
export const agentSelectConfig = {
message: 'Select your AI coding agent',
choices: [
{ name: 'Claude Code', value: 'claude-code', description: '...' },
new Separator('--- Coming Soon ---'),
{ name: 'Gemini CLI', value: 'gemini-cli', disabled: '(Coming Soon)' },
],
};
Custom Inquirer theme integrates with the CLI design system colors:
// src/presentation/tui/themes/shep.theme.ts
import { colors } from '@/presentation/cli/ui';
export const shepTheme = {
prefix: { idle: colors.brand('?'), done: colors.success('✓') },
style: {
highlight: (text: string) => colors.brand(text),
disabled: (text: string) => colors.muted(text),
},
};
src/presentation/tui/
├── index.ts # Barrel exports
├── wizards/ # Multi-step wizard flows
│ ├── agent-config.wizard.ts # Agent selection + auth config
│ ├── merge-review.wizard.ts # Merge/PR review flow
│ ├── plan-review.wizard.ts # Plan review flow
│ ├── prd-review.wizard.ts # PRD review flow
│ └── onboarding/ # First-run onboarding wizard
│ ├── onboarding.wizard.ts
│ ├── types.ts
│ └── steps/
│ ├── agent.step.ts
│ ├── ide.step.ts
│ └── workflow-defaults.step.ts
├── prompts/ # Reusable prompt configurations
│ ├── agent-select.prompt.ts
│ ├── auth-method.prompt.ts
│ ├── ide-select.prompt.ts
│ ├── prd-review-question.prompt.ts
│ └── prd-review-summary.prompt.ts
└── themes/ # Custom Inquirer themes
└── shep.theme.ts
@inquirer/prompts imports, test wizard logic and result mapping--flag bypass (non-interactive)