npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ccs-cloner

v0.3.5

Published

CLI tool to clone and modify Claude Code sessions

Readme

ccs-cloner

Clone and modify Claude Code sessions with context reduction.

Why This Exists

Claude Code sessions accumulate context over time: tool calls with large inputs/outputs, orphaned conversation branches from rollbacks, and thinking blocks. When sessions hit context limits, continuation becomes impossible.

ccs-cloner creates a lean copy of a session by:

  1. Removing tool calls from old turns while preserving recent ones
  2. Truncating tool content in intermediate turns for gradual context reduction
  3. Automatically removing thinking blocks when --strip-tools is used

The cloned session appears in claude --resume and can be continued with reduced context.

Installation

# Install globally via npm
npm install -g ccs-cloner

# Or via bun
bun add -g ccs-cloner

# Or build from source
git clone https://github.com/liminal-ai/ccs-cloner.git
cd ccs-cloner
bun install && bun link

Requires Bun 1.0+ or Node.js 18+.

Quick Start

TIP: Configure Claude Code to show session ID in status line for easy access.

# List recent sessions to find the session ID
ccs-cloner list

# Clone with default preset (keep 20 tool-turns)
ccs-cloner clone abc123 --strip-tools

# Clone with aggressive preset (keep 10 tool-turns)
ccs-cloner clone abc123 --strip-tools=aggressive

# Clone with extreme preset (remove all tools)
ccs-cloner clone abc123 --strip-tools=extreme

# Get detailed info about a session before cloning
ccs-cloner info abc123

Presets

Tool removal uses presets that define how many "turns with tools" to keep and how many of those to truncate.

| Preset | Keep | Truncate | Behavior | |--------|------|----------|----------| | default | 20 turns | 50% | 10 truncated, 10 full fidelity | | aggressive | 10 turns | 50% | 5 truncated, 5 full fidelity | | extreme | 0 | - | All tools removed |

Using --strip-tools or --strip-tools=default applies your configured default preset (initially default, configurable via defaultPreset in config).

How Presets Work

Tool removal targets turns that have tool calls, not all turns. This ensures consistent behavior across multiple clones of the same session.

Of the kept turns:

  • Oldest portion (truncate %) -> tool content reduced to ~2 lines
  • Newest portion -> full fidelity preserved

This provides graceful degradation: recent tool context is preserved exactly, older tool context is summarized, and ancient tool context is removed entirely.

Custom Presets

Define in ccs-cloner.config.ts:

export default {
  customPresets: {
    minimal: { name: "minimal", keepTurnsWithTools: 5, truncatePercent: 80 },
    thorough: { name: "thorough", keepTurnsWithTools: 30, truncatePercent: 30 },
  },
  defaultPreset: "minimal",  // Use custom preset as default
};

Use with: ccs-cloner clone abc123 --strip-tools=minimal

Commands

clone

Clone a session with optional modifications.

ccs-cloner clone <sessionId> [options]

Arguments:

  • sessionId - Session UUID to clone (required)

Options:

| Flag | Description | |------|-------------| | --strip-tools | Remove tools using default preset | | --strip-tools=<preset> | Remove tools using named preset (default, aggressive, extreme, or custom) | | --dsp | Include --dangerously-skip-permissions in resume command | | --output, -o <path> | Output path (default: auto-generated in same project directory) | | --claude-dir <path> | Claude data directory (default: ~/.claude) | | --json | Output result as JSON | | --verbose, -v | Verbose output with statistics |

Examples:

# Default preset: keep 20 tool-turns
ccs-cloner clone abc-123-def --strip-tools

# Aggressive: keep only 10 tool-turns
ccs-cloner clone abc-123-def --strip-tools=aggressive

# Extreme: remove all tools
ccs-cloner clone abc-123-def --strip-tools=extreme

# Include --dangerously-skip-permissions in resume command
ccs-cloner clone abc-123-def --strip-tools --dsp

# Custom output location
ccs-cloner clone abc-123-def --strip-tools -o ./backup.jsonl

# JSON output for scripting
ccs-cloner clone abc-123-def --json --strip-tools

list

List Claude Code sessions.

ccs-cloner list [options]

Options:

| Flag | Description | |------|-------------| | --project, -p <path> | Filter by project path (substring match) | | --limit, -n <count> | Maximum sessions to show (default: 20) | | --claude-dir <path> | Claude data directory (default: ~/.claude) | | --json | Output as JSON | | --verbose, -v | Show additional details |

Examples:

# List 20 most recent sessions
ccs-cloner list

# Filter by project path
ccs-cloner list -p my-project

# Show more sessions
ccs-cloner list -n 50

info

Show detailed information about a session.

ccs-cloner info <sessionId> [options]

Arguments:

  • sessionId - Session UUID to inspect (required)

Options:

| Flag | Description | |------|-------------| | --claude-dir <path> | Claude data directory (default: ~/.claude) | | --json | Output as JSON | | --verbose, -v | Show additional details |

Output includes:

  • Session ID and project path
  • Turn count and entry count
  • File size and timestamps
  • Tool call count
  • Whether session contains thinking blocks

Configuration

ccs-cloner uses c12 for configuration loading.

Config File

Create ccs-cloner.config.ts in your project root:

import type { UserConfiguration } from "ccs-cloner";

const config: UserConfiguration = {
  // Override Claude data directory
  claudeDataDirectory: "/custom/path/to/.claude",

  // Default preset when --strip-tools has no value
  defaultPreset: "default",

  // Custom presets
  customPresets: {
    minimal: { name: "minimal", keepTurnsWithTools: 5, truncatePercent: 80 },
  },

  // Default output format: "human" or "json"
  outputFormat: "human",

  // Enable verbose output by default
  verboseOutput: false,
};

export default config;

Supported config file names:

  • ccs-cloner.config.ts
  • ccs-cloner.config.js
  • .ccs-clonerrc
  • .ccs-clonerrc.json
  • .ccs-clonerrc.yaml

Environment Variables

| Variable | Description | |----------|-------------| | CCS_CLONER_CLAUDE_DIR | Claude data directory | | CCS_CLONER_OUTPUT_FORMAT | Output format (human or json) | | CCS_CLONER_VERBOSE | Enable verbose output (true or false) |

Precedence

Configuration sources are merged in order (later overrides earlier):

  1. Defaults
  2. Config file
  3. Environment variables
  4. CLI flags

How It Works

Active Branch Extraction (Disabled)

Note: This feature is currently disabled due to issues with cross-file parent references (subagent sessions). It is being evaluated for fixing or removal.

Claude Code sessions are stored as JSONL files with a tree structure using uuid and parentUuid fields. When you use rollback or continue from an earlier point, the old branch becomes orphaned but remains in the file.

When enabled, ccs-cloner walks the parentUuid chain from the leaf node back to the root, keeping only entries in the active conversation path. Orphaned branches would be discarded.

Tool Removal Algorithm

Tool removal uses a "keep last N turns-with-tools" model:

  1. Identify: Find all turns that contain tool calls
  2. Keep: Preserve the last N of those turns
  3. Truncate: Of kept turns, truncate the oldest X%
  4. Remove: Remove tools from everything else

This ensures consistent behavior across multiple clones. Unlike percentage-based removal, this algorithm doesn't degrade over repeated clones.

Thinking Block Removal

When --strip-tools is used on a session containing tools, all thinking blocks are automatically removed from the entire session. This is because thinking blocks often reference tool results that may no longer exist.

Session Index Update

After writing the cloned session file, ccs-cloner:

  1. Creates the session's todos file
  2. Creates the session-env directory
  3. Updates the project's sessions-index.json

This ensures the cloned session appears in claude --resume.

SDK Usage

ccs-cloner exports its core functions for programmatic use:

import {
  executeCloneOperation,
  listAllProjects,
  listSessionsInProject,
  findSessionFileById,
  parseSessionFile,
  removeToolCallsFromHistory,
  BUILT_IN_PRESETS,
  resolveToolRemovalOptions,
} from "ccs-cloner";

// Clone a session with default preset
const result = await executeCloneOperation({
  sourceSessionId: "abc-123-def",
  toolRemovalConfig: {
    preset: "default",
  },
});

console.log(result.clonedSessionId);
console.log(result.operationStatistics);

// Clone with aggressive preset
const aggressiveResult = await executeCloneOperation({
  sourceSessionId: "abc-123-def",
  toolRemovalConfig: {
    preset: "aggressive",
  },
});

// Clone with custom values (override preset)
const customResult = await executeCloneOperation({
  sourceSessionId: "abc-123-def",
  toolRemovalConfig: {
    preset: "default",
    keepTurnsWithTools: 15,  // override preset value
    truncatePercent: 75,      // override preset value
  },
});

// List all projects
const projects = await listAllProjects();
for (const project of projects) {
  console.log(project.path, project.folder);
}

// Find and parse a session
const sessionPath = await findSessionFileById("abc-123-def");
const { entries } = await parseSessionFile(sessionPath);

// Remove tools from entries directly
const resolved = resolveToolRemovalOptions({ preset: "default" });
const removalResult = removeToolCallsFromHistory(entries, resolved);
console.log(removalResult.statistics.turnsWithToolsRemoved);
console.log(removalResult.statistics.turnsWithToolsTruncated);
console.log(removalResult.statistics.turnsWithToolsPreserved);

Exported Functions

Core Operations:

  • executeCloneOperation(options) - Full clone pipeline
  • removeToolCallsFromHistory(entries, options) - Remove/truncate tools
  • filterCloneableEntries(entries) - Filter non-cloneable entry types
  • repairBrokenParentReferences(entries) - Fix parent chain after filtering
  • identifyTurnBoundaries(entries) - Calculate turn boundaries
  • countTurns(entries) - Count turns in session

Preset System:

  • BUILT_IN_PRESETS - Built-in preset definitions
  • resolvePreset(name, customPresets?) - Resolve preset by name
  • resolveToolRemovalOptions(options, customPresets?) - Resolve to concrete values
  • isValidPresetName(name, customPresets?) - Check if preset exists
  • listAvailablePresets(customPresets?) - List all preset names

IO Operations:

  • findSessionFileById(sessionId, claudeDir?) - Find session file path
  • listAllProjects(claudeDir?) - List all project directories
  • listSessionsInProject(projectPath) - List sessions in a project
  • parseSessionFile(path) - Parse JSONL session file
  • parseSessionContent(content) - Parse JSONL string
  • serializeSessionEntries(entries) - Serialize entries to JSONL
  • writeSessionFile(path, content) - Write session file
  • addSessionToIndex(projectDir, sessionId, path, metadata) - Update index

Configuration:

  • loadConfiguration(cliConfig?) - Load merged configuration
  • getDefaultClaudeDir() - Get default Claude directory path

Exported Types

import type {
  // Session types
  SessionLineItem,
  ContentBlock,
  ToolUseBlock,
  ToolResultBlock,
  ThinkingBlock,

  // Operation types
  CloneOperationOptions,
  CloneOperationResult,
  CloneOperationStatistics,
  ToolRemovalOptions,
  ToolRemovalResult,
  ToolRemovalStatistics,
  ToolRemovalPreset,
  ResolvedToolRemovalOptions,

  // Configuration
  UserConfiguration,
  ResolvedConfiguration,
} from "ccs-cloner";

Development

# Install dependencies
bun install

# Run tests
bun test

# Type check
bun run typecheck

# Lint
bun run lint

# Format
bun run format

# Build
bun run build

Project Structure

src/
  cli.ts                 # CLI entry point
  index.ts               # SDK exports
  commands/              # CLI command definitions
  config/                # Configuration and presets
  core/                  # Core logic (extraction, removal, etc.)
  io/                    # File system operations
  output/                # Output formatting
  types/                 # TypeScript type definitions
  errors/                # Custom error classes

Changelog

See CHANGELOG.md for version history.

License

MIT