Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ and the `shim` package does not carry the plugin folder. Clone the newest
release tag to a folder you keep:

```console
git clone --depth 1 --branch v1.2.0 https://github.com/GetSHIM/shim-cli ~/.local/share/shim-cli
git clone --depth 1 --branch v1.2.1 https://github.com/GetSHIM/shim-cli ~/.local/share/shim-cli
```

Then add the plugin folder to your user `settings.json` (Command Palette,
Expand Down Expand Up @@ -854,6 +854,7 @@ In a script, `shim ledger purge --yes` skips the question.
- [Architecture](https://github.com/GetSHIM/shim-cli/blob/main/docs/architecture.md)
- [Compatibility](https://github.com/GetSHIM/shim-cli/blob/main/docs/compatibility.md)
- [Privacy](https://github.com/GetSHIM/shim-cli/blob/main/docs/privacy.md)
- [1.2.1 release notes](https://github.com/GetSHIM/shim-cli/blob/main/docs/releases/1.2.1.md)
- [1.2.0 release notes](https://github.com/GetSHIM/shim-cli/blob/main/docs/releases/1.2.0.md)
- [1.1.2 release notes](https://github.com/GetSHIM/shim-cli/blob/main/docs/releases/1.1.2.md)
- [1.1.1 release notes](https://github.com/GetSHIM/shim-cli/blob/main/docs/releases/1.1.1.md)
Expand Down
29 changes: 29 additions & 0 deletions docs/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,35 @@ tool listings). `history.jsonl`, beside `projects/`, holds one line per
interactive prompt with the keys `display`, `pastedContents`, `project`,
`sessionId` and `timestamp`; `sessionId` is the transcript's file name.

## 1.2.1 release evidence

Recorded 11 October 2026 on macOS 26.4 arm64 (8 GB), uv 0.12.5, pipx 1.11.0.
The trials ran first on the released 1.2.0 from PyPI, which is what a visitor
installs, and the short re-check at the end ran on the 1.2.1 candidate wheel
and rebuilt `bin/shim.pyz`. Every trial used a scratch home (`HOME`, the XDG
folders, uv and pipx folders, `CODEX_HOME`, `COPILOT_HOME` and `TMPDIR`
inside it). Claude Code cannot sign in under a scratch home, so its live
sessions used the real home for sign-in only, with
`claude -p --setting-sources project --settings <scratch settings.json>
--strict-mcp-config` and shim's config, state and temporary folders from the
scratch home. Every value was synthetic.

| Evidence | Recorded result |
| --- | --- |
| Local gate | `python scripts/check.py` green on the 1.2.1 candidate: lint, format, types, 3,384 tests, build, `git diff --check`. |
| Install | With no Python 3.12 anywhere: `uv tool install --python 3.12 --compile-bytecode shim` fetched CPython 3.12 and installed 1.2.0 in 16 s; `pipx install --python python3.12 --fetch-missing-python shim` installed it on a standalone CPython 3.12.15 in 20 s. Upgrading 1.1.2 to 1.2.0 with `uv tool upgrade shim` and `pipx upgrade shim` left an installed Claude Code settings file unchanged. The 1.2.1 wheel installed the same way and answered `shim 1.2.1`. |
| Python 3.10 and 3.14 | The full suite at `v1.2.0`: 3,353 passed on CPython 3.10.21 and on 3.14.3. |
| Plugin archive on 3.9 | The 1.2.0 and the rebuilt 1.2.1 archives, run by the plugin launcher with only the stock macOS `python3` 3.9.6 on `PATH`, masked a recorded `Read` of a `.env` to `<SECRET_1>`, `<IBAN_1>`, `<EMAIL_1>` and answered a safe prompt with nothing. |
| Downgrade | 1.1.2 refuses a settings file that holds `markers` or `diet = ["json", "html"]`, and while it does, its prompt hook withholds every prompt. |
| Claude Code | tested: 2.1.291, run on 2.1.286. Package hook, 1.2.0: a `Read` of `.env` reached the model as `<SECRET_1>`, `<EMAIL_1>`, `<IBAN_1>`; a WebFetch of `https://httpbin.org/get?email=ops@example.com` with no allow rule was refused for want of permission, so the 1.1.1 fix holds; with `diet = ["json", "html"]` a `curl -s` of a 12,878-byte page reached the model converted, 10,494 bytes smaller, with `<EMAIL_1>` for `billing&#64;example&#46;com`. An IBAN split across two `<span>`s as `GB82 WEST 1234` and ` 5698 7654 32` reached the model as `GB82 WEST 1234 <PHONE_1>`, the same as with the default diet: the first pass masks the raw markup before the page is converted. Plugin route: `claude plugin marketplace add GetSHIM/shim-cli` and `claude plugin install shim-cli@shim-cli` in a scratch home installed 1.2.0, whose archive, loaded into a live session with no `shim-hook` on `PATH`, masked the same `.env`. 1.2.1 candidate: the `.env` read masked the same way, the WebFetch was refused the same way, and after `shim revert claude --yes` and `uv tool uninstall shim` the settings file was byte-identical to before. |
| `shim watch` | Claude Code, 1.2.0 and the candidate: reports with exact usage, the section split, `costliest`, `largest` and `largest tool result` (`Read, 42,808 bytes`), and the IBAN round trip (`3 in request, 3 in response`). `--json` `findings` held `cli.watch.large_tool_result`, valid against `docs/schemas/finding-v1.json`. In one of three identical runs, the request that carried the tool result arrived while both inspection slots were busy and was not measured, so its IBANs were not counted. A one-line `Say hi.` session in an empty folder counted 2 EMAIL in messages that Claude Code itself added. |
| Codex CLI | tested: 0.159.0. `shim install codex` and `shim doctor codex --json` into a scratch `CODEX_HOME`: the trust warning, and `plugin_not_discoverable` and `hook_activation_unverified`, schema-valid. Replayed prompt events: a report under `warn`, a block with a redacted copy under `enforce`. **No live session:** the only sign-in on the recording machine is a ChatGPT `auth.json`, which cannot be copied into a scratch `CODEX_HOME` without breaking it. |
| GitHub Copilot CLI | tested: 1.0.83, run on 1.0.85. Scratch `COPILOT_HOME`, `shim install copilot`, then `copilot -p` asked to repeat a prompt holding `ops@example.com` and `AKIAIOSFODNN7EXAMPLE`: it answered `<EMAIL_1>` and `<SECRET_1>`, and `shim report` listed both as masked in the prompt. |
| VS Code | tested: 1.137.0; 1.140.0 installed. **Not run live:** the agent chat needs a signed-in session in the GUI. Replayed prompt events gave a report and, under `enforce`, a stop with a redacted copy. |
| Commands | `doctor`, `status`, `install`, `revert` for all three clients, `scan`, `redact`, `keys`, `config`, `report`, `audit`, `ledger show` and `watch`: their `--json` findings validated against `docs/schemas/finding-v1.json`. A Claude Code settings file in its own format was byte-identical after install and revert. |
| Documentation | Three simulated first-time users (Claude Code, the other clients, the cookbook end to end) and a literal copy-paste of the README install and the first three recipes. What stopped or misled them in the first ten minutes is fixed in 1.2.1; nothing stopped them. |
| Windows | Unchanged: every command still refuses with exit 2 before touching a file (`test_on_windows_every_command_refuses_before_touching_a_file`). |

## 1.2.0 release evidence

Recorded 11 October 2026 on macOS 26.4 arm64, CPython 3.13.5 for the suite and
Expand Down
76 changes: 76 additions & 0 deletions docs/releases/1.2.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# shim-cli 1.2.1

1.2.1 fixes what three simulated first-time users and a literal copy-paste run
of the README and the cookbook tripped over in their first ten minutes on
1.2.0. The hook decides and masks exactly as in 1.2.0, so the detector and the
hook protocol are unchanged. The changes are in what the CLI prints, the
README's first screen and the cookbook.

Upgrading is `uv tool upgrade shim` or `pipx upgrade shim`, or
`/plugin update shim-cli@shim-cli` in Claude Code. `shim install` writes the
same entries as in 1.2.0.

## What the CLI says now

- **`shim demo <client>`** shows the synthetic sentence before and after
masking, then what that client does by default with a prompt or a tool result
like it. It used to print the same masked line for every client, though
Claude Code and Codex report a typed prompt and do not change it. `--json` is
unchanged.
- **`shim doctor`** with nothing installed says `No shim hook is installed, so
nothing is inspected twice.` It used to say `Exactly one shim hook path is
installed.`
- **`shim install claude`** no longer warns that existing hooks will be
preserved when the settings file has no hooks. Most Claude Code users already
have a `settings.json`, so most first installs printed a warning that was not
true. It now ends with the next step, `Start a new Claude Code session; /hooks
lists shim.`, and `shim install copilot` with `Start a new GitHub Copilot CLI
session; it has no trust step.`
- **A client settings file that does not parse** is named with Python's JSON
error and its line and column, by `install`, `revert`, `status` and `doctor`:
`~/.claude/settings.json is not valid JSON: Expecting value at line 1,
column 10.` They used to say only that the configuration could not be changed
safely.
- **`shim watch`** prints a two-line report when no request went through the
proxy, for example because the client was not signed in: `shim watch — 1s, 0
requests` and `no request reached the model provider through the proxy`. It
used to print nothing after its first line.
- **`shim redact`** ends its output the way the input ended. It used to add a
newline, so `shim redact < file > copy` gave a file with a blank last line.

## What a visitor reads

The README opens with a quickstart and a list of what shim cannot do. The
quickstart is install, `shim demo claude` and `shim install claude`. The list
says that a prompt typed into Claude Code or Codex is not masked, that Codex
and GitHub Copilot CLI tool traffic is not inspected, that VS Code masks
nothing, which Claude Code events are only reported, and that Windows is not
supported. The install example is Claude-first, and the four screenshots are
recaptured from this release's output.

The cookbook now warns about four traps. A second `[mode]` header makes the
settings file invalid. `--reset` turns off a ledger you turned on. Claude Code
puts email addresses of its own into a session, so `shim watch` counts them.
Pasting the redacted-prompt line makes Claude Code ask once to read a temporary
file.

A contract test checks every `shim` command in the README, the plugin README,
the cookbook, the command reference, the findings page and `llms.txt` against
the CLI's own commands and flags. It checks 259 lines.

The repository has issue forms, a bug report and a detection report, and a
pull request template. `CONTRIBUTING.md` says why `bin/shim.pyz` is rebuilt
only in a release commit. The Claude Code plugin installs from `main`, so an
archive rebuilt between releases ships unreleased code to plugin users.

## What to check after upgrading

- **Scripts that read `shim redact`:** the trailing newline is no longer added.
Input that ends with one still gets it.
- **Scripts that read `shim demo` text:** it now has `before` and `after` lines
and a sentence about the client. Read `shim demo <client> --json` instead.
- **Scripts that read JSON errors:** `CLIENT_SETTINGS_MALFORMED`'s `error` now
ends with the file and the JSON error. Match `code`, never `error`.
- **Downgrading:** a shim-cli older than 1.2.0 refuses a settings file that
holds `markers` or whose `diet` names `html`, and **while it is refused the
prompt hook withholds every prompt**. Remove both keys before you downgrade.
2 changes: 1 addition & 1 deletion llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ What it cannot do: a prompt typed into Claude Code or Codex cannot be masked, be

## Optional

- [1.2.0 release notes](https://github.com/GetSHIM/shim-cli/blob/main/docs/releases/1.2.0.md): the newest release
- [1.2.1 release notes](https://github.com/GetSHIM/shim-cli/blob/main/docs/releases/1.2.1.md): the newest release
2 changes: 1 addition & 1 deletion plugins/shim-cli/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "shim-cli",
"displayName": "shim-cli",
"version": "1.2.0",
"version": "1.2.1",
"description": "Masks secrets and personal data in the tool results Claude Code reads, before the model sees them; reports what was in your prompts; and, with `shim watch`, shows what a session sent and what it cost. Runs locally with no account, network destination or telemetry.",
"author": {
"name": "shim Engineering"
Expand Down
2 changes: 1 addition & 1 deletion plugins/shim-cli/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "shim-cli",
"version": "1.2.0",
"version": "1.2.1",
"description": "Reports secrets and personal data found in your Codex prompts before they are sent, locally, with no account, network destination or telemetry. Blocking is opt in.",
"author": {
"name": "shim Engineering"
Expand Down
Binary file modified plugins/shim-cli/bin/shim.pyz
Binary file not shown.
2 changes: 1 addition & 1 deletion plugins/shim-cli/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "shim-cli",
"version": "1.2.0",
"version": "1.2.1",
"description": "Finds secrets and personal data locally, in your prompts and in the tool results the agent reads, and tells you what it found. In VS Code it reports, and with enforcement on it stops a prompt or denies a tool call before it runs; a result that has already reached the model is reported, never masked. No account, no network destination, no telemetry.",
"author": {
"name": "shim Engineering"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "shim"
version = "1.2.0"
version = "1.2.1"
description = "Local traffic visibility and privacy controls for coding agents."
readme = "README.md"
requires-python = ">=3.10"
Expand Down
2 changes: 1 addition & 1 deletion src/shim_cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sys

__version__ = "1.2.0"
__version__ = "1.2.1"
WINDOWS = sys.platform == "win32"
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading