claude-mem-opencode 0.0.2 → 0.1.1

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.
@@ -0,0 +1,230 @@
1
+ // src/integration/worker-client.ts
2
+ class WorkerClient {
3
+ baseUrl;
4
+ timeout = 30000;
5
+ constructor(portOrUrl = 37777) {
6
+ if (typeof portOrUrl === "string") {
7
+ this.baseUrl = portOrUrl;
8
+ } else {
9
+ this.baseUrl = `http://127.0.0.1:${portOrUrl}`;
10
+ }
11
+ }
12
+ getPort() {
13
+ const match = this.baseUrl.match(/:(\d+)$/);
14
+ return match ? parseInt(match[1]) : 37777;
15
+ }
16
+ getWorkerUrl() {
17
+ return this.baseUrl;
18
+ }
19
+ async checkHealth() {
20
+ try {
21
+ const response = await fetch(`${this.baseUrl}/api/health`, {
22
+ signal: AbortSignal.timeout(5000)
23
+ });
24
+ const data = await response.json();
25
+ return data;
26
+ } catch (error) {
27
+ console.log("[WORKER_CLIENT] Health check failed:", error);
28
+ return { status: "error", version: "unknown" };
29
+ }
30
+ }
31
+ async healthCheck() {
32
+ const result = await this.checkHealth();
33
+ return result.status === "ok" || result.status === undefined;
34
+ }
35
+ async waitForReady(timeoutMs = 30000) {
36
+ const start = Date.now();
37
+ while (Date.now() - start < timeoutMs) {
38
+ const ready = await this.readinessCheck();
39
+ if (ready)
40
+ return true;
41
+ await new Promise((resolve) => setTimeout(resolve, 500));
42
+ }
43
+ return false;
44
+ }
45
+ async readinessCheck() {
46
+ try {
47
+ const response = await fetch(`${this.baseUrl}/api/readiness`);
48
+ return response.ok;
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+ async initSession(request) {
54
+ const response = await fetch(`${this.baseUrl}/api/sessions/init`, {
55
+ method: "POST",
56
+ headers: { "Content-Type": "application/json" },
57
+ body: JSON.stringify(request),
58
+ signal: AbortSignal.timeout(this.timeout)
59
+ });
60
+ if (!response.ok) {
61
+ throw new Error(`Session init failed: ${response.status} ${response.statusText}`);
62
+ }
63
+ return response.json();
64
+ }
65
+ async addObservation(request) {
66
+ const response = await fetch(`${this.baseUrl}/api/sessions/observations`, {
67
+ method: "POST",
68
+ headers: { "Content-Type": "application/json" },
69
+ body: JSON.stringify(request),
70
+ signal: AbortSignal.timeout(this.timeout)
71
+ });
72
+ if (!response.ok) {
73
+ throw new Error(`Observation add failed: ${response.status} ${response.statusText}`);
74
+ }
75
+ }
76
+ async completeSession(sessionDbId) {
77
+ const response = await fetch(`${this.baseUrl}/sessions/${sessionDbId}/complete`, {
78
+ method: "POST",
79
+ signal: AbortSignal.timeout(this.timeout)
80
+ });
81
+ if (!response.ok) {
82
+ throw new Error(`Session complete failed: ${response.status} ${response.statusText}`);
83
+ }
84
+ }
85
+ async getProjectContext(project) {
86
+ const url = `${this.baseUrl}/api/context/inject?project=${encodeURIComponent(project)}`;
87
+ const response = await fetch(url, {
88
+ signal: AbortSignal.timeout(this.timeout)
89
+ });
90
+ if (!response.ok) {
91
+ throw new Error(`Context fetch failed: ${response.status} ${response.statusText}`);
92
+ }
93
+ return response.text();
94
+ }
95
+ async search(query, options) {
96
+ const params = new URLSearchParams({
97
+ q: query,
98
+ limit: String(options?.limit ?? 10)
99
+ });
100
+ if (options?.type)
101
+ params.append("type", options.type);
102
+ if (options?.project)
103
+ params.append("project", options.project);
104
+ const response = await fetch(`${this.baseUrl}/api/search?${params}`, {
105
+ signal: AbortSignal.timeout(this.timeout)
106
+ });
107
+ if (!response.ok) {
108
+ throw new Error(`Search failed: ${response.status} ${response.statusText}`);
109
+ }
110
+ return response.json();
111
+ }
112
+ async searchMemories(params) {
113
+ return this.search(params.query, {
114
+ type: params.type,
115
+ limit: params.limit
116
+ });
117
+ }
118
+ async getObservations(ids) {
119
+ const response = await fetch(`${this.baseUrl}/api/observations/batch`, {
120
+ method: "POST",
121
+ headers: { "Content-Type": "application/json" },
122
+ body: JSON.stringify({ ids }),
123
+ signal: AbortSignal.timeout(this.timeout)
124
+ });
125
+ if (!response.ok) {
126
+ throw new Error(`Get observations failed: ${response.status} ${response.statusText}`);
127
+ }
128
+ return response.json();
129
+ }
130
+ async getTimeline(sessionDbId, observationId, window = 5) {
131
+ const response = await fetch(`${this.baseUrl}/api/timeline?session=${sessionDbId}&observation=${observationId}&window=${window}`, {
132
+ signal: AbortSignal.timeout(this.timeout)
133
+ });
134
+ if (!response.ok) {
135
+ throw new Error(`Timeline fetch failed: ${response.status} ${response.statusText}`);
136
+ }
137
+ return response.json();
138
+ }
139
+ }
140
+ // src/integration/utils/logger.ts
141
+ var LogLevel;
142
+ ((LogLevel2) => {
143
+ LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
144
+ LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
145
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
146
+ LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
147
+ })(LogLevel ||= {});
148
+
149
+ class Logger {
150
+ context;
151
+ constructor(context) {
152
+ this.context = context;
153
+ }
154
+ debug(message, ...args) {
155
+ console.log(`[${this.context}] [DEBUG] ${message}`, ...args);
156
+ }
157
+ info(message, ...args) {
158
+ console.log(`[${this.context}] [INFO] ${message}`, ...args);
159
+ }
160
+ warn(message, ...args) {
161
+ console.warn(`[${this.context}] [WARN] ${message}`, ...args);
162
+ }
163
+ error(message, ...args) {
164
+ console.error(`[${this.context}] [ERROR] ${message}`, ...args);
165
+ }
166
+ }
167
+ // src/integration/utils/project-name.ts
168
+ import path from "path";
169
+
170
+ class ProjectNameExtractor {
171
+ extract(directory) {
172
+ const baseName = path.basename(directory);
173
+ if (baseName.startsWith(".")) {
174
+ const parent = path.dirname(directory);
175
+ return path.basename(parent);
176
+ }
177
+ return baseName;
178
+ }
179
+ getCurrentProject() {
180
+ return this.extract(process.cwd());
181
+ }
182
+ }
183
+ // src/integration/utils/privacy.ts
184
+ class PrivacyTagStripper {
185
+ PRIVATE_TAG_REGEX = /<private>[\s\S]*?<\/private>/gi;
186
+ CONTEXT_TAG_REGEX = /<claude-mem-context>[\s\S]*?<\/claude-mem-context>/gi;
187
+ stripFromText(text) {
188
+ if (!text)
189
+ return text;
190
+ return text.replace(this.PRIVATE_TAG_REGEX, "[private content removed]").replace(this.CONTEXT_TAG_REGEX, "[system context removed]");
191
+ }
192
+ stripFromJson(obj) {
193
+ if (typeof obj === "string") {
194
+ return this.stripFromText(obj);
195
+ }
196
+ if (Array.isArray(obj)) {
197
+ return obj.map((item) => this.stripFromJson(item));
198
+ }
199
+ if (obj !== null && typeof obj === "object") {
200
+ const result = {};
201
+ for (const [key, value] of Object.entries(obj)) {
202
+ result[key] = this.stripFromJson(value);
203
+ }
204
+ return result;
205
+ }
206
+ return obj;
207
+ }
208
+ isFullyPrivate(text) {
209
+ const stripped = this.stripFromText(text);
210
+ return stripped.trim().length === 0;
211
+ }
212
+ hasPrivacyTags(text) {
213
+ return this.PRIVATE_TAG_REGEX.test(text) || this.CONTEXT_TAG_REGEX.test(text);
214
+ }
215
+ countPrivacyTags(text) {
216
+ const privateMatches = text.match(this.PRIVATE_TAG_REGEX);
217
+ const contextMatches = text.match(this.CONTEXT_TAG_REGEX);
218
+ return {
219
+ private: privateMatches ? privateMatches.length : 0,
220
+ context: contextMatches ? contextMatches.length : 0
221
+ };
222
+ }
223
+ }
224
+ export {
225
+ WorkerClient,
226
+ ProjectNameExtractor,
227
+ PrivacyTagStripper,
228
+ Logger,
229
+ LogLevel
230
+ };
@@ -0,0 +1,15 @@
1
+ import type { ClaudeMemConfig } from './config-schema.js';
2
+ /**
3
+ * Default configuration values
4
+ */
5
+ export declare const DEFAULT_CONFIG: ClaudeMemConfig;
6
+ /**
7
+ * Template for configuration file
8
+ * Users can copy this to create their own config
9
+ */
10
+ export declare const CONFIG_FILE_TEMPLATE = "{\n // claude-mem OpenCode Plugin Configuration\n // Supports JSONC (JavaScript with Comments)\n \n // Enable/disable the plugin\n \"enabled\": true,\n \n // Worker service port\n \"workerPort\": 37777,\n \n // Debug logging\n \"debug\": false,\n \n // Automatically inject context on first message\n \"autoInjectContext\": true,\n \n // Maximum number of memories to inject\n \"maxContextMemories\": 5\n}";
11
+ /**
12
+ * Environment variable prefix for configuration
13
+ */
14
+ export declare const ENV_PREFIX = "OPENCODE_CLAUDE_MEM_";
15
+ //# sourceMappingURL=config-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-defaults.d.ts","sourceRoot":"","sources":["../../src/integration/config-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,eAM5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,2aAkB/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU,yBAAyB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Default configuration values
3
+ */
4
+ export const DEFAULT_CONFIG = {
5
+ enabled: true,
6
+ workerPort: 37777,
7
+ debug: false,
8
+ autoInjectContext: true,
9
+ maxContextMemories: 5
10
+ };
11
+ /**
12
+ * Template for configuration file
13
+ * Users can copy this to create their own config
14
+ */
15
+ export const CONFIG_FILE_TEMPLATE = `{
16
+ // claude-mem OpenCode Plugin Configuration
17
+ // Supports JSONC (JavaScript with Comments)
18
+
19
+ // Enable/disable the plugin
20
+ "enabled": true,
21
+
22
+ // Worker service port
23
+ "workerPort": 37777,
24
+
25
+ // Debug logging
26
+ "debug": false,
27
+
28
+ // Automatically inject context on first message
29
+ "autoInjectContext": true,
30
+
31
+ // Maximum number of memories to inject
32
+ "maxContextMemories": 5
33
+ }`;
34
+ /**
35
+ * Environment variable prefix for configuration
36
+ */
37
+ export const ENV_PREFIX = 'OPENCODE_CLAUDE_MEM_';
38
+ //# sourceMappingURL=config-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-defaults.js","sourceRoot":"","sources":["../../src/integration/config-defaults.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,KAAK;IACjB,KAAK,EAAE,KAAK;IACZ,iBAAiB,EAAE,IAAI;IACvB,kBAAkB,EAAE,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;EAkBlC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Configuration interfaces for claude-mem-opencode plugin
3
+ */
4
+ export interface ClaudeMemConfig {
5
+ enabled: boolean;
6
+ workerPort: number;
7
+ debug: boolean;
8
+ autoInjectContext: boolean;
9
+ maxContextMemories: number;
10
+ }
11
+ export interface ConfigLoadResult {
12
+ config: ClaudeMemConfig;
13
+ errors: string[];
14
+ warnings: string[];
15
+ sources: string[];
16
+ }
17
+ export interface ConfigFile {
18
+ enabled?: boolean;
19
+ workerPort?: number;
20
+ debug?: boolean;
21
+ autoInjectContext?: boolean;
22
+ maxContextMemories?: number;
23
+ }
24
+ //# sourceMappingURL=config-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../../src/integration/config-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Configuration interfaces for claude-mem-opencode plugin
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=config-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../../src/integration/config-schema.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,63 @@
1
+ import type { ConfigLoadResult } from './config-schema.js';
2
+ /**
3
+ * Configuration loader for claude-mem-opencode plugin
4
+ * Loads config from multiple sources in priority order:
5
+ * 1. Default values
6
+ * 2. Environment variables
7
+ * 3. Global config file (~/.config/opencode/claude-mem.jsonc)
8
+ * 4. Project config file (project/.opencode/claude-mem.jsonc)
9
+ *
10
+ * Uses Bun APIs instead of Node.js built-ins for compatibility
11
+ */
12
+ export declare class ConfigLoader {
13
+ private projectDir;
14
+ constructor(projectDir: string);
15
+ /**
16
+ * Load configuration from all sources and merge
17
+ */
18
+ load(): Promise<ConfigLoadResult>;
19
+ /**
20
+ * Load configuration from environment variables
21
+ * Prefix: OPENCODE_CLAUDE_MEM_*
22
+ */
23
+ private loadFromEnv;
24
+ /**
25
+ * Load configuration from a JSONC file
26
+ * Returns null if file doesn't exist or is empty
27
+ * Uses Bun.file() which is available in Bun runtime
28
+ */
29
+ private loadFromFile;
30
+ /**
31
+ * Strip comments from JSONC content
32
+ */
33
+ private stripComments;
34
+ /**
35
+ * Get global config file path
36
+ * ~/.config/opencode/claude-mem.jsonc
37
+ */
38
+ private getGlobalConfigPath;
39
+ /**
40
+ * Get project config file path
41
+ * <project>/.opencode/claude-mem.jsonc
42
+ */
43
+ private getProjectConfigPath;
44
+ /**
45
+ * Get home directory path
46
+ * Uses environment variables
47
+ */
48
+ private getHomeDir;
49
+ /**
50
+ * Validate configuration
51
+ * Returns array of error messages (empty if valid)
52
+ */
53
+ private validateConfig;
54
+ /**
55
+ * Create default config file at specified path
56
+ */
57
+ createDefaultConfig(filePath: string): Promise<void>;
58
+ /**
59
+ * Check if config file exists
60
+ */
61
+ configExists(filePath: string): Promise<boolean>;
62
+ }
63
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/integration/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AAGxF;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,EAAE,MAAM;IAI9B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAqDvC;;;OAGG;IACH,OAAO,CAAC,WAAW;IAwCnB;;;;OAIG;YACW,YAAY;IA8B1B;;OAEG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;;OAGG;IACH,OAAO,CAAC,UAAU;IAKlB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA0BtB;;OAEG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1D;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAQvD"}
@@ -0,0 +1,216 @@
1
+ import { DEFAULT_CONFIG, ENV_PREFIX, CONFIG_FILE_TEMPLATE } from './config-defaults.js';
2
+ /**
3
+ * Configuration loader for claude-mem-opencode plugin
4
+ * Loads config from multiple sources in priority order:
5
+ * 1. Default values
6
+ * 2. Environment variables
7
+ * 3. Global config file (~/.config/opencode/claude-mem.jsonc)
8
+ * 4. Project config file (project/.opencode/claude-mem.jsonc)
9
+ *
10
+ * Uses Bun APIs instead of Node.js built-ins for compatibility
11
+ */
12
+ export class ConfigLoader {
13
+ projectDir;
14
+ constructor(projectDir) {
15
+ this.projectDir = projectDir;
16
+ }
17
+ /**
18
+ * Load configuration from all sources and merge
19
+ */
20
+ async load() {
21
+ const errors = [];
22
+ const warnings = [];
23
+ const sources = ['defaults'];
24
+ // Start with defaults
25
+ let config = { ...DEFAULT_CONFIG };
26
+ // Load environment variables
27
+ try {
28
+ const envConfig = this.loadFromEnv();
29
+ config = { ...config, ...envConfig };
30
+ if (Object.keys(envConfig).length > 0) {
31
+ sources.push('environment');
32
+ }
33
+ }
34
+ catch (error) {
35
+ errors.push(`Failed to load environment variables: ${error}`);
36
+ }
37
+ // Load global config file
38
+ try {
39
+ const globalConfig = await this.loadFromFile(this.getGlobalConfigPath());
40
+ if (globalConfig) {
41
+ config = { ...config, ...globalConfig };
42
+ sources.push('global-config');
43
+ }
44
+ }
45
+ catch (error) {
46
+ warnings.push(`Failed to load global config: ${error}`);
47
+ }
48
+ // Load project config file
49
+ try {
50
+ const projectConfig = await this.loadFromFile(this.getProjectConfigPath());
51
+ if (projectConfig) {
52
+ config = { ...config, ...projectConfig };
53
+ sources.push('project-config');
54
+ }
55
+ }
56
+ catch (error) {
57
+ warnings.push(`Failed to load project config: ${error}`);
58
+ }
59
+ // Validate final config
60
+ const validationErrors = this.validateConfig(config);
61
+ errors.push(...validationErrors);
62
+ return {
63
+ config,
64
+ errors,
65
+ warnings,
66
+ sources
67
+ };
68
+ }
69
+ /**
70
+ * Load configuration from environment variables
71
+ * Prefix: OPENCODE_CLAUDE_MEM_*
72
+ */
73
+ loadFromEnv() {
74
+ const envVars = {
75
+ enabled: process.env[`${ENV_PREFIX}ENABLED`],
76
+ workerPort: process.env[`${ENV_PREFIX}WORKER_PORT`],
77
+ debug: process.env[`${ENV_PREFIX}DEBUG`],
78
+ autoInjectContext: process.env[`${ENV_PREFIX}AUTO_INJECT_CONTEXT`],
79
+ maxContextMemories: process.env[`${ENV_PREFIX}MAX_CONTEXT_MEMORIES`]
80
+ };
81
+ const config = {};
82
+ if (envVars.enabled !== undefined) {
83
+ config.enabled = envVars.enabled.toLowerCase() === 'true';
84
+ }
85
+ if (envVars.workerPort !== undefined) {
86
+ const port = parseInt(envVars.workerPort, 10);
87
+ if (!isNaN(port)) {
88
+ config.workerPort = port;
89
+ }
90
+ }
91
+ if (envVars.debug !== undefined) {
92
+ config.debug = envVars.debug.toLowerCase() === 'true';
93
+ }
94
+ if (envVars.autoInjectContext !== undefined) {
95
+ config.autoInjectContext = envVars.autoInjectContext.toLowerCase() === 'true';
96
+ }
97
+ if (envVars.maxContextMemories !== undefined) {
98
+ const limit = parseInt(envVars.maxContextMemories, 10);
99
+ if (!isNaN(limit)) {
100
+ config.maxContextMemories = limit;
101
+ }
102
+ }
103
+ return config;
104
+ }
105
+ /**
106
+ * Load configuration from a JSONC file
107
+ * Returns null if file doesn't exist or is empty
108
+ * Uses Bun.file() which is available in Bun runtime
109
+ */
110
+ async loadFromFile(filePath) {
111
+ try {
112
+ // Read file using Bun.file()
113
+ const file = Bun.file(filePath);
114
+ const exists = await file.exists();
115
+ if (!exists) {
116
+ return null;
117
+ }
118
+ // Read and parse file
119
+ const content = await file.text();
120
+ // Remove JSONC comments (// and /* */)
121
+ const jsonContent = this.stripComments(content);
122
+ if (jsonContent.trim().length === 0) {
123
+ return null;
124
+ }
125
+ const parsed = JSON.parse(jsonContent);
126
+ return parsed;
127
+ }
128
+ catch (error) {
129
+ if (error.code === 'ENOENT') {
130
+ return null;
131
+ }
132
+ throw new Error(`Failed to parse ${filePath}: ${error}`);
133
+ }
134
+ }
135
+ /**
136
+ * Strip comments from JSONC content
137
+ */
138
+ stripComments(content) {
139
+ // Remove single-line comments (//)
140
+ let result = content.replace(/\/\/.*$/gm, '');
141
+ // Remove multi-line comments (/* */)
142
+ result = result.replace(/\/\*[\s\S]*?\*\//g, '');
143
+ return result;
144
+ }
145
+ /**
146
+ * Get global config file path
147
+ * ~/.config/opencode/claude-mem.jsonc
148
+ */
149
+ getGlobalConfigPath() {
150
+ const homeDir = this.getHomeDir();
151
+ return `${homeDir}/.config/opencode/claude-mem.jsonc`;
152
+ }
153
+ /**
154
+ * Get project config file path
155
+ * <project>/.opencode/claude-mem.jsonc
156
+ */
157
+ getProjectConfigPath() {
158
+ return `${this.projectDir}/.opencode/claude-mem.jsonc`;
159
+ }
160
+ /**
161
+ * Get home directory path
162
+ * Uses environment variables
163
+ */
164
+ getHomeDir() {
165
+ // Use environment variables (works in both Node.js and Bun)
166
+ return process.env.HOME || process.env.USERPROFILE || '/';
167
+ }
168
+ /**
169
+ * Validate configuration
170
+ * Returns array of error messages (empty if valid)
171
+ */
172
+ validateConfig(config) {
173
+ const errors = [];
174
+ if (typeof config.enabled !== 'boolean') {
175
+ errors.push('config.enabled must be a boolean');
176
+ }
177
+ if (typeof config.workerPort !== 'number' || config.workerPort < 1 || config.workerPort > 65535) {
178
+ errors.push('config.workerPort must be a valid port number (1-65535)');
179
+ }
180
+ if (typeof config.debug !== 'boolean') {
181
+ errors.push('config.debug must be a boolean');
182
+ }
183
+ if (typeof config.autoInjectContext !== 'boolean') {
184
+ errors.push('config.autoInjectContext must be a boolean');
185
+ }
186
+ if (typeof config.maxContextMemories !== 'number' || config.maxContextMemories < 0) {
187
+ errors.push('config.maxContextMemories must be a non-negative number');
188
+ }
189
+ return errors;
190
+ }
191
+ /**
192
+ * Create default config file at specified path
193
+ */
194
+ async createDefaultConfig(filePath) {
195
+ try {
196
+ const file = Bun.file(filePath);
197
+ await Bun.write(filePath, CONFIG_FILE_TEMPLATE);
198
+ }
199
+ catch (error) {
200
+ throw new Error(`Failed to create config file: ${error}`);
201
+ }
202
+ }
203
+ /**
204
+ * Check if config file exists
205
+ */
206
+ async configExists(filePath) {
207
+ try {
208
+ const file = Bun.file(filePath);
209
+ return await file.exists();
210
+ }
211
+ catch {
212
+ return false;
213
+ }
214
+ }
215
+ }
216
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/integration/config.ts"],"names":[],"mappings":"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"}
package/dist/plugin.d.ts CHANGED
@@ -1,13 +1,7 @@
1
- export default function plugin(input: {
2
- client: any;
3
- project: any;
4
- directory: string;
5
- worktree: string;
6
- serverUrl: URL;
7
- $: any;
8
- }): Promise<{
9
- event: ({ event }: {
10
- event: any;
11
- }) => Promise<void>;
12
- }>;
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ /**
3
+ * OpenCode plugin for claude-mem persistent memory
4
+ * Provides automatic context capture and injection across sessions
5
+ */
6
+ export declare const ClaudeMemPlugin: Plugin;
13
7
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAEA,wBAA8B,MAAM,CAAC,KAAK,EAAE;IAC1C,MAAM,EAAE,GAAG,CAAA;IACX,OAAO,EAAE,GAAG,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,GAAG,CAAA;IACd,CAAC,EAAE,GAAG,CAAA;CACP;uBAa4B;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE;GAI1C"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAmB/D;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAqV7B,CAAC"}