diff --git a/.codespellrc b/.codespellrc
index a3f0cd501..ec1f02408 100644
--- a/.codespellrc
+++ b/.codespellrc
@@ -1,6 +1,6 @@
[codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
-skip = .git*,vendor,*-lock.yaml,*.lock,.codespellrc,*test.ts,*.jsonl,frame*.txt,*.snap,*.snap.new
+skip = .git*,vendor,*-lock.yaml,*.lock,.codespellrc,*test.ts,*.jsonl,frame*.txt,*.snap,*.snap.new,*meriyah.umd.min.js
check-hidden = true
ignore-regex = ^\s*"image/\S+": ".*|\b(afterAll)\b
ignore-words-list = ratatui,ser,iTerm,iterm2,iterm
diff --git a/NOTICE b/NOTICE
index 2805899d5..2a64a45aa 100644
--- a/NOTICE
+++ b/NOTICE
@@ -4,3 +4,6 @@ Copyright 2025 OpenAI
This project includes code derived from [Ratatui](https://github.com/ratatui/ratatui), licensed under the MIT license.
Copyright (c) 2016-2022 Florian Dehau
Copyright (c) 2023-2025 The Ratatui Developers
+
+This project includes Meriyah parser assets from [meriyah](https://github.com/meriyah/meriyah), licensed under the ISC license.
+Copyright (c) 2019 and later, KFlash and others.
diff --git a/codex-rs/BUILD.bazel b/codex-rs/BUILD.bazel
index 8b1378917..47324dbdc 100644
--- a/codex-rs/BUILD.bazel
+++ b/codex-rs/BUILD.bazel
@@ -1 +1,3 @@
-
+exports_files([
+ "node-version.txt",
+])
diff --git a/codex-rs/core/BUILD.bazel b/codex-rs/core/BUILD.bazel
index 2ef299c5c..5269148bc 100644
--- a/codex-rs/core/BUILD.bazel
+++ b/codex-rs/core/BUILD.bazel
@@ -11,7 +11,9 @@ codex_rust_crate(
"Cargo.toml",
],
allow_empty = True,
- ),
+ ) + [
+ "//codex-rs:node-version.txt",
+ ],
integration_compile_data_extra = [
"//codex-rs/apply-patch:apply_patch_tool_instructions.md",
"models.json",
diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json
index ff5cbcdf7..5fb67c22b 100644
--- a/codex-rs/core/config.schema.json
+++ b/codex-rs/core/config.schema.json
@@ -221,6 +221,9 @@
"include_apply_patch_tool": {
"type": "boolean"
},
+ "js_repl": {
+ "type": "boolean"
+ },
"memory_tool": {
"type": "boolean"
},
@@ -290,6 +293,9 @@
"include_apply_patch_tool": {
"type": "boolean"
},
+ "js_repl_node_path": {
+ "$ref": "#/definitions/AbsolutePathBuf"
+ },
"model": {
"type": "string"
},
@@ -1299,6 +1305,9 @@
"include_apply_patch_tool": {
"type": "boolean"
},
+ "js_repl": {
+ "type": "boolean"
+ },
"memory_tool": {
"type": "boolean"
},
@@ -1421,6 +1430,14 @@
"description": "System instructions.",
"type": "string"
},
+ "js_repl_node_path": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/AbsolutePathBuf"
+ }
+ ],
+ "description": "Optional absolute path to the Node runtime used by `js_repl`."
+ },
"log_dir": {
"allOf": [
{
diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs
index 2b9b04e2e..4a6c8cff1 100644
--- a/codex-rs/core/src/codex.rs
+++ b/codex-rs/core/src/codex.rs
@@ -220,6 +220,7 @@ use crate::tasks::SessionTask;
use crate::tasks::SessionTaskContext;
use crate::tools::ToolRouter;
use crate::tools::context::SharedTurnDiffTracker;
+use crate::tools::js_repl::JsReplHandle;
use crate::tools::parallel::ToolCallRuntime;
use crate::tools::sandboxing::ApprovalStore;
use crate::tools::spec::ToolsConfig;
@@ -510,6 +511,7 @@ pub(crate) struct Session {
pending_mcp_server_refresh_config: Mutex