Skip to content

feat: add Codex-style tool mode#26

Merged
Waishnav merged 48 commits into
mainfrom
feat/codex-tool-mode
Jun 29, 2026
Merged

feat: add Codex-style tool mode#26
Waishnav merged 48 commits into
mainfrom
feat/codex-tool-mode

Conversation

@Waishnav

@Waishnav Waishnav commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

Adds an opt-in Codex-style tool mode that exposes a smaller coding-oriented tool surface while preserving the existing tool modes as the default.

What changed

  • adds DEVSPACE_TOOL_MODE=codex alongside the existing minimal and full modes
  • exposes stable short tool names in Codex mode
  • limits the Codex-mode tool surface to open_workspace, read, apply_patch, exec_command, and write_stdin
  • adds a workspace-confined apply_patch implementation with add, update, delete, and move operations
  • preserves line endings and executable file modes while applying patches
  • returns unified diff payloads and change statistics for patch tool cards
  • adds resumable command sessions for foreground and background processes
  • supports incremental output polling, stdin interaction, process interruption, output limits, and process-group cleanup
  • adds optional PTY support through node-pty, including terminal resizing
  • renders apply_patch through the existing diff UI and process tools through the existing shell UI
  • adds configuration, workflow, rollout, and manual QA documentation for the new mode

Compatibility

Codex mode is opt-in. Existing minimal and full tool modes retain their current behavior. The legacy DEVSPACE_MINIMAL_TOOLS configuration remains supported.

Summary by CodeRabbit

  • New Features
    • Added experimental codex tool mode with a codex-specific tool set for patching and command execution.
    • Introduced apply_patch, exec_command, and write_stdin tools.
    • Expanded DEVSPACE_TOOL_MODE to support minimal, full, and codex.
  • Improvements
    • Updated UI tool display with correct running vs. ran status and improved labeling for the new tools.
    • Enhanced patching reliability within the workspace and improved move/overwrite/newline handling.
  • Documentation
    • Added/expanded codex mode docs and a dedicated codex manual QA checklist.
  • Bug Fixes / Chores
    • Added a macOS post-install permission fix for the PTY helper.
  • Tests
    • Expanded coverage for patch application and process-session behavior across platforms.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds DEVSPACE_TOOL_MODE=codex as a third tool mode. It replaces the minimalTools config with toolMode, adds patch application and managed process sessions, wires new Codex tools into the server, updates UI tool handling, and expands docs, QA, and dependency support.

Changes

Codex Tool Mode

Layer / File(s) Summary
ToolMode config contract and parser
src/config.ts, src/config.test.ts
Replaces minimalTools: boolean with toolMode: ToolMode ("minimal" | "full" | "codex") in ServerConfig, adds parseToolMode with legacy DEVSPACE_MINIMAL_TOOLS mapping, and updates tests to assert string mode values.
Platform-aware shell resolution and process tree termination
src/process-platform.ts, src/process-platform.test.ts
Adds resolveShellCommand and terminateProcessTree, with multi-platform test coverage.
Patch parsing and application engine
src/apply-patch.ts, src/apply-patch.test.ts
Implements parsePatch and applyPatch, plus path confinement, unified diff output, transactional writes, and tests for multi-action patches, move semantics, path rejection, and hunk mismatch errors.
ProcessSessionManager: pipe and PTY-backed session lifecycle
src/process-sessions.ts, src/process-sessions.test.ts
Adds ProcessSessionManager and ProcessSnapshot for foreground/background commands, stdin writes, Ctrl-C, truncation, PTY resize, and TTL cleanup.
Server: Codex tool registration and session wiring
src/server.ts
Updates Codex instructions and tool gating, registers exec_command, write_stdin, and apply_patch, and wires processSessions into server creation and shutdown.
UI tool-name recognition and display
src/ui/card-types.ts, src/ui/card-types.test.ts, src/ui/workspace-app.tsx
Extends tool-name guards and display mapping for Codex tools, changes shell badge status text, and prefers sessionId in shell labels.
node-pty dependency, permission script, and docs
package.json, scripts/fix-node-pty-permissions.mjs, docs/configuration.md, docs/chatgpt-coding-workflow.md, docs/codex-tool-mode-qa.md
Adds node-pty, a macOS permission-fix script, expanded test scripts, and documentation plus QA coverage for Codex mode and sessions.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~90 minutes

Poem

🐇 Hop-hop, Codex tools are in the den,
Patches and sessions scurry out and in again.
exec_command hums, write_stdin replies,
While apply_patch stitches with careful little ties.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing an opt-in Codex-style tool mode.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/codex-tool-mode

Comment @coderabbitai help to get the list of available commands.

@Waishnav

Copy link
Copy Markdown
Owner Author

@coderabbitai review it

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

@Waishnav Sure! I'll kick off a full review of this PR right away.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package.json`:
- Around line 27-29: The PTY tests in src/process-sessions.test.ts (lines
137-158) that call manager.start({tty: true}) will fail when node-pty is not
installed, even though it is marked as optional in package.json. Modify the test
file to conditionally handle the absence of node-pty by either wrapping the
affected test cases with a check to skip them when node-pty is unavailable, or
by providing a mock implementation of node-pty for when the optional dependency
is not present. Ensure that startPty() either skips execution gracefully or has
a mocked fallback so the test suite can pass whether or not node-pty is
installed.

In `@src/apply-patch.ts`:
- Line 2: The issue is that symlinks within the workspace are not being rejected
before applying updates, which can cause `replaceFile()` to replace the symlink
path with a regular file instead of the actual target file. Add a check using
`lstat()` (which does not follow symlinks) at the beginning of the file
processing logic to detect if the final resolved path is a symlink, and reject
it before any file operations like `stat()`, `readFile()`, or `rename()` are
performed. This ensures symlinks are caught and handled appropriately rather
than being overwritten as regular files.
- Around line 1-2: The temporary file names used in staged writes are
predictable and vulnerable to being overwritten. Generate random suffixes for
temporary file names to make them unpredictable, and when calling writeFile for
temporary files, add the flag option set to "wx" to ensure exclusive creation
that will fail if the file already exists. Apply this fix to all temporary file
write operations in the file, including the ones referenced at lines 343-344.

In `@src/process-sessions.ts`:
- Around line 231-235: The resize property in the session.process object
currently provides a no-op function when input.tty is true, which incorrectly
advertises resize support for pipe-backed sessions. This causes the system to
accept resize requests and report success without actually resizing. Remove the
ternary logic that sets resize to a no-op function when input.tty is true, and
instead leave the resize property undefined unconditionally so that existing
guards can properly reject resize requests for non-PTY sessions.
- Around line 219-229: The startPipe method is passing the raw input.command
string to spawn instead of using the fully resolved shell command from
resolveShellCommand. Modify the spawn call to use shell.executable as the
command and combine shell.args with the command string as arguments passed to
spawn, similar to how the PTY backend implementation handles it. This ensures
critical shell flags (like /d /s /c for Windows cmd.exe or -lc for login shells)
are preserved when executing the pipe-backed command.

In `@src/server.ts`:
- Around line 1103-1177: The show_changes tool registration is not gated by
Codex mode, so it still registers when config.toolMode === "codex", adding a 6th
tool when the Codex surface should only have 5 tools. Modify the condition for
the show_changes registration (the if block checking config.widgets ===
"changes") to exclude Codex mode by adding an additional condition that prevents
its registration when config.toolMode === "codex".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 469c0360-89ce-42a5-b8dc-f5bfbf610495

📥 Commits

Reviewing files that changed from the base of the PR and between 4795509 and 7fa956c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (17)
  • docs/chatgpt-coding-workflow.md
  • docs/codex-tool-mode-qa.md
  • docs/configuration.md
  • package.json
  • scripts/fix-node-pty-permissions.mjs
  • src/apply-patch.test.ts
  • src/apply-patch.ts
  • src/config.test.ts
  • src/config.ts
  • src/process-platform.test.ts
  • src/process-platform.ts
  • src/process-sessions.test.ts
  • src/process-sessions.ts
  • src/server.ts
  • src/ui/card-types.test.ts
  • src/ui/card-types.ts
  • src/ui/workspace-app.tsx

Comment thread package.json Outdated
Comment thread src/apply-patch.ts
Comment thread src/apply-patch.ts
Comment thread src/process-sessions.ts
Comment thread src/process-sessions.ts
Comment thread src/server.ts
@Waishnav Waishnav force-pushed the feat/codex-tool-mode branch from 7fa956c to 17fa037 Compare June 28, 2026 13:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/codex-tool-mode-qa.md`:
- Line 31: The workspace probe currently relies on `pwd`, which is Unix-specific
and can fail in the `cmd.exe` path used by `resolveShellCommand()`. Update the
QA step to use a platform-aware check in the same docs section, either by
branching on OS/shell or replacing `pwd` with a cross-platform equivalent so the
workspace confirmation works on Windows and non-Windows shells.
- Around line 49-54: Scope the PTY checklist in the docs to non-Windows hosts
only, since ProcessSessionManager.start() uses the PTY path only when
process.platform is not win32. Update the expectations around tty=true, SIGINT
via \u0003, and PTY resize to apply only on POSIX systems, and note that Windows
currently falls back to pipe mode rather than surfacing the node-pty behavior.

In `@src/process-sessions.ts`:
- Around line 123-124: Reject the unsupported tty=true path on Windows in
process-sessions.ts instead of falling through to startPipe(session, input). In
the session startup branch that checks input.tty and process.platform, detect
the Windows case up front and return an explicit error from the session creation
flow rather than silently downgrading; keep startPty(session, input) for
supported platforms and leave startPipe(session, input) for non-TTY sessions
only.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 511d1293-bcf8-45df-a2bf-334edc4ab1c9

📥 Commits

Reviewing files that changed from the base of the PR and between 7fa956c and 17fa037.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (17)
  • docs/chatgpt-coding-workflow.md
  • docs/codex-tool-mode-qa.md
  • docs/configuration.md
  • package.json
  • scripts/fix-node-pty-permissions.mjs
  • src/apply-patch.test.ts
  • src/apply-patch.ts
  • src/config.test.ts
  • src/config.ts
  • src/process-platform.test.ts
  • src/process-platform.ts
  • src/process-sessions.test.ts
  • src/process-sessions.ts
  • src/server.ts
  • src/ui/card-types.test.ts
  • src/ui/card-types.ts
  • src/ui/workspace-app.tsx
✅ Files skipped from review due to trivial changes (2)
  • scripts/fix-node-pty-permissions.mjs
  • docs/chatgpt-coding-workflow.md
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/ui/card-types.test.ts
  • package.json
  • src/config.test.ts
  • docs/configuration.md
  • src/config.ts
  • src/ui/card-types.ts
  • src/ui/workspace-app.tsx
  • src/apply-patch.ts
  • src/process-platform.test.ts
  • src/apply-patch.test.ts
  • src/server.ts
  • src/process-sessions.test.ts

Comment thread docs/codex-tool-mode-qa.md
Comment thread docs/codex-tool-mode-qa.md
Comment thread src/process-sessions.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/apply-patch.test.ts`:
- Around line 136-160: The current tests in applyPatch lock in overwrite
behavior for add/move collisions, but the patch application contract should
reject existing destinations unless using update semantics. Update the
expectations around applyPatch so Add File and Move to cases against an existing
path assert a failure instead of successful replacement, using the existing
applyPatch helper and the overwriteRoot scenario to cover both duplicate.txt and
destination.txt. Keep the explicit Update File path as the only allowed
replacement behavior.
- Line 127: The patch application flow is leaving partial writes behind when a
later action fails, so the workspace is not restored to its original state.
Update the apply logic in apply-patch.ts so patch actions are applied
atomically: stage changes first or track successful writes and roll them back on
error, especially for Add File and other mutating actions. Adjust the
apply-patch.test.ts failure case to assert the workspace remains unchanged after
a rejected patch, using the applyPatch flow and its file mutation helpers as the
key points to fix.

In `@src/process-sessions.ts`:
- Around line 231-232: The TTY startup path in process-sessions.ts is using the
non-interactive yield default, which can delay returning sessionId for
interactive commands. Update the yieldTimeMs selection in the session startup
flow so that when input.tty is true it uses DEFAULT_INTERACTIVE_YIELD_MS, and
keep DEFAULT_EXEC_YIELD_MS for non-TTY sessions before calling
this.waitForExit(session, yieldTimeMs).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8586309-9c23-4033-b0d6-58904af6e41a

📥 Commits

Reviewing files that changed from the base of the PR and between 17fa037 and 960fd78.

📒 Files selected for processing (5)
  • src/apply-patch.test.ts
  • src/apply-patch.ts
  • src/process-sessions.test.ts
  • src/process-sessions.ts
  • src/server.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/apply-patch.ts
  • src/server.ts

Comment thread src/apply-patch.test.ts
Comment thread src/apply-patch.test.ts
Comment thread src/process-sessions.ts
@Waishnav Waishnav merged commit 89d99c9 into main Jun 29, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant