UNPKG

@listr2/manager

Version:

Extension for Listr2 to easily create sane defaults for task lists.

2,426 lines 84.6 kB
const require_chunk = require('./chunk-DWy1uDak.cjs');
const tty = require_chunk.__toESM(require("tty"));
const util = require_chunk.__toESM(require("util"));
const os = require_chunk.__toESM(require("os"));
const string_decoder = require_chunk.__toESM(require("string_decoder"));
const stream = require_chunk.__toESM(require("stream"));
const crypto = require_chunk.__toESM(require("crypto"));

//#region ../../node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.js
var require_eventemitter3 = require_chunk.__commonJS({ "../../node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.js"(exports, module) {
	var has = Object.prototype.hasOwnProperty, prefix = "~";
	/**
	* Constructor to create a storage for our `EE` objects.
	* An `Events` instance is a plain object whose properties are event names.
	*
	* @constructor
	* @private
	*/
	function Events() {}
	if (Object.create) {
		Events.prototype = Object.create(null);
		if (!new Events().__proto__) prefix = false;
	}
	/**
	* Representation of a single event listener.
	*
	* @param {Function} fn The listener function.
	* @param {*} context The context to invoke the listener with.
	* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
	* @constructor
	* @private
	*/
	function EE(fn, context, once) {
		this.fn = fn;
		this.context = context;
		this.once = once || false;
	}
	/**
	* Add a listener for a given event.
	*
	* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
	* @param {(String|Symbol)} event The event name.
	* @param {Function} fn The listener function.
	* @param {*} context The context to invoke the listener with.
	* @param {Boolean} once Specify if the listener is a one-time listener.
	* @returns {EventEmitter}
	* @private
	*/
	function addListener(emitter, event, fn, context, once) {
		if (typeof fn !== "function") throw new TypeError("The listener must be a function");
		var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
		if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
		else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
		else emitter._events[evt] = [emitter._events[evt], listener];
		return emitter;
	}
	/**
	* Clear event by name.
	*
	* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
	* @param {(String|Symbol)} evt The Event name.
	* @private
	*/
	function clearEvent(emitter, evt) {
		if (--emitter._eventsCount === 0) emitter._events = new Events();
		else delete emitter._events[evt];
	}
	/**
	* Minimal `EventEmitter` interface that is molded against the Node.js
	* `EventEmitter` interface.
	*
	* @constructor
	* @public
	*/
	function EventEmitter$1() {
		this._events = new Events();
		this._eventsCount = 0;
	}
	/**
	* Return an array listing the events for which the emitter has registered
	* listeners.
	*
	* @returns {Array}
	* @public
	*/
	EventEmitter$1.prototype.eventNames = function eventNames() {
		var names = [], events, name;
		if (this._eventsCount === 0) return names;
		for (name in events = this._events) if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
		if (Object.getOwnPropertySymbols) return names.concat(Object.getOwnPropertySymbols(events));
		return names;
	};
	/**
	* Return the listeners registered for a given event.
	*
	* @param {(String|Symbol)} event The event name.
	* @returns {Array} The registered listeners.
	* @public
	*/
	EventEmitter$1.prototype.listeners = function listeners(event) {
		var evt = prefix ? prefix + event : event, handlers = this._events[evt];
		if (!handlers) return [];
		if (handlers.fn) return [handlers.fn];
		for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) ee[i] = handlers[i].fn;
		return ee;
	};
	/**
	* Return the number of listeners listening to a given event.
	*
	* @param {(String|Symbol)} event The event name.
	* @returns {Number} The number of listeners.
	* @public
	*/
	EventEmitter$1.prototype.listenerCount = function listenerCount(event) {
		var evt = prefix ? prefix + event : event, listeners = this._events[evt];
		if (!listeners) return 0;
		if (listeners.fn) return 1;
		return listeners.length;
	};
	/**
	* Calls each of the listeners registered for a given event.
	*
	* @param {(String|Symbol)} event The event name.
	* @returns {Boolean} `true` if the event had listeners, else `false`.
	* @public
	*/
	EventEmitter$1.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
		var evt = prefix ? prefix + event : event;
		if (!this._events[evt]) return false;
		var listeners = this._events[evt], len = arguments.length, args, i;
		if (listeners.fn) {
			if (listeners.once) this.removeListener(event, listeners.fn, void 0, true);
			switch (len) {
				case 1: return listeners.fn.call(listeners.context), true;
				case 2: return listeners.fn.call(listeners.context, a1), true;
				case 3: return listeners.fn.call(listeners.context, a1, a2), true;
				case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
				case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
				case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
			}
			for (i = 1, args = new Array(len - 1); i < len; i++) args[i - 1] = arguments[i];
			listeners.fn.apply(listeners.context, args);
		} else {
			var length = listeners.length, j;
			for (i = 0; i < length; i++) {
				if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true);
				switch (len) {
					case 1:
						listeners[i].fn.call(listeners[i].context);
						break;
					case 2:
						listeners[i].fn.call(listeners[i].context, a1);
						break;
					case 3:
						listeners[i].fn.call(listeners[i].context, a1, a2);
						break;
					case 4:
						listeners[i].fn.call(listeners[i].context, a1, a2, a3);
						break;
					default:
						if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) args[j - 1] = arguments[j];
						listeners[i].fn.apply(listeners[i].context, args);
				}
			}
		}
		return true;
	};
	/**
	* Add a listener for a given event.
	*
	* @param {(String|Symbol)} event The event name.
	* @param {Function} fn The listener function.
	* @param {*} [context=this] The context to invoke the listener with.
	* @returns {EventEmitter} `this`.
	* @public
	*/
	EventEmitter$1.prototype.on = function on(event, fn, context) {
		return addListener(this, event, fn, context, false);
	};
	/**
	* Add a one-time listener for a given event.
	*
	* @param {(String|Symbol)} event The event name.
	* @param {Function} fn The listener function.
	* @param {*} [context=this] The context to invoke the listener with.
	* @returns {EventEmitter} `this`.
	* @public
	*/
	EventEmitter$1.prototype.once = function once(event, fn, context) {
		return addListener(this, event, fn, context, true);
	};
	/**
	* Remove the listeners of a given event.
	*
	* @param {(String|Symbol)} event The event name.
	* @param {Function} fn Only remove the listeners that match this function.
	* @param {*} context Only remove the listeners that have this context.
	* @param {Boolean} once Only remove one-time listeners.
	* @returns {EventEmitter} `this`.
	* @public
	*/
	EventEmitter$1.prototype.removeListener = function removeListener(event, fn, context, once) {
		var evt = prefix ? prefix + event : event;
		if (!this._events[evt]) return this;
		if (!fn) {
			clearEvent(this, evt);
			return this;
		}
		var listeners = this._events[evt];
		if (listeners.fn) {
			if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) clearEvent(this, evt);
		} else {
			for (var i = 0, events = [], length = listeners.length; i < length; i++) if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) events.push(listeners[i]);
			if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
			else clearEvent(this, evt);
		}
		return this;
	};
	/**
	* Remove all listeners, or those of the specified event.
	*
	* @param {(String|Symbol)} [event] The event name.
	* @returns {EventEmitter} `this`.
	* @public
	*/
	EventEmitter$1.prototype.removeAllListeners = function removeAllListeners(event) {
		var evt;
		if (event) {
			evt = prefix ? prefix + event : event;
			if (this._events[evt]) clearEvent(this, evt);
		} else {
			this._events = new Events();
			this._eventsCount = 0;
		}
		return this;
	};
	EventEmitter$1.prototype.off = EventEmitter$1.prototype.removeListener;
	EventEmitter$1.prototype.addListener = EventEmitter$1.prototype.on;
	EventEmitter$1.prefixed = prefix;
	EventEmitter$1.EventEmitter = EventEmitter$1;
	if ("undefined" !== typeof module) module.exports = EventEmitter$1;
} });

//#endregion
//#region ../../node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.mjs
var import_eventemitter3 = require_chunk.__toESM(require_eventemitter3(), 1);
var eventemitter3_default = import_eventemitter3.default;

//#endregion
//#region ../../node_modules/.pnpm/colorette@2.0.20/node_modules/colorette/index.js
const { env = {}, argv = [], platform = "" } = typeof process === "undefined" ? {} : process;
const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
const isForced = "FORCE_COLOR" in env || argv.includes("--color");
const isWindows = platform === "win32";
const isDumbTerminal = env.TERM === "dumb";
const isCompatibleTerminal = tty && tty.isatty && tty.isatty(1) && env.TERM && !isDumbTerminal;
const isCI = "CI" in env && ("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
const isColorSupported = !isDisabled && (isForced || isWindows && !isDumbTerminal || isCompatibleTerminal || isCI);
const replaceClose = (index, string, close, replace, head = string.substring(0, index) + replace, tail = string.substring(index + close.length), next = tail.indexOf(close)) => head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
const clearBleed = (index, string, open, close, replace) => index < 0 ? open + string + close : open + replaceClose(index, string, close, replace) + close;
const filterEmpty = (open, close, replace = open, at = open.length + 1) => (string) => string || !(string === "" || string === void 0) ? clearBleed(("" + string).indexOf(close, at), string, open, close, replace) : "";
const init = (open, close, replace) => filterEmpty(`\x1b[${open}m`, `\x1b[${close}m`, replace);
const colors = {
	reset: init(0, 0),
	bold: init(1, 22, "\x1B[22m\x1B[1m"),
	dim: init(2, 22, "\x1B[22m\x1B[2m"),
	italic: init(3, 23),
	underline: init(4, 24),
	inverse: init(7, 27),
	hidden: init(8, 28),
	strikethrough: init(9, 29),
	black: init(30, 39),
	red: init(31, 39),
	green: init(32, 39),
	yellow: init(33, 39),
	blue: init(34, 39),
	magenta: init(35, 39),
	cyan: init(36, 39),
	white: init(37, 39),
	gray: init(90, 39),
	bgBlack: init(40, 49),
	bgRed: init(41, 49),
	bgGreen: init(42, 49),
	bgYellow: init(43, 49),
	bgBlue: init(44, 49),
	bgMagenta: init(45, 49),
	bgCyan: init(46, 49),
	bgWhite: init(47, 49),
	blackBright: init(90, 39),
	redBright: init(91, 39),
	greenBright: init(92, 39),
	yellowBright: init(93, 39),
	blueBright: init(94, 39),
	magentaBright: init(95, 39),
	cyanBright: init(96, 39),
	whiteBright: init(97, 39),
	bgBlackBright: init(100, 49),
	bgRedBright: init(101, 49),
	bgGreenBright: init(102, 49),
	bgYellowBright: init(103, 49),
	bgBlueBright: init(104, 49),
	bgMagentaBright: init(105, 49),
	bgCyanBright: init(106, 49),
	bgWhiteBright: init(107, 49)
};
const createColors = ({ useColor = isColorSupported } = {}) => useColor ? colors : Object.keys(colors).reduce((colors$1, key) => ({
	...colors$1,
	[key]: String
}), {});
const { reset, bold, dim, italic, underline, inverse, hidden, strikethrough, black, red, green, yellow, blue, magenta, cyan, white, gray, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, blackBright, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright, bgBlackBright, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright } = createColors();

//#endregion
//#region ../../node_modules/.pnpm/rfdc@1.4.1/node_modules/rfdc/index.js
var require_rfdc = require_chunk.__commonJS({ "../../node_modules/.pnpm/rfdc@1.4.1/node_modules/rfdc/index.js"(exports, module) {
	module.exports = rfdc$1;
	function copyBuffer(cur) {
		if (cur instanceof Buffer) return Buffer.from(cur);
		return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length);
	}
	function rfdc$1(opts) {
		opts = opts || {};
		if (opts.circles) return rfdcCircles(opts);
		const constructorHandlers = /* @__PURE__ */ new Map();
		constructorHandlers.set(Date, (o) => new Date(o));
		constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)));
		constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)));
		if (opts.constructorHandlers) for (const handler$1 of opts.constructorHandlers) constructorHandlers.set(handler$1[0], handler$1[1]);
		let handler = null;
		return opts.proto ? cloneProto : clone$1;
		function cloneArray(a, fn) {
			const keys = Object.keys(a);
			const a2 = new Array(keys.length);
			for (let i = 0; i < keys.length; i++) {
				const k = keys[i];
				const cur = a[k];
				if (typeof cur !== "object" || cur === null) a2[k] = cur;
				else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) a2[k] = handler(cur, fn);
				else if (ArrayBuffer.isView(cur)) a2[k] = copyBuffer(cur);
				else a2[k] = fn(cur);
			}
			return a2;
		}
		function clone$1(o) {
			if (typeof o !== "object" || o === null) return o;
			if (Array.isArray(o)) return cloneArray(o, clone$1);
			if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) return handler(o, clone$1);
			const o2 = {};
			for (const k in o) {
				if (Object.hasOwnProperty.call(o, k) === false) continue;
				const cur = o[k];
				if (typeof cur !== "object" || cur === null) o2[k] = cur;
				else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) o2[k] = handler(cur, clone$1);
				else if (ArrayBuffer.isView(cur)) o2[k] = copyBuffer(cur);
				else o2[k] = clone$1(cur);
			}
			return o2;
		}
		function cloneProto(o) {
			if (typeof o !== "object" || o === null) return o;
			if (Array.isArray(o)) return cloneArray(o, cloneProto);
			if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) return handler(o, cloneProto);
			const o2 = {};
			for (const k in o) {
				const cur = o[k];
				if (typeof cur !== "object" || cur === null) o2[k] = cur;
				else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) o2[k] = handler(cur, cloneProto);
				else if (ArrayBuffer.isView(cur)) o2[k] = copyBuffer(cur);
				else o2[k] = cloneProto(cur);
			}
			return o2;
		}
	}
	function rfdcCircles(opts) {
		const refs = [];
		const refsNew = [];
		const constructorHandlers = /* @__PURE__ */ new Map();
		constructorHandlers.set(Date, (o) => new Date(o));
		constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)));
		constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)));
		if (opts.constructorHandlers) for (const handler$1 of opts.constructorHandlers) constructorHandlers.set(handler$1[0], handler$1[1]);
		let handler = null;
		return opts.proto ? cloneProto : clone$1;
		function cloneArray(a, fn) {
			const keys = Object.keys(a);
			const a2 = new Array(keys.length);
			for (let i = 0; i < keys.length; i++) {
				const k = keys[i];
				const cur = a[k];
				if (typeof cur !== "object" || cur === null) a2[k] = cur;
				else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) a2[k] = handler(cur, fn);
				else if (ArrayBuffer.isView(cur)) a2[k] = copyBuffer(cur);
				else {
					const index = refs.indexOf(cur);
					if (index !== -1) a2[k] = refsNew[index];
					else a2[k] = fn(cur);
				}
			}
			return a2;
		}
		function clone$1(o) {
			if (typeof o !== "object" || o === null) return o;
			if (Array.isArray(o)) return cloneArray(o, clone$1);
			if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) return handler(o, clone$1);
			const o2 = {};
			refs.push(o);
			refsNew.push(o2);
			for (const k in o) {
				if (Object.hasOwnProperty.call(o, k) === false) continue;
				const cur = o[k];
				if (typeof cur !== "object" || cur === null) o2[k] = cur;
				else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) o2[k] = handler(cur, clone$1);
				else if (ArrayBuffer.isView(cur)) o2[k] = copyBuffer(cur);
				else {
					const i = refs.indexOf(cur);
					if (i !== -1) o2[k] = refsNew[i];
					else o2[k] = clone$1(cur);
				}
			}
			refs.pop();
			refsNew.pop();
			return o2;
		}
		function cloneProto(o) {
			if (typeof o !== "object" || o === null) return o;
			if (Array.isArray(o)) return cloneArray(o, cloneProto);
			if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) return handler(o, cloneProto);
			const o2 = {};
			refs.push(o);
			refsNew.push(o2);
			for (const k in o) {
				const cur = o[k];
				if (typeof cur !== "object" || cur === null) o2[k] = cur;
				else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) o2[k] = handler(cur, cloneProto);
				else if (ArrayBuffer.isView(cur)) o2[k] = copyBuffer(cur);
				else {
					const i = refs.indexOf(cur);
					if (i !== -1) o2[k] = refsNew[i];
					else o2[k] = cloneProto(cur);
				}
			}
			refs.pop();
			refsNew.pop();
			return o2;
		}
	}
} });

//#endregion
//#region ../listr2/dist/index.js
var import_rfdc = require_chunk.__toESM(require_rfdc(), 1);
/**
* Indicates an UNICODE characters is coming up.
*/
const ANSI_ESCAPE = "\x1B[";
/**
* Generic ANSI escape characters for terminal based operations.
*/
const ANSI_ESCAPE_CODES = {
	CURSOR_HIDE: ANSI_ESCAPE + "?25l",
	CURSOR_SHOW: ANSI_ESCAPE + "?25h"
};
/**
* Environment variables for Listr.
*/
let ListrEnvironmentVariables = /* @__PURE__ */ function(ListrEnvironmentVariables$1) {
	ListrEnvironmentVariables$1["FORCE_UNICODE"] = "LISTR_FORCE_UNICODE";
	ListrEnvironmentVariables$1["FORCE_TTY"] = "LISTR_FORCE_TTY";
	ListrEnvironmentVariables$1["DISABLE_COLOR"] = "NO_COLOR";
	ListrEnvironmentVariables$1["FORCE_COLOR"] = "FORCE_COLOR";
	return ListrEnvironmentVariables$1;
}({});
/**
* The actual error type that is collected and to help identify where the error is triggered from.
*/
let ListrErrorTypes = /* @__PURE__ */ function(ListrErrorTypes$1) {
	/** Task has failed and will try to retry. */
	ListrErrorTypes$1["WILL_RETRY"] = "WILL_RETRY";
	/** Task has failed and will try to rollback. */
	ListrErrorTypes$1["WILL_ROLLBACK"] = "WILL_ROLLBACK";
	/** Task has failed, ran the rollback action but the rollback action itself has failed. */
	ListrErrorTypes$1["HAS_FAILED_TO_ROLLBACK"] = "HAS_FAILED_TO_ROLLBACK";
	/** Task has failed. */
	ListrErrorTypes$1["HAS_FAILED"] = "HAS_FAILED";
	/** Task has failed, but exitOnError is set to false, so will ignore this error. */
	ListrErrorTypes$1["HAS_FAILED_WITHOUT_ERROR"] = "HAS_FAILED_WITHOUT_ERROR";
	return ListrErrorTypes$1;
}({});
/**
* Events that are triggered by Listr.
*
* These are stateful and singleton events by being attached to the main Listr class and propagating to the subtasks.
*
* @see {@link https://listr2.kilic.dev/listr/events.html}
*/
let ListrEventType = /* @__PURE__ */ function(ListrEventType$1) {
	/** Indicates that underlying renderer should refresh the current render. */
	ListrEventType$1["SHOULD_REFRESH_RENDER"] = "SHOUD_REFRESH_RENDER";
	return ListrEventType$1;
}({});
let ListrRendererSelection = /* @__PURE__ */ function(ListrRendererSelection$1) {
	ListrRendererSelection$1["PRIMARY"] = "PRIMARY";
	ListrRendererSelection$1["SECONDARY"] = "SECONDARY";
	ListrRendererSelection$1["SILENT"] = "SILENT";
	return ListrRendererSelection$1;
}({});
/**
* Internal events that are fired from the Task.
*
* @see {@link https://listr2.kilic.dev/task/events.html}
*/
let ListrTaskEventType = /* @__PURE__ */ function(ListrTaskEventType$1) {
	/** Title has changed for the current Task. */
	ListrTaskEventType$1["TITLE"] = "TITLE";
	/**
	* State has changed for the current Task.
	*
	* @see {@link module:listr2.ListrTaskState}
	*/
	ListrTaskEventType$1["STATE"] = "STATE";
	/** The current Task has been marked as enabled. */
	ListrTaskEventType$1["ENABLED"] = "ENABLED";
	/** The current Task is currently processing subtasks. */
	ListrTaskEventType$1["SUBTASK"] = "SUBTASK";
	/** The current Task is now processing a prompt. */
	ListrTaskEventType$1["PROMPT"] = "PROMPT";
	/** The current Task is now dumping output. */
	ListrTaskEventType$1["OUTPUT"] = "OUTPUT";
	/**
	* The current Task is now dumping a message.
	*
	* @see {module:Listr2.ListrTaskMessage}
	*/
	ListrTaskEventType$1["MESSAGE"] = "MESSAGE";
	/** The current Task is closed and no further action in expected. */
	ListrTaskEventType$1["CLOSED"] = "CLOSED";
	return ListrTaskEventType$1;
}({});
/**
* Tasks can be in various states during the execution.
*
* Whenever a state change occurs, the task will emit a {@link module:listr2.ListrTaskEventType.STATE} with the appropriate state.
*/
let ListrTaskState = /* @__PURE__ */ function(ListrTaskState$1) {
	/** Task has not started yet, waiting for pick-up. */
	ListrTaskState$1["WAITING"] = "WAITING";
	/** Task has started. */
	ListrTaskState$1["STARTED"] = "STARTED";
	/** Task has been completed. */
	ListrTaskState$1["COMPLETED"] = "COMPLETED";
	/** Task has failed. */
	ListrTaskState$1["FAILED"] = "FAILED";
	/** Task has been skipped. */
	ListrTaskState$1["SKIPPED"] = "SKIPPED";
	/** Task is currently trying to rollback. */
	ListrTaskState$1["ROLLING_BACK"] = "ROLLING_BACK";
	/** Task has rolledback successfully after failing. */
	ListrTaskState$1["ROLLED_BACK"] = "ROLLED_BACK";
	/** Task is currently retrying. */
	ListrTaskState$1["RETRY"] = "RETRY";
	/** Task is currently paused. */
	ListrTaskState$1["PAUSED"] = "PAUSED";
	/** Task is currently trying to process a prompt. */
	ListrTaskState$1["PROMPT"] = "PROMPT";
	/** Task has successfully processed the prompt. */
	ListrTaskState$1["PROMPT_COMPLETED"] = "PROMPT_COMPLETED";
	/** Task has failed to process the prompt. */
	ListrTaskState$1["PROMPT_FAILED"] = "PROMPT_FAILED";
	return ListrTaskState$1;
}({});
var EventManager = class {
	emitter = new eventemitter3_default();
	emit(dispatch, args) {
		this.emitter.emit(dispatch, args);
	}
	on(dispatch, handler) {
		this.emitter.addListener(dispatch, handler);
	}
	once(dispatch, handler) {
		this.emitter.once(dispatch, handler);
	}
	off(dispatch, handler) {
		this.emitter.off(dispatch, handler);
	}
	complete() {
		this.emitter.removeAllListeners();
	}
};
/**
* Tests to see if the object is an RxJS {@link Observable}
* @param obj the object to test
*/
function isObservable(obj) {
	return !!obj && typeof obj === "object" && typeof obj.subscribe === "function";
}
/**
* Tests to see if the object is an Readable or NodeJS.ReadableStream {@link Readable, NodeJS.ReadableStream}
* @param obj the object to test
*/
function isReadable(obj) {
	return !!obj && typeof obj === "object" && obj.readable === true && typeof obj.read === "function" && typeof obj.on === "function";
}
function isUnicodeSupported() {
	/* istanbul ignore next */
	return !!process.env[ListrEnvironmentVariables.FORCE_UNICODE] || process.platform !== "win32" || !!process.env.CI || !!process.env.WT_SESSION || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty";
}
const CLEAR_LINE_REGEX = "(?:\\u001b|\\u009b)\\[[\\=><~/#&.:=?%@~_-]*[0-9]*[\\a-ln-tqyz=><~/#&.:=?%@~_-]+";
const BELL_REGEX = /\u0007/;
function cleanseAnsi(chunk) {
	return String(chunk).replace(new RegExp(CLEAR_LINE_REGEX, "gmi"), "").replace(new RegExp(BELL_REGEX, "gmi"), "").trim();
}
/**
* Creates color palette through underlying dependency of `colorette`.
*
* @see {@link https://www.npmjs.com/package/colorette}
*/
const color = createColors();
function indent(string, count) {
	return string.replace(/^(?!\s*$)/gm, " ".repeat(count));
}
const FIGURES_MAIN = {
	warning: "⚠",
	cross: "✖",
	arrowDown: "↓",
	tick: "✔",
	arrowRight: "→",
	pointer: "❯",
	checkboxOn: "☒",
	arrowLeft: "←",
	squareSmallFilled: "◼",
	pointerSmall: "›"
};
const FIGURES_FALLBACK = {
	...FIGURES_MAIN,
	warning: "‼",
	cross: "×",
	tick: "√",
	pointer: ">",
	checkboxOn: "[×]",
	squareSmallFilled: "■"
};
const figures = isUnicodeSupported() ? FIGURES_MAIN : FIGURES_FALLBACK;
function splat(message, ...splat$1) {
	return (0, util.format)(String(message), ...splat$1);
}
/** Default ListrLogLevels for the logger */
let ListrLogLevels = /* @__PURE__ */ function(ListrLogLevels$1) {
	ListrLogLevels$1["STARTED"] = "STARTED";
	ListrLogLevels$1["COMPLETED"] = "COMPLETED";
	ListrLogLevels$1["FAILED"] = "FAILED";
	ListrLogLevels$1["SKIPPED"] = "SKIPPED";
	ListrLogLevels$1["OUTPUT"] = "OUTPUT";
	ListrLogLevels$1["TITLE"] = "TITLE";
	ListrLogLevels$1["ROLLBACK"] = "ROLLBACK";
	ListrLogLevels$1["RETRY"] = "RETRY";
	ListrLogLevels$1["PROMPT"] = "PROMPT";
	ListrLogLevels$1["PAUSED"] = "PAUSED";
	return ListrLogLevels$1;
}({});
const LISTR_LOGGER_STYLE = {
	icon: {
		[ListrLogLevels.STARTED]: figures.pointer,
		[ListrLogLevels.FAILED]: figures.cross,
		[ListrLogLevels.SKIPPED]: figures.arrowDown,
		[ListrLogLevels.COMPLETED]: figures.tick,
		[ListrLogLevels.OUTPUT]: figures.pointerSmall,
		[ListrLogLevels.TITLE]: figures.arrowRight,
		[ListrLogLevels.RETRY]: figures.warning,
		[ListrLogLevels.ROLLBACK]: figures.arrowLeft,
		[ListrLogLevels.PAUSED]: figures.squareSmallFilled
	},
	color: {
		[ListrLogLevels.STARTED]: color.yellow,
		[ListrLogLevels.FAILED]: color.red,
		[ListrLogLevels.SKIPPED]: color.yellow,
		[ListrLogLevels.COMPLETED]: color.green,
		[ListrLogLevels.RETRY]: color.yellowBright,
		[ListrLogLevels.ROLLBACK]: color.redBright,
		[ListrLogLevels.PAUSED]: color.yellowBright
	}
};
const LISTR_LOGGER_STDERR_LEVELS = [
	ListrLogLevels.RETRY,
	ListrLogLevels.ROLLBACK,
	ListrLogLevels.FAILED
];
/**
* Creates a new Listr2 logger.
*
* This logger is used throughout the renderers for consistency.
*
* @see {@link https://listr2.kilic.dev/renderer/logger.html}
*/
var ListrLogger = class {
	process;
	constructor(options) {
		this.options = options;
		this.options = {
			useIcons: true,
			toStderr: [],
			...options ?? {}
		};
		this.options.fields ??= {};
		this.options.fields.prefix ??= [];
		this.options.fields.suffix ??= [];
		this.process = this.options.processOutput ?? new ProcessOutput();
	}
	log(level, message, options) {
		const output = this.format(level, message, options);
		if (this.options.toStderr.includes(level)) {
			this.process.toStderr(output);
			return;
		}
		this.process.toStdout(output);
	}
	toStdout(message, options, eol = true) {
		this.process.toStdout(this.format(null, message, options), eol);
	}
	toStderr(message, options, eol = true) {
		this.process.toStderr(this.format(null, message, options), eol);
	}
	wrap(message, options) {
		if (!message) return message;
		return this.applyFormat(`[${message}]`, options);
	}
	splat(...args) {
		const message = args.shift() ?? "";
		return args.length === 0 ? message : splat(message, args);
	}
	suffix(message, ...suffixes) {
		suffixes.filter(Boolean).forEach((suffix) => {
			message += this.spacing(message);
			if (typeof suffix === "string") message += this.wrap(suffix);
			else if (typeof suffix === "object") {
				suffix.args ??= [];
				if (typeof suffix.condition === "function" ? !suffix.condition(...suffix.args) : !(suffix.condition ?? true)) return message;
				message += this.wrap(typeof suffix.field === "function" ? suffix.field(...suffix.args) : suffix.field, { format: suffix?.format(...suffix.args) });
			}
		});
		return message;
	}
	prefix(message, ...prefixes) {
		prefixes.filter(Boolean).forEach((prefix$1) => {
			message = this.spacing(message) + message;
			if (typeof prefix$1 === "string") message = this.wrap(prefix$1) + message;
			else if (typeof prefix$1 === "object") {
				prefix$1.args ??= [];
				if (typeof prefix$1.condition === "function" ? !prefix$1.condition(...prefix$1.args) : !(prefix$1.condition ?? true)) return message;
				message = this.wrap(typeof prefix$1.field === "function" ? prefix$1.field(...prefix$1.args) : prefix$1.field, { format: prefix$1?.format() }) + message;
			}
		});
		return message;
	}
	fields(message, options) {
		if (this.options?.fields?.prefix) message = this.prefix(message, ...this.options.fields.prefix);
		if (options?.prefix) message = this.prefix(message, ...options.prefix);
		if (options?.suffix) message = this.suffix(message, ...options.suffix);
		if (this.options?.fields?.suffix) message = this.suffix(message, ...this.options.fields.suffix);
		return message;
	}
	icon(level, icon) {
		if (!level) return null;
		if (!icon) {
			const i = this.options.icon?.[level];
			icon = typeof i === "function" ? i() : i;
		}
		const coloring = this.options.color?.[level];
		if (icon && coloring) icon = coloring(icon);
		return icon;
	}
	format(level, message, options) {
		if (!Array.isArray(message)) message = [message];
		message = this.splat(message.shift(), ...message).toString().split(os.EOL).filter((m) => !m || m.trim() !== "").map((m) => {
			return this.style(level, this.fields(m, {
				prefix: Array.isArray(options?.prefix) ? options.prefix : [options?.prefix],
				suffix: Array.isArray(options?.suffix) ? options.suffix : [options?.suffix]
			}));
		}).join(os.EOL);
		return message;
	}
	style(level, message) {
		if (!level || !message) return message;
		const icon = this.icon(level, !this.options.useIcons && this.wrap(level));
		if (icon) message = icon + " " + message;
		return message;
	}
	applyFormat(message, options) {
		if (options?.format) return options.format(message);
		return message;
	}
	spacing(message) {
		return typeof message === "undefined" || message.trim() === "" ? "" : " ";
	}
};
var ProcessOutputBuffer = class {
	buffer = [];
	decoder = new string_decoder.StringDecoder();
	constructor(options) {
		this.options = options;
	}
	get all() {
		return this.buffer;
	}
	get last() {
		return this.buffer.at(-1);
	}
	get length() {
		return this.buffer.length;
	}
	write(data, ...args) {
		const callback = args[args.length - 1];
		this.buffer.push({
			time: Date.now(),
			stream: this.options?.stream,
			entry: this.decoder.write(typeof data === "string" ? Buffer.from(data, typeof args[0] === "string" ? args[0] : void 0) : Buffer.from(data))
		});
		if (this.options?.limit) this.buffer = this.buffer.slice(-this.options.limit);
		if (typeof callback === "function") callback();
		return true;
	}
	reset() {
		this.buffer = [];
	}
};
var ProcessOutputStream = class {
	method;
	buffer;
	constructor(stream$1) {
		this.stream = stream$1;
		this.method = stream$1.write;
		this.buffer = new ProcessOutputBuffer({ stream: stream$1 });
	}
	get out() {
		return Object.assign({}, this.stream, { write: this.write.bind(this) });
	}
	hijack() {
		this.stream.write = this.buffer.write.bind(this.buffer);
	}
	release() {
		this.stream.write = this.method;
		const buffer = [...this.buffer.all];
		this.buffer.reset();
		return buffer;
	}
	write(...args) {
		return this.method.apply(this.stream, args);
	}
};
/**
* Creates a new Listr2 process-output controller.
*
* This is used to control the flow to `process.stdout` and `process.stderr` for all renderers.
*
* @see {@link https://listr2.kilic.dev/renderer/process-output.html}
*/
var ProcessOutput = class {
	stream;
	active;
	constructor(stdout, stderr, options) {
		this.options = options;
		this.stream = {
			stdout: new ProcessOutputStream(stdout ?? process.stdout),
			stderr: new ProcessOutputStream(stderr ?? process.stderr)
		};
		this.options = {
			dump: ["stdout", "stderr"],
			leaveEmptyLine: true,
			...options
		};
	}
	get stdout() {
		return this.stream.stdout.out;
	}
	get stderr() {
		return this.stream.stderr.out;
	}
	hijack() {
		if (this.active) throw new Error("ProcessOutput has been already hijacked!");
		this.stream.stdout.write(ANSI_ESCAPE_CODES.CURSOR_HIDE);
		Object.values(this.stream).forEach((stream$1) => stream$1.hijack());
		this.active = true;
	}
	release() {
		const output = Object.entries(this.stream).map(([name, stream$1]) => ({
			name,
			buffer: stream$1.release()
		})).filter((output$1) => this.options.dump.includes(output$1.name)).flatMap((output$1) => output$1.buffer).sort((a, b) => a.time - b.time).map((message) => {
			return {
				...message,
				entry: cleanseAnsi(message.entry)
			};
		}).filter((message) => message.entry);
		if (output.length > 0) {
			if (this.options.leaveEmptyLine) this.stdout.write(os.EOL);
			output.forEach((message) => {
				const stream$1 = message.stream ?? this.stdout;
				stream$1.write(message.entry + os.EOL);
			});
		}
		this.stream.stdout.write(ANSI_ESCAPE_CODES.CURSOR_SHOW);
		this.active = false;
	}
	toStdout(buffer, eol = true) {
		if (eol) buffer = buffer + os.EOL;
		return this.stream.stdout.write(buffer);
	}
	toStderr(buffer, eol = true) {
		if (eol) buffer = buffer + os.EOL;
		return this.stream.stderr.write(buffer);
	}
};
/* istanbul ignore next */
function createWritable(cb) {
	const writable = new stream.Writable();
	writable.rows = Infinity;
	writable.columns = Infinity;
	writable.write = (chunk) => {
		cb(chunk.toString());
		return true;
	};
	return writable;
}
/* istanbul ignore next */
var Spinner = class {
	spinner = !isUnicodeSupported() ? [
		"-",
		"\\",
		"|",
		"/"
	] : [
		"⠋",
		"⠙",
		"⠹",
		"⠸",
		"⠼",
		"⠴",
		"⠦",
		"⠧",
		"⠇",
		"⠏"
	];
	id;
	spinnerPosition = 0;
	spin() {
		this.spinnerPosition = ++this.spinnerPosition % this.spinner.length;
	}
	fetch() {
		return this.spinner[this.spinnerPosition];
	}
	isRunning() {
		return !!this.id;
	}
	start(cb, interval = 100) {
		this.id = setInterval(() => {
			this.spin();
			if (cb) cb();
		}, interval);
	}
	stop() {
		clearInterval(this.id);
	}
};
let ListrDefaultRendererLogLevels = /* @__PURE__ */ function(ListrDefaultRendererLogLevels$1) {
	ListrDefaultRendererLogLevels$1["SKIPPED_WITH_COLLAPSE"] = "SKIPPED_WITH_COLLAPSE";
	ListrDefaultRendererLogLevels$1["SKIPPED_WITHOUT_COLLAPSE"] = "SKIPPED_WITHOUT_COLLAPSE";
	ListrDefaultRendererLogLevels$1["OUTPUT"] = "OUTPUT";
	ListrDefaultRendererLogLevels$1["OUTPUT_WITH_BOTTOMBAR"] = "OUTPUT_WITH_BOTTOMBAR";
	ListrDefaultRendererLogLevels$1["PENDING"] = "PENDING";
	ListrDefaultRendererLogLevels$1["COMPLETED"] = "COMPLETED";
	ListrDefaultRendererLogLevels$1["COMPLETED_WITH_FAILED_SUBTASKS"] = "COMPLETED_WITH_FAILED_SUBTASKS";
	ListrDefaultRendererLogLevels$1["COMPLETED_WITH_FAILED_SISTER_TASKS"] = "COMPLETED_WITH_SISTER_TASKS_FAILED";
	ListrDefaultRendererLogLevels$1["RETRY"] = "RETRY";
	ListrDefaultRendererLogLevels$1["ROLLING_BACK"] = "ROLLING_BACK";
	ListrDefaultRendererLogLevels$1["ROLLED_BACK"] = "ROLLED_BACK";
	ListrDefaultRendererLogLevels$1["FAILED"] = "FAILED";
	ListrDefaultRendererLogLevels$1["FAILED_WITH_FAILED_SUBTASKS"] = "FAILED_WITH_SUBTASKS";
	ListrDefaultRendererLogLevels$1["WAITING"] = "WAITING";
	ListrDefaultRendererLogLevels$1["PAUSED"] = "PAUSED";
	return ListrDefaultRendererLogLevels$1;
}({});
const LISTR_DEFAULT_RENDERER_STYLE = {
	icon: {
		[ListrDefaultRendererLogLevels.SKIPPED_WITH_COLLAPSE]: figures.arrowDown,
		[ListrDefaultRendererLogLevels.SKIPPED_WITHOUT_COLLAPSE]: figures.warning,
		[ListrDefaultRendererLogLevels.OUTPUT]: figures.pointerSmall,
		[ListrDefaultRendererLogLevels.OUTPUT_WITH_BOTTOMBAR]: figures.pointerSmall,
		[ListrDefaultRendererLogLevels.PENDING]: figures.pointer,
		[ListrDefaultRendererLogLevels.COMPLETED]: figures.tick,
		[ListrDefaultRendererLogLevels.COMPLETED_WITH_FAILED_SUBTASKS]: figures.warning,
		[ListrDefaultRendererLogLevels.COMPLETED_WITH_FAILED_SISTER_TASKS]: figures.squareSmallFilled,
		[ListrDefaultRendererLogLevels.RETRY]: figures.warning,
		[ListrDefaultRendererLogLevels.ROLLING_BACK]: figures.warning,
		[ListrDefaultRendererLogLevels.ROLLED_BACK]: figures.arrowLeft,
		[ListrDefaultRendererLogLevels.FAILED]: figures.cross,
		[ListrDefaultRendererLogLevels.FAILED_WITH_FAILED_SUBTASKS]: figures.pointer,
		[ListrDefaultRendererLogLevels.WAITING]: figures.squareSmallFilled,
		[ListrDefaultRendererLogLevels.PAUSED]: figures.squareSmallFilled
	},
	color: {
		[ListrDefaultRendererLogLevels.SKIPPED_WITH_COLLAPSE]: color.yellow,
		[ListrDefaultRendererLogLevels.SKIPPED_WITHOUT_COLLAPSE]: color.yellow,
		[ListrDefaultRendererLogLevels.PENDING]: color.yellow,
		[ListrDefaultRendererLogLevels.COMPLETED]: color.green,
		[ListrDefaultRendererLogLevels.COMPLETED_WITH_FAILED_SUBTASKS]: color.yellow,
		[ListrDefaultRendererLogLevels.COMPLETED_WITH_FAILED_SISTER_TASKS]: color.red,
		[ListrDefaultRendererLogLevels.RETRY]: color.yellowBright,
		[ListrDefaultRendererLogLevels.ROLLING_BACK]: color.redBright,
		[ListrDefaultRendererLogLevels.ROLLED_BACK]: color.redBright,
		[ListrDefaultRendererLogLevels.FAILED]: color.red,
		[ListrDefaultRendererLogLevels.FAILED_WITH_FAILED_SUBTASKS]: color.red,
		[ListrDefaultRendererLogLevels.WAITING]: color.dim,
		[ListrDefaultRendererLogLevels.PAUSED]: color.yellowBright
	}
};
/**
* A basic function to parse minutes and tasks passed given a duration.
* Useful for renderers to show the task time.
*/
/* istanbul ignore next */
function parseTimer(duration) {
	const seconds = Math.floor(duration / 1e3);
	const minutes = Math.floor(seconds / 60);
	let parsedTime;
	if (seconds === 0 && minutes === 0) parsedTime = `0.${Math.floor(duration / 100)}s`;
	if (seconds > 0) parsedTime = `${seconds % 60}s`;
	if (minutes > 0) parsedTime = `${minutes}m${parsedTime}`;
	return parsedTime;
}
/* istanbul ignore next */
const PRESET_TIMER = {
	condition: true,
	field: parseTimer,
	format: () => color.dim
};
var DefaultRenderer = class DefaultRenderer$1 {
	static nonTTY = false;
	static rendererOptions = {
		indentation: 2,
		clearOutput: false,
		showSubtasks: true,
		collapseSubtasks: true,
		collapseSkips: true,
		showSkipMessage: true,
		suffixSkips: false,
		collapseErrors: true,
		showErrorMessage: true,
		suffixRetries: true,
		lazy: false,
		removeEmptyLines: true,
		formatOutput: "wrap",
		pausedTimer: {
			...PRESET_TIMER,
			format: () => color.yellowBright
		}
	};
	static rendererTaskOptions = { outputBar: true };
	prompt;
	activePrompt;
	spinner;
	logger;
	updater;
	truncate;
	wrap;
	buffer = {
		output: /* @__PURE__ */ new Map(),
		bottom: /* @__PURE__ */ new Map()
	};
	cache = {
		render: /* @__PURE__ */ new Map(),
		rendererOptions: /* @__PURE__ */ new Map(),
		rendererTaskOptions: /* @__PURE__ */ new Map()
	};
	constructor(tasks, options, events) {
		this.tasks = tasks;
		this.options = options;
		this.events = events;
		this.options = {
			...DefaultRenderer$1.rendererOptions,
			...this.options,
			icon: {
				...LISTR_DEFAULT_RENDERER_STYLE.icon,
				...options?.icon ?? {}
			},
			color: {
				...LISTR_DEFAULT_RENDERER_STYLE.color,
				...options?.color ?? {}
			}
		};
		this.spinner = this.options.spinner ?? new Spinner();
		this.logger = this.options.logger ?? new ListrLogger({
			useIcons: true,
			toStderr: []
		});
		this.logger.options.icon = this.options.icon;
		this.logger.options.color = this.options.color;
	}
	async render() {
		const { createLogUpdate } = await Promise.resolve().then(() => require("./log-update-4uRZgyzJ.cjs"));
		const { default: truncate } = await Promise.resolve().then(() => require("./cli-truncate-BZsUcSxP.cjs"));
		const { default: wrap } = await Promise.resolve().then(() => require("./wrap-ansi-CguIj--u.cjs"));
		this.updater = createLogUpdate(this.logger.process.stdout);
		this.truncate = truncate;
		this.wrap = wrap;
		this.logger.process.hijack();
		/* istanbul ignore if */
		if (!this.options?.lazy) this.spinner.start(() => {
			this.update();
		});
		this.events.on(ListrEventType.SHOULD_REFRESH_RENDER, () => {
			this.update();
		});
	}
	update() {
		this.updater(this.create());
	}
	end() {
		this.spinner.stop();
		this.updater.clear();
		this.updater.done();
		if (!this.options.clearOutput) this.logger.process.toStdout(this.create({ prompt: false }));
		this.logger.process.release();
	}
	create(options) {
		options = {
			tasks: true,
			bottomBar: true,
			prompt: true,
			...options
		};
		const render = [];
		const renderTasks = this.renderer(this.tasks);
		const renderBottomBar = this.renderBottomBar();
		const renderPrompt = this.renderPrompt();
		if (options.tasks && renderTasks.length > 0) render.push(...renderTasks);
		if (options.bottomBar && renderBottomBar.length > 0) {
			if (render.length > 0) render.push("");
			render.push(...renderBottomBar);
		}
		if (options.prompt && renderPrompt.length > 0) {
			if (render.length > 0) render.push("");
			render.push(...renderPrompt);
		}
		return render.join(os.EOL);
	}
	style(task, output = false) {
		const rendererOptions = this.cache.rendererOptions.get(task.id);
		if (task.isSkipped()) {
			if (output || rendererOptions.collapseSkips) return this.logger.icon(ListrDefaultRendererLogLevels.SKIPPED_WITH_COLLAPSE);
			else if (rendererOptions.collapseSkips === false) return this.logger.icon(ListrDefaultRendererLogLevels.SKIPPED_WITHOUT_COLLAPSE);
		}
		if (output) {
			if (this.shouldOutputToBottomBar(task)) return this.logger.icon(ListrDefaultRendererLogLevels.OUTPUT_WITH_BOTTOMBAR);
			return this.logger.icon(ListrDefaultRendererLogLevels.OUTPUT);
		}
		if (task.hasSubtasks()) {
			if (task.isStarted() || task.isPrompt() && rendererOptions.showSubtasks !== false && !task.subtasks.every((subtask) => !subtask.hasTitle())) return this.logger.icon(ListrDefaultRendererLogLevels.PENDING);
			else if (task.isCompleted() && task.subtasks.some((subtask) => subtask.hasFailed())) return this.logger.icon(ListrDefaultRendererLogLevels.COMPLETED_WITH_FAILED_SUBTASKS);
			else if (task.hasFailed()) return this.logger.icon(ListrDefaultRendererLogLevels.FAILED_WITH_FAILED_SUBTASKS);
		}
		if (task.isStarted() || task.isPrompt()) return this.logger.icon(ListrDefaultRendererLogLevels.PENDING, !this.options?.lazy && this.spinner.fetch());
		else if (task.isCompleted()) return this.logger.icon(ListrDefaultRendererLogLevels.COMPLETED);
		else if (task.isRetrying()) return this.logger.icon(ListrDefaultRendererLogLevels.RETRY, !this.options?.lazy && this.spinner.fetch());
		else if (task.isRollingBack()) return this.logger.icon(ListrDefaultRendererLogLevels.ROLLING_BACK, !this.options?.lazy && this.spinner.fetch());
		else if (task.hasRolledBack()) return this.logger.icon(ListrDefaultRendererLogLevels.ROLLED_BACK);
		else if (task.hasFailed()) return this.logger.icon(ListrDefaultRendererLogLevels.FAILED);
		else if (task.isPaused()) return this.logger.icon(ListrDefaultRendererLogLevels.PAUSED);
		return this.logger.icon(ListrDefaultRendererLogLevels.WAITING);
	}
	format(message, icon, level) {
		if (message.trim() === "") return [];
		if (icon) message = icon + " " + message;
		let parsed;
		const columns = (process.stdout.columns ?? 80) - level * this.options.indentation - 2;
		switch (this.options.formatOutput) {
			case "truncate":
				parsed = message.split(os.EOL).map((s, i) => {
					return this.truncate(this.indent(s, i), columns);
				});
				break;
			case "wrap":
				parsed = this.wrap(message, columns, {
					hard: true,
					trim: false
				}).split(os.EOL).map((s, i) => this.indent(s, i));
				break;
			default: throw new ListrRendererError("Format option for the renderer is wrong.");
		}
		if (this.options.removeEmptyLines) parsed = parsed.filter(Boolean);
		return parsed.map((str) => indent(str, level * this.options.indentation));
	}
	shouldOutputToOutputBar(task) {
		const outputBar = this.cache.rendererTaskOptions.get(task.id).outputBar;
		return typeof outputBar === "number" && outputBar !== 0 || typeof outputBar === "boolean" && outputBar !== false;
	}
	shouldOutputToBottomBar(task) {
		const bottomBar = this.cache.rendererTaskOptions.get(task.id).bottomBar;
		return typeof bottomBar === "number" && bottomBar !== 0 || typeof bottomBar === "boolean" && bottomBar !== false || !task.hasTitle();
	}
	renderer(tasks, level = 0) {
		return tasks.flatMap((task) => {
			if (!task.isEnabled()) return [];
			if (this.cache.render.has(task.id)) return this.cache.render.get(task.id);
			this.calculate(task);
			this.setupBuffer(task);
			const rendererOptions = this.cache.rendererOptions.get(task.id);
			const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
			const output = [];
			if (task.isPrompt()) {
				if (this.activePrompt && this.activePrompt !== task.id) throw new ListrRendererError("Only one prompt can be active at the given time, please re-evaluate your task design.");
				else if (!this.activePrompt) {
					task.on(ListrTaskEventType.PROMPT, (prompt) => {
						const cleansed = cleanseAnsi(prompt);
						if (cleansed) this.prompt = cleansed;
					});
					task.on(ListrTaskEventType.STATE, (state) => {
						if (state === ListrTaskState.PROMPT_COMPLETED || task.hasFinalized() || task.hasReset()) {
							this.prompt = null;
							this.activePrompt = null;
							task.off(ListrTaskEventType.PROMPT);
						}
					});
					this.activePrompt = task.id;
				}
			}
			if (task.hasTitle()) if (!(tasks.some((task$1) => task$1.hasFailed()) && !task.hasFailed() && task.options.exitOnError !== false && !(task.isCompleted() || task.isSkipped()))) if (task.hasFailed() && rendererOptions.collapseErrors) output.push(...this.format(!task.hasSubtasks() && task.message.error && rendererOptions.showErrorMessage ? task.message.error : task.title, this.style(task), level));
			else if (task.isSkipped() && rendererOptions.collapseSkips) output.push(...this.format(this.logger.suffix(task.message.skip && rendererOptions.showSkipMessage ? task.message.skip : task.title, {
				field: ListrLogLevels.SKIPPED,
				condition: rendererOptions.suffixSkips,
				format: () => color.dim
			}), this.style(task), level));
			else if (task.isRetrying()) output.push(...this.format(this.logger.suffix(task.title, {
				field: `${ListrLogLevels.RETRY}:${task.message.retry.count}`,
				format: () => color.yellow,
				condition: rendererOptions.suffixRetries
			}), this.style(task), level));
			else if (task.isCompleted() && task.hasTitle() && assertFunctionOrSelf(rendererTaskOptions.timer?.condition, task.message.duration)) output.push(...this.format(this.logger.suffix(task?.title, {
				...rendererTaskOptions.timer,
				args: [task.message.duration]
			}), this.style(task), level));
			else if (task.isPaused()) output.push(...this.format(this.logger.suffix(task.title, {
				...rendererOptions.pausedTimer,
				args: [task.message.paused - Date.now()]
			}), this.style(task), level));
			else output.push(...this.format(task.title, this.style(task), level));
			else output.push(...this.format(task.title, this.logger.icon(ListrDefaultRendererLogLevels.COMPLETED_WITH_FAILED_SISTER_TASKS), level));
			if (!task.hasSubtasks() || !rendererOptions.showSubtasks) {
				if (task.hasFailed() && rendererOptions.collapseErrors === false && (rendererOptions.showErrorMessage || !rendererOptions.showSubtasks)) output.push(...this.dump(task, level, ListrLogLevels.FAILED));
				else if (task.isSkipped() && rendererOptions.collapseSkips === false && (rendererOptions.showSkipMessage || !rendererOptions.showSubtasks)) output.push(...this.dump(task, level, ListrLogLevels.SKIPPED));
			}
			if (task.isPending() || rendererTaskOptions.persistentOutput) output.push(...this.renderOutputBar(task, level));
			if (rendererOptions.showSubtasks !== false && task.hasSubtasks() && (task.isPending() || task.hasFinalized() && !task.hasTitle() || task.isCompleted() && rendererOptions.collapseSubtasks === false && !task.subtasks.some((subtask) => this.cache.rendererOptions.get(subtask.id)?.collapseSubtasks === true) || task.subtasks.some((subtask) => this.cache.rendererOptions.get(subtask.id)?.collapseSubtasks === false) || task.subtasks.some((subtask) => subtask.hasFailed()) || task.subtasks.some((subtask) => subtask.hasRolledBack()))) {
				const subtaskLevel = !task.hasTitle() ? level : level + 1;
				const subtaskRender = this.renderer(task.subtasks, subtaskLevel);
				output.push(...subtaskRender);
			}
			if (task.hasFinalized()) {
				if (!rendererTaskOptions.persistentOutput) {
					this.buffer.bottom.delete(task.id);
					this.buffer.output.delete(task.id);
				}
			}
			if (task.isClosed()) {
				this.cache.render.set(task.id, output);
				this.reset(task);
			}
			return output;
		});
	}
	renderOutputBar(task, level) {
		const output = this.buffer.output.get(task.id);
		if (!output) return [];
		return output.all.flatMap((o) => this.dump(task, level, ListrLogLevels.OUTPUT, o.entry));
	}
	renderBottomBar() {
		if (this.buffer.bottom.size === 0) return [];
		return Array.from(this.buffer.bottom.values()).flatMap((output) => output.all).sort((a, b) => a.time - b.time).map((output) => output.entry);
	}
	renderPrompt() {
		if (!this.prompt) return [];
		return [this.prompt];
	}
	calculate(task) {
		if (this.cache.rendererOptions.has(task.id) && this.cache.rendererTaskOptions.has(task.id)) return;
		const rendererOptions = {
			...this.options,
			...task.rendererOptions
		};
		this.cache.rendererOptions.set(task.id, rendererOptions);
		this.cache.rendererTaskOptions.set(task.id, {
			...DefaultRenderer$1.rendererTaskOptions,
			timer: rendererOptions.timer,
			...task.rendererTaskOptions
		});
	}
	setupBuffer(task) {
		if (this.buffer.bottom.has(task.id) || this.buffer.output.has(task.id)) return;
		const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
		if (this.shouldOutputToBottomBar(task) && !this.buffer.bottom.has(task.id)) {
			this.buffer.bottom.set(task.id, new ProcessOutputBuffer({ limit: typeof rendererTaskOptions.bottomBar === "number" ? rendererTaskOptions.bottomBar : 1 }));
			task.on(ListrTaskEventType.OUTPUT, (output) => {
				const data = this.dump(task, -1, ListrLogLevels.OUTPUT, output);
				this.buffer.bottom.get(task.id).write(data.join(os.EOL));
			});
			task.on(ListrTaskEventType.STATE, (state) => {
				switch (state) {
					case ListrTaskState.RETRY || ListrTaskState.ROLLING_BACK:
						this.buffer.bottom.delete(task.id);
						break;
				}
			});
		} else if (this.shouldOutputToOutputBar(task) && !this.buffer.output.has(task.id)) {
			this.buffer.output.set(task.id, new ProcessOutputBuffer({ limit: typeof rendererTaskOptions.outputBar === "number" ? rendererTaskOptions.outputBar : 1 }));
			task.on(ListrTaskEventType.OUTPUT, (output) => {
				this.buffer.output.get(task.id).write(output);
			});
			task.on(ListrTaskEventType.STATE, (state) => {
				switch (state) {
					case ListrTaskState.RETRY || ListrTaskState.ROLLING_BACK:
						this.buffer.output.delete(task.id);
						break;
				}
			});
		}
	}
	reset(task) {
		this.cache.rendererOptions.delete(task.id);
		this.cache.rendererTaskOptions.delete(task.id);
		this.buffer.output.delete(task.id);
	}
	dump(task, level, source = ListrLogLevels.OUTPUT, data) {
		if (!data) switch (source) {
			case ListrLogLevels.OUTPUT:
				data = task.output;
				break;
			case ListrLogLevels.SKIPPED:
				data = task.message.skip;
				break;
			case ListrLogLevels.FAILED:
				data = task.message.error;
				break;
		}
		if (task.hasTitle() && source === ListrLogLevels.FAILED && data === task.title || typeof data !== "string") return [];
		if (source === ListrLogLevels.OUTPUT) data = cleanseAnsi(data);
		return this.format(data, this.style(task, true), level + 1);
	}
	indent(str, i) {
		return i > 0 ? indent(str.trimEnd(), this.options.indentation) : str.trimEnd();
	}
};
var SilentRenderer = class {
	static nonTTY = true;
	static rendererOptions;
	static rendererTaskOptions;
	constructor(tasks, options) {
		this.tasks = tasks;
		this.options = options;
	}
	render() {
		return;
	}
	end() {
		return;
	}
};
var SimpleRenderer = class SimpleRenderer$1 {
	static nonTTY = true;
	static rendererOptions = { pausedTimer: {
		...PRESET_TIMER,
		field: (time) => `${ListrLogLevels.PAUSED}:${time}`,
		format: () => color.yellowBright
	} };
	static rendererTaskOptions = {};
	logger;
	cache = {
		rendererOptions: /* @__PURE__ */ new Map(),
		rendererTaskOptions: /* @__PURE__ */ new Map()
	};
	constructor(tasks, options) {
		this.tasks = tasks;
		this.options = options;
		this.options = {
			...SimpleRenderer$1.rendererOptions,
			...options,
			icon: {
				...LISTR_LOGGER_STYLE.icon,
				...options?.icon ?? {}
			},
			color: {
				...LISTR_LOGGER_STYLE.color,
				...options?.color ?? {}
			}
		};
		this.logger = this.options.logger ?? new ListrLogger({
			useIcons: true,
			toStderr: LISTR_LOGGER_STDERR_LEVELS
		});
		this.logger.options.icon = this.options.icon;
		this.logger.options.color = this.options.color;
		if (this.options.timestamp) this.logger.options.fields.prefix.unshift(this.options.timestamp);
	}
	end() {}
	render() {
		this.renderer(this.tasks);
	}
	renderer(tasks) {
		tasks.forEach((task) => {
			this.calculate(task);
			task.once(ListrTaskEventType.CLOSED, () => {
				this.reset(task);
			});
			const rendererOptions = this.cache.rendererOptions.get(task.id);
			const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
			task.on(ListrTaskEventType.SUBTASK, (subtasks) => {
				this.renderer(subtasks);
			});
			task.on(ListrTaskEventType.STATE, (state) => {
				if (!task.hasTitle()) return;
				if (state === ListrTaskState.STARTED) this.logger.log(ListrLogLevels.STARTED, task.title);
				else if (state === ListrTaskState.COMPLETED) {
					const timer = rendererTaskOptions?.timer;
					this.logger.log(ListrLogLevels.COMPLETED, task.title, timer && { suffix: {
						...timer,
						condition: !!task.message?.duration && timer.condition,
						args: [task.message.duration]
					} });
				} else if (state === ListrTaskState.PROMPT) {
					this.logger.process.hijack();
					task.on(ListrTaskEventType.PROMPT, (prompt) => {
						this.logger.process.toStderr(prompt, false);
					});
				} else if (state === ListrTaskState.PROMPT_COMPLETED) {
					task.off(ListrTaskEventType.PROMPT);
					this.logger.process.release();
				}
			});
			task.on(ListrTaskEventType.OUTPUT, (output) => {
				this.logger.log(ListrLogLevels.OUTPUT, output);
			});
			task.on(ListrTaskEventType.MESSAGE, (message) => {
				if (message.error) this.logger.log(ListrLogLevels.FAILED, task.title, { suffix: {
					field: `${ListrLogLevels.FAILED}: ${message.error}`,
					format: () => color.red
				} });
				else if (message.skip) this.logger.log(ListrLogLevels.SKIPPED, task.title, { suffix: {
					field: `${ListrLogLevels.SKIPPED}: ${message.skip}`,
					format: () => color.yellow
				} });
				else if (message.rollback) this.logger.log(ListrLogLevels.ROLLBACK, task.title, { suffix: {
					field: `${ListrLogLevels.ROLLBACK}: ${message.rollback}`,
					format: () => color.red
				} });
				else if (message.retry) this.logger.log(ListrLogLevels.RETRY, task.title, { suffix: {
					field: `${ListrLogLevels.RETRY}:${message.retry.count}`,
					format: () => color.red
				} });
				else if (message.paused) {
					const timer = rendererOptions?.pausedTimer;
					this.logger.log(ListrLogLevels.PAUSED, task.title, timer && { suffix: {
						...timer,
						condition: !!message?.paused && timer.condition,
						args: [message.paused - Date.now()]
					} });
				}
			});
		});
	}
	calculate(task) {
		if (this.cache.rendererOptions.has(task.id) && this.cache.rendererTaskOptions.has(task.id)) return;
		const rendererOptions = {
			...this.options,
			...task.rendererOptions
		};
		this.cache.rendererOptions.set(task.id, rendererOptions);
		this.cache.rendererTaskOptions.set(task.id, {
			...SimpleRenderer$1.rendererTaskOptions,
			timer: rendererOptions.timer,
			...task.rendererTaskOptions
		});
	}
	reset(task) {
		this.cache.rendererOptions.delete(task.id);
		this.cache.rendererTaskOptions.delete(task.id);
	}
};
var TestRendererSerializer = class {
	constructor(options) {
		this.options = options;
	}
	serialize(event, data, task) {
		return JSON.stringify(this.generate(event, data, task));
	}
	generate(event, data, task) {
		const output = {
			event,
			data
		};
		if (typeof this.options?.task !== "boolean") {
			const t = Object.fromEntries(this.options.task.map((entity) => {
				const property = task[entity];
				if (typeof property === "function") return [entity, property.call(task)];
				return [entity, property];
			}));
			if (Object.keys(task).length > 0) output.task = t;
		}
		return output;
	}
};
var TestRenderer = class TestRenderer$1 {
	static nonTTY = true;
	static rendererOptions = {
		subtasks: true,
		state: Object.values(ListrTaskState),
		output: true,
		prompt: true,
		title: true,
		messages: [
			"skip",
			"error",
			"retry",
			"rollback",
			"paused"
		],
		messagesToStderr: [
			"error",
			"rollback",
			"retry"
		],
		task: [
			"hasRolledBack",
			"isRollingBack",
			"isCompleted",
			"isSkipped",
			"hasFinalized",
			"hasSubtasks",
			"title",
			"hasReset",
			"hasTitle",
			"isPrompt",
			"isPaused",
			"isPending",
			"isSkipped",
			"isStarted",
			"hasFailed",
			"isEnabled",
			"isRetrying",
			"path"
		]
	};
	static rendererTaskOptions;
	logger;
	serializer;
	constructor(tasks, options) {
		this.tasks = tasks;
		this.options = options;
		this.options = {
			...TestRenderer$1.rendererOptions,
			...this.options
		};
		this.logger = this.options.logger ?? new ListrLogger({ useIcons: false });
		this.serializer = new TestRendererSerializer(this.options);
	}
	render() {
		this.renderer(this.tasks);
	}
	end() {}
	renderer(tasks) {
		tasks.forEach((task) => {
			if (this.options.subtasks) task.on(ListrTaskEventType.SUBTASK, (subtasks) => {
				this.renderer(subtasks);
			});
			if (this.options.state) task.on(ListrTaskEventType.STATE, (state) => {
				this.logger.toStdout(this.serializer.serialize(ListrTaskEventType.STATE, state, task));
			});
			if (this.options.output) task.on(ListrTaskEventType.OUTPUT, (data) => {
				this.logger.toStdout(this.serializer.serialize(ListrTaskEventType.OUTPUT, data, task));
			});
			if (this.options.prompt) task.on(ListrTaskEventType.PROMPT, (prompt) => {
				this.logger.toStdout(this.serializer.serialize(ListrTaskEventType.PROMPT, prompt, task));
			});
			if (this.options.title) task.on(ListrTaskEventType.TITLE, (title) => {
				this.logger.toStdout(this.serializer.serialize(ListrTaskEventType.TITLE, title, task));
			});
			task.on(ListrTaskEventType.MESSAGE, (message) => {
				const parsed = Object.fromEntries(Object.entries(message).map(([key, value]) => {
					if (this.options.messages.includes(key)) return [key, value];
				}).filter(Boolean));
				if (Object.keys(parsed).length > 0) {
					const output = this.serializer.serialize(ListrTaskEventType.MESSAGE, parsed, task);
					if (this.options.messagesToStderr.some((state) => Object.keys(parsed).includes(state))) this.logger.toStderr(output);
					else this.logger.toStdout(output);
				}
			});
		});
	}
};
var VerboseRenderer = class VerboseRenderer$1 {
	static nonTTY = true;
	static rendererOptions = {
		logTitleChange: false,
		pausedTimer: {
			...PRESET_TIMER,
			format: () => color.yellowBright
		}
	};
	static rendererTaskOptions;
	logger;
	cache = {
		rendererOptions: /* @__PURE__ */ new Map(),
		rendererTaskOptions: /* @__PURE__ */ new Map()
	};
	constructor(tasks, options) {
		this.tasks = tasks;
		this.options = options;
		this.options = {
			...VerboseRenderer$1.rendererOptions,
			...this.options,
			icon: {
				...LISTR_LOGGER_STYLE.icon,
				...options?.icon ?? {}
			},
			color: {
				...LISTR_LOGGER_STYLE.color,
				...options?.color ?? {}
			}
		};
		this.logger = this.options.logger ?? new ListrLogger({
			useIcons: false,
			toStderr: LISTR_LOGGER_STDERR_LEVELS
		});
		this.logger.options.icon = this.options.icon;
		this.logger.options.color = this.options.color;
		if (this.options.timestamp) this.logger.options.fields.prefix.unshift(this.options.timestamp);
	}
	render() {
		this.renderer(this.tasks);
	}
	end() {}
	renderer(tasks) {
		tasks.forEach((task) => {
			this.calculate(task);
			task.once(ListrTaskEventType.CLOSED, () => {
				this.reset(task);
			});
			const rendererOptions = this.cache.rendererOptions.get(task.id);
			const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
			task.on(ListrTaskEventType.SUBTASK, (subtasks) => {
				this.renderer(subtasks);
			});
			task.on(ListrTaskEventType.STATE, (state) => {
				if (!task.hasTitle()) return;
				if (state === ListrTaskState.STARTED) this.logger.log(ListrLogLevels.STARTED, task.title);
				else if (state === ListrTaskState.COMPLETED) {
					const timer = rendererTaskOptions.timer;
					this.logger.log(ListrLogLevels.COMPLETED, task.title, timer && { suffix: {
						...timer,
						condition: !!task.message?.duration && timer.condition,
						args: [task.message.duration]
					} });
				}
			});
			task.on(ListrTaskEventType.OUTPUT, (data) => {
				this.logger.log(ListrLogLevels.OUTPUT, data);
			});
			task.on(ListrTaskEventType.PROMPT, (prompt) => {
				const cleansed = cleanseAnsi(prompt);
				if (cleansed) this.logger.log(ListrLogLevels.PROMPT, cleansed);
			});
			if (this.options?.logTitleChange !== false) task.on(ListrTaskEventType.TITLE, (title) => {
				this.logger.log(ListrLogLevels.TITLE, title);
			});
			task.on(ListrTaskEventType.MESSAGE, (message) => {
				if (message?.error) this.logger.log(ListrLogLevels.FAILED, message.error);
				else if (message?.skip) this.logger.log(ListrLogLevels.SKIPPED, message.skip);
				else if (message?.rollback) this.logger.log(ListrLogLevels.ROLLBACK, message.rollback);
				else if (message?.retry) this.logger.log(ListrLogLevels.RETRY, task.title, { suffix: message.retry.count.toString() });
				else if (message?.paused) {
					const timer = rendererOptions?.pausedTimer;
					this.logger.log(ListrLogLevels.PAUSED, task.title, timer && { suffix: {
						...timer,
						condition: !!message?.paused && timer.condition,
						args: [message.paused - Date.now()]
					} });
				}
			});
		});
	}
	calculate(task) {
		if (this.cache.rendererOptions.has(task.id) && this.cache.rendererTaskOptions.has(task.id)) return;
		const rendererOptions = {
			...this.options,
			...task.rendererOptions
		};
		this.cache.rendererOptions.set(task.id, rendererOptions);
		this.cache.rendererTaskOptions.set(task.id, {
			...VerboseRenderer$1.rendererTaskOptions,
			timer: rendererOptions.timer,
			...task.rendererTaskOptions
		});
	}
	reset(task) {
		this.cache.rendererOptions.delete(task.id);
		this.cache.rendererTaskOptions.delete(task.id);
	}
};
const RENDERERS = {
	default: DefaultRenderer,
	simple: SimpleRenderer,
	verbose: VerboseRenderer,
	test: TestRenderer,
	silent: SilentRenderer
};
function isRendererSupported(renderer) {
	return process.stdout.isTTY === true || renderer.nonTTY === true;
}
function getRendererClass(renderer) {
	if (typeof renderer === "string") return RENDERERS[renderer] ?? RENDERERS.default;
	return typeof renderer === "function" ? renderer : RENDERERS.default;
}
function getRenderer(options) {
	if (assertFunctionOrSelf(options?.silentRendererCondition)) return {
		renderer: getRendererClass("silent"),
		selection: ListrRendererSelection.SILENT
	};
	const r = {
		renderer: getRendererClass(options.renderer),
		options: options.rendererOptions,
		selection: ListrRendererSelection.PRIMARY
	};
	if (!isRendererSupported(r.renderer) || assertFunctionOrSelf(options?.fallbackRendererCondition)) return {
		renderer: getRendererClass(options.fallbackRenderer),
		options: options.fallbackRendererOptions,
		selection: ListrRendererSelection.SECONDARY
	};
	return r;
}
/**
* This function asserts the given value as a function or itself.
* If the value itself is a function it will evaluate it with the passed in arguments,
* elsewise it will directly return itself.
*/
function assertFunctionOrSelf(functionOrSelf, ...args) {
	if (typeof functionOrSelf === "function") return functionOrSelf(...args);
	else return functionOrSelf;
}
const clone = (0, import_rfdc.default)({ circles: true });
/**
* Deep clones a object in the easiest manner.
*/
function cloneObject(obj) {
	return clone(obj);
}
var Concurrency = class {
	concurrency;
	count;
	queue;
	constructor(options) {
		this.concurrency = options.concurrency;
		this.count = 0;
		this.queue = /* @__PURE__ */ new Set();
	}
	add(fn) {
		if (this.count < this.concurrency) return this.run(fn);
		return new Promise((resolve) => {
			const callback = () => resolve(this.run(fn));
			this.queue.add(callback);
		});
	}
	flush() {
		for (const callback of this.queue) {
			if (this.count >= this.concurrency) break;
			this.queue.delete(callback);
			callback();
		}
	}
	run(fn) {
		this.count++;
		const promise = fn();
		const cleanup = () => {
			this.count--;
			this.flush();
		};
		promise.then(cleanup, () => {
			this.queue.clear();
		});
		return promise;
	}
};
function delay(time) {
	return new Promise((resolve) => {
		setTimeout(resolve, time);
	});
}
/**
* Internal error handling mechanism for Listr collects the errors and details for a failed task.
*
* @see {@link https://listr2.kilic.dev/task/error-handling.html}
*/
var ListrError = class extends Error {
	path;
	ctx;
	constructor(error, type, task) {
		super(error.message);
		this.error = error;
		this.type = type;
		this.task = task;
		this.name = "ListrError";
		this.path = task.path;
		if (task?.options.collectErrors === "full") {
			this.task = cloneObject(task);
			this.ctx = cloneObject(task.listr.ctx);
		}
		this.stack = error?.stack;
	}
};
/**
* Internal error coming from renderer.
*/
var ListrRendererError = class extends Error {};
/**
* Internal error handling mechanism for Listr prompts to identify the failing cause is coming from a prompt.
*
* @see {@link https://listr2.kilic.dev/task/prompts.html}
*/
var PromptError = class extends Error {};
/**
* The original Task that is defined by the user is wrapped with the TaskWrapper to provide additional functionality.
*
* @see {@link https://listr2.kilic.dev/task/task.html}
*/
var TaskWrapper = class {
	constructor(task) {
		this.task = task;
	}
	/* istanbul ignore next */
	get title() {
		return this.task.title;
	}
	/**
	* Title of the current task.
	*
	* @see {@link https://listr2.kilic.dev/task/title.html}
	*/
	set title(title) {
		title = Array.isArray(title) ? title : [title];
		this.task.title$ = splat(title.shift(), ...title);
	}
	/* istanbul ignore next */
	get output() {
		return this.task.output;
	}
	/* istanbul ignore next */
	/**
	* Send output from the current task to the renderer.
	*
	* @see {@link https://listr2.kilic.dev/task/output.html}
	*/
	set output(output) {
		output = Array.isArray(output) ? output : [output];
		this.task.output$ = splat(output.shift(), ...output);
	}
	/* istanbul ignore next */
	/** Send an output to the output channel as prompt. */
	set promptOutput(output) {
		this.task.promptOutput$ = output;
	}
	/**
	* Creates a new set of Listr subtasks.
	*
	* @see {@link https://listr2.kilic.dev/task/subtasks.html}
	*/
	newListr(task, options) {
		let tasks;
		if (typeof task === "function") tasks = task(this);
		else tasks = task;
		return new Listr(tasks, options, this.task);
	}
	/**
	* Report an error that has to be collected and handled.
	*
	* @see {@link https://listr2.kilic.dev/task/error-handling.html}
	*/
	report(error, type) {
		if (this.task.options.collectErrors !== false) this.task.listr.errors.push(new ListrError(error, type, this.task));
		this.task.message$ = { error: error.message ?? this.task?.title };
	}
	/**
	* Skip the current task.
	*
	* @see {@link https://listr2.kilic.dev/task/skip.html}
	*/
	skip(message, ...metadata) {
		this.task.state$ = ListrTaskState.SKIPPED;
		if (message) this.task.message$ = { skip: message ? splat(message, ...metadata) : this.task?.title };
	}
	/**
	* Check whether this task is currently in a retry state.
	*
	* @see {@link https://listr2.kilic.dev/task/retry.html}
	*/
	isRetrying() {
		return this.task.isRetrying() ? this.task.retry : { count: 0 };
	}
	/* istanbul ignore next */
	/**
	* Create a new prompt for getting user input through the prompt adapter.
	* This will create a new prompt through the adapter if the task is not currently rendering a prompt or will return the active instance.
	*
	* This part of the application requires optional peer dependencies, please refer to documentation.
	*
	* @see {@link https://listr2.kilic.dev/task/prompt.html}
	*/
	prompt(adapter) {
		if (this.task.prompt) return this.task.prompt;
		return new adapter(this.task, this);
	}
	/* istanbul ignore next */
	/**
	* Generates a fake stdout for your use case, where it will be tunnelled through Listr to handle the rendering process.
	*
	* @see {@link https://listr2.kilic.dev/renderer/process-output.html}
	*/
	stdout(type) {
		return createWritable((chunk) => {
			switch (type) {
				case ListrTaskEventType.PROMPT:
					this.promptOutput = chunk;
					break;
				default: this.output = chunk;
			}
		});
	}
	/** Run this task. */
	run(ctx) {
		return this.task.run(ctx, this);
	}
};
var ListrTaskEventManager = class extends EventManager {};
/**
* Creates and handles a runnable instance of the Task.
*/
var Task = class extends ListrTaskEventManager {
	/** Unique id per task, can be used for identifying a Task. */
	id = (0, crypto.randomUUID)();
	/** The current state of the task. */
	state = ListrTaskState.WAITING;
	/** Subtasks of the current task. */
	subtasks;
	/** Title of the task. */
	title;
	/** Initial/Untouched version of the title for using whenever task has a reset. */
	initialTitle;
	/** Output channel for the task. */
	output;
	/** Current state of the retry process whenever the task is retrying. */
	retry;
	/**
	* A channel for messages.
	*
	* This requires a separate channel for messages like error, skip or runtime messages to further utilize in the renderers.
	*/
	message = {};
	/** Current prompt instance or prompt error whenever the task is prompting. */
	prompt;
	/** Parent task of the current task. */
	parent;
	/** Enable flag of this task. */
	enabled;
	/** User provided Task callback function to run. */
	taskFn;
	/** Marks the task as closed. This is different from finalized since this is not really related to task itself. */
	closed;
	constructor(listr, task, options, rendererOptions, rendererTaskOptions) {
		super();
		this.listr = listr;
		this.task = task;
		this.options = options;
		this.rendererOptions = rendererOptions;
		this.rendererTaskOptions = rendererTaskOptions;
		if (task.title) {
			const title = Array.isArray(task?.title) ? task.title : [task.title];
			this.title = splat(title.shift(), ...title);
			this.initialTitle = this.title;
		}
		this.taskFn = task.task;
		this.parent = listr.parentTask;
	}
	/**
	* Update the current state of the Task and emit the neccassary events.
	*/
	set state$(state) {
		this.state = state;
		this.emit(ListrTaskEventType.STATE, state);
		if (this.hasSubtasks() && this.hasFailed()) {
			for (const subtask of this.subtasks) if (subtask.state === ListrTaskState.STARTED) subtask.state$ = ListrTaskState.FAILED;
		}
		this.listr.events.emit(ListrEventType.SHOULD_REFRESH_RENDER);
	}
	/**
	* Update the current output of the Task and emit the neccassary events.
	*/
	set output$(data) {
		this.output = data;
		this.emit(ListrTaskEventType.OUTPUT, data);
		this.listr.events.emit(ListrEventType.SHOULD_REFRESH_RENDER);
	}
	/**
	* Update the current prompt output of the Task and emit the neccassary events.
	*/
	set promptOutput$(data) {
		this.emit(ListrTaskEventType.PROMPT, data);
		if (cleanseAnsi(data)) this.listr.events.emit(ListrEventType.SHOULD_REFRESH_RENDER);
	}
	/**
	* Update or extend the current message of the Task and emit the neccassary events.
	*/
	set message$(data) {
		this.message = {
			...this.message,
			...data
		};
		this.emit(ListrTaskEventType.MESSAGE, data);
		this.listr.events.emit(ListrEventType.SHOULD_REFRESH_RENDER);
	}
	/**
	* Update the current title of the Task and emit the neccassary events.
	*/
	set title$(title) {
		this.title = title;
		this.emit(ListrTaskEventType.TITLE, title);
		this.listr.events.emit(ListrEventType.SHOULD_REFRESH_RENDER);
	}
	/**
	* Current task path in the hierarchy.
	*/
	get path() {
		return [...this.listr.path, this.initialTitle];
	}
	/**
	* Checks whether the current task with the given context should be set as enabled.
	*/
	async check(ctx) {
		if (this.state === ListrTaskState.WAITING) {
			this.enabled = await assertFunctionOrSelf(this.task?.enabled ?? true, ctx);
			this.emit(ListrTaskEventType.ENABLED, this.enabled);
			this.listr.events.emit(ListrEventType.SHOULD_REFRESH_RENDER);
		}
		return this.enabled;
	}
	/** Returns whether this task has subtasks. */
	hasSubtasks() {
		return this.subtasks?.length > 0;
	}
	/** Returns whether this task is finalized in someform. */
	hasFinalized() {
		return this.isCompleted() || this.hasFailed() || this.isSkipped() || this.hasRolledBack();
	}
	/** Returns whether this task is in progress. */
	isPending() {
		return this.isStarted() || this.isPrompt() || this.hasReset();
	}
	/** Returns whether this task has started. */
	isStarted() {
		return this.state === ListrTaskState.STARTED;
	}
	/** Returns whether this task is skipped. */
	isSkipped() {
		return this.state === ListrTaskState.SKIPPED;
	}
	/** Returns whether this task has been completed. */
	isCompleted() {
		return this.state === ListrTaskState.COMPLETED;
	}
	/** Returns whether this task has been failed. */
	hasFailed() {
		return this.state === ListrTaskState.FAILED;
	}
	/** Returns whether this task has an active rollback task going on. */
	isRollingBack() {
		return this.state === ListrTaskState.ROLLING_BACK;
	}
	/** Returns whether the rollback action was successful. */
	hasRolledBack() {
		return this.state === ListrTaskState.ROLLED_BACK;
	}
	/** Returns whether this task has an actively retrying task going on. */
	isRetrying() {
		return this.state === ListrTaskState.RETRY;
	}
	/** Returns whether this task has some kind of reset like retry and rollback going on. */
	hasReset() {
		return this.state === ListrTaskState.RETRY || this.state === ListrTaskState.ROLLING_BACK;
	}
	/** Returns whether enabled function resolves to true. */
	isEnabled() {
		return this.enabled;
	}
	/** Returns whether this task actually has a title. */
	hasTitle() {
		return typeof this?.title === "string";
	}
	/** Returns whether this task has a prompt inside. */
	isPrompt() {
		return this.state === ListrTaskState.PROMPT || this.state === ListrTaskState.PROMPT_COMPLETED;
	}
	/** Returns whether this task is currently paused. */
	isPaused() {
		return this.state === ListrTaskState.PAUSED;
	}
	/** Returns whether this task is closed. */
	isClosed() {
		return this.closed;
	}
	/** Pause the given task for certain time. */
	async pause(time) {
		const state = this.state;
		this.state$ = ListrTaskState.PAUSED;
		this.message$ = { paused: Date.now() + time };
		await delay(time);
		this.state$ = state;
		this.message$ = { paused: null };
	}
	/** Run the current task. */
	async run(context, wrapper) {
		const handleResult = (result) => {
			if (result instanceof Listr) {
				result.options = {
					...this.options,
					...result.options
				};
				result.rendererClass = getRendererClass("silent");
				this.subtasks = result.tasks;
				result.errors = this.listr.errors;
				this.emit(ListrTaskEventType.SUBTASK, this.subtasks);
				result = result.run(context);
			} else if (result instanceof Promise) result = result.then(handleResult);
			else if (isReadable(result)) result = new Promise((resolve, reject) => {
				result.on("data", (data) => {
					this.output$ = data.toString();
				});
				result.on("error", (error) => reject(error));
				result.on("end", () => resolve(null));
			});
			else if (isObservable(result)) result = new Promise((resolve, reject) => {
				result.subscribe({
					next: (data) => {
						this.output$ = data;
					},
					error: reject,
					complete: resolve
				});
			});
			return result;
		};
		const startTime = Date.now();
		this.state$ = ListrTaskState.STARTED;
		const skipped = await assertFunctionOrSelf(this.task?.skip ?? false, context);
		if (skipped) {
			if (typeof skipped === "string") this.message$ = { skip: skipped };
			else if (this.hasTitle()) this.message$ = { skip: this.title };
			else this.message$ = { skip: "Skipped task without a title." };
			this.state$ = ListrTaskState.SKIPPED;
			return;
		}
		try {
			const retryCount = typeof this.task?.retry === "number" && this.task.retry > 0 ? this.task.retry + 1 : typeof this.task?.retry === "object" && this.task.retry.tries > 0 ? this.task.retry.tries + 1 : 1;
			const retryDelay = typeof this.task.retry === "object" && this.task.retry.delay;
			for (let retries = 1; retries <= retryCount; retries++) try {
				await handleResult(this.taskFn(context, wrapper));
				break;
			} catch (err) {
				if (retries !== retryCount) {
					this.retry = {
						count: retries,
						error: err
					};
					this.message$ = { retry: this.retry };
					this.title$ = this.initialTitle;
					this.output = void 0;
					wrapper.report(err, ListrErrorTypes.WILL_RETRY);
					this.state$ = ListrTaskState.RETRY;
					if (retryDelay) await this.pause(retryDelay);
				} else throw err;
			}
			if (this.isStarted() || this.isRetrying()) {
				this.message$ = { duration: Date.now() - startTime };
				this.state$ = ListrTaskState.COMPLETED;
			}
		} catch (error) {
			if (this.prompt instanceof PromptError) error = this.prompt;
			if (this.task?.rollback) {
				wrapper.report(error, ListrErrorTypes.WILL_ROLLBACK);
				try {
					this.state$ = ListrTaskState.ROLLING_BACK;
					await this.task.rollback(context, wrapper);
					this.message$ = { rollback: this.title };
					this.state$ = ListrTaskState.ROLLED_BACK;
				} catch (err) {
					this.state$ = ListrTaskState.FAILED;
					wrapper.report(err, ListrErrorTypes.HAS_FAILED_TO_ROLLBACK);
					this.close();
					throw err;
				}
				if (this.listr.options?.exitAfterRollback !== false) {
					this.close();
					throw error;
				}
			} else {
				this.state$ = ListrTaskState.FAILED;
				if (this.listr.options.exitOnError !== false && await assertFunctionOrSelf(this.task?.exitOnError, context) !== false) {
					wrapper.report(error, ListrErrorTypes.HAS_FAILED);
					this.close();
					throw error;
				} else if (!this.hasSubtasks()) wrapper.report(error, ListrErrorTypes.HAS_FAILED_WITHOUT_ERROR);
			}
		} finally {
			this.close();
		}
	}
	close() {
		this.emit(ListrTaskEventType.CLOSED);
		this.listr.events.emit(ListrEventType.SHOULD_REFRESH_RENDER);
		this.complete();
	}
};
var ListrEventManager = class extends EventManager {};
/**
* Create a new task list with Listr.
*
* @see {@link https://listr2.kilic.dev/listr/listr.html}
*/
var Listr = class {
	tasks = [];
	errors = [];
	ctx;
	events;
	path = [];
	rendererClass;
	rendererClassOptions;
	rendererSelection;
	boundSignalHandler;
	concurrency;
	renderer;
	constructor(task, options, parentTask) {
		this.task = task;
		this.options = options;
		this.parentTask = parentTask;
		this.options = {
			concurrent: false,
			renderer: "default",
			fallbackRenderer: "simple",
			exitOnError: true,
			exitAfterRollback: true,
			collectErrors: false,
			registerSignalListeners: true,
			...this.parentTask?.options ?? {},
			...options
		};
		if (this.options.concurrent === true) this.options.concurrent = Infinity;
		else if (typeof this.options.concurrent !== "number") this.options.concurrent = 1;
		this.concurrency = new Concurrency({ concurrency: this.options.concurrent });
		if (parentTask) {
			this.path = [...parentTask.listr.path, parentTask.title];
			this.errors = parentTask.listr.errors;
		}
		if (this.parentTask?.listr.events instanceof ListrEventManager) this.events = this.parentTask.listr.events;
		else this.events = new ListrEventManager();
		/* istanbul ignore if */
		if (this.options?.forceTTY || process.env[ListrEnvironmentVariables.FORCE_TTY]) {
			process.stdout.isTTY = true;
			process.stderr.isTTY = true;
		}
		/* istanbul ignore if */
		if (this.options?.forceUnicode) process.env[ListrEnvironmentVariables.FORCE_UNICODE] = "1";
		const renderer = getRenderer({
			renderer: this.options.renderer,
			rendererOptions: this.options.rendererOptions,
			fallbackRenderer: this.options.fallbackRenderer,
			fallbackRendererOptions: this.options.fallbackRendererOptions,
			fallbackRendererCondition: this.options?.fallbackRendererCondition,
			silentRendererCondition: this.options?.silentRendererCondition
		});
		this.rendererClass = renderer.renderer;
		this.rendererClassOptions = renderer.options;
		this.rendererSelection = renderer.selection;
		/* istanbul ignore next */
		this.add(task ?? []);
		/* istanbul ignore if */
		if (this.options.registerSignalListeners) {
			this.boundSignalHandler = this.signalHandler.bind(this);
			process.once("SIGINT", this.boundSignalHandler).setMaxListeners(0);
		}
	}
	/**
	* Whether this is the root task.
	*/
	isRoot() {
		return !this.parentTask;
	}
	/**
	* Whether this is a subtask of another task list.
	*/
	isSubtask() {
		return !!this.parentTask;
	}
	/**
	* Add tasks to current task list.
	*
	* @see {@link https://listr2.kilic.dev/task/task.html}
	*/
	add(tasks) {
		this.tasks.push(...this.generate(tasks));
	}
	/**
	* Run the task list.
	*
	* @see {@link https://listr2.kilic.dev/listr/listr.html#run-the-generated-task-list}
	*/
	async run(context) {
		if (!this.renderer) this.renderer = new this.rendererClass(this.tasks, this.rendererClassOptions, this.events);
		await this.renderer.render();
		this.ctx = this.options?.ctx ?? context ?? {};
		await Promise.all(this.tasks.map((task) => task.check(this.ctx)));
		try {
			await Promise.all(this.tasks.map((task) => this.concurrency.add(() => this.runTask(task))));
			this.renderer.end();
			this.removeSignalHandler();
		} catch (err) {
			if (this.options.exitOnError !== false) {
				this.renderer.end(err);
				this.removeSignalHandler();
				throw err;
			}
		}
		return this.ctx;
	}
	generate(tasks) {
		tasks = Array.isArray(tasks) ? tasks : [tasks];
		return tasks.map((task) => {
			let rendererTaskOptions;
			if (this.rendererSelection === ListrRendererSelection.PRIMARY) rendererTaskOptions = task.rendererOptions;
			else if (this.rendererSelection === ListrRendererSelection.SECONDARY) rendererTaskOptions = task.fallbackRendererOptions;
			return new Task(this, task, this.options, this.rendererClassOptions, rendererTaskOptions);
		});
	}
	async runTask(task) {
		if (!await task.check(this.ctx)) return;
		return new TaskWrapper(task).run(this.ctx);
	}
	signalHandler() {
		this.tasks?.forEach(async (task) => {
			if (task.isPending()) task.state$ = ListrTaskState.FAILED;
		});
		if (this.isRoot()) {
			this.renderer?.end(/* @__PURE__ */ new Error("Interrupted."));
			process.exit(127);
		}
	}
	removeSignalHandler() {
		if (this.boundSignalHandler) process.removeListener("SIGINT", this.boundSignalHandler);
	}
};

//#endregion
//#region src/manager.ts
/**
* Creates a new Listr2 task manager.
*
* Useful for creating a single instance of Listr2 with pre-set settings.
*
* @see {@link https://listr2.kilic.dev/listr/manager.html}
*/
var Manager = class {
	errors = [];
	tasks = [];
	constructor(options) {
		this.options = options;
	}
	get ctx() {
		return this.options.ctx;
	}
	set ctx(ctx) {
		this.options.ctx = ctx;
	}
	add(tasks, options) {
		this.tasks = [...this.tasks, this.indent(tasks, options)];
	}
	async runAll(options) {
		options = {
			...this.options,
			...options
		};
		const tasks = [...this.tasks];
		this.tasks = [];
		const ctx = await this.run(tasks, options);
		return ctx;
	}
	newListr(tasks, options) {
		return new Listr(tasks, options);
	}
	indent(tasks, options, taskOptions) {
		options = {
			...this.options,
			...options
		};
		if (typeof tasks === "function") return {
			...taskOptions,
			task: (ctx) => this.newListr(tasks(ctx), options)
		};
		return {
			...taskOptions,
			task: () => this.newListr(tasks, options)
		};
	}
	async run(tasks, options) {
		options = {
			...this.options,
			...options
		};
		const task = this.newListr(tasks, options);
		const ctx = await task.run();
		this.errors.push(...task.errors);
		return ctx;
	}
};

//#endregion
exports.Manager = Manager;