cxs-cloner
v0.1.0
Published
CLI and SDK for cloning Codex sessions with reduced context
Maintainers
Readme
cxs-cloner
Clone and modify Codex sessions with context reduction.
Why This Exists
Codex sessions accumulate context over time: tool calls with large inputs and outputs, reasoning blocks, telemetry, replay state, and compacted history markers. When sessions get large enough, continuing them becomes slower and eventually impractical.
cxs-cloner creates a lean copy of a Codex rollout by:
- Removing tool content from older tool-bearing turns while preserving recent ones
- Truncating intermediate tool-bearing turns for gradual context reduction
- Stripping reasoning blocks when requested
- Preserving the replay-compatible events and metadata that let the clone remain resumable in Codex
- Optionally rewriting the clone's working directory and git metadata with
--target-cwd
The cloned session can be resumed with reduced context while keeping useful back-history intact.
Installation
# Install globally via npm
npm install -g cxs-cloner
# Or build from source
git clone https://github.com/liminal-ai/cxs-cloner.git
cd cxs-cloner
npm ci
npm run build
npm linkRequires Node.js 20.12 or newer.
Quick Start
# List recent sessions to find the session ID
cxs-cloner list
# Inspect a session before cloning
cxs-cloner info abc123
# Clone with default preset (keep 20 tool-turns)
cxs-cloner clone abc123 --strip-tools
# Clone with aggressive preset (keep 10 tool-turns)
cxs-cloner clone abc123 --strip-tools=aggressive
# Clone with heavy preset (keep 10 tool-turns, mostly truncated)
cxs-cloner clone abc123 --strip-tools=heavy
# Clone with extreme preset (remove all tools)
cxs-cloner clone abc123 --strip-tools=extreme
# Clone and rewrite cwd/git metadata
cxs-cloner clone abc123 --strip-tools --target-cwd /path/to/projectPresets
Tool removal uses presets that define how many turns with tools to keep and how many of those kept turns to truncate.
| Preset | Keep | Truncate | Behavior |
|--------|------|----------|----------|
| default | 20 turns | 50% | 10 truncated, 10 full fidelity |
| aggressive | 10 turns | 70% | 7 truncated, 3 full fidelity |
| heavy | 10 turns | 80% | 8 truncated, 2 full fidelity |
| extreme | 0 | 0% | All tools removed |
Using --strip-tools or --strip-tools=default applies your configured default preset, which initially resolves to default.
How Presets Work
Tool removal targets turns that have tool calls, not all turns. This ensures consistent behavior across repeated clones of the same session.
Of the kept turns:
- Oldest portion (truncate %) -> tool content is shortened
- Newest portion -> full fidelity is preserved
This gives graceful degradation: recent tool context stays exact, slightly older context stays recognizable, and ancient tool detail is removed.
Custom Presets
Define custom presets in cxs-cloner.config.ts:
import type { CxsConfiguration } from "cxs-cloner";
const config: Partial<CxsConfiguration> = {
customPresets: {
minimal: { keepTurnsWithTools: 5, truncatePercent: 80 },
thorough: { keepTurnsWithTools: 30, truncatePercent: 30 },
},
defaultPreset: "minimal",
};
export default config;Use with: cxs-cloner clone abc123 --strip-tools=minimal
Commands
clone
Clone a session with optional modifications.
cxs-cloner clone <sessionId> [options]Arguments:
sessionId- Session UUID to clone (required)
Options:
| Flag | Description |
|------|-------------|
| --strip-tools | Remove tools using the configured default preset |
| --strip-tools=<preset> | Remove tools using a named preset |
| --strip-reasoning=<mode> | Strip reasoning using full, summary-only, or none |
| --target-cwd <path> | Rewrite the cloned session's cwd and git metadata |
| --output, -o <path> | Write to a custom output path instead of the Codex sessions directory |
| --codex-dir <path> | Override Codex data directory (default: ~/.codex) |
| --json | Output clone result as JSON |
| --verbose, -v | Show detailed removal statistics |
| --force | Skip malformed JSON lines instead of aborting |
Examples:
# Default preset
cxs-cloner clone abc-123 --strip-tools
# Heavy preset
cxs-cloner clone abc-123 --strip-tools=heavy
# Reasoning-only clone
cxs-cloner clone abc-123 --strip-reasoning=full
# Clone into a different project directory
cxs-cloner clone abc-123 --strip-tools --target-cwd /Users/me/other-project
# JSON output for scripting
cxs-cloner clone abc-123 --strip-tools --jsonlist
List Codex sessions.
cxs-cloner list [options]Options:
| Flag | Description |
|------|-------------|
| --limit <count> | Maximum number of sessions to display |
| --codex-dir <path> | Override Codex data directory (default: ~/.codex) |
| --json | Output as JSON |
| --verbose, -v | Show additional metadata such as model provider and git branch |
Examples:
# List recent sessions
cxs-cloner list
# Show more sessions
cxs-cloner list --limit 50
# JSON output
cxs-cloner list --jsoninfo
Show detailed information about a session.
cxs-cloner info <sessionId> [options]Arguments:
sessionId- Session UUID to inspect (required)
Options:
| Flag | Description |
|------|-------------|
| --codex-dir <path> | Override Codex data directory (default: ~/.codex) |
| --json | Output as JSON |
| --verbose, -v | Show per-type record breakdown |
Output includes:
- Session ID and cwd
- File size and estimated token count
- Turn count
- Tool call count
- Reasoning block count
- Event count
- Compaction detection
Configuration
cxs-cloner uses c12 for configuration loading.
Config File
Create cxs-cloner.config.ts in your project root:
import type { CxsConfiguration } from "cxs-cloner";
const config: Partial<CxsConfiguration> = {
codexDir: "/custom/path/to/.codex",
defaultPreset: "default",
customPresets: {
minimal: { keepTurnsWithTools: 5, truncatePercent: 80 },
},
eventPreserveList: [],
truncateLength: 120,
};
export default config;Supported config file names include:
cxs-cloner.config.tscxs-cloner.config.js.cxs-clonerrc.cxs-clonerrc.json
Environment Variables
| Variable | Description |
|----------|-------------|
| CXS_CLONER_CODEX_DIR | Codex data directory |
Precedence
Configuration sources are merged in order, with later sources overriding earlier ones:
- Built-in defaults
- Config file
- Environment variables
- CLI flags
How It Works
Turn-Based Tool Stripping
Tool stripping uses a keep-last-N model over turns with tools:
- Identify turns that contain tool calls
- Keep the last N of those turns
- Truncate the oldest configured portion of the kept turns
- Remove tool content from everything older
This avoids the repeated-clone degradation you get from percentage-of-all-turns approaches.
Reasoning Stripping
Reasoning removal is independent of tool removal:
fullremoves reasoning blocks entirelysummary-onlykeeps summary text but removes full reasoning payloadsnonekeeps reasoning untouched
Replay Preservation
When cloning, cxs-cloner preserves the replay-compatible event messages and compaction markers needed for Codex history reconstruction. If the stripped output would lose the user message event required for replay compatibility, the clone logic synthesizes one from the surviving user message content when possible.
Clone Naming
For default-location clones, cxs-cloner tries to derive a useful clone title by:
- Reading the existing thread name from
session_index.jsonl - Falling back to the first real user prompt
- Ignoring bootstrap AGENTS/environment prompts during fallback naming
--target-cwd
When --target-cwd is provided, the clone rewrites:
session_meta.cwd- all
turn_context.cwdvalues - git metadata based on the target directory
This is useful when you want to continue the cloned session in a different checkout or workspace.
Session Index Update
For clones written into the default Codex sessions directory, cxs-cloner appends a matching entry to ~/.codex/session_index.jsonl. That keeps the clone discoverable through Codex tooling and resumable by thread ID.
If you write to a custom output path, the clone file is still produced, but it is not registered as a resumable session.
SDK Usage
cxs-cloner exports its core functions for programmatic use:
import {
BUILT_IN_PRESETS,
NATIVE_LIMITED_EVENT_PRESERVE_LIST,
executeCloneOperation,
loadConfiguration,
} from "cxs-cloner";
const config = await loadConfiguration();
const result = await executeCloneOperation({
sessionId: "abc123",
codexDir: config.codexDir,
outputPath: null,
targetCwd: null,
stripConfig: {
toolPreset: BUILT_IN_PRESETS.default,
reasoningMode: "full",
stripTools: true,
eventPreserveList: NATIVE_LIMITED_EVENT_PRESERVE_LIST,
truncateLength: config.truncateLength,
},
force: false,
jsonOutput: false,
verbose: false,
});
console.log(result.clonedThreadId);Smoke Tests
Real-session smoke fixtures live in test/fixtures/data/smoke/ and are curated copies of native Codex rollout files. Source manifests, capture notes, and manual smoke workflows live in smoke-tests/.
The automated smoke suite covers:
- tool-heavy real sessions
- assessment and improvement sessions
- replay-sensitive sessions
- compaction-sensitive sessions
- real low-tool / no-tool sessions
Development
npm ci
npm run verify