@lewishowles/cli-style 0.8.1 → 0.10.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/CHANGELOG.md +23 -0
- package/README.md +99 -1
- package/adapters/bash/cli-style.sh +128 -6
- package/adapters/python/cli_style.py +52 -3
- package/adapters/swift/CliStyle.swift +60 -6
- package/bin/cli-style.js +10 -0
- package/package.json +1 -1
- package/src/capability/terminal.js +98 -0
- package/src/catalogue/renderer-catalogue.js +62 -0
- package/src/cli/catalogue-command.js +108 -0
- package/src/cli/gallery-command.js +8 -1
- package/src/cli/help.js +5 -0
- package/src/cli/render-command.js +23 -2
- package/src/formatters/ansi.js +17 -1
- package/src/gallery/render-gallery.js +133 -2
- package/src/index.js +19 -2
- package/src/patterns/diff-block.js +333 -0
- package/src/primitives/chip.js +1 -1
- package/src/primitives/panel.js +6 -1
- package/src/primitives/row-group.js +84 -0
- package/src/primitives/sparkline.js +209 -0
- package/src/theme/colours.js +172 -36
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.10.0 - 2026-07-20
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added light and dark ANSI-256 colour palettes with automatic theme detection (explicit flag/option, `COLORFGBG`, then a `COLORTERM`/`TERM_PROGRAM` best-effort signal, falling back to dark).
|
|
10
|
+
- Added `cli-style list` and `cli-style describe` for static renderer catalogue discovery.
|
|
11
|
+
- Added a `sparkline()` renderer (`sparkline` for `cli-style render`) for compact trend display with latest, minimum, and maximum values.
|
|
12
|
+
- Added a `diffBlock()` renderer (`diff-block` for `cli-style render`) for structured added/removed/context/header diff presentation.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Fixed panel body text losing legibility against its background fill in some theme/terminal combinations by giving panels their own explicit theme-matched text colour instead of relying on the terminal-inherited default.
|
|
17
|
+
|
|
18
|
+
## 0.9.0 - 2026-07-16
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Added a `rowGroup` primitive (`rowGroup()` in JS, the `row-group` renderer for `cli-style render`, and the same generic `render()`/`cli_style_render`/`CliStyle.render` entry points in Python, Bash, and Swift) that aligns a group of related rows automatically, without the caller computing `labelWidth` by hand.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Fixed the Python, Bash, and Swift adapters silently dropping `row()`, `span()`, and `divider()` options beyond their two or three main fields. `row()` now forwards `labelWidth`, `labelColour`, `valueColour`, and `separator`; `span()` forwards `weight`; `divider()` forwards `dividerWidth`, `dividerColour`, and `labelColour`.
|
|
27
|
+
|
|
5
28
|
## 0.8.1 - 2026-07-15
|
|
6
29
|
|
|
7
30
|
### Fixed
|
package/README.md
CHANGED
|
@@ -227,6 +227,7 @@ Renderer names are stable for `cli-style render`, `cli_style_render`, and Python
|
|
|
227
227
|
| --------------------- | ------------------------------------- | ------------------------------------ | ---------------------------------- | -------------------------------------- | --------------------------------------------------------------- |
|
|
228
228
|
| `status` | `status(resultType, detail, options)` | `cli_style_status type label detail` | `status(type, label, detail)` | `CliStyle.status(type, label, detail)` | Result line with symbol, label, and detail. |
|
|
229
229
|
| `row` | `row(label, value, options)` | `cli_style_row label value [result]` | `row(label, value, result)` | `CliStyle.row(label, value, result)` | Aligned label/value row, optionally marked with a result state. |
|
|
230
|
+
| `row-group` | `rowGroup(options)` | Use `cli_style_render` | Use `render("row-group", ...)` | Use `CliStyle.render` | Auto-aligned group of labelled value rows. |
|
|
230
231
|
| `span` | `span(value, tone, options)` | `cli_style_span value [tone]` | `span(value, tone)` | `CliStyle.span(value, tone)` | Inline colour or weight for a word, command, file, or value. |
|
|
231
232
|
| `hint` | `hint(message, options)` | `cli_style_hint message` | `hint(message)` | `CliStyle.hint(message)` | Informational hint line. |
|
|
232
233
|
| `divider` | `divider(options)` | `cli_style_divider label` | `divider(label)` | `CliStyle.divider(label)` | Section divider with an optional label. |
|
|
@@ -240,10 +241,12 @@ Renderer names are stable for `cli-style render`, `cli_style_render`, and Python
|
|
|
240
241
|
| `table` | `table(options)` | Use `cli_style_render` | Use `render("table", ...)` | Use `CliStyle.render` | Tabular records with narrow-width fallback. |
|
|
241
242
|
| `progress-bar` | `progressBar(options)` | Use `cli_style_render` | Use `render("progress-bar", ...)` | Use `CliStyle.render` | Single progress value with numeric text. |
|
|
242
243
|
| `bar-chart` | `barChart(options)` | Use `cli_style_render` | Use `render("bar-chart", ...)` | Use `CliStyle.render` | Multi-row bar chart. |
|
|
244
|
+
| `sparkline` | `sparkline(options)` | Use `cli_style_render` | Use `render("sparkline", ...)` | Use `CliStyle.render` | Compact trend with latest, minimum, and maximum values. |
|
|
243
245
|
| `step` | `step(label, state, options)` | Use `cli_style_render` | Use `render("step", ...)` | Use `CliStyle.render` | One workflow step. |
|
|
244
246
|
| `step-progress` | `stepProgress(options)` | Use `cli_style_render` | Use `render("step-progress", ...)` | Use `CliStyle.render` | Numbered workflow steps. |
|
|
245
247
|
| `empty-state` | `emptyState(title, detail, options)` | Use `cli_style_render` | Use `render("empty-state", ...)` | Use `CliStyle.render` | Empty result message. |
|
|
246
248
|
| `error-block` | `errorBlock(title, lines, options)` | Use `cli_style_render` | Use `render("error-block", ...)` | Use `CliStyle.render` | Structured error block. |
|
|
249
|
+
| `diff-block` | `diffBlock(diff, options)` | Use `cli_style_render` | Use `render("diff-block", ...)` | Use `CliStyle.render` | Structured added, removed, context, and header lines. |
|
|
247
250
|
|
|
248
251
|
Use `render("<renderer>", data, ...)` (Python) or `CliStyle.render(_:data:options:)` (Swift) for aggregate patterns (`diagnostic-report`, `agent-transcript`, `compact-data-table`) or any renderer with multi-item fields.
|
|
249
252
|
|
|
@@ -282,6 +285,27 @@ Use these shapes with `cli-style render`, `cli_style_render`, or Python `render(
|
|
|
282
285
|
- `labelWidth`: optional minimum label width
|
|
283
286
|
- `labelColour`, `valueColour`, `separator`: optional presentation overrides
|
|
284
287
|
|
|
288
|
+
### `row-group`
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
{
|
|
292
|
+
"rows": [
|
|
293
|
+
{
|
|
294
|
+
"label": "Package",
|
|
295
|
+
"value": "@lewishowles/components"
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"label": "Version",
|
|
299
|
+
"value": "minor: 2.7.4 -> 2.8.0"
|
|
300
|
+
}
|
|
301
|
+
]
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
- `rows`: labelled values to align and render
|
|
306
|
+
- `labelWidth`: optional minimum width for every label
|
|
307
|
+
- Per-row fields match `row`, including `label`, `value`, `result`, `labelColour`, `valueColour`, and `separator`
|
|
308
|
+
|
|
285
309
|
### `span`
|
|
286
310
|
|
|
287
311
|
```json
|
|
@@ -315,6 +339,7 @@ Pre-render a `span` when only part of the hint needs emphasis.
|
|
|
315
339
|
| `table` | `columns`, `rows`, `width` |
|
|
316
340
|
| `progress-bar` | `value`, `max`, `barWidth`, `tone` |
|
|
317
341
|
| `bar-chart` | `rows`, `barWidth` |
|
|
342
|
+
| `sparkline` | `values`, `label`, `tone`, `width` |
|
|
318
343
|
| `step` | `label`, `state` |
|
|
319
344
|
| `step-progress` | `steps`, `current` |
|
|
320
345
|
| `empty-state` | `title`, `detail` |
|
|
@@ -322,6 +347,35 @@ Pre-render a `span` when only part of the hint needs emphasis.
|
|
|
322
347
|
|
|
323
348
|
For visual examples, run `cli-style gallery --section primitives`.
|
|
324
349
|
|
|
350
|
+
### `sparkline`
|
|
351
|
+
|
|
352
|
+
Pass finite numbers in time order. The rendered trend always includes `latest`, `min`, and `max` context. Set `width` to limit plotted samples, `tone` to choose an optional semantic colour, `colour: false` to disable ANSI output, or `unicode: false` for an ASCII-only ramp.
|
|
353
|
+
|
|
354
|
+
```js
|
|
355
|
+
sparkline({ label: "Deploys", values: [1, 2, 3, 5, 8] });
|
|
356
|
+
// Deploys: ▁▂▃▅█ latest=8 min=1 max=8
|
|
357
|
+
|
|
358
|
+
sparkline({ label: "Rollback rate", values: [8, 6, 4, 2], tone: "warning" });
|
|
359
|
+
// Rollback rate: █▆▃▁ latest=2 min=2 max=8
|
|
360
|
+
|
|
361
|
+
sparkline({ label: "Flat", values: [4, 4, 4, 4] });
|
|
362
|
+
// Flat: ▄▄▄▄ latest=4 min=4 max=4
|
|
363
|
+
|
|
364
|
+
sparkline({ label: "Negative", values: [-6, -4, -2], colour: false });
|
|
365
|
+
// Negative: ▁▅█ latest=-2 min=-6 max=-2
|
|
366
|
+
|
|
367
|
+
sparkline({ label: "Narrow", values: [0, 10, -5, 5, 2, 8], width: 4 });
|
|
368
|
+
// Narrow: ▃█▁▇ latest=8 min=-5 max=10
|
|
369
|
+
|
|
370
|
+
sparkline({ label: "No colour", values: [1, 3, 2], colour: false });
|
|
371
|
+
// No colour: ▁█▅ latest=2 min=1 max=3
|
|
372
|
+
|
|
373
|
+
sparkline({ label: "No Unicode", values: [1, 3, 2], unicode: false });
|
|
374
|
+
// No Unicode: .#= latest=2 min=1 max=3
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Empty or unusable `values` return `""`.
|
|
378
|
+
|
|
325
379
|
## Patterns
|
|
326
380
|
|
|
327
381
|
Patterns are built-in composite renderers for common report shapes. They use the same lower-level primitives internally, but accept structured objects so callers do not need to assemble panels, statuses, tables, and rows by hand.
|
|
@@ -336,6 +390,33 @@ Patterns are built-in composite renderers for common report shapes. They use the
|
|
|
336
390
|
| `confirmation-result` | `confirmationResult(confirmation, options)` | Confirmation outcome with detail. | `title`, `state`, `action`, `item`, `detail` |
|
|
337
391
|
| `next-step-block` | `nextStepBlock(nextStep, options)` | Next-step guidance. | `title`, `next`, `reason`, `commands`, `alternatives` |
|
|
338
392
|
| `compact-data-table` | `compactDataTable(data, options)` | Titled compact data table. | `title`, `summary`, `columns`, `rows` |
|
|
393
|
+
| `diff-block` | `diffBlock(diff, options)` | Structured diff presentation. | `title`, `path`, `lines` |
|
|
394
|
+
|
|
395
|
+
### `diff-block`
|
|
396
|
+
|
|
397
|
+
Pass structured lines with one of four types. The renderer adds stable textual prefixes, so colour is optional and never carries meaning alone.
|
|
398
|
+
|
|
399
|
+
```json
|
|
400
|
+
{
|
|
401
|
+
"title": "Renderer change",
|
|
402
|
+
"path": "src/render.js",
|
|
403
|
+
"lines": [
|
|
404
|
+
{ "type": "header", "text": "render()" },
|
|
405
|
+
{ "type": "added", "newLineNumber": 102, "text": "return nextStep;" },
|
|
406
|
+
{ "type": "removed", "oldLineNumber": 101, "text": "return currentStep;" },
|
|
407
|
+
{
|
|
408
|
+
"type": "context",
|
|
409
|
+
"oldLineNumber": 100,
|
|
410
|
+
"newLineNumber": 100,
|
|
411
|
+
"text": "const currentStep = getStep();"
|
|
412
|
+
}
|
|
413
|
+
]
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
`oldLineNumber` and `newLineNumber` are optional caller-supplied fields. Added lines use the new number, removed lines use the old number, and context lines use both. Numbered blocks show a stable gutter and computed `(+added -removed)` summary. Missing numbers fall back to the unnumbered output.
|
|
418
|
+
|
|
419
|
+
`diff-block` presents structured data only. It does not parse unified-diff strings, calculate patches or line numbers, or apply changes. Invalid line entries are ignored safely.
|
|
339
420
|
|
|
340
421
|
For visual examples, run `cli-style gallery --section patterns`.
|
|
341
422
|
|
|
@@ -511,16 +592,18 @@ Most renderers accept the same output options:
|
|
|
511
592
|
| --------- | ------------------------------------------------------------------------- |
|
|
512
593
|
| `profile` | Output profile: `human`, `agent`, `diagnostic`, `ci`, `plain`, or `json`. |
|
|
513
594
|
| `colour` | Whether ANSI colour should be applied. |
|
|
595
|
+
| `theme` | `auto`, `light`, or `dark` semantic colour palette. |
|
|
514
596
|
| `unicode` | Whether Unicode symbols should be used. |
|
|
515
597
|
| `width` | Available output width for renderers that adapt layout. |
|
|
516
598
|
|
|
517
|
-
Use `createCliStyle()` to resolve these options from `argv`, `env`, `stdout`, CI, TTY, `NO_COLOR`, `FORCE_COLOR`, and terminal capability.
|
|
599
|
+
Use `createCliStyle()` to resolve these options from `argv`, `env`, `stdout`, CI, TTY, `NO_COLOR`, `FORCE_COLOR`, and terminal capability. `theme: "auto"` resolves in this order: explicit `--light`/`--dark` flags or `theme: "light"`/`"dark"`, recognised `COLORFGBG` background slot, `COLORTERM` or `TERM_PROGRAM`, then a dark fallback. The additional environment signals are best-effort terminal identifiers, so they select the conservative dark palette rather than claiming a light or dark preference. `NO_COLOR`, `TERM=dumb`, `--plain`, and explicit no-colour flags still disable colour.
|
|
518
600
|
|
|
519
601
|
### CLI and Bash flags
|
|
520
602
|
|
|
521
603
|
| Flag | Purpose |
|
|
522
604
|
| ---------------------------- | -------------------------------------- |
|
|
523
605
|
| `--profile <name>` | Render with a named profile. |
|
|
606
|
+
| `--light` / `--dark` | Override automatic terminal theme. |
|
|
524
607
|
| `--plain` | Disable colour and Unicode decoration. |
|
|
525
608
|
| `--no-colour` / `--no-color` | Disable ANSI colour. |
|
|
526
609
|
| `--no-unicode` | Use ASCII symbols. |
|
|
@@ -584,6 +667,19 @@ Tone values used by public APIs include `info`, `success`, `warning`, `danger`,
|
|
|
584
667
|
|
|
585
668
|
## Gallery
|
|
586
669
|
|
|
670
|
+
## Renderer discovery
|
|
671
|
+
|
|
672
|
+
List the available renderers or inspect one renderer before constructing a JSON payload:
|
|
673
|
+
|
|
674
|
+
```bash
|
|
675
|
+
cli-style list
|
|
676
|
+
cli-style list --json
|
|
677
|
+
cli-style describe progress-bar
|
|
678
|
+
cli-style describe progress-bar --json
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
`describe` includes the JavaScript API name, main input fields, and a focused gallery command when one is available.
|
|
682
|
+
|
|
587
683
|
Use the gallery to review current renderer output:
|
|
588
684
|
|
|
589
685
|
```bash
|
|
@@ -595,6 +691,8 @@ cli-style gallery --fixture audit-finding
|
|
|
595
691
|
cli-style gallery --profile agent
|
|
596
692
|
cli-style gallery --width 64
|
|
597
693
|
cli-style gallery --variants
|
|
694
|
+
cli-style gallery --light --section primitives
|
|
695
|
+
cli-style gallery --dark --section primitives
|
|
598
696
|
```
|
|
599
697
|
|
|
600
698
|
Use `--interactive` to select a section or fixture with `fzf` when it is installed.
|
|
@@ -159,6 +159,11 @@ cli_style_row() {
|
|
|
159
159
|
local label="${1:-}"
|
|
160
160
|
local value="${2:-}"
|
|
161
161
|
local result=""
|
|
162
|
+
local label_width=""
|
|
163
|
+
local label_colour_json="null"
|
|
164
|
+
local value_colour_json="null"
|
|
165
|
+
local separator_json="null"
|
|
166
|
+
local -a render_args=()
|
|
162
167
|
local json
|
|
163
168
|
|
|
164
169
|
if (($# >= 3)) && [[ "${3:-}" != --* ]]; then
|
|
@@ -170,9 +175,60 @@ cli_style_row() {
|
|
|
170
175
|
set --
|
|
171
176
|
fi
|
|
172
177
|
|
|
173
|
-
|
|
178
|
+
while (($# > 0)); do
|
|
179
|
+
case "$1" in
|
|
180
|
+
--label-width)
|
|
181
|
+
label_width="${2:-}"
|
|
182
|
+
shift 2
|
|
183
|
+
;;
|
|
184
|
+
--label-width=*)
|
|
185
|
+
label_width="${1#*=}"
|
|
186
|
+
shift
|
|
187
|
+
;;
|
|
188
|
+
--label-colour)
|
|
189
|
+
label_colour_json="$(cli_style_json_string "${2:-}")"
|
|
190
|
+
shift 2
|
|
191
|
+
;;
|
|
192
|
+
--label-colour=*)
|
|
193
|
+
label_colour_json="$(cli_style_json_string "${1#*=}")"
|
|
194
|
+
shift
|
|
195
|
+
;;
|
|
196
|
+
--value-colour)
|
|
197
|
+
value_colour_json="$(cli_style_json_string "${2:-}")"
|
|
198
|
+
shift 2
|
|
199
|
+
;;
|
|
200
|
+
--value-colour=*)
|
|
201
|
+
value_colour_json="$(cli_style_json_string "${1#*=}")"
|
|
202
|
+
shift
|
|
203
|
+
;;
|
|
204
|
+
--separator)
|
|
205
|
+
separator_json="$(cli_style_json_string "${2:-}")"
|
|
206
|
+
shift 2
|
|
207
|
+
;;
|
|
208
|
+
--separator=*)
|
|
209
|
+
separator_json="$(cli_style_json_string "${1#*=}")"
|
|
210
|
+
shift
|
|
211
|
+
;;
|
|
212
|
+
*)
|
|
213
|
+
render_args+=("$1")
|
|
214
|
+
shift
|
|
215
|
+
;;
|
|
216
|
+
esac
|
|
217
|
+
done
|
|
218
|
+
|
|
219
|
+
json="{\"label\":$(cli_style_json_string "$label"),\"value\":$(cli_style_json_string "$value"),\"result\":$(cli_style_json_string "$result"),\"labelWidth\":$(cli_style_json_integer_or_null "$label_width"),\"separator\":$separator_json"
|
|
220
|
+
|
|
221
|
+
if [[ "$label_colour_json" != "null" ]]; then
|
|
222
|
+
json="${json},\"labelColour\":$label_colour_json"
|
|
223
|
+
fi
|
|
174
224
|
|
|
175
|
-
|
|
225
|
+
if [[ "$value_colour_json" != "null" ]]; then
|
|
226
|
+
json="${json},\"valueColour\":$value_colour_json"
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
json="${json}}"
|
|
230
|
+
|
|
231
|
+
cli_style_render_json row "$json" "${render_args[@]}"
|
|
176
232
|
}
|
|
177
233
|
|
|
178
234
|
# Render an inline span from Bash string values.
|
|
@@ -186,6 +242,8 @@ cli_style_row() {
|
|
|
186
242
|
cli_style_span() {
|
|
187
243
|
local value="${1:-}"
|
|
188
244
|
local tone="info"
|
|
245
|
+
local weight_json="null"
|
|
246
|
+
local -a render_args=()
|
|
189
247
|
local json
|
|
190
248
|
|
|
191
249
|
if (($# >= 2)) && [[ "${2:-}" != --* ]]; then
|
|
@@ -197,9 +255,26 @@ cli_style_span() {
|
|
|
197
255
|
set --
|
|
198
256
|
fi
|
|
199
257
|
|
|
200
|
-
|
|
258
|
+
while (($# > 0)); do
|
|
259
|
+
case "$1" in
|
|
260
|
+
--weight)
|
|
261
|
+
weight_json="$(cli_style_json_string "${2:-}")"
|
|
262
|
+
shift 2
|
|
263
|
+
;;
|
|
264
|
+
--weight=*)
|
|
265
|
+
weight_json="$(cli_style_json_string "${1#*=}")"
|
|
266
|
+
shift
|
|
267
|
+
;;
|
|
268
|
+
*)
|
|
269
|
+
render_args+=("$1")
|
|
270
|
+
shift
|
|
271
|
+
;;
|
|
272
|
+
esac
|
|
273
|
+
done
|
|
274
|
+
|
|
275
|
+
json="{\"value\":$(cli_style_json_string "$value"),\"tone\":$(cli_style_json_string "$tone"),\"weight\":$weight_json}"
|
|
201
276
|
|
|
202
|
-
cli_style_render_json span "$json" "
|
|
277
|
+
cli_style_render_json span "$json" "${render_args[@]}"
|
|
203
278
|
}
|
|
204
279
|
|
|
205
280
|
# Render a divider from a Bash string value.
|
|
@@ -210,6 +285,10 @@ cli_style_span() {
|
|
|
210
285
|
# Render flags passed through to `cli-style render`.
|
|
211
286
|
cli_style_divider() {
|
|
212
287
|
local label="${1:-}"
|
|
288
|
+
local divider_width=""
|
|
289
|
+
local divider_colour_json="null"
|
|
290
|
+
local label_colour_json="null"
|
|
291
|
+
local -a render_args=()
|
|
213
292
|
local json
|
|
214
293
|
|
|
215
294
|
if (($# >= 1)); then
|
|
@@ -218,9 +297,52 @@ cli_style_divider() {
|
|
|
218
297
|
set --
|
|
219
298
|
fi
|
|
220
299
|
|
|
221
|
-
|
|
300
|
+
while (($# > 0)); do
|
|
301
|
+
case "$1" in
|
|
302
|
+
--divider-width)
|
|
303
|
+
divider_width="${2:-}"
|
|
304
|
+
shift 2
|
|
305
|
+
;;
|
|
306
|
+
--divider-width=*)
|
|
307
|
+
divider_width="${1#*=}"
|
|
308
|
+
shift
|
|
309
|
+
;;
|
|
310
|
+
--divider-colour)
|
|
311
|
+
divider_colour_json="$(cli_style_json_string "${2:-}")"
|
|
312
|
+
shift 2
|
|
313
|
+
;;
|
|
314
|
+
--divider-colour=*)
|
|
315
|
+
divider_colour_json="$(cli_style_json_string "${1#*=}")"
|
|
316
|
+
shift
|
|
317
|
+
;;
|
|
318
|
+
--label-colour)
|
|
319
|
+
label_colour_json="$(cli_style_json_string "${2:-}")"
|
|
320
|
+
shift 2
|
|
321
|
+
;;
|
|
322
|
+
--label-colour=*)
|
|
323
|
+
label_colour_json="$(cli_style_json_string "${1#*=}")"
|
|
324
|
+
shift
|
|
325
|
+
;;
|
|
326
|
+
*)
|
|
327
|
+
render_args+=("$1")
|
|
328
|
+
shift
|
|
329
|
+
;;
|
|
330
|
+
esac
|
|
331
|
+
done
|
|
332
|
+
|
|
333
|
+
json="{\"label\":$(cli_style_json_string "$label"),\"dividerWidth\":$(cli_style_json_integer_or_null "$divider_width")"
|
|
334
|
+
|
|
335
|
+
if [[ "$divider_colour_json" != "null" ]]; then
|
|
336
|
+
json="${json},\"dividerColour\":$divider_colour_json"
|
|
337
|
+
fi
|
|
338
|
+
|
|
339
|
+
if [[ "$label_colour_json" != "null" ]]; then
|
|
340
|
+
json="${json},\"labelColour\":$label_colour_json"
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
json="${json}}"
|
|
222
344
|
|
|
223
|
-
cli_style_render_json divider "$json" "
|
|
345
|
+
cli_style_render_json divider "$json" "${render_args[@]}"
|
|
224
346
|
}
|
|
225
347
|
|
|
226
348
|
# Render a hint from a Bash string value.
|
|
@@ -124,13 +124,39 @@ def status(
|
|
|
124
124
|
# Row value.
|
|
125
125
|
# @param {str} result
|
|
126
126
|
# Optional result type for a symbol and tone.
|
|
127
|
+
# @param {int|None} label_width
|
|
128
|
+
# Optional minimum label width.
|
|
129
|
+
# @param {str|None} label_colour
|
|
130
|
+
# Optional label colour token.
|
|
131
|
+
# @param {str|None} value_colour
|
|
132
|
+
# Optional value colour token.
|
|
133
|
+
# @param {str|None} separator
|
|
134
|
+
# Optional text between the label and value.
|
|
127
135
|
def row(
|
|
128
136
|
label: str,
|
|
129
137
|
value: str,
|
|
130
138
|
result: str = "",
|
|
139
|
+
label_width: int | None = None,
|
|
140
|
+
label_colour: str | None = None,
|
|
141
|
+
value_colour: str | None = None,
|
|
142
|
+
separator: str | None = None,
|
|
131
143
|
**kwargs: Any,
|
|
132
144
|
) -> str:
|
|
133
|
-
|
|
145
|
+
data = {
|
|
146
|
+
"label": label,
|
|
147
|
+
"value": value,
|
|
148
|
+
"result": result,
|
|
149
|
+
"labelWidth": label_width,
|
|
150
|
+
"separator": separator,
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if label_colour is not None:
|
|
154
|
+
data["labelColour"] = label_colour
|
|
155
|
+
|
|
156
|
+
if value_colour is not None:
|
|
157
|
+
data["valueColour"] = value_colour
|
|
158
|
+
|
|
159
|
+
return render("row", data, **kwargs)
|
|
134
160
|
|
|
135
161
|
|
|
136
162
|
# Render an inline span from Python values.
|
|
@@ -139,23 +165,46 @@ def row(
|
|
|
139
165
|
# Span text.
|
|
140
166
|
# @param {str} tone
|
|
141
167
|
# Optional colour tone, defaulting to info.
|
|
168
|
+
# @param {str|None} weight
|
|
169
|
+
# Optional ANSI text weight.
|
|
142
170
|
def span(
|
|
143
171
|
value: str,
|
|
144
172
|
tone: str = "info",
|
|
173
|
+
weight: str | None = None,
|
|
145
174
|
**kwargs: Any,
|
|
146
175
|
) -> str:
|
|
147
|
-
return render("span", {"value": value, "tone": tone}, **kwargs)
|
|
176
|
+
return render("span", {"value": value, "tone": tone, "weight": weight}, **kwargs)
|
|
148
177
|
|
|
149
178
|
|
|
150
179
|
# Render a divider from a Python value.
|
|
151
180
|
#
|
|
152
181
|
# @param {str} label
|
|
153
182
|
# Optional divider label.
|
|
183
|
+
# @param {int|None} divider_width
|
|
184
|
+
# Optional divider width.
|
|
185
|
+
# @param {str|None} divider_colour
|
|
186
|
+
# Optional divider colour token.
|
|
187
|
+
# @param {str|None} label_colour
|
|
188
|
+
# Optional label colour token.
|
|
154
189
|
def divider(
|
|
155
190
|
label: str = "",
|
|
191
|
+
divider_width: int | None = None,
|
|
192
|
+
divider_colour: str | None = None,
|
|
193
|
+
label_colour: str | None = None,
|
|
156
194
|
**kwargs: Any,
|
|
157
195
|
) -> str:
|
|
158
|
-
|
|
196
|
+
data = {
|
|
197
|
+
"label": label,
|
|
198
|
+
"dividerWidth": divider_width,
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if divider_colour is not None:
|
|
202
|
+
data["dividerColour"] = divider_colour
|
|
203
|
+
|
|
204
|
+
if label_colour is not None:
|
|
205
|
+
data["labelColour"] = label_colour
|
|
206
|
+
|
|
207
|
+
return render("divider", data, **kwargs)
|
|
159
208
|
|
|
160
209
|
|
|
161
210
|
# Render a hint from a Python value.
|
|
@@ -175,6 +175,10 @@ enum CliStyle {
|
|
|
175
175
|
- parameter label: Row label.
|
|
176
176
|
- parameter value: Row value.
|
|
177
177
|
- parameter result: Optional result type for a symbol and tone.
|
|
178
|
+
- parameter labelWidth: Optional minimum label width.
|
|
179
|
+
- parameter labelColour: Optional label colour token.
|
|
180
|
+
- parameter valueColour: Optional value colour token.
|
|
181
|
+
- parameter separator: Optional text between the label and value.
|
|
178
182
|
- parameter options: Render options.
|
|
179
183
|
- returns: Rendered row line.
|
|
180
184
|
- throws: `CliStyleError` on failure.
|
|
@@ -183,13 +187,35 @@ enum CliStyle {
|
|
|
183
187
|
label: String,
|
|
184
188
|
value: String,
|
|
185
189
|
result: String = "",
|
|
190
|
+
labelWidth: Int? = nil,
|
|
191
|
+
labelColour: String? = nil,
|
|
192
|
+
valueColour: String? = nil,
|
|
193
|
+
separator: String? = nil,
|
|
186
194
|
options: CliStyleOptions = .init()
|
|
187
195
|
) throws -> String {
|
|
188
|
-
|
|
196
|
+
var data: [String: Any] = [
|
|
189
197
|
"label": label,
|
|
190
198
|
"value": value,
|
|
191
199
|
"result": result,
|
|
192
|
-
]
|
|
200
|
+
]
|
|
201
|
+
|
|
202
|
+
if let labelWidth = labelWidth {
|
|
203
|
+
data["labelWidth"] = labelWidth
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if let labelColour = labelColour {
|
|
207
|
+
data["labelColour"] = labelColour
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if let valueColour = valueColour {
|
|
211
|
+
data["valueColour"] = valueColour
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if let separator = separator {
|
|
215
|
+
data["separator"] = separator
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return try render("row", data: data, options: options)
|
|
193
219
|
}
|
|
194
220
|
|
|
195
221
|
/**
|
|
@@ -197,6 +223,7 @@ enum CliStyle {
|
|
|
197
223
|
|
|
198
224
|
- parameter value: Span text.
|
|
199
225
|
- parameter tone: Optional colour tone, defaulting to info.
|
|
226
|
+
- parameter weight: Optional ANSI text weight.
|
|
200
227
|
- parameter options: Render options.
|
|
201
228
|
- returns: Rendered span string.
|
|
202
229
|
- throws: `CliStyleError` on failure.
|
|
@@ -204,29 +231,56 @@ enum CliStyle {
|
|
|
204
231
|
static func span(
|
|
205
232
|
value: String,
|
|
206
233
|
tone: String = "info",
|
|
234
|
+
weight: String? = nil,
|
|
207
235
|
options: CliStyleOptions = .init()
|
|
208
236
|
) throws -> String {
|
|
209
|
-
|
|
237
|
+
var data: [String: Any] = [
|
|
210
238
|
"value": value,
|
|
211
239
|
"tone": tone,
|
|
212
|
-
]
|
|
240
|
+
]
|
|
241
|
+
|
|
242
|
+
if let weight = weight {
|
|
243
|
+
data["weight"] = weight
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return try render("span", data: data, options: options)
|
|
213
247
|
}
|
|
214
248
|
|
|
215
249
|
/**
|
|
216
250
|
Render a divider.
|
|
217
251
|
|
|
218
252
|
- parameter label: Optional divider label.
|
|
253
|
+
- parameter dividerWidth: Optional divider width.
|
|
254
|
+
- parameter dividerColour: Optional divider colour token.
|
|
255
|
+
- parameter labelColour: Optional label colour token.
|
|
219
256
|
- parameter options: Render options.
|
|
220
257
|
- returns: Rendered divider line.
|
|
221
258
|
- throws: `CliStyleError` on failure.
|
|
222
259
|
*/
|
|
223
260
|
static func divider(
|
|
224
261
|
label: String = "",
|
|
262
|
+
dividerWidth: Int? = nil,
|
|
263
|
+
dividerColour: String? = nil,
|
|
264
|
+
labelColour: String? = nil,
|
|
225
265
|
options: CliStyleOptions = .init()
|
|
226
266
|
) throws -> String {
|
|
227
|
-
|
|
267
|
+
var data: [String: Any] = [
|
|
228
268
|
"label": label,
|
|
229
|
-
]
|
|
269
|
+
]
|
|
270
|
+
|
|
271
|
+
if let dividerWidth = dividerWidth {
|
|
272
|
+
data["dividerWidth"] = dividerWidth
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if let dividerColour = dividerColour {
|
|
276
|
+
data["dividerColour"] = dividerColour
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if let labelColour = labelColour {
|
|
280
|
+
data["labelColour"] = labelColour
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return try render("divider", data: data, options: options)
|
|
230
284
|
}
|
|
231
285
|
|
|
232
286
|
/**
|
package/bin/cli-style.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { Buffer } from "node:buffer";
|
|
4
4
|
import { createCliStyle, renderGallery, renderHelp } from "../src/index.js";
|
|
5
5
|
import { parseAdapterPathRequest, renderAdapterPath } from "../src/cli/adapter-path-command.js";
|
|
6
|
+
import { parseCatalogueRequest, renderCatalogue } from "../src/cli/catalogue-command.js";
|
|
6
7
|
import { parseRenderRequest, renderJsonInput } from "../src/cli/render-command.js";
|
|
7
8
|
|
|
8
9
|
import {
|
|
@@ -54,6 +55,15 @@ if (command === undefined || command === "--help" || command === "-h") {
|
|
|
54
55
|
console.error(error.message);
|
|
55
56
|
process.exitCode = 1;
|
|
56
57
|
}
|
|
58
|
+
} else if (command === "list" || command === "describe") {
|
|
59
|
+
try {
|
|
60
|
+
const request = parseCatalogueRequest(command, args.slice(1));
|
|
61
|
+
|
|
62
|
+
print(renderCatalogue(request, ui.options));
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error(error.message);
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
}
|
|
57
67
|
} else if (command === "render") {
|
|
58
68
|
try {
|
|
59
69
|
const request = parseRenderRequest(args.slice(1));
|