Metadata-Version: 2.4
Name: kiro-fix-session-images
Version: 0.6.0
Summary: Repair Kiro CLI sessions broken by oversized (>=2000px) or too many inline images by resizing or trimming them in place.
Keywords: kiro,session,image,resize,repair
Author: sawitmee
License-Expression: MIT
License-File: LICENSE
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Topic :: Utilities
Requires-Dist: pillow>=10
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# kiro-fix-session-images

Repair Kiro CLI sessions that stopped working with either of these errors:

```
At least one of the image dimensions exceed max allowed size for many-image requests: 2000 pixels
too many inline media segments: 101 exceeds limit 100
```

A screenshot larger than 2000px (usually a Retina capture) gets stored in the
session history, so every later request that replays it fails. This tool scans
each session's transcript, downscales every embedded image above the
limit to 1900px on its longest side, and rewrites the file in place. The
original is kept next to it with `.bak` added to its name.

A session that has collected more than 100 images in total fails the same
way, however small they are. For those, the tool keeps the newest 80 images
and replaces each older one with a short text note (see
[Too many inline images](#too-many-inline-images)).

**Warning:** Close the session in Kiro before running, then resume it.

## Install

With uv (recommended):

```sh
uv tool install kiro-fix-session-images
```

Or run it once without installing:

```sh
uvx kiro-fix-session-images --all --dry-run
```

Or with pip:

```sh
pip install kiro-fix-session-images
```

## Quick start: fix a broken session

Works for Kiro CLI and Kiro IDE sessions, in both on-disk layouts:
`~/.kiro/sessions/<hash>/<id>/messages.jsonl` and the flat
`~/.kiro/sessions/cli/<id>.jsonl`. A session's sub-agent transcripts are
repaired along with it in both layouts.

**1. Exit the broken session.** In Kiro CLI type `/exit`; in Kiro IDE close the
chat tab. Kiro must not be writing to the session file while it is repaired.

**2. Pick the session and fix it.** `cd` into the project directory and run:

```sh
cd /path/to/your/project
uvx kiro-fix-session-images
```

A list of this directory's sessions opens (every directory's, if this one has
none), newest first, each marked `ok`, `N oversized`, `N excess images`, or
both (`N oversized, M excess images`). Type to filter (title, id or workspace), use the arrow keys to move, and press
**Enter** to fix the highlighted session. **Tab** switches to sessions from every
directory; **Esc** quits without changing anything.

Prefer to fix everything at once? `uvx kiro-fix-session-images --all`.

**3. Resume the session.**

```sh
kiro-cli chat --resume                  # Kiro CLI: most recent session here
kiro-cli chat --resume-id sess_<id>     # Kiro CLI: a specific session
```

In Kiro IDE, reopen it from the session history list.

If the session still fails, put the original back by copying the `.bak` file
over the transcript. Where that is depends on the layout:

```sh
# directory layout (Kiro CLI and IDE)
cd ~/.kiro/sessions/<hash>/<id>
cp messages.jsonl.bak messages.jsonl
cp sub-executions/<uuid>.jsonl.bak sub-executions/<uuid>.jsonl   # if one was repaired

# flat layout
cd ~/.kiro/sessions/cli
cp <id>.jsonl.bak <id>.jsonl
```

Every run that changes a file replaces its `.bak`, so after a second repair the
`.bak` holds the first repair's output, not the original. To keep the original
transcript, copy the `.bak` to another name before repairing the same session
again.

Sub-agent runs are grouped under the session that launched them, so one row
covers the whole conversation and fixing it repairs the lot. A rewind fork is
left as its own row, since it is an ordinary conversation you may want to
resume. Each sub-agent transcript keeps its own `.bak` next to it, and you can
still address one by its own id if you want to repair just that part.

## Usage

```sh
# Pick a session from a list (run inside the project directory)
kiro-fix-session-images

# List sessions for this directory with their IDs and status, then exit
kiro-fix-session-images --list
kiro-fix-session-images --list --title deploy   # match title, id or workspace
kiro-fix-session-images --list --all            # every directory

# Fix one session by ID (CLI sess_<id> or the bare IDE id both work)
kiro-fix-session-images sess_<id>

# The sess_ prefix is added automatically if you omit it
kiro-fix-session-images <id>

# Fix every session
kiro-fix-session-images --all

# Report what would change without touching any file
kiro-fix-session-images --all --dry-run

# Use a smaller target size (default 1900, must be below 2000)
kiro-fix-session-images --all --max 1600

# Keep at most 60 images per transcript (default 80, at most 100)
kiro-fix-session-images sess_<id> --max-images 60

# Scan a different sessions directory (default ~/.kiro/sessions)
kiro-fix-session-images --all --root /path/to/sessions
```

Each affected session is printed as `<id>: resized X/Y images`, followed
by a `done: N oversized image(s) fixed` summary. A repaired sub-agent
transcript is printed under its session as
`<id> (sub-execution <uuid>): resized X/Y images`. When images were trimmed,
the line ends with `, removed R oldest of T (limit N)` and the summary with
`, R excess image(s) removed`. With `--dry-run` the wording changes to
`would resize`, `would remove`, `found` and `to remove`.

`--list` and the picker take `--max-images` too, so the status they show
matches what a fix with the same flag would do.

## Too many inline images

The API rejects a request that carries more than 100 images in total, so a
long session full of screenshots breaks even when every image is small.
Downscaling does not help; only fewer images do.

The tool counts the images in each transcript file and, when there are more
than `--max-images` (default 80), replaces the oldest ones with this note,
keeping the newest:

```
[image removed by kiro-fix-session-images: session exceeded the 100 inline media limit]
```

The note goes into the record's text, and the image entry is removed, so the
transcript stays in the shape Kiro loads. Copying the `.bak` back restores the
removed images.

- The default is 80, not 100, because every turn after you resume adds more
  images. A session trimmed to exactly 100 breaks again on the next screenshot.
- Images from before Kiro compacted the conversation count too, even though
  Kiro no longer sends them. Keeping the newest N in the whole file is what
  guarantees the part Kiro does send stays under the limit, without the tool
  having to replay Kiro's compaction rules. The cost is that some old images
  you could still scroll back to are replaced by the note.
- Each sub-agent transcript is its own request, so it is counted and trimmed
  separately from its session.
- If an image is both oversized and among the oldest, it is removed, not
  resized. Both repairs happen in one rewrite with one `.bak`.

## How resizing works

Images are resized with [Pillow](https://python-pillow.org/), which is
installed as a dependency, and saved back in their original format (PNG, JPEG,
GIF or WEBP) with their EXIF metadata and color profile intact. Animated GIF
and WEBP keep every frame.

If an image can't be read, that image is skipped and reported as
`N unreadable`. The other images in the session are still fixed, the rest of
the run continues, and the exit status is 1. `--dry-run` reports and exits the
same way, so it tells you in advance what the real run cannot repair.

## Platforms

macOS, Linux and Windows. Requires Python 3.9 or newer.

## License

MIT
