Download server.js from habppyar/testoc: direct link, hf CLI and curl.
- Browser
- Download file 3.13 kB
-
https://huggingface.co/spaces/habppyar/testoc/resolve/main/server.js
- Command line
-
hf download hf://spaces/habppyar/testoc/server.js
-
curl -L -o server.js https://huggingface.co/spaces/habppyar/testoc/resolve/main/server.js
3.13 kB
| const { spawn, spawnSync } = require("child_process"); | |
| const fs = require("fs"); | |
| const path = require("path"); | |
| const PORT = String(process.env.PORT || 7860); | |
| const HOST = "0.0.0.0"; | |
| // Default workspace: use HOME so /home/node/chat temp project 会在 UI 里直接可见 | |
| const HOME = process.env.HOME || "/home/node"; | |
| const WORKSPACE_DIR = process.env.WORKSPACE_DIR || HOME; | |
| function resolveOpencodeBin() { | |
| const localBin = path.join(__dirname, "node_modules", ".bin", "opencode"); | |
| if (fs.existsSync(localBin)) return localBin; | |
| return "opencode"; | |
| } | |
| function spawnSyncSafe(cmd, args) { | |
| const r = spawnSync(cmd, args, { encoding: "utf-8" }); | |
| if (r.error) return "not found"; | |
| return (r.stdout || r.stderr || "").trim().split("\n")[0] || "ok"; | |
| } | |
| function buildEnv() { | |
| const env = { ...process.env }; | |
| // Map OPENCODE_PASSWORD -> OPENCODE_SERVER_PASSWORD (official var used by server basic-auth) | |
| if (!env.OPENCODE_SERVER_PASSWORD && env.OPENCODE_PASSWORD) { | |
| env.OPENCODE_SERVER_PASSWORD = env.OPENCODE_PASSWORD; | |
| } | |
| if (!env.OPENCODE_SERVER_USERNAME) { | |
| env.OPENCODE_SERVER_USERNAME = env.OPENCODE_USERNAME || "opencode"; | |
| } | |
| // Ensure PATH always contains local bin and bun | |
| const prefix = "/home/node/app/node_modules/.bin:/usr/local/bun/bin"; | |
| env.PATH = env.PATH ? `${prefix}:${env.PATH}` : prefix; | |
| // Keep your concurrency limits | |
| env.OPENCODE_BACKGROUND_CONCURRENCY = env.OPENCODE_BACKGROUND_CONCURRENCY || "1"; | |
| env.OPENCODE_MODEL_CONCURRENCY = env.OPENCODE_MODEL_CONCURRENCY || "1"; | |
| return env; | |
| } | |
| function ensureUserDirs() { | |
| // Your requested project folders under /home/node | |
| for (const d of ["chat", "temp", "project"]) { | |
| fs.mkdirSync(path.join(HOME, d), { recursive: true }); | |
| } | |
| } | |
| let child = null; | |
| function startOpenCode() { | |
| ensureUserDirs(); | |
| fs.mkdirSync(WORKSPACE_DIR, { recursive: true }); | |
| const opencodeBin = resolveOpencodeBin(); | |
| const env = buildEnv(); | |
| console.log(`[start] HOME=${HOME}`); | |
| console.log(`[start] workspace=${WORKSPACE_DIR}`); | |
| console.log(`[start] opencode=${opencodeBin}`); | |
| console.log(`[start] git=${spawnSyncSafe("git", ["--version"])}`); | |
| console.log(`[start] curl=${spawnSyncSafe("curl", ["--version"])}`); | |
| console.log(`[start] rg=${spawnSyncSafe("rg", ["--version"])}`); | |
| console.log(`[start] jq=${spawnSyncSafe("jq", ["--version"])}`); | |
| console.log(`[start] python3=${spawnSyncSafe("python3", ["--version"])}`); | |
| console.log(`[start] bun=${spawnSyncSafe("bun", ["--version"])}`); | |
| if (!env.OPENCODE_SERVER_PASSWORD) { | |
| console.log("[start] WARNING: OPENCODE_SERVER_PASSWORD is NOT set (public access)."); | |
| } | |
| console.log(`[start] Starting OpenCode web on ${HOST}:${PORT}`); | |
| child = spawn(opencodeBin, ["web", "--port", PORT, "--hostname", HOST], { | |
| env, | |
| cwd: WORKSPACE_DIR, | |
| stdio: "inherit", | |
| }); | |
| child.on("close", (code) => { | |
| console.log(`[start] OpenCode exited with code ${code}. Restarting in 5 seconds...`); | |
| setTimeout(startOpenCode, 5000); | |
| }); | |
| } | |
| process.on("SIGTERM", () => child?.kill("SIGTERM")); | |
| process.on("SIGINT", () => child?.kill("SIGINT")); | |
| startOpenCode(); |