78 lines
2.1 KiB
JavaScript
78 lines
2.1 KiB
JavaScript
'use strict';
|
||||
|
|
// 環境檢查:start 前確認 codex CLI、pm2、git 等工具是否就緒。
|
|||
|
|
const { execSync } = require('child_process');
|
|||
|
|
const fs = require('fs');
|
|||
|
|
const os = require('os');
|
|||
|
|
const path = require('path');
|
|||
|
|
|
|||
|
|
function tryExec(cmd) {
|
|||
|
|
try {
|
|||
|
|
return execSync(cmd, { encoding: 'utf-8', windowsHide: true, stdio: ['ignore', 'pipe', 'ignore'], timeout: 15000 }).trim();
|
|||
|
|
} catch {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 回傳 [{ name, ok, required, message }]
|
|||
|
|
function runChecks() {
|
|||
|
|
const checks = [];
|
|||
|
|
|
|||
|
|
const nodeMajor = Number(process.versions.node.split('.')[0]);
|
|||
|
|
checks.push({
|
|||
|
|
name: 'Node.js',
|
|||
|
|
ok: nodeMajor >= 18,
|
|||
|
|
required: true,
|
|||
|
|
message: nodeMajor >= 18 ? process.version : `${process.version}(需要 ≥ 18)`,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const codexVer = tryExec('codex --version');
|
|||
|
|
checks.push({
|
|||
|
|
name: 'Codex CLI',
|
|||
|
|
ok: !!codexVer,
|
|||
|
|
required: true,
|
|||
|
|
message: codexVer || '找不到 codex,請安裝:npm install -g @openai/codex',
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (codexVer) {
|
|||
|
|
const authFile = path.join(os.homedir(), '.codex', 'auth.json');
|
|||
|
|
const loggedIn = fs.existsSync(authFile);
|
|||
|
|
checks.push({
|
|||
|
|
name: 'Codex 登入',
|
|||
|
|
ok: loggedIn,
|
|||
|
|
required: false,
|
|||
|
|
message: loggedIn ? '已登入' : '尚未登入,請先執行:codex login(bot 啟動後才需要)',
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const pm2Ver = tryExec('pm2 -v');
|
|||
|
|
checks.push({
|
|||
|
|
name: 'pm2',
|
|||
|
|
ok: !!pm2Ver,
|
|||
|
|
required: true,
|
|||
|
|
message: pm2Ver ? `v${pm2Ver.split('\n').pop()}` : '找不到 pm2,請安裝:npm install -g pm2',
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const gitVer = tryExec('git --version');
|
|||
|
|
checks.push({
|
|||
|
|
name: 'git',
|
|||
|
|
ok: !!gitVer,
|
|||
|
|
required: false,
|
|||
|
|
message: gitVer || '找不到 git(非必要:bot 以 --skip-git-repo-check 執行,但 Codex 要做版控操作時會需要)',
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return checks;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function printChecks(checks) {
|
|||
|
|
for (const c of checks) {
|
|||
|
|
const icon = c.ok ? '✅' : c.required ? '❌' : '⚠️';
|
|||
|
|
console.log(`${icon} ${c.name}:${c.message}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hasBlocker(checks) {
|
|||
|
|
return checks.some((c) => c.required && !c.ok);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { runChecks, printChecks, hasBlocker };
|