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

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.
@@ -134,3 +134,91 @@ export function detectSetupHints(opts = {}) {
134
134
  anvilDefaultAddress: ANVIL_DEFAULT_ADDRESS,
135
135
  };
136
136
  }
137
+
138
+ /**
139
+ * Pad string to width (truncate with … if longer).
140
+ * @param {string} s
141
+ * @param {number} width
142
+ */
143
+ function cell(s, width) {
144
+ const t = String(s ?? "");
145
+ if (t.length === width) return t;
146
+ if (t.length < width) return t + " ".repeat(width - t.length);
147
+ if (width <= 1) return "…";
148
+ return `${t.slice(0, width - 1)}…`;
149
+ }
150
+
151
+ /**
152
+ * Render detection hints as an aligned two-column table for the terminal.
153
+ * @param {ReturnType<typeof detectSetupHints>} hints
154
+ * @returns {string}
155
+ */
156
+ export function formatSetupDetectTable(hints) {
157
+ /** @type {[string, string][]} */
158
+ const rows = [];
159
+ rows.push(["Profile dir", hints.home]);
160
+
161
+ if (hints.hasConfig) {
162
+ rows.push(["config.json", `present · preset=${hints.config?.preset ?? "?"}`]);
163
+ rows.push([
164
+ "registry",
165
+ hints.config?.registryAddress ? String(hints.config.registryAddress) : "(none)",
166
+ ]);
167
+ } else {
168
+ rows.push(["config.json", "missing · will create"]);
169
+ }
170
+
171
+ if (hints.hasOperator) {
172
+ rows.push([
173
+ "operator.json",
174
+ `present · ${hints.operator?.label ?? "?"} · ${hints.operator?.owner ?? "?"}`,
175
+ ]);
176
+ } else {
177
+ rows.push(["operator.json", "missing · needed for whoami"]);
178
+ }
179
+
180
+ if (hints.foundryAvailable && hints.foundryAccounts.length) {
181
+ rows.push([
182
+ "Foundry accounts",
183
+ `${hints.foundryAccounts.length}: ${hints.foundryAccounts.join(", ")}`,
184
+ ]);
185
+ } else if (hints.foundryAvailable) {
186
+ rows.push(["Foundry accounts", "none listed"]);
187
+ } else {
188
+ rows.push(["Foundry cast", "not on PATH"]);
189
+ }
190
+
191
+ if (hints.openclawBots.length) {
192
+ rows.push([
193
+ "OpenClaw bot keys",
194
+ `${hints.openclawBots.length} files (bot signing only)`,
195
+ ]);
196
+ for (const b of hints.openclawBots) {
197
+ rows.push([" ·", b]);
198
+ }
199
+ } else {
200
+ rows.push(["OpenClaw bot keys", "none"]);
201
+ }
202
+
203
+ if (hints.hasOperatorPrivateKeyEnv) {
204
+ rows.push([
205
+ "OPERATOR_PRIVATE_KEY",
206
+ hints.envAddress ? `set · ${hints.envAddress}` : "set · (invalid)",
207
+ ]);
208
+ } else {
209
+ rows.push(["OPERATOR_PRIVATE_KEY", "unset"]);
210
+ }
211
+
212
+ const col0 = Math.min(
213
+ 22,
214
+ Math.max(4, ...rows.map(([k]) => k.length)),
215
+ );
216
+ const lines = [
217
+ `${cell("What", col0)} Value`,
218
+ `${"-".repeat(col0)} ${"-".repeat(48)}`,
219
+ ];
220
+ for (const [k, v] of rows) {
221
+ lines.push(`${cell(k, col0)} ${v}`);
222
+ }
223
+ return lines.join("\n");
224
+ }
package/lib/setup.mjs CHANGED
@@ -26,6 +26,7 @@ import {
26
26
  addressFromEnv,
27
27
  addressFromKeyFile,
28
28
  detectSetupHints,
29
+ formatSetupDetectTable,
29
30
  } from "./setup-detect.mjs";
30
31
 
31
32
  /**
@@ -294,43 +295,7 @@ export async function runSetupInteractive(argv, opts = {}) {
294
295
  console.log("");
295
296
  console.log(`Profile directory: ${home}`);
296
297
  console.log("");
297
-
298
- // Detection summary
299
- console.log("Detected on this machine:");
300
- if (hints.hasConfig) {
301
- const p = hints.config?.preset ?? "?";
302
- const reg = hints.config?.registryAddress ?? "(none)";
303
- console.log(` • Network config already at config.json (preset=${p}, registry=${reg})`);
304
- } else {
305
- console.log(" • No config.json yet — will create one");
306
- }
307
- if (hints.hasOperator) {
308
- console.log(
309
- ` • Operator profile already at operator.json (label=${hints.operator?.label}, owner=${hints.operator?.owner})`,
310
- );
311
- } else {
312
- console.log(" • No operator.json yet — that is what we need for bare `whoami`");
313
- }
314
- if (hints.foundryAvailable && hints.foundryAccounts.length) {
315
- console.log(
316
- ` • Foundry keystore accounts: ${hints.foundryAccounts.join(", ")} (names only; you paste the 0x address)`,
317
- );
318
- } else if (!hints.foundryAvailable) {
319
- console.log(" • Foundry `cast` not on PATH (optional)");
320
- }
321
- if (hints.openclawBots.length) {
322
- console.log(
323
- ` • OpenClaw bot key files: ${hints.openclawBots.join(", ")}`,
324
- );
325
- console.log(
326
- " (These are bot signing keys — not your operator wallet. Useful context only.)",
327
- );
328
- }
329
- if (hints.hasOperatorPrivateKeyEnv) {
330
- console.log(
331
- ` • OPERATOR_PRIVATE_KEY is set in this shell → ${hints.envAddress ?? "(invalid key)"}`,
332
- );
333
- }
298
+ console.log(formatSetupDetectTable(hints));
334
299
  console.log("");
335
300
 
336
301
  if ((hints.hasConfig || hints.hasOperator) && !flags.force) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clanker-chain/clanker-cli",
3
- "version": "2026.9.7-2",
3
+ "version": "2026.9.7-3",
4
4
  "description": "CLI for wiring clanker-chain identity and MQTT into OpenClaw and other agentic stacks.",
5
5
  "type": "module",
6
6
  "bin": {