Skip to content

Commit 8abeecb

Browse files
authored
feat(create-pds): add create-pds cli (#19)
1 parent 0058743 commit 8abeecb

25 files changed

Lines changed: 1072 additions & 155 deletions

EDGE_PDS_PLAN.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,49 @@ Build a single-user AT Protocol Personal Data Server (PDS) on Cloudflare Workers
108108

109109
- None! All planned phases are complete.
110110

111+
### Future Work: did:plc Migration Support
112+
113+
Account migration is now possible from bsky.social. To support users migrating their existing `did:plc` accounts to this PDS, we need to implement the full migration flow.
114+
115+
**Migration Flow (4 phases):**
116+
117+
1. **Account Creation** - New PDS creates account in "deactivated" state with existing DID
118+
2. **Data Migration** - Export repo as CAR, import to new PDS, migrate blobs
119+
3. **Identity Update** - Old PDS signs PLC operation, new PDS submits to plc.directory
120+
4. **Finalization** - Activate on new PDS, deactivate on old
121+
122+
**Endpoints needed for incoming migration:**
123+
124+
| Endpoint | Status | Purpose |
125+
| --------------------------------------------------- | ------ | ------------------------------------- |
126+
| `com.atproto.server.createAccount` || Create account with existing DID |
127+
| `com.atproto.identity.getRecommendedDidCredentials` || Provide DID params for PLC operation |
128+
| `com.atproto.identity.submitPlcOperation` || Submit signed PLC op to plc.directory |
129+
| `com.atproto.server.activateAccount` || Activate migrated account |
130+
| `com.atproto.repo.listMissingBlobs` || Check which blobs need migration |
131+
132+
**Endpoints needed for outgoing migration:**
133+
134+
| Endpoint | Status | Purpose |
135+
| --------------------------------------------------- | ------ | ----------------------------------------- |
136+
| `com.atproto.server.getServiceAuth` || Generate service auth token for migration |
137+
| `com.atproto.identity.requestPlcOperationSignature` || Request email verification token |
138+
| `com.atproto.identity.signPlcOperation` || Sign PLC operation with rotation key |
139+
| `com.atproto.server.deactivateAccount` || Deactivate account after migration |
140+
141+
**Already implemented:**
142+
143+
-`com.atproto.sync.getRepo` - Export repository as CAR
144+
-`com.atproto.repo.importRepo` - Import repository from CAR
145+
-`com.atproto.sync.listBlobs` - List blobs for migration
146+
-`com.atproto.server.getAccountStatus` - Check account status
147+
148+
**References:**
149+
150+
- [Account Migration - AT Protocol](https://atproto.com/guides/account-migration)
151+
- [Account Migration Details Discussion](https://github.com/bluesky-social/atproto/discussions/3176)
152+
- [Enabling Account Migration Back to Bluesky's PDS](https://docs.bsky.app/blog/incoming-migration)
153+
111154
### Testing & Development Notes
112155

113156
**Vitest 4 Migration**: Successfully migrated to vitest 4 with `@cloudflare/vitest-pool-workers` PR build (#11632). This required:
@@ -195,7 +238,7 @@ for (const [cidStr, bytes] of internalMap) { ... }
195238
| ----------------- | --------------------------------------- |
196239
| OAuth Provider | Complex, not needed for single-user MVP |
197240
| Rate Limiting | Single user, not needed for MVP |
198-
| Account Migration | Complex, post-MVP feature |
241+
| did:plc Migration | Complex - see "Future Work" section |
199242
| Labelling | AppView concern, not PDS |
200243

201244
---
@@ -2064,6 +2107,7 @@ wrangler secret put PASSWORD_HASH # Generate: npx bcryptjs hash "your-password"
20642107
- Email verification
20652108
- Rate limiting
20662109
- Advanced admin endpoints
2110+
- Full did:plc migration (partial support exists - see "Future Work" section)
20672111
20682112
These can all be added later.
20692113

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
A single-user AT Protocol Personal Data Server (PDS) running on Cloudflare Workers with Durable Objects.
44

5+
> **⚠️ Experimental Software**
6+
>
7+
> This is an early-stage project under active development. **Do not migrate your main Bluesky account to this PDS yet.** Use a test account or create a new identity for experimentation. Data loss, breaking changes, and missing features are expected.
8+
59
## Overview
610

711
This PDS is designed to federate with the Bluesky network - relays can sync from it, and AppViews can read from it.

demos/pds/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
This is an example deployment of `@ascorbic/pds-worker` - a single-user AT Protocol Personal Data Server on Cloudflare Workers.
44

5+
> **⚠️ Experimental Software**
6+
>
7+
> This is an early-stage project under active development. **Do not migrate your main Bluesky account to this PDS yet.** Use a test account or create a new identity for experimentation.
8+
59
## Setup
610

711
### 1. Install dependencies
@@ -15,7 +19,7 @@ pnpm install
1519
Use the PDS CLI to generate keys and configure your local dev environment:
1620

1721
```bash
18-
pnpm pds init --local
22+
pnpm pds init
1923
```
2024

2125
This will prompt for your hostname, handle, and password, then write configuration to `.dev.vars`.

demos/pds/wrangler.jsonc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
// Demo PDS Deployment
3-
// Run `pnpm pds init` to configure, or `pnpm pds init --local` for local dev
3+
// Run `pnpm pds init` to configure, or `pnpm pds init --production` to deploy secrets
44
"name": "atproto-pds",
55
"main": "src/index.ts",
66
"compatibility_date": "2025-12-02",

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"version": "1.0.0",
55
"description": "AT Protocol PDS on Cloudflare Workers",
66
"scripts": {
7-
"check": "pnpm run --filter @ascorbic/* check",
8-
"test": "pnpm run --filter @ascorbic/* test",
9-
"build": "pnpm run --filter @ascorbic/* build",
7+
"check": "pnpm run --filter '@ascorbic/*' --filter 'create-pds' check",
8+
"test": "pnpm run --filter '@ascorbic/*' --filter 'create-pds' test",
9+
"build": "pnpm run --filter '@ascorbic/*' --filter 'create-pds' build",
1010
"format": "prettier --write ."
1111
},
1212
"keywords": [],

packages/create-pds/package.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "create-pds",
3+
"version": "0.0.0",
4+
"description": "Create a new AT Protocol PDS on Cloudflare Workers",
5+
"type": "module",
6+
"bin": {
7+
"create-pds": "./dist/index.js"
8+
},
9+
"files": [
10+
"dist",
11+
"templates"
12+
],
13+
"scripts": {
14+
"build": "tsdown",
15+
"test": "vitest run",
16+
"check": "publint"
17+
},
18+
"devDependencies": {
19+
"@clack/prompts": "^0.11.0",
20+
"@types/node": "^24.10.4",
21+
"citty": "^0.1.6",
22+
"publint": "^0.3.16",
23+
"tsdown": "^0.18.3",
24+
"typescript": "^5.9.3"
25+
},
26+
"repository": {
27+
"type": "git",
28+
"url": "git+https://github.com/ascorbic/atproto-worker.git",
29+
"directory": "packages/create-pds"
30+
},
31+
"homepage": "https://github.com/ascorbic/atproto-worker",
32+
"keywords": [
33+
"atproto",
34+
"bluesky",
35+
"pds",
36+
"cloudflare-workers"
37+
],
38+
"author": "Matt Kane",
39+
"license": "MIT"
40+
}

0 commit comments

Comments
 (0)