@willjackson/claude-code-bridge 0.6.2 → 0.7.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.
package/dist/cli.js CHANGED
@@ -4,9 +4,13 @@ import {
4
4
  BridgeMcpServer,
5
5
  ConnectionState,
6
6
  WebSocketTransport,
7
+ createAuthConfigFromOptions,
7
8
  createLogger,
8
- loadConfigSync
9
- } from "./chunk-XOAR3DQB.js";
9
+ isTLSEnabled,
10
+ loadConfigSync,
11
+ validateAuthConfig,
12
+ validateTLSConfig
13
+ } from "./chunk-2O352EPO.js";
10
14
 
11
15
  // src/cli/index.ts
12
16
  import { Command as Command7 } from "commander";
@@ -443,9 +447,26 @@ function registerHandlers(bridge, config) {
443
447
  logger.info("Handlers registered for context requests, tasks, and context sync");
444
448
  console.log(" Handlers: enabled (file reading & task processing)");
445
449
  }
450
+ function buildTLSConfig(options) {
451
+ if (!options.cert && !options.key && !options.ca) {
452
+ return void 0;
453
+ }
454
+ return {
455
+ cert: options.cert,
456
+ key: options.key,
457
+ ca: options.ca
458
+ };
459
+ }
446
460
  function buildBridgeConfig(options, globalOptions) {
447
461
  const fileConfig = loadConfigSync(globalOptions.config);
448
462
  const cliConfig = {};
463
+ const cliTlsConfig = buildTLSConfig(options);
464
+ const cliAuthConfig = createAuthConfigFromOptions({
465
+ authToken: options.authToken,
466
+ authPassword: options.authPassword,
467
+ authIp: options.authIp,
468
+ authRequireAll: options.authRequireAll
469
+ });
449
470
  if (options.port) {
450
471
  cliConfig.listen = {
451
472
  ...cliConfig.listen,
@@ -466,12 +487,18 @@ function buildBridgeConfig(options, globalOptions) {
466
487
  }
467
488
  const hasConnect = cliConfig.connect || fileConfig.connect;
468
489
  const mode = hasConnect ? "client" : "host";
490
+ const listenTls = cliTlsConfig ?? fileConfig.listen?.tls;
491
+ const connectTls = cliTlsConfig ?? fileConfig.connect?.tls;
492
+ const listenAuth = cliAuthConfig.type !== "none" ? cliAuthConfig : fileConfig.listen?.auth;
493
+ const connectAuth = cliAuthConfig.type !== "none" ? cliAuthConfig : fileConfig.connect?.auth;
469
494
  const finalConfig = {
470
495
  mode: cliConfig.mode ?? fileConfig.mode ?? mode,
471
496
  instanceName: cliConfig.instanceName ?? fileConfig.instanceName ?? `bridge-${process.pid}`,
472
497
  listen: {
473
498
  port: cliConfig.listen?.port ?? fileConfig.listen.port,
474
- host: cliConfig.listen?.host ?? fileConfig.listen.host
499
+ host: cliConfig.listen?.host ?? fileConfig.listen.host,
500
+ tls: listenTls,
501
+ auth: listenAuth
475
502
  },
476
503
  taskTimeout: fileConfig.interaction.taskTimeout,
477
504
  contextSharing: {
@@ -482,7 +509,9 @@ function buildBridgeConfig(options, globalOptions) {
482
509
  const connectUrl = cliConfig.connect?.url ?? fileConfig.connect?.url;
483
510
  if (connectUrl) {
484
511
  finalConfig.connect = {
485
- url: connectUrl
512
+ url: connectUrl,
513
+ tls: connectTls,
514
+ auth: connectAuth
486
515
  };
487
516
  }
488
517
  return finalConfig;
@@ -509,11 +538,48 @@ async function startBridge(options, globalOptions) {
509
538
  }
510
539
  }
511
540
  const config = buildBridgeConfig(options, globalOptions);
541
+ if (config.listen?.tls && isTLSEnabled(config.listen.tls)) {
542
+ const tlsValidation = validateTLSConfig(config.listen.tls);
543
+ if (!tlsValidation.valid) {
544
+ console.error("TLS configuration errors:");
545
+ for (const error of tlsValidation.errors) {
546
+ console.error(` - ${error}`);
547
+ }
548
+ process.exit(1);
549
+ }
550
+ for (const warning of tlsValidation.warnings) {
551
+ console.warn(` Warning: ${warning}`);
552
+ }
553
+ }
554
+ if (config.listen?.auth && config.listen.auth.type !== "none") {
555
+ const authValidation = validateAuthConfig(config.listen.auth);
556
+ if (!authValidation.valid) {
557
+ console.error("Authentication configuration errors:");
558
+ for (const error of authValidation.errors) {
559
+ console.error(` - ${error}`);
560
+ }
561
+ process.exit(1);
562
+ }
563
+ for (const warning of authValidation.warnings) {
564
+ console.warn(` Warning: ${warning}`);
565
+ }
566
+ }
512
567
  console.log("Starting Claude Code Bridge...");
513
568
  console.log(` Instance: ${config.instanceName}`);
514
569
  console.log(` Mode: ${config.mode}`);
515
570
  if (config.listen) {
516
- console.log(` Listening: ${config.listen.host}:${config.listen.port}`);
571
+ const protocol = isTLSEnabled(config.listen.tls) ? "wss" : "ws";
572
+ console.log(` Listening: ${protocol}://${config.listen.host}:${config.listen.port}`);
573
+ if (isTLSEnabled(config.listen.tls)) {
574
+ console.log(" TLS: enabled");
575
+ }
576
+ if (config.listen.auth && config.listen.auth.type !== "none") {
577
+ const authMethods = [];
578
+ if (config.listen.auth.token) authMethods.push("token");
579
+ if (config.listen.auth.password) authMethods.push("password");
580
+ if (config.listen.auth.allowedIps?.length) authMethods.push("ip");
581
+ console.log(` Auth: ${authMethods.join(", ")}${config.listen.auth.requireAll ? " (require all)" : ""}`);
582
+ }
517
583
  }
518
584
  if (config.connect) {
519
585
  console.log(` Connecting to: ${config.connect.url}`);
@@ -597,9 +663,12 @@ To connect from another bridge:`);
597
663
  process.exit(1);
598
664
  }
599
665
  }
666
+ function collect(value, previous) {
667
+ return previous.concat([value]);
668
+ }
600
669
  function createStartCommand() {
601
670
  const command = new Command("start");
602
- command.description("Start the bridge server").option("-p, --port <port>", "Port to listen on (default: 8765)").option("-h, --host <host>", "Host to bind to (default: 0.0.0.0)").option("-c, --connect <url>", "URL to connect to on startup (e.g., ws://localhost:8765)").option("-d, --daemon", "Run in background").option("--with-handlers", "Enable file reading and task handling capabilities").option("--launch-claude", "Start bridge daemon and launch Claude Code").argument("[claude-args...]", "Arguments to pass to Claude Code (use after --)").action(async (claudeArgs, options) => {
671
+ command.description("Start the bridge server").option("-p, --port <port>", "Port to listen on (default: 8765)").option("-h, --host <host>", "Host to bind to (default: 0.0.0.0)").option("-c, --connect <url>", "URL to connect to on startup (e.g., ws://localhost:8765 or wss://...)").option("-d, --daemon", "Run in background").option("--with-handlers", "Enable file reading and task handling capabilities").option("--launch-claude", "Start bridge daemon and launch Claude Code").option("--cert <path>", "Path to TLS certificate file").option("--key <path>", "Path to TLS private key file").option("--ca <path>", "Path to CA certificate file").option("--auth-token <token>", "Require token authentication").option("--auth-password <password>", "Require password authentication").option("--auth-ip <cidr>", "Allow connections from IP/CIDR (repeatable)", collect, []).option("--auth-require-all", "Require ALL auth methods to pass (default: any)").argument("[claude-args...]", "Arguments to pass to Claude Code (use after --)").action(async (claudeArgs, options) => {
603
672
  options.claudeArgs = claudeArgs;
604
673
  if (options.launchClaude) {
605
674
  options.daemon = true;
@@ -1153,12 +1222,31 @@ async function startMcpServer(options, _globalOptions) {
1153
1222
  console.error(`[MCP] Warning: Could not ensure daemon is running: ${error.message}`);
1154
1223
  }
1155
1224
  }
1225
+ let tlsConfig;
1226
+ if (options.ca || options.noVerifyTls) {
1227
+ tlsConfig = {
1228
+ ca: options.ca,
1229
+ rejectUnauthorized: options.noVerifyTls ? false : true
1230
+ };
1231
+ }
1232
+ let authConfig;
1233
+ if (options.authToken || options.authPassword) {
1234
+ const hasToken = !!options.authToken;
1235
+ const hasPassword = !!options.authPassword;
1236
+ authConfig = {
1237
+ type: hasToken && hasPassword ? "combined" : hasToken ? "token" : "password",
1238
+ token: options.authToken,
1239
+ password: options.authPassword
1240
+ };
1241
+ }
1156
1242
  const config = {
1157
1243
  bridgeUrl,
1158
1244
  name: options.name ?? "claude-bridge",
1159
1245
  version: "0.4.0",
1160
1246
  instanceName: `mcp-server-${process.pid}`,
1161
- taskTimeout: 6e4
1247
+ taskTimeout: 6e4,
1248
+ tls: tlsConfig,
1249
+ auth: authConfig
1162
1250
  };
1163
1251
  const server = new BridgeMcpServer(config);
1164
1252
  setupGracefulShutdown({
@@ -1185,7 +1273,7 @@ async function startMcpServer(options, _globalOptions) {
1185
1273
  }
1186
1274
  function createMcpServerCommand() {
1187
1275
  const command = new Command6("mcp-server");
1188
- command.description("Start the MCP server for Claude Code integration").option("-c, --connect <url>", `Bridge WebSocket URL (default: ws://localhost:${DEFAULT_DAEMON_PORT})`).option("--name <name>", "MCP server name (default: claude-bridge)").action(async (options) => {
1276
+ command.description("Start the MCP server for Claude Code integration").option("-c, --connect <url>", `Bridge WebSocket URL (default: ws://localhost:${DEFAULT_DAEMON_PORT})`).option("--name <name>", "MCP server name (default: claude-bridge)").option("--ca <path>", "CA certificate for verifying self-signed certs").option("--no-verify-tls", "Skip TLS certificate verification (insecure)").option("--auth-token <token>", "Token for authentication").option("--auth-password <password>", "Password for authentication").action(async (options) => {
1189
1277
  const globalOptions = command.parent?.opts();
1190
1278
  await startMcpServer(options, globalOptions);
1191
1279
  });