mumpix 1.0.6 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,66 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.11 - 2026-03-03
4
+
5
+ ## 1.0.12 - 2026-03-03
6
+
7
+ ### Fixes
8
+ - Fixed CLI database opening bug: `mumpix` commands now correctly `await Mumpix.open(...)` before operations, resolving `db.close is not a function`.
9
+
10
+ ### Verification
11
+ - Added executable truth-audit script: `npm run verify:claims`.
12
+ - Script validates core API, WAL replay, verified audit methods, integrations, CLI basic commands, SDK error surface, and license policy defaults.
13
+
14
+ ### Documentation
15
+ - Updated README examples to use `await Mumpix.open(...)`.
16
+ - Clarified that `strict`/`verified` are tier-gated capabilities (SDK and CLI).
17
+ - Added `verify:claims` usage to the examples section.
18
+
19
+ ## Unreleased
20
+
21
+ ### Licensing (offline/air-gapped)
22
+ - Added monthly tier capability mapping for paid durability modes (`eventual`, `strict`) while active.
23
+ - Set monthly offline lease default to 45 days (`MUMPIX_LICENSE_MAX_DAYS_MONTHLY=45` by default).
24
+ - Set enterprise/government/compliance lease defaults to long-window values (100 years default, env configurable).
25
+ - Enforced expiry downgrade policy: expired paid licenses continue in `eventual` mode; paid modes require renewal.
26
+ - Added `examples/license-expiry-downgrade-check.js` to verify downgrade behavior locally.
27
+
28
+ ### Authentication
29
+ - Added local account auth state support in `src/core/auth.js`.
30
+ - Added CLI auth commands: `mumpix auth login|status|logout`.
31
+ - Added automatic local-license loading in `MumpixDB.open()` when `licenseKey` is not passed explicitly.
32
+ - Added install-time auth script (`postinstall`) that prompts for account sign-in in interactive terminals.
33
+ - Added browser-open device flow on install; skip path remains `eventual` only.
34
+
35
+ ## 1.0.9 - 2026-03-02
36
+
37
+ ### Developer experience
38
+ - Added `MumpixDevClient` HTTP SDK for developers building on Mumpix services.
39
+ - Added `MumpixApiError` with structured `.status` and `.data` for reliable client-side error handling.
40
+ - Added API helpers for memory ops, explorer file ops, settings, ROM/manual endpoints, and export URL generation.
41
+ - Added `examples/developer-sdk.js` quick-start integration script.
42
+ - Updated README with a dedicated Developer SDK usage section and method reference.
43
+
44
+ ## 1.0.8 - 2026-02-27
45
+
46
+ ### Crash safety + integrity recovery hardening
47
+ - Added durable WAL writes (`fdatasync`) before main-file append to ensure recovery intent survives crashes.
48
+ - Added process lock file (`.lock`) to prevent concurrent writers from corrupting the same database file.
49
+ - Added strict-mode recovery path for tail corruption when WAL exists:
50
+ - truncates corrupted tail to last verified-good record set,
51
+ - replays WAL,
52
+ - continues open instead of hard-failing.
53
+ - Kept strict behavior secure when no WAL evidence exists (tamper/noise still fails fast).
54
+
55
+ ## 1.0.7 - 2026-02-27
56
+
57
+ ### Documentation
58
+ - Updated licensing and tier model in README to capability-based gating:
59
+ - Community: `eventual`
60
+ - Developer/Teams: `eventual`, `strict`
61
+ - Compliance: `eventual`, `strict`, `verified`
62
+ - Removed outdated mention of a 100-record free-tier cap from package docs.
63
+
3
64
  ## 1.0.6 - 2026-02-27
4
65
 
5
66
  ### Security hardening
@@ -19,4 +80,3 @@
19
80
 
20
81
  ### Reliability
21
82
  - Hardened strict-mode behavior to fail fast on malformed or tampered WAL/record entries.
22
-
package/README.md CHANGED
@@ -27,7 +27,7 @@ If you've ever watched an agent "forget" what it just learned, or had to explain
27
27
  const { Mumpix } = require('mumpix')
28
28
 
29
29
  // Open (or create) a local database
30
- const db = Mumpix.open('./agent.mumpix', { consistency: 'strict' })
30
+ const db = await Mumpix.open('./agent.mumpix', { consistency: 'eventual' })
31
31
 
32
32
  // Store memories
33
33
  await db.remember('User prefers TypeScript over JavaScript')
@@ -45,7 +45,47 @@ await db.close()
45
45
 
46
46
  ## API
47
47
 
48
- ### `Mumpix.open(filePath, [opts])` → `MumpixDB`
48
+ ### Developer SDK (HTTP Client)
49
+
50
+ For developers integrating Mumpix-backed services (local runner, benchmark APIs, hosted tools):
51
+
52
+ ```js
53
+ const { MumpixDevClient } = require('mumpix')
54
+
55
+ const client = new MumpixDevClient({
56
+ baseUrl: 'https://mumpixdb.com/benchmark'
57
+ })
58
+
59
+ const health = await client.health()
60
+ await client.remember('user likes concise answers')
61
+ const hit = await client.recall('what does the user like?')
62
+ const stats = await client.stats()
63
+ ```
64
+
65
+ ### `MumpixDevClient` methods
66
+
67
+ - `health()`
68
+ - `remember(content)`
69
+ - `recall(query)`
70
+ - `recallMany(query, k)`
71
+ - `memories()`
72
+ - `clear()`
73
+ - `stats()`
74
+ - `settings()`
75
+ - `updateSettings(patch)`
76
+ - `files()`
77
+ - `readFile(file, { atTs, source })`
78
+ - `timeline(file, { source })`
79
+ - `exportUrl(file, format, { atTs, source })`
80
+ - `roms()`
81
+ - `manualForRom(file)`
82
+ - `manualViewUrl(file, { isolate, v })`
83
+
84
+ Errors are thrown as `MumpixApiError` with `.status` and `.data` fields.
85
+
86
+ ---
87
+
88
+ ### `Mumpix.open(filePath, [opts])` → `Promise<MumpixDB>`
49
89
 
50
90
  Opens (or creates) a Mumpix database.
51
91
 
@@ -54,6 +94,8 @@ Opens (or creates) a Mumpix database.
54
94
  | `consistency` | `string` | `'eventual'` | `'eventual'` / `'strict'` / `'verified'` |
55
95
  | `embedFn` | `async fn(texts[]) → number[][]` | — | Custom embedding function (OpenAI, Cohere, etc.) |
56
96
 
97
+ Note: `strict` and `verified` are tier-gated capabilities. Without an active paid license, paid mode requests are blocked or downgraded to `eventual` based on license state.
98
+
57
99
  ### Consistency modes
58
100
 
59
101
  | Mode | Write behaviour | Audit log | Use case |
@@ -105,7 +147,7 @@ await db.close()
105
147
  ### Verified-mode methods
106
148
 
107
149
  ```js
108
- const db = Mumpix.open('./compliance.mumpix', { consistency: 'verified' })
150
+ const db = await Mumpix.open('./compliance.mumpix', { consistency: 'verified' })
109
151
 
110
152
  // Full audit log
111
153
  await db.audit()
@@ -145,7 +187,7 @@ async function embedFn(texts) {
145
187
  return res.data.map(d => d.embedding)
146
188
  }
147
189
 
148
- const db = Mumpix.open('./agent.mumpix', { consistency: 'strict', embedFn })
190
+ const db = await Mumpix.open('./agent.mumpix', { consistency: 'strict', embedFn })
149
191
  // db.recall() and db.recallMany() now use OpenAI embeddings automatically
150
192
  ```
151
193
 
@@ -157,7 +199,7 @@ const db = Mumpix.open('./agent.mumpix', { consistency: 'strict', embedFn })
157
199
  const { Mumpix } = require('mumpix')
158
200
  const { MumpixVectorStore, MumpixChatMemory, MumpixRetriever } = require('mumpix/src/integrations/langchain')
159
201
 
160
- const db = Mumpix.open('./agent.mumpix', { consistency: 'strict' })
202
+ const db = await Mumpix.open('./agent.mumpix', { consistency: 'strict' })
161
203
 
162
204
  // As a VectorStore
163
205
  const store = new MumpixVectorStore(db)
@@ -178,7 +220,7 @@ const results = await retriever.getRelevantDocuments('query')
178
220
  const { Mumpix } = require('mumpix')
179
221
  const { MumpixIndex, MumpixReader } = require('mumpix/src/integrations/llamaindex')
180
222
 
181
- const db = Mumpix.open('./agent.mumpix', { consistency: 'strict' })
223
+ const db = await Mumpix.open('./agent.mumpix', { consistency: 'strict' })
182
224
 
183
225
  const index = new MumpixIndex(db)
184
226
  const retriever = index.asRetriever({ topK: 5 })
@@ -213,6 +255,8 @@ mumpix recall ./agent.mumpix "query" --consistency=strict
213
255
  mumpix shell ./compliance.mumpix --consistency=verified
214
256
  ```
215
257
 
258
+ Note: CLI strict/verified modes are tier-gated the same as SDK/API mode selection.
259
+
216
260
  ---
217
261
 
218
262
  ## File format
@@ -221,8 +265,8 @@ The `.mumpix` file is plain NDJSON — human-readable, portable, no binary parse
221
265
 
222
266
  ```
223
267
  {"v":1,"consistency":"strict","created":1740000000000,"path":"agent.mumpix"}
224
- {"id":1,"content":"User prefers TypeScript","ts":1740000001000,"h":"0x4a2b1c3d"}
225
- {"id":2,"content":"Use pnpm workspaces","ts":1740000002000,"h":"0x9f8e7d6c"}
268
+ {"id":1,"content":"User prefers TypeScript","ts":1740000001000,"h":"hmac256:..."}
269
+ {"id":2,"content":"Use pnpm workspaces","ts":1740000002000,"h":"hmac256:..."}
226
270
  ```
227
271
 
228
272
  **Crash safety**: Mumpix uses a WAL (`.mumpix.wal`). On write:
@@ -242,6 +286,20 @@ On open, any leftover WAL is replayed before accepting new writes. A record is e
242
286
  node examples/basic.js # Zero-config 5-line demo
243
287
  node examples/agent-memory.js # Persistent agent preferences (run twice)
244
288
  node examples/verified-mode.js # Compliance audit log export
289
+ npm run verify:claims # executable truth-audit for package claims
290
+ ```
291
+
292
+ ### Release maintenance
293
+
294
+ ```bash
295
+ # Publish current version and deprecate all older npm versions
296
+ npm run release:publish-and-deprecate -- --otp=123456
297
+
298
+ # Optional flags:
299
+ # --skip-verify skip verify:claims
300
+ # --skip-publish only deprecate older versions
301
+ # --dry-run no writes to npm
302
+ # --remove-old try to unpublish old versions; deprecate on failure
245
303
  ```
246
304
 
247
305
  ---
@@ -262,14 +320,35 @@ Copyright © 2026 Mumpix (vdsx.cloud). All Rights Reserved.
262
320
 
263
321
  ## Licensing & Tiers
264
322
 
265
- Mumpix requires a license key for commercial use and advanced features.
323
+ Mumpix uses capability-based tiering: community is for building, paid tiers are for production operation and compliance.
266
324
 
267
- | Feature | Free | Pro ($79/mo) | Enterprise ($5K) |
268
- |---|---|---|---|
269
- | Max Records | 100 | Unlimited | Unlimited |
270
- | `strict` mode | ✅ | ✅ | ✅ |
271
- | `verified` mode | ❌ | | ✅ |
272
- | Offline Use | | | |
325
+ | Capability | Community (Free) | Developer ($19/mo) | Teams ($79/mo) | Compliance ($5K/mo) |
326
+ |---|---|---|---|---|
327
+ | `eventual` mode | | | | ✅ |
328
+ | `strict` mode | ❌ | ✅ | ✅ | ✅ |
329
+ | `verified` mode | ❌ | | ❌ | ✅ |
330
+ | Record writes | Unlimited | Unlimited | Unlimited | Unlimited |
331
+ | Offline use | ✅ | ✅ | ✅ | ✅ |
332
+
333
+ ### Tier intent
334
+
335
+ - **Community**: build and prototype with full local development flow.
336
+ - **Developer**: unlock production durability via `strict`.
337
+ - **Teams**: same core durability plus team/commercial operations.
338
+ - **Compliance**: regulated workflows with `verified` audit capabilities.
339
+
340
+ ### Offline/Air-gapped expiry policy
341
+
342
+ - Monthly licenses use a **45-day offline lease window** by default.
343
+ - Enterprise/government/compliance licenses support long/custom lease windows (for example 5-year, 10-year, or custom).
344
+ - When a paid license is expired, requested paid modes are automatically downgraded to `eventual` until renewal.
345
+
346
+ You can tune lease windows with environment variables:
347
+
348
+ - `MUMPIX_LICENSE_MAX_DAYS_MONTHLY` (default `45`)
349
+ - `MUMPIX_LICENSE_MAX_DAYS_ENTERPRISE` (default `36500`)
350
+ - `MUMPIX_LICENSE_MAX_DAYS_GOVERNMENT` (default `36500`)
351
+ - `MUMPIX_LICENSE_MAX_DAYS_COMPLIANCE` (default `36500`)
273
352
 
274
353
  ### Using a License Key
275
354
 
@@ -280,3 +359,33 @@ const db = await Mumpix.open('./agent.mumpix', {
280
359
  ```
281
360
 
282
361
  Get your key at [mumpixdb.com](https://mumpixdb.com).
362
+
363
+ ### No-Key account login (recommended)
364
+
365
+ You can link your paid account once and let Mumpix load the local signed license automatically:
366
+
367
+ ```bash
368
+ mumpix auth login # device flow (browser-based)
369
+ mumpix auth status
370
+ ```
371
+
372
+ Advanced login options:
373
+
374
+ ```bash
375
+ mumpix auth login --token=<account-token> # backend token exchange
376
+ mumpix auth login --license=<signed-license> # direct import
377
+ mumpix auth logout
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
+
382
+ By default, auth state is stored at `~/.config/mumpix/auth.json` (or `%APPDATA%/mumpix/auth.json` on Windows).
383
+
384
+ ### Install-time auth flow
385
+
386
+ On `npm install mumpix`, the package runs an install-time auth prompt in interactive terminals:
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.
390
+
391
+ Non-interactive installs (CI/containers) skip this prompt automatically and default to `eventual`.
package/bin/mumpix.js CHANGED
@@ -17,6 +17,15 @@
17
17
  const path = require('path');
18
18
  const readline = require('readline');
19
19
  const { Mumpix } = require('../src/index');
20
+ const {
21
+ loadAuthState,
22
+ clearAuthState,
23
+ upsertStoredLicense,
24
+ exchangeTokenForLicense,
25
+ loginWithDeviceFlow,
26
+ authStatePath,
27
+ configDir,
28
+ } = require('../src/core/auth');
20
29
 
21
30
  const USAGE = `
22
31
  mumpix — SQLite for AI
@@ -33,6 +42,7 @@ Commands:
33
42
  stats <file> Show database stats
34
43
  audit <file> Show audit log (verified mode)
35
44
  shell <file> Start interactive REPL
45
+ auth <subcommand> Account login/logout/status
36
46
  help Show this message
37
47
 
38
48
  Options (append to any command):
@@ -43,6 +53,9 @@ Examples:
43
53
  mumpix recall ./agent.mumpix "what language?" --consistency=strict
44
54
  mumpix search ./agent.mumpix "TypeScript" 3
45
55
  mumpix shell ./agent.mumpix --consistency=verified
56
+ mumpix auth status
57
+ mumpix auth login --token=<account-token>
58
+ mumpix auth login --license=<signed-license-key>
46
59
  `.trim();
47
60
 
48
61
  function parseArgs(argv) {
@@ -77,15 +90,103 @@ const yellow = t => colorize(t, '33');
77
90
  const red = t => colorize(t, '31');
78
91
  const bold = t => colorize(t, '1');
79
92
 
93
+ function fmtExpiry(ts) {
94
+ if (!ts) return '-';
95
+ const d = new Date(Number(ts));
96
+ if (Number.isNaN(d.getTime())) return '-';
97
+ return d.toISOString();
98
+ }
99
+
100
+ function mask(value, keep = 6) {
101
+ const s = String(value || '');
102
+ if (s.length <= keep) return s;
103
+ return `${s.slice(0, keep)}…`;
104
+ }
105
+
106
+ async function runAuth(parts, flags) {
107
+ const sub = String(parts[0] || 'status').toLowerCase();
108
+
109
+ if (sub === 'status') {
110
+ const s = loadAuthState();
111
+ if (!s || !s.license || !s.license.key) {
112
+ console.log(dim('Not logged in.'));
113
+ console.log(dim(`Config dir: ${configDir()}`));
114
+ return;
115
+ }
116
+ console.log(bold('Mumpix auth status'));
117
+ console.log(` account_id: ${s.account && s.account.id ? s.account.id : '-'}`);
118
+ console.log(` tier: ${s.license.tier || (s.account && s.account.tier) || '-'}`);
119
+ console.log(` issued_at: ${fmtExpiry(s.license.iat)}`);
120
+ console.log(` expires_at: ${fmtExpiry(s.license.exp)}`);
121
+ console.log(` license: ${green(mask(s.license.key, 18))}`);
122
+ console.log(` state: ${authStatePath()}`);
123
+ return;
124
+ }
125
+
126
+ if (sub === 'logout') {
127
+ clearAuthState();
128
+ console.log(green('✓') + ' Logged out. Local license removed.');
129
+ return;
130
+ }
131
+
132
+ if (sub === 'login') {
133
+ const directLicense = flags.license || flags['license-key'] || null;
134
+ if (directLicense) {
135
+ const state = upsertStoredLicense(String(directLicense));
136
+ console.log(green('✓') + ' License saved.');
137
+ console.log(` tier: ${state.license.tier || '-'}`);
138
+ console.log(` expires_at: ${fmtExpiry(state.license.exp)}`);
139
+ console.log(` state: ${authStatePath()}`);
140
+ return;
141
+ }
142
+
143
+ const token = flags.token || process.env.MUMPIX_AUTH_TOKEN || '';
144
+ if (token) {
145
+ const state = await exchangeTokenForLicense(String(token).trim(), {});
146
+ console.log(green('✓') + ' Account linked and license saved.');
147
+ console.log(` account_id: ${state.account.id || '-'}`);
148
+ console.log(` tier: ${state.license.tier || state.account.tier || '-'}`);
149
+ console.log(` expires_at: ${fmtExpiry(state.license.exp)}`);
150
+ console.log(` state: ${authStatePath()}`);
151
+ return;
152
+ }
153
+
154
+ const state = await loginWithDeviceFlow({
155
+ onPrompt: ({ userCode, verifyUrl, expiresInSec, intervalSec }) => {
156
+ console.log(bold('Mumpix device login'));
157
+ console.log(` 1) Open: ${verifyUrl}`);
158
+ console.log(` 2) Enter code: ${cyan(userCode)}`);
159
+ console.log(` 3) Waiting for approval... (expires in ${expiresInSec}s, polling ${intervalSec}s)`);
160
+ }
161
+ });
162
+ console.log(green('✓') + ' Account linked and license saved.');
163
+ console.log(` account_id: ${state.account.id || '-'}`);
164
+ console.log(` tier: ${state.license.tier || state.account.tier || '-'}`);
165
+ console.log(` expires_at: ${fmtExpiry(state.license.exp)}`);
166
+ console.log(` state: ${authStatePath()}`);
167
+ return;
168
+ }
169
+
170
+ console.error(red(`Unknown auth subcommand: ${sub}`));
171
+ console.log('Usage: mumpix auth <status|login|logout> [--token=...] [--license=...]');
172
+ process.exit(1);
173
+ }
174
+
80
175
  async function main() {
81
176
  const { args, flags } = parseArgs(process.argv.slice(2));
82
- const [command, filePath, ...rest] = args;
177
+ const [command, arg1, ...rest] = args;
83
178
 
84
179
  if (!command || command === 'help' || command === '--help' || command === '-h') {
85
180
  console.log(USAGE);
86
181
  process.exit(0);
87
182
  }
88
183
 
184
+ if (command === 'auth') {
185
+ await runAuth([arg1, ...rest], flags);
186
+ return;
187
+ }
188
+
189
+ const filePath = arg1;
89
190
  if (!filePath && command !== 'help') {
90
191
  console.error(red('Error: file path required'));
91
192
  console.log(USAGE);
@@ -96,7 +197,7 @@ async function main() {
96
197
  let db;
97
198
 
98
199
  try {
99
- db = Mumpix.open(filePath, { consistency });
200
+ db = await Mumpix.open(filePath, { consistency });
100
201
  } catch (err) {
101
202
  console.error(red(`Error opening ${filePath}: ${err.message}`));
102
203
  process.exit(1);
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const { MumpixDevClient } = require('../src');
4
+
5
+ async function main() {
6
+ const client = new MumpixDevClient({
7
+ baseUrl: process.env.MUMPIX_BASE_URL || 'http://127.0.0.1:3012',
8
+ });
9
+
10
+ const health = await client.health();
11
+ console.log('health:', health);
12
+
13
+ await client.remember('Developer SDK smoke test memory');
14
+ const recalled = await client.recall('smoke test memory');
15
+ console.log('recalled:', recalled);
16
+
17
+ const stats = await client.stats();
18
+ console.log('stats.records:', stats.records);
19
+
20
+ const files = await client.files();
21
+ console.log('files:', (files.files || []).slice(0, 5));
22
+ }
23
+
24
+ main().catch((err) => {
25
+ console.error(err);
26
+ process.exit(1);
27
+ });
28
+
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * examples/license-expiry-downgrade-check.js
5
+ *
6
+ * Verifies offline expiry behavior:
7
+ * - expired monthly license can still use eventual mode
8
+ * - strict mode is blocked for expired license
9
+ * - requested strict mode auto-downgrades to eventual at open()
10
+ *
11
+ * Run:
12
+ * node examples/license-expiry-downgrade-check.js
13
+ */
14
+
15
+ const os = require('os');
16
+ const path = require('path');
17
+ const { MumpixDB } = require('../src/core/MumpixDB');
18
+ const { LicenseManager } = require('../src/core/license');
19
+
20
+ async function main() {
21
+ const now = Date.now();
22
+ const lic = new LicenseManager();
23
+ lic.tier = 'monthly';
24
+ lic.verified = true;
25
+ lic.issuedAt = now - (50 * 24 * 60 * 60 * 1000);
26
+ lic.expiry = now - (60 * 1000);
27
+
28
+ // Expired monthly license: eventual should still be allowed.
29
+ lic.assertActive('eventual');
30
+
31
+ let strictBlocked = false;
32
+ try {
33
+ lic.assertActive('strict');
34
+ } catch (_) {
35
+ strictBlocked = true;
36
+ }
37
+ if (!strictBlocked) {
38
+ throw new Error('Expected strict mode to be blocked for expired monthly license');
39
+ }
40
+
41
+ // Requested strict should be downgraded to eventual at DB open.
42
+ const dbPath = path.join(
43
+ os.tmpdir(),
44
+ `mumpix-expiry-downgrade-check-${process.pid}-${Date.now()}.mpx`
45
+ );
46
+ const db = await MumpixDB.open(dbPath, {
47
+ consistency: 'strict',
48
+ licenseManager: lic
49
+ });
50
+
51
+ const okMode = db.consistency === 'eventual';
52
+ const okMeta = db._opts &&
53
+ db._opts.requestedConsistency === 'strict' &&
54
+ db._opts.downgradedConsistency &&
55
+ db._opts.downgradedConsistency.to === 'eventual';
56
+
57
+ await db.close();
58
+
59
+ if (!okMode || !okMeta) {
60
+ throw new Error(`Unexpected downgrade result: consistency=${db.consistency}`);
61
+ }
62
+
63
+ console.log('PASS license-expiry-downgrade-check');
64
+ }
65
+
66
+ main().catch((err) => {
67
+ console.error('FAIL license-expiry-downgrade-check:', err && err.message ? err.message : err);
68
+ process.exit(1);
69
+ });
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "mumpix",
3
- "version": "1.0.6",
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": {
7
- "mumpix": "./bin/mumpix.js"
7
+ "mumpix": "bin/mumpix.js"
8
+ },
9
+ "scripts": {
10
+ "postinstall": "node ./scripts/postinstall-auth.js",
11
+ "verify:claims": "node ./scripts/verify-claims.cjs",
12
+ "release:publish-and-deprecate": "node ./scripts/publish-and-deprecate.cjs",
13
+ "release:clean": "bash ./scripts/release-clean.sh",
14
+ "release:pack": "npm run release:clean && npm pack --cache /tmp/mumpix-npm-cache"
8
15
  },
9
- "scripts": {},
10
16
  "keywords": [
11
17
  "ai",
12
18
  "memory",
@@ -33,6 +39,7 @@
33
39
  "files": [
34
40
  "src/",
35
41
  "bin/",
42
+ "scripts/postinstall-auth.js",
36
43
  "examples/",
37
44
  "CHANGELOG.md",
38
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();