@layr-labs/ecloud-cli 1.0.0-devep2 → 1.0.0-devep4

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/VERSION CHANGED
@@ -1,2 +1,2 @@
1
- version=1.0.0-devep2
2
- commit=6556c862a68b0eb9962b654b22d428d984c9e6a5
1
+ version=1.0.0-devep4
2
+ commit=d34097bc2cac7cd1e0d74c3ae107481d47fbded9
@@ -8,60 +8,7 @@ import chalk from "chalk";
8
8
  import { input, confirm } from "@inquirer/prompts";
9
9
 
10
10
  // src/templates/tls/Caddyfile.tmpl
11
- var Caddyfile_default = `# Caddy configuration for automatic HTTPS
12
- # The DOMAIN environment variable will be injected at runtime
13
-
14
- {$DOMAIN:localhost} {
15
- # TLS configuration - always use provided certificates generated by tls-keygen
16
- tls /run/tls/fullchain.pem /run/tls/privkey.pem
17
-
18
- # Reverse proxy to your Node.js application
19
- # Modify the port to match your application (default: 3000)
20
- reverse_proxy localhost:{$APP_PORT:3000} {
21
- # Health check configuration
22
- health_uri /health
23
- health_interval 30s
24
- health_timeout 5s
25
- health_status 200
26
- }
27
-
28
- # Custom headers
29
- header {
30
- # Security headers
31
- X-Content-Type-Options "nosniff"
32
- X-Frame-Options "DENY"
33
- X-XSS-Protection "1; mode=block"
34
- Referrer-Policy "strict-origin-when-cross-origin"
35
-
36
- # Remove server header
37
- -Server
38
- }
39
-
40
- # Logging
41
- log {
42
- output stdout
43
- format console
44
- level INFO
45
- }
46
-
47
- # Request size limits
48
- request_body {
49
- max_size 10MB
50
- }
51
- }
52
-
53
- # HTTP endpoint (optional, for health checks or redirects)
54
- :80 {
55
- # Redirect to HTTPS only when host isn't localhost
56
- @for_domain expression {host} != "localhost"
57
- redir @for_domain https://{host}{uri} permanent
58
-
59
- # Health check endpoint (always available via HTTP)
60
- handle /health {
61
- respond "OK" 200
62
- }
63
- }
64
- `;
11
+ var Caddyfile_default = '# Caddy configuration for automatic HTTPS\n#\n# Two sites can be configured at runtime via env vars that\n# ecloud-platform / the CLI inject into tee-env metadata:\n#\n# ECLOUD_PLATFORM_HOST \u2014 the platform-derived hostname\n# (<addr>.<env>.eigencloud.xyz). Always set\n# for platform-routed apps. Cert at\n# /run/tls/platform/fullchain.pem.\n# DOMAIN \u2014 optional user-supplied custom domain.\n# Cert at /run/tls/domain/fullchain.pem.\n#\n# When a variable is unset, Caddy substitutes the default listed\n# after the colon. We use distinct defaults per site so each block\n# binds to a unique name at bootstrap \u2014 both blocks overlapping\n# on "localhost" would cause Caddy to reject the config.\n{$ECLOUD_PLATFORM_HOST:localhost.platform.invalid} {\n tls /run/tls/platform/fullchain.pem /run/tls/platform/privkey.pem\n\n reverse_proxy localhost:{$APP_PORT:3000} {\n health_uri /health\n health_interval 30s\n health_timeout 5s\n health_status 200\n }\n\n header {\n X-Content-Type-Options "nosniff"\n X-Frame-Options "DENY"\n X-XSS-Protection "1; mode=block"\n Referrer-Policy "strict-origin-when-cross-origin"\n -Server\n }\n\n log {\n output stdout\n format console\n level INFO\n }\n\n request_body {\n max_size 10MB\n }\n}\n\n{$DOMAIN:localhost.user.invalid} {\n tls /run/tls/domain/fullchain.pem /run/tls/domain/privkey.pem\n\n reverse_proxy localhost:{$APP_PORT:3000} {\n health_uri /health\n health_interval 30s\n health_timeout 5s\n health_status 200\n }\n\n header {\n X-Content-Type-Options "nosniff"\n X-Frame-Options "DENY"\n X-XSS-Protection "1; mode=block"\n Referrer-Policy "strict-origin-when-cross-origin"\n -Server\n }\n\n log {\n output stdout\n format console\n level INFO\n }\n\n request_body {\n max_size 10MB\n }\n}\n\n# HTTP endpoint (optional, for health checks or redirects)\n:80 {\n # Redirect to HTTPS for any real (non-placeholder) host\n @for_domain expression {host} != "localhost.platform.invalid" && {host} != "localhost.user.invalid" && {host} != "localhost"\n redir @for_domain https://{host}{uri} permanent\n\n # Health check endpoint (always available via HTTP)\n handle /health {\n respond "OK" 200\n }\n}\n';
65
12
 
66
13
  // src/templates/tls/templates.ts
67
14
  function getCaddyfileTemplate() {
@@ -106,24 +53,31 @@ function validatePort(value) {
106
53
  return true;
107
54
  }
108
55
  var ConfigureTLS = class _ConfigureTLS extends Command {
109
- static description = "Configure TLS for your application";
110
- static summary = `Configures TLS for your EigenCloud application.
56
+ static description = "Configure a custom domain for your app (optional)";
57
+ static summary = `Configures a custom domain for your EigenCloud application.
111
58
 
112
- Prompts for domain and TLS settings (or accepts them via flags), then:
113
- - Creates a Caddyfile for automatic HTTPS via Caddy reverse proxy
114
- - Appends TLS variables to .env with your values
59
+ By default, every deployed app is reachable at its platform-derived
60
+ hostname (<app-address>.<env-name>.eigencloud.xyz) with TLS already
61
+ set up. You only need this command if you also want the app reachable
62
+ at a custom domain you control.
63
+
64
+ Running this command:
65
+ - Creates a Caddyfile serving both the platform hostname and your
66
+ custom domain
67
+ - Appends DOMAIN + Caddy settings to .env
115
68
  - Appends TLS placeholders to .env.example
116
69
 
117
- TLS certificates are automatically obtained via Let's Encrypt using the tls-keygen tool.`;
70
+ After running this, set a DNS A record for your custom domain
71
+ pointing at the platform's proxy IP, then deploy/upgrade. Certs for
72
+ both hostnames are obtained via Let's Encrypt at VM boot.`;
118
73
  static examples = [
119
- "<%= config.bin %> compute app configure tls",
120
74
  "<%= config.bin %> compute app configure tls --domain myapp.example.com",
121
75
  "<%= config.bin %> compute app configure tls --domain myapp.example.com --app-port 8080",
122
76
  "<%= config.bin %> compute app configure tls --domain myapp.example.com --no-acme-staging"
123
77
  ];
124
78
  static flags = {
125
79
  domain: Flags.string({
126
- description: "Domain name for TLS certificate"
80
+ description: "Custom domain name for TLS certificate (additive to the platform hostname)"
127
81
  }),
128
82
  "app-port": Flags.string({
129
83
  description: "Port your application listens on",
@@ -145,7 +99,7 @@ TLS certificates are automatically obtained via Let's Encrypt using the tls-keyg
145
99
  const cwd = process.cwd();
146
100
  const envPath = path.join(cwd, ".env");
147
101
  if (envFileHasTlsConfig(envPath)) {
148
- this.warn("TLS is already configured in .env (DOMAIN is set). Skipping.");
102
+ this.warn("Custom domain is already configured in .env (DOMAIN is set). Skipping.");
149
103
  return;
150
104
  }
151
105
  const caddyfilePath = path.join(cwd, "Caddyfile");
@@ -160,14 +114,14 @@ TLS certificates are automatically obtained via Let's Encrypt using the tls-keyg
160
114
  let domain = flags.domain;
161
115
  if (!domain) {
162
116
  domain = await input({
163
- message: "Domain name:",
117
+ message: "Custom domain name:",
164
118
  validate: validateDomain
165
119
  });
166
120
  } else {
167
121
  const result = validateDomain(domain);
168
122
  if (result !== true) this.error(result);
169
123
  }
170
- let appPort = flags["app-port"];
124
+ const appPort = flags["app-port"];
171
125
  const portResult = validatePort(appPort);
172
126
  if (portResult !== true) this.error(portResult);
173
127
  const acmeStaging = flags["acme-staging"] !== void 0 ? flags["acme-staging"] : await confirm({
@@ -179,12 +133,18 @@ TLS certificates are automatically obtained via Let's Encrypt using the tls-keyg
179
133
  default: false
180
134
  });
181
135
  this.log("");
182
- this.log(chalk.bold("TLS Configuration:"));
183
- this.log(` Domain: ${domain.trim()}`);
136
+ this.log(chalk.bold("Custom domain configuration:"));
137
+ this.log(` Custom domain: ${domain.trim()}`);
184
138
  this.log(` App port: ${appPort.trim()}`);
185
139
  this.log(` ACME staging: ${acmeStaging}`);
186
140
  this.log(` Caddy logs: ${enableCaddyLogs}`);
187
141
  this.log("");
142
+ this.log(
143
+ chalk.gray(
144
+ "Note: your app will also be reachable at its platform-derived hostname (<app-address>.<env>.eigencloud.xyz) with its own cert."
145
+ )
146
+ );
147
+ this.log("");
188
148
  if (!flags.domain) {
189
149
  const confirmed = await confirm({
190
150
  message: "Write these settings to .env?",
@@ -210,12 +170,12 @@ TLS certificates are automatically obtained via Let's Encrypt using the tls-keyg
210
170
  this.log(`Updated .env.example`);
211
171
  }
212
172
  this.log("");
213
- this.log(chalk.green("TLS configured successfully"));
173
+ this.log(chalk.green("Custom domain configured successfully"));
214
174
  this.log("");
215
175
  this.log("Next steps:");
216
176
  this.log("");
217
- this.log("1. Set up DNS A record pointing to your instance IP");
218
- this.log(" Run 'ecloud compute app list' to get IP address");
177
+ this.log(`1. Set up a DNS A record for ${domain.trim()} pointing at the platform proxy IP`);
178
+ this.log(" Run 'ecloud compute app list' to confirm the IP once the app is running");
219
179
  this.log("");
220
180
  this.log("2. Deploy or upgrade:");
221
181
  this.log(" ecloud compute app deploy # new app");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/commands/compute/app/configure/tls.ts","../../../../../src/templates/tls/Caddyfile.tmpl","../../../../../src/templates/tls/templates.ts"],"sourcesContent":["import { Command, Flags } from \"@oclif/core\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport {\n getCaddyfileTemplate,\n getTlsEnvBlock,\n TLS_ENV_EXAMPLE_BLOCK,\n} from \"../../../../templates/tls/templates.js\";\n\nfunction envFileHasTlsConfig(filePath: string): boolean {\n if (!fs.existsSync(filePath)) return false;\n const content = fs.readFileSync(filePath, \"utf-8\");\n return /^DOMAIN=/m.test(content);\n}\n\nfunction validateDomain(value: string): true | string {\n const trimmed = value.trim();\n if (!trimmed) return \"Domain is required\";\n if (trimmed.toLowerCase() === \"localhost\") return \"Domain cannot be localhost\";\n if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*\\.)+[a-zA-Z]{2,}$/.test(trimmed))\n return \"Enter a valid domain (e.g. myapp.example.com)\";\n return true;\n}\n\nfunction validatePort(value: string): true | string {\n const num = Number(value.trim());\n if (!Number.isInteger(num) || num < 1 || num > 65535) return \"Enter a valid port (1-65535)\";\n return true;\n}\n\nexport default class ConfigureTLS extends Command {\n static description = \"Configure TLS for your application\";\n\n static summary = `Configures TLS for your EigenCloud application.\n\nPrompts for domain and TLS settings (or accepts them via flags), then:\n- Creates a Caddyfile for automatic HTTPS via Caddy reverse proxy\n- Appends TLS variables to .env with your values\n- Appends TLS placeholders to .env.example\n\nTLS certificates are automatically obtained via Let's Encrypt using the tls-keygen tool.`;\n\n static examples = [\n \"<%= config.bin %> compute app configure tls\",\n \"<%= config.bin %> compute app configure tls --domain myapp.example.com\",\n \"<%= config.bin %> compute app configure tls --domain myapp.example.com --app-port 8080\",\n \"<%= config.bin %> compute app configure tls --domain myapp.example.com --no-acme-staging\",\n ];\n\n static flags = {\n domain: Flags.string({\n description: \"Domain name for TLS certificate\",\n }),\n \"app-port\": Flags.string({\n description: \"Port your application listens on\",\n default: \"3000\",\n }),\n \"acme-staging\": Flags.boolean({\n description: \"Use Let's Encrypt staging environment\",\n default: true,\n allowNo: true,\n }),\n \"caddy-logs\": Flags.boolean({\n description: \"Enable Caddy debug logs\",\n default: false,\n allowNo: true,\n }),\n };\n\n async run() {\n const { flags } = await this.parse(ConfigureTLS);\n const cwd = process.cwd();\n\n // Check if TLS is already configured in .env\n const envPath = path.join(cwd, \".env\");\n if (envFileHasTlsConfig(envPath)) {\n this.warn(\"TLS is already configured in .env (DOMAIN is set). Skipping.\");\n return;\n }\n\n // Write Caddyfile\n const caddyfilePath = path.join(cwd, \"Caddyfile\");\n if (fs.existsSync(caddyfilePath)) {\n this.log(\"Caddyfile already exists, keeping existing file.\");\n } else {\n const caddyfileContent = getCaddyfileTemplate();\n fs.writeFileSync(caddyfilePath, caddyfileContent, { mode: 0o644 });\n this.log(\"Created Caddyfile\");\n }\n\n this.log(\"\");\n\n // Resolve values: use flags if provided, otherwise prompt\n let domain = flags.domain;\n if (!domain) {\n domain = await input({\n message: \"Domain name:\",\n validate: validateDomain,\n });\n } else {\n const result = validateDomain(domain);\n if (result !== true) this.error(result);\n }\n\n let appPort = flags[\"app-port\"];\n // Only prompt if the user didn't pass --app-port at all (default is \"3000\")\n // Since oclif always provides the default, we use the default directly\n const portResult = validatePort(appPort);\n if (portResult !== true) this.error(portResult);\n\n const acmeStaging =\n flags[\"acme-staging\"] !== undefined\n ? flags[\"acme-staging\"]\n : await confirm({\n message:\n \"Use Let's Encrypt staging? (recommended for first deploy to avoid rate limits)\",\n default: true,\n });\n\n const enableCaddyLogs =\n flags[\"caddy-logs\"] !== undefined\n ? flags[\"caddy-logs\"]\n : await confirm({\n message: \"Enable Caddy debug logs?\",\n default: false,\n });\n\n // Show summary\n this.log(\"\");\n this.log(chalk.bold(\"TLS Configuration:\"));\n this.log(` Domain: ${domain.trim()}`);\n this.log(` App port: ${appPort.trim()}`);\n this.log(` ACME staging: ${acmeStaging}`);\n this.log(` Caddy logs: ${enableCaddyLogs}`);\n this.log(\"\");\n\n // Only ask for confirmation in interactive mode (no --domain flag)\n if (!flags.domain) {\n const confirmed = await confirm({\n message: \"Write these settings to .env?\",\n default: true,\n });\n\n if (!confirmed) {\n this.log(\"Cancelled.\");\n return;\n }\n }\n\n const vars = {\n domain: domain.trim(),\n appPort: appPort.trim(),\n acmeStaging,\n enableCaddyLogs,\n };\n\n // Append to .env\n const envBlock = getTlsEnvBlock(vars);\n fs.appendFileSync(envPath, envBlock, { mode: 0o644 });\n this.log(`Updated .env`);\n\n // Append to .env.example (with placeholders, skip if already has DOMAIN)\n const envExamplePath = path.join(cwd, \".env.example\");\n if (!envFileHasTlsConfig(envExamplePath)) {\n fs.appendFileSync(envExamplePath, TLS_ENV_EXAMPLE_BLOCK, { mode: 0o644 });\n this.log(`Updated .env.example`);\n }\n\n // Print next steps\n this.log(\"\");\n this.log(chalk.green(\"TLS configured successfully\"));\n this.log(\"\");\n this.log(\"Next steps:\");\n this.log(\"\");\n this.log(\"1. Set up DNS A record pointing to your instance IP\");\n this.log(\" Run 'ecloud compute app list' to get IP address\");\n this.log(\"\");\n this.log(\"2. Deploy or upgrade:\");\n this.log(\" ecloud compute app deploy # new app\");\n this.log(\" ecloud compute app upgrade # existing app\");\n this.log(\"\");\n\n if (acmeStaging) {\n this.log(chalk.yellow(\"Note: ACME_STAGING is enabled (recommended for first deploy)\"));\n this.log(\"Once verified, switch to production certs:\");\n this.log(\" 1. Set ACME_STAGING=false in .env\");\n this.log(\" 2. Set ACME_FORCE_ISSUE=true in .env (one-time)\");\n this.log(\" 3. Run: ecloud compute app upgrade\");\n this.log(\"\");\n }\n\n this.log(\"Let's Encrypt rate limit: 5 certificates/week per domain\");\n }\n}\n","# Caddy configuration for automatic HTTPS\n# The DOMAIN environment variable will be injected at runtime\n\n{$DOMAIN:localhost} {\n # TLS configuration - always use provided certificates generated by tls-keygen\n tls /run/tls/fullchain.pem /run/tls/privkey.pem\n\n # Reverse proxy to your Node.js application\n # Modify the port to match your application (default: 3000)\n reverse_proxy localhost:{$APP_PORT:3000} {\n # Health check configuration\n health_uri /health\n health_interval 30s\n health_timeout 5s\n health_status 200\n }\n\n # Custom headers\n header {\n # Security headers\n X-Content-Type-Options \"nosniff\"\n X-Frame-Options \"DENY\"\n X-XSS-Protection \"1; mode=block\"\n Referrer-Policy \"strict-origin-when-cross-origin\"\n\n # Remove server header\n -Server\n }\n\n # Logging\n log {\n output stdout\n format console\n level INFO\n }\n\n # Request size limits\n request_body {\n max_size 10MB\n }\n}\n\n# HTTP endpoint (optional, for health checks or redirects)\n:80 {\n # Redirect to HTTPS only when host isn't localhost\n @for_domain expression {host} != \"localhost\"\n redir @for_domain https://{host}{uri} permanent\n\n # Health check endpoint (always available via HTTP)\n handle /health {\n respond \"OK\" 200\n }\n}\n","/**\n * TLS configuration templates\n */\n\nimport caddyfileTemplate from \"./Caddyfile.tmpl\";\n\n/**\n * Get the Caddyfile template\n */\nexport function getCaddyfileTemplate(): string {\n return caddyfileTemplate;\n}\n\nexport interface TlsEnvVars {\n domain: string;\n appPort: string;\n acmeStaging: boolean;\n enableCaddyLogs: boolean;\n}\n\n/**\n * Generate the TLS env block with user-provided values for .env\n */\nexport function getTlsEnvBlock(vars: TlsEnvVars): string {\n return `\n# TLS Configuration\nDOMAIN=${vars.domain}\nAPP_PORT=${vars.appPort}\nENABLE_CADDY_LOGS=${vars.enableCaddyLogs}\nACME_STAGING=${vars.acmeStaging}\nACME_FORCE_ISSUE=false\n`;\n}\n\n/**\n * Placeholder TLS block for .env.example\n */\nexport const TLS_ENV_EXAMPLE_BLOCK = `\n# TLS Configuration\n# DOMAIN=yourdomain.com\n# APP_PORT=3000\n# ENABLE_CADDY_LOGS=false\n# ACME_STAGING=false\n# ACME_FORCE_ISSUE=false\n`;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/commands/compute/app/configure/tls.ts","../../../../../src/templates/tls/Caddyfile.tmpl","../../../../../src/templates/tls/templates.ts"],"sourcesContent":["import { Command, Flags } from \"@oclif/core\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport {\n getCaddyfileTemplate,\n getTlsEnvBlock,\n TLS_ENV_EXAMPLE_BLOCK,\n} from \"../../../../templates/tls/templates.js\";\n\nfunction envFileHasTlsConfig(filePath: string): boolean {\n if (!fs.existsSync(filePath)) return false;\n const content = fs.readFileSync(filePath, \"utf-8\");\n return /^DOMAIN=/m.test(content);\n}\n\nfunction validateDomain(value: string): true | string {\n const trimmed = value.trim();\n if (!trimmed) return \"Domain is required\";\n if (trimmed.toLowerCase() === \"localhost\") return \"Domain cannot be localhost\";\n if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*\\.)+[a-zA-Z]{2,}$/.test(trimmed))\n return \"Enter a valid domain (e.g. myapp.example.com)\";\n return true;\n}\n\nfunction validatePort(value: string): true | string {\n const num = Number(value.trim());\n if (!Number.isInteger(num) || num < 1 || num > 65535) return \"Enter a valid port (1-65535)\";\n return true;\n}\n\nexport default class ConfigureTLS extends Command {\n static description = \"Configure a custom domain for your app (optional)\";\n\n static summary = `Configures a custom domain for your EigenCloud application.\n\nBy default, every deployed app is reachable at its platform-derived\nhostname (<app-address>.<env-name>.eigencloud.xyz) with TLS already\nset up. You only need this command if you also want the app reachable\nat a custom domain you control.\n\nRunning this command:\n- Creates a Caddyfile serving both the platform hostname and your\n custom domain\n- Appends DOMAIN + Caddy settings to .env\n- Appends TLS placeholders to .env.example\n\nAfter running this, set a DNS A record for your custom domain\npointing at the platform's proxy IP, then deploy/upgrade. Certs for\nboth hostnames are obtained via Let's Encrypt at VM boot.`;\n\n static examples = [\n \"<%= config.bin %> compute app configure tls --domain myapp.example.com\",\n \"<%= config.bin %> compute app configure tls --domain myapp.example.com --app-port 8080\",\n \"<%= config.bin %> compute app configure tls --domain myapp.example.com --no-acme-staging\",\n ];\n\n static flags = {\n domain: Flags.string({\n description: \"Custom domain name for TLS certificate (additive to the platform hostname)\",\n }),\n \"app-port\": Flags.string({\n description: \"Port your application listens on\",\n default: \"3000\",\n }),\n \"acme-staging\": Flags.boolean({\n description: \"Use Let's Encrypt staging environment\",\n default: true,\n allowNo: true,\n }),\n \"caddy-logs\": Flags.boolean({\n description: \"Enable Caddy debug logs\",\n default: false,\n allowNo: true,\n }),\n };\n\n async run() {\n const { flags } = await this.parse(ConfigureTLS);\n const cwd = process.cwd();\n\n const envPath = path.join(cwd, \".env\");\n if (envFileHasTlsConfig(envPath)) {\n this.warn(\"Custom domain is already configured in .env (DOMAIN is set). Skipping.\");\n return;\n }\n\n // Write Caddyfile. The same template also serves the platform\n // hostname so the file is safe to drop in even if the user\n // later removes the DOMAIN line from .env.\n const caddyfilePath = path.join(cwd, \"Caddyfile\");\n if (fs.existsSync(caddyfilePath)) {\n this.log(\"Caddyfile already exists, keeping existing file.\");\n } else {\n const caddyfileContent = getCaddyfileTemplate();\n fs.writeFileSync(caddyfilePath, caddyfileContent, { mode: 0o644 });\n this.log(\"Created Caddyfile\");\n }\n\n this.log(\"\");\n\n // Resolve values: use flags if provided, otherwise prompt\n let domain = flags.domain;\n if (!domain) {\n domain = await input({\n message: \"Custom domain name:\",\n validate: validateDomain,\n });\n } else {\n const result = validateDomain(domain);\n if (result !== true) this.error(result);\n }\n\n const appPort = flags[\"app-port\"];\n const portResult = validatePort(appPort);\n if (portResult !== true) this.error(portResult);\n\n const acmeStaging =\n flags[\"acme-staging\"] !== undefined\n ? flags[\"acme-staging\"]\n : await confirm({\n message:\n \"Use Let's Encrypt staging? (recommended for first deploy to avoid rate limits)\",\n default: true,\n });\n\n const enableCaddyLogs =\n flags[\"caddy-logs\"] !== undefined\n ? flags[\"caddy-logs\"]\n : await confirm({\n message: \"Enable Caddy debug logs?\",\n default: false,\n });\n\n // Show summary\n this.log(\"\");\n this.log(chalk.bold(\"Custom domain configuration:\"));\n this.log(` Custom domain: ${domain.trim()}`);\n this.log(` App port: ${appPort.trim()}`);\n this.log(` ACME staging: ${acmeStaging}`);\n this.log(` Caddy logs: ${enableCaddyLogs}`);\n this.log(\"\");\n this.log(\n chalk.gray(\n \"Note: your app will also be reachable at its platform-derived hostname (<app-address>.<env>.eigencloud.xyz) with its own cert.\",\n ),\n );\n this.log(\"\");\n\n // Only ask for confirmation in interactive mode (no --domain flag)\n if (!flags.domain) {\n const confirmed = await confirm({\n message: \"Write these settings to .env?\",\n default: true,\n });\n\n if (!confirmed) {\n this.log(\"Cancelled.\");\n return;\n }\n }\n\n const vars = {\n domain: domain.trim(),\n appPort: appPort.trim(),\n acmeStaging,\n enableCaddyLogs,\n };\n\n // Append to .env\n const envBlock = getTlsEnvBlock(vars);\n fs.appendFileSync(envPath, envBlock, { mode: 0o644 });\n this.log(`Updated .env`);\n\n // Append to .env.example (with placeholders, skip if already has DOMAIN)\n const envExamplePath = path.join(cwd, \".env.example\");\n if (!envFileHasTlsConfig(envExamplePath)) {\n fs.appendFileSync(envExamplePath, TLS_ENV_EXAMPLE_BLOCK, { mode: 0o644 });\n this.log(`Updated .env.example`);\n }\n\n // Print next steps\n this.log(\"\");\n this.log(chalk.green(\"Custom domain configured successfully\"));\n this.log(\"\");\n this.log(\"Next steps:\");\n this.log(\"\");\n this.log(`1. Set up a DNS A record for ${domain.trim()} pointing at the platform proxy IP`);\n this.log(\" Run 'ecloud compute app list' to confirm the IP once the app is running\");\n this.log(\"\");\n this.log(\"2. Deploy or upgrade:\");\n this.log(\" ecloud compute app deploy # new app\");\n this.log(\" ecloud compute app upgrade # existing app\");\n this.log(\"\");\n\n if (acmeStaging) {\n this.log(chalk.yellow(\"Note: ACME_STAGING is enabled (recommended for first deploy)\"));\n this.log(\"Once verified, switch to production certs:\");\n this.log(\" 1. Set ACME_STAGING=false in .env\");\n this.log(\" 2. Set ACME_FORCE_ISSUE=true in .env (one-time)\");\n this.log(\" 3. Run: ecloud compute app upgrade\");\n this.log(\"\");\n }\n\n this.log(\"Let's Encrypt rate limit: 5 certificates/week per domain\");\n }\n}\n","# Caddy configuration for automatic HTTPS\n#\n# Two sites can be configured at runtime via env vars that\n# ecloud-platform / the CLI inject into tee-env metadata:\n#\n# ECLOUD_PLATFORM_HOST — the platform-derived hostname\n# (<addr>.<env>.eigencloud.xyz). Always set\n# for platform-routed apps. Cert at\n# /run/tls/platform/fullchain.pem.\n# DOMAIN — optional user-supplied custom domain.\n# Cert at /run/tls/domain/fullchain.pem.\n#\n# When a variable is unset, Caddy substitutes the default listed\n# after the colon. We use distinct defaults per site so each block\n# binds to a unique name at bootstrap — both blocks overlapping\n# on \"localhost\" would cause Caddy to reject the config.\n{$ECLOUD_PLATFORM_HOST:localhost.platform.invalid} {\n tls /run/tls/platform/fullchain.pem /run/tls/platform/privkey.pem\n\n reverse_proxy localhost:{$APP_PORT:3000} {\n health_uri /health\n health_interval 30s\n health_timeout 5s\n health_status 200\n }\n\n header {\n X-Content-Type-Options \"nosniff\"\n X-Frame-Options \"DENY\"\n X-XSS-Protection \"1; mode=block\"\n Referrer-Policy \"strict-origin-when-cross-origin\"\n -Server\n }\n\n log {\n output stdout\n format console\n level INFO\n }\n\n request_body {\n max_size 10MB\n }\n}\n\n{$DOMAIN:localhost.user.invalid} {\n tls /run/tls/domain/fullchain.pem /run/tls/domain/privkey.pem\n\n reverse_proxy localhost:{$APP_PORT:3000} {\n health_uri /health\n health_interval 30s\n health_timeout 5s\n health_status 200\n }\n\n header {\n X-Content-Type-Options \"nosniff\"\n X-Frame-Options \"DENY\"\n X-XSS-Protection \"1; mode=block\"\n Referrer-Policy \"strict-origin-when-cross-origin\"\n -Server\n }\n\n log {\n output stdout\n format console\n level INFO\n }\n\n request_body {\n max_size 10MB\n }\n}\n\n# HTTP endpoint (optional, for health checks or redirects)\n:80 {\n # Redirect to HTTPS for any real (non-placeholder) host\n @for_domain expression {host} != \"localhost.platform.invalid\" && {host} != \"localhost.user.invalid\" && {host} != \"localhost\"\n redir @for_domain https://{host}{uri} permanent\n\n # Health check endpoint (always available via HTTP)\n handle /health {\n respond \"OK\" 200\n }\n}\n","/**\n * TLS configuration templates\n */\n\nimport caddyfileTemplate from \"./Caddyfile.tmpl\";\n\n/**\n * Get the Caddyfile template\n */\nexport function getCaddyfileTemplate(): string {\n return caddyfileTemplate;\n}\n\nexport interface TlsEnvVars {\n domain: string;\n appPort: string;\n acmeStaging: boolean;\n enableCaddyLogs: boolean;\n}\n\n/**\n * Generate the TLS env block with user-provided values for .env\n */\nexport function getTlsEnvBlock(vars: TlsEnvVars): string {\n return `\n# TLS Configuration\nDOMAIN=${vars.domain}\nAPP_PORT=${vars.appPort}\nENABLE_CADDY_LOGS=${vars.enableCaddyLogs}\nACME_STAGING=${vars.acmeStaging}\nACME_FORCE_ISSUE=false\n`;\n}\n\n/**\n * Placeholder TLS block for .env.example\n */\nexport const TLS_ENV_EXAMPLE_BLOCK = `\n# TLS Configuration\n# DOMAIN=yourdomain.com\n# APP_PORT=3000\n# ENABLE_CADDY_LOGS=false\n# ACME_STAGING=false\n# ACME_FORCE_ISSUE=false\n`;\n"],"mappings":";;;AAAA,SAAS,SAAS,aAAa;AAC/B,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,OAAO,WAAW;AAClB,SAAS,OAAO,eAAe;;;ACJ/B;;;ACSO,SAAS,uBAA+B;AAC7C,SAAO;AACT;AAYO,SAAS,eAAe,MAA0B;AACvD,SAAO;AAAA;AAAA,SAEA,KAAK,MAAM;AAAA,WACT,KAAK,OAAO;AAAA,oBACH,KAAK,eAAe;AAAA,eACzB,KAAK,WAAW;AAAA;AAAA;AAG/B;AAKO,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AF1BrC,SAAS,oBAAoB,UAA2B;AACtD,MAAI,CAAI,cAAW,QAAQ,EAAG,QAAO;AACrC,QAAM,UAAa,gBAAa,UAAU,OAAO;AACjD,SAAO,YAAY,KAAK,OAAO;AACjC;AAEA,SAAS,eAAe,OAA8B;AACpD,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,QAAQ,YAAY,MAAM,YAAa,QAAO;AAClD,MAAI,CAAC,8CAA8C,KAAK,OAAO;AAC7D,WAAO;AACT,SAAO;AACT;AAEA,SAAS,aAAa,OAA8B;AAClD,QAAM,MAAM,OAAO,MAAM,KAAK,CAAC;AAC/B,MAAI,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,KAAK,MAAM,MAAO,QAAO;AAC7D,SAAO;AACT;AAEA,IAAqB,eAArB,MAAqB,sBAAqB,QAAQ;AAAA,EAChD,OAAO,cAAc;AAAA,EAErB,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBjB,OAAO,WAAW;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ;AAAA,IACb,QAAQ,MAAM,OAAO;AAAA,MACnB,aAAa;AAAA,IACf,CAAC;AAAA,IACD,YAAY,MAAM,OAAO;AAAA,MACvB,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,gBAAgB,MAAM,QAAQ;AAAA,MAC5B,aAAa;AAAA,MACb,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAAA,IACD,cAAc,MAAM,QAAQ;AAAA,MAC1B,aAAa;AAAA,MACb,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM;AACV,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,aAAY;AAC/C,UAAM,MAAM,QAAQ,IAAI;AAExB,UAAM,UAAe,UAAK,KAAK,MAAM;AACrC,QAAI,oBAAoB,OAAO,GAAG;AAChC,WAAK,KAAK,wEAAwE;AAClF;AAAA,IACF;AAKA,UAAM,gBAAqB,UAAK,KAAK,WAAW;AAChD,QAAO,cAAW,aAAa,GAAG;AAChC,WAAK,IAAI,kDAAkD;AAAA,IAC7D,OAAO;AACL,YAAM,mBAAmB,qBAAqB;AAC9C,MAAG,iBAAc,eAAe,kBAAkB,EAAE,MAAM,IAAM,CAAC;AACjE,WAAK,IAAI,mBAAmB;AAAA,IAC9B;AAEA,SAAK,IAAI,EAAE;AAGX,QAAI,SAAS,MAAM;AACnB,QAAI,CAAC,QAAQ;AACX,eAAS,MAAM,MAAM;AAAA,QACnB,SAAS;AAAA,QACT,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,OAAO;AACL,YAAM,SAAS,eAAe,MAAM;AACpC,UAAI,WAAW,KAAM,MAAK,MAAM,MAAM;AAAA,IACxC;AAEA,UAAM,UAAU,MAAM,UAAU;AAChC,UAAM,aAAa,aAAa,OAAO;AACvC,QAAI,eAAe,KAAM,MAAK,MAAM,UAAU;AAE9C,UAAM,cACJ,MAAM,cAAc,MAAM,SACtB,MAAM,cAAc,IACpB,MAAM,QAAQ;AAAA,MACZ,SACE;AAAA,MACF,SAAS;AAAA,IACX,CAAC;AAEP,UAAM,kBACJ,MAAM,YAAY,MAAM,SACpB,MAAM,YAAY,IAClB,MAAM,QAAQ;AAAA,MACZ,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAGP,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,MAAM,KAAK,8BAA8B,CAAC;AACnD,SAAK,IAAI,sBAAsB,OAAO,KAAK,CAAC,EAAE;AAC9C,SAAK,IAAI,sBAAsB,QAAQ,KAAK,CAAC,EAAE;AAC/C,SAAK,IAAI,sBAAsB,WAAW,EAAE;AAC5C,SAAK,IAAI,sBAAsB,eAAe,EAAE;AAChD,SAAK,IAAI,EAAE;AACX,SAAK;AAAA,MACH,MAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,SAAK,IAAI,EAAE;AAGX,QAAI,CAAC,MAAM,QAAQ;AACjB,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC;AAED,UAAI,CAAC,WAAW;AACd,aAAK,IAAI,YAAY;AACrB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO;AAAA,MACX,QAAQ,OAAO,KAAK;AAAA,MACpB,SAAS,QAAQ,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAGA,UAAM,WAAW,eAAe,IAAI;AACpC,IAAG,kBAAe,SAAS,UAAU,EAAE,MAAM,IAAM,CAAC;AACpD,SAAK,IAAI,cAAc;AAGvB,UAAM,iBAAsB,UAAK,KAAK,cAAc;AACpD,QAAI,CAAC,oBAAoB,cAAc,GAAG;AACxC,MAAG,kBAAe,gBAAgB,uBAAuB,EAAE,MAAM,IAAM,CAAC;AACxE,WAAK,IAAI,sBAAsB;AAAA,IACjC;AAGA,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,MAAM,MAAM,uCAAuC,CAAC;AAC7D,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,aAAa;AACtB,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,gCAAgC,OAAO,KAAK,CAAC,oCAAoC;AAC1F,SAAK,IAAI,4EAA4E;AACrF,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,uBAAuB;AAChC,SAAK,IAAI,2CAA2C;AACpD,SAAK,IAAI,gDAAgD;AACzD,SAAK,IAAI,EAAE;AAEX,QAAI,aAAa;AACf,WAAK,IAAI,MAAM,OAAO,8DAA8D,CAAC;AACrF,WAAK,IAAI,4CAA4C;AACrD,WAAK,IAAI,qCAAqC;AAC9C,WAAK,IAAI,mDAAmD;AAC5D,WAAK,IAAI,sCAAsC;AAC/C,WAAK,IAAI,EAAE;AAAA,IACb;AAEA,SAAK,IAAI,0DAA0D;AAAA,EACrE;AACF;","names":[]}
@@ -304,7 +304,7 @@ function findAvailableName(environment, baseName) {
304
304
 
305
305
  // src/utils/version.ts
306
306
  function getCliVersion() {
307
- return true ? "1.0.0-devep2" : "0.0.0";
307
+ return true ? "1.0.0-devep4" : "0.0.0";
308
308
  }
309
309
  function getClientId() {
310
310
  return `ecloud-cli/v${getCliVersion()}`;
@@ -219,7 +219,7 @@ function listApps(environment) {
219
219
 
220
220
  // src/utils/version.ts
221
221
  function getCliVersion() {
222
- return true ? "1.0.0-devep2" : "0.0.0";
222
+ return true ? "1.0.0-devep4" : "0.0.0";
223
223
  }
224
224
  function getClientId() {
225
225
  return `ecloud-cli/v${getCliVersion()}`;
@@ -198,7 +198,7 @@ function getAppName(environment, appID) {
198
198
 
199
199
  // src/utils/version.ts
200
200
  function getCliVersion() {
201
- return true ? "1.0.0-devep2" : "0.0.0";
201
+ return true ? "1.0.0-devep4" : "0.0.0";
202
202
  }
203
203
  function getClientId() {
204
204
  return `ecloud-cli/v${getCliVersion()}`;
@@ -245,7 +245,7 @@ function listApps(environment) {
245
245
 
246
246
  // src/utils/version.ts
247
247
  function getCliVersion() {
248
- return true ? "1.0.0-devep2" : "0.0.0";
248
+ return true ? "1.0.0-devep4" : "0.0.0";
249
249
  }
250
250
  function getClientId() {
251
251
  return `ecloud-cli/v${getCliVersion()}`;
@@ -285,7 +285,7 @@ function listApps(environment) {
285
285
 
286
286
  // src/utils/version.ts
287
287
  function getCliVersion() {
288
- return true ? "1.0.0-devep2" : "0.0.0";
288
+ return true ? "1.0.0-devep4" : "0.0.0";
289
289
  }
290
290
  function getClientId() {
291
291
  return `ecloud-cli/v${getCliVersion()}`;
@@ -236,7 +236,7 @@ function listApps(environment) {
236
236
 
237
237
  // src/utils/version.ts
238
238
  function getCliVersion() {
239
- return true ? "1.0.0-devep2" : "0.0.0";
239
+ return true ? "1.0.0-devep4" : "0.0.0";
240
240
  }
241
241
  function getClientId() {
242
242
  return `ecloud-cli/v${getCliVersion()}`;
@@ -244,7 +244,7 @@ function listApps(environment) {
244
244
 
245
245
  // src/utils/version.ts
246
246
  function getCliVersion() {
247
- return true ? "1.0.0-devep2" : "0.0.0";
247
+ return true ? "1.0.0-devep4" : "0.0.0";
248
248
  }
249
249
  function getClientId() {
250
250
  return `ecloud-cli/v${getCliVersion()}`;
@@ -244,7 +244,7 @@ function listApps(environment) {
244
244
 
245
245
  // src/utils/version.ts
246
246
  function getCliVersion() {
247
- return true ? "1.0.0-devep2" : "0.0.0";
247
+ return true ? "1.0.0-devep4" : "0.0.0";
248
248
  }
249
249
  function getClientId() {
250
250
  return `ecloud-cli/v${getCliVersion()}`;
@@ -244,7 +244,7 @@ function listApps(environment) {
244
244
 
245
245
  // src/utils/version.ts
246
246
  function getCliVersion() {
247
- return true ? "1.0.0-devep2" : "0.0.0";
247
+ return true ? "1.0.0-devep4" : "0.0.0";
248
248
  }
249
249
  function getClientId() {
250
250
  return `ecloud-cli/v${getCliVersion()}`;
@@ -323,7 +323,7 @@ function listApps(environment) {
323
323
 
324
324
  // src/utils/version.ts
325
325
  function getCliVersion() {
326
- return true ? "1.0.0-devep2" : "0.0.0";
326
+ return true ? "1.0.0-devep4" : "0.0.0";
327
327
  }
328
328
  function getClientId() {
329
329
  return `ecloud-cli/v${getCliVersion()}`;
@@ -155,7 +155,7 @@ var APPS_DIR = path2.join(CONFIG_DIR, "apps");
155
155
 
156
156
  // src/utils/version.ts
157
157
  function getCliVersion() {
158
- return true ? "1.0.0-devep2" : "0.0.0";
158
+ return true ? "1.0.0-devep4" : "0.0.0";
159
159
  }
160
160
  function getClientId() {
161
161
  return `ecloud-cli/v${getCliVersion()}`;
@@ -158,7 +158,7 @@ var APPS_DIR = path2.join(CONFIG_DIR, "apps");
158
158
 
159
159
  // src/utils/version.ts
160
160
  function getCliVersion() {
161
- return true ? "1.0.0-devep2" : "0.0.0";
161
+ return true ? "1.0.0-devep4" : "0.0.0";
162
162
  }
163
163
  function getClientId() {
164
164
  return `ecloud-cli/v${getCliVersion()}`;
@@ -155,7 +155,7 @@ var APPS_DIR = path2.join(CONFIG_DIR, "apps");
155
155
 
156
156
  // src/utils/version.ts
157
157
  function getCliVersion() {
158
- return true ? "1.0.0-devep2" : "0.0.0";
158
+ return true ? "1.0.0-devep4" : "0.0.0";
159
159
  }
160
160
  function getClientId() {
161
161
  return `ecloud-cli/v${getCliVersion()}`;
@@ -156,7 +156,7 @@ var APPS_DIR = path2.join(CONFIG_DIR, "apps");
156
156
 
157
157
  // src/utils/version.ts
158
158
  function getCliVersion() {
159
- return true ? "1.0.0-devep2" : "0.0.0";
159
+ return true ? "1.0.0-devep4" : "0.0.0";
160
160
  }
161
161
  function getClientId() {
162
162
  return `ecloud-cli/v${getCliVersion()}`;
@@ -156,7 +156,7 @@ var APPS_DIR = path2.join(CONFIG_DIR, "apps");
156
156
 
157
157
  // src/utils/version.ts
158
158
  function getCliVersion() {
159
- return true ? "1.0.0-devep2" : "0.0.0";
159
+ return true ? "1.0.0-devep4" : "0.0.0";
160
160
  }
161
161
  function getClientId() {
162
162
  return `ecloud-cli/v${getCliVersion()}`;
@@ -156,7 +156,7 @@ var APPS_DIR = path2.join(CONFIG_DIR, "apps");
156
156
 
157
157
  // src/utils/version.ts
158
158
  function getCliVersion() {
159
- return true ? "1.0.0-devep2" : "0.0.0";
159
+ return true ? "1.0.0-devep4" : "0.0.0";
160
160
  }
161
161
  function getClientId() {
162
162
  return `ecloud-cli/v${getCliVersion()}`;
@@ -155,7 +155,7 @@ var APPS_DIR = path2.join(CONFIG_DIR, "apps");
155
155
 
156
156
  // src/utils/version.ts
157
157
  function getCliVersion() {
158
- return true ? "1.0.0-devep2" : "0.0.0";
158
+ return true ? "1.0.0-devep4" : "0.0.0";
159
159
  }
160
160
  function getClientId() {
161
161
  return `ecloud-cli/v${getCliVersion()}`;
@@ -7,7 +7,7 @@ import { getBuildType as getBuildType5 } from "@layr-labs/ecloud-sdk";
7
7
 
8
8
  // src/utils/version.ts
9
9
  function getCliVersion() {
10
- return true ? "1.0.0-devep2" : "0.0.0";
10
+ return true ? "1.0.0-devep4" : "0.0.0";
11
11
  }
12
12
 
13
13
  // src/commands/upgrade.ts
@@ -7,7 +7,7 @@ import { getBuildType as getBuildType4 } from "@layr-labs/ecloud-sdk";
7
7
 
8
8
  // src/utils/version.ts
9
9
  function getCliVersion() {
10
- return true ? "1.0.0-devep2" : "0.0.0";
10
+ return true ? "1.0.0-devep4" : "0.0.0";
11
11
  }
12
12
 
13
13
  // src/commands/upgrade.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layr-labs/ecloud-cli",
3
- "version": "1.0.0-devep2",
3
+ "version": "1.0.0-devep4",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@inquirer/prompts": "7.10.1",
17
- "@layr-labs/ecloud-sdk": "1.0.0-devep2",
17
+ "@layr-labs/ecloud-sdk": "1.0.0-devep4",
18
18
  "@napi-rs/keyring": "1.2.0",
19
19
  "@oclif/core": "4.8.0",
20
20
  "@oclif/plugin-autocomplete": "3.2.40",