{"_id":"@blackbelt-technology/pi-image-fit-extension","_rev":"5-7dbf195b1834978fcfafdbc1f3ddf2d5","name":"@blackbelt-technology/pi-image-fit-extension","dist-tags":{"latest":"0.8.0"},"versions":{"0.5.4":{"name":"@blackbelt-technology/pi-image-fit-extension","version":"0.5.4","keywords":["pi-package","pi-extension","image","resize"],"license":"MIT","_id":"@blackbelt-technology/pi-image-fit-extension@0.5.4","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"extensions":["src/extension.ts"]},"dist":{"shasum":"312f6bf54c35d60eba6c45e043654c60825ed179","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-image-fit-extension/-/pi-image-fit-extension-0.5.4.tgz","fileCount":6,"integrity":"sha512-+6qPek6aOBdrS7IQiAWQtRp9/pQ4GsBDkubdlHOvvH9y9M0oKbqXbvMkP9BknSLfR8+i1AO4HovvepSYCfEz/Q==","signatures":[{"sig":"MEYCIQDBktG0N+c6kp2uxvTwh3hoK5wwZsF6VQcEuwSqZOQa4AIhAImia5Ruc3AANej6h4mU7KLbhiaYX4XAxzqAZq1KVOtt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22623},"type":"module","gitHead":"676817fc2b61036bc861c1ca1406d37af016c072","_npmUser":{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/image-fit-extension"},"_npmVersion":"10.9.3","description":"Pi extension that resizes oversize images at Read-time so they fit model byte and pixel ceilings.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"jimp":"^1.6.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"@mariozechner/pi-coding-agent":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@mariozechner/pi-coding-agent":{"optional":true},"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-image-fit-extension_0.5.4_1782336707015_0.5576856571234463","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@blackbelt-technology/pi-image-fit-extension","version":"0.6.0","keywords":["pi-package","pi-extension","image","resize"],"license":"MIT","_id":"@blackbelt-technology/pi-image-fit-extension@0.6.0","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"extensions":["src/extension.ts"]},"dist":{"shasum":"8d9ed4087930a61536111d6d03bae30286652774","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-image-fit-extension/-/pi-image-fit-extension-0.6.0.tgz","fileCount":7,"integrity":"sha512-ROuUXSQm++Y4x45AkuMHgSFj5UKBPyM3mk12fiG9e1FGrrB/eCH8hQkwg8ctfNQ/QZ4xXsj+oXDPqUrT9SdRSQ==","signatures":[{"sig":"MEUCIQD0u0/zav3WUwgdyrmKRUPCJHQgzWnxR3gKEYruJIMSuwIgVLUNimRQYDWsWUmuDGHxUmD7JzvNo3LvE0GvNYLibyY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-image-fit-extension@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":24506},"type":"module","gitHead":"70c087ba97d3b7a9997767f7c9c758ac49d998f2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:60d5a53f-9be8-48ea-8b4e-e07b60256dce"}},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/image-fit-extension"},"_npmVersion":"11.12.1","description":"Pi extension that resizes oversize images at Read-time so they fit model byte and pixel ceilings.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jimp":"^1.6.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"@mariozechner/pi-coding-agent":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@mariozechner/pi-coding-agent":{"optional":true},"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-image-fit-extension_0.6.0_1784565563550_0.2540688140148779","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@blackbelt-technology/pi-image-fit-extension","version":"0.6.1","keywords":["pi-package","pi-extension","image","resize"],"license":"MIT","_id":"@blackbelt-technology/pi-image-fit-extension@0.6.1","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"extensions":["src/extension.ts"]},"dist":{"shasum":"99262f56f7790a1addd25c61bc4c6b1d0ee2aa46","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-image-fit-extension/-/pi-image-fit-extension-0.6.1.tgz","fileCount":7,"integrity":"sha512-tZ9rS7CpnIgm4ZKUadsQ+vBEJQR3qFzcuO3Nc8EeA/MgrNLuSffD1Xe1IWUSJoAAlqZ3UEDYekjWM0D1l6kGEA==","signatures":[{"sig":"MEYCIQCETu4oRrlh5SRH+l5T7+8YkVJLfznSofiU2RZ5PWQxwAIhAKa7+ia35nVHurS4916ioXC8wugJhh/XITNv9WavmvgW","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-image-fit-extension@0.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":24506},"type":"module","gitHead":"88a0cf3cc7d7c7c4e44eb61df3cceff19ed919ad","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:60d5a53f-9be8-48ea-8b4e-e07b60256dce"}},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/image-fit-extension"},"_npmVersion":"11.12.1","description":"Pi extension that resizes oversize images at Read-time so they fit model byte and pixel ceilings.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jimp":"^1.6.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"@mariozechner/pi-coding-agent":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@mariozechner/pi-coding-agent":{"optional":true},"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-image-fit-extension_0.6.1_1784571704840_0.9969623470152627","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@blackbelt-technology/pi-image-fit-extension","version":"0.7.0","keywords":["pi-package","pi-extension","image","resize"],"license":"MIT","_id":"@blackbelt-technology/pi-image-fit-extension@0.7.0","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"pi":{"extensions":["src/extension.ts"]},"dist":{"shasum":"6f574ebce3bd4a2313a006ef22520d5a96747907","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-image-fit-extension/-/pi-image-fit-extension-0.7.0.tgz","fileCount":7,"integrity":"sha512-JvijLYItdA3BY7UquV07wnekokQ5ViJtYNqVPFafVNpCfixFapW5CMHDxCJD8Y9kGQJiV8u5HjOjhwVGoncqGw==","signatures":[{"sig":"MEQCIAjxI0u/s3ZHDQ2T+wPv3fCKk8ZJmJnv4RF9kHBoPnMuAiAChROKjpQ8NruB1ttdCdY9UUzWWqg40o4QvtU2/bVBvw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-image-fit-extension@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":42867},"type":"module","gitHead":"9203d6a89f1b81c516e9351072ee5cb4c6579e0a","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:60d5a53f-9be8-48ea-8b4e-e07b60256dce"}},"repository":{"url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","type":"git","directory":"packages/image-fit-extension"},"_npmVersion":"12.0.1","description":"Pi extension that resizes oversize images at Read-time so they fit model byte and pixel ceilings.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"jimp":"^1.6.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@earendil-works/pi-coding-agent":"*"},"peerDependencies":{"@mariozechner/pi-coding-agent":"*","@earendil-works/pi-coding-agent":"*"},"peerDependenciesMeta":{"@mariozechner/pi-coding-agent":{"optional":true},"@earendil-works/pi-coding-agent":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pi-image-fit-extension_0.7.0_1784899056161_0.9980405163026456","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@blackbelt-technology/pi-image-fit-extension","version":"0.8.0","description":"Pi extension that resizes oversize images at Read-time so they fit model byte and pixel ceilings.","type":"module","repository":{"type":"git","url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","directory":"packages/image-fit-extension"},"license":"MIT","publishConfig":{"access":"public"},"keywords":["pi-package","pi-extension","image","resize"],"pi":{"extensions":["src/extension.ts"]},"dependencies":{"jimp":"^1.6.1"},"peerDependencies":{"@earendil-works/pi-coding-agent":">=0.80.10","@mariozechner/pi-coding-agent":">=0.73.1"},"peerDependenciesMeta":{"@earendil-works/pi-coding-agent":{"optional":true},"@mariozechner/pi-coding-agent":{"optional":true}},"devDependencies":{"@earendil-works/pi-coding-agent":">=0.80.10"},"gitHead":"9373dfa416660a285475febc0383608fe14270b1","_id":"@blackbelt-technology/pi-image-fit-extension@0.8.0","bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","_nodeVersion":"24.19.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-JK2J3u1J1Y/+lbe/yN+h07UoYO5DWVXy3qIOwybku0RQcf0KAo6c3RD0wpV3Fi8PsltQdHk73HsyuBy/akQaCw==","shasum":"f5993bb85a07e4089f18629ac8aa321bc1ed35f1","tarball":"https://registry.npmjs.org/@blackbelt-technology/pi-image-fit-extension/-/pi-image-fit-extension-0.8.0.tgz","fileCount":6,"unpackedSize":40197,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@blackbelt-technology%2fpi-image-fit-extension@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCd+RxdSDBQE2V3RXk7TImf2GqVLnMDg8O00vjFUydzwQIhAJ9jMTN5vklx6ZQZ0FX/QGdXBSgk5hK3T186wT1heFeq"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:60d5a53f-9be8-48ea-8b4e-e07b60256dce"}},"directories":{},"maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-image-fit-extension_0.8.0_1787745976347_0.05833010289221785"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-24T21:31:46.864Z","modified":"2026-08-26T12:06:16.886Z","0.5.4":"2026-06-24T21:31:47.149Z","0.6.0":"2026-07-20T16:39:23.808Z","0.6.1":"2026-07-20T18:21:44.976Z","0.7.0":"2026-07-24T13:17:36.301Z","0.8.0":"2026-08-26T12:06:16.499Z"},"bugs":{"url":"https://github.com/BlackBeltTechnology/pi-agent-dashboard/issues"},"license":"MIT","homepage":"https://github.com/BlackBeltTechnology/pi-agent-dashboard#readme","keywords":["pi-package","pi-extension","image","resize"],"repository":{"type":"git","url":"git+https://github.com/BlackBeltTechnology/pi-agent-dashboard.git","directory":"packages/image-fit-extension"},"description":"Pi extension that resizes oversize images at Read-time so they fit model byte and pixel ceilings.","maintainers":[{"name":"mbotond","email":"botond.molnar@blackbelt.hu"},{"name":"mrbence","email":"dbence10@gmail.com"},{"name":"robertcsakany","email":"robert.csakany@blackbelt.hu"},{"name":"norbert.herczeg","email":"norbert.herczeg@blackbelt.hu"}],"readme":"# @blackbelt-technology/pi-image-fit-extension\n\nPi extension that resizes oversize images at Read-time so they fit model\nbyte and pixel ceilings.\n\nThe extension hooks `pi.on(\"tool_call\", ...)`. When the agent runs the\nbuilt-in `read` tool with an image path (`.png`, `.jpg`, `.jpeg`, `.webp`,\n`.gif`), the extension:\n\n1. Stats the file and (lazily) probes dimensions via [jimp](https://github.com/jimp-dev/jimp).\n2. If the image already fits both thresholds, leaves `event.input.path`\n   untouched — built-in Read sees the original bytes, no temp file, no\n   telemetry.\n3. Otherwise, re-encodes the image (long-edge scaled, aspect-ratio\n   preserved) into a session-scoped temp file under\n   `os.tmpdir()/pi-image-fit/<session>/<sha256>.<ext>` and mutates\n   `event.input.path` to point at it. Built-in Read attaches the smaller\n   image to the agent's context window.\n\nNo native binary deps — `jimp` only. No `electron-rebuild` step, no\nplatform-specific prebuilt downloads. Pure JS install on every supported\npi target.\n\n## Second seam: the `context` event (any-origin images)\n\nThe `read`-tool seam above only covers images the agent opens through the\nbuilt-in `read` tool. Images that enter a session as **message content** —\n`tool_result` screenshots (browser / MCP), user-pasted / attached images, and\nimages already persisted in a transcript — never pass through `read`, so a\nsecond seam catches them.\n\nThe extension also hooks `pi.on(\"context\", ...)`, fired before every LLM call\non a deep copy of the message list. For every message (regardless of role) it\nwalks the content blocks and, for each oversize `ImageContent`\n(`{ type: \"image\", data, mimeType }`), resizes the bytes in-memory with jimp\nand replaces `data` + `mimeType`. Because it runs on the in-flight copy every\nturn, it also **rescues already-persisted oversize sessions on reload** — a\ncase no creation-time hook can cover (e.g. a session poisoned by an 8956×5080\nbrowser screenshot that is under the byte limit but over the pixel limit).\n\nHow it stays cheap on the per-turn hot path:\n\n- A **cheap header-probe gate** reads dimensions from the image header bytes\n  (PNG / JPEG / WEBP / GIF) and estimates size from the base64 length — no\n  full pixel decode. An image already within limits costs only this probe.\n- An oversize image is hashed (SHA-256 of\n  `base64|mimeType|maxEdge|maxBytes|quality`) and its resized bytes cached in\n  a **bounded in-memory LRU** (~64 MiB, evicted by byte budget). The same\n  historical image reappearing every turn is served from the cache — no\n  re-encode.\n\nThe on-disk transcript is **never rewritten** — only pi's per-turn deep copy\nis mutated, so the request sent to the model is always within limits while the\noriginal bytes stay on disk. This seam reuses the same `PI_IMAGE_FIT_*`\nthresholds and honors `PI_IMAGE_FIT_DISABLE` (which disables both seams). Any\nper-block failure falls open (one `WARN`, block passed through unchanged) so a\nsingle bad image never blocks a turn.\n\n> **GIF animation:** an oversize `image/gif` is re-encoded to a static JPEG\n> (first frame only) — same trade-off as the `read`-path seam.\n\n## Install\n\n```bash\npi install @blackbelt-technology/pi-image-fit-extension\n```\n\nThe next pi session loads the extension. No dashboard or other workspace\npackage required.\n\n## Default thresholds\n\n| Setting | Default | Env var |\n| --- | --- | --- |\n| Long-edge pixels | 1568 | `PI_IMAGE_FIT_MAX_EDGE` |\n| Byte size | 4,194,304 (4 MiB) | `PI_IMAGE_FIT_MAX_BYTES` |\n| JPEG quality | 85 | `PI_IMAGE_FIT_QUALITY` |\n| Kill switch | off | `PI_IMAGE_FIT_DISABLE` |\n\nResize triggers when **either** the byte size **or** the long edge\nexceeds its threshold. When both are at or below their thresholds, the\nextension is a no-op.\n\n## Environment variables\n\n- `PI_IMAGE_FIT_DISABLE` — truthy (`1`, `true`, `yes`, case-insensitive)\n  skips the `pi.on(\"tool_call\", ...)` registration entirely; the\n  extension logs a single disabled-message line on load and does nothing\n  else.\n- `PI_IMAGE_FIT_MAX_EDGE=<px>` — positive integer; override the\n  long-edge threshold.\n- `PI_IMAGE_FIT_MAX_BYTES=<bytes>` — positive integer; override the byte\n  threshold.\n- `PI_IMAGE_FIT_QUALITY=<1-100>` — JPEG output quality. Ignored for\n  PNG-in → PNG-out path (always lossless).\n\nInvalid values fall back to the documented default and log a single\nwarning line naming the variable.\n\n## Output format\n\nFormat-adaptive:\n\n- `.png` source → PNG output (lossless re-encode preserves transparency).\n- everything else → JPEG at the configured quality.\n\nCache file extension matches the chosen output format.\n\n## Telemetry\n\nOn a successful resize the extension emits exactly one line:\n\n```\n[pi-image-fit] <path> <srcW>×<srcH> <srcBytes>B → <dstW>×<dstH> <dstBytes>B\n```\n\nNo log on already-small pass-throughs, on non-image reads, or on\nnon-`read` tool calls. Failures log a single `[pi-image-fit] WARN ...`\nline and fall through to the original path (the agent's Read behaves\nexactly as if the extension were not installed).\n\n## Caveat: silent quality loss\n\nA 4K screenshot squashed to 1568 px may lose fine text. The agent has no\nway to tell that resize fired beyond the console log line. If pixel\nperfect Read matters for a workflow, set `PI_IMAGE_FIT_DISABLE=1` in\nthat environment.\n\n## License\n\nMIT. Part of the [pi-agent-dashboard](https://github.com/BlackBeltTechnology/pi-agent-dashboard)\nmonorepo; versions move in lockstep with the rest of the workspace.\n","readmeFilename":"README.md"}