@lasso-ai/cli 1.4.1 → 1.4.2

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.
@@ -10,6 +10,8 @@ const node_fs_1 = __importDefault(require("node:fs"));
10
10
  const node_os_1 = __importDefault(require("node:os"));
11
11
  const node_path_1 = __importDefault(require("node:path"));
12
12
  const node_child_process_1 = require("node:child_process");
13
+ const node_https_1 = __importDefault(require("node:https"));
14
+ const node_http_1 = __importDefault(require("node:http"));
13
15
  const paths_1 = require("./paths");
14
16
  exports.TLS_KEY_FILE = node_path_1.default.join(paths_1.HOST_DIR, "host.key");
15
17
  exports.TLS_CERT_FILE = node_path_1.default.join(paths_1.HOST_DIR, "host.crt");
@@ -17,73 +19,195 @@ function hasCertificate() {
17
19
  return node_fs_1.default.existsSync(exports.TLS_KEY_FILE) && node_fs_1.default.existsSync(exports.TLS_CERT_FILE);
18
20
  }
19
21
  function isMkcertInstalled() {
22
+ // Check system PATH first
20
23
  try {
21
24
  (0, node_child_process_1.execFileSync)("mkcert", ["-version"], { stdio: "ignore" });
22
25
  return true;
23
26
  }
24
27
  catch {
28
+ // Check local installation
29
+ try {
30
+ const localMkcert = node_path_1.default.join(node_os_1.default.homedir(), ".lasso", "bin", "mkcert");
31
+ if (node_fs_1.default.existsSync(localMkcert)) {
32
+ (0, node_child_process_1.execFileSync)(localMkcert, ["-version"], { stdio: "ignore" });
33
+ return true;
34
+ }
35
+ }
36
+ catch { }
25
37
  return false;
26
38
  }
27
39
  }
28
- async function installMkcert() {
40
+ function getMkcertPath() {
41
+ // Check local installation first
42
+ const localMkcert = node_path_1.default.join(node_os_1.default.homedir(), ".lasso", "bin", "mkcert");
43
+ if (node_fs_1.default.existsSync(localMkcert)) {
44
+ return localMkcert;
45
+ }
46
+ return "mkcert";
47
+ }
48
+ async function downloadMkcert() {
49
+ const platform = node_os_1.default.platform();
50
+ const arch = node_os_1.default.arch();
51
+ let downloadUrl;
52
+ let binaryName;
53
+ // Determine the correct binary for the platform
54
+ if (platform === "darwin") {
55
+ if (arch === "x64") {
56
+ downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-darwin-amd64";
57
+ binaryName = "mkcert-darwin-amd64";
58
+ }
59
+ else if (arch === "arm64") {
60
+ downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-darwin-arm64";
61
+ binaryName = "mkcert-darwin-arm64";
62
+ }
63
+ else {
64
+ return { ok: false, error: `Unsupported architecture: ${arch}` };
65
+ }
66
+ }
67
+ else if (platform === "linux") {
68
+ if (arch === "x64") {
69
+ downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64";
70
+ binaryName = "mkcert-linux-amd64";
71
+ }
72
+ else if (arch === "arm64") {
73
+ downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-arm64";
74
+ binaryName = "mkcert-linux-arm64";
75
+ }
76
+ else {
77
+ return { ok: false, error: `Unsupported architecture: ${arch}` };
78
+ }
79
+ }
80
+ else {
81
+ return { ok: false, error: `Unsupported platform: ${platform}` };
82
+ }
29
83
  return new Promise((resolve) => {
30
- const platform = node_os_1.default.platform();
31
- let installCommand;
32
- let installArgs;
33
- if (platform === "darwin") {
34
- // macOS: Check if Homebrew is available
35
- try {
36
- (0, node_child_process_1.execFileSync)("brew", ["--version"], { stdio: "ignore" });
37
- installCommand = "brew";
38
- installArgs = ["install", "mkcert", "nss"];
84
+ const protocol = downloadUrl.startsWith("https") ? node_https_1.default : node_http_1.default;
85
+ const tempDir = node_os_1.default.tmpdir();
86
+ const tempPath = node_path_1.default.join(tempDir, binaryName);
87
+ console.log(`[Lasso] Downloading mkcert from ${downloadUrl}...`);
88
+ const file = node_fs_1.default.createWriteStream(tempPath);
89
+ protocol.get(downloadUrl, (response) => {
90
+ if (response.statusCode !== 200) {
91
+ node_fs_1.default.unlinkSync(tempPath);
92
+ return resolve({ ok: false, error: `Failed to download mkcert: ${response.statusCode}` });
39
93
  }
40
- catch {
41
- return resolve({ ok: false, error: "Homebrew not found. Please install Homebrew first: https://brew.sh/" });
94
+ response.pipe(file);
95
+ file.on("finish", () => {
96
+ file.close();
97
+ node_fs_1.default.chmodSync(tempPath, 0o755);
98
+ console.log(`[Lasso] ✓ mkcert downloaded to ${tempPath}`);
99
+ resolve({ ok: true, path: tempPath });
100
+ });
101
+ }).on("error", (error) => {
102
+ node_fs_1.default.unlinkSync(tempPath);
103
+ resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
104
+ });
105
+ });
106
+ }
107
+ async function installMkcert() {
108
+ const platform = node_os_1.default.platform();
109
+ // Try package manager first
110
+ if (platform === "darwin") {
111
+ try {
112
+ (0, node_child_process_1.execFileSync)("brew", ["--version"], { stdio: "ignore" });
113
+ console.log("[Lasso] Installing mkcert via Homebrew...");
114
+ const installResult = await new Promise((resolve) => {
115
+ const install = (0, node_child_process_1.spawn)("brew", ["install", "mkcert", "nss"], { stdio: "inherit" });
116
+ install.on("close", (code) => {
117
+ if (code === 0)
118
+ resolve({ ok: true });
119
+ else
120
+ resolve({ ok: false, error: `Homebrew install failed with code ${code}` });
121
+ });
122
+ install.on("error", (error) => {
123
+ resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
124
+ });
125
+ });
126
+ if (installResult.ok) {
127
+ (0, node_child_process_1.execFileSync)("mkcert", ["-install"], { stdio: "ignore" });
128
+ console.log("[Lasso] ✓ mkcert installed and CA configured");
129
+ return { ok: true };
42
130
  }
43
131
  }
44
- else if (platform === "linux") {
45
- // Linux: Try different package managers
46
- try {
47
- (0, node_child_process_1.execFileSync)("apt-get", ["--version"], { stdio: "ignore" });
48
- installCommand = "sudo";
49
- installArgs = ["apt-get", "install", "-y", "mkcert"];
50
- }
51
- catch {
52
- try {
53
- (0, node_child_process_1.execFileSync)("dnf", ["--version"], { stdio: "ignore" });
54
- installCommand = "sudo";
55
- installArgs = ["dnf", "install", "-y", "mkcert"];
56
- }
57
- catch {
58
- return resolve({ ok: false, error: "Could not detect package manager. Please install mkcert manually: https://mkcert.dev/" });
59
- }
132
+ catch {
133
+ console.log("[Lasso] Homebrew not available, trying direct download...");
134
+ }
135
+ }
136
+ else if (platform === "linux") {
137
+ try {
138
+ (0, node_child_process_1.execFileSync)("apt-get", ["--version"], { stdio: "ignore" });
139
+ console.log("[Lasso] Installing mkcert via apt-get...");
140
+ const installResult = await new Promise((resolve) => {
141
+ const install = (0, node_child_process_1.spawn)("sudo", ["apt-get", "install", "-y", "mkcert"], { stdio: "inherit" });
142
+ install.on("close", (code) => {
143
+ if (code === 0)
144
+ resolve({ ok: true });
145
+ else
146
+ resolve({ ok: false, error: `apt-get install failed with code ${code}` });
147
+ });
148
+ install.on("error", (error) => {
149
+ resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
150
+ });
151
+ });
152
+ if (installResult.ok) {
153
+ (0, node_child_process_1.execFileSync)("mkcert", ["-install"], { stdio: "ignore" });
154
+ console.log("[Lasso] ✓ mkcert installed and CA configured");
155
+ return { ok: true };
60
156
  }
61
157
  }
62
- else {
63
- return resolve({ ok: false, error: `Automatic mkcert installation not supported on ${platform}. Please install manually: https://mkcert.dev/` });
64
- }
65
- console.log(`[Lasso] Installing mkcert (this may require sudo password)...`);
66
- const install = (0, node_child_process_1.spawn)(installCommand, installArgs, { stdio: "inherit" });
67
- install.on("close", (code) => {
68
- if (code === 0) {
69
- // Install the local CA
70
- try {
158
+ catch {
159
+ try {
160
+ (0, node_child_process_1.execFileSync)("dnf", ["--version"], { stdio: "ignore" });
161
+ console.log("[Lasso] Installing mkcert via dnf...");
162
+ const installResult = await new Promise((resolve) => {
163
+ const install = (0, node_child_process_1.spawn)("sudo", ["dnf", "install", "-y", "mkcert"], { stdio: "inherit" });
164
+ install.on("close", (code) => {
165
+ if (code === 0)
166
+ resolve({ ok: true });
167
+ else
168
+ resolve({ ok: false, error: `dnf install failed with code ${code}` });
169
+ });
170
+ install.on("error", (error) => {
171
+ resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
172
+ });
173
+ });
174
+ if (installResult.ok) {
71
175
  (0, node_child_process_1.execFileSync)("mkcert", ["-install"], { stdio: "ignore" });
72
176
  console.log("[Lasso] ✓ mkcert installed and CA configured");
73
- resolve({ ok: true });
74
- }
75
- catch (error) {
76
- resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
177
+ return { ok: true };
77
178
  }
78
179
  }
79
- else {
80
- resolve({ ok: false, error: `mkcert installation failed with code ${code}` });
180
+ catch {
181
+ console.log("[Lasso] Package manager not available, trying direct download...");
81
182
  }
82
- });
83
- install.on("error", (error) => {
84
- resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
85
- });
86
- });
183
+ }
184
+ }
185
+ // Fallback: Download mkcert binary directly from GitHub
186
+ console.log("[Lasso] Downloading mkcert binary from GitHub...");
187
+ const downloadResult = await downloadMkcert();
188
+ if (!downloadResult.ok || !downloadResult.path) {
189
+ return { ok: false, error: downloadResult.error || "Failed to download mkcert binary" };
190
+ }
191
+ // Copy binary to a permanent location
192
+ const binDir = node_path_1.default.join(node_os_1.default.homedir(), ".lasso", "bin");
193
+ node_fs_1.default.mkdirSync(binDir, { recursive: true, mode: 0o755 });
194
+ const mkcertPath = node_path_1.default.join(binDir, "mkcert");
195
+ node_fs_1.default.copyFileSync(downloadResult.path, mkcertPath);
196
+ node_fs_1.default.chmodSync(mkcertPath, 0o755);
197
+ // Clean up temp file
198
+ try {
199
+ node_fs_1.default.unlinkSync(downloadResult.path);
200
+ }
201
+ catch { }
202
+ // Install the local CA using the downloaded binary
203
+ try {
204
+ (0, node_child_process_1.execFileSync)(mkcertPath, ["-install"], { stdio: "inherit" });
205
+ console.log("[Lasso] ✓ mkcert installed and CA configured");
206
+ return { ok: true };
207
+ }
208
+ catch (error) {
209
+ return { ok: false, error: error instanceof Error ? error.message : String(error) };
210
+ }
87
211
  }
88
212
  async function ensureHostCertificate(onProgress) {
89
213
  node_fs_1.default.mkdirSync(paths_1.HOST_DIR, { recursive: true, mode: 0o700 });
@@ -104,7 +228,8 @@ async function ensureHostCertificate(onProgress) {
104
228
  if (isMkcertInstalled()) {
105
229
  try {
106
230
  onProgress?.("Creating trusted certificate with mkcert...");
107
- (0, node_child_process_1.execFileSync)("mkcert", ["-cert-file", exports.TLS_CERT_FILE, "-key-file", exports.TLS_KEY_FILE, "localhost", "127.0.0.1", "::1", "*.lasso"], { stdio: "ignore" });
231
+ const mkcertPath = getMkcertPath();
232
+ (0, node_child_process_1.execFileSync)(mkcertPath, ["-cert-file", exports.TLS_CERT_FILE, "-key-file", exports.TLS_KEY_FILE, "localhost", "127.0.0.1", "::1", "*.lasso"], { stdio: "ignore" });
108
233
  node_fs_1.default.chmodSync(exports.TLS_KEY_FILE, 0o600);
109
234
  onProgress?.("✓ SSL certificate ready (trusted)");
110
235
  return { ok: true, trusted: true };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lasso-ai/cli",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Select any part of your running app, describe a change, and let AI edit the real source code.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cli/index.js",