[js_repl] paths for node module resolution can be specified for js_repl (#11944)

# External (non-OpenAI) Pull Request Requirements

In `js_repl` mode, module resolution currently starts from
`js_repl_kernel.js`, which is written to a per-kernel temp dir. This
effectively means that bare imports will not resolve.

This PR adds a new config option, `js_repl_node_module_dirs`, which is a
list of dirs that are used (in order) to resolve a bare import. If none
of those work, the current working directory of the thread is used.

For example:
```toml
js_repl_node_module_dirs = [
    "/path/to/node_modules/",
    "/other/path/to/node_modules/",
]
```
This commit is contained in:
aaronl-openai
2026-02-17 23:29:49 -08:00
committed by GitHub
parent 57f4e37539
commit f600453699
8 changed files with 461 additions and 45 deletions

View File

@@ -336,6 +336,10 @@ pub struct Config {
/// Optional absolute path to the Node runtime used by `js_repl`.
pub js_repl_node_path: Option<PathBuf>,
/// Ordered list of directories to search for Node modules in `js_repl`.
pub js_repl_node_module_dirs: Vec<PathBuf>,
/// Optional absolute path to patched zsh used by zsh-exec-bridge-backed shell execution.
pub zsh_path: Option<PathBuf>,
@@ -977,6 +981,10 @@ pub struct ConfigToml {
/// Optional absolute path to the Node runtime used by `js_repl`.
pub js_repl_node_path: Option<AbsolutePathBuf>,
/// Ordered list of directories to search for Node modules in `js_repl`.
pub js_repl_node_module_dirs: Option<Vec<AbsolutePathBuf>>,
/// Optional absolute path to patched zsh used by zsh-exec-bridge-backed shell execution.
pub zsh_path: Option<AbsolutePathBuf>,
@@ -1357,6 +1365,7 @@ pub struct ConfigOverrides {
pub config_profile: Option<String>,
pub codex_linux_sandbox_exe: Option<PathBuf>,
pub js_repl_node_path: Option<PathBuf>,
pub js_repl_node_module_dirs: Option<Vec<PathBuf>>,
pub zsh_path: Option<PathBuf>,
pub base_instructions: Option<String>,
pub developer_instructions: Option<String>,
@@ -1485,6 +1494,7 @@ impl Config {
config_profile: config_profile_key,
codex_linux_sandbox_exe,
js_repl_node_path: js_repl_node_path_override,
js_repl_node_module_dirs: js_repl_node_module_dirs_override,
zsh_path: zsh_path_override,
base_instructions,
developer_instructions,
@@ -1746,6 +1756,17 @@ impl Config {
let js_repl_node_path = js_repl_node_path_override
.or(config_profile.js_repl_node_path.map(Into::into))
.or(cfg.js_repl_node_path.map(Into::into));
let js_repl_node_module_dirs = js_repl_node_module_dirs_override
.or_else(|| {
config_profile
.js_repl_node_module_dirs
.map(|dirs| dirs.into_iter().map(Into::into).collect::<Vec<PathBuf>>())
})
.or_else(|| {
cfg.js_repl_node_module_dirs
.map(|dirs| dirs.into_iter().map(Into::into).collect::<Vec<PathBuf>>())
})
.unwrap_or_default();
let zsh_path = zsh_path_override
.or(config_profile.zsh_path.map(Into::into))
.or(cfg.zsh_path.map(Into::into));
@@ -1873,6 +1894,7 @@ impl Config {
file_opener: cfg.file_opener.unwrap_or(UriBasedFileOpener::VsCode),
codex_linux_sandbox_exe,
js_repl_node_path,
js_repl_node_module_dirs,
zsh_path,
hide_agent_reasoning: cfg.hide_agent_reasoning.unwrap_or(false),
@@ -4202,6 +4224,7 @@ model_verbosity = "high"
file_opener: UriBasedFileOpener::VsCode,
codex_linux_sandbox_exe: None,
js_repl_node_path: None,
js_repl_node_module_dirs: Vec::new(),
zsh_path: None,
hide_agent_reasoning: false,
show_raw_agent_reasoning: false,
@@ -4315,6 +4338,7 @@ model_verbosity = "high"
file_opener: UriBasedFileOpener::VsCode,
codex_linux_sandbox_exe: None,
js_repl_node_path: None,
js_repl_node_module_dirs: Vec::new(),
zsh_path: None,
hide_agent_reasoning: false,
show_raw_agent_reasoning: false,
@@ -4426,6 +4450,7 @@ model_verbosity = "high"
file_opener: UriBasedFileOpener::VsCode,
codex_linux_sandbox_exe: None,
js_repl_node_path: None,
js_repl_node_module_dirs: Vec::new(),
zsh_path: None,
hide_agent_reasoning: false,
show_raw_agent_reasoning: false,
@@ -4523,6 +4548,7 @@ model_verbosity = "high"
file_opener: UriBasedFileOpener::VsCode,
codex_linux_sandbox_exe: None,
js_repl_node_path: None,
js_repl_node_module_dirs: Vec::new(),
zsh_path: None,
hide_agent_reasoning: false,
show_raw_agent_reasoning: false,