@memtensor/memos-cloud-openclaw-plugin 0.1.8-beta.7 → 0.1.8-beta.9
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/LICENSE +201 -201
- package/README.md +156 -156
- package/README_ZH.md +161 -161
- package/clawdbot.plugin.json +169 -169
- package/index.js +290 -290
- package/lib/check-update.js +96 -13
- package/lib/memos-cloud-api.js +451 -451
- package/moltbot.plugin.json +169 -169
- package/openclaw.plugin.json +169 -169
- package/package.json +46 -46
- package/scripts/sync-version.js +45 -45
package/lib/check-update.js
CHANGED
|
@@ -2,14 +2,31 @@ import https from "https";
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
|
-
import { spawn } from "child_process";
|
|
5
|
+
import { spawn, exec } from "child_process";
|
|
6
6
|
import os from "os";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Kill a spawned child process and its entire process tree.
|
|
10
|
+
*/
|
|
11
|
+
function killProcessTree(child) {
|
|
12
|
+
try {
|
|
13
|
+
if (process.platform === "win32") {
|
|
14
|
+
exec(`taskkill /pid ${child.pid} /T /F`, () => {});
|
|
15
|
+
} else {
|
|
16
|
+
// On Unix, kill the process group
|
|
17
|
+
process.kill(-child.pid, "SIGKILL");
|
|
18
|
+
}
|
|
19
|
+
} catch (e) {
|
|
20
|
+
// Fallback: try the basic kill
|
|
21
|
+
try { child.kill("SIGKILL"); } catch (_) {}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
8
25
|
let isUpdating = false;
|
|
9
26
|
|
|
10
27
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
28
|
|
|
12
|
-
const CHECK_INTERVAL =
|
|
29
|
+
const CHECK_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours check interval
|
|
13
30
|
const UPDATE_TIMEOUT = 3 * 60 * 1000; // 3 minutes timeout for the CLI update command to finish
|
|
14
31
|
const PLUGIN_NAME = "@memtensor/memos-cloud-openclaw-plugin";
|
|
15
32
|
const CHECK_FILE = path.join(os.tmpdir(), "memos_openclaw_update_check.json");
|
|
@@ -22,6 +39,36 @@ const ANSI = {
|
|
|
22
39
|
RED: "\x1b[31m"
|
|
23
40
|
};
|
|
24
41
|
|
|
42
|
+
function canExecuteCli(cliName, timeoutMs = 8000) {
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
let done = false;
|
|
45
|
+
const child = spawn(cliName, ["--version"], { shell: true });
|
|
46
|
+
const timer = setTimeout(() => {
|
|
47
|
+
if (done) return;
|
|
48
|
+
done = true;
|
|
49
|
+
killProcessTree(child);
|
|
50
|
+
resolve({ ok: false, reason: `timeout after ${timeoutMs}ms` });
|
|
51
|
+
}, timeoutMs);
|
|
52
|
+
|
|
53
|
+
child.on("error", (err) => {
|
|
54
|
+
if (done) return;
|
|
55
|
+
done = true;
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
resolve({ ok: false, reason: err?.message || String(err) });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
child.on("close", (code) => {
|
|
61
|
+
if (done) return;
|
|
62
|
+
done = true;
|
|
63
|
+
clearTimeout(timer);
|
|
64
|
+
resolve({
|
|
65
|
+
ok: code === 0,
|
|
66
|
+
reason: code === 0 ? "" : `exit code ${code}`,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
25
72
|
|
|
26
73
|
function getPackageVersion() {
|
|
27
74
|
try {
|
|
@@ -141,6 +188,15 @@ export function startUpdateChecker(log) {
|
|
|
141
188
|
return;
|
|
142
189
|
}
|
|
143
190
|
|
|
191
|
+
// Check if we have write permission to the plugin directory before attempting update
|
|
192
|
+
const pluginDir = path.join(__dirname, "..");
|
|
193
|
+
try {
|
|
194
|
+
fs.accessSync(pluginDir, fs.constants.W_OK);
|
|
195
|
+
} catch (err) {
|
|
196
|
+
log.warn?.(`${ANSI.YELLOW}[memos-cloud] Update available (${latestVersion}), but skipping auto-update due to missing write permissions in ${pluginDir}. Please run manually with sudo.${ANSI.RESET}`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
144
200
|
log.info?.(`${ANSI.YELLOW}[memos-cloud] Update available: ${currentVersion} -> ${latestVersion}. Updating in background...${ANSI.RESET}`);
|
|
145
201
|
|
|
146
202
|
let dotCount = 0;
|
|
@@ -160,19 +216,41 @@ export function startUpdateChecker(log) {
|
|
|
160
216
|
return "openclaw";
|
|
161
217
|
})();
|
|
162
218
|
|
|
219
|
+
const preflight = await canExecuteCli(cliName);
|
|
220
|
+
if (!preflight.ok) {
|
|
221
|
+
log.warn?.(
|
|
222
|
+
`${ANSI.YELLOW}[memos-cloud] Update available (${latestVersion}), but cannot execute CLI '${cliName}' (${preflight.reason}). Please update manually: ${cliName} plugins update memos-cloud-openclaw-plugin${ANSI.RESET}`,
|
|
223
|
+
);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
163
227
|
isUpdating = true;
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
228
|
+
const spawnOpts = { shell: true };
|
|
229
|
+
// On Unix, detach the process so we can kill the entire process group on timeout
|
|
230
|
+
if (process.platform !== "win32") {
|
|
231
|
+
spawnOpts.detached = true;
|
|
232
|
+
}
|
|
233
|
+
const child = spawn(cliName, ["plugins", "update", "memos-cloud-openclaw-plugin"], spawnOpts);
|
|
234
|
+
let finished = false;
|
|
235
|
+
const finishUpdateSequence = () => {
|
|
236
|
+
if (finished) return;
|
|
237
|
+
finished = true;
|
|
238
|
+
clearTimeout(updateTimeout);
|
|
239
|
+
clearInterval(progressInterval);
|
|
240
|
+
isUpdating = false;
|
|
241
|
+
};
|
|
167
242
|
|
|
168
243
|
// Timeout mechanism: forcefully kill the update process if it hangs for more than the configured timeout
|
|
169
244
|
const updateTimeout = setTimeout(() => {
|
|
170
245
|
log.warn?.(`${ANSI.RED}[memos-cloud] Update process timed out. Please try manually running: ${cliName} plugins update memos-cloud-openclaw-plugin${ANSI.RESET}`);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
246
|
+
killProcessTree(child);
|
|
247
|
+
|
|
248
|
+
// Fallback: if kill failed and the close event never fires, forcefully release the lock after 5 seconds
|
|
249
|
+
setTimeout(() => {
|
|
250
|
+
if (isUpdating) {
|
|
251
|
+
finishUpdateSequence();
|
|
252
|
+
}
|
|
253
|
+
}, 5000);
|
|
176
254
|
}, UPDATE_TIMEOUT);
|
|
177
255
|
|
|
178
256
|
child.stdout.on("data", (data) => {
|
|
@@ -196,9 +274,7 @@ export function startUpdateChecker(log) {
|
|
|
196
274
|
});
|
|
197
275
|
|
|
198
276
|
child.on("close", (code) => {
|
|
199
|
-
|
|
200
|
-
clearInterval(progressInterval);
|
|
201
|
-
isUpdating = false;
|
|
277
|
+
finishUpdateSequence();
|
|
202
278
|
|
|
203
279
|
// Wait for a brief moment to let file system sync if needed
|
|
204
280
|
setTimeout(() => {
|
|
@@ -213,6 +289,13 @@ export function startUpdateChecker(log) {
|
|
|
213
289
|
}, 1000); // Small 1-second buffer for file systems
|
|
214
290
|
});
|
|
215
291
|
|
|
292
|
+
child.on("error", (err) => {
|
|
293
|
+
finishUpdateSequence();
|
|
294
|
+
log.warn?.(
|
|
295
|
+
`${ANSI.RED}[memos-cloud] Failed to start auto-update process: ${err?.message || String(err)}. Please run manually: ${cliName} plugins update memos-cloud-openclaw-plugin${ANSI.RESET}`,
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
|
|
216
299
|
} catch (error) {
|
|
217
300
|
log.warn?.(`${ANSI.RED}[memos-cloud] Update check failed entirely: ${error.message}${ANSI.RESET}`);
|
|
218
301
|
}
|