feat(portable): 便携版更新检测 — config-server 加 /api/update-status + check/publish 脚本 + CI 剥 BOM
config-server 新增 /api/update-status 和 /api/update-check,读取 check-update.mjs 写入的 update-available.json,便携版可提示有无新版本。publish-latest.mjs 用于 发布端生成 manifest。release.yml 顺手修打包时 .bat 的 UTF-8 BOM(BOM 会让 cmd.exe 把首条命令认错报 not internal/external command)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -419,6 +419,50 @@ const server = http.createServer((req, res) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// API: Update status — read update-available.json written by check-update.mjs
|
||||
// Returns { available: false } if no info or stale; otherwise the manifest payload.
|
||||
if (req.url === '/api/update-status' && req.method === 'GET') {
|
||||
try {
|
||||
const stateDir = process.env.OPENCLAW_STATE_DIR
|
||||
|| path.join(__dirname, '../data/.openclaw');
|
||||
const updateFile = path.join(stateDir, 'update-available.json');
|
||||
if (!fs.existsSync(updateFile)) {
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ available: false, reason: 'no-check-yet' }));
|
||||
return;
|
||||
}
|
||||
const payload = JSON.parse(fs.readFileSync(updateFile, 'utf8'));
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify(payload));
|
||||
} catch (err) {
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ available: false, reason: 'read-failed', error: err.message }));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// API: Trigger update check on demand (so users can press a "Check now" button)
|
||||
if (req.url === '/api/update-check' && req.method === 'POST') {
|
||||
(async () => {
|
||||
try {
|
||||
const mod = await import('../lib/check-update.mjs');
|
||||
const portableRoot = path.join(__dirname, '..');
|
||||
const versionFilePath = fs.existsSync(path.join(portableRoot, 'OPENCLAW_VERSION'))
|
||||
? path.join(portableRoot, 'OPENCLAW_VERSION')
|
||||
: path.join(portableRoot, '..', 'OPENCLAW_VERSION');
|
||||
const stateDir = process.env.OPENCLAW_STATE_DIR
|
||||
|| path.join(portableRoot, 'data/.openclaw');
|
||||
const result = await mod.checkUpdate({ versionFilePath, stateDir });
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify(result));
|
||||
} catch (err) {
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: err.message }));
|
||||
}
|
||||
})();
|
||||
return;
|
||||
}
|
||||
|
||||
// API: Re-run bootstrap to inject the uclaw-cloud provider
|
||||
if (req.url === '/api/xiapan/bind' && req.method === 'POST') {
|
||||
(async () => {
|
||||
|
||||
Reference in New Issue
Block a user