mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-23 05:55:09 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
983ad4f18b |
@@ -12,7 +12,7 @@
|
|||||||
* 4. Creates start.sh for easy launch
|
* 4. Creates start.sh for easy launch
|
||||||
* 5. Optionally starts the proxy
|
* 5. Optionally starts the proxy
|
||||||
*/
|
*/
|
||||||
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, readdirSync } from "node:fs";
|
||||||
import { execSync } from "node:child_process";
|
import { execSync } from "node:child_process";
|
||||||
import { join, dirname } from "node:path";
|
import { join, dirname } from "node:path";
|
||||||
import { homedir } from "node:os";
|
import { homedir } from "node:os";
|
||||||
@@ -107,11 +107,18 @@ try {
|
|||||||
warn("Make sure you're logged in: claude login");
|
warn("Make sure you're logged in: claude login");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check openclaw config
|
// Check openclaw config (optional — OCP runs standalone without OpenClaw)
|
||||||
if (!existsSync(CONFIG_PATH)) fail(`OpenClaw config not found at ${CONFIG_PATH}`);
|
const OPENCLAW_PRESENT = existsSync(CONFIG_PATH);
|
||||||
|
if (OPENCLAW_PRESENT) {
|
||||||
log(`OpenClaw config: ${CONFIG_PATH}`);
|
log(`OpenClaw config: ${CONFIG_PATH}`);
|
||||||
|
} else {
|
||||||
|
warn(`OpenClaw not detected at ${CONFIG_PATH} — skipping OpenClaw integration.`);
|
||||||
|
warn(`To register OCP with OpenClaw later, install OpenClaw and re-run \`node setup.mjs\`,`);
|
||||||
|
warn(`or run \`ocp update\` if OpenClaw is installed afterward.`);
|
||||||
|
}
|
||||||
|
|
||||||
// ── Step 2: Patch openclaw.json ─────────────────────────────────────────
|
// ── Step 2: Patch openclaw.json ─────────────────────────────────────────
|
||||||
|
if (OPENCLAW_PRESENT) {
|
||||||
console.log("\n📝 Configuring OpenClaw...\n");
|
console.log("\n📝 Configuring OpenClaw...\n");
|
||||||
|
|
||||||
const config = readJSON(CONFIG_PATH);
|
const config = readJSON(CONFIG_PATH);
|
||||||
@@ -175,8 +182,6 @@ const agentDirs = existsSync(agentsDir)
|
|||||||
})
|
})
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
import { readdirSync } from "node:fs";
|
|
||||||
|
|
||||||
for (const agentId of agentDirs) {
|
for (const agentId of agentDirs) {
|
||||||
const apPath = join(agentsDir, agentId, "agent", "auth-profiles.json");
|
const apPath = join(agentsDir, agentId, "agent", "auth-profiles.json");
|
||||||
try {
|
try {
|
||||||
@@ -208,6 +213,7 @@ for (const agentId of agentDirs) {
|
|||||||
if (agentDirs.length === 0) {
|
if (agentDirs.length === 0) {
|
||||||
warn("No agent auth-profiles.json found — you may need to restart the gateway first");
|
warn("No agent auth-profiles.json found — you may need to restart the gateway first");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Step 4: Create start.sh ─────────────────────────────────────────────
|
// ── Step 4: Create start.sh ─────────────────────────────────────────────
|
||||||
console.log("\n🚀 Creating launcher...\n");
|
console.log("\n🚀 Creating launcher...\n");
|
||||||
@@ -238,31 +244,53 @@ if (!DRY_RUN) {
|
|||||||
log(`Launcher: ${startPath}`);
|
log(`Launcher: ${startPath}`);
|
||||||
|
|
||||||
// ── Step 5: Summary ─────────────────────────────────────────────────────
|
// ── Step 5: Summary ─────────────────────────────────────────────────────
|
||||||
console.log(`
|
const banner = [
|
||||||
╔══════════════════════════════════════════════════════════════╗
|
`╔══════════════════════════════════════════════════════════════╗`,
|
||||||
║ Setup complete! ║
|
`║ Setup complete! ║`,
|
||||||
╠══════════════════════════════════════════════════════════════╣
|
`╠══════════════════════════════════════════════════════════════╣`,
|
||||||
║ ║
|
`║ ║`,
|
||||||
║ Provider: ${PROVIDER_NAME.padEnd(44)}║
|
`║ Provider: ${PROVIDER_NAME.padEnd(44)}║`,
|
||||||
║ Port: ${String(PORT).padEnd(44)}║
|
`║ Port: ${String(PORT).padEnd(44)}║`,
|
||||||
║ Models: ${`see models.json (${MODELS.length} available)`.padEnd(44)}║
|
`║ Models: ${`see models.json (${MODELS.length} available)`.padEnd(44)}║`,
|
||||||
║ Default: ${DEFAULT_MODEL_ID.padEnd(44)}║
|
`║ Default: ${DEFAULT_MODEL_ID.padEnd(44)}║`,
|
||||||
║ ║
|
`║ ║`,
|
||||||
║ Start proxy: ║
|
`║ Start proxy: ║`,
|
||||||
║ bash ${startPath.replace(HOME, "~").padEnd(50)}║
|
`║ bash ${startPath.replace(HOME, "~").padEnd(50)}║`,
|
||||||
║ ║
|
`║ ║`,
|
||||||
║ Or directly: ║
|
`║ Or directly: ║`,
|
||||||
║ node ${serverPath.replace(HOME, "~").padEnd(49)}║
|
`║ node ${serverPath.replace(HOME, "~").padEnd(49)}║`,
|
||||||
║ ║
|
`║ ║`,
|
||||||
║ Set as default model in openclaw.json: ║
|
];
|
||||||
║ agents.defaults.model.primary = ║
|
if (OPENCLAW_PRESENT) {
|
||||||
║ "${PROVIDER_NAME}/${DEFAULT_MODEL_ID}"${" ".repeat(Math.max(0, 30 - PROVIDER_NAME.length - DEFAULT_MODEL_ID.length))}║
|
banner.push(
|
||||||
║ ║
|
`║ Set as default model in openclaw.json: ║`,
|
||||||
║ Then restart gateway: ║
|
`║ agents.defaults.model.primary = ║`,
|
||||||
║ openclaw gateway restart ║
|
`║ "${PROVIDER_NAME}/${DEFAULT_MODEL_ID}"${" ".repeat(Math.max(0, 30 - PROVIDER_NAME.length - DEFAULT_MODEL_ID.length))}║`,
|
||||||
║ ║
|
`║ ║`,
|
||||||
╚══════════════════════════════════════════════════════════════╝
|
`║ Then restart gateway: ║`,
|
||||||
`);
|
`║ openclaw gateway restart ║`,
|
||||||
|
`║ ║`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
banner.push(
|
||||||
|
`║ OpenClaw not detected — running in standalone mode. ║`,
|
||||||
|
`║ Point your IDE (Cline / Cursor / Continue / OpenCode / ║`,
|
||||||
|
`║ Aider / OpenClaw) at: ║`,
|
||||||
|
`║ http://${BIND_ADDRESS}:${String(PORT)}/v1${" ".repeat(Math.max(0, 47 - BIND_ADDRESS.length - String(PORT).length))}║`,
|
||||||
|
`║ ║`,
|
||||||
|
`║ See README § "Client Setup" for per-IDE instructions. ║`,
|
||||||
|
`║ ║`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
banner.push(`╚══════════════════════════════════════════════════════════════╝`);
|
||||||
|
console.log("\n" + banner.join("\n") + "\n");
|
||||||
|
|
||||||
|
// ── Step 6: Optionally start ────────────────────────────────────────────
|
||||||
|
if (!SKIP_START && !DRY_RUN) {
|
||||||
|
try {
|
||||||
|
execSync(`bash "${startPath}"`, { stdio: "inherit" });
|
||||||
|
} catch { /* ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
// ── Step 7: Install auto-start on boot ──────────────────────────────────
|
// ── Step 7: Install auto-start on boot ──────────────────────────────────
|
||||||
if (!DRY_RUN) {
|
if (!DRY_RUN) {
|
||||||
@@ -398,52 +426,4 @@ WantedBy=default.target
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log("\n✅ Auto-start installed — proxy will start automatically on login\n");
|
console.log("\n✅ Auto-start installed — proxy will start automatically on login\n");
|
||||||
|
|
||||||
// ── Step 8: Post-install health verification ───────────────────────────
|
|
||||||
if (!SKIP_START) {
|
|
||||||
console.log("⏳ Waiting for server to bind...\n");
|
|
||||||
await new Promise(r => setTimeout(r, 3000));
|
|
||||||
|
|
||||||
const healthUrl = `http://127.0.0.1:${PORT}/health`;
|
|
||||||
let verified = false;
|
|
||||||
try {
|
|
||||||
const controller = new AbortController();
|
|
||||||
const timer = setTimeout(() => controller.abort(), 5000);
|
|
||||||
const res = await fetch(healthUrl, { signal: controller.signal });
|
|
||||||
clearTimeout(timer);
|
|
||||||
|
|
||||||
if (res.ok) {
|
|
||||||
const body = await res.json().catch(() => ({}));
|
|
||||||
console.log(` ✓ Health check passed (${healthUrl})`);
|
|
||||||
console.log(` version: ${body.version ?? "unknown"}`);
|
|
||||||
console.log(` authMode: ${body.authMode ?? "unknown"}`);
|
|
||||||
|
|
||||||
// Verify bind socket
|
|
||||||
try {
|
|
||||||
const bindCheck = process.platform === "linux"
|
|
||||||
? execSync(`ss -tlnp 2>/dev/null | grep ':${PORT}'`, { encoding: "utf-8" }).trim()
|
|
||||||
: execSync(`lsof -nP -iTCP:${PORT} -sTCP:LISTEN 2>/dev/null`, { encoding: "utf-8" }).trim();
|
|
||||||
if (bindCheck) {
|
|
||||||
console.log(` bind: ${bindCheck.split("\n")[0]}`);
|
|
||||||
}
|
|
||||||
} catch { /* bind check is best-effort */ }
|
|
||||||
|
|
||||||
verified = true;
|
|
||||||
} else {
|
|
||||||
warn(`Health check returned HTTP ${res.status} — service may not have started cleanly`);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
const isTimeout = e.name === "AbortError" || (e.cause && e.cause.code === "UND_ERR_CONNECT_TIMEOUT");
|
|
||||||
warn(`Health check failed: ${isTimeout ? "timeout (5s)" : e.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verified) {
|
|
||||||
const logHint = process.platform === "linux"
|
|
||||||
? "journalctl --user -u ocp-proxy -n 50"
|
|
||||||
: `tail -n 100 ~/.ocp/logs/proxy.log`;
|
|
||||||
console.error(`\n ✗ Server did not respond on port ${PORT} within 5 seconds.`);
|
|
||||||
console.error(` Check service logs:\n ${logHint}\n`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user