or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

commands.mdconfiguration.mdevents.mdexecution.mdextensions.mdindex.mdstorage.mdui.md

ui.mddocs/

0

# User Interface Control

1

2

Terminal UI management including show/hide prompt, logging, user interaction through prompts, and advanced UI redraw functionality.

3

4

## Capabilities

5

6

### Show Interface

7

8

Shows the Vorpal prompt in the terminal.

9

10

```javascript { .api }

11

/**

12

* Shows the vorpal prompt in the terminal

13

* @returns Vorpal instance for chaining

14

*/

15

function show(): Vorpal;

16

```

17

18

**Usage Example:**

19

20

```javascript

21

const vorpal = require('vorpal')();

22

23

// Setup commands first

24

vorpal

25

.command('hello', 'Says hello')

26

.action(function(args, callback) {

27

this.log('Hello World!');

28

callback();

29

});

30

31

// Show the interactive prompt

32

vorpal

33

.delimiter('myapp$')

34

.show();

35

```

36

37

### Hide Interface

38

39

Hides the Vorpal prompt from the terminal.

40

41

```javascript { .api }

42

/**

43

* Hides the vorpal prompt from the terminal

44

* @returns Vorpal instance for chaining

45

*/

46

function hide(): Vorpal;

47

```

48

49

**Usage Example:**

50

51

```javascript

52

const vorpal = require('vorpal')();

53

54

// Show the prompt initially

55

vorpal.show();

56

57

// Later, hide it during some operation

58

vorpal.hide();

59

60

// Processing something in background...

61

setTimeout(() => {

62

console.log('Background task completed');

63

// Show the prompt again

64

vorpal.show();

65

}, 2000);

66

```

67

68

### Logging

69

70

Logs output to the console through Vorpal's logging system.

71

72

```javascript { .api }

73

/**

74

* Logs output to console through Vorpal's logging system

75

* @param args - Arguments to log (same as console.log)

76

* @returns Vorpal instance for chaining

77

*/

78

function log(...args: any[]): Vorpal;

79

```

80

81

**Usage Examples:**

82

83

```javascript

84

const vorpal = require('vorpal')();

85

86

// Basic logging

87

vorpal.log('Hello, world!');

88

89

// Multiple arguments

90

vorpal.log('User:', 'john', 'Age:', 25);

91

92

// Logging objects

93

vorpal.log('Config:', { port: 3000, env: 'development' });

94

95

// In command actions

96

vorpal

97

.command('status', 'Shows application status')

98

.action(function(args, callback) {

99

// Use this.log within command context

100

this.log('Application is running');

101

this.log('Status: OK');

102

103

// Or use vorpal.log from outside

104

callback();

105

});

106

```

107

108

### User Prompts

109

110

Prompts the user for input with configurable options.

111

112

```javascript { .api }

113

/**

114

* Prompts user for input

115

* @param options - Prompt configuration object or array of prompts

116

* @param userCallback - Optional callback function (if omitted, returns Promise)

117

* @returns Promise when no callback provided

118

*/

119

function prompt(options?: PromptOptions | PromptOptions[], userCallback?: (result: any) => void): Promise<any>;

120

121

interface PromptOptions {

122

type?: 'input' | 'password' | 'confirm' | 'list' | 'rawlist' | 'expand' | 'checkbox' | 'editor';

123

name?: string;

124

message?: string;

125

default?: any;

126

choices?: string[] | ChoiceOption[];

127

validate?: (input: any) => boolean | string;

128

filter?: (input: any) => any;

129

when?: boolean | ((answers: any) => boolean);

130

}

131

132

interface ChoiceOption {

133

name: string;

134

value?: any;

135

short?: string;

136

}

137

```

138

139

**Usage Examples:**

140

141

```javascript

142

const vorpal = require('vorpal')();

143

144

// Single input prompt with callback

145

vorpal.prompt({

146

type: 'input',

147

name: 'username',

148

message: 'Enter your username:',

149

default: 'guest'

150

}, function(result) {

151

console.log('Username:', result.username);

152

});

153

154

// Promise-based prompting

155

vorpal.prompt({

156

type: 'password',

157

name: 'password',

158

message: 'Enter your password:'

159

})

160

.then(function(result) {

161

console.log('Password length:', result.password.length);

162

});

163

164

// Multiple prompts

165

vorpal.prompt([

166

{

167

type: 'input',

168

name: 'name',

169

message: 'What is your name?'

170

},

171

{

172

type: 'list',

173

name: 'color',

174

message: 'What is your favorite color?',

175

choices: ['Red', 'Blue', 'Green', 'Yellow']

176

},

177

{

178

type: 'confirm',

179

name: 'confirmed',

180

message: 'Are you sure?',

181

default: true

182

}

183

])

184

.then(function(answers) {

185

console.log('Name:', answers.name);

186

console.log('Color:', answers.color);

187

console.log('Confirmed:', answers.confirmed);

188

});

189

190

// Validation example

191

vorpal.prompt({

192

type: 'input',

193

name: 'email',

194

message: 'Enter your email:',

195

validate: function(input) {

196

const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

197

if (!emailRegex.test(input)) {

198

return 'Please enter a valid email address';

199

}

200

return true;

201

}

202

})

203

.then(function(result) {

204

console.log('Valid email:', result.email);

205

});

206

207

// Using within command actions

208

vorpal

209

.command('setup', 'Interactive setup')

210

.action(function(args, callback) {

211

const self = this;

212

213

self.prompt([

214

{

215

type: 'input',

216

name: 'appName',

217

message: 'Application name:'

218

},

219

{

220

type: 'list',

221

name: 'environment',

222

message: 'Select environment:',

223

choices: ['development', 'staging', 'production']

224

}

225

], function(result) {

226

self.log(`Setting up ${result.appName} for ${result.environment}`);

227

callback();

228

});

229

});

230

```

231

232

### Conditional Prompts

233

234

Advanced prompting with conditional logic:

235

236

```javascript

237

vorpal.prompt([

238

{

239

type: 'confirm',

240

name: 'needsDatabase',

241

message: 'Do you need a database?'

242

},

243

{

244

type: 'list',

245

name: 'databaseType',

246

message: 'Select database type:',

247

choices: ['MySQL', 'PostgreSQL', 'MongoDB', 'SQLite'],

248

when: function(answers) {

249

return answers.needsDatabase;

250

}

251

},

252

{

253

type: 'input',

254

name: 'databaseUrl',

255

message: 'Database connection URL:',

256

when: function(answers) {

257

return answers.needsDatabase;

258

},

259

validate: function(input) {

260

if (!input.trim()) {

261

return 'Database URL is required';

262

}

263

return true;

264

}

265

}

266

])

267

.then(function(answers) {

268

if (answers.needsDatabase) {

269

console.log(`Using ${answers.databaseType} at ${answers.databaseUrl}`);

270

} else {

271

console.log('No database configured');

272

}

273

});

274

```

275

276

## Complete UI Example

277

278

```javascript

279

const vorpal = require('vorpal')();

280

281

// Setup interactive CLI with rich UI

282

vorpal

283

.delimiter('myapp$')

284

.banner('Welcome to My Application v1.0.0')

285

.command('configure', 'Interactive configuration')

286

.action(function(args, callback) {

287

const self = this;

288

289

self.log('Starting configuration wizard...');

290

291

self.prompt([

292

{

293

type: 'input',

294

name: 'name',

295

message: 'Project name:',

296

default: 'my-project'

297

},

298

{

299

type: 'list',

300

name: 'framework',

301

message: 'Select framework:',

302

choices: [

303

{ name: 'Express.js', value: 'express' },

304

{ name: 'Koa.js', value: 'koa' },

305

{ name: 'Fastify', value: 'fastify' }

306

]

307

},

308

{

309

type: 'checkbox',

310

name: 'features',

311

message: 'Select features:',

312

choices: [

313

'Authentication',

314

'Database',

315

'Caching',

316

'Logging',

317

'Testing'

318

]

319

},

320

{

321

type: 'confirm',

322

name: 'proceed',

323

message: 'Proceed with configuration?',

324

default: true

325

}

326

], function(result) {

327

if (result.proceed) {

328

self.log('Configuration saved:');

329

self.log('- Name:', result.name);

330

self.log('- Framework:', result.framework);

331

self.log('- Features:', result.features.join(', '));

332

} else {

333

self.log('Configuration cancelled');

334

}

335

callback();

336

});

337

});

338

339

// Show the interface

340

vorpal.show();

341

```

342

343

## Advanced UI Methods

344

345

### Prompt Pause and Resume

346

347

Controls prompt state for complex user interactions.

348

349

```javascript { .api }

350

/**

351

* Pauses active prompt, returning the value of what had been typed so far

352

* @returns Current prompt input string or false if no active prompt

353

*/

354

function pause(): string | false;

355

356

/**

357

* Resumes active prompt with optional text to fill prompt with

358

* @param val - Optional text to fill prompt with on resume

359

* @returns UI instance for chaining

360

*/

361

function resume(val?: string): UI;

362

```

363

364

**Usage Example:**

365

366

```javascript

367

const vorpal = require('vorpal')();

368

369

vorpal

370

.command('interactive', 'Interactive command with pause/resume')

371

.action(function(args, callback) {

372

const self = this;

373

374

// Start a prompt

375

self.prompt({

376

type: 'input',

377

name: 'data',

378

message: 'Enter some data (will be paused):'

379

}, function(result) {

380

self.log('Final result:', result.data);

381

callback();

382

});

383

384

// Pause the prompt after 2 seconds

385

setTimeout(() => {

386

const currentInput = vorpal.ui.pause();

387

self.log('Prompt paused. Current input:', currentInput);

388

389

// Do some processing...

390

setTimeout(() => {

391

self.log('Resuming prompt...');

392

vorpal.ui.resume(currentInput + ' [processed]');

393

}, 1000);

394

}, 2000);

395

});

396

```

397

398

### Prompt Cancellation

399

400

Cancels the currently active prompt.

401

402

```javascript { .api }

403

/**

404

* Cancels the active prompt

405

* @returns UI instance for chaining

406

*/

407

function cancel(): UI;

408

```

409

410

**Usage Example:**

411

412

```javascript

413

const vorpal = require('vorpal')();

414

415

vorpal

416

.command('cancelable', 'A command with cancelable prompt')

417

.action(function(args, callback) {

418

const self = this;

419

420

// Start a prompt

421

self.prompt({

422

type: 'input',

423

name: 'data',

424

message: 'Enter data (will auto-cancel in 5s):'

425

})

426

.then(result => {

427

self.log('Data entered:', result.data);

428

})

429

.catch(err => {

430

self.log('Prompt was cancelled');

431

})

432

.finally(() => {

433

callback();

434

});

435

436

// Auto-cancel after 5 seconds

437

setTimeout(() => {

438

self.log('Auto-cancelling prompt...');

439

vorpal.ui.cancel();

440

}, 5000);

441

});

442

```

443

444

### UI Redraw Methods

445

446

Advanced terminal output control for dynamic content updates.

447

448

```javascript { .api }

449

/**

450

* Writes over existing logging, useful for progress indicators

451

* @param str - Content to write over existing output

452

* @returns UI instance for chaining

453

*/

454

function redraw(str: string): UI;

455

456

/**

457

* Clears all redraw content permanently

458

* @returns UI instance for chaining

459

*/

460

function redraw.clear(): UI;

461

462

/**

463

* Makes current redraw content permanent

464

* @returns UI instance for chaining

465

*/

466

function redraw.done(): UI;

467

```

468

469

**Usage Examples:**

470

471

```javascript

472

const vorpal = require('vorpal')();

473

474

vorpal

475

.command('progress', 'Shows a progress indicator')

476

.action(function(args, callback) {

477

const self = this;

478

let progress = 0;

479

const total = 100;

480

481

const interval = setInterval(() => {

482

progress += 10;

483

const percentage = Math.round((progress / total) * 100);

484

const bar = '█'.repeat(Math.floor(percentage / 5)) +

485

'░'.repeat(20 - Math.floor(percentage / 5));

486

487

// Update the same line with progress

488

vorpal.ui.redraw(`Progress: [${bar}] ${percentage}%`);

489

490

if (progress >= total) {

491

clearInterval(interval);

492

// Make the final progress permanent

493

vorpal.ui.redraw.done();

494

self.log('Process completed!');

495

callback();

496

}

497

}, 200);

498

});

499

500

vorpal

501

.command('loading', 'Shows a loading spinner')

502

.action(function(args, callback) {

503

const self = this;

504

const spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];

505

let i = 0;

506

507

const interval = setInterval(() => {

508

vorpal.ui.redraw(`Loading ${spinner[i % spinner.length]} Please wait...`);

509

i++;

510

}, 100);

511

512

// Simulate work

513

setTimeout(() => {

514

clearInterval(interval);

515

// Clear the loading message

516

vorpal.ui.redraw.clear();

517

self.log('Loading completed!');

518

callback();

519

}, 3000);

520

});

521

522

vorpal

523

.command('live-data', 'Shows live updating data')

524

.action(function(args, callback) {

525

const self = this;

526

let counter = 0;

527

528

self.log('Starting live data feed (Ctrl+C to stop):');

529

530

const interval = setInterval(() => {

531

const timestamp = new Date().toLocaleTimeString();

532

const data = {

533

counter: ++counter,

534

timestamp: timestamp,

535

random: Math.floor(Math.random() * 1000)

536

};

537

538

// Update the display with current data

539

vorpal.ui.redraw(JSON.stringify(data, null, 2));

540

}, 1000);

541

542

// Handle cancellation

543

const originalCancel = self.cancel;

544

self.cancel = function() {

545

clearInterval(interval);

546

vorpal.ui.redraw.clear();

547

self.log('Live data feed stopped');

548

if (originalCancel) originalCancel.call(self);

549

callback();

550

};

551

552

// Auto-stop after 10 seconds for demo

553

setTimeout(() => {

554

clearInterval(interval);

555

vorpal.ui.redraw.done(); // Keep the last data visible

556

self.log('Live data feed ended');

557

callback();

558

}, 10000);

559

});

560

```

561

562

### Dynamic Status Display

563

564

Advanced example combining multiple UI methods:

565

566

```javascript

567

const vorpal = require('vorpal')();

568

569

vorpal

570

.command('system-monitor', 'Shows real-time system information')

571

.action(function(args, callback) {

572

const self = this;

573

const os = require('os');

574

575

self.log('System Monitor Started (press any key to stop)');

576

577

let monitoring = true;

578

const interval = setInterval(() => {

579

if (!monitoring) return;

580

581

const cpuUsage = process.cpuUsage();

582

const memUsage = process.memoryUsage();

583

const uptime = process.uptime();

584

585

const display = [

586

'=== System Monitor ===',

587

`Uptime: ${Math.floor(uptime)}s`,

588

`CPU User: ${(cpuUsage.user / 1000000).toFixed(2)}ms`,

589

`CPU System: ${(cpuUsage.system / 1000000).toFixed(2)}ms`,

590

`Memory RSS: ${(memUsage.rss / 1024 / 1024).toFixed(2)}MB`,

591

`Memory Heap: ${(memUsage.heapUsed / 1024 / 1024).toFixed(2)}MB`,

592

`Memory External: ${(memUsage.external / 1024 / 1024).toFixed(2)}MB`,

593

'=====================',

594

'Press any key to stop monitoring...'

595

].join('\n');

596

597

vorpal.ui.redraw(display);

598

}, 1000);

599

600

// Wait for any key press

601

process.stdin.setRawMode(true);

602

process.stdin.resume();

603

process.stdin.once('data', () => {

604

monitoring = false;

605

clearInterval(interval);

606

607

process.stdin.setRawMode(false);

608

process.stdin.pause();

609

610

vorpal.ui.redraw.clear();

611

self.log('System monitoring stopped');

612

callback();

613

});

614

});

615

```

616

617

## UI Best Practices

618

619

### Responsive Prompts

620

621

Handle different terminal sizes and capabilities:

622

623

```javascript

624

vorpal

625

.command('responsive-ui', 'Shows responsive UI elements')

626

.action(function(args, callback) {

627

const self = this;

628

const terminalWidth = process.stdout.columns || 80;

629

const narrow = terminalWidth < 60;

630

631

if (narrow) {

632

// Simplified UI for narrow terminals

633

self.prompt([

634

{

635

type: 'input',

636

name: 'name',

637

message: 'Name:'

638

},

639

{

640

type: 'confirm',

641

name: 'proceed',

642

message: 'OK?'

643

}

644

], function(result) {

645

self.log('Done:', result.name);

646

callback();

647

});

648

} else {

649

// Full UI for wider terminals

650

self.prompt([

651

{

652

type: 'input',

653

name: 'fullName',

654

message: 'Please enter your full name:'

655

},

656

{

657

type: 'list',

658

name: 'role',

659

message: 'Select your role:',

660

choices: ['Administrator', 'Developer', 'User', 'Guest']

661

},

662

{

663

type: 'confirm',

664

name: 'proceed',

665

message: 'Proceed with these settings?'

666

}

667

], function(result) {

668

self.log('Configuration complete:');

669

self.log('Name:', result.fullName);

670

self.log('Role:', result.role);

671

callback();

672

});

673

}

674

});

675

```

676

677

### Error Recovery

678

679

Handle UI errors gracefully:

680

681

```javascript

682

vorpal

683

.command('robust-ui', 'UI with error handling')

684

.action(function(args, callback) {

685

const self = this;

686

687

function safePrompt(options, retryCount = 0) {

688

const maxRetries = 3;

689

690

self.prompt(options)

691

.then(result => {

692

self.log('Success:', result);

693

callback();

694

})

695

.catch(err => {

696

if (retryCount < maxRetries) {

697

self.log(`Error occurred, retrying... (${retryCount + 1}/${maxRetries})`);

698

setTimeout(() => {

699

safePrompt(options, retryCount + 1);

700

}, 1000);

701

} else {

702

self.log('Max retries exceeded. Operation failed.');

703

callback(err);

704

}

705

});

706

}

707

708

safePrompt({

709

type: 'input',

710

name: 'data',

711

message: 'Enter data:'

712

});

713

});

714

```