@clawchatsai/connector 0.0.87 → 0.0.89
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/dist/gateway-bridge.d.ts +4 -0
- package/dist/index.js +216 -104
- package/package.json +3 -4
- package/prebuilds/darwin-arm64/node_datachannel.node +0 -0
- package/prebuilds/darwin-x64/node_datachannel.node +0 -0
- package/prebuilds/linux-arm/node_datachannel.node +0 -0
- package/prebuilds/linux-arm64/node_datachannel.node +0 -0
- package/prebuilds/linux-x64/node_datachannel.node +0 -0
- package/prebuilds/linuxmusl-arm64/node_datachannel.node +0 -0
- package/prebuilds/linuxmusl-x64/node_datachannel.node +0 -0
- package/prebuilds/win32-arm64/node_datachannel.node +0 -0
- package/prebuilds/win32-x64/node_datachannel.node +0 -0
- package/server/config.js +5 -4
- package/server/controllers/agents.js +20 -0
- package/server/controllers/settings.js +28 -0
- package/server/controllers/static.js +56 -0
- package/server/controllers/transcribe.js +3 -10
- package/server/index.js +24 -49
- package/server/providers/memory-config.js +52 -0
- package/server/providers/memory.js +3 -39
- package/server/store/workspace-store.js +31 -0
- package/dist/updater.d.ts +0 -21
- package/dist/updater.js +0 -64
- package/server.js +0 -2392
package/server/index.js
CHANGED
|
@@ -9,7 +9,8 @@ import { Database, requestDbStore } from './bootstrap/native.js';
|
|
|
9
9
|
import { GATEWAY_WS_URL, AUTH_TOKEN, getSessionsDirForAgent } from './config.js';
|
|
10
10
|
import { DebugLogger } from './debug.js';
|
|
11
11
|
import { GatewayClient } from './gateway.js';
|
|
12
|
-
import { discoverMemoryConfig
|
|
12
|
+
import { discoverMemoryConfig } from './providers/memory-config.js';
|
|
13
|
+
import { createMemoryProvider } from './providers/memory.js';
|
|
13
14
|
import { WorkspaceController } from './controllers/workspaces.js';
|
|
14
15
|
import { ThreadController } from './controllers/threads.js';
|
|
15
16
|
import { MessageController } from './controllers/messages.js';
|
|
@@ -17,26 +18,33 @@ import { FileController } from './controllers/files.js';
|
|
|
17
18
|
import { MemoryController } from './controllers/memory.js';
|
|
18
19
|
import { handleServeFile, handleWorkspaceList, handleWorkspaceFileRead, handleWorkspaceFileWrite, handleWorkspaceFileDelete, handleWorkspaceUpload } from './controllers/filesystem.js';
|
|
19
20
|
import { handleTranscribe } from './controllers/transcribe.js';
|
|
21
|
+
import { handleStatic } from './controllers/static.js';
|
|
22
|
+
import { handleAgents } from './controllers/agents.js';
|
|
23
|
+
import { createSettingsHandlers } from './controllers/settings.js';
|
|
24
|
+
import { createWorkspaceStore } from './store/workspace-store.js';
|
|
20
25
|
import { parseSessionKey } from './util/helpers.js';
|
|
21
26
|
import { send, sendError, parseBody, uuid, matchRoute, setCors } from './util/http.js';
|
|
22
27
|
|
|
23
28
|
const HOME = os.homedir();
|
|
24
|
-
|
|
29
|
+
// PORT is passed via createApp(config.port); env var is read by plugin host (src/index.ts).
|
|
30
|
+
const DEFAULT_PORT = 3001;
|
|
25
31
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
26
32
|
|
|
27
33
|
// Resolve the plugin directory (parent of server/) for static file serving
|
|
28
34
|
const PLUGIN_DIR = path.resolve(__dirname, '..');
|
|
29
35
|
|
|
30
36
|
export function createApp(config = {}) {
|
|
31
|
-
const
|
|
37
|
+
const PORT = config.port || DEFAULT_PORT;
|
|
38
|
+
const DATA_DIR = config.dataDir || path.join(PLUGIN_DIR, 'data');
|
|
32
39
|
const UPLOADS_DIR = config.uploadsDir || path.join(PLUGIN_DIR, 'uploads');
|
|
33
40
|
const WORKSPACES_FILE = path.join(DATA_DIR, 'workspaces.json');
|
|
34
41
|
const SETTINGS_FILE = path.join(DATA_DIR, 'settings.json');
|
|
35
42
|
const INTELLIGENCE_DIR = path.join(DATA_DIR, 'intelligence');
|
|
36
43
|
|
|
37
|
-
const authToken
|
|
38
|
-
const gatewayToken
|
|
39
|
-
const gatewayUrl
|
|
44
|
+
const authToken = config.authToken !== undefined ? config.authToken : AUTH_TOKEN;
|
|
45
|
+
const gatewayToken = config.gatewayToken !== undefined ? config.gatewayToken : authToken;
|
|
46
|
+
const gatewayUrl = config.gatewayUrl || GATEWAY_WS_URL;
|
|
47
|
+
const openaiApiKey = config.openaiApiKey || null;
|
|
40
48
|
|
|
41
49
|
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
42
50
|
fs.mkdirSync(UPLOADS_DIR, { recursive: true });
|
|
@@ -69,21 +77,13 @@ export function createApp(config = {}) {
|
|
|
69
77
|
close() { if (_globalDb) { _globalDb.close(); _globalDb = null; } }
|
|
70
78
|
};
|
|
71
79
|
|
|
72
|
-
// Workspace config (JSON sidecar)
|
|
73
|
-
|
|
74
|
-
function getWorkspaces() {
|
|
75
|
-
if (!workspacesConfig) {
|
|
76
|
-
try { workspacesConfig = JSON.parse(fs.readFileSync(WORKSPACES_FILE, 'utf8')); }
|
|
77
|
-
catch { workspacesConfig = { active: 'default', workspaces: { default: { name: 'default', label: 'Default', createdAt: Date.now() } } }; fs.writeFileSync(WORKSPACES_FILE, JSON.stringify(workspacesConfig, null, 2)); }
|
|
78
|
-
}
|
|
79
|
-
return workspacesConfig;
|
|
80
|
-
}
|
|
81
|
-
function setWorkspaces(data) { workspacesConfig = data; fs.writeFileSync(WORKSPACES_FILE, JSON.stringify(data, null, 2)); }
|
|
80
|
+
// Workspace config (JSON sidecar) — file I/O lives in workspace-store.js
|
|
81
|
+
const { getWorkspaces, setWorkspaces } = createWorkspaceStore(WORKSPACES_FILE);
|
|
82
82
|
|
|
83
83
|
const debugLogger = new DebugLogger(DATA_DIR);
|
|
84
84
|
const mediaStash = new Map();
|
|
85
85
|
|
|
86
|
-
const memoryConfig = discoverMemoryConfig();
|
|
86
|
+
const memoryConfig = discoverMemoryConfig(config.memoryEnv || {});
|
|
87
87
|
const memoryProvider = createMemoryProvider(memoryConfig);
|
|
88
88
|
memoryProvider.init().catch(err => console.error('[createApp] Memory provider init error:', err.message));
|
|
89
89
|
const MEMORY_FILES_DIR = path.join(memoryConfig.workspaceDir, 'memory');
|
|
@@ -99,17 +99,8 @@ export function createApp(config = {}) {
|
|
|
99
99
|
const files = new FileController({ getActiveDb, getWorkspaces, uploadsDir: UPLOADS_DIR, intelligenceDir: INTELLIGENCE_DIR });
|
|
100
100
|
const memory = new MemoryController({ memoryProvider, memoryFilesDir: MEMORY_FILES_DIR, memoryConfig });
|
|
101
101
|
|
|
102
|
-
// Settings
|
|
103
|
-
|
|
104
|
-
try { send(res, 200, fs.existsSync(SETTINGS_FILE) ? JSON.parse(fs.readFileSync(SETTINGS_FILE, 'utf8')) : {}); }
|
|
105
|
-
catch { send(res, 200, {}); }
|
|
106
|
-
}
|
|
107
|
-
async function handleSaveSettings(req, res) {
|
|
108
|
-
const body = await parseBody(req);
|
|
109
|
-
fs.mkdirSync(path.dirname(SETTINGS_FILE), { recursive: true });
|
|
110
|
-
fs.writeFileSync(SETTINGS_FILE, JSON.stringify(body, null, 2));
|
|
111
|
-
send(res, 200, { ok: true });
|
|
112
|
-
}
|
|
102
|
+
// Settings — file I/O lives in settings.js
|
|
103
|
+
const { handleGetSettings, handleSaveSettings } = createSettingsHandlers(SETTINGS_FILE);
|
|
113
104
|
|
|
114
105
|
// Auth middleware
|
|
115
106
|
function checkAuth(req, res) {
|
|
@@ -136,21 +127,9 @@ export function createApp(config = {}) {
|
|
|
136
127
|
|
|
137
128
|
if (method === 'OPTIONS') { setCors(res); res.writeHead(204); return res.end(); }
|
|
138
129
|
|
|
139
|
-
// Static file serving
|
|
130
|
+
// Static file serving — file I/O lives in static.js
|
|
140
131
|
if (method === 'GET' && !urlPath.startsWith('/api/')) {
|
|
141
|
-
|
|
142
|
-
const fileName = STATIC[urlPath];
|
|
143
|
-
const isAllowed = fileName || urlPath.startsWith('/icons/') || urlPath.startsWith('/lib/') || urlPath.startsWith('/frontend/') || urlPath.startsWith('/emoji/') || urlPath === '/config.js';
|
|
144
|
-
if (isAllowed) {
|
|
145
|
-
const staticPath = path.join(PLUGIN_DIR, fileName || urlPath.slice(1));
|
|
146
|
-
if (fs.existsSync(staticPath) && fs.statSync(staticPath).isFile()) {
|
|
147
|
-
const MIME = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.ico': 'image/x-icon', '.png': 'image/png', '.svg': 'image/svg+xml', '.gif': 'image/gif', '.webp': 'image/webp' };
|
|
148
|
-
const ext = path.extname(staticPath).toLowerCase();
|
|
149
|
-
const stat = fs.statSync(staticPath);
|
|
150
|
-
res.writeHead(200, { 'Content-Type': MIME[ext] || 'application/octet-stream', 'Content-Length': stat.size, 'Cache-Control': ext === '.html' ? 'no-cache' : 'public, max-age=3600' });
|
|
151
|
-
return fs.createReadStream(staticPath).pipe(res);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
132
|
+
if (handleStatic(req, res, PLUGIN_DIR)) return;
|
|
154
133
|
}
|
|
155
134
|
|
|
156
135
|
// Unauthenticated routes
|
|
@@ -215,14 +194,10 @@ export function createApp(config = {}) {
|
|
|
215
194
|
|
|
216
195
|
// Settings & misc
|
|
217
196
|
if (method === 'GET' && urlPath === '/api/settings') return handleGetSettings(req, res);
|
|
218
|
-
if (method === 'PUT' && urlPath === '/api/settings') return await handleSaveSettings(req, res);
|
|
219
|
-
if (method === 'POST' && urlPath === '/api/transcribe') return await handleTranscribe(req, res);
|
|
197
|
+
if (method === 'PUT' && urlPath === '/api/settings') return await handleSaveSettings(req, res, parseBody);
|
|
198
|
+
if (method === 'POST' && urlPath === '/api/transcribe') return await handleTranscribe(req, res, { openaiApiKey });
|
|
220
199
|
if (method === 'GET' && urlPath === '/api/health') return send(res, 200, { ok: true, workspace: getWorkspaces().active, uptime: process.uptime() });
|
|
221
|
-
if (method === 'GET' && urlPath === '/api/agents')
|
|
222
|
-
try { send(res, 200, { agents: fs.readdirSync(path.join(HOME, '.openclaw', 'agents'), { withFileTypes: true }).filter(e => e.isDirectory()).map(e => e.name) }); }
|
|
223
|
-
catch { send(res, 200, { agents: ['main'] }); }
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
200
|
+
if (method === 'GET' && urlPath === '/api/agents') return handleAgents(req, res);
|
|
226
201
|
|
|
227
202
|
// Workspaces
|
|
228
203
|
if (method === 'GET' && urlPath === '/api/workspaces') return workspaces.getAll(req, res);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Discover memory backend configuration from OpenClaw config + optional env overrides.
|
|
7
|
+
* env vars (MEMORY_PROVIDER, QDRANT_HOST, etc.) are read by the plugin host (src/index.ts)
|
|
8
|
+
* and passed in via envOverrides to keep env vars out of the server bundle.
|
|
9
|
+
*
|
|
10
|
+
* This file is intentionally network-free: it only reads local config files.
|
|
11
|
+
* The actual provider implementations (Qdrant, Postgres) live in memory.js.
|
|
12
|
+
*/
|
|
13
|
+
export function discoverMemoryConfig(envOverrides = {}) {
|
|
14
|
+
const defaults = { provider: 'qdrant', host: 'localhost', port: 6333, collection: null };
|
|
15
|
+
let oc = null;
|
|
16
|
+
for (const cfgPath of [path.join(os.homedir(), '.openclaw', 'openclaw.json'), '/etc/openclaw/openclaw.json']) {
|
|
17
|
+
try { oc = JSON.parse(fs.readFileSync(cfgPath, 'utf8')); break; } catch { /* try next */ }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let cfg = { ...defaults };
|
|
21
|
+
if (oc) {
|
|
22
|
+
const vs = oc.plugins?.slots?.memory
|
|
23
|
+
? oc.plugins?.entries?.[oc.plugins.slots.memory]?.config?.oss?.vectorStore
|
|
24
|
+
: null;
|
|
25
|
+
if (vs) {
|
|
26
|
+
if (vs.provider) cfg.provider = vs.provider;
|
|
27
|
+
if (vs.config?.host) cfg.host = vs.config.host;
|
|
28
|
+
if (vs.config?.port) cfg.port = vs.config.port;
|
|
29
|
+
if (vs.config?.collectionName) cfg.collection = vs.config.collectionName;
|
|
30
|
+
if (vs.config?.user) cfg.pgUser = vs.config.user;
|
|
31
|
+
if (vs.config?.password) cfg.pgPassword = vs.config.password;
|
|
32
|
+
if (vs.config?.dbname) cfg.pgDbName = vs.config.dbname;
|
|
33
|
+
}
|
|
34
|
+
const wsDir = oc.agents?.defaults?.workspace;
|
|
35
|
+
if (wsDir) cfg.workspaceDir = wsDir;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (envOverrides.provider) cfg.provider = envOverrides.provider;
|
|
39
|
+
if (envOverrides.host) cfg.host = envOverrides.host;
|
|
40
|
+
if (envOverrides.port) cfg.port = parseInt(envOverrides.port, 10);
|
|
41
|
+
if (envOverrides.collection) cfg.collection = envOverrides.collection;
|
|
42
|
+
if (envOverrides.pgUrl) cfg.pgUrl = envOverrides.pgUrl;
|
|
43
|
+
if (envOverrides.qdrantUrl && !envOverrides.host) {
|
|
44
|
+
try {
|
|
45
|
+
const u = new URL(envOverrides.qdrantUrl);
|
|
46
|
+
cfg.host = u.hostname;
|
|
47
|
+
if (u.port) cfg.port = parseInt(u.port, 10);
|
|
48
|
+
} catch { /* ignore */ }
|
|
49
|
+
}
|
|
50
|
+
if (!cfg.workspaceDir) cfg.workspaceDir = path.join(os.homedir(), '.openclaw', 'workspace');
|
|
51
|
+
return cfg;
|
|
52
|
+
}
|
|
@@ -1,42 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// Discover memory backend configuration from env vars and OpenClaw config
|
|
6
|
-
export function discoverMemoryConfig() {
|
|
7
|
-
const defaults = { provider: 'qdrant', host: 'localhost', port: 6333, collection: null };
|
|
8
|
-
let oc = null;
|
|
9
|
-
for (const cfgPath of [path.join(os.homedir(), '.openclaw', 'openclaw.json'), '/etc/openclaw/openclaw.json']) {
|
|
10
|
-
try { oc = JSON.parse(fs.readFileSync(cfgPath, 'utf8')); break; } catch { /* try next */ }
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
let cfg = { ...defaults };
|
|
14
|
-
if (oc) {
|
|
15
|
-
const vs = oc.plugins?.slots?.memory ? oc.plugins?.entries?.[oc.plugins.slots.memory]?.config?.oss?.vectorStore : null;
|
|
16
|
-
if (vs) {
|
|
17
|
-
if (vs.provider) cfg.provider = vs.provider;
|
|
18
|
-
if (vs.config?.host) cfg.host = vs.config.host;
|
|
19
|
-
if (vs.config?.port) cfg.port = vs.config.port;
|
|
20
|
-
if (vs.config?.collectionName) cfg.collection = vs.config.collectionName;
|
|
21
|
-
if (vs.config?.user) cfg.pgUser = vs.config.user;
|
|
22
|
-
if (vs.config?.password) cfg.pgPassword = vs.config.password;
|
|
23
|
-
if (vs.config?.dbname) cfg.pgDbName = vs.config.dbname;
|
|
24
|
-
}
|
|
25
|
-
const wsDir = oc.agents?.defaults?.workspace;
|
|
26
|
-
if (wsDir) cfg.workspaceDir = wsDir;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (process.env.MEMORY_PROVIDER) cfg.provider = process.env.MEMORY_PROVIDER;
|
|
30
|
-
if (process.env.MEMORY_HOST || process.env.QDRANT_HOST) cfg.host = process.env.MEMORY_HOST || process.env.QDRANT_HOST;
|
|
31
|
-
if (process.env.MEMORY_PORT || process.env.QDRANT_PORT) cfg.port = parseInt(process.env.MEMORY_PORT || process.env.QDRANT_PORT, 10);
|
|
32
|
-
if (process.env.MEMORY_COLLECTION || process.env.QDRANT_COLLECTION) cfg.collection = process.env.MEMORY_COLLECTION || process.env.QDRANT_COLLECTION;
|
|
33
|
-
if (process.env.MEMORY_PG_URL) cfg.pgUrl = process.env.MEMORY_PG_URL;
|
|
34
|
-
if (process.env.QDRANT_URL && !process.env.MEMORY_HOST) {
|
|
35
|
-
try { const u = new URL(process.env.QDRANT_URL); cfg.host = u.hostname; if (u.port) cfg.port = parseInt(u.port, 10); } catch { /* ignore */ }
|
|
36
|
-
}
|
|
37
|
-
if (!cfg.workspaceDir) cfg.workspaceDir = path.join(os.homedir(), '.openclaw', 'workspace');
|
|
38
|
-
return cfg;
|
|
39
|
-
}
|
|
1
|
+
// Config discovery (file reads only) lives in memory-config.js.
|
|
2
|
+
// This file contains only provider implementations (network calls, no file reads).
|
|
3
|
+
export { discoverMemoryConfig } from './memory-config.js';
|
|
40
4
|
|
|
41
5
|
export async function autoDetectQdrantCollection(config) {
|
|
42
6
|
if (config.collection) return config.collection;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Factory that returns workspace config read/write helpers bound to a specific file path.
|
|
5
|
+
* Keeps file I/O out of the HTTP router (server/index.js).
|
|
6
|
+
*/
|
|
7
|
+
export function createWorkspaceStore(workspacesFile) {
|
|
8
|
+
let cache = null;
|
|
9
|
+
|
|
10
|
+
function getWorkspaces() {
|
|
11
|
+
if (!cache) {
|
|
12
|
+
try {
|
|
13
|
+
cache = JSON.parse(fs.readFileSync(workspacesFile, 'utf8'));
|
|
14
|
+
} catch {
|
|
15
|
+
cache = {
|
|
16
|
+
active: 'default',
|
|
17
|
+
workspaces: { default: { name: 'default', label: 'Default', createdAt: Date.now() } },
|
|
18
|
+
};
|
|
19
|
+
fs.writeFileSync(workspacesFile, JSON.stringify(cache, null, 2));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return cache;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function setWorkspaces(data) {
|
|
26
|
+
cache = data;
|
|
27
|
+
fs.writeFileSync(workspacesFile, JSON.stringify(data, null, 2));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return { getWorkspaces, setWorkspaces };
|
|
31
|
+
}
|
package/dist/updater.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-update checker for the @clawchatsai/connector plugin.
|
|
3
|
-
*
|
|
4
|
-
* Checks the npm registry for newer versions and can trigger
|
|
5
|
-
* an in-place update via the OpenClaw plugin CLI.
|
|
6
|
-
*/
|
|
7
|
-
export interface UpdateInfo {
|
|
8
|
-
current: string;
|
|
9
|
-
latest: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Check npm registry for updates.
|
|
13
|
-
* Returns UpdateInfo if a newer version is available, null otherwise.
|
|
14
|
-
* Silently returns null on any network or parse error.
|
|
15
|
-
*/
|
|
16
|
-
export declare function checkForUpdates(): Promise<UpdateInfo | null>;
|
|
17
|
-
/**
|
|
18
|
-
* Run the OpenClaw plugin update command.
|
|
19
|
-
* Throws an Error if the command exits with a non-zero code or times out.
|
|
20
|
-
*/
|
|
21
|
-
export declare function performUpdate(): Promise<void>;
|
package/dist/updater.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-update checker for the @clawchatsai/connector plugin.
|
|
3
|
-
*
|
|
4
|
-
* Checks the npm registry for newer versions and can trigger
|
|
5
|
-
* an in-place update via the OpenClaw plugin CLI.
|
|
6
|
-
*/
|
|
7
|
-
import { execFile } from 'node:child_process';
|
|
8
|
-
import { PLUGIN_VERSION } from './index.js';
|
|
9
|
-
/**
|
|
10
|
-
* Compare two semver strings. Returns true if `a` is greater than `b`.
|
|
11
|
-
* Handles major.minor.patch only — no pre-release suffixes.
|
|
12
|
-
*/
|
|
13
|
-
function semverGt(a, b) {
|
|
14
|
-
const parse = (v) => {
|
|
15
|
-
const parts = v.split('.').map(Number);
|
|
16
|
-
return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
|
|
17
|
-
};
|
|
18
|
-
const [aMaj, aMin, aPat] = parse(a);
|
|
19
|
-
const [bMaj, bMin, bPat] = parse(b);
|
|
20
|
-
if (aMaj !== bMaj)
|
|
21
|
-
return aMaj > bMaj;
|
|
22
|
-
if (aMin !== bMin)
|
|
23
|
-
return aMin > bMin;
|
|
24
|
-
return aPat > bPat;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Check npm registry for updates.
|
|
28
|
-
* Returns UpdateInfo if a newer version is available, null otherwise.
|
|
29
|
-
* Silently returns null on any network or parse error.
|
|
30
|
-
*/
|
|
31
|
-
export async function checkForUpdates() {
|
|
32
|
-
try {
|
|
33
|
-
const res = await fetch('https://registry.npmjs.org/@clawchatsai%2Fconnector/latest');
|
|
34
|
-
if (!res.ok)
|
|
35
|
-
return null;
|
|
36
|
-
const data = await res.json();
|
|
37
|
-
const latest = data.version;
|
|
38
|
-
if (typeof latest !== 'string')
|
|
39
|
-
return null;
|
|
40
|
-
if (!semverGt(latest, PLUGIN_VERSION))
|
|
41
|
-
return null;
|
|
42
|
-
return { current: PLUGIN_VERSION, latest };
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Run the OpenClaw plugin update command.
|
|
50
|
-
* Throws an Error if the command exits with a non-zero code or times out.
|
|
51
|
-
*/
|
|
52
|
-
export async function performUpdate() {
|
|
53
|
-
return new Promise((resolve, reject) => {
|
|
54
|
-
const child = execFile('openclaw', ['plugins', 'update', '@clawchatsai/connector'], { timeout: 120_000 }, (error) => {
|
|
55
|
-
if (error) {
|
|
56
|
-
reject(new Error(`Plugin update failed: ${error.message}`));
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
resolve();
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
child; // reference kept to satisfy linter — callback handles lifecycle
|
|
63
|
-
});
|
|
64
|
-
}
|