opencode-mem 2.8.1 → 2.8.3
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 +2 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/services/web-server.d.ts +6 -0
- package/dist/services/web-server.d.ts.map +1 -1
- package/dist/services/web-server.js +52 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ Add to your OpenCode configuration at `~/.config/opencode/opencode.json`:
|
|
|
32
32
|
}
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
The plugin downloads automatically on next startup. macOS users with Apple Silicon must install Homebrew SQLite and configure the custom path
|
|
35
|
+
The plugin downloads automatically on next startup. macOS users with Apple Silicon must install Homebrew SQLite and configure the custom path.
|
|
36
36
|
|
|
37
37
|
## Usage Examples
|
|
38
38
|
|
|
@@ -95,14 +95,7 @@ Configure at `~/.config/opencode/opencode-mem.jsonc`:
|
|
|
95
95
|
"memoryApiKey": "env://OPENAI_API_KEY"
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
Full documentation available in
|
|
99
|
-
|
|
100
|
-
## Documentation
|
|
101
|
-
|
|
102
|
-
- [Installation Guide](https://github.com/tickernelz/opencode-mem/wiki/Installation-Guide)
|
|
103
|
-
- [API Reference](https://github.com/tickernelz/opencode-mem/wiki/API-Reference)
|
|
104
|
-
- [Troubleshooting](https://github.com/tickernelz/opencode-mem/wiki/Troubleshooting)
|
|
105
|
-
- [Complete Wiki](https://github.com/tickernelz/opencode-mem/wiki)
|
|
98
|
+
Full documentation available in this README.
|
|
106
99
|
|
|
107
100
|
## Development & Contribution
|
|
108
101
|
|
|
@@ -122,7 +115,6 @@ This project is actively seeking contributions to become the definitive memory p
|
|
|
122
115
|
MIT License - see LICENSE file
|
|
123
116
|
|
|
124
117
|
- **Repository**: https://github.com/tickernelz/opencode-mem
|
|
125
|
-
- **Wiki**: https://github.com/tickernelz/opencode-mem/wiki
|
|
126
118
|
- **Issues**: https://github.com/tickernelz/opencode-mem/issues
|
|
127
119
|
- **OpenCode Platform**: https://opencode.ai
|
|
128
120
|
|
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;AAkB/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;AAkB/D,eAAO,MAAM,iBAAiB,EAAE,MA8a/B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,20 @@ export const OpenCodeMemPlugin = async (ctx) => {
|
|
|
36
36
|
.then((server) => {
|
|
37
37
|
webServer = server;
|
|
38
38
|
const url = webServer.getUrl();
|
|
39
|
+
webServer.setOnTakeoverCallback(async () => {
|
|
40
|
+
if (ctx.client?.tui) {
|
|
41
|
+
ctx.client.tui
|
|
42
|
+
.showToast({
|
|
43
|
+
body: {
|
|
44
|
+
title: "Memory Explorer",
|
|
45
|
+
message: "Took over web server ownership",
|
|
46
|
+
variant: "success",
|
|
47
|
+
duration: 3000,
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
.catch(() => { });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
39
53
|
if (webServer.isServerOwner()) {
|
|
40
54
|
if (ctx.client?.tui) {
|
|
41
55
|
ctx.client.tui
|
|
@@ -8,9 +8,15 @@ export declare class WebServer {
|
|
|
8
8
|
private config;
|
|
9
9
|
private isOwner;
|
|
10
10
|
private startPromise;
|
|
11
|
+
private healthCheckInterval;
|
|
12
|
+
private onTakeoverCallback;
|
|
11
13
|
constructor(config: WebServerConfig);
|
|
14
|
+
setOnTakeoverCallback(callback: () => Promise<void>): void;
|
|
12
15
|
start(): Promise<void>;
|
|
13
16
|
private _start;
|
|
17
|
+
private startHealthCheckLoop;
|
|
18
|
+
private stopHealthCheckLoop;
|
|
19
|
+
private attemptTakeover;
|
|
14
20
|
stop(): Promise<void>;
|
|
15
21
|
isRunning(): boolean;
|
|
16
22
|
isServerOwner(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../../src/services/web-server.ts"],"names":[],"mappings":"AAOA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAeD,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAA8B;
|
|
1
|
+
{"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../../src/services/web-server.ts"],"names":[],"mappings":"AAOA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAeD,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,kBAAkB,CAAsC;gBAEpD,MAAM,EAAE,eAAe;IAInC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,MAAM;IA6EpB,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,mBAAmB;YAOb,eAAe;IA2BvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC3B,SAAS,IAAI,OAAO;IAIpB,aAAa,IAAI,OAAO;IAIxB,MAAM,IAAI,MAAM;IAIV,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;CAW/C;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAIhF"}
|
|
@@ -8,9 +8,14 @@ export class WebServer {
|
|
|
8
8
|
config;
|
|
9
9
|
isOwner = false;
|
|
10
10
|
startPromise = null;
|
|
11
|
+
healthCheckInterval = null;
|
|
12
|
+
onTakeoverCallback = null;
|
|
11
13
|
constructor(config) {
|
|
12
14
|
this.config = config;
|
|
13
15
|
}
|
|
16
|
+
setOnTakeoverCallback(callback) {
|
|
17
|
+
this.onTakeoverCallback = callback;
|
|
18
|
+
}
|
|
14
19
|
async start() {
|
|
15
20
|
if (this.startPromise) {
|
|
16
21
|
return this.startPromise;
|
|
@@ -73,6 +78,9 @@ export class WebServer {
|
|
|
73
78
|
host: this.config.host,
|
|
74
79
|
});
|
|
75
80
|
await startedPromise;
|
|
81
|
+
if (!this.isOwner) {
|
|
82
|
+
this.startHealthCheckLoop();
|
|
83
|
+
}
|
|
76
84
|
}
|
|
77
85
|
catch (error) {
|
|
78
86
|
this.isOwner = false;
|
|
@@ -84,7 +92,51 @@ export class WebServer {
|
|
|
84
92
|
throw error;
|
|
85
93
|
}
|
|
86
94
|
}
|
|
95
|
+
startHealthCheckLoop() {
|
|
96
|
+
if (this.healthCheckInterval) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.healthCheckInterval = setInterval(async () => {
|
|
100
|
+
const isAvailable = await this.checkServerAvailable();
|
|
101
|
+
if (!isAvailable) {
|
|
102
|
+
this.stopHealthCheckLoop();
|
|
103
|
+
await this.attemptTakeover();
|
|
104
|
+
}
|
|
105
|
+
}, 5000);
|
|
106
|
+
}
|
|
107
|
+
stopHealthCheckLoop() {
|
|
108
|
+
if (this.healthCheckInterval) {
|
|
109
|
+
clearInterval(this.healthCheckInterval);
|
|
110
|
+
this.healthCheckInterval = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async attemptTakeover() {
|
|
114
|
+
// prevent thundering herd: multiple non-owners racing to bind port
|
|
115
|
+
const jitterMs = 500 + Math.random() * 1000;
|
|
116
|
+
await new Promise((resolve) => setTimeout(resolve, jitterMs));
|
|
117
|
+
if (await this.checkServerAvailable()) {
|
|
118
|
+
this.startHealthCheckLoop();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
await this._start();
|
|
123
|
+
this.isOwner = true;
|
|
124
|
+
log("Web server takeover successful", { port: this.config.port });
|
|
125
|
+
if (this.onTakeoverCallback) {
|
|
126
|
+
try {
|
|
127
|
+
await this.onTakeoverCallback();
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
log("Takeover callback error", { error: String(error) });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
this.startHealthCheckLoop();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
87
138
|
async stop() {
|
|
139
|
+
this.stopHealthCheckLoop();
|
|
88
140
|
if (!this.isOwner || !this.worker) {
|
|
89
141
|
return;
|
|
90
142
|
}
|