Skip to main content

jusi-codex

jusi-codex brings OpenAI Codex into a Jusi/Jusivim notebook as a structured, Vim-first coding workflow.

It is for sessions where you want Codex to keep the text-driven prompt/reply loop, but you also want notebook cells, VisiData sheets, persistent turn artifacts, reviewable structured output, and editor-native diff/open/yank actions. Compared with the original Codex TUI, the main UX gain is review: live events, completed turns, touched files, and before/after diffs are separated into navigable views instead of being packed into one terminal transcript.

Installation

pip install jusi-codex

You also need:

  • Jusi 1.0.2 or newer
  • the Codex CLI available on PATH as codex
  • a Codex/OpenAI environment already configured for the Codex CLI
  • Git in project directories where you want diff and touched-file views

Jusi discovers this package as the exact codex provider through the jusi.plugins.v1 entry-point group.

Quick Start

Add a Codex target to your Jusi config:

[codex.my_app]
path = "/path/to/my-app"
model = "gpt-6-astra"
approval = "never"
sandbox = "workspace-write"

Then run a notebook cell:

%%codex my_app
Inspect the current implementation and make the smallest safe fix for the failing login test.
Show the relevant diff and mention any tests you ran.

The cell opens a VisiData runtime. While Codex is running, jusi-codex shows a live event sheet. When the turn finishes, it returns to the turns sheet with the prompt, final reply, model, thread id, and changed-file count.

Configuration

VisiData preferences and plugins load from the target account's normal VisiData configuration (~/.visidatarc, platform config.py, or VD_CONFIG). For example, options.disp_menu = False hides the menu in new Codex clients. Jusi copy/open bindings are installed afterward.

This configuration support requires Jusi 1.0.2 or newer.

jusi-codex reads the codex section from the active Jusi session config. Each key under [codex] is a target name used by %%codex TARGET.

[codex.my_app]
path = "/path/to/my-app"
model = "gpt-6-astra"
models = ["gpt-6-astra", "gpt-5.6", "gpt-5.6-terra", "gpt-5.6-luna"]
approval = "never"
sandbox = "workspace-write"
profile = "work"
add_dir = ["/path/to/shared-tools", "../sibling-repo"]

Available target options:

  • path: required for named targets. Absolute paths are used as-is; relative paths are resolved from the process working directory.
  • model: default model for new Codex turns in this target.
  • models: optional model list shown first in the model picker.
  • approval: approval policy passed to Codex with -a. If omitted, jusi-codex defaults to never.
  • approval_policy: alias for approval.
  • sandbox: sandbox mode passed to Codex with --sandbox.
  • profile: Codex profile passed with --profile.
  • add_dir: one path or a list of paths passed to Codex as writable --add-dir entries. Relative paths are resolved from the process working directory in config.

You can also pass a path directly as the target:

%%codex /path/to/my-app
Summarize the package layout.

Direct path targets do not use the named target options above unless they are also present in the Jusi config under the same target string.

Magic Arguments

The cell magic is:

%%codex TARGET [options]

Available arguments:

  • TARGET: named target from [codex.TARGET], or a filesystem path. Required by the runtime.
  • -r THREAD_ID, --resume THREAD_ID: resume a specific Codex thread id.
  • --resume without a thread id: resume the latest stored session for the target.
  • --last: same latest-session behavior as bare --resume.
  • --model MODEL: override the configured target model for this cell runtime.
  • --approval POLICY, --ask-for-approval POLICY: override target approval policy for this cell runtime.
  • --sandbox MODE: override target sandbox mode for this cell runtime.

Cell-level --model, --approval, and --sandbox affect the runtime started by that cell. Follow-up cells continue with the active runtime state unless a plugin slash command changes it.

Follow-Up Commands

Follow-up cells normally send their text as the next Codex prompt. If the first nonblank line starts with /, jusi-codex treats it as a plugin command.

/model

Opens the model sheet. Pick a model row to set the active model. For models with reasoning levels, opening the row shows a reasoning sheet first; selecting a reasoning level stores both model and reasoning effort for later turns.

/model MODEL

Sets the active model directly. /model default returns to the configured default model for the target. The selected model is persisted in the project plugin state and used for subsequent turns in the active runtime.

/resume

Opens the resumable sessions sheet for the current target. Open a row to switch the active runtime to that thread and reload its stored turns.

/add-dir PATH [PATH ...]

Adds writable directories to the active runtime without restarting the notebook client. Relative paths are resolved from the target project path. Added paths are passed to future Codex turns as --add-dir; existing paths are ignored. The command also opens a small sheet showing what was added.

Unsupported slash commands are intentionally rejected by the plugin. Text that does not start with a slash is sent to Codex as a normal prompt.

Views And Workflow

The main sheet is codex_turns. It contains one row per completed turn with:

  • prompt
  • final Codex reply
  • number of changed files
  • model and reasoning label
  • Codex thread id

Opening a turn row drills into the raw Codex event JSONL for that turn. Opening the changed_files cell opens a touched-files sheet for that turn.

The live sheet, codex_events_live, appears while Codex is running. It streams the structured JSON events produced by codex exec --json, including event type, item type, status, text, command preview, and exit code. If the cursor is already at the tail, the sheet follows new events as they arrive.

The touched-files sheet lists files whose worktree content changed across the turn. Opening a file row asks the Jusi frontend to show a split diff using the persisted before/after snapshots. The snapshot contents travel through Jusi's editor-action channel; target-side artifact paths are never treated as editor paths.

The resume sheet, codex_sessions, lists stored Codex thread ids, first prompt previews, turn counts, and update timestamps. Opening a row switches the active runtime to that thread.

The model sheet, codex_models, combines configured models with the built-in Codex model list or ~/.codex/models_cache.json when available. It supports reasoning-level drill-downs for models that advertise supported reasoning levels.

The metadata sheet shows target, path, plugin state location, model, thread, and local session id.

Skill completions are available for $skill-name tokens from CODEX_HOME/skills and ~/.codex/skills.

Jusi And VisiData Integration

jusi-codex is designed to feel like a Jusi workflow, not like a terminal emulator embedded in a cell.

Jusi follow-up cells route new prompts and plugin commands through the durable plugin worker into the same active VisiData runtime. A follow-up remains active until its Codex turn finishes, so Jusi interrupt/stop actions can cancel that exact turn without discarding the client; the next follow-up reuses the same runtime.

VisiData navigation, row opening, cell editing, and copy operations remain useful inside the Codex views. In a Jusivim frontend, editor-oriented actions integrate with the surrounding Vim workflow:

  • Ctrl+O sends the current value to an editor buffer
  • VisiData copy commands send the captured value or selection to an editor register
  • opening a touched file sends its before/after text to Jusi's native read-only diff view

That means you can inspect a turn, open its raw events, open changed files, yank structured cells into registers, and review diffs without leaving the notebook/editor flow.

State And Artifacts

State is stored under the first available location:

$JUSI_STATE_HOME/plugins/codex/<project-key>/
$XDG_STATE_HOME/jusi/plugins/codex/<project-key>/
~/.local/state/jusi/plugins/codex/<project-key>/

project-key is a stable slug plus a hash of the resolved project path, so projects with the same basename do not collide.

For each turn, jusi-codex stores:

  • prompt.md
  • final.md
  • codex-events.jsonl
  • diff.patch
  • before.json
  • after.json
  • per-file before/after artifacts for changed files
  • turn metadata in turn.json and session turns.jsonl

What Is Out Of Scope

jusi-codex does not try to reimplement the full Codex TUI. It uses codex exec --json as the execution engine and builds a structured Jusi/VisiData review workflow around it.

Out of scope:

  • Codex account login, API key setup, or CLI installation.
  • Full-screen Codex TUI layout, themes, panes, and interactive terminal controls.
  • General Codex CLI settings management beyond the options documented here.
  • Arbitrary Codex slash-command compatibility. Plugin slash commands are /model, /resume, and /add-dir.
  • Replacing Git or your editor review process. The plugin captures artifacts and asks the frontend to open diffs; it does not decide whether changes should be committed.

Use the original Codex TUI when you want the native terminal experience. Use jusi-codex when you want Codex turns to become notebook-native, queryable, reviewable Vim/VisiData structures.

Development

python -m pip install -e ".[dev,release]"
make test

Build and validate release artifacts:

make release-check

Metadata

Release files for jusi-codex 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jusi-codex 0.1.1
File Size Uploaded
jusi_codex-0.1.1.tar.gz 37.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jusi-codex 0.1.1
File Interpreter ABI Platform
jusi_codex-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 72.8 kB

Release files / jusi_codex-0.1.1.tar.gz

Download URL jusi_codex-0.1.1.tar.gz
Size 37.0 kB
Tags Source
SHA-256 checksum
How to use checksums
201c6148328408d59ef35f8a8285f513f2bca03a6ec6d55448858e0c563939c9
BLAKE2b-256 checksum
How to use checksums
6dfd5362ea42c7c1f37635275928430916eb0de424b55c82b60d23d753324c6f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / jusi_codex-0.1.1-py3-none-any.whl

Download URL jusi_codex-0.1.1-py3-none-any.whl
Size 35.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f57abb014064591d4c88ac139365156c770d56b621539ab29561854e0ec37a6f
BLAKE2b-256 checksum
How to use checksums
75b284173b9578f78bac007d6d106f7e8b133e02fbe4dcc5fd00345d730afb61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page