Brand Voice
The voice.ts module generates brand voice messages based on session state. These messages appear in the TUI to communicate what Nity is doing in natural language.
Interface
interface VoiceEngine {
getMessage(state: BrandState, context: VoiceContext): string
getLoadingMessage(): string
getErrorMessage(error: ErrorContext): string
getCompletionMessage(summary: WorkSummary): string
}
interface BrandState {
status: 'idle' | 'active' | 'thinking' | 'executing' | 'error' | 'complete'
task?: string
iteration?: number
maxIterations?: number
}
interface VoiceContext {
adapter: string
taskCategory: string
timeElapsed: number
circuitBreakerState: string
}
interface WorkSummary {
filesChanged: number
testsPassing: number
iterations: number
duration: number
}
interface ErrorContext {
type: string
message: string
recoverable: boolean
}State Messages
Idle
"Standing by. Ready when you are."Active
"Working on: {task}"
"Executing via {adapter} — iteration {n}/{max}"Thinking
"Analyzing approach..."
"Evaluating {n} possible strategies"
"Checking circuit breaker... {state}"Executing
"Iteration {n}: Running {taskCategory} task"
"Progress: {summary}"Error
"Hit a snag: {errorType}. {recoverable ? 'Attempting recovery.' : 'Needs your input.'}"
"Circuit breaker: {state} — {reason}"Complete
"Done. {filesChanged} files, {testsPassing} tests passing, {iterations} iterations in {duration}."Voice messages are concise by design. They communicate state and progress without consuming screen real estate. The TUI presence indicator carries the visual weight; the voice provides the narrative.
Message Selection
The voice engine selects messages based on a priority chain:
- Error state — always takes priority
- Execution state — iteration-specific messages
- Thinking state — analysis/planning messages
- Active state — task description
- Idle state — default resting message
function getMessage(state: BrandState, context: VoiceContext): string {
if (state.status === 'error') return getErrorMessage(context)
if (state.status === 'executing') return getExecutionMessage(state, context)
if (state.status === 'thinking') return getThinkingMessage(context)
if (state.status === 'complete') return getCompletionMessage(context)
if (state.status === 'active') return getActiveMessage(state)
return getIdleMessage()
}