drops-mcp 0.2.0 → 0.2.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.
Files changed (2) hide show
  1. package/drop.mjs +17 -8
  2. package/package.json +1 -1
package/drop.mjs CHANGED
@@ -363,16 +363,23 @@ async function cmdDrop(file, opts) {
363
363
  if (!file) die("usage: drop <file> [-p password] [-s slug] [--page] [--no-lock]");
364
364
  if (!existsSync(file)) die(`no such file: ${file}`);
365
365
 
366
- // Tier selection: explicit --managed wins; then self-host if a Blob token is set
367
- // (you brought your own infra); then hosted if you're logged in; else nudge.
368
- const token = opts.managed ? null : getToken();
369
- const apiKey = getApiKey();
370
- const mode = opts.managed ? "managed" : token ? "selfhost" : apiKey ? "hosted" : null;
371
- if (!mode) die("not set up yet.\n Free hosted: drop login\n Self-host: drop setup (needs a Vercel Blob token)\n One-off 24h: drop <file> --managed");
372
-
373
366
  const ext = extname(file).toLowerCase();
374
367
  const isMd = ext === ".md" || ext === ".markdown";
375
368
  const isHtml = ext === ".html" || ext === ".htm" || isMd;
369
+
370
+ // Tier selection: --managed wins. When you're logged in, single HTML/Markdown drops
371
+ // go to your hosted account (the PRD default for logged-in users); zip sites & arbitrary
372
+ // files need a Blob, so they fall through to self-host. A Blob token alone (not logged
373
+ // in) = self-host. Nothing configured → nudge.
374
+ const token = opts.managed ? null : getToken();
375
+ const apiKey = getApiKey();
376
+ const hostedEligible = isHtml && !opts.page && ext !== ".zip";
377
+ const mode = opts.managed ? "managed"
378
+ : (apiKey && hostedEligible) ? "hosted"
379
+ : token ? "selfhost"
380
+ : apiKey ? "hosted"
381
+ : null;
382
+ if (!mode) die("not set up yet.\n Free hosted: drop login\n Self-host: drop setup (needs a Vercel Blob token)\n One-off 24h: drop <file> --managed");
376
383
  const logoUri = await dataUri(join(BRAND, "logo-white.png"));
377
384
  const faviconUri = await dataUri(join(BRAND, "favicon.png"));
378
385
  const ogImage = `${ORIGIN}/_brand/og.png`; // optional; harmless if absent
@@ -808,7 +815,9 @@ async function saveApiKey(key) {
808
815
  }
809
816
  function openBrowser(url) {
810
817
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
811
- try { spawnSync(cmd, [url], { stdio: "ignore", shell: process.platform === "win32" }); } catch {}
818
+ // Detached + non-blocking: spawnSync would HANG the login (and its poll loop) if the
819
+ // opener doesn't return promptly — e.g. on headless machines where xdg-open stalls.
820
+ try { const c = spawn(cmd, [url], { stdio: "ignore", shell: process.platform === "win32", detached: true }); c.unref(); } catch {}
812
821
  }
813
822
  async function cmdLogin(opts) {
814
823
  if (opts.token && opts.token.startsWith("drop_")) { await saveApiKey(opts.token); ok("API key saved"); return cmdWhoami(); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drops-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Open-source artifact sharing — publish HTML/Markdown/files as branded, password-protected, zero-knowledge links on your own domain, from any AI agent. CLI + MCP server. The open-source, self-hosted Stacktree alternative.",
5
5
  "type": "module",
6
6
  "bin": {