{"_id":"@aundal/opencode-bonus-info","name":"@aundal/opencode-bonus-info","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@aundal/opencode-bonus-info","version":"1.0.0","description":"OpenCode TUI sidebar widget showing session open time and idle time since the last assistant response.","license":"MIT","type":"module","repository":{"type":"git","url":"git+https://github.com/aundal/opencode-bonus-info.git"},"homepage":"https://github.com/aundal/opencode-bonus-info#readme","bugs":{"url":"https://github.com/aundal/opencode-bonus-info/issues"},"exports":{"./tui":"./src/bonus-info.tsx"},"keywords":["opencode","opencode-plugin","opencode-tui","sidebar","idle-timer"],"dependencies":{"@opentui/solid":"0.4.0","solid-js":"1.9.12"},"peerDependencies":{"@opencode-ai/plugin":">=1.4.0"},"engines":{"opencode":">=1.4.0"},"gitHead":"46ba04555150b9cb3d1a148aa1dc9b32396a8702","_id":"@aundal/opencode-bonus-info@1.0.0","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-oPmURsKL9b7SLT+ueB96zRr8UKK9hIey8MEck8Ms123CRwRGCfvALtguqAcOjHDHcLnh5fco44NvZLJRn5QB2w==","shasum":"4b57ecfccb859b6f19410f3a73ee7ab27b34fce5","tarball":"https://registry.npmjs.org/@aundal/opencode-bonus-info/-/opencode-bonus-info-1.0.0.tgz","fileCount":5,"unpackedSize":16664,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDHIOPDbU+sIOJJO1KlgCwGnMXJYc9+IB6haiClh+TZCgIgfWJ0FtGNex+bp3TxoNlBf0BkaTyYKZjI2qiVTjtxUYU="}]},"_npmUser":{"name":"aundal","email":"aundal@gmail.com"},"directories":{},"maintainers":[{"name":"aundal","email":"aundal@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/opencode-bonus-info_1.0.0_1787582593043_0.2193449261722138"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-24T14:43:12.880Z","1.0.0":"2026-08-24T14:43:13.178Z","modified":"2026-08-24T14:43:13.352Z"},"maintainers":[{"name":"aundal","email":"aundal@gmail.com"}],"description":"OpenCode TUI sidebar widget showing session open time and idle time since the last assistant response.","homepage":"https://github.com/aundal/opencode-bonus-info#readme","keywords":["opencode","opencode-plugin","opencode-tui","sidebar","idle-timer"],"repository":{"type":"git","url":"git+https://github.com/aundal/opencode-bonus-info.git"},"bugs":{"url":"https://github.com/aundal/opencode-bonus-info/issues"},"license":"MIT","readme":"# opencode-bonus-info\n\nA [OpenCode](https://opencode.ai) TUI plugin that adds a collapsible **Bonus Info** section to the sidebar, showing:\n\n- **Start** — elapsed time since you opened the session in the window (resets on restart or session switch)\n- **Idle** — elapsed time since the assistant's last response, plus a timestamp of when it finished\n\n![Screenshot](docs/screenshot.png)\n\n```\n▼ Bonus Info\nStart: 00:18:48 (24-08-2026 15:55)\nIdle: 00:04:36 (24-08-2026 16:09)\n```\n\n## Features\n\n- **Foldable** — click the header (▼/▶) to expand/collapse; state persists across restarts\n- **Live timers** — `HH:MM:SS`, ticking every second, capped at `99:59:59`\n- **Idle ≤ Start guaranteed** — responses from before you opened the session are ignored, so Idle never counts time you were not looking at it\n- **Multi-window safe** — each window tracks its own session; no shared state files\n- **Zero server-side components** — a single TUI plugin file, no state files, no background processes\n\n## Install\n\nClone the repo into your OpenCode config directory:\n\n```\ngit clone https://github.com/aundal/opencode-bonus-info.git ~/.config/opencode/github/opencode-bonus-info\n```\n\nRegister the file in `~/.config/opencode/tui.json`:\n\n```json\n{\n  \"$schema\": \"https://opencode.ai/tui.json\",\n  \"plugin\": [\n    \"./github/opencode-bonus-info/src/bonus-info.tsx\"\n  ]\n}\n```\n\n(Paths are relative to `~/.config/opencode`.)\n\nAlternatively, copy `src/bonus-info.tsx` anywhere you like and reference that\npath instead. Restart OpenCode to load the plugin.\n\n## How it works\n\nThe widget resolves the current session ID from the slot props, falling back to\n`api.route.current` (older versions do not deliver `session_id` to the\n`sidebar_content` slot). It then finds the last completed assistant message via\n`api.client`, trying multiple SDK conventions until one returns data:\n\n1. `session.messages({ sessionID })` — legacy client, positional args\n2. `session.messages({ path: { id } })` — legacy client, hey-api style\n3. `v2.session.messages({ sessionID })` — SDK v2\n4. `v2.session.messages({ sessionID, limit: 0 })` — SDK v2, legacy store\n\nResponses are normalized across both envelope shapes (`data.data`, `data`, raw body).\nAs a final safety net, `message.updated` events carry `info.time.completed`\ndirectly, so Idle updates even if every HTTP convention fails.\n\n## Compatibility\n\nTested on OpenCode **1.18.16** (Windows). The fallback chain above exists because\nthe TUI plugin API surface has shifted between versions (slot props, SDK v2 vs\nlegacy client, and a messages endpoint that reads different stores depending on\nquery params). If one convention fails on your version, the next is tried — and\nthe event stream covers the rest.\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-497574bde3edaba6754fd0d65702554f"}