mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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">
|
||||
|
||||
Generated
+22
-22
@@ -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
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<()> {
|
||||
|
||||
@@ -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
@@ -1,4 +1,4 @@
|
||||
//! Zig 0.16 build for claude-image-proxy.
|
||||
//! Zig 0.16 build for pixelpipe.
|
||||
//!
|
||||
//! Targets:
|
||||
//! zig build # build all
|
||||
|
||||
Reference in New Issue
Block a user