openhome-cli 0.1.5 → 0.1.7

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/dist/cli.js CHANGED
@@ -276,6 +276,7 @@ function handleCancel(value) {
276
276
  // src/commands/login.ts
277
277
  import chalk2 from "chalk";
278
278
  var SETTINGS_URL = "https://app.openhome.com/dashboard/settings";
279
+ var OPENHOME_APP_URL = "https://app.openhome.com";
279
280
  function openBrowser(url) {
280
281
  try {
281
282
  if (process.platform === "darwin") {
@@ -290,14 +291,14 @@ function openBrowser(url) {
290
291
  }
291
292
  async function loginCommand() {
292
293
  p.intro("\u{1F511} OpenHome Login");
293
- const open = await p.confirm({
294
+ const openSettings = await p.confirm({
294
295
  message: `Press Enter to open your browser and navigate to the ${chalk2.bold("API Keys")} tab`,
295
296
  initialValue: true,
296
297
  active: "Open browser",
297
298
  inactive: "Skip"
298
299
  });
299
- handleCancel(open);
300
- if (open) {
300
+ handleCancel(openSettings);
301
+ if (openSettings) {
301
302
  openBrowser(SETTINGS_URL);
302
303
  console.log(
303
304
  `
@@ -336,7 +337,79 @@ async function loginCommand() {
336
337
  } else {
337
338
  info("No agents found. Create one at https://app.openhome.com");
338
339
  }
339
- p.outro("Logged in! You're ready to go.");
340
+ console.log("");
341
+ p.note(
342
+ [
343
+ "To manage your abilities (list, delete, enable/disable) from the CLI,",
344
+ "you need one more thing: a session token.",
345
+ "",
346
+ `This takes about ${chalk2.bold("30 seconds")} and you only do it once.`
347
+ ].join("\n"),
348
+ "One more step"
349
+ );
350
+ const doJwt = await p.confirm({
351
+ message: "Set up management access now?",
352
+ initialValue: true,
353
+ active: "Yes, do it now",
354
+ inactive: "Skip for now"
355
+ });
356
+ handleCancel(doJwt);
357
+ if (doJwt) {
358
+ await setupJwt();
359
+ } else {
360
+ p.outro(
361
+ `All set! Run ${chalk2.bold("openhome set-jwt")} anytime to enable management features.`
362
+ );
363
+ return;
364
+ }
365
+ p.outro("You're fully set up. Run openhome to get started.");
366
+ }
367
+ async function setupJwt() {
368
+ const { saveJwt: saveJwt2 } = await import("./store-USDMWKXY.js");
369
+ const openApp = await p.confirm({
370
+ message: `Press Enter to open ${chalk2.bold("app.openhome.com")} in your browser`,
371
+ initialValue: true,
372
+ active: "Open browser",
373
+ inactive: "Skip"
374
+ });
375
+ handleCancel(openApp);
376
+ if (openApp) {
377
+ openBrowser(OPENHOME_APP_URL);
378
+ console.log(
379
+ `
380
+ ${chalk2.dim(`Opened ${chalk2.bold("app.openhome.com")} \u2014 make sure you're logged in`)}
381
+ `
382
+ );
383
+ }
384
+ p.note(
385
+ [
386
+ `${chalk2.bold("1.")} Open the browser console:`,
387
+ ` Mac \u2192 press ${chalk2.cyan("Cmd + Option + J")}`,
388
+ ` Windows / Linux \u2192 press ${chalk2.cyan("F12")}, then click ${chalk2.cyan("Console")}`,
389
+ "",
390
+ `${chalk2.bold("2.")} Paste this command and press ${chalk2.bold("Enter")}:`,
391
+ "",
392
+ ` ${chalk2.green("copy(localStorage.getItem('token'))")}`,
393
+ "",
394
+ `${chalk2.bold("3.")} Your token is now copied to your clipboard.`,
395
+ ` Come back here and paste it below.`
396
+ ].join("\n"),
397
+ "How to get your session token"
398
+ );
399
+ const token = await p.password({
400
+ message: "Paste your session token here",
401
+ validate: (val) => {
402
+ if (!val || !val.trim()) return "Token is required";
403
+ if (val.trim().length < 20)
404
+ return "That doesn't look right \u2014 the token should be much longer";
405
+ }
406
+ });
407
+ if (typeof token === "symbol") {
408
+ p.cancel("Skipped.");
409
+ return;
410
+ }
411
+ saveJwt2(token.trim());
412
+ success("Session token saved. Management features are now unlocked.");
340
413
  }
341
414
 
342
415
  // src/commands/init.ts
@@ -3071,21 +3144,6 @@ async function logsCommand(opts = {}) {
3071
3144
  }
3072
3145
 
3073
3146
  // src/commands/set-jwt.ts
3074
- import { execFile as execFile2 } from "child_process";
3075
- import chalk13 from "chalk";
3076
- var OPENHOME_URL = "https://app.openhome.com";
3077
- function openBrowser2(url) {
3078
- try {
3079
- if (process.platform === "darwin") {
3080
- execFile2("open", [url]);
3081
- } else if (process.platform === "win32") {
3082
- execFile2("cmd", ["/c", "start", url]);
3083
- } else {
3084
- execFile2("xdg-open", [url]);
3085
- }
3086
- } catch {
3087
- }
3088
- }
3089
3147
  async function setJwtCommand(token) {
3090
3148
  if (token) {
3091
3149
  p.intro("\u{1F511} Enable Management Features");
@@ -3104,76 +3162,13 @@ async function setJwtCommand(token) {
3104
3162
  return;
3105
3163
  }
3106
3164
  p.intro("\u{1F511} Enable Management Features");
3107
- p.note(
3108
- [
3109
- "Some commands (list, delete, enable/disable abilities) need your",
3110
- "OpenHome session token to work.",
3111
- "",
3112
- "Think of it as a temporary key that proves you're logged in to",
3113
- "your account. You only need to do this once."
3114
- ].join("\n"),
3115
- "What's this?"
3116
- );
3117
- console.log("");
3118
- console.log(
3119
- chalk13.dim(` Opening ${chalk13.bold("app.openhome.com")} in your browser...`)
3120
- );
3121
- openBrowser2(OPENHOME_URL);
3122
- console.log("");
3123
- p.note(
3124
- [
3125
- `${chalk13.bold("Step 1")} Make sure you're logged in to app.openhome.com`,
3126
- "",
3127
- `${chalk13.bold("Step 2")} Open the browser console:`,
3128
- ` Mac \u2192 ${chalk13.cyan("Cmd + Option + J")}`,
3129
- ` Windows / Linux \u2192 ${chalk13.cyan("F12")}, then click the Console tab`,
3130
- "",
3131
- `${chalk13.bold("Step 3")} Paste this command into the console and press Enter:`,
3132
- "",
3133
- ` ${chalk13.green("copy(localStorage.getItem('token'))")}`,
3134
- "",
3135
- `${chalk13.bold("Step 4")} Your token is now in your clipboard.`,
3136
- ` Come back here and paste it below.`
3137
- ].join("\n"),
3138
- "How to get your token"
3139
- );
3140
- const input = await p.password({
3141
- message: "Paste your token here",
3142
- validate: (val) => {
3143
- if (!val || !val.trim()) return "Token is required";
3144
- if (val.trim().length < 20)
3145
- return "That doesn't look right \u2014 the token should be much longer";
3146
- }
3147
- });
3148
- if (typeof input === "symbol") {
3149
- p.cancel("Cancelled.");
3150
- return;
3151
- }
3152
- try {
3153
- saveJwt(input.trim());
3154
- success("Session token saved.");
3155
- p.note(
3156
- [
3157
- "These commands are now unlocked:",
3158
- ` ${chalk13.bold("openhome list")} \u2014 see all your deployed abilities`,
3159
- ` ${chalk13.bold("openhome delete")} \u2014 remove an ability`,
3160
- ` ${chalk13.bold("openhome toggle")} \u2014 enable or disable an ability`,
3161
- ` ${chalk13.bold("openhome assign")} \u2014 link abilities to an agent`
3162
- ].join("\n"),
3163
- "You're all set"
3164
- );
3165
- p.outro("Done!");
3166
- } catch (err) {
3167
- error(
3168
- `Failed to save token: ${err instanceof Error ? err.message : String(err)}`
3169
- );
3170
- process.exit(1);
3171
- }
3165
+ await setupJwt();
3166
+ p.outro("Done.");
3172
3167
  }
3173
3168
 
3174
3169
  // src/commands/validate.ts
3175
3170
  import { resolve as resolve5 } from "path";
3176
- import chalk14 from "chalk";
3171
+ import chalk13 from "chalk";
3177
3172
  async function validateCommand(pathArg = ".") {
3178
3173
  const targetDir = resolve5(pathArg);
3179
3174
  p.intro(`\u{1F50E} Validate ability`);
@@ -3189,7 +3184,7 @@ async function validateCommand(pathArg = ".") {
3189
3184
  if (result.errors.length > 0) {
3190
3185
  p.note(
3191
3186
  result.errors.map(
3192
- (issue) => `${chalk14.red("\u2717")} ${issue.file ? chalk14.bold(`[${issue.file}]`) + " " : ""}${issue.message}`
3187
+ (issue) => `${chalk13.red("\u2717")} ${issue.file ? chalk13.bold(`[${issue.file}]`) + " " : ""}${issue.message}`
3193
3188
  ).join("\n"),
3194
3189
  `${result.errors.length} Error(s)`
3195
3190
  );
@@ -3197,7 +3192,7 @@ async function validateCommand(pathArg = ".") {
3197
3192
  if (result.warnings.length > 0) {
3198
3193
  p.note(
3199
3194
  result.warnings.map(
3200
- (w) => `${chalk14.yellow("\u26A0")} ${w.file ? chalk14.bold(`[${w.file}]`) + " " : ""}${w.message}`
3195
+ (w) => `${chalk13.yellow("\u26A0")} ${w.file ? chalk13.bold(`[${w.file}]`) + " " : ""}${w.message}`
3201
3196
  ).join("\n"),
3202
3197
  `${result.warnings.length} Warning(s)`
3203
3198
  );
@@ -3221,6 +3216,39 @@ try {
3221
3216
  version = pkg.version ?? version;
3222
3217
  } catch {
3223
3218
  }
3219
+ async function checkForUpdates() {
3220
+ if (process.env.OPENHOME_NO_UPDATE === "1") return;
3221
+ try {
3222
+ const res = await fetch("https://registry.npmjs.org/openhome-cli/latest", {
3223
+ signal: AbortSignal.timeout(2e3)
3224
+ });
3225
+ const data = await res.json();
3226
+ const latest = data.version;
3227
+ if (!latest || latest === version) return;
3228
+ const toNum = (v) => v.split(".").map(Number).reduce((a, n) => a * 1e3 + n, 0);
3229
+ if (toNum(latest) <= toNum(version)) return;
3230
+ const arg1 = process.argv[1] ?? "";
3231
+ const isNpx = arg1.includes("_npx") || arg1.includes(".npm/") || (process.env.npm_execpath ?? "").includes("npx");
3232
+ if (isNpx) {
3233
+ const { execFileSync } = await import("child_process");
3234
+ execFileSync(
3235
+ "npx",
3236
+ [`openhome-cli@${latest}`, ...process.argv.slice(2)],
3237
+ { stdio: "inherit", env: { ...process.env, OPENHOME_NO_UPDATE: "1" } }
3238
+ );
3239
+ process.exit(0);
3240
+ } else {
3241
+ const { default: chalk14 } = await import("chalk");
3242
+ console.log(
3243
+ chalk14.yellow(
3244
+ ` Update available: v${version} \u2192 v${latest} Run: npm install -g openhome-cli@latest
3245
+ `
3246
+ )
3247
+ );
3248
+ }
3249
+ } catch {
3250
+ }
3251
+ }
3224
3252
  async function ensureLoggedIn() {
3225
3253
  const { getApiKey: getApiKey2 } = await import("./store-USDMWKXY.js");
3226
3254
  const key = getApiKey2();
@@ -3384,14 +3412,16 @@ program.command("set-jwt [token]").description(
3384
3412
  ).action(async (token) => {
3385
3413
  await setJwtCommand(token);
3386
3414
  });
3387
- if (process.argv.length <= 2) {
3388
- interactiveMenu().catch((err) => {
3389
- console.error(err instanceof Error ? err.message : String(err));
3390
- process.exit(1);
3391
- });
3392
- } else {
3393
- program.parseAsync(process.argv).catch((err) => {
3394
- console.error(err instanceof Error ? err.message : String(err));
3395
- process.exit(1);
3396
- });
3397
- }
3415
+ checkForUpdates().then(() => {
3416
+ if (process.argv.length <= 2) {
3417
+ interactiveMenu().catch((err) => {
3418
+ console.error(err instanceof Error ? err.message : String(err));
3419
+ process.exit(1);
3420
+ });
3421
+ } else {
3422
+ program.parseAsync(process.argv).catch((err) => {
3423
+ console.error(err instanceof Error ? err.message : String(err));
3424
+ process.exit(1);
3425
+ });
3426
+ }
3427
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openhome-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "CLI for managing OpenHome voice AI abilities",
5
5
  "type": "module",
6
6
  "bin": {
@@ -32,6 +32,9 @@
32
32
  "commander": "^12.1.0",
33
33
  "ws": "^8.19.0"
34
34
  },
35
+ "overrides": {
36
+ "glob": "^11.0.0"
37
+ },
35
38
  "devDependencies": {
36
39
  "@types/archiver": "^6.0.3",
37
40
  "@types/node": "^22.0.0",
package/src/cli.ts CHANGED
@@ -35,6 +35,57 @@ try {
35
35
  // fallback to default
36
36
  }
37
37
 
38
+ // ── Auto-update check ────────────────────────────────────────────
39
+ async function checkForUpdates(): Promise<void> {
40
+ // Skip if explicitly disabled or already running via auto-update re-exec
41
+ if (process.env.OPENHOME_NO_UPDATE === "1") return;
42
+
43
+ try {
44
+ const res = await fetch("https://registry.npmjs.org/openhome-cli/latest", {
45
+ signal: AbortSignal.timeout(2000),
46
+ });
47
+ const data = (await res.json()) as { version?: string };
48
+ const latest = data.version;
49
+ if (!latest || latest === version) return;
50
+
51
+ // Only act if npm version is strictly newer
52
+ const toNum = (v: string) =>
53
+ v
54
+ .split(".")
55
+ .map(Number)
56
+ .reduce((a, n) => a * 1000 + n, 0);
57
+ if (toNum(latest) <= toNum(version)) return;
58
+
59
+ // Detect npx: argv[1] contains _npx or npm_execpath points to npx
60
+ const arg1 = process.argv[1] ?? "";
61
+ const isNpx =
62
+ arg1.includes("_npx") ||
63
+ arg1.includes(".npm/") ||
64
+ (process.env.npm_execpath ?? "").includes("npx");
65
+
66
+ if (isNpx) {
67
+ // Re-exec with latest — user gets the new version transparently
68
+ const { execFileSync } = await import("node:child_process");
69
+ execFileSync(
70
+ "npx",
71
+ [`openhome-cli@${latest}`, ...process.argv.slice(2)],
72
+ { stdio: "inherit", env: { ...process.env, OPENHOME_NO_UPDATE: "1" } },
73
+ );
74
+ process.exit(0);
75
+ } else {
76
+ // Global install — show one-line notice, don't block
77
+ const { default: chalk } = await import("chalk");
78
+ console.log(
79
+ chalk.yellow(
80
+ ` Update available: v${version} → v${latest} Run: npm install -g openhome-cli@latest\n`,
81
+ ),
82
+ );
83
+ }
84
+ } catch {
85
+ // Network timeout or error — continue silently
86
+ }
87
+ }
88
+
38
89
  // ── Interactive menu (bare `openhome` with no args) ──────────────
39
90
 
40
91
  async function ensureLoggedIn(): Promise<void> {
@@ -304,14 +355,16 @@ program
304
355
 
305
356
  // ── Entry point: menu if no args, subcommand otherwise ───────────
306
357
 
307
- if (process.argv.length <= 2) {
308
- interactiveMenu().catch((err: unknown) => {
309
- console.error(err instanceof Error ? err.message : String(err));
310
- process.exit(1);
311
- });
312
- } else {
313
- program.parseAsync(process.argv).catch((err: unknown) => {
314
- console.error(err instanceof Error ? err.message : String(err));
315
- process.exit(1);
316
- });
317
- }
358
+ checkForUpdates().then(() => {
359
+ if (process.argv.length <= 2) {
360
+ interactiveMenu().catch((err: unknown) => {
361
+ console.error(err instanceof Error ? err.message : String(err));
362
+ process.exit(1);
363
+ });
364
+ } else {
365
+ program.parseAsync(process.argv).catch((err: unknown) => {
366
+ console.error(err instanceof Error ? err.message : String(err));
367
+ process.exit(1);
368
+ });
369
+ }
370
+ });
@@ -6,8 +6,9 @@ import { success, error, info, p, handleCancel } from "../ui/format.js";
6
6
  import chalk from "chalk";
7
7
 
8
8
  const SETTINGS_URL = "https://app.openhome.com/dashboard/settings";
9
+ const OPENHOME_APP_URL = "https://app.openhome.com";
9
10
 
10
- function openBrowser(url: string): void {
11
+ export function openBrowser(url: string): void {
11
12
  try {
12
13
  if (process.platform === "darwin") {
13
14
  execFile("open", [url]);
@@ -24,15 +25,16 @@ function openBrowser(url: string): void {
24
25
  export async function loginCommand(): Promise<void> {
25
26
  p.intro("🔑 OpenHome Login");
26
27
 
27
- const open = await p.confirm({
28
+ // Step 1: API key
29
+ const openSettings = await p.confirm({
28
30
  message: `Press Enter to open your browser and navigate to the ${chalk.bold("API Keys")} tab`,
29
31
  initialValue: true,
30
32
  active: "Open browser",
31
33
  inactive: "Skip",
32
34
  });
33
- handleCancel(open);
35
+ handleCancel(openSettings);
34
36
 
35
- if (open) {
37
+ if (openSettings) {
36
38
  openBrowser(SETTINGS_URL);
37
39
  console.log(
38
40
  `\n ${chalk.dim(`Opened ${chalk.bold("app.openhome.com/dashboard/settings")} — click the ${chalk.bold("API Keys")} tab`)}\n`,
@@ -81,5 +83,86 @@ export async function loginCommand(): Promise<void> {
81
83
  info("No agents found. Create one at https://app.openhome.com");
82
84
  }
83
85
 
84
- p.outro("Logged in! You're ready to go.");
86
+ // Step 2: Session token for management features
87
+ console.log("");
88
+ p.note(
89
+ [
90
+ "To manage your abilities (list, delete, enable/disable) from the CLI,",
91
+ "you need one more thing: a session token.",
92
+ "",
93
+ `This takes about ${chalk.bold("30 seconds")} and you only do it once.`,
94
+ ].join("\n"),
95
+ "One more step",
96
+ );
97
+
98
+ const doJwt = await p.confirm({
99
+ message: "Set up management access now?",
100
+ initialValue: true,
101
+ active: "Yes, do it now",
102
+ inactive: "Skip for now",
103
+ });
104
+ handleCancel(doJwt);
105
+
106
+ if (doJwt) {
107
+ await setupJwt();
108
+ } else {
109
+ p.outro(
110
+ `All set! Run ${chalk.bold("openhome set-jwt")} anytime to enable management features.`,
111
+ );
112
+ return;
113
+ }
114
+
115
+ p.outro("You're fully set up. Run openhome to get started.");
116
+ }
117
+
118
+ export async function setupJwt(): Promise<void> {
119
+ const { saveJwt } = await import("../config/store.js");
120
+
121
+ const openApp = await p.confirm({
122
+ message: `Press Enter to open ${chalk.bold("app.openhome.com")} in your browser`,
123
+ initialValue: true,
124
+ active: "Open browser",
125
+ inactive: "Skip",
126
+ });
127
+ handleCancel(openApp);
128
+
129
+ if (openApp) {
130
+ openBrowser(OPENHOME_APP_URL);
131
+ console.log(
132
+ `\n ${chalk.dim(`Opened ${chalk.bold("app.openhome.com")} — make sure you're logged in`)}\n`,
133
+ );
134
+ }
135
+
136
+ p.note(
137
+ [
138
+ `${chalk.bold("1.")} Open the browser console:`,
139
+ ` Mac → press ${chalk.cyan("Cmd + Option + J")}`,
140
+ ` Windows / Linux → press ${chalk.cyan("F12")}, then click ${chalk.cyan("Console")}`,
141
+ "",
142
+ `${chalk.bold("2.")} Paste this command and press ${chalk.bold("Enter")}:`,
143
+ "",
144
+ ` ${chalk.green("copy(localStorage.getItem('token'))")}`,
145
+ "",
146
+ `${chalk.bold("3.")} Your token is now copied to your clipboard.`,
147
+ ` Come back here and paste it below.`,
148
+ ].join("\n"),
149
+ "How to get your session token",
150
+ );
151
+
152
+ const token = await p.password({
153
+ message: "Paste your session token here",
154
+ validate: (val) => {
155
+ if (!val || !val.trim()) return "Token is required";
156
+ if (val.trim().length < 20)
157
+ return "That doesn't look right — the token should be much longer";
158
+ },
159
+ });
160
+
161
+ if (typeof token === "symbol") {
162
+ p.cancel("Skipped.");
163
+ return;
164
+ }
165
+
166
+ saveJwt((token as string).trim());
167
+ success("Session token saved. Management features are now unlocked.");
85
168
  }
@@ -1,23 +1,6 @@
1
- import { execFile } from "node:child_process";
1
+ import { setupJwt } from "./login.js";
2
2
  import { saveJwt } from "../config/store.js";
3
3
  import { success, error, p } from "../ui/format.js";
4
- import chalk from "chalk";
5
-
6
- const OPENHOME_URL = "https://app.openhome.com";
7
-
8
- function openBrowser(url: string): void {
9
- try {
10
- if (process.platform === "darwin") {
11
- execFile("open", [url]);
12
- } else if (process.platform === "win32") {
13
- execFile("cmd", ["/c", "start", url]);
14
- } else {
15
- execFile("xdg-open", [url]);
16
- }
17
- } catch {
18
- // best-effort — user can open manually
19
- }
20
- }
21
4
 
22
5
  export async function setJwtCommand(token?: string): Promise<void> {
23
6
  // Direct usage: openhome set-jwt eyJ...
@@ -38,77 +21,8 @@ export async function setJwtCommand(token?: string): Promise<void> {
38
21
  return;
39
22
  }
40
23
 
41
- // Guided interactive flow
24
+ // Guided flow — reuse the same walkthrough from login
42
25
  p.intro("🔑 Enable Management Features");
43
-
44
- p.note(
45
- [
46
- "Some commands (list, delete, enable/disable abilities) need your",
47
- "OpenHome session token to work.",
48
- "",
49
- "Think of it as a temporary key that proves you're logged in to",
50
- "your account. You only need to do this once.",
51
- ].join("\n"),
52
- "What's this?",
53
- );
54
-
55
- console.log("");
56
- console.log(
57
- chalk.dim(` Opening ${chalk.bold("app.openhome.com")} in your browser...`),
58
- );
59
- openBrowser(OPENHOME_URL);
60
- console.log("");
61
-
62
- p.note(
63
- [
64
- `${chalk.bold("Step 1")} Make sure you're logged in to app.openhome.com`,
65
- "",
66
- `${chalk.bold("Step 2")} Open the browser console:`,
67
- ` Mac → ${chalk.cyan("Cmd + Option + J")}`,
68
- ` Windows / Linux → ${chalk.cyan("F12")}, then click the Console tab`,
69
- "",
70
- `${chalk.bold("Step 3")} Paste this command into the console and press Enter:`,
71
- "",
72
- ` ${chalk.green("copy(localStorage.getItem('token'))")}`,
73
- "",
74
- `${chalk.bold("Step 4")} Your token is now in your clipboard.`,
75
- ` Come back here and paste it below.`,
76
- ].join("\n"),
77
- "How to get your token",
78
- );
79
-
80
- const input = await p.password({
81
- message: "Paste your token here",
82
- validate: (val) => {
83
- if (!val || !val.trim()) return "Token is required";
84
- if (val.trim().length < 20)
85
- return "That doesn't look right — the token should be much longer";
86
- },
87
- });
88
-
89
- if (typeof input === "symbol") {
90
- p.cancel("Cancelled.");
91
- return;
92
- }
93
-
94
- try {
95
- saveJwt((input as string).trim());
96
- success("Session token saved.");
97
- p.note(
98
- [
99
- "These commands are now unlocked:",
100
- ` ${chalk.bold("openhome list")} — see all your deployed abilities`,
101
- ` ${chalk.bold("openhome delete")} — remove an ability`,
102
- ` ${chalk.bold("openhome toggle")} — enable or disable an ability`,
103
- ` ${chalk.bold("openhome assign")} — link abilities to an agent`,
104
- ].join("\n"),
105
- "You're all set",
106
- );
107
- p.outro("Done!");
108
- } catch (err) {
109
- error(
110
- `Failed to save token: ${err instanceof Error ? err.message : String(err)}`,
111
- );
112
- process.exit(1);
113
- }
26
+ await setupJwt();
27
+ p.outro("Done.");
114
28
  }