mumpix 1.0.12 → 1.0.13

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
@@ -299,6 +299,7 @@ npm run release:publish-and-deprecate -- --otp=123456
299
299
  # --skip-verify skip verify:claims
300
300
  # --skip-publish only deprecate older versions
301
301
  # --dry-run no writes to npm
302
+ # --remove-old try to unpublish old versions; deprecate on failure
302
303
  ```
303
304
 
304
305
  ---
@@ -376,6 +377,8 @@ mumpix auth login --license=<signed-license> # direct import
376
377
  mumpix auth logout
377
378
  ```
378
379
 
380
+ For `--token` exchange, your backend should expose `/api/mumpix/auth/token/exchange` and map account tokens server-side (for example via `MUMPIX_AUTH_TOKEN_MAP`), not raw user IDs.
381
+
379
382
  By default, auth state is stored at `~/.config/mumpix/auth.json` (or `%APPDATA%/mumpix/auth.json` on Windows).
380
383
 
381
384
  ### Install-time auth flow
@@ -383,6 +386,6 @@ By default, auth state is stored at `~/.config/mumpix/auth.json` (or `%APPDATA%/
383
386
  On `npm install mumpix`, the package runs an install-time auth prompt in interactive terminals:
384
387
 
385
388
  - Press **Enter**: browser opens for account auth and local signed license is stored.
386
- - Type **skip**: install continues in `eventual` mode only.
389
+ - Press any other key: install continues in `eventual` mode only.
387
390
 
388
391
  Non-interactive installs (CI/containers) skip this prompt automatically and default to `eventual`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mumpix",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
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": {
@@ -39,6 +39,7 @@
39
39
  "files": [
40
40
  "src/",
41
41
  "bin/",
42
+ "scripts/postinstall-auth.js",
42
43
  "examples/",
43
44
  "CHANGELOG.md",
44
45
  "README.md",
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const readline = require('readline');
5
+ const { spawn } = require('child_process');
6
+ const {
7
+ loginWithDeviceFlow,
8
+ exchangeTokenForLicense,
9
+ authStatePath,
10
+ } = require('../src/core/auth');
11
+
12
+ function isInteractive() {
13
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY && process.env.CI !== 'true');
14
+ }
15
+
16
+ function fmtExpiry(ts) {
17
+ if (!ts) return '-';
18
+ const d = new Date(Number(ts));
19
+ if (Number.isNaN(d.getTime())) return '-';
20
+ return d.toISOString();
21
+ }
22
+
23
+ function openBrowser(url) {
24
+ if (!url) return false;
25
+ try {
26
+ if (process.platform === 'darwin') {
27
+ spawn('open', [url], { stdio: 'ignore', detached: true }).unref();
28
+ return true;
29
+ }
30
+ if (process.platform === 'win32') {
31
+ spawn('cmd', ['/c', 'start', '', url], { stdio: 'ignore', detached: true }).unref();
32
+ return true;
33
+ }
34
+ spawn('xdg-open', [url], { stdio: 'ignore', detached: true }).unref();
35
+ return true;
36
+ } catch {
37
+ return false;
38
+ }
39
+ }
40
+
41
+ function ask(question) {
42
+ return new Promise((resolve) => {
43
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
44
+ rl.question(question, (answer) => {
45
+ rl.close();
46
+ resolve(String(answer || '').trim());
47
+ });
48
+ });
49
+ }
50
+
51
+ async function run() {
52
+ try {
53
+ if (String(process.env.MUMPIX_POSTINSTALL_AUTH || '1') === '0') return;
54
+
55
+ const token = String(process.env.MUMPIX_AUTH_TOKEN || '').trim();
56
+ if (token) {
57
+ const state = await exchangeTokenForLicense(token, {});
58
+ console.log(`[mumpix] account linked via token. tier=${state.license.tier || '-'} exp=${fmtExpiry(state.license.exp)}`);
59
+ return;
60
+ }
61
+
62
+ if (!isInteractive()) {
63
+ console.log('[mumpix] install complete. auth skipped (non-interactive).');
64
+ console.log('[mumpix] run "mumpix auth login" later to unlock strict/verified. default mode remains eventual.');
65
+ return;
66
+ }
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
+ }
74
+
75
+ const state = await loginWithDeviceFlow({
76
+ onPrompt: ({ userCode, verifyUrl, expiresInSec, intervalSec }) => {
77
+ const opened = openBrowser(verifyUrl);
78
+ if (opened) {
79
+ console.log(`[mumpix] opened browser: ${verifyUrl}`);
80
+ } else {
81
+ console.log(`[mumpix] open this URL in your browser: ${verifyUrl}`);
82
+ }
83
+ console.log(`[mumpix] enter code: ${userCode}`);
84
+ console.log(`[mumpix] waiting for approval (expires in ${expiresInSec}s, polling ${intervalSec}s)...`);
85
+ }
86
+ });
87
+
88
+ console.log(`[mumpix] auth success. tier=${state.license.tier || state.account.tier || '-'} exp=${fmtExpiry(state.license.exp)}`);
89
+ console.log(`[mumpix] saved auth: ${authStatePath()}`);
90
+ } catch (err) {
91
+ const msg = err && err.message ? err.message : 'unknown error';
92
+ console.log(`[mumpix] auth step failed (${msg}).`);
93
+ if (String(msg).includes('404')) {
94
+ console.log('[mumpix] auth endpoints not found on this host. check MUMPIX_AUTH_BASE_URL or server auth routes.');
95
+ }
96
+ console.log('[mumpix] continuing install in eventual mode. run "mumpix auth login" later.');
97
+ }
98
+ }
99
+
100
+ run();