@mangomagic/cli 0.1.14 → 0.1.15

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/index.mjs +32 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mangomagic/cli",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "MangoMagic CLI — sign in, manage episodes, and expose MangoMagic to MCP clients (Claude Desktop, Cursor).",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.mjs CHANGED
@@ -175,15 +175,7 @@ async function enterChatAfterLogin(startChat) {
175
175
  await chat(actions(), { showHeader: false });
176
176
  }
177
177
 
178
- async function login({ openInBrowser = true, startChat = false } = {}) {
179
- if (loadToken()) {
180
- process.stdout.write(`${DIM}You're already signed in. Continuing in MangoMagic.${RESET}\n`);
181
- await playSplash({ mode: splashMode(), greetingLine: "Welcome back to MangoMagic." });
182
- if (!startChat) home();
183
- await enterChatAfterLogin(startChat);
184
- return;
185
- }
186
-
178
+ async function performDeviceLogin({ openInBrowser = true, startChat = false } = {}) {
187
179
  await deviceLogin({
188
180
  openInBrowser,
189
181
  onCode: (start) => {
@@ -206,6 +198,36 @@ ${BOLD}Sign in to MangoMagic${RESET}
206
198
  });
207
199
  }
208
200
 
201
+ async function validateCachedToken() {
202
+ try {
203
+ await runCatalogTool("get_user_stats", {});
204
+ return true;
205
+ } catch (err) {
206
+ const message = String(err?.message ?? err);
207
+ if (/token.*rejected|not signed in|not_authenticated|token_revoked|token_expired/i.test(message)) {
208
+ clearToken();
209
+ process.stdout.write(`${DIM}The saved terminal approval is no longer valid. Starting a fresh browser approval.${RESET}\n`);
210
+ return false;
211
+ }
212
+ process.stdout.write(`${DIM}Could not verify the saved terminal approval right now; continuing with the cached device token.${RESET}\n`);
213
+ return true;
214
+ }
215
+ }
216
+
217
+ async function login({ openInBrowser = true, startChat = false } = {}) {
218
+ if (loadToken()) {
219
+ process.stdout.write(`${DIM}This terminal is already approved for MangoMagic. Browser logout does not remove this device token.${RESET}\n`);
220
+ const stillValid = await validateCachedToken();
221
+ if (!stillValid) return performDeviceLogin({ openInBrowser, startChat });
222
+ await playSplash({ mode: splashMode(), greetingLine: "Welcome back to MangoMagic." });
223
+ if (!startChat) home();
224
+ await enterChatAfterLogin(startChat);
225
+ return;
226
+ }
227
+
228
+ return performDeviceLogin({ openInBrowser, startChat });
229
+ }
230
+
209
231
  async function enterChat() {
210
232
  await playSplash({ mode: splashMode(), greetingLine: "Welcome to MangoMagic." });
211
233
  await chat(actions());
@@ -213,7 +235,7 @@ async function enterChat() {
213
235
 
214
236
  function logout() {
215
237
  clearToken();
216
- process.stdout.write("Signed out.\n");
238
+ process.stdout.write("Signed out of this terminal. Your browser session is separate.\n");
217
239
  }
218
240
 
219
241
  function whoami() {