@jango-blockchained/hoox-cli 0.4.0 → 0.5.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/src/ui/banner.ts CHANGED
@@ -1,11 +1,23 @@
1
1
  /**
2
- * Hoox ASCII banner — big block letter style with box framing.
3
- * Rendered with theme colors for consistent terminal output.
2
+ * Hoox ASCII banner — variants for the interactive TUI.
3
+ * Each variant provides a different visual style while maintaining
4
+ * consistent branding and theme coloring.
4
5
  */
5
6
 
6
7
  import { theme } from "../utils/theme.js";
7
8
 
8
- const BANNER_LINES = [
9
+ const TAGLINE = "Cloudflare Workers Platform";
10
+ const VERSION = "0.3.0";
11
+
12
+ // ── Shared constants ──────────────────────────────────────────────
13
+
14
+ /** Disclaimer line rendered below the banner and in the footer. */
15
+ export const DISCLAIMER =
16
+ "DISCLAIMER: Trading cryptocurrencies involves substantial risk of loss. Use at your own risk.";
17
+
18
+ // ── Variant 0 — Default (legacy) ──────────────────────────────────
19
+
20
+ const LEGACY_LINES = [
9
21
  "██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗",
10
22
  "██║ ██║██╔═══██╗██╔═══██╗╚██╗██╔╝",
11
23
  "███████║██║ ██║██║ ██║ ╚███╔╝ ",
@@ -14,34 +26,111 @@ const BANNER_LINES = [
14
26
  "╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝",
15
27
  ];
16
28
 
17
- const TAGLINE = "Cloudflare Workers Platform";
18
- const VERSION = "v0.3.0";
29
+ function renderLegacy(): string {
30
+ const bw = 52;
31
+ const line = ` ${theme.dim("─").repeat(bw - 2)}`;
32
+ const top = ` ${theme.dim("┌")}${line.slice(2)}${theme.dim("┐")}`;
33
+ const bottom = ` ${theme.dim("└")}${line.slice(2)}${theme.dim("┘")}`;
34
+ const ascii = LEGACY_LINES.map((l) => ` ${theme.heading(l)}`);
35
+ const gap = Math.floor((bw - TAGLINE.length - VERSION.length - 2) / 2);
36
+ const tag = ` ${" ".repeat(gap)}${theme.dim(TAGLINE)} ${theme.dim(`v${VERSION}`)}`;
37
+ return [top, ...ascii, line, tag, bottom].join("\n");
38
+ }
19
39
 
20
- /**
21
- * Render the Hoox ASCII banner with theme coloring and box framing.
22
- */
23
- export function renderBanner(): string {
24
- const bannerWidth = 52;
25
- const top = ` ${theme.corner.charAt(0)}${theme.separator.repeat(bannerWidth - 2)}${theme.corner.charAt(2)}`;
26
- const bottom = ` ${theme.corner.charAt(3)}${theme.separator.repeat(bannerWidth - 2)}${theme.corner.charAt(1)}`;
27
-
28
- const lines = BANNER_LINES.map((line) => ` ${theme.heading(line)}`);
29
-
30
- // Center the tagline
31
- const taglineLeft = Math.floor(
32
- (bannerWidth - TAGLINE.length - VERSION.length - 2) / 2
33
- );
34
- const tagline = ` ${" ".repeat(taglineLeft)}${theme.dim(TAGLINE)} ${theme.dim(VERSION)}`;
35
-
36
- const result = [
37
- top,
38
- ...lines,
39
- ` ${theme.separator.repeat(bannerWidth - 2)}`,
40
- tagline,
41
- bottom,
40
+ // ── Variant 1 — "Horizon" (architectural) ─────────────────────────
41
+ // Uses double-line frame characters and a more open, architectural feel.
42
+ // The "HOOX" wordmark is built from simple geometric blocks.
43
+
44
+ const HORIZON_LINES = [
45
+ "╔═══╗ ╔═══╗ ╔═══╗ ╔═══╗",
46
+ "║ ║ ║ ║ ║ ║ ║",
47
+ "║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║",
48
+ "║ ╚═╝ ╚═╝ ║ ║ ╚═╝",
49
+ "║ ║ ║ ╚═╝ ║ ",
50
+ "╚═════╝ ╚═════╝ ╚═══╝ ╚═════╝",
51
+ ];
52
+
53
+ export function renderBannerHorizon(): string {
54
+ const bw = 56;
55
+ const inner = theme.dim("─").repeat(bw - 2);
56
+ const top = ` ${theme.dim("╭")}${inner}${theme.dim("╮")}`;
57
+ const bottom = ` ${theme.dim("╰")}${inner}${theme.dim("╯")}`;
58
+ const ascii = HORIZON_LINES.map((l) => ` ${theme.accent(l)}`);
59
+ const gap = Math.floor((bw - TAGLINE.length - VERSION.length - 4) / 2);
60
+ const tag = ` ${" ".repeat(gap)}${theme.dim(TAGLINE)} ${theme.dim(`v${VERSION}`)}`;
61
+ return [top, ...ascii, theme.dim("─").repeat(bw), tag, bottom].join("\n");
62
+ }
63
+
64
+ // ── Variant 2 — "Signal" (data / waveform) ────────────────────────
65
+ // Evokes trading signals and monitoring. Uses a smaller wordmark
66
+ // with a dynamic waveform motif beneath it.
67
+
68
+ const SIGNAL_LINES = [
69
+ " _ _ _ _ ",
70
+ " | | | | ___ __| | | | ",
71
+ " | |_| |/ _ \\ / _` | | | ",
72
+ " | _ | (_) | (_| | | | ",
73
+ " |_| |_|\\___/ \\__,_| |_| ",
74
+ ];
75
+
76
+ export function renderBannerSignal(): string {
77
+ const bw = 54;
78
+ const line = theme.dim("─").repeat(bw);
79
+ const top = ` ${theme.dim("┌")}${line.slice(2)}${theme.dim("┐")}`;
80
+ const bottom = ` ${theme.dim("└")}${line.slice(2)}${theme.dim("┘")}`;
81
+
82
+ const wordmark = SIGNAL_LINES.map((l) => {
83
+ // Colour the letters H O O X, dim the rest
84
+ return ` ${theme.heading(l.slice(0, 26))}${theme.dim(l.slice(26))}`;
85
+ });
86
+
87
+ // Waveform line — sine-wave art
88
+ const wave = ` ${theme.accent("~~")}${theme.dim("~")}${theme.accent("_")}${theme.dim(".")}${theme.accent("/\\")}${theme.dim("~")}${theme.accent("\\/")}${theme.dim("..")}${theme.accent("/~~\\")}${theme.dim("~")} ${theme.dim(TAGLINE)} ${theme.dim(`v${VERSION}`)}`;
89
+
90
+ return [top, ...wordmark, line, wave, bottom].join("\n");
91
+ }
92
+
93
+ // ── Variant 3 — "Minimal" (clean badge) ───────────────────────────
94
+ // No ASCII art — just the project name, version, and a clean
95
+ // double-rule header. Professional and understated.
96
+
97
+ export function renderBannerMinimal(): string {
98
+ const bw = 50;
99
+ const rule = theme.dim("━").repeat(bw);
100
+ const inner = theme.dim("─").repeat(bw);
101
+
102
+ const leftPad = Math.floor((bw - TAGLINE.length - VERSION.length - 8) / 2);
103
+ const titleLine =
104
+ " ".repeat(leftPad) +
105
+ theme.heading("H O O X") +
106
+ " " +
107
+ theme.dim(TAGLINE) +
108
+ " " +
109
+ theme.dim(`v${VERSION}`);
110
+
111
+ return [
112
+ ` ${rule}`,
113
+ ` ${theme.dim("│")}${" ".repeat(bw - 2)}${theme.dim("│")}`,
114
+ `${theme.dim("│")}${titleLine}${" ".repeat(Math.max(0, bw - titleLine.length - 2))}${theme.dim("│")}`,
115
+ ` ${theme.dim("│")}${" ".repeat(bw - 2)}${theme.dim("│")}`,
116
+ ` ${rule}`,
42
117
  ].join("\n");
118
+ }
119
+
120
+ // ── Exports ───────────────────────────────────────────────────────
121
+
122
+ export const BANNER_VARIANTS = {
123
+ legacy: renderLegacy,
124
+ horizon: renderBannerHorizon,
125
+ signal: renderBannerSignal,
126
+ minimal: renderBannerMinimal,
127
+ } as const;
128
+
129
+ export type BannerVariant = keyof typeof BANNER_VARIANTS;
43
130
 
44
- return result;
131
+ /** Default banner — the legacy ASCII block style. */
132
+ export function renderBanner(variant?: BannerVariant): string {
133
+ return variant ? BANNER_VARIANTS[variant]() : renderLegacy();
45
134
  }
46
135
 
47
136
  /**
package/src/ui/menu.ts CHANGED
@@ -17,8 +17,9 @@ import {
17
17
  isCancel,
18
18
  cancel,
19
19
  } from "@clack/prompts";
20
- import { renderBanner } from "./banner.js";
20
+ import { renderBanner, renderCompactBanner, DISCLAIMER } from "./banner.js";
21
21
  import { CLIError } from "../utils/errors.js";
22
+ import { theme } from "../utils/theme.js";
22
23
 
23
24
  // ---------------------------------------------------------------------------
24
25
  // Main entry
@@ -46,6 +47,10 @@ export async function runInteractiveTUI(program: Command): Promise<void> {
46
47
  // "back" or "continue" → loop back to main menu
47
48
  }
48
49
 
50
+ // Legal footer
51
+ process.stdout.write(
52
+ theme.dim("─".repeat(50)) + "\n" + theme.muted(DISCLAIMER) + "\n"
53
+ );
49
54
  outro("See you later!");
50
55
  }
51
56
 
@@ -54,8 +59,12 @@ export async function runInteractiveTUI(program: Command): Promise<void> {
54
59
  // ---------------------------------------------------------------------------
55
60
 
56
61
  const MAIN_CATEGORIES = [
62
+ {
63
+ value: "init",
64
+ label: "⚡ Setup Wizard",
65
+ hint: "bootstrap or reconfigure project",
66
+ },
57
67
  { value: "deploy", label: "Deploy", hint: "workers, dashboard" },
58
- { value: "develop", label: "Develop", hint: "dev server, init project" },
59
68
  {
60
69
  value: "manage",
61
70
  label: "Manage",
@@ -67,6 +76,7 @@ const MAIN_CATEGORIES = [
67
76
  hint: "diagnostics, health, logs, tests",
68
77
  },
69
78
  { value: "tools", label: "Tools", hint: "WAF, clone worker, dashboard UI" },
79
+ { value: "develop", label: "Develop", hint: "dev server, start project" },
70
80
  { value: "__exit", label: "Exit" },
71
81
  ] as const;
72
82
 
@@ -96,6 +106,9 @@ async function handleCategory(
96
106
  program: Command
97
107
  ): Promise<"back" | "exit" | "continue"> {
98
108
  switch (category) {
109
+ case "init":
110
+ await runCommand(program, "init");
111
+ return "continue";
99
112
  case "deploy":
100
113
  return showDeployMenu(program);
101
114
  case "develop":
@@ -168,7 +181,6 @@ async function showDevelopMenu(
168
181
  label: "Start dev server",
169
182
  hint: "runs all workers locally",
170
183
  },
171
- { value: "init", label: "Init project", hint: "bootstrap new project" },
172
184
  { value: "__back", label: "◀ Back to main menu" },
173
185
  ],
174
186
  });