[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-95938":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":17,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":15,"starSnapshotCount":15,"syncStatus":14,"lastSyncTime":25,"discoverSource":26},95938,"codenotch","vinzdg\u002Fcodenotch","vinzdg","A macOS app that pins usage limits from Claude Code, Cursor, Codex, and Antigravity to a screen edge.",null,"Swift",1417,221,5,2,0,880,20.04,false,"main",true,[],"2026-09-21 02:04:29","# Codenotch\n\nA macOS app that pins a small black notch to a screen edge, showing how much of\neach coding assistant's usage limit you have burned — and whether it is still\nworking, done, or waiting on you.\n\n![Collapsed notch with hover tooltip](docs\u002Fdesign\u002Fframe-124-hover-tooltip.png)\n\nHover a ring for its limit windows and when they reset. Claude's ring shows the\nsame **current session** window Claude Code's own `\u002Fusage` leads with, so the\ntwo never disagree.\n\n## What it reads\n\n| Provider | Source | How |\n|---|---|---|\n| **Claude Code** | official | The OAuth token in the login keychain, against the same endpoint Claude Code's own `\u002Fusage` uses. |\n| **Cursor** | official | The editor's own signed-in session, read from its local SQLite state — no separate sign-in. |\n| **Codex** | official | ChatGPT's usage endpoint, using the local Codex sign-in. Shows the 5-hour and weekly limits when available. |\n| **Antigravity** | official where licensed, otherwise a request count | Antigravity's local language server first, then Google's quota endpoint; a plain count when neither will answer for the account. |\n| **GLM** | official | Z.ai's Coding Plan monitor endpoint, with a key borrowed from whichever coding tool already holds one — Claude Code's `settings.json`, ZCode, or OpenCode. |\n| **Grok** | official | The Grok CLI session in `~\u002F.grok\u002Fauth.json`, against the same credits billing endpoint `\u002Fusage` uses. |\n| **OpenCode** | official | The Go plan's official usage endpoint, with the `opencode-go` key OpenCode itself stores on sign-in. |\n\nCodenotch never signs in anywhere. Every reading is borrowed from a credential\nor session a tool on your Mac already holds — install and sign in to any of\nthem, and its ring appears. Switching a provider off in Settings stops its\ncredential being read at all and forgets the readings taken from it; it does\nnot sign you out of the tool that owns the account, and the row says so.\n\nIt also answers **\"is it still working?\"** — a thin arc spins inside a\nprovider's ring while a session is busy, and becomes a pulsing amber ring when\none is blocked waiting on you. Hover for every live session by name, where it\nis running, and what it wants.\n\nTwo Claude Code logins are two rings. Anyone who keeps a work account apart with\n`CLAUDE_CONFIG_DIR=~\u002F.claude-work claude` gets a **Claude (work)** ring beside the\npersonal one, with its own limits, its own sessions and its own row in Settings.\nAny `~\u002F.claude-\u003Cslug>` directory Claude Code has run against is found at launch;\nthe default `~\u002F.claude` always comes first, the rest in alphabetical order, so the\nrings never swap places.\n\n## Placement\n\nThe notch lives on any of the four screen edges. Right and left keep a\nvertical column; top and bottom lay the readings out side by side. It pins\nitself to the *usable* edge, so a bottom notch rests on the Dock and follows\nwhen the Dock hides or moves. On a Mac with a hardware notch, the top\nplacement takes its exact shape, so the two read as one rather than as a bar\nparked underneath it.\n\nAt rest it is a small pill on the screen edge that unfolds when the pointer\nreaches it — configurable in Settings to always show, or to hide entirely.\nSettings live in an orb below the notch: an arc at rest, a gear on hover.\n\nThe app itself can show a Dock icon, a menu bar icon, or neither.\n\n## Updates\n\nCodenotch updates itself. [Sparkle](https:\u002F\u002Fsparkle-project.org) checks daily\nand installs in the background without prompting; Settings says so and can\nswitch it off. Every update is EdDSA-signed, so nothing installs that wasn't\nbuilt and signed by the maintainer.\n\n## Building\n\n```sh\nbrew install xcodegen   # once\nmake run                # generate, build, launch a Debug build\nmake test               # unit tests\n```\n\nNo signing identity is required for either. `make release` — which archives,\nnotarizes, and produces a signed auto-update feed — needs a Developer ID\ncertificate and an App Store Connect notary profile, and is only ever run by\nthe maintainer to cut an official release. See\n[CONTRIBUTING.md](CONTRIBUTING.md).\n\nRun with `CODENOTCH_DEMO=1` to see fixed sample data instead of live readings.\n\n## Architecture\n\nEvery provider implements `UsageProvider` (`Sources\u002FProviders\u002F`) and declares\nits own `Fidelity` — `.official`, `.derived`, or `.manual` — so the UI never\npresents a guess as if a vendor had published it. `UsageStore`\n(`Sources\u002FModel\u002F`) polls them on a timer, keeps the last good reading across\nlaunches, and degrades every failure to a visible status rather than a\nmade-up percentage.\n\nThe notch itself works in one-dimensional **stack space** (`along`\u002F`across`)\nregardless of which screen edge it's on; `NotchPlacement` is the only place\nthat maps that back onto real screen coordinates. `NotchLayout` holds every\nmeasurement, quoted from `docs\u002Fdesign\u002Fframe-124-hover-tooltip.png` so the\nlayout can be checked against the design frame directly.\n\n- Design spec: [`docs\u002Fspecs\u002F2026-08-28-usage-notch-design.md`](docs\u002Fspecs\u002F2026-08-28-usage-notch-design.md)\n- Implementation history: [`TASKS.md`](TASKS.md)\n\n## The honest caveat\n\nNo vendor publishes a clean \"your session limit is N% used\" API for any of\nthese tools. Each adapter reads whatever the owning app itself reads from —\nan internal endpoint, a local database, a language server's own RPC — and\nthose can change without notice. Every adapter's response shape is pinned by\ntests, and every failure degrades to a visible status (`stale`, `needsAuth`,\n`error`) rather than an invented number.\n\n**Keychain:** the app is signed with a stable Developer ID identity so the\none-time \"Always Allow\" grant on Claude Code's and Antigravity's keychain\nitems survives rebuilds. The secret itself is read only when the owning app\nhas actually changed it — checked via the item's modification date, which\nisn't behind the same access prompt as the credential — so a valid grant does\nnot mean a prompt on every poll.\n\n**Rate limits:** Claude's endpoint returns 429 if polled too hard, with an\nunhelpful `Retry-After: 0`. The back-off treats that as a floor-raiser only —\n60s, doubling per consecutive 429, capped at 15 minutes — and the deadline is\npersisted, so relaunching during a penalty waits instead of spending an\nattempt on it. Polling drops to every 5 minutes when nothing is running, and\nright-clicking the notch offers **Refresh now**.\n\n**Logs:** the app has no window, so anything worth diagnosing goes to the\nunified log.\n\n```sh\n\u002Fusr\u002Fbin\u002Flog stream --predicate 'subsystem == \"com.vinz.codenotch\"' --level debug\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\n[MIT](LICENSE)\n","Codenotch 是一款 macOS 应用，用于在屏幕边缘固定显示多个 AI 编程助手（如 Claude Code、Cursor、Codex、Antigravity 等）的实时用量配额与会话状态。它通过复用本地已登录工具的凭证（如 Keychain、SQLite 状态、配置文件中的 API key），安全读取各服务的官方用量接口，无需重复登录或额外授权；支持多账户区分（如个人\u002F工作 Claude）、动态会话监控（运行中\u002F等待中\u002F已耗尽）及自适应边缘布局（含对 Mac 硬件刘海屏的原生适配）。适用于频繁切换多个编程 AI 工具、需实时掌握配额余量与阻塞状态的开发者日常编码场景。","2026-09-07 02:30:03","CREATED_QUERY"]