@chrysb/alphaclaw 0.8.7-beta.3 → 0.8.7-beta.5
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/lib/server/alphaclaw-runtime.js +56 -0
- package/lib/server/gateway.js +32 -14
- package/lib/server/openclaw-runtime.js +1 -1
- package/lib/server/package-fingerprint.js +72 -0
- package/lib/server/pending-alphaclaw-update.js +16 -1
- package/lib/server/pending-openclaw-update.js +16 -1
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
computePackageFingerprint,
|
|
8
8
|
isPackageRootSymlink,
|
|
9
9
|
packLocalPackageForInstall,
|
|
10
|
+
seedRuntimeFromBundledInstall,
|
|
10
11
|
} = require("./package-fingerprint");
|
|
11
12
|
|
|
12
13
|
const getManagedAlphaclawRuntimeDir = ({ rootDir = kRootDir } = {}) =>
|
|
@@ -141,6 +142,37 @@ const installManagedAlphaclawRuntime = ({
|
|
|
141
142
|
};
|
|
142
143
|
};
|
|
143
144
|
|
|
145
|
+
const seedManagedAlphaclawRuntimeFromBundledInstall = ({
|
|
146
|
+
fsModule = fs,
|
|
147
|
+
logger = console,
|
|
148
|
+
runtimeDir,
|
|
149
|
+
packageRoot,
|
|
150
|
+
} = {}) => {
|
|
151
|
+
const seedResult = seedRuntimeFromBundledInstall({
|
|
152
|
+
fsModule,
|
|
153
|
+
packageRoot,
|
|
154
|
+
runtimeDir,
|
|
155
|
+
runtimePackageJson: {
|
|
156
|
+
name: "alphaclaw-runtime",
|
|
157
|
+
private: true,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
if (!seedResult.seeded) {
|
|
161
|
+
return {
|
|
162
|
+
seeded: false,
|
|
163
|
+
version: null,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
logger.log("[alphaclaw] Seeded managed AlphaClaw runtime from bundled node_modules");
|
|
167
|
+
return {
|
|
168
|
+
seeded: true,
|
|
169
|
+
version: readManagedAlphaclawRuntimeVersion({
|
|
170
|
+
fsModule,
|
|
171
|
+
runtimeDir,
|
|
172
|
+
}),
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
|
|
144
176
|
const syncManagedAlphaclawRuntimeWithBundled = ({
|
|
145
177
|
execSyncImpl,
|
|
146
178
|
fsModule = fs,
|
|
@@ -210,6 +242,29 @@ const syncManagedAlphaclawRuntimeWithBundled = ({
|
|
|
210
242
|
);
|
|
211
243
|
}
|
|
212
244
|
|
|
245
|
+
if (!runtimeVersion) {
|
|
246
|
+
try {
|
|
247
|
+
const seedResult = seedManagedAlphaclawRuntimeFromBundledInstall({
|
|
248
|
+
fsModule,
|
|
249
|
+
logger,
|
|
250
|
+
runtimeDir,
|
|
251
|
+
packageRoot,
|
|
252
|
+
});
|
|
253
|
+
if (seedResult.seeded) {
|
|
254
|
+
return {
|
|
255
|
+
checked: true,
|
|
256
|
+
synced: true,
|
|
257
|
+
bundledVersion,
|
|
258
|
+
runtimeVersion: seedResult.version || bundledVersion,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
} catch (error) {
|
|
262
|
+
logger.log(
|
|
263
|
+
`[alphaclaw] Could not seed managed AlphaClaw runtime from bundled node_modules: ${error.message}`,
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
213
268
|
const installResult = installManagedAlphaclawRuntime({
|
|
214
269
|
execSyncImpl,
|
|
215
270
|
fsModule,
|
|
@@ -234,5 +289,6 @@ module.exports = {
|
|
|
234
289
|
installManagedAlphaclawRuntime,
|
|
235
290
|
readBundledAlphaclawVersion,
|
|
236
291
|
readManagedAlphaclawRuntimeVersion,
|
|
292
|
+
seedManagedAlphaclawRuntimeFromBundledInstall,
|
|
237
293
|
syncManagedAlphaclawRuntimeWithBundled,
|
|
238
294
|
};
|
package/lib/server/gateway.js
CHANGED
|
@@ -2,6 +2,7 @@ const path = require("path");
|
|
|
2
2
|
const { spawn, execSync } = require("child_process");
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const net = require("net");
|
|
5
|
+
const { getManagedOpenclawBinPath } = require("./openclaw-runtime");
|
|
5
6
|
const {
|
|
6
7
|
ALPHACLAW_DIR,
|
|
7
8
|
OPENCLAW_DIR,
|
|
@@ -48,6 +49,16 @@ const gatewayEnv = () => ({
|
|
|
48
49
|
XDG_CONFIG_HOME: OPENCLAW_DIR,
|
|
49
50
|
});
|
|
50
51
|
|
|
52
|
+
const shellQuote = (value) =>
|
|
53
|
+
`'${String(value || "").replace(/'/g, `'\"'\"'`)}'`;
|
|
54
|
+
|
|
55
|
+
const getOpenclawCommandPath = () => {
|
|
56
|
+
const managedBinPath = getManagedOpenclawBinPath();
|
|
57
|
+
return fs.existsSync(managedBinPath) ? managedBinPath : "openclaw";
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const getOpenclawCommandPrefix = () => shellQuote(getOpenclawCommandPath());
|
|
61
|
+
|
|
51
62
|
const writeOnboardingMarker = (reason) => {
|
|
52
63
|
fs.mkdirSync(ALPHACLAW_DIR, { recursive: true });
|
|
53
64
|
fs.writeFileSync(
|
|
@@ -119,9 +130,10 @@ const isGatewayRunning = () =>
|
|
|
119
130
|
});
|
|
120
131
|
|
|
121
132
|
const runGatewayCmd = (cmd) => {
|
|
122
|
-
|
|
133
|
+
const openclawCommandPrefix = getOpenclawCommandPrefix();
|
|
134
|
+
console.log(`[alphaclaw] Running: ${openclawCommandPrefix} gateway ${cmd}`);
|
|
123
135
|
try {
|
|
124
|
-
const out = execSync(
|
|
136
|
+
const out = execSync(`${openclawCommandPrefix} gateway ${cmd}`, {
|
|
125
137
|
env: gatewayEnv(),
|
|
126
138
|
timeout: 15000,
|
|
127
139
|
encoding: "utf8",
|
|
@@ -146,7 +158,7 @@ const launchGatewayProcess = () => {
|
|
|
146
158
|
return gatewayChild;
|
|
147
159
|
}
|
|
148
160
|
gatewayStderrTail = [];
|
|
149
|
-
const child = spawn(
|
|
161
|
+
const child = spawn(getOpenclawCommandPath(), ["gateway", "run"], {
|
|
150
162
|
env: gatewayEnv(),
|
|
151
163
|
stdio: ["pipe", "pipe", "pipe"],
|
|
152
164
|
});
|
|
@@ -306,7 +318,7 @@ const syncChannelConfig = (savedVars, mode = "all") => {
|
|
|
306
318
|
const appToken = savedMap[def.extraEnvKeys?.[0]];
|
|
307
319
|
if (!appToken) continue;
|
|
308
320
|
execSync(
|
|
309
|
-
|
|
321
|
+
`${getOpenclawCommandPrefix()} channels add --channel slack --bot-token "${token}" --app-token "${appToken}"`,
|
|
310
322
|
{ env, timeout: 15000, encoding: "utf8" },
|
|
311
323
|
);
|
|
312
324
|
let raw = fs.readFileSync(configPath, "utf8");
|
|
@@ -318,11 +330,14 @@ const syncChannelConfig = (savedVars, mode = "all") => {
|
|
|
318
330
|
}
|
|
319
331
|
fs.writeFileSync(configPath, raw);
|
|
320
332
|
} else {
|
|
321
|
-
execSync(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
333
|
+
execSync(
|
|
334
|
+
`${getOpenclawCommandPrefix()} channels add --channel ${ch} --token "${token}"`,
|
|
335
|
+
{
|
|
336
|
+
env,
|
|
337
|
+
timeout: 15000,
|
|
338
|
+
encoding: "utf8",
|
|
339
|
+
},
|
|
340
|
+
);
|
|
326
341
|
const raw = fs.readFileSync(configPath, "utf8");
|
|
327
342
|
if (raw.includes(token)) {
|
|
328
343
|
fs.writeFileSync(
|
|
@@ -344,11 +359,14 @@ const syncChannelConfig = (savedVars, mode = "all") => {
|
|
|
344
359
|
) {
|
|
345
360
|
console.log(`[alphaclaw] Removing channel: ${ch}`);
|
|
346
361
|
try {
|
|
347
|
-
execSync(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
362
|
+
execSync(
|
|
363
|
+
`${getOpenclawCommandPrefix()} channels remove --channel ${ch} --delete`,
|
|
364
|
+
{
|
|
365
|
+
env,
|
|
366
|
+
timeout: 15000,
|
|
367
|
+
encoding: "utf8",
|
|
368
|
+
},
|
|
369
|
+
);
|
|
352
370
|
console.log(`[alphaclaw] Channel ${ch} removed`);
|
|
353
371
|
} catch (e) {
|
|
354
372
|
console.error(
|
|
@@ -280,7 +280,7 @@ const syncManagedOpenclawRuntimeWithBundled = ({
|
|
|
280
280
|
logger.log(
|
|
281
281
|
runtimeVersion
|
|
282
282
|
? `[alphaclaw] Managed OpenClaw runtime ${runtimeVersion} is older than bundled ${bundledVersion}; syncing runtime...`
|
|
283
|
-
: `[alphaclaw] Managed OpenClaw runtime missing;
|
|
283
|
+
: `[alphaclaw] Managed OpenClaw runtime missing; installing bundled OpenClaw ${bundledVersion}...`,
|
|
284
284
|
);
|
|
285
285
|
}
|
|
286
286
|
|
|
@@ -142,6 +142,76 @@ const resolvePackageRootFromEntryPath = ({
|
|
|
142
142
|
return null;
|
|
143
143
|
};
|
|
144
144
|
|
|
145
|
+
const resolveInstallRootFromPackageRoot = ({ packageRoot } = {}) => {
|
|
146
|
+
const resolvedPackageRoot = path.resolve(String(packageRoot || ""));
|
|
147
|
+
if (!resolvedPackageRoot) return "";
|
|
148
|
+
const nodeModulesSegment = `${path.sep}node_modules${path.sep}`;
|
|
149
|
+
const nodeModulesIndex = resolvedPackageRoot.lastIndexOf(nodeModulesSegment);
|
|
150
|
+
if (nodeModulesIndex < 0) {
|
|
151
|
+
return resolvedPackageRoot;
|
|
152
|
+
}
|
|
153
|
+
return resolvedPackageRoot.slice(0, nodeModulesIndex);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const seedRuntimeFromBundledInstall = ({
|
|
157
|
+
fsModule = fs,
|
|
158
|
+
packageRoot,
|
|
159
|
+
runtimeDir,
|
|
160
|
+
runtimePackageJson,
|
|
161
|
+
} = {}) => {
|
|
162
|
+
const installRoot = resolveInstallRootFromPackageRoot({ packageRoot });
|
|
163
|
+
const bundledNodeModulesPath = path.join(installRoot, "node_modules");
|
|
164
|
+
if (!installRoot || !fsModule.existsSync(bundledNodeModulesPath)) {
|
|
165
|
+
return {
|
|
166
|
+
seeded: false,
|
|
167
|
+
installRoot,
|
|
168
|
+
bundledNodeModulesPath,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const resolvedRuntimeDir = path.resolve(String(runtimeDir || ""));
|
|
173
|
+
const runtimeParentDir = path.dirname(resolvedRuntimeDir);
|
|
174
|
+
fsModule.mkdirSync(runtimeParentDir, { recursive: true });
|
|
175
|
+
const tempRuntimeDir = fsModule.mkdtempSync(
|
|
176
|
+
path.join(runtimeParentDir, `${path.basename(resolvedRuntimeDir)}-seed-`),
|
|
177
|
+
);
|
|
178
|
+
let seeded = false;
|
|
179
|
+
try {
|
|
180
|
+
if (runtimePackageJson) {
|
|
181
|
+
fsModule.writeFileSync(
|
|
182
|
+
path.join(tempRuntimeDir, "package.json"),
|
|
183
|
+
JSON.stringify(runtimePackageJson, null, 2),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
fsModule.cpSync(
|
|
187
|
+
bundledNodeModulesPath,
|
|
188
|
+
path.join(tempRuntimeDir, "node_modules"),
|
|
189
|
+
{
|
|
190
|
+
recursive: true,
|
|
191
|
+
dereference: true,
|
|
192
|
+
preserveTimestamps: true,
|
|
193
|
+
},
|
|
194
|
+
);
|
|
195
|
+
try {
|
|
196
|
+
fsModule.rmSync(resolvedRuntimeDir, { recursive: true, force: true });
|
|
197
|
+
} catch {}
|
|
198
|
+
fsModule.renameSync(tempRuntimeDir, resolvedRuntimeDir);
|
|
199
|
+
seeded = true;
|
|
200
|
+
return {
|
|
201
|
+
seeded: true,
|
|
202
|
+
installRoot,
|
|
203
|
+
bundledNodeModulesPath,
|
|
204
|
+
runtimeDir: resolvedRuntimeDir,
|
|
205
|
+
};
|
|
206
|
+
} finally {
|
|
207
|
+
if (!seeded) {
|
|
208
|
+
try {
|
|
209
|
+
fsModule.rmSync(tempRuntimeDir, { recursive: true, force: true });
|
|
210
|
+
} catch {}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
|
|
145
215
|
const packLocalPackageForInstall = ({
|
|
146
216
|
execSyncImpl,
|
|
147
217
|
fsModule = fs,
|
|
@@ -198,5 +268,7 @@ module.exports = {
|
|
|
198
268
|
computePackageFingerprint,
|
|
199
269
|
isPackageRootSymlink,
|
|
200
270
|
packLocalPackageForInstall,
|
|
271
|
+
resolveInstallRootFromPackageRoot,
|
|
201
272
|
resolvePackageRootFromEntryPath,
|
|
273
|
+
seedRuntimeFromBundledInstall,
|
|
202
274
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
|
|
1
3
|
const {
|
|
2
4
|
installManagedAlphaclawRuntime,
|
|
3
5
|
} = require("./alphaclaw-runtime");
|
|
@@ -36,13 +38,23 @@ const applyPendingAlphaclawUpdate = ({
|
|
|
36
38
|
const spec = buildPendingAlphaclawInstallSpec(marker);
|
|
37
39
|
logger.log(`[alphaclaw] Pending update detected, installing ${spec}...`);
|
|
38
40
|
|
|
41
|
+
const resolvedInstallDir = path.resolve(String(installDir || ""));
|
|
42
|
+
const installParentDir = path.dirname(resolvedInstallDir);
|
|
43
|
+
const tempInstallDir = fsModule.mkdtempSync(
|
|
44
|
+
path.join(installParentDir, `${path.basename(resolvedInstallDir)}-pending-`),
|
|
45
|
+
);
|
|
46
|
+
|
|
39
47
|
try {
|
|
40
48
|
installManagedAlphaclawRuntime({
|
|
41
49
|
execSyncImpl,
|
|
42
50
|
fsModule,
|
|
43
|
-
runtimeDir:
|
|
51
|
+
runtimeDir: tempInstallDir,
|
|
44
52
|
spec,
|
|
45
53
|
});
|
|
54
|
+
try {
|
|
55
|
+
fsModule.rmSync(resolvedInstallDir, { recursive: true, force: true });
|
|
56
|
+
} catch {}
|
|
57
|
+
fsModule.renameSync(tempInstallDir, resolvedInstallDir);
|
|
46
58
|
fsModule.unlinkSync(markerPath);
|
|
47
59
|
logger.log("[alphaclaw] Update applied successfully");
|
|
48
60
|
return {
|
|
@@ -52,6 +64,9 @@ const applyPendingAlphaclawUpdate = ({
|
|
|
52
64
|
};
|
|
53
65
|
} catch (error) {
|
|
54
66
|
logger.log(`[alphaclaw] Update install failed: ${error.message}`);
|
|
67
|
+
try {
|
|
68
|
+
fsModule.rmSync(tempInstallDir, { recursive: true, force: true });
|
|
69
|
+
} catch {}
|
|
55
70
|
try {
|
|
56
71
|
fsModule.unlinkSync(markerPath);
|
|
57
72
|
} catch {}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
|
|
1
3
|
const {
|
|
2
4
|
installManagedOpenclawRuntime,
|
|
3
5
|
} = require("./openclaw-runtime");
|
|
@@ -36,14 +38,24 @@ const applyPendingOpenclawUpdate = ({
|
|
|
36
38
|
const spec = buildPendingOpenclawInstallSpec(marker);
|
|
37
39
|
logger.log(`[alphaclaw] Pending OpenClaw update detected, installing ${spec}...`);
|
|
38
40
|
|
|
41
|
+
const resolvedInstallDir = path.resolve(String(installDir || ""));
|
|
42
|
+
const installParentDir = path.dirname(resolvedInstallDir);
|
|
43
|
+
const tempInstallDir = fsModule.mkdtempSync(
|
|
44
|
+
path.join(installParentDir, `${path.basename(resolvedInstallDir)}-pending-`),
|
|
45
|
+
);
|
|
46
|
+
|
|
39
47
|
try {
|
|
40
48
|
installManagedOpenclawRuntime({
|
|
41
49
|
execSyncImpl,
|
|
42
50
|
fsModule,
|
|
43
51
|
logger,
|
|
44
|
-
runtimeDir:
|
|
52
|
+
runtimeDir: tempInstallDir,
|
|
45
53
|
spec,
|
|
46
54
|
});
|
|
55
|
+
try {
|
|
56
|
+
fsModule.rmSync(resolvedInstallDir, { recursive: true, force: true });
|
|
57
|
+
} catch {}
|
|
58
|
+
fsModule.renameSync(tempInstallDir, resolvedInstallDir);
|
|
47
59
|
fsModule.unlinkSync(markerPath);
|
|
48
60
|
logger.log("[alphaclaw] OpenClaw update applied successfully");
|
|
49
61
|
return {
|
|
@@ -53,6 +65,9 @@ const applyPendingOpenclawUpdate = ({
|
|
|
53
65
|
};
|
|
54
66
|
} catch (error) {
|
|
55
67
|
logger.log(`[alphaclaw] OpenClaw update install failed: ${error.message}`);
|
|
68
|
+
try {
|
|
69
|
+
fsModule.rmSync(tempInstallDir, { recursive: true, force: true });
|
|
70
|
+
} catch {}
|
|
56
71
|
try {
|
|
57
72
|
fsModule.unlinkSync(markerPath);
|
|
58
73
|
} catch {}
|