@chrysb/alphaclaw 0.8.7-beta.3 → 0.8.7
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 +43 -174
- package/lib/public/css/tailwind.generated.css +1 -1
- package/lib/public/dist/app.bundle.js +2021 -2041
- package/lib/public/js/app.js +0 -3
- package/lib/public/js/components/gateway.js +3 -6
- package/lib/public/js/components/general/index.js +0 -2
- package/lib/public/js/components/onboarding/welcome-form-step.js +4 -29
- package/lib/public/js/components/routes/general-route.js +0 -2
- package/lib/public/js/components/routes/watchdog-route.js +0 -2
- package/lib/public/js/components/sidebar.js +7 -20
- package/lib/public/js/components/update-modal.js +1 -2
- package/lib/public/js/components/watchdog-tab/index.js +0 -2
- package/lib/public/js/components/welcome/index.js +0 -1
- package/lib/public/js/components/welcome/use-welcome.js +2 -52
- package/lib/public/js/hooks/use-app-shell-controller.js +9 -33
- package/lib/public/js/lib/api.js +0 -35
- package/lib/server/alphaclaw-version.js +128 -37
- package/lib/server/openclaw-version.js +130 -59
- package/lib/server/routes/system.js +1 -6
- package/lib/server/usage-tracker-config.js +3 -27
- package/package.json +2 -2
- package/patches/openclaw+2026.4.5.patch +13 -0
- package/lib/public/js/components/update-modal-helpers.js +0 -12
- package/lib/server/alphaclaw-runtime.js +0 -238
- package/lib/server/openclaw-runtime.js +0 -338
- package/lib/server/package-fingerprint.js +0 -202
- package/lib/server/pending-alphaclaw-update.js +0 -70
- package/lib/server/pending-openclaw-update.js +0 -71
- package/patches/openclaw+2026.4.1.patch +0 -13
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
const childProcess = require("child_process");
|
|
1
2
|
const fs = require("fs");
|
|
3
|
+
const os = require("os");
|
|
2
4
|
const path = require("path");
|
|
3
5
|
const https = require("https");
|
|
4
6
|
const http = require("http");
|
|
@@ -6,6 +8,7 @@ const {
|
|
|
6
8
|
kLatestVersionCacheTtlMs,
|
|
7
9
|
kAlphaclawRegistryUrl,
|
|
8
10
|
kNpmPackageRoot,
|
|
11
|
+
kOpenclawUpdateCopyTimeoutMs,
|
|
9
12
|
kRootDir,
|
|
10
13
|
} = require("./constants");
|
|
11
14
|
|
|
@@ -23,9 +26,6 @@ const isNewerVersion = (latest, current) => {
|
|
|
23
26
|
return l.patch > c.patch;
|
|
24
27
|
};
|
|
25
28
|
|
|
26
|
-
const buildAlphaclawInstallSpec = (version = "latest") =>
|
|
27
|
-
`@chrysb/alphaclaw@${String(version || "").trim() || "latest"}`;
|
|
28
|
-
|
|
29
29
|
const createAlphaclawVersionService = () => {
|
|
30
30
|
let kUpdateStatusCache = {
|
|
31
31
|
latestVersion: null,
|
|
@@ -108,6 +108,120 @@ const createAlphaclawVersionService = () => {
|
|
|
108
108
|
return { latestVersion, hasUpdate };
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
+
const findInstallDir = () => {
|
|
112
|
+
// Walk up from kNpmPackageRoot to find the consuming project's directory
|
|
113
|
+
// (the one with node_modules/@chrysb/alphaclaw). In Docker this is /app.
|
|
114
|
+
let dir = kNpmPackageRoot;
|
|
115
|
+
while (dir !== path.dirname(dir)) {
|
|
116
|
+
const parent = path.dirname(dir);
|
|
117
|
+
if (
|
|
118
|
+
path.basename(parent) === "node_modules" ||
|
|
119
|
+
parent.includes(`${path.sep}node_modules${path.sep}`)
|
|
120
|
+
) {
|
|
121
|
+
dir = parent;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const pkgPath = path.join(parent, "package.json");
|
|
125
|
+
if (fs.existsSync(pkgPath)) {
|
|
126
|
+
try {
|
|
127
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
128
|
+
if (
|
|
129
|
+
pkg.dependencies?.["@chrysb/alphaclaw"] ||
|
|
130
|
+
pkg.devDependencies?.["@chrysb/alphaclaw"] ||
|
|
131
|
+
pkg.optionalDependencies?.["@chrysb/alphaclaw"]
|
|
132
|
+
) {
|
|
133
|
+
return parent;
|
|
134
|
+
}
|
|
135
|
+
} catch {}
|
|
136
|
+
}
|
|
137
|
+
dir = parent;
|
|
138
|
+
}
|
|
139
|
+
// Fallback: if running directly (not from node_modules), use kNpmPackageRoot
|
|
140
|
+
return kNpmPackageRoot;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const installLatestAlphaclaw = () =>
|
|
144
|
+
new Promise((resolve, reject) => {
|
|
145
|
+
const installDir = findInstallDir();
|
|
146
|
+
const tmpDir = fs.mkdtempSync(
|
|
147
|
+
path.join(os.tmpdir(), "alphaclaw-update-"),
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const cleanup = () => {
|
|
151
|
+
try {
|
|
152
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
153
|
+
} catch {}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
fs.writeFileSync(
|
|
157
|
+
path.join(tmpDir, "package.json"),
|
|
158
|
+
JSON.stringify({
|
|
159
|
+
private: true,
|
|
160
|
+
dependencies: { "@chrysb/alphaclaw": "latest" },
|
|
161
|
+
}),
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const npmEnv = {
|
|
165
|
+
...process.env,
|
|
166
|
+
npm_config_update_notifier: "false",
|
|
167
|
+
npm_config_fund: "false",
|
|
168
|
+
npm_config_audit: "false",
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
console.log(
|
|
172
|
+
`[alphaclaw] Running: npm install @chrysb/alphaclaw@latest in temp dir (target: ${installDir})`,
|
|
173
|
+
);
|
|
174
|
+
childProcess.exec(
|
|
175
|
+
"npm install --omit=dev --prefer-online --package-lock=false",
|
|
176
|
+
{
|
|
177
|
+
cwd: tmpDir,
|
|
178
|
+
env: npmEnv,
|
|
179
|
+
timeout: 180000,
|
|
180
|
+
},
|
|
181
|
+
(err, stdout, stderr) => {
|
|
182
|
+
if (err) {
|
|
183
|
+
const message = String(stderr || err.message || "").trim();
|
|
184
|
+
console.log(
|
|
185
|
+
`[alphaclaw] alphaclaw install error: ${message.slice(0, 200)}`,
|
|
186
|
+
);
|
|
187
|
+
cleanup();
|
|
188
|
+
return reject(
|
|
189
|
+
new Error(
|
|
190
|
+
message || "Failed to install @chrysb/alphaclaw@latest",
|
|
191
|
+
),
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
if (stdout?.trim()) {
|
|
195
|
+
console.log(
|
|
196
|
+
`[alphaclaw] alphaclaw install stdout: ${stdout.trim().slice(0, 300)}`,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const src = path.join(tmpDir, "node_modules");
|
|
201
|
+
const dest = path.join(installDir, "node_modules");
|
|
202
|
+
childProcess.exec(
|
|
203
|
+
`cp -af "${src}/." "${dest}/"`,
|
|
204
|
+
{ timeout: kOpenclawUpdateCopyTimeoutMs },
|
|
205
|
+
(copyErr) => {
|
|
206
|
+
cleanup();
|
|
207
|
+
if (copyErr) {
|
|
208
|
+
console.log(
|
|
209
|
+
`[alphaclaw] alphaclaw copy error: ${(copyErr.message || "").slice(0, 200)}`,
|
|
210
|
+
);
|
|
211
|
+
return reject(
|
|
212
|
+
new Error(
|
|
213
|
+
`Failed to copy updated AlphaClaw files: ${copyErr.message}`,
|
|
214
|
+
),
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
console.log("[alphaclaw] alphaclaw install completed");
|
|
218
|
+
resolve({ stdout: stdout?.trim(), stderr: stderr?.trim() });
|
|
219
|
+
},
|
|
220
|
+
);
|
|
221
|
+
},
|
|
222
|
+
);
|
|
223
|
+
});
|
|
224
|
+
|
|
111
225
|
const isContainer = () =>
|
|
112
226
|
process.env.RAILWAY_ENVIRONMENT ||
|
|
113
227
|
process.env.RENDER ||
|
|
@@ -126,15 +240,9 @@ const createAlphaclawVersionService = () => {
|
|
|
126
240
|
// On bare metal / Mac / Linux, spawn a replacement process then exit.
|
|
127
241
|
console.log("[alphaclaw] Spawning new process and exiting...");
|
|
128
242
|
const { spawn } = require("child_process");
|
|
129
|
-
const
|
|
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)], {
|
|
243
|
+
const child = spawn(process.argv[0], process.argv.slice(1), {
|
|
135
244
|
detached: true,
|
|
136
245
|
stdio: "inherit",
|
|
137
|
-
env: nextEnv,
|
|
138
246
|
});
|
|
139
247
|
child.unref();
|
|
140
248
|
process.exit(0);
|
|
@@ -169,33 +277,18 @@ const createAlphaclawVersionService = () => {
|
|
|
169
277
|
kUpdateInProgress = true;
|
|
170
278
|
const previousVersion = readAlphaclawVersion();
|
|
171
279
|
try {
|
|
172
|
-
|
|
280
|
+
await installLatestAlphaclaw();
|
|
281
|
+
// Write marker to persistent volume so the update survives container recreation
|
|
282
|
+
const markerPath = path.join(kRootDir, ".alphaclaw-update-pending");
|
|
173
283
|
try {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
} catch (error) {
|
|
179
|
-
console.log(
|
|
180
|
-
`[alphaclaw] Could not resolve exact AlphaClaw version before restart: ${error.message || "unknown error"}`,
|
|
284
|
+
fs.writeFileSync(
|
|
285
|
+
markerPath,
|
|
286
|
+
JSON.stringify({ from: previousVersion, ts: Date.now() }),
|
|
181
287
|
);
|
|
288
|
+
console.log(`[alphaclaw] Update marker written to ${markerPath}`);
|
|
289
|
+
} catch (e) {
|
|
290
|
+
console.log(`[alphaclaw] Could not write update marker: ${e.message}`);
|
|
182
291
|
}
|
|
183
|
-
|
|
184
|
-
const spec = buildAlphaclawInstallSpec(targetVersion);
|
|
185
|
-
// Write marker to persistent volume so the update survives container recreation
|
|
186
|
-
const markerPath = path.join(kRootDir, ".alphaclaw-update-pending");
|
|
187
|
-
fs.writeFileSync(
|
|
188
|
-
markerPath,
|
|
189
|
-
JSON.stringify({
|
|
190
|
-
from: previousVersion,
|
|
191
|
-
to: targetVersion,
|
|
192
|
-
spec,
|
|
193
|
-
ts: Date.now(),
|
|
194
|
-
}),
|
|
195
|
-
);
|
|
196
|
-
console.log(
|
|
197
|
-
`[alphaclaw] Update marker written to ${markerPath} for ${spec}`,
|
|
198
|
-
);
|
|
199
292
|
kUpdateStatusCache = {
|
|
200
293
|
latestVersion: null,
|
|
201
294
|
hasUpdate: false,
|
|
@@ -206,17 +299,15 @@ const createAlphaclawVersionService = () => {
|
|
|
206
299
|
body: {
|
|
207
300
|
ok: true,
|
|
208
301
|
previousVersion,
|
|
209
|
-
targetVersion: targetVersion === "latest" ? null : targetVersion,
|
|
210
302
|
restarting: true,
|
|
211
303
|
},
|
|
212
304
|
};
|
|
213
305
|
} catch (err) {
|
|
306
|
+
kUpdateInProgress = false;
|
|
214
307
|
return {
|
|
215
308
|
status: 500,
|
|
216
309
|
body: { ok: false, error: err.message || "Failed to update AlphaClaw" },
|
|
217
310
|
};
|
|
218
|
-
} finally {
|
|
219
|
-
kUpdateInProgress = false;
|
|
220
311
|
}
|
|
221
312
|
};
|
|
222
313
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
const { execSync } = require("child_process");
|
|
1
|
+
const { exec, execSync } = require("child_process");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
+
const os = require("os");
|
|
3
4
|
const path = require("path");
|
|
4
5
|
const {
|
|
5
6
|
kVersionCacheTtlMs,
|
|
6
7
|
kLatestVersionCacheTtlMs,
|
|
7
|
-
|
|
8
|
+
kNpmPackageRoot,
|
|
9
|
+
kOpenclawUpdateCopyTimeoutMs,
|
|
8
10
|
} = require("./constants");
|
|
9
11
|
const { normalizeOpenclawVersion } = require("./helpers");
|
|
10
12
|
const { parseJsonObjectFromNoisyOutput } = require("./utils/json");
|
|
@@ -22,9 +24,6 @@ const createOpenclawVersionService = ({
|
|
|
22
24
|
};
|
|
23
25
|
let kOpenclawUpdateInProgress = false;
|
|
24
26
|
|
|
25
|
-
const buildOpenclawInstallSpec = (version = "latest") =>
|
|
26
|
-
`openclaw@${String(version || "").trim() || "latest"}`;
|
|
27
|
-
|
|
28
27
|
const readOpenclawVersion = () => {
|
|
29
28
|
const now = Date.now();
|
|
30
29
|
if (
|
|
@@ -88,6 +87,118 @@ const createOpenclawVersionService = ({
|
|
|
88
87
|
}
|
|
89
88
|
};
|
|
90
89
|
|
|
90
|
+
const findInstallDir = () => {
|
|
91
|
+
// Resolve the consumer app root (for example /app in Docker), not this package directory.
|
|
92
|
+
let dir = kNpmPackageRoot;
|
|
93
|
+
while (dir !== path.dirname(dir)) {
|
|
94
|
+
const parent = path.dirname(dir);
|
|
95
|
+
if (
|
|
96
|
+
path.basename(parent) === "node_modules" ||
|
|
97
|
+
parent.includes(`${path.sep}node_modules${path.sep}`)
|
|
98
|
+
) {
|
|
99
|
+
dir = parent;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const pkgPath = path.join(parent, "package.json");
|
|
103
|
+
if (fs.existsSync(pkgPath)) {
|
|
104
|
+
try {
|
|
105
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
106
|
+
if (
|
|
107
|
+
pkg.dependencies?.["@chrysb/alphaclaw"] ||
|
|
108
|
+
pkg.devDependencies?.["@chrysb/alphaclaw"] ||
|
|
109
|
+
pkg.optionalDependencies?.["@chrysb/alphaclaw"]
|
|
110
|
+
) {
|
|
111
|
+
return parent;
|
|
112
|
+
}
|
|
113
|
+
} catch {}
|
|
114
|
+
}
|
|
115
|
+
dir = parent;
|
|
116
|
+
}
|
|
117
|
+
return kNpmPackageRoot;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// Install to a temp directory, then copy into the real node_modules.
|
|
121
|
+
// Running `npm install` directly in the app dir causes EBUSY on Docker
|
|
122
|
+
// because npm tries to rename directories that the running process holds open.
|
|
123
|
+
// Copying individual files (cp -af) avoids the rename syscall entirely.
|
|
124
|
+
const installLatestOpenclaw = () =>
|
|
125
|
+
new Promise((resolve, reject) => {
|
|
126
|
+
const installDir = findInstallDir();
|
|
127
|
+
const tmpDir = fs.mkdtempSync(
|
|
128
|
+
path.join(os.tmpdir(), "openclaw-update-"),
|
|
129
|
+
);
|
|
130
|
+
const cleanup = () => {
|
|
131
|
+
try {
|
|
132
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
133
|
+
} catch {}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
fs.writeFileSync(
|
|
137
|
+
path.join(tmpDir, "package.json"),
|
|
138
|
+
JSON.stringify({
|
|
139
|
+
private: true,
|
|
140
|
+
dependencies: { openclaw: "latest" },
|
|
141
|
+
}),
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const npmEnv = {
|
|
145
|
+
...process.env,
|
|
146
|
+
npm_config_update_notifier: "false",
|
|
147
|
+
npm_config_fund: "false",
|
|
148
|
+
npm_config_audit: "false",
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
console.log(
|
|
152
|
+
`[alphaclaw] Running: npm install openclaw@latest in temp dir (target: ${installDir})`,
|
|
153
|
+
);
|
|
154
|
+
exec(
|
|
155
|
+
"npm install --omit=dev --prefer-online --package-lock=false",
|
|
156
|
+
{ cwd: tmpDir, env: npmEnv, timeout: 180000 },
|
|
157
|
+
(installErr, stdout, stderr) => {
|
|
158
|
+
if (installErr) {
|
|
159
|
+
const message = String(stderr || installErr.message || "").trim();
|
|
160
|
+
console.log(
|
|
161
|
+
`[alphaclaw] openclaw install error: ${message.slice(0, 200)}`,
|
|
162
|
+
);
|
|
163
|
+
cleanup();
|
|
164
|
+
return reject(
|
|
165
|
+
new Error(message || "Failed to install openclaw@latest"),
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
if (stdout?.trim()) {
|
|
169
|
+
console.log(
|
|
170
|
+
`[alphaclaw] openclaw install stdout: ${stdout.trim().slice(0, 300)}`,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const src = path.join(tmpDir, "node_modules");
|
|
175
|
+
const dest = path.join(installDir, "node_modules");
|
|
176
|
+
exec(
|
|
177
|
+
`cp -af "${src}/." "${dest}/"`,
|
|
178
|
+
{ timeout: kOpenclawUpdateCopyTimeoutMs },
|
|
179
|
+
(cpErr) => {
|
|
180
|
+
cleanup();
|
|
181
|
+
if (cpErr) {
|
|
182
|
+
console.log(
|
|
183
|
+
`[alphaclaw] openclaw copy error: ${(cpErr.message || "").slice(0, 200)}`,
|
|
184
|
+
);
|
|
185
|
+
return reject(
|
|
186
|
+
new Error(
|
|
187
|
+
`Failed to copy updated openclaw files: ${cpErr.message}`,
|
|
188
|
+
),
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
console.log("[alphaclaw] openclaw install completed");
|
|
192
|
+
resolve({
|
|
193
|
+
stdout: stdout?.trim() || "",
|
|
194
|
+
stderr: stderr?.trim() || "",
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
);
|
|
198
|
+
},
|
|
199
|
+
);
|
|
200
|
+
});
|
|
201
|
+
|
|
91
202
|
const getVersionStatus = async (refresh) => {
|
|
92
203
|
const currentVersion = readOpenclawVersion();
|
|
93
204
|
try {
|
|
@@ -117,67 +228,27 @@ const createOpenclawVersionService = ({
|
|
|
117
228
|
kOpenclawUpdateInProgress = true;
|
|
118
229
|
const previousVersion = readOpenclawVersion();
|
|
119
230
|
try {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (!hasUpdate && latestVersion && latestVersion === previousVersion) {
|
|
133
|
-
return {
|
|
134
|
-
status: 200,
|
|
135
|
-
body: {
|
|
136
|
-
ok: true,
|
|
137
|
-
previousVersion,
|
|
138
|
-
currentVersion: previousVersion,
|
|
139
|
-
latestVersion,
|
|
140
|
-
hasUpdate: false,
|
|
141
|
-
restarted: false,
|
|
142
|
-
restarting: false,
|
|
143
|
-
updated: false,
|
|
144
|
-
},
|
|
145
|
-
};
|
|
231
|
+
await installLatestOpenclaw();
|
|
232
|
+
kOpenclawVersionCache = { value: null, fetchedAt: 0 };
|
|
233
|
+
const currentVersion = readOpenclawVersion();
|
|
234
|
+
const { latestVersion, hasUpdate } = readOpenclawUpdateStatus({
|
|
235
|
+
refresh: true,
|
|
236
|
+
});
|
|
237
|
+
let restarted = false;
|
|
238
|
+
if (isOnboarded()) {
|
|
239
|
+
restartGateway();
|
|
240
|
+
restarted = true;
|
|
146
241
|
}
|
|
147
|
-
|
|
148
|
-
const targetVersion = latestVersion || "latest";
|
|
149
|
-
const spec = buildOpenclawInstallSpec(targetVersion);
|
|
150
|
-
const markerPath = path.join(kRootDir, ".openclaw-update-pending");
|
|
151
|
-
fs.writeFileSync(
|
|
152
|
-
markerPath,
|
|
153
|
-
JSON.stringify({
|
|
154
|
-
from: previousVersion,
|
|
155
|
-
to: targetVersion,
|
|
156
|
-
spec,
|
|
157
|
-
ts: Date.now(),
|
|
158
|
-
}),
|
|
159
|
-
);
|
|
160
|
-
console.log(
|
|
161
|
-
`[alphaclaw] OpenClaw update marker written to ${markerPath} for ${spec}`,
|
|
162
|
-
);
|
|
163
|
-
kOpenclawVersionCache = { value: previousVersion, fetchedAt: 0 };
|
|
164
|
-
kOpenclawUpdateStatusCache = {
|
|
165
|
-
latestVersion,
|
|
166
|
-
hasUpdate,
|
|
167
|
-
fetchedAt: 0,
|
|
168
|
-
};
|
|
169
242
|
return {
|
|
170
243
|
status: 200,
|
|
171
244
|
body: {
|
|
172
245
|
ok: true,
|
|
173
246
|
previousVersion,
|
|
174
|
-
currentVersion
|
|
175
|
-
targetVersion: targetVersion === "latest" ? null : targetVersion,
|
|
247
|
+
currentVersion,
|
|
176
248
|
latestVersion,
|
|
177
|
-
hasUpdate
|
|
178
|
-
restarted
|
|
179
|
-
|
|
180
|
-
updated: previousVersion !== targetVersion,
|
|
249
|
+
hasUpdate,
|
|
250
|
+
restarted,
|
|
251
|
+
updated: previousVersion !== currentVersion,
|
|
181
252
|
},
|
|
182
253
|
};
|
|
183
254
|
} catch (err) {
|
|
@@ -588,12 +588,7 @@ const registerSystemRoutes = ({
|
|
|
588
588
|
console.log(
|
|
589
589
|
`[alphaclaw] /api/openclaw/update result: status=${result.status} ok=${result.body?.ok === true}`,
|
|
590
590
|
);
|
|
591
|
-
|
|
592
|
-
res.json(result.body);
|
|
593
|
-
setTimeout(() => alphaclawVersionService.restartProcess(), 1000);
|
|
594
|
-
} else {
|
|
595
|
-
res.status(result.status).json(result.body);
|
|
596
|
-
}
|
|
591
|
+
res.status(result.status).json(result.body);
|
|
597
592
|
});
|
|
598
593
|
|
|
599
594
|
app.get("/api/alphaclaw/version", async (req, res) => {
|
|
@@ -8,27 +8,6 @@ const kUsageTrackerPluginPath = path.resolve(
|
|
|
8
8
|
"usage-tracker",
|
|
9
9
|
);
|
|
10
10
|
|
|
11
|
-
const normalizePluginPath = (value = "") =>
|
|
12
|
-
String(value || "")
|
|
13
|
-
.trim()
|
|
14
|
-
.replace(/\\/g, "/")
|
|
15
|
-
.replace(/\/+$/, "");
|
|
16
|
-
|
|
17
|
-
const isUsageTrackerPluginPath = (value = "") => {
|
|
18
|
-
const normalizedValue = normalizePluginPath(value);
|
|
19
|
-
const normalizedCanonicalPath = normalizePluginPath(kUsageTrackerPluginPath);
|
|
20
|
-
if (!normalizedValue) return false;
|
|
21
|
-
if (
|
|
22
|
-
normalizedValue === normalizedCanonicalPath ||
|
|
23
|
-
normalizedValue.startsWith(`${normalizedCanonicalPath}/`)
|
|
24
|
-
) {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
return /(?:^|\/)(?:node_modules\/@chrysb\/alphaclaw\/lib|lib)\/plugin\/usage-tracker(?:\/.*)?$/.test(
|
|
28
|
-
normalizedValue,
|
|
29
|
-
);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
11
|
const ensurePluginsShell = (cfg = {}) => {
|
|
33
12
|
if (!cfg.plugins || typeof cfg.plugins !== "object") cfg.plugins = {};
|
|
34
13
|
if (!Array.isArray(cfg.plugins.allow)) cfg.plugins.allow = [];
|
|
@@ -53,11 +32,9 @@ const ensurePluginAllowed = ({ cfg = {}, pluginKey = "" }) => {
|
|
|
53
32
|
const ensureUsageTrackerPluginEntry = (cfg = {}) => {
|
|
54
33
|
const before = JSON.stringify(cfg);
|
|
55
34
|
ensurePluginAllowed({ cfg, pluginKey: "usage-tracker" });
|
|
56
|
-
|
|
57
|
-
(
|
|
58
|
-
|
|
59
|
-
nextPaths.push(kUsageTrackerPluginPath);
|
|
60
|
-
cfg.plugins.load.paths = nextPaths;
|
|
35
|
+
if (!cfg.plugins.load.paths.includes(kUsageTrackerPluginPath)) {
|
|
36
|
+
cfg.plugins.load.paths.push(kUsageTrackerPluginPath);
|
|
37
|
+
}
|
|
61
38
|
cfg.plugins.entries["usage-tracker"] = {
|
|
62
39
|
...(cfg.plugins.entries["usage-tracker"] &&
|
|
63
40
|
typeof cfg.plugins.entries["usage-tracker"] === "object"
|
|
@@ -87,7 +64,6 @@ const ensureUsageTrackerPluginConfig = ({ fsModule, openclawDir }) => {
|
|
|
87
64
|
|
|
88
65
|
module.exports = {
|
|
89
66
|
kUsageTrackerPluginPath,
|
|
90
|
-
isUsageTrackerPluginPath,
|
|
91
67
|
ensurePluginsShell,
|
|
92
68
|
ensurePluginAllowed,
|
|
93
69
|
ensureUsageTrackerPluginEntry,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrysb/alphaclaw",
|
|
3
|
-
"version": "0.8.7
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"express": "^4.21.0",
|
|
38
38
|
"http-proxy": "^1.18.1",
|
|
39
|
-
"openclaw": "2026.4.
|
|
39
|
+
"openclaw": "2026.4.5",
|
|
40
40
|
"patch-package": "^8.0.1",
|
|
41
41
|
"ws": "^8.19.0"
|
|
42
42
|
},
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
diff --git a/node_modules/openclaw/dist/server-Cv5hzFG4.js b/node_modules/openclaw/dist/server-Cv5hzFG4.js
|
|
2
|
+
index 926102f391c94b0e8bb52c2d322c107636e267f3..9e04644fcb8cc406d9b50f2590c5e12788cb7b6e 100644
|
|
3
|
+
--- a/node_modules/openclaw/dist/server-Cv5hzFG4.js
|
|
4
|
+
+++ b/node_modules/openclaw/dist/server-Cv5hzFG4.js
|
|
5
|
+
@@ -26710,7 +26710,7 @@
|
|
6
|
+
close(1008, truncateCloseReason(authMessage));
|
|
7
|
+
};
|
|
8
|
+
const clearUnboundScopes = () => {
|
|
9
|
+
- if (scopes.length > 0) {
|
|
10
|
+
+ if (scopes.length > 0 && !sharedAuthOk) {
|
|
11
|
+
scopes = [];
|
|
12
|
+
connectParams.scopes = scopes;
|
|
13
|
+
}
|