rechrome 1.9.1 → 1.10.0

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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/rech.js +29 -11
  3. package/rech.ts +29 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rechrome",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/snomiao/rechrome.git"
package/rech.js CHANGED
@@ -11,8 +11,8 @@ export const DEFAULT_PORT = 13775;
11
11
  export const RECH_DIR = join(import.meta.dir, ".rech");
12
12
  export const LOG_DIR = join(RECH_DIR, "logs");
13
13
 
14
- const RECH_HOME_DIR = join(process.env.HOME!, ".rech");
15
- const TOKENS_FILE = join(RECH_HOME_DIR, "tokens.json");
14
+ const RECH_HOME_DIR = join(process.env.HOME!, ".rechrome");
15
+ const TOKENS_FILE = join(RECH_HOME_DIR, "profiles.json");
16
16
 
17
17
  type TokenEntry = { extensionId: string; token: string; profileDir: string; userDataDir?: string };
18
18
 
@@ -362,7 +362,7 @@ async function callServe(
362
362
  process.exit(1);
363
363
  });
364
364
  if (res.status === 401) {
365
- console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected -> playwright[unknown]`);
365
+ console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected (used: ${key.slice(0, 6)}...) -> playwright[unknown]`);
366
366
  process.exit(1);
367
367
  }
368
368
  return res.json();
@@ -549,13 +549,18 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
549
549
  const { host, port, protocol } = parseUrl(url);
550
550
 
551
551
  const { key: serveKey } = parseUrl(url);
552
- const authPing = await fetch(`${protocol}://${host}:${port}/ping`, {
552
+ // First check if server is up at all (unauthenticated root), then verify our key matches
553
+ const anonPing = await fetch(`${protocol}://${host}:${port}/`, { signal: AbortSignal.timeout(2000) }).catch(() => null);
554
+ const authPing = anonPing ? await fetch(`${protocol}://${host}:${port}/ping`, {
553
555
  headers: { Authorization: `Bearer ${serveKey}` },
554
556
  signal: AbortSignal.timeout(2000),
555
- }).catch(() => null);
556
- if (authPing?.ok) {
557
+ }).catch(() => null) : null;
558
+ if (anonPing && authPing?.ok) {
557
559
  console.log(` Already running at ${protocol}://${host}:${port} — skipping reinstall`);
558
560
  await runOxmgr(["service", "install"]);
561
+ } else if (anonPing && !authPing?.ok) {
562
+ console.log(` Server running but key mismatch — reinstalling with new key`);
563
+ await daemonInstall(url);
559
564
  } else {
560
565
  await daemonInstall(url);
561
566
  console.log(` Registered daemon: ${OXMGR_PROCESS_NAME}`);
@@ -603,7 +608,7 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
603
608
  return available[idx];
604
609
  }
605
610
 
606
- async function getExtAndToken(profileDir: string, profileDisplay: string): Promise<{ extId: string; token: string } | null> {
611
+ async function getExtAndToken(profileDir: string, profileDisplay: string, profileKey: string): Promise<{ extId: string; token: string } | null> {
607
612
  // Extension check
608
613
  let extId: string | undefined;
609
614
  while (true) {
@@ -620,6 +625,19 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
620
625
  }
621
626
  console.log(` Extension found: ${extId}`);
622
627
 
628
+ // Check for existing token in registry
629
+ const registry = await readTokenRegistry();
630
+ const existing = registry[profileKey];
631
+ if (existing && existing.extensionId === extId && existing.token) {
632
+ console.log(` Existing token found: ${existing.token.slice(0, 6)}…`);
633
+ if (!isTTY) console.log(` [agent] Provide y to keep existing token, n to refresh on next stdin line`);
634
+ const keep = (await ask(" Keep existing token? [Y/n]: ")).trim().toLowerCase();
635
+ if (keep !== "n") {
636
+ console.log(" Keeping existing token");
637
+ return { extId, token: existing.token };
638
+ }
639
+ }
640
+
623
641
  // Token
624
642
  const statusUrl = `chrome-extension://${extId}/status.html`;
625
643
  console.log(`\n Get auth token from the extension:`);
@@ -653,10 +671,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
653
671
 
654
672
  // [3+4/4] Extension + token for primary profile
655
673
  console.log("\n[3/4] Checking extension...");
656
- const primary = await getExtAndToken(profileDir, profileDisplay);
674
+ const profileEmail = profileInfoSel.user_name || profileDir;
675
+ const primary = await getExtAndToken(profileDir, profileDisplay, profileEmail);
657
676
  if (!primary) { rl?.close(); process.exit(1); }
658
677
  const { extId, token } = primary;
659
- const profileEmail = profileInfoSel.user_name || profileDir;
660
678
 
661
679
  // Build RECHROME_URL and show it before asking where to save
662
680
  const rechUrl = new URL(url);
@@ -703,10 +721,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
703
721
  if (!extra) { console.log(" Skipped."); continue; }
704
722
  const [extraDir, extraInfo] = extra;
705
723
  const extraDisplay = extraInfo.user_name || extraInfo.name || extraDir;
724
+ const extraEmail = extraInfo.user_name || extraDir;
706
725
  console.log(`\n Setting up: ${extraDisplay}`);
707
- const result = await getExtAndToken(extraDir, extraDisplay);
726
+ const result = await getExtAndToken(extraDir, extraDisplay, extraEmail);
708
727
  if (!result) { console.log(" Skipped."); continue; }
709
- const extraEmail = extraInfo.user_name || extraDir;
710
728
  await saveTokenEntry(extraEmail, { extensionId: result.extId, token: result.token, profileDir: extraDir, userDataDir: userDataDir ?? undefined });
711
729
  configured.add(extraDir);
712
730
  console.log(` Saved token for ${extraDisplay}`);
package/rech.ts CHANGED
@@ -11,8 +11,8 @@ export const DEFAULT_PORT = 13775;
11
11
  export const RECH_DIR = join(import.meta.dir, ".rech");
12
12
  export const LOG_DIR = join(RECH_DIR, "logs");
13
13
 
14
- const RECH_HOME_DIR = join(process.env.HOME!, ".rech");
15
- const TOKENS_FILE = join(RECH_HOME_DIR, "tokens.json");
14
+ const RECH_HOME_DIR = join(process.env.HOME!, ".rechrome");
15
+ const TOKENS_FILE = join(RECH_HOME_DIR, "profiles.json");
16
16
 
17
17
  type TokenEntry = { extensionId: string; token: string; profileDir: string; userDataDir?: string };
18
18
 
@@ -362,7 +362,7 @@ async function callServe(
362
362
  process.exit(1);
363
363
  });
364
364
  if (res.status === 401) {
365
- console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected -> playwright[unknown]`);
365
+ console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected (used: ${key.slice(0, 6)}...) -> playwright[unknown]`);
366
366
  process.exit(1);
367
367
  }
368
368
  return res.json();
@@ -549,13 +549,18 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
549
549
  const { host, port, protocol } = parseUrl(url);
550
550
 
551
551
  const { key: serveKey } = parseUrl(url);
552
- const authPing = await fetch(`${protocol}://${host}:${port}/ping`, {
552
+ // First check if server is up at all (unauthenticated root), then verify our key matches
553
+ const anonPing = await fetch(`${protocol}://${host}:${port}/`, { signal: AbortSignal.timeout(2000) }).catch(() => null);
554
+ const authPing = anonPing ? await fetch(`${protocol}://${host}:${port}/ping`, {
553
555
  headers: { Authorization: `Bearer ${serveKey}` },
554
556
  signal: AbortSignal.timeout(2000),
555
- }).catch(() => null);
556
- if (authPing?.ok) {
557
+ }).catch(() => null) : null;
558
+ if (anonPing && authPing?.ok) {
557
559
  console.log(` Already running at ${protocol}://${host}:${port} — skipping reinstall`);
558
560
  await runOxmgr(["service", "install"]);
561
+ } else if (anonPing && !authPing?.ok) {
562
+ console.log(` Server running but key mismatch — reinstalling with new key`);
563
+ await daemonInstall(url);
559
564
  } else {
560
565
  await daemonInstall(url);
561
566
  console.log(` Registered daemon: ${OXMGR_PROCESS_NAME}`);
@@ -603,7 +608,7 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
603
608
  return available[idx];
604
609
  }
605
610
 
606
- async function getExtAndToken(profileDir: string, profileDisplay: string): Promise<{ extId: string; token: string } | null> {
611
+ async function getExtAndToken(profileDir: string, profileDisplay: string, profileKey: string): Promise<{ extId: string; token: string } | null> {
607
612
  // Extension check
608
613
  let extId: string | undefined;
609
614
  while (true) {
@@ -620,6 +625,19 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
620
625
  }
621
626
  console.log(` Extension found: ${extId}`);
622
627
 
628
+ // Check for existing token in registry
629
+ const registry = await readTokenRegistry();
630
+ const existing = registry[profileKey];
631
+ if (existing && existing.extensionId === extId && existing.token) {
632
+ console.log(` Existing token found: ${existing.token.slice(0, 6)}…`);
633
+ if (!isTTY) console.log(` [agent] Provide y to keep existing token, n to refresh on next stdin line`);
634
+ const keep = (await ask(" Keep existing token? [Y/n]: ")).trim().toLowerCase();
635
+ if (keep !== "n") {
636
+ console.log(" Keeping existing token");
637
+ return { extId, token: existing.token };
638
+ }
639
+ }
640
+
623
641
  // Token
624
642
  const statusUrl = `chrome-extension://${extId}/status.html`;
625
643
  console.log(`\n Get auth token from the extension:`);
@@ -653,10 +671,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
653
671
 
654
672
  // [3+4/4] Extension + token for primary profile
655
673
  console.log("\n[3/4] Checking extension...");
656
- const primary = await getExtAndToken(profileDir, profileDisplay);
674
+ const profileEmail = profileInfoSel.user_name || profileDir;
675
+ const primary = await getExtAndToken(profileDir, profileDisplay, profileEmail);
657
676
  if (!primary) { rl?.close(); process.exit(1); }
658
677
  const { extId, token } = primary;
659
- const profileEmail = profileInfoSel.user_name || profileDir;
660
678
 
661
679
  // Build RECHROME_URL and show it before asking where to save
662
680
  const rechUrl = new URL(url);
@@ -703,10 +721,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
703
721
  if (!extra) { console.log(" Skipped."); continue; }
704
722
  const [extraDir, extraInfo] = extra;
705
723
  const extraDisplay = extraInfo.user_name || extraInfo.name || extraDir;
724
+ const extraEmail = extraInfo.user_name || extraDir;
706
725
  console.log(`\n Setting up: ${extraDisplay}`);
707
- const result = await getExtAndToken(extraDir, extraDisplay);
726
+ const result = await getExtAndToken(extraDir, extraDisplay, extraEmail);
708
727
  if (!result) { console.log(" Skipped."); continue; }
709
- const extraEmail = extraInfo.user_name || extraDir;
710
728
  await saveTokenEntry(extraEmail, { extensionId: result.extId, token: result.token, profileDir: extraDir, userDataDir: userDataDir ?? undefined });
711
729
  configured.add(extraDir);
712
730
  console.log(` Saved token for ${extraDisplay}`);