{"id":50665443,"url":"https://github.com/saadjs/runway","last_synced_at":"2026-06-08T06:01:09.833Z","repository":{"id":363248717,"uuid":"1262508259","full_name":"saadjs/Runway","owner":"saadjs","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-08T04:33:40.000Z","size":287,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T05:22:41.563Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saadjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-08T03:54:53.000Z","updated_at":"2026-06-08T04:33:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/saadjs/Runway","commit_stats":null,"previous_names":["saadjs/runway"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/saadjs/Runway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2FRunway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2FRunway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2FRunway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2FRunway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saadjs","download_url":"https://codeload.github.com/saadjs/Runway/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2FRunway/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34050225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-08T06:00:25.589Z","updated_at":"2026-06-08T06:01:09.825Z","avatar_url":"https://github.com/saadjs.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eRunway\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  A minimal macOS menu-bar app that shows your \u003cb\u003e5-hour\u003c/b\u003e and \u003cb\u003eweekly\u003c/b\u003e usage\n  limits for \u003cb\u003eClaude Code\u003c/b\u003e and \u003cb\u003eCodex\u003c/b\u003e, nothing else.\u003cbr\u003e\n  Native components, official logos, system colors only.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003emacOS 13+ · SwiftUI \u003ccode\u003eMenuBarExtra\u003c/code\u003e · menu-bar only (no Dock icon)\u003c/sub\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/saadjs/Runway/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/saadjs/Runway?sort=semver\u0026display_name=tag\u0026label=release\u0026color=2dba4e\" alt=\"Latest release\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/macOS-13%2B-000000?logo=apple\u0026logoColor=white\" alt=\"macOS 13+\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Swift-5-F05138?logo=swift\u0026logoColor=white\" alt=\"Swift 5\"\u003e\n  \u003ca href=\"https://github.com/saadjs/homebrew-tap\"\u003e\u003cimg src=\"https://img.shields.io/badge/install-brew%20cask-FBB040?logo=homebrew\u0026logoColor=white\" alt=\"Homebrew cask\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/notarized-%E2%9C%93-2dba4e\" alt=\"Notarized\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/popover.png\" alt=\"Runway popover showing Claude and Codex usage\" width=\"320\"\u003e\u003cbr\u003e\u003cbr\u003e\n  \u003cimg src=\"docs/menubar.png\" alt=\"Runway menu-bar label\" width=\"220\"\u003e\n\u003c/p\u003e\n\n## What it does\n\n- Reads the credentials the `claude` and `codex` CLIs already store, so there's\n  nothing to log into.\n- Shows each provider's rolling 5-hour and 7-day windows with a percentage and a\n  reset countdown.\n- The menu-bar label shows the highest current 5-hour usage at a glance.\n- Refreshes on launch, every 5 minutes, and on demand.\n\n## How usage is fetched\n\n| Provider    | Credentials                                                                                 | Endpoint                                 |\n| ----------- | ------------------------------------------------------------------------------------------- | ---------------------------------------- |\n| Claude Code | login Keychain item `Claude Code-credentials` (falls back to `~/.claude/.credentials.json`) | `GET api.anthropic.com/api/oauth/usage`  |\n| Codex       | `~/.codex/auth.json`                                                                        | `GET chatgpt.com/backend-api/wham/usage` |\n\nClaude tokens are **not** refreshed by Runway (the CLI rotates them); if the\nsession is expired it asks you to run `claude`. Codex tokens are refreshed and\nwritten back to `auth.json`, matching what the CLI does.\n\n## Install\n\n```bash\nbrew install --cask saadjs/tap/tokens-runway\n```\n\nA notarized, stapled build straight from [Releases](https://github.com/saadjs/Runway/releases).\n\n## Build \u0026 run\n\n```bash\n./Scripts/build-app.sh release   # builds build/Runway.app (ad-hoc signed)\nopen build/Runway.app\n```\n\nFor development you can also just `swift run`.\n\n\u003e The first launch reads the Claude Keychain item; approve **Always Allow** once.\n\u003e The build is ad-hoc signed so the grant persists across launches.\n\n## Current Release Process (notarized) \u0026 Homebrew\n\n### One-time setup\n\nStore the App Store Connect API key as a notarytool keychain profile named\n`runway-notary` (the cert is already in the login keychain):\n\n```bash\nxcrun notarytool store-credentials runway-notary \\\n  --key \u003cpath-to-.p8-file\u003e \\\n  --key-id \u003ckey-id\u003e \\\n  --issuer \u003cissuer-id\u003e\n```\n\n### Cut a release\n\n1. Bump the version (e.g. for `1.1`):\n\n    ```bash\n    APP_VERSION=1.1 ./Scripts/release.sh\n    ```\n\n    `release.sh` builds with the hardened runtime, Developer ID signs, submits to\n    Apple's notary service, staples the ticket, zips the stapled `.app`, and\n    prints the `version`/`sha256`/`url`.\n\n2. Publish the artifact:\n\n    ```bash\n    gh release create v1.1 build/Runway-1.1.zip --repo saadjs/Runway --generate-notes\n    ```\n\n3. Bump `version` **and** `sha256` (each notarized build has a unique hash) in\n   `saadjs/homebrew-tap/Casks/tokens-runway.rb`, using the values `release.sh` printed.\n   Keep `dist/tokens-runway.rb` in this repo in sync.\n\nVerify before announcing:\n\n```bash\nbrew update \u0026\u0026 brew fetch --cask saadjs/tap/tokens-runway   # resolves URL + checks sha256\n```\n\n## Adding another provider\n\nThe app is intentionally modular. To support a new app:\n\n1. Add a type conforming to `UsageProvider` in `Sources/Runway/Providers/`,\n   implementing `fetchUsage() -\u003e ProviderUsage` (a `fiveHour` and `weekly`\n   `UsageWindow`).\n2. Drop its logo PDF in `Sources/Runway/Resources/` and reference it via\n   `logoResource`.\n3. Append it to `ProviderRegistry.all`.\n\nEverything else (refresh loop, UI, menu-bar label) picks it up automatically.\n\n## Layout\n\n```\nSources/Runway/\n  App/        RunwayApp.swift        MenuBarExtra + accessory policy\n  Core/       UsageModels, UsageProvider, ProviderRegistry, Keychain\n  Providers/  ClaudeProvider, CodexProvider\n  Store/      UsageStore                 refresh loop + state\n  Views/      MenuView, ProviderCardView, UsageBarView, Support\n  Resources/  claude.pdf, codex.pdf      official logos (template-tinted)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaadjs%2Frunway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaadjs%2Frunway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaadjs%2Frunway/lists"}