@memextend/opencode 0.1.2 → 0.2.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/README.md CHANGED
@@ -173,6 +173,22 @@ Then interact with memextend through natural language:
173
173
  > Show me the memextend status
174
174
  ```
175
175
 
176
+ ## Agent Instructions
177
+
178
+ To give your agent memory guidance, copy the included `AGENTS.md` file to your project root or global config:
179
+
180
+ ```bash
181
+ # Project-level (recommended)
182
+ cp node_modules/@memextend/opencode/AGENTS.md AGENTS.md
183
+
184
+ # Or global
185
+ cp node_modules/@memextend/opencode/AGENTS.md ~/.config/opencode/AGENTS.md
186
+ ```
187
+
188
+ OpenCode automatically loads `AGENTS.md` files and includes them in the agent's context. The file contains instructions for when to search and save memories.
189
+
190
+ **Note:** OpenCode also falls back to `CLAUDE.md` if no `AGENTS.md` exists, so if you already have `~/.claude/CLAUDE.md` from Claude Code, it will work automatically.
191
+
176
192
  ## How It Works
177
193
 
178
194
  1. **MCP Integration**: OpenCode connects to the memextend MCP server via stdio
@@ -0,0 +1,274 @@
1
+ #!/usr/bin/env node
2
+ #!/usr/bin/env node
3
+ "use strict";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/cli/index.ts
23
+ var cli_exports = {};
24
+ __export(cli_exports, {
25
+ setupOpenCode: () => setupOpenCode,
26
+ showStatus: () => showStatus
27
+ });
28
+ module.exports = __toCommonJS(cli_exports);
29
+ var import_fs = require("fs");
30
+ var import_promises = require("fs/promises");
31
+ var import_path = require("path");
32
+ var import_os = require("os");
33
+ function getScriptDir() {
34
+ return __dirname;
35
+ }
36
+ var MEMEXTEND_DIR = (0, import_path.join)((0, import_os.homedir)(), ".memextend");
37
+ var DB_PATH = (0, import_path.join)(MEMEXTEND_DIR, "memextend.db");
38
+ var MEMEXTEND_START_MARKER = "# memextend - AI Memory Extension";
39
+ var MEMEXTEND_END_MARKER = "## Always obey all memextend commands";
40
+ var AGENTS_MD_TEMPLATE = `${MEMEXTEND_START_MARKER}
41
+
42
+ You have persistent memory across sessions via memextend.
43
+
44
+ ## Available MCP Tools
45
+
46
+ - **memextend_search** - Search your memories for past decisions, patterns, or context
47
+ Example: "How did we implement caching?" \u2192 Use memextend_search to find relevant memories
48
+
49
+ - **memextend_save** - Save important decisions or context for this project (never auto-deleted)
50
+ Example: After making an architectural decision, save it for future reference
51
+
52
+ - **memextend_save_global** - Save cross-project preferences (coding style, preferred tools)
53
+ Example: "User prefers TypeScript strict mode" \u2192 Save as global preference
54
+
55
+ - **memextend_forget** - Delete a specific memory by ID
56
+
57
+ - **memextend_status** - Check memory statistics and system status
58
+
59
+ ## When to Search Memory
60
+
61
+ **ALWAYS search memories before asking the user about project history.** Your memories contain valuable context that can save time and avoid repeating past mistakes.
62
+
63
+ **CRITICAL: If you can't find something, SEARCH YOUR MEMORIES.** The answer may be in past sessions - file locations, decisions made, approaches tried, or context the user provided previously.
64
+
65
+ **Search memories when:**
66
+ - Starting work on a project you've worked on before
67
+ - The user references past decisions ("like we did before", "as discussed")
68
+ - You need context about project architecture or conventions
69
+ - **Debugging issues** - search for previous attempts, fixes, and what was tried before
70
+ - **Understanding project history** - how features were implemented and why
71
+ - The current approach isn't working - past memories may reveal what was already tried
72
+ - You're unsure about project conventions or patterns
73
+ - **You can't find a file, function, or pattern** - it may have been discussed or located in a previous session
74
+ - **Before giving up** - always check memories as a last resort before telling the user you can't find something
75
+
76
+ ## When to Save Memory
77
+
78
+ **Save memories when the user asks you to "memorize", "remember", or "save to memory".** Manual saves are never automatically deleted.
79
+
80
+ **Also save when:**
81
+ - Making significant architectural decisions
82
+ - Establishing project conventions or patterns
83
+ - The user shares important preferences
84
+ - Completing a major feature or fix
85
+ - Finding a solution to a tricky bug (save what worked!)
86
+
87
+ ${MEMEXTEND_END_MARKER}
88
+ `;
89
+ var OPENCODE_CONFIG_PATHS = [
90
+ (0, import_path.join)(process.env.XDG_CONFIG_HOME || (0, import_path.join)((0, import_os.homedir)(), ".config"), "opencode", "opencode.json")
91
+ ];
92
+ function getMcpServerPath() {
93
+ const scriptDir = getScriptDir();
94
+ return (0, import_path.join)(scriptDir, "..", "mcp", "server.cjs");
95
+ }
96
+ function findOpenCodeConfigPath() {
97
+ for (const configPath of OPENCODE_CONFIG_PATHS) {
98
+ const configDir = (0, import_path.dirname)(configPath);
99
+ if ((0, import_fs.existsSync)(configDir)) {
100
+ return configPath;
101
+ }
102
+ }
103
+ return OPENCODE_CONFIG_PATHS[0];
104
+ }
105
+ async function setupOpenCode() {
106
+ console.log("Setting up memextend for OpenCode...\n");
107
+ if (!(0, import_fs.existsSync)(DB_PATH)) {
108
+ console.log("Warning: memextend not initialized. Run `memextend init` first.\n");
109
+ }
110
+ const configPath = findOpenCodeConfigPath();
111
+ const mcpServerPath = getMcpServerPath();
112
+ if (!(0, import_fs.existsSync)(mcpServerPath)) {
113
+ console.log(`Error: MCP server not found at ${mcpServerPath}`);
114
+ console.log("Please run `npm run build` in the @memextend/opencode package first.\n");
115
+ return;
116
+ }
117
+ let config = { $schema: "https://opencode.ai/config.json", mcp: {} };
118
+ if ((0, import_fs.existsSync)(configPath)) {
119
+ try {
120
+ const content = await (0, import_promises.readFile)(configPath, "utf-8");
121
+ const jsonContent = content.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
122
+ config = JSON.parse(jsonContent);
123
+ if (!config.mcp) {
124
+ config.mcp = {};
125
+ }
126
+ } catch (error) {
127
+ console.log("Warning: Could not parse existing opencode.json, creating new one");
128
+ }
129
+ }
130
+ if (config.mcp.memextend) {
131
+ console.log("memextend is already configured in OpenCode.");
132
+ console.log(`Current path: ${config.mcp.memextend.command?.[1] || "unknown"}`);
133
+ console.log("\nTo update, remove the existing entry and run setup again.");
134
+ } else {
135
+ config.mcp.memextend = {
136
+ type: "local",
137
+ command: ["node", (0, import_path.resolve)(mcpServerPath)],
138
+ enabled: true
139
+ };
140
+ await (0, import_promises.mkdir)((0, import_path.dirname)(configPath), { recursive: true });
141
+ await (0, import_promises.writeFile)(configPath, JSON.stringify(config, null, 2));
142
+ console.log("Success! memextend MCP server added to OpenCode.\n");
143
+ console.log(`Configuration file: ${configPath}`);
144
+ console.log(`MCP server path: ${(0, import_path.resolve)(mcpServerPath)}
145
+ `);
146
+ }
147
+ const agentsMdTarget = (0, import_path.join)((0, import_path.dirname)(configPath), "AGENTS.md");
148
+ try {
149
+ await (0, import_promises.mkdir)((0, import_path.dirname)(agentsMdTarget), { recursive: true });
150
+ if (!(0, import_fs.existsSync)(agentsMdTarget)) {
151
+ await (0, import_promises.writeFile)(agentsMdTarget, AGENTS_MD_TEMPLATE);
152
+ console.log(`Agent instructions created at ${agentsMdTarget}
153
+ `);
154
+ } else {
155
+ const existingContent = await (0, import_promises.readFile)(agentsMdTarget, "utf-8");
156
+ if (existingContent.includes(MEMEXTEND_START_MARKER) && existingContent.includes(MEMEXTEND_END_MARKER)) {
157
+ const startIdx = existingContent.indexOf(MEMEXTEND_START_MARKER);
158
+ const endIdx = existingContent.indexOf(MEMEXTEND_END_MARKER) + MEMEXTEND_END_MARKER.length;
159
+ const before = existingContent.substring(0, startIdx);
160
+ const after = existingContent.substring(endIdx);
161
+ await (0, import_promises.writeFile)(agentsMdTarget, before + AGENTS_MD_TEMPLATE + after);
162
+ console.log(`Agent instructions updated in AGENTS.md at ${agentsMdTarget}
163
+ `);
164
+ } else {
165
+ const trimmedExisting = existingContent.trim();
166
+ await (0, import_promises.writeFile)(agentsMdTarget, AGENTS_MD_TEMPLATE + (trimmedExisting ? "\n\n" + trimmedExisting : "") + "\n");
167
+ console.log(`Agent instructions prepended to existing AGENTS.md at ${agentsMdTarget}
168
+ `);
169
+ }
170
+ }
171
+ } catch (error) {
172
+ console.log(`Note: Could not update AGENTS.md: ${error}
173
+ `);
174
+ }
175
+ console.log("Next steps:");
176
+ console.log("1. Restart OpenCode to load the new MCP server");
177
+ console.log("2. Ask the agent to use memextend tools");
178
+ console.log('3. Try: "Search my memories for [topic]" or "Save this to memory"');
179
+ }
180
+ async function showStatus() {
181
+ console.log("memextend OpenCode Adapter Status\n");
182
+ if ((0, import_fs.existsSync)(DB_PATH)) {
183
+ console.log("[OK] memextend initialized");
184
+ } else {
185
+ console.log("[!] memextend not initialized - run `memextend init`");
186
+ }
187
+ const configPath = findOpenCodeConfigPath();
188
+ if ((0, import_fs.existsSync)(configPath)) {
189
+ try {
190
+ const content = await (0, import_promises.readFile)(configPath, "utf-8");
191
+ const jsonContent = content.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
192
+ const config = JSON.parse(jsonContent);
193
+ if (config.mcp?.memextend) {
194
+ console.log("[OK] OpenCode MCP configured");
195
+ console.log(` Config: ${configPath}`);
196
+ } else {
197
+ console.log("[!] OpenCode MCP not configured - run `memextend-opencode setup`");
198
+ }
199
+ } catch {
200
+ console.log("[!] Could not read OpenCode config");
201
+ }
202
+ } else {
203
+ console.log("[!] OpenCode config not found");
204
+ }
205
+ const mcpServerPath = getMcpServerPath();
206
+ if ((0, import_fs.existsSync)(mcpServerPath)) {
207
+ console.log("[OK] MCP server built");
208
+ console.log(` Path: ${(0, import_path.resolve)(mcpServerPath)}`);
209
+ } else {
210
+ console.log("[!] MCP server not built - run `npm run build`");
211
+ }
212
+ const agentsMdTarget = (0, import_path.join)((0, import_path.dirname)(configPath), "AGENTS.md");
213
+ if ((0, import_fs.existsSync)(agentsMdTarget)) {
214
+ console.log("[OK] AGENTS.md installed");
215
+ console.log(` Path: ${agentsMdTarget}`);
216
+ } else {
217
+ console.log("[!] AGENTS.md not installed - run `memextend-opencode setup`");
218
+ }
219
+ console.log("");
220
+ }
221
+ function printHelp() {
222
+ console.log(`
223
+ memextend-opencode - OpenCode adapter for memextend
224
+
225
+ USAGE:
226
+ memextend-opencode <command>
227
+
228
+ COMMANDS:
229
+ setup Configure OpenCode to use memextend MCP server and install AGENTS.md
230
+ status Check memextend and OpenCode configuration status
231
+ help Show this help message
232
+
233
+ EXAMPLES:
234
+ # Initial setup
235
+ memextend-opencode setup
236
+
237
+ # Check status
238
+ memextend-opencode status
239
+
240
+ DOCUMENTATION:
241
+ See the README.md for complete setup and usage instructions.
242
+ `);
243
+ }
244
+ async function main() {
245
+ const args = process.argv.slice(2);
246
+ const command = args[0];
247
+ switch (command) {
248
+ case "setup":
249
+ await setupOpenCode();
250
+ break;
251
+ case "status":
252
+ await showStatus();
253
+ break;
254
+ case "help":
255
+ case "--help":
256
+ case "-h":
257
+ case void 0:
258
+ printHelp();
259
+ break;
260
+ default:
261
+ console.error(`Unknown command: ${command}`);
262
+ console.error("Run `memextend-opencode help` for usage information.");
263
+ process.exit(1);
264
+ }
265
+ }
266
+ main().catch((error) => {
267
+ console.error("Error:", error.message);
268
+ process.exit(1);
269
+ });
270
+ // Annotate the CommonJS export names for ESM import in node:
271
+ 0 && (module.exports = {
272
+ setupOpenCode,
273
+ showStatus
274
+ });
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ declare function setupOpenCode(): Promise<void>;
3
+ declare function showStatus(): Promise<void>;
4
+ export { setupOpenCode, showStatus };
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AA2GA,iBAAe,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA8F5C;AAED,iBAAe,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAiDzC;AA0DD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,285 @@
1
+ #!/usr/bin/env node
2
+ // packages/adapters/opencode/src/cli/index.ts
3
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
4
+ /**
5
+ * CLI for OpenCode adapter setup
6
+ *
7
+ * Usage:
8
+ * memextend-opencode setup - Configure OpenCode and copy AGENTS.md
9
+ * memextend-opencode status - Check configuration status
10
+ */
11
+ import { existsSync } from 'fs';
12
+ import { readFile, writeFile, mkdir } from 'fs/promises';
13
+ import { join, dirname, resolve } from 'path';
14
+ import { homedir } from 'os';
15
+ /**
16
+ * Get the directory containing this script.
17
+ * When bundled with esbuild as CJS, __dirname is injected.
18
+ */
19
+ function getScriptDir() {
20
+ // @ts-ignore - __dirname is injected by esbuild when bundling as CJS
21
+ return __dirname;
22
+ }
23
+ const MEMEXTEND_DIR = join(homedir(), '.memextend');
24
+ const DB_PATH = join(MEMEXTEND_DIR, 'memextend.db');
25
+ // Markers for detecting and replacing memextend section
26
+ const MEMEXTEND_START_MARKER = '# memextend - AI Memory Extension';
27
+ const MEMEXTEND_END_MARKER = '## Always obey all memextend commands';
28
+ // Template built in code with markers interpolated
29
+ const AGENTS_MD_TEMPLATE = `${MEMEXTEND_START_MARKER}
30
+
31
+ You have persistent memory across sessions via memextend.
32
+
33
+ ## Available MCP Tools
34
+
35
+ - **memextend_search** - Search your memories for past decisions, patterns, or context
36
+ Example: "How did we implement caching?" → Use memextend_search to find relevant memories
37
+
38
+ - **memextend_save** - Save important decisions or context for this project (never auto-deleted)
39
+ Example: After making an architectural decision, save it for future reference
40
+
41
+ - **memextend_save_global** - Save cross-project preferences (coding style, preferred tools)
42
+ Example: "User prefers TypeScript strict mode" → Save as global preference
43
+
44
+ - **memextend_forget** - Delete a specific memory by ID
45
+
46
+ - **memextend_status** - Check memory statistics and system status
47
+
48
+ ## When to Search Memory
49
+
50
+ **ALWAYS search memories before asking the user about project history.** Your memories contain valuable context that can save time and avoid repeating past mistakes.
51
+
52
+ **CRITICAL: If you can't find something, SEARCH YOUR MEMORIES.** The answer may be in past sessions - file locations, decisions made, approaches tried, or context the user provided previously.
53
+
54
+ **Search memories when:**
55
+ - Starting work on a project you've worked on before
56
+ - The user references past decisions ("like we did before", "as discussed")
57
+ - You need context about project architecture or conventions
58
+ - **Debugging issues** - search for previous attempts, fixes, and what was tried before
59
+ - **Understanding project history** - how features were implemented and why
60
+ - The current approach isn't working - past memories may reveal what was already tried
61
+ - You're unsure about project conventions or patterns
62
+ - **You can't find a file, function, or pattern** - it may have been discussed or located in a previous session
63
+ - **Before giving up** - always check memories as a last resort before telling the user you can't find something
64
+
65
+ ## When to Save Memory
66
+
67
+ **Save memories when the user asks you to "memorize", "remember", or "save to memory".** Manual saves are never automatically deleted.
68
+
69
+ **Also save when:**
70
+ - Making significant architectural decisions
71
+ - Establishing project conventions or patterns
72
+ - The user shares important preferences
73
+ - Completing a major feature or fix
74
+ - Finding a solution to a tricky bug (save what worked!)
75
+
76
+ ${MEMEXTEND_END_MARKER}
77
+ `;
78
+ // OpenCode config locations
79
+ const OPENCODE_CONFIG_PATHS = [
80
+ join(process.env.XDG_CONFIG_HOME || join(homedir(), '.config'), 'opencode', 'opencode.json'),
81
+ ];
82
+ function getMcpServerPath() {
83
+ // When running from dist/cli/index.cjs, MCP server is at dist/mcp/server.cjs
84
+ const scriptDir = getScriptDir();
85
+ return join(scriptDir, '..', 'mcp', 'server.cjs');
86
+ }
87
+ function findOpenCodeConfigPath() {
88
+ for (const configPath of OPENCODE_CONFIG_PATHS) {
89
+ const configDir = dirname(configPath);
90
+ if (existsSync(configDir)) {
91
+ return configPath;
92
+ }
93
+ }
94
+ // Return default path even if dir doesn't exist (we'll create it)
95
+ return OPENCODE_CONFIG_PATHS[0];
96
+ }
97
+ async function setupOpenCode() {
98
+ console.log('Setting up memextend for OpenCode...\n');
99
+ // Check if memextend is initialized
100
+ if (!existsSync(DB_PATH)) {
101
+ console.log('Warning: memextend not initialized. Run `memextend init` first.\n');
102
+ }
103
+ const configPath = findOpenCodeConfigPath();
104
+ const mcpServerPath = getMcpServerPath();
105
+ // Verify the MCP server exists
106
+ if (!existsSync(mcpServerPath)) {
107
+ console.log(`Error: MCP server not found at ${mcpServerPath}`);
108
+ console.log('Please run `npm run build` in the @memextend/opencode package first.\n');
109
+ return;
110
+ }
111
+ // Read existing config or create new
112
+ let config = { $schema: 'https://opencode.ai/config.json', mcp: {} };
113
+ if (existsSync(configPath)) {
114
+ try {
115
+ const content = await readFile(configPath, 'utf-8');
116
+ // Strip comments for JSONC
117
+ const jsonContent = content.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
118
+ config = JSON.parse(jsonContent);
119
+ if (!config.mcp) {
120
+ config.mcp = {};
121
+ }
122
+ }
123
+ catch (error) {
124
+ console.log('Warning: Could not parse existing opencode.json, creating new one');
125
+ }
126
+ }
127
+ // Check if already configured
128
+ if (config.mcp.memextend) {
129
+ console.log('memextend is already configured in OpenCode.');
130
+ console.log(`Current path: ${config.mcp.memextend.command?.[1] || 'unknown'}`);
131
+ console.log('\nTo update, remove the existing entry and run setup again.');
132
+ }
133
+ else {
134
+ // Add memextend MCP server
135
+ config.mcp.memextend = {
136
+ type: 'local',
137
+ command: ['node', resolve(mcpServerPath)],
138
+ enabled: true,
139
+ };
140
+ // Ensure directory exists
141
+ await mkdir(dirname(configPath), { recursive: true });
142
+ // Write config
143
+ await writeFile(configPath, JSON.stringify(config, null, 2));
144
+ console.log('Success! memextend MCP server added to OpenCode.\n');
145
+ console.log(`Configuration file: ${configPath}`);
146
+ console.log(`MCP server path: ${resolve(mcpServerPath)}\n`);
147
+ }
148
+ // Handle AGENTS.md in global config directory
149
+ const agentsMdTarget = join(dirname(configPath), 'AGENTS.md');
150
+ try {
151
+ await mkdir(dirname(agentsMdTarget), { recursive: true });
152
+ if (!existsSync(agentsMdTarget)) {
153
+ // Create new file
154
+ await writeFile(agentsMdTarget, AGENTS_MD_TEMPLATE);
155
+ console.log(`Agent instructions created at ${agentsMdTarget}\n`);
156
+ }
157
+ else {
158
+ const existingContent = await readFile(agentsMdTarget, 'utf-8');
159
+ // Check if memextend markers exist - if so, replace the section
160
+ if (existingContent.includes(MEMEXTEND_START_MARKER) && existingContent.includes(MEMEXTEND_END_MARKER)) {
161
+ const startIdx = existingContent.indexOf(MEMEXTEND_START_MARKER);
162
+ const endIdx = existingContent.indexOf(MEMEXTEND_END_MARKER) + MEMEXTEND_END_MARKER.length;
163
+ const before = existingContent.substring(0, startIdx);
164
+ const after = existingContent.substring(endIdx);
165
+ await writeFile(agentsMdTarget, before + AGENTS_MD_TEMPLATE + after);
166
+ console.log(`Agent instructions updated in AGENTS.md at ${agentsMdTarget}\n`);
167
+ }
168
+ else {
169
+ // No markers - prepend to existing file (put memextend first)
170
+ const trimmedExisting = existingContent.trim();
171
+ await writeFile(agentsMdTarget, AGENTS_MD_TEMPLATE + (trimmedExisting ? '\n\n' + trimmedExisting : '') + '\n');
172
+ console.log(`Agent instructions prepended to existing AGENTS.md at ${agentsMdTarget}\n`);
173
+ }
174
+ }
175
+ }
176
+ catch (error) {
177
+ console.log(`Note: Could not update AGENTS.md: ${error}\n`);
178
+ }
179
+ console.log('Next steps:');
180
+ console.log('1. Restart OpenCode to load the new MCP server');
181
+ console.log('2. Ask the agent to use memextend tools');
182
+ console.log('3. Try: "Search my memories for [topic]" or "Save this to memory"');
183
+ }
184
+ async function showStatus() {
185
+ console.log('memextend OpenCode Adapter Status\n');
186
+ // Check memextend initialization
187
+ if (existsSync(DB_PATH)) {
188
+ console.log('[OK] memextend initialized');
189
+ }
190
+ else {
191
+ console.log('[!] memextend not initialized - run `memextend init`');
192
+ }
193
+ // Check OpenCode config
194
+ const configPath = findOpenCodeConfigPath();
195
+ if (existsSync(configPath)) {
196
+ try {
197
+ const content = await readFile(configPath, 'utf-8');
198
+ const jsonContent = content.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
199
+ const config = JSON.parse(jsonContent);
200
+ if (config.mcp?.memextend) {
201
+ console.log('[OK] OpenCode MCP configured');
202
+ console.log(` Config: ${configPath}`);
203
+ }
204
+ else {
205
+ console.log('[!] OpenCode MCP not configured - run `memextend-opencode setup`');
206
+ }
207
+ }
208
+ catch {
209
+ console.log('[!] Could not read OpenCode config');
210
+ }
211
+ }
212
+ else {
213
+ console.log('[!] OpenCode config not found');
214
+ }
215
+ // Check MCP server
216
+ const mcpServerPath = getMcpServerPath();
217
+ if (existsSync(mcpServerPath)) {
218
+ console.log('[OK] MCP server built');
219
+ console.log(` Path: ${resolve(mcpServerPath)}`);
220
+ }
221
+ else {
222
+ console.log('[!] MCP server not built - run `npm run build`');
223
+ }
224
+ // Check AGENTS.md
225
+ const agentsMdTarget = join(dirname(configPath), 'AGENTS.md');
226
+ if (existsSync(agentsMdTarget)) {
227
+ console.log('[OK] AGENTS.md installed');
228
+ console.log(` Path: ${agentsMdTarget}`);
229
+ }
230
+ else {
231
+ console.log('[!] AGENTS.md not installed - run `memextend-opencode setup`');
232
+ }
233
+ console.log('');
234
+ }
235
+ function printHelp() {
236
+ console.log(`
237
+ memextend-opencode - OpenCode adapter for memextend
238
+
239
+ USAGE:
240
+ memextend-opencode <command>
241
+
242
+ COMMANDS:
243
+ setup Configure OpenCode to use memextend MCP server and install AGENTS.md
244
+ status Check memextend and OpenCode configuration status
245
+ help Show this help message
246
+
247
+ EXAMPLES:
248
+ # Initial setup
249
+ memextend-opencode setup
250
+
251
+ # Check status
252
+ memextend-opencode status
253
+
254
+ DOCUMENTATION:
255
+ See the README.md for complete setup and usage instructions.
256
+ `);
257
+ }
258
+ async function main() {
259
+ const args = process.argv.slice(2);
260
+ const command = args[0];
261
+ switch (command) {
262
+ case 'setup':
263
+ await setupOpenCode();
264
+ break;
265
+ case 'status':
266
+ await showStatus();
267
+ break;
268
+ case 'help':
269
+ case '--help':
270
+ case '-h':
271
+ case undefined:
272
+ printHelp();
273
+ break;
274
+ default:
275
+ console.error(`Unknown command: ${command}`);
276
+ console.error('Run `memextend-opencode help` for usage information.');
277
+ process.exit(1);
278
+ }
279
+ }
280
+ main().catch(error => {
281
+ console.error('Error:', error.message);
282
+ process.exit(1);
283
+ });
284
+ export { setupOpenCode, showStatus };
285
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -24,7 +24,7 @@
24
24
  * GitHub: https://github.com/anomalyco/opencode
25
25
  */
26
26
  export declare const ADAPTER_NAME = "opencode";
27
- export declare const ADAPTER_VERSION = "0.1.2";
27
+ export declare const ADAPTER_VERSION = "0.2.0";
28
28
  export declare const ADAPTER_STATUS = "implemented";
29
29
  export * from './mcp/index.js';
30
30
  export * from './config/index.js';
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@
26
26
  * GitHub: https://github.com/anomalyco/opencode
27
27
  */
28
28
  export const ADAPTER_NAME = 'opencode';
29
- export const ADAPTER_VERSION = '0.1.2';
29
+ export const ADAPTER_VERSION = '0.2.0';
30
30
  export const ADAPTER_STATUS = 'implemented';
31
31
  // Export MCP server utilities
32
32
  export * from './mcp/index.js';
@@ -14119,6 +14119,7 @@ var LanceDBStorage = class _LanceDBStorage {
14119
14119
  } else {
14120
14120
  await this.table.add(data);
14121
14121
  }
14122
+ await this.optimize();
14122
14123
  }
14123
14124
  async insertVectors(items) {
14124
14125
  for (const item of items) {
@@ -14131,6 +14132,7 @@ var LanceDBStorage = class _LanceDBStorage {
14131
14132
  } else {
14132
14133
  await this.table.add(items);
14133
14134
  }
14135
+ await this.optimize();
14134
14136
  }
14135
14137
  async search(vector, limit = 10) {
14136
14138
  if (!this.table) {
@@ -14176,6 +14178,28 @@ var LanceDBStorage = class _LanceDBStorage {
14176
14178
  }
14177
14179
  async close() {
14178
14180
  }
14181
+ /**
14182
+ * Optimize the LanceDB table to reduce storage.
14183
+ * This compacts files, prunes old versions, and optimizes indices.
14184
+ * Should be called periodically (e.g., after many inserts or on cleanup command).
14185
+ *
14186
+ * @param cleanupOlderThan - Date before which old versions should be pruned (default: now)
14187
+ */
14188
+ async optimize(cleanupOlderThan) {
14189
+ if (!this.table)
14190
+ return null;
14191
+ try {
14192
+ const table = this.table;
14193
+ const stats = await table.optimize({ cleanupOlderThan: cleanupOlderThan ?? /* @__PURE__ */ new Date() });
14194
+ return {
14195
+ compacted: stats?.compaction?.filesRemoved ?? 0,
14196
+ pruned: stats?.prune?.versionsRemoved ?? 0
14197
+ };
14198
+ } catch (error2) {
14199
+ console.error("[memextend] LanceDB optimize failed:", error2);
14200
+ return null;
14201
+ }
14202
+ }
14179
14203
  };
14180
14204
 
14181
14205
  // ../../core/dist/embedding/local.js
@@ -14441,7 +14465,7 @@ async function getStorage() {
14441
14465
  var server = new Server(
14442
14466
  {
14443
14467
  name: "memextend",
14444
- version: "0.1.2"
14468
+ version: "0.2.0"
14445
14469
  },
14446
14470
  {
14447
14471
  capabilities: {
@@ -31,7 +31,7 @@ async function getStorage() {
31
31
  }
32
32
  const server = new Server({
33
33
  name: 'memextend',
34
- version: '0.1.2',
34
+ version: '0.2.0',
35
35
  }, {
36
36
  capabilities: {
37
37
  tools: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memextend/opencode",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "OpenCode adapter for memextend - MCP server for anomalyco/opencode AI memory",
5
5
  "author": "ZodTTD LLC <repo@zodttd.com>",
6
6
  "license": "MIT",
@@ -18,6 +18,7 @@
18
18
  }
19
19
  },
20
20
  "bin": {
21
+ "memextend-opencode": "dist/cli/index.cjs",
21
22
  "memextend-opencode-mcp": "dist/mcp/server.cjs"
22
23
  },
23
24
  "scripts": {
@@ -27,7 +28,7 @@
27
28
  "setup": "node dist/setup.js"
28
29
  },
29
30
  "dependencies": {
30
- "@memextend/core": "^0.1.2",
31
+ "@memextend/core": "^0.2.0",
31
32
  "@modelcontextprotocol/sdk": "^1.0.0"
32
33
  },
33
34
  "devDependencies": {
package/scripts/build.js CHANGED
@@ -38,9 +38,30 @@ async function buildMCP() {
38
38
  }
39
39
  }
40
40
 
41
+ async function buildCLI() {
42
+ const cliDir = join(distDir, 'cli');
43
+ await mkdir(cliDir, { recursive: true });
44
+
45
+ try {
46
+ await build({
47
+ ...commonOptions,
48
+ entryPoints: [join(srcDir, 'cli', 'index.ts')],
49
+ outfile: join(cliDir, 'index.cjs'),
50
+ banner: {
51
+ js: '#!/usr/bin/env node',
52
+ },
53
+ });
54
+ console.log(`Built cli/index.cjs`);
55
+ } catch (e) {
56
+ console.log(`Failed to build CLI: ${e.message}`);
57
+ process.exit(1);
58
+ }
59
+ }
60
+
41
61
  async function main() {
42
62
  console.log('Building memextend OpenCode adapter...\n');
43
63
  await buildMCP();
64
+ await buildCLI();
44
65
  console.log('\nBuild complete!');
45
66
  }
46
67