@openluxeco/cli 0.6.0 → 0.6.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/banner.js +66 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openluxeco/cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Official OpenLuxe command-line client — drive the OpenLuxe v1 API from your terminal or an AI agent.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/banner.js CHANGED
@@ -2,6 +2,10 @@
2
2
  * The OpenLuxe splash — the diamond estate mark stacked above the wordmark,
3
3
  * washed in champagne gold. Shown at the top of `openluxe` / `openluxe help`.
4
4
  *
5
+ * Responsive: picks a rendition that fits the terminal width (full ANSI-shadow
6
+ * wordmark ≥ 72 cols, compact box-drawing wordmark ≥ 36, spaced letters below
7
+ * that) so a thin pane never wraps the art into noise.
8
+ *
5
9
  * Zero-dep: hand-set ASCII + 256-color ANSI. Color is applied only on an
6
10
  * interactive stdout without NO_COLOR, so piped output stays clean.
7
11
  */
@@ -10,19 +14,31 @@ import { VERSION } from './config.js';
10
14
  // The mark: nested shield/gem outline (public/images/mark.svg) — apex, angled
11
15
  // shoulders, vertical sides, chamfered flat base, hollow double-walled center.
12
16
  const MARK = [
13
- ' ╱╲',
14
- ' ╱ ╲',
15
- ' ╱ ╱╲ ╲',
16
- ' ╱ ╱ ╲ ╲',
17
- ' ╱ ╱ ╲ ╲',
18
- ' ╱ ╱ ╲ ╲',
19
- ' │ │ │ │',
20
- ' │ │ │ │',
21
- ' │ ╰────────╯ │',
22
- ' ╲ ╱',
23
- ' ╲──────────╱',
17
+ ' ╱╲',
18
+ ' ╱ ╲',
19
+ ' ╱ ╱╲ ╲',
20
+ ' ╱ ╱ ╲ ╲',
21
+ ' ╱ ╱ ╲ ╲',
22
+ ' ╱ ╱ ╲ ╲',
23
+ '│ │ │ │',
24
+ '│ │ │ │',
25
+ '│ ╰────────╯ │',
26
+ '╲ ╱',
27
+ ' ╲──────────╱',
28
+ ];
29
+
30
+ const MARK_SMALL = [
31
+ ' ╱╲',
32
+ ' ╱ ╲',
33
+ ' ╱ ╱╲ ╲',
34
+ ' ╱ ╱ ╲ ╲',
35
+ '│ │ │ │',
36
+ '│ ╰────╯ │',
37
+ '╲ ╱',
38
+ ' ╲──────╱',
24
39
  ];
25
40
 
41
+ // 68 cols — ANSI-shadow.
26
42
  const WORDMARK = [
27
43
  ' ██████╗ ██████╗ ███████╗███╗ ██╗██╗ ██╗ ██╗██╗ ██╗███████╗',
28
44
  '██╔═══██╗██╔══██╗██╔════╝████╗ ██║██║ ██║ ██║╚██╗██╔╝██╔════╝',
@@ -32,37 +48,52 @@ const WORDMARK = [
32
48
  ' ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝',
33
49
  ];
34
50
 
35
- const WIDTH = 68; // wordmark widtheverything centers against it
51
+ // 32 colscompact box-drawing caps.
52
+ const WORDMARK_SMALL = [
53
+ '╔═╗ ╔═╗ ╔═╗ ╔╗╔ ╦ ╦ ╦ ═╗ ╦ ╔═╗',
54
+ '║ ║ ╠═╝ ║╣ ║║║ ║ ║ ║ ╔╩╦╝ ║╣ ',
55
+ '╚═╝ ╩ ╚═╝ ╝╚╝ ╩═╝ ╚═╝ ╩ ╚═ ╚═╝',
56
+ ];
36
57
 
37
58
  // Champagne ramp, light → deep gold (xterm 256).
38
- const MARK_RAMP = [230, 230, 223, 223, 222, 221, 220, 220, 178, 178, 172];
39
- const WORD_RAMP = [223, 222, 220, 220, 178, 172];
59
+ const RAMP = [230, 223, 222, 221, 220, 220, 178, 172];
40
60
 
41
- function paint(line, color, on) {
42
- return on ? `\x1b[38;5;${color}m${line}\x1b[0m` : line;
43
- }
44
-
45
- function center(line, width = WIDTH) {
46
- const pad = Math.max(0, Math.floor((width - line.length) / 2));
47
- return ' '.repeat(pad) + line;
61
+ function width(lines) {
62
+ return Math.max(...lines.map((l) => l.length));
48
63
  }
49
64
 
50
65
  export function banner() {
66
+ const cols = process.stdout.columns || 80;
51
67
  const on = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
52
68
  const dim = (s) => (on ? `\x1b[2m${s}\x1b[0m` : s);
53
69
 
54
- const markPad = ' '.repeat(Math.floor((WIDTH - 20) / 2) - 2);
55
- const lines = [
56
- '',
57
- ...MARK.map((l, i) => markPad + paint(l, MARK_RAMP[i], on)),
58
- '',
59
- ...WORDMARK.map((l, i) => paint(l, WORD_RAMP[i], on)),
60
- '',
61
- center(`v${VERSION} · the platform, from your terminal · openluxe.co/developers`).replace(
62
- /^(\s*)(.*)$/,
63
- (_, s, t) => s + dim(t),
64
- ),
65
- '',
66
- ];
67
- return lines.join('\n');
70
+ let mark, word, footer;
71
+ if (cols >= 72) {
72
+ mark = MARK;
73
+ word = WORDMARK;
74
+ footer = `v${VERSION} · the platform, from your terminal · openluxe.co/developers`;
75
+ } else if (cols >= 36) {
76
+ mark = MARK_SMALL;
77
+ word = WORDMARK_SMALL;
78
+ footer = `v${VERSION} · openluxe.co/developers`;
79
+ } else {
80
+ mark = MARK_SMALL;
81
+ word = ['O P E N L U X E'];
82
+ footer = `v${VERSION} · openluxe.co`;
83
+ }
84
+
85
+ // Center everything against the widest element that still fits the pane.
86
+ // Blocks get ONE shared left margin (per-line centering would bend the
87
+ // mark's diagonals, since its rows are pre-aligned to each other).
88
+ const frame = Math.min(cols, Math.max(width(mark), width(word), footer.length));
89
+ const center = (line) => ' '.repeat(Math.max(0, Math.floor((frame - line.length) / 2))) + line;
90
+ const shade = (lines) => {
91
+ const pad = ' '.repeat(Math.max(0, Math.floor((frame - width(lines)) / 2)));
92
+ return lines.map((l, i) => {
93
+ const color = RAMP[Math.min(RAMP.length - 1, Math.floor((i / lines.length) * RAMP.length))];
94
+ return on ? `\x1b[38;5;${color}m${pad}${l}\x1b[0m` : pad + l;
95
+ });
96
+ };
97
+
98
+ return ['', ...shade(mark), '', ...shade(word), '', dim(center(footer))].join('\n');
68
99
  }