@xiaoxiamimengfb/my-opencode-mem 2.12.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 (152) hide show
  1. package/README.md +155 -0
  2. package/dist/config.d.ts +58 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +411 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +427 -0
  8. package/dist/plugin.d.ts +5 -0
  9. package/dist/plugin.d.ts.map +1 -0
  10. package/dist/plugin.js +4 -0
  11. package/dist/services/ai/ai-provider-factory.d.ts +8 -0
  12. package/dist/services/ai/ai-provider-factory.d.ts.map +1 -0
  13. package/dist/services/ai/ai-provider-factory.js +28 -0
  14. package/dist/services/ai/opencode-provider.d.ts +30 -0
  15. package/dist/services/ai/opencode-provider.d.ts.map +1 -0
  16. package/dist/services/ai/opencode-provider.js +332 -0
  17. package/dist/services/ai/provider-config.d.ts +17 -0
  18. package/dist/services/ai/provider-config.d.ts.map +1 -0
  19. package/dist/services/ai/provider-config.js +14 -0
  20. package/dist/services/ai/providers/anthropic-messages.d.ts +12 -0
  21. package/dist/services/ai/providers/anthropic-messages.d.ts.map +1 -0
  22. package/dist/services/ai/providers/anthropic-messages.js +184 -0
  23. package/dist/services/ai/providers/base-provider.d.ts +25 -0
  24. package/dist/services/ai/providers/base-provider.d.ts.map +1 -0
  25. package/dist/services/ai/providers/base-provider.js +23 -0
  26. package/dist/services/ai/providers/google-gemini.d.ts +16 -0
  27. package/dist/services/ai/providers/google-gemini.d.ts.map +1 -0
  28. package/dist/services/ai/providers/google-gemini.js +228 -0
  29. package/dist/services/ai/providers/openai-chat-completion.d.ts +13 -0
  30. package/dist/services/ai/providers/openai-chat-completion.d.ts.map +1 -0
  31. package/dist/services/ai/providers/openai-chat-completion.js +277 -0
  32. package/dist/services/ai/providers/openai-responses.d.ts +14 -0
  33. package/dist/services/ai/providers/openai-responses.d.ts.map +1 -0
  34. package/dist/services/ai/providers/openai-responses.js +182 -0
  35. package/dist/services/ai/session/ai-session-manager.d.ts +21 -0
  36. package/dist/services/ai/session/ai-session-manager.d.ts.map +1 -0
  37. package/dist/services/ai/session/ai-session-manager.js +166 -0
  38. package/dist/services/ai/session/session-types.d.ts +43 -0
  39. package/dist/services/ai/session/session-types.d.ts.map +1 -0
  40. package/dist/services/ai/session/session-types.js +1 -0
  41. package/dist/services/ai/tools/tool-schema.d.ts +41 -0
  42. package/dist/services/ai/tools/tool-schema.d.ts.map +1 -0
  43. package/dist/services/ai/tools/tool-schema.js +24 -0
  44. package/dist/services/ai/validators/user-profile-validator.d.ts +13 -0
  45. package/dist/services/ai/validators/user-profile-validator.d.ts.map +1 -0
  46. package/dist/services/ai/validators/user-profile-validator.js +111 -0
  47. package/dist/services/api-handlers.d.ts +164 -0
  48. package/dist/services/api-handlers.d.ts.map +1 -0
  49. package/dist/services/api-handlers.js +901 -0
  50. package/dist/services/auto-capture.d.ts +3 -0
  51. package/dist/services/auto-capture.d.ts.map +1 -0
  52. package/dist/services/auto-capture.js +306 -0
  53. package/dist/services/cleanup-service.d.ts +23 -0
  54. package/dist/services/cleanup-service.d.ts.map +1 -0
  55. package/dist/services/cleanup-service.js +102 -0
  56. package/dist/services/client.d.ts +118 -0
  57. package/dist/services/client.d.ts.map +1 -0
  58. package/dist/services/client.js +251 -0
  59. package/dist/services/context.d.ts +11 -0
  60. package/dist/services/context.d.ts.map +1 -0
  61. package/dist/services/context.js +24 -0
  62. package/dist/services/deduplication-service.d.ts +30 -0
  63. package/dist/services/deduplication-service.d.ts.map +1 -0
  64. package/dist/services/deduplication-service.js +124 -0
  65. package/dist/services/embedding.d.ts +15 -0
  66. package/dist/services/embedding.d.ts.map +1 -0
  67. package/dist/services/embedding.js +106 -0
  68. package/dist/services/jsonc.d.ts +7 -0
  69. package/dist/services/jsonc.d.ts.map +1 -0
  70. package/dist/services/jsonc.js +76 -0
  71. package/dist/services/language-detector.d.ts +3 -0
  72. package/dist/services/language-detector.d.ts.map +1 -0
  73. package/dist/services/language-detector.js +16 -0
  74. package/dist/services/logger.d.ts +2 -0
  75. package/dist/services/logger.d.ts.map +1 -0
  76. package/dist/services/logger.js +51 -0
  77. package/dist/services/migration-service.d.ts +42 -0
  78. package/dist/services/migration-service.d.ts.map +1 -0
  79. package/dist/services/migration-service.js +250 -0
  80. package/dist/services/privacy.d.ts +3 -0
  81. package/dist/services/privacy.d.ts.map +1 -0
  82. package/dist/services/privacy.js +7 -0
  83. package/dist/services/secret-resolver.d.ts +2 -0
  84. package/dist/services/secret-resolver.d.ts.map +1 -0
  85. package/dist/services/secret-resolver.js +55 -0
  86. package/dist/services/sqlite/connection-manager.d.ts +13 -0
  87. package/dist/services/sqlite/connection-manager.d.ts.map +1 -0
  88. package/dist/services/sqlite/connection-manager.js +74 -0
  89. package/dist/services/sqlite/shard-manager.d.ts +23 -0
  90. package/dist/services/sqlite/shard-manager.d.ts.map +1 -0
  91. package/dist/services/sqlite/shard-manager.js +288 -0
  92. package/dist/services/sqlite/sqlite-bootstrap.d.ts +2 -0
  93. package/dist/services/sqlite/sqlite-bootstrap.d.ts.map +1 -0
  94. package/dist/services/sqlite/sqlite-bootstrap.js +8 -0
  95. package/dist/services/sqlite/types.d.ts +42 -0
  96. package/dist/services/sqlite/types.d.ts.map +1 -0
  97. package/dist/services/sqlite/types.js +1 -0
  98. package/dist/services/sqlite/vector-search.d.ts +29 -0
  99. package/dist/services/sqlite/vector-search.d.ts.map +1 -0
  100. package/dist/services/sqlite/vector-search.js +268 -0
  101. package/dist/services/tags.d.ts +24 -0
  102. package/dist/services/tags.d.ts.map +1 -0
  103. package/dist/services/tags.js +146 -0
  104. package/dist/services/user-memory-learning.d.ts +3 -0
  105. package/dist/services/user-memory-learning.d.ts.map +1 -0
  106. package/dist/services/user-memory-learning.js +231 -0
  107. package/dist/services/user-profile/profile-context.d.ts +2 -0
  108. package/dist/services/user-profile/profile-context.d.ts.map +1 -0
  109. package/dist/services/user-profile/profile-context.js +40 -0
  110. package/dist/services/user-profile/profile-utils.d.ts +3 -0
  111. package/dist/services/user-profile/profile-utils.d.ts.map +1 -0
  112. package/dist/services/user-profile/profile-utils.js +45 -0
  113. package/dist/services/user-profile/types.d.ts +46 -0
  114. package/dist/services/user-profile/types.d.ts.map +1 -0
  115. package/dist/services/user-profile/types.js +1 -0
  116. package/dist/services/user-profile/user-profile-manager.d.ts +23 -0
  117. package/dist/services/user-profile/user-profile-manager.d.ts.map +1 -0
  118. package/dist/services/user-profile/user-profile-manager.js +292 -0
  119. package/dist/services/user-prompt/user-prompt-manager.d.ts +41 -0
  120. package/dist/services/user-prompt/user-prompt-manager.d.ts.map +1 -0
  121. package/dist/services/user-prompt/user-prompt-manager.js +192 -0
  122. package/dist/services/vector-backends/backend-factory.d.ts +3 -0
  123. package/dist/services/vector-backends/backend-factory.d.ts.map +1 -0
  124. package/dist/services/vector-backends/backend-factory.js +104 -0
  125. package/dist/services/vector-backends/exact-scan-backend.d.ts +39 -0
  126. package/dist/services/vector-backends/exact-scan-backend.d.ts.map +1 -0
  127. package/dist/services/vector-backends/exact-scan-backend.js +63 -0
  128. package/dist/services/vector-backends/types.d.ts +51 -0
  129. package/dist/services/vector-backends/types.d.ts.map +1 -0
  130. package/dist/services/vector-backends/types.js +1 -0
  131. package/dist/services/vector-backends/usearch-backend.d.ts +47 -0
  132. package/dist/services/vector-backends/usearch-backend.d.ts.map +1 -0
  133. package/dist/services/vector-backends/usearch-backend.js +174 -0
  134. package/dist/services/web-server-worker.d.ts +2 -0
  135. package/dist/services/web-server-worker.d.ts.map +1 -0
  136. package/dist/services/web-server-worker.js +283 -0
  137. package/dist/services/web-server.d.ts +31 -0
  138. package/dist/services/web-server.d.ts.map +1 -0
  139. package/dist/services/web-server.js +356 -0
  140. package/dist/types/index.d.ts +19 -0
  141. package/dist/types/index.d.ts.map +1 -0
  142. package/dist/types/index.js +1 -0
  143. package/dist/web/app.d.ts +2 -0
  144. package/dist/web/app.d.ts.map +1 -0
  145. package/dist/web/app.js +1194 -0
  146. package/dist/web/favicon.ico +0 -0
  147. package/dist/web/i18n.d.ts +2 -0
  148. package/dist/web/i18n.d.ts.map +1 -0
  149. package/dist/web/i18n.js +265 -0
  150. package/dist/web/index.html +284 -0
  151. package/dist/web/styles.css +1631 -0
  152. package/package.json +71 -0
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # OpenCode Memory
2
+
3
+ [![npm version](https://img.shields.io/npm/v/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem)
4
+ [![npm downloads](https://img.shields.io/npm/dm/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem)
5
+ [![license](https://img.shields.io/npm/l/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem)
6
+
7
+ ![OpenCode Memory Banner](.github/banner.png)
8
+
9
+ A persistent memory system for AI coding agents that enables long-term context retention across sessions using local vector database technology.
10
+
11
+ ## Visual Overview
12
+
13
+ **Project Memory Timeline:**
14
+
15
+ ![Project Memory Timeline](.github/screenshot-project-memory.png)
16
+
17
+ **User Profile Viewer:**
18
+
19
+ ![User Profile Viewer](.github/screenshot-user-profile.png)
20
+
21
+ ## Core Features
22
+
23
+ Local vector database with SQLite + USearch-first vector indexing and ExactScan fallback, persistent project memories, automatic user profile learning, unified memory-prompt timeline, full-featured web UI, intelligent prompt-based memory extraction, multi-provider AI support (OpenAI, Anthropic), 12+ local embedding models, smart deduplication, and built-in privacy protection.
24
+
25
+ ## Prerequisites
26
+
27
+ This plugin uses `USearch` for preferred in-memory vector indexing with automatic ExactScan fallback. No custom SQLite build or browser runtime shim is required.
28
+
29
+ **Recommended runtime:**
30
+
31
+ - Bun
32
+ - Standard OpenCode plugin environment
33
+
34
+ **Notes:**
35
+
36
+ - If `USearch` is unavailable or fails at runtime, the plugin automatically falls back to exact vector scanning.
37
+ - SQLite remains the source of truth; search indexes are rebuilt from SQLite data when needed.
38
+
39
+ ## Getting Started
40
+
41
+ Add to your OpenCode configuration at `~/.config/opencode/opencode.json`:
42
+
43
+ ```jsonc
44
+ {
45
+ "plugin": ["opencode-mem"],
46
+ }
47
+ ```
48
+
49
+ The plugin downloads automatically on next startup.
50
+
51
+ ## Usage Examples
52
+
53
+ ```typescript
54
+ memory({ mode: "add", content: "Project uses microservices architecture" });
55
+ memory({ mode: "search", query: "architecture decisions" });
56
+ memory({ mode: "profile" });
57
+ memory({ mode: "list", limit: 10 });
58
+ ```
59
+
60
+ Access the web interface at `http://127.0.0.1:4747` for visual memory browsing and management.
61
+
62
+ ## Configuration Essentials
63
+
64
+ Configure at `~/.config/opencode/opencode-mem.jsonc`:
65
+
66
+ ```jsonc
67
+ {
68
+ "storagePath": "~/.opencode-mem/data",
69
+ "userEmailOverride": "user@example.com",
70
+ "userNameOverride": "John Doe",
71
+ "embeddingModel": "Xenova/nomic-embed-text-v1",
72
+ "webServerEnabled": true,
73
+ "webServerPort": 4747,
74
+
75
+ "autoCaptureEnabled": true,
76
+ "autoCaptureLanguage": "auto",
77
+
78
+ "opencodeProvider": "anthropic",
79
+ "opencodeModel": "claude-haiku-4-5-20251001",
80
+
81
+ "showAutoCaptureToasts": true,
82
+ "showUserProfileToasts": true,
83
+ "showErrorToasts": true,
84
+
85
+ "userProfileAnalysisInterval": 10,
86
+ "maxMemories": 10,
87
+
88
+ "compaction": {
89
+ "enabled": true,
90
+ "memoryLimit": 10,
91
+ },
92
+ "chatMessage": {
93
+ "enabled": true,
94
+ "maxMemories": 3,
95
+ "excludeCurrentSession": true,
96
+ "maxAgeDays": undefined,
97
+ "injectOn": "first",
98
+ },
99
+ }
100
+ ```
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
+
124
+ **API Key Formats:**
125
+
126
+ ```jsonc
127
+ "memoryApiKey": "sk-..."
128
+ "memoryApiKey": "file://~/.config/opencode/api-key.txt"
129
+ "memoryApiKey": "env://OPENAI_API_KEY"
130
+ ```
131
+
132
+ Full documentation available in this README.
133
+
134
+ ## Development & Contribution
135
+
136
+ Build and test locally:
137
+
138
+ ```bash
139
+ bun install
140
+ bun run build
141
+ bun run typecheck
142
+ bun run format
143
+ ```
144
+
145
+ This project is actively seeking contributions to become the definitive memory plugin for AI coding agents. Whether you are fixing bugs, adding features, improving documentation, or expanding embedding model support, your contributions are critical. The codebase is well-structured and ready for enhancement. If you hit a blocker or have improvement ideas, submit a pull request - we review and merge contributions quickly.
146
+
147
+ ## License & Links
148
+
149
+ MIT License - see LICENSE file
150
+
151
+ - **Repository**: https://github.com/tickernelz/opencode-mem
152
+ - **Issues**: https://github.com/tickernelz/opencode-mem/issues
153
+ - **OpenCode Platform**: https://opencode.ai
154
+
155
+ Inspired by [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory)
@@ -0,0 +1,58 @@
1
+ export declare const CONFIG: {
2
+ storagePath: string;
3
+ userEmailOverride: string | undefined;
4
+ userNameOverride: string | undefined;
5
+ embeddingModel: string;
6
+ embeddingDimensions: number;
7
+ embeddingApiUrl: string | undefined;
8
+ embeddingApiKey: string | undefined;
9
+ similarityThreshold: number;
10
+ maxMemories: number;
11
+ maxProfileItems: number;
12
+ injectProfile: boolean;
13
+ containerTagPrefix: string;
14
+ autoCaptureEnabled: boolean;
15
+ autoCaptureMaxIterations: number;
16
+ autoCaptureIterationTimeout: number;
17
+ autoCaptureLanguage: string | undefined;
18
+ memoryProvider: "openai-chat" | "openai-responses" | "anthropic";
19
+ memoryModel: string | undefined;
20
+ memoryApiUrl: string | undefined;
21
+ memoryApiKey: string | undefined;
22
+ memoryTemperature: number | false | undefined;
23
+ memoryExtraParams: Record<string, unknown> | undefined;
24
+ opencodeProvider: string | undefined;
25
+ opencodeModel: string | undefined;
26
+ vectorBackend: "usearch-first" | "usearch" | "exact-scan";
27
+ aiSessionRetentionDays: number;
28
+ webServerEnabled: boolean;
29
+ webServerPort: number;
30
+ webServerHost: string;
31
+ maxVectorsPerShard: number;
32
+ autoCleanupEnabled: boolean;
33
+ autoCleanupRetentionDays: number;
34
+ deduplicationEnabled: boolean;
35
+ deduplicationSimilarityThreshold: number;
36
+ userProfileAnalysisInterval: number;
37
+ userProfileMaxPreferences: number;
38
+ userProfileMaxPatterns: number;
39
+ userProfileMaxWorkflows: number;
40
+ userProfileConfidenceDecayDays: number;
41
+ userProfileChangelogRetentionCount: number;
42
+ showAutoCaptureToasts: boolean;
43
+ showUserProfileToasts: boolean;
44
+ showErrorToasts: boolean;
45
+ compaction: {
46
+ enabled: boolean | undefined;
47
+ memoryLimit: number | undefined;
48
+ };
49
+ chatMessage: {
50
+ enabled: boolean | undefined;
51
+ maxMemories: number | undefined;
52
+ excludeCurrentSession: boolean | undefined;
53
+ maxAgeDays: number | undefined;
54
+ injectOn: "first" | "always";
55
+ };
56
+ };
57
+ export declare function isConfigured(): boolean;
58
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAqcA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;oBAwBb,aAAa,GACb,kBAAkB,GAClB,WAAW;;;;;;;;mBASX,eAAe,GACf,SAAS,GACT,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoCV,OAAO,GACP,QAAQ;;CAEf,CAAC;AAEF,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
package/dist/config.js ADDED
@@ -0,0 +1,411 @@
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
+ import { resolveSecretValue } from "./services/secret-resolver.js";
6
+ const CONFIG_DIR = join(homedir(), ".config", "opencode");
7
+ const DATA_DIR = join(homedir(), ".opencode-mem");
8
+ const CONFIG_FILES = [
9
+ join(CONFIG_DIR, "opencode-mem.jsonc"),
10
+ join(CONFIG_DIR, "opencode-mem.json"),
11
+ ];
12
+ if (!existsSync(CONFIG_DIR)) {
13
+ mkdirSync(CONFIG_DIR, { recursive: true });
14
+ }
15
+ if (!existsSync(DATA_DIR)) {
16
+ mkdirSync(DATA_DIR, { recursive: true });
17
+ }
18
+ const DEFAULTS = {
19
+ storagePath: join(DATA_DIR, "data"),
20
+ embeddingModel: "Xenova/nomic-embed-text-v1",
21
+ embeddingDimensions: 768,
22
+ similarityThreshold: 0.6,
23
+ maxMemories: 10,
24
+ maxProfileItems: 5,
25
+ injectProfile: true,
26
+ containerTagPrefix: "opencode",
27
+ autoCaptureEnabled: true,
28
+ autoCaptureMaxIterations: 5,
29
+ autoCaptureIterationTimeout: 30000,
30
+ vectorBackend: "usearch-first",
31
+ aiSessionRetentionDays: 7,
32
+ webServerEnabled: true,
33
+ webServerPort: 4747,
34
+ webServerHost: "127.0.0.1",
35
+ maxVectorsPerShard: 50000,
36
+ autoCleanupEnabled: true,
37
+ autoCleanupRetentionDays: 30,
38
+ deduplicationEnabled: true,
39
+ deduplicationSimilarityThreshold: 0.9,
40
+ userProfileAnalysisInterval: 10,
41
+ userProfileMaxPreferences: 20,
42
+ userProfileMaxPatterns: 15,
43
+ userProfileMaxWorkflows: 10,
44
+ userProfileConfidenceDecayDays: 30,
45
+ userProfileChangelogRetentionCount: 5,
46
+ showAutoCaptureToasts: true,
47
+ showUserProfileToasts: true,
48
+ showErrorToasts: true,
49
+ compaction: {
50
+ enabled: true,
51
+ memoryLimit: 10,
52
+ },
53
+ chatMessage: {
54
+ enabled: true,
55
+ maxMemories: 3,
56
+ excludeCurrentSession: true,
57
+ maxAgeDays: undefined,
58
+ injectOn: "first",
59
+ },
60
+ };
61
+ function expandPath(path) {
62
+ if (path.startsWith("~/")) {
63
+ return join(homedir(), path.slice(2));
64
+ }
65
+ if (path === "~") {
66
+ return homedir();
67
+ }
68
+ return path;
69
+ }
70
+ function loadConfig() {
71
+ for (const path of CONFIG_FILES) {
72
+ if (existsSync(path)) {
73
+ try {
74
+ const content = readFileSync(path, "utf-8");
75
+ const json = stripJsoncComments(content);
76
+ return JSON.parse(json);
77
+ }
78
+ catch { }
79
+ }
80
+ }
81
+ return {};
82
+ }
83
+ const fileConfig = loadConfig();
84
+ const CONFIG_TEMPLATE = `{
85
+ // ============================================
86
+ // OpenCode Memory Plugin Configuration
87
+ // ============================================
88
+
89
+ // Storage location for vector database
90
+ "storagePath": "~/.opencode-mem/data",
91
+
92
+ "userEmailOverride": "",
93
+ "userNameOverride": "",
94
+
95
+ // ============================================
96
+ // Embedding Model (for similarity search)
97
+ // ============================================
98
+
99
+ // Default: Nomic Embed v1 (768 dimensions, 8192 context, multilingual)
100
+ "embeddingModel": "Xenova/nomic-embed-text-v1",
101
+
102
+ // Auto-detected dimensions (no need to set manually)
103
+ // "embeddingDimensions": 768,
104
+
105
+ // Other recommended models:
106
+ // "embeddingModel": "Xenova/jina-embeddings-v2-base-en", // 768 dims, English-only, 8192 context
107
+ // "embeddingModel": "Xenova/jina-embeddings-v2-small-en", // 512 dims, faster, 8192 context
108
+ // "embeddingModel": "Xenova/all-MiniLM-L6-v2", // 384 dims, very fast, 512 context
109
+ // "embeddingModel": "Xenova/all-mpnet-base-v2", // 768 dims, good quality, 512 context
110
+
111
+ // Optional: Use OpenAI-compatible API for embeddings
112
+ // "embeddingApiUrl": "https://api.openai.com/v1",
113
+ // "embeddingApiKey": "sk-...",
114
+ // "embeddingModel": "text-embedding-3-small", // 1536 dims, auto-detected
115
+
116
+ // ============================================
117
+ // Web Server Settings
118
+ // ============================================
119
+
120
+ // Enable web UI for managing memories (accessible at http://localhost:4747)
121
+ "webServerEnabled": true,
122
+
123
+ // Port for web UI server
124
+ "webServerPort": 4747,
125
+
126
+ // Host address for web UI (use 127.0.0.1 for local only, 0.0.0.0 for network access)
127
+ "webServerHost": "127.0.0.1",
128
+
129
+ // ============================================
130
+ // Database Settings
131
+ // ============================================
132
+
133
+ // Maximum vectors per database shard (auto-creates new shard when limit reached)
134
+ "maxVectorsPerShard": 50000,
135
+
136
+ // Automatically delete old memories based on retention period
137
+ "autoCleanupEnabled": true,
138
+
139
+ // Days to keep memories before auto-cleanup (only if autoCleanupEnabled is true)
140
+ "autoCleanupRetentionDays": 30,
141
+
142
+ // Automatically detect and remove duplicate memories
143
+ "deduplicationEnabled": true,
144
+
145
+ // Similarity threshold (0-1) for detecting duplicates (higher = stricter)
146
+ "deduplicationSimilarityThreshold": 0.90,
147
+
148
+ // ============================================
149
+ // OpenCode Provider Settings (RECOMMENDED)
150
+ // ============================================
151
+
152
+ // Use opencode's already-configured providers for auto-capture and user profile learning.
153
+ // When set, no separate API key is needed — uses your existing opencode authentication
154
+ // (including Claude Pro/Max plans via OAuth, or any API key configured in opencode).
155
+ //
156
+ // If NOT set, falls back to the manual config (memoryApiKey/memoryApiUrl/memoryModel below).
157
+ //
158
+ // Examples:
159
+ // Anthropic (OAuth/API key): "opencodeProvider": "anthropic", "opencodeModel": "claude-haiku-4-5-20251001"
160
+ // OpenAI (API key): "opencodeProvider": "openai", "opencodeModel": "gpt-4o-mini"
161
+ //
162
+ // The provider name must match a connected provider in opencode (check with: opencode providers list)
163
+ // "opencodeProvider": "anthropic",
164
+ // "opencodeModel": "claude-haiku-4-5-20251001",
165
+
166
+ // ============================================
167
+ // Auto-Capture Settings (REQUIRES EXTERNAL API)
168
+ // ============================================
169
+
170
+ // IMPORTANT: Auto-capture ONLY works with external API
171
+ // It runs in background without blocking your main session
172
+ // Note: Ollama may not support tool calling. Use OpenAI, Anthropic, or Groq for best results.
173
+
174
+ "autoCaptureEnabled": true,
175
+
176
+ // Provider type: "openai-chat" | "openai-responses" | "anthropic"
177
+ "memoryProvider": "openai-chat",
178
+
179
+ // REQUIRED for auto-capture (all 3 must be set):
180
+ "memoryModel": "gpt-4o-mini",
181
+ "memoryApiUrl": "https://api.openai.com/v1",
182
+ "memoryApiKey": "sk-...",
183
+
184
+ // API Key Formats:
185
+ // Direct value: "sk-..."
186
+ // From file: "file://~/.config/litellm-key.txt"
187
+ // From env variable: "env://LITELLM_API_KEY"
188
+
189
+ // Examples for different providers:
190
+ // OpenAI Chat Completion (default, backward compatible):
191
+ // "memoryProvider": "openai-chat"
192
+ // "memoryModel": "gpt-4o-mini"
193
+ // "memoryApiUrl": "https://api.openai.com/v1"
194
+ // "memoryApiKey": "sk-..."
195
+
196
+ // OpenAI Responses API (recommended, with session support):
197
+ // "memoryProvider": "openai-responses"
198
+ // "memoryModel": "gpt-4o"
199
+ // "memoryApiUrl": "https://api.openai.com/v1"
200
+ // "memoryApiKey": "sk-..."
201
+
202
+ // Anthropic (with session support):
203
+ // "memoryProvider": "anthropic"
204
+ // "memoryModel": "claude-3-5-haiku-20241022"
205
+ // "memoryApiUrl": "https://api.anthropic.com/v1"
206
+ // "memoryApiKey": "sk-ant-..."
207
+
208
+ // Groq (OpenAI-compatible, use openai-chat provider):
209
+ // "memoryProvider": "openai-chat"
210
+ // "memoryModel": "llama-3.3-70b-versatile"
211
+ // "memoryApiUrl": "https://api.groq.com/openai/v1"
212
+ // "memoryApiKey": "gsk_..."
213
+
214
+ // Maximum iterations for multi-turn AI analysis (for openai-responses and anthropic)
215
+ "autoCaptureMaxIterations": 5,
216
+
217
+ // Timeout per iteration in milliseconds (30 seconds default)
218
+ "autoCaptureIterationTimeout": 30000,
219
+
220
+ // Days to keep AI session history before cleanup
221
+ "aiSessionRetentionDays": 7,
222
+
223
+ // Temperature for AI API requests (set to false to omit parameter for models that don't support it)
224
+ // Some reasoning models (like o1, o3, gpt-5) don't support temperature parameter
225
+ // Set to false and add "memoryTemperature": false in config when using such models
226
+ "memoryTemperature": 0.3,
227
+
228
+ // Extra parameters to include in API request body
229
+ // Useful for local inference servers (e.g. llama-server with --jinja) that support
230
+ // additional parameters like disabling thinking/reasoning mode
231
+ // Example for Qwen3 models: { "enable_thinking": false }
232
+ // "memoryExtraParams": {},
233
+
234
+ // Language for auto-capture summaries (default: "auto" for auto-detection)
235
+ // Options: "auto", "en", "id", "zh", "ja", "es", "fr", "de", "ru", "pt", "ar", "ko"
236
+ // "autoCaptureLanguage": "auto",
237
+
238
+ // ============================================
239
+ // Toast Notifications
240
+ // ============================================
241
+
242
+ // Show toast when memory is auto-captured
243
+ "showAutoCaptureToasts": true,
244
+
245
+ // Show toast when user profile is updated
246
+ "showUserProfileToasts": true,
247
+
248
+ // Show toast for error messages
249
+ "showErrorToasts": true,
250
+
251
+ // ============================================
252
+ // User Profile System
253
+ // ============================================
254
+
255
+ // Analyze user prompts every N prompts to build/update your user profile
256
+ // When N uncaptured prompts accumulate, AI will analyze them to identify:
257
+ // - User preferences (code style, communication style, tool preferences)
258
+ // - User patterns (recurring topics, problem domains, technical interests)
259
+ // - User workflows (development habits, sequences, learning style)
260
+ // - Skill level (overall and per-domain assessment)
261
+ "userProfileAnalysisInterval": 10,
262
+
263
+ // Maximum number of preferences to keep in user profile (sorted by confidence)
264
+ // Preferences are things like "prefers code without comments", "likes concise responses"
265
+ "userProfileMaxPreferences": 20,
266
+
267
+ // Maximum number of patterns to keep in user profile (sorted by frequency)
268
+ // Patterns are recurring topics like "often asks about database optimization"
269
+ "userProfileMaxPatterns": 15,
270
+
271
+ // Maximum number of workflows to keep in user profile (sorted by frequency)
272
+ // Workflows are sequences like "usually asks for tests after implementation"
273
+ "userProfileMaxWorkflows": 10,
274
+
275
+ // Days before preference confidence starts to decay (if not reinforced)
276
+ // Preferences that aren't seen again will gradually lose confidence and be removed
277
+ "userProfileConfidenceDecayDays": 30,
278
+
279
+ // Number of profile versions to keep in changelog (for rollback/debugging)
280
+ // Older versions are automatically cleaned up
281
+ "userProfileChangelogRetentionCount": 5,
282
+
283
+ // ============================================
284
+ // Search Settings
285
+ // ============================================
286
+
287
+ // Minimum similarity score (0-1) for memory search results
288
+ "similarityThreshold": 0.6,
289
+
290
+ // Maximum number of memories to return in search results
291
+ "maxMemories": 10,
292
+
293
+ // ============================================
294
+ // Advanced Settings
295
+ // ============================================
296
+
297
+ // Inject user profile into AI context (preferences, patterns, workflows)
298
+ "injectProfile": true
299
+ }
300
+ `;
301
+ function ensureConfigExists() {
302
+ const configPath = join(CONFIG_DIR, "opencode-mem.jsonc");
303
+ if (!existsSync(configPath)) {
304
+ try {
305
+ writeFileSync(configPath, CONFIG_TEMPLATE, "utf-8");
306
+ console.log(`\n✓ Created config template: ${configPath}`);
307
+ console.log(" Edit this file to customize opencode-mem settings.\n");
308
+ }
309
+ catch { }
310
+ }
311
+ }
312
+ ensureConfigExists();
313
+ function getEmbeddingDimensions(model) {
314
+ const dimensionMap = {
315
+ // Local Xenova models
316
+ "Xenova/nomic-embed-text-v1": 768,
317
+ "Xenova/nomic-embed-text-v1-unsupervised": 768,
318
+ "Xenova/nomic-embed-text-v1-ablated": 768,
319
+ "Xenova/jina-embeddings-v2-base-en": 768,
320
+ "Xenova/jina-embeddings-v2-base-zh": 768,
321
+ "Xenova/jina-embeddings-v2-base-de": 768,
322
+ "Xenova/jina-embeddings-v2-small-en": 512,
323
+ "Xenova/all-MiniLM-L6-v2": 384,
324
+ "Xenova/all-MiniLM-L12-v2": 384,
325
+ "Xenova/all-mpnet-base-v2": 768,
326
+ "Xenova/bge-base-en-v1.5": 768,
327
+ "Xenova/bge-small-en-v1.5": 384,
328
+ "Xenova/gte-small": 384,
329
+ "Xenova/GIST-small-Embedding-v0": 384,
330
+ "Xenova/text-embedding-ada-002": 1536,
331
+ // OpenAI API models
332
+ "text-embedding-3-small": 1536,
333
+ "text-embedding-3-large": 3072,
334
+ "text-embedding-ada-002": 1536,
335
+ // Cohere API models
336
+ "embed-english-v3.0": 1024,
337
+ "embed-multilingual-v3.0": 1024,
338
+ "embed-english-light-v3.0": 384,
339
+ "embed-multilingual-light-v3.0": 384,
340
+ // Google API models
341
+ "text-embedding-004": 768,
342
+ "text-multilingual-embedding-002": 768,
343
+ // Voyage AI models
344
+ "voyage-3": 1024,
345
+ "voyage-3-lite": 512,
346
+ "voyage-code-3": 1024,
347
+ };
348
+ return dimensionMap[model] || 768;
349
+ }
350
+ export const CONFIG = {
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
+ export function isConfigured() {
410
+ return true;
411
+ }
@@ -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;AAmB/D,eAAO,MAAM,iBAAiB,EAAE,MA+b/B,CAAC"}