opencode-mem 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.
Files changed (84) hide show
  1. package/README.md +588 -0
  2. package/dist/config.d.ts +33 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +258 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +618 -0
  8. package/dist/plugin.d.ts +5 -0
  9. package/dist/plugin.d.ts.map +1 -0
  10. package/dist/plugin.js +15 -0
  11. package/dist/services/api-handlers.d.ts +102 -0
  12. package/dist/services/api-handlers.d.ts.map +1 -0
  13. package/dist/services/api-handlers.js +494 -0
  14. package/dist/services/auto-capture.d.ts +32 -0
  15. package/dist/services/auto-capture.d.ts.map +1 -0
  16. package/dist/services/auto-capture.js +451 -0
  17. package/dist/services/cleanup-service.d.ts +20 -0
  18. package/dist/services/cleanup-service.d.ts.map +1 -0
  19. package/dist/services/cleanup-service.js +88 -0
  20. package/dist/services/client.d.ts +104 -0
  21. package/dist/services/client.d.ts.map +1 -0
  22. package/dist/services/client.js +251 -0
  23. package/dist/services/compaction.d.ts +92 -0
  24. package/dist/services/compaction.d.ts.map +1 -0
  25. package/dist/services/compaction.js +421 -0
  26. package/dist/services/context.d.ts +17 -0
  27. package/dist/services/context.d.ts.map +1 -0
  28. package/dist/services/context.js +41 -0
  29. package/dist/services/deduplication-service.d.ts +30 -0
  30. package/dist/services/deduplication-service.d.ts.map +1 -0
  31. package/dist/services/deduplication-service.js +131 -0
  32. package/dist/services/embedding.d.ts +10 -0
  33. package/dist/services/embedding.d.ts.map +1 -0
  34. package/dist/services/embedding.js +77 -0
  35. package/dist/services/jsonc.d.ts +7 -0
  36. package/dist/services/jsonc.d.ts.map +1 -0
  37. package/dist/services/jsonc.js +76 -0
  38. package/dist/services/logger.d.ts +2 -0
  39. package/dist/services/logger.d.ts.map +1 -0
  40. package/dist/services/logger.js +16 -0
  41. package/dist/services/migration-service.d.ts +42 -0
  42. package/dist/services/migration-service.d.ts.map +1 -0
  43. package/dist/services/migration-service.js +258 -0
  44. package/dist/services/privacy.d.ts +4 -0
  45. package/dist/services/privacy.d.ts.map +1 -0
  46. package/dist/services/privacy.js +10 -0
  47. package/dist/services/sqlite/connection-manager.d.ts +10 -0
  48. package/dist/services/sqlite/connection-manager.d.ts.map +1 -0
  49. package/dist/services/sqlite/connection-manager.js +45 -0
  50. package/dist/services/sqlite/shard-manager.d.ts +20 -0
  51. package/dist/services/sqlite/shard-manager.d.ts.map +1 -0
  52. package/dist/services/sqlite/shard-manager.js +221 -0
  53. package/dist/services/sqlite/types.d.ts +39 -0
  54. package/dist/services/sqlite/types.d.ts.map +1 -0
  55. package/dist/services/sqlite/types.js +1 -0
  56. package/dist/services/sqlite/vector-search.d.ts +18 -0
  57. package/dist/services/sqlite/vector-search.d.ts.map +1 -0
  58. package/dist/services/sqlite/vector-search.js +129 -0
  59. package/dist/services/sqlite-client.d.ts +116 -0
  60. package/dist/services/sqlite-client.d.ts.map +1 -0
  61. package/dist/services/sqlite-client.js +284 -0
  62. package/dist/services/tags.d.ts +20 -0
  63. package/dist/services/tags.d.ts.map +1 -0
  64. package/dist/services/tags.js +76 -0
  65. package/dist/services/web-server-lock.d.ts +12 -0
  66. package/dist/services/web-server-lock.d.ts.map +1 -0
  67. package/dist/services/web-server-lock.js +157 -0
  68. package/dist/services/web-server-worker.d.ts +2 -0
  69. package/dist/services/web-server-worker.d.ts.map +1 -0
  70. package/dist/services/web-server-worker.js +221 -0
  71. package/dist/services/web-server.d.ts +22 -0
  72. package/dist/services/web-server.d.ts.map +1 -0
  73. package/dist/services/web-server.js +134 -0
  74. package/dist/types/index.d.ts +48 -0
  75. package/dist/types/index.d.ts.map +1 -0
  76. package/dist/types/index.js +1 -0
  77. package/dist/web/app.d.ts +2 -0
  78. package/dist/web/app.d.ts.map +1 -0
  79. package/dist/web/app.js +691 -0
  80. package/dist/web/favicon.ico +0 -0
  81. package/dist/web/favicon.svg +14 -0
  82. package/dist/web/index.html +202 -0
  83. package/dist/web/styles.css +851 -0
  84. package/package.json +52 -0
package/dist/config.js ADDED
@@ -0,0 +1,258 @@
1
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { stripJsoncComments } from "./services/jsonc.js";
5
+ const CONFIG_DIR = join(homedir(), ".config", "opencode");
6
+ const DATA_DIR = join(homedir(), ".opencode-mem");
7
+ const CONFIG_FILES = [
8
+ join(CONFIG_DIR, "opencode-mem.jsonc"),
9
+ join(CONFIG_DIR, "opencode-mem.json"),
10
+ ];
11
+ if (!existsSync(CONFIG_DIR)) {
12
+ mkdirSync(CONFIG_DIR, { recursive: true });
13
+ }
14
+ if (!existsSync(DATA_DIR)) {
15
+ mkdirSync(DATA_DIR, { recursive: true });
16
+ }
17
+ const DEFAULT_KEYWORD_PATTERNS = [
18
+ "remember",
19
+ "memorize",
20
+ "save\\s+this",
21
+ "note\\s+this",
22
+ "keep\\s+in\\s+mind",
23
+ "don'?t\\s+forget",
24
+ "learn\\s+this",
25
+ "store\\s+this",
26
+ "record\\s+this",
27
+ "make\\s+a\\s+note",
28
+ "take\\s+note",
29
+ "jot\\s+down",
30
+ "commit\\s+to\\s+memory",
31
+ "remember\\s+that",
32
+ "never\\s+forget",
33
+ "always\\s+remember",
34
+ ];
35
+ const DEFAULTS = {
36
+ storagePath: join(DATA_DIR, "data"),
37
+ embeddingModel: "Xenova/nomic-embed-text-v1",
38
+ embeddingDimensions: 768,
39
+ similarityThreshold: 0.6,
40
+ maxMemories: 5,
41
+ maxProjectMemories: 10,
42
+ maxProfileItems: 5,
43
+ injectProfile: true,
44
+ containerTagPrefix: "opencode",
45
+ keywordPatterns: [],
46
+ autoCaptureEnabled: true,
47
+ autoCaptureTokenThreshold: 10000,
48
+ autoCaptureMinTokens: 20000,
49
+ autoCaptureMaxMemories: 10,
50
+ autoCaptureSummaryMaxLength: 0,
51
+ autoCaptureContextWindow: 3,
52
+ webServerEnabled: true,
53
+ webServerPort: 4747,
54
+ webServerHost: "127.0.0.1",
55
+ maxVectorsPerShard: 50000,
56
+ autoCleanupEnabled: true,
57
+ autoCleanupRetentionDays: 30,
58
+ deduplicationEnabled: true,
59
+ deduplicationSimilarityThreshold: 0.9,
60
+ };
61
+ function isValidRegex(pattern) {
62
+ try {
63
+ new RegExp(pattern);
64
+ return true;
65
+ }
66
+ catch {
67
+ return false;
68
+ }
69
+ }
70
+ function expandPath(path) {
71
+ if (path.startsWith("~/")) {
72
+ return join(homedir(), path.slice(2));
73
+ }
74
+ if (path === "~") {
75
+ return homedir();
76
+ }
77
+ return path;
78
+ }
79
+ function loadConfig() {
80
+ for (const path of CONFIG_FILES) {
81
+ if (existsSync(path)) {
82
+ try {
83
+ const content = readFileSync(path, "utf-8");
84
+ const json = stripJsoncComments(content);
85
+ return JSON.parse(json);
86
+ }
87
+ catch { }
88
+ }
89
+ }
90
+ return {};
91
+ }
92
+ const fileConfig = loadConfig();
93
+ const CONFIG_TEMPLATE = `{
94
+ // ============================================
95
+ // OpenCode Memory Plugin Configuration
96
+ // ============================================
97
+
98
+ // Storage location for vector database
99
+ "storagePath": "~/.opencode-mem/data",
100
+
101
+ // ============================================
102
+ // Embedding Model (for similarity search)
103
+ // ============================================
104
+
105
+ // Default: Nomic Embed v1 (768 dimensions, 8192 context, multilingual)
106
+ "embeddingModel": "Xenova/nomic-embed-text-v1",
107
+
108
+ // Auto-detected dimensions (no need to set manually)
109
+ // "embeddingDimensions": 768,
110
+
111
+ // Other recommended models:
112
+ // "embeddingModel": "Xenova/jina-embeddings-v2-base-en", // 768 dims, English-only, 8192 context
113
+ // "embeddingModel": "Xenova/jina-embeddings-v2-small-en", // 512 dims, faster, 8192 context
114
+ // "embeddingModel": "Xenova/all-MiniLM-L6-v2", // 384 dims, very fast, 512 context
115
+ // "embeddingModel": "Xenova/all-mpnet-base-v2", // 768 dims, good quality, 512 context
116
+
117
+ // Optional: Use OpenAI-compatible API for embeddings
118
+ // "embeddingApiUrl": "https://api.openai.com/v1",
119
+ // "embeddingApiKey": "sk-...",
120
+
121
+ // ============================================
122
+ // Web Server Settings
123
+ // ============================================
124
+
125
+ "webServerEnabled": true,
126
+ "webServerPort": 4747,
127
+ "webServerHost": "127.0.0.1",
128
+
129
+ // ============================================
130
+ // Database Settings
131
+ // ============================================
132
+
133
+ "maxVectorsPerShard": 50000,
134
+ "autoCleanupEnabled": true,
135
+ "autoCleanupRetentionDays": 30,
136
+ "deduplicationEnabled": true,
137
+ "deduplicationSimilarityThreshold": 0.90,
138
+
139
+ // ============================================
140
+ // Auto-Capture Settings (REQUIRES EXTERNAL API)
141
+ // ============================================
142
+
143
+ // IMPORTANT: Auto-capture ONLY works with external API
144
+ // It runs in background without blocking your main session
145
+ // Note: Ollama may not support tool calling. Use OpenAI, Anthropic, or Groq for best results.
146
+
147
+ "autoCaptureEnabled": true,
148
+
149
+ // REQUIRED for auto-capture (all 3 must be set):
150
+ "memoryModel": "gpt-4o-mini",
151
+ "memoryApiUrl": "https://api.openai.com/v1",
152
+ "memoryApiKey": "sk-...",
153
+
154
+ // Examples for other providers:
155
+ // Anthropic:
156
+ // "memoryModel": "claude-3-5-haiku-20241022"
157
+ // "memoryApiUrl": "https://api.anthropic.com/v1"
158
+ // "memoryApiKey": "sk-ant-..."
159
+ // Groq (fast & cheap):
160
+ // "memoryModel": "llama-3.3-70b-versatile"
161
+ // "memoryApiUrl": "https://api.groq.com/openai/v1"
162
+ // "memoryApiKey": "gsk_..."
163
+
164
+ // Token thresholds
165
+ "autoCaptureTokenThreshold": 10000,
166
+ "autoCaptureMinTokens": 20000,
167
+ "autoCaptureMaxMemories": 10,
168
+ "autoCaptureContextWindow": 3,
169
+
170
+ // Summary length: 0 = AI decides optimal length, >0 = character limit
171
+ "autoCaptureSummaryMaxLength": 0,
172
+
173
+ // ============================================
174
+ // Search Settings
175
+ // ============================================
176
+
177
+ "similarityThreshold": 0.6,
178
+ "maxMemories": 5,
179
+ "maxProjectMemories": 10,
180
+
181
+ // ============================================
182
+ // Advanced Settings
183
+ // ============================================
184
+
185
+ "injectProfile": true,
186
+ "keywordPatterns": []
187
+ }
188
+ `;
189
+ function ensureConfigExists() {
190
+ const configPath = join(CONFIG_DIR, "opencode-mem.jsonc");
191
+ if (!existsSync(configPath)) {
192
+ try {
193
+ writeFileSync(configPath, CONFIG_TEMPLATE, "utf-8");
194
+ console.log(`\n✓ Created config template: ${configPath}`);
195
+ console.log(" Edit this file to customize opencode-mem settings.\n");
196
+ }
197
+ catch { }
198
+ }
199
+ }
200
+ ensureConfigExists();
201
+ function getEmbeddingDimensions(model) {
202
+ const dimensionMap = {
203
+ "Xenova/nomic-embed-text-v1": 768,
204
+ "Xenova/nomic-embed-text-v1-unsupervised": 768,
205
+ "Xenova/nomic-embed-text-v1-ablated": 768,
206
+ "Xenova/jina-embeddings-v2-base-en": 768,
207
+ "Xenova/jina-embeddings-v2-base-zh": 768,
208
+ "Xenova/jina-embeddings-v2-base-de": 768,
209
+ "Xenova/jina-embeddings-v2-small-en": 512,
210
+ "Xenova/all-MiniLM-L6-v2": 384,
211
+ "Xenova/all-MiniLM-L12-v2": 384,
212
+ "Xenova/all-mpnet-base-v2": 768,
213
+ "Xenova/bge-base-en-v1.5": 768,
214
+ "Xenova/bge-small-en-v1.5": 384,
215
+ "Xenova/gte-small": 384,
216
+ "Xenova/GIST-small-Embedding-v0": 384,
217
+ "Xenova/text-embedding-ada-002": 1536,
218
+ };
219
+ return dimensionMap[model] || 768;
220
+ }
221
+ export const CONFIG = {
222
+ storagePath: expandPath(fileConfig.storagePath ?? DEFAULTS.storagePath),
223
+ embeddingModel: fileConfig.embeddingModel ?? DEFAULTS.embeddingModel,
224
+ embeddingDimensions: fileConfig.embeddingDimensions ??
225
+ getEmbeddingDimensions(fileConfig.embeddingModel ?? DEFAULTS.embeddingModel),
226
+ embeddingApiUrl: fileConfig.embeddingApiUrl,
227
+ embeddingApiKey: fileConfig.embeddingApiKey ?? process.env.OPENAI_API_KEY,
228
+ similarityThreshold: fileConfig.similarityThreshold ?? DEFAULTS.similarityThreshold,
229
+ maxMemories: fileConfig.maxMemories ?? DEFAULTS.maxMemories,
230
+ maxProjectMemories: fileConfig.maxProjectMemories ?? DEFAULTS.maxProjectMemories,
231
+ maxProfileItems: fileConfig.maxProfileItems ?? DEFAULTS.maxProfileItems,
232
+ injectProfile: fileConfig.injectProfile ?? DEFAULTS.injectProfile,
233
+ containerTagPrefix: fileConfig.containerTagPrefix ?? DEFAULTS.containerTagPrefix,
234
+ keywordPatterns: [
235
+ ...DEFAULT_KEYWORD_PATTERNS,
236
+ ...(fileConfig.keywordPatterns ?? []).filter(isValidRegex),
237
+ ],
238
+ autoCaptureEnabled: fileConfig.autoCaptureEnabled ?? DEFAULTS.autoCaptureEnabled,
239
+ autoCaptureTokenThreshold: fileConfig.autoCaptureTokenThreshold ?? DEFAULTS.autoCaptureTokenThreshold,
240
+ autoCaptureMinTokens: fileConfig.autoCaptureMinTokens ?? DEFAULTS.autoCaptureMinTokens,
241
+ autoCaptureMaxMemories: fileConfig.autoCaptureMaxMemories ?? DEFAULTS.autoCaptureMaxMemories,
242
+ autoCaptureSummaryMaxLength: fileConfig.autoCaptureSummaryMaxLength ?? DEFAULTS.autoCaptureSummaryMaxLength,
243
+ autoCaptureContextWindow: fileConfig.autoCaptureContextWindow ?? DEFAULTS.autoCaptureContextWindow,
244
+ memoryModel: fileConfig.memoryModel,
245
+ memoryApiUrl: fileConfig.memoryApiUrl,
246
+ memoryApiKey: fileConfig.memoryApiKey,
247
+ webServerEnabled: fileConfig.webServerEnabled ?? DEFAULTS.webServerEnabled,
248
+ webServerPort: fileConfig.webServerPort ?? DEFAULTS.webServerPort,
249
+ webServerHost: fileConfig.webServerHost ?? DEFAULTS.webServerHost,
250
+ maxVectorsPerShard: fileConfig.maxVectorsPerShard ?? DEFAULTS.maxVectorsPerShard,
251
+ autoCleanupEnabled: fileConfig.autoCleanupEnabled ?? DEFAULTS.autoCleanupEnabled,
252
+ autoCleanupRetentionDays: fileConfig.autoCleanupRetentionDays ?? DEFAULTS.autoCleanupRetentionDays,
253
+ deduplicationEnabled: fileConfig.deduplicationEnabled ?? DEFAULTS.deduplicationEnabled,
254
+ deduplicationSimilarityThreshold: fileConfig.deduplicationSimilarityThreshold ?? DEFAULTS.deduplicationSimilarityThreshold,
255
+ };
256
+ export function isConfigured() {
257
+ return true;
258
+ }
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ export declare const OpenCodeMemPlugin: Plugin;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAuC/D,eAAO,MAAM,iBAAiB,EAAE,MAkpB/B,CAAC"}