@rahul_ur/devlink-bridge 1.0.0 → 1.0.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.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # devlink-bridge
2
+
3
+ The WebSocket tunnel between your browser app and VSCode. Part 2 of 4 in the devlink system.
4
+
5
+ ```
6
+ devlink-babel-plugin ← stamps data-source at build time
7
+ devlink-bridge ← THIS PACKAGE: browser ↔ VSCode tunnel + cache
8
+ devlink-editor ← Monaco editor panel
9
+ devlink-inspector ← click-to-inspect overlay
10
+ ```
11
+
12
+ ---
13
+
14
+ ## How it works
15
+
16
+ The bridge has two parts:
17
+
18
+ - **Browser SDK** (`devlink-bridge`) — a small class you instantiate in your app. It opens a WebSocket to localhost, manages a file cache, and exposes `readFile`, `writeFile`, `watchFile` methods.
19
+ - **VSCode Extension** (`extension/`) — starts a local WebSocket server when VSCode opens. It handles file reads/writes using the real filesystem and pushes file changes to the browser whenever a watched file is saved on disk.
20
+
21
+ Files cross the bridge **exactly once** — after the first read they live in the browser-side cache. The extension's file watcher pushes changes automatically, so the cache stays fresh without polling.
22
+
23
+ ---
24
+
25
+ ## Installation (Browser SDK)
26
+
27
+ ```bash
28
+ npm install devlink-bridge
29
+ # or during development:
30
+ npm link devlink-bridge
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Browser SDK usage
36
+
37
+ ```ts
38
+ import { DevlinkBridge } from 'devlink-bridge';
39
+
40
+ const bridge = new DevlinkBridge({
41
+ port: 7100, // optional — auto-discovers if omitted
42
+ heartbeatMs: 5000, // ping interval
43
+ timeoutMs: 10000, // request timeout
44
+ onStatusChange: (status) => console.log('Bridge:', status),
45
+ });
46
+
47
+ // Read a file (cached after first fetch)
48
+ const content = await bridge.readFile('/src/App.tsx');
49
+
50
+ // Write a file (debounce recommended — 500ms)
51
+ await bridge.writeFile('/src/App.tsx', newContent);
52
+
53
+ // Watch for changes pushed from VSCode
54
+ const unwatch = await bridge.watchFile('/src/App.tsx', (path, content) => {
55
+ console.log('File changed on disk:', path);
56
+ });
57
+
58
+ // Read directory tree
59
+ const tree = await bridge.readDir('/src', true); // recursive
60
+
61
+ // Status
62
+ bridge.onStatusChange(status => {
63
+ // 'connecting' | 'connected' | 'reconnecting' | 'disconnected'
64
+ });
65
+
66
+ // Debug
67
+ console.log(bridge.getCacheSnapshot());
68
+
69
+ // Cleanup
70
+ bridge.destroy();
71
+ ```
72
+
73
+ ---
74
+
75
+ ## VSCode Extension setup
76
+
77
+ The extension folder (`extension/`) is a standalone VSCode extension. Install it once on your machine.
78
+
79
+ **Development (local install):**
80
+
81
+ ```bash
82
+ cd devlink-bridge/extension
83
+ npm install
84
+ npm run build
85
+
86
+ # Then in VSCode:
87
+ # Ctrl+Shift+P → "Extensions: Install from VSIX..."
88
+ # Or press F5 in VSCode to launch an Extension Development Host
89
+ ```
90
+
91
+ **What it does when active:**
92
+ - Starts a WebSocket server on `127.0.0.1` (loopback only — not exposed to network)
93
+ - Scans ports 7100–7200, uses the first available one
94
+ - Shows the active port in the VSCode status bar: `$(radio-tower) devlink :7100`
95
+ - Watches files on request and pushes changes to all connected browsers
96
+ - Writes files directly to disk when the browser editor saves
97
+
98
+ ---
99
+
100
+ ## Options
101
+
102
+ | Option | Type | Default | Description |
103
+ |--------|------|---------|-------------|
104
+ | `port` | `number` | auto | Try this port first before scanning |
105
+ | `portRange` | `[number, number]` | `[7100, 7200]` | Range to scan for the extension |
106
+ | `heartbeatMs` | `number` | `5000` | Ping interval in ms |
107
+ | `timeoutMs` | `number` | `10000` | Request timeout in ms |
108
+ | `maxReconnectAttempts` | `number` | `Infinity` | Stop trying after N failures |
109
+ | `reconnectBaseMs` | `number` | `500` | Exponential backoff base |
110
+ | `onStatusChange` | `function` | — | Called on every status change |
111
+
112
+ ---
113
+
114
+ ## Connection status
115
+
116
+ ```ts
117
+ bridge.onStatusChange(status => {
118
+ switch (status) {
119
+ case 'connecting': // first connect attempt
120
+ case 'connected': // handshake complete, ready
121
+ case 'reconnecting': // lost connection, retrying with backoff
122
+ case 'disconnected': // gave up or destroyed
123
+ }
124
+ });
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Security
130
+
131
+ The WebSocket server binds to `127.0.0.1` only — it is **never** accessible from other machines on your network. It is a dev-only tool and should never run in production.
132
+
133
+ ---
134
+
135
+ ## License
136
+
137
+ MIT
package/dist/bridge.d.ts CHANGED
@@ -22,8 +22,14 @@ export declare class DevlinkBridge {
22
22
  private clientId;
23
23
  private destroyed;
24
24
  constructor(opts?: BridgeOptions);
25
+ /** Manually start the connection (use when autoConnect is false). */
26
+ start(): void;
25
27
  private connect;
26
28
  private findOpenPort;
29
+ /** Probe all ports concurrently and resolve with the first one that opens. */
30
+ private raceFirst;
31
+ private readLastPort;
32
+ private saveLastPort;
27
33
  private canConnect;
28
34
  private scheduleReconnect;
29
35
  private startHeartbeat;
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,QAAQ,EACT,MAAM,SAAS,CAAC;AAajB,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AACjE,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAChD,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAA6C;IACjE,OAAO,CAAC,cAAc,CAA6C;IACnE,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,IAAI,CAAuF;IACnG,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,GAAE,aAAkB;YAgBtB,OAAO;YAgDP,YAAY;IAqB1B,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;YAgDP,eAAe;IAa7B,OAAO,CAAC,OAAO;IA2Bf,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,SAAS;IASjB,2EAA2E;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS7C;;;;OAIG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7D,4BAA4B;IACtB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAInE;;;;OAIG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IAc9E,gCAAgC;IAChC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI;YAUrD,WAAW;IAgBzB,2DAA2D;IAC3D,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAQ1D,sEAAsE;IACtE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IAIzC,6CAA6C;IAC7C,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,IAAI;IAMlD,gCAAgC;IAChC,SAAS,IAAI,YAAY;IAIzB,sDAAsD;IACtD,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,+CAA+C;IAC/C,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,mCAAmC;IACnC,gBAAgB;;;;;IAIhB,sEAAsE;IACtE,OAAO,IAAI,IAAI;CAShB"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,QAAQ,EACT,MAAM,SAAS,CAAC;AAcjB,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AACjE,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAChD,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAA6C;IACjE,OAAO,CAAC,cAAc,CAA6C;IACnE,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,IAAI,CAAuG;IACnH,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,GAAE,aAAkB;IAcpC,qEAAqE;IAC9D,KAAK,IAAI,IAAI;YAMN,OAAO;YA2DP,YAAY;IAiC1B,8EAA8E;IAC9E,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;YAgDP,eAAe;IAa7B,OAAO,CAAC,OAAO;IA2Bf,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,SAAS;IASjB,2EAA2E;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS7C;;;;OAIG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7D,4BAA4B;IACtB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAInE;;;;OAIG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IAc9E,gCAAgC;IAChC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI;YAUrD,WAAW;IAgBzB,2DAA2D;IAC3D,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAQ1D,sEAAsE;IACtE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IAIzC,6CAA6C;IAC7C,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,IAAI;IAMlD,gCAAgC;IAChC,SAAS,IAAI,YAAY;IAIzB,sDAAsD;IACtD,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,+CAA+C;IAC/C,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,mCAAmC;IACnC,gBAAgB;;;;;IAIhB,sEAAsE;IACtE,OAAO,IAAI,IAAI;CAShB"}
package/dist/bridge.js CHANGED
@@ -2,6 +2,7 @@ import { FileCache } from './cache';
2
2
  const PROTOCOL_VERSION = '1.0';
3
3
  const DEFAULT_PORTS = [7100, 7101, 7102, 7103, 7104];
4
4
  const PORT_RANGE_DEFAULT = [7100, 7200];
5
+ const LAST_PORT_KEY = '__devlink_last_port__';
5
6
  export class DevlinkBridge {
6
7
  constructor(opts = {}) {
7
8
  var _a, _b, _c, _d, _e, _f;
@@ -31,20 +32,34 @@ export class DevlinkBridge {
31
32
  onStatusChange: opts.onStatusChange,
32
33
  };
33
34
  this.clientId = `devlink-${Math.random().toString(36).slice(2, 10)}`;
34
- this.connect();
35
+ if (opts.autoConnect !== false)
36
+ this.connect();
37
+ }
38
+ /** Manually start the connection (use when autoConnect is false). */
39
+ start() {
40
+ if (!this.destroyed && this.status === 'disconnected')
41
+ this.connect();
35
42
  }
36
43
  // ─── Connection lifecycle ───────────────────────────────────────────────────
37
44
  async connect() {
38
45
  if (this.destroyed)
39
46
  return;
40
47
  this.setStatus('connecting');
41
- const port = await this.findOpenPort();
48
+ // On reconnect, try the last known port directly before doing a full scan
49
+ let port = null;
50
+ if (this.activePort !== null) {
51
+ port = this.activePort;
52
+ }
53
+ else {
54
+ port = await this.findOpenPort();
55
+ }
42
56
  if (port === null) {
43
57
  console.warn('[devlink-bridge] No VSCode extension found on ports', this.opts.portRange);
44
58
  this.scheduleReconnect();
45
59
  return;
46
60
  }
47
61
  this.activePort = port;
62
+ this.saveLastPort(port);
48
63
  const url = `ws://127.0.0.1:${port}`;
49
64
  try {
50
65
  this.ws = new WebSocket(url);
@@ -71,38 +86,93 @@ export class DevlinkBridge {
71
86
  this.ws.onclose = () => {
72
87
  this.stopHeartbeat();
73
88
  this.rejectAllPending('Connection closed');
74
- if (!this.destroyed)
89
+ if (!this.destroyed) {
90
+ // If reconnect fails twice on the known port, do a fresh scan
91
+ if (this.reconnectAttempts >= 2)
92
+ this.activePort = null;
75
93
  this.scheduleReconnect();
94
+ }
76
95
  };
77
96
  this.ws.onerror = () => {
78
97
  // onerror is always followed by onclose, so we handle there
79
98
  };
80
99
  }
81
100
  async findOpenPort() {
82
- // Try specific port first if provided
101
+ // ── Fast path 1: explicit port option ────────────────────────────────────
83
102
  if (this.opts.port) {
84
103
  if (await this.canConnect(this.opts.port))
85
104
  return this.opts.port;
86
105
  }
87
- // Try default ports first (fast path)
88
- for (const p of DEFAULT_PORTS) {
89
- if (await this.canConnect(p))
90
- return p;
106
+ // ── Fast path 2: last known good port (cached across page reloads) ───────
107
+ const lastPort = this.readLastPort();
108
+ if (lastPort && !DEFAULT_PORTS.includes(lastPort)) {
109
+ if (await this.canConnect(lastPort))
110
+ return lastPort;
91
111
  }
92
- // Full range scan
112
+ // ── Fast path 3: race all default ports simultaneously ───────────────────
113
+ // Resolves the instant the first one answers — no waiting for others
114
+ const defaultPort = await this.raceFirst(DEFAULT_PORTS);
115
+ if (defaultPort !== null)
116
+ return defaultPort;
117
+ // ── Full range scan: batches of 20 concurrently ──────────────────────────
93
118
  const [min, max] = this.opts.portRange;
119
+ const rangePorts = [];
94
120
  for (let p = min; p <= max; p++) {
95
- if (DEFAULT_PORTS.includes(p))
96
- continue; // already tried
97
- if (await this.canConnect(p))
98
- return p;
121
+ if (!DEFAULT_PORTS.includes(p))
122
+ rangePorts.push(p);
123
+ }
124
+ const BATCH = 20;
125
+ for (let i = 0; i < rangePorts.length; i += BATCH) {
126
+ const batch = rangePorts.slice(i, i + BATCH);
127
+ const found = await this.raceFirst(batch);
128
+ if (found !== null)
129
+ return found;
99
130
  }
100
131
  return null;
101
132
  }
133
+ /** Probe all ports concurrently and resolve with the first one that opens. */
134
+ raceFirst(ports) {
135
+ return new Promise(resolve => {
136
+ let settled = false;
137
+ let remaining = ports.length;
138
+ const done = (port) => {
139
+ if (settled)
140
+ return;
141
+ if (port !== null) {
142
+ settled = true;
143
+ resolve(port);
144
+ }
145
+ else {
146
+ remaining--;
147
+ if (remaining === 0)
148
+ resolve(null);
149
+ }
150
+ };
151
+ for (const port of ports) {
152
+ this.canConnect(port).then(ok => done(ok ? port : null));
153
+ }
154
+ });
155
+ }
156
+ readLastPort() {
157
+ try {
158
+ const v = localStorage.getItem(LAST_PORT_KEY);
159
+ const n = v ? parseInt(v, 10) : NaN;
160
+ return Number.isFinite(n) ? n : null;
161
+ }
162
+ catch {
163
+ return null;
164
+ }
165
+ }
166
+ saveLastPort(port) {
167
+ try {
168
+ localStorage.setItem(LAST_PORT_KEY, String(port));
169
+ }
170
+ catch { }
171
+ }
102
172
  canConnect(port) {
103
173
  return new Promise(resolve => {
104
174
  const ws = new WebSocket(`ws://127.0.0.1:${port}`);
105
- const timer = setTimeout(() => { ws.close(); resolve(false); }, 2000);
175
+ const timer = setTimeout(() => { ws.close(); resolve(false); }, 1000);
106
176
  ws.onopen = () => { clearTimeout(timer); ws.close(); resolve(true); };
107
177
  ws.onerror = () => { clearTimeout(timer); resolve(false); };
108
178
  });
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -76,6 +76,8 @@ export interface BridgeOptions {
76
76
  reconnectBaseMs?: number;
77
77
  /** Called when connection state changes */
78
78
  onStatusChange?: (status: BridgeStatus) => void;
79
+ /** Whether to connect immediately on construction. Defaults to true */
80
+ autoConnect?: boolean;
79
81
  }
80
82
  export type BridgeStatus = 'connecting' | 'connected' | 'reconnecting' | 'disconnected';
81
83
  export interface DirEntry {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAIjC,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAIjC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB;AAID,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;CACjD;AAED,MAAM,MAAM,YAAY,GACpB,YAAY,GACZ,WAAW,GACX,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ const cache_1 = require("./cache");
5
5
  const PROTOCOL_VERSION = '1.0';
6
6
  const DEFAULT_PORTS = [7100, 7101, 7102, 7103, 7104];
7
7
  const PORT_RANGE_DEFAULT = [7100, 7200];
8
+ const LAST_PORT_KEY = '__devlink_last_port__';
8
9
  class DevlinkBridge {
9
10
  constructor(opts = {}) {
10
11
  var _a, _b, _c, _d, _e, _f;
@@ -34,20 +35,34 @@ class DevlinkBridge {
34
35
  onStatusChange: opts.onStatusChange,
35
36
  };
36
37
  this.clientId = `devlink-${Math.random().toString(36).slice(2, 10)}`;
37
- this.connect();
38
+ if (opts.autoConnect !== false)
39
+ this.connect();
40
+ }
41
+ /** Manually start the connection (use when autoConnect is false). */
42
+ start() {
43
+ if (!this.destroyed && this.status === 'disconnected')
44
+ this.connect();
38
45
  }
39
46
  // ─── Connection lifecycle ───────────────────────────────────────────────────
40
47
  async connect() {
41
48
  if (this.destroyed)
42
49
  return;
43
50
  this.setStatus('connecting');
44
- const port = await this.findOpenPort();
51
+ // On reconnect, try the last known port directly before doing a full scan
52
+ let port = null;
53
+ if (this.activePort !== null) {
54
+ port = this.activePort;
55
+ }
56
+ else {
57
+ port = await this.findOpenPort();
58
+ }
45
59
  if (port === null) {
46
60
  console.warn('[devlink-bridge] No VSCode extension found on ports', this.opts.portRange);
47
61
  this.scheduleReconnect();
48
62
  return;
49
63
  }
50
64
  this.activePort = port;
65
+ this.saveLastPort(port);
51
66
  const url = `ws://127.0.0.1:${port}`;
52
67
  try {
53
68
  this.ws = new WebSocket(url);
@@ -74,38 +89,93 @@ class DevlinkBridge {
74
89
  this.ws.onclose = () => {
75
90
  this.stopHeartbeat();
76
91
  this.rejectAllPending('Connection closed');
77
- if (!this.destroyed)
92
+ if (!this.destroyed) {
93
+ // If reconnect fails twice on the known port, do a fresh scan
94
+ if (this.reconnectAttempts >= 2)
95
+ this.activePort = null;
78
96
  this.scheduleReconnect();
97
+ }
79
98
  };
80
99
  this.ws.onerror = () => {
81
100
  // onerror is always followed by onclose, so we handle there
82
101
  };
83
102
  }
84
103
  async findOpenPort() {
85
- // Try specific port first if provided
104
+ // ── Fast path 1: explicit port option ────────────────────────────────────
86
105
  if (this.opts.port) {
87
106
  if (await this.canConnect(this.opts.port))
88
107
  return this.opts.port;
89
108
  }
90
- // Try default ports first (fast path)
91
- for (const p of DEFAULT_PORTS) {
92
- if (await this.canConnect(p))
93
- return p;
109
+ // ── Fast path 2: last known good port (cached across page reloads) ───────
110
+ const lastPort = this.readLastPort();
111
+ if (lastPort && !DEFAULT_PORTS.includes(lastPort)) {
112
+ if (await this.canConnect(lastPort))
113
+ return lastPort;
94
114
  }
95
- // Full range scan
115
+ // ── Fast path 3: race all default ports simultaneously ───────────────────
116
+ // Resolves the instant the first one answers — no waiting for others
117
+ const defaultPort = await this.raceFirst(DEFAULT_PORTS);
118
+ if (defaultPort !== null)
119
+ return defaultPort;
120
+ // ── Full range scan: batches of 20 concurrently ──────────────────────────
96
121
  const [min, max] = this.opts.portRange;
122
+ const rangePorts = [];
97
123
  for (let p = min; p <= max; p++) {
98
- if (DEFAULT_PORTS.includes(p))
99
- continue; // already tried
100
- if (await this.canConnect(p))
101
- return p;
124
+ if (!DEFAULT_PORTS.includes(p))
125
+ rangePorts.push(p);
126
+ }
127
+ const BATCH = 20;
128
+ for (let i = 0; i < rangePorts.length; i += BATCH) {
129
+ const batch = rangePorts.slice(i, i + BATCH);
130
+ const found = await this.raceFirst(batch);
131
+ if (found !== null)
132
+ return found;
102
133
  }
103
134
  return null;
104
135
  }
136
+ /** Probe all ports concurrently and resolve with the first one that opens. */
137
+ raceFirst(ports) {
138
+ return new Promise(resolve => {
139
+ let settled = false;
140
+ let remaining = ports.length;
141
+ const done = (port) => {
142
+ if (settled)
143
+ return;
144
+ if (port !== null) {
145
+ settled = true;
146
+ resolve(port);
147
+ }
148
+ else {
149
+ remaining--;
150
+ if (remaining === 0)
151
+ resolve(null);
152
+ }
153
+ };
154
+ for (const port of ports) {
155
+ this.canConnect(port).then(ok => done(ok ? port : null));
156
+ }
157
+ });
158
+ }
159
+ readLastPort() {
160
+ try {
161
+ const v = localStorage.getItem(LAST_PORT_KEY);
162
+ const n = v ? parseInt(v, 10) : NaN;
163
+ return Number.isFinite(n) ? n : null;
164
+ }
165
+ catch {
166
+ return null;
167
+ }
168
+ }
169
+ saveLastPort(port) {
170
+ try {
171
+ localStorage.setItem(LAST_PORT_KEY, String(port));
172
+ }
173
+ catch { }
174
+ }
105
175
  canConnect(port) {
106
176
  return new Promise(resolve => {
107
177
  const ws = new WebSocket(`ws://127.0.0.1:${port}`);
108
- const timer = setTimeout(() => { ws.close(); resolve(false); }, 2000);
178
+ const timer = setTimeout(() => { ws.close(); resolve(false); }, 1000);
109
179
  ws.onopen = () => { clearTimeout(timer); ws.close(); resolve(true); };
110
180
  ws.onerror = () => { clearTimeout(timer); resolve(false); };
111
181
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rahul_ur/devlink-bridge",
3
- "version": "1.0.0",
4
- "description": "Browser SDK + local bridge server for devlink connects your web app to VSCode over a local WebSocket",
3
+ "version": "1.0.2",
4
+ "description": "Browser SDK + local bridge server for devlink \u2014 connects your web app to VSCode over a local WebSocket",
5
5
  "main": "dist-cjs/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -26,9 +26,9 @@
26
26
  "README.md"
27
27
  ],
28
28
  "scripts": {
29
- "build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node scripts/rename-esm.mjs",
30
- "dev": "tsc --watch",
31
- "test": "jest --no-coverage --passWithNoTests",
29
+ "build": "npx tsc -p tsconfig.json && npx tsc -p tsconfig.cjs.json && node scripts/rename-esm.mjs",
30
+ "dev": "npx tsc --watch",
31
+ "test": "npx jest --no-coverage --passWithNoTests",
32
32
  "prepublishOnly": "npm run build && npm test && npm pack --dry-run"
33
33
  },
34
34
  "keywords": [
package/server.mjs CHANGED
@@ -6,13 +6,17 @@ import { exec } from 'child_process';
6
6
 
7
7
  const PORT = 7100;
8
8
  const WORKSPACE = process.cwd();
9
+ const EXEC_ENABLED = process.argv.includes('--enable-exec');
9
10
  const watchers = new Map();
10
11
 
11
12
  // ─── Security: resolve path inside workspace ──────────────────────────────────
12
13
  function safeResolvePath(filePath) {
13
- const resolved = path.resolve(filePath);
14
- // Allow absolute paths anywhere on the machine (needed for cross-project use)
15
- // but log them for awareness
14
+ // Resolve relative to workspace; block any path that escapes it
15
+ const resolved = path.resolve(WORKSPACE, filePath);
16
+ const wsNorm = WORKSPACE.endsWith(path.sep) ? WORKSPACE : WORKSPACE + path.sep;
17
+ if (resolved !== WORKSPACE && !resolved.startsWith(wsNorm)) {
18
+ throw new Error(`Path escape denied: ${filePath}`);
19
+ }
16
20
  return resolved;
17
21
  }
18
22
 
@@ -157,22 +161,30 @@ wss.on('connection', (ws) => {
157
161
  }
158
162
 
159
163
  // ── Execute shell command ─────────────────────────────────────────────────
160
- // Used by terminal tab and AI codex commands
164
+ // Used by terminal tab and AI codex commands.
165
+ // Only active when server is started with --enable-exec flag.
161
166
  case 'execCommand': {
162
- const { command, cwd } = msg;
163
-
164
- // Safety: block obviously destructive commands
165
- const blocked = ['rm -rf /', 'format c:', 'del /f /s /q c:\\'];
166
- const lower = (command || '').toLowerCase();
167
- if (blocked.some(b => lower.includes(b))) {
167
+ if (!EXEC_ENABLED) {
168
168
  ws.send(JSON.stringify({
169
- type: 'response', id: msg.id, ok: true,
170
- result: { stdout: '', stderr: 'Command blocked by devlink safety rules.', code: 1 },
169
+ type: 'response', id: msg.id, ok: false,
170
+ error: 'execCommand is disabled. Start devlink server with --enable-exec to enable it.',
171
171
  }));
172
172
  break;
173
173
  }
174
174
 
175
- const resolvedCwd = cwd ? safeResolvePath(cwd) : WORKSPACE;
175
+ const { command, cwd } = msg;
176
+ if (!command || typeof command !== 'string') {
177
+ ws.send(JSON.stringify({ type: 'response', id: msg.id, ok: false, error: 'Invalid command.' }));
178
+ break;
179
+ }
180
+
181
+ let resolvedCwd;
182
+ try {
183
+ resolvedCwd = cwd ? safeResolvePath(cwd) : WORKSPACE;
184
+ } catch (e) {
185
+ ws.send(JSON.stringify({ type: 'response', id: msg.id, ok: false, error: e.message }));
186
+ break;
187
+ }
176
188
 
177
189
  exec(command, { cwd: resolvedCwd, timeout: 60000 }, (err, stdout, stderr) => {
178
190
  if (ws.readyState !== ws.OPEN) return;
package/setup-devlink.mjs CHANGED
@@ -51,36 +51,36 @@ function updatePackageJson() {
51
51
 
52
52
  // Add bridge scripts
53
53
  if (!pkg.scripts['devlink:bridge']) {
54
- pkg.scripts['devlink:bridge'] = 'node node_modules/devlink-bridge/server.mjs';
54
+ pkg.scripts['devlink:bridge'] = 'node node_modules/@rahul_ur/devlink-bridge/server.mjs';
55
55
  changed = true; log('added script devlink:bridge');
56
56
  }
57
57
  if (!pkg.scripts['devlink:setup']) {
58
- pkg.scripts['devlink:setup'] = 'node node_modules/devlink-bridge/setup-devlink.mjs';
58
+ pkg.scripts['devlink:setup'] = 'node node_modules/@rahul_ur/devlink-bridge/setup-devlink.mjs';
59
59
  changed = true; log('added script devlink:setup');
60
60
  }
61
61
 
62
62
  const alphaRoot = path.resolve(bridgePackageRoot, '..');
63
63
  const deps = {
64
- 'devlink-bridge': maybeRelativeDep(bridgePackageRoot),
65
- 'devlink-studio': maybeRelativeDep(path.join(alphaRoot, 'devlink-v2', 'packages', 'devlink-studio')),
66
- 'devlink-babel-plugin': maybeRelativeDep(path.join(alphaRoot, 'devlink-babel-plugin')),
67
- 'devlink-vite-plugin': maybeRelativeDep(path.join(alphaRoot, 'devlink-vite-plugin')),
64
+ '@rahul_ur/devlink-bridge': maybeRelativeDep(bridgePackageRoot),
65
+ '@rahul_ur/devlink-studio': maybeRelativeDep(path.join(alphaRoot, 'devlink-studio')),
66
+ '@rahul_ur/devlink-babel-plugin': maybeRelativeDep(path.join(alphaRoot, '@rahul_ur/devlink-babel-plugin')),
67
+ '@rahul_ur/devlink-vite-plugin': maybeRelativeDep(path.join(alphaRoot, '@rahul_ur/devlink-vite-plugin')),
68
68
  };
69
69
 
70
- if (!pkg.dependencies['devlink-bridge'] && deps['devlink-bridge']) {
71
- pkg.dependencies['devlink-bridge'] = deps['devlink-bridge'];
70
+ if (!pkg.dependencies['@rahul_ur/devlink-bridge'] && deps['@rahul_ur/devlink-bridge']) {
71
+ pkg.dependencies['@rahul_ur/devlink-bridge'] = deps['@rahul_ur/devlink-bridge'];
72
72
  changed = true; log('added dependency devlink-bridge');
73
73
  }
74
- if (!pkg.dependencies['devlink-studio'] && deps['devlink-studio']) {
75
- pkg.dependencies['devlink-studio'] = deps['devlink-studio'];
74
+ if (!pkg.dependencies['@rahul_ur/devlink-studio'] && deps['@rahul_ur/devlink-studio']) {
75
+ pkg.dependencies['@rahul_ur/devlink-studio'] = deps['@rahul_ur/devlink-studio'];
76
76
  changed = true; log('added dependency devlink-studio');
77
77
  }
78
- if (!pkg.devDependencies['devlink-babel-plugin'] && deps['devlink-babel-plugin']) {
79
- pkg.devDependencies['devlink-babel-plugin'] = deps['devlink-babel-plugin'];
78
+ if (!pkg.devDependencies['@rahul_ur/devlink-babel-plugin'] && deps['@rahul_ur/devlink-babel-plugin']) {
79
+ pkg.devDependencies['@rahul_ur/devlink-babel-plugin'] = deps['@rahul_ur/devlink-babel-plugin'];
80
80
  changed = true; log('added devDependency devlink-babel-plugin');
81
81
  }
82
- if (!pkg.devDependencies['devlink-vite-plugin'] && deps['devlink-vite-plugin']) {
83
- pkg.devDependencies['devlink-vite-plugin'] = deps['devlink-vite-plugin'];
82
+ if (!pkg.devDependencies['@rahul_ur/devlink-vite-plugin'] && deps['@rahul_ur/devlink-vite-plugin']) {
83
+ pkg.devDependencies['@rahul_ur/devlink-vite-plugin'] = deps['@rahul_ur/devlink-vite-plugin'];
84
84
  changed = true; log('added devDependency devlink-vite-plugin');
85
85
  }
86
86
 
@@ -102,10 +102,10 @@ function setupCra() {
102
102
  let src = fs.readFileSync(configPath, 'utf8');
103
103
  let changed = false;
104
104
 
105
- if (!src.includes("require.resolve('devlink-babel-plugin')")) {
105
+ if (!src.includes("require.resolve('@rahul_ur/devlink-babel-plugin')")) {
106
106
  const marker = "const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash');";
107
107
  if (src.includes(marker)) {
108
- src = src.replace(marker, `${marker}\nconst devlinkBabelPlugin = require.resolve('devlink-babel-plugin');`);
108
+ src = src.replace(marker, `${marker}\nconst devlinkBabelPlugin = require.resolve('@rahul_ur/devlink-babel-plugin');`);
109
109
  changed = true;
110
110
  }
111
111
  }
@@ -147,7 +147,7 @@ function setupVite() {
147
147
  const configPath = path.join(projectRoot, configFile);
148
148
  let src = fs.readFileSync(configPath, 'utf8');
149
149
 
150
- if (src.includes('devlink-babel-plugin') || src.includes('devlink-vite-plugin')) {
150
+ if (src.includes('@rahul_ur/devlink-babel-plugin') || src.includes('@rahul_ur/devlink-vite-plugin')) {
151
151
  ok('vite.config already has devlink config');
152
152
  return true;
153
153
  }
@@ -156,8 +156,8 @@ function setupVite() {
156
156
  const isTs = configFile.endsWith('.ts') || configFile.endsWith('.mts');
157
157
 
158
158
  // Add import at top
159
- const importLine = `import { devlinkBabelConfig } from 'devlink-vite-plugin';\n`;
160
- if (!src.includes("from 'devlink-vite-plugin'")) {
159
+ const importLine = `import { devlinkBabelConfig } from '@rahul_ur/devlink-vite-plugin';\n`;
160
+ if (!src.includes("from '@rahul_ur/devlink-vite-plugin'")) {
161
161
  // Insert after last existing import
162
162
  const lastImportIdx = src.lastIndexOf('\nimport ');
163
163
  const insertAt = lastImportIdx === -1 ? 0 : src.indexOf('\n', lastImportIdx) + 1;
@@ -182,7 +182,7 @@ function setupVite() {
182
182
  } else {
183
183
  // Can't auto-patch safely — append comment instructions
184
184
  src += `\n// TODO: add devlink babel plugin to your react() config:\n`;
185
- src += `// import { devlinkBabelConfig } from 'devlink-vite-plugin'\n`;
185
+ src += `// import { devlinkBabelConfig } from '@rahul_ur/devlink-vite-plugin'\n`;
186
186
  src += `// react({ babel: { plugins: [devlinkBabelConfig({ root: process.cwd() })] } })\n`;
187
187
  warn('Could not auto-patch vite.config. See TODO comment added at bottom of file.');
188
188
  }
@@ -195,7 +195,7 @@ function setupVite() {
195
195
  function createViteConfig(filename) {
196
196
  const content = `import { defineConfig } from 'vite';
197
197
  import react from '@vitejs/plugin-react';
198
- import { devlinkBabelConfig } from 'devlink-vite-plugin';
198
+ import { devlinkBabelConfig } from '@rahul_ur/devlink-vite-plugin';
199
199
 
200
200
  export default defineConfig({
201
201
  plugins: [
@@ -228,7 +228,7 @@ function setupNext() {
228
228
  const configPath = path.join(projectRoot, configFile);
229
229
  let src = fs.readFileSync(configPath, 'utf8');
230
230
 
231
- if (src.includes('devlink-babel-plugin')) {
231
+ if (src.includes('@rahul_ur/devlink-babel-plugin')) {
232
232
  ok('next.config already has devlink config');
233
233
  return true;
234
234
  }
@@ -240,8 +240,8 @@ function setupNext() {
240
240
  const babelRc = readJson(babelRcPath);
241
241
  const devEnv = babelRc.env?.development || {};
242
242
  devEnv.plugins = devEnv.plugins || [];
243
- if (!devEnv.plugins.some(p => (Array.isArray(p) ? p[0] : p) === 'devlink-babel-plugin')) {
244
- devEnv.plugins.push(['devlink-babel-plugin', { root: '.', envs: ['development'] }]);
243
+ if (!devEnv.plugins.some(p => (Array.isArray(p) ? p[0] : p) === '@rahul_ur/devlink-babel-plugin')) {
244
+ devEnv.plugins.push(['@rahul_ur/devlink-babel-plugin', { root: '.', envs: ['development'] }]);
245
245
  babelRc.env = babelRc.env || {};
246
246
  babelRc.env.development = devEnv;
247
247
  writeJson(babelRcPath, babelRc);
@@ -256,7 +256,7 @@ function setupNext() {
256
256
  env: {
257
257
  development: {
258
258
  plugins: [
259
- ['devlink-babel-plugin', { root: '.', envs: ['development'] }]
259
+ ['@rahul_ur/devlink-babel-plugin', { root: '.', envs: ['development'] }]
260
260
  ]
261
261
  }
262
262
  }
@@ -320,8 +320,8 @@ function printMainInstructions(framework) {
320
320
  console.log('');
321
321
  if (framework === 'next') {
322
322
  console.log(` // pages/_app.tsx
323
- import { DevlinkBridge } from 'devlink-bridge'
324
- import { DevlinkStudio } from 'devlink-studio'
323
+ import { DevlinkBridge } from '@rahul_ur/devlink-bridge'
324
+ import { DevlinkStudio } from '@rahul_ur/devlink-studio'
325
325
  import devlinkConfig from '../devlink.config'
326
326
 
327
327
  const bridge = new DevlinkBridge()
@@ -334,8 +334,8 @@ function printMainInstructions(framework) {
334
334
  )
335
335
  }`);
336
336
  } else {
337
- console.log(` import { DevlinkBridge } from 'devlink-bridge'
338
- import { DevlinkStudio } from 'devlink-studio'
337
+ console.log(` import { DevlinkBridge } from '@rahul_ur/devlink-bridge'
338
+ import { DevlinkStudio } from '@rahul_ur/devlink-studio'
339
339
  import { devlinkConfig } from '../devlink.config'
340
340
 
341
341
  const bridge = new DevlinkBridge()