{"_id":"@championswimmer/pi-speedometer","_rev":"3-ecc05ba509576c51853e96030d5e6865","name":"@championswimmer/pi-speedometer","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@championswimmer/pi-speedometer","version":"0.1.0","license":"MIT","_id":"@championswimmer/pi-speedometer@0.1.0","maintainers":[{"name":"championswimmer","email":"championswimmer@gmail.com"}],"homepage":"https://github.com/championswimmer/pi-speedometer#readme","bugs":{"url":"https://github.com/championswimmer/pi-speedometer/issues"},"pi":{"extensions":["./src/index.ts"]},"dist":{"shasum":"423897858821e986c1938466e0199889a4a1e440","tarball":"https://registry.npmjs.org/@championswimmer/pi-speedometer/-/pi-speedometer-0.1.0.tgz","fileCount":3,"integrity":"sha512-Zhl0dejPCcDtlEyQyZrp0BQMSfM1bq1orEo41dfm4vRamX77LlvXOrMGy3pD1fcFpCONgJrvz7jgtisGpHVffA==","signatures":[{"sig":"MEUCIQDdFLYnBBsuInMGEhEvb6eBxLXOsgUIA69KxBMNU0e9BgIgXfcIiSNSl4daVWf/wgG4+j94S6NdrOd2lYTzZ5RIrhs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9688},"type":"module","gitHead":"29e6cc193d2ddd8f1bb7ffbe0eb5cc58201e0a5d","_npmUser":{"name":"championswimmer","email":"championswimmer@gmail.com"},"repository":{"url":"git+https://github.com/championswimmer/pi-speedometer.git","type":"git"},"_npmVersion":"10.9.4","description":"pi extension: live tokens/sec and time-to-first-token in the status bar","directories":{},"_nodeVersion":"22.21.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/pi-speedometer_0.1.0_1787170902257_0.7081709678733004","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@championswimmer/pi-speedometer","version":"0.1.1","license":"MIT","_id":"@championswimmer/pi-speedometer@0.1.1","maintainers":[{"name":"championswimmer","email":"championswimmer@gmail.com"}],"homepage":"https://github.com/championswimmer/pi-speedometer#readme","bugs":{"url":"https://github.com/championswimmer/pi-speedometer/issues"},"pi":{"extensions":["./src/index.ts"]},"dist":{"shasum":"38db70f072dc77a2997e8afb571a9ac49b26cd21","tarball":"https://registry.npmjs.org/@championswimmer/pi-speedometer/-/pi-speedometer-0.1.1.tgz","fileCount":3,"integrity":"sha512-G90TBPi7xCXp1JQq3NU40t+d+OPXtC3zBNwNBTjx4NQY4lwJ5CxpBIFSmPH/CD4H0RdsKwypyJZ2TpahqP68LQ==","signatures":[{"sig":"MEYCIQCIyv/04erXDtCG1mKTdlTXxpH+atuNzS5JyajgfYwr+QIhAKmt4RiG/Jmv+Ondd370WlXZwlhwRLNDLx8Zf0s7nf4t","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9688},"type":"module","gitHead":"ed48674b5a08827a6259605866c582dee68a82ed","_npmUser":{"name":"championswimmer","email":"championswimmer@gmail.com"},"repository":{"url":"git+https://github.com/championswimmer/pi-speedometer.git","type":"git"},"_npmVersion":"10.9.4","description":"pi extension: live tokens/sec and time-to-first-token in the status bar","directories":{},"_nodeVersion":"22.21.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/pi-speedometer_0.1.1_1787171356907_0.25593037069979374","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@championswimmer/pi-speedometer","version":"0.1.3","description":"pi extension: live tokens/sec and time-to-first-token in the status bar","type":"module","license":"MIT","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/championswimmer/pi-speedometer.git"},"homepage":"https://github.com/championswimmer/pi-speedometer#readme","bugs":{"url":"https://github.com/championswimmer/pi-speedometer/issues"},"pi":{"extensions":["./src/index.ts"]},"_id":"@championswimmer/pi-speedometer@0.1.3","gitHead":"a8a6909afb3687aaeb30f51392b5cb40e2617a43","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-XZPgFpp4meQ3snJfoE2vQRMHQqjl3S0SeVvPxG0HhFy+v94BR8W/MoNLgTrjYZmCHlyRgs/veswLwkmi7Wl8SA==","shasum":"bda50530e5eefb175667867fed197b8d9b147abc","tarball":"https://registry.npmjs.org/@championswimmer/pi-speedometer/-/pi-speedometer-0.1.3.tgz","fileCount":3,"unpackedSize":11178,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICX+tI1nC/IsRh5pQhn6F4wCHDuEOQK1n3Tn78efkK1FAiEAjzyAvx5/r1bnOgIHcAqEQL1Cgg7N3SAzRJcLLVjW22g="}]},"_npmUser":{"name":"championswimmer","email":"championswimmer@gmail.com"},"directories":{},"maintainers":[{"name":"championswimmer","email":"championswimmer@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-speedometer_0.1.3_1787172181044_0.4478032135814871"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-19T20:21:41.983Z","modified":"2026-08-19T20:43:01.341Z","0.1.0":"2026-08-19T20:21:42.422Z","0.1.1":"2026-08-19T20:29:17.046Z","0.1.3":"2026-08-19T20:43:01.183Z"},"bugs":{"url":"https://github.com/championswimmer/pi-speedometer/issues"},"license":"MIT","homepage":"https://github.com/championswimmer/pi-speedometer#readme","repository":{"type":"git","url":"git+https://github.com/championswimmer/pi-speedometer.git"},"description":"pi extension: live tokens/sec and time-to-first-token in the status bar","maintainers":[{"name":"championswimmer","email":"championswimmer@gmail.com"}],"readme":"# @championswimmer/pi-speedometer\n\nA [pi](https://github.com/earendil-works/pi-coding-agent) extension that shows live LLM streaming performance in the status bar:\n\n```\n⚡ 42.1 t/s ⏱ 412ms\n```\n\n- **⚡ TPS** — output tokens per second (first content delta → now / stream end)\n- **⏱ TTFT** — time to first token (provider request → first content delta)\n\nValues update live while streaming (throttled to ~4/sec) and the final exact numbers remain displayed after the response finishes.\n\n## Install\n\n**Development (symlink into pi's global extensions dir):**\n\n```sh\nmkdir -p ~/.pi/agent/extensions\nln -s \"$(pwd)/src/index.ts\" ~/.pi/agent/extensions/pi-speedometer.ts\n```\n\nHot-reload inside pi with `/reload`.\n\n**Quick one-off test:**\n\n```sh\npi -e ./src/index.ts\n```\n\n**As a package (published on npm under the scoped name):**\n\n```sh\npi install npm:@championswimmer/pi-speedometer\n```\n\n## Usage\n\nThe `/speed` command controls what is shown and how it is labeled:\n\n| Command | Effect |\n|---|---|\n| `/speed` | Show current settings summary |\n| `/speed tps on\\|off` | Toggle the tokens/sec readout |\n| `/speed ttft on\\|off` | Toggle the time-to-first-token readout |\n| `/speed tps icon\\|text` | Switch the TPS label between `⚡` and `TPS` |\n| `/speed ttft icon\\|text` | Switch the TTFT label between `⏱` and `TTFT` |\n\nSettings persist globally at `~/.pi/agent/pi-speedometer.json`, with the shape:\n\n```json\n{\n  \"showTps\": true,\n  \"showTtft\": true,\n  \"tpsStyle\": \"icon\",\n  \"ttftStyle\": \"icon\"\n}\n```\n\nWith both metrics off, the status entry is cleared.\n\n> Note: the npm package uses the scoped name `@championswimmer/pi-speedometer` because the unscoped `pi-speedometer` name is already taken on npm.\n\n## Notes\n\n- **Provider usage streaming differs.** Anthropic streams cumulative output-token counts mid-stream, so live TPS is exact. OpenAI chat-completions only send usage in the final chunk, so mid-stream TPS uses a `chars / 4` estimate and snaps to the exact value when the stream ends. Google usually reports per-chunk.\n- Multiple LLM calls per agent run (tool loops) re-anchor the timing on each request, so the display always reflects the current call.\n- No runtime dependencies — only Node builtins and type-only imports from pi packages.\n","readmeFilename":"README.md"}