osborn 0.9.151 → 0.9.152

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/dist/index.js +13 -36
  2. package/package.json +3 -1
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import { dirname, join } from 'node:path';
15
15
  import { fileURLToPath } from 'node:url';
16
16
  import { spawn } from 'node:child_process';
17
17
  import { randomUUID, randomBytes } from 'node:crypto';
18
- import { createConnection as netConnect } from 'node:net';
18
+ import httpProxy from 'http-proxy';
19
19
  import { createRequire } from 'node:module';
20
20
  // 0.9.71: createRequire for resolving package.json versions inside ESM
21
21
  const __sdkVersionRequire = createRequire(import.meta.url);
@@ -282,6 +282,17 @@ let ideProxyEnabled = false;
282
282
  // Bumped on every proxied HTTP request and WS upgrade so the idle watcher sees
283
283
  // real editor activity rather than code-server log noise.
284
284
  let ideLastProxiedActivity = 0;
285
+ // WebSocket proxy for code-server upgrades. Using http-proxy instead of a raw
286
+ // net.createConnection splice: the raw byte-splice causes an immediate 1006
287
+ // disconnect because it doesn't properly handle the HTTP/1.1 101 framing that
288
+ // code-server expects (confirmed: cloudflared works, raw splice does not).
289
+ const wsProxy = httpProxy.createProxyServer({ target: IDE_TARGET, ws: true, changeOrigin: true });
290
+ wsProxy.on('error', (err, _req, socket) => {
291
+ try {
292
+ socket?.destroy();
293
+ }
294
+ catch { }
295
+ });
285
296
  // Per-session cookie token minted when code-server becomes ready. The proxy
286
297
  // gate checks this token via the osborn_ide cookie — only requests carrying a
287
298
  // valid cookie are forwarded, so a forgotten agent route can never be silently
@@ -1591,41 +1602,7 @@ function startApiServer(workingDir, port) {
1591
1602
  const isAgentRoute = AGENT_ROUTE_PREFIXES.some(p => upgradePath === p || upgradePath.startsWith(p + '/'));
1592
1603
  if (ideProxyEnabled && hasValidIdeCookie(req) && !isAgentRoute) {
1593
1604
  ideLastProxiedActivity = Date.now();
1594
- // Raw TCP tunnel: connect to code-server and splice the socket.
1595
- // Pause the client socket before initiating the connect so that any
1596
- // bytes the browser sends before the connect callback fires are buffered
1597
- // by Node rather than silently dropped — the classic silent-hang shape
1598
- // for a websocket terminal on a slow connect.
1599
- socket.pause();
1600
- const conn = netConnect(8300, '127.0.0.1', () => {
1601
- // Forward the original HTTP upgrade request headers.
1602
- const headerLines = [`${req.method} ${req.url} HTTP/1.1`];
1603
- for (const [k, v] of Object.entries(req.headers)) {
1604
- if (k.toLowerCase() === 'host')
1605
- continue;
1606
- if (Array.isArray(v)) {
1607
- for (const vv of v)
1608
- headerLines.push(`${k}: ${vv}`);
1609
- }
1610
- else if (v != null)
1611
- headerLines.push(`${k}: ${v}`);
1612
- }
1613
- headerLines.push('host: 127.0.0.1:8300');
1614
- conn.write(headerLines.join('\r\n') + '\r\n\r\n');
1615
- if (head && head.length)
1616
- conn.write(head);
1617
- conn.pipe(socket);
1618
- socket.pipe(conn);
1619
- socket.resume();
1620
- });
1621
- conn.on('error', () => { try {
1622
- socket.destroy();
1623
- }
1624
- catch { } });
1625
- socket.on('error', () => { try {
1626
- conn.destroy();
1627
- }
1628
- catch { } });
1605
+ wsProxy.ws(req, socket, head, { target: IDE_TARGET });
1629
1606
  return;
1630
1607
  }
1631
1608
  socket.destroy();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osborn",
3
- "version": "0.9.151",
3
+ "version": "0.9.152",
4
4
  "description": "Voice AI coding assistant - local agent that connects to Osborn frontend",
5
5
  "type": "module",
6
6
  "bin": {
@@ -48,6 +48,7 @@
48
48
  "@vscode/ripgrep": "^1.17.1",
49
49
  "diff": "^8.0.4",
50
50
  "dotenv": "^16.4.0",
51
+ "http-proxy": "^1.18.1",
51
52
  "livekit-server-sdk": "^2.15.0",
52
53
  "minisearch": "^7.2.0",
53
54
  "node-pty": "^1.1.0",
@@ -57,6 +58,7 @@
57
58
  "zod": "^4.3.6"
58
59
  },
59
60
  "devDependencies": {
61
+ "@types/http-proxy": "^1.17.17",
60
62
  "@types/node": "^20.0.0",
61
63
  "@vitest/coverage-v8": "^4.0.18",
62
64
  "typescript": "^5.0.0",