termbridge 0.3.10 → 0.3.12

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/bin.js CHANGED
@@ -2480,8 +2480,8 @@ var createAuth = ({
2480
2480
  if (!record) {
2481
2481
  return null;
2482
2482
  }
2483
+ wsTokens.delete(token);
2483
2484
  if (record.expiresAt <= clock()) {
2484
- wsTokens.delete(token);
2485
2485
  return null;
2486
2486
  }
2487
2487
  return getSession(record.sessionId);
@@ -2599,22 +2599,10 @@ var createTerminalRegistry = () => {
2599
2599
  };
2600
2600
 
2601
2601
  // src/server/server.ts
2602
- import { createServer as createHttpServer, request as httpRequest } from "http";
2603
- import { request as httpsRequest } from "https";
2602
+ import { createServer as createHttpServer } from "http";
2604
2603
  import { randomBytes as randomBytes3 } from "crypto";
2605
2604
  import { WebSocketServer, WebSocket as WsWebSocket } from "ws";
2606
2605
 
2607
- // ../packages/shared/src/index.ts
2608
- var TERMINAL_CONTROL_KEYS = [
2609
- "ctrl_c",
2610
- "esc",
2611
- "tab",
2612
- "up",
2613
- "down",
2614
- "left",
2615
- "right"
2616
- ];
2617
-
2618
2606
  // src/server/static.ts
2619
2607
  import { readFile } from "fs/promises";
2620
2608
  import { extname, resolve as resolve3 } from "path";
@@ -2666,10 +2654,8 @@ var createStaticHandler = (uiDistPath, basePath) => {
2666
2654
  };
2667
2655
  };
2668
2656
 
2669
- // src/server/server.ts
2657
+ // src/server/http-utils.ts
2670
2658
  var MAX_HTTP_BODY_SIZE = 64 * 1024;
2671
- var MAX_WS_MESSAGE_SIZE = 1024 * 1024;
2672
- var MAX_INPUT_LENGTH = 64 * 1024;
2673
2659
  var jsonResponse = (response, status, payload) => {
2674
2660
  const body = JSON.stringify(payload);
2675
2661
  response.statusCode = status;
@@ -2716,6 +2702,21 @@ var isAllowedOrigin = (origin, host, forwardedHost) => {
2716
2702
  }
2717
2703
  };
2718
2704
  var resolveForwardedHost = (header) => Array.isArray(header) ? header[0] : header;
2705
+
2706
+ // ../packages/shared/src/index.ts
2707
+ var TERMINAL_CONTROL_KEYS = [
2708
+ "ctrl_c",
2709
+ "esc",
2710
+ "tab",
2711
+ "up",
2712
+ "down",
2713
+ "left",
2714
+ "right"
2715
+ ];
2716
+
2717
+ // src/server/ws-utils.ts
2718
+ var MAX_WS_MESSAGE_SIZE = 1024 * 1024;
2719
+ var MAX_INPUT_LENGTH = 64 * 1024;
2719
2720
  var allowedControlKeys = new Set(TERMINAL_CONTROL_KEYS);
2720
2721
  var parseClientMessage = (payload) => {
2721
2722
  const size = typeof payload === "string" ? payload.length : Array.isArray(payload) ? payload.reduce((sum, buf) => sum + buf.length, 0) : payload.byteLength;
@@ -2748,50 +2749,74 @@ var parseClientMessage = (payload) => {
2748
2749
  var sendWsMessage = (socket, message) => {
2749
2750
  socket.send(JSON.stringify(message));
2750
2751
  };
2752
+
2753
+ // src/server/proxy.ts
2754
+ import { request as httpRequest } from "http";
2755
+ import { request as httpsRequest } from "https";
2756
+ var resolveProxyUrl = (config, targetPath, search) => {
2757
+ if (typeof config.proxyPort === "number") {
2758
+ return new URL(`http://localhost:${config.proxyPort}${targetPath}${search}`);
2759
+ }
2760
+ if (config.devProxyUrl) {
2761
+ try {
2762
+ return new URL(`${targetPath}${search}`, config.devProxyUrl);
2763
+ } catch {
2764
+ return null;
2765
+ }
2766
+ }
2767
+ return null;
2768
+ };
2769
+ var proxyRequest = (config, request, response, targetPath, search) => {
2770
+ const targetUrl = resolveProxyUrl(config, targetPath, search);
2771
+ if (!targetUrl) {
2772
+ response.statusCode = 502;
2773
+ response.end("proxy error");
2774
+ return;
2775
+ }
2776
+ const proxyHeaders = { ...request.headers, ...config.devProxyHeaders ?? {} };
2777
+ delete proxyHeaders.cookie;
2778
+ delete proxyHeaders.host;
2779
+ proxyHeaders.host = targetUrl.host;
2780
+ const requestImpl = targetUrl.protocol === "https:" ? httpsRequest : httpRequest;
2781
+ const proxyReq = requestImpl(
2782
+ targetUrl,
2783
+ { method: request.method, headers: proxyHeaders },
2784
+ (proxyRes) => {
2785
+ response.writeHead(proxyRes.statusCode, proxyRes.headers);
2786
+ proxyRes.pipe(response);
2787
+ }
2788
+ );
2789
+ proxyReq.on("error", () => {
2790
+ response.statusCode = 502;
2791
+ response.end("proxy error");
2792
+ });
2793
+ request.pipe(proxyReq);
2794
+ };
2795
+ var getProxyWebSocketUrl = (config) => {
2796
+ try {
2797
+ if (typeof config.proxyPort === "number") {
2798
+ return new URL(`http://localhost:${config.proxyPort}`);
2799
+ }
2800
+ if (config.devProxyUrl) {
2801
+ return new URL(config.devProxyUrl);
2802
+ }
2803
+ } catch {
2804
+ return null;
2805
+ }
2806
+ return null;
2807
+ };
2808
+
2809
+ // src/server/server.ts
2751
2810
  var createSessionName = () => `termbridge-${randomBytes3(4).toString("hex")}`;
2752
2811
  var createAppServer = (deps) => {
2753
2812
  const staticHandler = createStaticHandler(deps.uiDistPath, "/__tb/app");
2754
2813
  const wss = new WebSocketServer({ noServer: true });
2755
2814
  const connectionInfo = /* @__PURE__ */ new WeakMap();
2756
2815
  const hasProxy = typeof deps.proxyPort === "number" || deps.devProxyUrl !== void 0;
2757
- const resolveProxyUrl = (targetPath, search) => {
2758
- if (typeof deps.proxyPort === "number") {
2759
- return new URL(`http://localhost:${deps.proxyPort}${targetPath}${search}`);
2760
- }
2761
- if (deps.devProxyUrl) {
2762
- try {
2763
- return new URL(`${targetPath}${search}`, deps.devProxyUrl);
2764
- } catch {
2765
- return null;
2766
- }
2767
- }
2768
- return null;
2769
- };
2770
- const proxyRequest = (request, response, targetPath, search) => {
2771
- const targetUrl = resolveProxyUrl(targetPath, search);
2772
- if (!targetUrl) {
2773
- response.statusCode = 502;
2774
- response.end("proxy error");
2775
- return;
2776
- }
2777
- const proxyHeaders = { ...request.headers, ...deps.devProxyHeaders ?? {} };
2778
- delete proxyHeaders.cookie;
2779
- delete proxyHeaders.host;
2780
- proxyHeaders.host = targetUrl.host;
2781
- const requestImpl = targetUrl.protocol === "https:" ? httpsRequest : httpRequest;
2782
- const proxyReq = requestImpl(
2783
- targetUrl,
2784
- { method: request.method, headers: proxyHeaders },
2785
- (proxyRes) => {
2786
- response.writeHead(proxyRes.statusCode, proxyRes.headers);
2787
- proxyRes.pipe(response);
2788
- }
2789
- );
2790
- proxyReq.on("error", () => {
2791
- response.statusCode = 502;
2792
- response.end("proxy error");
2793
- });
2794
- request.pipe(proxyReq);
2816
+ const proxyConfig = {
2817
+ proxyPort: deps.proxyPort,
2818
+ devProxyUrl: deps.devProxyUrl,
2819
+ devProxyHeaders: deps.devProxyHeaders
2795
2820
  };
2796
2821
  const server = createHttpServer(async (request, response) => {
2797
2822
  const url = new URL(request.url, `http://${request.headers.host}`);
@@ -2890,7 +2915,7 @@ var createAppServer = (deps) => {
2890
2915
  const handled = await staticHandler(request, response);
2891
2916
  if (!handled) {
2892
2917
  if (hasProxy && deps.auth.getSessionFromRequest(request)) {
2893
- proxyRequest(request, response, url.pathname, url.search);
2918
+ proxyRequest(proxyConfig, request, response, url.pathname, url.search);
2894
2919
  return;
2895
2920
  }
2896
2921
  response.statusCode = 404;
@@ -2901,17 +2926,15 @@ var createAppServer = (deps) => {
2901
2926
  const url = new URL(request.url, `http://${request.headers.host}`);
2902
2927
  if (!url.pathname.startsWith("/__tb/ws/terminal/")) {
2903
2928
  if (hasProxy && deps.auth.getSessionFromRequest(request)) {
2904
- let baseUrl = null;
2905
- try {
2906
- baseUrl = typeof deps.proxyPort === "number" ? new URL(`http://localhost:${deps.proxyPort}`) : new URL(deps.devProxyUrl);
2907
- } catch {
2929
+ const baseUrl = getProxyWebSocketUrl(proxyConfig);
2930
+ if (!baseUrl) {
2908
2931
  socket.destroy();
2909
2932
  return;
2910
2933
  }
2911
2934
  const wsProtocol = baseUrl.protocol === "https:" ? "wss:" : "ws:";
2912
2935
  const targetUrl = new URL(`${url.pathname}${url.search}`, baseUrl);
2913
2936
  targetUrl.protocol = wsProtocol;
2914
- const proxyHeaders = { ...request.headers, ...deps.devProxyHeaders ?? {} };
2937
+ const proxyHeaders = { ...request.headers, ...proxyConfig.devProxyHeaders ?? {} };
2915
2938
  delete proxyHeaders.cookie;
2916
2939
  delete proxyHeaders.host;
2917
2940
  proxyHeaders.host = targetUrl.host;
@@ -3844,47 +3867,7 @@ var createSandboxDaytonaServerProvider = (options = {}) => {
3844
3867
  };
3845
3868
  };
3846
3869
 
3847
- // src/cli/start.ts
3848
- var resolveUiDistPath = () => {
3849
- const currentDir = dirname3(fileURLToPath(import.meta.url));
3850
- const candidates = [
3851
- resolve5(currentDir, "../../ui/dist"),
3852
- resolve5(currentDir, "../ui/dist"),
3853
- resolve5(process.cwd(), "ui/dist"),
3854
- resolve5(process.cwd(), "cli/ui/dist")
3855
- ];
3856
- for (const candidate of candidates) {
3857
- if (existsSync(candidate)) {
3858
- return candidate;
3859
- }
3860
- }
3861
- return candidates[0];
3862
- };
3863
- var packLocalCli = (logger) => {
3864
- const cliDir = resolve5(dirname3(fileURLToPath(import.meta.url)), "..");
3865
- const packageJson = resolve5(cliDir, "package.json");
3866
- if (!existsSync(packageJson)) {
3867
- return void 0;
3868
- }
3869
- const result = spawnSync("npm", ["pack"], { cwd: cliDir, encoding: "utf8" });
3870
- if (result.status !== 0) {
3871
- const stderr = result.stderr?.toString().trim();
3872
- logger.warn(`Local CLI pack failed${stderr ? ` (${stderr})` : ""}`);
3873
- return void 0;
3874
- }
3875
- const lines = result.stdout?.toString().trim().split(/\r?\n/).filter(Boolean) ?? [];
3876
- const filename = lines[lines.length - 1];
3877
- if (!filename) {
3878
- logger.warn("Local CLI pack failed (no output)");
3879
- return void 0;
3880
- }
3881
- return resolve5(cliDir, filename);
3882
- };
3883
- var createDefaultLogger = () => ({
3884
- info: (message) => console.log(message),
3885
- warn: (message) => console.warn(message),
3886
- error: (message) => console.error(message)
3887
- });
3870
+ // src/cli/agent-config.ts
3888
3871
  var defaultAgentEnvKeys = [
3889
3872
  "OPENAI_API_KEY",
3890
3873
  "OPENAI_BASE_URL",
@@ -3955,6 +3938,48 @@ var resolveAutoAgentNames = (env) => {
3955
3938
  const auto = parseBoolean(env.TERMBRIDGE_SANDBOX_AGENT_AUTO);
3956
3939
  return auto ? ["all"] : [];
3957
3940
  };
3941
+
3942
+ // src/cli/start.ts
3943
+ var resolveUiDistPath = () => {
3944
+ const currentDir = dirname3(fileURLToPath(import.meta.url));
3945
+ const candidates = [
3946
+ resolve5(currentDir, "../../ui/dist"),
3947
+ resolve5(currentDir, "../ui/dist"),
3948
+ resolve5(process.cwd(), "ui/dist"),
3949
+ resolve5(process.cwd(), "cli/ui/dist")
3950
+ ];
3951
+ for (const candidate of candidates) {
3952
+ if (existsSync(candidate)) {
3953
+ return candidate;
3954
+ }
3955
+ }
3956
+ return candidates[0];
3957
+ };
3958
+ var packLocalCli = (logger) => {
3959
+ const cliDir = resolve5(dirname3(fileURLToPath(import.meta.url)), "..");
3960
+ const packageJson = resolve5(cliDir, "package.json");
3961
+ if (!existsSync(packageJson)) {
3962
+ return void 0;
3963
+ }
3964
+ const result = spawnSync("npm", ["pack"], { cwd: cliDir, encoding: "utf8" });
3965
+ if (result.status !== 0) {
3966
+ const stderr = result.stderr?.toString().trim();
3967
+ logger.warn(`Local CLI pack failed${stderr ? ` (${stderr})` : ""}`);
3968
+ return void 0;
3969
+ }
3970
+ const lines = result.stdout?.toString().trim().split(/\r?\n/).filter(Boolean) ?? [];
3971
+ const filename = lines[lines.length - 1];
3972
+ if (!filename) {
3973
+ logger.warn("Local CLI pack failed (no output)");
3974
+ return void 0;
3975
+ }
3976
+ return resolve5(cliDir, filename);
3977
+ };
3978
+ var createDefaultLogger = () => ({
3979
+ info: (message) => console.log(message),
3980
+ warn: (message) => console.warn(message),
3981
+ error: (message) => console.error(message)
3982
+ });
3958
3983
  var resolveBackendMode = (value) => {
3959
3984
  if (!value) {
3960
3985
  return "tmux";