extremely claude-assisted go game based on atproto! working on cleaning up and giving a more unique design, still has a bit of a slop vibe to it.

API Usage Guide#

Authentication Endpoints#

Login#

POST /auth/login

Start OAuth authentication with a Bluesky handle, DID, or PDS URL.

curl -X POST http://localhost:5173/auth/login \
  -H "Content-Type: application/json" \
  -d '{"handle":"alice.bsky.social"}'

Response: Redirects to OAuth authorization page


Logout#

POST /auth/logout

Revoke OAuth tokens and clear session.

curl -X POST http://localhost:5173/auth/logout \
  --cookie "go_session=..."

Response: Redirects to home page


Game Endpoints#

Create Game#

POST /api/games

Create a new Go game. Requires authentication.

curl -X POST http://localhost:5173/api/games \
  -H "Content-Type: application/json" \
  --cookie "go_session=..." \
  -d '{"boardSize": 19}'

Request Body:

{
  "boardSize": 9 | 13 | 19  // Optional, defaults to 19
}

Response:

{
  "gameId": "3l4k5j6h7g8f9",
  "uri": "at://did:plc:abc123/boo.sky.go.game/3l4k5j6h7g8f9"
}

Join Game#

POST /api/games/[id]/join

Join an existing game as the second player.

curl -X POST http://localhost:5173/api/games/3l4k5j6h7g8f9/join \
  --cookie "go_session=..."

Response:

{
  "success": true
}

Errors:

  • 401 - Not authenticated
  • 404 - Game not found
  • 400 - Game not in "waiting" status
  • 400 - Cannot join own game
  • 400 - Game already has two players

Make Move#

POST /api/games/[id]/move

Place a stone on the board.

curl -X POST http://localhost:5173/api/games/3l4k5j6h7g8f9/move \
  -H "Content-Type: application/json" \
  --cookie "go_session=..." \
  -d '{"x": 3, "y": 3, "captureCount": 0}'

Request Body:

{
  "x": 0-18,          // Column position (0-based)
  "y": 0-18,          // Row position (0-based)
  "captureCount": 0   // Number of stones captured by this move
}

Response:

{
  "success": true,
  "uri": "at://did:plc:abc123/boo.sky.go.move/3l4k5j6h7g8f9"
}

Move Rules:

  • Black plays first (player one)
  • Players alternate turns
  • Game must be "active" (two players joined)
  • Must be your turn

Pass Turn#

POST /api/games/[id]/pass

Pass your turn without placing a stone.

curl -X POST http://localhost:5173/api/games/3l4k5j6h7g8f9/pass \
  --cookie "go_session=..."

Response:

{
  "success": true,
  "uri": "at://did:plc:abc123/boo.sky.go.pass/3l4k5j6h7g8f9"
}

Special Behavior:

  • Two consecutive passes end the game
  • Game status changes to "completed"

OAuth Metadata Endpoints#

Client Metadata#

GET /oauth-client-metadata.json

Returns OAuth client metadata for discovery.

curl http://localhost:5173/oauth-client-metadata.json

JWKS (Public Keys)#

GET /jwks.json

Returns JSON Web Key Set for token verification.

curl http://localhost:5173/jwks.json

Using the UI#

Create a Game#

  1. Log in with your Bluesky handle
  2. On the home page, select board size (9x9, 13x13, or 19x19)
  3. Click "Create Game"
  4. Your game appears in the "Waiting for Players" list

Join a Game#

  1. Log in with your Bluesky handle
  2. Browse the list of waiting games
  3. Click "Join" on any game
  4. You'll be redirected to the game board

Play#

  1. Click on the board to place stones
  2. Click "Pass" to skip your turn
  3. Two consecutive passes end the game

Game States#

  • waiting - Game created, waiting for second player
  • active - Two players joined, game in progress
  • completed - Game ended (two passes or manual completion)

Testing Flow#

# 1. Create a game
GAME_ID=$(curl -X POST http://localhost:5173/api/games \
  -H "Content-Type: application/json" \
  --cookie "go_session=YOUR_SESSION_1" \
  -d '{"boardSize": 9}' | jq -r '.gameId')

echo "Created game: $GAME_ID"

# 2. Join with second player
curl -X POST http://localhost:5173/api/games/$GAME_ID/join \
  --cookie "go_session=YOUR_SESSION_2"

# 3. Player 1 makes first move (black)
curl -X POST http://localhost:5173/api/games/$GAME_ID/move \
  -H "Content-Type: application/json" \
  --cookie "go_session=YOUR_SESSION_1" \
  -d '{"x": 3, "y": 3, "captureCount": 0}'

# 4. Player 2 makes move (white)
curl -X POST http://localhost:5173/api/games/$GAME_ID/move \
  -H "Content-Type: application/json" \
  --cookie "go_session=YOUR_SESSION_2" \
  -d '{"x": 3, "y": 4, "captureCount": 0}'

# 5. Pass to end game (both players)
curl -X POST http://localhost:5173/api/games/$GAME_ID/pass \
  --cookie "go_session=YOUR_SESSION_1"

curl -X POST http://localhost:5173/api/games/$GAME_ID/pass \
  --cookie "go_session=YOUR_SESSION_2"

Error Codes#

  • 400 - Bad request (invalid parameters, validation failed)
  • 401 - Not authenticated (missing or invalid session)
  • 404 - Resource not found
  • 500 - Server error

All error responses include a message describing the issue.