From 0d61da51530c34f024ddbd2dd592e14a3d05621a Mon Sep 17 00:00:00 2001 From: dtzp555-max Date: Sat, 9 May 2026 00:49:43 +1000 Subject: [PATCH] fix(setup): inject CLAUDE_BIN, OCP_ADMIN_KEY, PROXY_ANONYMOUS_KEY into service env (#76) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gap #1 partial (CLAUDE_BIN): setup.mjs now detects `which claude` at install time (or reads $CLAUDE_BIN) and writes CLAUDE_BIN into the service unit EnvironmentVariables dict. Works for nvm/homebrew paths not in server.mjs's hardcoded list, and for older server.mjs deployments. Gap #2 (OCP_ADMIN_KEY): reads $OCP_ADMIN_KEY from the user's shell env and conditionally injects it into the plist/systemd unit. Empty/unset → key is omitted entirely (server.mjs treats empty string as "no admin"). Key value is never logged; only its length is reported. Gap #6 partial (PROXY_ANONYMOUS_KEY): reads $PROXY_ANONYMOUS_KEY and conditionally injects it. Unset → key is omitted (anonymous access disabled). All three keys are read via process.env at install time; no new CLI flags. Injection status is logged before the !DRY_RUN guard so dry-run shows what would be written. Identified during fresh-state Round 2 testing. Co-authored-by: dtzp555 Co-authored-by: Claude Sonnet 4.6 --- setup.mjs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/setup.mjs b/setup.mjs index c5d3215..ff26c51 100755 --- a/setup.mjs +++ b/setup.mjs @@ -39,6 +39,29 @@ const PROVIDER_NAME = opt("provider-name", "claude-local"); const BIND_ADDRESS = opt("bind", "127.0.0.1"); const AUTH_MODE_CONFIG = opt("auth-mode", "none"); +// ── Service-env injection: CLAUDE_BIN, OCP_ADMIN_KEY, PROXY_ANONYMOUS_KEY ── +// These are read from the user's shell env at install time and written into +// the service unit (plist / systemd) so the daemon picks them up on boot. + +// CLAUDE_BIN — detect at install time; omit if not found (server.mjs fallback) +let CLAUDE_BIN_INJECT = null; +if (process.env.CLAUDE_BIN) { + CLAUDE_BIN_INJECT = process.env.CLAUDE_BIN; +} else { + try { + const detected = execSync("which claude 2>/dev/null", { encoding: "utf-8" }).trim(); + if (detected && existsSync(detected)) { + CLAUDE_BIN_INJECT = detected; + } + } catch { /* which not available or claude not on PATH — omit */ } +} + +// OCP_ADMIN_KEY — omit entirely when empty/unset; don't write empty string +const OCP_ADMIN_KEY_INJECT = process.env.OCP_ADMIN_KEY || null; + +// PROXY_ANONYMOUS_KEY — same pattern +const PROXY_ANON_KEY_INJECT = process.env.PROXY_ANONYMOUS_KEY || null; + // ── Models: derived from models.json (single source of truth) ────────── const modelsConfig = JSON.parse(readFileSync(join(__dirname, "models.json"), "utf-8")); @@ -286,6 +309,29 @@ banner.push(`╚═════════════════════ console.log("\n" + banner.join("\n") + "\n"); // ── Step 7: Install auto-start on boot ────────────────────────────────── + +// Log service-env injection plan (shown in both dry-run and live mode) +console.log("\n🔧 Service unit env vars to inject:\n"); +if (CLAUDE_BIN_INJECT) { + log(`CLAUDE_BIN: ${CLAUDE_BIN_INJECT}`); +} else { + log(`CLAUDE_BIN: (not found — server.mjs will auto-detect at runtime)`); +} +if (OCP_ADMIN_KEY_INJECT) { + log(`OCP_ADMIN_KEY: injected (length: ${OCP_ADMIN_KEY_INJECT.length})`); +} else { + log(`OCP_ADMIN_KEY: (unset — admin endpoints disabled)`); +} +if (PROXY_ANON_KEY_INJECT) { + log(`PROXY_ANONYMOUS_KEY: injected (set)`); +} else { + log(`PROXY_ANONYMOUS_KEY: (unset — anonymous access disabled)`); +} + +if (DRY_RUN) { + console.log("\n [dry-run] would write service unit with above env vars\n"); +} + if (!DRY_RUN) { console.log("\n🔄 Installing auto-start on login...\n"); @@ -358,7 +404,13 @@ if (!DRY_RUN) { CLAUDE_BIND ${BIND_ADDRESS} CLAUDE_AUTH_MODE - ${AUTH_MODE_CONFIG} + ${AUTH_MODE_CONFIG}${CLAUDE_BIN_INJECT ? ` + CLAUDE_BIN + ${CLAUDE_BIN_INJECT}` : ""}${OCP_ADMIN_KEY_INJECT ? ` + OCP_ADMIN_KEY + ${OCP_ADMIN_KEY_INJECT}` : ""}${PROXY_ANON_KEY_INJECT ? ` + PROXY_ANONYMOUS_KEY + ${PROXY_ANON_KEY_INJECT}` : ""} RunAtLoad @@ -396,7 +448,7 @@ After=network.target ExecStart=${nodeBin} ${serverPath} Environment=CLAUDE_PROXY_PORT=${PORT} Environment=CLAUDE_BIND=${BIND_ADDRESS} -Environment=CLAUDE_AUTH_MODE=${AUTH_MODE_CONFIG} +Environment=CLAUDE_AUTH_MODE=${AUTH_MODE_CONFIG}${CLAUDE_BIN_INJECT ? `\nEnvironment=CLAUDE_BIN=${CLAUDE_BIN_INJECT}` : ""}${OCP_ADMIN_KEY_INJECT ? `\nEnvironment=OCP_ADMIN_KEY=${OCP_ADMIN_KEY_INJECT}` : ""}${PROXY_ANON_KEY_INJECT ? `\nEnvironment=PROXY_ANONYMOUS_KEY=${PROXY_ANON_KEY_INJECT}` : ""} Restart=always RestartSec=5 StandardOutput=append:${logPath}