diff --git a/apps/docs/self-hosting/backup-and-export.mdx b/apps/docs/self-hosting/backup-and-export.mdx index d217f3aa..57184fa7 100644 --- a/apps/docs/self-hosting/backup-and-export.mdx +++ b/apps/docs/self-hosting/backup-and-export.mdx @@ -75,9 +75,24 @@ Authorization: Bearer ## Full Export Scripts -### 1. Using `@supermemory/tools` (Node.js / Bun) +### 1. Using the CLI (`supermemory-export`) -If you use `@supermemory/tools`, use the built-in export helpers: +You can export memories directly from your terminal using the CLI packaged with `@supermemory/tools`: + +```bash +# Export to stdout as JSON +bunx @supermemory/tools supermemory-export --tag user_123 + +# Export to a JSON file from local self-hosted server +bunx @supermemory/tools supermemory-export --tag user_123 --out ./memories.json --url http://localhost:6767 + +# Export as formatted Markdown notes +bunx @supermemory/tools supermemory-export --tag user_123 --format markdown --out ./memories.md +``` + +### 2. Programmatic Export (TypeScript / Bun) + +If you use `@supermemory/tools` in your application: ```typescript import { @@ -100,7 +115,7 @@ const markdownNotes = await exportMemoriesAsMarkdown("user_123", options); await Bun.write("memories-export.md", markdownNotes); ``` -### 2. Standalone Python Export Script +### 3. Standalone Python Export Script Run this script against your local server to export all memories to JSON: @@ -160,7 +175,7 @@ if __name__ == "__main__": print(f"Exported {len(memories)} memories to {output_file}") ``` -### 3. Quick cURL Export +### 4. Quick cURL Export ```bash curl -s -X POST "http://localhost:6767/v4/memories/list" \ diff --git a/packages/tools/bin/supermemory-export.ts b/packages/tools/bin/supermemory-export.ts new file mode 100644 index 00000000..818a4dad --- /dev/null +++ b/packages/tools/bin/supermemory-export.ts @@ -0,0 +1,125 @@ +#!/usr/bin/env bun +/** + * CLI to export extracted memories from Supermemory (self-hosted or hosted platform). + * + * Usage: + * bun run ./bin/supermemory-export.ts --tag user_123 [--format json|markdown] [--out backup.json] [--url http://localhost:6767] + */ + +import { parseArgs } from "node:util" +import { writeFile } from "node:fs/promises" +import { + exportMemoriesAsJson, + exportMemoriesAsMarkdown, +} from "../src/shared/export-memories" + +function printHelp() { + console.log(` +Supermemory Memory Export CLI +============================= +Export extracted memories and facts from Supermemory (self-hosted or cloud platform). + +Usage: + supermemory-export --tag [options] + +Options: + -t, --tag Container tag to export memories from (required) + -f, --format Output format: 'json' (default) or 'markdown' + -o, --out Output file path (default: stdout) + -u, --url Supermemory server base URL (default: $SUPERMEMORY_API_URL or http://localhost:6767) + -k, --key Supermemory API key (default: $SUPERMEMORY_API_KEY) + --include-forgotten Include soft-forgotten memories in export + -h, --help Show this help message + +Examples: + # Export to stdout as JSON + supermemory-export --tag user_123 + + # Export to a JSON backup file from self-hosted server + supermemory-export --tag user_123 --out ./backup.json --url http://localhost:6767 + + # Export as Markdown notes from cloud platform + supermemory-export --tag user_123 --format markdown --out ./notes.md --url https://api.supermemory.ai --key sm_... +`) +} + +async function main() { + let parsed: ReturnType + try { + parsed = parseArgs({ + args: process.argv.slice(2), + options: { + tag: { type: "string", short: "t" }, + format: { type: "string", short: "f", default: "json" }, + out: { type: "string", short: "o" }, + url: { + type: "string", + short: "u", + default: process.env.SUPERMEMORY_API_URL || "http://localhost:6767", + }, + key: { + type: "string", + short: "k", + default: process.env.SUPERMEMORY_API_KEY || "", + }, + "include-forgotten": { type: "boolean", default: false }, + help: { type: "boolean", short: "h" }, + }, + allowPositionals: true, + }) + } catch (err: unknown) { + console.error(`Error: ${err instanceof Error ? err.message : String(err)}`) + printHelp() + process.exit(1) + } + + const { values } = parsed + + if (values.help) { + printHelp() + process.exit(0) + } + + const tag = values.tag + if (!tag) { + console.error("Error: --tag is required.") + printHelp() + process.exit(1) + } + + const format = values.format?.toLowerCase() || "json" + const baseUrl = values.url || "http://localhost:6767" + const apiKey = values.key || "" + const includeForgotten = Boolean(values["include-forgotten"]) + + try { + let output: string + if (format === "markdown" || format === "md") { + output = await exportMemoriesAsMarkdown(tag, { + baseUrl, + apiKey, + includeForgotten, + }) + } else { + output = await exportMemoriesAsJson(tag, { + baseUrl, + apiKey, + includeForgotten, + }) + } + + if (values.out) { + await writeFile(values.out, output, "utf-8") + console.error(`✓ Successfully exported memories for '${tag}' to ${values.out}`) + } else { + process.stdout.write(output + "\n") + } + } catch (err: unknown) { + console.error( + `Failed to export memories: ${err instanceof Error ? err.message : String(err)}`, + ) + process.exit(1) + } +} + +main() diff --git a/packages/tools/package.json b/packages/tools/package.json index 05f6b6f2..6190ac19 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -41,11 +41,15 @@ "optional": true } }, + "bin": { + "supermemory-export": "./bin/supermemory-export.ts" + }, "main": "./dist/index.js", "module": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ - "dist" + "dist", + "bin" ], "exports": { ".": "./dist/index.js",