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.
- package/README.md +588 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +258 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +618 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +15 -0
- package/dist/services/api-handlers.d.ts +102 -0
- package/dist/services/api-handlers.d.ts.map +1 -0
- package/dist/services/api-handlers.js +494 -0
- package/dist/services/auto-capture.d.ts +32 -0
- package/dist/services/auto-capture.d.ts.map +1 -0
- package/dist/services/auto-capture.js +451 -0
- package/dist/services/cleanup-service.d.ts +20 -0
- package/dist/services/cleanup-service.d.ts.map +1 -0
- package/dist/services/cleanup-service.js +88 -0
- package/dist/services/client.d.ts +104 -0
- package/dist/services/client.d.ts.map +1 -0
- package/dist/services/client.js +251 -0
- package/dist/services/compaction.d.ts +92 -0
- package/dist/services/compaction.d.ts.map +1 -0
- package/dist/services/compaction.js +421 -0
- package/dist/services/context.d.ts +17 -0
- package/dist/services/context.d.ts.map +1 -0
- package/dist/services/context.js +41 -0
- package/dist/services/deduplication-service.d.ts +30 -0
- package/dist/services/deduplication-service.d.ts.map +1 -0
- package/dist/services/deduplication-service.js +131 -0
- package/dist/services/embedding.d.ts +10 -0
- package/dist/services/embedding.d.ts.map +1 -0
- package/dist/services/embedding.js +77 -0
- package/dist/services/jsonc.d.ts +7 -0
- package/dist/services/jsonc.d.ts.map +1 -0
- package/dist/services/jsonc.js +76 -0
- package/dist/services/logger.d.ts +2 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +16 -0
- package/dist/services/migration-service.d.ts +42 -0
- package/dist/services/migration-service.d.ts.map +1 -0
- package/dist/services/migration-service.js +258 -0
- package/dist/services/privacy.d.ts +4 -0
- package/dist/services/privacy.d.ts.map +1 -0
- package/dist/services/privacy.js +10 -0
- package/dist/services/sqlite/connection-manager.d.ts +10 -0
- package/dist/services/sqlite/connection-manager.d.ts.map +1 -0
- package/dist/services/sqlite/connection-manager.js +45 -0
- package/dist/services/sqlite/shard-manager.d.ts +20 -0
- package/dist/services/sqlite/shard-manager.d.ts.map +1 -0
- package/dist/services/sqlite/shard-manager.js +221 -0
- package/dist/services/sqlite/types.d.ts +39 -0
- package/dist/services/sqlite/types.d.ts.map +1 -0
- package/dist/services/sqlite/types.js +1 -0
- package/dist/services/sqlite/vector-search.d.ts +18 -0
- package/dist/services/sqlite/vector-search.d.ts.map +1 -0
- package/dist/services/sqlite/vector-search.js +129 -0
- package/dist/services/sqlite-client.d.ts +116 -0
- package/dist/services/sqlite-client.d.ts.map +1 -0
- package/dist/services/sqlite-client.js +284 -0
- package/dist/services/tags.d.ts +20 -0
- package/dist/services/tags.d.ts.map +1 -0
- package/dist/services/tags.js +76 -0
- package/dist/services/web-server-lock.d.ts +12 -0
- package/dist/services/web-server-lock.d.ts.map +1 -0
- package/dist/services/web-server-lock.js +157 -0
- package/dist/services/web-server-worker.d.ts +2 -0
- package/dist/services/web-server-worker.d.ts.map +1 -0
- package/dist/services/web-server-worker.js +221 -0
- package/dist/services/web-server.d.ts +22 -0
- package/dist/services/web-server.d.ts.map +1 -0
- package/dist/services/web-server.js +134 -0
- package/dist/types/index.d.ts +48 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/web/app.d.ts +2 -0
- package/dist/web/app.d.ts.map +1 -0
- package/dist/web/app.js +691 -0
- package/dist/web/favicon.ico +0 -0
- package/dist/web/favicon.svg +14 -0
- package/dist/web/index.html +202 -0
- package/dist/web/styles.css +851 -0
- 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
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|