@clanker-chain/clanker-cli 2026.9.7 → 2026.9.8-2

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/lib/ui.mjs ADDED
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Shared human-path CLI UX (color, plans, next hints, structured errors).
3
+ * Respects NO_COLOR / non-TTY via picocolors.
4
+ */
5
+
6
+ import pc from "picocolors";
7
+ import * as clack from "@clack/prompts";
8
+
9
+ export const c = {
10
+ dim: (s) => pc.dim(String(s)),
11
+ green: (s) => pc.green(String(s)),
12
+ yellow: (s) => pc.yellow(String(s)),
13
+ red: (s) => pc.red(String(s)),
14
+ bold: (s) => pc.bold(String(s)),
15
+ cyan: (s) => pc.cyan(String(s)),
16
+ };
17
+
18
+ /**
19
+ * @param {string[]} argv
20
+ * @param {{ stdinTTY?: boolean }} [opts]
21
+ */
22
+ export function isInteractive(argv = [], opts = {}) {
23
+ const tty = opts.stdinTTY ?? Boolean(process.stdin.isTTY);
24
+ if (!tty) return false;
25
+ if (argv.includes("--yes") || argv.includes("-y")) return false;
26
+ if (argv.includes("--json")) return false;
27
+ return true;
28
+ }
29
+
30
+ /**
31
+ * @param {string|string[]} lines
32
+ */
33
+ export function nextHint(lines) {
34
+ const list = Array.isArray(lines) ? lines : [lines];
35
+ console.log("");
36
+ console.log(c.bold("Next:"));
37
+ for (const line of list) {
38
+ console.log(` ${c.cyan(line)}`);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Cargo-style human error.
44
+ * @param {{ error: string, because?: string, try?: string[] }} opts
45
+ * @returns {string}
46
+ */
47
+ export function formatCliError(opts) {
48
+ const lines = [c.red(`error: ${opts.error}`)];
49
+ if (opts.because) {
50
+ lines.push(c.dim(`because: ${opts.because}`));
51
+ }
52
+ if (opts.try?.length) {
53
+ lines.push(c.yellow("try:"));
54
+ for (const t of opts.try) {
55
+ lines.push(` ${t}`);
56
+ }
57
+ }
58
+ return lines.join("\n");
59
+ }
60
+
61
+ /**
62
+ * Print a plan table (key/value rows).
63
+ * @param {[string, string][]} rows
64
+ * @param {string} [title]
65
+ */
66
+ export function printPlan(rows, title = "Plan") {
67
+ console.log("");
68
+ console.log(c.bold(title));
69
+ const w = Math.min(18, Math.max(4, ...rows.map(([k]) => k.length)));
70
+ for (const [k, v] of rows) {
71
+ const pad = k + " ".repeat(Math.max(0, w - k.length));
72
+ console.log(` ${c.dim(pad)} ${v}`);
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Confirm a mutating plan. Skips when not interactive.
78
+ * @param {string[]} argv
79
+ * @param {[string, string][]} rows
80
+ * @param {string} [message]
81
+ * @returns {Promise<boolean>}
82
+ */
83
+ export async function confirmPlan(argv, rows, message = "Proceed?") {
84
+ printPlan(rows);
85
+ if (!isInteractive(argv)) return true;
86
+ const ok = await clack.confirm({
87
+ message,
88
+ initialValue: true,
89
+ });
90
+ if (clack.isCancel(ok) || ok === false) {
91
+ clack.cancel("Aborted.");
92
+ return false;
93
+ }
94
+ return true;
95
+ }
96
+
97
+ /**
98
+ * Print structured error to stderr and exit.
99
+ * @param {{ error: string, because?: string, try?: string[], status?: number }} opts
100
+ */
101
+ export function exitCliError(opts) {
102
+ console.error(formatCliError(opts));
103
+ process.exit(opts.status ?? 1);
104
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clanker-chain/clanker-cli",
3
- "version": "2026.9.7",
3
+ "version": "2026.9.8-2",
4
4
  "description": "CLI for wiring clanker-chain identity and MQTT into OpenClaw and other agentic stacks.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,6 +23,8 @@
23
23
  "mint-bot:sepolia": "bash ./scripts/with-sepolia-env.sh mint-bot"
24
24
  },
25
25
  "dependencies": {
26
+ "@clack/prompts": "^1.8.0",
27
+ "picocolors": "^1.1.1",
26
28
  "viem": "^2.21.0"
27
29
  }
28
30
  }