feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
use crate::app_event::AppEvent;
|
|
|
|
|
|
use crate::chatwidget::ChatWidget;
|
|
|
|
|
|
use crate::git_warning_screen::GitWarningOutcome;
|
|
|
|
|
|
use crate::git_warning_screen::GitWarningScreen;
|
2025-04-25 12:01:52 -07:00
|
|
|
|
use crate::scroll_event_helper::ScrollEventHelper;
|
feat: add support for commands in the Rust TUI (#935)
Introduces support for slash commands like in the TypeScript CLI. We do
not support the full set of commands yet, but the core abstraction is
there now.
In particular, we have a `SlashCommand` enum and due to thoughtful use
of the [strum](https://crates.io/crates/strum) crate, it requires
minimal boilerplate to add a new command to the list.
The key new piece of UI is `CommandPopup`, though the keyboard events
are still handled by `ChatComposer`. The behavior is roughly as follows:
* if the first character in the composer is `/`, the command popup is
displayed (if you really want to send a message to Codex that starts
with a `/`, simply put a space before the `/`)
* while the popup is displayed, up/down can be used to change the
selection of the popup
* if there is a selection, hitting tab completes the command, but does
not send it
* if there is a selection, hitting enter sends the command
* if the prefix of the composer matches a command, the command will be
visible in the popup so the user can see the description (commands could
take arguments, so additional text may appear after the command name
itself)
https://github.com/user-attachments/assets/39c3e6ee-eeb7-4ef7-a911-466d8184975f
Incidentally, Codex wrote almost all the code for this PR!
2025-05-14 12:55:49 -07:00
|
|
|
|
use crate::slash_command::SlashCommand;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
use crate::tui;
|
2025-04-27 21:47:50 -07:00
|
|
|
|
use codex_core::config::Config;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
use codex_core::protocol::Event;
|
|
|
|
|
|
use codex_core::protocol::Op;
|
|
|
|
|
|
use color_eyre::eyre::Result;
|
|
|
|
|
|
use crossterm::event::KeyCode;
|
|
|
|
|
|
use crossterm::event::KeyEvent;
|
2025-04-25 12:01:52 -07:00
|
|
|
|
use crossterm::event::MouseEvent;
|
|
|
|
|
|
use crossterm::event::MouseEventKind;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
use std::sync::mpsc::Receiver;
|
|
|
|
|
|
use std::sync::mpsc::Sender;
|
2025-05-07 08:37:48 -07:00
|
|
|
|
use std::sync::mpsc::channel;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
|
|
|
|
|
|
/// Top‑level application state – which full‑screen view is currently active.
|
|
|
|
|
|
enum AppState {
|
|
|
|
|
|
/// The main chat UI is visible.
|
|
|
|
|
|
Chat,
|
|
|
|
|
|
/// The start‑up warning that recommends running codex inside a Git repo.
|
|
|
|
|
|
GitWarning { screen: GitWarningScreen },
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) struct App<'a> {
|
|
|
|
|
|
app_event_tx: Sender<AppEvent>,
|
|
|
|
|
|
app_event_rx: Receiver<AppEvent>,
|
|
|
|
|
|
chat_widget: ChatWidget<'a>,
|
|
|
|
|
|
app_state: AppState,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl App<'_> {
|
|
|
|
|
|
pub(crate) fn new(
|
2025-04-27 21:47:50 -07:00
|
|
|
|
config: Config,
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
initial_prompt: Option<String>,
|
|
|
|
|
|
show_git_warning: bool,
|
|
|
|
|
|
initial_images: Vec<std::path::PathBuf>,
|
|
|
|
|
|
) -> Self {
|
|
|
|
|
|
let (app_event_tx, app_event_rx) = channel();
|
2025-04-25 12:01:52 -07:00
|
|
|
|
let scroll_event_helper = ScrollEventHelper::new(app_event_tx.clone());
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
|
|
|
|
|
|
// Spawn a dedicated thread for reading the crossterm event loop and
|
|
|
|
|
|
// re-publishing the events as AppEvents, as appropriate.
|
|
|
|
|
|
{
|
|
|
|
|
|
let app_event_tx = app_event_tx.clone();
|
|
|
|
|
|
std::thread::spawn(move || {
|
|
|
|
|
|
while let Ok(event) = crossterm::event::read() {
|
2025-05-09 11:33:46 -07:00
|
|
|
|
match event {
|
|
|
|
|
|
crossterm::event::Event::Key(key_event) => {
|
|
|
|
|
|
if let Err(e) = app_event_tx.send(AppEvent::KeyEvent(key_event)) {
|
|
|
|
|
|
tracing::error!("failed to send key event: {e}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
crossterm::event::Event::Resize(_, _) => {
|
|
|
|
|
|
if let Err(e) = app_event_tx.send(AppEvent::Redraw) {
|
|
|
|
|
|
tracing::error!("failed to send resize event: {e}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-25 12:01:52 -07:00
|
|
|
|
crossterm::event::Event::Mouse(MouseEvent {
|
|
|
|
|
|
kind: MouseEventKind::ScrollUp,
|
|
|
|
|
|
..
|
|
|
|
|
|
}) => {
|
|
|
|
|
|
scroll_event_helper.scroll_up();
|
|
|
|
|
|
}
|
|
|
|
|
|
crossterm::event::Event::Mouse(MouseEvent {
|
|
|
|
|
|
kind: MouseEventKind::ScrollDown,
|
|
|
|
|
|
..
|
|
|
|
|
|
}) => {
|
|
|
|
|
|
scroll_event_helper.scroll_down();
|
2025-05-09 11:33:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
crossterm::event::Event::Paste(pasted) => {
|
|
|
|
|
|
use crossterm::event::KeyModifiers;
|
|
|
|
|
|
|
|
|
|
|
|
for ch in pasted.chars() {
|
|
|
|
|
|
let key_event = match ch {
|
|
|
|
|
|
'\n' | '\r' => {
|
|
|
|
|
|
// Represent newline as <Shift+Enter> so that the bottom
|
|
|
|
|
|
// pane treats it as a literal newline instead of a submit
|
|
|
|
|
|
// action (submission is only triggered on Enter *without*
|
|
|
|
|
|
// any modifiers).
|
|
|
|
|
|
KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT)
|
|
|
|
|
|
}
|
|
|
|
|
|
_ => KeyEvent::new(KeyCode::Char(ch), KeyModifiers::empty()),
|
|
|
|
|
|
};
|
|
|
|
|
|
if let Err(e) = app_event_tx.send(AppEvent::KeyEvent(key_event)) {
|
|
|
|
|
|
tracing::error!("failed to send pasted key event: {e}");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-25 12:01:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
_ => {
|
2025-05-09 11:33:46 -07:00
|
|
|
|
// Ignore any other events.
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let chat_widget = ChatWidget::new(
|
2025-04-27 21:47:50 -07:00
|
|
|
|
config,
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
app_event_tx.clone(),
|
|
|
|
|
|
initial_prompt.clone(),
|
|
|
|
|
|
initial_images,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
let app_state = if show_git_warning {
|
|
|
|
|
|
AppState::GitWarning {
|
|
|
|
|
|
screen: GitWarningScreen::new(),
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
AppState::Chat
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Self {
|
|
|
|
|
|
app_event_tx,
|
|
|
|
|
|
app_event_rx,
|
|
|
|
|
|
chat_widget,
|
|
|
|
|
|
app_state,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Clone of the internal event sender so external tasks (e.g. log bridge)
|
|
|
|
|
|
/// can inject `AppEvent`s.
|
|
|
|
|
|
pub fn event_sender(&self) -> Sender<AppEvent> {
|
|
|
|
|
|
self.app_event_tx.clone()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) fn run(&mut self, terminal: &mut tui::Tui) -> Result<()> {
|
|
|
|
|
|
// Insert an event to trigger the first render.
|
|
|
|
|
|
let app_event_tx = self.app_event_tx.clone();
|
2025-05-08 09:46:18 -07:00
|
|
|
|
app_event_tx.send(AppEvent::Redraw)?;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
|
|
|
|
|
|
while let Ok(event) = self.app_event_rx.recv() {
|
|
|
|
|
|
match event {
|
|
|
|
|
|
AppEvent::Redraw => {
|
|
|
|
|
|
self.draw_next_frame(terminal)?;
|
|
|
|
|
|
}
|
|
|
|
|
|
AppEvent::KeyEvent(key_event) => {
|
|
|
|
|
|
match key_event {
|
|
|
|
|
|
KeyEvent {
|
|
|
|
|
|
code: KeyCode::Char('c'),
|
|
|
|
|
|
modifiers: crossterm::event::KeyModifiers::CONTROL,
|
|
|
|
|
|
..
|
|
|
|
|
|
} => {
|
|
|
|
|
|
self.chat_widget.submit_op(Op::Interrupt);
|
|
|
|
|
|
}
|
|
|
|
|
|
KeyEvent {
|
|
|
|
|
|
code: KeyCode::Char('d'),
|
|
|
|
|
|
modifiers: crossterm::event::KeyModifiers::CONTROL,
|
|
|
|
|
|
..
|
|
|
|
|
|
} => {
|
2025-05-08 09:46:18 -07:00
|
|
|
|
self.app_event_tx.send(AppEvent::ExitRequest)?;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
}
|
|
|
|
|
|
_ => {
|
|
|
|
|
|
self.dispatch_key_event(key_event);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2025-04-25 12:01:52 -07:00
|
|
|
|
AppEvent::Scroll(scroll_delta) => {
|
|
|
|
|
|
self.dispatch_scroll_event(scroll_delta);
|
|
|
|
|
|
}
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
AppEvent::CodexEvent(event) => {
|
|
|
|
|
|
self.dispatch_codex_event(event);
|
|
|
|
|
|
}
|
|
|
|
|
|
AppEvent::ExitRequest => {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
AppEvent::CodexOp(op) => {
|
|
|
|
|
|
if matches!(self.app_state, AppState::Chat) {
|
|
|
|
|
|
self.chat_widget.submit_op(op);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
AppEvent::LatestLog(line) => {
|
|
|
|
|
|
if matches!(self.app_state, AppState::Chat) {
|
|
|
|
|
|
let _ = self.chat_widget.update_latest_log(line);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
feat: add support for commands in the Rust TUI (#935)
Introduces support for slash commands like in the TypeScript CLI. We do
not support the full set of commands yet, but the core abstraction is
there now.
In particular, we have a `SlashCommand` enum and due to thoughtful use
of the [strum](https://crates.io/crates/strum) crate, it requires
minimal boilerplate to add a new command to the list.
The key new piece of UI is `CommandPopup`, though the keyboard events
are still handled by `ChatComposer`. The behavior is roughly as follows:
* if the first character in the composer is `/`, the command popup is
displayed (if you really want to send a message to Codex that starts
with a `/`, simply put a space before the `/`)
* while the popup is displayed, up/down can be used to change the
selection of the popup
* if there is a selection, hitting tab completes the command, but does
not send it
* if there is a selection, hitting enter sends the command
* if the prefix of the composer matches a command, the command will be
visible in the popup so the user can see the description (commands could
take arguments, so additional text may appear after the command name
itself)
https://github.com/user-attachments/assets/39c3e6ee-eeb7-4ef7-a911-466d8184975f
Incidentally, Codex wrote almost all the code for this PR!
2025-05-14 12:55:49 -07:00
|
|
|
|
AppEvent::DispatchCommand(command) => match command {
|
|
|
|
|
|
SlashCommand::Clear => {
|
|
|
|
|
|
let _ = self.chat_widget.clear_conversation_history();
|
|
|
|
|
|
}
|
|
|
|
|
|
SlashCommand::Quit => {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
terminal.clear()?;
|
|
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn draw_next_frame(&mut self, terminal: &mut tui::Tui) -> Result<()> {
|
|
|
|
|
|
match &mut self.app_state {
|
|
|
|
|
|
AppState::Chat => {
|
|
|
|
|
|
terminal.draw(|frame| frame.render_widget_ref(&self.chat_widget, frame.area()))?;
|
|
|
|
|
|
}
|
|
|
|
|
|
AppState::GitWarning { screen } => {
|
|
|
|
|
|
terminal.draw(|frame| frame.render_widget_ref(&*screen, frame.area()))?;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Dispatch a KeyEvent to the current view and let it decide what to do
|
|
|
|
|
|
/// with it.
|
|
|
|
|
|
fn dispatch_key_event(&mut self, key_event: KeyEvent) {
|
|
|
|
|
|
match &mut self.app_state {
|
|
|
|
|
|
AppState::Chat => {
|
|
|
|
|
|
if let Err(e) = self.chat_widget.handle_key_event(key_event) {
|
|
|
|
|
|
tracing::error!("SendError: {e}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
AppState::GitWarning { screen } => match screen.handle_key_event(key_event) {
|
|
|
|
|
|
GitWarningOutcome::Continue => {
|
|
|
|
|
|
self.app_state = AppState::Chat;
|
|
|
|
|
|
let _ = self.app_event_tx.send(AppEvent::Redraw);
|
|
|
|
|
|
}
|
|
|
|
|
|
GitWarningOutcome::Quit => {
|
|
|
|
|
|
let _ = self.app_event_tx.send(AppEvent::ExitRequest);
|
|
|
|
|
|
}
|
|
|
|
|
|
GitWarningOutcome::None => {
|
|
|
|
|
|
// do nothing
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-25 12:01:52 -07:00
|
|
|
|
fn dispatch_scroll_event(&mut self, scroll_delta: i32) {
|
|
|
|
|
|
if matches!(self.app_state, AppState::Chat) {
|
|
|
|
|
|
if let Err(e) = self.chat_widget.handle_scroll_delta(scroll_delta) {
|
|
|
|
|
|
tracing::error!("SendError: {e}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
fn dispatch_codex_event(&mut self, event: Event) {
|
|
|
|
|
|
if matches!(self.app_state, AppState::Chat) {
|
|
|
|
|
|
if let Err(e) = self.chat_widget.handle_codex_event(event) {
|
|
|
|
|
|
tracing::error!("SendError: {e}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|