or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

error-handling.mdevent-management.mdindex.mdrenderers.mdtask-configuration.mdtask-management.md
tile.json

index.mddocs/

0

# Listr2

1

2

Listr2 is a modern terminal task list library for Node.js that creates beautiful, interactive CLI interfaces. It provides multiple built-in renderers (default, verbose, silent, simple, test) with customizable themes and colors, supports nested task lists with concurrent and sequential execution modes, and includes comprehensive error handling and retry mechanisms with built-in progress indicators and spinners.

3

4

## Package Information

5

6

- **Package Name**: listr2

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install listr2`

10

11

## Core Imports

12

13

```typescript

14

import { Listr } from "listr2";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { Listr } = require("listr2");

21

```

22

23

Additional imports:

24

25

```typescript

26

import {

27

Listr,

28

ListrTaskState,

29

ListrError,

30

ListrEventManager,

31

ListrTaskEventManager,

32

EventManager,

33

DefaultRenderer,

34

SimpleRenderer,

35

VerboseRenderer,

36

PRESET_TIMER,

37

PRESET_TIMESTAMP

38

} from "listr2";

39

```

40

41

## Basic Usage

42

43

```typescript

44

import { Listr } from "listr2";

45

46

const tasks = new Listr([

47

{

48

title: "Installing dependencies",

49

task: () => {

50

// Simulate async work

51

return new Promise(resolve => setTimeout(resolve, 2000));

52

}

53

},

54

{

55

title: "Building project",

56

task: (ctx, task) => {

57

// Access task wrapper for output

58

task.output = "Compiling TypeScript...";

59

return new Promise(resolve => setTimeout(resolve, 3000));

60

}

61

},

62

{

63

title: "Running tests",

64

task: () => {

65

return new Promise(resolve => setTimeout(resolve, 1000));

66

}

67

}

68

]);

69

70

// Run the task list

71

try {

72

await tasks.run();

73

console.log("All tasks completed successfully!");

74

} catch (error) {

75

console.error("Tasks failed:", error);

76

}

77

```

78

79

## Architecture

80

81

Listr2 is built around several key components:

82

83

- **Listr Class**: Main orchestrator that manages task execution, context sharing, and renderer coordination

84

- **Task System**: Individual task management with state tracking, retry logic, and nested task support

85

- **Renderer System**: Pluggable rendering engines for different output formats (TTY, non-TTY, testing)

86

- **Event Management**: Observable-based event system for task state changes and lifecycle events

87

- **Context Sharing**: Type-safe context object passed between tasks for data sharing

88

- **Error Handling**: Comprehensive error collection and reporting with rollback capabilities

89

90

## Capabilities

91

92

### Core Task Management

93

94

Main Listr class for creating and executing task lists with context sharing, concurrent execution, and error handling.

95

96

```typescript { .api }

97

class Listr<Ctx = ListrContext, Renderer = ListrPrimaryRendererValue, FallbackRenderer = ListrSecondaryRendererValue> {

98

constructor(

99

task: ListrTask<Ctx, Renderer, FallbackRenderer> | ListrTask<Ctx, Renderer, FallbackRenderer>[],

100

options?: ListrBaseClassOptions<Ctx, Renderer, FallbackRenderer>,

101

parentTask?: Task<any, Renderer, FallbackRenderer>

102

);

103

104

add(tasks: ListrTask<Ctx, Renderer>[] | ListrTask<Ctx, Renderer>): void;

105

run(context?: Ctx): Promise<Ctx>;

106

isRoot(): boolean;

107

isSubtask(): boolean;

108

}

109

```

110

111

[Task Management](./task-management.md)

112

113

### Task Configuration and Lifecycle

114

115

Individual task definition, execution control, and lifecycle management including skip conditions, retry logic, and rollback functionality.

116

117

```typescript { .api }

118

interface ListrTask<Ctx, Renderer, FallbackRenderer> {

119

title?: string | any[];

120

task: ListrTaskFn<Ctx, Renderer, FallbackRenderer>;

121

enabled?: boolean | ((ctx: Ctx) => boolean | Promise<boolean>);

122

skip?: boolean | string | ((ctx: Ctx) => boolean | string | Promise<boolean | string>);

123

retry?: number | { tries: number; delay?: number };

124

rollback?: ListrTaskFn<Ctx, Renderer, FallbackRenderer>;

125

exitOnError?: boolean | ((ctx: Ctx) => boolean | Promise<boolean>);

126

}

127

128

type ListrTaskFn<Ctx, Renderer, FallbackRenderer> = (

129

ctx: Ctx,

130

task: TaskWrapper<Ctx, Renderer, FallbackRenderer>

131

) => void | ListrTaskResult<Ctx>;

132

```

133

134

[Task Configuration](./task-configuration.md)

135

136

### Rendering System

137

138

Multiple built-in renderers for different environments and use cases, with customizable options and TTY detection.

139

140

```typescript { .api }

141

type ListrRendererValue = 'default' | 'simple' | 'verbose' | 'test' | 'silent' | ListrRendererFactory;

142

143

interface ListrBaseClassOptions<Ctx, Renderer, FallbackRenderer> {

144

renderer?: Renderer;

145

fallbackRenderer?: FallbackRenderer;

146

rendererOptions?: ListrGetRendererOptions<ListrGetRendererClassFromValue<Renderer>>;

147

fallbackRendererOptions?: ListrGetRendererOptions<ListrGetRendererClassFromValue<FallbackRenderer>>;

148

fallbackRendererCondition?: boolean | (() => boolean);

149

silentRendererCondition?: boolean | (() => boolean);

150

}

151

```

152

153

[Renderers](./renderers.md)

154

155

### Event Management

156

157

Observable-based event system for monitoring task state changes, progress updates, and lifecycle events.

158

159

```typescript { .api }

160

class ListrEventManager extends EventManager {

161

// Inherits all EventManager functionality

162

}

163

164

class ListrTaskEventManager extends EventManager {

165

// Inherits all EventManager functionality

166

}

167

168

enum ListrTaskEventType {

169

TITLE = 'TITLE',

170

STATE = 'STATE',

171

ENABLED = 'ENABLED',

172

SUBTASK = 'SUBTASK',

173

PROMPT = 'PROMPT',

174

OUTPUT = 'OUTPUT',

175

MESSAGE = 'MESSAGE',

176

CLOSED = 'CLOSED'

177

}

178

```

179

180

[Event Management](./event-management.md)

181

182

### Error Handling and States

183

184

Comprehensive error handling system with task state management, error collection modes, and rollback capabilities.

185

186

```typescript { .api }

187

class ListrError<Ctx> extends Error {

188

public path: string[];

189

public ctx: Ctx;

190

constructor(error: Error, type: ListrErrorTypes, task: Task);

191

}

192

193

enum ListrTaskState {

194

WAITING = 'WAITING',

195

STARTED = 'STARTED',

196

COMPLETED = 'COMPLETED',

197

FAILED = 'FAILED',

198

SKIPPED = 'SKIPPED',

199

ROLLING_BACK = 'ROLLING_BACK',

200

ROLLED_BACK = 'ROLLED_BACK',

201

RETRY = 'RETRY',

202

PAUSED = 'PAUSED',

203

PROMPT = 'PROMPT',

204

PROMPT_COMPLETED = 'PROMPT_COMPLETED',

205

PROMPT_FAILED = 'PROMPT_FAILED'

206

}

207

208

enum ListrErrorTypes {

209

WILL_RETRY = 'WILL_RETRY',

210

WILL_ROLLBACK = 'WILL_ROLLBACK',

211

HAS_FAILED_TO_ROLLBACK = 'HAS_FAILED_TO_ROLLBACK',

212

HAS_FAILED = 'HAS_FAILED',

213

HAS_FAILED_WITHOUT_ERROR = 'HAS_FAILED_WITHOUT_ERROR'

214

}

215

```

216

217

[Error Handling](./error-handling.md)

218

219

### Presets and Utilities

220

221

Built-in formatting presets for timestamps and timers, plus utility functions for environment detection and UI formatting.

222

223

```typescript { .api }

224

// Timer preset for displaying elapsed time

225

const PRESET_TIMER: PresetTimer;

226

type PresetTimer = LoggerFieldFn<[number]>;

227

228

interface RendererPresetTimer {

229

/** Show duration for the tasks */

230

timer?: PresetTimer;

231

}

232

233

// Timestamp preset for displaying current time

234

const PRESET_TIMESTAMP: PresetTimestamp;

235

type PresetTimestamp = LoggerFieldFn;

236

237

interface RendererPresetTimestamp {

238

/** Show timestamp for each event that has been logged */

239

timestamp?: PresetTimestamp;

240

}

241

242

interface LoggerFieldFn<Args extends any[] = any[]> {

243

/** The value of the given field */

244

field: ((...args: Args) => string) | string;

245

/** Condition to display the given field */

246

condition?: ((...args: Args) => boolean) | boolean;

247

/** Formatting/coloring of the field */

248

format?: (...args: Args) => LoggerFormat;

249

/** Args to pass to other functions whenever this field is triggered */

250

args?: Args;

251

}

252

253

type LoggerFormat = (message?: string) => string;

254

255

// Utility functions

256

function getRenderer<Renderer extends ListrRendererValue, FallbackRenderer extends ListrRendererValue>(options: {

257

renderer: Renderer;

258

rendererOptions: ListrGetRendererOptions<Renderer>;

259

fallbackRenderer: FallbackRenderer;

260

fallbackRendererOptions: ListrGetRendererOptions<FallbackRenderer>;

261

fallbackRendererCondition?: boolean | (() => boolean);

262

silentRendererCondition?: boolean | (() => boolean);

263

}): SupportedRenderer<ListrRendererFactory>;

264

function getRendererClass(renderer: ListrRendererValue): ListrRendererFactory;

265

```

266

267

## Common Types

268

269

```typescript { .api }

270

type ListrContext = Record<PropertyKey, any>;

271

272

type ListrTaskResult<Ctx> =

273

| string

274

| Promise<any>

275

| Listr<Ctx, any, any>

276

| ReadableLike

277

| ObservableLike<any>;

278

279

interface ObservableLike<T> {

280

subscribe: (observer: ObserverLike<T>) => unknown;

281

}

282

283

interface ReadableLike {

284

readable: boolean;

285

read: (size?: number) => string | Buffer;

286

on: (eventName: 'data' | 'error' | 'end', listener: (data: Buffer | string) => void) => unknown;

287

}

288

289

enum ListrEnvironmentVariables {

290

FORCE_UNICODE = 'LISTR_FORCE_UNICODE',

291

FORCE_TTY = 'LISTR_FORCE_TTY',

292

DISABLE_COLOR = 'NO_COLOR',

293

FORCE_COLOR = 'FORCE_COLOR'

294

}

295

296

// Helper types for renderer-related generics

297

type ListrGetRendererClassFromValue<T extends ListrRendererValue> =

298

T extends ListrRendererFactory ? T :

299

T extends 'default' ? typeof DefaultRenderer :

300

T extends 'simple' ? typeof SimpleRenderer :

301

T extends 'verbose' ? typeof VerboseRenderer :

302

T extends 'test' ? typeof TestRenderer :

303

T extends 'silent' ? typeof SilentRenderer :

304

never;

305

306

type ListrGetRendererOptions<T extends ListrRendererFactory> =

307

T extends { rendererOptions: infer R } ? R : Record<PropertyKey, any>;

308

309

type ListrGetRendererTaskOptions<T extends ListrRendererFactory> =

310

T extends { rendererTaskOptions: infer R } ? R : Record<PropertyKey, any>;

311

312

type ListrRendererFactory = new (

313

tasks: Task[],

314

options: Record<PropertyKey, any>,

315

events?: ListrEventManager

316

) => ListrRenderer;

317

318

interface SupportedRenderer<Renderer extends ListrRendererFactory> {

319

renderer: Renderer;

320

options?: ListrGetRendererOptions<Renderer>;

321

selection: ListrRendererSelection;

322

}

323

324

enum ListrRendererSelection {

325

PRIMARY = 'PRIMARY',

326

SECONDARY = 'SECONDARY',

327

SILENT = 'SILENT'

328

}

329

330

// Renderer class declarations

331

declare class ListrRenderer {

332

static rendererOptions: Record<PropertyKey, any>;

333

static rendererTaskOptions: Record<PropertyKey, any>;

334

static nonTTY: boolean;

335

constructor(tasks: Task[], options: Record<PropertyKey, any>, events?: ListrEventManager);

336

render(): void | Promise<void>;

337

end(err?: Error): void;

338

}

339

340

declare class DefaultRenderer extends ListrRenderer {

341

static nonTTY: false;

342

}

343

344

declare class SimpleRenderer extends ListrRenderer {

345

static nonTTY: true;

346

}

347

348

declare class VerboseRenderer extends ListrRenderer {

349

static nonTTY: true;

350

}

351

352

declare class TestRenderer extends ListrRenderer {}

353

354

declare class SilentRenderer extends ListrRenderer {}

355

356

declare abstract class ListrPromptAdapter {

357

constructor(task: Task<any, any, any>, wrapper: TaskWrapper<any, any, any>);

358

protected reportStarted(): void;

359

protected reportFailed(): void;

360

protected reportCompleted(): void;

361

protected restoreState(): void;

362

public abstract run<T = any>(...args: any[]): T | Promise<T>;

363

}

364

365

// Core task classes

366

declare class Task<Ctx, Renderer, FallbackRenderer> {

367

public id: string;

368

public state: ListrTaskState;

369

public title?: string;

370

public output?: string;

371

public subtasks: Task<Ctx, Renderer, FallbackRenderer>[];

372

public retry?: ListrTaskRetry;

373

public message: ListrTaskMessage;

374

public prompt: ListrTaskPrompt;

375

public listr: Listr<Ctx, any, any>;

376

check(ctx: Ctx): Promise<boolean>;

377

isPending(): boolean;

378

isRunning(): boolean;

379

isCompleted(): boolean;

380

isFailed(): boolean;

381

isSkipped(): boolean;

382

isRetrying(): boolean;

383

isRollingBack(): boolean;

384

isRolledBack(): boolean;

385

pause(time: number): Promise<void>;

386

}

387

388

declare class TaskWrapper<Ctx, Renderer, FallbackRenderer> {

389

title: string | any[];

390

output: string | any[];

391

newListr(task: ListrTask<Ctx, Renderer> | ListrTask<Ctx, Renderer>[], options?: ListrBaseClassOptions<Ctx, any, any>): Listr<Ctx, any, any>;

392

report(error: Error, type?: ListrErrorTypes): void;

393

skip(message?: string): void;

394

isRetrying(): Task['retry'];

395

prompt<T extends ListrPromptAdapter = ListrPromptAdapter>(

396

adapter: new (task: Task<Ctx, Renderer, FallbackRenderer>, wrapper: TaskWrapper<Ctx, Renderer, FallbackRenderer>) => T

397

): T;

398

stdout(type?: ListrTaskEventType.OUTPUT | ListrTaskEventType.PROMPT): NodeJS.WritableStream;

399

}

400

```