Rename: claude-image-proxy -> pixelpipe (Tier 1: code + docs)

Project rename for the Show HN launch with framing:
  'pixelpipe — what if Opus saw a UI instead of just append-only logs?'

Renamed everywhere:
  - kebab-case 'claude-image-proxy' -> 'pixelpipe' (42 occurrences)
  - snake_case 'claude_image_proxy' -> 'pixelpipe'  (5 occurrences)
  - 14 files touched: package.json, Cargo.toml, Cargo.lock, *.md,
    bin/cli.js, scripts/install.js, src/proxy.py, src/rust/src/main.rs,
    src/rust/examples/{render_sample,transform_only,diff_render}.rs,
    src/zig/build.zig

Effects on build artifacts:
  - npm package name -> 'pixelpipe'
  - Rust binary name -> target/release/pixelpipe (was claude-image-proxy)
  - Python cache dir -> ~/.cache/pixelpipe/ (was ~/.cache/claude-image-proxy/)

NOT YET DONE in this commit (Tier 2+3, handled in next commit):
  - Repo on-disk directory still ~/Downloads/repos/claude-image-proxy/
  - Cache dir on disk still ~/.cache/claude-image-proxy/ — Python proxy
    currently writes here. Will be migrated alongside the running services
    in a coordinated stop/move/restart sequence.

Validation: scripts/diff_transform.py still produces exactly 1 structural
diff (the PNG bytes, expected — different fonts Python/Menlo vs
Rust/JetBrains Mono). No regression from the rename.
This commit is contained in:
teamchong
2026-05-18 14:16:48 -04:00
parent f094649831
commit f20207cd7b
12 changed files with 59 additions and 59 deletions
+4 -4
View File
@@ -1,4 +1,4 @@
# claude-image-proxy
# pixelpipe
A token-saving proxy for Claude Code that renders the system prompt + tool
definitions + tool schemas as **bitmap images** instead of sending them as text.
@@ -13,7 +13,7 @@ model gets the same context — but rendered as ~3,500 image tokens instead of
```bash
# Terminal 1
npx claude-image-proxy
npx pixelpipe
# Terminal 2
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude --exclude-dynamic-system-prompt-sections
@@ -64,7 +64,7 @@ cache_read), saving ~70% of input cost per turn forever.
## Architecture
```
~/Downloads/repos/claude-image-proxy/
~/Downloads/repos/pixelpipe/
├── bin/cli.js # npx entry point
├── scripts/
│ ├── install.js # postinstall: verify Python + install Pillow/httpx
@@ -128,7 +128,7 @@ Then `claude -p "Read out.png and transcribe"` to verify OCR.
## Configuration
```
npx claude-image-proxy [options]
npx pixelpipe [options]
-p, --port <N> Port to listen on (default: 47821)
--no-compress Disable all compression (pure passthrough)
+8 -8
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env node
/**
* claude-image-proxy CLI
* pixelpipe CLI
*
* Usage:
* npx claude-image-proxy # start on default port 47821
* npx claude-image-proxy --port 9000 # custom port
* npx claude-image-proxy --no-compress # disable compression (passthrough)
* npx pixelpipe # start on default port 47821
* npx pixelpipe --port 9000 # custom port
* npx pixelpipe --no-compress # disable compression (passthrough)
*
* Then point Claude Code at it:
* ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude
@@ -53,13 +53,13 @@ function parseArgs(argv) {
}
function printHelp() {
console.log(`claude-image-proxy — token-saving proxy for Claude Code
console.log(`pixelpipe — token-saving proxy for Claude Code
Renders system prompt + tool definitions as bitmap images. Achieves 65-73%
token savings on Opus 4.7 with 100% reasoning quality preserved.
USAGE
npx claude-image-proxy [options]
npx pixelpipe [options]
OPTIONS
-p, --port <N> Port to listen on (default: 47821)
@@ -74,7 +74,7 @@ OPTIONS
USAGE WITH CLAUDE CODE
Terminal 1:
npx claude-image-proxy
npx pixelpipe
Terminal 2:
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude --exclude-dynamic-system-prompt-sections
@@ -145,7 +145,7 @@ function main() {
MIN_COMPRESS_CHARS: String(opts.minChars),
};
console.log(`claude-image-proxy v${readPkgVersion()} starting...`);
console.log(`pixelpipe v${readPkgVersion()} starting...`);
console.log(` python: ${py}`);
console.log(` port: ${opts.port}`);
console.log(` compression: ${opts.compress ? "ON" : "OFF (passthrough)"}`);
+2 -2
View File
@@ -1,9 +1,9 @@
{
"name": "claude-image-proxy",
"name": "pixelpipe",
"version": "0.1.0",
"description": "Token-saving proxy for Claude Code: renders system prompt + tool definitions as images, achieving 65-73% token savings on Opus 4.7 while preserving 100% reasoning quality.",
"bin": {
"claude-image-proxy": "bin/cli.js"
"pixelpipe": "bin/cli.js"
},
"scripts": {
"postinstall": "node scripts/install.js",
+4 -4
View File
@@ -26,7 +26,7 @@ function hasModule(py, mod) {
const py = findPython();
if (!py) {
console.warn("\n[claude-image-proxy] WARNING: Python 3.8+ not found.");
console.warn("\n[pixelpipe] WARNING: Python 3.8+ not found.");
console.warn(" Install Python 3 (https://www.python.org/downloads/) then run:");
console.warn(" python3 -m pip install Pillow httpx");
console.warn(" Otherwise the proxy will fail to start.\n");
@@ -37,14 +37,14 @@ const need = [];
if (!hasModule(py, "PIL")) need.push("Pillow");
if (!hasModule(py, "httpx")) need.push("httpx");
if (need.length === 0) {
console.log("[claude-image-proxy] Python deps already installed.");
console.log("[pixelpipe] Python deps already installed.");
process.exit(0);
}
console.log(`[claude-image-proxy] Installing Python deps: ${need.join(", ")}`);
console.log(`[pixelpipe] Installing Python deps: ${need.join(", ")}`);
const args = ["-m", "pip", "install", "--quiet", "--user", ...need];
const r = spawnSync(py, args, { stdio: "inherit" });
if (r.status !== 0) {
console.warn("\n[claude-image-proxy] WARNING: failed to auto-install Python deps.");
console.warn("\n[pixelpipe] WARNING: failed to auto-install Python deps.");
console.warn(` Please run manually: ${py} -m pip install ${need.join(" ")}`);
}
+4 -4
View File
@@ -430,11 +430,11 @@ def transform_request(body: bytes) -> tuple[bytes, dict]:
# Running session totals so users can see live savings.
# Persisted to ~/.cache/claude-image-proxy/stats.json on every update so
# Persisted to ~/.cache/pixelpipe/stats.json on every update so
# restarts don't wipe history. Recent feed + latest PNG stay in-memory only.
import threading, time, collections, pathlib
_STATS_DIR = pathlib.Path.home() / ".cache" / "claude-image-proxy"
_STATS_DIR = pathlib.Path.home() / ".cache" / "pixelpipe"
_STATS_FILE = _STATS_DIR / "stats.json" # cumulative totals (rewritten atomically)
_REQUESTS_FILE = _STATS_DIR / "requests.jsonl" # full per-request log (append-only)
_REQUESTS_ROTATE_BYTES = 10 * 1024 * 1024 # rotate at 10 MB
@@ -534,7 +534,7 @@ DASHBOARD_HTML = """<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>claude-image-proxy — live dashboard</title>
<title>pixelpipe — live dashboard</title>
<style>
* { box-sizing: border-box; }
body { margin: 0; padding: 24px; background: #0d1117; color: #c9d1d9;
@@ -574,7 +574,7 @@ DASHBOARD_HTML = """<!doctype html>
</style>
</head>
<body>
<h1><span class="dot"></span>claude-image-proxy</h1>
<h1><span class="dot"></span>pixelpipe</h1>
<div class="sub" id="sub">connecting...</div>
<div class="grid">
+22 -22
View File
@@ -274,28 +274,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "claude-image-proxy"
version = "0.1.0"
dependencies = [
"ab_glyph",
"anyhow",
"axum",
"base64",
"bytes",
"clap",
"dashmap",
"once_cell",
"png",
"reqwest",
"serde",
"serde_json",
"sha2",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "colorchoice"
version = "1.0.5"
@@ -962,6 +940,28 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "pixelpipe"
version = "0.1.0"
dependencies = [
"ab_glyph",
"anyhow",
"axum",
"base64",
"bytes",
"clap",
"dashmap",
"once_cell",
"png",
"reqwest",
"serde",
"serde_json",
"sha2",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "png"
version = "0.17.16"
+4 -4
View File
@@ -1,13 +1,13 @@
[package]
name = "claude-image-proxy"
name = "pixelpipe"
version = "0.1.0"
edition = "2021"
description = "Token-saving proxy for Claude Code that renders system prompt + tools as images"
license = "MIT"
repository = "https://github.com/your/claude-image-proxy"
repository = "https://github.com/your/pixelpipe"
[[bin]]
name = "claude-image-proxy"
name = "pixelpipe"
path = "src/main.rs"
[dependencies]
@@ -67,5 +67,5 @@ inherits = "release"
opt-level = "z"
[lib]
name = "claude_image_proxy"
name = "pixelpipe"
path = "src/lib.rs"
+2 -2
View File
@@ -7,8 +7,8 @@
use std::collections::BTreeMap;
use std::path::PathBuf;
use claude_image_proxy::font::AtlasFont;
use claude_image_proxy::render::render_chunks;
use pixelpipe::font::AtlasFont;
use pixelpipe::render::render_chunks;
fn main() -> anyhow::Result<()> {
let mut args = std::env::args().skip(1);
+2 -2
View File
@@ -1,8 +1,8 @@
//! Render a sample text → PNG so we can visually inspect + OCR-test.
//! Run: cargo run --example render_sample -- <output.png> [size]
use claude_image_proxy::font::AtlasFont;
use claude_image_proxy::render::render_chunks;
use pixelpipe::font::AtlasFont;
use pixelpipe::render::render_chunks;
fn main() -> anyhow::Result<()> {
let mut args = std::env::args().skip(1);
+2 -2
View File
@@ -13,8 +13,8 @@
use std::path::PathBuf;
use claude_image_proxy::font::AtlasFont;
use claude_image_proxy::transform::{transform, TransformConfig};
use pixelpipe::font::AtlasFont;
use pixelpipe::transform::{transform, TransformConfig};
use dashmap::DashMap;
fn main() -> anyhow::Result<()> {
+4 -4
View File
@@ -1,4 +1,4 @@
//! claude-image-proxy — token-saving proxy for Claude Code.
//! pixelpipe — token-saving proxy for Claude Code.
//!
//! Architecture mirrors the proven Python prototype:
//! 1. Accept HTTP from Claude Code on a local port.
@@ -20,7 +20,7 @@ mod render;
mod font;
#[derive(Parser, Debug, Clone)]
#[command(name = "claude-image-proxy", version, about, long_about = None)]
#[command(name = "pixelpipe", version, about, long_about = None)]
struct Args {
/// Port to listen on
#[arg(short, long, default_value_t = 47821)]
@@ -75,7 +75,7 @@ async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("claude_image_proxy=info,info")),
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("pixelpipe=info,info")),
)
.with_target(false)
.init();
@@ -94,7 +94,7 @@ async fn main() -> anyhow::Result<()> {
font: Arc::new(font::AtlasFont::load(font_size)?),
};
println!("claude-image-proxy v{} starting", env!("CARGO_PKG_VERSION"));
println!("pixelpipe v{} starting", env!("CARGO_PKG_VERSION"));
println!(" port: {}", port);
println!(" compression: {}", if compress { "ON" } else { "OFF (passthrough)" });
if compress {
+1 -1
View File
@@ -1,4 +1,4 @@
//! Zig 0.16 build for claude-image-proxy.
//! Zig 0.16 build for pixelpipe.
//!
//! Targets:
//! zig build # build all