{"id":50529045,"url":"https://github.com/christiansch/agentbridge","last_synced_at":"2026-06-03T11:01:33.163Z","repository":{"id":358915338,"uuid":"1243683954","full_name":"ChristianSch/agentbridge","owner":"ChristianSch","description":"a server/UI to manage remote hermes, pi and terminal sessions","archived":false,"fork":false,"pushed_at":"2026-05-19T17:25:27.000Z","size":537,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-19T18:39:42.559Z","etag":null,"topics":["agents","hermes-agent","pi-coding-agent"],"latest_commit_sha":null,"homepage":"","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/ChristianSch.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":null,"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-19T15:07:37.000Z","updated_at":"2026-05-19T17:25:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ChristianSch/agentbridge","commit_stats":null,"previous_names":["christiansch/agentbridge"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ChristianSch/agentbridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChristianSch%2Fagentbridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChristianSch%2Fagentbridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChristianSch%2Fagentbridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChristianSch%2Fagentbridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChristianSch","download_url":"https://codeload.github.com/ChristianSch/agentbridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChristianSch%2Fagentbridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33860971,"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-03T02:00:06.370Z","response_time":59,"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":["agents","hermes-agent","pi-coding-agent"],"created_at":"2026-06-03T11:01:32.121Z","updated_at":"2026-06-03T11:01:33.157Z","avatar_url":"https://github.com/ChristianSch.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AgentBridge\n\nUnified remote UI for Pi, Hermes, and terminal sessions.\n\n![AgentBridge screenshot](screenshot.png)\n\n## Architecture\n\nPorts and adapters layout:\n\n- `internal/core`: domain types and ports\n- `internal/app`: session/process manager use cases\n- `internal/adapters/agent`: Pi and Hermes protocol adapters\n- `internal/adapters/http`: REST and WebSocket transport\n- `internal/static`: embedded frontend assets\n\n## Run locally\n\n```sh\ncp agentbridge.yaml.example agentbridge.yaml\nAGENTBRIDGE_TOKEN=dev go run ./cmd/agentbridge --config ./agentbridge.yaml 2\u003e\u00261 | tee agentbridge.log\n```\n\nOpen:\n\n```text\nhttp://127.0.0.1:7777/login\n```\n\nEnter the token in the login form.\n\nBuild a binary:\n\n```sh\nmake frontend\nmake server\n./agentbridge --config ./agentbridge.yaml\n```\n\n## Secure tailnet setup\n\nAgentBridge exposes terminals and coding agents. Treat it like shell access.\n\nRecommended setup:\n\n1. Keep AgentBridge bound to loopback:\n   ```yaml\n   bind: \"127.0.0.1:7777\"\n   ```\n2. Use a real token:\n   ```sh\n   export AGENTBRIDGE_TOKEN=\"$(openssl rand -hex 32)\"\n   ```\n3. Put Tailscale Serve in front of the local listener:\n   ```sh\n   tailscale serve --bg --http=7777 http://127.0.0.1:7777\n   tailscale serve status\n   ```\n   Then open `/login` on the Tailscale Serve URL from devices in your tailnet and enter the token in the form.\n4. Optional, enable passkeys for Face ID / Touch ID / security keys:\n   ```yaml\n   auth:\n     passkeys: true\n     rp_id: \"sam-1.example.ts.net\"\n     origins:\n       - \"https://sam-1.example.ts.net\"\n   ```\n   Open `/login` with your bootstrap token once, register a passkey, then normal browser sessions unlock with Face ID or a security key. WebAuthn requires HTTPS, so use the HTTPS Tailscale Serve URL.\n5. Do not enable Tailscale Funnel for AgentBridge. Funnel makes it internet-facing.\n\nAgentBridge logs a security warning if token auth is disabled, if a development token is used, or if it is bound to a non-loopback address. If neither token auth nor passkeys are configured, protected routes stay locked unless `auth.allow_insecure_no_auth: true` is explicitly set. API requests without valid auth return a clear locked message, and the main UI redirects to `/login` instead of loading unauthenticated. Tokens should be entered in the login form, not placed in URLs.\n\n## Current status\n\nImplemented:\n\n- Token auth for REST and WebSockets\n- REST health/projects/session endpoints\n- Multiplexed agent WebSocket at `/ws`\n- Terminal WebSocket at `/ws/term/:id`\n- Multi-session manager for Pi, Hermes, and terminal sessions\n- PTY terminals via `github.com/creack/pty`\n- Pi protocol adapter. Current implementation starts `pi --mode rpc` with the session cwd as the child process working directory.\n- Hermes JSON-RPC adapter with `session.create` and `session.resume`\n- Agent restart with exponential backoff\n- Idle reaper for sessions with no clients\n- Session event history replay on subscribe\n- Session/history persistence across AgentBridge restarts (`~/.local/state/agentbridge/sessions.json`, or `$AGENTBRIDGE_STATE_DIR/sessions.json`), including Hermes `session.resume` and Pi `--session` resume when remote session IDs are known. Terminal sessions are use-once and restore only as exited history.\n- Separate stderr event capture\n- ntfy notification hook for waiting/approval events\n- Activity summaries for hidden thinking/tool activity, with deterministic fallback or a cheap OpenAI/Anthropic model via `activity_summary`\n- Attachment uploads with image support for Pi RPC, an `attachment_read` Pi tool, a Hermes `read_attachment` tool, and attachment/text fallback\n- Local voice transcription via whisper.cpp-compatible `whisper-cli`\n- Preact/xterm frontend with session sidebar, agent chat, terminal panes, attachment chips, voice recording, and approval buttons\n\nAttachment uploads are stored in AgentBridge's state directory and scoped to the browser owner/session. Coding agents may receive a local attachment path so they can read uploaded files directly; treat uploaded files as available to that session's agent process.\n\n## Useful API\n\n```sh\ncurl -H \"Authorization: Bearer dev\" http://127.0.0.1:7777/api/health\ncurl -H \"Authorization: Bearer dev\" http://127.0.0.1:7777/api/sessions\n```\n\nCreate a terminal:\n\n```sh\ncurl -X POST -H \"Authorization: Bearer dev\" -H 'Content-Type: application/json' \\\n  -d '{\"kind\":\"terminal\",\"name\":\"shell\",\"cwd\":\"/tmp\"}' \\\n  http://127.0.0.1:7777/api/sessions\n```\n\nCreate Hermes resume session:\n\n```sh\ncurl -X POST -H \"Authorization: Bearer dev\" -H 'Content-Type: application/json' \\\n  -d '{\"kind\":\"hermes\",\"name\":\"general\",\"cwd\":\"/home/user\",\"resume_id\":\"SESSION_ID\"}' \\\n  http://127.0.0.1:7777/api/sessions\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristiansch%2Fagentbridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristiansch%2Fagentbridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristiansch%2Fagentbridge/lists"}