Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,64 @@ DATABASE_URL=postgres://user:pass@host/nixamp NIXAMP_JWT_SECRET=… nixamp serve
Accounts live where the directory lives and nowhere else: a nixamp on a laptop
has nobody to be an account of.

## Watch parties, and signing in with nixamp

A watch party lives on the site that has the film. bittorrented.com has them:
a six-character code, a host, and everybody at the same second. nixamp has
rooms, chat, invitations, a directory, and five clients that can already open
one. A bridged party is both.

The identity link is **OAuth 2.1**, with nixamp.com as the authorization
server. The site sends somebody here, they approve it once, and the site holds
a token that acts on their nixamp account. It is 2.1 and not 2.0, so:

- authorization code only, with PKCE (S256) required of every client, public
or confidential. No implicit grant, no password grant.
- redirect URIs match the registered string exactly; only a loopback port may
vary, because a CLI cannot know its port before it listens.
- a code is spent once; presenting it twice withdraws everything it produced.
- refresh tokens rotate, and a retired one presented again withdraws the whole
family.

The endpoints are where RFC 8414 says to look for them:

```
GET /.well-known/oauth-authorization-server
GET /api/v1/oauth/authorize the consent page
POST /api/v1/oauth/token authorization_code, refresh_token
POST /api/v1/oauth/revoke
GET /api/v1/oauth/userinfo
```

Scopes are `profile`, `email`, `parties` and `offline_access`. The Account
panel on nixamp.com lists what is connected and takes it away again.

bittorrented.com is registered out of the box. Another client is added with
`NIXAMP_OAUTH_CLIENTS`, a JSON list:

```
NIXAMP_OAUTH_CLIENTS='[{"id":"example","name":"Example","redirectUris":["https://example.com/cb"]}]'
```

Once a party is bridged it is an ordinary live event with a room, so every
surface already knows what to do with it:

```
nixamp party list the ones you could join right now
nixamp party join ABC123 --open the room here, the film where it lives
nixamp party host ABC123 --url URL put one on the air as a nixamp room
nixamp party sync ABC123 --at 930 where playback is (hosts only)
```

and an agent reaches the same five actions over the Model Context Protocol:

```
nixamp mcp a stdio MCP server: list, get, host, sync, end
```

It acts as whoever the machine is signed in as, so `nixamp login` comes first.
The film never crosses over: what nixamp carries is the room.

## BackToSchool.help

BackToSchool.help is a branded, mobile-first client for NixAmp live events. It
Expand Down
41 changes: 41 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ const HELP = `nixamp — it really whips the terminal's ass.
nixamp dns [set|rm] names under your handle, for your servers
nixamp library [folder] where the media is; the daemon serves this and nothing outside it
nixamp server list|add|remove the machines you run, kept against your account
nixamp party list|join|host watch parties, here and on the sites nixamp is connected to
nixamp mcp speak Model Context Protocol on stdin, for an agent
nixamp opendir list|add|remove folders found on the web, published for everyone
nixamp update [version] re-run the installer, keeping your choices
nixamp uninstall [--yes] remove everything the installer created
Expand Down Expand Up @@ -234,6 +236,35 @@ A share link printed in a terminal you have since closed is a server you have
lost. This keeps the address against your account, so the answer is the same
here, in the browser and in the desktop app. The share key is kept with it only
if you pass one, since it is the secret that opens the machine.
`,
party: `nixamp party — watch parties, here and on the sites nixamp is connected to.

nixamp party list the ones you could join right now
nixamp party join CODE the room, the links, and where the film is
nixamp party join CODE --open and open the picture in a browser
nixamp party host CODE --url URL put a party on the air as a nixamp room
nixamp party sync CODE --at 1234 say where playback is (hosts only)
nixamp party end CODE end it

A watch party lives on the site that has the film — bittorrented.com, say —
and is bridged into nixamp as a room, so every nixamp client can join it: the
browser, this terminal, the desktop app, the television and an agent over MCP.
The film stays where it is; what nixamp carries is the room, the chat and the
second everybody is supposed to be at.

The site connects to your nixamp account with OAuth 2.1, which you approve
once in a browser. The Account panel on nixamp.com lists what is connected and
takes it away again.
`,
mcp: `nixamp mcp — nixamp as a tool an agent can use.

nixamp mcp speak Model Context Protocol on stdin and stdout

It offers the watch party tools: list them, read one, put one on the air,
say where playback is, end it. It acts as whoever this machine is signed in
as, so \`nixamp login\` (or NIXAMP_TOKEN) comes first.

Point an MCP client at it as a stdio server running \`nixamp mcp\`.
`,
attach: `nixamp attach — the player, in front of the running daemon.

Expand Down Expand Up @@ -424,6 +455,16 @@ export async function main(): Promise<void> {
process.exitCode = await servers(rest);
return;
}
if (first === "party" || first === "parties" || first === "watch-party") {
const { party } = await import("./party.ts");
process.exitCode = await party(rest);
return;
}
if (first === "mcp") {
const { mcp } = await import("./mcp.ts");
process.exitCode = await mcp();
return;
}
if (first === "token" || first === "tokens") {
const { tokens } = await import("./session.ts");
process.exitCode = await tokens(rest);
Expand Down
Loading