codex-cissor — edit your Codex session context
cissor edits the context of Codex CLI sessions: trim bloated tool outputs,
summarize stale turns in place, evict spans to files with recovery pointers,
transplant or inject content — then resume the leaner session with
codex resume <id>. It also inspects what is eating the window, exports
markdown archives, and answers questions about oversized material without
loading it into your context.
Edits happen on fork drafts; publishing (gated on offline validation) is how a finished fork returns to the canonical sessions tree.
Sessions live in ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl. cissor
parses that format directly, including compacted records.
Install
uv tool install codex-cissor # from PyPI (or: pipx install codex-cissor)
Requires OPENROUTER_API_KEY in the environment for LLM-backed commands
(summarize / index / export chronicle / ask / replace / evict --with-summary).
Inspection, forking, editing, validation, and transcript export work offline.
Token estimates use tiktoken (o200k_base by default).
Web UI
cissor ui # serves http://127.0.0.1:8766 and opens the browser
cissor ui --port 9000 --no-browser # headless / custom port
Browse sessions and forks, inspect per-item/per-turn token bars, and run the full
edit surface visually: select items (checkboxes or range input), then drop,
trim outputs/inputs, replace with a summary (LLM or hand-written), inject, evict
with a pointer, uncompact — drafts only, canonical sessions stay read-only.
Forks show lineage, per-op history, and changed-vs-source row highlighting;
validate and publish are one click. React + Vite + shadcn/ui frontend in web/
(npm run dev proxies to a running cissor ui --no-browser for development).
Config
cissor config path # where config/manifest/logs live (~/.codex/cxcm/)
cissor config show
cissor config set model z-ai/glm-5.3-flash # summarizer
cissor config set ask_max_input_tokens 120000 # above this, ask() switches to map-reduce
cissor config set encoding o200k_base
Any OpenRouter model id works; env overrides via CISSOR_MODEL, CISSOR_ASK_MAX_INPUT_TOKENS, etc.
ask_max_input_tokens(120k): the switch-point whereaskstops sending the whole material in one call and switches to question-keyed map-reduce.context_window_tokens(0 = unknown): the model's context limit, purely advisory —inspectreports % of window. Codex defaults to 272k (expandable to 1M); auto-compaction triggers around the ~682k hard max.
Compaction-aware scope
A compacted record contains {message, replacement_history}. On resume, Codex
replays only the last compaction's replacement_history + everything after it.
cissor therefore:
- numbers turns/items over the effective context (post-last-compaction) by default,
- warns when you touch pre-compaction items (they are not in the live window),
- supports
--scope fullto address the entire file including pre-compaction history, and--scope post-compact|auto|fulleverywhere selection applies, edit uncompactremoves the compacted record to restore the full pre-compaction history (all of it is still in the file),- items inside
replacement_historyare addressable and editable like any other item, historylists every compaction point with what it hides.
Commands
Inspection
cissor list [--limit N] [--json] # sessions, newest first (fork names shown)
cissor inspect <session> [--scope full] [--json] # per-turn + per-type token breakdown
cissor inspect <session> --turns 3-7 # breakdown of a selection
cissor show <session> --turns 3-4 [--max-chars N] # actual content of a selection
cissor history <session> [--json] # compaction points: line, summary, hidden tokens
cissor validate <session> [--json] # structural check (pairs, reasoning, meta)
cissor forks [--channel X] [--json] # registered forks: channels, lineage, op counts
cissor log [--session X] [--channel C] [--project P] [--stats] [--path] # activity trail
Address a session by: full/prefix id, manifest name, latest, or file path.
Two kinds of placeholders: <session> = any of the above, for read-only
commands. <fork-id> = the draft id returned by cissor fork — required by every
mutating command (edit, transplant, inject, extract --evict); latest is
refused there and non-fork originals are always refused.
Selection (shared by inspect/show/summarize/index/export/extract/ask/edit ops)
--scope auto|post-compact|full
--turns "2-10" turn ranges/lists
--items "12,15-20" item numbers
--from-text "needle" from first item containing text to end (inclusive)
--to-text "needle" from start to last item containing text (inclusive)
--turn-from-text / --turn-to-text
--all everything in scope
--from-text + --to-text together bound a single inclusive span (both anchor
items included). One-sided use opens a range to the start/end of scope.
Summarize (read-only)
cissor summarize <session> --turns 1-40 --style index
cissor summarize <session> --turns 2-10 --style key-points --out s.md
cissor summarize <session> --turns 2-10 --prompt "focus only on pricing decisions"
Styles are editable markdown files (see Styles below): chronicle, index,
short, key-points, export-chronicle, plus your own — or pass a one-off
--prompt/--prompt-file inline. Long selections are map-reduced in
~48k-token chunks (chunk_tokens).
Event index
cissor index <session> # generate + save to cissor state
cissor index <session> --locate "pricing" # search existing index, else generate
cissor index <session> --out D:\indexes\voice.md # custom location
Produces Items A-B (turn T): title — description entries for fast navigation;
--locate answers "where was X discussed" in item/turn ranges.
Export (archival)
cissor export <session> # markdown transcript to stdout
cissor export <session> --turns 3-9 --out archive.md
cissor export <session> --strategy chronicle # LLM chronicle segment
cissor export <session> --strategy chronicle --chronicle-dir docs\chronicles
cissor export <session> --strategy index-only
cissor export <session> --no-outputs --include-reasoning --max-item-chars 2000
Transcripts use **User** (item 4): / **Assistant** / **Tool call: name**
labels under ## Turn N headings. Developer/system messages and synthetic user
context (<environment_context> etc.) are excluded by default — pass
--include-developer / --include-synthetic to keep them (the header records
what was excluded).
--chronicle-dir maintains the conversation-chronicle skill layout: numbered
segments (NNNN-YYYY-MM-DD-HHMM-title.md) + master INDEX.md with event index.
Extract / evict to file
cissor extract <session> --turns 5-11 --out span.md # read-only dump (md|json|raw)
cissor extract <fork> --items 17-56 --out span.md --evict # + pointer message in fork
cissor extract <fork> --from-text A --to-text B --evict --with-summary --out span.md
--evict removes the span from the fork and leaves a <context_evicted> user
message with the archive path (plus an LLM summary with --with-summary).
Text anchors are inclusive (both anchor items are part of the span); evictions
covering >60% of scope or >150k tokens are refused without --force (over-broad
anchor protection). --format raw writes re-importable JSONL lines.
Ask — query oversized material with another LLM (stateful)
cissor ask D:\data\huge.json "What are the top-level keys and their types?"
cissor ask <session> --scope full "What did we decide about X early on?"
cissor ask <ask-id> "follow-up question" # continues the session
cissor asks list / cissor asks show <ask-id>
The target (any text file, or a session slice) is sent WHOLE to the ask model —
your agent's context never holds it. Above ask_max_input_tokens it falls back to
question-keyed map-reduce: the material is split into ~48k-token chunks, and
each chunk is filtered through the QUESTION ("extract every fact relevant to this
question, with exact values and anchors") — that's the map phase, keyed to the
question rather than generic summarization. A final reduce call merges the
extracts into a grounded answer citing which fragments support each claim. Note:
each new question on an oversized target re-scans the chunks. Answers cite
item/turn anchors when the material provides them. PDFs/binary are rejected with a
conversion hint — convert to text/markdown first, then ask the converted file.
Fork (draft) → edit → publish
Forks are drafts stored in ~/.codex/cxcm/forks/ — invisible to Codex until
published, so the canonical session list stays clean while editing is in progress.
cissor fork <session> --name my-fork # or --suffix trimmed, or neither (auto -fork)
cissor fork <session> --channel diet-auth # stable work-stream id (default: source session id,
# inherited by fork-of-fork so a chain stays grouped)
cissor edit <fork-id> ... # work on the draft
cissor publish <fork-id> # offline validation gate, then copies into sessions tree
codex resume <published-id> # user resumes
cissor forks [--channel diet-auth] # registered forks: status, lineage, op counts
Fork discipline: the fork is agent-invoked and returns an id; every editing
action must pass that id explicitly. latest is refused for edits. Multiple forks
are fine when each is deliberate; channels group related forks, and a repeat fork
in the same channel within 30 minutes prints a warning pointing at the existing
one. Fork of a fork inherits the parent channel and extends the lineage chain.
Originals are never edited in place — no override exists. Editing requires a
registered fork; --force only exists for the over-broad eviction guard.
cissor publish <fork-id> runs the offline validator first (no Codex invocation, no
tokens) and refuses to publish a structurally broken fork; --open then launches
codex resume <id> in the fork's project directory. Re-publishing an already
published fork is refused unless --republish.
Note: forks keep the source session's cwd (provenance). Codex's resume lookup
filters by cwd, so resume from the same project works directly; from a different
directory use codex resume --all <id> / codex exec resume --all <id>.
Edit (fork drafts only — originals are immutable; requires the explicit fork id)
cissor edit <fork> drop --turns 3-7
cissor edit <fork> replace --turns 2-40 --style index # summarize + splice summary
cissor edit <fork> replace --turns 2-40 --summary-file s.md # splice a hand-written summary
cissor edit <fork> trim-outputs --turns 2-10 --keep-chars 250 --min-tokens 200
cissor edit <fork> trim-outputs --all --keep-chars 400
cissor edit <fork> trim-inputs --all --keep-chars 200
cissor edit <fork> uncompact [--which last|first|all]
cissor edit <fork> transplant --from <other-session> --turns 3-9 # copy a span in (pairs kept intact)
cissor edit <fork> inject --file notes.md --label project_notes # add a whole document as a turn
inject appends ONE message at the end — user role by default
(--role developer|assistant available) — wrapped in <label> tags; no fake
assistant turn is added. transplant requires complete call/output pairs in the
span and renames colliding call_ids automatically.
Safety model:
- originals are immutable — edits only ever touch fork drafts, never
--force-able - never touches
session_meta,turn_context,event_msg,world_staterecords - dropping/replacing a tool call auto-includes its paired output (and vice versa), plus any reasoning items directly attached to them — a broken call/output pair or a dangling reasoning item makes resume fail
- refuses to remove the last user message
- every save: pre-edit
.cxcm-bakbackup, post-edit validation; pre-existing structural errors (some of Codex's own compactions leave orphan calls) are reported but don't block edits — only new errors do - all writes are atomic (temp file + rename)
- reports/log lines compress item lists to ranges (
17-56) to save agent context
Styles — editable prompts
cissor styles list # builtin | file | custom
cissor styles show index
cissor styles edit index # materializes the default, prints the path; edit at will
cissor styles reset index # back to builtin
Style files live in ~/.codex/cxcm/styles/<name>.md; a file overrides the builtin.
Create <your-style>.md for custom compaction flavours and use --style your-style.
Traceability
Every mutating or LLM-backed action appends one line to
~/.codex/cxcm/activity.jsonl (ts, kind, session, channel, project cwd, op, items,
tokens before/after, model, outputs). Forks additionally keep per-fork op history
in ~/.codex/cxcm/manifest.json.
cissor log # last 30 events (item lists range-compressed)
cissor log --stats # compact aggregate: events by kind, total tokens saved, channels
cissor log --channel diet-auth # everything for one work stream
cissor log --project ai-landscape # everything for one project cwd
cissor log --path # just print the file paths — grep them with bash for deep dives
Never dump the whole log into an agent context; use --path + shell search, or
--stats for a summary.
Agent self-service workflow
cissor fork latest --suffix context-diet
cissor index <fork> --locate "the pricing bug" # find what matters
cissor extract <fork> --turns 3-8 --out dump.md --evict --with-summary
cissor edit <fork> trim-outputs --all --keep-chars 300 --min-tokens 300
cissor edit <fork> replace --turns 9-40 --style index
cissor validate <fork>
codex resume <new-id>
Notes
- Token estimates cover conversation items only — not the system prompt, developer
instructions stored in
session_meta, or tool schemas. Real API usage (fromtoken_countevents) is shown byinspectfor comparison. .cxcm-bakfiles sit next to edited sessions; Codex ignores them.- Roadmap ideas live in
ROADMAP.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codex_cissor-0.4.0.tar.gz.
File metadata
- Download URL: codex_cissor-0.4.0.tar.gz
- Upload date:
- Size: 310.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d36e91abdc4be62d0b3aa51f1736d062ec0ea538f9164050fb75fe61c119c229
|
|
| MD5 |
80298b57ff53a6b178256c0c9610b5f1
|
|
| BLAKE2b-256 |
225e3ca33654fe3d3ab5f1f5c69ba99d258caa3a415b0671c3f4dfc097664c65
|
File details
Details for the file codex_cissor-0.4.0-py3-none-any.whl.
File metadata
- Download URL: codex_cissor-0.4.0-py3-none-any.whl
- Upload date:
- Size: 300.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e185e15b507437a06dcd05032d313b4de07190a461fd530197720910854079c
|
|
| MD5 |
9d60b0d98d9e7722002ed374501a2b81
|
|
| BLAKE2b-256 |
4f0b3a314793be04ceeaefaf8b1bcd500c6a2ff856e55a93964ae533d8251046
|