File size: 1,456 Bytes
64648ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { createHash, randomBytes } from "node:crypto";
import { createDb, invites } from "@paperclipai/db";

function hashToken(token: string) {
  return createHash("sha256").update(token).digest("hex");
}

function createInviteToken() {
  return `pcp_bootstrap_${randomBytes(24).toString("hex")}`;
}

async function main() {
  const dbUrl = process.env.DATABASE_URL || "postgres://paperclip:paperclip@localhost:5432/paperclip";
  const db = createDb(dbUrl);
  
  try {
    // Check if admin exists
    const adminCount = await db.select({ count: invites.id }).from(invites).limit(1).then(rows => rows.length);
    
    const token = createInviteToken();
    const expiresAt = new Date(Date.now() + 72 * 60 * 60 * 1000); // 72 hours
    
    const created = await db
      .insert(invites)
      .values({
        inviteType: "bootstrap_ceo",
        tokenHash: hashToken(token),
        allowedJoinTypes: "human",
        expiresAt,
        invitedByUserId: "system",
      })
      .returning()
      .then(rows => rows[0]);
    
    const baseUrl = process.env.PAPERCLIP_PUBLIC_URL || "http://localhost:3100";
    const inviteUrl = `${baseUrl}/invite/${token}`;
    
    console.log("Created bootstrap CEO invite.");
    console.log(`Invite URL: ${inviteUrl}`);
    console.log(`Expires: ${created.expiresAt.toISOString()}`);
  } finally {
    await (db as any).$client?.end?.({ timeout: 5 }).catch(() => undefined);
  }
}

main().catch(console.error);