import { spawn, spawnSync } from "node:child_process"; import { randomUUID } from "node:crypto"; import { accessSync, constants as fsConstants, existsSync, realpathSync, statSync } from "node:fs"; import { mkdir, readdir, readFile, rm, rmdir, stat, writeFile } from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { createCodeAgentTraceRecorder, defaultCodeAgentTraceStore, runnerTraceFromSnapshot } from "./code-agent-trace-store.mjs"; import { CODE_AGENT_SESSION_LIFECYCLE_STATUSES, CODE_AGENT_SESSION_STATUS_ALIASES, codeAgentSessionLifecycleSummary, decorateCodeAgentSession } from "./code-agent-session-lifecycle.mjs"; export const CODEX_STDIO_PROVIDER = "codex-stdio"; export const CODEX_STDIO_BACKEND = "hwlab-cloud-api/codex-app-server-stdio"; export const CODEX_STDIO_RUNNER_KIND = "codex-app-server-stdio-runner"; export const CODEX_STDIO_SESSION_MODE = "codex-app-server-stdio-long-lived"; export const CODEX_STDIO_IMPLEMENTATION_TYPE = "repo-owned-codex-app-server-stdio-session"; export const CODEX_STDIO_CAPABILITY_LEVEL = "long-lived-codex-stdio-session"; export const CODEX_STDIO_SANDBOX = "workspace-write"; export const DEFAULT_CODEX_STDIO_IDLE_TIMEOUT_MS = 30 * 60 * 1000; export const DEFAULT_CODEX_STDIO_MAX_SESSIONS = 64; export const DEFAULT_CODEX_STDIO_COMMAND = "codex"; export const DEFAULT_CODEX_STDIO_PROBE_TTL_MS = 30 * 1000; const DEFAULT_CODEX_STDIO_TURN_ACTIVITY_TIMEOUT_MS = 10 * 60 * 1000; const DEFAULT_CODEX_STDIO_TURN_HARD_TIMEOUT_MS = 10 * 60 * 1000; export const CODEX_STDIO_SESSION_STATUSES = Object.freeze([ "creating", "ready", "busy", "idle", "timeout", "error", "canceled", "interrupted", "expired", "failed" ]); const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const CODEX_APP_SERVER_PROTOCOL = "codex-app-server-jsonrpc-stdio"; const CODEX_APP_SERVER_WIRE_API = "responses"; const CODEX_APP_SERVER_REQUIRED_METHODS = Object.freeze(["initialize", "thread/start", "thread/resume", "turn/start"]); const CODEX_STDIO_TOOL_OUTPUT_LIMIT = 4000; const CODEX_STDIO_SKILL_LIMIT = 40; const CODEX_STDIO_SKILL_REPLY_LIMIT = 20; const CODEX_STDIO_SKILL_SUMMARY_LIMIT = 180; const CODEX_STDIO_COMMAND_PROBE_TIMEOUT_MS = 3000; const CODEX_STDIO_COMMAND_PROBE_TRACE_ID = "trc_codex_stdio_command_probe"; const CODEX_STDIO_COMMAND_PROBE_CONVERSATION_ID = "cnv_codex_stdio_command_probe"; const CODEX_STDIO_FIRST_TOKEN_PROGRESS_MS = 15 * 1000; const CODEX_CHILD_STRIPPED_ENV_KEYS = Object.freeze([ "OPENAI_API_KEY", "CODEX_API_KEY", "HWLAB_CODE_AGENT_OPENAI_BASE_URL", "OPENAI_BASE_URL", "OPENAI_API_BASE", "OPENAI_RESPONSES_URL", "CODEX_OPENAI_BASE_URL", "CODEX_BASE_URL", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy" ]); const CODEX_CHILD_NO_PROXY_REQUIRED = Object.freeze([ "hyueapi.com", ".hyueapi.com", "hyui.com", ".hyui.com", "127.0.0.1", "localhost", "::1", "api.minimaxi.com", ".minimaxi.com" ]); const CODEX_STDIO_BOUNDARY_INSTRUCTIONS = [ "You are the HWLAB Cloud Workbench Code Agent.", "Use the provided workspace and repo-owned Codex stdio session only.", "Do not read or print secrets, tokens, kubeconfig files, DB URLs, private keys, or raw environment values.", "For hardware, gateway, box-simu, patch-panel, DAP, PWM, Keil, serial, and Windows skill requests, execute the requested work through the repo-owned Codex stdio session with the available tran wrapper, skill CLI, or project tool that actually reaches the target.", "For registered PC gateway Windows command or skill requests, use the preloaded tran wrapper: node /app/tools/hwlab-gateway-tran.mjs gws_DESKTOP-1MHOD9I:/f/work [options] -- . The locator before ':' is the gateway session and the path after ':' is the Windows workspace, with /f/work and f:/work both mapping to F:\\work.", "For Windows cmd, call tran as: node /app/tools/hwlab-gateway-tran.mjs gws_DESKTOP-1MHOD9I:/f/work cmd -- . For PowerShell, call tran as: node /app/tools/hwlab-gateway-tran.mjs gws_DESKTOP-1MHOD9I:/f/work ps --