sub-bridge 1.2.1 → 1.2.2

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 (2) hide show
  1. package/index.html +89 -0
  2. package/package.json +1 -1
package/index.html CHANGED
@@ -10,6 +10,52 @@
10
10
  <body class="min-h-screen bg-neutral-950 text-neutral-100 antialiased">
11
11
  <main class="mx-auto flex w-full max-w-xl flex-col gap-4 px-5 py-6" x-data="app()">
12
12
 
13
+ <!-- Embedded Browser Warning Overlay -->
14
+ <template x-if="embeddedBrowser.detected && !embeddedBrowser.dismissed && oauth.active">
15
+ <div class="fixed inset-0 z-50 flex items-center justify-center bg-neutral-950/95 p-6">
16
+ <div class="max-w-md rounded-2xl border border-amber-500/30 bg-neutral-900 p-6 shadow-2xl">
17
+ <div class="flex flex-col items-center gap-4 text-center">
18
+ <div class="flex h-12 w-12 items-center justify-center rounded-full bg-amber-500/20">
19
+ <svg class="h-6 w-6 text-amber-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
20
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
21
+ </svg>
22
+ </div>
23
+ <div>
24
+ <h2 class="text-lg font-semibold text-amber-100">Open in External Browser</h2>
25
+ <p class="mt-2 text-sm text-neutral-400">
26
+ Authentication needs to run in your system browser, not Cursor's built-in browser.
27
+ </p>
28
+ </div>
29
+ <div class="w-full space-y-3">
30
+ <div class="flex items-center gap-2 rounded-lg bg-neutral-800 p-3">
31
+ <input
32
+ type="text"
33
+ readonly
34
+ :value="window.location.href"
35
+ class="flex-1 bg-transparent text-xs text-neutral-300 outline-none"
36
+ x-ref="urlInput"
37
+ />
38
+ <button
39
+ @click="copyUrlToClipboard()"
40
+ class="shrink-0 rounded-md bg-amber-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-amber-500 transition"
41
+ x-text="embeddedBrowser.copied ? 'Copied!' : 'Copy URL'"
42
+ ></button>
43
+ </div>
44
+ <p class="text-xs text-neutral-500">
45
+ Copy the URL above and paste it in Chrome, Safari, or Firefox.
46
+ </p>
47
+ </div>
48
+ <button
49
+ @click="embeddedBrowser.dismissed = true"
50
+ class="mt-2 text-xs text-neutral-500 hover:text-neutral-300 underline"
51
+ >
52
+ Continue anyway (may not work)
53
+ </button>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </template>
58
+
13
59
  <!-- SVG Icons -->
14
60
  <svg class="hidden" aria-hidden="true">
15
61
  <symbol id="logo-claude" viewBox="0 0 24 24">
@@ -530,6 +576,27 @@
530
576
  completing: false
531
577
  },
532
578
 
579
+ // Embedded browser detection (Cursor Simple Browser, VS Code, etc.)
580
+ embeddedBrowser: {
581
+ detected: (() => {
582
+ const ua = navigator.userAgent.toLowerCase();
583
+ // Detect VS Code, Cursor, Electron-based editors' embedded browsers
584
+ const isElectron = ua.includes('electron');
585
+ const isVSCode = ua.includes('vscode') || ua.includes('code/');
586
+ const isCursor = ua.includes('cursor');
587
+ // Check for Simple Browser characteristics
588
+ const hasVSCodeApi = typeof window.acquireVsCodeApi === 'function';
589
+ // Simple Browser in Electron doesn't have full Chrome features
590
+ const isEmbedded = isElectron || isVSCode || isCursor || hasVSCodeApi;
591
+ if (isEmbedded) {
592
+ console.log('[Sub Bridge] Embedded browser detected:', { ua, isElectron, isVSCode, isCursor, hasVSCodeApi });
593
+ }
594
+ return isEmbedded;
595
+ })(),
596
+ dismissed: false,
597
+ copied: false
598
+ },
599
+
533
600
  // Check if we have an external URL (pre-configured tunnel via --tunnel flag)
534
601
  get hasExternalUrl() {
535
602
  return this.publicUrl.startsWith('https://') && !this.publicUrl.includes('localhost');
@@ -710,6 +777,28 @@
710
777
  }
711
778
  },
712
779
 
780
+ // Copy URL to clipboard for embedded browser workaround
781
+ async copyUrlToClipboard() {
782
+ try {
783
+ await navigator.clipboard.writeText(window.location.href);
784
+ this.embeddedBrowser.copied = true;
785
+ setTimeout(() => {
786
+ this.embeddedBrowser.copied = false;
787
+ }, 2000);
788
+ } catch (e) {
789
+ // Fallback for older browsers or if clipboard API fails
790
+ const input = this.$refs.urlInput;
791
+ if (input) {
792
+ input.select();
793
+ document.execCommand('copy');
794
+ this.embeddedBrowser.copied = true;
795
+ setTimeout(() => {
796
+ this.embeddedBrowser.copied = false;
797
+ }, 2000);
798
+ }
799
+ }
800
+ },
801
+
713
802
  // Claude code input handler (1s debounce)
714
803
  claudeCodeInput() {
715
804
  clearTimeout(this._debounce);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sub-bridge",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "MCP bridge to use ChatGPT Pro, Claude Max, etc. in Cursor via an OpenAI-compatible proxy",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {