styrby-cli 0.1.0-beta.2 → 0.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -17264,22 +17264,22 @@ var require_nacl_fast = __commonJS({
17264
17264
  randombytes = fn;
17265
17265
  };
17266
17266
  (function() {
17267
- var crypto4 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
17268
- if (crypto4 && crypto4.getRandomValues) {
17267
+ var crypto3 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
17268
+ if (crypto3 && crypto3.getRandomValues) {
17269
17269
  var QUOTA = 65536;
17270
17270
  nacl2.setPRNG(function(x, n) {
17271
17271
  var i, v = new Uint8Array(n);
17272
17272
  for (i = 0; i < n; i += QUOTA) {
17273
- crypto4.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
17273
+ crypto3.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
17274
17274
  }
17275
17275
  for (i = 0; i < n; i++) x[i] = v[i];
17276
17276
  cleanup(v);
17277
17277
  });
17278
17278
  } else if (typeof __require !== "undefined") {
17279
- crypto4 = __require("crypto");
17280
- if (crypto4 && crypto4.randomBytes) {
17279
+ crypto3 = __require("crypto");
17280
+ if (crypto3 && crypto3.randomBytes) {
17281
17281
  nacl2.setPRNG(function(x, n) {
17282
- var i, v = crypto4.randomBytes(n);
17282
+ var i, v = crypto3.randomBytes(n);
17283
17283
  for (i = 0; i < n; i++) x[i] = v[i];
17284
17284
  cleanup(v);
17285
17285
  });
@@ -22449,101 +22449,51 @@ var init_local_server = __esm({
22449
22449
  });
22450
22450
 
22451
22451
  // src/auth/browser-auth.ts
22452
- import * as crypto2 from "node:crypto";
22453
- function generatePKCE() {
22454
- const verifierBytes = crypto2.randomBytes(32);
22455
- const verifier = verifierBytes.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
22456
- const hash = crypto2.createHash("sha256").update(verifier).digest();
22457
- const challenge = hash.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
22458
- return {
22459
- verifier,
22460
- challenge,
22461
- method: "S256"
22462
- };
22463
- }
22464
- function generateState() {
22465
- return crypto2.randomBytes(16).toString("base64url");
22466
- }
22467
- function buildAuthUrl(supabaseUrl, redirectUri, pkce, state, provider) {
22468
- const params = new URLSearchParams({
22469
- redirect_to: redirectUri,
22470
- code_challenge: pkce.challenge,
22471
- code_challenge_method: pkce.method,
22472
- state
22473
- });
22474
- if (provider) {
22475
- params.set("provider", provider);
22476
- }
22477
- return `${supabaseUrl}/auth/v1/authorize?${params.toString()}`;
22478
- }
22479
- function buildTokenUrl(supabaseUrl) {
22480
- return `${supabaseUrl}/auth/v1/token`;
22481
- }
22482
- async function exchangeCodeForTokens(supabaseUrl, code, verifier, redirectUri) {
22483
- const tokenUrl = buildTokenUrl(supabaseUrl);
22484
- const body = new URLSearchParams({
22485
- grant_type: "authorization_code",
22486
- code,
22487
- code_verifier: verifier,
22488
- redirect_uri: redirectUri
22489
- });
22490
- try {
22491
- const response = await fetch(tokenUrl, {
22492
- method: "POST",
22493
- headers: {
22494
- "Content-Type": "application/x-www-form-urlencoded"
22495
- },
22496
- body: body.toString()
22497
- });
22498
- if (!response.ok) {
22499
- const errorText = await response.text();
22500
- logger.debug("Token exchange failed", { status: response.status, error: errorText });
22501
- throw new AuthError(
22502
- "invalid_code",
22503
- `Token exchange failed: ${response.status} ${response.statusText}`
22504
- );
22505
- }
22506
- const data = await response.json();
22507
- return {
22508
- accessToken: data.access_token,
22509
- refreshToken: data.refresh_token,
22510
- expiresIn: data.expires_in,
22511
- tokenType: data.token_type,
22512
- user: {
22513
- id: data.user?.id || "",
22514
- email: data.user?.email,
22515
- name: data.user?.user_metadata?.full_name || data.user?.user_metadata?.name,
22516
- avatarUrl: data.user?.user_metadata?.avatar_url
22517
- }
22518
- };
22519
- } catch (error40) {
22520
- if (error40 instanceof AuthError) {
22521
- throw error40;
22522
- }
22523
- throw new AuthError(
22524
- "network_error",
22525
- "Failed to exchange authorization code for tokens",
22526
- error40
22527
- );
22528
- }
22529
- }
22530
22452
  async function startBrowserAuth(options) {
22531
- const { supabaseUrl, provider = "github", timeout = 12e4, skipBrowser = false } = options;
22532
- const pkce = generatePKCE();
22533
- const state = generateState();
22453
+ const {
22454
+ supabaseUrl,
22455
+ supabaseAnonKey,
22456
+ provider = "github",
22457
+ timeout = 12e4,
22458
+ skipBrowser = false
22459
+ } = options;
22534
22460
  logger.debug("Starting browser auth", { provider, supabaseUrl });
22535
22461
  const server = await startAuthCallbackServer({ timeout });
22536
22462
  const redirectUri = server.callbackUrl;
22537
22463
  logger.debug("Callback server started", { redirectUri, port: server.port });
22538
- const authUrl = buildAuthUrl(supabaseUrl, redirectUri, pkce, state, provider);
22464
+ const supabase = createClient(supabaseUrl, supabaseAnonKey || "dummy", {
22465
+ auth: {
22466
+ persistSession: false,
22467
+ autoRefreshToken: false,
22468
+ detectSessionInUrl: false,
22469
+ flowType: "pkce"
22470
+ }
22471
+ });
22472
+ const { data, error: oauthError } = await supabase.auth.signInWithOAuth({
22473
+ provider,
22474
+ options: {
22475
+ redirectTo: redirectUri,
22476
+ skipBrowserRedirect: true
22477
+ // We handle browser opening ourselves
22478
+ }
22479
+ });
22480
+ if (oauthError || !data?.url) {
22481
+ await server.close();
22482
+ throw new AuthError(
22483
+ "server_error",
22484
+ `Failed to create auth URL: ${oauthError?.message || "No URL returned"}`
22485
+ );
22486
+ }
22487
+ const authUrl = data.url;
22488
+ logger.debug("Auth URL generated by Supabase client", { authUrl, redirectUri });
22539
22489
  if (!skipBrowser) {
22540
22490
  logger.info("Opening browser for authentication...");
22541
- console.log("\n Please sign in with your Styrby account.\n");
22491
+ console.log("\n Sign in with GitHub to get started.\n");
22542
22492
  try {
22543
22493
  await open_default(authUrl);
22544
- } catch (error40) {
22494
+ } catch {
22545
22495
  console.log(" Could not open browser automatically.");
22546
- console.log(" Please open this URL manually:\n");
22496
+ console.log(" Please open this URL in your browser:\n");
22547
22497
  console.log(` ${authUrl}
22548
22498
  `);
22549
22499
  }
@@ -22554,12 +22504,6 @@ async function startBrowserAuth(options) {
22554
22504
  } finally {
22555
22505
  await server.close();
22556
22506
  }
22557
- if (callbackResult.state !== state) {
22558
- throw new AuthError(
22559
- "server_error",
22560
- "State mismatch - possible CSRF attack or stale auth flow"
22561
- );
22562
- }
22563
22507
  if (callbackResult.error) {
22564
22508
  throw new AuthError(
22565
22509
  "server_error",
@@ -22569,20 +22513,36 @@ async function startBrowserAuth(options) {
22569
22513
  if (!callbackResult.code) {
22570
22514
  throw new AuthError("server_error", "No authorization code received");
22571
22515
  }
22572
- logger.debug("Received authorization code, exchanging for tokens");
22573
- const result = await exchangeCodeForTokens(
22574
- supabaseUrl,
22575
- callbackResult.code,
22576
- pkce.verifier,
22577
- redirectUri
22516
+ logger.debug("Received authorization code, exchanging for session");
22517
+ const { data: sessionData, error: sessionError } = await supabase.auth.exchangeCodeForSession(
22518
+ callbackResult.code
22578
22519
  );
22579
- logger.debug("Authentication successful", { userId: result.user.id });
22580
- return result;
22520
+ if (sessionError || !sessionData?.session) {
22521
+ throw new AuthError(
22522
+ "invalid_code",
22523
+ `Token exchange failed: ${sessionError?.message || "No session returned"}`
22524
+ );
22525
+ }
22526
+ const { session } = sessionData;
22527
+ logger.debug("Authentication successful", { userId: session.user.id });
22528
+ return {
22529
+ accessToken: session.access_token,
22530
+ refreshToken: session.refresh_token,
22531
+ expiresIn: session.expires_in ?? 3600,
22532
+ tokenType: session.token_type ?? "bearer",
22533
+ user: {
22534
+ id: session.user.id,
22535
+ email: session.user.email,
22536
+ name: session.user.user_metadata?.full_name || session.user.user_metadata?.name,
22537
+ avatarUrl: session.user.user_metadata?.avatar_url
22538
+ }
22539
+ };
22581
22540
  }
22582
22541
  var AuthError;
22583
22542
  var init_browser_auth = __esm({
22584
22543
  "src/auth/browser-auth.ts"() {
22585
22544
  init_open();
22545
+ init_dist4();
22586
22546
  init_logger();
22587
22547
  init_local_server();
22588
22548
  AuthError = class extends Error {
@@ -22596,17 +22556,12 @@ var init_browser_auth = __esm({
22596
22556
  __name(this, "AuthError");
22597
22557
  }
22598
22558
  };
22599
- __name(generatePKCE, "generatePKCE");
22600
- __name(generateState, "generateState");
22601
- __name(buildAuthUrl, "buildAuthUrl");
22602
- __name(buildTokenUrl, "buildTokenUrl");
22603
- __name(exchangeCodeForTokens, "exchangeCodeForTokens");
22604
22559
  __name(startBrowserAuth, "startBrowserAuth");
22605
22560
  }
22606
22561
  });
22607
22562
 
22608
22563
  // src/auth/machine-registration.ts
22609
- import * as crypto3 from "node:crypto";
22564
+ import * as crypto2 from "node:crypto";
22610
22565
  import * as os5 from "node:os";
22611
22566
  function generateMachineFingerprint() {
22612
22567
  const components = [
@@ -22615,10 +22570,10 @@ function generateMachineFingerprint() {
22615
22570
  process.platform,
22616
22571
  os5.homedir()
22617
22572
  ].join(":");
22618
- return crypto3.createHash("sha256").update(components).digest("hex");
22573
+ return crypto2.createHash("sha256").update(components).digest("hex");
22619
22574
  }
22620
22575
  function generateMachineId() {
22621
- return crypto3.randomUUID();
22576
+ return crypto2.randomUUID();
22622
22577
  }
22623
22578
  function getMachineName() {
22624
22579
  return os5.hostname();
@@ -22640,7 +22595,7 @@ async function registerMachine(supabase, userId, existingMachineId) {
22640
22595
  platform: platform3
22641
22596
  });
22642
22597
  try {
22643
- const { data: existing, error: selectError } = await supabase.from("machines").select("id, fingerprint, name, platform, created_at").eq("user_id", userId).eq("fingerprint", fingerprint).single();
22598
+ const { data: existing, error: selectError } = await supabase.from("machines").select("id, machine_fingerprint, name, platform, created_at").eq("user_id", userId).eq("machine_fingerprint", fingerprint).single();
22644
22599
  if (selectError && selectError.code !== "PGRST116") {
22645
22600
  throw new MachineRegistrationError(
22646
22601
  `Failed to check existing machine: ${selectError.message}`,
@@ -22663,7 +22618,7 @@ async function registerMachine(supabase, userId, existingMachineId) {
22663
22618
  isNew: false,
22664
22619
  machine: {
22665
22620
  machineId: existing.id,
22666
- fingerprint: existing.fingerprint,
22621
+ fingerprint: existing.machine_fingerprint,
22667
22622
  machineName: existing.name || machineName,
22668
22623
  platform: existing.platform || platform3,
22669
22624
  platformVersion
@@ -22676,14 +22631,14 @@ async function registerMachine(supabase, userId, existingMachineId) {
22676
22631
  const { data: inserted, error: insertError } = await supabase.from("machines").insert({
22677
22632
  id: machineId,
22678
22633
  user_id: userId,
22679
- fingerprint,
22634
+ machine_fingerprint: fingerprint,
22680
22635
  name: machineName,
22681
22636
  platform: platform3,
22682
22637
  platform_version: platformVersion,
22683
22638
  is_online: true,
22684
22639
  last_seen_at: now,
22685
22640
  created_at: now
22686
- }).select("id, fingerprint, name, platform, created_at").single();
22641
+ }).select("id, machine_fingerprint, name, platform, created_at").single();
22687
22642
  if (insertError) {
22688
22643
  if (insertError.code === "23505") {
22689
22644
  return registerMachine(supabase, userId, existingMachineId);
@@ -22698,7 +22653,7 @@ async function registerMachine(supabase, userId, existingMachineId) {
22698
22653
  isNew: true,
22699
22654
  machine: {
22700
22655
  machineId: inserted.id,
22701
- fingerprint: inserted.fingerprint,
22656
+ fingerprint: inserted.machine_fingerprint,
22702
22657
  machineName: inserted.name || machineName,
22703
22658
  platform: inserted.platform || platform3,
22704
22659
  platformVersion
@@ -22797,11 +22752,12 @@ function displayPreflightChecks(checks) {
22797
22752
  }
22798
22753
  async function runAuthentication(options) {
22799
22754
  console.log(source_default.bold("\n [2/6] Opening browser for authentication..."));
22800
- console.log(" Please sign in with your Styrby account.");
22755
+ console.log(" Sign in with GitHub to create your account.");
22801
22756
  console.log(source_default.dim(" Waiting for authentication..."));
22802
22757
  try {
22803
22758
  const result = await startBrowserAuth({
22804
22759
  supabaseUrl: SUPABASE_URL,
22760
+ supabaseAnonKey: SUPABASE_ANON_KEY,
22805
22761
  provider: "github",
22806
22762
  timeout: options.timeout || 12e4
22807
22763
  });
@@ -42568,7 +42524,7 @@ var init_package = __esm({
42568
42524
  "package.json"() {
42569
42525
  package_default = {
42570
42526
  name: "styrby-cli",
42571
- version: "0.1.0-beta.2",
42527
+ version: "0.1.0-beta.3",
42572
42528
  description: "Mobile remote control for AI coding agents. Control Claude Code, Codex, Gemini, and OpenCode from your phone.",
42573
42529
  author: {
42574
42530
  name: "Steel Motion LLC",
@@ -46365,7 +46321,7 @@ async function handleAuth() {
46365
46321
  async function handlePair() {
46366
46322
  const qrcode2 = await Promise.resolve().then(() => __toESM(require_main4(), 1));
46367
46323
  const os6 = await import("os");
46368
- const crypto4 = await import("crypto");
46324
+ const crypto3 = await import("crypto");
46369
46325
  const { createClient: createClient2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
46370
46326
  const chalk2 = (await Promise.resolve().then(() => (init_source(), source_exports))).default;
46371
46327
  const { encodePairingUrl: encodePairingUrl2, generatePairingToken: generatePairingToken2, PAIRING_EXPIRY_MINUTES: PAIRING_EXPIRY_MINUTES2, createRelayClient: createRelayClient2 } = await Promise.resolve().then(() => (init_src(), src_exports));
@@ -46375,7 +46331,7 @@ async function handlePair() {
46375
46331
  logger.error('Not authenticated. Please run "styrby onboard" first.');
46376
46332
  process.exit(1);
46377
46333
  }
46378
- const machineId = data.machineId || `machine_${crypto4.randomUUID()}`;
46334
+ const machineId = data.machineId || `machine_${crypto3.randomUUID()}`;
46379
46335
  const deviceName = os6.hostname();
46380
46336
  const token = generatePairingToken2();
46381
46337
  const { config: config3 } = await Promise.resolve().then(() => (init_env(), env_exports));
@@ -46972,7 +46928,7 @@ var init_index = __esm({
46972
46928
  "src/index.ts"() {
46973
46929
  init_logger();
46974
46930
  init_AgentRegistry();
46975
- VERSION = "0.1.0-beta.2";
46931
+ VERSION = "0.1.0-beta.3";
46976
46932
  __name(main, "main");
46977
46933
  __name(handleStop2, "handleStop");
46978
46934
  __name(handleLogs2, "handleLogs");