cursor-supermemory 1.0.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.
@@ -0,0 +1,1654 @@
1
+ // src/config.ts
2
+ import path2 from "node:path";
3
+ import os2 from "node:os";
4
+ import fs2 from "node:fs";
5
+
6
+ // src/auth.ts
7
+ import path from "node:path";
8
+ import os from "node:os";
9
+ import fs from "node:fs";
10
+ var CREDENTIALS_DIR = path.join(os.homedir(), ".supermemory-cursor");
11
+ var CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, "credentials.json");
12
+ function loadCredentials() {
13
+ try {
14
+ if (!fs.existsSync(CREDENTIALS_FILE))
15
+ return null;
16
+ const data = JSON.parse(fs.readFileSync(CREDENTIALS_FILE, "utf-8"));
17
+ if (data.apiKey)
18
+ return data;
19
+ return null;
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+
25
+ // src/config.ts
26
+ var DEFAULTS = {
27
+ similarityThreshold: 0.3,
28
+ maxMemories: 10,
29
+ maxProjectMemories: 5,
30
+ injectProfile: true,
31
+ userContainerTag: null,
32
+ projectContainerTag: null
33
+ };
34
+ function readJson(filePath) {
35
+ try {
36
+ if (!fs2.existsSync(filePath))
37
+ return null;
38
+ return JSON.parse(fs2.readFileSync(filePath, "utf-8"));
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+ function findProjectConfig(cwd) {
44
+ let dir = cwd;
45
+ while (true) {
46
+ const configPath = path2.join(dir, ".cursor", ".supermemory", "config.json");
47
+ const data = readJson(configPath);
48
+ if (data)
49
+ return data;
50
+ const parent = path2.dirname(dir);
51
+ if (parent === dir)
52
+ break;
53
+ dir = parent;
54
+ }
55
+ return null;
56
+ }
57
+ function loadConfig(cwd) {
58
+ const projectConfig = findProjectConfig(cwd || process.cwd());
59
+ const globalConfig = readJson(path2.join(os2.homedir(), ".config", "cursor", "supermemory.json"));
60
+ const merged = { ...DEFAULTS, ...globalConfig, ...projectConfig };
61
+ return {
62
+ apiKey: process.env.SUPERMEMORY_API_KEY ?? merged.apiKey ?? null,
63
+ similarityThreshold: merged.similarityThreshold,
64
+ maxMemories: merged.maxMemories,
65
+ maxProjectMemories: merged.maxProjectMemories,
66
+ injectProfile: merged.injectProfile,
67
+ userContainerTag: merged.userContainerTag,
68
+ projectContainerTag: merged.projectContainerTag
69
+ };
70
+ }
71
+ function getApiKey(config) {
72
+ if (config.apiKey)
73
+ return config.apiKey;
74
+ const creds = loadCredentials();
75
+ return creds?.apiKey ?? null;
76
+ }
77
+
78
+ // src/tags.ts
79
+ import crypto from "node:crypto";
80
+ import os3 from "node:os";
81
+ import { execSync } from "node:child_process";
82
+ function sha256(input) {
83
+ return crypto.createHash("sha256").update(input).digest("hex").slice(0, 16);
84
+ }
85
+ function getGitEmail() {
86
+ try {
87
+ return execSync("git config user.email", {
88
+ encoding: "utf-8",
89
+ stdio: ["pipe", "pipe", "pipe"]
90
+ }).trim() || null;
91
+ } catch {
92
+ return null;
93
+ }
94
+ }
95
+ function getGitRoot(dir) {
96
+ try {
97
+ return execSync("git rev-parse --show-toplevel", {
98
+ cwd: dir,
99
+ encoding: "utf-8",
100
+ stdio: ["pipe", "pipe", "pipe"]
101
+ }).trim() || null;
102
+ } catch {
103
+ return null;
104
+ }
105
+ }
106
+ function getMachineId() {
107
+ return `${os3.hostname()}_${os3.userInfo().username}`;
108
+ }
109
+ function getUserTag(config) {
110
+ const identity = config.userContainerTag ?? process.env.SUPERMEMORY_USER_TAG ?? process.env.CURSOR_USER_EMAIL ?? getGitEmail() ?? getMachineId();
111
+ return `cursor_user_${sha256(identity)}`;
112
+ }
113
+ function getProjectTag(workspaceRoot, config) {
114
+ const identity = config.projectContainerTag ?? process.env.SUPERMEMORY_PROJECT_TAG ?? (getGitRoot(workspaceRoot) || workspaceRoot);
115
+ return `cursor_project_${sha256(identity)}`;
116
+ }
117
+
118
+ // node_modules/supermemory/internal/tslib.mjs
119
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
120
+ if (kind === "m")
121
+ throw new TypeError("Private method is not writable");
122
+ if (kind === "a" && !f)
123
+ throw new TypeError("Private accessor was defined without a setter");
124
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
125
+ throw new TypeError("Cannot write private member to an object whose class did not declare it");
126
+ return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
127
+ }
128
+ function __classPrivateFieldGet(receiver, state, kind, f) {
129
+ if (kind === "a" && !f)
130
+ throw new TypeError("Private accessor was defined without a getter");
131
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
132
+ throw new TypeError("Cannot read private member from an object whose class did not declare it");
133
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
134
+ }
135
+
136
+ // node_modules/supermemory/internal/utils/uuid.mjs
137
+ var uuid4 = function() {
138
+ const { crypto: crypto2 } = globalThis;
139
+ if (crypto2?.randomUUID) {
140
+ uuid4 = crypto2.randomUUID.bind(crypto2);
141
+ return crypto2.randomUUID();
142
+ }
143
+ const u8 = new Uint8Array(1);
144
+ const randomByte = crypto2 ? () => crypto2.getRandomValues(u8)[0] : () => Math.random() * 255 & 255;
145
+ return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => (+c ^ randomByte() & 15 >> +c / 4).toString(16));
146
+ };
147
+
148
+ // node_modules/supermemory/internal/errors.mjs
149
+ function isAbortError(err) {
150
+ return typeof err === "object" && err !== null && (("name" in err) && err.name === "AbortError" || ("message" in err) && String(err.message).includes("FetchRequestCanceledException"));
151
+ }
152
+ var castToError = (err) => {
153
+ if (err instanceof Error)
154
+ return err;
155
+ if (typeof err === "object" && err !== null) {
156
+ try {
157
+ if (Object.prototype.toString.call(err) === "[object Error]") {
158
+ const error = new Error(err.message, err.cause ? { cause: err.cause } : {});
159
+ if (err.stack)
160
+ error.stack = err.stack;
161
+ if (err.cause && !error.cause)
162
+ error.cause = err.cause;
163
+ if (err.name)
164
+ error.name = err.name;
165
+ return error;
166
+ }
167
+ } catch {}
168
+ try {
169
+ return new Error(JSON.stringify(err));
170
+ } catch {}
171
+ }
172
+ return new Error(err);
173
+ };
174
+
175
+ // node_modules/supermemory/core/error.mjs
176
+ class SupermemoryError extends Error {
177
+ }
178
+
179
+ class APIError extends SupermemoryError {
180
+ constructor(status, error, message, headers) {
181
+ super(`${APIError.makeMessage(status, error, message)}`);
182
+ this.status = status;
183
+ this.headers = headers;
184
+ this.error = error;
185
+ }
186
+ static makeMessage(status, error, message) {
187
+ const msg = error?.message ? typeof error.message === "string" ? error.message : JSON.stringify(error.message) : error ? JSON.stringify(error) : message;
188
+ if (status && msg) {
189
+ return `${status} ${msg}`;
190
+ }
191
+ if (status) {
192
+ return `${status} status code (no body)`;
193
+ }
194
+ if (msg) {
195
+ return msg;
196
+ }
197
+ return "(no status code or body)";
198
+ }
199
+ static generate(status, errorResponse, message, headers) {
200
+ if (!status || !headers) {
201
+ return new APIConnectionError({ message, cause: castToError(errorResponse) });
202
+ }
203
+ const error = errorResponse;
204
+ if (status === 400) {
205
+ return new BadRequestError(status, error, message, headers);
206
+ }
207
+ if (status === 401) {
208
+ return new AuthenticationError(status, error, message, headers);
209
+ }
210
+ if (status === 403) {
211
+ return new PermissionDeniedError(status, error, message, headers);
212
+ }
213
+ if (status === 404) {
214
+ return new NotFoundError(status, error, message, headers);
215
+ }
216
+ if (status === 409) {
217
+ return new ConflictError(status, error, message, headers);
218
+ }
219
+ if (status === 422) {
220
+ return new UnprocessableEntityError(status, error, message, headers);
221
+ }
222
+ if (status === 429) {
223
+ return new RateLimitError(status, error, message, headers);
224
+ }
225
+ if (status >= 500) {
226
+ return new InternalServerError(status, error, message, headers);
227
+ }
228
+ return new APIError(status, error, message, headers);
229
+ }
230
+ }
231
+
232
+ class APIUserAbortError extends APIError {
233
+ constructor({ message } = {}) {
234
+ super(undefined, undefined, message || "Request was aborted.", undefined);
235
+ }
236
+ }
237
+
238
+ class APIConnectionError extends APIError {
239
+ constructor({ message, cause }) {
240
+ super(undefined, undefined, message || "Connection error.", undefined);
241
+ if (cause)
242
+ this.cause = cause;
243
+ }
244
+ }
245
+
246
+ class APIConnectionTimeoutError extends APIConnectionError {
247
+ constructor({ message } = {}) {
248
+ super({ message: message ?? "Request timed out." });
249
+ }
250
+ }
251
+
252
+ class BadRequestError extends APIError {
253
+ }
254
+
255
+ class AuthenticationError extends APIError {
256
+ }
257
+
258
+ class PermissionDeniedError extends APIError {
259
+ }
260
+
261
+ class NotFoundError extends APIError {
262
+ }
263
+
264
+ class ConflictError extends APIError {
265
+ }
266
+
267
+ class UnprocessableEntityError extends APIError {
268
+ }
269
+
270
+ class RateLimitError extends APIError {
271
+ }
272
+
273
+ class InternalServerError extends APIError {
274
+ }
275
+
276
+ // node_modules/supermemory/internal/utils/values.mjs
277
+ var startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
278
+ var isAbsoluteURL = (url) => {
279
+ return startsWithSchemeRegexp.test(url);
280
+ };
281
+ var isArray = (val) => (isArray = Array.isArray, isArray(val));
282
+ var isReadonlyArray = isArray;
283
+ function isEmptyObj(obj) {
284
+ if (!obj)
285
+ return true;
286
+ for (const _k in obj)
287
+ return false;
288
+ return true;
289
+ }
290
+ function hasOwn(obj, key) {
291
+ return Object.prototype.hasOwnProperty.call(obj, key);
292
+ }
293
+ var validatePositiveInteger = (name, n) => {
294
+ if (typeof n !== "number" || !Number.isInteger(n)) {
295
+ throw new SupermemoryError(`${name} must be an integer`);
296
+ }
297
+ if (n < 0) {
298
+ throw new SupermemoryError(`${name} must be a positive integer`);
299
+ }
300
+ return n;
301
+ };
302
+ var safeJSON = (text) => {
303
+ try {
304
+ return JSON.parse(text);
305
+ } catch (err) {
306
+ return;
307
+ }
308
+ };
309
+
310
+ // node_modules/supermemory/internal/utils/sleep.mjs
311
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
312
+
313
+ // node_modules/supermemory/version.mjs
314
+ var VERSION = "4.11.1";
315
+
316
+ // node_modules/supermemory/internal/detect-platform.mjs
317
+ function getDetectedPlatform() {
318
+ if (typeof Deno !== "undefined" && Deno.build != null) {
319
+ return "deno";
320
+ }
321
+ if (typeof EdgeRuntime !== "undefined") {
322
+ return "edge";
323
+ }
324
+ if (Object.prototype.toString.call(typeof globalThis.process !== "undefined" ? globalThis.process : 0) === "[object process]") {
325
+ return "node";
326
+ }
327
+ return "unknown";
328
+ }
329
+ var getPlatformProperties = () => {
330
+ const detectedPlatform = getDetectedPlatform();
331
+ if (detectedPlatform === "deno") {
332
+ return {
333
+ "X-Stainless-Lang": "js",
334
+ "X-Stainless-Package-Version": VERSION,
335
+ "X-Stainless-OS": normalizePlatform(Deno.build.os),
336
+ "X-Stainless-Arch": normalizeArch(Deno.build.arch),
337
+ "X-Stainless-Runtime": "deno",
338
+ "X-Stainless-Runtime-Version": typeof Deno.version === "string" ? Deno.version : Deno.version?.deno ?? "unknown"
339
+ };
340
+ }
341
+ if (typeof EdgeRuntime !== "undefined") {
342
+ return {
343
+ "X-Stainless-Lang": "js",
344
+ "X-Stainless-Package-Version": VERSION,
345
+ "X-Stainless-OS": "Unknown",
346
+ "X-Stainless-Arch": `other:${EdgeRuntime}`,
347
+ "X-Stainless-Runtime": "edge",
348
+ "X-Stainless-Runtime-Version": globalThis.process.version
349
+ };
350
+ }
351
+ if (detectedPlatform === "node") {
352
+ return {
353
+ "X-Stainless-Lang": "js",
354
+ "X-Stainless-Package-Version": VERSION,
355
+ "X-Stainless-OS": normalizePlatform(globalThis.process.platform ?? "unknown"),
356
+ "X-Stainless-Arch": normalizeArch(globalThis.process.arch ?? "unknown"),
357
+ "X-Stainless-Runtime": "node",
358
+ "X-Stainless-Runtime-Version": globalThis.process.version ?? "unknown"
359
+ };
360
+ }
361
+ const browserInfo = getBrowserInfo();
362
+ if (browserInfo) {
363
+ return {
364
+ "X-Stainless-Lang": "js",
365
+ "X-Stainless-Package-Version": VERSION,
366
+ "X-Stainless-OS": "Unknown",
367
+ "X-Stainless-Arch": "unknown",
368
+ "X-Stainless-Runtime": `browser:${browserInfo.browser}`,
369
+ "X-Stainless-Runtime-Version": browserInfo.version
370
+ };
371
+ }
372
+ return {
373
+ "X-Stainless-Lang": "js",
374
+ "X-Stainless-Package-Version": VERSION,
375
+ "X-Stainless-OS": "Unknown",
376
+ "X-Stainless-Arch": "unknown",
377
+ "X-Stainless-Runtime": "unknown",
378
+ "X-Stainless-Runtime-Version": "unknown"
379
+ };
380
+ };
381
+ function getBrowserInfo() {
382
+ if (typeof navigator === "undefined" || !navigator) {
383
+ return null;
384
+ }
385
+ const browserPatterns = [
386
+ { key: "edge", pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
387
+ { key: "ie", pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
388
+ { key: "ie", pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
389
+ { key: "chrome", pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
390
+ { key: "firefox", pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
391
+ { key: "safari", pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ }
392
+ ];
393
+ for (const { key, pattern } of browserPatterns) {
394
+ const match = pattern.exec(navigator.userAgent);
395
+ if (match) {
396
+ const major = match[1] || 0;
397
+ const minor = match[2] || 0;
398
+ const patch = match[3] || 0;
399
+ return { browser: key, version: `${major}.${minor}.${patch}` };
400
+ }
401
+ }
402
+ return null;
403
+ }
404
+ var normalizeArch = (arch) => {
405
+ if (arch === "x32")
406
+ return "x32";
407
+ if (arch === "x86_64" || arch === "x64")
408
+ return "x64";
409
+ if (arch === "arm")
410
+ return "arm";
411
+ if (arch === "aarch64" || arch === "arm64")
412
+ return "arm64";
413
+ if (arch)
414
+ return `other:${arch}`;
415
+ return "unknown";
416
+ };
417
+ var normalizePlatform = (platform) => {
418
+ platform = platform.toLowerCase();
419
+ if (platform.includes("ios"))
420
+ return "iOS";
421
+ if (platform === "android")
422
+ return "Android";
423
+ if (platform === "darwin")
424
+ return "MacOS";
425
+ if (platform === "win32")
426
+ return "Windows";
427
+ if (platform === "freebsd")
428
+ return "FreeBSD";
429
+ if (platform === "openbsd")
430
+ return "OpenBSD";
431
+ if (platform === "linux")
432
+ return "Linux";
433
+ if (platform)
434
+ return `Other:${platform}`;
435
+ return "Unknown";
436
+ };
437
+ var _platformHeaders;
438
+ var getPlatformHeaders = () => {
439
+ return _platformHeaders ?? (_platformHeaders = getPlatformProperties());
440
+ };
441
+
442
+ // node_modules/supermemory/internal/shims.mjs
443
+ function getDefaultFetch() {
444
+ if (typeof fetch !== "undefined") {
445
+ return fetch;
446
+ }
447
+ throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Supermemory({ fetch })` or polyfill the global, `globalThis.fetch = fetch`");
448
+ }
449
+ function makeReadableStream(...args) {
450
+ const ReadableStream = globalThis.ReadableStream;
451
+ if (typeof ReadableStream === "undefined") {
452
+ throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");
453
+ }
454
+ return new ReadableStream(...args);
455
+ }
456
+ function ReadableStreamFrom(iterable) {
457
+ let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
458
+ return makeReadableStream({
459
+ async pull(controller) {
460
+ const { done, value } = await iter.next();
461
+ if (done) {
462
+ controller.close();
463
+ } else {
464
+ controller.enqueue(value);
465
+ }
466
+ },
467
+ async cancel() {
468
+ await iter.return?.();
469
+ }
470
+ });
471
+ }
472
+ async function CancelReadableStream(stream) {
473
+ if (stream === null || typeof stream !== "object")
474
+ return;
475
+ if (stream[Symbol.asyncIterator]) {
476
+ await stream[Symbol.asyncIterator]().return?.();
477
+ return;
478
+ }
479
+ const reader = stream.getReader();
480
+ const cancelPromise = reader.cancel();
481
+ reader.releaseLock();
482
+ await cancelPromise;
483
+ }
484
+
485
+ // node_modules/supermemory/internal/request-options.mjs
486
+ var FallbackEncoder = ({ headers, body }) => {
487
+ return {
488
+ bodyHeaders: {
489
+ "content-type": "application/json"
490
+ },
491
+ body: JSON.stringify(body)
492
+ };
493
+ };
494
+
495
+ // node_modules/supermemory/internal/uploads.mjs
496
+ var checkFileSupport = () => {
497
+ if (typeof File === "undefined") {
498
+ const { process: process2 } = globalThis;
499
+ const isOldNode = typeof process2?.versions?.node === "string" && parseInt(process2.versions.node.split(".")) < 20;
500
+ throw new Error("`File` is not defined as a global, which is required for file uploads." + (isOldNode ? " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`." : ""));
501
+ }
502
+ };
503
+ function makeFile(fileBits, fileName, options) {
504
+ checkFileSupport();
505
+ return new File(fileBits, fileName ?? "unknown_file", options);
506
+ }
507
+ function getName(value) {
508
+ return (typeof value === "object" && value !== null && (("name" in value) && value.name && String(value.name) || ("url" in value) && value.url && String(value.url) || ("filename" in value) && value.filename && String(value.filename) || ("path" in value) && value.path && String(value.path)) || "").split(/[\\/]/).pop() || undefined;
509
+ }
510
+ var isAsyncIterable = (value) => value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
511
+ var multipartFormRequestOptions = async (opts, fetch2) => {
512
+ return { ...opts, body: await createForm(opts.body, fetch2) };
513
+ };
514
+ var supportsFormDataMap = /* @__PURE__ */ new WeakMap;
515
+ function supportsFormData(fetchObject) {
516
+ const fetch2 = typeof fetchObject === "function" ? fetchObject : fetchObject.fetch;
517
+ const cached = supportsFormDataMap.get(fetch2);
518
+ if (cached)
519
+ return cached;
520
+ const promise = (async () => {
521
+ try {
522
+ const FetchResponse = "Response" in fetch2 ? fetch2.Response : (await fetch2("data:,")).constructor;
523
+ const data = new FormData;
524
+ if (data.toString() === await new FetchResponse(data).text()) {
525
+ return false;
526
+ }
527
+ return true;
528
+ } catch {
529
+ return true;
530
+ }
531
+ })();
532
+ supportsFormDataMap.set(fetch2, promise);
533
+ return promise;
534
+ }
535
+ var createForm = async (body, fetch2) => {
536
+ if (!await supportsFormData(fetch2)) {
537
+ throw new TypeError("The provided fetch function does not support file uploads with the current global FormData class.");
538
+ }
539
+ const form = new FormData;
540
+ await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value)));
541
+ return form;
542
+ };
543
+ var isNamedBlob = (value) => value instanceof Blob && ("name" in value);
544
+ var addFormValue = async (form, key, value) => {
545
+ if (value === undefined)
546
+ return;
547
+ if (value == null) {
548
+ throw new TypeError(`Received null for "${key}"; to pass null in FormData, you must use the string 'null'`);
549
+ }
550
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
551
+ form.append(key, String(value));
552
+ } else if (value instanceof Response) {
553
+ form.append(key, makeFile([await value.blob()], getName(value)));
554
+ } else if (isAsyncIterable(value)) {
555
+ form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value)));
556
+ } else if (isNamedBlob(value)) {
557
+ form.append(key, value, getName(value));
558
+ } else if (Array.isArray(value)) {
559
+ await Promise.all(value.map((entry) => addFormValue(form, key + "[]", entry)));
560
+ } else if (typeof value === "object") {
561
+ await Promise.all(Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)));
562
+ } else {
563
+ throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`);
564
+ }
565
+ };
566
+
567
+ // node_modules/supermemory/internal/to-file.mjs
568
+ var isBlobLike = (value) => value != null && typeof value === "object" && typeof value.size === "number" && typeof value.type === "string" && typeof value.text === "function" && typeof value.slice === "function" && typeof value.arrayBuffer === "function";
569
+ var isFileLike = (value) => value != null && typeof value === "object" && typeof value.name === "string" && typeof value.lastModified === "number" && isBlobLike(value);
570
+ var isResponseLike = (value) => value != null && typeof value === "object" && typeof value.url === "string" && typeof value.blob === "function";
571
+ async function toFile(value, name, options) {
572
+ checkFileSupport();
573
+ value = await value;
574
+ if (isFileLike(value)) {
575
+ if (value instanceof File) {
576
+ return value;
577
+ }
578
+ return makeFile([await value.arrayBuffer()], value.name);
579
+ }
580
+ if (isResponseLike(value)) {
581
+ const blob = await value.blob();
582
+ name || (name = new URL(value.url).pathname.split(/[\\/]/).pop());
583
+ return makeFile(await getBytes(blob), name, options);
584
+ }
585
+ const parts = await getBytes(value);
586
+ name || (name = getName(value));
587
+ if (!options?.type) {
588
+ const type = parts.find((part) => typeof part === "object" && ("type" in part) && part.type);
589
+ if (typeof type === "string") {
590
+ options = { ...options, type };
591
+ }
592
+ }
593
+ return makeFile(parts, name, options);
594
+ }
595
+ async function getBytes(value) {
596
+ let parts = [];
597
+ if (typeof value === "string" || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
598
+ parts.push(value);
599
+ } else if (isBlobLike(value)) {
600
+ parts.push(value instanceof Blob ? value : await value.arrayBuffer());
601
+ } else if (isAsyncIterable(value)) {
602
+ for await (const chunk of value) {
603
+ parts.push(...await getBytes(chunk));
604
+ }
605
+ } else {
606
+ const constructor = value?.constructor?.name;
607
+ throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ""}${propsForError(value)}`);
608
+ }
609
+ return parts;
610
+ }
611
+ function propsForError(value) {
612
+ if (typeof value !== "object" || value === null)
613
+ return "";
614
+ const props = Object.getOwnPropertyNames(value);
615
+ return `; props: [${props.map((p) => `"${p}"`).join(", ")}]`;
616
+ }
617
+ // node_modules/supermemory/core/resource.mjs
618
+ class APIResource {
619
+ constructor(client) {
620
+ this._client = client;
621
+ }
622
+ }
623
+
624
+ // node_modules/supermemory/internal/headers.mjs
625
+ var brand_privateNullableHeaders = /* @__PURE__ */ Symbol("brand.privateNullableHeaders");
626
+ function* iterateHeaders(headers) {
627
+ if (!headers)
628
+ return;
629
+ if (brand_privateNullableHeaders in headers) {
630
+ const { values, nulls } = headers;
631
+ yield* values.entries();
632
+ for (const name of nulls) {
633
+ yield [name, null];
634
+ }
635
+ return;
636
+ }
637
+ let shouldClear = false;
638
+ let iter;
639
+ if (headers instanceof Headers) {
640
+ iter = headers.entries();
641
+ } else if (isReadonlyArray(headers)) {
642
+ iter = headers;
643
+ } else {
644
+ shouldClear = true;
645
+ iter = Object.entries(headers ?? {});
646
+ }
647
+ for (let row of iter) {
648
+ const name = row[0];
649
+ if (typeof name !== "string")
650
+ throw new TypeError("expected header name to be a string");
651
+ const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
652
+ let didClear = false;
653
+ for (const value of values) {
654
+ if (value === undefined)
655
+ continue;
656
+ if (shouldClear && !didClear) {
657
+ didClear = true;
658
+ yield [name, null];
659
+ }
660
+ yield [name, value];
661
+ }
662
+ }
663
+ }
664
+ var buildHeaders = (newHeaders) => {
665
+ const targetHeaders = new Headers;
666
+ const nullHeaders = new Set;
667
+ for (const headers of newHeaders) {
668
+ const seenHeaders = new Set;
669
+ for (const [name, value] of iterateHeaders(headers)) {
670
+ const lowerName = name.toLowerCase();
671
+ if (!seenHeaders.has(lowerName)) {
672
+ targetHeaders.delete(name);
673
+ seenHeaders.add(lowerName);
674
+ }
675
+ if (value === null) {
676
+ targetHeaders.delete(name);
677
+ nullHeaders.add(lowerName);
678
+ } else {
679
+ targetHeaders.append(name, value);
680
+ nullHeaders.delete(lowerName);
681
+ }
682
+ }
683
+ }
684
+ return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders };
685
+ };
686
+
687
+ // node_modules/supermemory/internal/utils/path.mjs
688
+ function encodeURIPath(str) {
689
+ return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
690
+ }
691
+ var EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
692
+ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path(statics, ...params) {
693
+ if (statics.length === 1)
694
+ return statics[0];
695
+ let postPath = false;
696
+ const invalidSegments = [];
697
+ const path3 = statics.reduce((previousValue, currentValue, index) => {
698
+ if (/[?#]/.test(currentValue)) {
699
+ postPath = true;
700
+ }
701
+ const value = params[index];
702
+ let encoded = (postPath ? encodeURIComponent : pathEncoder)("" + value);
703
+ if (index !== params.length && (value == null || typeof value === "object" && value.toString === Object.getPrototypeOf(Object.getPrototypeOf(value.hasOwnProperty ?? EMPTY) ?? EMPTY)?.toString)) {
704
+ encoded = value + "";
705
+ invalidSegments.push({
706
+ start: previousValue.length + currentValue.length,
707
+ length: encoded.length,
708
+ error: `Value of type ${Object.prototype.toString.call(value).slice(8, -1)} is not a valid path parameter`
709
+ });
710
+ }
711
+ return previousValue + currentValue + (index === params.length ? "" : encoded);
712
+ }, "");
713
+ const pathOnly = path3.split(/[?#]/, 1)[0];
714
+ const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
715
+ let match;
716
+ while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
717
+ invalidSegments.push({
718
+ start: match.index,
719
+ length: match[0].length,
720
+ error: `Value "${match[0]}" can't be safely passed as a path parameter`
721
+ });
722
+ }
723
+ invalidSegments.sort((a, b) => a.start - b.start);
724
+ if (invalidSegments.length > 0) {
725
+ let lastEnd = 0;
726
+ const underline = invalidSegments.reduce((acc, segment) => {
727
+ const spaces = " ".repeat(segment.start - lastEnd);
728
+ const arrows = "^".repeat(segment.length);
729
+ lastEnd = segment.start + segment.length;
730
+ return acc + spaces + arrows;
731
+ }, "");
732
+ throw new SupermemoryError(`Path parameters result in path with invalid segments:
733
+ ${invalidSegments.map((e) => e.error).join(`
734
+ `)}
735
+ ${path3}
736
+ ${underline}`);
737
+ }
738
+ return path3;
739
+ };
740
+ var path3 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
741
+
742
+ // node_modules/supermemory/resources/connections.mjs
743
+ class Connections extends APIResource {
744
+ create(provider, body = {}, options) {
745
+ return this._client.post(path3`/v3/connections/${provider}`, { body, ...options });
746
+ }
747
+ list(body = {}, options) {
748
+ return this._client.post("/v3/connections/list", { body, ...options });
749
+ }
750
+ configure(connectionID, body, options) {
751
+ return this._client.post(path3`/v3/connections/${connectionID}/configure`, { body, ...options });
752
+ }
753
+ deleteByID(connectionID, options) {
754
+ return this._client.delete(path3`/v3/connections/${connectionID}`, options);
755
+ }
756
+ deleteByProvider(provider, body, options) {
757
+ return this._client.delete(path3`/v3/connections/${provider}`, { body, ...options });
758
+ }
759
+ getByID(connectionID, options) {
760
+ return this._client.get(path3`/v3/connections/${connectionID}`, options);
761
+ }
762
+ getByTag(provider, body, options) {
763
+ return this._client.post(path3`/v3/connections/${provider}/connection`, { body, ...options });
764
+ }
765
+ import(provider, body = {}, options) {
766
+ return this._client.post(path3`/v3/connections/${provider}/import`, {
767
+ body,
768
+ ...options,
769
+ headers: buildHeaders([{ Accept: "text/plain" }, options?.headers])
770
+ });
771
+ }
772
+ listDocuments(provider, body = {}, options) {
773
+ return this._client.post(path3`/v3/connections/${provider}/documents`, { body, ...options });
774
+ }
775
+ resources(connectionID, query = {}, options) {
776
+ return this._client.get(path3`/v3/connections/${connectionID}/resources`, { query, ...options });
777
+ }
778
+ }
779
+ // node_modules/supermemory/resources/documents.mjs
780
+ class Documents extends APIResource {
781
+ update(id, body = {}, options) {
782
+ return this._client.patch(path3`/v3/documents/${id}`, { body, ...options });
783
+ }
784
+ list(body = {}, options) {
785
+ return this._client.post("/v3/documents/list", { body, ...options });
786
+ }
787
+ delete(id, options) {
788
+ return this._client.delete(path3`/v3/documents/${id}`, {
789
+ ...options,
790
+ headers: buildHeaders([{ Accept: "*/*" }, options?.headers])
791
+ });
792
+ }
793
+ add(body, options) {
794
+ return this._client.post("/v3/documents", { body, ...options });
795
+ }
796
+ batchAdd(body, options) {
797
+ return this._client.post("/v3/documents/batch", { body, ...options });
798
+ }
799
+ deleteBulk(body = {}, options) {
800
+ return this._client.delete("/v3/documents/bulk", { body, ...options });
801
+ }
802
+ get(id, options) {
803
+ return this._client.get(path3`/v3/documents/${id}`, options);
804
+ }
805
+ listProcessing(options) {
806
+ return this._client.get("/v3/documents/processing", options);
807
+ }
808
+ uploadFile(body, options) {
809
+ return this._client.post("/v3/documents/file", multipartFormRequestOptions({ body, ...options }, this._client));
810
+ }
811
+ }
812
+ // node_modules/supermemory/resources/memories.mjs
813
+ class Memories extends APIResource {
814
+ forget(body, options) {
815
+ return this._client.delete("/v4/memories", { body, ...options });
816
+ }
817
+ updateMemory(body, options) {
818
+ return this._client.patch("/v4/memories", { body, ...options });
819
+ }
820
+ }
821
+ // node_modules/supermemory/resources/search.mjs
822
+ class Search extends APIResource {
823
+ documents(body, options) {
824
+ return this._client.post("/v3/search", { body, ...options });
825
+ }
826
+ execute(body, options) {
827
+ return this._client.post("/v3/search", { body, ...options });
828
+ }
829
+ memories(body, options) {
830
+ return this._client.post("/v4/search", { body, ...options });
831
+ }
832
+ }
833
+ // node_modules/supermemory/resources/settings.mjs
834
+ class Settings extends APIResource {
835
+ update(body = {}, options) {
836
+ return this._client.patch("/v3/settings", { body, ...options });
837
+ }
838
+ get(options) {
839
+ return this._client.get("/v3/settings", options);
840
+ }
841
+ }
842
+ // node_modules/supermemory/internal/utils/log.mjs
843
+ var levelNumbers = {
844
+ off: 0,
845
+ error: 200,
846
+ warn: 300,
847
+ info: 400,
848
+ debug: 500
849
+ };
850
+ var parseLogLevel = (maybeLevel, sourceName, client) => {
851
+ if (!maybeLevel) {
852
+ return;
853
+ }
854
+ if (hasOwn(levelNumbers, maybeLevel)) {
855
+ return maybeLevel;
856
+ }
857
+ loggerFor(client).warn(`${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(Object.keys(levelNumbers))}`);
858
+ return;
859
+ };
860
+ function noop() {}
861
+ function makeLogFn(fnLevel, logger, logLevel) {
862
+ if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
863
+ return noop;
864
+ } else {
865
+ return logger[fnLevel].bind(logger);
866
+ }
867
+ }
868
+ var noopLogger = {
869
+ error: noop,
870
+ warn: noop,
871
+ info: noop,
872
+ debug: noop
873
+ };
874
+ var cachedLoggers = /* @__PURE__ */ new WeakMap;
875
+ function loggerFor(client) {
876
+ const logger = client.logger;
877
+ const logLevel = client.logLevel ?? "off";
878
+ if (!logger) {
879
+ return noopLogger;
880
+ }
881
+ const cachedLogger = cachedLoggers.get(logger);
882
+ if (cachedLogger && cachedLogger[0] === logLevel) {
883
+ return cachedLogger[1];
884
+ }
885
+ const levelLogger = {
886
+ error: makeLogFn("error", logger, logLevel),
887
+ warn: makeLogFn("warn", logger, logLevel),
888
+ info: makeLogFn("info", logger, logLevel),
889
+ debug: makeLogFn("debug", logger, logLevel)
890
+ };
891
+ cachedLoggers.set(logger, [logLevel, levelLogger]);
892
+ return levelLogger;
893
+ }
894
+ var formatRequestDetails = (details) => {
895
+ if (details.options) {
896
+ details.options = { ...details.options };
897
+ delete details.options["headers"];
898
+ }
899
+ if (details.headers) {
900
+ details.headers = Object.fromEntries((details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(([name, value]) => [
901
+ name,
902
+ name.toLowerCase() === "authorization" || name.toLowerCase() === "cookie" || name.toLowerCase() === "set-cookie" ? "***" : value
903
+ ]));
904
+ }
905
+ if ("retryOfRequestLogID" in details) {
906
+ if (details.retryOfRequestLogID) {
907
+ details.retryOf = details.retryOfRequestLogID;
908
+ }
909
+ delete details.retryOfRequestLogID;
910
+ }
911
+ return details;
912
+ };
913
+
914
+ // node_modules/supermemory/internal/parse.mjs
915
+ async function defaultParseResponse(client, props) {
916
+ const { response, requestLogID, retryOfRequestLogID, startTime } = props;
917
+ const body = await (async () => {
918
+ if (response.status === 204) {
919
+ return null;
920
+ }
921
+ if (props.options.__binaryResponse) {
922
+ return response;
923
+ }
924
+ const contentType = response.headers.get("content-type");
925
+ const mediaType = contentType?.split(";")[0]?.trim();
926
+ const isJSON = mediaType?.includes("application/json") || mediaType?.endsWith("+json");
927
+ if (isJSON) {
928
+ const contentLength = response.headers.get("content-length");
929
+ if (contentLength === "0") {
930
+ return;
931
+ }
932
+ const json = await response.json();
933
+ return json;
934
+ }
935
+ const text = await response.text();
936
+ return text;
937
+ })();
938
+ loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
939
+ retryOfRequestLogID,
940
+ url: response.url,
941
+ status: response.status,
942
+ body,
943
+ durationMs: Date.now() - startTime
944
+ }));
945
+ return body;
946
+ }
947
+
948
+ // node_modules/supermemory/core/api-promise.mjs
949
+ var _APIPromise_client;
950
+
951
+ class APIPromise extends Promise {
952
+ constructor(client, responsePromise, parseResponse = defaultParseResponse) {
953
+ super((resolve) => {
954
+ resolve(null);
955
+ });
956
+ this.responsePromise = responsePromise;
957
+ this.parseResponse = parseResponse;
958
+ _APIPromise_client.set(this, undefined);
959
+ __classPrivateFieldSet(this, _APIPromise_client, client, "f");
960
+ }
961
+ _thenUnwrap(transform) {
962
+ return new APIPromise(__classPrivateFieldGet(this, _APIPromise_client, "f"), this.responsePromise, async (client, props) => transform(await this.parseResponse(client, props), props));
963
+ }
964
+ asResponse() {
965
+ return this.responsePromise.then((p) => p.response);
966
+ }
967
+ async withResponse() {
968
+ const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
969
+ return { data, response };
970
+ }
971
+ parse() {
972
+ if (!this.parsedPromise) {
973
+ this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(__classPrivateFieldGet(this, _APIPromise_client, "f"), data));
974
+ }
975
+ return this.parsedPromise;
976
+ }
977
+ then(onfulfilled, onrejected) {
978
+ return this.parse().then(onfulfilled, onrejected);
979
+ }
980
+ catch(onrejected) {
981
+ return this.parse().catch(onrejected);
982
+ }
983
+ finally(onfinally) {
984
+ return this.parse().finally(onfinally);
985
+ }
986
+ }
987
+ _APIPromise_client = new WeakMap;
988
+
989
+ // node_modules/supermemory/internal/utils/env.mjs
990
+ var readEnv = (env) => {
991
+ if (typeof globalThis.process !== "undefined") {
992
+ return globalThis.process.env?.[env]?.trim() ?? undefined;
993
+ }
994
+ if (typeof globalThis.Deno !== "undefined") {
995
+ return globalThis.Deno.env?.get?.(env)?.trim();
996
+ }
997
+ return;
998
+ };
999
+
1000
+ // node_modules/supermemory/client.mjs
1001
+ var _Supermemory_instances;
1002
+ var _a;
1003
+ var _Supermemory_encoder;
1004
+ var _Supermemory_baseURLOverridden;
1005
+
1006
+ class Supermemory {
1007
+ constructor({ baseURL = readEnv("SUPERMEMORY_BASE_URL"), apiKey = readEnv("SUPERMEMORY_API_KEY"), ...opts } = {}) {
1008
+ _Supermemory_instances.add(this);
1009
+ _Supermemory_encoder.set(this, undefined);
1010
+ this.memories = new Memories(this);
1011
+ this.documents = new Documents(this);
1012
+ this.search = new Search(this);
1013
+ this.settings = new Settings(this);
1014
+ this.connections = new Connections(this);
1015
+ if (apiKey === undefined) {
1016
+ throw new SupermemoryError("The SUPERMEMORY_API_KEY environment variable is missing or empty; either provide it, or instantiate the Supermemory client with an apiKey option, like new Supermemory({ apiKey: 'My API Key' }).");
1017
+ }
1018
+ const options = {
1019
+ apiKey,
1020
+ ...opts,
1021
+ baseURL: baseURL || `https://api.supermemory.ai`
1022
+ };
1023
+ this.baseURL = options.baseURL;
1024
+ this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT;
1025
+ this.logger = options.logger ?? console;
1026
+ const defaultLogLevel = "warn";
1027
+ this.logLevel = defaultLogLevel;
1028
+ this.logLevel = parseLogLevel(options.logLevel, "ClientOptions.logLevel", this) ?? parseLogLevel(readEnv("SUPERMEMORY_LOG"), "process.env['SUPERMEMORY_LOG']", this) ?? defaultLogLevel;
1029
+ this.fetchOptions = options.fetchOptions;
1030
+ this.maxRetries = options.maxRetries ?? 2;
1031
+ this.fetch = options.fetch ?? getDefaultFetch();
1032
+ __classPrivateFieldSet(this, _Supermemory_encoder, FallbackEncoder, "f");
1033
+ this._options = options;
1034
+ this.apiKey = apiKey;
1035
+ }
1036
+ withOptions(options) {
1037
+ const client = new this.constructor({
1038
+ ...this._options,
1039
+ baseURL: this.baseURL,
1040
+ maxRetries: this.maxRetries,
1041
+ timeout: this.timeout,
1042
+ logger: this.logger,
1043
+ logLevel: this.logLevel,
1044
+ fetch: this.fetch,
1045
+ fetchOptions: this.fetchOptions,
1046
+ apiKey: this.apiKey,
1047
+ ...options
1048
+ });
1049
+ return client;
1050
+ }
1051
+ add(body, options) {
1052
+ return this.post("/v3/documents", { body, ...options });
1053
+ }
1054
+ profile(body, options) {
1055
+ return this.post("/v4/profile", { body, ...options });
1056
+ }
1057
+ defaultQuery() {
1058
+ return this._options.defaultQuery;
1059
+ }
1060
+ validateHeaders({ values, nulls }) {
1061
+ return;
1062
+ }
1063
+ async authHeaders(opts) {
1064
+ return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
1065
+ }
1066
+ stringifyQuery(query) {
1067
+ return Object.entries(query).filter(([_, value]) => typeof value !== "undefined").map(([key, value]) => {
1068
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1069
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
1070
+ }
1071
+ if (value === null) {
1072
+ return `${encodeURIComponent(key)}=`;
1073
+ }
1074
+ throw new SupermemoryError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`);
1075
+ }).join("&");
1076
+ }
1077
+ getUserAgent() {
1078
+ return `${this.constructor.name}/JS ${VERSION}`;
1079
+ }
1080
+ defaultIdempotencyKey() {
1081
+ return `stainless-node-retry-${uuid4()}`;
1082
+ }
1083
+ makeStatusError(status, error, message, headers) {
1084
+ return APIError.generate(status, error, message, headers);
1085
+ }
1086
+ buildURL(path4, query, defaultBaseURL) {
1087
+ const baseURL = !__classPrivateFieldGet(this, _Supermemory_instances, "m", _Supermemory_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
1088
+ const url = isAbsoluteURL(path4) ? new URL(path4) : new URL(baseURL + (baseURL.endsWith("/") && path4.startsWith("/") ? path4.slice(1) : path4));
1089
+ const defaultQuery = this.defaultQuery();
1090
+ if (!isEmptyObj(defaultQuery)) {
1091
+ query = { ...defaultQuery, ...query };
1092
+ }
1093
+ if (typeof query === "object" && query && !Array.isArray(query)) {
1094
+ url.search = this.stringifyQuery(query);
1095
+ }
1096
+ return url.toString();
1097
+ }
1098
+ async prepareOptions(options) {}
1099
+ async prepareRequest(request, { url, options }) {}
1100
+ get(path4, opts) {
1101
+ return this.methodRequest("get", path4, opts);
1102
+ }
1103
+ post(path4, opts) {
1104
+ return this.methodRequest("post", path4, opts);
1105
+ }
1106
+ patch(path4, opts) {
1107
+ return this.methodRequest("patch", path4, opts);
1108
+ }
1109
+ put(path4, opts) {
1110
+ return this.methodRequest("put", path4, opts);
1111
+ }
1112
+ delete(path4, opts) {
1113
+ return this.methodRequest("delete", path4, opts);
1114
+ }
1115
+ methodRequest(method, path4, opts) {
1116
+ return this.request(Promise.resolve(opts).then((opts2) => {
1117
+ return { method, path: path4, ...opts2 };
1118
+ }));
1119
+ }
1120
+ request(options, remainingRetries = null) {
1121
+ return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
1122
+ }
1123
+ async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
1124
+ const options = await optionsInput;
1125
+ const maxRetries = options.maxRetries ?? this.maxRetries;
1126
+ if (retriesRemaining == null) {
1127
+ retriesRemaining = maxRetries;
1128
+ }
1129
+ await this.prepareOptions(options);
1130
+ const { req, url, timeout } = await this.buildRequest(options, {
1131
+ retryCount: maxRetries - retriesRemaining
1132
+ });
1133
+ await this.prepareRequest(req, { url, options });
1134
+ const requestLogID = "log_" + (Math.random() * (1 << 24) | 0).toString(16).padStart(6, "0");
1135
+ const retryLogStr = retryOfRequestLogID === undefined ? "" : `, retryOf: ${retryOfRequestLogID}`;
1136
+ const startTime = Date.now();
1137
+ loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
1138
+ retryOfRequestLogID,
1139
+ method: options.method,
1140
+ url,
1141
+ options,
1142
+ headers: req.headers
1143
+ }));
1144
+ if (options.signal?.aborted) {
1145
+ throw new APIUserAbortError;
1146
+ }
1147
+ const controller = new AbortController;
1148
+ const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
1149
+ const headersTime = Date.now();
1150
+ if (response instanceof globalThis.Error) {
1151
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
1152
+ if (options.signal?.aborted) {
1153
+ throw new APIUserAbortError;
1154
+ }
1155
+ const isTimeout = isAbortError(response) || /timed? ?out/i.test(String(response) + ("cause" in response ? String(response.cause) : ""));
1156
+ if (retriesRemaining) {
1157
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} - ${retryMessage}`);
1158
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} (${retryMessage})`, formatRequestDetails({
1159
+ retryOfRequestLogID,
1160
+ url,
1161
+ durationMs: headersTime - startTime,
1162
+ message: response.message
1163
+ }));
1164
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
1165
+ }
1166
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} - error; no more retries left`);
1167
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} (error; no more retries left)`, formatRequestDetails({
1168
+ retryOfRequestLogID,
1169
+ url,
1170
+ durationMs: headersTime - startTime,
1171
+ message: response.message
1172
+ }));
1173
+ if (isTimeout) {
1174
+ throw new APIConnectionTimeoutError;
1175
+ }
1176
+ throw new APIConnectionError({ cause: response });
1177
+ }
1178
+ const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? "succeeded" : "failed"} with status ${response.status} in ${headersTime - startTime}ms`;
1179
+ if (!response.ok) {
1180
+ const shouldRetry = await this.shouldRetry(response);
1181
+ if (retriesRemaining && shouldRetry) {
1182
+ const retryMessage2 = `retrying, ${retriesRemaining} attempts remaining`;
1183
+ await CancelReadableStream(response.body);
1184
+ loggerFor(this).info(`${responseInfo} - ${retryMessage2}`);
1185
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage2})`, formatRequestDetails({
1186
+ retryOfRequestLogID,
1187
+ url: response.url,
1188
+ status: response.status,
1189
+ headers: response.headers,
1190
+ durationMs: headersTime - startTime
1191
+ }));
1192
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
1193
+ }
1194
+ const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
1195
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
1196
+ const errText = await response.text().catch((err2) => castToError(err2).message);
1197
+ const errJSON = safeJSON(errText);
1198
+ const errMessage = errJSON ? undefined : errText;
1199
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
1200
+ retryOfRequestLogID,
1201
+ url: response.url,
1202
+ status: response.status,
1203
+ headers: response.headers,
1204
+ message: errMessage,
1205
+ durationMs: Date.now() - startTime
1206
+ }));
1207
+ const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
1208
+ throw err;
1209
+ }
1210
+ loggerFor(this).info(responseInfo);
1211
+ loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
1212
+ retryOfRequestLogID,
1213
+ url: response.url,
1214
+ status: response.status,
1215
+ headers: response.headers,
1216
+ durationMs: headersTime - startTime
1217
+ }));
1218
+ return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
1219
+ }
1220
+ async fetchWithTimeout(url, init, ms, controller) {
1221
+ const { signal, method, ...options } = init || {};
1222
+ const abort = this._makeAbort(controller);
1223
+ if (signal)
1224
+ signal.addEventListener("abort", abort, { once: true });
1225
+ const timeout = setTimeout(abort, ms);
1226
+ const isReadableBody = globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream || typeof options.body === "object" && options.body !== null && Symbol.asyncIterator in options.body;
1227
+ const fetchOptions = {
1228
+ signal: controller.signal,
1229
+ ...isReadableBody ? { duplex: "half" } : {},
1230
+ method: "GET",
1231
+ ...options
1232
+ };
1233
+ if (method) {
1234
+ fetchOptions.method = method.toUpperCase();
1235
+ }
1236
+ try {
1237
+ return await this.fetch.call(undefined, url, fetchOptions);
1238
+ } finally {
1239
+ clearTimeout(timeout);
1240
+ }
1241
+ }
1242
+ async shouldRetry(response) {
1243
+ const shouldRetryHeader = response.headers.get("x-should-retry");
1244
+ if (shouldRetryHeader === "true")
1245
+ return true;
1246
+ if (shouldRetryHeader === "false")
1247
+ return false;
1248
+ if (response.status === 408)
1249
+ return true;
1250
+ if (response.status === 409)
1251
+ return true;
1252
+ if (response.status === 429)
1253
+ return true;
1254
+ if (response.status >= 500)
1255
+ return true;
1256
+ return false;
1257
+ }
1258
+ async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
1259
+ let timeoutMillis;
1260
+ const retryAfterMillisHeader = responseHeaders?.get("retry-after-ms");
1261
+ if (retryAfterMillisHeader) {
1262
+ const timeoutMs = parseFloat(retryAfterMillisHeader);
1263
+ if (!Number.isNaN(timeoutMs)) {
1264
+ timeoutMillis = timeoutMs;
1265
+ }
1266
+ }
1267
+ const retryAfterHeader = responseHeaders?.get("retry-after");
1268
+ if (retryAfterHeader && !timeoutMillis) {
1269
+ const timeoutSeconds = parseFloat(retryAfterHeader);
1270
+ if (!Number.isNaN(timeoutSeconds)) {
1271
+ timeoutMillis = timeoutSeconds * 1000;
1272
+ } else {
1273
+ timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
1274
+ }
1275
+ }
1276
+ if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
1277
+ const maxRetries = options.maxRetries ?? this.maxRetries;
1278
+ timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
1279
+ }
1280
+ await sleep(timeoutMillis);
1281
+ return this.makeRequest(options, retriesRemaining - 1, requestLogID);
1282
+ }
1283
+ calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
1284
+ const initialRetryDelay = 0.5;
1285
+ const maxRetryDelay = 8;
1286
+ const numRetries = maxRetries - retriesRemaining;
1287
+ const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
1288
+ const jitter = 1 - Math.random() * 0.25;
1289
+ return sleepSeconds * jitter * 1000;
1290
+ }
1291
+ async buildRequest(inputOptions, { retryCount = 0 } = {}) {
1292
+ const options = { ...inputOptions };
1293
+ const { method, path: path4, query, defaultBaseURL } = options;
1294
+ const url = this.buildURL(path4, query, defaultBaseURL);
1295
+ if ("timeout" in options)
1296
+ validatePositiveInteger("timeout", options.timeout);
1297
+ options.timeout = options.timeout ?? this.timeout;
1298
+ const { bodyHeaders, body } = this.buildBody({ options });
1299
+ const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
1300
+ const req = {
1301
+ method,
1302
+ headers: reqHeaders,
1303
+ ...options.signal && { signal: options.signal },
1304
+ ...globalThis.ReadableStream && body instanceof globalThis.ReadableStream && { duplex: "half" },
1305
+ ...body && { body },
1306
+ ...this.fetchOptions ?? {},
1307
+ ...options.fetchOptions ?? {}
1308
+ };
1309
+ return { req, url, timeout: options.timeout };
1310
+ }
1311
+ async buildHeaders({ options, method, bodyHeaders, retryCount }) {
1312
+ let idempotencyHeaders = {};
1313
+ if (this.idempotencyHeader && method !== "get") {
1314
+ if (!options.idempotencyKey)
1315
+ options.idempotencyKey = this.defaultIdempotencyKey();
1316
+ idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
1317
+ }
1318
+ const headers = buildHeaders([
1319
+ idempotencyHeaders,
1320
+ {
1321
+ Accept: "application/json",
1322
+ "User-Agent": this.getUserAgent(),
1323
+ "X-Stainless-Retry-Count": String(retryCount),
1324
+ ...options.timeout ? { "X-Stainless-Timeout": String(Math.trunc(options.timeout / 1000)) } : {},
1325
+ ...getPlatformHeaders()
1326
+ },
1327
+ await this.authHeaders(options),
1328
+ this._options.defaultHeaders,
1329
+ bodyHeaders,
1330
+ options.headers
1331
+ ]);
1332
+ this.validateHeaders(headers);
1333
+ return headers.values;
1334
+ }
1335
+ _makeAbort(controller) {
1336
+ return () => controller.abort();
1337
+ }
1338
+ buildBody({ options: { body, headers: rawHeaders } }) {
1339
+ if (!body) {
1340
+ return { bodyHeaders: undefined, body: undefined };
1341
+ }
1342
+ const headers = buildHeaders([rawHeaders]);
1343
+ if (ArrayBuffer.isView(body) || body instanceof ArrayBuffer || body instanceof DataView || typeof body === "string" && headers.values.has("content-type") || globalThis.Blob && body instanceof globalThis.Blob || body instanceof FormData || body instanceof URLSearchParams || globalThis.ReadableStream && body instanceof globalThis.ReadableStream) {
1344
+ return { bodyHeaders: undefined, body };
1345
+ } else if (typeof body === "object" && ((Symbol.asyncIterator in body) || (Symbol.iterator in body) && ("next" in body) && typeof body.next === "function")) {
1346
+ return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
1347
+ } else {
1348
+ return __classPrivateFieldGet(this, _Supermemory_encoder, "f").call(this, { body, headers });
1349
+ }
1350
+ }
1351
+ }
1352
+ _a = Supermemory, _Supermemory_encoder = new WeakMap, _Supermemory_instances = new WeakSet, _Supermemory_baseURLOverridden = function _Supermemory_baseURLOverridden2() {
1353
+ return this.baseURL !== "https://api.supermemory.ai";
1354
+ };
1355
+ Supermemory.Supermemory = _a;
1356
+ Supermemory.DEFAULT_TIMEOUT = 60000;
1357
+ Supermemory.SupermemoryError = SupermemoryError;
1358
+ Supermemory.APIError = APIError;
1359
+ Supermemory.APIConnectionError = APIConnectionError;
1360
+ Supermemory.APIConnectionTimeoutError = APIConnectionTimeoutError;
1361
+ Supermemory.APIUserAbortError = APIUserAbortError;
1362
+ Supermemory.NotFoundError = NotFoundError;
1363
+ Supermemory.ConflictError = ConflictError;
1364
+ Supermemory.RateLimitError = RateLimitError;
1365
+ Supermemory.BadRequestError = BadRequestError;
1366
+ Supermemory.AuthenticationError = AuthenticationError;
1367
+ Supermemory.InternalServerError = InternalServerError;
1368
+ Supermemory.PermissionDeniedError = PermissionDeniedError;
1369
+ Supermemory.UnprocessableEntityError = UnprocessableEntityError;
1370
+ Supermemory.toFile = toFile;
1371
+ Supermemory.Memories = Memories;
1372
+ Supermemory.Documents = Documents;
1373
+ Supermemory.Search = Search;
1374
+ Supermemory.Settings = Settings;
1375
+ Supermemory.Connections = Connections;
1376
+ // src/client.ts
1377
+ import { createHash, createHmac } from "node:crypto";
1378
+ var INTEGRITY_VERSION = 1;
1379
+ var SEED = "7f2a9c4b8e1d6f3a5c0b9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a";
1380
+ function sha2562(input) {
1381
+ return createHash("sha256").update(input).digest("hex");
1382
+ }
1383
+ function integrityHeaders(apiKey, containerTag) {
1384
+ const contentHash = sha2562(containerTag);
1385
+ const payload = [sha2562(apiKey), contentHash, INTEGRITY_VERSION].join(":");
1386
+ const sig = createHmac("sha256", SEED).update(payload).digest("base64url");
1387
+ return {
1388
+ "X-Content-Hash": contentHash,
1389
+ "X-Request-Integrity": `v${INTEGRITY_VERSION}.${sig}`
1390
+ };
1391
+ }
1392
+ function createClient(apiKey, containerTag = "cursor") {
1393
+ return new Supermemory({
1394
+ apiKey,
1395
+ defaultHeaders: integrityHeaders(apiKey, containerTag)
1396
+ });
1397
+ }
1398
+
1399
+ // src/mcp-server.ts
1400
+ var TOOLS = [
1401
+ {
1402
+ name: "supermemory_search",
1403
+ description: "Search the user's memory for relevant information. Use this to find previously stored knowledge, preferences, and context.",
1404
+ inputSchema: {
1405
+ type: "object",
1406
+ properties: {
1407
+ query: { type: "string", description: "Search query" },
1408
+ container: {
1409
+ type: "string",
1410
+ enum: ["user", "project"],
1411
+ description: "Search user memories or project memories",
1412
+ default: "user"
1413
+ },
1414
+ limit: {
1415
+ type: "number",
1416
+ description: "Max results to return",
1417
+ default: 10
1418
+ }
1419
+ },
1420
+ required: ["query"]
1421
+ }
1422
+ },
1423
+ {
1424
+ name: "supermemory_add",
1425
+ description: "Save information to the user's memory. Use this to remember preferences, facts, decisions, or any knowledge worth persisting.",
1426
+ inputSchema: {
1427
+ type: "object",
1428
+ properties: {
1429
+ content: { type: "string", description: "Content to save" },
1430
+ container: {
1431
+ type: "string",
1432
+ enum: ["user", "project"],
1433
+ description: "Save to user memories or project memories",
1434
+ default: "user"
1435
+ }
1436
+ },
1437
+ required: ["content"]
1438
+ }
1439
+ },
1440
+ {
1441
+ name: "supermemory_profile",
1442
+ description: "Get the user's profile summary — a distilled view of who they are based on their memories.",
1443
+ inputSchema: {
1444
+ type: "object",
1445
+ properties: {
1446
+ query: {
1447
+ type: "string",
1448
+ description: "Optional search query to include relevant results"
1449
+ }
1450
+ }
1451
+ }
1452
+ },
1453
+ {
1454
+ name: "supermemory_list",
1455
+ description: "List stored documents/memories.",
1456
+ inputSchema: {
1457
+ type: "object",
1458
+ properties: {
1459
+ limit: { type: "number", description: "Max items", default: 20 },
1460
+ page: { type: "number", description: "Page number", default: 1 }
1461
+ }
1462
+ }
1463
+ },
1464
+ {
1465
+ name: "supermemory_forget",
1466
+ description: "Forget a specific memory. Use when the user asks to remove or forget something.",
1467
+ inputSchema: {
1468
+ type: "object",
1469
+ properties: {
1470
+ id: { type: "string", description: "Memory ID to forget" },
1471
+ content: {
1472
+ type: "string",
1473
+ description: "Exact content match (if ID unknown)"
1474
+ },
1475
+ container: {
1476
+ type: "string",
1477
+ enum: ["user", "project"],
1478
+ default: "user"
1479
+ }
1480
+ }
1481
+ }
1482
+ }
1483
+ ];
1484
+ function getAuth() {
1485
+ const config = loadConfig();
1486
+ const apiKey = getApiKey(config);
1487
+ if (!apiKey) {
1488
+ throw new Error("Not authenticated. Run `cursor-supermemory login` to connect your account.");
1489
+ }
1490
+ const userTag = getUserTag(config);
1491
+ const projectTag = getProjectTag(process.cwd(), config);
1492
+ return { apiKey, userTag, projectTag };
1493
+ }
1494
+ function containerTag(auth, container) {
1495
+ return container === "project" ? auth.projectTag : auth.userTag;
1496
+ }
1497
+ async function handleSearch(args) {
1498
+ const auth = getAuth();
1499
+ const tag = containerTag(auth, args.container);
1500
+ const client = createClient(auth.apiKey, tag);
1501
+ const result = await client.search.memories({
1502
+ q: args.query,
1503
+ containerTag: tag,
1504
+ limit: args.limit || 10
1505
+ });
1506
+ const formatted = result.results.map((r) => ({
1507
+ id: r.id,
1508
+ memory: r.memory ?? r.chunk ?? "",
1509
+ similarity: r.similarity,
1510
+ updatedAt: r.updatedAt
1511
+ }));
1512
+ return JSON.stringify(formatted, null, 2);
1513
+ }
1514
+ async function handleAdd(args) {
1515
+ const auth = getAuth();
1516
+ const tag = containerTag(auth, args.container);
1517
+ const client = createClient(auth.apiKey, tag);
1518
+ const result = await client.add({
1519
+ content: args.content,
1520
+ containerTag: tag
1521
+ });
1522
+ return JSON.stringify(result, null, 2);
1523
+ }
1524
+ async function handleProfile(args) {
1525
+ const auth = getAuth();
1526
+ const client = createClient(auth.apiKey, auth.userTag);
1527
+ const result = await client.profile({
1528
+ containerTag: auth.userTag,
1529
+ q: args.query
1530
+ });
1531
+ return JSON.stringify(result, null, 2);
1532
+ }
1533
+ async function handleList(args) {
1534
+ const auth = getAuth();
1535
+ const client = createClient(auth.apiKey, auth.userTag);
1536
+ const result = await client.documents.list({
1537
+ limit: args.limit || 20,
1538
+ page: args.page || 1
1539
+ });
1540
+ return JSON.stringify(result, null, 2);
1541
+ }
1542
+ async function handleForget(args) {
1543
+ const auth = getAuth();
1544
+ const tag = containerTag(auth, args.container);
1545
+ const client = createClient(auth.apiKey, tag);
1546
+ const params = {
1547
+ containerTag: containerTag(auth, args.container)
1548
+ };
1549
+ if (args.id)
1550
+ params.id = args.id;
1551
+ if (args.content)
1552
+ params.content = args.content;
1553
+ if (!params.id && !params.content) {
1554
+ throw new Error("Provide either id or content to forget.");
1555
+ }
1556
+ const result = await client.memories.forget(params);
1557
+ return JSON.stringify(result, null, 2);
1558
+ }
1559
+ var HANDLERS = {
1560
+ supermemory_search: handleSearch,
1561
+ supermemory_add: handleAdd,
1562
+ supermemory_profile: handleProfile,
1563
+ supermemory_list: handleList,
1564
+ supermemory_forget: handleForget
1565
+ };
1566
+ function jsonRpcResponse(id, result) {
1567
+ return JSON.stringify({ jsonrpc: "2.0", id, result });
1568
+ }
1569
+ function jsonRpcError(id, code, message) {
1570
+ return JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } });
1571
+ }
1572
+ async function handleMessage(msg) {
1573
+ const { id, method, params } = msg;
1574
+ switch (method) {
1575
+ case "initialize":
1576
+ return jsonRpcResponse(id, {
1577
+ protocolVersion: "2024-11-05",
1578
+ capabilities: { tools: {} },
1579
+ serverInfo: { name: "supermemory", version: "1.0.0" }
1580
+ });
1581
+ case "notifications/initialized":
1582
+ return null;
1583
+ case "tools/list":
1584
+ return jsonRpcResponse(id, { tools: TOOLS });
1585
+ case "tools/call": {
1586
+ const toolName = params?.name;
1587
+ const handler = HANDLERS[toolName];
1588
+ if (!handler) {
1589
+ return jsonRpcError(id, -32601, `Unknown tool: ${toolName}`);
1590
+ }
1591
+ try {
1592
+ const text = await handler(params?.arguments ?? {});
1593
+ return jsonRpcResponse(id, {
1594
+ content: [{ type: "text", text }]
1595
+ });
1596
+ } catch (err) {
1597
+ return jsonRpcResponse(id, {
1598
+ content: [{ type: "text", text: `Error: ${err.message}` }],
1599
+ isError: true
1600
+ });
1601
+ }
1602
+ }
1603
+ default:
1604
+ if (id !== undefined) {
1605
+ return jsonRpcError(id, -32601, `Method not found: ${method}`);
1606
+ }
1607
+ return null;
1608
+ }
1609
+ }
1610
+ async function startMcpServer() {
1611
+ const decoder = new TextDecoder;
1612
+ let buffer = "";
1613
+ for await (const chunk of Bun.stdin.stream()) {
1614
+ buffer += decoder.decode(chunk, { stream: true });
1615
+ while (true) {
1616
+ const headerEnd = buffer.indexOf(`\r
1617
+ \r
1618
+ `);
1619
+ if (headerEnd === -1)
1620
+ break;
1621
+ const header = buffer.slice(0, headerEnd);
1622
+ const match = header.match(/Content-Length:\s*(\d+)/i);
1623
+ if (!match) {
1624
+ buffer = buffer.slice(headerEnd + 4);
1625
+ continue;
1626
+ }
1627
+ const contentLength = parseInt(match[1], 10);
1628
+ const bodyStart = headerEnd + 4;
1629
+ if (buffer.length < bodyStart + contentLength)
1630
+ break;
1631
+ const body = buffer.slice(bodyStart, bodyStart + contentLength);
1632
+ buffer = buffer.slice(bodyStart + contentLength);
1633
+ try {
1634
+ const msg = JSON.parse(body);
1635
+ const response = await handleMessage(msg);
1636
+ if (response) {
1637
+ const out = `Content-Length: ${Buffer.byteLength(response)}\r
1638
+ \r
1639
+ ${response}`;
1640
+ process.stdout.write(out);
1641
+ }
1642
+ } catch (err) {
1643
+ const errResp = jsonRpcError(null, -32700, "Parse error");
1644
+ const out = `Content-Length: ${Buffer.byteLength(errResp)}\r
1645
+ \r
1646
+ ${errResp}`;
1647
+ process.stdout.write(out);
1648
+ }
1649
+ }
1650
+ }
1651
+ }
1652
+ export {
1653
+ startMcpServer
1654
+ };