@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.
@@ -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
  };
@@ -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
- console.log(`[alphaclaw] Running: openclaw gateway ${cmd}`);
133
+ const openclawCommandPrefix = getOpenclawCommandPrefix();
134
+ console.log(`[alphaclaw] Running: ${openclawCommandPrefix} gateway ${cmd}`);
123
135
  try {
124
- const out = execSync(`openclaw gateway ${cmd}`, {
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("openclaw", ["gateway", "run"], {
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
- `openclaw channels add --channel slack --bot-token "${token}" --app-token "${appToken}"`,
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(`openclaw channels add --channel ${ch} --token "${token}"`, {
322
- env,
323
- timeout: 15000,
324
- encoding: "utf8",
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(`openclaw channels remove --channel ${ch} --delete`, {
348
- env,
349
- timeout: 15000,
350
- encoding: "utf8",
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; seeding bundled OpenClaw ${bundledVersion}...`,
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: installDir,
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: installDir,
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 {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrysb/alphaclaw",
3
- "version": "0.8.7-beta.3",
3
+ "version": "0.8.7-beta.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },