@memextend/cursor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/cli/capture.ts"],"names":[],"mappings":""}
@@ -0,0 +1,222 @@
1
+ // packages/adapters/cursor/src/cli/capture.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ /**
4
+ * Session Capture CLI for Cursor
5
+ *
6
+ * Since Cursor doesn't have hooks like Claude Code, this CLI tool provides
7
+ * a way to capture session content manually or via automation.
8
+ *
9
+ * Usage:
10
+ * memextend-cursor-capture [options]
11
+ * memextend-cursor-capture --file <path> # Capture from file
12
+ * memextend-cursor-capture --stdin # Capture from stdin
13
+ * memextend-cursor-capture --content "..." # Capture direct content
14
+ * memextend-cursor-capture --workspace <dir> # Specify workspace
15
+ *
16
+ * This can be integrated with Cursor's tasks or keyboard shortcuts.
17
+ */
18
+ import { randomUUID, createHash } from 'crypto';
19
+ import { existsSync } from 'fs';
20
+ import { readFile } from 'fs/promises';
21
+ import { join, basename, resolve } from 'path';
22
+ import { homedir } from 'os';
23
+ import { execSync } from 'child_process';
24
+ import { SQLiteStorage, LanceDBStorage, createEmbedFunction } from '@memextend/core';
25
+ const MEMEXTEND_DIR = join(homedir(), '.memextend');
26
+ const DB_PATH = join(MEMEXTEND_DIR, 'memextend.db');
27
+ const VECTORS_PATH = join(MEMEXTEND_DIR, 'vectors');
28
+ const MODELS_PATH = join(MEMEXTEND_DIR, 'models');
29
+ function parseArgs() {
30
+ const args = process.argv.slice(2);
31
+ const options = {};
32
+ for (let i = 0; i < args.length; i++) {
33
+ const arg = args[i];
34
+ const next = args[i + 1];
35
+ switch (arg) {
36
+ case '--content':
37
+ case '-c':
38
+ options.content = next;
39
+ i++;
40
+ break;
41
+ case '--file':
42
+ case '-f':
43
+ options.file = next;
44
+ i++;
45
+ break;
46
+ case '--stdin':
47
+ case '-i':
48
+ options.stdin = true;
49
+ break;
50
+ case '--workspace':
51
+ case '-w':
52
+ options.workspace = next;
53
+ i++;
54
+ break;
55
+ case '--type':
56
+ case '-t':
57
+ options.type = next;
58
+ i++;
59
+ break;
60
+ case '--source':
61
+ case '-s':
62
+ options.sourceTool = next;
63
+ i++;
64
+ break;
65
+ case '--session':
66
+ options.sessionId = next;
67
+ i++;
68
+ break;
69
+ case '--quiet':
70
+ case '-q':
71
+ options.quiet = true;
72
+ break;
73
+ case '--help':
74
+ case '-h':
75
+ printHelp();
76
+ process.exit(0);
77
+ }
78
+ }
79
+ return options;
80
+ }
81
+ function printHelp() {
82
+ console.log(`
83
+ memextend-cursor-capture - Capture session content to memory
84
+
85
+ USAGE:
86
+ memextend-cursor-capture [OPTIONS]
87
+
88
+ OPTIONS:
89
+ -c, --content <text> Content to capture directly
90
+ -f, --file <path> Read content from file
91
+ -i, --stdin Read content from stdin
92
+ -w, --workspace <dir> Workspace directory (default: cwd)
93
+ -t, --type <type> Memory type: summary, tool_capture, manual (default: manual)
94
+ -s, --source <tool> Source tool name (for tool_capture type)
95
+ --session <id> Session ID for grouping captures
96
+ -q, --quiet Suppress output
97
+ -h, --help Show this help
98
+
99
+ EXAMPLES:
100
+ # Capture direct content
101
+ memextend-cursor-capture -c "Implemented Redis caching for user sessions"
102
+
103
+ # Capture from file
104
+ memextend-cursor-capture -f session-notes.txt
105
+
106
+ # Capture from pipe (e.g., from AI output)
107
+ echo "Fixed authentication bug" | memextend-cursor-capture --stdin
108
+
109
+ # Capture with workspace context
110
+ memextend-cursor-capture -c "Added API endpoints" -w /path/to/project
111
+
112
+ INTEGRATION:
113
+ Add as a Cursor task in tasks.json or bind to a keyboard shortcut.
114
+ `);
115
+ }
116
+ async function readStdin() {
117
+ const chunks = [];
118
+ for await (const chunk of process.stdin) {
119
+ chunks.push(chunk);
120
+ }
121
+ return Buffer.concat(chunks).toString('utf-8');
122
+ }
123
+ function getProjectId(cwd) {
124
+ try {
125
+ const gitRoot = execSync('git rev-parse --show-toplevel', {
126
+ cwd,
127
+ encoding: 'utf-8',
128
+ stdio: ['pipe', 'pipe', 'pipe']
129
+ }).trim();
130
+ return createHash('sha256').update(gitRoot).digest('hex').slice(0, 16);
131
+ }
132
+ catch {
133
+ return createHash('sha256').update(cwd).digest('hex').slice(0, 16);
134
+ }
135
+ }
136
+ async function main() {
137
+ const options = parseArgs();
138
+ // Check if memextend is initialized
139
+ if (!existsSync(DB_PATH)) {
140
+ console.error('Error: memextend not initialized. Run `memextend init` first.');
141
+ process.exit(1);
142
+ }
143
+ // Get content from specified source
144
+ let content;
145
+ if (options.content) {
146
+ content = options.content;
147
+ }
148
+ else if (options.file) {
149
+ if (!existsSync(options.file)) {
150
+ console.error(`Error: File not found: ${options.file}`);
151
+ process.exit(1);
152
+ }
153
+ content = await readFile(options.file, 'utf-8');
154
+ }
155
+ else if (options.stdin) {
156
+ content = await readStdin();
157
+ }
158
+ else {
159
+ console.error('Error: No content source specified. Use --content, --file, or --stdin');
160
+ console.error('Run with --help for usage information.');
161
+ process.exit(1);
162
+ }
163
+ content = content.trim();
164
+ if (!content || content.length < 5) {
165
+ console.error('Error: Content is empty or too short (minimum 5 characters)');
166
+ process.exit(1);
167
+ }
168
+ // Determine workspace
169
+ const workspace = options.workspace ? resolve(options.workspace) : process.cwd();
170
+ const projectId = getProjectId(workspace);
171
+ // Initialize storage
172
+ const sqlite = new SQLiteStorage(DB_PATH);
173
+ const lancedb = await LanceDBStorage.create(VECTORS_PATH);
174
+ const embedder = await createEmbedFunction(MODELS_PATH);
175
+ try {
176
+ // Ensure project is registered
177
+ const project = sqlite.getProject(projectId);
178
+ if (!project) {
179
+ sqlite.insertProject({
180
+ id: projectId,
181
+ name: basename(workspace),
182
+ path: workspace,
183
+ createdAt: new Date().toISOString()
184
+ });
185
+ }
186
+ // Create memory
187
+ const memoryId = randomUUID();
188
+ const memory = {
189
+ id: memoryId,
190
+ projectId,
191
+ content,
192
+ type: options.type ?? 'manual',
193
+ sourceTool: options.sourceTool ?? null,
194
+ createdAt: new Date().toISOString(),
195
+ sessionId: options.sessionId ?? null,
196
+ metadata: null,
197
+ };
198
+ // Store in SQLite
199
+ sqlite.insertMemory(memory);
200
+ // Generate and store embedding
201
+ const vector = await embedder.embed(content);
202
+ await lancedb.insertVector(memoryId, vector);
203
+ if (!options.quiet) {
204
+ console.log(`Memory captured successfully!`);
205
+ console.log(` ID: ${memoryId}`);
206
+ console.log(` Project: ${basename(workspace)}`);
207
+ console.log(` Type: ${memory.type}`);
208
+ console.log(` Content: ${content.slice(0, 100)}${content.length > 100 ? '...' : ''}`);
209
+ }
210
+ }
211
+ finally {
212
+ // Cleanup
213
+ sqlite.close();
214
+ await lancedb.close();
215
+ await embedder.close();
216
+ }
217
+ }
218
+ main().catch(error => {
219
+ console.error('Error:', error.message);
220
+ process.exit(1);
221
+ });
222
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/cli/capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/cli/index.ts
22
+ var cli_exports = {};
23
+ __export(cli_exports, {
24
+ setupCursor: () => setupCursor,
25
+ showStatus: () => showStatus
26
+ });
27
+ module.exports = __toCommonJS(cli_exports);
28
+ var import_fs = require("fs");
29
+ var import_promises = require("fs/promises");
30
+ var import_path = require("path");
31
+ var import_os = require("os");
32
+ var import_child_process = require("child_process");
33
+ var MEMEXTEND_DIR = (0, import_path.join)((0, import_os.homedir)(), ".memextend");
34
+ var DB_PATH = (0, import_path.join)(MEMEXTEND_DIR, "memextend.db");
35
+ var CURSOR_CONFIG_PATHS = [
36
+ (0, import_path.join)((0, import_os.homedir)(), ".cursor", "mcp.json"),
37
+ (0, import_path.join)((0, import_os.homedir)(), "Library", "Application Support", "Cursor", "User", "mcp.json"),
38
+ // macOS
39
+ (0, import_path.join)((0, import_os.homedir)(), ".config", "Cursor", "User", "mcp.json"),
40
+ // Linux
41
+ (0, import_path.join)((0, import_os.homedir)(), "AppData", "Roaming", "Cursor", "User", "mcp.json")
42
+ // Windows
43
+ ];
44
+ function getScriptDir() {
45
+ return __dirname;
46
+ }
47
+ function getMcpServerPath() {
48
+ const scriptDir = getScriptDir();
49
+ return (0, import_path.join)(scriptDir, "..", "mcp", "server.cjs");
50
+ }
51
+ function findCursorConfigPath() {
52
+ for (const configPath of CURSOR_CONFIG_PATHS) {
53
+ const configDir = (0, import_path.dirname)(configPath);
54
+ if ((0, import_fs.existsSync)(configDir)) {
55
+ return configPath;
56
+ }
57
+ }
58
+ return null;
59
+ }
60
+ async function setupCursor() {
61
+ console.log("Setting up memextend for Cursor...\n");
62
+ if (!(0, import_fs.existsSync)(DB_PATH)) {
63
+ console.log("Warning: memextend not initialized. Run `memextend init` first.\n");
64
+ }
65
+ const configPath = findCursorConfigPath();
66
+ if (!configPath) {
67
+ console.log("Could not find Cursor configuration directory.");
68
+ console.log("Please ensure Cursor is installed and has been run at least once.\n");
69
+ console.log("Manual setup instructions:");
70
+ printManualSetupInstructions();
71
+ return;
72
+ }
73
+ const mcpServerPath = getMcpServerPath();
74
+ if (!(0, import_fs.existsSync)(mcpServerPath)) {
75
+ console.log(`Error: MCP server not found at ${mcpServerPath}`);
76
+ console.log("Please run `npm run build` in the @memextend/cursor package first.\n");
77
+ return;
78
+ }
79
+ let config = { mcpServers: {} };
80
+ if ((0, import_fs.existsSync)(configPath)) {
81
+ try {
82
+ const content = await (0, import_promises.readFile)(configPath, "utf-8");
83
+ config = JSON.parse(content);
84
+ if (!config.mcpServers) {
85
+ config.mcpServers = {};
86
+ }
87
+ } catch (error) {
88
+ console.log("Warning: Could not parse existing mcp.json, creating new one");
89
+ }
90
+ }
91
+ if (config.mcpServers.memextend) {
92
+ console.log("memextend is already configured in Cursor.");
93
+ console.log(`Current path: ${config.mcpServers.memextend.args?.[0] || "unknown"}`);
94
+ console.log("\nTo update, remove the existing entry and run setup again.");
95
+ return;
96
+ }
97
+ config.mcpServers.memextend = {
98
+ command: "node",
99
+ args: [(0, import_path.resolve)(mcpServerPath)]
100
+ };
101
+ await (0, import_promises.mkdir)((0, import_path.dirname)(configPath), { recursive: true });
102
+ await (0, import_promises.writeFile)(configPath, JSON.stringify(config, null, 2));
103
+ console.log("Success! memextend MCP server added to Cursor.\n");
104
+ console.log(`Configuration file: ${configPath}`);
105
+ console.log(`MCP server path: ${(0, import_path.resolve)(mcpServerPath)}
106
+ `);
107
+ console.log("Next steps:");
108
+ console.log("1. Restart Cursor to load the new MCP server");
109
+ console.log("2. In Cursor, ask Claude to use memextend tools");
110
+ console.log('3. Try: "Search my memories for [topic]" or "Save this to memory"');
111
+ }
112
+ function printManualSetupInstructions() {
113
+ const mcpServerPath = getMcpServerPath();
114
+ console.log(`
115
+ Create or edit ~/.cursor/mcp.json with the following content:
116
+
117
+ {
118
+ "mcpServers": {
119
+ "memextend": {
120
+ "command": "node",
121
+ "args": ["${(0, import_path.resolve)(mcpServerPath)}"]
122
+ }
123
+ }
124
+ }
125
+
126
+ Then restart Cursor to load the MCP server.
127
+ `);
128
+ }
129
+ async function showStatus() {
130
+ console.log("memextend Cursor Adapter Status\n");
131
+ if ((0, import_fs.existsSync)(DB_PATH)) {
132
+ console.log("[OK] memextend initialized");
133
+ } else {
134
+ console.log("[!] memextend not initialized - run `memextend init`");
135
+ }
136
+ const configPath = findCursorConfigPath();
137
+ if (configPath && (0, import_fs.existsSync)(configPath)) {
138
+ try {
139
+ const content = await (0, import_promises.readFile)(configPath, "utf-8");
140
+ const config = JSON.parse(content);
141
+ if (config.mcpServers?.memextend) {
142
+ console.log("[OK] Cursor MCP configured");
143
+ console.log(` Config: ${configPath}`);
144
+ } else {
145
+ console.log("[!] Cursor MCP not configured - run `memextend-cursor setup`");
146
+ }
147
+ } catch {
148
+ console.log("[!] Could not read Cursor config");
149
+ }
150
+ } else {
151
+ console.log("[!] Cursor config not found");
152
+ }
153
+ const mcpServerPath = getMcpServerPath();
154
+ if ((0, import_fs.existsSync)(mcpServerPath)) {
155
+ console.log("[OK] MCP server built");
156
+ console.log(` Path: ${(0, import_path.resolve)(mcpServerPath)}`);
157
+ } else {
158
+ console.log("[!] MCP server not built - run `npm run build`");
159
+ }
160
+ console.log("");
161
+ }
162
+ function printHelp() {
163
+ console.log(`
164
+ memextend-cursor - Cursor IDE adapter for memextend
165
+
166
+ USAGE:
167
+ memextend-cursor <command> [options]
168
+
169
+ COMMANDS:
170
+ setup Configure Cursor to use memextend MCP server
171
+ status Check memextend and Cursor configuration status
172
+ capture Capture content to memory (alias for memextend-cursor-capture)
173
+ inject Get context for session (alias for memextend-cursor-inject)
174
+ help Show this help message
175
+
176
+ EXAMPLES:
177
+ # Initial setup
178
+ memextend-cursor setup
179
+
180
+ # Check status
181
+ memextend-cursor status
182
+
183
+ # Capture a memory
184
+ memextend-cursor capture -c "Implemented user auth with JWT"
185
+
186
+ # Get session context
187
+ memextend-cursor inject
188
+
189
+ For more details on capture and inject commands:
190
+ memextend-cursor capture --help
191
+ memextend-cursor inject --help
192
+
193
+ DOCUMENTATION:
194
+ See the README.md for complete setup and usage instructions.
195
+ `);
196
+ }
197
+ async function main() {
198
+ const args = process.argv.slice(2);
199
+ const command = args[0];
200
+ switch (command) {
201
+ case "setup":
202
+ await setupCursor();
203
+ break;
204
+ case "status":
205
+ await showStatus();
206
+ break;
207
+ case "capture": {
208
+ const scriptDir = getScriptDir();
209
+ const captureScript = (0, import_path.join)(scriptDir, "capture.cjs");
210
+ const child = (0, import_child_process.spawn)("node", [captureScript, ...args.slice(1)], {
211
+ stdio: "inherit"
212
+ });
213
+ child.on("close", (code) => process.exit(code ?? 0));
214
+ break;
215
+ }
216
+ case "inject": {
217
+ const scriptDir = getScriptDir();
218
+ const injectScript = (0, import_path.join)(scriptDir, "inject.cjs");
219
+ const child = (0, import_child_process.spawn)("node", [injectScript, ...args.slice(1)], {
220
+ stdio: "inherit"
221
+ });
222
+ child.on("close", (code) => process.exit(code ?? 0));
223
+ break;
224
+ }
225
+ case "help":
226
+ case "--help":
227
+ case "-h":
228
+ case void 0:
229
+ printHelp();
230
+ break;
231
+ default:
232
+ console.error(`Unknown command: ${command}`);
233
+ console.error("Run `memextend-cursor help` for usage information.");
234
+ process.exit(1);
235
+ }
236
+ }
237
+ main().catch((error) => {
238
+ console.error("Error:", error.message);
239
+ process.exit(1);
240
+ });
241
+ // Annotate the CommonJS export names for ESM import in node:
242
+ 0 && (module.exports = {
243
+ setupCursor,
244
+ showStatus
245
+ });
@@ -0,0 +1,4 @@
1
+ declare function setupCursor(): Promise<void>;
2
+ declare function showStatus(): Promise<void>;
3
+ export { setupCursor, showStatus };
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AA4DA,iBAAe,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAmE1C;AAqBD,iBAAe,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAuCzC;AA4FD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC"}