clay-server 2.17.0-beta.2 → 2.17.0-beta.3

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 (3) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +55 -24
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -168,7 +168,7 @@ Yes. Create as many as you need. A code reviewer, a writing partner, a project m
168
168
 
169
169
  ## HTTPS
170
170
 
171
- HTTPS is enabled by default using a builtin wildcard certificate for `*.d.clay.studio`. No setup required. Your browser connects to a URL like:
171
+ HTTPS is enabled by default using a builtin wildcard certificate for `*.d.clay.studio`. No setup required. Available from `v2.17.0-beta.2`. Your browser connects to a URL like:
172
172
 
173
173
  ```
174
174
  https://192-168-1-50.d.clay.studio:2633
package/bin/cli.js CHANGED
@@ -599,12 +599,6 @@ function toClayStudioUrl(ip, port, protocol) {
599
599
  }
600
600
 
601
601
  function ensureCerts(ip) {
602
- // Check builtin cert first (unless --local-cert flag is set)
603
- if (!forceMkcert) {
604
- var builtin = getBuiltinCert();
605
- if (builtin) return builtin;
606
- }
607
-
608
602
  var homeDir = os.homedir();
609
603
  var certDir = path.join(process.env.CLAY_HOME || path.join(homeDir, ".clay"), "certs");
610
604
  var keyPath = path.join(certDir, "key.pem");
@@ -619,14 +613,18 @@ function ensureCerts(ip) {
619
613
  fs.copyFileSync(legacyCert, certPath);
620
614
  }
621
615
 
616
+ var mkcertInstalled = hasMkcert();
617
+
622
618
  var caRoot = null;
623
- try {
624
- caRoot = path.join(
625
- execSync("mkcert -CAROOT", { encoding: "utf8" }).trim(),
626
- "rootCA.pem"
627
- );
628
- if (!fs.existsSync(caRoot)) caRoot = null;
629
- } catch (e) {}
619
+ if (mkcertInstalled) {
620
+ try {
621
+ caRoot = path.join(
622
+ execSync("mkcert -CAROOT", { encoding: "utf8" }).trim(),
623
+ "rootCA.pem"
624
+ );
625
+ if (!fs.existsSync(caRoot)) caRoot = null;
626
+ } catch (e) {}
627
+ }
630
628
 
631
629
  // Collect all IPv4 addresses (Tailscale + LAN)
632
630
  var allIPs = getAllIPs();
@@ -644,24 +642,39 @@ function ensureCerts(ip) {
644
642
  }
645
643
  }
646
644
  } catch (e) { needRegen = true; }
647
- if (!needRegen) return { key: keyPath, cert: certPath, caRoot: caRoot };
645
+ if (!needRegen) {
646
+ return { key: keyPath, cert: certPath, caRoot: caRoot, mkcertDetected: mkcertInstalled && !forceMkcert };
647
+ }
648
648
  }
649
649
 
650
- fs.mkdirSync(certDir, { recursive: true });
650
+ // mkcert installed: generate local cert (legacy behavior)
651
+ if (mkcertInstalled) {
652
+ fs.mkdirSync(certDir, { recursive: true });
653
+
654
+ var domains = ["localhost", "127.0.0.1", "::1"];
655
+ for (var i = 0; i < allIPs.length; i++) {
656
+ if (domains.indexOf(allIPs[i]) === -1) domains.push(allIPs[i]);
657
+ }
651
658
 
652
- var domains = ["localhost", "127.0.0.1", "::1"];
653
- for (var i = 0; i < allIPs.length; i++) {
654
- if (domains.indexOf(allIPs[i]) === -1) domains.push(allIPs[i]);
659
+ try {
660
+ var mkcertArgs = ["-key-file", keyPath, "-cert-file", certPath].concat(domains);
661
+ execFileSync("mkcert", mkcertArgs, { stdio: "pipe" });
662
+ } catch (err) {
663
+ // mkcert generation failed, fall through to builtin
664
+ }
665
+
666
+ if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
667
+ return { key: keyPath, cert: certPath, caRoot: caRoot, mkcertDetected: !forceMkcert };
668
+ }
655
669
  }
656
670
 
657
- try {
658
- var mkcertArgs = ["-key-file", keyPath, "-cert-file", certPath].concat(domains);
659
- execFileSync("mkcert", mkcertArgs, { stdio: "pipe" });
660
- } catch (err) {
661
- return null;
671
+ // Fallback: builtin cert (unless --local-cert forces mkcert-only)
672
+ if (!forceMkcert) {
673
+ var builtin = getBuiltinCert();
674
+ if (builtin) return builtin;
662
675
  }
663
676
 
664
- return { key: keyPath, cert: certPath, caRoot: caRoot };
677
+ return null;
665
678
  }
666
679
 
667
680
  // --- Logo ---
@@ -1436,12 +1449,14 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
1436
1449
  var ip = getLocalIP();
1437
1450
  var hasTls = false;
1438
1451
  var hasBuiltinCert = false;
1452
+ var mkcertDetected = false;
1439
1453
 
1440
1454
  if (useHttps) {
1441
1455
  var certPaths = ensureCerts(ip);
1442
1456
  if (certPaths) {
1443
1457
  hasTls = true;
1444
1458
  if (certPaths.builtin) hasBuiltinCert = true;
1459
+ if (certPaths.mkcertDetected) mkcertDetected = true;
1445
1460
  } else {
1446
1461
  log(sym.warn + " " + a.yellow + "HTTPS unavailable" + a.reset + a.dim + " · mkcert not installed" + a.reset);
1447
1462
  }
@@ -1516,6 +1531,7 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
1516
1531
  pinHash: mode === "multi" && cliPin ? generateAuthToken(cliPin) : null,
1517
1532
  tls: hasTls,
1518
1533
  builtinCert: hasBuiltinCert,
1534
+ mkcertDetected: mkcertDetected,
1519
1535
  debug: debugMode,
1520
1536
  keepAwake: keepAwake,
1521
1537
  dangerouslySkipPermissions: dangerouslySkipPermissions,
@@ -1596,6 +1612,7 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
1596
1612
  console.log(" " + sym.done + " Daemon started (PID " + config.pid + ")");
1597
1613
  console.log(" " + sym.done + " " + url);
1598
1614
  if (config.builtinCert) console.log(" " + sym.done + " d.clay.studio is only used for HTTPS certificates. All traffic stays on your local network. https://github.com/chadbyte/clay/tree/main/clay-dns");
1615
+ if (config.mkcertDetected) console.log(" " + sym.warn + " mkcert detected. Uninstall mkcert to use builtin cert, or pass --local-cert to suppress this warning.");
1599
1616
  console.log(" " + sym.done + " Headless mode — exiting CLI");
1600
1617
  process.exit(0);
1601
1618
  return;
@@ -1612,12 +1629,14 @@ async function devMode(mode, keepAwake, existingPinHash) {
1612
1629
  var ip = getLocalIP();
1613
1630
  var hasTls = false;
1614
1631
  var hasBuiltinCert = false;
1632
+ var mkcertDetected = false;
1615
1633
 
1616
1634
  if (useHttps) {
1617
1635
  var certPaths = ensureCerts(ip);
1618
1636
  if (certPaths) {
1619
1637
  hasTls = true;
1620
1638
  if (certPaths.builtin) hasBuiltinCert = true;
1639
+ if (certPaths.mkcertDetected) mkcertDetected = true;
1621
1640
  }
1622
1641
  }
1623
1642
 
@@ -1681,6 +1700,7 @@ async function devMode(mode, keepAwake, existingPinHash) {
1681
1700
  pinHash: existingPinHash || null,
1682
1701
  tls: hasTls,
1683
1702
  builtinCert: hasBuiltinCert,
1703
+ mkcertDetected: mkcertDetected,
1684
1704
  debug: true,
1685
1705
  keepAwake: keepAwake || false,
1686
1706
  dangerouslySkipPermissions: dangerouslySkipPermissions,
@@ -1830,6 +1850,7 @@ async function restartDaemonWithTLS(config, callback) {
1830
1850
  return;
1831
1851
  }
1832
1852
  var hasBuiltinCert = !!(certPaths && certPaths.builtin);
1853
+ var mkcertDetected = !!(certPaths && certPaths.mkcertDetected);
1833
1854
 
1834
1855
  // Shut down old daemon
1835
1856
  stopDaemonWatcher();
@@ -1854,6 +1875,7 @@ async function restartDaemonWithTLS(config, callback) {
1854
1875
  pinHash: config.pinHash || null,
1855
1876
  tls: true,
1856
1877
  builtinCert: hasBuiltinCert,
1878
+ mkcertDetected: mkcertDetected,
1857
1879
  debug: config.debug || false,
1858
1880
  keepAwake: config.keepAwake || false,
1859
1881
  dangerouslySkipPermissions: config.dangerouslySkipPermissions || false,
@@ -1963,6 +1985,15 @@ function showMainMenu(config, ip) {
1963
1985
  log(" Press " + a.bold + "o" + a.reset + " to open in browser");
1964
1986
  log("");
1965
1987
 
1988
+ if (config.mkcertDetected) {
1989
+ log(" " + sym.warn + " " + a.yellow + "mkcert detected." + a.reset + " Clay now ships with a builtin HTTPS certificate.");
1990
+ log(" " + a.dim + "Uninstall mkcert to use it. No more CA setup on each device." + a.reset);
1991
+ log(" " + a.dim + " brew uninstall mkcert (macOS)" + a.reset);
1992
+ log(" " + a.dim + " sudo apt remove mkcert (Linux)" + a.reset);
1993
+ log(" " + a.dim + "Or pass --local-cert to keep using mkcert without this warning." + a.reset);
1994
+ log("");
1995
+ }
1996
+
1966
1997
  showMenuItems();
1967
1998
  }
1968
1999
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.17.0-beta.2",
3
+ "version": "2.17.0-beta.3",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",