{"id":49923602,"url":"https://github.com/nvk/agentnoise","last_synced_at":"2026-06-05T01:00:51.210Z","repository":{"id":357761584,"uuid":"1238386254","full_name":"nvk/agentnoise","owner":"nvk","description":"Chat with local coding agents through White Noise. agentnoise is a native desktop helper for using a phone running White Noise as the control surface for local Codex and Claude sessions. It is intentionally Rust-first and keeps Node/npm/bun out of the trusted bridge path.","archived":false,"fork":false,"pushed_at":"2026-06-03T01:08:32.000Z","size":512,"stargazers_count":17,"open_issues_count":3,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T02:13:26.442Z","etag":null,"topics":["agent","brew","chat","im","mls","nostr","whitenoise"],"latest_commit_sha":null,"homepage":"https://agentnoise.org/","language":"Rust","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/nvk.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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-14T04:33:42.000Z","updated_at":"2026-06-03T01:08:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nvk/agentnoise","commit_stats":null,"previous_names":["nvk/agentnoise"],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/nvk/agentnoise","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvk%2Fagentnoise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvk%2Fagentnoise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvk%2Fagentnoise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvk%2Fagentnoise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nvk","download_url":"https://codeload.github.com/nvk/agentnoise/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvk%2Fagentnoise/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33926275,"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-04T02:00:06.755Z","response_time":64,"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":["agent","brew","chat","im","mls","nostr","whitenoise"],"created_at":"2026-05-16T22:04:17.218Z","updated_at":"2026-06-05T01:00:51.203Z","avatar_url":"https://github.com/nvk.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agentnoise\n\n```text\n░█▀█░█▀▀░█▀▀░█▀█░▀█▀░█▀█░█▀█░▀█▀░█▀▀░█▀▀\n░█▀█░█░█░█▀▀░█░█░░█░░█░█░█░█░░█░░▀▀█░█▀▀\n░▀░▀░▀▀▀░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀\n```\n\nChat with local coding agents through White Noise.\n\n`agentnoise` is a native desktop helper for using a phone running White Noise as the control surface for local Codex, Claude, and optional Hermes sessions. It is intentionally Rust-first and keeps Node/npm/bun out of the trusted bridge path.\n\nagentnoise exists because the available agent-chat bridges were too heavy,\ntoo slow-moving, or too awkward for the simple workflow this project needs: a\nnative desktop helper, a phone chat UI, strong first-pairing, and local coding\nagents launched through a [local policy boundary](https://agentbondage.org/).\n\nThe less polite design brief: I had to build it because everything else sucks\nand Jeff moves too slow.\n\nsuch alpha, much wow.\n\n## Changelog\n\nDetailed per-version notes live in [docs/release-notes.md](docs/release-notes.md).\nThe README keeps the recent history grouped by product milestone.\n\n**v0.1.31-v0.1.35** - **Mobile chat UX stabilization.** agentnoise now\ndefaults to phone-safe progress: raw command/tool progress and routine agent\nself-narration stay in `/tail`, job acks/finals use compact chat labels, long\nanswers point to `/tail \u003cjob\u003e`, and agent prompts include the White Noise\nmobile-chat delivery contract. This release window also fixed the active-job\nself-echo loop, clamped quiet-mode \"still working\" pings to a five-minute\nminimum, kept failed Codex/Claude jobs from dumping raw JSON stream\nfragments into phone chat, and restored newer Claude Code compatibility by\nadding the required stream-json verbose launch flag.\n\n**v0.1.29-v0.1.30** - **White Noise media ingest and fake-phone TUI.**\nPhone-sent media is saved into the active workspace and attached to agent\nprompts, including `/wiki` runs that use LLM Wiki ingest framing. Supported\nchat media now covers JPEG/PNG/GIF/WebP, MP4/WebM/MOV, MP3/OGG/M4A/WAV, and\nPDF, and agent replies can upload referenced supported media files from the\nworkspace back to chat. The default-built `agentnoise fake-phone tui` adds live\nreplies, `:attach \u003cpath\u003e [caption]`, chat switching, and automatic handoff\nfollowing.\n\n**v0.1.28** - **Transport/worker split.** Homebrew, launchd, systemd, and\nrc services now run `agentnoise transport run`, which keeps White Noise\nsubscriptions and pairing alive and writes jobs to a local SQLite queue. Local\nagent execution moves to `agentnoise worker start` from a login shell, with\noptional `--tmux` when tmux is installed. `agentnoise up` remains the all-in-one\nforeground path.\n\n**v0.1.27** - **Pending proposal recovery and clearer diagnostics.** Reply\nsends now refresh pending White Noise group proposals immediately when White\nNoise reports `pending proposal exists`, giving the normal retry loop a real\nchance to recover. Service startup logs the active listener pid while waiting\non an existing lock, and fake-phone tests now print the early `wnd` stderr\nexcerpt instead of hiding daemon startup failures behind a missing socket\ntimeout.\n\n**v0.1.26** - **Named instances and subscription recovery.** Added\n`agentnoise --instance \u003cname\u003e` for safer multi-tenant hosts with separate\nconfig, data, logs, keychain service names, White Noise profile names, and\nnative service names. The listener now also records subscription health,\nreconciles recent White Noise group history, recovers missed inbound messages,\nand restarts stale `wn messages subscribe` children so phone commands do not\nget accepted and then disappear.\n\n**v0.1.25** - **Work chat replies without slashes.** The inbox stays command\noriented, but work/session chats now remember the agent mode that created or\nlast explicitly ran in them. After `/codex`, `/claude`, `/hermes`, or `/wiki`\nstarts a work chat, plain text in that chat continues with the same\nagent/profile/wiki mode and workspace.\n\n**v0.1.24** - **Mobile chat cleanup and opt-in local session watch.** White\nNoise replies are shorter and more phone-readable: compact startup hellos,\nqueue/final job replies, progress pings, status, help, session lists, and local\nagent session metadata. Job ids and local session ids can be referenced by\nshort unique prefixes for `/tail`, `/cancel`, and `*-resume` commands. Added\nthe opt-in local session watcher so `agentnoise config local-sessions-watch on`\ncan notify the primary paired chat when same-account Codex/Claude metadata\nappears, while staying off by default for privacy.\n\n**v0.1.23** - **Inbox sessions and stale group cleanup.** The primary paired\nchat now acts as an inbox: new `/codex`, `/claude`, `/hermes`, and `/wiki`\njobs from that chat open a fresh White Noise work session named from the\nhostname and a short prompt summary, then progress and final output continue\nthere. The fake-phone harness follows those handoff links, session open links\nare shown with shorter refs, and startup reconciles saved control chats against\nactive White Noise groups so removed chats stop looking live.\n\n**v0.1.22** - **Service-mode and White Noise delivery fix.** Codex jobs now\nfail fast with a clear explanation when launched from macOS launchd/brew\nservice contexts that make Codex hang before producing output. Direct Codex\nlaunches use a stable agentnoise data dir while still passing the selected\nworkspace through `codex -C`, startup has a no-output watchdog/retry, removed\nWhite Noise groups are ignored, pending paired control chats are accepted, and\nreply send failures no longer kill the listener.\n\n**v0.1.21** - **Quiet-job chat pings.** Running jobs now send a visible\n`still running` message when Codex, Claude, Hermes, or the launcher stays alive\nbut produces no new output. The ping includes `/tail \u003cjob\u003e` and `/cancel \u003cjob\u003e`\nso a phone user can inspect or stop the job instead of staring at an accepted\ncommand with no follow-up.\n\n**v0.1.20** - **Fake-phone E2E and Codex launch fix.** The fake-phone harness\nnow waits for real command replies and final job output instead of passing on\nstartup hellos or unrelated auth replies. Codex jobs also pass\n`--skip-git-repo-check`, which fixes phone-launched jobs in configured\nworkspaces that are plain directories.\n\n**v0.1.16** - **Startup hello.** Once the listener is up, already-paired\ncontrol chats get a timestamped `agentnoise is up` message with profile and\nworkspace context. First-pairing mode stays quiet until the PIN succeeds.\n\n**v0.1.15** - **Homebrew service keychain prompt fix.** Service startup now\nwaits longer for `wnd` to become ready and avoids a redundant second daemon\nstartup check after setup. This prevents launchd keep-alive loops from\nrepeatedly touching the macOS Keychain when White Noise startup is slow.\n\n**v0.1.14** - **Optional direct launcher and reliability polish.**\n`bondage` remains the default and recommended local policy boundary, but\nfirst-run commands can now opt into `runner.launcher = \"direct\"` with\n`--direct-agents`. Direct mode runs raw `codex`, `claude`, or optional\n`hermes` CLIs with structured argv and skips the `bondage` binary/config\nchecks in `agentnoise doctor`. Session replies now spell out current chat,\ntarget chat, workspace, and next command more clearly for phone use.\nLive fake-phone tests and service diagnostics were tightened, and `status` /\n`doctor` avoid slow implicit keychain probes. A local White Noise send can still\narrive on the phone late; the docs now call out how to separate local send\nsuccess from phone sync/display lag.\n\n**v0.1.13** - **White Noise login detection fix.** `wn whoami` reports logged\nin accounts as hex pubkeys while agentnoise config stores the desktop account\nas `npub`. The startup check now normalizes both forms, so agentnoise only\nskips Keychain repair when the actual White Noise signing account is present.\n\n**v0.1.12** - **Service keychain startup fix.** `agentnoise up` now reuses the\ncached desktop `npub` from config for QR/profile setup instead of loading the\ndesktop `nsec` on every service restart. Homebrew services should only touch\nthe OS keychain when creating the identity or repairing a missing White Noise\nlogin. Keychain repair errors now explain the Terminal authorization step.\n\n**v0.1.11** - **Pairing identity fix.** Normalized Nostr sender identity\nchecks across hex pubkeys and `npub` values. This stops agentnoise from\ntreating its own White Noise replies as unpaired inbound messages when the\ndesktop identity is stored as `npub` but White Noise reports authors as hex.\nAllowed phone senders also match across both forms.\n\n**v0.1.10** - **Reliability and identity polish.** Bare text, unknown\ncommands, unauthorized senders, and startup catch-up events now get explicit\nphone replies instead of silent drops. Added reply send retries,\n`agentnoise identity status`, `agentnoise identity rename \u003cname\u003e`, and support\nfor the common typo `agentnoise -- help`. Added configured White Noise message\nrelays and `agentnoise whitenoise relays`/`ensure-relays` so message delivery\ncan use a broader account relay set instead of only the QR discovery hints.\n\n**v0.1.9** - **Remote pairing polish.** Added SSH pairing mode with\nterminal-only PIN display, `--name` for per-machine White Noise/Nostr profile\nlabels, and a remote SSH guide that passes the phone `npub` without moving any\n`nsec` over SSH.\n\n**v0.1.8** - **Parity hardening pass.** Added a fake phone harness for\nisolated White Noise testing, durable runtime event journaling, `agentnoise\nstatus`, progress messages from Codex/Claude JSON streams, approval replay for\nrisky local profiles, attachment metadata capture, a direct `wnd` socket probe,\n`/agents`, opt-in git worktree sessions, and local release smoke checks.\n\n**v0.1.7** - **Optional Hermes backend.** Added `/hermes` and\n`/hermes-resume` as disabled-by-default commands that route Hermes through the\nsame `bondage` local policy boundary used for Codex and Claude. Command\nparsing, config compatibility, command construction, doctor output, and\npackaging are tested; live Hermes CLI/runtime execution is still alpha and\nuntested.\n\n**v0.1.6** - **Service console and dev burner identity.** `agentnoise up` can\nattach to an already-running Homebrew service as a local console instead of\nstarting a second listener, and disposable development identities can use\n`--dev-burner-nsec` without repeated OS keychain prompts.\n\n## What It Does\n\nagentnoise listens to one or more White Noise chats and accepts a small command set from allowlisted senders. It launches local coding agents through the configured launcher: direct raw Codex/Claude CLIs for the simplest setup, or [`bondage`](https://agentbondage.org/) profiles when you want a hardened local policy boundary. It stores job state and logs locally, and posts results back through White Noise. The primary paired chat acts like an inbox: starting a new job there creates a new White Noise work session named `hostname - short prompt summary`, then progress and final output continue in that session. Each White Noise group id gets its own workspace state, so the same phone user can keep multiple independent agentnoise sessions open in separate chat windows.\n\nThe most tested target is macOS. Linux and FreeBSD service templates are\nincluded and should be treated as newer paths.\n\n## Requirements\n\n- Rust toolchain for building from source\n- Codex CLI and/or Claude Code CLI installed and logged in locally\n- no `agentbondage` required for the simple path: use `agentnoise init --direct-agents`\n- recommended hardened path: `bondage` with `codex-agentnoise` and `claude-agentnoise` profiles\n- optional: Hermes Agent CLI plus a dedicated `bondage` profile, or direct Hermes mode\n- `wn` and `wnd` from `marmot-protocol/whitenoise-rs`, either packaged beside `agentnoise` or installed with `agentnoise whitenoise install`\n- OS keychain access if using automatic White Noise login repair with a real identity\n- a dedicated White Noise group for agent control\n\nFor a normal public install without `agentbondage`, use direct mode:\n\n```sh\nagentnoise init --direct-agents\n```\n\nOr set it during first setup:\n\n```sh\nagentnoise up --direct-agents --no-listen\n```\n\nThat writes:\n\n```toml\n[runner]\nlauncher = \"direct\"\n```\n\nDirect mode does not require `bondage` at runtime. It still uses structured argv\nand the same White Noise pairing/allowlist, but local filesystem, network,\nsecret, and approval behavior is whatever the raw agent CLI enforces. Use\n`agentnoise doctor` or `agentnoise agents` to confirm the active launcher.\n\nFor the hardened local-agent-stack setup, use dedicated `bondage` profiles:\n`codex-agentnoise`, `claude-agentnoise`, and optional `hermes-agentnoise`. If an\nolder config still says `profile = \"codex\"` or `profile = \"claude\"`,\nagentnoise uses the matching `*-agentnoise` profile for remote chat runs unless\n`runner.allow_generic_agent_profiles = true` is set. This keeps phone-triggered\njobs separate from human terminal profiles and gives the launcher a place to\npin sandbox, secrets, and non-interactive behavior.\n\nExisting installs can switch explicitly:\n\n```sh\nagentnoise config launcher direct\nagentnoise config launcher bondage\n```\n\nSee [Configuration](docs/configuration.md) for copy/paste examples covering\nraw Codex/Claude mode, `bondage` profiles, repo aliases, and extra commands\nlike `/codex-fix`.\n\n## Security Stack\n\nagentnoise is the phone and White Noise control plane. It does not try to make\nremote chat messages safe by itself; it keeps command parsing small, requires a\nfirst-pairing PIN before trusting a sender, and hands local execution to the\nagent security stack.\n\nThe intended stack is:\n\n- [White Noise](https://www.whitenoise.chat/) carries the phone chat and desktop identity discovery.\n- The OS keychain stores the dedicated desktop helper `nsec` for normal use; `config.toml` stores only public identity and runtime configuration.\n- [`bondage`](https://agentbondage.org/) is the local launcher/policy boundary for Codex, Claude, and other agent profiles. It keeps launch decisions explicit: pinned target, expected hash, configured args, and selected sandbox profile.\n- [`envchain-xtra`](https://envchain-xtra.org/) can be used under bondage when an agent profile needs explicit secret release instead of ambient shell environment.\n- [`nono`](https://nono.sh/) can provide the OS sandbox layer used by bondage profiles.\n- [Learn to Prompt](https://learntoprompt.org/guides/agent-stack.html) is the living operator guide for the larger local agent stack, sandbox profiles, prompt/workflow conventions, and vendor-independent setup notes.\n\nIn short: the phone can ask for work, agentnoise authenticates and routes the\nrequest, and the local stack decides what the agent process is actually allowed\nto touch. In direct mode that local stack is just the raw agent CLI and its own\npermissions model.\n\n## First Run\n\nInstall from Homebrew:\n\n```sh\nbrew install nvk/tap/agentnoise\n```\n\nThe simplest setup does not need `agentbondage`:\n\n```sh\n# raw Codex/Claude mode\nagentnoise init --direct-agents\n```\n\nUse the hardened policy-boundary setup only if you already have `bondage`\nprofiles such as `codex-agentnoise` and `claude-agentnoise`:\n\n```sh\nagentnoise init\n```\n\nFor an existing config:\n\n```sh\nagentnoise config launcher direct\n# or, for bondage profiles\nagentnoise config launcher bondage\n```\n\nThen start it. Homebrew services are the simple setup and boot path:\n\n```sh\nagentnoise up --direct-agents --no-listen\nbrew services start nvk/tap/agentnoise\nagentnoise worker start\n# or, if tmux is installed:\nagentnoise worker start --tmux\n```\n\nThe first command creates the desktop identity, writes config, stores the\ndesktop `nsec` in the OS keychain, and prints the desktop QR/setup hints. The\nHomebrew service then shows the pairing PIN when needed and keeps the White\nNoise transport alive after reboot. The worker\nruns Codex/Claude/Hermes jobs from your login shell so those CLIs see the same\nprofile, TTY/session, and local permissions you use manually.\n\nFor a single foreground process while developing or debugging, skip the service\nand worker split:\n\n```sh\nbrew services stop nvk/tap/agentnoise\nagentnoise up --direct-agents\n```\n\nOver SSH, keep the worker alive with tmux:\n\n```sh\nbrew install tmux\nagentnoise worker start --tmux\n```\n\n`agentnoise up` is still safe to run while the Homebrew service is enabled. If\nthe service already owns the transport, `up` attaches as the terminal UI and\nfollows logs instead of starting a second listener.\n\nOn first run, agentnoise starts White Noise, publishes the profile/key package,\nand opens the pairing window.\n\nAfter the desktop `npub` is written to config, service restarts use that public\nidentity for QR/profile setup and avoid reading the `nsec` unless White Noise\nlogin repair is needed. The listener still requires a logged-in White Noise\nsigning account before it can send replies. If macOS blocks background Keychain\naccess during repair, authorize it from Terminal once:\n\n```sh\nagentnoise keychain status\n```\n\nPair the phone:\n\n1. Look for the macOS `agentnoise pairing` window.\n2. Scan the QR from White Noise on the phone.\n3. Create a White Noise chat/group with the agentnoise desktop identity.\n4. Type the 6-digit PIN shown on the desktop as the first phone message.\n5. Send `/status`, then `/help`.\n\nIf the pairing window is hidden or blocked, the same QR/PIN is in the service\nlogs:\n\n```sh\ntail -f \"$(brew --prefix)/var/log/agentnoise.log\"\ntail -f \"$(brew --prefix)/var/log/agentnoise.err.log\"\n```\n\nUseful local diagnostics:\n\n```sh\nagentnoise status\nagentnoise transport status\nagentnoise worker status\nagentnoise doctor\nagentnoise agents\nagentnoise config path\nagentnoise identity status\nagentnoise identity rename agentnoise-mbp\nagentnoise fake-phone plan\n```\n\nRemote SSH pairing:\n\n```sh\nbrew services stop nvk/tap/agentnoise\nagentnoise up --ssh --phone npub1... --name agentnoise-mbp\n```\n\nIn `--ssh` mode, agentnoise prints the pairing PIN in the SSH session and does\nnot open a desktop GUI alert. Pass the phone `npub`, not an `nsec`; the remote\nmachine creates and stores its own desktop identity locally. Use a distinct\n`--name` per machine so White Noise can show `agentnoise-mbp`,\n`agentnoise-linuxbox`, or whatever label makes sense.\n\nAfter setup, check or change the published machine label without passing any\nphone identity:\n\n```sh\nagentnoise identity status\nagentnoise identity rename agentnoise-linuxbox\n```\n\nThe service is expected to start even before the White Noise chat exists. It\nwaits, keeps showing a rotating PIN while pairing is required, and discovers\nthe phone-created chat automatically. During first pairing it also reads a small\ninitial message window, so a PIN sent right after chat creation can still be\naccepted.\n\nBuild from source:\n\n```sh\ncargo build --release\ntarget/release/agentnoise up\n```\n\nThe QR scans as the desktop `npub`. The terminal also prints the `nprofile`\nwith relay hints. Neither value exposes the desktop `nsec`.\n\nPairing relay hints are for discovery. Message delivery uses the White Noise\naccount relay list. agentnoise now keeps a broader message relay list in config\nand reconciles it through `wn relays add` after login:\n\n```toml\n[whitenoise]\nmessage_relays = [\n  \"wss://index.hzrd149.com\",\n  \"wss://relay.primal.net\",\n  \"wss://relay.ditto.pub\",\n  \"wss://nos.lol\",\n  \"wss://nostr.mom\",\n]\n```\n\nInspect or apply those relays manually:\n\n```sh\nagentnoise whitenoise relays\nagentnoise whitenoise ensure-relays\n```\n\nIf the phone does not show a reply, first check whether the desktop created one:\n\n```sh\nagentnoise status\ntail -f \"$HOME/Library/Application Support/agentnoise/runtime-events.jsonl\"\n```\n\n`reply-sent` means agentnoise handed the message to White Noise and stored it\nlocally. The phone can still render it late if the White Noise relay or mobile\nsync path is delayed. Reopening the chat or restarting the local `agentnoise up`\n/ `wnd` pair can flush old replies, but treat that as a transport diagnostic,\nnot proof that the agent ignored the command.\n\n### Development Burner Identity\n\nFor local development and throwaway relay testing, skip OS keychain prompts:\n\n```sh\nagentnoise up --dev-burner-nsec\n```\n\nThat creates a burner `nsec` at\n`~/Library/Application Support/agentnoise/dev-burner.nsec`, sets\n`whitenoise.dev_burner_nsec = true`, and makes future `agentnoise up` or\nHomebrew service runs use that file instead of the OS keychain. This is\nplaintext by design. Do not use it for a real phone identity or a production\ndesktop helper.\n\nThis flag bypasses the agentnoise keychain store. White Noise still owns its\nown daemon account store after `wn login`; on platforms where that store is\nunavailable, `agentnoise doctor` or startup will show the upstream White Noise\nlogin error explicitly.\n\nIf you already have the phone identity `npub`, agentnoise can create the White\nNoise control chat too:\n\n```sh\ntarget/release/agentnoise up --phone npub... --name agentnoise-mbp\n```\n\nOtherwise scan the QR, create a White Noise chat/group with the desktop\nidentity, and leave the listener running. If you used `--no-listen` or stopped\nthe process, start or attach again:\n\n```sh\ntarget/release/agentnoise up\n```\n\nTo open another independent session, create another White Noise chat with the\nsame agentnoise desktop identity. The running listener discovers visible chats\nperiodically; each chat has separate `/use`, `/cd`, and prompt context.\n\n### Multiple People on One Machine\n\nUse named instances when two people share one host but need separate phone\npairing, desktop identities, keychain entries, services, logs, and sandboxes.\nDo not put both phone npubs in the same `allowed_senders` list unless they are\nintentionally sharing the same repos and launcher policy.\n\nExample with Alice and Bob:\n\n```sh\nagentnoise --instance alice up --ssh --name frontier-alice\nagentnoise --instance bob up --ssh --name frontier-bob\n```\n\nEach instance gets its own default config:\n\n```text\n~/Library/Application Support/agentnoise/instances/alice/config.toml\n~/Library/Application Support/agentnoise/instances/bob/config.toml\n```\n\nEach generated config uses a separate keychain service, data directory, log\ndirectory, worktree directory, White Noise profile name, and default sandbox:\n\n```text\nagentnoise-alice -\u003e ~/Library/Application Support/agentnoise/instances/alice/sandbox\nagentnoise-bob   -\u003e ~/Library/Application Support/agentnoise/instances/bob/sandbox\n```\n\nInstall separate services after each instance is paired:\n\n```sh\nagentnoise --instance alice service install --target launchd --force --load\nagentnoise --instance bob service install --target launchd --force --load\n```\n\nOn Linux the user units are named `agentnoise-alice.service` and\n`agentnoise-bob.service`; on macOS the LaunchAgent labels are\n`com.agentnoise.agentnoise.alice` and `com.agentnoise.agentnoise.bob`.\n\nIf `wn`/`wnd` are not already packaged beside `agentnoise`, install them under agentnoise's managed data directory:\n\n```sh\ntarget/release/agentnoise whitenoise install\n```\n\nInstall as a user LaunchAgent:\n\n```sh\ntarget/release/agentnoise service install --target launchd --force --load\n```\n\nIf first pairing is still required, macOS shows a pairing window with the\ndesktop identity QR, current PIN, and live countdown. The same PIN is also\nprinted to the terminal or service log.\n\n## Linux Quick Start\n\nBuild or install `agentnoise`, then put it on the user `PATH`:\n\n```sh\ncargo build --release\ninstall -Dm755 target/release/agentnoise ~/.local/bin/agentnoise\n```\n\nInstall the bundled White Noise CLI tools if `wn` and `wnd` are not already on\nthe service user's `PATH`:\n\n```sh\nagentnoise whitenoise install\n```\n\nRun the first pairing in the foreground. On Linux the QR and rotating PIN are\nprinted to the terminal/logs:\n\n```sh\nagentnoise up --no-listen\n```\n\nAfter the phone is paired, install a user systemd transport service and start\na login-shell worker:\n\n```sh\nagentnoise service install --target systemd-user --force --load\nagentnoise worker start\nsystemctl --user status agentnoise.service\njournalctl --user -u agentnoise.service -f\n```\n\nFor boot without an active login session, enable lingering:\n\n```sh\nloginctl enable-linger \"$USER\"\n```\n\nSecret storage on Linux uses keyutils plus Secret Service persistence. Headless\nservers need the same user service context to reach an unlocked Secret Service\ncollection; test that before relying on unattended restart:\n\n```sh\nagentnoise keychain status\n```\n\n## FreeBSD Quick Start\n\nBuild or install `agentnoise`, then install the binary somewhere in the service\n`PATH`:\n\n```sh\ncargo build --release\nsudo install -m 0755 target/release/agentnoise /usr/local/bin/agentnoise\n```\n\nCreate the config and do first pairing as the user that should own the helper:\n\n```sh\nagentnoise whitenoise install\nagentnoise up --no-listen\n```\n\nThen install the rc.d transport service using that user's config path and keep\na worker alive in tmux or another user supervisor:\n\n```sh\nCONFIG=\"$(agentnoise config path)\"\nsudo agentnoise --config \"$CONFIG\" service install --target freebsd-rc --force\nsudo sysrc agentnoise_enable=YES\nsudo sysrc agentnoise_user=\"$USER\"\nsudo sysrc agentnoise_config=\"$CONFIG\"\nsudo service agentnoise start\nagentnoise worker start\nsudo service agentnoise status\n```\n\nFor service logs, use the normal rc/daemon logs for the host, commonly:\n\n```sh\ntail -f /var/log/messages\n```\n\nFreeBSD uses DBus Secret Service for real `nsec` storage. Confirm the service\naccount can read the stored secret before depending on restart repair:\n\n```sh\nagentnoise keychain status\n```\n\nFor disposable relay testing only, `agentnoise up --dev-burner-nsec` uses a\nplaintext burner identity and avoids Secret Service setup.\n\n## Chat Commands\n\n- `/status`\n- `/agents`\n- `/agent-sessions [limit]`\n- `/new [name]`\n- `/rename [name]`\n- `/list`\n- `/jump \u003cnumber|name|id\u003e`\n- `/resume \u003cnumber|name|id\u003e`\n- `/close`\n- `/repos`\n- `/use \u003crepo\u003e`\n- `/pwd`\n- `/ls [path]`\n- `/cd \u003cpath\u003e`\n- `/codex \u003cprompt\u003e`\n- `/codex \u003crepo\u003e \u003cprompt\u003e`\n- `/codex-resume \u003csession\u003e \u003cprompt\u003e`\n- `/claude \u003cprompt\u003e`\n- `/claude \u003crepo\u003e \u003cprompt\u003e`\n- `/claude-resume \u003csession\u003e \u003cprompt\u003e`\n- `/hermes \u003cprompt\u003e`\n- `/hermes \u003crepo\u003e \u003cprompt\u003e`\n- `/hermes-resume \u003csession\u003e \u003cprompt\u003e`\n- `/wiki \u003cprompt\u003e`\n- `/codex-wiki \u003cprompt\u003e`\n- `/claude-wiki \u003cprompt\u003e`\n- `/jobs`\n- `/tail \u003cjob\u003e`\n- `/cancel \u003cjob\u003e`\n- `/approvals`\n- `/approve \u003capproval\u003e`\n- `/deny \u003capproval\u003e`\n- `/attachments`\n- `/attach \u003cnumber|id\u003e`\n- `/download \u003cnumber|id\u003e [file-number]`\n- `/worktrees`\n- `/worktree new \u003cname\u003e`\n- `/worktree use \u003cname\u003e`\n- `/worktree remove \u003cname\u003e confirm`\n- `/help`\n\nEach White Noise chat is one agentnoise session. The first paired chat is the\ninbox. Send `/codex ...`, `/claude ...`, `/hermes ...`, or `/wiki ...` there to\nopen a fresh work chat; agentnoise names it from the machine hostname and a\n2-4 word prompt summary, sends an open link back to the inbox, and posts\nquiet status plus final output in the new chat. Follow-up plain text sent inside\nthat work chat continues with the same agent/profile/wiki mode after the prior\nqueued job has finished, while slash\ncommands remain available when you want to change workspace, inspect jobs, or\nforce a different agent.\n\n`/new bugfix-ui` still creates a manual parallel White Noise chat with the\npaired phone identity and clones the current workspace into it. `/rename main`\nnames the current chat, `/list` shows known sessions with short chat refs and\n`whitenoise://chat/...` open links, `/jump 2` or `/resume 2` resumes a session\nfrom that list, and `/close` marks the current session closed locally.\n`/sessions` remains accepted as a readable alias for `/list`.\n\nRepos are aliases from the config, not arbitrary paths. `/use` selects a repo\nfor the session, `/cd ..` moves within that selected repo, and plain `/codex` or\n`/claude` uses the selected workspace. `/hermes` does the same when Hermes is\nenabled. `/wiki` follows the local Codex `codex-wiki` convention by prefixing\n`@wiki`; `/claude-wiki` sends a `wiki ...` prompt for Claude installations with\nthe LLM Wiki instructions/plugin available.\n\nPlain text in the inbox, and plain text in chats without a remembered agent\nmode, is not executed. The reply points the user at `/help` and `/codex\n\u003cprompt\u003e` so a mistyped phone message does not look like a dead daemon.\n\nCodex and Claude JSON streams are parsed for progress while a job runs, but the\ndefault `runner.progress_mode = \"quiet\"` keeps raw command/tool progress and\nagent self-narration out of the phone chat. Use `progress_mode = \"verbose\"` only\nwhen debugging transport. If a running job goes quiet, agentnoise sends a\n\"still working\" ping after `runner.silence_ping_seconds = 60`, but quiet mode\nenforces a five-minute minimum so phone chats are not pinged every minute. Set\n`silence_ping_seconds = 0` to disable those pings. Pings include `/tail \u003cjob\u003e`\nand `/cancel \u003cjob\u003e` hints. If a new launch emits no output at all for\n`runner.startup_silence_timeout_seconds = 90`, agentnoise terminates that\nattempt and retries once by default. Final job output still arrives as one\nnormal reply, compacted for phone when needed, with `/tail \u003cjob\u003e` for logs.\n\nIf a configured agent profile looks intentionally elevated, for example a\nprofile or permission mode containing `unsafe`, agentnoise creates an approval\nobject instead of launching immediately. Approvals are bound to the same White\nNoise chat that requested them and expire after\n`runner.approval_ttl_seconds`.\n\nFor Homebrew service use, keep configured repos outside iCloud Drive/CloudDocs.\nCodex can hang under launchd before writing output when `-C` points at those\nGUI-backed sync folders. `agentnoise doctor` warns about this; run\n`agentnoise up` from an interactive terminal if you must use an iCloud\nworkspace.\n\nWhite Noise media sent by the phone is accepted automatically. agentnoise saves\nthe attachment metadata, calls `wn media download` when White Noise exposes a\nmedia file hash, copies downloaded supported media into\n`.agentnoise/attachments/\u003cattachment-id\u003e/` under the chat's selected\nrepo/worktree, and adds those local file paths to the agent prompt when the\nmedia arrives with a caption or work-chat follow-up. The supported chat-media\nset mirrors White Noise: JPEG/PNG/GIF/WebP images, MP4/WebM/MOV video,\nMP3/OGG/M4A/WAV audio, and PDF. That workspace-local default is readable by the\ndefault `bondage`/nono agent profiles because it sits inside the same workdir\npassed to the agent. `/wiki` media prompts are framed for the LLM Wiki\nfile-ingestion workflow so the wiki can create raw metadata stubs before\ncontinuing the requested wiki task. `/attachments` and `/attach \u003cid\u003e` show saved\nmetadata and local paths; `/download \u003cid\u003e` remains available for manual\nretrieval. When a completed agent job references a supported media file it\ncreated in the selected repo/worktree, agentnoise sends that file back through\nWhite Noise media upload automatically.\n\nGit worktrees are opt-in per chat. `/worktree new fix-ui` creates a git\nworktree under the configured `runner.worktree_dir`, switches only that chat to\nthe new path, and keeps other White Noise sessions on their existing\nworkspaces. Removal requires the explicit `confirm` word.\n\n## Fake Phone Testing\n\n`agentnoise fake-phone` starts from a separate White Noise daemon data\ndirectory, keeps a throwaway phone `nsec` in the fake-phone test root, creates\na chat with the desktop agentnoise identity, and sends test messages without\ntouching the real phone identity or the normal agentnoise keychain.\n\n```sh\nagentnoise fake-phone plan\nagentnoise fake-phone tui --pin 123456\nagentnoise fake-phone roundtrip --pin 123456 /status\nagentnoise fake-phone roundtrip /help\nagentnoise fake-phone roundtrip \\\n  --timeout-seconds 180 \\\n  --min-replies 2 \\\n  --require-job-final \\\n  --expect agentnoise-e2e-ok \\\n  /codex \"Reply with exactly: agentnoise-e2e-ok\"\n```\n\n`fake-phone tui` is compiled into the default `agentnoise` binary, including\nHomebrew installs. It opens a human-driven terminal fake phone with the same\nburner identity/root as `roundtrip`: type `/status`, `/help`, `/wiki ...`, or\nplain text to send to the active chat. Local TUI commands start with `:` so\nthey do not collide with agentnoise slash commands: `:attach \u003cpath\u003e [caption]`\nsends a supported media file through White Noise media, `:chats` lists followed chats,\n`:use \u003cnumber|group-prefix\u003e` switches chats, and `:quit` exits. The TUI\nauto-follows `whitenoise://chat/\u003cgroup\u003e` job handoff links unless\n`--no-follow-handoffs` is set.\n\nFor first-pairing tests, pass the current desktop PIN. After pairing, omit\n`--pin`. The harness resends the test message for the timeout window because a\nrunning agentnoise service may need one discovery cycle before subscribing to\nthe newly-created chat. With `--expect`, unrelated replies such as startup\nhellos or auth errors do not stop resends. Use `--require-job-final` for\n`/codex`, `/claude`, or `/hermes` tests; otherwise the first ack would be\nenough to pass.\n\n## Screenshots\n\nProduct screenshots and Open Graph assets are generated from a dedicated\n`agentnoise.org/shots.html` staging page, not from the marketing site. See\n[Screenshots](docs/screenshots.md) for the exact commands and privacy checklist\nbefore using a real phone or terminal capture.\n\n![agentnoise product screenshot](https://agentnoise.org/shots/desktop.png)\n\n## Transport Notes\n\nThe default White Noise transport remains the tested `wn` CLI path. Setting\n`whitenoise.socket` points `wn` at a specific `wnd` daemon socket. The\nexperimental direct socket adapter is exposed as a probe only:\n\n```sh\nagentnoise whitenoise socket-probe --method ping\n```\n\nThis keeps production message send/subscribe behavior on the stable upstream\nCLI while giving us a tested JSON-line Unix socket client for future direct\n`wnd` work.\n\n### Local Agent Session Visibility\n\n`/agent-sessions` shows recent local Codex and Claude session metadata from the\nsame user account, including sessions started outside agentnoise. It returns\nsession ids, update times, cwd when available, and the explicit resume command\nto use next:\n\n```text\n/agent-sessions\n/codex-resume \u003csession\u003e continue\n/claude-resume \u003csession\u003e continue\n```\n\nThis is intentionally conservative: it does not return transcript content,\ninspect process environments, or silently attach unrelated local work to a\nWhite Noise chat. The phone user must explicitly resume a listed session.\n\nAutomatic local session notifications are disabled by default. Enable them only\non machines where it is okay to send same-account Codex/Claude session metadata\nto the primary paired White Noise chat:\n\n```sh\nagentnoise config local-sessions-watch on\nbrew services restart nvk/tap/agentnoise\n```\n\nThe watcher baselines existing sessions at startup, then reports newly seen\nlocal session ids, update times, and cwd metadata. It does not send transcript\ncontent or attach automatically. To turn it off:\n\n```sh\nagentnoise config local-sessions-watch off\nbrew services restart nvk/tap/agentnoise\n```\n\n## Optional Hermes Support\n\nHermes support is disabled by default. agentnoise does not run the Hermes Agent\ngateway and does not expose a second remote API. It launches the Hermes CLI as a\nlocal backend through `bondage`, the same way it launches Codex and Claude.\n\nEnable it in `~/.config/agentnoise/config.toml` after installing Hermes and\ncreating a dedicated `bondage` profile:\n\n```toml\n[agents.hermes]\nenabled = true\nprofile = \"hermes-agentnoise\"\nbin = \"hermes\"\n```\n\nThen restart the listener:\n\n```sh\nbrew services restart nvk/tap/agentnoise\n```\n\nFrom White Noise:\n\n```text\n/hermes summarize this repo\n/hermes-resume \u003csession\u003e continue\n```\n\nThe command shape is intentionally narrow:\n\n```sh\nbondage exec hermes-agentnoise ~/.config/bondage/bondage.conf -- hermes chat --quiet --source agentnoise --toolsets skills -q \"\u003cprompt\u003e\"\n```\n\nUse the `bondage` profile to set a dedicated `HERMES_HOME`, model endpoint\nenvironment, filesystem policy, and any local secrets release rules. Start with\nrestricted toolsets and widen policy only after the local profile is behaving.\n\n## First Pairing\n\nThe agentnoise `npub` is public on relays, so first-run command authorization is\nseparate from discovery. When `allowed_senders` is empty, `agentnoise up` enters\npairing mode:\n\n1. Desktop shows a QR for the agentnoise desktop `npub`.\n2. On macOS, agentnoise opens a pairing window with the QR, the desktop `npub`,\n   a live countdown, and the current 6-digit PIN.\n3. The phone sends the PIN as the first message, either `123456` or `/pair 123456`.\n4. agentnoise stores that sender in `allowed_senders`.\n5. All other messages are ignored until this succeeds.\n\nThe PIN also prints to stdout/stderr logs for headless and non-macOS setups.\nWhile the listener is running, `agentnoise pair` prints the same live PIN in the\nterminal alongside the QR. It rotates on `whitenoise.pairing_pin_seconds`, which\ndefaults to 30 seconds.\n\n## Security Defaults\n\n- Use a dedicated White Noise bot identity for the desktop helper.\n- Put only trusted devices/users in agentnoise control chats.\n- Keep first pairing local: the sender must prove they can see the desktop PIN.\n- Keep repos as configured aliases.\n- For the simple setup, use direct raw Codex/Claude mode and rely on those\n  CLIs' own permission model.\n- For the hardened setup, keep agent execution behind\n  [`bondage`](https://agentbondage.org/).\n- Store the bot `nsec` in the OS keychain for normal use, not in `config.toml`.\n- Keep automatic local-session notifications off unless that machine is meant\n  to expose same-account Codex/Claude metadata to the paired chat.\n- Use `--dev-burner-nsec` only for throwaway development identities.\n\n## More\n\n- [White Noise setup](docs/whitenoise.md)\n- [Local bring-up](docs/local-bringup.md)\n- [Remote SSH pairing](docs/remote-ssh.md)\n- [Fake phone testing](docs/fake-phone-testing.md)\n- [Testing](docs/testing.md)\n- [Terminal client plan](docs/terminal-client-plan.md)\n- [Screenshots](docs/screenshots.md)\n- [Supervisor services](docs/services.md)\n- [Launchd service](docs/launchd.md)\n- [Homebrew packaging](docs/homebrew.md)\n- [Release notes](docs/release-notes.md)\n- [Learn to Prompt agent stack](https://learntoprompt.org/guides/agent-stack.html)\n- [Bondage local launcher](https://agentbondage.org/)\n\n## License\n\nMIT License. Copyright (c) 2026 nvk.\n\nThis software is provided as-is, without warranty of any kind.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvk%2Fagentnoise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnvk%2Fagentnoise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvk%2Fagentnoise/lists"}