{"_id":"omniglyph","_rev":"8-86f5900302cd349e405d6a8cda4427a5","name":"omniglyph","dist-tags":{"latest":"1.4.0"},"versions":{"1.0.0":{"name":"omniglyph","version":"1.0.0","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"license":"MIT","_id":"omniglyph@1.0.0","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"bin":{"omniglyph":"bin/cli.js"},"dist":{"shasum":"a4ede15e593a1e3a850530fca66dbf9748c0b7a2","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.0.0.tgz","fileCount":114,"integrity":"sha512-Jz48LVU4UOtQ++kad4Pa5bNqJEqa0OfYRR7iJtsLoMgpNmnAqjAnQao/VIsh2anTurC+BLPhCthzmAjIo746iA==","signatures":[{"sig":"MEUCIQDzcN7eqAq0nt1/1zQRX5XlYXKXcLWx7NSQ4UPDfGcX2AIgA9CIKgn9CNLvqrJVIXuWwIvF1m4hbK3Df8ubHj+qJ0k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14491043},"pnpm":{"overrides":{"ws@>=8.0.0 <8.20.1":"^8.20.1","vite@>=8.0.0 <8.0.16":"^8.0.16","undici@>=7.0.0 <7.28.0":"^7.28.0","esbuild@>=0.27.3 <0.28.1":"^0.28.1"}},"type":"module","engines":{"node":">=18"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"}},"gitHead":"dbe2dd8ffe31f1c2b81065669ce63a3781d673e6","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/build.mjs","restart":"bash scripts/restart.sh","dev:node":"tsx watch src/node.ts","typecheck":"tsc --noEmit","vendor:ui":"node scripts/vendor-ui.mjs","dev:worker":"wrangler dev","test:watch":"vitest","build:atlas":"tsx scripts/gen-atlas.ts","test:restart":"bash tests/restart.test.sh","deploy:worker":"wrangler deploy","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build"},"_npmUser":{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"},"repository":{"url":"git+https://github.com/diegosouzapw/OmniGlyph.git","type":"git"},"_npmVersion":"11.13.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"gpt-tokenizer":"^3.4.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.21.0","devDependencies":{"tsx":"^4.10.0","vite":"^8.0.16","eslint":"^10.6.0","vitest":"^4.1.6","esbuild":"^0.28.1","wrangler":"^4.92.0","@eslint/js":"^10.0.1","typescript":"^5.4.0","@types/node":"^20.12.0","@napi-rs/canvas":"^0.1.53","typescript-eslint":"^8.63.0","@cloudflare/workers-types":"^4.20240512.0"},"_npmOperationalInternal":{"tmp":"tmp/omniglyph_1.0.0_1783477625990_0.6096772470909682","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"omniglyph","version":"1.0.1","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"license":"MIT","_id":"omniglyph@1.0.1","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"bin":{"omniglyph":"bin/cli.js"},"dist":{"shasum":"707945f94dc51f3f7061f58ca0a5c28f7fb828e7","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.0.1.tgz","fileCount":114,"integrity":"sha512-QC0U5mm22IoqFms4P0g4bfcF1PK2vmt28td169N+CONt0iPmpbFaQwZBz0IrmOYMFR84DaoVkg9Jm2zJ4lBWXQ==","signatures":[{"sig":"MEUCIBB+i9ATZV0aqH/cl86p27vBssByYjaFZpFZ6NccCvO2AiEAyelpbKckDhDuSX1bdxes9EvKk7eeBEFJrdIdis8habs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14494538},"pnpm":{"overrides":{"ws@>=8.0.0 <8.20.1":"^8.20.1","vite@>=8.0.0 <8.0.16":"^8.0.16","undici@>=7.0.0 <7.28.0":"^7.28.0","esbuild@>=0.27.3 <0.28.1":"^0.28.1"}},"type":"module","engines":{"node":">=18"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"}},"gitHead":"a895d6f672f0041715c69451c24263ab6752b266","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/build.mjs","restart":"bash scripts/restart.sh","dev:node":"tsx watch src/node.ts","typecheck":"tsc --noEmit","vendor:ui":"node scripts/vendor-ui.mjs","dev:worker":"wrangler dev","test:watch":"vitest","build:atlas":"tsx scripts/gen-atlas.ts","test:restart":"bash tests/restart.test.sh","deploy:worker":"wrangler deploy","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build"},"_npmUser":{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"},"repository":{"url":"git+https://github.com/diegosouzapw/OmniGlyph.git","type":"git"},"_npmVersion":"11.13.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"gpt-tokenizer":"^3.4.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.21.0","devDependencies":{"tsx":"^4.10.0","vite":"^8.0.16","eslint":"^10.6.0","vitest":"^4.1.6","esbuild":"^0.28.1","wrangler":"^4.92.0","@eslint/js":"^10.0.1","typescript":"^5.4.0","@types/node":"^20.12.0","@napi-rs/canvas":"^0.1.53","typescript-eslint":"^8.63.0","@cloudflare/workers-types":"^4.20240512.0"},"_npmOperationalInternal":{"tmp":"tmp/omniglyph_1.0.1_1783514183343_0.48379475285785345","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"omniglyph","version":"1.0.2","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"license":"MIT","_id":"omniglyph@1.0.2","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"bin":{"omniglyph":"bin/cli.js"},"dist":{"shasum":"aa6c45bc3e02a48cb9df9980c6afffe91eea8111","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.0.2.tgz","fileCount":114,"integrity":"sha512-GGLet99n3HVxOx3WuNPda4B0ETptX9SA8h1fnm/AYSXmvsKXE3mN11Ae2jfX8ldAOA/rVJRXHzPhNkXsRHzMsg==","signatures":[{"sig":"MEUCIAer+xn+iIDI3bLW7HdaxvHBcSCQU4OFvCBgbs5eNyTOAiEAouWw40LD8hNntvGsWAQso640rm5LvvCr0XNNRkd4epU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/omniglyph@1.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":14494538},"pnpm":{"overrides":{"ws@>=8.0.0 <8.20.1":"^8.20.1","vite@>=8.0.0 <8.0.16":"^8.0.16","undici@>=7.0.0 <7.28.0":"^7.28.0","esbuild@>=0.27.3 <0.28.1":"^0.28.1"}},"type":"module","engines":{"node":">=18"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"}},"gitHead":"617cce2f9ce4d8d21be5e93f2d03dd5b42283316","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/build.mjs","restart":"bash scripts/restart.sh","dev:node":"tsx watch src/node.ts","typecheck":"tsc --noEmit","vendor:ui":"node scripts/vendor-ui.mjs","dev:worker":"wrangler dev","test:watch":"vitest","build:atlas":"tsx scripts/gen-atlas.ts","test:restart":"bash tests/restart.test.sh","deploy:worker":"wrangler deploy","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:018bce3f-4767-41f1-90e9-fb13f4412905"}},"repository":{"url":"git+https://github.com/diegosouzapw/OmniGlyph.git","type":"git"},"_npmVersion":"11.18.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"gpt-tokenizer":"^3.4.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.21.0","devDependencies":{"tsx":"^4.10.0","vite":"^8.0.16","eslint":"^10.6.0","vitest":"^4.1.6","esbuild":"^0.28.1","wrangler":"^4.92.0","@eslint/js":"^10.0.1","typescript":"^5.4.0","@types/node":"^20.12.0","@napi-rs/canvas":"^0.1.53","typescript-eslint":"^8.63.0","@cloudflare/workers-types":"^4.20240512.0"},"_npmOperationalInternal":{"tmp":"tmp/omniglyph_1.0.2_1783516067231_0.4861371605071876","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"omniglyph","version":"1.1.0","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"license":"MIT","_id":"omniglyph@1.1.0","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"bin":{"omniglyph":"bin/cli.js"},"dist":{"shasum":"e087473d0883ee02cf0ef4756ffa7a1ae469ee9c","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.1.0.tgz","fileCount":118,"integrity":"sha512-H7kCagbT2S9QTBBOEv7Ah5odL7sxkevc2g0MP8sYkmT+1fGNsAzGLfnnThHUvQY3UnndiDl1DyV3pb/25ltpEg==","signatures":[{"sig":"MEUCICGgaRCq/ShqBJzzoga8SfHg6jG8x+CGeGcEvvBvTqGmAiEAxUKI8UFP0MUE2J9EuQg4jQg2Y9rf9u/Bkw6XOx+7NI0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/omniglyph@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":15621635},"pnpm":{"overrides":{"ws@>=8.0.0 <8.20.1":"^8.20.1","vite@>=8.0.0 <8.0.16":"^8.0.16","undici@>=7.0.0 <7.28.0":"^7.28.0","esbuild@>=0.27.3 <0.28.1":"^0.28.1"}},"type":"module","engines":{"node":">=18"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"}},"gitHead":"a4eabf47d4bbea4a80683dda7b6f9cf1013da202","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/build.mjs","restart":"bash scripts/restart.sh","dev:node":"tsx watch src/node.ts","typecheck":"tsc --noEmit","vendor:ui":"node scripts/vendor-ui.mjs","dev:worker":"wrangler dev","test:watch":"vitest","build:atlas":"tsx scripts/gen-atlas.ts","test:restart":"bash tests/restart.test.sh","deploy:worker":"wrangler deploy","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:018bce3f-4767-41f1-90e9-fb13f4412905"}},"repository":{"url":"git+https://github.com/diegosouzapw/OmniGlyph.git","type":"git"},"_npmVersion":"11.18.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"gpt-tokenizer":"^3.4.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.21.0","devDependencies":{"tsx":"^4.10.0","vite":"^8.0.16","eslint":"^10.6.0","vitest":"^4.1.6","esbuild":"^0.28.1","wrangler":"^4.92.0","@eslint/js":"^10.0.1","typescript":"^5.4.0","@types/node":"^20.12.0","@napi-rs/canvas":"^0.1.53","typescript-eslint":"^8.63.0","@cloudflare/workers-types":"^4.20240512.0"},"_npmOperationalInternal":{"tmp":"tmp/omniglyph_1.1.0_1783545095275_0.38486636185400114","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"omniglyph","version":"1.2.0","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"license":"MIT","_id":"omniglyph@1.2.0","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"bin":{"omniglyph":"bin/cli.js"},"dist":{"shasum":"bf156c316695ad0e8a40640b8d7cfe60a6fc9d48","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.2.0.tgz","fileCount":118,"integrity":"sha512-JSWCa9JZfW/DOH8wM8Hb915N7EqzvVP/9dvJzusrADx8KuDxWD+mG+o+1dJaFFOKDW8QRXsRQzEMuqKqAg/E0Q==","signatures":[{"sig":"MEUCIQDCkRLR0VObjayW30sR3SbzWuIPK6OgGxiFlBr1X3Bl5wIgQIflINc7TmK0QuiKTRcNeneWGMpb69DLF2vPh9mRcjI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/omniglyph@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":15623505},"pnpm":{"overrides":{"ws@>=8.0.0 <8.20.1":"^8.20.1","vite@>=8.0.0 <8.0.16":"^8.0.16","undici@>=7.0.0 <7.28.0":"^7.28.0","esbuild@>=0.27.3 <0.28.1":"^0.28.1"}},"type":"module","engines":{"node":">=18"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"}},"gitHead":"02a19f5da8f28f7be82b0bed84a97b56e0bb4047","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/build.mjs","restart":"bash scripts/restart.sh","dev:node":"tsx watch src/node.ts","typecheck":"tsc --noEmit","vendor:ui":"node scripts/vendor-ui.mjs","dev:worker":"wrangler dev","test:watch":"vitest","build:atlas":"tsx scripts/gen-atlas.ts","test:restart":"bash tests/restart.test.sh","deploy:worker":"wrangler deploy","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:018bce3f-4767-41f1-90e9-fb13f4412905"}},"repository":{"url":"git+https://github.com/diegosouzapw/OmniGlyph.git","type":"git"},"_npmVersion":"11.16.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"gpt-tokenizer":"^3.4.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.21.0","devDependencies":{"tsx":"^4.10.0","vite":"^8.0.16","eslint":"^10.6.0","vitest":"^4.1.6","esbuild":"^0.28.1","wrangler":"^4.92.0","@eslint/js":"^10.0.1","typescript":"^5.4.0","@types/node":"^20.12.0","@napi-rs/canvas":"^0.1.53","typescript-eslint":"^8.63.0","@cloudflare/workers-types":"^4.20240512.0"},"_npmOperationalInternal":{"tmp":"tmp/omniglyph_1.2.0_1783549933727_0.5595412023316231","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"omniglyph","version":"1.3.0","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"license":"MIT","_id":"omniglyph@1.3.0","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"bin":{"omniglyph":"bin/cli.js"},"dist":{"shasum":"d9783635ea03ab4a5b2d7aae5bfb873ff453c89e","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.3.0.tgz","fileCount":122,"integrity":"sha512-gGbZ2D23Ljny6xida++PN6mhn3MKiO+oH1FgwzQ0DZ/Gzn9coG0e0Zx/hZDDT34ScXcf8r9/BGDNEYSuQpD+dg==","signatures":[{"sig":"MEQCIAkC3W4IXCWnwHlgBDSOiLB50S+qPfP/naeaZKJBKSQoAiBQnAyolMszOj69WyiRzisx3ucJgPcThEydmXxx9AiHkg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/omniglyph@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":15783503},"pnpm":{"overrides":{"ws@>=8.0.0 <8.20.1":"^8.20.1","vite@>=8.0.0 <8.0.16":"^8.0.16","undici@>=7.0.0 <7.28.0":"^7.28.0","esbuild@>=0.27.3 <0.28.1":"^0.28.1"}},"type":"module","engines":{"node":">=18"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"}},"gitHead":"cac0a91e31440ef309bab23de4a7bc600bb1a736","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/build.mjs","restart":"bash scripts/restart.sh","dev:node":"tsx watch src/node.ts","typecheck":"tsc --noEmit","vendor:ui":"node scripts/vendor-ui.mjs","dev:worker":"wrangler dev","test:watch":"vitest","build:atlas":"tsx scripts/gen-atlas.ts","test:restart":"bash tests/restart.test.sh","deploy:worker":"wrangler deploy","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:018bce3f-4767-41f1-90e9-fb13f4412905"}},"repository":{"url":"git+https://github.com/diegosouzapw/OmniGlyph.git","type":"git"},"_npmVersion":"11.16.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"gpt-tokenizer":"^3.4.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.21.0","devDependencies":{"tsx":"^4.10.0","vite":"^8.0.16","eslint":"^10.6.0","vitest":"^4.1.6","esbuild":"^0.28.1","wrangler":"^4.92.0","@eslint/js":"^10.0.1","typescript":"^5.4.0","@types/node":"^20.12.0","@napi-rs/canvas":"^0.1.53","typescript-eslint":"^8.63.0","@cloudflare/workers-types":"^4.20240512.0"},"_npmOperationalInternal":{"tmp":"tmp/omniglyph_1.3.0_1783888962121_0.16345325605236494","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"omniglyph","version":"1.3.1","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"license":"MIT","_id":"omniglyph@1.3.1","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"bin":{"omniglyph":"bin/cli.js"},"dist":{"shasum":"49c87d98f44e1d3a6bdb65d096752bad83b9f662","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.3.1.tgz","fileCount":122,"integrity":"sha512-6QnZCoXYczjsPN2x+XpbimimjO6kCoSZUzsdSvoKjtw28U1U724VgLICBNaLX4FFs5jd7SrYNNs9Aee2iIkcoA==","signatures":[{"sig":"MEQCIC9HmsaA67aNZwABEe2C5V5+1iAsY0q7//r9+snIHDeNAiBFov8cBkJERnABNKzH0G735Vx8YszCKHsjDS91/cLh2Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/omniglyph@1.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":15784391},"pnpm":{"overrides":{"ws@>=8.0.0 <8.20.1":"^8.20.1","vite@>=8.0.0 <8.0.16":"^8.0.16","undici@>=7.0.0 <7.28.0":"^7.28.0","esbuild@>=0.27.3 <0.28.1":"^0.28.1"}},"type":"module","engines":{"node":">=18"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"}},"gitHead":"c9ed17b882b82593cf57d52256106ea859cfe339","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/build.mjs","restart":"bash scripts/restart.sh","dev:node":"tsx watch src/node.ts","typecheck":"tsc --noEmit","vendor:ui":"node scripts/vendor-ui.mjs","dev:worker":"wrangler dev","test:watch":"vitest","build:atlas":"tsx scripts/gen-atlas.ts","test:restart":"bash tests/restart.test.sh","deploy:worker":"wrangler deploy","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:018bce3f-4767-41f1-90e9-fb13f4412905"}},"repository":{"url":"git+https://github.com/diegosouzapw/OmniGlyph.git","type":"git"},"_npmVersion":"11.16.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"gpt-tokenizer":"^3.4.0"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.21.0","devDependencies":{"tsx":"^4.10.0","vite":"^8.0.16","eslint":"^10.6.0","vitest":"^4.1.6","esbuild":"^0.28.1","wrangler":"^4.92.0","@eslint/js":"^10.0.1","typescript":"^5.4.0","@types/node":"^20.12.0","@napi-rs/canvas":"^0.1.53","typescript-eslint":"^8.63.0","@cloudflare/workers-types":"^4.20240512.0"},"_npmOperationalInternal":{"tmp":"tmp/omniglyph_1.3.1_1783894825020_0.1615086187598851","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"omniglyph","version":"1.4.0","description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","type":"module","bin":{"omniglyph":"bin/cli.js"},"exports":{".":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./transform":{"types":"./dist/core/library.d.ts","import":"./dist/core/library.js"},"./measurement":{"types":"./dist/core/measurement.d.ts","import":"./dist/core/measurement.js"},"./applicability":{"types":"./dist/core/applicability.d.ts","import":"./dist/core/applicability.js"},"./proxy":{"types":"./dist/core/proxy.d.ts","import":"./dist/core/proxy.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./worker":{"types":"./dist/worker.d.ts","import":"./dist/worker.js"}},"scripts":{"build":"node scripts/build.mjs","build:atlas":"tsx scripts/gen-atlas.ts","dev:node":"tsx watch src/node.ts","dev:worker":"wrangler dev","deploy:worker":"wrangler deploy","restart":"bash scripts/restart.sh","typecheck":"tsc --noEmit","lint":"eslint .","test":"vitest run","test:watch":"vitest","test:restart":"bash tests/restart.test.sh","prepublishOnly":"pnpm run lint && pnpm run typecheck && pnpm test && pnpm run build","vendor:ui":"node scripts/vendor-ui.mjs"},"keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"engines":{"node":">=18"},"packageManager":"pnpm@10.21.0","license":"MIT","devDependencies":{"@cloudflare/workers-types":"^4.20240512.0","@eslint/js":"^10.0.1","@napi-rs/canvas":"^0.1.53","@types/node":"^20.12.0","esbuild":"^0.28.1","eslint":"^10.6.0","tsx":"^4.10.0","typescript":"^5.4.0","typescript-eslint":"^8.63.0","vite":"^8.0.16","vitest":"^4.1.6","wrangler":"^4.92.0"},"dependencies":{"gpt-tokenizer":"^3.4.0"},"repository":{"type":"git","url":"git+https://github.com/diegosouzapw/OmniGlyph.git"},"homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"gitHead":"2b340109e3a50909b657f3319feb5056bb925736","_id":"omniglyph@1.4.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-4zAqDW9pBb2i+fiGOVLIKbdecZeo55UmKQoLku1apxo3TSA4gfqcMo2MqQpal1VicckUwTbexFLasW7qngXUHA==","shasum":"7ba027b78bd609b7055ff656ec41df466c96ffa3","tarball":"https://registry.npmjs.org/omniglyph/-/omniglyph-1.4.0.tgz","fileCount":128,"unpackedSize":15830381,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/omniglyph@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAwdXybVQp3AqB29502pAn3P1icW7BT9m2y483VFQESpAiBuxe+8Y8ybY3jPbnsZ4nVc0Xu6D/GfR0EgfnV2/tvbYA=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:018bce3f-4767-41f1-90e9-fb13f4412905"}},"directories":{},"maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/omniglyph_1.4.0_1787010640530_0.1952545519393294"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-08T02:27:05.809Z","modified":"2026-08-17T23:50:41.069Z","1.0.0":"2026-07-08T02:27:06.239Z","1.0.1":"2026-07-08T12:36:23.572Z","1.0.2":"2026-07-08T13:07:47.512Z","1.1.0":"2026-07-08T21:11:35.631Z","1.2.0":"2026-07-08T22:32:13.995Z","1.3.0":"2026-07-12T20:42:42.341Z","1.3.1":"2026-07-12T22:20:25.303Z","1.4.0":"2026-08-17T23:50:40.775Z"},"bugs":{"url":"https://github.com/diegosouzapw/OmniGlyph/issues"},"license":"MIT","homepage":"https://github.com/diegosouzapw/OmniGlyph#readme","keywords":["omniglyph","omniroute","claude","claude-code","anthropic","openai","gemini","proxy","token-optimization","prompt-cache","vision-tokens","optical-context-compression"],"repository":{"type":"git","url":"git+https://github.com/diegosouzapw/OmniGlyph.git"},"description":"Context-as-image compression proxy for LLMs: renders bulky context (system prompt, tool docs, history) as dense PNG pages with exact per-provider billing math (Anthropic/OpenAI/Gemini). Node and Cloudflare Workers. Part of the OmniRoute family.","maintainers":[{"name":"diegosouza.pw","email":"diegosouza.pw@outlook.com"}],"readme":"<div align=\"center\">\n\n<img src=\"./docs/assets/example-render.png\" alt=\"A real render: system prompt + tool docs packed into one dense 1568×728 page\" width=\"520\"/>\n\n<br/>\n\n# 🖼️ OmniGlyph — Context as Image\n\n### Cut your Claude bill by **59–70%** by rendering bulky context as dense PNG pages — the same content, in a fraction of the tokens.\n\n**Models bill text per token, but bill an image by its dimensions — not by how much text is inside it.**\n\n<br/>\n\n[![59–70% Bill Cut](https://img.shields.io/badge/59--70%25-Bill_Cut-00B894?style=for-the-badge)](#-the-numbers--measured-not-estimated)\n[![10x Fewer Tokens](https://img.shields.io/badge/10%C3%97-Fewer_Tokens-6C5CE7?style=for-the-badge)](benchmarks/billing-sweep/README.md)\n[![100% Read Accuracy](https://img.shields.io/badge/100%25-Read_Accuracy-0984E3?style=for-the-badge)](benchmarks/density-frontier/README.md)\n[![Zero Confabulations](https://img.shields.io/badge/0-Silent_Confabulations-E17055?style=for-the-badge)](#-the-honest-part)\n\n[![CI](https://github.com/diegosouzapw/OmniGlyph/actions/workflows/ci.yml/badge.svg)](https://github.com/diegosouzapw/OmniGlyph/actions/workflows/ci.yml)\n[![npm version](https://img.shields.io/npm/v/omniglyph?style=flat-square)](https://www.npmjs.com/package/omniglyph)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE)\n[![Node ≥18](https://img.shields.io/badge/node-%E2%89%A518-339933?style=flat-square&logo=node.js&logoColor=white)](package.json)\n\nPart of the [**OmniRoute**](https://github.com/diegosouzapw/OmniRoute) family · [🌐 All languages](docs/i18n/README.md)\n\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"README.md\">🇺🇸</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/ar/README.md\">🇸🇦</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/az/README.md\">🇦🇿</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/bg/README.md\">🇧🇬</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/bn/README.md\">🇧🇩</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/cs/README.md\">🇨🇿</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/da/README.md\">🇩🇰</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/de/README.md\">🇩🇪</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/es/README.md\">🇪🇸</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/fa/README.md\">🇮🇷</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/fi/README.md\">🇫🇮</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/fr/README.md\">🇫🇷</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/gu/README.md\">🇮🇳</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/he/README.md\">🇮🇱</a></td>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"docs/i18n/hi/README.md\">🇮🇳</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/hu/README.md\">🇭🇺</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/id/README.md\">🇮🇩</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/it/README.md\">🇮🇹</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/ja/README.md\">🇯🇵</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/ko/README.md\">🇰🇷</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/mr/README.md\">🇮🇳</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/ms/README.md\">🇲🇾</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/nl/README.md\">🇳🇱</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/no/README.md\">🇳🇴</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/phi/README.md\">🇵🇭</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/pl/README.md\">🇵🇱</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/pt/README.md\">🇵🇹</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/pt-BR/README.md\">🇧🇷</a></td>\n  </tr>\n  <tr>\n    <td align=\"center\"><a href=\"docs/i18n/ro/README.md\">🇷🇴</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/ru/README.md\">🇷🇺</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/sk/README.md\">🇸🇰</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/sv/README.md\">🇸🇪</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/sw/README.md\">🇰🇪</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/ta/README.md\">🇮🇳</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/te/README.md\">🇮🇳</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/th/README.md\">🇹🇭</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/tr/README.md\">🇹🇷</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/uk-UA/README.md\">🇺🇦</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/ur/README.md\">🇵🇰</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/vi/README.md\">🇻🇳</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/zh-CN/README.md\">🇨🇳</a></td>\n    <td align=\"center\"><a href=\"docs/i18n/zh-TW/README.md\">🇹🇼</a></td>\n  </tr>\n</table>\n\n</div>\n\n![chart: characters a frontier context window holds, 2018–2026 — every vendor line tops out near the ~4M chars a 1M-token window holds as text; the same Fable 5 1M window through OmniGlyph images holds a measured ~18M chars, 4.54× the text ceiling](docs/assets/context-window-chars.png)\n\n*Eight years of context growth, in characters. Every text line tops out near\n~4M chars (a 1M-token window at ~4 chars/token); the orange point is the\n**same Fable 5 1M window** read through OmniGlyph images — ~18M chars at the\nmeasured 18.16 chars/vision-token, **4.54×** the text ceiling. The density and\nmultiplier are measured from a live render at generation time, not hand-typed:\nregenerate with `npx tsx scripts/gen-context-chart.ts`\n([source](scripts/gen-context-chart.ts)).*\n\n---\n\n# 📊 The numbers — measured, not estimated\n\n| metric | result | receipt |\n|---|---|---|\n| End-to-end bill reduction | **59–70%** | production trace, 13,709 requests |\n| Tokens per converted block | **10× fewer** (28,080 chars: 14,040 → 1,460 tokens) | [billing sweep](benchmarks/billing-sweep/README.md) |\n| Billing-formula accuracy | residual **zero** across 22 `count_tokens` probes, 2 models × 2 tiers | `benchmarks/billing-sweep/results/` |\n| Exact-read accuracy, production config | **30/30 (100%)** on Claude Fable 5 | [density frontier](benchmarks/density-frontier/README.md) |\n| Silent confabulations in ~300 read probes | **0** — every miss abstains as `ILEGIVEL` | `benchmarks/density-frontier/results/` |\n\n**Model scorecard** (can it read dense renders? n=30 per arm, deterministic scoring):\n\n| model | reading | verdict |\n|---|---|---|\n| Claude **Fable 5** | **100%** exact | ✅ production target |\n| Claude Opus 4.8 | 77–87% at 4× glyph size | ⚠️ opt-in safe mode (savings drop to ~2×) |\n| GPT-5.5 | 0/60 — and inflates its answers ~40× trying | ❌ blocked by the gate, with proof |\n| Gemini 2.5-flash | 0/26 — and confabulates instead of abstaining | ❌ blocked (partial test, quota-limited) |\n\nThe advantage is **Fable-specific today** — other vision encoders don't resolve dense glyphs yet. The [benchmark harness](benchmarks/README.md) re-tests any new model in one command.\n\n# 🤔 Why OmniGlyph?\n\nEvery long-running agent session drags the same dead weight on every request: the system prompt, tool docs, and old history — re-billed per token, every turn. OmniGlyph is a **local proxy** that rewrites those bulky parts into dense PNG pages *before they leave your machine*:\n\n- **Exact billing math, not heuristics** — it computes the provider's real image-token formula (measured to residual zero) and converts only when the math wins.\n- **Fail-closed by design** — models that can't read dense renders are blocked by a gate, with benchmark receipts. No silent quality loss.\n- **Private & local-first** — the rewrite happens on `127.0.0.1`; nothing extra is sent anywhere.\n- **Reproducible** — every number above has a receipt in `benchmarks/*/results/`, re-runnable in one command.\n\n# ⚡ Quick Start\n\n```bash\nnpx omniglyph                                     # proxy on 127.0.0.1:47821\nANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude  # point Claude Code at it\n```\n\n![Quickstart: start the proxy, check the dashboard, point Claude Code at it](docs/assets/demo-quickstart.gif)\n\nWorks both ways:\n- **API key** (pay per token): your bill drops 59–70% end-to-end.\n- **Subscription session**: you don't pay less, but usage limits are counted in tokens — so your limits stretch **~2–3×**.\n\nDashboard at <http://127.0.0.1:47821/>: tokens saved, every text→image conversion side by side, kill switch, live model chips. Responses stream normally — only the *request* is compressed, never the model's output.\n\n# 🔌 Use with Claude clients\n\nStart the proxy in one terminal, then point the client at it.\n\n**Claude Code CLI (macOS/Linux):**\n\n```bash\nnpx omniglyph\nANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude\n```\n\n**Claude Code CLI (Windows PowerShell):**\n\n```powershell\nnpx omniglyph\n$env:ANTHROPIC_BASE_URL = \"http://127.0.0.1:47821\"\nclaude\n```\n\n**Claude Desktop** uses the same `ANTHROPIC_BASE_URL` environment variable for its bundled Claude Code runtime — start `omniglyph` first, then launch Claude Desktop from an environment where `ANTHROPIC_BASE_URL` is set to `http://127.0.0.1:47821`.\n\n# 🖥️ The dashboard\n\nA full local dashboard ships inside the package — offline, single-file, zero external requests. Six pages, updated live over SSE as requests flow:\n\n![Overview: mission-control KPI cards, savings sparkline and live event feed](docs/assets/dashboard-overview.png)\n\n- **Overview** — mission control: savings %, $ saved, latency p95, cache hits, errors, live feed.\n- **Live Flow** — the pipeline as a node graph: client → gate → renderer / passthrough → API, with a particle per real request.\n- **Telemetry** — a token/$ odometer and a live request timeline; click any request to see exactly which parts became images and read the source text behind every page.\n- **Benchmarks** — the harness receipts rendered from `benchmarks/*/results/`, one row per model·config experiment, and **run the benchmarks from the UI**: `$0` dry-runs stream their output live; live runs stay gated behind your API key plus an explicit cost confirmation.\n- **Sessions / History** — top sessions by tokens saved and every event on disk.\n\n| Live Flow | Benchmarks |\n|---|---|\n| ![The request pipeline as a live node graph](docs/assets/dashboard-flow.png) | ![Benchmark receipts and in-UI dry-runs](docs/assets/dashboard-benchmarks.png) |\n\n![Telemetry: odometer and live request timeline](docs/assets/dashboard-telemetry.png)\n\n# ⚙️ How it works\n\n```\nbulky request block ──► profitability gate ──► reflow + render (1-bit 5×8 atlas)\n                       (exact billing math)     ──► 1568×728 PNG pages ──► splice back, cache-friendly\n```\n\n- **Billing is computed exactly, before converting**: Anthropic bills `⌈w/28⌉ × ⌈h/28⌉ + 4` tokens per image (28 px patches — measured to residual zero). A full page carries 28,080 chars for 1,460 tokens ≈ **19 chars/token**, vs ~2 chars/token for dense text. The gate converts only when the math wins.\n- **What converts**: the static system prompt + tool docs, old collapsed history, large tool outputs.\n- **What never converts**: your messages, recent turns, the model's output, sparse prose, byte-exact values (hashes/IDs ride alongside as text), and any model that failed the reading benchmark.\n\n### Opt-in flags\n\nAll off by default — the compression path above is unchanged unless you set them. `omniglyph --help` lists every flag.\n\n- `OMNIGLYPH_GUARD_SECRETS=text|redact` — keep API keys, tokens, and other credentials out of rendered images: `text` never images a block that holds one, `redact` masks it in place. Never alters what the upstream API receives.\n- `OMNIGLYPH_PROFILE=coding-safe|balanced|aggressive|passthrough` — choose a semantic compression boundary. `coding-safe` keeps authority, schemas, live tool state, and a 12-turn tail native; `balanced` protects an 8-turn tail; `aggressive` is the unchanged default; `passthrough` routes without transforming.\n- `OMNIGLYPH_KEEP_SYSTEM_TEXT=1` — never image the session config (system prompt, tool docs, reminders); tool outputs and old history still convert. Guards against Anthropic's refusal classifier on system-shaped images.\n- `OMNIGLYPH_MODELS` — comma-separated model bases to image (default `claude-fable-5,gpt-5.6`; `off` disables). **Grok** is supported opt-in on the OpenAI-compatible wire but stays fail-closed: text-only until acked via `OMNIGLYPH_UNVERIFIED_MODELS=grok-4.5`, pending its own reading receipt.\n\n# 📚 Library use (no proxy)\n\nEverything the proxy does per request is also a documented, importable API:\n\n```ts\nimport { renderTextToImages, transformAnthropicMessages } from \"omniglyph\";\n\n// Render any text to dense 1-bit PNG pages\nconst { pages } = await renderTextToImages(bigToolOutput, { reflow: true });\n// pages[i].png: Uint8Array · pages[i].width × pages[i].height\n\n// Or run the full request transform yourself — gate, billing math and all\nconst { body, applied, reason } = await transformAnthropicMessages({\n  body: requestBytes,           // the raw /v1/messages JSON body\n  model: \"claude-fable-5\",\n});\n```\n\n`options.keepSharp(block)` pins blocks as text; `options.emitRecoverable` returns the originals of imaged blocks. The exact billing math ships at the package root too (`anthropicImageTokens`, `resolveAnthropicVisionTier`, `openAIVisionTokens`) — that is what [OmniRoute](https://github.com/diegosouzapw/OmniRoute) consumes. Pure-JS runtime (Node and edge/Workers). Full surface: `src/core/index.ts`.\n\n# 📤 Offline export — no proxy, no Claude Code\n\nNot on Claude Code? Render the context to PNG pages **locally** and paste them into Cursor, ChatGPT, or any chat that accepts image uploads. No proxy, no API key, no account wired up:\n\n```bash\nnpx omniglyph export --include \"*.ts\" src/   # render a folder to image pages\ncat big.log | npx omniglyph export --stdin   # …or pipe any text through\n```\n\nYou get one folder with everything to drop into the chat:\n\n```\nOmniGlyph-export-<hash>/\n  page-001.png …   the rendered image pages — attach these\n  factsheet.txt    verbatim precision tokens (paths, SHAs, ids, numbers)\n  prompt.txt       a paste-ready instruction that points the model at the pages\n  manifest.json    metadata + the text-vs-image token report (% saved)\n```\n\n`--git` renders your uncommitted diff, `--diff <ref>` a commit range, `--open` reveals the folder (macOS). It all runs on your machine — the export path never starts the proxy and never calls a model. Run `omniglyph export --help` for every flag.\n\n# 🧭 The honest part\n\n- **It is lossy.** Byte-exact recall from images is unreliable by nature. Mitigations shipped: exact identifiers travel as text next to the image, and the measured production config produced **zero silent confabulations** — failed reads abstain.\n- **Only Fable 5 is approved today**, with receipts. GPT-5.5 and Gemini 2.5-flash measurably cannot read dense renders; Opus 4.8 needs 4× bigger glyphs. The gate enforces this.\n- **We found and avoided a billing trap**: the high-resolution image tier bills 3.3× more per page, but the vision encoder doesn't receive the extra resolution — bigger pages read *worse*. Measured, documented in [docs/benchmarks/BENCHMARKS.md](docs/benchmarks/BENCHMARKS.md), not enabled.\n- Prices change; the durable metric is the token cut, which the proxy logs per request against a free `count_tokens` counterfactual.\n\n# 🧠 FAQ\n\n**I enabled it mid-session and my usage spiked — why?**\nA session that ran without OmniGlyph has its entire prefix cached by Anthropic as text at the 0.1× read rate; the first imaged request would re-pay all of it as a fresh 1.25× cache write in a single prompt. The proxy guards against this: a session it has never imaged feeds that one-prompt cost into the break-even gate and only switches to images when it still wins — otherwise the session stays as text, and the savings start with your next new session.\n\n**Is the 59–70% end-to-end, or only on the requests it touched?**\nEnd-to-end — the whole bill. Most compression tools report savings only on the slice they touched, which flatters the number. Our denominator is *every* request: the small ones the gate correctly left untouched, all cache writes and reads, and all output tokens (which the proxy never compresses). Compressed-only runs higher and is quoted separately, never as the headline.\n\n**How is the saving measured?**\nBoth sides of the same request, at the same moment. For every `/v1/messages` POST the proxy fires a free `count_tokens` probe on the original uncompressed body (the counterfactual) in parallel with the real forward, and reads the provider's actually-billed usage block off the response — both land in the same event row. Cache pricing is applied identically to both sides, so the caching discount cancels and can't be double-counted as \"savings\". The formula lives in `src/core/baseline.ts`; re-derive it from your own events log.\n\n**Why would a miss be a confabulation instead of a read error?**\nBecause model vision is not OCR: the page becomes patch embeddings, never discrete characters, so there is no per-glyph confidence to fail loudly on — when pixels underdetermine a glyph, the language prior fills the gap with something plausible. That mechanism is exactly why OmniGlyph is fail-closed about it: byte-exact values always ride as text next to the image, models that misread are blocked by the gate, and the measured production config produced **zero** silent confabulations in ~300 read probes — failed reads abstain.\n\n**What about byte-exact work (hashes, IDs, secrets)?**\nRecent turns and exact identifiers stay text by design. For workloads that are *all* byte-exact, route them to a non-allowlisted model (e.g. a subagent on another Claude model) — anything outside the allowlist passes through byte-identical, untouched.\n\n**Didn't DeepSeek-OCR settle whether this works?**\nIt proved the *channel* works — with an encoder/decoder pair trained for the job. The skepticism dates from when no stock production model could read dense renders; that changed, and the [model scorecard](#-the-numbers--measured-not-estimated) above shows exactly who reads them today, with receipts. The [benchmark harness](benchmarks/README.md) re-tests any new model in one command — the gate follows the data, not the hype.\n\n**Can I use it without Claude Code — Cursor, ChatGPT, a plain pipe?**\nYes, two ways. As a **proxy** it works with any client that lets you set the API base URL (`ANTHROPIC_BASE_URL`, or the OpenAI base URL) — Claude Code, your own scripts, anything HTTP. And for tools that can't proxy, the **Offline export** above renders the context to PNG pages you paste in by hand — `omniglyph export --stdin` even reads straight from a Unix pipe.\n\n**A client feature (like Claude Code's `/remote-control`) disappears when I point it at the proxy — is that OmniGlyph?**\nNo. A few client features gate themselves on a *first-party* connection — and on which auth source is set — inside the client itself, before any request ever reaches a proxy. So they can hide, or refuse to pair, behind *any* `ANTHROPIC_BASE_URL` proxy, not just OmniGlyph, and nothing the proxy returns can switch them back on. Run those features on a direct, no-proxy session.\n\n**How does it actually turn text into an image?**\nIt reflows the text and paints it with a 1-bit 5×8 pixel glyph atlas onto dense 1568×728 PNG pages — one bit per pixel, no anti-aliasing, so the model bills the page by its dimensions, not by how many characters are inside. **How it works** above has the pipeline; the benchmarks doc has the geometry and why denser isn't always cheaper.\n\n# 🔬 Reproduce every number\n\n```bash\npnpm install && pnpm test                                     # full suite\nnode benchmarks/billing-sweep/run.mjs --dry-run               # billing predictions, $0\npnpm exec tsx benchmarks/density-frontier/run.ts --dry-run    # cost table, $0\n# with keys: ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY (or --via-cli for a Claude Code subscription)\n```\n\n![The two benchmark harnesses running in dry-run mode](docs/assets/demo-benchmarks.gif)\n\nFull methodology and every result table: [docs/benchmarks/BENCHMARKS.md](docs/benchmarks/BENCHMARKS.md). Raw per-answer receipts: `benchmarks/*/results/*.jsonl`.\n\n# 🚀 The OmniRoute family\n\nOmniGlyph also ships as a **native compression engine inside [OmniRoute](https://github.com/diegosouzapw/OmniRoute)** — the free AI gateway. There it runs as the `omniglyph` engine (standalone single mode or stacked with the other engines), with fail-closed gates and image-aware token accounting.\n\n# 🛠️ Tech Stack\n\n| layer | tech |\n|---|---|\n| Language | TypeScript (strict), ESM |\n| Runtime | Node ≥18 · Cloudflare Workers (`wrangler.toml`) |\n| Rendering | own 1-bit glyph atlas (Spleen/Unifont-derived, licenses in `assets/`) → PNG |\n| Tests | Vitest — TDD, plus docs-integrity and rebrand guards |\n| Benchmarks | `benchmarks/` harnesses (billing-sweep, density-frontier) with JSONL receipts |\n\n## Project layout\n\n| path | what |\n|---|---|\n| `src/` | the proxy: transform pipeline, exact billing per provider, renderer, hosts (Node + Cloudflare Workers) |\n| `benchmarks/` | the harnesses that produced every number above — re-runnable |\n| `docs/` | [BENCHMARKS](docs/benchmarks/BENCHMARKS.md) · [ARCHITECTURE](docs/architecture/ARCHITECTURE.md) · [ROADMAP](docs/ROADMAP.md) |\n\n# 📧 Support & Community\n\n- 🐛 [Issues](https://github.com/diegosouzapw/OmniGlyph/issues) — bugs and feature requests\n- 🔒 [SECURITY.md](SECURITY.md) — vulnerability reports\n- 🤝 [CONTRIBUTING.md](CONTRIBUTING.md) — strict TDD + measurement-before-claims\n- 📜 [CHANGELOG.md](CHANGELOG.md) · [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)\n\n<!-- omniglyph:upstream-credits:start -->\n# 🙏 Acknowledgments\n\nOmniGlyph stands on the shoulders of one project in particular — this section is our permanent thank-you.\n\n| Project | How it shaped OmniGlyph |\n|---|---|\n| **[pxpipe](https://github.com/teamchong/pxpipe)** · [teamchong](https://github.com/teamchong) | **The discovery this whole project is built on.** pxpipe proved, with receipts, that a production LLM's vision channel can carry dense textual context at a fraction of the token cost — and that the conversion must be decided per-request by exact billing math, never by vibes. The dense 1-bit rendering, the profitability gate, the `count_tokens` counterfactual, the fail-closed model allowlist, and the \"measure before you claim\" documentation culture were all pioneered there. OmniGlyph descends directly from that codebase (MIT — the original copyright line stays in our [LICENSE](LICENSE)). |\n| **[Spleen](https://github.com/fcambus/spleen)** · Frederic Cambus | The 5×8 bitmap font family our dense 1-bit glyph atlas derives from (license in `assets/`). |\n| **[GNU Unifont](https://unifoundry.com/unifont/)** · Unifoundry | Coverage for the glyphs beyond Spleen's range in the same atlas (license in `assets/`). |\n\nIf you find OmniGlyph useful, go star the upstream too — the discovery was theirs. 🙏\n<!-- omniglyph:upstream-credits:end -->\n\n## 📄 License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md"}