Metadata-Version: 2.4
Name: jusi-codex
Version: 0.1.0
Summary: Codex display-handler plugin for Jusi
Project-URL: Homepage, https://github.com/notawhaleble/jusi-codex
Project-URL: Repository, https://github.com/notawhaleble/jusi-codex
Project-URL: Issues, https://github.com/notawhaleble/jusi-codex/issues
Author: notawhaleble
License: MIT License
        
        Copyright (c) 2026 notawhaleble
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: codex,jupyter,jusi,notebook,plugin
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Jupyter
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development
Requires-Python: >=3.9
Requires-Dist: ipython>=8
Requires-Dist: jusi[vd]<2,>=1.0
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: release
Requires-Dist: build>=1.2; extra == 'release'
Requires-Dist: twine>=5; extra == 'release'
Description-Content-Type: text/markdown

# 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

```bash
pip install jusi-codex
```

You also need:

- Jusi 1.0
- 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:

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

Then run a notebook cell:

```python
%%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

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

```toml
[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:

```python
%%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:

```text
%%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:

```text
$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

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

Build and validate release artifacts:

```bash
make release-check
```
