This repository has no description
3

Configure Feed

Select the types of activity you want to include in your feed.

README.md

Resolver — the consumer side#

A read-only, zero-auth, zero-dependency resolver that discovers a user's action graph from their repo footprint, and a CLI over it. This is the reference implementation a consumer embeds.

resolver.mjs   core lib (Node 18+ and browser; fetch-based)
cli.mjs        prints the action graph / answers "which app can do X?"
fixtures/      demo records (not yet on the network) for the offline loop

The loop#

actor (handle/DID)
  -> scan repo for dev.at-intent.usage records          (discovery)
  -> resolve each app DID -> its dev.at-intent.capability records
  -> assemble (verb, subject, handler) action graph     (the triple)
matchActions(graph, {verb, subject}) -> "which handler can do X?"
requiredScopes(actions)              -> the include:<nsid> scopes to request

CLI#

node cli.mjs --demo                          # full action graph (offline fixtures)
node cli.mjs --demo --feed https://blog/rss  # "which of my apps subscribe to a feed?"
node cli.mjs --demo --scopes                 # scopes to request to enable everything
node cli.mjs --demo --json                   # raw graph
node cli.mjs alice.bsky.social               # live: real handle, real repo scan

Live mode does real atproto plumbing — handle→DID, DID doc→PDS, com.atproto.repo.listRecords for usage/capability records. Until apps publish these records it finds nothing against live handles — which is itself proof the plumbing is real, not mocked. The fixtures stand in for the network so the full loop runs offline today.

Library#

import { resolveActionGraph, matchActions, requiredScopes } from "./resolver.mjs";

const graph = await resolveActionGraph("alice.bsky.social", { cache: new Map() });
const handlers = matchActions(graph, { verb: "subscribe", subject: { kind: "uri" } });
const scopes = requiredScopes(handlers);

opts: fixtures (offline records), cache (Map, persist with a long TTL), staleDays (default 180), includeStale, fetchImpl, now.

Caveats#

  • No real records exist yet — everything non-demo resolves to empty until an app publishes dev.at-intent.* records.
  • Browser live mode can hit CORSlistRecords against arbitrary PDSes may be blocked from a web origin; a tiny read proxy fixes it. The Node path and demo mode have no such limit.
  • Routing is read-only hererepo/service capabilities show what they would do; performing the write/call is the consumer's job (see consumers.md).