Crew-level Cordn chat already existed (lib/cordn, useCordnChat, CrewChat,
CrewCoordinatorCard, the crew 'coordinator' tag). The real gap: the crew form
accepted a URL only, so a coordinator run from Cordn's phone app — which yields
an nprofile, not a URL — could not be entered at all.
- lib/coordinator.ts: parseCrewCoordinatorInput / crewCoordinatorInputValue —
the same pointer formats as Settings -> Coordinator (nprofile / cordn.net
link / npub / hex) plus a plain endpoint URL.
- CrewForm: parses the pointer, shows live valid/invalid feedback, sets
['coordinator', url, pubkey?] (schema unchanged), and gains a one-tap
'Use my coordinator' prefill from Settings.
- NIP.md: note the accepted pointer formats on the coordinator tag.
- AGENTS.md: record that crew-level Cordn chat already exists (the lesson:
grep src before building).
SkateSpots stays a Cordn *client*: it points at a coordinator the user
chooses or runs, and hands phone-hosting off to Cordn's own app. No embedded
coordinator, no default SkateSpots coordinator (deliberate: liability).
- src/lib/coordinator.ts: Cordn's own formats — an nprofile pointer, the
canonical add-link https://cordn.net/chat/coordinators?c=<nprofile> (from
Cordn packages/server/src/main.ts), default relay wss://relay.contextvm.org,
the docker one-liner. Parses nprofile/npub/hex/link; encodes an add-link.
- src/hooks/useCoordinator.ts: device-local store + presence probe. Health is
NOT Cordn RPC — it queries the coordinator's relays for authors:[pubkey] (its
ContextVM announcement/heartbeat), so a private/unannounced coordinator
honestly reads 'Not seen' rather than failing.
- src/components/CoordinatorSettingsCard.tsx + Settings -> Coordinator:
empty/connected states, add by paste or QR scan, add-link copy + QR, and a
'Run your own' hand-off (open Cordn, scan its QR, copy the docker command).
- smoke test now boots /settings?section=coordinator.