import { serve } from "bun"; import { mkdirSync, existsSync, writeFileSync, rmSync, readdirSync, statSync, readFileSync } from "fs"; import { createHash } from "crypto"; import { homedir } from "os"; const CMD_PATH = "/usr/bin/cmd"; const PORT = parseInt(process.env.PORT || "9877"); const MAX_PROMPT_LENGTH = 50_000; const IMAGE_DIR = "/home/workspace/Projects/command-code-proxy/images"; const SESSION_BASE_DIR = "/tmp/cmd-sessions"; const CMD_TIMEOUT_MS = 120_000; // 120s timeout for cmd calls const SESSION_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours idle → expire (cmd .jsonl persists on disk) const MAX_SESSIONS = 50; const START_TIME = Date.now(); // --------------------------------------------------------------------------- // /goal command handling // --------------------------------------------------------------------------- const GOAL_DEFAULT_MAX_TURNS = 100; // matches Command Code /goal default const GOAL_MAX_TURNS_LIMIT = 500; // matches Command Code /goal ceiling const GOAL_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes for long-running goals const GOAL_STATUS_CLEAR_TIMEOUT_MS = 30_000; // quick for /goal status and /goal clear interface GoalCommand { type: "goal" | "goal-status" | "goal-clear" | "none"; objective?: string; } function parseGoalCommand(text: string): GoalCommand { const trimmed = text.trim(); const lower = trimmed.toLowerCase(); if (lower === "/goal status") return { type: "goal-status" }; if (lower === "/goal clear") return { type: "goal-clear" }; if (lower.startsWith("/goal ")) { const objective = trimmed.slice(6).trim(); return { type: "goal", objective: objective || undefined }; } return { type: "none" }; } function clampGoalMaxTurns(value: number): number { return Math.max(1, Math.min(value, GOAL_MAX_TURNS_LIMIT)); } // --------------------------------------------------------------------------- // Two-account rotation for 5-hour usage limit bypass // --------------------------------------------------------------------------- const ACCOUNTS = [ { name: "SillyHippy", apiKey: "YOUR_COMMAND_CODE_API_KEY_HERE", userId: "YOUR_USER_ID_HERE", }, { name: "iannazzijosephblgb", apiKey: "YOUR_COMMAND_CODE_API_KEY_HERE", userId: "YOUR_USER_ID_HERE", }, ]; let activeAccountIndex = 0; function switchAccount(): void { activeAccountIndex = (activeAccountIndex + 1) % ACCOUNTS.length; console.log(`[proxy] Switched to account: ${ACCOUNTS[activeAccountIndex].name}`); } function writeAuthJson(accountIndex: number): void { const account = ACCOUNTS[accountIndex]; const authData = { apiKey: account.apiKey, userId: account.userId, userName: account.name, keyName: "cli-manual-entry", authenticatedAt: new Date().toISOString(), }; const authPath = `${homedir()}/.commandcode/auth.json`; writeFileSync(authPath, JSON.stringify(authData, null, 2)); console.log(`[proxy] Wrote auth.json for account: ${account.name}`); } function isRateLimitError(stderr: string): boolean { const clean = stripAnsi(stderr).toLowerCase(); return ( (clean.includes("429") && clean.includes("usage limit")) || clean.includes("5-hour usage limit") || (clean.includes("you've reached your") && clean.includes("usage limit")) ); } if (!existsSync(IMAGE_DIR)) mkdirSync(IMAGE_DIR, { recursive: true }); if (!existsSync(SESSION_BASE_DIR)) mkdirSync(SESSION_BASE_DIR, { recursive: true }); // Initialize auth.json with first account on startup writeAuthJson(activeAccountIndex); // Sweep stale session dirs from previous runs (older than 1 hour) try { const now = Date.now(); for (const entry of readdirSync(SESSION_BASE_DIR)) { const dirPath = `${SESSION_BASE_DIR}/${entry}`; try { const st = statSync(dirPath); if (st.isDirectory() && now - st.mtimeMs > 60 * 60 * 1000) { rmSync(dirPath, { recursive: true, force: true }); } } catch {} } } catch {} // --------------------------------------------------------------------------- // Scan for .jsonl files from previous proxy runs (recovery) // --------------------------------------------------------------------------- interface RecoveredSession { id: string; dir: string; mtime: number; } function scanForJsonlSessions(): RecoveredSession[] { const recovered: RecoveredSession[] = []; try { for (const entry of readdirSync(SESSION_BASE_DIR)) { const dirPath = `${SESSION_BASE_DIR}/${entry}`; try { const st = statSync(dirPath); if (!st.isDirectory()) continue; // Check for .jsonl files in this directory const files = readdirSync(dirPath); const jsonlFile = files.find(f => f.endsWith(".jsonl")); if (jsonlFile) { recovered.push({ id: entry, dir: dirPath, mtime: st.mtimeMs, }); } } catch {} } } catch {} return recovered; } // Initialize sessions from .jsonl files (proxy restart recovery) function recoverSessionsFromJsonl(): void { const recovered = scanForJsonlSessions(); for (const session of recovered) { const existing = sessions.get(session.id); if (!existing) { const state: SessionState = { dir: session.dir, lastActivity: session.mtime, turnCount: 1, // Assume at least 1 turn if .jsonl exists }; sessions.set(session.id, state); console.log(`[proxy] Recovered session ${session.id} from .jsonl (dir: ${session.dir})`); } } } recoverSessionsFromJsonl(); interface ChatMsg { role: string; content: string | Array<{ type: string; text?: string; image_url?: { url: string } }> | null; } interface ChatReq { model: string; messages: ChatMsg[]; stream?: boolean; max_tokens?: number; max_turns?: number; // client-controlled turn budget cmd_timeout?: number; // client-controlled cmd timeout in ms } // --------------------------------------------------------------------------- // Model list: Go plan only — no Claude, no GPT, no Google // --------------------------------------------------------------------------- const GO_PLAN_MODELS = [ { id: "moonshotai/Kimi-K2.7-Code", owned_by: "moonshotai" }, { id: "moonshotai/Kimi-K2.7-Code-Highspeed", owned_by: "moonshotai" }, { id: "moonshotai/Kimi-K2.6", owned_by: "moonshotai" }, { id: "moonshotai/Kimi-K2.5", owned_by: "moonshotai" }, { id: "deepseek/deepseek-v4-pro", owned_by: "deepseek" }, { id: "deepseek/deepseek-v4-flash", owned_by: "deepseek" }, { id: "Qwen/Qwen3.7-Max", owned_by: "qwen" }, { id: "Qwen/Qwen3.7-Plus", owned_by: "qwen" }, { id: "Qwen/Qwen3.6-Plus", owned_by: "qwen" }, { id: "MiniMaxAI/MiniMax-M2.7", owned_by: "minimax" }, { id: "MiniMaxAI/MiniMax-M2.5", owned_by: "minimax" }, { id: "zai-org/GLM-5.2", owned_by: "zhipu" }, { id: "zai-org/GLM-5.2-Fast", owned_by: "zhipu" }, { id: "zai-org/GLM-5.1", owned_by: "zhipu" }, { id: "zai-org/GLM-5", owned_by: "zhipu" }, { id: "stepfun/Step-3.7-Flash", owned_by: "stepfun" }, { id: "stepfun/Step-3.5-Flash", owned_by: "stepfun" }, ]; // Short-name aliases → full model ID (for clients that send short names) const MODEL_ALIASES: Record = { "deepseek-v4-pro": "deepseek/deepseek-v4-pro", "deepseek-v4-flash": "deepseek/deepseek-v4-flash", "kimi-k2.7-code": "moonshotai/Kimi-K2.7-Code", "kimi-k2.7-code-highspeed": "moonshotai/Kimi-K2.7-Code-Highspeed", "kimi-k2.7-hs": "moonshotai/Kimi-K2.7-Code-Highspeed", "kimi-k2.6": "moonshotai/Kimi-K2.6", "kimi-k2.5": "moonshotai/Kimi-K2.5", "qwen3.7-max": "Qwen/Qwen3.7-Max", "qwen3.7-plus": "Qwen/Qwen3.7-Plus", "qwen3.6-plus": "Qwen/Qwen3.6-Plus", "minimax-m2.7": "MiniMaxAI/MiniMax-M2.7", "minimax-m2.5": "MiniMaxAI/MiniMax-M2.5", "glm-5.2": "zai-org/GLM-5.2", "glm-5.2-fast": "zai-org/GLM-5.2-Fast", "glm-5.1": "zai-org/GLM-5.1", "glm-5": "zai-org/GLM-5", "step-3.7-flash": "stepfun/Step-3.7-Flash", "step-3.5-flash": "stepfun/Step-3.5-Flash", }; function mapModel(name: string): string { return MODEL_ALIASES[name.toLowerCase()] || name; } // --------------------------------------------------------------------------- // Content extraction // --------------------------------------------------------------------------- function saveBase64Image(dataUrl: string, id: string): string { const match = dataUrl.match(/^data:image\/(\w+);base64,(.+)$/); if (!match) return ""; const [, ext, base64] = match; const buffer = Buffer.from(base64, "base64"); const filename = `${IMAGE_DIR}/img_${id}.${ext}`; writeFileSync(filename, buffer); return filename; } function contentToText(content: ChatMsg["content"]): string { if (typeof content === "string") return content; if (!Array.isArray(content)) return ""; const parts: string[] = []; let imgCounter = 0; for (const item of content) { if (item.type === "text" && item.text) { parts.push(item.text); } else if (item.type === "image_url" && item.image_url?.url) { const url = item.image_url.url; if (url.startsWith("data:")) { const path = saveBase64Image(url, `${Date.now()}_${imgCounter++}`); if (path) parts.push(`Use read_file to examine this image file and describe any visible text/content: ${path}`); } else { parts.push(`Attached image URL: ${url}`); } } } return parts.join("\n"); } function truncateMessage(text: string, maxLen: number): string { if (text.length <= maxLen) return text; return text.slice(0, maxLen - 15) + "... [truncated]"; } function stripAnsi(str: string): string { return str.replace(/\x1b\[[0-9;]*m/g, "").replace(/\x1b\[[0-9;]*[A-Za-z]/g, ""); } // --------------------------------------------------------------------------- // Session management — per-conversation temp dirs + cmd --resume // --------------------------------------------------------------------------- interface SessionState { dir: string; lastActivity: number; turnCount: number; cmdSessionId: string | null; // UUID from `cmd --verbose` stderr — the authoritative session handle } const sessions = new Map(); const sessionLocks = new Map>(); function sessionIdFor(messages: ChatMsg[]): string { const seed = messages .filter((msg) => msg.role === "user") .slice(0, 1) .map((msg) => contentToText(msg.content).trim()) .join("\n---\n") || "empty-session"; return createHash("sha256").update(seed).digest("hex").slice(0, 16); } function cleanupSessions(): void { const now = Date.now(); for (const [id, state] of sessions) { if (now - state.lastActivity > SESSION_TTL_MS) { try { rmSync(state.dir, { recursive: true, force: true }); } catch {} sessions.delete(id); } } if (sessions.size > MAX_SESSIONS) { const sorted = [...sessions.entries()].sort((a, b) => a[1].lastActivity - b[1].lastActivity); const toRemove = sorted.slice(0, sessions.size - MAX_SESSIONS); for (const [id, state] of toRemove) { try { rmSync(state.dir, { recursive: true, force: true }); } catch {} sessions.delete(id); } } } async function withSessionLock(sessionId: string, fn: () => Promise): Promise { const prev = sessionLocks.get(sessionId) ?? Promise.resolve(); let release: () => void; const gate = new Promise((r) => { release = r; }); sessionLocks.set(sessionId, gate); await prev; try { return await fn(); } finally { release!(); } } function recoverCmdSessionId(dir: string): string | null { // cmd maps cwd → project dir by replacing / with -, then stripping leading - const projectDirName = dir.replace(/\//g, "-").replace(/^-+/, ""); const projectPath = `${homedir()}/.commandcode/projects/${projectDirName}`; if (!existsSync(projectPath)) return null; try { const files = readdirSync(projectPath) .filter(f => f.endsWith(".jsonl")) .map(f => ({ name: f, mtime: statSync(`${projectPath}/${f}`).mtimeMs })) .sort((a, b) => b.mtime - a.mtime); if (files.length === 0) return null; const recovered = files[0].name.replace(".jsonl", ""); console.log(`[proxy] Recovered cmd session ID from disk: ${recovered}`); return recovered; } catch { return null; } } function getOrCreateSession(sessionId: string): SessionState { let state = sessions.get(sessionId); if (!state) { const dir = `${SESSION_BASE_DIR}/${sessionId}`; mkdirSync(dir, { recursive: true }); state = { dir, lastActivity: Date.now(), turnCount: 0, cmdSessionId: null }; // Try to recover a prior cmd session ID from .jsonl files on disk const recovered = recoverCmdSessionId(dir); if (recovered) { state.cmdSessionId = recovered; state.turnCount = 1; // assume prior conversation exists } sessions.set(sessionId, state); } return state; } // --------------------------------------------------------------------------- // Extract only the latest user message (+ system prompt for fresh sessions) // --------------------------------------------------------------------------- function isTitleGenerationCall(systemText: string): boolean { return systemText.includes("Generate a short, descriptive title"); } function extractLatestUserMessage(messages: ChatMsg[]): { userText: string; systemText: string; isTitleGen: boolean } { let userText = ""; let systemText = ""; for (let i = messages.length - 1; i >= 0; i--) { if (messages[i].role === "user") { userText = contentToText(messages[i].content).trim(); break; } } for (const msg of messages) { if (msg.role === "system") { systemText = contentToText(msg.content).trim(); break; } } if (!userText) userText = "Hello"; return { userText: truncateMessage(userText, MAX_PROMPT_LENGTH), systemText, isTitleGen: isTitleGenerationCall(systemText) }; } // --------------------------------------------------------------------------- // Core: run cmd with --resume for multi-turn sessions + account rotation // --------------------------------------------------------------------------- async function runCommandCode( prompt: string, options: { model?: string; maxTurns?: number; cwd: string; cmdSessionId: string | null; timeout?: number } ): Promise<{ response: string; cmdSessionId: string | null }> { const maxTurns = options.maxTurns ?? 5; const timeout = options.timeout ?? CMD_TIMEOUT_MS; // Try with current account, then rotate if rate limited for (let attempt = 0; attempt < ACCOUNTS.length; attempt++) { // Write auth.json for the active account writeAuthJson(activeAccountIndex); const args = [ "-p", prompt, "--verbose", // ← prints `session: ` to stderr for --resume chaining "--skip-onboarding", "--trust", "--yolo", "--max-turns", String(maxTurns), "--add-dir", "/home/workspace", "--add-dir", "/home/.z", "--add-dir", IMAGE_DIR, ]; // Use --resume for explicit session resumption (instead of --continue which picks most-recent .jsonl) if (options.cmdSessionId) { args.push("--resume", options.cmdSessionId); } if (options.model && options.model !== "command-code" && options.model !== "taste-1") { args.push("-m", options.model); } const proc = Bun.spawn([CMD_PATH, ...args], { cwd: options.cwd, stdout: "pipe", stderr: "pipe", env: { ...process.env }, }); const timer = setTimeout(() => { proc.kill("SIGTERM"); }, timeout); const stdout = await new Response(proc.stdout).text(); const stderr = await new Response(proc.stderr).text(); await proc.exited; clearTimeout(timer); const clean = stripAnsi(stdout).trim(); // Parse session ID from --verbose stderr: "session: " const sessionMatch = stderr.match(/^session:\s*([a-f0-9-]+)/m); const newSessionId = sessionMatch ? sessionMatch[1] : null; if (newSessionId) { console.log(`[proxy] Captured cmd session ID: ${newSessionId}`); } // Check for rate limit error — switch account and retry if (isRateLimitError(stderr)) { console.log(`[proxy] Rate limit hit on account ${ACCOUNTS[activeAccountIndex].name}, switching...`); switchAccount(); continue; // Try next account } // Exit code 8 = max-turns cap hit. Return the response anyway. if (proc.exitCode !== 0 && proc.exitCode !== 8 && !clean) { throw new Error(stripAnsi(stderr).trim() || `cmd exited with code ${proc.exitCode}`); } return { response: clean, cmdSessionId: newSessionId }; } throw new Error("All accounts rate limited"); } // --------------------------------------------------------------------------- // HTTP server // --------------------------------------------------------------------------- const server = serve({ port: PORT, hostname: "0.0.0.0", async fetch(req) { const url = new URL(req.url); // CORS preflight if (req.method === "OPTIONS") { return new Response(null, { headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization", }, }); } // Health if (url.pathname === "/health" || url.pathname === "/") { return Response.json({ status: "ok", service: "command-code-proxy", port: PORT, plan: "go", uptime_s: Math.floor((Date.now() - START_TIME) / 1000), active_sessions: sessions.size, cmd_version: "0.40.17", mode: "resume-jsonl", }); } // Sessions debug endpoint if (url.pathname === "/sessions") { const list = [...sessions.entries()].map(([id, s]) => ({ id, dir: s.dir, turns: s.turnCount, cmd_session_id: s.cmdSessionId, idle_s: Math.floor((Date.now() - s.lastActivity) / 1000), })); return Response.json({ count: list.length, ttl_ms: SESSION_TTL_MS, max: MAX_SESSIONS, sessions: list }); } // Model list if (url.pathname === "/v1/models") { return Response.json({ object: "list", data: GO_PLAN_MODELS.map((m) => ({ ...m, object: "model", created: Math.floor(Date.now() / 1000), })), }); } // Chat completions if (url.pathname === "/v1/chat/completions" && req.method === "POST") { try { const body: ChatReq = await req.json(); const resolvedModel = mapModel(body.model || "deepseek-v4-flash"); console.log(`[proxy] model=${resolvedModel} msgs=${body.messages.length}`); cleanupSessions(); const sessionId = sessionIdFor(body.messages); const { userText, systemText, isTitleGen } = extractLatestUserMessage(body.messages); // Title-generation calls get a separate temp dir so they don't pollute the main session's project dir const effectiveSessionId = isTitleGen ? `titlegen-${sessionId}` : sessionId; const titleGenDir = `${SESSION_BASE_DIR}/titlegen`; if (isTitleGen && !existsSync(titleGenDir)) mkdirSync(titleGenDir, { recursive: true }); const response = await withSessionLock(effectiveSessionId, async () => { const state = getOrCreateSession(effectiveSessionId); // Title-gen calls always start fresh (no --resume) const useResume = !isTitleGen && state.cmdSessionId !== null; // For fresh sessions, prepend system prompt if present let prompt = userText; if (!useResume && systemText) { prompt = `[System context: ${truncateMessage(systemText, 5000)}]\n\n${userText}`; } // Determine /goal-specific budget and timeout const goalCmd = parseGoalCommand(prompt); let requestMaxTurns = 5; let requestTimeout = CMD_TIMEOUT_MS; if (goalCmd.type === "goal") { requestMaxTurns = clampGoalMaxTurns(body.max_turns ?? GOAL_DEFAULT_MAX_TURNS); requestTimeout = body.cmd_timeout ?? GOAL_TIMEOUT_MS; console.log(`[proxy] /goal objective="${goalCmd.objective}", max_turns=${requestMaxTurns}, timeout=${requestTimeout}ms`); } else if (goalCmd.type === "goal-status" || goalCmd.type === "goal-clear") { requestTimeout = body.cmd_timeout ?? GOAL_STATUS_CLEAR_TIMEOUT_MS; console.log(`[proxy] /goal ${goalCmd.type.replace("goal-", "")}, timeout=${requestTimeout}ms`); } else if (body.max_turns) { requestMaxTurns = Math.max(1, Math.min(body.max_turns, GOAL_MAX_TURNS_LIMIT)); requestTimeout = body.cmd_timeout ?? CMD_TIMEOUT_MS; console.log(`[proxy] custom max_turns=${requestMaxTurns}, timeout=${requestTimeout}ms`); } console.log(`[proxy] session=${effectiveSessionId} turn=${state.turnCount + 1} resume=${useResume} cmdSid=${state.cmdSessionId ?? "none"} cwd=${state.dir}${isTitleGen ? " [titlegen]" : ""}`); try { const result = await runCommandCode(prompt, { model: resolvedModel, maxTurns: requestMaxTurns, timeout: requestTimeout, cwd: state.dir, cmdSessionId: useResume ? state.cmdSessionId : null, }); // Capture the cmd session ID from --verbose stderr if (result.cmdSessionId) { state.cmdSessionId = result.cmdSessionId; } state.turnCount++; state.lastActivity = Date.now(); return result.response; } catch (err: any) { // If --resume failed, try fresh (but keep the .jsonl on disk — don't delete) if (useResume) { console.log(`[proxy] --resume failed (${err.message}), retrying fresh`); state.cmdSessionId = null; state.turnCount = 0; const freshPrompt = systemText ? `[System context: ${truncateMessage(systemText, 5000)}]\n\n${userText}` : userText; const freshGoalCmd = parseGoalCommand(freshPrompt); let freshMaxTurns = 5; let freshTimeout = CMD_TIMEOUT_MS; if (freshGoalCmd.type === "goal") { freshMaxTurns = clampGoalMaxTurns(body.max_turns ?? GOAL_DEFAULT_MAX_TURNS); freshTimeout = body.cmd_timeout ?? GOAL_TIMEOUT_MS; } else if (freshGoalCmd.type === "goal-status" || freshGoalCmd.type === "goal-clear") { freshTimeout = body.cmd_timeout ?? GOAL_STATUS_CLEAR_TIMEOUT_MS; } else if (body.max_turns) { freshMaxTurns = Math.max(1, Math.min(body.max_turns, GOAL_MAX_TURNS_LIMIT)); freshTimeout = body.cmd_timeout ?? CMD_TIMEOUT_MS; } const result = await runCommandCode(freshPrompt, { model: resolvedModel, maxTurns: freshMaxTurns, timeout: freshTimeout, cwd: state.dir, cmdSessionId: null, }); if (result.cmdSessionId) { state.cmdSessionId = result.cmdSessionId; } state.turnCount = 1; state.lastActivity = Date.now(); return result.response; } throw err; } }); const id = `chatcmpl-${crypto.randomUUID()}`; if (body.stream) { const encoder = new TextEncoder(); const stream = new ReadableStream({ start(controller) { controller.enqueue(encoder.encode( `data: ${JSON.stringify({ id, object: "chat.completion.chunk", created: Math.floor(Date.now() / 1000), model: resolvedModel, choices: [{ index: 0, delta: { content: response }, finish_reason: null }] })}\n\n` )); controller.enqueue(encoder.encode( `data: ${JSON.stringify({ id, object: "chat.completion.chunk", created: Math.floor(Date.now() / 1000), model: resolvedModel, choices: [{ index: 0, delta: {}, finish_reason: "stop" }] })}\n\ndata: [DONE]\n\n` )); controller.close(); }, }); return new Response(stream, { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Connection": "keep-alive", "Access-Control-Allow-Origin": "*", }, }); } return Response.json( { id, object: "chat.completion", created: Math.floor(Date.now() / 1000), model: resolvedModel, choices: [{ index: 0, message: { role: "assistant", content: response }, finish_reason: "stop" }], usage: { prompt_tokens: Math.round(userText.length / 4), completion_tokens: Math.round(response.length / 4), total_tokens: Math.round((userText.length + response.length) / 4), }, }, { headers: { "Access-Control-Allow-Origin": "*" } } ); } catch (err: any) { console.error(`[proxy] Error: ${err.message}`); return Response.json( { error: { message: err.message, type: "server_error" } }, { status: 500, headers: { "Access-Control-Allow-Origin": "*" } } ); } } return Response.json({ error: "Not found" }, { status: 404 }); }, }); console.log(`Command Code proxy (Go plan, resume-jsonl mode) running on http://0.0.0.0:${PORT}`);