Skip to main content

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).

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 where ask stops 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 — inspect reports % 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 full to address the entire file including pre-compaction history, and --scope post-compact|auto|full everywhere selection applies,
  • edit uncompact removes the compacted record to restore the full pre-compaction history (all of it is still in the file),
  • items inside replacement_history are addressable and editable like any other item,
  • history lists 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_state records
  • 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-bak backup, 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 (from token_count events) is shown by inspect for comparison.
  • .cxcm-bak files 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

codex_cissor-0.2.0.tar.gz (53.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codex_cissor-0.2.0-py3-none-any.whl (46.1 kB view details)

Uploaded Python 3

File details

Details for the file codex_cissor-0.2.0.tar.gz.

File metadata

  • Download URL: codex_cissor-0.2.0.tar.gz
  • Upload date:
  • Size: 53.8 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

Hashes for codex_cissor-0.2.0.tar.gz
Algorithm Hash digest
SHA256 783fcb8e52b265df99c4a7be482d0b28fbbbfe7b603d1972c593fdd0ca5453ac
MD5 8be92d3c0717efc0d217fe4d9376f8d2
BLAKE2b-256 58c0d7cd3c1a1d86c4614a2e1f8c8d3659fc9a49ee5b60e845cc2616918390d9

See more details on using hashes here.

File details

Details for the file codex_cissor-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: codex_cissor-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 46.1 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

Hashes for codex_cissor-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7073046e3270a2177265b26b0df3fa2e89c7d1f04112a0ca5a9ef072e76d7233
MD5 51b7aa30ad0a15765636e9ee99321b85
BLAKE2b-256 e9afb1391613107a958c22ce5c7e7f6488a07a14c86e2c546711b78b16183cf7

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.0

2 files

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.1

2 files

This release

0.2.0 This release

2 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