termkit 2.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +582 -37
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/index.d.ts +49 -96
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2584 -170
- package/dist/index.mjs +2563 -165
- package/dist/models/Bar.d.ts +125 -0
- package/dist/models/Bar.d.ts.map +1 -0
- package/dist/models/Chart.d.ts +106 -0
- package/dist/models/Chart.d.ts.map +1 -0
- package/dist/models/Column.d.ts +20 -0
- package/dist/models/Column.d.ts.map +1 -0
- package/dist/models/Command.d.ts +38 -0
- package/dist/models/Command.d.ts.map +1 -0
- package/dist/models/Input.d.ts +58 -0
- package/dist/models/Input.d.ts.map +1 -0
- package/dist/models/Log.d.ts +24 -0
- package/dist/models/Log.d.ts.map +1 -0
- package/dist/models/Markup.d.ts +17 -0
- package/dist/models/Markup.d.ts.map +1 -0
- package/dist/models/MultiBar.d.ts +17 -0
- package/dist/models/MultiBar.d.ts.map +1 -0
- package/dist/models/MultiSelect.d.ts +45 -0
- package/dist/models/MultiSelect.d.ts.map +1 -0
- package/dist/models/Option.d.ts +17 -0
- package/dist/models/Option.d.ts.map +1 -0
- package/dist/models/Scrollbox.d.ts +20 -0
- package/dist/models/Scrollbox.d.ts.map +1 -0
- package/dist/models/Select.d.ts +39 -0
- package/dist/models/Select.d.ts.map +1 -0
- package/dist/models/Spinner.d.ts +67 -0
- package/dist/models/Spinner.d.ts.map +1 -0
- package/dist/models/Table.d.ts +26 -0
- package/dist/models/Table.d.ts.map +1 -0
- package/dist/models/TermKit.d.ts +19 -0
- package/dist/models/TermKit.d.ts.map +1 -0
- package/dist/models/Variable.d.ts +28 -0
- package/dist/models/Variable.d.ts.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/cleanup.d.ts +2 -0
- package/dist/utils/cleanup.d.ts.map +1 -0
- package/dist/utils/color.d.ts +29 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/findCommand.d.ts +3 -0
- package/dist/utils/findCommand.d.ts.map +1 -0
- package/dist/utils/findCommandVariables.d.ts +3 -0
- package/dist/utils/findCommandVariables.d.ts.map +1 -0
- package/dist/utils/findOption.d.ts +3 -0
- package/dist/utils/findOption.d.ts.map +1 -0
- package/dist/utils/findOptions.d.ts +3 -0
- package/dist/utils/findOptions.d.ts.map +1 -0
- package/dist/utils/findVariable.d.ts +5 -0
- package/dist/utils/findVariable.d.ts.map +1 -0
- package/dist/utils/findVariables.d.ts +3 -0
- package/dist/utils/findVariables.d.ts.map +1 -0
- package/dist/utils/getVariables.d.ts +3 -0
- package/dist/utils/getVariables.d.ts.map +1 -0
- package/dist/utils/padLeft.d.ts +2 -0
- package/dist/utils/padLeft.d.ts.map +1 -0
- package/dist/utils/padRight.d.ts +2 -0
- package/dist/utils/padRight.d.ts.map +1 -0
- package/dist/utils/padSides.d.ts +2 -0
- package/dist/utils/padSides.d.ts.map +1 -0
- package/dist/utils/stringLength.d.ts +2 -0
- package/dist/utils/stringLength.d.ts.map +1 -0
- package/dist/utils/truncate.d.ts +2 -0
- package/dist/utils/truncate.d.ts.map +1 -0
- package/dist/utils/wrap.d.ts +2 -0
- package/dist/utils/wrap.d.ts.map +1 -0
- package/package.json +35 -7
- package/dist/index.d.mts +0 -99
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TermKit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TermKit is a complete terminal toolkit for Node.js. Build CLI programs with a fluent command API — nested subcommands, middleware, typed options — then prompt users interactively, render progress bars, tables, and charts, all from a single package with full TypeScript support.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -10,12 +10,14 @@ npm install termkit
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Program
|
|
14
|
+
|
|
15
|
+
`Program` is the entry point for CLI argument parsing. Define commands with `Program.command`, declare options, attach middleware and actions, then call `Program.parse` to run.
|
|
14
16
|
|
|
15
17
|
```ts
|
|
16
|
-
import {
|
|
18
|
+
import { Program } from 'termkit'
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
Program.command('my-app')
|
|
19
21
|
.version('1.0.0')
|
|
20
22
|
.description('My CLI application')
|
|
21
23
|
.option('v', 'verbose', null, 'Enable verbose output')
|
|
@@ -24,11 +26,7 @@ const program = command('my-app')
|
|
|
24
26
|
console.log(options.output)
|
|
25
27
|
})
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
program.parse(process.argv)
|
|
29
|
-
} catch (err) {
|
|
30
|
-
console.error(err)
|
|
31
|
-
}
|
|
29
|
+
Program.parse(process.argv)
|
|
32
30
|
```
|
|
33
31
|
|
|
34
32
|
### Options
|
|
@@ -36,7 +34,7 @@ try {
|
|
|
36
34
|
Options support four variable shapes:
|
|
37
35
|
|
|
38
36
|
```ts
|
|
39
|
-
command('app')
|
|
37
|
+
Program.command('app')
|
|
40
38
|
.option('b', 'boolean', null, 'Flag with no value')
|
|
41
39
|
.option('o', 'optional', '[val]', 'Optional value')
|
|
42
40
|
.option('r', 'required', '<val>', 'Required value')
|
|
@@ -56,34 +54,40 @@ Accessible in actions and middleware via the long name:
|
|
|
56
54
|
|
|
57
55
|
### Value coercion
|
|
58
56
|
|
|
59
|
-
Append `:number
|
|
57
|
+
Append `:number`, `:integer`, or `:boolean` to a variable to coerce the parsed string. Append `(min,max)` to enforce a numeric or length range. Use `|`-separated values for an enum:
|
|
60
58
|
|
|
61
59
|
```ts
|
|
62
|
-
command('app')
|
|
63
|
-
.option('p', 'port',
|
|
64
|
-
.option('
|
|
65
|
-
.option('n', 'nums',
|
|
60
|
+
Program.command('app')
|
|
61
|
+
.option('p', 'port', '<port:integer(1,65535)>', 'Port number')
|
|
62
|
+
.option('e', 'env', '<env:dev|staging|prod>', 'Environment')
|
|
63
|
+
.option('n', 'nums', '[nums:number...]', 'List of numbers')
|
|
64
|
+
.option('t', 'token', '<token:string(32,64)>', 'API token')
|
|
66
65
|
.action((options) => {
|
|
67
|
-
options.port
|
|
68
|
-
options.
|
|
69
|
-
options.nums
|
|
66
|
+
options.port // number
|
|
67
|
+
options.env // 'dev' | 'staging' | 'prod'
|
|
68
|
+
options.nums // number[]
|
|
69
|
+
options.token // string
|
|
70
70
|
})
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
Append `=default` inside the brackets to set a default value:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
.option('p', 'port', '[port:integer=3000]', 'Port number')
|
|
77
|
+
```
|
|
78
|
+
|
|
73
79
|
### Subcommands
|
|
74
80
|
|
|
75
81
|
Commands nest to any depth. Each level can have its own options and middleware.
|
|
76
82
|
|
|
77
83
|
```ts
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
command('app')
|
|
84
|
+
Program.command('app')
|
|
81
85
|
.commands([
|
|
82
|
-
command('serve')
|
|
86
|
+
Program.command('serve')
|
|
83
87
|
.option('p', 'port', '<port:number>', 'Port to listen on')
|
|
84
88
|
.action((options) => startServer(options.port)),
|
|
85
89
|
|
|
86
|
-
command('build')
|
|
90
|
+
Program.command('build')
|
|
87
91
|
.option('w', 'watch', null, 'Watch for changes')
|
|
88
92
|
.action((options) => runBuild(options)),
|
|
89
93
|
])
|
|
@@ -92,9 +96,9 @@ command('app')
|
|
|
92
96
|
Commands can also carry their own positional variables:
|
|
93
97
|
|
|
94
98
|
```ts
|
|
95
|
-
command('get', '<id>') // required
|
|
96
|
-
command('list', '[filter]') // optional
|
|
97
|
-
command('tag', '[tags...]') // array
|
|
99
|
+
Program.command('get', '<id>') // required
|
|
100
|
+
Program.command('list', '[filter]') // optional
|
|
101
|
+
Program.command('tag', '[tags...]') // array
|
|
98
102
|
```
|
|
99
103
|
|
|
100
104
|
### Middleware
|
|
@@ -102,7 +106,7 @@ command('tag', '[tags...]') // array
|
|
|
102
106
|
Middleware runs before the action. It can mutate the options object and supports async.
|
|
103
107
|
|
|
104
108
|
```ts
|
|
105
|
-
command('app')
|
|
109
|
+
Program.command('app')
|
|
106
110
|
.middleware(async (options) => {
|
|
107
111
|
options.user = await getUser(options.token)
|
|
108
112
|
})
|
|
@@ -118,9 +122,7 @@ Use `.middlewares([...])` to register several at once. When navigating into a su
|
|
|
118
122
|
Apply middleware or options to every command created after the call:
|
|
119
123
|
|
|
120
124
|
```ts
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
setDefaults({
|
|
125
|
+
Program.setDefaults({
|
|
124
126
|
middlewares: [
|
|
125
127
|
async (options) => { options.timestamp = Date.now() }
|
|
126
128
|
]
|
|
@@ -136,25 +138,568 @@ my-app help
|
|
|
136
138
|
my-app serve help
|
|
137
139
|
```
|
|
138
140
|
|
|
141
|
+
### configure
|
|
142
|
+
|
|
143
|
+
Sets global display options for the entire toolkit — accent color used in help output, tables, charts, and prompts; plus Unicode glyph support.
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { configure } from 'termkit'
|
|
147
|
+
|
|
148
|
+
configure({
|
|
149
|
+
color: '#a855f7', // any named color, hex string, or xterm number
|
|
150
|
+
glyphs: true,
|
|
151
|
+
})
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Input
|
|
155
|
+
|
|
156
|
+
Interactive text prompt. Supports string, number, integer, boolean, and enum types with validation.
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { input, confirm } from 'termkit'
|
|
160
|
+
|
|
161
|
+
const name = await input('Project name?', { default: 'my-app', minLength: 2, maxLength: 20 })
|
|
162
|
+
const port = await input('Port?', { type: 'number', default: 3000, min: 1024, max: 65535 })
|
|
163
|
+
const env = await input('Environment?', { type: 'enum', enum: ['dev', 'staging', 'prod'] })
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Use `confirm` as a shorthand for boolean prompts:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
const deploy = await confirm('Deploy to production?', { default: false })
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The text cursor supports left/right arrows, Home/End, Ctrl+A/E, and forward Delete for mid-string editing.
|
|
173
|
+
|
|
174
|
+
Options: `type`, `default`, `placeholder`, `mask`, `inline`, `required`, `min`, `max`, `minLength`, `maxLength`, `enum`, `match`, `regex`, `errorMessage`, `promptColor`, `promptGlyph`, `inputColor`, `errorColor`.
|
|
175
|
+
|
|
176
|
+
### Select
|
|
177
|
+
|
|
178
|
+
Single-item interactive picker. Navigate with ↑↓ or number keys, confirm with Enter.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { select } from 'termkit'
|
|
182
|
+
|
|
183
|
+
const env = await select('Deploy target?', [
|
|
184
|
+
{ label: 'Production', description: 'live traffic' },
|
|
185
|
+
{ label: 'Staging', description: 'QA sign-off required' },
|
|
186
|
+
{ label: 'Development', description: 'free-for-all' },
|
|
187
|
+
])
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Pass `search: true` to add a type-to-filter input. Typing narrows the list; Backspace removes the last character. Number shortcuts are disabled in search mode — use ↑↓.
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
const pkg = await select('Pick a package:', packages, { search: true })
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Pass `maxHeight` to cap the visible rows and enable scrolling. The viewport follows the cursor automatically.
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
const tz = await select('Timezone?', timezones, { maxHeight: 8 })
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Both options compose freely:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const country = await select('Country?', countries, { search: true, maxHeight: 6 })
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Options: `colors`, `colorCycle`, `shimmer`, `skipLabel`, `promptColor`, `promptGlyph`, `descriptionColor`, `selectedPrefix`, `selectedSuffix`, `interval`, `search`, `maxHeight`.
|
|
209
|
+
|
|
210
|
+
### MultiSelect
|
|
211
|
+
|
|
212
|
+
Multi-item interactive picker. Returns an array of the selected items.
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
import { multiSelect } from 'termkit'
|
|
216
|
+
|
|
217
|
+
const features = await multiSelect('Enable features?', [
|
|
218
|
+
{ label: 'Authentication' },
|
|
219
|
+
{ label: 'Rate limiting' },
|
|
220
|
+
{ label: 'Caching', description: 'Redis-backed' },
|
|
221
|
+
{ label: 'Webhooks' },
|
|
222
|
+
])
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Keyboard controls: ↑↓ navigate · Space/Tab toggle · → select · ← deselect · `a` select all · Enter confirm.
|
|
226
|
+
|
|
227
|
+
Enforce selection counts with `min` and `max`:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
const roles = await multiSelect('Assign roles:', items, { min: 1, max: 3 })
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Pass `search: true` to add a type-to-filter input. All printable characters go to the query; `a` select-all is disabled in search mode. Checked items are tracked by their position in the original list so toggling survives filtering.
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
const pkgs = await multiSelect('Add dependencies:', packages, { search: true })
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Pass `maxHeight` to cap the visible rows with auto-scrolling:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const regions = await multiSelect('Deploy to:', regions, { maxHeight: 6 })
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Options: `min`, `max`, `allowSkip`, `colors`, `colorCycle`, `shimmer`, `checkedPrefix`, `uncheckedPrefix`, `promptColor`, `promptGlyph`, `descriptionColor`, `errorColor`, `interval`, `search`, `maxHeight`.
|
|
246
|
+
|
|
247
|
+
### Log
|
|
248
|
+
|
|
249
|
+
`log` is a singleton logger. `Log` is the class for custom instances.
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
import { log } from 'termkit'
|
|
253
|
+
|
|
254
|
+
log.succeed('Build complete')
|
|
255
|
+
log.fail('Connection refused')
|
|
256
|
+
log.warn('Rate limited, retrying')
|
|
257
|
+
log.info('Listening on port 3000')
|
|
258
|
+
log.data({ user: 'alice', role: 'admin', active: true })
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Custom instance with colors:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
import { Log } from 'termkit'
|
|
265
|
+
|
|
266
|
+
const logger = new Log({ successColor: '#a855f7', failColor: '#ef4444' })
|
|
267
|
+
logger.succeed('Custom color')
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### markup
|
|
271
|
+
|
|
272
|
+
Pretty-prints any value with syntax coloring — strings, numbers, booleans, `null`, `Date`, nested objects, and arrays.
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import { markup } from 'termkit'
|
|
276
|
+
|
|
277
|
+
console.log(markup({ name: 'alice', roles: ['admin', 'editor'], active: true }))
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Custom styles and value translations:
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
import { markup, Color } from 'termkit'
|
|
284
|
+
|
|
285
|
+
const out = markup(data, {
|
|
286
|
+
styles: {
|
|
287
|
+
number: (v) => Color.hex('#f97316')(v),
|
|
288
|
+
boolean: (v) => Color.hex('#a855f7')(v),
|
|
289
|
+
},
|
|
290
|
+
translations: {
|
|
291
|
+
createdAt: (v) => new Date(v as string),
|
|
292
|
+
},
|
|
293
|
+
})
|
|
294
|
+
console.log(out)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Table
|
|
298
|
+
|
|
299
|
+
Renders tabular data with auto-sized columns, optional titles, alignment, and meta rows.
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
import { Table } from 'termkit'
|
|
303
|
+
|
|
304
|
+
const rows = [
|
|
305
|
+
{ name: 'Alice', role: 'admin', active: true },
|
|
306
|
+
{ name: 'Bob', role: 'editor', active: false },
|
|
307
|
+
]
|
|
308
|
+
|
|
309
|
+
new Table(rows).print()
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Column configuration — pass a `columns` array to control ordering, titles, alignment, and value formatting:
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
new Table(rows, {
|
|
316
|
+
title: 'Users',
|
|
317
|
+
columns: [
|
|
318
|
+
{ key: 'name', title: 'Name' },
|
|
319
|
+
{ key: 'role', title: 'Role', align: 'center' },
|
|
320
|
+
{ key: 'active', title: 'Active', value: (v) => (v ? 'yes' : 'no'), align: 'right' },
|
|
321
|
+
],
|
|
322
|
+
separator: ' ',
|
|
323
|
+
}).print()
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Global alignment, margin, and meta rows (rendered below a separator after the data rows):
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
new Table(rows, {
|
|
330
|
+
align: Table.center, // Table.left | Table.center | Table.right
|
|
331
|
+
margin: 1, // extra space added to each column's padding
|
|
332
|
+
meta: [{ name: 'Total', role: '', active: '' }],
|
|
333
|
+
}).print()
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Passing a string shorthand instead of a `ColumnOptions` object uses the key as both key and title:
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
new Table(rows, { columns: ['name', 'role'] }).print()
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Chart
|
|
343
|
+
|
|
344
|
+
The `Chart` namespace provides horizontal bar, vertical column, heatmap, scatter, line, and sparkline visualizations. Every chart class has a `.print()` method that writes to stdout and a `.toString()` method that returns the rendered string.
|
|
345
|
+
|
|
346
|
+
All chart constructors accept optional `paddingX` and `paddingY` options to add whitespace around the output.
|
|
347
|
+
|
|
348
|
+
#### Chart.Bar
|
|
349
|
+
|
|
350
|
+
Horizontal bar chart. Each item maps a label to a value; the bar width scales to fill the terminal.
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
import { Chart } from 'termkit'
|
|
354
|
+
|
|
355
|
+
new Chart.Bar([
|
|
356
|
+
{ key: 'Mon', value: 42 },
|
|
357
|
+
{ key: 'Tue', value: 67 },
|
|
358
|
+
{ key: 'Wed', value: 31 },
|
|
359
|
+
]).print()
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Custom style and `null` gaps (blank rows):
|
|
363
|
+
|
|
364
|
+
```ts
|
|
365
|
+
import { Chart, Color } from 'termkit'
|
|
366
|
+
|
|
367
|
+
new Chart.Bar([
|
|
368
|
+
{ key: 'Errors', value: 12, style: Color.red },
|
|
369
|
+
{ key: 'Warnings', value: 45, style: Color.yellow },
|
|
370
|
+
null,
|
|
371
|
+
{ key: 'OK', value: 89, style: Color.green },
|
|
372
|
+
]).print()
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Pass `character` to use a custom fill character instead of a solid block:
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
new Chart.Bar([
|
|
379
|
+
{ key: 'CPU', value: 72, character: '▪' },
|
|
380
|
+
{ key: 'RAM', value: 55, character: '▪' },
|
|
381
|
+
]).print()
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Pass `width` to override the terminal column width used for scaling:
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
new Chart.Bar(data, { width: 60, paddingX: 2, paddingY: 1 }).print()
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### Chart.VerticalBar
|
|
391
|
+
|
|
392
|
+
Vertical column chart using Unicode block characters with fractional height resolution.
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
new Chart.VerticalBar([
|
|
396
|
+
{ key: 'M', value: 10 },
|
|
397
|
+
{ key: 'T', value: 25 },
|
|
398
|
+
{ key: 'W', value: 18 },
|
|
399
|
+
{ key: 'T', value: 30 },
|
|
400
|
+
{ key: 'F', value: 22 },
|
|
401
|
+
], { height: 8, colWidth: 3 }).print()
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Pass `null` items to insert gaps between column groups:
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
new Chart.VerticalBar([
|
|
408
|
+
{ key: 'A', value: 15, style: Color.blue },
|
|
409
|
+
{ key: 'B', value: 28, style: Color.blue },
|
|
410
|
+
null,
|
|
411
|
+
{ key: 'C', value: 10, style: Color.magenta },
|
|
412
|
+
], { height: 10 }).print()
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Pass `width` to have `colWidth` auto-calculated to fill a fixed total width:
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
new Chart.VerticalBar(data, { width: 40, height: 12 }).print()
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### Chart.Heatmap
|
|
422
|
+
|
|
423
|
+
2-D grid colored by value intensity between a configurable low and high color.
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
new Chart.Heatmap(
|
|
427
|
+
[
|
|
428
|
+
[1, 5, 9, 3],
|
|
429
|
+
[2, 6, 3, 8],
|
|
430
|
+
[8, 4, 7, 2],
|
|
431
|
+
],
|
|
432
|
+
{
|
|
433
|
+
rowLabels: ['Row A', 'Row B', 'Row C'],
|
|
434
|
+
colLabels: ['C1', 'C2', 'C3', 'C4'],
|
|
435
|
+
colors: ['#0000ff', '#ff0000'],
|
|
436
|
+
}
|
|
437
|
+
).print()
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Multi-stop color scale and explicit range:
|
|
441
|
+
|
|
442
|
+
```ts
|
|
443
|
+
new Chart.Heatmap(data, {
|
|
444
|
+
colors: ['#0000ff', '#00ffff', '#ffff00', '#ff0000'],
|
|
445
|
+
min: 0,
|
|
446
|
+
max: 100,
|
|
447
|
+
cellWidth: 3,
|
|
448
|
+
}).print()
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
#### Chart.Scatter
|
|
452
|
+
|
|
453
|
+
2-D scatter plot with optional labeled axes. Points outside the plot bounds are silently clipped.
|
|
454
|
+
|
|
455
|
+
```ts
|
|
456
|
+
new Chart.Scatter([
|
|
457
|
+
{ x: 1, y: 2 },
|
|
458
|
+
{ x: 3, y: 5 },
|
|
459
|
+
{ x: 7, y: 3 },
|
|
460
|
+
]).print()
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
Custom characters, per-point styles, and explicit axis bounds:
|
|
464
|
+
|
|
465
|
+
```ts
|
|
466
|
+
import { Chart, Color } from 'termkit'
|
|
467
|
+
|
|
468
|
+
new Chart.Scatter([
|
|
469
|
+
{ x: 10, y: 20, character: '●', style: Color.green },
|
|
470
|
+
{ x: 30, y: 50, character: '●', style: Color.red },
|
|
471
|
+
], {
|
|
472
|
+
width: 60,
|
|
473
|
+
height: 20,
|
|
474
|
+
xMin: 0,
|
|
475
|
+
xMax: 40,
|
|
476
|
+
yMin: 0,
|
|
477
|
+
yMax: 60,
|
|
478
|
+
}).print()
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Disable axes for a raw grid output:
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
new Chart.Scatter(data, { axes: false }).print()
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
#### Chart.Line
|
|
488
|
+
|
|
489
|
+
Line chart that interpolates between data points. Accepts the same axis options as `Chart.Scatter`.
|
|
490
|
+
|
|
491
|
+
```ts
|
|
492
|
+
import { Chart } from 'termkit'
|
|
493
|
+
|
|
494
|
+
new Chart.Line(
|
|
495
|
+
Array.from({ length: 40 }, (_, i) => ({ x: i, y: Math.sin(i * 0.3) * 4 })),
|
|
496
|
+
{ height: 12 }
|
|
497
|
+
).print()
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
Per-point styles and optional fill below the line:
|
|
501
|
+
|
|
502
|
+
```ts
|
|
503
|
+
import { Chart, Color } from 'termkit'
|
|
504
|
+
|
|
505
|
+
new Chart.Line(data, { fill: true, style: (s) => Color.cyan(s) }).print()
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Options: `width`, `height`, `xMin`, `xMax`, `yMin`, `yMax`, `character`, `axes`, `fill`, `paddingX`, `paddingY`.
|
|
509
|
+
|
|
510
|
+
#### Chart.Sparkline
|
|
511
|
+
|
|
512
|
+
Returns a single-line sparkline string using Unicode block characters. Useful for inline metrics.
|
|
513
|
+
|
|
514
|
+
```ts
|
|
515
|
+
import { Chart, Color } from 'termkit'
|
|
516
|
+
|
|
517
|
+
const samples = [12, 45, 23, 67, 89, 55, 34, 78, 61]
|
|
518
|
+
console.log('CPU ' + Chart.Sparkline(samples, { style: (s) => Color.green(s) }))
|
|
519
|
+
// CPU ▁▃▁▅█▄▂▆▄
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Options: `min`, `max`, `style`.
|
|
523
|
+
|
|
524
|
+
### Bar — ETA and rate tracking
|
|
525
|
+
|
|
526
|
+
Attach progress tracking to an animated `Bar` with `.track()` and `.tick()`.
|
|
527
|
+
|
|
528
|
+
```ts
|
|
529
|
+
import { Bar } from 'termkit'
|
|
530
|
+
|
|
531
|
+
const total = 500
|
|
532
|
+
const bar = new Bar({ progress: 0 })
|
|
533
|
+
bar.track(total, { showRate: true, showEta: true, unit: 'files' })
|
|
534
|
+
bar.message('Processing…')
|
|
535
|
+
bar.start()
|
|
536
|
+
|
|
537
|
+
for await (const item of items) {
|
|
538
|
+
await process(item)
|
|
539
|
+
bar.tick()
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
bar.stop()
|
|
543
|
+
bar.succeed(`Done — ${total} files processed`)
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Each `tick(n?)` increments the completed count, updates `progress`, and appends a live `12.3/s · ETA 8s` suffix that shrinks the bar to keep the full line within terminal width.
|
|
547
|
+
|
|
548
|
+
Raw values are available as getters at any time:
|
|
549
|
+
|
|
550
|
+
```ts
|
|
551
|
+
bar.rate // units per second (number)
|
|
552
|
+
bar.eta // estimated seconds remaining (number)
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
Options on `track(total, opts?)`: `unit` (label appended to rate), `showRate` (default `true`), `showEta` (default `true`). Both can also be set via constructor: `new Bar({ showRate: true, showEta: true, rateUnit: 'MB' })`.
|
|
556
|
+
|
|
557
|
+
### MultiBar
|
|
558
|
+
|
|
559
|
+
Renders multiple `Bar` instances as a synchronized block. Each bar animates independently; calling `.succeed()`, `.fail()`, `.warn()`, or `.info()` on a bar freezes that line while the others keep running. The group stops automatically when every bar is finalized.
|
|
560
|
+
|
|
561
|
+
```ts
|
|
562
|
+
import { MultiBar, Bar } from 'termkit'
|
|
563
|
+
|
|
564
|
+
const multi = new MultiBar()
|
|
565
|
+
const download = multi.add({ text: 'Downloading', progress: 0, colors: Bar.COLORS.cool })
|
|
566
|
+
const build = multi.add({ text: 'Building', progress: 0, colors: Bar.COLORS.heat })
|
|
567
|
+
const deploy = multi.add({ text: 'Deploying' }) // indeterminate until started
|
|
568
|
+
|
|
569
|
+
multi.start()
|
|
570
|
+
|
|
571
|
+
await runDownload(p => { download.progress = p })
|
|
572
|
+
download.succeed('Downloaded')
|
|
573
|
+
|
|
574
|
+
await runBuild(p => { build.progress = p })
|
|
575
|
+
build.succeed('Built')
|
|
576
|
+
|
|
577
|
+
deploy.progress = 0
|
|
578
|
+
await runDeploy(p => { deploy.progress = p })
|
|
579
|
+
deploy.succeed('Deployed')
|
|
580
|
+
|
|
581
|
+
multi.stop()
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Each `add()` call accepts the same options as `Bar` and returns a `Bar` instance — `.message()`, `.tick()`, `.track()`, `.progress`, and the completion methods all work the same way. Bars must be added before `.start()`.
|
|
585
|
+
|
|
586
|
+
Options: `interval`.
|
|
587
|
+
|
|
588
|
+
### Spinner
|
|
589
|
+
|
|
590
|
+
Animated spinner for indeterminate work. Shares the same completion API as `Bar` — `.succeed()`, `.fail()`, `.warn()`, `.info()`.
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
import { Spinner } from 'termkit'
|
|
594
|
+
|
|
595
|
+
const spinner = new Spinner({ text: 'Loading…' })
|
|
596
|
+
spinner.start()
|
|
597
|
+
|
|
598
|
+
await doWork()
|
|
599
|
+
|
|
600
|
+
spinner.succeed('Done')
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
Update the label while running:
|
|
604
|
+
|
|
605
|
+
```ts
|
|
606
|
+
spinner.message('Still working…')
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Built-in frame sets are available on `Spinner.FRAMES`:
|
|
610
|
+
|
|
611
|
+
```ts
|
|
612
|
+
new Spinner({ frames: Spinner.FRAMES.dots, text: 'Thinking…' }).start()
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Frame sets: `braille`, `dots`, `line`, `arrow`, `bounce`.
|
|
616
|
+
|
|
617
|
+
Options: `frames`, `text`, `prefix`, `suffix`, `reverse`, `interval`, `colors`, `bgColors`, `colorCycle`, `shimmer`, `successColor`, `failColor`, `warnColor`, `infoColor`, `glyphs`.
|
|
618
|
+
|
|
619
|
+
### Scrollbox
|
|
620
|
+
|
|
621
|
+
Interactive terminal pager. Renders a fixed-height viewport over an array of strings with keyboard navigation. Requires an interactive TTY.
|
|
622
|
+
|
|
623
|
+
```ts
|
|
624
|
+
import { scrollbox } from 'termkit'
|
|
625
|
+
|
|
626
|
+
await scrollbox(lines, { height: 20, title: 'Output', lineNumbers: true })
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Or use the class directly for more control:
|
|
630
|
+
|
|
631
|
+
```ts
|
|
632
|
+
import { Scrollbox } from 'termkit'
|
|
633
|
+
|
|
634
|
+
const box = new Scrollbox({ height: 15, scrollbar: true, wrapLines: true })
|
|
635
|
+
await box.show(lines)
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Keyboard controls: ↑↓ / `j` `k` scroll one line · `d` / `u` half-page · `f` / `b` full page · `g` top · `G` bottom · Enter / Escape / `q` close.
|
|
639
|
+
|
|
640
|
+
Options: `height`, `title`, `lineNumbers`, `scrollbar`, `borderColor`, `wrapLines`.
|
|
641
|
+
|
|
642
|
+
### truncate
|
|
643
|
+
|
|
644
|
+
ANSI-aware string truncation. Measures visible length ignoring escape codes, and appends a configurable suffix.
|
|
645
|
+
|
|
646
|
+
```ts
|
|
647
|
+
import { truncate } from 'termkit'
|
|
648
|
+
|
|
649
|
+
truncate('The quick brown fox jumps over the lazy dog', 20)
|
|
650
|
+
// 'The quick brown fox…'
|
|
651
|
+
|
|
652
|
+
truncate(coloredString, 40, ' [more]')
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
### wrap
|
|
656
|
+
|
|
657
|
+
ANSI-aware word wrap. Breaks at spaces to keep each line within a given column width.
|
|
658
|
+
|
|
659
|
+
```ts
|
|
660
|
+
import { wrap } from 'termkit'
|
|
661
|
+
|
|
662
|
+
console.log(wrap(longParagraph, 60))
|
|
663
|
+
```
|
|
664
|
+
|
|
139
665
|
## API
|
|
140
666
|
|
|
667
|
+
### Program
|
|
668
|
+
|
|
669
|
+
| Method | Signature | Description |
|
|
670
|
+
|---|---|---|
|
|
671
|
+
| `Program.command` | `(name, variables?, info?) => Command` | Create a command |
|
|
672
|
+
| `Program.option` | `(short, long, variables, info) => Option` | Create a standalone option |
|
|
673
|
+
| `Program.middleware` | `(fn) => fn` | Identity helper for typing middleware inline |
|
|
674
|
+
| `Program.parse` | `(argv) => Promise<void>` | Parse argv using the root command |
|
|
675
|
+
| `Program.setDefaults` | `(defaults) => void` | Apply middleware/options to all new commands |
|
|
676
|
+
|
|
141
677
|
### Functions
|
|
142
678
|
|
|
143
679
|
| Function | Signature | Description |
|
|
144
680
|
|---|---|---|
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
681
|
+
| `configure` | `(opts) => void` | Set global accent color and display options |
|
|
682
|
+
| `scrollbox` | `(lines, options?) => Promise<void>` | Interactive terminal pager |
|
|
683
|
+
| `markup` | `(data, options?) => string` | Pretty-print a value with syntax coloring |
|
|
684
|
+
| `input` | `(prompt, options?) => Promise<string \| number \| boolean \| null>` | Interactive text prompt |
|
|
685
|
+
| `confirm` | `(prompt, options?) => Promise<boolean \| null>` | Boolean yes/no prompt |
|
|
686
|
+
| `select` | `(prompt, items, options?) => Promise<T \| null>` | Single-item interactive picker |
|
|
687
|
+
| `multiSelect` | `(prompt, items, options?) => Promise<T[] \| null>` | Multi-item interactive picker |
|
|
688
|
+
| `Chart.Sparkline` | `(data, options?) => string` | Single-line sparkline string |
|
|
689
|
+
| `truncate` | `(s, maxLength, suffix?) => string` | ANSI-aware string truncation |
|
|
690
|
+
| `wrap` | `(s, width) => string` | ANSI-aware word wrap |
|
|
691
|
+
| `padLeft` | `(s, width) => string` | Right-align a string within a fixed width |
|
|
692
|
+
| `padRight` | `(s, width) => string` | Left-align a string within a fixed width |
|
|
693
|
+
| `padSides` | `(s, width) => string` | Center a string within a fixed width |
|
|
694
|
+
| `stringLength` | `(s) => number` | Visual length of a string, stripping ANSI escape codes |
|
|
150
695
|
|
|
151
696
|
### Classes
|
|
152
697
|
|
|
153
|
-
`Command`, `Option`, `Variable`, `TermKit`
|
|
698
|
+
`Command`, `Option`, `Variable`, `TermKit`, `Bar`, `MultiBar`, `Spinner`, `Scrollbox`, `Input`, `Select`, `MultiSelect`, `Log`, `Table`, `Column`, `Chart.Bar`, `Chart.VerticalBar`, `Chart.Heatmap`, `Chart.Scatter`, `Chart.Line`
|
|
154
699
|
|
|
155
700
|
### Types
|
|
156
701
|
|
|
157
|
-
`ActionFn`, `MiddlewareFn`, `ParsedOptions`, `CommandDefaults`, `VariableType`
|
|
702
|
+
`ActionFn`, `MiddlewareFn`, `ParsedOptions`, `CommandDefaults`, `VariableType`, `BarMode`, `BarOptions`, `MultiBarOptions`, `SpinnerOptions`, `InputOptions`, `InputReturn`, `InputType`, `SelectItem`, `SelectOptions`, `MultiSelectItem`, `MultiSelectOptions`, `LogOptions`, `TableOptions`, `ColumnOptions`, `ColumnAlign`, `MarkupOptions`, `MarkupStyleFn`, `MarkupStyles`, `HelpColor`, `Chart.BarItem`, `Chart.BarOptions`, `Chart.VerticalBarItem`, `Chart.VerticalBarOptions`, `Chart.HeatmapOptions`, `Chart.ScatterPoint`, `Chart.ScatterOptions`, `Chart.LinePoint`, `Chart.LineOptions`, `Chart.SparklineOptions`
|
|
158
703
|
|
|
159
704
|
## Authors
|
|
160
705
|
|