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