opencode-mem 2.12.0 → 2.13.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 +25 -5
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +75 -62
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/plugin.d.ts +4 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1 -2
- package/dist/web/app.js +16 -0
- package/dist/web/i18n.js +2 -0
- package/dist/web/index.html +3 -0
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -74,11 +74,9 @@ Configure at `~/.config/opencode/opencode-mem.jsonc`:
|
|
|
74
74
|
|
|
75
75
|
"autoCaptureEnabled": true,
|
|
76
76
|
"autoCaptureLanguage": "auto",
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"memoryApiKey": "sk-...",
|
|
81
|
-
"memoryTemperature": 0.3,
|
|
77
|
+
|
|
78
|
+
"opencodeProvider": "anthropic",
|
|
79
|
+
"opencodeModel": "claude-haiku-4-5-20251001",
|
|
82
80
|
|
|
83
81
|
"showAutoCaptureToasts": true,
|
|
84
82
|
"showUserProfileToasts": true,
|
|
@@ -101,6 +99,28 @@ Configure at `~/.config/opencode/opencode-mem.jsonc`:
|
|
|
101
99
|
}
|
|
102
100
|
```
|
|
103
101
|
|
|
102
|
+
### Auto-Capture AI Provider
|
|
103
|
+
|
|
104
|
+
**Recommended:** Use opencode's built-in providers (no separate API key needed):
|
|
105
|
+
|
|
106
|
+
```jsonc
|
|
107
|
+
"opencodeProvider": "anthropic",
|
|
108
|
+
"opencodeModel": "claude-haiku-4-5-20251001",
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This leverages your existing opencode authentication (OAuth or API key). Works with Claude Pro/Max plans via OAuth - no individual API keys required.
|
|
112
|
+
|
|
113
|
+
Supported providers: `anthropic`, `openai`
|
|
114
|
+
|
|
115
|
+
**Fallback:** Manual API configuration (if not using opencodeProvider):
|
|
116
|
+
|
|
117
|
+
```jsonc
|
|
118
|
+
"memoryProvider": "openai-chat",
|
|
119
|
+
"memoryModel": "gpt-4o-mini",
|
|
120
|
+
"memoryApiUrl": "https://api.openai.com/v1",
|
|
121
|
+
"memoryApiKey": "sk-...",
|
|
122
|
+
```
|
|
123
|
+
|
|
104
124
|
**API Key Formats:**
|
|
105
125
|
|
|
106
126
|
```jsonc
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare let CONFIG: {
|
|
2
2
|
storagePath: string;
|
|
3
3
|
userEmailOverride: string | undefined;
|
|
4
4
|
userNameOverride: string | undefined;
|
|
@@ -54,5 +54,6 @@ export declare const CONFIG: {
|
|
|
54
54
|
injectOn: "first" | "always";
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
|
+
export declare function initConfig(directory: string): void;
|
|
57
58
|
export declare function isConfigured(): boolean;
|
|
58
59
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAohBA,eAAO,IAAI,MAAM;;;;;;;;;;;;;;;;;oBAxDT,aAAa,GACb,kBAAkB,GAClB,WAAW;;;;;;;;mBASX,eAAe,GACf,SAAS,GACT,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoCV,OAAO,GACP,QAAQ;;CAMgC,CAAC;AAEnD,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CASlD;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
|
package/dist/config.js
CHANGED
|
@@ -67,8 +67,8 @@ function expandPath(path) {
|
|
|
67
67
|
}
|
|
68
68
|
return path;
|
|
69
69
|
}
|
|
70
|
-
function
|
|
71
|
-
for (const path of
|
|
70
|
+
function loadConfigFromPaths(paths) {
|
|
71
|
+
for (const path of paths) {
|
|
72
72
|
if (existsSync(path)) {
|
|
73
73
|
try {
|
|
74
74
|
const content = readFileSync(path, "utf-8");
|
|
@@ -80,7 +80,6 @@ function loadConfig() {
|
|
|
80
80
|
}
|
|
81
81
|
return {};
|
|
82
82
|
}
|
|
83
|
-
const fileConfig = loadConfig();
|
|
84
83
|
const CONFIG_TEMPLATE = `{
|
|
85
84
|
// ============================================
|
|
86
85
|
// OpenCode Memory Plugin Configuration
|
|
@@ -347,65 +346,79 @@ function getEmbeddingDimensions(model) {
|
|
|
347
346
|
};
|
|
348
347
|
return dimensionMap[model] || 768;
|
|
349
348
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
349
|
+
function buildConfig(fileConfig) {
|
|
350
|
+
return {
|
|
351
|
+
storagePath: expandPath(fileConfig.storagePath ?? DEFAULTS.storagePath),
|
|
352
|
+
userEmailOverride: fileConfig.userEmailOverride,
|
|
353
|
+
userNameOverride: fileConfig.userNameOverride,
|
|
354
|
+
embeddingModel: fileConfig.embeddingModel ?? DEFAULTS.embeddingModel,
|
|
355
|
+
embeddingDimensions: fileConfig.embeddingDimensions ??
|
|
356
|
+
getEmbeddingDimensions(fileConfig.embeddingModel ?? DEFAULTS.embeddingModel),
|
|
357
|
+
embeddingApiUrl: fileConfig.embeddingApiUrl,
|
|
358
|
+
embeddingApiKey: fileConfig.embeddingApiUrl
|
|
359
|
+
? resolveSecretValue(fileConfig.embeddingApiKey ?? process.env.OPENAI_API_KEY)
|
|
360
|
+
: undefined,
|
|
361
|
+
similarityThreshold: fileConfig.similarityThreshold ?? DEFAULTS.similarityThreshold,
|
|
362
|
+
maxMemories: fileConfig.maxMemories ?? DEFAULTS.maxMemories,
|
|
363
|
+
maxProfileItems: fileConfig.maxProfileItems ?? DEFAULTS.maxProfileItems,
|
|
364
|
+
injectProfile: fileConfig.injectProfile ?? DEFAULTS.injectProfile,
|
|
365
|
+
containerTagPrefix: fileConfig.containerTagPrefix ?? DEFAULTS.containerTagPrefix,
|
|
366
|
+
autoCaptureEnabled: fileConfig.autoCaptureEnabled ?? DEFAULTS.autoCaptureEnabled,
|
|
367
|
+
autoCaptureMaxIterations: fileConfig.autoCaptureMaxIterations ?? DEFAULTS.autoCaptureMaxIterations,
|
|
368
|
+
autoCaptureIterationTimeout: fileConfig.autoCaptureIterationTimeout ?? DEFAULTS.autoCaptureIterationTimeout,
|
|
369
|
+
autoCaptureLanguage: fileConfig.autoCaptureLanguage,
|
|
370
|
+
memoryProvider: (fileConfig.memoryProvider ?? "openai-chat"),
|
|
371
|
+
memoryModel: fileConfig.memoryModel,
|
|
372
|
+
memoryApiUrl: fileConfig.memoryApiUrl,
|
|
373
|
+
memoryApiKey: resolveSecretValue(fileConfig.memoryApiKey),
|
|
374
|
+
memoryTemperature: fileConfig.memoryTemperature,
|
|
375
|
+
memoryExtraParams: fileConfig.memoryExtraParams,
|
|
376
|
+
opencodeProvider: fileConfig.opencodeProvider,
|
|
377
|
+
opencodeModel: fileConfig.opencodeModel,
|
|
378
|
+
vectorBackend: (fileConfig.vectorBackend ?? "usearch-first"),
|
|
379
|
+
aiSessionRetentionDays: fileConfig.aiSessionRetentionDays ?? DEFAULTS.aiSessionRetentionDays,
|
|
380
|
+
webServerEnabled: fileConfig.webServerEnabled ?? DEFAULTS.webServerEnabled,
|
|
381
|
+
webServerPort: fileConfig.webServerPort ?? DEFAULTS.webServerPort,
|
|
382
|
+
webServerHost: fileConfig.webServerHost ?? DEFAULTS.webServerHost,
|
|
383
|
+
maxVectorsPerShard: fileConfig.maxVectorsPerShard ?? DEFAULTS.maxVectorsPerShard,
|
|
384
|
+
autoCleanupEnabled: fileConfig.autoCleanupEnabled ?? DEFAULTS.autoCleanupEnabled,
|
|
385
|
+
autoCleanupRetentionDays: fileConfig.autoCleanupRetentionDays ?? DEFAULTS.autoCleanupRetentionDays,
|
|
386
|
+
deduplicationEnabled: fileConfig.deduplicationEnabled ?? DEFAULTS.deduplicationEnabled,
|
|
387
|
+
deduplicationSimilarityThreshold: fileConfig.deduplicationSimilarityThreshold ?? DEFAULTS.deduplicationSimilarityThreshold,
|
|
388
|
+
userProfileAnalysisInterval: fileConfig.userProfileAnalysisInterval ?? DEFAULTS.userProfileAnalysisInterval,
|
|
389
|
+
userProfileMaxPreferences: fileConfig.userProfileMaxPreferences ?? DEFAULTS.userProfileMaxPreferences,
|
|
390
|
+
userProfileMaxPatterns: fileConfig.userProfileMaxPatterns ?? DEFAULTS.userProfileMaxPatterns,
|
|
391
|
+
userProfileMaxWorkflows: fileConfig.userProfileMaxWorkflows ?? DEFAULTS.userProfileMaxWorkflows,
|
|
392
|
+
userProfileConfidenceDecayDays: fileConfig.userProfileConfidenceDecayDays ?? DEFAULTS.userProfileConfidenceDecayDays,
|
|
393
|
+
userProfileChangelogRetentionCount: fileConfig.userProfileChangelogRetentionCount ?? DEFAULTS.userProfileChangelogRetentionCount,
|
|
394
|
+
showAutoCaptureToasts: fileConfig.showAutoCaptureToasts ?? DEFAULTS.showAutoCaptureToasts,
|
|
395
|
+
showUserProfileToasts: fileConfig.showUserProfileToasts ?? DEFAULTS.showUserProfileToasts,
|
|
396
|
+
showErrorToasts: fileConfig.showErrorToasts ?? DEFAULTS.showErrorToasts,
|
|
397
|
+
compaction: {
|
|
398
|
+
enabled: fileConfig.compaction?.enabled ?? DEFAULTS.compaction.enabled,
|
|
399
|
+
memoryLimit: fileConfig.compaction?.memoryLimit ?? DEFAULTS.compaction.memoryLimit,
|
|
400
|
+
},
|
|
401
|
+
chatMessage: {
|
|
402
|
+
enabled: fileConfig.chatMessage?.enabled ?? DEFAULTS.chatMessage.enabled,
|
|
403
|
+
maxMemories: fileConfig.chatMessage?.maxMemories ?? DEFAULTS.chatMessage.maxMemories,
|
|
404
|
+
excludeCurrentSession: fileConfig.chatMessage?.excludeCurrentSession ?? DEFAULTS.chatMessage.excludeCurrentSession,
|
|
405
|
+
maxAgeDays: fileConfig.chatMessage?.maxAgeDays,
|
|
406
|
+
injectOn: (fileConfig.chatMessage?.injectOn ?? DEFAULTS.chatMessage.injectOn),
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
let _globalFileConfig = loadConfigFromPaths(CONFIG_FILES);
|
|
411
|
+
export let CONFIG = buildConfig(_globalFileConfig);
|
|
412
|
+
export function initConfig(directory) {
|
|
413
|
+
const projectPaths = [
|
|
414
|
+
join(directory, ".opencode", "opencode-mem.jsonc"),
|
|
415
|
+
join(directory, ".opencode", "opencode-mem.json"),
|
|
416
|
+
];
|
|
417
|
+
const globalConfig = loadConfigFromPaths(CONFIG_FILES);
|
|
418
|
+
const projectConfig = loadConfigFromPaths(projectPaths);
|
|
419
|
+
const merged = { ...globalConfig, ...projectConfig };
|
|
420
|
+
CONFIG = buildConfig(merged);
|
|
421
|
+
}
|
|
409
422
|
export function isConfigured() {
|
|
410
423
|
return true;
|
|
411
424
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAmB/D,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAmB/D,eAAO,MAAM,iBAAiB,EAAE,MAgc/B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,12 +7,13 @@ import { performAutoCapture } from "./services/auto-capture.js";
|
|
|
7
7
|
import { performUserProfileLearning } from "./services/user-memory-learning.js";
|
|
8
8
|
import { userPromptManager } from "./services/user-prompt/user-prompt-manager.js";
|
|
9
9
|
import { startWebServer, WebServer } from "./services/web-server.js";
|
|
10
|
-
import { isConfigured, CONFIG } from "./config.js";
|
|
10
|
+
import { isConfigured, CONFIG, initConfig } from "./config.js";
|
|
11
11
|
import { log } from "./services/logger.js";
|
|
12
12
|
import { getLanguageName } from "./services/language-detector.js";
|
|
13
13
|
import { setStatePath, setConnectedProviders } from "./services/ai/opencode-provider.js";
|
|
14
14
|
export const OpenCodeMemPlugin = async (ctx) => {
|
|
15
15
|
const { directory } = ctx;
|
|
16
|
+
initConfig(directory);
|
|
16
17
|
const tags = getTags(directory);
|
|
17
18
|
let webServer = null;
|
|
18
19
|
let idleTimeout = null;
|
|
@@ -330,7 +331,7 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
330
331
|
event: async (input) => {
|
|
331
332
|
const event = input.event;
|
|
332
333
|
if (event.type === "session.idle") {
|
|
333
|
-
if (!isConfigured())
|
|
334
|
+
if (!isConfigured() || !CONFIG.autoCaptureEnabled)
|
|
334
335
|
return;
|
|
335
336
|
const sessionID = event.properties?.sessionID;
|
|
336
337
|
if (!sessionID)
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
declare const OpenCodeMemPlugin: import("@opencode-ai/plugin").Plugin;
|
|
3
2
|
export { OpenCodeMemPlugin };
|
|
4
|
-
|
|
3
|
+
declare const _default: {
|
|
4
|
+
server: import("@opencode-ai/plugin").Plugin;
|
|
5
|
+
};
|
|
6
|
+
export default _default;
|
|
5
7
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,QAAA,MAAQ,iBAAiB,sCAA+B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,CAAC;;;;AAC7B,wBAAoE"}
|
package/dist/plugin.js
CHANGED
package/dist/web/app.js
CHANGED
|
@@ -527,6 +527,21 @@ function deselectAll() {
|
|
|
527
527
|
updateBulkActions();
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
+
function selectAllCurrentPage() {
|
|
531
|
+
const checkboxes = document.querySelectorAll(".memory-checkbox");
|
|
532
|
+
if (checkboxes.length === 0) return;
|
|
533
|
+
|
|
534
|
+
checkboxes.forEach((cb) => {
|
|
535
|
+
cb.checked = true;
|
|
536
|
+
if (cb.dataset.id) {
|
|
537
|
+
state.selectedMemories.add(cb.dataset.id);
|
|
538
|
+
updateCardSelection(cb.dataset.id, true);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
updateBulkActions();
|
|
543
|
+
}
|
|
544
|
+
|
|
530
545
|
function editMemory(id) {
|
|
531
546
|
const memory = state.memories.find((m) => m.id === id && m.type === "memory");
|
|
532
547
|
if (!memory) return;
|
|
@@ -1164,6 +1179,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
1164
1179
|
document.getElementById("next-page-bottom").addEventListener("click", () => changePage(1));
|
|
1165
1180
|
|
|
1166
1181
|
document.getElementById("bulk-delete-btn").addEventListener("click", bulkDelete);
|
|
1182
|
+
document.getElementById("select-all-btn").addEventListener("click", selectAllCurrentPage);
|
|
1167
1183
|
document.getElementById("deselect-all-btn").addEventListener("click", deselectAll);
|
|
1168
1184
|
|
|
1169
1185
|
document.getElementById("cleanup-btn").addEventListener("click", runCleanup);
|
package/dist/web/i18n.js
CHANGED
|
@@ -10,6 +10,7 @@ const translations = {
|
|
|
10
10
|
"btn-cleanup": "Cleanup",
|
|
11
11
|
"btn-deduplicate": "Deduplicate",
|
|
12
12
|
"btn-delete-selected": "Delete Selected",
|
|
13
|
+
"btn-select-all": "Select Page",
|
|
13
14
|
"btn-deselect-all": "Deselect All",
|
|
14
15
|
"btn-add-memory": "Add Memory",
|
|
15
16
|
"section-project": "└─ PROJECT MEMORIES ({count}) ──",
|
|
@@ -116,6 +117,7 @@ const translations = {
|
|
|
116
117
|
"btn-cleanup": "清理",
|
|
117
118
|
"btn-deduplicate": "去重",
|
|
118
119
|
"btn-delete-selected": "删除选中",
|
|
120
|
+
"btn-select-all": "全选当前页",
|
|
119
121
|
"btn-deselect-all": "取消全选",
|
|
120
122
|
"btn-add-memory": "添加记忆",
|
|
121
123
|
"section-project": "└─ 项目记忆 ({count}) ──",
|
package/dist/web/index.html
CHANGED
|
@@ -77,6 +77,9 @@
|
|
|
77
77
|
|
|
78
78
|
<div class="bulk-actions hidden" id="bulk-actions">
|
|
79
79
|
<span id="selected-count" data-i18n="text-selected">0 selected</span>
|
|
80
|
+
<button id="select-all-btn" data-i18n="btn-select-all">
|
|
81
|
+
<i data-lucide="check-square" class="icon"></i> Select Page
|
|
82
|
+
</button>
|
|
80
83
|
<button id="bulk-delete-btn" data-i18n="btn-delete-selected">
|
|
81
84
|
<i data-lucide="trash-2" class="icon"></i> Delete Selected
|
|
82
85
|
</button>
|
package/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-mem",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "OpenCode plugin that gives coding agents persistent memory using local vector database",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/plugin.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/plugin.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./server": {
|
|
14
|
+
"import": "./dist/plugin.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
8
18
|
"scripts": {
|
|
9
19
|
"build": "bunx tsc && mkdir -p dist/web && cp -r src/web/* dist/web/",
|
|
10
20
|
"dev": "tsc --watch",
|
|
@@ -35,8 +45,8 @@
|
|
|
35
45
|
"dependencies": {
|
|
36
46
|
"@ai-sdk/anthropic": "^3.0.58",
|
|
37
47
|
"@ai-sdk/openai": "^3.0.41",
|
|
38
|
-
"@opencode-ai/plugin": "^1.0
|
|
39
|
-
"@opencode-ai/sdk": "^1.
|
|
48
|
+
"@opencode-ai/plugin": "^1.3.0",
|
|
49
|
+
"@opencode-ai/sdk": "^1.3.0",
|
|
40
50
|
"@xenova/transformers": "^2.17.2",
|
|
41
51
|
"ai": "^6.0.116",
|
|
42
52
|
"franc-min": "^6.2.0",
|