mneme-sdk 0.1.0 → 0.4.0

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/dist/index.cjs CHANGED
@@ -112,7 +112,13 @@ var Mneme = class {
112
112
  events;
113
113
  kvs;
114
114
  constructor(opts) {
115
- this.auth = "accessToken" in opts && opts.accessToken ? { accessToken: opts.accessToken } : { account: opts.account };
115
+ if ("apiKey" in opts && opts.apiKey) {
116
+ this.auth = { apiKey: opts.apiKey };
117
+ } else if ("accessToken" in opts && opts.accessToken) {
118
+ this.auth = { accessToken: opts.accessToken };
119
+ } else {
120
+ this.auth = { account: opts.account };
121
+ }
116
122
  this.gatewayUrl = opts.gatewayUrl.replace(/\/$/, "");
117
123
  this.chainId = opts.chainId ?? 8453;
118
124
  this.domainName = opts.domainName ?? "Mneme";
@@ -140,6 +146,50 @@ var Mneme = class {
140
146
  from(table) {
141
147
  return new Collection(this, table);
142
148
  }
149
+ /**
150
+ * Natural-language → SQL via the gateway's LLM proxy.
151
+ * Use the returned SQL with `m.sql(...)` to execute it.
152
+ */
153
+ llm = {
154
+ sql: (args) => this.request(
155
+ "POST",
156
+ "/v1/llm/sql",
157
+ args
158
+ )
159
+ };
160
+ /**
161
+ * Service-account API keys — for B2B2C integrators (e.g. Gitlawb) that
162
+ * distribute scoped keys to end-users who don't have wallets.
163
+ *
164
+ * Only callable by wallet-authed clients (keys cannot mint more keys).
165
+ */
166
+ serviceKeys = {
167
+ /** Mint a new scoped key. Returns the raw key value ONCE. */
168
+ create: (args) => this.request("POST", "/v1/service/keys", args),
169
+ /** List all keys you've created (no raw values — only metadata). */
170
+ list: () => this.request("GET", "/v1/service/keys"),
171
+ /** Revoke a key by id. */
172
+ revoke: (id) => this.request("DELETE", `/v1/service/keys/${id}`)
173
+ };
174
+ /**
175
+ * Run raw SQL against your project's Postgres schema.
176
+ *
177
+ * Safety guards (server-side):
178
+ * - 5-second statement timeout
179
+ * - search_path pinned to your schema (unqualified table refs resolve to YOUR schema)
180
+ * - cross-tenant schema references are blocked
181
+ * - 1000-row result cap
182
+ * - single statement only
183
+ *
184
+ * Returns rows, column metadata, and elapsed time.
185
+ *
186
+ * @example
187
+ * await m.sql("SELECT count(*) FROM memories");
188
+ * await m.sql("CREATE INDEX ON books (rating)");
189
+ */
190
+ sql(query) {
191
+ return this.request("POST", "/v1/sql", { query });
192
+ }
143
193
  // ─── Storage (Cloudflare R2 backend, $MNEME burn quota) ──────────────────
144
194
  storage = {
145
195
  upload: async (args) => {
@@ -187,7 +237,9 @@ var Mneme = class {
187
237
  async request(method, path, body) {
188
238
  const bodyText = body === void 0 ? "" : JSON.stringify(body);
189
239
  const headers = { "Content-Type": "application/json" };
190
- if ("accessToken" in this.auth && this.auth.accessToken) {
240
+ if ("apiKey" in this.auth && this.auth.apiKey) {
241
+ headers["Authorization"] = `ApiKey ${this.auth.apiKey}`;
242
+ } else if ("accessToken" in this.auth && this.auth.accessToken) {
191
243
  headers["Authorization"] = `Bearer ${this.auth.accessToken}`;
192
244
  } else if ("account" in this.auth && this.auth.account) {
193
245
  const signed = await signRequest({
@@ -201,7 +253,7 @@ var Mneme = class {
201
253
  });
202
254
  Object.assign(headers, signed);
203
255
  } else {
204
- throw new Error("Mneme: either { account } or { accessToken } is required");
256
+ throw new Error("Mneme: one of { account }, { accessToken }, or { apiKey } is required");
205
257
  }
206
258
  const res = await fetch(`${this.gatewayUrl}${path}`, {
207
259
  method,
@@ -220,6 +272,7 @@ var Collection = class {
220
272
  }
221
273
  mneme;
222
274
  table;
275
+ /** Insert one row or an array of rows. Returns the inserted rows. */
223
276
  insert(rows) {
224
277
  return this.mneme.request(
225
278
  "POST",
@@ -227,14 +280,54 @@ var Collection = class {
227
280
  rows
228
281
  );
229
282
  }
283
+ /**
284
+ * List rows. Supports filtering with `where` (PostgREST-style col.op.value),
285
+ * ordering with `order` (e.g. "created_at.desc"), and pagination.
286
+ *
287
+ * Ops: eq, neq, gt, gte, lt, lte, like, ilike, in, is.
288
+ * Example: `m.from("todos").list({ where: ["done.eq.false"], order: "created_at.desc" })`
289
+ */
230
290
  list(opts) {
231
291
  const q = new URLSearchParams();
232
292
  if (opts?.limit != null) q.set("limit", String(opts.limit));
233
293
  if (opts?.offset != null) q.set("offset", String(opts.offset));
234
294
  if (opts?.order) q.set("order", opts.order);
295
+ if (opts?.where) {
296
+ const ws = Array.isArray(opts.where) ? opts.where : [opts.where];
297
+ for (const w of ws) q.append("where", w);
298
+ }
235
299
  const qs = q.toString() ? `?${q}` : "";
236
300
  return this.mneme.request("GET", `/v1/rows/${this.table}${qs}`);
237
301
  }
302
+ /** Update one row by id. Returns the updated row. */
303
+ update(id, updates) {
304
+ return this.mneme.request(
305
+ "PATCH",
306
+ `/v1/rows/${this.table}/${id}`,
307
+ updates
308
+ );
309
+ }
310
+ /** Delete one row by id. */
311
+ delete(id) {
312
+ return this.mneme.request(
313
+ "DELETE",
314
+ `/v1/rows/${this.table}/${id}`
315
+ );
316
+ }
317
+ /**
318
+ * Bulk delete by filter. Refuses to delete the whole table — at least one
319
+ * where clause is required. Returns the count of deleted rows.
320
+ */
321
+ deleteWhere(where) {
322
+ const ws = Array.isArray(where) ? where : [where];
323
+ if (ws.length === 0) throw new Error("deleteWhere requires at least one filter");
324
+ const q = new URLSearchParams();
325
+ for (const w of ws) q.append("where", w);
326
+ return this.mneme.request(
327
+ "DELETE",
328
+ `/v1/rows/${this.table}?${q}`
329
+ );
330
+ }
238
331
  };
239
332
 
240
333
  // src/types.ts
package/dist/index.d.cts CHANGED
@@ -64,9 +64,15 @@ interface KvRow {
64
64
  type MnemeAuth = {
65
65
  account: Account;
66
66
  accessToken?: never;
67
+ apiKey?: never;
67
68
  } | {
68
69
  accessToken: string;
69
70
  account?: never;
71
+ apiKey?: never;
72
+ } | {
73
+ apiKey: string;
74
+ account?: never;
75
+ accessToken?: never;
70
76
  };
71
77
  type MnemeOptions = MnemeAuth & {
72
78
  gatewayUrl: string;
@@ -112,6 +118,86 @@ declare class Mneme {
112
118
  }>;
113
119
  stats(): Promise<StatsResponse>;
114
120
  from<T = unknown>(table: string): Collection<T>;
121
+ /**
122
+ * Natural-language → SQL via the gateway's LLM proxy.
123
+ * Use the returned SQL with `m.sql(...)` to execute it.
124
+ */
125
+ llm: {
126
+ sql: (args: {
127
+ prompt: string;
128
+ schema?: string;
129
+ }) => Promise<{
130
+ sql: string;
131
+ model: string;
132
+ elapsed_ms: number;
133
+ }>;
134
+ };
135
+ /**
136
+ * Service-account API keys — for B2B2C integrators (e.g. Gitlawb) that
137
+ * distribute scoped keys to end-users who don't have wallets.
138
+ *
139
+ * Only callable by wallet-authed clients (keys cannot mint more keys).
140
+ */
141
+ readonly serviceKeys: {
142
+ /** Mint a new scoped key. Returns the raw key value ONCE. */
143
+ create: (args: {
144
+ scope: string;
145
+ label?: string;
146
+ rpm_limit?: number;
147
+ }) => Promise<{
148
+ ok: true;
149
+ id: number;
150
+ key: string;
151
+ key_prefix: string;
152
+ scope: string;
153
+ label: string | null;
154
+ rpm_limit: number;
155
+ created_at: string;
156
+ warning: string;
157
+ }>;
158
+ /** List all keys you've created (no raw values — only metadata). */
159
+ list: () => Promise<{
160
+ keys: Array<{
161
+ id: number;
162
+ key_prefix: string;
163
+ scope: string;
164
+ label: string | null;
165
+ rpm_limit: number;
166
+ revoked: boolean;
167
+ revoked_at: string | null;
168
+ last_used_at: string | null;
169
+ created_at: string;
170
+ }>;
171
+ }>;
172
+ /** Revoke a key by id. */
173
+ revoke: (id: number) => Promise<{
174
+ ok: true;
175
+ id: number;
176
+ }>;
177
+ };
178
+ /**
179
+ * Run raw SQL against your project's Postgres schema.
180
+ *
181
+ * Safety guards (server-side):
182
+ * - 5-second statement timeout
183
+ * - search_path pinned to your schema (unqualified table refs resolve to YOUR schema)
184
+ * - cross-tenant schema references are blocked
185
+ * - 1000-row result cap
186
+ * - single statement only
187
+ *
188
+ * Returns rows, column metadata, and elapsed time.
189
+ *
190
+ * @example
191
+ * await m.sql("SELECT count(*) FROM memories");
192
+ * await m.sql("CREATE INDEX ON books (rating)");
193
+ */
194
+ sql<T = Record<string, unknown>>(query: string): Promise<{
195
+ rows: T[];
196
+ row_count: number;
197
+ columns: string[];
198
+ truncated: boolean;
199
+ elapsed_ms: number;
200
+ }>;
115
201
  readonly storage: {
116
202
  upload: (args: {
117
203
  key: string;
@@ -183,20 +269,49 @@ declare class Mneme {
183
269
  };
184
270
  request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
185
271
  }
272
+ /** PostgREST-ish where clause. e.g. `["status.eq.done", "score.gt.10"]`. */
273
+ type WhereClause = string;
186
274
  declare class Collection<T = unknown> {
187
275
  private mneme;
188
276
  readonly table: string;
189
277
  constructor(mneme: Mneme, table: string);
278
+ /** Insert one row or an array of rows. Returns the inserted rows. */
190
279
  insert(rows: T | T[]): Promise<{
191
280
  inserted: number;
192
281
  rows: T[];
193
282
  }>;
283
+ /**
284
+ * List rows. Supports filtering with `where` (PostgREST-style col.op.value),
285
+ * ordering with `order` (e.g. "created_at.desc"), and pagination.
286
+ *
287
+ * Ops: eq, neq, gt, gte, lt, lte, like, ilike, in, is.
288
+ * Example: `m.from("todos").list({ where: ["done.eq.false"], order: "created_at.desc" })`
289
+ */
194
290
  list(opts?: {
195
291
  limit?: number;
196
292
  offset?: number;
197
293
  order?: string;
294
+ where?: WhereClause | WhereClause[];
198
295
  }): Promise<{
199
296
  rows: T[];
297
+ count: number;
298
+ }>;
299
+ /** Update one row by id. Returns the updated row. */
300
+ update(id: string | number, updates: Partial<T>): Promise<{
301
+ updated: 1;
302
+ row: T;
303
+ }>;
304
+ /** Delete one row by id. */
305
+ delete(id: string | number): Promise<{
306
+ deleted: 1;
307
+ id: number | string;
308
+ }>;
309
+ /**
310
+ * Bulk delete by filter. Refuses to delete the whole table — at least one
311
+ * where clause is required. Returns the count of deleted rows.
312
+ */
313
+ deleteWhere(where: WhereClause | WhereClause[]): Promise<{
314
+ deleted: number;
200
315
  }>;
201
316
  }
202
317
 
package/dist/index.d.ts CHANGED
@@ -64,9 +64,15 @@ interface KvRow {
64
64
  type MnemeAuth = {
65
65
  account: Account;
66
66
  accessToken?: never;
67
+ apiKey?: never;
67
68
  } | {
68
69
  accessToken: string;
69
70
  account?: never;
71
+ apiKey?: never;
72
+ } | {
73
+ apiKey: string;
74
+ account?: never;
75
+ accessToken?: never;
70
76
  };
71
77
  type MnemeOptions = MnemeAuth & {
72
78
  gatewayUrl: string;
@@ -112,6 +118,86 @@ declare class Mneme {
112
118
  }>;
113
119
  stats(): Promise<StatsResponse>;
114
120
  from<T = unknown>(table: string): Collection<T>;
121
+ /**
122
+ * Natural-language → SQL via the gateway's LLM proxy.
123
+ * Use the returned SQL with `m.sql(...)` to execute it.
124
+ */
125
+ llm: {
126
+ sql: (args: {
127
+ prompt: string;
128
+ schema?: string;
129
+ }) => Promise<{
130
+ sql: string;
131
+ model: string;
132
+ elapsed_ms: number;
133
+ }>;
134
+ };
135
+ /**
136
+ * Service-account API keys — for B2B2C integrators (e.g. Gitlawb) that
137
+ * distribute scoped keys to end-users who don't have wallets.
138
+ *
139
+ * Only callable by wallet-authed clients (keys cannot mint more keys).
140
+ */
141
+ readonly serviceKeys: {
142
+ /** Mint a new scoped key. Returns the raw key value ONCE. */
143
+ create: (args: {
144
+ scope: string;
145
+ label?: string;
146
+ rpm_limit?: number;
147
+ }) => Promise<{
148
+ ok: true;
149
+ id: number;
150
+ key: string;
151
+ key_prefix: string;
152
+ scope: string;
153
+ label: string | null;
154
+ rpm_limit: number;
155
+ created_at: string;
156
+ warning: string;
157
+ }>;
158
+ /** List all keys you've created (no raw values — only metadata). */
159
+ list: () => Promise<{
160
+ keys: Array<{
161
+ id: number;
162
+ key_prefix: string;
163
+ scope: string;
164
+ label: string | null;
165
+ rpm_limit: number;
166
+ revoked: boolean;
167
+ revoked_at: string | null;
168
+ last_used_at: string | null;
169
+ created_at: string;
170
+ }>;
171
+ }>;
172
+ /** Revoke a key by id. */
173
+ revoke: (id: number) => Promise<{
174
+ ok: true;
175
+ id: number;
176
+ }>;
177
+ };
178
+ /**
179
+ * Run raw SQL against your project's Postgres schema.
180
+ *
181
+ * Safety guards (server-side):
182
+ * - 5-second statement timeout
183
+ * - search_path pinned to your schema (unqualified table refs resolve to YOUR schema)
184
+ * - cross-tenant schema references are blocked
185
+ * - 1000-row result cap
186
+ * - single statement only
187
+ *
188
+ * Returns rows, column metadata, and elapsed time.
189
+ *
190
+ * @example
191
+ * await m.sql("SELECT count(*) FROM memories");
192
+ * await m.sql("CREATE INDEX ON books (rating)");
193
+ */
194
+ sql<T = Record<string, unknown>>(query: string): Promise<{
195
+ rows: T[];
196
+ row_count: number;
197
+ columns: string[];
198
+ truncated: boolean;
199
+ elapsed_ms: number;
200
+ }>;
115
201
  readonly storage: {
116
202
  upload: (args: {
117
203
  key: string;
@@ -183,20 +269,49 @@ declare class Mneme {
183
269
  };
184
270
  request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
185
271
  }
272
+ /** PostgREST-ish where clause. e.g. `["status.eq.done", "score.gt.10"]`. */
273
+ type WhereClause = string;
186
274
  declare class Collection<T = unknown> {
187
275
  private mneme;
188
276
  readonly table: string;
189
277
  constructor(mneme: Mneme, table: string);
278
+ /** Insert one row or an array of rows. Returns the inserted rows. */
190
279
  insert(rows: T | T[]): Promise<{
191
280
  inserted: number;
192
281
  rows: T[];
193
282
  }>;
283
+ /**
284
+ * List rows. Supports filtering with `where` (PostgREST-style col.op.value),
285
+ * ordering with `order` (e.g. "created_at.desc"), and pagination.
286
+ *
287
+ * Ops: eq, neq, gt, gte, lt, lte, like, ilike, in, is.
288
+ * Example: `m.from("todos").list({ where: ["done.eq.false"], order: "created_at.desc" })`
289
+ */
194
290
  list(opts?: {
195
291
  limit?: number;
196
292
  offset?: number;
197
293
  order?: string;
294
+ where?: WhereClause | WhereClause[];
198
295
  }): Promise<{
199
296
  rows: T[];
297
+ count: number;
298
+ }>;
299
+ /** Update one row by id. Returns the updated row. */
300
+ update(id: string | number, updates: Partial<T>): Promise<{
301
+ updated: 1;
302
+ row: T;
303
+ }>;
304
+ /** Delete one row by id. */
305
+ delete(id: string | number): Promise<{
306
+ deleted: 1;
307
+ id: number | string;
308
+ }>;
309
+ /**
310
+ * Bulk delete by filter. Refuses to delete the whole table — at least one
311
+ * where clause is required. Returns the count of deleted rows.
312
+ */
313
+ deleteWhere(where: WhereClause | WhereClause[]): Promise<{
314
+ deleted: number;
200
315
  }>;
201
316
  }
202
317
 
package/dist/index.js CHANGED
@@ -80,7 +80,13 @@ var Mneme = class {
80
80
  events;
81
81
  kvs;
82
82
  constructor(opts) {
83
- this.auth = "accessToken" in opts && opts.accessToken ? { accessToken: opts.accessToken } : { account: opts.account };
83
+ if ("apiKey" in opts && opts.apiKey) {
84
+ this.auth = { apiKey: opts.apiKey };
85
+ } else if ("accessToken" in opts && opts.accessToken) {
86
+ this.auth = { accessToken: opts.accessToken };
87
+ } else {
88
+ this.auth = { account: opts.account };
89
+ }
84
90
  this.gatewayUrl = opts.gatewayUrl.replace(/\/$/, "");
85
91
  this.chainId = opts.chainId ?? 8453;
86
92
  this.domainName = opts.domainName ?? "Mneme";
@@ -108,6 +114,50 @@ var Mneme = class {
108
114
  from(table) {
109
115
  return new Collection(this, table);
110
116
  }
117
+ /**
118
+ * Natural-language → SQL via the gateway's LLM proxy.
119
+ * Use the returned SQL with `m.sql(...)` to execute it.
120
+ */
121
+ llm = {
122
+ sql: (args) => this.request(
123
+ "POST",
124
+ "/v1/llm/sql",
125
+ args
126
+ )
127
+ };
128
+ /**
129
+ * Service-account API keys — for B2B2C integrators (e.g. Gitlawb) that
130
+ * distribute scoped keys to end-users who don't have wallets.
131
+ *
132
+ * Only callable by wallet-authed clients (keys cannot mint more keys).
133
+ */
134
+ serviceKeys = {
135
+ /** Mint a new scoped key. Returns the raw key value ONCE. */
136
+ create: (args) => this.request("POST", "/v1/service/keys", args),
137
+ /** List all keys you've created (no raw values — only metadata). */
138
+ list: () => this.request("GET", "/v1/service/keys"),
139
+ /** Revoke a key by id. */
140
+ revoke: (id) => this.request("DELETE", `/v1/service/keys/${id}`)
141
+ };
142
+ /**
143
+ * Run raw SQL against your project's Postgres schema.
144
+ *
145
+ * Safety guards (server-side):
146
+ * - 5-second statement timeout
147
+ * - search_path pinned to your schema (unqualified table refs resolve to YOUR schema)
148
+ * - cross-tenant schema references are blocked
149
+ * - 1000-row result cap
150
+ * - single statement only
151
+ *
152
+ * Returns rows, column metadata, and elapsed time.
153
+ *
154
+ * @example
155
+ * await m.sql("SELECT count(*) FROM memories");
156
+ * await m.sql("CREATE INDEX ON books (rating)");
157
+ */
158
+ sql(query) {
159
+ return this.request("POST", "/v1/sql", { query });
160
+ }
111
161
  // ─── Storage (Cloudflare R2 backend, $MNEME burn quota) ──────────────────
112
162
  storage = {
113
163
  upload: async (args) => {
@@ -155,7 +205,9 @@ var Mneme = class {
155
205
  async request(method, path, body) {
156
206
  const bodyText = body === void 0 ? "" : JSON.stringify(body);
157
207
  const headers = { "Content-Type": "application/json" };
158
- if ("accessToken" in this.auth && this.auth.accessToken) {
208
+ if ("apiKey" in this.auth && this.auth.apiKey) {
209
+ headers["Authorization"] = `ApiKey ${this.auth.apiKey}`;
210
+ } else if ("accessToken" in this.auth && this.auth.accessToken) {
159
211
  headers["Authorization"] = `Bearer ${this.auth.accessToken}`;
160
212
  } else if ("account" in this.auth && this.auth.account) {
161
213
  const signed = await signRequest({
@@ -169,7 +221,7 @@ var Mneme = class {
169
221
  });
170
222
  Object.assign(headers, signed);
171
223
  } else {
172
- throw new Error("Mneme: either { account } or { accessToken } is required");
224
+ throw new Error("Mneme: one of { account }, { accessToken }, or { apiKey } is required");
173
225
  }
174
226
  const res = await fetch(`${this.gatewayUrl}${path}`, {
175
227
  method,
@@ -188,6 +240,7 @@ var Collection = class {
188
240
  }
189
241
  mneme;
190
242
  table;
243
+ /** Insert one row or an array of rows. Returns the inserted rows. */
191
244
  insert(rows) {
192
245
  return this.mneme.request(
193
246
  "POST",
@@ -195,14 +248,54 @@ var Collection = class {
195
248
  rows
196
249
  );
197
250
  }
251
+ /**
252
+ * List rows. Supports filtering with `where` (PostgREST-style col.op.value),
253
+ * ordering with `order` (e.g. "created_at.desc"), and pagination.
254
+ *
255
+ * Ops: eq, neq, gt, gte, lt, lte, like, ilike, in, is.
256
+ * Example: `m.from("todos").list({ where: ["done.eq.false"], order: "created_at.desc" })`
257
+ */
198
258
  list(opts) {
199
259
  const q = new URLSearchParams();
200
260
  if (opts?.limit != null) q.set("limit", String(opts.limit));
201
261
  if (opts?.offset != null) q.set("offset", String(opts.offset));
202
262
  if (opts?.order) q.set("order", opts.order);
263
+ if (opts?.where) {
264
+ const ws = Array.isArray(opts.where) ? opts.where : [opts.where];
265
+ for (const w of ws) q.append("where", w);
266
+ }
203
267
  const qs = q.toString() ? `?${q}` : "";
204
268
  return this.mneme.request("GET", `/v1/rows/${this.table}${qs}`);
205
269
  }
270
+ /** Update one row by id. Returns the updated row. */
271
+ update(id, updates) {
272
+ return this.mneme.request(
273
+ "PATCH",
274
+ `/v1/rows/${this.table}/${id}`,
275
+ updates
276
+ );
277
+ }
278
+ /** Delete one row by id. */
279
+ delete(id) {
280
+ return this.mneme.request(
281
+ "DELETE",
282
+ `/v1/rows/${this.table}/${id}`
283
+ );
284
+ }
285
+ /**
286
+ * Bulk delete by filter. Refuses to delete the whole table — at least one
287
+ * where clause is required. Returns the count of deleted rows.
288
+ */
289
+ deleteWhere(where) {
290
+ const ws = Array.isArray(where) ? where : [where];
291
+ if (ws.length === 0) throw new Error("deleteWhere requires at least one filter");
292
+ const q = new URLSearchParams();
293
+ for (const w of ws) q.append("where", w);
294
+ return this.mneme.request(
295
+ "DELETE",
296
+ `/v1/rows/${this.table}?${q}`
297
+ );
298
+ }
206
299
  };
207
300
 
208
301
  // src/types.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mneme-sdk",
3
- "version": "0.1.0",
4
- "description": "TypeScript SDK for Mneme — agent-native Postgres + R2 storage on Base. Wallet-auth, runtime DDL, pgvector, wallet-bound files with $MNEME burn quota.",
3
+ "version": "0.4.0",
4
+ "description": "TypeScript SDK for Mneme — agent-native Postgres + R2 storage on Base. Wallet-auth, runtime DDL, full CRUD with WHERE filters, raw SQL, pgvector, service-account API keys for B2B2C integrations, wallet-bound files with $MNEME burn quota.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",