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.
- package/.cursor-plugin/plugin.json +14 -0
- package/.mcp.json +8 -0
- package/README.md +40 -0
- package/commands/supermemory-config.md +21 -0
- package/commands/supermemory-logout.md +12 -0
- package/commands/supermemory-setup.md +14 -0
- package/dist/cli.js +1767 -0
- package/dist/mcp-server.js +1654 -0
- package/dist/session-end.js +1447 -0
- package/dist/session-start.js +1479 -0
- package/hooks/hooks.json +18 -0
- package/package.json +28 -0
- package/rules/supermemory.mdc +21 -0
- package/skills/memory-init/SKILL.md +13 -0
- package/skills/memory-save/SKILL.md +10 -0
- package/skills/memory-search/SKILL.md +9 -0
|
@@ -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
|
+
});
|