@chrysb/alphaclaw 0.8.7-beta.1 → 0.8.7-beta.2
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/bin/alphaclaw.js
CHANGED
|
@@ -16,6 +16,11 @@ const {
|
|
|
16
16
|
const {
|
|
17
17
|
applyPendingAlphaclawUpdate,
|
|
18
18
|
} = require("../lib/server/pending-alphaclaw-update");
|
|
19
|
+
const {
|
|
20
|
+
getManagedAlphaclawCliPath,
|
|
21
|
+
getManagedAlphaclawRuntimeDir,
|
|
22
|
+
syncManagedAlphaclawRuntimeWithBundled,
|
|
23
|
+
} = require("../lib/server/alphaclaw-runtime");
|
|
19
24
|
const {
|
|
20
25
|
applyPendingOpenclawUpdate,
|
|
21
26
|
} = require("../lib/server/pending-openclaw-update");
|
|
@@ -173,10 +178,89 @@ if (portFlag) {
|
|
|
173
178
|
process.env.PORT = portFlag;
|
|
174
179
|
}
|
|
175
180
|
|
|
181
|
+
const kManagedAlphaclawRuntimeEnvFlag = "ALPHACLAW_MANAGED_RUNTIME_ACTIVE";
|
|
182
|
+
const shouldBootstrapManagedAlphaclawRuntime =
|
|
183
|
+
command === "start" &&
|
|
184
|
+
process.env[kManagedAlphaclawRuntimeEnvFlag] !== "1";
|
|
185
|
+
|
|
176
186
|
// ---------------------------------------------------------------------------
|
|
177
187
|
// 2. Create directory structure
|
|
178
188
|
// ---------------------------------------------------------------------------
|
|
179
189
|
|
|
190
|
+
if (shouldBootstrapManagedAlphaclawRuntime) {
|
|
191
|
+
const { spawn } = require("child_process");
|
|
192
|
+
const managedAlphaclawRuntimeDir = getManagedAlphaclawRuntimeDir({ rootDir });
|
|
193
|
+
const pendingUpdateMarker = path.join(rootDir, ".alphaclaw-update-pending");
|
|
194
|
+
if (fs.existsSync(pendingUpdateMarker)) {
|
|
195
|
+
applyPendingAlphaclawUpdate({
|
|
196
|
+
execSyncImpl: execSync,
|
|
197
|
+
fsModule: fs,
|
|
198
|
+
installDir: managedAlphaclawRuntimeDir,
|
|
199
|
+
logger: console,
|
|
200
|
+
markerPath: pendingUpdateMarker,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
syncManagedAlphaclawRuntimeWithBundled({
|
|
205
|
+
execSyncImpl: execSync,
|
|
206
|
+
fsModule: fs,
|
|
207
|
+
logger: console,
|
|
208
|
+
runtimeDir: managedAlphaclawRuntimeDir,
|
|
209
|
+
});
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.log(
|
|
212
|
+
`[alphaclaw] Could not sync managed AlphaClaw runtime from bundled install: ${error.message}`,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const managedAlphaclawCliPath = getManagedAlphaclawCliPath({
|
|
217
|
+
runtimeDir: managedAlphaclawRuntimeDir,
|
|
218
|
+
});
|
|
219
|
+
if (!fs.existsSync(managedAlphaclawCliPath)) {
|
|
220
|
+
console.error(
|
|
221
|
+
`[alphaclaw] Managed AlphaClaw runtime missing CLI at ${managedAlphaclawCliPath}`,
|
|
222
|
+
);
|
|
223
|
+
process.exit(1);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const runtimeChild = spawn(
|
|
227
|
+
process.argv[0],
|
|
228
|
+
[managedAlphaclawCliPath, ...process.argv.slice(2)],
|
|
229
|
+
{
|
|
230
|
+
stdio: "inherit",
|
|
231
|
+
env: {
|
|
232
|
+
...process.env,
|
|
233
|
+
[kManagedAlphaclawRuntimeEnvFlag]: "1",
|
|
234
|
+
ALPHACLAW_BOOTSTRAP_CLI_PATH: __filename,
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
const forwardSignal = (signal) => {
|
|
240
|
+
if (runtimeChild.exitCode === null && !runtimeChild.killed) {
|
|
241
|
+
runtimeChild.kill(signal);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
process.on("SIGTERM", () => forwardSignal("SIGTERM"));
|
|
246
|
+
process.on("SIGINT", () => forwardSignal("SIGINT"));
|
|
247
|
+
|
|
248
|
+
runtimeChild.on("error", (error) => {
|
|
249
|
+
console.error(
|
|
250
|
+
`[alphaclaw] Managed AlphaClaw runtime launch failed: ${error.message}`,
|
|
251
|
+
);
|
|
252
|
+
process.exit(1);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
runtimeChild.on("exit", (code, signal) => {
|
|
256
|
+
if (signal) {
|
|
257
|
+
process.kill(process.pid, signal);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
process.exit(Number.isInteger(code) ? code : 0);
|
|
261
|
+
});
|
|
262
|
+
} else {
|
|
263
|
+
|
|
180
264
|
const openclawDir = path.join(rootDir, ".openclaw");
|
|
181
265
|
fs.mkdirSync(openclawDir, { recursive: true });
|
|
182
266
|
const { hourlyGitSyncPath } = migrateManagedInternalFiles({
|
|
@@ -952,3 +1036,4 @@ try {
|
|
|
952
1036
|
|
|
953
1037
|
console.log("[alphaclaw] Setup complete -- starting server");
|
|
954
1038
|
require("../lib/server.js");
|
|
1039
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
const { kRootDir } = require("./constants");
|
|
5
|
+
const { compareVersionParts } = require("./helpers");
|
|
6
|
+
|
|
7
|
+
const getManagedAlphaclawRuntimeDir = ({ rootDir = kRootDir } = {}) =>
|
|
8
|
+
path.join(rootDir, ".alphaclaw-runtime");
|
|
9
|
+
|
|
10
|
+
const getManagedAlphaclawCliPath = ({ runtimeDir } = {}) =>
|
|
11
|
+
path.join(
|
|
12
|
+
runtimeDir || getManagedAlphaclawRuntimeDir(),
|
|
13
|
+
"node_modules",
|
|
14
|
+
"@chrysb",
|
|
15
|
+
"alphaclaw",
|
|
16
|
+
"bin",
|
|
17
|
+
"alphaclaw.js",
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const getManagedAlphaclawPackageJsonPath = ({ runtimeDir } = {}) =>
|
|
21
|
+
path.join(
|
|
22
|
+
runtimeDir || getManagedAlphaclawRuntimeDir(),
|
|
23
|
+
"node_modules",
|
|
24
|
+
"@chrysb",
|
|
25
|
+
"alphaclaw",
|
|
26
|
+
"package.json",
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const ensureManagedAlphaclawRuntimeProject = ({
|
|
30
|
+
fsModule = fs,
|
|
31
|
+
runtimeDir,
|
|
32
|
+
} = {}) => {
|
|
33
|
+
const resolvedRuntimeDir = runtimeDir || getManagedAlphaclawRuntimeDir();
|
|
34
|
+
const packageJsonPath = path.join(resolvedRuntimeDir, "package.json");
|
|
35
|
+
fsModule.mkdirSync(resolvedRuntimeDir, { recursive: true });
|
|
36
|
+
if (!fsModule.existsSync(packageJsonPath)) {
|
|
37
|
+
fsModule.writeFileSync(
|
|
38
|
+
packageJsonPath,
|
|
39
|
+
JSON.stringify(
|
|
40
|
+
{
|
|
41
|
+
name: "alphaclaw-runtime",
|
|
42
|
+
private: true,
|
|
43
|
+
},
|
|
44
|
+
null,
|
|
45
|
+
2,
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
runtimeDir: resolvedRuntimeDir,
|
|
51
|
+
packageJsonPath,
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const readManagedAlphaclawRuntimeVersion = ({
|
|
56
|
+
fsModule = fs,
|
|
57
|
+
runtimeDir,
|
|
58
|
+
} = {}) => {
|
|
59
|
+
try {
|
|
60
|
+
const pkg = JSON.parse(
|
|
61
|
+
fsModule.readFileSync(
|
|
62
|
+
getManagedAlphaclawPackageJsonPath({ runtimeDir }),
|
|
63
|
+
"utf8",
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
return String(pkg?.version || "").trim() || null;
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const readBundledAlphaclawVersion = ({
|
|
73
|
+
fsModule = fs,
|
|
74
|
+
packageJsonPath = path.resolve(__dirname, "..", "..", "package.json"),
|
|
75
|
+
} = {}) => {
|
|
76
|
+
try {
|
|
77
|
+
const pkg = JSON.parse(fsModule.readFileSync(packageJsonPath, "utf8"));
|
|
78
|
+
return String(pkg?.version || "").trim() || null;
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const shellQuote = (value) =>
|
|
85
|
+
`'${String(value || "").replace(/'/g, `'\"'\"'`)}'`;
|
|
86
|
+
|
|
87
|
+
const installManagedAlphaclawRuntime = ({
|
|
88
|
+
execSyncImpl,
|
|
89
|
+
fsModule = fs,
|
|
90
|
+
runtimeDir,
|
|
91
|
+
spec,
|
|
92
|
+
} = {}) => {
|
|
93
|
+
const normalizedSpec =
|
|
94
|
+
String(spec || "").trim() || "@chrysb/alphaclaw@latest";
|
|
95
|
+
ensureManagedAlphaclawRuntimeProject({
|
|
96
|
+
fsModule,
|
|
97
|
+
runtimeDir,
|
|
98
|
+
});
|
|
99
|
+
execSyncImpl(
|
|
100
|
+
`npm install ${shellQuote(normalizedSpec)} --omit=dev --no-save --save=false --package-lock=false --prefer-online`,
|
|
101
|
+
{
|
|
102
|
+
cwd: runtimeDir,
|
|
103
|
+
stdio: "inherit",
|
|
104
|
+
timeout: 180000,
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
return {
|
|
108
|
+
spec: normalizedSpec,
|
|
109
|
+
version: readManagedAlphaclawRuntimeVersion({
|
|
110
|
+
fsModule,
|
|
111
|
+
runtimeDir,
|
|
112
|
+
}),
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const syncManagedAlphaclawRuntimeWithBundled = ({
|
|
117
|
+
execSyncImpl,
|
|
118
|
+
fsModule = fs,
|
|
119
|
+
logger = console,
|
|
120
|
+
runtimeDir,
|
|
121
|
+
packageJsonPath,
|
|
122
|
+
} = {}) => {
|
|
123
|
+
const bundledVersion = readBundledAlphaclawVersion({
|
|
124
|
+
fsModule,
|
|
125
|
+
packageJsonPath,
|
|
126
|
+
});
|
|
127
|
+
if (!bundledVersion) {
|
|
128
|
+
return {
|
|
129
|
+
checked: false,
|
|
130
|
+
synced: false,
|
|
131
|
+
bundledVersion: null,
|
|
132
|
+
runtimeVersion: readManagedAlphaclawRuntimeVersion({
|
|
133
|
+
fsModule,
|
|
134
|
+
runtimeDir,
|
|
135
|
+
}),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const runtimeVersion = readManagedAlphaclawRuntimeVersion({
|
|
140
|
+
fsModule,
|
|
141
|
+
runtimeDir,
|
|
142
|
+
});
|
|
143
|
+
if (runtimeVersion && compareVersionParts(runtimeVersion, bundledVersion) >= 0) {
|
|
144
|
+
return {
|
|
145
|
+
checked: true,
|
|
146
|
+
synced: false,
|
|
147
|
+
bundledVersion,
|
|
148
|
+
runtimeVersion,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
logger.log(
|
|
153
|
+
runtimeVersion
|
|
154
|
+
? `[alphaclaw] Managed AlphaClaw runtime ${runtimeVersion} is older than bundled ${bundledVersion}; syncing runtime...`
|
|
155
|
+
: `[alphaclaw] Managed AlphaClaw runtime missing; seeding bundled AlphaClaw ${bundledVersion}...`,
|
|
156
|
+
);
|
|
157
|
+
const installResult = installManagedAlphaclawRuntime({
|
|
158
|
+
execSyncImpl,
|
|
159
|
+
fsModule,
|
|
160
|
+
runtimeDir,
|
|
161
|
+
spec: `@chrysb/alphaclaw@${bundledVersion}`,
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
checked: true,
|
|
165
|
+
synced: true,
|
|
166
|
+
bundledVersion,
|
|
167
|
+
runtimeVersion: installResult.version || bundledVersion,
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
module.exports = {
|
|
172
|
+
ensureManagedAlphaclawRuntimeProject,
|
|
173
|
+
getManagedAlphaclawCliPath,
|
|
174
|
+
getManagedAlphaclawPackageJsonPath,
|
|
175
|
+
getManagedAlphaclawRuntimeDir,
|
|
176
|
+
installManagedAlphaclawRuntime,
|
|
177
|
+
readBundledAlphaclawVersion,
|
|
178
|
+
readManagedAlphaclawRuntimeVersion,
|
|
179
|
+
syncManagedAlphaclawRuntimeWithBundled,
|
|
180
|
+
};
|
|
@@ -126,9 +126,15 @@ const createAlphaclawVersionService = () => {
|
|
|
126
126
|
// On bare metal / Mac / Linux, spawn a replacement process then exit.
|
|
127
127
|
console.log("[alphaclaw] Spawning new process and exiting...");
|
|
128
128
|
const { spawn } = require("child_process");
|
|
129
|
-
const
|
|
129
|
+
const nextEnv = { ...process.env };
|
|
130
|
+
delete nextEnv.ALPHACLAW_MANAGED_RUNTIME_ACTIVE;
|
|
131
|
+
const bootstrapCliPath =
|
|
132
|
+
String(process.env.ALPHACLAW_BOOTSTRAP_CLI_PATH || "").trim() ||
|
|
133
|
+
process.argv[1];
|
|
134
|
+
const child = spawn(process.argv[0], [bootstrapCliPath, ...process.argv.slice(2)], {
|
|
130
135
|
detached: true,
|
|
131
136
|
stdio: "inherit",
|
|
137
|
+
env: nextEnv,
|
|
132
138
|
});
|
|
133
139
|
child.unref();
|
|
134
140
|
process.exit(0);
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
const {
|
|
2
|
+
installManagedAlphaclawRuntime,
|
|
3
|
+
} = require("./alphaclaw-runtime");
|
|
4
|
+
|
|
1
5
|
const buildPendingAlphaclawInstallSpec = (marker = {}) => {
|
|
2
6
|
const explicitSpec = String(marker?.spec || "").trim();
|
|
3
7
|
if (explicitSpec) {
|
|
@@ -7,9 +11,6 @@ const buildPendingAlphaclawInstallSpec = (marker = {}) => {
|
|
|
7
11
|
return `@chrysb/alphaclaw@${targetVersion}`;
|
|
8
12
|
};
|
|
9
13
|
|
|
10
|
-
const shellQuote = (value) =>
|
|
11
|
-
`'${String(value || "").replace(/'/g, `'\"'\"'`)}'`;
|
|
12
|
-
|
|
13
14
|
const applyPendingAlphaclawUpdate = ({
|
|
14
15
|
execSyncImpl,
|
|
15
16
|
fsModule,
|
|
@@ -36,14 +37,12 @@ const applyPendingAlphaclawUpdate = ({
|
|
|
36
37
|
logger.log(`[alphaclaw] Pending update detected, installing ${spec}...`);
|
|
37
38
|
|
|
38
39
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
},
|
|
46
|
-
);
|
|
40
|
+
installManagedAlphaclawRuntime({
|
|
41
|
+
execSyncImpl,
|
|
42
|
+
fsModule,
|
|
43
|
+
runtimeDir: installDir,
|
|
44
|
+
spec,
|
|
45
|
+
});
|
|
47
46
|
fsModule.unlinkSync(markerPath);
|
|
48
47
|
logger.log("[alphaclaw] Update applied successfully");
|
|
49
48
|
return {
|