{"id":13638482,"url":"https://github.com/polrel-witter/live","last_synced_at":"2025-04-19T18:30:38.104Z","repository":{"id":209079047,"uuid":"667619968","full_name":"polrel-witter/live","owner":"polrel-witter","description":"An event coordination app on Urbit","archived":false,"fork":false,"pushed_at":"2024-10-24T11:00:12.000Z","size":826,"stargazers_count":6,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-24T16:56:01.493Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"hoon","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/polrel-witter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-07-17T23:54:39.000Z","updated_at":"2024-10-22T14:14:56.000Z","dependencies_parsed_at":"2023-12-02T21:25:32.378Z","dependency_job_id":"9f4cf751-dac8-45d9-b8ee-002dddeefcf3","html_url":"https://github.com/polrel-witter/live","commit_stats":null,"previous_names":["polrel-witter/live"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polrel-witter%2Flive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polrel-witter%2Flive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polrel-witter%2Flive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polrel-witter%2Flive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/polrel-witter","download_url":"https://codeload.github.com/polrel-witter/live/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249764700,"owners_count":21322286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-02T01:00:46.595Z","updated_at":"2025-04-19T18:30:38.097Z","avatar_url":"https://github.com/polrel-witter.png","language":"hoon","funding_links":[],"categories":["Applications"],"sub_categories":[],"readme":"# Overview\n%live is a protocol and web app for organizing social events. It's best approached from two perspectives:\n\n### As an event host\nThe core data structure is an `$event` which consists of the following:\n- Basic info: title, description, location, venue map, a start and end date, the kind of event, and status of the event.\n- A series of sessions within the event (i.e. sub events).\n- Max number of guests.\n- A Tlon group link.\n- An optional secret message for registrants.\n\nOnce an event is written to state, the host can begin building a guest list which are stored as `$record`s. This can be done in one of two ways: either by inviting ships directly or sharing the event link so that others can find it.\n\nEvent discoverability functions differently based on its `$kind`. `%public` and `%private` events are searchable; `%secret` ones are hidden, leaving the host to invite ships directly.\n\nAdditionally, `$record` status changes will behave differently according to these types:\n- `%public`: anyone can send a `%register` poke and get a `%registered` status.\n- `%private`: if a `%register` poke is sent the guest's status will initiate to `%requested` forcing the host to register them, unless the host invites them first.\n- `%secret`: invite-only.\n\nFinally, the status of an event (i.e. its `$latch`) will also change its registration behavior:\n- `%open`: actively accepting registrants.\n- `%closed`: all `%register` pokes will default to a `%requested` status.\n- `%over`: the event is archived so pokes (excluding a `$latch` change) will fail.\n\n### As a guest\nWith a `$record` to an event, a guest will have one of 5 statuses:\n- `%invited` (ditto)\n- `%requested` (requesting access to a private or closed event; subject to host\n  approval)\n- `%registered` (has access to the event)\n- `%unregistered` (registration was revoked either by the host or guest\n  themselves)\n- `%attended` (for bookkeeping purposes, indicating a guest 'showed up')\n\nA `$record` contains the event `$info`, as well as, guest access data (status and time of status change) and the event `$secret`, if the status is `%registered` or `%attended`.\n\n#### Matching\nAs a way to facilitate guest networking, `%live` includes a matching feature. This begins with a guest setting their profile (i.e. contact fields such as github, X handle, etc), which is stored locally and sent to guests they match with.\n\nWithin the event page there's a Connections tab that will display guest profiles. When a guest initiates a match request, the `%matcher` agent sends a positive `%shake` poke to the host ship where the connection status is stored locally until the recipient initiates a postive `%shake` on their own accord. The host ship notifies both parties of the match when it becomes mutual. At this point, profile info is shared with each other, directly. Profile data is never sent to the host unless a guest matches with them.\n\nAs the host, this operation is handled automatically in the background.\n\n# Pokes\n## %live\nMost pokes are event-specific and sent via an `$operation`. An operation requires the event `$id` and an `$action` to be performed on the event. All actions are explained in `desk/sur/live.hoon`.\n\nNon-event-specific pokes take a `$dial`, which includes a `%find` and `%case` option. `%find` is an external event search and `%case` is a purely backend function: used to obtain the remote scry endpoint's 'latest' revision number.\n\n## %matcher\nThere are two poke types:\n- `$dictum` a host-only action\n- `$deed` a host or guest action\n\nAll pokes are defined in `desk/sur/matcher.hoon`. The only ones that aren't implicitly handled by `%matcher` are `%edit-profile` and `%shake`, to change profile info and match with guests, respectively.\n\n# Scries\n## %live\nThe `%live` agent contains the following scry endpoints. Each result in a `$demand` type, defined in `/desk/sur/live.hoon`. References to 'host ship' and 'name' correlate to the event id: `[=ship name=term]`.\n\n### %u scries\n`/event/exists/[host ship]/[name]` -\u003e does an event exist?\n\n`/record/exists/[host ship]/[name]/[guest ship]` -\u003e does a record exist?\n\n### %x scries\n`/result` -\u003e latest search result\n\n`/events/all` -\u003e a map of all events\n\n`/records/all` -\u003e a mip of all records\n\n`/events/remote` -\u003e a map of events discoverable over remote scry (i.e. %public and %private that aren't %over)\n\n`/records/[host ship]/[name]` -\u003e a map of all records for a specific event\n\n`/event/[host ship]/[name]` -\u003e an event\n\n`/session/ids/[host ship]/[name]` -\u003e all session ids and their corresponding title for an event\n\n`/record/[host ship]/[name]/[guest ship]` -\u003e a record\n\n`/counts/[host ship]/[name]` -\u003e a map of record statuses with their cumulative\ntotals\n\n## %matcher\nThese result in a `$demand` type defined in `desk/sur/matcher.hoon`.\n\n### %x scries\n`/pals/add` -\u003e boolean setting indicating whether we're converting matched ships to %pals and adding event tags\n\n`/profile/[ship]` -\u003e a profile\n\n`/all/profiles` -\u003e a map of all profiles\n\n`/peer-status/[host ship]/[name]/[ship]` -\u003e a peer's status\n\n`/peers/[host ship]/[name]` -\u003e a map of all peers\n\n`/matches/[host ship]/[name]` -\u003e a map of matches (only the host will\nhave this data)\n\n`/reaches/[host ship]/[name]` -\u003e a map of initialized matches, i.e. not\nyet mutual (only the host will have this data)\n\n# Subscriptions\nBackend solid state subscriptions are maintained in `%live` and `%matcher` to keep `$record`s and peer `$status`es in sync between host and guests.\n\nThere's also a local subscription maintained for frontend updates on the following paths:\n- %matcher: `/updates`\n- %live: `/updates`, `/errors`, and `/search`\n\n# Install\n### On Urbit\n`|install ~mocbel %live`\n\n### From source\n1. create a blank desk: `|new-desk %live`\n2. mount to filesystem: `|mount %live`\n3. sync this repo with mounted desk: `rsync -avL \u003cthis repo\u003e \u003cmounted desk in pier\u003e`\n4. `|commit %live`\n5. `|install our %live`\n\n# Feedback and support\nPlease dm `~polrel-witter` on Urbit or [@polrel_wittter](https://x.com/polrel_witter) on X.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolrel-witter%2Flive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolrel-witter%2Flive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolrel-witter%2Flive/lists"}