Wires Claude Code to a didbot personal data server: hooks, a plugin, and the harness contract they rest on.

feat(plugin): list web apps that sign in as an agent's identity #110

Closed permadeath.com
targeting main from claude/session-did-registry
Closed opened by and assigned to permadeath.com
targeting main from claude/session-did-registry

Adds web apps to the place registry from PR 47, and fixes a hook bug that hid browser sign-ins.

  • Browser entries. A place entry with browser = true names a sign-in url in place of on_path and command. It shows only when the daemon names a browser sign-in page. Its line tells the agent to sign in from its browser tool, once that browser is signed in as the agent. Command entries come first. The filter stage now also receives the daemon's answer.
  • Four entries, each signed in end to end with a didbot agent on 2026-10-20: pdsls, Leaflet, plyr.fm and Tangled's website. plyr.fm and Tangled write a profile record on sign-in, and each entry says so. The test write-up, including Frontpage, which fails with RS256 DPoP proofs, is /home/jmm/Documents/didbot-review/research/oauth-third-party.html.
  • Cap. The default max_chars goes from 1200 to 2400. The six entries take 2039 characters with this session's DID. The atgc, Leaflet and Tangled lines were trimmed.
  • Fix. evaluate_script prints the authorize URL inside JSON, followed by a literal \n. navigate_page and press_key end it with a full stop. Either one ended up in the request_uri the hook sent, so the daemon never showed that sign-in. A backslash now ends a URL, and trailing punctuation is stripped.

Stacked on PR 47, which it extends.

Before (PR 47, first tool call, both CLIs installed, browser sign-in offered) #

Your agent identity on this machine is did:web:agent.pds.example.
When an app asks to sign in as you, the request appears here with what it asked for and what policy allows; approve it with `didbot oauth approve <token>` or decline with `didbot oauth decline <token>`.
A web app's sign-in finishes only in a browser signed in as you. Open https://pds.example/oauth/browser with your browser tool to sign it in.

Tools on this machine you can sign in to as this identity:
- atgc: opens pull requests and issues on Tangled as you. Sign in with `(atgc auth login did:web:agent.pds.example 2>/dev/null &) | head -n1`. Then pass `--account did:web:agent.pds.example` to every atgc command, since a checkout acts as the account its git config names, and open pulls with `atgc pr create --patch-only` where you cannot push. Signing in joins Tangled, and your pulls, issues and comments are public under this account.
- vibescrobble: posts one line of what you are doing, with an emoji, to the status board at vibescrobble.com. Sign in with `vibescrobble login --as did:web:agent.pds.example`. Every post is a public atproto record that anyone can read and that relays keep after you delete it, so post no secrets, credentials, private data or file contents.

After #

Your agent identity on this machine is did:web:agent.pds.example.
When an app asks to sign in as you, the request appears here with what it asked for and what policy allows; approve it with `didbot oauth approve <token>` or decline with `didbot oauth decline <token>`.
A web app's sign-in finishes only in a browser signed in as you. Open https://pds.example/oauth/browser with your browser tool to sign it in.

Where you can sign in as this identity:
- atgc: opens pull requests and issues on Tangled as you. Sign in with `(atgc auth login did:web:agent.pds.example 2>/dev/null &) | head -n1`. Then pass `--account did:web:agent.pds.example` to every atgc command, since a checkout acts as its git config's account, and use `atgc pr create --patch-only` where you cannot push. Signing in joins Tangled, and your pulls, issues and comments are public under this account.
- vibescrobble: posts one line of what you are doing, with an emoji, to the status board at vibescrobble.com. Sign in with `vibescrobble login --as did:web:agent.pds.example`. Every post is a public atproto record that anyone can read and that relays keep after you delete it, so post no secrets, credentials, private data or file contents.
- leaflet: writes and publishes blog posts and newsletters on leaflet.pub. Sign in at https://leaflet.pub/api/oauth/login?handle=did:web:agent.pds.example in your browser tool, signed in as you. What you publish is a public atproto record.
- pdsls: browses any atproto repository and creates, edits or deletes records in yours. Sign in at https://pdsls.dev/account/add in your browser tool, signed in as you. Enter `did:web:agent.pds.example` there. An edit or delete there changes your public repository at once.
- plyr.fm: streams, uploads and likes audio; its settings issue a token for its CLI and MCP server. Sign in at https://plyr.fm/login in your browser tool, signed in as you. Enter `did:web:agent.pds.example` there. Signing in writes a public fm.plyr.actor.profile record, and uploads and likes are public.
- tangled: changes your Tangled settings, such as SSH keys. Sign in at https://tangled.org/login in your browser tool, signed in as you. Enter `did:web:agent.pds.example` there, and skip its onboarding. Signing in joins Tangled and writes a public sh.tangled.actor.profile record.

🤖 Generated with Claude Code

Commits 4

feat(plugin): list web apps that sign in as an agent's identity
fix(plugin): read an authorize URL that a browser tool prints as JSON
feat(plugin): tell a context which tools can sign in as its identity
docs(harnesses): record that a Bash call returns past a waiting child