dank-ai 1.0.12 → 1.0.14

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 (2) hide show
  1. package/lib/docker/manager.js +175 -10
  2. package/package.json +1 -1
@@ -132,16 +132,108 @@ class DockerManager {
132
132
  async installDockerMacOS() {
133
133
  this.logger.info('Installing Docker Desktop for macOS...');
134
134
 
135
- // Check if Homebrew is available
135
+ // Check if Homebrew is available with multiple methods
136
+ let homebrewAvailable = false;
137
+ let homebrewPath = 'brew';
138
+
136
139
  try {
137
- await execAsync('which brew');
138
- this.logger.info('Using Homebrew to install Docker Desktop...');
139
-
140
- // Install Docker Desktop via Homebrew
141
- await this.runCommand('brew install --cask docker', 'Installing Docker Desktop via Homebrew');
142
-
140
+ // Try different ways to detect Homebrew
141
+ await execAsync('brew --version');
142
+ homebrewAvailable = true;
143
+ homebrewPath = 'brew';
143
144
  } catch (error) {
145
+ try {
146
+ // Try with full path (Apple Silicon Macs)
147
+ await execAsync('/opt/homebrew/bin/brew --version');
148
+ homebrewAvailable = true;
149
+ homebrewPath = '/opt/homebrew/bin/brew';
150
+ } catch (error2) {
151
+ try {
152
+ // Try with usr/local path (Intel Macs)
153
+ await execAsync('/usr/local/bin/brew --version');
154
+ homebrewAvailable = true;
155
+ homebrewPath = '/usr/local/bin/brew';
156
+ } catch (error3) {
157
+ // Try to find brew in PATH
158
+ try {
159
+ const { stdout } = await execAsync('which brew');
160
+ if (stdout.trim()) {
161
+ await execAsync(`${stdout.trim()} --version`);
162
+ homebrewAvailable = true;
163
+ homebrewPath = stdout.trim();
164
+ }
165
+ } catch (error4) {
166
+ // Homebrew not found
167
+ this.logger.debug('Homebrew detection failed:', error4.message);
168
+ }
169
+ }
170
+ }
171
+ }
172
+
173
+ if (homebrewAvailable) {
174
+ this.logger.info(`Using Homebrew to install Docker Desktop (found at: ${homebrewPath})...`);
175
+
176
+ try {
177
+ // First, try to update Homebrew to ensure it's working
178
+ this.logger.info('Updating Homebrew...');
179
+ try {
180
+ await this.runCommandWithEnv(`${homebrewPath} update`, 'Updating Homebrew');
181
+ } catch (updateError) {
182
+ this.logger.warn('Homebrew update failed, continuing with installation...');
183
+ }
184
+
185
+ // Try different installation approaches
186
+ let installSuccess = false;
187
+
188
+ // Approach 1: Direct installation
189
+ try {
190
+ this.logger.info('Attempting direct installation...');
191
+ await this.runCommandWithEnv(`${homebrewPath} install --cask docker`, 'Installing Docker Desktop via Homebrew');
192
+ installSuccess = true;
193
+ } catch (error1) {
194
+ this.logger.warn('Direct installation failed, trying alternative approach...');
195
+
196
+ // Approach 2: Try with --force flag
197
+ try {
198
+ this.logger.info('Attempting installation with --force flag...');
199
+ await this.runCommandWithEnv(`${homebrewPath} install --cask --force docker`, 'Installing Docker Desktop via Homebrew (force)');
200
+ installSuccess = true;
201
+ } catch (error2) {
202
+ this.logger.warn('Force installation failed, trying with --no-quarantine flag...');
203
+
204
+ // Approach 3: Try with --no-quarantine flag
205
+ try {
206
+ this.logger.info('Attempting installation with --no-quarantine flag...');
207
+ await this.runCommandWithEnv(`${homebrewPath} install --cask --no-quarantine docker`, 'Installing Docker Desktop via Homebrew (no-quarantine)');
208
+ installSuccess = true;
209
+ } catch (error3) {
210
+ this.logger.error('All installation approaches failed');
211
+ throw error3;
212
+ }
213
+ }
214
+ }
215
+
216
+ if (installSuccess) {
217
+ // Try to start Docker Desktop
218
+ this.logger.info('Starting Docker Desktop...');
219
+ try {
220
+ await this.runCommandWithEnv('open -a Docker', 'Starting Docker Desktop');
221
+ } catch (startError) {
222
+ this.logger.warn('Could not start Docker Desktop automatically. Please start it manually from Applications.');
223
+ }
224
+ }
225
+
226
+ } catch (error) {
227
+ this.logger.warn('Homebrew found but installation failed. Please install Docker Desktop manually from https://www.docker.com/products/docker-desktop/');
228
+ this.logger.error(`Installation error: ${error.message}`);
229
+ this.logger.info('You can also try installing Docker Desktop manually:');
230
+ this.logger.info('1. Download from: https://www.docker.com/products/docker-desktop/');
231
+ this.logger.info('2. Or try: brew install --cask docker');
232
+ throw new Error('Docker Desktop installation via Homebrew failed. Please install manually from https://www.docker.com/products/docker-desktop/');
233
+ }
234
+ } else {
144
235
  this.logger.warn('Homebrew not found. Please install Docker Desktop manually from https://www.docker.com/products/docker-desktop/');
236
+ this.logger.info('You can install Homebrew by running: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"');
145
237
  throw new Error('Docker Desktop installation requires manual intervention. Please install from https://www.docker.com/products/docker-desktop/');
146
238
  }
147
239
  }
@@ -171,7 +263,7 @@ class DockerManager {
171
263
  // Install Docker
172
264
  await this.runCommand('sudo apt-get install -y docker-ce docker-ce-cli containerd.io', 'Installing Docker');
173
265
 
174
- // Add current user to docker group
266
+ // Add current user to docker groupl
175
267
  await this.runCommand('sudo usermod -aG docker $USER', 'Adding user to docker group');
176
268
 
177
269
  this.logger.info('Docker installation completed. You may need to log out and back in for group changes to take effect.');
@@ -258,6 +350,7 @@ class DockerManager {
258
350
  */
259
351
  async runCommand(command, description) {
260
352
  this.logger.info(`${description}...`);
353
+ this.logger.debug(`Executing command: ${command}`);
261
354
 
262
355
  return new Promise((resolve, reject) => {
263
356
  const child = spawn('sh', ['-c', command], {
@@ -269,11 +362,79 @@ class DockerManager {
269
362
  let stderr = '';
270
363
 
271
364
  child.stdout.on('data', (data) => {
272
- stdout += data.toString();
365
+ const output = data.toString();
366
+ stdout += output;
367
+ // Log output in debug mode
368
+ this.logger.debug(`STDOUT: ${output.trim()}`);
369
+ });
370
+
371
+ child.stderr.on('data', (data) => {
372
+ const output = data.toString();
373
+ stderr += output;
374
+ // Log stderr in debug mode
375
+ this.logger.debug(`STDERR: ${output.trim()}`);
376
+ });
377
+
378
+ child.on('close', (code) => {
379
+ if (code === 0) {
380
+ this.logger.info(`${description} completed successfully`);
381
+ resolve({ stdout, stderr });
382
+ } else {
383
+ const error = new Error(`Command failed with exit code ${code}: ${stderr}`);
384
+ this.logger.error(`${description} failed: ${error.message}`);
385
+ this.logger.error(`Command: ${command}`);
386
+ this.logger.error(`STDOUT: ${stdout}`);
387
+ this.logger.error(`STDERR: ${stderr}`);
388
+ reject(error);
389
+ }
390
+ });
391
+
392
+ child.on('error', (error) => {
393
+ this.logger.error(`${description} failed: ${error.message}`);
394
+ this.logger.error(`Command: ${command}`);
395
+ reject(error);
396
+ });
397
+ });
398
+ }
399
+
400
+ /**
401
+ * Run a command with proper environment setup for Homebrew
402
+ */
403
+ async runCommandWithEnv(command, description) {
404
+ this.logger.info(`${description}...`);
405
+ this.logger.debug(`Executing command: ${command}`);
406
+
407
+ return new Promise((resolve, reject) => {
408
+ // Set up environment for Homebrew
409
+ const env = {
410
+ ...process.env,
411
+ PATH: process.env.PATH,
412
+ HOMEBREW_NO_AUTO_UPDATE: '1', // Prevent auto-update during installation
413
+ HOMEBREW_NO_INSTALL_CLEANUP: '1' // Keep installation files
414
+ };
415
+
416
+ // Use bash instead of sh for better environment support
417
+ const child = spawn('bash', ['-c', command], {
418
+ stdio: ['inherit', 'pipe', 'pipe'],
419
+ shell: true,
420
+ env: env
421
+ });
422
+
423
+ let stdout = '';
424
+ let stderr = '';
425
+
426
+ child.stdout.on('data', (data) => {
427
+ const output = data.toString();
428
+ stdout += output;
429
+ // Log output in debug mode
430
+ this.logger.debug(`STDOUT: ${output.trim()}`);
273
431
  });
274
432
 
275
433
  child.stderr.on('data', (data) => {
276
- stderr += data.toString();
434
+ const output = data.toString();
435
+ stderr += output;
436
+ // Log stderr in debug mode
437
+ this.logger.debug(`STDERR: ${output.trim()}`);
277
438
  });
278
439
 
279
440
  child.on('close', (code) => {
@@ -283,12 +444,16 @@ class DockerManager {
283
444
  } else {
284
445
  const error = new Error(`Command failed with exit code ${code}: ${stderr}`);
285
446
  this.logger.error(`${description} failed: ${error.message}`);
447
+ this.logger.error(`Command: ${command}`);
448
+ this.logger.error(`STDOUT: ${stdout}`);
449
+ this.logger.error(`STDERR: ${stderr}`);
286
450
  reject(error);
287
451
  }
288
452
  });
289
453
 
290
454
  child.on('error', (error) => {
291
455
  this.logger.error(`${description} failed: ${error.message}`);
456
+ this.logger.error(`Command: ${command}`);
292
457
  reject(error);
293
458
  });
294
459
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dank-ai",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Dank Agent Service - Docker-based AI agent orchestration platform",
5
5
  "main": "lib/index.js",
6
6
  "exports": {