{"id":50996426,"url":"https://github.com/kanywst/approval-hub","last_synced_at":"2026-06-20T10:01:27.196Z","repository":{"id":361382438,"uuid":"1254257523","full_name":"kanywst/approval-hub","owner":"kanywst","description":"Aggregate Claude Code permission prompts from multiple sessions into one TUI broker.","archived":false,"fork":false,"pushed_at":"2026-05-30T11:50:01.000Z","size":104,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T12:17:26.876Z","etag":null,"topics":["bubbletea","claude-code","claude-code-plugin","cli","developer-tools","go","permission-broker","tui"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kanywst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T10:42:23.000Z","updated_at":"2026-05-30T11:24:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kanywst/approval-hub","commit_stats":null,"previous_names":["kanywst/approval-hub"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/kanywst/approval-hub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanywst%2Fapproval-hub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanywst%2Fapproval-hub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanywst%2Fapproval-hub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanywst%2Fapproval-hub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kanywst","download_url":"https://codeload.github.com/kanywst/approval-hub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanywst%2Fapproval-hub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34565244,"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-20T02:00:06.407Z","response_time":98,"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":["bubbletea","claude-code","claude-code-plugin","cli","developer-tools","go","permission-broker","tui"],"created_at":"2026-06-20T10:01:26.417Z","updated_at":"2026-06-20T10:01:27.190Z","avatar_url":"https://github.com/kanywst.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# approval-hub\n\n\u003cimg src=\"assets/logo.svg\" alt=\"approval-hub\" width=\"160\" align=\"right\"\u003e\n\n\u003e One TUI for every Claude Code permission prompt.\n\n![CI](https://github.com/kanywst/approval-hub/actions/workflows/ci.yml/badge.svg)\n![License](https://img.shields.io/github/license/kanywst/approval-hub)\n![Release](https://img.shields.io/github/v/release/kanywst/approval-hub)\n\n---\n\nWhen you run multiple Claude Code sessions in parallel, every\nPreToolUse permission prompt fires in a different terminal.\n`approval-hub` aggregates them into a single TUI so you can resolve\nevery request from one place. Learned rules apply to future requests\nacross every session on the same machine.\n\n\u003cimg src=\"assets/demo.gif\" alt=\"approval-hub demo\" width=\"900\"\u003e\n\nTwo parallel Claude Code sessions queue PreToolUse requests; one TUI\nresolves them. `a` persists a learned `Bash(npm:*)` allow rule, `d`\npersists an `Edit(.env.local)` deny rule, and the next matching request\nfrom any session resolves from the store without prompting. `t` grants\na TTL rule instead of a forever one.\n\n## Install\n\n```bash\nbrew install kanywst/tap/approval-hub\n```\n\nOr, from source:\n\n```bash\ngo install github.com/kanywst/approval-hub/cmd/approval-hub@latest\n```\n\n## Quick start\n\n```bash\n# 1. run the broker daemon (foreground)\napproval-hub serve\n\n# 2. in another terminal, attach the TUI\napproval-hub attach\n\n# 3. in any Claude Code session, install the plugin and bootstrap\n/plugin install kanywst-plugins/approval-hub\n/approval-hub:install\n```\n\nThe plugin's PreToolUse hook now routes every permission prompt to the\nbroker. Spin up a second Claude Code session anywhere on the same\nmachine and its requests join the same TUI.\n\n## TUI keybindings\n\n| Key         | Action                                          |\n| ----------- | ----------------------------------------------- |\n| `y`         | allow once                                      |\n| `n`         | deny once                                       |\n| `a`         | allow and learn the matcher (persist)           |\n| `d`         | deny and learn the matcher (persist)            |\n| `t`         | allow with a TTL (prompted for seconds)         |\n| `k` / `up`  | move selection up                               |\n| `j` / `dn`  | move selection down                             |\n| `?`         | toggle help                                     |\n| `q`         | quit (broker keeps running)                     |\n\n## CLI\n\n| Command                    | Purpose                                |\n| -------------------------- | -------------------------------------- |\n| `approval-hub serve`       | run the broker daemon in the foreground|\n| `approval-hub attach`      | open the TUI client                    |\n| `approval-hub list`        | list learned matcher rules             |\n| `approval-hub revoke \u003cid\u003e` | delete a learned rule                  |\n| `approval-hub rotate`      | rotate the bearer token                |\n| `approval-hub doctor`      | diagnose the install                   |\n\n## How it works\n\n```text\n+------------------+      +------------------+\n| claude session A |      | claude session B |\n|  PreToolUse:http |      |  PreToolUse:http |\n+---------+--------+      +---------+--------+\n          | POST /decide            | POST /decide\n          +-------------+-----------+\n                        v\n            +-----------------------+\n            |  broker daemon        |\n            |  127.0.0.1:17456      |\n            |  matcher store (JSONL)|\n            +-----------+-----------+\n                        | SSE /events\n                        v\n            +-----------------------+\n            |  TUI client           |\n            |  approval-hub attach  |\n            +-----------------------+\n```\n\nCache hits return in single-digit milliseconds; the user never sees a\nprompt for a rule they have already learned. See\n[ARCHITECTURE.md](ARCHITECTURE.md) for component responsibilities and\nthe broker HTTP API.\n\n## Security\n\n`approval-hub` listens on `127.0.0.1` only and authenticates every\nrequest with a `crypto/rand` 32-byte bearer token stored in `0600`\nfiles. If the broker is not running, Claude Code's hook gets a\nconnection error and falls back to its built-in prompt, so no session\nis blocked by a daemon outage. See [SECURITY.md](SECURITY.md) for the\nthreat model.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkanywst%2Fapproval-hub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkanywst%2Fapproval-hub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkanywst%2Fapproval-hub/lists"}