mumpix 1.0.13 → 1.0.14

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/README.md CHANGED
@@ -385,7 +385,11 @@ By default, auth state is stored at `~/.config/mumpix/auth.json` (or `%APPDATA%/
385
385
 
386
386
  On `npm install mumpix`, the package runs an install-time auth prompt in interactive terminals:
387
387
 
388
- - Press **Enter**: browser opens for account auth and local signed license is stored.
389
- - Press any other key: install continues in `eventual` mode only.
388
+ - Interactive terminals: install automatically opens browser auth and saves local signed license on success.
389
+ - If browser auth is cancelled/fails, install continues in `eventual` mode only.
390
390
 
391
391
  Non-interactive installs (CI/containers) skip this prompt automatically and default to `eventual`.
392
+
393
+ Auth endpoint fallback:
394
+ - CLI tries `https://mumpixdb.com` first, then automatically retries `https://mumpixdb.com/benchmark` on 404.
395
+ - Override with `MUMPIX_AUTH_BASE_URL` if your auth API is hosted elsewhere.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mumpix",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "SQLite for AI — embedded, zero-config memory database for AI agents and LLM applications",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -65,12 +65,8 @@ async function run() {
65
65
  return;
66
66
  }
67
67
 
68
- console.log('\n[mumpix] authenticate to unlock your paid durability modes (strict/verified).');
69
- const answer = await ask('[mumpix] press Enter to continue, or press any other key to install free (eventual mode): ');
70
- if (answer.length > 0) {
71
- console.log('[mumpix] auth skipped. default mode is eventual.');
72
- return;
73
- }
68
+ console.log('\n[mumpix] attempting automatic account link (interactive install).');
69
+ console.log('[mumpix] if you close/cancel browser auth, install continues in eventual mode.');
74
70
 
75
71
  const state = await loginWithDeviceFlow({
76
72
  onPrompt: ({ userCode, verifyUrl, expiresInSec, intervalSec }) => {
package/src/core/auth.js CHANGED
@@ -56,7 +56,11 @@ function requestJson(method, targetUrl, body = null, headers = {}, timeoutMs = 1
56
56
  return;
57
57
  }
58
58
  const msg = json.error || json.message || `HTTP ${res.statusCode}`;
59
- reject(new Error(msg));
59
+ const err = new Error(msg);
60
+ err.statusCode = Number(res.statusCode || 0);
61
+ err.response = json;
62
+ err.url = targetUrl;
63
+ reject(err);
60
64
  });
61
65
  });
62
66
  req.on('error', reject);
@@ -66,6 +70,13 @@ function requestJson(method, targetUrl, body = null, headers = {}, timeoutMs = 1
66
70
  });
67
71
  }
68
72
 
73
+ function authBaseCandidates(inputBase) {
74
+ const raw = String(inputBase || process.env.MUMPIX_AUTH_BASE_URL || 'https://mumpixdb.com').replace(/\/+$/, '');
75
+ const out = [raw];
76
+ if (!raw.endsWith('/benchmark')) out.push(`${raw}/benchmark`);
77
+ return Array.from(new Set(out));
78
+ }
79
+
69
80
  function decodeLicenseClaims(licenseKey) {
70
81
  if (!licenseKey || typeof licenseKey !== 'string') return null;
71
82
  const [payloadB64] = licenseKey.split('.');
@@ -131,25 +142,48 @@ function upsertStoredLicense(licenseKey, account = {}) {
131
142
  }
132
143
 
133
144
  async function exchangeTokenForLicense(authToken, opts = {}) {
134
- const base = String(opts.baseUrl || process.env.MUMPIX_AUTH_BASE_URL || 'https://mumpixdb.com').replace(/\/+$/, '');
135
145
  const endpoint = String(opts.exchangePath || process.env.MUMPIX_AUTH_TOKEN_EXCHANGE_PATH || '/api/mumpix/auth/token/exchange');
136
- const body = await requestJson('POST', `${base}${endpoint}`, {}, {
137
- authorization: `Bearer ${authToken}`
138
- }, Number(opts.timeoutMs || process.env.MUMPIX_AUTH_TIMEOUT_MS || 10000));
139
- const licenseKey = body.licenseKey || body.license || null;
140
- if (!licenseKey) throw new Error('No license key returned from auth exchange');
141
- return upsertStoredLicense(licenseKey, body.account || {});
146
+ const timeoutMs = Number(opts.timeoutMs || process.env.MUMPIX_AUTH_TIMEOUT_MS || 10000);
147
+ let lastErr = null;
148
+ for (const base of authBaseCandidates(opts.baseUrl)) {
149
+ try {
150
+ const body = await requestJson('POST', `${base}${endpoint}`, {}, {
151
+ authorization: `Bearer ${authToken}`
152
+ }, timeoutMs);
153
+ const licenseKey = body.licenseKey || body.license || null;
154
+ if (!licenseKey) throw new Error('No license key returned from auth exchange');
155
+ return upsertStoredLicense(licenseKey, body.account || {});
156
+ } catch (err) {
157
+ lastErr = err;
158
+ if (Number(err && err.statusCode) === 404) continue;
159
+ throw err;
160
+ }
161
+ }
162
+ throw lastErr || new Error('Auth token exchange failed');
142
163
  }
143
164
 
144
165
  async function loginWithDeviceFlow(opts = {}) {
145
- const base = String(opts.baseUrl || process.env.MUMPIX_AUTH_BASE_URL || 'https://mumpixdb.com').replace(/\/+$/, '');
146
166
  const startPath = String(opts.startPath || process.env.MUMPIX_AUTH_DEVICE_START_PATH || '/api/mumpix/auth/device/start');
147
167
  const pollPath = String(opts.pollPath || process.env.MUMPIX_AUTH_DEVICE_POLL_PATH || '/api/mumpix/auth/device/poll');
148
168
  const timeoutMs = Number(opts.timeoutMs || process.env.MUMPIX_AUTH_TIMEOUT_MS || 10000);
149
169
 
150
- const start = await requestJson('POST', `${base}${startPath}`, {
151
- client: 'mumpix-cli'
152
- }, {}, timeoutMs);
170
+ let start = null;
171
+ let base = '';
172
+ let lastErr = null;
173
+ for (const candidate of authBaseCandidates(opts.baseUrl)) {
174
+ try {
175
+ start = await requestJson('POST', `${candidate}${startPath}`, {
176
+ client: 'mumpix-cli'
177
+ }, {}, timeoutMs);
178
+ base = candidate;
179
+ break;
180
+ } catch (err) {
181
+ lastErr = err;
182
+ if (Number(err && err.statusCode) === 404) continue;
183
+ throw err;
184
+ }
185
+ }
186
+ if (!start) throw lastErr || new Error('Device auth start failed');
153
187
 
154
188
  const deviceCode = start.deviceCode || start.device_code;
155
189
  const userCode = start.userCode || start.user_code;
@@ -196,4 +230,3 @@ module.exports = {
196
230
  loginWithDeviceFlow,
197
231
  decodeLicenseClaims,
198
232
  };
199
-