feat(ui): enhance delegation with listr2 task lists and styled output

Phase 5 of CLI UI/UX Enhancement - Delegation + Listr2

Added Listr2 integration for enhanced delegation progress display:
- Intelligent renderer selection (TTY/CI/Claude Code context detection)
- Styled result boxes and tables using ui layer
- Graceful fallback chain: Listr2 → Spinners → Plain text
- All delegation formatters converted to async

Changes:
- src/utils/ui.ts: Added taskList wrapper, isClaudeCodeContext detection
- src/delegation/result-formatter.ts: Async formatting with styled boxes/tables
- src/delegation/delegation-handler.ts: Async format calls
- src/delegation/headless-executor.ts: UI layer progress messages
- tests: Updated all formatter tests to handle async
- docs: Enhanced code standards and codebase summary

All validation passing (157/157 tests)
Phase 5 complete - All 5 phases delivered
This commit is contained in:
kaitranntt committed 2025-12-01 20:53:04 -05:00
1 parent 57016f3f76
commit 716193a682
10 files changed
+527 -227

No files matched your search

+217 -19
View File
@@ -435,7 +435,142 @@ for (const [flag, handler] of Object.entries(commandHandlers)) {
}
```
## Delegation System Patterns (v4.0+)
## UI System Patterns (Phase 5, v4.5.0+)
### Central UI Module (src/utils/ui.ts)
#### Initialization Pattern
```typescript
import { ui } from '../utils/ui';
// Initialize UI (call once at startup)
async function main() {
await ui.init();
// UI functions now available
}
```
#### Semantic Color Usage
```typescript
// Apply semantic colors
ui.color('Success!', 'success') // Green bold
ui.color('Error!', 'error') // Red bold
ui.color('Warning!', 'warning') // Yellow
ui.color('Info', 'info') // Cyan
ui.color('Command: ccs', 'command') // Yellow italic
ui.color('/path/to/file', 'path') // Cyan underline
```
#### ASCII Status Indicators (NO EMOJIS)
```typescript
// Preferred: ASCII indicators only
ui.ok('Installation complete') // [OK] Installation complete
ui.fail('Build failed') // [X] Build failed
ui.warn('Deprecated feature') // [!] Deprecated feature
ui.info('Checking system') // [i] Checking system
// NEVER use emoji (violates CLAUDE.md)
// DON'T: console.log('✓ Success') or '❌ Error'
```
#### Box & Table Rendering
```typescript
// Styled boxes
ui.box('Content here', {
title: 'Header',
borderColor: '#00ECFA',
padding: 1
});
ui.errorBox('Error message', 'ERROR');
ui.infoBox('Info content', 'INFO');
// Styled tables
ui.table([
['Column 1', 'Column 2'],
['Data 1', 'Data 2']
], {
head: ['Header 1', 'Header 2'],
style: 'unicode'
});
```
#### Spinner & Progress
```typescript
// Simple spinner (falls back to plain text in non-TTY)
const spin = await ui.spinner('Processing...');
await doWork();
spin.succeed('Done!');
// Spinner with message update
const spin = await ui.spinner('Loading');
spin.update('Still loading...');
spin.succeed('Completed');
```
#### Task Lists (Listr2 Integration - Phase 5)
```typescript
// Create task list with intelligent renderer selection
const ctx = await ui.taskList([
{
title: 'Install dependencies',
task: async () => {
await installDeps();
}
},
{
title: 'Build project',
task: async () => {
await build();
},
skip: () => !needsBuild() ? 'Already built' : undefined
}
], {
concurrent: false // Set true for parallel execution
});
// Renderer selection (automatic):
// - TTY: Default renderer with subtask hierarchy
// - Non-TTY: Simple renderer (plain text)
// - CI environment: Simple renderer
// - Claude Code context: Fallback spinner-based
```
#### Context Detection
```typescript
// Check if running in interactive TTY
if (ui.isInteractive()) {
// Can use full spinner/box features
}
// Check if running inside Claude Code tool
if (ui.isClaudeCodeContext()) {
// May need fallback rendering
}
```
### UI Compliance Rules (STRICT)
**Mandatory**:
- ALWAYS call `await ui.init()` before using any UI functions
- ASCII status indicators ONLY: [OK], [X], [!], [i] - NO EMOJIS
- Respect NO_COLOR and FORCE_COLOR environment variables
- Use semantic colors (success, error, warning, info, dim, primary, secondary, command, path)
**Patterns**:
- Status messages: `ui.ok()`, `ui.fail()`, `ui.warn()`, `ui.info()`
- Styled output: `ui.box()`, `ui.table()`, `ui.spinner()`
- Progress: Use `ui.taskList()` for multi-step operations (Phase 5)
- Fallback-first: Always test in non-TTY (pipe) mode
**Testing**:
```bash
# Test in non-TTY (pipes/CI)
ccs doctor | cat # Forces plain text output
NO_COLOR=1 ccs doctor # Disables colors
```
## Delegation System Patterns (v4.0+, Phase 5 Enhanced)
### Stream-JSON Parsing
@@ -532,12 +667,76 @@ function executeHeadless(claudeCli, profile, prompt, sessionId = null) {
}
```
### Result Formatting Pattern
### Result Formatting Pattern (Phase 5 Enhanced - Async)
#### Cost and Duration Extraction
```javascript
// Extract cost and duration from Claude CLI output
function parseExecutionStats(output) {
#### Async Result Formatter with UI Integration
```typescript
// result-formatter.ts - Phase 5 now fully async
import { ui } from '../utils/ui';
class ResultFormatter {
// Initialize UI and format result
static async format(result: ExecutionResult): Promise<string> {
await ui.init(); // Phase 5: Initialize UI layer
// Build styled output
let output = '';
// Header box with status indicator
const modelName = this.getModelDisplayName(result.profile);
const headerIcon = result.success ? '[i]' : '[X]';
output += ui.box(`${headerIcon} Delegated to ${modelName}`, {
borderStyle: 'round',
padding: 0,
});
output += '\n\n';
// Info table with styled columns
output += this.formatInfoTable(result);
// Error details if needed
if (result.errors && result.errors.length > 0) {
output += '\n' + ui.errorBox('Execution Errors', 'ERRORS');
}
return output;
}
// Phase 5: Table formatting
private static formatInfoTable(result: ExecutionResult): string {
const rows = [
['Working Directory', result.cwd],
['Model', this.getModelDisplayName(result.profile)],
['Duration', `${(result.duration / 1000).toFixed(2)}s`],
['Exit Code', result.exitCode === 0 ? '[OK]' : '[X]'],
];
if (result.totalCost) {
rows.push(['Total Cost', `$${result.totalCost.toFixed(4)}`]);
}
return ui.table(rows, {
style: 'unicode',
wordWrap: true
});
}
}
// Usage in delegation-handler.ts
const formatted = await ResultFormatter.format(result); // Phase 5: Now async!
console.log(formatted);
```
#### Cost and Duration Extraction (Unchanged from v4.0)
```typescript
// Extract cost and duration from stream-JSON output
interface ExecutionStats {
cost: number | null;
duration: number | null;
exitCode: number;
}
function parseExecutionStats(output: string): ExecutionStats {
const costRegex = /Cost:\s+\$(\d+\.\d+)/;
const durationRegex = /Duration:\s+(\d+)ms/;
@@ -546,20 +745,10 @@ function parseExecutionStats(output) {
return {
cost: costMatch ? parseFloat(costMatch[1]) : null,
duration: durationMatch ? parseInt(durationMatch[1]) : null
duration: durationMatch ? parseInt(durationMatch[1]) : null,
exitCode: 0
};
}
// Format results
function formatResults(exitCode, stats) {
const status = exitCode === 0 ? '[OK]' : '[X]';
const costStr = stats.cost ? `\$${stats.cost.toFixed(4)}` : 'N/A';
const durationStr = stats.duration ? `${(stats.duration / 1000).toFixed(2)}s` : 'N/A';
console.log(`\n${status} Execution complete`);
console.log(` Cost: ${costStr}`);
console.log(` Duration: ${durationStr}`);
}
```
## Symlinking Patterns (v4.1+)
@@ -960,10 +1149,19 @@ These code standards ensure the CCS codebase remains:
- **Compatible**: Cross-platform symlinking, Windows fallbacks, unified behavior
- **Extensible**: Clean subsystem boundaries, reusable patterns
- **Type-Safe**: Enhanced ESLint strictness enforces zero-tolerance for code quality issues
- **User-Friendly**: Semantic UI system with intelligent fallback rendering (Phase 5)
**Phase 5 (2025-12-01) - UI & Listr2 Integration**:
- **Central UI Module**: src/utils/ui.ts with semantic colors, status indicators, boxes, tables
- **Listr2 Integration**: Task list progress with intelligent renderer selection
- **Claude Code Detection**: Automatic fallback for tool context (isClaudeCodeContext)
- **Async Formatting**: Result formatter now async with ui.init() call
- **Compliance**: ASCII-only indicators ([OK], [X], [!], [i]), NO_COLOR respect
**v4.x Specific Standards**:
- **Delegation patterns**: Stream-JSON parsing, session management, headless execution
- **Symlinking patterns**: Cross-platform symlink creation, validation, repair
- **UI patterns**: Semantic colors, status indicators, boxes, tables, spinners, task lists
- **Subsystem organization**: Clear separation (auth, delegation, glmt, management, utils)
- **Naming conventions**: handler, executor, manager, validator, formatter, parser suffixes
@@ -973,4 +1171,4 @@ These code standards ensure the CCS codebase remains:
- **No shell dependencies**: error-codes.sh, progress-indicator.sh, prompt.sh removed
- **First-run bootstrap**: Auto-installs @kaitranntt/ccs npm package globally
Following these standards helps maintain the quality, modularity, and extensibility of the v4.x architecture while enabling future development with AI delegation, shared data management, and comprehensive diagnostics.
Following these standards helps maintain the quality, modularity, and extensibility of the v4.x architecture while enabling future development with AI delegation, shared data management, and comprehensive diagnostics. Phase 5 adds a professional UI layer that gracefully degrades in non-TTY environments while maintaining strict compliance with project constraints.
+39 -21
View File
@@ -23,7 +23,7 @@ CCS (Claude Code Switch) v4.5.0 is a lightweight CLI wrapper enabling instant pr
- **Phase 02 (2025-11-28)**: Modular command architecture, native installer deprecation, main file 44.6% reduction
- **v4.5.0**: npm-first distribution, TypeScript package with quality gates, modular commands, text-only output (no emojis)
## Core Components (Phase 02 Complete - 2025-11-28)
## Core Components (Phase 05 Complete - 2025-12-01 | UI Phase 1 + Listr2)
### 1. Main Entry Point (`src/ccs.ts` - 593 lines, 44.6% reduction)
@@ -103,16 +103,16 @@ interface CommandHandler {
- **shell-executor.ts** (1.5KB): Cross-platform shell command execution with process management
- **package-manager-detector.ts** (3.8KB): Package manager detection (npm, yarn, pnpm, bun)
### 3. Delegation System (`src/delegation/` - ~1,200 lines)
### 3. Delegation System (`src/delegation/` - ~1,200 lines, Phase 5 Enhanced)
**New in v4.0**: Complete delegation subsystem
**New in v4.0**: Complete delegation subsystem; **Phase 5 Enhanced** with UI layer & Listr2
**Components**:
- **delegation-handler.js** (~300 lines): Routes `-p` commands, validates profiles
- **headless-executor.js** (~400 lines): Executes Claude CLI in headless mode with stream-JSON
- **session-manager.js** (~200 lines): Manages delegation session persistence (continue support)
- **result-formatter.js** (~150 lines): Formats execution results with cost/duration
- **settings-parser.js** (~150 lines): Parses profile settings for validation
- **delegation-handler.ts** (~300 lines): Routes `-p` commands, validates profiles; async formatting
- **headless-executor.ts** (~400 lines): Executes Claude CLI in headless mode with stream-JSON; UI progress
- **session-manager.ts** (~200 lines): Manages delegation session persistence (continue support)
- **result-formatter.ts** (~150 lines): **Async formatting** with styled boxes and tables (Phase 5)
- **settings-parser.ts** (~150 lines): Parses profile settings for validation
**Key Features**:
- **Stream-JSON output**: Real-time tool visibility (`--output-format stream-json --verbose`)
@@ -121,6 +121,11 @@ interface CommandHandler {
- **Signal handling**: Ctrl+C kills child processes properly
- **Cost tracking**: USD cost display per delegation
- **13 Claude Code tools** supported: Bash, Read, Write, Edit, Glob, Grep, NotebookEdit, SlashCommand, TodoWrite, etc.
- **Phase 5 Enhancements**:
- **Styled output**: UI layer integration for semantic boxes and tables
- **Async formatting**: Result formatter now fully async with ui.init() call
- **Listr2 integration**: Optional task list progress in TTY mode
- **Fallback chain**: Graceful degradation for non-TTY/CI environments
**Delegation Flow**:
```
@@ -271,20 +276,20 @@ src/ # TypeScript source files (Phase 02 Modular Archite
│ ├── instance-manager.ts # Instance lifecycle (~220 lines)
│ ├── recovery-manager.ts # Auto-recovery (~80 lines)
│ └── shared-manager.ts # Shared symlinking (~50 lines)
├── utils/ # Utilities (expanded in v4.x + Phase 02, UI Phase 1)
├── utils/ # Utilities (expanded in v4.x + Phase 02 + Phase 05, UI + Listr2)
│ ├── claude-detector.ts # CLI detection (~70 lines)
│ ├── claude-dir-installer.ts # .claude/ installer (v4.1.1, ~150 lines)
│ ├── claude-symlink-manager.ts # Selective symlinks (v4.1, ~200 lines)
│ ├── config-manager.ts # Config management (~80 lines)
│ ├── shell-executor.ts # 1.5KB - Cross-platform execution (Phase 02 NEW)
│ ├── package-manager-detector.ts # 3.8KB - Package manager detection (Phase 02 NEW)
│ ├── ui.ts # 5.2KB - Central UI abstraction (UI Phase 1 NEW)
│ ├── delegation-validator.js # Delegation validation (v4.0, ~100 lines)
│ ├── error-codes.js # Error codes (~50 lines)
│ ├── error-manager.js # Error handling (~200 lines)
│ ├── helpers.js # Utilities (~100 lines)
│ ├── progress-indicator.js # Progress display (~150 lines)
│ ├── prompt.js # User prompting (~100 lines)
│ ├── shell-executor.ts # 1.5KB - Cross-platform execution (Phase 02)
│ ├── package-manager-detector.ts # 3.8KB - Package manager detection (Phase 02)
│ ├── ui.ts # 5.2KB - Central UI abstraction (Phase 5, Listr2 integration)
│ ├── delegation-validator.ts # Delegation validation (v4.0, ~100 lines)
│ ├── error-codes.ts # Error codes (~50 lines)
│ ├── error-manager.ts # Error handling (~200 lines)
│ ├── helpers.ts # Utilities (~100 lines)
│ ├── progress-indicator.ts # Progress display (~150 lines)
│ ├── prompt.ts # User prompting (~100 lines)
│ ├── shell-completion.ts # Shell completion (v4.1.4, ~250 lines)
│ └── update-checker.ts # Update checker (v4.1, ~100 lines)
├── types/ # TypeScript type definitions
@@ -427,9 +432,9 @@ Claude CLI: Read credentials from instance, execute
## Key Features (v4.5.0 - Phase 02 Complete, UI Phase 1)
### 0. Central UI Abstraction Layer (UI Phase 1 - 2025-12-01)
### 0. Central UI Abstraction Layer (UI Phase 1 - 2025-12-01, Phase 5 Complete)
- **New Module**: src/utils/ui.ts (5.2KB) - Semantic, TTY-aware CLI styling
- **Dependencies**: chalk@5.6.2, boxen@8.0.1, gradient-string@3.0.0, cli-table3@0.6.5, ora@5.4.1
- **Dependencies**: chalk@5.6.2, boxen@8.0.1, gradient-string@3.0.0, cli-table3@0.6.5, ora@5.4.1, listr2@8.0.0
- **Features**:
- Semantic color system (success, error, warning, info, dim, primary, secondary, command, path)
- ASCII-only status indicators ([OK], [X], [!], [i]) - NO EMOJIS per CLAUDE.md
@@ -438,10 +443,15 @@ Claude CLI: Read credentials from instance, execute
- Table rendering via cli-table3
- Spinner/progress (ora wrapper with fallback)
- Section headers with optional gradient
- **Listr2 task lists** (Phase 5 NEW) - intelligent renderer selection:
- TTY mode: Default renderer with subtask hierarchy
- Non-TTY/CI: Simple renderer for clean output
- Claude Code detection: Automatic fallback for tool context
- Lazy loading of ESM modules for CommonJS compatibility
- **Type Support**: SemanticColor, BoxOptions, TableOptions, SpinnerOptions, SpinnerController
- **Type Support**: SemanticColor, BoxOptions, TableOptions, SpinnerOptions, SpinnerController, TaskItem, TaskListOptions
- **Compliance**: Strict CLAUDE.md adherence (no emojis, TTY-aware, NO_COLOR respect)
- **Fallback Architecture**: Works in non-TTY environments with graceful degradation
- **Claude Code Integration** (Phase 5): `isClaudeCodeContext()` detection for adaptive UI rendering
### 1. npm-First Installation (Phase 02 - 2025-11-28)
- **Recommended method**: All users directed to npm installation
@@ -569,6 +579,14 @@ Claude CLI: Read credentials from instance, execute
## Summary
**CCS Phase 5 Achievements (2025-12-01, UI + Listr2 Integration)**:
- **Listr2 Task Lists**: Integrated task list progress display with intelligent renderer selection
- **Claude Code Detection**: Automatic fallback for tool context via `isClaudeCodeContext()`
- **Async Result Formatting**: Delegation system now fully async with ui initialization
- **UI Layer Integration**: Styled boxes and tables for enhanced delegation output
- **Adaptive Rendering**: TTY (default), non-TTY (simple), CI (simple), Claude Code (fallback)
- **Type System**: TaskItem, TaskListOptions for task list operations
**CCS UI Phase 1 Achievements (2025-12-01)**:
- **Central UI Module**: Introduced src/utils/ui.ts for semantic, TTY-aware CLI styling
- **CLAUDE.md Compliance**: ASCII-only indicators, NO_COLOR respect, TTY detection