Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/cli/package-lock.json
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit of a weird diff. (?)..

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openrouter/spawn",
"version": "1.0.44",
"version": "1.0.46",
"type": "module",
"bin": {
"spawn": "cli.js"
Expand Down
39 changes: 29 additions & 10 deletions packages/cli/src/shared/cursor-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,22 @@ export async function setupCursorProxy(
logStep("Deploying Cursor→OpenRouter proxy...");

// 1. Install Caddy if not present
// Detect OS and arch at runtime so this works on macOS (darwin/arm64|amd64)
// and Linux (linux/amd64|arm64). Write to ~/.local/bin which is user-writable
// on every platform -- /usr/local/bin is SIP-protected on macOS and requires
// root elsewhere.
const installCaddy = [
"set -e",
'if command -v caddy >/dev/null 2>&1; then echo "caddy already installed"; exit 0; fi',
'echo "Installing Caddy..."',
'curl -sf "https://caddyserver.com/api/download?os=linux&arch=amd64" -o /usr/local/bin/caddy',
"chmod +x /usr/local/bin/caddy",
'OS=$(uname -s | tr "[:upper:]" "[:lower:]")',
"ARCH=$(uname -m)",
'[ "$ARCH" = "x86_64" ] && ARCH="amd64"',
'[ "$ARCH" = "aarch64" ] && ARCH="arm64"',
'mkdir -p "$HOME/.local/bin"',
'curl -fsSL "https://caddyserver.com/api/download?os=${OS}&arch=${ARCH}" -o "$HOME/.local/bin/caddy"',
'chmod +x "$HOME/.local/bin/caddy"',
'export PATH="$HOME/.local/bin:$PATH"',
"caddy version",
].join("\n");

Expand Down Expand Up @@ -334,18 +345,23 @@ export async function setupCursorProxy(
logInfo("Proxy scripts deployed");

// 3. Configure /etc/hosts for domain spoofing
// Requires elevated privileges on all platforms (/etc/hosts is root-owned).
// Use a temp-file swap via sudo cp to avoid sed -i portability issues
// (macOS sed requires a backup suffix with -i; Linux does not).
const hostsScript = [
// Remove any existing cursor entries
'sed -i "/cursor\\.sh/d" /etc/hosts 2>/dev/null || true',
// Add our entries
`echo "127.0.0.1 ${CURSOR_DOMAINS.join(" ")}" >> /etc/hosts`,
// Build a clean copy without existing cursor entries then append ours
'grep -v "cursor.sh" /etc/hosts > /tmp/hosts_cursor_new 2>/dev/null || cp /etc/hosts /tmp/hosts_cursor_new',
`echo "127.0.0.1 ${CURSOR_DOMAINS.join(" ")}" >> /tmp/hosts_cursor_new`,
"sudo cp /tmp/hosts_cursor_new /etc/hosts",
"rm -f /tmp/hosts_cursor_new",
].join(" && ");

await wrapSshCall(runner.runServer(hostsScript));
logInfo("Hosts spoofing configured");

// 4. Install Caddy's internal CA cert
const trustScript = "caddy trust 2>/dev/null || true";
// Include ~/.local/bin in PATH since Caddy may have been installed there above.
const trustScript = 'export PATH="$HOME/.local/bin:$PATH" && caddy trust 2>/dev/null || true';
await wrapSshCall(runner.runServer(trustScript, 30));
logInfo("Caddy CA trusted");

Expand All @@ -365,7 +381,7 @@ CONF`,

/**
* Start the Cursor proxy services (Caddy + two Node.js backends).
* Uses systemd if available, falls back to setsid/nohup.
* Uses systemd if available, falls back to nohup (POSIX -- works on macOS and Linux).
*/
export async function startCursorProxy(
runner: CloudRunner,
Expand All @@ -390,6 +406,8 @@ export async function startCursorProxy(

const script = [
"source ~/.spawnrc 2>/dev/null",
// Ensure ~/.local/bin (where Caddy may be installed) is in PATH for this script.
'export PATH="$HOME/.local/bin:$PATH"',
nodeFind,

// Start unary backend
Expand All @@ -415,7 +433,8 @@ export async function startCursorProxy(
" $_sudo systemctl daemon-reload",
" $_sudo systemctl restart cursor-proxy-unary",
" else",
" setsid $NODE ~/.cursor/proxy/unary.mjs < /dev/null &",
// setsid is Linux-only; nohup is POSIX and works on macOS and Linux.
" nohup $NODE ~/.cursor/proxy/unary.mjs < /dev/null > /tmp/cursor-proxy-unary.log 2>&1 &",
" fi",
"fi",

Expand Down Expand Up @@ -443,7 +462,7 @@ export async function startCursorProxy(
" $_sudo systemctl daemon-reload",
" $_sudo systemctl restart cursor-proxy-bidi",
" else",
" setsid $NODE ~/.cursor/proxy/bidi.mjs < /dev/null &",
" nohup $NODE ~/.cursor/proxy/bidi.mjs < /dev/null > /tmp/cursor-proxy-bidi.log 2>&1 &",
" fi",
"fi",

Expand Down