mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-21 21:15:09 +00:00
feat: add auto-start on boot and restructure README (v1.5.0)
- setup.mjs: install launchd plist (macOS) or systemd user service (Linux) after proxy starts; logs to ~/.openclaw/logs/proxy.log - Add uninstall.mjs to stop and remove the auto-start entry - README: Quick Start (Node.js) first, Security section, Docker moved to Server/Advanced - Bump version to 1.5.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,33 +26,13 @@ The proxy translates OpenAI-compatible `/v1/chat/completions` requests into `cla
|
||||
- **Claude CLI** installed and authenticated (`claude login`)
|
||||
- **OpenClaw** installed
|
||||
|
||||
## Quick Install
|
||||
|
||||
### Docker (recommended)
|
||||
## Quick Start (Node.js)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git
|
||||
cd openclaw-claude-proxy
|
||||
cp .env.example .env # add your CLAUDE_SESSION_TOKEN / CLAUDE_COOKIES
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Or as a single command if you already have a `.env` ready:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git && cd openclaw-claude-proxy && docker compose up -d
|
||||
```
|
||||
|
||||
Health check: `curl http://localhost:3456/health`
|
||||
|
||||
### Node.js (local)
|
||||
|
||||
```bash
|
||||
# Clone
|
||||
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git
|
||||
cd openclaw-claude-proxy
|
||||
|
||||
# Auto-configure OpenClaw + start proxy
|
||||
# Auto-configure OpenClaw + start proxy + install auto-start
|
||||
node setup.mjs
|
||||
```
|
||||
|
||||
@@ -61,6 +41,7 @@ That's it. The setup script will:
|
||||
2. Add `claude-local` provider to `openclaw.json`
|
||||
3. Add auth profiles to all agents
|
||||
4. Start the proxy
|
||||
5. Install auto-start on login (launchd on macOS, systemd on Linux)
|
||||
|
||||
Then set your preferred Claude model as default:
|
||||
```bash
|
||||
@@ -68,6 +49,17 @@ openclaw config set agents.defaults.model.primary "claude-local/claude-opus-4-6"
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- **Localhost only** — the proxy binds to `127.0.0.1` and is not exposed to the internet or your local network
|
||||
- **No API keys** — authentication goes through Claude CLI's OAuth session, no credentials are stored in the proxy
|
||||
- **Auto-start via launchd/systemd** — `node setup.mjs` installs a user-level launch agent (macOS) or systemd user service (Linux) so the proxy starts automatically on login
|
||||
- **Remove auto-start** at any time:
|
||||
|
||||
```bash
|
||||
node uninstall.mjs
|
||||
```
|
||||
|
||||
## Manual Install
|
||||
|
||||
### 1. Start the proxy
|
||||
@@ -148,13 +140,25 @@ openclaw gateway restart
|
||||
- `POST /v1/chat/completions` — Chat completion (streaming + non-streaming)
|
||||
- `GET /health` — Health check
|
||||
|
||||
## Auto-start on Login (macOS)
|
||||
## Server / Advanced: Docker
|
||||
|
||||
For server deployments or if you prefer Docker:
|
||||
|
||||
Add to your `~/.zshrc`:
|
||||
```bash
|
||||
bash ~/.openclaw/projects/claude-proxy/start.sh 2>/dev/null
|
||||
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git
|
||||
cd openclaw-claude-proxy
|
||||
cp .env.example .env # add your CLAUDE_SESSION_TOKEN / CLAUDE_COOKIES
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Or as a single command if you already have a `.env` ready:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git && cd openclaw-claude-proxy && docker compose up -d
|
||||
```
|
||||
|
||||
Health check: `curl http://localhost:3456/health`
|
||||
|
||||
## Recovery after OpenClaw upgrade
|
||||
|
||||
OpenClaw upgrades (`npm update -g openclaw`) **do not overwrite** the user config at `~/.openclaw/openclaw.json`. However, if the claude-local models stop working after an upgrade, follow these steps:
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openclaw-claude-proxy",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"description": "OpenAI-compatible proxy that routes requests through Claude CLI — use your Claude Pro/Max subscription as an OpenClaw model provider",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
|
||||
@@ -279,3 +279,96 @@ if (!SKIP_START && !DRY_RUN) {
|
||||
execSync(`bash "${startPath}"`, { stdio: "inherit" });
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
// ── Step 7: Install auto-start on boot ──────────────────────────────────
|
||||
if (!DRY_RUN) {
|
||||
console.log("\n🔄 Installing auto-start on login...\n");
|
||||
|
||||
const platform = process.platform;
|
||||
const nodeBin = process.execPath;
|
||||
|
||||
// Ensure logs dir exists
|
||||
const logsDir = join(OPENCLAW_DIR, "logs");
|
||||
if (!existsSync(logsDir)) mkdirSync(logsDir, { recursive: true });
|
||||
|
||||
if (platform === "darwin") {
|
||||
// macOS: launchd
|
||||
const plistDir = join(HOME, "Library", "LaunchAgents");
|
||||
if (!existsSync(plistDir)) mkdirSync(plistDir, { recursive: true });
|
||||
|
||||
const plistPath = join(plistDir, "ai.openclaw.proxy.plist");
|
||||
const logPath = join(logsDir, "proxy.log");
|
||||
|
||||
const plistXml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>ai.openclaw.proxy</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>${nodeBin}</string>
|
||||
<string>${serverPath}</string>
|
||||
</array>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>CLAUDE_PROXY_PORT</key>
|
||||
<string>${PORT}</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>${logPath}</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>${logPath}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
`;
|
||||
|
||||
writeFileSync(plistPath, plistXml);
|
||||
log(`Plist written: ${plistPath}`);
|
||||
|
||||
// Unload first (in case it was already loaded) then load
|
||||
try { execSync(`launchctl unload "${plistPath}" 2>/dev/null`); } catch { /* ignore */ }
|
||||
execSync(`launchctl load "${plistPath}"`);
|
||||
log(`launchctl loaded ai.openclaw.proxy`);
|
||||
|
||||
} else if (platform === "linux") {
|
||||
// Linux: systemd user service
|
||||
const systemdDir = join(HOME, ".config", "systemd", "user");
|
||||
if (!existsSync(systemdDir)) mkdirSync(systemdDir, { recursive: true });
|
||||
|
||||
const servicePath = join(systemdDir, "openclaw-proxy.service");
|
||||
const logPath = join(logsDir, "proxy.log");
|
||||
|
||||
const serviceUnit = `[Unit]
|
||||
Description=OpenClaw Claude Proxy
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=${nodeBin} ${serverPath}
|
||||
Environment=CLAUDE_PROXY_PORT=${PORT}
|
||||
Restart=always
|
||||
StandardOutput=append:${logPath}
|
||||
StandardError=append:${logPath}
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`;
|
||||
|
||||
writeFileSync(servicePath, serviceUnit);
|
||||
log(`Service file written: ${servicePath}`);
|
||||
|
||||
execSync(`systemctl --user daemon-reload`);
|
||||
execSync(`systemctl --user enable openclaw-proxy`);
|
||||
execSync(`systemctl --user start openclaw-proxy`);
|
||||
log(`systemd user service enabled and started`);
|
||||
|
||||
} else {
|
||||
warn(`Auto-start not supported on ${platform} — start manually with: bash ${startPath}`);
|
||||
}
|
||||
|
||||
console.log("\n✅ Auto-start installed — proxy will start automatically on login\n");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* openclaw-claude-proxy uninstaller
|
||||
*
|
||||
* Stops and removes the launchd (macOS) or systemd (Linux) auto-start entry.
|
||||
* Run: node uninstall.mjs
|
||||
*/
|
||||
import { existsSync, unlinkSync } from "node:fs";
|
||||
import { execSync } from "node:child_process";
|
||||
import { join } from "node:path";
|
||||
import { homedir } from "node:os";
|
||||
|
||||
const HOME = homedir();
|
||||
|
||||
function log(msg) { console.log(` ✓ ${msg}`); }
|
||||
function warn(msg) { console.log(` ⚠ ${msg}`); }
|
||||
|
||||
console.log("\n🗑 Uninstalling openclaw-claude-proxy auto-start...\n");
|
||||
|
||||
const platform = process.platform;
|
||||
|
||||
if (platform === "darwin") {
|
||||
const plistPath = join(HOME, "Library", "LaunchAgents", "ai.openclaw.proxy.plist");
|
||||
|
||||
if (existsSync(plistPath)) {
|
||||
try {
|
||||
execSync(`launchctl unload "${plistPath}" 2>/dev/null`);
|
||||
log("launchd service stopped and unloaded");
|
||||
} catch {
|
||||
warn("launchctl unload failed (service may not have been running)");
|
||||
}
|
||||
unlinkSync(plistPath);
|
||||
log(`Plist removed: ${plistPath}`);
|
||||
} else {
|
||||
warn(`Plist not found: ${plistPath}`);
|
||||
}
|
||||
|
||||
} else if (platform === "linux") {
|
||||
const servicePath = join(HOME, ".config", "systemd", "user", "openclaw-proxy.service");
|
||||
|
||||
try { execSync(`systemctl --user stop openclaw-proxy 2>/dev/null`); } catch { /* ignore */ }
|
||||
log("systemd service stopped");
|
||||
|
||||
try { execSync(`systemctl --user disable openclaw-proxy 2>/dev/null`); } catch { /* ignore */ }
|
||||
log("systemd service disabled");
|
||||
|
||||
if (existsSync(servicePath)) {
|
||||
unlinkSync(servicePath);
|
||||
log(`Service file removed: ${servicePath}`);
|
||||
} else {
|
||||
warn(`Service file not found: ${servicePath}`);
|
||||
}
|
||||
|
||||
try { execSync(`systemctl --user daemon-reload`); } catch { /* ignore */ }
|
||||
|
||||
} else {
|
||||
warn(`Auto-start not supported on ${platform} — nothing to remove`);
|
||||
}
|
||||
|
||||
console.log("\n✅ Auto-start removed — proxy will no longer start on login\n");
|
||||
Reference in New Issue
Block a user