MCPcopy Create free account
hub / github.com/OpenHands/OpenHands / buildConfigFromPorts

Function buildConfigFromPorts

scripts/dev-safe.mjs:611–677  ·  view source on GitHub ↗

* Internal helper to build config from already-resolved ports. * @param {{backendPort: number, vscodePort: number}} ports * @param {string} cwd * @param {Record } env * @returns {SafeDevConfig}

(ports, cwd, env)

Source from the content-addressed store, hash-verified

609 * @returns {SafeDevConfig}
610 */
611function buildConfigFromPorts(ports, cwd, env) {
612 const { backendPort, vscodePort } = ports;
613 const stateDir = path.resolve(
614 cwd,
615 env.OH_CANVAS_SAFE_STATE_DIR ||
616 path.join(homedir(), ".openhands", "agent-canvas"),
617 );
618 const conversationsPath = path.join(stateDir, "dev_conversations");
619 const workspacesPath = path.join(stateDir, "workspaces");
620 // Use provided secret key, or read/generate one persisted to
621 // ~/.openhands/agent-canvas/secret-key.txt. Persisting ensures dev mode
622 // and Docker mode share the same encryption key when they mount the same
623 // ~/.openhands directory (docker/entrypoint.sh reads/writes the same file).
624 const secretKeyPath = env.OH_SECRET_KEY_PATH || DEFAULT_SECRET_KEY_PATH;
625 const secretKey =
626 env.OH_SECRET_KEY || getOrCreatePersistedApiKey(secretKeyPath, "secret");
627 // Use the user-provided LOCAL_BACKEND_API_KEY or fall back to a key
628 // persisted to ~/.openhands/agent-canvas/api-key.txt. Persisting on disk
629 // keeps the agent-server, the Vite-baked VITE_SESSION_API_KEY, and any
630 // `openhands-backends` localStorage entries the frontend has cached all
631 // pointing at the same value across dev restarts.
632 //
633 // LOCAL_BACKEND_API_KEY is the single user-facing env var for the API key.
634 // OH_SESSION_API_KEY_PATH overrides the persisted file path (used by tests).
635 const persistedKeyPath = env.OH_SESSION_API_KEY_PATH || DEFAULT_API_KEY_PATH;
636 const sessionApiKey =
637 env.LOCAL_BACKEND_API_KEY ||
638 getOrCreatePersistedApiKeyFile(persistedKeyPath);
639
640 // Host directory containing the legacy canvas_ui Python module. Persisted
641 // conversations created before the client_tools migration still reference
642 // its module qualname, so the agent-server can import it when resuming them.
643 const canvasToolsDir = fileURLToPath(new URL("../tools", import.meta.url));
644
645 return {
646 cwd,
647 backendPort,
648 vscodePort,
649 stateDir,
650 // tmux socket directory. Defaults to <stateDir>/tmux (under
651 // ~/.openhands/agent-canvas), matching where the rest of dev state lives
652 // and persisting across restarts.
653 //
654 // Do NOT use os.tmpdir() here: on macOS it resolves to the per-user
655 // $TMPDIR (/var/folders/.../T), which the OS periodically reaps
656 // (com.apple.bsd.dirhelper deletes entries untouched for a few days).
657 // Reaping deletes the live tmux socket while the server process keeps
658 // running, orphaning it — every later new-window then fails with
659 // "error connecting to .../openhands (No such file or directory)".
660 //
661 // The only hosts where <stateDir>/tmux can't hold the socket are those
662 // whose $HOME is a network/overlay mount without Unix-domain-socket
663 // support (some devcontainers, NFS/CIFS homes). Those rare cases can point
664 // tmux at a local, socket-capable path with the standard TMUX_TMPDIR env
665 // var (e.g. TMUX_TMPDIR=/tmp), which we honor and pass through below.
666 tmuxTmpDir: env.TMUX_TMPDIR || path.join(stateDir, "tmux"),
667 conversationsPath,
668 workspacesPath,

Callers 2

buildSafeDevConfigFunction · 0.85
buildSafeDevConfigAsyncFunction · 0.85

Calls 2

Tested by

no test coverage detected