or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdfile-system.mdindex.mdnetwork-operations.mdprocess-management.mdshell-execution.mduser-interaction.mdutilities.md

user-interaction.mddocs/

0

# User Interaction

1

2

Interactive utilities for user input, output formatting, visual feedback, and data processing in command-line scripts.

3

4

## Capabilities

5

6

### Output Functions

7

8

Display formatted output and information to users.

9

10

```typescript { .api }

11

/**

12

* Print formatted output to console

13

* @param args - Values to print (or template literal with interpolations)

14

*/

15

function echo(...args: any[]): void;

16

function echo(pieces: TemplateStringsArray, ...args: any[]): void;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { echo, $ } from "zx";

23

24

// Simple output

25

echo('Hello World');

26

echo('Deployment status:', 'success');

27

28

// Template literal format

29

const status = 'completed';

30

const time = new Date().toISOString();

31

echo`Deployment ${status} at ${time}`;

32

33

// With ProcessOutput

34

const result = await $`git branch --show-current`;

35

echo`Current branch: ${result}`;

36

37

// Multiple values

38

echo('Server:', 'production', 'Port:', 8080);

39

```

40

41

### User Input

42

43

Get interactive input from users with optional choices and completion.

44

45

```typescript { .api }

46

/**

47

* Prompt user for input with optional choices and completion

48

* @param query - Question to ask the user

49

* @param options - Configuration options

50

* @returns Promise resolving to user's input

51

*/

52

function question(

53

query?: string,

54

options?: {

55

/** Array of suggested choices for tab completion */

56

choices?: string[];

57

/** Input stream (default: process.stdin) */

58

input?: NodeJS.ReadStream;

59

/** Output stream (default: process.stdout) */

60

output?: NodeJS.WriteStream;

61

}

62

): Promise<string>;

63

```

64

65

**Usage Examples:**

66

67

```typescript

68

import { question, echo } from "zx";

69

70

// Simple question

71

const name = await question('What is your name? ');

72

echo`Hello, ${name}!`;

73

74

// With choices (tab completion)

75

const environment = await question('Deploy to which environment? ', {

76

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

77

});

78

79

// Confirmation prompt

80

const proceed = await question('Continue with deployment? (y/n) ');

81

if (proceed.toLowerCase() !== 'y') {

82

echo('Deployment cancelled');

83

process.exit(0);

84

}

85

86

// Custom streams

87

import fs from 'fs';

88

const input = fs.createReadStream('./input.txt');

89

const response = await question('Question: ', { input });

90

```

91

92

### Standard Input Processing

93

94

Read and process data from standard input streams.

95

96

```typescript { .api }

97

/**

98

* Read all data from standard input

99

* @param stream - Input stream (default: process.stdin)

100

* @returns Promise resolving to input content as string

101

*/

102

function stdin(stream?: Readable): Promise<string>;

103

```

104

105

**Usage Examples:**

106

107

```typescript

108

import { stdin, echo, $ } from "zx";

109

110

// Read from standard input

111

echo('Please enter your data (Ctrl+D to finish):');

112

const input = await stdin();

113

echo`You entered: ${input}`;

114

115

// Process piped input

116

const data = await stdin();

117

const lines = data.trim().split('\n');

118

echo`Received ${lines.length} lines`;

119

120

// Use with custom stream

121

import fs from 'fs';

122

const fileStream = fs.createReadStream('./data.txt');

123

const fileContent = await stdin(fileStream);

124

echo`File content: ${fileContent}`;

125

126

// Combine with shell commands

127

const logData = await $`tail -f /var/log/system.log`.pipe(process.stdout);

128

```

129

130

### Visual Feedback

131

132

Provide visual feedback during long-running operations.

133

134

```typescript { .api }

135

/**

136

* Show a spinner during async operation execution

137

* @param title - Spinner text (optional)

138

* @param callback - Async function to execute

139

* @returns Promise resolving to callback result

140

*/

141

function spinner<T>(title: string, callback: () => T): Promise<T>;

142

function spinner<T>(callback: () => T): Promise<T>;

143

```

144

145

**Usage Examples:**

146

147

```typescript

148

import { spinner, $, sleep } from "zx";

149

150

// Simple spinner

151

const result = await spinner('Deploying application...', async () => {

152

await $`docker build -t myapp .`;

153

await $`docker push myapp`;

154

return 'success';

155

});

156

157

// Spinner without title

158

await spinner(async () => {

159

await sleep('2s');

160

await $`npm install`;

161

});

162

163

// Complex operations

164

const deployment = await spinner('Setting up infrastructure...', async () => {

165

// Multiple operations

166

await $`terraform init`;

167

await $`terraform plan -out=plan.out`;

168

await $`terraform apply plan.out`;

169

170

return {

171

status: 'deployed',

172

timestamp: new Date().toISOString()

173

};

174

});

175

176

echo`Deployment completed: ${deployment.status}`;

177

178

// Conditional spinner (disabled in CI)

179

const buildResult = await spinner('Building project...', async () => {

180

return await $`npm run build`;

181

});

182

// Spinner automatically disabled if process.env.CI is set

183

```

184

185

### Argument Processing

186

187

Parse and process command-line arguments.

188

189

```typescript { .api }

190

/**

191

* Parse command-line arguments with options

192

* @param args - Arguments array (default: process.argv.slice(2))

193

* @param opts - Parsing options

194

* @param defs - Default values

195

* @returns Parsed arguments object

196

*/

197

function parseArgv(

198

args?: string[],

199

opts?: ArgvOpts,

200

defs?: Record<string, any>

201

): minimist.ParsedArgs;

202

203

/**

204

* Update the global argv object with new arguments

205

* @param args - New arguments to parse

206

* @param opts - Parsing options

207

*/

208

function updateArgv(args?: string[], opts?: ArgvOpts): void;

209

210

/**

211

* Global parsed arguments object

212

*/

213

declare const argv: minimist.ParsedArgs;

214

215

interface ArgvOpts extends minimist.Opts {

216

/** Convert kebab-case to camelCase */

217

camelCase?: boolean;

218

/** Parse string 'true'/'false' to boolean */

219

parseBoolean?: boolean;

220

}

221

```

222

223

**Usage Examples:**

224

225

```typescript

226

import { parseArgv, argv, echo } from "zx";

227

228

// Using global argv

229

echo`Script called with:`, argv;

230

console.log('Environment:', argv.env || 'development');

231

console.log('Verbose mode:', argv.verbose || false);

232

233

// Custom argument parsing

234

const args = parseArgv(['--port', '3000', '--host', 'localhost', '--verbose'], {

235

default: { port: 8080 },

236

boolean: ['verbose'],

237

string: ['host']

238

});

239

console.log(args); // { port: 3000, host: 'localhost', verbose: true, _: [] }

240

241

// With camelCase conversion

242

const camelArgs = parseArgv(['--api-key', 'secret', '--max-retries', '3'], {

243

camelCase: true,

244

parseBoolean: true

245

});

246

console.log(camelArgs.apiKey); // 'secret'

247

console.log(camelArgs.maxRetries); // 3

248

249

// Update global argv

250

updateArgv(['--env', 'production'], { camelCase: true });

251

echo`Environment: ${argv.env}`;

252

253

// Default values

254

const config = parseArgv(process.argv.slice(2), {

255

default: {

256

port: 8080,

257

host: '0.0.0.0',

258

env: 'development'

259

},

260

boolean: ['verbose', 'debug'],

261

string: ['host', 'env'],

262

number: ['port']

263

});

264

```

265

266

### Sleep and Timing

267

268

Asynchronous delays and timing utilities.

269

270

```typescript { .api }

271

/**

272

* Asynchronous sleep/delay

273

* @param duration - Sleep duration (string like '2s', '500ms' or number in ms)

274

* @returns Promise that resolves after the specified duration

275

*/

276

function sleep(duration: Duration): Promise<void>;

277

278

type Duration = string | number;

279

```

280

281

**Usage Examples:**

282

283

```typescript

284

import { sleep, echo, $ } from "zx";

285

286

// String duration formats

287

await sleep('2s'); // 2 seconds

288

await sleep('500ms'); // 500 milliseconds

289

await sleep('1m'); // 1 minute

290

await sleep('1.5s'); // 1.5 seconds

291

292

// Numeric duration (milliseconds)

293

await sleep(1000); // 1 second

294

295

// In scripts

296

echo('Starting deployment...');

297

await sleep('1s');

298

299

await $`docker build -t myapp .`;

300

echo('Build complete, waiting before push...');

301

await sleep('2s');

302

303

await $`docker push myapp`;

304

echo('Deployment complete!');

305

306

// Retry with delays

307

for (let i = 0; i < 3; i++) {

308

try {

309

await $`curl -f https://api.example.com/health`;

310

echo('Service is healthy');

311

break;

312

} catch (error) {

313

echo(`Health check failed (attempt ${i + 1}), retrying...`);

314

await sleep('5s');

315

}

316

}

317

```

318

319

## Types

320

321

```typescript { .api }

322

/**

323

* Duration specification as string or milliseconds

324

*/

325

type Duration = string | number;

326

327

/**

328

* Parsed command-line arguments

329

*/

330

interface ParsedArgs {

331

/** Non-option arguments */

332

_: string[];

333

/** Named arguments */

334

[key: string]: any;

335

}

336

337

/**

338

* minimist parsing options extended with zx-specific options

339

*/

340

interface ArgvOpts extends minimist.Opts {

341

/** Convert kebab-case to camelCase */

342

camelCase?: boolean;

343

/** Parse 'true'/'false' strings to booleans */

344

parseBoolean?: boolean;

345

/** Default values for arguments */

346

default?: Record<string, any>;

347

/** Keys that should be treated as booleans */

348

boolean?: string | string[];

349

/** Keys that should be treated as strings */

350

string?: string | string[];

351

/** Keys that should be treated as numbers */

352

number?: string | string[];

353

/** Argument aliases */

354

alias?: Record<string, string | string[]>;

355

}

356

357

/**

358

* Node.js readable stream interface

359

*/

360

interface Readable extends NodeJS.ReadableStream {

361

setEncoding(encoding: BufferEncoding): this;

362

[Symbol.asyncIterator](): AsyncIterableIterator<any>;

363

}

364

```