@remnic/import-supermemory 0.1.1 → 9.3.515

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/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # @remnic/import-supermemory
2
+
3
+ Import a Supermemory JSON export into Remnic.
4
+
5
+ This package is an optional companion for `@remnic/cli`. Install it only when
6
+ you want to migrate memories out of Supermemory and into Remnic's local memory
7
+ store.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g @remnic/cli
13
+ npm install -g @remnic/import-supermemory
14
+ ```
15
+
16
+ If you use Remnic from a project instead of globally, add both packages to the
17
+ same project:
18
+
19
+ ```bash
20
+ pnpm add @remnic/cli @remnic/import-supermemory
21
+ ```
22
+
23
+ ## Export From Supermemory
24
+
25
+ Export or collect your Supermemory memories as JSON. The importer accepts:
26
+
27
+ - A flat JSON array of memory objects.
28
+ - An object with one of these array keys: `memoryEntries`, `memories`,
29
+ `results`, or `data`.
30
+
31
+ Each memory can provide content in `content`, `memory`, `summary`, or `title`.
32
+ Remnic keeps Supermemory IDs, timestamps, container tags, source metadata, and
33
+ the source file path when they are present.
34
+
35
+ If your Supermemory export is paginated, combine the pages into one flat array
36
+ or into an object like this:
37
+
38
+ ```json
39
+ {
40
+ "memories": [
41
+ {
42
+ "id": "mem_123",
43
+ "content": "The user prefers short release notes.",
44
+ "updatedAt": "2026-05-05T12:00:00Z",
45
+ "containerTags": ["product"]
46
+ }
47
+ ]
48
+ }
49
+ ```
50
+
51
+ ## Dry Run First
52
+
53
+ Run a dry run before writing anything:
54
+
55
+ ```bash
56
+ remnic import --adapter supermemory --file ./supermemory-memories.json --dry-run
57
+ ```
58
+
59
+ When the count and warnings look right, run the import:
60
+
61
+ ```bash
62
+ remnic import --adapter supermemory --file ./supermemory-memories.json
63
+ ```
64
+
65
+ The importer writes records with `sourceLabel: "supermemory"` and
66
+ `metadata.kind: "supermemory_memory"` so you can audit where imported memories
67
+ came from later.
68
+
69
+ ## Privacy
70
+
71
+ Parsing and writing run locally. If your Remnic extraction or consolidation
72
+ pipeline is configured to use a remote model provider, imported content may be
73
+ sent to that provider during normal Remnic processing. Use local model routing
74
+ or gateway settings if you need the full migration path to stay local.
75
+
76
+ ## API
77
+
78
+ ```ts
79
+ import { adapter, supermemoryAdapter } from "@remnic/import-supermemory";
80
+ ```
81
+
82
+ Both exports expose the same Remnic importer adapter:
83
+
84
+ - `name: "supermemory"`
85
+ - `sourceLabel: "supermemory"`
86
+ - `parse(input, options)`
87
+ - `transform(parsed)`
88
+ - `writeTo(target, memories)`
89
+
90
+ ## More Documentation
91
+
92
+ - Remnic importer docs: https://github.com/joshuaswarren/remnic/blob/main/docs/importers.md
93
+ - Supermemory migration guide: https://remnic.ai/guides/import-supermemory/
94
+ - Package source: https://github.com/joshuaswarren/remnic/tree/main/packages/import-supermemory
package/dist/index.d.ts CHANGED
@@ -21,6 +21,10 @@ declare function parseSupermemoryExport(input: unknown, filePath?: string): Pars
21
21
  declare const adapter: ImporterAdapter<ParsedSupermemoryExport>;
22
22
  declare const supermemoryAdapter: ImporterAdapter<ParsedSupermemoryExport>;
23
23
 
24
- declare function transformSupermemoryExport(parsed: ParsedSupermemoryExport): ImportedMemory[];
24
+ interface SupermemoryTransformOptions {
25
+ /** Optional cap on total memories emitted — primarily for tests. */
26
+ maxMemories?: number;
27
+ }
28
+ declare function transformSupermemoryExport(parsed: ParsedSupermemoryExport, options?: SupermemoryTransformOptions): ImportedMemory[];
25
29
 
26
30
  export { adapter, parseSupermemoryExport, supermemoryAdapter, transformSupermemoryExport };
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ function parseSupermemoryExport(input, filePath) {
11
11
  const raw = coerceJson(input);
12
12
  const memories = [];
13
13
  if (Array.isArray(raw)) {
14
- append(memories, raw);
14
+ append(memories, raw, "");
15
15
  return { memories, ...filePath ? { importedFromPath: filePath } : {} };
16
16
  } else if (raw && typeof raw === "object") {
17
17
  const obj = raw;
@@ -22,7 +22,7 @@ function parseSupermemoryExport(input, filePath) {
22
22
  if (!Array.isArray(obj[key])) {
23
23
  throw new Error(`Supermemory export key '${key}' must be an array.`);
24
24
  }
25
- append(memories, obj[key]);
25
+ append(memories, obj[key], key);
26
26
  return { memories, ...filePath ? { importedFromPath: filePath } : {} };
27
27
  }
28
28
  }
@@ -34,9 +34,15 @@ function parseSupermemoryExport(input, filePath) {
34
34
  }
35
35
  throw new Error(`Supermemory export must be a JSON array or object; received ${describeType(raw)}.`);
36
36
  }
37
- function append(dest, src) {
38
- for (const item of src) {
39
- if (item && typeof item === "object") dest.push(item);
37
+ function append(dest, src, key) {
38
+ for (const [index, item] of src.entries()) {
39
+ if (!item || typeof item !== "object" || Array.isArray(item)) {
40
+ const location = key ? `${key}[${index}]` : `[${index}]`;
41
+ throw new Error(
42
+ `Supermemory export entry ${location} must be an object record; received ${describeType(item)}.`
43
+ );
44
+ }
45
+ dest.push(item);
40
46
  }
41
47
  }
42
48
  function coerceJson(input) {
@@ -51,14 +57,17 @@ function coerceJson(input) {
51
57
  }
52
58
  function describeType(value) {
53
59
  if (value === null) return "null";
60
+ if (Array.isArray(value)) return "array";
54
61
  return typeof value;
55
62
  }
56
63
 
57
64
  // src/transform.ts
58
65
  var SUPERMEMORY_SOURCE_LABEL = "supermemory";
59
- function transformSupermemoryExport(parsed) {
66
+ function transformSupermemoryExport(parsed, options = {}) {
60
67
  const out = [];
68
+ const cap = options.maxMemories;
61
69
  for (const row of parsed.memories) {
70
+ if (cap !== void 0 && out.length >= cap) return out;
62
71
  const m = toImported(row, parsed.importedFromPath);
63
72
  if (m) out.push(m);
64
73
  }
@@ -67,12 +76,12 @@ function transformSupermemoryExport(parsed) {
67
76
  function toImported(row, importedFromPath) {
68
77
  const content = pickContent(row);
69
78
  if (!content) return void 0;
70
- const sourceId = pickSourceId(row.id) ?? content.slice(0, 64);
79
+ const sourceId = pickSourceId(row.id);
71
80
  const sourceTimestamp = pickTimestamp(row);
72
81
  return {
73
82
  content,
74
83
  sourceLabel: SUPERMEMORY_SOURCE_LABEL,
75
- sourceId,
84
+ ...sourceId ? { sourceId } : {},
76
85
  ...sourceTimestamp ? { sourceTimestamp } : {},
77
86
  ...importedFromPath ? { importedFromPath } : {},
78
87
  metadata: {
@@ -84,12 +93,28 @@ function toImported(row, importedFromPath) {
84
93
  }
85
94
  function pickTimestamp(row) {
86
95
  for (const timestamp of [row.updatedAt, row.createdAt]) {
87
- if (typeof timestamp === "string" && timestamp.trim().length > 0) {
88
- return timestamp.trim();
96
+ const parsed = pickValidTimestamp(timestamp);
97
+ if (parsed) {
98
+ return parsed;
89
99
  }
90
100
  }
91
101
  return void 0;
92
102
  }
103
+ function pickValidTimestamp(value) {
104
+ if (typeof value !== "string") return void 0;
105
+ const trimmed = value.trim();
106
+ if (trimmed.length === 0) return void 0;
107
+ const match = /^(\d{4})-(\d{2})-(\d{2})T/.exec(trimmed);
108
+ if (!match) return void 0;
109
+ const parsed = Date.parse(trimmed);
110
+ if (!Number.isFinite(parsed)) return void 0;
111
+ const date = new Date(parsed);
112
+ const [, year, month, day] = match;
113
+ if (date.getUTCFullYear() !== Number(year) || date.getUTCMonth() + 1 !== Number(month) || date.getUTCDate() !== Number(day)) {
114
+ return void 0;
115
+ }
116
+ return trimmed;
117
+ }
93
118
  function pickSourceId(value) {
94
119
  if (typeof value === "string") {
95
120
  const trimmed = value.trim();
@@ -114,8 +139,10 @@ var adapter = {
114
139
  parse(input, options) {
115
140
  return parseSupermemoryExport(input, options?.filePath);
116
141
  },
117
- transform(parsed) {
118
- return transformSupermemoryExport(parsed);
142
+ transform(parsed, options) {
143
+ return transformSupermemoryExport(parsed, {
144
+ ...options?.maxMemories !== void 0 ? { maxMemories: options.maxMemories } : {}
145
+ });
119
146
  },
120
147
  writeTo(target, memories) {
121
148
  return defaultWriteMemoriesToOrchestrator(target, memories);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapter.ts","../src/parser.ts","../src/transform.ts"],"sourcesContent":["import type { ImporterAdapter } from \"@remnic/core\";\nimport { defaultWriteMemoriesToOrchestrator } from \"@remnic/core\";\n\nimport { parseSupermemoryExport, type ParsedSupermemoryExport } from \"./parser.js\";\nimport { SUPERMEMORY_SOURCE_LABEL, transformSupermemoryExport } from \"./transform.js\";\n\nexport const adapter: ImporterAdapter<ParsedSupermemoryExport> = {\n name: \"supermemory\",\n sourceLabel: SUPERMEMORY_SOURCE_LABEL,\n parse(input, options) {\n return parseSupermemoryExport(input, options?.filePath);\n },\n transform(parsed) {\n return transformSupermemoryExport(parsed);\n },\n writeTo(target, memories) {\n return defaultWriteMemoriesToOrchestrator(target, memories);\n },\n};\n\nexport const supermemoryAdapter = adapter;\n","export interface SupermemoryRecord {\n id?: string;\n memory?: string;\n content?: string;\n summary?: string;\n title?: string;\n createdAt?: string;\n updatedAt?: string;\n containerTags?: string[];\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ParsedSupermemoryExport {\n memories: SupermemoryRecord[];\n importedFromPath?: string;\n}\n\nexport function parseSupermemoryExport(input: unknown, filePath?: string): ParsedSupermemoryExport {\n if (input == null) {\n throw new Error(\"Supermemory import requires JSON input. Pass --file <supermemory-export.json>.\");\n }\n\n const raw = coerceJson(input);\n const memories: SupermemoryRecord[] = [];\n\n if (Array.isArray(raw)) {\n append(memories, raw);\n return { memories, ...(filePath ? { importedFromPath: filePath } : {}) };\n } else if (raw && typeof raw === \"object\") {\n const obj = raw as Record<string, unknown>;\n let sawKnownKey = false;\n for (const key of [\"memoryEntries\", \"memories\", \"results\", \"data\"] as const) {\n if (key in obj) {\n sawKnownKey = true;\n if (!Array.isArray(obj[key])) {\n throw new Error(`Supermemory export key '${key}' must be an array.`);\n }\n append(memories, obj[key] as unknown[]);\n return { memories, ...(filePath ? { importedFromPath: filePath } : {}) };\n }\n }\n if (!sawKnownKey) {\n throw new Error(\n \"Supermemory export object has no recognized memory key. Expected one of 'memoryEntries', 'memories', 'results', or 'data'.\",\n );\n }\n }\n\n throw new Error(`Supermemory export must be a JSON array or object; received ${describeType(raw)}.`);\n}\n\nfunction append(dest: SupermemoryRecord[], src: unknown[]): void {\n for (const item of src) {\n if (item && typeof item === \"object\") dest.push(item as SupermemoryRecord);\n }\n}\n\nfunction coerceJson(input: unknown): unknown {\n if (typeof input !== \"string\") return input;\n\n try {\n return JSON.parse(input);\n } catch (err) {\n throw new Error(\n `Supermemory export is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\nfunction describeType(value: unknown): string {\n if (value === null) return \"null\";\n return typeof value;\n}\n","import type { ImportedMemory } from \"@remnic/core\";\nimport type { ParsedSupermemoryExport, SupermemoryRecord } from \"./parser.js\";\n\nexport const SUPERMEMORY_SOURCE_LABEL = \"supermemory\";\n\nexport function transformSupermemoryExport(parsed: ParsedSupermemoryExport): ImportedMemory[] {\n const out: ImportedMemory[] = [];\n for (const row of parsed.memories) {\n const m = toImported(row, parsed.importedFromPath);\n if (m) out.push(m);\n }\n return out;\n}\n\nfunction toImported(row: SupermemoryRecord, importedFromPath?: string): ImportedMemory | undefined {\n const content = pickContent(row);\n if (!content) return undefined;\n const sourceId = pickSourceId(row.id) ?? content.slice(0, 64);\n const sourceTimestamp = pickTimestamp(row);\n return {\n content,\n sourceLabel: SUPERMEMORY_SOURCE_LABEL,\n sourceId,\n ...(sourceTimestamp ? { sourceTimestamp } : {}),\n ...(importedFromPath ? { importedFromPath } : {}),\n metadata: {\n kind: \"supermemory_memory\",\n ...(Array.isArray(row.containerTags) && row.containerTags.length > 0\n ? { containerTags: [...row.containerTags] }\n : {}),\n ...(row.metadata && typeof row.metadata === \"object\" ? { sourceMetadata: row.metadata } : {}),\n },\n };\n}\n\nfunction pickTimestamp(row: SupermemoryRecord): string | undefined {\n for (const timestamp of [row.updatedAt, row.createdAt]) {\n if (typeof timestamp === \"string\" && timestamp.trim().length > 0) {\n return timestamp.trim();\n }\n }\n return undefined;\n}\n\nfunction pickSourceId(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return String(value);\n }\n return undefined;\n}\n\nfunction pickContent(row: SupermemoryRecord): string | undefined {\n for (const c of [row.content, row.memory, row.summary, row.title]) {\n if (typeof c === \"string\" && c.trim().length > 0) return c.trim();\n }\n return undefined;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/adapter.ts","../src/parser.ts","../src/transform.ts"],"sourcesContent":["import type { ImporterAdapter, ImporterTransformOptions } from \"@remnic/core\";\nimport { defaultWriteMemoriesToOrchestrator } from \"@remnic/core\";\n\nimport { parseSupermemoryExport, type ParsedSupermemoryExport } from \"./parser.js\";\nimport { SUPERMEMORY_SOURCE_LABEL, transformSupermemoryExport } from \"./transform.js\";\n\nexport const adapter: ImporterAdapter<ParsedSupermemoryExport> = {\n name: \"supermemory\",\n sourceLabel: SUPERMEMORY_SOURCE_LABEL,\n parse(input, options) {\n return parseSupermemoryExport(input, options?.filePath);\n },\n transform(\n parsed,\n options?: ImporterTransformOptions,\n ) {\n return transformSupermemoryExport(parsed, {\n ...(options?.maxMemories !== undefined\n ? { maxMemories: options.maxMemories }\n : {}),\n });\n },\n writeTo(target, memories) {\n return defaultWriteMemoriesToOrchestrator(target, memories);\n },\n};\n\nexport const supermemoryAdapter = adapter;\n","export interface SupermemoryRecord {\n id?: string;\n memory?: string;\n content?: string;\n summary?: string;\n title?: string;\n createdAt?: string;\n updatedAt?: string;\n containerTags?: string[];\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ParsedSupermemoryExport {\n memories: SupermemoryRecord[];\n importedFromPath?: string;\n}\n\nexport function parseSupermemoryExport(input: unknown, filePath?: string): ParsedSupermemoryExport {\n if (input == null) {\n throw new Error(\"Supermemory import requires JSON input. Pass --file <supermemory-export.json>.\");\n }\n\n const raw = coerceJson(input);\n const memories: SupermemoryRecord[] = [];\n\n if (Array.isArray(raw)) {\n append(memories, raw, \"\");\n return { memories, ...(filePath ? { importedFromPath: filePath } : {}) };\n } else if (raw && typeof raw === \"object\") {\n const obj = raw as Record<string, unknown>;\n let sawKnownKey = false;\n for (const key of [\"memoryEntries\", \"memories\", \"results\", \"data\"] as const) {\n if (key in obj) {\n sawKnownKey = true;\n if (!Array.isArray(obj[key])) {\n throw new Error(`Supermemory export key '${key}' must be an array.`);\n }\n append(memories, obj[key] as unknown[], key);\n return { memories, ...(filePath ? { importedFromPath: filePath } : {}) };\n }\n }\n if (!sawKnownKey) {\n throw new Error(\n \"Supermemory export object has no recognized memory key. Expected one of 'memoryEntries', 'memories', 'results', or 'data'.\",\n );\n }\n }\n\n throw new Error(`Supermemory export must be a JSON array or object; received ${describeType(raw)}.`);\n}\n\nfunction append(dest: SupermemoryRecord[], src: unknown[], key: string): void {\n for (const [index, item] of src.entries()) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) {\n const location = key ? `${key}[${index}]` : `[${index}]`;\n throw new Error(\n `Supermemory export entry ${location} must be an object record; received ${describeType(item)}.`,\n );\n }\n dest.push(item as SupermemoryRecord);\n }\n}\n\nfunction coerceJson(input: unknown): unknown {\n if (typeof input !== \"string\") return input;\n\n try {\n return JSON.parse(input);\n } catch (err) {\n throw new Error(\n `Supermemory export is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\nfunction describeType(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n","import type { ImportedMemory } from \"@remnic/core\";\nimport type { ParsedSupermemoryExport, SupermemoryRecord } from \"./parser.js\";\n\nexport const SUPERMEMORY_SOURCE_LABEL = \"supermemory\";\n\nexport interface SupermemoryTransformOptions {\n /** Optional cap on total memories emitted — primarily for tests. */\n maxMemories?: number;\n}\n\nexport function transformSupermemoryExport(\n parsed: ParsedSupermemoryExport,\n options: SupermemoryTransformOptions = {},\n): ImportedMemory[] {\n const out: ImportedMemory[] = [];\n const cap = options.maxMemories;\n for (const row of parsed.memories) {\n if (cap !== undefined && out.length >= cap) return out;\n const m = toImported(row, parsed.importedFromPath);\n if (m) out.push(m);\n }\n return out;\n}\n\nfunction toImported(row: SupermemoryRecord, importedFromPath?: string): ImportedMemory | undefined {\n const content = pickContent(row);\n if (!content) return undefined;\n const sourceId = pickSourceId(row.id);\n const sourceTimestamp = pickTimestamp(row);\n return {\n content,\n sourceLabel: SUPERMEMORY_SOURCE_LABEL,\n ...(sourceId ? { sourceId } : {}),\n ...(sourceTimestamp ? { sourceTimestamp } : {}),\n ...(importedFromPath ? { importedFromPath } : {}),\n metadata: {\n kind: \"supermemory_memory\",\n ...(Array.isArray(row.containerTags) && row.containerTags.length > 0\n ? { containerTags: [...row.containerTags] }\n : {}),\n ...(row.metadata && typeof row.metadata === \"object\" ? { sourceMetadata: row.metadata } : {}),\n },\n };\n}\n\nfunction pickTimestamp(row: SupermemoryRecord): string | undefined {\n for (const timestamp of [row.updatedAt, row.createdAt]) {\n const parsed = pickValidTimestamp(timestamp);\n if (parsed) {\n return parsed;\n }\n }\n return undefined;\n}\n\nfunction pickValidTimestamp(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})T/.exec(trimmed);\n if (!match) return undefined;\n const parsed = Date.parse(trimmed);\n if (!Number.isFinite(parsed)) return undefined;\n const date = new Date(parsed);\n const [, year, month, day] = match;\n if (\n date.getUTCFullYear() !== Number(year) ||\n date.getUTCMonth() + 1 !== Number(month) ||\n date.getUTCDate() !== Number(day)\n ) {\n return undefined;\n }\n return trimmed;\n}\n\nfunction pickSourceId(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return String(value);\n }\n return undefined;\n}\n\nfunction pickContent(row: SupermemoryRecord): string | undefined {\n for (const c of [row.content, row.memory, row.summary, row.title]) {\n if (typeof c === \"string\" && c.trim().length > 0) return c.trim();\n }\n return undefined;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/import-supermemory",
3
- "version": "0.1.1",
3
+ "version": "9.3.515",
4
4
  "description": "Import Supermemory exports into Remnic",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -19,13 +19,13 @@
19
19
  "provenance": true
20
20
  },
21
21
  "peerDependencies": {
22
- "@remnic/core": "^1.1.9"
22
+ "@remnic/core": "^9.3.515"
23
23
  },
24
24
  "devDependencies": {
25
25
  "tsup": "^8.0.0",
26
26
  "tsx": "^4.0.0",
27
27
  "typescript": "^5.7.0",
28
- "@remnic/core": "1.1.9"
28
+ "@remnic/core": "9.3.515"
29
29
  },
30
30
  "license": "MIT",
31
31
  "repository": {
@@ -40,8 +40,9 @@
40
40
  "import"
41
41
  ],
42
42
  "scripts": {
43
- "build": "tsup src/index.ts --format esm --dts",
43
+ "build": "tsup src/index.ts --format esm --dts --clean",
44
+ "precheck-types": "node ../../scripts/ensure-bench-build-deps.mjs",
44
45
  "check-types": "tsc --noEmit",
45
- "test": "tsx --test src/parser.test.ts src/transform.test.ts src/adapter.test.ts"
46
+ "test": "tsx --test src/parser.test.ts src/transform.test.ts src/adapter.test.ts src/build-script.test.ts"
46
47
  }
47
48
  }