closeclaw 3.0.13 → 3.0.15
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.cjs +204 -6
- package/dist/cli.jsc +0 -0
- package/dist/index.jsc +0 -0
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -7954,7 +7954,7 @@ function saveLicenseKey(key) {
|
|
|
7954
7954
|
}
|
|
7955
7955
|
async function commandOnboard() {
|
|
7956
7956
|
const version = readPkgVersion();
|
|
7957
|
-
const TOTAL_STEPS =
|
|
7957
|
+
const TOTAL_STEPS = 9;
|
|
7958
7958
|
console.log("");
|
|
7959
7959
|
console.log(` ${c.cyan}${c.bold}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557${c.reset}`);
|
|
7960
7960
|
console.log(` ${c.cyan}${c.bold}\u2551 CloseClaw \u2014 Setup Wizard \u2551${c.reset}`);
|
|
@@ -8174,17 +8174,154 @@ async function commandOnboard() {
|
|
|
8174
8174
|
result(INFO, `Enable later: ${c.dim}closeclaw onboard${c.reset} or edit ${c.dim}~/.closeclaw/config.json${c.reset}`);
|
|
8175
8175
|
}
|
|
8176
8176
|
}
|
|
8177
|
-
step(8, TOTAL_STEPS, "
|
|
8177
|
+
step(8, TOTAL_STEPS, "Domain & SSL (optional)");
|
|
8178
|
+
if (config.domain) {
|
|
8179
|
+
result(PASS, `Domain configured: ${c.bold}${config.domain}${c.reset}`);
|
|
8180
|
+
const caddyBin = (0, import_node_path6.join)(CONFIG_DIR, "bin", "caddy");
|
|
8181
|
+
if ((0, import_node_fs7.existsSync)(caddyBin)) {
|
|
8182
|
+
result(PASS, "Caddy installed");
|
|
8183
|
+
} else {
|
|
8184
|
+
result(WARN, "Caddy not installed \u2014 will download on first start with --domain");
|
|
8185
|
+
}
|
|
8186
|
+
} else {
|
|
8187
|
+
const setupDomain = await ask(` Set up a public domain with HTTPS? ${c.dim}(y/N)${c.reset} `);
|
|
8188
|
+
if (setupDomain.toLowerCase() === "y" || setupDomain.toLowerCase() === "yes") {
|
|
8189
|
+
console.log("");
|
|
8190
|
+
console.log(` ${c.bold}Before continuing, you need:${c.reset}`);
|
|
8191
|
+
console.log(` ${c.cyan}1.${c.reset} A server with a public IP address`);
|
|
8192
|
+
console.log(` ${c.cyan}2.${c.reset} A domain pointing to that IP`);
|
|
8193
|
+
console.log(` ${c.cyan}3.${c.reset} Ports 80 and 443 open in your firewall`);
|
|
8194
|
+
console.log("");
|
|
8195
|
+
console.log(` ${c.bold}How to add the DNS record:${c.reset}`);
|
|
8196
|
+
console.log("");
|
|
8197
|
+
console.log(` ${c.yellow}Hostinger:${c.reset}`);
|
|
8198
|
+
console.log(` ${c.dim}\u2192 hPanel \u2192 Domains \u2192 DNS/Nameservers \u2192 DNS Records${c.reset}`);
|
|
8199
|
+
console.log(` ${c.dim}\u2192 Add Record: Type=A, Name=app, Points to=YOUR_SERVER_IP${c.reset}`);
|
|
8200
|
+
console.log("");
|
|
8201
|
+
console.log(` ${c.yellow}AWS Route 53:${c.reset}`);
|
|
8202
|
+
console.log(` ${c.dim}\u2192 Route 53 \u2192 Hosted Zones \u2192 your domain \u2192 Create Record${c.reset}`);
|
|
8203
|
+
console.log(` ${c.dim}\u2192 Record type=A, Record name=app, Value=YOUR_SERVER_IP${c.reset}`);
|
|
8204
|
+
console.log("");
|
|
8205
|
+
console.log(` ${c.yellow}Cloudflare:${c.reset}`);
|
|
8206
|
+
console.log(` ${c.dim}\u2192 DNS \u2192 Records \u2192 Add Record${c.reset}`);
|
|
8207
|
+
console.log(` ${c.dim}\u2192 Type=A, Name=app, IPv4=YOUR_SERVER_IP, Proxy=OFF${c.reset}`);
|
|
8208
|
+
console.log("");
|
|
8209
|
+
console.log(` ${c.yellow}GoDaddy:${c.reset}`);
|
|
8210
|
+
console.log(` ${c.dim}\u2192 My Products \u2192 DNS \u2192 Add Record${c.reset}`);
|
|
8211
|
+
console.log(` ${c.dim}\u2192 Type=A, Name=app, Value=YOUR_SERVER_IP, TTL=600${c.reset}`);
|
|
8212
|
+
console.log("");
|
|
8213
|
+
console.log(` ${c.yellow}Namecheap:${c.reset}`);
|
|
8214
|
+
console.log(` ${c.dim}\u2192 Domain List \u2192 Manage \u2192 Advanced DNS \u2192 Add New Record${c.reset}`);
|
|
8215
|
+
console.log(` ${c.dim}\u2192 Type=A, Host=app, Value=YOUR_SERVER_IP${c.reset}`);
|
|
8216
|
+
console.log("");
|
|
8217
|
+
const domain = await ask(` Your domain (e.g. app.company.com): `);
|
|
8218
|
+
if (domain) {
|
|
8219
|
+
config.domain = domain;
|
|
8220
|
+
console.log("");
|
|
8221
|
+
result(INFO, `Checking DNS for ${domain}...`);
|
|
8222
|
+
try {
|
|
8223
|
+
const dns = require("dns");
|
|
8224
|
+
const resolved = await new Promise((resolve, reject) => {
|
|
8225
|
+
dns.resolve4(domain, (err, addresses) => {
|
|
8226
|
+
if (err) reject(err);
|
|
8227
|
+
else resolve(addresses);
|
|
8228
|
+
});
|
|
8229
|
+
});
|
|
8230
|
+
result(PASS, `DNS resolves to ${c.bold}${resolved.join(", ")}${c.reset}`);
|
|
8231
|
+
} catch {
|
|
8232
|
+
result(WARN, "DNS not resolving yet \u2014 it can take up to 48h to propagate");
|
|
8233
|
+
result(INFO, "You can still proceed \u2014 Caddy will retry on start");
|
|
8234
|
+
}
|
|
8235
|
+
result(INFO, "Installing Caddy (reverse proxy for auto-SSL)...");
|
|
8236
|
+
const caddyDir = (0, import_node_path6.join)(CONFIG_DIR, "bin");
|
|
8237
|
+
const caddyBin = (0, import_node_path6.join)(caddyDir, "caddy");
|
|
8238
|
+
if ((0, import_node_fs7.existsSync)(caddyBin)) {
|
|
8239
|
+
result(PASS, "Caddy already installed");
|
|
8240
|
+
} else {
|
|
8241
|
+
try {
|
|
8242
|
+
(0, import_node_fs7.mkdirSync)(caddyDir, { recursive: true });
|
|
8243
|
+
const os2 = require("os");
|
|
8244
|
+
const platform = os2.platform();
|
|
8245
|
+
const arch = os2.arch();
|
|
8246
|
+
const caddyOS = platform === "darwin" ? "mac" : "linux";
|
|
8247
|
+
const caddyArch = arch === "arm64" ? "arm64" : "amd64";
|
|
8248
|
+
const version2 = "2.9.1";
|
|
8249
|
+
const ext = platform === "darwin" ? "zip" : "tar.gz";
|
|
8250
|
+
const url = `https://github.com/caddyserver/caddy/releases/download/v${version2}/caddy_${version2}_${caddyOS}_${caddyArch}.${ext}`;
|
|
8251
|
+
result(INFO, `Downloading from ${c.dim}${url}${c.reset}`);
|
|
8252
|
+
if (ext === "tar.gz") {
|
|
8253
|
+
(0, import_node_child_process3.execSync)(`curl -fsSL "${url}" | tar xz -C "${caddyDir}" caddy`, { stdio: "pipe", timeout: 12e4 });
|
|
8254
|
+
} else {
|
|
8255
|
+
const tmpZip = (0, import_node_path6.join)(caddyDir, "caddy.zip");
|
|
8256
|
+
(0, import_node_child_process3.execSync)(`curl -fsSL -o "${tmpZip}" "${url}"`, { stdio: "pipe", timeout: 12e4 });
|
|
8257
|
+
(0, import_node_child_process3.execSync)(`unzip -o -j "${tmpZip}" caddy -d "${caddyDir}"`, { stdio: "pipe" });
|
|
8258
|
+
(0, import_node_fs7.unlinkSync)(tmpZip);
|
|
8259
|
+
}
|
|
8260
|
+
(0, import_node_child_process3.execSync)(`chmod +x "${caddyBin}"`);
|
|
8261
|
+
result(PASS, `Caddy installed at ${c.dim}${caddyBin}${c.reset}`);
|
|
8262
|
+
} catch (err) {
|
|
8263
|
+
result(FAIL, `Could not download Caddy: ${err.message?.split("\n")[0]}`);
|
|
8264
|
+
result(INFO, `Install manually: ${c.dim}https://caddyserver.com/download${c.reset}`);
|
|
8265
|
+
result(INFO, `Then copy the binary to ${c.dim}${caddyDir}/caddy${c.reset}`);
|
|
8266
|
+
}
|
|
8267
|
+
}
|
|
8268
|
+
console.log("");
|
|
8269
|
+
result(INFO, "Checking ports 80 and 443...");
|
|
8270
|
+
for (const p of [80, 443]) {
|
|
8271
|
+
try {
|
|
8272
|
+
const net = require("net");
|
|
8273
|
+
const inUse = await new Promise((resolve) => {
|
|
8274
|
+
const srv = net.createServer();
|
|
8275
|
+
srv.once("error", () => resolve(true));
|
|
8276
|
+
srv.once("listening", () => {
|
|
8277
|
+
srv.close();
|
|
8278
|
+
resolve(false);
|
|
8279
|
+
});
|
|
8280
|
+
srv.listen(p, "0.0.0.0");
|
|
8281
|
+
});
|
|
8282
|
+
if (inUse) {
|
|
8283
|
+
result(WARN, `Port ${p} is in use \u2014 Caddy needs it free`);
|
|
8284
|
+
} else {
|
|
8285
|
+
result(PASS, `Port ${p} available`);
|
|
8286
|
+
}
|
|
8287
|
+
} catch {
|
|
8288
|
+
result(WARN, `Could not check port ${p} (may need root/sudo)`);
|
|
8289
|
+
}
|
|
8290
|
+
}
|
|
8291
|
+
(0, import_node_fs7.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
8292
|
+
(0, import_node_fs7.writeFileSync)(configPath, JSON.stringify(config, null, 2));
|
|
8293
|
+
result(PASS, "Domain configuration saved");
|
|
8294
|
+
console.log("");
|
|
8295
|
+
console.log(` ${c.bold}To start with HTTPS:${c.reset}`);
|
|
8296
|
+
console.log(` ${c.cyan}closeclaw start --domain ${domain}${c.reset}`);
|
|
8297
|
+
console.log("");
|
|
8298
|
+
console.log(` ${c.dim}Caddy will auto-provision an SSL certificate from Let's Encrypt.${c.reset}`);
|
|
8299
|
+
console.log(` ${c.dim}First request may take ~5 seconds while the cert is issued.${c.reset}`);
|
|
8300
|
+
} else {
|
|
8301
|
+
result(SKIP, "Skipped");
|
|
8302
|
+
}
|
|
8303
|
+
} else {
|
|
8304
|
+
result(SKIP, "Localhost only \u2014 no HTTPS");
|
|
8305
|
+
result(INFO, `Add later: ${c.dim}closeclaw start --domain app.company.com${c.reset}`);
|
|
8306
|
+
}
|
|
8307
|
+
}
|
|
8308
|
+
step(9, TOTAL_STEPS, "Ready!");
|
|
8178
8309
|
console.log("");
|
|
8179
8310
|
console.log(` ${c.green}${c.bold}Setup complete.${c.reset} Start the server with:`);
|
|
8180
8311
|
console.log("");
|
|
8181
|
-
if (
|
|
8312
|
+
if (config.domain) {
|
|
8182
8313
|
console.log(` ${c.cyan}closeclaw start${c.reset}`);
|
|
8314
|
+
console.log("");
|
|
8315
|
+
console.log(` Then open ${c.bold}https://${config.domain}${c.reset} in your browser.`);
|
|
8316
|
+
} else if (licenseKey) {
|
|
8317
|
+
console.log(` ${c.cyan}closeclaw start${c.reset}`);
|
|
8318
|
+
console.log("");
|
|
8319
|
+
console.log(` Then open ${c.bold}http://localhost:3001${c.reset} in your browser.`);
|
|
8183
8320
|
} else {
|
|
8184
8321
|
console.log(` ${c.cyan}closeclaw start${c.reset} ${c.dim}(dev mode)${c.reset}`);
|
|
8322
|
+
console.log("");
|
|
8323
|
+
console.log(` Then open ${c.bold}http://localhost:3001${c.reset} in your browser.`);
|
|
8185
8324
|
}
|
|
8186
|
-
console.log("");
|
|
8187
|
-
console.log(` Then open ${c.bold}http://localhost:3001${c.reset} in your browser.`);
|
|
8188
8325
|
console.log(` First signup becomes admin.`);
|
|
8189
8326
|
console.log("");
|
|
8190
8327
|
const startNow = await ask(` Start the server now? ${c.dim}(Y/n)${c.reset} `);
|
|
@@ -8211,7 +8348,13 @@ async function commandStart(args) {
|
|
|
8211
8348
|
const host2 = values.host;
|
|
8212
8349
|
let licenseKey = values.key || getSavedLicenseKey() || "";
|
|
8213
8350
|
const dataDir = values["data-dir"];
|
|
8214
|
-
|
|
8351
|
+
let domain = values.domain;
|
|
8352
|
+
if (!domain) {
|
|
8353
|
+
try {
|
|
8354
|
+
domain = JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path6.join)(CONFIG_DIR, "config.json"), "utf-8")).domain || "";
|
|
8355
|
+
} catch {
|
|
8356
|
+
}
|
|
8357
|
+
}
|
|
8215
8358
|
process.env.PORT = String(port2);
|
|
8216
8359
|
process.env.HOST = host2;
|
|
8217
8360
|
if (licenseKey) process.env.PLATFORM_LICENSE_KEY = licenseKey;
|
|
@@ -8267,17 +8410,72 @@ async function commandStart(args) {
|
|
|
8267
8410
|
}
|
|
8268
8411
|
await Promise.resolve().then(() => (init_index(), index_exports));
|
|
8269
8412
|
writePid();
|
|
8413
|
+
let caddyProcess = null;
|
|
8414
|
+
const effectiveDomain = domain || (() => {
|
|
8415
|
+
try {
|
|
8416
|
+
return JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path6.join)(CONFIG_DIR, "config.json"), "utf-8")).domain;
|
|
8417
|
+
} catch {
|
|
8418
|
+
return "";
|
|
8419
|
+
}
|
|
8420
|
+
})();
|
|
8421
|
+
if (effectiveDomain) {
|
|
8422
|
+
const caddyBin = (0, import_node_path6.join)(CONFIG_DIR, "bin", "caddy");
|
|
8423
|
+
if ((0, import_node_fs7.existsSync)(caddyBin)) {
|
|
8424
|
+
console.log(` ${c.dim}Starting Caddy reverse proxy for ${effectiveDomain}...${c.reset}`);
|
|
8425
|
+
const { spawn: spawnChild } = require("child_process");
|
|
8426
|
+
caddyProcess = spawnChild(caddyBin, [
|
|
8427
|
+
"reverse-proxy",
|
|
8428
|
+
"--from",
|
|
8429
|
+
effectiveDomain,
|
|
8430
|
+
"--to",
|
|
8431
|
+
`localhost:${port2}`
|
|
8432
|
+
], {
|
|
8433
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
8434
|
+
detached: false
|
|
8435
|
+
});
|
|
8436
|
+
caddyProcess.stdout?.on("data", (d) => {
|
|
8437
|
+
const msg = d.toString().trim();
|
|
8438
|
+
if (msg) console.log(` ${c.dim}[caddy]${c.reset} ${msg}`);
|
|
8439
|
+
});
|
|
8440
|
+
caddyProcess.stderr?.on("data", (d) => {
|
|
8441
|
+
const msg = d.toString().trim();
|
|
8442
|
+
if (msg) console.log(` ${c.dim}[caddy]${c.reset} ${msg}`);
|
|
8443
|
+
});
|
|
8444
|
+
caddyProcess.on("exit", (code) => {
|
|
8445
|
+
if (code) console.error(` ${c.red}[caddy] Exited with code ${code}${c.reset}`);
|
|
8446
|
+
});
|
|
8447
|
+
const killCaddy = () => {
|
|
8448
|
+
try {
|
|
8449
|
+
caddyProcess?.kill("SIGTERM");
|
|
8450
|
+
} catch {
|
|
8451
|
+
}
|
|
8452
|
+
};
|
|
8453
|
+
process.on("SIGTERM", killCaddy);
|
|
8454
|
+
process.on("SIGINT", killCaddy);
|
|
8455
|
+
process.on("exit", killCaddy);
|
|
8456
|
+
} else {
|
|
8457
|
+
console.log(` ${c.yellow}Caddy not found at ${caddyBin}${c.reset}`);
|
|
8458
|
+
console.log(` ${c.yellow}Run ${c.cyan}closeclaw onboard${c.reset}${c.yellow} to install Caddy, or download from https://caddyserver.com${c.reset}`);
|
|
8459
|
+
}
|
|
8460
|
+
}
|
|
8270
8461
|
const version = readPkgVersion();
|
|
8271
8462
|
const localUrl = `http://localhost:${port2}`;
|
|
8463
|
+
const publicUrl = effectiveDomain ? `https://${effectiveDomain}` : null;
|
|
8272
8464
|
console.log("");
|
|
8273
8465
|
console.log(` ${c.green}${c.bold}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557${c.reset}`);
|
|
8274
8466
|
console.log(` ${c.green}${c.bold}\u2551 CloseClaw v${version.padEnd(31)}\u2551${c.reset}`);
|
|
8275
8467
|
console.log(` ${c.green}${c.bold}\u2551 \u2551${c.reset}`);
|
|
8468
|
+
if (publicUrl) {
|
|
8469
|
+
console.log(` ${c.green}${c.bold}\u2551${c.reset} ${c.cyan}${publicUrl.padEnd(40)}${c.reset}${c.green}${c.bold}\u2551${c.reset}`);
|
|
8470
|
+
}
|
|
8276
8471
|
console.log(` ${c.green}${c.bold}\u2551${c.reset} ${c.cyan}${localUrl.padEnd(40)}${c.reset}${c.green}${c.bold}\u2551${c.reset}`);
|
|
8277
8472
|
console.log(` ${c.green}${c.bold}\u2551${c.reset} ${c.dim}PID: ${String(process.pid).padEnd(36)}${c.reset}${c.green}${c.bold}\u2551${c.reset}`);
|
|
8278
8473
|
if (openclawPath) {
|
|
8279
8474
|
console.log(` ${c.green}${c.bold}\u2551${c.reset} ${c.dim}OpenClaw: port 18789${" ".repeat(21)}${c.reset}${c.green}${c.bold}\u2551${c.reset}`);
|
|
8280
8475
|
}
|
|
8476
|
+
if (publicUrl) {
|
|
8477
|
+
console.log(` ${c.green}${c.bold}\u2551${c.reset} ${c.dim}SSL: auto (Let's Encrypt via Caddy)${" ".repeat(5)}${c.reset}${c.green}${c.bold}\u2551${c.reset}`);
|
|
8478
|
+
}
|
|
8281
8479
|
console.log(` ${c.green}${c.bold}\u2551 \u2551${c.reset}`);
|
|
8282
8480
|
console.log(` ${c.green}${c.bold}\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${c.reset}`);
|
|
8283
8481
|
console.log("");
|
package/dist/cli.jsc
CHANGED
|
Binary file
|
package/dist/index.jsc
CHANGED
|
Binary file
|